diff --git a/.envrc b/.envrc new file mode 100644 index 00000000..c0594df0 --- /dev/null +++ b/.envrc @@ -0,0 +1,5 @@ +use flake + +if [ -f .env ]; then + . .env +fi diff --git a/.github/ISSUE_TEMPLATE/advisory.md b/.github/ISSUE_TEMPLATE/advisory.md new file mode 100644 index 00000000..30051c7e --- /dev/null +++ b/.github/ISSUE_TEMPLATE/advisory.md @@ -0,0 +1,25 @@ +--- +name: advisory +about: declare a (potential) vulnerability +title: '' +labels: advisory +assignees: '' + +--- + +Mandatory information: + +* Package : `?` +* cvss: `?` +* affected versions: `?` + +Optional: + +* cve: `?` +* keywords: `?` +* aliases: `?` +* related: `?` +* affected OSes: `?` +* affected architecture: `?` +* declarations: `?` +* Long description: `?` diff --git a/.github/ISSUE_TEMPLATE/hsec-tools.md b/.github/ISSUE_TEMPLATE/hsec-tools.md new file mode 100644 index 00000000..bee56cba --- /dev/null +++ b/.github/ISSUE_TEMPLATE/hsec-tools.md @@ -0,0 +1,16 @@ +--- +name: hsec-tools related +about: Bug or suggestion about hsec-tools +title: '' +labels: hsec-tools +assignees: '' + +--- + +## Summary + +## Steps to reproduce + +## Expected behavior + +## Cause of the bug diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 41d1ac28..7db92657 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -2,7 +2,7 @@ ## Contributor checklist -- [ ] My PR is related to \ +- [ ] My PR is related to \ - [ ] I have read and understood the [CONTRIBUTING guide](https://github.com/flora-pm/flora-server/blob/development/CONTRIBUTING.md) - [ ] I have inserted my change and a link to this PR in the [CHANGELOG](https://github.com/flora-pm/flora-server/blob/development/CHANGELOG.md) - [ ] I have updated documentation in `./docs/docs` if a public feature has a behaviour change diff --git a/.github/haskell-ci.patch b/.github/haskell-ci.patch new file mode 100644 index 00000000..16ad7805 --- /dev/null +++ b/.github/haskell-ci.patch @@ -0,0 +1,27 @@ +diff --git a/.github/workflows/haskell-ci.yml b/.github/workflows/haskell-ci.yml +index 96282c2..e40c573 100644 +--- a/.github/workflows/haskell-ci.yml ++++ b/.github/workflows/haskell-ci.yml +@@ -19,6 +19,21 @@ + jobs: ++ tools_changed: ++ continue-on-error: true ++ runs-on: ubuntu-22.04 ++ outputs: ++ should_skip: ${{ steps.skip_check.outputs.should_skip }} ++ steps: ++ - id: skip_check ++ uses: fkirc/skip-duplicate-actions@v5.3.1 ++ with: ++ concurrent_skipping: "never" ++ skip_after_successful_duplicate: "true" ++ paths: '["code/**"]' ++ do_not_skip: '["push", "workflow_dispatch", "schedule"]' + linux: + name: Haskell-CI - Linux - ${{ matrix.compiler }} +- runs-on: ubuntu-20.04 ++ needs: tools_changed ++ if: ${{ needs.tools_changed.outputs.should_skip != 'true' }} ++ runs-on: ubuntu-22.04 + timeout-minutes: + 60 diff --git a/.github/workflows/backend.yml b/.github/workflows/backend.yml index 66912614..d87e3212 100644 --- a/.github/workflows/backend.yml +++ b/.github/workflows/backend.yml @@ -56,12 +56,6 @@ jobs: ghc-version: "${{ matrix.ghc }}" cabal-version: "latest" - - uses: actions/setup-node@v4 - with: - node-version: "18" - cache: "yarn" - cache-dependency-path: assets/yarn.lock - - name: Configure environment run: | ./.github/workflows/setup.sh @@ -77,20 +71,28 @@ jobs: echo "${FLORA_DB_HOST}:${FLORA_DB_PORT}:${FLORA_DB_DATABASE}:${FLORA_DB_USER}:${FLORA_DB_PASSWORD}" > .pgpass cat ~/.pgpass cabal update + mkdir -p ~/.local/share + git clone https://github.com/haskell/security-advisories.git ~/.local/share/security-advisories + cd ~/.local/share/security-advisories + git checkout df64e86a39668c057031fe7e2c679b1003090e03 + cd - + + - name: "Create freeze file" + run: | + cabal freeze --enable-tests - name: Cache - uses: actions/cache@v4.1.2 + uses: actions/cache@v4 with: path: ${{ steps.setup-haskell.outputs.cabal-store }} - key: ${{ runner.os }}-ghc-${{ matrix.ghc }}-cabal-${{ hashFiles('./.plan.json') }} + key: ${{ runner.os }}-ghc-${{ matrix.ghc }}-cabal-${{ hashFiles('./dist-newstyle/cache/plan.json') }} restore-keys: ${{ runner.os }}-ghc-${{ matrix.ghc }}- - name: Build run: | cabal install postgresql-migration make soufflé - make assets-deps - make build-assets make build + - name: Test run: | set -x diff --git a/.github/workflows/haskell-ci.yml b/.github/workflows/haskell-ci.yml new file mode 100644 index 00000000..57df1b76 --- /dev/null +++ b/.github/workflows/haskell-ci.yml @@ -0,0 +1,263 @@ +# This GitHub workflow config has been generated by a script via +# +# haskell-ci 'github' '--haddock' '--github-patches' '.github/haskell-ci.patch' 'cabal.project' +# +# To regenerate the script (for example after adjusting tested-with) run +# +# haskell-ci regenerate +# +# For more information, see https://github.com/haskell-CI/haskell-ci +# +# version: 0.19.20240708 +# +# REGENDATA ("0.19.20240708",["github","--haddock","--github-patches",".github/haskell-ci.patch","cabal.project"]) +# +name: Haskell-CI +on: + - push + - pull_request +jobs: + tools_changed: + continue-on-error: true + runs-on: ubuntu-22.04 + outputs: + should_skip: ${{ steps.skip_check.outputs.should_skip }} + steps: + - id: skip_check + uses: fkirc/skip-duplicate-actions@v5.3.1 + with: + concurrent_skipping: "never" + skip_after_successful_duplicate: "true" + paths: '["code/**"]' + do_not_skip: '["push", "workflow_dispatch", "schedule"]' + linux: + name: Haskell-CI - Linux - ${{ matrix.compiler }} + needs: tools_changed + if: ${{ needs.tools_changed.outputs.should_skip != 'true' }} + runs-on: ubuntu-22.04 + timeout-minutes: + 60 + container: + image: buildpack-deps:jammy + continue-on-error: ${{ matrix.allow-failure }} + strategy: + matrix: + include: + - compiler: ghc-9.8.1 + compilerKind: ghc + compilerVersion: 9.8.1 + setup-method: ghcup + allow-failure: false + - compiler: ghc-9.6.3 + compilerKind: ghc + compilerVersion: 9.6.3 + setup-method: ghcup + allow-failure: false + - compiler: ghc-9.4.8 + compilerKind: ghc + compilerVersion: 9.4.8 + setup-method: ghcup + allow-failure: false + - compiler: ghc-9.2.8 + compilerKind: ghc + compilerVersion: 9.2.8 + setup-method: ghcup + allow-failure: false + - compiler: ghc-9.0.2 + compilerKind: ghc + compilerVersion: 9.0.2 + setup-method: ghcup + allow-failure: false + - compiler: ghc-8.10.7 + compilerKind: ghc + compilerVersion: 8.10.7 + setup-method: ghcup + allow-failure: false + fail-fast: false + steps: + - name: apt + run: | + apt-get update + apt-get install -y --no-install-recommends gnupg ca-certificates dirmngr curl git software-properties-common libtinfo5 + mkdir -p "$HOME/.ghcup/bin" + curl -sL https://downloads.haskell.org/ghcup/0.1.30.0/x86_64-linux-ghcup-0.1.30.0 > "$HOME/.ghcup/bin/ghcup" + chmod a+x "$HOME/.ghcup/bin/ghcup" + "$HOME/.ghcup/bin/ghcup" install ghc "$HCVER" || (cat "$HOME"/.ghcup/logs/*.* && false) + "$HOME/.ghcup/bin/ghcup" install cabal 3.12.1.0 || (cat "$HOME"/.ghcup/logs/*.* && false) + env: + HCKIND: ${{ matrix.compilerKind }} + HCNAME: ${{ matrix.compiler }} + HCVER: ${{ matrix.compilerVersion }} + - name: Set PATH and environment variables + run: | + echo "$HOME/.cabal/bin" >> $GITHUB_PATH + echo "LANG=C.UTF-8" >> "$GITHUB_ENV" + echo "CABAL_DIR=$HOME/.cabal" >> "$GITHUB_ENV" + echo "CABAL_CONFIG=$HOME/.cabal/config" >> "$GITHUB_ENV" + HCDIR=/opt/$HCKIND/$HCVER + HC=$("$HOME/.ghcup/bin/ghcup" whereis ghc "$HCVER") + HCPKG=$(echo "$HC" | sed 's#ghc$#ghc-pkg#') + HADDOCK=$(echo "$HC" | sed 's#ghc$#haddock#') + echo "HC=$HC" >> "$GITHUB_ENV" + echo "HCPKG=$HCPKG" >> "$GITHUB_ENV" + echo "HADDOCK=$HADDOCK" >> "$GITHUB_ENV" + echo "CABAL=$HOME/.ghcup/bin/cabal-3.12.1.0 -vnormal+nowrap" >> "$GITHUB_ENV" + HCNUMVER=$(${HC} --numeric-version|perl -ne '/^(\d+)\.(\d+)\.(\d+)(\.(\d+))?$/; print(10000 * $1 + 100 * $2 + ($3 == 0 ? $5 != 1 : $3))') + echo "HCNUMVER=$HCNUMVER" >> "$GITHUB_ENV" + echo "ARG_TESTS=--enable-tests" >> "$GITHUB_ENV" + echo "ARG_BENCH=--enable-benchmarks" >> "$GITHUB_ENV" + echo "HEADHACKAGE=false" >> "$GITHUB_ENV" + echo "ARG_COMPILER=--$HCKIND --with-compiler=$HC" >> "$GITHUB_ENV" + echo "GHCJSARITH=0" >> "$GITHUB_ENV" + env: + HCKIND: ${{ matrix.compilerKind }} + HCNAME: ${{ matrix.compiler }} + HCVER: ${{ matrix.compilerVersion }} + - name: env + run: | + env + - name: write cabal config + run: | + mkdir -p $CABAL_DIR + cat >> $CABAL_CONFIG <> $CABAL_CONFIG < cabal-plan.xz + echo 'f62ccb2971567a5f638f2005ad3173dba14693a45154c1508645c52289714cb2 cabal-plan.xz' | sha256sum -c - + xz -d < cabal-plan.xz > $HOME/.cabal/bin/cabal-plan + rm -f cabal-plan.xz + chmod a+x $HOME/.cabal/bin/cabal-plan + cabal-plan --version + - name: checkout + uses: actions/checkout@v4 + with: + path: source + - name: initial cabal.project for sdist + run: | + touch cabal.project + echo "packages: $GITHUB_WORKSPACE/source/code/hsec-tools" >> cabal.project + echo "packages: $GITHUB_WORKSPACE/source/code/cvss" >> cabal.project + echo "packages: $GITHUB_WORKSPACE/source/code/hsec-core" >> cabal.project + echo "packages: $GITHUB_WORKSPACE/source/code/hsec-sync" >> cabal.project + echo "packages: $GITHUB_WORKSPACE/source/code/osv" >> cabal.project + cat cabal.project + - name: sdist + run: | + mkdir -p sdist + $CABAL sdist all --output-dir $GITHUB_WORKSPACE/sdist + - name: unpack + run: | + mkdir -p unpacked + find sdist -maxdepth 1 -type f -name '*.tar.gz' -exec tar -C $GITHUB_WORKSPACE/unpacked -xzvf {} \; + - name: generate cabal.project + run: | + PKGDIR_hsec_tools="$(find "$GITHUB_WORKSPACE/unpacked" -maxdepth 1 -type d -regex '.*/hsec-tools-[0-9.]*')" + echo "PKGDIR_hsec_tools=${PKGDIR_hsec_tools}" >> "$GITHUB_ENV" + PKGDIR_cvss="$(find "$GITHUB_WORKSPACE/unpacked" -maxdepth 1 -type d -regex '.*/cvss-[0-9.]*')" + echo "PKGDIR_cvss=${PKGDIR_cvss}" >> "$GITHUB_ENV" + PKGDIR_hsec_core="$(find "$GITHUB_WORKSPACE/unpacked" -maxdepth 1 -type d -regex '.*/hsec-core-[0-9.]*')" + echo "PKGDIR_hsec_core=${PKGDIR_hsec_core}" >> "$GITHUB_ENV" + PKGDIR_hsec_sync="$(find "$GITHUB_WORKSPACE/unpacked" -maxdepth 1 -type d -regex '.*/hsec-sync-[0-9.]*')" + echo "PKGDIR_hsec_sync=${PKGDIR_hsec_sync}" >> "$GITHUB_ENV" + PKGDIR_osv="$(find "$GITHUB_WORKSPACE/unpacked" -maxdepth 1 -type d -regex '.*/osv-[0-9.]*')" + echo "PKGDIR_osv=${PKGDIR_osv}" >> "$GITHUB_ENV" + rm -f cabal.project cabal.project.local + touch cabal.project + touch cabal.project.local + echo "packages: ${PKGDIR_hsec_tools}" >> cabal.project + echo "packages: ${PKGDIR_cvss}" >> cabal.project + echo "packages: ${PKGDIR_hsec_core}" >> cabal.project + echo "packages: ${PKGDIR_hsec_sync}" >> cabal.project + echo "packages: ${PKGDIR_osv}" >> cabal.project + echo "package hsec-tools" >> cabal.project + echo " ghc-options: -Werror=missing-methods" >> cabal.project + echo "package cvss" >> cabal.project + echo " ghc-options: -Werror=missing-methods" >> cabal.project + echo "package hsec-core" >> cabal.project + echo " ghc-options: -Werror=missing-methods" >> cabal.project + echo "package hsec-sync" >> cabal.project + echo " ghc-options: -Werror=missing-methods" >> cabal.project + echo "package osv" >> cabal.project + echo " ghc-options: -Werror=missing-methods" >> cabal.project + cat >> cabal.project <> cabal.project.local + cat cabal.project + cat cabal.project.local + - name: dump install plan + run: | + $CABAL v2-build $ARG_COMPILER $ARG_TESTS $ARG_BENCH --dry-run all + cabal-plan + - name: restore cache + uses: actions/cache/restore@v4 + with: + key: ${{ runner.os }}-${{ matrix.compiler }}-${{ github.sha }} + path: ~/.cabal/store + restore-keys: ${{ runner.os }}-${{ matrix.compiler }}- + - name: install dependencies + run: | + $CABAL v2-build $ARG_COMPILER --disable-tests --disable-benchmarks --dependencies-only -j2 all + $CABAL v2-build $ARG_COMPILER $ARG_TESTS $ARG_BENCH --dependencies-only -j2 all + - name: build w/o tests + run: | + $CABAL v2-build $ARG_COMPILER --disable-tests --disable-benchmarks all + - name: build + run: | + $CABAL v2-build $ARG_COMPILER $ARG_TESTS $ARG_BENCH all --write-ghc-environment-files=always + - name: tests + run: | + $CABAL v2-test $ARG_COMPILER $ARG_TESTS $ARG_BENCH all --test-show-details=direct + - name: cabal check + run: | + cd ${PKGDIR_hsec_tools} || false + ${CABAL} -vnormal check + cd ${PKGDIR_cvss} || false + ${CABAL} -vnormal check + cd ${PKGDIR_hsec_core} || false + ${CABAL} -vnormal check + cd ${PKGDIR_hsec_sync} || false + ${CABAL} -vnormal check + cd ${PKGDIR_osv} || false + ${CABAL} -vnormal check + - name: haddock + run: | + $CABAL v2-haddock --disable-documentation --haddock-all $ARG_COMPILER --with-haddock $HADDOCK $ARG_TESTS $ARG_BENCH all + - name: unconstrained build + run: | + rm -f cabal.project.local + $CABAL v2-build $ARG_COMPILER --disable-tests --disable-benchmarks all + - name: save cache + uses: actions/cache/save@v4 + if: always() + with: + key: ${{ runner.os }}-${{ matrix.compiler }}-${{ github.sha }} + path: ~/.cabal/store diff --git a/.github/workflows/nix.yml b/.github/workflows/nix.yml new file mode 100644 index 00000000..c94954f8 --- /dev/null +++ b/.github/workflows/nix.yml @@ -0,0 +1,115 @@ +name: nix build and check advisories +on: + - push + - pull_request +jobs: + check-nix: + name: Check nix build + runs-on: ubuntu-22.04 + steps: + - name: git checkout + uses: actions/checkout@v4 + with: + # We need to retrieve full history to determine the correct + # `published` and `modified` timestamps + fetch-depth: 0 + - name: Install Nix + uses: DeterminateSystems/nix-installer-action@main + with: + extra-conf: system-features = nixos-test benchmark big-parallel kvm + - uses: DeterminateSystems/magic-nix-cache-action@main + - name: Check Nix flake inputs + uses: DeterminateSystems/flake-checker-action@v4 + - name: Build executable (hsec-tools) + run: nix -L build + - name: Build docker image + run: nix build -L '.#packages.x86_64-linux.hsec-tools-image' + - run: mkdir -p ~/.local/dockerImages + - run: cp result ~/.local/dockerImages/hsec-tools + - name: upload executable + uses: actions/upload-artifact@v4 + if: ${{ github.event_name == 'push' && github.ref_name == 'main' }} + with: + name: hsec-tools-${{ github.sha }} + path: ~/.local/dockerImages + - run: docker load -i ~/.local/dockerImages/hsec-tools + - name: Run advisory syntax checks + run: | + RESULT=0 + # Remove the begining of the README to extract the example. + (echo '```toml'; sed -e '1,/```toml/d' README.md) > EXAMPLE_README.md + while read FILE ; do + [ "$(dirname "$FILE")" != advisories/reserved ] || continue + echo -n "$FILE: " + docker run --rm -v $PWD:/repo --workdir /repo haskell/hsec-tools:latest /bin/hsec-tools check "$FILE" || RESULT=1 + done < <(find advisories EXAMPLE_README.md EXAMPLE_ADVISORY.md -type f -name "*.md") + exit $RESULT + - name: Run advisory uniqueness checks + run: | + ! find advisories -type f -name '*.md' -print0 \ + | xargs -0n1 basename | sort | uniq -c | grep -E -v '[[:space:]]*1 ' + - name: Generate OSV data + run: | + DATA_DIR=$PWD/osv + mkdir "$DATA_DIR" + while read FILE ; do + echo "$FILE" + ID=$(basename "$FILE" .md) + YEAR=$(echo "$ID" | cut -d - -f 2) + mkdir -p $DATA_DIR/$YEAR + docker run --rm -v $PWD:/repo --workdir /repo haskell/hsec-tools:latest /bin/hsec-tools osv "$FILE" > $DATA_DIR/$YEAR/$ID.json + done < <(find advisories -type f -name "*.md" | grep -v '^advisories/reserved/') + - name: Publish OSV data + if: ${{ github.event_name == 'push' && github.ref_name == 'main' && github.repository == 'haskell/security-advisories' }} + env: + GITHUB_SHA: ${{ github.sha }} + run: | + DATA_DIR=$PWD/osv + BRANCH=generated/osv-export + REF=refs/remotes/origin/$BRANCH + export GIT_WORK_TREE=$DATA_DIR + git read-tree "$REF" + git add --all --intent-to-add + git diff --quiet && exit + git add --all + TREE=$(git write-tree) + git config user.email security-advisories@haskell.org + git config user.name "Haskell Security Response Team" + COMMIT=$(git commit-tree "$TREE" -p "$REF" -m "$(date --utc --rfc-3339=seconds) ($GITHUB_SHA)") + git push origin $COMMIT:$BRANCH + - name: Generate snapshot data + run: | + docker run --rm -v $PWD:/repo --workdir /repo haskell/hsec-tools:latest /bin/hsec-tools generate-snapshot . snapshot + diff -r advisories snapshot/advisories | grep -v gitkeep | grep -v 'Only in advisories: reserved' | grep Only && echo 'Some advisories have been created/deleted' && exit 1 || exit 0 + - name: Publish snapshot data + if: ${{ github.event_name == 'push' && github.ref_name == 'main' && github.repository == 'haskell/security-advisories' }} + env: + GITHUB_SHA: ${{ github.sha }} + run: | + DATA_DIR=$PWD/snapshot + BRANCH=generated/snapshot-export + REF=refs/remotes/origin/$BRANCH + export GIT_WORK_TREE=$DATA_DIR + git read-tree "$REF" + git add --all --intent-to-add + git diff --quiet && exit + git add --all + TREE=$(git write-tree) + git config user.email security-advisories@haskell.org + git config user.name "Haskell Security Response Team" + COMMIT=$(git commit-tree "$TREE" -p "$REF" -m "$(date --utc --rfc-3339=seconds) ($GITHUB_SHA)") + git push origin $COMMIT:$BRANCH + - name: Generate the website + run: | + mkdir generatedWebsite + docker run --rm -v $PWD:/repo --workdir /repo haskell/hsec-tools:latest /bin/hsec-tools generate-index . generatedWebsite + cp generatedWebsite/by-dates.html generatedWebsite/index.html + rm -Rf generatedWebsite/advisories || echo "Markdown links issue has been fixed" + - name: Deploy the website + uses: peaceiris/actions-gh-pages@v3 + if: ${{ github.event_name == 'push' && github.ref_name == 'main' && github.repository == 'haskell/security-advisories' }} + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + publish_dir: ./generatedWebsite + publish_branch: generated/gh-pages + force_orphan: true diff --git a/.mailmap b/.mailmap new file mode 100644 index 00000000..10561ffc --- /dev/null +++ b/.mailmap @@ -0,0 +1 @@ +Fraser Tweedale diff --git a/.plan.json b/.plan.json deleted file mode 100644 index 2b7d2171..00000000 --- a/.plan.json +++ /dev/null @@ -1 +0,0 @@ -{"cabal-version":"3.11.0.0","cabal-lib-version":"3.11.0.0","compiler-id":"ghc-9.6.4","os":"linux","arch":"x86_64","install-plan":[{"type":"pre-existing","id":"Cabal-3.10.1.0","pkg-name":"Cabal","pkg-version":"3.10.1.0","depends":["Cabal-syntax-3.10.1.0","array-0.5.6.0","base-4.18.2.0","bytestring-0.11.5.3","containers-0.6.7","deepseq-1.4.8.1","directory-1.3.8.1","filepath-1.4.200.1","mtl-2.3.1","parsec-3.1.16.1","pretty-1.1.3.6","process-1.6.17.0","text-2.0.2","time-1.12.2","transformers-0.6.1.0","unix-2.8.4.0"]},{"type":"pre-existing","id":"Cabal-syntax-3.10.1.0","pkg-name":"Cabal-syntax","pkg-version":"3.10.1.0","depends":["array-0.5.6.0","base-4.18.2.0","binary-0.8.9.1","bytestring-0.11.5.3","containers-0.6.7","deepseq-1.4.8.1","directory-1.3.8.1","filepath-1.4.200.1","mtl-2.3.1","parsec-3.1.16.1","pretty-1.1.3.6","text-2.0.2","time-1.12.2","transformers-0.6.1.0","unix-2.8.4.0"]},{"type":"configured","id":"HUnit-1.6.2.0-d1570da0a2808fb4ce9b1c3f1e99a0cf4a27d7c4071d9714ae835af7748ace92","pkg-name":"HUnit","pkg-version":"1.6.2.0","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"1a79174e8af616117ad39464cac9de205ca923da6582825e97c10786fda933a4","pkg-src-sha256":"b0b7538871ffc058486fc00740886d2f3172f8fa6869936bfe83a5e10bd744ab","depends":["base-4.18.2.0","call-stack-0.4.0-a0fd887e5d06d11a75269d5dfed7da6fe2656edbbd7cc1697fb2a2b8ad4fe392","deepseq-1.4.8.1"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"JuicyPixels-3.3.8-295ba873739530be2ad2e0f5ef3880f23fb240b49297676915db7967d6106794","pkg-name":"JuicyPixels","pkg-version":"3.3.8","flags":{"mmap":false},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"c9721541b4c9d9de57dd271ead1f433cf3e3acc6c16baf2dba91368c8aa675bd","pkg-src-sha256":"d3a0f6ca3515a1b3d526cbf79f2e0b0aab57f208ab216f9c26437bbcd86fb63e","depends":["base-4.18.2.0","binary-0.8.9.1","bytestring-0.11.5.3","containers-0.6.7","deepseq-1.4.8.1","mtl-2.3.1","primitive-0.9.0.0-a6aa61bd9fff8d6cfd4880894dd85d8e644fbcf178b2bff38f87569871ea4a0d","transformers-0.6.1.0","vector-0.13.1.0-eb53bdac16f057ad838f4e8cb865b51b400abac71a36dc5bfde93ea1d0859eae","zlib-0.6.3.0-61cb40f46d103a622525dc3a70a9004984ec56d61deea65d2dc01c964606b7e9"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"OneTuple-0.4.1.1-8e8d21c288285c8a6e306ca430dcdc949a96b5c76772aaa2b31f79c6abb3541e","pkg-name":"OneTuple","pkg-version":"0.4.1.1","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"632dfded172086fb9f0e26d3578bcfffa3fb6d135ea5a8de17b7a33ff6e6e682","pkg-src-sha256":"c9e764d4ee1e57cad8341bd5d0de33ba3a52b6793fc1309679f2bf60c030bb2b","depends":["base-4.18.2.0","ghc-prim-0.10.0","template-haskell-2.20.0.0"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"Only-0.1-914e2ddfdd5fc0b9704050502cc99fcb5926b3ef60f86855ee94bd6fc8c46a18","pkg-name":"Only","pkg-version":"0.1","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"c6033d181e0f802e9e8543f683fa9c50aeb01cfdf6c83cd5bb72fb47aa863b07","pkg-src-sha256":"ab7aa193e8c257d3bda6b0b3c1cbcf74cdaa85ab08cb20c2dd62ba248c1ab265","depends":["base-4.18.2.0","deepseq-1.4.8.1"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"PyF-0.11.2.1-136109de9a2dff073e8ac6c2d415f86bbe2b3b9b72015bfb5fd638fdd22d1843","pkg-name":"PyF","pkg-version":"0.11.2.1","flags":{"python_test":false},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"3bd749eac5f91e44c148adf97f20c7424662e0cf1235d399f3f4848379c6038e","pkg-src-sha256":"e865c45a9323fc60f0a35f0aedf9e9f5c12258a6344bbd49031c09211b82220a","depends":["base-4.18.2.0","bytestring-0.11.5.3","ghc-9.6.4","mtl-2.3.1","parsec-3.1.16.1","template-haskell-2.20.0.0","text-2.0.2","time-1.12.2"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"QuickCheck-2.14.3-091d344acf9c963200a9b2af6c5417d91912262a9a84b607d918b50fdf8a8b02","pkg-name":"QuickCheck","pkg-version":"2.14.3","flags":{"old-random":false,"templatehaskell":true},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"f03d2f404d5ba465453d0fbc1944832789a759fe7c4f9bf8616bc1378a02fde4","pkg-src-sha256":"5c0f22b36b28a1a8fa110b3819818d3f29494a3b0dedbae299f064123ca70501","depends":["base-4.18.2.0","containers-0.6.7","deepseq-1.4.8.1","random-1.2.1.2-cc746490e13a1f967de173a54c09753b2ccdb5d95056b0f1206a29c62c83de45","splitmix-0.1.0.5-4c4c1f33537354cbf1e3da145a4775d1633faaa320080e06e92a1f67dbed4227","template-haskell-2.20.0.0","transformers-0.6.1.0"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"RSA-2.4.1-b4c924e20cf67b5e5898315a61da3d3144fe72c89c2d8d7467b5705a0e72d092","pkg-name":"RSA","pkg-version":"2.4.1","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"d2e711da52c19e332d374b3c0202a77d3088b59a0ba64abe6107569752fd1e24","pkg-src-sha256":"72c5d8c45ef1013e0e8aff763bb8894df0f022f28e698e33ae87bbdb33d69041","depends":["SHA-1.6.4.4-e6c31f0f5d851572b6ee53a36a002efa9780db2fdc8b31c1410f129bd3d58934","base-4.18.2.0","binary-0.8.9.1","bytestring-0.11.5.3","crypto-api-0.13.3-7a787ea36d9a45cc1748699175ede37f55426b32db3712140ca048f1a888c44f","crypto-pubkey-types-0.4.3-0e51728f266377e9408460fc3416717740bf7a0fd1ea1d3d056abfa0f9de4241"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"SHA-1.6.4.4-e6c31f0f5d851572b6ee53a36a002efa9780db2fdc8b31c1410f129bd3d58934","pkg-name":"SHA","pkg-version":"1.6.4.4","flags":{"exe":false},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"3b7523df3e2186ae8c5ac78c745efb586814afe9c775b886a747556d9f4d429c","pkg-src-sha256":"6bd950df6b11a3998bb1452d875d2da043ee43385459afc5f16d471d25178b44","depends":["array-0.5.6.0","base-4.18.2.0","binary-0.8.9.1","bytestring-0.11.5.3"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"StateVar-1.2.2-ad33ce876594474d931417853bfd72c6eb94d534a6634dcbf0af13ec95c0e031","pkg-name":"StateVar","pkg-version":"1.2.2","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"3c022c00485fe165e3080d5da6b3ca9c9b02f62c5deebc584d1b3d1309ce673e","pkg-src-sha256":"5e4b39da395656a59827b0280508aafdc70335798b50e5d6fd52596026251825","depends":["base-4.18.2.0","stm-2.5.1.0","transformers-0.6.1.0"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"abstract-deque-0.3-58da01f2d5856552665a639ed7e62652de2627cfca39d756a0f29f4265e71d1b","pkg-name":"abstract-deque","pkg-version":"0.3","flags":{"usecas":false},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"308bff92bb8b6621ed1dae718e859da145c8f31b8a9050aeacac40a8a21c9c90","pkg-src-sha256":"09aa10f38193a8275a7791b92a4f3a7192a304874637e2a35c897dde25d75ca2","depends":["array-0.5.6.0","base-4.18.2.0","containers-0.6.7","random-1.2.1.2-cc746490e13a1f967de173a54c09753b2ccdb5d95056b0f1206a29c62c83de45","time-1.12.2"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"adjunctions-4.4.2-f3221dcb76f82009b3161054c42f2ac113ea03b7e3e1a3d9dff315fac6299a27","pkg-name":"adjunctions","pkg-version":"4.4.2","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"30206ae6b78d3d523c2ff73640f84b51fa204ac3f05267a5f0c77c486b96781d","pkg-src-sha256":"147b5f8db810bca0ea8952ef974982ffc447cecd21f01e1ea1121df77e276518","depends":["array-0.5.6.0","base-4.18.2.0","comonad-5.0.8-8505feb1b75f0b6bf19ef9b666132d0031c1214df6db91aab78f0a9def57751c","containers-0.6.7","contravariant-1.5.5-45cb856efb41788f255562487551496b619a1cf555a23fc4a29495fda3e0c50f","distributive-0.6.2.1-70a2f4c4bffafd7749c1d755f27db885f954a9d9be1cd7db8a6e99887121ec8c","free-5.2-841f6f1c7522ed92dbed9d024b48671e79a9cdd76652f8bdbf9c0e63908771e7","mtl-2.3.1","profunctors-5.6.2-8b084a9552445e5776f01a7b42f1722ce1ecf20cf9a8e839007b9baea33b9fa4","semigroupoids-6.0.0.1-e83bc6491c75c3522014917ab4d3335127e2ee3b4989f0a49f9791f8bead28c6","semigroups-0.20-b7dd1b9febe28a509d4e029a8add1506aac955b99fce2599f25e63f8127812a9","tagged-0.8.8-5d06ce789c37adf39496775b08f7d82bb9509e4c2a3f973b0c868e35bca55ad5","transformers-0.6.1.0","transformers-compat-0.7.2-15ca92c51f3c4b3e5a349c3cc2a7f406ca01ba50aecd92a631a1c4d508b1230f","void-0.7.3-0dce7608060d286489a924498d4580dafe61112f075ee061dc6545c66ff6e691"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"aeson-2.2.1.0-2595d249b227784b9febcd5a91568775f66fd262ac45c82c44f7b4a55e9d4c27","pkg-name":"aeson","pkg-version":"2.2.1.0","flags":{"ordered-keymap":true},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"a23a61aada8233e10573e1612c0b2efe5a1aba0d59b05dbe2f63301822f136cb","pkg-src-sha256":"914eefd0e80d12db5c721daa2cbab427acee39795f125c5460c1fe48cf9a5d7f","depends":["OneTuple-0.4.1.1-8e8d21c288285c8a6e306ca430dcdc949a96b5c76772aaa2b31f79c6abb3541e","QuickCheck-2.14.3-091d344acf9c963200a9b2af6c5417d91912262a9a84b607d918b50fdf8a8b02","base-4.18.2.0","bytestring-0.11.5.3","containers-0.6.7","data-fix-0.3.2-5add57223d3c0b4ba49ecf522767d4a71475f5e86cefa1a15e9af611e468b46f","deepseq-1.4.8.1","dlist-1.0-1ec91dd3ad8405ed390138bce1c7d55220d4758eda9fb3ad6fbb8b1ee6dc0c94","exceptions-0.10.7","generically-0.1.1-bdc1b22218832bf69277f07778576bdaa3d8df05d3081150e9ff6dabe4f79249","ghc-prim-0.10.0","hashable-1.4.3.0-17b447e0ce504d4e093d6bf5a9838da3805c7caa5d16355da40827d004febbc8","indexed-traversable-0.1.3-8f7210e35c0cb4bf73ec163bed4014cbba70e17aa189447497a492e60990637b","integer-conversion-0.1.0.1-8c064ed0d1fb658105e6fb4ccc9c29b5609d33ee30393dfe431660a716d124d0","integer-logarithms-1.0.3.1-49bf09c2474200e80cd296b047116a8ad20403e42301ba2d71d615b2824b3fcd","network-uri-2.6.4.2-d62d36021f4a84b02c9243cbe37e9dfd5b7ba840b4aaedb5e002f05582564fc4","primitive-0.9.0.0-a6aa61bd9fff8d6cfd4880894dd85d8e644fbcf178b2bff38f87569871ea4a0d","scientific-0.3.7.0-ad7c6f4dff0f6cf6540942c40157e54f8c090b5d960104c70801b0a2f7c99215","semialign-1.3-d56979a02604b49151cb0b8ca42b64e13b0f633dac64c7e0a9a02902d973b559","strict-0.5-84b2c7152a9fd6aee3e1d1082edade7580c5af3226a0afc18e19724ada9d7fe4","tagged-0.8.8-5d06ce789c37adf39496775b08f7d82bb9509e4c2a3f973b0c868e35bca55ad5","template-haskell-2.20.0.0","text-2.0.2","text-iso8601-0.1-ca672f6e92319e19ff854d44b5ac9b4e7c827c1996a06b87b8a221dbacac85fb","text-short-0.1.5-e014e79f76c5438274db6ad0455e870f44faf95f73a43bdf4e1c22851755dbaa","th-abstraction-0.6.0.0-b49a83d27ea2604c7977c309bd302e93941309c5040c248dbdb6b55147976b2b","these-1.2-a7d4e934136841dac2b8ed0dc77fee3f581d8c4e25fe99bdad5b76406c57bf16","time-1.12.2","time-compat-1.9.6.1-2b2aa066adc7c0d5baad9d0716626a41574966c2265b4ff355b83a2bfd5ca61a","unordered-containers-0.2.20-013ecc3e94c07bd5bdb23da8c9cf4d68ac66e04c4144b4096b291104672db345","uuid-types-1.0.5.1-c19e00cab51fb72d8874dd99ac787f44fda9996af8117c2d227cfb3294e06a9c","vector-0.13.1.0-eb53bdac16f057ad838f4e8cb865b51b400abac71a36dc5bfde93ea1d0859eae","witherable-0.4.2-1767ce3334bad414dff74c30d2272bb1f265e0098708c8aa764f138b1a282619"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"aeson-pretty-0.8.10-9bd6a60b424b6a69fcd0507ef3b99938ee971580bc5bfa89249b16ff60b2c117","pkg-name":"aeson-pretty","pkg-version":"0.8.10","flags":{"lib-only":false},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"6b0d3c1004dc696cdfea45b442dd025b5ca62ecce44bf8669775529d5b672114","pkg-src-sha256":"2a21f2cd78adcb149ceba770239ed664519552911e7680172b18ff695cfa7ae5","depends":["aeson-2.2.1.0-2595d249b227784b9febcd5a91568775f66fd262ac45c82c44f7b4a55e9d4c27","base-4.18.2.0","base-compat-0.13.1-f0385202d32a5d6c7b36f9e6f39a361e139bf7a5858ef12f1c89ce0c83283469","bytestring-0.11.5.3","scientific-0.3.7.0-ad7c6f4dff0f6cf6540942c40157e54f8c090b5d960104c70801b0a2f7c99215","text-2.0.2","unordered-containers-0.2.20-013ecc3e94c07bd5bdb23da8c9cf4d68ac66e04c4144b4096b291104672db345","vector-0.13.1.0-eb53bdac16f057ad838f4e8cb865b51b400abac71a36dc5bfde93ea1d0859eae"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"aeson-pretty-0.8.10-e-aeson-pretty-b5fd8b2889d4e80f43983202a91dcfdb587598c0ed194ffee06d355a65ed67f9","pkg-name":"aeson-pretty","pkg-version":"0.8.10","flags":{"lib-only":false},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"6b0d3c1004dc696cdfea45b442dd025b5ca62ecce44bf8669775529d5b672114","pkg-src-sha256":"2a21f2cd78adcb149ceba770239ed664519552911e7680172b18ff695cfa7ae5","depends":["aeson-2.2.1.0-2595d249b227784b9febcd5a91568775f66fd262ac45c82c44f7b4a55e9d4c27","aeson-pretty-0.8.10-9bd6a60b424b6a69fcd0507ef3b99938ee971580bc5bfa89249b16ff60b2c117","attoparsec-0.14.4-5061b5f729de9f72f69961345d54e0249a28df7c232bb9cf2b0525b6f17a253a","attoparsec-aeson-2.2.0.1-768c79d04d1cb0ad1b116957e8c9aabf909372ca2c907dc42310e8efd0a37a03","base-4.18.2.0","bytestring-0.11.5.3","cmdargs-0.10.22-f5bcda1abe20b4892a5dd9a037b87b25157ad0148e6ed24d10071b61bda0375c"],"exe-depends":[],"component-name":"exe:aeson-pretty","bin-file":"/home/hecate/Projects/Flora/1-flora-server/_build/cabal-store/ghc-9.6.4/aeson-pretty-0.8.10-e-aeson-pretty-b5fd8b2889d4e80f43983202a91dcfdb587598c0ed194ffee06d355a65ed67f9/bin/aeson-pretty"},{"type":"configured","id":"ansi-terminal-1.0.2-f2271bf25e5299c165409ab78d5917aeba79c479959932bb5fb284c513226fc0","pkg-name":"ansi-terminal","pkg-version":"1.0.2","flags":{"example":false},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"1f90bb88e670ce63fbf2c9216d50857f2419582f1c6791e542c3eab97ecfd364","pkg-src-sha256":"46e516cbf66c7807940ba9896c2d71ba5ffdaa35a4fb80dea9313703efa8d834","depends":["ansi-terminal-types-0.11.5-a44e7be0d661302c2158cac2d1ab7efe513e657bcc7a366e4c289e6e43a0b2f6","base-4.18.2.0","colour-2.3.6-b9efcf2f194d8cd3334d28c9a0c2645a368b8c516a5d80ca0692194cbd33006d"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"ansi-terminal-types-0.11.5-a44e7be0d661302c2158cac2d1ab7efe513e657bcc7a366e4c289e6e43a0b2f6","pkg-name":"ansi-terminal-types","pkg-version":"0.11.5","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"f78440dfd95c4509e88855ac7cc2d9566ddf956a92c1290404cac93ad1a1b00a","pkg-src-sha256":"bf7b230389f43105100a6d5740822598a88b38eaaf7d042de595ccf72db4fdd1","depends":["base-4.18.2.0","colour-2.3.6-b9efcf2f194d8cd3334d28c9a0c2645a368b8c516a5d80ca0692194cbd33006d"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"appar-0.1.8-588a61c15c8bd457e6a1dd16deebaeef67d39cbf3527f952054c1230e05fa294","pkg-name":"appar","pkg-version":"0.1.8","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"a5d529bacbb74d566e4c5f9479af0637eac5957705f6db4d2670517489795de8","pkg-src-sha256":"c4ceeddc26525b58d82c41b6d3e32141371a200a6794aae185b6266ccc81631f","components":{"lib":{"depends":["base-4.18.2.0","bytestring-0.11.5.3"],"exe-depends":[]}}},{"type":"pre-existing","id":"array-0.5.6.0","pkg-name":"array","pkg-version":"0.5.6.0","depends":["base-4.18.2.0"]},{"type":"configured","id":"asn1-encoding-0.9.6-9bf64732d7af18045ee22a12f781934262d76015cf823acd133e41c1341a5fb9","pkg-name":"asn1-encoding","pkg-version":"0.9.6","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"27ed8f6043aed79630313bb931f7c8e2b510f0b4586cd55c16ae040c7d1ea098","pkg-src-sha256":"d9f8deabd3b908e5cf83c0d813c08dc0143b3ec1c0d97f660d2cfa02c1c8da0a","depends":["asn1-types-0.3.4-09d5674972306ee58c9f15c425744939cc04dad257e3b9dd8f0168fbdc38ab70","base-4.18.2.0","bytestring-0.11.5.3","hourglass-0.2.12-ff77f9ff09de83d24a0ee40cfa0cec90de8666d5167809a314d26ad4a7544cdd"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"asn1-parse-0.9.5-2a949cca1e96d33a3cea78e8f484af2b63e4592b43690a951c967874e85dcf09","pkg-name":"asn1-parse","pkg-version":"0.9.5","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"77c0126d63070df2d82cb4cfa4febb26c4e280f6d854bc778c2fa4d80ce692b8","pkg-src-sha256":"8f1fe1344d30b39dc594d74df2c55209577722af1497204b4c2b6d6e8747f39e","components":{"lib":{"depends":["asn1-encoding-0.9.6-9bf64732d7af18045ee22a12f781934262d76015cf823acd133e41c1341a5fb9","asn1-types-0.3.4-09d5674972306ee58c9f15c425744939cc04dad257e3b9dd8f0168fbdc38ab70","base-4.18.2.0","bytestring-0.11.5.3"],"exe-depends":[]}}},{"type":"configured","id":"asn1-types-0.3.4-09d5674972306ee58c9f15c425744939cc04dad257e3b9dd8f0168fbdc38ab70","pkg-name":"asn1-types","pkg-version":"0.3.4","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"8e879b3a5bbdd0031232eb84d904b5a3a2c20a18847692b996d774f4ff811355","pkg-src-sha256":"78ee92a251379298ca820fa53edbf4b33c539b9fcd887c86f520c30e3b4e21a8","components":{"lib":{"depends":["base-4.18.2.0","bytestring-0.11.5.3","hourglass-0.2.12-ff77f9ff09de83d24a0ee40cfa0cec90de8666d5167809a314d26ad4a7544cdd","memory-0.18.0-273ad672f1703dee0dfe07994633c93d17f815a149738659ef6afa30cbe4f6a8"],"exe-depends":[]}}},{"type":"configured","id":"assoc-1.1-44564689989a4d2721c54fe7433f3b2450e556c3fe6c52752ad54623647f561c","pkg-name":"assoc","pkg-version":"1.1","flags":{"tagged":true},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"56d0fd1c17aaf6268e81bf19ba5afe186128d7f88126bd546d5b3151ab692652","pkg-src-sha256":"7aa2e6548b3d9d49a286ac20639479aaf6c47a1446113ed784d98737c5f60df4","depends":["base-4.18.2.0","tagged-0.8.8-5d06ce789c37adf39496775b08f7d82bb9509e4c2a3f973b0c868e35bca55ad5"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"async-2.2.4-2107e60f1bee7c70ffed77e551ffc7db01e350edd8784cc9493cc782305122d0","pkg-name":"async","pkg-version":"2.2.4","flags":{"bench":false},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"9b8ceefce014e490f9e1335fa5f511161309926c55d01cec795016f4363b5d2d","pkg-src-sha256":"484df85be0e76c4fed9376451e48e1d0c6e97952ce79735b72d54297e7e0a725","depends":["base-4.18.2.0","hashable-1.4.3.0-17b447e0ce504d4e093d6bf5a9838da3805c7caa5d16355da40827d004febbc8","stm-2.5.1.0"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"atomic-primops-0.8.5-619a7ba3c59ea074ae39e3adf75904b21a27146e973f334ea4ab876a9cc1e3c2","pkg-name":"atomic-primops","pkg-version":"0.8.5","flags":{"debug":false},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"6496469ffe3847c71b38283d33e3bb392cc90e23fa0083c8ef0f8e509c57fe3c","pkg-src-sha256":"1ca55794c3adb8077c747e7cf1b3083b9938dbdadeab27555babbfdc87fa8b1f","depends":["base-4.18.2.0","ghc-prim-0.10.0","primitive-0.9.0.0-a6aa61bd9fff8d6cfd4880894dd85d8e644fbcf178b2bff38f87569871ea4a0d"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"attoparsec-0.14.4-5061b5f729de9f72f69961345d54e0249a28df7c232bb9cf2b0525b6f17a253a","pkg-name":"attoparsec","pkg-version":"0.14.4","flags":{"developer":false},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"ec709539b881d6431620bd7c40fbfa680aaf4a98c6f35b51536d8f455682b1ae","pkg-src-sha256":"3f337fe58624565de12426f607c23e60c7b09c86b4e3adfc827ca188c9979e6c","depends":["array-0.5.6.0","attoparsec-0.14.4-l-attoparsec-internal-f600b7076f93db9231c3b18ae83441a8fa6c0ca8eb782110fd08fd0479e72589","base-4.18.2.0","bytestring-0.11.5.3","containers-0.6.7","deepseq-1.4.8.1","ghc-prim-0.10.0","scientific-0.3.7.0-ad7c6f4dff0f6cf6540942c40157e54f8c090b5d960104c70801b0a2f7c99215","text-2.0.2","transformers-0.6.1.0"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"attoparsec-0.14.4-l-attoparsec-internal-f600b7076f93db9231c3b18ae83441a8fa6c0ca8eb782110fd08fd0479e72589","pkg-name":"attoparsec","pkg-version":"0.14.4","flags":{"developer":false},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"ec709539b881d6431620bd7c40fbfa680aaf4a98c6f35b51536d8f455682b1ae","pkg-src-sha256":"3f337fe58624565de12426f607c23e60c7b09c86b4e3adfc827ca188c9979e6c","depends":["array-0.5.6.0","base-4.18.2.0","bytestring-0.11.5.3","text-2.0.2"],"exe-depends":[],"component-name":"lib:attoparsec-internal"},{"type":"configured","id":"attoparsec-aeson-2.2.0.1-768c79d04d1cb0ad1b116957e8c9aabf909372ca2c907dc42310e8efd0a37a03","pkg-name":"attoparsec-aeson","pkg-version":"2.2.0.1","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"00026bb205aaa087215a4c3a65a62c4561c3fb58e882778c9607c63e2aa960e9","pkg-src-sha256":"cfc5f23a7b45d00c1121cbd94aef7ff0b3d997039931862c460340599a01c409","depends":["aeson-2.2.1.0-2595d249b227784b9febcd5a91568775f66fd262ac45c82c44f7b4a55e9d4c27","attoparsec-0.14.4-5061b5f729de9f72f69961345d54e0249a28df7c232bb9cf2b0525b6f17a253a","base-4.18.2.0","bytestring-0.11.5.3","integer-conversion-0.1.0.1-8c064ed0d1fb658105e6fb4ccc9c29b5609d33ee30393dfe431660a716d124d0","primitive-0.9.0.0-a6aa61bd9fff8d6cfd4880894dd85d8e644fbcf178b2bff38f87569871ea4a0d","scientific-0.3.7.0-ad7c6f4dff0f6cf6540942c40157e54f8c090b5d960104c70801b0a2f7c99215","text-2.0.2","vector-0.13.1.0-eb53bdac16f057ad838f4e8cb865b51b400abac71a36dc5bfde93ea1d0859eae"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"authenticate-oauth-1.7-17cbc43210a12a6ae641a7faea62b4f2f2c36ac4c243d15ee4ff7bbccaf8c6d1","pkg-name":"authenticate-oauth","pkg-version":"1.7","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"af2b03698756b2bbb42b8d30236b4d012e31db2b7ce63753158f63d5b0a81da5","pkg-src-sha256":"746ff695fec1bd7c7b90f1952847ce3453fadf0f18a31db206753360b3219b78","depends":["RSA-2.4.1-b4c924e20cf67b5e5898315a61da3d3144fe72c89c2d8d7467b5705a0e72d092","SHA-1.6.4.4-e6c31f0f5d851572b6ee53a36a002efa9780db2fdc8b31c1410f129bd3d58934","base-4.18.2.0","base64-bytestring-1.2.1.0-ecb3bf792eac6ec696f20e02e528e8a7b2a76a5b32c46409c4645e1bfbd71cf4","blaze-builder-0.4.2.3-60676f992d653075aeba6aad80b2dd0b054859608a5712ecfc9d4a4968aefdb8","bytestring-0.11.5.3","crypto-pubkey-types-0.4.3-0e51728f266377e9408460fc3416717740bf7a0fd1ea1d3d056abfa0f9de4241","data-default-0.7.1.1-fb1a461d5390de89b4af18b225f51df41ca3a345d820ee4756653e4cd2f3cd8e","http-client-0.7.16-08ac6af6261aa24f586bbb528e8ea2f0bd2e7510d1883948d770173e7ea8b633","http-types-0.12.4-0f52a9ec33f3c65ef0b77ad8ce14b65f9164f8a761e42800dc9c80ee1768aacc","random-1.2.1.2-cc746490e13a1f967de173a54c09753b2ccdb5d95056b0f1206a29c62c83de45","time-1.12.2","transformers-0.6.1.0","transformers-compat-0.7.2-15ca92c51f3c4b3e5a349c3cc2a7f406ca01ba50aecd92a631a1c4d508b1230f"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"auto-update-0.1.6-3f7af882e90ee16fd9e6ebf1ca739ba4ad18afcdae045a3375fe3adefea17239","pkg-name":"auto-update","pkg-version":"0.1.6","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"10adca282e131a2fa01fb7a411b02811685c1cea02e9813df2d7fb468b5ef638","pkg-src-sha256":"f4e023dc8713c387ecf20d851247597fd012cabea3872310b35e911105eb66c4","depends":["base-4.18.2.0"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"barbies-2.1.1.0-a2e90384bd5520adcdbd08bf5d3ad4beac274ed17c2784dd44f1bf5a9ba6ef3f","pkg-name":"barbies","pkg-version":"2.1.1.0","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"ec928dbc06fa00e1f323b9b7f4f5ba3cffcaa1e0d7d3cc275789a40a5a32f053","pkg-src-sha256":"73972093f6a5f8e8daaeb5f1058abbd0944d3fcb9f073f2ad3cdb94095d4d2b7","depends":["base-4.18.2.0","distributive-0.6.2.1-70a2f4c4bffafd7749c1d755f27db885f954a9d9be1cd7db8a6e99887121ec8c","transformers-0.6.1.0"],"exe-depends":[],"component-name":"lib"},{"type":"pre-existing","id":"base-4.18.2.0","pkg-name":"base","pkg-version":"4.18.2.0","depends":["ghc-bignum-1.3","ghc-prim-0.10.0","rts-1.0.2"]},{"type":"configured","id":"base-compat-0.13.1-f0385202d32a5d6c7b36f9e6f39a361e139bf7a5858ef12f1c89ce0c83283469","pkg-name":"base-compat","pkg-version":"0.13.1","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"70632b4e8d8355a1993d3a1bffd8a2022570c859b486b5d114021ee838427940","pkg-src-sha256":"db1d9e8d56c8bb0066d313a3b5bc4143c021698d377f4c51b3ba010cff1e8421","depends":["base-4.18.2.0","ghc-prim-0.10.0","unix-2.8.4.0"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"base-compat-batteries-0.13.1-25e7385abd281169497a6f5094374b17c8dd67030772349b80bd82c47b483cae","pkg-name":"base-compat-batteries","pkg-version":"0.13.1","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"19463f09774812886b51be4c02d524063454a0dfaec3bfc6df7fb40520fafecd","pkg-src-sha256":"3e525b51a1db32a0d5d826ee3000e8436aa142505f24467737b9519545a7a802","depends":["base-4.18.2.0","base-compat-0.13.1-f0385202d32a5d6c7b36f9e6f39a361e139bf7a5858ef12f1c89ce0c83283469","ghc-prim-0.10.0"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"base-orphans-0.9.1-61d128d6a3318593c785a97751f2418cc86b42b03e2b46ed92e9b27fc5da689c","pkg-name":"base-orphans","pkg-version":"0.9.1","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"c4733d09f798fc4304e936924a1a7d9fc2425aefad6c46ad4592035254b46051","pkg-src-sha256":"5bbf2da382c5b212d6a8be2f8c49edee0eba30f272a15fd32c13e6e4091ef172","depends":["base-4.18.2.0","ghc-prim-0.10.0"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"base16-1.0-a724bafd7515d95cb8fc6e89e9d0f282f5ab5b792fe4d5387e65ac02f31e861c","pkg-name":"base16","pkg-version":"1.0","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"9366318622ec10e124929591015f1814e48c882a59d33ac612213935e8902003","pkg-src-sha256":"86366364910b78609677817cf3f987bf1690e1f75bba04bc91a5ed993d619cde","depends":["base-4.18.2.0","bytestring-0.11.5.3","deepseq-1.4.8.1","primitive-0.9.0.0-a6aa61bd9fff8d6cfd4880894dd85d8e644fbcf178b2bff38f87569871ea4a0d","text-2.0.2","text-short-0.1.5-e014e79f76c5438274db6ad0455e870f44faf95f73a43bdf4e1c22851755dbaa"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"base16-bytestring-1.0.2.0-b470eb3428775005093b18dbb34dd687b575cadcc3d709cf63c09611d917e654","pkg-name":"base16-bytestring","pkg-version":"1.0.2.0","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"a694e88f9ec9fc79f0b03f233d3fea592b68f70a34aac2ddb5bcaecb6562e2fd","pkg-src-sha256":"1d5a91143ef0e22157536093ec8e59d226a68220ec89378d5dcaeea86472c784","depends":["base-4.18.2.0","bytestring-0.11.5.3"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"base32-0.4-3d897481f9dfd13903e614afd99fb6b4ab13c775030063f288dd112a84583017","pkg-name":"base32","pkg-version":"0.4","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"123184f74db39ca58ccc3f9a3952497e585f49c693ebd83ba33db3477854f09e","pkg-src-sha256":"9ae7861d509528d3e8f4ecd946051b05f7141e907216e672d18e26d242a908d4","depends":["base-4.18.2.0","bytestring-0.11.5.3","deepseq-1.4.8.1","text-2.0.2","text-short-0.1.5-e014e79f76c5438274db6ad0455e870f44faf95f73a43bdf4e1c22851755dbaa"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"base64-1.0-dd5d13a79aacb87c11501514ee42d94f31fb8135c9427a7dddef0b4e4e537062","pkg-name":"base64","pkg-version":"1.0","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"304b260d9dba7cb04118e6fe84e1eb2de72212461460e4eea3684115c059dfa6","pkg-src-sha256":"7942239f1804945fd6d319a953f26c53b64518076cd294141fda983f2ff1b2b6","depends":["base-4.18.2.0","bytestring-0.11.5.3","deepseq-1.4.8.1","text-2.0.2","text-short-0.1.5-e014e79f76c5438274db6ad0455e870f44faf95f73a43bdf4e1c22851755dbaa"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"base64-bytestring-1.2.1.0-ecb3bf792eac6ec696f20e02e528e8a7b2a76a5b32c46409c4645e1bfbd71cf4","pkg-name":"base64-bytestring","pkg-version":"1.2.1.0","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"45305ccf8914c66d385b518721472c7b8c858f1986945377f74f85c1e0d49803","pkg-src-sha256":"fbf8ed30edde271eb605352021431d8f1b055f95a56af31fe2eacf6bdfdc49c9","depends":["base-4.18.2.0","bytestring-0.11.5.3"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"basement-0.0.16-2ba9d181df7bdd547d6fedd5acdec581f03e379e22b0e08ff998fb0462257d08","pkg-name":"basement","pkg-version":"0.0.16","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"e9458cbe67f396fb81900ec65852a582a2b7febd09b17a85adee576c8d7cc321","pkg-src-sha256":"7fb77e249aef76ba5aed3059d556800ce02b614597c488ba01f0a16449146300","depends":["base-4.18.2.0","ghc-prim-0.10.0"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"bifunctors-5.6.1-3bfddc97d0532e0f4bedd1f64454f96744d2fe805f93a5f9e443c2c5e1035ff1","pkg-name":"bifunctors","pkg-version":"5.6.1","flags":{"tagged":true},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"82fa7ed8f69f0bfa375de117ab36414c0b96a97ee046edc3ac6da7a295a94755","pkg-src-sha256":"06381471b5be16516a1b2c4b21a5101a3d991038bface8e0cad144c0044d57fc","depends":["assoc-1.1-44564689989a4d2721c54fe7433f3b2450e556c3fe6c52752ad54623647f561c","base-4.18.2.0","comonad-5.0.8-8505feb1b75f0b6bf19ef9b666132d0031c1214df6db91aab78f0a9def57751c","containers-0.6.7","tagged-0.8.8-5d06ce789c37adf39496775b08f7d82bb9509e4c2a3f973b0c868e35bca55ad5","template-haskell-2.20.0.0","th-abstraction-0.6.0.0-b49a83d27ea2604c7977c309bd302e93941309c5040c248dbdb6b55147976b2b","transformers-0.6.1.0"],"exe-depends":[],"component-name":"lib"},{"type":"pre-existing","id":"binary-0.8.9.1","pkg-name":"binary","pkg-version":"0.8.9.1","depends":["array-0.5.6.0","base-4.18.2.0","bytestring-0.11.5.3","containers-0.6.7"]},{"type":"configured","id":"bitvec-1.1.5.0-134351d7461857a38c09b3cd302761a8b59d5482f7705b4680a47926f8628740","pkg-name":"bitvec","pkg-version":"1.1.5.0","flags":{"simd":true},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"7c5639f95c8ce9d5be810152bfcaf701aac3b7d7f08685a869c7eda63dc2cd76","pkg-src-sha256":"83d27cee5be1d5342ddbf39999d0c8ea54cb433d0891eea5471fbfaa29f8dec5","depends":["base-4.18.2.0","bytestring-0.11.5.3","deepseq-1.4.8.1","ghc-bignum-1.3","primitive-0.9.0.0-a6aa61bd9fff8d6cfd4880894dd85d8e644fbcf178b2bff38f87569871ea4a0d","vector-0.13.1.0-eb53bdac16f057ad838f4e8cb865b51b400abac71a36dc5bfde93ea1d0859eae"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"blaze-builder-0.4.2.3-60676f992d653075aeba6aad80b2dd0b054859608a5712ecfc9d4a4968aefdb8","pkg-name":"blaze-builder","pkg-version":"0.4.2.3","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"3f2ff408e858e3ecac30183f98bbb14ce6cf6314c654bd9107e51defd386d5ef","pkg-src-sha256":"66291874236b7342adab033e3cddae414a23a2865dfb44095dfc4e0b9d46703b","depends":["base-4.18.2.0","bytestring-0.11.5.3","deepseq-1.4.8.1","ghc-prim-0.10.0","text-2.0.2"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"blaze-html-0.9.1.2-3a4f994094b15669094f06ad98d568adb79b03a7829eff4349476c2fafb25845","pkg-name":"blaze-html","pkg-version":"0.9.1.2","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"2e40ad3828320b72122f09754091fb686fa0fd4c083769f17ef84584972ec450","pkg-src-sha256":"60503f42546c6c1b954014d188ea137e43d74dcffd2bf6157c113fd91a0c394c","depends":["base-4.18.2.0","blaze-builder-0.4.2.3-60676f992d653075aeba6aad80b2dd0b054859608a5712ecfc9d4a4968aefdb8","blaze-markup-0.8.3.0-2e784e1507a2d7d5a307522e712dffb50117e7a08a6219ee2f5a0daa30ff9ab0","bytestring-0.11.5.3","text-2.0.2"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"blaze-markup-0.8.3.0-2e784e1507a2d7d5a307522e712dffb50117e7a08a6219ee2f5a0daa30ff9ab0","pkg-name":"blaze-markup","pkg-version":"0.8.3.0","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"a8365ac8b98738065c2867682dbcd9b0baeb7a5cd1eaa8e508279edfd19227b9","pkg-src-sha256":"8606ac8b4a1f7f8f1bbc0770b2752e9b6f88ccc9fbdcbb33aa20577d0e5930e8","depends":["base-4.18.2.0","blaze-builder-0.4.2.3-60676f992d653075aeba6aad80b2dd0b054859608a5712ecfc9d4a4968aefdb8","bytestring-0.11.5.3","text-2.0.2"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"boring-0.2.1-9a8dc8e41ea918a09754ff07614d4843b0ebe75d8757fd3273e17938f5bf6233","pkg-name":"boring","pkg-version":"0.2.1","flags":{"tagged":true},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"9e2566d93e8db00ea7c428bf6a4052f8479ef6b6a86294d65c6086d45a842e4b","pkg-src-sha256":"b1ffddf0f9d50ac8742aa01b270856d57937cc8f7aae783e3b5f3abee7aa3154","depends":["base-4.18.2.0","tagged-0.8.8-5d06ce789c37adf39496775b08f7d82bb9509e4c2a3f973b0c868e35bca55ad5","transformers-0.6.1.0"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"bsb-http-chunked-0.0.0.4-f0471e0efa2dd6ebef9e206b6727cf6fe5e8a009c301af9a3b7199515a1e2c08","pkg-name":"bsb-http-chunked","pkg-version":"0.0.0.4","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"1cce7371c31b1d3cfa3eb155e2aecffc0ec212d1d8a7e7c8a3b00ef76818a43b","pkg-src-sha256":"148309e23eb8b261c1de374712372d62d8c8dc8ee504c392809c7ec33c0a0e7c","depends":["base-4.18.2.0","bytestring-0.11.5.3"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"bytebuild-0.3.16.2-cdc53c5f9fe77d8a2e07a053df6e6cc49bf0b599080e951bea083f37245f23ad","pkg-name":"bytebuild","pkg-version":"0.3.16.2","flags":{"checked":false},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"313814827be2536850fe6fd5b9b53174f44cb7988475724fdbb15e2ed79c575a","pkg-src-sha256":"2cb53fb854682ee38bccd560291ebd0651b4d54d6ba27f9e2a17b5168ed49687","depends":["base-4.18.2.0","byteslice-0.2.13.2-93a4f1e735c3da2a6b67f70d01ac2fe3652393dc05bb13f3b274ebaf67729ba4","bytestring-0.11.5.3","haskell-src-meta-0.8.13-d3053a08f8d9deda4e92997b870b23096956d6c11736d5eed8f387ed509f1133","integer-logarithms-1.0.3.1-49bf09c2474200e80cd296b047116a8ad20403e42301ba2d71d615b2824b3fcd","natural-arithmetic-0.2.1.0-327b3d0462a9fdccd1f5901b636a5c6f1c1996b903146b3f4bf006389c9d4483","primitive-0.9.0.0-a6aa61bd9fff8d6cfd4880894dd85d8e644fbcf178b2bff38f87569871ea4a0d","primitive-offset-0.2.0.0-b93fd3063a232ecde01c2f1c6c7f349f7bbfba6a51590e6011e8c669dc2ff008","run-st-0.1.3.3-af1ad044a973fec4afa0830cc37bb6f0f7961cd9e6ffb5b32198ce4b6d73c331","template-haskell-2.20.0.0","text-2.0.2","text-short-0.1.5-e014e79f76c5438274db6ad0455e870f44faf95f73a43bdf4e1c22851755dbaa","wide-word-0.1.6.0-701ecedac0a6c9b47e334c978d1acbc2be6ad5ec17436c6d5c3ac80532b45795","zigzag-0.1.0.0-566d257af37db43b1ea7fe61e93ddea5f662ad8c5b1df04c1e845b14b13bcf67"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"byteorder-1.0.4-fa2515b96f172f97bd2e2638b538e2286cb035eb8b87892a4857a50c6e738631","pkg-name":"byteorder","pkg-version":"1.0.4","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"a952817dcbe20af0346fb55a28c13e95e2ddbf3e99f9b4fffdc063f150f13b20","pkg-src-sha256":"bd20bbb586947f99c38a4c93d9d0266f49f6fc581767b51ba568f6d5d52d2919","components":{"lib":{"depends":["base-4.18.2.0"],"exe-depends":[]}}},{"type":"configured","id":"byteslice-0.2.13.2-93a4f1e735c3da2a6b67f70d01ac2fe3652393dc05bb13f3b274ebaf67729ba4","pkg-name":"byteslice","pkg-version":"0.2.13.2","flags":{"avoid-rawmemchr":true},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"0dd9dc4bf4679b9ae413b97bf22140adac6278807759329cc1b2ee791b150079","pkg-src-sha256":"67c7b30f862aad1deef05f807d438db57866ca99d3d0461716d9666d21943ffc","depends":["base-4.18.2.0","bytestring-0.11.5.3","natural-arithmetic-0.2.1.0-327b3d0462a9fdccd1f5901b636a5c6f1c1996b903146b3f4bf006389c9d4483","primitive-0.9.0.0-a6aa61bd9fff8d6cfd4880894dd85d8e644fbcf178b2bff38f87569871ea4a0d","primitive-addr-0.1.0.2-1d786758faf617b086ce4cbc72b559d853b44b3c0637695f91811d3095dde6e1","primitive-unlifted-2.1.0.0-aea76574320ac1dea77e342956c3de02d6d7ed0b25f80413b31e3a4622eea123","run-st-0.1.3.3-af1ad044a973fec4afa0830cc37bb6f0f7961cd9e6ffb5b32198ce4b6d73c331","text-2.0.2","text-short-0.1.5-e014e79f76c5438274db6ad0455e870f44faf95f73a43bdf4e1c22851755dbaa","tuples-0.1.0.0-c9da1e31c493a9db3a026d6ed37a9f2e238abe29b118611180b8b3b5a28d1337","vector-0.13.1.0-eb53bdac16f057ad838f4e8cb865b51b400abac71a36dc5bfde93ea1d0859eae"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"bytesmith-0.3.11.0-110aed7be9e82cf40e2b317b574dcf8dfef014f7e0dbb78475aca851e3d498dd","pkg-name":"bytesmith","pkg-version":"0.3.11.0","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"4680a3268248b87376db1faa940fb3248a517b14eb9c014d6f2181e723c8a9ed","pkg-src-sha256":"7f6bd1b77dcb1428c9e10d073646c757046c46b41aeb21e6c34e7796db7d3a31","depends":["base-4.18.2.0","byteslice-0.2.13.2-93a4f1e735c3da2a6b67f70d01ac2fe3652393dc05bb13f3b274ebaf67729ba4","bytestring-0.11.5.3","contiguous-0.6.4.2-05fdf6e288b8c7809eb95c94784c40e7f5746e0c73b7ad5b8a9f9a3c7449d34f","natural-arithmetic-0.2.1.0-327b3d0462a9fdccd1f5901b636a5c6f1c1996b903146b3f4bf006389c9d4483","primitive-0.9.0.0-a6aa61bd9fff8d6cfd4880894dd85d8e644fbcf178b2bff38f87569871ea4a0d","run-st-0.1.3.3-af1ad044a973fec4afa0830cc37bb6f0f7961cd9e6ffb5b32198ce4b6d73c331","text-short-0.1.5-e014e79f76c5438274db6ad0455e870f44faf95f73a43bdf4e1c22851755dbaa","wide-word-0.1.6.0-701ecedac0a6c9b47e334c978d1acbc2be6ad5ec17436c6d5c3ac80532b45795"],"exe-depends":[],"component-name":"lib"},{"type":"pre-existing","id":"bytestring-0.11.5.3","pkg-name":"bytestring","pkg-version":"0.11.5.3","depends":["base-4.18.2.0","deepseq-1.4.8.1","ghc-prim-0.10.0","template-haskell-2.20.0.0"]},{"type":"configured","id":"bytestring-builder-0.10.8.2.0-e19114b40bd07b22b89d1b66ea0a2320498dd92342a0ffbe5a84431b412d2a4c","pkg-name":"bytestring-builder","pkg-version":"0.10.8.2.0","flags":{"bytestring_has_builder":true},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"6b2b812cdac53f5a2c82376a416dde04adbb5ca3e1604c0d075368a0498f762b","pkg-src-sha256":"27faef6db27c5be5a3715fd68b93725853e0e668849eaf92ce7c33cef9cb2c3f","depends":["base-4.18.2.0","bytestring-0.11.5.3","deepseq-1.4.8.1"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"cabal-doctest-1.0.9-4a685fb2745cdab49526ff8fe3801bf6bd4ab5085239033fcfd51613f7e3fd76","pkg-name":"cabal-doctest","pkg-version":"1.0.9","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"6dea0dbd1457f43d96ce1cfb1bab8b9f55d4fb82940e2bfa5aad78e6e2260656","pkg-src-sha256":"5556088496111d33810c4ae6c4a065bb37fa3315e9e8891e8000b1ab6707ba73","depends":["Cabal-3.10.1.0","base-4.18.2.0","directory-1.3.8.1","filepath-1.4.200.1"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"call-stack-0.4.0-a0fd887e5d06d11a75269d5dfed7da6fe2656edbbd7cc1697fb2a2b8ad4fe392","pkg-name":"call-stack","pkg-version":"0.4.0","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"ac44d2c00931dc20b01750da8c92ec443eb63a7231e8550188cb2ac2385f7feb","pkg-src-sha256":"430bcf8a3404f7e55319573c0b807b1356946f0c8f289bb3d9afb279c636b87b","depends":["base-4.18.2.0"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"case-insensitive-1.2.1.0-5255eaf892b10e8489fdad145ca833a10864bd951f3e69d04088fbcadf28ec6d","pkg-name":"case-insensitive","pkg-version":"1.2.1.0","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"9dfd3171fc7698cf8d931727d3af3a7b389135b583e46b5adac1f9d2026fff61","pkg-src-sha256":"296dc17e0c5f3dfb3d82ced83e4c9c44c338ecde749b278b6eae512f1d04e406","depends":["base-4.18.2.0","bytestring-0.11.5.3","deepseq-1.4.8.1","hashable-1.4.3.0-17b447e0ce504d4e093d6bf5a9838da3805c7caa5d16355da40827d004febbc8","text-2.0.2"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"cborg-0.2.10.0-cfaa438104ce487b61248b85071f08fb39e16a23a8eb0f32a1ad8b086d37fb6b","pkg-name":"cborg","pkg-version":"0.2.10.0","flags":{"optimize-gmp":true},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"61655189275a1d3f74553e918c90ae87448bc4af6c5f41159c01849b22b1ee75","pkg-src-sha256":"17fe070c38fc498cab49bcb9d6215b7747d53bedf96502e9bcce9cad73b9c797","depends":["array-0.5.6.0","base-4.18.2.0","bytestring-0.11.5.3","containers-0.6.7","deepseq-1.4.8.1","ghc-bignum-1.3","ghc-prim-0.10.0","half-0.3.1-abaa8d4e544e24e38c9200d7b5cfb6731ae8b4aec4a1d27bf34cec5836e12ff6","primitive-0.9.0.0-a6aa61bd9fff8d6cfd4880894dd85d8e644fbcf178b2bff38f87569871ea4a0d","text-2.0.2"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"cereal-0.5.8.3-930e90604013ce2a32c6d28d3567d1d966e50eb1bf0c18108838f2b4ff0d64ca","pkg-name":"cereal","pkg-version":"0.5.8.3","flags":{"bytestring-builder":false},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"87a227c7b510217ea059db3dd59d9665edd8f0d1d3d8de39458e371a1d9402fb","pkg-src-sha256":"99905220661b26e5bd91130bd9772554938608a5b1d717240a6eb331121e0f6a","depends":["array-0.5.6.0","base-4.18.2.0","bytestring-0.11.5.3","containers-0.6.7","ghc-prim-0.10.0"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"chronos-1.1.6.1-e20dbb7d5779b22a2f3541a6e640402e4330514b14ff822947c4209317b25bd6","pkg-name":"chronos","pkg-version":"1.1.6.1","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"79f83f2db47065c9019ab8d958e82c0c3e211e9714840746bd8bd038f4ae7eb0","pkg-src-sha256":"3998e5495247338506e0cc35bd5aecf5c8e89f79a069d2c5338b3c72c27e4259","depends":["aeson-2.2.1.0-2595d249b227784b9febcd5a91568775f66fd262ac45c82c44f7b4a55e9d4c27","attoparsec-0.14.4-5061b5f729de9f72f69961345d54e0249a28df7c232bb9cf2b0525b6f17a253a","base-4.18.2.0","bytebuild-0.3.16.2-cdc53c5f9fe77d8a2e07a053df6e6cc49bf0b599080e951bea083f37245f23ad","byteslice-0.2.13.2-93a4f1e735c3da2a6b67f70d01ac2fe3652393dc05bb13f3b274ebaf67729ba4","bytesmith-0.3.11.0-110aed7be9e82cf40e2b317b574dcf8dfef014f7e0dbb78475aca851e3d498dd","bytestring-0.11.5.3","deepseq-1.4.8.1","hashable-1.4.3.0-17b447e0ce504d4e093d6bf5a9838da3805c7caa5d16355da40827d004febbc8","natural-arithmetic-0.2.1.0-327b3d0462a9fdccd1f5901b636a5c6f1c1996b903146b3f4bf006389c9d4483","primitive-0.9.0.0-a6aa61bd9fff8d6cfd4880894dd85d8e644fbcf178b2bff38f87569871ea4a0d","text-2.0.2","text-short-0.1.5-e014e79f76c5438274db6ad0455e870f44faf95f73a43bdf4e1c22851755dbaa","torsor-0.1.0.1-264ad98156300f7b86fb968625df8515c2fbbce5479b450f036ac11b2f5c7444","vector-0.13.1.0-eb53bdac16f057ad838f4e8cb865b51b400abac71a36dc5bfde93ea1d0859eae"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"clock-0.8.4-ad97d5c0d9c88bea3fcc07810f4bfa48bfd5e30af51e35ab1d3d70d0ad238573","pkg-name":"clock","pkg-version":"0.8.4","flags":{"llvm":false},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"b938655b00cf204ce69abfff946021bed111d2609a9f7a9c22e28a1a202e9115","pkg-src-sha256":"6ae9898afe788a5e334cd5fad5d18a3c2e8e59fa09aaf7b957dbb38a4767df2e","depends":["base-4.18.2.0"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"cmark-gfm-0.2.6-75f7486f403003de2a2443033871ceb43cdf01f5fac50f7409807d10e27f29bc","pkg-name":"cmark-gfm","pkg-version":"0.2.6","flags":{"pkgconfig":false},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"8672b9388f5ddfa8ece691e59b4272fa807a2ddf0698970cd73af9bebb98058d","pkg-src-sha256":"958cfb3bd54b1bfa9e1e2d9cd1748e76c10d2b30a3cceeab3f6a852205c1a869","depends":["base-4.18.2.0","bytestring-0.11.5.3","text-2.0.2"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"cmdargs-0.10.22-f5bcda1abe20b4892a5dd9a037b87b25157ad0148e6ed24d10071b61bda0375c","pkg-name":"cmdargs","pkg-version":"0.10.22","flags":{"quotation":true,"testprog":false},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"0d1a33c3978fbcdda4f2543e62ac3ed8ad36152e141cdeebeece7e08d6529d63","pkg-src-sha256":"b8b12e7f8795cf13037bb062d453b86c788eae62558586f59e9419aabe6e9bef","depends":["base-4.18.2.0","filepath-1.4.200.1","process-1.6.17.0","template-haskell-2.20.0.0","transformers-0.6.1.0"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"colour-2.3.6-b9efcf2f194d8cd3334d28c9a0c2645a368b8c516a5d80ca0692194cbd33006d","pkg-name":"colour","pkg-version":"2.3.6","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"ebdcbf15023958838a527e381ab3c3b1e99ed12d1b25efeb7feaa4ad8c37664a","pkg-src-sha256":"2cd35dcd6944a5abc9f108a5eb5ee564b6b1fa98a9ec79cefcc20b588991f871","depends":["base-4.18.2.0"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"colourista-0.1.0.2-f2248bbbb4ee79cbf9fe81e61effe11fd685506de3685fc7950c57e7408058a6","pkg-name":"colourista","pkg-version":"0.1.0.2","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"87b6c096563c3dc5afb1161f06891235370862fc3406406f1f10f1864e55e0a1","pkg-src-sha256":"96afae0b54b12205a9871ecb4c7ee173e8b9f05363d843c15d373d394d08063c","depends":["ansi-terminal-1.0.2-f2271bf25e5299c165409ab78d5917aeba79c479959932bb5fb284c513226fc0","base-4.18.2.0","bytestring-0.11.5.3","text-2.0.2"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"commonmark-0.2.5.1-42b2b423f134ce671347ac1eb3ef3f9f8d898f5b6f290e2c7f708d870c7508f8","pkg-name":"commonmark","pkg-version":"0.2.5.1","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"cd1a6f9bc24459643a8f7b73190d92ff7d2eab4151694de4299e5fd3af2f6558","pkg-src-sha256":"cdd629cf07be861ba9ae2395b4caca61138bc281fc27f457f1f8cce31719c548","depends":["base-4.18.2.0","bytestring-0.11.5.3","containers-0.6.7","parsec-3.1.16.1","text-2.0.2","transformers-0.6.1.0","unicode-data-0.4.0.1-2cec5f4ee6f7dac835f9656497f58d5132b6da46ac07f33c15ef93dbfe67a942","unicode-transforms-0.4.0.1-8c67b0eaf2d5104e81ffbe7caf4900a211ea1e275b21ae6aca8253bd0b8d074b"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"commonmark-extensions-0.2.5.2-59454db801b34e805acb6c8d83dde32037a0c2284a4baf2daa746c128a386e1d","pkg-name":"commonmark-extensions","pkg-version":"0.2.5.2","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"4fa3a7dd7f5f1325ebaf23d1f73cc21abc1b124e74cf49dc7157a88874b6f504","pkg-src-sha256":"ec8d2ced4f126aed144e98888f1af845402395a351d8b1c291a372723a7811ab","depends":["base-4.18.2.0","commonmark-0.2.5.1-42b2b423f134ce671347ac1eb3ef3f9f8d898f5b6f290e2c7f708d870c7508f8","containers-0.6.7","emojis-0.1.3-f8293844dfb248bd5ce62ece3582fb79ba4132f2e1ac9c78fac78b46fb1d71d5","filepath-1.4.200.1","network-uri-2.6.4.2-d62d36021f4a84b02c9243cbe37e9dfd5b7ba840b4aaedb5e002f05582564fc4","parsec-3.1.16.1","text-2.0.2","transformers-0.6.1.0"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"comonad-5.0.8-8505feb1b75f0b6bf19ef9b666132d0031c1214df6db91aab78f0a9def57751c","pkg-name":"comonad","pkg-version":"5.0.8","flags":{"containers":true,"distributive":true,"indexed-traversable":true},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"4a4dbfbd03fb4963987710fca994e8b5624bd05a33e5f95b7581b26f8229c5e3","pkg-src-sha256":"ef6cdf2cc292cc43ee6aa96c581b235fdea8ab44a0bffb24dc79ae2b2ef33d13","depends":["base-4.18.2.0","containers-0.6.7","distributive-0.6.2.1-70a2f4c4bffafd7749c1d755f27db885f954a9d9be1cd7db8a6e99887121ec8c","indexed-traversable-0.1.3-8f7210e35c0cb4bf73ec163bed4014cbba70e17aa189447497a492e60990637b","tagged-0.8.8-5d06ce789c37adf39496775b08f7d82bb9509e4c2a3f973b0c868e35bca55ad5","transformers-0.6.1.0","transformers-compat-0.7.2-15ca92c51f3c4b3e5a349c3cc2a7f406ca01ba50aecd92a631a1c4d508b1230f"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"concurrent-output-1.10.20-c4a120b1daa3b0b9738f4f9f1b441737023740231d880696da957f2afe7f5fcc","pkg-name":"concurrent-output","pkg-version":"1.10.20","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"b0ebf122b3f22c9739045825334bd02bd2814752933a92db41e5b4648527139c","pkg-src-sha256":"8e23b5aa95fb9ed5224173f2587a9e4af244322c40249fe24e948bd6007421ca","depends":["ansi-terminal-1.0.2-f2271bf25e5299c165409ab78d5917aeba79c479959932bb5fb284c513226fc0","async-2.2.4-2107e60f1bee7c70ffed77e551ffc7db01e350edd8784cc9493cc782305122d0","base-4.18.2.0","directory-1.3.8.1","exceptions-0.10.7","process-1.6.17.0","stm-2.5.1.0","terminal-size-0.3.4-172d551b468144cc78b519639c232b4d8e46869dd22d4d30ed85ae123e1301e8","text-2.0.2","transformers-0.6.1.0","unix-2.8.4.0"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"conduit-1.3.5-96fa916ebd7a150aa66076e6ed1e4a9d7982e51658f9fd750ad31ce33c46afd7","pkg-name":"conduit","pkg-version":"1.3.5","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"22665df25c9c158d5fcfb299e46b0b642868add42a6bb13b79d457dc7ff7be1a","pkg-src-sha256":"2bb0d3e0eecc43e3d1d8cfc2125914f9175cde752be2d5908a1e120f321c782d","depends":["base-4.18.2.0","bytestring-0.11.5.3","directory-1.3.8.1","exceptions-0.10.7","filepath-1.4.200.1","mono-traversable-1.0.15.3-ee2c72a88a7e0e61e75d356539364a91ed39c83311aa5272b47ebaa5412d78cc","mtl-2.3.1","primitive-0.9.0.0-a6aa61bd9fff8d6cfd4880894dd85d8e644fbcf178b2bff38f87569871ea4a0d","resourcet-1.3.0-0f210c6e8ffe9f595ad8fd1a6cf6726e42a6695abb7febee22452f40436a2bc5","text-2.0.2","transformers-0.6.1.0","unix-2.8.4.0","unliftio-core-0.2.1.0-1e6dce1dfe73ef335e0615b0af7f06b171c3572cf7a04fe671b6cec407b73dee","vector-0.13.1.0-eb53bdac16f057ad838f4e8cb865b51b400abac71a36dc5bfde93ea1d0859eae"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"conduit-extra-1.3.6-a9b74b7c97cb9e39e8f4262bfd1952b446fe950cb07e127ba073c16301e30755","pkg-name":"conduit-extra","pkg-version":"1.3.6","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"83303e6fea78a683fdbb41682fc8dbc47b1d8830da1f09e88940f9a744a7f984","pkg-src-sha256":"8950c38049d892c38590d389bed49ecf880671f58ec63dd4709d9fe3d4b8f153","depends":["async-2.2.4-2107e60f1bee7c70ffed77e551ffc7db01e350edd8784cc9493cc782305122d0","attoparsec-0.14.4-5061b5f729de9f72f69961345d54e0249a28df7c232bb9cf2b0525b6f17a253a","base-4.18.2.0","bytestring-0.11.5.3","conduit-1.3.5-96fa916ebd7a150aa66076e6ed1e4a9d7982e51658f9fd750ad31ce33c46afd7","directory-1.3.8.1","filepath-1.4.200.1","network-3.1.4.0-9d41c9df77e8d21da5aaf51c19540d3c0fc11e5e2c2940bea5411915b8a462ff","primitive-0.9.0.0-a6aa61bd9fff8d6cfd4880894dd85d8e644fbcf178b2bff38f87569871ea4a0d","process-1.6.17.0","resourcet-1.3.0-0f210c6e8ffe9f595ad8fd1a6cf6726e42a6695abb7febee22452f40436a2bc5","stm-2.5.1.0","streaming-commons-0.2.2.6-9fa4239301ef39252b6218423c0a2438611fe43c2ddbebd4f8953d4455c07935","text-2.0.2","transformers-0.6.1.0","typed-process-0.2.11.1-4907353577cf7b0488b9e45d5074486e7c2bbc62c713aeaa26212d7c9d609d10","unliftio-core-0.2.1.0-1e6dce1dfe73ef335e0615b0af7f06b171c3572cf7a04fe671b6cec407b73dee"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"constraints-0.14-ab15a9f94938365a9f7a935af490e603978d84c5e110ef254a28de6613181c00","pkg-name":"constraints","pkg-version":"0.14","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"0af61e4b5f982bd0113640692c409e6344e7b3fe3690d51212a4a6fa84d02872","pkg-src-sha256":"b809322abced0f6b6bf4ceed9e4e823bfdeda808664563b860add1dff3cdc4a5","depends":["base-4.18.2.0","binary-0.8.9.1","boring-0.2.1-9a8dc8e41ea918a09754ff07614d4843b0ebe75d8757fd3273e17938f5bf6233","deepseq-1.4.8.1","ghc-prim-0.10.0","hashable-1.4.3.0-17b447e0ce504d4e093d6bf5a9838da3805c7caa5d16355da40827d004febbc8","mtl-2.3.1","transformers-0.6.1.0","type-equality-1-0b6d3f1475843f8a2ec92f8308f7e4e437169ac42b8e9e6533f304adcd6f533e"],"exe-depends":[],"component-name":"lib"},{"type":"pre-existing","id":"containers-0.6.7","pkg-name":"containers","pkg-version":"0.6.7","depends":["array-0.5.6.0","base-4.18.2.0","deepseq-1.4.8.1","template-haskell-2.20.0.0"]},{"type":"configured","id":"contiguous-0.6.4.2-05fdf6e288b8c7809eb95c94784c40e7f5746e0c73b7ad5b8a9f9a3c7449d34f","pkg-name":"contiguous","pkg-version":"0.6.4.2","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"5b9908787d229f98e80c03030439697863aaf7c42a943bfb07a4481d191e3839","pkg-src-sha256":"a8ead64063b68e5a0bf35b8b51f829de4f7815ab5cb380be58433e115b86c02b","depends":["base-4.18.2.0","deepseq-1.4.8.1","primitive-0.9.0.0-a6aa61bd9fff8d6cfd4880894dd85d8e644fbcf178b2bff38f87569871ea4a0d","primitive-unlifted-2.1.0.0-aea76574320ac1dea77e342956c3de02d6d7ed0b25f80413b31e3a4622eea123","run-st-0.1.3.3-af1ad044a973fec4afa0830cc37bb6f0f7961cd9e6ffb5b32198ce4b6d73c331"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"contravariant-1.5.5-45cb856efb41788f255562487551496b619a1cf555a23fc4a29495fda3e0c50f","pkg-name":"contravariant","pkg-version":"1.5.5","flags":{"semigroups":true,"statevar":true,"tagged":true},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"470ed0e040e879e2da4af1b2c8f94e199f6135852a8107858d5ae0a95365835f","pkg-src-sha256":"062fd66580d7aad0b5ba93e644ffa7feee69276ef50f20d4ed9f1deb7642dffa","depends":["StateVar-1.2.2-ad33ce876594474d931417853bfd72c6eb94d534a6634dcbf0af13ec95c0e031","base-4.18.2.0","transformers-0.6.1.0"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"cookie-0.4.6-0f17f671a430f9d3670a38aa989d096c8a941ff590a1a1a5bc4f595def792f73","pkg-name":"cookie","pkg-version":"0.4.6","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"00f3a7d5604a3ccbfe89b9c52f8eb1edea753dc273d015333895118f32683ecd","pkg-src-sha256":"8c41a956c32b9733d525a53d43b0338a236a34d36658ecc4364c8249a6664baa","depends":["base-4.18.2.0","bytestring-0.11.5.3","data-default-class-0.1.2.0-4350681fcf6087f7ee4836ea8af486e6eeb8f64bb56f88dbd081081499b0bef6","deepseq-1.4.8.1","text-2.0.2","time-1.12.2"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"crypto-api-0.13.3-7a787ea36d9a45cc1748699175ede37f55426b32db3712140ca048f1a888c44f","pkg-name":"crypto-api","pkg-version":"0.13.3","flags":{"all_cpolys":false},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"e572c0cdc58ba6773ea200ea5261d6bf5fc116d910b52cf1c671d85b940ed6fc","pkg-src-sha256":"298a9ea7ce97c8ccf4bfe46d4864092c3a007a56bede73560070db3bf1ac7aa5","components":{"lib":{"depends":["base-4.18.2.0","bytestring-0.11.5.3","cereal-0.5.8.3-930e90604013ce2a32c6d28d3567d1d966e50eb1bf0c18108838f2b4ff0d64ca","entropy-0.4.1.10-8c6fb48b38b19d07f9b370b6707c9d29f3ebf9f4746fb1c84bdfc52bb55247e8","tagged-0.8.8-5d06ce789c37adf39496775b08f7d82bb9509e4c2a3f973b0c868e35bca55ad5","transformers-0.6.1.0"],"exe-depends":[]}}},{"type":"configured","id":"crypto-pubkey-types-0.4.3-0e51728f266377e9408460fc3416717740bf7a0fd1ea1d3d056abfa0f9de4241","pkg-name":"crypto-pubkey-types","pkg-version":"0.4.3","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"9bcf9ec7045f1043edac2b8331d9120bc055083578dbd953a3cccfc7452d9e8c","pkg-src-sha256":"7ed9f52281ec4e34021a91818fe45288e33d65bff937f60334a3f45be5a71c60","components":{"lib":{"depends":["asn1-encoding-0.9.6-9bf64732d7af18045ee22a12f781934262d76015cf823acd133e41c1341a5fb9","asn1-types-0.3.4-09d5674972306ee58c9f15c425744939cc04dad257e3b9dd8f0168fbdc38ab70","base-4.18.2.0"],"exe-depends":[]}}},{"type":"configured","id":"cryptohash-md5-0.11.101.0-3dd4c39d92ff47630ac61716ac3e4f1bd76b570bf3eb70cf3c6a25610e31a06c","pkg-name":"cryptohash-md5","pkg-version":"0.11.101.0","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"71a6e856a4ce0b844a27eb4ba58e214e4263ffbde9c8f406eed3f9a43ad8efec","pkg-src-sha256":"3b08db0ae39df2b44e83053ad30d7546a4c6200a852c22a240a7e03ae1080f05","depends":["base-4.18.2.0","bytestring-0.11.5.3"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"cryptohash-sha1-0.11.101.0-a3ef13c78463fdd04d9d6245ad7391e038dbf79d9c19ec5ab64f9b19a6fb91a8","pkg-name":"cryptohash-sha1","pkg-version":"0.11.101.0","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"bc5d3373ed5bbfd34b9deea62dc3b2ba21dde5b89e41d2a2399de7562543c621","pkg-src-sha256":"a4042c97ad02eb68e766577ca35c01970c33e96cfd74ccb4dd403e3476a23241","depends":["base-4.18.2.0","bytestring-0.11.5.3"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"cryptohash-sha256-0.11.102.1-fcfb37d142b9653401581f09c5dcc32f0ef1d86e4c59d0d3f29420dde251f653","pkg-name":"cryptohash-sha256","pkg-version":"0.11.102.1","flags":{"exe":false,"use-cbits":true},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"03db065161987f614a3a2bbcd16264f78e47efe231fb5bd161be2043eaf20488","pkg-src-sha256":"73a7dc7163871a80837495039a099967b11f5c4fe70a118277842f7a713c6bf6","depends":["base-4.18.2.0","bytestring-0.11.5.3"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"crypton-0.34-c8d7db2766b56c26f144f8f589058be74cfcc7e68ff2d08f8f41d2ef1a1fa0e8","pkg-name":"crypton","pkg-version":"0.34","flags":{"check_alignment":false,"integer-gmp":true,"old_toolchain_inliner":false,"support_aesni":true,"support_deepseq":true,"support_pclmuldq":true,"support_rdrand":true,"support_sse":false,"use_target_attributes":true},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"9e4b50d79d1fba681befa08151db7223d2b4bb72564853e8530e614105d53a1a","pkg-src-sha256":"4444846924ca55615fce104913a5a68675a180cfeadc350ab2b124fba1bc1ed6","depends":["base-4.18.2.0","basement-0.0.16-2ba9d181df7bdd547d6fedd5acdec581f03e379e22b0e08ff998fb0462257d08","bytestring-0.11.5.3","deepseq-1.4.8.1","ghc-prim-0.10.0","integer-gmp-1.1","memory-0.18.0-273ad672f1703dee0dfe07994633c93d17f815a149738659ef6afa30cbe4f6a8"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"crypton-connection-0.3.2-804034b7a3e50ed75e1849613e844c1579d8bd18848efe958529bc613747e852","pkg-name":"crypton-connection","pkg-version":"0.3.2","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"c7937edc25ab022bcf167703f2ec5ab73b62908e545bb587d2aa42b33cd6f6cc","pkg-src-sha256":"208be23bc910f8e5f9431995b9c011ed376bb947d79f74c8f51a5e4ecd9e991e","depends":["base-4.18.2.0","basement-0.0.16-2ba9d181df7bdd547d6fedd5acdec581f03e379e22b0e08ff998fb0462257d08","bytestring-0.11.5.3","containers-0.6.7","crypton-x509-1.7.6-ace8f9d140333c88f85ccfc3589bf27f34ff44a133899eca8703ad0a2550cbd2","crypton-x509-store-1.6.9-a22fb54b4d19ed5d96223b9252ac458efdc316468954bf7427b768e536d62b27","crypton-x509-system-1.6.7-4263b9110e48de6418ac901ce9fe1729cf296cecbfa131cfcac7f4c1050d1761","crypton-x509-validation-1.6.12-7d625ee1af564079d6fbb1cad937bb153313fe0a40e0d69ba93055d71efd6686","data-default-class-0.1.2.0-4350681fcf6087f7ee4836ea8af486e6eeb8f64bb56f88dbd081081499b0bef6","network-3.1.4.0-9d41c9df77e8d21da5aaf51c19540d3c0fc11e5e2c2940bea5411915b8a462ff","socks-0.6.1-6b9e88c9a8f5eb4e1297331a35574d1481e0bfa053fb8eb954e442854a2c7b98","tls-2.0.1-b47e0fd7dac1558b195f1752f4ccbcc31081e04ec060bb63474359a715d7657d"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"crypton-x509-1.7.6-ace8f9d140333c88f85ccfc3589bf27f34ff44a133899eca8703ad0a2550cbd2","pkg-name":"crypton-x509","pkg-version":"1.7.6","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"c567657a705b6d6521f9dd2de999bf530d618ec00f3b939df76a41fb0fe94281","pkg-src-sha256":"ebb74aca2d00261e2fb4927d211ba1a174e190e5257f309e190f019727f8caff","depends":["asn1-encoding-0.9.6-9bf64732d7af18045ee22a12f781934262d76015cf823acd133e41c1341a5fb9","asn1-parse-0.9.5-2a949cca1e96d33a3cea78e8f484af2b63e4592b43690a951c967874e85dcf09","asn1-types-0.3.4-09d5674972306ee58c9f15c425744939cc04dad257e3b9dd8f0168fbdc38ab70","base-4.18.2.0","bytestring-0.11.5.3","containers-0.6.7","crypton-0.34-c8d7db2766b56c26f144f8f589058be74cfcc7e68ff2d08f8f41d2ef1a1fa0e8","hourglass-0.2.12-ff77f9ff09de83d24a0ee40cfa0cec90de8666d5167809a314d26ad4a7544cdd","memory-0.18.0-273ad672f1703dee0dfe07994633c93d17f815a149738659ef6afa30cbe4f6a8","pem-0.2.4-fc2f4716715ce340b3916ffcbdd4e6509f0d10442951de390cdd9d623db1033a","transformers-0.6.1.0"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"crypton-x509-store-1.6.9-a22fb54b4d19ed5d96223b9252ac458efdc316468954bf7427b768e536d62b27","pkg-name":"crypton-x509-store","pkg-version":"1.6.9","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"422b9b9f87a7382c66385d047615b16fc86a68c08ea22b1e0117c143a2d44050","pkg-src-sha256":"3e6218af12e039cc291d19792db044df1647b5cf0bbc60b909a027e7595a256f","depends":["asn1-encoding-0.9.6-9bf64732d7af18045ee22a12f781934262d76015cf823acd133e41c1341a5fb9","asn1-types-0.3.4-09d5674972306ee58c9f15c425744939cc04dad257e3b9dd8f0168fbdc38ab70","base-4.18.2.0","bytestring-0.11.5.3","containers-0.6.7","crypton-0.34-c8d7db2766b56c26f144f8f589058be74cfcc7e68ff2d08f8f41d2ef1a1fa0e8","crypton-x509-1.7.6-ace8f9d140333c88f85ccfc3589bf27f34ff44a133899eca8703ad0a2550cbd2","directory-1.3.8.1","filepath-1.4.200.1","mtl-2.3.1","pem-0.2.4-fc2f4716715ce340b3916ffcbdd4e6509f0d10442951de390cdd9d623db1033a"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"crypton-x509-system-1.6.7-4263b9110e48de6418ac901ce9fe1729cf296cecbfa131cfcac7f4c1050d1761","pkg-name":"crypton-x509-system","pkg-version":"1.6.7","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"023ed573d82983bc473a37a89e0434a085b413be9f68d07e085361056afd4637","pkg-src-sha256":"a436261e5f5e83d85080f57a5509c8224c9e75a6e56d0c43a7d2967052b634ca","depends":["base-4.18.2.0","bytestring-0.11.5.3","containers-0.6.7","crypton-x509-1.7.6-ace8f9d140333c88f85ccfc3589bf27f34ff44a133899eca8703ad0a2550cbd2","crypton-x509-store-1.6.9-a22fb54b4d19ed5d96223b9252ac458efdc316468954bf7427b768e536d62b27","directory-1.3.8.1","filepath-1.4.200.1","mtl-2.3.1","pem-0.2.4-fc2f4716715ce340b3916ffcbdd4e6509f0d10442951de390cdd9d623db1033a","process-1.6.17.0"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"crypton-x509-validation-1.6.12-7d625ee1af564079d6fbb1cad937bb153313fe0a40e0d69ba93055d71efd6686","pkg-name":"crypton-x509-validation","pkg-version":"1.6.12","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"85989721b64be4b90de9f66ef641c26f57575cffed1a50d707065fb60176f386","pkg-src-sha256":"0e60b7e237a4fd5e7e6e7200018c7947314292ef63751cbb51877836ebe650f6","depends":["asn1-encoding-0.9.6-9bf64732d7af18045ee22a12f781934262d76015cf823acd133e41c1341a5fb9","asn1-types-0.3.4-09d5674972306ee58c9f15c425744939cc04dad257e3b9dd8f0168fbdc38ab70","base-4.18.2.0","bytestring-0.11.5.3","containers-0.6.7","crypton-0.34-c8d7db2766b56c26f144f8f589058be74cfcc7e68ff2d08f8f41d2ef1a1fa0e8","crypton-x509-1.7.6-ace8f9d140333c88f85ccfc3589bf27f34ff44a133899eca8703ad0a2550cbd2","crypton-x509-store-1.6.9-a22fb54b4d19ed5d96223b9252ac458efdc316468954bf7427b768e536d62b27","data-default-class-0.1.2.0-4350681fcf6087f7ee4836ea8af486e6eeb8f64bb56f88dbd081081499b0bef6","hourglass-0.2.12-ff77f9ff09de83d24a0ee40cfa0cec90de8666d5167809a314d26ad4a7544cdd","memory-0.18.0-273ad672f1703dee0dfe07994633c93d17f815a149738659ef6afa30cbe4f6a8","mtl-2.3.1","pem-0.2.4-fc2f4716715ce340b3916ffcbdd4e6509f0d10442951de390cdd9d623db1033a"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"cryptonite-0.30-a4317e7e07f60749ecfe221f105aa6192fceaa0071302418f9317d0ad2cd4d81","pkg-name":"cryptonite","pkg-version":"0.30","flags":{"check_alignment":false,"integer-gmp":true,"old_toolchain_inliner":false,"support_aesni":true,"support_deepseq":true,"support_pclmuldq":false,"support_rdrand":true,"support_sse":false,"use_target_attributes":true},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"12c85dea7be63e5ad90bcb487eb3846bf3c413347f94336fa1dede7b28f9936a","pkg-src-sha256":"56099c8a8aa01d2ee914b670c97c1f818186dbb886e2025b73d9c2afe3496b1d","depends":["base-4.18.2.0","basement-0.0.16-2ba9d181df7bdd547d6fedd5acdec581f03e379e22b0e08ff998fb0462257d08","bytestring-0.11.5.3","deepseq-1.4.8.1","ghc-prim-0.10.0","integer-gmp-1.1","memory-0.18.0-273ad672f1703dee0dfe07994633c93d17f815a149738659ef6afa30cbe4f6a8"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"cryptonite-conduit-0.2.2-dc6649104789f26beacba5c896f4efecfdc457327c1993ac619628030998d8a7","pkg-name":"cryptonite-conduit","pkg-version":"0.2.2","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"bfbae677a44f3a5cf3bf7f36271682979a402825f3d1e8767cfd62f2ddb702c2","pkg-src-sha256":"705d69ab3f79b7b8810c7b9e7da81a1c6686b6a4323b1e78150576a25a658dae","depends":["base-4.18.2.0","bytestring-0.11.5.3","conduit-1.3.5-96fa916ebd7a150aa66076e6ed1e4a9d7982e51658f9fd750ad31ce33c46afd7","conduit-extra-1.3.6-a9b74b7c97cb9e39e8f4262bfd1952b446fe950cb07e127ba073c16301e30755","cryptonite-0.30-a4317e7e07f60749ecfe221f105aa6192fceaa0071302418f9317d0ad2cd4d81","exceptions-0.10.7","memory-0.18.0-273ad672f1703dee0dfe07994633c93d17f815a149738659ef6afa30cbe4f6a8","resourcet-1.3.0-0f210c6e8ffe9f595ad8fd1a6cf6726e42a6695abb7febee22452f40436a2bc5","transformers-0.6.1.0"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"data-default-0.7.1.1-fb1a461d5390de89b4af18b225f51df41ca3a345d820ee4756653e4cd2f3cd8e","pkg-name":"data-default","pkg-version":"0.7.1.1","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"2804e8d14f521a1edee88b68b66347448e7f3b685868290fdc55930e4471f5a9","pkg-src-sha256":"b0f95d279cd75cacaa8152a01590dc3460f7134f6840b37052abb3ba3cb2a511","components":{"lib":{"depends":["base-4.18.2.0","data-default-class-0.1.2.0-4350681fcf6087f7ee4836ea8af486e6eeb8f64bb56f88dbd081081499b0bef6","data-default-instances-containers-0.0.1-3b2bd3972f1fe587fa0e2b950640dd67b79a64674b8dbf89500902c3c9c31e3f","data-default-instances-dlist-0.0.1-834ba711e749a3311d3bc2d831127402fe965724977bf227862f4c25e9a2e22e","data-default-instances-old-locale-0.0.1-7212215bbe1bf7a79167a625399e4c186658fb645ff6a90daef2696377a0f5af"],"exe-depends":[]}}},{"type":"configured","id":"data-default-class-0.1.2.0-4350681fcf6087f7ee4836ea8af486e6eeb8f64bb56f88dbd081081499b0bef6","pkg-name":"data-default-class","pkg-version":"0.1.2.0","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"63e62120b7efd733a5a17cf59ceb43268e9a929c748127172d7d42f4a336e327","pkg-src-sha256":"4f01b423f000c3e069aaf52a348564a6536797f31498bb85c3db4bd2d0973e56","components":{"lib":{"depends":["base-4.18.2.0"],"exe-depends":[]}}},{"type":"configured","id":"data-default-instances-containers-0.0.1-3b2bd3972f1fe587fa0e2b950640dd67b79a64674b8dbf89500902c3c9c31e3f","pkg-name":"data-default-instances-containers","pkg-version":"0.0.1","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"6e1f4b28028a3bc455aaf4b5a9104b71ea72cff78b1b8041863df7afd1a8deb3","pkg-src-sha256":"a55e07af005c9815d82f3fc95e125db82994377c9f4a769428878701d4ec081a","components":{"lib":{"depends":["base-4.18.2.0","containers-0.6.7","data-default-class-0.1.2.0-4350681fcf6087f7ee4836ea8af486e6eeb8f64bb56f88dbd081081499b0bef6"],"exe-depends":[]}}},{"type":"configured","id":"data-default-instances-dlist-0.0.1-834ba711e749a3311d3bc2d831127402fe965724977bf227862f4c25e9a2e22e","pkg-name":"data-default-instances-dlist","pkg-version":"0.0.1","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"4286abacbb256c392907701be16986a6e07f2beaf2778e7bd925465655d9e301","pkg-src-sha256":"7d683711cbf08abd7adcd5ac2be825381308d220397315a5570fe61b719b5959","components":{"lib":{"depends":["base-4.18.2.0","data-default-class-0.1.2.0-4350681fcf6087f7ee4836ea8af486e6eeb8f64bb56f88dbd081081499b0bef6","dlist-1.0-1ec91dd3ad8405ed390138bce1c7d55220d4758eda9fb3ad6fbb8b1ee6dc0c94"],"exe-depends":[]}}},{"type":"configured","id":"data-default-instances-old-locale-0.0.1-7212215bbe1bf7a79167a625399e4c186658fb645ff6a90daef2696377a0f5af","pkg-name":"data-default-instances-old-locale","pkg-version":"0.0.1","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"d4a757f68f0f83531fcb34a4525fe6769c54a45182e28ffdfff19c2b0ace42fb","pkg-src-sha256":"60d3b02922958c4908d7bf2b24ddf61511665745f784227d206745784b0c0802","components":{"lib":{"depends":["base-4.18.2.0","data-default-class-0.1.2.0-4350681fcf6087f7ee4836ea8af486e6eeb8f64bb56f88dbd081081499b0bef6","old-locale-1.0.0.7-682418540979bf75be932863a87a0db4ab12d3f7ec5faaeba30e4175347cd126"],"exe-depends":[]}}},{"type":"configured","id":"data-fix-0.3.2-5add57223d3c0b4ba49ecf522767d4a71475f5e86cefa1a15e9af611e468b46f","pkg-name":"data-fix","pkg-version":"0.3.2","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"cd7d6ff8b68aca3b51d8116870fc8ccdbc557989562cd3d5c941e4f0b7bc5af1","pkg-src-sha256":"3a172d3bc0639c327345e965f9d9023e099425814b28dcdb7b60ff66d66219cc","depends":["base-4.18.2.0","deepseq-1.4.8.1","hashable-1.4.3.0-17b447e0ce504d4e093d6bf5a9838da3805c7caa5d16355da40827d004febbc8"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"dec-0.0.5-df077fdbf908bb3fdbc8e113d90c87e216153ded7ddd81017ddf01027a3a495b","pkg-name":"dec","pkg-version":"0.0.5","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"1044421ac555d062a843865b06941b8c744261e122930f680524c0bd2095b6ed","pkg-src-sha256":"e18043c7c7e68168489f164921a02efede0c0175a5012ed5451ec2242338df88","depends":["base-4.18.2.0","boring-0.2.1-9a8dc8e41ea918a09754ff07614d4843b0ebe75d8757fd3273e17938f5bf6233"],"exe-depends":[],"component-name":"lib"},{"type":"pre-existing","id":"deepseq-1.4.8.1","pkg-name":"deepseq","pkg-version":"1.4.8.1","depends":["array-0.5.6.0","base-4.18.2.0","ghc-prim-0.10.0"]},{"type":"configured","id":"deriving-aeson-0.2.9-f86850669d5d4b90b08e438464fff4f49c8d0959ce8a2fd31d585b5dec88f689","pkg-name":"deriving-aeson","pkg-version":"0.2.9","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"957bd6da5a4f40f74ea8c485084c3e48dd9278073f95809f068b02bdcf9c3892","pkg-src-sha256":"c0b2975df7ed5ba668982ba442318c36adfe8be3c32dcf136c13bf9662261833","depends":["aeson-2.2.1.0-2595d249b227784b9febcd5a91568775f66fd262ac45c82c44f7b4a55e9d4c27","base-4.18.2.0"],"exe-depends":[],"component-name":"lib"},{"type":"pre-existing","id":"directory-1.3.8.1","pkg-name":"directory","pkg-version":"1.3.8.1","depends":["base-4.18.2.0","filepath-1.4.200.1","time-1.12.2","unix-2.8.4.0"]},{"type":"configured","id":"distributive-0.6.2.1-70a2f4c4bffafd7749c1d755f27db885f954a9d9be1cd7db8a6e99887121ec8c","pkg-name":"distributive","pkg-version":"0.6.2.1","flags":{"semigroups":true,"tagged":true},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"0f99f5541cca04acf89b64432b03422b6408e830a8dff30e6c4334ef1a48680c","pkg-src-sha256":"d7351392e078f58caa46630a4b9c643e1e2e9dddee45848c5c8358e7b1316b91","depends":["base-4.18.2.0","base-orphans-0.9.1-61d128d6a3318593c785a97751f2418cc86b42b03e2b46ed92e9b27fc5da689c","tagged-0.8.8-5d06ce789c37adf39496775b08f7d82bb9509e4c2a3f973b0c868e35bca55ad5","transformers-0.6.1.0"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"dlist-1.0-1ec91dd3ad8405ed390138bce1c7d55220d4758eda9fb3ad6fbb8b1ee6dc0c94","pkg-name":"dlist","pkg-version":"1.0","flags":{"werror":false},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"55ff69d20ce638fc7727342ee67f2f868da61d3dcf3763f790bf9aa0b145e568","pkg-src-sha256":"173d637328bb173fcc365f30d29ff4a94292a1e0e5558aeb3dfc11de81510115","depends":["base-4.18.2.0","deepseq-1.4.8.1"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"easy-file-0.2.5-5fa303965280a30fe8c9bcd5e7d5323c903dc206d322c6c1f552800a235b3607","pkg-name":"easy-file","pkg-version":"0.2.5","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"1c93b6bd30cac2ccad359d1e3e50d71b77f599730407a7f3481c8c67a856fb6b","pkg-src-sha256":"ee0fa0914b3bb3662838a689d7cd23a2785ccbc29def366664f994bc524ff2bb","depends":["base-4.18.2.0","directory-1.3.8.1","filepath-1.4.200.1","time-1.12.2","unix-2.8.4.0"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"effectful-2.3.0.0-52623768742e178fa9448f87d55f19ed0d8237dc80135fee9505d1c022c6ed6f","pkg-name":"effectful","pkg-version":"2.3.0.0","flags":{"benchmark-foreign-libraries":false},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"7d9b9913f29c2ab640e449bcd1d196ac0d0f74b1e2c8c7ddec459353d75976db","pkg-src-sha256":"6742be657fc65af9aa4f0cedfc7e90b76fba9cb5c736494075182a153244d90f","depends":["async-2.2.4-2107e60f1bee7c70ffed77e551ffc7db01e350edd8784cc9493cc782305122d0","base-4.18.2.0","bytestring-0.11.5.3","directory-1.3.8.1","effectful-core-2.3.0.1-011d84ab0bc8bb2010bac83565500e3039592cab57d902e9a2a502684b92d90f","process-1.6.17.0","stm-2.5.1.0","time-1.12.2","unliftio-0.2.25.0-494677154ed69a76841d775b50166f52e9d0797a41ece2fd3d94e08aebf372f3"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"effectful-core-2.3.0.1-011d84ab0bc8bb2010bac83565500e3039592cab57d902e9a2a502684b92d90f","pkg-name":"effectful-core","pkg-version":"2.3.0.1","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"377b9057b43d65d100f36ceb22f2d675e927fe47d678a51ae7dea6998aa9ebf9","pkg-src-sha256":"3cb1e1e12542e15c03856be8865111e2f71f40d9b108ad7de27612efa52e739b","depends":["base-4.18.2.0","containers-0.6.7","exceptions-0.10.7","monad-control-1.0.3.1-2bf3452c923aa94707518b6d970f4377279fd8c4ccca1256725eef18b6097440","primitive-0.9.0.0-a6aa61bd9fff8d6cfd4880894dd85d8e644fbcf178b2bff38f87569871ea4a0d","transformers-base-0.4.6-91c64a4b19c3f5f9f196345e9032803d52322bd0857ba94ea6c4260a27a2ff07","unliftio-core-0.2.1.0-1e6dce1dfe73ef335e0615b0af7f06b171c3572cf7a04fe671b6cec407b73dee"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"either-5.0.2-d8d7bb84305283af81161a95ec2aebe67483cc07c71e171fc392eccfafdfb663","pkg-name":"either","pkg-version":"5.0.2","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"fb3d130c37df6b4c7aa5f093e83bb4527fe13d8a72f94bce3d6ab00764ee59f0","pkg-src-sha256":"bfa45b967fd77b1c7c952e156377441e3c42b6dc873ab1f06a7421a3222287be","depends":["base-4.18.2.0","bifunctors-5.6.1-3bfddc97d0532e0f4bedd1f64454f96744d2fe805f93a5f9e443c2c5e1035ff1","mtl-2.3.1","profunctors-5.6.2-8b084a9552445e5776f01a7b42f1722ce1ecf20cf9a8e839007b9baea33b9fa4","semigroupoids-6.0.0.1-e83bc6491c75c3522014917ab4d3335127e2ee3b4989f0a49f9791f8bead28c6"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"emojis-0.1.3-f8293844dfb248bd5ce62ece3582fb79ba4132f2e1ac9c78fac78b46fb1d71d5","pkg-name":"emojis","pkg-version":"0.1.3","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"75a6953d8ad064415cb5aac2b52040a1e2bcf7a923d99055038f17219d4b8852","pkg-src-sha256":"817fc6c4d0040418d981b82349e389566db6ce0e0337dc70fe5d1483e1d91af8","depends":["base-4.18.2.0","containers-0.6.7","text-2.0.2"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"entropy-0.4.1.10-8c6fb48b38b19d07f9b370b6707c9d29f3ebf9f4746fb1c84bdfc52bb55247e8","pkg-name":"entropy","pkg-version":"0.4.1.10","flags":{"donotgetentropy":false},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"82bd7b600fb8df540dd292ed91dc781f4523eecef3bb588b14787b4851722cb1","pkg-src-sha256":"85ac1d53f1d1c095aedd23fdb20c8e3ada04a7fd8aa6d7e6445ae6a59a277de5","components":{"lib":{"depends":["base-4.18.2.0","bytestring-0.11.5.3","unix-2.8.4.0"],"exe-depends":[]},"setup":{"depends":["Cabal-3.10.1.0","base-4.18.2.0","directory-1.3.8.1","filepath-1.4.200.1","process-1.6.17.0"],"exe-depends":[]}}},{"type":"configured","id":"envparse-0.5.0-c225ff1d783744cd1f9863f791cab7f87b9c995b2fca94b0138f73571480411e","pkg-name":"envparse","pkg-version":"0.5.0","flags":{},"style":"global","pkg-src":{"type":"source-repo","source-repo":{"type":"git","location":"https://github.com/supki/envparse","tag":"503a699"}},"pkg-src-sha256":"3a8c0b34bb5290d1fa7d691c2e7d28c350973a5f6db8388b527a82e39ead8d3f","depends":["base-4.18.2.0","containers-0.6.7"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"erf-2.0.0.0-5e00dd8595b2d92c48d9f543d9269f193e14d19af8d53cfaa38744b61539cdae","pkg-name":"erf","pkg-version":"2.0.0.0","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"11c5d3747d17b589009cbe9656ca792e4b5b2560d4aa44f6f1e80044794b1a8b","pkg-src-sha256":"24f0b79c7e1d25cb2cd44c2258d7a464bf6db8079775b50b60b54a254616b337","components":{"lib":{"depends":["base-4.18.2.0"],"exe-depends":[]}}},{"type":"pre-existing","id":"exceptions-0.10.7","pkg-name":"exceptions","pkg-version":"0.10.7","depends":["base-4.18.2.0","mtl-2.3.1","stm-2.5.1.0","template-haskell-2.20.0.0","transformers-0.6.1.0"]},{"type":"configured","id":"extensible-exceptions-0.1.1.4-9ada676787e2c2f8f4d2dc78ab24d80159488100b1a4433d25572f0c9366f79f","pkg-name":"extensible-exceptions","pkg-version":"0.1.1.4","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"eb5fe684a7ffe8d1ed2ed6cdaec7dfb29efc780811ea7158a64edc2abc516f47","pkg-src-sha256":"6ce5e8801760385a408dab71b53550f87629e661b260bdc2cd41c6a439b6e388","components":{"lib":{"depends":["base-4.18.2.0"],"exe-depends":[]}}},{"type":"configured","id":"extra-1.7.14-f1add2fd140928c4ff98846cf958be82c050721a89872d0804fd7c0b0133cad4","pkg-name":"extra","pkg-version":"1.7.14","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"e3d3ce1dc7746b1132930e48c59fb5e8c51a09e92e0c031316be031067a273fb","pkg-src-sha256":"b6a909f8f0e4b8076a1653b4d34815a782f0a8c1e83d5267f4d00496471ef567","depends":["base-4.18.2.0","clock-0.8.4-ad97d5c0d9c88bea3fcc07810f4bfa48bfd5e30af51e35ab1d3d70d0ad238573","directory-1.3.8.1","filepath-1.4.200.1","process-1.6.17.0","time-1.12.2","unix-2.8.4.0"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"fast-logger-3.2.2-f2b66566923a1fa76e5c48eecb73e2ef0a379b38ce325b13b8e81e8022003d26","pkg-name":"fast-logger","pkg-version":"3.2.2","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"9b17bc98ed0dc8f29f855560ac9b0dc6791392e6de36f9a6060dd201c3f2aed1","pkg-src-sha256":"575bbe9fc2d130fe665bb6d135349200b4825fcb60b59533f89c2a8c9844afdd","depends":["array-0.5.6.0","auto-update-0.1.6-3f7af882e90ee16fd9e6ebf1ca739ba4ad18afcdae045a3375fe3adefea17239","base-4.18.2.0","bytestring-0.11.5.3","directory-1.3.8.1","easy-file-0.2.5-5fa303965280a30fe8c9bcd5e7d5323c903dc206d322c6c1f552800a235b3607","filepath-1.4.200.1","stm-2.5.1.0","text-2.0.2","unix-compat-0.7.1-d99eb5acf38b31b458b2a5f48db2ff44a4954123ddfa4c9c3d585ea4ef03206d","unix-time-0.4.12-45eb997f2b10c03cbe95532ca065341d046b4309aac2f8aad0358668133acf67"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"file-embed-0.0.16.0-d63ac8c371cd44fa36b87af3f4672e6a9da8a4dd85e53dc2781049b6fa1aeeda","pkg-name":"file-embed","pkg-version":"0.0.16.0","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"2e8983240c1faae020b4acef6d30f0281f5ec87c2f38736dc1dc5456355e22a5","pkg-src-sha256":"5f18672eff936355557cdd163905451205d7ee22742edac313dd27cf42a3f415","depends":["base-4.18.2.0","bytestring-0.11.5.3","directory-1.3.8.1","filepath-1.4.200.1","template-haskell-2.20.0.0"],"exe-depends":[],"component-name":"lib"},{"type":"pre-existing","id":"filepath-1.4.200.1","pkg-name":"filepath","pkg-version":"1.4.200.1","depends":["base-4.18.2.0","bytestring-0.11.5.3","deepseq-1.4.8.1","exceptions-0.10.7","template-haskell-2.20.0.0"]},{"type":"configured","id":"flora-1.0.15-inplace","pkg-name":"flora","pkg-version":"1.0.15","flags":{"prod":false},"style":"local","pkg-src":{"type":"local","path":"/home/hecate/Projects/Flora/1-flora-server/."},"dist-dir":"/home/hecate/Projects/Flora/1-flora-server/dist-newstyle/build/x86_64-linux/ghc-9.6.4/flora-1.0.15","build-info":"/home/hecate/Projects/Flora/1-flora-server/dist-newstyle/build/x86_64-linux/ghc-9.6.4/flora-1.0.15/build-info.json","depends":["Cabal-syntax-3.10.1.0","JuicyPixels-3.3.8-295ba873739530be2ad2e0f5ef3880f23fb240b49297676915db7967d6106794","aeson-2.2.1.0-2595d249b227784b9febcd5a91568775f66fd262ac45c82c44f7b4a55e9d4c27","base-4.18.2.0","base16-bytestring-1.0.2.0-b470eb3428775005093b18dbb34dd687b575cadcc3d709cf63c09611d917e654","base64-1.0-dd5d13a79aacb87c11501514ee42d94f31fb8135c9427a7dddef0b4e4e537062","blaze-builder-0.4.2.3-60676f992d653075aeba6aad80b2dd0b054859608a5712ecfc9d4a4968aefdb8","bytestring-0.11.5.3","colourista-0.1.0.2-f2248bbbb4ee79cbf9fe81e61effe11fd685506de3685fc7950c57e7408058a6","containers-0.6.7","cryptohash-md5-0.11.101.0-3dd4c39d92ff47630ac61716ac3e4f1bd76b570bf3eb70cf3c6a25610e31a06c","cryptohash-sha256-0.11.102.1-fcfb37d142b9653401581f09c5dcc32f0ef1d86e4c59d0d3f29420dde251f653","cryptonite-0.30-a4317e7e07f60749ecfe221f105aa6192fceaa0071302418f9317d0ad2cd4d81","cryptonite-conduit-0.2.2-dc6649104789f26beacba5c896f4efecfdc457327c1993ac619628030998d8a7","deepseq-1.4.8.1","deriving-aeson-0.2.9-f86850669d5d4b90b08e438464fff4f49c8d0959ce8a2fd31d585b5dec88f689","directory-1.3.8.1","effectful-core-2.3.0.1-011d84ab0bc8bb2010bac83565500e3039592cab57d902e9a2a502684b92d90f","envparse-0.5.0-c225ff1d783744cd1f9863f791cab7f87b9c995b2fca94b0138f73571480411e","filepath-1.4.200.1","http-api-data-0.6-f8db4c3e7ff814c1476ac3873683211db56d23f0c28cabdd051460114fc3de4f","http-media-0.8.1.1-82ac8def17fc7bb0c409983a665f6b7cccbfddad16ad03396e0ea28fa6b4797e","iso8601-time-0.1.5-613661a1ea46bf04f83cf7f01f86b46eac75038540215814c13f119e8c47a17d","log-base-0.12.0.1-f6c93830f52a9d5925fa4be3f430d1262c4e2bbf3222e6a925872b2eec0a9d75","log-effectful-1.0.0.0-1daa99a173049071f9677770e30ef537619d4b74217444ebd179050ac6230f31","lucid-2.11.20230408-181c7ed44fa9b37af3ac434ed53e16dbe6a7ca9ec7ef1f7e5c921196d628f3c0","memory-0.18.0-273ad672f1703dee0dfe07994633c93d17f815a149738659ef6afa30cbe4f6a8","monad-time-effectful-1.0.0.0-3bcc12595825f15e6c956704de800593d9caa43c86932b7456205b4fcd7a3fee","odd-jobs-0.2.3-2ea7e869e131ba9271dc166fb94494d9c4695adf80a10aeb2c6885388c248e44","openapi3-3.2.4-36a3dd9c34b66f8d7bf989194c80a50284551837b7d8417e8ce95b4a35d15c2e","optics-core-0.4.1.1-f8d9a3ddd3e59e269ad03738aca54bb92446a15ba98a2b4ae8ec19ed7d20df70","pcre2-2.2.1-497aee97a6283223eea2bb30f3bd7127ff8bb3d2b6ece9c4e0a73371dc66b90c","pg-entity-0.0.4.4-c09d4801d2c9b8aac6587451fb3276698aa673bffbbe13e20e92459744a89058","pg-transact-0.3.2.0-154eca34326a8779919f5450f98657e0bdd42098d5eb39bd64fe3ab6b57ef08c","pg-transact-effectful-0.0.1.0-19059a8ff842cc019bf692ea57228ae755836f0ae48aa91885f40683ea8347a6","poolboy-0.2.2.0-2b5751910b4c714d0b69899eea5770ca156a5f1311f953bd68bceb7c3f9f9275","postgresql-simple-0.6.5.1-ec621799555c8b1b15b3683ac92cdc3770e891696c7afc3195aa6f26571cbbe0","pretty-1.1.3.6","qrcode-core-0.9.9-26498b4ed47f926f2f064d25ff1a73747fe531dce4fe1eaf0dd664493c00bbbc","qrcode-juicypixels-0.8.5-6838fee4a1ce854292c21f8a386f97468fe4ea877b3c81266871b5ccf74fbeb5","resource-pool-0.4.0.0-b943f9aab32b14d553510f77b995882007d913763eb4c8a34a077c78a8909098","sel-0.0.1.0-a107cece4307b775602a0ac4fef5e5489f9cf07913069de7b0aebbe27daff576","servant-0.20.1-b63507222e1b19c7b8333551fd2fbdae76248ba97753767f7ab4d32b7816d39d","servant-lucid-0.9.0.6-3245f97c511011e42d95122d5373c12ebeb20de76226f6491768d04935bf6b52","servant-server-0.20-3dbcc60207566a1f80874e61a86b73ab8a41f98f3231692dec244b2ce96f8132","slugify-0.1.0.1-4ab88c5012a98f82389b22741a6da4533ceb4b7336ca607b4e641118933d2d75","souffle-haskell-4.0.0-122eb0210bf095a8300c9247fb7467920a26f76fde9fbfed4d1bae48e6666480","streamly-0.10.1-355a5bd5db83dc8d0325992ae963a6091c0eb61a91ecdda01c0d7d997bd43408","streamly-core-0.2.2-1de2fd5320df2135ec5ee591367a8233ec85c39bfb2366f77b325fca4e8a6657","tar-0.6.1.0-2355dea2b7e5a1fb20c6753c9c6e0e55e2208d19d4f800ee0c38ad10afdd8945","text-2.0.2","text-display-0.0.5.1-ae9f66e9765923d9edec209058cc153706fead0e7c7287c2994a985da1c39623","time-1.12.2","unliftio-0.2.25.0-494677154ed69a76841d775b50166f52e9d0797a41ece2fd3d94e08aebf372f3","utf8-string-1.0.2-5e8d116496349c38d20293f85d47a22c703548b74e7d267d8d6d20ff907c03cd","uuid-1.3.15-413cef239f477249b51ed712d27bea33e15b08237221be1f41f0bc89ce5e1463","vector-0.13.1.0-eb53bdac16f057ad838f4e8cb865b51b400abac71a36dc5bfde93ea1d0859eae","vector-algorithms-0.9.0.1-0d5de6c527fb6ba0e7be854c1685b82a6a99d5798a407e65dc55cac4091e272a","zlib-0.6.3.0-61cb40f46d103a622525dc3a70a9004984ec56d61deea65d2dc01c964606b7e9"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"flora-1.0.15-inplace-flora-cli","pkg-name":"flora","pkg-version":"1.0.15","flags":{"prod":false},"style":"local","pkg-src":{"type":"local","path":"/home/hecate/Projects/Flora/1-flora-server/."},"dist-dir":"/home/hecate/Projects/Flora/1-flora-server/dist-newstyle/build/x86_64-linux/ghc-9.6.4/flora-1.0.15/x/flora-cli","build-info":"/home/hecate/Projects/Flora/1-flora-server/dist-newstyle/build/x86_64-linux/ghc-9.6.4/flora-1.0.15/x/flora-cli/build-info.json","depends":["Cabal-syntax-3.10.1.0","PyF-0.11.2.1-136109de9a2dff073e8ac6c2d415f86bbe2b3b9b72015bfb5fd638fdd22d1843","base-4.18.2.0","bytestring-0.11.5.3","effectful-core-2.3.0.1-011d84ab0bc8bb2010bac83565500e3039592cab57d902e9a2a502684b92d90f","envparse-0.5.0-c225ff1d783744cd1f9863f791cab7f87b9c995b2fca94b0138f73571480411e","filepath-1.4.200.1","flora-1.0.15-inplace","flora-1.0.15-inplace-flora-web","log-base-0.12.0.1-f6c93830f52a9d5925fa4be3f430d1262c4e2bbf3222e6a925872b2eec0a9d75","log-effectful-1.0.0.0-1daa99a173049071f9677770e30ef537619d4b74217444ebd179050ac6230f31","lucid-2.11.20230408-181c7ed44fa9b37af3ac434ed53e16dbe6a7ca9ec7ef1f7e5c921196d628f3c0","monad-time-effectful-1.0.0.0-3bcc12595825f15e6c956704de800593d9caa43c86932b7456205b4fcd7a3fee","optics-core-0.4.1.1-f8d9a3ddd3e59e269ad03738aca54bb92446a15ba98a2b4ae8ec19ed7d20df70","optparse-applicative-0.18.1.0-1de8f12cfc2915bc6d323ba97415a7e0795036a6b613e7301735aedf9d0425be","pg-transact-effectful-0.0.1.0-19059a8ff842cc019bf692ea57228ae755836f0ae48aa91885f40683ea8347a6","sel-0.0.1.0-a107cece4307b775602a0ac4fef5e5489f9cf07913069de7b0aebbe27daff576","text-2.0.2","text-display-0.0.5.1-ae9f66e9765923d9edec209058cc153706fead0e7c7287c2994a985da1c39623","transformers-0.6.1.0","uuid-1.3.15-413cef239f477249b51ed712d27bea33e15b08237221be1f41f0bc89ce5e1463","vector-0.13.1.0-eb53bdac16f057ad838f4e8cb865b51b400abac71a36dc5bfde93ea1d0859eae","zlib-0.6.3.0-61cb40f46d103a622525dc3a70a9004984ec56d61deea65d2dc01c964606b7e9"],"exe-depends":[],"component-name":"exe:flora-cli","bin-file":"/home/hecate/Projects/Flora/1-flora-server/dist-newstyle/build/x86_64-linux/ghc-9.6.4/flora-1.0.15/x/flora-cli/build/flora-cli/flora-cli"},{"type":"configured","id":"flora-1.0.15-inplace-flora-jobs","pkg-name":"flora","pkg-version":"1.0.15","flags":{"prod":false},"style":"local","pkg-src":{"type":"local","path":"/home/hecate/Projects/Flora/1-flora-server/."},"dist-dir":"/home/hecate/Projects/Flora/1-flora-server/dist-newstyle/build/x86_64-linux/ghc-9.6.4/flora-1.0.15/l/flora-jobs","build-info":"/home/hecate/Projects/Flora/1-flora-server/dist-newstyle/build/x86_64-linux/ghc-9.6.4/flora-1.0.15/l/flora-jobs/build-info.json","depends":["Cabal-syntax-3.10.1.0","aeson-2.2.1.0-2595d249b227784b9febcd5a91568775f66fd262ac45c82c44f7b4a55e9d4c27","base-4.18.2.0","bytestring-0.11.5.3","commonmark-0.2.5.1-42b2b423f134ce671347ac1eb3ef3f9f8d898f5b6f290e2c7f708d870c7508f8","commonmark-extensions-0.2.5.2-59454db801b34e805acb6c8d83dde32037a0c2284a4baf2daa746c128a386e1d","containers-0.6.7","effectful-core-2.3.0.1-011d84ab0bc8bb2010bac83565500e3039592cab57d902e9a2a502684b92d90f","flora-1.0.15-inplace","http-client-0.7.16-08ac6af6261aa24f586bbb528e8ea2f0bd2e7510d1883948d770173e7ea8b633","http-media-0.8.1.1-82ac8def17fc7bb0c409983a665f6b7cccbfddad16ad03396e0ea28fa6b4797e","http-types-0.12.4-0f52a9ec33f3c65ef0b77ad8ce14b65f9164f8a761e42800dc9c80ee1768aacc","log-base-0.12.0.1-f6c93830f52a9d5925fa4be3f430d1262c4e2bbf3222e6a925872b2eec0a9d75","log-effectful-1.0.0.0-1daa99a173049071f9677770e30ef537619d4b74217444ebd179050ac6230f31","lucid-2.11.20230408-181c7ed44fa9b37af3ac434ed53e16dbe6a7ca9ec7ef1f7e5c921196d628f3c0","monad-time-effectful-1.0.0.0-3bcc12595825f15e6c956704de800593d9caa43c86932b7456205b4fcd7a3fee","odd-jobs-0.2.3-2ea7e869e131ba9271dc166fb94494d9c4695adf80a10aeb2c6885388c248e44","pg-entity-0.0.4.4-c09d4801d2c9b8aac6587451fb3276698aa673bffbbe13e20e92459744a89058","pg-transact-effectful-0.0.1.0-19059a8ff842cc019bf692ea57228ae755836f0ae48aa91885f40683ea8347a6","postgresql-simple-0.6.5.1-ec621799555c8b1b15b3683ac92cdc3770e891696c7afc3195aa6f26571cbbe0","req-3.13.2-58b3576f35ee75f77b2d839cec460285be510fca18162b9b1542b8ae69fa9e34","resource-pool-0.4.0.0-b943f9aab32b14d553510f77b995882007d913763eb4c8a34a077c78a8909098","servant-0.20.1-b63507222e1b19c7b8333551fd2fbdae76248ba97753767f7ab4d32b7816d39d","servant-client-0.20-ffd6b2eca0816fa09c64c230d34ebe7b6ee3f06a805980e86e28fb7d902f65e2","servant-client-core-0.20-9e603d4d82c8eefde573caf5b7328a91ee474d7e0ede0539645efa20a15a89d4","text-2.0.2","text-display-0.0.5.1-ae9f66e9765923d9edec209058cc153706fead0e7c7287c2994a985da1c39623","time-1.12.2","vector-0.13.1.0-eb53bdac16f057ad838f4e8cb865b51b400abac71a36dc5bfde93ea1d0859eae"],"exe-depends":[],"component-name":"lib:flora-jobs"},{"type":"configured","id":"flora-1.0.15-inplace-flora-server","pkg-name":"flora","pkg-version":"1.0.15","flags":{"prod":false},"style":"local","pkg-src":{"type":"local","path":"/home/hecate/Projects/Flora/1-flora-server/."},"dist-dir":"/home/hecate/Projects/Flora/1-flora-server/dist-newstyle/build/x86_64-linux/ghc-9.6.4/flora-1.0.15/x/flora-server","build-info":"/home/hecate/Projects/Flora/1-flora-server/dist-newstyle/build/x86_64-linux/ghc-9.6.4/flora-1.0.15/x/flora-server/build-info.json","depends":["base-4.18.2.0","flora-1.0.15-inplace-flora-web"],"exe-depends":[],"component-name":"exe:flora-server","bin-file":"/home/hecate/Projects/Flora/1-flora-server/dist-newstyle/build/x86_64-linux/ghc-9.6.4/flora-1.0.15/x/flora-server/build/flora-server/flora-server"},{"type":"configured","id":"flora-1.0.15-inplace-flora-test","pkg-name":"flora","pkg-version":"1.0.15","flags":{"prod":false},"style":"local","pkg-src":{"type":"local","path":"/home/hecate/Projects/Flora/1-flora-server/."},"dist-dir":"/home/hecate/Projects/Flora/1-flora-server/dist-newstyle/build/x86_64-linux/ghc-9.6.4/flora-1.0.15/t/flora-test","build-info":"/home/hecate/Projects/Flora/1-flora-server/dist-newstyle/build/x86_64-linux/ghc-9.6.4/flora-1.0.15/t/flora-test/build-info.json","depends":["Cabal-syntax-3.10.1.0","aeson-2.2.1.0-2595d249b227784b9febcd5a91568775f66fd262ac45c82c44f7b4a55e9d4c27","base-4.18.2.0","bytestring-0.11.5.3","containers-0.6.7","effectful-core-2.3.0.1-011d84ab0bc8bb2010bac83565500e3039592cab57d902e9a2a502684b92d90f","exceptions-0.10.7","filepath-1.4.200.1","flora-1.0.15-inplace","flora-1.0.15-inplace-flora-web","hedgehog-1.4-6a1134b766e3ee92aee20c92175e4b367d76546ac9575a629ee2eb67aab3a3cb","http-client-0.7.16-08ac6af6261aa24f586bbb528e8ea2f0bd2e7510d1883948d770173e7ea8b633","log-base-0.12.0.1-f6c93830f52a9d5925fa4be3f430d1262c4e2bbf3222e6a925872b2eec0a9d75","log-effectful-1.0.0.0-1daa99a173049071f9677770e30ef537619d4b74217444ebd179050ac6230f31","monad-time-effectful-1.0.0.0-3bcc12595825f15e6c956704de800593d9caa43c86932b7456205b4fcd7a3fee","optics-core-0.4.1.1-f8d9a3ddd3e59e269ad03738aca54bb92446a15ba98a2b4ae8ec19ed7d20df70","pg-entity-0.0.4.4-c09d4801d2c9b8aac6587451fb3276698aa673bffbbe13e20e92459744a89058","pg-transact-0.3.2.0-154eca34326a8779919f5450f98657e0bdd42098d5eb39bd64fe3ab6b57ef08c","pg-transact-effectful-0.0.1.0-19059a8ff842cc019bf692ea57228ae755836f0ae48aa91885f40683ea8347a6","postgresql-migration-0.2.1.7-559534ce1dd13a52b2fe575db34bd39f392a7c262dc6d5bd81bff72f2e148d8e","postgresql-simple-0.6.5.1-ec621799555c8b1b15b3683ac92cdc3770e891696c7afc3195aa6f26571cbbe0","resource-pool-0.4.0.0-b943f9aab32b14d553510f77b995882007d913763eb4c8a34a077c78a8909098","sel-0.0.1.0-a107cece4307b775602a0ac4fef5e5489f9cf07913069de7b0aebbe27daff576","servant-0.20.1-b63507222e1b19c7b8333551fd2fbdae76248ba97753767f7ab4d32b7816d39d","servant-client-0.20-ffd6b2eca0816fa09c64c230d34ebe7b6ee3f06a805980e86e28fb7d902f65e2","servant-server-0.20-3dbcc60207566a1f80874e61a86b73ab8a41f98f3231692dec244b2ce96f8132","tar-0.6.1.0-2355dea2b7e5a1fb20c6753c9c6e0e55e2208d19d4f800ee0c38ad10afdd8945","tasty-1.5-fd9a969b42a912ece8c4543e101cd6e26eee76689c8c5a012bcea4edbf273551","tasty-hunit-0.10.1-d5d74b078c2fc7d0540add40bfcb063d16fc8fc5e21d9467944dfc172c67d6a5","text-2.0.2","time-1.12.2","uuid-1.3.15-413cef239f477249b51ed712d27bea33e15b08237221be1f41f0bc89ce5e1463","vector-0.13.1.0-eb53bdac16f057ad838f4e8cb865b51b400abac71a36dc5bfde93ea1d0859eae","vector-algorithms-0.9.0.1-0d5de6c527fb6ba0e7be854c1685b82a6a99d5798a407e65dc55cac4091e272a","zlib-0.6.3.0-61cb40f46d103a622525dc3a70a9004984ec56d61deea65d2dc01c964606b7e9"],"exe-depends":[],"component-name":"test:flora-test","bin-file":"/home/hecate/Projects/Flora/1-flora-server/dist-newstyle/build/x86_64-linux/ghc-9.6.4/flora-1.0.15/t/flora-test/build/flora-test/flora-test"},{"type":"configured","id":"flora-1.0.15-inplace-flora-web","pkg-name":"flora","pkg-version":"1.0.15","flags":{"prod":false},"style":"local","pkg-src":{"type":"local","path":"/home/hecate/Projects/Flora/1-flora-server/."},"dist-dir":"/home/hecate/Projects/Flora/1-flora-server/dist-newstyle/build/x86_64-linux/ghc-9.6.4/flora-1.0.15/l/flora-web","build-info":"/home/hecate/Projects/Flora/1-flora-server/dist-newstyle/build/x86_64-linux/ghc-9.6.4/flora-1.0.15/l/flora-web/build-info.json","depends":["Cabal-syntax-3.10.1.0","PyF-0.11.2.1-136109de9a2dff073e8ac6c2d415f86bbe2b3b9b72015bfb5fd638fdd22d1843","aeson-2.2.1.0-2595d249b227784b9febcd5a91568775f66fd262ac45c82c44f7b4a55e9d4c27","async-2.2.4-2107e60f1bee7c70ffed77e551ffc7db01e350edd8784cc9493cc782305122d0","base-4.18.2.0","base32-0.4-3d897481f9dfd13903e614afd99fb6b4ab13c775030063f288dd112a84583017","bytestring-0.11.5.3","chronos-1.1.6.1-e20dbb7d5779b22a2f3541a6e640402e4330514b14ff822947c4209317b25bd6","cmark-gfm-0.2.6-75f7486f403003de2a2443033871ceb43cdf01f5fac50f7409807d10e27f29bc","colourista-0.1.0.2-f2248bbbb4ee79cbf9fe81e61effe11fd685506de3685fc7950c57e7408058a6","containers-0.6.7","cookie-0.4.6-0f17f671a430f9d3670a38aa989d096c8a941ff590a1a1a5bc4f595def792f73","data-default-0.7.1.1-fb1a461d5390de89b4af18b225f51df41ca3a345d820ee4756653e4cd2f3cd8e","deepseq-1.4.8.1","deriving-aeson-0.2.9-f86850669d5d4b90b08e438464fff4f49c8d0959ce8a2fd31d585b5dec88f689","effectful-2.3.0.0-52623768742e178fa9448f87d55f19ed0d8237dc80135fee9505d1c022c6ed6f","effectful-core-2.3.0.1-011d84ab0bc8bb2010bac83565500e3039592cab57d902e9a2a502684b92d90f","extra-1.7.14-f1add2fd140928c4ff98846cf958be82c050721a89872d0804fd7c0b0133cad4","flora-1.0.15-inplace","flora-1.0.15-inplace-flora-jobs","haddock-library-1.11.0-326b2de9b01f2443dad3c93dff0450ea221702c5b8e9319df728d76c9762159c","http-api-data-0.6-f8db4c3e7ff814c1476ac3873683211db56d23f0c28cabdd051460114fc3de4f","http-client-0.7.16-08ac6af6261aa24f586bbb528e8ea2f0bd2e7510d1883948d770173e7ea8b633","http-client-tls-0.3.6.3-67f7c5e1b646b6720d31cd47b325354e5e9c257cef0d9522c9b4a5648422c65e","http-media-0.8.1.1-82ac8def17fc7bb0c409983a665f6b7cccbfddad16ad03396e0ea28fa6b4797e","http-types-0.12.4-0f52a9ec33f3c65ef0b77ad8ce14b65f9164f8a761e42800dc9c80ee1768aacc","log-base-0.12.0.1-f6c93830f52a9d5925fa4be3f430d1262c4e2bbf3222e6a925872b2eec0a9d75","log-effectful-1.0.0.0-1daa99a173049071f9677770e30ef537619d4b74217444ebd179050ac6230f31","lucid-2.11.20230408-181c7ed44fa9b37af3ac434ed53e16dbe6a7ca9ec7ef1f7e5c921196d628f3c0","lucid-alpine-0.1.0.7-b7f14424060b05c5c69e15f1069098caf1990249242463a26aa1a08d9cb5e98c","lucid-svg-0.7.1.1-2b919f949d217797fe4a4bf74b5ae72e72599c4304e6d78dc5d24024c6bb957f","monad-time-0.4.0.0-1b1c52822cdc65b1e9b65bdb86f7b0aec26973256197697f3b44b64ee669d1f7","monad-time-effectful-1.0.0.0-3bcc12595825f15e6c956704de800593d9caa43c86932b7456205b4fcd7a3fee","mtl-2.3.1","network-uri-2.6.4.2-d62d36021f4a84b02c9243cbe37e9dfd5b7ba840b4aaedb5e002f05582564fc4","odd-jobs-0.2.3-2ea7e869e131ba9271dc166fb94494d9c4695adf80a10aeb2c6885388c248e44","one-time-password-3.0.0.0-cbe2caf30a2aa172cf2c5cdfc1edad8761e857fde6fe8f0adb23c2013d6f8108","openapi3-3.2.4-36a3dd9c34b66f8d7bf989194c80a50284551837b7d8417e8ce95b4a35d15c2e","optics-core-0.4.1.1-f8d9a3ddd3e59e269ad03738aca54bb92446a15ba98a2b4ae8ec19ed7d20df70","pg-entity-0.0.4.4-c09d4801d2c9b8aac6587451fb3276698aa673bffbbe13e20e92459744a89058","pg-transact-effectful-0.0.1.0-19059a8ff842cc019bf692ea57228ae755836f0ae48aa91885f40683ea8347a6","postgresql-simple-0.6.5.1-ec621799555c8b1b15b3683ac92cdc3770e891696c7afc3195aa6f26571cbbe0","pretty-1.1.3.6","raven-haskell-0.1.4.1-44d3b6ed541acb7607ead7976c2238c005386ee5ef27fe0c44b3443d3c3d76b7","resource-pool-0.4.0.0-b943f9aab32b14d553510f77b995882007d913763eb4c8a34a077c78a8909098","safe-exceptions-0.1.7.4-51b8325bd2c9c2c32246cef5b80f09fba6aa9b6005978a7b87ef943c7ddd1182","sel-0.0.1.0-a107cece4307b775602a0ac4fef5e5489f9cf07913069de7b0aebbe27daff576","servant-0.20.1-b63507222e1b19c7b8333551fd2fbdae76248ba97753767f7ab4d32b7816d39d","servant-client-0.20-ffd6b2eca0816fa09c64c230d34ebe7b6ee3f06a805980e86e28fb7d902f65e2","servant-client-core-0.20-9e603d4d82c8eefde573caf5b7328a91ee474d7e0ede0539645efa20a15a89d4","servant-lucid-0.9.0.6-3245f97c511011e42d95122d5373c12ebeb20de76226f6491768d04935bf6b52","servant-openapi3-2.0.1.6-92378e8ee0bea5a4e54c3dd4fc1e97b9c790b2fcc65c5a79e54d520319677c44","servant-server-0.20-3dbcc60207566a1f80874e61a86b73ab8a41f98f3231692dec244b2ce96f8132","text-2.0.2","text-display-0.0.5.1-ae9f66e9765923d9edec209058cc153706fead0e7c7287c2994a985da1c39623","time-1.12.2","torsor-0.1.0.1-264ad98156300f7b86fb968625df8515c2fbbce5479b450f036ac11b2f5c7444","uuid-1.3.15-413cef239f477249b51ed712d27bea33e15b08237221be1f41f0bc89ce5e1463","vector-0.13.1.0-eb53bdac16f057ad838f4e8cb865b51b400abac71a36dc5bfde93ea1d0859eae","vector-algorithms-0.9.0.1-0d5de6c527fb6ba0e7be854c1685b82a6a99d5798a407e65dc55cac4091e272a","wai-3.2.4-acf062ae483a435740bc88b21ee81f62d3f94a62faea15a5bf17463ace439645","wai-app-static-3.1.8-d2d0c9be3a5bd2980a68b3225b620c023885a62d44f09cee23e1325fcbe6c50c","wai-log-0.4.0.1-479434afc1461896e7a927d8fb2df0160b14dae19bb9a79688f196ec7d42177b","wai-middleware-heartbeat-0.0.1.0-de5d48bf3f801ad6a7c2e1238d0d30545239fd081520428e7cfa1d9f6b41c104","warp-3.3.31-3a081a14799ab48e5efe3a315077d1e89ea4da61799497b4990d5fc7e0dcb380","xml-conduit-1.9.1.3-bf19b431d216b0a2413840aa01a4a651624a00a392ce27bb32e3cbe5522c5d28","xml-conduit-writer-0.1.1.5-af45083ef430fdd7f499ccdbcbffc63138c7fd12623f1529c3a0777b83867c2e"],"exe-depends":[],"component-name":"lib:flora-web"},{"type":"configured","id":"foreign-store-0.2-38a004231d79ea11822d0929a9cc1c95c0b47fcefc2bf90dbf83bf2d93adaf90","pkg-name":"foreign-store","pkg-version":"0.2","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"5673289d703e523dfec904555e132c46e70c9221c4c9a75fcbc3e587c0b9e63c","pkg-src-sha256":"06718a214d068eaa494cc82376f23b2059a141b01048cd7efcf2176a6c3383dc","depends":["base-4.18.2.0"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"free-5.2-841f6f1c7522ed92dbed9d024b48671e79a9cdd76652f8bdbf9c0e63908771e7","pkg-name":"free","pkg-version":"5.2","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"4dd76c1a19f81d7866e7b75682350f1ef3e0441b19b4d07eccdd9ef326a0be70","pkg-src-sha256":"72867f7c89173263765736e8d395e94291f1aaea626ecb1d673d72ce90b94f89","depends":["base-4.18.2.0","comonad-5.0.8-8505feb1b75f0b6bf19ef9b666132d0031c1214df6db91aab78f0a9def57751c","containers-0.6.7","distributive-0.6.2.1-70a2f4c4bffafd7749c1d755f27db885f954a9d9be1cd7db8a6e99887121ec8c","exceptions-0.10.7","indexed-traversable-0.1.3-8f7210e35c0cb4bf73ec163bed4014cbba70e17aa189447497a492e60990637b","mtl-2.3.1","profunctors-5.6.2-8b084a9552445e5776f01a7b42f1722ce1ecf20cf9a8e839007b9baea33b9fa4","semigroupoids-6.0.0.1-e83bc6491c75c3522014917ab4d3335127e2ee3b4989f0a49f9791f8bead28c6","template-haskell-2.20.0.0","th-abstraction-0.6.0.0-b49a83d27ea2604c7977c309bd302e93941309c5040c248dbdb6b55147976b2b","transformers-0.6.1.0","transformers-base-0.4.6-91c64a4b19c3f5f9f196345e9032803d52322bd0857ba94ea6c4260a27a2ff07"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"friendly-time-0.4.1-abf55dee5aabd3d8d1a3bf852e9269ad8c33f771fd59ecb030b252f999bd9e16","pkg-name":"friendly-time","pkg-version":"0.4.1","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"fa350c6bb17352281415359355ce8f9408a4676f051388e9ea266ed5b172d624","pkg-src-sha256":"9af3443227c3f271f5d11ed8c3c15c77a59de3ab82d87d93ac1f8455a54393c8","depends":["base-4.18.2.0","old-locale-1.0.0.7-682418540979bf75be932863a87a0db4ab12d3f7ec5faaeba30e4175347cd126","time-1.12.2"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"fusion-plugin-types-0.1.0-af0a0db9279412adcb5a431d750045b40fdb99350a31564d7ec80e2944df0ac3","pkg-name":"fusion-plugin-types","pkg-version":"0.1.0","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"0f11bbc445ab8ae3dbbb3d5d2ea198bdb1ac020518b7f4f7579035dc89182438","pkg-src-sha256":"6d0453886b0aca46ab311b8ac8031fd249417e96a1b675248fca196565f59f92","depends":["base-4.18.2.0"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"generic-deriving-1.14.5-a1fd2d043c8cafb22abedc758c45dbc284b28f5354f3eb1c717c80c43a96a9e6","pkg-name":"generic-deriving","pkg-version":"1.14.5","flags":{"base-4-9":true},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"8069afb7fa52c2fdae001c43d3b4d98cb68dffa0dc07ebe1ebba72e08c7762bb","pkg-src-sha256":"ea9f74049bdfae8159738e42beed07ca7ecd7483192407fd29afdde11a339449","depends":["base-4.18.2.0","containers-0.6.7","ghc-prim-0.10.0","template-haskell-2.20.0.0","th-abstraction-0.6.0.0-b49a83d27ea2604c7977c309bd302e93941309c5040c248dbdb6b55147976b2b"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"generically-0.1.1-bdc1b22218832bf69277f07778576bdaa3d8df05d3081150e9ff6dabe4f79249","pkg-name":"generically","pkg-version":"0.1.1","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"378ec049bc2853b8011df116647fbd34bb9f00edce9840e4957f98abc097597c","pkg-src-sha256":"04c5a436bec4b041f71a733f56a1bd7f435f63dde8d3eb5c1f48d55b4dbc43cf","depends":["base-4.18.2.0"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"generics-sop-0.5.1.4-7f93bc69a981e910350e3e463cbbc84ff4d890645a9659a18c10b5d43ad5b6aa","pkg-name":"generics-sop","pkg-version":"0.5.1.4","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"db1929b3c61a6ed4cb5fe99c5a6a1baf0c4e36846d5a3dbb5052f39cc042fcb2","pkg-src-sha256":"616a1c2176097469f9514e76d979fffdbc12d569f44fd01deb14377c7888797e","depends":["base-4.18.2.0","ghc-prim-0.10.0","sop-core-0.5.0.2-916ec985869f4742a9c9e1c1cdd20338928cdc574be8814bb09c58ce2e7bf566","template-haskell-2.20.0.0","th-abstraction-0.6.0.0-b49a83d27ea2604c7977c309bd302e93941309c5040c248dbdb6b55147976b2b"],"exe-depends":[],"component-name":"lib"},{"type":"pre-existing","id":"ghc-9.6.4","pkg-name":"ghc","pkg-version":"9.6.4","depends":["array-0.5.6.0","base-4.18.2.0","binary-0.8.9.1","bytestring-0.11.5.3","containers-0.6.7","deepseq-1.4.8.1","directory-1.3.8.1","exceptions-0.10.7","filepath-1.4.200.1","ghc-boot-9.6.4","ghc-heap-9.6.4","ghci-9.6.4","hpc-0.6.2.0","process-1.6.17.0","stm-2.5.1.0","template-haskell-2.20.0.0","time-1.12.2","transformers-0.6.1.0","unix-2.8.4.0"]},{"type":"pre-existing","id":"ghc-bignum-1.3","pkg-name":"ghc-bignum","pkg-version":"1.3","depends":["ghc-prim-0.10.0"]},{"type":"pre-existing","id":"ghc-boot-9.6.4","pkg-name":"ghc-boot","pkg-version":"9.6.4","depends":["base-4.18.2.0","binary-0.8.9.1","bytestring-0.11.5.3","containers-0.6.7","deepseq-1.4.8.1","directory-1.3.8.1","filepath-1.4.200.1","ghc-boot-th-9.6.4","unix-2.8.4.0"]},{"type":"pre-existing","id":"ghc-boot-th-9.6.4","pkg-name":"ghc-boot-th","pkg-version":"9.6.4","depends":["base-4.18.2.0"]},{"type":"pre-existing","id":"ghc-heap-9.6.4","pkg-name":"ghc-heap","pkg-version":"9.6.4","depends":["base-4.18.2.0","containers-0.6.7","ghc-prim-0.10.0","rts-1.0.2"]},{"type":"pre-existing","id":"ghc-prim-0.10.0","pkg-name":"ghc-prim","pkg-version":"0.10.0","depends":["rts-1.0.2"]},{"type":"pre-existing","id":"ghci-9.6.4","pkg-name":"ghci","pkg-version":"9.6.4","depends":["array-0.5.6.0","base-4.18.2.0","binary-0.8.9.1","bytestring-0.11.5.3","containers-0.6.7","deepseq-1.4.8.1","filepath-1.4.200.1","ghc-boot-9.6.4","ghc-heap-9.6.4","ghc-prim-0.10.0","rts-1.0.2","template-haskell-2.20.0.0","transformers-0.6.1.0","unix-2.8.4.0"]},{"type":"configured","id":"haddock-library-1.11.0-326b2de9b01f2443dad3c93dff0450ea221702c5b8e9319df728d76c9762159c","pkg-name":"haddock-library","pkg-version":"1.11.0","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"17af50285f4aa50b1dcf67ecf25ffc84cb62790340120099ddeb86ad5abc0d27","pkg-src-sha256":"7c075ec9a378b0a2d9d605e72135201e6c7ff316564f2c974113582f43bea20a","depends":["base-4.18.2.0","containers-0.6.7","parsec-3.1.16.1","text-2.0.2"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"half-0.3.1-abaa8d4e544e24e38c9200d7b5cfb6731ae8b4aec4a1d27bf34cec5836e12ff6","pkg-name":"half","pkg-version":"0.3.1","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"f43f16671b42bdc92b4be9e0b0ce1bcff817c928d0a50f13a6264a24586c1a7c","pkg-src-sha256":"e2afc32724e11bf5c695d797b9169d9d9b2dc62a530aed31284c8187af1615d1","depends":["base-4.18.2.0","binary-0.8.9.1","deepseq-1.4.8.1","template-haskell-2.20.0.0"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"happy-1.20.1.1-e-happy-182aa5abbcffb81f5451895cca70d0e3fc7d8d0e3c5bdde45132d65f06643d40","pkg-name":"happy","pkg-version":"1.20.1.1","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"a381633c5e8f9e9e5a8e1900930ce13172397b4677fcfcc08cd38eb3f73b61b1","pkg-src-sha256":"8b4e7dc5a6c5fd666f8f7163232931ab28746d0d17da8fa1cbd68be9e878881b","depends":["array-0.5.6.0","base-4.18.2.0","containers-0.6.7","mtl-2.3.1"],"exe-depends":[],"component-name":"exe:happy","bin-file":"/home/hecate/Projects/Flora/1-flora-server/_build/cabal-store/ghc-9.6.4/happy-1.20.1.1-e-happy-182aa5abbcffb81f5451895cca70d0e3fc7d8d0e3c5bdde45132d65f06643d40/bin/happy"},{"type":"configured","id":"hashable-1.4.3.0-17b447e0ce504d4e093d6bf5a9838da3805c7caa5d16355da40827d004febbc8","pkg-name":"hashable","pkg-version":"1.4.3.0","flags":{"integer-gmp":true,"random-initial-seed":false},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"f3bf68acfa0df7a064a378ef2cdcfeb55e6fb96100675f4c593556dcbf3d7194","pkg-src-sha256":"32efb16c2891786209b7cbe5c39df9b3a9ae51e836f1a54f646bc4602b7ab0f5","depends":["base-4.18.2.0","bytestring-0.11.5.3","containers-0.6.7","deepseq-1.4.8.1","filepath-1.4.200.1","ghc-bignum-1.3","ghc-prim-0.10.0","text-2.0.2"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"haskell-lexer-1.1.1-833f66de7c919d07c41146e9931dfd902b8b694cd3302de1c3d836c85a3c47a3","pkg-name":"haskell-lexer","pkg-version":"1.1.1","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"4ce310678b7e56b51acb558c0233d2f71a3f3553f8a88e9b48c0bc68301f799b","pkg-src-sha256":"c8eeda569a30f115244c17920247ba2c45d11b3e30805f648a878f7855d8f349","depends":["base-4.18.2.0"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"haskell-src-exts-1.23.1-f41334025207b7f06d64532205cdb691bfd3b10cf027d5c23c98ee25bf2c9f5e","pkg-name":"haskell-src-exts","pkg-version":"1.23.1","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"339841f4a6710e915a0bac8df18d8a454c11d626131aee4d05b6be150b7f863e","pkg-src-sha256":"67853047169fff7d3e5d87acef214ee185a6ab8c6a104ed9c59e389574cf6c05","depends":["array-0.5.6.0","base-4.18.2.0","ghc-prim-0.10.0","pretty-1.1.3.6"],"exe-depends":["happy-1.20.1.1-e-happy-182aa5abbcffb81f5451895cca70d0e3fc7d8d0e3c5bdde45132d65f06643d40"],"component-name":"lib"},{"type":"configured","id":"haskell-src-meta-0.8.13-d3053a08f8d9deda4e92997b870b23096956d6c11736d5eed8f387ed509f1133","pkg-name":"haskell-src-meta","pkg-version":"0.8.13","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"ed2fa4b98106500bcd44df5144f4bcb9227d3fb26101dbaa9c70ca8b8d56510b","pkg-src-sha256":"ea0281c916585d3ff4ce0594b000ac844031cab6e0eb16fba4fe0f019aa2c025","depends":["base-4.18.2.0","haskell-src-exts-1.23.1-f41334025207b7f06d64532205cdb691bfd3b10cf027d5c23c98ee25bf2c9f5e","pretty-1.1.3.6","syb-0.7.2.4-80d2f5060ad894d00e83dbe185e57c37c081728996394fa6f5a2fa912bb894f4","template-haskell-2.20.0.0","th-orphans-0.13.14-16db0f9bff8b7cf7d9193a41514705710e6bf8cf8d36317661b9cbe3736fdc28"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"hdaemonize-0.5.7-554f4deed801598a70abe3e63685f792ae09fe10e60f21faf1abe49687142f9f","pkg-name":"hdaemonize","pkg-version":"0.5.7","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"b75b877f0704bcea84bf641c23d5f16e1e220a6147ed4ecabe0b916c128b9cfd","pkg-src-sha256":"748823288eec23252335c00576384fc322e4f91c8e86f456530ba5d7c727f01b","depends":["base-4.18.2.0","bytestring-0.11.5.3","extensible-exceptions-0.1.1.4-9ada676787e2c2f8f4d2dc78ab24d80159488100b1a4433d25572f0c9366f79f","filepath-1.4.200.1","hsyslog-5.0.2-9ac10b37c77c7762f93b70afc58e9b363345f68fafa0faa62d9b9e8fc01b8031","mtl-2.3.1","unix-2.8.4.0"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"heaps-0.4-8352de6c15db4be4912bb7418446dab1e2d80f26647938794abadafee6111c60","pkg-name":"heaps","pkg-version":"0.4","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"66b19fcd813b0e4db3e0bac541bd46606c3b13d3d081d9f9666f4be0f5ff14b8","pkg-src-sha256":"89329df8b95ae99ef272e41e7a2d0fe2f1bb7eacfcc34bc01664414b33067cfd","depends":["base-4.18.2.0"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"hedgehog-1.4-6a1134b766e3ee92aee20c92175e4b367d76546ac9575a629ee2eb67aab3a3cb","pkg-name":"hedgehog","pkg-version":"1.4","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"9195af7e03f6255b087f0a09b4100ba3d805d303aef64b3a8543b2123f7851a2","pkg-src-sha256":"f54afb31552e0f809030becad349cbfe19a65753a778771dc7314b2a6c41e6eb","depends":["ansi-terminal-1.0.2-f2271bf25e5299c165409ab78d5917aeba79c479959932bb5fb284c513226fc0","async-2.2.4-2107e60f1bee7c70ffed77e551ffc7db01e350edd8784cc9493cc782305122d0","barbies-2.1.1.0-a2e90384bd5520adcdbd08bf5d3ad4beac274ed17c2784dd44f1bf5a9ba6ef3f","base-4.18.2.0","bytestring-0.11.5.3","concurrent-output-1.10.20-c4a120b1daa3b0b9738f4f9f1b441737023740231d880696da957f2afe7f5fcc","containers-0.6.7","deepseq-1.4.8.1","directory-1.3.8.1","erf-2.0.0.0-5e00dd8595b2d92c48d9f543d9269f193e14d19af8d53cfaa38744b61539cdae","exceptions-0.10.7","lifted-async-0.10.2.5-0e5383cde07ceba316c6eb9f965038eb2ea32a6c803d5b96f22bdcdba63bfe14","mmorph-1.2.0-967f2a66454abded96663c19c27c375e74faace9a8cd232a9ae738ec2604ffa1","monad-control-1.0.3.1-2bf3452c923aa94707518b6d970f4377279fd8c4ccca1256725eef18b6097440","mtl-2.3.1","pretty-show-1.10-39ae5e05ab98b3c924fb13a2d338f92ec77dadc8f9be190ec6bbf2401618cf8f","primitive-0.9.0.0-a6aa61bd9fff8d6cfd4880894dd85d8e644fbcf178b2bff38f87569871ea4a0d","random-1.2.1.2-cc746490e13a1f967de173a54c09753b2ccdb5d95056b0f1206a29c62c83de45","resourcet-1.3.0-0f210c6e8ffe9f595ad8fd1a6cf6726e42a6695abb7febee22452f40436a2bc5","safe-exceptions-0.1.7.4-51b8325bd2c9c2c32246cef5b80f09fba6aa9b6005978a7b87ef943c7ddd1182","stm-2.5.1.0","template-haskell-2.20.0.0","text-2.0.2","time-1.12.2","transformers-0.6.1.0","transformers-base-0.4.6-91c64a4b19c3f5f9f196345e9032803d52322bd0857ba94ea6c4260a27a2ff07","wl-pprint-annotated-0.1.0.1-2ffc62f3d112419f639c5f9a11a9f5522560693bebb7563fb4d9e6fbf7d077e8"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"hostname-1.0-5085af94c98cc8316318de7e81d25ddb5a73601cfd27bfccc90a5b913cd9891b","pkg-name":"hostname","pkg-version":"1.0","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"8203b6ecd14ca1ef12f73a471b0a6a4be3ad4568d8b84f2bc4bc9e0abb8c4153","pkg-src-sha256":"9b43dab1b6da521f35685b20555da00738c8e136eb972458c786242406a9cf5c","components":{"lib":{"depends":["base-4.18.2.0"],"exe-depends":[]}}},{"type":"configured","id":"hourglass-0.2.12-ff77f9ff09de83d24a0ee40cfa0cec90de8666d5167809a314d26ad4a7544cdd","pkg-name":"hourglass","pkg-version":"0.2.12","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"e083f5e030dfebe432e30a9c0fa07a99a54eac992f622442646be561fd7a44e8","pkg-src-sha256":"44335b5c402e80c60f1db6a74462be4ea29d1a9043aa994334ffee1164f1ca4a","depends":["base-4.18.2.0","deepseq-1.4.8.1"],"exe-depends":[],"component-name":"lib"},{"type":"pre-existing","id":"hpc-0.6.2.0","pkg-name":"hpc","pkg-version":"0.6.2.0","depends":["base-4.18.2.0","containers-0.6.7","deepseq-1.4.8.1","directory-1.3.8.1","filepath-1.4.200.1","time-1.12.2"]},{"type":"configured","id":"hsc2hs-0.68.10-e-hsc2hs-3b4e464e6a657183d9f83bd37c6d876421d9f6d00ca34e12b12ca3365e55159d","pkg-name":"hsc2hs","pkg-version":"0.68.10","flags":{"in-ghc-tree":false},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"488cca2a179a5141da8f35a3a7e6699a0ef690f834f589d6b152c4947aa8fe2d","pkg-src-sha256":"6f4e34d788fe2ca7091ee0a10307ee8a7c060a1ba890f2bffad16a7d4d5cef76","depends":["base-4.18.2.0","containers-0.6.7","directory-1.3.8.1","filepath-1.4.200.1","process-1.6.17.0"],"exe-depends":[],"component-name":"exe:hsc2hs","bin-file":"/home/hecate/Projects/Flora/1-flora-server/_build/cabal-store/ghc-9.6.4/hsc2hs-0.68.10-e-hsc2hs-3b4e464e6a657183d9f83bd37c6d876421d9f6d00ca34e12b12ca3365e55159d/bin/hsc2hs"},{"type":"configured","id":"hspec-2.11.7-e5ff04a60a8c23d1953854fc051870a447d8cf15eac67b388ed88c8c0711ecd0","pkg-name":"hspec","pkg-version":"2.11.7","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"2869580a2a29e7beb6268ea3dc561583f4ae229ed1f47fb1c92e8c09ce35acec","pkg-src-sha256":"2a3e108abd9ba4133f96131cf22e5e4e4c77f3f125b377e6d4c14719746e3096","depends":["QuickCheck-2.14.3-091d344acf9c963200a9b2af6c5417d91912262a9a84b607d918b50fdf8a8b02","base-4.18.2.0","hspec-core-2.11.7-bd08de6d39a4a92bb0f77a0acddbefeb44097fad60030fb9a37560e06da00a3d","hspec-discover-2.11.7-0a5ad2b844295ffaf106e018fc6b84c09cb732bdd31518d7d2ef593ad4cb5b27","hspec-expectations-0.8.4-4186df589755fef0bfbd675b6f8cdae8d4fa1bb936ff33dcfeeeef23aca9e02b"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"hspec-core-2.11.7-bd08de6d39a4a92bb0f77a0acddbefeb44097fad60030fb9a37560e06da00a3d","pkg-name":"hspec-core","pkg-version":"2.11.7","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"90d8873356d7e15f843bc523360e206e8e356ff6b82a1fa4b3889dc31d073ea1","pkg-src-sha256":"6ffa9b86b8a79bb7e8de47c4c850a2e2500f770827d6645ff478ea50f731b134","depends":["HUnit-1.6.2.0-d1570da0a2808fb4ce9b1c3f1e99a0cf4a27d7c4071d9714ae835af7748ace92","QuickCheck-2.14.3-091d344acf9c963200a9b2af6c5417d91912262a9a84b607d918b50fdf8a8b02","ansi-terminal-1.0.2-f2271bf25e5299c165409ab78d5917aeba79c479959932bb5fb284c513226fc0","array-0.5.6.0","base-4.18.2.0","call-stack-0.4.0-a0fd887e5d06d11a75269d5dfed7da6fe2656edbbd7cc1697fb2a2b8ad4fe392","deepseq-1.4.8.1","directory-1.3.8.1","filepath-1.4.200.1","haskell-lexer-1.1.1-833f66de7c919d07c41146e9931dfd902b8b694cd3302de1c3d836c85a3c47a3","hspec-expectations-0.8.4-4186df589755fef0bfbd675b6f8cdae8d4fa1bb936ff33dcfeeeef23aca9e02b","process-1.6.17.0","quickcheck-io-0.2.0-72cfeb1839042c70144c107e73cbb146738a02891278b479561ca9d6da09e7d6","random-1.2.1.2-cc746490e13a1f967de173a54c09753b2ccdb5d95056b0f1206a29c62c83de45","stm-2.5.1.0","tf-random-0.5-d20b981bd0edba50c6bca263adb1566e44b7f7cb2b92de86a3f3b07af9e476eb","time-1.12.2","transformers-0.6.1.0"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"hspec-discover-2.11.7-0a5ad2b844295ffaf106e018fc6b84c09cb732bdd31518d7d2ef593ad4cb5b27","pkg-name":"hspec-discover","pkg-version":"2.11.7","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"6307eb16d308258a99a242025df50217d835ba0a3f205b1202a100a175877b38","pkg-src-sha256":"2862b230bb45eb320dd985659b81b482de98f869f4ed88398555a6a7cd12d82a","depends":["base-4.18.2.0","directory-1.3.8.1","filepath-1.4.200.1"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"hspec-discover-2.11.7-e-hspec-discover-052bee0253fffdc2b9ca8c624ab1ff0f1164b1a50fb6477f7c1f138014bb4b61","pkg-name":"hspec-discover","pkg-version":"2.11.7","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"6307eb16d308258a99a242025df50217d835ba0a3f205b1202a100a175877b38","pkg-src-sha256":"2862b230bb45eb320dd985659b81b482de98f869f4ed88398555a6a7cd12d82a","depends":["base-4.18.2.0","directory-1.3.8.1","filepath-1.4.200.1","hspec-discover-2.11.7-0a5ad2b844295ffaf106e018fc6b84c09cb732bdd31518d7d2ef593ad4cb5b27"],"exe-depends":[],"component-name":"exe:hspec-discover","bin-file":"/home/hecate/Projects/Flora/1-flora-server/_build/cabal-store/ghc-9.6.4/hspec-discover-2.11.7-e-hspec-discover-052bee0253fffdc2b9ca8c624ab1ff0f1164b1a50fb6477f7c1f138014bb4b61/bin/hspec-discover"},{"type":"configured","id":"hspec-expectations-0.8.4-4186df589755fef0bfbd675b6f8cdae8d4fa1bb936ff33dcfeeeef23aca9e02b","pkg-name":"hspec-expectations","pkg-version":"0.8.4","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"4237f094a7931202ff57ac6475542b0b314b50a7024550e2b6eb87cfb0d4ff93","pkg-src-sha256":"7b8dde7e230ecfda90c95fd80478b244a45e68602fb3dd4a76f4710619be21ff","depends":["HUnit-1.6.2.0-d1570da0a2808fb4ce9b1c3f1e99a0cf4a27d7c4071d9714ae835af7748ace92","base-4.18.2.0","call-stack-0.4.0-a0fd887e5d06d11a75269d5dfed7da6fe2656edbbd7cc1697fb2a2b8ad4fe392"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"hsyslog-5.0.2-9ac10b37c77c7762f93b70afc58e9b363345f68fafa0faa62d9b9e8fc01b8031","pkg-name":"hsyslog","pkg-version":"5.0.2","flags":{"install-examples":false},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"0b604c9f3d1bcbe7cd223b1b530110309ae01f2d7c57bc08ffc4fc31ad21324c","pkg-src-sha256":"3eec43c8fb42c23d03f1db7b0b594d39cd94275c2284dcd0c64aa4d680bd7ece","depends":["base-4.18.2.0"],"exe-depends":["hsc2hs-0.68.10-e-hsc2hs-3b4e464e6a657183d9f83bd37c6d876421d9f6d00ca34e12b12ca3365e55159d"],"component-name":"lib"},{"type":"configured","id":"http-api-data-0.6-f8db4c3e7ff814c1476ac3873683211db56d23f0c28cabdd051460114fc3de4f","pkg-name":"http-api-data","pkg-version":"0.6","flags":{"use-text-show":false},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"fb724ab5d42656b1f0f982ffb73ccb457ef73c6d6461f6a1b2b0a70d41d05d6e","pkg-src-sha256":"74904382dfd0774a34fef881d895afafdb856bd57f162db275cfe550a1dc1346","depends":["base-4.18.2.0","bytestring-0.11.5.3","containers-0.6.7","cookie-0.4.6-0f17f671a430f9d3670a38aa989d096c8a941ff590a1a1a5bc4f595def792f73","hashable-1.4.3.0-17b447e0ce504d4e093d6bf5a9838da3805c7caa5d16355da40827d004febbc8","http-types-0.12.4-0f52a9ec33f3c65ef0b77ad8ce14b65f9164f8a761e42800dc9c80ee1768aacc","tagged-0.8.8-5d06ce789c37adf39496775b08f7d82bb9509e4c2a3f973b0c868e35bca55ad5","text-2.0.2","text-iso8601-0.1-ca672f6e92319e19ff854d44b5ac9b4e7c827c1996a06b87b8a221dbacac85fb","time-compat-1.9.6.1-2b2aa066adc7c0d5baad9d0716626a41574966c2265b4ff355b83a2bfd5ca61a","transformers-0.6.1.0","unordered-containers-0.2.20-013ecc3e94c07bd5bdb23da8c9cf4d68ac66e04c4144b4096b291104672db345","uuid-types-1.0.5.1-c19e00cab51fb72d8874dd99ac787f44fda9996af8117c2d227cfb3294e06a9c"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"http-client-0.7.16-08ac6af6261aa24f586bbb528e8ea2f0bd2e7510d1883948d770173e7ea8b633","pkg-name":"http-client","pkg-version":"0.7.16","flags":{"network-uri":true},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"af80ec3d34534d1db1148ef6a54eb87d5364261236ade169ba0603a2e441fb8f","pkg-src-sha256":"3a84ca8f94306084aef3ff5128db231cb6bb7c606fbee16910f8d0df400c6291","depends":["array-0.5.6.0","async-2.2.4-2107e60f1bee7c70ffed77e551ffc7db01e350edd8784cc9493cc782305122d0","base-4.18.2.0","base64-bytestring-1.2.1.0-ecb3bf792eac6ec696f20e02e528e8a7b2a76a5b32c46409c4645e1bfbd71cf4","blaze-builder-0.4.2.3-60676f992d653075aeba6aad80b2dd0b054859608a5712ecfc9d4a4968aefdb8","bytestring-0.11.5.3","case-insensitive-1.2.1.0-5255eaf892b10e8489fdad145ca833a10864bd951f3e69d04088fbcadf28ec6d","containers-0.6.7","cookie-0.4.6-0f17f671a430f9d3670a38aa989d096c8a941ff590a1a1a5bc4f595def792f73","deepseq-1.4.8.1","exceptions-0.10.7","filepath-1.4.200.1","ghc-prim-0.10.0","http-types-0.12.4-0f52a9ec33f3c65ef0b77ad8ce14b65f9164f8a761e42800dc9c80ee1768aacc","iproute-1.7.12-1154efefaf645ab127d46e471b4ebe1968e3b3f8497cc0b74c21385bb289cbb0","mime-types-0.1.2.0-3d20aa710271c28a90c1e88feb88ab239804502c494312d5102d19e4b368709f","network-3.1.4.0-9d41c9df77e8d21da5aaf51c19540d3c0fc11e5e2c2940bea5411915b8a462ff","network-uri-2.6.4.2-d62d36021f4a84b02c9243cbe37e9dfd5b7ba840b4aaedb5e002f05582564fc4","random-1.2.1.2-cc746490e13a1f967de173a54c09753b2ccdb5d95056b0f1206a29c62c83de45","stm-2.5.1.0","streaming-commons-0.2.2.6-9fa4239301ef39252b6218423c0a2438611fe43c2ddbebd4f8953d4455c07935","text-2.0.2","time-1.12.2","transformers-0.6.1.0"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"http-client-tls-0.3.6.3-67f7c5e1b646b6720d31cd47b325354e5e9c257cef0d9522c9b4a5648422c65e","pkg-name":"http-client-tls","pkg-version":"0.3.6.3","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"a5909ce412ee65c141b8547f8fe22236f175186c95c708e86a46b5547394f910","pkg-src-sha256":"38dcfc3d772eb6898b4a8856d6159824d13f65eb291733619f625a802dad9095","depends":["base-4.18.2.0","bytestring-0.11.5.3","case-insensitive-1.2.1.0-5255eaf892b10e8489fdad145ca833a10864bd951f3e69d04088fbcadf28ec6d","containers-0.6.7","crypton-0.34-c8d7db2766b56c26f144f8f589058be74cfcc7e68ff2d08f8f41d2ef1a1fa0e8","crypton-connection-0.3.2-804034b7a3e50ed75e1849613e844c1579d8bd18848efe958529bc613747e852","data-default-class-0.1.2.0-4350681fcf6087f7ee4836ea8af486e6eeb8f64bb56f88dbd081081499b0bef6","exceptions-0.10.7","http-client-0.7.16-08ac6af6261aa24f586bbb528e8ea2f0bd2e7510d1883948d770173e7ea8b633","http-types-0.12.4-0f52a9ec33f3c65ef0b77ad8ce14b65f9164f8a761e42800dc9c80ee1768aacc","memory-0.18.0-273ad672f1703dee0dfe07994633c93d17f815a149738659ef6afa30cbe4f6a8","network-3.1.4.0-9d41c9df77e8d21da5aaf51c19540d3c0fc11e5e2c2940bea5411915b8a462ff","network-uri-2.6.4.2-d62d36021f4a84b02c9243cbe37e9dfd5b7ba840b4aaedb5e002f05582564fc4","text-2.0.2","tls-2.0.1-b47e0fd7dac1558b195f1752f4ccbcc31081e04ec060bb63474359a715d7657d","transformers-0.6.1.0"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"http-conduit-2.3.8.3-4ad7853d8f1fc07a23d239e66fd76a570e24733747408dace515a7e5a7be3940","pkg-name":"http-conduit","pkg-version":"2.3.8.3","flags":{"aeson":true},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"82f7d4d5d1d4d9bf99c008ee91c221952560096161c77577fa941e799d3d3677","pkg-src-sha256":"6a5109528a2d2a795bac6a7de9486436a7f09d2d3b8949af11b5372bd9ddd7f4","depends":["aeson-2.2.1.0-2595d249b227784b9febcd5a91568775f66fd262ac45c82c44f7b4a55e9d4c27","attoparsec-0.14.4-5061b5f729de9f72f69961345d54e0249a28df7c232bb9cf2b0525b6f17a253a","attoparsec-aeson-2.2.0.1-768c79d04d1cb0ad1b116957e8c9aabf909372ca2c907dc42310e8efd0a37a03","base-4.18.2.0","bytestring-0.11.5.3","conduit-1.3.5-96fa916ebd7a150aa66076e6ed1e4a9d7982e51658f9fd750ad31ce33c46afd7","conduit-extra-1.3.6-a9b74b7c97cb9e39e8f4262bfd1952b446fe950cb07e127ba073c16301e30755","http-client-0.7.16-08ac6af6261aa24f586bbb528e8ea2f0bd2e7510d1883948d770173e7ea8b633","http-client-tls-0.3.6.3-67f7c5e1b646b6720d31cd47b325354e5e9c257cef0d9522c9b4a5648422c65e","http-types-0.12.4-0f52a9ec33f3c65ef0b77ad8ce14b65f9164f8a761e42800dc9c80ee1768aacc","mtl-2.3.1","resourcet-1.3.0-0f210c6e8ffe9f595ad8fd1a6cf6726e42a6695abb7febee22452f40436a2bc5","transformers-0.6.1.0","unliftio-core-0.2.1.0-1e6dce1dfe73ef335e0615b0af7f06b171c3572cf7a04fe671b6cec407b73dee"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"http-date-0.0.11-4d5bd8aa95bbcd52e33572812314a340168d474209374f7c85b86a113b02b6f3","pkg-name":"http-date","pkg-version":"0.0.11","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"b278b07f880705e3b0b073206ad26954548b666d616733c9a6b5d50993f547d4","pkg-src-sha256":"32f923ac1ad9bdfeadce7c52a03c9ba6225ba60dc14137cb1cdf32ea84ccf4d3","depends":["array-0.5.6.0","attoparsec-0.14.4-5061b5f729de9f72f69961345d54e0249a28df7c232bb9cf2b0525b6f17a253a","base-4.18.2.0","bytestring-0.11.5.3","time-1.12.2"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"http-media-0.8.1.1-82ac8def17fc7bb0c409983a665f6b7cccbfddad16ad03396e0ea28fa6b4797e","pkg-name":"http-media","pkg-version":"0.8.1.1","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"d39d81cac3e183d8a1659efb26e3bcda788721e07058be024a91621c60ed8a6e","pkg-src-sha256":"1920adf31b15d167f60374fbfd0a53a1fbe7820fd7fd459beacf6eb00d03f183","depends":["base-4.18.2.0","bytestring-0.11.5.3","case-insensitive-1.2.1.0-5255eaf892b10e8489fdad145ca833a10864bd951f3e69d04088fbcadf28ec6d","containers-0.6.7","utf8-string-1.0.2-5e8d116496349c38d20293f85d47a22c703548b74e7d267d8d6d20ff907c03cd"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"http-types-0.12.4-0f52a9ec33f3c65ef0b77ad8ce14b65f9164f8a761e42800dc9c80ee1768aacc","pkg-name":"http-types","pkg-version":"0.12.4","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"c8bdda528c9d74dea90effb30958fdacdb09b116c61a63b6f1b233ffea72b776","pkg-src-sha256":"4d4b1bb0cc817e5fef0c9c76c9647f69f4d300c45a105043493eff86381be549","depends":["array-0.5.6.0","base-4.18.2.0","bytestring-0.11.5.3","case-insensitive-1.2.1.0-5255eaf892b10e8489fdad145ca833a10864bd951f3e69d04088fbcadf28ec6d","text-2.0.2"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"http2-5.0.1-751b9c3f95a93da8cddfb732f2965a32e07b1353df03d60f755b561f5ddd83d2","pkg-name":"http2","pkg-version":"5.0.1","flags":{"devel":false,"h2spec":false},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"3efc2b788a6e76e4f1ae47a29ff6dd6ae0ebf730a607c8fda7a767e98c10a862","pkg-src-sha256":"3bf0f51b8753b7c3f9e80aab6d5af40c49ed3b3c16dc6498c3f1d42301a499d5","depends":["array-0.5.6.0","async-2.2.4-2107e60f1bee7c70ffed77e551ffc7db01e350edd8784cc9493cc782305122d0","base-4.18.2.0","bytestring-0.11.5.3","case-insensitive-1.2.1.0-5255eaf892b10e8489fdad145ca833a10864bd951f3e69d04088fbcadf28ec6d","containers-0.6.7","http-types-0.12.4-0f52a9ec33f3c65ef0b77ad8ce14b65f9164f8a761e42800dc9c80ee1768aacc","network-3.1.4.0-9d41c9df77e8d21da5aaf51c19540d3c0fc11e5e2c2940bea5411915b8a462ff","network-byte-order-0.1.7-6187e46250f032410d7a0260e366b7a19b0a14bfb995a55c702a814854302ac5","network-control-0.0.2-7c769723340179dac91438f2426d2634daade0d81c9bc8565a97df5f0784660c","stm-2.5.1.0","time-manager-0.0.1-bda26b5ab69166d31b9d00a6f11da4ed98f23c5730095e52dea9d4e88200bb30","unix-time-0.4.12-45eb997f2b10c03cbe95532ca065341d046b4309aac2f8aad0358668133acf67","unliftio-0.2.25.0-494677154ed69a76841d775b50166f52e9d0797a41ece2fd3d94e08aebf372f3"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"indexed-profunctors-0.1.1.1-8d925dea1c4443bc16b2bc6a7c10d1b7794d7d65d9ab1d1c3b10993e592e1e9e","pkg-name":"indexed-profunctors","pkg-version":"0.1.1.1","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"c9beac8df06dda097d9dc7a8d60f9e5fb6ecaf56c40938bb30b132ee09f15c87","pkg-src-sha256":"2e69bb2900bb7e562efffff7bcf3f72daf79f013232ce603263a57595412c398","depends":["base-4.18.2.0"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"indexed-traversable-0.1.3-8f7210e35c0cb4bf73ec163bed4014cbba70e17aa189447497a492e60990637b","pkg-name":"indexed-traversable","pkg-version":"0.1.3","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"911f96592752ce4ffbeda00b1155dbbfac5135c71d6755ae02c00552819a9b17","pkg-src-sha256":"1d32925fb6f78e3a52a849b29fc4360df51c97be95ba8ac642517d3ff01a53d9","depends":["array-0.5.6.0","base-4.18.2.0","containers-0.6.7","transformers-0.6.1.0"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"indexed-traversable-instances-0.1.1.2-23d2e9c28613d77bfd5595533e39512e3e8b808382cee8d422cee021acbf7fc4","pkg-name":"indexed-traversable-instances","pkg-version":"0.1.1.2","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"00d5e3e149e2bee0f7a547e0093294c306d4276e73a619abe7d8e69f7ce03c7b","pkg-src-sha256":"0f9b4e895ccc819f74d15f913c93613cc74cab74dbb05d7e305aa387bdbe374a","depends":["OneTuple-0.4.1.1-8e8d21c288285c8a6e306ca430dcdc949a96b5c76772aaa2b31f79c6abb3541e","base-4.18.2.0","indexed-traversable-0.1.3-8f7210e35c0cb4bf73ec163bed4014cbba70e17aa189447497a492e60990637b","tagged-0.8.8-5d06ce789c37adf39496775b08f7d82bb9509e4c2a3f973b0c868e35bca55ad5","unordered-containers-0.2.20-013ecc3e94c07bd5bdb23da8c9cf4d68ac66e04c4144b4096b291104672db345","vector-0.13.1.0-eb53bdac16f057ad838f4e8cb865b51b400abac71a36dc5bfde93ea1d0859eae"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"insert-ordered-containers-0.2.5.3-3706f6956e9c93eb40f4960ef2def44ebba2c69366f9391e537c47e536d7a5e7","pkg-name":"insert-ordered-containers","pkg-version":"0.2.5.3","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"7648a0e91b0af2ed553d3950f098438b999c50d885781fc256823b7032d7d389","pkg-src-sha256":"f04f6e59795d8e362d15422a62d7c7c48312c2d97d2bc4372002a8a9b9a2436c","depends":["aeson-2.2.1.0-2595d249b227784b9febcd5a91568775f66fd262ac45c82c44f7b4a55e9d4c27","base-4.18.2.0","deepseq-1.4.8.1","hashable-1.4.3.0-17b447e0ce504d4e093d6bf5a9838da3805c7caa5d16355da40827d004febbc8","indexed-traversable-0.1.3-8f7210e35c0cb4bf73ec163bed4014cbba70e17aa189447497a492e60990637b","lens-5.2.3-fd9d842bd7b66c837b8b9d8ed9b74a1913e207465f21d80d3c84691d23c5c119","optics-core-0.4.1.1-f8d9a3ddd3e59e269ad03738aca54bb92446a15ba98a2b4ae8ec19ed7d20df70","optics-extra-0.4.2.1-14425af293a1407bfbe91e7d352b65135de2d1e89bcd3809c37b7b5300219c9f","semigroupoids-6.0.0.1-e83bc6491c75c3522014917ab4d3335127e2ee3b4989f0a49f9791f8bead28c6","text-2.0.2","transformers-0.6.1.0","unordered-containers-0.2.20-013ecc3e94c07bd5bdb23da8c9cf4d68ac66e04c4144b4096b291104672db345"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"integer-conversion-0.1.0.1-8c064ed0d1fb658105e6fb4ccc9c29b5609d33ee30393dfe431660a716d124d0","pkg-name":"integer-conversion","pkg-version":"0.1.0.1","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"0e57a82635323f015b5d6c242bcfbbeeaa9854fe9c8058e57052254dbb24bb14","pkg-src-sha256":"20ac70cf1cb65458bba2c562c209a8930e45bdb89886182d644d0a457fc46f39","depends":["base-4.18.2.0","bytestring-0.11.5.3","primitive-0.9.0.0-a6aa61bd9fff8d6cfd4880894dd85d8e644fbcf178b2bff38f87569871ea4a0d","text-2.0.2"],"exe-depends":[],"component-name":"lib"},{"type":"pre-existing","id":"integer-gmp-1.1","pkg-name":"integer-gmp","pkg-version":"1.1","depends":["base-4.18.2.0","ghc-bignum-1.3","ghc-prim-0.10.0"]},{"type":"configured","id":"integer-logarithms-1.0.3.1-49bf09c2474200e80cd296b047116a8ad20403e42301ba2d71d615b2824b3fcd","pkg-name":"integer-logarithms","pkg-version":"1.0.3.1","flags":{"check-bounds":false,"integer-gmp":true},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"4d0dfc334e64ff57bb1a08717afa4a4a7f28e4cdc46615dd287be31ef63ec00d","pkg-src-sha256":"9b0a9f9fab609b15cd015865721fb05f744a1bc77ae92fd133872de528bbea7f","depends":["array-0.5.6.0","base-4.18.2.0","ghc-bignum-1.3","ghc-prim-0.10.0"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"invariant-0.6.2-8ec7276e1c699d2bb785b2aeacbc2b3a667b510a0c0b568bb58241106a6d17a2","pkg-name":"invariant","pkg-version":"0.6.2","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"4338158fe36c3ff9ee741eeff79cb886222cab9da3f476071956cb01b0d9bbff","pkg-src-sha256":"c36485e8088a57e9df1a93881211a1c09e8920ce1b14bfa141cac9f75b7ee108","depends":["StateVar-1.2.2-ad33ce876594474d931417853bfd72c6eb94d534a6634dcbf0af13ec95c0e031","array-0.5.6.0","base-4.18.2.0","bifunctors-5.6.1-3bfddc97d0532e0f4bedd1f64454f96744d2fe805f93a5f9e443c2c5e1035ff1","comonad-5.0.8-8505feb1b75f0b6bf19ef9b666132d0031c1214df6db91aab78f0a9def57751c","containers-0.6.7","contravariant-1.5.5-45cb856efb41788f255562487551496b619a1cf555a23fc4a29495fda3e0c50f","ghc-prim-0.10.0","profunctors-5.6.2-8b084a9552445e5776f01a7b42f1722ce1ecf20cf9a8e839007b9baea33b9fa4","stm-2.5.1.0","tagged-0.8.8-5d06ce789c37adf39496775b08f7d82bb9509e4c2a3f973b0c868e35bca55ad5","template-haskell-2.20.0.0","th-abstraction-0.6.0.0-b49a83d27ea2604c7977c309bd302e93941309c5040c248dbdb6b55147976b2b","transformers-0.6.1.0","transformers-compat-0.7.2-15ca92c51f3c4b3e5a349c3cc2a7f406ca01ba50aecd92a631a1c4d508b1230f","unordered-containers-0.2.20-013ecc3e94c07bd5bdb23da8c9cf4d68ac66e04c4144b4096b291104672db345"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"iproute-1.7.12-1154efefaf645ab127d46e471b4ebe1968e3b3f8497cc0b74c21385bb289cbb0","pkg-name":"iproute","pkg-version":"1.7.12","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"85d181599fab8ceebf4c849110ad571bea2834d6c8c95ae7da33856c42453f40","pkg-src-sha256":"f1751d1579fcbc1d9f86d9d1c9ede48cb71cbeb1d7b2043491c6216e4f236b63","depends":["appar-0.1.8-588a61c15c8bd457e6a1dd16deebaeef67d39cbf3527f952054c1230e05fa294","base-4.18.2.0","byteorder-1.0.4-fa2515b96f172f97bd2e2638b538e2286cb035eb8b87892a4857a50c6e738631","bytestring-0.11.5.3","containers-0.6.7","network-3.1.4.0-9d41c9df77e8d21da5aaf51c19540d3c0fc11e5e2c2940bea5411915b8a462ff"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"iso8601-time-0.1.5-613661a1ea46bf04f83cf7f01f86b46eac75038540215814c13f119e8c47a17d","pkg-name":"iso8601-time","pkg-version":"0.1.5","flags":{"new-time":true},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"4b690a86f4948557c802b5298e07d9076ef4ea7142baaad20c9847a9030a8c40","pkg-src-sha256":"f2cd444b2be68402c773a4b451912817f06d33093aea691b42ebeed3630ff0c8","depends":["base-4.18.2.0","time-1.12.2"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"kan-extensions-5.2.5-60f11eb11e93cf481fad2a42529d0965e7472bd8d512eba70477a626921ed65c","pkg-name":"kan-extensions","pkg-version":"5.2.5","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"fbdba767565f40faf515b044a774cc3b371eb6ce8a082d9f659411cea88698cf","pkg-src-sha256":"b914dccc040caf1d8764b99df1028dad3e4fdf46c262192e54b59c9da66ead22","depends":["adjunctions-4.4.2-f3221dcb76f82009b3161054c42f2ac113ea03b7e3e1a3d9dff315fac6299a27","array-0.5.6.0","base-4.18.2.0","comonad-5.0.8-8505feb1b75f0b6bf19ef9b666132d0031c1214df6db91aab78f0a9def57751c","containers-0.6.7","contravariant-1.5.5-45cb856efb41788f255562487551496b619a1cf555a23fc4a29495fda3e0c50f","distributive-0.6.2.1-70a2f4c4bffafd7749c1d755f27db885f954a9d9be1cd7db8a6e99887121ec8c","free-5.2-841f6f1c7522ed92dbed9d024b48671e79a9cdd76652f8bdbf9c0e63908771e7","invariant-0.6.2-8ec7276e1c699d2bb785b2aeacbc2b3a667b510a0c0b568bb58241106a6d17a2","mtl-2.3.1","profunctors-5.6.2-8b084a9552445e5776f01a7b42f1722ce1ecf20cf9a8e839007b9baea33b9fa4","semigroupoids-6.0.0.1-e83bc6491c75c3522014917ab4d3335127e2ee3b4989f0a49f9791f8bead28c6","tagged-0.8.8-5d06ce789c37adf39496775b08f7d82bb9509e4c2a3f973b0c868e35bca55ad5","transformers-0.6.1.0","transformers-compat-0.7.2-15ca92c51f3c4b3e5a349c3cc2a7f406ca01ba50aecd92a631a1c4d508b1230f"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"lens-5.2.3-fd9d842bd7b66c837b8b9d8ed9b74a1913e207465f21d80d3c84691d23c5c119","pkg-name":"lens","pkg-version":"5.2.3","flags":{"benchmark-uniplate":false,"dump-splices":false,"inlining":true,"j":false,"test-hunit":true,"test-properties":true,"test-templates":true,"trustworthy":true},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"637287c76adff383063b3206a4213640de1a74839ec16008cc71b5b407f7d05e","pkg-src-sha256":"df1e8ca8dd89d884994e0c80761a972088326fa43ed5d47c01b14abb710b994d","depends":["array-0.5.6.0","assoc-1.1-44564689989a4d2721c54fe7433f3b2450e556c3fe6c52752ad54623647f561c","base-4.18.2.0","base-orphans-0.9.1-61d128d6a3318593c785a97751f2418cc86b42b03e2b46ed92e9b27fc5da689c","bifunctors-5.6.1-3bfddc97d0532e0f4bedd1f64454f96744d2fe805f93a5f9e443c2c5e1035ff1","bytestring-0.11.5.3","call-stack-0.4.0-a0fd887e5d06d11a75269d5dfed7da6fe2656edbbd7cc1697fb2a2b8ad4fe392","comonad-5.0.8-8505feb1b75f0b6bf19ef9b666132d0031c1214df6db91aab78f0a9def57751c","containers-0.6.7","contravariant-1.5.5-45cb856efb41788f255562487551496b619a1cf555a23fc4a29495fda3e0c50f","distributive-0.6.2.1-70a2f4c4bffafd7749c1d755f27db885f954a9d9be1cd7db8a6e99887121ec8c","exceptions-0.10.7","filepath-1.4.200.1","free-5.2-841f6f1c7522ed92dbed9d024b48671e79a9cdd76652f8bdbf9c0e63908771e7","ghc-prim-0.10.0","hashable-1.4.3.0-17b447e0ce504d4e093d6bf5a9838da3805c7caa5d16355da40827d004febbc8","indexed-traversable-0.1.3-8f7210e35c0cb4bf73ec163bed4014cbba70e17aa189447497a492e60990637b","indexed-traversable-instances-0.1.1.2-23d2e9c28613d77bfd5595533e39512e3e8b808382cee8d422cee021acbf7fc4","kan-extensions-5.2.5-60f11eb11e93cf481fad2a42529d0965e7472bd8d512eba70477a626921ed65c","mtl-2.3.1","parallel-3.2.2.0-86a50f94aa82e9af5f21bfb4d27ed83c8cf2231ac3fb348b2b433b2f10943c05","profunctors-5.6.2-8b084a9552445e5776f01a7b42f1722ce1ecf20cf9a8e839007b9baea33b9fa4","reflection-2.1.7-6e3964bab098962c0f1cc95d37584b10d2c12c8d4578f9c794643c142cc40415","semigroupoids-6.0.0.1-e83bc6491c75c3522014917ab4d3335127e2ee3b4989f0a49f9791f8bead28c6","strict-0.5-84b2c7152a9fd6aee3e1d1082edade7580c5af3226a0afc18e19724ada9d7fe4","tagged-0.8.8-5d06ce789c37adf39496775b08f7d82bb9509e4c2a3f973b0c868e35bca55ad5","template-haskell-2.20.0.0","text-2.0.2","th-abstraction-0.6.0.0-b49a83d27ea2604c7977c309bd302e93941309c5040c248dbdb6b55147976b2b","these-1.2-a7d4e934136841dac2b8ed0dc77fee3f581d8c4e25fe99bdad5b76406c57bf16","transformers-0.6.1.0","transformers-compat-0.7.2-15ca92c51f3c4b3e5a349c3cc2a7f406ca01ba50aecd92a631a1c4d508b1230f","unordered-containers-0.2.20-013ecc3e94c07bd5bdb23da8c9cf4d68ac66e04c4144b4096b291104672db345","vector-0.13.1.0-eb53bdac16f057ad838f4e8cb865b51b400abac71a36dc5bfde93ea1d0859eae"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"libsodium-bindings-0.0.1.1-203ee47d320ef77833137696f6f56e75297ffec7d7a2503d46941bdb48c428b0","pkg-name":"libsodium-bindings","pkg-version":"0.0.1.1","flags":{"homebrew-libsodium":false,"use-pkg-config":false},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"1fb61987c7c70cd3f203b66b54370d8bce7382d8204452cf32aca780700dcb35","pkg-src-sha256":"aaada3df0291c982ee4d65975ad0332aa6cb72875c7d0feb5023d07c08d7d33d","depends":["base-4.18.2.0"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"lifted-async-0.10.2.5-0e5383cde07ceba316c6eb9f965038eb2ea32a6c803d5b96f22bdcdba63bfe14","pkg-name":"lifted-async","pkg-version":"0.10.2.5","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"2025bfa72a42232b5dee72ed16440762996415c912e6a26957fbaa7bd79cc0a3","pkg-src-sha256":"16a0d603a220724c013270cad78f56b8fc23ca428a9df844061ad32bc6961ed2","depends":["async-2.2.4-2107e60f1bee7c70ffed77e551ffc7db01e350edd8784cc9493cc782305122d0","base-4.18.2.0","constraints-0.14-ab15a9f94938365a9f7a935af490e603978d84c5e110ef254a28de6613181c00","lifted-base-0.2.3.12-40327bf54bf51ef75eab04e6e7c88e46b7f1de3255d1ec5ed76d02fc71c9cdf5","monad-control-1.0.3.1-2bf3452c923aa94707518b6d970f4377279fd8c4ccca1256725eef18b6097440","transformers-base-0.4.6-91c64a4b19c3f5f9f196345e9032803d52322bd0857ba94ea6c4260a27a2ff07"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"lifted-base-0.2.3.12-40327bf54bf51ef75eab04e6e7c88e46b7f1de3255d1ec5ed76d02fc71c9cdf5","pkg-name":"lifted-base","pkg-version":"0.2.3.12","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"e94ad0692c9c5d85c373e508f23654f2da8ac8c3e475c2b65ffbc04fb165ad69","pkg-src-sha256":"c134a95f56750aae806e38957bb03c59627cda16034af9e00a02b699474317c5","depends":["base-4.18.2.0","monad-control-1.0.3.1-2bf3452c923aa94707518b6d970f4377279fd8c4ccca1256725eef18b6097440","transformers-base-0.4.6-91c64a4b19c3f5f9f196345e9032803d52322bd0857ba94ea6c4260a27a2ff07"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"lockfree-queue-0.2.4-db50ab392a0002236dd2987e766180a4fb8a8cc2c59dcf98973caca190b12610","pkg-name":"lockfree-queue","pkg-version":"0.2.4","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"156e7ccc193fc5d8b43f065e9cd31c3171c79ec25863283d546900d92930846d","pkg-src-sha256":"a0f6770cdcbe0c4f86ba2a498af06933db615d83ff5457a1750f733f6ef399ee","depends":["abstract-deque-0.3-58da01f2d5856552665a639ed7e62652de2627cfca39d756a0f29f4265e71d1b","atomic-primops-0.8.5-619a7ba3c59ea074ae39e3adf75904b21a27146e973f334ea4ab876a9cc1e3c2","base-4.18.2.0","ghc-prim-0.10.0"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"log-base-0.12.0.1-f6c93830f52a9d5925fa4be3f430d1262c4e2bbf3222e6a925872b2eec0a9d75","pkg-name":"log-base","pkg-version":"0.12.0.1","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"cd22a5277c58117aef574a846afd6cad17dfec3e505da6c03662246fdd9ee7b0","pkg-src-sha256":"44e37f318de0f415eff5116d1614e5c0ec6ba41acf690f072bf8f8f726872c08","depends":["aeson-2.2.1.0-2595d249b227784b9febcd5a91568775f66fd262ac45c82c44f7b4a55e9d4c27","aeson-pretty-0.8.10-9bd6a60b424b6a69fcd0507ef3b99938ee971580bc5bfa89249b16ff60b2c117","base-4.18.2.0","bytestring-0.11.5.3","deepseq-1.4.8.1","exceptions-0.10.7","mmorph-1.2.0-967f2a66454abded96663c19c27c375e74faace9a8cd232a9ae738ec2604ffa1","monad-control-1.0.3.1-2bf3452c923aa94707518b6d970f4377279fd8c4ccca1256725eef18b6097440","mtl-2.3.1","semigroups-0.20-b7dd1b9febe28a509d4e029a8add1506aac955b99fce2599f25e63f8127812a9","stm-2.5.1.0","text-2.0.2","time-1.12.2","transformers-base-0.4.6-91c64a4b19c3f5f9f196345e9032803d52322bd0857ba94ea6c4260a27a2ff07","unliftio-core-0.2.1.0-1e6dce1dfe73ef335e0615b0af7f06b171c3572cf7a04fe671b6cec407b73dee","unordered-containers-0.2.20-013ecc3e94c07bd5bdb23da8c9cf4d68ac66e04c4144b4096b291104672db345"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"log-effectful-1.0.0.0-1daa99a173049071f9677770e30ef537619d4b74217444ebd179050ac6230f31","pkg-name":"log-effectful","pkg-version":"1.0.0.0","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"126f328c9325c10998289378191dc69e55b5ffdc37a7845f2d0ee57f6f13392e","pkg-src-sha256":"5dff1f43d29299efb8de1a186c0798009b8146b451c31365cc0bb0fbe0fe20a6","depends":["base-4.18.2.0","effectful-core-2.3.0.1-011d84ab0bc8bb2010bac83565500e3039592cab57d902e9a2a502684b92d90f","log-base-0.12.0.1-f6c93830f52a9d5925fa4be3f430d1262c4e2bbf3222e6a925872b2eec0a9d75","text-2.0.2","time-1.12.2"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"lucid-2.11.20230408-181c7ed44fa9b37af3ac434ed53e16dbe6a7ca9ec7ef1f7e5c921196d628f3c0","pkg-name":"lucid","pkg-version":"2.11.20230408","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"1a3bd496343dd314e2e4937ae7ae63f819a6f6ddd42a3177075712d7d35963bd","pkg-src-sha256":"0f112990fee9c5b1c62c64c926147272534781ed8a7225d39dd0248a670f441d","depends":["base-4.18.2.0","blaze-builder-0.4.2.3-60676f992d653075aeba6aad80b2dd0b054859608a5712ecfc9d4a4968aefdb8","bytestring-0.11.5.3","containers-0.6.7","hashable-1.4.3.0-17b447e0ce504d4e093d6bf5a9838da3805c7caa5d16355da40827d004febbc8","mmorph-1.2.0-967f2a66454abded96663c19c27c375e74faace9a8cd232a9ae738ec2604ffa1","mtl-2.3.1","text-2.0.2","transformers-0.6.1.0"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"lucid-alpine-0.1.0.7-b7f14424060b05c5c69e15f1069098caf1990249242463a26aa1a08d9cb5e98c","pkg-name":"lucid-alpine","pkg-version":"0.1.0.7","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"0f62a7bf2c4c97fa3a30cbeae84526e6f98dcbc4df35519f2044edc7a0d1f6ad","pkg-src-sha256":"fd7919480fa483ce19ac5c8774eac78ed541f62be12d36d690fcd8b8baacccdc","depends":["base-4.18.2.0","lucid-2.11.20230408-181c7ed44fa9b37af3ac434ed53e16dbe6a7ca9ec7ef1f7e5c921196d628f3c0","text-2.0.2"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"lucid-alpine-0.1.0.7-e-lucid-alpine-exe-4fb5011bfc617e99d75df24c8bbbadc3b290cd02eeb350e6355203ac92a8462e","pkg-name":"lucid-alpine","pkg-version":"0.1.0.7","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"0f62a7bf2c4c97fa3a30cbeae84526e6f98dcbc4df35519f2044edc7a0d1f6ad","pkg-src-sha256":"fd7919480fa483ce19ac5c8774eac78ed541f62be12d36d690fcd8b8baacccdc","depends":["base-4.18.2.0","lucid-2.11.20230408-181c7ed44fa9b37af3ac434ed53e16dbe6a7ca9ec7ef1f7e5c921196d628f3c0","lucid-alpine-0.1.0.7-b7f14424060b05c5c69e15f1069098caf1990249242463a26aa1a08d9cb5e98c","text-2.0.2"],"exe-depends":[],"component-name":"exe:lucid-alpine-exe","bin-file":"/home/hecate/Projects/Flora/1-flora-server/_build/cabal-store/ghc-9.6.4/lucid-alpine-0.1.0.7-e-lucid-alpine-exe-4fb5011bfc617e99d75df24c8bbbadc3b290cd02eeb350e6355203ac92a8462e/bin/lucid-alpine-exe"},{"type":"configured","id":"lucid-svg-0.7.1.1-2b919f949d217797fe4a4bf74b5ae72e72599c4304e6d78dc5d24024c6bb957f","pkg-name":"lucid-svg","pkg-version":"0.7.1.1","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"52f3842a4fdec8a0f2661b437305fbedae480568428daef93aead58a91ef2c67","pkg-src-sha256":"2dbb8f0575ec7a731442a449d86437e997626d07a1bb2516e20c95baac93d19b","depends":["base-4.18.2.0","blaze-builder-0.4.2.3-60676f992d653075aeba6aad80b2dd0b054859608a5712ecfc9d4a4968aefdb8","lucid-2.11.20230408-181c7ed44fa9b37af3ac434ed53e16dbe6a7ca9ec7ef1f7e5c921196d628f3c0","text-2.0.2","transformers-0.6.1.0"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"megaparsec-9.6.1-ff48fb0fe697114f4c52b8871db38a94f339b62ffe366244b49c58b0b23ad4a5","pkg-name":"megaparsec","pkg-version":"9.6.1","flags":{"dev":false},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"8d8f8ee5aca5d5c16aa4219afd13687ceab8be640f40ba179359f2b42a628241","pkg-src-sha256":"a32257be847dbe71ac22d512ab115f9ce26fa08bcdbea7ca8b5256a1700dcbff","depends":["base-4.18.2.0","bytestring-0.11.5.3","case-insensitive-1.2.1.0-5255eaf892b10e8489fdad145ca833a10864bd951f3e69d04088fbcadf28ec6d","containers-0.6.7","deepseq-1.4.8.1","mtl-2.3.1","parser-combinators-1.3.0-702f2638f70c15b6b5b11fbe7dcdd3e6d0d73f0193261f85b4d42c011d1949f6","scientific-0.3.7.0-ad7c6f4dff0f6cf6540942c40157e54f8c090b5d960104c70801b0a2f7c99215","text-2.0.2","transformers-0.6.1.0"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"memory-0.18.0-273ad672f1703dee0dfe07994633c93d17f815a149738659ef6afa30cbe4f6a8","pkg-name":"memory","pkg-version":"0.18.0","flags":{"support_bytestring":true,"support_deepseq":true},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"e12bde756b01c1a28c62e46f0f8433c4890898051a786794a7d88907ca14abca","pkg-src-sha256":"fd4eb6f638e24b81b4e6cdd68772a531726f2f67686c8969d3407d82f7862e3e","depends":["base-4.18.2.0","basement-0.0.16-2ba9d181df7bdd547d6fedd5acdec581f03e379e22b0e08ff998fb0462257d08","bytestring-0.11.5.3","deepseq-1.4.8.1","ghc-prim-0.10.0"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"microlens-0.4.13.1-7fc67fa4a915fe46c53bdefdd38fdb5fc86a0fe5166c99a699781b2db9bc2c2f","pkg-name":"microlens","pkg-version":"0.4.13.1","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"fc256e2b5d78e8e4f39b3dd359c57b8c19df50853a86eaf8f154a17441a5a51d","pkg-src-sha256":"0a54abee8ff4f6aeb4bea0783409a3dbd28a4e7a892bac916b0fb6a71382d7fc","depends":["base-4.18.2.0"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"mime-types-0.1.2.0-3d20aa710271c28a90c1e88feb88ab239804502c494312d5102d19e4b368709f","pkg-name":"mime-types","pkg-version":"0.1.2.0","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"3ddd330c16da943651db37e237d44dc0593ef9b1a63d39e98a48811644615bf6","pkg-src-sha256":"013ae48a4c1726a4f91a64e882f3fe1fb903a7d4b8c14da51286fe5e4b974f61","depends":["base-4.18.2.0","bytestring-0.11.5.3","containers-0.6.7","text-2.0.2"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"mmorph-1.2.0-967f2a66454abded96663c19c27c375e74faace9a8cd232a9ae738ec2604ffa1","pkg-name":"mmorph","pkg-version":"1.2.0","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"df9b213ec18f811cb3137b478d148f3f1680ee43f841cb775835fa282fdb0295","pkg-src-sha256":"61338058eb676b466a462ca45d59f436a77a3bd6b816e4268c6d88522b6a4280","depends":["base-4.18.2.0","mtl-2.3.1","transformers-0.6.1.0","transformers-compat-0.7.2-15ca92c51f3c4b3e5a349c3cc2a7f406ca01ba50aecd92a631a1c4d508b1230f"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"modern-uri-0.3.6.1-c2deadb57eaf5495142288d2ce86c3ffbf3db59eea2c3ffe34643053cf0d66a0","pkg-name":"modern-uri","pkg-version":"0.3.6.1","flags":{"dev":false},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"183005f5554c040ea7c0a2c63ef99351594d048ccea3787cb5c3248d15ca1530","pkg-src-sha256":"0246f9cfced1227abe3a6403eeacc6b5f79f7e3319759a4dd1fd341c12454fe9","depends":["QuickCheck-2.14.3-091d344acf9c963200a9b2af6c5417d91912262a9a84b607d918b50fdf8a8b02","base-4.18.2.0","bytestring-0.11.5.3","containers-0.6.7","deepseq-1.4.8.1","exceptions-0.10.7","hashable-1.4.3.0-17b447e0ce504d4e093d6bf5a9838da3805c7caa5d16355da40827d004febbc8","megaparsec-9.6.1-ff48fb0fe697114f4c52b8871db38a94f339b62ffe366244b49c58b0b23ad4a5","mtl-2.3.1","profunctors-5.6.2-8b084a9552445e5776f01a7b42f1722ce1ecf20cf9a8e839007b9baea33b9fa4","reflection-2.1.7-6e3964bab098962c0f1cc95d37584b10d2c12c8d4578f9c794643c142cc40415","tagged-0.8.8-5d06ce789c37adf39496775b08f7d82bb9509e4c2a3f973b0c868e35bca55ad5","template-haskell-2.20.0.0","text-2.0.2"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"monad-control-1.0.3.1-2bf3452c923aa94707518b6d970f4377279fd8c4ccca1256725eef18b6097440","pkg-name":"monad-control","pkg-version":"1.0.3.1","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"2d657279839e1a760c86a69f00f0c36473ef6972d413ec0f83a40249c70e098e","pkg-src-sha256":"ae0baea04d99375ef788140367179994a7178d400a8ce0d9026846546772713c","depends":["base-4.18.2.0","stm-2.5.1.0","transformers-0.6.1.0","transformers-base-0.4.6-91c64a4b19c3f5f9f196345e9032803d52322bd0857ba94ea6c4260a27a2ff07","transformers-compat-0.7.2-15ca92c51f3c4b3e5a349c3cc2a7f406ca01ba50aecd92a631a1c4d508b1230f"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"monad-logger-0.3.40-9d168f3d26e168d935793595f1fdbe137ac850b43b0a75ed5c41cd97c589de1e","pkg-name":"monad-logger","pkg-version":"0.3.40","flags":{"template_haskell":true},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"8337b8396d2e1bc414771e68d987f54d6e371bfaad14aa43ed7a41400e44c5ca","pkg-src-sha256":"cbed8667cff6dede6ceac5127bc713b30b700c480fd1405028bd0493f424cea9","depends":["base-4.18.2.0","bytestring-0.11.5.3","conduit-1.3.5-96fa916ebd7a150aa66076e6ed1e4a9d7982e51658f9fd750ad31ce33c46afd7","conduit-extra-1.3.6-a9b74b7c97cb9e39e8f4262bfd1952b446fe950cb07e127ba073c16301e30755","exceptions-0.10.7","fast-logger-3.2.2-f2b66566923a1fa76e5c48eecb73e2ef0a379b38ce325b13b8e81e8022003d26","lifted-base-0.2.3.12-40327bf54bf51ef75eab04e6e7c88e46b7f1de3255d1ec5ed76d02fc71c9cdf5","monad-control-1.0.3.1-2bf3452c923aa94707518b6d970f4377279fd8c4ccca1256725eef18b6097440","monad-loops-0.4.3-7c6b911eed42bfc1b833e8549c1b3cebeb50ddc4be71019205db41fa458f5032","mtl-2.3.1","resourcet-1.3.0-0f210c6e8ffe9f595ad8fd1a6cf6726e42a6695abb7febee22452f40436a2bc5","stm-2.5.1.0","stm-chans-3.0.0.9-577989fa35770d28044d742360c9f0596a5d84e540cf2b1ce7716c9d1fa528e0","template-haskell-2.20.0.0","text-2.0.2","transformers-0.6.1.0","transformers-base-0.4.6-91c64a4b19c3f5f9f196345e9032803d52322bd0857ba94ea6c4260a27a2ff07","transformers-compat-0.7.2-15ca92c51f3c4b3e5a349c3cc2a7f406ca01ba50aecd92a631a1c4d508b1230f","unliftio-core-0.2.1.0-1e6dce1dfe73ef335e0615b0af7f06b171c3572cf7a04fe671b6cec407b73dee"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"monad-loops-0.4.3-7c6b911eed42bfc1b833e8549c1b3cebeb50ddc4be71019205db41fa458f5032","pkg-name":"monad-loops","pkg-version":"0.4.3","flags":{"base4":true},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"ada4f1295ece07f9a7398bc5b40c4532f95a733a8604d2a2f57f05f878766df2","pkg-src-sha256":"7eaaaf6bc43661e9e86e310ff8c56fbea16eb6bf13c31a2e28103138ac164c18","depends":["base-4.18.2.0"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"monad-time-0.4.0.0-1b1c52822cdc65b1e9b65bdb86f7b0aec26973256197697f3b44b64ee669d1f7","pkg-name":"monad-time","pkg-version":"0.4.0.0","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"421f648c30f4bb1b276d3088cf7ee74a45e36d0d12b4a7a542506aa0e301a4e1","pkg-src-sha256":"b4493edf9e7f839cb4ccfcdd53845de493bffbb3ceb4fbb54ba173db68192960","depends":["base-4.18.2.0","mtl-2.3.1","time-1.12.2"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"monad-time-effectful-1.0.0.0-3bcc12595825f15e6c956704de800593d9caa43c86932b7456205b4fcd7a3fee","pkg-name":"monad-time-effectful","pkg-version":"1.0.0.0","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"4994617545bb4b25ba01eaf2bdb1c2c74f7cefab36945af8eb92dca9842fc4b6","pkg-src-sha256":"693e4222d6252c8607f6ee3e32a0ca949eb8f01eb1e0c46d66b6ddbc517eb5bf","depends":["base-4.18.2.0","effectful-core-2.3.0.1-011d84ab0bc8bb2010bac83565500e3039592cab57d902e9a2a502684b92d90f","monad-time-0.4.0.0-1b1c52822cdc65b1e9b65bdb86f7b0aec26973256197697f3b44b64ee669d1f7","time-1.12.2"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"mono-traversable-1.0.15.3-ee2c72a88a7e0e61e75d356539364a91ed39c83311aa5272b47ebaa5412d78cc","pkg-name":"mono-traversable","pkg-version":"1.0.15.3","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"059bf3c05cdbef2d06b765333fe41c2168ced2503a23de674e2a59ceb2548c48","pkg-src-sha256":"98b220f3313d74227a4249210c8818e839678343e62b3ebb1b8c867cf2b974b7","depends":["base-4.18.2.0","bytestring-0.11.5.3","containers-0.6.7","hashable-1.4.3.0-17b447e0ce504d4e093d6bf5a9838da3805c7caa5d16355da40827d004febbc8","split-0.2.5-f91000d531a43d0958a6d552a0e528a48098723972009db93c4b79044dc4bd51","text-2.0.2","transformers-0.6.1.0","unordered-containers-0.2.20-013ecc3e94c07bd5bdb23da8c9cf4d68ac66e04c4144b4096b291104672db345","vector-0.13.1.0-eb53bdac16f057ad838f4e8cb865b51b400abac71a36dc5bfde93ea1d0859eae","vector-algorithms-0.9.0.1-0d5de6c527fb6ba0e7be854c1685b82a6a99d5798a407e65dc55cac4091e272a"],"exe-depends":[],"component-name":"lib"},{"type":"pre-existing","id":"mtl-2.3.1","pkg-name":"mtl","pkg-version":"2.3.1","depends":["base-4.18.2.0","transformers-0.6.1.0"]},{"type":"configured","id":"mtl-compat-0.2.2-9b77842584114154ec5c5ab666cf431f0be7716025713aae3e0ce53ce1b7ad9f","pkg-name":"mtl-compat","pkg-version":"0.2.2","flags":{"two-point-one":false,"two-point-two":false},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"4257fb56e5690734973aad060010bec6c2857f5c1ac6cf87fc335ed3bc7c85f4","pkg-src-sha256":"1955398fe2115674f47f553b2caaf928c6aa3424271a5cd13bc191e54bfe3a9e","depends":["base-4.18.2.0","mtl-2.3.1"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"natural-arithmetic-0.2.1.0-327b3d0462a9fdccd1f5901b636a5c6f1c1996b903146b3f4bf006389c9d4483","pkg-name":"natural-arithmetic","pkg-version":"0.2.1.0","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"1296ff4149f878df02d15a9b0197c6f27f311d56d478223d7e7935f030e293f0","pkg-src-sha256":"36e6e214473eed1bde1bd390d0b697e0e1b1d9682a9fd6747438836982006d9e","depends":["base-4.18.2.0","unlifted-0.2.2.0-331af0eb9d6315f1de30144f92ea1bd99f7de6c15dd09cf6c2850c461258375e"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"network-3.1.4.0-9d41c9df77e8d21da5aaf51c19540d3c0fc11e5e2c2940bea5411915b8a462ff","pkg-name":"network","pkg-version":"3.1.4.0","flags":{"devel":false},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"e152cdb03243afb52bbc740cfbe96905ca298a6f6342f0c47b3f2e227ff19def","pkg-src-sha256":"b452a2afac95d9207357eb3820c719c7c7d27871ef4b6ed7bfcd03a036b9158e","components":{"lib":{"depends":["base-4.18.2.0","bytestring-0.11.5.3","deepseq-1.4.8.1","directory-1.3.8.1"],"exe-depends":["hsc2hs-0.68.10-e-hsc2hs-3b4e464e6a657183d9f83bd37c6d876421d9f6d00ca34e12b12ca3365e55159d"]}}},{"type":"configured","id":"network-byte-order-0.1.7-6187e46250f032410d7a0260e366b7a19b0a14bfb995a55c702a814854302ac5","pkg-name":"network-byte-order","pkg-version":"0.1.7","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"3b6e875fe2f363817b157ecc9c45411ac84544bfa4a30364943e49e817db7fdf","pkg-src-sha256":"480ce0ad7f67364ec8d4ce8d815f463d9e4074e3789be22a5722cfdebed08679","depends":["base-4.18.2.0","bytestring-0.11.5.3"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"network-control-0.0.2-7c769723340179dac91438f2426d2634daade0d81c9bc8565a97df5f0784660c","pkg-name":"network-control","pkg-version":"0.0.2","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"b30f0dc9635a6b1ebda2f77785cec2afef909edecbc2a101d25bcd2b89b5bd99","pkg-src-sha256":"134e9c6f309641bfbb508d8c3957bca76a2715e71138f4c058dba675b06326d4","depends":["base-4.18.2.0","psqueues-0.2.8.0-3b5625b932d73ea3cc0319c7b0eff1a4b49b3ba87f855df869f83ada38fcc584","unix-time-0.4.12-45eb997f2b10c03cbe95532ca065341d046b4309aac2f8aad0358668133acf67"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"network-info-0.2.1-cbd12ac17ed981e872c92e3a8fd70b4ca80c64afdcc8cd7ebfd75eaa846f81c9","pkg-name":"network-info","pkg-version":"0.2.1","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"2798c2e4cc2c32108bd4b05efa921ce6f054ebc381c5e465c9bd74c7d538af17","pkg-src-sha256":"9b2d88312fc8280351d5003200cc07decbb865f85d3aa7b1094b238bd6a8b404","depends":["base-4.18.2.0"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"network-uri-2.6.4.2-d62d36021f4a84b02c9243cbe37e9dfd5b7ba840b4aaedb5e002f05582564fc4","pkg-name":"network-uri","pkg-version":"2.6.4.2","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"6fffb57373962b5651a2db8b0af732098b3bf029a7ced76a9855615de2026588","pkg-src-sha256":"9c188973126e893250b881f20e8811dca06c223c23402b06f7a1f2e995797228","depends":["base-4.18.2.0","deepseq-1.4.8.1","parsec-3.1.16.1","template-haskell-2.20.0.0","th-compat-0.1.4-102530325c2b6ccd251d9c304ca6729eb04836a98ab4cdda25fa565147ccb66e"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"odd-jobs-0.2.3-2ea7e869e131ba9271dc166fb94494d9c4695adf80a10aeb2c6885388c248e44","pkg-name":"odd-jobs","pkg-version":"0.2.3","flags":{},"style":"global","pkg-src":{"type":"source-repo","source-repo":{"type":"git","location":"https://github.com/saurabhnanda/odd-jobs","tag":"411d5d0"}},"pkg-src-sha256":"9276e626c2d938fb0880b134b7dc4b9482db3dce26787821f74d99482afe4e47","depends":["aeson-2.2.1.0-2595d249b227784b9febcd5a91568775f66fd262ac45c82c44f7b4a55e9d4c27","async-2.2.4-2107e60f1bee7c70ffed77e551ffc7db01e350edd8784cc9493cc782305122d0","base-4.18.2.0","bytestring-0.11.5.3","containers-0.6.7","directory-1.3.8.1","either-5.0.2-d8d7bb84305283af81161a95ec2aebe67483cc07c71e171fc392eccfafdfb663","fast-logger-3.2.2-f2b66566923a1fa76e5c48eecb73e2ef0a379b38ce325b13b8e81e8022003d26","filepath-1.4.200.1","friendly-time-0.4.1-abf55dee5aabd3d8d1a3bf852e9269ad8c33f771fd59ecb030b252f999bd9e16","generic-deriving-1.14.5-a1fd2d043c8cafb22abedc758c45dbc284b28f5354f3eb1c717c80c43a96a9e6","hdaemonize-0.5.7-554f4deed801598a70abe3e63685f792ae09fe10e60f21faf1abe49687142f9f","hostname-1.0-5085af94c98cc8316318de7e81d25ddb5a73601cfd27bfccc90a5b913cd9891b","lucid-2.11.20230408-181c7ed44fa9b37af3ac434ed53e16dbe6a7ca9ec7ef1f7e5c921196d628f3c0","monad-control-1.0.3.1-2bf3452c923aa94707518b6d970f4377279fd8c4ccca1256725eef18b6097440","monad-logger-0.3.40-9d168f3d26e168d935793595f1fdbe137ac850b43b0a75ed5c41cd97c589de1e","mtl-2.3.1","optparse-applicative-0.18.1.0-1de8f12cfc2915bc6d323ba97415a7e0795036a6b613e7301735aedf9d0425be","postgresql-simple-0.6.5.1-ec621799555c8b1b15b3683ac92cdc3770e891696c7afc3195aa6f26571cbbe0","resource-pool-0.4.0.0-b943f9aab32b14d553510f77b995882007d913763eb4c8a34a077c78a8909098","safe-0.3.21-31bf385773e1c6ef212139e0505190c20d1e3d1af99bcbfc189c01c3a1e0e739","servant-0.20.1-b63507222e1b19c7b8333551fd2fbdae76248ba97753767f7ab4d32b7816d39d","servant-lucid-0.9.0.6-3245f97c511011e42d95122d5373c12ebeb20de76226f6491768d04935bf6b52","servant-server-0.20-3dbcc60207566a1f80874e61a86b73ab8a41f98f3231692dec244b2ce96f8132","servant-static-th-1.0.0.0-fa0f3ab3712e7a8402c328f207cfc41d9d7c81ead2eb76b54e22775de96a15db","string-conv-0.2.0-2b20138e5715fec3a0be370b62f70071e607c80729c0151ebac083484fb380fb","text-2.0.2","text-conversions-0.3.1.1-b955b2970b27e7be4b7afdac05f3480d3269bc092ad183c3d72cd22fe91a90cd","time-1.12.2","timing-convenience-0.1-532d7dc3aaa5fc1300afadca7cc392ec1bf3c6b6c0600c8609536b7b4d87e195","unix-2.8.4.0","unliftio-0.2.25.0-494677154ed69a76841d775b50166f52e9d0797a41ece2fd3d94e08aebf372f3","unliftio-core-0.2.1.0-1e6dce1dfe73ef335e0615b0af7f06b171c3572cf7a04fe671b6cec407b73dee","unordered-containers-0.2.20-013ecc3e94c07bd5bdb23da8c9cf4d68ac66e04c4144b4096b291104672db345","wai-3.2.4-acf062ae483a435740bc88b21ee81f62d3f94a62faea15a5bf17463ace439645","warp-3.3.31-3a081a14799ab48e5efe3a315077d1e89ea4da61799497b4990d5fc7e0dcb380"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"odd-jobs-0.2.3-e-devel-b12e6088114ebd4e8a5f5b848d0e940855c41da1b623872663251e9109531a2c","pkg-name":"odd-jobs","pkg-version":"0.2.3","flags":{},"style":"global","pkg-src":{"type":"source-repo","source-repo":{"type":"git","location":"https://github.com/saurabhnanda/odd-jobs","tag":"411d5d0"}},"pkg-src-sha256":"9276e626c2d938fb0880b134b7dc4b9482db3dce26787821f74d99482afe4e47","depends":["aeson-2.2.1.0-2595d249b227784b9febcd5a91568775f66fd262ac45c82c44f7b4a55e9d4c27","async-2.2.4-2107e60f1bee7c70ffed77e551ffc7db01e350edd8784cc9493cc782305122d0","base-4.18.2.0","bytestring-0.11.5.3","containers-0.6.7","directory-1.3.8.1","either-5.0.2-d8d7bb84305283af81161a95ec2aebe67483cc07c71e171fc392eccfafdfb663","fast-logger-3.2.2-f2b66566923a1fa76e5c48eecb73e2ef0a379b38ce325b13b8e81e8022003d26","filepath-1.4.200.1","foreign-store-0.2-38a004231d79ea11822d0929a9cc1c95c0b47fcefc2bf90dbf83bf2d93adaf90","friendly-time-0.4.1-abf55dee5aabd3d8d1a3bf852e9269ad8c33f771fd59ecb030b252f999bd9e16","generic-deriving-1.14.5-a1fd2d043c8cafb22abedc758c45dbc284b28f5354f3eb1c717c80c43a96a9e6","hdaemonize-0.5.7-554f4deed801598a70abe3e63685f792ae09fe10e60f21faf1abe49687142f9f","hostname-1.0-5085af94c98cc8316318de7e81d25ddb5a73601cfd27bfccc90a5b913cd9891b","lucid-2.11.20230408-181c7ed44fa9b37af3ac434ed53e16dbe6a7ca9ec7ef1f7e5c921196d628f3c0","monad-control-1.0.3.1-2bf3452c923aa94707518b6d970f4377279fd8c4ccca1256725eef18b6097440","monad-logger-0.3.40-9d168f3d26e168d935793595f1fdbe137ac850b43b0a75ed5c41cd97c589de1e","mtl-2.3.1","odd-jobs-0.2.3-2ea7e869e131ba9271dc166fb94494d9c4695adf80a10aeb2c6885388c248e44","optparse-applicative-0.18.1.0-1de8f12cfc2915bc6d323ba97415a7e0795036a6b613e7301735aedf9d0425be","postgresql-simple-0.6.5.1-ec621799555c8b1b15b3683ac92cdc3770e891696c7afc3195aa6f26571cbbe0","resource-pool-0.4.0.0-b943f9aab32b14d553510f77b995882007d913763eb4c8a34a077c78a8909098","safe-0.3.21-31bf385773e1c6ef212139e0505190c20d1e3d1af99bcbfc189c01c3a1e0e739","servant-0.20.1-b63507222e1b19c7b8333551fd2fbdae76248ba97753767f7ab4d32b7816d39d","servant-lucid-0.9.0.6-3245f97c511011e42d95122d5373c12ebeb20de76226f6491768d04935bf6b52","servant-server-0.20-3dbcc60207566a1f80874e61a86b73ab8a41f98f3231692dec244b2ce96f8132","servant-static-th-1.0.0.0-fa0f3ab3712e7a8402c328f207cfc41d9d7c81ead2eb76b54e22775de96a15db","string-conv-0.2.0-2b20138e5715fec3a0be370b62f70071e607c80729c0151ebac083484fb380fb","text-2.0.2","text-conversions-0.3.1.1-b955b2970b27e7be4b7afdac05f3480d3269bc092ad183c3d72cd22fe91a90cd","time-1.12.2","timing-convenience-0.1-532d7dc3aaa5fc1300afadca7cc392ec1bf3c6b6c0600c8609536b7b4d87e195","unix-2.8.4.0","unliftio-0.2.25.0-494677154ed69a76841d775b50166f52e9d0797a41ece2fd3d94e08aebf372f3","unliftio-core-0.2.1.0-1e6dce1dfe73ef335e0615b0af7f06b171c3572cf7a04fe671b6cec407b73dee","unordered-containers-0.2.20-013ecc3e94c07bd5bdb23da8c9cf4d68ac66e04c4144b4096b291104672db345","wai-3.2.4-acf062ae483a435740bc88b21ee81f62d3f94a62faea15a5bf17463ace439645","warp-3.3.31-3a081a14799ab48e5efe3a315077d1e89ea4da61799497b4990d5fc7e0dcb380"],"exe-depends":[],"component-name":"exe:devel","bin-file":"/home/hecate/Projects/Flora/1-flora-server/_build/cabal-store/ghc-9.6.4/odd-jobs-0.2.3-e-devel-b12e6088114ebd4e8a5f5b848d0e940855c41da1b623872663251e9109531a2c/bin/devel"},{"type":"configured","id":"odd-jobs-0.2.3-e-odd-jobs-cli-example-b48478a9ae62e6e29ddf07360cc7cfb1595f39f470dd278891aa0af1d0aeb51a","pkg-name":"odd-jobs","pkg-version":"0.2.3","flags":{},"style":"global","pkg-src":{"type":"source-repo","source-repo":{"type":"git","location":"https://github.com/saurabhnanda/odd-jobs","tag":"411d5d0"}},"pkg-src-sha256":"9276e626c2d938fb0880b134b7dc4b9482db3dce26787821f74d99482afe4e47","depends":["aeson-2.2.1.0-2595d249b227784b9febcd5a91568775f66fd262ac45c82c44f7b4a55e9d4c27","async-2.2.4-2107e60f1bee7c70ffed77e551ffc7db01e350edd8784cc9493cc782305122d0","base-4.18.2.0","bytestring-0.11.5.3","directory-1.3.8.1","either-5.0.2-d8d7bb84305283af81161a95ec2aebe67483cc07c71e171fc392eccfafdfb663","fast-logger-3.2.2-f2b66566923a1fa76e5c48eecb73e2ef0a379b38ce325b13b8e81e8022003d26","filepath-1.4.200.1","friendly-time-0.4.1-abf55dee5aabd3d8d1a3bf852e9269ad8c33f771fd59ecb030b252f999bd9e16","generic-deriving-1.14.5-a1fd2d043c8cafb22abedc758c45dbc284b28f5354f3eb1c717c80c43a96a9e6","hdaemonize-0.5.7-554f4deed801598a70abe3e63685f792ae09fe10e60f21faf1abe49687142f9f","hostname-1.0-5085af94c98cc8316318de7e81d25ddb5a73601cfd27bfccc90a5b913cd9891b","lucid-2.11.20230408-181c7ed44fa9b37af3ac434ed53e16dbe6a7ca9ec7ef1f7e5c921196d628f3c0","monad-control-1.0.3.1-2bf3452c923aa94707518b6d970f4377279fd8c4ccca1256725eef18b6097440","monad-logger-0.3.40-9d168f3d26e168d935793595f1fdbe137ac850b43b0a75ed5c41cd97c589de1e","mtl-2.3.1","odd-jobs-0.2.3-2ea7e869e131ba9271dc166fb94494d9c4695adf80a10aeb2c6885388c248e44","optparse-applicative-0.18.1.0-1de8f12cfc2915bc6d323ba97415a7e0795036a6b613e7301735aedf9d0425be","postgresql-simple-0.6.5.1-ec621799555c8b1b15b3683ac92cdc3770e891696c7afc3195aa6f26571cbbe0","resource-pool-0.4.0.0-b943f9aab32b14d553510f77b995882007d913763eb4c8a34a077c78a8909098","safe-0.3.21-31bf385773e1c6ef212139e0505190c20d1e3d1af99bcbfc189c01c3a1e0e739","servant-0.20.1-b63507222e1b19c7b8333551fd2fbdae76248ba97753767f7ab4d32b7816d39d","servant-lucid-0.9.0.6-3245f97c511011e42d95122d5373c12ebeb20de76226f6491768d04935bf6b52","servant-server-0.20-3dbcc60207566a1f80874e61a86b73ab8a41f98f3231692dec244b2ce96f8132","servant-static-th-1.0.0.0-fa0f3ab3712e7a8402c328f207cfc41d9d7c81ead2eb76b54e22775de96a15db","string-conv-0.2.0-2b20138e5715fec3a0be370b62f70071e607c80729c0151ebac083484fb380fb","text-2.0.2","text-conversions-0.3.1.1-b955b2970b27e7be4b7afdac05f3480d3269bc092ad183c3d72cd22fe91a90cd","time-1.12.2","timing-convenience-0.1-532d7dc3aaa5fc1300afadca7cc392ec1bf3c6b6c0600c8609536b7b4d87e195","unix-2.8.4.0","unliftio-0.2.25.0-494677154ed69a76841d775b50166f52e9d0797a41ece2fd3d94e08aebf372f3","unliftio-core-0.2.1.0-1e6dce1dfe73ef335e0615b0af7f06b171c3572cf7a04fe671b6cec407b73dee","unordered-containers-0.2.20-013ecc3e94c07bd5bdb23da8c9cf4d68ac66e04c4144b4096b291104672db345","wai-3.2.4-acf062ae483a435740bc88b21ee81f62d3f94a62faea15a5bf17463ace439645","warp-3.3.31-3a081a14799ab48e5efe3a315077d1e89ea4da61799497b4990d5fc7e0dcb380"],"exe-depends":[],"component-name":"exe:odd-jobs-cli-example","bin-file":"/home/hecate/Projects/Flora/1-flora-server/_build/cabal-store/ghc-9.6.4/odd-jobs-0.2.3-e-odd-jobs-cli-example-b48478a9ae62e6e29ddf07360cc7cfb1595f39f470dd278891aa0af1d0aeb51a/bin/odd-jobs-cli-example"},{"type":"configured","id":"old-locale-1.0.0.7-682418540979bf75be932863a87a0db4ab12d3f7ec5faaeba30e4175347cd126","pkg-name":"old-locale","pkg-version":"1.0.0.7","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"fa998be2c7e00cd26a6e9075bea790caaf3932caa3e9497ad69bc20380dd6911","pkg-src-sha256":"dbaf8bf6b888fb98845705079296a23c3f40ee2f449df7312f7f7f1de18d7b50","depends":["base-4.18.2.0"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"old-time-1.1.0.4-41f5636c376ef03b6ed0709860b733d4263cbb5dd153bb15926d2e3fb2df8cee","pkg-name":"old-time","pkg-version":"1.1.0.4","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"6e3dfb5b1d7cb24ed7ea9bbca1153485ae38fa0534b0581886dd42eeedf82447","pkg-src-sha256":"1e22eb7f7b924a676f52e317917b3b5eeceee11c74ef4bc609c0bcec624c166f","components":{"lib":{"depends":["base-4.18.2.0","old-locale-1.0.0.7-682418540979bf75be932863a87a0db4ab12d3f7ec5faaeba30e4175347cd126"],"exe-depends":["hsc2hs-0.68.10-e-hsc2hs-3b4e464e6a657183d9f83bd37c6d876421d9f6d00ca34e12b12ca3365e55159d"]}}},{"type":"configured","id":"one-time-password-3.0.0.0-cbe2caf30a2aa172cf2c5cdfc1edad8761e857fde6fe8f0adb23c2013d6f8108","pkg-name":"one-time-password","pkg-version":"3.0.0.0","flags":{},"style":"global","pkg-src":{"type":"source-repo","source-repo":{"type":"git","location":"https://github.com/haskell-cryptography/one-time-password","tag":"2ca2313"}},"pkg-src-sha256":"98e30a1469139de37b2ee690a0a745c52465abbe661b292301b70994f838d0e3","depends":["base-4.18.2.0","bytestring-0.11.5.3","cereal-0.5.8.3-930e90604013ce2a32c6d28d3567d1d966e50eb1bf0c18108838f2b4ff0d64ca","chronos-1.1.6.1-e20dbb7d5779b22a2f3541a6e640402e4330514b14ff822947c4209317b25bd6","cryptohash-sha1-0.11.101.0-a3ef13c78463fdd04d9d6245ad7391e038dbf79d9c19ec5ab64f9b19a6fb91a8","network-uri-2.6.4.2-d62d36021f4a84b02c9243cbe37e9dfd5b7ba840b4aaedb5e002f05582564fc4","sel-0.0.1.0-a107cece4307b775602a0ac4fef5e5489f9cf07913069de7b0aebbe27daff576","text-2.0.2","text-display-0.0.5.1-ae9f66e9765923d9edec209058cc153706fead0e7c7287c2994a985da1c39623","torsor-0.1.0.1-264ad98156300f7b86fb968625df8515c2fbbce5479b450f036ac11b2f5c7444"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"openapi3-3.2.4-36a3dd9c34b66f8d7bf989194c80a50284551837b7d8417e8ce95b4a35d15c2e","pkg-name":"openapi3","pkg-version":"3.2.4","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"d3d63e66b1dd9fa0cfffbc271a53a7d8e1647dea14f1f228bde3776740693322","pkg-src-sha256":"dbcb90464b4712a03c37fa3fcaca3a6784ace2794d85730a8a8c5d9b3ea14ba0","components":{"lib":{"depends":["QuickCheck-2.14.3-091d344acf9c963200a9b2af6c5417d91912262a9a84b607d918b50fdf8a8b02","aeson-2.2.1.0-2595d249b227784b9febcd5a91568775f66fd262ac45c82c44f7b4a55e9d4c27","aeson-pretty-0.8.10-9bd6a60b424b6a69fcd0507ef3b99938ee971580bc5bfa89249b16ff60b2c117","base-4.18.2.0","base-compat-batteries-0.13.1-25e7385abd281169497a6f5094374b17c8dd67030772349b80bd82c47b483cae","bytestring-0.11.5.3","containers-0.6.7","cookie-0.4.6-0f17f671a430f9d3670a38aa989d096c8a941ff590a1a1a5bc4f595def792f73","generics-sop-0.5.1.4-7f93bc69a981e910350e3e463cbbc84ff4d890645a9659a18c10b5d43ad5b6aa","hashable-1.4.3.0-17b447e0ce504d4e093d6bf5a9838da3805c7caa5d16355da40827d004febbc8","http-media-0.8.1.1-82ac8def17fc7bb0c409983a665f6b7cccbfddad16ad03396e0ea28fa6b4797e","insert-ordered-containers-0.2.5.3-3706f6956e9c93eb40f4960ef2def44ebba2c69366f9391e537c47e536d7a5e7","lens-5.2.3-fd9d842bd7b66c837b8b9d8ed9b74a1913e207465f21d80d3c84691d23c5c119","mtl-2.3.1","optics-core-0.4.1.1-f8d9a3ddd3e59e269ad03738aca54bb92446a15ba98a2b4ae8ec19ed7d20df70","optics-th-0.4.1-90f0163ff0ce0756a0c2b2710d750aca3af41c9fde2d3cd29f09811f71392eff","scientific-0.3.7.0-ad7c6f4dff0f6cf6540942c40157e54f8c090b5d960104c70801b0a2f7c99215","template-haskell-2.20.0.0","text-2.0.2","time-1.12.2","transformers-0.6.1.0","unordered-containers-0.2.20-013ecc3e94c07bd5bdb23da8c9cf4d68ac66e04c4144b4096b291104672db345","uuid-types-1.0.5.1-c19e00cab51fb72d8874dd99ac787f44fda9996af8117c2d227cfb3294e06a9c","vector-0.13.1.0-eb53bdac16f057ad838f4e8cb865b51b400abac71a36dc5bfde93ea1d0859eae"],"exe-depends":[]},"exe:example":{"depends":["aeson-2.2.1.0-2595d249b227784b9febcd5a91568775f66fd262ac45c82c44f7b4a55e9d4c27","base-4.18.2.0","lens-5.2.3-fd9d842bd7b66c837b8b9d8ed9b74a1913e207465f21d80d3c84691d23c5c119","text-2.0.2"],"exe-depends":[],"bin-file":"/home/hecate/Projects/Flora/1-flora-server/_build/cabal-store/ghc-9.6.4/openapi3-3.2.4-36a3dd9c34b66f8d7bf989194c80a50284551837b7d8417e8ce95b4a35d15c2e/bin/example"},"setup":{"depends":["Cabal-3.10.1.0","base-4.18.2.0","cabal-doctest-1.0.9-4a685fb2745cdab49526ff8fe3801bf6bd4ab5085239033fcfd51613f7e3fd76"],"exe-depends":[]}}},{"type":"configured","id":"optics-core-0.4.1.1-f8d9a3ddd3e59e269ad03738aca54bb92446a15ba98a2b4ae8ec19ed7d20df70","pkg-name":"optics-core","pkg-version":"0.4.1.1","flags":{"explicit-generic-labels":false},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"45b92b72475c266134bfbdfcb4801df3a6487453e8a6c389623b7161661f8bfa","pkg-src-sha256":"3e817e3c66a0120ac4b4b6d790e659b75f8c0fb27c5f65f3974f4c697b7bb3fb","depends":["array-0.5.6.0","base-4.18.2.0","containers-0.6.7","indexed-profunctors-0.1.1.1-8d925dea1c4443bc16b2bc6a7c10d1b7794d7d65d9ab1d1c3b10993e592e1e9e","indexed-traversable-0.1.3-8f7210e35c0cb4bf73ec163bed4014cbba70e17aa189447497a492e60990637b","transformers-0.6.1.0"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"optics-extra-0.4.2.1-14425af293a1407bfbe91e7d352b65135de2d1e89bcd3809c37b7b5300219c9f","pkg-name":"optics-extra","pkg-version":"0.4.2.1","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"a40b0175bfaba71ac48b00c9eb30b4294dbbb3c8afeb992de8953cbeefa9ea70","pkg-src-sha256":"7e23a7a325e3448354614d3d958279c9ac2fdd0831ceee2808830e7a962fca41","depends":["array-0.5.6.0","base-4.18.2.0","bytestring-0.11.5.3","containers-0.6.7","hashable-1.4.3.0-17b447e0ce504d4e093d6bf5a9838da3805c7caa5d16355da40827d004febbc8","indexed-profunctors-0.1.1.1-8d925dea1c4443bc16b2bc6a7c10d1b7794d7d65d9ab1d1c3b10993e592e1e9e","indexed-traversable-instances-0.1.1.2-23d2e9c28613d77bfd5595533e39512e3e8b808382cee8d422cee021acbf7fc4","mtl-2.3.1","optics-core-0.4.1.1-f8d9a3ddd3e59e269ad03738aca54bb92446a15ba98a2b4ae8ec19ed7d20df70","text-2.0.2","transformers-0.6.1.0","unordered-containers-0.2.20-013ecc3e94c07bd5bdb23da8c9cf4d68ac66e04c4144b4096b291104672db345","vector-0.13.1.0-eb53bdac16f057ad838f4e8cb865b51b400abac71a36dc5bfde93ea1d0859eae"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"optics-th-0.4.1-90f0163ff0ce0756a0c2b2710d750aca3af41c9fde2d3cd29f09811f71392eff","pkg-name":"optics-th","pkg-version":"0.4.1","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"d306ba320a4235338dcac597042fc1174fbc7d3b095c6c1fa3f824fe0e36150f","pkg-src-sha256":"d73857b79dcd8f7c7e70fa4727f134145b62902e8d3e448f8b25c38a9da4fd17","depends":["base-4.18.2.0","containers-0.6.7","mtl-2.3.1","optics-core-0.4.1.1-f8d9a3ddd3e59e269ad03738aca54bb92446a15ba98a2b4ae8ec19ed7d20df70","template-haskell-2.20.0.0","th-abstraction-0.6.0.0-b49a83d27ea2604c7977c309bd302e93941309c5040c248dbdb6b55147976b2b","transformers-0.6.1.0"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"optparse-applicative-0.18.1.0-1de8f12cfc2915bc6d323ba97415a7e0795036a6b613e7301735aedf9d0425be","pkg-name":"optparse-applicative","pkg-version":"0.18.1.0","flags":{"process":true},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"b4cf8d9018e5e67cb1f14edb5130b6d05ad8bc1b5f6bd4efaa6ec0b7f28f559d","pkg-src-sha256":"63811ab4fd26e829b8868364325a88be3acc79819f5bb5005b2dd3b961ecc491","depends":["base-4.18.2.0","prettyprinter-1.7.1-990f242c6c8062a20fcaf6f8bd5136049b2bbd93d07db5eae42d61de7c9d6c8c","prettyprinter-ansi-terminal-1.1.3-2b2de842f45b3d06338f00062771358f66ec85709eb8a1df5b48b49bf0d58c33","process-1.6.17.0","text-2.0.2","transformers-0.6.1.0","transformers-compat-0.7.2-15ca92c51f3c4b3e5a349c3cc2a7f406ca01ba50aecd92a631a1c4d508b1230f"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"os-string-2.0.2-c94c7716dceda9adcf8c3208c87dc23b7f71b84fca751a70ffc309850517a402","pkg-name":"os-string","pkg-version":"2.0.2","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"32fa47f8345a2c0662fb602fc42e4b674e41ec48079b68bdecb4b6f68032c24e","pkg-src-sha256":"0953126e962966719753c98d71f596f5fea07e100bce191b7453735a1ff2caa1","depends":["base-4.18.2.0","bytestring-0.11.5.3","deepseq-1.4.8.1","exceptions-0.10.7","template-haskell-2.20.0.0"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"parallel-3.2.2.0-86a50f94aa82e9af5f21bfb4d27ed83c8cf2231ac3fb348b2b433b2f10943c05","pkg-name":"parallel","pkg-version":"3.2.2.0","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"b993406e98fe9126eff4a69d28e7e361037dd1c0892a9fd6c26e1f92eb9c4fa4","pkg-src-sha256":"170453a71a2a8b31cca63125533f7771d7debeb639700bdabdd779c34d8a6ef6","depends":["array-0.5.6.0","base-4.18.2.0","containers-0.6.7","deepseq-1.4.8.1","ghc-prim-0.10.0"],"exe-depends":[],"component-name":"lib"},{"type":"pre-existing","id":"parsec-3.1.16.1","pkg-name":"parsec","pkg-version":"3.1.16.1","depends":["base-4.18.2.0","bytestring-0.11.5.3","mtl-2.3.1","text-2.0.2"]},{"type":"configured","id":"parser-combinators-1.3.0-702f2638f70c15b6b5b11fbe7dcdd3e6d0d73f0193261f85b4d42c011d1949f6","pkg-name":"parser-combinators","pkg-version":"1.3.0","flags":{"dev":false},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"8659573e0d443d573f5b53f81b81dafbdc988d282b90c11e3da73562b4ea7876","pkg-src-sha256":"9310ef0d49f8a8922acda10b1cded9854cbee04dea717effc6ee5983072e4447","depends":["base-4.18.2.0"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"pcre2-2.2.1-497aee97a6283223eea2bb30f3bd7127ff8bb3d2b6ece9c4e0a73371dc66b90c","pkg-name":"pcre2","pkg-version":"2.2.1","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"057bd6337dbb681708f5df7ce2d13884e93830f1b2f4f51f8e7096dd87358285","pkg-src-sha256":"d48d8669d68f2858d825fb08b3730cfeb49eed964b093b39e78052fd1f510870","depends":["base-4.18.2.0","containers-0.6.7","microlens-0.4.13.1-7fc67fa4a915fe46c53bdefdd38fdb5fc86a0fe5166c99a699781b2db9bc2c2f","mtl-2.3.1","template-haskell-2.20.0.0","text-2.0.2"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"pem-0.2.4-fc2f4716715ce340b3916ffcbdd4e6509f0d10442951de390cdd9d623db1033a","pkg-name":"pem","pkg-version":"0.2.4","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"cc8e62118b783e284dc0fa032f54fe386a3861a948ec88079370a433c103a705","pkg-src-sha256":"770c4c1b9cd24b3db7f511f8a48404a0d098999e28573c3743a8a296bb96f8d4","depends":["base-4.18.2.0","basement-0.0.16-2ba9d181df7bdd547d6fedd5acdec581f03e379e22b0e08ff998fb0462257d08","bytestring-0.11.5.3","memory-0.18.0-273ad672f1703dee0dfe07994633c93d17f815a149738659ef6afa30cbe4f6a8"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"pg-entity-0.0.4.4-c09d4801d2c9b8aac6587451fb3276698aa673bffbbe13e20e92459744a89058","pkg-name":"pg-entity","pkg-version":"0.0.4.4","flags":{"book":false,"prod":false},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"c1b547bfa22b09f1ebf0b9c7cac6dc70292bd1bac2aeacadbe89acceb908bfa0","pkg-src-sha256":"02d6e5b4464caeeeec549f9086a84f5bb89a252bdb1c00f7a8045d0389f67a75","depends":["base-4.18.2.0","bytestring-0.11.5.3","colourista-0.1.0.2-f2248bbbb4ee79cbf9fe81e61effe11fd685506de3685fc7950c57e7408058a6","parsec-3.1.16.1","pg-transact-0.3.2.0-154eca34326a8779919f5450f98657e0bdd42098d5eb39bd64fe3ab6b57ef08c","postgresql-simple-0.6.5.1-ec621799555c8b1b15b3683ac92cdc3770e891696c7afc3195aa6f26571cbbe0","resource-pool-0.4.0.0-b943f9aab32b14d553510f77b995882007d913763eb4c8a34a077c78a8909098","template-haskell-2.20.0.0","text-2.0.2","text-display-0.0.5.1-ae9f66e9765923d9edec209058cc153706fead0e7c7287c2994a985da1c39623","text-manipulate-0.3.1.0-bbaadf2af0a73d136732896cbf24da16ec9680c37b15a75cb7d27e4488f229a7","time-1.12.2","uuid-1.3.15-413cef239f477249b51ed712d27bea33e15b08237221be1f41f0bc89ce5e1463","vector-0.13.1.0-eb53bdac16f057ad838f4e8cb865b51b400abac71a36dc5bfde93ea1d0859eae"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"pg-transact-0.3.2.0-154eca34326a8779919f5450f98657e0bdd42098d5eb39bd64fe3ab6b57ef08c","pkg-name":"pg-transact","pkg-version":"0.3.2.0","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"585184bbbc95d2c59885377cc713383d808686df62044f4da8d708184bbec215","pkg-src-sha256":"af109e82fee758d159654b9c02c396197852cbd909b5f02dbbd4ef0613270432","depends":["base-4.18.2.0","bytestring-0.11.5.3","exceptions-0.10.7","monad-control-1.0.3.1-2bf3452c923aa94707518b6d970f4377279fd8c4ccca1256725eef18b6097440","postgresql-simple-0.6.5.1-ec621799555c8b1b15b3683ac92cdc3770e891696c7afc3195aa6f26571cbbe0","transformers-0.6.1.0"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"pg-transact-effectful-0.0.1.0-19059a8ff842cc019bf692ea57228ae755836f0ae48aa91885f40683ea8347a6","pkg-name":"pg-transact-effectful","pkg-version":"0.0.1.0","flags":{},"style":"global","pkg-src":{"type":"source-repo","source-repo":{"type":"git","location":"https://github.com/kleidukos/pg-transact-effectful","tag":"d3f3f3d"}},"pkg-src-sha256":"ffd239fca5c580205e8553dc36d5eddf59dc951a7b1e8ee121d2f0bdd92c09fa","depends":["base-4.18.2.0","deepseq-1.4.8.1","effectful-core-2.3.0.1-011d84ab0bc8bb2010bac83565500e3039592cab57d902e9a2a502684b92d90f","mtl-2.3.1","pg-transact-0.3.2.0-154eca34326a8779919f5450f98657e0bdd42098d5eb39bd64fe3ab6b57ef08c","postgresql-simple-0.6.5.1-ec621799555c8b1b15b3683ac92cdc3770e891696c7afc3195aa6f26571cbbe0","resource-pool-0.4.0.0-b943f9aab32b14d553510f77b995882007d913763eb4c8a34a077c78a8909098"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"poolboy-0.2.2.0-2b5751910b4c714d0b69899eea5770ca156a5f1311f953bd68bceb7c3f9f9275","pkg-name":"poolboy","pkg-version":"0.2.2.0","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"1e69e86bcf2ad4e28dc3d5ff6053879de836923e6a274f9733c7346e8e56fc46","pkg-src-sha256":"c36dd0e6c4edfb6e161dad6934a1781fb0ff4532fbade6dfb6878fe33cee1434","depends":["async-2.2.4-2107e60f1bee7c70ffed77e551ffc7db01e350edd8784cc9493cc782305122d0","base-4.18.2.0","stm-2.5.1.0","unliftio-0.2.25.0-494677154ed69a76841d775b50166f52e9d0797a41ece2fd3d94e08aebf372f3"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"postgresql-libpq-0.9.5.0-071d9ee8ef83b1f776abe0db562cc5fd3ddb99923740b0f31e6cd7ac1d8703e8","pkg-name":"postgresql-libpq","pkg-version":"0.9.5.0","flags":{"use-pkg-config":false},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"6680ac3c947bf8fbe1d181d0ce1abb9bd0691316fa1e2dfd547b631b2a4be609","pkg-src-sha256":"d1592bd805c088bb0c136c03eea92af9c1d7dbd85e32d0b6d522fd940f325470","components":{"lib":{"depends":["base-4.18.2.0","bytestring-0.11.5.3","unix-2.8.4.0"],"exe-depends":["hsc2hs-0.68.10-e-hsc2hs-3b4e464e6a657183d9f83bd37c6d876421d9f6d00ca34e12b12ca3365e55159d"]},"setup":{"depends":["Cabal-3.10.1.0","base-4.18.2.0"],"exe-depends":[]}}},{"type":"configured","id":"postgresql-migration-0.2.1.7-559534ce1dd13a52b2fe575db34bd39f392a7c262dc6d5bd81bff72f2e148d8e","pkg-name":"postgresql-migration","pkg-version":"0.2.1.7","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"7b511be780305beb7940c99476911de47231a448f4eee5b50cbe40bdac63b3e8","pkg-src-sha256":"e838a5f15eb1f5614cda1c6078fe534589768421fad6b5d54ea4149092af1765","depends":["base-4.18.2.0","base64-bytestring-1.2.1.0-ecb3bf792eac6ec696f20e02e528e8a7b2a76a5b32c46409c4645e1bfbd71cf4","bytestring-0.11.5.3","cryptohash-md5-0.11.101.0-3dd4c39d92ff47630ac61716ac3e4f1bd76b570bf3eb70cf3c6a25610e31a06c","directory-1.3.8.1","filepath-1.4.200.1","postgresql-simple-0.6.5.1-ec621799555c8b1b15b3683ac92cdc3770e891696c7afc3195aa6f26571cbbe0","text-2.0.2","time-1.12.2"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"postgresql-migration-0.2.1.7-e-migrate-1a1cee7879444d74e7f41af0ac61ebdfa8fb20f515c4c982254ad7f1e55fd446","pkg-name":"postgresql-migration","pkg-version":"0.2.1.7","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"7b511be780305beb7940c99476911de47231a448f4eee5b50cbe40bdac63b3e8","pkg-src-sha256":"e838a5f15eb1f5614cda1c6078fe534589768421fad6b5d54ea4149092af1765","depends":["base-4.18.2.0","base64-bytestring-1.2.1.0-ecb3bf792eac6ec696f20e02e528e8a7b2a76a5b32c46409c4645e1bfbd71cf4","bytestring-0.11.5.3","cryptohash-md5-0.11.101.0-3dd4c39d92ff47630ac61716ac3e4f1bd76b570bf3eb70cf3c6a25610e31a06c","directory-1.3.8.1","postgresql-migration-0.2.1.7-559534ce1dd13a52b2fe575db34bd39f392a7c262dc6d5bd81bff72f2e148d8e","postgresql-simple-0.6.5.1-ec621799555c8b1b15b3683ac92cdc3770e891696c7afc3195aa6f26571cbbe0","text-2.0.2","time-1.12.2"],"exe-depends":[],"component-name":"exe:migrate","bin-file":"/home/hecate/Projects/Flora/1-flora-server/_build/cabal-store/ghc-9.6.4/postgresql-migration-0.2.1.7-e-migrate-1a1cee7879444d74e7f41af0ac61ebdfa8fb20f515c4c982254ad7f1e55fd446/bin/migrate"},{"type":"configured","id":"postgresql-simple-0.6.5.1-ec621799555c8b1b15b3683ac92cdc3770e891696c7afc3195aa6f26571cbbe0","pkg-name":"postgresql-simple","pkg-version":"0.6.5.1","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"527939755637c1ea3fdad2819a7725e63d0a01931678e631549367c9faedc620","pkg-src-sha256":"c861410b73d279c6d1b712dc20632c37612a1098f23593f6475a995b14191b6c","depends":["Only-0.1-914e2ddfdd5fc0b9704050502cc99fcb5926b3ef60f86855ee94bd6fc8c46a18","aeson-2.2.1.0-2595d249b227784b9febcd5a91568775f66fd262ac45c82c44f7b4a55e9d4c27","attoparsec-0.14.4-5061b5f729de9f72f69961345d54e0249a28df7c232bb9cf2b0525b6f17a253a","base-4.18.2.0","bytestring-0.11.5.3","bytestring-builder-0.10.8.2.0-e19114b40bd07b22b89d1b66ea0a2320498dd92342a0ffbe5a84431b412d2a4c","case-insensitive-1.2.1.0-5255eaf892b10e8489fdad145ca833a10864bd951f3e69d04088fbcadf28ec6d","containers-0.6.7","hashable-1.4.3.0-17b447e0ce504d4e093d6bf5a9838da3805c7caa5d16355da40827d004febbc8","postgresql-libpq-0.9.5.0-071d9ee8ef83b1f776abe0db562cc5fd3ddb99923740b0f31e6cd7ac1d8703e8","scientific-0.3.7.0-ad7c6f4dff0f6cf6540942c40157e54f8c090b5d960104c70801b0a2f7c99215","template-haskell-2.20.0.0","text-2.0.2","time-compat-1.9.6.1-2b2aa066adc7c0d5baad9d0716626a41574966c2265b4ff355b83a2bfd5ca61a","transformers-0.6.1.0","uuid-types-1.0.5.1-c19e00cab51fb72d8874dd99ac787f44fda9996af8117c2d227cfb3294e06a9c","vector-0.13.1.0-eb53bdac16f057ad838f4e8cb865b51b400abac71a36dc5bfde93ea1d0859eae"],"exe-depends":[],"component-name":"lib"},{"type":"pre-existing","id":"pretty-1.1.3.6","pkg-name":"pretty","pkg-version":"1.1.3.6","depends":["base-4.18.2.0","deepseq-1.4.8.1","ghc-prim-0.10.0"]},{"type":"configured","id":"pretty-show-1.10-39ae5e05ab98b3c924fb13a2d338f92ec77dadc8f9be190ec6bbf2401618cf8f","pkg-name":"pretty-show","pkg-version":"1.10","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"bfef8da0ac4db4fc7f41edfec9e9a701ac206418d70702bff1e40f20d6a2b1f1","pkg-src-sha256":"307f9086e0b063d439dc4f513e36a145e8a57f23de448aefae2a6c00f6da6fd2","depends":["array-0.5.6.0","base-4.18.2.0","filepath-1.4.200.1","ghc-prim-0.10.0","haskell-lexer-1.1.1-833f66de7c919d07c41146e9931dfd902b8b694cd3302de1c3d836c85a3c47a3","pretty-1.1.3.6","text-2.0.2"],"exe-depends":["happy-1.20.1.1-e-happy-182aa5abbcffb81f5451895cca70d0e3fc7d8d0e3c5bdde45132d65f06643d40"],"component-name":"lib"},{"type":"configured","id":"pretty-show-1.10-e-ppsh-544a1a4ea59118346d01876f1be198e7af495917d88b621a8de8213ba3aa2987","pkg-name":"pretty-show","pkg-version":"1.10","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"bfef8da0ac4db4fc7f41edfec9e9a701ac206418d70702bff1e40f20d6a2b1f1","pkg-src-sha256":"307f9086e0b063d439dc4f513e36a145e8a57f23de448aefae2a6c00f6da6fd2","depends":["base-4.18.2.0","pretty-show-1.10-39ae5e05ab98b3c924fb13a2d338f92ec77dadc8f9be190ec6bbf2401618cf8f"],"exe-depends":[],"component-name":"exe:ppsh","bin-file":"/home/hecate/Projects/Flora/1-flora-server/_build/cabal-store/ghc-9.6.4/pretty-show-1.10-e-ppsh-544a1a4ea59118346d01876f1be198e7af495917d88b621a8de8213ba3aa2987/bin/ppsh"},{"type":"configured","id":"prettyprinter-1.7.1-990f242c6c8062a20fcaf6f8bd5136049b2bbd93d07db5eae42d61de7c9d6c8c","pkg-name":"prettyprinter","pkg-version":"1.7.1","flags":{"buildreadme":false,"text":true},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"9c43c9d8c3cd9f445596e5a2379574bba87f935a4d1fa41b5407ee3cf4edc743","pkg-src-sha256":"5e6ea6903114fa118fcc359633dfb7ecddecb92c06c853d02a77b72b251f0b45","depends":["base-4.18.2.0","text-2.0.2"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"prettyprinter-ansi-terminal-1.1.3-2b2de842f45b3d06338f00062771358f66ec85709eb8a1df5b48b49bf0d58c33","pkg-name":"prettyprinter-ansi-terminal","pkg-version":"1.1.3","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"b00f727b964cf13adff7acf575a71fa7e405f5240aff50b07f10df76ab89f8d3","pkg-src-sha256":"813739308ad6050620578994effe21058a170a341716acf52573fae42b5b1db3","depends":["ansi-terminal-1.0.2-f2271bf25e5299c165409ab78d5917aeba79c479959932bb5fb284c513226fc0","base-4.18.2.0","prettyprinter-1.7.1-990f242c6c8062a20fcaf6f8bd5136049b2bbd93d07db5eae42d61de7c9d6c8c","text-2.0.2"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"primitive-0.9.0.0-a6aa61bd9fff8d6cfd4880894dd85d8e644fbcf178b2bff38f87569871ea4a0d","pkg-name":"primitive","pkg-version":"0.9.0.0","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"1ceb39f67c0e614180f2992a6d30f26603ab2cd23c4f8e25b30213f98807f6f1","pkg-src-sha256":"696d4bd291c94d736142d6182117dca4258d3ef28bfefdb649ac8b5ecd0999c7","depends":["base-4.18.2.0","deepseq-1.4.8.1","template-haskell-2.20.0.0","transformers-0.6.1.0"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"primitive-addr-0.1.0.2-1d786758faf617b086ce4cbc72b559d853b44b3c0637695f91811d3095dde6e1","pkg-name":"primitive-addr","pkg-version":"0.1.0.2","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"f6e102445287c5406f256da95f8bdb6ff58290144b348e64a3062453bb5928e8","pkg-src-sha256":"4281c3a429bc03ab2940d072a6cbd63948bdf2607561456d972ba3ca4db9211b","depends":["base-4.18.2.0","primitive-0.9.0.0-a6aa61bd9fff8d6cfd4880894dd85d8e644fbcf178b2bff38f87569871ea4a0d"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"primitive-offset-0.2.0.0-b93fd3063a232ecde01c2f1c6c7f349f7bbfba6a51590e6011e8c669dc2ff008","pkg-name":"primitive-offset","pkg-version":"0.2.0.0","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"f8006927d5c0a3e83707610bbc5514aabe8f84a907ecb07edd2c815f58299dea","pkg-src-sha256":"b15e7de9ebf36ec12b4e2fac2a2c3cefd2b99afa76231fbd0b5cf5d03f6d572b","depends":["base-4.18.2.0","primitive-0.9.0.0-a6aa61bd9fff8d6cfd4880894dd85d8e644fbcf178b2bff38f87569871ea4a0d"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"primitive-unlifted-2.1.0.0-aea76574320ac1dea77e342956c3de02d6d7ed0b25f80413b31e3a4622eea123","pkg-name":"primitive-unlifted","pkg-version":"2.1.0.0","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"ef1113c8796391ef098a026f16dc827abd32a15cb847acdf2d83af9eba103299","pkg-src-sha256":"613421078a2f4c012a99233dbc7a8ff0a17a0cb5abfd9baf544f4695751a3d1e","depends":["array-0.5.6.0","base-4.18.2.0","bytestring-0.11.5.3","primitive-0.9.0.0-a6aa61bd9fff8d6cfd4880894dd85d8e644fbcf178b2bff38f87569871ea4a0d","text-short-0.1.5-e014e79f76c5438274db6ad0455e870f44faf95f73a43bdf4e1c22851755dbaa"],"exe-depends":[],"component-name":"lib"},{"type":"pre-existing","id":"process-1.6.17.0","pkg-name":"process","pkg-version":"1.6.17.0","depends":["base-4.18.2.0","deepseq-1.4.8.1","directory-1.3.8.1","filepath-1.4.200.1","unix-2.8.4.0"]},{"type":"configured","id":"profunctors-5.6.2-8b084a9552445e5776f01a7b42f1722ce1ecf20cf9a8e839007b9baea33b9fa4","pkg-name":"profunctors","pkg-version":"5.6.2","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"e178ba4468982326656626e2089e296f64485e68fdddc9f4476dcd5d612b4f78","pkg-src-sha256":"65955d7b50525a4a3bccdab1d982d2ae342897fd38140d5a94b5ef3800d8c92a","depends":["base-4.18.2.0","base-orphans-0.9.1-61d128d6a3318593c785a97751f2418cc86b42b03e2b46ed92e9b27fc5da689c","bifunctors-5.6.1-3bfddc97d0532e0f4bedd1f64454f96744d2fe805f93a5f9e443c2c5e1035ff1","comonad-5.0.8-8505feb1b75f0b6bf19ef9b666132d0031c1214df6db91aab78f0a9def57751c","contravariant-1.5.5-45cb856efb41788f255562487551496b619a1cf555a23fc4a29495fda3e0c50f","distributive-0.6.2.1-70a2f4c4bffafd7749c1d755f27db885f954a9d9be1cd7db8a6e99887121ec8c","tagged-0.8.8-5d06ce789c37adf39496775b08f7d82bb9509e4c2a3f973b0c868e35bca55ad5","transformers-0.6.1.0"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"psqueues-0.2.8.0-3b5625b932d73ea3cc0319c7b0eff1a4b49b3ba87f855df869f83ada38fcc584","pkg-name":"psqueues","pkg-version":"0.2.8.0","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"e71ef88119df3449e3018ecdd487ad844e112352baae0df8c229f76b009d399d","pkg-src-sha256":"b36de238414845d5f0e8e521154e670b2129a21b98070a02fd6b7c873b46e462","depends":["base-4.18.2.0","deepseq-1.4.8.1","ghc-prim-0.10.0","hashable-1.4.3.0-17b447e0ce504d4e093d6bf5a9838da3805c7caa5d16355da40827d004febbc8"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"qrcode-core-0.9.9-26498b4ed47f926f2f064d25ff1a73747fe531dce4fe1eaf0dd664493c00bbbc","pkg-name":"qrcode-core","pkg-version":"0.9.9","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"5ecfe933786a3b13be59ada3126dd13ba03e3fd3dbc5ec234bf85054a313c063","pkg-src-sha256":"bc596ab168b4d2fdc34ad2ffe4fa3e52f30e8a8ef3215a798a8851f7409050ad","depends":["base-4.18.2.0","binary-0.8.9.1","bytestring-0.11.5.3","case-insensitive-1.2.1.0-5255eaf892b10e8489fdad145ca833a10864bd951f3e69d04088fbcadf28ec6d","containers-0.6.7","dlist-1.0-1ec91dd3ad8405ed390138bce1c7d55220d4758eda9fb3ad6fbb8b1ee6dc0c94","primitive-0.9.0.0-a6aa61bd9fff8d6cfd4880894dd85d8e644fbcf178b2bff38f87569871ea4a0d","text-2.0.2","vector-0.13.1.0-eb53bdac16f057ad838f4e8cb865b51b400abac71a36dc5bfde93ea1d0859eae"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"qrcode-juicypixels-0.8.5-6838fee4a1ce854292c21f8a386f97468fe4ea877b3c81266871b5ccf74fbeb5","pkg-name":"qrcode-juicypixels","pkg-version":"0.8.5","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"2a35d88a67e10a39dccd0e9e6f3c199b762c683316758031911578a21aac4507","pkg-src-sha256":"6f594f2e03c5aec83e3244919a2032a3a74ad1fc16919e0527a0fb784e6cec61","depends":["JuicyPixels-3.3.8-295ba873739530be2ad2e0f5ef3880f23fb240b49297676915db7967d6106794","base-4.18.2.0","base64-bytestring-1.2.1.0-ecb3bf792eac6ec696f20e02e528e8a7b2a76a5b32c46409c4645e1bfbd71cf4","bytestring-0.11.5.3","qrcode-core-0.9.9-26498b4ed47f926f2f064d25ff1a73747fe531dce4fe1eaf0dd664493c00bbbc","text-2.0.2","vector-0.13.1.0-eb53bdac16f057ad838f4e8cb865b51b400abac71a36dc5bfde93ea1d0859eae"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"quickcheck-io-0.2.0-72cfeb1839042c70144c107e73cbb146738a02891278b479561ca9d6da09e7d6","pkg-name":"quickcheck-io","pkg-version":"0.2.0","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"7bf0b68fb90873825eb2e5e958c1b76126dcf984debb998e81673e6d837e0b2d","pkg-src-sha256":"fb779119d79fe08ff4d502fb6869a70c9a8d5fd8ae0959f605c3c937efd96422","depends":["HUnit-1.6.2.0-d1570da0a2808fb4ce9b1c3f1e99a0cf4a27d7c4071d9714ae835af7748ace92","QuickCheck-2.14.3-091d344acf9c963200a9b2af6c5417d91912262a9a84b607d918b50fdf8a8b02","base-4.18.2.0"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"random-1.2.1.2-cc746490e13a1f967de173a54c09753b2ccdb5d95056b0f1206a29c62c83de45","pkg-name":"random","pkg-version":"1.2.1.2","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"32397de181e20ccaacf806ec70de9308cf044f089a2be37c936f3f8967bde867","pkg-src-sha256":"790f4dc2d2327c453ff6aac7bf15399fd123d55e927935f68f84b5df42d9a4b4","depends":["base-4.18.2.0","bytestring-0.11.5.3","deepseq-1.4.8.1","mtl-2.3.1","splitmix-0.1.0.5-4c4c1f33537354cbf1e3da145a4775d1633faaa320080e06e92a1f67dbed4227"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"raven-haskell-0.1.4.1-44d3b6ed541acb7607ead7976c2238c005386ee5ef27fe0c44b3443d3c3d76b7","pkg-name":"raven-haskell","pkg-version":"0.1.4.1","flags":{"tests":false},"style":"global","pkg-src":{"type":"source-repo","source-repo":{"type":"git","location":"https://gitlab.com/dpwiz/raven-haskell.git/","tag":"180088b26fb79515627644545955aed5c50d804a","subdir":"./raven-haskell"}},"pkg-src-sha256":"823a05623175b3429dd26af367e5d7a253c252087676a3c576afbba8e7fccbe4","depends":["aeson-2.2.1.0-2595d249b227784b9febcd5a91568775f66fd262ac45c82c44f7b4a55e9d4c27","base-4.18.2.0","bytestring-0.11.5.3","http-conduit-2.3.8.3-4ad7853d8f1fc07a23d239e66fd76a570e24733747408dace515a7e5a7be3940","mtl-2.3.1","network-3.1.4.0-9d41c9df77e8d21da5aaf51c19540d3c0fc11e5e2c2940bea5411915b8a462ff","random-1.2.1.2-cc746490e13a1f967de173a54c09753b2ccdb5d95056b0f1206a29c62c83de45","resourcet-1.3.0-0f210c6e8ffe9f595ad8fd1a6cf6726e42a6695abb7febee22452f40436a2bc5","text-2.0.2","time-1.12.2","unordered-containers-0.2.20-013ecc3e94c07bd5bdb23da8c9cf4d68ac66e04c4144b4096b291104672db345","uuid-types-1.0.5.1-c19e00cab51fb72d8874dd99ac787f44fda9996af8117c2d227cfb3294e06a9c"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"recv-0.1.0-d170336de78e6c12b94f8cc756fe783212924d934de94f3714815c10ebbd9fad","pkg-name":"recv","pkg-version":"0.1.0","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"04058c90ed3d2821b92e589dd3428f5a6e9d49ab405296dda3583304cb0b9bb3","pkg-src-sha256":"f664905cffb44b7f9cba604cd75bd69011a666ba06bccbcb7f3fae0cd4f14d5b","depends":["base-4.18.2.0","bytestring-0.11.5.3","network-3.1.4.0-9d41c9df77e8d21da5aaf51c19540d3c0fc11e5e2c2940bea5411915b8a462ff"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"reflection-2.1.7-6e3964bab098962c0f1cc95d37584b10d2c12c8d4578f9c794643c142cc40415","pkg-name":"reflection","pkg-version":"2.1.7","flags":{"slow":false,"template-haskell":true},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"f2b5b3f0983a605d16e53af489ebba62967d2c80353473ca66cc1734222b3a04","pkg-src-sha256":"6cbb18a8b02871533bb8b641dc6f76813a097d94404e5808bb5d52b0f0e415fd","depends":["base-4.18.2.0","template-haskell-2.20.0.0"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"req-3.13.2-58b3576f35ee75f77b2d839cec460285be510fca18162b9b1542b8ae69fa9e34","pkg-name":"req","pkg-version":"3.13.2","flags":{"dev":false},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"18760b5d2d5aebee4d5337056d42a64979a28f7b48b0ab3285db452c72bbe750","pkg-src-sha256":"5bbe4029906138e509d50c68730a7537aa7890900bd15aa5c8c5129c8975b0de","depends":["aeson-2.2.1.0-2595d249b227784b9febcd5a91568775f66fd262ac45c82c44f7b4a55e9d4c27","authenticate-oauth-1.7-17cbc43210a12a6ae641a7faea62b4f2f2c36ac4c243d15ee4ff7bbccaf8c6d1","base-4.18.2.0","blaze-builder-0.4.2.3-60676f992d653075aeba6aad80b2dd0b054859608a5712ecfc9d4a4968aefdb8","bytestring-0.11.5.3","case-insensitive-1.2.1.0-5255eaf892b10e8489fdad145ca833a10864bd951f3e69d04088fbcadf28ec6d","containers-0.6.7","crypton-connection-0.3.2-804034b7a3e50ed75e1849613e844c1579d8bd18848efe958529bc613747e852","exceptions-0.10.7","http-api-data-0.6-f8db4c3e7ff814c1476ac3873683211db56d23f0c28cabdd051460114fc3de4f","http-client-0.7.16-08ac6af6261aa24f586bbb528e8ea2f0bd2e7510d1883948d770173e7ea8b633","http-client-tls-0.3.6.3-67f7c5e1b646b6720d31cd47b325354e5e9c257cef0d9522c9b4a5648422c65e","http-types-0.12.4-0f52a9ec33f3c65ef0b77ad8ce14b65f9164f8a761e42800dc9c80ee1768aacc","modern-uri-0.3.6.1-c2deadb57eaf5495142288d2ce86c3ffbf3db59eea2c3ffe34643053cf0d66a0","monad-control-1.0.3.1-2bf3452c923aa94707518b6d970f4377279fd8c4ccca1256725eef18b6097440","mtl-2.3.1","retry-0.9.3.1-2d114b37a558b4b151118167182e7d5cccd7193b8d2085b56dd490d68f56aea0","template-haskell-2.20.0.0","text-2.0.2","transformers-0.6.1.0","transformers-base-0.4.6-91c64a4b19c3f5f9f196345e9032803d52322bd0857ba94ea6c4260a27a2ff07","unliftio-core-0.2.1.0-1e6dce1dfe73ef335e0615b0af7f06b171c3572cf7a04fe671b6cec407b73dee"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"resource-pool-0.4.0.0-b943f9aab32b14d553510f77b995882007d913763eb4c8a34a077c78a8909098","pkg-name":"resource-pool","pkg-version":"0.4.0.0","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"9c1e448a159875e21a7e68697feee2b61a4e584720974fa465a2fa1bc0776c73","pkg-src-sha256":"8c0d783e3e75788d65f79157309132999f1bbb70684bacc2ea5dd18f904ae9b1","depends":["base-4.18.2.0","hashable-1.4.3.0-17b447e0ce504d4e093d6bf5a9838da3805c7caa5d16355da40827d004febbc8","primitive-0.9.0.0-a6aa61bd9fff8d6cfd4880894dd85d8e644fbcf178b2bff38f87569871ea4a0d","time-1.12.2"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"resourcet-1.3.0-0f210c6e8ffe9f595ad8fd1a6cf6726e42a6695abb7febee22452f40436a2bc5","pkg-name":"resourcet","pkg-version":"1.3.0","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"faa760fb28fb5c98fbe4867e375a775495cabc00926da81fa102dc991017d2c5","pkg-src-sha256":"ec601785ee42a201f32adb205b8685c983f18757b1bd33d2e806d571e0f9996b","depends":["base-4.18.2.0","containers-0.6.7","exceptions-0.10.7","mtl-2.3.1","primitive-0.9.0.0-a6aa61bd9fff8d6cfd4880894dd85d8e644fbcf178b2bff38f87569871ea4a0d","transformers-0.6.1.0","unliftio-core-0.2.1.0-1e6dce1dfe73ef335e0615b0af7f06b171c3572cf7a04fe671b6cec407b73dee"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"retry-0.9.3.1-2d114b37a558b4b151118167182e7d5cccd7193b8d2085b56dd490d68f56aea0","pkg-name":"retry","pkg-version":"0.9.3.1","flags":{"lib-werror":false},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"1a61625dc1c3dd6677ffde1c8142004026dfb08085d0d0af5848088d56ec6110","pkg-src-sha256":"622e35114b920f76fa2e1ae6515575b9973fac19c679f5426ea6574a5d0b7ed6","depends":["base-4.18.2.0","exceptions-0.10.7","ghc-prim-0.10.0","mtl-2.3.1","mtl-compat-0.2.2-9b77842584114154ec5c5ab666cf431f0be7716025713aae3e0ce53ce1b7ad9f","random-1.2.1.2-cc746490e13a1f967de173a54c09753b2ccdb5d95056b0f1206a29c62c83de45","transformers-0.6.1.0","unliftio-core-0.2.1.0-1e6dce1dfe73ef335e0615b0af7f06b171c3572cf7a04fe671b6cec407b73dee"],"exe-depends":[],"component-name":"lib"},{"type":"pre-existing","id":"rts-1.0.2","pkg-name":"rts","pkg-version":"1.0.2","depends":[]},{"type":"configured","id":"run-st-0.1.3.3-af1ad044a973fec4afa0830cc37bb6f0f7961cd9e6ffb5b32198ce4b6d73c331","pkg-name":"run-st","pkg-version":"0.1.3.3","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"da932d882d3fefc9cd53fb367375a64c1dd6ffd702702854d26c8d5af6a4fd59","pkg-src-sha256":"97585d13dcffc30a6b29d83296d1fb2c8eb52d7ffd2d605e78e8dc8ac8d8a654","depends":["base-4.18.2.0","primitive-0.9.0.0-a6aa61bd9fff8d6cfd4880894dd85d8e644fbcf178b2bff38f87569871ea4a0d","primitive-unlifted-2.1.0.0-aea76574320ac1dea77e342956c3de02d6d7ed0b25f80413b31e3a4622eea123"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"safe-0.3.21-31bf385773e1c6ef212139e0505190c20d1e3d1af99bcbfc189c01c3a1e0e739","pkg-name":"safe","pkg-version":"0.3.21","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"b928ea1645876788155b38ce85c7e46d157a1bb41d2b05f5770b13d60bc6a3f7","pkg-src-sha256":"2c81fea42bbe79ec488774043c1ec54f30efba059df9a4f3681ce83d85007f01","depends":["base-4.18.2.0"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"safe-exceptions-0.1.7.4-51b8325bd2c9c2c32246cef5b80f09fba6aa9b6005978a7b87ef943c7ddd1182","pkg-name":"safe-exceptions","pkg-version":"0.1.7.4","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"8bb7261bd54bd58acfcb154be6a161fb6d0d31a1852aadc8e927d2ad2d7651d1","pkg-src-sha256":"3c51d8d50c9b60ff8bf94f942fd92e3bea9e62c5afa778dfc9f707b79da41ef6","depends":["base-4.18.2.0","deepseq-1.4.8.1","exceptions-0.10.7","transformers-0.6.1.0"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"scientific-0.3.7.0-ad7c6f4dff0f6cf6540942c40157e54f8c090b5d960104c70801b0a2f7c99215","pkg-name":"scientific","pkg-version":"0.3.7.0","flags":{"bytestring-builder":false,"integer-simple":false},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"909755ab19b453169ff85281323da1488407776b2360bd9f7afdd219fd306ef2","pkg-src-sha256":"a3a121c4b3d68fb8b9f8c709ab012e48f090ed553609247a805ad070d6b343a9","depends":["base-4.18.2.0","binary-0.8.9.1","bytestring-0.11.5.3","containers-0.6.7","deepseq-1.4.8.1","hashable-1.4.3.0-17b447e0ce504d4e093d6bf5a9838da3805c7caa5d16355da40827d004febbc8","integer-logarithms-1.0.3.1-49bf09c2474200e80cd296b047116a8ad20403e42301ba2d71d615b2824b3fcd","primitive-0.9.0.0-a6aa61bd9fff8d6cfd4880894dd85d8e644fbcf178b2bff38f87569871ea4a0d","template-haskell-2.20.0.0","text-2.0.2"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"sel-0.0.1.0-a107cece4307b775602a0ac4fef5e5489f9cf07913069de7b0aebbe27daff576","pkg-name":"sel","pkg-version":"0.0.1.0","flags":{},"style":"global","pkg-src":{"type":"source-repo","source-repo":{"type":"git","location":"https://github.com/haskell-cryptography/libsodium-bindings","tag":"86161d48","subdir":"./sel"}},"pkg-src-sha256":"a2ec222a3a7b3b7163483325bf2a0eca8d3a3416fb5ff10225526e99d362d145","depends":["base-4.18.2.0","base16-1.0-a724bafd7515d95cb8fc6e89e9d0f282f5ab5b792fe4d5387e65ac02f31e861c","bytestring-0.11.5.3","libsodium-bindings-0.0.1.1-203ee47d320ef77833137696f6f56e75297ffec7d7a2503d46941bdb48c428b0","text-2.0.2","text-display-0.0.5.1-ae9f66e9765923d9edec209058cc153706fead0e7c7287c2994a985da1c39623"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"semialign-1.3-d56979a02604b49151cb0b8ca42b64e13b0f633dac64c7e0a9a02902d973b559","pkg-name":"semialign","pkg-version":"1.3","flags":{"semigroupoids":true},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"7be9ef5ca1d6b052991f68c053aab68b9d1ab3b1938c9557ac84c97937815223","pkg-src-sha256":"628e43319f584a8dd46c124ee0685cac586e0f6f877c5ceff37c3dbb2e3cc56c","depends":["base-4.18.2.0","containers-0.6.7","hashable-1.4.3.0-17b447e0ce504d4e093d6bf5a9838da3805c7caa5d16355da40827d004febbc8","indexed-traversable-0.1.3-8f7210e35c0cb4bf73ec163bed4014cbba70e17aa189447497a492e60990637b","indexed-traversable-instances-0.1.1.2-23d2e9c28613d77bfd5595533e39512e3e8b808382cee8d422cee021acbf7fc4","semigroupoids-6.0.0.1-e83bc6491c75c3522014917ab4d3335127e2ee3b4989f0a49f9791f8bead28c6","tagged-0.8.8-5d06ce789c37adf39496775b08f7d82bb9509e4c2a3f973b0c868e35bca55ad5","these-1.2-a7d4e934136841dac2b8ed0dc77fee3f581d8c4e25fe99bdad5b76406c57bf16","transformers-0.6.1.0","unordered-containers-0.2.20-013ecc3e94c07bd5bdb23da8c9cf4d68ac66e04c4144b4096b291104672db345","vector-0.13.1.0-eb53bdac16f057ad838f4e8cb865b51b400abac71a36dc5bfde93ea1d0859eae"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"semigroupoids-6.0.0.1-e83bc6491c75c3522014917ab4d3335127e2ee3b4989f0a49f9791f8bead28c6","pkg-name":"semigroupoids","pkg-version":"6.0.0.1","flags":{"comonad":true,"containers":true,"contravariant":true,"distributive":true,"tagged":true,"unordered-containers":true},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"47a23b451c114e65361e713e8fe36828fca3a84285325e8f444254b2ab0c43c5","pkg-src-sha256":"7da38a9891bdf8205fd6522cdb712956b8c0bf5c52983da60295c8e057d77934","depends":["base-4.18.2.0","base-orphans-0.9.1-61d128d6a3318593c785a97751f2418cc86b42b03e2b46ed92e9b27fc5da689c","bifunctors-5.6.1-3bfddc97d0532e0f4bedd1f64454f96744d2fe805f93a5f9e443c2c5e1035ff1","comonad-5.0.8-8505feb1b75f0b6bf19ef9b666132d0031c1214df6db91aab78f0a9def57751c","containers-0.6.7","contravariant-1.5.5-45cb856efb41788f255562487551496b619a1cf555a23fc4a29495fda3e0c50f","distributive-0.6.2.1-70a2f4c4bffafd7749c1d755f27db885f954a9d9be1cd7db8a6e99887121ec8c","hashable-1.4.3.0-17b447e0ce504d4e093d6bf5a9838da3805c7caa5d16355da40827d004febbc8","tagged-0.8.8-5d06ce789c37adf39496775b08f7d82bb9509e4c2a3f973b0c868e35bca55ad5","template-haskell-2.20.0.0","transformers-0.6.1.0","transformers-compat-0.7.2-15ca92c51f3c4b3e5a349c3cc2a7f406ca01ba50aecd92a631a1c4d508b1230f","unordered-containers-0.2.20-013ecc3e94c07bd5bdb23da8c9cf4d68ac66e04c4144b4096b291104672db345"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"semigroups-0.20-b7dd1b9febe28a509d4e029a8add1506aac955b99fce2599f25e63f8127812a9","pkg-name":"semigroups","pkg-version":"0.20","flags":{"binary":true,"bytestring":true,"bytestring-builder":false,"containers":true,"deepseq":true,"hashable":true,"tagged":true,"template-haskell":true,"text":true,"transformers":true,"unordered-containers":true},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"925341e6f7eb104cb490bef06eab93bb7995c7c67c51ee938185a2ddefa7aaf2","pkg-src-sha256":"902d2e33c96b40a89de5957f2a9e097197afcc35e257e45b32ebe770993673e1","depends":["base-4.18.2.0"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"serialise-0.2.6.1-9a84217bb1945b5559a174f6d6db34ff78ae2ce9f9cba7b4a3abdeedb09747ca","pkg-name":"serialise","pkg-version":"0.2.6.1","flags":{"newtime15":true},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"48e55f150c7e3bac9003adeb49fcd4573814780c374c494a46ffccc2b2043df8","pkg-src-sha256":"63949799ffd10675ef70ea701c1eb63e618629b3b2f7b25f07c5a966e24e77f4","depends":["array-0.5.6.0","base-4.18.2.0","bytestring-0.11.5.3","cborg-0.2.10.0-cfaa438104ce487b61248b85071f08fb39e16a23a8eb0f32a1ad8b086d37fb6b","containers-0.6.7","ghc-prim-0.10.0","half-0.3.1-abaa8d4e544e24e38c9200d7b5cfb6731ae8b4aec4a1d27bf34cec5836e12ff6","hashable-1.4.3.0-17b447e0ce504d4e093d6bf5a9838da3805c7caa5d16355da40827d004febbc8","primitive-0.9.0.0-a6aa61bd9fff8d6cfd4880894dd85d8e644fbcf178b2bff38f87569871ea4a0d","strict-0.5-84b2c7152a9fd6aee3e1d1082edade7580c5af3226a0afc18e19724ada9d7fe4","text-2.0.2","these-1.2-a7d4e934136841dac2b8ed0dc77fee3f581d8c4e25fe99bdad5b76406c57bf16","time-1.12.2","unordered-containers-0.2.20-013ecc3e94c07bd5bdb23da8c9cf4d68ac66e04c4144b4096b291104672db345","vector-0.13.1.0-eb53bdac16f057ad838f4e8cb865b51b400abac71a36dc5bfde93ea1d0859eae"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"servant-0.20.1-b63507222e1b19c7b8333551fd2fbdae76248ba97753767f7ab4d32b7816d39d","pkg-name":"servant","pkg-version":"0.20.1","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"3f0850b019cfcb66501048e6e881a005b2decfee9abb36efc8a2bb5e4f76fe8c","pkg-src-sha256":"94f773f9bdff67eb2d7aec9c67f80e8af79d531ba6f52fad2e142d8ce4551be9","depends":["QuickCheck-2.14.3-091d344acf9c963200a9b2af6c5417d91912262a9a84b607d918b50fdf8a8b02","aeson-2.2.1.0-2595d249b227784b9febcd5a91568775f66fd262ac45c82c44f7b4a55e9d4c27","attoparsec-0.14.4-5061b5f729de9f72f69961345d54e0249a28df7c232bb9cf2b0525b6f17a253a","base-4.18.2.0","base-compat-0.13.1-f0385202d32a5d6c7b36f9e6f39a361e139bf7a5858ef12f1c89ce0c83283469","bifunctors-5.6.1-3bfddc97d0532e0f4bedd1f64454f96744d2fe805f93a5f9e443c2c5e1035ff1","bytestring-0.11.5.3","case-insensitive-1.2.1.0-5255eaf892b10e8489fdad145ca833a10864bd951f3e69d04088fbcadf28ec6d","constraints-0.14-ab15a9f94938365a9f7a935af490e603978d84c5e110ef254a28de6613181c00","deepseq-1.4.8.1","http-api-data-0.6-f8db4c3e7ff814c1476ac3873683211db56d23f0c28cabdd051460114fc3de4f","http-media-0.8.1.1-82ac8def17fc7bb0c409983a665f6b7cccbfddad16ad03396e0ea28fa6b4797e","http-types-0.12.4-0f52a9ec33f3c65ef0b77ad8ce14b65f9164f8a761e42800dc9c80ee1768aacc","mmorph-1.2.0-967f2a66454abded96663c19c27c375e74faace9a8cd232a9ae738ec2604ffa1","mtl-2.3.1","network-uri-2.6.4.2-d62d36021f4a84b02c9243cbe37e9dfd5b7ba840b4aaedb5e002f05582564fc4","singleton-bool-0.1.7-fbe38d0a2a0228b679b4c8812d28d8c40fc5a0ec6c5d0e43b3986b92d3dfc0aa","sop-core-0.5.0.2-916ec985869f4742a9c9e1c1cdd20338928cdc574be8814bb09c58ce2e7bf566","string-conversions-0.4.0.1-84561bf691f05f917e60aa94bd28d55750bb3e08ac9a7bd02c365e1ff133b25f","tagged-0.8.8-5d06ce789c37adf39496775b08f7d82bb9509e4c2a3f973b0c868e35bca55ad5","text-2.0.2","transformers-0.6.1.0","vault-0.3.1.5-20d43e8d257de908486713884f035343ca6659f91d72e14d1c91b355c58e3031"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"servant-blaze-0.9.1-da2a7530394d74e561426e042173ccf4cf339c8817d4384d3298e88abfef4266","pkg-name":"servant-blaze","pkg-version":"0.9.1","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"88f4c23a97ea014909755de651800c12eda66e9f8d0cdfddbbacf1eef61889ad","pkg-src-sha256":"264aa17b95400a13cf23f7421f54b3a3160119c15380a31a96bdfc4a40f2db21","depends":["base-4.18.2.0","blaze-html-0.9.1.2-3a4f994094b15669094f06ad98d568adb79b03a7829eff4349476c2fafb25845","http-media-0.8.1.1-82ac8def17fc7bb0c409983a665f6b7cccbfddad16ad03396e0ea28fa6b4797e","servant-0.20.1-b63507222e1b19c7b8333551fd2fbdae76248ba97753767f7ab4d32b7816d39d"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"servant-client-0.20-ffd6b2eca0816fa09c64c230d34ebe7b6ee3f06a805980e86e28fb7d902f65e2","pkg-name":"servant-client","pkg-version":"0.20","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"d89d787d3b35fc0aa6721b6f33e78271fa2d5b3181ade11ca9150921844e932b","pkg-src-sha256":"765d30f3579b74bebfe79f59a4aacfd9dec0c02c7d355f389caa604f0ac3b276","depends":["base-4.18.2.0","base-compat-0.13.1-f0385202d32a5d6c7b36f9e6f39a361e139bf7a5858ef12f1c89ce0c83283469","bytestring-0.11.5.3","containers-0.6.7","deepseq-1.4.8.1","exceptions-0.10.7","http-client-0.7.16-08ac6af6261aa24f586bbb528e8ea2f0bd2e7510d1883948d770173e7ea8b633","http-media-0.8.1.1-82ac8def17fc7bb0c409983a665f6b7cccbfddad16ad03396e0ea28fa6b4797e","http-types-0.12.4-0f52a9ec33f3c65ef0b77ad8ce14b65f9164f8a761e42800dc9c80ee1768aacc","kan-extensions-5.2.5-60f11eb11e93cf481fad2a42529d0965e7472bd8d512eba70477a626921ed65c","monad-control-1.0.3.1-2bf3452c923aa94707518b6d970f4377279fd8c4ccca1256725eef18b6097440","mtl-2.3.1","semigroupoids-6.0.0.1-e83bc6491c75c3522014917ab4d3335127e2ee3b4989f0a49f9791f8bead28c6","servant-0.20.1-b63507222e1b19c7b8333551fd2fbdae76248ba97753767f7ab4d32b7816d39d","servant-client-core-0.20-9e603d4d82c8eefde573caf5b7328a91ee474d7e0ede0539645efa20a15a89d4","stm-2.5.1.0","text-2.0.2","time-1.12.2","transformers-0.6.1.0","transformers-base-0.4.6-91c64a4b19c3f5f9f196345e9032803d52322bd0857ba94ea6c4260a27a2ff07","transformers-compat-0.7.2-15ca92c51f3c4b3e5a349c3cc2a7f406ca01ba50aecd92a631a1c4d508b1230f"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"servant-client-core-0.20-9e603d4d82c8eefde573caf5b7328a91ee474d7e0ede0539645efa20a15a89d4","pkg-name":"servant-client-core","pkg-version":"0.20","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"fb4d8c3ee3bcb09afbea93994cc9d0d54278d5460213b8002c36b08deb76070b","pkg-src-sha256":"a6744916079ec769c248ff5f7a2cc62d7eb03abb445be6c1fa7811c2866b4b04","depends":["aeson-2.2.1.0-2595d249b227784b9febcd5a91568775f66fd262ac45c82c44f7b4a55e9d4c27","base-4.18.2.0","base-compat-0.13.1-f0385202d32a5d6c7b36f9e6f39a361e139bf7a5858ef12f1c89ce0c83283469","base64-bytestring-1.2.1.0-ecb3bf792eac6ec696f20e02e528e8a7b2a76a5b32c46409c4645e1bfbd71cf4","bytestring-0.11.5.3","constraints-0.14-ab15a9f94938365a9f7a935af490e603978d84c5e110ef254a28de6613181c00","containers-0.6.7","deepseq-1.4.8.1","exceptions-0.10.7","free-5.2-841f6f1c7522ed92dbed9d024b48671e79a9cdd76652f8bdbf9c0e63908771e7","http-media-0.8.1.1-82ac8def17fc7bb0c409983a665f6b7cccbfddad16ad03396e0ea28fa6b4797e","http-types-0.12.4-0f52a9ec33f3c65ef0b77ad8ce14b65f9164f8a761e42800dc9c80ee1768aacc","network-uri-2.6.4.2-d62d36021f4a84b02c9243cbe37e9dfd5b7ba840b4aaedb5e002f05582564fc4","safe-0.3.21-31bf385773e1c6ef212139e0505190c20d1e3d1af99bcbfc189c01c3a1e0e739","servant-0.20.1-b63507222e1b19c7b8333551fd2fbdae76248ba97753767f7ab4d32b7816d39d","sop-core-0.5.0.2-916ec985869f4742a9c9e1c1cdd20338928cdc574be8814bb09c58ce2e7bf566","template-haskell-2.20.0.0","text-2.0.2","transformers-0.6.1.0"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"servant-effectful-0.0.1.0-c4ee2e1edab9dee5d08c4d73546b8e7f68d11d1fb84ee678884d3202776c376f","pkg-name":"servant-effectful","pkg-version":"0.0.1.0","flags":{},"style":"global","pkg-src":{"type":"source-repo","source-repo":{"type":"git","location":"https://github.com/kleidukos/servant-effectful","tag":"cec4d54"}},"pkg-src-sha256":"447e32a04da1415d62bad0b7f243962f235b353a738e2005241d5378a4fc2024","depends":["base-4.18.2.0","effectful-core-2.3.0.1-011d84ab0bc8bb2010bac83565500e3039592cab57d902e9a2a502684b92d90f","mtl-2.3.1","servant-server-0.20-3dbcc60207566a1f80874e61a86b73ab8a41f98f3231692dec244b2ce96f8132","warp-3.3.31-3a081a14799ab48e5efe3a315077d1e89ea4da61799497b4990d5fc7e0dcb380"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"servant-lucid-0.9.0.6-3245f97c511011e42d95122d5373c12ebeb20de76226f6491768d04935bf6b52","pkg-name":"servant-lucid","pkg-version":"0.9.0.6","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"b7de9f07a056037a10cc012136e7cabc2e685403791d2c0cb0a92f16e3ade6ac","pkg-src-sha256":"a03973035722f9aee7a67fcbb6f44a2d515284e21b0bbf236fda3207132709fd","depends":["base-4.18.2.0","http-media-0.8.1.1-82ac8def17fc7bb0c409983a665f6b7cccbfddad16ad03396e0ea28fa6b4797e","lucid-2.11.20230408-181c7ed44fa9b37af3ac434ed53e16dbe6a7ca9ec7ef1f7e5c921196d628f3c0","servant-0.20.1-b63507222e1b19c7b8333551fd2fbdae76248ba97753767f7ab4d32b7816d39d","text-2.0.2"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"servant-openapi3-2.0.1.6-92378e8ee0bea5a4e54c3dd4fc1e97b9c790b2fcc65c5a79e54d520319677c44","pkg-name":"servant-openapi3","pkg-version":"2.0.1.6","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"bd35a4d7c9d6c1d01763ab65461978a0c1212d6070c72f4cf745b78918145d0f","pkg-src-sha256":"322a2181fb2becb20b80ad8319dd3ce1874d89cd344a8d8a4e17d1428d1dbfc3","components":{"lib":{"depends":["QuickCheck-2.14.3-091d344acf9c963200a9b2af6c5417d91912262a9a84b607d918b50fdf8a8b02","aeson-2.2.1.0-2595d249b227784b9febcd5a91568775f66fd262ac45c82c44f7b4a55e9d4c27","aeson-pretty-0.8.10-9bd6a60b424b6a69fcd0507ef3b99938ee971580bc5bfa89249b16ff60b2c117","base-4.18.2.0","base-compat-0.13.1-f0385202d32a5d6c7b36f9e6f39a361e139bf7a5858ef12f1c89ce0c83283469","bytestring-0.11.5.3","hspec-2.11.7-e5ff04a60a8c23d1953854fc051870a447d8cf15eac67b388ed88c8c0711ecd0","http-media-0.8.1.1-82ac8def17fc7bb0c409983a665f6b7cccbfddad16ad03396e0ea28fa6b4797e","insert-ordered-containers-0.2.5.3-3706f6956e9c93eb40f4960ef2def44ebba2c69366f9391e537c47e536d7a5e7","lens-5.2.3-fd9d842bd7b66c837b8b9d8ed9b74a1913e207465f21d80d3c84691d23c5c119","openapi3-3.2.4-36a3dd9c34b66f8d7bf989194c80a50284551837b7d8417e8ce95b4a35d15c2e","servant-0.20.1-b63507222e1b19c7b8333551fd2fbdae76248ba97753767f7ab4d32b7816d39d","singleton-bool-0.1.7-fbe38d0a2a0228b679b4c8812d28d8c40fc5a0ec6c5d0e43b3986b92d3dfc0aa","text-2.0.2","unordered-containers-0.2.20-013ecc3e94c07bd5bdb23da8c9cf4d68ac66e04c4144b4096b291104672db345"],"exe-depends":[]},"setup":{"depends":["Cabal-3.10.1.0","base-4.18.2.0","cabal-doctest-1.0.9-4a685fb2745cdab49526ff8fe3801bf6bd4ab5085239033fcfd51613f7e3fd76"],"exe-depends":[]}}},{"type":"configured","id":"servant-server-0.20-3dbcc60207566a1f80874e61a86b73ab8a41f98f3231692dec244b2ce96f8132","pkg-name":"servant-server","pkg-version":"0.20","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"6f312610f197b0162dc198250c553c9bcfeeb8d2f960929909a1d21e278d37f8","pkg-src-sha256":"13b2fe785be1aae07e15d139fa1f94c7c5db6c8d36d0fc7789576b31a9bee8be","depends":["base-4.18.2.0","base-compat-0.13.1-f0385202d32a5d6c7b36f9e6f39a361e139bf7a5858ef12f1c89ce0c83283469","base64-bytestring-1.2.1.0-ecb3bf792eac6ec696f20e02e528e8a7b2a76a5b32c46409c4645e1bfbd71cf4","bytestring-0.11.5.3","constraints-0.14-ab15a9f94938365a9f7a935af490e603978d84c5e110ef254a28de6613181c00","containers-0.6.7","exceptions-0.10.7","filepath-1.4.200.1","http-api-data-0.6-f8db4c3e7ff814c1476ac3873683211db56d23f0c28cabdd051460114fc3de4f","http-media-0.8.1.1-82ac8def17fc7bb0c409983a665f6b7cccbfddad16ad03396e0ea28fa6b4797e","http-types-0.12.4-0f52a9ec33f3c65ef0b77ad8ce14b65f9164f8a761e42800dc9c80ee1768aacc","monad-control-1.0.3.1-2bf3452c923aa94707518b6d970f4377279fd8c4ccca1256725eef18b6097440","mtl-2.3.1","network-3.1.4.0-9d41c9df77e8d21da5aaf51c19540d3c0fc11e5e2c2940bea5411915b8a462ff","network-uri-2.6.4.2-d62d36021f4a84b02c9243cbe37e9dfd5b7ba840b4aaedb5e002f05582564fc4","resourcet-1.3.0-0f210c6e8ffe9f595ad8fd1a6cf6726e42a6695abb7febee22452f40436a2bc5","servant-0.20.1-b63507222e1b19c7b8333551fd2fbdae76248ba97753767f7ab4d32b7816d39d","sop-core-0.5.0.2-916ec985869f4742a9c9e1c1cdd20338928cdc574be8814bb09c58ce2e7bf566","string-conversions-0.4.0.1-84561bf691f05f917e60aa94bd28d55750bb3e08ac9a7bd02c365e1ff133b25f","tagged-0.8.8-5d06ce789c37adf39496775b08f7d82bb9509e4c2a3f973b0c868e35bca55ad5","text-2.0.2","transformers-0.6.1.0","transformers-base-0.4.6-91c64a4b19c3f5f9f196345e9032803d52322bd0857ba94ea6c4260a27a2ff07","wai-3.2.4-acf062ae483a435740bc88b21ee81f62d3f94a62faea15a5bf17463ace439645","wai-app-static-3.1.8-d2d0c9be3a5bd2980a68b3225b620c023885a62d44f09cee23e1325fcbe6c50c","word8-0.1.3-f7afede617c5019b5fe8b27341f573a6ee2d2232a9ed28ec7e4caca5e3512696"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"servant-server-0.20-e-greet-c4c2dabfbf5e13a9abbac418346eb7480bf780a0e30e97504f50adc6ed1fe689","pkg-name":"servant-server","pkg-version":"0.20","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"6f312610f197b0162dc198250c553c9bcfeeb8d2f960929909a1d21e278d37f8","pkg-src-sha256":"13b2fe785be1aae07e15d139fa1f94c7c5db6c8d36d0fc7789576b31a9bee8be","depends":["aeson-2.2.1.0-2595d249b227784b9febcd5a91568775f66fd262ac45c82c44f7b4a55e9d4c27","base-4.18.2.0","base-compat-0.13.1-f0385202d32a5d6c7b36f9e6f39a361e139bf7a5858ef12f1c89ce0c83283469","servant-0.20.1-b63507222e1b19c7b8333551fd2fbdae76248ba97753767f7ab4d32b7816d39d","servant-server-0.20-3dbcc60207566a1f80874e61a86b73ab8a41f98f3231692dec244b2ce96f8132","text-2.0.2","wai-3.2.4-acf062ae483a435740bc88b21ee81f62d3f94a62faea15a5bf17463ace439645","warp-3.3.31-3a081a14799ab48e5efe3a315077d1e89ea4da61799497b4990d5fc7e0dcb380"],"exe-depends":[],"component-name":"exe:greet","bin-file":"/home/hecate/Projects/Flora/1-flora-server/_build/cabal-store/ghc-9.6.4/servant-server-0.20-e-greet-c4c2dabfbf5e13a9abbac418346eb7480bf780a0e30e97504f50adc6ed1fe689/bin/greet"},{"type":"configured","id":"servant-static-th-1.0.0.0-fa0f3ab3712e7a8402c328f207cfc41d9d7c81ead2eb76b54e22775de96a15db","pkg-name":"servant-static-th","pkg-version":"1.0.0.0","flags":{"buildexample":false},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"7dc46a426d8c78ee0386729159e8bbc18ff98e0dd700a2c723c87901b204fa6c","pkg-src-sha256":"25d4ca76d10bcaef4ae33571c3629d015b92297bb0391806d7f06f91e6327ec6","depends":["base-4.18.2.0","blaze-html-0.9.1.2-3a4f994094b15669094f06ad98d568adb79b03a7829eff4349476c2fafb25845","bytestring-0.11.5.3","containers-0.6.7","directory-1.3.8.1","filepath-1.4.200.1","http-media-0.8.1.1-82ac8def17fc7bb0c409983a665f6b7cccbfddad16ad03396e0ea28fa6b4797e","semigroups-0.20-b7dd1b9febe28a509d4e029a8add1506aac955b99fce2599f25e63f8127812a9","servant-0.20.1-b63507222e1b19c7b8333551fd2fbdae76248ba97753767f7ab4d32b7816d39d","servant-blaze-0.9.1-da2a7530394d74e561426e042173ccf4cf339c8817d4384d3298e88abfef4266","servant-server-0.20-3dbcc60207566a1f80874e61a86b73ab8a41f98f3231692dec244b2ce96f8132","template-haskell-2.20.0.0","text-2.0.2"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"simple-sendfile-0.2.32-40d1e9f7a944730d0ccd2218dd6dd93bb24e35bc984ac0852a20de36b49e40dc","pkg-name":"simple-sendfile","pkg-version":"0.2.32","flags":{"allow-bsd":true,"fallback":false},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"133f419b9b6b8a4db8541f381c20b8dfca962a59e82ba203e66d6bef41cf8ea4","pkg-src-sha256":"9f28d0a67ac3d956d2dd78eb19ea922c0a9192bbbeeeead20d39f561636828a3","depends":["base-4.18.2.0","bytestring-0.11.5.3","network-3.1.4.0-9d41c9df77e8d21da5aaf51c19540d3c0fc11e5e2c2940bea5411915b8a462ff","unix-2.8.4.0"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"singleton-bool-0.1.7-fbe38d0a2a0228b679b4c8812d28d8c40fc5a0ec6c5d0e43b3986b92d3dfc0aa","pkg-name":"singleton-bool","pkg-version":"0.1.7","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"ec20e246f8bbe46c17789113b5f2154abdddf14b8a06efc4724832f657680dab","pkg-src-sha256":"1c2d196386c3697e884fcc8bef530506045a4860a5f669cc8416358b473bb29b","depends":["base-4.18.2.0","boring-0.2.1-9a8dc8e41ea918a09754ff07614d4843b0ebe75d8757fd3273e17938f5bf6233","dec-0.0.5-df077fdbf908bb3fdbc8e113d90c87e216153ded7ddd81017ddf01027a3a495b","deepseq-1.4.8.1","some-1.0.6-b5e68e5a2560a2bb7914b23d969585e8eec636a7a4ee9bccb9ebc0ce020bbc67"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"slugify-0.1.0.1-4ab88c5012a98f82389b22741a6da4533ceb4b7336ca607b4e641118933d2d75","pkg-name":"slugify","pkg-version":"0.1.0.1","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"0764c30a5d6d6342ca055a97f0a7b4279a26b42b9483b73420d1b364d3f8fb38","pkg-src-sha256":"7b6304a31eef16fe291fd24b539a875795500e53f4b2d244a6203438c65db4c0","depends":["base-4.18.2.0","text-2.0.2","unicode-transforms-0.4.0.1-8c67b0eaf2d5104e81ffbe7caf4900a211ea1e275b21ae6aca8253bd0b8d074b"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"socks-0.6.1-6b9e88c9a8f5eb4e1297331a35574d1481e0bfa053fb8eb954e442854a2c7b98","pkg-name":"socks","pkg-version":"0.6.1","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"ac190808eea704672df18f702e8f2ad0b7a4d0af528e95ee55ea6ee0be672e2a","pkg-src-sha256":"734447558bb061ce768f53a0df1f2401902c6bee396cc96ce627edd986ef6a73","depends":["base-4.18.2.0","basement-0.0.16-2ba9d181df7bdd547d6fedd5acdec581f03e379e22b0e08ff998fb0462257d08","bytestring-0.11.5.3","cereal-0.5.8.3-930e90604013ce2a32c6d28d3567d1d966e50eb1bf0c18108838f2b4ff0d64ca","network-3.1.4.0-9d41c9df77e8d21da5aaf51c19540d3c0fc11e5e2c2940bea5411915b8a462ff"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"some-1.0.6-b5e68e5a2560a2bb7914b23d969585e8eec636a7a4ee9bccb9ebc0ce020bbc67","pkg-name":"some","pkg-version":"1.0.6","flags":{"newtype-unsafe":true},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"563f5e0db06772cb1c64d690a07fa9976a1a2dc43ee85a8de52e058d579c4d77","pkg-src-sha256":"f7a606ad5df4a07459986364f7d739eb653495fbbe1d7158582fb29a4584bfb9","depends":["base-4.18.2.0","base-orphans-0.9.1-61d128d6a3318593c785a97751f2418cc86b42b03e2b46ed92e9b27fc5da689c","deepseq-1.4.8.1"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"sop-core-0.5.0.2-916ec985869f4742a9c9e1c1cdd20338928cdc574be8814bb09c58ce2e7bf566","pkg-name":"sop-core","pkg-version":"0.5.0.2","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"9d857199f5eab3e2467be69336568d147fa24116a0999000100e4f0739719966","pkg-src-sha256":"87bffd2254b98ded822d449fcd1c33dbd74d2ce96bf35e7a6714abc5a2297265","depends":["base-4.18.2.0","deepseq-1.4.8.1"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"souffle-haskell-4.0.0-122eb0210bf095a8300c9247fb7467920a26f76fde9fbfed4d1bae48e6666480","pkg-name":"souffle-haskell","pkg-version":"4.0.0","flags":{},"style":"global","pkg-src":{"type":"source-repo","source-repo":{"type":"git","location":"https://github.com/tchoutri/souffle-haskell","tag":"3afe53f"}},"pkg-src-sha256":"fa4cf59eff0d2b759c3c8ad720a5f849c988431a3d024e993b4d12c740ef5d37","depends":["array-0.5.6.0","base-4.18.2.0","bytestring-0.11.5.3","deepseq-1.4.8.1","directory-1.3.8.1","filepath-1.4.200.1","mtl-2.3.1","process-1.6.17.0","profunctors-5.6.2-8b084a9552445e5776f01a7b42f1722ce1ecf20cf9a8e839007b9baea33b9fa4","temporary-1.3-8e8fc8e7de23013c321e5cc7c7df5ece76432805295711c83110e9fdced98b05","text-2.0.2","vector-0.13.1.0-eb53bdac16f057ad838f4e8cb865b51b400abac71a36dc5bfde93ea1d0859eae"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"split-0.2.5-f91000d531a43d0958a6d552a0e528a48098723972009db93c4b79044dc4bd51","pkg-name":"split","pkg-version":"0.2.5","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"5bc1ae848bfded3087ea3e568908f1b75f56ecde6f02df3fad1a138dd5c783d5","pkg-src-sha256":"52da404e8397c1ab238354c8d4fd9a7e9c5cac8849cc2ce2e45facc85e74a913","depends":["base-4.18.2.0"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"splitmix-0.1.0.5-4c4c1f33537354cbf1e3da145a4775d1633faaa320080e06e92a1f67dbed4227","pkg-name":"splitmix","pkg-version":"0.1.0.5","flags":{"optimised-mixer":false},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"bac0ae8d46a04e410666b0c8081cff63f060f29157983b569ca86ddb6e6e0dc6","pkg-src-sha256":"9df07a9611ef45f1b1258a0b412f4d02c920248f69d2e2ce8ccda328f7e13002","depends":["base-4.18.2.0","deepseq-1.4.8.1"],"exe-depends":[],"component-name":"lib"},{"type":"pre-existing","id":"stm-2.5.1.0","pkg-name":"stm","pkg-version":"2.5.1.0","depends":["array-0.5.6.0","base-4.18.2.0"]},{"type":"configured","id":"stm-chans-3.0.0.9-577989fa35770d28044d742360c9f0596a5d84e540cf2b1ce7716c9d1fa528e0","pkg-name":"stm-chans","pkg-version":"3.0.0.9","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"b2d4b54b2859da7a002819165fae0b051582036af7c313c23e9e0d28562e1938","pkg-src-sha256":"7a060df537cb93c98380a770f88d4a1ff08b79fe07203c859be7bc815dc1325d","depends":["base-4.18.2.0","stm-2.5.1.0"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"streaming-commons-0.2.2.6-9fa4239301ef39252b6218423c0a2438611fe43c2ddbebd4f8953d4455c07935","pkg-name":"streaming-commons","pkg-version":"0.2.2.6","flags":{"use-bytestring-builder":false},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"d5c6fb99efd4e71bdb0351d55f2d87e16c11880f42998e39363eb63f057ae24b","pkg-src-sha256":"0180958a882eb0f6262b812fe886c2b1b8285474b5b958f814ae4f05409fbf79","depends":["array-0.5.6.0","async-2.2.4-2107e60f1bee7c70ffed77e551ffc7db01e350edd8784cc9493cc782305122d0","base-4.18.2.0","bytestring-0.11.5.3","directory-1.3.8.1","network-3.1.4.0-9d41c9df77e8d21da5aaf51c19540d3c0fc11e5e2c2940bea5411915b8a462ff","process-1.6.17.0","random-1.2.1.2-cc746490e13a1f967de173a54c09753b2ccdb5d95056b0f1206a29c62c83de45","stm-2.5.1.0","text-2.0.2","transformers-0.6.1.0","unix-2.8.4.0","zlib-0.6.3.0-61cb40f46d103a622525dc3a70a9004984ec56d61deea65d2dc01c964606b7e9"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"streamly-0.10.1-355a5bd5db83dc8d0325992ae963a6091c0eb61a91ecdda01c0d7d997bd43408","pkg-name":"streamly","pkg-version":"0.10.1","flags":{"debug":false,"dev":false,"fusion-plugin":false,"has-llvm":false,"inspection":false,"limit-build-mem":false,"opt":true,"use-unliftio":false},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"f63db612bd97182c3eca4e23f0ddc6bbf45d025db155e113335e7b07ccdef49f","pkg-src-sha256":"b66b832aec36db07edb6e00901cbfe32c55ef245a5bbc6ab2c9cbb4d25ccdbc7","components":{"lib":{"depends":["atomic-primops-0.8.5-619a7ba3c59ea074ae39e3adf75904b21a27146e973f334ea4ab876a9cc1e3c2","base-4.18.2.0","containers-0.6.7","deepseq-1.4.8.1","directory-1.3.8.1","exceptions-0.10.7","hashable-1.4.3.0-17b447e0ce504d4e093d6bf5a9838da3805c7caa5d16355da40827d004febbc8","heaps-0.4-8352de6c15db4be4912bb7418446dab1e2d80f26647938794abadafee6111c60","lockfree-queue-0.2.4-db50ab392a0002236dd2987e766180a4fb8a8cc2c59dcf98973caca190b12610","monad-control-1.0.3.1-2bf3452c923aa94707518b6d970f4377279fd8c4ccca1256725eef18b6097440","mtl-2.3.1","network-3.1.4.0-9d41c9df77e8d21da5aaf51c19540d3c0fc11e5e2c2940bea5411915b8a462ff","streamly-core-0.2.2-1de2fd5320df2135ec5ee591367a8233ec85c39bfb2366f77b325fca4e8a6657","template-haskell-2.20.0.0","transformers-0.6.1.0","unicode-data-0.4.0.1-2cec5f4ee6f7dac835f9656497f58d5132b6da46ac07f33c15ef93dbfe67a942","unordered-containers-0.2.20-013ecc3e94c07bd5bdb23da8c9cf4d68ac66e04c4144b4096b291104672db345"],"exe-depends":[]}}},{"type":"configured","id":"streamly-core-0.2.2-1de2fd5320df2135ec5ee591367a8233ec85c39bfb2366f77b325fca4e8a6657","pkg-name":"streamly-core","pkg-version":"0.2.2","flags":{"debug":false,"dev":false,"has-llvm":false,"limit-build-mem":false,"opt":true,"use-folds":false,"use-unfolds":false,"use-unliftio":false},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"e44a0f6e4870df7a206dbaad531deac7907a73a883fbdb5a460d63a8e086efe7","pkg-src-sha256":"ca94773dece7e0cc0c8afbdca15c5f62d48c769b781833abd231bf80d88cd583","components":{"lib":{"depends":["base-4.18.2.0","containers-0.6.7","directory-1.3.8.1","exceptions-0.10.7","filepath-1.4.200.1","fusion-plugin-types-0.1.0-af0a0db9279412adcb5a431d750045b40fdb99350a31564d7ec80e2944df0ac3","ghc-bignum-1.3","ghc-prim-0.10.0","heaps-0.4-8352de6c15db4be4912bb7418446dab1e2d80f26647938794abadafee6111c60","monad-control-1.0.3.1-2bf3452c923aa94707518b6d970f4377279fd8c4ccca1256725eef18b6097440","template-haskell-2.20.0.0","transformers-0.6.1.0","unix-2.8.4.0"],"exe-depends":[]}}},{"type":"configured","id":"strict-0.5-84b2c7152a9fd6aee3e1d1082edade7580c5af3226a0afc18e19724ada9d7fe4","pkg-name":"strict","pkg-version":"0.5","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"bd57d7b3655951dfaa7d1e1374d7352dfe83f82a9c98309bf3a6587ef8cbd87d","pkg-src-sha256":"3f4f0995dec2d520d0e321542f71412dac023658fdab603db04364d75269a0fd","depends":["assoc-1.1-44564689989a4d2721c54fe7433f3b2450e556c3fe6c52752ad54623647f561c","base-4.18.2.0","binary-0.8.9.1","bytestring-0.11.5.3","deepseq-1.4.8.1","ghc-prim-0.10.0","hashable-1.4.3.0-17b447e0ce504d4e093d6bf5a9838da3805c7caa5d16355da40827d004febbc8","text-2.0.2","these-1.2-a7d4e934136841dac2b8ed0dc77fee3f581d8c4e25fe99bdad5b76406c57bf16","transformers-0.6.1.0"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"string-conv-0.2.0-2b20138e5715fec3a0be370b62f70071e607c80729c0151ebac083484fb380fb","pkg-name":"string-conv","pkg-version":"0.2.0","flags":{"lib-werror":false},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"5aaa21ad20be79ec6fedcc6f45ef2d34b32797da8715e48d803ac467059b7333","pkg-src-sha256":"39cea3010eb1c52b6dd21c4108e23b89926f0f21b872ad1f5f644328c73a9096","depends":["base-4.18.2.0","bytestring-0.11.5.3","text-2.0.2"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"string-conversions-0.4.0.1-84561bf691f05f917e60aa94bd28d55750bb3e08ac9a7bd02c365e1ff133b25f","pkg-name":"string-conversions","pkg-version":"0.4.0.1","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"9af49d61d1dcbc8b90b66f1b6580996b7927f745273edb59141ad6744aef7cbc","pkg-src-sha256":"46bcce6d9ce62c558b7658a75d9c6a62f7259d6b0473d011d8078234ad6a1994","depends":["base-4.18.2.0","bytestring-0.11.5.3","text-2.0.2","utf8-string-1.0.2-5e8d116496349c38d20293f85d47a22c703548b74e7d267d8d6d20ff907c03cd"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"syb-0.7.2.4-80d2f5060ad894d00e83dbe185e57c37c081728996394fa6f5a2fa912bb894f4","pkg-name":"syb","pkg-version":"0.7.2.4","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"936d5a92084ad9d88c5a9dd2e622deab57ce48ce85be93e6273b3f8eb64c12ca","pkg-src-sha256":"ec7c1e8822d62ab910386361cdcee40a22a26cd344c34741fadd982302291e60","depends":["base-4.18.2.0"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"tagged-0.8.8-5d06ce789c37adf39496775b08f7d82bb9509e4c2a3f973b0c868e35bca55ad5","pkg-name":"tagged","pkg-version":"0.8.8","flags":{"deepseq":true,"transformers":true},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"c4fdbd3e1c423af0ccf8eb9e9962620106c34e32ed8e0cc647fb06899a703e04","pkg-src-sha256":"a083fa7835516203c168433a1c8dfc0290a94b05fedab566ad0640fc9137a6a7","depends":["base-4.18.2.0","deepseq-1.4.8.1","template-haskell-2.20.0.0","transformers-0.6.1.0"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"tar-0.6.1.0-2355dea2b7e5a1fb20c6753c9c6e0e55e2208d19d4f800ee0c38ad10afdd8945","pkg-name":"tar","pkg-version":"0.6.1.0","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"3ed979ee1bb00b4e488537988ee6bb3c2c67e66678804125e2df08a527822b4e","pkg-src-sha256":"edfef2e126440839d34f23fff7f3616d0bfffa0345ea13d4d0fee9a669d305da","depends":["tar-0.6.1.0-l-tar-internal-1aae186eb408d3785bd7f67a0382b0e7a4c4edeff6562f680c56aba961b4dd7a"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"tar-0.6.1.0-l-tar-internal-1aae186eb408d3785bd7f67a0382b0e7a4c4edeff6562f680c56aba961b4dd7a","pkg-name":"tar","pkg-version":"0.6.1.0","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"3ed979ee1bb00b4e488537988ee6bb3c2c67e66678804125e2df08a527822b4e","pkg-src-sha256":"edfef2e126440839d34f23fff7f3616d0bfffa0345ea13d4d0fee9a669d305da","depends":["array-0.5.6.0","base-4.18.2.0","bytestring-0.11.5.3","containers-0.6.7","deepseq-1.4.8.1","directory-1.3.8.1","filepath-1.4.200.1","os-string-2.0.2-c94c7716dceda9adcf8c3208c87dc23b7f71b84fca751a70ffc309850517a402","time-1.12.2","transformers-0.6.1.0"],"exe-depends":[],"component-name":"lib:tar-internal"},{"type":"configured","id":"tasty-1.5-fd9a969b42a912ece8c4543e101cd6e26eee76689c8c5a012bcea4edbf273551","pkg-name":"tasty","pkg-version":"1.5","flags":{"unix":true},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"8da3f47fff790714f7d676692f1207aac156b41f705c55f14d1d8147a751264b","pkg-src-sha256":"ca5cf7852a210e691d4dce67ee34de7ccb8ae390a3a68ecffde307e326d029ac","depends":["ansi-terminal-1.0.2-f2271bf25e5299c165409ab78d5917aeba79c479959932bb5fb284c513226fc0","base-4.18.2.0","containers-0.6.7","optparse-applicative-0.18.1.0-1de8f12cfc2915bc6d323ba97415a7e0795036a6b613e7301735aedf9d0425be","stm-2.5.1.0","tagged-0.8.8-5d06ce789c37adf39496775b08f7d82bb9509e4c2a3f973b0c868e35bca55ad5","transformers-0.6.1.0","unix-2.8.4.0"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"tasty-hunit-0.10.1-d5d74b078c2fc7d0540add40bfcb063d16fc8fc5e21d9467944dfc172c67d6a5","pkg-name":"tasty-hunit","pkg-version":"0.10.1","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"ebc17b490750d4796b21d44001b852688cc39f9c34e387d5e7958e09b9b3f3b9","pkg-src-sha256":"9ceb423bd258b04c893b8b43434f50b7ff487c7afd092fe2ef9415ca8c2c2083","depends":["base-4.18.2.0","call-stack-0.4.0-a0fd887e5d06d11a75269d5dfed7da6fe2656edbbd7cc1697fb2a2b8ad4fe392","tasty-1.5-fd9a969b42a912ece8c4543e101cd6e26eee76689c8c5a012bcea4edbf273551"],"exe-depends":[],"component-name":"lib"},{"type":"pre-existing","id":"template-haskell-2.20.0.0","pkg-name":"template-haskell","pkg-version":"2.20.0.0","depends":["base-4.18.2.0","ghc-boot-th-9.6.4","ghc-prim-0.10.0","pretty-1.1.3.6"]},{"type":"configured","id":"temporary-1.3-8e8fc8e7de23013c321e5cc7c7df5ece76432805295711c83110e9fdced98b05","pkg-name":"temporary","pkg-version":"1.3","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"3a66c136f700dbf42f3c5000ca93e80b26dead51e54322c83272b236c1ec8ef1","pkg-src-sha256":"8c442993694b5ffca823ce864af95bd2841fb5264ee511c61cf48cc71d879890","depends":["base-4.18.2.0","directory-1.3.8.1","exceptions-0.10.7","filepath-1.4.200.1","random-1.2.1.2-cc746490e13a1f967de173a54c09753b2ccdb5d95056b0f1206a29c62c83de45","transformers-0.6.1.0","unix-2.8.4.0"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"terminal-size-0.3.4-172d551b468144cc78b519639c232b4d8e46869dd22d4d30ed85ae123e1301e8","pkg-name":"terminal-size","pkg-version":"0.3.4","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"f0318c54273d04afb65109683b442792dcb67af1ad01ab5ec64423a28bb97715","pkg-src-sha256":"b0f070d6926cdaacf3a412c5518e5c23afca1e0ed00808a5328c96e468b67f49","depends":["base-4.18.2.0"],"exe-depends":["hsc2hs-0.68.10-e-hsc2hs-3b4e464e6a657183d9f83bd37c6d876421d9f6d00ca34e12b12ca3365e55159d"],"component-name":"lib"},{"type":"pre-existing","id":"text-2.0.2","pkg-name":"text","pkg-version":"2.0.2","depends":["array-0.5.6.0","base-4.18.2.0","binary-0.8.9.1","bytestring-0.11.5.3","deepseq-1.4.8.1","ghc-prim-0.10.0","template-haskell-2.20.0.0"]},{"type":"configured","id":"text-conversions-0.3.1.1-b955b2970b27e7be4b7afdac05f3480d3269bc092ad183c3d72cd22fe91a90cd","pkg-name":"text-conversions","pkg-version":"0.3.1.1","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"35dc3ee494275509a3a771d5d27fc02d4af34478a40126cba87cdc6f007d551e","pkg-src-sha256":"c8770fba789ce80334cae628285103c49abec0fa074773cbb5a88e26f5a7725d","depends":["base-4.18.2.0","base16-bytestring-1.0.2.0-b470eb3428775005093b18dbb34dd687b575cadcc3d709cf63c09611d917e654","base64-bytestring-1.2.1.0-ecb3bf792eac6ec696f20e02e528e8a7b2a76a5b32c46409c4645e1bfbd71cf4","bytestring-0.11.5.3","text-2.0.2"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"text-display-0.0.5.1-ae9f66e9765923d9edec209058cc153706fead0e7c7287c2994a985da1c39623","pkg-name":"text-display","pkg-version":"0.0.5.1","flags":{"book":false},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"da3515adb03b5c01d8e8f0ca81ac0cce4f3ae36f7b74e8566108220a1da670eb","pkg-src-sha256":"1885fc8e32ac66f7396b8356dc216685a43e53693df3979854f4158c3277228f","depends":["base-4.18.2.0","bytestring-0.11.5.3","text-2.0.2"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"text-iso8601-0.1-ca672f6e92319e19ff854d44b5ac9b4e7c827c1996a06b87b8a221dbacac85fb","pkg-name":"text-iso8601","pkg-version":"0.1","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"ac86f2500ca751db3c0de029dd7e7826bef7366d59dc0085b00fc695c43b9f76","pkg-src-sha256":"f58e7a46f951f1f13d2929e0a2f84f6db7894d55a641169aaf300aea9ada5fcf","depends":["base-4.18.2.0","integer-conversion-0.1.0.1-8c064ed0d1fb658105e6fb4ccc9c29b5609d33ee30393dfe431660a716d124d0","text-2.0.2","time-1.12.2","time-compat-1.9.6.1-2b2aa066adc7c0d5baad9d0716626a41574966c2265b4ff355b83a2bfd5ca61a"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"text-manipulate-0.3.1.0-bbaadf2af0a73d136732896cbf24da16ec9680c37b15a75cb7d27e4488f229a7","pkg-name":"text-manipulate","pkg-version":"0.3.1.0","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"aa2b074d0bba21a15e2d4b5b3ff439dea75f3b114b25436b75e615e7cebe9d66","pkg-src-sha256":"9a67efef74bf8a0166436e11bc5b668c10a943c5454fdac3c8de366668a306bc","depends":["base-4.18.2.0","text-2.0.2"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"text-short-0.1.5-e014e79f76c5438274db6ad0455e870f44faf95f73a43bdf4e1c22851755dbaa","pkg-name":"text-short","pkg-version":"0.1.5","flags":{"asserts":false},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"9c73c9c9182ca69ee92ce3758f515b1c078cd167d882ccc8c46f92f68c65e190","pkg-src-sha256":"a35ec6cde2ada084c1a050dc5885be5ab01f851b93d744cf0facbc1c18002dda","depends":["base-4.18.2.0","binary-0.8.9.1","bytestring-0.11.5.3","deepseq-1.4.8.1","ghc-prim-0.10.0","hashable-1.4.3.0-17b447e0ce504d4e093d6bf5a9838da3805c7caa5d16355da40827d004febbc8","template-haskell-2.20.0.0","text-2.0.2"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"tf-random-0.5-d20b981bd0edba50c6bca263adb1566e44b7f7cb2b92de86a3f3b07af9e476eb","pkg-name":"tf-random","pkg-version":"0.5","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"14012837d0f0e18fdbbe3d56e67da8622ee5e20b180abce952dd50bd9f36b326","pkg-src-sha256":"2e30cec027b313c9e1794d326635d8fc5f79b6bf6e7580ab4b00186dadc88510","depends":["base-4.18.2.0","primitive-0.9.0.0-a6aa61bd9fff8d6cfd4880894dd85d8e644fbcf178b2bff38f87569871ea4a0d","random-1.2.1.2-cc746490e13a1f967de173a54c09753b2ccdb5d95056b0f1206a29c62c83de45","time-1.12.2"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"th-abstraction-0.6.0.0-b49a83d27ea2604c7977c309bd302e93941309c5040c248dbdb6b55147976b2b","pkg-name":"th-abstraction","pkg-version":"0.6.0.0","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"d8959fa6a2812afcdd5f6f255fd6be8b3e0ca01e425586a554544fcb70b0ec7c","pkg-src-sha256":"69ea6eca1f0c00b6e1e1f8329c908ec76e73855e2ce6e91ace2f8bbf92c51a30","depends":["base-4.18.2.0","containers-0.6.7","ghc-prim-0.10.0","template-haskell-2.20.0.0"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"th-compat-0.1.4-102530325c2b6ccd251d9c304ca6729eb04836a98ab4cdda25fa565147ccb66e","pkg-name":"th-compat","pkg-version":"0.1.4","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"f5f2c679ecc1c1b83d2d68db6cc564e5c78d53425e69e1b9e36784820e122d37","pkg-src-sha256":"d8f97ac14ab47b6b8a7b0fdb4ff95426322ec56badd01652ac15da4a44d4bab8","depends":["base-4.18.2.0","template-haskell-2.20.0.0"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"th-expand-syns-0.4.11.0-3f181234350a5a4d61570069da1a928aba2739a9b90cb8092c414ac27d235846","pkg-name":"th-expand-syns","pkg-version":"0.4.11.0","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"d1c1d48d5a27e0c52c68ab0d783c649046723b566600e1440f26027eca45e221","pkg-src-sha256":"8acd59ce73078ec6fb39f7555c4bb6cf1e49c256859c30aa8a4fda6d029bf7d0","depends":["base-4.18.2.0","containers-0.6.7","syb-0.7.2.4-80d2f5060ad894d00e83dbe185e57c37c081728996394fa6f5a2fa912bb894f4","template-haskell-2.20.0.0","th-abstraction-0.6.0.0-b49a83d27ea2604c7977c309bd302e93941309c5040c248dbdb6b55147976b2b"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"th-lift-0.8.4-b78b8ae6ed3a29479941c4c76a4210b30bb4ca9e4875ac5a71d61b9bd84dfece","pkg-name":"th-lift","pkg-version":"0.8.4","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"1bb5bab13b61be2bdecf977d5cf274e8ba2ed76b5058a15a021687ebc159b36f","pkg-src-sha256":"f9c577238d4ba65fe3e78bc77f0cca54f17d02c0f6075b2487da5c63bdb4a61b","depends":["base-4.18.2.0","ghc-prim-0.10.0","template-haskell-2.20.0.0","th-abstraction-0.6.0.0-b49a83d27ea2604c7977c309bd302e93941309c5040c248dbdb6b55147976b2b"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"th-orphans-0.13.14-16db0f9bff8b7cf7d9193a41514705710e6bf8cf8d36317661b9cbe3736fdc28","pkg-name":"th-orphans","pkg-version":"0.13.14","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"dcdcebb070b68681de623c74e80450b1aace3a52568bb19abecb6849663c4bce","pkg-src-sha256":"9ddb2a1a0f6afeb8b6697256bfa5930f1f75e99624e370931c4b48bd16c3077c","depends":["base-4.18.2.0","mtl-2.3.1","template-haskell-2.20.0.0","th-compat-0.1.4-102530325c2b6ccd251d9c304ca6729eb04836a98ab4cdda25fa565147ccb66e","th-lift-0.8.4-b78b8ae6ed3a29479941c4c76a4210b30bb4ca9e4875ac5a71d61b9bd84dfece","th-reify-many-0.1.10-05fb0efe7385d7f849bd174d4d29a2933ccfd13505ca108b3b9058761bdaa899"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"th-reify-many-0.1.10-05fb0efe7385d7f849bd174d4d29a2933ccfd13505ca108b3b9058761bdaa899","pkg-name":"th-reify-many","pkg-version":"0.1.10","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"1827dcffb0c9f214e9739053fc808683336ea65c3749ff2d6148db189cbbd2a4","pkg-src-sha256":"9d250e61242f2fb887dedc9d28c0141832ff256e63bebc2bf5abff81037be4a5","depends":["base-4.18.2.0","containers-0.6.7","mtl-2.3.1","safe-0.3.21-31bf385773e1c6ef212139e0505190c20d1e3d1af99bcbfc189c01c3a1e0e739","template-haskell-2.20.0.0","th-expand-syns-0.4.11.0-3f181234350a5a4d61570069da1a928aba2739a9b90cb8092c414ac27d235846"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"these-1.2-a7d4e934136841dac2b8ed0dc77fee3f581d8c4e25fe99bdad5b76406c57bf16","pkg-name":"these","pkg-version":"1.2","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"011e22f6891ca028f87c04ea48796696c92d593313a9c699f7ff4f9ffd7aec6e","pkg-src-sha256":"a8ed7174b7f790764360f48aab72fea382a6093ed369c7bc6881fae1abacd4b8","depends":["assoc-1.1-44564689989a4d2721c54fe7433f3b2450e556c3fe6c52752ad54623647f561c","base-4.18.2.0","binary-0.8.9.1","deepseq-1.4.8.1","hashable-1.4.3.0-17b447e0ce504d4e093d6bf5a9838da3805c7caa5d16355da40827d004febbc8"],"exe-depends":[],"component-name":"lib"},{"type":"pre-existing","id":"time-1.12.2","pkg-name":"time","pkg-version":"1.12.2","depends":["base-4.18.2.0","deepseq-1.4.8.1"]},{"type":"configured","id":"time-compat-1.9.6.1-2b2aa066adc7c0d5baad9d0716626a41574966c2265b4ff355b83a2bfd5ca61a","pkg-name":"time-compat","pkg-version":"1.9.6.1","flags":{"old-locale":false},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"17631ef01a03a6f55fbe131690f87f6dee9a1572acc99b6c06f04882470ffb52","pkg-src-sha256":"ad07bb00eb9678c2136d3680752b00acc4cbc522654bb3199bf31c61ef1e6b80","depends":["base-4.18.2.0","base-orphans-0.9.1-61d128d6a3318593c785a97751f2418cc86b42b03e2b46ed92e9b27fc5da689c","deepseq-1.4.8.1","hashable-1.4.3.0-17b447e0ce504d4e093d6bf5a9838da3805c7caa5d16355da40827d004febbc8","time-1.12.2"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"time-manager-0.0.1-bda26b5ab69166d31b9d00a6f11da4ed98f23c5730095e52dea9d4e88200bb30","pkg-name":"time-manager","pkg-version":"0.0.1","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"4445d343847df0d140972f3d45ca1429d71d186690c2f5fd67a049b4cf66f281","pkg-src-sha256":"07492523fabc69b8ec308f6276cc93df3dd060c91f23df2ac8a1f56d331ea05b","depends":["auto-update-0.1.6-3f7af882e90ee16fd9e6ebf1ca739ba4ad18afcdae045a3375fe3adefea17239","base-4.18.2.0","unliftio-0.2.25.0-494677154ed69a76841d775b50166f52e9d0797a41ece2fd3d94e08aebf372f3"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"timing-convenience-0.1-532d7dc3aaa5fc1300afadca7cc392ec1bf3c6b6c0600c8609536b7b4d87e195","pkg-name":"timing-convenience","pkg-version":"0.1","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"7ff807a9a9e5596f2b18d45c5a01aefb91d4a98f6a1008d183b5c550f68f7cb7","pkg-src-sha256":"72200ea2c942bfb4ac4c5ae53222353ac3af0c40058f4a9179c99df5ff33171d","components":{"lib":{"depends":["base-4.18.2.0","time-1.12.2"],"exe-depends":[]}}},{"type":"configured","id":"tls-2.0.1-b47e0fd7dac1558b195f1752f4ccbcc31081e04ec060bb63474359a715d7657d","pkg-name":"tls","pkg-version":"2.0.1","flags":{"devel":false},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"6f93816f1b67efafe63a91296e047d6218ccdfd355cd17cd47c798871c871444","pkg-src-sha256":"98658cb0394a9cd08c56c5fe11a6c96f16c892a2a594db421cd72e0e7f7be684","depends":["asn1-encoding-0.9.6-9bf64732d7af18045ee22a12f781934262d76015cf823acd133e41c1341a5fb9","asn1-types-0.3.4-09d5674972306ee58c9f15c425744939cc04dad257e3b9dd8f0168fbdc38ab70","async-2.2.4-2107e60f1bee7c70ffed77e551ffc7db01e350edd8784cc9493cc782305122d0","base-4.18.2.0","base16-bytestring-1.0.2.0-b470eb3428775005093b18dbb34dd687b575cadcc3d709cf63c09611d917e654","bytestring-0.11.5.3","cereal-0.5.8.3-930e90604013ce2a32c6d28d3567d1d966e50eb1bf0c18108838f2b4ff0d64ca","crypton-0.34-c8d7db2766b56c26f144f8f589058be74cfcc7e68ff2d08f8f41d2ef1a1fa0e8","crypton-x509-1.7.6-ace8f9d140333c88f85ccfc3589bf27f34ff44a133899eca8703ad0a2550cbd2","crypton-x509-store-1.6.9-a22fb54b4d19ed5d96223b9252ac458efdc316468954bf7427b768e536d62b27","crypton-x509-validation-1.6.12-7d625ee1af564079d6fbb1cad937bb153313fe0a40e0d69ba93055d71efd6686","data-default-class-0.1.2.0-4350681fcf6087f7ee4836ea8af486e6eeb8f64bb56f88dbd081081499b0bef6","memory-0.18.0-273ad672f1703dee0dfe07994633c93d17f815a149738659ef6afa30cbe4f6a8","mtl-2.3.1","network-3.1.4.0-9d41c9df77e8d21da5aaf51c19540d3c0fc11e5e2c2940bea5411915b8a462ff","serialise-0.2.6.1-9a84217bb1945b5559a174f6d6db34ff78ae2ce9f9cba7b4a3abdeedb09747ca","transformers-0.6.1.0","unix-time-0.4.12-45eb997f2b10c03cbe95532ca065341d046b4309aac2f8aad0358668133acf67"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"torsor-0.1.0.1-264ad98156300f7b86fb968625df8515c2fbbce5479b450f036ac11b2f5c7444","pkg-name":"torsor","pkg-version":"0.1.0.1","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"a16c1308705d4cab73dc55b21893e725a4749530bb991ada8a2ffe1eea962346","pkg-src-sha256":"a901845703fe42d0d852ccefb1b7b9210623289203dccd875e0ea70036ed4c52","depends":["base-4.18.2.0"],"exe-depends":[],"component-name":"lib"},{"type":"pre-existing","id":"transformers-0.6.1.0","pkg-name":"transformers","pkg-version":"0.6.1.0","depends":["base-4.18.2.0"]},{"type":"configured","id":"transformers-base-0.4.6-91c64a4b19c3f5f9f196345e9032803d52322bd0857ba94ea6c4260a27a2ff07","pkg-name":"transformers-base","pkg-version":"0.4.6","flags":{"orphaninstances":true},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"6f18f320e371c8954c4b6b211e2fdd5d15a6d6310bd605b9d640f47ede408961","pkg-src-sha256":"323bf8689eb691b122661cffa41a25e00fea7a768433fe2dde35d3da7d32cf90","depends":["base-4.18.2.0","base-orphans-0.9.1-61d128d6a3318593c785a97751f2418cc86b42b03e2b46ed92e9b27fc5da689c","stm-2.5.1.0","transformers-0.6.1.0","transformers-compat-0.7.2-15ca92c51f3c4b3e5a349c3cc2a7f406ca01ba50aecd92a631a1c4d508b1230f"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"transformers-compat-0.7.2-15ca92c51f3c4b3e5a349c3cc2a7f406ca01ba50aecd92a631a1c4d508b1230f","pkg-name":"transformers-compat","pkg-version":"0.7.2","flags":{"five":false,"five-three":true,"four":false,"generic-deriving":true,"mtl":true,"three":false,"two":false},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"044fb9955f63ee138fcebedfdcbe54afe741f2d5892a2d0bdf3a8052bd342643","pkg-src-sha256":"b62c7304c9f3cbc9463d0739aa85cb9489f217ea092b9d625d417514fbcc9d6a","depends":["base-4.18.2.0","ghc-prim-0.10.0","transformers-0.6.1.0"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"tuples-0.1.0.0-c9da1e31c493a9db3a026d6ed37a9f2e238abe29b118611180b8b3b5a28d1337","pkg-name":"tuples","pkg-version":"0.1.0.0","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"0b3f3fe4f65b976e6e449eea77686e9407033f69bba1418a09c6babe3571a821","pkg-src-sha256":"2590bb956598066fb5182d820827de0040f7e43d558bcbea6c35b5830115014f","depends":["base-4.18.2.0","primitive-0.9.0.0-a6aa61bd9fff8d6cfd4880894dd85d8e644fbcf178b2bff38f87569871ea4a0d"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"type-equality-1-0b6d3f1475843f8a2ec92f8308f7e4e437169ac42b8e9e6533f304adcd6f533e","pkg-name":"type-equality","pkg-version":"1","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"ebf53eaf3881b946d4ab56112a19f8b635c0f19cb5252c08fbf2588bc1ea22a5","pkg-src-sha256":"4728b502a211454ef682a10d7a3e817c22d06ba509df114bb267ef9d43a08ce8","depends":["base-4.18.2.0"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"typed-process-0.2.11.1-4907353577cf7b0488b9e45d5074486e7c2bbc62c713aeaa26212d7c9d609d10","pkg-name":"typed-process","pkg-version":"0.2.11.1","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"79e8555666f27a3e4e67fedf430000631d95c937147190b3f10817daca1874b0","pkg-src-sha256":"d5c5dda091d61bac35de4ed6d9ddb530e4eb2564ca3c0b93e577762b63d94148","depends":["async-2.2.4-2107e60f1bee7c70ffed77e551ffc7db01e350edd8784cc9493cc782305122d0","base-4.18.2.0","bytestring-0.11.5.3","process-1.6.17.0","stm-2.5.1.0","transformers-0.6.1.0","unliftio-core-0.2.1.0-1e6dce1dfe73ef335e0615b0af7f06b171c3572cf7a04fe671b6cec407b73dee"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"unicode-data-0.4.0.1-2cec5f4ee6f7dac835f9656497f58d5132b6da46ac07f33c15ef93dbfe67a942","pkg-name":"unicode-data","pkg-version":"0.4.0.1","flags":{"ucd2haskell":false},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"5edc785e09ba1c8ded8262f35187e8d7bfa5fa8bf9f8e3911cd3003314d7f3ec","pkg-src-sha256":"37a5dea6801940beb65c4ac4b9d0f7e653a686cf773507f0ca61c210e0b06080","depends":["base-4.18.2.0"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"unicode-transforms-0.4.0.1-8c67b0eaf2d5104e81ffbe7caf4900a211ea1e275b21ae6aca8253bd0b8d074b","pkg-name":"unicode-transforms","pkg-version":"0.4.0.1","flags":{"bench-show":false,"dev":false,"has-icu":false,"has-llvm":false,"use-gauge":false},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"49bc0f4a277e7a83de66d6584dddd6c3cdf96f11daf5e15ae78d0bbd7ca2a699","pkg-src-sha256":"3278e1e1d648da4bcd7368658ae091a89080e88a2f44db9df5136711e99649fc","depends":["base-4.18.2.0","bytestring-0.11.5.3","ghc-prim-0.10.0","text-2.0.2","unicode-data-0.4.0.1-2cec5f4ee6f7dac835f9656497f58d5132b6da46ac07f33c15ef93dbfe67a942"],"exe-depends":[],"component-name":"lib"},{"type":"pre-existing","id":"unix-2.8.4.0","pkg-name":"unix","pkg-version":"2.8.4.0","depends":["base-4.18.2.0","bytestring-0.11.5.3","filepath-1.4.200.1","time-1.12.2"]},{"type":"configured","id":"unix-compat-0.7.1-d99eb5acf38b31b458b2a5f48db2ff44a4954123ddfa4c9c3d585ea4ef03206d","pkg-name":"unix-compat","pkg-version":"0.7.1","flags":{"old-time":false},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"bd5bb4e04b2ed707f3e3466470a452354310389506cf0a7a73bf10e4d533f6d1","pkg-src-sha256":"c04806e8835ac261de6c9b1bbf886dfc1ea3ab38e0b12581f9d2bff18803e33f","depends":["base-4.18.2.0","unix-2.8.4.0"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"unix-time-0.4.12-45eb997f2b10c03cbe95532ca065341d046b4309aac2f8aad0358668133acf67","pkg-name":"unix-time","pkg-version":"0.4.12","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"97abf524e631f9a6fba975c67b4f34f6ba678986c620e1efcef41ded4af58916","pkg-src-sha256":"50a57298e5cba81e9db2be9f4c24c7e514af96e541a97df05a5ecd411aaf97e2","components":{"lib":{"depends":["base-4.18.2.0","binary-0.8.9.1","bytestring-0.11.5.3","old-time-1.1.0.4-41f5636c376ef03b6ed0709860b733d4263cbb5dd153bb15926d2e3fb2df8cee"],"exe-depends":["hsc2hs-0.68.10-e-hsc2hs-3b4e464e6a657183d9f83bd37c6d876421d9f6d00ca34e12b12ca3365e55159d"]}}},{"type":"configured","id":"unlifted-0.2.2.0-331af0eb9d6315f1de30144f92ea1bd99f7de6c15dd09cf6c2850c461258375e","pkg-name":"unlifted","pkg-version":"0.2.2.0","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"9c7711677e2acb7d27b688a6c5d9d72aab8839d30bad2ecd822a900f10be9e3b","pkg-src-sha256":"7d92ea399142e4c19c05614c1839c780fe99cd8c1a9d7680eda01f25a7a7f01a","depends":["base-4.18.2.0","bytestring-0.11.5.3","text-short-0.1.5-e014e79f76c5438274db6ad0455e870f44faf95f73a43bdf4e1c22851755dbaa"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"unliftio-0.2.25.0-494677154ed69a76841d775b50166f52e9d0797a41ece2fd3d94e08aebf372f3","pkg-name":"unliftio","pkg-version":"0.2.25.0","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"d015242554890370bcbc3a575019be691d0edc279736ef97d29412fb9d0c4349","pkg-src-sha256":"fb85a22291e78f9e58cd7f5e563a726500ad1a004b3b335b93c0975b828a112b","depends":["async-2.2.4-2107e60f1bee7c70ffed77e551ffc7db01e350edd8784cc9493cc782305122d0","base-4.18.2.0","bytestring-0.11.5.3","deepseq-1.4.8.1","directory-1.3.8.1","filepath-1.4.200.1","process-1.6.17.0","safe-exceptions-0.1.7.4-51b8325bd2c9c2c32246cef5b80f09fba6aa9b6005978a7b87ef943c7ddd1182","stm-2.5.1.0","time-1.12.2","transformers-0.6.1.0","unix-2.8.4.0","unliftio-core-0.2.1.0-1e6dce1dfe73ef335e0615b0af7f06b171c3572cf7a04fe671b6cec407b73dee"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"unliftio-core-0.2.1.0-1e6dce1dfe73ef335e0615b0af7f06b171c3572cf7a04fe671b6cec407b73dee","pkg-name":"unliftio-core","pkg-version":"0.2.1.0","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"28800633b20e0f7bfbdda1248c28022749aa0935aea10b1e3fc9c88cbebb06de","pkg-src-sha256":"99384cba8d56d9d61b85e38a313a93ebcdb78be6566367f0930ef580597fe3e3","depends":["base-4.18.2.0","transformers-0.6.1.0"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"unordered-containers-0.2.20-013ecc3e94c07bd5bdb23da8c9cf4d68ac66e04c4144b4096b291104672db345","pkg-name":"unordered-containers","pkg-version":"0.2.20","flags":{"debug":false},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"746c32b23f93cb13e52309e54e82d69e4315105f9815b1fcac25a57071505cff","pkg-src-sha256":"d9cfb287cf00592d39dc9c3cac8b99627ea08f2c01798e70130fc39f7c90f11d","depends":["base-4.18.2.0","deepseq-1.4.8.1","hashable-1.4.3.0-17b447e0ce504d4e093d6bf5a9838da3805c7caa5d16355da40827d004febbc8","template-haskell-2.20.0.0"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"utf8-string-1.0.2-5e8d116496349c38d20293f85d47a22c703548b74e7d267d8d6d20ff907c03cd","pkg-name":"utf8-string","pkg-version":"1.0.2","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"79416292186feeaf1f60e49ac5a1ffae9bf1b120e040a74bf0e81ca7f1d31d3f","pkg-src-sha256":"ee48deada7600370728c4156cb002441de770d0121ae33a68139a9ed9c19b09a","depends":["base-4.18.2.0","bytestring-0.11.5.3"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"uuid-1.3.15-413cef239f477249b51ed712d27bea33e15b08237221be1f41f0bc89ce5e1463","pkg-name":"uuid","pkg-version":"1.3.15","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"7d553f95a750502228fc8411a5ad7e672d9b95272e3a61e5c711f19a49143821","pkg-src-sha256":"f885958d8934930b7c0f9b91f980722f7f992c9383fc98f075cf9df64c800564","depends":["base-4.18.2.0","binary-0.8.9.1","bytestring-0.11.5.3","cryptohash-md5-0.11.101.0-3dd4c39d92ff47630ac61716ac3e4f1bd76b570bf3eb70cf3c6a25610e31a06c","cryptohash-sha1-0.11.101.0-a3ef13c78463fdd04d9d6245ad7391e038dbf79d9c19ec5ab64f9b19a6fb91a8","entropy-0.4.1.10-8c6fb48b38b19d07f9b370b6707c9d29f3ebf9f4746fb1c84bdfc52bb55247e8","network-info-0.2.1-cbd12ac17ed981e872c92e3a8fd70b4ca80c64afdcc8cd7ebfd75eaa846f81c9","random-1.2.1.2-cc746490e13a1f967de173a54c09753b2ccdb5d95056b0f1206a29c62c83de45","text-2.0.2","time-1.12.2","uuid-types-1.0.5.1-c19e00cab51fb72d8874dd99ac787f44fda9996af8117c2d227cfb3294e06a9c"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"uuid-types-1.0.5.1-c19e00cab51fb72d8874dd99ac787f44fda9996af8117c2d227cfb3294e06a9c","pkg-name":"uuid-types","pkg-version":"1.0.5.1","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"918c8a115a0bc427cdaa4d1f51c1634bf3ac53679d0bbe039b77b9c1b62cfcbd","pkg-src-sha256":"0bec6d6982b3c92bfa5eab1d213be2d4b6696b9a2c3a1f1f05812dc3762dca2c","depends":["base-4.18.2.0","binary-0.8.9.1","bytestring-0.11.5.3","deepseq-1.4.8.1","hashable-1.4.3.0-17b447e0ce504d4e093d6bf5a9838da3805c7caa5d16355da40827d004febbc8","random-1.2.1.2-cc746490e13a1f967de173a54c09753b2ccdb5d95056b0f1206a29c62c83de45","template-haskell-2.20.0.0","text-2.0.2"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"vault-0.3.1.5-20d43e8d257de908486713884f035343ca6659f91d72e14d1c91b355c58e3031","pkg-name":"vault","pkg-version":"0.3.1.5","flags":{"useghc":true},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"a3096e7709951eed5e3891ad92f6c3f960438a0f80028cbf755d65d720928682","pkg-src-sha256":"ac2a6b6adf58598c5c8faa931ae961a8a2aa50ddb2f0f7a2044ff6e8c3d433a0","depends":["base-4.18.2.0","containers-0.6.7","hashable-1.4.3.0-17b447e0ce504d4e093d6bf5a9838da3805c7caa5d16355da40827d004febbc8","unordered-containers-0.2.20-013ecc3e94c07bd5bdb23da8c9cf4d68ac66e04c4144b4096b291104672db345"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"vector-0.13.1.0-eb53bdac16f057ad838f4e8cb865b51b400abac71a36dc5bfde93ea1d0859eae","pkg-name":"vector","pkg-version":"0.13.1.0","flags":{"boundschecks":true,"internalchecks":false,"unsafechecks":false,"wall":false},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"4650d28eb918812a3158130f833b5ff5020259b28a8f9ee5d28701ce60cf8a16","pkg-src-sha256":"63f272279eab8ab9411a0fffb1252ac309b297313f8e33be9ebbc2f981edecee","depends":["base-4.18.2.0","deepseq-1.4.8.1","primitive-0.9.0.0-a6aa61bd9fff8d6cfd4880894dd85d8e644fbcf178b2bff38f87569871ea4a0d","vector-stream-0.1.0.1-3c90690d1f553232c8d2479a7997ff1cd5a15df3f660a90ce0ab774b7b6aee75"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"vector-algorithms-0.9.0.1-0d5de6c527fb6ba0e7be854c1685b82a6a99d5798a407e65dc55cac4091e272a","pkg-name":"vector-algorithms","pkg-version":"0.9.0.1","flags":{"bench":true,"boundschecks":true,"internalchecks":false,"llvm":false,"properties":true,"unsafechecks":false},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"222b01a4c0b9e13d73d04fba7c65930df16d1647acc07d84c47ef0356fa33dba","pkg-src-sha256":"2ba7c0d3a8f26ef3ada24ff4abe81609225ecbab3b5754f048f8a0a3ecc33841","depends":["base-4.18.2.0","bitvec-1.1.5.0-134351d7461857a38c09b3cd302761a8b59d5482f7705b4680a47926f8628740","bytestring-0.11.5.3","primitive-0.9.0.0-a6aa61bd9fff8d6cfd4880894dd85d8e644fbcf178b2bff38f87569871ea4a0d","vector-0.13.1.0-eb53bdac16f057ad838f4e8cb865b51b400abac71a36dc5bfde93ea1d0859eae"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"vector-stream-0.1.0.1-3c90690d1f553232c8d2479a7997ff1cd5a15df3f660a90ce0ab774b7b6aee75","pkg-name":"vector-stream","pkg-version":"0.1.0.1","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"be36ab2bee3ec5b7bccc92af5ce27ddd07b7e630cd6bd912344413329ea1652c","pkg-src-sha256":"d0f507334bdea5431a2f07f525a97f29e76522c32210f5de6d5a2b4f1d42bf7c","depends":["base-4.18.2.0","ghc-prim-0.10.0"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"void-0.7.3-0dce7608060d286489a924498d4580dafe61112f075ee061dc6545c66ff6e691","pkg-name":"void","pkg-version":"0.7.3","flags":{"safe":false},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"13d30f62fcdf065e595d679d4ac8b4b0c1bb1a1b73db7b5b5a8f857cb5c8a546","pkg-src-sha256":"53af758ddc37dc63981671e503438d02c6f64a2d8744e9bec557a894431f7317","depends":["base-4.18.2.0"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"wai-3.2.4-acf062ae483a435740bc88b21ee81f62d3f94a62faea15a5bf17463ace439645","pkg-name":"wai","pkg-version":"3.2.4","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"e14fde953183f9db8c10da79b44a2b24d241c1203426c5636995069e2dacb1fe","pkg-src-sha256":"a6088f847d886d7c767092d170c03c7690d197eb3189d7cc67dbaaab33bf6d94","depends":["base-4.18.2.0","bytestring-0.11.5.3","http-types-0.12.4-0f52a9ec33f3c65ef0b77ad8ce14b65f9164f8a761e42800dc9c80ee1768aacc","network-3.1.4.0-9d41c9df77e8d21da5aaf51c19540d3c0fc11e5e2c2940bea5411915b8a462ff","text-2.0.2","vault-0.3.1.5-20d43e8d257de908486713884f035343ca6659f91d72e14d1c91b355c58e3031"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"wai-app-static-3.1.8-d2d0c9be3a5bd2980a68b3225b620c023885a62d44f09cee23e1325fcbe6c50c","pkg-name":"wai-app-static","pkg-version":"3.1.8","flags":{"crypton":true,"print":false},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"22c5b1e83e8f14c6639bf1d0ddca02a6710b74492f7c70f16e058ca7db0a5bc9","pkg-src-sha256":"1a7081096bd425533d87fc40eca7a0f3ed3e3eb08c3a7ef93eecc6f1cf012f02","depends":["base-4.18.2.0","blaze-html-0.9.1.2-3a4f994094b15669094f06ad98d568adb79b03a7829eff4349476c2fafb25845","blaze-markup-0.8.3.0-2e784e1507a2d7d5a307522e712dffb50117e7a08a6219ee2f5a0daa30ff9ab0","bytestring-0.11.5.3","containers-0.6.7","crypton-0.34-c8d7db2766b56c26f144f8f589058be74cfcc7e68ff2d08f8f41d2ef1a1fa0e8","directory-1.3.8.1","file-embed-0.0.16.0-d63ac8c371cd44fa36b87af3f4672e6a9da8a4dd85e53dc2781049b6fa1aeeda","filepath-1.4.200.1","http-date-0.0.11-4d5bd8aa95bbcd52e33572812314a340168d474209374f7c85b86a113b02b6f3","http-types-0.12.4-0f52a9ec33f3c65ef0b77ad8ce14b65f9164f8a761e42800dc9c80ee1768aacc","memory-0.18.0-273ad672f1703dee0dfe07994633c93d17f815a149738659ef6afa30cbe4f6a8","mime-types-0.1.2.0-3d20aa710271c28a90c1e88feb88ab239804502c494312d5102d19e4b368709f","old-locale-1.0.0.7-682418540979bf75be932863a87a0db4ab12d3f7ec5faaeba30e4175347cd126","optparse-applicative-0.18.1.0-1de8f12cfc2915bc6d323ba97415a7e0795036a6b613e7301735aedf9d0425be","template-haskell-2.20.0.0","text-2.0.2","time-1.12.2","transformers-0.6.1.0","unix-compat-0.7.1-d99eb5acf38b31b458b2a5f48db2ff44a4954123ddfa4c9c3d585ea4ef03206d","unordered-containers-0.2.20-013ecc3e94c07bd5bdb23da8c9cf4d68ac66e04c4144b4096b291104672db345","wai-3.2.4-acf062ae483a435740bc88b21ee81f62d3f94a62faea15a5bf17463ace439645","wai-extra-3.1.14-cd0dcb1edc3ae39df542a453943fecc32333d2e7ec94bbfbe140ffe95cb27e37","warp-3.3.31-3a081a14799ab48e5efe3a315077d1e89ea4da61799497b4990d5fc7e0dcb380","zlib-0.6.3.0-61cb40f46d103a622525dc3a70a9004984ec56d61deea65d2dc01c964606b7e9"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"wai-app-static-3.1.8-e-warp-0ca15beb0733735df77c986700e682b297230e1049c5c4c674df8d2591f7ad52","pkg-name":"wai-app-static","pkg-version":"3.1.8","flags":{"crypton":true,"print":false},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"22c5b1e83e8f14c6639bf1d0ddca02a6710b74492f7c70f16e058ca7db0a5bc9","pkg-src-sha256":"1a7081096bd425533d87fc40eca7a0f3ed3e3eb08c3a7ef93eecc6f1cf012f02","depends":["base-4.18.2.0","wai-app-static-3.1.8-d2d0c9be3a5bd2980a68b3225b620c023885a62d44f09cee23e1325fcbe6c50c"],"exe-depends":[],"component-name":"exe:warp","bin-file":"/home/hecate/Projects/Flora/1-flora-server/_build/cabal-store/ghc-9.6.4/wai-app-static-3.1.8-e-warp-0ca15beb0733735df77c986700e682b297230e1049c5c4c674df8d2591f7ad52/bin/warp"},{"type":"configured","id":"wai-extra-3.1.14-cd0dcb1edc3ae39df542a453943fecc32333d2e7ec94bbfbe140ffe95cb27e37","pkg-name":"wai-extra","pkg-version":"3.1.14","flags":{"build-example":false},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"1b093366842dc0057cebb4a23dbf9a29269321d70fd242c7695ce0bbd80d32fb","pkg-src-sha256":"5704f51b09ce16417f174885b99fd2c24d70e31b653187801716254dcd8f64b5","depends":["HUnit-1.6.2.0-d1570da0a2808fb4ce9b1c3f1e99a0cf4a27d7c4071d9714ae835af7748ace92","aeson-2.2.1.0-2595d249b227784b9febcd5a91568775f66fd262ac45c82c44f7b4a55e9d4c27","ansi-terminal-1.0.2-f2271bf25e5299c165409ab78d5917aeba79c479959932bb5fb284c513226fc0","base-4.18.2.0","base64-bytestring-1.2.1.0-ecb3bf792eac6ec696f20e02e528e8a7b2a76a5b32c46409c4645e1bfbd71cf4","bytestring-0.11.5.3","call-stack-0.4.0-a0fd887e5d06d11a75269d5dfed7da6fe2656edbbd7cc1697fb2a2b8ad4fe392","case-insensitive-1.2.1.0-5255eaf892b10e8489fdad145ca833a10864bd951f3e69d04088fbcadf28ec6d","containers-0.6.7","cookie-0.4.6-0f17f671a430f9d3670a38aa989d096c8a941ff590a1a1a5bc4f595def792f73","data-default-class-0.1.2.0-4350681fcf6087f7ee4836ea8af486e6eeb8f64bb56f88dbd081081499b0bef6","directory-1.3.8.1","fast-logger-3.2.2-f2b66566923a1fa76e5c48eecb73e2ef0a379b38ce325b13b8e81e8022003d26","http-types-0.12.4-0f52a9ec33f3c65ef0b77ad8ce14b65f9164f8a761e42800dc9c80ee1768aacc","iproute-1.7.12-1154efefaf645ab127d46e471b4ebe1968e3b3f8497cc0b74c21385bb289cbb0","network-3.1.4.0-9d41c9df77e8d21da5aaf51c19540d3c0fc11e5e2c2940bea5411915b8a462ff","resourcet-1.3.0-0f210c6e8ffe9f595ad8fd1a6cf6726e42a6695abb7febee22452f40436a2bc5","streaming-commons-0.2.2.6-9fa4239301ef39252b6218423c0a2438611fe43c2ddbebd4f8953d4455c07935","text-2.0.2","time-1.12.2","transformers-0.6.1.0","unix-2.8.4.0","vault-0.3.1.5-20d43e8d257de908486713884f035343ca6659f91d72e14d1c91b355c58e3031","wai-3.2.4-acf062ae483a435740bc88b21ee81f62d3f94a62faea15a5bf17463ace439645","wai-logger-2.4.0-0b88ea4c877c6b91e325a6e5662dda948a3ac06bb58a6408dd648183671b5845","warp-3.3.31-3a081a14799ab48e5efe3a315077d1e89ea4da61799497b4990d5fc7e0dcb380","word8-0.1.3-f7afede617c5019b5fe8b27341f573a6ee2d2232a9ed28ec7e4caca5e3512696"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"wai-log-0.4.0.1-479434afc1461896e7a927d8fb2df0160b14dae19bb9a79688f196ec7d42177b","pkg-name":"wai-log","pkg-version":"0.4.0.1","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"0b4b57ae218cf5ec59523c8cf405802a588d4e299436b5a663a6001ea34bb7e6","pkg-src-sha256":"19d21d688e3093289afd7632d33bfaf27c0ab49e5956f153ad72c81ce85e990a","depends":["aeson-2.2.1.0-2595d249b227784b9febcd5a91568775f66fd262ac45c82c44f7b4a55e9d4c27","base-4.18.2.0","bytestring-0.11.5.3","http-types-0.12.4-0f52a9ec33f3c65ef0b77ad8ce14b65f9164f8a761e42800dc9c80ee1768aacc","log-base-0.12.0.1-f6c93830f52a9d5925fa4be3f430d1262c4e2bbf3222e6a925872b2eec0a9d75","string-conversions-0.4.0.1-84561bf691f05f917e60aa94bd28d55750bb3e08ac9a7bd02c365e1ff133b25f","text-2.0.2","time-1.12.2","uuid-1.3.15-413cef239f477249b51ed712d27bea33e15b08237221be1f41f0bc89ce5e1463","wai-3.2.4-acf062ae483a435740bc88b21ee81f62d3f94a62faea15a5bf17463ace439645"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"wai-logger-2.4.0-0b88ea4c877c6b91e325a6e5662dda948a3ac06bb58a6408dd648183671b5845","pkg-name":"wai-logger","pkg-version":"2.4.0","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"630b3d573dce5c6a84dfb372d69f8d15f9dbb52d6a04df43e57a44f0ca0eab0a","pkg-src-sha256":"057e635acd35a39d6ddae4ba4c5dfa1425e251579bbd3239c7f4b557bc96290a","components":{"lib":{"depends":["base-4.18.2.0","byteorder-1.0.4-fa2515b96f172f97bd2e2638b538e2286cb035eb8b87892a4857a50c6e738631","bytestring-0.11.5.3","fast-logger-3.2.2-f2b66566923a1fa76e5c48eecb73e2ef0a379b38ce325b13b8e81e8022003d26","http-types-0.12.4-0f52a9ec33f3c65ef0b77ad8ce14b65f9164f8a761e42800dc9c80ee1768aacc","network-3.1.4.0-9d41c9df77e8d21da5aaf51c19540d3c0fc11e5e2c2940bea5411915b8a462ff","wai-3.2.4-acf062ae483a435740bc88b21ee81f62d3f94a62faea15a5bf17463ace439645"],"exe-depends":[]},"setup":{"depends":["Cabal-3.10.1.0","base-4.18.2.0","cabal-doctest-1.0.9-4a685fb2745cdab49526ff8fe3801bf6bd4ab5085239033fcfd51613f7e3fd76"],"exe-depends":[]}}},{"type":"configured","id":"wai-middleware-heartbeat-0.0.1.0-de5d48bf3f801ad6a7c2e1238d0d30545239fd081520428e7cfa1d9f6b41c104","pkg-name":"wai-middleware-heartbeat","pkg-version":"0.0.1.0","flags":{},"style":"global","pkg-src":{"type":"source-repo","source-repo":{"type":"git","location":"https://github.com/flora-pm/wai-middleware-heartbeat","tag":"5b56e1d"}},"pkg-src-sha256":"14dc4f4c511394b4ebe8f0d5ceaf3e942998e5606a6e41c8a24f5254c398c723","depends":["base-4.18.2.0","http-types-0.12.4-0f52a9ec33f3c65ef0b77ad8ce14b65f9164f8a761e42800dc9c80ee1768aacc","wai-3.2.4-acf062ae483a435740bc88b21ee81f62d3f94a62faea15a5bf17463ace439645"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"warp-3.3.31-3a081a14799ab48e5efe3a315077d1e89ea4da61799497b4990d5fc7e0dcb380","pkg-name":"warp","pkg-version":"3.3.31","flags":{"allow-sendfilefd":true,"network-bytestring":false,"warp-debug":false,"x509":false},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"b855196d0e6f65c648662647f9c749fbbf193e97d9b0c034429731f9e34c5ddc","pkg-src-sha256":"7ca9c7df2ba44ffe225df63866f32b14b70ea2c045ff9301bac982ce377ec38d","depends":["array-0.5.6.0","auto-update-0.1.6-3f7af882e90ee16fd9e6ebf1ca739ba4ad18afcdae045a3375fe3adefea17239","base-4.18.2.0","bsb-http-chunked-0.0.0.4-f0471e0efa2dd6ebef9e206b6727cf6fe5e8a009c301af9a3b7199515a1e2c08","bytestring-0.11.5.3","case-insensitive-1.2.1.0-5255eaf892b10e8489fdad145ca833a10864bd951f3e69d04088fbcadf28ec6d","containers-0.6.7","ghc-prim-0.10.0","hashable-1.4.3.0-17b447e0ce504d4e093d6bf5a9838da3805c7caa5d16355da40827d004febbc8","http-date-0.0.11-4d5bd8aa95bbcd52e33572812314a340168d474209374f7c85b86a113b02b6f3","http-types-0.12.4-0f52a9ec33f3c65ef0b77ad8ce14b65f9164f8a761e42800dc9c80ee1768aacc","http2-5.0.1-751b9c3f95a93da8cddfb732f2965a32e07b1353df03d60f755b561f5ddd83d2","iproute-1.7.12-1154efefaf645ab127d46e471b4ebe1968e3b3f8497cc0b74c21385bb289cbb0","network-3.1.4.0-9d41c9df77e8d21da5aaf51c19540d3c0fc11e5e2c2940bea5411915b8a462ff","recv-0.1.0-d170336de78e6c12b94f8cc756fe783212924d934de94f3714815c10ebbd9fad","simple-sendfile-0.2.32-40d1e9f7a944730d0ccd2218dd6dd93bb24e35bc984ac0852a20de36b49e40dc","stm-2.5.1.0","streaming-commons-0.2.2.6-9fa4239301ef39252b6218423c0a2438611fe43c2ddbebd4f8953d4455c07935","text-2.0.2","time-manager-0.0.1-bda26b5ab69166d31b9d00a6f11da4ed98f23c5730095e52dea9d4e88200bb30","unix-2.8.4.0","unliftio-0.2.25.0-494677154ed69a76841d775b50166f52e9d0797a41ece2fd3d94e08aebf372f3","vault-0.3.1.5-20d43e8d257de908486713884f035343ca6659f91d72e14d1c91b355c58e3031","wai-3.2.4-acf062ae483a435740bc88b21ee81f62d3f94a62faea15a5bf17463ace439645","word8-0.1.3-f7afede617c5019b5fe8b27341f573a6ee2d2232a9ed28ec7e4caca5e3512696"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"wide-word-0.1.6.0-701ecedac0a6c9b47e334c978d1acbc2be6ad5ec17436c6d5c3ac80532b45795","pkg-name":"wide-word","pkg-version":"0.1.6.0","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"3df0e04e5c18e9540daba074f2a670fa3ee9f145dfaa8df008d318767c6a40dc","pkg-src-sha256":"df6aa01a18d2b191f96793fab1cb4b43d465f8c9ad5239f9df4ca9255b059797","depends":["base-4.18.2.0","binary-0.8.9.1","deepseq-1.4.8.1","ghc-prim-0.10.0","hashable-1.4.3.0-17b447e0ce504d4e093d6bf5a9838da3805c7caa5d16355da40827d004febbc8","primitive-0.9.0.0-a6aa61bd9fff8d6cfd4880894dd85d8e644fbcf178b2bff38f87569871ea4a0d"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"witherable-0.4.2-1767ce3334bad414dff74c30d2272bb1f265e0098708c8aa764f138b1a282619","pkg-name":"witherable","pkg-version":"0.4.2","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"cec516b35df0ff53ab0068e70a912a0ba7b65c672fbc554727183faa195ad3b8","pkg-src-sha256":"790d2bb274283419173bd89104439860675a9410f70f21912973ecd9098b4104","depends":["base-4.18.2.0","base-orphans-0.9.1-61d128d6a3318593c785a97751f2418cc86b42b03e2b46ed92e9b27fc5da689c","containers-0.6.7","hashable-1.4.3.0-17b447e0ce504d4e093d6bf5a9838da3805c7caa5d16355da40827d004febbc8","indexed-traversable-0.1.3-8f7210e35c0cb4bf73ec163bed4014cbba70e17aa189447497a492e60990637b","indexed-traversable-instances-0.1.1.2-23d2e9c28613d77bfd5595533e39512e3e8b808382cee8d422cee021acbf7fc4","transformers-0.6.1.0","unordered-containers-0.2.20-013ecc3e94c07bd5bdb23da8c9cf4d68ac66e04c4144b4096b291104672db345","vector-0.13.1.0-eb53bdac16f057ad838f4e8cb865b51b400abac71a36dc5bfde93ea1d0859eae"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"wl-pprint-annotated-0.1.0.1-2ffc62f3d112419f639c5f9a11a9f5522560693bebb7563fb4d9e6fbf7d077e8","pkg-name":"wl-pprint-annotated","pkg-version":"0.1.0.1","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"79d12e6d7302c8bea0986cb713fcbfc33225cca3ee158ac741cf1a468f5ed8bc","pkg-src-sha256":"6b662b244b2e318a2923dc7057d707369a29ea4a0e721b4710eac7239cc727af","depends":["base-4.18.2.0","containers-0.6.7","deepseq-1.4.8.1","text-2.0.2"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"word8-0.1.3-f7afede617c5019b5fe8b27341f573a6ee2d2232a9ed28ec7e4caca5e3512696","pkg-name":"word8","pkg-version":"0.1.3","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"e5464d0600821a116467d4b12fef12b15ff040c3599500e5f0274225e78c6faf","pkg-src-sha256":"2630934c75728bfbf390c1f0206b225507b354f68d4047b06c018a36823b5d8a","depends":["base-4.18.2.0"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"xml-conduit-1.9.1.3-bf19b431d216b0a2413840aa01a4a651624a00a392ce27bb32e3cbe5522c5d28","pkg-name":"xml-conduit","pkg-version":"1.9.1.3","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"7cbc7829804ce4cd297f3df16bd15e7808c608ae4e0bcc4013e0e456dc4e1ab8","pkg-src-sha256":"d8e9169562c71c9e6bc616f15832f521a68c362aa4fc03682748a809755f1bf4","components":{"lib":{"depends":["attoparsec-0.14.4-5061b5f729de9f72f69961345d54e0249a28df7c232bb9cf2b0525b6f17a253a","base-4.18.2.0","blaze-html-0.9.1.2-3a4f994094b15669094f06ad98d568adb79b03a7829eff4349476c2fafb25845","blaze-markup-0.8.3.0-2e784e1507a2d7d5a307522e712dffb50117e7a08a6219ee2f5a0daa30ff9ab0","bytestring-0.11.5.3","conduit-1.3.5-96fa916ebd7a150aa66076e6ed1e4a9d7982e51658f9fd750ad31ce33c46afd7","conduit-extra-1.3.6-a9b74b7c97cb9e39e8f4262bfd1952b446fe950cb07e127ba073c16301e30755","containers-0.6.7","data-default-class-0.1.2.0-4350681fcf6087f7ee4836ea8af486e6eeb8f64bb56f88dbd081081499b0bef6","deepseq-1.4.8.1","resourcet-1.3.0-0f210c6e8ffe9f595ad8fd1a6cf6726e42a6695abb7febee22452f40436a2bc5","text-2.0.2","transformers-0.6.1.0","xml-types-0.3.8-d2a265fd20021a57d6f815997b9b3d3ac55b25363a4801f11d0a9db2d0cc2488"],"exe-depends":[]},"setup":{"depends":["Cabal-3.10.1.0","base-4.18.2.0","cabal-doctest-1.0.9-4a685fb2745cdab49526ff8fe3801bf6bd4ab5085239033fcfd51613f7e3fd76"],"exe-depends":[]}}},{"type":"configured","id":"xml-conduit-writer-0.1.1.5-af45083ef430fdd7f499ccdbcbffc63138c7fd12623f1529c3a0777b83867c2e","pkg-name":"xml-conduit-writer","pkg-version":"0.1.1.5","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"7b62f92e91d5f7c2c4440b2021d6b9309f9966598b110017b2cbcf3fcd1107df","pkg-src-sha256":"c10527f535e5d3e1fe89bb42a8ad28afb601045e45363a2caa30db398d2a42d5","depends":["base-4.18.2.0","containers-0.6.7","data-default-0.7.1.1-fb1a461d5390de89b4af18b225f51df41ca3a345d820ee4756653e4cd2f3cd8e","dlist-1.0-1ec91dd3ad8405ed390138bce1c7d55220d4758eda9fb3ad6fbb8b1ee6dc0c94","mtl-2.3.1","text-2.0.2","xml-conduit-1.9.1.3-bf19b431d216b0a2413840aa01a4a651624a00a392ce27bb32e3cbe5522c5d28","xml-types-0.3.8-d2a265fd20021a57d6f815997b9b3d3ac55b25363a4801f11d0a9db2d0cc2488"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"xml-types-0.3.8-d2a265fd20021a57d6f815997b9b3d3ac55b25363a4801f11d0a9db2d0cc2488","pkg-name":"xml-types","pkg-version":"0.3.8","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"0d1420f967a5f6439dc03f554b4d77cf15f9ff0aa58fa408efc52ca16459119b","pkg-src-sha256":"dad5e4ce602b7d1f4be37c0cfd99a261a4573746bfd80d917dc955b72da84c80","depends":["base-4.18.2.0","deepseq-1.4.8.1","text-2.0.2"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"zigzag-0.1.0.0-566d257af37db43b1ea7fe61e93ddea5f662ad8c5b1df04c1e845b14b13bcf67","pkg-name":"zigzag","pkg-version":"0.1.0.0","flags":{},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"794afe9e8f7a8abd79d77ae4bb0bb2eeb14b56bc49d2e2cbd8220b6778eecb70","pkg-src-sha256":"f538e7db692aa6c760f092473fa69b416207b9e58c8c640c192b98f6778eafb3","depends":["base-4.18.2.0"],"exe-depends":[],"component-name":"lib"},{"type":"configured","id":"zlib-0.6.3.0-61cb40f46d103a622525dc3a70a9004984ec56d61deea65d2dc01c964606b7e9","pkg-name":"zlib","pkg-version":"0.6.3.0","flags":{"bundled-c-zlib":false,"non-blocking-ffi":false,"pkg-config":false},"style":"global","pkg-src":{"type":"repo-tar","repo":{"type":"secure-repo","uri":"https://hackage.haskell.org/"}},"pkg-cabal-sha256":"19eb7759af71957811d5ec10ddb1e2f4c98700ddb9c0da6860c0441d811f0e6d","pkg-src-sha256":"9eaa989ad4534438b5beb51c1d3a4c8f6a088fdff0b259a5394fbf39aaee04da","depends":["base-4.18.2.0","bytestring-0.11.5.3"],"exe-depends":[],"component-name":"lib"}]} \ No newline at end of file diff --git a/EXAMPLE_ADVISORY.md b/EXAMPLE_ADVISORY.md new file mode 100644 index 00000000..f56c2650 --- /dev/null +++ b/EXAMPLE_ADVISORY.md @@ -0,0 +1,78 @@ +```toml + +[advisory] +# Submit PRs with HSEC-0000-0000, or run `hsec-tools next-id` to +# print the next available ID. +id = "HSEC-0000-0000" +cwe = [] + +# Arbitrary keywords. We recommend to include keywords relating +# to the protocols, data formats or services pertaining to the +# affected package (e.g. "json", "tls", "aws"). You can also +# include keywords describing the vulnerability or impact (e.g. +# "dos", "sqli" "csrf"). Just think, "what keywords would I use +# if I was searching for issues affecting this package, or a +# particular class of vulnerabilities?" +keywords = ["example", "freeform", "keywords"] + +# Corresponding and related advisory IDs. You could include +# CVE, GHSA or other well known databases, as well as other +# HSEC IDs in the `related` field. +aliases = ["CVE-2022-XXXX"] +related = ["CVE-2022-YYYY", "CVE-2022-ZZZZ"] + +# You can declare multiple affected packages +[[affected]] + +# Declare the affected package/component via ONE of the +# following options +# +# OPTION 1: package = hackage-package-name +package = "package-name" +# +# OPTION 2: ghc-component = {ghc,ghci,rts,ghc-pkg,runghc,ghc-iserv,hp2ps,hpc,hsc2hs,haddock} +# ghc-component = "ghci" + +# CVSS vector. Accepted versions: 2.0, 3.0, 3.1 +cvss = "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H" + +# arch = ["x86", "x86_64"] +# os = ["mingw32"] +# declarations = { "Acme.Broken.function" = ">= 1.1.0 && < 1.2.0", "Acme.Broken.renamedFunction" = ">= 1.2.0 && < 1.2.0.5"} + +# Versions affected by the vulnerability. +# +# The `fixed` field is optional. You can specify multiple ranges +# (for example, if the issue was introduced in multiple releases +# series). In the case of multiple ranges, use `fixed` to "close" +# a range, even when the release series does not actually have a +# fix. For example, if an issue was introduced in 1.0.8 and 1.1.2 +# (but 1.1 is unaffected), and a fix has not been released for the +# 1.0.x series, specify: +[[affected.versions]] +introduced = "1.0.8" +fixed = "1.1" +[[affected.versions]] +introduced = "1.1.2" + +# References to articles, issues/PRs, etc. Recognised types: +# ADVISORY, ARTICLE, DETECTION, DISCUSSION, REPORT, +# FIX, INTRODUCED, PACKAGE, EVIDENCE, WEB +[[references]] +type = "ARTICLE" +url = "https://example.com" +``` + +# Advisory Template - Title Goes Here + +This is an example template for an advisory. Please copy this to packages/ and rename it to HSEC-0000-0000.md. + +In this section of the advisory you can write an extended description of the vulnerability. + + * Markdown formatted + * TOML "front matter". See README.md for schema. + * Please include as much detail as you'd like. + +A well structured advisory will include information like: + + > Acme Broken implements safe internal mutation using `unsafePerformIO`. However, in a multithreaded context, an attacker can cause a service to return the wrong answer by forcing an interleaving of writes that violates internal invariants. The flaw was corrected by replacing uses of `IORef` with `MVar` in commit abc123. diff --git a/LICENSE.txt b/LICENSE.txt new file mode 100644 index 00000000..d3fbc786 --- /dev/null +++ b/LICENSE.txt @@ -0,0 +1,18 @@ +All advisories in the HSec advisory database repository is dedicated to +the public domain: + +https://creativecommons.org/publicdomain/zero/1.0/ + +By committing an advisory to this repository, you hereby waive all +rights to the work worldwide under copyright law, including all +related and neighboring rights, to the extent allowed by law. + +You can copy, modify, distribute, and retransmit any security advisory +information in this repository, even for commercial purposes, without +asking permission. + +------------------------------------------------------- + +The code for processing advisories (in the "code" directory) is +licensed separately, under the 3-clause BSD license. See +code/LICENSE.txt for details. diff --git a/Makefile b/Makefile index 6c780276..fd257a15 100644 --- a/Makefile +++ b/Makefile @@ -30,14 +30,14 @@ clean-assets: ## Remove JS artifacts @cd assets/ && rm -R node_modules @cd docs/ && rm -R node_modules +db-setup: db-create db-init db-migrate ## Setup the dev database + db-create: ## Create the database @createdb -h $(FLORA_DB_HOST) -p $(FLORA_DB_PORT) -U $(FLORA_DB_USER) $(FLORA_DB_DATABASE) db-drop: ## Drop the database @dropdb -f --if-exists -h $(FLORA_DB_HOST) -p $(FLORA_DB_PORT) -U $(FLORA_DB_USER) $(FLORA_DB_DATABASE) -db-setup: db-create db-init db-migrate ## Setup the dev database - db-init: ## Create the database schema @migrate init "$(FLORA_DB_CONNSTRING)" @@ -56,10 +56,38 @@ db-provision: ## Create categories and repositories @cabal run -- flora-cli provision-repository --name "horizon" --url https://packages.horizon-haskell.net \ --description "Packages of the Horizon project" -db-provision-test-packages: ## Load development data in the database +db-provision-advisories: ## Load HSEC advisories in the database + @cabal run -- flora-cli provision advisories + +db-provision-packages: ## Load development data in the dev database @cabal run -- flora-cli provision test-packages --repository "hackage" @cabal run -- flora-cli provision test-packages --repository "cardano" +db-test-create: ## Create the test database + ./scripts/run-with-test-config.sh db-create + +db-test-setup: db-test-create db-test-init db-test-migrate ## Setup the dev database + +db-test-drop: ## Drop the test database + ./scripts/run-with-test-config.sh db-drop + +db-test-init: ## Create the test database schema + ./scripts/run-with-test-config.sh db-init + +db-test-migrate: ## Apply test database migrations + ./scripts/run-with-test-config.sh db-migrate + +db-test-reset: db-test-drop db-test-setup db-test-provision ## Reset the test database + +db-test-provision: ## Create categories and repositories + ./scripts/run-with-test-config.sh db-provision + +db-test-provision-advisories: ## Load HSEC advisories in the test database + ./scripts/run-with-test-config.sh db-provision-advisories + +db-test-provision-packages: ## Load development data in the database + ./scripts/run-with-test-config.sh db-provision-packages + import-from-hackage: ## Imports every cabal file from the ./index-01 directory @cabal run -- flora-cli import-packages ./01-index @@ -125,9 +153,20 @@ tags: ## Generate ctags for the project with `ghc-tags` design-system: ## Generate the HTML components used by the design system @cabal run -- flora-cli gen-design-system + start-design-sysytem: ## Start storybook.js @cd design; yarn storybook +migration: ## Generate timestamped database migration boilerplate files + @if test -z "$$name"; then \ + echo "Usage: make migration name=some-name"; \ + else \ + migName="`date -u '+%Y%m%d%H%M%S'`_$$name"; \ + fname="migrations/$$migName.sql"; \ + touch "$$fname"; \ + echo "Touched $$fname";\ + fi + help: @grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.* ?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}' @@ -144,14 +183,3 @@ endif .PHONY: all $(MAKECMDGOALS) .DEFAULT_GOAL := help - -.PHONY: migration -migration: ## Generate timestamped database migration boilerplate files - @if test -z "$$name"; then \ - echo "Usage: make migration name=some-name"; \ - else \ - migName="`date -u '+%Y%m%d%H%M%S'`_$$name"; \ - fname="migrations/$$migName.sql"; \ - touch "$$fname"; \ - echo "Touched $$fname";\ - fi diff --git a/PROCESS.md b/PROCESS.md new file mode 100644 index 00000000..39798dc0 --- /dev/null +++ b/PROCESS.md @@ -0,0 +1,213 @@ +# Haskell Security Response Team Process + +> Copyright 2017, OpenStack Vulnerability Management Team +> Copyright 2023, Haskell Security Response Team +> This work is licensed under a Creative Commons Attribution 3.0 Unported License. +> http://creativecommons.org/licenses/by/3.0/legalcode +> Original version: https://opendev.org/openstack/ossa/src/branch/master/doc/source/vmt-process.rst + +The HSRT coordinates responsible disclosure of security vulnerabilities in +the Haskell ecosystem and help Haskell users have an accurate and timely +assessment of risks. + +Members of the team are independent and security-minded folks who ensure +that vulnerabilities are dealt with in a timely manner and that +downstream stakeholders are notified in a coordinated and fair manner. +Where a member of the team is employed by a downstream stakeholder, the +member does not give their employer prior notice of any vulnerabilities. +In order to reduce the disclosure of vulnerability in the early stages, +membership of this team is intentionally limited to a small number of +people. + +## Process + +Each security bug is assigned a HSRT *coordinator* (member from the +haskell security response team) that will coordinate the +disclosure process. Here are the steps we follow. + +### Reception + +High-impact vulnerabilities can be reported privately to +[security-advisories@haskell.org](mailto:security-advisories@haskell.org). +We do not use PGP. Alternatively, Haskell vulnerabilities can be +reported via the CERT/CC [VINCE] system. Use "Haskell Programming +Language" as the vendor name. + +[VINCE]: https://kb.cert.org/vince/ + +As a volunteer effort with limited resources, we coordinate security +response for embargoed vulnerabilities for high impact issues only. +Factors that influence whether we will deal with an issue under +embargo or not include: + +- How severe is the vulnerability? +- How widely used is the library or tool in which the issue occurs? +- Does the issue also affect other ecosystems, or is there already a + security response underway? (We will not break someone else's + embargo.) + +Public reports can be submitted as a [regular issue or PR on the security-advisories repo](https://github.com/haskell/security-advisories/issues). +In that case, please follow the process defined in +the [Reporting Vulnerabilities](./CONTRIBUTING.md) document. + +The first steps performed by the HSRT are to: + +- check that the report indicates the correct project and adjust as + necessary. +- contact the project's maintainer for confirmation + of impact and determination of affected version. + +### Draft advisory + +In the mean time, the HSRT coordinator works with the reporter to +to refine their draft security advisory using the template defined +in the [Reporting Vulnerabilities](./CONTRIBUTING.md) document. + +### Review advisory + +The advisory is validated by the reporter and the project's maintainer. + +### Vulnerability disclosure + +Once the patches are approved, a signed email +with the vulnerability description is sent to the downstream +stakeholders. The notice will state the planned disclosure date. +No stakeholder is supposed to deploy public patches before +disclosure date. + +### Open bug, Push patch + +In preparation for this, make sure you have a maintainer available to +help pushing the fix at disclosure time. + +On the disclosure hour, open bug, push patches for review and +fast-track approvals (referencing the bug). + +If a CVE got assigned when the report is still private, +[MITRE's CVE Request form](https://cveform.mitre.org/) should be used +again at this point, but instead select a *request type* of +`Notify CVE about a publication` and fill in the coordinator's *e-mail +address*, provide a *link to the advisory*, the *CVE IDs* covered, and +the *date published*. Once more, fill in the +*security code* at the bottom of the page and *submit request*. + +### Publish HSEC + +Shortly after pushing the patches (potentially waiting for the first +test runs to complete), publish the advisory to the repository. + +### All patches merged + +Patches approved in code review do not necessarily merge immediately, +but should be tracked closely until they do. + +### Abnormal termination + +If a report is held in private for 90 days without a fix, or significant +details of the report are disclosed in a public venue, the report is +terminated by a HSRT coordinator at that time and subsequent process +switches to the public report workflow instead. + +## Extent of Disclosure + +The science of vulnerability management is somewhere around being able +to assess impact and severity of a report, being able to design security +patches, being an obsessive process-following perfectionist and +respecting the rule of lesser disclosure. + +Lesser disclosure is about disclosing the vulnerability details to an +increasing number of people over time, but only to the people that are +necessary to reach the next step. + +Vulnerability reporters retain final control over the disclosure of +their findings. If for some reason they are uncomfortable with our +process, their choice of disclosure terms prevails. + +### Downstream stakeholders + +Haskell packages are used in a number of distributions, +products, private and public service offerings that are negatively +affected by vulnerabilities. In the spirit of responsible disclosure, +this ecosystem, collectively known as the downstream stakeholders, needs +to be warned in advance to be able to prepare patches and roll them out +in a coordinated fashion on disclosure day. The disclosure period is kept +voluntarily small (3-5 business days), as a middle ground between +keeping the vulnerability under cover for too long and not giving a +chance to downstream stakeholders to react. + +If you're currently not a referenced stakeholder and think you should +definitely be included on that email distribution list, please submit an +email with a rationale to member(s) of the HSRT. + +Currently, we use the following private email lists for responsible +disclosures: + +- [security@archlinux.org](mailto:security@archlinux.org) +- [security@debian.org](mailto:security@debian.org) +- [security@ubuntu.org](mailto:security@ubuntu.org) +- [security@lists.fedoraproject.org](mailto:security@lists.fedoraproject.org) +- [secalert@redhat.com](mailto:secalert@redhat.com) + +We also have a few personal emails for interested parties which are not +published in the repository, for privacy/anti-spam reasons. If you want your +email to be included here, please send us a PR. + +## Templates + +### Reception reminder (private issues) + + This issue is being treated as a potential security risk. + Please do not make any public mention of private + security vulnerabilities before their coordinated + publication by the Haskell Security Response Team in the + form of an official Haskell Security Advisory (HSEC). This includes + discussion of the bug or associated fixes in public forums such as + mailing lists, code review systems and bug trackers. Please also + avoid private disclosure to other individuals not already approved + for access to this information, and provide this same reminder to + those who are made aware of the issue prior to publication. All + discussion should remain confined to this private bug report, and + any proposed fixes should be added to the bug as attachments. This + status shall not extend past $NINETY_DAYS and will be made + public by or on that date even if no fix is identified. + +The NINETY_DAYS value should be 90 days from the date the report is +accepted by the coordinator and project reviewers are subscribed. It can +be trivially calculated with the `date -I -d90days` shell command. + +### Downstream stakeholders notification email (private issues) + +- *To:* TBD +- *Subject:* [pre-HSEC] Vulnerability in Haskell $PROJECT ($CVE) + +The message body for both emails should be identical: : + + This is an advance warning of a vulnerability discovered in + Haskell $PROJECT, to give you, as downstream stakeholders, a chance to + coordinate the release of fixes and reduce the vulnerability window. + Please treat the following information as confidential until the + proposed public disclosure date. + + $ADVISORY + + See attached patches. Unless a flaw is discovered in them, these + patches will be merged to their corresponding branches on the public + disclosure date. + + Proposed public disclosure date/time: + $DISCLOSURE, 1500UTC + Please do not make the issue public (or release public patches) + before this coordinated disclosure date. + + -- + $HSRT_COORDINATOR_NAME + Haskell Security Response Team + +Proposed patches are attached, email must be GPG-signed. Use something +unique and descriptive for the patch attachment file names, for example +`cve-2013-4183-$project.patch` or +`cve-2013-4183-$project-stable-1.0.patch`. + +### Haskell security advisories (HSEC) + +Refers to the [./EXAMPLE_ADVISORY.md](./EXAMPLE_ADVISORY.md). diff --git a/README.md b/README.md index 94c2cf8d..253ae23e 100644 --- a/README.md +++ b/README.md @@ -49,7 +49,7 @@ * 🌓 Dark and light modes * 📱 Mobile user interface -## 📖 Guides +## 📖 Guides Visit https://flora.pm/documentation for explanations on what Flora can do. @@ -66,4 +66,4 @@ To setup a local installation, see [CONTRIBUTING.md#project-setup](https://githu ## 🫶 Special Collaborations -We would like to thank our dear friends at Guérilla Studio ([www](https://guerilla.studio/), [GitHub](https://github.com/GuerillaStudio)) for help with accessibility and CSS integration. +We would like to thank our dear friends at Guérilla.Studio ([www](https://guerilla.studio/), [GitHub](https://github.com/GuerillaStudio)) for help with accessibility and CSS integration. diff --git a/test/fixtures/Advisories/advisories/reserved/.gitkeep b/advisories/.gitkeep similarity index 100% rename from test/fixtures/Advisories/advisories/reserved/.gitkeep rename to advisories/.gitkeep diff --git a/test/fixtures/Advisories/advisories/hackage/aeson/HSEC-2023-0001.md b/advisories/hackage/aeson/HSEC-2023-0001.md similarity index 100% rename from test/fixtures/Advisories/advisories/hackage/aeson/HSEC-2023-0001.md rename to advisories/hackage/aeson/HSEC-2023-0001.md diff --git a/test/fixtures/Advisories/advisories/hackage/base/HSEC-2023-0007.md b/advisories/hackage/base/HSEC-2023-0007.md similarity index 100% rename from test/fixtures/Advisories/advisories/hackage/base/HSEC-2023-0007.md rename to advisories/hackage/base/HSEC-2023-0007.md diff --git a/test/fixtures/Advisories/advisories/hackage/biscuit-haskell/HSEC-2023-0002.md b/advisories/hackage/biscuit-haskell/HSEC-2023-0002.md similarity index 100% rename from test/fixtures/Advisories/advisories/hackage/biscuit-haskell/HSEC-2023-0002.md rename to advisories/hackage/biscuit-haskell/HSEC-2023-0002.md diff --git a/test/fixtures/Advisories/advisories/hackage/biscuit-haskell/HSEC-2024-0009.md b/advisories/hackage/biscuit-haskell/HSEC-2024-0009.md similarity index 100% rename from test/fixtures/Advisories/advisories/hackage/biscuit-haskell/HSEC-2024-0009.md rename to advisories/hackage/biscuit-haskell/HSEC-2024-0009.md diff --git a/advisories/hackage/bz2/HSEC-2024-0002.md b/advisories/hackage/bz2/HSEC-2024-0002.md new file mode 120000 index 00000000..cb2989c5 --- /dev/null +++ b/advisories/hackage/bz2/HSEC-2024-0002.md @@ -0,0 +1 @@ +../bzlib/HSEC-2024-0002.md \ No newline at end of file diff --git a/advisories/hackage/bzlib-conduit/HSEC-2024-0002.md b/advisories/hackage/bzlib-conduit/HSEC-2024-0002.md new file mode 120000 index 00000000..cb2989c5 --- /dev/null +++ b/advisories/hackage/bzlib-conduit/HSEC-2024-0002.md @@ -0,0 +1 @@ +../bzlib/HSEC-2024-0002.md \ No newline at end of file diff --git a/advisories/hackage/bzlib/HSEC-2024-0002.md b/advisories/hackage/bzlib/HSEC-2024-0002.md new file mode 100644 index 00000000..d9e49d1f --- /dev/null +++ b/advisories/hackage/bzlib/HSEC-2024-0002.md @@ -0,0 +1,61 @@ +```toml +[advisory] +id = "HSEC-2024-0002" +cwe = [787] +keywords = ["corruption", "vendored-code", "language-c"] +aliases = ["CVE-2019-12900"] + +[[references]] +type = "DISCUSSION" +url = "https://gnu.wildebeest.org/blog/mjw/2019/08/02/bzip2-and-the-cve-that-wasnt/" + +[[references]] +type = "DISCUSSION" +url = "http://scary.beasts.org/security/CESA-2008-005.html" + +[[references]] +type = "ADVISORY" +url = "https://access.redhat.com/security/cve/cve-2019-12900" + +[[references]] +type = "FIX" +url = "https://sourceware.org/git/?p=bzip2.git;a=commit;h=7ed62bfb46e87a9e878712603469440e6882b184" + +[[affected]] +package = "bzlib" +cvss = "CVSS:3.0/AV:L/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:N" + +[[affected.versions]] +introduced = "0.4" +fixed = "0.5.2.0" + +[[affected]] +package = "bz2" +cvss = "CVSS:3.0/AV:L/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:N" + +[[affected.versions]] +introduced = "0.1.0.0" +fixed = "1.0.1.1" + +[[affected]] +package = "bzlib-conduit" +cvss = "CVSS:3.0/AV:L/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:N" + +[[affected.versions]] +introduced = "0.1.0.0" +fixed = "0.3.0.3" +``` + +# out-of-bounds write when there are many bzip2 selectors + +A malicious bzip2 payload may produce a memory corruption +resulting in a denial of service and/or remote code execution. +Network services or command line utilities decompressing +untrusted bzip2 payloads are affected. + +Note that the exploitation of this bug relies on an undefined +behavior that appears to be handled safely by current compilers. + +The Haskell libraires are vulnerable when they are built using +the bundled C library source code, which is the default +in most cases. diff --git a/test/fixtures/Advisories/advisories/hackage/cabal-install/HSEC-2023-0015.md b/advisories/hackage/cabal-install/HSEC-2023-0015.md similarity index 100% rename from test/fixtures/Advisories/advisories/hackage/cabal-install/HSEC-2023-0015.md rename to advisories/hackage/cabal-install/HSEC-2023-0015.md diff --git a/advisories/hackage/git-annex/HSEC-2023-0009.md b/advisories/hackage/git-annex/HSEC-2023-0009.md new file mode 100644 index 00000000..237e1859 --- /dev/null +++ b/advisories/hackage/git-annex/HSEC-2023-0009.md @@ -0,0 +1,46 @@ +```toml +[advisory] +id = "HSEC-2023-0009" +cwe = [20, 78] +keywords = ["ssh", "command-injection", "historical"] +aliases = ["CVE-2017-12976"] +related = ["CVE-2017-9800", "CVE-2017-12836", "CVE-2017-1000116", "CVE-2017-1000117"] + +[[affected]] +package = "git-annex" +cvss = "CVSS:3.0/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H" +[[affected.versions]] +introduced = "0" +fixed = "6.20170818" + +[[references]] +type = "ADVISORY" +url = "https://git-annex.branchable.com/security/CVE-2017-12976/" +[[references]] +type = "FIX" +url = "http://source.git-annex.branchable.com/?p=source.git;a=commitdiff;h=df11e54788b254efebb4898b474de11ae8d3b471" +``` + +# *git-annex* command injection via malicious SSH hostname + +*git-annex* was vulnerable to the same class of security hole as +git's **CVE-2017-1000117**. In several cases, `git-annex` parses a +repository URL, and uses it to generate a `ssh` command, with the +hostname to ssh to coming from the URL. If the hostname it parses is +something like `-eProxyCommand=evil`, this could result in arbitrary +local code execution. + +Some details of URL parsing may prevent the exploit working in some +cases. + +Exploiting this would involve the attacker tricking the victim into +adding a remote something like `ssh://-eProxyCommand=evil/blah`. + +One possible avenue for an attacker that avoids exposing the URL to +the user is to use `initremote` with an SSH remote, so embedding the +URL in the *git-annex* branch. Then the victim would enable it with +`enableremote`. + +This was fixed in version **6.20170818**. Now there's a `SshHost` +type that is not allowed to start with a dash, and every invocation +of `git-annex` uses a function that takes a `SshHost`. diff --git a/advisories/hackage/git-annex/HSEC-2023-0010.md b/advisories/hackage/git-annex/HSEC-2023-0010.md new file mode 100644 index 00000000..9b31b907 --- /dev/null +++ b/advisories/hackage/git-annex/HSEC-2023-0010.md @@ -0,0 +1,78 @@ +```toml +[advisory] +id = "HSEC-2023-0010" +cwe = [200, 610] +keywords = ["exfiltration", "historical"] +aliases = ["CVE-2018-10857"] + +[[affected]] +package = "git-annex" +cvss = "CVSS:3.0/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:N/A:N" +[[affected.versions]] +introduced = "0" +fixed = "6.20180626" + +[[references]] +type = "ADVISORY" +url = "https://git-annex.branchable.com/security/CVE-2018-10857_and_CVE-2018-10859/" +``` + +# *git-annex* private data exfiltration to compromised remote + +Some uses of git-annex were vulnerable to a private data exposure +and exfiltration attack. It could expose the content of files +located outside the *git-annex* repository, or content from a +private web server on localhost or the LAN. Joey Hess discovered +this attack. + +To perform this attack, the attacker needs to have control over one +of the remotes of the victim's *git-annex* repository. For example, +they may provide a public *git-annex* repository that the victim +clones. Or, equivalantly, the attacker could have read access to the +victim's *git-annex* repository or a repository it pushes to, and +some channel to get commits into it (e.g. pull requests). + +These exploits are most likely to succeed when the victim is running +the `git-annex` assistant, or is periodically running `git annex +sync --content`. + +To perform the attack the attacker runs `git-annex addurl --relaxed +file:///etc/passwd` and commits this to the repository in some out +of the way place. After the victim's git repository receives that +change, `git-annex` follows the attacker-provided URL to the private +data, which it stores in the *git-annex* repository. From there it +transfers the content to the remote *git-annex* repository that the +attacker has access to. + +As well as `file:///` URLs, the attacker can use URLs to private web +servers. The URL can also be one that the attacker controls, that +redirects to a URL that is accessible to the victim system (and not +necessarily the compromised remote). + +## Fix + +The issue was fixed by making `git-annex` refuse to follow +`file:///` urls and URLs pointing to private/local IP addresses by +default. Two new configuration settings, +`annex.security.allowed-url-schemes` and +`annex.security.allowed-ip-addresses`, can relax this security +policy, and are intended for cases where the *git-annex* repository +is kept private and so the attack does not apply. + +## Impact on external special remotes + +One variant of this issue can exploit a vulnerable external special +remote, and could not be prevented by `git-annex`. (`git-annex`'s +own built-in special remotes are not vulnerable to this attack.) + +In this attack variant, the attacker guesses the hash of a file +stored on the victim's private web server, and adds it to the +`git-annex` repository. The attacker also has control of the server +hosting an encrypted special remote used by the victim's *git-annex* +repository. They cause that server to redirect to the victim's web +server. This allows the attacker to verify if the victim's web +server contains a file that the attacker already knows the content +of, assuming they can guess the URL to it. + +Developers of external special remotes are encouraged to prevent +this attack by not following such HTTP redirects. diff --git a/advisories/hackage/git-annex/HSEC-2023-0011.md b/advisories/hackage/git-annex/HSEC-2023-0011.md new file mode 100644 index 00000000..7adc7c0e --- /dev/null +++ b/advisories/hackage/git-annex/HSEC-2023-0011.md @@ -0,0 +1,47 @@ +```toml +[advisory] +id = "HSEC-2023-0011" +cwe = [200] +keywords = ["exfiltration", "pgp", "historical"] +aliases = ["CVE-2018-10859"] +related = ["HSEC-2023-0010", "CVE-2018-10857"] + +[[affected]] +package = "git-annex" +cvss = "CVSS:3.0/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:N/A:N" +[[affected.versions]] +introduced = "0.20110417" +fixed = "6.20180626" + +[[references]] +type = "ADVISORY" +url = "https://git-annex.branchable.com/security/CVE-2018-10857_and_CVE-2018-10859/" +``` + +# *git-annex* GPG decryption attack via compromised remote + +A malicious server for a special remote could trick `git-annex` into +decrypting a file that was encrypted to the user's GPG key. This +attack could be used to expose encrypted data that was never stored +in *git-annex*. Daniel Dent discovered this attack in collaboration +with Joey Hess. + +To perform this attack the attacker needs control of a server +hosting an *encrypted* special remote used by the victim's +*git-annex* repository. The attacker uses `git annex addurl +--relaxed` with an innocuous URL, and waits for the user's +`git-annex` to download it, and upload an (encrypted) copy to the +special remote they also control. At some later point, when the +user downloads the content from the special remote, the attacker +instead sends them the content of the GPG-encrypted file that they +wish to have decrypted in its place (which may have been exfiltrated +from the victim's system via the attack described in +**HSEC-2023-0010** / **CVE-2018-10857**, or acquired by other +means). Finally, the attacker drops their own copy of the original +innocuous URL, and waits for the victim `git-annex` to send them the +accidentially decrypted file. + +The issue was fixed by making `git-annex` refuse to download +encrypted content from special remotes, unless it knows the hash of +the expected content. When the attacker provides some other +GPG-encrypted content, it will fail the hash check and be discarded. diff --git a/advisories/hackage/git-annex/HSEC-2023-0012.md b/advisories/hackage/git-annex/HSEC-2023-0012.md new file mode 100644 index 00000000..c0d6ba26 --- /dev/null +++ b/advisories/hackage/git-annex/HSEC-2023-0012.md @@ -0,0 +1,34 @@ +```toml +[advisory] +id = "HSEC-2023-0012" +cwe = [200] +keywords = ["historical"] + +[[affected]] +package = "git-annex" +cvss = "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:N/A:N" +[[affected.versions]] +introduced = "0.20110417" +fixed = "6.20160419" + +[[references]] +type = "ADVISORY" +url = "https://git-annex.branchable.com/security/checksum_exposure_to_encrypted_special_remotes/" +[[references]] +type = "FIX" +url = "http://source.git-annex.branchable.com/?p=source.git;a=commitdiff;h=b890f3a53d936b5e40aa9acc5876cb98f18b9657" +``` + +# *git-annex* checksum exposure to encrypted special remotes + +A bug exposed the checksum of annexed files to encrypted special +remotes, which are not supposed to have access to the checksum of +the un-encrypted file. This only occurred when resuming uploads to +the encrypted special remote, so it is considered a low-severity +security hole. + +For details, see commit `b890f3a53d936b5e40aa9acc5876cb98f18b9657`. + +No CVE was assigned for this issue. + +Fixed in *git-annex-6.20160419*. diff --git a/advisories/hackage/git-annex/HSEC-2023-0013.md b/advisories/hackage/git-annex/HSEC-2023-0013.md new file mode 100644 index 00000000..ff59b37b --- /dev/null +++ b/advisories/hackage/git-annex/HSEC-2023-0013.md @@ -0,0 +1,73 @@ +```toml +[advisory] +id = "HSEC-2023-0013" +cwe = [312] +keywords = ["historical"] +aliases = ["CVE-2014-6274"] + +[[affected]] +package = "git-annex" +cvss = "CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H" +[[affected.versions]] +introduced = "0.20110401" +fixed = "5.20140919" + +[[references]] +type = "ADVISORY" +url = "https://git-annex.branchable.com/security/CVE-2014-6274/" +[[references]] +type = "ARTICLE" +url = "https://git-annex.branchable.com/upgrades/insecure_embedded_creds/" +``` + +# *git-annex* plaintext storage of embedded credentials on encrypted remotes + +*git-annex* had a bug in the **S3** and **Glacier** remotes where if +`embedcreds=yes` was set, and the remote used `encryption=pubkey` or +`encryption=hybrid`, the embedded AWS credentials were stored in the +Git repository in (effectively) plaintext, not encrypted as they +were supposed to be. + +That means that anyone who gets a copy of the Git repository can +extract the AWS credentials from it. Which would be bad. + +A remote with this problem cannot be enabled using `git annex +enableremote`. Old versions of *git-annex* will fail with a GPG +error; the current version will fail with a pointer to this web +page. + +## Remediation + +If your repository has this problem, chose from one of these +approaches to deal with it: + +1. Change your AWS credentials, so the ones stored in the clear in + git won't be used. + + After changing the credentials, make sure you have a fixed + version of git-annex, and you can then re-embed the new creds + into the repository, encrypted this time, by setting the + `AWS_SECRET_ACCESS_KEY` and `AWS_ACCESS_KEY_ID` environment + variables, and running `git annex enableremote $remotename + embedcreds=yes`. + +2. Fix the problem and then remove the history of the *git-annex* + branch of the repository. + + Make sure you have a fixed version of *git-annex*, and force + *git-annex* to rewrite the embedded creds, with encryption this + time, by setting by setting the `AWS_SECRET_ACCESS_KEY` and + `AWS_ACCESS_KEY_ID` environment variables, and running `git annex + enableremote $remotename embedcreds=yes`. + + Then, to get rid of old versions of the *git-annex* branch that + still contains the creds in cleartext, you can use `git annex + forget`; note that it will remove other historical data too. + + Keep in mind that this will not necessarily delete data from + clones you do not control. + +3. If you're sure that you're the only one who has access to the + repository, you could decide to leave it as-is. It's no more + insecure than if you had used `encryption=shared` in the first + place when setting it up. diff --git a/test/fixtures/Advisories/advisories/hackage/hledger-web/HSEC-2023-0008.md b/advisories/hackage/hledger-web/HSEC-2023-0008.md similarity index 100% rename from test/fixtures/Advisories/advisories/hackage/hledger-web/HSEC-2023-0008.md rename to advisories/hackage/hledger-web/HSEC-2023-0008.md diff --git a/test/fixtures/Advisories/advisories/hackage/keter/HSEC-2024-0001.md b/advisories/hackage/keter/HSEC-2024-0001.md similarity index 100% rename from test/fixtures/Advisories/advisories/hackage/keter/HSEC-2024-0001.md rename to advisories/hackage/keter/HSEC-2024-0001.md diff --git a/test/fixtures/Advisories/advisories/hackage/pandoc/HSEC-2023-0014.md b/advisories/hackage/pandoc/HSEC-2023-0014.md similarity index 100% rename from test/fixtures/Advisories/advisories/hackage/pandoc/HSEC-2023-0014.md rename to advisories/hackage/pandoc/HSEC-2023-0014.md diff --git a/test/fixtures/Advisories/advisories/hackage/process/HSEC-2024-0003.md b/advisories/hackage/process/HSEC-2024-0003.md similarity index 99% rename from test/fixtures/Advisories/advisories/hackage/process/HSEC-2024-0003.md rename to advisories/hackage/process/HSEC-2024-0003.md index e366fe14..ac98ec0c 100644 --- a/test/fixtures/Advisories/advisories/hackage/process/HSEC-2024-0003.md +++ b/advisories/hackage/process/HSEC-2024-0003.md @@ -146,7 +146,7 @@ releases were the first in their series to include a fixed version of the *process* library: - **GHC 9.10.1-alpha3** (released 2024-04-15) -- GHC 9.8.x (**no release with fix yet**) +- **GHC 9.8.3** (released 2024-10-20) - **GHC 9.6.5** (released 2024-04-16) Such a change in semantics should normally result in a major version diff --git a/test/fixtures/Advisories/advisories/hackage/tls-extra/HSEC-2023-0005.md b/advisories/hackage/tls-extra/HSEC-2023-0005.md similarity index 100% rename from test/fixtures/Advisories/advisories/hackage/tls-extra/HSEC-2023-0005.md rename to advisories/hackage/tls-extra/HSEC-2023-0005.md diff --git a/test/fixtures/Advisories/advisories/hackage/toml-reader/HSEC-2023-0007.md b/advisories/hackage/toml-reader/HSEC-2023-0007.md similarity index 100% rename from test/fixtures/Advisories/advisories/hackage/toml-reader/HSEC-2023-0007.md rename to advisories/hackage/toml-reader/HSEC-2023-0007.md diff --git a/advisories/hackage/x509-validation/HSEC-2023-0006.md b/advisories/hackage/x509-validation/HSEC-2023-0006.md new file mode 100644 index 00000000..da8f6b6a --- /dev/null +++ b/advisories/hackage/x509-validation/HSEC-2023-0006.md @@ -0,0 +1,26 @@ +```toml +[advisory] +id = "HSEC-2023-0006" +cwe = [295] +keywords = ["x509", "pki", "historical"] + +[[affected]] +package = "x509-validation" +cvss = "CVSS:3.1/AV:N/AC:H/PR:H/UI:R/S:U/C:H/I:H/A:N" + +[[affected.versions]] +introduced = "1.4.0" +fixed = "1.4.8" + +[[references]] +type = "FIX" +url = "https://github.com/haskell-tls/hs-certificate/commit/06d15dbbc53739314760d8504ca764000770e46e" +``` + +# x509-validation does not enforce pathLenConstraint + +*x509-validation* prior to version 1.4.8 did not enforce the +pathLenConstraint value. Constrained CAs could accidentally (or +deliberately) issue CAs below the maximum depth and +*x509-validation* would accept certificates issued by the +unauthorised intermediate CAs. diff --git a/advisories/hackage/xml-conduit/HSEC-2023-0004.md b/advisories/hackage/xml-conduit/HSEC-2023-0004.md new file mode 100644 index 00000000..0822a530 --- /dev/null +++ b/advisories/hackage/xml-conduit/HSEC-2023-0004.md @@ -0,0 +1,33 @@ +```toml +[advisory] +id = "HSEC-2023-0004" +cwe = [776] +keywords = ["xml", "dos", "historical"] +aliases = ["CVE-2021-4249", "VDB-216204"] + +[[affected]] +package = "xml-conduit" +cvss = "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H" + +[[affected.versions]] +introduced = "0.5.0" +fixed = "1.9.1.0" + +[[references]] +type = "FIX" +url = "https://github.com/snoyberg/xml/pull/161" +[[references]] +type = "FIX" +url = "https://github.com/snoyberg/xml/commit/4be1021791dcdee8b164d239433a2043dc0939ea" +``` + +# xml-conduit unbounded entity expansion + +A vulnerability was found in *xml-conduit*. It has been classified +as problematic. Affected is an unknown function of the file +`xml-conduit/src/Text/XML/Stream/Parse.hs` of the component DOCTYPE +Entity Expansion Handler. The manipulation leads to infinite loop. +It is possible to launch the attack remotely. Upgrading to version +1.9.1.0 is able to address this issue. The name of the patch is +`4be1021791dcdee8b164d239433a2043dc0939ea`. It is recommended to +upgrade the affected component. diff --git a/advisories/hackage/xmonad-contrib/HSEC-2023-0003.md b/advisories/hackage/xmonad-contrib/HSEC-2023-0003.md new file mode 100644 index 00000000..e5fb1a73 --- /dev/null +++ b/advisories/hackage/xmonad-contrib/HSEC-2023-0003.md @@ -0,0 +1,31 @@ +```toml +[advisory] +id = "HSEC-2023-0003" +cwe = [94] +keywords = ["code", "injection", "historical"] +aliases = ["CVE-2013-1436"] + +[[affected]] +package = "xmonad-contrib" +cvss = "AV:N/AC:L/Au:N/C:P/I:P/A:P" +[[affected.versions]] +introduced = "0.5" +fixed = "0.11.2" + +[[references]] +type = "ADVISORY" +url = "https://security.gentoo.org/glsa/201405-28" +[[references]] +type = "DISCUSSION" +url = "http://www.openwall.com/lists/oss-security/2013/07/26/5" +[[references]] +type = "FIX" +url = "https://github.com/xmonad/xmonad-contrib/commit/d3b2a01e3d01ac628e7a3139dd55becbfa37cf51" +``` + +# code injection in *xmonad-contrib* + +The `XMonad.Hooks.DynamicLog` module in _xmonad-contrib_ before +**0.11.2** allows remote attackers to execute arbitrary commands via a +web page title, which activates the commands when the user clicks on +the xmobar window title, as demonstrated using an action tag. diff --git a/test/fixtures/Advisories/advisories/reserved/HSEC-2024-0004.md b/advisories/reserved/.gitkeep similarity index 100% rename from test/fixtures/Advisories/advisories/reserved/HSEC-2024-0004.md rename to advisories/reserved/.gitkeep diff --git a/test/fixtures/Advisories/advisories/reserved/HSEC-2024-0005.md b/advisories/reserved/HSEC-2024-0004.md similarity index 100% rename from test/fixtures/Advisories/advisories/reserved/HSEC-2024-0005.md rename to advisories/reserved/HSEC-2024-0004.md diff --git a/advisories/reserved/HSEC-2024-0005.md b/advisories/reserved/HSEC-2024-0005.md new file mode 100644 index 00000000..e69de29b diff --git a/app/cli/DesignSystem.hs b/app/cli/DesignSystem.hs index c31459a5..5d7f59d4 100644 --- a/app/cli/DesignSystem.hs +++ b/app/cli/DesignSystem.hs @@ -7,6 +7,7 @@ import Data.ByteString.Lazy (ByteString) import Data.ByteString.Lazy qualified as ByteString import Data.Foldable (forM_) import Data.Functor.Identity (runIdentity) +import Data.Maybe (fromJust) import Data.Text (Text) import Data.Text.Lazy qualified as TL import Data.Time.Calendar.OrdinalDate as Time @@ -20,13 +21,16 @@ import Effectful.Fail import Env import Lucid import PyF (fmt) +import Security.Advisories.Core.HsecId qualified as HsecId +import Advisories.Model.Affected.Types import Distribution.SPDX import Flora.Environment.Config import Flora.Model.Category import Flora.Model.Category qualified as Category import Flora.Model.Package import Flora.Search +import FloraWeb.Components.AdvisoryListItem qualified as Component import FloraWeb.Components.Alert qualified as Component import FloraWeb.Components.CategoryCard qualified as Component import FloraWeb.Components.PackageListItem qualified as Component @@ -73,6 +77,7 @@ components = , ("category-card", ComponentTitle "Category", ComponentName "CategoryCard", categoryCardExample) , ("pagination-area", ComponentTitle "Pagination Area", ComponentName "Pagination", paginationExample) , ("alerts", ComponentTitle "Alerts", ComponentName "Alert", alertsExample) + , ("advisory-preview", ComponentTitle "Advisories", ComponentName "AdvisoryPreviews", packageAdvisoriesExample) ] ----------------------- @@ -133,9 +138,15 @@ paginationExample = div_ $ do Component.paginationNav 32 1 (SearchPackages "text") alertsExample :: FloraHTML -alertsExample = div_ $ do - div_ $ do - h4_ "Info alert" - Component.info "Info alert" - h4_ "Error alert" - Component.exception "Error alert!" +alertsExample = div_ $ div_ $ do + h4_ "Info alert" + Component.info "Info alert" + h4_ "Error alert" + Component.exception "Error alert!" + +packageAdvisoriesExample :: FloraHTML +packageAdvisoriesExample = do + let advisoryPreviews = + Vector.fromList + [] + ul_ [class_ "advisory-list"] $ Vector.forM_ advisoryPreviews (\preview -> Component.advisoryListItem preview) diff --git a/app/cli/Main.hs b/app/cli/Main.hs index f2aae621..96e0ca6e 100644 --- a/app/cli/Main.hs +++ b/app/cli/Main.hs @@ -1,33 +1,41 @@ module Main where import Codec.Compression.GZip qualified as GZip +import Control.Monad.Extra (unlessM) import Data.ByteString.Lazy.Char8 qualified as BS +import Data.List.NonEmpty (NonEmpty) import Data.Maybe import Data.Poolboy (poolboySettingsWith) +import Data.Set (Set) import Data.Text (Text) import Data.Text qualified as Text import Data.Text.Display (display) import DesignSystem (generateComponents) import Distribution.Version (Version) import Effectful +import Effectful.Error.Static (Error, runErrorNoCallStack) import Effectful.Fail import Effectful.FileSystem import Effectful.Log (Log, runLog) +import Effectful.Poolboy import Effectful.PostgreSQL.Transact.Effect +import Effectful.State.Static.Shared (State) +import Effectful.State.Static.Shared qualified as State import Effectful.Time (Time, runTime) +import Effectful.Trace (Trace) +import Effectful.Trace qualified as Trace import GHC.Conc import GHC.Generics (Generic) import Log qualified import Log.Backend.StandardOutput qualified as Log +import Monitor.Tracing.Zipkin (Zipkin (..)) import Optics.Core import Options.Applicative import Sel.Hashing.Password qualified as Sel import System.FilePath (()) -import Data.Set (Set) -import Effectful.Poolboy -import Effectful.State.Static.Shared (State) -import Effectful.State.Static.Shared qualified as State +import Advisories.Import (importAdvisories) +import Advisories.Import.Error (AdvisoryImportError) import Flora.Environment import Flora.Import.Categories (importCategories) import Flora.Import.Package.Bulk (importAllFilesInRelativeDirectory, importFromIndex) @@ -40,6 +48,8 @@ import Flora.Model.PackageIndex.Update qualified as Update import Flora.Model.User import Flora.Model.User.Query qualified as Query import Flora.Model.User.Update +import Flora.Tracing qualified as Tracing +import System.Exit (exitFailure) data Options = Options { cliCommand :: Command @@ -59,6 +69,7 @@ data Command data ProvisionTarget = Categories | TestPackages Text + | Advisories deriving stock (Show, Eq) data UserCreationOptions = UserCreationOptions @@ -72,23 +83,36 @@ data UserCreationOptions = UserCreationOptions main :: IO () main = Log.withStdOutLogger $ \logger -> do - result <- execParser (parseOptions `withInfo` "CLI tool for flora-server") + cliArgs <- execParser (parseOptions `withInfo` "CLI tool for flora-server") capabilities <- getNumCapabilities env <- getFloraEnv & runFailIO & runEff - runEff - . State.evalState (mempty @(Set (Namespace, PackageName, Version))) - . withUnliftStrategy (ConcUnlift Ephemeral Unlimited) - . runDB env.pool - . runFailIO - . runTime - . runPoolboy (poolboySettingsWith capabilities) - . ( case env.features.blobStoreImpl of - Just (BlobStoreFS fp) -> runBlobStoreFS fp - _ -> runBlobStorePure - ) - . runFileSystem - . runLog "flora-cli" logger Log.LogTrace - $ runOptions result + runTrace <- + if env.environment == Production + then do + zipkin <- liftIO $ Tracing.newZipkin env.mltp.zipkinHost "flora-cli" + pure $ Trace.runTrace zipkin.zipkinTracer + else pure Trace.runNoTrace + result <- + runEff + . runTrace + . runErrorNoCallStack + . State.evalState (mempty @(Set (Namespace, PackageName, Version))) + . withUnliftStrategy (ConcUnlift Ephemeral Unlimited) + . runDB env.pool + . runFailIO + . runTime + . runPoolboy (poolboySettingsWith capabilities) + . ( case env.features.blobStoreImpl of + Just (BlobStoreFS fp) -> runBlobStoreFS fp + _ -> runBlobStorePure + ) + . runFileSystem + . runLog "flora-cli" logger Log.LogTrace + $ runOptions cliArgs + case result of + Right _ -> pure () + Left errors -> + error $ show errors parseOptions :: Parser Options parseOptions = @@ -114,6 +138,7 @@ parseProvision = subparser $ command "categories" (pure (Provision Categories) `withInfo` "Load the canonical categories in the system") <> command "test-packages" (parseProvisionTestPackages `withInfo` "Load the test packages in the database") + <> command "advisories" (pure (Provision Advisories) `withInfo` "Load the security advisories database") parseProvisionTestPackages :: Parser Command parseProvisionTestPackages = @@ -169,10 +194,19 @@ runOptions , BlobStoreAPI :> es , State (Set (Namespace, PackageName, Version)) :> es , Poolboy :> es + , Error (NonEmpty AdvisoryImportError) :> es + , Trace :> es ) => Options -> Eff es () runOptions (Options (Provision Categories)) = importCategories +runOptions (Options (Provision Advisories)) = do + dataDir <- getXdgDirectory XdgData "" + let advisoriesDirectory = dataDir "security-advisories" + unlessM (doesDirectoryExist advisoriesDirectory) $ do + Log.logAttention_ $ Text.pack $ "Could not find " <> advisoriesDirectory <> ". Clone https://github.com/haskell/security-advisories.git at this location." + liftIO exitFailure + importAdvisories advisoriesDirectory runOptions (Options (Provision (TestPackages repository))) = importFolderOfCabalFiles "./test/fixtures/Cabal/" repository runOptions (Options (CreateUser opts)) = do let username = opts ^. #username @@ -189,7 +223,7 @@ runOptions (Options (CreateUser opts)) = do >>= \admin -> if canLogin then pure () - else lockAccount (admin ^. #userId) + else lockAccount admin.userId else do templateUser <- mkUser UserCreationForm{..} let user = if canLogin then templateUser else templateUser & #userFlags % #canLogin .~ False diff --git a/assets/.stylelintrc.json b/assets/.stylelintrc.json index 27593a46..38e0a7d4 100644 --- a/assets/.stylelintrc.json +++ b/assets/.stylelintrc.json @@ -4,6 +4,7 @@ "hue-degree-notation": "number", "media-feature-range-notation": "prefix", "import-notation": "string", + "selector-class-pattern": null, "at-rule-no-unknown": [ true, { diff --git a/assets/css/1-core/3-variables.css b/assets/css/1-core/3-variables.css index 441d5430..f9366a31 100644 --- a/assets/css/1-core/3-variables.css +++ b/assets/css/1-core/3-variables.css @@ -46,6 +46,9 @@ --light-red-background: hsl(355 73% 97%); --light-green: hsl(206 41% 97%); + --pale-blue: hsl(184, 55%, 77%); + --pale-green: hsl(120, 93%, 79%); + /* Dark foregrounds to go with backgrounds */ --dark-blue: hsl(220 64% 33%); --dark-red: hsl(0 69% 36%); @@ -88,6 +91,13 @@ --deprecated-version: var(--red-60); --breadcrumb-color: var(--gray-30); + --severity-critical: var(--red-60); + --severity-high: orange; + --severity-medium: gold; + --severity-low: var(--pale-blue); + --severity-none: hsl(156, 100%, 99%); + --severity-rating-colour: black; + /* Focus ring (aka outline) */ --outline-offset-shadow: 0 0 #0000; --outline-shadow: 0 0 #0000; @@ -135,4 +145,11 @@ html[data-theme="dark"] { --main-page-button-divider: var(--blue-15); --deprecated-version: var(--red-60); --breadcrumb-color: hsl(221 9% 60%); + + --severity-critical: var(--red-60); + --severity-high: orange; + --severity-medium: gold; + --severity-low: var(--pale-blue); + --severity-none: hsl(156, 100%, 99%); + --severity-rating-colour: black; } diff --git a/assets/css/2-components/11-advisory-list-item.css b/assets/css/2-components/11-advisory-list-item.css new file mode 100644 index 00000000..83a9e6af --- /dev/null +++ b/assets/css/2-components/11-advisory-list-item.css @@ -0,0 +1,74 @@ +.package-advisory-list-item { + display: table-row; + font-size: 1.10rem; + line-height: 2rem; +} + +.package-advisory-list-item__hsec-id { + display: table-cell; +} + +.package-advisory-list-item__summary { + display: table-cell; + font-weight: bolder; +} + +.package-advisory-list-item__published { + display: table-cell; +} + +.package-advisory-list-item__attributes { + display: table-cell; + font-size: 0.90em; + + .advisory-list-item__severity-none { + background-color: var(--severity-none); + border-radius: 0.5rem; + color: var(--severity-rating-colour); + padding-left: 0.5rem; + padding-right: 0.5rem; + } + + .advisory-list-item__severity-low { + background-color: var(--severity-low); + border-radius: 0.5rem; + color: var(--severity-rating-colour); + padding-left: 0.5rem; + padding-right: 0.5rem; + } + + .advisory-list-item__severity-medium { + background-color: var(--severity-medium); + border-radius: 0.5rem; + color: var(--severity-rating-colour); + padding-left: 0.5rem; + padding-right: 0.5rem; + } + + .advisory-list-item__severity-high { + background-color: var(--severity-high); + border-radius: 0.5rem; + color: var(--severity-rating-colour); + padding-left: 0.5rem; + padding-right: 0.5rem; + } + + .advisory-list-item__severity-critical { + background-color: var(--severity-critical); + border-radius: 0.5rem; + color: var(--severity-rating-colour); + padding-left: 0.5rem; + padding-right: 0.5rem; + } + + .advisory-list-item__fix-available { + background-color: var(--pale-green); + border-radius: 0.5rem; + color: var(--severity-rating-colour); + padding-left: 0.5rem; + padding-right: 0.5rem; + margin-left: 0.5rem; + + } + +} diff --git a/assets/css/3-screens/1-package/5-security.css b/assets/css/3-screens/1-package/5-security.css new file mode 100644 index 00000000..94964dec --- /dev/null +++ b/assets/css/3-screens/1-package/5-security.css @@ -0,0 +1,20 @@ +.advisory-list { + display: table; + border-collapse: separate; + border-spacing: 12px; +} + +.advisory-list__head { + display: table-header-group; + border-inline: solid; + font-size: 1.25rem; + +} + +.advisory-list__body { + display: table-row-group; +} + +.advisory-list__header { + display: table-cell; +} diff --git a/assets/css/styles.css b/assets/css/styles.css index 6ead1242..4574c47c 100644 --- a/assets/css/styles.css +++ b/assets/css/styles.css @@ -17,12 +17,14 @@ @import "2-components/8-alert.css"; @import "2-components/9-terminal-icon.css"; @import "2-components/10-error.css"; +@import "2-components/11-advisory-list-item.css"; /* Screens/Pages specific style */ @import "3-screens/1-package/1-package.css"; @import "3-screens/1-package/2-release-changelog.css"; @import "3-screens/1-package/3-release-readme.css"; @import "3-screens/1-package/4-compiler-badge.css"; +@import "3-screens/1-package/5-security.css"; @import "3-screens/2-categories.css"; @import "3-screens/3-about.css"; @import "3-screens/4-front-page.css"; diff --git a/code/LICENSE.txt b/code/LICENSE.txt new file mode 100644 index 00000000..2b6b9116 --- /dev/null +++ b/code/LICENSE.txt @@ -0,0 +1,11 @@ +The code in this directory is copyright 2023, The Haskell Foundation + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/code/README.md b/code/README.md new file mode 100644 index 00000000..2bfca286 --- /dev/null +++ b/code/README.md @@ -0,0 +1 @@ +This directory contains code for working with advisories. diff --git a/code/cvss/CHANGELOG.md b/code/cvss/CHANGELOG.md new file mode 100644 index 00000000..a084be39 --- /dev/null +++ b/code/cvss/CHANGELOG.md @@ -0,0 +1,7 @@ +# 0.2 + +Changed the CVSS v2 parser and printer to omit the "CVSS:2.0/" version prefix according to the spec. + +# 0.1 + +Introduction diff --git a/code/cvss/cvss.cabal b/code/cvss/cvss.cabal new file mode 100644 index 00000000..54ae786b --- /dev/null +++ b/code/cvss/cvss.cabal @@ -0,0 +1,41 @@ +cabal-version: 2.4 +name: cvss +version: 0.2 +synopsis: Common Vulnerability Scoring System. +description: + Use this library to parse CVSS string and compute its score. + +license: BSD-3-Clause +author: Tristan de Cacqueray +maintainer: tdecacqu@redhat.com +category: Data +extra-doc-files: CHANGELOG.md +tested-with: GHC ==8.10.7 || ==9.0.2 || ==9.2.8 || ==9.4.8 || ==9.6.3 || ==9.8.1 + +library + exposed-modules: Security.CVSS + build-depends: + , base >=4.14 && <5 + , text >=1.2 && <3 + + hs-source-dirs: src + default-language: Haskell2010 + ghc-options: + -Wall -Wcompat -Widentities -Wincomplete-record-updates + -Wincomplete-uni-patterns -Wpartial-fields -Wredundant-constraints + +test-suite spec + type: exitcode-stdio-1.0 + hs-source-dirs: test + main-is: Spec.hs + build-depends: + , base <5 + , cvss + , tasty <1.5 + , tasty-hunit <1.0 + , text + + default-language: Haskell2010 + ghc-options: + -Wall -Wcompat -Widentities -Wincomplete-record-updates + -Wincomplete-uni-patterns -Wpartial-fields -Wredundant-constraints diff --git a/code/cvss/src/Security/CVSS.hs b/code/cvss/src/Security/CVSS.hs new file mode 100644 index 00000000..5399b752 --- /dev/null +++ b/code/cvss/src/Security/CVSS.hs @@ -0,0 +1,563 @@ +{-# LANGUAGE DerivingStrategies #-} +{-# LANGUAGE GeneralisedNewtypeDeriving #-} +{-# LANGUAGE ImportQualifiedPost #-} +{-# LANGUAGE OverloadedStrings #-} +{-# LANGUAGE PatternSynonyms #-} +{-# LANGUAGE TypeApplications #-} + +-- | This module provides a CVSS parser and utility functions +-- adapted from https://www.first.org/cvss/v3.1/specification-document +module Security.CVSS + ( -- * Type + CVSS (cvssVersion), + CVSSVersion (..), + Rating (..), + + -- * Parser + parseCVSS, + CVSSError (..), + + -- * Helpers + cvssVectorString, + cvssVectorStringOrdered, + cvssScore, + cvssInfo, + ) +where + +import Data.Coerce (coerce) +import Data.Foldable (traverse_) +import Data.List (find, group, sort) +import Data.Maybe (mapMaybe) +import Data.String (IsString) +import Data.Text (Text) +import Data.Text qualified as Text +import GHC.Float (powerFloat) + +-- | The CVSS version. +data CVSSVersion + = -- | Version 3.1: https://www.first.org/cvss/v3-1/ + CVSS31 + | -- | Version 3.0: https://www.first.org/cvss/v3.0/ + CVSS30 + | -- | Version 2.0: https://www.first.org/cvss/v2/ + CVSS20 + deriving (Eq) + +-- | Parsed CVSS string obtained with 'parseCVSS'. +data CVSS = CVSS + { -- | The CVSS Version. + cvssVersion :: CVSSVersion, + -- | The metrics are stored as provided by the user + cvssMetrics :: [Metric] + } + deriving stock (Eq) + +instance Show CVSS where + show = Text.unpack . cvssVectorString + +-- | CVSS Rating obtained with 'cvssScore' +data Rating = None | Low | Medium | High | Critical + deriving (Enum, Eq, Ord, Show) + +-- | Implementation of Section 5. "Qualitative Severity Rating Scale" +toRating :: Float -> Rating +toRating score + | score <= 0 = None + | score < 4 = Low + | score < 7 = Medium + | score < 9 = High + | otherwise = Critical + +data CVSSError + = UnknownVersion + | EmptyComponent + | MissingValue Text + | DuplicateMetric Text + | MissingRequiredMetric Text + | UnknownMetric Text + | UnknownValue Text Char + +instance Show CVSSError where + show = Text.unpack . showCVSSError + +showCVSSError :: CVSSError -> Text +showCVSSError e = case e of + UnknownVersion -> "Unknown CVSS version" + EmptyComponent -> "Empty component" + MissingValue name -> "Missing value for \"" <> name <> "\"" + DuplicateMetric name -> "Duplicate metric for \"" <> name <> "\"" + MissingRequiredMetric name -> "Missing required metric \"" <> name <> "\"" + UnknownMetric name -> "Unknown metric \"" <> name <> "\"" + UnknownValue name value -> "Unknown value '" <> Text.pack (show value) <> "' for \"" <> name <> "\"" + +newtype MetricShortName = MetricShortName Text + deriving newtype (Eq, IsString, Ord, Show) + +newtype MetricValueChar = MetricValueChar Char + deriving newtype (Eq, Ord, Show) + +data Metric = Metric + { mName :: MetricShortName, + mChar :: MetricValueChar + } + deriving (Eq, Show) + +-- example CVSS string: CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:U/C:L/I:L/A:N + +-- | Parse a CVSS string. +parseCVSS :: Text -> Either CVSSError CVSS +parseCVSS txt + | "CVSS:3.1/" `Text.isPrefixOf` txt = CVSS CVSS31 <$> validateComponents True validateCvss31 + | "CVSS:3.0/" `Text.isPrefixOf` txt = CVSS CVSS30 <$> validateComponents True validateCvss30 + | "CVSS:" `Text.isPrefixOf` txt = Left UnknownVersion + | otherwise = CVSS CVSS20 <$> validateComponents False validateCvss20 + where + validateComponents withPrefix validator = do + metrics <- traverse splitComponent $ components withPrefix + validator metrics + + components withPrefix = (if withPrefix then drop 1 else id) $ Text.split (== '/') txt + splitComponent :: Text -> Either CVSSError Metric + splitComponent componentTxt = case Text.unsnoc componentTxt of + Nothing -> Left EmptyComponent + Just (rest, c) -> case Text.unsnoc rest of + Just (name, ':') -> Right (Metric (MetricShortName name) (MetricValueChar c)) + _ -> Left (MissingValue componentTxt) + +-- | Compute the base score. +cvssScore :: CVSS -> (Rating, Float) +cvssScore cvss = case cvssVersion cvss of + CVSS31 -> cvss31score (cvssMetrics cvss) + CVSS30 -> cvss30score (cvssMetrics cvss) + CVSS20 -> cvss20score (cvssMetrics cvss) + +-- | Explain the CVSS metrics. +cvssInfo :: CVSS -> [Text] +cvssInfo cvss = doCVSSInfo (cvssDB (cvssVersion cvss)) (cvssMetrics cvss) + +-- | Format the CVSS back to its original string. +cvssVectorString :: CVSS -> Text +cvssVectorString = cvssShow False + +-- | Format the CVSS to the prefered ordered vector string. +cvssVectorStringOrdered :: CVSS -> Text +cvssVectorStringOrdered = cvssShow True + +cvssShow :: Bool -> CVSS -> Text +cvssShow ordered cvss = case cvssVersion cvss of + CVSS31 -> Text.intercalate "/" ("CVSS:3.1" : components) + CVSS30 -> Text.intercalate "/" ("CVSS:3.0" : components) + CVSS20 -> Text.intercalate "/" components + where + components = map toComponent (cvssOrder (cvssMetrics cvss)) + toComponent :: Metric -> Text + toComponent (Metric (MetricShortName name) (MetricValueChar value)) = Text.snoc (name <> ":") value + cvssOrder metrics + | ordered = mapMaybe getMetric (allMetrics (cvssDB (cvssVersion cvss))) + | otherwise = metrics + where + getMetric mi = find (\metric -> miShortName mi == mName metric) metrics + +newtype CVSSDB = CVSSDB [MetricGroup] + +cvssDB :: CVSSVersion -> CVSSDB +cvssDB v = case v of + CVSS31 -> cvss31 + CVSS30 -> cvss30 + CVSS20 -> cvss20 + +-- | Description of a metric group. +data MetricGroup = MetricGroup + { mgName :: Text, + mgMetrics :: [MetricInfo] + } + +-- | Description of a single metric. +data MetricInfo = MetricInfo + { miName :: Text, + miShortName :: MetricShortName, + miRequired :: Bool, + miValues :: [MetricValue] + } + +-- | Description of a single metric value +data MetricValue = MetricValue + { mvName :: Text, + mvChar :: MetricValueChar, + mvNum :: Float, + mvNumChangedScope :: Maybe Float, + mvDesc :: Text + } + +-- | CVSS3.1 metrics pulled from section 2. "Base Metrics" and section section 7.4. "Metric Values" +cvss31 :: CVSSDB +cvss31 = + CVSSDB + [ MetricGroup "Base" baseMetrics, + MetricGroup "Temporal" temporalMetrics, + MetricGroup "Environmental" environmentalMetrics + ] + where + baseMetrics = + [ MetricInfo + "Attack Vector" + "AV" + True + [ MetricValue "Network" (C 'N') 0.85 Nothing "The vulnerable component is bound to the network stack and the set of possible attackers extends beyond the other options listed below, up to and including the entire Internet.", + MetricValue "Adjacent" (C 'A') 0.62 Nothing "The vulnerable component is bound to the network stack, but the attack is limited at the protocol level to a logically adjacent topology.", + MetricValue "Local" (C 'L') 0.55 Nothing "The vulnerable component is not bound to the network stack and the attacker’s path is via read/write/execute capabilities.", + MetricValue "Physical" (C 'P') 0.2 Nothing "The attack requires the attacker to physically touch or manipulate the vulnerable component." + ], + MetricInfo + "Attack Complexity" + "AC" + True + [ MetricValue "Low" (C 'L') 0.77 Nothing "Specialized access conditions or extenuating circumstances do not exist.", + MetricValue "High" (C 'H') 0.44 Nothing "A successful attack depends on conditions beyond the attacker's control." + ], + MetricInfo + "Privileges Required" + "PR" + True + [ MetricValue "None" (C 'N') 0.85 Nothing "The attacker is unauthorized prior to attack, and therefore does not require any access to settings or files of the vulnerable system to carry out an attack.", + MetricValue "Low" (C 'L') 0.62 (Just 0.68) "The attacker requires privileges that provide basic user capabilities that could normally affect only settings and files owned by a user.", + MetricValue "High" (C 'H') 0.27 (Just 0.5) "The attacker requires privileges that provide significant (e.g., administrative) control over the vulnerable component allowing access to component-wide settings and files." + ], + MetricInfo + "User Interaction" + "UI" + True + [ MetricValue "None" (C 'N') 0.85 Nothing "The vulnerable system can be exploited without interaction from any user.", + MetricValue "Required" (C 'R') 0.62 Nothing "Successful exploitation of this vulnerability requires a user to take some action before the vulnerability can be exploited." + ], + MetricInfo + "Scope" + "S" + True + [ -- Note: not defined as contants in specification + MetricValue "Unchanged" (C 'U') Unchanged Nothing "An exploited vulnerability can only affect resources managed by the same security authority.", + MetricValue "Changed" (C 'C') Changed Nothing "An exploited vulnerability can affect resources beyond the security scope managed by the security authority of the vulnerable component." + ], + MetricInfo + "Confidentiality Impact" + "C" + True + [ mkHigh "There is a total loss of confidentiality, resulting in all resources within the impacted component being divulged to the attacker.", + mkLow "There is some loss of confidentiality.", + mkNone "There is no loss of confidentiality within the impacted component." + ], + MetricInfo + "Integrity Impact" + "I" + True + [ mkHigh "There is a total loss of integrity, or a complete loss of protection.", + mkLow "Modification of data is possible, but the attacker does not have control over the consequence of a modification, or the amount of modification is limited.", + mkNone "There is no loss of integrity within the impacted component." + ], + MetricInfo + "Availability Impact" + "A" + True + [ mkHigh "There is a total loss of availability, resulting in the attacker being able to fully deny access to resources in the impacted component", + mkLow "Performance is reduced or there are interruptions in resource availability.", + mkNone "There is no impact to availability within the impacted component." + ] + ] + mkHigh = MetricValue "High" (C 'H') 0.56 Nothing + mkLow = MetricValue "Low" (C 'L') 0.22 Nothing + mkNone = MetricValue "None" (C 'N') 0 Nothing + -- TODOs + temporalMetrics = [] + environmentalMetrics = [] + +pattern C :: Char -> MetricValueChar +pattern C c = MetricValueChar c + +pattern Unchanged :: Float +pattern Unchanged = 6.42 + +pattern Changed :: Float +pattern Changed = 7.52 + +doCVSSInfo :: CVSSDB -> [Metric] -> [Text] +doCVSSInfo (CVSSDB db) = map showMetricInfo + where + showMetricInfo metric = case mapMaybe (getInfo metric) db of + [(mg, mi, mv)] -> + mconcat [mgName mg, " ", miName mi, ": ", mvName mv, " (", mvDesc mv, ")"] + _ -> error $ "The impossible have happened for " <> show metric + getInfo metric mg = do + mi <- find (\mi -> miShortName mi == mName metric) (mgMetrics mg) + mv <- find (\mv -> mvChar mv == mChar metric) (miValues mi) + pure (mg, mi, mv) + +allMetrics :: CVSSDB -> [MetricInfo] +allMetrics (CVSSDB db) = concatMap mgMetrics db + +-- | Implementation of the Appendix A - "Floating Point Rounding" +roundup :: Float -> Float +roundup input + | int_input `mod` 10000 == 0 = fromIntegral int_input / 100000 + | otherwise = (fromIntegral (floor_int (fromIntegral int_input / 10000)) + 1) / 10 + where + floor_int :: Float -> Int + floor_int = floor + int_input :: Int + int_input = round (input * 100000) + +-- | Implementation of section 7.1. Base Metrics Equations +cvss31score :: [Metric] -> (Rating, Float) +cvss31score metrics = (toRating score, score) + where + iss = 1 - (1 - gm "Confidentiality Impact") * (1 - gm "Integrity Impact") * (1 - gm "Availability Impact") + impact + | scope == Unchanged = scope * iss + | otherwise = scope * (iss - 0.029) - 3.25 * powerFloat (iss - 0.02) 15 + exploitability = 8.22 * gm "Attack Vector" * gm "Attack Complexity" * gm "Privileges Required" * gm "User Interaction" + score + | impact <= 0 = 0 + | scope == Unchanged = roundup (min (impact + exploitability) 10) + | otherwise = roundup (min (1.08 * (impact + exploitability)) 10) + scope = gm "Scope" + + gm :: Text -> Float + gm = getMetricValue cvss31 metrics scope + +getMetricValue :: CVSSDB -> [Metric] -> Float -> Text -> Float +getMetricValue db metrics scope name = case mValue of + Nothing -> error $ "The impossible have happened, unknown metric: " <> Text.unpack name + Just v -> v + where + mValue = do + mi <- find (\mi -> miName mi == name) (allMetrics db) + Metric _ valueChar <- find (\metric -> miShortName mi == mName metric) metrics + mv <- find (\mv -> mvChar mv == valueChar) (miValues mi) + pure $ case mvNumChangedScope mv of + Just value | scope /= Unchanged -> value + _ -> mvNum mv + +validateCvss31 :: [Metric] -> Either CVSSError [Metric] +validateCvss31 metrics = do + traverse_ (\t -> t metrics) [validateUnique, validateKnown cvss31, validateRequired cvss31] + pure metrics + +cvss30 :: CVSSDB +cvss30 = + CVSSDB + [ MetricGroup "Base" baseMetrics + ] + where + baseMetrics = + [ MetricInfo + "Attack Vector" + "AV" + True + [ MetricValue "Network" (C 'N') 0.85 Nothing "A vulnerability exploitable with network access means the vulnerable component is bound to the network stack and the attacker's path is through OSI layer 3 (the network layer).", + MetricValue "Adjacent" (C 'A') 0.62 Nothing "A vulnerability exploitable with adjacent network access means the vulnerable component is bound to the network stack", + MetricValue "Local" (C 'L') 0.55 Nothing "A vulnerability exploitable with Local access means that the vulnerable component is not bound to the network stack, and the attacker's path is via read/write/execute capabilities.", + MetricValue "Physical" (C 'P') 0.2 Nothing "A vulnerability exploitable with Physical access requires the attacker to physically touch or manipulate the vulnerable component." + ], + MetricInfo + "Attack Complexity" + "AC" + True + [ MetricValue "Low" (C 'L') 0.77 Nothing "Specialized access conditions or extenuating circumstances do not exist.", + MetricValue "High" (C 'H') 0.44 Nothing "A successful attack depends on conditions beyond the attacker's control." + ], + MetricInfo + "Privileges Required" + "PR" + True + [ MetricValue "None" (C 'N') 0.85 Nothing "The attacker is unauthorized prior to attack, and therefore does not require any access to settings or files to carry out an attack.", + MetricValue "Low" (C 'L') 0.62 (Just 0.68) "The attacker is authorized with (i.e. requires) privileges that provide basic user capabilities that could normally affect only settings and files owned by a user.", + MetricValue "High" (C 'H') 0.27 (Just 0.5) "The attacker is authorized with (i.e. requires) privileges that provide significant (e.g. administrative) control over the vulnerable component that could affect component-wide settings and files." + ], + MetricInfo + "User Interaction" + "UI" + True + [ MetricValue "None" (C 'N') 0.85 Nothing "The vulnerable system can be exploited without interaction from any user.", + MetricValue "Required" (C 'R') 0.62 Nothing "Successful exploitation of this vulnerability requires a user to take some action before the vulnerability can be exploited." + ], + MetricInfo + "Scope" + "S" + True + [ MetricValue "Unchanged" (C 'U') Unchanged Nothing "An exploited vulnerability can only affect resources managed by the same authority.", + MetricValue "Changed" (C 'C') Changed Nothing "An exploited vulnerability can affect resources beyond the authorization privileges intended by the vulnerable component." + ], + MetricInfo + "Confidentiality Impact" + "C" + True + [ mkHigh "There is a total loss of confidentiality, resulting in all resources within the impacted component being divulged to the attacker.", + mkLow "There is some loss of confidentiality.", + mkNone "There is no loss of confidentiality within the impacted component." + ], + MetricInfo + "Integrity Impact" + "I" + True + [ mkHigh "There is a total loss of integrity, or a complete loss of protection.", + mkLow "Modification of data is possible, but the attacker does not have control over the consequence of a modification, or the amount of modification is limited.", + mkNone "There is no loss of integrity within the impacted component." + ], + MetricInfo + "Availability Impact" + "A" + True + [ mkHigh "There is a total loss of availability, resulting in the attacker being able to fully deny access to resources in the impacted component", + mkLow "Performance is reduced or there are interruptions in resource availability.", + mkNone "There is no impact to availability within the impacted component." + ] + ] + mkHigh = MetricValue "High" (C 'H') 0.56 Nothing + mkLow = MetricValue "Low" (C 'L') 0.22 Nothing + mkNone = MetricValue "None" (C 'N') 0 Nothing + +-- | Implementation of Section 8.1 "Base" +cvss30score :: [Metric] -> (Rating, Float) +cvss30score metrics = (toRating score, score) + where + score + | impact <= 0 = 0 + | scope == Unchanged = roundup (min (impact + exploitability) 10) + | otherwise = roundup (min (1.08 * (impact + exploitability)) 10) + impact + | scope == Unchanged = scope * iscBase + | otherwise = scope * (iscBase - 0.029) - 3.25 * powerFloat (iscBase - 0.02) 15 + iscBase = 1 - (1 - gm "Confidentiality Impact") * (1 - gm "Integrity Impact") * (1 - gm "Availability Impact") + scope = gm "Scope" + + exploitability = 8.22 * gm "Attack Vector" * gm "Attack Complexity" * gm "Privileges Required" * gm "User Interaction" + gm = getMetricValue cvss30 metrics scope + +validateCvss30 :: [Metric] -> Either CVSSError [Metric] +validateCvss30 metrics = do + traverse_ (\t -> t metrics) [validateUnique, validateKnown cvss30, validateRequired cvss30] + pure metrics + +cvss20 :: CVSSDB +cvss20 = + CVSSDB + [ MetricGroup "Base" baseMetrics + ] + where + baseMetrics = + [ MetricInfo + "Access Vector" + "AV" + True + [ MetricValue "Local" (C 'L') 0.395 Nothing "A vulnerability exploitable with only local access requires the attacker to have either physical access to the vulnerable system or a local (shell) account.", + MetricValue "Adjacent Network" (C 'A') 0.646 Nothing "A vulnerability exploitable with adjacent network access requires the attacker to have access to either the broadcast or collision domain of the vulnerable software.", + MetricValue "Network" (C 'N') 1.0 Nothing "A vulnerability exploitable with network access means the vulnerable software is bound to the network stack and the attacker does not require local network access or local access." + ], + MetricInfo + "Access Complexity" + "AC" + True + [ MetricValue "High" (C 'H') 0.35 Nothing "Specialized access conditions exist.", + MetricValue "Medium" (C 'M') 0.61 Nothing "The access conditions are somewhat specialized.", + MetricValue "Low" (C 'L') 0.71 Nothing "Specialized access conditions or extenuating circumstances do not exist." + ], + MetricInfo + "Authentication" + "Au" + True + [ MetricValue "Multiple" (C 'M') 0.45 Nothing "Exploiting the vulnerability requires that the attacker authenticate two or more times, even if the same credentials are used each time.", + MetricValue "Single" (C 'S') 0.56 Nothing "The vulnerability requires an attacker to be logged into the system (such as at a command line or via a desktop session or web interface).", + MetricValue "None" (C 'N') 0.704 Nothing "Authentication is not required to exploit the vulnerability." + ], + MetricInfo + "Confidentiality Impact" + "C" + True + [ mkNone "There is no impact to the confidentiality of the system.", + mkPartial "There is considerable informational disclosure.", + mkComplete "There is total information disclosure, resulting in all system files being revealed." + ], + MetricInfo + "Integrity Impact" + "I" + True + [ mkNone "There is no impact to the integrity of the system.", + mkPartial "Modification of some system files or information is possible, but the attacker does not have control over what can be modified, or the scope of what the attacker can affect is limited.", + mkComplete "There is a total compromise of system integrity." + ], + MetricInfo + "Availability Impact" + "A" + True + [ mkNone "There is no impact to the availability of the system.", + mkPartial "There is reduced performance or interruptions in resource availability.", + mkComplete "There is a total shutdown of the affected resource." + ] + ] + mkNone = MetricValue "None" (C 'N') 0 Nothing + mkPartial = MetricValue "Partial" (C 'P') 0.275 Nothing + mkComplete = MetricValue "Complete" (C 'C') 0.660 Nothing + +validateCvss20 :: [Metric] -> Either CVSSError [Metric] +validateCvss20 metrics = do + traverse_ (\t -> t metrics) [validateUnique, validateKnown cvss20, validateRequired cvss20] + pure metrics + +-- | Implementation of section 3.2.1. "Base Equation" +cvss20score :: [Metric] -> (Rating, Float) +cvss20score metrics = (toRating score, score) + where + score = round_to_1_decimal ((0.6 * impact + 0.4 * exploitability - 1.5) * fImpact) + impact = 10.41 * (1 - (1 - gm "Confidentiality Impact") * (1 - gm "Integrity Impact") * (1 - gm "Availability Impact")) + exploitability = 20 * gm "Access Vector" * gm "Access Complexity" * gm "Authentication" + fImpact + | impact == 0 = 0 + | otherwise = 1.176 + + round_to_1_decimal :: Float -> Float + round_to_1_decimal x = fromIntegral @Int (round (x * 10)) / 10 + + gm :: Text -> Float + gm = getMetricValue cvss20 metrics 0 + +-- | Check for duplicates metric +-- +-- >>> validateUnique [("AV", (C 'N')), ("AC", (C 'L')), ("AV", (C 'L'))] +-- Left "Duplicated \"AV\"" +validateUnique :: [Metric] -> Either CVSSError () +validateUnique = traverse_ checkDouble . group . sort . map mName + where + checkDouble [] = error "The impossible have happened" + checkDouble [_] = pure () + checkDouble (MetricShortName n : _) = Left (DuplicateMetric n) + +-- | Check for unknown metric +-- +-- >>> validateKnown [("AV", (C 'M'))] +-- Left "Unknown value: (C 'M')" +-- +-- >>> validateKnown [("AW", (C 'L'))] +-- Left "Unknown metric: \"AW\"" +validateKnown :: CVSSDB -> [Metric] -> Either CVSSError () +validateKnown db = traverse_ checkKnown + where + checkKnown (Metric name char) = do + mi <- case find (\mi -> miShortName mi == name) (allMetrics db) of + Nothing -> Left (UnknownMetric (coerce name)) + Just m -> pure m + case find (\mv -> mvChar mv == char) (miValues mi) of + Nothing -> Left (UnknownValue (coerce name) (coerce char)) + Just _ -> pure () + +-- | Check for required metric +-- +-- >>> validateRequired [] +-- Left "Missing \"Attack Vector\"" +validateRequired :: CVSSDB -> [Metric] -> Either CVSSError () +validateRequired db metrics = traverse_ checkRequired (allMetrics db) + where + checkRequired mi + | miRequired mi, + Nothing <- find (\metric -> miShortName mi == mName metric) metrics = + Left (MissingRequiredMetric (miName mi)) + | otherwise = pure () diff --git a/code/cvss/test/Spec.hs b/code/cvss/test/Spec.hs new file mode 100644 index 00000000..01d48fdf --- /dev/null +++ b/code/cvss/test/Spec.hs @@ -0,0 +1,36 @@ +{-# LANGUAGE OverloadedStrings #-} + +module Main where + +import Control.Monad +import Data.Text (Text) +import qualified Security.CVSS as CVSS +import Test.Tasty +import Test.Tasty.HUnit + +main :: IO () +main = defaultMain $ + testCase "Security.CVSS" $ do + forM_ examples $ \(cvssString, score, rating) -> do + case CVSS.parseCVSS cvssString of + Left e -> assertFailure (show e) + Right cvss -> do + CVSS.cvssScore cvss @?= (rating, score) + CVSS.cvssVectorString cvss @?= cvssString + CVSS.cvssVectorStringOrdered cvss @?= cvssString + +examples :: [(Text, Float, CVSS.Rating)] +examples = + [ ("CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:N/I:L/A:N", 5.8, CVSS.Medium) + , ("CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:L/I:L/A:N", 6.4, CVSS.Medium) + , ("CVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:U/C:L/I:N/A:N", 3.1, CVSS.Low) + , ("CVSS:3.0/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N", 6.1, CVSS.Medium) + , ("CVSS:3.0/AV:N/AC:L/PR:L/UI:N/S:C/C:L/I:L/A:N", 6.4, CVSS.Medium) + , ("CVSS:3.0/AV:N/AC:H/PR:N/UI:R/S:U/C:L/I:N/A:N", 3.1, CVSS.Low) + , ("CVSS:3.0/AV:L/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:N", 4.0, CVSS.Medium) + , ("CVSS:3.0/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H", 9.9, CVSS.Critical) + , ("CVSS:3.0/AV:L/AC:L/PR:H/UI:N/S:U/C:L/I:L/A:L", 4.2, CVSS.Medium) + , ("AV:N/AC:L/Au:N/C:N/I:N/A:C", 7.8, CVSS.High) + , ("AV:N/AC:L/Au:N/C:C/I:C/A:C", 10, CVSS.Critical) + , ("AV:L/AC:H/Au:N/C:C/I:C/A:C", 6.2, CVSS.Medium) + ] diff --git a/code/hsec-core/.gitignore b/code/hsec-core/.gitignore new file mode 100644 index 00000000..c5e63c97 --- /dev/null +++ b/code/hsec-core/.gitignore @@ -0,0 +1,30 @@ +##### Haskell +dist +dist-* +cabal-dev +*.o +*.hi +*.hie +*.chi +*.chs.h +*.dyn_o +*.dyn_hi +.hpc +.hsenv +.cabal-sandbox/ +cabal.sandbox.config +*.prof +*.aux +*.hp +*.eventlog +.stack-work/ +cabal.project.local +cabal.project.local~ +.HTF/ +.ghc.environment.* +build +bin-* + +result +.direnv +.env diff --git a/code/hsec-core/CHANGELOG.md b/code/hsec-core/CHANGELOG.md new file mode 100644 index 00000000..e69de29b diff --git a/code/hsec-core/README.md b/code/hsec-core/README.md new file mode 100644 index 00000000..93d792e4 --- /dev/null +++ b/code/hsec-core/README.md @@ -0,0 +1,15 @@ +# hsec-core + +`hesc-core` aims to support [Haskell advisories database](https://github.com/haskell/security-advisories). + +## Building + +We aim to support both regular cabal-based and nix-based builds. + +## Testing + +Run (and auto update) the golden test: + +```ShellSession +cabal test -O0 --test-show-details=direct --test-option=--accept +``` diff --git a/code/hsec-core/hsec-core.cabal b/code/hsec-core/hsec-core.cabal new file mode 100644 index 00000000..f783d9a0 --- /dev/null +++ b/code/hsec-core/hsec-core.cabal @@ -0,0 +1,67 @@ +cabal-version: 2.4 +name: hsec-core +version: 0.2.0.1 + +-- A short (one-line) description of the package. +synopsis: Core package representing Haskell advisories + +-- A longer description of the package. +description: Core package representing Haskell advisories. + +-- A URL where users can report bugs. +-- bug-reports: + +-- The license under which the package is released. +license: BSD-3-Clause +author: Haskell Security Response Team +maintainer: security-advisories@haskell.org + +-- A copyright notice. +-- copyright: +category: Data +extra-doc-files: CHANGELOG.md + +tested-with: + GHC ==8.10.7 || ==9.0.2 || ==9.2.8 || ==9.4.8 || ==9.6.3 || ==9.8.1 + +library + exposed-modules: + Security.Advisories.Core.Advisory + Security.Advisories.Core.HsecId + + build-depends: + , base >=4.14 && <4.20 + , Cabal-syntax >=3.8.1.0 && <3.13 + , cvss >= 0.2 && < 0.3 + , osv >= 0.1 && < 0.2 + , pandoc-types >=1.22 && <2 + , safe >=0.3 && <0.4 + , text >=1.2 && <3 + , time >=1.9 && <1.14 + + -- , commonmark ^>=0.2.2 + -- , commonmark-pandoc >=0.2 && <0.3 + -- , containers >=0.6 && <0.7 + -- , mtl >=2.2 && <2.4 + hs-source-dirs: src + default-language: Haskell2010 + ghc-options: + -Wall -Wcompat -Widentities -Wincomplete-record-updates + -Wincomplete-uni-patterns -Wpartial-fields -Wredundant-constraints + +test-suite spec + type: exitcode-stdio-1.0 + hs-source-dirs: test + main-is: Spec.hs + build-depends: + , base <5 + , cvss + , hsec-core + , tasty <1.5 + , tasty-hunit <0.11 + , text + + default-language: Haskell2010 + ghc-options: + -Wall -Wcompat -Widentities -Wincomplete-record-updates + -Wincomplete-uni-patterns -Wpartial-fields -Wredundant-constraints diff --git a/code/hsec-core/src/Security/Advisories/Core/Advisory.hs b/code/hsec-core/src/Security/Advisories/Core/Advisory.hs new file mode 100644 index 00000000..92ef84d7 --- /dev/null +++ b/code/hsec-core/src/Security/Advisories/Core/Advisory.hs @@ -0,0 +1,149 @@ +{-# LANGUAGE DerivingVia, OverloadedStrings #-} + +module Security.Advisories.Core.Advisory + ( Advisory(..) + -- * Supporting types + , Affected(..) + , CAPEC(..) + , CWE(..) + , Architecture(..) + , AffectedVersionRange(..) + , OS(..) + , Keyword(..) + , ComponentIdentifier(..) + , GHCComponent(..) + , ghcComponentToText + , ghcComponentFromText + ) + where + +import Data.Text (Text) +import Data.Time (UTCTime) +import Distribution.Types.Version (Version) +import Distribution.Types.VersionRange (VersionRange) + +import Text.Pandoc.Definition (Pandoc) + +import Security.Advisories.Core.HsecId (HsecId) +import qualified Security.CVSS as CVSS +import Security.OSV (Reference) + +data Advisory = Advisory + { advisoryId :: HsecId + , advisoryModified :: UTCTime + , advisoryPublished :: UTCTime + , advisoryCAPECs :: [CAPEC] + , advisoryCWEs :: [CWE] + , advisoryKeywords :: [Keyword] + , advisoryAliases :: [Text] + , advisoryRelated :: [Text] + , advisoryAffected :: [Affected] + , advisoryReferences :: [Reference] + , advisoryPandoc :: Pandoc -- ^ Parsed document, without TOML front matter + , advisoryHtml :: Text + , advisorySummary :: Text + -- ^ A one-line, English textual summary of the vulnerability + , advisoryDetails :: Text + -- ^ Details of the vulnerability (CommonMark), without TOML front matter + } + deriving stock (Show) + +data ComponentIdentifier = Hackage Text | GHC GHCComponent + deriving stock (Show, Eq) + +-- Keep this list in sync with the 'ghcComponentFromText' below +data GHCComponent = GHCCompiler | GHCi | GHCRTS | GHCPkg | RunGHC | IServ | HP2PS | HPC | HSC2HS | Haddock + deriving stock (Show, Eq, Enum, Bounded) + +ghcComponentToText :: GHCComponent -> Text +ghcComponentToText c = case c of + GHCCompiler -> "ghc" + GHCi -> "ghci" + GHCRTS -> "rts" + GHCPkg -> "ghc-pkg" + RunGHC -> "runghc" + IServ -> "ghc-iserv" + HP2PS -> "hp2ps" + HPC -> "hpc" + HSC2HS -> "hsc2hs" + Haddock -> "haddock" + +ghcComponentFromText :: Text -> Maybe GHCComponent +ghcComponentFromText c = case c of + "ghc" -> Just GHCCompiler + "ghci" -> Just GHCi + "rts" -> Just GHCRTS + "ghc-pkg" -> Just GHCPkg + "runghc" -> Just RunGHC + "ghc-iserv" -> Just IServ + "hp2ps" -> Just HP2PS + "hpc" -> Just HPC + "hsc2hs" -> Just HSC2HS + "haddock" -> Just Haddock + _ -> Nothing + +-- | An affected package (or package component). An 'Advisory' must +-- mention one or more packages. +data Affected = Affected + { affectedComponentIdentifier :: ComponentIdentifier + , affectedCVSS :: CVSS.CVSS + , affectedVersions :: [AffectedVersionRange] + , affectedArchitectures :: Maybe [Architecture] + , affectedOS :: Maybe [OS] + , affectedDeclarations :: [(Text, VersionRange)] + } + deriving stock (Eq, Show) + +newtype CAPEC = CAPEC {unCAPEC :: Integer} + deriving stock (Eq, Show) + +newtype CWE = CWE {unCWE :: Integer} + deriving stock (Eq, Show) + +data Architecture + = AArch64 + | Alpha + | Arm + | HPPA + | HPPA1_1 + | I386 + | IA64 + | M68K + | MIPS + | MIPSEB + | MIPSEL + | NIOS2 + | PowerPC + | PowerPC64 + | PowerPC64LE + | RISCV32 + | RISCV64 + | RS6000 + | S390 + | S390X + | SH4 + | SPARC + | SPARC64 + | VAX + | X86_64 + deriving stock (Eq, Show, Enum, Bounded) + +data OS + = Windows + | MacOS + | Linux + | FreeBSD + | Android + | NetBSD + | OpenBSD + deriving stock (Eq, Show, Enum, Bounded) + +newtype Keyword = Keyword {unKeyword :: Text} + deriving stock (Eq, Ord) + deriving (Show) via Text + +data AffectedVersionRange = AffectedVersionRange + { affectedVersionRangeIntroduced :: Version, + affectedVersionRangeFixed :: Maybe Version + } + deriving stock (Eq, Show) diff --git a/code/hsec-core/src/Security/Advisories/Core/HsecId.hs b/code/hsec-core/src/Security/Advisories/Core/HsecId.hs new file mode 100644 index 00000000..e1155cf2 --- /dev/null +++ b/code/hsec-core/src/Security/Advisories/Core/HsecId.hs @@ -0,0 +1,93 @@ +module Security.Advisories.Core.HsecId + ( + HsecId + , hsecIdYear + , hsecIdSerial + , mkHsecId + , placeholder + , isPlaceholder + , parseHsecId + , printHsecId + , nextHsecId + , getNextHsecId + ) where + +import Control.Monad (guard, join) + +import Data.Time (getCurrentTime, utctDay) +import Data.Time.Calendar.OrdinalDate (toOrdinalDate) + +import Safe (readMay) + +data HsecId = HsecId Integer Integer + deriving (Eq, Ord) + +instance Show HsecId where + show = printHsecId + +-- | Make an 'HsecId'. Year and serial must both be positive, or +-- else both must be zero (the 'placeholder'). +mkHsecId + :: Integer -- ^ Year + -> Integer -- ^ Serial number within year + -> Maybe HsecId +mkHsecId y n + | y > 0 && n > 0 || y == 0 && n == 0 = Just $ HsecId y n + | otherwise = Nothing + +hsecIdYear :: HsecId -> Integer +hsecIdYear (HsecId y _) = y + +hsecIdSerial :: HsecId -> Integer +hsecIdSerial (HsecId _ n) = n + +-- | The placeholder ID: __HSEC-0000-0000__. +-- See also 'isPlaceholder'. +placeholder :: HsecId +placeholder = HsecId 0 0 + +-- | Test whether an ID is the 'placeholder' +isPlaceholder :: HsecId -> Bool +isPlaceholder = (==) placeholder + +-- | Parse an 'HsecId'. The 'placeholder' is accepted. +parseHsecId :: String -> Maybe HsecId +parseHsecId s = case s of + 'H':'S':'E':'C':'-':t -> + let + (y, t') = break (== '-') t + n = drop 1 t' + in do + guard $ length y >= 4 -- year must have at least 4 digits + guard $ length n >= 4 -- serial must have at least 4 digits + join $ mkHsecId <$> readMay y <*> readMay n + _ -> Nothing + +printHsecId :: HsecId -> String +printHsecId (HsecId y n) = "HSEC-" <> pad (show y) <> "-" <> pad (show n) + where + pad s = replicate (4 - length s) '0' <> s + +-- | Given a year and an HSEC ID, return a larger HSEC ID. This +-- function, when given the current year and the greatest allocated +-- HSEC ID, returns the next HSEC ID to allocate. +-- +nextHsecId + :: Integer -- ^ Current year + -> HsecId + -> HsecId +nextHsecId curYear (HsecId idYear n) + | curYear > idYear = HsecId curYear 1 + | otherwise = HsecId idYear (n + 1) + +-- | Get the current time, and return an HSEC ID greater than the +-- given HSEC ID. The year of the returned HSEC ID is the current +-- year. +-- +getNextHsecId + :: HsecId + -> IO HsecId +getNextHsecId oldId = do + t <- getCurrentTime + let (year, _dayOfYear) = toOrdinalDate (utctDay t) + pure $ nextHsecId year oldId diff --git a/code/hsec-core/test/Spec.hs b/code/hsec-core/test/Spec.hs new file mode 100644 index 00000000..52c35ba7 --- /dev/null +++ b/code/hsec-core/test/Spec.hs @@ -0,0 +1,10 @@ +module Main where + +import Test.Tasty + +main :: IO () +main = + defaultMain $ + testGroup + "Tests" + [] diff --git a/code/hsec-sync/.gitignore b/code/hsec-sync/.gitignore new file mode 100644 index 00000000..c5e63c97 --- /dev/null +++ b/code/hsec-sync/.gitignore @@ -0,0 +1,30 @@ +##### Haskell +dist +dist-* +cabal-dev +*.o +*.hi +*.hie +*.chi +*.chs.h +*.dyn_o +*.dyn_hi +.hpc +.hsenv +.cabal-sandbox/ +cabal.sandbox.config +*.prof +*.aux +*.hp +*.eventlog +.stack-work/ +cabal.project.local +cabal.project.local~ +.HTF/ +.ghc.environment.* +build +bin-* + +result +.direnv +.env diff --git a/code/hsec-sync/CHANGELOG.md b/code/hsec-sync/CHANGELOG.md new file mode 100644 index 00000000..456d3824 --- /dev/null +++ b/code/hsec-sync/CHANGELOG.md @@ -0,0 +1,7 @@ +## 0.2.0.0 + +* Rewrite, using `hsec-tools` snapshots + +## 0.1.0.0 + +* Introduction, `git`-based diff --git a/code/hsec-sync/README.md b/code/hsec-sync/README.md new file mode 100644 index 00000000..cefe0b35 --- /dev/null +++ b/code/hsec-sync/README.md @@ -0,0 +1,29 @@ +# hsec-sync + +Synchronize with the [Haskell advisories database](https://github.com/haskell/security-advisories). + +## Building + +We aim to support both regular cabal-based and nix-based builds. + +## Design + +[hsec-tools](../hsec-tools/) is the main entry point for dealing with [security advisories](https://github.com/haskell/security-advisories). + +Libraries implementors and services providers will mainly be interested by +`Security.Advisories.Queries` and `hsec-tools query` which allows querying +against a directory containing the advisories. + +There are two ways for maintaining this local directory up-to-date: + +* Manually (based on `git` of fetching archive from GitHub) +* Relying on `hsec-sync` (either via `Security.Advisories.Sync.sync` or `hsec-sync sync`) + +![overview](./overview.png) + +The recommended workflow is: + +1. Use `hsec-sync` to ensure having an up-to-date advisories directory (created or updated) +2. Use `hsec-tools` to perform queries against it + +![recommended-workflow](./recommended-workflow.png) diff --git a/code/hsec-sync/app/Main.hs b/code/hsec-sync/app/Main.hs new file mode 100644 index 00000000..38731e31 --- /dev/null +++ b/code/hsec-sync/app/Main.hs @@ -0,0 +1,103 @@ +{-# LANGUAGE OverloadedStrings #-} + +module Main where + +import Control.Monad (join) +import Options.Applicative +import Security.Advisories.Sync +import System.Exit (die) +import System.IO (hPutStrLn, stderr) + +main :: IO () +main = + join $ + customExecParser + (prefs showHelpOnEmpty) + cliOpts + +cliOpts :: ParserInfo (IO ()) +cliOpts = info (commandsParser <**> helper) (fullDesc <> header "Haskell Advisories tools") + where + commandsParser :: Parser (IO ()) + commandsParser = + hsubparser + ( command "sync" (info commandSync (progDesc "Synchronize a local Haskell Security Advisory repository snapshot")) + <> command "status" (info commandStatus (progDesc "Check the status of a local Haskell Security Advisory repository snapshot")) + ) + +commandSync :: Parser (IO ()) +commandSync = go <$> repositoryParser + where + go snapshot = do + result <- sync snapshot + case result of + Left e -> + die e + Right s -> do + putStrLn $ + "Snapshot at " + <> show (snapshotRoot snapshot) + <> " from " + <> show (getSnapshotUrl $ snapshotUrl snapshot) + putStrLn $ + case s of + Created -> "Snapshot just created" + Updated -> "Snapshot updated" + AlreadyUpToDate -> "Snapshot already up-to-date" + +commandStatus :: Parser (IO ()) +commandStatus = go <$> repositoryParser + where + go snapshot = do + result <- status snapshot + hPutStrLn stderr $ + case result of + DirectoryMissing -> "Directory is missing" + DirectoryIncoherent -> "Directory is incoherent" + DirectoryUpToDate -> "Repository is up-to-date" + DirectoryOutDated -> "Repository is out-dated" + +repositoryParser :: Parser Snapshot +repositoryParser = + mkSnapshotSnapshot + <$> strOption + ( long "snapshot-root" + <> short 'd' + <> metavar "SNAPSHOT-ROOT" + <> value (snapshotRoot defaultSnapshot) + ) + <*> (fmap Left repositoryGithubParser <|> fmap Right repositoryUrlParser) + where mkSnapshotSnapshot root params = + case params of + Left (repoUrl, repoBranch) -> + githubSnapshot root repoUrl repoBranch + Right snapshotUrl' -> + Snapshot + { snapshotRoot = root, + snapshotUrl = SnapshotUrl snapshotUrl' + } + + +repositoryGithubParser :: Parser (String, String) +repositoryGithubParser = + (,) + <$> strOption + ( long "repository-url" + <> short 'r' + <> metavar "REPOSITORY-URL" + <> value "https://github.com/haskell/security-advisories" + ) + <*> strOption + ( long "repository-branch" + <> short 'b' + <> metavar "REPOSITORY-BRANCH" + <> value "generated/snapshot-export" + ) + +repositoryUrlParser :: Parser String +repositoryUrlParser = + strOption + ( long "archive-url" + <> short 'u' + <> metavar "ARCHIVE-URL" + ) diff --git a/code/hsec-sync/hsec-sync.cabal b/code/hsec-sync/hsec-sync.cabal new file mode 100644 index 00000000..081e600a --- /dev/null +++ b/code/hsec-sync/hsec-sync.cabal @@ -0,0 +1,101 @@ +cabal-version: 2.4 +name: hsec-sync +version: 0.2.0.1 + +-- A short (one-line) description of the package. +synopsis: Synchronize with the Haskell security advisory database + +-- A longer description of the package. +description: Synchronize with the Haskell security advisory database. + +-- A URL where users can report bugs. +-- bug-reports: + +-- The license under which the package is released. +license: BSD-3-Clause +author: Gautier DI FOLCO +maintainer: gautier.difolco@gmail.com + +-- A copyright notice. +-- copyright: +category: Data +extra-doc-files: CHANGELOG.md, overview.png, recommended-workflow.png +tested-with: + GHC ==8.10.7 || ==9.0.2 || ==9.2.8 || ==9.4.8 || ==9.6.3 || ==9.8.1 + +library + exposed-modules: Security.Advisories.Sync + other-modules: + Security.Advisories.Sync.Snapshot + Security.Advisories.Sync.Url + + build-depends: + , aeson >=2.0 && <2.3 + , base >=4.14 && <4.21 + , bytestring >=0.10 && <0.13 + , directory >=1.3 && <1.4 + , either >=5.0 && <5.1 + , extra >=1.7 && <1.8 + , feed >=1.3 && <1.4 + , filepath >=1.4 && <1.6 + , hsec-core ^>=0.2 + , http-client >=0.7.0 && <0.8 + , lens >=5.1 && <5.4 + , tar >=0.5 && <0.7 + , tar-conduit >=0.3 && <0.5 + , temporary >=1 && <2 + , text >=1.2 && <3 + , time >=1.9 && <1.15 + , transformers >=0.5 && <0.7 + , wreq >=0.5 && <0.6 + , zlib >=0.6 && <0.8 + + hs-source-dirs: src + default-language: Haskell2010 + ghc-options: + -Wall -Wcompat -Widentities -Wincomplete-record-updates + -Wincomplete-uni-patterns -Wpartial-fields -Wredundant-constraints + +executable hsec-sync + main-is: Main.hs + + -- Modules included in this executable, other than Main. + -- other-modules: + + -- LANGUAGE extensions used by modules in this package. + -- other-extensions: + build-depends: + , aeson >=2.0.1.0 && <3 + , base >=4.14 && <4.20 + , bytestring >=0.10 && <0.13 + , filepath >=1.4 && <1.5 + , hsec-sync + , optparse-applicative >=0.17 && <0.19 + , text >=1.2 && <3 + + hs-source-dirs: app + default-language: Haskell2010 + ghc-options: + -Wall -Wcompat -Widentities -Wincomplete-record-updates + -Wincomplete-uni-patterns -Wpartial-fields -Wredundant-constraints + +test-suite spec + type: exitcode-stdio-1.0 + hs-source-dirs: test + main-is: Spec.hs + other-modules: Spec.SyncSpec + build-depends: + , base <5 + , directory + , filepath + , hsec-sync + , tasty <1.5 + , tasty-hunit <0.11 + , temporary >=1 && <2 + , text + , time + + default-language: Haskell2010 + ghc-options: + -Wall -Wcompat -Widentities -Wincomplete-record-updates + -Wincomplete-uni-patterns -Wpartial-fields -Wredundant-constraints diff --git a/code/hsec-sync/overview.png b/code/hsec-sync/overview.png new file mode 100644 index 00000000..6011609f Binary files /dev/null and b/code/hsec-sync/overview.png differ diff --git a/code/hsec-sync/recommended-workflow.png b/code/hsec-sync/recommended-workflow.png new file mode 100644 index 00000000..6c8ec724 Binary files /dev/null and b/code/hsec-sync/recommended-workflow.png differ diff --git a/code/hsec-sync/src/Security/Advisories/Sync.hs b/code/hsec-sync/src/Security/Advisories/Sync.hs new file mode 100644 index 00000000..589fba7e --- /dev/null +++ b/code/hsec-sync/src/Security/Advisories/Sync.hs @@ -0,0 +1,93 @@ +{-# LANGUAGE DerivingStrategies #-} +{-# LANGUAGE LambdaCase #-} + +module Security.Advisories.Sync + ( Snapshot (..), + SnapshotUrl (..), + defaultSnapshot, + githubSnapshot, + SyncStatus (..), + sync, + RepositoryStatus (..), + status, + ) +where + +import Control.Monad.IO.Class (liftIO) +import Control.Monad.Trans.Except (runExceptT, withExceptT) +import Security.Advisories.Sync.Snapshot +import Security.Advisories.Sync.Url + +data Snapshot = Snapshot + { snapshotRoot :: FilePath, + snapshotUrl :: SnapshotUrl + } + +defaultSnapshot :: Snapshot +defaultSnapshot = + githubSnapshot + "security-advisories" + "https://github.com/haskell/security-advisories" + "generated/snapshot-export" + +githubSnapshot :: FilePath -> String -> String -> Snapshot +githubSnapshot root repoUrl repoBranch = + Snapshot + { snapshotRoot = root, + snapshotUrl = SnapshotUrl $ ensureFile (mkUrl [repoUrl, "archive/refs/heads", repoBranch]) <> ".tar.gz" + } + +data SyncStatus + = Created + | Updated + | AlreadyUpToDate + deriving stock (Eq, Show) + +sync :: Snapshot -> IO (Either String SyncStatus) +sync s = + runExceptT $ do + snapshotStatus <- liftIO $ snapshotRepositoryStatus $ snapshotRoot s + ensuredStatus <- withExceptT explainSnapshotError $ ensureSnapshot (snapshotRoot s) (snapshotUrl s) snapshotStatus + case ensuredStatus of + SnapshotRepositoryCreated -> + return Created + SnapshotRepositoryExisting -> do + repoStatus <- liftIO $ status' s snapshotStatus + if repoStatus == DirectoryOutDated + then do + withExceptT explainSnapshotError $ overwriteSnapshot (snapshotRoot s) (snapshotUrl s) + return Updated + else return AlreadyUpToDate + +data RepositoryStatus + = DirectoryMissing + | -- | Used when expected files/directories are missing or not readable + DirectoryIncoherent + | DirectoryUpToDate + | DirectoryOutDated + deriving stock (Eq, Show) + +status :: Snapshot -> IO RepositoryStatus +status s = + status' s =<< snapshotRepositoryStatus (snapshotRoot s) + +status' :: Snapshot -> SnapshotRepositoryStatus -> IO RepositoryStatus +status' s = + \case + SnapshotDirectoryMissing -> + return DirectoryMissing + SnapshotDirectoryIncoherent -> + return DirectoryIncoherent + SnapshotDirectoryInitialized -> do + snapshotInfo <- getDirectorySnapshotInfo $ snapshotRoot s + case snapshotInfo of + Left _ -> + return DirectoryOutDated + Right info -> do + update <- runExceptT $ latestUpdate $ snapshotUrl s + return $ + case update of + Right latestETag | latestETag == etag info -> + DirectoryUpToDate + _ -> + DirectoryOutDated diff --git a/code/hsec-sync/src/Security/Advisories/Sync/Snapshot.hs b/code/hsec-sync/src/Security/Advisories/Sync/Snapshot.hs new file mode 100644 index 00000000..d164790a --- /dev/null +++ b/code/hsec-sync/src/Security/Advisories/Sync/Snapshot.hs @@ -0,0 +1,214 @@ +{-# LANGUAGE DerivingStrategies #-} +{-# LANGUAGE LambdaCase #-} +{-# LANGUAGE OverloadedStrings #-} + +-- | +-- +-- Helpers for deriving advisory metadata from a Snapshot s. +module Security.Advisories.Sync.Snapshot + ( SnapshotDirectoryInfo (..), + ETag (..), + SnapshotError (..), + explainSnapshotError, + SnapshotUrl (..), + SnapshotRepositoryEnsuredStatus (..), + ensureSnapshot, + getDirectorySnapshotInfo, + overwriteSnapshot, + SnapshotRepositoryStatus (..), + snapshotRepositoryStatus, + latestUpdate, + ) +where + +import qualified Codec.Archive.Tar as Tar +import qualified Codec.Archive.Tar.Entry as Tar +import qualified Codec.Compression.GZip as GZip +import Control.Exception (Exception (displayException), IOException, try) +import Control.Lens +import Control.Monad.Extra (unlessM, whenM) +import Control.Monad.IO.Class (liftIO) +import Control.Monad.Trans.Except (ExceptT, runExceptT, throwE, withExceptT) +import qualified Data.ByteString.Lazy as BL +import Data.Either.Combinators (whenLeft, fromRight) +import qualified Data.Text as T +import qualified Data.Text.Encoding as T +import qualified Data.Text.IO as T +import Network.HTTP.Client (HttpException (..), HttpExceptionContent (..)) +import Network.Wreq +import qualified System.Directory as D +import System.FilePath ((), hasTrailingPathSeparator, joinPath, splitPath) +import System.IO.Temp (withSystemTempDirectory) + +data SnapshotError + = SnapshotDirectoryMissingE + | SnapshotIncoherent String + | SnapshotProcessError SnapshotProcessError + +data SnapshotProcessError + = FetchSnapshotArchive String + | DirectorySetupSnapshotArchive IOException + | ExtractSnapshotArchive IOException + +explainSnapshotError :: SnapshotError -> String +explainSnapshotError = + \case + SnapshotDirectoryMissingE -> "Snapshot directory is missing" + SnapshotIncoherent e -> "Snapshot directory is incoherent: " <> e + SnapshotProcessError e -> + unlines + [ "An exception occurred during snapshot processing:", + case e of + FetchSnapshotArchive x -> "Fetching failed with: " <> show x + DirectorySetupSnapshotArchive x -> "Directory setup got an exception: " <> show x + ExtractSnapshotArchive x -> "Extraction got an exception: " <> displayException x + ] + +newtype SnapshotUrl = SnapshotUrl {getSnapshotUrl :: String} + +data SnapshotRepositoryStatus + = SnapshotDirectoryMissing + | SnapshotDirectoryInitialized + | SnapshotDirectoryIncoherent + +snapshotRepositoryStatus :: FilePath -> IO SnapshotRepositoryStatus +snapshotRepositoryStatus root = do + dirExists <- D.doesDirectoryExist root + if dirExists + then do + dirAdvisoriesExists <- D.doesDirectoryExist $ root "advisories" + etagMetadataExists <- D.doesFileExist $ root "snapshot-etag" + return $ + if dirAdvisoriesExists && etagMetadataExists + then SnapshotDirectoryInitialized + else SnapshotDirectoryIncoherent + else return SnapshotDirectoryMissing + +data SnapshotRepositoryEnsuredStatus + = SnapshotRepositoryCreated + | SnapshotRepositoryExisting + +ensureSnapshot :: + FilePath -> + SnapshotUrl -> + SnapshotRepositoryStatus -> + ExceptT SnapshotError IO SnapshotRepositoryEnsuredStatus +ensureSnapshot root url = + \case + SnapshotDirectoryMissing -> do + overwriteSnapshot root url + return SnapshotRepositoryCreated + SnapshotDirectoryIncoherent -> do + overwriteSnapshot root url + return SnapshotRepositoryCreated + SnapshotDirectoryInitialized -> + return SnapshotRepositoryExisting + +overwriteSnapshot :: FilePath -> SnapshotUrl -> ExceptT SnapshotError IO () +overwriteSnapshot root url = + withExceptT SnapshotProcessError $ do + ensuringPerformed <- liftIO $ try $ ensureEmptyRoot root + whenLeft ensuringPerformed $ + throwE . DirectorySetupSnapshotArchive + + resultE <- liftIO $ try $ get $ getSnapshotUrl url + case resultE of + Left e -> + throwE $ + FetchSnapshotArchive $ + case e of + InvalidUrlException url' reason -> + "Invalid URL " <> show url' <> ": " <> show reason + HttpExceptionRequest _ content -> + case content of + StatusCodeException response body -> + "Request (GET " <> getSnapshotUrl url <> ") failed with " <> show (response ^. responseStatus) <> ": " <> show body + _ -> + "Request (GET " <> getSnapshotUrl url <> ") failed: " <> show content + Right result -> do + performed <- + liftIO $ + try $ + withSystemTempDirectory "security-advisories" $ \tempDir -> do + let archivePath = tempDir <> "/snapshot-export.tar.gz" + BL.writeFile archivePath $ result ^. responseBody + contents <- BL.readFile archivePath + let fixEntry e = e { Tar.entryTarPath = fixEntryPath $ Tar.entryTarPath e } + fixEntryPath :: Tar.TarPath -> Tar.TarPath + fixEntryPath p = + fromRight p $ + maybe + (Right p) + (Tar.toTarPath (hasTrailingPathSeparator $ Tar.fromTarPath p) . joinPath) $ + stripRootPath $ + splitPath $ + Tar.fromTarPath p + stripRootPath = + \case + ("/":_:p:ps) -> Just (p:ps) + (_:p:ps) -> Just (p:ps) + [p] | hasTrailingPathSeparator p -> Nothing + ps -> Just ps + Tar.unpack root $ Tar.mapEntriesNoFail fixEntry $ Tar.read $ GZip.decompress contents + whenLeft performed $ + throwE . ExtractSnapshotArchive + + etagWritten <- + liftIO $ + try $ + T.writeFile (root "snapshot-etag") $ + T.decodeUtf8 $ + result ^. responseHeader "etag" + whenLeft etagWritten $ + throwE . ExtractSnapshotArchive + +ensureEmptyRoot :: FilePath -> IO () +ensureEmptyRoot root = do + D.createDirectoryIfMissing False root + + whenM (D.doesDirectoryExist $ root "advisories") $ + D.removeDirectoryRecursive $ + root "advisories" + + whenM (D.doesFileExist $ root "snapshot-etag") $ + D.removeFile $ + root "snapshot-etag" + +newtype SnapshotDirectoryInfo = SnapshotDirectoryInfo + { etag :: ETag + } + deriving stock (Eq, Show) + +newtype ETag = ETag T.Text + deriving stock (Eq, Show) + +getDirectorySnapshotInfo :: FilePath -> IO (Either SnapshotError SnapshotDirectoryInfo) +getDirectorySnapshotInfo root = + runExceptT $ do + let metadataPath = root "snapshot-etag" + unlessM (liftIO $ D.doesFileExist metadataPath) $ + throwE SnapshotDirectoryMissingE + + SnapshotDirectoryInfo . ETag <$> liftIO (T.readFile metadataPath) + +latestUpdate :: SnapshotUrl -> ExceptT SnapshotError IO ETag +latestUpdate url = + withExceptT SnapshotProcessError $ do + resultE <- liftIO $ try $ headWith (defaults & redirects .~ 3) $ getSnapshotUrl url + case resultE of + Left e -> + throwE $ + FetchSnapshotArchive $ + case e of + InvalidUrlException url' reason -> + "Invalid URL " <> show url' <> ": " <> show reason + HttpExceptionRequest _ content -> + case content of + StatusCodeException response body -> + "Request (HEAD " <> getSnapshotUrl url <> ") failed with " <> show (response ^. responseStatus) <> ": " <> show body + _ -> + "Request (HEAD " <> getSnapshotUrl url <> ") failed: " <> show content + Right result -> + case result ^? responseHeader "etag" of + Nothing -> throwE $ FetchSnapshotArchive "Missing ETag header" + Just rawETag -> return $ ETag $ T.decodeUtf8 rawETag diff --git a/code/hsec-sync/src/Security/Advisories/Sync/Url.hs b/code/hsec-sync/src/Security/Advisories/Sync/Url.hs new file mode 100644 index 00000000..41ff4311 --- /dev/null +++ b/code/hsec-sync/src/Security/Advisories/Sync/Url.hs @@ -0,0 +1,27 @@ +{-# LANGUAGE LambdaCase #-} +module Security.Advisories.Sync.Url + ( mkUrl + , ensureFile + ) +where + +mkUrl :: [String] -> String +mkUrl = foldl1 () + +infixr 5 + +() :: String -> String -> String +"/" ('/' : ys) = '/' : ys +"/" ys = '/' : ys +"" ('/' : ys) = '/' : ys +"" ys = '/' : ys +[x] ('/' : ys) = x : '/' : ys +[x] ys = x : '/' : ys +(x0 : x1 : xs) ys = x0 : ((x1 : xs) ys) + +ensureFile :: String -> String +ensureFile = + \case + "" -> "" + "/" -> "" + (x:xs) -> x : ensureFile xs diff --git a/code/hsec-sync/test/Spec.hs b/code/hsec-sync/test/Spec.hs new file mode 100644 index 00000000..0a5f1552 --- /dev/null +++ b/code/hsec-sync/test/Spec.hs @@ -0,0 +1,14 @@ +{-# LANGUAGE OverloadedStrings #-} + +module Main where + +import Test.Tasty + +import qualified Spec.SyncSpec as SyncSpec + +main :: IO () +main = do + defaultMain $ + testGroup "Tests" + [ SyncSpec.spec + ] diff --git a/code/hsec-sync/test/Spec/SyncSpec.hs b/code/hsec-sync/test/Spec/SyncSpec.hs new file mode 100644 index 00000000..f1b727f6 --- /dev/null +++ b/code/hsec-sync/test/Spec/SyncSpec.hs @@ -0,0 +1,93 @@ +{-# LANGUAGE OverloadedStrings #-} + +module Spec.SyncSpec (spec) where + +import Control.Monad (unless) +import Data.Bifunctor (first) +import Security.Advisories.Sync +import qualified System.Directory as D +import System.Environment (lookupEnv) +import System.FilePath (()) +import System.IO.Temp (withSystemTempDirectory) +import Test.Tasty +import Test.Tasty.HUnit + +spec :: TestTree +spec = testGroup "Sync" [] + +_spec :: TestTree +_spec = + testGroup + "Sync" + [ testGroup + "sync" + [ testCase "Invalid root should fail" $ do + let snapshot = snapshotAt "/dev/advisories" + status snapshot >>= (@?= DirectoryMissing) + isGitHubActionRunner <- lookupEnv "GITHUB_ACTIONS" + unless (isGitHubActionRunner == Just "true") $ do + -- GitHub Action runners let you write anywhere + result <- sync snapshot + first (const ("" :: String)) result @?= Left "" + status snapshot >>= (@?= DirectoryMissing), + testCase "Subdirectory creation should work" $ + withSystemTempDirectory "hsec-sync" $ \p -> do + let snapshot = snapshotAt $ p "snapshot" + status snapshot >>= (@?= DirectoryMissing) + result <- sync snapshot + result @?= Right Created + status snapshot >>= (@?= DirectoryUpToDate), + testCase "With existing subdirectory creation should work" $ + withSystemTempDirectory "hsec-sync" $ \p -> do + D.createDirectory $ p "snapshot" + let snapshot = snapshotAt $ p "snapshot" + result <- sync snapshot + result @?= Right Created, + testCase "Sync twice should be a no-op" $ + withSystemTempDirectory "hsec-sync" $ \p -> do + let snapshot = snapshotAt p + status snapshot >>= (@?= DirectoryIncoherent) + resultCreate <- sync snapshot + resultCreate @?= Right Created + resultResync <- sync snapshot + resultResync @?= Right AlreadyUpToDate, + testCase "Sync behind should update" $ + withSystemTempDirectory "hsec-sync" $ \p -> do + let snapshot = snapshotAt p + resultCreate <- sync snapshot + resultCreate @?= Right Created + writeFile + (p "snapshot.json") + "{\"latestUpdate\":\"2020-03-11T12:26:51Z\",\"snapshotVersion\":\"0.1.0.0\"}" + status snapshot >>= (@?= DirectoryOutDated) + resultResync <- sync snapshot + resultResync @?= Right Updated + status snapshot >>= (@?= DirectoryUpToDate), + testCase "Sync a broken snapshot.json" $ + withSystemTempDirectory "hsec-sync" $ \p -> do + let snapshot = snapshotAt p + resultCreate <- sync snapshot + resultCreate @?= Right Created + writeFile + (p "snapshot.json") + "{\"latestpdate\":\"2020-03-11T12:26:51Z\",\"snapshotVersion\":\"0.1.0.0\"}" + status snapshot >>= (@?= DirectoryIncoherent) + resultResync <- sync snapshot + resultResync @?= Right Updated + status snapshot >>= (@?= DirectoryUpToDate), + testCase "Sync a deleted snapshot.json" $ + withSystemTempDirectory "hsec-sync" $ \p -> do + let snapshot = snapshotAt p + resultCreate <- sync snapshot + resultCreate @?= Right Created + D.removeFile (p "snapshot.json") + status snapshot >>= (@?= DirectoryOutDated) + resultResync <- sync snapshot + resultResync @?= Right Updated + status snapshot >>= (@?= DirectoryIncoherent) + ] + ] + +snapshotAt :: FilePath -> Snapshot +snapshotAt root = + defaultSnapshot {snapshotRoot = root} diff --git a/code/hsec-tools/.gitignore b/code/hsec-tools/.gitignore new file mode 100644 index 00000000..c5e63c97 --- /dev/null +++ b/code/hsec-tools/.gitignore @@ -0,0 +1,30 @@ +##### Haskell +dist +dist-* +cabal-dev +*.o +*.hi +*.hie +*.chi +*.chs.h +*.dyn_o +*.dyn_hi +.hpc +.hsenv +.cabal-sandbox/ +cabal.sandbox.config +*.prof +*.aux +*.hp +*.eventlog +.stack-work/ +cabal.project.local +cabal.project.local~ +.HTF/ +.ghc.environment.* +build +bin-* + +result +.direnv +.env diff --git a/code/hsec-tools/CHANGELOG.md b/code/hsec-tools/CHANGELOG.md new file mode 100644 index 00000000..cd56e671 --- /dev/null +++ b/code/hsec-tools/CHANGELOG.md @@ -0,0 +1,3 @@ +## 0.1.1.0 + +- Redesign index diff --git a/code/hsec-tools/README.md b/code/hsec-tools/README.md new file mode 100644 index 00000000..a5e2e0d3 --- /dev/null +++ b/code/hsec-tools/README.md @@ -0,0 +1,15 @@ +# hsec-tools + +`hesc-tools` aims to support [Haskell advisories database](https://github.com/haskell/security-advisories). + +## Building + +We aim to support both regular cabal-based and nix-based builds. + +## Testing + +Run (and auto update) the golden test: + +```ShellSession +cabal test -O0 --test-show-details=direct --test-option=--accept +``` diff --git a/code/hsec-tools/app/Command/NextID.hs b/code/hsec-tools/app/Command/NextID.hs new file mode 100644 index 00000000..9c581401 --- /dev/null +++ b/code/hsec-tools/app/Command/NextID.hs @@ -0,0 +1,10 @@ +module Command.NextID where + +import Security.Advisories.Core.HsecId (printHsecId, getNextHsecId) +import Security.Advisories.Filesystem (getGreatestId) + +import Util (ensureRepo) + +runNextIDCommand :: Maybe FilePath -> IO () +runNextIDCommand mPath = + ensureRepo mPath >>= getGreatestId >>= getNextHsecId >>= putStrLn . printHsecId diff --git a/code/hsec-tools/app/Command/Reserve.hs b/code/hsec-tools/app/Command/Reserve.hs new file mode 100644 index 00000000..1545d810 --- /dev/null +++ b/code/hsec-tools/app/Command/Reserve.hs @@ -0,0 +1,63 @@ +{-# LANGUAGE LambdaCase #-} + +module Command.Reserve where + +import Control.Monad (when) +import System.Exit (die) +import System.FilePath ((), (<.>)) + +import Security.Advisories.Git + ( add + , commit + , explainGitError + ) +import Security.Advisories.Core.HsecId + ( placeholder + , printHsecId + , getNextHsecId + ) +import Security.Advisories.Filesystem + ( dirNameAdvisories + , dirNameReserved + , getGreatestId + ) + +import Util (ensureRepo) + +-- | How to choose IDs when creating advisories or +-- reservations. +data IdMode + = IdModePlaceholder + -- ^ Create a placeholder ID (e.g. HSEC-0000-0000). Real IDs + -- will be assigned later. + | IdModeAuto + -- ^ Use the next available ID. This option is more likely to + -- result in conflicts when submitting advisories or reservations. + +data CommitFlag = Commit | DoNotCommit + deriving (Eq) + +runReserveCommand :: Maybe FilePath -> IdMode -> CommitFlag -> IO () +runReserveCommand mPath idMode commitFlag = do + repoPath <- ensureRepo mPath + + hsid <- case idMode of + IdModePlaceholder -> pure placeholder + IdModeAuto -> do + curMax <- getGreatestId repoPath + getNextHsecId curMax + + let + advisoriesPath = repoPath dirNameAdvisories + fileName = printHsecId hsid <.> "md" + filePath = advisoriesPath dirNameReserved fileName + writeFile filePath "" -- write empty file + + when (commitFlag == Commit) $ do + let msg = printHsecId hsid <> ": reserve id" + add repoPath [filePath] >>= \case + Left e -> die $ "Failed to update Git index: " <> explainGitError e + Right _ -> pure () + commit repoPath msg >>= \case + Left e -> die $ "Failed to create Git commit: " <> explainGitError e + Right _ -> pure () diff --git a/code/hsec-tools/app/Main.hs b/code/hsec-tools/app/Main.hs new file mode 100644 index 00000000..2eca100f --- /dev/null +++ b/code/hsec-tools/app/Main.hs @@ -0,0 +1,195 @@ +{-# LANGUAGE OverloadedStrings #-} + +module Main where + +import Control.Monad (forM_, join, void, when) +import Control.Monad.Trans.Except (runExceptT, ExceptT (ExceptT), withExceptT, throwE) +import Control.Monad.IO.Class (liftIO) +import qualified Data.Aeson +import qualified Data.ByteString.Lazy as L +import Data.Foldable (for_) +import Data.List (intercalate, isPrefixOf) +import Data.Maybe (fromMaybe) +import qualified Data.Text as T +import qualified Data.Text.IO as T +import Control.Exception (Exception(displayException)) +import Distribution.Parsec (eitherParsec) +import Distribution.Types.VersionRange (VersionRange, anyVersion) +import Options.Applicative +import Security.Advisories +import qualified Security.Advisories.Convert.OSV as OSV +import Security.Advisories.Generate.HTML +import Security.Advisories.Generate.Snapshot +import Security.Advisories.Git +import Security.Advisories.Queries (listVersionRangeAffectedBy) +import Security.Advisories.Filesystem (parseComponentIdentifier) +import System.Exit (die, exitFailure, exitSuccess) +import System.FilePath (takeBaseName) +import System.IO (hPrint, hPutStrLn, stderr) +import Validation (Validation (..)) + +import qualified Command.Reserve +import qualified Command.NextID + +main :: IO () +main = + join $ + customExecParser + (prefs showHelpOnEmpty) + cliOpts + +cliOpts :: ParserInfo (IO ()) +cliOpts = info (commandsParser <**> helper) (fullDesc <> header "Haskell Advisories tools") + where + commandsParser :: Parser (IO ()) + commandsParser = + hsubparser + ( command "check" (info commandCheck (progDesc "Syntax check a single advisory")) + <> command "next-id" (info commandNextID (progDesc "Print the next available HSEC ID")) + <> command "reserve" (info commandReserve (progDesc "Reserve an HSEC ID")) + <> command "osv" (info commandOsv (progDesc "Convert a single advisory to OSV")) + <> command "render" (info commandRender (progDesc "Render a single advisory as HTML")) + <> command "generate-index" (info commandGenerateIndex (progDesc "Generate an HTML index")) + <> command "generate-snapshot" (info commandGenerateSnapshot (progDesc "Generate a snapshot from a Git repository")) + <> command "query" (info commandQuery (progDesc "Run various queries against the database")) + <> command "help" (info commandHelp (progDesc "Show command help")) + ) + +-- | Create an option with a fixed set of values +multiOption :: [(String, a)] -> Mod OptionFields a -> Parser a +multiOption kvs m = option rdr (m <> metavar choices) + where + choices = "{" <> intercalate "|" (fmap fst kvs) <> "}" + errMsg = "must be one of " <> choices + rdr = eitherReader (maybe (Left errMsg) Right . flip lookup kvs) + +commandReserve :: Parser (IO ()) +commandReserve = + Command.Reserve.runReserveCommand + <$> optional (argument str (metavar "REPO")) + <*> multiOption + [ ("placeholder", Command.Reserve.IdModePlaceholder), + ("auto", Command.Reserve.IdModeAuto) + ] + (long "id-mode" <> help "How to assign IDs") + <*> flag + Command.Reserve.DoNotCommit -- default value + Command.Reserve.Commit -- active value + ( long "commit" + <> help "Commit the reservation file" + ) + +commandNextID :: Parser (IO ()) +commandNextID = + Command.NextID.runNextIDCommand + <$> optional (argument str (metavar "REPO")) + +commandCheck :: Parser (IO ()) +commandCheck = + withAdvisory go + <$> optional (argument str (metavar "FILE")) + where + go mPath advisory = do + for_ mPath $ \path -> do + let base = takeBaseName path + when ("HSEC-" `isPrefixOf` base && base /= printHsecId (advisoryId advisory)) $ + die $ + "Filename does not match advisory ID: " <> path + T.putStrLn "no error" + +commandOsv :: Parser (IO ()) +commandOsv = + withAdvisory go + <$> optional (argument str (metavar "FILE")) + where + go _ adv = do + L.putStr (Data.Aeson.encode (OSV.convert adv)) + putChar '\n' + +commandRender :: Parser (IO ()) +commandRender = + withAdvisory (\_ -> T.putStrLn . advisoryHtml) + <$> optional (argument str (metavar "FILE")) + +commandQuery :: Parser (IO ()) +commandQuery = + subparser + ( command "is-affected" (info isAffected (progDesc "Check if a package/version range is marked vulnerable")) + ) + where + isAffected :: Parser (IO ()) + isAffected = + go + <$> argument str (metavar "PACKAGE") + <*> optional (option versionRangeReader (metavar "VERSION-RANGE" <> short 'v' <> long "version-range")) + <*> optional (option str (metavar "ADVISORIES-PATH" <> short 'p' <> long "advisories-path")) + where + go :: T.Text -> Maybe VersionRange -> Maybe FilePath -> IO () + go packageName versionRange advisoriesPath = do + let versionRange' = fromMaybe anyVersion versionRange + maybeAffectedAdvisories <- listVersionRangeAffectedBy (fromMaybe "." advisoriesPath) packageName versionRange' + case maybeAffectedAdvisories of + Validation.Failure errors -> do + T.hPutStrLn stderr "Cannot parse some advisories" + forM_ errors $ + hPrint stderr + exitFailure + Validation.Success [] -> putStrLn "Not affected" + Validation.Success affectedAdvisories -> do + hPutStrLn stderr "Affected by:" + forM_ affectedAdvisories $ \advisory -> + T.hPutStrLn stderr $ "* [" <> T.pack (printHsecId $ advisoryId advisory) <> "] " <> advisorySummary advisory + exitFailure + +commandGenerateIndex :: Parser (IO ()) +commandGenerateIndex = + ( \src dst -> do + renderAdvisoriesIndex src dst + T.putStrLn "Index generated" + ) + <$> argument str (metavar "SOURCE-DIR") + <*> argument str (metavar "DESTINATION-DIR") + +commandGenerateSnapshot :: Parser (IO ()) +commandGenerateSnapshot = + ( \src dst -> do + createSnapshot src dst + T.putStrLn "Snapshot generated" + ) + <$> argument str (metavar "SOURCE-DIR") + <*> argument str (metavar "DESTINATION-DIR") + +commandHelp :: Parser (IO ()) +commandHelp = + ( \mCmd -> + let args = maybe id (:) mCmd ["-h"] + in void $ handleParseResult $ execParserPure defaultPrefs cliOpts args + ) + <$> optional (argument str (metavar "COMMAND")) + +versionRangeReader :: ReadM VersionRange +versionRangeReader = eitherReader eitherParsec + +withAdvisory :: (Maybe FilePath -> Advisory -> IO ()) -> Maybe FilePath -> IO () +withAdvisory go file = do + input <- maybe T.getContents T.readFile file + + oob <- runExceptT $ case file of + Nothing -> throwE StdInHasNoOOB + Just path -> do + ecosystem <- parseComponentIdentifier path + withExceptT GitHasNoOOB $ do + gitInfo <- ExceptT $ liftIO $ getAdvisoryGitInfo path + pure OutOfBandAttributes + { oobPublished = firstAppearanceCommitDate gitInfo + , oobModified = lastModificationCommitDate gitInfo + , oobComponentIdentifier = ecosystem + } + + case parseAdvisory NoOverrides oob input of + Left e -> do + hPutStrLn stderr (displayException e) + exitFailure + Right advisory -> do + go file advisory + exitSuccess diff --git a/code/hsec-tools/app/Util.hs b/code/hsec-tools/app/Util.hs new file mode 100644 index 00000000..b072606a --- /dev/null +++ b/code/hsec-tools/app/Util.hs @@ -0,0 +1,21 @@ +{-# LANGUAGE LambdaCase #-} + +module Util where + +import Data.Maybe (fromMaybe) +import System.Exit (die) + +import Security.Advisories.Filesystem (isSecurityAdvisoriesRepo) +import Security.Advisories.Git (getRepoRoot) + +-- | Ensure the given path (or current directory "." if @Nothing@) +-- is an advisory Git repo. Return the (valid) repo root, or die +-- with an error message. +-- +ensureRepo :: Maybe FilePath -> IO FilePath +ensureRepo mPath = + getRepoRoot (fromMaybe "." mPath) >>= \case + Left _ -> die "Not a git repo" + Right repoPath -> isSecurityAdvisoriesRepo repoPath >>= \case + False -> die "Not a security-advisories repo" + True -> pure repoPath diff --git a/code/hsec-tools/assets/css/default.css b/code/hsec-tools/assets/css/default.css new file mode 100644 index 00000000..17973558 --- /dev/null +++ b/code/hsec-tools/assets/css/default.css @@ -0,0 +1,152 @@ +:root{ + --bg-color:#FFFFFF; + --text-color:#333; + --outline-color:#DB83ED; + --header-color:#5E5184; + --anchor-color:#9E358F; + --anchor-visited-color:#6F5F9C; + --code-bg-color:#FAFAFA; + --filename-bg:#EAEAEA; + --code-color:#383a42; + --code-bg-color:#fafafa; + --code-comment-color:#a0a1a7; + --code-kw-color:#af005f; + --code-name-color:#e45649; + --code-literal-color:#268bd2; + --code-string-color:#cb4b16; + --code-attr-color:#986801; + --code-constructor-color:#5f5faf; + --code-symbol-color:#4078f2; + --code-record-field-color:#c18401; + --code-pragma-color:#2aa198 +} +@media (prefers-color-scheme:dark){ + :root{ + --bg-color:#333; + --text-color:#C9D1D9; + --header-color:#BBA1FF; + --anchor-color:#EB82DC; + --anchor-visited-color:#D5C5FF; + --code-bg-color:transparent; + --filename-bg:#2C2C2C; + --code-color:#C9D1D9; + --code-bg-color:#333; + --code-comment-color:#a0a1a7; + --code-kw-color:#BBA1FF; + --code-name-color:#e45649; + --code-literal-color:#268bd2; + --code-string-color:#cb4b16; + --code-attr-color:#986801; + --code-constructor-color:#d079c9; + --code-symbol-color:var(--code-color); + --code-record-field-color:#c18401; + --code-pragma-color:#2aa198 + } +} +*:focus-visible{ + outline-color:var(--outline-color) +} +body{ + color:var(--text-color); + background-color:var(--bg-color) +} +a{ + color:var(--anchor-color) +} +a:visited{ + color:var(--anchor-visited-color) +} +h1,h2,h3,h4,h5,h6{ + color:var(--header-color) +} +input{ + background-color:rgba(255,255,255,0.06); + color:var(--text-color) +} +.nav-bar{ + text-align: right; +} +.nav-bar ul{ + display: inline-block; + list-style: none; + margin: 0; + padding: 0; +} +.nav-bar li{ + display: inline-block; + vertical-align: middle; + padding: 0; + margin: 0; + height: 100%; + position: relative; +} + *:focus-visible{ + outline-offset:4px; + outline-width:1px +} +body{ + font-size:1.6rem; + margin:0 auto; + max-width:120rem +} +footer{ + margin-top:3rem; + padding:1.2rem 0; + border-top:0.2rem solid #000; + font-size:1.2rem; + color:#555 +} +h1{ + font-size:2.4rem +} +h2{ + font-size:2rem +} +html{ + font-size:62.5%; + font-family:Helvetica,sans-serif +} +table tbody td{ + padding:5px +} +footer{ + padding: 0 2%; + text-align: center; +} +footer .HF{ + height:50px; + line-height:50px; + display:inline-block; + background-repeat:no-repeat; + background-image:url('../images/hf-logo.png'); + background-size:50px; + background-position:left center; + padding-left:60px +} +@media (max-width:319px){ + .nav-bar{ + margin:0 1.5rem 0 0; + } + .nav-bar a{ + display:block; + line-height:1.6 + } +} +@media (min-width:320px){ + .nav-bar{ + margin:0 2rem 0 0; + } + .nav-bar a{ + display:inline; + margin:0 0.6rem + } +} +@media (min-width:640px){ + .nav-bar{ + margin:0 3rem 0 0; + } + .nav-bar a{ + margin:0 0 0 1.2rem; + display:inline + } +} diff --git a/code/hsec-tools/assets/images/hf-logo.png b/code/hsec-tools/assets/images/hf-logo.png new file mode 100644 index 00000000..5a79f4c1 Binary files /dev/null and b/code/hsec-tools/assets/images/hf-logo.png differ diff --git a/code/hsec-tools/hsec-tools.cabal b/code/hsec-tools/hsec-tools.cabal new file mode 100644 index 00000000..7571448c --- /dev/null +++ b/code/hsec-tools/hsec-tools.cabal @@ -0,0 +1,152 @@ +cabal-version: 3.0 +name: hsec-tools +version: 0.2.0.1 + +-- A short (one-line) description of the package. +synopsis: + Tools for working with the Haskell security advisory database + +-- A longer description of the package. +description: + Tools for working with the Haskell security advisory database. + +-- A URL where users can report bugs. +-- bug-reports: + +-- The license under which the package is released. +license: BSD-3-Clause +author: Haskell Security Response Team +maintainer: security-advisories@haskell.org + +-- A copyright notice. +-- copyright: +category: Data +extra-doc-files: CHANGELOG.md +extra-source-files: + assets/css/*.css + assets/images/*.png + test/golden/*.golden + test/golden/*.md + +tested-with: + GHC ==8.10.7 || ==9.0.2 || ==9.2.8 || ==9.4.8 || ==9.6.3 || ==9.8.1 + +library + exposed-modules: + Security.Advisories + Security.Advisories.Convert.OSV + Security.Advisories.Filesystem + Security.Advisories.Generate.HTML + Security.Advisories.Generate.Snapshot + Security.Advisories.Generate.TH + Security.Advisories.Git + Security.Advisories.Format + Security.Advisories.Parse + Security.Advisories.Queries + + other-modules: + Paths_hsec_tools + autogen-modules: + Paths_hsec_tools + + build-depends: + , aeson >=2.0.1.0 && <3 + , base >=4.14 && <4.21 + , bytestring >=0.10 && <0.14 + , Cabal-syntax >=3.8.1.0 && <3.13 + , commonmark ^>=0.2.2 + , commonmark-pandoc >=0.2 && <0.3 + , containers >=0.6 && <0.7 + , cvss >= 0.2 && < 0.3 + , data-default >=0.7 && <0.8 + , directory <2 + , extra ^>=1.7.5 + , filepath >=1.4 && <1.5 + , hsec-core ^>= 0.2 + , feed ==1.3.* + , file-embed >=0.0.13.0 && <0.0.17 + , lucid >=2.9.0 && < 3 + , mtl >=2.2 && <2.4 + , osv >= 0.1 && < 0.2 + , pandoc >=2.0 && <3.6 + , pandoc-types >=1.22 && <2 + , parsec >=3 && <4 + , pathwalk >=0.3 && <0.4 + , pretty >=1.0 && <1.2 + , prettyprinter >=1.7 && <1.8 + , process >=1.6 && <1.7 + , safe >=0.3 && <0.4 + , text >=1.2 && <3 + , template-haskell >=2.16.0.0 && <2.23 + , time >=1.9 && <1.14 + , toml-parser >=2.0.0.0 && <2.1 + , validation-selective >=0.1 && <1 + + hs-source-dirs: src + default-language: Haskell2010 + ghc-options: + -Wall -Wcompat -Widentities -Wincomplete-record-updates + -Wincomplete-uni-patterns -Wpartial-fields -Wredundant-constraints + +executable hsec-tools + main-is: Main.hs + other-modules: Command.Reserve + , Command.NextID + , Util + + -- Modules included in this executable, other than Main. + -- other-modules: + + -- LANGUAGE extensions used by modules in this package. + -- other-extensions: + build-depends: + , aeson >=2.0.1.0 && <3 + , base >=4.14 && <4.20 + , bytestring >=0.10 && <0.13 + , Cabal-syntax >=3.8.1.0 && <3.11 + , filepath >=1.4 && <1.5 + , hsec-core ^>= 0.2 + , hsec-tools + , optparse-applicative >=0.17 && <0.19 + , text >=1.2 && <3 + , transformers + , validation-selective >=0.1 && <1 + + hs-source-dirs: app + default-language: Haskell2010 + ghc-options: + -Wall -Wcompat -Widentities -Wincomplete-record-updates + -Wincomplete-uni-patterns -Wpartial-fields -Wredundant-constraints + +test-suite spec + type: exitcode-stdio-1.0 + hs-source-dirs: test + main-is: Spec.hs + other-modules: + Spec.FormatSpec + Spec.QueriesSpec + build-depends: + , aeson-pretty <2 + , base <5 + , Cabal-syntax + , containers + , cvss + , directory + , hedgehog <2 + , hsec-core + , hsec-tools + , osv + , pretty-simple <5 + , prettyprinter + , tasty <1.5 + , tasty-golden <2.4 + , tasty-hedgehog <2 + , tasty-hunit <0.11 + , text + , time + , toml-parser + + default-language: Haskell2010 + ghc-options: + -Wall -Wcompat -Widentities -Wincomplete-record-updates + -Wincomplete-uni-patterns -Wpartial-fields -Wredundant-constraints diff --git a/code/hsec-tools/index.html b/code/hsec-tools/index.html new file mode 100644 index 00000000..28fb61f3 --- /dev/null +++ b/code/hsec-tools/index.html @@ -0,0 +1,133 @@ + + + + + + + Haskell Security Advisories + + + +
+
+ Advisories list + +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
#Package(s)Title
HSEC-2023-0003xmonad-contribcode injection in xmonad-contrib
HSEC-2023-0002biscuit-haskellImproper Verification of Cryptographic Signature
HSEC-2023-0001aesonHash flooding vulnerability in aeson
+
+
+
+

aeson

+
+ + + + + + + + + + + + + + + + + +
#IntroducedFixedTitle
HSEC-2023-00011.1.0Hash flooding vulnerability in aeson
+
+

biscuit-haskell

+
+ + + + + + + + + + + + + + + + + +
#IntroducedFixedTitle
HSEC-2023-00021.1.02.0.0Improper Verification of Cryptographic Signature
+
+

xmonad-contrib

+
+ + + + + + + + + + + + + + + + + +
#IntroducedFixedTitle
HSEC-2023-00031.1.02.0.0code injection in xmonad-contrib
+
+
+
+ + diff --git a/code/hsec-tools/src/Security/Advisories.hs b/code/hsec-tools/src/Security/Advisories.hs new file mode 100644 index 00000000..4c8e5f8b --- /dev/null +++ b/code/hsec-tools/src/Security/Advisories.hs @@ -0,0 +1,10 @@ +module Security.Advisories + ( module Security.Advisories.Core.Advisory + , module Security.Advisories.Core.HsecId + , module Security.Advisories.Parse + ) +where + +import Security.Advisories.Core.Advisory +import Security.Advisories.Core.HsecId +import Security.Advisories.Parse diff --git a/code/hsec-tools/src/Security/Advisories/Convert/OSV.hs b/code/hsec-tools/src/Security/Advisories/Convert/OSV.hs new file mode 100644 index 00000000..c63e0e72 --- /dev/null +++ b/code/hsec-tools/src/Security/Advisories/Convert/OSV.hs @@ -0,0 +1,58 @@ +{-# LANGUAGE OverloadedStrings #-} + +module Security.Advisories.Convert.OSV + ( convert + ) + where + +import qualified Data.Text as T +import Data.Void +import Distribution.Pretty (prettyShow) + +import Security.Advisories +import qualified Security.OSV as OSV + +convert :: Advisory -> OSV.Model Void Void Void Void +convert adv = + ( OSV.newModel' + (T.pack . printHsecId $ advisoryId adv) + (advisoryModified adv) + ) + { OSV.modelPublished = Just $ advisoryPublished adv + , OSV.modelAliases = advisoryAliases adv + , OSV.modelRelated = advisoryRelated adv + , OSV.modelSummary = Just $ advisorySummary adv + , OSV.modelDetails = Just $ advisoryDetails adv + , OSV.modelReferences = advisoryReferences adv + , OSV.modelAffected = fmap mkAffected (advisoryAffected adv) + } + +mkAffected :: Affected -> OSV.Affected Void Void Void +mkAffected aff = + OSV.Affected + { OSV.affectedPackage = mkPackage (affectedComponentIdentifier aff) + , OSV.affectedRanges = pure $ mkRange (affectedVersions aff) + , OSV.affectedSeverity = [OSV.Severity (affectedCVSS aff)] + , OSV.affectedEcosystemSpecific = Nothing + , OSV.affectedDatabaseSpecific = Nothing + } + +mkPackage :: ComponentIdentifier -> OSV.Package +mkPackage ecosystem = OSV.Package + { OSV.packageName = packageName + , OSV.packageEcosystem = ecosystemName + , OSV.packagePurl = Nothing + } + where + (ecosystemName, packageName) = case ecosystem of + Hackage n -> ("Hackage", n) + GHC c -> ("GHC", ghcComponentToText c) + +mkRange :: [AffectedVersionRange] -> OSV.Range Void +mkRange ranges = + OSV.RangeEcosystem (foldMap mkEvs ranges) Nothing + where + mkEvs :: AffectedVersionRange -> [OSV.Event T.Text] + mkEvs range = + OSV.EventIntroduced (T.pack $ prettyShow $ affectedVersionRangeIntroduced range) + : maybe [] (pure . OSV.EventFixed . T.pack . prettyShow) (affectedVersionRangeFixed range) diff --git a/code/hsec-tools/src/Security/Advisories/Filesystem.hs b/code/hsec-tools/src/Security/Advisories/Filesystem.hs new file mode 100644 index 00000000..897a7d2d --- /dev/null +++ b/code/hsec-tools/src/Security/Advisories/Filesystem.hs @@ -0,0 +1,184 @@ +{-| + +Helpers for the /security-advisories/ file system. + +Top-level functions that take a @FilePath@ expect the path to the +top-level directory of the /security-advisories/ repository (i.e. +it must have the @advisories/@ subdirectory). + +-} +module Security.Advisories.Filesystem + ( + dirNameAdvisories + , dirNameReserved + , isSecurityAdvisoriesRepo + , getReservedIds + , getAdvisoryIds + , getAllocatedIds + , greatestId + , getGreatestId + , forReserved + , forAdvisory + , listAdvisories + , advisoryFromFile + , parseComponentIdentifier + ) where + +import Control.Applicative (liftA2) +import Data.Bifunctor (bimap) +import Data.Foldable (fold) +import Data.Semigroup (Max(Max, getMax)) +import Data.Traversable (for) + +import Control.Monad.IO.Class (MonadIO, liftIO) +import Control.Monad.Writer.Strict (execWriterT, tell) +import qualified Data.Text as T +import qualified Data.Text.IO as T +import System.FilePath ((), takeBaseName, splitDirectories) +import System.Directory (doesDirectoryExist, pathIsSymbolicLink) +import System.Directory.PathWalk +import Validation (Validation (..)) + +import Security.Advisories (Advisory, AttributeOverridePolicy (NoOverrides), OutOfBandAttributes (..), ParseAdvisoryError, parseAdvisory, ComponentIdentifier(..)) +import Security.Advisories.Core.HsecId (HsecId, parseHsecId, placeholder) +import Security.Advisories.Git(firstAppearanceCommitDate, getAdvisoryGitInfo, lastModificationCommitDate) +import Control.Monad.Except (runExceptT, ExceptT (ExceptT), withExceptT) +import Security.Advisories.Parse (OOBError(GitHasNoOOB, PathHasNoComponentIdentifier)) +import Security.Advisories.Core.Advisory (ghcComponentFromText) + + +dirNameAdvisories :: FilePath +dirNameAdvisories = "advisories" + +dirNameReserved :: FilePath +dirNameReserved = "reserved" + +-- | Check whether the directory appears to be the root of a +-- /security-advisories/ filesystem. Only checks that the +-- @advisories@ subdirectory exists. +-- +isSecurityAdvisoriesRepo :: FilePath -> IO Bool +isSecurityAdvisoriesRepo path = + doesDirectoryExist (path dirNameAdvisories) + + +-- | Get a list of reserved HSEC IDs. The order is unspecified. +-- +getReservedIds :: FilePath -> IO [HsecId] +getReservedIds root = + forReserved root (\_ hsid -> pure [hsid]) + +-- | Get a list of used IDs (does not include reserved IDs) +-- There may be duplicates and the order is unspecified. +-- +getAdvisoryIds :: FilePath -> IO [HsecId] +getAdvisoryIds root = + forAdvisory root (\_ hsid -> pure [hsid]) + +-- | Get all allocated IDs, including reserved IDs. +-- There may be duplicates and the order is unspecified. +-- +getAllocatedIds :: FilePath -> IO [HsecId] +getAllocatedIds root = + liftA2 (<>) + (getAdvisoryIds root) + (getReservedIds root) + +-- | Return the greatest ID in a collection of IDs. If the +-- collection is empty, return the 'placeholder'. +-- +greatestId :: (Foldable t) => t HsecId -> HsecId +greatestId = getMax . foldr ((<>) . Max) (Max placeholder) + +-- | Return the greatest ID in the database, including reserved IDs. +-- If there are IDs in the database, returns the 'placeholder'. +-- +getGreatestId :: FilePath -> IO HsecId +getGreatestId = fmap greatestId . getAllocatedIds + + +-- | Invoke a callback for each HSEC ID in the reserved +-- directory. The results are combined monoidally. +-- +forReserved + :: (MonadIO m, Monoid r) + => FilePath -> (FilePath -> HsecId -> m r) -> m r +forReserved root = + _forFiles (root dirNameAdvisories dirNameReserved) + +-- | Invoke a callback for each HSEC ID under each of the advisory +-- subdirectories, excluding the @reserved@ directory. The results +-- are combined monoidally. +-- +-- The same ID could appear multiple times. In particular, the callback +-- is invoked for symbolic links as well as regular files. +-- +forAdvisory + :: (MonadIO m, Monoid r) + => FilePath -> (FilePath -> HsecId -> m r) -> m r +forAdvisory root go = do + let dir = root dirNameAdvisories + subdirs <- filter (/= dirNameReserved) <$> _getSubdirs dir + fmap fold $ for subdirs $ \subdir -> _forFiles (dir subdir) go + +-- | List deduplicated parsed Advisories +listAdvisories + :: (MonadIO m) + => FilePath -> m (Validation [(FilePath, ParseAdvisoryError)] [Advisory]) +listAdvisories root = + forAdvisory root $ \advisoryPath _advisoryId -> do + isSym <- liftIO $ pathIsSymbolicLink advisoryPath + if isSym + then return $ pure [] + else + bimap (\err -> [(advisoryPath, err)]) pure + <$> advisoryFromFile advisoryPath + +-- | Parse an advisory from a file system path +advisoryFromFile + :: (MonadIO m) + => FilePath -> m (Validation ParseAdvisoryError Advisory) +advisoryFromFile advisoryPath = do + oob <- runExceptT $ do + ecosystem <- parseComponentIdentifier advisoryPath + withExceptT GitHasNoOOB $ do + gitInfo <- ExceptT $ liftIO $ getAdvisoryGitInfo advisoryPath + pure OutOfBandAttributes + { oobPublished = firstAppearanceCommitDate gitInfo + , oobModified = lastModificationCommitDate gitInfo + , oobComponentIdentifier = ecosystem + } + fileContent <- liftIO $ T.readFile advisoryPath + pure + $ either Failure Success + $ parseAdvisory NoOverrides oob fileContent + +-- | Get names (not paths) of subdirectories of the given directory +-- (one level). There's no monoidal, interruptible variant of +-- @pathWalk@ so we use @WriterT@ to smuggle the result out. +-- +_getSubdirs :: (MonadIO m) => FilePath -> m [FilePath] +_getSubdirs root = + execWriterT $ + pathWalkInterruptible root $ \_ subdirs _ -> do + tell subdirs + pure Stop + +_forFiles + :: (MonadIO m, Monoid r) + => FilePath -- ^ (sub)directory name + -> (FilePath -> HsecId -> m r) + -> m r +_forFiles root go = + pathWalkAccumulate root $ \dir _ files -> + fmap fold $ for files $ \file -> + case parseHsecId (takeBaseName file) of + Nothing -> pure mempty + Just hsid -> go (dir file) hsid + +parseComponentIdentifier :: Monad m => FilePath -> ExceptT OOBError m (Maybe ComponentIdentifier) +parseComponentIdentifier fp = ExceptT . pure $ case drop 1 $ reverse $ splitDirectories fp of + package : "hackage" : _ -> pure (Just $ Hackage $ T.pack package) + component : "ghc" : _ | Just ghc <- ghcComponentFromText (T.pack component) -> pure (Just $ GHC ghc) + _ : _ : "advisories" : _ -> Left PathHasNoComponentIdentifier + _ -> pure Nothing diff --git a/code/hsec-tools/src/Security/Advisories/Format.hs b/code/hsec-tools/src/Security/Advisories/Format.hs new file mode 100644 index 00000000..19037c53 --- /dev/null +++ b/code/hsec-tools/src/Security/Advisories/Format.hs @@ -0,0 +1,376 @@ +{-# LANGUAGE DeriveGeneric #-} +{-# LANGUAGE DerivingVia #-} +{-# LANGUAGE GeneralizedNewtypeDeriving #-} +{-# LANGUAGE MultiParamTypeClasses #-} +{-# LANGUAGE OverloadedStrings #-} +{-# OPTIONS_GHC -Wno-orphans #-} + +module Security.Advisories.Format + ( FrontMatter (..), + fromAdvisory, + AdvisoryMetadata (..), + Toml.ToTable (..), + Toml.ToValue (..), + Toml.FromValue (..), + ) +where + +import Control.Applicative ((<|>)) +import Commonmark.Types (HasAttributes (..), IsBlock (..), IsInline (..), Rangeable (..), SourceRange (..)) +import qualified Data.Map as Map +import Data.Maybe (fromMaybe) +import Data.Monoid (First (..)) +import Data.List (intercalate) +import Data.Tuple (swap) +import GHC.Generics (Generic) + +import Data.Text (Text) +import qualified Data.Text as T +import Data.Time (utc, UTCTime(..), zonedTimeToUTC, localTimeToUTC) +import Distribution.Parsec (eitherParsec) +import Distribution.Pretty (pretty) +import Distribution.Types.Version (Version) +import Distribution.Types.VersionRange (VersionRange) +import qualified Text.PrettyPrint as Pretty +import qualified Toml +import qualified Toml.Schema as Toml + +import Security.Advisories.Core.Advisory +import Security.Advisories.Core.HsecId +import qualified Security.CVSS as CVSS +import Security.OSV (Reference (..), ReferenceType, referenceTypes) + +fromAdvisory :: Advisory -> FrontMatter +fromAdvisory advisory = + FrontMatter + { frontMatterAdvisory = + AdvisoryMetadata + { amdId = advisoryId advisory, + amdPublished = Just $ advisoryPublished advisory, + amdModified = Just $ advisoryModified advisory, + amdCAPECs = advisoryCAPECs advisory, + amdCWEs = advisoryCWEs advisory, + amdKeywords = advisoryKeywords advisory, + amdAliases = advisoryAliases advisory, + amdRelated = advisoryRelated advisory + }, + frontMatterReferences = advisoryReferences advisory, + frontMatterAffected = advisoryAffected advisory + } + +-- advisory markdown file. +data FrontMatter = FrontMatter { + frontMatterAdvisory :: AdvisoryMetadata, + frontMatterReferences :: [Reference], + frontMatterAffected :: [Affected] +} deriving (Show, Generic) + +instance Toml.FromValue FrontMatter where + fromValue = Toml.parseTableFromValue $ + do advisory <- Toml.reqKey "advisory" + affected <- Toml.reqKey "affected" + references <- fromMaybe [] <$> Toml.optKey "references" + pure FrontMatter { + frontMatterAdvisory = advisory, + frontMatterAffected = affected, + frontMatterReferences = references + } + +instance Toml.ToValue FrontMatter where + toValue = Toml.defaultTableToValue + +instance Toml.ToTable FrontMatter where + toTable x = Toml.table + [ "advisory" Toml..= frontMatterAdvisory x + , "affected" Toml..= frontMatterAffected x + , "references" Toml..= frontMatterReferences x + ] + +-- | Internal type corresponding to the @[advisory]@ subsection of the +-- TOML frontmatter in an advisory markdown file. +data AdvisoryMetadata = AdvisoryMetadata + { amdId :: HsecId + , amdModified :: Maybe UTCTime + , amdPublished :: Maybe UTCTime + , amdCAPECs :: [CAPEC] + , amdCWEs :: [CWE] + , amdKeywords :: [Keyword] + , amdAliases :: [T.Text] + , amdRelated :: [T.Text] + } + deriving (Show, Generic) + +instance Toml.FromValue AdvisoryMetadata where + fromValue = Toml.parseTableFromValue $ + do identifier <- Toml.reqKey "id" + published <- Toml.optKeyOf "date" getDefaultedZonedTime + modified <- Toml.optKeyOf "modified" getDefaultedZonedTime + let optList key = fromMaybe [] <$> Toml.optKey key + capecs <- optList "capec" + cwes <- optList "cwe" + kwds <- optList "keywords" + aliases <- optList "aliases" + related <- optList "related" + pure AdvisoryMetadata + { amdId = identifier + , amdModified = modified + , amdPublished = published + , amdCAPECs = capecs + , amdCWEs = cwes + , amdKeywords = kwds + , amdAliases = aliases + , amdRelated = related + } + +instance Toml.ToValue AdvisoryMetadata where + toValue = Toml.defaultTableToValue + +instance Toml.ToTable AdvisoryMetadata where + toTable x = Toml.table $ + ["id" Toml..= amdId x] ++ + ["modified" Toml..= y | Just y <- [amdModified x]] ++ + ["date" Toml..= y | Just y <- [amdPublished x]] ++ + ["capec" Toml..= amdCAPECs x | not (null (amdCAPECs x))] ++ + ["cwe" Toml..= amdCWEs x | not (null (amdCWEs x))] ++ + ["keywords" Toml..= amdKeywords x | not (null (amdKeywords x))] ++ + ["aliases" Toml..= amdAliases x | not (null (amdAliases x))] ++ + ["related" Toml..= amdRelated x | not (null (amdRelated x))] + +instance Toml.FromValue GHCComponent where + fromValue v = case v of + Toml.Text' _ n + | Just c <- ghcComponentFromText n + -> pure c + | otherwise + -> Toml.failAt (Toml.valueAnn v) $ + "Invalid ghc-component '" + <> T.unpack n + <> "', expected " + <> T.unpack (T.intercalate "|" componentNames) + _ -> Toml.failAt (Toml.valueAnn v) $ + "Non-text ghc-component, expected" + <> T.unpack (T.intercalate "|" componentNames) + where + componentNames = map ghcComponentToText [minBound..maxBound] + +instance Toml.ToValue GHCComponent where + toValue = Toml.Text' () . ghcComponentToText + +instance Toml.FromValue Affected where + fromValue = Toml.parseTableFromValue $ + do ecosystem <- (Hackage <$> Toml.reqKey "package") <|> (GHC <$> Toml.reqKey "ghc-component") + cvss <- Toml.reqKey "cvss" -- TODO validate CVSS format + os <- Toml.optKey "os" + arch <- Toml.optKey "arch" + decls <- maybe [] Map.toList <$> Toml.optKey "declarations" + versions <- Toml.reqKey "versions" + pure $ Affected + { affectedComponentIdentifier = ecosystem + , affectedCVSS = cvss + , affectedVersions = versions + , affectedArchitectures = arch + , affectedOS = os + , affectedDeclarations = decls + } + +instance Toml.ToValue Affected where + toValue = Toml.defaultTableToValue + +instance Toml.ToTable Affected where + toTable x = Toml.table $ + ecosystem ++ + [ "cvss" Toml..= affectedCVSS x + , "versions" Toml..= affectedVersions x + ] ++ + [ "os" Toml..= y | Just y <- [affectedOS x]] ++ + [ "arch" Toml..= y | Just y <- [affectedArchitectures x]] ++ + [ "declarations" Toml..= asTable (affectedDeclarations x) | not (null (affectedDeclarations x))] + where + ecosystem = case affectedComponentIdentifier x of + Hackage pkg -> ["package" Toml..= pkg] + GHC c -> ["ghc-component" Toml..= c] + asTable kvs = Map.fromList [(T.unpack k, v) | (k,v) <- kvs] + +instance Toml.FromValue AffectedVersionRange where + fromValue = Toml.parseTableFromValue $ + do introduced <- Toml.reqKey "introduced" + fixed <- Toml.optKey "fixed" + pure AffectedVersionRange { + affectedVersionRangeIntroduced = introduced, + affectedVersionRangeFixed = fixed + } + +instance Toml.ToValue AffectedVersionRange where + toValue = Toml.defaultTableToValue + +instance Toml.ToTable AffectedVersionRange where + toTable x = Toml.table $ + ("introduced" Toml..= affectedVersionRangeIntroduced x) : + ["fixed" Toml..= y | Just y <- [affectedVersionRangeFixed x]] + + +instance Toml.FromValue HsecId where + fromValue v = + do s <- Toml.fromValue v + case parseHsecId s of + Nothing -> Toml.failAt (Toml.valueAnn v) "invalid HSEC-ID: expected HSEC-[0-9]{4,}-[0-9]{4,}" + Just x -> pure x + +instance Toml.ToValue HsecId where + toValue = Toml.toValue . printHsecId + +instance Toml.FromValue CAPEC where + fromValue v = CAPEC <$> Toml.fromValue v + +instance Toml.ToValue CAPEC where + toValue (CAPEC x) = Toml.toValue x + +instance Toml.FromValue CWE where + fromValue v = CWE <$> Toml.fromValue v + +instance Toml.ToValue CWE where + toValue (CWE x) = Toml.toValue x + +instance Toml.FromValue Keyword where + fromValue v = Keyword <$> Toml.fromValue v + +instance Toml.ToValue Keyword where + toValue (Keyword x) = Toml.toValue x + +-- | Get a datetime with the timezone defaulted to UTC and the time defaulted to midnight +getDefaultedZonedTime :: Toml.Value' l -> Toml.Matcher l UTCTime +getDefaultedZonedTime (Toml.ZonedTime' _ x) = pure (zonedTimeToUTC x) +getDefaultedZonedTime (Toml.LocalTime' _ x) = pure (localTimeToUTC utc x) +getDefaultedZonedTime (Toml.Day' _ x) = pure (UTCTime x 0) +getDefaultedZonedTime v = Toml.failAt (Toml.valueAnn v) "expected a date with optional time and timezone" + +instance Toml.FromValue Reference where + fromValue = Toml.parseTableFromValue $ + do refType <- Toml.reqKey "type" + url <- Toml.reqKey "url" + pure (Reference refType url) + +instance Toml.FromValue ReferenceType where + fromValue (Toml.Text' _ refTypeStr) + | Just a <- lookup refTypeStr (fmap swap referenceTypes) = pure a + fromValue v = + Toml.failAt (Toml.valueAnn v) $ + "reference.type should be one of: " ++ intercalate ", " (T.unpack . snd <$> referenceTypes) + +instance Toml.ToValue Reference where + toValue = Toml.defaultTableToValue + +instance Toml.ToTable Reference where + toTable x = Toml.table + [ "type" Toml..= fromMaybe "UNKNOWN" (lookup (referencesType x) referenceTypes) + , "url" Toml..= referencesUrl x + ] + +instance Toml.FromValue OS where + fromValue v = + do s <- Toml.fromValue v + case s :: String of + "darwin" -> pure MacOS + "freebsd" -> pure FreeBSD + "linux" -> pure Linux + "linux-android" -> pure Android + "mingw32" -> pure Windows + "netbsd" -> pure NetBSD + "openbsd" -> pure OpenBSD + other -> Toml.failAt (Toml.valueAnn v) ("Invalid OS: " ++ show other) + +instance Toml.ToValue OS where + toValue x = + Toml.toValue $ + case x of + MacOS -> "darwin" :: String + FreeBSD -> "freebsd" + Linux -> "linux" + Android -> "linux-android" + Windows -> "mingw32" + NetBSD -> "netbsd" + OpenBSD -> "openbsd" + +instance Toml.FromValue Architecture where + fromValue v = + do s <- Toml.fromValue v + case parseArchitecture s of + Just a -> pure a + Nothing -> Toml.failAt (Toml.valueAnn v) ("Invalid architecture: " ++ show s) + +instance Toml.ToValue Architecture where + toValue = Toml.toValue . printArchitecture + +printArchitecture :: Architecture -> Text +printArchitecture = T.toLower . T.pack . show + +parseArchitecture :: Text -> Maybe Architecture +parseArchitecture = flip lookup [(printArchitecture arch, arch) | arch <- [minBound .. maxBound]] + +instance Toml.FromValue Version where + fromValue v = + do s <- Toml.fromValue v + case eitherParsec s of + Left err -> Toml.failAt (Toml.valueAnn v) ("parse error in version: " ++ err) + Right affected -> pure affected + +instance Toml.ToValue Version where + toValue = Toml.toValue . Pretty.render . pretty + +instance Toml.FromValue VersionRange where + fromValue v = + do s <- Toml.fromValue v + case eitherParsec s of + Left err -> Toml.failAt (Toml.valueAnn v) ("parse error in version range: " ++ err) + Right affected -> pure affected + +instance Toml.ToValue VersionRange where + toValue = Toml.toValue . Pretty.render . pretty + +instance Toml.FromValue CVSS.CVSS where + fromValue v = + do s <- Toml.fromValue v + case CVSS.parseCVSS s of + Left err -> Toml.failAt (Toml.valueAnn v) ("parse error in cvss: " ++ show err) + Right cvss -> pure cvss + +instance Toml.ToValue CVSS.CVSS where + toValue = Toml.toValue . CVSS.cvssVectorString + +-- | A solution to an awkward problem: how to delete the TOML +-- block. We parse into this type to get the source range of +-- the first block element. We can use it to delete the lines +-- from the input. +-- +newtype FirstSourceRange = FirstSourceRange (First SourceRange) + deriving (Show, Semigroup, Monoid) + +instance Rangeable FirstSourceRange where + ranged range = (FirstSourceRange (First (Just range)) <>) + +instance HasAttributes FirstSourceRange where + addAttributes _ = id + +instance IsBlock FirstSourceRange FirstSourceRange where + paragraph _ = mempty + plain _ = mempty + thematicBreak = mempty + blockQuote _ = mempty + codeBlock _ = mempty + heading _ = mempty + rawBlock _ = mempty + referenceLinkDefinition _ = mempty + list _ = mempty + +instance IsInline FirstSourceRange where + lineBreak = mempty + softBreak = mempty + str _ = mempty + entity _ = mempty + escapedChar _ = mempty + emph = id + strong = id + link _ _ _ = mempty + image _ _ _ = mempty + code _ = mempty + rawInline _ _ = mempty diff --git a/code/hsec-tools/src/Security/Advisories/Generate/HTML.hs b/code/hsec-tools/src/Security/Advisories/Generate/HTML.hs new file mode 100644 index 00000000..b28cfc6b --- /dev/null +++ b/code/hsec-tools/src/Security/Advisories/Generate/HTML.hs @@ -0,0 +1,286 @@ +{-# LANGUAGE DerivingStrategies #-} +{-# LANGUAGE LambdaCase #-} +{-# LANGUAGE OverloadedStrings #-} +{-# LANGUAGE TemplateHaskell #-} + +module Security.Advisories.Generate.HTML + ( renderAdvisoriesIndex, + ) +where + +import Control.Monad (forM_) +import qualified Data.ByteString.Char8 as BS8 +import Data.List (sortOn) +import Data.List.Extra (groupSort) +import qualified Data.Map.Strict as Map +import Data.Ord (Down (..)) +import Data.Text (Text) +import qualified Data.Text as T +import qualified Data.Text.IO as T +import qualified Data.Text.Lazy as TL +import Data.Time (UTCTime) +import Data.Time.Format.ISO8601 +import System.Directory (createDirectoryIfMissing) +import System.Exit (exitFailure) +import System.FilePath ((), takeDirectory) +import System.IO (hPrint, hPutStrLn, stderr) + +import Distribution.Pretty (prettyShow) +import Lucid +import Safe (maximumMay) +import qualified Text.Atom.Feed as Feed +import qualified Text.Atom.Feed.Export as FeedExport +import Validation (Validation (..)) + +import qualified Security.Advisories as Advisories +import Security.Advisories.Filesystem (listAdvisories) +import Security.Advisories.Generate.TH (readDirFilesTH) +import Security.Advisories.Core.Advisory (ComponentIdentifier (..), ghcComponentToText) + +-- * Actions + +renderAdvisoriesIndex :: FilePath -> FilePath -> IO () +renderAdvisoriesIndex src dst = do + advisories <- + listAdvisories src >>= \case + Failure errors -> do + T.hPutStrLn stderr "Cannot parse some advisories" + forM_ errors $ + hPrint stderr + exitFailure + Success advisories -> + return advisories + + let renderHTMLToFile path content = do + hPutStrLn stderr $ "Rendering " <> path + renderToFile path content + + createDirectoryIfMissing False dst + let indexAdvisories = map toAdvisoryR advisories + renderHTMLToFile (dst "by-dates.html") $ listByDates indexAdvisories + renderHTMLToFile (dst "by-packages.html") $ listByPackages indexAdvisories + + let advisoriesDir = dst "advisory" + createDirectoryIfMissing False advisoriesDir + forM_ advisories $ \advisory -> + renderHTMLToFile (advisoriesDir advisoryHtmlFilename (Advisories.advisoryId advisory)) $ + inPage PageAdvisory $ + toHtmlRaw (Advisories.advisoryHtml advisory) + + hPutStrLn stderr $ "Rendering " <> (dst "atom.xml") + writeFile (dst "atom.xml") $ T.unpack $ renderFeed advisories + + putStrLn "Copying assets" + let assetsDir = dst "assets" + forM_ $(readDirFilesTH "assets") $ \(path, content) -> do + createDirectoryIfMissing True $ assetsDir takeDirectory path + putStrLn $ "Copying " <> (assetsDir path) + BS8.writeFile (assetsDir path) content + +-- * Rendering types + +data AdvisoryR = AdvisoryR + { advisoryId :: Advisories.HsecId, + advisorySummary :: Text, + advisoryAffected :: [AffectedPackageR], + advisoryModified :: UTCTime + } + deriving stock (Show) + +data AffectedPackageR = AffectedPackageR + { ecosystem :: ComponentIdentifier, + introduced :: Text, + fixed :: Maybe Text + } + deriving stock (Eq, Show) + +-- * Pages + +listByDates :: [AdvisoryR] -> Html () +listByDates advisories = + inPage PageListByDates $ do + indexDescription + div_ [class_ "advisories"] $ do + table_ [class_ "pure-table pure-table-horizontal"] $ do + thead_ $ do + tr_ $ do + th_ "#" + th_ "Package(s)" + th_ "Summary" + + tbody_ $ do + let sortedAdvisories = + zip + (sortOn (Down . advisoryId) advisories) + (cycle [[], [class_ "pure-table-odd"]]) + forM_ sortedAdvisories $ \(advisory, trClasses) -> + tr_ trClasses $ do + td_ [class_ "advisory-id"] $ a_ [href_ $ advisoryLink (advisoryId advisory)] $ toHtml (Advisories.printHsecId (advisoryId advisory)) + td_ [class_ "advisory-packages"] $ toHtml $ T.intercalate "," $ packageName <$> advisoryAffected advisory + td_ [class_ "advisory-summary"] $ toHtml $ advisorySummary advisory + +packageName :: AffectedPackageR -> Text +packageName af = case ecosystem af of + Hackage n -> n + GHC c -> "ghc:" <> ghcComponentToText c + +listByPackages :: [AdvisoryR] -> Html () +listByPackages advisories = + inPage PageListByPackages $ do + indexDescription + + let byPackage :: Map.Map Text [(AdvisoryR, AffectedPackageR)] + byPackage = + Map.fromList $ + groupSort + [ (packageName package, (advisory, package)) + | advisory <- advisories, + package <- advisoryAffected advisory + ] + + forM_ (Map.toList byPackage) $ \(currentPackageName, perPackageAdvisory) -> do + h2_ $ toHtml currentPackageName + div_ [class_ "advisories"] $ do + table_ [] $ do + thead_ $ do + tr_ $ do + th_ "#" + th_ "Introduced" + th_ "Fixed" + th_ "Summary" + + tbody_ $ do + let sortedAdvisories = + sortOn (Down . advisoryId . fst) perPackageAdvisory + forM_ sortedAdvisories $ \(advisory, package) -> do + tr_ $ do + td_ [class_ "advisory-id"] $ + a_ [href_ $ advisoryLink $ advisoryId advisory] $ + toHtml (Advisories.printHsecId $ advisoryId advisory) + td_ [class_ "advisory-introduced"] $ toHtml $ introduced package + td_ [class_ "advisory-fixed"] $ maybe (return ()) toHtml $ fixed package + td_ [class_ "advisory-summary"] $ toHtml $ advisorySummary advisory + +indexDescription :: Html () +indexDescription = + div_ [class_ "description"] $ do + p_ "The Haskell Security Advisory Database is a repository of security advisories filed against packages published via Hackage." + p_ $ do + "It is generated from " + a_ [href_ "https://github.com/haskell/security-advisories/", target_ "_blank", rel_ "noopener noreferrer"] "Haskell Security Advisory Database" + ". " + "Feel free to " + a_ [href_ "https://github.com/haskell/security-advisories/blob/main/PROCESS.md", target_ "_blank", rel_ "noopener noreferrer"] "report new or historic security issues" + "." + +-- * Utils + +data NavigationPage + = PageListByDates + | PageListByPackages + | PageAdvisory + deriving stock (Eq, Show) + +baseUrlForPage :: NavigationPage -> Text +baseUrlForPage = \case + PageListByDates -> "." + PageListByPackages -> "." + PageAdvisory -> ".." + +inPage :: NavigationPage -> Html () -> Html () +inPage page content = + doctypehtml_ $ + html_ [lang_ "en"] $ do + head_ $ do + meta_ [charset_ "UTF-8"] + base_ [href_ $ baseUrlForPage page] + link_ [rel_ "alternate", type_ "application/atom+xml", href_ atomFeedUrl] + link_ [rel_ "stylesheet", href_ "assets/css/default.css"] + meta_ [name_ "viewport", content_ "width=device-width, initial-scale=1"] + meta_ [name_ "description", content_ "Haskell Security advisories"] + title_ "Haskell Security advisories" + body_ $ do + div_ [class_ "nav-bar"] $ do + let selectedOn p = + if page == p + then "selected" + else "" + ul_ [class_ "items"] $ do + li_ [class_ $ selectedOn PageListByDates] $ + a_ [href_ "by-dates.html"] "by date" + li_ [class_ $ selectedOn PageListByPackages] $ + a_ [href_ "by-packages.html"] "by package" + h1_ [] "Advisories list" + div_ [class_ "content"] content + footer_ [] $ do + div_ [class_ "HF"] $ do + "This site is a project of " + a_ [href_ "https://haskell.foundation", target_ "_blank", rel_ "noopener noreferrer"] "The Haskell Foundation" + "." + +advisoryHtmlFilename :: Advisories.HsecId -> FilePath +advisoryHtmlFilename advisoryId' = Advisories.printHsecId advisoryId' <> ".html" + +advisoryLink :: Advisories.HsecId -> Text +advisoryLink advisoryId' = "advisory/" <> T.pack (advisoryHtmlFilename advisoryId') + +toAdvisoryR :: Advisories.Advisory -> AdvisoryR +toAdvisoryR x = + AdvisoryR + { advisoryId = Advisories.advisoryId x, + advisorySummary = Advisories.advisorySummary x, + advisoryAffected = concatMap toAffectedPackageR $ Advisories.advisoryAffected x, + advisoryModified = Advisories.advisoryModified x + } + where + toAffectedPackageR :: Advisories.Affected -> [AffectedPackageR] + toAffectedPackageR p = + flip map (Advisories.affectedVersions p) $ \versionRange -> + AffectedPackageR + { ecosystem = Advisories.affectedComponentIdentifier p, + introduced = T.pack $ prettyShow $ Advisories.affectedVersionRangeIntroduced versionRange, + fixed = T.pack . prettyShow <$> Advisories.affectedVersionRangeFixed versionRange + } + +-- * Atom/RSS feed + +feed :: [Advisories.Advisory] -> Feed.Feed +feed advisories = + ( Feed.nullFeed + atomFeedUrl + (Feed.TextString "Haskell Security Advisory DB") -- Title + (maybe "" (T.pack . iso8601Show) . maximumMay . fmap Advisories.advisoryModified $ advisories) + ) + { Feed.feedEntries = fmap toEntry advisories + , Feed.feedLinks = [(Feed.nullLink atomFeedUrl) { Feed.linkRel = Just (Left "self") }] + , Feed.feedAuthors = [Feed.nullPerson { Feed.personName = "Haskell Security Response Team" }] + } + where + toEntry advisory = + ( Feed.nullEntry + (toUrl advisory) + (mkSummary advisory) + (T.pack . iso8601Show $ Advisories.advisoryModified advisory) + ) + { Feed.entryLinks = [(Feed.nullLink (toUrl advisory)) { Feed.linkRel = Just (Left "alternate") }] + , Feed.entryContent = Just (Feed.HTMLContent (Advisories.advisoryHtml advisory)) + } + + mkSummary advisory = + Feed.TextString $ + T.pack (Advisories.printHsecId (Advisories.advisoryId advisory)) + <> " - " + <> Advisories.advisorySummary advisory + toUrl advisory = advisoriesRootUrl <> "/" <> advisoryLink (Advisories.advisoryId advisory) + +renderFeed :: [Advisories.Advisory] -> Text +renderFeed = + maybe (error "Cannot render atom feed") TL.toStrict + . FeedExport.textFeed + . feed + +advisoriesRootUrl :: T.Text +advisoriesRootUrl = "https://haskell.github.io/security-advisories" + +atomFeedUrl :: T.Text +atomFeedUrl = advisoriesRootUrl <> "/atom.xml" diff --git a/code/hsec-tools/src/Security/Advisories/Generate/Snapshot.hs b/code/hsec-tools/src/Security/Advisories/Generate/Snapshot.hs new file mode 100644 index 00000000..9270d5de --- /dev/null +++ b/code/hsec-tools/src/Security/Advisories/Generate/Snapshot.hs @@ -0,0 +1,84 @@ +{-# LANGUAGE DeriveAnyClass #-} +{-# LANGUAGE DeriveGeneric #-} +{-# LANGUAGE DerivingStrategies #-} +{-# LANGUAGE LambdaCase #-} +{-# LANGUAGE OverloadedStrings #-} + +module Security.Advisories.Generate.Snapshot + ( createSnapshot, + ) +where + +import Data.Aeson (ToJSON, encodeFile) +import Data.Default (def) +import qualified Data.Text.IO as T +import Data.Time (UTCTime) +import Data.Version (Version) +import GHC.Generics (Generic) +import Paths_hsec_tools (version) +import qualified Prettyprinter as Pretty +import qualified Prettyprinter.Render.Text as Pretty +import Security.Advisories.Core.Advisory +import Security.Advisories.Filesystem (advisoryFromFile, forAdvisory, forReserved) +import Security.Advisories.Format (fromAdvisory) +import System.Directory (copyFileWithMetadata, createDirectoryIfMissing) +import System.FilePath (takeDirectory, ()) +import System.IO (hPrint, hPutStrLn, stderr) +import Text.Pandoc (Block (CodeBlock), Pandoc (Pandoc), nullMeta, runIOorExplode) +import Text.Pandoc.Writers (writeCommonMark) +import qualified Toml +import Validation (Validation (..)) + +-- * Actions + +createSnapshot :: FilePath -> FilePath -> IO () +createSnapshot src dst = do + let toDstFilePath orig = dst drop (length src + 1) orig + + forReserved src $ \p _ -> do + createDirectoryIfMissing True $ takeDirectory $ toDstFilePath p + hPutStrLn stderr $ "Copying '" <> p <> "' to '" <> toDstFilePath p <> "'" + copyFileWithMetadata p $ toDstFilePath p + + advisoriesLatestUpdates <- + forAdvisory src $ \p _ -> do + createDirectoryIfMissing True $ takeDirectory $ toDstFilePath p + hPutStrLn stderr $ "Taking a snapshot of '" <> p <> "' to '" <> toDstFilePath p <> "'" + advisoryFromFile p + >>= \case + Failure e -> do + hPrint stderr e + return [] + Success advisory -> do + let pandoc = + Pandoc + nullMeta + ( CodeBlock + ("", ["toml"], []) + ( Pretty.renderStrict $ + Pretty.layoutPretty Pretty.defaultLayoutOptions $ + Toml.encode $ + fromAdvisory advisory + ) + : blocks (advisoryPandoc advisory) + ) + blocks (Pandoc _ xs) = xs + rendered <- runIOorExplode $ writeCommonMark def pandoc + T.writeFile (toDstFilePath p) rendered + return [advisoryModified advisory] + + let metadataPath = dst "snapshot.json" + metadata = + SnapshotMetadata + { latestUpdate = maximum advisoriesLatestUpdates, + snapshotVersion = version + } + hPutStrLn stderr $ "Writing snapshot metadata to '" <> metadataPath <> "'" + encodeFile metadataPath metadata + +data SnapshotMetadata = SnapshotMetadata + { latestUpdate :: UTCTime, + snapshotVersion :: Version + } + deriving stock (Generic) + deriving anyclass (ToJSON) diff --git a/code/hsec-tools/src/Security/Advisories/Generate/TH.hs b/code/hsec-tools/src/Security/Advisories/Generate/TH.hs new file mode 100644 index 00000000..700a3a36 --- /dev/null +++ b/code/hsec-tools/src/Security/Advisories/Generate/TH.hs @@ -0,0 +1,22 @@ +module Security.Advisories.Generate.TH ( + readFileTH, + readDirFilesTH, + fileLocation, + ) where + +import Control.Monad.IO.Class (liftIO) +import Data.ByteString.Char8 as BS8 +import Data.FileEmbed (embedDir, makeRelativeToLocationPredicate) +import Language.Haskell.TH (Exp (LitE), Lit (StringL), Q) + +-- | Read file at compile-time. +readFileTH :: FilePath -> Q Exp +readFileTH p = fileLocation p $ \p' -> LitE . StringL . BS8.unpack <$> liftIO (BS8.readFile p') + +-- | Read files in (sub-)directory at compile-time. +-- Gives a [(FilePath, ByteString)] +readDirFilesTH :: FilePath -> Q Exp +readDirFilesTH p = fileLocation p embedDir + +fileLocation :: FilePath -> (FilePath -> Q Exp) -> Q Exp +fileLocation fp act = makeRelativeToLocationPredicate (== "hsec-tools.cabal") fp >>= act diff --git a/code/hsec-tools/src/Security/Advisories/Git.hs b/code/hsec-tools/src/Security/Advisories/Git.hs new file mode 100644 index 00000000..274e0c6e --- /dev/null +++ b/code/hsec-tools/src/Security/Advisories/Git.hs @@ -0,0 +1,125 @@ +{-# LANGUAGE LambdaCase #-} +{-# LANGUAGE DerivingStrategies #-} + +{-| + +Helpers for deriving advisory metadata from a Git repo. + +-} +module Security.Advisories.Git + ( AdvisoryGitInfo(..) + , GitError(..) + , explainGitError + , getAdvisoryGitInfo + , getRepoRoot + , add + , commit + ) + where + +import Data.Char (isSpace) +import Data.List (dropWhileEnd) +import Data.Time (UTCTime, zonedTimeToUTC) +import Data.Time.Format.ISO8601 (iso8601ParseM) +import System.Exit (ExitCode(ExitSuccess)) +import System.FilePath (splitFileName) +import System.Process (readProcessWithExitCode) +import Control.Applicative ((<|>)) + +data AdvisoryGitInfo = AdvisoryGitInfo + { firstAppearanceCommitDate :: UTCTime + , lastModificationCommitDate :: UTCTime + } + +data GitError + = GitProcessError ExitCode String String -- ^ exit code, stdout and stderr + | GitTimeParseError String -- ^ unable to parse this input as a datetime + deriving stock (Eq, Ord, Show) + +explainGitError :: GitError -> String +explainGitError = \case + GitProcessError status stdout stderr -> + unlines + [ "git exited with status " <> show status + , ">>> standard output:" + , stdout + , ">>> standard error:" + , stderr + ] + GitTimeParseError s -> + "failed to parse time: " <> s + +-- | Get top-level directory of the working tree. +-- +getRepoRoot :: FilePath -> IO (Either GitError FilePath) +getRepoRoot path = do + (status, stdout, stderr) <- readProcessWithExitCode + "git" + [ "-C", path + , "rev-parse" + , "--show-toplevel" + ] + "" -- standard input + pure $ case status of + ExitSuccess -> Right $ trim stdout + _ -> Left $ GitProcessError status stdout stderr + where + trim = dropWhileEnd isSpace . dropWhile isSpace + +-- | Add changes to index +-- +add + :: FilePath -- ^ path to working tree + -> [FilePath] -- ^ files to update in index + -> IO (Either GitError ()) +add path pathspecs = do + (status, stdout, stderr) <- readProcessWithExitCode + "git" + ( ["-C", path, "add"] <> pathspecs ) + "" -- standard input + pure $ case status of + ExitSuccess -> Right () + _ -> Left $ GitProcessError status stdout stderr + +-- | Commit changes to repo. +-- +commit + :: FilePath -- ^ path to working tree + -> String -- ^ commit message + -> IO (Either GitError ()) +commit path msg = do + (status, stdout, stderr) <- readProcessWithExitCode + "git" + ["-C", path, "commit", "-m", msg] + "" -- standard input + pure $ case status of + ExitSuccess -> Right () + _ -> Left $ GitProcessError status stdout stderr + +getAdvisoryGitInfo :: FilePath -> IO (Either GitError AdvisoryGitInfo) +getAdvisoryGitInfo path = do + let (dir, file) = splitFileName path + (status, stdout, stderr) <- readProcessWithExitCode + "git" + [ "-C", dir + , "log" + , "--pretty=format:%cI" -- print committer date + , "--find-renames" + , file + ] + "" -- standard input + let timestamps = filter (not . null) $ lines stdout + case status of + ExitSuccess | not (null timestamps) -> + pure $ AdvisoryGitInfo + <$> parseTime (last timestamps) -- first commit is last line + <*> parseTime (head timestamps) -- most recent commit is first line + _ -> + -- `null lines` should not happen, but if it does we treat it + -- the same as `ExitFailure` + pure . Left $ GitProcessError status stdout stderr + where + parseTime :: String -> Either GitError UTCTime + parseTime s = maybe (Left $ GitTimeParseError s) Right $ + iso8601ParseM s + <|> zonedTimeToUTC <$> iso8601ParseM s diff --git a/code/hsec-tools/src/Security/Advisories/Parse.hs b/code/hsec-tools/src/Security/Advisories/Parse.hs new file mode 100644 index 00000000..b16f7f78 --- /dev/null +++ b/code/hsec-tools/src/Security/Advisories/Parse.hs @@ -0,0 +1,332 @@ +{-# LANGUAGE ApplicativeDo #-} +{-# LANGUAGE BangPatterns #-} +{-# LANGUAGE DeriveGeneric #-} +{-# LANGUAGE DerivingVia #-} +{-# LANGUAGE GeneralizedNewtypeDeriving #-} +{-# LANGUAGE LambdaCase #-} +{-# LANGUAGE MultiParamTypeClasses #-} +{-# LANGUAGE OverloadedStrings #-} +{-# OPTIONS_GHC -Wno-orphans #-} + + module Security.Advisories.Parse + ( parseAdvisory + , OOB + , OOBError (..) + , OutOfBandAttributes(..) + , displayOOBError + , AttributeOverridePolicy(..) + , ParseAdvisoryError(..) + , validateComponentIdentifier + ) +where + +import Control.Exception (Exception(displayException)) +import Data.Bifunctor (first) +import Data.Foldable (toList) +import Data.Maybe (fromMaybe) +import Data.Monoid (First(..)) + +import Data.Tuple (swap) +import Control.Applicative ((<|>)) + +import GHC.Generics (Generic) + +import Data.Sequence (Seq((:<|))) +import Data.Text (Text) +import qualified Data.Text as T +import qualified Data.Text.Lazy as T (toStrict) +import Data.Time (UTCTime(..)) + +import Commonmark.Html (Html, renderHtml) +import qualified Commonmark.Parser as Commonmark +import Commonmark.Types (HasAttributes(..), IsBlock(..), IsInline(..), Rangeable(..), SourceRange(..)) +import Commonmark.Pandoc (Cm(unCm)) +import qualified Toml +import qualified Toml.Syntax as Toml (startPos) +import qualified Toml.Schema as Toml +import Text.Pandoc.Builder (Blocks, Many(..)) +import Text.Pandoc.Definition (Block(..), Inline(..), Pandoc(..)) +import Text.Pandoc.Walk (query) +import Text.Parsec.Pos (sourceLine) + +import Security.Advisories.Core.Advisory +import Security.Advisories.Format (FrontMatter(..), AdvisoryMetadata(..)) +import Security.Advisories.Git (GitError, explainGitError) + +-- | if there are no out of band attributes, attach a reason why that's the case +-- +-- @since 0.2.0.0 +type OOB = Either OOBError OutOfBandAttributes + +-- | A source of attributes supplied out of band from the advisory +-- content. Values provided out of band are treated according to +-- the 'AttributeOverridePolicy'. +data OutOfBandAttributes = OutOfBandAttributes + { oobModified :: UTCTime + , oobPublished :: UTCTime + , oobComponentIdentifier :: Maybe ComponentIdentifier + } + deriving (Show) + +data AttributeOverridePolicy + = PreferInBand + | PreferOutOfBand + | NoOverrides -- ^ Parse error if attribute occurs both in-band and out-of-band + deriving (Show, Eq) + +data ParseAdvisoryError + = MarkdownError Commonmark.ParseError Text + | MarkdownFormatError Text + | TomlError String Text + | AdvisoryError [Toml.MatchMessage Toml.Position] T.Text + deriving stock (Eq, Show, Generic) + +-- | @since 0.2.0.0 +instance Exception ParseAdvisoryError where + displayException = T.unpack . \case + MarkdownError _ explanation -> "Markdown parsing error:\n" <> explanation + MarkdownFormatError explanation -> "Markdown structure error:\n" <> explanation + TomlError _ explanation -> "Couldn't parse front matter as TOML:\n" <> explanation + AdvisoryError _ explanation -> "Advisory structure error:\n" <> explanation + +-- | errors that may occur while ingesting oob data +-- +-- @since 0.2.0.0 +data OOBError + = StdInHasNoOOB -- ^ we obtain the advisory via stdin and can hence not parse git history + | PathHasNoComponentIdentifier -- ^ the path is missing 'hackage' or 'ghc' directory + | GitHasNoOOB GitError -- ^ processing oob info via git failed + deriving stock (Eq, Show, Generic) + +displayOOBError :: OOBError -> String +displayOOBError = \case + StdInHasNoOOB -> "stdin doesn't provide out of band information" + PathHasNoComponentIdentifier -> "the path is missing 'hackage' or 'ghc' directory" + GitHasNoOOB gitErr -> "no out of band information obtained with git error:\n" + <> explainGitError gitErr + +parseAdvisory + :: AttributeOverridePolicy + -> OOB + -> T.Text -- ^ input (CommonMark with TOML header) + -> Either ParseAdvisoryError Advisory +parseAdvisory policy attrs raw = do + markdown <- + unCm + <$> firstPretty MarkdownError (T.pack . show) + (Commonmark.commonmark "input" raw :: Either Commonmark.ParseError (Cm () Blocks)) + (frontMatter, rest) <- first MarkdownFormatError $ advisoryDoc markdown + let doc = Pandoc mempty rest + !summary <- first MarkdownFormatError $ parseAdvisorySummary doc + table <- case Toml.parse frontMatter of + Left e -> Left (TomlError e (T.pack e)) + Right t -> Right t + + -- Re-parse as FirstSourceRange to find the source range of + -- the TOML header. + FirstSourceRange (First mRange) <- + firstPretty MarkdownError (T.pack . show) (Commonmark.commonmark "input" raw) + let + details = case mRange of + Just (SourceRange ((_,end):_)) -> + T.unlines + . dropWhile T.null + . fmap snd + . dropWhile ((< sourceLine end) . fst) + . zip [1..] + $ T.lines raw + _ -> + -- no block elements? empty range list? + -- these shouldn't happen, but better be total + raw + -- Re-parse input as HTML. This will probably go away; we now store the + -- Pandoc doc and can render that instead, where needed. + html <- + T.toStrict . renderHtml + <$> firstPretty MarkdownError (T.pack . show) + (Commonmark.commonmark "input" raw :: Either Commonmark.ParseError (Html ())) + + case parseAdvisoryTable attrs policy doc summary details html table of + Left es -> Left (AdvisoryError es (T.pack (unlines (map Toml.prettyMatchMessage es)))) + Right adv -> pure adv + + where + firstPretty + :: (e -> Text -> ParseAdvisoryError) + -> (e -> Text) + -> Either e a + -> Either ParseAdvisoryError a + firstPretty ctr pretty = first $ mkPretty ctr pretty + + mkPretty + :: (e -> Text -> ParseAdvisoryError) + -> (e -> Text) + -> e + -> ParseAdvisoryError + mkPretty ctr pretty x = ctr x $ pretty x + +parseAdvisoryTable + :: OOB + -> AttributeOverridePolicy + -> Pandoc -- ^ parsed document (without frontmatter) + -> Text -- ^ summary + -> Text -- ^ details + -> Text -- ^ rendered HTML + -> Toml.Table' Toml.Position + -> Either [Toml.MatchMessage Toml.Position] Advisory +parseAdvisoryTable oob policy doc summary details html tab = + Toml.runMatcherFatalWarn $ + do fm <- Toml.fromValue (Toml.Table' Toml.startPos tab) + published <- + mergeOobMandatory policy + (oobPublished <$> oob) + displayOOBError + "advisory.date" + (amdPublished (frontMatterAdvisory fm)) + modified <- + fromMaybe published <$> + mergeOobOptional policy + (oobPublished <$> oob) + "advisory.modified" + (amdModified (frontMatterAdvisory fm)) + let affected = frontMatterAffected fm + case oob of + Right (OutOfBandAttributes _ _ (Just ecosystem)) -> validateComponentIdentifier ecosystem affected + _ -> pure () + pure Advisory + { advisoryId = amdId (frontMatterAdvisory fm) + , advisoryPublished = published + , advisoryModified = modified + , advisoryCAPECs = amdCAPECs (frontMatterAdvisory fm) + , advisoryCWEs = amdCWEs (frontMatterAdvisory fm) + , advisoryKeywords = amdKeywords (frontMatterAdvisory fm) + , advisoryAliases = amdAliases (frontMatterAdvisory fm) + , advisoryRelated = amdRelated (frontMatterAdvisory fm) + , advisoryAffected = affected + , advisoryReferences = frontMatterReferences fm + , advisoryPandoc = doc + , advisoryHtml = html + , advisorySummary = summary + , advisoryDetails = details + } + +-- | Make sure one of the affected match the ecosystem +validateComponentIdentifier :: MonadFail m => ComponentIdentifier -> [Affected] -> m () +validateComponentIdentifier ecosystem xs + | any (\affected -> affectedComponentIdentifier affected == ecosystem) xs = pure () + | otherwise = fail $ "Expected an affected to match the ecosystem: " <> show ecosystem + +advisoryDoc :: Blocks -> Either Text (Text, [Block]) +advisoryDoc (Many blocks) = case blocks of + CodeBlock (_, classes, _) frontMatter :<| t + | "toml" `elem` classes -> + pure (frontMatter, toList t) + _ -> + Left "Does not have toml code block as first element" + +parseAdvisorySummary :: Pandoc -> Either Text Text +parseAdvisorySummary = fmap inlineText . firstHeading + +firstHeading :: Pandoc -> Either Text [Inline] +firstHeading (Pandoc _ xs) = go xs + where + go [] = Left "Does not have summary heading" + go (Header _ _ ys : _) = Right ys + go (_ : t) = go t + +-- yield "plain" terminal inline content; discard formatting +inlineText :: [Inline] -> Text +inlineText = query f + where + f inl = case inl of + Str s -> s + Code _ s -> s + Space -> " " + SoftBreak -> " " + LineBreak -> "\n" + Math _ s -> s + RawInline _ s -> s + _ -> "" + +mergeOob + :: MonadFail m + => AttributeOverridePolicy + -> Either e a -- ^ out-of-band value + -> String -- ^ key + -> Maybe a -- ^ in-band-value + -> (e -> m b) -- ^ when key and out-of-band value absent + -> (a -> m b) -- ^ when value present + -> m b +mergeOob policy oob k ib absent present = do + case (oob, ib) of + (Right l, Just r) -> case policy of + NoOverrides -> fail ("illegal out of band override: " ++ k) + PreferOutOfBand -> present l + PreferInBand -> present r + (Right a, Nothing) -> present a + (Left _, Just a) -> present a + (Left e, Nothing) -> absent e + +mergeOobOptional + :: MonadFail m + => AttributeOverridePolicy + -> Either e a -- ^ out-of-band value + -> String -- ^ key + -> Maybe a -- ^ in-band-value + -> m (Maybe a) +mergeOobOptional policy oob k ib = + mergeOob policy oob k ib (const $ pure Nothing) (pure . Just) + +mergeOobMandatory + :: MonadFail m + => AttributeOverridePolicy + -> Either e a -- ^ out-of-band value + -> (e -> String) -- ^ how to display information about a missing out of band value + -> String -- ^ key + -> Maybe a -- ^ in-band value + -> m a +mergeOobMandatory policy eoob doob k ib = + mergeOob policy eoob k ib everythingFailed pure + where + everythingFailed e = fail $ unlines + [ "while trying to lookup mandatory key " <> show k <> ":" + , doob e + ] + +{- | A solution to an awkward problem: how to delete the TOML + block. We parse into this type to get the source range of + the first block element. We can use it to delete the lines + from the input. +-} +newtype FirstSourceRange = FirstSourceRange (First SourceRange) + deriving (Show, Semigroup, Monoid) + +instance Rangeable FirstSourceRange where + ranged range = (FirstSourceRange (First (Just range)) <>) + +instance HasAttributes FirstSourceRange where + addAttributes _ = id + +instance IsBlock FirstSourceRange FirstSourceRange where + paragraph _ = mempty + plain _ = mempty + thematicBreak = mempty + blockQuote _ = mempty + codeBlock _ = mempty + heading _ = mempty + rawBlock _ = mempty + referenceLinkDefinition _ = mempty + list _ = mempty + +instance IsInline FirstSourceRange where + lineBreak = mempty + softBreak = mempty + str _ = mempty + entity _ = mempty + escapedChar _ = mempty + emph = id + strong = id + link _ _ _ = mempty + image _ _ _ = mempty + code _ = mempty + rawInline _ _ = mempty diff --git a/code/hsec-tools/src/Security/Advisories/Queries.hs b/code/hsec-tools/src/Security/Advisories/Queries.hs new file mode 100644 index 00000000..06ed2b25 --- /dev/null +++ b/code/hsec-tools/src/Security/Advisories/Queries.hs @@ -0,0 +1,74 @@ +module Security.Advisories.Queries + ( listVersionAffectedBy + , listVersionRangeAffectedBy + , isVersionAffectedBy + , isVersionRangeAffectedBy + ) +where + +import Control.Monad.IO.Class (MonadIO) +import Data.Text (Text) +import Distribution.Types.Version (Version) +import Distribution.Types.VersionInterval (asVersionIntervals) +import Distribution.Types.VersionRange (VersionRange, anyVersion, earlierVersion, intersectVersionRanges, noVersion, orLaterVersion, unionVersionRanges, withinRange) +import Validation (Validation(..)) + +import Security.Advisories.Core.Advisory +import Security.Advisories.Filesystem +import Security.Advisories.Parse + +-- | Check whether a package and a version is concerned by an advisory +isVersionAffectedBy :: Text -> Version -> Advisory -> Bool +isVersionAffectedBy = isAffectedByHelper withinRange + +-- | Check whether a package and a version range is concerned by an advisory +isVersionRangeAffectedBy :: Text -> VersionRange -> Advisory -> Bool +isVersionRangeAffectedBy = isAffectedByHelper $ + \queryVersionRange affectedVersionRange -> + isSomeVersion (affectedVersionRange `intersectVersionRanges` queryVersionRange) + where + isSomeVersion :: VersionRange -> Bool + isSomeVersion range + | [] <- asVersionIntervals range = False + | otherwise = True + +-- | Helper function for 'isVersionAffectedBy' and 'isVersionRangeAffectedBy' +isAffectedByHelper :: (a -> VersionRange -> Bool) -> Text -> a -> Advisory -> Bool +isAffectedByHelper checkWithRange queryPackageName queryVersionish = + any checkAffected . advisoryAffected + where + checkAffected :: Affected -> Bool + checkAffected affected = case affectedComponentIdentifier affected of + Hackage pkg -> queryPackageName == pkg && checkWithRange queryVersionish (fromAffected affected) + -- TODO: support GHC ecosystem query, e.g. by adding a cli flag + _ -> False + + fromAffected :: Affected -> VersionRange + fromAffected = foldr (unionVersionRanges . fromAffectedVersionRange) noVersion . affectedVersions + + fromAffectedVersionRange :: AffectedVersionRange -> VersionRange + fromAffectedVersionRange avr = intersectVersionRanges + (orLaterVersion (affectedVersionRangeIntroduced avr)) + (maybe anyVersion earlierVersion (affectedVersionRangeFixed avr)) + +type QueryResult = Validation [(FilePath, ParseAdvisoryError)] [Advisory] + +-- | List the advisories matching a package name and a version +listVersionAffectedBy + :: MonadIO m + => FilePath -> Text -> Version -> m QueryResult +listVersionAffectedBy = listAffectedByHelper isVersionAffectedBy + +-- | List the advisories matching a package name and a version range +listVersionRangeAffectedBy + :: (MonadIO m) + => FilePath -> Text -> VersionRange -> m QueryResult +listVersionRangeAffectedBy = listAffectedByHelper isVersionRangeAffectedBy + +-- | Helper function for 'listVersionAffectedBy' and 'listVersionRangeAffectedBy' +listAffectedByHelper + :: (MonadIO m) + => (Text -> a -> Advisory -> Bool) -> FilePath -> Text -> a -> m QueryResult +listAffectedByHelper checkAffectedBy root queryPackageName queryVersionish = + fmap (filter (checkAffectedBy queryPackageName queryVersionish)) <$> + listAdvisories root diff --git a/code/hsec-tools/test/Spec.hs b/code/hsec-tools/test/Spec.hs new file mode 100644 index 00000000..836e19ec --- /dev/null +++ b/code/hsec-tools/test/Spec.hs @@ -0,0 +1,61 @@ +{-# LANGUAGE OverloadedStrings #-} + +module Main where + +import Data.Aeson.Encode.Pretty (encodePretty) +import Data.List (isSuffixOf) +import qualified Data.Text.IO as T +import qualified Data.Text.Lazy as LText +import qualified Data.Text.Lazy.Encoding as LText +import Data.Time (UTCTime(UTCTime)) +import Data.Time.Calendar.OrdinalDate (fromOrdinalDate) +import qualified Security.Advisories.Convert.OSV as OSV +import Security.Advisories.Parse +import qualified Spec.FormatSpec as FormatSpec +import qualified Spec.QueriesSpec as QueriesSpec +import System.Directory (listDirectory) +import Test.Tasty (defaultMain, testGroup, TestTree) +import Test.Tasty.Golden (goldenVsString) +import Text.Pretty.Simple (pShowNoColor) + +main :: IO () +main = do + goldenFiles <- listGoldenFiles + defaultMain $ + testGroup + "Tests" + [ goldenTestsSpec goldenFiles + , QueriesSpec.spec + , FormatSpec.spec + ] + +listGoldenFiles :: IO [FilePath] +listGoldenFiles = map (mappend dpath) . filter (not . isSuffixOf ".golden") <$> listDirectory dpath + where + dpath = "test/golden/" + +goldenTestsSpec :: [FilePath] -> TestTree +goldenTestsSpec goldenFiles = testGroup "Golden test" $ map doGoldenTest goldenFiles + +doGoldenTest :: FilePath -> TestTree +doGoldenTest fp = goldenVsString fp (fp <> ".golden") (LText.encodeUtf8 <$> doCheck) + where + doCheck :: IO LText.Text + doCheck = do + input <- T.readFile fp + let fakeDate = UTCTime (fromOrdinalDate 1970 0) 0 + attr = OutOfBandAttributes + { oobPublished = fakeDate + , oobModified = fakeDate + , oobComponentIdentifier = Nothing + } + res = parseAdvisory NoOverrides (Right attr) input + osvExport = case res of + Right adv -> + let osv = OSV.convert adv + in LText.unlines + [ pShowNoColor osv + , LText.decodeUtf8 (encodePretty osv) + ] + Left _ -> "" + pure (LText.unlines [pShowNoColor res, osvExport]) diff --git a/code/hsec-tools/test/Spec/FormatSpec.hs b/code/hsec-tools/test/Spec/FormatSpec.hs new file mode 100644 index 00000000..8a4e1d7a --- /dev/null +++ b/code/hsec-tools/test/Spec/FormatSpec.hs @@ -0,0 +1,168 @@ +{-# LANGUAGE DerivingStrategies #-} +{-# LANGUAGE GeneralizedNewtypeDeriving #-} +{-# LANGUAGE OverloadedStrings #-} + +module Spec.FormatSpec (spec) where + +import Data.Fixed (Fixed (MkFixed)) +import Data.Function (on) +import qualified Data.Map.Strict as Map +import Data.Text (Text) +import qualified Data.Text as T +import Data.Time +import Distribution.Types.Version +import Distribution.Types.VersionRange +import qualified Hedgehog as Gen +import qualified Hedgehog.Gen as Gen +import qualified Hedgehog.Range as Range +import qualified Prettyprinter as Pretty +import qualified Prettyprinter.Render.Text as Pretty +import Security.Advisories.Core.Advisory +import Security.Advisories.Core.HsecId +import Security.Advisories.Format +import Security.CVSS +import Security.OSV (Reference (..), ReferenceType (..)) +import Test.Tasty +import Test.Tasty.Hedgehog +import qualified Toml + +spec :: TestTree +spec = + testGroup + "Format" + [ testGroup + "FrontMatter" + [ testProperty "parse . render == id" $ + Gen.property $ do + fm <- Gen.forAll genFrontMatter + let rendered = + Pretty.renderStrict $ Pretty.layoutPretty Pretty.defaultLayoutOptions $ Toml.encode fm + Gen.footnote $ T.unpack rendered + Toml.decode rendered Gen.=== Toml.Success mempty (FrontMatterEq fm) + ] + ] + +newtype FrontMatterEq = FrontMatterEq {unFrontMatter :: FrontMatter} + deriving newtype (Show, FromValue) + +instance Eq FrontMatterEq where + (==) = (==) `on` show . unFrontMatter + +genFrontMatter :: Gen.Gen FrontMatter +genFrontMatter = + FrontMatter + <$> genAdvisoryMetadata + <*> Gen.list (Range.linear 0 10) genReference + <*> Gen.list (Range.linear 0 10) genAffected + +genAdvisoryMetadata :: Gen.Gen AdvisoryMetadata +genAdvisoryMetadata = + AdvisoryMetadata + <$> genHsecId + <*> Gen.maybe genUTCTime + <*> Gen.maybe genUTCTime + <*> Gen.list (Range.linear 0 5) genCAPEC + <*> Gen.list (Range.linear 0 5) genCWE + <*> Gen.list (Range.linear 0 5) genKeyword + <*> Gen.list (Range.linear 0 5) genText + <*> Gen.list (Range.linear 0 5) genText + +genAffected :: Gen.Gen Affected +genAffected = + Affected + <$> genComponentIdentifier + <*> genCVSS + <*> Gen.list (Range.linear 0 5) genAffectedVersionRange + <*> Gen.maybe (Gen.list (Range.linear 0 5) genArchitecture) + <*> Gen.maybe (Gen.list (Range.linear 0 5) genOS) + <*> (Map.toList . Map.fromList <$> Gen.list (Range.linear 0 5) ((,) <$> genText <*> genVersionRange)) + +genComponentIdentifier :: Gen.Gen ComponentIdentifier +genComponentIdentifier = Gen.choice $ + [ Hackage <$> genText + , GHC <$> Gen.enumBounded + ] + +genCVSS :: Gen.Gen CVSS +genCVSS = + Gen.choice $ + map + (\x -> either (\e -> error $ "Cannot parse CVSS " <> show x <> " " <> show e) return $ parseCVSS x) + [ "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:N/I:L/A:N", + "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:L/I:L/A:N", + "CVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:U/C:L/I:N/A:N", + "CVSS:3.0/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N", + "CVSS:3.0/AV:N/AC:L/PR:L/UI:N/S:C/C:L/I:L/A:N", + "CVSS:3.0/AV:N/AC:H/PR:N/UI:R/S:U/C:L/I:N/A:N", + "CVSS:3.0/AV:L/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:N", + "CVSS:3.0/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H", + "CVSS:3.0/AV:L/AC:L/PR:H/UI:N/S:U/C:L/I:L/A:L", + "AV:N/AC:L/Au:N/C:N/I:N/A:C", + "AV:N/AC:L/Au:N/C:C/I:C/A:C", + "AV:L/AC:H/Au:N/C:C/I:C/A:C" + ] + +genCAPEC :: Gen.Gen CAPEC +genCAPEC = CAPEC <$> Gen.integral (Range.linear 100 999) + +genCWE :: Gen.Gen CWE +genCWE = CWE <$> Gen.integral (Range.linear 100 999) + +genHsecId :: Gen.Gen HsecId +genHsecId = flip nextHsecId placeholder <$> Gen.integral (Range.linear 2024 2032) + +genUTCTime :: Gen.Gen UTCTime +genUTCTime = + UTCTime + <$> genDay + <*> fmap secondsToDiffTime (Gen.integral $ Range.constant 0 86401) + +genDay :: Gen.Gen Day +genDay = do + y <- toInteger <$> Gen.int (Range.constant 1968 2019) + m <- Gen.int (Range.constant 1 12) + d <- Gen.int (Range.constant 1 28) + pure $ fromGregorian y m d + +genVersionRange :: Gen.Gen VersionRange +genVersionRange = + Gen.recursive + Gen.choice + [ pure anyVersion, + pure noVersion, + thisVersion <$> genVersion, + notThisVersion <$> genVersion, + laterVersion <$> genVersion, + earlierVersion <$> genVersion, + orLaterVersion <$> genVersion, + orEarlierVersion <$> genVersion, + withinVersion <$> genVersion, + majorBoundVersion <$> genVersion + ] + [ Gen.subterm2 genVersionRange genVersionRange unionVersionRanges, + Gen.subterm2 genVersionRange genVersionRange intersectVersionRanges + ] + +genText :: Gen.Gen Text +genText = Gen.text (Range.linear 1 20) Gen.alphaNum + +genAffectedVersionRange :: Gen.Gen AffectedVersionRange +genAffectedVersionRange = AffectedVersionRange <$> genVersion <*> Gen.maybe genVersion + +genVersion :: Gen.Gen Version +genVersion = mkVersion <$> Gen.list (Range.linear 1 5) (Gen.integral (Range.linear 0 999)) + +genArchitecture :: Gen.Gen Architecture +genArchitecture = Gen.enumBounded + +genOS :: Gen.Gen OS +genOS = Gen.enumBounded + +genKeyword :: Gen.Gen Keyword +genKeyword = Keyword <$> genText + +genReference :: Gen.Gen Reference +genReference = Reference <$> genReferenceType <*> genText + +genReferenceType :: Gen.Gen ReferenceType +genReferenceType = Gen.enumBounded diff --git a/code/hsec-tools/test/Spec/QueriesSpec.hs b/code/hsec-tools/test/Spec/QueriesSpec.hs new file mode 100644 index 00000000..54be3d90 --- /dev/null +++ b/code/hsec-tools/test/Spec/QueriesSpec.hs @@ -0,0 +1,194 @@ +{-# LANGUAGE LambdaCase #-} +{-# LANGUAGE OverloadedStrings #-} + +module Spec.QueriesSpec (spec) where + +import Data.Bifunctor (first) +import Data.Either (fromRight) +import Data.Maybe (fromMaybe) +import Data.Text (Text) +import qualified Data.Text as T +import Distribution.Parsec (eitherParsec) +import Distribution.Types.Version (version0, alterVersion) +import Distribution.Types.VersionRange (VersionRange, VersionRangeF(..), anyVersion, projectVersionRange) +import Test.Tasty +import Test.Tasty.HUnit + +import Security.CVSS (parseCVSS) +import Security.Advisories.Core.Advisory +import Security.Advisories.Core.HsecId +import Security.Advisories.Queries + +spec :: TestTree +spec = + testGroup "Queries" [ + testGroup "isAffectedBy" $ + flip concatMap cases $ map $ \(actual, query, expected) -> + let title x y = + if expected + then show x <> " is vulnerable to " <> show y + else show x <> " is not vulnerable to " <> show y + versionRange x = + either (\e -> error $ "Cannot parse version range " <> show x <> " : " <> show e) id $ + parseVersionRange $ + if x == "" + then Nothing + else Just x + in testCase (title actual query) $ + let query' = versionRange query + affectedVersion' = versionRange actual + in isVersionRangeAffectedBy packageName query' (mkAdvisory affectedVersion') + @?= expected + ] + +cases :: [[(Text, Text, Bool)]] +cases = + [ + reversible ("", "", True) + , reversible ("", "==1", True) + , reversible ("==1.1", "<=2", True) + , reversible ("==1.1", ">1", True) + , reversible ("==1", "==1", True) + , reversible ("==2||==1", "==1", True) + , reversible ("==1.1", "<=2&&>1", True) + , reversible ("^>=1", ">1&&<1.2", True) + , reversible (">=1", "==2", True) + , reversible (">=1", "==1", True) + , reversible ("==2", ">=2", True) + , reversible ("==2", ">1", True) + , reversible (">5", ">=2", True) + , reversible (">5", ">2", True) + , reversible ("==5", ">=2", True) + , reversible ("==5", ">2", True) + , reversible (">=5", ">2", True) + , reversible ("<=5", ">2", True) + , reversible ("<=5", "<=2", True) + , reversible ("<5", ">=2", True) + , reversible (">=2", "==5", True) + , reversible (">2", "==5", True) + , reversible (">5", ">=5", True) + , reversible ("^>=1.1", ">1", True) + , reversible ("^>=1.1", "<2", True) + , reversible ("^>=1.1", "<=1.2", True) + , reversible ("^>=1.1", ">1.1", True) + , reversible ("^>=1.1", ">=1.1.5", True) + , reversible ("^>=1.1", ">=1", True) + , reversible ("==1.1", "<1", False) + , reversible ("==2.1", "<=2", False) + , reversible ("==1", ">1.1", False) + , reversible ("==2", "==1", False) + , reversible ("==2||==1", ">3", False) + , notReversible ("<=2&&>1", "==3", True) + , reversible (">=2", "==1.1", False) + , reversible (">=1.1", "==1", False) + , reversible ("==2", ">=2.1", False) + , notReversible (">1", "==1", False) + , reversible ("<2", ">=2", False) + , reversible ("==2", ">=5", False) + , reversible ("==2", ">5", False) + , reversible ("<=2", ">5", False) + , reversible ("<=2", ">5", False) + , reversible ("<2", ">=5", False) + , reversible (">=2", "==1.1", False) + , reversible ("<2", "==5", False) + , reversible ("<5", ">=5", False) + , reversible ("^>=1.1", "<1", False) + , reversible ("^>=1.1", "<1.1", False) + , reversible ("^>=1.1", ">=1.2", False) + , reversible ("^>=1.1", "<=1", False) + , reversible ("^>=1.1", ">2", False) + , reversible ("^>=1", ">=2", False) + ] + where reversible (query, affectedVersion, expected) = [(query, affectedVersion, expected), (query, affectedVersion, expected)] + notReversible (query, affectedVersion, expected) = [(query, affectedVersion, expected), (affectedVersion, query, not expected)] + +mkAdvisory :: VersionRange -> Advisory +mkAdvisory versionRange = + Advisory + { advisoryId = fromMaybe (error "Cannot mkHsecId") $ mkHsecId 2023 42 + , advisoryModified = read "2023-01-01T00:00:00" + , advisoryPublished = read "2023-01-01T00:00:00" + , advisoryCAPECs = [] + , advisoryCWEs = [] + , advisoryKeywords = [] + , advisoryAliases = [ "CVE-2022-XXXX" ] + , advisoryRelated = [ "CVE-2022-YYYY" , "CVE-2022-ZZZZ" ] + , advisoryAffected = + [ Affected + { affectedComponentIdentifier = Hackage packageName + , affectedCVSS = cvss + , affectedVersions = mkAffectedVersions versionRange + , affectedArchitectures = Nothing + , affectedOS = Nothing + , affectedDeclarations = [] + } + ] + , advisoryReferences = [] + , advisoryPandoc = mempty + , advisoryHtml = "" + , advisorySummary = "" + , advisoryDetails = "" + } + where + cvss = fromRight (error "Cannot parseCVSS") (parseCVSS "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H") + +mkAffectedVersions :: VersionRange -> [AffectedVersionRange] +mkAffectedVersions vr = + let + fixed from to = + AffectedVersionRange + { affectedVersionRangeIntroduced = from + , affectedVersionRangeFixed = Just to + } + onlyFixed to = + AffectedVersionRange + { affectedVersionRangeIntroduced = version0 + , affectedVersionRangeFixed = Just to + } + vulnerable from = + AffectedVersionRange + { affectedVersionRangeIntroduced = from + , affectedVersionRangeFixed = Nothing + } + nextMinor = + \case + [] -> [1] + [x] -> [x, 1] + [x, y] -> [x, y, 1] + [x, y, z] -> [x, y, z, 1] + [w, x, y, z] -> [w, x, y, z + 1] + xs -> xs ++ [1] + previousMinor = + \case + [] -> [0] + [x] -> [x - 1 , 99] + [x, y] -> [x, y - 1, 99] + [x, y, z] -> [x, y, z - 1, 99] + [w, x, y, z] -> [w, x, y, z - 1] + _ -> error "TODO" + mkMajorBoundVersion = + \case + [] -> [0] + [x] -> [x, 1] + (x:y:_) -> [x, y + 1] + in + case projectVersionRange vr of + ThisVersionF x -> [fixed x $ alterVersion (<> [0,0,1]) x] + LaterVersionF x -> [vulnerable $ alterVersion nextMinor x] + OrLaterVersionF x -> [vulnerable x] + EarlierVersionF x -> [onlyFixed $ alterVersion previousMinor x] + OrEarlierVersionF x -> [onlyFixed x] + MajorBoundVersionF x -> [fixed x $ alterVersion mkMajorBoundVersion x] + UnionVersionRangesF x y -> mkAffectedVersions x <> mkAffectedVersions y + IntersectVersionRangesF x y -> + [ low { affectedVersionRangeFixed = affectedVersionRangeFixed high } + | low <- mkAffectedVersions x + , high <- mkAffectedVersions y + ] + +packageName :: Text +packageName = "package-name" + +-- | Parse 'VersionRange' as given to the CLI +parseVersionRange :: Maybe Text -> Either Text VersionRange +parseVersionRange = maybe (return anyVersion) (first T.pack . eitherParsec . T.unpack) diff --git a/code/hsec-tools/test/golden/EXAMPLE_ADVISORY.md b/code/hsec-tools/test/golden/EXAMPLE_ADVISORY.md new file mode 100644 index 00000000..47a8ffe5 --- /dev/null +++ b/code/hsec-tools/test/golden/EXAMPLE_ADVISORY.md @@ -0,0 +1,32 @@ +```toml + +[advisory] +id = "HSEC-0000-0000" +cwe = [] +keywords = ["example", "freeform", "keywords"] +aliases = ["CVE-2022-XXXX"] +related = ["CVE-2022-YYYY", "CVE-2022-ZZZZ"] + +[[affected]] +package = "package-name" +cvss = "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H" + +[[affected.versions]] +introduced = "1.0.8" +fixed = "1.1" +[[affected.versions]] +introduced = "1.1.2" + +[[references]] +type = "ARTICLE" +url = "https://example.com" +``` + +# Advisory Template - Title Goes Here + +This is an example template. + + * Markdown + * TOML "front matter". + + > Acme Broken. diff --git a/code/hsec-tools/test/golden/EXAMPLE_ADVISORY.md.golden b/code/hsec-tools/test/golden/EXAMPLE_ADVISORY.md.golden new file mode 100644 index 00000000..62dda0c3 --- /dev/null +++ b/code/hsec-tools/test/golden/EXAMPLE_ADVISORY.md.golden @@ -0,0 +1,259 @@ +Right + ( Advisory + { advisoryId = HSEC-0000-0000 + , advisoryModified = 1970-01-01 00:00:00 UTC + , advisoryPublished = 1970-01-01 00:00:00 UTC + , advisoryCAPECs = [] + , advisoryCWEs = [] + , advisoryKeywords = + [ "example" + , "freeform" + , "keywords" + ] + , advisoryAliases = [ "CVE-2022-XXXX" ] + , advisoryRelated = + [ "CVE-2022-YYYY" + , "CVE-2022-ZZZZ" + ] + , advisoryAffected = + [ Affected + { affectedComponentIdentifier = Hackage "package-name" + , affectedCVSS = CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H + , affectedVersions = + [ AffectedVersionRange + { affectedVersionRangeIntroduced = mkVersion + [ 1 + , 0 + , 8 + ] + , affectedVersionRangeFixed = Just + ( mkVersion + [ 1 + , 1 + ] + ) + } + , AffectedVersionRange + { affectedVersionRangeIntroduced = mkVersion + [ 1 + , 1 + , 2 + ] + , affectedVersionRangeFixed = Nothing + } + ] + , affectedArchitectures = Nothing + , affectedOS = Nothing + , affectedDeclarations = [] + } + ] + , advisoryReferences = + [ Reference + { referencesType = ReferenceTypeArticle + , referencesUrl = "https://example.com" + } + ] + , advisoryPandoc = Pandoc + ( Meta + { unMeta = fromList [] } + ) + [ Header 1 + ( "" + , [] + , [] + ) + [ Str "Advisory" + , Space + , Str "Template" + , Space + , Str "-" + , Space + , Str "Title" + , Space + , Str "Goes" + , Space + , Str "Here" + ] + , Para + [ Str "This" + , Space + , Str "is" + , Space + , Str "an" + , Space + , Str "example" + , Space + , Str "template." + ] + , BulletList + [ + [ Plain + [ Str "Markdown" ] + ] + , + [ Plain + [ Str "TOML" + , Space + , Str ""front" + , Space + , Str "matter"." + ] + ] + ] + , BlockQuote + [ Para + [ Str "Acme" + , Space + , Str "Broken." + ] + ] + ] + , advisoryHtml = "

+          [advisory]
+          id = "HSEC-0000-0000"
+          cwe = []
+          keywords = ["example", "freeform", "keywords"]
+          aliases = ["CVE-2022-XXXX"]
+          related = ["CVE-2022-YYYY", "CVE-2022-ZZZZ"]
+
+          [[affected]]
+          package = "package-name"
+          cvss = "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H"
+
+          [[affected.versions]]
+          introduced = "1.0.8"
+          fixed = "1.1"
+          [[affected.versions]]
+          introduced = "1.1.2"
+
+          [[references]]
+          type = "ARTICLE"
+          url = "https://example.com"
+          
+

Advisory Template - Title Goes Here

+

This is an example template.

+
    +
  • Markdown +
  • +
  • TOML "front matter". +
  • +
+
+

Acme Broken.

+
+ " + , advisorySummary = "Advisory Template - Title Goes Here" + , advisoryDetails = "# Advisory Template - Title Goes Here + + This is an example template. + + * Markdown + * TOML "front matter". + + > Acme Broken. + " + } + ) +Model + { modelSchemaVersion = "1.5.0" + , modelId = "HSEC-0000-0000" + , modelModified = 1970-01-01 00:00:00 UTC + , modelPublished = Just 1970-01-01 00:00:00 UTC + , modelWithdrawn = Nothing + , modelAliases = [ "CVE-2022-XXXX" ] + , modelRelated = + [ "CVE-2022-YYYY" + , "CVE-2022-ZZZZ" + ] + , modelSummary = Just "Advisory Template - Title Goes Here" + , modelDetails = Just "# Advisory Template - Title Goes Here + + This is an example template. + + * Markdown + * TOML "front matter". + + > Acme Broken. + " + , modelSeverity = [] + , modelAffected = + [ Affected + { affectedRanges = + [ RangeEcosystem + [ EventIntroduced "1.0.8" + , EventFixed "1.1" + , EventIntroduced "1.1.2" + ] Nothing + ] + , affectedPackage = Package + { packageName = "package-name" + , packageEcosystem = "Hackage" + , packagePurl = Nothing + } + , affectedSeverity = + [ Severity CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H ] + , affectedEcosystemSpecific = Nothing + , affectedDatabaseSpecific = Nothing + } + ] + , modelReferences = + [ Reference + { referencesType = ReferenceTypeArticle + , referencesUrl = "https://example.com" + } + ] + , modelCredits = [] + , modelDatabaseSpecific = Nothing + } +{ + "affected": [ + { + "package": { + "ecosystem": "Hackage", + "name": "package-name" + }, + "ranges": [ + { + "events": [ + { + "introduced": "1.0.8" + }, + { + "fixed": "1.1" + }, + { + "introduced": "1.1.2" + } + ], + "type": "ECOSYSTEM" + } + ], + "severity": [ + { + "score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H", + "type": "CVSS_V3" + } + ] + } + ], + "aliases": [ + "CVE-2022-XXXX" + ], + "details": "# Advisory Template - Title Goes Here\n\nThis is an example template.\n\n * Markdown\n * TOML \"front matter\".\n\n > Acme Broken.\n", + "id": "HSEC-0000-0000", + "modified": "1970-01-01T00:00:00Z", + "published": "1970-01-01T00:00:00Z", + "references": [ + { + "type": "ARTICLE", + "url": "https://example.com" + } + ], + "related": [ + "CVE-2022-YYYY", + "CVE-2022-ZZZZ" + ], + "schema_version": "1.5.0", + "summary": "Advisory Template - Title Goes Here" +} + diff --git a/code/hsec-tools/test/golden/MISSING_AFFECTED.md b/code/hsec-tools/test/golden/MISSING_AFFECTED.md new file mode 100644 index 00000000..2242023c --- /dev/null +++ b/code/hsec-tools/test/golden/MISSING_AFFECTED.md @@ -0,0 +1,7 @@ +```toml +[advisory] +id = "HSEC-0000-0000" +cwe = [] +``` + +## Title diff --git a/code/hsec-tools/test/golden/MISSING_AFFECTED.md.golden b/code/hsec-tools/test/golden/MISSING_AFFECTED.md.golden new file mode 100644 index 00000000..c08d6850 --- /dev/null +++ b/code/hsec-tools/test/golden/MISSING_AFFECTED.md.golden @@ -0,0 +1,17 @@ +Left + ( AdvisoryError + [ MatchMessage + { matchAnn = Just + ( Position + { posIndex = 0 + , posLine = 1 + , posColumn = 1 + } + ) + , matchPath = [] + , matchMessage = "missing key: affected" + } + ] "1:1: missing key: affected in + " + ) + diff --git a/code/hsec-tools/test/golden/MISSING_TITLE.md b/code/hsec-tools/test/golden/MISSING_TITLE.md new file mode 100644 index 00000000..e8ece844 --- /dev/null +++ b/code/hsec-tools/test/golden/MISSING_TITLE.md @@ -0,0 +1,6 @@ +```toml +[advisory] +id = "HSEC-0000-0000" +cwe = [] +date = 1970-01-01 +``` diff --git a/code/hsec-tools/test/golden/MISSING_TITLE.md.golden b/code/hsec-tools/test/golden/MISSING_TITLE.md.golden new file mode 100644 index 00000000..60d66e48 --- /dev/null +++ b/code/hsec-tools/test/golden/MISSING_TITLE.md.golden @@ -0,0 +1,3 @@ +Left + ( MarkdownFormatError "Does not have summary heading" ) + diff --git a/code/osv/.gitignore b/code/osv/.gitignore new file mode 100644 index 00000000..c5e63c97 --- /dev/null +++ b/code/osv/.gitignore @@ -0,0 +1,30 @@ +##### Haskell +dist +dist-* +cabal-dev +*.o +*.hi +*.hie +*.chi +*.chs.h +*.dyn_o +*.dyn_hi +.hpc +.hsenv +.cabal-sandbox/ +cabal.sandbox.config +*.prof +*.aux +*.hp +*.eventlog +.stack-work/ +cabal.project.local +cabal.project.local~ +.HTF/ +.ghc.environment.* +build +bin-* + +result +.direnv +.env diff --git a/code/osv/CHANGELOG.md b/code/osv/CHANGELOG.md new file mode 100644 index 00000000..e69de29b diff --git a/code/osv/README.md b/code/osv/README.md new file mode 100644 index 00000000..eb2d86dc --- /dev/null +++ b/code/osv/README.md @@ -0,0 +1,7 @@ +# osv + +This project aims to support [Open Source Vulnerability format](https://ossf.github.io/osv-schema/). + +## Building + +We aim to support both regular cabal-based and nix-based builds. diff --git a/code/osv/osv.cabal b/code/osv/osv.cabal new file mode 100644 index 00000000..2f0edf56 --- /dev/null +++ b/code/osv/osv.cabal @@ -0,0 +1,59 @@ +cabal-version: 2.4 +name: osv +version: 0.1.0.2 + +-- A short (one-line) description of the package. +synopsis: + Open Source Vulnerability format + +-- A longer description of the package. +description: + Open Source Vulnerability format. + +-- A URL where users can report bugs. +-- bug-reports: + +-- The license under which the package is released. +license: BSD-3-Clause +author: Haskell Security Response Team +maintainer: security-advisories@haskell.org + +-- A copyright notice. +-- copyright: +category: Data +extra-doc-files: CHANGELOG.md + +tested-with: + GHC ==8.10.7 || ==9.0.2 || ==9.2.8 || ==9.4.8 || ==9.6.3 || ==9.8.1 + +library + exposed-modules: + Security.OSV + + build-depends: + , aeson >=2.0.1.0 && <3 + , base >=4.14 && <4.21 + , cvss >=0.2 && <0.3 + , text >=1.2 && <3 + , time >=1.9 && <1.15 + + hs-source-dirs: src + default-language: Haskell2010 + ghc-options: + -Wall -Wcompat -Widentities -Wincomplete-record-updates + -Wincomplete-uni-patterns -Wpartial-fields -Wredundant-constraints + +test-suite spec + type: exitcode-stdio-1.0 + hs-source-dirs: test + main-is: Spec.hs + build-depends: + , base <5 + , osv + , tasty <1.5 + , tasty-hunit <0.11 + + default-language: Haskell2010 + ghc-options: + -Wall -Wcompat -Widentities -Wincomplete-record-updates + -Wincomplete-uni-patterns -Wpartial-fields -Wredundant-constraints diff --git a/code/osv/src/Security/OSV.hs b/code/osv/src/Security/OSV.hs new file mode 100644 index 00000000..745b4207 --- /dev/null +++ b/code/osv/src/Security/OSV.hs @@ -0,0 +1,483 @@ +-- | This module contains the OSV datatype and its ToJSON instance. +-- The module was initialized with http://json-to-haskell.chrispenner.ca/ +{-# LANGUAGE DuplicateRecordFields #-} +{-# LANGUAGE RecordWildCards #-} +{-# LANGUAGE OverloadedStrings #-} + +module Security.OSV + ( + -- * Top-level data type + Model(..) + , newModel + , newModel' + , defaultSchemaVersion + + -- * Subsidiary data types + , Affected(..) + , Credit(..) + , CreditType(..) + , creditTypes + , Event(..) + , Package(..) + , Range(..) + , Reference(..) + , ReferenceType(..) + , referenceTypes + , Severity(..) + ) + where + +import Control.Applicative ((<|>)) +import Control.Monad (when) +import Data.Maybe (catMaybes, fromMaybe) +import Data.Aeson + ( ToJSON(..), FromJSON(..), Value(..) + , (.:), (.:?), (.=), object, withObject, withText + ) +import Data.Aeson.Types + ( Key, Object, Parser + , explicitParseField, explicitParseFieldMaybe, prependFailure, typeMismatch + ) +import Data.Text (Text) +import qualified Data.Text as T +import Data.Time (UTCTime) +import Data.Time.Format.ISO8601 (iso8601ParseM) +import Data.Tuple (swap) + +import qualified Security.CVSS as CVSS + +data Affected dbSpecific ecosystemSpecific rangeDbSpecific = Affected + { affectedRanges :: [Range rangeDbSpecific] + , affectedPackage :: Package + , affectedSeverity :: [Severity] + , affectedEcosystemSpecific :: Maybe ecosystemSpecific + , affectedDatabaseSpecific :: Maybe dbSpecific + } deriving (Show, Eq) + +data Event a + = EventIntroduced a + | EventFixed a + | EventLastAffected a + | EventLimit a + deriving (Eq, Ord, Show) + +instance (FromJSON a) => FromJSON (Event a) where + parseJSON = withObject "events[]" $ \o -> do + -- there must exactly one key + when (length o /= 1) $ typeMismatch "events[]" (Object o) + prependFailure "unknown event type" $ + EventIntroduced <$> o .: "introduced" + <|> EventFixed <$> o .: "fixed" + <|> EventLastAffected <$> o .: "last_affected" + <|> EventLimit <$> o .: "limit" + +instance (ToJSON a) => ToJSON (Event a) where + toJSON ev = object . pure $ case ev of + EventIntroduced a -> "introduced" .= a + EventFixed a -> "fixed" .= a + EventLastAffected a -> "last_affected" .= a + EventLimit a -> "limit" .= a + +-- | OSV model parameterised over database-specific and +-- ecosystem-specific fields. +-- +-- A naĂŻve consumer can parse @'Model' 'Value' Value Value Value@ +-- for no loss of information. +-- +-- A producer can instantiate unused database/ecosystem-specific +-- fields at @Data.Void.Void@. '()' is not recommended, because +-- @'Just' ()@ will serialise as an empty JSON array. +-- +data Model dbSpecific affectedEcosystemSpecific affectedDbSpecific rangeDbSpecific = Model + { modelSchemaVersion :: Text -- TODO make it a proper semver version type + , modelId :: Text -- TODO we should newtype it + , modelModified :: UTCTime + , modelPublished :: Maybe UTCTime + , modelWithdrawn :: Maybe UTCTime + , modelAliases :: [Text] + , modelRelated :: [Text] + , modelSummary :: Maybe Text + -- ^ A one-line, English textual summary of the vulnerability. It is + -- recommended that this field be kept short, on the order of no more than + -- 120 characters. + , modelDetails :: Maybe Text + -- ^ CommonMark markdown giving additional English textual details about + -- the vulnerability. + , modelSeverity :: [Severity] + , modelAffected :: [Affected affectedEcosystemSpecific affectedDbSpecific rangeDbSpecific] + , modelReferences :: [Reference] + , modelCredits :: [Credit] + , modelDatabaseSpecific :: Maybe dbSpecific + } deriving (Show, Eq) + +-- | Schema version implemented by this library. Currently @1.5.0@. +defaultSchemaVersion :: Text +defaultSchemaVersion = "1.5.0" + +-- | Construct a new model with only the required fields +newModel + :: Text -- ^ schema version + -> Text -- ^ id + -> UTCTime -- ^ modified + -> Model dbs aes adbs rdbs +newModel ver ident modified = Model + ver + ident + modified + Nothing + Nothing + [] + [] + Nothing + Nothing + [] + [] + [] + [] + Nothing + +-- | Construct a new model given @id@ and @modified@ values, +-- using 'defaultSchemaVersion'. +newModel' + :: Text -- ^ id + -> UTCTime -- ^ modified + -> Model dbs aes adbs rdbs +newModel' = newModel defaultSchemaVersion + +-- | Severity. There is no 'Ord' instance. Severity scores should be +-- calculated and compared in a more nuanced way than 'Ord' can provide +-- for. +-- +newtype Severity = Severity CVSS.CVSS + deriving (Show) + +instance Eq Severity where + Severity s1 == Severity s2 = CVSS.cvssVectorString s1 == CVSS.cvssVectorString s2 + +instance FromJSON Severity where + parseJSON = withObject "severity" $ \o -> do + typ <- o .: "type" :: Parser Text + score <- o .: "score" :: Parser Text + cvss <- case CVSS.parseCVSS score of + Right cvss -> pure cvss + Left err -> + prependFailure ("unregognised severity score: " <> show err) + $ typeMismatch "severity" (Object o) + case typ of + "CVSS_V2" | CVSS.cvssVersion cvss == CVSS.CVSS20 -> pure $ Severity cvss + "CVSS_V3" | CVSS.cvssVersion cvss `elem` [CVSS.CVSS30, CVSS.CVSS31] -> pure $ Severity cvss + s -> + prependFailure ("unregognised severity type: " <> show s) + $ typeMismatch "severity" (Object o) + +instance ToJSON Severity where + toJSON (Severity cvss) = object ["score" .= CVSS.cvssVectorString cvss, "type" .= typ] + where + typ :: Text + typ = case CVSS.cvssVersion cvss of + CVSS.CVSS31 -> "CVSS_V3" + CVSS.CVSS30 -> "CVSS_V3" + CVSS.CVSS20 -> "CVSS_V2" + +data Package = Package + { packageName :: Text + , packageEcosystem :: Text + , packagePurl :: Maybe Text -- TODO refine type + } deriving (Show, Eq, Ord) + +data Range dbSpecific + = RangeSemVer [Event Text {- TODO refine -}] (Maybe dbSpecific) + | RangeEcosystem [Event Text] (Maybe dbSpecific) + | RangeGit + [Event Text {- TODO refine -}] + Text -- ^ Git repo URL + (Maybe dbSpecific) + deriving (Eq, Show) + +instance (FromJSON dbSpecific) => FromJSON (Range dbSpecific) where + parseJSON = withObject "ranges[]" $ \o -> do + typ <- o .: "type" :: Parser Text + case typ of + "SEMVER" -> RangeSemVer <$> o .: "events" <*> o .:? "database_specific" + "ECOSYSTEM" -> RangeEcosystem <$> o .: "events" <*> o .:? "database_specific" + "GIT" -> RangeGit <$> o .: "events" <*> o .: "repo" <*> o .:? "database_specific" + s -> + prependFailure ("unregognised range type: " <> show s) + $ typeMismatch "ranges[]" (Object o) + +instance (ToJSON dbSpecific) => ToJSON (Range dbSpecific) where + toJSON range = object $ case range of + RangeSemVer evs dbs -> [typ "SEMVER", "events" .= evs] <> mkDbSpecific dbs + RangeEcosystem evs dbs -> [typ "ECOSYSTEM", "events" .= evs] <> mkDbSpecific dbs + RangeGit evs repo dbs -> [typ "GIT", "events" .= evs, "repo" .= repo] <> mkDbSpecific dbs + where + mkDbSpecific = maybe [] (\v -> ["database_specific" .= v]) + typ s = "type" .= (s :: Text) + +data ReferenceType + = ReferenceTypeAdvisory + -- ^ A published security advisory for the vulnerability. + | ReferenceTypeArticle + -- ^ An article or blog post describing the vulnerability. + | ReferenceTypeDetection + -- ^ A tool, script, scanner, or other mechanism that allows for detection of + -- the vulnerability in production environments. e.g. YARA rules, hashes, + -- virus signature, or other scanners. + | ReferenceTypeDiscussion + -- ^ A social media discussion regarding the vulnerability, e.g. a Twitter, + -- Mastodon, Hacker News, or Reddit thread. + | ReferenceTypeReport + -- ^ A report, typically on a bug or issue tracker, of the vulnerability. + | ReferenceTypeFix + -- ^ A source code browser link to the fix (e.g., a GitHub commit) Note that + -- the @Fix@ type is meant for viewing by people using web browsers. Programs + -- interested in analyzing the exact commit range would do better to use the + -- GIT-typed affected 'Range' entries. + | ReferenceTypeIntroduced + -- ^ A source code browser link to the introduction of the vulnerability + -- (e.g., a GitHub commit) Note that the introduced type is meant for viewing + -- by people using web browsers. Programs interested in analyzing the exact + -- commit range would do better to use the GIT-typed affected 'Range' + -- entries. + | ReferenceTypePackage + -- ^ A home web page for the package. + | ReferenceTypeEvidence + -- ^ A demonstration of the validity of a vulnerability claim, e.g. + -- @app.any.run@ replaying the exploitation of the vulnerability. + | ReferenceTypeWeb + -- ^ A web page of some unspecified kind. + deriving (Show, Eq, Enum, Bounded) + +-- | Bijection of reference types and their string representations +referenceTypes :: [(ReferenceType, Text)] +referenceTypes = + [ (ReferenceTypeAdvisory , "ADVISORY") + , (ReferenceTypeArticle , "ARTICLE") + , (ReferenceTypeDetection , "DETECTION") + , (ReferenceTypeDiscussion , "DISCUSSION") + , (ReferenceTypeReport , "REPORT") + , (ReferenceTypeFix , "FIX") + , (ReferenceTypeIntroduced , "INTRODUCED") + , (ReferenceTypePackage , "PACKAGE") + , (ReferenceTypeEvidence , "EVIDENCE") + , (ReferenceTypeWeb , "WEB") + ] + +instance FromJSON ReferenceType where + parseJSON = withText "references.type" $ \s -> + case lookup s (fmap swap referenceTypes) of + Just v -> pure v + Nothing -> typeMismatch "references.type" (String s) + +instance ToJSON ReferenceType where + toJSON v = String $ fromMaybe "WEB" (lookup v referenceTypes) + +data Reference = Reference + { referencesType :: ReferenceType + , referencesUrl :: Text + } deriving (Show, Eq) + + +-- | Types of individuals or entities to be credited in relation to +-- an advisory. +data CreditType + = CreditTypeFinder + -- ^ Identified the vulnerability + | CreditTypeReporter + -- ^ Notified the vendor of the vulnerability to a CNA + | CreditTypeAnalyst + -- ^ Validated the vulnerability to ensure accuracy or severity + | CreditTypeCoordinator + -- ^ Facilitated the coordinated response process + | CreditTypeRemediationDeveloper + -- ^ prepared a code change or other remediation plans + | CreditTypeRemediationReviewer + -- ^ Reviewed vulnerability remediation plans or code changes for effectiveness and completeness + | CreditTypeRemediationVerifier + -- ^ Tested and verified the vulnerability or its remediation + | CreditTypeTool + -- ^ Names of tools used in vulnerability discovery or identification + | CreditTypeSponsor + -- ^ Supported the vulnerability identification or remediation activities + | CreditTypeOther + -- ^ Any other type or role that does not fall under the categories described above + deriving (Show, Eq) + +-- | Bijection of credit types and their string representations +creditTypes :: [(CreditType, Text)] +creditTypes = + [ (CreditTypeFinder , "FINDER") + , (CreditTypeReporter , "REPORTER") + , (CreditTypeAnalyst , "ANALYST") + , (CreditTypeCoordinator , "COORDINATOR") + , (CreditTypeRemediationDeveloper , "REMEDIATION_DEVELOPER") + , (CreditTypeRemediationReviewer , "REMEDIATION_REVIEWER") + , (CreditTypeRemediationVerifier , "REMEDIATION_VERIFIER") + , (CreditTypeTool , "TOOL") + , (CreditTypeSponsor , "SPONSOR") + , (CreditTypeOther , "OTHER") + ] + +instance FromJSON CreditType where + parseJSON = withText "credits[].type" $ \s -> + case lookup s (fmap swap creditTypes) of + Just v -> pure v + Nothing -> typeMismatch "credits[].type" (String s) + +instance ToJSON CreditType where + toJSON v = String $ fromMaybe "OTHER" (lookup v creditTypes) + +data Credit = Credit + { creditType :: CreditType + , creditName :: Text + -- ^ The name, label, or other identifier of the individual or entity + -- being credited, using whatever notation the creditor prefers. + , creditContacts :: [Text] -- TODO refine tpye + -- ^ Fully qualified, plain-text URLs at which the credited can be reached. + } + deriving (Show, Eq) + +instance FromJSON Credit where + parseJSON = withObject "credits[]" $ \o -> do + creditType <- o .: "type" + creditName <- o .: "name" + creditContacts <- o .::? "contact" + pure $ Credit{..} + +instance ToJSON Credit where + toJSON Credit{..} = object $ + [ "type" .= creditType + , "name" .= creditName + ] + <> omitEmptyList "contact" creditContacts + where + omitEmptyList _ [] = [] + omitEmptyList k xs = [k .= xs] + + +instance + (ToJSON ecosystemSpecific, ToJSON dbSpecific, ToJSON rangeDbSpecific) + => ToJSON (Affected ecosystemSpecific dbSpecific rangeDbSpecific) where + toJSON Affected{..} = object $ + [ "ranges" .= affectedRanges + , "package" .= affectedPackage + ] + <> omitEmptyList "severity" affectedSeverity + <> maybe [] (pure . ("ecosystem_specific" .=)) affectedEcosystemSpecific + <> maybe [] (pure . ("database_specific" .=)) affectedDatabaseSpecific + where + omitEmptyList _ [] = [] + omitEmptyList k xs = [k .= xs] + +instance + ( ToJSON dbSpecific + , ToJSON affectedEcosystemSpecific + , ToJSON affectedDbSpecific + , ToJSON rangeDbSpecific + ) => ToJSON (Model dbSpecific affectedEcosystemSpecific affectedDbSpecific rangeDbSpecific) + where + toJSON Model{..} = object $ + [ "schema_version" .= modelSchemaVersion + , "id" .= modelId + , "modified" .= modelModified + ] + <> catMaybes + [ ("published" .=) <$> modelPublished + , ("withdrawn" .=) <$> modelWithdrawn + , ("aliases" .=) <$> omitEmptyList modelAliases + , ("related" .=) <$> omitEmptyList modelRelated + , ("summary" .=) <$> modelSummary + , ("details" .=) <$> modelDetails + , ("severity" .=) <$> omitEmptyList modelSeverity + , ("affected" .=) <$> omitEmptyList modelAffected + , ("references" .=) <$> omitEmptyList modelReferences + , ("credits" .=) <$> omitEmptyList modelCredits + , ("database_specific" .=) <$> modelDatabaseSpecific + ] + where + omitEmptyList [] = Nothing + omitEmptyList xs = Just xs + +instance ToJSON Package where + toJSON Package{..} = object $ + [ "name" .= packageName + , "ecosystem" .= packageEcosystem + ] + <> maybe [] (pure . ("purl" .=)) packagePurl + +instance ToJSON Reference where + toJSON Reference{..} = object + [ "type" .= referencesType + , "url" .= referencesUrl + ] + +instance + (FromJSON ecosystemSpecific, FromJSON dbSpecific, FromJSON rangeDbSpecific) + => FromJSON (Affected ecosystemSpecific dbSpecific rangeDbSpecific) where + parseJSON (Object v) = do + affectedRanges <- v .: "ranges" + affectedPackage <- v .: "package" + affectedSeverity <- v .::? "severity" + affectedEcosystemSpecific <- v .:? "ecosystem_specific" + affectedDatabaseSpecific <- v .:? "database_specific" + pure $ Affected{..} + parseJSON invalid = do + prependFailure "parsing Affected failed, " + (typeMismatch "Object" invalid) + +-- | Explicit parser for 'UTCTime', stricter than the @FromJSON@ +-- instance for that type. +-- +parseUTCTime :: Value -> Parser UTCTime +parseUTCTime = withText "UTCTime" $ \s -> + case iso8601ParseM (T.unpack s) of + Nothing -> typeMismatch "UTCTime" (String s) + Just t -> pure t + +-- | Parse helper for optional lists. If the key is absent, +-- it will be interpreted as an empty list. +-- +(.::?) :: FromJSON a => Object -> Key -> Parser [a] +o .::? k = fromMaybe [] <$> o .:? k + +instance + ( FromJSON dbSpecific + , FromJSON affectedEcosystemSpecific + , FromJSON affectedDbSpecific + , FromJSON rangeDbSpecific + ) => FromJSON (Model dbSpecific affectedEcosystemSpecific affectedDbSpecific rangeDbSpecific) where + parseJSON = withObject "osv-schema" $ \v -> do + modelSchemaVersion <- v .: "schema_version" + modelId <- v .: "id" + modelModified <- explicitParseField parseUTCTime v "modified" + modelPublished <- explicitParseFieldMaybe parseUTCTime v "published" + modelWithdrawn <- explicitParseFieldMaybe parseUTCTime v "withdrawn" + modelAliases <- v .::? "aliases" + modelRelated <- v .::? "related" + modelSummary <- v .:? "summary" + modelDetails <- v .:? "details" + modelSeverity <- v .::? "severity" + modelAffected <- v .::? "affected" + modelReferences <- v .::? "references" + modelCredits <- v .::? "credits" + modelDatabaseSpecific <- v .:? "database_specific" + pure $ Model{..} + +instance FromJSON Package where + parseJSON (Object v) = do + packageName <- v .: "name" + packageEcosystem <- v .: "ecosystem" + packagePurl <- v .:? "purl" + pure $ Package{..} + parseJSON invalid = do + prependFailure "parsing Package failed, " + (typeMismatch "Object" invalid) + +instance FromJSON Reference where + parseJSON (Object v) = do + referencesType <- v .: "type" + referencesUrl <- v .: "url" + pure $ Reference{..} + parseJSON invalid = do + prependFailure "parsing References failed, " + (typeMismatch "Object" invalid) diff --git a/code/osv/test/Spec.hs b/code/osv/test/Spec.hs new file mode 100644 index 00000000..0ffe11d5 --- /dev/null +++ b/code/osv/test/Spec.hs @@ -0,0 +1,11 @@ +{-# LANGUAGE OverloadedStrings #-} + +module Main where + +import Test.Tasty + +main :: IO () +main = + defaultMain $ + testGroup "Tests" + [] diff --git a/design/package.json b/design/package.json index d3236729..7d76255f 100644 --- a/design/package.json +++ b/design/package.json @@ -23,5 +23,6 @@ "react-dom": "^18.2.0", "storybook": "^7.2.0", "vite": "^4.4.9" - } + }, + "packageManager": "yarn@1.22.22+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e" } diff --git a/design/stories/Colours.stories.mdx b/design/stories/Colours.stories.mdx index 01d310b8..ac33ce78 100644 --- a/design/stories/Colours.stories.mdx +++ b/design/stories/Colours.stories.mdx @@ -15,8 +15,8 @@ import { Meta, ColorPalette, ColorItem } from "@storybook/addon-docs"; "blue-80": "hsl(221, 30%, 80%)", }} /> - + + + + + + + + + + diff --git a/design/stories/advisory-preview.stories.js b/design/stories/advisory-preview.stories.js new file mode 100644 index 00000000..d709ef85 --- /dev/null +++ b/design/stories/advisory-preview.stories.js @@ -0,0 +1,6 @@ + +export default { + title: "Components/Advisories" +}; + +export const AdvisoryPreviews = () => "
  • git-annex command injection via malicious SSH hostname

    0.16.20170818HSEC-2023-0009
  • git-annex private data exfiltration to compromised remote

    0.16.20180626HSEC-2023-0010
  • git-annex GPG decryption attack via compromised remote

    0.201104176.20180626HSEC-2023-0011
  • git-annex checksum exposure to encrypted special remotes

    0.201104176.20160419HSEC-2023-0012
  • git-annex plaintext storage of embedded credentials on encrypted remotes

    0.201104015.20140919HSEC-2023-0013
" diff --git a/design/yarn.lock b/design/yarn.lock new file mode 100644 index 00000000..c45ed1c0 --- /dev/null +++ b/design/yarn.lock @@ -0,0 +1,6228 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@ampproject/remapping@^2.2.0": + version "2.3.0" + resolved "https://registry.yarnpkg.com/@ampproject/remapping/-/remapping-2.3.0.tgz#ed441b6fa600072520ce18b43d2c8cc8caecc7f4" + integrity sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw== + dependencies: + "@jridgewell/gen-mapping" "^0.3.5" + "@jridgewell/trace-mapping" "^0.3.24" + +"@aw-web-design/x-default-browser@1.4.126": + version "1.4.126" + resolved "https://registry.yarnpkg.com/@aw-web-design/x-default-browser/-/x-default-browser-1.4.126.tgz#43e4bd8f0314ed907a8718d7e862a203af79bc16" + integrity sha512-Xk1sIhyNC/esHGGVjL/niHLowM0csl/kFO5uawBy4IrWwy0o1G8LGt3jP6nmWGz+USxeeqbihAmp/oVZju6wug== + dependencies: + default-browser-id "3.0.0" + +"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.10.4", "@babel/code-frame@^7.25.9", "@babel/code-frame@^7.26.0": + version "7.26.2" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.26.2.tgz#4b5fab97d33338eff916235055f0ebc21e573a85" + integrity sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ== + dependencies: + "@babel/helper-validator-identifier" "^7.25.9" + js-tokens "^4.0.0" + picocolors "^1.0.0" + +"@babel/compat-data@^7.22.6", "@babel/compat-data@^7.25.9", "@babel/compat-data@^7.26.0": + version "7.26.2" + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.26.2.tgz#278b6b13664557de95b8f35b90d96785850bb56e" + integrity sha512-Z0WgzSEa+aUcdiJuCIqgujCshpMWgUpgOxXotrYPSA53hA3qopNaqcJpyr0hVb1FeWdnqFA35/fUtXgBK8srQg== + +"@babel/core@^7.11.6", "@babel/core@^7.12.3", "@babel/core@^7.23.0", "@babel/core@^7.23.2": + version "7.26.0" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.26.0.tgz#d78b6023cc8f3114ccf049eb219613f74a747b40" + integrity sha512-i1SLeK+DzNnQ3LL/CswPCa/E5u4lh1k6IAEphON8F+cXt0t9euTshDru0q7/IqMa1PMPz5RnHuHscF8/ZJsStg== + dependencies: + "@ampproject/remapping" "^2.2.0" + "@babel/code-frame" "^7.26.0" + "@babel/generator" "^7.26.0" + "@babel/helper-compilation-targets" "^7.25.9" + "@babel/helper-module-transforms" "^7.26.0" + "@babel/helpers" "^7.26.0" + "@babel/parser" "^7.26.0" + "@babel/template" "^7.25.9" + "@babel/traverse" "^7.25.9" + "@babel/types" "^7.26.0" + convert-source-map "^2.0.0" + debug "^4.1.0" + gensync "^1.0.0-beta.2" + json5 "^2.2.3" + semver "^6.3.1" + +"@babel/generator@^7.23.0", "@babel/generator@^7.25.9", "@babel/generator@^7.26.0": + version "7.26.2" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.26.2.tgz#87b75813bec87916210e5e01939a4c823d6bb74f" + integrity sha512-zevQbhbau95nkoxSq3f/DC/SC+EEOUZd3DYqfSkMhY2/wfSeaHV1Ew4vk8e+x8lja31IbyuUa2uQ3JONqKbysw== + dependencies: + "@babel/parser" "^7.26.2" + "@babel/types" "^7.26.0" + "@jridgewell/gen-mapping" "^0.3.5" + "@jridgewell/trace-mapping" "^0.3.25" + jsesc "^3.0.2" + +"@babel/helper-annotate-as-pure@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.25.9.tgz#d8eac4d2dc0d7b6e11fa6e535332e0d3184f06b4" + integrity sha512-gv7320KBUFJz1RnylIg5WWYPRXKZ884AGkYpgpWW02TH66Dl+HaC1t1CKd0z3R4b6hdYEcmrNZHUmfCP+1u3/g== + dependencies: + "@babel/types" "^7.25.9" + +"@babel/helper-builder-binary-assignment-operator-visitor@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.25.9.tgz#f41752fe772a578e67286e6779a68a5a92de1ee9" + integrity sha512-C47lC7LIDCnz0h4vai/tpNOI95tCd5ZT3iBt/DBH5lXKHZsyNQv18yf1wIIg2ntiQNgmAvA+DgZ82iW8Qdym8g== + dependencies: + "@babel/traverse" "^7.25.9" + "@babel/types" "^7.25.9" + +"@babel/helper-compilation-targets@^7.22.6", "@babel/helper-compilation-targets@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.25.9.tgz#55af025ce365be3cdc0c1c1e56c6af617ce88875" + integrity sha512-j9Db8Suy6yV/VHa4qzrj9yZfZxhLWQdVnRlXxmKLYlhWUVB1sB2G5sxuWYXk/whHD9iW76PmNzxZ4UCnTQTVEQ== + dependencies: + "@babel/compat-data" "^7.25.9" + "@babel/helper-validator-option" "^7.25.9" + browserslist "^4.24.0" + lru-cache "^5.1.1" + semver "^6.3.1" + +"@babel/helper-create-class-features-plugin@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.25.9.tgz#7644147706bb90ff613297d49ed5266bde729f83" + integrity sha512-UTZQMvt0d/rSz6KI+qdu7GQze5TIajwTS++GUozlw8VBJDEOAqSXwm1WvmYEZwqdqSGQshRocPDqrt4HBZB3fQ== + dependencies: + "@babel/helper-annotate-as-pure" "^7.25.9" + "@babel/helper-member-expression-to-functions" "^7.25.9" + "@babel/helper-optimise-call-expression" "^7.25.9" + "@babel/helper-replace-supers" "^7.25.9" + "@babel/helper-skip-transparent-expression-wrappers" "^7.25.9" + "@babel/traverse" "^7.25.9" + semver "^6.3.1" + +"@babel/helper-create-regexp-features-plugin@^7.18.6", "@babel/helper-create-regexp-features-plugin@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.25.9.tgz#3e8999db94728ad2b2458d7a470e7770b7764e26" + integrity sha512-ORPNZ3h6ZRkOyAa/SaHU+XsLZr0UQzRwuDQ0cczIA17nAzZ+85G5cVkOJIj7QavLZGSe8QXUmNFxSZzjcZF9bw== + dependencies: + "@babel/helper-annotate-as-pure" "^7.25.9" + regexpu-core "^6.1.1" + semver "^6.3.1" + +"@babel/helper-define-polyfill-provider@^0.6.2", "@babel/helper-define-polyfill-provider@^0.6.3": + version "0.6.3" + resolved "https://registry.yarnpkg.com/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.3.tgz#f4f2792fae2ef382074bc2d713522cf24e6ddb21" + integrity sha512-HK7Bi+Hj6H+VTHA3ZvBis7V/6hu9QuTrnMXNybfUf2iiuU/N97I8VjB+KbhFF8Rld/Lx5MzoCwPCpPjfK+n8Cg== + dependencies: + "@babel/helper-compilation-targets" "^7.22.6" + "@babel/helper-plugin-utils" "^7.22.5" + debug "^4.1.1" + lodash.debounce "^4.0.8" + resolve "^1.14.2" + +"@babel/helper-member-expression-to-functions@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.25.9.tgz#9dfffe46f727005a5ea29051ac835fb735e4c1a3" + integrity sha512-wbfdZ9w5vk0C0oyHqAJbc62+vet5prjj01jjJ8sKn3j9h3MQQlflEdXYvuqRWjHnM12coDEqiC1IRCi0U/EKwQ== + dependencies: + "@babel/traverse" "^7.25.9" + "@babel/types" "^7.25.9" + +"@babel/helper-module-imports@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.25.9.tgz#e7f8d20602ebdbf9ebbea0a0751fb0f2a4141715" + integrity sha512-tnUA4RsrmflIM6W6RFTLFSXITtl0wKjgpnLgXyowocVPrbYrLUXSBXDgTs8BlbmIzIdlBySRQjINYs2BAkiLtw== + dependencies: + "@babel/traverse" "^7.25.9" + "@babel/types" "^7.25.9" + +"@babel/helper-module-transforms@^7.25.9", "@babel/helper-module-transforms@^7.26.0": + version "7.26.0" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.26.0.tgz#8ce54ec9d592695e58d84cd884b7b5c6a2fdeeae" + integrity sha512-xO+xu6B5K2czEnQye6BHA7DolFFmS3LB7stHZFaOLb1pAwO1HWLS8fXA+eh0A2yIvltPVmx3eNNDBJA2SLHXFw== + dependencies: + "@babel/helper-module-imports" "^7.25.9" + "@babel/helper-validator-identifier" "^7.25.9" + "@babel/traverse" "^7.25.9" + +"@babel/helper-optimise-call-expression@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.25.9.tgz#3324ae50bae7e2ab3c33f60c9a877b6a0146b54e" + integrity sha512-FIpuNaz5ow8VyrYcnXQTDRGvV6tTjkNtCK/RYNDXGSLlUD6cBuQTSw43CShGxjvfBTfcUA/r6UhUCbtYqkhcuQ== + dependencies: + "@babel/types" "^7.25.9" + +"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.18.6", "@babel/helper-plugin-utils@^7.22.5", "@babel/helper-plugin-utils@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.25.9.tgz#9cbdd63a9443a2c92a725cca7ebca12cc8dd9f46" + integrity sha512-kSMlyUVdWe25rEsRGviIgOWnoT/nfABVWlqt9N19/dIPWViAOW2s9wznP5tURbs/IDuNk4gPy3YdYRgH3uxhBw== + +"@babel/helper-remap-async-to-generator@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.25.9.tgz#e53956ab3d5b9fb88be04b3e2f31b523afd34b92" + integrity sha512-IZtukuUeBbhgOcaW2s06OXTzVNJR0ybm4W5xC1opWFFJMZbwRj5LCk+ByYH7WdZPZTt8KnFwA8pvjN2yqcPlgw== + dependencies: + "@babel/helper-annotate-as-pure" "^7.25.9" + "@babel/helper-wrap-function" "^7.25.9" + "@babel/traverse" "^7.25.9" + +"@babel/helper-replace-supers@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.25.9.tgz#ba447224798c3da3f8713fc272b145e33da6a5c5" + integrity sha512-IiDqTOTBQy0sWyeXyGSC5TBJpGFXBkRynjBeXsvbhQFKj2viwJC76Epz35YLU1fpe/Am6Vppb7W7zM4fPQzLsQ== + dependencies: + "@babel/helper-member-expression-to-functions" "^7.25.9" + "@babel/helper-optimise-call-expression" "^7.25.9" + "@babel/traverse" "^7.25.9" + +"@babel/helper-simple-access@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.25.9.tgz#6d51783299884a2c74618d6ef0f86820ec2e7739" + integrity sha512-c6WHXuiaRsJTyHYLJV75t9IqsmTbItYfdj99PnzYGQZkYKvan5/2jKJ7gu31J3/BJ/A18grImSPModuyG/Eo0Q== + dependencies: + "@babel/traverse" "^7.25.9" + "@babel/types" "^7.25.9" + +"@babel/helper-skip-transparent-expression-wrappers@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.25.9.tgz#0b2e1b62d560d6b1954893fd2b705dc17c91f0c9" + integrity sha512-K4Du3BFa3gvyhzgPcntrkDgZzQaq6uozzcpGbOO1OEJaI+EJdqWIMTLgFgQf6lrfiDFo5FU+BxKepI9RmZqahA== + dependencies: + "@babel/traverse" "^7.25.9" + "@babel/types" "^7.25.9" + +"@babel/helper-string-parser@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz#1aabb72ee72ed35789b4bbcad3ca2862ce614e8c" + integrity sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA== + +"@babel/helper-validator-identifier@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz#24b64e2c3ec7cd3b3c547729b8d16871f22cbdc7" + integrity sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ== + +"@babel/helper-validator-option@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.25.9.tgz#86e45bd8a49ab7e03f276577f96179653d41da72" + integrity sha512-e/zv1co8pp55dNdEcCynfj9X7nyUKUXoUEwfXqaZt0omVOmDe9oOTdKStH4GmAw6zxMFs50ZayuMfHDKlO7Tfw== + +"@babel/helper-wrap-function@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.25.9.tgz#d99dfd595312e6c894bd7d237470025c85eea9d0" + integrity sha512-ETzz9UTjQSTmw39GboatdymDq4XIQbR8ySgVrylRhPOFpsd+JrKHIuF0de7GCWmem+T4uC5z7EZguod7Wj4A4g== + dependencies: + "@babel/template" "^7.25.9" + "@babel/traverse" "^7.25.9" + "@babel/types" "^7.25.9" + +"@babel/helpers@^7.26.0": + version "7.26.0" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.26.0.tgz#30e621f1eba5aa45fe6f4868d2e9154d884119a4" + integrity sha512-tbhNuIxNcVb21pInl3ZSjksLCvgdZy9KwJ8brv993QtIVKJBBkYXz4q4ZbAv31GdnC+R90np23L5FbEBlthAEw== + dependencies: + "@babel/template" "^7.25.9" + "@babel/types" "^7.26.0" + +"@babel/parser@^7.1.0", "@babel/parser@^7.14.7", "@babel/parser@^7.20.7", "@babel/parser@^7.23.0", "@babel/parser@^7.25.9", "@babel/parser@^7.26.0", "@babel/parser@^7.26.2": + version "7.26.2" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.26.2.tgz#fd7b6f487cfea09889557ef5d4eeb9ff9a5abd11" + integrity sha512-DWMCZH9WA4Maitz2q21SRKHo9QXZxkDsbNZoVD62gusNtNBBqDg9i7uOhASfTfIGNzW+O+r7+jAlM8dwphcJKQ== + dependencies: + "@babel/types" "^7.26.0" + +"@babel/plugin-bugfix-firefox-class-in-computed-class-key@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.25.9.tgz#cc2e53ebf0a0340777fff5ed521943e253b4d8fe" + integrity sha512-ZkRyVkThtxQ/J6nv3JFYv1RYY+JT5BvU0y3k5bWrmuG4woXypRa4PXmm9RhOwodRkYFWqC0C0cqcJ4OqR7kW+g== + dependencies: + "@babel/helper-plugin-utils" "^7.25.9" + "@babel/traverse" "^7.25.9" + +"@babel/plugin-bugfix-safari-class-field-initializer-scope@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-safari-class-field-initializer-scope/-/plugin-bugfix-safari-class-field-initializer-scope-7.25.9.tgz#af9e4fb63ccb8abcb92375b2fcfe36b60c774d30" + integrity sha512-MrGRLZxLD/Zjj0gdU15dfs+HH/OXvnw/U4jJD8vpcP2CJQapPEv1IWwjc/qMg7ItBlPwSv1hRBbb7LeuANdcnw== + dependencies: + "@babel/helper-plugin-utils" "^7.25.9" + +"@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.25.9.tgz#e8dc26fcd616e6c5bf2bd0d5a2c151d4f92a9137" + integrity sha512-2qUwwfAFpJLZqxd02YW9btUCZHl+RFvdDkNfZwaIJrvB8Tesjsk8pEQkTvGwZXLqXUx/2oyY3ySRhm6HOXuCug== + dependencies: + "@babel/helper-plugin-utils" "^7.25.9" + +"@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.25.9.tgz#807a667f9158acac6f6164b4beb85ad9ebc9e1d1" + integrity sha512-6xWgLZTJXwilVjlnV7ospI3xi+sl8lN8rXXbBD6vYn3UYDlGsag8wrZkKcSI8G6KgqKP7vNFaDgeDnfAABq61g== + dependencies: + "@babel/helper-plugin-utils" "^7.25.9" + "@babel/helper-skip-transparent-expression-wrappers" "^7.25.9" + "@babel/plugin-transform-optional-chaining" "^7.25.9" + +"@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.25.9.tgz#de7093f1e7deaf68eadd7cc6b07f2ab82543269e" + integrity sha512-aLnMXYPnzwwqhYSCyXfKkIkYgJ8zv9RK+roo9DkTXz38ynIhd9XCbN08s3MGvqL2MYGVUGdRQLL/JqBIeJhJBg== + dependencies: + "@babel/helper-plugin-utils" "^7.25.9" + "@babel/traverse" "^7.25.9" + +"@babel/plugin-proposal-private-property-in-object@7.21.0-placeholder-for-preset-env.2": + version "7.21.0-placeholder-for-preset-env.2" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz#7844f9289546efa9febac2de4cfe358a050bd703" + integrity sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w== + +"@babel/plugin-syntax-flow@^7.25.9": + version "7.26.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.26.0.tgz#96507595c21b45fccfc2bc758d5c45452e6164fa" + integrity sha512-B+O2DnPc0iG+YXFqOxv2WNuNU97ToWjOomUQ78DouOENWUaM5sVrmet9mcomUGQFwpJd//gvUagXBSdzO1fRKg== + dependencies: + "@babel/helper-plugin-utils" "^7.25.9" + +"@babel/plugin-syntax-import-assertions@^7.26.0": + version "7.26.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.26.0.tgz#620412405058efa56e4a564903b79355020f445f" + integrity sha512-QCWT5Hh830hK5EQa7XzuqIkQU9tT/whqbDz7kuaZMHFl1inRRg7JnuAEOQ0Ur0QUl0NufCk1msK2BeY79Aj/eg== + dependencies: + "@babel/helper-plugin-utils" "^7.25.9" + +"@babel/plugin-syntax-import-attributes@^7.26.0": + version "7.26.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.26.0.tgz#3b1412847699eea739b4f2602c74ce36f6b0b0f7" + integrity sha512-e2dttdsJ1ZTpi3B9UYGLw41hifAubg19AtCu/2I/F1QNVclOBr1dYpTdmdyZ84Xiz43BS/tCUkMAZNLv12Pi+A== + dependencies: + "@babel/helper-plugin-utils" "^7.25.9" + +"@babel/plugin-syntax-jsx@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.25.9.tgz#a34313a178ea56f1951599b929c1ceacee719290" + integrity sha512-ld6oezHQMZsZfp6pWtbjaNDF2tiiCYYDqQszHt5VV437lewP9aSi2Of99CK0D0XB21k7FLgnLcmQKyKzynfeAA== + dependencies: + "@babel/helper-plugin-utils" "^7.25.9" + +"@babel/plugin-syntax-typescript@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.25.9.tgz#67dda2b74da43727cf21d46cf9afef23f4365399" + integrity sha512-hjMgRy5hb8uJJjUcdWunWVcoi9bGpJp8p5Ol1229PoN6aytsLwNMgmdftO23wnCLMfVmTwZDWMPNq/D1SY60JQ== + dependencies: + "@babel/helper-plugin-utils" "^7.25.9" + +"@babel/plugin-syntax-unicode-sets-regex@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-unicode-sets-regex/-/plugin-syntax-unicode-sets-regex-7.18.6.tgz#d49a3b3e6b52e5be6740022317580234a6a47357" + integrity sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.18.6" + "@babel/helper-plugin-utils" "^7.18.6" + +"@babel/plugin-transform-arrow-functions@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.25.9.tgz#7821d4410bee5daaadbb4cdd9a6649704e176845" + integrity sha512-6jmooXYIwn9ca5/RylZADJ+EnSxVUS5sjeJ9UPk6RWRzXCmOJCy6dqItPJFpw2cuCangPK4OYr5uhGKcmrm5Qg== + dependencies: + "@babel/helper-plugin-utils" "^7.25.9" + +"@babel/plugin-transform-async-generator-functions@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.25.9.tgz#1b18530b077d18a407c494eb3d1d72da505283a2" + integrity sha512-RXV6QAzTBbhDMO9fWwOmwwTuYaiPbggWQ9INdZqAYeSHyG7FzQ+nOZaUUjNwKv9pV3aE4WFqFm1Hnbci5tBCAw== + dependencies: + "@babel/helper-plugin-utils" "^7.25.9" + "@babel/helper-remap-async-to-generator" "^7.25.9" + "@babel/traverse" "^7.25.9" + +"@babel/plugin-transform-async-to-generator@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.25.9.tgz#c80008dacae51482793e5a9c08b39a5be7e12d71" + integrity sha512-NT7Ejn7Z/LjUH0Gv5KsBCxh7BH3fbLTV0ptHvpeMvrt3cPThHfJfst9Wrb7S8EvJ7vRTFI7z+VAvFVEQn/m5zQ== + dependencies: + "@babel/helper-module-imports" "^7.25.9" + "@babel/helper-plugin-utils" "^7.25.9" + "@babel/helper-remap-async-to-generator" "^7.25.9" + +"@babel/plugin-transform-block-scoped-functions@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.25.9.tgz#5700691dbd7abb93de300ca7be94203764fce458" + integrity sha512-toHc9fzab0ZfenFpsyYinOX0J/5dgJVA2fm64xPewu7CoYHWEivIWKxkK2rMi4r3yQqLnVmheMXRdG+k239CgA== + dependencies: + "@babel/helper-plugin-utils" "^7.25.9" + +"@babel/plugin-transform-block-scoping@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.25.9.tgz#c33665e46b06759c93687ca0f84395b80c0473a1" + integrity sha512-1F05O7AYjymAtqbsFETboN1NvBdcnzMerO+zlMyJBEz6WkMdejvGWw9p05iTSjC85RLlBseHHQpYaM4gzJkBGg== + dependencies: + "@babel/helper-plugin-utils" "^7.25.9" + +"@babel/plugin-transform-class-properties@^7.22.5", "@babel/plugin-transform-class-properties@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.25.9.tgz#a8ce84fedb9ad512549984101fa84080a9f5f51f" + integrity sha512-bbMAII8GRSkcd0h0b4X+36GksxuheLFjP65ul9w6C3KgAamI3JqErNgSrosX6ZPj+Mpim5VvEbawXxJCyEUV3Q== + dependencies: + "@babel/helper-create-class-features-plugin" "^7.25.9" + "@babel/helper-plugin-utils" "^7.25.9" + +"@babel/plugin-transform-class-static-block@^7.26.0": + version "7.26.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.26.0.tgz#6c8da219f4eb15cae9834ec4348ff8e9e09664a0" + integrity sha512-6J2APTs7BDDm+UMqP1useWqhcRAXo0WIoVj26N7kPFB6S73Lgvyka4KTZYIxtgYXiN5HTyRObA72N2iu628iTQ== + dependencies: + "@babel/helper-create-class-features-plugin" "^7.25.9" + "@babel/helper-plugin-utils" "^7.25.9" + +"@babel/plugin-transform-classes@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.25.9.tgz#7152457f7880b593a63ade8a861e6e26a4469f52" + integrity sha512-mD8APIXmseE7oZvZgGABDyM34GUmK45Um2TXiBUt7PnuAxrgoSVf123qUzPxEr/+/BHrRn5NMZCdE2m/1F8DGg== + dependencies: + "@babel/helper-annotate-as-pure" "^7.25.9" + "@babel/helper-compilation-targets" "^7.25.9" + "@babel/helper-plugin-utils" "^7.25.9" + "@babel/helper-replace-supers" "^7.25.9" + "@babel/traverse" "^7.25.9" + globals "^11.1.0" + +"@babel/plugin-transform-computed-properties@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.25.9.tgz#db36492c78460e534b8852b1d5befe3c923ef10b" + integrity sha512-HnBegGqXZR12xbcTHlJ9HGxw1OniltT26J5YpfruGqtUHlz/xKf/G2ak9e+t0rVqrjXa9WOhvYPz1ERfMj23AA== + dependencies: + "@babel/helper-plugin-utils" "^7.25.9" + "@babel/template" "^7.25.9" + +"@babel/plugin-transform-destructuring@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.25.9.tgz#966ea2595c498224340883602d3cfd7a0c79cea1" + integrity sha512-WkCGb/3ZxXepmMiX101nnGiU+1CAdut8oHyEOHxkKuS1qKpU2SMXE2uSvfz8PBuLd49V6LEsbtyPhWC7fnkgvQ== + dependencies: + "@babel/helper-plugin-utils" "^7.25.9" + +"@babel/plugin-transform-dotall-regex@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.25.9.tgz#bad7945dd07734ca52fe3ad4e872b40ed09bb09a" + integrity sha512-t7ZQ7g5trIgSRYhI9pIJtRl64KHotutUJsh4Eze5l7olJv+mRSg4/MmbZ0tv1eeqRbdvo/+trvJD/Oc5DmW2cA== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.25.9" + "@babel/helper-plugin-utils" "^7.25.9" + +"@babel/plugin-transform-duplicate-keys@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.25.9.tgz#8850ddf57dce2aebb4394bb434a7598031059e6d" + integrity sha512-LZxhJ6dvBb/f3x8xwWIuyiAHy56nrRG3PeYTpBkkzkYRRQ6tJLu68lEF5VIqMUZiAV7a8+Tb78nEoMCMcqjXBw== + dependencies: + "@babel/helper-plugin-utils" "^7.25.9" + +"@babel/plugin-transform-duplicate-named-capturing-groups-regex@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-named-capturing-groups-regex/-/plugin-transform-duplicate-named-capturing-groups-regex-7.25.9.tgz#6f7259b4de127721a08f1e5165b852fcaa696d31" + integrity sha512-0UfuJS0EsXbRvKnwcLjFtJy/Sxc5J5jhLHnFhy7u4zih97Hz6tJkLU+O+FMMrNZrosUPxDi6sYxJ/EA8jDiAog== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.25.9" + "@babel/helper-plugin-utils" "^7.25.9" + +"@babel/plugin-transform-dynamic-import@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.25.9.tgz#23e917de63ed23c6600c5dd06d94669dce79f7b8" + integrity sha512-GCggjexbmSLaFhqsojeugBpeaRIgWNTcgKVq/0qIteFEqY2A+b9QidYadrWlnbWQUrW5fn+mCvf3tr7OeBFTyg== + dependencies: + "@babel/helper-plugin-utils" "^7.25.9" + +"@babel/plugin-transform-exponentiation-operator@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.25.9.tgz#ece47b70d236c1d99c263a1e22b62dc20a4c8b0f" + integrity sha512-KRhdhlVk2nObA5AYa7QMgTMTVJdfHprfpAk4DjZVtllqRg9qarilstTKEhpVjyt+Npi8ThRyiV8176Am3CodPA== + dependencies: + "@babel/helper-builder-binary-assignment-operator-visitor" "^7.25.9" + "@babel/helper-plugin-utils" "^7.25.9" + +"@babel/plugin-transform-export-namespace-from@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.25.9.tgz#90745fe55053394f554e40584cda81f2c8a402a2" + integrity sha512-2NsEz+CxzJIVOPx2o9UsW1rXLqtChtLoVnwYHHiB04wS5sgn7mrV45fWMBX0Kk+ub9uXytVYfNP2HjbVbCB3Ww== + dependencies: + "@babel/helper-plugin-utils" "^7.25.9" + +"@babel/plugin-transform-flow-strip-types@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.25.9.tgz#85879b42a8f5948fd6317069978e98f23ef8aec1" + integrity sha512-/VVukELzPDdci7UUsWQaSkhgnjIWXnIyRpM02ldxaVoFK96c41So8JcKT3m0gYjyv7j5FNPGS5vfELrWalkbDA== + dependencies: + "@babel/helper-plugin-utils" "^7.25.9" + "@babel/plugin-syntax-flow" "^7.25.9" + +"@babel/plugin-transform-for-of@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.25.9.tgz#4bdc7d42a213397905d89f02350c5267866d5755" + integrity sha512-LqHxduHoaGELJl2uhImHwRQudhCM50pT46rIBNvtT/Oql3nqiS3wOwP+5ten7NpYSXrrVLgtZU3DZmPtWZo16A== + dependencies: + "@babel/helper-plugin-utils" "^7.25.9" + "@babel/helper-skip-transparent-expression-wrappers" "^7.25.9" + +"@babel/plugin-transform-function-name@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.25.9.tgz#939d956e68a606661005bfd550c4fc2ef95f7b97" + integrity sha512-8lP+Yxjv14Vc5MuWBpJsoUCd3hD6V9DgBon2FVYL4jJgbnVQ9fTgYmonchzZJOVNgzEgbxp4OwAf6xz6M/14XA== + dependencies: + "@babel/helper-compilation-targets" "^7.25.9" + "@babel/helper-plugin-utils" "^7.25.9" + "@babel/traverse" "^7.25.9" + +"@babel/plugin-transform-json-strings@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.25.9.tgz#c86db407cb827cded902a90c707d2781aaa89660" + integrity sha512-xoTMk0WXceiiIvsaquQQUaLLXSW1KJ159KP87VilruQm0LNNGxWzahxSS6T6i4Zg3ezp4vA4zuwiNUR53qmQAw== + dependencies: + "@babel/helper-plugin-utils" "^7.25.9" + +"@babel/plugin-transform-literals@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.25.9.tgz#1a1c6b4d4aa59bc4cad5b6b3a223a0abd685c9de" + integrity sha512-9N7+2lFziW8W9pBl2TzaNht3+pgMIRP74zizeCSrtnSKVdUl8mAjjOP2OOVQAfZ881P2cNjDj1uAMEdeD50nuQ== + dependencies: + "@babel/helper-plugin-utils" "^7.25.9" + +"@babel/plugin-transform-logical-assignment-operators@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.25.9.tgz#b19441a8c39a2fda0902900b306ea05ae1055db7" + integrity sha512-wI4wRAzGko551Y8eVf6iOY9EouIDTtPb0ByZx+ktDGHwv6bHFimrgJM/2T021txPZ2s4c7bqvHbd+vXG6K948Q== + dependencies: + "@babel/helper-plugin-utils" "^7.25.9" + +"@babel/plugin-transform-member-expression-literals@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.25.9.tgz#63dff19763ea64a31f5e6c20957e6a25e41ed5de" + integrity sha512-PYazBVfofCQkkMzh2P6IdIUaCEWni3iYEerAsRWuVd8+jlM1S9S9cz1dF9hIzyoZ8IA3+OwVYIp9v9e+GbgZhA== + dependencies: + "@babel/helper-plugin-utils" "^7.25.9" + +"@babel/plugin-transform-modules-amd@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.25.9.tgz#49ba478f2295101544abd794486cd3088dddb6c5" + integrity sha512-g5T11tnI36jVClQlMlt4qKDLlWnG5pP9CSM4GhdRciTNMRgkfpo5cR6b4rGIOYPgRRuFAvwjPQ/Yk+ql4dyhbw== + dependencies: + "@babel/helper-module-transforms" "^7.25.9" + "@babel/helper-plugin-utils" "^7.25.9" + +"@babel/plugin-transform-modules-commonjs@^7.23.0", "@babel/plugin-transform-modules-commonjs@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.25.9.tgz#d165c8c569a080baf5467bda88df6425fc060686" + integrity sha512-dwh2Ol1jWwL2MgkCzUSOvfmKElqQcuswAZypBSUsScMXvgdT8Ekq5YA6TtqpTVWH+4903NmboMuH1o9i8Rxlyg== + dependencies: + "@babel/helper-module-transforms" "^7.25.9" + "@babel/helper-plugin-utils" "^7.25.9" + "@babel/helper-simple-access" "^7.25.9" + +"@babel/plugin-transform-modules-systemjs@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.25.9.tgz#8bd1b43836269e3d33307151a114bcf3ba6793f8" + integrity sha512-hyss7iIlH/zLHaehT+xwiymtPOpsiwIIRlCAOwBB04ta5Tt+lNItADdlXw3jAWZ96VJ2jlhl/c+PNIQPKNfvcA== + dependencies: + "@babel/helper-module-transforms" "^7.25.9" + "@babel/helper-plugin-utils" "^7.25.9" + "@babel/helper-validator-identifier" "^7.25.9" + "@babel/traverse" "^7.25.9" + +"@babel/plugin-transform-modules-umd@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.25.9.tgz#6710079cdd7c694db36529a1e8411e49fcbf14c9" + integrity sha512-bS9MVObUgE7ww36HEfwe6g9WakQ0KF07mQF74uuXdkoziUPfKyu/nIm663kz//e5O1nPInPFx36z7WJmJ4yNEw== + dependencies: + "@babel/helper-module-transforms" "^7.25.9" + "@babel/helper-plugin-utils" "^7.25.9" + +"@babel/plugin-transform-named-capturing-groups-regex@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.25.9.tgz#454990ae6cc22fd2a0fa60b3a2c6f63a38064e6a" + integrity sha512-oqB6WHdKTGl3q/ItQhpLSnWWOpjUJLsOCLVyeFgeTktkBSCiurvPOsyt93gibI9CmuKvTUEtWmG5VhZD+5T/KA== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.25.9" + "@babel/helper-plugin-utils" "^7.25.9" + +"@babel/plugin-transform-new-target@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.25.9.tgz#42e61711294b105c248336dcb04b77054ea8becd" + integrity sha512-U/3p8X1yCSoKyUj2eOBIx3FOn6pElFOKvAAGf8HTtItuPyB+ZeOqfn+mvTtg9ZlOAjsPdK3ayQEjqHjU/yLeVQ== + dependencies: + "@babel/helper-plugin-utils" "^7.25.9" + +"@babel/plugin-transform-nullish-coalescing-operator@^7.22.11", "@babel/plugin-transform-nullish-coalescing-operator@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.25.9.tgz#bcb1b0d9e948168102d5f7104375ca21c3266949" + integrity sha512-ENfftpLZw5EItALAD4WsY/KUWvhUlZndm5GC7G3evUsVeSJB6p0pBeLQUnRnBCBx7zV0RKQjR9kCuwrsIrjWog== + dependencies: + "@babel/helper-plugin-utils" "^7.25.9" + +"@babel/plugin-transform-numeric-separator@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.25.9.tgz#bfed75866261a8b643468b0ccfd275f2033214a1" + integrity sha512-TlprrJ1GBZ3r6s96Yq8gEQv82s8/5HnCVHtEJScUj90thHQbwe+E5MLhi2bbNHBEJuzrvltXSru+BUxHDoog7Q== + dependencies: + "@babel/helper-plugin-utils" "^7.25.9" + +"@babel/plugin-transform-object-rest-spread@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.25.9.tgz#0203725025074164808bcf1a2cfa90c652c99f18" + integrity sha512-fSaXafEE9CVHPweLYw4J0emp1t8zYTXyzN3UuG+lylqkvYd7RMrsOQ8TYx5RF231be0vqtFC6jnx3UmpJmKBYg== + dependencies: + "@babel/helper-compilation-targets" "^7.25.9" + "@babel/helper-plugin-utils" "^7.25.9" + "@babel/plugin-transform-parameters" "^7.25.9" + +"@babel/plugin-transform-object-super@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.25.9.tgz#385d5de135162933beb4a3d227a2b7e52bb4cf03" + integrity sha512-Kj/Gh+Rw2RNLbCK1VAWj2U48yxxqL2x0k10nPtSdRa0O2xnHXalD0s+o1A6a0W43gJ00ANo38jxkQreckOzv5A== + dependencies: + "@babel/helper-plugin-utils" "^7.25.9" + "@babel/helper-replace-supers" "^7.25.9" + +"@babel/plugin-transform-optional-catch-binding@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.25.9.tgz#10e70d96d52bb1f10c5caaac59ac545ea2ba7ff3" + integrity sha512-qM/6m6hQZzDcZF3onzIhZeDHDO43bkNNlOX0i8n3lR6zLbu0GN2d8qfM/IERJZYauhAHSLHy39NF0Ctdvcid7g== + dependencies: + "@babel/helper-plugin-utils" "^7.25.9" + +"@babel/plugin-transform-optional-chaining@^7.23.0", "@babel/plugin-transform-optional-chaining@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.25.9.tgz#e142eb899d26ef715435f201ab6e139541eee7dd" + integrity sha512-6AvV0FsLULbpnXeBjrY4dmWF8F7gf8QnvTEoO/wX/5xm/xE1Xo8oPuD3MPS+KS9f9XBEAWN7X1aWr4z9HdOr7A== + dependencies: + "@babel/helper-plugin-utils" "^7.25.9" + "@babel/helper-skip-transparent-expression-wrappers" "^7.25.9" + +"@babel/plugin-transform-parameters@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.25.9.tgz#b856842205b3e77e18b7a7a1b94958069c7ba257" + integrity sha512-wzz6MKwpnshBAiRmn4jR8LYz/g8Ksg0o80XmwZDlordjwEk9SxBzTWC7F5ef1jhbrbOW2DJ5J6ayRukrJmnr0g== + dependencies: + "@babel/helper-plugin-utils" "^7.25.9" + +"@babel/plugin-transform-private-methods@^7.22.5", "@babel/plugin-transform-private-methods@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.25.9.tgz#847f4139263577526455d7d3223cd8bda51e3b57" + integrity sha512-D/JUozNpQLAPUVusvqMxyvjzllRaF8/nSrP1s2YGQT/W4LHK4xxsMcHjhOGTS01mp9Hda8nswb+FblLdJornQw== + dependencies: + "@babel/helper-create-class-features-plugin" "^7.25.9" + "@babel/helper-plugin-utils" "^7.25.9" + +"@babel/plugin-transform-private-property-in-object@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.25.9.tgz#9c8b73e64e6cc3cbb2743633885a7dd2c385fe33" + integrity sha512-Evf3kcMqzXA3xfYJmZ9Pg1OvKdtqsDMSWBDzZOPLvHiTt36E75jLDQo5w1gtRU95Q4E5PDttrTf25Fw8d/uWLw== + dependencies: + "@babel/helper-annotate-as-pure" "^7.25.9" + "@babel/helper-create-class-features-plugin" "^7.25.9" + "@babel/helper-plugin-utils" "^7.25.9" + +"@babel/plugin-transform-property-literals@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.25.9.tgz#d72d588bd88b0dec8b62e36f6fda91cedfe28e3f" + integrity sha512-IvIUeV5KrS/VPavfSM/Iu+RE6llrHrYIKY1yfCzyO/lMXHQ+p7uGhonmGVisv6tSBSVgWzMBohTcvkC9vQcQFA== + dependencies: + "@babel/helper-plugin-utils" "^7.25.9" + +"@babel/plugin-transform-regenerator@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.25.9.tgz#03a8a4670d6cebae95305ac6defac81ece77740b" + integrity sha512-vwDcDNsgMPDGP0nMqzahDWE5/MLcX8sv96+wfX7as7LoF/kr97Bo/7fI00lXY4wUXYfVmwIIyG80fGZ1uvt2qg== + dependencies: + "@babel/helper-plugin-utils" "^7.25.9" + regenerator-transform "^0.15.2" + +"@babel/plugin-transform-regexp-modifiers@^7.26.0": + version "7.26.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regexp-modifiers/-/plugin-transform-regexp-modifiers-7.26.0.tgz#2f5837a5b5cd3842a919d8147e9903cc7455b850" + integrity sha512-vN6saax7lrA2yA/Pak3sCxuD6F5InBjn9IcrIKQPjpsLvuHYLVroTxjdlVRHjjBWxKOqIwpTXDkOssYT4BFdRw== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.25.9" + "@babel/helper-plugin-utils" "^7.25.9" + +"@babel/plugin-transform-reserved-words@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.25.9.tgz#0398aed2f1f10ba3f78a93db219b27ef417fb9ce" + integrity sha512-7DL7DKYjn5Su++4RXu8puKZm2XBPHyjWLUidaPEkCUBbE7IPcsrkRHggAOOKydH1dASWdcUBxrkOGNxUv5P3Jg== + dependencies: + "@babel/helper-plugin-utils" "^7.25.9" + +"@babel/plugin-transform-shorthand-properties@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.25.9.tgz#bb785e6091f99f826a95f9894fc16fde61c163f2" + integrity sha512-MUv6t0FhO5qHnS/W8XCbHmiRWOphNufpE1IVxhK5kuN3Td9FT1x4rx4K42s3RYdMXCXpfWkGSbCSd0Z64xA7Ng== + dependencies: + "@babel/helper-plugin-utils" "^7.25.9" + +"@babel/plugin-transform-spread@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.25.9.tgz#24a35153931b4ba3d13cec4a7748c21ab5514ef9" + integrity sha512-oNknIB0TbURU5pqJFVbOOFspVlrpVwo2H1+HUIsVDvp5VauGGDP1ZEvO8Nn5xyMEs3dakajOxlmkNW7kNgSm6A== + dependencies: + "@babel/helper-plugin-utils" "^7.25.9" + "@babel/helper-skip-transparent-expression-wrappers" "^7.25.9" + +"@babel/plugin-transform-sticky-regex@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.25.9.tgz#c7f02b944e986a417817b20ba2c504dfc1453d32" + integrity sha512-WqBUSgeVwucYDP9U/xNRQam7xV8W5Zf+6Eo7T2SRVUFlhRiMNFdFz58u0KZmCVVqs2i7SHgpRnAhzRNmKfi2uA== + dependencies: + "@babel/helper-plugin-utils" "^7.25.9" + +"@babel/plugin-transform-template-literals@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.25.9.tgz#6dbd4a24e8fad024df76d1fac6a03cf413f60fe1" + integrity sha512-o97AE4syN71M/lxrCtQByzphAdlYluKPDBzDVzMmfCobUjjhAryZV0AIpRPrxN0eAkxXO6ZLEScmt+PNhj2OTw== + dependencies: + "@babel/helper-plugin-utils" "^7.25.9" + +"@babel/plugin-transform-typeof-symbol@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.25.9.tgz#224ba48a92869ddbf81f9b4a5f1204bbf5a2bc4b" + integrity sha512-v61XqUMiueJROUv66BVIOi0Fv/CUuZuZMl5NkRoCVxLAnMexZ0A3kMe7vvZ0nulxMuMp0Mk6S5hNh48yki08ZA== + dependencies: + "@babel/helper-plugin-utils" "^7.25.9" + +"@babel/plugin-transform-typescript@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.25.9.tgz#69267905c2b33c2ac6d8fe765e9dc2ddc9df3849" + integrity sha512-7PbZQZP50tzv2KGGnhh82GSyMB01yKY9scIjf1a+GfZCtInOWqUH5+1EBU4t9fyR5Oykkkc9vFTs4OHrhHXljQ== + dependencies: + "@babel/helper-annotate-as-pure" "^7.25.9" + "@babel/helper-create-class-features-plugin" "^7.25.9" + "@babel/helper-plugin-utils" "^7.25.9" + "@babel/helper-skip-transparent-expression-wrappers" "^7.25.9" + "@babel/plugin-syntax-typescript" "^7.25.9" + +"@babel/plugin-transform-unicode-escapes@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.25.9.tgz#a75ef3947ce15363fccaa38e2dd9bc70b2788b82" + integrity sha512-s5EDrE6bW97LtxOcGj1Khcx5AaXwiMmi4toFWRDP9/y0Woo6pXC+iyPu/KuhKtfSrNFd7jJB+/fkOtZy6aIC6Q== + dependencies: + "@babel/helper-plugin-utils" "^7.25.9" + +"@babel/plugin-transform-unicode-property-regex@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.25.9.tgz#a901e96f2c1d071b0d1bb5dc0d3c880ce8f53dd3" + integrity sha512-Jt2d8Ga+QwRluxRQ307Vlxa6dMrYEMZCgGxoPR8V52rxPyldHu3hdlHspxaqYmE7oID5+kB+UKUB/eWS+DkkWg== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.25.9" + "@babel/helper-plugin-utils" "^7.25.9" + +"@babel/plugin-transform-unicode-regex@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.25.9.tgz#5eae747fe39eacf13a8bd006a4fb0b5d1fa5e9b1" + integrity sha512-yoxstj7Rg9dlNn9UQxzk4fcNivwv4nUYz7fYXBaKxvw/lnmPuOm/ikoELygbYq68Bls3D/D+NBPHiLwZdZZ4HA== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.25.9" + "@babel/helper-plugin-utils" "^7.25.9" + +"@babel/plugin-transform-unicode-sets-regex@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.25.9.tgz#65114c17b4ffc20fa5b163c63c70c0d25621fabe" + integrity sha512-8BYqO3GeVNHtx69fdPshN3fnzUNLrWdHhk/icSwigksJGczKSizZ+Z6SBCxTs723Fr5VSNorTIK7a+R2tISvwQ== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.25.9" + "@babel/helper-plugin-utils" "^7.25.9" + +"@babel/preset-env@^7.23.2": + version "7.26.0" + resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.26.0.tgz#30e5c6bc1bcc54865bff0c5a30f6d4ccdc7fa8b1" + integrity sha512-H84Fxq0CQJNdPFT2DrfnylZ3cf5K43rGfWK4LJGPpjKHiZlk0/RzwEus3PDDZZg+/Er7lCA03MVacueUuXdzfw== + dependencies: + "@babel/compat-data" "^7.26.0" + "@babel/helper-compilation-targets" "^7.25.9" + "@babel/helper-plugin-utils" "^7.25.9" + "@babel/helper-validator-option" "^7.25.9" + "@babel/plugin-bugfix-firefox-class-in-computed-class-key" "^7.25.9" + "@babel/plugin-bugfix-safari-class-field-initializer-scope" "^7.25.9" + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression" "^7.25.9" + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining" "^7.25.9" + "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly" "^7.25.9" + "@babel/plugin-proposal-private-property-in-object" "7.21.0-placeholder-for-preset-env.2" + "@babel/plugin-syntax-import-assertions" "^7.26.0" + "@babel/plugin-syntax-import-attributes" "^7.26.0" + "@babel/plugin-syntax-unicode-sets-regex" "^7.18.6" + "@babel/plugin-transform-arrow-functions" "^7.25.9" + "@babel/plugin-transform-async-generator-functions" "^7.25.9" + "@babel/plugin-transform-async-to-generator" "^7.25.9" + "@babel/plugin-transform-block-scoped-functions" "^7.25.9" + "@babel/plugin-transform-block-scoping" "^7.25.9" + "@babel/plugin-transform-class-properties" "^7.25.9" + "@babel/plugin-transform-class-static-block" "^7.26.0" + "@babel/plugin-transform-classes" "^7.25.9" + "@babel/plugin-transform-computed-properties" "^7.25.9" + "@babel/plugin-transform-destructuring" "^7.25.9" + "@babel/plugin-transform-dotall-regex" "^7.25.9" + "@babel/plugin-transform-duplicate-keys" "^7.25.9" + "@babel/plugin-transform-duplicate-named-capturing-groups-regex" "^7.25.9" + "@babel/plugin-transform-dynamic-import" "^7.25.9" + "@babel/plugin-transform-exponentiation-operator" "^7.25.9" + "@babel/plugin-transform-export-namespace-from" "^7.25.9" + "@babel/plugin-transform-for-of" "^7.25.9" + "@babel/plugin-transform-function-name" "^7.25.9" + "@babel/plugin-transform-json-strings" "^7.25.9" + "@babel/plugin-transform-literals" "^7.25.9" + "@babel/plugin-transform-logical-assignment-operators" "^7.25.9" + "@babel/plugin-transform-member-expression-literals" "^7.25.9" + "@babel/plugin-transform-modules-amd" "^7.25.9" + "@babel/plugin-transform-modules-commonjs" "^7.25.9" + "@babel/plugin-transform-modules-systemjs" "^7.25.9" + "@babel/plugin-transform-modules-umd" "^7.25.9" + "@babel/plugin-transform-named-capturing-groups-regex" "^7.25.9" + "@babel/plugin-transform-new-target" "^7.25.9" + "@babel/plugin-transform-nullish-coalescing-operator" "^7.25.9" + "@babel/plugin-transform-numeric-separator" "^7.25.9" + "@babel/plugin-transform-object-rest-spread" "^7.25.9" + "@babel/plugin-transform-object-super" "^7.25.9" + "@babel/plugin-transform-optional-catch-binding" "^7.25.9" + "@babel/plugin-transform-optional-chaining" "^7.25.9" + "@babel/plugin-transform-parameters" "^7.25.9" + "@babel/plugin-transform-private-methods" "^7.25.9" + "@babel/plugin-transform-private-property-in-object" "^7.25.9" + "@babel/plugin-transform-property-literals" "^7.25.9" + "@babel/plugin-transform-regenerator" "^7.25.9" + "@babel/plugin-transform-regexp-modifiers" "^7.26.0" + "@babel/plugin-transform-reserved-words" "^7.25.9" + "@babel/plugin-transform-shorthand-properties" "^7.25.9" + "@babel/plugin-transform-spread" "^7.25.9" + "@babel/plugin-transform-sticky-regex" "^7.25.9" + "@babel/plugin-transform-template-literals" "^7.25.9" + "@babel/plugin-transform-typeof-symbol" "^7.25.9" + "@babel/plugin-transform-unicode-escapes" "^7.25.9" + "@babel/plugin-transform-unicode-property-regex" "^7.25.9" + "@babel/plugin-transform-unicode-regex" "^7.25.9" + "@babel/plugin-transform-unicode-sets-regex" "^7.25.9" + "@babel/preset-modules" "0.1.6-no-external-plugins" + babel-plugin-polyfill-corejs2 "^0.4.10" + babel-plugin-polyfill-corejs3 "^0.10.6" + babel-plugin-polyfill-regenerator "^0.6.1" + core-js-compat "^3.38.1" + semver "^6.3.1" + +"@babel/preset-flow@^7.22.15": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/preset-flow/-/preset-flow-7.25.9.tgz#ef8b5e7e3f24a42b3711e77fb14919b87dffed0a" + integrity sha512-EASHsAhE+SSlEzJ4bzfusnXSHiU+JfAYzj+jbw2vgQKgq5HrUr8qs+vgtiEL5dOH6sEweI+PNt2D7AqrDSHyqQ== + dependencies: + "@babel/helper-plugin-utils" "^7.25.9" + "@babel/helper-validator-option" "^7.25.9" + "@babel/plugin-transform-flow-strip-types" "^7.25.9" + +"@babel/preset-modules@0.1.6-no-external-plugins": + version "0.1.6-no-external-plugins" + resolved "https://registry.yarnpkg.com/@babel/preset-modules/-/preset-modules-0.1.6-no-external-plugins.tgz#ccb88a2c49c817236861fee7826080573b8a923a" + integrity sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/types" "^7.4.4" + esutils "^2.0.2" + +"@babel/preset-typescript@^7.23.0": + version "7.26.0" + resolved "https://registry.yarnpkg.com/@babel/preset-typescript/-/preset-typescript-7.26.0.tgz#4a570f1b8d104a242d923957ffa1eaff142a106d" + integrity sha512-NMk1IGZ5I/oHhoXEElcm+xUnL/szL6xflkFZmoEU9xj1qSJXpiS7rsspYo92B4DRCDvZn2erT5LdsCeXAKNCkg== + dependencies: + "@babel/helper-plugin-utils" "^7.25.9" + "@babel/helper-validator-option" "^7.25.9" + "@babel/plugin-syntax-jsx" "^7.25.9" + "@babel/plugin-transform-modules-commonjs" "^7.25.9" + "@babel/plugin-transform-typescript" "^7.25.9" + +"@babel/register@^7.22.15": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/register/-/register-7.25.9.tgz#1c465acf7dc983d70ccc318eb5b887ecb04f021b" + integrity sha512-8D43jXtGsYmEeDvm4MWHYUpWf8iiXgWYx3fW7E7Wb7Oe6FWqJPl5K6TuFW0dOwNZzEE5rjlaSJYH9JjrUKJszA== + dependencies: + clone-deep "^4.0.1" + find-cache-dir "^2.0.0" + make-dir "^2.1.0" + pirates "^4.0.6" + source-map-support "^0.5.16" + +"@babel/runtime@^7.12.5", "@babel/runtime@^7.13.10", "@babel/runtime@^7.17.8", "@babel/runtime@^7.8.4": + version "7.26.0" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.26.0.tgz#8600c2f595f277c60815256418b85356a65173c1" + integrity sha512-FDSOghenHTiToteC/QRlv2q3DhPZ/oOXTBoirfWNx1Cx3TMVcGWQtMMmQcSvb/JjpNeGzx8Pq/b4fKEJuWm1sw== + dependencies: + regenerator-runtime "^0.14.0" + +"@babel/template@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.25.9.tgz#ecb62d81a8a6f5dc5fe8abfc3901fc52ddf15016" + integrity sha512-9DGttpmPvIxBb/2uwpVo3dqJ+O6RooAFOS+lB+xDqoE2PVCE8nfoHMdZLpfCQRLwvohzXISPZcgxt80xLfsuwg== + dependencies: + "@babel/code-frame" "^7.25.9" + "@babel/parser" "^7.25.9" + "@babel/types" "^7.25.9" + +"@babel/traverse@^7.23.2", "@babel/traverse@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.25.9.tgz#a50f8fe49e7f69f53de5bea7e413cd35c5e13c84" + integrity sha512-ZCuvfwOwlz/bawvAuvcj8rrithP2/N55Tzz342AkTvq4qaWbGfmCk/tKhNaV2cthijKrPAA8SRJV5WWe7IBMJw== + dependencies: + "@babel/code-frame" "^7.25.9" + "@babel/generator" "^7.25.9" + "@babel/parser" "^7.25.9" + "@babel/template" "^7.25.9" + "@babel/types" "^7.25.9" + debug "^4.3.1" + globals "^11.1.0" + +"@babel/types@^7.0.0", "@babel/types@^7.20.7", "@babel/types@^7.23.0", "@babel/types@^7.25.9", "@babel/types@^7.26.0", "@babel/types@^7.4.4": + version "7.26.0" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.26.0.tgz#deabd08d6b753bc8e0f198f8709fb575e31774ff" + integrity sha512-Z/yiTPj+lDVnF7lWeKCIJzaIkI0vYO87dMpZ4bg4TDrFe4XXLFWL1TbXU27gBP3QccxV9mZICCrnjnYlJjXHOA== + dependencies: + "@babel/helper-string-parser" "^7.25.9" + "@babel/helper-validator-identifier" "^7.25.9" + +"@colors/colors@1.5.0": + version "1.5.0" + resolved "https://registry.yarnpkg.com/@colors/colors/-/colors-1.5.0.tgz#bb504579c1cae923e6576a4f5da43d25f97bdbd9" + integrity sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ== + +"@discoveryjs/json-ext@^0.5.3": + version "0.5.7" + resolved "https://registry.yarnpkg.com/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz#1d572bfbbe14b7704e0ba0f39b74815b84870d70" + integrity sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw== + +"@emotion/use-insertion-effect-with-fallbacks@^1.0.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.1.0.tgz#1a818a0b2c481efba0cf34e5ab1e0cb2dcb9dfaf" + integrity sha512-+wBOcIV5snwGgI2ya3u99D7/FJquOIniQT1IKyDsBmEgwvpxMNeS65Oib7OnE2d2aY+3BU4OiH+0Wchf8yk3Hw== + +"@esbuild/android-arm64@0.18.20": + version "0.18.20" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.18.20.tgz#984b4f9c8d0377443cc2dfcef266d02244593622" + integrity sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ== + +"@esbuild/android-arm@0.18.20": + version "0.18.20" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.18.20.tgz#fedb265bc3a589c84cc11f810804f234947c3682" + integrity sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw== + +"@esbuild/android-x64@0.18.20": + version "0.18.20" + resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.18.20.tgz#35cf419c4cfc8babe8893d296cd990e9e9f756f2" + integrity sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg== + +"@esbuild/darwin-arm64@0.18.20": + version "0.18.20" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.18.20.tgz#08172cbeccf95fbc383399a7f39cfbddaeb0d7c1" + integrity sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA== + +"@esbuild/darwin-x64@0.18.20": + version "0.18.20" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.18.20.tgz#d70d5790d8bf475556b67d0f8b7c5bdff053d85d" + integrity sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ== + +"@esbuild/freebsd-arm64@0.18.20": + version "0.18.20" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.20.tgz#98755cd12707f93f210e2494d6a4b51b96977f54" + integrity sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw== + +"@esbuild/freebsd-x64@0.18.20": + version "0.18.20" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.18.20.tgz#c1eb2bff03915f87c29cece4c1a7fa1f423b066e" + integrity sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ== + +"@esbuild/linux-arm64@0.18.20": + version "0.18.20" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.18.20.tgz#bad4238bd8f4fc25b5a021280c770ab5fc3a02a0" + integrity sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA== + +"@esbuild/linux-arm@0.18.20": + version "0.18.20" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.18.20.tgz#3e617c61f33508a27150ee417543c8ab5acc73b0" + integrity sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg== + +"@esbuild/linux-ia32@0.18.20": + version "0.18.20" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.18.20.tgz#699391cccba9aee6019b7f9892eb99219f1570a7" + integrity sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA== + +"@esbuild/linux-loong64@0.18.20": + version "0.18.20" + resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.18.20.tgz#e6fccb7aac178dd2ffb9860465ac89d7f23b977d" + integrity sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg== + +"@esbuild/linux-mips64el@0.18.20": + version "0.18.20" + resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.18.20.tgz#eeff3a937de9c2310de30622a957ad1bd9183231" + integrity sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ== + +"@esbuild/linux-ppc64@0.18.20": + version "0.18.20" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.18.20.tgz#2f7156bde20b01527993e6881435ad79ba9599fb" + integrity sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA== + +"@esbuild/linux-riscv64@0.18.20": + version "0.18.20" + resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.18.20.tgz#6628389f210123d8b4743045af8caa7d4ddfc7a6" + integrity sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A== + +"@esbuild/linux-s390x@0.18.20": + version "0.18.20" + resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.18.20.tgz#255e81fb289b101026131858ab99fba63dcf0071" + integrity sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ== + +"@esbuild/linux-x64@0.18.20": + version "0.18.20" + resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.18.20.tgz#c7690b3417af318a9b6f96df3031a8865176d338" + integrity sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w== + +"@esbuild/netbsd-x64@0.18.20": + version "0.18.20" + resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.18.20.tgz#30e8cd8a3dded63975e2df2438ca109601ebe0d1" + integrity sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A== + +"@esbuild/openbsd-x64@0.18.20": + version "0.18.20" + resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.18.20.tgz#7812af31b205055874c8082ea9cf9ab0da6217ae" + integrity sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg== + +"@esbuild/sunos-x64@0.18.20": + version "0.18.20" + resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.18.20.tgz#d5c275c3b4e73c9b0ecd38d1ca62c020f887ab9d" + integrity sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ== + +"@esbuild/win32-arm64@0.18.20": + version "0.18.20" + resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.18.20.tgz#73bc7f5a9f8a77805f357fab97f290d0e4820ac9" + integrity sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg== + +"@esbuild/win32-ia32@0.18.20": + version "0.18.20" + resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.18.20.tgz#ec93cbf0ef1085cc12e71e0d661d20569ff42102" + integrity sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g== + +"@esbuild/win32-x64@0.18.20": + version "0.18.20" + resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.18.20.tgz#786c5f41f043b07afb1af37683d7c33668858f6d" + integrity sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ== + +"@fal-works/esbuild-plugin-global-externals@^2.1.2": + version "2.1.2" + resolved "https://registry.yarnpkg.com/@fal-works/esbuild-plugin-global-externals/-/esbuild-plugin-global-externals-2.1.2.tgz#c05ed35ad82df8e6ac616c68b92c2282bd083ba4" + integrity sha512-cEee/Z+I12mZcFJshKcCqC8tuX5hG3s+d+9nZ3LabqKF1vKdF41B92pJVCBggjAGORAeOzyyDDKrZwIkLffeOQ== + +"@floating-ui/core@^1.6.0": + version "1.6.8" + resolved "https://registry.yarnpkg.com/@floating-ui/core/-/core-1.6.8.tgz#aa43561be075815879305965020f492cdb43da12" + integrity sha512-7XJ9cPU+yI2QeLS+FCSlqNFZJq8arvswefkZrYI1yQBbftw6FyrZOxYSh+9S7z7TpeWlRt9zJ5IhM1WIL334jA== + dependencies: + "@floating-ui/utils" "^0.2.8" + +"@floating-ui/dom@^1.0.0": + version "1.6.12" + resolved "https://registry.yarnpkg.com/@floating-ui/dom/-/dom-1.6.12.tgz#6333dcb5a8ead3b2bf82f33d6bc410e95f54e556" + integrity sha512-NP83c0HjokcGVEMeoStg317VD9W7eDlGK7457dMBANbKA6GJZdc7rjujdgqzTaz93jkGgc5P/jeWbaCHnMNc+w== + dependencies: + "@floating-ui/core" "^1.6.0" + "@floating-ui/utils" "^0.2.8" + +"@floating-ui/react-dom@^2.0.0": + version "2.1.2" + resolved "https://registry.yarnpkg.com/@floating-ui/react-dom/-/react-dom-2.1.2.tgz#a1349bbf6a0e5cb5ded55d023766f20a4d439a31" + integrity sha512-06okr5cgPzMNBy+Ycse2A6udMi4bqwW/zgBF/rwjcNqWkyr82Mcg8b0vjX8OJpZFy/FKjJmw6wV7t44kK6kW7A== + dependencies: + "@floating-ui/dom" "^1.0.0" + +"@floating-ui/utils@^0.2.8": + version "0.2.8" + resolved "https://registry.yarnpkg.com/@floating-ui/utils/-/utils-0.2.8.tgz#21a907684723bbbaa5f0974cf7730bd797eb8e62" + integrity sha512-kym7SodPp8/wloecOpcmSnWJsK7M0E5Wg8UcFA+uO4B9s5d0ywXOEro/8HM9x0rW+TljRzul/14UYz3TleT3ig== + +"@isaacs/cliui@^8.0.2": + version "8.0.2" + resolved "https://registry.yarnpkg.com/@isaacs/cliui/-/cliui-8.0.2.tgz#b37667b7bc181c168782259bab42474fbf52b550" + integrity sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA== + dependencies: + string-width "^5.1.2" + string-width-cjs "npm:string-width@^4.2.0" + strip-ansi "^7.0.1" + strip-ansi-cjs "npm:strip-ansi@^6.0.1" + wrap-ansi "^8.1.0" + wrap-ansi-cjs "npm:wrap-ansi@^7.0.0" + +"@istanbuljs/load-nyc-config@^1.0.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz#fd3db1d59ecf7cf121e80650bb86712f9b55eced" + integrity sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ== + dependencies: + camelcase "^5.3.1" + find-up "^4.1.0" + get-package-type "^0.1.0" + js-yaml "^3.13.1" + resolve-from "^5.0.0" + +"@istanbuljs/schema@^0.1.2": + version "0.1.3" + resolved "https://registry.yarnpkg.com/@istanbuljs/schema/-/schema-0.1.3.tgz#e45e384e4b8ec16bce2fd903af78450f6bf7ec98" + integrity sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA== + +"@jest/schemas@^29.6.3": + version "29.6.3" + resolved "https://registry.yarnpkg.com/@jest/schemas/-/schemas-29.6.3.tgz#430b5ce8a4e0044a7e3819663305a7b3091c8e03" + integrity sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA== + dependencies: + "@sinclair/typebox" "^0.27.8" + +"@jest/transform@^29.3.1": + version "29.7.0" + resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-29.7.0.tgz#df2dd9c346c7d7768b8a06639994640c642e284c" + integrity sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw== + dependencies: + "@babel/core" "^7.11.6" + "@jest/types" "^29.6.3" + "@jridgewell/trace-mapping" "^0.3.18" + babel-plugin-istanbul "^6.1.1" + chalk "^4.0.0" + convert-source-map "^2.0.0" + fast-json-stable-stringify "^2.1.0" + graceful-fs "^4.2.9" + jest-haste-map "^29.7.0" + jest-regex-util "^29.6.3" + jest-util "^29.7.0" + micromatch "^4.0.4" + pirates "^4.0.4" + slash "^3.0.0" + write-file-atomic "^4.0.2" + +"@jest/types@^27.5.1": + version "27.5.1" + resolved "https://registry.yarnpkg.com/@jest/types/-/types-27.5.1.tgz#3c79ec4a8ba61c170bf937bcf9e98a9df175ec80" + integrity sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw== + dependencies: + "@types/istanbul-lib-coverage" "^2.0.0" + "@types/istanbul-reports" "^3.0.0" + "@types/node" "*" + "@types/yargs" "^16.0.0" + chalk "^4.0.0" + +"@jest/types@^29.6.3": + version "29.6.3" + resolved "https://registry.yarnpkg.com/@jest/types/-/types-29.6.3.tgz#1131f8cf634e7e84c5e77bab12f052af585fba59" + integrity sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw== + dependencies: + "@jest/schemas" "^29.6.3" + "@types/istanbul-lib-coverage" "^2.0.0" + "@types/istanbul-reports" "^3.0.0" + "@types/node" "*" + "@types/yargs" "^17.0.8" + chalk "^4.0.0" + +"@jridgewell/gen-mapping@^0.3.5": + version "0.3.5" + resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz#dcce6aff74bdf6dad1a95802b69b04a2fcb1fb36" + integrity sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg== + dependencies: + "@jridgewell/set-array" "^1.2.1" + "@jridgewell/sourcemap-codec" "^1.4.10" + "@jridgewell/trace-mapping" "^0.3.24" + +"@jridgewell/resolve-uri@^3.1.0": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz#7a0ee601f60f99a20c7c7c5ff0c80388c1189bd6" + integrity sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw== + +"@jridgewell/set-array@^1.2.1": + version "1.2.1" + resolved "https://registry.yarnpkg.com/@jridgewell/set-array/-/set-array-1.2.1.tgz#558fb6472ed16a4c850b889530e6b36438c49280" + integrity sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A== + +"@jridgewell/sourcemap-codec@^1.4.10", "@jridgewell/sourcemap-codec@^1.4.14", "@jridgewell/sourcemap-codec@^1.5.0": + version "1.5.0" + resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz#3188bcb273a414b0d215fd22a58540b989b9409a" + integrity sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ== + +"@jridgewell/trace-mapping@^0.3.18", "@jridgewell/trace-mapping@^0.3.24", "@jridgewell/trace-mapping@^0.3.25": + version "0.3.25" + resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz#15f190e98895f3fc23276ee14bc76b675c2e50f0" + integrity sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ== + dependencies: + "@jridgewell/resolve-uri" "^3.1.0" + "@jridgewell/sourcemap-codec" "^1.4.14" + +"@juggle/resize-observer@^3.3.1": + version "3.4.0" + resolved "https://registry.yarnpkg.com/@juggle/resize-observer/-/resize-observer-3.4.0.tgz#08d6c5e20cf7e4cc02fd181c4b0c225cd31dbb60" + integrity sha512-dfLbk+PwWvFzSxwk3n5ySL0hfBog779o8h68wK/7/APo/7cgyWp5jcXockbxdk5kFRkbeXWm4Fbi9FrdN381sA== + +"@mdx-js/react@^2.1.5": + version "2.3.0" + resolved "https://registry.yarnpkg.com/@mdx-js/react/-/react-2.3.0.tgz#4208bd6d70f0d0831def28ef28c26149b03180b3" + integrity sha512-zQH//gdOmuu7nt2oJR29vFhDv88oGPmVw6BggmrHeMI+xgEkp1B2dX9/bMBSYtK0dyLX/aOmesKS09g222K1/g== + dependencies: + "@types/mdx" "^2.0.0" + "@types/react" ">=16" + +"@ndelangen/get-tarball@^3.0.7": + version "3.0.9" + resolved "https://registry.yarnpkg.com/@ndelangen/get-tarball/-/get-tarball-3.0.9.tgz#727ff4454e65f34707e742a59e5e6b1f525d8964" + integrity sha512-9JKTEik4vq+yGosHYhZ1tiH/3WpUS0Nh0kej4Agndhox8pAdWhEx5knFVRcb/ya9knCRCs1rPxNrSXTDdfVqpA== + dependencies: + gunzip-maybe "^1.4.2" + pump "^3.0.0" + tar-fs "^2.1.1" + +"@nodelib/fs.scandir@2.1.5": + version "2.1.5" + resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" + integrity sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g== + dependencies: + "@nodelib/fs.stat" "2.0.5" + run-parallel "^1.1.9" + +"@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2": + version "2.0.5" + resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz#5bd262af94e9d25bd1e71b05deed44876a222e8b" + integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== + +"@nodelib/fs.walk@^1.2.3": + version "1.2.8" + resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz#e95737e8bb6746ddedf69c556953494f196fe69a" + integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg== + dependencies: + "@nodelib/fs.scandir" "2.1.5" + fastq "^1.6.0" + +"@pkgjs/parseargs@^0.11.0": + version "0.11.0" + resolved "https://registry.yarnpkg.com/@pkgjs/parseargs/-/parseargs-0.11.0.tgz#a77ea742fab25775145434eb1d2328cf5013ac33" + integrity sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg== + +"@radix-ui/number@1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@radix-ui/number/-/number-1.0.1.tgz#644161a3557f46ed38a042acf4a770e826021674" + integrity sha512-T5gIdVO2mmPW3NNhjNgEP3cqMXjXL9UbO0BzWcXfvdBs+BohbQxvd/K5hSVKmn9/lbTdsQVKbUcP5WLCwvUbBg== + dependencies: + "@babel/runtime" "^7.13.10" + +"@radix-ui/primitive@1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@radix-ui/primitive/-/primitive-1.0.1.tgz#e46f9958b35d10e9f6dc71c497305c22e3e55dbd" + integrity sha512-yQ8oGX2GVsEYMWGxcovu1uGWPCxV5BFfeeYxqPmuAzUyLT9qmaMXSAhXpb0WrspIeqYzdJpkh2vHModJPgRIaw== + dependencies: + "@babel/runtime" "^7.13.10" + +"@radix-ui/primitive@1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@radix-ui/primitive/-/primitive-1.1.0.tgz#42ef83b3b56dccad5d703ae8c42919a68798bbe2" + integrity sha512-4Z8dn6Upk0qk4P74xBhZ6Hd/w0mPEzOOLxy4xiPXOXqjF7jZS0VAKk7/x/H6FyY2zCkYJqePf1G5KmkmNJ4RBA== + +"@radix-ui/react-arrow@1.0.3": + version "1.0.3" + resolved "https://registry.yarnpkg.com/@radix-ui/react-arrow/-/react-arrow-1.0.3.tgz#c24f7968996ed934d57fe6cde5d6ec7266e1d25d" + integrity sha512-wSP+pHsB/jQRaL6voubsQ/ZlrGBHHrOjmBnr19hxYgtS0WvAFwZhK2WP/YY5yF9uKECCEEDGxuLxq1NBK51wFA== + dependencies: + "@babel/runtime" "^7.13.10" + "@radix-ui/react-primitive" "1.0.3" + +"@radix-ui/react-collection@1.0.3": + version "1.0.3" + resolved "https://registry.yarnpkg.com/@radix-ui/react-collection/-/react-collection-1.0.3.tgz#9595a66e09026187524a36c6e7e9c7d286469159" + integrity sha512-3SzW+0PW7yBBoQlT8wNcGtaxaD0XSu0uLUFgrtHY08Acx05TaHaOmVLR73c0j/cqpDy53KBMO7s0dx2wmOIDIA== + dependencies: + "@babel/runtime" "^7.13.10" + "@radix-ui/react-compose-refs" "1.0.1" + "@radix-ui/react-context" "1.0.1" + "@radix-ui/react-primitive" "1.0.3" + "@radix-ui/react-slot" "1.0.2" + +"@radix-ui/react-collection@1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@radix-ui/react-collection/-/react-collection-1.1.0.tgz#f18af78e46454a2360d103c2251773028b7724ed" + integrity sha512-GZsZslMJEyo1VKm5L1ZJY8tGDxZNPAoUeQUIbKeJfoi7Q4kmig5AsgLMYYuyYbfjd8fBmFORAIwYAkXMnXZgZw== + dependencies: + "@radix-ui/react-compose-refs" "1.1.0" + "@radix-ui/react-context" "1.1.0" + "@radix-ui/react-primitive" "2.0.0" + "@radix-ui/react-slot" "1.1.0" + +"@radix-ui/react-compose-refs@1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@radix-ui/react-compose-refs/-/react-compose-refs-1.0.1.tgz#7ed868b66946aa6030e580b1ffca386dd4d21989" + integrity sha512-fDSBgd44FKHa1FRMU59qBMPFcl2PZE+2nmqunj+BWFyYYjnhIDWL2ItDs3rrbJDQOtzt5nIebLCQc4QRfz6LJw== + dependencies: + "@babel/runtime" "^7.13.10" + +"@radix-ui/react-compose-refs@1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.0.tgz#656432461fc8283d7b591dcf0d79152fae9ecc74" + integrity sha512-b4inOtiaOnYf9KWyO3jAeeCG6FeyfY6ldiEPanbUjWd+xIk5wZeHa8yVwmrJ2vderhu/BQvzCrJI0lHd+wIiqw== + +"@radix-ui/react-context@1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@radix-ui/react-context/-/react-context-1.0.1.tgz#fe46e67c96b240de59187dcb7a1a50ce3e2ec00c" + integrity sha512-ebbrdFoYTcuZ0v4wG5tedGnp9tzcV8awzsxYph7gXUyvnNLuTIcCk1q17JEbnVhXAKG9oX3KtchwiMIAYp9NLg== + dependencies: + "@babel/runtime" "^7.13.10" + +"@radix-ui/react-context@1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@radix-ui/react-context/-/react-context-1.1.0.tgz#6df8d983546cfd1999c8512f3a8ad85a6e7fcee8" + integrity sha512-OKrckBy+sMEgYM/sMmqmErVn0kZqrHPJze+Ql3DzYsDDp0hl0L62nx/2122/Bvps1qz645jlcu2tD9lrRSdf8A== + +"@radix-ui/react-direction@1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@radix-ui/react-direction/-/react-direction-1.0.1.tgz#9cb61bf2ccf568f3421422d182637b7f47596c9b" + integrity sha512-RXcvnXgyvYvBEOhCBuddKecVkoMiI10Jcm5cTI7abJRAHYfFxeu+FBQs/DvdxSYucxR5mna0dNsL6QFlds5TMA== + dependencies: + "@babel/runtime" "^7.13.10" + +"@radix-ui/react-direction@1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@radix-ui/react-direction/-/react-direction-1.1.0.tgz#a7d39855f4d077adc2a1922f9c353c5977a09cdc" + integrity sha512-BUuBvgThEiAXh2DWu93XsT+a3aWrGqolGlqqw5VU1kG7p/ZH2cuDlM1sRLNnY3QcBS69UIz2mcKhMxDsdewhjg== + +"@radix-ui/react-dismissable-layer@1.0.4": + version "1.0.4" + resolved "https://registry.yarnpkg.com/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.0.4.tgz#883a48f5f938fa679427aa17fcba70c5494c6978" + integrity sha512-7UpBa/RKMoHJYjie1gkF1DlK8l1fdU/VKDpoS3rCCo8YBJR294GwcEHyxHw72yvphJ7ld0AXEcSLAzY2F/WyCg== + dependencies: + "@babel/runtime" "^7.13.10" + "@radix-ui/primitive" "1.0.1" + "@radix-ui/react-compose-refs" "1.0.1" + "@radix-ui/react-primitive" "1.0.3" + "@radix-ui/react-use-callback-ref" "1.0.1" + "@radix-ui/react-use-escape-keydown" "1.0.3" + +"@radix-ui/react-focus-guards@1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@radix-ui/react-focus-guards/-/react-focus-guards-1.0.1.tgz#1ea7e32092216b946397866199d892f71f7f98ad" + integrity sha512-Rect2dWbQ8waGzhMavsIbmSVCgYxkXLxxR3ZvCX79JOglzdEy4JXMb98lq4hPxUbLr77nP0UOGf4rcMU+s1pUA== + dependencies: + "@babel/runtime" "^7.13.10" + +"@radix-ui/react-focus-scope@1.0.3": + version "1.0.3" + resolved "https://registry.yarnpkg.com/@radix-ui/react-focus-scope/-/react-focus-scope-1.0.3.tgz#9c2e8d4ed1189a1d419ee61edd5c1828726472f9" + integrity sha512-upXdPfqI4islj2CslyfUBNlaJCPybbqRHAi1KER7Isel9Q2AtSJ0zRBZv8mWQiFXD2nyAJ4BhC3yXgZ6kMBSrQ== + dependencies: + "@babel/runtime" "^7.13.10" + "@radix-ui/react-compose-refs" "1.0.1" + "@radix-ui/react-primitive" "1.0.3" + "@radix-ui/react-use-callback-ref" "1.0.1" + +"@radix-ui/react-id@1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@radix-ui/react-id/-/react-id-1.0.1.tgz#73cdc181f650e4df24f0b6a5b7aa426b912c88c0" + integrity sha512-tI7sT/kqYp8p96yGWY1OAnLHrqDgzHefRBKQ2YAkBS5ja7QLcZ9Z/uY7bEjPUatf8RomoXM8/1sMj1IJaE5UzQ== + dependencies: + "@babel/runtime" "^7.13.10" + "@radix-ui/react-use-layout-effect" "1.0.1" + +"@radix-ui/react-id@1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@radix-ui/react-id/-/react-id-1.1.0.tgz#de47339656594ad722eb87f94a6b25f9cffae0ed" + integrity sha512-EJUrI8yYh7WOjNOqpoJaf1jlFIH2LvtgAl+YcFqNCa+4hj64ZXmPkAKOFs/ukjz3byN6bdb/AVUqHkI8/uWWMA== + dependencies: + "@radix-ui/react-use-layout-effect" "1.1.0" + +"@radix-ui/react-popper@1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@radix-ui/react-popper/-/react-popper-1.1.2.tgz#4c0b96fcd188dc1f334e02dba2d538973ad842e9" + integrity sha512-1CnGGfFi/bbqtJZZ0P/NQY20xdG3E0LALJaLUEoKwPLwl6PPPfbeiCqMVQnhoFRAxjJj4RpBRJzDmUgsex2tSg== + dependencies: + "@babel/runtime" "^7.13.10" + "@floating-ui/react-dom" "^2.0.0" + "@radix-ui/react-arrow" "1.0.3" + "@radix-ui/react-compose-refs" "1.0.1" + "@radix-ui/react-context" "1.0.1" + "@radix-ui/react-primitive" "1.0.3" + "@radix-ui/react-use-callback-ref" "1.0.1" + "@radix-ui/react-use-layout-effect" "1.0.1" + "@radix-ui/react-use-rect" "1.0.1" + "@radix-ui/react-use-size" "1.0.1" + "@radix-ui/rect" "1.0.1" + +"@radix-ui/react-portal@1.0.3": + version "1.0.3" + resolved "https://registry.yarnpkg.com/@radix-ui/react-portal/-/react-portal-1.0.3.tgz#ffb961244c8ed1b46f039e6c215a6c4d9989bda1" + integrity sha512-xLYZeHrWoPmA5mEKEfZZevoVRK/Q43GfzRXkWV6qawIWWK8t6ifIiLQdd7rmQ4Vk1bmI21XhqF9BN3jWf+phpA== + dependencies: + "@babel/runtime" "^7.13.10" + "@radix-ui/react-primitive" "1.0.3" + +"@radix-ui/react-primitive@1.0.3": + version "1.0.3" + resolved "https://registry.yarnpkg.com/@radix-ui/react-primitive/-/react-primitive-1.0.3.tgz#d49ea0f3f0b2fe3ab1cb5667eb03e8b843b914d0" + integrity sha512-yi58uVyoAcK/Nq1inRY56ZSjKypBNKTa/1mcL8qdl6oJeEaDbOldlzrGn7P6Q3Id5d+SYNGc5AJgc4vGhjs5+g== + dependencies: + "@babel/runtime" "^7.13.10" + "@radix-ui/react-slot" "1.0.2" + +"@radix-ui/react-primitive@2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@radix-ui/react-primitive/-/react-primitive-2.0.0.tgz#fe05715faa9203a223ccc0be15dc44b9f9822884" + integrity sha512-ZSpFm0/uHa8zTvKBDjLFWLo8dkr4MBsiDLz0g3gMUwqgLHz9rTaRRGYDgvZPtBJgYCBKXkS9fzmoySgr8CO6Cw== + dependencies: + "@radix-ui/react-slot" "1.1.0" + +"@radix-ui/react-roving-focus@1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@radix-ui/react-roving-focus/-/react-roving-focus-1.1.0.tgz#b30c59daf7e714c748805bfe11c76f96caaac35e" + integrity sha512-EA6AMGeq9AEeQDeSH0aZgG198qkfHSbvWTf1HvoDmOB5bBG/qTxjYMWUKMnYiV6J/iP/J8MEFSuB2zRU2n7ODA== + dependencies: + "@radix-ui/primitive" "1.1.0" + "@radix-ui/react-collection" "1.1.0" + "@radix-ui/react-compose-refs" "1.1.0" + "@radix-ui/react-context" "1.1.0" + "@radix-ui/react-direction" "1.1.0" + "@radix-ui/react-id" "1.1.0" + "@radix-ui/react-primitive" "2.0.0" + "@radix-ui/react-use-callback-ref" "1.1.0" + "@radix-ui/react-use-controllable-state" "1.1.0" + +"@radix-ui/react-select@^1.2.2": + version "1.2.2" + resolved "https://registry.yarnpkg.com/@radix-ui/react-select/-/react-select-1.2.2.tgz#caa981fa0d672cf3c1b2a5240135524e69b32181" + integrity sha512-zI7McXr8fNaSrUY9mZe4x/HC0jTLY9fWNhO1oLWYMQGDXuV4UCivIGTxwioSzO0ZCYX9iSLyWmAh/1TOmX3Cnw== + dependencies: + "@babel/runtime" "^7.13.10" + "@radix-ui/number" "1.0.1" + "@radix-ui/primitive" "1.0.1" + "@radix-ui/react-collection" "1.0.3" + "@radix-ui/react-compose-refs" "1.0.1" + "@radix-ui/react-context" "1.0.1" + "@radix-ui/react-direction" "1.0.1" + "@radix-ui/react-dismissable-layer" "1.0.4" + "@radix-ui/react-focus-guards" "1.0.1" + "@radix-ui/react-focus-scope" "1.0.3" + "@radix-ui/react-id" "1.0.1" + "@radix-ui/react-popper" "1.1.2" + "@radix-ui/react-portal" "1.0.3" + "@radix-ui/react-primitive" "1.0.3" + "@radix-ui/react-slot" "1.0.2" + "@radix-ui/react-use-callback-ref" "1.0.1" + "@radix-ui/react-use-controllable-state" "1.0.1" + "@radix-ui/react-use-layout-effect" "1.0.1" + "@radix-ui/react-use-previous" "1.0.1" + "@radix-ui/react-visually-hidden" "1.0.3" + aria-hidden "^1.1.1" + react-remove-scroll "2.5.5" + +"@radix-ui/react-separator@1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@radix-ui/react-separator/-/react-separator-1.1.0.tgz#ee0f4d86003b0e3ea7bc6ccab01ea0adee32663e" + integrity sha512-3uBAs+egzvJBDZAzvb/n4NxxOYpnspmWxO2u5NbZ8Y6FM/NdrGSF9bop3Cf6F6C71z1rTSn8KV0Fo2ZVd79lGA== + dependencies: + "@radix-ui/react-primitive" "2.0.0" + +"@radix-ui/react-slot@1.0.2": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@radix-ui/react-slot/-/react-slot-1.0.2.tgz#a9ff4423eade67f501ffb32ec22064bc9d3099ab" + integrity sha512-YeTpuq4deV+6DusvVUW4ivBgnkHwECUu0BiN43L5UCDFgdhsRUWAghhTF5MbvNTPzmiFOx90asDSUjWuCNapwg== + dependencies: + "@babel/runtime" "^7.13.10" + "@radix-ui/react-compose-refs" "1.0.1" + +"@radix-ui/react-slot@1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@radix-ui/react-slot/-/react-slot-1.1.0.tgz#7c5e48c36ef5496d97b08f1357bb26ed7c714b84" + integrity sha512-FUCf5XMfmW4dtYl69pdS4DbxKy8nj4M7SafBgPllysxmdachynNflAdp/gCsnYWNDnge6tI9onzMp5ARYc1KNw== + dependencies: + "@radix-ui/react-compose-refs" "1.1.0" + +"@radix-ui/react-toggle-group@1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@radix-ui/react-toggle-group/-/react-toggle-group-1.1.0.tgz#28714c4d1ff4961a8fd259b1feef58b4cac92f80" + integrity sha512-PpTJV68dZU2oqqgq75Uzto5o/XfOVgkrJ9rulVmfTKxWp3HfUjHE6CP/WLRR4AzPX9HWxw7vFow2me85Yu+Naw== + dependencies: + "@radix-ui/primitive" "1.1.0" + "@radix-ui/react-context" "1.1.0" + "@radix-ui/react-direction" "1.1.0" + "@radix-ui/react-primitive" "2.0.0" + "@radix-ui/react-roving-focus" "1.1.0" + "@radix-ui/react-toggle" "1.1.0" + "@radix-ui/react-use-controllable-state" "1.1.0" + +"@radix-ui/react-toggle@1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@radix-ui/react-toggle/-/react-toggle-1.1.0.tgz#1f7697b82917019330a16c6f96f649f46b4606cf" + integrity sha512-gwoxaKZ0oJ4vIgzsfESBuSgJNdc0rv12VhHgcqN0TEJmmZixXG/2XpsLK8kzNWYcnaoRIEEQc0bEi3dIvdUpjw== + dependencies: + "@radix-ui/primitive" "1.1.0" + "@radix-ui/react-primitive" "2.0.0" + "@radix-ui/react-use-controllable-state" "1.1.0" + +"@radix-ui/react-toolbar@^1.0.4": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@radix-ui/react-toolbar/-/react-toolbar-1.1.0.tgz#a25d65b394ab6e9e7f45f4843cc0c55845bbcfab" + integrity sha512-ZUKknxhMTL/4hPh+4DuaTot9aO7UD6Kupj4gqXCsBTayX1pD1L+0C2/2VZKXb4tIifQklZ3pf2hG9T+ns+FclQ== + dependencies: + "@radix-ui/primitive" "1.1.0" + "@radix-ui/react-context" "1.1.0" + "@radix-ui/react-direction" "1.1.0" + "@radix-ui/react-primitive" "2.0.0" + "@radix-ui/react-roving-focus" "1.1.0" + "@radix-ui/react-separator" "1.1.0" + "@radix-ui/react-toggle-group" "1.1.0" + +"@radix-ui/react-use-callback-ref@1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.0.1.tgz#f4bb1f27f2023c984e6534317ebc411fc181107a" + integrity sha512-D94LjX4Sp0xJFVaoQOd3OO9k7tpBYNOXdVhkltUbGv2Qb9OXdrg/CpsjlZv7ia14Sylv398LswWBVVu5nqKzAQ== + dependencies: + "@babel/runtime" "^7.13.10" + +"@radix-ui/react-use-callback-ref@1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.1.0.tgz#bce938ca413675bc937944b0d01ef6f4a6dc5bf1" + integrity sha512-CasTfvsy+frcFkbXtSJ2Zu9JHpN8TYKxkgJGWbjiZhFivxaeW7rMeZt7QELGVLaYVfFMsKHjb7Ak0nMEe+2Vfw== + +"@radix-ui/react-use-controllable-state@1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.0.1.tgz#ecd2ced34e6330caf89a82854aa2f77e07440286" + integrity sha512-Svl5GY5FQeN758fWKrjM6Qb7asvXeiZltlT4U2gVfl8Gx5UAv2sMR0LWo8yhsIZh2oQ0eFdZ59aoOOMV7b47VA== + dependencies: + "@babel/runtime" "^7.13.10" + "@radix-ui/react-use-callback-ref" "1.0.1" + +"@radix-ui/react-use-controllable-state@1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.1.0.tgz#1321446857bb786917df54c0d4d084877aab04b0" + integrity sha512-MtfMVJiSr2NjzS0Aa90NPTnvTSg6C/JLCV7ma0W6+OMV78vd8OyRpID+Ng9LxzsPbLeuBnWBA1Nq30AtBIDChw== + dependencies: + "@radix-ui/react-use-callback-ref" "1.1.0" + +"@radix-ui/react-use-escape-keydown@1.0.3": + version "1.0.3" + resolved "https://registry.yarnpkg.com/@radix-ui/react-use-escape-keydown/-/react-use-escape-keydown-1.0.3.tgz#217b840c250541609c66f67ed7bab2b733620755" + integrity sha512-vyL82j40hcFicA+M4Ex7hVkB9vHgSse1ZWomAqV2Je3RleKGO5iM8KMOEtfoSB0PnIelMd2lATjTGMYqN5ylTg== + dependencies: + "@babel/runtime" "^7.13.10" + "@radix-ui/react-use-callback-ref" "1.0.1" + +"@radix-ui/react-use-layout-effect@1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.0.1.tgz#be8c7bc809b0c8934acf6657b577daf948a75399" + integrity sha512-v/5RegiJWYdoCvMnITBkNNx6bCj20fiaJnWtRkU18yITptraXjffz5Qbn05uOiQnOvi+dbkznkoaMltz1GnszQ== + dependencies: + "@babel/runtime" "^7.13.10" + +"@radix-ui/react-use-layout-effect@1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.1.0.tgz#3c2c8ce04827b26a39e442ff4888d9212268bd27" + integrity sha512-+FPE0rOdziWSrH9athwI1R0HDVbWlEhd+FR+aSDk4uWGmSJ9Z54sdZVDQPZAinJhJXwfT+qnj969mCsT2gfm5w== + +"@radix-ui/react-use-previous@1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@radix-ui/react-use-previous/-/react-use-previous-1.0.1.tgz#b595c087b07317a4f143696c6a01de43b0d0ec66" + integrity sha512-cV5La9DPwiQ7S0gf/0qiD6YgNqM5Fk97Kdrlc5yBcrF3jyEZQwm7vYFqMo4IfeHgJXsRaMvLABFtd0OVEmZhDw== + dependencies: + "@babel/runtime" "^7.13.10" + +"@radix-ui/react-use-rect@1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@radix-ui/react-use-rect/-/react-use-rect-1.0.1.tgz#fde50b3bb9fd08f4a1cd204572e5943c244fcec2" + integrity sha512-Cq5DLuSiuYVKNU8orzJMbl15TXilTnJKUCltMVQg53BQOF1/C5toAaGrowkgksdBQ9H+SRL23g0HDmg9tvmxXw== + dependencies: + "@babel/runtime" "^7.13.10" + "@radix-ui/rect" "1.0.1" + +"@radix-ui/react-use-size@1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@radix-ui/react-use-size/-/react-use-size-1.0.1.tgz#1c5f5fea940a7d7ade77694bb98116fb49f870b2" + integrity sha512-ibay+VqrgcaI6veAojjofPATwledXiSmX+C0KrBk/xgpX9rBzPV3OsfwlhQdUOFbh+LKQorLYT+xTXW9V8yd0g== + dependencies: + "@babel/runtime" "^7.13.10" + "@radix-ui/react-use-layout-effect" "1.0.1" + +"@radix-ui/react-visually-hidden@1.0.3": + version "1.0.3" + resolved "https://registry.yarnpkg.com/@radix-ui/react-visually-hidden/-/react-visually-hidden-1.0.3.tgz#51aed9dd0fe5abcad7dee2a234ad36106a6984ac" + integrity sha512-D4w41yN5YRKtu464TLnByKzMDG/JlMPHtfZgQAu9v6mNakUqGUI9vUrfQKz8NK41VMm/xbZbh76NUTVtIYqOMA== + dependencies: + "@babel/runtime" "^7.13.10" + "@radix-ui/react-primitive" "1.0.3" + +"@radix-ui/rect@1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@radix-ui/rect/-/rect-1.0.1.tgz#bf8e7d947671996da2e30f4904ece343bc4a883f" + integrity sha512-fyrgCaedtvMg9NK3en0pnOYJdtfwxUcNolezkNPUsoX57X8oQk+NkqcvzHXD2uKNij6GXmWU9NDru2IWjrO4BQ== + dependencies: + "@babel/runtime" "^7.13.10" + +"@sinclair/typebox@^0.27.8": + version "0.27.8" + resolved "https://registry.yarnpkg.com/@sinclair/typebox/-/typebox-0.27.8.tgz#6667fac16c436b5434a387a34dedb013198f6e6e" + integrity sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA== + +"@storybook/addon-actions@7.6.20": + version "7.6.20" + resolved "https://registry.yarnpkg.com/@storybook/addon-actions/-/addon-actions-7.6.20.tgz#4264d1fba6e889f28f717ebb23c55b7d774a2f60" + integrity sha512-c/GkEQ2U9BC/Ew/IMdh+zvsh4N6y6n7Zsn2GIhJgcu9YEAa5aF2a9/pNgEGBMOABH959XE8DAOMERw/5qiLR8g== + dependencies: + "@storybook/core-events" "7.6.20" + "@storybook/global" "^5.0.0" + "@types/uuid" "^9.0.1" + dequal "^2.0.2" + polished "^4.2.2" + uuid "^9.0.0" + +"@storybook/addon-backgrounds@7.6.20": + version "7.6.20" + resolved "https://registry.yarnpkg.com/@storybook/addon-backgrounds/-/addon-backgrounds-7.6.20.tgz#a84758c07b236181f2d67966a7c159d0b3bc1abb" + integrity sha512-a7ukoaXT42vpKsMxkseIeO3GqL0Zst2IxpCTq5dSlXiADrcemSF/8/oNpNW9C4L6F1Zdt+WDtECXslEm017FvQ== + dependencies: + "@storybook/global" "^5.0.0" + memoizerific "^1.11.3" + ts-dedent "^2.0.0" + +"@storybook/addon-controls@7.6.20": + version "7.6.20" + resolved "https://registry.yarnpkg.com/@storybook/addon-controls/-/addon-controls-7.6.20.tgz#5487064259a71f10b0aab04a4b7745ecf948e4cc" + integrity sha512-06ZT5Ce1sZW52B0s6XuokwjkKO9GqHlTUHvuflvd8wifxKlCmRvNUxjBvwh+ccGJ49ZS73LbMSLFgtmBEkCxbg== + dependencies: + "@storybook/blocks" "7.6.20" + lodash "^4.17.21" + ts-dedent "^2.0.0" + +"@storybook/addon-docs@7.6.20": + version "7.6.20" + resolved "https://registry.yarnpkg.com/@storybook/addon-docs/-/addon-docs-7.6.20.tgz#0bff85bdbdca58c9535384a4ded69dadb2fe7e4e" + integrity sha512-XNfYRhbxH5JP7B9Lh4W06PtMefNXkfpV39Gaoih5HuqngV3eoSL4RikZYOMkvxRGQ738xc6axySU3+JKcP1OZg== + dependencies: + "@jest/transform" "^29.3.1" + "@mdx-js/react" "^2.1.5" + "@storybook/blocks" "7.6.20" + "@storybook/client-logger" "7.6.20" + "@storybook/components" "7.6.20" + "@storybook/csf-plugin" "7.6.20" + "@storybook/csf-tools" "7.6.20" + "@storybook/global" "^5.0.0" + "@storybook/mdx2-csf" "^1.0.0" + "@storybook/node-logger" "7.6.20" + "@storybook/postinstall" "7.6.20" + "@storybook/preview-api" "7.6.20" + "@storybook/react-dom-shim" "7.6.20" + "@storybook/theming" "7.6.20" + "@storybook/types" "7.6.20" + fs-extra "^11.1.0" + remark-external-links "^8.0.0" + remark-slug "^6.0.0" + ts-dedent "^2.0.0" + +"@storybook/addon-essentials@^7.2.0": + version "7.6.20" + resolved "https://registry.yarnpkg.com/@storybook/addon-essentials/-/addon-essentials-7.6.20.tgz#149c22b51a7abd8977acaaf2e1941c5b5dcb2fd5" + integrity sha512-hCupSOiJDeOxJKZSgH0x5Mb2Xqii6mps21g5hpxac1XjhQtmGflShxi/xOHhK3sNqrbgTSbScfpUP3hUlZO/2Q== + dependencies: + "@storybook/addon-actions" "7.6.20" + "@storybook/addon-backgrounds" "7.6.20" + "@storybook/addon-controls" "7.6.20" + "@storybook/addon-docs" "7.6.20" + "@storybook/addon-highlight" "7.6.20" + "@storybook/addon-measure" "7.6.20" + "@storybook/addon-outline" "7.6.20" + "@storybook/addon-toolbars" "7.6.20" + "@storybook/addon-viewport" "7.6.20" + "@storybook/core-common" "7.6.20" + "@storybook/manager-api" "7.6.20" + "@storybook/node-logger" "7.6.20" + "@storybook/preview-api" "7.6.20" + ts-dedent "^2.0.0" + +"@storybook/addon-highlight@7.6.20": + version "7.6.20" + resolved "https://registry.yarnpkg.com/@storybook/addon-highlight/-/addon-highlight-7.6.20.tgz#d118e4cce549238d866bbbe4d49b9509afda01a7" + integrity sha512-7/x7xFdFyqCki5Dm3uBePldUs9l98/WxJ7rTHQuYqlX7kASwyN5iXPzuhmMRUhlMm/6G6xXtLabIpzwf1sFurA== + dependencies: + "@storybook/global" "^5.0.0" + +"@storybook/addon-interactions@^7.2.0": + version "7.6.20" + resolved "https://registry.yarnpkg.com/@storybook/addon-interactions/-/addon-interactions-7.6.20.tgz#9471575cb3699d12a7011299ce6bca1cb8aea252" + integrity sha512-uH+OIxLtvfnnmdN3Uf8MwzfEFYtaqSA6Hir6QNPc643se0RymM8mULN0rzRyvspwd6OagWdtOxsws3aHk02KTA== + dependencies: + "@storybook/global" "^5.0.0" + "@storybook/types" "7.6.20" + jest-mock "^27.0.6" + polished "^4.2.2" + ts-dedent "^2.2.0" + +"@storybook/addon-links@^7.2.0": + version "7.6.20" + resolved "https://registry.yarnpkg.com/@storybook/addon-links/-/addon-links-7.6.20.tgz#c6bedc7bdc0112ce4cb3f1bfc701445df696598d" + integrity sha512-iomSnBD90CA4MinesYiJkFX2kb3P1Psd/a1Y0ghlFEsHD4uMId9iT6sx2s16DYMja0SlPkrbWYnGukqaCjZpRw== + dependencies: + "@storybook/csf" "^0.1.2" + "@storybook/global" "^5.0.0" + ts-dedent "^2.0.0" + +"@storybook/addon-measure@7.6.20": + version "7.6.20" + resolved "https://registry.yarnpkg.com/@storybook/addon-measure/-/addon-measure-7.6.20.tgz#c764009ce3e980b5b67e462ad0de5986c38cdfab" + integrity sha512-i2Iq08bGfI7gZbG6Lb8uF/L287tnaGUR+2KFEmdBjH6+kgjWLiwfpanoPQpy4drm23ar0gUjX+L3Ri03VI5/Xg== + dependencies: + "@storybook/global" "^5.0.0" + tiny-invariant "^1.3.1" + +"@storybook/addon-outline@7.6.20": + version "7.6.20" + resolved "https://registry.yarnpkg.com/@storybook/addon-outline/-/addon-outline-7.6.20.tgz#0ebe829b6d8d269f691a110f3b34884b1df8ee74" + integrity sha512-TdsIQZf/TcDsGoZ1XpO+9nBc4OKqcMIzY4SrI8Wj9dzyFLQ37s08gnZr9POci8AEv62NTUOVavsxcafllkzqDQ== + dependencies: + "@storybook/global" "^5.0.0" + ts-dedent "^2.0.0" + +"@storybook/addon-toolbars@7.6.20": + version "7.6.20" + resolved "https://registry.yarnpkg.com/@storybook/addon-toolbars/-/addon-toolbars-7.6.20.tgz#c1cd31c6a8f98d3ec4853157134ca143d065d31a" + integrity sha512-5Btg4i8ffWTDHsU72cqxC8nIv9N3E3ObJAc6k0llrmPBG/ybh3jxmRfs8fNm44LlEXaZ5qrK/petsXX3UbpIFg== + +"@storybook/addon-viewport@7.6.20": + version "7.6.20" + resolved "https://registry.yarnpkg.com/@storybook/addon-viewport/-/addon-viewport-7.6.20.tgz#882571f4b0f405e1cf2cfad9a1f74b30d22f9a93" + integrity sha512-i8mIw8BjLWAVHEQsOTE6UPuEGQvJDpsu1XZnOCkpfTfPMz73m+3td/PmLG7mMT2wPnLu9IZncKLCKTAZRbt/YQ== + dependencies: + memoizerific "^1.11.3" + +"@storybook/addons@7.6.20": + version "7.6.20" + resolved "https://registry.yarnpkg.com/@storybook/addons/-/addons-7.6.20.tgz#5aab8614ff913b93bbff68946e03c25f48c297be" + integrity sha512-ilXE2CrdI+Z/nJ4Ur5lTCk2yM/DzzLpAeUxIq1TDk5lsMcjYJIH5/pmpFMM/uCsvd8TLRCZsAAju1tbhzXVy1w== + dependencies: + "@storybook/manager-api" "7.6.20" + "@storybook/preview-api" "7.6.20" + "@storybook/types" "7.6.20" + +"@storybook/blocks@7.6.20", "@storybook/blocks@^7.2.0": + version "7.6.20" + resolved "https://registry.yarnpkg.com/@storybook/blocks/-/blocks-7.6.20.tgz#1cc142f1c238616f0f3a9f900965c651e7ee7c52" + integrity sha512-xADKGEOJWkG0UD5jbY4mBXRlmj2C+CIupDL0/hpzvLvwobxBMFPKZIkcZIMvGvVnI/Ui+tJxQxLSuJ5QsPthUw== + dependencies: + "@storybook/channels" "7.6.20" + "@storybook/client-logger" "7.6.20" + "@storybook/components" "7.6.20" + "@storybook/core-events" "7.6.20" + "@storybook/csf" "^0.1.2" + "@storybook/docs-tools" "7.6.20" + "@storybook/global" "^5.0.0" + "@storybook/manager-api" "7.6.20" + "@storybook/preview-api" "7.6.20" + "@storybook/theming" "7.6.20" + "@storybook/types" "7.6.20" + "@types/lodash" "^4.14.167" + color-convert "^2.0.1" + dequal "^2.0.2" + lodash "^4.17.21" + markdown-to-jsx "^7.1.8" + memoizerific "^1.11.3" + polished "^4.2.2" + react-colorful "^5.1.2" + telejson "^7.2.0" + tocbot "^4.20.1" + ts-dedent "^2.0.0" + util-deprecate "^1.0.2" + +"@storybook/builder-manager@7.6.20": + version "7.6.20" + resolved "https://registry.yarnpkg.com/@storybook/builder-manager/-/builder-manager-7.6.20.tgz#d550a3f209012e4e383e61320ea756cddfdb416e" + integrity sha512-e2GzpjLaw6CM/XSmc4qJRzBF8GOoOyotyu3JrSPTYOt4RD8kjUsK4QlismQM1DQRu8i39aIexxmRbiJyD74xzQ== + dependencies: + "@fal-works/esbuild-plugin-global-externals" "^2.1.2" + "@storybook/core-common" "7.6.20" + "@storybook/manager" "7.6.20" + "@storybook/node-logger" "7.6.20" + "@types/ejs" "^3.1.1" + "@types/find-cache-dir" "^3.2.1" + "@yarnpkg/esbuild-plugin-pnp" "^3.0.0-rc.10" + browser-assert "^1.2.1" + ejs "^3.1.8" + esbuild "^0.18.0" + esbuild-plugin-alias "^0.2.1" + express "^4.17.3" + find-cache-dir "^3.0.0" + fs-extra "^11.1.0" + process "^0.11.10" + util "^0.12.4" + +"@storybook/builder-vite@7.6.20": + version "7.6.20" + resolved "https://registry.yarnpkg.com/@storybook/builder-vite/-/builder-vite-7.6.20.tgz#4e46e658640049afccbb75d28ff52a72020edb8d" + integrity sha512-q3vf8heE7EaVYTWlm768ewaJ9lh6v/KfoPPeHxXxzSstg4ByP9kg4E1mrfAo/l6broE9E9zo3/Q4gsM/G/rw8Q== + dependencies: + "@storybook/channels" "7.6.20" + "@storybook/client-logger" "7.6.20" + "@storybook/core-common" "7.6.20" + "@storybook/csf-plugin" "7.6.20" + "@storybook/node-logger" "7.6.20" + "@storybook/preview" "7.6.20" + "@storybook/preview-api" "7.6.20" + "@storybook/types" "7.6.20" + "@types/find-cache-dir" "^3.2.1" + browser-assert "^1.2.1" + es-module-lexer "^0.9.3" + express "^4.17.3" + find-cache-dir "^3.0.0" + fs-extra "^11.1.0" + magic-string "^0.30.0" + rollup "^2.25.0 || ^3.3.0" + +"@storybook/channels@7.6.20": + version "7.6.20" + resolved "https://registry.yarnpkg.com/@storybook/channels/-/channels-7.6.20.tgz#33d8292b1b16d7f504bf751c57a792477d1c3a9e" + integrity sha512-4hkgPSH6bJclB2OvLnkZOGZW1WptJs09mhQ6j6qLjgBZzL/ZdD6priWSd7iXrmPiN5TzUobkG4P4Dp7FjkiO7A== + dependencies: + "@storybook/client-logger" "7.6.20" + "@storybook/core-events" "7.6.20" + "@storybook/global" "^5.0.0" + qs "^6.10.0" + telejson "^7.2.0" + tiny-invariant "^1.3.1" + +"@storybook/cli@7.6.20": + version "7.6.20" + resolved "https://registry.yarnpkg.com/@storybook/cli/-/cli-7.6.20.tgz#498625db5f2447e8e1ad34827a7803c5940527f0" + integrity sha512-ZlP+BJyqg7HlnXf7ypjG2CKMI/KVOn03jFIiClItE/jQfgR6kRFgtjRU7uajh427HHfjv9DRiur8nBzuO7vapA== + dependencies: + "@babel/core" "^7.23.2" + "@babel/preset-env" "^7.23.2" + "@babel/types" "^7.23.0" + "@ndelangen/get-tarball" "^3.0.7" + "@storybook/codemod" "7.6.20" + "@storybook/core-common" "7.6.20" + "@storybook/core-events" "7.6.20" + "@storybook/core-server" "7.6.20" + "@storybook/csf-tools" "7.6.20" + "@storybook/node-logger" "7.6.20" + "@storybook/telemetry" "7.6.20" + "@storybook/types" "7.6.20" + "@types/semver" "^7.3.4" + "@yarnpkg/fslib" "2.10.3" + "@yarnpkg/libzip" "2.3.0" + chalk "^4.1.0" + commander "^6.2.1" + cross-spawn "^7.0.3" + detect-indent "^6.1.0" + envinfo "^7.7.3" + execa "^5.0.0" + express "^4.17.3" + find-up "^5.0.0" + fs-extra "^11.1.0" + get-npm-tarball-url "^2.0.3" + get-port "^5.1.1" + giget "^1.0.0" + globby "^11.0.2" + jscodeshift "^0.15.1" + leven "^3.1.0" + ora "^5.4.1" + prettier "^2.8.0" + prompts "^2.4.0" + puppeteer-core "^2.1.1" + read-pkg-up "^7.0.1" + semver "^7.3.7" + strip-json-comments "^3.0.1" + tempy "^1.0.1" + ts-dedent "^2.0.0" + util-deprecate "^1.0.2" + +"@storybook/client-api@7.6.20": + version "7.6.20" + resolved "https://registry.yarnpkg.com/@storybook/client-api/-/client-api-7.6.20.tgz#1b39a3d0c31696fd47df487f047cbbb2e7cc5d00" + integrity sha512-q7fG11XesBG+kDMMjUHiVOIKhFRawfyUEb+8YJpGHqWCzMk4obpNwK+YjGua9vsRsen6yhMqJ/KSZmDvnR6x9g== + dependencies: + "@storybook/client-logger" "7.6.20" + "@storybook/preview-api" "7.6.20" + +"@storybook/client-logger@7.6.20": + version "7.6.20" + resolved "https://registry.yarnpkg.com/@storybook/client-logger/-/client-logger-7.6.20.tgz#1d6e93443091cccd50e269371aa786172d0c4659" + integrity sha512-NwG0VIJQCmKrSaN5GBDFyQgTAHLNishUPLW1NrzqTDNAhfZUoef64rPQlinbopa0H4OXmlB+QxbQIb3ubeXmSQ== + dependencies: + "@storybook/global" "^5.0.0" + +"@storybook/codemod@7.6.20": + version "7.6.20" + resolved "https://registry.yarnpkg.com/@storybook/codemod/-/codemod-7.6.20.tgz#0aa7e0c1aacc605c7691b4b06baef0a9abefe114" + integrity sha512-8vmSsksO4XukNw0TmqylPmk7PxnfNfE21YsxFa7mnEBmEKQcZCQsNil4ZgWfG0IzdhTfhglAN4r++Ew0WE+PYA== + dependencies: + "@babel/core" "^7.23.2" + "@babel/preset-env" "^7.23.2" + "@babel/types" "^7.23.0" + "@storybook/csf" "^0.1.2" + "@storybook/csf-tools" "7.6.20" + "@storybook/node-logger" "7.6.20" + "@storybook/types" "7.6.20" + "@types/cross-spawn" "^6.0.2" + cross-spawn "^7.0.3" + globby "^11.0.2" + jscodeshift "^0.15.1" + lodash "^4.17.21" + prettier "^2.8.0" + recast "^0.23.1" + +"@storybook/components@7.6.20": + version "7.6.20" + resolved "https://registry.yarnpkg.com/@storybook/components/-/components-7.6.20.tgz#09d044923142d2e087a1c4a43dec6731a42d2871" + integrity sha512-0d8u4m558R+W5V+rseF/+e9JnMciADLXTpsILrG+TBhwECk0MctIWW18bkqkujdCm8kDZr5U2iM/5kS1Noy7Ug== + dependencies: + "@radix-ui/react-select" "^1.2.2" + "@radix-ui/react-toolbar" "^1.0.4" + "@storybook/client-logger" "7.6.20" + "@storybook/csf" "^0.1.2" + "@storybook/global" "^5.0.0" + "@storybook/theming" "7.6.20" + "@storybook/types" "7.6.20" + memoizerific "^1.11.3" + use-resize-observer "^9.1.0" + util-deprecate "^1.0.2" + +"@storybook/core-client@7.6.20": + version "7.6.20" + resolved "https://registry.yarnpkg.com/@storybook/core-client/-/core-client-7.6.20.tgz#831681d64194e4d604a859ed3eb452981f6824c5" + integrity sha512-upQuQQinLmlOPKcT8yqXNtwIucZ4E4qegYZXH5HXRWoLAL6GQtW7sUVSIuFogdki8OXRncr/dz8OA+5yQyYS4w== + dependencies: + "@storybook/client-logger" "7.6.20" + "@storybook/preview-api" "7.6.20" + +"@storybook/core-common@7.6.20": + version "7.6.20" + resolved "https://registry.yarnpkg.com/@storybook/core-common/-/core-common-7.6.20.tgz#3a2a3ae570bd13dc34726178c0eb36cf6a64e2a4" + integrity sha512-8H1zPWPjcmeD4HbDm4FDD0WLsfAKGVr566IZ4hG+h3iWVW57II9JW9MLBtiR2LPSd8u7o0kw64lwRGmtCO1qAw== + dependencies: + "@storybook/core-events" "7.6.20" + "@storybook/node-logger" "7.6.20" + "@storybook/types" "7.6.20" + "@types/find-cache-dir" "^3.2.1" + "@types/node" "^18.0.0" + "@types/node-fetch" "^2.6.4" + "@types/pretty-hrtime" "^1.0.0" + chalk "^4.1.0" + esbuild "^0.18.0" + esbuild-register "^3.5.0" + file-system-cache "2.3.0" + find-cache-dir "^3.0.0" + find-up "^5.0.0" + fs-extra "^11.1.0" + glob "^10.0.0" + handlebars "^4.7.7" + lazy-universal-dotenv "^4.0.0" + node-fetch "^2.0.0" + picomatch "^2.3.0" + pkg-dir "^5.0.0" + pretty-hrtime "^1.0.3" + resolve-from "^5.0.0" + ts-dedent "^2.0.0" + +"@storybook/core-events@7.6.20": + version "7.6.20" + resolved "https://registry.yarnpkg.com/@storybook/core-events/-/core-events-7.6.20.tgz#6648d661d1c96841a4c2a710a35759b01b6a06a1" + integrity sha512-tlVDuVbDiNkvPDFAu+0ou3xBBYbx9zUURQz4G9fAq0ScgBOs/bpzcRrFb4mLpemUViBAd47tfZKdH4MAX45KVQ== + dependencies: + ts-dedent "^2.0.0" + +"@storybook/core-server@7.6.20": + version "7.6.20" + resolved "https://registry.yarnpkg.com/@storybook/core-server/-/core-server-7.6.20.tgz#fa143fbcad64fb7b0f0dc6d555d083c506a44ab4" + integrity sha512-qC5BdbqqwMLTdCwMKZ1Hbc3+3AaxHYWLiJaXL9e8s8nJw89xV8c8l30QpbJOGvcDmsgY6UTtXYaJ96OsTr7MrA== + dependencies: + "@aw-web-design/x-default-browser" "1.4.126" + "@discoveryjs/json-ext" "^0.5.3" + "@storybook/builder-manager" "7.6.20" + "@storybook/channels" "7.6.20" + "@storybook/core-common" "7.6.20" + "@storybook/core-events" "7.6.20" + "@storybook/csf" "^0.1.2" + "@storybook/csf-tools" "7.6.20" + "@storybook/docs-mdx" "^0.1.0" + "@storybook/global" "^5.0.0" + "@storybook/manager" "7.6.20" + "@storybook/node-logger" "7.6.20" + "@storybook/preview-api" "7.6.20" + "@storybook/telemetry" "7.6.20" + "@storybook/types" "7.6.20" + "@types/detect-port" "^1.3.0" + "@types/node" "^18.0.0" + "@types/pretty-hrtime" "^1.0.0" + "@types/semver" "^7.3.4" + better-opn "^3.0.2" + chalk "^4.1.0" + cli-table3 "^0.6.1" + compression "^1.7.4" + detect-port "^1.3.0" + express "^4.17.3" + fs-extra "^11.1.0" + globby "^11.0.2" + lodash "^4.17.21" + open "^8.4.0" + pretty-hrtime "^1.0.3" + prompts "^2.4.0" + read-pkg-up "^7.0.1" + semver "^7.3.7" + telejson "^7.2.0" + tiny-invariant "^1.3.1" + ts-dedent "^2.0.0" + util "^0.12.4" + util-deprecate "^1.0.2" + watchpack "^2.2.0" + ws "^8.2.3" + +"@storybook/csf-plugin@7.6.20": + version "7.6.20" + resolved "https://registry.yarnpkg.com/@storybook/csf-plugin/-/csf-plugin-7.6.20.tgz#0e79e58d5ed47dfb472b1dc202b0e754c21ec33b" + integrity sha512-dzBzq0dN+8WLDp6NxYS4G7BCe8+vDeDRBRjHmM0xb0uJ6xgQViL8SDplYVSGnk3bXE/1WmtvyRzQyTffBnaj9Q== + dependencies: + "@storybook/csf-tools" "7.6.20" + unplugin "^1.3.1" + +"@storybook/csf-tools@7.6.20": + version "7.6.20" + resolved "https://registry.yarnpkg.com/@storybook/csf-tools/-/csf-tools-7.6.20.tgz#fdd9fa9459720a627e83e31d3839721dbc655f22" + integrity sha512-rwcwzCsAYh/m/WYcxBiEtLpIW5OH1ingxNdF/rK9mtGWhJxXRDV8acPkFrF8rtFWIVKoOCXu5USJYmc3f2gdYQ== + dependencies: + "@babel/generator" "^7.23.0" + "@babel/parser" "^7.23.0" + "@babel/traverse" "^7.23.2" + "@babel/types" "^7.23.0" + "@storybook/csf" "^0.1.2" + "@storybook/types" "7.6.20" + fs-extra "^11.1.0" + recast "^0.23.1" + ts-dedent "^2.0.0" + +"@storybook/csf@^0.1.2": + version "0.1.11" + resolved "https://registry.yarnpkg.com/@storybook/csf/-/csf-0.1.11.tgz#ad685a4fe564a47a6b73571c2e7c07b526f4f71b" + integrity sha512-dHYFQH3mA+EtnCkHXzicbLgsvzYjcDJ1JWsogbItZogkPHgSJM/Wr71uMkcvw8v9mmCyP4NpXJuu6bPoVsOnzg== + dependencies: + type-fest "^2.19.0" + +"@storybook/docs-mdx@^0.1.0": + version "0.1.0" + resolved "https://registry.yarnpkg.com/@storybook/docs-mdx/-/docs-mdx-0.1.0.tgz#33ba0e39d1461caf048b57db354b2cc410705316" + integrity sha512-JDaBR9lwVY4eSH5W8EGHrhODjygPd6QImRbwjAuJNEnY0Vw4ie3bPkeGfnacB3OBW6u/agqPv2aRlR46JcAQLg== + +"@storybook/docs-tools@7.6.20": + version "7.6.20" + resolved "https://registry.yarnpkg.com/@storybook/docs-tools/-/docs-tools-7.6.20.tgz#2a6dd402c880e24ec6bec8411beee89cfe69f932" + integrity sha512-Bw2CcCKQ5xGLQgtexQsI1EGT6y5epoFzOINi0FSTGJ9Wm738nRp5LH3dLk1GZLlywIXcYwOEThb2pM+pZeRQxQ== + dependencies: + "@storybook/core-common" "7.6.20" + "@storybook/preview-api" "7.6.20" + "@storybook/types" "7.6.20" + "@types/doctrine" "^0.0.3" + assert "^2.1.0" + doctrine "^3.0.0" + lodash "^4.17.21" + +"@storybook/global@^5.0.0": + version "5.0.0" + resolved "https://registry.yarnpkg.com/@storybook/global/-/global-5.0.0.tgz#b793d34b94f572c1d7d9e0f44fac4e0dbc9572ed" + integrity sha512-FcOqPAXACP0I3oJ/ws6/rrPT9WGhu915Cg8D02a9YxLo0DE9zI+a9A5gRGvmQ09fiWPukqI8ZAEoQEdWUKMQdQ== + +"@storybook/html-vite@^7.2.0": + version "7.6.20" + resolved "https://registry.yarnpkg.com/@storybook/html-vite/-/html-vite-7.6.20.tgz#cb701ffab3eeb09952ecdafed776e3dff7193cd3" + integrity sha512-JAk5uvY5rrr8DwVzczHqb2SO3IiOKePdIXF3esUJb0yomPviAL87u4WALEaa7TdeUBO3q0ZQmmR35CXrDbSXbQ== + dependencies: + "@storybook/addons" "7.6.20" + "@storybook/builder-vite" "7.6.20" + "@storybook/client-api" "7.6.20" + "@storybook/core-server" "7.6.20" + "@storybook/html" "7.6.20" + "@storybook/node-logger" "7.6.20" + "@storybook/preview-web" "7.6.20" + magic-string "^0.30.0" + +"@storybook/html@7.6.20", "@storybook/html@^7.2.0": + version "7.6.20" + resolved "https://registry.yarnpkg.com/@storybook/html/-/html-7.6.20.tgz#783f19234cc49c1cf5629ed80e1c19fb4bf7cf23" + integrity sha512-438v36zDSfZOKiOYY3qiakPag7YtLXEubwYp4gyHzQ54j0GcopbGoBaRpdx4lhc6uix09i0n9hgern6VsX/IMw== + dependencies: + "@storybook/core-client" "7.6.20" + "@storybook/docs-tools" "7.6.20" + "@storybook/global" "^5.0.0" + "@storybook/preview-api" "7.6.20" + "@storybook/types" "7.6.20" + ts-dedent "^2.0.0" + +"@storybook/manager-api@7.6.20": + version "7.6.20" + resolved "https://registry.yarnpkg.com/@storybook/manager-api/-/manager-api-7.6.20.tgz#225ff7dea3dbdb2e82bb5568babdaace4071c32e" + integrity sha512-gOB3m8hO3gBs9cBoN57T7jU0wNKDh+hi06gLcyd2awARQlAlywnLnr3s1WH5knih6Aq+OpvGBRVKkGLOkaouCQ== + dependencies: + "@storybook/channels" "7.6.20" + "@storybook/client-logger" "7.6.20" + "@storybook/core-events" "7.6.20" + "@storybook/csf" "^0.1.2" + "@storybook/global" "^5.0.0" + "@storybook/router" "7.6.20" + "@storybook/theming" "7.6.20" + "@storybook/types" "7.6.20" + dequal "^2.0.2" + lodash "^4.17.21" + memoizerific "^1.11.3" + store2 "^2.14.2" + telejson "^7.2.0" + ts-dedent "^2.0.0" + +"@storybook/manager@7.6.20": + version "7.6.20" + resolved "https://registry.yarnpkg.com/@storybook/manager/-/manager-7.6.20.tgz#eb619fe8d33446e581a7b1c3050644c196364d39" + integrity sha512-0Cf6WN0t7yEG2DR29tN5j+i7H/TH5EfPppg9h9/KiQSoFHk+6KLoy2p5do94acFU+Ro4+zzxvdCGbcYGKuArpg== + +"@storybook/mdx2-csf@^1.0.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@storybook/mdx2-csf/-/mdx2-csf-1.1.0.tgz#97f6df04d0bf616991cc1005a073ac004a7281e5" + integrity sha512-TXJJd5RAKakWx4BtpwvSNdgTDkKM6RkXU8GK34S/LhidQ5Pjz3wcnqb0TxEkfhK/ztbP8nKHqXFwLfa2CYkvQw== + +"@storybook/node-logger@7.6.20": + version "7.6.20" + resolved "https://registry.yarnpkg.com/@storybook/node-logger/-/node-logger-7.6.20.tgz#c0ca90cf68cf31d84cdcf53c76cec22769407ece" + integrity sha512-l2i4qF1bscJkOplNffcRTsgQWYR7J51ewmizj5YrTM8BK6rslWT1RntgVJWB1RgPqvx6VsCz1gyP3yW1oKxvYw== + +"@storybook/postinstall@7.6.20": + version "7.6.20" + resolved "https://registry.yarnpkg.com/@storybook/postinstall/-/postinstall-7.6.20.tgz#5a77ce7913375b11bd7c72388798854bd8507b91" + integrity sha512-AN4WPeNma2xC2/K/wP3I/GMbBUyeSGD3+86ZFFJFO1QmE/Zea6E+1aVlTd1iKHQUcNkZ9bZTrqkhPGVYx10pIw== + +"@storybook/preview-api@7.6.20": + version "7.6.20" + resolved "https://registry.yarnpkg.com/@storybook/preview-api/-/preview-api-7.6.20.tgz#688a435ee2cfe57eeb1e3053c18025a9e0a03bbb" + integrity sha512-3ic2m9LDZEPwZk02wIhNc3n3rNvbi7VDKn52hDXfAxnL5EYm7yDICAkaWcVaTfblru2zn0EDJt7ROpthscTW5w== + dependencies: + "@storybook/channels" "7.6.20" + "@storybook/client-logger" "7.6.20" + "@storybook/core-events" "7.6.20" + "@storybook/csf" "^0.1.2" + "@storybook/global" "^5.0.0" + "@storybook/types" "7.6.20" + "@types/qs" "^6.9.5" + dequal "^2.0.2" + lodash "^4.17.21" + memoizerific "^1.11.3" + qs "^6.10.0" + synchronous-promise "^2.0.15" + ts-dedent "^2.0.0" + util-deprecate "^1.0.2" + +"@storybook/preview-web@7.6.20": + version "7.6.20" + resolved "https://registry.yarnpkg.com/@storybook/preview-web/-/preview-web-7.6.20.tgz#413a291db5c292b750a42f8dd3018f8e74e1066c" + integrity sha512-Gvac4q3Fq2w9C7r88e3hKl+97vZfokHlmogeOfr86+6PCF9mK9qN+xhbf0DpifS/ArQdEjhNbcnvJS4zeJ9OeA== + dependencies: + "@storybook/client-logger" "7.6.20" + "@storybook/preview-api" "7.6.20" + +"@storybook/preview@7.6.20": + version "7.6.20" + resolved "https://registry.yarnpkg.com/@storybook/preview/-/preview-7.6.20.tgz#df39739dce6e183efaf06a8c15a9459f019e631b" + integrity sha512-cxYlZ5uKbCYMHoFpgleZqqGWEnqHrk5m5fT8bYSsDsdQ+X5wPcwI/V+v8dxYAdQcMphZVIlTjo6Dno9WG8qmVA== + +"@storybook/react-dom-shim@7.6.20": + version "7.6.20" + resolved "https://registry.yarnpkg.com/@storybook/react-dom-shim/-/react-dom-shim-7.6.20.tgz#20b902663474b731c22b211ec29c7fd0e86b4b7f" + integrity sha512-SRvPDr9VWcS24ByQOVmbfZ655y5LvjXRlsF1I6Pr9YZybLfYbu3L5IicfEHT4A8lMdghzgbPFVQaJez46DTrkg== + +"@storybook/router@7.6.20": + version "7.6.20" + resolved "https://registry.yarnpkg.com/@storybook/router/-/router-7.6.20.tgz#ffa6a3ba1790e86f1d2364c27d3511f7975742a6" + integrity sha512-mCzsWe6GrH47Xb1++foL98Zdek7uM5GhaSlrI7blWVohGa0qIUYbfJngqR4ZsrXmJeeEvqowobh+jlxg3IJh+w== + dependencies: + "@storybook/client-logger" "7.6.20" + memoizerific "^1.11.3" + qs "^6.10.0" + +"@storybook/telemetry@7.6.20": + version "7.6.20" + resolved "https://registry.yarnpkg.com/@storybook/telemetry/-/telemetry-7.6.20.tgz#5b3705eb5100b21070d76767dde1040ed5d9b35b" + integrity sha512-dmAOCWmOscYN6aMbhCMmszQjoycg7tUPRVy2kTaWg6qX10wtMrvEtBV29W4eMvqdsoRj5kcvoNbzRdYcWBUOHQ== + dependencies: + "@storybook/client-logger" "7.6.20" + "@storybook/core-common" "7.6.20" + "@storybook/csf-tools" "7.6.20" + chalk "^4.1.0" + detect-package-manager "^2.0.1" + fetch-retry "^5.0.2" + fs-extra "^11.1.0" + read-pkg-up "^7.0.1" + +"@storybook/testing-library@^0.2.0": + version "0.2.2" + resolved "https://registry.yarnpkg.com/@storybook/testing-library/-/testing-library-0.2.2.tgz#c8e089cc8d7354f6066fdb580fae3eedf568aa7c" + integrity sha512-L8sXFJUHmrlyU2BsWWZGuAjv39Jl1uAqUHdxmN42JY15M4+XCMjGlArdCCjDe1wpTSW6USYISA9axjZojgtvnw== + dependencies: + "@testing-library/dom" "^9.0.0" + "@testing-library/user-event" "^14.4.0" + ts-dedent "^2.2.0" + +"@storybook/theming@7.6.20": + version "7.6.20" + resolved "https://registry.yarnpkg.com/@storybook/theming/-/theming-7.6.20.tgz#c932cd82c27314979d22d0e7867268e301f5f97c" + integrity sha512-iT1pXHkSkd35JsCte6Qbanmprx5flkqtSHC6Gi6Umqoxlg9IjiLPmpHbaIXzoC06DSW93hPj5Zbi1lPlTvRC7Q== + dependencies: + "@emotion/use-insertion-effect-with-fallbacks" "^1.0.0" + "@storybook/client-logger" "7.6.20" + "@storybook/global" "^5.0.0" + memoizerific "^1.11.3" + +"@storybook/types@7.6.20": + version "7.6.20" + resolved "https://registry.yarnpkg.com/@storybook/types/-/types-7.6.20.tgz#b8d62b30914b35e6750b1f4937da532432f02890" + integrity sha512-GncdY3x0LpbhmUAAJwXYtJDUQEwfF175gsjH0/fxPkxPoV7Sef9TM41jQLJW/5+6TnZoCZP/+aJZTJtq3ni23Q== + dependencies: + "@storybook/channels" "7.6.20" + "@types/babel__core" "^7.0.0" + "@types/express" "^4.7.0" + file-system-cache "2.3.0" + +"@testing-library/dom@^9.0.0": + version "9.3.4" + resolved "https://registry.yarnpkg.com/@testing-library/dom/-/dom-9.3.4.tgz#50696ec28376926fec0a1bf87d9dbac5e27f60ce" + integrity sha512-FlS4ZWlp97iiNWig0Muq8p+3rVDjRiYE+YKGbAqXOu9nwJFFOdL00kFpz42M+4huzYi86vAK1sOOfyOG45muIQ== + dependencies: + "@babel/code-frame" "^7.10.4" + "@babel/runtime" "^7.12.5" + "@types/aria-query" "^5.0.1" + aria-query "5.1.3" + chalk "^4.1.0" + dom-accessibility-api "^0.5.9" + lz-string "^1.5.0" + pretty-format "^27.0.2" + +"@testing-library/user-event@^14.4.0": + version "14.5.2" + resolved "https://registry.yarnpkg.com/@testing-library/user-event/-/user-event-14.5.2.tgz#db7257d727c891905947bd1c1a99da20e03c2ebd" + integrity sha512-YAh82Wh4TIrxYLmfGcixwD18oIjyC1pFQC2Y01F2lzV2HTMiYrI0nze0FD0ocB//CKS/7jIUgae+adPqxK5yCQ== + +"@types/aria-query@^5.0.1": + version "5.0.4" + resolved "https://registry.yarnpkg.com/@types/aria-query/-/aria-query-5.0.4.tgz#1a31c3d378850d2778dabb6374d036dcba4ba708" + integrity sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw== + +"@types/babel__core@^7.0.0": + version "7.20.5" + resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.20.5.tgz#3df15f27ba85319caa07ba08d0721889bb39c017" + integrity sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA== + dependencies: + "@babel/parser" "^7.20.7" + "@babel/types" "^7.20.7" + "@types/babel__generator" "*" + "@types/babel__template" "*" + "@types/babel__traverse" "*" + +"@types/babel__generator@*": + version "7.6.8" + resolved "https://registry.yarnpkg.com/@types/babel__generator/-/babel__generator-7.6.8.tgz#f836c61f48b1346e7d2b0d93c6dacc5b9535d3ab" + integrity sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw== + dependencies: + "@babel/types" "^7.0.0" + +"@types/babel__template@*": + version "7.4.4" + resolved "https://registry.yarnpkg.com/@types/babel__template/-/babel__template-7.4.4.tgz#5672513701c1b2199bc6dad636a9d7491586766f" + integrity sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A== + dependencies: + "@babel/parser" "^7.1.0" + "@babel/types" "^7.0.0" + +"@types/babel__traverse@*": + version "7.20.6" + resolved "https://registry.yarnpkg.com/@types/babel__traverse/-/babel__traverse-7.20.6.tgz#8dc9f0ae0f202c08d8d4dab648912c8d6038e3f7" + integrity sha512-r1bzfrm0tomOI8g1SzvCaQHo6Lcv6zu0EA+W2kHrt8dyrHQxGzBBL4kdkzIS+jBMV+EYcMAEAqXqYaLJq5rOZg== + dependencies: + "@babel/types" "^7.20.7" + +"@types/body-parser@*": + version "1.19.5" + resolved "https://registry.yarnpkg.com/@types/body-parser/-/body-parser-1.19.5.tgz#04ce9a3b677dc8bd681a17da1ab9835dc9d3ede4" + integrity sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg== + dependencies: + "@types/connect" "*" + "@types/node" "*" + +"@types/connect@*": + version "3.4.38" + resolved "https://registry.yarnpkg.com/@types/connect/-/connect-3.4.38.tgz#5ba7f3bc4fbbdeaff8dded952e5ff2cc53f8d858" + integrity sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug== + dependencies: + "@types/node" "*" + +"@types/cross-spawn@^6.0.2": + version "6.0.6" + resolved "https://registry.yarnpkg.com/@types/cross-spawn/-/cross-spawn-6.0.6.tgz#0163d0b79a6f85409e0decb8dcca17147f81fd22" + integrity sha512-fXRhhUkG4H3TQk5dBhQ7m/JDdSNHKwR2BBia62lhwEIq9xGiQKLxd6LymNhn47SjXhsUEPmxi+PKw2OkW4LLjA== + dependencies: + "@types/node" "*" + +"@types/detect-port@^1.3.0": + version "1.3.5" + resolved "https://registry.yarnpkg.com/@types/detect-port/-/detect-port-1.3.5.tgz#deecde143245989dee0e82115f3caba5ee0ea747" + integrity sha512-Rf3/lB9WkDfIL9eEKaSYKc+1L/rNVYBjThk22JTqQw0YozXarX8YljFAz+HCoC6h4B4KwCMsBPZHaFezwT4BNA== + +"@types/doctrine@^0.0.3": + version "0.0.3" + resolved "https://registry.yarnpkg.com/@types/doctrine/-/doctrine-0.0.3.tgz#e892d293c92c9c1d3f9af72c15a554fbc7e0895a" + integrity sha512-w5jZ0ee+HaPOaX25X2/2oGR/7rgAQSYII7X7pp0m9KgBfMP7uKfMfTvcpl5Dj+eDBbpxKGiqE+flqDr6XTd2RA== + +"@types/ejs@^3.1.1": + version "3.1.5" + resolved "https://registry.yarnpkg.com/@types/ejs/-/ejs-3.1.5.tgz#49d738257cc73bafe45c13cb8ff240683b4d5117" + integrity sha512-nv+GSx77ZtXiJzwKdsASqi+YQ5Z7vwHsTP0JY2SiQgjGckkBRKZnk8nIM+7oUZ1VCtuTz0+By4qVR7fqzp/Dfg== + +"@types/emscripten@^1.39.6": + version "1.39.13" + resolved "https://registry.yarnpkg.com/@types/emscripten/-/emscripten-1.39.13.tgz#afeb1648648dc096efe57983e20387627306e2aa" + integrity sha512-cFq+fO/isvhvmuP/+Sl4K4jtU6E23DoivtbO4r50e3odaxAiVdbfSYRDdJ4gCdxx+3aRjhphS5ZMwIH4hFy/Cw== + +"@types/express-serve-static-core@^4.17.33": + version "4.19.6" + resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.19.6.tgz#e01324c2a024ff367d92c66f48553ced0ab50267" + integrity sha512-N4LZ2xG7DatVqhCZzOGb1Yi5lMbXSZcmdLDe9EzSndPV2HpWYWzRbaerl2n27irrm94EPpprqa8KpskPT085+A== + dependencies: + "@types/node" "*" + "@types/qs" "*" + "@types/range-parser" "*" + "@types/send" "*" + +"@types/express@^4.7.0": + version "4.17.21" + resolved "https://registry.yarnpkg.com/@types/express/-/express-4.17.21.tgz#c26d4a151e60efe0084b23dc3369ebc631ed192d" + integrity sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ== + dependencies: + "@types/body-parser" "*" + "@types/express-serve-static-core" "^4.17.33" + "@types/qs" "*" + "@types/serve-static" "*" + +"@types/find-cache-dir@^3.2.1": + version "3.2.1" + resolved "https://registry.yarnpkg.com/@types/find-cache-dir/-/find-cache-dir-3.2.1.tgz#7b959a4b9643a1e6a1a5fe49032693cc36773501" + integrity sha512-frsJrz2t/CeGifcu/6uRo4b+SzAwT4NYCVPu1GN8IB9XTzrpPkGuV0tmh9mN+/L0PklAlsC3u5Fxt0ju00LXIw== + +"@types/graceful-fs@^4.1.3": + version "4.1.9" + resolved "https://registry.yarnpkg.com/@types/graceful-fs/-/graceful-fs-4.1.9.tgz#2a06bc0f68a20ab37b3e36aa238be6abdf49e8b4" + integrity sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ== + dependencies: + "@types/node" "*" + +"@types/http-errors@*": + version "2.0.4" + resolved "https://registry.yarnpkg.com/@types/http-errors/-/http-errors-2.0.4.tgz#7eb47726c391b7345a6ec35ad7f4de469cf5ba4f" + integrity sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA== + +"@types/istanbul-lib-coverage@*", "@types/istanbul-lib-coverage@^2.0.0": + version "2.0.6" + resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz#7739c232a1fee9b4d3ce8985f314c0c6d33549d7" + integrity sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w== + +"@types/istanbul-lib-report@*": + version "3.0.3" + resolved "https://registry.yarnpkg.com/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz#53047614ae72e19fc0401d872de3ae2b4ce350bf" + integrity sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA== + dependencies: + "@types/istanbul-lib-coverage" "*" + +"@types/istanbul-reports@^3.0.0": + version "3.0.4" + resolved "https://registry.yarnpkg.com/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz#0f03e3d2f670fbdac586e34b433783070cc16f54" + integrity sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ== + dependencies: + "@types/istanbul-lib-report" "*" + +"@types/lodash@^4.14.167": + version "4.17.13" + resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.17.13.tgz#786e2d67cfd95e32862143abe7463a7f90c300eb" + integrity sha512-lfx+dftrEZcdBPczf9d0Qv0x+j/rfNCMuC6OcfXmO8gkfeNAY88PgKUbvG56whcN23gc27yenwF6oJZXGFpYxg== + +"@types/mdx@^2.0.0": + version "2.0.13" + resolved "https://registry.yarnpkg.com/@types/mdx/-/mdx-2.0.13.tgz#68f6877043d377092890ff5b298152b0a21671bd" + integrity sha512-+OWZQfAYyio6YkJb3HLxDrvnx6SWWDbC0zVPfBRzUk0/nqoDyf6dNxQi3eArPe8rJ473nobTMQ/8Zk+LxJ+Yuw== + +"@types/mime-types@^2.1.0": + version "2.1.4" + resolved "https://registry.yarnpkg.com/@types/mime-types/-/mime-types-2.1.4.tgz#93a1933e24fed4fb9e4adc5963a63efcbb3317a2" + integrity sha512-lfU4b34HOri+kAY5UheuFMWPDOI+OPceBSHZKp69gEyTL/mmJ4cnU6Y/rlme3UL3GyOn6Y42hyIEw0/q8sWx5w== + +"@types/mime@^1": + version "1.3.5" + resolved "https://registry.yarnpkg.com/@types/mime/-/mime-1.3.5.tgz#1ef302e01cf7d2b5a0fa526790c9123bf1d06690" + integrity sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w== + +"@types/node-fetch@^2.6.4": + version "2.6.12" + resolved "https://registry.yarnpkg.com/@types/node-fetch/-/node-fetch-2.6.12.tgz#8ab5c3ef8330f13100a7479e2cd56d3386830a03" + integrity sha512-8nneRWKCg3rMtF69nLQJnOYUcbafYeFSjqkw3jCRLsqkWFlHaoQrr5mXmofFGOx3DKn7UfmBMyov8ySvLRVldA== + dependencies: + "@types/node" "*" + form-data "^4.0.0" + +"@types/node@*": + version "22.9.0" + resolved "https://registry.yarnpkg.com/@types/node/-/node-22.9.0.tgz#b7f16e5c3384788542c72dc3d561a7ceae2c0365" + integrity sha512-vuyHg81vvWA1Z1ELfvLko2c8f34gyA0zaic0+Rllc5lbCnbSyuvb2Oxpm6TAUAC/2xZN3QGqxBNggD1nNR2AfQ== + dependencies: + undici-types "~6.19.8" + +"@types/node@^18.0.0": + version "18.19.64" + resolved "https://registry.yarnpkg.com/@types/node/-/node-18.19.64.tgz#122897fb79f2a9ec9c979bded01c11461b2b1478" + integrity sha512-955mDqvO2vFf/oL7V3WiUtiz+BugyX8uVbaT2H8oj3+8dRyH2FLiNdowe7eNqRM7IOIZvzDH76EoAT+gwm6aIQ== + dependencies: + undici-types "~5.26.4" + +"@types/normalize-package-data@^2.4.0": + version "2.4.4" + resolved "https://registry.yarnpkg.com/@types/normalize-package-data/-/normalize-package-data-2.4.4.tgz#56e2cc26c397c038fab0e3a917a12d5c5909e901" + integrity sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA== + +"@types/pretty-hrtime@^1.0.0": + version "1.0.3" + resolved "https://registry.yarnpkg.com/@types/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz#ee1bd8c9f7a01b3445786aad0ef23aba5f511a44" + integrity sha512-nj39q0wAIdhwn7DGUyT9irmsKK1tV0bd5WFEhgpqNTMFZ8cE+jieuTphCW0tfdm47S2zVT5mr09B28b1chmQMA== + +"@types/prop-types@*": + version "15.7.13" + resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.13.tgz#2af91918ee12d9d32914feb13f5326658461b451" + integrity sha512-hCZTSvwbzWGvhqxp/RqVqwU999pBf2vp7hzIjiYOsl8wqOmUxkQ6ddw1cV3l8811+kdUFus/q4d1Y3E3SyEifA== + +"@types/qs@*", "@types/qs@^6.9.5": + version "6.9.17" + resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.17.tgz#fc560f60946d0aeff2f914eb41679659d3310e1a" + integrity sha512-rX4/bPcfmvxHDv0XjfJELTTr+iB+tn032nPILqHm5wbthUUUuVtNGGqzhya9XUxjTP8Fpr0qYgSZZKxGY++svQ== + +"@types/range-parser@*": + version "1.2.7" + resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.7.tgz#50ae4353eaaddc04044279812f52c8c65857dbcb" + integrity sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ== + +"@types/react@>=16": + version "18.3.12" + resolved "https://registry.yarnpkg.com/@types/react/-/react-18.3.12.tgz#99419f182ccd69151813b7ee24b792fe08774f60" + integrity sha512-D2wOSq/d6Agt28q7rSI3jhU7G6aiuzljDGZ2hTZHIkrTLUI+AF3WMeKkEZ9nN2fkBAlcktT6vcZjDFiIhMYEQw== + dependencies: + "@types/prop-types" "*" + csstype "^3.0.2" + +"@types/semver@^7.3.4": + version "7.5.8" + resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.5.8.tgz#8268a8c57a3e4abd25c165ecd36237db7948a55e" + integrity sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ== + +"@types/send@*": + version "0.17.4" + resolved "https://registry.yarnpkg.com/@types/send/-/send-0.17.4.tgz#6619cd24e7270793702e4e6a4b958a9010cfc57a" + integrity sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA== + dependencies: + "@types/mime" "^1" + "@types/node" "*" + +"@types/serve-static@*": + version "1.15.7" + resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.15.7.tgz#22174bbd74fb97fe303109738e9b5c2f3064f714" + integrity sha512-W8Ym+h8nhuRwaKPaDw34QUkwsGi6Rc4yYqvKFo5rm2FUEhCFbzVWrxXUxuKK8TASjWsysJY0nsmNCGhCOIsrOw== + dependencies: + "@types/http-errors" "*" + "@types/node" "*" + "@types/send" "*" + +"@types/unist@^2.0.0": + version "2.0.11" + resolved "https://registry.yarnpkg.com/@types/unist/-/unist-2.0.11.tgz#11af57b127e32487774841f7a4e54eab166d03c4" + integrity sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA== + +"@types/uuid@^9.0.1": + version "9.0.8" + resolved "https://registry.yarnpkg.com/@types/uuid/-/uuid-9.0.8.tgz#7545ba4fc3c003d6c756f651f3bf163d8f0f29ba" + integrity sha512-jg+97EGIcY9AGHJJRaaPVgetKDsrTgbRjQ5Msgjh/DQKEFl0DtyRr/VCOyD1T2R1MNeWPK/u7JoGhlDZnKBAfA== + +"@types/yargs-parser@*": + version "21.0.3" + resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-21.0.3.tgz#815e30b786d2e8f0dcd85fd5bcf5e1a04d008f15" + integrity sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ== + +"@types/yargs@^16.0.0": + version "16.0.9" + resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-16.0.9.tgz#ba506215e45f7707e6cbcaf386981155b7ab956e" + integrity sha512-tHhzvkFXZQeTECenFoRljLBYPZJ7jAVxqqtEI0qTLOmuultnFp4I9yKE17vTuhf7BkhCu7I4XuemPgikDVuYqA== + dependencies: + "@types/yargs-parser" "*" + +"@types/yargs@^17.0.8": + version "17.0.33" + resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-17.0.33.tgz#8c32303da83eec050a84b3c7ae7b9f922d13e32d" + integrity sha512-WpxBCKWPLr4xSsHgz511rFJAM+wS28w2zEO1QDNY5zM/S8ok70NNfztH0xwhqKyaK0OHCbN98LDAZuy1ctxDkA== + dependencies: + "@types/yargs-parser" "*" + +"@yarnpkg/esbuild-plugin-pnp@^3.0.0-rc.10": + version "3.0.0-rc.15" + resolved "https://registry.yarnpkg.com/@yarnpkg/esbuild-plugin-pnp/-/esbuild-plugin-pnp-3.0.0-rc.15.tgz#4e40e7d2eb28825c9a35ab9d04c363931d7c0e67" + integrity sha512-kYzDJO5CA9sy+on/s2aIW0411AklfCi8Ck/4QDivOqsMKpStZA2SsR+X27VTggGwpStWaLrjJcDcdDMowtG8MA== + dependencies: + tslib "^2.4.0" + +"@yarnpkg/fslib@2.10.3": + version "2.10.3" + resolved "https://registry.yarnpkg.com/@yarnpkg/fslib/-/fslib-2.10.3.tgz#a8c9893df5d183cf6362680b9f1c6d7504dd5717" + integrity sha512-41H+Ga78xT9sHvWLlFOZLIhtU6mTGZ20pZ29EiZa97vnxdohJD2AF42rCoAoWfqUz486xY6fhjMH+DYEM9r14A== + dependencies: + "@yarnpkg/libzip" "^2.3.0" + tslib "^1.13.0" + +"@yarnpkg/libzip@2.3.0", "@yarnpkg/libzip@^2.3.0": + version "2.3.0" + resolved "https://registry.yarnpkg.com/@yarnpkg/libzip/-/libzip-2.3.0.tgz#fe1e762e47669f6e2c960fc118436608d834e3be" + integrity sha512-6xm38yGVIa6mKm/DUCF2zFFJhERh/QWp1ufm4cNUvxsONBmfPg8uZ9pZBdOmF6qFGr/HlT6ABBkCSx/dlEtvWg== + dependencies: + "@types/emscripten" "^1.39.6" + tslib "^1.13.0" + +accepts@~1.3.8: + version "1.3.8" + resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.8.tgz#0bf0be125b67014adcb0b0921e62db7bffe16b2e" + integrity sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw== + dependencies: + mime-types "~2.1.34" + negotiator "0.6.3" + +acorn@^8.14.0: + version "8.14.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.14.0.tgz#063e2c70cac5fb4f6467f0b11152e04c682795b0" + integrity sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA== + +address@^1.0.1: + version "1.2.2" + resolved "https://registry.yarnpkg.com/address/-/address-1.2.2.tgz#2b5248dac5485a6390532c6a517fda2e3faac89e" + integrity sha512-4B/qKCfeE/ODUaAUpSwfzazo5x29WD4r3vXiWsB7I2mSDAihwEqKO+g8GELZUQSSAo5e1XTYh3ZVfLyxBc12nA== + +agent-base@5: + version "5.1.1" + resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-5.1.1.tgz#e8fb3f242959db44d63be665db7a8e739537a32c" + integrity sha512-TMeqbNl2fMW0nMjTEPOwe3J/PRFP4vqeoNuQMG0HlMrtm5QxKqdvAkZ1pRBQ/ulIyDD5Yq0nJ7YbdD8ey0TO3g== + +aggregate-error@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/aggregate-error/-/aggregate-error-3.1.0.tgz#92670ff50f5359bdb7a3e0d40d0ec30c5737687a" + integrity sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA== + dependencies: + clean-stack "^2.0.0" + indent-string "^4.0.0" + +ansi-regex@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" + integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== + +ansi-regex@^6.0.1: + version "6.1.0" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-6.1.0.tgz#95ec409c69619d6cb1b8b34f14b660ef28ebd654" + integrity sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA== + +ansi-styles@^4.0.0, ansi-styles@^4.1.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" + integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== + dependencies: + color-convert "^2.0.1" + +ansi-styles@^5.0.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-5.2.0.tgz#07449690ad45777d1924ac2abb2fc8895dba836b" + integrity sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA== + +ansi-styles@^6.1.0: + version "6.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-6.2.1.tgz#0e62320cf99c21afff3b3012192546aacbfb05c5" + integrity sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug== + +anymatch@^3.0.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.3.tgz#790c58b19ba1720a84205b57c618d5ad8524973e" + integrity sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw== + dependencies: + normalize-path "^3.0.0" + picomatch "^2.0.4" + +app-root-dir@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/app-root-dir/-/app-root-dir-1.0.2.tgz#38187ec2dea7577fff033ffcb12172692ff6e118" + integrity sha512-jlpIfsOoNoafl92Sz//64uQHGSyMrD2vYG5d8o2a4qGvyNCvXur7bzIsWtAC/6flI2RYAp3kv8rsfBtaLm7w0g== + +argparse@^1.0.7: + version "1.0.10" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" + integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== + dependencies: + sprintf-js "~1.0.2" + +aria-hidden@^1.1.1: + version "1.2.4" + resolved "https://registry.yarnpkg.com/aria-hidden/-/aria-hidden-1.2.4.tgz#b78e383fdbc04d05762c78b4a25a501e736c4522" + integrity sha512-y+CcFFwelSXpLZk/7fMB2mUbGtX9lKycf1MWJ7CaTIERyitVlyQx6C+sxcROU2BAJ24OiZyK+8wj2i8AlBoS3A== + dependencies: + tslib "^2.0.0" + +aria-query@5.1.3: + version "5.1.3" + resolved "https://registry.yarnpkg.com/aria-query/-/aria-query-5.1.3.tgz#19db27cd101152773631396f7a95a3b58c22c35e" + integrity sha512-R5iJ5lkuHybztUfuOAznmboyjWq8O6sqNqtK7CLOqdydi54VNbORp49mb14KbWgG1QD3JFO9hJdZ+y4KutfdOQ== + dependencies: + deep-equal "^2.0.5" + +array-buffer-byte-length@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/array-buffer-byte-length/-/array-buffer-byte-length-1.0.1.tgz#1e5583ec16763540a27ae52eed99ff899223568f" + integrity sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg== + dependencies: + call-bind "^1.0.5" + is-array-buffer "^3.0.4" + +array-flatten@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" + integrity sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg== + +array-union@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" + integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== + +assert@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/assert/-/assert-2.1.0.tgz#6d92a238d05dc02e7427c881fb8be81c8448b2dd" + integrity sha512-eLHpSK/Y4nhMJ07gDaAzoX/XAKS8PSaojml3M0DM4JpV1LAi5JOJ/p6H/XWrl8L+DzVEvVCW1z3vWAaB9oTsQw== + dependencies: + call-bind "^1.0.2" + is-nan "^1.3.2" + object-is "^1.1.5" + object.assign "^4.1.4" + util "^0.12.5" + +ast-types@^0.16.1: + version "0.16.1" + resolved "https://registry.yarnpkg.com/ast-types/-/ast-types-0.16.1.tgz#7a9da1617c9081bc121faafe91711b4c8bb81da2" + integrity sha512-6t10qk83GOG8p0vKmaCr8eiilZwO171AvbROMtvvNiwrTly62t+7XkA8RdIIVbpMhCASAsxgAzdRSwh6nw/5Dg== + dependencies: + tslib "^2.0.1" + +async-limiter@~1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.1.tgz#dd379e94f0db8310b08291f9d64c3209766617fd" + integrity sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ== + +async@^3.2.3: + version "3.2.6" + resolved "https://registry.yarnpkg.com/async/-/async-3.2.6.tgz#1b0728e14929d51b85b449b7f06e27c1145e38ce" + integrity sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA== + +asynckit@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" + integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q== + +available-typed-arrays@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz#a5cc375d6a03c2efc87a553f3e0b1522def14846" + integrity sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ== + dependencies: + possible-typed-array-names "^1.0.0" + +babel-core@^7.0.0-bridge.0: + version "7.0.0-bridge.0" + resolved "https://registry.yarnpkg.com/babel-core/-/babel-core-7.0.0-bridge.0.tgz#95a492ddd90f9b4e9a4a1da14eb335b87b634ece" + integrity sha512-poPX9mZH/5CSanm50Q+1toVci6pv5KSRv/5TWCwtzQS5XEwn40BcCrgIeMFWP9CKKIniKXNxoIOnOq4VVlGXhg== + +babel-plugin-istanbul@^6.1.1: + version "6.1.1" + resolved "https://registry.yarnpkg.com/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz#fa88ec59232fd9b4e36dbbc540a8ec9a9b47da73" + integrity sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@istanbuljs/load-nyc-config" "^1.0.0" + "@istanbuljs/schema" "^0.1.2" + istanbul-lib-instrument "^5.0.4" + test-exclude "^6.0.0" + +babel-plugin-polyfill-corejs2@^0.4.10: + version "0.4.12" + resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.12.tgz#ca55bbec8ab0edeeef3d7b8ffd75322e210879a9" + integrity sha512-CPWT6BwvhrTO2d8QVorhTCQw9Y43zOu7G9HigcfxvepOU6b8o3tcWad6oVgZIsZCTt42FFv97aA7ZJsbM4+8og== + dependencies: + "@babel/compat-data" "^7.22.6" + "@babel/helper-define-polyfill-provider" "^0.6.3" + semver "^6.3.1" + +babel-plugin-polyfill-corejs3@^0.10.6: + version "0.10.6" + resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.10.6.tgz#2deda57caef50f59c525aeb4964d3b2f867710c7" + integrity sha512-b37+KR2i/khY5sKmWNVQAnitvquQbNdWy6lJdsr0kmquCKEEUgMKK4SboVM3HtfnZilfjr4MMQ7vY58FVWDtIA== + dependencies: + "@babel/helper-define-polyfill-provider" "^0.6.2" + core-js-compat "^3.38.0" + +babel-plugin-polyfill-regenerator@^0.6.1: + version "0.6.3" + resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.3.tgz#abeb1f3f1c762eace37587f42548b08b57789bc8" + integrity sha512-LiWSbl4CRSIa5x/JAU6jZiG9eit9w6mz+yVMFwDE83LAWvt0AfGBoZ7HS/mkhrKuh2ZlzfVZYKoLjXdqw6Yt7Q== + dependencies: + "@babel/helper-define-polyfill-provider" "^0.6.3" + +balanced-match@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" + integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== + +base64-js@^1.3.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" + integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== + +better-opn@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/better-opn/-/better-opn-3.0.2.tgz#f96f35deaaf8f34144a4102651babcf00d1d8817" + integrity sha512-aVNobHnJqLiUelTaHat9DZ1qM2w0C0Eym4LPI/3JxOnSokGVdsl1T1kN7TFvsEAD8G47A6VKQ0TVHqbBnYMJlQ== + dependencies: + open "^8.0.4" + +big-integer@^1.6.44: + version "1.6.52" + resolved "https://registry.yarnpkg.com/big-integer/-/big-integer-1.6.52.tgz#60a887f3047614a8e1bffe5d7173490a97dc8c85" + integrity sha512-QxD8cf2eVqJOOz63z6JIN9BzvVs/dlySa5HGSBH5xtR8dPteIRQnBxxKqkNTiT6jbDTF6jAfrd4oMcND9RGbQg== + +bl@^4.0.3, bl@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/bl/-/bl-4.1.0.tgz#451535264182bec2fbbc83a62ab98cf11d9f7b3a" + integrity sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w== + dependencies: + buffer "^5.5.0" + inherits "^2.0.4" + readable-stream "^3.4.0" + +body-parser@1.20.3: + version "1.20.3" + resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.3.tgz#1953431221c6fb5cd63c4b36d53fab0928e548c6" + integrity sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g== + dependencies: + bytes "3.1.2" + content-type "~1.0.5" + debug "2.6.9" + depd "2.0.0" + destroy "1.2.0" + http-errors "2.0.0" + iconv-lite "0.4.24" + on-finished "2.4.1" + qs "6.13.0" + raw-body "2.5.2" + type-is "~1.6.18" + unpipe "1.0.0" + +bplist-parser@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/bplist-parser/-/bplist-parser-0.2.0.tgz#43a9d183e5bf9d545200ceac3e712f79ebbe8d0e" + integrity sha512-z0M+byMThzQmD9NILRniCUXYsYpjwnlO8N5uCFaCqIOpqRsJCrQL9NK3JsD67CN5a08nF5oIL2bD6loTdHOuKw== + dependencies: + big-integer "^1.6.44" + +brace-expansion@^1.1.7: + version "1.1.11" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" + integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + +brace-expansion@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.0.1.tgz#1edc459e0f0c548486ecf9fc99f2221364b9a0ae" + integrity sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA== + dependencies: + balanced-match "^1.0.0" + +braces@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.3.tgz#490332f40919452272d55a8480adc0c441358789" + integrity sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA== + dependencies: + fill-range "^7.1.1" + +browser-assert@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/browser-assert/-/browser-assert-1.2.1.tgz#9aaa5a2a8c74685c2ae05bfe46efd606f068c200" + integrity sha512-nfulgvOR6S4gt9UKCeGJOuSGBPGiFT6oQ/2UBnvTY/5aQ1PnksW72fhZkM30DzoRRv2WpwZf1vHHEr3mtuXIWQ== + +browserify-zlib@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/browserify-zlib/-/browserify-zlib-0.1.4.tgz#bb35f8a519f600e0fa6b8485241c979d0141fb2d" + integrity sha512-19OEpq7vWgsH6WkvkBJQDFvJS1uPcbFOQ4v9CU839dO+ZZXUZO6XpE6hNCqvlIIj+4fZvRiJ6DsAQ382GwiyTQ== + dependencies: + pako "~0.2.0" + +browserslist@^4.24.0, browserslist@^4.24.2: + version "4.24.2" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.24.2.tgz#f5845bc91069dbd55ee89faf9822e1d885d16580" + integrity sha512-ZIc+Q62revdMcqC6aChtW4jz3My3klmCO1fEmINZY/8J3EpBg5/A/D0AKmBveUh6pgoeycoMkVMko84tuYS+Gg== + dependencies: + caniuse-lite "^1.0.30001669" + electron-to-chromium "^1.5.41" + node-releases "^2.0.18" + update-browserslist-db "^1.1.1" + +bser@2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/bser/-/bser-2.1.1.tgz#e6787da20ece9d07998533cfd9de6f5c38f4bc05" + integrity sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ== + dependencies: + node-int64 "^0.4.0" + +buffer-crc32@~0.2.3: + version "0.2.13" + resolved "https://registry.yarnpkg.com/buffer-crc32/-/buffer-crc32-0.2.13.tgz#0d333e3f00eac50aa1454abd30ef8c2a5d9a7242" + integrity sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ== + +buffer-from@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" + integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== + +buffer@^5.5.0: + version "5.7.1" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.7.1.tgz#ba62e7c13133053582197160851a8f648e99eed0" + integrity sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ== + dependencies: + base64-js "^1.3.1" + ieee754 "^1.1.13" + +bytes@3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.2.tgz#8b0beeb98605adf1b128fa4386403c009e0221a5" + integrity sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg== + +call-bind@^1.0.0, call-bind@^1.0.2, call-bind@^1.0.5, call-bind@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.7.tgz#06016599c40c56498c18769d2730be242b6fa3b9" + integrity sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w== + dependencies: + es-define-property "^1.0.0" + es-errors "^1.3.0" + function-bind "^1.1.2" + get-intrinsic "^1.2.4" + set-function-length "^1.2.1" + +camelcase@^5.3.1: + version "5.3.1" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" + integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== + +caniuse-lite@^1.0.30001669: + version "1.0.30001680" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001680.tgz#5380ede637a33b9f9f1fc6045ea99bd142f3da5e" + integrity sha512-rPQy70G6AGUMnbwS1z6Xg+RkHYPAi18ihs47GH0jcxIG7wArmPgY3XbS2sRdBbxJljp3thdT8BIqv9ccCypiPA== + +chalk@^4.0.0, chalk@^4.0.2, chalk@^4.1.0, chalk@^4.1.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" + integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== + dependencies: + ansi-styles "^4.1.0" + supports-color "^7.1.0" + +chownr@^1.1.1: + version "1.1.4" + resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.4.tgz#6fc9d7b42d32a583596337666e7d08084da2cc6b" + integrity sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg== + +chownr@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/chownr/-/chownr-2.0.0.tgz#15bfbe53d2eab4cf70f18a8cd68ebe5b3cb1dece" + integrity sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ== + +ci-info@^3.2.0: + version "3.9.0" + resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-3.9.0.tgz#4279a62028a7b1f262f3473fc9605f5e218c59b4" + integrity sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ== + +citty@^0.1.6: + version "0.1.6" + resolved "https://registry.yarnpkg.com/citty/-/citty-0.1.6.tgz#0f7904da1ed4625e1a9ea7e0fa780981aab7c5e4" + integrity sha512-tskPPKEs8D2KPafUypv2gxwJP8h/OaJmC82QQGGDQcHvXX43xF2VDACcJVmZ0EuSxkpO9Kc4MlrA3q0+FG58AQ== + dependencies: + consola "^3.2.3" + +clean-stack@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/clean-stack/-/clean-stack-2.2.0.tgz#ee8472dbb129e727b31e8a10a427dee9dfe4008b" + integrity sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A== + +cli-cursor@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-3.1.0.tgz#264305a7ae490d1d03bf0c9ba7c925d1753af307" + integrity sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw== + dependencies: + restore-cursor "^3.1.0" + +cli-spinners@^2.5.0: + version "2.9.2" + resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-2.9.2.tgz#1773a8f4b9c4d6ac31563df53b3fc1d79462fe41" + integrity sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg== + +cli-table3@^0.6.1: + version "0.6.5" + resolved "https://registry.yarnpkg.com/cli-table3/-/cli-table3-0.6.5.tgz#013b91351762739c16a9567c21a04632e449bf2f" + integrity sha512-+W/5efTR7y5HRD7gACw9yQjqMVvEMLBHmboM/kPWam+H+Hmyrgjh6YncVKK122YZkXrLudzTuAukUw9FnMf7IQ== + dependencies: + string-width "^4.2.0" + optionalDependencies: + "@colors/colors" "1.5.0" + +clone-deep@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/clone-deep/-/clone-deep-4.0.1.tgz#c19fd9bdbbf85942b4fd979c84dcf7d5f07c2387" + integrity sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ== + dependencies: + is-plain-object "^2.0.4" + kind-of "^6.0.2" + shallow-clone "^3.0.0" + +clone@^1.0.2: + version "1.0.4" + resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.4.tgz#da309cc263df15994c688ca902179ca3c7cd7c7e" + integrity sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg== + +color-convert@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" + integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== + dependencies: + color-name "~1.1.4" + +color-name@~1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" + integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== + +combined-stream@^1.0.8: + version "1.0.8" + resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" + integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== + dependencies: + delayed-stream "~1.0.0" + +commander@^6.2.1: + version "6.2.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-6.2.1.tgz#0792eb682dfbc325999bb2b84fddddba110ac73c" + integrity sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA== + +commondir@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" + integrity sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg== + +compressible@~2.0.18: + version "2.0.18" + resolved "https://registry.yarnpkg.com/compressible/-/compressible-2.0.18.tgz#af53cca6b070d4c3c0750fbd77286a6d7cc46fba" + integrity sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg== + dependencies: + mime-db ">= 1.43.0 < 2" + +compression@^1.7.4: + version "1.7.5" + resolved "https://registry.yarnpkg.com/compression/-/compression-1.7.5.tgz#fdd256c0a642e39e314c478f6c2cd654edd74c93" + integrity sha512-bQJ0YRck5ak3LgtnpKkiabX5pNF7tMUh1BSy2ZBOTh0Dim0BUu6aPPwByIns6/A5Prh8PufSPerMDUklpzes2Q== + dependencies: + bytes "3.1.2" + compressible "~2.0.18" + debug "2.6.9" + negotiator "~0.6.4" + on-headers "~1.0.2" + safe-buffer "5.2.1" + vary "~1.1.2" + +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== + +concat-stream@^1.6.2: + version "1.6.2" + resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.2.tgz#904bdf194cd3122fc675c77fc4ac3d4ff0fd1a34" + integrity sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw== + dependencies: + buffer-from "^1.0.0" + inherits "^2.0.3" + readable-stream "^2.2.2" + typedarray "^0.0.6" + +confbox@^0.1.8: + version "0.1.8" + resolved "https://registry.yarnpkg.com/confbox/-/confbox-0.1.8.tgz#820d73d3b3c82d9bd910652c5d4d599ef8ff8b06" + integrity sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w== + +consola@^3.2.3: + version "3.2.3" + resolved "https://registry.yarnpkg.com/consola/-/consola-3.2.3.tgz#0741857aa88cfa0d6fd53f1cff0375136e98502f" + integrity sha512-I5qxpzLv+sJhTVEoLYNcTW+bThDCPsit0vLNKShZx6rLtpilNpmmeTPaeqJb9ZE9dV3DGaeby6Vuhrw38WjeyQ== + +content-disposition@0.5.4: + version "0.5.4" + resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.4.tgz#8b82b4efac82512a02bb0b1dcec9d2c5e8eb5bfe" + integrity sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ== + dependencies: + safe-buffer "5.2.1" + +content-type@~1.0.4, content-type@~1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.5.tgz#8b773162656d1d1086784c8f23a54ce6d73d7918" + integrity sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA== + +convert-source-map@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-2.0.0.tgz#4b560f649fc4e918dd0ab75cf4961e8bc882d82a" + integrity sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg== + +cookie-signature@1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" + integrity sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ== + +cookie@0.7.1: + version "0.7.1" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.7.1.tgz#2f73c42142d5d5cf71310a74fc4ae61670e5dbc9" + integrity sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w== + +core-js-compat@^3.38.0, core-js-compat@^3.38.1: + version "3.39.0" + resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.39.0.tgz#b12dccb495f2601dc860bdbe7b4e3ffa8ba63f61" + integrity sha512-VgEUx3VwlExr5no0tXlBt+silBvhTryPwCXRI2Id1PN8WTKu7MreethvddqOubrYxkFdv/RnYrqlv1sFNAUelw== + dependencies: + browserslist "^4.24.2" + +core-util-is@~1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85" + integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ== + +cross-spawn@^7.0.0, cross-spawn@^7.0.3: + version "7.0.5" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.5.tgz#910aac880ff5243da96b728bc6521a5f6c2f2f82" + integrity sha512-ZVJrKKYunU38/76t0RMOulHOnUcbU9GbpWKAOZ0mhjr7CX6FVrH+4FrAapSOekrgFQ3f/8gwMEuIft0aKq6Hug== + dependencies: + path-key "^3.1.0" + shebang-command "^2.0.0" + which "^2.0.1" + +crypto-random-string@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/crypto-random-string/-/crypto-random-string-2.0.0.tgz#ef2a7a966ec11083388369baa02ebead229b30d5" + integrity sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA== + +csstype@^3.0.2: + version "3.1.3" + resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.1.3.tgz#d80ff294d114fb0e6ac500fbf85b60137d7eff81" + integrity sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw== + +debug@2.6.9, debug@^2.6.9: + version "2.6.9" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" + integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== + dependencies: + ms "2.0.0" + +debug@4, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.4: + version "4.3.7" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.7.tgz#87945b4151a011d76d95a198d7111c865c360a52" + integrity sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ== + dependencies: + ms "^2.1.3" + +deep-equal@^2.0.5: + version "2.2.3" + resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-2.2.3.tgz#af89dafb23a396c7da3e862abc0be27cf51d56e1" + integrity sha512-ZIwpnevOurS8bpT4192sqAowWM76JDKSHYzMLty3BZGSswgq6pBaH3DhCSW5xVAZICZyKdOBPjwww5wfgT/6PA== + dependencies: + array-buffer-byte-length "^1.0.0" + call-bind "^1.0.5" + es-get-iterator "^1.1.3" + get-intrinsic "^1.2.2" + is-arguments "^1.1.1" + is-array-buffer "^3.0.2" + is-date-object "^1.0.5" + is-regex "^1.1.4" + is-shared-array-buffer "^1.0.2" + isarray "^2.0.5" + object-is "^1.1.5" + object-keys "^1.1.1" + object.assign "^4.1.4" + regexp.prototype.flags "^1.5.1" + side-channel "^1.0.4" + which-boxed-primitive "^1.0.2" + which-collection "^1.0.1" + which-typed-array "^1.1.13" + +default-browser-id@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/default-browser-id/-/default-browser-id-3.0.0.tgz#bee7bbbef1f4e75d31f98f4d3f1556a14cea790c" + integrity sha512-OZ1y3y0SqSICtE8DE4S8YOE9UZOJ8wO16fKWVP5J1Qz42kV9jcnMVFrEE/noXb/ss3Q4pZIH79kxofzyNNtUNA== + dependencies: + bplist-parser "^0.2.0" + untildify "^4.0.0" + +defaults@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/defaults/-/defaults-1.0.4.tgz#b0b02062c1e2aa62ff5d9528f0f98baa90978d7a" + integrity sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A== + dependencies: + clone "^1.0.2" + +define-data-property@^1.0.1, define-data-property@^1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/define-data-property/-/define-data-property-1.1.4.tgz#894dc141bb7d3060ae4366f6a0107e68fbe48c5e" + integrity sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A== + dependencies: + es-define-property "^1.0.0" + es-errors "^1.3.0" + gopd "^1.0.1" + +define-lazy-prop@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz#3f7ae421129bcaaac9bc74905c98a0009ec9ee7f" + integrity sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og== + +define-properties@^1.1.3, define-properties@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.2.1.tgz#10781cc616eb951a80a034bafcaa7377f6af2b6c" + integrity sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg== + dependencies: + define-data-property "^1.0.1" + has-property-descriptors "^1.0.0" + object-keys "^1.1.1" + +defu@^6.1.4: + version "6.1.4" + resolved "https://registry.yarnpkg.com/defu/-/defu-6.1.4.tgz#4e0c9cf9ff68fe5f3d7f2765cc1a012dfdcb0479" + integrity sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg== + +del@^6.0.0: + version "6.1.1" + resolved "https://registry.yarnpkg.com/del/-/del-6.1.1.tgz#3b70314f1ec0aa325c6b14eb36b95786671edb7a" + integrity sha512-ua8BhapfP0JUJKC/zV9yHHDW/rDoDxP4Zhn3AkA6/xT6gY7jYXJiaeyBZznYVujhZZET+UgcbZiQ7sN3WqcImg== + dependencies: + globby "^11.0.1" + graceful-fs "^4.2.4" + is-glob "^4.0.1" + is-path-cwd "^2.2.0" + is-path-inside "^3.0.2" + p-map "^4.0.0" + rimraf "^3.0.2" + slash "^3.0.0" + +delayed-stream@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" + integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ== + +depd@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df" + integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw== + +dequal@^2.0.2: + version "2.0.3" + resolved "https://registry.yarnpkg.com/dequal/-/dequal-2.0.3.tgz#2644214f1997d39ed0ee0ece72335490a7ac67be" + integrity sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA== + +destroy@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.2.0.tgz#4803735509ad8be552934c67df614f94e66fa015" + integrity sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg== + +detect-indent@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-6.1.0.tgz#592485ebbbf6b3b1ab2be175c8393d04ca0d57e6" + integrity sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA== + +detect-node-es@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/detect-node-es/-/detect-node-es-1.1.0.tgz#163acdf643330caa0b4cd7c21e7ee7755d6fa493" + integrity sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ== + +detect-package-manager@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/detect-package-manager/-/detect-package-manager-2.0.1.tgz#6b182e3ae5e1826752bfef1de9a7b828cffa50d8" + integrity sha512-j/lJHyoLlWi6G1LDdLgvUtz60Zo5GEj+sVYtTVXnYLDPuzgC3llMxonXym9zIwhhUII8vjdw0LXxavpLqTbl1A== + dependencies: + execa "^5.1.1" + +detect-port@^1.3.0: + version "1.6.1" + resolved "https://registry.yarnpkg.com/detect-port/-/detect-port-1.6.1.tgz#45e4073997c5f292b957cb678fb0bb8ed4250a67" + integrity sha512-CmnVc+Hek2egPx1PeTFVta2W78xy2K/9Rkf6cC4T59S50tVnzKj+tnx5mmx5lwvCkujZ4uRrpRSuV+IVs3f90Q== + dependencies: + address "^1.0.1" + debug "4" + +dir-glob@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f" + integrity sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA== + dependencies: + path-type "^4.0.0" + +doctrine@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-3.0.0.tgz#addebead72a6574db783639dc87a121773973961" + integrity sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w== + dependencies: + esutils "^2.0.2" + +dom-accessibility-api@^0.5.9: + version "0.5.16" + resolved "https://registry.yarnpkg.com/dom-accessibility-api/-/dom-accessibility-api-0.5.16.tgz#5a7429e6066eb3664d911e33fb0e45de8eb08453" + integrity sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg== + +dotenv-expand@^10.0.0: + version "10.0.0" + resolved "https://registry.yarnpkg.com/dotenv-expand/-/dotenv-expand-10.0.0.tgz#12605d00fb0af6d0a592e6558585784032e4ef37" + integrity sha512-GopVGCpVS1UKH75VKHGuQFqS1Gusej0z4FyQkPdwjil2gNIv+LNsqBlboOzpJFZKVT95GkCyWJbBSdFEFUWI2A== + +dotenv@^16.0.0: + version "16.4.5" + resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.4.5.tgz#cdd3b3b604cb327e286b4762e13502f717cb099f" + integrity sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg== + +duplexify@^3.5.0, duplexify@^3.6.0: + version "3.7.1" + resolved "https://registry.yarnpkg.com/duplexify/-/duplexify-3.7.1.tgz#2a4df5317f6ccfd91f86d6fd25d8d8a103b88309" + integrity sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g== + dependencies: + end-of-stream "^1.0.0" + inherits "^2.0.1" + readable-stream "^2.0.0" + stream-shift "^1.0.0" + +eastasianwidth@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/eastasianwidth/-/eastasianwidth-0.2.0.tgz#696ce2ec0aa0e6ea93a397ffcf24aa7840c827cb" + integrity sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA== + +ee-first@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" + integrity sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow== + +ejs@^3.1.8: + version "3.1.10" + resolved "https://registry.yarnpkg.com/ejs/-/ejs-3.1.10.tgz#69ab8358b14e896f80cc39e62087b88500c3ac3b" + integrity sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA== + dependencies: + jake "^10.8.5" + +electron-to-chromium@^1.5.41: + version "1.5.57" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.57.tgz#cb43af8784166bca24565b3418bf5f775a6b1c86" + integrity sha512-xS65H/tqgOwUBa5UmOuNSLuslDo7zho0y/lgQw35pnrqiZh7UOWHCeL/Bt6noJATbA6tpQJGCifsFsIRZj1Fqg== + +emoji-regex@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" + integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== + +emoji-regex@^9.2.2: + version "9.2.2" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-9.2.2.tgz#840c8803b0d8047f4ff0cf963176b32d4ef3ed72" + integrity sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg== + +encodeurl@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" + integrity sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w== + +encodeurl@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-2.0.0.tgz#7b8ea898077d7e409d3ac45474ea38eaf0857a58" + integrity sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg== + +end-of-stream@^1.0.0, end-of-stream@^1.1.0, end-of-stream@^1.4.1: + version "1.4.4" + resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" + integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q== + dependencies: + once "^1.4.0" + +envinfo@^7.7.3: + version "7.14.0" + resolved "https://registry.yarnpkg.com/envinfo/-/envinfo-7.14.0.tgz#26dac5db54418f2a4c1159153a0b2ae980838aae" + integrity sha512-CO40UI41xDQzhLB1hWyqUKgFhs250pNcGbyGKe1l/e4FSaI/+YE4IMG76GDt0In67WLPACIITC+sOi08x4wIvg== + +error-ex@^1.3.1: + version "1.3.2" + resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" + integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== + dependencies: + is-arrayish "^0.2.1" + +es-define-property@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/es-define-property/-/es-define-property-1.0.0.tgz#c7faefbdff8b2696cf5f46921edfb77cc4ba3845" + integrity sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ== + dependencies: + get-intrinsic "^1.2.4" + +es-errors@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/es-errors/-/es-errors-1.3.0.tgz#05f75a25dab98e4fb1dcd5e1472c0546d5057c8f" + integrity sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw== + +es-get-iterator@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/es-get-iterator/-/es-get-iterator-1.1.3.tgz#3ef87523c5d464d41084b2c3c9c214f1199763d6" + integrity sha512-sPZmqHBe6JIiTfN5q2pEi//TwxmAFHwj/XEuYjTuse78i8KxaqMTTzxPoFKuzRpDpTJ+0NAbpfenkmH2rePtuw== + dependencies: + call-bind "^1.0.2" + get-intrinsic "^1.1.3" + has-symbols "^1.0.3" + is-arguments "^1.1.1" + is-map "^2.0.2" + is-set "^2.0.2" + is-string "^1.0.7" + isarray "^2.0.5" + stop-iteration-iterator "^1.0.0" + +es-module-lexer@^0.9.3: + version "0.9.3" + resolved "https://registry.yarnpkg.com/es-module-lexer/-/es-module-lexer-0.9.3.tgz#6f13db00cc38417137daf74366f535c8eb438f19" + integrity sha512-1HQ2M2sPtxwnvOvT1ZClHyQDiggdNjURWpY2we6aMKCQiUVxTmVs2UYPLIrD84sS+kMdUwfBSylbJPwNnBrnHQ== + +esbuild-plugin-alias@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/esbuild-plugin-alias/-/esbuild-plugin-alias-0.2.1.tgz#45a86cb941e20e7c2bc68a2bea53562172494fcb" + integrity sha512-jyfL/pwPqaFXyKnj8lP8iLk6Z0m099uXR45aSN8Av1XD4vhvQutxxPzgA2bTcAwQpa1zCXDcWOlhFgyP3GKqhQ== + +esbuild-register@^3.5.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/esbuild-register/-/esbuild-register-3.6.0.tgz#cf270cfa677baebbc0010ac024b823cbf723a36d" + integrity sha512-H2/S7Pm8a9CL1uhp9OvjwrBh5Pvx0H8qVOxNu8Wed9Y7qv56MPtq+GGM8RJpq6glYJn9Wspr8uw7l55uyinNeg== + dependencies: + debug "^4.3.4" + +esbuild@^0.18.0, esbuild@^0.18.10: + version "0.18.20" + resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.18.20.tgz#4709f5a34801b43b799ab7d6d82f7284a9b7a7a6" + integrity sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA== + optionalDependencies: + "@esbuild/android-arm" "0.18.20" + "@esbuild/android-arm64" "0.18.20" + "@esbuild/android-x64" "0.18.20" + "@esbuild/darwin-arm64" "0.18.20" + "@esbuild/darwin-x64" "0.18.20" + "@esbuild/freebsd-arm64" "0.18.20" + "@esbuild/freebsd-x64" "0.18.20" + "@esbuild/linux-arm" "0.18.20" + "@esbuild/linux-arm64" "0.18.20" + "@esbuild/linux-ia32" "0.18.20" + "@esbuild/linux-loong64" "0.18.20" + "@esbuild/linux-mips64el" "0.18.20" + "@esbuild/linux-ppc64" "0.18.20" + "@esbuild/linux-riscv64" "0.18.20" + "@esbuild/linux-s390x" "0.18.20" + "@esbuild/linux-x64" "0.18.20" + "@esbuild/netbsd-x64" "0.18.20" + "@esbuild/openbsd-x64" "0.18.20" + "@esbuild/sunos-x64" "0.18.20" + "@esbuild/win32-arm64" "0.18.20" + "@esbuild/win32-ia32" "0.18.20" + "@esbuild/win32-x64" "0.18.20" + +escalade@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.2.0.tgz#011a3f69856ba189dffa7dc8fcce99d2a87903e5" + integrity sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA== + +escape-html@~1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" + integrity sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow== + +esprima@^4.0.0, esprima@~4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" + integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== + +esutils@^2.0.2: + version "2.0.3" + resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" + integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== + +etag@~1.8.1: + version "1.8.1" + resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" + integrity sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg== + +execa@^5.0.0, execa@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/execa/-/execa-5.1.1.tgz#f80ad9cbf4298f7bd1d4c9555c21e93741c411dd" + integrity sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg== + dependencies: + cross-spawn "^7.0.3" + get-stream "^6.0.0" + human-signals "^2.1.0" + is-stream "^2.0.0" + merge-stream "^2.0.0" + npm-run-path "^4.0.1" + onetime "^5.1.2" + signal-exit "^3.0.3" + strip-final-newline "^2.0.0" + +execa@^8.0.1: + version "8.0.1" + resolved "https://registry.yarnpkg.com/execa/-/execa-8.0.1.tgz#51f6a5943b580f963c3ca9c6321796db8cc39b8c" + integrity sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg== + dependencies: + cross-spawn "^7.0.3" + get-stream "^8.0.1" + human-signals "^5.0.0" + is-stream "^3.0.0" + merge-stream "^2.0.0" + npm-run-path "^5.1.0" + onetime "^6.0.0" + signal-exit "^4.1.0" + strip-final-newline "^3.0.0" + +express@^4.17.3: + version "4.21.1" + resolved "https://registry.yarnpkg.com/express/-/express-4.21.1.tgz#9dae5dda832f16b4eec941a4e44aa89ec481b281" + integrity sha512-YSFlK1Ee0/GC8QaO91tHcDxJiE/X4FbpAyQWkxAvG6AXCuR65YzK8ua6D9hvi/TzUfZMpc+BwuM1IPw8fmQBiQ== + dependencies: + accepts "~1.3.8" + array-flatten "1.1.1" + body-parser "1.20.3" + content-disposition "0.5.4" + content-type "~1.0.4" + cookie "0.7.1" + cookie-signature "1.0.6" + debug "2.6.9" + depd "2.0.0" + encodeurl "~2.0.0" + escape-html "~1.0.3" + etag "~1.8.1" + finalhandler "1.3.1" + fresh "0.5.2" + http-errors "2.0.0" + merge-descriptors "1.0.3" + methods "~1.1.2" + on-finished "2.4.1" + parseurl "~1.3.3" + path-to-regexp "0.1.10" + proxy-addr "~2.0.7" + qs "6.13.0" + range-parser "~1.2.1" + safe-buffer "5.2.1" + send "0.19.0" + serve-static "1.16.2" + setprototypeof "1.2.0" + statuses "2.0.1" + type-is "~1.6.18" + utils-merge "1.0.1" + vary "~1.1.2" + +extend@^3.0.0: + version "3.0.2" + resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" + integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== + +extract-zip@^1.6.6: + version "1.7.0" + resolved "https://registry.yarnpkg.com/extract-zip/-/extract-zip-1.7.0.tgz#556cc3ae9df7f452c493a0cfb51cc30277940927" + integrity sha512-xoh5G1W/PB0/27lXgMQyIhP5DSY/LhoCsOyZgb+6iMmRtCwVBo55uKaMoEYrDCKQhWvqEip5ZPKAc6eFNyf/MA== + dependencies: + concat-stream "^1.6.2" + debug "^2.6.9" + mkdirp "^0.5.4" + yauzl "^2.10.0" + +fast-glob@^3.2.9: + version "3.3.2" + resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.3.2.tgz#a904501e57cfdd2ffcded45e99a54fef55e46129" + integrity sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow== + dependencies: + "@nodelib/fs.stat" "^2.0.2" + "@nodelib/fs.walk" "^1.2.3" + glob-parent "^5.1.2" + merge2 "^1.3.0" + micromatch "^4.0.4" + +fast-json-stable-stringify@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" + integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== + +fastq@^1.6.0: + version "1.17.1" + resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.17.1.tgz#2a523f07a4e7b1e81a42b91b8bf2254107753b47" + integrity sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w== + dependencies: + reusify "^1.0.4" + +fb-watchman@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/fb-watchman/-/fb-watchman-2.0.2.tgz#e9524ee6b5c77e9e5001af0f85f3adbb8623255c" + integrity sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA== + dependencies: + bser "2.1.1" + +fd-slicer@~1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/fd-slicer/-/fd-slicer-1.1.0.tgz#25c7c89cb1f9077f8891bbe61d8f390eae256f1e" + integrity sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g== + dependencies: + pend "~1.2.0" + +fetch-retry@^5.0.2: + version "5.0.6" + resolved "https://registry.yarnpkg.com/fetch-retry/-/fetch-retry-5.0.6.tgz#17d0bc90423405b7a88b74355bf364acd2a7fa56" + integrity sha512-3yurQZ2hD9VISAhJJP9bpYFNQrHHBXE2JxxjY5aLEcDi46RmAzJE2OC9FAde0yis5ElW0jTTzs0zfg/Cca4XqQ== + +file-system-cache@2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/file-system-cache/-/file-system-cache-2.3.0.tgz#201feaf4c8cd97b9d0d608e96861bb6005f46fe6" + integrity sha512-l4DMNdsIPsVnKrgEXbJwDJsA5mB8rGwHYERMgqQx/xAUtChPJMre1bXBzDEqqVbWv9AIbFezXMxeEkZDSrXUOQ== + dependencies: + fs-extra "11.1.1" + ramda "0.29.0" + +filelist@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/filelist/-/filelist-1.0.4.tgz#f78978a1e944775ff9e62e744424f215e58352b5" + integrity sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q== + dependencies: + minimatch "^5.0.1" + +fill-range@^7.1.1: + version "7.1.1" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.1.1.tgz#44265d3cac07e3ea7dc247516380643754a05292" + integrity sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg== + dependencies: + to-regex-range "^5.0.1" + +finalhandler@1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.3.1.tgz#0c575f1d1d324ddd1da35ad7ece3df7d19088019" + integrity sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ== + dependencies: + debug "2.6.9" + encodeurl "~2.0.0" + escape-html "~1.0.3" + on-finished "2.4.1" + parseurl "~1.3.3" + statuses "2.0.1" + unpipe "~1.0.0" + +find-cache-dir@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-2.1.0.tgz#8d0f94cd13fe43c6c7c261a0d86115ca918c05f7" + integrity sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ== + dependencies: + commondir "^1.0.1" + make-dir "^2.0.0" + pkg-dir "^3.0.0" + +find-cache-dir@^3.0.0: + version "3.3.2" + resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-3.3.2.tgz#b30c5b6eff0730731aea9bbd9dbecbd80256d64b" + integrity sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig== + dependencies: + commondir "^1.0.1" + make-dir "^3.0.2" + pkg-dir "^4.1.0" + +find-up@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-3.0.0.tgz#49169f1d7993430646da61ecc5ae355c21c97b73" + integrity sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg== + dependencies: + locate-path "^3.0.0" + +find-up@^4.0.0, find-up@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19" + integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw== + dependencies: + locate-path "^5.0.0" + path-exists "^4.0.0" + +find-up@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc" + integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== + dependencies: + locate-path "^6.0.0" + path-exists "^4.0.0" + +flow-parser@0.*: + version "0.252.0" + resolved "https://registry.yarnpkg.com/flow-parser/-/flow-parser-0.252.0.tgz#8f9795cbd1b5108f1aec2602f951dcb97ffbd247" + integrity sha512-z8hKPUjZ33VLn4HVntifqmEhmolUMopysnMNzazoDqo1GLUkBsreLNsxETlKJMPotUWStQnen6SGvUNe1j4Hlg== + +for-each@^0.3.3: + version "0.3.3" + resolved "https://registry.yarnpkg.com/for-each/-/for-each-0.3.3.tgz#69b447e88a0a5d32c3e7084f3f1710034b21376e" + integrity sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw== + dependencies: + is-callable "^1.1.3" + +foreground-child@^3.1.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/foreground-child/-/foreground-child-3.3.0.tgz#0ac8644c06e431439f8561db8ecf29a7b5519c77" + integrity sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg== + dependencies: + cross-spawn "^7.0.0" + signal-exit "^4.0.1" + +form-data@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.1.tgz#ba1076daaaa5bfd7e99c1a6cb02aa0a5cff90d48" + integrity sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw== + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.8" + mime-types "^2.1.12" + +forwarded@0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.2.0.tgz#2269936428aad4c15c7ebe9779a84bf0b2a81811" + integrity sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow== + +fresh@0.5.2: + version "0.5.2" + resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" + integrity sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q== + +fs-constants@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs-constants/-/fs-constants-1.0.0.tgz#6be0de9be998ce16af8afc24497b9ee9b7ccd9ad" + integrity sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow== + +fs-extra@11.1.1: + version "11.1.1" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-11.1.1.tgz#da69f7c39f3b002378b0954bb6ae7efdc0876e2d" + integrity sha512-MGIE4HOvQCeUCzmlHs0vXpih4ysz4wg9qiSAu6cd42lVwPbTM1TjV7RusoyQqMmk/95gdQZX72u+YW+c3eEpFQ== + dependencies: + graceful-fs "^4.2.0" + jsonfile "^6.0.1" + universalify "^2.0.0" + +fs-extra@^11.1.0: + version "11.2.0" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-11.2.0.tgz#e70e17dfad64232287d01929399e0ea7c86b0e5b" + integrity sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw== + dependencies: + graceful-fs "^4.2.0" + jsonfile "^6.0.1" + universalify "^2.0.0" + +fs-minipass@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-2.1.0.tgz#7f5036fdbf12c63c169190cbe4199c852271f9fb" + integrity sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg== + dependencies: + minipass "^3.0.0" + +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== + +fsevents@^2.3.2, fsevents@~2.3.2: + version "2.3.3" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6" + integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw== + +function-bind@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.2.tgz#2c02d864d97f3ea6c8830c464cbd11ab6eab7a1c" + integrity sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA== + +functions-have-names@^1.2.3: + version "1.2.3" + resolved "https://registry.yarnpkg.com/functions-have-names/-/functions-have-names-1.2.3.tgz#0404fe4ee2ba2f607f0e0ec3c80bae994133b834" + integrity sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ== + +gensync@^1.0.0-beta.2: + version "1.0.0-beta.2" + resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0" + integrity sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg== + +get-intrinsic@^1.1.3, get-intrinsic@^1.2.1, get-intrinsic@^1.2.2, get-intrinsic@^1.2.4: + version "1.2.4" + resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.2.4.tgz#e385f5a4b5227d449c3eabbad05494ef0abbeadd" + integrity sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ== + dependencies: + es-errors "^1.3.0" + function-bind "^1.1.2" + has-proto "^1.0.1" + has-symbols "^1.0.3" + hasown "^2.0.0" + +get-nonce@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/get-nonce/-/get-nonce-1.0.1.tgz#fdf3f0278073820d2ce9426c18f07481b1e0cdf3" + integrity sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q== + +get-npm-tarball-url@^2.0.3: + version "2.1.0" + resolved "https://registry.yarnpkg.com/get-npm-tarball-url/-/get-npm-tarball-url-2.1.0.tgz#cbd6bb25884622bc3191c761466c93ac83343213" + integrity sha512-ro+DiMu5DXgRBabqXupW38h7WPZ9+Ad8UjwhvsmmN8w1sU7ab0nzAXvVZ4kqYg57OrqomRtJvepX5/xvFKNtjA== + +get-package-type@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/get-package-type/-/get-package-type-0.1.0.tgz#8de2d803cff44df3bc6c456e6668b36c3926e11a" + integrity sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q== + +get-port@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/get-port/-/get-port-5.1.1.tgz#0469ed07563479de6efb986baf053dcd7d4e3193" + integrity sha512-g/Q1aTSDOxFpchXC4i8ZWvxA1lnPqx/JHqcpIw0/LX9T8x/GBbi6YnlN5nhaKIFkT8oFsscUKgDJYxfwfS6QsQ== + +get-stream@^6.0.0: + version "6.0.1" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7" + integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg== + +get-stream@^8.0.1: + version "8.0.1" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-8.0.1.tgz#def9dfd71742cd7754a7761ed43749a27d02eca2" + integrity sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA== + +giget@^1.0.0: + version "1.2.3" + resolved "https://registry.yarnpkg.com/giget/-/giget-1.2.3.tgz#ef6845d1140e89adad595f7f3bb60aa31c672cb6" + integrity sha512-8EHPljDvs7qKykr6uw8b+lqLiUc/vUg+KVTI0uND4s63TdsZM2Xus3mflvF0DDG9SiM4RlCkFGL+7aAjRmV7KA== + dependencies: + citty "^0.1.6" + consola "^3.2.3" + defu "^6.1.4" + node-fetch-native "^1.6.3" + nypm "^0.3.8" + ohash "^1.1.3" + pathe "^1.1.2" + tar "^6.2.0" + +github-slugger@^1.0.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/github-slugger/-/github-slugger-1.5.0.tgz#17891bbc73232051474d68bd867a34625c955f7d" + integrity sha512-wIh+gKBI9Nshz2o46B0B3f5k/W+WI9ZAv6y5Dn5WJ5SK1t0TnDimB4WE5rmTD05ZAIn8HALCZVmCsvj0w0v0lw== + +glob-parent@^5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" + integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== + dependencies: + is-glob "^4.0.1" + +glob-to-regexp@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz#c75297087c851b9a578bd217dd59a92f59fe546e" + integrity sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw== + +glob@^10.0.0: + version "10.4.5" + resolved "https://registry.yarnpkg.com/glob/-/glob-10.4.5.tgz#f4d9f0b90ffdbab09c9d77f5f29b4262517b0956" + integrity sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg== + dependencies: + foreground-child "^3.1.0" + jackspeak "^3.1.2" + minimatch "^9.0.4" + minipass "^7.1.2" + package-json-from-dist "^1.0.0" + path-scurry "^1.11.1" + +glob@^7.1.3, glob@^7.1.4: + version "7.2.3" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b" + integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.1.1" + once "^1.3.0" + path-is-absolute "^1.0.0" + +globals@^11.1.0: + version "11.12.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" + integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== + +globby@^11.0.1, globby@^11.0.2: + version "11.1.0" + resolved "https://registry.yarnpkg.com/globby/-/globby-11.1.0.tgz#bd4be98bb042f83d796f7e3811991fbe82a0d34b" + integrity sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g== + dependencies: + array-union "^2.1.0" + dir-glob "^3.0.1" + fast-glob "^3.2.9" + ignore "^5.2.0" + merge2 "^1.4.1" + slash "^3.0.0" + +gopd@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/gopd/-/gopd-1.0.1.tgz#29ff76de69dac7489b7c0918a5788e56477c332c" + integrity sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA== + dependencies: + get-intrinsic "^1.1.3" + +graceful-fs@^4.1.11, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.4, graceful-fs@^4.2.9: + version "4.2.11" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3" + integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ== + +gunzip-maybe@^1.4.2: + version "1.4.2" + resolved "https://registry.yarnpkg.com/gunzip-maybe/-/gunzip-maybe-1.4.2.tgz#b913564ae3be0eda6f3de36464837a9cd94b98ac" + integrity sha512-4haO1M4mLO91PW57BMsDFf75UmwoRX0GkdD+Faw+Lr+r/OZrOCS0pIBwOL1xCKQqnQzbNFGgK2V2CpBUPeFNTw== + dependencies: + browserify-zlib "^0.1.4" + is-deflate "^1.0.0" + is-gzip "^1.0.0" + peek-stream "^1.1.0" + pumpify "^1.3.3" + through2 "^2.0.3" + +handlebars@^4.7.7: + version "4.7.8" + resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.7.8.tgz#41c42c18b1be2365439188c77c6afae71c0cd9e9" + integrity sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ== + dependencies: + minimist "^1.2.5" + neo-async "^2.6.2" + source-map "^0.6.1" + wordwrap "^1.0.0" + optionalDependencies: + uglify-js "^3.1.4" + +has-bigints@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/has-bigints/-/has-bigints-1.0.2.tgz#0871bd3e3d51626f6ca0966668ba35d5602d6eaa" + integrity sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ== + +has-flag@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" + integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== + +has-property-descriptors@^1.0.0, has-property-descriptors@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz#963ed7d071dc7bf5f084c5bfbe0d1b6222586854" + integrity sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg== + dependencies: + es-define-property "^1.0.0" + +has-proto@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has-proto/-/has-proto-1.0.3.tgz#b31ddfe9b0e6e9914536a6ab286426d0214f77fd" + integrity sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q== + +has-symbols@^1.0.2, has-symbols@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8" + integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A== + +has-tostringtag@^1.0.0, has-tostringtag@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/has-tostringtag/-/has-tostringtag-1.0.2.tgz#2cdc42d40bef2e5b4eeab7c01a73c54ce7ab5abc" + integrity sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw== + dependencies: + has-symbols "^1.0.3" + +hasown@^2.0.0, hasown@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/hasown/-/hasown-2.0.2.tgz#003eaf91be7adc372e84ec59dc37252cedb80003" + integrity sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ== + dependencies: + function-bind "^1.1.2" + +hosted-git-info@^2.1.4: + version "2.8.9" + resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.9.tgz#dffc0bf9a21c02209090f2aa69429e1414daf3f9" + integrity sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw== + +http-errors@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-2.0.0.tgz#b7774a1486ef73cf7667ac9ae0858c012c57b9d3" + integrity sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ== + dependencies: + depd "2.0.0" + inherits "2.0.4" + setprototypeof "1.2.0" + statuses "2.0.1" + toidentifier "1.0.1" + +https-proxy-agent@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-4.0.0.tgz#702b71fb5520a132a66de1f67541d9e62154d82b" + integrity sha512-zoDhWrkR3of1l9QAL8/scJZyLu8j/gBkcwcaQOZh7Gyh/+uJQzGVETdgT30akuwkpL8HTRfssqI3BZuV18teDg== + dependencies: + agent-base "5" + debug "4" + +human-signals@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0" + integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw== + +human-signals@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-5.0.0.tgz#42665a284f9ae0dade3ba41ebc37eb4b852f3a28" + integrity sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ== + +iconv-lite@0.4.24: + version "0.4.24" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" + integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== + dependencies: + safer-buffer ">= 2.1.2 < 3" + +ieee754@^1.1.13: + version "1.2.1" + resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" + integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== + +ignore@^5.2.0: + version "5.3.2" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.3.2.tgz#3cd40e729f3643fd87cb04e50bf0eb722bc596f5" + integrity sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g== + +imurmurhash@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" + integrity sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA== + +indent-string@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-4.0.0.tgz#624f8f4497d619b2d9768531d58f4122854d7251" + integrity sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg== + +inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + integrity sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA== + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.3: + version "2.0.4" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" + integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== + +internal-slot@^1.0.4: + version "1.0.7" + resolved "https://registry.yarnpkg.com/internal-slot/-/internal-slot-1.0.7.tgz#c06dcca3ed874249881007b0a5523b172a190802" + integrity sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g== + dependencies: + es-errors "^1.3.0" + hasown "^2.0.0" + side-channel "^1.0.4" + +invariant@^2.2.4: + version "2.2.4" + resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6" + integrity sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA== + dependencies: + loose-envify "^1.0.0" + +ipaddr.js@1.9.1: + version "1.9.1" + resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3" + integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g== + +is-absolute-url@^3.0.0: + version "3.0.3" + resolved "https://registry.yarnpkg.com/is-absolute-url/-/is-absolute-url-3.0.3.tgz#96c6a22b6a23929b11ea0afb1836c36ad4a5d698" + integrity sha512-opmNIX7uFnS96NtPmhWQgQx6/NYFgsUXYMllcfzwWKUMwfo8kku1TvE6hkNcH+Q1ts5cMVrsY7j0bxXQDciu9Q== + +is-arguments@^1.0.4, is-arguments@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/is-arguments/-/is-arguments-1.1.1.tgz#15b3f88fda01f2a97fec84ca761a560f123efa9b" + integrity sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA== + dependencies: + call-bind "^1.0.2" + has-tostringtag "^1.0.0" + +is-array-buffer@^3.0.2, is-array-buffer@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/is-array-buffer/-/is-array-buffer-3.0.4.tgz#7a1f92b3d61edd2bc65d24f130530ea93d7fae98" + integrity sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw== + dependencies: + call-bind "^1.0.2" + get-intrinsic "^1.2.1" + +is-arrayish@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" + integrity sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg== + +is-bigint@^1.0.1: + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-bigint/-/is-bigint-1.0.4.tgz#08147a1875bc2b32005d41ccd8291dffc6691df3" + integrity sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg== + dependencies: + has-bigints "^1.0.1" + +is-boolean-object@^1.1.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/is-boolean-object/-/is-boolean-object-1.1.2.tgz#5c6dc200246dd9321ae4b885a114bb1f75f63719" + integrity sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA== + dependencies: + call-bind "^1.0.2" + has-tostringtag "^1.0.0" + +is-callable@^1.1.3: + version "1.2.7" + resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.7.tgz#3bc2a85ea742d9e36205dcacdd72ca1fdc51b055" + integrity sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA== + +is-core-module@^2.13.0: + version "2.15.1" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.15.1.tgz#a7363a25bee942fefab0de13bf6aa372c82dcc37" + integrity sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ== + dependencies: + hasown "^2.0.2" + +is-date-object@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.5.tgz#0841d5536e724c25597bf6ea62e1bd38298df31f" + integrity sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ== + dependencies: + has-tostringtag "^1.0.0" + +is-deflate@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-deflate/-/is-deflate-1.0.0.tgz#c862901c3c161fb09dac7cdc7e784f80e98f2f14" + integrity sha512-YDoFpuZWu1VRXlsnlYMzKyVRITXj7Ej/V9gXQ2/pAe7X1J7M/RNOqaIYi6qUn+B7nGyB9pDXrv02dsB58d2ZAQ== + +is-docker@^2.0.0, is-docker@^2.1.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-2.2.1.tgz#33eeabe23cfe86f14bde4408a02c0cfb853acdaa" + integrity sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ== + +is-extglob@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" + integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== + +is-fullwidth-code-point@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" + integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== + +is-generator-function@^1.0.7: + version "1.0.10" + resolved "https://registry.yarnpkg.com/is-generator-function/-/is-generator-function-1.0.10.tgz#f1558baf1ac17e0deea7c0415c438351ff2b3c72" + integrity sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A== + dependencies: + has-tostringtag "^1.0.0" + +is-glob@^4.0.1: + version "4.0.3" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" + integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== + dependencies: + is-extglob "^2.1.1" + +is-gzip@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-gzip/-/is-gzip-1.0.0.tgz#6ca8b07b99c77998025900e555ced8ed80879a83" + integrity sha512-rcfALRIb1YewtnksfRIHGcIY93QnK8BIQ/2c9yDYcG/Y6+vRoJuTWBmmSEbyLLYtXm7q35pHOHbZFQBaLrhlWQ== + +is-interactive@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-interactive/-/is-interactive-1.0.0.tgz#cea6e6ae5c870a7b0a0004070b7b587e0252912e" + integrity sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w== + +is-map@^2.0.2, is-map@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/is-map/-/is-map-2.0.3.tgz#ede96b7fe1e270b3c4465e3a465658764926d62e" + integrity sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw== + +is-nan@^1.3.2: + version "1.3.2" + resolved "https://registry.yarnpkg.com/is-nan/-/is-nan-1.3.2.tgz#043a54adea31748b55b6cd4e09aadafa69bd9e1d" + integrity sha512-E+zBKpQ2t6MEo1VsonYmluk9NxGrbzpeeLC2xIViuO2EjU2xsXsBPwTr3Ykv9l08UYEVEdWeRZNouaZqF6RN0w== + dependencies: + call-bind "^1.0.0" + define-properties "^1.1.3" + +is-number-object@^1.0.4: + version "1.0.7" + resolved "https://registry.yarnpkg.com/is-number-object/-/is-number-object-1.0.7.tgz#59d50ada4c45251784e9904f5246c742f07a42fc" + integrity sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ== + dependencies: + has-tostringtag "^1.0.0" + +is-number@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" + integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== + +is-path-cwd@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/is-path-cwd/-/is-path-cwd-2.2.0.tgz#67d43b82664a7b5191fd9119127eb300048a9fdb" + integrity sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ== + +is-path-inside@^3.0.2: + version "3.0.3" + resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-3.0.3.tgz#d231362e53a07ff2b0e0ea7fed049161ffd16283" + integrity sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ== + +is-plain-object@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" + integrity sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og== + dependencies: + isobject "^3.0.1" + +is-regex@^1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.4.tgz#eef5663cd59fa4c0ae339505323df6854bb15958" + integrity sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg== + dependencies: + call-bind "^1.0.2" + has-tostringtag "^1.0.0" + +is-set@^2.0.2, is-set@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/is-set/-/is-set-2.0.3.tgz#8ab209ea424608141372ded6e0cb200ef1d9d01d" + integrity sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg== + +is-shared-array-buffer@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/is-shared-array-buffer/-/is-shared-array-buffer-1.0.3.tgz#1237f1cba059cdb62431d378dcc37d9680181688" + integrity sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg== + dependencies: + call-bind "^1.0.7" + +is-stream@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.1.tgz#fac1e3d53b97ad5a9d0ae9cef2389f5810a5c077" + integrity sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg== + +is-stream@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-3.0.0.tgz#e6bfd7aa6bef69f4f472ce9bb681e3e57b4319ac" + integrity sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA== + +is-string@^1.0.5, is-string@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.7.tgz#0dd12bf2006f255bb58f695110eff7491eebc0fd" + integrity sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg== + dependencies: + has-tostringtag "^1.0.0" + +is-symbol@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.4.tgz#a6dac93b635b063ca6872236de88910a57af139c" + integrity sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg== + dependencies: + has-symbols "^1.0.2" + +is-typed-array@^1.1.3: + version "1.1.13" + resolved "https://registry.yarnpkg.com/is-typed-array/-/is-typed-array-1.1.13.tgz#d6c5ca56df62334959322d7d7dd1cca50debe229" + integrity sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw== + dependencies: + which-typed-array "^1.1.14" + +is-unicode-supported@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz#3f26c76a809593b52bfa2ecb5710ed2779b522a7" + integrity sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw== + +is-weakmap@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/is-weakmap/-/is-weakmap-2.0.2.tgz#bf72615d649dfe5f699079c54b83e47d1ae19cfd" + integrity sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w== + +is-weakset@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/is-weakset/-/is-weakset-2.0.3.tgz#e801519df8c0c43e12ff2834eead84ec9e624007" + integrity sha512-LvIm3/KWzS9oRFHugab7d+M/GcBXuXX5xZkzPmN+NxihdQlZUQ4dWuSV1xR/sq6upL1TJEDrfBgRepHFdBtSNQ== + dependencies: + call-bind "^1.0.7" + get-intrinsic "^1.2.4" + +is-wsl@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-2.2.0.tgz#74a4c76e77ca9fd3f932f290c17ea326cd157271" + integrity sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww== + dependencies: + is-docker "^2.0.0" + +isarray@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-2.0.5.tgz#8af1e4c1221244cc62459faf38940d4e644a5723" + integrity sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw== + +isarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" + integrity sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ== + +isexe@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" + integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== + +isobject@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" + integrity sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg== + +istanbul-lib-coverage@^3.2.0: + version "3.2.2" + resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz#2d166c4b0644d43a39f04bf6c2edd1e585f31756" + integrity sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg== + +istanbul-lib-instrument@^5.0.4: + version "5.2.1" + resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz#d10c8885c2125574e1c231cacadf955675e1ce3d" + integrity sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg== + dependencies: + "@babel/core" "^7.12.3" + "@babel/parser" "^7.14.7" + "@istanbuljs/schema" "^0.1.2" + istanbul-lib-coverage "^3.2.0" + semver "^6.3.0" + +jackspeak@^3.1.2: + version "3.4.3" + resolved "https://registry.yarnpkg.com/jackspeak/-/jackspeak-3.4.3.tgz#8833a9d89ab4acde6188942bd1c53b6390ed5a8a" + integrity sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw== + dependencies: + "@isaacs/cliui" "^8.0.2" + optionalDependencies: + "@pkgjs/parseargs" "^0.11.0" + +jake@^10.8.5: + version "10.9.2" + resolved "https://registry.yarnpkg.com/jake/-/jake-10.9.2.tgz#6ae487e6a69afec3a5e167628996b59f35ae2b7f" + integrity sha512-2P4SQ0HrLQ+fw6llpLnOaGAvN2Zu6778SJMrCUwns4fOoG9ayrTiZk3VV8sCPkVZF8ab0zksVpS8FDY5pRCNBA== + dependencies: + async "^3.2.3" + chalk "^4.0.2" + filelist "^1.0.4" + minimatch "^3.1.2" + +jest-haste-map@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-29.7.0.tgz#3c2396524482f5a0506376e6c858c3bbcc17b104" + integrity sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA== + dependencies: + "@jest/types" "^29.6.3" + "@types/graceful-fs" "^4.1.3" + "@types/node" "*" + anymatch "^3.0.3" + fb-watchman "^2.0.0" + graceful-fs "^4.2.9" + jest-regex-util "^29.6.3" + jest-util "^29.7.0" + jest-worker "^29.7.0" + micromatch "^4.0.4" + walker "^1.0.8" + optionalDependencies: + fsevents "^2.3.2" + +jest-mock@^27.0.6: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-27.5.1.tgz#19948336d49ef4d9c52021d34ac7b5f36ff967d6" + integrity sha512-K4jKbY1d4ENhbrG2zuPWaQBvDly+iZ2yAW+T1fATN78hc0sInwn7wZB8XtlNnvHug5RMwV897Xm4LqmPM4e2Og== + dependencies: + "@jest/types" "^27.5.1" + "@types/node" "*" + +jest-regex-util@^29.6.3: + version "29.6.3" + resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-29.6.3.tgz#4a556d9c776af68e1c5f48194f4d0327d24e8a52" + integrity sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg== + +jest-util@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-29.7.0.tgz#23c2b62bfb22be82b44de98055802ff3710fc0bc" + integrity sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA== + dependencies: + "@jest/types" "^29.6.3" + "@types/node" "*" + chalk "^4.0.0" + ci-info "^3.2.0" + graceful-fs "^4.2.9" + picomatch "^2.2.3" + +jest-worker@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-29.7.0.tgz#acad073acbbaeb7262bd5389e1bcf43e10058d4a" + integrity sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw== + dependencies: + "@types/node" "*" + jest-util "^29.7.0" + merge-stream "^2.0.0" + supports-color "^8.0.0" + +"js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" + integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== + +js-yaml@^3.13.1: + version "3.14.1" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.1.tgz#dae812fdb3825fa306609a8717383c50c36a0537" + integrity sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g== + dependencies: + argparse "^1.0.7" + esprima "^4.0.0" + +jscodeshift@^0.15.1: + version "0.15.2" + resolved "https://registry.yarnpkg.com/jscodeshift/-/jscodeshift-0.15.2.tgz#145563860360b4819a558c75c545f39683e5a0be" + integrity sha512-FquR7Okgmc4Sd0aEDwqho3rEiKR3BdvuG9jfdHjLJ6JQoWSMpavug3AoIfnfWhxFlf+5pzQh8qjqz0DWFrNQzA== + dependencies: + "@babel/core" "^7.23.0" + "@babel/parser" "^7.23.0" + "@babel/plugin-transform-class-properties" "^7.22.5" + "@babel/plugin-transform-modules-commonjs" "^7.23.0" + "@babel/plugin-transform-nullish-coalescing-operator" "^7.22.11" + "@babel/plugin-transform-optional-chaining" "^7.23.0" + "@babel/plugin-transform-private-methods" "^7.22.5" + "@babel/preset-flow" "^7.22.15" + "@babel/preset-typescript" "^7.23.0" + "@babel/register" "^7.22.15" + babel-core "^7.0.0-bridge.0" + chalk "^4.1.2" + flow-parser "0.*" + graceful-fs "^4.2.4" + micromatch "^4.0.4" + neo-async "^2.5.0" + node-dir "^0.1.17" + recast "^0.23.3" + temp "^0.8.4" + write-file-atomic "^2.3.0" + +jsesc@^3.0.2, jsesc@~3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-3.0.2.tgz#bb8b09a6597ba426425f2e4a07245c3d00b9343e" + integrity sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g== + +json-parse-even-better-errors@^2.3.0: + version "2.3.1" + resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz#7c47805a94319928e05777405dc12e1f7a4ee02d" + integrity sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w== + +json5@^2.2.3: + version "2.2.3" + resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.3.tgz#78cd6f1a19bdc12b73db5ad0c61efd66c1e29283" + integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg== + +jsonfile@^6.0.1: + version "6.1.0" + resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-6.1.0.tgz#bc55b2634793c679ec6403094eb13698a6ec0aae" + integrity sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ== + dependencies: + universalify "^2.0.0" + optionalDependencies: + graceful-fs "^4.1.6" + +kind-of@^6.0.2: + version "6.0.3" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd" + integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw== + +kleur@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/kleur/-/kleur-3.0.3.tgz#a79c9ecc86ee1ce3fa6206d1216c501f147fc07e" + integrity sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w== + +lazy-universal-dotenv@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/lazy-universal-dotenv/-/lazy-universal-dotenv-4.0.0.tgz#0b220c264e89a042a37181a4928cdd298af73422" + integrity sha512-aXpZJRnTkpK6gQ/z4nk+ZBLd/Qdp118cvPruLSIQzQNRhKwEcdXCOzXuF55VDqIiuAaY3UGZ10DJtvZzDcvsxg== + dependencies: + app-root-dir "^1.0.2" + dotenv "^16.0.0" + dotenv-expand "^10.0.0" + +leven@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/leven/-/leven-3.1.0.tgz#77891de834064cccba82ae7842bb6b14a13ed7f2" + integrity sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A== + +lines-and-columns@^1.1.6: + version "1.2.4" + resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz#eca284f75d2965079309dc0ad9255abb2ebc1632" + integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg== + +locate-path@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-3.0.0.tgz#dbec3b3ab759758071b58fe59fc41871af21400e" + integrity sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A== + dependencies: + p-locate "^3.0.0" + path-exists "^3.0.0" + +locate-path@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-5.0.0.tgz#1afba396afd676a6d42504d0a67a3a7eb9f62aa0" + integrity sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g== + dependencies: + p-locate "^4.1.0" + +locate-path@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286" + integrity sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw== + dependencies: + p-locate "^5.0.0" + +lodash.debounce@^4.0.8: + version "4.0.8" + resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af" + integrity sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow== + +lodash@^4.17.21: + version "4.17.21" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" + integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== + +log-symbols@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-4.1.0.tgz#3fbdbb95b4683ac9fc785111e792e558d4abd503" + integrity sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg== + dependencies: + chalk "^4.1.0" + is-unicode-supported "^0.1.0" + +loose-envify@^1.0.0, loose-envify@^1.1.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" + integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== + dependencies: + js-tokens "^3.0.0 || ^4.0.0" + +lru-cache@^10.2.0: + version "10.4.3" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-10.4.3.tgz#410fc8a17b70e598013df257c2446b7f3383f119" + integrity sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ== + +lru-cache@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" + integrity sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w== + dependencies: + yallist "^3.0.2" + +lz-string@^1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/lz-string/-/lz-string-1.5.0.tgz#c1ab50f77887b712621201ba9fd4e3a6ed099941" + integrity sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ== + +magic-string@^0.30.0: + version "0.30.12" + resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.30.12.tgz#9eb11c9d072b9bcb4940a5b2c2e1a217e4ee1a60" + integrity sha512-Ea8I3sQMVXr8JhN4z+H/d8zwo+tYDgHE9+5G4Wnrwhs0gaK9fXTKx0Tw5Xwsd/bCPTTZNRAdpyzvoeORe9LYpw== + dependencies: + "@jridgewell/sourcemap-codec" "^1.5.0" + +make-dir@^2.0.0, make-dir@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-2.1.0.tgz#5f0310e18b8be898cc07009295a30ae41e91e6f5" + integrity sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA== + dependencies: + pify "^4.0.1" + semver "^5.6.0" + +make-dir@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.1.0.tgz#415e967046b3a7f1d185277d84aa58203726a13f" + integrity sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw== + dependencies: + semver "^6.0.0" + +makeerror@1.0.12: + version "1.0.12" + resolved "https://registry.yarnpkg.com/makeerror/-/makeerror-1.0.12.tgz#3e5dd2079a82e812e983cc6610c4a2cb0eaa801a" + integrity sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg== + dependencies: + tmpl "1.0.5" + +map-or-similar@^1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/map-or-similar/-/map-or-similar-1.5.0.tgz#6de2653174adfb5d9edc33c69d3e92a1b76faf08" + integrity sha512-0aF7ZmVon1igznGI4VS30yugpduQW3y3GkcgGJOp7d8x8QrizhigUxjI/m2UojsXXto+jLAH3KSz+xOJTiORjg== + +markdown-to-jsx@^7.1.8: + version "7.6.1" + resolved "https://registry.yarnpkg.com/markdown-to-jsx/-/markdown-to-jsx-7.6.1.tgz#048b872fee1cf78d8c8268e30b5ae28335a58b73" + integrity sha512-kZCvhxW70lZQoP3h75piO/CTmDX87jE0aPzw46u7dRZ4AykBYAYbn4Zu3wav0vBzn4PZ8k0kgknVOeEzdBtMPA== + +mdast-util-definitions@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/mdast-util-definitions/-/mdast-util-definitions-4.0.0.tgz#c5c1a84db799173b4dcf7643cda999e440c24db2" + integrity sha512-k8AJ6aNnUkB7IE+5azR9h81O5EQ/cTDXtWdMq9Kk5KcEW/8ritU5CeLg/9HhOC++nALHBlaogJ5jz0Ybk3kPMQ== + dependencies: + unist-util-visit "^2.0.0" + +mdast-util-to-string@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/mdast-util-to-string/-/mdast-util-to-string-1.1.0.tgz#27055500103f51637bd07d01da01eb1967a43527" + integrity sha512-jVU0Nr2B9X3MU4tSK7JP1CMkSvOj7X5l/GboG1tKRw52lLF1x2Ju92Ms9tNetCcbfX3hzlM73zYo2NKkWSfF/A== + +media-typer@0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" + integrity sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ== + +memoizerific@^1.11.3: + version "1.11.3" + resolved "https://registry.yarnpkg.com/memoizerific/-/memoizerific-1.11.3.tgz#7c87a4646444c32d75438570905f2dbd1b1a805a" + integrity sha512-/EuHYwAPdLtXwAwSZkh/Gutery6pD2KYd44oQLhAvQp/50mpyduZh8Q7PYHXTCJ+wuXxt7oij2LXyIJOOYFPog== + dependencies: + map-or-similar "^1.5.0" + +merge-descriptors@1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.3.tgz#d80319a65f3c7935351e5cfdac8f9318504dbed5" + integrity sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ== + +merge-stream@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" + integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== + +merge2@^1.3.0, merge2@^1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" + integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== + +methods@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" + integrity sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w== + +micromatch@^4.0.4: + version "4.0.8" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.8.tgz#d66fa18f3a47076789320b9b1af32bd86d9fa202" + integrity sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA== + dependencies: + braces "^3.0.3" + picomatch "^2.3.1" + +mime-db@1.52.0: + version "1.52.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" + integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== + +"mime-db@>= 1.43.0 < 2": + version "1.53.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.53.0.tgz#3cb63cd820fc29896d9d4e8c32ab4fcd74ccb447" + integrity sha512-oHlN/w+3MQ3rba9rqFr6V/ypF10LSkdwUysQL7GkXoTgIWeV+tcXGA852TBxH+gsh8UWoyhR1hKcoMJTuWflpg== + +mime-types@^2.1.12, mime-types@^2.1.25, mime-types@~2.1.24, mime-types@~2.1.34: + version "2.1.35" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a" + integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== + dependencies: + mime-db "1.52.0" + +mime@1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" + integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== + +mime@^2.0.3: + version "2.6.0" + resolved "https://registry.yarnpkg.com/mime/-/mime-2.6.0.tgz#a2a682a95cd4d0cb1d6257e28f83da7e35800367" + integrity sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg== + +mimic-fn@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" + integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== + +mimic-fn@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-4.0.0.tgz#60a90550d5cb0b239cca65d893b1a53b29871ecc" + integrity sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw== + +minimatch@^3.0.2, minimatch@^3.0.4, minimatch@^3.1.1, minimatch@^3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" + integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== + dependencies: + brace-expansion "^1.1.7" + +minimatch@^5.0.1: + version "5.1.6" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.1.6.tgz#1cfcb8cf5522ea69952cd2af95ae09477f122a96" + integrity sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g== + dependencies: + brace-expansion "^2.0.1" + +minimatch@^9.0.4: + version "9.0.5" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-9.0.5.tgz#d74f9dd6b57d83d8e98cfb82133b03978bc929e5" + integrity sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow== + dependencies: + brace-expansion "^2.0.1" + +minimist@^1.2.5, minimist@^1.2.6: + version "1.2.8" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c" + integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== + +minipass@^3.0.0: + version "3.3.6" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-3.3.6.tgz#7bba384db3a1520d18c9c0e5251c3444e95dd94a" + integrity sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw== + dependencies: + yallist "^4.0.0" + +minipass@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-5.0.0.tgz#3e9788ffb90b694a5d0ec94479a45b5d8738133d" + integrity sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ== + +"minipass@^5.0.0 || ^6.0.2 || ^7.0.0", minipass@^7.1.2: + version "7.1.2" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-7.1.2.tgz#93a9626ce5e5e66bd4db86849e7515e92340a707" + integrity sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw== + +minizlib@^2.1.1: + version "2.1.2" + resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-2.1.2.tgz#e90d3466ba209b932451508a11ce3d3632145931" + integrity sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg== + dependencies: + minipass "^3.0.0" + yallist "^4.0.0" + +mkdirp-classic@^0.5.2: + version "0.5.3" + resolved "https://registry.yarnpkg.com/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz#fa10c9115cc6d8865be221ba47ee9bed78601113" + integrity sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A== + +mkdirp@^0.5.4: + version "0.5.6" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.6.tgz#7def03d2432dcae4ba1d611445c48396062255f6" + integrity sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw== + dependencies: + minimist "^1.2.6" + +mkdirp@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" + integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== + +mlly@^1.7.2: + version "1.7.3" + resolved "https://registry.yarnpkg.com/mlly/-/mlly-1.7.3.tgz#d86c0fcd8ad8e16395eb764a5f4b831590cee48c" + integrity sha512-xUsx5n/mN0uQf4V548PKQ+YShA4/IW0KI1dZhrNrPCLG+xizETbHTkOa1f8/xut9JRPp8kQuMnz0oqwkTiLo/A== + dependencies: + acorn "^8.14.0" + pathe "^1.1.2" + pkg-types "^1.2.1" + ufo "^1.5.4" + +ms@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" + integrity sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A== + +ms@2.1.3, ms@^2.1.3: + version "2.1.3" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" + integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== + +nanoid@^3.3.7: + version "3.3.7" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.7.tgz#d0c301a691bc8d54efa0a2226ccf3fe2fd656bd8" + integrity sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g== + +negotiator@0.6.3: + version "0.6.3" + resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.3.tgz#58e323a72fedc0d6f9cd4d31fe49f51479590ccd" + integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg== + +negotiator@~0.6.4: + version "0.6.4" + resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.4.tgz#777948e2452651c570b712dd01c23e262713fff7" + integrity sha512-myRT3DiWPHqho5PrJaIRyaMv2kgYf0mUVgBNOYMuCH5Ki1yEiQaf/ZJuQ62nvpc44wL5WDbTX7yGJi1Neevw8w== + +neo-async@^2.5.0, neo-async@^2.6.2: + version "2.6.2" + resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f" + integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw== + +node-dir@^0.1.17: + version "0.1.17" + resolved "https://registry.yarnpkg.com/node-dir/-/node-dir-0.1.17.tgz#5f5665d93351335caabef8f1c554516cf5f1e4e5" + integrity sha512-tmPX422rYgofd4epzrNoOXiE8XFZYOcCq1vD7MAXCDO+O+zndlA2ztdKKMa+EeuBG5tHETpr4ml4RGgpqDCCAg== + dependencies: + minimatch "^3.0.2" + +node-fetch-native@^1.6.3: + version "1.6.4" + resolved "https://registry.yarnpkg.com/node-fetch-native/-/node-fetch-native-1.6.4.tgz#679fc8fd8111266d47d7e72c379f1bed9acff06e" + integrity sha512-IhOigYzAKHd244OC0JIMIUrjzctirCmPkaIfhDeGcEETWof5zKYUW7e7MYvChGWh/4CJeXEgsRyGzuF334rOOQ== + +node-fetch@^2.0.0: + version "2.7.0" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.7.0.tgz#d0f0fa6e3e2dc1d27efcd8ad99d550bda94d187d" + integrity sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A== + dependencies: + whatwg-url "^5.0.0" + +node-int64@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b" + integrity sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw== + +node-releases@^2.0.18: + version "2.0.18" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.18.tgz#f010e8d35e2fe8d6b2944f03f70213ecedc4ca3f" + integrity sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g== + +normalize-package-data@^2.5.0: + version "2.5.0" + resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.5.0.tgz#e66db1838b200c1dfc233225d12cb36520e234a8" + integrity sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA== + dependencies: + hosted-git-info "^2.1.4" + resolve "^1.10.0" + semver "2 || 3 || 4 || 5" + validate-npm-package-license "^3.0.1" + +normalize-path@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" + integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== + +npm-run-path@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea" + integrity sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw== + dependencies: + path-key "^3.0.0" + +npm-run-path@^5.1.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-5.3.0.tgz#e23353d0ebb9317f174e93417e4a4d82d0249e9f" + integrity sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ== + dependencies: + path-key "^4.0.0" + +nypm@^0.3.8: + version "0.3.12" + resolved "https://registry.yarnpkg.com/nypm/-/nypm-0.3.12.tgz#37541bec0af3a37d3acd81d6662c6666e650b22e" + integrity sha512-D3pzNDWIvgA+7IORhD/IuWzEk4uXv6GsgOxiid4UU3h9oq5IqV1KtPDi63n4sZJ/xcWlr88c0QM2RgN5VbOhFA== + dependencies: + citty "^0.1.6" + consola "^3.2.3" + execa "^8.0.1" + pathe "^1.1.2" + pkg-types "^1.2.0" + ufo "^1.5.4" + +object-inspect@^1.13.1: + version "1.13.3" + resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.13.3.tgz#f14c183de51130243d6d18ae149375ff50ea488a" + integrity sha512-kDCGIbxkDSXE3euJZZXzc6to7fCrKHNI/hSRQnRuQ+BWjFNzZwiFF8fj/6o2t2G9/jTj8PSIYTfCLelLZEeRpA== + +object-is@^1.1.5: + version "1.1.6" + resolved "https://registry.yarnpkg.com/object-is/-/object-is-1.1.6.tgz#1a6a53aed2dd8f7e6775ff870bea58545956ab07" + integrity sha512-F8cZ+KfGlSGi09lJT7/Nd6KJZ9ygtvYC0/UYYLI9nmQKLMnydpB9yvbv9K1uSkEu7FU9vYPmVwLg328tX+ot3Q== + dependencies: + call-bind "^1.0.7" + define-properties "^1.2.1" + +object-keys@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" + integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== + +object.assign@^4.1.4: + version "4.1.5" + resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.5.tgz#3a833f9ab7fdb80fc9e8d2300c803d216d8fdbb0" + integrity sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ== + dependencies: + call-bind "^1.0.5" + define-properties "^1.2.1" + has-symbols "^1.0.3" + object-keys "^1.1.1" + +ohash@^1.1.3: + version "1.1.4" + resolved "https://registry.yarnpkg.com/ohash/-/ohash-1.1.4.tgz#ae8d83014ab81157d2c285abf7792e2995fadd72" + integrity sha512-FlDryZAahJmEF3VR3w1KogSEdWX3WhA5GPakFx4J81kEAiHyLMpdLLElS8n8dfNadMgAne/MywcvmogzscVt4g== + +on-finished@2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.4.1.tgz#58c8c44116e54845ad57f14ab10b03533184ac3f" + integrity sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg== + dependencies: + ee-first "1.1.1" + +on-headers@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/on-headers/-/on-headers-1.0.2.tgz#772b0ae6aaa525c399e489adfad90c403eb3c28f" + integrity sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA== + +once@^1.3.0, once@^1.3.1, once@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== + dependencies: + wrappy "1" + +onetime@^5.1.0, onetime@^5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e" + integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg== + dependencies: + mimic-fn "^2.1.0" + +onetime@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/onetime/-/onetime-6.0.0.tgz#7c24c18ed1fd2e9bca4bd26806a33613c77d34b4" + integrity sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ== + dependencies: + mimic-fn "^4.0.0" + +open@^8.0.4, open@^8.4.0: + version "8.4.2" + resolved "https://registry.yarnpkg.com/open/-/open-8.4.2.tgz#5b5ffe2a8f793dcd2aad73e550cb87b59cb084f9" + integrity sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ== + dependencies: + define-lazy-prop "^2.0.0" + is-docker "^2.1.1" + is-wsl "^2.2.0" + +ora@^5.4.1: + version "5.4.1" + resolved "https://registry.yarnpkg.com/ora/-/ora-5.4.1.tgz#1b2678426af4ac4a509008e5e4ac9e9959db9e18" + integrity sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ== + dependencies: + bl "^4.1.0" + chalk "^4.1.0" + cli-cursor "^3.1.0" + cli-spinners "^2.5.0" + is-interactive "^1.0.0" + is-unicode-supported "^0.1.0" + log-symbols "^4.1.0" + strip-ansi "^6.0.0" + wcwidth "^1.0.1" + +p-limit@^2.0.0, p-limit@^2.2.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" + integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== + dependencies: + p-try "^2.0.0" + +p-limit@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" + integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== + dependencies: + yocto-queue "^0.1.0" + +p-locate@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-3.0.0.tgz#322d69a05c0264b25997d9f40cd8a891ab0064a4" + integrity sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ== + dependencies: + p-limit "^2.0.0" + +p-locate@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-4.1.0.tgz#a3428bb7088b3a60292f66919278b7c297ad4f07" + integrity sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A== + dependencies: + p-limit "^2.2.0" + +p-locate@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-5.0.0.tgz#83c8315c6785005e3bd021839411c9e110e6d834" + integrity sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw== + dependencies: + p-limit "^3.0.2" + +p-map@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/p-map/-/p-map-4.0.0.tgz#bb2f95a5eda2ec168ec9274e06a747c3e2904d2b" + integrity sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ== + dependencies: + aggregate-error "^3.0.0" + +p-try@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" + integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== + +package-json-from-dist@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz#4f1471a010827a86f94cfd9b0727e36d267de505" + integrity sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw== + +pako@~0.2.0: + version "0.2.9" + resolved "https://registry.yarnpkg.com/pako/-/pako-0.2.9.tgz#f3f7522f4ef782348da8161bad9ecfd51bf83a75" + integrity sha512-NUcwaKxUxWrZLpDG+z/xZaCgQITkA/Dv4V/T6bw7VON6l1Xz/VnrBqrYjZQ12TamKHzITTfOEIYUj48y2KXImA== + +parse-json@^5.0.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-5.2.0.tgz#c76fc66dee54231c962b22bcc8a72cf2f99753cd" + integrity sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg== + dependencies: + "@babel/code-frame" "^7.0.0" + error-ex "^1.3.1" + json-parse-even-better-errors "^2.3.0" + lines-and-columns "^1.1.6" + +parseurl@~1.3.3: + version "1.3.3" + resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" + integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== + +path-exists@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" + integrity sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ== + +path-exists@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" + integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== + +path-is-absolute@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== + +path-key@^3.0.0, path-key@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" + integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== + +path-key@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-4.0.0.tgz#295588dc3aee64154f877adb9d780b81c554bf18" + integrity sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ== + +path-parse@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" + integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== + +path-scurry@^1.11.1: + version "1.11.1" + resolved "https://registry.yarnpkg.com/path-scurry/-/path-scurry-1.11.1.tgz#7960a668888594a0720b12a911d1a742ab9f11d2" + integrity sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA== + dependencies: + lru-cache "^10.2.0" + minipass "^5.0.0 || ^6.0.2 || ^7.0.0" + +path-to-regexp@0.1.10: + version "0.1.10" + resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.10.tgz#67e9108c5c0551b9e5326064387de4763c4d5f8b" + integrity sha512-7lf7qcQidTku0Gu3YDPc8DJ1q7OOucfa/BSsIwjuh56VU7katFvuM8hULfkwB3Fns/rsVF7PwPKVw1sl5KQS9w== + +path-type@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" + integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== + +pathe@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/pathe/-/pathe-1.1.2.tgz#6c4cb47a945692e48a1ddd6e4094d170516437ec" + integrity sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ== + +peek-stream@^1.1.0: + version "1.1.3" + resolved "https://registry.yarnpkg.com/peek-stream/-/peek-stream-1.1.3.tgz#3b35d84b7ccbbd262fff31dc10da56856ead6d67" + integrity sha512-FhJ+YbOSBb9/rIl2ZeE/QHEsWn7PqNYt8ARAY3kIgNGOk13g9FGyIY6JIl/xB/3TFRVoTv5as0l11weORrTekA== + dependencies: + buffer-from "^1.0.0" + duplexify "^3.5.0" + through2 "^2.0.3" + +pend@~1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/pend/-/pend-1.2.0.tgz#7a57eb550a6783f9115331fcf4663d5c8e007a50" + integrity sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg== + +picocolors@^1.0.0, picocolors@^1.1.0, picocolors@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.1.1.tgz#3d321af3eab939b083c8f929a1d12cda81c26b6b" + integrity sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA== + +picomatch@^2.0.4, picomatch@^2.2.3, picomatch@^2.3.0, picomatch@^2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" + integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== + +pify@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/pify/-/pify-4.0.1.tgz#4b2cd25c50d598735c50292224fd8c6df41e3231" + integrity sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g== + +pirates@^4.0.4, pirates@^4.0.6: + version "4.0.6" + resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.6.tgz#3018ae32ecfcff6c29ba2267cbf21166ac1f36b9" + integrity sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg== + +pkg-dir@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-3.0.0.tgz#2749020f239ed990881b1f71210d51eb6523bea3" + integrity sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw== + dependencies: + find-up "^3.0.0" + +pkg-dir@^4.1.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-4.2.0.tgz#f099133df7ede422e81d1d8448270eeb3e4261f3" + integrity sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ== + dependencies: + find-up "^4.0.0" + +pkg-dir@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-5.0.0.tgz#a02d6aebe6ba133a928f74aec20bafdfe6b8e760" + integrity sha512-NPE8TDbzl/3YQYY7CSS228s3g2ollTFnc+Qi3tqmqJp9Vg2ovUpixcJEo2HJScN2Ez+kEaal6y70c0ehqJBJeA== + dependencies: + find-up "^5.0.0" + +pkg-types@^1.2.0, pkg-types@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/pkg-types/-/pkg-types-1.2.1.tgz#6ac4e455a5bb4b9a6185c1c79abd544c901db2e5" + integrity sha512-sQoqa8alT3nHjGuTjuKgOnvjo4cljkufdtLMnO2LBP/wRwuDlo1tkaEdMxCRhyGRPacv/ztlZgDPm2b7FAmEvw== + dependencies: + confbox "^0.1.8" + mlly "^1.7.2" + pathe "^1.1.2" + +polished@^4.2.2: + version "4.3.1" + resolved "https://registry.yarnpkg.com/polished/-/polished-4.3.1.tgz#5a00ae32715609f83d89f6f31d0f0261c6170548" + integrity sha512-OBatVyC/N7SCW/FaDHrSd+vn0o5cS855TOmYi4OkdWUMSJCET/xip//ch8xGUvtr3i44X9LVyWwQlRMTN3pwSA== + dependencies: + "@babel/runtime" "^7.17.8" + +possible-typed-array-names@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz#89bb63c6fada2c3e90adc4a647beeeb39cc7bf8f" + integrity sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q== + +postcss@^8.4.27: + version "8.4.49" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.49.tgz#4ea479048ab059ab3ae61d082190fabfd994fe19" + integrity sha512-OCVPnIObs4N29kxTjzLfUryOkvZEq+pf8jTF0lg8E7uETuWHA+v7j3c/xJmiqpX450191LlmZfUKkXxkTry7nA== + dependencies: + nanoid "^3.3.7" + picocolors "^1.1.1" + source-map-js "^1.2.1" + +prettier@^2.8.0: + version "2.8.8" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.8.8.tgz#e8c5d7e98a4305ffe3de2e1fc4aca1a71c28b1da" + integrity sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q== + +pretty-format@^27.0.2: + version "27.5.1" + resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-27.5.1.tgz#2181879fdea51a7a5851fb39d920faa63f01d88e" + integrity sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ== + dependencies: + ansi-regex "^5.0.1" + ansi-styles "^5.0.0" + react-is "^17.0.1" + +pretty-hrtime@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz#b7e3ea42435a4c9b2759d99e0f201eb195802ee1" + integrity sha512-66hKPCr+72mlfiSjlEB1+45IjXSqvVAIy6mocupoww4tBFE9R9IhwwUGoI4G++Tc9Aq+2rxOt0RFU6gPcrte0A== + +process-nextick-args@~2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" + integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== + +process@^0.11.10: + version "0.11.10" + resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182" + integrity sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A== + +progress@^2.0.1: + version "2.0.3" + resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" + integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== + +prompts@^2.4.0: + version "2.4.2" + resolved "https://registry.yarnpkg.com/prompts/-/prompts-2.4.2.tgz#7b57e73b3a48029ad10ebd44f74b01722a4cb069" + integrity sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q== + dependencies: + kleur "^3.0.3" + sisteransi "^1.0.5" + +proxy-addr@~2.0.7: + version "2.0.7" + resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.7.tgz#f19fe69ceab311eeb94b42e70e8c2070f9ba1025" + integrity sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg== + dependencies: + forwarded "0.2.0" + ipaddr.js "1.9.1" + +proxy-from-env@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz#e102f16ca355424865755d2c9e8ea4f24d58c3e2" + integrity sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg== + +pump@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/pump/-/pump-2.0.1.tgz#12399add6e4cf7526d973cbc8b5ce2e2908b3909" + integrity sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA== + dependencies: + end-of-stream "^1.1.0" + once "^1.3.1" + +pump@^3.0.0: + version "3.0.2" + resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.2.tgz#836f3edd6bc2ee599256c924ffe0d88573ddcbf8" + integrity sha512-tUPXtzlGM8FE3P0ZL6DVs/3P58k9nk8/jZeQCurTJylQA8qFYzHFfhBJkuqyE0FifOsQ0uKWekiZ5g8wtr28cw== + dependencies: + end-of-stream "^1.1.0" + once "^1.3.1" + +pumpify@^1.3.3: + version "1.5.1" + resolved "https://registry.yarnpkg.com/pumpify/-/pumpify-1.5.1.tgz#36513be246ab27570b1a374a5ce278bfd74370ce" + integrity sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ== + dependencies: + duplexify "^3.6.0" + inherits "^2.0.3" + pump "^2.0.0" + +puppeteer-core@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/puppeteer-core/-/puppeteer-core-2.1.1.tgz#e9b3fbc1237b4f66e25999832229e9db3e0b90ed" + integrity sha512-n13AWriBMPYxnpbb6bnaY5YoY6rGj8vPLrz6CZF3o0qJNEwlcfJVxBzYZ0NJsQ21UbdJoijPCDrM++SUVEz7+w== + dependencies: + "@types/mime-types" "^2.1.0" + debug "^4.1.0" + extract-zip "^1.6.6" + https-proxy-agent "^4.0.0" + mime "^2.0.3" + mime-types "^2.1.25" + progress "^2.0.1" + proxy-from-env "^1.0.0" + rimraf "^2.6.1" + ws "^6.1.0" + +qs@6.13.0, qs@^6.10.0: + version "6.13.0" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.13.0.tgz#6ca3bd58439f7e245655798997787b0d88a51906" + integrity sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg== + dependencies: + side-channel "^1.0.6" + +queue-microtask@^1.2.2: + version "1.2.3" + resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" + integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== + +ramda@0.29.0: + version "0.29.0" + resolved "https://registry.yarnpkg.com/ramda/-/ramda-0.29.0.tgz#fbbb67a740a754c8a4cbb41e2a6e0eb8507f55fb" + integrity sha512-BBea6L67bYLtdbOqfp8f58fPMqEwx0doL+pAi8TZyp2YWz8R9G8z9x75CZI8W+ftqhFHCpEX2cRnUUXK130iKA== + +range-parser@~1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" + integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== + +raw-body@2.5.2: + version "2.5.2" + resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.5.2.tgz#99febd83b90e08975087e8f1f9419a149366b68a" + integrity sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA== + dependencies: + bytes "3.1.2" + http-errors "2.0.0" + iconv-lite "0.4.24" + unpipe "1.0.0" + +react-colorful@^5.1.2: + version "5.6.1" + resolved "https://registry.yarnpkg.com/react-colorful/-/react-colorful-5.6.1.tgz#7dc2aed2d7c72fac89694e834d179e32f3da563b" + integrity sha512-1exovf0uGTGyq5mXQT0zgQ80uvj2PCwvF8zY1RN9/vbJVSjSo3fsB/4L3ObbF7u70NduSiK4xu4Y6q1MHoUGEw== + +react-dom@^18.2.0: + version "18.3.1" + resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-18.3.1.tgz#c2265d79511b57d479b3dd3fdfa51536494c5cb4" + integrity sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw== + dependencies: + loose-envify "^1.1.0" + scheduler "^0.23.2" + +react-is@^17.0.1: + version "17.0.2" + resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.2.tgz#e691d4a8e9c789365655539ab372762b0efb54f0" + integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w== + +react-remove-scroll-bar@^2.3.3: + version "2.3.6" + resolved "https://registry.yarnpkg.com/react-remove-scroll-bar/-/react-remove-scroll-bar-2.3.6.tgz#3e585e9d163be84a010180b18721e851ac81a29c" + integrity sha512-DtSYaao4mBmX+HDo5YWYdBWQwYIQQshUV/dVxFxK+KM26Wjwp1gZ6rv6OC3oujI6Bfu6Xyg3TwK533AQutsn/g== + dependencies: + react-style-singleton "^2.2.1" + tslib "^2.0.0" + +react-remove-scroll@2.5.5: + version "2.5.5" + resolved "https://registry.yarnpkg.com/react-remove-scroll/-/react-remove-scroll-2.5.5.tgz#1e31a1260df08887a8a0e46d09271b52b3a37e77" + integrity sha512-ImKhrzJJsyXJfBZ4bzu8Bwpka14c/fQt0k+cyFp/PBhTfyDnU5hjOtM4AG/0AMyy8oKzOTR0lDgJIM7pYXI0kw== + dependencies: + react-remove-scroll-bar "^2.3.3" + react-style-singleton "^2.2.1" + tslib "^2.1.0" + use-callback-ref "^1.3.0" + use-sidecar "^1.1.2" + +react-style-singleton@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/react-style-singleton/-/react-style-singleton-2.2.1.tgz#f99e420492b2d8f34d38308ff660b60d0b1205b4" + integrity sha512-ZWj0fHEMyWkHzKYUr2Bs/4zU6XLmq9HsgBURm7g5pAVfyn49DgUiNgY2d4lXRlYSiCif9YBGpQleewkcqddc7g== + dependencies: + get-nonce "^1.0.0" + invariant "^2.2.4" + tslib "^2.0.0" + +react@^18.2.0: + version "18.3.1" + resolved "https://registry.yarnpkg.com/react/-/react-18.3.1.tgz#49ab892009c53933625bd16b2533fc754cab2891" + integrity sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ== + dependencies: + loose-envify "^1.1.0" + +read-pkg-up@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-7.0.1.tgz#f3a6135758459733ae2b95638056e1854e7ef507" + integrity sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg== + dependencies: + find-up "^4.1.0" + read-pkg "^5.2.0" + type-fest "^0.8.1" + +read-pkg@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-5.2.0.tgz#7bf295438ca5a33e56cd30e053b34ee7250c93cc" + integrity sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg== + dependencies: + "@types/normalize-package-data" "^2.4.0" + normalize-package-data "^2.5.0" + parse-json "^5.0.0" + type-fest "^0.6.0" + +readable-stream@^2.0.0, readable-stream@^2.2.2, readable-stream@~2.3.6: + version "2.3.8" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.8.tgz#91125e8042bba1b9887f49345f6277027ce8be9b" + integrity sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA== + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.3" + isarray "~1.0.0" + process-nextick-args "~2.0.0" + safe-buffer "~5.1.1" + string_decoder "~1.1.1" + util-deprecate "~1.0.1" + +readable-stream@^3.1.1, readable-stream@^3.4.0: + version "3.6.2" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.2.tgz#56a9b36ea965c00c5a93ef31eb111a0f11056967" + integrity sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA== + dependencies: + inherits "^2.0.3" + string_decoder "^1.1.1" + util-deprecate "^1.0.1" + +recast@^0.23.1, recast@^0.23.3: + version "0.23.9" + resolved "https://registry.yarnpkg.com/recast/-/recast-0.23.9.tgz#587c5d3a77c2cfcb0c18ccce6da4361528c2587b" + integrity sha512-Hx/BGIbwj+Des3+xy5uAtAbdCyqK9y9wbBcDFDYanLS9JnMqf7OeF87HQwUimE87OEc72mr6tkKUKMBBL+hF9Q== + dependencies: + ast-types "^0.16.1" + esprima "~4.0.0" + source-map "~0.6.1" + tiny-invariant "^1.3.3" + tslib "^2.0.1" + +regenerate-unicode-properties@^10.2.0: + version "10.2.0" + resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-10.2.0.tgz#626e39df8c372338ea9b8028d1f99dc3fd9c3db0" + integrity sha512-DqHn3DwbmmPVzeKj9woBadqmXxLvQoQIwu7nopMc72ztvxVmVk2SBhSnx67zuye5TP+lJsb/TBQsjLKhnDf3MA== + dependencies: + regenerate "^1.4.2" + +regenerate@^1.4.2: + version "1.4.2" + resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.2.tgz#b9346d8827e8f5a32f7ba29637d398b69014848a" + integrity sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A== + +regenerator-runtime@^0.14.0: + version "0.14.1" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz#356ade10263f685dda125100cd862c1db895327f" + integrity sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw== + +regenerator-transform@^0.15.2: + version "0.15.2" + resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.15.2.tgz#5bbae58b522098ebdf09bca2f83838929001c7a4" + integrity sha512-hfMp2BoF0qOk3uc5V20ALGDS2ddjQaLrdl7xrGXvAIow7qeWRM2VA2HuCHkUKk9slq3VwEwLNK3DFBqDfPGYtg== + dependencies: + "@babel/runtime" "^7.8.4" + +regexp.prototype.flags@^1.5.1: + version "1.5.3" + resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.5.3.tgz#b3ae40b1d2499b8350ab2c3fe6ef3845d3a96f42" + integrity sha512-vqlC04+RQoFalODCbCumG2xIOvapzVMHwsyIGM/SIE8fRhFFsXeH8/QQ+s0T0kDAhKc4k30s73/0ydkHQz6HlQ== + dependencies: + call-bind "^1.0.7" + define-properties "^1.2.1" + es-errors "^1.3.0" + set-function-name "^2.0.2" + +regexpu-core@^6.1.1: + version "6.1.1" + resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-6.1.1.tgz#b469b245594cb2d088ceebc6369dceb8c00becac" + integrity sha512-k67Nb9jvwJcJmVpw0jPttR1/zVfnKf8Km0IPatrU/zJ5XeG3+Slx0xLXs9HByJSzXzrlz5EDvN6yLNMDc2qdnw== + dependencies: + regenerate "^1.4.2" + regenerate-unicode-properties "^10.2.0" + regjsgen "^0.8.0" + regjsparser "^0.11.0" + unicode-match-property-ecmascript "^2.0.0" + unicode-match-property-value-ecmascript "^2.1.0" + +regjsgen@^0.8.0: + version "0.8.0" + resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.8.0.tgz#df23ff26e0c5b300a6470cad160a9d090c3a37ab" + integrity sha512-RvwtGe3d7LvWiDQXeQw8p5asZUmfU1G/l6WbUXeHta7Y2PEIvBTwH6E2EfmYUK8pxcxEdEmaomqyp0vZZ7C+3Q== + +regjsparser@^0.11.0: + version "0.11.2" + resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.11.2.tgz#7404ad42be00226d72bcf1f003f1f441861913d8" + integrity sha512-3OGZZ4HoLJkkAZx/48mTXJNlmqTGOzc0o9OWQPuWpkOlXXPbyN6OafCcoXUnBqE2D3f/T5L+pWc1kdEmnfnRsA== + dependencies: + jsesc "~3.0.2" + +remark-external-links@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/remark-external-links/-/remark-external-links-8.0.0.tgz#308de69482958b5d1cd3692bc9b725ce0240f345" + integrity sha512-5vPSX0kHoSsqtdftSHhIYofVINC8qmp0nctkeU9YoJwV3YfiBRiI6cbFRJ0oI/1F9xS+bopXG0m2KS8VFscuKA== + dependencies: + extend "^3.0.0" + is-absolute-url "^3.0.0" + mdast-util-definitions "^4.0.0" + space-separated-tokens "^1.0.0" + unist-util-visit "^2.0.0" + +remark-slug@^6.0.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/remark-slug/-/remark-slug-6.1.0.tgz#0503268d5f0c4ecb1f33315c00465ccdd97923ce" + integrity sha512-oGCxDF9deA8phWvxFuyr3oSJsdyUAxMFbA0mZ7Y1Sas+emILtO+e5WutF9564gDsEN4IXaQXm5pFo6MLH+YmwQ== + dependencies: + github-slugger "^1.0.0" + mdast-util-to-string "^1.0.0" + unist-util-visit "^2.0.0" + +resolve-from@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-5.0.0.tgz#c35225843df8f776df21c57557bc087e9dfdfc69" + integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw== + +resolve@^1.10.0, resolve@^1.14.2: + version "1.22.8" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.8.tgz#b6c87a9f2aa06dfab52e3d70ac8cde321fa5a48d" + integrity sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw== + dependencies: + is-core-module "^2.13.0" + path-parse "^1.0.7" + supports-preserve-symlinks-flag "^1.0.0" + +restore-cursor@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-3.1.0.tgz#39f67c54b3a7a58cea5236d95cf0034239631f7e" + integrity sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA== + dependencies: + onetime "^5.1.0" + signal-exit "^3.0.2" + +reusify@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" + integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== + +rimraf@^2.6.1: + version "2.7.1" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec" + integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w== + dependencies: + glob "^7.1.3" + +rimraf@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" + integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== + dependencies: + glob "^7.1.3" + +rimraf@~2.6.2: + version "2.6.3" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.3.tgz#b2d104fe0d8fb27cf9e0a1cda8262dd3833c6cab" + integrity sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA== + dependencies: + glob "^7.1.3" + +"rollup@^2.25.0 || ^3.3.0", rollup@^3.27.1: + version "3.29.5" + resolved "https://registry.yarnpkg.com/rollup/-/rollup-3.29.5.tgz#8a2e477a758b520fb78daf04bca4c522c1da8a54" + integrity sha512-GVsDdsbJzzy4S/v3dqWPJ7EfvZJfCHiDqe80IyrF59LYuP+e6U1LJoUqeuqRbwAWoMNoXivMNeNAOf5E22VA1w== + optionalDependencies: + fsevents "~2.3.2" + +run-parallel@^1.1.9: + version "1.2.0" + resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee" + integrity sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA== + dependencies: + queue-microtask "^1.2.2" + +safe-buffer@5.2.1, safe-buffer@~5.2.0: + version "5.2.1" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" + integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== + +safe-buffer@~5.1.0, safe-buffer@~5.1.1: + version "5.1.2" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" + integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== + +"safer-buffer@>= 2.1.2 < 3": + version "2.1.2" + resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" + integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== + +scheduler@^0.23.2: + version "0.23.2" + resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.23.2.tgz#414ba64a3b282892e944cf2108ecc078d115cdc3" + integrity sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ== + dependencies: + loose-envify "^1.1.0" + +"semver@2 || 3 || 4 || 5", semver@^5.6.0: + version "5.7.2" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.2.tgz#48d55db737c3287cd4835e17fa13feace1c41ef8" + integrity sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g== + +semver@^6.0.0, semver@^6.3.0, semver@^6.3.1: + version "6.3.1" + resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4" + integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== + +semver@^7.3.7: + version "7.6.3" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.6.3.tgz#980f7b5550bc175fb4dc09403085627f9eb33143" + integrity sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A== + +send@0.19.0: + version "0.19.0" + resolved "https://registry.yarnpkg.com/send/-/send-0.19.0.tgz#bbc5a388c8ea6c048967049dbeac0e4a3f09d7f8" + integrity sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw== + dependencies: + debug "2.6.9" + depd "2.0.0" + destroy "1.2.0" + encodeurl "~1.0.2" + escape-html "~1.0.3" + etag "~1.8.1" + fresh "0.5.2" + http-errors "2.0.0" + mime "1.6.0" + ms "2.1.3" + on-finished "2.4.1" + range-parser "~1.2.1" + statuses "2.0.1" + +serve-static@1.16.2: + version "1.16.2" + resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.16.2.tgz#b6a5343da47f6bdd2673848bf45754941e803296" + integrity sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw== + dependencies: + encodeurl "~2.0.0" + escape-html "~1.0.3" + parseurl "~1.3.3" + send "0.19.0" + +set-function-length@^1.2.1: + version "1.2.2" + resolved "https://registry.yarnpkg.com/set-function-length/-/set-function-length-1.2.2.tgz#aac72314198eaed975cf77b2c3b6b880695e5449" + integrity sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg== + dependencies: + define-data-property "^1.1.4" + es-errors "^1.3.0" + function-bind "^1.1.2" + get-intrinsic "^1.2.4" + gopd "^1.0.1" + has-property-descriptors "^1.0.2" + +set-function-name@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/set-function-name/-/set-function-name-2.0.2.tgz#16a705c5a0dc2f5e638ca96d8a8cd4e1c2b90985" + integrity sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ== + dependencies: + define-data-property "^1.1.4" + es-errors "^1.3.0" + functions-have-names "^1.2.3" + has-property-descriptors "^1.0.2" + +setprototypeof@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.2.0.tgz#66c9a24a73f9fc28cbe66b09fed3d33dcaf1b424" + integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw== + +shallow-clone@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/shallow-clone/-/shallow-clone-3.0.1.tgz#8f2981ad92531f55035b01fb230769a40e02efa3" + integrity sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA== + dependencies: + kind-of "^6.0.2" + +shebang-command@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" + integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== + dependencies: + shebang-regex "^3.0.0" + +shebang-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" + integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== + +side-channel@^1.0.4, side-channel@^1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.6.tgz#abd25fb7cd24baf45466406b1096b7831c9215f2" + integrity sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA== + dependencies: + call-bind "^1.0.7" + es-errors "^1.3.0" + get-intrinsic "^1.2.4" + object-inspect "^1.13.1" + +signal-exit@^3.0.2, signal-exit@^3.0.3, signal-exit@^3.0.7: + version "3.0.7" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" + integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== + +signal-exit@^4.0.1, signal-exit@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-4.1.0.tgz#952188c1cbd546070e2dd20d0f41c0ae0530cb04" + integrity sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw== + +sisteransi@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/sisteransi/-/sisteransi-1.0.5.tgz#134d681297756437cc05ca01370d3a7a571075ed" + integrity sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg== + +slash@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" + integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== + +source-map-js@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.2.1.tgz#1ce5650fddd87abc099eda37dcff024c2667ae46" + integrity sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA== + +source-map-support@^0.5.16: + version "0.5.21" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.21.tgz#04fe7c7f9e1ed2d662233c28cb2b35b9f63f6e4f" + integrity sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w== + dependencies: + buffer-from "^1.0.0" + source-map "^0.6.0" + +source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" + integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== + +space-separated-tokens@^1.0.0: + version "1.1.5" + resolved "https://registry.yarnpkg.com/space-separated-tokens/-/space-separated-tokens-1.1.5.tgz#85f32c3d10d9682007e917414ddc5c26d1aa6899" + integrity sha512-q/JSVd1Lptzhf5bkYm4ob4iWPjx0KiRe3sRFBNrVqbJkFaBm5vbbowy1mymoPNLRa52+oadOhJ+K49wsSeSjTA== + +spdx-correct@^3.0.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.2.0.tgz#4f5ab0668f0059e34f9c00dce331784a12de4e9c" + integrity sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA== + dependencies: + spdx-expression-parse "^3.0.0" + spdx-license-ids "^3.0.0" + +spdx-exceptions@^2.1.0: + version "2.5.0" + resolved "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz#5d607d27fc806f66d7b64a766650fa890f04ed66" + integrity sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w== + +spdx-expression-parse@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz#cf70f50482eefdc98e3ce0a6833e4a53ceeba679" + integrity sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q== + dependencies: + spdx-exceptions "^2.1.0" + spdx-license-ids "^3.0.0" + +spdx-license-ids@^3.0.0: + version "3.0.20" + resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.20.tgz#e44ed19ed318dd1e5888f93325cee800f0f51b89" + integrity sha512-jg25NiDV/1fLtSgEgyvVyDunvaNHbuwF9lfNV17gSmPFAlYzdfNBlLtLzXTevwkPj7DhGbmN9VnmJIgLnhvaBw== + +sprintf-js@~1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" + integrity sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g== + +statuses@2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/statuses/-/statuses-2.0.1.tgz#55cb000ccf1d48728bd23c685a063998cf1a1b63" + integrity sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ== + +stop-iteration-iterator@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/stop-iteration-iterator/-/stop-iteration-iterator-1.0.0.tgz#6a60be0b4ee757d1ed5254858ec66b10c49285e4" + integrity sha512-iCGQj+0l0HOdZ2AEeBADlsRC+vsnDsZsbdSiH1yNSjcfKM7fdpCMfqAL/dwF5BLiw/XhRft/Wax6zQbhq2BcjQ== + dependencies: + internal-slot "^1.0.4" + +store2@^2.14.2: + version "2.14.3" + resolved "https://registry.yarnpkg.com/store2/-/store2-2.14.3.tgz#24077d7ba110711864e4f691d2af941ec533deb5" + integrity sha512-4QcZ+yx7nzEFiV4BMLnr/pRa5HYzNITX2ri0Zh6sT9EyQHbBHacC6YigllUPU9X3D0f/22QCgfokpKs52YRrUg== + +storybook@^7.2.0: + version "7.6.20" + resolved "https://registry.yarnpkg.com/storybook/-/storybook-7.6.20.tgz#6204ff0c28471536a1a64cb16d1c97872dd33f95" + integrity sha512-Wt04pPTO71pwmRmsgkyZhNo4Bvdb/1pBAMsIFb9nQLykEdzzpXjvingxFFvdOG4nIowzwgxD+CLlyRqVJqnATw== + dependencies: + "@storybook/cli" "7.6.20" + +stream-shift@^1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/stream-shift/-/stream-shift-1.0.3.tgz#85b8fab4d71010fc3ba8772e8046cc49b8a3864b" + integrity sha512-76ORR0DO1o1hlKwTbi/DM3EXWGf3ZJYO8cXX5RJwnul2DEg2oyoZyjLNoQM8WsvZiFKCRfC1O0J7iCvie3RZmQ== + +"string-width-cjs@npm:string-width@^4.2.0": + version "4.2.3" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" + integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.1" + +string-width@^4.1.0, string-width@^4.2.0: + version "4.2.3" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" + integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.1" + +string-width@^5.0.1, string-width@^5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-5.1.2.tgz#14f8daec6d81e7221d2a357e668cab73bdbca794" + integrity sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA== + dependencies: + eastasianwidth "^0.2.0" + emoji-regex "^9.2.2" + strip-ansi "^7.0.1" + +string_decoder@^1.1.1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" + integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== + dependencies: + safe-buffer "~5.2.0" + +string_decoder@~1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" + integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== + dependencies: + safe-buffer "~5.1.0" + +"strip-ansi-cjs@npm:strip-ansi@^6.0.1": + version "6.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" + integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== + dependencies: + ansi-regex "^5.0.1" + +strip-ansi@^6.0.0, strip-ansi@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" + integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== + dependencies: + ansi-regex "^5.0.1" + +strip-ansi@^7.0.1: + version "7.1.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.1.0.tgz#d5b6568ca689d8561370b0707685d22434faff45" + integrity sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ== + dependencies: + ansi-regex "^6.0.1" + +strip-final-newline@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad" + integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA== + +strip-final-newline@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-3.0.0.tgz#52894c313fbff318835280aed60ff71ebf12b8fd" + integrity sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw== + +strip-json-comments@^3.0.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" + integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== + +supports-color@^7.1.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" + integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== + dependencies: + has-flag "^4.0.0" + +supports-color@^8.0.0: + version "8.1.1" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c" + integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== + dependencies: + has-flag "^4.0.0" + +supports-preserve-symlinks-flag@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" + integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== + +synchronous-promise@^2.0.15: + version "2.0.17" + resolved "https://registry.yarnpkg.com/synchronous-promise/-/synchronous-promise-2.0.17.tgz#38901319632f946c982152586f2caf8ddc25c032" + integrity sha512-AsS729u2RHUfEra9xJrE39peJcc2stq2+poBXX8bcM08Y6g9j/i/PUzwNQqkaJde7Ntg1TO7bSREbR5sdosQ+g== + +tar-fs@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/tar-fs/-/tar-fs-2.1.1.tgz#489a15ab85f1f0befabb370b7de4f9eb5cbe8784" + integrity sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng== + dependencies: + chownr "^1.1.1" + mkdirp-classic "^0.5.2" + pump "^3.0.0" + tar-stream "^2.1.4" + +tar-stream@^2.1.4: + version "2.2.0" + resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-2.2.0.tgz#acad84c284136b060dc3faa64474aa9aebd77287" + integrity sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ== + dependencies: + bl "^4.0.3" + end-of-stream "^1.4.1" + fs-constants "^1.0.0" + inherits "^2.0.3" + readable-stream "^3.1.1" + +tar@^6.2.0: + version "6.2.1" + resolved "https://registry.yarnpkg.com/tar/-/tar-6.2.1.tgz#717549c541bc3c2af15751bea94b1dd068d4b03a" + integrity sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A== + dependencies: + chownr "^2.0.0" + fs-minipass "^2.0.0" + minipass "^5.0.0" + minizlib "^2.1.1" + mkdirp "^1.0.3" + yallist "^4.0.0" + +telejson@^7.2.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/telejson/-/telejson-7.2.0.tgz#3994f6c9a8f8d7f2dba9be2c7c5bbb447e876f32" + integrity sha512-1QTEcJkJEhc8OnStBx/ILRu5J2p0GjvWsBx56bmZRqnrkdBMUe+nX92jxV+p3dB4CP6PZCdJMQJwCggkNBMzkQ== + dependencies: + memoizerific "^1.11.3" + +temp-dir@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/temp-dir/-/temp-dir-2.0.0.tgz#bde92b05bdfeb1516e804c9c00ad45177f31321e" + integrity sha512-aoBAniQmmwtcKp/7BzsH8Cxzv8OL736p7v1ihGb5e9DJ9kTwGWHrQrVB5+lfVDzfGrdRzXch+ig7LHaY1JTOrg== + +temp@^0.8.4: + version "0.8.4" + resolved "https://registry.yarnpkg.com/temp/-/temp-0.8.4.tgz#8c97a33a4770072e0a05f919396c7665a7dd59f2" + integrity sha512-s0ZZzd0BzYv5tLSptZooSjK8oj6C+c19p7Vqta9+6NPOf7r+fxq0cJe6/oN4LTC79sy5NY8ucOJNgwsKCSbfqg== + dependencies: + rimraf "~2.6.2" + +tempy@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/tempy/-/tempy-1.0.1.tgz#30fe901fd869cfb36ee2bd999805aa72fbb035de" + integrity sha512-biM9brNqxSc04Ee71hzFbryD11nX7VPhQQY32AdDmjFvodsRFz/3ufeoTZ6uYkRFfGo188tENcASNs3vTdsM0w== + dependencies: + del "^6.0.0" + is-stream "^2.0.0" + temp-dir "^2.0.0" + type-fest "^0.16.0" + unique-string "^2.0.0" + +test-exclude@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-6.0.0.tgz#04a8698661d805ea6fa293b6cb9e63ac044ef15e" + integrity sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w== + dependencies: + "@istanbuljs/schema" "^0.1.2" + glob "^7.1.4" + minimatch "^3.0.4" + +through2@^2.0.3: + version "2.0.5" + resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.5.tgz#01c1e39eb31d07cb7d03a96a70823260b23132cd" + integrity sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ== + dependencies: + readable-stream "~2.3.6" + xtend "~4.0.1" + +tiny-invariant@^1.3.1, tiny-invariant@^1.3.3: + version "1.3.3" + resolved "https://registry.yarnpkg.com/tiny-invariant/-/tiny-invariant-1.3.3.tgz#46680b7a873a0d5d10005995eb90a70d74d60127" + integrity sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg== + +tmpl@1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.5.tgz#8683e0b902bb9c20c4f726e3c0b69f36518c07cc" + integrity sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw== + +to-regex-range@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" + integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== + dependencies: + is-number "^7.0.0" + +tocbot@^4.20.1: + version "4.32.2" + resolved "https://registry.yarnpkg.com/tocbot/-/tocbot-4.32.2.tgz#24d178e5f13b8fea7aeb5393522b67d718e5083c" + integrity sha512-UbVZNXX79LUqMzsnSTwE/YF/PYc2pg3G77D/jcolHd6lmw+oklzfcLtHSsmWBhOf1wfWD1HfYzdjGQef1VcQgg== + +toidentifier@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.1.tgz#3be34321a88a820ed1bd80dfaa33e479fbb8dd35" + integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA== + +tr46@~0.0.3: + version "0.0.3" + resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" + integrity sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw== + +ts-dedent@^2.0.0, ts-dedent@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/ts-dedent/-/ts-dedent-2.2.0.tgz#39e4bd297cd036292ae2394eb3412be63f563bb5" + integrity sha512-q5W7tVM71e2xjHZTlgfTDoPF/SmqKG5hddq9SzR49CH2hayqRKJtQ4mtRlSxKaJlR/+9rEM+mnBHf7I2/BQcpQ== + +tslib@^1.13.0: + version "1.14.1" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" + integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== + +tslib@^2.0.0, tslib@^2.0.1, tslib@^2.1.0, tslib@^2.4.0: + version "2.8.1" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.8.1.tgz#612efe4ed235d567e8aba5f2a5fab70280ade83f" + integrity sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w== + +type-fest@^0.16.0: + version "0.16.0" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.16.0.tgz#3240b891a78b0deae910dbeb86553e552a148860" + integrity sha512-eaBzG6MxNzEn9kiwvtre90cXaNLkmadMWa1zQMs3XORCXNbsH/OewwbxC5ia9dCxIxnTAsSxXJaa/p5y8DlvJg== + +type-fest@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.6.0.tgz#8d2a2370d3df886eb5c90ada1c5bf6188acf838b" + integrity sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg== + +type-fest@^0.8.1: + version "0.8.1" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.8.1.tgz#09e249ebde851d3b1e48d27c105444667f17b83d" + integrity sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA== + +type-fest@^2.19.0: + version "2.19.0" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-2.19.0.tgz#88068015bb33036a598b952e55e9311a60fd3a9b" + integrity sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA== + +type-is@~1.6.18: + version "1.6.18" + resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" + integrity sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g== + dependencies: + media-typer "0.3.0" + mime-types "~2.1.24" + +typedarray@^0.0.6: + version "0.0.6" + resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" + integrity sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA== + +ufo@^1.5.4: + version "1.5.4" + resolved "https://registry.yarnpkg.com/ufo/-/ufo-1.5.4.tgz#16d6949674ca0c9e0fbbae1fa20a71d7b1ded754" + integrity sha512-UsUk3byDzKd04EyoZ7U4DOlxQaD14JUKQl6/P7wiX4FNvUfm3XL246n9W5AmqwW5RSFJ27NAuM0iLscAOYUiGQ== + +uglify-js@^3.1.4: + version "3.19.3" + resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.19.3.tgz#82315e9bbc6f2b25888858acd1fff8441035b77f" + integrity sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ== + +undici-types@~5.26.4: + version "5.26.5" + resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-5.26.5.tgz#bcd539893d00b56e964fd2657a4866b221a65617" + integrity sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA== + +undici-types@~6.19.8: + version "6.19.8" + resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-6.19.8.tgz#35111c9d1437ab83a7cdc0abae2f26d88eda0a02" + integrity sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw== + +unicode-canonical-property-names-ecmascript@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.1.tgz#cb3173fe47ca743e228216e4a3ddc4c84d628cc2" + integrity sha512-dA8WbNeb2a6oQzAQ55YlT5vQAWGV9WXOsi3SskE3bcCdM0P4SDd+24zS/OCacdRq5BkdsRj9q3Pg6YyQoxIGqg== + +unicode-match-property-ecmascript@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz#54fd16e0ecb167cf04cf1f756bdcc92eba7976c3" + integrity sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q== + dependencies: + unicode-canonical-property-names-ecmascript "^2.0.0" + unicode-property-aliases-ecmascript "^2.0.0" + +unicode-match-property-value-ecmascript@^2.1.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.2.0.tgz#a0401aee72714598f739b68b104e4fe3a0cb3c71" + integrity sha512-4IehN3V/+kkr5YeSSDDQG8QLqO26XpL2XP3GQtqwlT/QYSECAwFztxVHjlbh0+gjJ3XmNLS0zDsbgs9jWKExLg== + +unicode-property-aliases-ecmascript@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz#43d41e3be698bd493ef911077c9b131f827e8ccd" + integrity sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w== + +unique-string@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/unique-string/-/unique-string-2.0.0.tgz#39c6451f81afb2749de2b233e3f7c5e8843bd89d" + integrity sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg== + dependencies: + crypto-random-string "^2.0.0" + +unist-util-is@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/unist-util-is/-/unist-util-is-4.1.0.tgz#976e5f462a7a5de73d94b706bac1b90671b57797" + integrity sha512-ZOQSsnce92GrxSqlnEEseX0gi7GH9zTJZ0p9dtu87WRb/37mMPO2Ilx1s/t9vBHrFhbgweUwb+t7cIn5dxPhZg== + +unist-util-visit-parents@^3.0.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/unist-util-visit-parents/-/unist-util-visit-parents-3.1.1.tgz#65a6ce698f78a6b0f56aa0e88f13801886cdaef6" + integrity sha512-1KROIZWo6bcMrZEwiH2UrXDyalAa0uqzWCxCJj6lPOvTve2WkfgCytoDTPaMnodXh1WrXOq0haVYHj99ynJlsg== + dependencies: + "@types/unist" "^2.0.0" + unist-util-is "^4.0.0" + +unist-util-visit@^2.0.0: + version "2.0.3" + resolved "https://registry.yarnpkg.com/unist-util-visit/-/unist-util-visit-2.0.3.tgz#c3703893146df47203bb8a9795af47d7b971208c" + integrity sha512-iJ4/RczbJMkD0712mGktuGpm/U4By4FfDonL7N/9tATGIF4imikjOuagyMY53tnZq3NP6BcmlrHhEKAfGWjh7Q== + dependencies: + "@types/unist" "^2.0.0" + unist-util-is "^4.0.0" + unist-util-visit-parents "^3.0.0" + +universalify@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/universalify/-/universalify-2.0.1.tgz#168efc2180964e6386d061e094df61afe239b18d" + integrity sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw== + +unpipe@1.0.0, unpipe@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" + integrity sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ== + +unplugin@^1.3.1: + version "1.15.0" + resolved "https://registry.yarnpkg.com/unplugin/-/unplugin-1.15.0.tgz#cd1e92e537ab14a03354d6f83f29d536fac2e5a9" + integrity sha512-jTPIs63W+DUEDW207ztbaoO7cQ4p5aVaB823LSlxpsFEU3Mykwxf3ZGC/wzxFJeZlASZYgVrWeo7LgOrqJZ8RA== + dependencies: + acorn "^8.14.0" + webpack-virtual-modules "^0.6.2" + +untildify@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/untildify/-/untildify-4.0.0.tgz#2bc947b953652487e4600949fb091e3ae8cd919b" + integrity sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw== + +update-browserslist-db@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.1.1.tgz#80846fba1d79e82547fb661f8d141e0945755fe5" + integrity sha512-R8UzCaa9Az+38REPiJ1tXlImTJXlVfgHZsglwBD/k6nj76ctsH1E3q4doGrukiLQd3sGQYu56r5+lo5r94l29A== + dependencies: + escalade "^3.2.0" + picocolors "^1.1.0" + +use-callback-ref@^1.3.0: + version "1.3.2" + resolved "https://registry.yarnpkg.com/use-callback-ref/-/use-callback-ref-1.3.2.tgz#6134c7f6ff76e2be0b56c809b17a650c942b1693" + integrity sha512-elOQwe6Q8gqZgDA8mrh44qRTQqpIHDcZ3hXTLjBe1i4ph8XpNJnO+aQf3NaG+lriLopI4HMx9VjQLfPQ6vhnoA== + dependencies: + tslib "^2.0.0" + +use-resize-observer@^9.1.0: + version "9.1.0" + resolved "https://registry.yarnpkg.com/use-resize-observer/-/use-resize-observer-9.1.0.tgz#14735235cf3268569c1ea468f8a90c5789fc5c6c" + integrity sha512-R25VqO9Wb3asSD4eqtcxk8sJalvIOYBqS8MNZlpDSQ4l4xMQxC/J7Id9HoTqPq8FwULIn0PVW+OAqF2dyYbjow== + dependencies: + "@juggle/resize-observer" "^3.3.1" + +use-sidecar@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/use-sidecar/-/use-sidecar-1.1.2.tgz#2f43126ba2d7d7e117aa5855e5d8f0276dfe73c2" + integrity sha512-epTbsLuzZ7lPClpz2TyryBfztm7m+28DlEv2ZCQ3MDr5ssiwyOwGH/e5F9CkfWjJ1t4clvI58yF822/GUkjjhw== + dependencies: + detect-node-es "^1.1.0" + tslib "^2.0.0" + +util-deprecate@^1.0.1, util-deprecate@^1.0.2, util-deprecate@~1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" + integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== + +util@^0.12.4, util@^0.12.5: + version "0.12.5" + resolved "https://registry.yarnpkg.com/util/-/util-0.12.5.tgz#5f17a6059b73db61a875668781a1c2b136bd6fbc" + integrity sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA== + dependencies: + inherits "^2.0.3" + is-arguments "^1.0.4" + is-generator-function "^1.0.7" + is-typed-array "^1.1.3" + which-typed-array "^1.1.2" + +utils-merge@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" + integrity sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA== + +uuid@^9.0.0: + version "9.0.1" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-9.0.1.tgz#e188d4c8853cc722220392c424cd637f32293f30" + integrity sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA== + +validate-npm-package-license@^3.0.1: + version "3.0.4" + resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a" + integrity sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew== + dependencies: + spdx-correct "^3.0.0" + spdx-expression-parse "^3.0.0" + +vary@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" + integrity sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg== + +vite@^4.4.9: + version "4.5.5" + resolved "https://registry.yarnpkg.com/vite/-/vite-4.5.5.tgz#639b9feca5c0a3bfe3c60cb630ef28bf219d742e" + integrity sha512-ifW3Lb2sMdX+WU91s3R0FyQlAyLxOzCSCP37ujw0+r5POeHPwe6udWVIElKQq8gk3t7b8rkmvqC6IHBpCff4GQ== + dependencies: + esbuild "^0.18.10" + postcss "^8.4.27" + rollup "^3.27.1" + optionalDependencies: + fsevents "~2.3.2" + +walker@^1.0.8: + version "1.0.8" + resolved "https://registry.yarnpkg.com/walker/-/walker-1.0.8.tgz#bd498db477afe573dc04185f011d3ab8a8d7653f" + integrity sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ== + dependencies: + makeerror "1.0.12" + +watchpack@^2.2.0: + version "2.4.2" + resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-2.4.2.tgz#2feeaed67412e7c33184e5a79ca738fbd38564da" + integrity sha512-TnbFSbcOCcDgjZ4piURLCbJ3nJhznVh9kw6F6iokjiFPl8ONxe9A6nMDVXDiNbrSfLILs6vB07F7wLBrwPYzJw== + dependencies: + glob-to-regexp "^0.4.1" + graceful-fs "^4.1.2" + +wcwidth@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/wcwidth/-/wcwidth-1.0.1.tgz#f0b0dcf915bc5ff1528afadb2c0e17b532da2fe8" + integrity sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg== + dependencies: + defaults "^1.0.3" + +webidl-conversions@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871" + integrity sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ== + +webpack-virtual-modules@^0.6.2: + version "0.6.2" + resolved "https://registry.yarnpkg.com/webpack-virtual-modules/-/webpack-virtual-modules-0.6.2.tgz#057faa9065c8acf48f24cb57ac0e77739ab9a7e8" + integrity sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ== + +whatwg-url@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d" + integrity sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw== + dependencies: + tr46 "~0.0.3" + webidl-conversions "^3.0.0" + +which-boxed-primitive@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz#13757bc89b209b049fe5d86430e21cf40a89a8e6" + integrity sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg== + dependencies: + is-bigint "^1.0.1" + is-boolean-object "^1.1.0" + is-number-object "^1.0.4" + is-string "^1.0.5" + is-symbol "^1.0.3" + +which-collection@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/which-collection/-/which-collection-1.0.2.tgz#627ef76243920a107e7ce8e96191debe4b16c2a0" + integrity sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw== + dependencies: + is-map "^2.0.3" + is-set "^2.0.3" + is-weakmap "^2.0.2" + is-weakset "^2.0.3" + +which-typed-array@^1.1.13, which-typed-array@^1.1.14, which-typed-array@^1.1.2: + version "1.1.15" + resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.15.tgz#264859e9b11a649b388bfaaf4f767df1f779b38d" + integrity sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA== + dependencies: + available-typed-arrays "^1.0.7" + call-bind "^1.0.7" + for-each "^0.3.3" + gopd "^1.0.1" + has-tostringtag "^1.0.2" + +which@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" + integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== + dependencies: + isexe "^2.0.0" + +wordwrap@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" + integrity sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q== + +"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" + integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + +wrap-ansi@^8.1.0: + version "8.1.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz#56dc22368ee570face1b49819975d9b9a5ead214" + integrity sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ== + dependencies: + ansi-styles "^6.1.0" + string-width "^5.0.1" + strip-ansi "^7.0.1" + +wrappy@1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== + +write-file-atomic@^2.3.0: + version "2.4.3" + resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-2.4.3.tgz#1fd2e9ae1df3e75b8d8c367443c692d4ca81f481" + integrity sha512-GaETH5wwsX+GcnzhPgKcKjJ6M2Cq3/iZp1WyY/X1CSqrW+jVNM9Y7D8EC2sM4ZG/V8wZlSniJnCKWPmBYAucRQ== + dependencies: + graceful-fs "^4.1.11" + imurmurhash "^0.1.4" + signal-exit "^3.0.2" + +write-file-atomic@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-4.0.2.tgz#a9df01ae5b77858a027fd2e80768ee433555fcfd" + integrity sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg== + dependencies: + imurmurhash "^0.1.4" + signal-exit "^3.0.7" + +ws@^6.1.0: + version "6.2.3" + resolved "https://registry.yarnpkg.com/ws/-/ws-6.2.3.tgz#ccc96e4add5fd6fedbc491903075c85c5a11d9ee" + integrity sha512-jmTjYU0j60B+vHey6TfR3Z7RD61z/hmxBS3VMSGIrroOWXQEneK1zNuotOUrGyBHQj0yrpsLHPWtigEFd13ndA== + dependencies: + async-limiter "~1.0.0" + +ws@^8.2.3: + version "8.18.0" + resolved "https://registry.yarnpkg.com/ws/-/ws-8.18.0.tgz#0d7505a6eafe2b0e712d232b42279f53bc289bbc" + integrity sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw== + +xtend@~4.0.1: + version "4.0.2" + resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" + integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ== + +yallist@^3.0.2: + version "3.1.1" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" + integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== + +yallist@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" + integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== + +yauzl@^2.10.0: + version "2.10.0" + resolved "https://registry.yarnpkg.com/yauzl/-/yauzl-2.10.0.tgz#c7eb17c93e112cb1086fa6d8e51fb0667b79a5f9" + integrity sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g== + dependencies: + buffer-crc32 "~0.2.3" + fd-slicer "~1.1.0" + +yocto-queue@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" + integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== diff --git a/flora.cabal b/flora.cabal index db79b121..161c7fd2 100644 --- a/flora.cabal +++ b/flora.cabal @@ -285,6 +285,7 @@ library flora-web FloraWeb.Common.Pagination FloraWeb.Common.Tracing FloraWeb.Common.Utils + FloraWeb.Components.AdvisoryListItem FloraWeb.Components.Alert FloraWeb.Components.Button FloraWeb.Components.CategoryCard @@ -350,6 +351,7 @@ library flora-web , colourista , containers , cookie + , cvss , dani-servant-lucid2 , data-default , deepseq @@ -359,6 +361,7 @@ library flora-web , effectful-plugin , extra , flora + , flora-advisories , flora-jobs , haddock-library , htmx-lucid @@ -499,9 +502,12 @@ executable flora-cli , effectful-core , effectful-plugin , envparse + , extra , filepath , flora + , flora-advisories , flora-web + , hsec-core , log-base , log-effectful , lucid2 @@ -515,11 +521,15 @@ executable flora-cli , text , text-display , time + , tracing + , tracing-effectful , transformers , uuid , vector , zlib + ghc-options: -fplugin=Effectful.Plugin + test-suite flora-test import: common-extensions import: common-ghc-options @@ -537,6 +547,7 @@ test-suite flora-test , effectful-core , effectful-plugin , exceptions + , extra , filepath , flora , flora-advisories diff --git a/guides/github.md b/guides/github.md new file mode 100644 index 00000000..665e7b68 --- /dev/null +++ b/guides/github.md @@ -0,0 +1,157 @@ +# How to secure GitHub repositories + +It is recommended to turn on 2FA for most repositories, especially if building +a package that is a dependency of multiple other packages. Note that this is +not a complete security guarantee, as it can easily be circumvented. + +At least for critical packages, administrators should enable branch +protection: allow only repository owners to merge PRs, and only after CI +passes. Contributors should contribute via forks. It is recommended to +contribute via PRs instead of direct pushes to main branch, even for +repository owners, as this prevents accidental pushes of bad code. Only +repository owners should be able to change the main branch, by merging PRs. + +> [!WARNING] +> It is recommended to run workflows only after the PR has been reviewed. The +> "Require approval for all outside collaborators" setting is the recommended +> one. However, this can cause friction in repositories with a high number of +> PRs but small number of contributors. In this case, if all contributors are +> trusted, "Require approval for first-time contributors" is a valid option, +> but dedicate more efforts to separate sensitive steps into workflows that +> can only run after approval. + +It is ideal to require PR reviews before merging. For security critical +packages, having at least two reviewers is ideal, as this alleviates the risk +of [sock-puppet accounts][sock]. + +To keep dependencies up to date, it is advisable to enable tools such as +[Dependabot][dependabot] or [Renovate][renovate]. These create PRs to update +dependencies and alert on vulnerabilities in dependencies. Both of these tools +can be configured to send a PR at regular intervals (e.g., once a week). + +> [!NOTE] +> Neither [Dependabot][dependabot-2745] nor [Renovate][renovate-8187] +> currently support Haskell dependencies. Use these tools to update +> dependencies from other ecosystems (in multi-language projects). + +For Haskell dependencies, one way to keep them up to date is to use +[haskell-bounds-bump-action][haskell-dep-bump] as a GitHub Action. + +It is recommended to install [Scorecards action][scorecard] for public +repositories and trying to improve the score as high as possible. This is a +scanner for security best practices, most of which are already discussed in +this document. + +## Securing GitHub Actions and GitHub Apps + +It is preferable to use the hosted runners whenever possible. The large +runners supported by GitHub come with usage costs, but are better from the +point of view of supply chain security than hosting your own infrastructure +for CI. + +> [!NOTE] +> If you have the ability to secure your own hosting infrastructure, it is +> feasible to use that instead of GitHub's large hosted runners. + +All GitHub Actions workflows should restrict [permissions][gha-permissions] to +the minimum scope needed. Scope the permissions at job level, instead of at +workflow level. + +``` + check-tests: + permissions: + actions: read +``` + +Minimize usage of actions that create PRs or push code to branch, and review +those that are indispensable for the repository. Thoroughly inspect actions +that can approve PRs and workflows that are triggered after a PR has been +approved (time-of-check-vs-time-of-use type of concerns). Similarly, +thoroughly review any GitHub application (bot, tool) that you use to maintain +the repository (e.g., [mergify][mergify]). + +If using actions which are defined outside of your organisation (that is, +using the `uses` syntax), these should be pinned by commit hash. Don't pin by +version tag as these tags can be forced pushed. The [Scorecards Pinned +Dependencies workflow][scorecard] can help identify which actions should still +be pinned. [Dependabot][dependabot] is able to upgrade the versions of these +actions periodically: + +``` + - name: Upload sdist as an artifact for later jobs in workflow + uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3 + with: + ... +``` + +If secrets are used as arguments to commands for the workflows, pass them via +environment variables. The action log can leak command line arguments! + +If using secrets, these should be scrubbed as soon as they are no longer +needed. Make sure they don't show up in logs, including debug runs of the +workflow! + +Be extra careful of GitHub context variables (e.g., +`github.event.issue.title`) which are vulnerable to command injection attacks. +Don't use these directly in commands. Prefer passing them via environment +variables. Use [Scorecards][scorecard] to identify dangerous workflows. + +Audit carefully all workflows of type `pull_request_target` and +`workflow_run`. For these, don't use secrets at all and separate the sensitive +parts into separate runs. Validate all inputs and only run these workflows on +protected branches. Never use `pull_request_head.ref` as the branch head +reference since this can be updated between the time the PR gets approved and +the time the CI workflow starts executing. + +### Using self-hosted runners + +If using self-hosted runners, create 2 separate pools: one pool to be used +only for CI for PRs and another one to be used for releases and other +sensitive jobs. Ideally, don't share these pools across multiple projects in +the same organisation. + +> [!WARNING] +> Repository-level self-hosted runners are accessible to any workflow in the +> repository. Never trigger a CI job before the PR is reviewed as a PR can +> maliciously alter the workflow to attack the hosted runner. + +Don't allow any secrets in jobs that run in the CI pool. Only use secrets on +the release pool and never trigger jobs on the release pool on code that is +not reviewed. + +Ideally, the self-hosted runners should be ephemeral. Destroy them as soon as +the CI run finishes (see [Github documentation for scripting +this][ephemeral-runner]). If caching between jobs is required, periodically +recycle all runners (e.g., destroy them every week). + +Do not allow writing to the repository from the workflow actions if using +self-hosted runners. A compromise of the runner can result in compromise of +the repository otherwise. + +All CI runners should have a timeout. All workflows that run on CI runners +should not run on forks of the repository. Gate workflow runs by checking the +value of the `github.repository` variable: + +``` +jobs: + build: + if: github.repository == 'haskell/haskell-language-server' # Don't do this in forks +``` + +You can also use `pull_request.author_association` to differentiate between +owners of the project and collaborators added to the project that also have +write access. + +Monitor all activity on the runners and have separate infrastructure to scan +for malicious activity. + +[dependabot-2745]: https://github.com/dependabot/dependabot-core/issues/2745 +[dependabot]: https://github.com/dependabot +[ephemeral-runner]: https://docs.github.com/en/rest/actions/self-hosted-runners?apiVersion=2022-11-28#create-configuration-for-a-just-in-time-runner-for-an-organization +[gha-permissions]: https://docs.github.com/en/actions/using-jobs/assigning-permissions-to-jobs +[haskell-dep-bump]: https://github.com/nomeata/haskell-bounds-bump-action +[mergify]: https://github.com/marketplace/mergify +[renovate-8187]: https://github.com/renovatebot/renovate/issues/8187 +[renovate]: https://github.com/renovatebot/renovate +[scorecard]: https://github.com/ossf/scorecard-action +[sock]: https://en.wikipedia.org/wiki/Sock_puppet_account diff --git a/meeting-notes/2023-05-03.md b/meeting-notes/2023-05-03.md new file mode 100644 index 00000000..88fb42e2 --- /dev/null +++ b/meeting-notes/2023-05-03.md @@ -0,0 +1,170 @@ +# SRT Kickoff Meeting + +## Present + - Mihai Maruseac + - Gautier DI FOLCO + - Tristan de Cacqueray + - Fraser Tweedale + - David Thrane Christiansen + - Casey Mattingly + +## Agenda + +### Communication + +How will the group generally communicate? (any or all of public mailing list, closed mailing list, regular meetings, discourse.haskell.org) + +Mihai: On Tensorflow, we used a private "contact the maintainers" page along with public discussions otherwise + +Casey: Signal or closed mailing list is also OK, but seconds Mihai's suggestion + +GitHub has a private contact info feature now for vulnerabilities. We can use this to talk to project owners. + +Gautier: in OpenBSD, there's RSS feeds for vulnerabilities and fixes. This would be useful. + +Fraser: this is downstream of the repo, and a good way to make the DB more useful. The first thing to work out is how we as a team operate and receive reports. Personally in favor of a mailing list, e.g. security-advisories@haskell.org ? Name not so important as long as it's discoverable and reaches the right people. + +Casey: OK with it + +Tristan: this list is to report vulnerabilities? + +Fraser: yes. This is for things not yet publicly disclosed. It's not our responsiblity to fix the issues, but we can coordinate with maintainers and advise them, prepare advisories for a quick release when things have been made public, and prepare communication if there are any high-severity issues that might need some widespread communication from haskell.org, GHC, HF, etc. Things that we want to get in front of and be more "official" about - we can prepare this in the private channels. + +Casey: To clarify: would it be pertinent to encrypt communications between ourselves? + +Fraser: A private list seems sufficient + +Casey: OK + +Fraser: would rather not deal with the overheads and bootstrapping of GPG keys. + +**Decision**: + * We get a mailing list that the public can post to but only group members can read, for private communication when needed + * Discourse can be used for public communication + * The Github repo will usually receive advisories as pull requests, and most discussions can happen in the open on the PRs + +Tristan: we should have a specified time limit for embargoed information so that vulnerabilities don't stick around too long + +Fraser: this should be transparently documented on the description of how to contact the team (with flexibility for negotiating something else) + +Mihai: Let's use the Project Zero default of 30 days + +**Decision**: 30 day standard embargo unless something else is agreed + +Question: how do we determine what is and is not a vulnerability? + +Casey: Are we working one-on-one as individuals with review by the group, collectively, or some other way? + +Fraser: We should not require an absolute majority, but a lone voice saying "it's a vulnerability" should probably be overridden. Perhaps "more than one" as a standard? + +**Decision**: "More than one" + +## Work assignments / team organisation + +Casey: Work assignment - how do we decide who does what when? Different members of the team have different backgrounds - will it be "whoever volunteers first"? Regular call? + +Tristan: To reach this quorum it will be easiest to do it via PRs or through the mailing list. How do we communicate to the user? Chat or other place to discuss among us? Just comment on the PR? An email seems like it would work for internal confidential communication. + +Fraser: Anything reported in public should have public discussion. Few people should be surprised by having public discussions, and the transparency will likely be appreciated. + +David: would the group like to have a regularly scheduled call? It seems that some people want it, but the email discussion resulted in that being not preferred. + +Casey: calls are useful but OK without them + +Fraser: Definitely not more than fortnightly, but ad-hoc is useful. Better to not require regular meetings, but to be OK to have an irregular meeting if necessary. It seems good to meet once per quarter to check in on the high-level agenda, projects, health, and trends of the team, and to make/approve a quarterly community report. Perhaps start with fortnightly/monthly and reduce as quickly as possible? + +Tristan: has had success in the past with having a regular meeting, but empty agenda means it gets cancelled. + +**Decision**: Start fortnightly, and cancel when no agenda. Keep this slot, and then change as needed. + +### Review design + +History of current design: + +* Requirements: + * GitHub asked "how to dependabot for haskell" + * Checkbox for certifications +* Current design strongly influenced by RustSec, with some differences + * we added CVSS score. Motivation: enable users to express their threat model to silence "false positives" + +How much of David's initial design needs revision? + +Here it is: https://github.com/haskell/security-advisories + + + +Mihai: Suggests using OSV instead: +https://osv.dev/ and schema at https://ossf.github.io/osv-schema/ . Lots of tools already exist that consume this, including Dependabot. There's also the tool Guac that he's working on and can be launched soon. + +Tristan: It looks like Rustsec already works with OSV? + +Mihai: There are converters for lots of formats already and we can send our own + +David: Please feel free to throw away things that I wrote, I'm not at all attached to them + +Fraser: We need to consider the people who are submitting reports, and make sure that it's good for them + +Tristan: The RustSec-inspired format looks good for this, then. + +Comments from Fraser: +* [FT] a way to represent sources other than hackage? (e.g. GHC toolchain, nix, GitHub) +* [FT] a way to annotate Cabal flags that affect the issue? + +Mihai: +1 on both sources and flags. https://github.com/package-url/purl-spec allows unambiguous naming of packages from various sources. + +Fraser: This seems appropriate + +David: The reason for being Hackage-only in the beginning was to keep the scope of the project + +Fraser: It seems at least important at this phase to be able to talk about vulnerabilities in GHC - GHC the library is on hackage, but not e.g. GHCI + +Tristan: It seems unlikely that this is a real problem + +Fraser: Example: there was an issue in GHCI once where it would run arbitrary code in a config file in a directory. Suggests that the team first only admit Hackage packages, but ensure that the schema doesn't tie us down to this. + +Casey: pointed out the difficulties of Nix namespacing + +Mihai: The PURL spec starts with an ecosystem, followed by a specific representation of the package based on the ecosystem + +Casey: Thanks fot the clarification, sounds good + +Tristan: We could have the rule "without a prefix, it's Hackage" and then extend it later. + +Mihai: we could have a default Hackage namespace + +Fraser: we can do much of this work through issues in the repo, and work from there. No need for it to be perfect in the early days - if something needs to change, we just change it. This is cheap while the database is still small. + +Tristan: Should we put the aeson issue in as the first step? + +Fraser: Sounds like a good example. Let's set up the infrastructure, then use the advisory via a PR to test it. We don't want to overburden the team hunting for advisories - we can solicit from the public. + +Tristan: What are our deliverables? Cabal command, website, other? + +Fraser: we don't have to do these things, but we want to facilitate them happening. It'd be fairly straightforward to build a Hakyll site with a feed with recent issues. So our deliverables: + * RSS feed + * The DB itself + * Conversions to things like OSV, maybe (we'll evaluate on case-by-case basis) +Mostly we just curate the DB and keep it useful for downstream tooling, not to develop the tooling itself. We can do it individually but it's not the team's responsibility. + +Tristan: What about a library to load the advisories? + +Fraser: We will have this for our own use anyway, so we can build and maintain it. + +Fraser: How do we assign identifiers to historical advisories? Year of discovery or the year in which the advisory is published? + +Mihai: CVE assignment is based on the year in which the identifier is created + +Fraser: This seems fine, but not good for historical data. + +Casey: Suggestion - track a separate field for "identified" rather than "reported" for metrics purposes + + +### Other business + +None + +### Action items + - David: schedule fortnightly meetings in this slot + - David: Contact haskell.org to create the mailing list `security-advisories@haskell.org` + - Fraser: Will create issues based on the contents of these notes to serve as basis for assigning tasks + - David: figure out how to get the Github permissions to happen diff --git a/meeting-notes/2023-05-17.md b/meeting-notes/2023-05-17.md new file mode 100644 index 00000000..6016af5b --- /dev/null +++ b/meeting-notes/2023-05-17.md @@ -0,0 +1,48 @@ +# SRT 2023-05-17 + +## Preview meeting's Action items + + - David: schedule fortnightly meetings in this slot + - David: Contact haskell.org to create the mailing list security-advisories@haskell.org (TODO) + - Fraser: Will create issues based on the contents of these notes to serve as basis for assigning tasks + - David: figure out how to get the Github permissions to happen + + +## Review open GitHub tickets + +- review open tickets + + +## License for tool source code + +- Decision: BSD-3-Clause +- Advisories themselves remain under Public Domain + +- Labels for issues PRs: + - ones to add: advisory, tools, operations + +## Mailing list + +Question from haskell.org admin: "do you want a genuine mailman list that’s like a google group (only members can post), or an “alias list” that’s just an alias that forwards to a specified set of people?" + +- Casey: prefers proper list with archive. Broad agreement. + +## GitHub automation + +BTW, do we merge PRs manually, or do we use an app/bot such as mergify? + +- FT: I'm for it, but it's not urgent. Get the repo "open for business" first. + +## Nix + +There was a discussion about using it, but not mandating. + +- Agreed. +- FT has a PR relaxing version bounds and adding CI for GHC 8.10 through 9.6. +- https://github.com/blackheaven/security-advisories/blob/tools/introduce-nix/.github/workflows/nix.yml + +## The tool + +- Tristan: What is the scope? +- David: The initial idea is "what RustSec does". Please rewrite it to whatever we need. +- FT: conformance checking and conversions (e.g OSV, HTML, RSS) diff --git a/meeting-notes/2023-05-31.md b/meeting-notes/2023-05-31.md new file mode 100644 index 00000000..232615ee --- /dev/null +++ b/meeting-notes/2023-05-31.md @@ -0,0 +1,56 @@ +# SRT 2023-05-31 + +## Review open tickets + +- **ensure OSV schema compatibility (#3)** +- register HSEC database and hackage ecosystem with OSV (#4) +- update hackage with "report security issue" feature (#7) + - Tristan's update: there is a template, where we can add it. +- add reporting how-to to haskell.org (#8) +- example advisory (#14) + +## Future tasks (no issue yet) + +- **Announcements of security-advisories readiness to receive contributions** +- OSV export +- improving the tooling to "check all" / "render all" +- static site generation / CI/CD for publishing it + +## Directory structure + +- rustsec uses directories for `crates/packagename` and `rust/(rustdoc|std|...)`. We can do similar. +- the CI already supports nested directory +- the only file extension examined is: `*.md` + + +## Ask about cabal.project.freeze + +- it gets in the way of development (for me) as I have different GHC version. +- do we need to keep it? If so, can we mitigate the impact on developers somehow? +- Gautier: it's a way to be in sync with nix, but if the CI does not use it, I guess we can drop it +- Remove it and see if nix build breaks? + +## Tooling to import older CVEs + +- FT: AFAIK it's mostly in blog posts, a few CVE registrations, and tribal knowledge/folklore. There doesn't seem to be much we could do automate that. + + +## Announcing the security-advisories is open for business + +- ASAP, after we are happy with the schema and CI machinery +- Mailing list(s), discourse, reddit +- "official" orgs - Haskell.org, HF + - and their twitter/fediverse accounts, ... + +## ZuriHac + +- Remote participation via discord server +- We should have a security-advisories channel to solicit advisories, and maybe hack on tooling too. +- https://s.surveylegend.com/-NWCiIfeZ0IjuNxEs7CL + +## Other AIs + +- Follow with David about google meet access +- Create issue for zurihac. If we need an impromptu meeting it's ok :) +- Create issue to discuss if/how to represent packages not on hackage (e.g. on GitHub only). + - For example, hackage-server lives on GitHub and makes releases from a branch. If there is an issue, how to represent introduced/fixed versions. How does OSV deal with this scenario? \ No newline at end of file diff --git a/meeting-notes/2023-06-15.md b/meeting-notes/2023-06-15.md new file mode 100644 index 00000000..038e1f7b --- /dev/null +++ b/meeting-notes/2023-06-15.md @@ -0,0 +1,56 @@ +# SRT 2023-06-15 + +## Present + - Gautier + - Casey + - Mihai + - Fraser + - David + +## Apology from David + +David apologized for not being there to let people into the meeting room. He will change the invite to a jit.si link for next time. + +## How to make the announcement + +- official announcement: on discourse +- David: suggests doing so after there are ~5 real advisories in the repo +- We should give a few days heads up to projects that the public might think support it but don't at the start +- Announcement should include: + - Short-term plans (e.g. OSV integration) + - Long-term goals (cabal audit, Stack, Hackage, etc) +- Fraser will draft on mailing list next week + +## Initial content + +- List of known security issues: https://github.com/haskell/security-advisories/issues/32 +- We should validate that the CVSS is correct while creating the advisory, rather than taking it at face value + - Relevant post: https://daniel.haxx.se/blog/2023/06/12/nvd-damage-continued/ + - Fraser plans to work on a CVSS toolkit in Haskell +- David will create one for the TOML parser on Monday + +## ZuriHac + +- a lot of people were excited +- folks wondered why it was empty +- One volunteer pull request + - FT it was a great contribution! +- David's general comments: + - GHC workshop went well + - Getting folks together to contribute to important core stuff is very good. + - Future thoughts: projects for Cabal / Hackage integration. + +## Other community interest +- Casey: Should we look into letting Linux distributions know about us so we can get their reports? + - Fraser: Let's rely on the OSV tooling and hope that projects are consuming those streams. Also, most distros package only the dependencies for particular programs they want (e.g. pandoc) so we would have (a little) extra work to determine which distros are affected by an advisory. + + +# hsec-tools tooling + +- support for multiple references, instead of single-valued "url" field, with the types supported by OSV (e.g. advisory, blog post, etc) +- We presently parse it as CommonMark, but we store the rendered HTML in the advisory datatype. We should instead store the CommonMark, because that's what's needed for OSV. + - Store original text or AST or both? We should try and see. +- Can we migrate to `pandoc-types`? David didn't pick them to avoid GPL constraints, but it seems that the Pandoc integration is doable with BSD after all (the types package is BSD3). We should migrate. +- *pandoc* is GPL, so static site builder w/ Hakyll needs to be a separate package under GPL, which consumes our libraries. +- We should (not urgent) extract OSV bits to a dedicated package. +- FT plans to write a CVSS library. \ No newline at end of file diff --git a/meeting-notes/2023-06-28.md b/meeting-notes/2023-06-28.md new file mode 100644 index 00000000..dab5f053 --- /dev/null +++ b/meeting-notes/2023-06-28.md @@ -0,0 +1,61 @@ +# SRT 2023-06-28 + +## Previous Action Items + +- Fraser did not yet draft the SRT announcement +- We still have several known issues yet to have the advisories submitted + +## Library advisory role-play + +- For multiple affected packages, where root cause is in a + lower-level dependency: we MUST mention the "root" package, and + SHOULD mention dependent packages that specifically mitigate the + issue. So that tooling (e.g. cabal audit) can deduce that the + issue is not occurring. + + - Upcoming "vex" standard: + - https://blog.adolus.com/what-is-vex-and-what-does-it-have-to-do-with-sboms + - https://cyclonedx.org/capabilities/vex/ + + +## OSV export + +- demo +- branch name + - **decision: `generated/osv-export`** +- git "user id" (name and email address) + - Haskell Security Response Team +- commit message + - currently just the timestamp + - could include a reference to commit ID and/or commit message from the `main` branch + - **Decision**: include source commit ID in OSV branch commit message +- Casey: what about signing the commits? + - FT: then the private key needs to live in GitHub secrets. Not thrilled about it. + - sigstore? What sort of GitHub actions integration do they have? + - https://github.com/sigstore/gitsign + - **Decision: investigate further** + + +## Real advisories +(redacted) + +## Distributor notification + +- We should have a directory of important distributors so that they can + respond to issues. + - Commit the checklist / playbook to the repo. + - **Owner: Tristan** +- Who: + - Stack, GHCup, haskell-ci? + - Linux distros + +## Advisory "official launch" + +- still needs to draft announcement (David will draft and send to mailing list) +- Also need to do quarterly report, so can roll them into one announcement :) + +## Action items + - Tristan: will adapt responsible disclosure instructions + - Fraser: complete OSV data export CI action + - David: will draft announcement/report for group + - Tristan: Will email mailing list about **** issue and affected packages diff --git a/meeting-notes/2023-07-12.md b/meeting-notes/2023-07-12.md new file mode 100644 index 00000000..70b51c6b --- /dev/null +++ b/meeting-notes/2023-07-12.md @@ -0,0 +1,39 @@ +# SRT 2023-07-12 + +[Previous meeting](https://github.com/haskell/security-advisories/blob/main/meeting-notes/2023-06-28.md) + +## Previous Items + + * Fraser sent the announcement/Q2 report - we are officially launched! + * Tristan: will adapt responsible disclosure instructions - merged! + * We do need to collect emails of packagers - Mihai will probably have them by tomorrow + * We need a process update that specifies a collaboration with maintainers where they ensure patches apply cleanly and approve everything + * Fraser: complete OSV data export CI action + * Works on the test instance, waiting for review from OSV: https://github.com/haskell/security-advisories/tree/generated/osv-export/2023 + * Tristan: Will email mailing list about issue and affected packages Disclosure + +## Switch TOML libraries? + +We were sent a patch to use a different TOML parser by its author. David will get back to the author and ask him for a PR + - Advantages: It can output TOML (nice in case of schema upgrades) and it lets us delete a little code + +## GHC issue 23538 +https://gitlab.haskell.org/ghc/ghc/-/issues/23538 + +David will ask GHC developers about an advisory + +## Example roleplay (PR #56) +https://github.com/haskell/security-advisories/pull/56 + +David submitted and got CI to pass. +Process issues: + * CVSS didn´t get checked, and David didn't know what to do - ask for screenshot of CVSS calculator? + * Can we make a GitHub bot that creates a verbose table from a CVSS vector in a PR? + * PR isn't merged + * What about a bot that merges anything approved? We can just use an existing one. + +## Action Items + - Tristan: will create an issue about using the declaration field in the schema for tooling + - David will ask GHC about a base advisory + - David will ask the TOML library author for a PR + - Mihai will get the rest of the package maintainer emails diff --git a/meeting-notes/2023-07-26.md b/meeting-notes/2023-07-26.md new file mode 100644 index 00000000..c33f33d4 --- /dev/null +++ b/meeting-notes/2023-07-26.md @@ -0,0 +1,59 @@ +# SRT 2023-07-26 + +## osv.dev + +- Hackage advisories are in production now +- Version enumeration for Hackage and GHC was merged +- Outstanding task: add examples to osv-schema + - Mihai has PR in the works + +## Update on handling embargoed stuff + +- Gathering contact points for downstream +- Someone needs to connect the dots to send messages +- Contact list needs to be committed somewhere + - Private contacts not be in the repo... so where? + - Stored encrypted version in the security-advisories repo? + - no + - Use HF bitwarden account? (access/modify via HF admin access) + - agreed + +## What should be part of the database format? + +- Repo data storage / semantics. David has some concerns: + - Symlinks. Doesn't work well on Windows? + - dates being stored in Git repo + +## Audit GHCup download practices + +- https://github.com/haskell/ghcup-hs/issues/858 +- FT's comments: https://github.com/haskell/ghcup-hs/issues/858#issuecomment-1639300092 + +## Reserving HSEC IDs + +- It would be useful to be able to reserve an HSEC ID +- FT will propose a way to do it (discuss it in a GH issue) + +## Any other known historical (or current) issues? + +- Pandoc + - https://nvd.nist.gov/vuln/detail/CVE-2023-38745 + - https://nvd.nist.gov/vuln/detail/CVE-2023-35936 + +## Action items + - Mihai + - Will follow up for project contacts for embargoed issues + - Look into GHCup #858 + - Everyone + - Send David the email address used by your Bitwarden account + so it can be added to HF's organization. + - FT + - Documentation of repo structure, including symlinks + - Documentation about dates - that they are retieved from Git history + - full history required, not shallow clone + - Create GH issue to design HSEC ID reservation feature + - re Base readFloat, update bgamari that advisory exists + - ping pandoc folks, ask them to submit advisories + - someone + - Requirements/guidelines for dependency analysis tooling + - Start writing them down, commit to our repo diff --git a/meeting-notes/2023-08-09.md b/meeting-notes/2023-08-09.md new file mode 100644 index 00000000..59e15363 --- /dev/null +++ b/meeting-notes/2023-08-09.md @@ -0,0 +1,71 @@ +# SRT meeting 2023-08-09 + +[Previous meeting notes](https://github.com/haskell/security-advisories/blob/main/meeting-notes/2023-07-26.md) + +## Previous AIs: + + - Mihai + - Will follow up for project contacts for embargoed issues + - Look into GHCup #858 -- still in progress + - Everyone + - Send David the email address used by your Bitwarden account + so it can be added to HF's organization. + - FT + - Documentation of repo structure, including symlinks + - Documentation about dates - that they are retieved from Git history + - full history required, not shallow clone + - Create GH issue to design HSEC ID reservation feature + - re Base readFloat, update bgamari that advisory exists + - ping pandoc folks, ask them to submit advisories + - someone + - Requirements/guidelines for dependency analysis tooling + - Start writing them down, commit to our repo + +## Pandoc + +- New pandoc issue: https://github.com/jgm/pandoc/security/advisories/GHSA-xj5q-fv23-575g +- Related issue: https://github.com/jgm/pandoc/issues/8584 +- Security section of manual: https://pandoc.org/MANUAL.html#a-note-on-security + + +## Recording affected symbols + +- Tristan looking into it +- Some doubts about how to record e.g. type class instances +- GitHub issue we can use for discussion: https://github.com/haskell/security-advisories/issues/86 *"Leverage the declaration field to specify which function is affected"* + + +## ID reservation + +- PR: https://github.com/haskell/security-advisories/pull/114 +- `hsec-tools reserve-id --assign --commit` +- TODO: add diagnostic output e.g. "Reserved HSEC-YYYY-NNNN.md" + + +## Publishing hsec-tools to hackage? + +- We should probably do it some time :) +- Maybe extract OSV library first, and land the toml library change first + +## Purl parsing + +- [spec](https://github.com/package-url/purl-spec) +- [Hackage](https://github.com/package-url/purl-spec/blob/master/PURL-TYPES.rst#hackage) +- Casey started work on this +- We should define and propose to haskell community a *profile* of Purl, in particular how to represent + - Package components (`lib`, `exe:`, `lib:`) + - Cabal flags (`[+-]`) + - There is a hackage namespace defined for Purl, but it does not suggest how to represent these data + + +## Action Items + - Bitwarden accounts? + - Mihai: + - Progress on embargoed items + - Look into GHCup #858 -- still in progress + - Tristan: rebase the toml-parser PR#88 + + - David: Encourage Pandoc devs to test out our advisory process + - FT: Documentation of repo structure + - FT: Diagnostic output (created file XYZ) + - FT to publish PR for (currently WIP) enhancement to record package components in HSEC security-advisories diff --git a/meeting-notes/2023-08-23.md b/meeting-notes/2023-08-23.md new file mode 100644 index 00000000..4e4aa449 --- /dev/null +++ b/meeting-notes/2023-08-23.md @@ -0,0 +1,43 @@ +# SRT 2023-08-23 + +[Previous meeting](https://github.com/haskell/security-advisories/blob/main/meeting-notes/2023-08-09.md) + +Present: + * Gautier + * Mihai + * Casey + * Tristan + * david + +# Previous action items + + +* Bitwarden accounts? + * Mihai and Casey have access and are confirmed + +* Mihai: + + * Progress on embargoed items + * The repo now contains the distribution list for who to send embargoed items to + * Look into GHCup #858 -- still in progress + * Mostly done, need to decide whether to send private email or reply on issue + +* Tristan: rebase the toml-parser PR#88 + * Done, this is now ready to review + +* David: Encourage Pandoc devs to test out our advisory process + * Done: HSEC-2023-0014 + +* FT: Documentation of repo structure + +* FT: Diagnostic output (created file XYZ) + +* FT to publish PR for (currently WIP) enhancement to record package components in HSEC security-advisories + +# HSEC-2023-0014 + +* First advisory contribution: https://github.com/haskell/security-advisories/pull/115 + +# CWE Library + +* Tristan proposed a new library to resolve CWE id and make advisory more readable: https://github.com/haskell/security-advisories/pull/116 diff --git a/meeting-notes/2023-09-20.md b/meeting-notes/2023-09-20.md new file mode 100644 index 00000000..ba9754c6 --- /dev/null +++ b/meeting-notes/2023-09-20.md @@ -0,0 +1,14 @@ +- SRT 2023/09/20 + +# Present +- Gautier +- Mihai +- David +- Casey + +# hsec-tools +- casey: need to rebase changes in regarding purl spec code and sync up with Frasier about his comments about the specification. +- mihai: embargo status and still working on GHCup review + +# security scanner +- david: had a conversation about the need for a security scanner. diff --git a/meeting-notes/2023-10-04.md b/meeting-notes/2023-10-04.md new file mode 100644 index 00000000..1267891b --- /dev/null +++ b/meeting-notes/2023-10-04.md @@ -0,0 +1,15 @@ +- SRT 2023/10/04 + +# Present +- Gautier +- Tristan + +# Pull-Requests +- Gautier: many PRs are stalling, while being approved +- Gautier: rebase PRs and merge them if there are enough approval + +# Embargo update +- Tristan: still waiting for upstream release, should we make the advisory public? + +# Action items +- Let's merge the open PR unless there is an objections diff --git a/meeting-notes/2023-10-18.md b/meeting-notes/2023-10-18.md new file mode 100644 index 00000000..5db6bd1a --- /dev/null +++ b/meeting-notes/2023-10-18.md @@ -0,0 +1,32 @@ +# SRT meeting 2023-10-18 + +[Previous meeting notes](https://github.com/haskell/security-advisories/blob/main/meeting-notes/2023-10-04.md) + +## Present + +- Tristan, Gautier and Fraser + +## Previous AIs + +- PR have been merged + +## Remaining work to be merged + +- CWE and CVSS validation and data type +- Work on GitHub workflow automation enhancement can proceed when this has been merged. + - FT: As far as I know, we have to pursue a webhook or "bot" approach + rather than exeucting behaviour within webhooks, because PRs from + forks do not have privileged tokens. + - Tristan: what about issues? Do actions triggered by issues have the needed permissions? + - OpenStack CI has a concept of config job which can run with privileged on untrusted project. + +## Downstream tooling + +- David's post calling for action: + https://discourse.haskell.org/t/would-you-like-to-write-a-security-advisory-analyzer/7638 +- Gautier: community contribution that was merged as part of the `check` command: https://github.com/blackheaven/security-advisories/pull/2 + +## Outstanding embargoed issue + +- Follow up with Mihai if he knows the status. We might + set a date for disclosure and advise downstream and upstream diff --git a/meeting-notes/2023-11-01.md b/meeting-notes/2023-11-01.md new file mode 100644 index 00000000..e0d6474b --- /dev/null +++ b/meeting-notes/2023-11-01.md @@ -0,0 +1,27 @@ +# SRT meeting 2023-11-01 + +Previous notes: https://edit.smart-cactus.org/cpEZf5ykQZGowfAzI3OPcA?both# + +## Present + +- Tristan, Gautier and Fraser + + +## CVSS + +- Tristan is working through the TODOs. + +## GitHub automation + +- Fraser is hoping to start work during the next 2 weeks. + + +## Outstanding embargoed issue + +- Follow up with Mihai if he knows the status. We might + set a date for disclosure and advise downstream and upstream + +## Quarterly report + +- We are overdue for the Q3 report. Fraser will draft + a report in the next period. \ No newline at end of file diff --git a/meeting-notes/2023-11-15.md b/meeting-notes/2023-11-15.md new file mode 100644 index 00000000..296370b6 --- /dev/null +++ b/meeting-notes/2023-11-15.md @@ -0,0 +1,31 @@ +# SRT meeting 2023-11-15 + +Previous notes: https://github.com/haskell/security-advisories/blob/main/meeting-notes/2023-11-01.md + +## Previous AIs + +- FT still need to write up (overdue) quarterly report + +## cabal-install issue + +- It is now public and the HSEC advisory created. + - https://osv.dev/vulnerability/HSEC-2023-0015 + +## Purl-spec refinements + +- https://github.com/haskell/security-advisories/issues/102 +- This work should resume soon + +## Website + +- https://github.com/haskell/security-advisories/issues/31 +- Where to publish + - GitHub pages, and ask haskell.org for a subdomain? + - Gautier will handle GitHub pages publication + - **AI**: Mihai will ask. + +## VEX + +## New HF ED + +- FT will sync with Jose and let him know what we're up to. diff --git a/meeting-notes/2023-11-29.md b/meeting-notes/2023-11-29.md new file mode 100644 index 00000000..3fc2d216 --- /dev/null +++ b/meeting-notes/2023-11-29.md @@ -0,0 +1,26 @@ +# SRT meeting 2023-11-29 + +Previous meeting notes: +https://github.com/haskell/security-advisories/blob/main/meeting-notes/2023-11-15.md + +## Previous AIs + +- Website - generation and pushing to `generated/gh-pages` is done. + But it is not being published as expected. Investigation ongoing. +- FT synced with Jose. +- "Quarterly" report still TODO + +## Purl-spec refinements + +- https://github.com/haskell/security-advisories/issues/102 +- Casey: should be happening soon + +## GitHub tooling + +- FT hoping to start over Christmas break + +## Libraries + +- Still plan to do OSV extration. +- Still plan to extract our core Advisory types and parsing/printing. +- Publishing our libs on Hackage. diff --git a/meeting-notes/2023-12-13.md b/meeting-notes/2023-12-13.md new file mode 100644 index 00000000..dc55b7c2 --- /dev/null +++ b/meeting-notes/2023-12-13.md @@ -0,0 +1,20 @@ +# SRT meeting 2023-12-13 + +Previous meeting notes: https://github.com/haskell/security-advisories/blob/main/meeting-notes/2023-11-29.md + +## Previous AIs + +- Website publication (from https://github.com/haskell/security-advisories/tree/generated/gh-pages ) +- "Quarterly" report still TODO + +## OSV output fixed + +- Reported by a community member: https://github.com/haskell/security-advisories/issues/135 + +## Website + +- Need to request the creation of this repository: https://github.com/haskell/haskell.github.io + +## CWE data type + +- TC: to add osv export golden test and rebase the PR diff --git a/meeting-notes/2024-01-10.md b/meeting-notes/2024-01-10.md new file mode 100644 index 00000000..e9a089db --- /dev/null +++ b/meeting-notes/2024-01-10.md @@ -0,0 +1,31 @@ +# SRT meeting 2024-01-10 + +Previous meeting notes: https://github.com/haskell/security-advisories/blob/main/meeting-notes/2023-12-13.md + + +## 2023 H2 report + +- Draft sent to list; thanks for reviews. FT will publish today. + +## ZuriHac plans + +- We agree it's a good idea to have a project, e.g. `cabal audit`, Hackage server. +- Timeline: Jan for concept, March for concrete budget. +- Jose has contact points with cabal-install and HLS. hackage-server seems somewhat unloved. +- Maybe we prioritise getting hackage-server attention? + - Many security improvment should/could be done (e.g. 2FA) +- Can continue the discussion on list or GH issue (public). + +## Oustanding PRs + +- CWE library support. + +## Downstream toolling + +- Tristan already started something regarding tracking function calls +https://github.com/TristanCacqueray/cabal-audit +- Support to suppress false positives will be important, esp. because we have >0 advisories for *base*. This could be VEX and/or some other mechanism. + +## Publishing the HTML advisory index + +- Mihai: I was planning to look into the GHA but didn't get a chance yet diff --git a/meeting-notes/2024-01-24.md b/meeting-notes/2024-01-24.md new file mode 100644 index 00000000..bda77d2b --- /dev/null +++ b/meeting-notes/2024-01-24.md @@ -0,0 +1,18 @@ +# SRT meeting 2024-01-24 + +Previous meeting notes: https://github.com/haskell/security-advisories/blob/main/meeting-notes/2024-01-10.md + +## Undisclosed security issue + +- Received via the mailing-list + - the reporter was unable to send the full report (the PDF is too big) +- Gautier has contacted the maintainers. + +## WebSite got published + +Initial version is now available at: https://haskell.github.io/security-advisories/ + +## Report got published + +The H2 report has been published on discourse: +https://discourse.haskell.org/t/haskell-security-response-team-2023-july-december-report/8531 diff --git a/meeting-notes/2024-02-07.md b/meeting-notes/2024-02-07.md new file mode 100644 index 00000000..55185031 --- /dev/null +++ b/meeting-notes/2024-02-07.md @@ -0,0 +1,22 @@ +# SRT meeting 2024-02-07 + +Previous meeting notes: +https://github.com/haskell/security-advisories/blob/main/meeting-notes/2024-01-24.md + +## Ongoing security issue (embargoed) + +- SRT agrees it matters, but it is out of our hands. +- All we can do is make recommendations. +- Mihai will lead response. + +## hackage-server + +- Gautier filed a PR adding link to security-advisories repo: + https://github.com/haskell/hackage-server/pull/1292 + +## Small CLI improvements + +- A community member worked on small fix in + [#147](https://github.com/haskell/security-advisories/pull/147) and + bootstrapped the cabal audit command in + [#148](https://github.com/haskell/security-advisories/pull/148). diff --git a/meeting-notes/2024-02-21.md b/meeting-notes/2024-02-21.md new file mode 100644 index 00000000..fcebdd90 --- /dev/null +++ b/meeting-notes/2024-02-21.md @@ -0,0 +1,17 @@ +# SRT meeting 2024-02-21 + +Previous meeting notes: +https://github.com/haskell/security-advisories/blob/main/meeting-notes/2024-02-07.md + +## Ongoing security issue (embargoed) + +- Mihai wits for Google approval to share the guidelines (hopefully today or tomorrow) + +## Small CLI improvements + +- [#148](https://github.com/haskell/security-advisories/pull/148) some progress have been made, but the PR is still in draft + +## ZuriHac workshop + +- Two days has been nearly filled +- Jose will coordinate HRT and Hackage team diff --git a/meeting-notes/2024-03-06.md b/meeting-notes/2024-03-06.md new file mode 100644 index 00000000..f164a36e --- /dev/null +++ b/meeting-notes/2024-03-06.md @@ -0,0 +1,33 @@ +# SRT meeting 2024-03-06 + +- Previous meeting: + https://github.com/haskell/security-advisories/blob/main/meeting-notes/2024-02-21.md + +## pre-ZuriHac ecosystem workshop + +- 6-7 June (before ZuriHac) +- https://haskell.foundation/events/2024-haskell-ecosystem-workshop.html +- Registration is open; fee can be waived for SRT members +- SRT members attending: + - Gautier confirmed, others looking into it. + - Jose wants all of us to attend, if we can. + Other SRT members want to come but need to work out if we can. + + +## Other updates (things that happened) + +- Update hsec-tools to toml-parser v2 +- Fixed web advisory index publishing. +- One historical advisory added (external contributor) +- Mihai has approval to publish the GHA documentation/guide. + He will send to SRT list first, then to researcher. + +## Outstanding PRs + +- CWE module + ([#116](https://github.com/haskell/security-advisories/pull/116)) + +## Other work to be done + +- Publishing our libraries on Hackage. +- What is the state of our package docs? Might need some work... diff --git a/meeting-notes/2024-03-20.md b/meeting-notes/2024-03-20.md new file mode 100644 index 00000000..cc4e863a --- /dev/null +++ b/meeting-notes/2024-03-20.md @@ -0,0 +1,16 @@ +# SRT meeting 2024-03-20 + +- Previous meeting: + https://github.com/haskell/security-advisories/blob/main/meeting-notes/2024-03-20.md + +## Code update + +- We implemented an atom feed in [#160](https://github.com/haskell/security-advisories/pull/157): https://haskell.github.io/security-advisories/atom.xml +- We added a CAPEC field in [#164](https://github.com/haskell/security-advisories/pull/164). +- The command line to check a given project is taking shape in [#148](https://github.com/haskell/security-advisories/pull/148). +- The CWE module is still up for review ([#116](https://github.com/haskell/security-advisories/pull/116)). + +## Advisory update + +- We published HSEC-2024-0002 quickly after the initial report ([#157](https://github.com/haskell/security-advisories/pull/157)). +- We are coordinating a new issue reported via the mailing-list. diff --git a/meeting-notes/2024-04-03.md b/meeting-notes/2024-04-03.md new file mode 100644 index 00000000..5cd3d9a3 --- /dev/null +++ b/meeting-notes/2024-04-03.md @@ -0,0 +1,68 @@ +# SRT meeting 2024-04-03 + +Previous meeting notes: +https://github.com/haskell/security-advisories/blob/main/meeting-notes/2024-03-20.md + +## ZuriHac / Haskell Ecosystem Workshop + +- Fraser is going +- Gautier is going +- Mihai will know on Friday if he is attending +- Tristan cannot attend + +## Quarterly report + +- Draft: https://github.com/haskell/security-advisories/pull/180 +- FT asked Mihai to contribute a section for the CI security + recommendations. + +## VINCE + +- FT reached out to CERT/CC to ask for help +- `security-advisories@haskell.org` is notification-only. +- We should make individual accounts (TOTP required) and they can be + associated with the "Haskell Programming Language" org within + VINCE. + +## GitHub Actions Runners + +- The reporter was asking what the resolution was. +- Mihai will create a PR with the guidelines documentation and + contact the repo and reporter. +- We cannot fix globally because there is not a single org with all + the Haskell. But we can provide the guidance and recommendations + to the community. + +## A "security" section within haskell.org + +- Jose: Is there a place for collecting ecosystem-wide best + practices? (whether for security, or more generally) +- We would like a section within haskell.org where our + recommendations and info about the advisory DB lives. A more + "official" documentation about Haskell security and the SRT. +- Perhaps also the wiki. + +## liblzma/xz vulnerability? + +- The backdoor was inserted using binary data from test suite, and + only during RPM/.deb builds. Even if code was lifted and used in + cbits, the backdoor probably would not be there. +- But we should still verify. FT will ask Casey. + +## yaml vulnerability + +- Impact and exploitability vector are not clear enough to offer + remediation advice. +- FT will create the advisory. +- We need to check if other yaml packages are affected. + +## Pull requests + +- [cabal audit (#148)](https://github.com/haskell/security-advisories/pull/148) + - The author is keen on making changes if any more feedback + - He is afraid of going forward with other contributions if he has to rebase +- [cabal audit osv/json (#178)](https://github.com/haskell/security-advisories/pull/178) + +- [hsec-sync (#168)](https://github.com/haskell/security-advisories/pull/168) (merged) +- [hsec-tools snapshot (#179)](https://github.com/haskell/security-advisories/pull/179) + - FT: we want to avoid switching TOML library (again), if we can. diff --git a/meeting-notes/2024-04-17.md b/meeting-notes/2024-04-17.md new file mode 100644 index 00000000..6888fad4 --- /dev/null +++ b/meeting-notes/2024-04-17.md @@ -0,0 +1,22 @@ +# SRT meeting 2024-04-17 + +Previous meeting notes: +https://github.com/haskell/security-advisories/blob/main/meeting-notes/2024-04-03.md + +## YAML vulnerability + +* Assessment in progress for CVE-2024-3205 ([#181](https://github.com/haskell/security-advisories/issues/181)) + +## Revised HSEC-2024-0003 + +* Updated advisory to include released fixes ([#191](https://github.com/haskell/security-advisories/pull/191)) + +## Initial Hackage password storage migration plan + +* Fraser came up with a draft +* Some comments have been made but everyone agree it is the right direction + +## SRT meeting rescheduling + +* Over time the chosen time-slot seems to conflict with team members' schedules +* Gautier will create and send a new poll to pick a more suitable one diff --git a/meeting-notes/2024-05-01.md b/meeting-notes/2024-05-01.md new file mode 100644 index 00000000..03bcaa8a --- /dev/null +++ b/meeting-notes/2024-05-01.md @@ -0,0 +1,49 @@ +# SRT meeting 2024-05-01 + +Previous notes: +https://github.com/haskell/security-advisories/blob/main/meeting-notes/2024-04-17.md + +## CI security advice + +- Mihai published the draft: + https://github.com/haskell/security-advisories/blob/main/guides/github.md +- A couple more comments to handle, then it will be published to Discourse + +## Web area for SRT + +- FT will work to bootstrap this. We can publish our guides, + reports, and general information there. + +## Publishing our packages to Hackage + +- FT will begin on this in the next week. +- Discussion: do we want to set up auto-publish from GitHub? + - There is a GHA by Brandon Chinn to publish to Hackage. + - https://github.com/fourmolu/fourmolu/blob/main/.github/workflows/release.yml + - Does it work with subpackages? We would need to see. + - From supply chain security POV it's better to have an action + than having developers make the dist and publish themselves. + - Maybe this is a good topic for our second *guide* and/or a tool + to validate release tarball from the sources :) + - We will look into this after the initial package release to Hackage. + +## New meeting time + +- The when2meet tool does not seem to take timezones into account? +- We might need a second round / better tool :) +- FT will look for a better tool. Or else use same tool but in UTC. + +## The expanding scope of SRT + +- With cabal-audit proposed for our repo, the scope has expanded. + +- Advisory workload is low, so team does have capacity to own this + +- FT: I see cabal-audit as a transitional effort anyway; ideally we + do not have to own it forever and the capability can be absorbed + into Cabal itself. + +- Idea: cabal-audit lives in its own repo, not security-advisories repo + - Prerequisite: publish our packages + - Advantage: not "owned" by SRT, others might be more eager/willing to contribute. + - We will have the discussion in public, with the contributor MangoIV. diff --git a/meeting-notes/2024-05-15.md b/meeting-notes/2024-05-15.md new file mode 100644 index 00000000..48f2fb56 --- /dev/null +++ b/meeting-notes/2024-05-15.md @@ -0,0 +1,22 @@ +# SRT meeting 2024-05-15 + +Previous notes: +https://github.com/haskell/security-advisories/blob/main/meeting-notes/2024-05-01.md + +## Cabal plan integration + +- A new cabal-audit project consuming the security-avisories is now being worked on https://github.com/mangoiv/cabal-audit + +## CI Security Advice Update + +- Shared on [discourse]( https://discourse.haskell.org/t/how-to-secure-github-repositories/9478) +- Updated the guide based on feedback [PR#193](https://github.com/haskell/security-advisories/pull/193) + +## Hackage Auth + +- Discussed with hackage team to improve the authentication scheme. + +## Dependencies analysis + +- Investigated getting in touch with deps.dev to increase audit coverage. +- Also considering dependabot support for cabal dependencies. diff --git a/meeting-notes/2024-05-29.md b/meeting-notes/2024-05-29.md new file mode 100644 index 00000000..fa899098 --- /dev/null +++ b/meeting-notes/2024-05-29.md @@ -0,0 +1,52 @@ +# SRT meeting 2024-05-29 + +Previously: +https://github.com/haskell/security-advisories/blob/main/meeting-notes/2024-05-15.md + +## publishing our tools on Hackage + +- Packages: cvss, osv, hsec-core, hsec-tools, hsec-sync +- FT will upload. Just asking if there are further comments about + version numbers, dep version constraints, etc? +- Co-maintainers - who, and what are your Hackage usernames? + - `gdifolco` + - `TristanCacqueray` + +## SRT members, moving forward + +- Casey has limited time +- We're at the 1y point, time for a new call? +- Updating the charter: Casey thinks we should expand it to be more + involved with the tooling (within and without ecosystem) + +- Remember the original motivation: supporting enterprise adoption. + - e.g. financial industry - how well do we meet their standards? + - Survey industry users to understand what is lacking? + - [FT] FIPS mode, verified crypto libraries (i.e. back on to + OpenSSL/NSS/etc) + +- What is missing: + - SBOM? ("software provenance") + - Larger discovery effort? + - OSS-Fuzz support? + - OpenSSF best practices: + https://www.bestpractices.dev/en/criteria/0 ? + +- SRT has some context-switching. Should we have separate subgroups + for triage / tool development / etc? + +- We can discuss on list over the coming days, and engage with folks + at ZuriHac to determine the next move. General agreement that we + can/should grow the team. + +- Retirements: Casey will step back. (Thank you for all you've + done!) + +## YAML advisory has been rejected ([#181](https://github.com/haskell/security-advisories/issues/181)) + +- FT will ask Julian if he is satisfied with this conclusion. + +## deps.dev + +- FT received message from deps.dev developer at Google. Still need + to follow up. diff --git a/meeting-notes/2024-06-12.md b/meeting-notes/2024-06-12.md new file mode 100644 index 00000000..0864dba4 --- /dev/null +++ b/meeting-notes/2024-06-12.md @@ -0,0 +1,36 @@ +# SRT meeting 2024-06-12 + +Previously: +https://github.com/haskell/security-advisories/blob/main/meeting-notes/2024-05-29.md + +## haskell.org security page + +There is now https://www.haskell.org/security/ + +We still need to configre subdomains so advisories (which was redesigned to be compliant with Haskell Foundation design) index is automatically updated. + +## CVSS Version 4 + +Initial PR to support CVSS Version 4 [#208](https://github.com/haskell/security-advisories/pull/208) + +## Fixed git timestamp parsing logic + +Switched to UTCTime everywhere to avoid unexpected issues [#201](https://github.com/haskell/security-advisories/pull/201). + +## Snapshots to distribute advisories + +Gautier worked on [#179](https://github.com/haskell/security-advisories/pull/179) to introduce a new export mode to hsec-sync to help downstream user (without git dependency). + +## Ecosystem Workshop + +Fraser introduced the SRT at the ZuriHac workshop. + +The main issue to tackle is the SBOM (e.g. with SPDX). + +## 2024 April-June report + +Fraser mostly completed it, we might want to add the slides he has used during ZuriHac Ecosystem Workshop in the repository. + +## Advisory database + +Additionally, 2 HSEC ID has been reserved for an embargoed vulnerability that we anticipate will be published in Q3. diff --git a/meeting-notes/2024-06-26.md b/meeting-notes/2024-06-26.md new file mode 100644 index 00000000..0e81e892 --- /dev/null +++ b/meeting-notes/2024-06-26.md @@ -0,0 +1,27 @@ +# SRT meeting 2024-06-26 + +Previously: +https://github.com/haskell/security-advisories/blob/main/meeting-notes/2024-06-12.md + +## GHC numeric bugs [#210](https://github.com/haskell/security-advisories/issues/210) + +- Tristan will prepare advisory + +- For the aarch64 / powerpc issues, these are not base but compiler. +- advisory content would live in `advisories/ghc/compiler`, e.g. +- we need to decide and document the "component" names in the `ghc` namespace +- e.g. `compiler`, `GHCi`, `RTS` +- And we will also need to update our OSV generation code to read the + files in the `ghc` subdir and generate the correct osv, using the `GHC` + namespace and the recognised component names. +- We are up to `HSEC-2024-0006` (0004 and 0005 have been reserved) + +## Snapshot PR + +- Gautier addressed the review comments; Fraser is still + reviewing the updates. + +## GitHub integration + +- Gautier will reach out to others who already looked at or + thought about this. diff --git a/meeting-notes/2024-07-10.md b/meeting-notes/2024-07-10.md new file mode 100644 index 00000000..29a6cb13 --- /dev/null +++ b/meeting-notes/2024-07-10.md @@ -0,0 +1,22 @@ +# SRT meeting 2024-07-10 + +Previously: +https://github.com/haskell/security-advisories/blob/main/meeting-notes/2024-06-26.md + +## Advisories ecosystem ([#213](https://github.com/haskell/security-advisories/pull/213)) + +- Schema update proposed. +- Example advisories for GHC proposed in [#214](https://github.com/haskell/security-advisories/pull/214). + +## Snapshots + +- FT still needs to (re)review Gautier's PR. + +## Growing SRT / call for volunteers + +- Time to draft a call for volunteers ([previous one](https://discourse.haskell.org/t/call-for-volunteers-haskell-security-response-team/5770)) +- How many people? + +## Dependabot + +- Gautier will ping people who had previously attempted GitHub integration diff --git a/meeting-notes/2024-07-24.md b/meeting-notes/2024-07-24.md new file mode 100644 index 00000000..d33580fa --- /dev/null +++ b/meeting-notes/2024-07-24.md @@ -0,0 +1,59 @@ +# SRT meeting 2024-07-24 + +Previously: +https://github.com/haskell/security-advisories/blob/main/meeting-notes/2024-07-10.md + + +## GitHub dependabot integration + +- Gautier talked to Arnaud which made an integration attempt +- Arnaud paired with someone in GH but they have not made + significant work on it +- We may have to start over + + +## Tooling + +- Finally merged the snapshots PR [(#179)][pr-179] (thanks Gautier) +- Merged the CVSS v2.0 (+ OSV) fix [(#218)][pr-218] (thanks Tristan) +- Adding the GHC ecosystem support [(#213)][pr-213] + - review in progress + - advisory for GHC numeric bugs [(#214)][pr-214] depends on this +- CVSS 4.0 support [(#208)][pr-208] + - ping andrii for status update? + +[pr-179]: https://github.com/haskell/security-advisories/pull/179 +[pr-208]: https://github.com/haskell/security-advisories/pull/208 +[pr-213]: https://github.com/haskell/security-advisories/pull/213 +[pr-214]: https://github.com/haskell/security-advisories/pull/214 +[pr-218]: https://github.com/haskell/security-advisories/pull/218 + + +## Quarterly report + +- Was published: + https://discourse.haskell.org/t/haskell-security-response-team-2024-april-june-report/9983 + + +## Call for Volunteers + +- We should draft and publish one soon. +- Q: call for a specific number, or wait and see? + - Be general and commit later. +- We can mention particular projects / initiatives and applicants + can (optionally) identify the particular area(s) they'd like to + tackle. + - This includes development efforts, and "latent capacity" for + dealing with advisory or security incidents. +- José will draft an announcement, and we will review on the mailing + list. + + +## Mailing list + +- FT will make sure José is on it! + + +## Bay Area Haskell meetup + +- Mihai will present about SRT at a future session diff --git a/meeting-notes/2024-08-07.md b/meeting-notes/2024-08-07.md new file mode 100644 index 00000000..b769465e --- /dev/null +++ b/meeting-notes/2024-08-07.md @@ -0,0 +1,30 @@ +# SRT meeting 2024-08-07 + +Previously: +https://github.com/haskell/security-advisories/blob/main/meeting-notes/2024-07-24.md + +## Embargoed vulnerability work + +We contacted the affected maintainers and we are coordinating the disclosure. + +## haskell.org crlf injection vulnerability + +Divya Singh reported a vulnerability on the haskell.org website that has been fixed by upgrading the apache package. + +## CVSS version 4.0 [#208](https://github.com/haskell/security-advisories/pull/208) + +@unorsk added support for the latest Common Vulnerability Scoring System. + +## haskell.org blog and security advisories + +We discussed about posting security update news to the upcoming haskell.org blog. + +## Call for Volunteers + +The draft is still in progress. + +## GitHub Action cabal-audit scan + +* Gautier has start to work on a [GitHub Action](https://github.com/blackheaven/haskell-security-action) which aims to run `cabal audit` +* Still under development, most of the code is done (i.e. push results to the security section of the repository) +* Packaging issues mainly for the moment diff --git a/meeting-notes/2024-08-21.md b/meeting-notes/2024-08-21.md new file mode 100644 index 00000000..4345e728 --- /dev/null +++ b/meeting-notes/2024-08-21.md @@ -0,0 +1,19 @@ +# SRT meeting 2024-08-21 + +Previously: +https://github.com/haskell/security-advisories/blob/main/meeting-notes/2024-08-07 + +## Embargoed vulnerability work + +We provided a fix and we are coordinating the disclosure. + +## Call for Volunteers + +Jose wrote a draft to be communicated soon. + +## GitHub Action cabal-audit scan + +* Gautier has a minimal working version [GitHub Action](https://github.com/blackheaven/haskell-security-action) +* Some example: [here](https://github.com/blackheaven/vulnerable-sandbox/security/code-scanning/1) +* He made a [RFC](https://discourse.haskell.org/t/request-for-comments-github-haskell-security-action/10191) +* After discussing with MangoIV, Gautier will upstream the sarif file generation in `cabal-audit` diff --git a/meeting-notes/2024-09-04.md b/meeting-notes/2024-09-04.md new file mode 100644 index 00000000..8aaf574e --- /dev/null +++ b/meeting-notes/2024-09-04.md @@ -0,0 +1,45 @@ +# SRT meeting 2024-09-04 + +Previously: https://github.com/haskell/security-advisories/blob/main/meeting-notes/2024-08-21.md + +## HSEC-2024-0003 - process fix + +- PR [#324](https://github.com/haskell/process/pull/324) published (expect merge and release soon) +- HSEC-2024-0003 advisory update draft PR: [#236](https://github.com/haskell/security-advisories/pull/236) + +## *Trusted publishing* for Hackage + +- Token workflow +- Hackage supports token authn today, but they are unscoped +- See also PyPI implementation: https://docs.pypi.org/trusted-publishers/ + - Project page references the trusted repo + - GHA uses OIDC to auth to PyPI and get short-lived (minutes) token + - GHA or publishing workflow uses the token to publish new package version. + +## Roadmap of ecosystem security improvements + +- Man years of effort are already known :) +- We should write it all down in an disgestible form. +- Might make getting funding easier? + - Menu / prospectus + +### New ideas + +- RTS fuzzing (Mihai) + - or general fuzzing tooling for Haskell programmers + +## haskell-security-action (GHA) + +- Gautier published draft GHA for detecting security + issues and bumping bounds (using [cabal-audit](https://github.com/MangoIV/cabal-audit/pull/50)) +- GHA draft: https://github.com/blackheaven/haskell-security-action +- Playground: https://github.com/blackheaven/vulnerable-sandbox/ +- Please review and test! +- Still a lot of work on it: correct file name/line, fix propositions, PR creation, etc. + +## Call for volunteers + +- Jose's draft is good. +- How many: "around two or three more members" +- Closing date: end of September. +- Fraser will be primary collector of submissions diff --git a/meeting-notes/2024-10-02.md b/meeting-notes/2024-10-02.md new file mode 100644 index 00000000..61b1829e --- /dev/null +++ b/meeting-notes/2024-10-02.md @@ -0,0 +1,43 @@ +# SRT meeting 2024-10-02 + +Previously: https://github.com/haskell/security-advisories/blob/main/meeting-notes/2024-09-04.md + +## Quarterly report + +Fraser will draft this weekend, and send to list for review. + +## New SRT members + +Application period closed. There were 4 applications. +Fraser will compile them and share in the coming days. + +## Hacktoberfest (GitHub) + +- Hécate asks us to put forward some issues. +- `good-first-issue` (or similar) label? +- Let's review the open issues and discuss on-list, then share with Hécate. + +## Hackage packages release + +- Downstream (`cabal-audit`, `flora`) ask for it (the new `hsec-sync` does not rely on `git`) +- Too much work left to be done on `CVSS 4.0`, it'll be shipped in the next release + +## Trusted publishing and fuzzing + +- Mihai still to do this prep/proposal. + +## Prospectus + +- Prospectus of ideas for SRT (or other people working on Haskell security) + will be valuable for HF in asking for funding. +- So, we need to put it together :) + +## GHC 9.10 support in tools/libs + +- Still waiting on `feed` which does not support base-4.20. +- Probably need to nudge Hackage trustees for a metadata revision. + +## Outstanding PR review + +- We went through the outstanding PRs in our repo; discussed + what to do with them. diff --git a/meeting-notes/2024-10-16.md b/meeting-notes/2024-10-16.md new file mode 100644 index 00000000..642a353d --- /dev/null +++ b/meeting-notes/2024-10-16.md @@ -0,0 +1,67 @@ +# SRT meeting 2024-10-16 + +Previously: +https://github.com/haskell/security-advisories/blob/main/meeting-notes/2024-10-02.md + +## Call for Volunteers + +- FT sent each of the 4 application to the list +- Upon discussion, we will accept 2 +- SRT members, please review and respond on the ML (the initial thread) + +## Stack traces proposal + +- CLC proposal: + https://github.com/haskell/core-libraries-committee/issues/285#issuecomment-2414727239 +- Discussion: + - For 2 decades people wanted stack traces, now we have them + there are doubts :D + - Most other languages are showing the stack trace + - Sensitive information in error messages is an application + developer's fault + - It's not unreasonable to want a way to disable the default + behaviour, or catch and suppress, if the actual program + structure (e.g. function names) is sensitive for some reason. + - The proposal Part 2 seems to suggest the stacktrace would be + leaked with `displayException` too, which might be used for + end-user facing message, perhaps it would be safer to only + print them through the main exception handler. That's how + python does it, printing an exception just show the error, the + stacktrace is only displayed by default from uncaught + exception. + +## Draft quarterly report + +- call for volunteers update +- advisory DB changes (1 new vuln, 0 historical, 2 reserved) +- HSEC-2024-0003 update +- haskell.org Apache httpd update +- hackage-server "Reporting Vulnerabilities" link +- tooling update + - CVSS 4.0 work (ongoing) + - GHA / Renovate progress + +## GHC hash collision + +- Simon PJ and FT think it is not a huge deal +- But we should fix it. +- Changing the Hash function is simple and buys us another 10-20 + years (hopefully) + +### Documenting known weaknesses + +This is a good opportunity to take a look at the ways +that the compiler/toolchain can be compromised by malicious +source code, and document them. Guide / blog post / GHC docs. + +Many of these would not warrant an HSEC-ID (especially structural +issues that are impossible / very hard to fix), but we can still +collect them and let the community know in a more formal way. + +## GHC numeric bug + +- Tristan will rebase the advisory draft #214 + +## Updated major dependencies for hsec-tools + +#239 and #241 diff --git a/meeting-notes/2024-10-30.md b/meeting-notes/2024-10-30.md new file mode 100644 index 00000000..71755b1c --- /dev/null +++ b/meeting-notes/2024-10-30.md @@ -0,0 +1,12 @@ +# SRT meeting 2024-10-30 + +Previously: +https://github.com/haskell/security-advisories/blob/main/meeting-notes/2024-10-16.md + +## Call for Volunteers + +We received the candidatures and voted for the new members to be announced. + +## GHC Math bugs + +The advisories are updated and available for review: [#214](https://github.com/haskell/security-advisories/pull/214) diff --git a/meeting-notes/2024-11-13.md b/meeting-notes/2024-11-13.md new file mode 100644 index 00000000..9f78bb8b --- /dev/null +++ b/meeting-notes/2024-11-13.md @@ -0,0 +1,29 @@ +# SRT meeting 2024-11-13 + +Previously: +https://github.com/haskell/security-advisories/blob/main/meeting-notes/2024-10-30.md + +## Q3(+) report + +The report is proposed: [#244](https://github.com/haskell/security-advisories/pull/244). We will reproduce it on Discourse tomorrow, and submit a PR to update https://www.haskell.org/security/. + +## SRT Process + +We should document more thoroughly the SRT processes +(administrative), particularly since we went through our first +vacancy->new appointments cycle. + +## GHC Math bugs + +The advisories are updated and available for review: [#214](https://github.com/haskell/security-advisories/pull/214) + +## flora integration + +[flora](https://github.com/flora-pm/flora-server/) has pinged Gautier and Fraser +regarding [security advisories integration PR#762](https://github.com/flora-pm/flora-server/pull/762). + +After a discussion between Gautier and Hecate (the maintainer), flora will +integrate advisories search and the decision was made to replicate the advisories +structure in PostGreSQL. + +Perhaps we should recommend to use the OSV export? diff --git a/reports/2023-07-10-ann-q2-report.md b/reports/2023-07-10-ann-q2-report.md new file mode 100644 index 00000000..c26f6639 --- /dev/null +++ b/reports/2023-07-10-ann-q2-report.md @@ -0,0 +1,252 @@ +# Haskell Security Response Team - Announcement and Q2 2023 report + +The Haskell Security Response Team (SRT) is a volunteer organization +within the Haskell Foundation that is building tools and processes +to aid the entire Haskell ecosystem in assessing and responding to +security risks. In particular, we maintain a [database][] of +security advisories that can serve as a data source for automated +tooling. + +This post announces the SRT membership and the commencement of our +work, and also serves as our first quarterly report. + +## How to contact the SRT + +For assistance in coordinating a security response to new, high +impact vulnerabilities, contact `security-advisories@haskell.org`. +Due to limited resources, we can only coordinate embargoed +disclosures for high impact vulnerabilities affecting core Haskell +tools and libraries. We'll decide whether to offer this service on +a case by case basis. + +You can submit lower-impact or historical vulnerabilities to the +advisory database via the pull request process. There are further +details later in this report. + +You can also contact the SRT about non-advisory/security-response +topics. We prefer public communication where possible. In most +cases, GitHub issues are an appropriate forum. But the mail address +is there if no other appropriate channel exists. + +## SRT membership and kick-off + +Fraser Tweedale volunteered to found the team, based on preparatory +work done by the Haskell Foundation's Technical Working Group. After +he came up with an initial set of procedures and the group +structure, we posted a [call for volunteers][] on February 9. We +received many qualified applicants, and it was difficult to choose +the initial committee. We tried to prioritize recruiting people with +non-overlapping technical knowledge as well as substantial +real-world experience managing security processes for open-source +projects. + +[call for volunteers]: https://discourse.haskell.org/t/call-for-volunteers-haskell-security-response-team/5770 + +The members of the SRT are: + +* **Casey Mattingly** - Security Research Scientist at a large + financial institution, responds to and manages CVEs and + disclosures, experience with data-driven security governance + processes, undergoes mandatory annual security trainings with + employer, implemented three authentication frameworks +* **Fraser Tweedale** - Principal Software Engineer at Red Hat working + on PKI and identity management solutions. Organizer of the + Haskell devroom at FOSDEM and regular speaker at conferences. +* **Gautier Di Folco** - Haskeller for more than a decade, full-time + for more than two years. Primarily responsible for his companies' + security policies. Prior experience in secure development in + networking and telecommunications hardware as well as managing + security for Web applications. +* **Mihai Maruseac** - Stackage curator, contributor to Stack, former + contributor to Haskell Communities and Activities Report, founder + of the TensorFlow security team, member of Google Open Source + Security Team +* **Tristan de Cacqueray** - Principal Software Engineer at Red Hat. + Six years of experience on the OpenStack Vulnerability Management + Team; produced 56 advisories through this process, including + technical analysis, public communication, and CVE assignment. + +Additionally, **David Thrane Christiansen**, Executive Director of +the Haskell Foundation, participates in meetings and helps connect +the group to other Haskell projects. + +The first meeting of the SRT was held on May 3. Most of us were +strangers so we spent some time getting to know each others' +personalities, areas of expertise, and ways of working. Since then +we've been busy preparing our tools and processes, refining our +database format, and making contact with the broader open source +security response ecosystem. + + +### Processes + +The SRT has a video-conference every 2 weeks. Meeting notes are +published in the *security-advisories* repository (possibly with +redactions). Technical discussion is primarily in (public) GitHub +issues and pull requests. SRT process/management topics and +embargoed vulnerabilities are discussed during our meetings and in a +private mailing list. + +### Terms and recruitment + +The initial terms of some SRT members will expire at the end of Q3. +We have decided that members wishing to continue may do so. Closer +to the end of Q3, we will consider whether we should grow the team. +If we decide to do that, and/or there are casual vacancies, we will +put out a new call for volunteers toward the end of Q3. + + +## Technical work + +### Database is open for submissions. + +The *security-advisories* [database][] is open for submissions. So +far, there are only a few historical vulnerabilities, which we used +to test our tool code and submission processes. + +We have a list of several known historical advisories ([GitHub +issue][historical advisories]) still to be added. If you know of +any others, please let us know in the issue (or write and submit the +advisory yourself). + +The submission process is detailed in +[`CONTRIBUTING.md`][CONTRIBUTING]. If something goes wrong or the +steps are not sufficiently clear, that is a bug; please let us know +(e.g. create a GitHub issue). + +[database]: https://github.com/haskell/security-advisories +[historical advisories]: https://github.com/haskell/security-advisories/issues/32#issuecomment-1588601639 +[CONTRIBUTING]: https://github.com/haskell/security-advisories/blob/main/CONTRIBUTING.md + +**If you want to submit a new, high-impact vulnerability**, or would +like SRT assistance to coordinate a response, please mail +`security-advisories@haskell.org` with details instead of submitting +a pull request (PRs are public). Rule of thumb: *a high-severity +vulnerability affecting the GHC toolchain or a popular library*. If +you think you *might* have a high-impact vulnerability, please +contact the SRT and we will help to assess the impact. + +The SRT has not adopted a means of end-to-end encrypted +communication (e.g. OpenPGP) at this time. + + +### Advisory format + +The advisory format is Markdown with a TOML header containing +metadata, such as affected packages/versions, CVSS scores, and +references. The [`EXAMPLE_ADVISORY`][EXAMPLE] explains the header +format. + +The design followed [RustSec's advisory format][]. During our +initial work, we made some changes to more closely align with the +format used by [OSV](https://osv.dev/), a multi-language repository +of security advisories. Many systems already read from OSV, making +it even easier for the Haskell community to get value from these +systems. + +[EXAMPLE]: https://github.com/haskell/security-advisories/blob/main/EXAMPLE_ADVISORY.md +[RustSec's advisory format]: https://github.com/RustSec/advisory-db#advisory-format + + +### OSV Export + +The [native format](https://ossf.github.io/osv-schema/) of OSV is +generated from our database and published on the +`generated/osv-export` branch. This makes it easy for systems that +understand OSV to consume our advisories. + +We are working with the osv.dev project to get the HSEC source set +up (see [osv.dev issue #1418][]). As of early July, the OSV test +instance is ingesting HSEC advisories ([results][osv-test]). + +[osv.dev issue #1418]: https://github.com/google/osv.dev/issues/1418 +[osv-test]: https://oss-vdb-test.appspot.com/list?ecosystem=Hackage + + +### Automation Improvements + +We hope to enable a richer advisory contributor (and reviewer) +experience through GitHub automation. Ideas are being gathered at +https://github.com/haskell/security-advisories/issues/57. Community +input or contributions are welcome. If you have experience +developing GitHub webhook applications, your contributions could be +especially valuable. + + +### Haskell Development + +The `hsec-tools` library and executable live in the +*security-advisories* database, alongside the advisories themselves. +Our code is published under a BSD 3-Clause license. + +In Q3 of 2023, we plan to extract the general-purpose OSV-related +datatypes and utilities from our tools into a standalone package and +release it separately on Hackage. We additionally plan to develop +and release a library for processing [CVSS][] scores. + +[CVSS]: https://en.wikipedia.org/wiki/Common_Vulnerability_Scoring_System + + +### Rehearsals + +We have rehearsed our processes by creating advisories for a number +of already-known security issues in the Haskell ecosystem. This +helped us uncover ways in which our tools, data formats, and +processes were not quite ready. In addition to the resulting data +being useful, we are now better prepared for incoming reports, +whether confidential or public. + + +## Future investigations + +The [Vulnerability Exploitable eXchange (VEX)][VEX] data model +describes the impact (or lack of) of some vulnerability in a +particular program or component. The SRT plans to investigate VEX +as a means to suppress false-positives where some dependency of a +program/library contains a vulnerability, but that vulnerability is +mitigated or not present at all in the dependent program. + +VEX also requires "action statements" for affected programs, which +are intended to convey possible mitigations, workarounds or +remediations. Storing and conveying this kind of information in +security tooling could further enhance the Haskell security tooling +story. + +[VEX]: https://www.cisa.gov/resources-tools/resources/minimum-requirements-vulnerability-exploitability-exchange-vex + + +## Opportunities + +If you'd like to make it easier for Haskell programmers to avoid +security problems in dependencies, there are many concrete projects +that would be very helpful! The SRT doesn't have the capacity to +take these tasks on, but we're happy to advise. + +* Build plan auditing for `cabal-install` would allow users to be + notified if their build plan depends on a package for which there + is an advisory, similar to `cargo audit` or `npm audit`. In addition + to their features, it could also be useful to additionally allow a + specification of a threat model, so that advisories for attack + vectors requiring network access would not be shown for offline-only + applications. + +* A tool that scans Stackage snapshots for versions affected by + advisories, notifying both users and the Stackage maintainers so + that the snapshot can be updated + +* Integration with `hackage-server`, to indicate known-vulnerable + package versions. + +* A tool for project maintainers to generate a skeleton advisory for + their own project, parsing information out of the Cabal file and + asking some convenient questions + +* Integration with other sources of advisories that don't pull from + OSV + +Generally speaking, we'd like to support every effort to increase +the value that the advisories provide to the Haskell ecosystem. +However, it is not within the capacity or scope of the SRT to +develop all the above ideas. Instead, we hope to collaborate with +"downstream" projects, evolving both the database content and the +associated tools and libraries to meet their needs. diff --git a/reports/2024-01-10-half-year-report.md b/reports/2024-01-10-half-year-report.md new file mode 100644 index 00000000..300445f1 --- /dev/null +++ b/reports/2024-01-10-half-year-report.md @@ -0,0 +1,152 @@ +# Haskell Security Response Team - 2023 July–December report + +The Haskell Security Response Team (SRT) is a volunteer organization +within the Haskell Foundation that is building tools and processes +to aid the entire Haskell ecosystem in assessing and responding to +security risks. In particular, we maintain a [database][repo] of +security advisories that can serve as a data source for security +tooling. + +This report details the SRT activities from July to December 2023. +The SRT is supposed to report quarterly, but we missed giving a Q3 +report. We'll try not to let that happen again. + +The SRT is: + +- Casey Mattingly +- Fraser Tweedale +- Gautier Di Folco +- Mihai Maruseac +- Tristan de Cacqueray + + +## How to contact the SRT + +For assistance in coordinating a security response to newly +discovered, high impact vulnerabilities, contact +`security-advisories@haskell.org`. Due to limited resources, we can +only coordinate embargoed disclosures for high impact +vulnerabilities affecting current versions of core Haskell tools and +libraries. + +You can submit lower-impact or historical vulnerabilities to the +advisory database via a pull request to our [GitHub +repository][repo]. + +You can also contact the SRT about non-advisory/security-response +topics. We prefer public communication where possible. In most +cases, [GitHub issues][gh-new-issue] are an appropriate forum. But +the mail address is there if no other appropriate channel exists. + + +## Advisory database + +3 contemporary advisories were added to the database during the +reporting period. + +9 historical advisories were added to the database during the +reporting period. Most of these were found by searching established +CVE and vulnerability databases. It is important to record +historical vulnerabilities so if you know of any, please submit a +pull request or let the SRT know! + + +## Coordinated disclosure and downstream stakeholders + +[`HSEC-2023-0015`][HSEC-2023-0015] was a medium severity theoretical +attack against `cabal-install`. This was the SRT's first embargoed +vulnerability where we coordinated disclosure with downstream +distributions. Unfortunately, we missed an important +distributor—GHCup—causing some stress and embarrassment. We have +added GHCup to our list of distributors. + +The SRT maintains a public [list of downstream +stakeholders][stakeholders], as well as some private stakeholder +addresses. If you want to add a contact point to either the public +or private list, please let us know. + + +## osv.dev integration + +The OSV project aggregates the security advisories for many open +source languages, ecosystems and projects. In addition to exporting +our advisory content in the OSV data format and requesting osv.dev +to import our advisories, we delivered [an enhancement][pr-osv] to +OSV itself to enable it to understand Haskell package and GHC +version numbers. + +As a result of these efforts, all HSEC security advisories are now +published in OSV (see https://osv.dev/list?ecosystem=Hackage). + + +## Tooling development + +- HSEC IDs can now be reserved (e.g. allocate an ID for an embargoed + vulnerability). + +- Gautier implemented the `hsec-tools query` subcommand for querying + whether a package/version is affected by any advisories. + +- Gautier extracted core advisory data types and functions as the + `hsec-core` library, separating it from the `hsec-tools` + executable. We have not yet published it on Hackage, but intend + to do so. + +- Gautier extracted the OSV modules to the `osv` library. We have + not yet published it on Hackage, but will certainly do so, + probably in Q1. + +- Tristan implemented a library for CVSS parsing, printing and + calculations. As with the others, it is not yet on Hackage, but + watch this space. + +- Tristian implemented library support for mapping CWE numbers and + descriptions. + +- `hsec-tools` CLI help has been improved. + +- Eric Mertens (non-SRT contributor) migrated us to a richer TOML + library which includes generation, enabling us to print as well as + parse advisories. + +- The `generate-index` subcommand generates an HTML index of the + advisories. For now it is fairly basic. We plan to publish this + index somewhere prominent, e.g. within the `haskell.org` site, + and are currently working through the details. + + +## Future work + +We plan to develop GitHub tooling (e.g. webhooks or GitHub app) to +improve the contributor (and maintainer) experience. For example, +we can expand CVSS and CWE definitions, or provide contextual help +to fill out missing fields in the advisory TOML. + +As mentioned above, we have several libraries awaiting publication +on Hackage. We hope that CVSS, CWE and OSV libraries will be +broadly useful, and the `hsec-core` library will be useful in +developing enhanced security tooling for Haskell development. + +The SRT is eager to provide whatever is needed on our side to +support the development of "downstream" tooling. In particular, we +would love to see integration with package repositories (Hackage, +Flora), and tooling for analysing dependency contraints, build +plans, freeze files, GHC package databases or similar artifacts to +detect and advise users of vulnerable packages in (potential) use. +See also David Christiansen's [call to action][]. + +Development of downstream tooling is not in the SRT's current scope +of work, but it *is* in our charter to do whatever we can to support +such development. This could include things like advisory schema +changes, enhancing our libraries, or consultation and co-design. If +you want to contribute to these important efforts, and especially if +you are a developer/maintainer of an obvious integration target, the +SRT would love to hear from you and support you. + + +[repo]: https://github.com/haskell/security-advisories +[gh-new-issue]: https://github.com/haskell/security-advisories/issues/new/choose +[pr-osv]: https://github.com/google/osv.dev/pull/1463 +[HSEC-2023-0015]: https://osv.dev/vulnerability/HSEC-2023-0015 +[stakeholders]: https://github.com/haskell/security-advisories/blob/main/PROCESS.md#downstream-stakeholders +[call to action]: https://discourse.haskell.org/t/would-you-like-to-write-a-security-advisory-analyzer/7638 diff --git a/reports/2024-04-08-Q1-report.md b/reports/2024-04-08-Q1-report.md new file mode 100644 index 00000000..abedc483 --- /dev/null +++ b/reports/2024-04-08-Q1-report.md @@ -0,0 +1,182 @@ +# Haskell Security Response Team - 2024 January–March report + +The Haskell Security Response Team (SRT) is a volunteer organization +within the Haskell Foundation that is building tools and processes +to aid the entire Haskell ecosystem in assessing and responding to +security risks. In particular, we maintain a [database][repo] of +security advisories that can serve as a data source for security +tooling. + +This report details the SRT activities from January through March +2024. + +The SRT is: + +- Casey Mattingly +- Fraser Tweedale +- Gautier Di Folco +- Mihai Maruseac +- Tristan de Cacqueray + + +## How to contact the SRT + +For assistance in coordinating a security response to newly +discovered, high impact vulnerabilities, contact +`security-advisories@haskell.org`. Due to limited resources, we can +only coordinate embargoed disclosures for high impact +vulnerabilities affecting current versions of core Haskell tools and +libraries, or in other exceptional cases. + +You can submit lower-impact or historical vulnerabilities to the +advisory database via a pull request to our [GitHub +repository][repo]. + +You can also contact the SRT about non-advisory/security-response +topics. We prefer public communication where possible. In most +cases, [GitHub issues][gh-new-issue] are an appropriate forum. But +the mail address is there if no other appropriate channel exists. + + +## Advisory database + +1 contemporary advisory (affecting 3 packages) was added to the +database during the reporting period. + +1 historical advisory was added to the database during the reporting +period. + +Additionally, 1 HSEC ID has been reserved for an embargoed +vulnerability that we anticipate will be published in Q2. + +We urge community members to submit to the database any known +security issues, including historical issues, that are not yet +represented. + + +## Security risks of bundled/vendored C code in Haskell packages + +[HSEC-2024-0002] was a vulnerability affecting several packages that +perform bzip2 compression or decompression. It was introduced by +way of *bundled* (interchangable term: *vendored*) C sources. As +demonstrated in this case, there is a risk of these bundled sources +not being updated when security issues are discovered and fixed in +the "upstream" project. + +Thanks to Julian Ospald, HSEC-2024-0002 was resolved in all known +affected packages by introducing +[*bzip2-clib*](https://hackage.haskell.org/package/bzip2-clib), a +new, separate package that contains the (updated) bzip2 cbits. The +affected packages were modified to depend on *bizp2-clib*, instead +of independently bundling the C sources. This will also make future +updates easier. Other packages could benefit from taking a similar +approach, especially where multiple packages currently bundle the +same upstream C library independently. + +There is a clear need for better identification of libraries that +contain vendored cbits within the Haskell ecosystem—especially those +that are widely depended upon. Issue +[#162](https://github.com/haskell/security-advisories/issues/162) +tracks this topic. We welcome all community members to contribute +to the discussion. The SRT will communicate further about this need +in the coming months. + + +## liblzma / xz utils backdoor + +A significant attack against `sshd` via malicious code introduced +into xz/liblzma was recently discovered. It was assigned +**CVE-2024-3094**. Russ Cox published an excellent [timeline of the +attack][xz-timeline]. Casey analysed the Haskell ecosystem's +exposure to this risk. + +The [`lzma`][hackage-lzma] package binds to the system library. Any +Haskell projects that use this package, or systems on which the +resulting artifacts are deployed, **may be compromised if the system +package was an affected version**. Because the issue is in the +system liblzma package, we will not public an HSEC advisory for this +issue. + +Very much related to the preceding topic: the +[`lzma-clib`][hackage-lzma-clib] and +[`lzma-static`][hackage-lzma-static] packages bundle the upstream +sources. The bundled source code is from versions prior to the +attack. Therefore these packages are **unaffected**. + +[xz-timeline]: https://research.swtch.com/xz-timeline +[hackage-lzma]: https://hackage.haskell.org/package/lzma +[hackage-lzma-clib]: https://hackage.haskell.org/package/lzma-clib +[hackage-lzma-static]: https://hackage.haskell.org/package/lzma-static + + +## SRT at Haskell Ecosystem Workshop and ZuriHac 2024 + +In early June, Gautier and Fraser (maybe Mihai too) will attend the +[Haskell Ecosystem Workshop] and [ZuriHac] in June. Fraser will +present at the Workshop to give participants an orientation in the +technical details of our tooling, share our ideas for high-impact +integration with the advisory database, and propose new work for +improving Haskell's overall security posture. + +If you are interested in the security of the Haskell ecosystem, +please consider attending the workshop and/or ZuriHac. We look +forward to meeting and collaborating with you! + + +## Introducing `cabal-audit` + +Thanks to the work of GitHub user **MangoIV**, we will soon merge +the `cabal-audit` program (see [PR +#148](https://github.com/haskell/security-advisories/pull/148)). +`cabal-audit` runs the Cabal solver on a project, looks for +vulnerabilities in the dependencies, and proposes fix versions. +Some churn should be expected as the tool matures. We would +eventually like *cabal-install* to have native audit capabilities, +but this is a significant step that provides a foundation for +technical problem solving and UX experimentation. Thank you for +your valuable contributions, MangoIV! + + +## HTML index and atom feed + +In addition to our advisories being [published on +OSV.dev][osv-advs], we now generate an HTML index of our advisories, +currently hosted at https://haskell.github.io/security-advisories/. + +We would like to also get it hosted somewhere more "canonical", and +improve the appearance (it is quite rough). + +We also added an [atom feed][]. + +[osv-advs]: https://osv.dev/list?ecosystem=Hackage +[atom feed]: https://haskell.github.io/security-advisories/atom.xml + + +## Tooling updates + +Advisories now support the optional `capec` field, for recording +[*Common Attack Pattern Enumerations and Classifications +(CAPEC)*][capec] data. CAPEC differs from CWE in that CWE is a +classification of programming or configuration errors that give rise +to security weaknesses, CAPEC classifies known patterns of attack. + +[capec]: https://capec.mitre.org/ + +We introduced the `hsec-sync` command, which is intended for +downstream tools to **synchronise a local cache of the advisory +content**. It currently clones the whole `security-advisories` Git +repo, but that will soon change. Gautier is working on an snapshot +format that we will use to distribute advisory data and `hsec-sync` +will be modified to download these snapshots instead. + +Soon (certainly ahead of ZuriHac in June) we will **publish our +libraries on Hackage**. We hope that `cvss`, `cwe` and `osv` +packages will be broadly useful, and the `hsec-core` library will be +helpful for working with Haskell security advisories. + + +[repo]: https://github.com/haskell/security-advisories +[gh-new-issue]: https://github.com/haskell/security-advisories/issues/new/choose +[HSEC-2024-0002]: https://osv.dev/vulnerability/HSEC-2024-0002 +[Haskell Ecosystem Workshop]: https://haskell.foundation/events/2024-haskell-ecosystem-workshop.html +[ZuriHac]: https://zfoh.ch/zurihac2024/ diff --git a/reports/2024-07-18-Q2-report.md b/reports/2024-07-18-Q2-report.md new file mode 100644 index 00000000..89da59d6 --- /dev/null +++ b/reports/2024-07-18-Q2-report.md @@ -0,0 +1,196 @@ +# Haskell Security Response Team - 2024 April–June report + +The Haskell Security Response Team (SRT) is a volunteer organization +within the Haskell Foundation that is building tools and processes +to aid the entire Haskell ecosystem in assessing and responding to +security risks. In particular, we maintain a [database][repo] of +security advisories that can serve as a data source for security +tooling. + +This report details the SRT activities from April through June +2024. + +The SRT is: + +- Casey Mattingly +- Fraser Tweedale +- Gautier Di Folco +- Mihai Maruseac +- Tristan de Cacqueray + +[repo]: https://github.com/haskell/security-advisories + + +## How to contact the SRT + +For assistance in coordinating a security response to newly +discovered, high impact vulnerabilities, contact +`security-advisories@haskell.org`. Due to limited resources, we can +only coordinate embargoed disclosures for high impact +vulnerabilities affecting current versions of core Haskell tools and +libraries, or in other exceptional cases. + +You can submit lower-impact or historical vulnerabilities to the +advisory database via a pull request to our [GitHub +repository][repo]. + +You can also contact the SRT about non-advisory/security-response +topics. We prefer public communication where possible. In most +cases, [GitHub issues][gh-new-issue] are an appropriate forum. But +the mail address is there if no other appropriate channel exists. + +[gh-new-issue]: https://github.com/haskell/security-advisories/issues/new/choose + + +## Growing the SRT + +Following discussions at the 2024 Haskell Ecosystem Workshop, we +have decided to grow the SRT. This is in recognition of the +expanding scope of the SRT's work. For example, we would like to +improve security tooling for Haskell developers, but we are limited +by our volunteer members' capacity. There are several high-impact +projects awaiting attention. Growing the team will enable us to +address more of these, while (hopefully) reserving some capacity to +address urgent security issues when they arise. + +Additionally, Casey Mattingly has decided to retire from the SRT. +Casey, thank you for your significant contributions during the SRT's +first year. + +The SRT will put out a new Call for Volunteers soon. Keep an eye +out for it, and we look forward to welcoming new members soon! + + +## Advisory database + +1 contemporary advisory was published during the reporting period. + +0 historical advisories were added during the reporting period. + +2 HSEC IDs (HSEC-2024-0004 and HSEC-2024-0005) have been reserved +for embargoed vulnerabilities, which will be published later. + +We urge community members to submit to the database any known +security issues, including historical issues, that are not yet +included. + + +## SRT at the Haskell Ecosystem Workshop and ZuriHac 2024 + +In early June, Gautier and Fraser attended the [Haskell Ecosystem +Workshop] and [ZuriHac], co-located at OST Rapperswil near Zürich. +Fraser presented ([slides]) at the Workshop, giving an overview of +the SRT's processes, work, tooling, and future evolution. + +[Haskell Ecosystem Workshop]: https://haskell.foundation/events/2024-haskell-ecosystem-workshop.html +[ZuriHac]: https://zfoh.ch/zurihac2024/ +[slides]: https://speakerdeck.com/frasertweedale/haskell-security-response-team-haskell-ecosystem-workshop-2024 + +There were many highlights from 5 days of collaboration across both +events: + +- New security issues were reported, and SRT initiated a response. +- New contributors made valuable contributions: + - André Espaze implemented a [*Security* page][haskell.org-security] + for the `www.haskell.org` website ([pull request][pr-300]). + - andrii (`@unorsk`) took up the work of implementing CVSS 4.0 + support for the advisory database. + +- Gautier improved the HTML advisory index generation +- Mango (`@MangoIV`) continued work on [cabal-audit] and + bugfixes/improvements to the advisory libraries. +- Mango also started work on SPDX SBOM generation. +- SRT members gave security advice to other projects. +- Many people shared ideas about the evolution and strengthening of + the SRT, and the Haskell security posture more generally. + +[pr-300]: https://github.com/haskell-infra/www.haskell.org/pull/300 +[cabal-audit]: https://github.com/MangoIV/cabal-audit +[haskell.org-security]: https://www.haskell.org/security/ + +Fraser especially thanks the Haskell Foundation for travel +assistance (Zürich is a long way from Australia!) + + +## Reporting vulnerabilities via VINCE + +The CERT/CC [VINCE] system supports confidential reporting of +vulnerabilities and response coordination. The Haskell ecosystem is +now represented in VINCE as the *"Haskell Programming Language"* +vendor. + +VINCE is especially valuable for coordinated security response and +disclosure of vulnerabilities that impact multiple ecosystems. For +example, [HSEC-2024-0003] impacted many languages, including Rust, +PHP, Node.js and Erlang. Representatives of the affected ecosystems +shared information, including mitigation techniques, and prepared +for coordinated disclosure and fix releases. + +Although anyone can use VINCE to report a vulnerability to the SRT, +we encourage its use only for **high-impact vulnerabilities** and +**vulnerabilities that impact multiple ecosystems** or vendors. For +low-severity issues that only impact the Haskell ecosystem, please +follow the process in the [Reporting Vulnerabilities][reporting] +document. + +[VINCE]: https://kb.cert.org/vince/ +[HSEC-2024-0003]: https://osv.dev/vulnerability/HSEC-2024-0003 +[reporting]: https://github.com/haskell/security-advisories/blob/main/CONTRIBUTING.md + + +## Security guides + +The SRT from time to time will publish "security best practices" +guides on particular topics, tailored to users of Haskell. Mihai +published the first of these in May: [How to secure GitHub +repositories][guide-github]. Thanks Mihai! + +What other security guides would be helpful for the Haskell +community? Please let us know via email or GitHub issue. + +[guide-github]: https://github.com/haskell/security-advisories/blob/main/guides/github.md + + +## SRT libraries and tools on Hackage + +We have published the following libraries and tools on +`hackage.haskell.org`: + +- [***cvss***](https://hackage.haskell.org/package/cvss): + types and functions for the [*Common Vulnerability Scoring System*][cvss] +- [***osv***](https://hackage.haskell.org/package/osv): + the [*Open Source Vulnerabilities (OSV) schema*][osv-schema] +- [***hsec-core***](https://hackage.haskell.org/package/hsec-core): + our core advisory type +- [***hsec-tools***](https://hackage.haskell.org/package/hsec-tools): + advisory parsing and processing (library), *and* the `hsec-tools` + executable for managing the advisory database and export + artifacts +- [***hsec-sync***](https://hackage.haskell.org/package/hsec-sync): + executable for downloading and synchronising *snapshots* of the + advisory database content, intended for Haskell ecosystem tooling + +[cvss]: https://en.wikipedia.org/wiki/Common_Vulnerability_Scoring_System +[osv-schema]: https://ossf.github.io/osv-schema/ + +We will also publish a [*Common Weakness Enumeration (CWE)*][cwe] +library, which is still in development. + +[cwe]: https://cwe.mitre.org/ + + +## Tooling updates + +- Gautier implemented advisory snapshots. These are intended for + distribution and consumption by downstream tools (so they don't + have to clone the whole *security-advisories* Git repo). +- Gautier enhanced the style and content of our HTML advisory index + generator. +- Mango fixed several bugs in *hsec-core* and purged `ZonedTime` + from the codebase. The `Advisory` type now uses `UTCTime`. +- Tristan is adding support for the `GHC` advisory namespace, which + is already defined in the OSV schema. It is for advisories + affecting the compiler or other tools that can not be properly + identified in the `Hackage` namespace. +- Early in Q3 we will publish new versions of most of our packages, + incorporating the changes mentioned above (and more). diff --git a/reports/2024-11-14-Q3-report.md b/reports/2024-11-14-Q3-report.md new file mode 100644 index 00000000..08ad6c65 --- /dev/null +++ b/reports/2024-11-14-Q3-report.md @@ -0,0 +1,144 @@ +# Haskell Security Response Team - 2024 July–October report + new members + +The Haskell Security Response Team (SRT) is a volunteer organization +within the Haskell Foundation that is building tools and processes +to aid the entire Haskell ecosystem in assessing and responding to +security risks. In particular, we maintain a [database][repo] of +security advisories that can serve as a data source for security +tooling. + +This report details the SRT activities from July through October +\2024. We extended this reporting period by one month to include +the results of our recent Call for Volunteers. + +[repo]: https://github.com/haskell/security-advisories + +The SRT is: + +- Fraser Tweedale +- Gautier Di Folco +- Lei Zhu (new!) +- Mihai Maruseac +- Montez Fitzpatrick (new!) +- Tristan de Cacqueray + + +## How to contact the SRT + +For assistance in coordinating a security response to newly +discovered, high impact vulnerabilities, contact +`security-advisories@haskell.org`. Due to limited resources, we can +only coordinate embargoed disclosures for high impact +vulnerabilities affecting current versions of core Haskell tools and +libraries, or in other exceptional cases. + +You can submit lower-impact or historical vulnerabilities to the +advisory database via a pull request to our [GitHub +repository][repo]. + +You can also contact the SRT about non-advisory/security-response +topics. We prefer public communication where possible. In most +cases, [GitHub issues][gh-new-issue] are an appropriate forum. But +the mail address is there if no other appropriate channel exists. + +[gh-new-issue]: https://github.com/haskell/security-advisories/issues/new/choose + + +## Growing the SRT + +Following our mid-year decision to grow the SRT, José on behalf of +the SRT published a [Call for Volunteers]. Applications closed at +the end of September, with 4 applications received. Thank you to +all applicants! We accepted 2 of the proposals, having in mind the +long term sustainability of the SRT as a volunteer organisation +(i.e. we should avoid burning the willing volunteers all at once!) + +The new members of the SRT are: + +- **Lei Zhu**, who brings experience with web security, Linux + security, privacy regulations and threat analysis. Lei has also + contributed to HLS, vscode-haskell, and related projects, and + maintains the *array* package. + +- **Montez Fitzpatrick** has a breadth of cybersecurity experience + across two decades. As CISO of a healthcare company, GRC is + his current focus. He has used Haskell professionally to build + tooling for cybersecurity tasks. + +Welcome to the team! + +[Call for Volunteers]: https://discourse.haskell.org/t/call-for-volunteers-haskell-security-response-team-2024/10287 + + +## Advisory database + +1 contemporary advisory was published during the reporting period. + +0 historical advisories were added during the reporting period. + +2 HSEC IDs (HSEC-2024-0004 and HSEC-2024-0005) **remain** reserved +for embargoed vulnerabilities, which will be published later. + +Additionally, [HSEC-2024-0003] received substantive updates, because +it was discovered that the original fix was incomplete. + +We ask community members to report any known security issues, +including historical issues, that are not yet included. + +[HSEC-2024-0003]: https://osv.dev/vulnerability/HSEC-2024-0003 + + +## `haskell.org` Apache security update + +In early August bug hunter Divya Singh ([Dgirlwhohacks]) notified +the SRT that the version of Apache httpd serving `haskell.org` was +vulnerable to CRLF injection. We escalated the issue to the +[Haskell Infrastructure Admins][haskell-infra], and Gershom Bazerman +promptly resolved the issue by upgrading Apache. Thanks to Divya +for reporting, and Gershom for fixing the issue. + +[Dgirlwhohacks]: https://www.linkedin.com/in/dgirlwhohacks/ +[haskell-infra]: https://github.com/haskell-infra/haskell-admins + + +## *hackage-server* "Reporting Vulnerabilities" link + +Gautier implemented a *Reporting Vulnerabilities* link on package +pages in *hackage-server* ([pull request #1292]). The change has +been deployed on `hackage.haskell.org`. For now it links to +`CONTRIBUTING.md` in the *haskell/security-advisories* GitHub +repository. + +In the future we would like to improve the contributor experience +(e.g. a web form). But this small change is a big improvement +because it alerts users that they *can* report security issues. + +[pull request #1292]: https://github.com/haskell/hackage-server/pull/1292 + + +## Tooling updates + +- CVSS 4.0 support is stalled. andrii (@unorsk) did significant + initial work, and Fraser is reviewing, iterating and integrating + it. CVSS 4.0 is *much* more complex than previous versions, and + parts of the specification are ambiguous. We hope to finish the + implementation and release updates around the end of year. + +- Hécate is working on integrating security advisory data in + *flora-server* ([pull + request](https://github.com/flora-pm/flora-server/pull/762)). + They engaged the SRT for review (Gautier answered the call). + +- Because [Flora](https://flora.pm/) indexes Haskell packages from + namespaces beyond Hackage (e.g. Cardano), there is an ask + ([#240](https://github.com/haskell/security-advisories/issues/240)) + to extend the Advisory DB data model and tooling to support + additional namespaces. We have agreed on the approach but we have + not started implementing it. + +- Mihai has been following the work by Janus Troelsen to add Haskell + support to [Renovate](https://github.com/renovatebot/renovate), an + automated dependency update tool. + - [Feature request](https://github.com/renovatebot/renovate/issues/8187) + - [PVP versioning module discussion](https://github.com/renovatebot/renovate/discussions/31663) + - [PVP versioning scheme pull request (open)](https://github.com/renovatebot/renovate/pull/32298) diff --git a/scripts/run-with-test-config.sh b/scripts/run-with-test-config.sh new file mode 100755 index 00000000..ff6c125e --- /dev/null +++ b/scripts/run-with-test-config.sh @@ -0,0 +1,16 @@ +#!/usr/bin/env bash + +set -eao pipefail + +[ -f ./environment.test.local.sh ] && source ./environment.test.local.sh || source ./environment.test.sh + +export DATALOG_DIR="cbits/" + +if [ -z "$@" ] ; +then + print "Call this script with an argument!" + exit 1 +else + make "$@" +fi + diff --git a/src/advisories/Advisories/Import.hs b/src/advisories/Advisories/Import.hs index cd254102..e366f350 100644 --- a/src/advisories/Advisories/Import.hs +++ b/src/advisories/Advisories/Import.hs @@ -42,7 +42,7 @@ importAdvisories root = Tracing.rootSpan alwaysSampled "import-advisories" $ do Failure failures -> let errors = case NonEmpty.nonEmpty failures of Just nonEmptyFailures -> fmap AdvisoryParsingError nonEmptyFailures - Nothing -> NonEmpty.singleton FackinHell + Nothing -> error "Impossible: Only one error caught." in throwError errors Success advisoryList -> do forM_ advisoryList $ \advisory -> importAdvisory advisory diff --git a/src/advisories/Advisories/Import/Error.hs b/src/advisories/Advisories/Import/Error.hs index 8d761a78..519caf48 100644 --- a/src/advisories/Advisories/Import/Error.hs +++ b/src/advisories/Advisories/Import/Error.hs @@ -9,6 +9,5 @@ import Flora.Model.Package.Types data AdvisoryImportError = AffectedPackageNotFound Namespace PackageName | AdvisoryParsingError (FilePath, ParseAdvisoryError) - | AffectedVersionNotFound PackageId Version - | FackinHell + | AffectedVersionNotFound Namespace PackageName Version deriving stock (Eq, Show, Generic) diff --git a/src/advisories/Advisories/Model/Advisory/Query.hs b/src/advisories/Advisories/Model/Advisory/Query.hs index a19f1830..d95847a8 100644 --- a/src/advisories/Advisories/Model/Advisory/Query.hs +++ b/src/advisories/Advisories/Model/Advisory/Query.hs @@ -2,7 +2,6 @@ module Advisories.Model.Advisory.Query where -import Advisories.Model.Affected.Types import Data.Vector (Vector) import Database.PostgreSQL.Entity import Database.PostgreSQL.Entity.Types @@ -12,6 +11,7 @@ import Effectful.PostgreSQL.Transact.Effect import Security.Advisories.Core.HsecId import Advisories.Model.Advisory.Types +import Advisories.Model.Affected.Types import Flora.Model.Package.Types getAdvisoryById :: DB :> es => AdvisoryId -> Eff es (Maybe AdvisoryDAO) diff --git a/src/advisories/Advisories/Model/Affected/Query.hs b/src/advisories/Advisories/Model/Affected/Query.hs index 4df13297..48a3b2fb 100644 --- a/src/advisories/Advisories/Model/Affected/Query.hs +++ b/src/advisories/Advisories/Model/Affected/Query.hs @@ -4,8 +4,10 @@ module Advisories.Model.Affected.Query where import Data.Vector (Vector) import Database.PostgreSQL.Entity +import Database.PostgreSQL.Entity.DBT (QueryNature (..), query) import Database.PostgreSQL.Entity.Types (field) import Database.PostgreSQL.Simple (Only (..)) +import Database.PostgreSQL.Simple.SqlQQ import Effectful import Effectful.PostgreSQL.Transact.Effect (DB, dbtToEff) import Security.Advisories.Core.HsecId @@ -13,6 +15,7 @@ import Security.Advisories.Core.HsecId import Advisories.HsecId.Orphans () import Advisories.Model.Advisory.Types import Advisories.Model.Affected.Types +import Flora.Model.Package.Types getAffectedPackageById :: DB :> es @@ -37,3 +40,26 @@ getAffectedPackagesByHsecId hsecId = [field| advisory_id |] [field| hsec_id |] hsecId + +getAdvisoryPreviewsByPackageId :: DB :> es => PackageId -> Eff es (Vector PackageAdvisoryPreview) +getAdvisoryPreviewsByPackageId packageId = + dbtToEff $ + query + Select + [sql| +SELECT s0.hsec_id + , s0.summary + , CASE + WHEN a2.fixed_version IS NULL + THEN FALSE + ELSE TRUE + END as fixed + , s0.published + , a1.cvss +FROM security_advisories AS s0 + INNER JOIN affected_packages AS a1 ON s0.advisory_id = a1.advisory_id + INNER JOIN affected_version_ranges AS a2 ON a1.affected_package_id = a2.affected_package_id + INNER JOIN packages AS p3 ON a1.package_id = p3.package_id +WHERE a1.package_id = ? + |] + (Only packageId) diff --git a/src/advisories/Advisories/Model/Affected/Types.hs b/src/advisories/Advisories/Model/Affected/Types.hs index 30dbe316..d8dbfffe 100644 --- a/src/advisories/Advisories/Model/Affected/Types.hs +++ b/src/advisories/Advisories/Model/Affected/Types.hs @@ -3,6 +3,7 @@ module Advisories.Model.Affected.Types where import Control.DeepSeq import Data.Aeson import Data.Text (Text) +import Data.Time (UTCTime) import Data.UUID (UUID) import Data.Vector (Vector) import Database.PostgreSQL.Entity.Types @@ -10,9 +11,11 @@ import Database.PostgreSQL.Simple (FromRow, ToRow) import Database.PostgreSQL.Simple.FromField import Database.PostgreSQL.Simple.Newtypes import Database.PostgreSQL.Simple.ToField -import Distribution.Version +import Distribution.Types.Version +import Distribution.Types.VersionRange (VersionRange) import GHC.Generics import Security.Advisories.Core.Advisory +import Security.Advisories.Core.HsecId import Security.CVSS (CVSS) import Advisories.AffectedVersionRange.Orphans () @@ -72,3 +75,13 @@ data AffectedVersionRangeDAO = AffectedVersionRangeDAO deriving (Entity) via (GenericEntity '[TableName "affected_version_ranges"] AffectedVersionRangeDAO) + +data PackageAdvisoryPreview = PackageAdvisoryPreview + { hsecId :: HsecId + , summary :: Text + , fixed :: Bool + , published :: UTCTime + , cvss :: CVSS + } + deriving stock (Show, Generic) + deriving anyclass (FromRow, NFData) diff --git a/src/core/Flora/Model/Package/Guard.hs b/src/core/Flora/Model/Package/Guard.hs index bfc475ca..8e5edf06 100644 --- a/src/core/Flora/Model/Package/Guard.hs +++ b/src/core/Flora/Model/Package/Guard.hs @@ -15,13 +15,14 @@ guardThatPackageExists -> (Namespace -> PackageName -> Eff es Package) -- ^ Action to run if the package does not exist -> Eff es Package -guardThatPackageExists namespace packageName action = do - result <- - Tracing.childSpan "Query.getPackageByNamespaceAndName " $ - Query.getPackageByNamespaceAndName namespace packageName - case result of - Nothing -> action namespace packageName - Just package -> - case package.status of - FullyImportedPackage -> pure package - UnknownPackage -> action namespace packageName +guardThatPackageExists namespace packageName action = + Tracing.childSpan "guardThatPackageExists " $ do + result <- + Tracing.childSpan "Query.getPackageByNamespaceAndName " $ + Query.getPackageByNamespaceAndName namespace packageName + case result of + Nothing -> action namespace packageName + Just package -> + case package.status of + FullyImportedPackage -> pure package + UnknownPackage -> action namespace packageName diff --git a/src/web/FloraWeb/Common/Guards.hs b/src/web/FloraWeb/Common/Guards.hs index ac0d1d86..4bc51fe4 100644 --- a/src/web/FloraWeb/Common/Guards.hs +++ b/src/web/FloraWeb/Common/Guards.hs @@ -5,8 +5,10 @@ module FloraWeb.Common.Guards where import Data.Text (Text) import Effectful import Effectful.PostgreSQL.Transact.Effect +import Effectful.Trace (Trace) import FloraWeb.Pages.Templates import Log qualified +import Monitor.Tracing qualified as Tracing import Optics.Core import Servant (respond) import Servant.API.UVerb @@ -21,16 +23,19 @@ import FloraWeb.Session (Session) import FloraWeb.Types (FloraEff) guardThatPackageIndexExists - :: DB :> es + :: (DB :> es, Trace :> es) => Namespace -> (Namespace -> Eff es PackageIndex) -- ^ Action to run if the package index does not exist -> Eff es PackageIndex -guardThatPackageIndexExists namespace action = do - result <- Query.getPackageIndexByName (extractNamespaceText namespace) - case result of - Just packageIndex -> pure packageIndex - Nothing -> action namespace +guardThatPackageIndexExists namespace action = + Tracing.childSpan "guardThatPackageIndexExists " $ do + result <- + Tracing.childSpan "Query.getPackageIndexByName" $ + Query.getPackageIndexByName (extractNamespaceText namespace) + case result of + Just packageIndex -> pure packageIndex + Nothing -> action namespace guardThatUserHasProvidedTOTP :: Session (Maybe User) diff --git a/src/web/FloraWeb/Components/AdvisoryListItem.hs b/src/web/FloraWeb/Components/AdvisoryListItem.hs new file mode 100644 index 00000000..8c367180 --- /dev/null +++ b/src/web/FloraWeb/Components/AdvisoryListItem.hs @@ -0,0 +1,39 @@ +module FloraWeb.Components.AdvisoryListItem + ( advisoryListRow + ) where + +import Data.Text.Display +import Data.Time qualified as Time +import Lucid +import Security.CVSS (Rating (..), cvssScore) + +import Advisories.HsecId.Orphans () +import Advisories.Model.Affected.Types +import Control.Monad (when) +import Distribution.Orphans.Version () +import FloraWeb.Components.Pill +import FloraWeb.Pages.Templates.Types + +advisoryListRow + :: PackageAdvisoryPreview + -> FloraHTML +advisoryListRow preview = do + let href = "https://haskell.github.io/security-advisories/advisory/" <> display preview.hsecId <> ".html" + let (rating, score) = cvssScore preview.cvss + let severity = case rating of + None -> ratingNone + Low -> ratingLow score + Medium -> ratingMedium score + High -> ratingHigh score + Critical -> ratingCritical score + div_ [class_ "package-advisory-list-item"] $ do + div_ [class_ "package-advisory-list-item__hsec-id"] $ + a_ [href_ href] (toHtml $ display preview.hsecId) + div_ [class_ "package-advisory-list-item__summary"] (toHtml preview.summary) + div_ [class_ "package-advisory-list-item__published"] $ + toHtml $ + Time.formatTime Time.defaultTimeLocale "%_d %b %Y" preview.published + div_ [class_ "package-advisory-list-item__attributes"] $ do + severity + when preview.fixed $ + fixAvailable diff --git a/src/web/FloraWeb/Components/Pill.hs b/src/web/FloraWeb/Components/Pill.hs index 635d57a7..94a5aa20 100644 --- a/src/web/FloraWeb/Components/Pill.hs +++ b/src/web/FloraWeb/Components/Pill.hs @@ -1,13 +1,45 @@ module FloraWeb.Components.Pill ( customBuildType + , fixAvailable + , ratingCritical + , ratingHigh + , ratingLow + , ratingMedium + , ratingNone ) where import Lucid import FloraWeb.Pages.Templates.Types (FloraHTML) +import Data.Text (Text) +import Data.Text.Display (display) import FloraWeb.Components.Utils (dataText_) customBuildType :: FloraHTML customBuildType = span_ [dataText_ "This package uses the Custom cabal build type", class_ "package-build-type-custom"] "Custom" + +fixAvailable :: FloraHTML +fixAvailable = + span_ [class_ "advisory-list-item__fix-available"] "Fix available" + +ratingCritical :: Float -> FloraHTML +ratingCritical score = + span_ [dataText_ "Critical", class_ "advisory-list-item__severity-critical"] $ toHtml @Text $ "Critical - " <> display score + +ratingHigh :: Float -> FloraHTML +ratingHigh score = + span_ [dataText_ "High", class_ "advisory-list-item__severity-high"] $ toHtml @Text $ "High - " <> display score + +ratingLow :: Float -> FloraHTML +ratingLow score = + span_ [dataText_ "Low", class_ "advisory-list-item__severity-low"] $ toHtml @Text $ "Low - " <> display score + +ratingMedium :: Float -> FloraHTML +ratingMedium score = + span_ [dataText_ "Medium", class_ "advisory-list-item__severity-medium"] $ toHtml @Text $ "Medium - " <> display score + +ratingNone :: FloraHTML +ratingNone = + span_ [dataText_ "None", class_ "advisory-list-item__severity-none"] "None" diff --git a/src/web/FloraWeb/Pages/Routes/Packages.hs b/src/web/FloraWeb/Pages/Routes/Packages.hs index 4ea9b992..b668c230 100644 --- a/src/web/FloraWeb/Pages/Routes/Packages.hs +++ b/src/web/FloraWeb/Pages/Routes/Packages.hs @@ -106,5 +106,12 @@ data Routes' mode = Routes' :> Capture "version" Version :> Capture "tarball" Text :> Get '[GZipped] ByteString + , showPackageSecurity + :: mode + :- AuthProtect "optional-cookie-auth" + :> Capture "namespace" Namespace + :> Capture "package" PackageName + :> "security" + :> Get '[HTML] (Html ()) } deriving stock (Generic) diff --git a/src/web/FloraWeb/Pages/Server/Packages.hs b/src/web/FloraWeb/Pages/Server/Packages.hs index f7d0886d..43e93db9 100644 --- a/src/web/FloraWeb/Pages/Server/Packages.hs +++ b/src/web/FloraWeb/Pages/Server/Packages.hs @@ -13,11 +13,15 @@ import Data.Positive import Data.Text (Text) import Data.Text.Display (display) import Data.Vector qualified as Vector +import Data.Vector.Algorithms.Intro qualified as MVector import Distribution.Orphans () import Distribution.Types.Version (Version) import Effectful (Eff, IOE, (:>)) import Effectful.Error.Static (Error, throwError) +import Effectful.Log (Log) +import Effectful.PostgreSQL.Transact.Effect (DB) import Effectful.Reader.Static (Reader, ask) +import Effectful.Time (Time) import Effectful.Trace import Log (object, (.=)) import Log qualified @@ -27,9 +31,8 @@ import Monitor.Tracing qualified as Tracing import Servant (Headers (..), ServerError, ServerT) import Servant.Server (err404) -import Effectful.Log (Log) -import Effectful.PostgreSQL.Transact.Effect (DB) -import Effectful.Time (Time) +import Advisories.Model.Affected.Query qualified as Query +import Advisories.Model.Affected.Types import Flora.Environment (FeatureEnv (..)) import Flora.Model.BlobIndex.Query qualified as Query import Flora.Model.BlobStore.API (BlobStoreAPI) @@ -70,6 +73,7 @@ server = , showVersionChangelog = showVersionChangelogHandler , listVersions = listVersionsHandler , getTarball = getTarballHandler + , showPackageSecurity = showPackageSecurityHandler } listPackagesHandler @@ -184,13 +188,8 @@ showPackageVersion showPackageVersion (Headers session _) packageNamespace packageName mversion = Tracing.rootSpan alwaysSampled "show-package-with-version" $ do templateEnv' <- templateFromSession session defaultTemplateEnv - package <- - Tracing.childSpan "guardThatPackageExists " $ - guardThatPackageExists packageNamespace packageName (\_ _ -> web404 session) - packageIndex <- - Tracing.childSpan "guardThatPackageIndexExists " $ - guardThatPackageIndexExists packageNamespace $ - const (web404 session) + package <- guardThatPackageExists packageNamespace packageName (\_ _ -> web404 session) + packageIndex <- guardThatPackageIndexExists packageNamespace $ const (web404 session) releases <- Tracing.childSpan "Query.getReleases" $ Query.getReleases package.packageId @@ -468,3 +467,32 @@ getTarballHandler (Headers session _) packageNamespace packageName version tarba | constructTarballPath packageName version == tarballName -> Query.queryTar packageName version rootHash _ -> throwError err404 + +showPackageSecurityHandler + :: ( DB :> es + , Reader FeatureEnv :> es + , IOE :> es + , Error ServerError :> es + , Trace :> es + ) + => SessionWithCookies (Maybe User) + -> Namespace + -> PackageName + -> Eff es (Html ()) +showPackageSecurityHandler (Headers session _) packageNamespace packageName = + Tracing.rootSpan alwaysSampled "show-package-security" $ do + templateEnv' <- templateFromSession session defaultTemplateEnv + package <- guardThatPackageExists packageNamespace packageName (\_ _ -> web404 session) + advisoryPreviews <- + Tracing.childSpan "Query.getAdvisoryPreviewsByPackageId" $ + Query.getAdvisoryPreviewsByPackageId package.packageId + let templateEnv = + templateEnv' + { title = display packageNamespace <> "/" <> display packageName + , description = "Releases of " <> display packageNamespace <> display packageName + } + render templateEnv $ + Package.showPackageSecurityPage + packageNamespace + packageName + (Vector.reverse $ Vector.modify (MVector.sortBy (\v1 v2 -> compare v1.hsecId v2.hsecId)) advisoryPreviews) diff --git a/src/web/FloraWeb/Pages/Templates/Packages.hs b/src/web/FloraWeb/Pages/Templates/Packages.hs index f3e19ee3..185bd1a5 100644 --- a/src/web/FloraWeb/Pages/Templates/Packages.hs +++ b/src/web/FloraWeb/Pages/Templates/Packages.hs @@ -19,9 +19,11 @@ module FloraWeb.Pages.Templates.Packages , packageWithExecutableListing , presentationHeaderForSubpage , presentationHeaderForVersions + , presentationHeaderForAdvisories , showChangelog , showDependencies , showDependents + , showPackageSecurityPage ) where import Control.Monad (when) @@ -52,12 +54,14 @@ import Servant (ToHttpApiData (..)) import Text.PrettyPrint (Doc, hcat, render) import Text.PrettyPrint qualified as PP +import Advisories.Model.Affected.Types import Flora.Environment (FeatureEnv (..)) import Flora.Model.Category.Types import Flora.Model.Package import Flora.Model.Release.Types import Flora.Model.Requirement import Flora.Search (SearchAction (..)) +import FloraWeb.Components.AdvisoryListItem import FloraWeb.Components.Icons qualified as Icon import FloraWeb.Components.PackageListItem ( packageListItem @@ -75,12 +79,14 @@ data Target = Dependents | Dependencies | Versions + | Security deriving stock (Eq, Ord) instance Display Target where displayBuilder Dependents = "dependents" displayBuilder Dependencies = "dependencies" displayBuilder Versions = "versions" + displayBuilder Security = "security" presentationHeaderForSubpage :: Namespace @@ -122,6 +128,19 @@ presentationHeaderForVersions namespace packageName numberOfReleases = div_ [cla display numberOfReleases <> " results" +presentationHeaderForAdvisories + :: Namespace + -> PackageName + -> FloraHTML +presentationHeaderForAdvisories namespace packageName = div_ [class_ "divider"] $ do + div_ [class_ "page-title"] $ h1_ [class_ ""] $ do + span_ [class_ "headline"] $ do + displayNamespace namespace + Icon.chevronRightOutline + linkToPackage namespace packageName + Icon.chevronRightOutline + toHtml (display Security) + showDependents :: Namespace -> PackageName @@ -534,3 +553,20 @@ formatInstallString packageName Release{version} = if List.head (versionNumbers version) == 0 then pretty $ mkVersion $ List.take 3 $ versionNumbers version else pretty $ mkVersion $ List.take 2 $ versionNumbers version + +showPackageSecurityPage + :: Namespace + -> PackageName + -> Vector PackageAdvisoryPreview + -> FloraHTML +showPackageSecurityPage namespace packageName advisoryPreviews = do + div_ [class_ "container"] $ do + presentationHeaderForAdvisories namespace packageName + div_ [class_ "advisory-list"] $ do + div_ [class_ "advisory-list__head"] $ do + div_ [class_ "advisory-list__header"] "ID" + div_ [class_ "advisory-list__header"] "Summary" + div_ [class_ "advisory-list__header"] "Published" + div_ [class_ "advisory-list__header"] "Attributes" + div_ [class_ "advisory-list__body"] $ + Vector.forM_ advisoryPreviews (\preview -> advisoryListRow preview) diff --git a/test/Flora/AdvisorySpec.hs b/test/Flora/AdvisorySpec.hs index c41810e4..3810aa7a 100644 --- a/test/Flora/AdvisorySpec.hs +++ b/test/Flora/AdvisorySpec.hs @@ -1,6 +1,7 @@ module Flora.AdvisorySpec where import Advisories.Model.Advisory.Query qualified as Query +import Advisories.Model.Affected.Query qualified as Query import Data.Vector qualified as Vector import Flora.Model.Package.Query qualified as Query import Flora.Model.Package.Types @@ -10,7 +11,8 @@ spec :: TestEff TestTree spec = testThese "Advisory tests" - [ testThis "Fetching specific advisories by package id" testFetchingAllBiscuitHaskellAdvisories + [ testThis "Fetch advisories by package id" testFetchingAllBiscuitHaskellAdvisories + , testThis "Fetch advisory previews by package id" testFetchingAdvisoryPreviewByPackageId ] testFetchingAllBiscuitHaskellAdvisories :: TestEff () @@ -22,3 +24,23 @@ testFetchingAllBiscuitHaskellAdvisories = do (PackageName "biscuit-haskell") advisories <- Query.getAdvisoriesByPackageId package.packageId assertEqual (Vector.length advisories) 2 + +testFetchingAllBaseAdvisories :: TestEff () +testFetchingAllBaseAdvisories = do + package <- + assertJust + =<< Query.getPackageByNamespaceAndName + (Namespace "haskell") + (PackageName "base") + advisories <- Query.getAdvisoriesByPackageId package.packageId + assertEqual (Vector.length advisories) 1 + +testFetchingAdvisoryPreviewByPackageId :: TestEff () +testFetchingAdvisoryPreviewByPackageId = do + package <- + assertJust + =<< Query.getPackageByNamespaceAndName + (Namespace "haskell") + (PackageName "base") + advisories <- Query.getAdvisoryPreviewsByPackageId package.packageId + assertEqual (Vector.length advisories) 1 diff --git a/test/Flora/PackageSpec.hs b/test/Flora/PackageSpec.hs index 70289179..377c9234 100644 --- a/test/Flora/PackageSpec.hs +++ b/test/Flora/PackageSpec.hs @@ -203,7 +203,7 @@ testGetNonDeprecatedPackages = do testReleaseDeprecation :: TestEff () testReleaseDeprecation = do result <- Query.getHackagePackagesWithoutReleaseDeprecationInformation - assertEqual 79 (length result) + assertEqual 86 (length result) binary <- fromJust <$> Query.getPackageByNamespaceAndName (Namespace "haskell") (PackageName "binary") deprecatedBinaryVersion' <- assertJust =<< Query.getReleaseByVersion binary.packageId (mkVersion [0, 10, 0, 0]) diff --git a/test/Main.hs b/test/Main.hs index c31ce510..b6c3f036 100644 --- a/test/Main.hs +++ b/test/Main.hs @@ -1,13 +1,17 @@ module Main where -import Control.Monad (void) +import Control.Monad.Extra import Data.List.NonEmpty +import Data.Text qualified as Text import Database.PostgreSQL.Entity.DBT (QueryNature (Delete), execute) import Effectful import Effectful.Error.Static +import Effectful.FileSystem import Effectful.PostgreSQL.Transact.Effect (DB, dbtToEff) +import Log qualified import Sel.Hashing.Password qualified as Sel import System.Exit +import System.FilePath (()) import System.IO import Test.Tasty import Test.Tasty.Runners.Reporter qualified as Reporter @@ -48,7 +52,13 @@ main = do Update.insertUser templateUser f' <- getFixtures importAllPackages f' - result <- runErrorNoCallStack @(NonEmpty AdvisoryImportError) (Advisories.importAdvisories "./test/fixtures/Advisories") + result <- runErrorNoCallStack @(NonEmpty AdvisoryImportError) $ do + dataDir <- getXdgDirectory XdgData "" + let advisoriesDirectory = dataDir "security-advisories" + unlessM (doesDirectoryExist advisoriesDirectory) $ do + Log.logAttention_ $ Text.pack $ "Could not find " <> advisoriesDirectory <> ". Clone https://github.com/haskell/security-advisories.git at this location." + liftIO exitFailure + Advisories.importAdvisories advisoriesDirectory case result of Left errors -> do liftIO $ print errors diff --git a/test/fixtures/Cabal/hackage/bz2-0.1.0.0.cabal b/test/fixtures/Cabal/hackage/bz2-0.1.0.0.cabal new file mode 100644 index 00000000..427a6c33 --- /dev/null +++ b/test/fixtures/Cabal/hackage/bz2-0.1.0.0.cabal @@ -0,0 +1,61 @@ +cabal-version: 1.18 +name: bz2 +version: 0.1.0.0 +x-revision: 1 +license: BSD3 +license-file: LICENSE +copyright: Copyright: (c) 2020 Vanessa McHale +maintainer: vamchale@gmail.com +author: Vanessa McHale +bug-reports: https://hub.darcs.net/vmchale/bz2/issues +synopsis: Bindings to libbz2 +description: Low-level bindings to libbz2 using c2hs +category: Compression +build-type: Simple + +extra-doc-files: + README.md + CHANGELOG.md + +source-repository head + type: darcs + location: https://hub.darcs.net/vmchale/bz2 + +flag cross + description: Set this flag if cross-compiling + default: False + manual: True + +library + exposed-modules: + Codec.Compression.BZip.Foreign + + c-sources: + cbits/bzlib.c + cbits/randtable.c + cbits/crctable.c + cbits/compress.c + cbits/blocksort.c + cbits/huffman.c + cbits/decompress.c + + hs-source-dirs: src + + default-language: Haskell2010 + include-dirs: cbits + install-includes: cbits/bzlib.h + ghc-options: -Wall + build-depends: + base >=5 && <5, + bytestring -any + + if !flag(cross) + build-tool-depends: c2hs:c2hs >=0.28 + + if impl(ghc >=8.0) + ghc-options: + -Wincomplete-uni-patterns -Wincomplete-record-updates + -Wredundant-constraints + + if impl(ghc >=8.4) + ghc-options: -Wmissing-export-lists diff --git a/test/fixtures/Cabal/hackage/bz2-1.0.1.1.cabal b/test/fixtures/Cabal/hackage/bz2-1.0.1.1.cabal new file mode 100644 index 00000000..b0fd1340 --- /dev/null +++ b/test/fixtures/Cabal/hackage/bz2-1.0.1.1.cabal @@ -0,0 +1,144 @@ +cabal-version: 2.0 +name: bz2 +version: 1.0.1.1 +license: BSD3 +license-file: LICENSE +copyright: Copyright: (c) 2020 Vanessa McHale +maintainer: vamchale@gmail.com +author: Vanessa McHale +bug-reports: https://hub.darcs.net/vmchale/bz2/issues +synopsis: Bindings to libbz2 +description: High-level bindings to libbz2 via ByteString +category: Compression +build-type: Simple +data-files: + test/data/sample1.ref + test/data/sample2.ref + test/data/sample3.ref + test/data/sample1.bz2 + test/data/sample2.bz2 + test/data/sample3.bz2 + +extra-source-files: + Makefile + +extra-doc-files: + README.md + CHANGELOG.md + +source-repository head + type: darcs + location: https://hub.darcs.net/vmchale/bz2 + +flag cross + description: Set this flag if cross-compiling + default: False + manual: True + +flag with-bzlib + description: + Bench against [bzlib](http://hackage.haskell.org/package/bzlib) + +library + exposed-modules: Codec.Compression.BZip + cc-options: -O3 + + hs-source-dirs: src + other-modules: + Codec.Compression.BZip.Common + Codec.Compression.BZip.Foreign.Common + Codec.Compression.BZip.Foreign.Compress + Codec.Compression.BZip.Foreign.Decompress + Codec.Compression.BZip.Unpack + Codec.Compression.BZip.Pack + + default-language: Haskell2010 + other-extensions: DeriveDataTypeable TupleSections + ghc-options: -Wall + build-depends: + base >=4.7 && <5, + bytestring -any, + bzip2-clib + + + if !flag(cross) + build-tool-depends: c2hs:c2hs >=0.26.1 + + if impl(ghc >=8.0) + ghc-options: + -Wincomplete-uni-patterns -Wincomplete-record-updates + -Wredundant-constraints + + if impl(ghc >=8.4) + ghc-options: -Wmissing-export-lists + + if impl(ghc >=8.10) + ghc-options: -Wunused-packages + +test-suite bz2-test + type: exitcode-stdio-1.0 + main-is: Spec.hs + hs-source-dirs: test + default-language: Haskell2010 + ghc-options: -threaded -rtsopts "-with-rtsopts=-N -K1K" -Wall + build-depends: + base >=4.8, + bz2 -any, + bytestring -any, + filepath >=1.4.0.0, + tasty -any, + tasty-golden -any, + tasty-hunit -any, + deepseq -any, + directory -any + + if impl(ghc >=8.0) + ghc-options: + -Wincomplete-uni-patterns -Wincomplete-record-updates + -Wredundant-constraints -Widentities + + if impl(ghc >=8.4) + ghc-options: -Wmissing-export-lists + + if impl(ghc >=8.2) + ghc-options: -Wcpp-undef + + if impl(ghc >=8.10) + ghc-options: -Wunused-packages + +benchmark bz2-bench + type: exitcode-stdio-1.0 + main-is: Bench.hs + build-tool-depends: cpphs:cpphs -any + hs-source-dirs: bench + other-modules: BZip.Dump + default-language: Haskell2010 + other-extensions: PackageImports + ghc-options: -threaded -rtsopts -with-rtsopts=-N -O3 -Wall + build-depends: + base -any, + bz2 -any, + criterion -any, + temporary -any, + filepath -any, + bytestring -any + + if flag(with-bzlib) + build-depends: bzlib -any + + if flag(with-bzlib) + cpp-options: -DWITH_BZLIB + + if impl(ghc >=8.0) + ghc-options: + -Wincomplete-uni-patterns -Wincomplete-record-updates + -Wredundant-constraints -Widentities + + if impl(ghc >=8.4) + ghc-options: -Wmissing-export-lists + + if impl(ghc >=8.2) + ghc-options: -Wcpp-undef + + if impl(ghc >=8.10) + ghc-options: -Wunused-packages diff --git a/test/fixtures/Cabal/hackage/bzlib-0.4.cabal b/test/fixtures/Cabal/hackage/bzlib-0.4.cabal new file mode 100644 index 00000000..646afff7 --- /dev/null +++ b/test/fixtures/Cabal/hackage/bzlib-0.4.cabal @@ -0,0 +1,41 @@ +name: bzlib +version: 0.4 +x-revision: 1 +copyright: (c) 2006-2007 Duncan Coutts +license: BSD3 +license-file: LICENSE +author: Duncan Coutts +maintainer: Duncan Coutts +synopsis: Compression and decompression in the bzip2 format +stability: provisional +build-type: Simple +cabal-version: >= 1.2.1 + +flag bytestring-in-base + description: In the ghc-6.6 era the bytestring modules were + included in the base package. + +library + exposed-modules: Codec.Compression.BZip, + Codec.Compression.BZip.Internal + other-modules: Codec.Compression.BZip.Stream + extensions: CPP, ForeignFunctionInterface + if flag(bytestring-in-base) + -- bytestring was in base-2.0 and 2.1.1 + build-depends: base >= 2.0 && < 2.2 + cpp-options: -DBYTESTRING_IN_BASE + else + build-depends: base >= 2.2 && < 4.7, bytestring >= 0.9 + includes: bzlib.h + ghc-options: -fvia-C + if !os(windows) + -- Normally we use the the standard system zlib: + extra-libraries: bz2 + else + -- However for the benefit of users of Windows (which does not have zlib + -- by default) we bundle a complete copy of the C sources of bzip2-1.0.4 + c-sources: cbits/blocksort.c cbits/bzlib.c cbits/compress.c + cbits/crctable.c cbits/decompress.c cbits/huffman.c + cbits/randtable.c + include-dirs: cbits + install-includes: bzlib.h diff --git a/test/fixtures/Cabal/hackage/bzlib-0.5.2.0.cabal b/test/fixtures/Cabal/hackage/bzlib-0.5.2.0.cabal new file mode 100644 index 00000000..70d218ba --- /dev/null +++ b/test/fixtures/Cabal/hackage/bzlib-0.5.2.0.cabal @@ -0,0 +1,64 @@ +name: bzlib +version: 0.5.2.0 +copyright: (c) 2006-2015 Duncan Coutts +license: BSD3 +license-file: LICENSE +author: Duncan Coutts +maintainer: Duncan Coutts +bug-reports: https://github.com/haskell/bzlib/issues +category: Codec +synopsis: Compression and decompression in the bzip2 format +description: This package provides a pure interface for compressing and + decompressing streams of data represented as lazy + 'ByteString's. It uses the bz2 C library so it has high + performance. + . + It provides a convenient high level API suitable for most + tasks and for the few cases where more control is needed it + provides access to the full bzip2 feature set. +build-type: Simple +cabal-version: 2.0 +extra-doc-files: README.md CHANGELOG.md +extra-source-files: cbits-extra/hs-bzlib.h + +tested-with: GHC==9.8.2, GHC==9.6.4, GHC==9.4.8, GHC==9.2.8, GHC==9.0.2, GHC==8.10.7, GHC==8.8.4, GHC==8.6.5, GHC==8.4.4, GHC==8.2.2, GHC==8.0.2, GHC==7.10.3, GHC==7.8.4, GHC==7.6.3, GHC==7.4.2, GHC==7.2.2, GHC==7.0.4 + +source-repository head + type: git + location: https://github.com/haskell/bzlib.git + +library + default-language: Haskell2010 + exposed-modules: Codec.Compression.BZip, + Codec.Compression.BZip.Internal + other-modules: Codec.Compression.BZip.Stream + build-depends: base >= 3 && < 5, + bytestring >= 0.9 && < 0.13 + if impl(ghc < 8.0) + build-depends: fail < 5 + if os(windows) + build-depends: base >= 4.11 + includes: bzlib.h + ghc-options: -Wall + if !(os(windows) || impl(ghcjs) || os(ghcjs) || arch(wasm32)) + -- Normally we use the the standard system bz2 lib: + extra-libraries: bz2 + else + build-depends: bzip2-clib < 1.1 + include-dirs: cbits-extra + c-sources: cbits-extra/hs-bzlib.c + +test-suite tests + type: exitcode-stdio-1.0 + main-is: Test.hs + other-modules: Utils, + Test.Codec.Compression.BZip.Internal, + Test.Codec.Compression.BZip.Stream + hs-source-dirs: test + default-language: Haskell2010 + build-depends: base, bytestring, bzlib, + QuickCheck == 2.*, + tasty >= 0.8 && < 1.6, + tasty-quickcheck >= 0.8 && < 0.11, + tasty-hunit >= 0.8 && < 0.11 + ghc-options: -Wall diff --git a/test/fixtures/Cabal/hackage/bzlib-conduit-0.1.0.0.cabal b/test/fixtures/Cabal/hackage/bzlib-conduit-0.1.0.0.cabal new file mode 100644 index 00000000..5a166601 --- /dev/null +++ b/test/fixtures/Cabal/hackage/bzlib-conduit-0.1.0.0.cabal @@ -0,0 +1,66 @@ +name: bzlib-conduit +version: 0.1.0.0 +synopsis: Streaming compression/decompression via conduits. +description: Streaming compression/decompression via conduits. +homepage: https://github.com/tanakh/bzlib-conduit +license: BSD3 +license-file: LICENSE +author: Hideyuki Tanaka +maintainer: tanaka.hideyuki@gmail.com +copyright: (c) 2012, Hideyuki Tanaka +category: Codec +build-type: Simple +cabal-version: >=1.8 + +data-files: test/*.bz2 + test/*.ref + +source-repository head + type: git + location: git://github.com/tanakh/bzlib-conduit.git + +library + exposed-modules: Data.Conduit.BZlib + other-modules: Data.Conduit.BZlib.Internal + + build-depends: base == 4.* + , bytestring == 0.9.* + , mtl == 2.* + , conduit == 0.4.* + , resourcet + , data-default + , bindings-DSL + + if !os(windows) + extra-libraries: bz2 + else + install-includes: bzlib.h, bzlib_private.h + include-dirs: cbits + c-sources: cbits/blocksort.c + cbits/huffman.c + cbits/crctable.c + cbits/randtable.c + cbits/compress.c + cbits/decompress.c + cbits/bzlib.c + +test-suite test + type: exitcode-stdio-1.0 + hs-source-dirs: test + main-is: test.hs + build-depends: base == 4.* + , bytestring == 0.9.* + , hspec == 1.0.* + , HUnit + , QuickCheck + , random + , conduit == 0.4.* + , bzlib-conduit + +benchmark bench + type: exitcode-stdio-1.0 + hs-source-dirs: bench + main-is: bench.hs + build-depends: base == 4.* + , conduit + , bzlib-conduit diff --git a/test/fixtures/Cabal/hackage/bzlib-conduit-0.3.0.3.cabal b/test/fixtures/Cabal/hackage/bzlib-conduit-0.3.0.3.cabal new file mode 100644 index 00000000..0057ea5c --- /dev/null +++ b/test/fixtures/Cabal/hackage/bzlib-conduit-0.3.0.3.cabal @@ -0,0 +1,99 @@ +cabal-version: 1.12 + +-- This file has been generated from package.yaml by hpack version 0.36.0. +-- +-- see: https://github.com/sol/hpack + +name: bzlib-conduit +version: 0.3.0.3 +synopsis: Streaming compression/decompression via conduits. +description: Please see the README and docs at +category: Codec +homepage: https://github.com/snoyberg/bzlib-conduit#readme +bug-reports: https://github.com/snoyberg/bzlib-conduit/issues +author: Hideyuki Tanaka +maintainer: Michael Snoyman +copyright: (c) 2012, Hideyuki Tanaka +license: BSD3 +license-file: LICENSE +build-type: Simple +extra-source-files: + README.md + ChangeLog.md +data-files: + test/sample1.bz2 + test/sample2.bz2 + test/sample3.bz2 + test/sample4.bz2 + test/sample5.bz2 + test/sample1.ref + test/sample2.ref + test/sample3.ref + test/sample4.ref + test/sample5.ref + +source-repository head + type: git + location: https://github.com/snoyberg/bzlib-conduit + +library + exposed-modules: + Data.Conduit.BZlib + Data.Conduit.BZlib.Internal + other-modules: + Paths_bzlib_conduit + hs-source-dirs: + src + build-depends: + base >=4.9 && <10 + , bindings-DSL + , bytestring >=0.9 + , conduit >=1.3 + , data-default-class + , mtl >=2.0 + , resourcet >=1.2 + default-language: Haskell2010 + if !(os(windows)) + extra-libraries: + bz2 + else + build-depends: + bzip2-clib + +test-suite test + type: exitcode-stdio-1.0 + main-is: test.hs + other-modules: + Paths_bzlib_conduit + hs-source-dirs: + test + build-depends: + base >=4.9 && <10 + , bindings-DSL + , bytestring >=0.9 + , bzlib-conduit + , conduit >=1.3 + , data-default-class + , hspec >=1.3 + , mtl >=2.0 + , random + , resourcet >=1.2 + default-language: Haskell2010 + +benchmark bench + type: exitcode-stdio-1.0 + main-is: bench.hs + other-modules: + Paths_bzlib_conduit + hs-source-dirs: + bench + build-depends: + base >=4.9 && <10 + , bindings-DSL + , bytestring >=0.9 + , bzlib-conduit + , conduit >=1.3 + , data-default-class + , mtl >=2.0 + , resourcet >=1.2 + default-language: Haskell2010 diff --git a/test/fixtures/Cabal/hackage/git-annex-5.20140919.cabal b/test/fixtures/Cabal/hackage/git-annex-5.20140919.cabal new file mode 100644 index 00000000..5b2b2dac --- /dev/null +++ b/test/fixtures/Cabal/hackage/git-annex-5.20140919.cabal @@ -0,0 +1,239 @@ +Name: git-annex +Version: 5.20140919 +Cabal-Version: >= 1.8 +License: GPL-3 +Maintainer: Joey Hess +Author: Joey Hess +Stability: Stable +Copyright: 2010-2014 Joey Hess +License-File: COPYRIGHT +Extra-Source-Files: CHANGELOG +Homepage: http://git-annex.branchable.com/ +Build-type: Custom +Category: Utility +Synopsis: manage files with git, without checking their contents into git +Description: + git-annex allows managing files with git, without checking the file + contents into git. While that may seem paradoxical, it is useful when + dealing with files larger than git can currently easily handle, whether due + to limitations in memory, time, or disk space. + . + Even without file content tracking, being able to manage files with git, + move files around and delete files with versioned directory trees, and use + branches and distributed clones, are all very handy reasons to use git. And + annexed files can co-exist in the same git repository with regularly + versioned files, which is convenient for maintaining documents, Makefiles, + etc that are associated with annexed files but that benefit from full + revision control. + +Flag S3 + Description: Enable S3 support + +Flag WebDAV + Description: Enable WebDAV support + +Flag Inotify + Description: Enable inotify support + +Flag Dbus + Description: Enable dbus support + +Flag Assistant + Description: Enable git-annex assistant and watch command + +Flag Webapp + Description: Enable git-annex webapp + +Flag Webapp-secure + Description: Secure webapp + +Flag Pairing + Description: Enable pairing + +Flag XMPP + Description: Enable notifications using XMPP + +Flag DNS + Description: Enable the haskell DNS library for DNS lookup + +Flag Production + Description: Enable production build (slower build; faster binary) + +Flag Android + Description: Cross building for Android + Default: False + +Flag AndroidSplice + Description: Building to get TH splices for Android + Default: False + +Flag TestSuite + Description: Embed the test suite into git-annex + +Flag TDFA + Description: Use regex-tdfa for wildcards + +Flag Feed + Description: Enable podcast feed support + +Flag Quvi + Description: Enable use of quvi to download videos + +Flag Tahoe + Description: Enable the tahoe special remote + +Flag CryptoHash + Description: Enable use of cryptohash for checksumming + +Flag DesktopNotify + Description: Enable desktop environment notifications + +Flag EKG + Description: Enable use of EKG to monitor git-annex as it runs (at http://localhost:4242/) + Default: False + +Flag network-uri + Description: Get Network.URI from the network-uri package + Default: True + +Executable git-annex + Main-Is: git-annex.hs + Build-Depends: MissingH, hslogger, directory, filepath, + containers, utf8-string, mtl (>= 2), + bytestring, old-locale, time, dataenc, SHA, process, json, + base (>= 4.5 && < 4.9), monad-control, exceptions (>= 0.6), transformers, + IfElse, text, QuickCheck >= 2.1, bloomfilter, edit-distance, process, + SafeSemaphore, uuid, random, dlist, unix-compat, async, stm (>= 2.3), + data-default, case-insensitive, http-conduit, http-types + CC-Options: -Wall + GHC-Options: -Wall + Extensions: PackageImports + -- Some things don't work with the non-threaded RTS. + GHC-Options: -threaded + + if flag(network-uri) + Build-Depends: network-uri (>= 2.6), network (>= 2.6) + else + Build-Depends: network (< 2.6), network (>= 2.0) + + if flag(Production) + GHC-Options: -O2 + + if (os(windows)) + Build-Depends: Win32, Win32-extras, unix-compat (>= 0.4.1.3) + C-Sources: Utility/winprocess.c + else + Build-Depends: unix + -- Need to list these because they're generated from .hsc files. + Other-Modules: Utility.Touch Utility.Mounts + Include-Dirs: Utility + C-Sources: Utility/libdiskfree.c Utility/libmounts.c + CPP-Options: -DWITH_CLIBS + + if flag(TestSuite) + Build-Depends: tasty (>= 0.7), tasty-hunit, tasty-quickcheck, tasty-rerun, + optparse-applicative (>= 0.9.1), crypto-api + CPP-Options: -DWITH_TESTSUITE + + if flag(TDFA) + Build-Depends: regex-tdfa + CPP-Options: -DWITH_TDFA + else + Build-Depends: regex-compat + + if flag(CryptoHash) + Build-Depends: cryptohash (>= 0.10.0) + CPP-Options: -DWITH_CRYPTOHASH + + if flag(S3) + Build-Depends: hS3 + CPP-Options: -DWITH_S3 + + if flag(WebDAV) + Build-Depends: DAV (>= 1.0), http-client + CPP-Options: -DWITH_WEBDAV + + if flag(Assistant) && ! os(solaris) + CPP-Options: -DWITH_ASSISTANT + + if flag(Assistant) + if os(linux) && flag(Inotify) + Build-Depends: hinotify + CPP-Options: -DWITH_INOTIFY + else + if os(darwin) + Build-Depends: hfsevents + CPP-Options: -DWITH_FSEVENTS + else + if os(windows) + Build-Depends: Win32-notify + CPP-Options: -DWITH_WIN32NOTIFY + else + if (! os(solaris) && ! os(linux)) + if flag(Android) + Build-Depends: hinotify + CPP-Options: -DWITH_INOTIFY + else + CPP-Options: -DWITH_KQUEUE + C-Sources: Utility/libkqueue.c + + if (os(linux)) + if flag(Dbus) + Build-Depends: dbus (>= 0.10.3) + CPP-Options: -DWITH_DBUS + + if flag(DesktopNotify) + if flag(Dbus) + Build-Depends: dbus (>= 0.10.3), fdo-notify (>= 0.3) + CPP-Options: -DWITH_DESKTOP_NOTIFY -DWITH_DBUS_NOTIFICATIONS + + if flag(Android) + Build-Depends: data-endian + CPP-Options: -D__ANDROID__ -DANDROID_SPLICES -D__NO_TH__ + if flag(AndroidSplice) + CPP-Options: -DANDROID_SPLICES + + if flag(Webapp) + Build-Depends: + yesod, yesod-default, yesod-static, yesod-form, yesod-core, + wai, wai-extra, warp, warp-tls, + blaze-builder, crypto-api, hamlet, clientsession, + template-haskell, data-default, aeson, path-pieces, + shakespeare + CPP-Options: -DWITH_WEBAPP + if flag(Webapp) && flag (Webapp-secure) + Build-Depends: warp-tls (>= 1.4), securemem, byteable + CPP-Options: -DWITH_WEBAPP_SECURE + + if flag(Pairing) + Build-Depends: network-multicast, network-info + CPP-Options: -DWITH_PAIRING + + if flag(XMPP) && (! os(windows)) + Build-Depends: network-protocol-xmpp, gnutls (>= 0.1.4), xml-types + CPP-Options: -DWITH_XMPP + + if flag(DNS) + Build-Depends: dns + CPP-Options: -DWITH_DNS + + if flag(Feed) + Build-Depends: feed + CPP-Options: -DWITH_FEED + + if flag(Quvi) + Build-Depends: aeson + CPP-Options: -DWITH_QUVI + + if flag(Tahoe) + Build-Depends: aeson + CPP-Options: -DWITH_TAHOE + + if flag(EKG) + Build-Depends: ekg + GHC-Options: -with-rtsopts=-T + CPP-Options: -DWITH_EKG + +source-repository head + type: git + location: git://git-annex.branchable.com/ diff --git a/test/fixtures/Cabal/hackage/git-annex-6.20160419.cabal b/test/fixtures/Cabal/hackage/git-annex-6.20160419.cabal new file mode 100644 index 00000000..23baea6f --- /dev/null +++ b/test/fixtures/Cabal/hackage/git-annex-6.20160419.cabal @@ -0,0 +1,252 @@ +Name: git-annex +Version: 6.20160419 +Cabal-Version: >= 1.8 +License: GPL-3 +Maintainer: Joey Hess +Author: Joey Hess +Stability: Stable +Copyright: 2010-2014 Joey Hess +License-File: COPYRIGHT +Extra-Source-Files: CHANGELOG +Homepage: http://git-annex.branchable.com/ +Build-type: Custom +Category: Utility +Synopsis: manage files with git, without checking their contents into git +Description: + git-annex allows managing files with git, without checking the file + contents into git. While that may seem paradoxical, it is useful when + dealing with files larger than git can currently easily handle, whether due + to limitations in memory, time, or disk space. + . + It can store large files in many places, from local hard drives, to a + large number of cloud storage services, including S3, WebDAV, + and rsync, with a dozen cloud storage providers usable via plugins. + Files can be stored encrypted with gpg, so that the cloud storage + provider cannot see your data. git-annex keeps track of where each file + is stored, so it knows how many copies are available, and has many + facilities to ensure your data is preserved. + . + git-annex can also be used to keep a folder in sync between computers, + noticing when files are changed, and automatically committing them + to git and transferring them to other computers. The git-annex webapp + makes it easy to set up and use git-annex this way. + +Flag S3 + Description: Enable S3 support + +Flag WebDAV + Description: Enable WebDAV support + +Flag Assistant + Description: Enable git-annex assistant and watch command + +Flag Webapp + Description: Enable git-annex webapp + +Flag Pairing + Description: Enable pairing + +Flag Production + Description: Enable production build (slower build; faster binary) + +Flag Android + Description: Cross building for Android + Default: False + +Flag AndroidSplice + Description: Building to get TH splices for Android + Default: False + +Flag TestSuite + Description: Embed the test suite into git-annex + +Flag TorrentParser + Description: Use haskell torrent library to parse torrent files + +Flag MagicMime + Description: Use libmagic to determine file MIME types + +Flag ConcurrentOutput + Description: Use concurrent-output library + +Flag EKG + Description: Enable use of EKG to monitor git-annex as it runs (at http://localhost:4242/) + Default: False + +Flag Benchmark + Description: Enable benchmarking + Default: False + +Flag network-uri + Description: Get Network.URI from the network-uri package + Default: True + +Flag Cryptonite + Description: Use the cryptonite library, instead of the older cryptohash + +Flag Dbus + Description: Enable dbus support + +Flag XMPP + Description: Enable notifications using XMPP + +Executable git-annex + Main-Is: git-annex.hs + Build-Depends: + base (>= 4.5 && < 4.9), + optparse-applicative (>= 0.11.0), + containers (>= 0.5.0.0), + exceptions (>= 0.6), + QuickCheck (>= 2.1), + stm (>= 2.3), + mtl (>= 2), + process, data-default, case-insensitive, uuid, random, dlist, + unix-compat, SafeSemaphore, async, directory, filepath, IfElse, + MissingH, hslogger, monad-logger, + utf8-string, bytestring, text, sandi, json, + monad-control, transformers, + bloomfilter, edit-distance, + resourcet, http-conduit, http-client, http-types, + time, old-locale, + esqueleto, persistent-sqlite, persistent, persistent-template, + aeson, + feed, + regex-tdfa + CC-Options: -Wall + GHC-Options: -Wall -fno-warn-tabs + Extensions: PackageImports + -- Some things don't work with the non-threaded RTS. + GHC-Options: -threaded + + -- Fully optimize for production. + if flag(Production) + GHC-Options: -O2 + + -- Avoid linking with unused dynamic libaries. + -- (Only tested on Linux). + if os(Linux) + GHC-Options: -optl-Wl,--as-needed + + if flag(network-uri) + Build-Depends: network-uri (>= 2.6), network (>= 2.6) + else + Build-Depends: network (< 2.6), network (>= 2.4) + + if flag(Cryptonite) + Build-Depends: cryptonite + CPP-Options: -DWITH_CRYPTONITE + else + Build-Depends: cryptohash (>= 0.11.0) + + if (os(windows)) + Build-Depends: Win32, Win32-extras, unix-compat (>= 0.4.1.3), setenv, + process (>= 1.3.0.0) + else + Build-Depends: unix + if impl(ghc <= 7.6.3) + Other-Modules: Utility.Touch.Old + + if flag(TestSuite) + Build-Depends: tasty (>= 0.7), tasty-hunit, tasty-quickcheck, tasty-rerun, + crypto-api + CPP-Options: -DWITH_TESTSUITE + + if flag(S3) + Build-Depends: conduit, conduit-extra, aws (>= 0.9.2) + CPP-Options: -DWITH_S3 + + if flag(WebDAV) + Build-Depends: DAV (>= 1.0) + CPP-Options: -DWITH_WEBDAV + + if flag(Assistant) && ! os(solaris) + Build-Depends: dns, mountpoints + CPP-Options: -DWITH_ASSISTANT + + if flag(Assistant) + if os(linux) + Build-Depends: hinotify + CPP-Options: -DWITH_INOTIFY + else + if os(darwin) + Build-Depends: hfsevents + CPP-Options: -DWITH_FSEVENTS + else + if os(windows) + Build-Depends: Win32-notify + CPP-Options: -DWITH_WIN32NOTIFY + else + if (! os(solaris) && ! os(linux)) + if flag(Android) + Build-Depends: hinotify + CPP-Options: -DWITH_INOTIFY + else + CPP-Options: -DWITH_KQUEUE + C-Sources: Utility/libkqueue.c + + if flag(Dbus) + if (os(linux)) + Build-Depends: dbus (>= 0.10.7), fdo-notify (>= 0.3) + CPP-Options: -DWITH_DBUS -DWITH_DESKTOP_NOTIFY -DWITH_DBUS_NOTIFICATIONS + + if flag(Android) + Build-Depends: data-endian + CPP-Options: -D__ANDROID__ -DANDROID_SPLICES -D__NO_TH__ + else + Build-Depends: disk-free-space + + if flag(AndroidSplice) + CPP-Options: -DANDROID_SPLICES + + if flag(Webapp) + Build-Depends: + yesod (>= 1.2.6), + yesod-default (>= 1.2.0), + yesod-static (>= 1.2.4), + yesod-form (>= 1.3.15), + yesod-core (>= 1.2.19), + path-pieces (>= 0.1.4), + warp (>= 3.0.0.5), + warp-tls (>= 1.4), + wai, wai-extra, + blaze-builder, crypto-api, clientsession, + template-haskell, + shakespeare (>= 2.0.0), + securemem, + byteable + CPP-Options: -DWITH_WEBAPP + + if flag(Pairing) + Build-Depends: network-multicast, network-info + CPP-Options: -DWITH_PAIRING + + if flag(XMPP) + if (! os(windows)) + Build-Depends: network-protocol-xmpp, gnutls (>= 0.1.4), xml-types + CPP-Options: -DWITH_XMPP + + if flag(TorrentParser) + Build-Depends: torrent (>= 10000.0.0) + CPP-Options: -DWITH_TORRENTPARSER + + if flag(MagicMime) + if (! os(windows)) + Build-Depends: magic + CPP-Options: -DWITH_MAGICMIME + + if flag(ConcurrentOutput) + Build-Depends: concurrent-output (>= 1.6) + CPP-Options: -DWITH_CONCURRENTOUTPUT + + if flag(EKG) + Build-Depends: ekg + GHC-Options: -with-rtsopts=-T + CPP-Options: -DWITH_EKG + + if flag(Benchmark) + Build-Depends: criterion, deepseq + CPP-Options: -DWITH_BENCHMARK + +source-repository head + type: git + location: git://git-annex.branchable.com/ diff --git a/test/fixtures/Cabal/hackage/git-annex-6.20170818.cabal b/test/fixtures/Cabal/hackage/git-annex-6.20170818.cabal new file mode 100644 index 00000000..16b6bda2 --- /dev/null +++ b/test/fixtures/Cabal/hackage/git-annex-6.20170818.cabal @@ -0,0 +1,1065 @@ +Name: git-annex +Version: 6.20170818 +Cabal-Version: >= 1.8 +License: GPL-3 +Maintainer: Joey Hess +Author: Joey Hess +Stability: Stable +Copyright: 2010-2017 Joey Hess +License-File: COPYRIGHT +Homepage: http://git-annex.branchable.com/ +Build-type: Custom +Category: Utility +Synopsis: manage files with git, without checking their contents into git +Description: + git-annex allows managing files with git, without checking the file + contents into git. While that may seem paradoxical, it is useful when + dealing with files larger than git can currently easily handle, whether due + to limitations in memory, time, or disk space. + . + It can store large files in many places, from local hard drives, to a + large number of cloud storage services, including S3, WebDAV, + and rsync, with a dozen cloud storage providers usable via plugins. + Files can be stored encrypted with gpg, so that the cloud storage + provider cannot see your data. git-annex keeps track of where each file + is stored, so it knows how many copies are available, and has many + facilities to ensure your data is preserved. + . + git-annex can also be used to keep a folder in sync between computers, + noticing when files are changed, and automatically committing them + to git and transferring them to other computers. The git-annex webapp + makes it easy to set up and use git-annex this way. +-- The tarball uploaded to hackage does not include every non-haskell +-- file in the git repo. The website is left out, so is build machinary for +-- standalone apps, and packages. Include only files that are needed +-- make cabal install git-annex work. +Extra-Source-Files: + stack.yaml + README + CHANGELOG + NEWS + doc/license/GPL + doc/license/AGPL + doc/git-annex.mdwn + doc/git-annex-add.mdwn + doc/git-annex-addunused.mdwn + doc/git-annex-addurl.mdwn + doc/git-annex-adjust.mdwn + doc/git-annex-assistant.mdwn + doc/git-annex-calckey.mdwn + doc/git-annex-checkpresentkey.mdwn + doc/git-annex-contentlocation.mdwn + doc/git-annex-copy.mdwn + doc/git-annex-dead.mdwn + doc/git-annex-describe.mdwn + doc/git-annex-diffdriver.mdwn + doc/git-annex-direct.mdwn + doc/git-annex-drop.mdwn + doc/git-annex-dropkey.mdwn + doc/git-annex-dropunused.mdwn + doc/git-annex-edit.mdwn + doc/git-annex-enableremote.mdwn + doc/git-annex-enable-tor.mdwn + doc/git-annex-examinekey.mdwn + doc/git-annex-expire.mdwn + doc/git-annex-find.mdwn + doc/git-annex-findref.mdwn + doc/git-annex-fix.mdwn + doc/git-annex-forget.mdwn + doc/git-annex-fromkey.mdwn + doc/git-annex-fsck.mdwn + doc/git-annex-fuzztest.mdwn + doc/git-annex-get.mdwn + doc/git-annex-group.mdwn + doc/git-annex-groupwanted.mdwn + doc/git-annex-import.mdwn + doc/git-annex-importfeed.mdwn + doc/git-annex-indirect.mdwn + doc/git-annex-info.mdwn + doc/git-annex-init.mdwn + doc/git-annex-initremote.mdwn + doc/git-annex-list.mdwn + doc/git-annex-lock.mdwn + doc/git-annex-log.mdwn + doc/git-annex-lookupkey.mdwn + doc/git-annex-map.mdwn + doc/git-annex-matchexpression.mdwn + doc/git-annex-matching-options.mdwn + doc/git-annex-merge.mdwn + doc/git-annex-metadata.mdwn + doc/git-annex-migrate.mdwn + doc/git-annex-mirror.mdwn + doc/git-annex-move.mdwn + doc/git-annex-multicast.mdwn + doc/git-annex-numcopies.mdwn + doc/git-annex-p2p.mdwn + doc/git-annex-pre-commit.mdwn + doc/git-annex-preferred-content.mdwn + doc/git-annex-proxy.mdwn + doc/git-annex-readpresentkey.mdwn + doc/git-annex-registerurl.mdwn + doc/git-annex-reinit.mdwn + doc/git-annex-reinject.mdwn + doc/git-annex-rekey.mdwn + doc/git-annex-remotedaemon.mdwn + doc/git-annex-repair.mdwn + doc/git-annex-required.mdwn + doc/git-annex-resolvemerge.mdwn + doc/git-annex-rmurl.mdwn + doc/git-annex-schedule.mdwn + doc/git-annex-semitrust.mdwn + doc/git-annex-setkey.mdwn + doc/git-annex-setpresentkey.mdwn + doc/git-annex-shell.mdwn + doc/git-annex-smudge.mdwn + doc/git-annex-status.mdwn + doc/git-annex-sync.mdwn + doc/git-annex-test.mdwn + doc/git-annex-testremote.mdwn + doc/git-annex-transferkey.mdwn + doc/git-annex-transferkeys.mdwn + doc/git-annex-trust.mdwn + doc/git-annex-unannex.mdwn + doc/git-annex-undo.mdwn + doc/git-annex-ungroup.mdwn + doc/git-annex-uninit.mdwn + doc/git-annex-unlock.mdwn + doc/git-annex-untrust.mdwn + doc/git-annex-unused.mdwn + doc/git-annex-upgrade.mdwn + doc/git-annex-vadd.mdwn + doc/git-annex-vcycle.mdwn + doc/git-annex-version.mdwn + doc/git-annex-vfilter.mdwn + doc/git-annex-vicfg.mdwn + doc/git-annex-view.mdwn + doc/git-annex-vpop.mdwn + doc/git-annex-wanted.mdwn + doc/git-annex-watch.mdwn + doc/git-annex-webapp.mdwn + doc/git-annex-whereis.mdwn + doc/git-remote-tor-annex.mdwn + doc/logo.svg + doc/logo_16x16.png + Build/mdwn2man + Assistant/WebApp/routes + static/activityicon.gif + static/css/bootstrap.css + static/css/bootstrap-theme.css + static/js/jquery.ui.core.js + static/js/longpolling.js + static/js/jquery.full.js + static/js/jquery.ui.sortable.js + static/js/jquery.ui.mouse.js + static/js/jquery.ui.widget.js + static/js/bootstrap.js + static/syncicon.gif + static/favicon.ico + static/fonts/glyphicons-halflings-regular.woff + static/fonts/glyphicons-halflings-regular.eot + static/fonts/glyphicons-halflings-regular.svg + static/fonts/glyphicons-halflings-regular.ttf + templates/sidebar/main.hamlet + templates/sidebar/alert.hamlet + templates/bootstrap.hamlet + templates/error.cassius + templates/README + templates/error.hamlet + templates/documentation/license.hamlet + templates/documentation/repogroup.hamlet + templates/documentation/about.hamlet + templates/dashboard/main.hamlet + templates/dashboard/transfers.cassius + templates/dashboard/transfers.hamlet + templates/dashboard/metarefresh.hamlet + templates/page.cassius + templates/page.hamlet + templates/control/repairrepository.hamlet + templates/control/repairrepository/done.hamlet + templates/control/notrunning.julius + templates/control/notrunning.hamlet + templates/control/repositoryswitcher.hamlet + templates/control/shutdown.hamlet + templates/control/log.hamlet + templates/page.julius + templates/repolist.julius + templates/configurators/adddrive/combine.hamlet + templates/configurators/adddrive/setupmodal.hamlet + templates/configurators/adddrive/encrypt.hamlet + templates/configurators/newrepository.hamlet + templates/configurators/needglaciercli.hamlet + templates/configurators/adds3.hamlet + templates/configurators/genkeymodal.hamlet + templates/configurators/main.hamlet + templates/configurators/needconnection.hamlet + templates/configurators/newrepository/form.hamlet + templates/configurators/newrepository/first.hamlet + templates/configurators/newrepository/combine.hamlet + templates/configurators/enablewebdav.hamlet + templates/configurators/pairing/local/inprogress.hamlet + templates/configurators/pairing/local/prompt.hamlet + templates/configurators/pairing/wormhole/prompt.hamlet + templates/configurators/pairing/wormhole/start.hamlet + templates/configurators/pairing/disabled.hamlet + templates/configurators/addglacier.hamlet + templates/configurators/fsck.cassius + templates/configurators/edit/nonannexremote.hamlet + templates/configurators/edit/webrepository.hamlet + templates/configurators/edit/repository.hamlet + templates/configurators/unused.hamlet + templates/configurators/addbox.com.hamlet + templates/configurators/ssh/testmodal.hamlet + templates/configurators/ssh/expiredpassword.hamlet + templates/configurators/ssh/error.hamlet + templates/configurators/ssh/combine.hamlet + templates/configurators/ssh/enable.hamlet + templates/configurators/ssh/add.hamlet + templates/configurators/ssh/setupmodal.hamlet + templates/configurators/ssh/confirm.hamlet + templates/configurators/upgrade/android.hamlet + templates/configurators/enableia.hamlet + templates/configurators/fsck.hamlet + templates/configurators/addrepository/archive.hamlet + templates/configurators/addrepository/cloud.hamlet + templates/configurators/addrepository/connection.hamlet + templates/configurators/addrepository/ssh.hamlet + templates/configurators/addrepository/misc.hamlet + templates/configurators/addrepository/wormholepairing.hamlet + templates/configurators/rsync.net/add.hamlet + templates/configurators/rsync.net/encrypt.hamlet + templates/configurators/gitlab.com/add.hamlet + templates/configurators/needgcrypt.hamlet + templates/configurators/needtor.hamlet + templates/configurators/needmagicwormhole.hamlet + templates/configurators/enabledirectory.hamlet + templates/configurators/fsck/status.hamlet + templates/configurators/fsck/form.hamlet + templates/configurators/fsck/preferencesform.hamlet + templates/configurators/fsck/formcontent.hamlet + templates/configurators/delete/finished.hamlet + templates/configurators/delete/start.hamlet + templates/configurators/delete/currentrepository.hamlet + templates/configurators/unused/form.hamlet + templates/configurators/adddrive.hamlet + templates/configurators/preferences.hamlet + templates/configurators/addia.hamlet + templates/configurators/enableaws.hamlet + templates/configurators/addrepository.hamlet + templates/actionbutton.hamlet + templates/repolist.hamlet + templates/controlmenu.hamlet + templates/notifications/longpolling.julius + +Flag S3 + Description: Enable S3 support + +Flag WebDAV + Description: Enable WebDAV support + +Flag Assistant + Description: Enable git-annex assistant and watch command + +Flag Webapp + Description: Enable git-annex webapp + +Flag Pairing + Description: Enable pairing + +Flag Production + Description: Enable production build (slower build; faster binary) + +Flag Android + Description: Cross building for Android + Default: False + +Flag AndroidSplice + Description: Building to get TH splices for Android + Default: False + +Flag TestSuite + Description: Embed the test suite into git-annex + +Flag TorrentParser + Description: Use haskell torrent library to parse torrent files + +Flag MagicMime + Description: Use libmagic to determine file MIME types + +Flag ConcurrentOutput + Description: Use concurrent-output library + +Flag Benchmark + Description: Enable benchmarking + Default: False + +Flag network-uri + Description: Get Network.URI from the network-uri package + Default: True + +Flag Dbus + Description: Enable dbus support + +source-repository head + type: git + location: git://git-annex.branchable.com/ + +custom-setup + Setup-Depends: base (>= 4.5), hslogger, split, unix-compat, process, + unix, filepath, exceptions, bytestring, directory, IfElse, data-default, + Cabal + +Executable git-annex + Main-Is: git-annex.hs + Build-Depends: + base (>= 4.5 && < 5.0), + optparse-applicative (>= 0.11.0), + containers (>= 0.5.0.0), + exceptions (>= 0.6), + QuickCheck (>= 2.1), + stm (>= 2.3), + mtl (>= 2), + uuid (>= 1.2.6), + process, + data-default, + case-insensitive, + random, + dlist, + unix-compat, + SafeSemaphore, + async, + directory (>= 1.2), + filepath, + IfElse, + hslogger, + monad-logger, + free, + utf8-string, + bytestring, + text, + sandi, + monad-control, + transformers, + bloomfilter, + edit-distance, + resourcet, + http-client, + http-types (>= 0.7), + http-conduit (>= 2.0), + time, + old-locale, + esqueleto, + persistent-sqlite, + persistent, + persistent-template, + aeson, + unordered-containers, + feed (>= 0.3.9), + regex-tdfa, + socks, + byteable, + stm-chans, + securemem, + crypto-api, + cryptonite, + memory, + split + CC-Options: -Wall + GHC-Options: -Wall -fno-warn-tabs + Extensions: PackageImports + -- Some things don't work with the non-threaded RTS. + GHC-Options: -threaded + Other-Extensions: TemplateHaskell + + -- Fully optimize for production. + if flag(Production) + GHC-Options: -O2 + + -- Avoid linking with unused dynamic libaries. + -- (Only tested on Linux). + if os(Linux) + GHC-Options: -optl-Wl,--as-needed + + if flag(network-uri) + Build-Depends: network-uri (>= 2.6), network (>= 2.6) + else + Build-Depends: network (< 2.6), network (>= 2.4) + + if (os(windows)) + Build-Depends: Win32 (>= 2.5), unix-compat (>= 0.4.1.3), setenv, + process (>= 1.4.2.0) + else + Build-Depends: unix + if impl(ghc <= 7.6.3) + Other-Modules: Utility.Touch.Old + + if flag(TestSuite) + Build-Depends: tasty (>= 0.7), tasty-hunit, tasty-quickcheck, tasty-rerun + CPP-Options: -DWITH_TESTSUITE + + if flag(S3) + Build-Depends: conduit, conduit-extra, aws (>= 0.9.2) + CPP-Options: -DWITH_S3 + + if flag(WebDAV) + Build-Depends: DAV (>= 1.0) + CPP-Options: -DWITH_WEBDAV + + if flag(Assistant) && ! os(solaris) + Build-Depends: dns (>= 1.0.0), mountpoints + CPP-Options: -DWITH_ASSISTANT + + if flag(Assistant) + if os(linux) || flag(Android) + Build-Depends: hinotify + CPP-Options: -DWITH_INOTIFY + Other-Modules: Utility.DirWatcher.INotify + else + if os(darwin) + Build-Depends: hfsevents + CPP-Options: -DWITH_FSEVENTS + Other-Modules: Utility.DirWatcher.FSEvents + else + if os(windows) + Build-Depends: Win32-notify + CPP-Options: -DWITH_WIN32NOTIFY + Other-Modules: Utility.DirWatcher.Win32Notify + else + if (! os(solaris) && ! os(linux)) + CPP-Options: -DWITH_KQUEUE + C-Sources: Utility/libkqueue.c + Other-Modules: Utility.DirWatcher.Kqueue + + if flag(Dbus) + if (os(linux)) + Build-Depends: dbus (>= 0.10.7), fdo-notify (>= 0.3) + CPP-Options: -DWITH_DBUS -DWITH_DESKTOP_NOTIFY -DWITH_DBUS_NOTIFICATIONS + Other-Modules: Utility.DBus + + if flag(Android) + Build-Depends: data-endian + CPP-Options: -D__ANDROID__ -DANDROID_SPLICES -D__NO_TH__ + else + Build-Depends: disk-free-space + + if flag(AndroidSplice) + CPP-Options: -DANDROID_SPLICES + + if flag(Webapp) + Build-Depends: + yesod (>= 1.2.6), + yesod-default (>= 1.2.0), + yesod-static (>= 1.2.4), + yesod-form (>= 1.3.15), + yesod-core (>= 1.2.19), + path-pieces (>= 0.1.4), + warp (>= 3.0.0.5), + warp-tls (>= 1.4), + wai, + wai-extra, + blaze-builder, + clientsession, + template-haskell, + shakespeare (>= 2.0.0) + CPP-Options: -DWITH_WEBAPP + + if flag(Pairing) + Build-Depends: network-multicast, network-info + CPP-Options: -DWITH_PAIRING + + if flag(TorrentParser) + Build-Depends: torrent (>= 10000.0.0) + CPP-Options: -DWITH_TORRENTPARSER + + if flag(MagicMime) + if (! os(windows)) + Build-Depends: magic + CPP-Options: -DWITH_MAGICMIME + + if flag(ConcurrentOutput) + Build-Depends: concurrent-output (>= 1.6) + CPP-Options: -DWITH_CONCURRENTOUTPUT + + if flag(Benchmark) + Build-Depends: criterion, deepseq + CPP-Options: -DWITH_BENCHMARK + Other-Modules: Command.Benchmark + + Other-Modules: + Annex + Annex.Action + Annex.AdjustedBranch + Annex.AutoMerge + Annex.BloomFilter + Annex.Branch + Annex.Branch.Transitions + Annex.BranchState + Annex.CatFile + Annex.ChangedRefs + Annex.CheckAttr + Annex.CheckIgnore + Annex.Common + Annex.Concurrent + Annex.Content + Annex.Content.Direct + Annex.Difference + Annex.DirHashes + Annex.Direct + Annex.Drop + Annex.Environment + Annex.FileMatcher + Annex.Fixup + Annex.GitOverlay + Annex.HashObject + Annex.Hook + Annex.Ingest + Annex.Init + Annex.InodeSentinal + Annex.Journal + Annex.Link + Annex.Locations + Annex.LockFile + Annex.LockPool + Annex.LockPool.PosixOrPid + Annex.MakeRepo + Annex.MetaData + Annex.MetaData.StandardFields + Annex.Multicast + Annex.Notification + Annex.NumCopies + Annex.Path + Annex.Perms + Annex.Queue + Annex.Quvi + Annex.ReplaceFile + Annex.SpecialRemote + Annex.Ssh + Annex.TaggedPush + Annex.Transfer + Annex.UpdateInstead + Annex.UUID + Annex.Url + Annex.VectorClock + Annex.VariantFile + Annex.Version + Annex.View + Annex.View.ViewedFile + Annex.Wanted + Annex.WorkTree + Assistant + Assistant.Alert + Assistant.Alert.Utility + Assistant.BranchChange + Assistant.Changes + Assistant.Commits + Assistant.Common + Assistant.CredPairCache + Assistant.DaemonStatus + Assistant.DeleteRemote + Assistant.Drop + Assistant.Fsck + Assistant.Gpg + Assistant.Install + Assistant.Install.AutoStart + Assistant.Install.Menu + Assistant.MakeRemote + Assistant.Monad + Assistant.NamedThread + Assistant.Pairing + Assistant.Pairing.MakeRemote + Assistant.Pairing.Network + Assistant.Pushes + Assistant.RemoteControl + Assistant.Repair + Assistant.RepoProblem + Assistant.Restart + Assistant.ScanRemotes + Assistant.Ssh + Assistant.Sync + Assistant.Threads.Committer + Assistant.Threads.ConfigMonitor + Assistant.Threads.Cronner + Assistant.Threads.DaemonStatus + Assistant.Threads.Glacier + Assistant.Threads.Merger + Assistant.Threads.MountWatcher + Assistant.Threads.NetWatcher + Assistant.Threads.PairListener + Assistant.Threads.ProblemFixer + Assistant.Threads.Pusher + Assistant.Threads.RemoteControl + Assistant.Threads.SanityChecker + Assistant.Threads.TransferPoller + Assistant.Threads.TransferScanner + Assistant.Threads.TransferWatcher + Assistant.Threads.Transferrer + Assistant.Threads.UpgradeWatcher + Assistant.Threads.Upgrader + Assistant.Threads.Watcher + Assistant.Threads.WebApp + Assistant.TransferQueue + Assistant.TransferSlots + Assistant.TransferrerPool + Assistant.Types.Alert + Assistant.Types.BranchChange + Assistant.Types.Changes + Assistant.Types.Commits + Assistant.Types.CredPairCache + Assistant.Types.DaemonStatus + Assistant.Types.NamedThread + Assistant.Types.Pushes + Assistant.Types.RemoteControl + Assistant.Types.RepoProblem + Assistant.Types.ScanRemotes + Assistant.Types.ThreadName + Assistant.Types.ThreadedMonad + Assistant.Types.TransferQueue + Assistant.Types.TransferSlots + Assistant.Types.TransferrerPool + Assistant.Types.UrlRenderer + Assistant.Unused + Assistant.Upgrade + Assistant.WebApp + Assistant.WebApp.Common + Assistant.WebApp.Configurators + Assistant.WebApp.Configurators.AWS + Assistant.WebApp.Configurators.Delete + Assistant.WebApp.Configurators.Edit + Assistant.WebApp.Configurators.Fsck + Assistant.WebApp.Configurators.IA + Assistant.WebApp.Configurators.Local + Assistant.WebApp.Configurators.Pairing + Assistant.WebApp.Configurators.Preferences + Assistant.WebApp.Configurators.Ssh + Assistant.WebApp.Configurators.Unused + Assistant.WebApp.Configurators.Upgrade + Assistant.WebApp.Configurators.WebDAV + Assistant.WebApp.Control + Assistant.WebApp.DashBoard + Assistant.WebApp.Documentation + Assistant.WebApp.Form + Assistant.WebApp.Gpg + Assistant.WebApp.MakeRemote + Assistant.WebApp.Notifications + Assistant.WebApp.OtherRepos + Assistant.WebApp.Page + Assistant.WebApp.Pairing + Assistant.WebApp.Repair + Assistant.WebApp.RepoId + Assistant.WebApp.RepoList + Assistant.WebApp.SideBar + Assistant.WebApp.Types + Backend + Backend.Hash + Backend.URL + Backend.Utilities + Backend.WORM + Build.BundledPrograms + Build.Configure + Build.DesktopFile + Build.Mans + Build.TestConfig + Build.Version + BuildInfo + CmdLine + CmdLine.Action + CmdLine.Batch + CmdLine.GitAnnex + CmdLine.GitAnnex.Options + CmdLine.GitAnnexShell + CmdLine.GitAnnexShell.Checks + CmdLine.GitAnnexShell.Fields + CmdLine.GlobalSetter + CmdLine.Option + CmdLine.GitRemoteTorAnnex + CmdLine.Seek + CmdLine.Usage + Command + Command.Add + Command.AddUnused + Command.AddUrl + Command.Adjust + Command.Assistant + Command.CalcKey + Command.CheckPresentKey + Command.Commit + Command.Config + Command.ConfigList + Command.ContentLocation + Command.Copy + Command.Dead + Command.Describe + Command.DiffDriver + Command.Direct + Command.Drop + Command.DropKey + Command.DropUnused + Command.EnableRemote + Command.EnableTor + Command.ExamineKey + Command.Expire + Command.Find + Command.FindRef + Command.Fix + Command.Forget + Command.FromKey + Command.Fsck + Command.FuzzTest + Command.GCryptSetup + Command.Get + Command.Group + Command.GroupWanted + Command.Help + Command.Import + Command.ImportFeed + Command.InAnnex + Command.Indirect + Command.Info + Command.Init + Command.InitRemote + Command.List + Command.Lock + Command.LockContent + Command.Log + Command.LookupKey + Command.Map + Command.MatchExpression + Command.Merge + Command.MetaData + Command.Migrate + Command.Mirror + Command.Move + Command.Multicast + Command.NotifyChanges + Command.NumCopies + Command.P2P + Command.PostReceive + Command.PreCommit + Command.Proxy + Command.ReKey + Command.ReadPresentKey + Command.RecvKey + Command.RegisterUrl + Command.Reinit + Command.Reinject + Command.RemoteDaemon + Command.Repair + Command.Required + Command.ResolveMerge + Command.RmUrl + Command.Schedule + Command.Semitrust + Command.SendKey + Command.SetKey + Command.SetPresentKey + Command.Smudge + Command.Status + Command.Sync + Command.Test + Command.TestRemote + Command.TransferInfo + Command.TransferKey + Command.TransferKeys + Command.Trust + Command.Unannex + Command.Undo + Command.Ungroup + Command.Uninit + Command.Unlock + Command.Untrust + Command.Unused + Command.Upgrade + Command.VAdd + Command.VCycle + Command.VFilter + Command.VPop + Command.Version + Command.Vicfg + Command.View + Command.Wanted + Command.Watch + Command.WebApp + Command.Whereis + Common + Config + Config.Cost + Config.Files + Config.DynamicConfig + Config.GitConfig + Creds + Crypto + Database.Fsck + Database.Handle + Database.Init + Database.Keys + Database.Keys.Handle + Database.Keys.SQL + Database.Queue + Database.Types + Git + Git.AutoCorrect + Git.Branch + Git.BuildVersion + Git.CatFile + Git.CheckAttr + Git.CheckIgnore + Git.Command + Git.Command.Batch + Git.Config + Git.ConfigTypes + Git.Construct + Git.CurrentRepo + Git.DiffTree + Git.DiffTreeItem + Git.Env + Git.FileMode + Git.FilePath + Git.Filename + Git.Fsck + Git.GCrypt + Git.HashObject + Git.Hook + Git.Index + Git.LockFile + Git.LsFiles + Git.LsTree + Git.Merge + Git.Objects + Git.Queue + Git.Ref + Git.RefLog + Git.Remote + Git.Remote.Remove + Git.Repair + Git.Sha + Git.Ssh + Git.Status + Git.Tree + Git.Types + Git.UnionMerge + Git.UpdateIndex + Git.Url + Git.Version + Key + Limit + Limit.Wanted + Logs + Logs.Activity + Logs.Chunk + Logs.Chunk.Pure + Logs.Config + Logs.Difference + Logs.Difference.Pure + Logs.FsckResults + Logs.Group + Logs.Line + Logs.Location + Logs.MapLog + Logs.MetaData + Logs.Multicast + Logs.NumCopies + Logs.PreferredContent + Logs.PreferredContent.Raw + Logs.Presence + Logs.Presence.Pure + Logs.Remote + Logs.RemoteState + Logs.Schedule + Logs.SingleValue + Logs.TimeStamp + Logs.Transfer + Logs.Transitions + Logs.Trust + Logs.Trust.Basic + Logs.Trust.Pure + Logs.UUID + Logs.UUIDBased + Logs.Unused + Logs.View + Logs.Web + Messages + Messages.Concurrent + Messages.Internal + Messages.JSON + Messages.Progress + P2P.Address + P2P.Annex + P2P.Auth + P2P.IO + P2P.Protocol + Remote + Remote.BitTorrent + Remote.Bup + Remote.Ddar + Remote.Directory + Remote.Directory.LegacyChunked + Remote.External + Remote.External.Types + Remote.GCrypt + Remote.Git + Remote.Glacier + Remote.Helper.AWS + Remote.Helper.Chunked + Remote.Helper.Chunked.Legacy + Remote.Helper.Encryptable + Remote.Helper.Git + Remote.Helper.Hooks + Remote.Helper.Http + Remote.Helper.Messages + Remote.Helper.ReadOnly + Remote.Helper.Special + Remote.Helper.Ssh + Remote.Hook + Remote.List + Remote.P2P + Remote.Rsync + Remote.Rsync.RsyncUrl + Remote.S3 + Remote.Tahoe + Remote.Web + Remote.WebDAV + Remote.WebDAV.DavLocation + RemoteDaemon.Common + RemoteDaemon.Core + RemoteDaemon.Transport + RemoteDaemon.Transport.GCrypt + RemoteDaemon.Transport.Tor + RemoteDaemon.Transport.Ssh + RemoteDaemon.Transport.Ssh.Types + RemoteDaemon.Types + Test + Types + Types.ActionItem + Types.Availability + Types.Backend + Types.BranchState + Types.CleanupActions + Types.Command + Types.Concurrency + Types.Creds + Types.Crypto + Types.DeferredParse + Types.DesktopNotify + Types.Difference + Types.Distribution + Types.FileMatcher + Types.GitConfig + Types.Group + Types.Key + Types.KeySource + Types.LockCache + Types.Messages + Types.MetaData + Types.NumCopies + Types.RefSpec + Types.Remote + Types.ScheduledActivity + Types.StandardGroups + Types.StoreRetrieve + Types.Test + Types.Transfer + Types.TrustLevel + Types.UUID + Types.UrlContents + Types.View + Upgrade + Upgrade.V0 + Upgrade.V1 + Upgrade.V2 + Upgrade.V3 + Upgrade.V4 + Upgrade.V5 + Utility.Applicative + Utility.AuthToken + Utility.Base64 + Utility.Batch + Utility.Bloom + Utility.CoProcess + Utility.CopyFile + Utility.Daemon + Utility.Data + Utility.DataUnits + Utility.DirWatcher + Utility.DirWatcher.Types + Utility.Directory + Utility.DiskFree + Utility.Dot + Utility.DottedVersion + Utility.Env + Utility.Exception + Utility.ExternalSHA + Utility.FileMode + Utility.FileSize + Utility.FileSystemEncoding + Utility.Format + Utility.FreeDesktop + Utility.Glob + Utility.Gpg + Utility.Hash + Utility.HumanNumber + Utility.HumanTime + Utility.InodeCache + Utility.LinuxMkLibs + Utility.LockFile + Utility.LockFile.LockStatus + Utility.LockFile.PidLock + Utility.LockPool + Utility.LockPool.LockHandle + Utility.LockPool.PidLock + Utility.LockPool.STM + Utility.LogFile + Utility.Lsof + Utility.MagicWormhole + Utility.Matcher + Utility.Metered + Utility.Misc + Utility.Monad + Utility.Mounts + Utility.Network + Utility.NotificationBroadcaster + Utility.OSX + Utility.OptParse + Utility.PID + Utility.Parallel + Utility.PartialPrelude + Utility.Path + Utility.Percentage + Utility.PosixFiles + Utility.Process + Utility.Process.Shim + Utility.QuickCheck + Utility.Quvi + Utility.Rsync + Utility.SRV + Utility.SafeCommand + Utility.Scheduled + Utility.Scheduled.QuickCheck + Utility.Shell + Utility.SimpleProtocol + Utility.Split + Utility.SshConfig + Utility.SshHost + Utility.Su + Utility.SystemDirectory + Utility.TList + Utility.Tense + Utility.ThreadLock + Utility.ThreadScheduler + Utility.Tmp + Utility.Tor + Utility.Touch + Utility.Tuple + Utility.Url + Utility.UserInfo + Utility.Verifiable + Utility.WebApp + Utility.Yesod + + if (os(windows)) + Other-Modules: + Utility.LockFile.Windows + Utility.LockPool.Windows + Utility.WinProcess + else + Other-Modules: + Utility.LockFile.Posix + Utility.LockPool.Posix diff --git a/test/fixtures/Cabal/hackage/git-annex-6.20180626.cabal b/test/fixtures/Cabal/hackage/git-annex-6.20180626.cabal new file mode 100644 index 00000000..a497eeae --- /dev/null +++ b/test/fixtures/Cabal/hackage/git-annex-6.20180626.cabal @@ -0,0 +1,1104 @@ +Name: git-annex +Version: 6.20180626 +Cabal-Version: >= 1.8 +License: GPL-3 +Maintainer: Joey Hess +Author: Joey Hess +Stability: Stable +Copyright: 2010-2017 Joey Hess +License-File: COPYRIGHT +Homepage: http://git-annex.branchable.com/ +Build-type: Custom +Category: Utility +Synopsis: manage files with git, without checking their contents into git +Description: + git-annex allows managing files with git, without checking the file + contents into git. While that may seem paradoxical, it is useful when + dealing with files larger than git can currently easily handle, whether due + to limitations in memory, time, or disk space. + . + It can store large files in many places, from local hard drives, to a + large number of cloud storage services, including S3, WebDAV, + and rsync, with a dozen cloud storage providers usable via plugins. + Files can be stored encrypted with gpg, so that the cloud storage + provider cannot see your data. git-annex keeps track of where each file + is stored, so it knows how many copies are available, and has many + facilities to ensure your data is preserved. + . + git-annex can also be used to keep a folder in sync between computers, + noticing when files are changed, and automatically committing them + to git and transferring them to other computers. The git-annex webapp + makes it easy to set up and use git-annex this way. +-- The tarball uploaded to hackage does not include every non-haskell +-- file in the git repo. The website is left out, so is build machinary for +-- standalone apps, and packages. Include only files that are needed +-- make cabal install git-annex work. +Extra-Source-Files: + stack.yaml + README + CHANGELOG + NEWS + doc/license/GPL + doc/license/AGPL + doc/git-annex.mdwn + doc/git-annex-add.mdwn + doc/git-annex-addunused.mdwn + doc/git-annex-addurl.mdwn + doc/git-annex-adjust.mdwn + doc/git-annex-assistant.mdwn + doc/git-annex-calckey.mdwn + doc/git-annex-checkpresentkey.mdwn + doc/git-annex-contentlocation.mdwn + doc/git-annex-copy.mdwn + doc/git-annex-dead.mdwn + doc/git-annex-describe.mdwn + doc/git-annex-diffdriver.mdwn + doc/git-annex-direct.mdwn + doc/git-annex-drop.mdwn + doc/git-annex-dropkey.mdwn + doc/git-annex-dropunused.mdwn + doc/git-annex-edit.mdwn + doc/git-annex-enableremote.mdwn + doc/git-annex-enable-tor.mdwn + doc/git-annex-examinekey.mdwn + doc/git-annex-expire.mdwn + doc/git-annex-export.mdwn + doc/git-annex-find.mdwn + doc/git-annex-findref.mdwn + doc/git-annex-fix.mdwn + doc/git-annex-forget.mdwn + doc/git-annex-fromkey.mdwn + doc/git-annex-fsck.mdwn + doc/git-annex-fuzztest.mdwn + doc/git-annex-get.mdwn + doc/git-annex-group.mdwn + doc/git-annex-groupwanted.mdwn + doc/git-annex-import.mdwn + doc/git-annex-importfeed.mdwn + doc/git-annex-indirect.mdwn + doc/git-annex-info.mdwn + doc/git-annex-init.mdwn + doc/git-annex-initremote.mdwn + doc/git-annex-inprogress.mdwn + doc/git-annex-list.mdwn + doc/git-annex-lock.mdwn + doc/git-annex-log.mdwn + doc/git-annex-lookupkey.mdwn + doc/git-annex-map.mdwn + doc/git-annex-matchexpression.mdwn + doc/git-annex-matching-options.mdwn + doc/git-annex-merge.mdwn + doc/git-annex-metadata.mdwn + doc/git-annex-migrate.mdwn + doc/git-annex-mirror.mdwn + doc/git-annex-move.mdwn + doc/git-annex-multicast.mdwn + doc/git-annex-numcopies.mdwn + doc/git-annex-p2p.mdwn + doc/git-annex-pre-commit.mdwn + doc/git-annex-preferred-content.mdwn + doc/git-annex-proxy.mdwn + doc/git-annex-readpresentkey.mdwn + doc/git-annex-registerurl.mdwn + doc/git-annex-reinit.mdwn + doc/git-annex-reinject.mdwn + doc/git-annex-rekey.mdwn + doc/git-annex-remotedaemon.mdwn + doc/git-annex-repair.mdwn + doc/git-annex-required.mdwn + doc/git-annex-resolvemerge.mdwn + doc/git-annex-rmurl.mdwn + doc/git-annex-schedule.mdwn + doc/git-annex-semitrust.mdwn + doc/git-annex-setkey.mdwn + doc/git-annex-setpresentkey.mdwn + doc/git-annex-shell.mdwn + doc/git-annex-smudge.mdwn + doc/git-annex-status.mdwn + doc/git-annex-sync.mdwn + doc/git-annex-test.mdwn + doc/git-annex-testremote.mdwn + doc/git-annex-transferkey.mdwn + doc/git-annex-transferkeys.mdwn + doc/git-annex-trust.mdwn + doc/git-annex-unannex.mdwn + doc/git-annex-undo.mdwn + doc/git-annex-ungroup.mdwn + doc/git-annex-uninit.mdwn + doc/git-annex-unlock.mdwn + doc/git-annex-untrust.mdwn + doc/git-annex-unused.mdwn + doc/git-annex-upgrade.mdwn + doc/git-annex-vadd.mdwn + doc/git-annex-vcycle.mdwn + doc/git-annex-version.mdwn + doc/git-annex-vfilter.mdwn + doc/git-annex-vicfg.mdwn + doc/git-annex-view.mdwn + doc/git-annex-vpop.mdwn + doc/git-annex-wanted.mdwn + doc/git-annex-watch.mdwn + doc/git-annex-webapp.mdwn + doc/git-annex-whereis.mdwn + doc/git-remote-tor-annex.mdwn + doc/logo.svg + doc/logo_16x16.png + Build/mdwn2man + Assistant/WebApp/routes + static/activityicon.gif + static/css/bootstrap.css + static/css/bootstrap-theme.css + static/js/jquery.ui.core.js + static/js/longpolling.js + static/js/jquery.full.js + static/js/jquery.ui.sortable.js + static/js/jquery.ui.mouse.js + static/js/jquery.ui.widget.js + static/js/bootstrap.js + static/syncicon.gif + static/favicon.ico + static/fonts/glyphicons-halflings-regular.woff + static/fonts/glyphicons-halflings-regular.eot + static/fonts/glyphicons-halflings-regular.svg + static/fonts/glyphicons-halflings-regular.ttf + templates/sidebar/main.hamlet + templates/sidebar/alert.hamlet + templates/bootstrap.hamlet + templates/error.cassius + templates/README + templates/error.hamlet + templates/documentation/license.hamlet + templates/documentation/repogroup.hamlet + templates/documentation/about.hamlet + templates/dashboard/main.hamlet + templates/dashboard/transfers.cassius + templates/dashboard/transfers.hamlet + templates/dashboard/metarefresh.hamlet + templates/page.cassius + templates/page.hamlet + templates/control/repairrepository.hamlet + templates/control/repairrepository/done.hamlet + templates/control/notrunning.julius + templates/control/notrunning.hamlet + templates/control/repositoryswitcher.hamlet + templates/control/shutdown.hamlet + templates/control/log.hamlet + templates/page.julius + templates/repolist.julius + templates/configurators/adddrive/combine.hamlet + templates/configurators/adddrive/setupmodal.hamlet + templates/configurators/adddrive/encrypt.hamlet + templates/configurators/newrepository.hamlet + templates/configurators/needglaciercli.hamlet + templates/configurators/adds3.hamlet + templates/configurators/genkeymodal.hamlet + templates/configurators/main.hamlet + templates/configurators/needconnection.hamlet + templates/configurators/newrepository/form.hamlet + templates/configurators/newrepository/first.hamlet + templates/configurators/newrepository/combine.hamlet + templates/configurators/enablewebdav.hamlet + templates/configurators/pairing/local/inprogress.hamlet + templates/configurators/pairing/local/prompt.hamlet + templates/configurators/pairing/wormhole/prompt.hamlet + templates/configurators/pairing/wormhole/start.hamlet + templates/configurators/pairing/disabled.hamlet + templates/configurators/addglacier.hamlet + templates/configurators/fsck.cassius + templates/configurators/edit/nonannexremote.hamlet + templates/configurators/edit/webrepository.hamlet + templates/configurators/edit/repository.hamlet + templates/configurators/unused.hamlet + templates/configurators/addbox.com.hamlet + templates/configurators/ssh/testmodal.hamlet + templates/configurators/ssh/expiredpassword.hamlet + templates/configurators/ssh/error.hamlet + templates/configurators/ssh/combine.hamlet + templates/configurators/ssh/enable.hamlet + templates/configurators/ssh/add.hamlet + templates/configurators/ssh/setupmodal.hamlet + templates/configurators/ssh/confirm.hamlet + templates/configurators/upgrade/android.hamlet + templates/configurators/enableia.hamlet + templates/configurators/fsck.hamlet + templates/configurators/addrepository/archive.hamlet + templates/configurators/addrepository/cloud.hamlet + templates/configurators/addrepository/connection.hamlet + templates/configurators/addrepository/ssh.hamlet + templates/configurators/addrepository/misc.hamlet + templates/configurators/addrepository/wormholepairing.hamlet + templates/configurators/rsync.net/add.hamlet + templates/configurators/rsync.net/encrypt.hamlet + templates/configurators/gitlab.com/add.hamlet + templates/configurators/needgcrypt.hamlet + templates/configurators/needtor.hamlet + templates/configurators/needmagicwormhole.hamlet + templates/configurators/enabledirectory.hamlet + templates/configurators/fsck/status.hamlet + templates/configurators/fsck/form.hamlet + templates/configurators/fsck/preferencesform.hamlet + templates/configurators/fsck/formcontent.hamlet + templates/configurators/delete/finished.hamlet + templates/configurators/delete/start.hamlet + templates/configurators/delete/currentrepository.hamlet + templates/configurators/unused/form.hamlet + templates/configurators/adddrive.hamlet + templates/configurators/preferences.hamlet + templates/configurators/addia.hamlet + templates/configurators/enableaws.hamlet + templates/configurators/addrepository.hamlet + templates/actionbutton.hamlet + templates/repolist.hamlet + templates/controlmenu.hamlet + templates/notifications/longpolling.julius + +Flag S3 + Description: Enable S3 support + +Flag WebDAV + Description: Enable WebDAV support + +Flag Assistant + Description: Enable git-annex assistant and watch command + +Flag Webapp + Description: Enable git-annex webapp + +Flag Pairing + Description: Enable pairing + +Flag Production + Description: Enable production build (slower build; faster binary) + +Flag Android + Description: Cross building for Android + Default: False + +Flag AndroidSplice + Description: Building to get TH splices for Android + Default: False + +Flag TorrentParser + Description: Use haskell torrent library to parse torrent files + +Flag MagicMime + Description: Use libmagic to determine file MIME types + +Flag ConcurrentOutput + Description: Use concurrent-output library + +Flag Benchmark + Description: Enable benchmarking + Default: False + +Flag network-uri + Description: Get Network.URI from the network-uri package + Default: True + +Flag Dbus + Description: Enable dbus support + +source-repository head + type: git + location: git://git-annex.branchable.com/ + +custom-setup + Setup-Depends: base (>= 4.6), hslogger, split, unix-compat, process, + filepath, exceptions, bytestring, directory, IfElse, data-default, + utf8-string, Cabal + +Executable git-annex + Main-Is: git-annex.hs + Build-Depends: + base (>= 4.6 && < 5.0), + optparse-applicative (>= 0.11.0), + containers (>= 0.5.0.0), + exceptions (>= 0.6), + stm (>= 2.3), + mtl (>= 2), + uuid (>= 1.2.6), + process, + data-default, + case-insensitive, + random, + dlist, + unix-compat, + SafeSemaphore, + async, + directory (>= 1.2), + filepath, + IfElse, + hslogger, + monad-logger, + free, + utf8-string, + bytestring, + text, + sandi, + monad-control, + transformers, + bloomfilter, + edit-distance, + resourcet, + connection (>= 0.2.6), + http-client (>= 0.4.31), + http-client-tls, + http-types (>= 0.7), + http-conduit (>= 2.0), + conduit, + time, + old-locale, + esqueleto, + persistent-sqlite, + persistent, + persistent-template, + aeson, + vector, + tagsoup, + unordered-containers, + feed (>= 0.3.9), + regex-tdfa, + socks, + byteable, + stm-chans, + securemem, + crypto-api, + cryptonite, + memory, + split, + QuickCheck (>= 2.1), + tasty (>= 0.7), + tasty-hunit, + tasty-quickcheck, + tasty-rerun + CC-Options: -Wall + GHC-Options: -Wall -fno-warn-tabs + Extensions: PackageImports, LambdaCase + -- Some things don't work with the non-threaded RTS. + GHC-Options: -threaded + Other-Extensions: TemplateHaskell + + -- Fully optimize for production. + if flag(Production) + -- Lower memory systems can run out of memory with -O2, so + -- optimise slightly less. + -- This needs -O1 before the -optlo, due to this bug: + -- https://ghc.haskell.org/trac/ghc/ticket/14821 + -- But unfortunately, hackage currently refuses to accept -O1 + if arch(arm) + GHC-Options: -optlo-O2 + else + GHC-Options: -O2 + + -- Avoid linking with unused dynamic libaries. + -- (Only tested on Linux). + if os(Linux) + GHC-Options: -optl-Wl,--as-needed + + if flag(network-uri) + Build-Depends: network-uri (>= 2.6), network (>= 2.6) + else + Build-Depends: network (< 2.6), network (>= 2.4) + + if (os(windows)) + Build-Depends: + Win32 (>= 2.6.1.0), + unix-compat (>= 0.5), + setenv, + process (>= 1.6.2.0) + else + Build-Depends: unix + if impl(ghc <= 7.6.3) + Other-Modules: Utility.Touch.Old + + if flag(S3) + Build-Depends: aws (>= 0.9.2) + CPP-Options: -DWITH_S3 + Other-Modules: Remote.S3 + + if flag(WebDAV) + Build-Depends: DAV (>= 1.0) + CPP-Options: -DWITH_WEBDAV + Other-Modules: + Remote.WebDAV + Remote.WebDAV.DavLocation + + if flag(Assistant) && ! os(solaris) && ! os(gnu) + Build-Depends: dns (>= 1.0.0), mountpoints + CPP-Options: -DWITH_ASSISTANT + + if flag(Assistant) + if os(linux) || flag(Android) + Build-Depends: hinotify + CPP-Options: -DWITH_INOTIFY + Other-Modules: Utility.DirWatcher.INotify + else + if os(darwin) + Build-Depends: hfsevents + CPP-Options: -DWITH_FSEVENTS + Other-Modules: Utility.DirWatcher.FSEvents + else + if os(windows) + Build-Depends: Win32-notify + CPP-Options: -DWITH_WIN32NOTIFY + Other-Modules: Utility.DirWatcher.Win32Notify + else + if (! os(solaris) && ! os(gnu) && ! os(linux)) + CPP-Options: -DWITH_KQUEUE + C-Sources: Utility/libkqueue.c + Includes: Utility/libkqueue.h + Other-Modules: Utility.DirWatcher.Kqueue + + if flag(Dbus) + if (os(linux)) + Build-Depends: dbus (>= 0.10.7), fdo-notify (>= 0.3) + CPP-Options: -DWITH_DBUS -DWITH_DESKTOP_NOTIFY -DWITH_DBUS_NOTIFICATIONS + Other-Modules: Utility.DBus + + if flag(Android) + Build-Depends: data-endian + CPP-Options: -D__ANDROID__ -DANDROID_SPLICES -D__NO_TH__ + else + Build-Depends: disk-free-space + + if flag(AndroidSplice) + CPP-Options: -DANDROID_SPLICES + + if flag(Webapp) + Build-Depends: + yesod (>= 1.2.6), + yesod-static (>= 1.2.4), + yesod-form (>= 1.3.15), + yesod-core (>= 1.2.19), + path-pieces (>= 0.1.4), + warp (>= 3.0.0.5), + warp-tls (>= 1.4), + wai, + wai-extra, + blaze-builder, + clientsession, + template-haskell, + shakespeare (>= 2.0.0) + CPP-Options: -DWITH_WEBAPP + Other-Modules: + Command.WebApp + Assistant.Threads.WebApp + Assistant.Threads.PairListener + Assistant.WebApp + Assistant.WebApp.Common + Assistant.WebApp.Configurators + Assistant.WebApp.Configurators.AWS + Assistant.WebApp.Configurators.Delete + Assistant.WebApp.Configurators.Edit + Assistant.WebApp.Configurators.Fsck + Assistant.WebApp.Configurators.IA + Assistant.WebApp.Configurators.Local + Assistant.WebApp.Configurators.Pairing + Assistant.WebApp.Configurators.Preferences + Assistant.WebApp.Configurators.Ssh + Assistant.WebApp.Configurators.Unused + Assistant.WebApp.Configurators.Upgrade + Assistant.WebApp.Configurators.WebDAV + Assistant.WebApp.Control + Assistant.WebApp.DashBoard + Assistant.WebApp.Documentation + Assistant.WebApp.Form + Assistant.WebApp.Gpg + Assistant.WebApp.MakeRemote + Assistant.WebApp.Notifications + Assistant.WebApp.OtherRepos + Assistant.WebApp.Page + Assistant.WebApp.Pairing + Assistant.WebApp.Repair + Assistant.WebApp.RepoId + Assistant.WebApp.RepoList + Assistant.WebApp.SideBar + Assistant.WebApp.Types + Annex.MakeRepo + Utility.Yesod + Utility.WebApp + + if flag(Pairing) + Build-Depends: network-multicast, network-info + CPP-Options: -DWITH_PAIRING + + if flag(TorrentParser) + Build-Depends: torrent (>= 10000.0.0) + CPP-Options: -DWITH_TORRENTPARSER + + if flag(MagicMime) + if (! os(windows)) + Build-Depends: magic + CPP-Options: -DWITH_MAGICMIME + + if flag(ConcurrentOutput) + Build-Depends: concurrent-output (>= 1.6) + CPP-Options: -DWITH_CONCURRENTOUTPUT + + if flag(Benchmark) + Build-Depends: criterion, deepseq + CPP-Options: -DWITH_BENCHMARK + Other-Modules: Command.Benchmark + + Other-Modules: + Annex + Annex.Action + Annex.AdjustedBranch + Annex.AutoMerge + Annex.BloomFilter + Annex.Branch + Annex.Branch.Transitions + Annex.BranchState + Annex.CatFile + Annex.ChangedRefs + Annex.CheckAttr + Annex.CheckIgnore + Annex.Common + Annex.Concurrent + Annex.Content + Annex.Content.Direct + Annex.Difference + Annex.DirHashes + Annex.Direct + Annex.Drop + Annex.Environment + Annex.Export + Annex.FileMatcher + Annex.Fixup + Annex.GitOverlay + Annex.HashObject + Annex.Hook + Annex.Ingest + Annex.Init + Annex.InodeSentinal + Annex.Journal + Annex.Link + Annex.Locations + Annex.LockFile + Annex.LockPool + Annex.LockPool.PosixOrPid + Annex.MetaData + Annex.MetaData.StandardFields + Annex.Multicast + Annex.Notification + Annex.NumCopies + Annex.Path + Annex.Perms + Annex.Queue + Annex.ReplaceFile + Annex.SpecialRemote + Annex.Ssh + Annex.TaggedPush + Annex.Transfer + Annex.UpdateInstead + Annex.UUID + Annex.Url + Annex.VectorClock + Annex.VariantFile + Annex.Version + Annex.View + Annex.View.ViewedFile + Annex.Wanted + Annex.WorkTree + Annex.YoutubeDl + Assistant + Assistant.Alert + Assistant.Alert.Utility + Assistant.BranchChange + Assistant.Changes + Assistant.Commits + Assistant.Common + Assistant.CredPairCache + Assistant.DaemonStatus + Assistant.DeleteRemote + Assistant.Drop + Assistant.Fsck + Assistant.Gpg + Assistant.Install + Assistant.Install.AutoStart + Assistant.Install.Menu + Assistant.MakeRemote + Assistant.Monad + Assistant.NamedThread + Assistant.Pairing + Assistant.Pairing.MakeRemote + Assistant.Pairing.Network + Assistant.Pushes + Assistant.RemoteControl + Assistant.Repair + Assistant.RepoProblem + Assistant.Restart + Assistant.ScanRemotes + Assistant.Ssh + Assistant.Sync + Assistant.Threads.Committer + Assistant.Threads.ConfigMonitor + Assistant.Threads.Cronner + Assistant.Threads.DaemonStatus + Assistant.Threads.Exporter + Assistant.Threads.Glacier + Assistant.Threads.Merger + Assistant.Threads.MountWatcher + Assistant.Threads.NetWatcher + Assistant.Threads.ProblemFixer + Assistant.Threads.Pusher + Assistant.Threads.RemoteControl + Assistant.Threads.SanityChecker + Assistant.Threads.TransferPoller + Assistant.Threads.TransferScanner + Assistant.Threads.TransferWatcher + Assistant.Threads.Transferrer + Assistant.Threads.UpgradeWatcher + Assistant.Threads.Upgrader + Assistant.Threads.Watcher + Assistant.TransferQueue + Assistant.TransferSlots + Assistant.TransferrerPool + Assistant.Types.Alert + Assistant.Types.BranchChange + Assistant.Types.Changes + Assistant.Types.Commits + Assistant.Types.CredPairCache + Assistant.Types.DaemonStatus + Assistant.Types.NamedThread + Assistant.Types.Pushes + Assistant.Types.RemoteControl + Assistant.Types.RepoProblem + Assistant.Types.ScanRemotes + Assistant.Types.ThreadName + Assistant.Types.ThreadedMonad + Assistant.Types.TransferQueue + Assistant.Types.TransferSlots + Assistant.Types.TransferrerPool + Assistant.Types.UrlRenderer + Assistant.Unused + Assistant.Upgrade + Backend + Backend.Hash + Backend.URL + Backend.Utilities + Backend.WORM + Build.BundledPrograms + Build.Configure + Build.DesktopFile + Build.Mans + Build.TestConfig + Build.Version + BuildInfo + BuildFlags + CmdLine + CmdLine.Action + CmdLine.Batch + CmdLine.GitAnnex + CmdLine.GitAnnex.Options + CmdLine.GitAnnexShell + CmdLine.GitAnnexShell.Checks + CmdLine.GitAnnexShell.Fields + CmdLine.GlobalSetter + CmdLine.Option + CmdLine.GitRemoteTorAnnex + CmdLine.Seek + CmdLine.Usage + Command + Command.Add + Command.AddUnused + Command.AddUrl + Command.Adjust + Command.Assistant + Command.CalcKey + Command.CheckPresentKey + Command.Commit + Command.Config + Command.ConfigList + Command.ContentLocation + Command.Copy + Command.Dead + Command.Describe + Command.DiffDriver + Command.Direct + Command.Drop + Command.DropKey + Command.DropUnused + Command.EnableRemote + Command.EnableTor + Command.ExamineKey + Command.Expire + Command.Export + Command.Find + Command.FindRef + Command.Fix + Command.Forget + Command.FromKey + Command.Fsck + Command.FuzzTest + Command.GCryptSetup + Command.Get + Command.Group + Command.GroupWanted + Command.Help + Command.Import + Command.ImportFeed + Command.InAnnex + Command.Indirect + Command.Info + Command.Init + Command.InitRemote + Command.Inprogress + Command.List + Command.Lock + Command.LockContent + Command.Log + Command.LookupKey + Command.Map + Command.MatchExpression + Command.Merge + Command.MetaData + Command.Migrate + Command.Mirror + Command.Move + Command.Multicast + Command.NotifyChanges + Command.NumCopies + Command.P2P + Command.P2PStdIO + Command.PostReceive + Command.PreCommit + Command.Proxy + Command.ReKey + Command.ReadPresentKey + Command.RecvKey + Command.RegisterUrl + Command.Reinit + Command.Reinject + Command.RemoteDaemon + Command.Repair + Command.Required + Command.ResolveMerge + Command.RmUrl + Command.Schedule + Command.Semitrust + Command.SendKey + Command.SetKey + Command.SetPresentKey + Command.Smudge + Command.Status + Command.Sync + Command.Test + Command.TestRemote + Command.TransferInfo + Command.TransferKey + Command.TransferKeys + Command.Trust + Command.Unannex + Command.Undo + Command.Ungroup + Command.Uninit + Command.Unlock + Command.Untrust + Command.Unused + Command.Upgrade + Command.VAdd + Command.VCycle + Command.VFilter + Command.VPop + Command.Version + Command.Vicfg + Command.View + Command.Wanted + Command.Watch + Command.Whereis + Common + Config + Config.Cost + Config.Files + Config.DynamicConfig + Config.GitConfig + Creds + Crypto + Database.Export + Database.Fsck + Database.Handle + Database.Init + Database.Keys + Database.Keys.Handle + Database.Keys.SQL + Database.Queue + Database.Types + Git + Git.AutoCorrect + Git.Branch + Git.BuildVersion + Git.CatFile + Git.CheckAttr + Git.CheckIgnore + Git.Command + Git.Command.Batch + Git.Config + Git.ConfigTypes + Git.Construct + Git.CurrentRepo + Git.DiffTree + Git.DiffTreeItem + Git.Env + Git.FileMode + Git.FilePath + Git.Filename + Git.Fsck + Git.GCrypt + Git.HashObject + Git.Hook + Git.Index + Git.LockFile + Git.LsFiles + Git.LsTree + Git.Merge + Git.Objects + Git.Queue + Git.Ref + Git.RefLog + Git.Remote + Git.Remote.Remove + Git.Repair + Git.Sha + Git.Ssh + Git.Status + Git.Tree + Git.Types + Git.UnionMerge + Git.UpdateIndex + Git.Url + Git.Version + Key + Limit + Limit.Wanted + Logs + Logs.Activity + Logs.Chunk + Logs.Chunk.Pure + Logs.Config + Logs.Difference + Logs.Difference.Pure + Logs.Export + Logs.File + Logs.FsckResults + Logs.Group + Logs.Line + Logs.Location + Logs.MapLog + Logs.MetaData + Logs.Multicast + Logs.NumCopies + Logs.PreferredContent + Logs.PreferredContent.Raw + Logs.Presence + Logs.Presence.Pure + Logs.Remote + Logs.RemoteState + Logs.Schedule + Logs.SingleValue + Logs.TimeStamp + Logs.Transfer + Logs.Transitions + Logs.Trust + Logs.Trust.Basic + Logs.Trust.Pure + Logs.UUID + Logs.UUIDBased + Logs.Unused + Logs.View + Logs.Web + Messages + Messages.Concurrent + Messages.Internal + Messages.JSON + Messages.Progress + P2P.Address + P2P.Annex + P2P.Auth + P2P.IO + P2P.Protocol + Remote + Remote.Adb + Remote.BitTorrent + Remote.Bup + Remote.Ddar + Remote.Directory + Remote.Directory.LegacyChunked + Remote.External + Remote.External.Types + Remote.GCrypt + Remote.Git + Remote.Glacier + Remote.Helper.AWS + Remote.Helper.Chunked + Remote.Helper.Chunked.Legacy + Remote.Helper.Encryptable + Remote.Helper.Export + Remote.Helper.Git + Remote.Helper.Hooks + Remote.Helper.Http + Remote.Helper.Messages + Remote.Helper.P2P + Remote.Helper.ReadOnly + Remote.Helper.Special + Remote.Helper.Ssh + Remote.Hook + Remote.List + Remote.P2P + Remote.Rsync + Remote.Rsync.RsyncUrl + Remote.Tahoe + Remote.Web + RemoteDaemon.Common + RemoteDaemon.Core + RemoteDaemon.Transport + RemoteDaemon.Transport.GCrypt + RemoteDaemon.Transport.Tor + RemoteDaemon.Transport.Ssh + RemoteDaemon.Transport.Ssh.Types + RemoteDaemon.Types + Test + Test.Framework + Types + Types.ActionItem + Types.Availability + Types.Backend + Types.BranchState + Types.CleanupActions + Types.Command + Types.Concurrency + Types.Creds + Types.Crypto + Types.DeferredParse + Types.DesktopNotify + Types.Difference + Types.Distribution + Types.Export + Types.FileMatcher + Types.GitConfig + Types.Group + Types.Key + Types.KeySource + Types.LockCache + Types.Messages + Types.MetaData + Types.NumCopies + Types.RefSpec + Types.Remote + Types.ScheduledActivity + Types.StandardGroups + Types.StoreRetrieve + Types.Test + Types.Transfer + Types.TrustLevel + Types.UUID + Types.UrlContents + Types.View + Upgrade + Upgrade.V0 + Upgrade.V1 + Upgrade.V2 + Upgrade.V3 + Upgrade.V4 + Upgrade.V5 + Utility.Aeson + Utility.Android + Utility.Applicative + Utility.AuthToken + Utility.Base64 + Utility.Batch + Utility.Bloom + Utility.CoProcess + Utility.CopyFile + Utility.Daemon + Utility.Data + Utility.DataUnits + Utility.DirWatcher + Utility.DirWatcher.Types + Utility.Directory + Utility.Directory.Stream + Utility.DiskFree + Utility.Dot + Utility.DottedVersion + Utility.Env + Utility.Env.Basic + Utility.Env.Set + Utility.Exception + Utility.ExternalSHA + Utility.FileMode + Utility.FileSize + Utility.FileSystemEncoding + Utility.Format + Utility.FreeDesktop + Utility.Glob + Utility.Gpg + Utility.Hash + Utility.HtmlDetect + Utility.HttpManagerRestricted + Utility.HumanNumber + Utility.HumanTime + Utility.InodeCache + Utility.IPAddress + Utility.LinuxMkLibs + Utility.LockFile + Utility.LockFile.LockStatus + Utility.LockFile.PidLock + Utility.LockPool + Utility.LockPool.LockHandle + Utility.LockPool.PidLock + Utility.LockPool.STM + Utility.LogFile + Utility.Lsof + Utility.MagicWormhole + Utility.Matcher + Utility.Metered + Utility.Misc + Utility.Monad + Utility.Mounts + Utility.Network + Utility.NotificationBroadcaster + Utility.OSX + Utility.OptParse + Utility.PID + Utility.Parallel + Utility.PartialPrelude + Utility.Path + Utility.Path.Max + Utility.Percentage + Utility.Process + Utility.Process.Shim + Utility.Process.Transcript + Utility.QuickCheck + Utility.Rsync + Utility.SRV + Utility.SafeCommand + Utility.Scheduled + Utility.Scheduled.QuickCheck + Utility.Shell + Utility.SimpleProtocol + Utility.Split + Utility.SshConfig + Utility.SshHost + Utility.Su + Utility.SystemDirectory + Utility.TList + Utility.Tense + Utility.ThreadLock + Utility.ThreadScheduler + Utility.Tmp + Utility.Tmp.Dir + Utility.Tor + Utility.Touch + Utility.Tuple + Utility.Url + Utility.UserInfo + Utility.Verifiable + + if (os(windows)) + Other-Modules: + Utility.LockFile.Windows + Utility.LockPool.Windows + else + Other-Modules: + Utility.LockFile.Posix + Utility.LockPool.Posix diff --git a/test/fixtures/Cabal/hackage/x509-validation-1.4.0.cabal b/test/fixtures/Cabal/hackage/x509-validation-1.4.0.cabal new file mode 100644 index 00000000..4b97c12f --- /dev/null +++ b/test/fixtures/Cabal/hackage/x509-validation-1.4.0.cabal @@ -0,0 +1,38 @@ +Name: x509-validation +Version: 1.4.0 +x-revision: 1 +Description: X.509 Certificate and CRL validation +License: BSD3 +License-file: LICENSE +Copyright: Vincent Hanquez +Author: Vincent Hanquez +Maintainer: Vincent Hanquez +Synopsis: X.509 Certificate and CRL validation +Build-Type: Simple +Category: Data +stability: experimental +Homepage: http://github.com/vincenthz/hs-certificate +Cabal-Version: >=1.6 + +Library + Build-Depends: base >= 3 && < 5 + , bytestring + , mtl + , pem >= 0.1 && < 0.2 + , asn1-types + , x509 < 1.4.2 + , x509-store + , crypto-pubkey < 0.1.4 + , cryptohash + , containers + , directory + , filepath + , process + , time + Exposed-modules: Data.X509.Validation + Other-modules: Data.X509.Validation.Signature + ghc-options: -Wall + +source-repository head + type: git + location: git://github.com/vincenthz/hs-certificate diff --git a/test/fixtures/Cabal/hackage/x509-validation-1.4.8.cabal b/test/fixtures/Cabal/hackage/x509-validation-1.4.8.cabal new file mode 100644 index 00000000..c17b9db6 --- /dev/null +++ b/test/fixtures/Cabal/hackage/x509-validation-1.4.8.cabal @@ -0,0 +1,41 @@ +Name: x509-validation +Version: 1.4.8 +Description: X.509 Certificate and CRL validation +License: BSD3 +License-file: LICENSE +Copyright: Vincent Hanquez +Author: Vincent Hanquez +Maintainer: Vincent Hanquez +Synopsis: X.509 Certificate and CRL validation +Build-Type: Simple +Category: Data +stability: experimental +Homepage: http://github.com/vincenthz/hs-certificate +Cabal-Version: >=1.6 + +Library + Build-Depends: base >= 3 && < 5 + , bytestring + , mtl + , containers + , directory + , filepath + , process + , time + , pem >= 0.1 && < 0.3 + , asn1-types >= 0.2 && < 0.3 + , asn1-encoding >= 0.8 && < 0.9 + , x509 >= 1.4.7 && < 1.5 + , x509-store >= 1.4 && < 1.5 + , crypto-pubkey >= 0.1.4 && < 0.3 + , crypto-pubkey-types >= 0.4 && < 0.5 + , cryptohash >= 0.9 && < 0.12 + Exposed-modules: Data.X509.Validation + Other-modules: Data.X509.Validation.Signature + Data.X509.Validation.Fingerprint + ghc-options: -Wall + +source-repository head + type: git + location: git://github.com/vincenthz/hs-certificate + subdir: x509-validation diff --git a/test/fixtures/Cabal/hackage/xml-conduit-0.5.0.cabal b/test/fixtures/Cabal/hackage/xml-conduit-0.5.0.cabal new file mode 100644 index 00000000..fe92ffbc --- /dev/null +++ b/test/fixtures/Cabal/hackage/xml-conduit-0.5.0.cabal @@ -0,0 +1,73 @@ +name: xml-conduit +version: 0.5.0 +license: BSD3 +license-file: LICENSE +author: Michael Snoyman , Aristid Breitkreuz +maintainer: Michael Snoyman +synopsis: Pure-Haskell utilities for dealing with XML with the conduit package. +description: + This package provides parsing and rendering functions for XML. It is based on the datatypes found in the xml-types package. This package is broken up into the following modules: + . + * Text.XML: DOM-based parsing and rendering. This is the most commonly used module. + . + * Text.XML.Cursor: A wrapper around "Text.XML" which allows bidirectional traversing of the DOM, similar to XPath. (Note: Text.XML.Cursor.Generic is the same concept, but will work with any node representation.) + . + * Text.XML.Unresolved: A slight modification to "Text.XML" which does not require all entities to be resolved at parsing. The datatypes are slightly more complicated here, and therefore this module is only recommended when you need to deal directly with raw entities. + . + * Text.XML.Stream.Parse: Streaming parser, including some streaming parser combinators. + . + * Text.XML.Stream.Render: Streaming renderer. + . + Additionally, the xml-hamlet package provides a more convenient syntax for creating XML documents. For a more thorough tutorial on this library, please see . +category: XML, Conduit +stability: Stable +cabal-version: >= 1.8 +build-type: Simple +homepage: http://github.com/snoyberg/xml +extra-source-files: test/main.hs + +flag test + default: False + +library + build-depends: base >= 4 && < 5 + , conduit >= 0.0 && < 0.1 + , attoparsec-conduit >= 0.0 && < 0.1 + , blaze-builder-conduit >= 0.0 && < 0.1 + , bytestring >= 0.9 && < 0.10 + , text >= 0.7 && < 0.12 + , containers >= 0.2 && < 0.5 + , xml-types >= 0.3 && < 0.4 + , attoparsec >= 0.10 + , blaze-builder >= 0.2 && < 0.4 + , transformers >= 0.2 && < 0.3 + , failure >= 0.1 && < 0.2 + , data-default >= 0.2 && < 0.4 + , system-filepath >= 0.4 && < 0.5 + exposed-modules: Text.XML.Stream.Parse + Text.XML.Stream.Render + Text.XML.Unresolved + Text.XML.Cursor + Text.XML.Cursor.Generic + Text.XML + other-modules: Text.XML.Stream.Token + ghc-options: -Wall + +test-suite runtests + type: exitcode-stdio-1.0 + main-is: main.hs + hs-source-dirs: test + build-depends: base + , containers + , text + , transformers + , bytestring + , xml-conduit + , hspec + , HUnit + , xml-types + , conduit + +source-repository head + type: git + location: git://github.com/snoyberg/xml.git diff --git a/test/fixtures/Cabal/hackage/xml-conduit-1.9.1.0.cabal b/test/fixtures/Cabal/hackage/xml-conduit-1.9.1.0.cabal new file mode 100644 index 00000000..162a1457 --- /dev/null +++ b/test/fixtures/Cabal/hackage/xml-conduit-1.9.1.0.cabal @@ -0,0 +1,77 @@ +cabal-version: >= 1.14 + +name: xml-conduit +version: 1.9.1.0 +license: MIT +license-file: LICENSE +author: Michael Snoyman , Aristid Breitkreuz +maintainer: Michael Snoyman +synopsis: Pure-Haskell utilities for dealing with XML with the conduit package. +description: Hackage documentation generation is not reliable. For up to date documentation, please see: . +category: XML, Conduit +stability: Stable +build-type: Custom +homepage: http://github.com/snoyberg/xml +extra-source-files: README.md + ChangeLog.md +tested-with: GHC >=8.0 && <8.12 + +custom-setup + setup-depends: base >= 4 && <5, Cabal, cabal-doctest >= 1 && <1.1 + +library + build-depends: base >= 4 && < 5 + , conduit >= 1.3 && < 1.4 + , conduit-extra >= 1.3 && < 1.4 + , resourcet >= 1.2 && < 1.3 + , bytestring >= 0.10.2 + , text >= 0.7 + , containers >= 0.2 + , xml-types >= 0.3.4 && < 0.4 + , attoparsec >= 0.10 + , transformers >= 0.2 && < 0.6 + , data-default-class + , blaze-markup >= 0.5 + , blaze-html >= 0.5 + , deepseq >= 1.1.0.0 + exposed-modules: Text.XML.Stream.Parse + Text.XML.Stream.Render + Text.XML.Unresolved + Text.XML.Cursor + Text.XML.Cursor.Generic + Text.XML + other-modules: Text.XML.Stream.Token + ghc-options: -Wall + hs-source-dirs: src + default-language: Haskell2010 + +test-suite unit + type: exitcode-stdio-1.0 + main-is: unit.hs + hs-source-dirs: test + build-depends: base + , containers + , text + , transformers + , bytestring + , xml-conduit + , hspec >= 1.3 + , HUnit + , xml-types >= 0.3.1 + , conduit + , blaze-markup + , resourcet + default-language: Haskell2010 + +test-suite doctest + type: exitcode-stdio-1.0 + main-is: doctest.hs + hs-source-dirs: test + build-depends: base + , doctest >= 0.8 + , xml-conduit + default-language: Haskell2010 + +source-repository head + type: git + location: git://github.com/snoyberg/xml.git diff --git a/test/fixtures/Cabal/hackage/xmonad-contrib-0.11.2.cabal b/test/fixtures/Cabal/hackage/xmonad-contrib-0.11.2.cabal new file mode 100644 index 00000000..7b3d73c4 --- /dev/null +++ b/test/fixtures/Cabal/hackage/xmonad-contrib-0.11.2.cabal @@ -0,0 +1,314 @@ +name: xmonad-contrib +version: 0.11.2 +x-revision: 1 +homepage: http://xmonad.org/ +synopsis: Third party extensions for xmonad +description: + Third party tiling algorithms, configurations and scripts to xmonad, + a tiling window manager for X. + . + For an introduction to building, configuring and using xmonad + extensions, see "XMonad.Doc". In particular: + . + "XMonad.Doc.Configuring", a guide to configuring xmonad + . + "XMonad.Doc.Extending", using the contributed extensions library + . + "XMonad.Doc.Developing", introduction to xmonad internals and writing + your own extensions. + . +category: System +license: BSD3 +license-file: LICENSE +author: Spencer Janssen & others +maintainer: xmonad@haskell.org +extra-source-files: README scripts/generate-configs scripts/run-xmonad.sh + scripts/window-properties.sh + scripts/xinitrc scripts/xmonad-acpi.c + scripts/xmonad-clock.c + tests/genMain.hs + tests/ManageDocks.hs + tests/Selective.hs + tests/SwapWorkspaces.hs + tests/XPrompt.hs +cabal-version: >= 1.6 +build-type: Simple +bug-reports: http://code.google.com/p/xmonad/issues/list + +tested-with: GHC==7.6.1 + +source-repository head + type: darcs + location: http://code.haskell.org/XMonadContrib + + +flag small_base + description: Choose the new smaller, split-up base package. + +flag use_xft + description: Use Xft to render text + +flag testing + description: Testing mode + default: False + +library + if flag(small_base) + build-depends: base >= 3 && < 4.7, + containers, + directory, + extensible-exceptions, + old-locale, + old-time, + process, + random + else + build-depends: base < 3 + + if flag(use_xft) + build-depends: X11-xft >= 0.2, utf8-string + extensions: ForeignFunctionInterface + cpp-options: -DXFT + + build-depends: mtl >= 1 && < 3, unix, X11 >= 1.6.1 && < 1.7, xmonad >= 0.11 && < 0.12, utf8-string + + if true + ghc-options: -fwarn-tabs -Wall + + extensions: ForeignFunctionInterface + + if flag(testing) + ghc-options: -fwarn-tabs -Werror + + if impl(ghc >= 6.12.1) + ghc-options: -fno-warn-unused-do-bind + + if impl (ghc == 6.10.1) && arch (x86_64) + ghc-options: -O0 + + exposed-modules: XMonad.Doc + XMonad.Doc.Configuring + XMonad.Doc.Extending + XMonad.Doc.Developing + XMonad.Actions.BluetileCommands + XMonad.Actions.Commands + XMonad.Actions.ConstrainedResize + XMonad.Actions.CopyWindow + XMonad.Actions.CycleRecentWS + XMonad.Actions.CycleSelectedLayouts + XMonad.Actions.CycleWindows + XMonad.Actions.CycleWS + XMonad.Actions.DeManage + XMonad.Actions.DwmPromote + XMonad.Actions.DynamicWorkspaces + XMonad.Actions.DynamicWorkspaceGroups + XMonad.Actions.DynamicWorkspaceOrder + XMonad.Actions.FindEmptyWorkspace + XMonad.Actions.FlexibleManipulate + XMonad.Actions.FlexibleResize + XMonad.Actions.FloatKeys + XMonad.Actions.FloatSnap + XMonad.Actions.FocusNth + XMonad.Actions.GridSelect + XMonad.Actions.GroupNavigation + XMonad.Actions.Launcher + XMonad.Actions.MessageFeedback + XMonad.Actions.MouseGestures + XMonad.Actions.MouseResize + XMonad.Actions.Navigation2D + XMonad.Actions.NoBorders + XMonad.Actions.OnScreen + XMonad.Actions.PerWorkspaceKeys + XMonad.Actions.PhysicalScreens + XMonad.Actions.Plane + XMonad.Actions.Promote + XMonad.Actions.RandomBackground + XMonad.Actions.KeyRemap + XMonad.Actions.RotSlaves + XMonad.Actions.Search + XMonad.Actions.ShowText + XMonad.Actions.SimpleDate + XMonad.Actions.SinkAll + XMonad.Actions.SpawnOn + XMonad.Actions.Submap + XMonad.Actions.SwapWorkspaces + XMonad.Actions.TagWindows + XMonad.Actions.TopicSpace + XMonad.Actions.UpdateFocus + XMonad.Actions.UpdatePointer + XMonad.Actions.Warp + XMonad.Actions.WindowBringer + XMonad.Actions.WindowGo + XMonad.Actions.WindowMenu + XMonad.Actions.WindowNavigation + XMonad.Actions.WithAll + XMonad.Actions.WorkspaceCursors + XMonad.Actions.WorkspaceNames + XMonad.Actions.Workscreen + XMonad.Config.Arossato + XMonad.Config.Azerty + XMonad.Config.Bluetile + XMonad.Config.Desktop + XMonad.Config.Droundy + XMonad.Config.Gnome + XMonad.Config.Kde + XMonad.Config.Sjanssen + XMonad.Config.Xfce + XMonad.Hooks.CurrentWorkspaceOnTop + XMonad.Hooks.DebugEvents + XMonad.Hooks.DebugKeyEvents + XMonad.Hooks.DynamicBars + XMonad.Hooks.DynamicHooks + XMonad.Hooks.DynamicLog + XMonad.Hooks.DebugStack + XMonad.Hooks.EwmhDesktops + XMonad.Hooks.FadeInactive + XMonad.Hooks.FadeWindows + XMonad.Hooks.FloatNext + XMonad.Hooks.ICCCMFocus + XMonad.Hooks.InsertPosition + XMonad.Hooks.ManageDocks + XMonad.Hooks.ManageHelpers + XMonad.Hooks.Minimize + XMonad.Hooks.Place + XMonad.Hooks.PositionStoreHooks + XMonad.Hooks.RestoreMinimized + XMonad.Hooks.ScreenCorners + XMonad.Hooks.Script + XMonad.Hooks.ServerMode + XMonad.Hooks.SetWMName + XMonad.Hooks.ToggleHook + XMonad.Hooks.UrgencyHook + XMonad.Hooks.WorkspaceByPos + XMonad.Hooks.XPropManage + XMonad.Layout.Accordion + XMonad.Layout.AutoMaster + XMonad.Layout.BorderResize + XMonad.Layout.BoringWindows + XMonad.Layout.ButtonDecoration + XMonad.Layout.CenteredMaster + XMonad.Layout.Circle + XMonad.Layout.Column + XMonad.Layout.Combo + XMonad.Layout.ComboP + XMonad.Layout.Cross + XMonad.Layout.Decoration + XMonad.Layout.DecorationAddons + XMonad.Layout.DecorationMadness + XMonad.Layout.Dishes + XMonad.Layout.DraggingVisualizer + XMonad.Layout.DragPane + XMonad.Layout.Drawer + XMonad.Layout.DwmStyle + XMonad.Layout.FixedColumn + XMonad.Layout.Fullscreen + XMonad.Layout.Gaps + XMonad.Layout.Grid + XMonad.Layout.GridVariants + XMonad.Layout.Groups + XMonad.Layout.Groups.Examples + XMonad.Layout.Groups.Helpers + XMonad.Layout.Groups.Wmii + XMonad.Layout.HintedGrid + XMonad.Layout.HintedTile + XMonad.Layout.IM + XMonad.Layout.ImageButtonDecoration + XMonad.Layout.IndependentScreens + XMonad.Layout.LayoutBuilder + XMonad.Layout.LayoutBuilderP + XMonad.Layout.LayoutCombinators + XMonad.Layout.LayoutHints + XMonad.Layout.LayoutModifier + XMonad.Layout.LayoutScreens + XMonad.Layout.LimitWindows + XMonad.Layout.MagicFocus + XMonad.Layout.Magnifier + XMonad.Layout.Master + XMonad.Layout.Maximize + XMonad.Layout.MessageControl + XMonad.Layout.Minimize + XMonad.Layout.Monitor + XMonad.Layout.Mosaic + XMonad.Layout.MosaicAlt + XMonad.Layout.MouseResizableTile + XMonad.Layout.MultiColumns + XMonad.Layout.MultiToggle + XMonad.Layout.MultiToggle.Instances + XMonad.Layout.Named + XMonad.Layout.NoBorders + XMonad.Layout.NoFrillsDecoration + XMonad.Layout.OnHost + XMonad.Layout.OneBig + XMonad.Layout.PerWorkspace + XMonad.Layout.PositionStoreFloat + XMonad.Layout.Reflect + XMonad.Layout.Renamed + XMonad.Layout.ResizableTile + XMonad.Layout.ResizeScreen + XMonad.Layout.Roledex + XMonad.Layout.ShowWName + XMonad.Layout.SimpleDecoration + XMonad.Layout.SimpleFloat + XMonad.Layout.Simplest + XMonad.Layout.SimplestFloat + XMonad.Layout.Spacing + XMonad.Layout.Spiral + XMonad.Layout.Square + XMonad.Layout.StackTile + XMonad.Layout.SubLayouts + XMonad.Layout.TabBarDecoration + XMonad.Layout.Tabbed + XMonad.Layout.ThreeColumns + XMonad.Layout.ToggleLayouts + XMonad.Layout.TrackFloating + XMonad.Layout.TwoPane + XMonad.Layout.WindowArranger + XMonad.Layout.WindowNavigation + XMonad.Layout.WindowSwitcherDecoration + XMonad.Layout.WorkspaceDir + XMonad.Layout.ZoomRow + XMonad.Prompt + XMonad.Prompt.AppendFile + XMonad.Prompt.AppLauncher + XMonad.Prompt.Directory + XMonad.Prompt.DirExec + XMonad.Prompt.Email + XMonad.Prompt.Input + XMonad.Prompt.Layout + XMonad.Prompt.Man + XMonad.Prompt.RunOrRaise + XMonad.Prompt.Shell + XMonad.Prompt.Ssh + XMonad.Prompt.Theme + XMonad.Prompt.Window + XMonad.Prompt.Workspace + XMonad.Prompt.XMonad + XMonad.Util.Cursor + XMonad.Util.CustomKeys + XMonad.Util.DebugWindow + XMonad.Util.Dmenu + XMonad.Util.Dzen + XMonad.Util.ExtensibleState + XMonad.Util.EZConfig + XMonad.Util.Font + XMonad.Util.Image + XMonad.Util.Invisible + XMonad.Util.Loggers + XMonad.Util.NamedActions + XMonad.Util.NamedScratchpad + XMonad.Util.NamedWindows + XMonad.Util.Paste + XMonad.Util.PositionStore + XMonad.Util.Replace + XMonad.Util.Run + XMonad.Util.Scratchpad + XMonad.Util.SpawnOnce + XMonad.Util.Stack + XMonad.Util.StringProp + XMonad.Util.Themes + XMonad.Util.Timer + XMonad.Util.Types + XMonad.Util.WindowProperties + XMonad.Util.WorkspaceCompare + XMonad.Util.XSelection + XMonad.Util.XUtils diff --git a/test/fixtures/Cabal/hackage/xmonad-contrib-0.5.cabal b/test/fixtures/Cabal/hackage/xmonad-contrib-0.5.cabal new file mode 100644 index 00000000..6798108a --- /dev/null +++ b/test/fixtures/Cabal/hackage/xmonad-contrib-0.5.cabal @@ -0,0 +1,137 @@ +name: xmonad-contrib +version: 0.5 +homepage: http://xmonad.org/ +synopsis: Third party extensions for xmonad +description: + Third party tiling algorithms, configurations and scripts to xmonad, + a tiling window manager for X. + . + For an introduction to building, configuring and using xmonad + extensions, see "XMonad.Doc". In particular: + . + "XMonad.Doc.Configuring", a guide to configuring xmonad + . + "XMonad.Doc.Extending", using the contributed extensions library + . + "XMonad.Doc.Developing", introduction to xmonad internals and writing + your own extensions. + . +category: System +license: BSD3 +license-file: LICENSE +author: Spencer Janssen +maintainer: sjanssen@cse.unl.edu +extra-source-files: README scripts/generate-configs scripts/run-xmonad.sh + scripts/xinitrc scripts/xmonad-acpi.c + scripts/xmonad-clock.c tests/test_SwapWorkspaces.hs + tests/test_XPrompt.hs +cabal-version: >= 1.2.1 + +flag small_base + description: Choose the new smaller, split-up base package. + +flag use_xft + description: Use Xft to render text + +library + if flag(small_base) + build-depends: base >= 3, containers, directory, process, random + else + build-depends: base < 3 + + if flag(use_xft) + build-depends: X11-xft >= 0.2 + cpp-options: -DXFT + + build-depends: mtl, unix, X11>=1.4.0, xmonad==0.5 + ghc-options: -Wall -Werror + exposed-modules: XMonad.Doc + XMonad.Doc.Configuring + XMonad.Doc.Extending + XMonad.Doc.Developing + XMonad.Actions.Commands + XMonad.Actions.ConstrainedResize + XMonad.Actions.CopyWindow + XMonad.Actions.CycleWS + XMonad.Actions.DeManage + XMonad.Actions.DwmPromote + XMonad.Actions.DynamicWorkspaces + XMonad.Actions.FindEmptyWorkspace + XMonad.Actions.FlexibleManipulate + XMonad.Actions.FlexibleResize + XMonad.Actions.FloatKeys + XMonad.Actions.FocusNth + XMonad.Actions.MouseGestures + XMonad.Actions.RotSlaves + XMonad.Actions.RotView + XMonad.Actions.SimpleDate + XMonad.Actions.SinkAll + XMonad.Actions.Submap + XMonad.Actions.SwapWorkspaces + XMonad.Actions.TagWindows + XMonad.Actions.Warp + XMonad.Actions.WindowBringer + XMonad.Actions.WmiiActions + XMonad.Config.Sjanssen + XMonad.Config.Dons + XMonad.Config.Arossato + XMonad.Config.Droundy + XMonad.Hooks.DynamicLog + XMonad.Hooks.EwmhDesktops + XMonad.Hooks.ManageDocks + XMonad.Hooks.SetWMName + XMonad.Hooks.UrgencyHook + XMonad.Hooks.XPropManage + XMonad.Layout.Accordion + XMonad.Layout.Circle + XMonad.Layout.Combo + XMonad.Layout.Dishes + XMonad.Layout.DragPane + XMonad.Layout.Grid + XMonad.Layout.HintedTile + XMonad.Layout.LayoutCombinators + XMonad.Layout.LayoutHints + XMonad.Layout.LayoutModifier + XMonad.Layout.LayoutScreens + XMonad.Layout.MagicFocus + XMonad.Layout.Magnifier + XMonad.Layout.Maximize + XMonad.Layout.Mosaic + XMonad.Layout.MosaicAlt + XMonad.Layout.MultiToggle + XMonad.Layout.Named + XMonad.Layout.NoBorders + XMonad.Layout.PerWorkspace + XMonad.Layout.ResizableTile + XMonad.Layout.Roledex + XMonad.Layout.Spiral + XMonad.Layout.Square + XMonad.Layout.Tabbed + XMonad.Layout.ThreeColumns + XMonad.Layout.ToggleLayouts + XMonad.Layout.TwoPane + XMonad.Layout.WindowNavigation + XMonad.Layout.WorkspaceDir + XMonad.Prompt.Directory + XMonad.Prompt + XMonad.Prompt.Layout + XMonad.Prompt.Man + XMonad.Prompt.Shell + XMonad.Prompt.Ssh + XMonad.Prompt.Window + XMonad.Prompt.Workspace + XMonad.Prompt.XMonad + XMonad.Prompt.AppendFile + XMonad.Prompt.Input + XMonad.Prompt.Email + XMonad.Util.Anneal + XMonad.Util.CustomKeys + XMonad.Util.Dmenu + XMonad.Util.Dzen + XMonad.Util.EZConfig + XMonad.Util.Font + XMonad.Util.Invisible + XMonad.Util.NamedWindows + XMonad.Util.Run + XMonad.Util.XSelection + XMonad.Util.XUtils