diff --git a/.github/dependabot.yml b/.github/dependabot.yml index b5eaa004db36..7ff4b3ed8af5 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -10,7 +10,7 @@ updates: directory: "/apps/block_scout_web/assets" open-pull-requests-limit: 10 schedule: - interval: "weekly" + interval: "monthly" ignore: - dependency-name: "bootstrap" - dependency-name: "web3" @@ -20,4 +20,4 @@ updates: directory: "/apps/explorer" open-pull-requests-limit: 10 schedule: - interval: "weekly" + interval: "monthly" diff --git a/.github/workflows/config.yml b/.github/workflows/config.yml index 4f22355b41b0..a7f759e30465 100644 --- a/.github/workflows/config.yml +++ b/.github/workflows/config.yml @@ -26,6 +26,7 @@ on: - 'docker/*' - 'docker-compose/*' pull_request: + types: [opened, synchronize, reopened, labeled] branches: - master - production-optimism @@ -33,8 +34,8 @@ on: env: MIX_ENV: test - OTP_VERSION: ${{ vars.OTP_VERSION }} - ELIXIR_VERSION: ${{ vars.ELIXIR_VERSION }} + OTP_VERSION: ${{ vars.OTP_VERSION || '25.3.2.8' }} + ELIXIR_VERSION: ${{ vars.ELIXIR_VERSION || '1.14.5' }} ACCOUNT_AUTH0_DOMAIN: "blockscoutcom.us.auth0.com" jobs: @@ -46,9 +47,30 @@ jobs: steps: - id: set-matrix run: | - echo "matrix=$matrixStringifiedObject" >> $GITHUB_OUTPUT - env: - matrixStringifiedObject: '{"chain-type": ["ethereum", "polygon_edge", "polygon_zkevm", "rsk", "suave", "stability", "filecoin"]}' + echo "matrix=$(node -e ' + + // Add/remove CI matrix chain types here + const defaultChainTypes = ["default"]; + const chainTypes = ["ethereum", "polygon_zkevm", "rsk", "stability", "filecoin", "optimism", "arbitrum"]; + const extraChainTypes = ["suave", "polygon_edge"]; + + // Chain type matrix we use in master branch + const allChainTypes = [].concat(defaultChainTypes, chainTypes, extraChainTypes); + + const labels = ${{ github.event_name == 'pull_request' && toJson(github.event.pull_request.labels.*.name) || '[]' }}; + const ciLabels = labels.filter(label => label.startsWith("ci:")); + const labeledChainTypes = [].concat( + defaultChainTypes.filter(chainType => ciLabels.includes("ci:" + chainType)), + chainTypes.filter(chainType => ciLabels.includes("ci:all") || ciLabels.includes("ci:" + chainType)), + extraChainTypes.filter(chainType => ciLabels.includes("ci:" + chainType)) + ); + + // Chain type matrix we use in PRs to master branch + const ciChainTypes = labeledChainTypes.length > 0 ? labeledChainTypes : defaultChainTypes; + + const matrix = { "chain-type": ${{ github.event_name == 'pull_request' && 'ciChainTypes' || 'allChainTypes' }} }; + console.log(JSON.stringify(matrix)); + ')" >> $GITHUB_OUTPUT build-and-cache: name: Build and Cache deps @@ -59,6 +81,9 @@ jobs: with: otp-version: ${{ env.OTP_VERSION }} elixir-version: ${{ env.ELIXIR_VERSION }} + hexpm-mirrors: | + https://builds.hex.pm + https://cdn.jsdelivr.net/hex - name: "ELIXIR_VERSION.lock" run: echo "${ELIXIR_VERSION}" > ELIXIR_VERSION.lock @@ -123,6 +148,9 @@ jobs: with: otp-version: ${{ env.OTP_VERSION }} elixir-version: ${{ env.ELIXIR_VERSION }} + hexpm-mirrors: | + https://builds.hex.pm + https://cdn.jsdelivr.net/hex - name: Restore Mix Deps Cache uses: actions/cache/restore@v4 @@ -147,6 +175,9 @@ jobs: with: otp-version: ${{ env.OTP_VERSION }} elixir-version: ${{ env.ELIXIR_VERSION }} + hexpm-mirrors: | + https://builds.hex.pm + https://cdn.jsdelivr.net/hex - name: Restore Mix Deps Cache uses: actions/cache/restore@v4 @@ -176,6 +207,9 @@ jobs: with: otp-version: ${{ env.OTP_VERSION }} elixir-version: ${{ env.ELIXIR_VERSION }} + hexpm-mirrors: | + https://builds.hex.pm + https://cdn.jsdelivr.net/hex - name: Restore Mix Deps Cache uses: actions/cache/restore@v4 @@ -203,12 +237,12 @@ jobs: mkdir -p priv/plts mix dialyzer --plt env: - CHAIN_TYPE: ${{ matrix.chain-type }} + CHAIN_TYPE: ${{ matrix.chain-type != 'default' && matrix.chain-type || '' }} - name: Run Dialyzer run: mix dialyzer --halt-exit-status env: - CHAIN_TYPE: ${{ matrix.chain-type }} + CHAIN_TYPE: ${{ matrix.chain-type != 'default' && matrix.chain-type || '' }} gettext: name: Missing translation keys check @@ -220,6 +254,9 @@ jobs: with: otp-version: ${{ env.OTP_VERSION }} elixir-version: ${{ env.ELIXIR_VERSION }} + hexpm-mirrors: | + https://builds.hex.pm + https://cdn.jsdelivr.net/hex - name: Restore Mix Deps Cache uses: actions/cache/restore@v4 @@ -246,6 +283,9 @@ jobs: with: otp-version: ${{ env.OTP_VERSION }} elixir-version: ${{ env.ELIXIR_VERSION }} + hexpm-mirrors: | + https://builds.hex.pm + https://cdn.jsdelivr.net/hex - name: Mix Deps Cache uses: actions/cache/restore@v4 @@ -275,6 +315,9 @@ jobs: with: otp-version: ${{ env.OTP_VERSION }} elixir-version: ${{ env.ELIXIR_VERSION }} + hexpm-mirrors: | + https://builds.hex.pm + https://cdn.jsdelivr.net/hex - name: Mix Deps Cache uses: actions/cache/restore@v4 @@ -323,6 +366,9 @@ jobs: with: otp-version: ${{ env.OTP_VERSION }} elixir-version: ${{ env.ELIXIR_VERSION }} + hexpm-mirrors: | + https://builds.hex.pm + https://cdn.jsdelivr.net/hex - name: Mix Deps Cache uses: actions/cache/restore@v4 @@ -369,6 +415,9 @@ jobs: with: otp-version: ${{ env.OTP_VERSION }} elixir-version: ${{ env.ELIXIR_VERSION }} + hexpm-mirrors: | + https://builds.hex.pm + https://cdn.jsdelivr.net/hex - name: Mix Deps Cache uses: actions/cache/restore@v4 @@ -431,6 +480,9 @@ jobs: with: otp-version: ${{ env.OTP_VERSION }} elixir-version: ${{ env.ELIXIR_VERSION }} + hexpm-mirrors: | + https://builds.hex.pm + https://cdn.jsdelivr.net/hex - name: Mix Deps Cache uses: actions/cache/restore@v4 @@ -456,7 +508,7 @@ jobs: PGUSER: postgres ETHEREUM_JSONRPC_CASE: "EthereumJSONRPC.Case.Nethermind.Mox" ETHEREUM_JSONRPC_WEB_SOCKET_CASE: "EthereumJSONRPC.WebSocket.Case.Mox" - CHAIN_TYPE: "${{ matrix.chain-type }}" + CHAIN_TYPE: ${{ matrix.chain-type != 'default' && matrix.chain-type || '' }} test_nethermind_mox_explorer: strategy: fail-fast: false @@ -491,6 +543,9 @@ jobs: with: otp-version: ${{ env.OTP_VERSION }} elixir-version: ${{ env.ELIXIR_VERSION }} + hexpm-mirrors: | + https://builds.hex.pm + https://cdn.jsdelivr.net/hex - name: Mix Deps Cache uses: actions/cache/restore@v4 @@ -527,7 +582,7 @@ jobs: PGUSER: postgres ETHEREUM_JSONRPC_CASE: "EthereumJSONRPC.Case.Nethermind.Mox" ETHEREUM_JSONRPC_WEB_SOCKET_CASE: "EthereumJSONRPC.WebSocket.Case.Mox" - CHAIN_TYPE: "${{ matrix.chain-type }}" + CHAIN_TYPE: ${{ matrix.chain-type != 'default' && matrix.chain-type || '' }} test_nethermind_mox_indexer: strategy: fail-fast: false @@ -562,6 +617,9 @@ jobs: with: otp-version: ${{ env.OTP_VERSION }} elixir-version: ${{ env.ELIXIR_VERSION }} + hexpm-mirrors: | + https://builds.hex.pm + https://cdn.jsdelivr.net/hex - name: Mix Deps Cache uses: actions/cache/restore@v4 @@ -590,7 +648,7 @@ jobs: PGUSER: postgres ETHEREUM_JSONRPC_CASE: "EthereumJSONRPC.Case.Nethermind.Mox" ETHEREUM_JSONRPC_WEB_SOCKET_CASE: "EthereumJSONRPC.WebSocket.Case.Mox" - CHAIN_TYPE: "${{ matrix.chain-type }}" + CHAIN_TYPE: ${{ matrix.chain-type != 'default' && matrix.chain-type || '' }} test_nethermind_mox_block_scout_web: strategy: fail-fast: false @@ -630,6 +688,9 @@ jobs: with: otp-version: ${{ env.OTP_VERSION }} elixir-version: ${{ env.ELIXIR_VERSION }} + hexpm-mirrors: | + https://builds.hex.pm + https://cdn.jsdelivr.net/hex - name: Mix Deps Cache uses: actions/cache/restore@v4 @@ -682,8 +743,9 @@ jobs: ETHEREUM_JSONRPC_WEB_SOCKET_CASE: "EthereumJSONRPC.WebSocket.Case.Mox" CHAIN_ID: "10200" API_RATE_LIMIT_DISABLED: "true" + API_GRAPHQL_RATE_LIMIT_DISABLED: "true" ADMIN_PANEL_ENABLED: "true" ACCOUNT_ENABLED: "true" ACCOUNT_REDIS_URL: "redis://localhost:6379" SOURCIFY_INTEGRATION_ENABLED: "true" - CHAIN_TYPE: "${{ matrix.chain-type }}" + CHAIN_TYPE: ${{ matrix.chain-type != 'default' && matrix.chain-type || '' }} diff --git a/.github/workflows/prerelease.yml b/.github/workflows/prerelease.yml index b47c998c8a35..42233668dffc 100644 --- a/.github/workflows/prerelease.yml +++ b/.github/workflows/prerelease.yml @@ -25,18 +25,15 @@ jobs: docker-username: ${{ secrets.DOCKER_USERNAME }} docker-password: ${{ secrets.DOCKER_PASSWORD }} - - name: Build & Push Docker image + - name: Build and push Docker image for Ethereum uses: docker/build-push-action@v5 with: context: . file: ./docker/Dockerfile push: true - cache-from: type=registry,ref=blockscout/blockscout:buildcache - cache-to: type=registry,ref=blockscout/blockscout:buildcache,mode=max - tags: blockscout/blockscout:master, blockscout/blockscout:latest, blockscout/blockscout:${{ env.RELEASE_VERSION }}-alpha.${{ inputs.number }} + tags: blockscout/blockscout-ethereum:${{ env.RELEASE_VERSION }}-alpha.${{ inputs.number }} platforms: | linux/amd64 - linux/arm64/v8 build-args: | CACHE_EXCHANGE_RATES_PERIOD= API_V1_READ_METHODS_DISABLED=false @@ -44,14 +41,10 @@ jobs: API_V1_WRITE_METHODS_DISABLED=false CACHE_TOTAL_GAS_USAGE_COUNTER_ENABLED= ADMIN_PANEL_ENABLED=false - DECODE_NOT_A_CONTRACT_CALLS=false - MIXPANEL_URL= - MIXPANEL_TOKEN= - AMPLITUDE_URL= - AMPLITUDE_API_KEY= CACHE_ADDRESS_WITH_BALANCES_UPDATE_INTERVAL= BLOCKSCOUT_VERSION=v${{ env.RELEASE_VERSION }}-alpha.${{ inputs.number }} RELEASE_VERSION=${{ env.RELEASE_VERSION }} + CHAIN_TYPE=ethereum - name: Build & Push Docker image for Shibarium uses: docker/build-push-action@v5 @@ -61,7 +54,7 @@ jobs: push: true cache-from: type=registry,ref=blockscout/blockscout-shibarium:buildcache cache-to: type=registry,ref=blockscout/blockscout-shibarium:buildcache,mode=max - tags: blockscout/blockscout-shibarium:latest, blockscout/blockscout-shibarium:${{ env.RELEASE_VERSION }}-alpha.${{ inputs.number }} + tags: blockscout/blockscout-shibarium:${{ env.RELEASE_VERSION }}-alpha.${{ inputs.number }} platforms: | linux/amd64 build-args: | @@ -74,4 +67,74 @@ jobs: CACHE_ADDRESS_WITH_BALANCES_UPDATE_INTERVAL= BLOCKSCOUT_VERSION=v${{ env.RELEASE_VERSION }}-alpha.${{ inputs.number }} RELEASE_VERSION=${{ env.RELEASE_VERSION }} - CHAIN_TYPE=shibarium \ No newline at end of file + CHAIN_TYPE=shibarium + + - name: Build and push Docker image for ZkSync + uses: docker/build-push-action@v5 + with: + context: . + file: ./docker/Dockerfile + push: true + tags: blockscout/blockscout-zksync:${{ env.RELEASE_VERSION }}-alpha.${{ inputs.number }} + platforms: | + linux/amd64 + build-args: | + CACHE_EXCHANGE_RATES_PERIOD= + API_V1_READ_METHODS_DISABLED=false + DISABLE_WEBAPP=false + API_V1_WRITE_METHODS_DISABLED=false + CACHE_TOTAL_GAS_USAGE_COUNTER_ENABLED= + ADMIN_PANEL_ENABLED=false + CACHE_ADDRESS_WITH_BALANCES_UPDATE_INTERVAL= + BLOCKSCOUT_VERSION=v${{ env.RELEASE_VERSION }}-alpha.${{ inputs.number }} + RELEASE_VERSION=${{ env.RELEASE_VERSION }} + CHAIN_TYPE=zksync + + - name: Build and push Docker image for Optimism + uses: docker/build-push-action@v5 + with: + context: . + file: ./docker/Dockerfile + push: true + tags: blockscout/blockscout-optimism:${{ env.RELEASE_VERSION }}-alpha.${{ inputs.number }} + platforms: | + linux/amd64 + build-args: | + CACHE_EXCHANGE_RATES_PERIOD= + API_V1_READ_METHODS_DISABLED=false + DISABLE_WEBAPP=false + API_V1_WRITE_METHODS_DISABLED=false + CACHE_TOTAL_GAS_USAGE_COUNTER_ENABLED= + ADMIN_PANEL_ENABLED=false + CACHE_ADDRESS_WITH_BALANCES_UPDATE_INTERVAL= + BLOCKSCOUT_VERSION=v${{ env.RELEASE_VERSION }}-beta.+commit.${{ env.SHORT_SHA }} + RELEASE_VERSION=${{ env.RELEASE_VERSION }} + CHAIN_TYPE=optimism + + - name: Build & Push Docker image + uses: docker/build-push-action@v5 + with: + context: . + file: ./docker/Dockerfile + push: true + cache-from: type=registry,ref=blockscout/blockscout:buildcache + cache-to: type=registry,ref=blockscout/blockscout:buildcache,mode=max + tags: blockscout/blockscout:master, blockscout/blockscout:${{ env.RELEASE_VERSION }}-alpha.${{ inputs.number }} + platforms: | + linux/amd64 + linux/arm64/v8 + build-args: | + CACHE_EXCHANGE_RATES_PERIOD= + API_V1_READ_METHODS_DISABLED=false + DISABLE_WEBAPP=false + API_V1_WRITE_METHODS_DISABLED=false + CACHE_TOTAL_GAS_USAGE_COUNTER_ENABLED= + ADMIN_PANEL_ENABLED=false + DECODE_NOT_A_CONTRACT_CALLS=false + MIXPANEL_URL= + MIXPANEL_TOKEN= + AMPLITUDE_URL= + AMPLITUDE_API_KEY= + CACHE_ADDRESS_WITH_BALANCES_UPDATE_INTERVAL= + BLOCKSCOUT_VERSION=v${{ env.RELEASE_VERSION }}-alpha.${{ inputs.number }} + RELEASE_VERSION=${{ env.RELEASE_VERSION }} \ No newline at end of file diff --git a/.github/workflows/publish-docker-image-for-eth-goerli.yml b/.github/workflows/publish-docker-image-for-eth-goerli.yml index 5fc153cf9e41..262802e27ec2 100644 --- a/.github/workflows/publish-docker-image-for-eth-goerli.yml +++ b/.github/workflows/publish-docker-image-for-eth-goerli.yml @@ -28,6 +28,7 @@ jobs: push: true tags: blockscout/blockscout-${{ env.DOCKER_CHAIN_NAME }}:latest, blockscout/blockscout-${{ env.DOCKER_CHAIN_NAME }}:${{ env.RELEASE_VERSION }}-postrelease-${{ env.SHORT_SHA }} build-args: | + CHAIN_TYPE=ethereum CACHE_EXCHANGE_RATES_PERIOD= API_V1_READ_METHODS_DISABLED=false DISABLE_WEBAPP=false diff --git a/.github/workflows/publish-docker-image-for-eth-sepolia.yml b/.github/workflows/publish-docker-image-for-eth-sepolia.yml index e476ad5f47a4..d63d935df4a6 100644 --- a/.github/workflows/publish-docker-image-for-eth-sepolia.yml +++ b/.github/workflows/publish-docker-image-for-eth-sepolia.yml @@ -28,6 +28,7 @@ jobs: push: true tags: blockscout/blockscout-${{ env.DOCKER_CHAIN_NAME }}:latest, blockscout/blockscout-${{ env.DOCKER_CHAIN_NAME }}:${{ env.RELEASE_VERSION }}-postrelease-${{ env.SHORT_SHA }} build-args: | + CHAIN_TYPE=ethereum CACHE_EXCHANGE_RATES_PERIOD= API_V1_READ_METHODS_DISABLED=false DISABLE_WEBAPP=false diff --git a/.github/workflows/publish-docker-image-for-eth.yml b/.github/workflows/publish-docker-image-for-eth.yml index 02635daa56c7..3e3bed50190d 100644 --- a/.github/workflows/publish-docker-image-for-eth.yml +++ b/.github/workflows/publish-docker-image-for-eth.yml @@ -28,6 +28,7 @@ jobs: push: true tags: blockscout/blockscout-${{ env.DOCKER_CHAIN_NAME }}:${{ env.RELEASE_VERSION }}-postrelease-${{ env.SHORT_SHA }}-experimental build-args: | + CHAIN_TYPE=ethereum CACHE_EXCHANGE_RATES_PERIOD= API_V1_READ_METHODS_DISABLED=false DISABLE_WEBAPP=false diff --git a/.github/workflows/publish-docker-image-for-gnosis-chain.yml b/.github/workflows/publish-docker-image-for-gnosis-chain.yml index 31aa884f38f7..86f59dfd0643 100644 --- a/.github/workflows/publish-docker-image-for-gnosis-chain.yml +++ b/.github/workflows/publish-docker-image-for-gnosis-chain.yml @@ -36,8 +36,6 @@ jobs: CACHE_TOTAL_GAS_USAGE_COUNTER_ENABLED= ADMIN_PANEL_ENABLED=false CACHE_ADDRESS_WITH_BALANCES_UPDATE_INTERVAL= - DISABLE_BRIDGE_MARKET_CAP_UPDATER=false - CACHE_BRIDGE_MARKET_CAP_UPDATE_INTERVAL= - SENTRY_DSN_CLIENT_GNOSIS=${{ secrets.SENTRY_DSN_CLIENT_GNOSIS }} BLOCKSCOUT_VERSION=v${{ env.RELEASE_VERSION }}-beta.+commit.${{ env.SHORT_SHA }} - RELEASE_VERSION=${{ env.RELEASE_VERSION }} \ No newline at end of file + RELEASE_VERSION=${{ env.RELEASE_VERSION }} + CHAIN_TYPE=ethereum \ No newline at end of file diff --git a/.github/workflows/publish-docker-image-for-optimism.yml b/.github/workflows/publish-docker-image-for-optimism.yml index c47114afc547..13361808767f 100644 --- a/.github/workflows/publish-docker-image-for-optimism.yml +++ b/.github/workflows/publish-docker-image-for-optimism.yml @@ -39,4 +39,5 @@ jobs: ADMIN_PANEL_ENABLED=false CACHE_ADDRESS_WITH_BALANCES_UPDATE_INTERVAL= BLOCKSCOUT_VERSION=v${{ env.RELEASE_VERSION }}-beta.+commit.${{ env.SHORT_SHA }} - RELEASE_VERSION=${{ env.RELEASE_VERSION }} \ No newline at end of file + RELEASE_VERSION=${{ env.RELEASE_VERSION }} + CHAIN_TYPE=optimism \ No newline at end of file diff --git a/.github/workflows/publish-docker-image-for-zetachain.yml b/.github/workflows/publish-docker-image-for-zetachain.yml new file mode 100644 index 000000000000..0abd04fe2cca --- /dev/null +++ b/.github/workflows/publish-docker-image-for-zetachain.yml @@ -0,0 +1,40 @@ +name: Zetachain publish Docker image + +on: + workflow_dispatch: + push: + branches: + - production-zetachain +jobs: + push_to_registry: + name: Push Docker image to Docker Hub + runs-on: ubuntu-latest + env: + RELEASE_VERSION: ${{ vars.RELEASE_VERSION }} + DOCKER_CHAIN_NAME: zetachain + steps: + - uses: actions/checkout@v4 + - name: Setup repo + uses: ./.github/actions/setup-repo-and-short-sha + with: + docker-username: ${{ secrets.DOCKER_USERNAME }} + docker-password: ${{ secrets.DOCKER_PASSWORD }} + + - name: Build and push Docker image + uses: docker/build-push-action@v5 + with: + context: . + file: ./docker/Dockerfile + push: true + tags: blockscout/blockscout-${{ env.DOCKER_CHAIN_NAME }}:${{ env.RELEASE_VERSION }}-postrelease-${{ env.SHORT_SHA }} + build-args: | + CACHE_EXCHANGE_RATES_PERIOD= + API_V1_READ_METHODS_DISABLED=false + DISABLE_WEBAPP=false + API_V1_WRITE_METHODS_DISABLED=false + CACHE_TOTAL_GAS_USAGE_COUNTER_ENABLED= + ADMIN_PANEL_ENABLED=false + CACHE_ADDRESS_WITH_BALANCES_UPDATE_INTERVAL= + BLOCKSCOUT_VERSION=v${{ env.RELEASE_VERSION }}-beta.+commit.${{ env.SHORT_SHA }} + RELEASE_VERSION=${{ env.RELEASE_VERSION }} + CHAIN_TYPE=zetachain \ No newline at end of file diff --git a/.github/workflows/publish-docker-image-for-zksync.yml b/.github/workflows/publish-docker-image-for-zksync.yml index 3cd9c2ad750d..7cb48f0ab8bb 100644 --- a/.github/workflows/publish-docker-image-for-zksync.yml +++ b/.github/workflows/publish-docker-image-for-zksync.yml @@ -1,7 +1,6 @@ name: Zksync publish Docker image on: - workflow_dispatch: push: branches: - production-zksync @@ -36,4 +35,5 @@ jobs: ADMIN_PANEL_ENABLED=false CACHE_ADDRESS_WITH_BALANCES_UPDATE_INTERVAL= BLOCKSCOUT_VERSION=v${{ env.RELEASE_VERSION }}-beta.+commit.${{ env.SHORT_SHA }} - RELEASE_VERSION=${{ env.RELEASE_VERSION }} \ No newline at end of file + RELEASE_VERSION=${{ env.RELEASE_VERSION }} + CHAIN_TYPE=zksync \ No newline at end of file diff --git a/.github/workflows/release-additional.yml b/.github/workflows/release-additional.yml index a16c4511080a..be7db50858fa 100644 --- a/.github/workflows/release-additional.yml +++ b/.github/workflows/release-additional.yml @@ -44,28 +44,6 @@ jobs: RELEASE_VERSION=${{ env.RELEASE_VERSION }} CHAIN_TYPE=rsk - - name: Build and push Docker image for Polygon Edge - uses: docker/build-push-action@v5 - with: - context: . - file: ./docker/Dockerfile - push: true - tags: blockscout/blockscout-polygon-edge:latest, blockscout/blockscout-polygon-edge:${{ env.RELEASE_VERSION }} - platforms: | - linux/amd64 - linux/arm64/v8 - build-args: | - CACHE_EXCHANGE_RATES_PERIOD= - API_V1_READ_METHODS_DISABLED=false - DISABLE_WEBAPP=false - API_V1_WRITE_METHODS_DISABLED=false - CACHE_TOTAL_GAS_USAGE_COUNTER_ENABLED= - ADMIN_PANEL_ENABLED=false - CACHE_ADDRESS_WITH_BALANCES_UPDATE_INTERVAL= - BLOCKSCOUT_VERSION=v${{ env.RELEASE_VERSION }}-beta - RELEASE_VERSION=${{ env.RELEASE_VERSION }} - CHAIN_TYPE=polygon_edge - - name: Build and push Docker image for Stability uses: docker/build-push-action@v5 with: @@ -87,17 +65,19 @@ jobs: BLOCKSCOUT_VERSION=v${{ env.RELEASE_VERSION }}-beta RELEASE_VERSION=${{ env.RELEASE_VERSION }} CHAIN_TYPE=stability - - name: Build and push Docker image for Shibarium + + - name: Build and push Docker image for Fuse uses: docker/build-push-action@v5 with: context: . file: ./docker/Dockerfile push: true - tags: blockscout/blockscout-shibarium:latest, blockscout/blockscout-shibarium:${{ env.RELEASE_VERSION }} + tags: blockscout/blockscout-fuse:latest, blockscout/blockscout-fuse:${{ env.RELEASE_VERSION }} platforms: | linux/amd64 linux/arm64/v8 build-args: | + BRIDGED_TOKENS_ENABLED=true CACHE_EXCHANGE_RATES_PERIOD= API_V1_READ_METHODS_DISABLED=false DISABLE_WEBAPP=false @@ -107,19 +87,18 @@ jobs: CACHE_ADDRESS_WITH_BALANCES_UPDATE_INTERVAL= BLOCKSCOUT_VERSION=v${{ env.RELEASE_VERSION }}-beta RELEASE_VERSION=${{ env.RELEASE_VERSION }} - CHAIN_TYPE=shibarium - - name: Build and push Docker image for Fuse + + - name: Build and push Docker image for Polygon Edge uses: docker/build-push-action@v5 with: context: . file: ./docker/Dockerfile push: true - tags: blockscout/blockscout-fuse:latest, blockscout/blockscout-fuse:${{ env.RELEASE_VERSION }} + tags: blockscout/blockscout-polygon-edge:latest, blockscout/blockscout-polygon-edge:${{ env.RELEASE_VERSION }} platforms: | linux/amd64 linux/arm64/v8 build-args: | - BRIDGED_TOKENS_ENABLED=true CACHE_EXCHANGE_RATES_PERIOD= API_V1_READ_METHODS_DISABLED=false DISABLE_WEBAPP=false @@ -128,4 +107,5 @@ jobs: ADMIN_PANEL_ENABLED=false CACHE_ADDRESS_WITH_BALANCES_UPDATE_INTERVAL= BLOCKSCOUT_VERSION=v${{ env.RELEASE_VERSION }}-beta - RELEASE_VERSION=${{ env.RELEASE_VERSION }} \ No newline at end of file + RELEASE_VERSION=${{ env.RELEASE_VERSION }} + CHAIN_TYPE=polygon_edge \ No newline at end of file diff --git a/.github/workflows/release-arbitrum.yml b/.github/workflows/release-arbitrum.yml new file mode 100644 index 000000000000..8ba7fafae2c3 --- /dev/null +++ b/.github/workflows/release-arbitrum.yml @@ -0,0 +1,45 @@ +name: Release for Arbitrum + +on: + release: + types: [published] + +env: + OTP_VERSION: ${{ vars.OTP_VERSION }} + ELIXIR_VERSION: ${{ vars.ELIXIR_VERSION }} + +jobs: + push_to_registry: + name: Push Docker image to Docker Hub + runs-on: ubuntu-latest + env: + RELEASE_VERSION: ${{ vars.RELEASE_VERSION }} + steps: + - uses: actions/checkout@v4 + - name: Setup repo + uses: ./.github/actions/setup-repo + with: + docker-username: ${{ secrets.DOCKER_USERNAME }} + docker-password: ${{ secrets.DOCKER_PASSWORD }} + + - name: Build and push Docker image for Arbitrum + uses: docker/build-push-action@v5 + with: + context: . + file: ./docker/Dockerfile + push: true + tags: blockscout/blockscout-arbitrum:latest, blockscout/blockscout-arbitrum:${{ env.RELEASE_VERSION }} + platforms: | + linux/amd64 + linux/arm64/v8 + build-args: | + CACHE_EXCHANGE_RATES_PERIOD= + API_V1_READ_METHODS_DISABLED=false + DISABLE_WEBAPP=false + API_V1_WRITE_METHODS_DISABLED=false + CACHE_TOTAL_GAS_USAGE_COUNTER_ENABLED= + ADMIN_PANEL_ENABLED=false + CACHE_ADDRESS_WITH_BALANCES_UPDATE_INTERVAL= + BLOCKSCOUT_VERSION=v${{ env.RELEASE_VERSION }}-beta + RELEASE_VERSION=${{ env.RELEASE_VERSION }} + CHAIN_TYPE=arbitrum \ No newline at end of file diff --git a/.github/workflows/release-eth.yml b/.github/workflows/release-eth.yml new file mode 100644 index 000000000000..b6d1b6743e49 --- /dev/null +++ b/.github/workflows/release-eth.yml @@ -0,0 +1,45 @@ +name: Release for Ethereum + +on: + release: + types: [published] + +env: + OTP_VERSION: ${{ vars.OTP_VERSION }} + ELIXIR_VERSION: ${{ vars.ELIXIR_VERSION }} + +jobs: + push_to_registry: + name: Push Docker image to Docker Hub + runs-on: ubuntu-latest + env: + RELEASE_VERSION: ${{ vars.RELEASE_VERSION }} + steps: + - uses: actions/checkout@v4 + - name: Setup repo + uses: ./.github/actions/setup-repo + with: + docker-username: ${{ secrets.DOCKER_USERNAME }} + docker-password: ${{ secrets.DOCKER_PASSWORD }} + + - name: Build and push Docker image for Ethereum + uses: docker/build-push-action@v5 + with: + context: . + file: ./docker/Dockerfile + push: true + tags: blockscout/blockscout-ethereum:latest, blockscout/blockscout-ethereum:${{ env.RELEASE_VERSION }} + platforms: | + linux/amd64 + linux/arm64/v8 + build-args: | + CACHE_EXCHANGE_RATES_PERIOD= + API_V1_READ_METHODS_DISABLED=false + DISABLE_WEBAPP=false + API_V1_WRITE_METHODS_DISABLED=false + CACHE_TOTAL_GAS_USAGE_COUNTER_ENABLED= + ADMIN_PANEL_ENABLED=false + CACHE_ADDRESS_WITH_BALANCES_UPDATE_INTERVAL= + BLOCKSCOUT_VERSION=v${{ env.RELEASE_VERSION }}-beta + RELEASE_VERSION=${{ env.RELEASE_VERSION }} + CHAIN_TYPE=ethereum \ No newline at end of file diff --git a/.github/workflows/release-filecoin.yml b/.github/workflows/release-filecoin.yml new file mode 100644 index 000000000000..d8b77901a75d --- /dev/null +++ b/.github/workflows/release-filecoin.yml @@ -0,0 +1,45 @@ +name: Release for Filecoin + +on: + release: + types: [published] + +env: + OTP_VERSION: ${{ vars.OTP_VERSION }} + ELIXIR_VERSION: ${{ vars.ELIXIR_VERSION }} + +jobs: + push_to_registry: + name: Push Docker image to Docker Hub + runs-on: ubuntu-latest + env: + RELEASE_VERSION: ${{ vars.RELEASE_VERSION }} + steps: + - uses: actions/checkout@v4 + - name: Setup repo + uses: ./.github/actions/setup-repo + with: + docker-username: ${{ secrets.DOCKER_USERNAME }} + docker-password: ${{ secrets.DOCKER_PASSWORD }} + + - name: Build and push Docker image for Filecoin + uses: docker/build-push-action@v5 + with: + context: . + file: ./docker/Dockerfile + push: true + tags: blockscout/blockscout-filecoin:latest, blockscout/blockscout-filecoin:${{ env.RELEASE_VERSION }} + platforms: | + linux/amd64 + linux/arm64/v8 + build-args: | + CACHE_EXCHANGE_RATES_PERIOD= + API_V1_READ_METHODS_DISABLED=false + DISABLE_WEBAPP=false + API_V1_WRITE_METHODS_DISABLED=false + CACHE_TOTAL_GAS_USAGE_COUNTER_ENABLED= + ADMIN_PANEL_ENABLED=false + CACHE_ADDRESS_WITH_BALANCES_UPDATE_INTERVAL= + BLOCKSCOUT_VERSION=v${{ env.RELEASE_VERSION }}-beta + RELEASE_VERSION=${{ env.RELEASE_VERSION }} + CHAIN_TYPE=filecoin \ No newline at end of file diff --git a/.github/workflows/release-gnosis.yml b/.github/workflows/release-gnosis.yml new file mode 100644 index 000000000000..bdabb752b213 --- /dev/null +++ b/.github/workflows/release-gnosis.yml @@ -0,0 +1,46 @@ +name: Release for Gnosis Chain + +on: + release: + types: [published] + +env: + OTP_VERSION: ${{ vars.OTP_VERSION }} + ELIXIR_VERSION: ${{ vars.ELIXIR_VERSION }} + +jobs: + push_to_registry: + name: Push Docker image to Docker Hub + runs-on: ubuntu-latest + env: + RELEASE_VERSION: ${{ vars.RELEASE_VERSION }} + steps: + - uses: actions/checkout@v4 + - name: Setup repo + uses: ./.github/actions/setup-repo + with: + docker-username: ${{ secrets.DOCKER_USERNAME }} + docker-password: ${{ secrets.DOCKER_PASSWORD }} + + - name: Build and push Docker image for Gnosis chain + uses: docker/build-push-action@v5 + with: + context: . + file: ./docker/Dockerfile + push: true + tags: blockscout/blockscout-xdai:latest, blockscout/blockscout-xdai:${{ env.RELEASE_VERSION }} + platforms: | + linux/amd64 + linux/arm64/v8 + build-args: | + BRIDGED_TOKENS_ENABLED=true + CACHE_EXCHANGE_RATES_PERIOD= + API_V1_READ_METHODS_DISABLED=false + DISABLE_WEBAPP=false + API_V1_WRITE_METHODS_DISABLED=false + CACHE_TOTAL_GAS_USAGE_COUNTER_ENABLED= + ADMIN_PANEL_ENABLED=false + CACHE_ADDRESS_WITH_BALANCES_UPDATE_INTERVAL= + BLOCKSCOUT_VERSION=v${{ env.RELEASE_VERSION }}-beta + RELEASE_VERSION=${{ env.RELEASE_VERSION }} + CHAIN_TYPE=ethereum \ No newline at end of file diff --git a/.github/workflows/release-optimism.yml b/.github/workflows/release-optimism.yml new file mode 100644 index 000000000000..486d73967cfd --- /dev/null +++ b/.github/workflows/release-optimism.yml @@ -0,0 +1,45 @@ +name: Release for Optimism + +on: + release: + types: [published] + +env: + OTP_VERSION: ${{ vars.OTP_VERSION }} + ELIXIR_VERSION: ${{ vars.ELIXIR_VERSION }} + +jobs: + push_to_registry: + name: Push Docker image to Docker Hub + runs-on: ubuntu-latest + env: + RELEASE_VERSION: ${{ vars.RELEASE_VERSION }} + steps: + - uses: actions/checkout@v4 + - name: Setup repo + uses: ./.github/actions/setup-repo + with: + docker-username: ${{ secrets.DOCKER_USERNAME }} + docker-password: ${{ secrets.DOCKER_PASSWORD }} + + - name: Build and push Docker image for Optimism + uses: docker/build-push-action@v5 + with: + context: . + file: ./docker/Dockerfile + push: true + tags: blockscout/blockscout-optimism:latest, blockscout/blockscout-optimism:${{ env.RELEASE_VERSION }} + platforms: | + linux/amd64 + linux/arm64/v8 + build-args: | + CACHE_EXCHANGE_RATES_PERIOD= + API_V1_READ_METHODS_DISABLED=false + DISABLE_WEBAPP=false + API_V1_WRITE_METHODS_DISABLED=false + CACHE_TOTAL_GAS_USAGE_COUNTER_ENABLED= + ADMIN_PANEL_ENABLED=false + CACHE_ADDRESS_WITH_BALANCES_UPDATE_INTERVAL= + BLOCKSCOUT_VERSION=v${{ env.RELEASE_VERSION }}-beta + RELEASE_VERSION=${{ env.RELEASE_VERSION }} + CHAIN_TYPE=optimism \ No newline at end of file diff --git a/.github/workflows/release-shibarium.yml b/.github/workflows/release-shibarium.yml new file mode 100644 index 000000000000..8ed678ee7cb9 --- /dev/null +++ b/.github/workflows/release-shibarium.yml @@ -0,0 +1,45 @@ +name: Release for Shibarium + +on: + release: + types: [published] + +env: + OTP_VERSION: ${{ vars.OTP_VERSION }} + ELIXIR_VERSION: ${{ vars.ELIXIR_VERSION }} + +jobs: + push_to_registry: + name: Push Docker image to Docker Hub + runs-on: ubuntu-latest + env: + RELEASE_VERSION: ${{ vars.RELEASE_VERSION }} + steps: + - uses: actions/checkout@v4 + - name: Setup repo + uses: ./.github/actions/setup-repo + with: + docker-username: ${{ secrets.DOCKER_USERNAME }} + docker-password: ${{ secrets.DOCKER_PASSWORD }} + + - name: Build and push Docker image for Shibarium + uses: docker/build-push-action@v5 + with: + context: . + file: ./docker/Dockerfile + push: true + tags: blockscout/blockscout-shibarium:latest, blockscout/blockscout-shibarium:${{ env.RELEASE_VERSION }} + platforms: | + linux/amd64 + linux/arm64/v8 + build-args: | + CACHE_EXCHANGE_RATES_PERIOD= + API_V1_READ_METHODS_DISABLED=false + DISABLE_WEBAPP=false + API_V1_WRITE_METHODS_DISABLED=false + CACHE_TOTAL_GAS_USAGE_COUNTER_ENABLED= + ADMIN_PANEL_ENABLED=false + CACHE_ADDRESS_WITH_BALANCES_UPDATE_INTERVAL= + BLOCKSCOUT_VERSION=v${{ env.RELEASE_VERSION }}-beta + RELEASE_VERSION=${{ env.RELEASE_VERSION }} + CHAIN_TYPE=shibarium \ No newline at end of file diff --git a/.github/workflows/release-zetachain.yml b/.github/workflows/release-zetachain.yml new file mode 100644 index 000000000000..cd9c5abc14c9 --- /dev/null +++ b/.github/workflows/release-zetachain.yml @@ -0,0 +1,45 @@ +name: Release for Zetachain + +on: + release: + types: [published] + +env: + OTP_VERSION: ${{ vars.OTP_VERSION }} + ELIXIR_VERSION: ${{ vars.ELIXIR_VERSION }} + +jobs: + push_to_registry: + name: Push Docker image to Docker Hub + runs-on: ubuntu-latest + env: + RELEASE_VERSION: ${{ vars.RELEASE_VERSION }} + steps: + - uses: actions/checkout@v4 + - name: Setup repo + uses: ./.github/actions/setup-repo + with: + docker-username: ${{ secrets.DOCKER_USERNAME }} + docker-password: ${{ secrets.DOCKER_PASSWORD }} + + - name: Build and push Docker image for Zetachain + uses: docker/build-push-action@v5 + with: + context: . + file: ./docker/Dockerfile + push: true + tags: blockscout/blockscout-zetachain:latest, blockscout/blockscout-zetachain:${{ env.RELEASE_VERSION }} + platforms: | + linux/amd64 + linux/arm64/v8 + build-args: | + CACHE_EXCHANGE_RATES_PERIOD= + API_V1_READ_METHODS_DISABLED=false + DISABLE_WEBAPP=false + API_V1_WRITE_METHODS_DISABLED=false + CACHE_TOTAL_GAS_USAGE_COUNTER_ENABLED= + ADMIN_PANEL_ENABLED=false + CACHE_ADDRESS_WITH_BALANCES_UPDATE_INTERVAL= + BLOCKSCOUT_VERSION=v${{ env.RELEASE_VERSION }}-beta + RELEASE_VERSION=${{ env.RELEASE_VERSION }} + CHAIN_TYPE=zetachain \ No newline at end of file diff --git a/.github/workflows/release-zksync.yml b/.github/workflows/release-zksync.yml new file mode 100644 index 000000000000..15ed069ca941 --- /dev/null +++ b/.github/workflows/release-zksync.yml @@ -0,0 +1,46 @@ +name: Release for ZkSync + +on: + workflow_dispatch: + release: + types: [published] + +env: + OTP_VERSION: ${{ vars.OTP_VERSION }} + ELIXIR_VERSION: ${{ vars.ELIXIR_VERSION }} + +jobs: + push_to_registry: + name: Push Docker image to Docker Hub + runs-on: ubuntu-latest + env: + RELEASE_VERSION: ${{ vars.RELEASE_VERSION }} + steps: + - uses: actions/checkout@v4 + - name: Setup repo + uses: ./.github/actions/setup-repo + with: + docker-username: ${{ secrets.DOCKER_USERNAME }} + docker-password: ${{ secrets.DOCKER_PASSWORD }} + + - name: Build and push Docker image for ZkSync + uses: docker/build-push-action@v5 + with: + context: . + file: ./docker/Dockerfile + push: true + tags: blockscout/blockscout-zksync:latest, blockscout/blockscout-zksync:${{ env.RELEASE_VERSION }} + platforms: | + linux/amd64 + linux/arm64/v8 + build-args: | + CACHE_EXCHANGE_RATES_PERIOD= + API_V1_READ_METHODS_DISABLED=false + DISABLE_WEBAPP=false + API_V1_WRITE_METHODS_DISABLED=false + CACHE_TOTAL_GAS_USAGE_COUNTER_ENABLED= + ADMIN_PANEL_ENABLED=false + CACHE_ADDRESS_WITH_BALANCES_UPDATE_INTERVAL= + BLOCKSCOUT_VERSION=v${{ env.RELEASE_VERSION }}-beta + RELEASE_VERSION=${{ env.RELEASE_VERSION }} + CHAIN_TYPE=zksync \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 94a70192b09e..443947cc02b2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,18 +1,267 @@ -# ChangeLog +# Changelog + +## 6.5.0 + +### 🚀 Features + +- Certified smart contracts ([#9910](https://github.com/blockscout/blockscout/issues/9910)) +- Exit on provided invalid CHAIN_TYPE ([#9904](https://github.com/blockscout/blockscout/issues/9904)) +- IPFS gateway URL extra params ([#9898](https://github.com/blockscout/blockscout/issues/9898)) +- Zerion API proxy ([#9896](https://github.com/blockscout/blockscout/issues/9896)) +- Support Optimism Fault Proofs ([#9892](https://github.com/blockscout/blockscout/issues/9892)) +- Return number of days in address's coin-balance-history-by-day API v2 endpoint ([#9806](https://github.com/blockscout/blockscout/issues/9806)) +- Allow the use of Coingecko demo account ([#9835](https://github.com/blockscout/blockscout/issues/9835)) + +### 🐛 Bug Fixes + +- Set refetch_needed: false on block import ([#9953](https://github.com/blockscout/blockscout/issues/9953)) +- `GAS_PRICE_ORACLE_NUM_OF_BLOCKS` calculation ([#9943](https://github.com/blockscout/blockscout/issues/9943)) +- Handle "null" filter in api/v1/logs-csv ([#9933](https://github.com/blockscout/blockscout/issues/9933)) +- Fix metadata preload ([#9925](https://github.com/blockscout/blockscout/issues/9925)) +- `coin_price_change_percentage` calculation ([#9774](https://github.com/blockscout/blockscout/issues/9774)) +- Remove backend dependency in microservices.yml ([#9905](https://github.com/blockscout/blockscout/issues/9905)) +- Expand memory only if it was shrunk ([#9907](https://github.com/blockscout/blockscout/issues/9907)) +- Coin balances fetcher error logging ([#9902](https://github.com/blockscout/blockscout/issues/9902)) +- Refactor catchup rudimentaries + fix graceful shutdown ([#9729](https://github.com/blockscout/blockscout/issues/9729)) +- Handle transactions with `gas_price` set to `nil` in `transaction_revert_reason/2` ([#9647](https://github.com/blockscout/blockscout/issues/9647)) +- Correct processing of sized array to view in API v2 ([#9854](https://github.com/blockscout/blockscout/issues/9854)) +- Broadcast realtime coin balances ([#9804](https://github.com/blockscout/blockscout/issues/9804)) +- Disable BlockReward fetcher for unsupported variants ([#9859](https://github.com/blockscout/blockscout/issues/9859)) +- Add non-unique log_index support in update_token_instances_owner ([#9862](https://github.com/blockscout/blockscout/issues/9862)) + +### ⚡ Performance + +- Paging function edge cases fix ([#9820](https://github.com/blockscout/blockscout/issues/9820)) +- Adjust unfetched_address_token_balances_index to fit all bound query conditions ([#9912](https://github.com/blockscout/blockscout/issues/9912)) +- Enhance index for token holders list ([#9816](https://github.com/blockscout/blockscout/issues/9816)) +- Improve performance of token page transfers tab ([#9809](https://github.com/blockscout/blockscout/issues/9809)) + +### ⚙️ Miscellaneous Tasks + +- Fix some typos in comments ([#9900](https://github.com/blockscout/blockscout/issues/9900)) +- Add queue expanding logic to memory monitor ([#9870](https://github.com/blockscout/blockscout/issues/9870)) +- Bump ex_doc from 0.31.2 to 0.32.1 ([#9889](https://github.com/blockscout/blockscout/issues/9889)) +- Separate reorgs from blocks that just need refetch ([#9674](https://github.com/blockscout/blockscout/issues/9674)) +- Unknown token in email template ([#9883](https://github.com/blockscout/blockscout/issues/9883)) +- Bump tesla from 1.8.0 to 1.9.0 ([#9886](https://github.com/blockscout/blockscout/issues/9886)) +- Bump logger_file_backend from 0.0.13 to 0.0.14 ([#9885](https://github.com/blockscout/blockscout/issues/9885)) +- Bump cloak_ecto from 1.2.0 to 1.3.0 ([#9890](https://github.com/blockscout/blockscout/issues/9890)) +- Bump ex_secp256k1 from 0.7.2 to 0.7.3 ([#9888](https://github.com/blockscout/blockscout/issues/9888)) +- Bump ex_cldr_units from 3.16.4 to 3.16.5 ([#9884](https://github.com/blockscout/blockscout/issues/9884)) +- Move `has_methods_*` fields to `/smart-contracts` endpoint response ([#9599](https://github.com/blockscout/blockscout/issues/9599)) +- Add metrics for realtime event handlers queue length ([#9822](https://github.com/blockscout/blockscout/issues/9822)) +- Increase MissingRangesCollector past check interval after the first cycle ([#9872](https://github.com/blockscout/blockscout/issues/9872)) +- Reduce number of warnings in web tests ([#9851](https://github.com/blockscout/blockscout/issues/9851)) +- Fix some typos in conments ([#9838](https://github.com/blockscout/blockscout/issues/9838)) +- Bump ex_abi from 0.7.1 to 0.7.2 ([#9841](https://github.com/blockscout/blockscout/issues/9841)) +- Remove /config/json-rpc-url API endpoint ([#9798](https://github.com/blockscout/blockscout/issues/9798)) +- Bump junit_formatter from 3.3.1 to 3.4.0 ([#9842](https://github.com/blockscout/blockscout/issues/9842)) +- Bump number from 1.0.4 to 1.0.5 ([#9843](https://github.com/blockscout/blockscout/issues/9843)) +- Bump absinthe_phoenix from 2.0.2 to 2.0.3 ([#9840](https://github.com/blockscout/blockscout/issues/9840)) +- Bump plug_cowboy from 2.7.0 to 2.7.1 ([#9844](https://github.com/blockscout/blockscout/issues/9844)) + +## 6.4.0 + +### 🚀 Features + +- Secondary coin price in `api/v2/stats` ([#9777](https://github.com/blockscout/blockscout/issues/9777)) +- Add /api/v2/blocks/{hash_or_number}/internal-transactions endpoint ([#9668](https://github.com/blockscout/blockscout/issues/9668)) +- Integrate Metadata microservice ([#9706](https://github.com/blockscout/blockscout/issues/9706)) +- Support verifier alliance and eth-bytecode-db v1.7.0 changes ([#9724](https://github.com/blockscout/blockscout/issues/9724)) +- Add rate limits to graphQL API ([#9771](https://github.com/blockscout/blockscout/issues/9771)) +- Support for internal user operation calldata decoded by microservice ([#9776](https://github.com/blockscout/blockscout/issues/9776)) +- Internal txs fetching for Arbitrum ([#9737](https://github.com/blockscout/blockscout/issues/9737)) +- Allow for custom base_url for fetching prices ([#9679](https://github.com/blockscout/blockscout/issues/9679)) +- Contract code on-demand fetcher ([#9708](https://github.com/blockscout/blockscout/issues/9708)) +- Add /api/v2/tokens/:address_hash_param/holders/csv endpoint ([#9722](https://github.com/blockscout/blockscout/issues/9722)) +- Support the 2nd version of L2<->L1 Polygon zkEVM Bridge ([#9637](https://github.com/blockscout/blockscout/issues/9637)) +- GraphQL management env vars ([#9751](https://github.com/blockscout/blockscout/issues/9751)) +- Improvements in zksync batch related transactions requests ([#9680](https://github.com/blockscout/blockscout/issues/9680)) +- Add trying to decode internal calldata for user ops ([#9675](https://github.com/blockscout/blockscout/issues/9675)) + +### 🐛 Bug Fixes + +- Apply quantity_to_integer/1 to effectiveGasPrice ([#9812](https://github.com/blockscout/blockscout/issues/9812)) +- Replace tx gas_price with effectiveGasPrice from receipt ([#9733](https://github.com/blockscout/blockscout/issues/9733)) +- Fetching GraphQL schema by GraphiQL IDE ([#9630](https://github.com/blockscout/blockscout/issues/9630)) +- Add block range check into OP Withdrawals fetcher ([#9770](https://github.com/blockscout/blockscout/issues/9770)) +- Update token's holder_count in the db from ETS module ([#9623](https://github.com/blockscout/blockscout/issues/9623)) +- Fix UTF-8 json handling in NFT metadata fetching ([#9707](https://github.com/blockscout/blockscout/issues/9707)) +- Separate ZkSync and ZkEvm readers in API controller ([#9749](https://github.com/blockscout/blockscout/issues/9749)) +- Add missing preloads ([#9520](https://github.com/blockscout/blockscout/issues/9520)) +- Change CoinGecko token image attribute priority ([#9671](https://github.com/blockscout/blockscout/issues/9671)) +- Fix Geth block tracing errors handling ([#9672](https://github.com/blockscout/blockscout/issues/9672)) +- Erc-404 token transfers null value ([#9698](https://github.com/blockscout/blockscout/issues/9698)) +- Erc-404 type stored in token balances tables ([#9700](https://github.com/blockscout/blockscout/issues/9700)) + +### 🚜 Refactor + +- `Enum.count` to `Enum.empty?` ([#9666](https://github.com/blockscout/blockscout/issues/9666)) + +### ⚡ Performance + +- Add EIP4844 blob transactions index ([#9661](https://github.com/blockscout/blockscout/issues/9661)) + +### ⚙️ Miscellaneous Tasks + +- Rework chain type matrix in CI runs ([#9704](https://github.com/blockscout/blockscout/issues/9704)) +- Exclude latest tag update from alpha releases ([#9800](https://github.com/blockscout/blockscout/issues/9800)) +- Reduce default API v1 limit by key 50 -> 10 ([#9799](https://github.com/blockscout/blockscout/issues/9799)) +- Bump autoprefixer in /apps/block_scout_web/assets ([#9786](https://github.com/blockscout/blockscout/issues/9786)) +- Remove /api/account/v1 path ([#9660](https://github.com/blockscout/blockscout/issues/9660)) +- Bump sass from 1.71.1 to 1.72.0 in /apps/block_scout_web/assets ([#9780](https://github.com/blockscout/blockscout/issues/9780)) +- Bump @babel/core in /apps/block_scout_web/assets ([#9782](https://github.com/blockscout/blockscout/issues/9782)) +- Bump webpack in /apps/block_scout_web/assets ([#9787](https://github.com/blockscout/blockscout/issues/9787)) +- Bump postcss in /apps/block_scout_web/assets ([#9785](https://github.com/blockscout/blockscout/issues/9785)) +- Bump @amplitude/analytics-browser in /apps/block_scout_web/assets ([#9788](https://github.com/blockscout/blockscout/issues/9788)) +- Bump solc from 0.8.24 to 0.8.25 in /apps/explorer ([#9789](https://github.com/blockscout/blockscout/issues/9789)) +- Bump sweetalert2 in /apps/block_scout_web/assets ([#9783](https://github.com/blockscout/blockscout/issues/9783)) +- Bump @babel/preset-env in /apps/block_scout_web/assets ([#9784](https://github.com/blockscout/blockscout/issues/9784)) +- Bump core-js in /apps/block_scout_web/assets ([#9781](https://github.com/blockscout/blockscout/issues/9781)) +- Enable Rust sc-verifier microservice by default ([#9752](https://github.com/blockscout/blockscout/issues/9752)) +- Temporarily ignore OP batches written to Celestia ([#9734](https://github.com/blockscout/blockscout/issues/9734)) +- Bump cldr_utils from 2.24.2 to 2.25.0 ([#9723](https://github.com/blockscout/blockscout/issues/9723)) +- Bump express in /apps/block_scout_web/assets ([#9725](https://github.com/blockscout/blockscout/issues/9725)) +- Bump bureaucrat from 0.2.9 to 0.2.10 ([#9669](https://github.com/blockscout/blockscout/issues/9669)) +- Fix typos ([#9693](https://github.com/blockscout/blockscout/issues/9693)) +- Bump follow-redirects from 1.15.4 to 1.15.6 in /apps/explorer ([#9648](https://github.com/blockscout/blockscout/issues/9648)) +- Bump floki from 0.36.0 to 0.36.1 ([#9670](https://github.com/blockscout/blockscout/issues/9670)) +- Use git-cliff changelog generator ([#9687](https://github.com/blockscout/blockscout/issues/9687)) + +## 6.3.0 + +### Features + +- [#9631](https://github.com/blockscout/blockscout/pull/9631) - Initial support of zksync chain type +- [#9532](https://github.com/blockscout/blockscout/pull/9532) - Add last output root size counter +- [#9511](https://github.com/blockscout/blockscout/pull/9511) - Separate errors by type in EndpointAvailabilityObserver +- [#9490](https://github.com/blockscout/blockscout/pull/9490), [#9644](https://github.com/blockscout/blockscout/pull/9644) - Add blob transaction counter and filter in block view +- [#9486](https://github.com/blockscout/blockscout/pull/9486) - Massive blocks fetcher +- [#9483](https://github.com/blockscout/blockscout/pull/9483) - Add secondary coin and transaction stats +- [#9473](https://github.com/blockscout/blockscout/pull/9473) - Add user_op interpretation +- [#9461](https://github.com/blockscout/blockscout/pull/9461) - Fetch blocks without internal transactions backwards +- [#9460](https://github.com/blockscout/blockscout/pull/9460) - Optimism chain type +- [#9409](https://github.com/blockscout/blockscout/pull/9409) - ETH JSON RPC extension +- [#9390](https://github.com/blockscout/blockscout/pull/9390) - Add stability validators +- [#8702](https://github.com/blockscout/blockscout/pull/8702) - Add OP withdrawal status to transaction page in API +- [#7200](https://github.com/blockscout/blockscout/pull/7200) - Add Optimism BedRock Deposits to the main page in API +- [#6980](https://github.com/blockscout/blockscout/pull/6980) - Add Optimism BedRock support (Txn Batches, Output Roots, Deposits, Withdrawals) + +### Fixes + +- [#9654](https://github.com/blockscout/blockscout/pull/9654) - Send timeout param in debug_traceBlockByNumber request +- [#9653](https://github.com/blockscout/blockscout/pull/9653) - Tokens import improvements +- [#9652](https://github.com/blockscout/blockscout/pull/9652) - Remove duplicated tx hashes while indexing OP batches +- [#9646](https://github.com/blockscout/blockscout/pull/9646) - Hotfix for Optimism Ecotone batch blobs indexing +- [#9640](https://github.com/blockscout/blockscout/pull/9640) - Fix no function clause matching in `BENS.item_to_address_hash_strings/1` +- [#9638](https://github.com/blockscout/blockscout/pull/9638) - Do not broadcast coin balance changes with empty value/delta +- [#9635](https://github.com/blockscout/blockscout/pull/9635) - Reset missing ranges collector to max number after the cycle is done +- [#9629](https://github.com/blockscout/blockscout/pull/9629) - Don't insert pbo for not inserted blocks +- [#9620](https://github.com/blockscout/blockscout/pull/9620) - Fix infinite retries for orphaned blobs +- [#9601](https://github.com/blockscout/blockscout/pull/9601) - Fix token instance transform for some unconventional tokens +- [#9597](https://github.com/blockscout/blockscout/pull/9597) - Update token transfers block_consensus by block_number +- [#9596](https://github.com/blockscout/blockscout/pull/9596) - Fix logging +- [#9585](https://github.com/blockscout/blockscout/pull/9585) - Fix Geth block internal transactions fetching +- [#9576](https://github.com/blockscout/blockscout/pull/9576) - Rewrite query for token transfers on address to eliminate "or" +- [#9572](https://github.com/blockscout/blockscout/pull/9572) - Fix Shibarium L1 fetcher +- [#9563](https://github.com/blockscout/blockscout/pull/9563) - Fix timestamp handler for unfinalized zkEVM batches +- [#9560](https://github.com/blockscout/blockscout/pull/9560) - Fix fetch pending transaction for hyperledger besu client +- [#9555](https://github.com/blockscout/blockscout/pull/9555) - Fix EIP-1967 beacon proxy pattern detection +- [#9529](https://github.com/blockscout/blockscout/pull/9529) - Fix `MAX_SAFE_INTEGER` frontend bug +- [#9518](https://github.com/blockscout/blockscout/pull/9518), [#9628](https://github.com/blockscout/blockscout/pull/9628) - Fix MultipleResultsError in `smart_contract_creation_tx_bytecode/1` +- [#9514](https://github.com/blockscout/blockscout/pull/9514) - Fix missing `0x` prefix for `blockNumber`, `logIndex`, `transactionIndex` and remove `transactionLogIndex` in `eth_getLogs` response. +- [#9510](https://github.com/blockscout/blockscout/pull/9510) - Fix WS false 0 token balances +- [#9512](https://github.com/blockscout/blockscout/pull/9512) - Docker-compose 2.24.6 compatibility +- [#9407](https://github.com/blockscout/blockscout/pull/9407) - ERC-404 basic support +- [#9262](https://github.com/blockscout/blockscout/pull/9262) - Fix withdrawal status +- [#9123](https://github.com/blockscout/blockscout/pull/9123) - Fixes in Optimism due to changed log topics type +- [#8831](https://github.com/blockscout/blockscout/pull/8831) - Return all OP Withdrawals bound to L2 transaction +- [#8822](https://github.com/blockscout/blockscout/pull/8822) - Hotfix for optimism_withdrawal_transaction_status function +- [#8811](https://github.com/blockscout/blockscout/pull/8811) - Consider consensus block only when retrieving OP withdrawal transaction status +- [#8364](https://github.com/blockscout/blockscout/pull/8364) - Fix API v2 for OP Withdrawals +- [#8229](https://github.com/blockscout/blockscout/pull/8229) - Fix Indexer.Fetcher.OptimismTxnBatch +- [#8208](https://github.com/blockscout/blockscout/pull/8208) - Ignore invalid frame by OP transaction batches module +- [#8122](https://github.com/blockscout/blockscout/pull/8122) - Ignore previously handled frame by OP transaction batches module +- [#7827](https://github.com/blockscout/blockscout/pull/7827) - Fix transaction batches module for L2 OP stack +- [#7776](https://github.com/blockscout/blockscout/pull/7776) - Fix transactions ordering in Indexer.Fetcher.OptimismTxnBatch +- [#7219](https://github.com/blockscout/blockscout/pull/7219) - Output L1 fields in API v2 for transaction page and fix transaction fee calculation +- [#6699](https://github.com/blockscout/blockscout/pull/6699) - L1 tx fields fix for Goerli Optimism BedRock update -## Current +### Chore + +- [#9622](https://github.com/blockscout/blockscout/pull/9622) - Add alternative `hex.pm` mirrors +- [#9571](https://github.com/blockscout/blockscout/pull/9571) - Support Optimism Ecotone upgrade by Indexer.Fetcher.Optimism.TxnBatch module +- [#9562](https://github.com/blockscout/blockscout/pull/9562) - Add cancun evm version +- [#9506](https://github.com/blockscout/blockscout/pull/9506) - API v1 bridgedtokenlist endpoint +- [#9260](https://github.com/blockscout/blockscout/pull/9260) - Optimism Delta upgrade support by Indexer.Fetcher.OptimismTxnBatch module +- [#8740](https://github.com/blockscout/blockscout/pull/8740) - Add delay to Indexer.Fetcher.OptimismTxnBatch module initialization + +
+ Dependencies version bumps + +- [#9544](https://github.com/blockscout/blockscout/pull/9544) - Bump @babel/core from 7.23.9 to 7.24.0 in /apps/block_scout_web/assets +- [#9537](https://github.com/blockscout/blockscout/pull/9537) - Bump logger_json from 5.1.3 to 5.1.4 +- [#9550](https://github.com/blockscout/blockscout/pull/9550) - Bump xss from 1.0.14 to 1.0.15 in /apps/block_scout_web/assets +- [#9539](https://github.com/blockscout/blockscout/pull/9539) - Bump floki from 0.35.4 to 0.36.0 +- [#9551](https://github.com/blockscout/blockscout/pull/9551) - Bump @amplitude/analytics-browser from 2.5.1 to 2.5.2 in /apps/block_scout_web/assets +- [#9547](https://github.com/blockscout/blockscout/pull/9547) - Bump @babel/preset-env from 7.23.9 to 7.24.0 in /apps/block_scout_web/assets +- [#9549](https://github.com/blockscout/blockscout/pull/9549) - Bump postcss-loader from 8.1.0 to 8.1.1 in /apps/block_scout_web/assets +- [#9542](https://github.com/blockscout/blockscout/pull/9542) - Bump phoenix_ecto from 4.4.3 to 4.5.0 +- [#9546](https://github.com/blockscout/blockscout/pull/9546) - https://github.com/blockscout/blockscout/pull/9546 +- [#9545](https://github.com/blockscout/blockscout/pull/9545) - Bump chart.js from 4.4.1 to 4.4.2 in /apps/block_scout_web/assets +- [#9540](https://github.com/blockscout/blockscout/pull/9540) - Bump postgrex from 0.17.4 to 0.17.5 +- [#9543](https://github.com/blockscout/blockscout/pull/9543) - Bump ueberauth from 0.10.7 to 0.10.8 +- [#9538](https://github.com/blockscout/blockscout/pull/9538) - Bump credo from 1.7.4 to 1.7.5 +- [#9607](https://github.com/blockscout/blockscout/pull/9607) - Bump redix from 1.3.0 to 1.4.1 +- [#9606](https://github.com/blockscout/blockscout/pull/9606) - Bump ecto from 3.11.1 to 3.11.2 +- [#9605](https://github.com/blockscout/blockscout/pull/9605) - Bump ex_doc from 0.31.1 to 0.31.2 +- [#9604](https://github.com/blockscout/blockscout/pull/9604) - Bump phoenix_ecto from 4.5.0 to 4.5.1 + +
+ +## 6.2.2 ### Features ### Fixes +- [#9505](https://github.com/blockscout/blockscout/pull/9505) - Add env vars for NFT sanitize migration + ### Chore +- [#9487](https://github.com/blockscout/blockscout/pull/9487) - Add tsvector index on smart_contracts.name +
Dependencies version bumps
+## 6.2.1 + +### Features + +### Fixes + +- [#9591](https://github.com/blockscout/blockscout/pull/9591) - Fix duplicated results in `methods-read` endpoint +- [#9502](https://github.com/blockscout/blockscout/pull/9502) - Add batch_size and concurrency envs for tt token type migration +- [#9493](https://github.com/blockscout/blockscout/pull/9493) - Fix API response for unknown blob hashes +- [#9484](https://github.com/blockscout/blockscout/pull/9484) - Fix read contract error +- [#9426](https://github.com/blockscout/blockscout/pull/9426) - Fix tabs counter cache bug + +### Chore + +
+ Dependencies version bumps + +- [#9478](https://github.com/blockscout/blockscout/pull/9478) - Bump floki from 0.35.3 to 0.35.4 +- [#9477](https://github.com/blockscout/blockscout/pull/9477) - Bump hammer from 6.2.0 to 6.2.1 +- [#9476](https://github.com/blockscout/blockscout/pull/9476) - Bump eslint from 8.56.0 to 8.57.0 in /apps/block_scout_web/assets +- [#9475](https://github.com/blockscout/blockscout/pull/9475) - Bump @amplitude/analytics-browser from 2.4.1 to 2.5.1 in /apps/block_scout_web/assets +- [#9474](https://github.com/blockscout/blockscout/pull/9474) - Bump sass from 1.71.0 to 1.71.1 in /apps/block_scout_web/assets +- [#9492](https://github.com/blockscout/blockscout/pull/9492) - Bump es5-ext from 0.10.62 to 0.10.64 in /apps/block_scout_web/assets + +
+ ## 6.2.0 ### Features @@ -86,6 +335,7 @@ - [#9424](https://github.com/blockscout/blockscout/pull/9424) - Bump webpack from 5.90.1 to 5.90.3 in /apps/block_scout_web/assets - [#9425](https://github.com/blockscout/blockscout/pull/9425) - Bump sass-loader from 14.1.0 to 14.1.1 in /apps/block_scout_web/assets - [#9421](https://github.com/blockscout/blockscout/pull/9421) - Bump sass from 1.70.0 to 1.71.0 in /apps/block_scout_web/assets + ## 6.1.0 @@ -779,6 +1029,7 @@ - [#7958](https://github.com/blockscout/blockscout/pull/7958) - Bump ex_doc from 0.30.2 to 0.30.3 - [#7965](https://github.com/blockscout/blockscout/pull/7965) - Bump webpack from 5.88.1 to 5.88.2 in /apps/block_scout_web/assets - [#7972](https://github.com/blockscout/blockscout/pull/7972) - Bump word-wrap from 1.2.3 to 1.2.4 in /apps/block_scout_web/assets + ## 5.2.0-beta @@ -2546,8 +2797,8 @@ - [#3249](https://github.com/blockscout/blockscout/pull/3249) - Fix incorrect ABI decoding of address in tuple output - [#3237](https://github.com/blockscout/blockscout/pull/3237) - Refine contract method signature detection for read/write feature -- [#3235](https://github.com/blockscout/blockscout/pull/3235) - Fix coin supply api edpoint -- [#3233](https://github.com/blockscout/blockscout/pull/3233) - Fix for the contract verifiaction for solc 0.5 family with experimental features enabled +- [#3235](https://github.com/blockscout/blockscout/pull/3235) - Fix coin supply api endpoint +- [#3233](https://github.com/blockscout/blockscout/pull/3233) - Fix for the contract verification for solc 0.5 family with experimental features enabled - [#3231](https://github.com/blockscout/blockscout/pull/3231) - Improve search: unlimited number of searching results - [#3231](https://github.com/blockscout/blockscout/pull/3231) - Improve search: allow search with space - [#3231](https://github.com/blockscout/blockscout/pull/3231) - Improve search: order by token holders in descending order and token/contract name is ascending order @@ -2558,7 +2809,7 @@ - [#3326](https://github.com/blockscout/blockscout/pull/3326) - Chart smooth lines - [#3250](https://github.com/blockscout/blockscout/pull/3250) - Eliminate occurrences of obsolete env variable ETHEREUM_JSONRPC_JSON_RPC_TRANSPORT -- [#3240](https://github.com/blockscout/blockscout/pull/3240), [#3251](https://github.com/blockscout/blockscout/pull/3251) - various CSS imroving +- [#3240](https://github.com/blockscout/blockscout/pull/3240), [#3251](https://github.com/blockscout/blockscout/pull/3251) - various CSS improving - [f3a720](https://github.com/blockscout/blockscout/commit/2dd909c10a79b0bf4b7541a486be114152f3a720) - Make wobserver optional ## 3.3.1-beta @@ -2923,11 +3174,11 @@ fixed menu hovers in dark mode desktop view - [#2596](https://github.com/blockscout/blockscout/pull/2596) - support AuRa's empty step reward type - [#2588](https://github.com/blockscout/blockscout/pull/2588) - add verification submission comment - [#2505](https://github.com/blockscout/blockscout/pull/2505) - support POA Network emission rewards -- [#2581](https://github.com/blockscout/blockscout/pull/2581) - Add generic Map-like Cache behaviour and implementation +- [#2581](https://github.com/blockscout/blockscout/pull/2581) - Add generic Map-like Cache behavior and implementation - [#2561](https://github.com/blockscout/blockscout/pull/2561) - Add token's type to the response of tokenlist method - [#2555](https://github.com/blockscout/blockscout/pull/2555) - find and show decoding candidates for logs - [#2499](https://github.com/blockscout/blockscout/pull/2499) - import emission reward ranges -- [#2497](https://github.com/blockscout/blockscout/pull/2497) - Add generic Ordered Cache behaviour and implementation +- [#2497](https://github.com/blockscout/blockscout/pull/2497) - Add generic Ordered Cache behavior and implementation ### Fixes @@ -2959,7 +3210,7 @@ fixed menu hovers in dark mode desktop view - [#2617](https://github.com/blockscout/blockscout/pull/2617) - skip cache update if there are no blocks inserted - [#2611](https://github.com/blockscout/blockscout/pull/2611) - fix js dependency vulnerabilities - [#2594](https://github.com/blockscout/blockscout/pull/2594) - do not start genesis data fetching periodically -- [#2590](https://github.com/blockscout/blockscout/pull/2590) - restore backward compatablity with old releases +- [#2590](https://github.com/blockscout/blockscout/pull/2590) - restore backward compatibility with old releases - [#2577](https://github.com/blockscout/blockscout/pull/2577) - Need recompile column in the env vars table - [#2574](https://github.com/blockscout/blockscout/pull/2574) - limit request body in json rpc error - [#2566](https://github.com/blockscout/blockscout/pull/2566) - upgrade absinthe phoenix @@ -2983,7 +3234,7 @@ fixed menu hovers in dark mode desktop view - [#2559](https://github.com/blockscout/blockscout/pull/2559) - fix rsk total supply for empty exchange rate - [#2553](https://github.com/blockscout/blockscout/pull/2553) - Dark theme import to the end of sass - [#2550](https://github.com/blockscout/blockscout/pull/2550) - correctly encode decimal values for frontend -- [#2549](https://github.com/blockscout/blockscout/pull/2549) - Fix wrong colour of tooltip +- [#2549](https://github.com/blockscout/blockscout/pull/2549) - Fix wrong color of tooltip - [#2548](https://github.com/blockscout/blockscout/pull/2548) - CSS preload support in Firefox - [#2547](https://github.com/blockscout/blockscout/pull/2547) - do not show eth value if it's zero on the transaction overview page - [#2543](https://github.com/blockscout/blockscout/pull/2543) - do not hide search input during logs search @@ -3172,7 +3423,7 @@ fixed menu hovers in dark mode desktop view ### Chore -- [#2127](https://github.com/blockscout/blockscout/pull/2127) - use previouse chromedriver version +- [#2127](https://github.com/blockscout/blockscout/pull/2127) - use previous chromedriver version - [#2118](https://github.com/blockscout/blockscout/pull/2118) - show only the last decompiled contract - [#2255](https://github.com/blockscout/blockscout/pull/2255) - upgrade elixir version to 1.9.0 - [#2256](https://github.com/blockscout/blockscout/pull/2256) - use the latest version of chromedriver @@ -3407,7 +3658,7 @@ Reverting of synchronous block counter, implemented in #1848 ### Fixes -- [#1630](https://github.com/blockscout/blockscout/pull/1630) - (Fix) colour for release link in the footer +- [#1630](https://github.com/blockscout/blockscout/pull/1630) - (Fix) color for release link in the footer - [#1621](https://github.com/blockscout/blockscout/pull/1621) - Modify query to fetch failed contract creations - [#1614](https://github.com/blockscout/blockscout/pull/1614) - Do not fetch burn address token balance - [#1639](https://github.com/blockscout/blockscout/pull/1614) - Optimize token holder count updates when importing address current balances diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 122503bc252f..694f0e404236 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,14 +1,13 @@ -## Contributing +# Contributing 1. Fork it ( ) 2. Create your feature branch (`git checkout -b my-new-feature`) 3. Write tests that cover your work 4. Commit your changes (`git commit -am 'Add some feature'`) 5. Push to the branch (`git push origin my-new-feature`) -6. Create a new Pull Request -7. Update CHANGELOG.md with the link to PR and description of the changes +6. Create a new Pull Request. The title of Pull Request should follow [Conventional Commits specification](https://www.conventionalcommits.org/en/v1.0.0/) and should start with `feat:`, `fix:`, `chore:`, `doc:`, `perf:`, `refactor:` prefix. -### General +## General * Commits should be one logical change that still allows all tests to pass. Prefer smaller commits if there could be two levels of logic grouping. The goal is to allow contributors in the future (including your own future self) to determine your reasoning for making changes and to allow them to cherry-pick, patch or port those changes in isolation to other branches or forks. * If during your PR you reveal a pre-existing bug: @@ -18,14 +17,14 @@ 2. Commit the fix for the bug. 3. Continue original PR work. -### Enhancements +## Enhancements Enhancements cover all changes that make users lives better: * [feature requests filed as issues](https://github.com/blockscout/blockscout/labels/enhancement) that impact end-user [contributors](https://github.com/blockscout/blockscout/labels/contributor) and [developers](https://github.com/blockscout/blockscout/labels/developer) * changes to the [architecture](https://github.com/blockscout/blockscout/labels/architecture) that make it easier for contributors (in the GitHub sense), dev-ops, and deployers to maintain and run blockscout -### Bug Fixes +## Bug Fixes For bug fixes, whenever possible, there should be at least 2 commits: @@ -34,7 +33,7 @@ For bug fixes, whenever possible, there should be at least 2 commits: This format ensures that we can run the test to reproduce the original bug without depending on the new code in the fix, which could lead to the test falsely passing. -### Incompatible Changes +## Incompatible Changes Incompatible changes can arise as a side-effect of either Enhancements or Bug Fixes. During Enhancements, incompatible changes can occur because, as an example, in order to support showing end-users new data, the database schema may need to be changed and the index rebuilt from scratch. During bug fixes, incompatible changes can occur because in order to fix a bug, the schema had to change, or how certain internal APIs are called changed. @@ -45,7 +44,7 @@ Incompatible changes can arise as a side-effect of either Enhancements or Bug Fi **NOTE**: A database reset and re-index is required ``` -### Pull Request +## Pull Request There is a [PULL_REQUEST_TEMPLATE.md](PULL_REQUEST_TEMPLATE.md) for this repository, but since it can't fill in the title for you, please follow the following steps when opening a Pull Request before filling in the template: diff --git a/PULL_REQUEST_TEMPLATE.md b/PULL_REQUEST_TEMPLATE.md index 001deecbdfeb..6e15223f201f 100644 --- a/PULL_REQUEST_TEMPLATE.md +++ b/PULL_REQUEST_TEMPLATE.md @@ -21,9 +21,9 @@ ## Checklist for your Pull Request (PR) - - [ ] I added an entry to `CHANGELOG.md` with this PR - [ ] If I added new functionality, I added tests covering it. - [ ] If I fixed a bug, I added a regression test to prevent the bug from silently reappearing again. - [ ] I checked whether I should update the docs and did so by submitting a PR to https://github.com/blockscout/docs - [ ] If I added/changed/removed ENV var, I submitted a PR to https://github.com/blockscout/docs to update the list of env vars at https://github.com/blockscout/docs/blob/master/for-developers/information-and-settings/env-variables.md and I updated the version to `master` in the Version column. Changes will be reflected in this table: https://docs.blockscout.com/for-developers/information-and-settings/env-variables. - - [ ] If I add new indices into DB, I checked, that they are not redundant with PGHero or other tools + - [ ] If I added new DB indices, I checked, that they are not redundant with PGHero or other tools. + - [ ] If I added/removed chain type, I modified the Github CI matrix and PR labels accordingly. diff --git a/apps/block_scout_web/assets/package-lock.json b/apps/block_scout_web/assets/package-lock.json index 615db5ef19c3..9dad321ad147 100644 --- a/apps/block_scout_web/assets/package-lock.json +++ b/apps/block_scout_web/assets/package-lock.json @@ -7,17 +7,17 @@ "name": "blockscout", "license": "GPL-3.0", "dependencies": { - "@amplitude/analytics-browser": "^2.4.1", + "@amplitude/analytics-browser": "^2.6.1", "@fortawesome/fontawesome-free": "^6.5.1", "@tarekraafat/autocomplete.js": "^10.2.7", "@walletconnect/web3-provider": "^1.8.0", "assert": "^2.1.0", "bignumber.js": "^9.1.2", "bootstrap": "^4.6.0", - "chart.js": "^4.4.1", + "chart.js": "^4.4.2", "chartjs-adapter-luxon": "^1.3.1", "clipboard": "^2.0.11", - "core-js": "^3.36.0", + "core-js": "^3.36.1", "crypto-browserify": "^3.12.0", "dropzone": "^5.9.3", "eth-net-props": "^1.0.41", @@ -61,24 +61,24 @@ "redux": "^5.0.1", "stream-browserify": "^3.0.0", "stream-http": "^3.1.1", - "sweetalert2": "^11.10.5", + "sweetalert2": "^11.10.7", "urijs": "^1.19.11", "url": "^0.11.3", "util": "^0.12.5", "viewerjs": "^1.11.6", "web3": "^1.10.4", "web3modal": "^1.9.12", - "xss": "^1.0.14" + "xss": "^1.0.15" }, "devDependencies": { - "@babel/core": "^7.23.9", - "@babel/preset-env": "^7.23.9", - "autoprefixer": "^10.4.17", + "@babel/core": "^7.24.3", + "@babel/preset-env": "^7.24.3", + "autoprefixer": "^10.4.19", "babel-loader": "^9.1.3", "copy-webpack-plugin": "^12.0.2", "css-loader": "^6.10.0", "css-minimizer-webpack-plugin": "^6.0.0", - "eslint": "^8.56.0", + "eslint": "^8.57.0", "eslint-config-standard": "^17.1.0", "eslint-plugin-import": "^2.29.1", "eslint-plugin-node": "^11.1.0", @@ -86,13 +86,13 @@ "file-loader": "^6.2.0", "jest": "^29.7.0", "jest-environment-jsdom": "^29.7.0", - "mini-css-extract-plugin": "^2.8.0", - "postcss": "^8.4.35", - "postcss-loader": "^8.1.0", - "sass": "^1.71.0", + "mini-css-extract-plugin": "^2.8.1", + "postcss": "^8.4.38", + "postcss-loader": "^8.1.1", + "sass": "^1.72.0", "sass-loader": "^14.1.1", "style-loader": "^3.3.4", - "webpack": "^5.90.3", + "webpack": "^5.91.0", "webpack-cli": "^5.1.4" }, "engines": { @@ -116,15 +116,15 @@ } }, "node_modules/@amplitude/analytics-browser": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@amplitude/analytics-browser/-/analytics-browser-2.4.1.tgz", - "integrity": "sha512-sxudfDAOZcyTJOHUc66uAHgZbZY9PORh4CAX4V66ozW+0vneeYPJm3ECCJqIrdJ/JWceOe/ohCT8G06X9s/4yg==", - "dependencies": { - "@amplitude/analytics-client-common": "^2.0.11", - "@amplitude/analytics-core": "^2.2.0", - "@amplitude/analytics-types": "^2.4.0", - "@amplitude/plugin-page-view-tracking-browser": "^2.1.1", - "@amplitude/plugin-web-attribution-browser": "^2.1.1", + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/@amplitude/analytics-browser/-/analytics-browser-2.6.1.tgz", + "integrity": "sha512-mGHPW5gGbYJhJOskYd9t4TPpf8v5jkDB2ndCmWipSm/OXHVCcQucRGUrJdmQIRrW+5aB4ertYCK0t2m/yzj2zw==", + "dependencies": { + "@amplitude/analytics-client-common": "^2.1.2", + "@amplitude/analytics-core": "^2.2.3", + "@amplitude/analytics-types": "^2.5.0", + "@amplitude/plugin-page-view-tracking-browser": "^2.2.5", + "@amplitude/plugin-web-attribution-browser": "^2.1.6", "tslib": "^2.4.1" } }, @@ -134,13 +134,13 @@ "integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==" }, "node_modules/@amplitude/analytics-client-common": { - "version": "2.0.11", - "resolved": "https://registry.npmjs.org/@amplitude/analytics-client-common/-/analytics-client-common-2.0.11.tgz", - "integrity": "sha512-f2zzo7Sk1hz8/WT7kPB6HZqAyHJrxMzw9nTqbLoRsaG9xm4YOJ0WCwtlu42RVRqIoWR89RTmIkqIjqimqMaHEQ==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@amplitude/analytics-client-common/-/analytics-client-common-2.1.2.tgz", + "integrity": "sha512-ekDMrXk7G15NPUGGcyB2x8WtBnzR6jRPRgW4vRToed7e3PVGzIWRSVyO9ymJZepQ+TCZ3ChlsBS1YonuTE0r2Q==", "dependencies": { "@amplitude/analytics-connector": "^1.4.8", - "@amplitude/analytics-core": "^2.2.0", - "@amplitude/analytics-types": "^2.4.0", + "@amplitude/analytics-core": "^2.2.3", + "@amplitude/analytics-types": "^2.5.0", "tslib": "^2.4.1" } }, @@ -155,11 +155,11 @@ "integrity": "sha512-T8mOYzB9RRxckzhL0NTHwdge9xuFxXEOplC8B1Y3UX3NHa3BLh7DlBUZlCOwQgMc2nxDfnSweDL5S3bhC+W90g==" }, "node_modules/@amplitude/analytics-core": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@amplitude/analytics-core/-/analytics-core-2.2.0.tgz", - "integrity": "sha512-JVx1chKa/sfqpBNEZn6jaZZV3DW/6cOoJxx8b5oqHIn+5HXizEOV85aLFY0rrtZ/uR/HrdffxrMKzr/uBFlV+A==", + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/@amplitude/analytics-core/-/analytics-core-2.2.3.tgz", + "integrity": "sha512-rtA7TSqie6Jgcvax3tEHaZUzOJM5Hdd5/+JYFIJK2gPgHsWZj3jDF75fL8BSn4uBiA2zcZ0vbCHORMVqXg5pRw==", "dependencies": { - "@amplitude/analytics-types": "^2.4.0", + "@amplitude/analytics-types": "^2.5.0", "tslib": "^2.4.1" } }, @@ -169,17 +169,17 @@ "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" }, "node_modules/@amplitude/analytics-types": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/@amplitude/analytics-types/-/analytics-types-2.4.0.tgz", - "integrity": "sha512-GVj9W4X3XMVyGfqXdES2vFU8pqTIHvihj/vNOjOrwYHVdia3GjlcGl77GXuERCIwr52MoiUVTGXmXn3adf+A+Q==" + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@amplitude/analytics-types/-/analytics-types-2.5.0.tgz", + "integrity": "sha512-aY69WxUvVlaCU+9geShjTsAYdUTvegEXH9i4WK/97kNbNLl4/7qUuIPe4hNireDeKLuQA9SA3H7TKynuNomDxw==" }, "node_modules/@amplitude/plugin-page-view-tracking-browser": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/@amplitude/plugin-page-view-tracking-browser/-/plugin-page-view-tracking-browser-2.1.1.tgz", - "integrity": "sha512-dZwA0kb/dvFTokF2yVklfjwl0Ben6g6Sukpr84tocpurJ7Ojhh1egISCZ4QWt2VgKKh7X4pyK73f5Fcp/1JcNw==", + "version": "2.2.5", + "resolved": "https://registry.npmjs.org/@amplitude/plugin-page-view-tracking-browser/-/plugin-page-view-tracking-browser-2.2.5.tgz", + "integrity": "sha512-uhX1bP57DrvkV3KYWR0NwyTTSBXU3m+LbwBm/0vm4YRLLM1I8dEle+Wb3mN3inbIYOOVyEd3ARR+NS8Xf/hEeQ==", "dependencies": { - "@amplitude/analytics-client-common": "^2.0.11", - "@amplitude/analytics-types": "^2.4.0", + "@amplitude/analytics-client-common": "^2.1.2", + "@amplitude/analytics-types": "^2.5.0", "tslib": "^2.4.1" } }, @@ -189,13 +189,13 @@ "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" }, "node_modules/@amplitude/plugin-web-attribution-browser": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/@amplitude/plugin-web-attribution-browser/-/plugin-web-attribution-browser-2.1.1.tgz", - "integrity": "sha512-paWFk+uJeVlUF/HYNoczIxP3IJX/KR573B/E4Wp5bLB3XeJIhRbj3RQdJKhnKN5keg8+Vei/8uGdGQK4d3DYDg==", + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/@amplitude/plugin-web-attribution-browser/-/plugin-web-attribution-browser-2.1.6.tgz", + "integrity": "sha512-3Nds/vfLTBXFi5rLOUF78TL2OkzBAXzJuslSFfSHl7C8psGcpkWTnWcxPakfLHuev3yteknCkWaevdio+GMljg==", "dependencies": { - "@amplitude/analytics-client-common": "^2.0.11", - "@amplitude/analytics-core": "^2.2.0", - "@amplitude/analytics-types": "^2.4.0", + "@amplitude/analytics-client-common": "^2.1.2", + "@amplitude/analytics-core": "^2.2.3", + "@amplitude/analytics-types": "^2.5.0", "tslib": "^2.4.1" } }, @@ -229,40 +229,40 @@ } }, "node_modules/@babel/code-frame": { - "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.5.tgz", - "integrity": "sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==", + "version": "7.24.2", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.2.tgz", + "integrity": "sha512-y5+tLQyV8pg3fsiln67BVLD1P13Eg4lh5RW9mF0zUuvLrv9uIQ4MCL+CRT+FTsBlBjcIan6PGsLcBN0m3ClUyQ==", "dependencies": { - "@babel/highlight": "^7.23.4", - "chalk": "^2.4.2" + "@babel/highlight": "^7.24.2", + "picocolors": "^1.0.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/compat-data": { - "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.23.5.tgz", - "integrity": "sha512-uU27kfDRlhfKl+w1U6vp16IuvSLtjAxdArVXPa9BvLkrr7CYIsxH5adpHObeAGY/41+syctUWOZ140a2Rvkgjw==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.24.1.tgz", + "integrity": "sha512-Pc65opHDliVpRHuKfzI+gSA4zcgr65O4cl64fFJIWEEh8JoHIHh0Oez1Eo8Arz8zq/JhgKodQaxEwUPRtZylVA==", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/core": { - "version": "7.23.9", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.23.9.tgz", - "integrity": "sha512-5q0175NOjddqpvvzU+kDiSOAk4PfdO6FvwCWoQ6RO7rTzEe8vlo+4HVfcnAREhD4npMs0e9uZypjTwzZPCf/cw==", + "version": "7.24.3", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.24.3.tgz", + "integrity": "sha512-5FcvN1JHw2sHJChotgx8Ek0lyuh4kCKelgMTTqhYJJtloNvUfpAFMeNQUtdlIaktwrSV9LtCdqwk48wL2wBacQ==", "dependencies": { "@ampproject/remapping": "^2.2.0", - "@babel/code-frame": "^7.23.5", - "@babel/generator": "^7.23.6", + "@babel/code-frame": "^7.24.2", + "@babel/generator": "^7.24.1", "@babel/helper-compilation-targets": "^7.23.6", "@babel/helper-module-transforms": "^7.23.3", - "@babel/helpers": "^7.23.9", - "@babel/parser": "^7.23.9", - "@babel/template": "^7.23.9", - "@babel/traverse": "^7.23.9", - "@babel/types": "^7.23.9", + "@babel/helpers": "^7.24.1", + "@babel/parser": "^7.24.1", + "@babel/template": "^7.24.0", + "@babel/traverse": "^7.24.1", + "@babel/types": "^7.24.0", "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", @@ -283,13 +283,13 @@ "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==" }, "node_modules/@babel/generator": { - "version": "7.23.6", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.6.tgz", - "integrity": "sha512-qrSfCYxYQB5owCmGLbl8XRpX1ytXlpueOb0N0UmQwA073KZxejgQTzAmJezxvpwQD9uGtK2shHdi55QT+MbjIw==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.24.1.tgz", + "integrity": "sha512-DfCRfZsBcrPEHUfuBMgbJ1Ut01Y/itOs+hY2nFLgqsqXd52/iSiVq5TITtUasIUgm+IIKdY2/1I7auiQOEeC9A==", "dependencies": { - "@babel/types": "^7.23.6", - "@jridgewell/gen-mapping": "^0.3.2", - "@jridgewell/trace-mapping": "^0.3.17", + "@babel/types": "^7.24.0", + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25", "jsesc": "^2.5.1" }, "engines": { @@ -348,17 +348,17 @@ "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" }, "node_modules/@babel/helper-create-class-features-plugin": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.22.15.tgz", - "integrity": "sha512-jKkwA59IXcvSaiK2UN45kKwSC9o+KuoXsBDvHvU/7BecYIp8GQ2UwrVvFgJASUT+hBnwJx6MhvMCuMzwZZ7jlg==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.24.1.tgz", + "integrity": "sha512-1yJa9dX9g//V6fDebXoEfEsxkZHk3Hcbm+zLhyu6qVgYFLvmTALTeV+jNU9e5RnYtioBrGEOdoI2joMSNQ/+aA==", "dev": true, "dependencies": { "@babel/helper-annotate-as-pure": "^7.22.5", - "@babel/helper-environment-visitor": "^7.22.5", - "@babel/helper-function-name": "^7.22.5", - "@babel/helper-member-expression-to-functions": "^7.22.15", + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-function-name": "^7.23.0", + "@babel/helper-member-expression-to-functions": "^7.23.0", "@babel/helper-optimise-call-expression": "^7.22.5", - "@babel/helper-replace-supers": "^7.22.9", + "@babel/helper-replace-supers": "^7.24.1", "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", "@babel/helper-split-export-declaration": "^7.22.6", "semver": "^6.3.1" @@ -447,11 +447,11 @@ } }, "node_modules/@babel/helper-module-imports": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.22.15.tgz", - "integrity": "sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==", + "version": "7.24.3", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.24.3.tgz", + "integrity": "sha512-viKb0F9f2s0BCS22QSF308z/+1YWKV/76mwt61NBzS5izMzDPwdq1pTrzf+Li3npBWX9KdQbkeCt1jSAM7lZqg==", "dependencies": { - "@babel/types": "^7.22.15" + "@babel/types": "^7.24.0" }, "engines": { "node": ">=6.9.0" @@ -488,9 +488,9 @@ } }, "node_modules/@babel/helper-plugin-utils": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz", - "integrity": "sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg==", + "version": "7.24.0", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.0.tgz", + "integrity": "sha512-9cUznXMG0+FxRuJfvL82QlTqIzhVW9sL0KjMPHhAOOvpQGL8QtdxnBKILjBqxlHyliz0yCa1G903ZXI/FuHy2w==", "engines": { "node": ">=6.9.0" } @@ -513,13 +513,13 @@ } }, "node_modules/@babel/helper-replace-supers": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.22.20.tgz", - "integrity": "sha512-qsW0In3dbwQUbK8kejJ4R7IHVGwHJlV6lpG6UA7a9hSa2YEiAib+N1T2kr6PEeUT+Fl7najmSOS6SmAwCHK6Tw==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.24.1.tgz", + "integrity": "sha512-QCR1UqC9BzG5vZl8BMicmZ28RuUBnHhAMddD8yHFHDRH9lLTZ9uUPehX8ctVPT8l0TKblJidqcgUUKGVrePleQ==", "dev": true, "dependencies": { "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-member-expression-to-functions": "^7.22.15", + "@babel/helper-member-expression-to-functions": "^7.23.0", "@babel/helper-optimise-call-expression": "^7.22.5" }, "engines": { @@ -602,35 +602,36 @@ } }, "node_modules/@babel/helpers": { - "version": "7.23.9", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.23.9.tgz", - "integrity": "sha512-87ICKgU5t5SzOT7sBMfCOZQ2rHjRU+Pcb9BoILMYz600W6DkVRLFBPwQ18gwUVvggqXivaUakpnxWQGbpywbBQ==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.24.1.tgz", + "integrity": "sha512-BpU09QqEe6ZCHuIHFphEFgvNSrubve1FtyMton26ekZ85gRGi6LrTF7zArARp2YvyFxloeiRmtSCq5sjh1WqIg==", "dependencies": { - "@babel/template": "^7.23.9", - "@babel/traverse": "^7.23.9", - "@babel/types": "^7.23.9" + "@babel/template": "^7.24.0", + "@babel/traverse": "^7.24.1", + "@babel/types": "^7.24.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/highlight": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.23.4.tgz", - "integrity": "sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==", + "version": "7.24.2", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.2.tgz", + "integrity": "sha512-Yac1ao4flkTxTteCDZLEvdxg2fZfz1v8M4QpaGypq/WPDqg3ijHYbDfs+LG5hvzSoqaSZ9/Z9lKSP3CjZjv+pA==", "dependencies": { "@babel/helper-validator-identifier": "^7.22.20", "chalk": "^2.4.2", - "js-tokens": "^4.0.0" + "js-tokens": "^4.0.0", + "picocolors": "^1.0.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/parser": { - "version": "7.23.9", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.9.tgz", - "integrity": "sha512-9tcKgqKbs3xGJ+NtKF2ndOBBLVwPjl1SHxPQkd36r3Dlirw3xWUeGaTbqr7uGZcTaxkVNwc+03SVP7aCdWrTlA==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.1.tgz", + "integrity": "sha512-Zo9c7N3xdOIQrNip7Lc9wvRPzlRtovHVE4lkz8WEDr7uYh/GMQhSiIgFxGIArRHYdJE5kxtZjAf8rT0xhdLCzg==", "bin": { "parser": "bin/babel-parser.js" }, @@ -639,12 +640,12 @@ } }, "node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.23.3.tgz", - "integrity": "sha512-iRkKcCqb7iGnq9+3G6rZ+Ciz5VywC4XNRHe57lKM+jOeYAoR0lVqdeeDRfh0tQcTfw/+vBhHn926FmQhLtlFLQ==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.24.1.tgz", + "integrity": "sha512-y4HqEnkelJIOQGd+3g1bTeKsA5c6qM7eOn7VggGVbBc0y8MLSKHacwcIE2PplNlQSj0PqS9rrXL/nkPVK+kUNg==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.24.0" }, "engines": { "node": ">=6.9.0" @@ -654,14 +655,14 @@ } }, "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.23.3.tgz", - "integrity": "sha512-WwlxbfMNdVEpQjZmK5mhm7oSwD3dS6eU+Iwsi4Knl9wAletWem7kaRsGOG+8UEbRyqxY4SS5zvtfXwX+jMxUwQ==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.24.1.tgz", + "integrity": "sha512-Hj791Ii4ci8HqnaKHAlLNs+zaLXb0EzSDhiAWp5VNlyvCNymYfacs64pxTxbH1znW/NcArSmwpmG9IKE/TUVVQ==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-plugin-utils": "^7.24.0", "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", - "@babel/plugin-transform-optional-chaining": "^7.23.3" + "@babel/plugin-transform-optional-chaining": "^7.24.1" }, "engines": { "node": ">=6.9.0" @@ -671,13 +672,13 @@ } }, "node_modules/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": { - "version": "7.23.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.23.7.tgz", - "integrity": "sha512-LlRT7HgaifEpQA1ZgLVOIJZZFVPWN5iReq/7/JixwBtwcoeVGDBD53ZV28rrsLYOZs1Y/EHhA8N/Z6aazHR8cw==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.24.1.tgz", + "integrity": "sha512-m9m/fXsXLiHfwdgydIFnpk+7jlVbnvlK5B2EKiPdLUb6WX654ZaaEWJUjk8TftRbZpK0XibovlLWX4KIZhV6jw==", "dev": true, "dependencies": { "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.24.0" }, "engines": { "node": ">=6.9.0" @@ -774,12 +775,12 @@ } }, "node_modules/@babel/plugin-syntax-import-assertions": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.23.3.tgz", - "integrity": "sha512-lPgDSU+SJLK3xmFDTV2ZRQAiM7UuUjGidwBywFavObCiZc1BeAAcMtHJKUya92hPHO+at63JJPLygilZard8jw==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.24.1.tgz", + "integrity": "sha512-IuwnI5XnuF189t91XbxmXeCDz3qs6iDRO7GJ++wcfgeXNs/8FmIlKcpDSXNVyuLQxlwvskmI3Ct73wUODkJBlQ==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.24.0" }, "engines": { "node": ">=6.9.0" @@ -789,12 +790,12 @@ } }, "node_modules/@babel/plugin-syntax-import-attributes": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.23.3.tgz", - "integrity": "sha512-pawnE0P9g10xgoP7yKr6CK63K2FMsTE+FZidZO/1PwRdzmAPVs+HS1mAURUsgaoxammTJvULUdIkEK0gOcU2tA==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.24.1.tgz", + "integrity": "sha512-zhQTMH0X2nVLnb04tz+s7AMuasX8U0FnpE+nHTOhSOINjWMnopoZTxtIKsd45n4GQ/HIZLyfIpoul8e2m0DnRA==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.24.0" }, "engines": { "node": ">=6.9.0" @@ -976,12 +977,12 @@ } }, "node_modules/@babel/plugin-transform-arrow-functions": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.23.3.tgz", - "integrity": "sha512-NzQcQrzaQPkaEwoTm4Mhyl8jI1huEL/WWIEvudjTCMJ9aBZNpsJbMASx7EQECtQQPS/DcnFpo0FIh3LvEO9cxQ==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.24.1.tgz", + "integrity": "sha512-ngT/3NkRhsaep9ck9uj2Xhv9+xB1zShY3tM3g6om4xxCELwCDN4g4Aq5dRn48+0hasAql7s2hdBOysCfNpr4fw==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.24.0" }, "engines": { "node": ">=6.9.0" @@ -991,13 +992,13 @@ } }, "node_modules/@babel/plugin-transform-async-generator-functions": { - "version": "7.23.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.23.9.tgz", - "integrity": "sha512-8Q3veQEDGe14dTYuwagbRtwxQDnytyg1JFu4/HwEMETeofocrB0U0ejBJIXoeG/t2oXZ8kzCyI0ZZfbT80VFNQ==", + "version": "7.24.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.24.3.tgz", + "integrity": "sha512-Qe26CMYVjpQxJ8zxM1340JFNjZaF+ISWpr1Kt/jGo+ZTUzKkfw/pphEWbRCb+lmSM6k/TOgfYLvmbHkUQ0asIg==", "dev": true, "dependencies": { "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-plugin-utils": "^7.24.0", "@babel/helper-remap-async-to-generator": "^7.22.20", "@babel/plugin-syntax-async-generators": "^7.8.4" }, @@ -1009,13 +1010,13 @@ } }, "node_modules/@babel/plugin-transform-async-to-generator": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.23.3.tgz", - "integrity": "sha512-A7LFsKi4U4fomjqXJlZg/u0ft/n8/7n7lpffUP/ZULx/DtV9SGlNKZolHH6PE8Xl1ngCc0M11OaeZptXVkfKSw==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.24.1.tgz", + "integrity": "sha512-AawPptitRXp1y0n4ilKcGbRYWfbbzFWz2NqNu7dacYDtFtz0CMjG64b3LQsb3KIgnf4/obcUL78hfaOS7iCUfw==", "dev": true, "dependencies": { - "@babel/helper-module-imports": "^7.22.15", - "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-module-imports": "^7.24.1", + "@babel/helper-plugin-utils": "^7.24.0", "@babel/helper-remap-async-to-generator": "^7.22.20" }, "engines": { @@ -1026,12 +1027,12 @@ } }, "node_modules/@babel/plugin-transform-block-scoped-functions": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.23.3.tgz", - "integrity": "sha512-vI+0sIaPIO6CNuM9Kk5VmXcMVRiOpDh7w2zZt9GXzmE/9KD70CUEVhvPR/etAeNK/FAEkhxQtXOzVF3EuRL41A==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.24.1.tgz", + "integrity": "sha512-TWWC18OShZutrv9C6mye1xwtam+uNi2bnTOCBUd5sZxyHOiWbU6ztSROofIMrK84uweEZC219POICK/sTYwfgg==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.24.0" }, "engines": { "node": ">=6.9.0" @@ -1041,12 +1042,12 @@ } }, "node_modules/@babel/plugin-transform-block-scoping": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.23.4.tgz", - "integrity": "sha512-0QqbP6B6HOh7/8iNR4CQU2Th/bbRtBp4KS9vcaZd1fZ0wSh5Fyssg0UCIHwxh+ka+pNDREbVLQnHCMHKZfPwfw==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.24.1.tgz", + "integrity": "sha512-h71T2QQvDgM2SmT29UYU6ozjMlAt7s7CSs5Hvy8f8cf/GM/Z4a2zMfN+fjVGaieeCrXR3EdQl6C4gQG+OgmbKw==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.24.0" }, "engines": { "node": ">=6.9.0" @@ -1056,13 +1057,13 @@ } }, "node_modules/@babel/plugin-transform-class-properties": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.23.3.tgz", - "integrity": "sha512-uM+AN8yCIjDPccsKGlw271xjJtGii+xQIF/uMPS8H15L12jZTsLfF4o5vNO7d/oUguOyfdikHGc/yi9ge4SGIg==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.24.1.tgz", + "integrity": "sha512-OMLCXi0NqvJfORTaPQBwqLXHhb93wkBKZ4aNwMl6WtehO7ar+cmp+89iPEQPqxAnxsOKTaMcs3POz3rKayJ72g==", "dev": true, "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.22.15", - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-create-class-features-plugin": "^7.24.1", + "@babel/helper-plugin-utils": "^7.24.0" }, "engines": { "node": ">=6.9.0" @@ -1072,13 +1073,13 @@ } }, "node_modules/@babel/plugin-transform-class-static-block": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.23.4.tgz", - "integrity": "sha512-nsWu/1M+ggti1SOALj3hfx5FXzAY06fwPJsUZD4/A5e1bWi46VUIWtD+kOX6/IdhXGsXBWllLFDSnqSCdUNydQ==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.24.1.tgz", + "integrity": "sha512-FUHlKCn6J3ERiu8Dv+4eoz7w8+kFLSyeVG4vDAikwADGjUCoHw/JHokyGtr8OR4UjpwPVivyF+h8Q5iv/JmrtA==", "dev": true, "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.22.15", - "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-create-class-features-plugin": "^7.24.1", + "@babel/helper-plugin-utils": "^7.24.0", "@babel/plugin-syntax-class-static-block": "^7.14.5" }, "engines": { @@ -1089,17 +1090,17 @@ } }, "node_modules/@babel/plugin-transform-classes": { - "version": "7.23.8", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.23.8.tgz", - "integrity": "sha512-yAYslGsY1bX6Knmg46RjiCiNSwJKv2IUC8qOdYKqMMr0491SXFhcHqOdRDeCRohOOIzwN/90C6mQ9qAKgrP7dg==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.24.1.tgz", + "integrity": "sha512-ZTIe3W7UejJd3/3R4p7ScyyOoafetUShSf4kCqV0O7F/RiHxVj/wRaRnQlrGwflvcehNA8M42HkAiEDYZu2F1Q==", "dev": true, "dependencies": { "@babel/helper-annotate-as-pure": "^7.22.5", "@babel/helper-compilation-targets": "^7.23.6", "@babel/helper-environment-visitor": "^7.22.20", "@babel/helper-function-name": "^7.23.0", - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/helper-replace-supers": "^7.22.20", + "@babel/helper-plugin-utils": "^7.24.0", + "@babel/helper-replace-supers": "^7.24.1", "@babel/helper-split-export-declaration": "^7.22.6", "globals": "^11.1.0" }, @@ -1111,13 +1112,13 @@ } }, "node_modules/@babel/plugin-transform-computed-properties": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.23.3.tgz", - "integrity": "sha512-dTj83UVTLw/+nbiHqQSFdwO9CbTtwq1DsDqm3CUEtDrZNET5rT5E6bIdTlOftDTDLMYxvxHNEYO4B9SLl8SLZw==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.24.1.tgz", + "integrity": "sha512-5pJGVIUfJpOS+pAqBQd+QMaTD2vCL/HcePooON6pDpHgRp4gNRmzyHTPIkXntwKsq3ayUFVfJaIKPw2pOkOcTw==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/template": "^7.22.15" + "@babel/helper-plugin-utils": "^7.24.0", + "@babel/template": "^7.24.0" }, "engines": { "node": ">=6.9.0" @@ -1127,12 +1128,12 @@ } }, "node_modules/@babel/plugin-transform-destructuring": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.23.3.tgz", - "integrity": "sha512-n225npDqjDIr967cMScVKHXJs7rout1q+tt50inyBCPkyZ8KxeI6d+GIbSBTT/w/9WdlWDOej3V9HE5Lgk57gw==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.24.1.tgz", + "integrity": "sha512-ow8jciWqNxR3RYbSNVuF4U2Jx130nwnBnhRw6N6h1bOejNkABmcI5X5oz29K4alWX7vf1C+o6gtKXikzRKkVdw==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.24.0" }, "engines": { "node": ">=6.9.0" @@ -1142,13 +1143,13 @@ } }, "node_modules/@babel/plugin-transform-dotall-regex": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.23.3.tgz", - "integrity": "sha512-vgnFYDHAKzFaTVp+mneDsIEbnJ2Np/9ng9iviHw3P/KVcgONxpNULEW/51Z/BaFojG2GI2GwwXck5uV1+1NOYQ==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.24.1.tgz", + "integrity": "sha512-p7uUxgSoZwZ2lPNMzUkqCts3xlp8n+o05ikjy7gbtFJSt9gdU88jAmtfmOxHM14noQXBxfgzf2yRWECiNVhTCw==", "dev": true, "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.22.15", - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.24.0" }, "engines": { "node": ">=6.9.0" @@ -1158,12 +1159,12 @@ } }, "node_modules/@babel/plugin-transform-duplicate-keys": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.23.3.tgz", - "integrity": "sha512-RrqQ+BQmU3Oyav3J+7/myfvRCq7Tbz+kKLLshUmMwNlDHExbGL7ARhajvoBJEvc+fCguPPu887N+3RRXBVKZUA==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.24.1.tgz", + "integrity": "sha512-msyzuUnvsjsaSaocV6L7ErfNsa5nDWL1XKNnDePLgmz+WdU4w/J8+AxBMrWfi9m4IxfL5sZQKUPQKDQeeAT6lA==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.24.0" }, "engines": { "node": ">=6.9.0" @@ -1173,12 +1174,12 @@ } }, "node_modules/@babel/plugin-transform-dynamic-import": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.23.4.tgz", - "integrity": "sha512-V6jIbLhdJK86MaLh4Jpghi8ho5fGzt3imHOBu/x0jlBaPYqDoWz4RDXjmMOfnh+JWNaQleEAByZLV0QzBT4YQQ==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.24.1.tgz", + "integrity": "sha512-av2gdSTyXcJVdI+8aFZsCAtR29xJt0S5tas+Ef8NvBNmD1a+N/3ecMLeMBgfcK+xzsjdLDT6oHt+DFPyeqUbDA==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-plugin-utils": "^7.24.0", "@babel/plugin-syntax-dynamic-import": "^7.8.3" }, "engines": { @@ -1189,13 +1190,13 @@ } }, "node_modules/@babel/plugin-transform-exponentiation-operator": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.23.3.tgz", - "integrity": "sha512-5fhCsl1odX96u7ILKHBj4/Y8vipoqwsJMh4csSA8qFfxrZDEA4Ssku2DyNvMJSmZNOEBT750LfFPbtrnTP90BQ==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.24.1.tgz", + "integrity": "sha512-U1yX13dVBSwS23DEAqU+Z/PkwE9/m7QQy8Y9/+Tdb8UWYaGNDYwTLi19wqIAiROr8sXVum9A/rtiH5H0boUcTw==", "dev": true, "dependencies": { "@babel/helper-builder-binary-assignment-operator-visitor": "^7.22.15", - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.24.0" }, "engines": { "node": ">=6.9.0" @@ -1205,12 +1206,12 @@ } }, "node_modules/@babel/plugin-transform-export-namespace-from": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.23.4.tgz", - "integrity": "sha512-GzuSBcKkx62dGzZI1WVgTWvkkz84FZO5TC5T8dl/Tht/rAla6Dg/Mz9Yhypg+ezVACf/rgDuQt3kbWEv7LdUDQ==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.24.1.tgz", + "integrity": "sha512-Ft38m/KFOyzKw2UaJFkWG9QnHPG/Q/2SkOrRk4pNBPg5IPZ+dOxcmkK5IyuBcxiNPyyYowPGUReyBvrvZs7IlQ==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-plugin-utils": "^7.24.0", "@babel/plugin-syntax-export-namespace-from": "^7.8.3" }, "engines": { @@ -1221,12 +1222,12 @@ } }, "node_modules/@babel/plugin-transform-for-of": { - "version": "7.23.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.23.6.tgz", - "integrity": "sha512-aYH4ytZ0qSuBbpfhuofbg/e96oQ7U2w1Aw/UQmKT+1l39uEhUPoFS3fHevDc1G0OvewyDudfMKY1OulczHzWIw==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.24.1.tgz", + "integrity": "sha512-OxBdcnF04bpdQdR3i4giHZNZQn7cm8RQKcSwA17wAAqEELo1ZOwp5FFgeptWUQXFyT9kwHo10aqqauYkRZPCAg==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-plugin-utils": "^7.24.0", "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5" }, "engines": { @@ -1237,14 +1238,14 @@ } }, "node_modules/@babel/plugin-transform-function-name": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.23.3.tgz", - "integrity": "sha512-I1QXp1LxIvt8yLaib49dRW5Okt7Q4oaxao6tFVKS/anCdEOMtYwWVKoiOA1p34GOWIZjUK0E+zCp7+l1pfQyiw==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.24.1.tgz", + "integrity": "sha512-BXmDZpPlh7jwicKArQASrj8n22/w6iymRnvHYYd2zO30DbE277JO20/7yXJT3QxDPtiQiOxQBbZH4TpivNXIxA==", "dev": true, "dependencies": { - "@babel/helper-compilation-targets": "^7.22.15", + "@babel/helper-compilation-targets": "^7.23.6", "@babel/helper-function-name": "^7.23.0", - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.24.0" }, "engines": { "node": ">=6.9.0" @@ -1254,12 +1255,12 @@ } }, "node_modules/@babel/plugin-transform-json-strings": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.23.4.tgz", - "integrity": "sha512-81nTOqM1dMwZ/aRXQ59zVubN9wHGqk6UtqRK+/q+ciXmRy8fSolhGVvG09HHRGo4l6fr/c4ZhXUQH0uFW7PZbg==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.24.1.tgz", + "integrity": "sha512-U7RMFmRvoasscrIFy5xA4gIp8iWnWubnKkKuUGJjsuOH7GfbMkB+XZzeslx2kLdEGdOJDamEmCqOks6e8nv8DQ==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-plugin-utils": "^7.24.0", "@babel/plugin-syntax-json-strings": "^7.8.3" }, "engines": { @@ -1270,12 +1271,12 @@ } }, "node_modules/@babel/plugin-transform-literals": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.23.3.tgz", - "integrity": "sha512-wZ0PIXRxnwZvl9AYpqNUxpZ5BiTGrYt7kueGQ+N5FiQ7RCOD4cm8iShd6S6ggfVIWaJf2EMk8eRzAh52RfP4rQ==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.24.1.tgz", + "integrity": "sha512-zn9pwz8U7nCqOYIiBaOxoQOtYmMODXTJnkxG4AtX8fPmnCRYWBOHD0qcpwS9e2VDSp1zNJYpdnFMIKb8jmwu6g==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.24.0" }, "engines": { "node": ">=6.9.0" @@ -1285,12 +1286,12 @@ } }, "node_modules/@babel/plugin-transform-logical-assignment-operators": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.23.4.tgz", - "integrity": "sha512-Mc/ALf1rmZTP4JKKEhUwiORU+vcfarFVLfcFiolKUo6sewoxSEgl36ak5t+4WamRsNr6nzjZXQjM35WsU+9vbg==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.24.1.tgz", + "integrity": "sha512-OhN6J4Bpz+hIBqItTeWJujDOfNP+unqv/NJgyhlpSqgBTPm37KkMmZV6SYcOj+pnDbdcl1qRGV/ZiIjX9Iy34w==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-plugin-utils": "^7.24.0", "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" }, "engines": { @@ -1301,12 +1302,12 @@ } }, "node_modules/@babel/plugin-transform-member-expression-literals": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.23.3.tgz", - "integrity": "sha512-sC3LdDBDi5x96LA+Ytekz2ZPk8i/Ck+DEuDbRAll5rknJ5XRTSaPKEYwomLcs1AA8wg9b3KjIQRsnApj+q51Ag==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.24.1.tgz", + "integrity": "sha512-4ojai0KysTWXzHseJKa1XPNXKRbuUrhkOPY4rEGeR+7ChlJVKxFa3H3Bz+7tWaGKgJAXUWKOGmltN+u9B3+CVg==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.24.0" }, "engines": { "node": ">=6.9.0" @@ -1316,13 +1317,13 @@ } }, "node_modules/@babel/plugin-transform-modules-amd": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.23.3.tgz", - "integrity": "sha512-vJYQGxeKM4t8hYCKVBlZX/gtIY2I7mRGFNcm85sgXGMTBcoV3QdVtdpbcWEbzbfUIUZKwvgFT82mRvaQIebZzw==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.24.1.tgz", + "integrity": "sha512-lAxNHi4HVtjnHd5Rxg3D5t99Xm6H7b04hUS7EHIXcUl2EV4yl1gWdqZrNzXnSrHveL9qMdbODlLF55mvgjAfaQ==", "dev": true, "dependencies": { "@babel/helper-module-transforms": "^7.23.3", - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.24.0" }, "engines": { "node": ">=6.9.0" @@ -1332,13 +1333,13 @@ } }, "node_modules/@babel/plugin-transform-modules-commonjs": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.23.3.tgz", - "integrity": "sha512-aVS0F65LKsdNOtcz6FRCpE4OgsP2OFnW46qNxNIX9h3wuzaNcSQsJysuMwqSibC98HPrf2vCgtxKNwS0DAlgcA==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.24.1.tgz", + "integrity": "sha512-szog8fFTUxBfw0b98gEWPaEqF42ZUD/T3bkynW/wtgx2p/XCP55WEsb+VosKceRSd6njipdZvNogqdtI4Q0chw==", "dev": true, "dependencies": { "@babel/helper-module-transforms": "^7.23.3", - "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-plugin-utils": "^7.24.0", "@babel/helper-simple-access": "^7.22.5" }, "engines": { @@ -1349,14 +1350,14 @@ } }, "node_modules/@babel/plugin-transform-modules-systemjs": { - "version": "7.23.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.23.9.tgz", - "integrity": "sha512-KDlPRM6sLo4o1FkiSlXoAa8edLXFsKKIda779fbLrvmeuc3itnjCtaO6RrtoaANsIJANj+Vk1zqbZIMhkCAHVw==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.24.1.tgz", + "integrity": "sha512-mqQ3Zh9vFO1Tpmlt8QPnbwGHzNz3lpNEMxQb1kAemn/erstyqw1r9KeOlOfo3y6xAnFEcOv2tSyrXfmMk+/YZA==", "dev": true, "dependencies": { "@babel/helper-hoist-variables": "^7.22.5", "@babel/helper-module-transforms": "^7.23.3", - "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-plugin-utils": "^7.24.0", "@babel/helper-validator-identifier": "^7.22.20" }, "engines": { @@ -1367,13 +1368,13 @@ } }, "node_modules/@babel/plugin-transform-modules-umd": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.23.3.tgz", - "integrity": "sha512-zHsy9iXX2nIsCBFPud3jKn1IRPWg3Ing1qOZgeKV39m1ZgIdpJqvlWVeiHBZC6ITRG0MfskhYe9cLgntfSFPIg==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.24.1.tgz", + "integrity": "sha512-tuA3lpPj+5ITfcCluy6nWonSL7RvaG0AOTeAuvXqEKS34lnLzXpDb0dcP6K8jD0zWZFNDVly90AGFJPnm4fOYg==", "dev": true, "dependencies": { "@babel/helper-module-transforms": "^7.23.3", - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.24.0" }, "engines": { "node": ">=6.9.0" @@ -1399,12 +1400,12 @@ } }, "node_modules/@babel/plugin-transform-new-target": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.23.3.tgz", - "integrity": "sha512-YJ3xKqtJMAT5/TIZnpAR3I+K+WaDowYbN3xyxI8zxx/Gsypwf9B9h0VB+1Nh6ACAAPRS5NSRje0uVv5i79HYGQ==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.24.1.tgz", + "integrity": "sha512-/rurytBM34hYy0HKZQyA0nHbQgQNFm4Q/BOc9Hflxi2X3twRof7NaE5W46j4kQitm7SvACVRXsa6N/tSZxvPug==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.24.0" }, "engines": { "node": ">=6.9.0" @@ -1414,12 +1415,12 @@ } }, "node_modules/@babel/plugin-transform-nullish-coalescing-operator": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.23.4.tgz", - "integrity": "sha512-jHE9EVVqHKAQx+VePv5LLGHjmHSJR76vawFPTdlxR/LVJPfOEGxREQwQfjuZEOPTwG92X3LINSh3M40Rv4zpVA==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.24.1.tgz", + "integrity": "sha512-iQ+caew8wRrhCikO5DrUYx0mrmdhkaELgFa+7baMcVuhxIkN7oxt06CZ51D65ugIb1UWRQ8oQe+HXAVM6qHFjw==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-plugin-utils": "^7.24.0", "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" }, "engines": { @@ -1430,12 +1431,12 @@ } }, "node_modules/@babel/plugin-transform-numeric-separator": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.23.4.tgz", - "integrity": "sha512-mps6auzgwjRrwKEZA05cOwuDc9FAzoyFS4ZsG/8F43bTLf/TgkJg7QXOrPO1JO599iA3qgK9MXdMGOEC8O1h6Q==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.24.1.tgz", + "integrity": "sha512-7GAsGlK4cNL2OExJH1DzmDeKnRv/LXq0eLUSvudrehVA5Rgg4bIrqEUW29FbKMBRT0ztSqisv7kjP+XIC4ZMNw==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-plugin-utils": "^7.24.0", "@babel/plugin-syntax-numeric-separator": "^7.10.4" }, "engines": { @@ -1446,16 +1447,15 @@ } }, "node_modules/@babel/plugin-transform-object-rest-spread": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.23.4.tgz", - "integrity": "sha512-9x9K1YyeQVw0iOXJlIzwm8ltobIIv7j2iLyP2jIhEbqPRQ7ScNgwQufU2I0Gq11VjyG4gI4yMXt2VFags+1N3g==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.24.1.tgz", + "integrity": "sha512-XjD5f0YqOtebto4HGISLNfiNMTTs6tbkFf2TOqJlYKYmbo+mN9Dnpl4SRoofiziuOWMIyq3sZEUqLo3hLITFEA==", "dev": true, "dependencies": { - "@babel/compat-data": "^7.23.3", - "@babel/helper-compilation-targets": "^7.22.15", - "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-compilation-targets": "^7.23.6", + "@babel/helper-plugin-utils": "^7.24.0", "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-transform-parameters": "^7.23.3" + "@babel/plugin-transform-parameters": "^7.24.1" }, "engines": { "node": ">=6.9.0" @@ -1465,13 +1465,13 @@ } }, "node_modules/@babel/plugin-transform-object-super": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.23.3.tgz", - "integrity": "sha512-BwQ8q0x2JG+3lxCVFohg+KbQM7plfpBwThdW9A6TMtWwLsbDA01Ek2Zb/AgDN39BiZsExm4qrXxjk+P1/fzGrA==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.24.1.tgz", + "integrity": "sha512-oKJqR3TeI5hSLRxudMjFQ9re9fBVUU0GICqM3J1mi8MqlhVr6hC/ZN4ttAyMuQR6EZZIY6h/exe5swqGNNIkWQ==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/helper-replace-supers": "^7.22.20" + "@babel/helper-plugin-utils": "^7.24.0", + "@babel/helper-replace-supers": "^7.24.1" }, "engines": { "node": ">=6.9.0" @@ -1481,12 +1481,12 @@ } }, "node_modules/@babel/plugin-transform-optional-catch-binding": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.23.4.tgz", - "integrity": "sha512-XIq8t0rJPHf6Wvmbn9nFxU6ao4c7WhghTR5WyV8SrJfUFzyxhCm4nhC+iAp3HFhbAKLfYpgzhJ6t4XCtVwqO5A==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.24.1.tgz", + "integrity": "sha512-oBTH7oURV4Y+3EUrf6cWn1OHio3qG/PVwO5J03iSJmBg6m2EhKjkAu/xuaXaYwWW9miYtvbWv4LNf0AmR43LUA==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-plugin-utils": "^7.24.0", "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" }, "engines": { @@ -1497,12 +1497,12 @@ } }, "node_modules/@babel/plugin-transform-optional-chaining": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.23.4.tgz", - "integrity": "sha512-ZU8y5zWOfjM5vZ+asjgAPwDaBjJzgufjES89Rs4Lpq63O300R/kOz30WCLo6BxxX6QVEilwSlpClnG5cZaikTA==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.24.1.tgz", + "integrity": "sha512-n03wmDt+987qXwAgcBlnUUivrZBPZ8z1plL0YvgQalLm+ZE5BMhGm94jhxXtA1wzv1Cu2aaOv1BM9vbVttrzSg==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-plugin-utils": "^7.24.0", "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", "@babel/plugin-syntax-optional-chaining": "^7.8.3" }, @@ -1514,12 +1514,12 @@ } }, "node_modules/@babel/plugin-transform-parameters": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.23.3.tgz", - "integrity": "sha512-09lMt6UsUb3/34BbECKVbVwrT9bO6lILWln237z7sLaWnMsTi7Yc9fhX5DLpkJzAGfaReXI22wP41SZmnAA3Vw==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.24.1.tgz", + "integrity": "sha512-8Jl6V24g+Uw5OGPeWNKrKqXPDw2YDjLc53ojwfMcKwlEoETKU9rU0mHUtcg9JntWI/QYzGAXNWEcVHZ+fR+XXg==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.24.0" }, "engines": { "node": ">=6.9.0" @@ -1529,13 +1529,13 @@ } }, "node_modules/@babel/plugin-transform-private-methods": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.23.3.tgz", - "integrity": "sha512-UzqRcRtWsDMTLrRWFvUBDwmw06tCQH9Rl1uAjfh6ijMSmGYQ+fpdB+cnqRC8EMh5tuuxSv0/TejGL+7vyj+50g==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.24.1.tgz", + "integrity": "sha512-tGvisebwBO5em4PaYNqt4fkw56K2VALsAbAakY0FjTYqJp7gfdrgr7YX76Or8/cpik0W6+tj3rZ0uHU9Oil4tw==", "dev": true, "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.22.15", - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-create-class-features-plugin": "^7.24.1", + "@babel/helper-plugin-utils": "^7.24.0" }, "engines": { "node": ">=6.9.0" @@ -1545,14 +1545,14 @@ } }, "node_modules/@babel/plugin-transform-private-property-in-object": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.23.4.tgz", - "integrity": "sha512-9G3K1YqTq3F4Vt88Djx1UZ79PDyj+yKRnUy7cZGSMe+a7jkwD259uKKuUzQlPkGam7R+8RJwh5z4xO27fA1o2A==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.24.1.tgz", + "integrity": "sha512-pTHxDVa0BpUbvAgX3Gat+7cSciXqUcY9j2VZKTbSB6+VQGpNgNO9ailxTGHSXlqOnX1Hcx1Enme2+yv7VqP9bg==", "dev": true, "dependencies": { "@babel/helper-annotate-as-pure": "^7.22.5", - "@babel/helper-create-class-features-plugin": "^7.22.15", - "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-create-class-features-plugin": "^7.24.1", + "@babel/helper-plugin-utils": "^7.24.0", "@babel/plugin-syntax-private-property-in-object": "^7.14.5" }, "engines": { @@ -1563,12 +1563,12 @@ } }, "node_modules/@babel/plugin-transform-property-literals": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.23.3.tgz", - "integrity": "sha512-jR3Jn3y7cZp4oEWPFAlRsSWjxKe4PZILGBSd4nis1TsC5qeSpb+nrtihJuDhNI7QHiVbUaiXa0X2RZY3/TI6Nw==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.24.1.tgz", + "integrity": "sha512-LetvD7CrHmEx0G442gOomRr66d7q8HzzGGr4PMHGr+5YIm6++Yke+jxj246rpvsbyhJwCLxcTn6zW1P1BSenqA==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.24.0" }, "engines": { "node": ">=6.9.0" @@ -1578,12 +1578,12 @@ } }, "node_modules/@babel/plugin-transform-regenerator": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.23.3.tgz", - "integrity": "sha512-KP+75h0KghBMcVpuKisx3XTu9Ncut8Q8TuvGO4IhY+9D5DFEckQefOuIsB/gQ2tG71lCke4NMrtIPS8pOj18BQ==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.24.1.tgz", + "integrity": "sha512-sJwZBCzIBE4t+5Q4IGLaaun5ExVMRY0lYwos/jNecjMrVCygCdph3IKv0tkP5Fc87e/1+bebAmEAGBfnRD+cnw==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-plugin-utils": "^7.24.0", "regenerator-transform": "^0.15.2" }, "engines": { @@ -1594,12 +1594,12 @@ } }, "node_modules/@babel/plugin-transform-reserved-words": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.23.3.tgz", - "integrity": "sha512-QnNTazY54YqgGxwIexMZva9gqbPa15t/x9VS+0fsEFWplwVpXYZivtgl43Z1vMpc1bdPP2PP8siFeVcnFvA3Cg==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.24.1.tgz", + "integrity": "sha512-JAclqStUfIwKN15HrsQADFgeZt+wexNQ0uLhuqvqAUFoqPMjEcFCYZBhq0LUdz6dZK/mD+rErhW71fbx8RYElg==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.24.0" }, "engines": { "node": ">=6.9.0" @@ -1640,12 +1640,12 @@ } }, "node_modules/@babel/plugin-transform-shorthand-properties": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.23.3.tgz", - "integrity": "sha512-ED2fgqZLmexWiN+YNFX26fx4gh5qHDhn1O2gvEhreLW2iI63Sqm4llRLCXALKrCnbN4Jy0VcMQZl/SAzqug/jg==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.24.1.tgz", + "integrity": "sha512-LyjVB1nsJ6gTTUKRjRWx9C1s9hE7dLfP/knKdrfeH9UPtAGjYGgxIbFfx7xyLIEWs7Xe1Gnf8EWiUqfjLhInZA==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.24.0" }, "engines": { "node": ">=6.9.0" @@ -1655,12 +1655,12 @@ } }, "node_modules/@babel/plugin-transform-spread": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.23.3.tgz", - "integrity": "sha512-VvfVYlrlBVu+77xVTOAoxQ6mZbnIq5FM0aGBSFEcIh03qHf+zNqA4DC/3XMUozTg7bZV3e3mZQ0i13VB6v5yUg==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.24.1.tgz", + "integrity": "sha512-KjmcIM+fxgY+KxPVbjelJC6hrH1CgtPmTvdXAfn3/a9CnWGSTY7nH4zm5+cjmWJybdcPSsD0++QssDsjcpe47g==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-plugin-utils": "^7.24.0", "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5" }, "engines": { @@ -1671,12 +1671,12 @@ } }, "node_modules/@babel/plugin-transform-sticky-regex": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.23.3.tgz", - "integrity": "sha512-HZOyN9g+rtvnOU3Yh7kSxXrKbzgrm5X4GncPY1QOquu7epga5MxKHVpYu2hvQnry/H+JjckSYRb93iNfsioAGg==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.24.1.tgz", + "integrity": "sha512-9v0f1bRXgPVcPrngOQvLXeGNNVLc8UjMVfebo9ka0WF3/7+aVUHmaJVT3sa0XCzEFioPfPHZiOcYG9qOsH63cw==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.24.0" }, "engines": { "node": ">=6.9.0" @@ -1686,12 +1686,12 @@ } }, "node_modules/@babel/plugin-transform-template-literals": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.23.3.tgz", - "integrity": "sha512-Flok06AYNp7GV2oJPZZcP9vZdszev6vPBkHLwxwSpaIqx75wn6mUd3UFWsSsA0l8nXAKkyCmL/sR02m8RYGeHg==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.24.1.tgz", + "integrity": "sha512-WRkhROsNzriarqECASCNu/nojeXCDTE/F2HmRgOzi7NGvyfYGq1NEjKBK3ckLfRgGc6/lPAqP0vDOSw3YtG34g==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.24.0" }, "engines": { "node": ">=6.9.0" @@ -1701,12 +1701,12 @@ } }, "node_modules/@babel/plugin-transform-typeof-symbol": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.23.3.tgz", - "integrity": "sha512-4t15ViVnaFdrPC74be1gXBSMzXk3B4Us9lP7uLRQHTFpV5Dvt33pn+2MyyNxmN3VTTm3oTrZVMUmuw3oBnQ2oQ==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.24.1.tgz", + "integrity": "sha512-CBfU4l/A+KruSUoW+vTQthwcAdwuqbpRNB8HQKlZABwHRhsdHZ9fezp4Sn18PeAlYxTNiLMlx4xUBV3AWfg1BA==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.24.0" }, "engines": { "node": ">=6.9.0" @@ -1716,12 +1716,12 @@ } }, "node_modules/@babel/plugin-transform-unicode-escapes": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.23.3.tgz", - "integrity": "sha512-OMCUx/bU6ChE3r4+ZdylEqAjaQgHAgipgW8nsCfu5pGqDcFytVd91AwRvUJSBZDz0exPGgnjoqhgRYLRjFZc9Q==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.24.1.tgz", + "integrity": "sha512-RlkVIcWT4TLI96zM660S877E7beKlQw7Ig+wqkKBiWfj0zH5Q4h50q6er4wzZKRNSYpfo6ILJ+hrJAGSX2qcNw==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.24.0" }, "engines": { "node": ">=6.9.0" @@ -1731,13 +1731,13 @@ } }, "node_modules/@babel/plugin-transform-unicode-property-regex": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.23.3.tgz", - "integrity": "sha512-KcLIm+pDZkWZQAFJ9pdfmh89EwVfmNovFBcXko8szpBeF8z68kWIPeKlmSOkT9BXJxs2C0uk+5LxoxIv62MROA==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.24.1.tgz", + "integrity": "sha512-Ss4VvlfYV5huWApFsF8/Sq0oXnGO+jB+rijFEFugTd3cwSObUSnUi88djgR5528Csl0uKlrI331kRqe56Ov2Ng==", "dev": true, "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.22.15", - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.24.0" }, "engines": { "node": ">=6.9.0" @@ -1747,13 +1747,13 @@ } }, "node_modules/@babel/plugin-transform-unicode-regex": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.23.3.tgz", - "integrity": "sha512-wMHpNA4x2cIA32b/ci3AfwNgheiva2W0WUKWTK7vBHBhDKfPsc5cFGNWm69WBqpwd86u1qwZ9PWevKqm1A3yAw==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.24.1.tgz", + "integrity": "sha512-2A/94wgZgxfTsiLaQ2E36XAOdcZmGAaEEgVmxQWwZXWkGhvoHbaqXcKnU8zny4ycpu3vNqg0L/PcCiYtHtA13g==", "dev": true, "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.22.15", - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.24.0" }, "engines": { "node": ">=6.9.0" @@ -1763,13 +1763,13 @@ } }, "node_modules/@babel/plugin-transform-unicode-sets-regex": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.23.3.tgz", - "integrity": "sha512-W7lliA/v9bNR83Qc3q1ip9CQMZ09CcHDbHfbLRDNuAhn1Mvkr1ZNF7hPmztMQvtTGVLJ9m8IZqWsTkXOml8dbw==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.24.1.tgz", + "integrity": "sha512-fqj4WuzzS+ukpgerpAoOnMfQXwUHFxXUZUE84oL2Kao2N8uSlvcpnAidKASgsNgzZHBsHWvcm8s9FPWUhAb8fA==", "dev": true, "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.22.15", - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.24.0" }, "engines": { "node": ">=6.9.0" @@ -1779,26 +1779,26 @@ } }, "node_modules/@babel/preset-env": { - "version": "7.23.9", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.23.9.tgz", - "integrity": "sha512-3kBGTNBBk9DQiPoXYS0g0BYlwTQYUTifqgKTjxUwEUkduRT2QOa0FPGBJ+NROQhGyYO5BuTJwGvBnqKDykac6A==", + "version": "7.24.3", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.24.3.tgz", + "integrity": "sha512-fSk430k5c2ff8536JcPvPWK4tZDwehWLGlBp0wrsBUjZVdeQV6lePbwKWZaZfK2vnh/1kQX1PzAJWsnBmVgGJA==", "dev": true, "dependencies": { - "@babel/compat-data": "^7.23.5", + "@babel/compat-data": "^7.24.1", "@babel/helper-compilation-targets": "^7.23.6", - "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-plugin-utils": "^7.24.0", "@babel/helper-validator-option": "^7.23.5", - "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.23.3", - "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.23.3", - "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.23.7", + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.24.1", + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.24.1", + "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.24.1", "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2", "@babel/plugin-syntax-async-generators": "^7.8.4", "@babel/plugin-syntax-class-properties": "^7.12.13", "@babel/plugin-syntax-class-static-block": "^7.14.5", "@babel/plugin-syntax-dynamic-import": "^7.8.3", "@babel/plugin-syntax-export-namespace-from": "^7.8.3", - "@babel/plugin-syntax-import-assertions": "^7.23.3", - "@babel/plugin-syntax-import-attributes": "^7.23.3", + "@babel/plugin-syntax-import-assertions": "^7.24.1", + "@babel/plugin-syntax-import-attributes": "^7.24.1", "@babel/plugin-syntax-import-meta": "^7.10.4", "@babel/plugin-syntax-json-strings": "^7.8.3", "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", @@ -1810,58 +1810,58 @@ "@babel/plugin-syntax-private-property-in-object": "^7.14.5", "@babel/plugin-syntax-top-level-await": "^7.14.5", "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6", - "@babel/plugin-transform-arrow-functions": "^7.23.3", - "@babel/plugin-transform-async-generator-functions": "^7.23.9", - "@babel/plugin-transform-async-to-generator": "^7.23.3", - "@babel/plugin-transform-block-scoped-functions": "^7.23.3", - "@babel/plugin-transform-block-scoping": "^7.23.4", - "@babel/plugin-transform-class-properties": "^7.23.3", - "@babel/plugin-transform-class-static-block": "^7.23.4", - "@babel/plugin-transform-classes": "^7.23.8", - "@babel/plugin-transform-computed-properties": "^7.23.3", - "@babel/plugin-transform-destructuring": "^7.23.3", - "@babel/plugin-transform-dotall-regex": "^7.23.3", - "@babel/plugin-transform-duplicate-keys": "^7.23.3", - "@babel/plugin-transform-dynamic-import": "^7.23.4", - "@babel/plugin-transform-exponentiation-operator": "^7.23.3", - "@babel/plugin-transform-export-namespace-from": "^7.23.4", - "@babel/plugin-transform-for-of": "^7.23.6", - "@babel/plugin-transform-function-name": "^7.23.3", - "@babel/plugin-transform-json-strings": "^7.23.4", - "@babel/plugin-transform-literals": "^7.23.3", - "@babel/plugin-transform-logical-assignment-operators": "^7.23.4", - "@babel/plugin-transform-member-expression-literals": "^7.23.3", - "@babel/plugin-transform-modules-amd": "^7.23.3", - "@babel/plugin-transform-modules-commonjs": "^7.23.3", - "@babel/plugin-transform-modules-systemjs": "^7.23.9", - "@babel/plugin-transform-modules-umd": "^7.23.3", + "@babel/plugin-transform-arrow-functions": "^7.24.1", + "@babel/plugin-transform-async-generator-functions": "^7.24.3", + "@babel/plugin-transform-async-to-generator": "^7.24.1", + "@babel/plugin-transform-block-scoped-functions": "^7.24.1", + "@babel/plugin-transform-block-scoping": "^7.24.1", + "@babel/plugin-transform-class-properties": "^7.24.1", + "@babel/plugin-transform-class-static-block": "^7.24.1", + "@babel/plugin-transform-classes": "^7.24.1", + "@babel/plugin-transform-computed-properties": "^7.24.1", + "@babel/plugin-transform-destructuring": "^7.24.1", + "@babel/plugin-transform-dotall-regex": "^7.24.1", + "@babel/plugin-transform-duplicate-keys": "^7.24.1", + "@babel/plugin-transform-dynamic-import": "^7.24.1", + "@babel/plugin-transform-exponentiation-operator": "^7.24.1", + "@babel/plugin-transform-export-namespace-from": "^7.24.1", + "@babel/plugin-transform-for-of": "^7.24.1", + "@babel/plugin-transform-function-name": "^7.24.1", + "@babel/plugin-transform-json-strings": "^7.24.1", + "@babel/plugin-transform-literals": "^7.24.1", + "@babel/plugin-transform-logical-assignment-operators": "^7.24.1", + "@babel/plugin-transform-member-expression-literals": "^7.24.1", + "@babel/plugin-transform-modules-amd": "^7.24.1", + "@babel/plugin-transform-modules-commonjs": "^7.24.1", + "@babel/plugin-transform-modules-systemjs": "^7.24.1", + "@babel/plugin-transform-modules-umd": "^7.24.1", "@babel/plugin-transform-named-capturing-groups-regex": "^7.22.5", - "@babel/plugin-transform-new-target": "^7.23.3", - "@babel/plugin-transform-nullish-coalescing-operator": "^7.23.4", - "@babel/plugin-transform-numeric-separator": "^7.23.4", - "@babel/plugin-transform-object-rest-spread": "^7.23.4", - "@babel/plugin-transform-object-super": "^7.23.3", - "@babel/plugin-transform-optional-catch-binding": "^7.23.4", - "@babel/plugin-transform-optional-chaining": "^7.23.4", - "@babel/plugin-transform-parameters": "^7.23.3", - "@babel/plugin-transform-private-methods": "^7.23.3", - "@babel/plugin-transform-private-property-in-object": "^7.23.4", - "@babel/plugin-transform-property-literals": "^7.23.3", - "@babel/plugin-transform-regenerator": "^7.23.3", - "@babel/plugin-transform-reserved-words": "^7.23.3", - "@babel/plugin-transform-shorthand-properties": "^7.23.3", - "@babel/plugin-transform-spread": "^7.23.3", - "@babel/plugin-transform-sticky-regex": "^7.23.3", - "@babel/plugin-transform-template-literals": "^7.23.3", - "@babel/plugin-transform-typeof-symbol": "^7.23.3", - "@babel/plugin-transform-unicode-escapes": "^7.23.3", - "@babel/plugin-transform-unicode-property-regex": "^7.23.3", - "@babel/plugin-transform-unicode-regex": "^7.23.3", - "@babel/plugin-transform-unicode-sets-regex": "^7.23.3", + "@babel/plugin-transform-new-target": "^7.24.1", + "@babel/plugin-transform-nullish-coalescing-operator": "^7.24.1", + "@babel/plugin-transform-numeric-separator": "^7.24.1", + "@babel/plugin-transform-object-rest-spread": "^7.24.1", + "@babel/plugin-transform-object-super": "^7.24.1", + "@babel/plugin-transform-optional-catch-binding": "^7.24.1", + "@babel/plugin-transform-optional-chaining": "^7.24.1", + "@babel/plugin-transform-parameters": "^7.24.1", + "@babel/plugin-transform-private-methods": "^7.24.1", + "@babel/plugin-transform-private-property-in-object": "^7.24.1", + "@babel/plugin-transform-property-literals": "^7.24.1", + "@babel/plugin-transform-regenerator": "^7.24.1", + "@babel/plugin-transform-reserved-words": "^7.24.1", + "@babel/plugin-transform-shorthand-properties": "^7.24.1", + "@babel/plugin-transform-spread": "^7.24.1", + "@babel/plugin-transform-sticky-regex": "^7.24.1", + "@babel/plugin-transform-template-literals": "^7.24.1", + "@babel/plugin-transform-typeof-symbol": "^7.24.1", + "@babel/plugin-transform-unicode-escapes": "^7.24.1", + "@babel/plugin-transform-unicode-property-regex": "^7.24.1", + "@babel/plugin-transform-unicode-regex": "^7.24.1", + "@babel/plugin-transform-unicode-sets-regex": "^7.24.1", "@babel/preset-modules": "0.1.6-no-external-plugins", - "babel-plugin-polyfill-corejs2": "^0.4.8", - "babel-plugin-polyfill-corejs3": "^0.9.0", - "babel-plugin-polyfill-regenerator": "^0.5.5", + "babel-plugin-polyfill-corejs2": "^0.4.10", + "babel-plugin-polyfill-corejs3": "^0.10.4", + "babel-plugin-polyfill-regenerator": "^0.6.1", "core-js-compat": "^3.31.0", "semver": "^6.3.1" }, @@ -1873,9 +1873,9 @@ } }, "node_modules/@babel/preset-env/node_modules/@babel/helper-define-polyfill-provider": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.5.0.tgz", - "integrity": "sha512-NovQquuQLAQ5HuyjCz7WQP9MjRj7dx++yspwiyUiGl9ZyadHRSql1HZh5ogRd8W8w6YM6EQ/NTB8rgjLt5W65Q==", + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.1.tgz", + "integrity": "sha512-o7SDgTJuvx5vLKD6SFvkydkSMBvahDKGiNJzG22IZYXhiqoe9efY7zocICBgzHV4IRg5wdgl2nEL/tulKIEIbA==", "dev": true, "dependencies": { "@babel/helper-compilation-targets": "^7.22.6", @@ -1889,13 +1889,13 @@ } }, "node_modules/@babel/preset-env/node_modules/babel-plugin-polyfill-corejs2": { - "version": "0.4.8", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.8.tgz", - "integrity": "sha512-OtIuQfafSzpo/LhnJaykc0R/MMnuLSSVjVYy9mHArIZ9qTCSZ6TpWCuEKZYVoN//t8HqBNScHrOtCrIK5IaGLg==", + "version": "0.4.10", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.10.tgz", + "integrity": "sha512-rpIuu//y5OX6jVU+a5BCn1R5RSZYWAl2Nar76iwaOdycqb6JPxediskWFMMl7stfwNJR4b7eiQvh5fB5TEQJTQ==", "dev": true, "dependencies": { "@babel/compat-data": "^7.22.6", - "@babel/helper-define-polyfill-provider": "^0.5.0", + "@babel/helper-define-polyfill-provider": "^0.6.1", "semver": "^6.3.1" }, "peerDependencies": { @@ -1903,12 +1903,12 @@ } }, "node_modules/@babel/preset-env/node_modules/babel-plugin-polyfill-regenerator": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.5.5.tgz", - "integrity": "sha512-OJGYZlhLqBh2DDHeqAxWB1XIvr49CxiJ2gIt61/PU55CQK4Z58OzMqjDe1zwQdQk+rBYsRc+1rJmdajM3gimHg==", + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.1.tgz", + "integrity": "sha512-JfTApdE++cgcTWjsiCQlLyFBMbTUft9ja17saCc93lgV33h4tuCVj7tlvu//qpLwaG+3yEz7/KhahGrUMkVq9g==", "dev": true, "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.5.0" + "@babel/helper-define-polyfill-provider": "^0.6.1" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" @@ -1946,31 +1946,31 @@ } }, "node_modules/@babel/template": { - "version": "7.23.9", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.23.9.tgz", - "integrity": "sha512-+xrD2BWLpvHKNmX2QbpdpsBaWnRxahMwJjO+KZk2JOElj5nSmKezyS1B4u+QbHMTX69t4ukm6hh9lsYQ7GHCKA==", + "version": "7.24.0", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.24.0.tgz", + "integrity": "sha512-Bkf2q8lMB0AFpX0NFEqSbx1OkTHf0f+0j82mkw+ZpzBnkk7e9Ql0891vlfgi+kHwOk8tQjiQHpqh4LaSa0fKEA==", "dependencies": { "@babel/code-frame": "^7.23.5", - "@babel/parser": "^7.23.9", - "@babel/types": "^7.23.9" + "@babel/parser": "^7.24.0", + "@babel/types": "^7.24.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/traverse": { - "version": "7.23.9", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.9.tgz", - "integrity": "sha512-I/4UJ9vs90OkBtY6iiiTORVMyIhJ4kAVmsKo9KFc8UOxMeUfi2hvtIBsET5u9GizXE6/GFSuKCTNfgCswuEjRg==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.24.1.tgz", + "integrity": "sha512-xuU6o9m68KeqZbQuDt2TcKSxUw/mrsvavlEqQ1leZ/B+C9tk6E4sRWy97WaXgvq5E+nU3cXMxv3WKOCanVMCmQ==", "dependencies": { - "@babel/code-frame": "^7.23.5", - "@babel/generator": "^7.23.6", + "@babel/code-frame": "^7.24.1", + "@babel/generator": "^7.24.1", "@babel/helper-environment-visitor": "^7.22.20", "@babel/helper-function-name": "^7.23.0", "@babel/helper-hoist-variables": "^7.22.5", "@babel/helper-split-export-declaration": "^7.22.6", - "@babel/parser": "^7.23.9", - "@babel/types": "^7.23.9", + "@babel/parser": "^7.24.1", + "@babel/types": "^7.24.0", "debug": "^4.3.1", "globals": "^11.1.0" }, @@ -1979,9 +1979,9 @@ } }, "node_modules/@babel/types": { - "version": "7.23.9", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.9.tgz", - "integrity": "sha512-dQjSq/7HaSjRM43FFGnv5keM2HsxpmyV1PfaSVm0nzzjwwTmjOe6J4bC8e3+pTEIgHaHj+1ZlLThRJ2auc/w1Q==", + "version": "7.24.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.0.tgz", + "integrity": "sha512-+j7a5c253RfKh8iABBhywc8NSfP5LURe7Uh4qpsh6jc+aLJguvmIUBdjSdEMQv2bENrCR5MfRdjGo7vzS/ob7w==", "dependencies": { "@babel/helper-string-parser": "^7.23.4", "@babel/helper-validator-identifier": "^7.22.20", @@ -2122,9 +2122,9 @@ } }, "node_modules/@eslint/js": { - "version": "8.56.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.56.0.tgz", - "integrity": "sha512-gMsVel9D7f2HLkBma9VbtzZRehRogVRfbr++f06nL2vnCGCNlzOD+/MUov/F4p8myyAHspEhVobgjpX64q5m6A==", + "version": "8.57.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz", + "integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -2567,13 +2567,13 @@ } }, "node_modules/@humanwhocodes/config-array": { - "version": "0.11.13", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.13.tgz", - "integrity": "sha512-JSBDMiDKSzQVngfRjOdFXgFfklaXI4K9nLF49Auh21lmBWRLIK3+xTErTWD4KU54pb6coM6ESE7Awz/FNU3zgQ==", + "version": "0.11.14", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", + "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==", "dev": true, "dependencies": { - "@humanwhocodes/object-schema": "^2.0.1", - "debug": "^4.1.1", + "@humanwhocodes/object-schema": "^2.0.2", + "debug": "^4.3.1", "minimatch": "^3.0.5" }, "engines": { @@ -2594,9 +2594,9 @@ } }, "node_modules/@humanwhocodes/object-schema": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.1.tgz", - "integrity": "sha512-dvuCeX5fC9dXgJn9t+X5atfmgQAzUOWqS1254Gh0m6i8wKd10ebXkfNKiRK+1GWi/yTvvLDHpoxLr0xxxeslWw==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.2.tgz", + "integrity": "sha512-6EwiSjwWYP7pTckG6I5eyFANjPhmPjUX9JRLUSfNPC7FX7zK9gyZAfUEaECL6ALTpGX5AjnBq3C9XmVWPitNpw==", "dev": true }, "node_modules/@istanbuljs/load-nyc-config": { @@ -3298,13 +3298,13 @@ } }, "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz", - "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==", + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", + "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", "dependencies": { - "@jridgewell/set-array": "^1.0.1", + "@jridgewell/set-array": "^1.2.1", "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.9" + "@jridgewell/trace-mapping": "^0.3.24" }, "engines": { "node": ">=6.0.0" @@ -3319,9 +3319,9 @@ } }, "node_modules/@jridgewell/set-array": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", - "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", + "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", "engines": { "node": ">=6.0.0" } @@ -3342,9 +3342,9 @@ "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==" }, "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.22", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.22.tgz", - "integrity": "sha512-Wf963MzWtA2sjrNt+g18IAln9lKnlRp+K2eH4jjIoF1wYeq3aMREpG09xhlhdzS0EjwU7qmUJYangWa+151vZw==", + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" @@ -3999,148 +3999,148 @@ } }, "node_modules/@webassemblyjs/ast": { - "version": "1.11.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.5.tgz", - "integrity": "sha512-LHY/GSAZZRpsNQH+/oHqhRQ5FT7eoULcBqgfyTB5nQHogFnK3/7QoN7dLnwSE/JkUAF0SrRuclT7ODqMFtWxxQ==", + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.12.1.tgz", + "integrity": "sha512-EKfMUOPRRUTy5UII4qJDGPpqfwjOmZ5jeGFwid9mnoqIFK+e0vqoi1qH56JpmZSzEL53jKnNzScdmftJyG5xWg==", "dev": true, "dependencies": { - "@webassemblyjs/helper-numbers": "1.11.5", - "@webassemblyjs/helper-wasm-bytecode": "1.11.5" + "@webassemblyjs/helper-numbers": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6" } }, "node_modules/@webassemblyjs/floating-point-hex-parser": { - "version": "1.11.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.5.tgz", - "integrity": "sha512-1j1zTIC5EZOtCplMBG/IEwLtUojtwFVwdyVMbL/hwWqbzlQoJsWCOavrdnLkemwNoC/EOwtUFch3fuo+cbcXYQ==", + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz", + "integrity": "sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==", "dev": true }, "node_modules/@webassemblyjs/helper-api-error": { - "version": "1.11.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.5.tgz", - "integrity": "sha512-L65bDPmfpY0+yFrsgz8b6LhXmbbs38OnwDCf6NpnMUYqa+ENfE5Dq9E42ny0qz/PdR0LJyq/T5YijPnU8AXEpA==", + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz", + "integrity": "sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==", "dev": true }, "node_modules/@webassemblyjs/helper-buffer": { - "version": "1.11.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.5.tgz", - "integrity": "sha512-fDKo1gstwFFSfacIeH5KfwzjykIE6ldh1iH9Y/8YkAZrhmu4TctqYjSh7t0K2VyDSXOZJ1MLhht/k9IvYGcIxg==", + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.12.1.tgz", + "integrity": "sha512-nzJwQw99DNDKr9BVCOZcLuJJUlqkJh+kVzVl6Fmq/tI5ZtEyWT1KZMyOXltXLZJmDtvLCDgwsyrkohEtopTXCw==", "dev": true }, "node_modules/@webassemblyjs/helper-numbers": { - "version": "1.11.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.5.tgz", - "integrity": "sha512-DhykHXM0ZABqfIGYNv93A5KKDw/+ywBFnuWybZZWcuzWHfbp21wUfRkbtz7dMGwGgT4iXjWuhRMA2Mzod6W4WA==", + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz", + "integrity": "sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==", "dev": true, "dependencies": { - "@webassemblyjs/floating-point-hex-parser": "1.11.5", - "@webassemblyjs/helper-api-error": "1.11.5", + "@webassemblyjs/floating-point-hex-parser": "1.11.6", + "@webassemblyjs/helper-api-error": "1.11.6", "@xtuc/long": "4.2.2" } }, "node_modules/@webassemblyjs/helper-wasm-bytecode": { - "version": "1.11.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.5.tgz", - "integrity": "sha512-oC4Qa0bNcqnjAowFn7MPCETQgDYytpsfvz4ujZz63Zu/a/v71HeCAAmZsgZ3YVKec3zSPYytG3/PrRCqbtcAvA==", + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz", + "integrity": "sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==", "dev": true }, "node_modules/@webassemblyjs/helper-wasm-section": { - "version": "1.11.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.5.tgz", - "integrity": "sha512-uEoThA1LN2NA+K3B9wDo3yKlBfVtC6rh0i4/6hvbz071E8gTNZD/pT0MsBf7MeD6KbApMSkaAK0XeKyOZC7CIA==", + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.12.1.tgz", + "integrity": "sha512-Jif4vfB6FJlUlSbgEMHUyk1j234GTNG9dBJ4XJdOySoj518Xj0oGsNi59cUQF4RRMS9ouBUxDDdyBVfPTypa5g==", "dev": true, "dependencies": { - "@webassemblyjs/ast": "1.11.5", - "@webassemblyjs/helper-buffer": "1.11.5", - "@webassemblyjs/helper-wasm-bytecode": "1.11.5", - "@webassemblyjs/wasm-gen": "1.11.5" + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-buffer": "1.12.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/wasm-gen": "1.12.1" } }, "node_modules/@webassemblyjs/ieee754": { - "version": "1.11.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.5.tgz", - "integrity": "sha512-37aGq6qVL8A8oPbPrSGMBcp38YZFXcHfiROflJn9jxSdSMMM5dS5P/9e2/TpaJuhE+wFrbukN2WI6Hw9MH5acg==", + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz", + "integrity": "sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==", "dev": true, "dependencies": { "@xtuc/ieee754": "^1.2.0" } }, "node_modules/@webassemblyjs/leb128": { - "version": "1.11.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.5.tgz", - "integrity": "sha512-ajqrRSXaTJoPW+xmkfYN6l8VIeNnR4vBOTQO9HzR7IygoCcKWkICbKFbVTNMjMgMREqXEr0+2M6zukzM47ZUfQ==", + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.6.tgz", + "integrity": "sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==", "dev": true, "dependencies": { "@xtuc/long": "4.2.2" } }, "node_modules/@webassemblyjs/utf8": { - "version": "1.11.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.5.tgz", - "integrity": "sha512-WiOhulHKTZU5UPlRl53gHR8OxdGsSOxqfpqWeA2FmcwBMaoEdz6b2x2si3IwC9/fSPLfe8pBMRTHVMk5nlwnFQ==", + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.6.tgz", + "integrity": "sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==", "dev": true }, "node_modules/@webassemblyjs/wasm-edit": { - "version": "1.11.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.5.tgz", - "integrity": "sha512-C0p9D2fAu3Twwqvygvf42iGCQ4av8MFBLiTb+08SZ4cEdwzWx9QeAHDo1E2k+9s/0w1DM40oflJOpkZ8jW4HCQ==", + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.12.1.tgz", + "integrity": "sha512-1DuwbVvADvS5mGnXbE+c9NfA8QRcZ6iKquqjjmR10k6o+zzsRVesil54DKexiowcFCPdr/Q0qaMgB01+SQ1u6g==", "dev": true, "dependencies": { - "@webassemblyjs/ast": "1.11.5", - "@webassemblyjs/helper-buffer": "1.11.5", - "@webassemblyjs/helper-wasm-bytecode": "1.11.5", - "@webassemblyjs/helper-wasm-section": "1.11.5", - "@webassemblyjs/wasm-gen": "1.11.5", - "@webassemblyjs/wasm-opt": "1.11.5", - "@webassemblyjs/wasm-parser": "1.11.5", - "@webassemblyjs/wast-printer": "1.11.5" + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-buffer": "1.12.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/helper-wasm-section": "1.12.1", + "@webassemblyjs/wasm-gen": "1.12.1", + "@webassemblyjs/wasm-opt": "1.12.1", + "@webassemblyjs/wasm-parser": "1.12.1", + "@webassemblyjs/wast-printer": "1.12.1" } }, "node_modules/@webassemblyjs/wasm-gen": { - "version": "1.11.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.5.tgz", - "integrity": "sha512-14vteRlRjxLK9eSyYFvw1K8Vv+iPdZU0Aebk3j6oB8TQiQYuO6hj9s4d7qf6f2HJr2khzvNldAFG13CgdkAIfA==", + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.12.1.tgz", + "integrity": "sha512-TDq4Ojh9fcohAw6OIMXqiIcTq5KUXTGRkVxbSo1hQnSy6lAM5GSdfwWeSxpAo0YzgsgF182E/U0mDNhuA0tW7w==", "dev": true, "dependencies": { - "@webassemblyjs/ast": "1.11.5", - "@webassemblyjs/helper-wasm-bytecode": "1.11.5", - "@webassemblyjs/ieee754": "1.11.5", - "@webassemblyjs/leb128": "1.11.5", - "@webassemblyjs/utf8": "1.11.5" + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/ieee754": "1.11.6", + "@webassemblyjs/leb128": "1.11.6", + "@webassemblyjs/utf8": "1.11.6" } }, "node_modules/@webassemblyjs/wasm-opt": { - "version": "1.11.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.5.tgz", - "integrity": "sha512-tcKwlIXstBQgbKy1MlbDMlXaxpucn42eb17H29rawYLxm5+MsEmgPzeCP8B1Cl69hCice8LeKgZpRUAPtqYPgw==", + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.12.1.tgz", + "integrity": "sha512-Jg99j/2gG2iaz3hijw857AVYekZe2SAskcqlWIZXjji5WStnOpVoat3gQfT/Q5tb2djnCjBtMocY/Su1GfxPBg==", "dev": true, "dependencies": { - "@webassemblyjs/ast": "1.11.5", - "@webassemblyjs/helper-buffer": "1.11.5", - "@webassemblyjs/wasm-gen": "1.11.5", - "@webassemblyjs/wasm-parser": "1.11.5" + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-buffer": "1.12.1", + "@webassemblyjs/wasm-gen": "1.12.1", + "@webassemblyjs/wasm-parser": "1.12.1" } }, "node_modules/@webassemblyjs/wasm-parser": { - "version": "1.11.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.5.tgz", - "integrity": "sha512-SVXUIwsLQlc8srSD7jejsfTU83g7pIGr2YYNb9oHdtldSxaOhvA5xwvIiWIfcX8PlSakgqMXsLpLfbbJ4cBYew==", + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.12.1.tgz", + "integrity": "sha512-xikIi7c2FHXysxXe3COrVUPSheuBtpcfhbpFj4gmu7KRLYOzANztwUU0IbsqvMqzuNK2+glRGWCEqZo1WCLyAQ==", "dev": true, "dependencies": { - "@webassemblyjs/ast": "1.11.5", - "@webassemblyjs/helper-api-error": "1.11.5", - "@webassemblyjs/helper-wasm-bytecode": "1.11.5", - "@webassemblyjs/ieee754": "1.11.5", - "@webassemblyjs/leb128": "1.11.5", - "@webassemblyjs/utf8": "1.11.5" + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-api-error": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/ieee754": "1.11.6", + "@webassemblyjs/leb128": "1.11.6", + "@webassemblyjs/utf8": "1.11.6" } }, "node_modules/@webassemblyjs/wast-printer": { - "version": "1.11.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.5.tgz", - "integrity": "sha512-f7Pq3wvg3GSPUPzR0F6bmI89Hdb+u9WXrSKc4v+N0aV0q6r42WoF92Jp2jEorBEBRoRNXgjp53nBniDXcqZYPA==", + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.12.1.tgz", + "integrity": "sha512-+X4WAlOisVWQMikjbcvY2e0rwPsKQ9F688lksZhBcPycBBuii3O7m8FACbDMWDojpAqvjIncrG8J0XHKyQfVeA==", "dev": true, "dependencies": { - "@webassemblyjs/ast": "1.11.5", + "@webassemblyjs/ast": "1.12.1", "@xtuc/long": "4.2.2" } }, @@ -4634,9 +4634,9 @@ "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" }, "node_modules/autoprefixer": { - "version": "10.4.17", - "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.17.tgz", - "integrity": "sha512-/cpVNRLSfhOtcGflT13P2794gVSgmPgTR+erw5ifnMLZb0UnSlkK4tquLmkd3BhA+nLo5tX8Cu0upUsGKvKbmg==", + "version": "10.4.19", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.19.tgz", + "integrity": "sha512-BaENR2+zBZ8xXhM4pUaKUxlVdxZ0EZhjvbopwnXmxRUfqDmwSpC2lAi/QXvx7NRdPCo1WKEcEF6mV64si1z4Ew==", "dev": true, "funding": [ { @@ -4653,8 +4653,8 @@ } ], "dependencies": { - "browserslist": "^4.22.2", - "caniuse-lite": "^1.0.30001578", + "browserslist": "^4.23.0", + "caniuse-lite": "^1.0.30001599", "fraction.js": "^4.3.7", "normalize-range": "^0.1.2", "picocolors": "^1.0.0", @@ -4863,22 +4863,22 @@ } }, "node_modules/babel-plugin-polyfill-corejs3": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.9.0.tgz", - "integrity": "sha512-7nZPG1uzK2Ymhy/NbaOWTg3uibM2BmGASS4vHS4szRZAIR8R6GwA/xAujpdrXU5iyklrimWnLWU+BLF9suPTqg==", + "version": "0.10.4", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.10.4.tgz", + "integrity": "sha512-25J6I8NGfa5YkCDogHRID3fVCadIR8/pGl1/spvCkzb6lVn6SR3ojpx9nOn9iEBcUsjY24AmdKm5khcfKdylcg==", "dev": true, "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.5.0", - "core-js-compat": "^3.34.0" + "@babel/helper-define-polyfill-provider": "^0.6.1", + "core-js-compat": "^3.36.1" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, "node_modules/babel-plugin-polyfill-corejs3/node_modules/@babel/helper-define-polyfill-provider": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.5.0.tgz", - "integrity": "sha512-NovQquuQLAQ5HuyjCz7WQP9MjRj7dx++yspwiyUiGl9ZyadHRSql1HZh5ogRd8W8w6YM6EQ/NTB8rgjLt5W65Q==", + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.1.tgz", + "integrity": "sha512-o7SDgTJuvx5vLKD6SFvkydkSMBvahDKGiNJzG22IZYXhiqoe9efY7zocICBgzHV4IRg5wdgl2nEL/tulKIEIbA==", "dev": true, "dependencies": { "@babel/helper-compilation-targets": "^7.22.6", @@ -5237,9 +5237,9 @@ ] }, "node_modules/browserslist": { - "version": "4.22.2", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.22.2.tgz", - "integrity": "sha512-0UgcrvQmBDvZHFGdYUehrCNIazki7/lUP3kkoi/r3YB2amZbFM9J43ZRkJTXBUZK4gmx56+Sqk9+Vs9mwZx9+A==", + "version": "4.23.0", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.0.tgz", + "integrity": "sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ==", "funding": [ { "type": "opencollective", @@ -5255,8 +5255,8 @@ } ], "dependencies": { - "caniuse-lite": "^1.0.30001565", - "electron-to-chromium": "^1.4.601", + "caniuse-lite": "^1.0.30001587", + "electron-to-chromium": "^1.4.668", "node-releases": "^2.0.14", "update-browserslist-db": "^1.0.13" }, @@ -5508,9 +5508,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001579", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001579.tgz", - "integrity": "sha512-u5AUVkixruKHJjw/pj9wISlcMpgFWzSrczLZbrqBSxukQixmg0SJ5sZTpvaFvxU0HoQKd4yoyAogyrAz9pzJnA==", + "version": "1.0.30001605", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001605.tgz", + "integrity": "sha512-nXwGlFWo34uliI9z3n6Qc0wZaf7zaZWA1CPZ169La5mV3I/gem7bst0vr5XQH5TJXZIMfDeZyOrZnSlVzKxxHQ==", "funding": [ { "type": "opencollective", @@ -5570,14 +5570,14 @@ } }, "node_modules/chart.js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/chart.js/-/chart.js-4.4.1.tgz", - "integrity": "sha512-C74QN1bxwV1v2PEujhmKjOZ7iUM4w6BWs23Md/6aOZZSlwMzeCIDGuZay++rBgChYru7/+QFeoQW0fQoP534Dg==", + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/chart.js/-/chart.js-4.4.2.tgz", + "integrity": "sha512-6GD7iKwFpP5kbSD4MeRRRlTnQvxfQREy36uEtm1hzHzcOqwWx0YEHuspuoNlslu+nciLIB7fjjsHkUv/FzFcOg==", "dependencies": { "@kurkle/color": "^0.3.0" }, "engines": { - "pnpm": ">=7" + "pnpm": ">=8" } }, "node_modules/chartjs-adapter-luxon": { @@ -5899,9 +5899,9 @@ } }, "node_modules/cookie": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", - "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz", + "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==", "engines": { "node": ">= 0.6" } @@ -5949,9 +5949,9 @@ } }, "node_modules/core-js": { - "version": "3.36.0", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.36.0.tgz", - "integrity": "sha512-mt7+TUBbTFg5+GngsAxeKBTl5/VS0guFeJacYge9OmHb+m058UwwIm41SE9T4Den7ClatV57B6TYTuJ0CX1MAw==", + "version": "3.36.1", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.36.1.tgz", + "integrity": "sha512-BTvUrwxVBezj5SZ3f10ImnX2oRByMxql3EimVqMysepbC9EeMUOpLwdy6Eoili2x6E4kf+ZUB5k/+Jv55alPfA==", "hasInstallScript": true, "funding": { "type": "opencollective", @@ -5959,11 +5959,11 @@ } }, "node_modules/core-js-compat": { - "version": "3.35.0", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.35.0.tgz", - "integrity": "sha512-5blwFAddknKeNgsjBzilkdQ0+YK8L1PfqPYq40NOYMYFSS38qj+hpTcLLWwpIwA2A5bje/x5jmVn2tzUMg9IVw==", + "version": "3.36.1", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.36.1.tgz", + "integrity": "sha512-Dk997v9ZCt3X/npqzyGdTlq6t7lDBhZwGvV94PKzDArjp7BTRm7WlDAXYd/OWdeFHO8OChQYRJNJvUCqCbrtKA==", "dependencies": { - "browserslist": "^4.22.2" + "browserslist": "^4.23.0" }, "funding": { "type": "opencollective", @@ -6936,9 +6936,9 @@ "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" }, "node_modules/electron-to-chromium": { - "version": "1.4.609", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.609.tgz", - "integrity": "sha512-ihiCP7PJmjoGNuLpl7TjNA8pCQWu09vGyjlPYw1Rqww4gvNuCcmvl+44G+2QyJ6S2K4o+wbTS++Xz0YN8Q9ERw==" + "version": "1.4.692", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.692.tgz", + "integrity": "sha512-d5rZRka9n2Y3MkWRN74IoAsxR0HK3yaAt7T50e3iT9VZmCCQDT3geXUO5ZRMhDToa1pkCeQXuNo+0g+NfDOVPA==" }, "node_modules/elliptic": { "version": "6.5.4", @@ -7026,9 +7026,9 @@ } }, "node_modules/enhanced-resolve": { - "version": "5.15.0", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.15.0.tgz", - "integrity": "sha512-LXYT42KJ7lpIKECr2mAXIaMldcNCh/7E0KBKOu4KSfkHmP+mZmSs+8V5gBAqisWBy0OO4W5Oyys0GO1Y8KtdKg==", + "version": "5.16.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.16.0.tgz", + "integrity": "sha512-O+QWCviPNSSLAD9Ucn8Awv+poAkqn3T1XY5/N7kR7rQO9yfSGWkYZDwpJ+iKF7B8rxaQKWngSqACpgzeapSyoA==", "dev": true, "dependencies": { "graceful-fs": "^4.2.4", @@ -7191,13 +7191,14 @@ } }, "node_modules/es5-ext": { - "version": "0.10.62", - "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.62.tgz", - "integrity": "sha512-BHLqn0klhEpnOKSrzn/Xsz2UIW8j+cGmo9JLzr8BiUapV8hPL9+FliFqjwr9ngW7jWdnxv6eO+/LqyhJVqgrjA==", + "version": "0.10.64", + "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.64.tgz", + "integrity": "sha512-p2snDhiLaXe6dahss1LddxqEm+SkuDvV8dnIQG0MWjyHpcMNfXKPE+/Cc0y+PhxJX3A4xGNeFCj5oc0BUh6deg==", "hasInstallScript": true, "dependencies": { "es6-iterator": "^2.0.3", "es6-symbol": "^3.1.3", + "esniff": "^2.0.1", "next-tick": "^1.1.0" }, "engines": { @@ -7332,16 +7333,16 @@ } }, "node_modules/eslint": { - "version": "8.56.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.56.0.tgz", - "integrity": "sha512-Go19xM6T9puCOWntie1/P997aXxFsOi37JIHRWI514Hc6ZnaHGKY9xFhrU65RT6CcBEzZoGG1e6Nq+DT04ZtZQ==", + "version": "8.57.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz", + "integrity": "sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.6.1", "@eslint/eslintrc": "^2.1.4", - "@eslint/js": "8.56.0", - "@humanwhocodes/config-array": "^0.11.13", + "@eslint/js": "8.57.0", + "@humanwhocodes/config-array": "^0.11.14", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", "@ungap/structured-clone": "^1.2.0", @@ -7911,6 +7912,25 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/esniff": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/esniff/-/esniff-2.0.1.tgz", + "integrity": "sha512-kTUIGKQ/mDPFoJ0oVfcmyJn4iBDRptjNVIzwIFR7tqWXdVI9xfA2RMwY/gbSpJG3lkdWNEjLap/NqVHZiJsdfg==", + "dependencies": { + "d": "^1.0.1", + "es5-ext": "^0.10.62", + "event-emitter": "^0.3.5", + "type": "^2.7.2" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esniff/node_modules/type": { + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/type/-/type-2.7.2.tgz", + "integrity": "sha512-dzlvlNlt6AXU7EBSfpAscydQ7gXB+pPGsPnfJnZpiNJBDj7IaJzQlBZYGdEi4R9HmPdBv2XmWJ6YUtoTa7lmCw==" + }, "node_modules/espree": { "version": "9.6.1", "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", @@ -8501,6 +8521,15 @@ "npm": ">=3" } }, + "node_modules/event-emitter": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz", + "integrity": "sha512-D9rRn9y7kLPnJ+hMq7S/nhvoKwwvVJahBi2BPmx3bvbsEdK3W9ii8cBSGjP+72/LnM4n6fo3+dkCX5FeTQruXA==", + "dependencies": { + "d": "1", + "es5-ext": "~0.10.14" + } + }, "node_modules/eventemitter3": { "version": "4.0.4", "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.4.tgz", @@ -8572,16 +8601,16 @@ } }, "node_modules/express": { - "version": "4.18.2", - "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz", - "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==", + "version": "4.19.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.19.2.tgz", + "integrity": "sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==", "dependencies": { "accepts": "~1.3.8", "array-flatten": "1.1.1", - "body-parser": "1.20.1", + "body-parser": "1.20.2", "content-disposition": "0.5.4", "content-type": "~1.0.4", - "cookie": "0.5.0", + "cookie": "0.6.0", "cookie-signature": "1.0.6", "debug": "2.6.9", "depd": "2.0.0", @@ -8612,29 +8641,6 @@ "node": ">= 0.10.0" } }, - "node_modules/express/node_modules/body-parser": { - "version": "1.20.1", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", - "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==", - "dependencies": { - "bytes": "3.1.2", - "content-type": "~1.0.4", - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "on-finished": "2.4.1", - "qs": "6.11.0", - "raw-body": "2.5.1", - "type-is": "~1.6.18", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8", - "npm": "1.2.8000 || >= 1.4.16" - } - }, "node_modules/express/node_modules/debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", @@ -8662,20 +8668,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/express/node_modules/raw-body": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", - "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", - "dependencies": { - "bytes": "3.1.2", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, "node_modules/express/node_modules/safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", @@ -9334,9 +9326,9 @@ } }, "node_modules/graceful-fs": { - "version": "4.2.9", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.9.tgz", - "integrity": "sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ==" + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==" }, "node_modules/graphemer": { "version": "1.4.0", @@ -12856,9 +12848,9 @@ } }, "node_modules/mini-css-extract-plugin": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.8.0.tgz", - "integrity": "sha512-CxmUYPFcTgET1zImteG/LZOy/4T5rTojesQXkSNBiquhydn78tfbCE9sjIjnJ/UcjNjOC1bphTCCW5rrS7cXAg==", + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.8.1.tgz", + "integrity": "sha512-/1HDlyFRxWIZPI1ZpgqlZ8jMw/1Dp/dl3P0L1jtZ+zVcHqwPhGwaJwKL00WVgfnBy6PWCde9W65or7IIETImuA==", "dev": true, "dependencies": { "schema-utils": "^4.0.0", @@ -13765,9 +13757,9 @@ } }, "node_modules/postcss": { - "version": "8.4.35", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.35.tgz", - "integrity": "sha512-u5U8qYpBCpN13BsiEB0CbR1Hhh4Gc0zLFuedrHJKMctHCHAGrMdG0PRM/KErzAL3CU6/eckEtmHNB3x6e3c0vA==", + "version": "8.4.38", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.38.tgz", + "integrity": "sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==", "dev": true, "funding": [ { @@ -13786,7 +13778,7 @@ "dependencies": { "nanoid": "^3.3.7", "picocolors": "^1.0.0", - "source-map-js": "^1.0.2" + "source-map-js": "^1.2.0" }, "engines": { "node": "^10 || ^12 || >=14" @@ -13891,9 +13883,9 @@ } }, "node_modules/postcss-loader": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-8.1.0.tgz", - "integrity": "sha512-AbperNcX3rlob7Ay7A/HQcrofug1caABBkopoFeOQMspZBqcqj6giYn1Bwey/0uiOPAcR+NQD0I2HC7rXzk91w==", + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-8.1.1.tgz", + "integrity": "sha512-0IeqyAsG6tYiDRCYKQJLAmgQr47DX6N7sFSWvQxt6AcupX8DIdmykuk/o/tx0Lze3ErGHJEp5OSRxrelC6+NdQ==", "dev": true, "dependencies": { "cosmiconfig": "^9.0.0", @@ -15224,9 +15216,9 @@ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, "node_modules/sass": { - "version": "1.71.0", - "resolved": "https://registry.npmjs.org/sass/-/sass-1.71.0.tgz", - "integrity": "sha512-HKKIKf49Vkxlrav3F/w6qRuPcmImGVbIXJ2I3Kg0VMA+3Bav+8yE9G5XmP5lMj6nl4OlqbPftGAscNaNu28b8w==", + "version": "1.72.0", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.72.0.tgz", + "integrity": "sha512-Gpczt3WA56Ly0Mn8Sl21Vj94s1axi9hDIzDFn9Ph9x3C3p4nNyvsqJoQyVXKou6cBlfFWEgRW4rT8Tb4i3XnVA==", "dev": true, "dependencies": { "chokidar": ">=3.0.0 <4.0.0", @@ -15663,9 +15655,9 @@ } }, "node_modules/source-map-js": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", - "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", + "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==", "dev": true, "engines": { "node": ">=0.10.0" @@ -16127,9 +16119,9 @@ } }, "node_modules/sweetalert2": { - "version": "11.10.5", - "resolved": "https://registry.npmjs.org/sweetalert2/-/sweetalert2-11.10.5.tgz", - "integrity": "sha512-q9eE3EKhMcpIDU/Xcz7z5lk8axCGkgxwK47gXGrrfncnBJWxHPPHnBVAjfsVXcTt8Yi8U6HNEcBRSu+qGeyFdA==", + "version": "11.10.7", + "resolved": "https://registry.npmjs.org/sweetalert2/-/sweetalert2-11.10.7.tgz", + "integrity": "sha512-5Jlzrmaitay6KzU+2+LhYu9q+L4v/dZ8oZyEDH14ep0C/QilCnFLHmqAyD/Lhq/lm5DiwsOs6Tr58iv8k3wyGg==", "funding": { "type": "individual", "url": "https://github.com/sponsors/limonte" @@ -16862,9 +16854,9 @@ } }, "node_modules/watchpack": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz", - "integrity": "sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.1.tgz", + "integrity": "sha512-8wrBCMtVhqcXP2Sup1ctSkga6uc2Bx0IIvKyT7yTFier5AXHooSI+QyQQAtTb7+E0IUCCKyTFmXqdqgum2XWGg==", "dev": true, "dependencies": { "glob-to-regexp": "^0.4.1", @@ -17369,26 +17361,26 @@ } }, "node_modules/webpack": { - "version": "5.90.3", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.90.3.tgz", - "integrity": "sha512-h6uDYlWCctQRuXBs1oYpVe6sFcWedl0dpcVaTf/YF67J9bKvwJajFulMVSYKHrksMB3I/pIagRzDxwxkebuzKA==", + "version": "5.91.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.91.0.tgz", + "integrity": "sha512-rzVwlLeBWHJbmgTC/8TvAcu5vpJNII+MelQpylD4jNERPwpBJOE2lEcko1zJX3QJeLjTTAnQxn/OJ8bjDzVQaw==", "dev": true, "dependencies": { "@types/eslint-scope": "^3.7.3", "@types/estree": "^1.0.5", - "@webassemblyjs/ast": "^1.11.5", - "@webassemblyjs/wasm-edit": "^1.11.5", - "@webassemblyjs/wasm-parser": "^1.11.5", + "@webassemblyjs/ast": "^1.12.1", + "@webassemblyjs/wasm-edit": "^1.12.1", + "@webassemblyjs/wasm-parser": "^1.12.1", "acorn": "^8.7.1", "acorn-import-assertions": "^1.9.0", "browserslist": "^4.21.10", "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.15.0", + "enhanced-resolve": "^5.16.0", "es-module-lexer": "^1.2.1", "eslint-scope": "5.1.1", "events": "^3.2.0", "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.2.9", + "graceful-fs": "^4.2.11", "json-parse-even-better-errors": "^2.3.1", "loader-runner": "^4.2.0", "mime-types": "^2.1.27", @@ -17396,7 +17388,7 @@ "schema-utils": "^3.2.0", "tapable": "^2.1.1", "terser-webpack-plugin": "^5.3.10", - "watchpack": "^2.4.0", + "watchpack": "^2.4.1", "webpack-sources": "^3.2.3" }, "bin": { @@ -17804,9 +17796,9 @@ "dev": true }, "node_modules/xss": { - "version": "1.0.14", - "resolved": "https://registry.npmjs.org/xss/-/xss-1.0.14.tgz", - "integrity": "sha512-og7TEJhXvn1a7kzZGQ7ETjdQVS2UfZyTlsEdDOqvQF7GoxNfY+0YLCzBy1kPdsDDx4QuNAonQPddpsn6Xl/7sw==", + "version": "1.0.15", + "resolved": "https://registry.npmjs.org/xss/-/xss-1.0.15.tgz", + "integrity": "sha512-FVdlVVC67WOIPvfOwhoMETV72f6GbW7aOabBC3WxN/oUdoEMDyLz4OgRv5/gck2ZeNqEQu+Tb0kloovXOfpYVg==", "dependencies": { "commander": "^2.20.3", "cssfilter": "0.0.10" @@ -17907,15 +17899,15 @@ "dev": true }, "@amplitude/analytics-browser": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@amplitude/analytics-browser/-/analytics-browser-2.4.1.tgz", - "integrity": "sha512-sxudfDAOZcyTJOHUc66uAHgZbZY9PORh4CAX4V66ozW+0vneeYPJm3ECCJqIrdJ/JWceOe/ohCT8G06X9s/4yg==", - "requires": { - "@amplitude/analytics-client-common": "^2.0.11", - "@amplitude/analytics-core": "^2.2.0", - "@amplitude/analytics-types": "^2.4.0", - "@amplitude/plugin-page-view-tracking-browser": "^2.1.1", - "@amplitude/plugin-web-attribution-browser": "^2.1.1", + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/@amplitude/analytics-browser/-/analytics-browser-2.6.1.tgz", + "integrity": "sha512-mGHPW5gGbYJhJOskYd9t4TPpf8v5jkDB2ndCmWipSm/OXHVCcQucRGUrJdmQIRrW+5aB4ertYCK0t2m/yzj2zw==", + "requires": { + "@amplitude/analytics-client-common": "^2.1.2", + "@amplitude/analytics-core": "^2.2.3", + "@amplitude/analytics-types": "^2.5.0", + "@amplitude/plugin-page-view-tracking-browser": "^2.2.5", + "@amplitude/plugin-web-attribution-browser": "^2.1.6", "tslib": "^2.4.1" }, "dependencies": { @@ -17927,13 +17919,13 @@ } }, "@amplitude/analytics-client-common": { - "version": "2.0.11", - "resolved": "https://registry.npmjs.org/@amplitude/analytics-client-common/-/analytics-client-common-2.0.11.tgz", - "integrity": "sha512-f2zzo7Sk1hz8/WT7kPB6HZqAyHJrxMzw9nTqbLoRsaG9xm4YOJ0WCwtlu42RVRqIoWR89RTmIkqIjqimqMaHEQ==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@amplitude/analytics-client-common/-/analytics-client-common-2.1.2.tgz", + "integrity": "sha512-ekDMrXk7G15NPUGGcyB2x8WtBnzR6jRPRgW4vRToed7e3PVGzIWRSVyO9ymJZepQ+TCZ3ChlsBS1YonuTE0r2Q==", "requires": { "@amplitude/analytics-connector": "^1.4.8", - "@amplitude/analytics-core": "^2.2.0", - "@amplitude/analytics-types": "^2.4.0", + "@amplitude/analytics-core": "^2.2.3", + "@amplitude/analytics-types": "^2.5.0", "tslib": "^2.4.1" }, "dependencies": { @@ -17950,11 +17942,11 @@ "integrity": "sha512-T8mOYzB9RRxckzhL0NTHwdge9xuFxXEOplC8B1Y3UX3NHa3BLh7DlBUZlCOwQgMc2nxDfnSweDL5S3bhC+W90g==" }, "@amplitude/analytics-core": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@amplitude/analytics-core/-/analytics-core-2.2.0.tgz", - "integrity": "sha512-JVx1chKa/sfqpBNEZn6jaZZV3DW/6cOoJxx8b5oqHIn+5HXizEOV85aLFY0rrtZ/uR/HrdffxrMKzr/uBFlV+A==", + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/@amplitude/analytics-core/-/analytics-core-2.2.3.tgz", + "integrity": "sha512-rtA7TSqie6Jgcvax3tEHaZUzOJM5Hdd5/+JYFIJK2gPgHsWZj3jDF75fL8BSn4uBiA2zcZ0vbCHORMVqXg5pRw==", "requires": { - "@amplitude/analytics-types": "^2.4.0", + "@amplitude/analytics-types": "^2.5.0", "tslib": "^2.4.1" }, "dependencies": { @@ -17966,17 +17958,17 @@ } }, "@amplitude/analytics-types": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/@amplitude/analytics-types/-/analytics-types-2.4.0.tgz", - "integrity": "sha512-GVj9W4X3XMVyGfqXdES2vFU8pqTIHvihj/vNOjOrwYHVdia3GjlcGl77GXuERCIwr52MoiUVTGXmXn3adf+A+Q==" + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@amplitude/analytics-types/-/analytics-types-2.5.0.tgz", + "integrity": "sha512-aY69WxUvVlaCU+9geShjTsAYdUTvegEXH9i4WK/97kNbNLl4/7qUuIPe4hNireDeKLuQA9SA3H7TKynuNomDxw==" }, "@amplitude/plugin-page-view-tracking-browser": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/@amplitude/plugin-page-view-tracking-browser/-/plugin-page-view-tracking-browser-2.1.1.tgz", - "integrity": "sha512-dZwA0kb/dvFTokF2yVklfjwl0Ben6g6Sukpr84tocpurJ7Ojhh1egISCZ4QWt2VgKKh7X4pyK73f5Fcp/1JcNw==", + "version": "2.2.5", + "resolved": "https://registry.npmjs.org/@amplitude/plugin-page-view-tracking-browser/-/plugin-page-view-tracking-browser-2.2.5.tgz", + "integrity": "sha512-uhX1bP57DrvkV3KYWR0NwyTTSBXU3m+LbwBm/0vm4YRLLM1I8dEle+Wb3mN3inbIYOOVyEd3ARR+NS8Xf/hEeQ==", "requires": { - "@amplitude/analytics-client-common": "^2.0.11", - "@amplitude/analytics-types": "^2.4.0", + "@amplitude/analytics-client-common": "^2.1.2", + "@amplitude/analytics-types": "^2.5.0", "tslib": "^2.4.1" }, "dependencies": { @@ -17988,13 +17980,13 @@ } }, "@amplitude/plugin-web-attribution-browser": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/@amplitude/plugin-web-attribution-browser/-/plugin-web-attribution-browser-2.1.1.tgz", - "integrity": "sha512-paWFk+uJeVlUF/HYNoczIxP3IJX/KR573B/E4Wp5bLB3XeJIhRbj3RQdJKhnKN5keg8+Vei/8uGdGQK4d3DYDg==", + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/@amplitude/plugin-web-attribution-browser/-/plugin-web-attribution-browser-2.1.6.tgz", + "integrity": "sha512-3Nds/vfLTBXFi5rLOUF78TL2OkzBAXzJuslSFfSHl7C8psGcpkWTnWcxPakfLHuev3yteknCkWaevdio+GMljg==", "requires": { - "@amplitude/analytics-client-common": "^2.0.11", - "@amplitude/analytics-core": "^2.2.0", - "@amplitude/analytics-types": "^2.4.0", + "@amplitude/analytics-client-common": "^2.1.2", + "@amplitude/analytics-core": "^2.2.3", + "@amplitude/analytics-types": "^2.5.0", "tslib": "^2.4.1" }, "dependencies": { @@ -18026,34 +18018,34 @@ } }, "@babel/code-frame": { - "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.5.tgz", - "integrity": "sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==", + "version": "7.24.2", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.2.tgz", + "integrity": "sha512-y5+tLQyV8pg3fsiln67BVLD1P13Eg4lh5RW9mF0zUuvLrv9uIQ4MCL+CRT+FTsBlBjcIan6PGsLcBN0m3ClUyQ==", "requires": { - "@babel/highlight": "^7.23.4", - "chalk": "^2.4.2" + "@babel/highlight": "^7.24.2", + "picocolors": "^1.0.0" } }, "@babel/compat-data": { - "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.23.5.tgz", - "integrity": "sha512-uU27kfDRlhfKl+w1U6vp16IuvSLtjAxdArVXPa9BvLkrr7CYIsxH5adpHObeAGY/41+syctUWOZ140a2Rvkgjw==" + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.24.1.tgz", + "integrity": "sha512-Pc65opHDliVpRHuKfzI+gSA4zcgr65O4cl64fFJIWEEh8JoHIHh0Oez1Eo8Arz8zq/JhgKodQaxEwUPRtZylVA==" }, "@babel/core": { - "version": "7.23.9", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.23.9.tgz", - "integrity": "sha512-5q0175NOjddqpvvzU+kDiSOAk4PfdO6FvwCWoQ6RO7rTzEe8vlo+4HVfcnAREhD4npMs0e9uZypjTwzZPCf/cw==", + "version": "7.24.3", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.24.3.tgz", + "integrity": "sha512-5FcvN1JHw2sHJChotgx8Ek0lyuh4kCKelgMTTqhYJJtloNvUfpAFMeNQUtdlIaktwrSV9LtCdqwk48wL2wBacQ==", "requires": { "@ampproject/remapping": "^2.2.0", - "@babel/code-frame": "^7.23.5", - "@babel/generator": "^7.23.6", + "@babel/code-frame": "^7.24.2", + "@babel/generator": "^7.24.1", "@babel/helper-compilation-targets": "^7.23.6", "@babel/helper-module-transforms": "^7.23.3", - "@babel/helpers": "^7.23.9", - "@babel/parser": "^7.23.9", - "@babel/template": "^7.23.9", - "@babel/traverse": "^7.23.9", - "@babel/types": "^7.23.9", + "@babel/helpers": "^7.24.1", + "@babel/parser": "^7.24.1", + "@babel/template": "^7.24.0", + "@babel/traverse": "^7.24.1", + "@babel/types": "^7.24.0", "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", @@ -18069,13 +18061,13 @@ } }, "@babel/generator": { - "version": "7.23.6", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.6.tgz", - "integrity": "sha512-qrSfCYxYQB5owCmGLbl8XRpX1ytXlpueOb0N0UmQwA073KZxejgQTzAmJezxvpwQD9uGtK2shHdi55QT+MbjIw==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.24.1.tgz", + "integrity": "sha512-DfCRfZsBcrPEHUfuBMgbJ1Ut01Y/itOs+hY2nFLgqsqXd52/iSiVq5TITtUasIUgm+IIKdY2/1I7auiQOEeC9A==", "requires": { - "@babel/types": "^7.23.6", - "@jridgewell/gen-mapping": "^0.3.2", - "@jridgewell/trace-mapping": "^0.3.17", + "@babel/types": "^7.24.0", + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25", "jsesc": "^2.5.1" } }, @@ -18124,17 +18116,17 @@ } }, "@babel/helper-create-class-features-plugin": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.22.15.tgz", - "integrity": "sha512-jKkwA59IXcvSaiK2UN45kKwSC9o+KuoXsBDvHvU/7BecYIp8GQ2UwrVvFgJASUT+hBnwJx6MhvMCuMzwZZ7jlg==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.24.1.tgz", + "integrity": "sha512-1yJa9dX9g//V6fDebXoEfEsxkZHk3Hcbm+zLhyu6qVgYFLvmTALTeV+jNU9e5RnYtioBrGEOdoI2joMSNQ/+aA==", "dev": true, "requires": { "@babel/helper-annotate-as-pure": "^7.22.5", - "@babel/helper-environment-visitor": "^7.22.5", - "@babel/helper-function-name": "^7.22.5", - "@babel/helper-member-expression-to-functions": "^7.22.15", + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-function-name": "^7.23.0", + "@babel/helper-member-expression-to-functions": "^7.23.0", "@babel/helper-optimise-call-expression": "^7.22.5", - "@babel/helper-replace-supers": "^7.22.9", + "@babel/helper-replace-supers": "^7.24.1", "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", "@babel/helper-split-export-declaration": "^7.22.6", "semver": "^6.3.1" @@ -18196,11 +18188,11 @@ } }, "@babel/helper-module-imports": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.22.15.tgz", - "integrity": "sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==", + "version": "7.24.3", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.24.3.tgz", + "integrity": "sha512-viKb0F9f2s0BCS22QSF308z/+1YWKV/76mwt61NBzS5izMzDPwdq1pTrzf+Li3npBWX9KdQbkeCt1jSAM7lZqg==", "requires": { - "@babel/types": "^7.22.15" + "@babel/types": "^7.24.0" } }, "@babel/helper-module-transforms": { @@ -18225,9 +18217,9 @@ } }, "@babel/helper-plugin-utils": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz", - "integrity": "sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg==" + "version": "7.24.0", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.0.tgz", + "integrity": "sha512-9cUznXMG0+FxRuJfvL82QlTqIzhVW9sL0KjMPHhAOOvpQGL8QtdxnBKILjBqxlHyliz0yCa1G903ZXI/FuHy2w==" }, "@babel/helper-remap-async-to-generator": { "version": "7.22.20", @@ -18241,13 +18233,13 @@ } }, "@babel/helper-replace-supers": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.22.20.tgz", - "integrity": "sha512-qsW0In3dbwQUbK8kejJ4R7IHVGwHJlV6lpG6UA7a9hSa2YEiAib+N1T2kr6PEeUT+Fl7najmSOS6SmAwCHK6Tw==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.24.1.tgz", + "integrity": "sha512-QCR1UqC9BzG5vZl8BMicmZ28RuUBnHhAMddD8yHFHDRH9lLTZ9uUPehX8ctVPT8l0TKblJidqcgUUKGVrePleQ==", "dev": true, "requires": { "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-member-expression-to-functions": "^7.22.15", + "@babel/helper-member-expression-to-functions": "^7.23.0", "@babel/helper-optimise-call-expression": "^7.22.5" } }, @@ -18303,58 +18295,59 @@ } }, "@babel/helpers": { - "version": "7.23.9", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.23.9.tgz", - "integrity": "sha512-87ICKgU5t5SzOT7sBMfCOZQ2rHjRU+Pcb9BoILMYz600W6DkVRLFBPwQ18gwUVvggqXivaUakpnxWQGbpywbBQ==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.24.1.tgz", + "integrity": "sha512-BpU09QqEe6ZCHuIHFphEFgvNSrubve1FtyMton26ekZ85gRGi6LrTF7zArARp2YvyFxloeiRmtSCq5sjh1WqIg==", "requires": { - "@babel/template": "^7.23.9", - "@babel/traverse": "^7.23.9", - "@babel/types": "^7.23.9" + "@babel/template": "^7.24.0", + "@babel/traverse": "^7.24.1", + "@babel/types": "^7.24.0" } }, "@babel/highlight": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.23.4.tgz", - "integrity": "sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==", + "version": "7.24.2", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.2.tgz", + "integrity": "sha512-Yac1ao4flkTxTteCDZLEvdxg2fZfz1v8M4QpaGypq/WPDqg3ijHYbDfs+LG5hvzSoqaSZ9/Z9lKSP3CjZjv+pA==", "requires": { "@babel/helper-validator-identifier": "^7.22.20", "chalk": "^2.4.2", - "js-tokens": "^4.0.0" + "js-tokens": "^4.0.0", + "picocolors": "^1.0.0" } }, "@babel/parser": { - "version": "7.23.9", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.9.tgz", - "integrity": "sha512-9tcKgqKbs3xGJ+NtKF2ndOBBLVwPjl1SHxPQkd36r3Dlirw3xWUeGaTbqr7uGZcTaxkVNwc+03SVP7aCdWrTlA==" + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.1.tgz", + "integrity": "sha512-Zo9c7N3xdOIQrNip7Lc9wvRPzlRtovHVE4lkz8WEDr7uYh/GMQhSiIgFxGIArRHYdJE5kxtZjAf8rT0xhdLCzg==" }, "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.23.3.tgz", - "integrity": "sha512-iRkKcCqb7iGnq9+3G6rZ+Ciz5VywC4XNRHe57lKM+jOeYAoR0lVqdeeDRfh0tQcTfw/+vBhHn926FmQhLtlFLQ==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.24.1.tgz", + "integrity": "sha512-y4HqEnkelJIOQGd+3g1bTeKsA5c6qM7eOn7VggGVbBc0y8MLSKHacwcIE2PplNlQSj0PqS9rrXL/nkPVK+kUNg==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.24.0" } }, "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.23.3.tgz", - "integrity": "sha512-WwlxbfMNdVEpQjZmK5mhm7oSwD3dS6eU+Iwsi4Knl9wAletWem7kaRsGOG+8UEbRyqxY4SS5zvtfXwX+jMxUwQ==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.24.1.tgz", + "integrity": "sha512-Hj791Ii4ci8HqnaKHAlLNs+zaLXb0EzSDhiAWp5VNlyvCNymYfacs64pxTxbH1znW/NcArSmwpmG9IKE/TUVVQ==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-plugin-utils": "^7.24.0", "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", - "@babel/plugin-transform-optional-chaining": "^7.23.3" + "@babel/plugin-transform-optional-chaining": "^7.24.1" } }, "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": { - "version": "7.23.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.23.7.tgz", - "integrity": "sha512-LlRT7HgaifEpQA1ZgLVOIJZZFVPWN5iReq/7/JixwBtwcoeVGDBD53ZV28rrsLYOZs1Y/EHhA8N/Z6aazHR8cw==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.24.1.tgz", + "integrity": "sha512-m9m/fXsXLiHfwdgydIFnpk+7jlVbnvlK5B2EKiPdLUb6WX654ZaaEWJUjk8TftRbZpK0XibovlLWX4KIZhV6jw==", "dev": true, "requires": { "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.24.0" } }, "@babel/plugin-proposal-private-property-in-object": { @@ -18419,21 +18412,21 @@ } }, "@babel/plugin-syntax-import-assertions": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.23.3.tgz", - "integrity": "sha512-lPgDSU+SJLK3xmFDTV2ZRQAiM7UuUjGidwBywFavObCiZc1BeAAcMtHJKUya92hPHO+at63JJPLygilZard8jw==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.24.1.tgz", + "integrity": "sha512-IuwnI5XnuF189t91XbxmXeCDz3qs6iDRO7GJ++wcfgeXNs/8FmIlKcpDSXNVyuLQxlwvskmI3Ct73wUODkJBlQ==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.24.0" } }, "@babel/plugin-syntax-import-attributes": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.23.3.tgz", - "integrity": "sha512-pawnE0P9g10xgoP7yKr6CK63K2FMsTE+FZidZO/1PwRdzmAPVs+HS1mAURUsgaoxammTJvULUdIkEK0gOcU2tA==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.24.1.tgz", + "integrity": "sha512-zhQTMH0X2nVLnb04tz+s7AMuasX8U0FnpE+nHTOhSOINjWMnopoZTxtIKsd45n4GQ/HIZLyfIpoul8e2m0DnRA==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.24.0" } }, "@babel/plugin-syntax-import-meta": { @@ -18555,260 +18548,260 @@ } }, "@babel/plugin-transform-arrow-functions": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.23.3.tgz", - "integrity": "sha512-NzQcQrzaQPkaEwoTm4Mhyl8jI1huEL/WWIEvudjTCMJ9aBZNpsJbMASx7EQECtQQPS/DcnFpo0FIh3LvEO9cxQ==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.24.1.tgz", + "integrity": "sha512-ngT/3NkRhsaep9ck9uj2Xhv9+xB1zShY3tM3g6om4xxCELwCDN4g4Aq5dRn48+0hasAql7s2hdBOysCfNpr4fw==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.24.0" } }, "@babel/plugin-transform-async-generator-functions": { - "version": "7.23.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.23.9.tgz", - "integrity": "sha512-8Q3veQEDGe14dTYuwagbRtwxQDnytyg1JFu4/HwEMETeofocrB0U0ejBJIXoeG/t2oXZ8kzCyI0ZZfbT80VFNQ==", + "version": "7.24.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.24.3.tgz", + "integrity": "sha512-Qe26CMYVjpQxJ8zxM1340JFNjZaF+ISWpr1Kt/jGo+ZTUzKkfw/pphEWbRCb+lmSM6k/TOgfYLvmbHkUQ0asIg==", "dev": true, "requires": { "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-plugin-utils": "^7.24.0", "@babel/helper-remap-async-to-generator": "^7.22.20", "@babel/plugin-syntax-async-generators": "^7.8.4" } }, "@babel/plugin-transform-async-to-generator": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.23.3.tgz", - "integrity": "sha512-A7LFsKi4U4fomjqXJlZg/u0ft/n8/7n7lpffUP/ZULx/DtV9SGlNKZolHH6PE8Xl1ngCc0M11OaeZptXVkfKSw==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.24.1.tgz", + "integrity": "sha512-AawPptitRXp1y0n4ilKcGbRYWfbbzFWz2NqNu7dacYDtFtz0CMjG64b3LQsb3KIgnf4/obcUL78hfaOS7iCUfw==", "dev": true, "requires": { - "@babel/helper-module-imports": "^7.22.15", - "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-module-imports": "^7.24.1", + "@babel/helper-plugin-utils": "^7.24.0", "@babel/helper-remap-async-to-generator": "^7.22.20" } }, "@babel/plugin-transform-block-scoped-functions": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.23.3.tgz", - "integrity": "sha512-vI+0sIaPIO6CNuM9Kk5VmXcMVRiOpDh7w2zZt9GXzmE/9KD70CUEVhvPR/etAeNK/FAEkhxQtXOzVF3EuRL41A==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.24.1.tgz", + "integrity": "sha512-TWWC18OShZutrv9C6mye1xwtam+uNi2bnTOCBUd5sZxyHOiWbU6ztSROofIMrK84uweEZC219POICK/sTYwfgg==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.24.0" } }, "@babel/plugin-transform-block-scoping": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.23.4.tgz", - "integrity": "sha512-0QqbP6B6HOh7/8iNR4CQU2Th/bbRtBp4KS9vcaZd1fZ0wSh5Fyssg0UCIHwxh+ka+pNDREbVLQnHCMHKZfPwfw==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.24.1.tgz", + "integrity": "sha512-h71T2QQvDgM2SmT29UYU6ozjMlAt7s7CSs5Hvy8f8cf/GM/Z4a2zMfN+fjVGaieeCrXR3EdQl6C4gQG+OgmbKw==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.24.0" } }, "@babel/plugin-transform-class-properties": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.23.3.tgz", - "integrity": "sha512-uM+AN8yCIjDPccsKGlw271xjJtGii+xQIF/uMPS8H15L12jZTsLfF4o5vNO7d/oUguOyfdikHGc/yi9ge4SGIg==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.24.1.tgz", + "integrity": "sha512-OMLCXi0NqvJfORTaPQBwqLXHhb93wkBKZ4aNwMl6WtehO7ar+cmp+89iPEQPqxAnxsOKTaMcs3POz3rKayJ72g==", "dev": true, "requires": { - "@babel/helper-create-class-features-plugin": "^7.22.15", - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-create-class-features-plugin": "^7.24.1", + "@babel/helper-plugin-utils": "^7.24.0" } }, "@babel/plugin-transform-class-static-block": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.23.4.tgz", - "integrity": "sha512-nsWu/1M+ggti1SOALj3hfx5FXzAY06fwPJsUZD4/A5e1bWi46VUIWtD+kOX6/IdhXGsXBWllLFDSnqSCdUNydQ==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.24.1.tgz", + "integrity": "sha512-FUHlKCn6J3ERiu8Dv+4eoz7w8+kFLSyeVG4vDAikwADGjUCoHw/JHokyGtr8OR4UjpwPVivyF+h8Q5iv/JmrtA==", "dev": true, "requires": { - "@babel/helper-create-class-features-plugin": "^7.22.15", - "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-create-class-features-plugin": "^7.24.1", + "@babel/helper-plugin-utils": "^7.24.0", "@babel/plugin-syntax-class-static-block": "^7.14.5" } }, "@babel/plugin-transform-classes": { - "version": "7.23.8", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.23.8.tgz", - "integrity": "sha512-yAYslGsY1bX6Knmg46RjiCiNSwJKv2IUC8qOdYKqMMr0491SXFhcHqOdRDeCRohOOIzwN/90C6mQ9qAKgrP7dg==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.24.1.tgz", + "integrity": "sha512-ZTIe3W7UejJd3/3R4p7ScyyOoafetUShSf4kCqV0O7F/RiHxVj/wRaRnQlrGwflvcehNA8M42HkAiEDYZu2F1Q==", "dev": true, "requires": { "@babel/helper-annotate-as-pure": "^7.22.5", "@babel/helper-compilation-targets": "^7.23.6", "@babel/helper-environment-visitor": "^7.22.20", "@babel/helper-function-name": "^7.23.0", - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/helper-replace-supers": "^7.22.20", + "@babel/helper-plugin-utils": "^7.24.0", + "@babel/helper-replace-supers": "^7.24.1", "@babel/helper-split-export-declaration": "^7.22.6", "globals": "^11.1.0" } }, "@babel/plugin-transform-computed-properties": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.23.3.tgz", - "integrity": "sha512-dTj83UVTLw/+nbiHqQSFdwO9CbTtwq1DsDqm3CUEtDrZNET5rT5E6bIdTlOftDTDLMYxvxHNEYO4B9SLl8SLZw==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.24.1.tgz", + "integrity": "sha512-5pJGVIUfJpOS+pAqBQd+QMaTD2vCL/HcePooON6pDpHgRp4gNRmzyHTPIkXntwKsq3ayUFVfJaIKPw2pOkOcTw==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/template": "^7.22.15" + "@babel/helper-plugin-utils": "^7.24.0", + "@babel/template": "^7.24.0" } }, "@babel/plugin-transform-destructuring": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.23.3.tgz", - "integrity": "sha512-n225npDqjDIr967cMScVKHXJs7rout1q+tt50inyBCPkyZ8KxeI6d+GIbSBTT/w/9WdlWDOej3V9HE5Lgk57gw==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.24.1.tgz", + "integrity": "sha512-ow8jciWqNxR3RYbSNVuF4U2Jx130nwnBnhRw6N6h1bOejNkABmcI5X5oz29K4alWX7vf1C+o6gtKXikzRKkVdw==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.24.0" } }, "@babel/plugin-transform-dotall-regex": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.23.3.tgz", - "integrity": "sha512-vgnFYDHAKzFaTVp+mneDsIEbnJ2Np/9ng9iviHw3P/KVcgONxpNULEW/51Z/BaFojG2GI2GwwXck5uV1+1NOYQ==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.24.1.tgz", + "integrity": "sha512-p7uUxgSoZwZ2lPNMzUkqCts3xlp8n+o05ikjy7gbtFJSt9gdU88jAmtfmOxHM14noQXBxfgzf2yRWECiNVhTCw==", "dev": true, "requires": { "@babel/helper-create-regexp-features-plugin": "^7.22.15", - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.24.0" } }, "@babel/plugin-transform-duplicate-keys": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.23.3.tgz", - "integrity": "sha512-RrqQ+BQmU3Oyav3J+7/myfvRCq7Tbz+kKLLshUmMwNlDHExbGL7ARhajvoBJEvc+fCguPPu887N+3RRXBVKZUA==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.24.1.tgz", + "integrity": "sha512-msyzuUnvsjsaSaocV6L7ErfNsa5nDWL1XKNnDePLgmz+WdU4w/J8+AxBMrWfi9m4IxfL5sZQKUPQKDQeeAT6lA==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.24.0" } }, "@babel/plugin-transform-dynamic-import": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.23.4.tgz", - "integrity": "sha512-V6jIbLhdJK86MaLh4Jpghi8ho5fGzt3imHOBu/x0jlBaPYqDoWz4RDXjmMOfnh+JWNaQleEAByZLV0QzBT4YQQ==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.24.1.tgz", + "integrity": "sha512-av2gdSTyXcJVdI+8aFZsCAtR29xJt0S5tas+Ef8NvBNmD1a+N/3ecMLeMBgfcK+xzsjdLDT6oHt+DFPyeqUbDA==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-plugin-utils": "^7.24.0", "@babel/plugin-syntax-dynamic-import": "^7.8.3" } }, "@babel/plugin-transform-exponentiation-operator": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.23.3.tgz", - "integrity": "sha512-5fhCsl1odX96u7ILKHBj4/Y8vipoqwsJMh4csSA8qFfxrZDEA4Ssku2DyNvMJSmZNOEBT750LfFPbtrnTP90BQ==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.24.1.tgz", + "integrity": "sha512-U1yX13dVBSwS23DEAqU+Z/PkwE9/m7QQy8Y9/+Tdb8UWYaGNDYwTLi19wqIAiROr8sXVum9A/rtiH5H0boUcTw==", "dev": true, "requires": { "@babel/helper-builder-binary-assignment-operator-visitor": "^7.22.15", - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.24.0" } }, "@babel/plugin-transform-export-namespace-from": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.23.4.tgz", - "integrity": "sha512-GzuSBcKkx62dGzZI1WVgTWvkkz84FZO5TC5T8dl/Tht/rAla6Dg/Mz9Yhypg+ezVACf/rgDuQt3kbWEv7LdUDQ==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.24.1.tgz", + "integrity": "sha512-Ft38m/KFOyzKw2UaJFkWG9QnHPG/Q/2SkOrRk4pNBPg5IPZ+dOxcmkK5IyuBcxiNPyyYowPGUReyBvrvZs7IlQ==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-plugin-utils": "^7.24.0", "@babel/plugin-syntax-export-namespace-from": "^7.8.3" } }, "@babel/plugin-transform-for-of": { - "version": "7.23.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.23.6.tgz", - "integrity": "sha512-aYH4ytZ0qSuBbpfhuofbg/e96oQ7U2w1Aw/UQmKT+1l39uEhUPoFS3fHevDc1G0OvewyDudfMKY1OulczHzWIw==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.24.1.tgz", + "integrity": "sha512-OxBdcnF04bpdQdR3i4giHZNZQn7cm8RQKcSwA17wAAqEELo1ZOwp5FFgeptWUQXFyT9kwHo10aqqauYkRZPCAg==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-plugin-utils": "^7.24.0", "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5" } }, "@babel/plugin-transform-function-name": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.23.3.tgz", - "integrity": "sha512-I1QXp1LxIvt8yLaib49dRW5Okt7Q4oaxao6tFVKS/anCdEOMtYwWVKoiOA1p34GOWIZjUK0E+zCp7+l1pfQyiw==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.24.1.tgz", + "integrity": "sha512-BXmDZpPlh7jwicKArQASrj8n22/w6iymRnvHYYd2zO30DbE277JO20/7yXJT3QxDPtiQiOxQBbZH4TpivNXIxA==", "dev": true, "requires": { - "@babel/helper-compilation-targets": "^7.22.15", + "@babel/helper-compilation-targets": "^7.23.6", "@babel/helper-function-name": "^7.23.0", - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.24.0" } }, "@babel/plugin-transform-json-strings": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.23.4.tgz", - "integrity": "sha512-81nTOqM1dMwZ/aRXQ59zVubN9wHGqk6UtqRK+/q+ciXmRy8fSolhGVvG09HHRGo4l6fr/c4ZhXUQH0uFW7PZbg==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.24.1.tgz", + "integrity": "sha512-U7RMFmRvoasscrIFy5xA4gIp8iWnWubnKkKuUGJjsuOH7GfbMkB+XZzeslx2kLdEGdOJDamEmCqOks6e8nv8DQ==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-plugin-utils": "^7.24.0", "@babel/plugin-syntax-json-strings": "^7.8.3" } }, "@babel/plugin-transform-literals": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.23.3.tgz", - "integrity": "sha512-wZ0PIXRxnwZvl9AYpqNUxpZ5BiTGrYt7kueGQ+N5FiQ7RCOD4cm8iShd6S6ggfVIWaJf2EMk8eRzAh52RfP4rQ==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.24.1.tgz", + "integrity": "sha512-zn9pwz8U7nCqOYIiBaOxoQOtYmMODXTJnkxG4AtX8fPmnCRYWBOHD0qcpwS9e2VDSp1zNJYpdnFMIKb8jmwu6g==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.24.0" } }, "@babel/plugin-transform-logical-assignment-operators": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.23.4.tgz", - "integrity": "sha512-Mc/ALf1rmZTP4JKKEhUwiORU+vcfarFVLfcFiolKUo6sewoxSEgl36ak5t+4WamRsNr6nzjZXQjM35WsU+9vbg==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.24.1.tgz", + "integrity": "sha512-OhN6J4Bpz+hIBqItTeWJujDOfNP+unqv/NJgyhlpSqgBTPm37KkMmZV6SYcOj+pnDbdcl1qRGV/ZiIjX9Iy34w==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-plugin-utils": "^7.24.0", "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" } }, "@babel/plugin-transform-member-expression-literals": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.23.3.tgz", - "integrity": "sha512-sC3LdDBDi5x96LA+Ytekz2ZPk8i/Ck+DEuDbRAll5rknJ5XRTSaPKEYwomLcs1AA8wg9b3KjIQRsnApj+q51Ag==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.24.1.tgz", + "integrity": "sha512-4ojai0KysTWXzHseJKa1XPNXKRbuUrhkOPY4rEGeR+7ChlJVKxFa3H3Bz+7tWaGKgJAXUWKOGmltN+u9B3+CVg==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.24.0" } }, "@babel/plugin-transform-modules-amd": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.23.3.tgz", - "integrity": "sha512-vJYQGxeKM4t8hYCKVBlZX/gtIY2I7mRGFNcm85sgXGMTBcoV3QdVtdpbcWEbzbfUIUZKwvgFT82mRvaQIebZzw==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.24.1.tgz", + "integrity": "sha512-lAxNHi4HVtjnHd5Rxg3D5t99Xm6H7b04hUS7EHIXcUl2EV4yl1gWdqZrNzXnSrHveL9qMdbODlLF55mvgjAfaQ==", "dev": true, "requires": { "@babel/helper-module-transforms": "^7.23.3", - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.24.0" } }, "@babel/plugin-transform-modules-commonjs": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.23.3.tgz", - "integrity": "sha512-aVS0F65LKsdNOtcz6FRCpE4OgsP2OFnW46qNxNIX9h3wuzaNcSQsJysuMwqSibC98HPrf2vCgtxKNwS0DAlgcA==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.24.1.tgz", + "integrity": "sha512-szog8fFTUxBfw0b98gEWPaEqF42ZUD/T3bkynW/wtgx2p/XCP55WEsb+VosKceRSd6njipdZvNogqdtI4Q0chw==", "dev": true, "requires": { "@babel/helper-module-transforms": "^7.23.3", - "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-plugin-utils": "^7.24.0", "@babel/helper-simple-access": "^7.22.5" } }, "@babel/plugin-transform-modules-systemjs": { - "version": "7.23.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.23.9.tgz", - "integrity": "sha512-KDlPRM6sLo4o1FkiSlXoAa8edLXFsKKIda779fbLrvmeuc3itnjCtaO6RrtoaANsIJANj+Vk1zqbZIMhkCAHVw==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.24.1.tgz", + "integrity": "sha512-mqQ3Zh9vFO1Tpmlt8QPnbwGHzNz3lpNEMxQb1kAemn/erstyqw1r9KeOlOfo3y6xAnFEcOv2tSyrXfmMk+/YZA==", "dev": true, "requires": { "@babel/helper-hoist-variables": "^7.22.5", "@babel/helper-module-transforms": "^7.23.3", - "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-plugin-utils": "^7.24.0", "@babel/helper-validator-identifier": "^7.22.20" } }, "@babel/plugin-transform-modules-umd": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.23.3.tgz", - "integrity": "sha512-zHsy9iXX2nIsCBFPud3jKn1IRPWg3Ing1qOZgeKV39m1ZgIdpJqvlWVeiHBZC6ITRG0MfskhYe9cLgntfSFPIg==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.24.1.tgz", + "integrity": "sha512-tuA3lpPj+5ITfcCluy6nWonSL7RvaG0AOTeAuvXqEKS34lnLzXpDb0dcP6K8jD0zWZFNDVly90AGFJPnm4fOYg==", "dev": true, "requires": { "@babel/helper-module-transforms": "^7.23.3", - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.24.0" } }, "@babel/plugin-transform-named-capturing-groups-regex": { @@ -18822,135 +18815,134 @@ } }, "@babel/plugin-transform-new-target": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.23.3.tgz", - "integrity": "sha512-YJ3xKqtJMAT5/TIZnpAR3I+K+WaDowYbN3xyxI8zxx/Gsypwf9B9h0VB+1Nh6ACAAPRS5NSRje0uVv5i79HYGQ==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.24.1.tgz", + "integrity": "sha512-/rurytBM34hYy0HKZQyA0nHbQgQNFm4Q/BOc9Hflxi2X3twRof7NaE5W46j4kQitm7SvACVRXsa6N/tSZxvPug==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.24.0" } }, "@babel/plugin-transform-nullish-coalescing-operator": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.23.4.tgz", - "integrity": "sha512-jHE9EVVqHKAQx+VePv5LLGHjmHSJR76vawFPTdlxR/LVJPfOEGxREQwQfjuZEOPTwG92X3LINSh3M40Rv4zpVA==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.24.1.tgz", + "integrity": "sha512-iQ+caew8wRrhCikO5DrUYx0mrmdhkaELgFa+7baMcVuhxIkN7oxt06CZ51D65ugIb1UWRQ8oQe+HXAVM6qHFjw==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-plugin-utils": "^7.24.0", "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" } }, "@babel/plugin-transform-numeric-separator": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.23.4.tgz", - "integrity": "sha512-mps6auzgwjRrwKEZA05cOwuDc9FAzoyFS4ZsG/8F43bTLf/TgkJg7QXOrPO1JO599iA3qgK9MXdMGOEC8O1h6Q==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.24.1.tgz", + "integrity": "sha512-7GAsGlK4cNL2OExJH1DzmDeKnRv/LXq0eLUSvudrehVA5Rgg4bIrqEUW29FbKMBRT0ztSqisv7kjP+XIC4ZMNw==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-plugin-utils": "^7.24.0", "@babel/plugin-syntax-numeric-separator": "^7.10.4" } }, "@babel/plugin-transform-object-rest-spread": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.23.4.tgz", - "integrity": "sha512-9x9K1YyeQVw0iOXJlIzwm8ltobIIv7j2iLyP2jIhEbqPRQ7ScNgwQufU2I0Gq11VjyG4gI4yMXt2VFags+1N3g==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.24.1.tgz", + "integrity": "sha512-XjD5f0YqOtebto4HGISLNfiNMTTs6tbkFf2TOqJlYKYmbo+mN9Dnpl4SRoofiziuOWMIyq3sZEUqLo3hLITFEA==", "dev": true, "requires": { - "@babel/compat-data": "^7.23.3", - "@babel/helper-compilation-targets": "^7.22.15", - "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-compilation-targets": "^7.23.6", + "@babel/helper-plugin-utils": "^7.24.0", "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-transform-parameters": "^7.23.3" + "@babel/plugin-transform-parameters": "^7.24.1" } }, "@babel/plugin-transform-object-super": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.23.3.tgz", - "integrity": "sha512-BwQ8q0x2JG+3lxCVFohg+KbQM7plfpBwThdW9A6TMtWwLsbDA01Ek2Zb/AgDN39BiZsExm4qrXxjk+P1/fzGrA==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.24.1.tgz", + "integrity": "sha512-oKJqR3TeI5hSLRxudMjFQ9re9fBVUU0GICqM3J1mi8MqlhVr6hC/ZN4ttAyMuQR6EZZIY6h/exe5swqGNNIkWQ==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/helper-replace-supers": "^7.22.20" + "@babel/helper-plugin-utils": "^7.24.0", + "@babel/helper-replace-supers": "^7.24.1" } }, "@babel/plugin-transform-optional-catch-binding": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.23.4.tgz", - "integrity": "sha512-XIq8t0rJPHf6Wvmbn9nFxU6ao4c7WhghTR5WyV8SrJfUFzyxhCm4nhC+iAp3HFhbAKLfYpgzhJ6t4XCtVwqO5A==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.24.1.tgz", + "integrity": "sha512-oBTH7oURV4Y+3EUrf6cWn1OHio3qG/PVwO5J03iSJmBg6m2EhKjkAu/xuaXaYwWW9miYtvbWv4LNf0AmR43LUA==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-plugin-utils": "^7.24.0", "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" } }, "@babel/plugin-transform-optional-chaining": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.23.4.tgz", - "integrity": "sha512-ZU8y5zWOfjM5vZ+asjgAPwDaBjJzgufjES89Rs4Lpq63O300R/kOz30WCLo6BxxX6QVEilwSlpClnG5cZaikTA==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.24.1.tgz", + "integrity": "sha512-n03wmDt+987qXwAgcBlnUUivrZBPZ8z1plL0YvgQalLm+ZE5BMhGm94jhxXtA1wzv1Cu2aaOv1BM9vbVttrzSg==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-plugin-utils": "^7.24.0", "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", "@babel/plugin-syntax-optional-chaining": "^7.8.3" } }, "@babel/plugin-transform-parameters": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.23.3.tgz", - "integrity": "sha512-09lMt6UsUb3/34BbECKVbVwrT9bO6lILWln237z7sLaWnMsTi7Yc9fhX5DLpkJzAGfaReXI22wP41SZmnAA3Vw==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.24.1.tgz", + "integrity": "sha512-8Jl6V24g+Uw5OGPeWNKrKqXPDw2YDjLc53ojwfMcKwlEoETKU9rU0mHUtcg9JntWI/QYzGAXNWEcVHZ+fR+XXg==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.24.0" } }, "@babel/plugin-transform-private-methods": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.23.3.tgz", - "integrity": "sha512-UzqRcRtWsDMTLrRWFvUBDwmw06tCQH9Rl1uAjfh6ijMSmGYQ+fpdB+cnqRC8EMh5tuuxSv0/TejGL+7vyj+50g==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.24.1.tgz", + "integrity": "sha512-tGvisebwBO5em4PaYNqt4fkw56K2VALsAbAakY0FjTYqJp7gfdrgr7YX76Or8/cpik0W6+tj3rZ0uHU9Oil4tw==", "dev": true, "requires": { - "@babel/helper-create-class-features-plugin": "^7.22.15", - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-create-class-features-plugin": "^7.24.1", + "@babel/helper-plugin-utils": "^7.24.0" } }, "@babel/plugin-transform-private-property-in-object": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.23.4.tgz", - "integrity": "sha512-9G3K1YqTq3F4Vt88Djx1UZ79PDyj+yKRnUy7cZGSMe+a7jkwD259uKKuUzQlPkGam7R+8RJwh5z4xO27fA1o2A==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.24.1.tgz", + "integrity": "sha512-pTHxDVa0BpUbvAgX3Gat+7cSciXqUcY9j2VZKTbSB6+VQGpNgNO9ailxTGHSXlqOnX1Hcx1Enme2+yv7VqP9bg==", "dev": true, "requires": { "@babel/helper-annotate-as-pure": "^7.22.5", - "@babel/helper-create-class-features-plugin": "^7.22.15", - "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-create-class-features-plugin": "^7.24.1", + "@babel/helper-plugin-utils": "^7.24.0", "@babel/plugin-syntax-private-property-in-object": "^7.14.5" } }, "@babel/plugin-transform-property-literals": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.23.3.tgz", - "integrity": "sha512-jR3Jn3y7cZp4oEWPFAlRsSWjxKe4PZILGBSd4nis1TsC5qeSpb+nrtihJuDhNI7QHiVbUaiXa0X2RZY3/TI6Nw==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.24.1.tgz", + "integrity": "sha512-LetvD7CrHmEx0G442gOomRr66d7q8HzzGGr4PMHGr+5YIm6++Yke+jxj246rpvsbyhJwCLxcTn6zW1P1BSenqA==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.24.0" } }, "@babel/plugin-transform-regenerator": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.23.3.tgz", - "integrity": "sha512-KP+75h0KghBMcVpuKisx3XTu9Ncut8Q8TuvGO4IhY+9D5DFEckQefOuIsB/gQ2tG71lCke4NMrtIPS8pOj18BQ==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.24.1.tgz", + "integrity": "sha512-sJwZBCzIBE4t+5Q4IGLaaun5ExVMRY0lYwos/jNecjMrVCygCdph3IKv0tkP5Fc87e/1+bebAmEAGBfnRD+cnw==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-plugin-utils": "^7.24.0", "regenerator-transform": "^0.15.2" } }, "@babel/plugin-transform-reserved-words": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.23.3.tgz", - "integrity": "sha512-QnNTazY54YqgGxwIexMZva9gqbPa15t/x9VS+0fsEFWplwVpXYZivtgl43Z1vMpc1bdPP2PP8siFeVcnFvA3Cg==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.24.1.tgz", + "integrity": "sha512-JAclqStUfIwKN15HrsQADFgeZt+wexNQ0uLhuqvqAUFoqPMjEcFCYZBhq0LUdz6dZK/mD+rErhW71fbx8RYElg==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.24.0" } }, "@babel/plugin-transform-runtime": { @@ -18978,111 +18970,111 @@ } }, "@babel/plugin-transform-shorthand-properties": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.23.3.tgz", - "integrity": "sha512-ED2fgqZLmexWiN+YNFX26fx4gh5qHDhn1O2gvEhreLW2iI63Sqm4llRLCXALKrCnbN4Jy0VcMQZl/SAzqug/jg==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.24.1.tgz", + "integrity": "sha512-LyjVB1nsJ6gTTUKRjRWx9C1s9hE7dLfP/knKdrfeH9UPtAGjYGgxIbFfx7xyLIEWs7Xe1Gnf8EWiUqfjLhInZA==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.24.0" } }, "@babel/plugin-transform-spread": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.23.3.tgz", - "integrity": "sha512-VvfVYlrlBVu+77xVTOAoxQ6mZbnIq5FM0aGBSFEcIh03qHf+zNqA4DC/3XMUozTg7bZV3e3mZQ0i13VB6v5yUg==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.24.1.tgz", + "integrity": "sha512-KjmcIM+fxgY+KxPVbjelJC6hrH1CgtPmTvdXAfn3/a9CnWGSTY7nH4zm5+cjmWJybdcPSsD0++QssDsjcpe47g==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-plugin-utils": "^7.24.0", "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5" } }, "@babel/plugin-transform-sticky-regex": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.23.3.tgz", - "integrity": "sha512-HZOyN9g+rtvnOU3Yh7kSxXrKbzgrm5X4GncPY1QOquu7epga5MxKHVpYu2hvQnry/H+JjckSYRb93iNfsioAGg==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.24.1.tgz", + "integrity": "sha512-9v0f1bRXgPVcPrngOQvLXeGNNVLc8UjMVfebo9ka0WF3/7+aVUHmaJVT3sa0XCzEFioPfPHZiOcYG9qOsH63cw==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.24.0" } }, "@babel/plugin-transform-template-literals": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.23.3.tgz", - "integrity": "sha512-Flok06AYNp7GV2oJPZZcP9vZdszev6vPBkHLwxwSpaIqx75wn6mUd3UFWsSsA0l8nXAKkyCmL/sR02m8RYGeHg==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.24.1.tgz", + "integrity": "sha512-WRkhROsNzriarqECASCNu/nojeXCDTE/F2HmRgOzi7NGvyfYGq1NEjKBK3ckLfRgGc6/lPAqP0vDOSw3YtG34g==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.24.0" } }, "@babel/plugin-transform-typeof-symbol": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.23.3.tgz", - "integrity": "sha512-4t15ViVnaFdrPC74be1gXBSMzXk3B4Us9lP7uLRQHTFpV5Dvt33pn+2MyyNxmN3VTTm3oTrZVMUmuw3oBnQ2oQ==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.24.1.tgz", + "integrity": "sha512-CBfU4l/A+KruSUoW+vTQthwcAdwuqbpRNB8HQKlZABwHRhsdHZ9fezp4Sn18PeAlYxTNiLMlx4xUBV3AWfg1BA==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.24.0" } }, "@babel/plugin-transform-unicode-escapes": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.23.3.tgz", - "integrity": "sha512-OMCUx/bU6ChE3r4+ZdylEqAjaQgHAgipgW8nsCfu5pGqDcFytVd91AwRvUJSBZDz0exPGgnjoqhgRYLRjFZc9Q==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.24.1.tgz", + "integrity": "sha512-RlkVIcWT4TLI96zM660S877E7beKlQw7Ig+wqkKBiWfj0zH5Q4h50q6er4wzZKRNSYpfo6ILJ+hrJAGSX2qcNw==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.24.0" } }, "@babel/plugin-transform-unicode-property-regex": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.23.3.tgz", - "integrity": "sha512-KcLIm+pDZkWZQAFJ9pdfmh89EwVfmNovFBcXko8szpBeF8z68kWIPeKlmSOkT9BXJxs2C0uk+5LxoxIv62MROA==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.24.1.tgz", + "integrity": "sha512-Ss4VvlfYV5huWApFsF8/Sq0oXnGO+jB+rijFEFugTd3cwSObUSnUi88djgR5528Csl0uKlrI331kRqe56Ov2Ng==", "dev": true, "requires": { "@babel/helper-create-regexp-features-plugin": "^7.22.15", - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.24.0" } }, "@babel/plugin-transform-unicode-regex": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.23.3.tgz", - "integrity": "sha512-wMHpNA4x2cIA32b/ci3AfwNgheiva2W0WUKWTK7vBHBhDKfPsc5cFGNWm69WBqpwd86u1qwZ9PWevKqm1A3yAw==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.24.1.tgz", + "integrity": "sha512-2A/94wgZgxfTsiLaQ2E36XAOdcZmGAaEEgVmxQWwZXWkGhvoHbaqXcKnU8zny4ycpu3vNqg0L/PcCiYtHtA13g==", "dev": true, "requires": { "@babel/helper-create-regexp-features-plugin": "^7.22.15", - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.24.0" } }, "@babel/plugin-transform-unicode-sets-regex": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.23.3.tgz", - "integrity": "sha512-W7lliA/v9bNR83Qc3q1ip9CQMZ09CcHDbHfbLRDNuAhn1Mvkr1ZNF7hPmztMQvtTGVLJ9m8IZqWsTkXOml8dbw==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.24.1.tgz", + "integrity": "sha512-fqj4WuzzS+ukpgerpAoOnMfQXwUHFxXUZUE84oL2Kao2N8uSlvcpnAidKASgsNgzZHBsHWvcm8s9FPWUhAb8fA==", "dev": true, "requires": { "@babel/helper-create-regexp-features-plugin": "^7.22.15", - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.24.0" } }, "@babel/preset-env": { - "version": "7.23.9", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.23.9.tgz", - "integrity": "sha512-3kBGTNBBk9DQiPoXYS0g0BYlwTQYUTifqgKTjxUwEUkduRT2QOa0FPGBJ+NROQhGyYO5BuTJwGvBnqKDykac6A==", + "version": "7.24.3", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.24.3.tgz", + "integrity": "sha512-fSk430k5c2ff8536JcPvPWK4tZDwehWLGlBp0wrsBUjZVdeQV6lePbwKWZaZfK2vnh/1kQX1PzAJWsnBmVgGJA==", "dev": true, "requires": { - "@babel/compat-data": "^7.23.5", + "@babel/compat-data": "^7.24.1", "@babel/helper-compilation-targets": "^7.23.6", - "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-plugin-utils": "^7.24.0", "@babel/helper-validator-option": "^7.23.5", - "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.23.3", - "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.23.3", - "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.23.7", + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.24.1", + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.24.1", + "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.24.1", "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2", "@babel/plugin-syntax-async-generators": "^7.8.4", "@babel/plugin-syntax-class-properties": "^7.12.13", "@babel/plugin-syntax-class-static-block": "^7.14.5", "@babel/plugin-syntax-dynamic-import": "^7.8.3", "@babel/plugin-syntax-export-namespace-from": "^7.8.3", - "@babel/plugin-syntax-import-assertions": "^7.23.3", - "@babel/plugin-syntax-import-attributes": "^7.23.3", + "@babel/plugin-syntax-import-assertions": "^7.24.1", + "@babel/plugin-syntax-import-attributes": "^7.24.1", "@babel/plugin-syntax-import-meta": "^7.10.4", "@babel/plugin-syntax-json-strings": "^7.8.3", "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", @@ -19094,66 +19086,66 @@ "@babel/plugin-syntax-private-property-in-object": "^7.14.5", "@babel/plugin-syntax-top-level-await": "^7.14.5", "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6", - "@babel/plugin-transform-arrow-functions": "^7.23.3", - "@babel/plugin-transform-async-generator-functions": "^7.23.9", - "@babel/plugin-transform-async-to-generator": "^7.23.3", - "@babel/plugin-transform-block-scoped-functions": "^7.23.3", - "@babel/plugin-transform-block-scoping": "^7.23.4", - "@babel/plugin-transform-class-properties": "^7.23.3", - "@babel/plugin-transform-class-static-block": "^7.23.4", - "@babel/plugin-transform-classes": "^7.23.8", - "@babel/plugin-transform-computed-properties": "^7.23.3", - "@babel/plugin-transform-destructuring": "^7.23.3", - "@babel/plugin-transform-dotall-regex": "^7.23.3", - "@babel/plugin-transform-duplicate-keys": "^7.23.3", - "@babel/plugin-transform-dynamic-import": "^7.23.4", - "@babel/plugin-transform-exponentiation-operator": "^7.23.3", - "@babel/plugin-transform-export-namespace-from": "^7.23.4", - "@babel/plugin-transform-for-of": "^7.23.6", - "@babel/plugin-transform-function-name": "^7.23.3", - "@babel/plugin-transform-json-strings": "^7.23.4", - "@babel/plugin-transform-literals": "^7.23.3", - "@babel/plugin-transform-logical-assignment-operators": "^7.23.4", - "@babel/plugin-transform-member-expression-literals": "^7.23.3", - "@babel/plugin-transform-modules-amd": "^7.23.3", - "@babel/plugin-transform-modules-commonjs": "^7.23.3", - "@babel/plugin-transform-modules-systemjs": "^7.23.9", - "@babel/plugin-transform-modules-umd": "^7.23.3", + "@babel/plugin-transform-arrow-functions": "^7.24.1", + "@babel/plugin-transform-async-generator-functions": "^7.24.3", + "@babel/plugin-transform-async-to-generator": "^7.24.1", + "@babel/plugin-transform-block-scoped-functions": "^7.24.1", + "@babel/plugin-transform-block-scoping": "^7.24.1", + "@babel/plugin-transform-class-properties": "^7.24.1", + "@babel/plugin-transform-class-static-block": "^7.24.1", + "@babel/plugin-transform-classes": "^7.24.1", + "@babel/plugin-transform-computed-properties": "^7.24.1", + "@babel/plugin-transform-destructuring": "^7.24.1", + "@babel/plugin-transform-dotall-regex": "^7.24.1", + "@babel/plugin-transform-duplicate-keys": "^7.24.1", + "@babel/plugin-transform-dynamic-import": "^7.24.1", + "@babel/plugin-transform-exponentiation-operator": "^7.24.1", + "@babel/plugin-transform-export-namespace-from": "^7.24.1", + "@babel/plugin-transform-for-of": "^7.24.1", + "@babel/plugin-transform-function-name": "^7.24.1", + "@babel/plugin-transform-json-strings": "^7.24.1", + "@babel/plugin-transform-literals": "^7.24.1", + "@babel/plugin-transform-logical-assignment-operators": "^7.24.1", + "@babel/plugin-transform-member-expression-literals": "^7.24.1", + "@babel/plugin-transform-modules-amd": "^7.24.1", + "@babel/plugin-transform-modules-commonjs": "^7.24.1", + "@babel/plugin-transform-modules-systemjs": "^7.24.1", + "@babel/plugin-transform-modules-umd": "^7.24.1", "@babel/plugin-transform-named-capturing-groups-regex": "^7.22.5", - "@babel/plugin-transform-new-target": "^7.23.3", - "@babel/plugin-transform-nullish-coalescing-operator": "^7.23.4", - "@babel/plugin-transform-numeric-separator": "^7.23.4", - "@babel/plugin-transform-object-rest-spread": "^7.23.4", - "@babel/plugin-transform-object-super": "^7.23.3", - "@babel/plugin-transform-optional-catch-binding": "^7.23.4", - "@babel/plugin-transform-optional-chaining": "^7.23.4", - "@babel/plugin-transform-parameters": "^7.23.3", - "@babel/plugin-transform-private-methods": "^7.23.3", - "@babel/plugin-transform-private-property-in-object": "^7.23.4", - "@babel/plugin-transform-property-literals": "^7.23.3", - "@babel/plugin-transform-regenerator": "^7.23.3", - "@babel/plugin-transform-reserved-words": "^7.23.3", - "@babel/plugin-transform-shorthand-properties": "^7.23.3", - "@babel/plugin-transform-spread": "^7.23.3", - "@babel/plugin-transform-sticky-regex": "^7.23.3", - "@babel/plugin-transform-template-literals": "^7.23.3", - "@babel/plugin-transform-typeof-symbol": "^7.23.3", - "@babel/plugin-transform-unicode-escapes": "^7.23.3", - "@babel/plugin-transform-unicode-property-regex": "^7.23.3", - "@babel/plugin-transform-unicode-regex": "^7.23.3", - "@babel/plugin-transform-unicode-sets-regex": "^7.23.3", + "@babel/plugin-transform-new-target": "^7.24.1", + "@babel/plugin-transform-nullish-coalescing-operator": "^7.24.1", + "@babel/plugin-transform-numeric-separator": "^7.24.1", + "@babel/plugin-transform-object-rest-spread": "^7.24.1", + "@babel/plugin-transform-object-super": "^7.24.1", + "@babel/plugin-transform-optional-catch-binding": "^7.24.1", + "@babel/plugin-transform-optional-chaining": "^7.24.1", + "@babel/plugin-transform-parameters": "^7.24.1", + "@babel/plugin-transform-private-methods": "^7.24.1", + "@babel/plugin-transform-private-property-in-object": "^7.24.1", + "@babel/plugin-transform-property-literals": "^7.24.1", + "@babel/plugin-transform-regenerator": "^7.24.1", + "@babel/plugin-transform-reserved-words": "^7.24.1", + "@babel/plugin-transform-shorthand-properties": "^7.24.1", + "@babel/plugin-transform-spread": "^7.24.1", + "@babel/plugin-transform-sticky-regex": "^7.24.1", + "@babel/plugin-transform-template-literals": "^7.24.1", + "@babel/plugin-transform-typeof-symbol": "^7.24.1", + "@babel/plugin-transform-unicode-escapes": "^7.24.1", + "@babel/plugin-transform-unicode-property-regex": "^7.24.1", + "@babel/plugin-transform-unicode-regex": "^7.24.1", + "@babel/plugin-transform-unicode-sets-regex": "^7.24.1", "@babel/preset-modules": "0.1.6-no-external-plugins", - "babel-plugin-polyfill-corejs2": "^0.4.8", - "babel-plugin-polyfill-corejs3": "^0.9.0", - "babel-plugin-polyfill-regenerator": "^0.5.5", + "babel-plugin-polyfill-corejs2": "^0.4.10", + "babel-plugin-polyfill-corejs3": "^0.10.4", + "babel-plugin-polyfill-regenerator": "^0.6.1", "core-js-compat": "^3.31.0", "semver": "^6.3.1" }, "dependencies": { "@babel/helper-define-polyfill-provider": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.5.0.tgz", - "integrity": "sha512-NovQquuQLAQ5HuyjCz7WQP9MjRj7dx++yspwiyUiGl9ZyadHRSql1HZh5ogRd8W8w6YM6EQ/NTB8rgjLt5W65Q==", + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.1.tgz", + "integrity": "sha512-o7SDgTJuvx5vLKD6SFvkydkSMBvahDKGiNJzG22IZYXhiqoe9efY7zocICBgzHV4IRg5wdgl2nEL/tulKIEIbA==", "dev": true, "requires": { "@babel/helper-compilation-targets": "^7.22.6", @@ -19164,23 +19156,23 @@ } }, "babel-plugin-polyfill-corejs2": { - "version": "0.4.8", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.8.tgz", - "integrity": "sha512-OtIuQfafSzpo/LhnJaykc0R/MMnuLSSVjVYy9mHArIZ9qTCSZ6TpWCuEKZYVoN//t8HqBNScHrOtCrIK5IaGLg==", + "version": "0.4.10", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.10.tgz", + "integrity": "sha512-rpIuu//y5OX6jVU+a5BCn1R5RSZYWAl2Nar76iwaOdycqb6JPxediskWFMMl7stfwNJR4b7eiQvh5fB5TEQJTQ==", "dev": true, "requires": { "@babel/compat-data": "^7.22.6", - "@babel/helper-define-polyfill-provider": "^0.5.0", + "@babel/helper-define-polyfill-provider": "^0.6.1", "semver": "^6.3.1" } }, "babel-plugin-polyfill-regenerator": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.5.5.tgz", - "integrity": "sha512-OJGYZlhLqBh2DDHeqAxWB1XIvr49CxiJ2gIt61/PU55CQK4Z58OzMqjDe1zwQdQk+rBYsRc+1rJmdajM3gimHg==", + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.1.tgz", + "integrity": "sha512-JfTApdE++cgcTWjsiCQlLyFBMbTUft9ja17saCc93lgV33h4tuCVj7tlvu//qpLwaG+3yEz7/KhahGrUMkVq9g==", "dev": true, "requires": { - "@babel/helper-define-polyfill-provider": "^0.5.0" + "@babel/helper-define-polyfill-provider": "^0.6.1" } } } @@ -19211,36 +19203,36 @@ } }, "@babel/template": { - "version": "7.23.9", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.23.9.tgz", - "integrity": "sha512-+xrD2BWLpvHKNmX2QbpdpsBaWnRxahMwJjO+KZk2JOElj5nSmKezyS1B4u+QbHMTX69t4ukm6hh9lsYQ7GHCKA==", + "version": "7.24.0", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.24.0.tgz", + "integrity": "sha512-Bkf2q8lMB0AFpX0NFEqSbx1OkTHf0f+0j82mkw+ZpzBnkk7e9Ql0891vlfgi+kHwOk8tQjiQHpqh4LaSa0fKEA==", "requires": { "@babel/code-frame": "^7.23.5", - "@babel/parser": "^7.23.9", - "@babel/types": "^7.23.9" + "@babel/parser": "^7.24.0", + "@babel/types": "^7.24.0" } }, "@babel/traverse": { - "version": "7.23.9", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.9.tgz", - "integrity": "sha512-I/4UJ9vs90OkBtY6iiiTORVMyIhJ4kAVmsKo9KFc8UOxMeUfi2hvtIBsET5u9GizXE6/GFSuKCTNfgCswuEjRg==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.24.1.tgz", + "integrity": "sha512-xuU6o9m68KeqZbQuDt2TcKSxUw/mrsvavlEqQ1leZ/B+C9tk6E4sRWy97WaXgvq5E+nU3cXMxv3WKOCanVMCmQ==", "requires": { - "@babel/code-frame": "^7.23.5", - "@babel/generator": "^7.23.6", + "@babel/code-frame": "^7.24.1", + "@babel/generator": "^7.24.1", "@babel/helper-environment-visitor": "^7.22.20", "@babel/helper-function-name": "^7.23.0", "@babel/helper-hoist-variables": "^7.22.5", "@babel/helper-split-export-declaration": "^7.22.6", - "@babel/parser": "^7.23.9", - "@babel/types": "^7.23.9", + "@babel/parser": "^7.24.1", + "@babel/types": "^7.24.0", "debug": "^4.3.1", "globals": "^11.1.0" } }, "@babel/types": { - "version": "7.23.9", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.9.tgz", - "integrity": "sha512-dQjSq/7HaSjRM43FFGnv5keM2HsxpmyV1PfaSVm0nzzjwwTmjOe6J4bC8e3+pTEIgHaHj+1ZlLThRJ2auc/w1Q==", + "version": "7.24.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.0.tgz", + "integrity": "sha512-+j7a5c253RfKh8iABBhywc8NSfP5LURe7Uh4qpsh6jc+aLJguvmIUBdjSdEMQv2bENrCR5MfRdjGo7vzS/ob7w==", "requires": { "@babel/helper-string-parser": "^7.23.4", "@babel/helper-validator-identifier": "^7.22.20", @@ -19347,9 +19339,9 @@ } }, "@eslint/js": { - "version": "8.56.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.56.0.tgz", - "integrity": "sha512-gMsVel9D7f2HLkBma9VbtzZRehRogVRfbr++f06nL2vnCGCNlzOD+/MUov/F4p8myyAHspEhVobgjpX64q5m6A==", + "version": "8.57.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz", + "integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==", "dev": true }, "@ethereumjs/common": { @@ -19598,13 +19590,13 @@ "integrity": "sha512-CNy5vSwN3fsUStPRLX7fUYojyuzoEMSXPl7zSLJ8TgtRfjv24LOnOWKT2zYwaHZCJGkdyRnTmstR0P+Ah503Gw==" }, "@humanwhocodes/config-array": { - "version": "0.11.13", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.13.tgz", - "integrity": "sha512-JSBDMiDKSzQVngfRjOdFXgFfklaXI4K9nLF49Auh21lmBWRLIK3+xTErTWD4KU54pb6coM6ESE7Awz/FNU3zgQ==", + "version": "0.11.14", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", + "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==", "dev": true, "requires": { - "@humanwhocodes/object-schema": "^2.0.1", - "debug": "^4.1.1", + "@humanwhocodes/object-schema": "^2.0.2", + "debug": "^4.3.1", "minimatch": "^3.0.5" } }, @@ -19615,9 +19607,9 @@ "dev": true }, "@humanwhocodes/object-schema": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.1.tgz", - "integrity": "sha512-dvuCeX5fC9dXgJn9t+X5atfmgQAzUOWqS1254Gh0m6i8wKd10ebXkfNKiRK+1GWi/yTvvLDHpoxLr0xxxeslWw==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.2.tgz", + "integrity": "sha512-6EwiSjwWYP7pTckG6I5eyFANjPhmPjUX9JRLUSfNPC7FX7zK9gyZAfUEaECL6ALTpGX5AjnBq3C9XmVWPitNpw==", "dev": true }, "@istanbuljs/load-nyc-config": { @@ -20152,13 +20144,13 @@ } }, "@jridgewell/gen-mapping": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz", - "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==", + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", + "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", "requires": { - "@jridgewell/set-array": "^1.0.1", + "@jridgewell/set-array": "^1.2.1", "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.9" + "@jridgewell/trace-mapping": "^0.3.24" } }, "@jridgewell/resolve-uri": { @@ -20167,9 +20159,9 @@ "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==" }, "@jridgewell/set-array": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", - "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==" + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", + "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==" }, "@jridgewell/source-map": { "version": "0.3.5", @@ -20187,9 +20179,9 @@ "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==" }, "@jridgewell/trace-mapping": { - "version": "0.3.22", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.22.tgz", - "integrity": "sha512-Wf963MzWtA2sjrNt+g18IAln9lKnlRp+K2eH4jjIoF1wYeq3aMREpG09xhlhdzS0EjwU7qmUJYangWa+151vZw==", + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", "requires": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" @@ -20769,148 +20761,148 @@ } }, "@webassemblyjs/ast": { - "version": "1.11.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.5.tgz", - "integrity": "sha512-LHY/GSAZZRpsNQH+/oHqhRQ5FT7eoULcBqgfyTB5nQHogFnK3/7QoN7dLnwSE/JkUAF0SrRuclT7ODqMFtWxxQ==", + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.12.1.tgz", + "integrity": "sha512-EKfMUOPRRUTy5UII4qJDGPpqfwjOmZ5jeGFwid9mnoqIFK+e0vqoi1qH56JpmZSzEL53jKnNzScdmftJyG5xWg==", "dev": true, "requires": { - "@webassemblyjs/helper-numbers": "1.11.5", - "@webassemblyjs/helper-wasm-bytecode": "1.11.5" + "@webassemblyjs/helper-numbers": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6" } }, "@webassemblyjs/floating-point-hex-parser": { - "version": "1.11.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.5.tgz", - "integrity": "sha512-1j1zTIC5EZOtCplMBG/IEwLtUojtwFVwdyVMbL/hwWqbzlQoJsWCOavrdnLkemwNoC/EOwtUFch3fuo+cbcXYQ==", + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz", + "integrity": "sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==", "dev": true }, "@webassemblyjs/helper-api-error": { - "version": "1.11.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.5.tgz", - "integrity": "sha512-L65bDPmfpY0+yFrsgz8b6LhXmbbs38OnwDCf6NpnMUYqa+ENfE5Dq9E42ny0qz/PdR0LJyq/T5YijPnU8AXEpA==", + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz", + "integrity": "sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==", "dev": true }, "@webassemblyjs/helper-buffer": { - "version": "1.11.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.5.tgz", - "integrity": "sha512-fDKo1gstwFFSfacIeH5KfwzjykIE6ldh1iH9Y/8YkAZrhmu4TctqYjSh7t0K2VyDSXOZJ1MLhht/k9IvYGcIxg==", + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.12.1.tgz", + "integrity": "sha512-nzJwQw99DNDKr9BVCOZcLuJJUlqkJh+kVzVl6Fmq/tI5ZtEyWT1KZMyOXltXLZJmDtvLCDgwsyrkohEtopTXCw==", "dev": true }, "@webassemblyjs/helper-numbers": { - "version": "1.11.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.5.tgz", - "integrity": "sha512-DhykHXM0ZABqfIGYNv93A5KKDw/+ywBFnuWybZZWcuzWHfbp21wUfRkbtz7dMGwGgT4iXjWuhRMA2Mzod6W4WA==", + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz", + "integrity": "sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==", "dev": true, "requires": { - "@webassemblyjs/floating-point-hex-parser": "1.11.5", - "@webassemblyjs/helper-api-error": "1.11.5", + "@webassemblyjs/floating-point-hex-parser": "1.11.6", + "@webassemblyjs/helper-api-error": "1.11.6", "@xtuc/long": "4.2.2" } }, "@webassemblyjs/helper-wasm-bytecode": { - "version": "1.11.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.5.tgz", - "integrity": "sha512-oC4Qa0bNcqnjAowFn7MPCETQgDYytpsfvz4ujZz63Zu/a/v71HeCAAmZsgZ3YVKec3zSPYytG3/PrRCqbtcAvA==", + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz", + "integrity": "sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==", "dev": true }, "@webassemblyjs/helper-wasm-section": { - "version": "1.11.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.5.tgz", - "integrity": "sha512-uEoThA1LN2NA+K3B9wDo3yKlBfVtC6rh0i4/6hvbz071E8gTNZD/pT0MsBf7MeD6KbApMSkaAK0XeKyOZC7CIA==", + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.12.1.tgz", + "integrity": "sha512-Jif4vfB6FJlUlSbgEMHUyk1j234GTNG9dBJ4XJdOySoj518Xj0oGsNi59cUQF4RRMS9ouBUxDDdyBVfPTypa5g==", "dev": true, "requires": { - "@webassemblyjs/ast": "1.11.5", - "@webassemblyjs/helper-buffer": "1.11.5", - "@webassemblyjs/helper-wasm-bytecode": "1.11.5", - "@webassemblyjs/wasm-gen": "1.11.5" + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-buffer": "1.12.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/wasm-gen": "1.12.1" } }, "@webassemblyjs/ieee754": { - "version": "1.11.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.5.tgz", - "integrity": "sha512-37aGq6qVL8A8oPbPrSGMBcp38YZFXcHfiROflJn9jxSdSMMM5dS5P/9e2/TpaJuhE+wFrbukN2WI6Hw9MH5acg==", + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz", + "integrity": "sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==", "dev": true, "requires": { "@xtuc/ieee754": "^1.2.0" } }, "@webassemblyjs/leb128": { - "version": "1.11.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.5.tgz", - "integrity": "sha512-ajqrRSXaTJoPW+xmkfYN6l8VIeNnR4vBOTQO9HzR7IygoCcKWkICbKFbVTNMjMgMREqXEr0+2M6zukzM47ZUfQ==", + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.6.tgz", + "integrity": "sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==", "dev": true, "requires": { "@xtuc/long": "4.2.2" } }, "@webassemblyjs/utf8": { - "version": "1.11.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.5.tgz", - "integrity": "sha512-WiOhulHKTZU5UPlRl53gHR8OxdGsSOxqfpqWeA2FmcwBMaoEdz6b2x2si3IwC9/fSPLfe8pBMRTHVMk5nlwnFQ==", + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.6.tgz", + "integrity": "sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==", "dev": true }, "@webassemblyjs/wasm-edit": { - "version": "1.11.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.5.tgz", - "integrity": "sha512-C0p9D2fAu3Twwqvygvf42iGCQ4av8MFBLiTb+08SZ4cEdwzWx9QeAHDo1E2k+9s/0w1DM40oflJOpkZ8jW4HCQ==", + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.12.1.tgz", + "integrity": "sha512-1DuwbVvADvS5mGnXbE+c9NfA8QRcZ6iKquqjjmR10k6o+zzsRVesil54DKexiowcFCPdr/Q0qaMgB01+SQ1u6g==", "dev": true, "requires": { - "@webassemblyjs/ast": "1.11.5", - "@webassemblyjs/helper-buffer": "1.11.5", - "@webassemblyjs/helper-wasm-bytecode": "1.11.5", - "@webassemblyjs/helper-wasm-section": "1.11.5", - "@webassemblyjs/wasm-gen": "1.11.5", - "@webassemblyjs/wasm-opt": "1.11.5", - "@webassemblyjs/wasm-parser": "1.11.5", - "@webassemblyjs/wast-printer": "1.11.5" + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-buffer": "1.12.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/helper-wasm-section": "1.12.1", + "@webassemblyjs/wasm-gen": "1.12.1", + "@webassemblyjs/wasm-opt": "1.12.1", + "@webassemblyjs/wasm-parser": "1.12.1", + "@webassemblyjs/wast-printer": "1.12.1" } }, "@webassemblyjs/wasm-gen": { - "version": "1.11.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.5.tgz", - "integrity": "sha512-14vteRlRjxLK9eSyYFvw1K8Vv+iPdZU0Aebk3j6oB8TQiQYuO6hj9s4d7qf6f2HJr2khzvNldAFG13CgdkAIfA==", + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.12.1.tgz", + "integrity": "sha512-TDq4Ojh9fcohAw6OIMXqiIcTq5KUXTGRkVxbSo1hQnSy6lAM5GSdfwWeSxpAo0YzgsgF182E/U0mDNhuA0tW7w==", "dev": true, "requires": { - "@webassemblyjs/ast": "1.11.5", - "@webassemblyjs/helper-wasm-bytecode": "1.11.5", - "@webassemblyjs/ieee754": "1.11.5", - "@webassemblyjs/leb128": "1.11.5", - "@webassemblyjs/utf8": "1.11.5" + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/ieee754": "1.11.6", + "@webassemblyjs/leb128": "1.11.6", + "@webassemblyjs/utf8": "1.11.6" } }, "@webassemblyjs/wasm-opt": { - "version": "1.11.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.5.tgz", - "integrity": "sha512-tcKwlIXstBQgbKy1MlbDMlXaxpucn42eb17H29rawYLxm5+MsEmgPzeCP8B1Cl69hCice8LeKgZpRUAPtqYPgw==", + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.12.1.tgz", + "integrity": "sha512-Jg99j/2gG2iaz3hijw857AVYekZe2SAskcqlWIZXjji5WStnOpVoat3gQfT/Q5tb2djnCjBtMocY/Su1GfxPBg==", "dev": true, "requires": { - "@webassemblyjs/ast": "1.11.5", - "@webassemblyjs/helper-buffer": "1.11.5", - "@webassemblyjs/wasm-gen": "1.11.5", - "@webassemblyjs/wasm-parser": "1.11.5" + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-buffer": "1.12.1", + "@webassemblyjs/wasm-gen": "1.12.1", + "@webassemblyjs/wasm-parser": "1.12.1" } }, "@webassemblyjs/wasm-parser": { - "version": "1.11.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.5.tgz", - "integrity": "sha512-SVXUIwsLQlc8srSD7jejsfTU83g7pIGr2YYNb9oHdtldSxaOhvA5xwvIiWIfcX8PlSakgqMXsLpLfbbJ4cBYew==", + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.12.1.tgz", + "integrity": "sha512-xikIi7c2FHXysxXe3COrVUPSheuBtpcfhbpFj4gmu7KRLYOzANztwUU0IbsqvMqzuNK2+glRGWCEqZo1WCLyAQ==", "dev": true, "requires": { - "@webassemblyjs/ast": "1.11.5", - "@webassemblyjs/helper-api-error": "1.11.5", - "@webassemblyjs/helper-wasm-bytecode": "1.11.5", - "@webassemblyjs/ieee754": "1.11.5", - "@webassemblyjs/leb128": "1.11.5", - "@webassemblyjs/utf8": "1.11.5" + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-api-error": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/ieee754": "1.11.6", + "@webassemblyjs/leb128": "1.11.6", + "@webassemblyjs/utf8": "1.11.6" } }, "@webassemblyjs/wast-printer": { - "version": "1.11.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.5.tgz", - "integrity": "sha512-f7Pq3wvg3GSPUPzR0F6bmI89Hdb+u9WXrSKc4v+N0aV0q6r42WoF92Jp2jEorBEBRoRNXgjp53nBniDXcqZYPA==", + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.12.1.tgz", + "integrity": "sha512-+X4WAlOisVWQMikjbcvY2e0rwPsKQ9F688lksZhBcPycBBuii3O7m8FACbDMWDojpAqvjIncrG8J0XHKyQfVeA==", "dev": true, "requires": { - "@webassemblyjs/ast": "1.11.5", + "@webassemblyjs/ast": "1.12.1", "@xtuc/long": "4.2.2" } }, @@ -21292,13 +21284,13 @@ "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" }, "autoprefixer": { - "version": "10.4.17", - "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.17.tgz", - "integrity": "sha512-/cpVNRLSfhOtcGflT13P2794gVSgmPgTR+erw5ifnMLZb0UnSlkK4tquLmkd3BhA+nLo5tX8Cu0upUsGKvKbmg==", + "version": "10.4.19", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.19.tgz", + "integrity": "sha512-BaENR2+zBZ8xXhM4pUaKUxlVdxZ0EZhjvbopwnXmxRUfqDmwSpC2lAi/QXvx7NRdPCo1WKEcEF6mV64si1z4Ew==", "dev": true, "requires": { - "browserslist": "^4.22.2", - "caniuse-lite": "^1.0.30001578", + "browserslist": "^4.23.0", + "caniuse-lite": "^1.0.30001599", "fraction.js": "^4.3.7", "normalize-range": "^0.1.2", "picocolors": "^1.0.0", @@ -21447,19 +21439,19 @@ } }, "babel-plugin-polyfill-corejs3": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.9.0.tgz", - "integrity": "sha512-7nZPG1uzK2Ymhy/NbaOWTg3uibM2BmGASS4vHS4szRZAIR8R6GwA/xAujpdrXU5iyklrimWnLWU+BLF9suPTqg==", + "version": "0.10.4", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.10.4.tgz", + "integrity": "sha512-25J6I8NGfa5YkCDogHRID3fVCadIR8/pGl1/spvCkzb6lVn6SR3ojpx9nOn9iEBcUsjY24AmdKm5khcfKdylcg==", "dev": true, "requires": { - "@babel/helper-define-polyfill-provider": "^0.5.0", - "core-js-compat": "^3.34.0" + "@babel/helper-define-polyfill-provider": "^0.6.1", + "core-js-compat": "^3.36.1" }, "dependencies": { "@babel/helper-define-polyfill-provider": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.5.0.tgz", - "integrity": "sha512-NovQquuQLAQ5HuyjCz7WQP9MjRj7dx++yspwiyUiGl9ZyadHRSql1HZh5ogRd8W8w6YM6EQ/NTB8rgjLt5W65Q==", + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.1.tgz", + "integrity": "sha512-o7SDgTJuvx5vLKD6SFvkydkSMBvahDKGiNJzG22IZYXhiqoe9efY7zocICBgzHV4IRg5wdgl2nEL/tulKIEIbA==", "dev": true, "requires": { "@babel/helper-compilation-targets": "^7.22.6", @@ -21743,12 +21735,12 @@ } }, "browserslist": { - "version": "4.22.2", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.22.2.tgz", - "integrity": "sha512-0UgcrvQmBDvZHFGdYUehrCNIazki7/lUP3kkoi/r3YB2amZbFM9J43ZRkJTXBUZK4gmx56+Sqk9+Vs9mwZx9+A==", + "version": "4.23.0", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.0.tgz", + "integrity": "sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ==", "requires": { - "caniuse-lite": "^1.0.30001565", - "electron-to-chromium": "^1.4.601", + "caniuse-lite": "^1.0.30001587", + "electron-to-chromium": "^1.4.668", "node-releases": "^2.0.14", "update-browserslist-db": "^1.0.13" } @@ -21941,9 +21933,9 @@ } }, "caniuse-lite": { - "version": "1.0.30001579", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001579.tgz", - "integrity": "sha512-u5AUVkixruKHJjw/pj9wISlcMpgFWzSrczLZbrqBSxukQixmg0SJ5sZTpvaFvxU0HoQKd4yoyAogyrAz9pzJnA==" + "version": "1.0.30001605", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001605.tgz", + "integrity": "sha512-nXwGlFWo34uliI9z3n6Qc0wZaf7zaZWA1CPZ169La5mV3I/gem7bst0vr5XQH5TJXZIMfDeZyOrZnSlVzKxxHQ==" }, "caseless": { "version": "0.12.0", @@ -21980,9 +21972,9 @@ "dev": true }, "chart.js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/chart.js/-/chart.js-4.4.1.tgz", - "integrity": "sha512-C74QN1bxwV1v2PEujhmKjOZ7iUM4w6BWs23Md/6aOZZSlwMzeCIDGuZay++rBgChYru7/+QFeoQW0fQoP534Dg==", + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/chart.js/-/chart.js-4.4.2.tgz", + "integrity": "sha512-6GD7iKwFpP5kbSD4MeRRRlTnQvxfQREy36uEtm1hzHzcOqwWx0YEHuspuoNlslu+nciLIB7fjjsHkUv/FzFcOg==", "requires": { "@kurkle/color": "^0.3.0" } @@ -22241,9 +22233,9 @@ } }, "cookie": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", - "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==" + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz", + "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==" }, "cookie-signature": { "version": "1.0.6", @@ -22278,16 +22270,16 @@ } }, "core-js": { - "version": "3.36.0", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.36.0.tgz", - "integrity": "sha512-mt7+TUBbTFg5+GngsAxeKBTl5/VS0guFeJacYge9OmHb+m058UwwIm41SE9T4Den7ClatV57B6TYTuJ0CX1MAw==" + "version": "3.36.1", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.36.1.tgz", + "integrity": "sha512-BTvUrwxVBezj5SZ3f10ImnX2oRByMxql3EimVqMysepbC9EeMUOpLwdy6Eoili2x6E4kf+ZUB5k/+Jv55alPfA==" }, "core-js-compat": { - "version": "3.35.0", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.35.0.tgz", - "integrity": "sha512-5blwFAddknKeNgsjBzilkdQ0+YK8L1PfqPYq40NOYMYFSS38qj+hpTcLLWwpIwA2A5bje/x5jmVn2tzUMg9IVw==", + "version": "3.36.1", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.36.1.tgz", + "integrity": "sha512-Dk997v9ZCt3X/npqzyGdTlq6t7lDBhZwGvV94PKzDArjp7BTRm7WlDAXYd/OWdeFHO8OChQYRJNJvUCqCbrtKA==", "requires": { - "browserslist": "^4.22.2" + "browserslist": "^4.23.0" } }, "core-util-is": { @@ -22993,9 +22985,9 @@ "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" }, "electron-to-chromium": { - "version": "1.4.609", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.609.tgz", - "integrity": "sha512-ihiCP7PJmjoGNuLpl7TjNA8pCQWu09vGyjlPYw1Rqww4gvNuCcmvl+44G+2QyJ6S2K4o+wbTS++Xz0YN8Q9ERw==" + "version": "1.4.692", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.692.tgz", + "integrity": "sha512-d5rZRka9n2Y3MkWRN74IoAsxR0HK3yaAt7T50e3iT9VZmCCQDT3geXUO5ZRMhDToa1pkCeQXuNo+0g+NfDOVPA==" }, "elliptic": { "version": "6.5.4", @@ -23072,9 +23064,9 @@ } }, "enhanced-resolve": { - "version": "5.15.0", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.15.0.tgz", - "integrity": "sha512-LXYT42KJ7lpIKECr2mAXIaMldcNCh/7E0KBKOu4KSfkHmP+mZmSs+8V5gBAqisWBy0OO4W5Oyys0GO1Y8KtdKg==", + "version": "5.16.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.16.0.tgz", + "integrity": "sha512-O+QWCviPNSSLAD9Ucn8Awv+poAkqn3T1XY5/N7kR7rQO9yfSGWkYZDwpJ+iKF7B8rxaQKWngSqACpgzeapSyoA==", "dev": true, "requires": { "graceful-fs": "^4.2.4", @@ -23201,12 +23193,13 @@ } }, "es5-ext": { - "version": "0.10.62", - "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.62.tgz", - "integrity": "sha512-BHLqn0klhEpnOKSrzn/Xsz2UIW8j+cGmo9JLzr8BiUapV8hPL9+FliFqjwr9ngW7jWdnxv6eO+/LqyhJVqgrjA==", + "version": "0.10.64", + "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.64.tgz", + "integrity": "sha512-p2snDhiLaXe6dahss1LddxqEm+SkuDvV8dnIQG0MWjyHpcMNfXKPE+/Cc0y+PhxJX3A4xGNeFCj5oc0BUh6deg==", "requires": { "es6-iterator": "^2.0.3", "es6-symbol": "^3.1.3", + "esniff": "^2.0.1", "next-tick": "^1.1.0" } }, @@ -23310,16 +23303,16 @@ } }, "eslint": { - "version": "8.56.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.56.0.tgz", - "integrity": "sha512-Go19xM6T9puCOWntie1/P997aXxFsOi37JIHRWI514Hc6ZnaHGKY9xFhrU65RT6CcBEzZoGG1e6Nq+DT04ZtZQ==", + "version": "8.57.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz", + "integrity": "sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==", "dev": true, "requires": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.6.1", "@eslint/eslintrc": "^2.1.4", - "@eslint/js": "8.56.0", - "@humanwhocodes/config-array": "^0.11.13", + "@eslint/js": "8.57.0", + "@humanwhocodes/config-array": "^0.11.14", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", "@ungap/structured-clone": "^1.2.0", @@ -23709,6 +23702,24 @@ "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", "dev": true }, + "esniff": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/esniff/-/esniff-2.0.1.tgz", + "integrity": "sha512-kTUIGKQ/mDPFoJ0oVfcmyJn4iBDRptjNVIzwIFR7tqWXdVI9xfA2RMwY/gbSpJG3lkdWNEjLap/NqVHZiJsdfg==", + "requires": { + "d": "^1.0.1", + "es5-ext": "^0.10.62", + "event-emitter": "^0.3.5", + "type": "^2.7.2" + }, + "dependencies": { + "type": { + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/type/-/type-2.7.2.tgz", + "integrity": "sha512-dzlvlNlt6AXU7EBSfpAscydQ7gXB+pPGsPnfJnZpiNJBDj7IaJzQlBZYGdEi4R9HmPdBv2XmWJ6YUtoTa7lmCw==" + } + } + }, "espree": { "version": "9.6.1", "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", @@ -24272,6 +24283,15 @@ "strip-hex-prefix": "1.0.0" } }, + "event-emitter": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz", + "integrity": "sha512-D9rRn9y7kLPnJ+hMq7S/nhvoKwwvVJahBi2BPmx3bvbsEdK3W9ii8cBSGjP+72/LnM4n6fo3+dkCX5FeTQruXA==", + "requires": { + "d": "1", + "es5-ext": "~0.10.14" + } + }, "eventemitter3": { "version": "4.0.4", "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.4.tgz", @@ -24328,16 +24348,16 @@ } }, "express": { - "version": "4.18.2", - "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz", - "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==", + "version": "4.19.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.19.2.tgz", + "integrity": "sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==", "requires": { "accepts": "~1.3.8", "array-flatten": "1.1.1", - "body-parser": "1.20.1", + "body-parser": "1.20.2", "content-disposition": "0.5.4", "content-type": "~1.0.4", - "cookie": "0.5.0", + "cookie": "0.6.0", "cookie-signature": "1.0.6", "debug": "2.6.9", "depd": "2.0.0", @@ -24365,25 +24385,6 @@ "vary": "~1.1.2" }, "dependencies": { - "body-parser": { - "version": "1.20.1", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", - "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==", - "requires": { - "bytes": "3.1.2", - "content-type": "~1.0.4", - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "on-finished": "2.4.1", - "qs": "6.11.0", - "raw-body": "2.5.1", - "type-is": "~1.6.18", - "unpipe": "1.0.0" - } - }, "debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", @@ -24405,17 +24406,6 @@ "side-channel": "^1.0.4" } }, - "raw-body": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", - "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", - "requires": { - "bytes": "3.1.2", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" - } - }, "safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", @@ -24914,9 +24904,9 @@ } }, "graceful-fs": { - "version": "4.2.9", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.9.tgz", - "integrity": "sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ==" + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==" }, "graphemer": { "version": "1.4.0", @@ -27598,9 +27588,9 @@ } }, "mini-css-extract-plugin": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.8.0.tgz", - "integrity": "sha512-CxmUYPFcTgET1zImteG/LZOy/4T5rTojesQXkSNBiquhydn78tfbCE9sjIjnJ/UcjNjOC1bphTCCW5rrS7cXAg==", + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.8.1.tgz", + "integrity": "sha512-/1HDlyFRxWIZPI1ZpgqlZ8jMw/1Dp/dl3P0L1jtZ+zVcHqwPhGwaJwKL00WVgfnBy6PWCde9W65or7IIETImuA==", "dev": true, "requires": { "schema-utils": "^4.0.0", @@ -28268,14 +28258,14 @@ "integrity": "sha512-Wb4p1J4zyFTbM+u6WuO4XstYx4Ky9Cewe4DWrel7B0w6VVICvPwdOpotjzcf6eD8TsckVnIMNONQyPIUFOUbCQ==" }, "postcss": { - "version": "8.4.35", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.35.tgz", - "integrity": "sha512-u5U8qYpBCpN13BsiEB0CbR1Hhh4Gc0zLFuedrHJKMctHCHAGrMdG0PRM/KErzAL3CU6/eckEtmHNB3x6e3c0vA==", + "version": "8.4.38", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.38.tgz", + "integrity": "sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==", "dev": true, "requires": { "nanoid": "^3.3.7", "picocolors": "^1.0.0", - "source-map-js": "^1.0.2" + "source-map-js": "^1.2.0" } }, "postcss-calc": { @@ -28339,9 +28329,9 @@ "requires": {} }, "postcss-loader": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-8.1.0.tgz", - "integrity": "sha512-AbperNcX3rlob7Ay7A/HQcrofug1caABBkopoFeOQMspZBqcqj6giYn1Bwey/0uiOPAcR+NQD0I2HC7rXzk91w==", + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-8.1.1.tgz", + "integrity": "sha512-0IeqyAsG6tYiDRCYKQJLAmgQr47DX6N7sFSWvQxt6AcupX8DIdmykuk/o/tx0Lze3ErGHJEp5OSRxrelC6+NdQ==", "dev": true, "requires": { "cosmiconfig": "^9.0.0", @@ -29294,9 +29284,9 @@ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, "sass": { - "version": "1.71.0", - "resolved": "https://registry.npmjs.org/sass/-/sass-1.71.0.tgz", - "integrity": "sha512-HKKIKf49Vkxlrav3F/w6qRuPcmImGVbIXJ2I3Kg0VMA+3Bav+8yE9G5XmP5lMj6nl4OlqbPftGAscNaNu28b8w==", + "version": "1.72.0", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.72.0.tgz", + "integrity": "sha512-Gpczt3WA56Ly0Mn8Sl21Vj94s1axi9hDIzDFn9Ph9x3C3p4nNyvsqJoQyVXKou6cBlfFWEgRW4rT8Tb4i3XnVA==", "dev": true, "requires": { "chokidar": ">=3.0.0 <4.0.0", @@ -29621,9 +29611,9 @@ "dev": true }, "source-map-js": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", - "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", + "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==", "dev": true }, "source-map-support": { @@ -29947,9 +29937,9 @@ } }, "sweetalert2": { - "version": "11.10.5", - "resolved": "https://registry.npmjs.org/sweetalert2/-/sweetalert2-11.10.5.tgz", - "integrity": "sha512-q9eE3EKhMcpIDU/Xcz7z5lk8axCGkgxwK47gXGrrfncnBJWxHPPHnBVAjfsVXcTt8Yi8U6HNEcBRSu+qGeyFdA==" + "version": "11.10.7", + "resolved": "https://registry.npmjs.org/sweetalert2/-/sweetalert2-11.10.7.tgz", + "integrity": "sha512-5Jlzrmaitay6KzU+2+LhYu9q+L4v/dZ8oZyEDH14ep0C/QilCnFLHmqAyD/Lhq/lm5DiwsOs6Tr58iv8k3wyGg==" }, "symbol-tree": { "version": "3.2.4", @@ -30491,9 +30481,9 @@ } }, "watchpack": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz", - "integrity": "sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.1.tgz", + "integrity": "sha512-8wrBCMtVhqcXP2Sup1ctSkga6uc2Bx0IIvKyT7yTFier5AXHooSI+QyQQAtTb7+E0IUCCKyTFmXqdqgum2XWGg==", "dev": true, "requires": { "glob-to-regexp": "^0.4.1", @@ -30935,26 +30925,26 @@ "dev": true }, "webpack": { - "version": "5.90.3", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.90.3.tgz", - "integrity": "sha512-h6uDYlWCctQRuXBs1oYpVe6sFcWedl0dpcVaTf/YF67J9bKvwJajFulMVSYKHrksMB3I/pIagRzDxwxkebuzKA==", + "version": "5.91.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.91.0.tgz", + "integrity": "sha512-rzVwlLeBWHJbmgTC/8TvAcu5vpJNII+MelQpylD4jNERPwpBJOE2lEcko1zJX3QJeLjTTAnQxn/OJ8bjDzVQaw==", "dev": true, "requires": { "@types/eslint-scope": "^3.7.3", "@types/estree": "^1.0.5", - "@webassemblyjs/ast": "^1.11.5", - "@webassemblyjs/wasm-edit": "^1.11.5", - "@webassemblyjs/wasm-parser": "^1.11.5", + "@webassemblyjs/ast": "^1.12.1", + "@webassemblyjs/wasm-edit": "^1.12.1", + "@webassemblyjs/wasm-parser": "^1.12.1", "acorn": "^8.7.1", "acorn-import-assertions": "^1.9.0", "browserslist": "^4.21.10", "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.15.0", + "enhanced-resolve": "^5.16.0", "es-module-lexer": "^1.2.1", "eslint-scope": "5.1.1", "events": "^3.2.0", "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.2.9", + "graceful-fs": "^4.2.11", "json-parse-even-better-errors": "^2.3.1", "loader-runner": "^4.2.0", "mime-types": "^2.1.27", @@ -30962,7 +30952,7 @@ "schema-utils": "^3.2.0", "tapable": "^2.1.1", "terser-webpack-plugin": "^5.3.10", - "watchpack": "^2.4.0", + "watchpack": "^2.4.1", "webpack-sources": "^3.2.3" }, "dependencies": { @@ -31257,9 +31247,9 @@ "dev": true }, "xss": { - "version": "1.0.14", - "resolved": "https://registry.npmjs.org/xss/-/xss-1.0.14.tgz", - "integrity": "sha512-og7TEJhXvn1a7kzZGQ7ETjdQVS2UfZyTlsEdDOqvQF7GoxNfY+0YLCzBy1kPdsDDx4QuNAonQPddpsn6Xl/7sw==", + "version": "1.0.15", + "resolved": "https://registry.npmjs.org/xss/-/xss-1.0.15.tgz", + "integrity": "sha512-FVdlVVC67WOIPvfOwhoMETV72f6GbW7aOabBC3WxN/oUdoEMDyLz4OgRv5/gck2ZeNqEQu+Tb0kloovXOfpYVg==", "requires": { "commander": "^2.20.3", "cssfilter": "0.0.10" diff --git a/apps/block_scout_web/assets/package.json b/apps/block_scout_web/assets/package.json index e7edf532c30c..5d5ae6ebae04 100644 --- a/apps/block_scout_web/assets/package.json +++ b/apps/block_scout_web/assets/package.json @@ -20,16 +20,16 @@ }, "dependencies": { "@fortawesome/fontawesome-free": "^6.5.1", - "@amplitude/analytics-browser": "^2.4.1", + "@amplitude/analytics-browser": "^2.6.1", "@tarekraafat/autocomplete.js": "^10.2.7", "@walletconnect/web3-provider": "^1.8.0", "assert": "^2.1.0", "bignumber.js": "^9.1.2", "bootstrap": "^4.6.0", - "chart.js": "^4.4.1", + "chart.js": "^4.4.2", "chartjs-adapter-luxon": "^1.3.1", "clipboard": "^2.0.11", - "core-js": "^3.36.0", + "core-js": "^3.36.1", "crypto-browserify": "^3.12.0", "dropzone": "^5.9.3", "eth-net-props": "^1.0.41", @@ -73,24 +73,24 @@ "redux": "^5.0.1", "stream-browserify": "^3.0.0", "stream-http": "^3.1.1", - "sweetalert2": "^11.10.5", + "sweetalert2": "^11.10.7", "urijs": "^1.19.11", "url": "^0.11.3", "util": "^0.12.5", "viewerjs": "^1.11.6", "web3": "^1.10.4", "web3modal": "^1.9.12", - "xss": "^1.0.14" + "xss": "^1.0.15" }, "devDependencies": { - "@babel/core": "^7.23.9", - "@babel/preset-env": "^7.23.9", - "autoprefixer": "^10.4.17", + "@babel/core": "^7.24.3", + "@babel/preset-env": "^7.24.3", + "autoprefixer": "^10.4.19", "babel-loader": "^9.1.3", "copy-webpack-plugin": "^12.0.2", "css-loader": "^6.10.0", "css-minimizer-webpack-plugin": "^6.0.0", - "eslint": "^8.56.0", + "eslint": "^8.57.0", "eslint-config-standard": "^17.1.0", "eslint-plugin-import": "^2.29.1", "eslint-plugin-node": "^11.1.0", @@ -98,13 +98,13 @@ "file-loader": "^6.2.0", "jest": "^29.7.0", "jest-environment-jsdom": "^29.7.0", - "mini-css-extract-plugin": "^2.8.0", - "postcss": "^8.4.35", - "postcss-loader": "^8.1.0", - "sass": "^1.71.0", + "mini-css-extract-plugin": "^2.8.1", + "postcss": "^8.4.38", + "postcss-loader": "^8.1.1", + "sass": "^1.72.0", "sass-loader": "^14.1.1", "style-loader": "^3.3.4", - "webpack": "^5.90.3", + "webpack": "^5.91.0", "webpack-cli": "^5.1.4" }, "jest": { diff --git a/apps/block_scout_web/assets/static/images/icons/fontawesome/twitter.svg b/apps/block_scout_web/assets/static/images/icons/fontawesome/twitter.svg index e189ab857d20..d1242d3930c7 100644 --- a/apps/block_scout_web/assets/static/images/icons/fontawesome/twitter.svg +++ b/apps/block_scout_web/assets/static/images/icons/fontawesome/twitter.svg @@ -1 +1,4 @@ - \ No newline at end of file + + + + diff --git a/apps/block_scout_web/config/config.exs b/apps/block_scout_web/config/config.exs index bb545430cbe8..aa3a4616a6a3 100644 --- a/apps/block_scout_web/config/config.exs +++ b/apps/block_scout_web/config/config.exs @@ -20,7 +20,7 @@ config :block_scout_web, api_v2_temp_token_key: "api_v2_temp_token" config :block_scout_web, - admin_panel_enabled: System.get_env("ADMIN_PANEL_ENABLED", "") == "true" + admin_panel_enabled: ConfigHelper.parse_bool_env_var("ADMIN_PANEL_ENABLED") config :block_scout_web, BlockScoutWeb.Counters.BlocksIndexedCounter, enabled: true @@ -72,7 +72,7 @@ config :logger, :api_v2, block_number step count error_count shrunk import_id transaction_id)a, metadata_filter: [application: :api_v2] -config :prometheus, BlockScoutWeb.Prometheus.Instrumenter, +config :prometheus, BlockScoutWeb.Prometheus.PhoenixInstrumenter, # override default for Phoenix 1.4 compatibility # * `:transport_name` to `:transport` # * remove `:vsn` @@ -85,15 +85,21 @@ config :prometheus, BlockScoutWeb.Prometheus.Instrumenter, config :spandex_phoenix, tracer: BlockScoutWeb.Tracer config :block_scout_web, BlockScoutWeb.ApiRouter, - writing_enabled: System.get_env("API_V1_WRITE_METHODS_DISABLED") != "true", - reading_enabled: System.get_env("API_V1_READ_METHODS_DISABLED") != "true" + writing_enabled: !ConfigHelper.parse_bool_env_var("API_V1_WRITE_METHODS_DISABLED"), + reading_enabled: !ConfigHelper.parse_bool_env_var("API_V1_READ_METHODS_DISABLED") -config :block_scout_web, BlockScoutWeb.WebRouter, enabled: System.get_env("DISABLE_WEBAPP") != "true" +config :block_scout_web, BlockScoutWeb.WebRouter, enabled: !ConfigHelper.parse_bool_env_var("DISABLE_WEBAPP") config :block_scout_web, BlockScoutWeb.CSPHeader, mixpanel_url: System.get_env("MIXPANEL_URL", "https://api-js.mixpanel.com"), amplitude_url: System.get_env("AMPLITUDE_URL", "https://api2.amplitude.com/2/httpapi") +config :block_scout_web, Api.GraphQL, + enabled: ConfigHelper.parse_bool_env_var("API_GRAPHQL_ENABLED", "true"), + token_limit: ConfigHelper.parse_integer_env_var("API_GRAPHQL_TOKEN_LIMIT", 1000), + # Needs to be 215 to support the schema introspection for graphiql + max_complexity: ConfigHelper.parse_integer_env_var("API_GRAPHQL_MAX_COMPLEXITY", 215) + # Configures Ueberauth local settings config :ueberauth, Ueberauth, providers: [ diff --git a/apps/block_scout_web/lib/block_scout_web.ex b/apps/block_scout_web/lib/block_scout_web.ex index e996557820bc..c56ab8c116fa 100644 --- a/apps/block_scout_web/lib/block_scout_web.ex +++ b/apps/block_scout_web/lib/block_scout_web.ex @@ -56,6 +56,8 @@ defmodule BlockScoutWeb do WeiHelper } + import Explorer.Chain.CurrencyHelper, only: [divide_decimals: 2] + import BlockScoutWeb.WebRouter.Helpers, except: [static_path: 2] end end diff --git a/apps/block_scout_web/lib/block_scout_web/api_router.ex b/apps/block_scout_web/lib/block_scout_web/api_router.ex index 9b3e12dd76c5..939e55297c26 100644 --- a/apps/block_scout_web/lib/block_scout_web/api_router.ex +++ b/apps/block_scout_web/lib/block_scout_web/api_router.ex @@ -47,73 +47,14 @@ defmodule BlockScoutWeb.ApiRouter do plug(RateLimit) end - alias BlockScoutWeb.Account.Api.V1.{AuthenticateController, EmailController, TagsController, UserController} - alias BlockScoutWeb.API.V2 - - # TODO: Remove /account/v1 paths - scope "/account/v1", as: :account_v1 do - pipe_through(:api) - pipe_through(:account_api) - - get("/authenticate", AuthenticateController, :authenticate_get) - post("/authenticate", AuthenticateController, :authenticate_post) - - get("/get_csrf", UserController, :get_csrf) - - scope "/email" do - get("/resend", EmailController, :resend_email) - end - - scope "/user" do - get("/info", UserController, :info) - - get("/watchlist", UserController, :watchlist_old) - delete("/watchlist/:id", UserController, :delete_watchlist) - post("/watchlist", UserController, :create_watchlist) - put("/watchlist/:id", UserController, :update_watchlist) - - get("/api_keys", UserController, :api_keys) - delete("/api_keys/:api_key", UserController, :delete_api_key) - post("/api_keys", UserController, :create_api_key) - put("/api_keys/:api_key", UserController, :update_api_key) - - get("/custom_abis", UserController, :custom_abis) - delete("/custom_abis/:id", UserController, :delete_custom_abi) - post("/custom_abis", UserController, :create_custom_abi) - put("/custom_abis/:id", UserController, :update_custom_abi) - - get("/public_tags", UserController, :public_tags_requests) - delete("/public_tags/:id", UserController, :delete_public_tags_request) - post("/public_tags", UserController, :create_public_tags_request) - put("/public_tags/:id", UserController, :update_public_tags_request) - - scope "/tags" do - get("/address/", UserController, :tags_address_old) - get("/address/:id", UserController, :tags_address) - delete("/address/:id", UserController, :delete_tag_address) - post("/address/", UserController, :create_tag_address) - put("/address/:id", UserController, :update_tag_address) - - get("/transaction/", UserController, :tags_transaction_old) - get("/transaction/:id", UserController, :tags_transaction) - delete("/transaction/:id", UserController, :delete_tag_transaction) - post("/transaction/", UserController, :create_tag_transaction) - put("/transaction/:id", UserController, :update_tag_transaction) - end - end + pipeline :api_v1_graphql do + plug(BlockScoutWeb.Plug.Logger, application: :api) + plug(:accepts, ["json"]) + plug(RateLimit, graphql?: true) end - # TODO: Remove /account/v1 paths - scope "/account/v1" do - pipe_through(:api) - pipe_through(:account_api) - - scope "/tags" do - get("/address/:address_hash", TagsController, :tags_address) - - get("/transaction/:transaction_hash", TagsController, :tags_transaction) - end - end + alias BlockScoutWeb.Account.Api.V2.{AuthenticateController, EmailController, TagsController, UserController} + alias BlockScoutWeb.API.V2 scope "/account/v2", as: :account_v2 do pipe_through(:api) @@ -195,19 +136,23 @@ defmodule BlockScoutWeb.ApiRouter do end scope "/config" do - get("/json-rpc-url", V2.ConfigController, :json_rpc_url) get("/backend-version", V2.ConfigController, :backend_version) end scope "/transactions" do get("/", V2.TransactionController, :transactions) get("/watchlist", V2.TransactionController, :watchlist_transactions) + get("/stats", V2.TransactionController, :stats) - if System.get_env("CHAIN_TYPE") == "polygon_zkevm" do + if Application.compile_env(:explorer, :chain_type) == :polygon_zkevm do get("/zkevm-batch/:batch_number", V2.TransactionController, :polygon_zkevm_batch) end - if System.get_env("CHAIN_TYPE") == "suave" do + if Application.compile_env(:explorer, :chain_type) == :zksync do + get("/zksync-batch/:batch_number", V2.TransactionController, :zksync_batch) + end + + if Application.compile_env(:explorer, :chain_type) == :suave do get("/execution-node/:execution_node_hash_param", V2.TransactionController, :execution_node) end @@ -219,7 +164,7 @@ defmodule BlockScoutWeb.ApiRouter do get("/:transaction_hash_param/state-changes", V2.TransactionController, :state_changes) get("/:transaction_hash_param/summary", V2.TransactionController, :summary) - if System.get_env("CHAIN_TYPE") == "ethereum" do + if Application.compile_env(:explorer, :chain_type) == :ethereum do get("/:transaction_hash_param/blobs", V2.TransactionController, :blobs) end end @@ -228,6 +173,7 @@ defmodule BlockScoutWeb.ApiRouter do get("/", V2.BlockController, :blocks) get("/:block_hash_or_number", V2.BlockController, :block) get("/:block_hash_or_number/transactions", V2.BlockController, :transactions) + get("/:block_hash_or_number/internal-transactions", V2.BlockController, :internal_transactions) get("/:block_hash_or_number/withdrawals", V2.BlockController, :withdrawals) end @@ -260,6 +206,7 @@ defmodule BlockScoutWeb.ApiRouter do get("/:address_hash_param/counters", V2.TokenController, :counters) get("/:address_hash_param/transfers", V2.TokenController, :transfers) get("/:address_hash_param/holders", V2.TokenController, :holders) + get("/:address_hash_param/holders/csv", V2.CSVExportController, :export_token_holders) get("/:address_hash_param/instances", V2.TokenController, :instances) get("/:address_hash_param/instances/:token_id", V2.TokenController, :instance) get("/:address_hash_param/instances/:token_id/transfers", V2.TokenController, :transfers_by_instance) @@ -273,10 +220,19 @@ defmodule BlockScoutWeb.ApiRouter do get("/transactions/watchlist", V2.MainPageController, :watchlist_transactions) get("/indexing-status", V2.MainPageController, :indexing_status) - if System.get_env("CHAIN_TYPE") == "polygon_zkevm" do + if Application.compile_env(:explorer, :chain_type) == :optimism do + get("/optimism-deposits", V2.MainPageController, :optimism_deposits) + end + + if Application.compile_env(:explorer, :chain_type) == :polygon_zkevm do get("/zkevm/batches/confirmed", V2.PolygonZkevmController, :batches_confirmed) get("/zkevm/batches/latest-number", V2.PolygonZkevmController, :batch_latest_number) end + + if Application.compile_env(:explorer, :chain_type) == :zksync do + get("/zksync/batches/confirmed", V2.ZkSyncController, :batches_confirmed) + get("/zksync/batches/latest-number", V2.ZkSyncController, :batch_latest_number) + end end scope "/stats" do @@ -285,11 +241,27 @@ defmodule BlockScoutWeb.ApiRouter do scope "/charts" do get("/transactions", V2.StatsController, :transactions_chart) get("/market", V2.StatsController, :market_chart) + get("/secondary-coin-market", V2.StatsController, :secondary_coin_market_chart) + end + end + + scope "/optimism" do + if Application.compile_env(:explorer, :chain_type) == :optimism do + get("/txn-batches", V2.OptimismController, :txn_batches) + get("/txn-batches/count", V2.OptimismController, :txn_batches_count) + get("/output-roots", V2.OptimismController, :output_roots) + get("/output-roots/count", V2.OptimismController, :output_roots_count) + get("/deposits", V2.OptimismController, :deposits) + get("/deposits/count", V2.OptimismController, :deposits_count) + get("/withdrawals", V2.OptimismController, :withdrawals) + get("/withdrawals/count", V2.OptimismController, :withdrawals_count) + get("/games", V2.OptimismController, :games) + get("/games/count", V2.OptimismController, :games_count) end end scope "/polygon-edge" do - if System.get_env("CHAIN_TYPE") == "polygon_edge" do + if Application.compile_env(:explorer, :chain_type) == :polygon_edge do get("/deposits", V2.PolygonEdgeController, :deposits) get("/deposits/count", V2.PolygonEdgeController, :deposits_count) get("/withdrawals", V2.PolygonEdgeController, :withdrawals) @@ -298,7 +270,7 @@ defmodule BlockScoutWeb.ApiRouter do end scope "/shibarium" do - if System.get_env("CHAIN_TYPE") == "shibarium" do + if Application.compile_env(:explorer, :chain_type) == :shibarium do get("/deposits", V2.ShibariumController, :deposits) get("/deposits/count", V2.ShibariumController, :deposits_count) get("/withdrawals", V2.ShibariumController, :withdrawals) @@ -312,7 +284,7 @@ defmodule BlockScoutWeb.ApiRouter do end scope "/zkevm" do - if System.get_env("CHAIN_TYPE") == "polygon_zkevm" do + if Application.compile_env(:explorer, :chain_type) == :polygon_zkevm do get("/batches", V2.PolygonZkevmController, :batches) get("/batches/count", V2.PolygonZkevmController, :batches_count) get("/batches/:batch_number", V2.PolygonZkevmController, :batch) @@ -334,6 +306,7 @@ defmodule BlockScoutWeb.ApiRouter do scope "/account-abstraction" do get("/operations/:operation_hash_param", V2.Proxy.AccountAbstractionController, :operation) + get("/operations/:operation_hash_param/summary", V2.Proxy.AccountAbstractionController, :summary) get("/bundlers/:address_hash_param", V2.Proxy.AccountAbstractionController, :bundler) get("/bundlers", V2.Proxy.AccountAbstractionController, :bundlers) get("/factories/:address_hash_param", V2.Proxy.AccountAbstractionController, :factory) @@ -345,13 +318,47 @@ defmodule BlockScoutWeb.ApiRouter do get("/bundles", V2.Proxy.AccountAbstractionController, :bundles) get("/operations", V2.Proxy.AccountAbstractionController, :operations) end + + scope "/zerion" do + get("/wallets/:address_hash_param/portfolio", V2.Proxy.ZerionController, :wallet_portfolio) + end end scope "/blobs" do - if System.get_env("CHAIN_TYPE") == "ethereum" do + if Application.compile_env(:explorer, :chain_type) == :ethereum do get("/:blob_hash_param", V2.BlobController, :blob) end end + + scope "/validators" do + if Application.compile_env(:explorer, :chain_type) == :stability do + scope "/stability" do + get("/", V2.ValidatorController, :stability_validators_list) + get("/counters", V2.ValidatorController, :stability_validators_counters) + end + end + end + + scope "/zksync" do + if Application.compile_env(:explorer, :chain_type) == :zksync do + get("/batches", V2.ZkSyncController, :batches) + get("/batches/count", V2.ZkSyncController, :batches_count) + get("/batches/:batch_number", V2.ZkSyncController, :batch) + end + end + end + + scope "/v1/graphql" do + pipe_through(:api_v1_graphql) + + if Application.compile_env(:block_scout_web, Api.GraphQL)[:enabled] do + forward("/", Absinthe.Plug, + schema: BlockScoutWeb.GraphQL.Schema, + analyze_complexity: true, + max_complexity: Application.compile_env(:block_scout_web, Api.GraphQL)[:max_complexity], + token_limit: Application.compile_env(:block_scout_web, Api.GraphQL)[:token_limit] + ) + end end scope "/v1", as: :api_v1 do @@ -363,14 +370,6 @@ defmodule BlockScoutWeb.ApiRouter do # leave the same endpoint in v1 in order to keep backward compatibility get("/search", SearchController, :search) - @max_complexity 200 - - forward("/graphql", Absinthe.Plug, - schema: BlockScoutWeb.Schema, - analyze_complexity: true, - max_complexity: @max_complexity - ) - get("/transactions-csv", AddressTransactionController, :transactions_csv) get("/token-transfers-csv", AddressTransactionController, :token_transfers_csv) diff --git a/apps/block_scout_web/lib/block_scout_web/application.ex b/apps/block_scout_web/lib/block_scout_web/application.ex index f323ef8e959d..6c33c11900a6 100644 --- a/apps/block_scout_web/lib/block_scout_web/application.ex +++ b/apps/block_scout_web/lib/block_scout_web/application.ex @@ -7,14 +7,15 @@ defmodule BlockScoutWeb.Application do alias BlockScoutWeb.API.APILogger alias BlockScoutWeb.Counters.{BlocksIndexedCounter, InternalTransactionsIndexedCounter} - alias BlockScoutWeb.{Endpoint, Prometheus} - alias BlockScoutWeb.{MainPageRealtimeEventHandler, RealtimeEventHandler, SmartContractRealtimeEventHandler} + alias BlockScoutWeb.Prometheus.{Exporter, PhoenixInstrumenter} + alias BlockScoutWeb.{Endpoint, MainPageRealtimeEventHandler, RealtimeEventHandler, SmartContractRealtimeEventHandler} + alias BlockScoutWeb.Utility.EventHandlersMetrics def start(_type, _args) do import Supervisor - Prometheus.Instrumenter.setup() - Prometheus.Exporter.setup() + PhoenixInstrumenter.setup() + Exporter.setup() APILogger.message( "Current global API rate limit #{inspect(Application.get_env(:block_scout_web, :api_rate_limit)[:global_limit])} reqs/sec" @@ -38,7 +39,8 @@ defmodule BlockScoutWeb.Application do {RealtimeEventHandler, name: RealtimeEventHandler}, {SmartContractRealtimeEventHandler, name: SmartContractRealtimeEventHandler}, {BlocksIndexedCounter, name: BlocksIndexedCounter}, - {InternalTransactionsIndexedCounter, name: InternalTransactionsIndexedCounter} + {InternalTransactionsIndexedCounter, name: InternalTransactionsIndexedCounter}, + {EventHandlersMetrics, []} ] opts = [strategy: :one_for_one, name: BlockScoutWeb.Supervisor, max_restarts: 1_000] diff --git a/apps/block_scout_web/lib/block_scout_web/chain.ex b/apps/block_scout_web/lib/block_scout_web/chain.ex index 5dff1d691b5e..8125942f7f98 100644 --- a/apps/block_scout_web/lib/block_scout_web/chain.ex +++ b/apps/block_scout_web/lib/block_scout_web/chain.ex @@ -11,13 +11,14 @@ defmodule BlockScoutWeb.Chain do number_to_block: 1, string_to_address_hash: 1, string_to_block_hash: 1, - string_to_transaction_hash: 1, - token_contract_address_from_token_name: 1 + string_to_transaction_hash: 1 ] import Explorer.Helper, only: [parse_integer: 1] + alias BlockScoutWeb.PagingHelper alias Ecto.Association.NotLoaded + alias Explorer.Chain.UserOperation alias Explorer.Account.{TagAddress, TagTransaction, WatchlistAddress} alias Explorer.Chain.Beacon.Reader, as: BeaconReader alias Explorer.Chain.Block.Reward @@ -31,6 +32,7 @@ defmodule BlockScoutWeb.Chain do Hash, InternalTransaction, Log, + Search, SmartContract, Token, Token.Instance, @@ -41,6 +43,9 @@ defmodule BlockScoutWeb.Chain do Wei } + alias Explorer.Chain.Optimism.Deposit, as: OptimismDeposit + alias Explorer.Chain.Optimism.OutputRoot, as: OptimismOutputRoot + alias Explorer.Chain.PolygonZkevm.TransactionBatch alias Explorer.PagingOptions @@ -101,7 +106,7 @@ defmodule BlockScoutWeb.Chain do def from_param(string) when is_binary(string) do case param_to_block_number(string) do {:ok, number} -> number_to_block(number) - _ -> token_address_from_name(string) + _ -> search_ens_domain(string) end end @@ -337,6 +342,16 @@ defmodule BlockScoutWeb.Chain do [paging_options: %{@default_paging_options | key: {index}}] end + def paging_options(%{"nonce" => nonce_string}) when is_binary(nonce_string) do + case Integer.parse(nonce_string) do + {nonce, ""} -> + [paging_options: %{@default_paging_options | key: {nonce}}] + + _ -> + [paging_options: @default_paging_options] + end + end + def paging_options(%{"number" => number_string}) when is_binary(number_string) do case Integer.parse(number_string) do {number, ""} -> @@ -347,6 +362,10 @@ defmodule BlockScoutWeb.Chain do end end + def paging_options(%{"nonce" => nonce}) when is_integer(nonce) do + [paging_options: %{@default_paging_options | key: {nonce}}] + end + def paging_options(%{"number" => number}) when is_integer(number) do [paging_options: %{@default_paging_options | key: {number}}] end @@ -404,6 +423,16 @@ defmodule BlockScoutWeb.Chain do end end + def paging_options(%{"l1_block_number" => block_number, "tx_hash" => tx_hash}) do + with {block_number, ""} <- Integer.parse(block_number), + {:ok, tx_hash} <- string_to_transaction_hash(tx_hash) do + [paging_options: %{@default_paging_options | key: {block_number, tx_hash}}] + else + _ -> + [paging_options: @default_paging_options] + end + end + # clause for Polygon Edge Deposits and Withdrawals and for account's entities pagination def paging_options(%{"id" => id_string}) when is_binary(id_string) do case Integer.parse(id_string) do @@ -432,6 +461,41 @@ defmodule BlockScoutWeb.Chain do [paging_options: %{@default_paging_options | key: {token_contract_address_hash, token_type}}] end + # Clause for `Explorer.Chain.Stability.Validator`, + # returned by `BlockScoutWeb.API.V2.ValidatorController.stability_validators_list/2` (`/api/v2/validators/stability`) + def paging_options(%{ + "state" => state, + "address_hash" => address_hash_string, + "blocks_validated" => blocks_validated_string + }) do + [ + paging_options: %{ + @default_paging_options + | key: %{ + address_hash: parse_address_hash(address_hash_string), + blocks_validated: parse_integer(blocks_validated_string), + state: if(state in PagingHelper.allowed_stability_validators_states(), do: state) + } + } + ] + end + + # Clause for InternalTransaction by block: + # returned by `BlockScoutWeb.API.V2.BlockController.internal_transactions/2` (`/api/v2/blocks/:block_hash_or_number/internal-transactions`) + def paging_options(%{"block_index" => index_string}) when is_binary(index_string) do + case Integer.parse(index_string) do + {index, ""} -> + [paging_options: %{@default_paging_options | key: %{block_index: index}}] + + _ -> + [paging_options: @default_paging_options] + end + end + + def paging_options(%{"block_index" => index}) when is_integer(index) do + [paging_options: %{@default_paging_options | key: %{block_index: index}}] + end + def paging_options(_params), do: [paging_options: @default_paging_options] def put_key_value_to_paging_options([paging_options: paging_options], key, value) do @@ -507,10 +571,20 @@ defmodule BlockScoutWeb.Chain do end end - defp token_address_from_name(name) do - case token_contract_address_from_token_name(name) do - {:ok, hash} -> find_or_insert_address_from_hash(hash) - _ -> {:error, :not_found} + defp search_ens_domain(search_query) do + case Search.search_ens_name_in_bens(search_query) do + nil -> + {:error, :not_found} + + result -> + {:ok, result} + end + end + + defp parse_address_hash(address_hash_string) do + case Hash.Address.cast(address_hash_string) do + {:ok, address_hash} -> address_hash + _ -> nil end end @@ -602,6 +676,14 @@ defmodule BlockScoutWeb.Chain do %{"smart_contract_id" => smart_contract.id} end + defp paging_params(%OptimismDeposit{l1_block_number: l1_block_number, l2_transaction_hash: l2_tx_hash}) do + %{"l1_block_number" => l1_block_number, "tx_hash" => l2_tx_hash} + end + + defp paging_params(%OptimismOutputRoot{l2_output_index: index}) do + %{"index" => index} + end + defp paging_params(%SmartContract{} = smart_contract) do %{ "smart_contract_id" => smart_contract.id, @@ -615,6 +697,14 @@ defmodule BlockScoutWeb.Chain do %{"index" => index} end + defp paging_params(%{msg_nonce: nonce}) do + %{"nonce" => nonce} + end + + defp paging_params(%{l2_block_number: block_number}) do + %{"block_number" => block_number} + end + # clause for zkEVM batches pagination defp paging_params(%TransactionBatch{number: number}) do %{"number" => number} @@ -695,7 +785,7 @@ defmodule BlockScoutWeb.Chain do end defp hash_to_blob(hash) do - if Application.get_env(:explorer, :chain_type) == "ethereum" do + if Application.get_env(:explorer, :chain_type) == :ethereum do BeaconReader.blob(hash, false) else {:error, :not_found} diff --git a/apps/block_scout_web/lib/block_scout_web/channels/address_channel.ex b/apps/block_scout_web/lib/block_scout_web/channels/address_channel.ex index 89795fb8a76f..8f95108bb2be 100644 --- a/apps/block_scout_web/lib/block_scout_web/channels/address_channel.ex +++ b/apps/block_scout_web/lib/block_scout_web/channels/address_channel.ex @@ -193,11 +193,13 @@ defmodule BlockScoutWeb.AddressChannel do ) do coin_balance = Chain.get_coin_balance(socket.assigns.address_hash, block_number) - rendered_coin_balance = AddressViewAPI.render("coin_balance.json", %{coin_balance: coin_balance}) + if coin_balance.value && coin_balance.delta do + rendered_coin_balance = AddressViewAPI.render("coin_balance.json", %{coin_balance: coin_balance}) - push(socket, "coin_balance", %{coin_balance: rendered_coin_balance}) + push(socket, "coin_balance", %{coin_balance: rendered_coin_balance}) - push_current_coin_balance(socket, block_number, coin_balance) + push_current_coin_balance(socket, block_number, coin_balance) + end {:noreply, socket} end @@ -207,19 +209,21 @@ defmodule BlockScoutWeb.AddressChannel do Gettext.put_locale(BlockScoutWeb.Gettext, socket.assigns.locale) - rendered_coin_balance = - View.render_to_string( - AddressCoinBalanceView, - "_coin_balances.html", - conn: socket, - coin_balance: coin_balance - ) + if coin_balance.value && coin_balance.delta do + rendered_coin_balance = + View.render_to_string( + AddressCoinBalanceView, + "_coin_balances.html", + conn: socket, + coin_balance: coin_balance + ) - push(socket, "coin_balance", %{ - coin_balance_html: rendered_coin_balance - }) + push(socket, "coin_balance", %{ + coin_balance_html: rendered_coin_balance + }) - push_current_coin_balance(socket, block_number, coin_balance) + push_current_coin_balance(socket, block_number, coin_balance) + end {:noreply, socket} end @@ -237,6 +241,7 @@ defmodule BlockScoutWeb.AddressChannel do push_current_token_balances(socket, address_current_token_balances, "erc_20", "ERC-20") push_current_token_balances(socket, address_current_token_balances, "erc_721", "ERC-721") push_current_token_balances(socket, address_current_token_balances, "erc_1155", "ERC-1155") + push_current_token_balances(socket, address_current_token_balances, "erc_404", "ERC-404") {:noreply, socket} end diff --git a/apps/block_scout_web/lib/block_scout_web/channels/optimism_deposit_channel.ex b/apps/block_scout_web/lib/block_scout_web/channels/optimism_deposit_channel.ex new file mode 100644 index 000000000000..3f2c513f9b1c --- /dev/null +++ b/apps/block_scout_web/lib/block_scout_web/channels/optimism_deposit_channel.ex @@ -0,0 +1,22 @@ +defmodule BlockScoutWeb.OptimismDepositChannel do + @moduledoc """ + Establishes pub/sub channel for live updates of Optimism deposit events. + """ + use BlockScoutWeb, :channel + + intercept(["deposits"]) + + def join("optimism_deposits:new_deposits", _params, socket) do + {:ok, %{}, socket} + end + + def handle_out( + "deposits", + %{deposits: deposits}, + %Phoenix.Socket{handler: BlockScoutWeb.UserSocketV2} = socket + ) do + push(socket, "deposits", %{deposits: Enum.count(deposits)}) + + {:noreply, socket} + end +end diff --git a/apps/block_scout_web/lib/block_scout_web/channels/transaction_channel.ex b/apps/block_scout_web/lib/block_scout_web/channels/transaction_channel.ex index 5c1247786a05..e1ddb1db5ba3 100644 --- a/apps/block_scout_web/lib/block_scout_web/channels/transaction_channel.ex +++ b/apps/block_scout_web/lib/block_scout_web/channels/transaction_channel.ex @@ -9,7 +9,7 @@ defmodule BlockScoutWeb.TransactionChannel do alias BlockScoutWeb.API.V2.TransactionView, as: TransactionViewV2 alias BlockScoutWeb.{TransactionRawTraceView, TransactionView} alias Explorer.Chain - alias Explorer.Chain.Hash + alias Explorer.Chain.{Hash, InternalTransaction} alias Phoenix.View intercept(["pending_transaction", "transaction", "raw_trace"]) @@ -116,7 +116,7 @@ defmodule BlockScoutWeb.TransactionChannel do %{raw_trace_origin: transaction_hash}, %Phoenix.Socket{handler: BlockScoutWeb.UserSocketV2} = socket ) do - internal_transactions = Chain.all_transaction_to_internal_transactions(transaction_hash) + internal_transactions = InternalTransaction.all_transaction_to_internal_transactions(transaction_hash) push(socket, "raw_trace", %{ raw_trace: TransactionViewV2.render("raw_trace.json", %{internal_transactions: internal_transactions}) @@ -130,7 +130,7 @@ defmodule BlockScoutWeb.TransactionChannel do %{raw_trace_origin: transaction_hash}, socket ) do - internal_transactions = Chain.all_transaction_to_internal_transactions(transaction_hash) + internal_transactions = InternalTransaction.all_transaction_to_internal_transactions(transaction_hash) push(socket, "raw_trace", %{ raw_trace: diff --git a/apps/block_scout_web/lib/block_scout_web/channels/user_socket.ex b/apps/block_scout_web/lib/block_scout_web/channels/user_socket.ex index 6060428a7981..7f1b4993a184 100644 --- a/apps/block_scout_web/lib/block_scout_web/channels/user_socket.ex +++ b/apps/block_scout_web/lib/block_scout_web/channels/user_socket.ex @@ -1,10 +1,11 @@ defmodule BlockScoutWeb.UserSocket do use Phoenix.Socket - use Absinthe.Phoenix.Socket, schema: BlockScoutWeb.Schema + use Absinthe.Phoenix.Socket, schema: BlockScoutWeb.GraphQL.Schema channel("addresses:*", BlockScoutWeb.AddressChannel) channel("blocks:*", BlockScoutWeb.BlockChannel) channel("exchange_rate:*", BlockScoutWeb.ExchangeRateChannel) + channel("optimism_deposits:*", BlockScoutWeb.OptimismDepositChannel) channel("rewards:*", BlockScoutWeb.RewardChannel) channel("transactions:*", BlockScoutWeb.TransactionChannel) channel("tokens:*", BlockScoutWeb.TokenChannel) diff --git a/apps/block_scout_web/lib/block_scout_web/channels/user_socket_v2.ex b/apps/block_scout_web/lib/block_scout_web/channels/user_socket_v2.ex index ec3e5460ecc4..740b716dc322 100644 --- a/apps/block_scout_web/lib/block_scout_web/channels/user_socket_v2.ex +++ b/apps/block_scout_web/lib/block_scout_web/channels/user_socket_v2.ex @@ -7,6 +7,7 @@ defmodule BlockScoutWeb.UserSocketV2 do channel("addresses:*", BlockScoutWeb.AddressChannel) channel("blocks:*", BlockScoutWeb.BlockChannel) channel("exchange_rate:*", BlockScoutWeb.ExchangeRateChannel) + channel("optimism_deposits:*", BlockScoutWeb.OptimismDepositChannel) channel("rewards:*", BlockScoutWeb.RewardChannel) channel("transactions:*", BlockScoutWeb.TransactionChannel) channel("tokens:*", BlockScoutWeb.TokenChannel) diff --git a/apps/block_scout_web/lib/block_scout_web/controllers/account/api/v1/authenticate_controller.ex b/apps/block_scout_web/lib/block_scout_web/controllers/account/api/v2/authenticate_controller.ex similarity index 87% rename from apps/block_scout_web/lib/block_scout_web/controllers/account/api/v1/authenticate_controller.ex rename to apps/block_scout_web/lib/block_scout_web/controllers/account/api/v2/authenticate_controller.ex index 0c16034d0217..b0b9454a8387 100644 --- a/apps/block_scout_web/lib/block_scout_web/controllers/account/api/v1/authenticate_controller.ex +++ b/apps/block_scout_web/lib/block_scout_web/controllers/account/api/v2/authenticate_controller.ex @@ -1,4 +1,4 @@ -defmodule BlockScoutWeb.Account.Api.V1.AuthenticateController do +defmodule BlockScoutWeb.Account.Api.V2.AuthenticateController do use BlockScoutWeb, :controller import BlockScoutWeb.Account.AuthController, only: [current_user: 1] @@ -6,7 +6,7 @@ defmodule BlockScoutWeb.Account.Api.V1.AuthenticateController do alias BlockScoutWeb.Models.UserFromAuth alias Explorer.Account.Identity - action_fallback(BlockScoutWeb.Account.Api.V1.FallbackController) + action_fallback(BlockScoutWeb.Account.Api.V2.FallbackController) def authenticate_get(conn, params) do authenticate(conn, params) diff --git a/apps/block_scout_web/lib/block_scout_web/controllers/account/api/v1/email_controller.ex b/apps/block_scout_web/lib/block_scout_web/controllers/account/api/v2/email_controller.ex similarity index 94% rename from apps/block_scout_web/lib/block_scout_web/controllers/account/api/v1/email_controller.ex rename to apps/block_scout_web/lib/block_scout_web/controllers/account/api/v2/email_controller.ex index 9e79c2d33645..c9b7f321e1cc 100644 --- a/apps/block_scout_web/lib/block_scout_web/controllers/account/api/v1/email_controller.ex +++ b/apps/block_scout_web/lib/block_scout_web/controllers/account/api/v2/email_controller.ex @@ -1,4 +1,4 @@ -defmodule BlockScoutWeb.Account.Api.V1.EmailController do +defmodule BlockScoutWeb.Account.Api.V2.EmailController do use BlockScoutWeb, :controller alias BlockScoutWeb.Models.UserFromAuth @@ -10,7 +10,7 @@ defmodule BlockScoutWeb.Account.Api.V1.EmailController do @invalid_session_key Application.compile_env(:block_scout_web, :invalid_session_key) - action_fallback(BlockScoutWeb.Account.Api.V1.FallbackController) + action_fallback(BlockScoutWeb.Account.Api.V2.FallbackController) plug(:fetch_cookies, signed: [@invalid_session_key]) diff --git a/apps/block_scout_web/lib/block_scout_web/controllers/account/api/v1/fallback_controller.ex b/apps/block_scout_web/lib/block_scout_web/controllers/account/api/v2/fallback_controller.ex similarity index 96% rename from apps/block_scout_web/lib/block_scout_web/controllers/account/api/v1/fallback_controller.ex rename to apps/block_scout_web/lib/block_scout_web/controllers/account/api/v2/fallback_controller.ex index 14d44fffb3c0..a4821b23e41f 100644 --- a/apps/block_scout_web/lib/block_scout_web/controllers/account/api/v1/fallback_controller.ex +++ b/apps/block_scout_web/lib/block_scout_web/controllers/account/api/v2/fallback_controller.ex @@ -1,7 +1,7 @@ -defmodule BlockScoutWeb.Account.Api.V1.FallbackController do +defmodule BlockScoutWeb.Account.Api.V2.FallbackController do use Phoenix.Controller - alias BlockScoutWeb.Account.Api.V1.UserView + alias BlockScoutWeb.Account.Api.V2.UserView alias Ecto.Changeset def call(conn, {:identity, _}) do diff --git a/apps/block_scout_web/lib/block_scout_web/controllers/account/api/v1/tags_controller.ex b/apps/block_scout_web/lib/block_scout_web/controllers/account/api/v2/tags_controller.ex similarity index 96% rename from apps/block_scout_web/lib/block_scout_web/controllers/account/api/v1/tags_controller.ex rename to apps/block_scout_web/lib/block_scout_web/controllers/account/api/v2/tags_controller.ex index 3549024f905c..13c37f48b551 100644 --- a/apps/block_scout_web/lib/block_scout_web/controllers/account/api/v1/tags_controller.ex +++ b/apps/block_scout_web/lib/block_scout_web/controllers/account/api/v2/tags_controller.ex @@ -1,4 +1,4 @@ -defmodule BlockScoutWeb.Account.Api.V1.TagsController do +defmodule BlockScoutWeb.Account.Api.V2.TagsController do use BlockScoutWeb, :controller import BlockScoutWeb.Account.AuthController, only: [current_user: 1] @@ -8,7 +8,7 @@ defmodule BlockScoutWeb.Account.Api.V1.TagsController do alias Explorer.{Chain, Repo} alias Explorer.Chain.Hash.{Address, Full} - action_fallback(BlockScoutWeb.Account.Api.V1.FallbackController) + action_fallback(BlockScoutWeb.Account.Api.V2.FallbackController) def tags_address(conn, %{"address_hash" => address_hash}) do personal_tags = diff --git a/apps/block_scout_web/lib/block_scout_web/controllers/account/api/v1/user_controller.ex b/apps/block_scout_web/lib/block_scout_web/controllers/account/api/v2/user_controller.ex similarity index 87% rename from apps/block_scout_web/lib/block_scout_web/controllers/account/api/v1/user_controller.ex rename to apps/block_scout_web/lib/block_scout_web/controllers/account/api/v2/user_controller.ex index 724378cc69d6..89e60d607f61 100644 --- a/apps/block_scout_web/lib/block_scout_web/controllers/account/api/v1/user_controller.ex +++ b/apps/block_scout_web/lib/block_scout_web/controllers/account/api/v2/user_controller.ex @@ -1,4 +1,4 @@ -defmodule BlockScoutWeb.Account.Api.V1.UserController do +defmodule BlockScoutWeb.Account.Api.V2.UserController do use BlockScoutWeb, :controller import BlockScoutWeb.Account.AuthController, only: [current_user: 1] @@ -12,8 +12,6 @@ defmodule BlockScoutWeb.Account.Api.V1.UserController do import BlockScoutWeb.PagingHelper, only: [delete_parameters_from_next_page_params: 1] - import Ecto.Query, only: [from: 2] - alias BlockScoutWeb.Models.UserFromAuth alias Explorer.Account.Api.Key, as: ApiKey alias Explorer.Account.CustomABI @@ -21,7 +19,7 @@ defmodule BlockScoutWeb.Account.Api.V1.UserController do alias Explorer.{Chain, Market, PagingOptions, Repo} alias Plug.CSRFProtection - action_fallback(BlockScoutWeb.Account.Api.V1.FallbackController) + action_fallback(BlockScoutWeb.Account.Api.V2.FallbackController) @ok_message "OK" @token_balances_amount 150 @@ -35,44 +33,6 @@ defmodule BlockScoutWeb.Account.Api.V1.UserController do end end - def watchlist_old(conn, _params) do - with {:auth, %{id: uid}} <- {:auth, current_user(conn)}, - {:identity, %Identity{} = identity} <- {:identity, UserFromAuth.find_identity(uid)}, - {:watchlist, %{watchlists: [watchlist | _]}} <- - {:watchlist, Repo.account_repo().preload(identity, :watchlists)}, - watchlist_with_addresses <- preload_watchlist_addresses(watchlist) do - watchlist_addresses = - Enum.map(watchlist_with_addresses.watchlist_addresses, fn wa -> - balances = - Chain.fetch_paginated_last_token_balances(wa.address_hash, - paging_options: %PagingOptions{page_size: @token_balances_amount + 1} - ) - - count = Enum.count(balances) - overflow? = count > @token_balances_amount - - fiat_sum = - balances - |> Enum.take(@token_balances_amount) - |> Enum.reduce(Decimal.new(0), fn tb, acc -> Decimal.add(acc, tb.fiat_value || 0) end) - - %WatchlistAddress{ - wa - | tokens_fiat_value: fiat_sum, - tokens_count: min(count, @token_balances_amount), - tokens_overflow: overflow? - } - end) - - conn - |> put_status(200) - |> render(:watchlist_addresses, %{ - exchange_rate: Market.get_coin_exchange_rate(), - watchlist_addresses: watchlist_addresses - }) - end - end - def watchlist(conn, params) do with {:auth, %{id: uid}} <- {:auth, current_user(conn)}, {:identity, %Identity{} = identity} <- {:identity, UserFromAuth.find_identity(uid)}, @@ -146,12 +106,15 @@ defmodule BlockScoutWeb.Account.Api.V1.UserController do "ERC-721" => %{ "incoming" => watch_erc_721_input, "outcoming" => watch_erc_721_output - } - # , + }, # "ERC-1155" => %{ # "incoming" => watch_erc_1155_input, # "outcoming" => watch_erc_1155_output - # } + # }, + "ERC-404" => %{ + "incoming" => watch_erc_404_input, + "outcoming" => watch_erc_404_output + } }, "notification_methods" => %{ "email" => notify_email @@ -167,6 +130,8 @@ defmodule BlockScoutWeb.Account.Api.V1.UserController do watch_erc_721_output: watch_erc_721_output, watch_erc_1155_input: watch_erc_721_input, watch_erc_1155_output: watch_erc_721_output, + watch_erc_404_input: watch_erc_404_input, + watch_erc_404_output: watch_erc_404_output, notify_email: notify_email, address_hash: address_hash } @@ -202,12 +167,15 @@ defmodule BlockScoutWeb.Account.Api.V1.UserController do "ERC-721" => %{ "incoming" => watch_erc_721_input, "outcoming" => watch_erc_721_output - } - # , + }, # "ERC-1155" => %{ # "incoming" => watch_erc_1155_input, # "outcoming" => watch_erc_1155_output - # } + # }, + "ERC-404" => %{ + "incoming" => watch_erc_404_input, + "outcoming" => watch_erc_404_output + } }, "notification_methods" => %{ "email" => notify_email @@ -224,6 +192,8 @@ defmodule BlockScoutWeb.Account.Api.V1.UserController do watch_erc_721_output: watch_erc_721_output, watch_erc_1155_input: watch_erc_721_input, watch_erc_1155_output: watch_erc_721_output, + watch_erc_404_input: watch_erc_404_input, + watch_erc_404_output: watch_erc_404_output, notify_email: notify_email, address_hash: address_hash } @@ -243,16 +213,6 @@ defmodule BlockScoutWeb.Account.Api.V1.UserController do end end - def tags_address_old(conn, _params) do - with {:auth, %{id: uid}} <- {:auth, current_user(conn)}, - {:identity, %Identity{} = identity} <- {:identity, UserFromAuth.find_identity(uid)}, - address_tags <- TagAddress.get_tags_address_by_identity_id(identity.id) do - conn - |> put_status(200) - |> render(:address_tags, %{address_tags: address_tags}) - end - end - def tags_address(conn, params) do with {:auth, %{id: uid}} <- {:auth, current_user(conn)}, {:identity, %Identity{} = identity} <- {:identity, UserFromAuth.find_identity(uid)} do @@ -312,16 +272,6 @@ defmodule BlockScoutWeb.Account.Api.V1.UserController do end end - def tags_transaction_old(conn, _params) do - with {:auth, %{id: uid}} <- {:auth, current_user(conn)}, - {:identity, %Identity{} = identity} <- {:identity, UserFromAuth.find_identity(uid)}, - transaction_tags <- TagTransaction.get_tags_transaction_by_identity_id(identity.id) do - conn - |> put_status(200) - |> render(:transaction_tags, %{transaction_tags: transaction_tags}) - end - end - def tags_transaction(conn, params) do with {:auth, %{id: uid}} <- {:auth, current_user(conn)}, {:identity, %Identity{} = identity} <- {:identity, UserFromAuth.find_identity(uid)} do @@ -573,9 +523,4 @@ defmodule BlockScoutWeb.Account.Api.V1.UserController do defp reject_nil_map_values(map) when is_map(map) do Map.reject(map, fn {_k, v} -> is_nil(v) end) end - - defp preload_watchlist_addresses(watchlist) do - watchlist - |> Repo.account_repo().preload(watchlist_addresses: from(wa in WatchlistAddress, order_by: [desc: wa.id])) - end end diff --git a/apps/block_scout_web/lib/block_scout_web/controllers/address_coin_balance_controller.ex b/apps/block_scout_web/lib/block_scout_web/controllers/address_coin_balance_controller.ex index c0bbf0097584..6ab39700b629 100644 --- a/apps/block_scout_web/lib/block_scout_web/controllers/address_coin_balance_controller.ex +++ b/apps/block_scout_web/lib/block_scout_web/controllers/address_coin_balance_controller.ex @@ -12,7 +12,7 @@ defmodule BlockScoutWeb.AddressCoinBalanceController do alias BlockScoutWeb.{AccessHelper, AddressCoinBalanceView, Controller} alias Explorer.{Chain, Market} alias Explorer.Chain.{Address, Wei} - alias Indexer.Fetcher.CoinBalanceOnDemand + alias Indexer.Fetcher.OnDemand.CoinBalance, as: CoinBalanceOnDemand alias Phoenix.View def index(conn, %{"address_id" => address_hash_string, "type" => "JSON"} = params) do diff --git a/apps/block_scout_web/lib/block_scout_web/controllers/address_contract_controller.ex b/apps/block_scout_web/lib/block_scout_web/controllers/address_contract_controller.ex index a43c5c7b2b1c..48598c1c21ed 100644 --- a/apps/block_scout_web/lib/block_scout_web/controllers/address_contract_controller.ex +++ b/apps/block_scout_web/lib/block_scout_web/controllers/address_contract_controller.ex @@ -8,7 +8,7 @@ defmodule BlockScoutWeb.AddressContractController do alias BlockScoutWeb.AccessHelper alias Explorer.{Chain, Market} alias Explorer.SmartContract.Solidity.PublishHelper - alias Indexer.Fetcher.CoinBalanceOnDemand + alias Indexer.Fetcher.OnDemand.CoinBalance, as: CoinBalanceOnDemand def index(conn, %{"address_id" => address_hash_string} = params) do address_options = [ diff --git a/apps/block_scout_web/lib/block_scout_web/controllers/address_controller.ex b/apps/block_scout_web/lib/block_scout_web/controllers/address_controller.ex index 3e50dff92ba7..96556cc387ee 100644 --- a/apps/block_scout_web/lib/block_scout_web/controllers/address_controller.ex +++ b/apps/block_scout_web/lib/block_scout_web/controllers/address_controller.ex @@ -17,7 +17,8 @@ defmodule BlockScoutWeb.AddressController do alias Explorer.{Chain, Market} alias Explorer.Chain.Address.Counters alias Explorer.Chain.{Address, Wei} - alias Indexer.Fetcher.CoinBalanceOnDemand + alias Indexer.Fetcher.OnDemand.CoinBalance, as: CoinBalanceOnDemand + alias Indexer.Fetcher.OnDemand.ContractCode, as: ContractCodeOnDemand alias Phoenix.View def index(conn, %{"type" => "JSON"} = params) do @@ -96,6 +97,8 @@ defmodule BlockScoutWeb.AddressController do with {:ok, address_hash} <- Chain.string_to_address_hash(address_hash_string), {:ok, address} <- Chain.hash_to_address(address_hash), {:ok, false} <- AccessHelper.restricted_access?(address_hash_string, params) do + ContractCodeOnDemand.trigger_fetch(address) + render( conn, "_show_address_transactions.html", diff --git a/apps/block_scout_web/lib/block_scout_web/controllers/address_decompiled_contract_controller.ex b/apps/block_scout_web/lib/block_scout_web/controllers/address_decompiled_contract_controller.ex index 69c2d7dc0f6f..89ff14b1c6d9 100644 --- a/apps/block_scout_web/lib/block_scout_web/controllers/address_decompiled_contract_controller.ex +++ b/apps/block_scout_web/lib/block_scout_web/controllers/address_decompiled_contract_controller.ex @@ -6,7 +6,7 @@ defmodule BlockScoutWeb.AddressDecompiledContractController do alias BlockScoutWeb.AccessHelper alias Explorer.{Chain, Market} - alias Indexer.Fetcher.CoinBalanceOnDemand + alias Indexer.Fetcher.OnDemand.CoinBalance, as: CoinBalanceOnDemand def index(conn, %{"address_id" => address_hash_string} = params) do with {:ok, address_hash} <- Chain.string_to_address_hash(address_hash_string), diff --git a/apps/block_scout_web/lib/block_scout_web/controllers/address_internal_transaction_controller.ex b/apps/block_scout_web/lib/block_scout_web/controllers/address_internal_transaction_controller.ex index 92fbe1712b44..30e81a09122c 100644 --- a/apps/block_scout_web/lib/block_scout_web/controllers/address_internal_transaction_controller.ex +++ b/apps/block_scout_web/lib/block_scout_web/controllers/address_internal_transaction_controller.ex @@ -12,7 +12,7 @@ defmodule BlockScoutWeb.AddressInternalTransactionController do alias BlockScoutWeb.{AccessHelper, Controller, InternalTransactionView} alias Explorer.{Chain, Market} alias Explorer.Chain.{Address, Wei} - alias Indexer.Fetcher.CoinBalanceOnDemand + alias Indexer.Fetcher.OnDemand.CoinBalance, as: CoinBalanceOnDemand alias Phoenix.View def index(conn, %{"address_id" => address_hash_string, "type" => "JSON"} = params) do diff --git a/apps/block_scout_web/lib/block_scout_web/controllers/address_logs_controller.ex b/apps/block_scout_web/lib/block_scout_web/controllers/address_logs_controller.ex index b76d713d3927..21d0977fcdbd 100644 --- a/apps/block_scout_web/lib/block_scout_web/controllers/address_logs_controller.ex +++ b/apps/block_scout_web/lib/block_scout_web/controllers/address_logs_controller.ex @@ -12,7 +12,7 @@ defmodule BlockScoutWeb.AddressLogsController do alias BlockScoutWeb.{AccessHelper, AddressLogsView, Controller} alias Explorer.{Chain, Market} alias Explorer.Chain.Address - alias Indexer.Fetcher.CoinBalanceOnDemand + alias Indexer.Fetcher.OnDemand.CoinBalance, as: CoinBalanceOnDemand alias Phoenix.View use BlockScoutWeb, :controller diff --git a/apps/block_scout_web/lib/block_scout_web/controllers/address_read_contract_controller.ex b/apps/block_scout_web/lib/block_scout_web/controllers/address_read_contract_controller.ex index ae534280cc74..6f792b6a1752 100644 --- a/apps/block_scout_web/lib/block_scout_web/controllers/address_read_contract_controller.ex +++ b/apps/block_scout_web/lib/block_scout_web/controllers/address_read_contract_controller.ex @@ -16,7 +16,7 @@ defmodule BlockScoutWeb.AddressReadContractController do alias Explorer.{Chain, Market} alias Explorer.Chain.Address alias Explorer.SmartContract.Reader - alias Indexer.Fetcher.CoinBalanceOnDemand + alias Indexer.Fetcher.OnDemand.CoinBalance, as: CoinBalanceOnDemand def index(conn, %{"address_id" => address_hash_string} = params) do address_options = [ diff --git a/apps/block_scout_web/lib/block_scout_web/controllers/address_read_proxy_controller.ex b/apps/block_scout_web/lib/block_scout_web/controllers/address_read_proxy_controller.ex index 5a4d9c981d04..3364dde55207 100644 --- a/apps/block_scout_web/lib/block_scout_web/controllers/address_read_proxy_controller.ex +++ b/apps/block_scout_web/lib/block_scout_web/controllers/address_read_proxy_controller.ex @@ -8,7 +8,7 @@ defmodule BlockScoutWeb.AddressReadProxyController do alias BlockScoutWeb.AccessHelper alias Explorer.{Chain, Market} alias Explorer.Chain.Address - alias Indexer.Fetcher.CoinBalanceOnDemand + alias Indexer.Fetcher.OnDemand.CoinBalance, as: CoinBalanceOnDemand def index(conn, %{"address_id" => address_hash_string} = params) do address_options = [ diff --git a/apps/block_scout_web/lib/block_scout_web/controllers/address_token_balance_controller.ex b/apps/block_scout_web/lib/block_scout_web/controllers/address_token_balance_controller.ex index 5899458fd887..f95d5f4443cf 100644 --- a/apps/block_scout_web/lib/block_scout_web/controllers/address_token_balance_controller.ex +++ b/apps/block_scout_web/lib/block_scout_web/controllers/address_token_balance_controller.ex @@ -4,7 +4,7 @@ defmodule BlockScoutWeb.AddressTokenBalanceController do alias BlockScoutWeb.AccessHelper alias Explorer.Chain alias Explorer.Chain.Address - alias Indexer.Fetcher.TokenBalanceOnDemand + alias Indexer.Fetcher.OnDemand.TokenBalance, as: TokenBalanceOnDemand def index(conn, %{"address_id" => address_hash_string} = params) do with true <- ajax?(conn), diff --git a/apps/block_scout_web/lib/block_scout_web/controllers/address_token_controller.ex b/apps/block_scout_web/lib/block_scout_web/controllers/address_token_controller.ex index d130043d8700..334dfa76dd55 100644 --- a/apps/block_scout_web/lib/block_scout_web/controllers/address_token_controller.ex +++ b/apps/block_scout_web/lib/block_scout_web/controllers/address_token_controller.ex @@ -10,7 +10,7 @@ defmodule BlockScoutWeb.AddressTokenController do alias BlockScoutWeb.{AccessHelper, AddressTokenView, Controller} alias Explorer.{Chain, Market} alias Explorer.Chain.Address - alias Indexer.Fetcher.CoinBalanceOnDemand + alias Indexer.Fetcher.OnDemand.CoinBalance, as: CoinBalanceOnDemand alias Phoenix.View def index(conn, %{"address_id" => address_hash_string, "type" => "JSON"} = params) do diff --git a/apps/block_scout_web/lib/block_scout_web/controllers/address_token_transfer_controller.ex b/apps/block_scout_web/lib/block_scout_web/controllers/address_token_transfer_controller.ex index 94f87de09348..b1e10ed0add7 100644 --- a/apps/block_scout_web/lib/block_scout_web/controllers/address_token_transfer_controller.ex +++ b/apps/block_scout_web/lib/block_scout_web/controllers/address_token_transfer_controller.ex @@ -7,7 +7,7 @@ defmodule BlockScoutWeb.AddressTokenTransferController do alias BlockScoutWeb.{AccessHelper, Controller, TransactionView} alias Explorer.{Chain, Market} alias Explorer.Chain.{Address, DenormalizationHelper} - alias Indexer.Fetcher.CoinBalanceOnDemand + alias Indexer.Fetcher.OnDemand.CoinBalance, as: CoinBalanceOnDemand alias Phoenix.View import BlockScoutWeb.Chain, diff --git a/apps/block_scout_web/lib/block_scout_web/controllers/address_transaction_controller.ex b/apps/block_scout_web/lib/block_scout_web/controllers/address_transaction_controller.ex index a27e3153f118..9e3710ef1364 100644 --- a/apps/block_scout_web/lib/block_scout_web/controllers/address_transaction_controller.ex +++ b/apps/block_scout_web/lib/block_scout_web/controllers/address_transaction_controller.ex @@ -11,8 +11,10 @@ defmodule BlockScoutWeb.AddressTransactionController do import Explorer.Chain.SmartContract, only: [burn_address_hash_string: 0] alias BlockScoutWeb.{AccessHelper, Controller, TransactionView} + alias BlockScoutWeb.API.V2.CSVExportController alias Explorer.{Chain, Market} alias Explorer.Chain.Address + alias Explorer.Chain.CSVExport.Helper, as: CSVHelper alias Explorer.Chain.CSVExport.{ AddressInternalTransactionCsvExporter, @@ -23,7 +25,7 @@ defmodule BlockScoutWeb.AddressTransactionController do alias Explorer.Chain.{DenormalizationHelper, Transaction, Wei} - alias Indexer.Fetcher.CoinBalanceOnDemand + alias Indexer.Fetcher.OnDemand.CoinBalance, as: CoinBalanceOnDemand alias Phoenix.View alias Plug.Conn @@ -166,19 +168,6 @@ defmodule BlockScoutWeb.AddressTransactionController do end end - defp captcha_helper do - :block_scout_web - |> Application.get_env(:captcha_helper) - end - - defp put_resp_params(conn) do - conn - |> put_resp_content_type("application/csv") - |> put_resp_header("content-disposition", "attachment;") - |> put_resp_cookie("csv-downloaded", "true", max_age: 86_400, http_only: false) - |> send_chunked(200) - end - defp items_csv( conn, %{ @@ -192,13 +181,13 @@ defmodule BlockScoutWeb.AddressTransactionController do when is_binary(address_hash_string) do with {:ok, address_hash} <- Chain.string_to_address_hash(address_hash_string), {:address_exists, true} <- {:address_exists, Address.address_exists?(address_hash)}, - {:recaptcha, true} <- {:recaptcha, captcha_helper().recaptcha_passed?(recaptcha_response)} do + {:recaptcha, true} <- {:recaptcha, CSVHelper.captcha_helper().recaptcha_passed?(recaptcha_response)} do filter_type = Map.get(params, "filter_type") filter_value = Map.get(params, "filter_value") address_hash |> csv_export_module.export(from_period, to_period, filter_type, filter_value) - |> Enum.reduce_while(put_resp_params(conn), fn chunk, conn -> + |> Enum.reduce_while(CSVExportController.put_resp_params(conn), fn chunk, conn -> case Conn.chunk(conn, chunk) do {:ok, conn} -> {:cont, conn} @@ -237,7 +226,7 @@ defmodule BlockScoutWeb.AddressTransactionController do address_hash |> csv_export_module.export(from_period, to_period, filter_type, filter_value) - |> Enum.reduce_while(put_resp_params(conn), fn chunk, conn -> + |> Enum.reduce_while(CSVExportController.put_resp_params(conn), fn chunk, conn -> case Conn.chunk(conn, chunk) do {:ok, conn} -> {:cont, conn} diff --git a/apps/block_scout_web/lib/block_scout_web/controllers/address_validation_controller.ex b/apps/block_scout_web/lib/block_scout_web/controllers/address_validation_controller.ex index 244deb3af04d..48442d0adbbd 100644 --- a/apps/block_scout_web/lib/block_scout_web/controllers/address_validation_controller.ex +++ b/apps/block_scout_web/lib/block_scout_web/controllers/address_validation_controller.ex @@ -13,7 +13,7 @@ defmodule BlockScoutWeb.AddressValidationController do alias BlockScoutWeb.{AccessHelper, BlockView, Controller} alias Explorer.{Chain, Market} - alias Indexer.Fetcher.CoinBalanceOnDemand + alias Indexer.Fetcher.OnDemand.CoinBalance, as: CoinBalanceOnDemand alias Phoenix.View def index(conn, %{"address_id" => address_hash_string, "type" => "JSON"} = params) do diff --git a/apps/block_scout_web/lib/block_scout_web/controllers/address_withdrawal_controller.ex b/apps/block_scout_web/lib/block_scout_web/controllers/address_withdrawal_controller.ex index 937899617445..4fd1b9c366a7 100644 --- a/apps/block_scout_web/lib/block_scout_web/controllers/address_withdrawal_controller.ex +++ b/apps/block_scout_web/lib/block_scout_web/controllers/address_withdrawal_controller.ex @@ -16,7 +16,7 @@ defmodule BlockScoutWeb.AddressWithdrawalController do alias Explorer.Chain.Wei - alias Indexer.Fetcher.CoinBalanceOnDemand + alias Indexer.Fetcher.OnDemand.CoinBalance, as: CoinBalanceOnDemand alias Phoenix.View def index(conn, %{"address_id" => address_hash_string, "type" => "JSON"} = params) do diff --git a/apps/block_scout_web/lib/block_scout_web/controllers/address_write_contract_controller.ex b/apps/block_scout_web/lib/block_scout_web/controllers/address_write_contract_controller.ex index 32fc477ed283..cf3904e86781 100644 --- a/apps/block_scout_web/lib/block_scout_web/controllers/address_write_contract_controller.ex +++ b/apps/block_scout_web/lib/block_scout_web/controllers/address_write_contract_controller.ex @@ -15,7 +15,7 @@ defmodule BlockScoutWeb.AddressWriteContractController do alias BlockScoutWeb.AddressView alias Explorer.{Chain, Market} alias Explorer.Chain.Address - alias Indexer.Fetcher.CoinBalanceOnDemand + alias Indexer.Fetcher.OnDemand.CoinBalance, as: CoinBalanceOnDemand def index(conn, %{"address_id" => address_hash_string} = params) do address_options = [ diff --git a/apps/block_scout_web/lib/block_scout_web/controllers/address_write_proxy_controller.ex b/apps/block_scout_web/lib/block_scout_web/controllers/address_write_proxy_controller.ex index 68903261d6e3..be8e61415716 100644 --- a/apps/block_scout_web/lib/block_scout_web/controllers/address_write_proxy_controller.ex +++ b/apps/block_scout_web/lib/block_scout_web/controllers/address_write_proxy_controller.ex @@ -8,7 +8,7 @@ defmodule BlockScoutWeb.AddressWriteProxyController do alias BlockScoutWeb.{AccessHelper, AddressView} alias Explorer.{Chain, Market} alias Explorer.Chain.Address - alias Indexer.Fetcher.CoinBalanceOnDemand + alias Indexer.Fetcher.OnDemand.CoinBalance, as: CoinBalanceOnDemand def index(conn, %{"address_id" => address_hash_string} = params) do address_options = [ diff --git a/apps/block_scout_web/lib/block_scout_web/controllers/api/eth_rpc/eth_controller.ex b/apps/block_scout_web/lib/block_scout_web/controllers/api/eth_rpc/eth_controller.ex index 2a4287cf98d6..f67ef4afb9dd 100644 --- a/apps/block_scout_web/lib/block_scout_web/controllers/api/eth_rpc/eth_controller.ex +++ b/apps/block_scout_web/lib/block_scout_web/controllers/api/eth_rpc/eth_controller.ex @@ -3,20 +3,29 @@ defmodule BlockScoutWeb.API.EthRPC.EthController do alias BlockScoutWeb.AccessHelper alias BlockScoutWeb.API.EthRPC.View, as: EthRPCView + alias BlockScoutWeb.API.RPC.RPCView alias Explorer.EthRPC def eth_request(%{body_params: %{"_json" => requests}} = conn, _) when is_list(requests) do - case AccessHelper.check_rate_limit(conn) do - :ok -> - responses = EthRPC.responses(requests) + eth_json_rpc_max_batch_size = Application.get_env(:block_scout_web, :api_rate_limit)[:eth_json_rpc_max_batch_size] - conn - |> put_status(200) - |> put_view(EthRPCView) - |> render("responses.json", %{responses: responses}) + with :ok <- AccessHelper.check_rate_limit(conn), + {:batch_size, true} <- {:batch_size, Enum.count(requests) <= eth_json_rpc_max_batch_size} do + responses = EthRPC.responses(requests) + conn + |> put_status(200) + |> put_view(EthRPCView) + |> render("responses.json", %{responses: responses}) + else :rate_limit_reached -> AccessHelper.handle_rate_limit_deny(conn) + + {:batch_size, _} -> + conn + |> put_status(413) + |> put_view(RPCView) + |> render(:error, %{:error => "Payload Too Large. Max batch size is #{eth_json_rpc_max_batch_size}"}) end end diff --git a/apps/block_scout_web/lib/block_scout_web/controllers/api/rpc/address_controller.ex b/apps/block_scout_web/lib/block_scout_web/controllers/api/rpc/address_controller.ex index ff81d7fc2da0..3e7187267433 100644 --- a/apps/block_scout_web/lib/block_scout_web/controllers/api/rpc/address_controller.ex +++ b/apps/block_scout_web/lib/block_scout_web/controllers/api/rpc/address_controller.ex @@ -5,7 +5,7 @@ defmodule BlockScoutWeb.API.RPC.AddressController do alias Explorer.{Chain, Etherscan} alias Explorer.Chain.{Address, Wei} alias Explorer.Etherscan.{Addresses, Blocks} - alias Indexer.Fetcher.CoinBalanceOnDemand + alias Indexer.Fetcher.OnDemand.CoinBalance, as: CoinBalanceOnDemand @api_true [api?: true] @@ -200,7 +200,7 @@ defmodule BlockScoutWeb.API.RPC.AddressController do {:contract_address, to_address_hash_optional(params["contractaddress"])}, true <- !is_nil(address_hash) or !is_nil(contract_address_hash), {:ok, token_transfers, max_block_number} <- - list_nft_token_transfers(address_hash, contract_address_hash, options) do + list_nft_transfers(address_hash, contract_address_hash, options) do render(conn, :tokennfttx, %{token_transfers: token_transfers, max_block_number: max_block_number}) else false -> @@ -531,10 +531,10 @@ defmodule BlockScoutWeb.API.RPC.AddressController do end end - defp list_nft_token_transfers(nil, contract_address_hash, options) do + defp list_nft_transfers(nil, contract_address_hash, options) do with {:ok, max_block_number} <- Chain.max_consensus_block_number(), token_transfers when token_transfers != [] <- - Etherscan.list_nft_token_transfers_by_token(contract_address_hash, options) do + Etherscan.list_nft_transfers_by_token(contract_address_hash, options) do {:ok, token_transfers, max_block_number} else _ -> @@ -542,11 +542,11 @@ defmodule BlockScoutWeb.API.RPC.AddressController do end end - defp list_nft_token_transfers(address_hash, contract_address_hash, options) do + defp list_nft_transfers(address_hash, contract_address_hash, options) do with {:address, :ok} <- {:address, Address.check_address_exists(address_hash, @api_true)}, {:ok, max_block_number} <- Chain.max_consensus_block_number(), token_transfers when token_transfers != [] <- - Etherscan.list_nft_token_transfers(address_hash, contract_address_hash, options) do + Etherscan.list_nft_transfers(address_hash, contract_address_hash, options) do {:ok, token_transfers, max_block_number} else _ -> diff --git a/apps/block_scout_web/lib/block_scout_web/controllers/api/rpc/token_controller.ex b/apps/block_scout_web/lib/block_scout_web/controllers/api/rpc/token_controller.ex index 4f6ccd5a448d..51e1aff18221 100644 --- a/apps/block_scout_web/lib/block_scout_web/controllers/api/rpc/token_controller.ex +++ b/apps/block_scout_web/lib/block_scout_web/controllers/api/rpc/token_controller.ex @@ -3,6 +3,7 @@ defmodule BlockScoutWeb.API.RPC.TokenController do alias BlockScoutWeb.API.RPC.Helper alias Explorer.{Chain, PagingOptions} + alias Explorer.Chain.BridgedToken def gettoken(conn, params) do with {:contractaddress_param, {:ok, contractaddress_param}} <- fetch_contractaddress(params), @@ -50,6 +51,38 @@ defmodule BlockScoutWeb.API.RPC.TokenController do end end + if Application.compile_env(:explorer, BridgedToken)[:enabled] do + @api_true [api?: true] + def bridgedtokenlist(conn, params) do + import BlockScoutWeb.PagingHelper, + only: [ + chain_ids_filter_options: 1, + tokens_sorting: 1 + ] + + import BlockScoutWeb.Chain, + only: [ + paging_options: 1 + ] + + bridged_tokens = + if BridgedToken.enabled?() do + options = + params + |> paging_options() + |> Keyword.merge(chain_ids_filter_options(params)) + |> Keyword.merge(tokens_sorting(params)) + |> Keyword.merge(@api_true) + + "" |> BridgedToken.list_top_bridged_tokens(options) + else + [] + end + + render(conn, "bridgedtokenlist.json", %{bridged_tokens: bridged_tokens}) + end + end + defp fetch_contractaddress(params) do {:contractaddress_param, Map.fetch(params, "contractaddress")} end diff --git a/apps/block_scout_web/lib/block_scout_web/controllers/api/v2/address_controller.ex b/apps/block_scout_web/lib/block_scout_web/controllers/api/v2/address_controller.ex index e77b2a0c1f00..10c0d44a18d9 100644 --- a/apps/block_scout_web/lib/block_scout_web/controllers/api/v2/address_controller.ex +++ b/apps/block_scout_web/lib/block_scout_web/controllers/api/v2/address_controller.ex @@ -17,10 +17,11 @@ defmodule BlockScoutWeb.API.V2.AddressController do delete_parameters_from_next_page_params: 1, token_transfers_types_options: 1, address_transactions_sorting: 1, - nft_token_types_options: 1 + nft_types_options: 1 ] import Explorer.MicroserviceInterfaces.BENS, only: [maybe_preload_ens: 1, maybe_preload_ens_to_address: 1] + import Explorer.MicroserviceInterfaces.Metadata, only: [maybe_preload_metadata: 1] alias BlockScoutWeb.AccessHelper alias BlockScoutWeb.API.V2.{BlockView, TransactionView, WithdrawalView} @@ -28,7 +29,10 @@ defmodule BlockScoutWeb.API.V2.AddressController do alias Explorer.Chain.{Address, Hash, Transaction} alias Explorer.Chain.Address.Counters alias Explorer.Chain.Token.Instance - alias Indexer.Fetcher.{CoinBalanceOnDemand, TokenBalanceOnDemand} + + alias Indexer.Fetcher.OnDemand.CoinBalance, as: CoinBalanceOnDemand + alias Indexer.Fetcher.OnDemand.ContractCode, as: ContractCodeOnDemand + alias Indexer.Fetcher.OnDemand.TokenBalance, as: TokenBalanceOnDemand @transaction_necessity_by_association [ necessity_by_association: %{ @@ -45,10 +49,13 @@ defmodule BlockScoutWeb.API.V2.AddressController do @token_transfer_necessity_by_association [ necessity_by_association: %{ - :to_address => :optional, - :from_address => :optional, + [to_address: :smart_contract] => :optional, + [from_address: :smart_contract] => :optional, + [to_address: :names] => :optional, + [from_address: :names] => :optional, :block => :optional, - :transaction => :optional + :transaction => :optional, + :token => :optional }, api?: true ] @@ -83,6 +90,8 @@ defmodule BlockScoutWeb.API.V2.AddressController do Address.maybe_preload_smart_contract_associations(address, @contract_address_preloads, @api_true) do CoinBalanceOnDemand.trigger_fetch(fully_preloaded_address) + ContractCodeOnDemand.trigger_fetch(address) + conn |> put_status(200) |> render(:address, %{address: fully_preloaded_address |> maybe_preload_ens_to_address()}) @@ -144,7 +153,10 @@ defmodule BlockScoutWeb.API.V2.AddressController do conn |> put_status(200) |> put_view(TransactionView) - |> render(:transactions, %{transactions: transactions |> maybe_preload_ens(), next_page_params: next_page_params}) + |> render(:transactions, %{ + transactions: transactions |> maybe_preload_ens() |> maybe_preload_metadata(), + next_page_params: next_page_params + }) end end @@ -159,8 +171,10 @@ defmodule BlockScoutWeb.API.V2.AddressController do options = [ necessity_by_association: %{ - :to_address => :optional, - :from_address => :optional, + [to_address: :smart_contract] => :optional, + [from_address: :smart_contract] => :optional, + [to_address: :names] => :optional, + [from_address: :names] => :optional, :block => :optional, :token => :optional, :transaction => :optional @@ -188,7 +202,7 @@ defmodule BlockScoutWeb.API.V2.AddressController do |> put_status(200) |> put_view(TransactionView) |> render(:token_transfers, %{ - token_transfers: token_transfers |> maybe_preload_ens(), + token_transfers: token_transfers |> maybe_preload_ens() |> maybe_preload_metadata(), next_page_params: next_page_params }) end @@ -220,7 +234,7 @@ defmodule BlockScoutWeb.API.V2.AddressController do |> put_status(200) |> put_view(TransactionView) |> render(:token_transfers, %{ - token_transfers: token_transfers |> maybe_preload_ens(), + token_transfers: token_transfers |> maybe_preload_ens() |> maybe_preload_metadata(), next_page_params: next_page_params }) end @@ -253,7 +267,7 @@ defmodule BlockScoutWeb.API.V2.AddressController do |> put_status(200) |> put_view(TransactionView) |> render(:internal_transactions, %{ - internal_transactions: internal_transactions |> maybe_preload_ens(), + internal_transactions: internal_transactions |> maybe_preload_ens() |> maybe_preload_metadata(), next_page_params: next_page_params }) end @@ -276,7 +290,10 @@ defmodule BlockScoutWeb.API.V2.AddressController do conn |> put_status(200) |> put_view(TransactionView) - |> render(:logs, %{logs: logs |> maybe_preload_ens(), next_page_params: next_page_params}) + |> render(:logs, %{ + logs: logs |> maybe_preload_ens() |> maybe_preload_metadata(), + next_page_params: next_page_params + }) end end @@ -293,7 +310,10 @@ defmodule BlockScoutWeb.API.V2.AddressController do conn |> put_status(200) |> put_view(TransactionView) - |> render(:logs, %{logs: logs |> maybe_preload_ens(), next_page_params: next_page_params}) + |> render(:logs, %{ + logs: logs |> maybe_preload_ens() |> maybe_preload_metadata(), + next_page_params: next_page_params + }) end end @@ -395,7 +415,10 @@ defmodule BlockScoutWeb.API.V2.AddressController do conn |> put_status(200) |> put_view(WithdrawalView) - |> render(:withdrawals, %{withdrawals: withdrawals |> maybe_preload_ens(), next_page_params: next_page_params}) + |> render(:withdrawals, %{ + withdrawals: withdrawals |> maybe_preload_ens() |> maybe_preload_metadata(), + next_page_params: next_page_params + }) end end @@ -415,7 +438,7 @@ defmodule BlockScoutWeb.API.V2.AddressController do conn |> put_status(200) |> render(:addresses, %{ - addresses: addresses |> maybe_preload_ens(), + addresses: addresses |> maybe_preload_ens() |> maybe_preload_metadata(), next_page_params: next_page_params, exchange_rate: exchange_rate, total_supply: total_supply @@ -448,7 +471,7 @@ defmodule BlockScoutWeb.API.V2.AddressController do address_hash, params |> paging_options() - |> Keyword.merge(nft_token_types_options(params)) + |> Keyword.merge(nft_types_options(params)) |> Keyword.merge(@api_true) |> Keyword.merge(@nft_necessity_by_association) ) @@ -476,7 +499,7 @@ defmodule BlockScoutWeb.API.V2.AddressController do address_hash, params |> paging_options() - |> Keyword.merge(nft_token_types_options(params)) + |> Keyword.merge(nft_types_options(params)) |> Keyword.merge(@api_true) |> Keyword.merge(@nft_necessity_by_association) ) diff --git a/apps/block_scout_web/lib/block_scout_web/controllers/api/v2/blob_controller.ex b/apps/block_scout_web/lib/block_scout_web/controllers/api/v2/blob_controller.ex index 724b4b8e9bbf..f72a6424a7c3 100644 --- a/apps/block_scout_web/lib/block_scout_web/controllers/api/v2/blob_controller.ex +++ b/apps/block_scout_web/lib/block_scout_web/controllers/api/v2/blob_controller.ex @@ -2,7 +2,7 @@ defmodule BlockScoutWeb.API.V2.BlobController do use BlockScoutWeb, :controller alias Explorer.Chain - alias Explorer.Chain.Beacon.Reader + alias Explorer.Chain.Beacon.{Blob, Reader} action_fallback(BlockScoutWeb.API.V2.FallbackController) @@ -14,16 +14,18 @@ defmodule BlockScoutWeb.API.V2.BlobController do with {:format, {:ok, blob_hash}} <- {:format, Chain.string_to_transaction_hash(blob_hash_string)} do transaction_hashes = Reader.blob_hash_to_transactions(blob_hash, api?: true) - case Reader.blob(blob_hash, true, api?: true) do - {:ok, blob} -> - conn - |> put_status(200) - |> render(:blob, %{blob: blob, transaction_hashes: transaction_hashes}) + {status, blob} = + case Reader.blob(blob_hash, true, api?: true) do + {:ok, blob} -> {:ok, blob} + {:error, :not_found} -> {:pending, %Blob{hash: blob_hash}} + end - {:error, :not_found} -> - conn - |> put_status(200) - |> render(:blob, %{transaction_hashes: transaction_hashes}) + if Enum.empty?(transaction_hashes) and status == :pending do + {:error, :not_found} + else + conn + |> put_status(200) + |> render(:blob, %{blob: blob, transaction_hashes: transaction_hashes}) end end end diff --git a/apps/block_scout_web/lib/block_scout_web/controllers/api/v2/block_controller.ex b/apps/block_scout_web/lib/block_scout_web/controllers/api/v2/block_controller.ex index ddb798f43209..4bc20eb21fa4 100644 --- a/apps/block_scout_web/lib/block_scout_web/controllers/api/v2/block_controller.ex +++ b/apps/block_scout_web/lib/block_scout_web/controllers/api/v2/block_controller.ex @@ -4,20 +4,25 @@ defmodule BlockScoutWeb.API.V2.BlockController do import BlockScoutWeb.Chain, only: [ next_page_params: 3, + next_page_params: 4, paging_options: 1, put_key_value_to_paging_options: 3, split_list_by_page: 1, parse_block_hash_or_number_param: 1 ] - import BlockScoutWeb.PagingHelper, only: [delete_parameters_from_next_page_params: 1, select_block_type: 1] + import BlockScoutWeb.PagingHelper, + only: [delete_parameters_from_next_page_params: 1, select_block_type: 1, type_filter_options: 1] + import Explorer.MicroserviceInterfaces.BENS, only: [maybe_preload_ens: 1] + import Explorer.MicroserviceInterfaces.Metadata, only: [maybe_preload_metadata: 1] alias BlockScoutWeb.API.V2.{TransactionView, WithdrawalView} alias Explorer.Chain + alias Explorer.Chain.InternalTransaction case Application.compile_env(:explorer, :chain_type) do - "ethereum" -> + :ethereum -> @chain_type_transaction_necessity_by_association %{ :beacon_blob_transaction => :optional } @@ -25,6 +30,15 @@ defmodule BlockScoutWeb.API.V2.BlockController do [transactions: :beacon_blob_transaction] => :optional } + :zksync -> + @chain_type_transaction_necessity_by_association %{} + @chain_type_block_necessity_by_association %{ + :zksync_batch => :optional, + :zksync_commit_transaction => :optional, + :zksync_prove_transaction => :optional, + :zksync_execute_transaction => :optional + } + _ -> @chain_type_transaction_necessity_by_association %{} @chain_type_block_necessity_by_association %{} @@ -44,6 +58,17 @@ defmodule BlockScoutWeb.API.V2.BlockController do |> Map.merge(@chain_type_transaction_necessity_by_association) ] + @internal_transaction_necessity_by_association [ + necessity_by_association: %{ + [created_contract_address: :names] => :optional, + [from_address: :names] => :optional, + [to_address: :names] => :optional, + [created_contract_address: :smart_contract] => :optional, + [from_address: :smart_contract] => :optional, + [to_address: :smart_contract] => :optional + } + ] + @api_true [api?: true] @block_params [ @@ -60,11 +85,31 @@ defmodule BlockScoutWeb.API.V2.BlockController do api?: true ] + @block_params [ + necessity_by_association: + %{ + [miner: :names] => :optional, + :uncles => :optional, + :nephews => :optional, + :rewards => :optional, + :transactions => :optional, + :withdrawals => :optional + } + |> Map.merge(@chain_type_block_necessity_by_association), + api?: true + ] + action_fallback(BlockScoutWeb.API.V2.FallbackController) + @doc """ + Function to handle GET requests to `/api/v2/blocks/:block_hash_or_number` endpoint. + """ + @spec block(Plug.Conn.t(), map()) :: + {:error, :not_found | {:invalid, :hash | :number}} + | {:lost_consensus, {:error, :not_found} | {:ok, Explorer.Chain.Block.t()}} + | Plug.Conn.t() def block(conn, %{"block_hash_or_number" => block_hash_or_number}) do - with {:ok, type, value} <- parse_block_hash_or_number_param(block_hash_or_number), - {:ok, block} <- fetch_block(type, value, @block_params) do + with {:ok, block} <- block_param_to_block(block_hash_or_number, @block_params) do conn |> put_status(200) |> render(:block, %{block: block}) @@ -85,6 +130,10 @@ defmodule BlockScoutWeb.API.V2.BlockController do end end + @doc """ + Function to handle GET requests to `/api/v2/blocks` endpoint. + """ + @spec blocks(Plug.Conn.t(), any()) :: Plug.Conn.t() def blocks(conn, params) do full_options = select_block_type(params) @@ -100,15 +149,25 @@ defmodule BlockScoutWeb.API.V2.BlockController do conn |> put_status(200) - |> render(:blocks, %{blocks: blocks |> maybe_preload_ens(), next_page_params: next_page_params}) + |> render(:blocks, %{ + blocks: blocks |> maybe_preload_ens() |> maybe_preload_metadata(), + next_page_params: next_page_params + }) end + @doc """ + Function to handle GET requests to `/api/v2/blocks/:block_hash_or_number/transactions` endpoint. + """ + @spec transactions(Plug.Conn.t(), map()) :: + {:error, :not_found | {:invalid, :hash | :number}} + | {:lost_consensus, {:error, :not_found} | {:ok, Explorer.Chain.Block.t()}} + | Plug.Conn.t() def transactions(conn, %{"block_hash_or_number" => block_hash_or_number} = params) do - with {:ok, type, value} <- parse_block_hash_or_number_param(block_hash_or_number), - {:ok, block} <- fetch_block(type, value, @api_true) do + with {:ok, block} <- block_param_to_block(block_hash_or_number) do full_options = @transaction_necessity_by_association |> Keyword.merge(put_key_value_to_paging_options(paging_options(params), :is_index_in_asc_order, true)) + |> Keyword.merge(type_filter_options(params)) |> Keyword.merge(@api_true) transactions_plus_one = Chain.block_to_transactions(block.hash, full_options, false) @@ -122,13 +181,59 @@ defmodule BlockScoutWeb.API.V2.BlockController do conn |> put_status(200) |> put_view(TransactionView) - |> render(:transactions, %{transactions: transactions |> maybe_preload_ens(), next_page_params: next_page_params}) + |> render(:transactions, %{ + transactions: transactions |> maybe_preload_ens() |> maybe_preload_metadata(), + next_page_params: next_page_params + }) end end + @doc """ + Function to handle GET requests to `/api/v2/blocks/:block_hash_or_number/internal-transactions` endpoint. + """ + @spec internal_transactions(Plug.Conn.t(), map()) :: + {:error, :not_found | {:invalid, :hash | :number}} + | {:lost_consensus, {:error, :not_found} | {:ok, Explorer.Chain.Block.t()}} + | Plug.Conn.t() + def internal_transactions(conn, %{"block_hash_or_number" => block_hash_or_number} = params) do + with {:ok, block} <- block_param_to_block(block_hash_or_number) do + full_options = + @internal_transaction_necessity_by_association + |> Keyword.merge(paging_options(params)) + |> Keyword.merge(@api_true) + + internal_transactions_plus_one = InternalTransaction.block_to_internal_transactions(block.hash, full_options) + + {internal_transactions, next_page} = split_list_by_page(internal_transactions_plus_one) + + next_page_params = + next_page + |> next_page_params( + internal_transactions, + delete_parameters_from_next_page_params(params), + &InternalTransaction.internal_transaction_to_block_paging_options/1 + ) + + conn + |> put_status(200) + |> put_view(TransactionView) + |> render(:internal_transactions, %{ + internal_transactions: internal_transactions, + next_page_params: next_page_params, + block: block + }) + end + end + + @doc """ + Function to handle GET requests to `/api/v2/blocks/:block_hash_or_number/withdrawals` endpoint. + """ + @spec withdrawals(Plug.Conn.t(), map()) :: + {:error, :not_found | {:invalid, :hash | :number}} + | {:lost_consensus, {:error, :not_found} | {:ok, Explorer.Chain.Block.t()}} + | Plug.Conn.t() def withdrawals(conn, %{"block_hash_or_number" => block_hash_or_number} = params) do - with {:ok, type, value} <- parse_block_hash_or_number_param(block_hash_or_number), - {:ok, block} <- fetch_block(type, value, @api_true) do + with {:ok, block} <- block_param_to_block(block_hash_or_number) do full_options = [necessity_by_association: %{address: :optional}, api?: true] |> Keyword.merge(paging_options(params)) @@ -141,7 +246,16 @@ defmodule BlockScoutWeb.API.V2.BlockController do conn |> put_status(200) |> put_view(WithdrawalView) - |> render(:withdrawals, %{withdrawals: withdrawals |> maybe_preload_ens(), next_page_params: next_page_params}) + |> render(:withdrawals, %{ + withdrawals: withdrawals |> maybe_preload_ens() |> maybe_preload_metadata(), + next_page_params: next_page_params + }) + end + end + + defp block_param_to_block(block_hash_or_number, options \\ @api_true) do + with {:ok, type, value} <- parse_block_hash_or_number_param(block_hash_or_number) do + fetch_block(type, value, options) end end end diff --git a/apps/block_scout_web/lib/block_scout_web/controllers/api/v2/config_controller.ex b/apps/block_scout_web/lib/block_scout_web/controllers/api/v2/config_controller.ex index f3ee90b05446..f9d2dfc0a463 100644 --- a/apps/block_scout_web/lib/block_scout_web/controllers/api/v2/config_controller.ex +++ b/apps/block_scout_web/lib/block_scout_web/controllers/api/v2/config_controller.ex @@ -1,14 +1,6 @@ defmodule BlockScoutWeb.API.V2.ConfigController do use BlockScoutWeb, :controller - def json_rpc_url(conn, _params) do - json_rpc_url = Application.get_env(:block_scout_web, :json_rpc) - - conn - |> put_status(200) - |> render(:json_rpc_url, %{url: json_rpc_url}) - end - def backend_version(conn, _params) do backend_version = Application.get_env(:block_scout_web, :version) diff --git a/apps/block_scout_web/lib/block_scout_web/controllers/api/v2/csv_export_controller.ex b/apps/block_scout_web/lib/block_scout_web/controllers/api/v2/csv_export_controller.ex new file mode 100644 index 000000000000..1c2c3844033e --- /dev/null +++ b/apps/block_scout_web/lib/block_scout_web/controllers/api/v2/csv_export_controller.ex @@ -0,0 +1,53 @@ +defmodule BlockScoutWeb.API.V2.CSVExportController do + use BlockScoutWeb, :controller + + alias BlockScoutWeb.AccessHelper + alias Explorer.{Chain, PagingOptions} + alias Explorer.Chain.Address.CurrentTokenBalance + alias Explorer.Chain.CSVExport.Helper, as: CSVHelper + alias Plug.Conn + + action_fallback(BlockScoutWeb.API.V2.FallbackController) + + @options [paging_options: %PagingOptions{page_size: CSVHelper.limit()}, api?: true] + @api_true [api?: true] + + @doc """ + Performs CSV export of token holders for a given address + Endpoint: `/api/v2/tokens/:address_hash_param/holders/csv` + """ + @spec export_token_holders(Plug.Conn.t(), map()) :: Plug.Conn.t() + def export_token_holders(conn, %{"address_hash_param" => address_hash_string} = params) do + with {:format, {:ok, address_hash}} <- {:format, Chain.string_to_address_hash(address_hash_string)}, + {:ok, false} <- AccessHelper.restricted_access?(address_hash_string, params), + {:not_found, {:ok, token}} <- {:not_found, Chain.token_from_address_hash(address_hash, @api_true)}, + {:recaptcha, true} <- + {:recaptcha, + Application.get_env(:block_scout_web, :recaptcha)[:is_disabled] || + CSVHelper.captcha_helper().recaptcha_passed?(params["recaptcha_response"])} do + token_holders = Chain.fetch_token_holders_from_token_hash_for_csv(address_hash, @options) + + token_holders + |> CurrentTokenBalance.to_csv_format(token) + |> CSVHelper.dump_to_stream() + |> Enum.reduce_while(put_resp_params(conn), fn chunk, conn -> + case Conn.chunk(conn, chunk) do + {:ok, conn} -> + {:cont, conn} + + {:error, :closed} -> + {:halt, conn} + end + end) + end + end + + @spec put_resp_params(Plug.Conn.t()) :: Plug.Conn.t() + def put_resp_params(conn) do + conn + |> put_resp_content_type("application/csv") + |> put_resp_header("content-disposition", "attachment;") + |> put_resp_cookie("csv-downloaded", "true", max_age: 86_400, http_only: false) + |> send_chunked(200) + end +end diff --git a/apps/block_scout_web/lib/block_scout_web/controllers/api/v2/fallback_controller.ex b/apps/block_scout_web/lib/block_scout_web/controllers/api/v2/fallback_controller.ex index 4948bc20eea4..373704ccb03a 100644 --- a/apps/block_scout_web/lib/block_scout_web/controllers/api/v2/fallback_controller.ex +++ b/apps/block_scout_web/lib/block_scout_web/controllers/api/v2/fallback_controller.ex @@ -3,7 +3,7 @@ defmodule BlockScoutWeb.API.V2.FallbackController do require Logger - alias BlockScoutWeb.Account.Api.V1.UserView + alias BlockScoutWeb.Account.Api.V2.UserView alias BlockScoutWeb.API.V2.ApiView alias Ecto.Changeset @@ -30,8 +30,9 @@ defmodule BlockScoutWeb.API.V2.FallbackController do @vyper_smart_contract_is_not_supported "Vyper smart-contracts are not supported by SolidityScan" @unverified_smart_contract "Smart-contract is unverified" @empty_response "Empty response" - @tx_interpreter_service_disabled "Transaction Interpretation Service is not enabled" + @tx_interpreter_service_disabled "Transaction Interpretation Service is disabled" @disabled "API endpoint is disabled" + @service_disabled "Service is disabled" def call(conn, {:format, _params}) do Logger.error(fn -> @@ -297,4 +298,17 @@ defmodule BlockScoutWeb.API.V2.FallbackController do |> put_view(ApiView) |> render(:message, %{message: @disabled}) end + + def call(conn, {:error, :disabled}) do + conn + |> put_status(501) + |> put_view(ApiView) + |> render(:message, %{message: @service_disabled}) + end + + def call(conn, {code, response}) when is_integer(code) do + conn + |> put_status(code) + |> json(response) + end end diff --git a/apps/block_scout_web/lib/block_scout_web/controllers/api/v2/import_controller.ex b/apps/block_scout_web/lib/block_scout_web/controllers/api/v2/import_controller.ex index d8fefb4f2b5c..c570d9608692 100644 --- a/apps/block_scout_web/lib/block_scout_web/controllers/api/v2/import_controller.ex +++ b/apps/block_scout_web/lib/block_scout_web/controllers/api/v2/import_controller.ex @@ -2,8 +2,8 @@ defmodule BlockScoutWeb.API.V2.ImportController do use BlockScoutWeb, :controller alias BlockScoutWeb.API.V2.ApiView - alias Explorer.{Chain, Repo} - alias Explorer.Chain.{Data, SmartContract, Token} + alias Explorer.Chain + alias Explorer.Chain.{Data, SmartContract} alias Explorer.Chain.Fetcher.LookUpSmartContractSourcesOnDemand alias Explorer.SmartContract.EthBytecodeDBInterface @@ -35,7 +35,7 @@ defmodule BlockScoutWeb.API.V2.ImportController do |> put_token_string_field(token_symbol, :symbol) |> put_token_string_field(token_name, :name) - case token |> Token.changeset(changeset) |> Repo.update() do + case Chain.update_token(token, changeset, true) do {:ok, _} -> conn |> put_view(ApiView) @@ -66,7 +66,7 @@ defmodule BlockScoutWeb.API.V2.ImportController do | {:not_found, {:error, :not_found}} | {:sensitive_endpoints_api_key, any()} | Plug.Conn.t() - def try_to_search_contract(conn, %{"address_hash_param" => address_hash_string}) do + def try_to_search_contract(conn, %{"address_hash_param" => address_hash_string} = params) do with {:sensitive_endpoints_api_key, api_key} when not is_nil(api_key) <- {:sensitive_endpoints_api_key, Application.get_env(:block_scout_web, :sensitive_endpoints_api_key)}, {:api_key, ^api_key} <- {:api_key, get_api_key_header(conn)}, @@ -79,7 +79,10 @@ defmodule BlockScoutWeb.API.V2.ImportController do with {:ok, %{"sourceType" => type} = source} <- %{} |> prepare_bytecode_for_microservice(creation_tx_input, Data.to_string(address.contract_code)) - |> EthBytecodeDBInterface.search_contract_in_eth_bytecode_internal_db(), + |> EthBytecodeDBInterface.search_contract_in_eth_bytecode_internal_db( + address_hash_string, + params_to_contract_search_options(params) + ), {:ok, _} <- LookUpSmartContractSourcesOnDemand.process_contract_source(type, source, address.hash) do conn |> put_view(ApiView) @@ -93,6 +96,16 @@ defmodule BlockScoutWeb.API.V2.ImportController do end end + defp params_to_contract_search_options(%{"import_from" => "verifier_alliance"}) do + [only_verifier_alliance?: true] + end + + defp params_to_contract_search_options(%{"import_from" => "eth_bytecode_db"}) do + [only_eth_bytecode_db?: true] + end + + defp params_to_contract_search_options(_), do: [] + defp valid_url?(url) when is_binary(url) do uri = URI.parse(url) uri.scheme != nil && uri.host =~ "." diff --git a/apps/block_scout_web/lib/block_scout_web/controllers/api/v2/main_page_controller.ex b/apps/block_scout_web/lib/block_scout_web/controllers/api/v2/main_page_controller.ex index 0e06f6e058ca..8a39c3e36804 100644 --- a/apps/block_scout_web/lib/block_scout_web/controllers/api/v2/main_page_controller.ex +++ b/apps/block_scout_web/lib/block_scout_web/controllers/api/v2/main_page_controller.ex @@ -2,11 +2,13 @@ defmodule BlockScoutWeb.API.V2.MainPageController do use Phoenix.Controller alias Explorer.{Chain, PagingOptions} - alias BlockScoutWeb.API.V2.{BlockView, TransactionView} + alias BlockScoutWeb.API.V2.{BlockView, OptimismView, TransactionView} alias Explorer.{Chain, Repo} + alias Explorer.Chain.Optimism.Deposit import BlockScoutWeb.Account.AuthController, only: [current_user: 1] import Explorer.MicroserviceInterfaces.BENS, only: [maybe_preload_ens: 1] + import Explorer.MicroserviceInterfaces.Metadata, only: [maybe_preload_metadata: 1] @transactions_options [ necessity_by_association: %{ @@ -33,7 +35,20 @@ defmodule BlockScoutWeb.API.V2.MainPageController do conn |> put_status(200) |> put_view(BlockView) - |> render(:blocks, %{blocks: blocks |> maybe_preload_ens()}) + |> render(:blocks, %{blocks: blocks |> maybe_preload_ens() |> maybe_preload_metadata()}) + end + + def optimism_deposits(conn, _params) do + recent_deposits = + Deposit.list( + paging_options: %PagingOptions{page_size: 6}, + api?: true + ) + + conn + |> put_status(200) + |> put_view(OptimismView) + |> render(:optimism_deposits, %{deposits: recent_deposits}) end def transactions(conn, _params) do @@ -42,7 +57,7 @@ defmodule BlockScoutWeb.API.V2.MainPageController do conn |> put_status(200) |> put_view(TransactionView) - |> render(:transactions, %{transactions: recent_transactions |> maybe_preload_ens()}) + |> render(:transactions, %{transactions: recent_transactions |> maybe_preload_ens() |> maybe_preload_metadata()}) end def watchlist_transactions(conn, _params) do @@ -53,7 +68,7 @@ defmodule BlockScoutWeb.API.V2.MainPageController do |> put_status(200) |> put_view(TransactionView) |> render(:transactions_watchlist, %{ - transactions: transactions |> maybe_preload_ens(), + transactions: transactions |> maybe_preload_ens() |> maybe_preload_metadata(), watchlist_names: watchlist_names }) end diff --git a/apps/block_scout_web/lib/block_scout_web/controllers/api/v2/optimism_controller.ex b/apps/block_scout_web/lib/block_scout_web/controllers/api/v2/optimism_controller.ex new file mode 100644 index 000000000000..928180129775 --- /dev/null +++ b/apps/block_scout_web/lib/block_scout_web/controllers/api/v2/optimism_controller.ex @@ -0,0 +1,173 @@ +defmodule BlockScoutWeb.API.V2.OptimismController do + use BlockScoutWeb, :controller + + import BlockScoutWeb.Chain, + only: [ + next_page_params: 3, + paging_options: 1, + split_list_by_page: 1 + ] + + alias Explorer.Chain + alias Explorer.Chain.Optimism.{Deposit, DisputeGame, OutputRoot, TxnBatch, Withdrawal} + + action_fallback(BlockScoutWeb.API.V2.FallbackController) + + @doc """ + Function to handle GET requests to `/api/v2/optimism/txn-batches` endpoint. + """ + @spec txn_batches(Plug.Conn.t(), map()) :: Plug.Conn.t() + def txn_batches(conn, params) do + {batches, next_page} = + params + |> paging_options() + |> Keyword.put(:api?, true) + |> TxnBatch.list() + |> split_list_by_page() + + next_page_params = next_page_params(next_page, batches, params) + + conn + |> put_status(200) + |> render(:optimism_txn_batches, %{ + batches: batches, + next_page_params: next_page_params + }) + end + + @doc """ + Function to handle GET requests to `/api/v2/optimism/txn-batches/count` endpoint. + """ + @spec txn_batches_count(Plug.Conn.t(), map()) :: Plug.Conn.t() + def txn_batches_count(conn, _params) do + items_count(conn, TxnBatch) + end + + @doc """ + Function to handle GET requests to `/api/v2/optimism/output-roots` endpoint. + """ + @spec output_roots(Plug.Conn.t(), map()) :: Plug.Conn.t() + def output_roots(conn, params) do + {roots, next_page} = + params + |> paging_options() + |> Keyword.put(:api?, true) + |> OutputRoot.list() + |> split_list_by_page() + + next_page_params = next_page_params(next_page, roots, params) + + conn + |> put_status(200) + |> render(:optimism_output_roots, %{ + roots: roots, + next_page_params: next_page_params + }) + end + + @doc """ + Function to handle GET requests to `/api/v2/optimism/output-roots/count` endpoint. + """ + @spec output_roots_count(Plug.Conn.t(), map()) :: Plug.Conn.t() + def output_roots_count(conn, _params) do + items_count(conn, OutputRoot) + end + + @doc """ + Function to handle GET requests to `/api/v2/optimism/games` endpoint. + """ + @spec games(Plug.Conn.t(), map()) :: Plug.Conn.t() + def games(conn, params) do + {games, next_page} = + params + |> paging_options() + |> Keyword.put(:api?, true) + |> DisputeGame.list() + |> split_list_by_page() + + next_page_params = next_page_params(next_page, games, params) + + conn + |> put_status(200) + |> render(:optimism_games, %{ + games: games, + next_page_params: next_page_params + }) + end + + @doc """ + Function to handle GET requests to `/api/v2/optimism/games/count` endpoint. + """ + @spec games_count(Plug.Conn.t(), map()) :: Plug.Conn.t() + def games_count(conn, _params) do + items_count(conn, DisputeGame) + end + + @doc """ + Function to handle GET requests to `/api/v2/optimism/deposits` endpoint. + """ + @spec deposits(Plug.Conn.t(), map()) :: Plug.Conn.t() + def deposits(conn, params) do + {deposits, next_page} = + params + |> paging_options() + |> Keyword.put(:api?, true) + |> Deposit.list() + |> split_list_by_page() + + next_page_params = next_page_params(next_page, deposits, params) + + conn + |> put_status(200) + |> render(:optimism_deposits, %{ + deposits: deposits, + next_page_params: next_page_params + }) + end + + @doc """ + Function to handle GET requests to `/api/v2/optimism/deposits/count` endpoint. + """ + @spec deposits_count(Plug.Conn.t(), map()) :: Plug.Conn.t() + def deposits_count(conn, _params) do + items_count(conn, Deposit) + end + + @doc """ + Function to handle GET requests to `/api/v2/optimism/withdrawals` endpoint. + """ + @spec withdrawals(Plug.Conn.t(), map()) :: Plug.Conn.t() + def withdrawals(conn, params) do + {withdrawals, next_page} = + params + |> paging_options() + |> Keyword.put(:api?, true) + |> Withdrawal.list() + |> split_list_by_page() + + next_page_params = next_page_params(next_page, withdrawals, params) + + conn + |> put_status(200) + |> render(:optimism_withdrawals, %{ + withdrawals: withdrawals, + next_page_params: next_page_params + }) + end + + @doc """ + Function to handle GET requests to `/api/v2/optimism/withdrawals/count` endpoint. + """ + @spec withdrawals_count(Plug.Conn.t(), map()) :: Plug.Conn.t() + def withdrawals_count(conn, _params) do + items_count(conn, Withdrawal) + end + + defp items_count(conn, module) do + count = Chain.get_table_rows_total_count(module, api?: true) + + conn + |> put_status(200) + |> render(:optimism_items_count, %{count: count}) + end +end diff --git a/apps/block_scout_web/lib/block_scout_web/controllers/api/v2/proxy/account_abstraction_controller.ex b/apps/block_scout_web/lib/block_scout_web/controllers/api/v2/proxy/account_abstraction_controller.ex index 69bd9b9d4420..5565f003b5e8 100644 --- a/apps/block_scout_web/lib/block_scout_web/controllers/api/v2/proxy/account_abstraction_controller.ex +++ b/apps/block_scout_web/lib/block_scout_web/controllers/api/v2/proxy/account_abstraction_controller.ex @@ -2,11 +2,11 @@ defmodule BlockScoutWeb.API.V2.Proxy.AccountAbstractionController do use BlockScoutWeb, :controller alias BlockScoutWeb.API.V2.Helper - + alias BlockScoutWeb.MicroserviceInterfaces.TransactionInterpretation, as: TransactionInterpretationService alias Explorer.Chain alias Explorer.MicroserviceInterfaces.AccountAbstraction - @address_fields ["bundler", "entry_point", "sender", "address", "factory", "paymaster"] + @address_fields ["bundler", "entry_point", "sender", "address", "factory", "paymaster", "execute_target"] action_fallback(BlockScoutWeb.API.V2.FallbackController) @@ -20,6 +20,36 @@ defmodule BlockScoutWeb.API.V2.Proxy.AccountAbstractionController do |> process_response(conn) end + @doc """ + Function to handle GET requests to `/api/v2/proxy/account-abstraction/operations/:user_operation_hash_param/summary` endpoint. + """ + @spec summary(Plug.Conn.t(), map()) :: + {:error | :format | :tx_interpreter_enabled | non_neg_integer(), any()} | Plug.Conn.t() + def summary(conn, %{"operation_hash_param" => operation_hash_string, "just_request_body" => "true"}) do + with {:format, {:ok, _operation_hash}} <- {:format, Chain.string_to_transaction_hash(operation_hash_string)}, + {200, %{"hash" => _} = user_op} <- AccountAbstraction.get_user_ops_by_hash(operation_hash_string) do + conn + |> json(TransactionInterpretationService.get_user_op_request_body(user_op)) + end + end + + def summary(conn, %{"operation_hash_param" => operation_hash_string}) do + with {:format, {:ok, _operation_hash}} <- {:format, Chain.string_to_transaction_hash(operation_hash_string)}, + {:tx_interpreter_enabled, true} <- {:tx_interpreter_enabled, TransactionInterpretationService.enabled?()}, + {200, %{"hash" => _} = user_op} <- AccountAbstraction.get_user_ops_by_hash(operation_hash_string) do + {response, code} = + case TransactionInterpretationService.interpret_user_operation(user_op) do + {:ok, response} -> {response, 200} + {:error, %Jason.DecodeError{}} -> {%{error: "Error while tx interpreter response decoding"}, 500} + {{:error, error}, code} -> {%{error: error}, code} + end + + conn + |> put_status(code) + |> json(response) + end + end + @doc """ Function to handle GET requests to `/api/v2/proxy/account-abstraction/bundlers/:address_hash_param` endpoint. """ @@ -147,7 +177,7 @@ defmodule BlockScoutWeb.API.V2.Proxy.AccountAbstractionController do end address_hash_strings - |> Enum.filter(&(!is_nil(&1))) + |> Enum.reject(&is_nil/1) |> Enum.uniq() |> Enum.map(fn hash_string -> case Chain.string_to_address_hash(hash_string) do @@ -155,7 +185,7 @@ defmodule BlockScoutWeb.API.V2.Proxy.AccountAbstractionController do _ -> nil end end) - |> Enum.filter(&(!is_nil(&1))) + |> Enum.reject(&is_nil/1) end defp replace_address_hashes(response, addresses) do @@ -188,12 +218,30 @@ defmodule BlockScoutWeb.API.V2.Proxy.AccountAbstractionController do {:error, :disabled} -> conn |> put_status(501) - |> json(extended_info(%{message: "Service is disabled"})) + |> json(%{message: "Service is disabled"}) {status_code, response} -> + final_json = response |> try_to_decode_call_data() |> extended_info() + conn |> put_status(status_code) - |> json(extended_info(response)) + |> json(final_json) end end + + defp try_to_decode_call_data(%{"call_data" => _call_data} = user_op) do + user_op_hash = user_op["hash"] + + {_mock_tx, _decoded_call_data, decoded_call_data_json} = + TransactionInterpretationService.decode_user_op_calldata(user_op_hash, user_op["call_data"]) + + {_mock_tx, _decoded_execute_call_data, decoded_execute_call_data_json} = + TransactionInterpretationService.decode_user_op_calldata(user_op_hash, user_op["execute_call_data"]) + + user_op + |> Map.put("decoded_call_data", decoded_call_data_json) + |> Map.put("decoded_execute_call_data", decoded_execute_call_data_json) + end + + defp try_to_decode_call_data(response), do: response end diff --git a/apps/block_scout_web/lib/block_scout_web/controllers/api/v2/proxy/noves_fi_controller.ex b/apps/block_scout_web/lib/block_scout_web/controllers/api/v2/proxy/noves_fi_controller.ex index 69463dae21f8..c14d2bc60040 100644 --- a/apps/block_scout_web/lib/block_scout_web/controllers/api/v2/proxy/noves_fi_controller.ex +++ b/apps/block_scout_web/lib/block_scout_web/controllers/api/v2/proxy/noves_fi_controller.ex @@ -17,7 +17,7 @@ defmodule BlockScoutWeb.API.V2.Proxy.NovesFiController do api?: true ), url = NovesFi.tx_url(transaction_hash_string), - {response, status} <- NovesFi.noves_fi_api_request(url, conn), + {response, status} <- NovesFi.api_request(url, conn), {:is_empty_response, false} <- {:is_empty_response, is_nil(response)} do conn |> put_status(status) @@ -26,13 +26,13 @@ defmodule BlockScoutWeb.API.V2.Proxy.NovesFiController do end @doc """ - Function to handle GET requests to `/api/v2/proxy/noves-fi/transactions/:transaction_hash_param/transaction` endpoint. + Function to handle GET requests to `/api/v2/proxy/noves-fi/addresses/:address_hash_param/transactions` endpoint. """ @spec address_transactions(Plug.Conn.t(), map()) :: Plug.Conn.t() | {atom(), any()} def address_transactions(conn, %{"address_hash_param" => address_hash_string} = params) do with {:ok, _address_hash, _address} <- AddressController.validate_address(address_hash_string, params), url = NovesFi.address_txs_url(address_hash_string), - {response, status} <- NovesFi.noves_fi_api_request(url, conn), + {response, status} <- NovesFi.api_request(url, conn), {:is_empty_response, false} <- {:is_empty_response, is_nil(response)} do conn |> put_status(status) @@ -47,7 +47,7 @@ defmodule BlockScoutWeb.API.V2.Proxy.NovesFiController do def describe_transactions(conn, _) do url = NovesFi.describe_txs_url() - with {response, status} <- NovesFi.noves_fi_api_request(url, conn, :post_transactions), + with {response, status} <- NovesFi.api_request(url, conn, :post_transactions), {:is_empty_response, false} <- {:is_empty_response, is_nil(response)} do conn |> put_status(status) diff --git a/apps/block_scout_web/lib/block_scout_web/controllers/api/v2/proxy/zerion_controller.ex b/apps/block_scout_web/lib/block_scout_web/controllers/api/v2/proxy/zerion_controller.ex new file mode 100644 index 000000000000..f5ecdf67336a --- /dev/null +++ b/apps/block_scout_web/lib/block_scout_web/controllers/api/v2/proxy/zerion_controller.ex @@ -0,0 +1,24 @@ +defmodule BlockScoutWeb.API.V2.Proxy.ZerionController do + use BlockScoutWeb, :controller + + alias BlockScoutWeb.API.V2.AddressController + + alias Explorer.ThirdPartyIntegrations.Zerion + + action_fallback(BlockScoutWeb.API.V2.FallbackController) + + @doc """ + Function to handle GET requests to `/api/v2/proxy/zerion/wallet-portfolio/:address_hash_param` endpoint. + """ + @spec wallet_portfolio(Plug.Conn.t(), map()) :: Plug.Conn.t() | {atom(), any()} + def wallet_portfolio(conn, %{"address_hash_param" => address_hash_string} = params) do + with {:ok, _address_hash, _address} <- AddressController.validate_address(address_hash_string, params), + url = Zerion.wallet_portfolio_url(address_hash_string), + {response, status} <- Zerion.api_request(url, conn), + {:is_empty_response, false} <- {:is_empty_response, is_nil(response)} do + conn + |> put_status(status) + |> json(response) + end + end +end diff --git a/apps/block_scout_web/lib/block_scout_web/controllers/api/v2/smart_contract_controller.ex b/apps/block_scout_web/lib/block_scout_web/controllers/api/v2/smart_contract_controller.ex index 864a7243c5b8..9dbc80236b08 100644 --- a/apps/block_scout_web/lib/block_scout_web/controllers/api/v2/smart_contract_controller.ex +++ b/apps/block_scout_web/lib/block_scout_web/controllers/api/v2/smart_contract_controller.ex @@ -49,7 +49,7 @@ defmodule BlockScoutWeb.API.V2.SmartContractController do custom_abi <- AddressView.fetch_custom_abi(conn, address_hash_string), {:not_found, true} <- {:not_found, AddressView.check_custom_abi_for_having_read_functions(custom_abi)} do read_only_functions_from_abi = - Reader.read_only_functions_from_abi_with_sender(custom_abi.abi, address_hash, params["from"]) + Reader.read_only_functions_from_abi_with_sender(custom_abi.abi, address_hash, params["from"], @api_true) read_functions_required_wallet_from_abi = Reader.read_functions_required_wallet_from_abi(custom_abi.abi) @@ -61,7 +61,7 @@ defmodule BlockScoutWeb.API.V2.SmartContractController do def methods_read(conn, %{"address_hash" => address_hash_string} = params) do with {:ok, address_hash, smart_contract} <- validate_smart_contract(params, address_hash_string) do - read_only_functions_from_abi = Reader.read_only_functions(smart_contract, address_hash, params["from"]) + read_only_functions_from_abi = Reader.read_only_functions(smart_contract, address_hash, params["from"], @api_true) read_functions_required_wallet_from_abi = Reader.read_functions_required_wallet(smart_contract) @@ -166,7 +166,8 @@ defmodule BlockScoutWeb.API.V2.SmartContractController do address_hash, %{method_id: params["method_id"], args: prepare_args(args)}, params["from"], - custom_abi.abi + custom_abi.abi, + @api_true ) else Reader.query_function_with_names( diff --git a/apps/block_scout_web/lib/block_scout_web/controllers/api/v2/stats_controller.ex b/apps/block_scout_web/lib/block_scout_web/controllers/api/v2/stats_controller.ex index 6ba3b57e7b5c..ceaf7bbda612 100644 --- a/apps/block_scout_web/lib/block_scout_web/controllers/api/v2/stats_controller.ex +++ b/apps/block_scout_web/lib/block_scout_web/controllers/api/v2/stats_controller.ex @@ -3,11 +3,10 @@ defmodule BlockScoutWeb.API.V2.StatsController do alias BlockScoutWeb.API.V2.Helper alias BlockScoutWeb.Chain.MarketHistoryChartController - alias EthereumJSONRPC.Variant alias Explorer.{Chain, Market} alias Explorer.Chain.Address.Counters alias Explorer.Chain.Cache.Block, as: BlockCache - alias Explorer.Chain.Cache.{GasPriceOracle, GasUsage, RootstockLockedBTC} + alias Explorer.Chain.Cache.{GasPriceOracle, GasUsage} alias Explorer.Chain.Cache.Transaction, as: TransactionCache alias Explorer.Chain.Supply.RSK alias Explorer.Chain.Transaction.History.TransactionStats @@ -28,6 +27,7 @@ defmodule BlockScoutWeb.API.V2.StatsController do end exchange_rate = Market.get_coin_exchange_rate() + secondary_coin_exchange_rate = Market.get_secondary_coin_exchange_rate() transaction_stats = Helper.get_transaction_stats() @@ -42,9 +42,9 @@ defmodule BlockScoutWeb.API.V2.StatsController do coin_price_change = case Market.fetch_recent_history() do - [today, yesterday | _] -> - today.closing_price && yesterday.closing_price && - today.closing_price + [_today, yesterday | _] -> + exchange_rate.usd_value && yesterday.closing_price && + exchange_rate.usd_value |> Decimal.div(yesterday.closing_price) |> Decimal.sub(1) |> Decimal.mult(100) @@ -67,6 +67,7 @@ defmodule BlockScoutWeb.API.V2.StatsController do "coin_image" => exchange_rate.image_url, "coin_price" => exchange_rate.usd_value, "coin_price_change_percentage" => coin_price_change, + "secondary_coin_price" => secondary_coin_exchange_rate.usd_value, "total_gas_used" => GasUsage.total() |> to_string(), "transactions_today" => Enum.at(transaction_stats, 0).number_of_transactions |> to_string(), "gas_used_today" => Enum.at(transaction_stats, 0).gas_used, @@ -78,7 +79,7 @@ defmodule BlockScoutWeb.API.V2.StatsController do "tvl" => exchange_rate.tvl_usd, "network_utilization_percentage" => network_utilization_percentage() } - |> add_rootstock_locked_btc() + |> add_chain_type_fields() |> backward_compatibility(conn) ) end @@ -148,13 +149,16 @@ defmodule BlockScoutWeb.API.V2.StatsController do }) end - defp add_rootstock_locked_btc(stats) do - with "rsk" <- Variant.get(), - rootstock_locked_btc when not is_nil(rootstock_locked_btc) <- RootstockLockedBTC.get_locked_value() do - stats |> Map.put("rootstock_locked_btc", rootstock_locked_btc) - else - _ -> stats - end + def secondary_coin_market_chart(conn, _params) do + recent_market_history = Market.fetch_recent_history(true) + + chart_data = + recent_market_history + |> Enum.map(fn day -> Map.take(day, [:closing_price, :date]) end) + + json(conn, %{ + chart_data: chart_data + }) end defp backward_compatibility(response, conn) do @@ -170,4 +174,28 @@ defmodule BlockScoutWeb.API.V2.StatsController do end) end end + + case Application.compile_env(:explorer, :chain_type) do + :rsk -> + defp add_chain_type_fields(response) do + alias Explorer.Chain.Cache.RootstockLockedBTC + + case RootstockLockedBTC.get_locked_value() do + rootstock_locked_btc when not is_nil(rootstock_locked_btc) -> + response |> Map.put("rootstock_locked_btc", rootstock_locked_btc) + + _ -> + response + end + end + + "optimism" -> + defp add_chain_type_fields(response) do + import Explorer.Counters.LastOutputRootSizeCounter, only: [fetch: 1] + response |> Map.put("last_output_root_size", fetch(@api_true)) + end + + _ -> + defp add_chain_type_fields(response), do: response + end end diff --git a/apps/block_scout_web/lib/block_scout_web/controllers/api/v2/token_controller.ex b/apps/block_scout_web/lib/block_scout_web/controllers/api/v2/token_controller.ex index 3a62f1de48e7..6d212582423a 100644 --- a/apps/block_scout_web/lib/block_scout_web/controllers/api/v2/token_controller.ex +++ b/apps/block_scout_web/lib/block_scout_web/controllers/api/v2/token_controller.ex @@ -5,7 +5,7 @@ defmodule BlockScoutWeb.API.V2.TokenController do alias BlockScoutWeb.API.V2.{AddressView, TransactionView} alias Explorer.{Chain, Repo} alias Explorer.Chain.{Address, BridgedToken, Token, Token.Instance} - alias Indexer.Fetcher.TokenTotalSupplyOnDemand + alias Indexer.Fetcher.OnDemand.TokenTotalSupply, as: TokenTotalSupplyOnDemand import BlockScoutWeb.Chain, only: [ @@ -26,6 +26,7 @@ defmodule BlockScoutWeb.API.V2.TokenController do ] import Explorer.MicroserviceInterfaces.BENS, only: [maybe_preload_ens: 1] + import Explorer.MicroserviceInterfaces.Metadata, only: [maybe_preload_metadata: 1] action_fallback(BlockScoutWeb.API.V2.FallbackController) @@ -96,7 +97,7 @@ defmodule BlockScoutWeb.API.V2.TokenController do |> put_status(200) |> put_view(TransactionView) |> render(:token_transfers, %{ - token_transfers: token_transfers |> maybe_preload_ens(), + token_transfers: token_transfers |> maybe_preload_ens() |> maybe_preload_metadata(), next_page_params: next_page_params }) end @@ -116,7 +117,7 @@ defmodule BlockScoutWeb.API.V2.TokenController do conn |> put_status(200) |> render(:token_balances, %{ - token_balances: token_balances |> maybe_preload_ens(), + token_balances: token_balances |> maybe_preload_ens() |> maybe_preload_metadata(), next_page_params: next_page_params, token: token }) @@ -189,7 +190,7 @@ defmodule BlockScoutWeb.API.V2.TokenController do {:not_found, false} <- {:not_found, Chain.erc_20_token?(token)}, {:format, {token_id, ""}} <- {:format, Integer.parse(token_id_str)} do token_instance = - case Chain.erc721_or_erc1155_token_instance_from_token_id_and_token_address(token_id, address_hash, @api_true) do + case Chain.nft_instance_from_token_id_and_token_address(token_id, address_hash, @api_true) do {:ok, token_instance} -> token_instance |> Chain.select_repo(@api_true).preload(:owner) @@ -239,7 +240,7 @@ defmodule BlockScoutWeb.API.V2.TokenController do |> put_status(200) |> put_view(TransactionView) |> render(:token_transfers, %{ - token_transfers: token_transfers |> maybe_preload_ens(), + token_transfers: token_transfers |> maybe_preload_ens() |> maybe_preload_metadata(), next_page_params: next_page_params }) end @@ -269,7 +270,7 @@ defmodule BlockScoutWeb.API.V2.TokenController do conn |> put_status(200) |> render(:token_balances, %{ - token_balances: token_holders |> maybe_preload_ens(), + token_balances: token_holders |> maybe_preload_ens() |> maybe_preload_metadata(), next_page_params: next_page_params, token: token }) diff --git a/apps/block_scout_web/lib/block_scout_web/controllers/api/v2/transaction_controller.ex b/apps/block_scout_web/lib/block_scout_web/controllers/api/v2/transaction_controller.ex index a850ed2c421e..51989d4431ad 100644 --- a/apps/block_scout_web/lib/block_scout_web/controllers/api/v2/transaction_controller.ex +++ b/apps/block_scout_web/lib/block_scout_web/controllers/api/v2/transaction_controller.ex @@ -25,19 +25,24 @@ defmodule BlockScoutWeb.API.V2.TransactionController do import Explorer.MicroserviceInterfaces.BENS, only: [maybe_preload_ens: 1, maybe_preload_ens_to_transaction: 1] + import Explorer.MicroserviceInterfaces.Metadata, + only: [maybe_preload_metadata: 1, maybe_preload_metadata_to_transaction: 1] + alias BlockScoutWeb.AccessHelper alias BlockScoutWeb.MicroserviceInterfaces.TransactionInterpretation, as: TransactionInterpretationService alias BlockScoutWeb.Models.TransactionStateHelper alias Explorer.Chain alias Explorer.Chain.Beacon.Reader, as: BeaconReader - alias Explorer.Chain.{Hash, Transaction} - alias Explorer.Chain.PolygonZkevm.Reader - alias Indexer.Fetcher.FirstTraceOnDemand + alias Explorer.Chain.{Hash, InternalTransaction, Transaction} + alias Explorer.Chain.PolygonZkevm.Reader, as: PolygonZkevmReader + alias Explorer.Chain.ZkSync.Reader, as: ZkSyncReader + alias Explorer.Counters.{FreshPendingTransactionsCounter, Transactions24hStats} + alias Indexer.Fetcher.OnDemand.FirstTrace, as: FirstTraceOnDemand action_fallback(BlockScoutWeb.API.V2.FallbackController) case Application.compile_env(:explorer, :chain_type) do - "ethereum" -> + :ethereum -> @chain_type_transaction_necessity_by_association %{ :beacon_blob_transaction => :optional } @@ -51,6 +56,7 @@ defmodule BlockScoutWeb.API.V2.TransactionController do :block => :optional, [created_contract_address: :names] => :optional, [created_contract_address: :token] => :optional, + [created_contract_address: :smart_contract] => :optional, [from_address: :names] => :optional, [to_address: :names] => :optional, [to_address: :smart_contract] => :optional @@ -95,13 +101,20 @@ defmodule BlockScoutWeb.API.V2.TransactionController do necessity_by_association = case Application.get_env(:explorer, :chain_type) do - "polygon_zkevm" -> + :polygon_zkevm -> necessity_by_association_with_actions |> Map.put(:zkevm_batch, :optional) |> Map.put(:zkevm_sequence_transaction, :optional) |> Map.put(:zkevm_verify_transaction, :optional) - "suave" -> + :zksync -> + necessity_by_association_with_actions + |> Map.put(:zksync_batch, :optional) + |> Map.put(:zksync_commit_transaction, :optional) + |> Map.put(:zksync_prove_transaction, :optional) + |> Map.put(:zksync_execute_transaction, :optional) + + :suave -> necessity_by_association_with_actions |> Map.put(:logs, :optional) |> Map.put([execution_node: :names], :optional) @@ -120,7 +133,9 @@ defmodule BlockScoutWeb.API.V2.TransactionController do Chain.preload_token_transfers(transaction, @token_transfers_in_tx_necessity_by_association, @api_true, false) do conn |> put_status(200) - |> render(:transaction, %{transaction: preloaded |> maybe_preload_ens_to_transaction()}) + |> render(:transaction, %{ + transaction: preloaded |> maybe_preload_ens_to_transaction() |> maybe_preload_metadata_to_transaction() + }) end end @@ -148,7 +163,10 @@ defmodule BlockScoutWeb.API.V2.TransactionController do conn |> put_status(200) - |> render(:transactions, %{transactions: transactions |> maybe_preload_ens(), next_page_params: next_page_params}) + |> render(:transactions, %{ + transactions: transactions |> maybe_preload_ens() |> maybe_preload_metadata(), + next_page_params: next_page_params + }) end @doc """ @@ -159,13 +177,50 @@ defmodule BlockScoutWeb.API.V2.TransactionController do def polygon_zkevm_batch(conn, %{"batch_number" => batch_number} = _params) do transactions = batch_number - |> Reader.batch_transactions(api?: true) + |> PolygonZkevmReader.batch_transactions(api?: true) |> Enum.map(fn tx -> tx.hash end) |> Chain.hashes_to_transactions(api?: true, necessity_by_association: @transaction_necessity_by_association) conn |> put_status(200) - |> render(:transactions, %{transactions: transactions |> maybe_preload_ens(), items: true}) + |> render(:transactions, %{ + transactions: transactions |> maybe_preload_ens() |> maybe_preload_metadata(), + items: true + }) + end + + @doc """ + Function to handle GET requests to `/api/v2/transactions/zksync-batch/:batch_number` endpoint. + It renders the list of L2 transactions bound to the specified batch. + """ + @spec zksync_batch(Plug.Conn.t(), map()) :: Plug.Conn.t() + def zksync_batch(conn, %{"batch_number" => batch_number} = params) do + full_options = + [ + necessity_by_association: @transaction_necessity_by_association + ] + |> Keyword.merge(paging_options(params)) + |> Keyword.merge(@api_true) + + # Although a naive way is to implement pagination on the level of `batch_transactions` call, + # it will require to re-implement all pagination logic existing in Explorer.Chain.Transaction + # In order to simplify the code, all transaction are requested from the batch and then + # only subset of them is returned from `hashes_to_transactions`. + raw_transactions_list = + batch_number + |> ZkSyncReader.batch_transactions(api?: true) + |> Enum.map(fn tx -> tx.hash end) + |> Chain.hashes_to_transactions(full_options) + + {transactions, next_page} = split_list_by_page(raw_transactions_list) + next_page_params = next_page |> next_page_params(transactions, delete_parameters_from_next_page_params(params)) + + conn + |> put_status(200) + |> render(:transactions, %{ + transactions: transactions |> maybe_preload_ens() |> maybe_preload_metadata(), + next_page_params: next_page_params + }) end def execution_node(conn, %{"execution_node_hash_param" => execution_node_hash_string} = params) do @@ -185,7 +240,10 @@ defmodule BlockScoutWeb.API.V2.TransactionController do conn |> put_status(200) - |> render(:transactions, %{transactions: transactions |> maybe_preload_ens(), next_page_params: next_page_params}) + |> render(:transactions, %{ + transactions: transactions |> maybe_preload_ens() |> maybe_preload_metadata(), + next_page_params: next_page_params + }) end end @@ -200,7 +258,8 @@ defmodule BlockScoutWeb.API.V2.TransactionController do |> put_status(200) |> render(:raw_trace, %{internal_transactions: []}) else - internal_transactions = Chain.all_transaction_to_internal_transactions(transaction_hash, @api_true) + internal_transactions = + InternalTransaction.all_transaction_to_internal_transactions(transaction_hash, @api_true) first_trace_exists = Enum.find_index(internal_transactions, fn trace -> @@ -247,7 +306,7 @@ defmodule BlockScoutWeb.API.V2.TransactionController do conn |> put_status(200) |> render(:token_transfers, %{ - token_transfers: token_transfers |> maybe_preload_ens(), + token_transfers: token_transfers |> maybe_preload_ens() |> maybe_preload_metadata(), next_page_params: next_page_params }) end @@ -264,7 +323,8 @@ defmodule BlockScoutWeb.API.V2.TransactionController do |> Keyword.merge(paging_options(params)) |> Keyword.merge(@api_true) - internal_transactions_plus_one = Chain.transaction_to_internal_transactions(transaction_hash, full_options) + internal_transactions_plus_one = + InternalTransaction.transaction_to_internal_transactions(transaction_hash, full_options) {internal_transactions, next_page} = split_list_by_page(internal_transactions_plus_one) @@ -275,7 +335,7 @@ defmodule BlockScoutWeb.API.V2.TransactionController do conn |> put_status(200) |> render(:internal_transactions, %{ - internal_transactions: internal_transactions |> maybe_preload_ens(), + internal_transactions: internal_transactions |> maybe_preload_ens() |> maybe_preload_metadata(), next_page_params: next_page_params }) end @@ -310,7 +370,7 @@ defmodule BlockScoutWeb.API.V2.TransactionController do |> put_status(200) |> render(:logs, %{ tx_hash: transaction_hash, - logs: logs |> maybe_preload_ens(), + logs: logs |> maybe_preload_ens() |> maybe_preload_metadata(), next_page_params: next_page_params }) end @@ -364,7 +424,7 @@ defmodule BlockScoutWeb.API.V2.TransactionController do conn |> put_status(200) |> render(:transactions_watchlist, %{ - transactions: transactions |> maybe_preload_ens(), + transactions: transactions |> maybe_preload_ens() |> maybe_preload_metadata(), next_page_params: next_page_params, watchlist_names: watchlist_names }) @@ -421,6 +481,25 @@ defmodule BlockScoutWeb.API.V2.TransactionController do end end + def stats(conn, _params) do + transactions_count = Transactions24hStats.fetch_count(@api_true) + pending_transactions_count = FreshPendingTransactionsCounter.fetch(@api_true) + transaction_fees_sum = Transactions24hStats.fetch_fee_sum(@api_true) + transaction_fees_avg = Transactions24hStats.fetch_fee_average(@api_true) + + conn + |> put_status(200) + |> render( + :stats, + %{ + transactions_count_24h: transactions_count, + pending_transactions_count: pending_transactions_count, + transaction_fees_sum_24h: transaction_fees_sum, + transaction_fees_avg_24h: transaction_fees_avg + } + ) + end + @doc """ Checks if this valid transaction hash string, and this transaction doesn't belong to prohibited address """ diff --git a/apps/block_scout_web/lib/block_scout_web/controllers/api/v2/validator_controller.ex b/apps/block_scout_web/lib/block_scout_web/controllers/api/v2/validator_controller.ex new file mode 100644 index 000000000000..4c7883502814 --- /dev/null +++ b/apps/block_scout_web/lib/block_scout_web/controllers/api/v2/validator_controller.ex @@ -0,0 +1,83 @@ +defmodule BlockScoutWeb.API.V2.ValidatorController do + use BlockScoutWeb, :controller + + alias Explorer.Chain.Cache.StabilityValidatorsCounters + alias Explorer.Chain.Stability.Validator, as: ValidatorStability + + import BlockScoutWeb.PagingHelper, + only: [ + delete_parameters_from_next_page_params: 1, + stability_validators_state_options: 1, + validators_stability_sorting: 1 + ] + + import BlockScoutWeb.Chain, + only: [ + split_list_by_page: 1, + paging_options: 1, + next_page_params: 4 + ] + + @api_true api?: true + + @doc """ + Function to handle GET requests to `/api/v2/validators/stability` endpoint. + """ + @spec stability_validators_list(Plug.Conn.t(), map()) :: Plug.Conn.t() + def stability_validators_list(conn, params) do + options = + [ + necessity_by_association: %{ + :address => :optional + } + ] + |> Keyword.merge(@api_true) + |> Keyword.merge(paging_options(params)) + |> Keyword.merge(validators_stability_sorting(params)) + |> Keyword.merge(stability_validators_state_options(params)) + + {validators, next_page} = options |> ValidatorStability.get_paginated_validators() |> split_list_by_page() + + next_page_params = + next_page + |> next_page_params( + validators, + delete_parameters_from_next_page_params(params), + &ValidatorStability.next_page_params/1 + ) + + conn + |> render(:stability_validators, %{validators: validators, next_page_params: next_page_params}) + end + + @doc """ + Function to handle GET requests to `/api/v2/validators/stability/counters` endpoint. + """ + @spec stability_validators_counters(Plug.Conn.t(), map()) :: Plug.Conn.t() + def stability_validators_counters(conn, _params) do + %{ + validators_counter: validators_counter, + new_validators_counter: new_validators_counter, + active_validators_counter: active_validators_counter + } = StabilityValidatorsCounters.get_counters(@api_true) + + conn + |> json(%{ + validators_counter: validators_counter, + new_validators_counter_24h: new_validators_counter, + active_validators_counter: active_validators_counter, + active_validators_percentage: + calculate_active_validators_percentage(active_validators_counter, validators_counter) + }) + end + + defp calculate_active_validators_percentage(active_validators_counter, validators_counter) do + if Decimal.compare(validators_counter, Decimal.new(0)) == :gt do + active_validators_counter + |> Decimal.div(validators_counter) + |> Decimal.mult(100) + |> Decimal.to_float() + |> Float.floor(2) + end + end +end diff --git a/apps/block_scout_web/lib/block_scout_web/controllers/api/v2/withdrawal_controller.ex b/apps/block_scout_web/lib/block_scout_web/controllers/api/v2/withdrawal_controller.ex index 4282d16d4fbb..f9f9e17e9be9 100644 --- a/apps/block_scout_web/lib/block_scout_web/controllers/api/v2/withdrawal_controller.ex +++ b/apps/block_scout_web/lib/block_scout_web/controllers/api/v2/withdrawal_controller.ex @@ -6,6 +6,7 @@ defmodule BlockScoutWeb.API.V2.WithdrawalController do import BlockScoutWeb.PagingHelper, only: [delete_parameters_from_next_page_params: 1] import Explorer.MicroserviceInterfaces.BENS, only: [maybe_preload_ens: 1] + import Explorer.MicroserviceInterfaces.Metadata, only: [maybe_preload_metadata: 1] alias Explorer.Chain @@ -21,7 +22,10 @@ defmodule BlockScoutWeb.API.V2.WithdrawalController do conn |> put_status(200) - |> render(:withdrawals, %{withdrawals: withdrawals |> maybe_preload_ens(), next_page_params: next_page_params}) + |> render(:withdrawals, %{ + withdrawals: withdrawals |> maybe_preload_ens() |> maybe_preload_metadata(), + next_page_params: next_page_params + }) end def withdrawals_counters(conn, _params) do diff --git a/apps/block_scout_web/lib/block_scout_web/controllers/api/v2/zksync_controller.ex b/apps/block_scout_web/lib/block_scout_web/controllers/api/v2/zksync_controller.ex new file mode 100644 index 000000000000..8f96f0e1c2df --- /dev/null +++ b/apps/block_scout_web/lib/block_scout_web/controllers/api/v2/zksync_controller.ex @@ -0,0 +1,113 @@ +defmodule BlockScoutWeb.API.V2.ZkSyncController do + use BlockScoutWeb, :controller + + import BlockScoutWeb.Chain, + only: [ + next_page_params: 4, + paging_options: 1, + split_list_by_page: 1 + ] + + alias Explorer.Chain.ZkSync.{Reader, TransactionBatch} + + action_fallback(BlockScoutWeb.API.V2.FallbackController) + + @batch_necessity_by_association %{ + :commit_transaction => :optional, + :prove_transaction => :optional, + :execute_transaction => :optional + } + + @doc """ + Function to handle GET requests to `/api/v2/zksync/batches/:batch_number` endpoint. + """ + @spec batch(Plug.Conn.t(), map()) :: Plug.Conn.t() + def batch(conn, %{"batch_number" => batch_number} = _params) do + case Reader.batch( + batch_number, + necessity_by_association: @batch_necessity_by_association, + api?: true + ) do + {:ok, batch} -> + conn + |> put_status(200) + |> render(:zksync_batch, %{batch: batch}) + + {:error, :not_found} = res -> + res + end + end + + @doc """ + Function to handle GET requests to `/api/v2/zksync/batches` endpoint. + """ + @spec batches(Plug.Conn.t(), map()) :: Plug.Conn.t() + def batches(conn, params) do + {batches, next_page} = + params + |> paging_options() + |> Keyword.put(:necessity_by_association, @batch_necessity_by_association) + |> Keyword.put(:api?, true) + |> Reader.batches() + |> split_list_by_page() + + next_page_params = + next_page_params( + next_page, + batches, + params, + fn %TransactionBatch{number: number} -> %{"number" => number} end + ) + + conn + |> put_status(200) + |> render(:zksync_batches, %{ + batches: batches, + next_page_params: next_page_params + }) + end + + @doc """ + Function to handle GET requests to `/api/v2/zksync/batches/count` endpoint. + """ + @spec batches_count(Plug.Conn.t(), map()) :: Plug.Conn.t() + def batches_count(conn, _params) do + conn + |> put_status(200) + |> render(:zksync_batches_count, %{count: Reader.batches_count(api?: true)}) + end + + @doc """ + Function to handle GET requests to `/api/v2/main-page/zksync/batches/confirmed` endpoint. + """ + @spec batches_confirmed(Plug.Conn.t(), map()) :: Plug.Conn.t() + def batches_confirmed(conn, _params) do + batches = + [] + |> Keyword.put(:necessity_by_association, @batch_necessity_by_association) + |> Keyword.put(:api?, true) + |> Keyword.put(:confirmed?, true) + |> Reader.batches() + + conn + |> put_status(200) + |> render(:zksync_batches, %{batches: batches}) + end + + @doc """ + Function to handle GET requests to `/api/v2/main-page/zksync/batches/latest-number` endpoint. + """ + @spec batch_latest_number(Plug.Conn.t(), map()) :: Plug.Conn.t() + def batch_latest_number(conn, _params) do + conn + |> put_status(200) + |> render(:zksync_batch_latest_number, %{number: batch_latest_number()}) + end + + defp batch_latest_number do + case Reader.batch(:latest, api?: true) do + {:ok, batch} -> batch.number + {:error, :not_found} -> 0 + end + end +end diff --git a/apps/block_scout_web/lib/block_scout_web/controllers/tokens/holder_controller.ex b/apps/block_scout_web/lib/block_scout_web/controllers/tokens/holder_controller.ex index 6a61ff30e5a3..1a3a7d7e183e 100644 --- a/apps/block_scout_web/lib/block_scout_web/controllers/tokens/holder_controller.ex +++ b/apps/block_scout_web/lib/block_scout_web/controllers/tokens/holder_controller.ex @@ -8,7 +8,7 @@ defmodule BlockScoutWeb.Tokens.HolderController do alias BlockScoutWeb.Tokens.HolderView alias Explorer.Chain alias Explorer.Chain.Address - alias Indexer.Fetcher.TokenTotalSupplyOnDemand + alias Indexer.Fetcher.OnDemand.TokenTotalSupply, as: TokenTotalSupplyOnDemand alias Phoenix.View import BlockScoutWeb.Chain, diff --git a/apps/block_scout_web/lib/block_scout_web/controllers/tokens/instance/holder_controller.ex b/apps/block_scout_web/lib/block_scout_web/controllers/tokens/instance/holder_controller.ex index 4794e14723b4..2b2eab99b7ef 100644 --- a/apps/block_scout_web/lib/block_scout_web/controllers/tokens/instance/holder_controller.ex +++ b/apps/block_scout_web/lib/block_scout_web/controllers/tokens/instance/holder_controller.ex @@ -60,7 +60,7 @@ defmodule BlockScoutWeb.Tokens.Instance.HolderController do {:ok, token} <- Chain.token_from_address_hash(hash, options), false <- Chain.erc_20_token?(token), {token_id, ""} <- Integer.parse(token_id_str) do - case Chain.erc721_or_erc1155_token_instance_from_token_id_and_token_address(token_id, hash) do + case Chain.nft_instance_from_token_id_and_token_address(token_id, hash) do {:ok, token_instance} -> Helper.render(conn, token_instance, hash, token_id, token) {:error, :not_found} -> Helper.render(conn, nil, hash, token_id, token) end diff --git a/apps/block_scout_web/lib/block_scout_web/controllers/tokens/instance/metadata_controller.ex b/apps/block_scout_web/lib/block_scout_web/controllers/tokens/instance/metadata_controller.ex index fe691d770e17..0036a95563ca 100644 --- a/apps/block_scout_web/lib/block_scout_web/controllers/tokens/instance/metadata_controller.ex +++ b/apps/block_scout_web/lib/block_scout_web/controllers/tokens/instance/metadata_controller.ex @@ -12,7 +12,7 @@ defmodule BlockScoutWeb.Tokens.Instance.MetadataController do false <- Chain.erc_20_token?(token), {token_id, ""} <- Integer.parse(token_id_str), {:ok, token_instance} <- - Chain.erc721_or_erc1155_token_instance_from_token_id_and_token_address(token_id, hash) do + Chain.nft_instance_from_token_id_and_token_address(token_id, hash) do if token_instance.metadata do Helper.render(conn, token_instance, hash, token_id, token) else diff --git a/apps/block_scout_web/lib/block_scout_web/controllers/tokens/instance/transfer_controller.ex b/apps/block_scout_web/lib/block_scout_web/controllers/tokens/instance/transfer_controller.ex index bd52bdba24f0..30a8212a75f9 100644 --- a/apps/block_scout_web/lib/block_scout_web/controllers/tokens/instance/transfer_controller.ex +++ b/apps/block_scout_web/lib/block_scout_web/controllers/tokens/instance/transfer_controller.ex @@ -63,7 +63,7 @@ defmodule BlockScoutWeb.Tokens.Instance.TransferController do {:ok, token} <- Chain.token_from_address_hash(hash, options), false <- Chain.erc_20_token?(token), {token_id, ""} <- Integer.parse(token_id_str) do - case Chain.erc721_or_erc1155_token_instance_from_token_id_and_token_address(token_id, hash) do + case Chain.nft_instance_from_token_id_and_token_address(token_id, hash) do {:ok, token_instance} -> Helper.render(conn, token_instance, hash, token_id, token) {:error, :not_found} -> Helper.render(conn, nil, hash, token_id, token) end diff --git a/apps/block_scout_web/lib/block_scout_web/controllers/tokens/transfer_controller.ex b/apps/block_scout_web/lib/block_scout_web/controllers/tokens/transfer_controller.ex index b36159b82b66..c604d0750c7c 100644 --- a/apps/block_scout_web/lib/block_scout_web/controllers/tokens/transfer_controller.ex +++ b/apps/block_scout_web/lib/block_scout_web/controllers/tokens/transfer_controller.ex @@ -8,7 +8,7 @@ defmodule BlockScoutWeb.Tokens.TransferController do alias BlockScoutWeb.Tokens.TransferView alias Explorer.Chain alias Explorer.Chain.Address - alias Indexer.Fetcher.TokenTotalSupplyOnDemand + alias Indexer.Fetcher.OnDemand.TokenTotalSupply, as: TokenTotalSupplyOnDemand alias Phoenix.View import BlockScoutWeb.Chain, only: [split_list_by_page: 1, paging_options: 1, next_page_params: 3] diff --git a/apps/block_scout_web/lib/block_scout_web/controllers/transaction_internal_transaction_controller.ex b/apps/block_scout_web/lib/block_scout_web/controllers/transaction_internal_transaction_controller.ex index 5ea1e447211a..f3f9cc4910c9 100644 --- a/apps/block_scout_web/lib/block_scout_web/controllers/transaction_internal_transaction_controller.ex +++ b/apps/block_scout_web/lib/block_scout_web/controllers/transaction_internal_transaction_controller.ex @@ -8,7 +8,7 @@ defmodule BlockScoutWeb.TransactionInternalTransactionController do alias BlockScoutWeb.{AccessHelper, Controller, InternalTransactionView, TransactionController} alias Explorer.{Chain, Market} - alias Explorer.Chain.DenormalizationHelper + alias Explorer.Chain.{DenormalizationHelper, InternalTransaction} alias Phoenix.View def index(conn, %{"transaction_id" => transaction_hash_string, "type" => "JSON"} = params) do @@ -32,7 +32,8 @@ defmodule BlockScoutWeb.TransactionInternalTransactionController do |> DenormalizationHelper.extend_transaction_block_necessity(:optional) |> Keyword.merge(paging_options(params)) - internal_transactions_plus_one = Chain.transaction_to_internal_transactions(transaction_hash, full_options) + internal_transactions_plus_one = + InternalTransaction.transaction_to_internal_transactions(transaction_hash, full_options) {internal_transactions, next_page} = split_list_by_page(internal_transactions_plus_one) diff --git a/apps/block_scout_web/lib/block_scout_web/controllers/transaction_raw_trace_controller.ex b/apps/block_scout_web/lib/block_scout_web/controllers/transaction_raw_trace_controller.ex index 93002d434822..05c3da6d8db4 100644 --- a/apps/block_scout_web/lib/block_scout_web/controllers/transaction_raw_trace_controller.ex +++ b/apps/block_scout_web/lib/block_scout_web/controllers/transaction_raw_trace_controller.ex @@ -8,7 +8,8 @@ defmodule BlockScoutWeb.TransactionRawTraceController do alias BlockScoutWeb.{AccessHelper, TransactionController} alias EthereumJSONRPC alias Explorer.{Chain, Market} - alias Indexer.Fetcher.FirstTraceOnDemand + alias Explorer.Chain.InternalTransaction + alias Indexer.Fetcher.OnDemand.FirstTrace, as: FirstTraceOnDemand def index(conn, %{"transaction_id" => hash_string} = params) do with {:ok, hash} <- Chain.string_to_transaction_hash(hash_string), @@ -29,7 +30,7 @@ defmodule BlockScoutWeb.TransactionRawTraceController do if is_nil(transaction.block_number) do render_raw_trace(conn, [], transaction, hash) else - internal_transactions = Chain.all_transaction_to_internal_transactions(hash) + internal_transactions = InternalTransaction.all_transaction_to_internal_transactions(hash) first_trace_exists = Enum.find_index(internal_transactions, fn trace -> diff --git a/apps/block_scout_web/lib/block_scout_web/etherscan.ex b/apps/block_scout_web/lib/block_scout_web/etherscan.ex index e477eb9dca5c..b6be61809eb5 100644 --- a/apps/block_scout_web/lib/block_scout_web/etherscan.ex +++ b/apps/block_scout_web/lib/block_scout_web/etherscan.ex @@ -2,6 +2,7 @@ defmodule BlockScoutWeb.Etherscan do @moduledoc """ Documentation data for Etherscan-compatible API. """ + alias Explorer.Chain.BridgedToken @account_balance_example_value %{ "status" => "1", @@ -2009,6 +2010,117 @@ defmodule BlockScoutWeb.Etherscan do ] } + if Application.compile_env(:explorer, BridgedToken)[:enabled] do + @success_status_type %{ + type: "status", + enum: ~s(["1"]), + enum_interpretation: %{"1" => "ok"} + } + + @bridged_token_details %{ + name: "Bridged Token Detail", + fields: %{ + foreignChainId: %{ + type: "value", + definition: "Chain ID of the chain where original token exists.", + example: ~s("1") + }, + foreignTokenContractAddressHash: @address_hash_type, + homeContractAddressHash: @address_hash_type, + homeDecimals: @token_decimal_type, + homeHolderCount: %{ + type: "value", + definition: "Token holders count.", + example: ~s("393") + }, + homeName: @token_name_type, + homeSymbol: @token_symbol_type, + homeTotalSupply: %{ + type: "value", + definition: "Total supply of the token on the home side (where token was bridged).", + example: ~s("1484374.775044204093387391") + }, + homeUsdValue: %{ + type: "value", + definition: "Total supply of the token on the home side (where token was bridged) in USD.", + example: ~s("6638727.472651464170990256943") + } + } + } + + @token_bridgedtokenlist_example_value %{ + "status" => "1", + "message" => "OK", + "result" => [ + %{ + "foreignChainId" => "1", + "foreignTokenContractAddressHash" => "0x0ae055097c6d159879521c384f1d2123d1f195e6", + "homeContractAddressHash" => "0xb7d311e2eb55f2f68a9440da38e7989210b9a05e", + "homeDecimals" => "18", + "homeHolderCount" => 393, + "homeName" => "STAKE on xDai", + "homeSymbol" => "STAKE", + "homeTotalSupply" => "1484374.775044204093387391", + "homeUsdValue" => "18807028.39981006586321824397" + }, + %{ + "foreignChainId" => "1", + "foreignTokenContractAddressHash" => "0xf5581dfefd8fb0e4aec526be659cfab1f8c781da", + "homeContractAddressHash" => "0xd057604a14982fe8d88c5fc25aac3267ea142a08", + "homeDecimals" => "18", + "homeHolderCount" => 73, + "homeName" => "HOPR Token on xDai", + "homeSymbol" => "HOPR", + "homeTotalSupply" => "26600449.86076749062791602", + "homeUsdValue" => "6638727.472651464170990256943" + } + ] + } + + @token_bridgedtokenlist_action %{ + name: "bridgedTokenList", + description: "Get bridged tokens list.", + required_params: [], + optional_params: [ + %{ + key: "chainid", + type: "integer", + description: "A nonnegative integer that represents the chain id, where original token exists." + }, + %{ + key: "page", + type: "integer", + description: + "A nonnegative integer that represents the page number to be used for pagination. 'offset' must be provided in conjunction." + }, + %{ + key: "offset", + type: "integer", + description: + "A nonnegative integer that represents the maximum number of records to return when paginating. 'page' must be provided in conjunction." + } + ], + responses: [ + %{ + code: "200", + description: "successful operation", + example_value: Jason.encode!(@token_bridgedtokenlist_example_value), + model: %{ + name: "Result", + fields: %{ + status: @success_status_type, + message: @message_type, + result: %{ + type: "array", + array_type: @bridged_token_details + } + } + } + } + ] + } + end + @stats_tokensupply_action %{ name: "tokensupply", description: @@ -2947,12 +3059,18 @@ defmodule BlockScoutWeb.Etherscan do actions: [@logs_getlogs_action] } + @base_token_actions [ + @token_gettoken_action, + @token_gettokenholders_action + ] + + @token_actions if Application.compile_env(:explorer, BridgedToken)[:enabled], + do: [@token_bridgedtokenlist_action, @base_token_actions], + else: @base_token_actions + @token_module %{ name: "token", - actions: [ - @token_gettoken_action, - @token_gettokenholders_action - ] + actions: @token_actions } @stats_module %{ diff --git a/apps/block_scout_web/lib/block_scout_web/graphql/resolvers/address.ex b/apps/block_scout_web/lib/block_scout_web/graphql/resolvers/address.ex new file mode 100644 index 000000000000..4a9449979b4c --- /dev/null +++ b/apps/block_scout_web/lib/block_scout_web/graphql/resolvers/address.ex @@ -0,0 +1,28 @@ +defmodule BlockScoutWeb.GraphQL.Resolvers.Address do + @moduledoc false + + alias BlockScoutWeb.GraphQL.Resolvers.Helper + alias Explorer.Chain + + def get_by(_, %{hashes: hashes}, resolution) do + if resolution.context.api_enabled do + case Chain.hashes_to_addresses(hashes) do + [] -> {:error, "Addresses not found."} + result -> {:ok, result} + end + else + {:error, Helper.api_is_disabled()} + end + end + + def get_by(_, %{hash: hash}, resolution) do + if resolution.context.api_enabled do + case Chain.hash_to_address(hash) do + {:error, :not_found} -> {:error, "Address not found."} + {:ok, _} = result -> result + end + else + {:error, Helper.api_is_disabled()} + end + end +end diff --git a/apps/block_scout_web/lib/block_scout_web/graphql/resolvers/block.ex b/apps/block_scout_web/lib/block_scout_web/graphql/resolvers/block.ex new file mode 100644 index 000000000000..913ae80586d9 --- /dev/null +++ b/apps/block_scout_web/lib/block_scout_web/graphql/resolvers/block.ex @@ -0,0 +1,16 @@ +defmodule BlockScoutWeb.GraphQL.Resolvers.Block do + @moduledoc false + + alias BlockScoutWeb.GraphQL.Resolvers.Helper + alias Explorer.Chain + + def get_by(_, %{number: number}, resolution) do + with {:api_enabled, true} <- {:api_enabled, resolution.context.api_enabled}, + {:ok, _} = result <- Chain.number_to_block(number) do + result + else + {:api_enabled, false} -> {:error, Helper.api_is_disabled()} + {:error, :not_found} -> {:error, "Block number #{number} was not found."} + end + end +end diff --git a/apps/block_scout_web/lib/block_scout_web/graphql/resolvers/helper.ex b/apps/block_scout_web/lib/block_scout_web/graphql/resolvers/helper.ex new file mode 100644 index 000000000000..215e713acff9 --- /dev/null +++ b/apps/block_scout_web/lib/block_scout_web/graphql/resolvers/helper.ex @@ -0,0 +1,9 @@ +defmodule BlockScoutWeb.GraphQL.Resolvers.Helper do + @moduledoc """ + Helper functions for BlockScoutWeb.GraphQL.Resolvers modules + """ + + @api_is_disabled "GraphQL API is disabled." + + def api_is_disabled, do: @api_is_disabled +end diff --git a/apps/block_scout_web/lib/block_scout_web/graphql/resolvers/internal_transaction.ex b/apps/block_scout_web/lib/block_scout_web/graphql/resolvers/internal_transaction.ex new file mode 100644 index 000000000000..647ae0b36134 --- /dev/null +++ b/apps/block_scout_web/lib/block_scout_web/graphql/resolvers/internal_transaction.ex @@ -0,0 +1,32 @@ +defmodule BlockScoutWeb.GraphQL.Resolvers.InternalTransaction do + @moduledoc false + + alias Absinthe.Relay.Connection + alias BlockScoutWeb.GraphQL.Resolvers.Helper + alias Explorer.Chain.Transaction + alias Explorer.{GraphQL, Repo} + + def get_by(%{transaction_hash: _, index: _} = args, resolution) do + if resolution.context.api_enabled do + GraphQL.get_internal_transaction(args) + else + {:error, Helper.api_is_disabled()} + end + end + + def get_by(%Transaction{} = transaction, args, resolution) do + if resolution.context.api_enabled do + transaction + |> GraphQL.transaction_to_internal_transactions_query() + |> Connection.from_query(&Repo.all/1, args, options(args)) + else + {:error, Helper.api_is_disabled()} + end + end + + defp options(%{before: _}), do: [] + + defp options(%{count: count}), do: [count: count] + + defp options(_), do: [] +end diff --git a/apps/block_scout_web/lib/block_scout_web/graphql/resolvers/token_transfer.ex b/apps/block_scout_web/lib/block_scout_web/graphql/resolvers/token_transfer.ex new file mode 100644 index 000000000000..2fe2a05a6521 --- /dev/null +++ b/apps/block_scout_web/lib/block_scout_web/graphql/resolvers/token_transfer.ex @@ -0,0 +1,33 @@ +defmodule BlockScoutWeb.GraphQL.Resolvers.TokenTransfer do + @moduledoc false + + alias Absinthe.Relay.Connection + alias BlockScoutWeb.GraphQL.Resolvers.Helper + alias Explorer.{GraphQL, Repo} + + def get_by(%{transaction_hash: _, log_index: _} = args, resolution) do + if resolution.context.api_enabled do + GraphQL.get_token_transfer(args) + else + {:error, Helper.api_is_disabled()} + end + end + + def get_by(_, %{token_contract_address_hash: token_contract_address_hash} = args, resolution) do + if resolution.context.api_enabled do + connection_args = Map.take(args, [:after, :before, :first, :last]) + + token_contract_address_hash + |> GraphQL.list_token_transfers_query() + |> Connection.from_query(&Repo.all/1, connection_args, options(args)) + else + {:error, Helper.api_is_disabled()} + end + end + + defp options(%{before: _}), do: [] + + defp options(%{count: count}), do: [count: count] + + defp options(_), do: [] +end diff --git a/apps/block_scout_web/lib/block_scout_web/graphql/resolvers/transaction.ex b/apps/block_scout_web/lib/block_scout_web/graphql/resolvers/transaction.ex new file mode 100644 index 000000000000..2dd299abae1a --- /dev/null +++ b/apps/block_scout_web/lib/block_scout_web/graphql/resolvers/transaction.ex @@ -0,0 +1,36 @@ +defmodule BlockScoutWeb.GraphQL.Resolvers.Transaction do + @moduledoc false + + alias Absinthe.Relay.Connection + alias BlockScoutWeb.GraphQL.Resolvers.Helper + alias Explorer.{Chain, GraphQL, Repo} + alias Explorer.Chain.Address + + def get_by(_, %{hash: hash}, resolution) do + with {:api_enabled, true} <- {:api_enabled, resolution.context.api_enabled}, + {:ok, transaction} <- Chain.hash_to_transaction(hash) do + {:ok, transaction} + else + {:api_enabled, false} -> {:error, Helper.api_is_disabled()} + {:error, :not_found} -> {:error, "Transaction not found."} + end + end + + def get_by(%Address{hash: address_hash}, args, resolution) do + connection_args = Map.take(args, [:after, :before, :first, :last]) + + if resolution.context.api_enabled do + address_hash + |> GraphQL.address_to_transactions_query(args.order) + |> Connection.from_query(&Repo.all/1, connection_args, options(args)) + else + {:error, Helper.api_is_disabled()} + end + end + + defp options(%{before: _}), do: [] + + defp options(%{count: count}), do: [count: count] + + defp options(_), do: [] +end diff --git a/apps/block_scout_web/lib/block_scout_web/schema.ex b/apps/block_scout_web/lib/block_scout_web/graphql/schema.ex similarity index 80% rename from apps/block_scout_web/lib/block_scout_web/schema.ex rename to apps/block_scout_web/lib/block_scout_web/graphql/schema.ex index 42d644c41830..91b11a695900 100644 --- a/apps/block_scout_web/lib/block_scout_web/schema.ex +++ b/apps/block_scout_web/lib/block_scout_web/graphql/schema.ex @@ -1,4 +1,4 @@ -defmodule BlockScoutWeb.Schema do +defmodule BlockScoutWeb.GraphQL.Schema do @moduledoc false use Absinthe.Schema @@ -7,7 +7,7 @@ defmodule BlockScoutWeb.Schema do alias Absinthe.Middleware.Dataloader, as: AbsintheMiddlewareDataloader alias Absinthe.Plugin, as: AbsinthePlugin - alias BlockScoutWeb.Resolvers.{ + alias BlockScoutWeb.GraphQL.Resolvers.{ Address, Block, InternalTransaction, @@ -20,7 +20,7 @@ defmodule BlockScoutWeb.Schema do alias Explorer.Chain.TokenTransfer, as: ExplorerChainTokenTransfer alias Explorer.Chain.Transaction, as: ExplorerChainTransaction - import_types(BlockScoutWeb.Schema.Types) + import_types(BlockScoutWeb.GraphQL.Schema.Types) node interface do resolve_type(fn @@ -41,19 +41,19 @@ defmodule BlockScoutWeb.Schema do query do node field do resolve(fn - %{type: :internal_transaction, id: id}, _ -> + %{type: :internal_transaction, id: id}, resolution -> %{"transaction_hash" => transaction_hash_string, "index" => index} = Jason.decode!(id) {:ok, transaction_hash} = Chain.string_to_transaction_hash(transaction_hash_string) - InternalTransaction.get_by(%{transaction_hash: transaction_hash, index: index}) + InternalTransaction.get_by(%{transaction_hash: transaction_hash, index: index}, resolution) - %{type: :token_transfer, id: id}, _ -> + %{type: :token_transfer, id: id}, resolution -> %{"transaction_hash" => transaction_hash_string, "log_index" => log_index} = Jason.decode!(id) {:ok, transaction_hash} = Chain.string_to_transaction_hash(transaction_hash_string) - TokenTransfer.get_by(%{transaction_hash: transaction_hash, log_index: log_index}) + TokenTransfer.get_by(%{transaction_hash: transaction_hash, log_index: log_index}, resolution) - %{type: :transaction, id: transaction_hash_string}, _ -> + %{type: :transaction, id: transaction_hash_string}, resolution -> {:ok, hash} = Chain.string_to_transaction_hash(transaction_hash_string) - Transaction.get_by(%{}, %{hash: hash}, %{}) + Transaction.get_by(%{}, %{hash: hash}, resolution) _, _ -> {:error, "Unknown node"} @@ -113,9 +113,16 @@ defmodule BlockScoutWeb.Schema do end def context(context) do - loader = Dataloader.add_source(Dataloader.new(), :db, Chain.data()) - - Map.put(context, :loader, loader) + if Application.get_env(:block_scout_web, Api.GraphQL)[:enabled] do + loader = Dataloader.add_source(Dataloader.new(), :db, Chain.data()) + + context + |> Map.put(:loader, loader) + |> Map.put(:api_enabled, true) + else + context + |> Map.put(:api_enabled, false) + end end def plugins do diff --git a/apps/block_scout_web/lib/block_scout_web/schema/scalars.ex b/apps/block_scout_web/lib/block_scout_web/graphql/schema/scalars.ex similarity index 96% rename from apps/block_scout_web/lib/block_scout_web/schema/scalars.ex rename to apps/block_scout_web/lib/block_scout_web/graphql/schema/scalars.ex index 51ebae097d4d..e74af83ba582 100644 --- a/apps/block_scout_web/lib/block_scout_web/schema/scalars.ex +++ b/apps/block_scout_web/lib/block_scout_web/graphql/schema/scalars.ex @@ -1,4 +1,4 @@ -defmodule BlockScoutWeb.Schema.Scalars do +defmodule BlockScoutWeb.GraphQL.Schema.Scalars do @moduledoc false use Absinthe.Schema.Notation @@ -6,7 +6,7 @@ defmodule BlockScoutWeb.Schema.Scalars do alias Explorer.Chain.{Data, Hash, Wei} alias Explorer.Chain.Hash.{Address, Full, Nonce} - import_types(BlockScoutWeb.Schema.Scalars.JSON) + import_types(BlockScoutWeb.GraphQL.Schema.Scalars.JSON) @desc """ The address (40 (hex) characters / 160 bits / 20 bytes) is derived from the public key (128 (hex) characters / diff --git a/apps/block_scout_web/lib/block_scout_web/schema/scalars/JSON.ex b/apps/block_scout_web/lib/block_scout_web/graphql/schema/scalars/JSON.ex similarity index 93% rename from apps/block_scout_web/lib/block_scout_web/schema/scalars/JSON.ex rename to apps/block_scout_web/lib/block_scout_web/graphql/schema/scalars/JSON.ex index 8b4ef285f594..530e2a01baa0 100644 --- a/apps/block_scout_web/lib/block_scout_web/schema/scalars/JSON.ex +++ b/apps/block_scout_web/lib/block_scout_web/graphql/schema/scalars/JSON.ex @@ -1,4 +1,4 @@ -defmodule BlockScoutWeb.Schema.Scalars.JSON do +defmodule BlockScoutWeb.GraphQL.Schema.Scalars.JSON do @moduledoc """ The JSON scalar type allows arbitrary JSON values to be passed in and out. """ diff --git a/apps/block_scout_web/lib/block_scout_web/schema/types.ex b/apps/block_scout_web/lib/block_scout_web/graphql/schema/types.ex similarity index 97% rename from apps/block_scout_web/lib/block_scout_web/schema/types.ex rename to apps/block_scout_web/lib/block_scout_web/graphql/schema/types.ex index d81f6eca5137..27bd81ae4fb0 100644 --- a/apps/block_scout_web/lib/block_scout_web/schema/types.ex +++ b/apps/block_scout_web/lib/block_scout_web/graphql/schema/types.ex @@ -1,4 +1,4 @@ -defmodule BlockScoutWeb.Schema.Types do +defmodule BlockScoutWeb.GraphQL.Schema.Types do @moduledoc false use Absinthe.Schema.Notation @@ -6,13 +6,13 @@ defmodule BlockScoutWeb.Schema.Types do import Absinthe.Resolution.Helpers - alias BlockScoutWeb.Resolvers.{ + alias BlockScoutWeb.GraphQL.Resolvers.{ InternalTransaction, Transaction } import_types(Absinthe.Type.Custom) - import_types(BlockScoutWeb.Schema.Scalars) + import_types(BlockScoutWeb.GraphQL.Schema.Scalars) connection(node_type: :transaction) connection(node_type: :internal_transaction) diff --git a/apps/block_scout_web/lib/block_scout_web/microservice_interfaces/transaction_interpretation.ex b/apps/block_scout_web/lib/block_scout_web/microservice_interfaces/transaction_interpretation.ex index d5e388cefa1c..4ea71d7a9e61 100644 --- a/apps/block_scout_web/lib/block_scout_web/microservice_interfaces/transaction_interpretation.ex +++ b/apps/block_scout_web/lib/block_scout_web/microservice_interfaces/transaction_interpretation.ex @@ -4,11 +4,12 @@ defmodule BlockScoutWeb.MicroserviceInterfaces.TransactionInterpretation do """ alias BlockScoutWeb.API.V2.{Helper, TokenView, TransactionView} + alias Ecto.Association.NotLoaded alias Explorer.Chain - alias Explorer.Chain.Transaction + alias Explorer.Chain.{Data, Log, TokenTransfer, Transaction} alias HTTPoison.Response - import Explorer.Utility.Microservice, only: [base_url: 2] + import Explorer.Utility.Microservice, only: [base_url: 2, check_enabled: 2] require Logger @@ -17,15 +18,18 @@ defmodule BlockScoutWeb.MicroserviceInterfaces.TransactionInterpretation do @api_true api?: true @items_limit 50 - @spec interpret(Transaction.t()) :: + @doc """ + Interpret transaction or user operation + """ + @spec interpret(Transaction.t() | map(), (Transaction.t() -> any()) | (map() -> any())) :: {{:error, :disabled | binary()}, integer()} | {:error, Jason.DecodeError.t()} - | {:ok, any} - def interpret(transaction) do + | {:ok, any()} + def interpret(transaction_or_map, request_builder \\ &prepare_request_body/1) do if enabled?() do url = interpret_url() - body = prepare_request_body(transaction) + body = request_builder.(transaction_or_map) http_post_request(url, body) else @@ -33,10 +37,33 @@ defmodule BlockScoutWeb.MicroserviceInterfaces.TransactionInterpretation do end end + @doc """ + Interpret user operation + """ + @spec interpret_user_operation(map()) :: + {{:error, :disabled | binary()}, integer()} + | {:error, Jason.DecodeError.t()} + | {:ok, any()} + def interpret_user_operation(user_operation) do + interpret(user_operation, &prepare_request_body_from_user_op/1) + end + + @doc """ + Build the request body as for the tx interpreter POST request. + """ + @spec get_request_body(Transaction.t()) :: map() def get_request_body(transaction) do prepare_request_body(transaction) end + @doc """ + Build the request body as for the tx interpreter POST request. + """ + @spec get_user_op_request_body(map()) :: map() + def get_user_op_request_body(user_op) do + prepare_request_body_from_user_op(user_op) + end + defp http_post_request(url, body) do headers = [{"Content-Type", "application/json"}] @@ -63,11 +90,7 @@ defmodule BlockScoutWeb.MicroserviceInterfaces.TransactionInterpretation do defp http_response_code({:ok, %Response{status_code: status_code}}), do: status_code defp http_response_code(_), do: 500 - defp config do - Application.get_env(:block_scout_web, __MODULE__) - end - - def enabled?, do: config()[:enabled] + def enabled?, do: check_enabled(:block_scout_web, __MODULE__) == :ok defp interpret_url do base_url(:block_scout_web, __MODULE__) <> "/transactions/summary" @@ -100,7 +123,7 @@ defmodule BlockScoutWeb.MicroserviceInterfaces.TransactionInterpretation do hash: transaction.hash, type: transaction.type, value: transaction.value, - method: TransactionView.method_name(transaction, decoded_input), + method: TransactionView.method_name(transaction, TransactionView.format_decoded_input(decoded_input)), status: transaction.status, actions: TransactionView.transaction_actions(transaction.transaction_actions), tx_types: TransactionView.tx_types(transaction), @@ -131,6 +154,51 @@ defmodule BlockScoutWeb.MicroserviceInterfaces.TransactionInterpretation do |> Enum.map(&TransactionView.prepare_token_transfer(&1, nil, decoded_input)) end + defp user_op_to_logs_and_token_transfers(user_op, decoded_input) do + log_options = + [ + necessity_by_association: %{ + [address: :names] => :optional, + [address: :smart_contract] => :optional, + address: :optional + }, + limit: @items_limit + ] + |> Keyword.merge(@api_true) + + logs = Log.user_op_to_logs(user_op, log_options) + + decoded_logs = TransactionView.decode_logs(logs, false) + + prepared_logs = + logs + |> Enum.zip(decoded_logs) + |> Enum.map(fn {log, decoded_log} -> + TransactionView.prepare_log(log, user_op["transaction_hash"], decoded_log, true) + end) + + token_transfer_options = + [ + necessity_by_association: %{ + [from_address: :smart_contract] => :optional, + [to_address: :smart_contract] => :optional, + [from_address: :names] => :optional, + [to_address: :names] => :optional, + :token => :optional + } + ] + |> Keyword.merge(@api_true) + + prepared_token_transfers = + logs + |> TokenTransfer.logs_to_token_transfers(token_transfer_options) + |> Chain.flat_1155_batch_token_transfers() + |> Enum.take(@items_limit) + |> Enum.map(&TransactionView.prepare_token_transfer(&1, nil, decoded_input)) + + {prepared_logs, prepared_token_transfers} + end + defp prepare_logs(transaction) do full_options = [ @@ -210,4 +278,65 @@ defmodule BlockScoutWeb.MicroserviceInterfaces.TransactionInterpretation do address.hash, true ) + + defp prepare_request_body_from_user_op(user_op) do + user_op_hash = user_op["hash"] + user_op_call_data = user_op["execute_call_data"] || user_op["call_data"] + user_op_from = user_op["sender"] + user_op_to = user_op["execute_target"] || user_op["sender"] + + {mock_tx, decoded_input, decoded_input_json} = decode_user_op_calldata(user_op_hash, user_op_call_data) + + {prepared_logs, prepared_token_transfers} = user_op_to_logs_and_token_transfers(user_op, decoded_input) + + {:ok, from_address_hash} = Chain.string_to_address_hash(user_op_from) + + {:ok, to_address_hash} = Chain.string_to_address_hash(user_op_to) + + from_address = Chain.hash_to_address(from_address_hash, []) + + to_address = Chain.hash_to_address(to_address_hash, []) + + %{ + data: %{ + to: Helper.address_with_info(nil, to_address, to_address_hash, true), + from: Helper.address_with_info(nil, from_address, from_address_hash, true), + hash: user_op_hash, + type: 0, + value: "0", + method: TransactionView.method_name(mock_tx, TransactionView.format_decoded_input(decoded_input), true), + status: user_op["status"], + actions: [], + tx_types: [], + raw_input: user_op_call_data, + decoded_input: decoded_input_json, + token_transfers: prepared_token_transfers + }, + logs_data: %{items: prepared_logs} + } + end + + @doc """ + Decodes user_op["call_data"] and return {mock_tx, decoded_input, decoded_input_json} + """ + @spec decode_user_op_calldata(binary(), binary() | nil) :: {Transaction.t(), tuple(), map()} | {nil, nil, nil} + def decode_user_op_calldata(_user_op_hash, nil), do: {nil, nil, nil} + + def decode_user_op_calldata(user_op_hash, call_data) do + {:ok, input} = Data.cast(call_data) + + {:ok, op_hash} = Chain.string_to_transaction_hash(user_op_hash) + + mock_tx = %Transaction{ + to_address: %NotLoaded{}, + input: input, + hash: op_hash + } + + skip_sig_provider? = false + + {decoded_input, _abi_acc, _methods_acc} = Transaction.decoded_input_data(mock_tx, skip_sig_provider?, @api_true) + + {mock_tx, decoded_input, decoded_input |> TransactionView.format_decoded_input() |> TransactionView.decoded_input()} + end end diff --git a/apps/block_scout_web/lib/block_scout_web/models/transaction_state_helper.ex b/apps/block_scout_web/lib/block_scout_web/models/transaction_state_helper.ex index e37d94adfab9..1502e9b2148c 100644 --- a/apps/block_scout_web/lib/block_scout_web/models/transaction_state_helper.ex +++ b/apps/block_scout_web/lib/block_scout_web/models/transaction_state_helper.ex @@ -10,7 +10,8 @@ defmodule BlockScoutWeb.Models.TransactionStateHelper do alias Explorer.{Chain, PagingOptions} alias Explorer.Chain.{Block, BlockNumberHelper, Transaction, Wei} alias Explorer.Chain.Cache.StateChanges - alias Indexer.Fetcher.{CoinBalanceOnDemand, TokenBalanceOnDemand} + alias Indexer.Fetcher.OnDemand.CoinBalance, as: CoinBalanceOnDemand + alias Indexer.Fetcher.OnDemand.TokenBalance, as: TokenBalanceOnDemand {:ok, burn_address_hash} = Chain.string_to_address_hash(burn_address_hash_string()) @burn_address_hash burn_address_hash diff --git a/apps/block_scout_web/lib/block_scout_web/notifier.ex b/apps/block_scout_web/lib/block_scout_web/notifier.ex index b9e5df6ca61d..724c1e7e5bc1 100644 --- a/apps/block_scout_web/lib/block_scout_web/notifier.ex +++ b/apps/block_scout_web/lib/block_scout_web/notifier.ex @@ -105,7 +105,7 @@ defmodule BlockScoutWeb.Notifier do end def handle_event({:chain_event, :blocks, :realtime, blocks}) do - last_broadcasted_block_number = Helper.fetch_from_cache(:number, :last_broadcasted_block) + last_broadcasted_block_number = Helper.fetch_from_ets_cache(:number, :last_broadcasted_block) blocks |> Enum.sort_by(& &1.number, :asc) @@ -172,7 +172,14 @@ defmodule BlockScoutWeb.Notifier do |> Enum.map( &(&1 |> Repo.preload( - DenormalizationHelper.extend_transaction_preload([:from_address, :to_address, :token, :transaction]) + DenormalizationHelper.extend_transaction_preload([ + :token, + :transaction, + from_address: :smart_contract, + to_address: :smart_contract, + from_address: :names, + to_address: :names + ]) )) ) @@ -193,7 +200,16 @@ defmodule BlockScoutWeb.Notifier do end def handle_event({:chain_event, :transactions, :realtime, transactions}) do - base_preloads = [:block, created_contract_address: :names, from_address: :names, to_address: :names] + base_preloads = [ + :block, + created_contract_address: :names, + from_address: :names, + to_address: :names, + created_contract_address: :smart_contract, + from_address: :smart_contract, + to_address: :smart_contract + ] + preloads = if API_V2.enabled?(), do: [:token_transfers | base_preloads], else: base_preloads transactions @@ -228,10 +244,18 @@ defmodule BlockScoutWeb.Notifier do Endpoint.broadcast("tokens:#{to_string(contract_address_hash)}", "token_total_supply", %{token: token}) end + def handle_event({:chain_event, :fetched_bytecode, :on_demand, [address_hash, fetched_bytecode]}) do + Endpoint.broadcast("addresses:#{to_string(address_hash)}", "fetched_bytecode", %{fetched_bytecode: fetched_bytecode}) + end + def handle_event({:chain_event, :changed_bytecode, :on_demand, [address_hash]}) do Endpoint.broadcast("addresses:#{to_string(address_hash)}", "changed_bytecode", %{}) end + def handle_event({:chain_event, :optimism_deposits, :realtime, deposits}) do + broadcast_optimism_deposits(deposits, "optimism_deposits:new_deposits", "deposits") + end + def handle_event({:chain_event, :smart_contract_was_verified = event, :on_demand, [address_hash]}) do broadcast_automatic_verification_events(event, address_hash) end @@ -323,7 +347,7 @@ defmodule BlockScoutWeb.Notifier do defp schedule_broadcasting(block) do :timer.sleep(@check_broadcast_sequence_period) - last_broadcasted_block_number = Helper.fetch_from_cache(:number, :last_broadcasted_block) + last_broadcasted_block_number = Helper.fetch_from_ets_cache(:number, :last_broadcasted_block) if last_broadcasted_block_number == BlockNumberHelper.previous_block_number(block.number) do broadcast_block(block) @@ -400,6 +424,10 @@ defmodule BlockScoutWeb.Notifier do end end + defp broadcast_optimism_deposits(deposits, deposit_channel, event) do + Endpoint.broadcast(deposit_channel, event, %{deposits: deposits}) + end + defp broadcast_transactions_websocket_v2(transactions) do pending_transactions = Enum.filter(transactions, fn @@ -425,7 +453,7 @@ defmodule BlockScoutWeb.Notifier do end defp broadcast_transactions_websocket_v2_inner(transactions, default_channel, event) do - if Enum.count(transactions) > 0 do + if not Enum.empty?(transactions) do Endpoint.broadcast(default_channel, event, %{ transactions: transactions }) diff --git a/apps/block_scout_web/lib/block_scout_web/paging_helper.ex b/apps/block_scout_web/lib/block_scout_web/paging_helper.ex index 1a054b091e72..d3e11c498de8 100644 --- a/apps/block_scout_web/lib/block_scout_web/paging_helper.ex +++ b/apps/block_scout_web/lib/block_scout_web/paging_helper.ex @@ -3,6 +3,7 @@ defmodule BlockScoutWeb.PagingHelper do Helper for fetching filters and other url query parameters """ import Explorer.Chain, only: [string_to_transaction_hash: 1] + alias Explorer.Chain.Stability.Validator, as: ValidatorStability alias Explorer.Chain.Transaction alias Explorer.{Helper, PagingOptions, SortingHelper} @@ -11,7 +12,7 @@ defmodule BlockScoutWeb.PagingHelper do @allowed_filter_labels ["validated", "pending"] case Application.compile_env(:explorer, :chain_type) do - "ethereum" -> + :ethereum -> @allowed_type_labels [ "coin_transfer", "contract_call", @@ -31,9 +32,12 @@ defmodule BlockScoutWeb.PagingHelper do ] end - @allowed_token_transfer_type_labels ["ERC-20", "ERC-721", "ERC-1155"] - @allowed_nft_token_type_labels ["ERC-721", "ERC-1155"] + @allowed_token_transfer_type_labels ["ERC-20", "ERC-721", "ERC-1155", "ERC-404"] + @allowed_nft_type_labels ["ERC-721", "ERC-1155", "ERC-404"] @allowed_chain_id [1, 56, 99] + @allowed_stability_validators_states ["active", "probation", "inactive"] + + def allowed_stability_validators_states, do: @allowed_stability_validators_states def paging_options(%{"block_number" => block_number_string, "index" => index_string}, [:validated | _]) do with {block_number, ""} <- Integer.parse(block_number_string), @@ -57,6 +61,13 @@ defmodule BlockScoutWeb.PagingHelper do def paging_options(_params, _filter), do: [paging_options: @default_paging_options] + @spec stability_validators_state_options(map()) :: [{:state, list()}, ...] + def stability_validators_state_options(%{"state_filter" => state}) do + [state: filters_to_list(state, @allowed_stability_validators_states, :downcase)] + end + + def stability_validators_state_options(_), do: [state: []] + @spec token_transfers_types_options(map()) :: [{:token_type, list}] def token_transfers_types_options(%{"type" => filters}) do [ @@ -69,16 +80,18 @@ defmodule BlockScoutWeb.PagingHelper do @doc """ Parse 'type' query parameter from request option map """ - @spec nft_token_types_options(map()) :: [{:token_type, list}] - def nft_token_types_options(%{"type" => filters}) do + @spec nft_types_options(map()) :: [{:token_type, list}] + def nft_types_options(%{"type" => filters}) do [ - token_type: filters_to_list(filters, @allowed_nft_token_type_labels) + token_type: filters_to_list(filters, @allowed_nft_type_labels) ] end - def nft_token_types_options(_), do: [token_type: []] + def nft_types_options(_), do: [token_type: []] - defp filters_to_list(filters, allowed), do: filters |> String.upcase() |> parse_filter(allowed) + defp filters_to_list(filters, allowed, variant \\ :upcase) + defp filters_to_list(filters, allowed, :downcase), do: filters |> String.downcase() |> parse_filter(allowed) + defp filters_to_list(filters, allowed, :upcase), do: filters |> String.upcase() |> parse_filter(allowed) # sobelow_skip ["DOS.StringToAtom"] def filter_options(%{"filter" => filter}, fallback) do @@ -188,7 +201,8 @@ defmodule BlockScoutWeb.PagingHelper do "filter", "q", "sort", - "order" + "order", + "state_filter" ]) end @@ -267,4 +281,26 @@ defmodule BlockScoutWeb.PagingHelper do do: [{:dynamic, :fee, :desc_nulls_last, Transaction.dynamic_fee()}] defp do_address_transaction_sorting(_, _), do: [] + + @spec validators_stability_sorting(%{required(String.t()) => String.t()}) :: [ + {:sorting, SortingHelper.sorting_params()} + ] + def validators_stability_sorting(%{"sort" => sort_field, "order" => order}) do + [sorting: do_validators_stability_sorting(sort_field, order)] + end + + def validators_stability_sorting(_), do: [] + + defp do_validators_stability_sorting("state", "asc"), do: [asc_nulls_first: :state] + defp do_validators_stability_sorting("state", "desc"), do: [desc_nulls_last: :state] + defp do_validators_stability_sorting("address_hash", "asc"), do: [asc_nulls_first: :address_hash] + defp do_validators_stability_sorting("address_hash", "desc"), do: [desc_nulls_last: :address_hash] + + defp do_validators_stability_sorting("blocks_validated", "asc"), + do: [{:dynamic, :blocks_validated, :asc_nulls_first, ValidatorStability.dynamic_validated_blocks()}] + + defp do_validators_stability_sorting("blocks_validated", "desc"), + do: [{:dynamic, :blocks_validated, :desc_nulls_last, ValidatorStability.dynamic_validated_blocks()}] + + defp do_validators_stability_sorting(_, _), do: [] end diff --git a/apps/block_scout_web/lib/block_scout_web/plug/graphql.ex b/apps/block_scout_web/lib/block_scout_web/plug/graphql.ex index e46cbed1badd..6e2a0c5bea22 100644 --- a/apps/block_scout_web/lib/block_scout_web/plug/graphql.ex +++ b/apps/block_scout_web/lib/block_scout_web/plug/graphql.ex @@ -2,10 +2,9 @@ defmodule BlockScoutWeb.Plug.GraphQL do @moduledoc """ Default query for GraphiQL interface. """ - @default_transaction_hash "0x69e3923eef50eada197c3336d546936d0c994211492c9f947a24c02827568f9f" def default_query do - transaction_hash = System.get_env("GRAPHIQL_TRANSACTION") || @default_transaction_hash + transaction_hash = Application.get_env(:block_scout_web, Api.GraphQL)[:default_transaction_hash] "{transaction(hash: \"#{transaction_hash}\") { hash, blockNumber, value, gasUsed }}" end diff --git a/apps/block_scout_web/lib/block_scout_web/plug/rate_limit.ex b/apps/block_scout_web/lib/block_scout_web/plug/rate_limit.ex index c7e22f4e9cfb..5f6de5f4fef1 100644 --- a/apps/block_scout_web/lib/block_scout_web/plug/rate_limit.ex +++ b/apps/block_scout_web/lib/block_scout_web/plug/rate_limit.ex @@ -6,6 +6,19 @@ defmodule BlockScoutWeb.Plug.RateLimit do def init(opts), do: opts + def call(conn, graphql?: true) do + case AccessHelper.check_rate_limit(conn, graphql?: true) do + :ok -> + conn + + true -> + conn + + _ -> + AccessHelper.handle_rate_limit_deny(conn, true) + end + end + def call(conn, _opts) do case AccessHelper.check_rate_limit(conn) do :ok -> diff --git a/apps/block_scout_web/lib/block_scout_web/prometheus/instrumenter.ex b/apps/block_scout_web/lib/block_scout_web/prometheus/instrumenter.ex index a782d433bccc..d329c2751a28 100644 --- a/apps/block_scout_web/lib/block_scout_web/prometheus/instrumenter.ex +++ b/apps/block_scout_web/lib/block_scout_web/prometheus/instrumenter.ex @@ -1,16 +1,17 @@ defmodule BlockScoutWeb.Prometheus.Instrumenter do @moduledoc """ - Phoenix request metrics for `Prometheus`. + BlockScoutWeb metrics for `Prometheus`. """ - @dialyzer {:no_match, - [ - phoenix_channel_join: 3, - phoenix_channel_receive: 3, - phoenix_controller_call: 3, - phoenix_controller_render: 3, - setup: 0 - ]} + use Prometheus.Metric - use Prometheus.PhoenixInstrumenter + @gauge [ + name: :event_handler_queue_length, + labels: [:handler], + help: "Number of events in event handlers queue" + ] + + def event_handler_queue_length(handler, length) do + Gauge.set([name: :event_handler_queue_length, labels: [handler]], length) + end end diff --git a/apps/block_scout_web/lib/block_scout_web/prometheus/phoenix_instrumenter.ex b/apps/block_scout_web/lib/block_scout_web/prometheus/phoenix_instrumenter.ex new file mode 100644 index 000000000000..5b25969f3f1b --- /dev/null +++ b/apps/block_scout_web/lib/block_scout_web/prometheus/phoenix_instrumenter.ex @@ -0,0 +1,16 @@ +defmodule BlockScoutWeb.Prometheus.PhoenixInstrumenter do + @moduledoc """ + Phoenix request metrics for `Prometheus`. + """ + + @dialyzer {:no_match, + [ + phoenix_channel_join: 3, + phoenix_channel_receive: 3, + phoenix_controller_call: 3, + phoenix_controller_render: 3, + setup: 0 + ]} + + use Prometheus.PhoenixInstrumenter +end diff --git a/apps/block_scout_web/lib/block_scout_web/realtime_event_handler.ex b/apps/block_scout_web/lib/block_scout_web/realtime_event_handler.ex index 1fedc2dc3dba..dc956b249f74 100644 --- a/apps/block_scout_web/lib/block_scout_web/realtime_event_handler.ex +++ b/apps/block_scout_web/lib/block_scout_web/realtime_event_handler.ex @@ -19,6 +19,7 @@ defmodule BlockScoutWeb.RealtimeEventHandler do Subscriber.to(:block_rewards, :realtime) Subscriber.to(:internal_transactions, :realtime) Subscriber.to(:internal_transactions, :on_demand) + Subscriber.to(:optimism_deposits, :realtime) Subscriber.to(:token_transfers, :realtime) Subscriber.to(:addresses, :on_demand) Subscriber.to(:address_coin_balances, :on_demand) @@ -26,6 +27,7 @@ defmodule BlockScoutWeb.RealtimeEventHandler do Subscriber.to(:address_token_balances, :on_demand) Subscriber.to(:token_total_supply, :on_demand) Subscriber.to(:changed_bytecode, :on_demand) + Subscriber.to(:fetched_bytecode, :on_demand) Subscriber.to(:eth_bytecode_db_lookup_started, :on_demand) Subscriber.to(:zkevm_confirmed_batches, :realtime) # Does not come from the indexer diff --git a/apps/block_scout_web/lib/block_scout_web/resolvers/address.ex b/apps/block_scout_web/lib/block_scout_web/resolvers/address.ex deleted file mode 100644 index dda5aaf792cd..000000000000 --- a/apps/block_scout_web/lib/block_scout_web/resolvers/address.ex +++ /dev/null @@ -1,19 +0,0 @@ -defmodule BlockScoutWeb.Resolvers.Address do - @moduledoc false - - alias Explorer.Chain - - def get_by(_, %{hashes: hashes}, _) do - case Chain.hashes_to_addresses(hashes) do - [] -> {:error, "Addresses not found."} - result -> {:ok, result} - end - end - - def get_by(_, %{hash: hash}, _) do - case Chain.hash_to_address(hash) do - {:error, :not_found} -> {:error, "Address not found."} - {:ok, _} = result -> result - end - end -end diff --git a/apps/block_scout_web/lib/block_scout_web/resolvers/block.ex b/apps/block_scout_web/lib/block_scout_web/resolvers/block.ex deleted file mode 100644 index a970f7c4ef91..000000000000 --- a/apps/block_scout_web/lib/block_scout_web/resolvers/block.ex +++ /dev/null @@ -1,12 +0,0 @@ -defmodule BlockScoutWeb.Resolvers.Block do - @moduledoc false - - alias Explorer.Chain - - def get_by(_, %{number: number}, _) do - case Chain.number_to_block(number) do - {:ok, _} = result -> result - {:error, :not_found} -> {:error, "Block number #{number} was not found."} - end - end -end diff --git a/apps/block_scout_web/lib/block_scout_web/resolvers/internal_transaction.ex b/apps/block_scout_web/lib/block_scout_web/resolvers/internal_transaction.ex deleted file mode 100644 index 08f3ca45ce67..000000000000 --- a/apps/block_scout_web/lib/block_scout_web/resolvers/internal_transaction.ex +++ /dev/null @@ -1,23 +0,0 @@ -defmodule BlockScoutWeb.Resolvers.InternalTransaction do - @moduledoc false - - alias Absinthe.Relay.Connection - alias Explorer.Chain.Transaction - alias Explorer.{GraphQL, Repo} - - def get_by(%{transaction_hash: _, index: _} = args) do - GraphQL.get_internal_transaction(args) - end - - def get_by(%Transaction{} = transaction, args, _) do - transaction - |> GraphQL.transaction_to_internal_transactions_query() - |> Connection.from_query(&Repo.all/1, args, options(args)) - end - - defp options(%{before: _}), do: [] - - defp options(%{count: count}), do: [count: count] - - defp options(_), do: [] -end diff --git a/apps/block_scout_web/lib/block_scout_web/resolvers/token_transfer.ex b/apps/block_scout_web/lib/block_scout_web/resolvers/token_transfer.ex deleted file mode 100644 index 38b8b3f4acaf..000000000000 --- a/apps/block_scout_web/lib/block_scout_web/resolvers/token_transfer.ex +++ /dev/null @@ -1,24 +0,0 @@ -defmodule BlockScoutWeb.Resolvers.TokenTransfer do - @moduledoc false - - alias Absinthe.Relay.Connection - alias Explorer.{GraphQL, Repo} - - def get_by(%{transaction_hash: _, log_index: _} = args) do - GraphQL.get_token_transfer(args) - end - - def get_by(_, %{token_contract_address_hash: token_contract_address_hash} = args, _) do - connection_args = Map.take(args, [:after, :before, :first, :last]) - - token_contract_address_hash - |> GraphQL.list_token_transfers_query() - |> Connection.from_query(&Repo.all/1, connection_args, options(args)) - end - - defp options(%{before: _}), do: [] - - defp options(%{count: count}), do: [count: count] - - defp options(_), do: [] -end diff --git a/apps/block_scout_web/lib/block_scout_web/resolvers/transaction.ex b/apps/block_scout_web/lib/block_scout_web/resolvers/transaction.ex deleted file mode 100644 index adfe1b793d68..000000000000 --- a/apps/block_scout_web/lib/block_scout_web/resolvers/transaction.ex +++ /dev/null @@ -1,28 +0,0 @@ -defmodule BlockScoutWeb.Resolvers.Transaction do - @moduledoc false - - alias Absinthe.Relay.Connection - alias Explorer.{Chain, GraphQL, Repo} - alias Explorer.Chain.Address - - def get_by(_, %{hash: hash}, _) do - case Chain.hash_to_transaction(hash) do - {:ok, transaction} -> {:ok, transaction} - {:error, :not_found} -> {:error, "Transaction not found."} - end - end - - def get_by(%Address{hash: address_hash}, args, _) do - connection_args = Map.take(args, [:after, :before, :first, :last]) - - address_hash - |> GraphQL.address_to_transactions_query(args.order) - |> Connection.from_query(&Repo.all/1, connection_args, options(args)) - end - - defp options(%{before: _}), do: [] - - defp options(%{count: count}), do: [count: count] - - defp options(_), do: [] -end diff --git a/apps/block_scout_web/lib/block_scout_web/router.ex b/apps/block_scout_web/lib/block_scout_web/router.ex index b56899ce80f3..86da395f13cf 100644 --- a/apps/block_scout_web/lib/block_scout_web/router.ex +++ b/apps/block_scout_web/lib/block_scout_web/router.ex @@ -1,7 +1,7 @@ defmodule BlockScoutWeb.Router do use BlockScoutWeb, :router - alias BlockScoutWeb.Plug.GraphQL + alias BlockScoutWeb.Plug.{GraphQL, RateLimit} alias BlockScoutWeb.{ApiRouter, WebRouter} if Application.compile_env(:block_scout_web, :admin_panel_enabled) do @@ -22,25 +22,25 @@ defmodule BlockScoutWeb.Router do plug(:accepts, ["json"]) end + pipeline :api_v1_graphql do + plug(BlockScoutWeb.Plug.Logger, application: :api) + plug(:accepts, ["json"]) + plug(RateLimit, graphql?: true) + end + forward("/api", ApiRouter) - if Application.compile_env(:block_scout_web, ApiRouter)[:reading_enabled] do - # Needs to be 200 to support the schema introspection for graphiql - @max_complexity 200 + scope "/graphiql" do + pipe_through(:api_v1_graphql) - forward("/graphiql", Absinthe.Plug.GraphiQL, - schema: BlockScoutWeb.Schema, - interface: :advanced, - default_query: GraphQL.default_query(), - socket: BlockScoutWeb.UserSocket, - analyze_complexity: true, - max_complexity: @max_complexity - ) - else - scope "/", BlockScoutWeb do - pipe_through(:browser) - get("/api-docs", PageNotFoundController, :index) - get("/eth-rpc-api-docs", PageNotFoundController, :index) + if Application.compile_env(:block_scout_web, Api.GraphQL)[:enabled] && + Application.compile_env(:block_scout_web, ApiRouter)[:reading_enabled] do + forward("/", Absinthe.Plug.GraphiQL, + schema: BlockScoutWeb.GraphQL.Schema, + interface: :advanced, + default_query: GraphQL.default_query(), + socket: BlockScoutWeb.UserSocket + ) end end @@ -49,8 +49,14 @@ defmodule BlockScoutWeb.Router do get("/robots.txt", RobotsController, :robots) get("/sitemap.xml", RobotsController, :sitemap) - get("/api-docs", APIDocsController, :index) - get("/eth-rpc-api-docs", APIDocsController, :eth_rpc) + + if Application.compile_env(:block_scout_web, ApiRouter)[:reading_enabled] do + get("/api-docs", APIDocsController, :index) + get("/eth-rpc-api-docs", APIDocsController, :eth_rpc) + else + get("/api-docs", PageNotFoundController, :index) + get("/eth-rpc-api-docs", PageNotFoundController, :index) + end end scope "/verify_smart_contract" do diff --git a/apps/block_scout_web/lib/block_scout_web/templates/address/_link.html.eex b/apps/block_scout_web/lib/block_scout_web/templates/address/_link.html.eex index 275a8f058dc1..d28be9224205 100644 --- a/apps/block_scout_web/lib/block_scout_web/templates/address/_link.html.eex +++ b/apps/block_scout_web/lib/block_scout_web/templates/address/_link.html.eex @@ -1,7 +1,7 @@ <%= if @address do %> <%= if assigns[:show_full_hash] do %> <%= if name = if assigns[:ignore_implementation_name], do: primary_name(@address), else: implementation_name(@address) || primary_name(@address) do %> - <%= name %> | + <%= name %> | <% end %> <%= link to: address_path(BlockScoutWeb.Endpoint, :show, @address), "data-test": "address_hash_link", class: assigns[:class] do %> <%= @address %> diff --git a/apps/block_scout_web/lib/block_scout_web/templates/address/overview.html.eex b/apps/block_scout_web/lib/block_scout_web/templates/address/overview.html.eex index 2b8ba6e6aa23..005508956e65 100644 --- a/apps/block_scout_web/lib/block_scout_web/templates/address/overview.html.eex +++ b/apps/block_scout_web/lib/block_scout_web/templates/address/overview.html.eex @@ -62,7 +62,7 @@ @address.hash), "data-test": "token_hash_link" - ) + ) %> @@ -137,7 +137,7 @@ (if name, do: name <> " | " <> implementation_address, else: implementation_address), to: address_path(@conn, :show, implementation_address), class: "contract-address" - ) + ) %> @@ -160,7 +160,7 @@ data-placement="top" data-toggle="tooltip" data-html="true" - title='<%= "@ " <> usd_value <> "/" <> Explorer.coin_name() %>' + title='<%= "@ " <> usd_value <> "/" <> Explorer.coin_name() %>' > ) @@ -288,4 +288,4 @@ <%= render BlockScoutWeb.CommonComponentsView, "_modal_qr_code.html", qr_code: qr_code(@address), title: @address %> -<%= render BlockScoutWeb.Advertisement.BannersAdView, "_banner_728.html", conn: @conn %> +<%= render BlockScoutWeb.Advertisement.BannersAdView, "_banner_728.html", conn: @conn %> diff --git a/apps/block_scout_web/lib/block_scout_web/templates/address_token/overview.html.eex b/apps/block_scout_web/lib/block_scout_web/templates/address_token/overview.html.eex index 6f922375b973..3afb3d97a3f4 100644 --- a/apps/block_scout_web/lib/block_scout_web/templates/address_token/overview.html.eex +++ b/apps/block_scout_web/lib/block_scout_web/templates/address_token/overview.html.eex @@ -14,14 +14,14 @@ _ -> Decimal.new(0) end %> -<% data_usd_exchange_rate = +<% data_usd_exchange_rate = unless AddressView.empty_exchange_rate?(@exchange_rate) do "data-usd-exchange-rate='#{@exchange_rate.usd_value}' data-raw-usd-value='#{raw_usd_value}'" end %> <% native_coin_balance_token = AddressView.balance(@address) %> -<% native_coin_balance_usd = +<% native_coin_balance_usd = if AddressView.empty_exchange_rate?(@exchange_rate) do nil else @@ -32,7 +32,7 @@ " end %> -<% native_coin_balance = +<% native_coin_balance = if native_coin_balance_usd do native_coin_balance_usd <> " | " <> native_coin_balance_token else @@ -70,4 +70,4 @@ classes: ["fs-14"], container_classes: ["d-none"] %> - \ No newline at end of file + diff --git a/apps/block_scout_web/lib/block_scout_web/templates/advertisement/banners_ad/_banner_728.html.eex b/apps/block_scout_web/lib/block_scout_web/templates/advertisement/banners_ad/_banner_728.html.eex index 20c47d29fe4b..550a85799498 100644 --- a/apps/block_scout_web/lib/block_scout_web/templates/advertisement/banners_ad/_banner_728.html.eex +++ b/apps/block_scout_web/lib/block_scout_web/templates/advertisement/banners_ad/_banner_728.html.eex @@ -3,4 +3,4 @@ - \ No newline at end of file + diff --git a/apps/block_scout_web/lib/block_scout_web/templates/advertisement/text_ad/index.html.eex b/apps/block_scout_web/lib/block_scout_web/templates/advertisement/text_ad/index.html.eex index c8dc85c5621d..66eedb9a02f9 100644 --- a/apps/block_scout_web/lib/block_scout_web/templates/advertisement/text_ad/index.html.eex +++ b/apps/block_scout_web/lib/block_scout_web/templates/advertisement/text_ad/index.html.eex @@ -1,4 +1,4 @@ \ No newline at end of file + diff --git a/apps/block_scout_web/lib/block_scout_web/templates/block/_tile.html.eex b/apps/block_scout_web/lib/block_scout_web/templates/block/_tile.html.eex index 452c73a3feb0..419ac616db73 100644 --- a/apps/block_scout_web/lib/block_scout_web/templates/block/_tile.html.eex +++ b/apps/block_scout_web/lib/block_scout_web/templates/block/_tile.html.eex @@ -33,7 +33,7 @@ <%= Cldr.Unit.new!(:byte, @block.size) |> cldr_unit_to_string!() %> <% end %> - + <%= if !Application.get_env(:block_scout_web, :hide_block_miner) do %>
diff --git a/apps/block_scout_web/lib/block_scout_web/templates/block_transaction/404.html.eex b/apps/block_scout_web/lib/block_scout_web/templates/block_transaction/404.html.eex index 5f87d8debbf5..84fe3df3aa39 100644 --- a/apps/block_scout_web/lib/block_scout_web/templates/block_transaction/404.html.eex +++ b/apps/block_scout_web/lib/block_scout_web/templates/block_transaction/404.html.eex @@ -10,4 +10,4 @@
- \ No newline at end of file + diff --git a/apps/block_scout_web/lib/block_scout_web/templates/chain/show.html.eex b/apps/block_scout_web/lib/block_scout_web/templates/chain/show.html.eex index 33b1995cfa0f..189955032356 100644 --- a/apps/block_scout_web/lib/block_scout_web/templates/chain/show.html.eex +++ b/apps/block_scout_web/lib/block_scout_web/templates/chain/show.html.eex @@ -92,18 +92,20 @@
- <%= case @average_block_time do %> - <% {:error, :disabled} -> %> - <%= nil %> - <% average_block_time -> %> -
- - <%= gettext "Average block time" %> - - - <%= Timex.format_duration(average_block_time, Explorer.Counters.AverageBlockTimeDurationFormat) %> - -
+ <%= unless Application.get_env(:explorer, :chain_type) == :optimism do %> + <%= case @average_block_time do %> + <% {:error, :disabled} -> %> + <%= nil %> + <% average_block_time -> %> +
+ + <%= gettext "Average block time" %> + + + <%= Timex.format_duration(average_block_time, Explorer.Counters.AverageBlockTimeDurationFormat) %> + +
+ <% end %> <% end %>
@@ -172,7 +174,7 @@ diff --git a/apps/block_scout_web/lib/block_scout_web/templates/common_components/_btn_copy.html.eex b/apps/block_scout_web/lib/block_scout_web/templates/common_components/_btn_copy.html.eex index d36e97feccb7..135fe488e534 100644 --- a/apps/block_scout_web/lib/block_scout_web/templates/common_components/_btn_copy.html.eex +++ b/apps/block_scout_web/lib/block_scout_web/templates/common_components/_btn_copy.html.eex @@ -11,4 +11,4 @@ - \ No newline at end of file + diff --git a/apps/block_scout_web/lib/block_scout_web/templates/form/_tag.html.eex b/apps/block_scout_web/lib/block_scout_web/templates/form/_tag.html.eex index 54f032df05f8..962284ff61fe 100644 --- a/apps/block_scout_web/lib/block_scout_web/templates/form/_tag.html.eex +++ b/apps/block_scout_web/lib/block_scout_web/templates/form/_tag.html.eex @@ -1,3 +1,3 @@
"> <%= @text %> -
\ No newline at end of file +
diff --git a/apps/block_scout_web/lib/block_scout_web/templates/internal_transaction/_tile.html.eex b/apps/block_scout_web/lib/block_scout_web/templates/internal_transaction/_tile.html.eex index 27ede917dd8a..3c23ba78c6fa 100644 --- a/apps/block_scout_web/lib/block_scout_web/templates/internal_transaction/_tile.html.eex +++ b/apps/block_scout_web/lib/block_scout_web/templates/internal_transaction/_tile.html.eex @@ -33,7 +33,7 @@ to: block_path(BlockScoutWeb.Endpoint, :show, @internal_transaction.block_number) ) %> - + <%= if assigns[:current_address] do %> <%= if assigns[:current_address].hash == @internal_transaction.from_address_hash do %> diff --git a/apps/block_scout_web/lib/block_scout_web/templates/layout/_topnav.html.eex b/apps/block_scout_web/lib/block_scout_web/templates/layout/_topnav.html.eex index 1f8707d57f69..eb7342cf9319 100644 --- a/apps/block_scout_web/lib/block_scout_web/templates/layout/_topnav.html.eex +++ b/apps/block_scout_web/lib/block_scout_web/templates/layout/_topnav.html.eex @@ -83,7 +83,7 @@ <%= gettext("Tokens") %> -