diff --git a/CHANGELOG.md b/CHANGELOG.md index 3906f58..039232e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,30 @@ # Changelog Changes to the project will be tracked in this file via the date of change. +## 2024-05-30 +- **Improved Project Structure**: Strelka UI backend now runs as a package. +- **Enhanced Metadata**: Structured client metadata added to Strelka events. +- **Encryption Status Indicators**: Added icons and tooltips for decryption success/failure in `seven_zip`, `rar`, and `encrypted_zip` scanners. +- **Mimetype/YARA Accuracy**: Refactored handling to show all mimetypes and YARA hits. +- **Edge Styling Enhancements**: Conditional edge styling and interactive highlights. +- **Scan Source Edge Addition**: Added source scan information for parent-child relationships. +- **Tooltips for Checkboxes**: Descriptive tooltips added for checkboxes. +- **Human Readable Text Option**: Toggle view for `string_text` between human-readable form and array form. +- **Background for Image**: Added a visual background stage for images. + +## 2024-03-29 +- Adding unencrypted VirusTotal submission support +- Update dependency (Black) + +## 2024-03-20 +- Dependency updates + +## 2024-03-04 +- Adding TLSH Card support + +## 2024-02-02 +- Adding QR Card support + ## 2024-01-17 - Bug fix for Visual Basic card where page fails to load if data does not exist for a section. diff --git a/Dockerfile b/Dockerfile index 776eed3..cc9f668 100644 --- a/Dockerfile +++ b/Dockerfile @@ -2,6 +2,10 @@ FROM node:16-slim AS UI_BUILDER # We are using a multi-stage build as we require node for # building react. +# Copy package.json and package-lock.json into the builder. +# Copying just these files first allows us to take advantage +# of cached Docker layers. + # Define UI build arguments. ARG REACT_APP_SEARCH_NAME ARG REACT_APP_SEARCH_URL @@ -10,9 +14,6 @@ ARG REACT_APP_SEARCH_URL ENV REACT_APP_SEARCH_NAME=$REACT_APP_SEARCH_NAME ENV REACT_APP_SEARCH_URL=$REACT_APP_SEARCH_URL -# Copy package.json and package-lock.json into the builder. -# Copying just these files first allows us to take advantage -# of cached Docker layers. WORKDIR /usr/src/app COPY ./ui/package.json ./ui/yarn.lock ./ @@ -24,21 +25,16 @@ COPY ./ui . # Build the js app for production RUN yarn run build -# Since we are serving it all from python, switch over to +# Since we are serving it all from python, switch over to # a more appropriate base image. FROM python:3.9-slim -RUN apt-get -y update && apt-get -y upgrade -RUN apt-get install -y build-essential libpq-dev - -# Copy over just the Python backend app code. -WORKDIR /app -ENV ENV=production +RUN apt-get -y update && apt-get -y upgrade +RUN apt-get install -y build-essential libpq-dev libmagic1 # Set Runtime Variables ENV PYTHONDONTWRITEBYTECODE=1 ENV PYTHONUNBUFFERED=1 -ENV PYTHONPATH /app # Install Poetry globally and copy project files RUN python3 -m pip install -U pip setuptools && \ @@ -46,21 +42,29 @@ RUN python3 -m pip install -U pip setuptools && \ rm -rf /root/.cache/pip # Set the working directory and copy the project files -COPY ./app/pyproject.toml ./app/poetry.lock ./ +WORKDIR /app # Use Poetry to install the project dependencies globally # This step is after the COPY step because it is more likely to change, # and therefore should not be included in earlier layers that can be cached. + +COPY ./app/pyproject.toml ./app/poetry.lock ./ + RUN poetry config virtualenvs.create false && \ - poetry install --no-dev && \ + poetry install --no-root --no-dev && \ rm -rf /root/.cache/pypoetry -WORKDIR /app +# Copy the other project files COPY ./app . -# Copy the production UI assets into the new base image. -COPY --from=UI_BUILDER /usr/src/app/build/ ./react-app/ +# Use Poetry to install the local package strelka-ui +RUN poetry install --only-root && \ + rm -rf /root/.cache/pypoetry + +# Copy the production UI assets into the new base image. +COPY --from=UI_BUILDER /usr/src/app/build/ ./strelka_ui/react-app/ +# Run App COPY entrypoint.sh . RUN chmod +x entrypoint.sh ENTRYPOINT ["./entrypoint.sh"] diff --git a/LICENSE.md b/LICENSE.md index cca5658..7e605fd 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -1,4 +1,4 @@ -Copyright (c) 2022 Target Brands, Inc. +Copyright (c) 2024 Target Brands, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/app/__init__.py b/app/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/app/blueprints/__init__.py b/app/blueprints/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/app/config/__init__.py b/app/config/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/app/node_modules/.yarn-integrity b/app/node_modules/.yarn-integrity deleted file mode 100644 index e274d7f..0000000 --- a/app/node_modules/.yarn-integrity +++ /dev/null @@ -1,10 +0,0 @@ -{ - "systemParams": "darwin-x64-102", - "modulesFolders": [], - "flags": [], - "linkedModules": [], - "topLevelPatterns": [], - "lockfileEntries": {}, - "files": [], - "artifacts": {} -} \ No newline at end of file diff --git a/app/poetry.lock b/app/poetry.lock index 08592d8..e7b2938 100644 --- a/app/poetry.lock +++ b/app/poetry.lock @@ -1,88 +1,88 @@ -# This file is automatically @generated by Poetry 1.7.1 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.8.2 and should not be changed by hand. [[package]] name = "aiohttp" -version = "3.9.1" +version = "3.9.5" description = "Async http client/server framework (asyncio)" optional = false python-versions = ">=3.8" files = [ - {file = "aiohttp-3.9.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:e1f80197f8b0b846a8d5cf7b7ec6084493950d0882cc5537fb7b96a69e3c8590"}, - {file = "aiohttp-3.9.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c72444d17777865734aa1a4d167794c34b63e5883abb90356a0364a28904e6c0"}, - {file = "aiohttp-3.9.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9b05d5cbe9dafcdc733262c3a99ccf63d2f7ce02543620d2bd8db4d4f7a22f83"}, - {file = "aiohttp-3.9.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5c4fa235d534b3547184831c624c0b7c1e262cd1de847d95085ec94c16fddcd5"}, - {file = "aiohttp-3.9.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:289ba9ae8e88d0ba16062ecf02dd730b34186ea3b1e7489046fc338bdc3361c4"}, - {file = "aiohttp-3.9.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:bff7e2811814fa2271be95ab6e84c9436d027a0e59665de60edf44e529a42c1f"}, - {file = "aiohttp-3.9.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:81b77f868814346662c96ab36b875d7814ebf82340d3284a31681085c051320f"}, - {file = "aiohttp-3.9.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3b9c7426923bb7bd66d409da46c41e3fb40f5caf679da624439b9eba92043fa6"}, - {file = "aiohttp-3.9.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:8d44e7bf06b0c0a70a20f9100af9fcfd7f6d9d3913e37754c12d424179b4e48f"}, - {file = "aiohttp-3.9.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:22698f01ff5653fe66d16ffb7658f582a0ac084d7da1323e39fd9eab326a1f26"}, - {file = "aiohttp-3.9.1-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:ca7ca5abfbfe8d39e653870fbe8d7710be7a857f8a8386fc9de1aae2e02ce7e4"}, - {file = "aiohttp-3.9.1-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:8d7f98fde213f74561be1d6d3fa353656197f75d4edfbb3d94c9eb9b0fc47f5d"}, - {file = "aiohttp-3.9.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:5216b6082c624b55cfe79af5d538e499cd5f5b976820eac31951fb4325974501"}, - {file = "aiohttp-3.9.1-cp310-cp310-win32.whl", hash = "sha256:0e7ba7ff228c0d9a2cd66194e90f2bca6e0abca810b786901a569c0de082f489"}, - {file = "aiohttp-3.9.1-cp310-cp310-win_amd64.whl", hash = "sha256:c7e939f1ae428a86e4abbb9a7c4732bf4706048818dfd979e5e2839ce0159f23"}, - {file = "aiohttp-3.9.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:df9cf74b9bc03d586fc53ba470828d7b77ce51b0582d1d0b5b2fb673c0baa32d"}, - {file = "aiohttp-3.9.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ecca113f19d5e74048c001934045a2b9368d77b0b17691d905af18bd1c21275e"}, - {file = "aiohttp-3.9.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:8cef8710fb849d97c533f259103f09bac167a008d7131d7b2b0e3a33269185c0"}, - {file = "aiohttp-3.9.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bea94403a21eb94c93386d559bce297381609153e418a3ffc7d6bf772f59cc35"}, - {file = "aiohttp-3.9.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:91c742ca59045dce7ba76cab6e223e41d2c70d79e82c284a96411f8645e2afff"}, - {file = "aiohttp-3.9.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6c93b7c2e52061f0925c3382d5cb8980e40f91c989563d3d32ca280069fd6a87"}, - {file = "aiohttp-3.9.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ee2527134f95e106cc1653e9ac78846f3a2ec1004cf20ef4e02038035a74544d"}, - {file = "aiohttp-3.9.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:11ff168d752cb41e8492817e10fb4f85828f6a0142b9726a30c27c35a1835f01"}, - {file = "aiohttp-3.9.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:b8c3a67eb87394386847d188996920f33b01b32155f0a94f36ca0e0c635bf3e3"}, - {file = "aiohttp-3.9.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:c7b5d5d64e2a14e35a9240b33b89389e0035e6de8dbb7ffa50d10d8b65c57449"}, - {file = "aiohttp-3.9.1-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:69985d50a2b6f709412d944ffb2e97d0be154ea90600b7a921f95a87d6f108a2"}, - {file = "aiohttp-3.9.1-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:c9110c06eaaac7e1f5562caf481f18ccf8f6fdf4c3323feab28a93d34cc646bd"}, - {file = "aiohttp-3.9.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:d737e69d193dac7296365a6dcb73bbbf53bb760ab25a3727716bbd42022e8d7a"}, - {file = "aiohttp-3.9.1-cp311-cp311-win32.whl", hash = "sha256:4ee8caa925aebc1e64e98432d78ea8de67b2272252b0a931d2ac3bd876ad5544"}, - {file = "aiohttp-3.9.1-cp311-cp311-win_amd64.whl", hash = "sha256:a34086c5cc285be878622e0a6ab897a986a6e8bf5b67ecb377015f06ed316587"}, - {file = "aiohttp-3.9.1-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:f800164276eec54e0af5c99feb9494c295118fc10a11b997bbb1348ba1a52065"}, - {file = "aiohttp-3.9.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:500f1c59906cd142d452074f3811614be04819a38ae2b3239a48b82649c08821"}, - {file = "aiohttp-3.9.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:0b0a6a36ed7e164c6df1e18ee47afbd1990ce47cb428739d6c99aaabfaf1b3af"}, - {file = "aiohttp-3.9.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:69da0f3ed3496808e8cbc5123a866c41c12c15baaaead96d256477edf168eb57"}, - {file = "aiohttp-3.9.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:176df045597e674fa950bf5ae536be85699e04cea68fa3a616cf75e413737eb5"}, - {file = "aiohttp-3.9.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b796b44111f0cab6bbf66214186e44734b5baab949cb5fb56154142a92989aeb"}, - {file = "aiohttp-3.9.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f27fdaadce22f2ef950fc10dcdf8048407c3b42b73779e48a4e76b3c35bca26c"}, - {file = "aiohttp-3.9.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bcb6532b9814ea7c5a6a3299747c49de30e84472fa72821b07f5a9818bce0f66"}, - {file = "aiohttp-3.9.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:54631fb69a6e44b2ba522f7c22a6fb2667a02fd97d636048478db2fd8c4e98fe"}, - {file = "aiohttp-3.9.1-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:4b4c452d0190c5a820d3f5c0f3cd8a28ace48c54053e24da9d6041bf81113183"}, - {file = "aiohttp-3.9.1-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:cae4c0c2ca800c793cae07ef3d40794625471040a87e1ba392039639ad61ab5b"}, - {file = "aiohttp-3.9.1-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:565760d6812b8d78d416c3c7cfdf5362fbe0d0d25b82fed75d0d29e18d7fc30f"}, - {file = "aiohttp-3.9.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:54311eb54f3a0c45efb9ed0d0a8f43d1bc6060d773f6973efd90037a51cd0a3f"}, - {file = "aiohttp-3.9.1-cp312-cp312-win32.whl", hash = "sha256:85c3e3c9cb1d480e0b9a64c658cd66b3cfb8e721636ab8b0e746e2d79a7a9eed"}, - {file = "aiohttp-3.9.1-cp312-cp312-win_amd64.whl", hash = "sha256:11cb254e397a82efb1805d12561e80124928e04e9c4483587ce7390b3866d213"}, - {file = "aiohttp-3.9.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:8a22a34bc594d9d24621091d1b91511001a7eea91d6652ea495ce06e27381f70"}, - {file = "aiohttp-3.9.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:598db66eaf2e04aa0c8900a63b0101fdc5e6b8a7ddd805c56d86efb54eb66672"}, - {file = "aiohttp-3.9.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:2c9376e2b09895c8ca8b95362283365eb5c03bdc8428ade80a864160605715f1"}, - {file = "aiohttp-3.9.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:41473de252e1797c2d2293804e389a6d6986ef37cbb4a25208de537ae32141dd"}, - {file = "aiohttp-3.9.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9c5857612c9813796960c00767645cb5da815af16dafb32d70c72a8390bbf690"}, - {file = "aiohttp-3.9.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ffcd828e37dc219a72c9012ec44ad2e7e3066bec6ff3aaa19e7d435dbf4032ca"}, - {file = "aiohttp-3.9.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:219a16763dc0294842188ac8a12262b5671817042b35d45e44fd0a697d8c8361"}, - {file = "aiohttp-3.9.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f694dc8a6a3112059258a725a4ebe9acac5fe62f11c77ac4dcf896edfa78ca28"}, - {file = "aiohttp-3.9.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:bcc0ea8d5b74a41b621ad4a13d96c36079c81628ccc0b30cfb1603e3dfa3a014"}, - {file = "aiohttp-3.9.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:90ec72d231169b4b8d6085be13023ece8fa9b1bb495e4398d847e25218e0f431"}, - {file = "aiohttp-3.9.1-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:cf2a0ac0615842b849f40c4d7f304986a242f1e68286dbf3bd7a835e4f83acfd"}, - {file = "aiohttp-3.9.1-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:0e49b08eafa4f5707ecfb321ab9592717a319e37938e301d462f79b4e860c32a"}, - {file = "aiohttp-3.9.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:2c59e0076ea31c08553e868cec02d22191c086f00b44610f8ab7363a11a5d9d8"}, - {file = "aiohttp-3.9.1-cp38-cp38-win32.whl", hash = "sha256:4831df72b053b1eed31eb00a2e1aff6896fb4485301d4ccb208cac264b648db4"}, - {file = "aiohttp-3.9.1-cp38-cp38-win_amd64.whl", hash = "sha256:3135713c5562731ee18f58d3ad1bf41e1d8883eb68b363f2ffde5b2ea4b84cc7"}, - {file = "aiohttp-3.9.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:cfeadf42840c1e870dc2042a232a8748e75a36b52d78968cda6736de55582766"}, - {file = "aiohttp-3.9.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:70907533db712f7aa791effb38efa96f044ce3d4e850e2d7691abd759f4f0ae0"}, - {file = "aiohttp-3.9.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:cdefe289681507187e375a5064c7599f52c40343a8701761c802c1853a504558"}, - {file = "aiohttp-3.9.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d7481f581251bb5558ba9f635db70908819caa221fc79ee52a7f58392778c636"}, - {file = "aiohttp-3.9.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:49f0c1b3c2842556e5de35f122fc0f0b721334ceb6e78c3719693364d4af8499"}, - {file = "aiohttp-3.9.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0d406b01a9f5a7e232d1b0d161b40c05275ffbcbd772dc18c1d5a570961a1ca4"}, - {file = "aiohttp-3.9.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8d8e4450e7fe24d86e86b23cc209e0023177b6d59502e33807b732d2deb6975f"}, - {file = "aiohttp-3.9.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3c0266cd6f005e99f3f51e583012de2778e65af6b73860038b968a0a8888487a"}, - {file = "aiohttp-3.9.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:ab221850108a4a063c5b8a70f00dd7a1975e5a1713f87f4ab26a46e5feac5a0e"}, - {file = "aiohttp-3.9.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:c88a15f272a0ad3d7773cf3a37cc7b7d077cbfc8e331675cf1346e849d97a4e5"}, - {file = "aiohttp-3.9.1-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:237533179d9747080bcaad4d02083ce295c0d2eab3e9e8ce103411a4312991a0"}, - {file = "aiohttp-3.9.1-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:02ab6006ec3c3463b528374c4cdce86434e7b89ad355e7bf29e2f16b46c7dd6f"}, - {file = "aiohttp-3.9.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:04fa38875e53eb7e354ece1607b1d2fdee2d175ea4e4d745f6ec9f751fe20c7c"}, - {file = "aiohttp-3.9.1-cp39-cp39-win32.whl", hash = "sha256:82eefaf1a996060602f3cc1112d93ba8b201dbf5d8fd9611227de2003dddb3b7"}, - {file = "aiohttp-3.9.1-cp39-cp39-win_amd64.whl", hash = "sha256:9b05d33ff8e6b269e30a7957bd3244ffbce2a7a35a81b81c382629b80af1a8bf"}, - {file = "aiohttp-3.9.1.tar.gz", hash = "sha256:8fc49a87ac269d4529da45871e2ffb6874e87779c3d0e2ccd813c0899221239d"}, + {file = "aiohttp-3.9.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:fcde4c397f673fdec23e6b05ebf8d4751314fa7c24f93334bf1f1364c1c69ac7"}, + {file = "aiohttp-3.9.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:5d6b3f1fabe465e819aed2c421a6743d8debbde79b6a8600739300630a01bf2c"}, + {file = "aiohttp-3.9.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:6ae79c1bc12c34082d92bf9422764f799aee4746fd7a392db46b7fd357d4a17a"}, + {file = "aiohttp-3.9.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4d3ebb9e1316ec74277d19c5f482f98cc65a73ccd5430540d6d11682cd857430"}, + {file = "aiohttp-3.9.5-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:84dabd95154f43a2ea80deffec9cb44d2e301e38a0c9d331cc4aa0166fe28ae3"}, + {file = "aiohttp-3.9.5-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c8a02fbeca6f63cb1f0475c799679057fc9268b77075ab7cf3f1c600e81dd46b"}, + {file = "aiohttp-3.9.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c26959ca7b75ff768e2776d8055bf9582a6267e24556bb7f7bd29e677932be72"}, + {file = "aiohttp-3.9.5-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:714d4e5231fed4ba2762ed489b4aec07b2b9953cf4ee31e9871caac895a839c0"}, + {file = "aiohttp-3.9.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:e7a6a8354f1b62e15d48e04350f13e726fa08b62c3d7b8401c0a1314f02e3558"}, + {file = "aiohttp-3.9.5-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:c413016880e03e69d166efb5a1a95d40f83d5a3a648d16486592c49ffb76d0db"}, + {file = "aiohttp-3.9.5-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:ff84aeb864e0fac81f676be9f4685f0527b660f1efdc40dcede3c251ef1e867f"}, + {file = "aiohttp-3.9.5-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:ad7f2919d7dac062f24d6f5fe95d401597fbb015a25771f85e692d043c9d7832"}, + {file = "aiohttp-3.9.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:702e2c7c187c1a498a4e2b03155d52658fdd6fda882d3d7fbb891a5cf108bb10"}, + {file = "aiohttp-3.9.5-cp310-cp310-win32.whl", hash = "sha256:67c3119f5ddc7261d47163ed86d760ddf0e625cd6246b4ed852e82159617b5fb"}, + {file = "aiohttp-3.9.5-cp310-cp310-win_amd64.whl", hash = "sha256:471f0ef53ccedec9995287f02caf0c068732f026455f07db3f01a46e49d76bbb"}, + {file = "aiohttp-3.9.5-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:e0ae53e33ee7476dd3d1132f932eeb39bf6125083820049d06edcdca4381f342"}, + {file = "aiohttp-3.9.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c088c4d70d21f8ca5c0b8b5403fe84a7bc8e024161febdd4ef04575ef35d474d"}, + {file = "aiohttp-3.9.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:639d0042b7670222f33b0028de6b4e2fad6451462ce7df2af8aee37dcac55424"}, + {file = "aiohttp-3.9.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f26383adb94da5e7fb388d441bf09c61e5e35f455a3217bfd790c6b6bc64b2ee"}, + {file = "aiohttp-3.9.5-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:66331d00fb28dc90aa606d9a54304af76b335ae204d1836f65797d6fe27f1ca2"}, + {file = "aiohttp-3.9.5-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4ff550491f5492ab5ed3533e76b8567f4b37bd2995e780a1f46bca2024223233"}, + {file = "aiohttp-3.9.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f22eb3a6c1080d862befa0a89c380b4dafce29dc6cd56083f630073d102eb595"}, + {file = "aiohttp-3.9.5-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a81b1143d42b66ffc40a441379387076243ef7b51019204fd3ec36b9f69e77d6"}, + {file = "aiohttp-3.9.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:f64fd07515dad67f24b6ea4a66ae2876c01031de91c93075b8093f07c0a2d93d"}, + {file = "aiohttp-3.9.5-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:93e22add827447d2e26d67c9ac0161756007f152fdc5210277d00a85f6c92323"}, + {file = "aiohttp-3.9.5-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:55b39c8684a46e56ef8c8d24faf02de4a2b2ac60d26cee93bc595651ff545de9"}, + {file = "aiohttp-3.9.5-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:4715a9b778f4293b9f8ae7a0a7cef9829f02ff8d6277a39d7f40565c737d3771"}, + {file = "aiohttp-3.9.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:afc52b8d969eff14e069a710057d15ab9ac17cd4b6753042c407dcea0e40bf75"}, + {file = "aiohttp-3.9.5-cp311-cp311-win32.whl", hash = "sha256:b3df71da99c98534be076196791adca8819761f0bf6e08e07fd7da25127150d6"}, + {file = "aiohttp-3.9.5-cp311-cp311-win_amd64.whl", hash = "sha256:88e311d98cc0bf45b62fc46c66753a83445f5ab20038bcc1b8a1cc05666f428a"}, + {file = "aiohttp-3.9.5-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:c7a4b7a6cf5b6eb11e109a9755fd4fda7d57395f8c575e166d363b9fc3ec4678"}, + {file = "aiohttp-3.9.5-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:0a158704edf0abcac8ac371fbb54044f3270bdbc93e254a82b6c82be1ef08f3c"}, + {file = "aiohttp-3.9.5-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:d153f652a687a8e95ad367a86a61e8d53d528b0530ef382ec5aaf533140ed00f"}, + {file = "aiohttp-3.9.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:82a6a97d9771cb48ae16979c3a3a9a18b600a8505b1115cfe354dfb2054468b4"}, + {file = "aiohttp-3.9.5-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:60cdbd56f4cad9f69c35eaac0fbbdf1f77b0ff9456cebd4902f3dd1cf096464c"}, + {file = "aiohttp-3.9.5-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8676e8fd73141ded15ea586de0b7cda1542960a7b9ad89b2b06428e97125d4fa"}, + {file = "aiohttp-3.9.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:da00da442a0e31f1c69d26d224e1efd3a1ca5bcbf210978a2ca7426dfcae9f58"}, + {file = "aiohttp-3.9.5-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:18f634d540dd099c262e9f887c8bbacc959847cfe5da7a0e2e1cf3f14dbf2daf"}, + {file = "aiohttp-3.9.5-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:320e8618eda64e19d11bdb3bd04ccc0a816c17eaecb7e4945d01deee2a22f95f"}, + {file = "aiohttp-3.9.5-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:2faa61a904b83142747fc6a6d7ad8fccff898c849123030f8e75d5d967fd4a81"}, + {file = "aiohttp-3.9.5-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:8c64a6dc3fe5db7b1b4d2b5cb84c4f677768bdc340611eca673afb7cf416ef5a"}, + {file = "aiohttp-3.9.5-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:393c7aba2b55559ef7ab791c94b44f7482a07bf7640d17b341b79081f5e5cd1a"}, + {file = "aiohttp-3.9.5-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:c671dc117c2c21a1ca10c116cfcd6e3e44da7fcde37bf83b2be485ab377b25da"}, + {file = "aiohttp-3.9.5-cp312-cp312-win32.whl", hash = "sha256:5a7ee16aab26e76add4afc45e8f8206c95d1d75540f1039b84a03c3b3800dd59"}, + {file = "aiohttp-3.9.5-cp312-cp312-win_amd64.whl", hash = "sha256:5ca51eadbd67045396bc92a4345d1790b7301c14d1848feaac1d6a6c9289e888"}, + {file = "aiohttp-3.9.5-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:694d828b5c41255e54bc2dddb51a9f5150b4eefa9886e38b52605a05d96566e8"}, + {file = "aiohttp-3.9.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:0605cc2c0088fcaae79f01c913a38611ad09ba68ff482402d3410bf59039bfb8"}, + {file = "aiohttp-3.9.5-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:4558e5012ee03d2638c681e156461d37b7a113fe13970d438d95d10173d25f78"}, + {file = "aiohttp-3.9.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9dbc053ac75ccc63dc3a3cc547b98c7258ec35a215a92bd9f983e0aac95d3d5b"}, + {file = "aiohttp-3.9.5-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4109adee842b90671f1b689901b948f347325045c15f46b39797ae1bf17019de"}, + {file = "aiohttp-3.9.5-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a6ea1a5b409a85477fd8e5ee6ad8f0e40bf2844c270955e09360418cfd09abac"}, + {file = "aiohttp-3.9.5-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f3c2890ca8c59ee683fd09adf32321a40fe1cf164e3387799efb2acebf090c11"}, + {file = "aiohttp-3.9.5-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3916c8692dbd9d55c523374a3b8213e628424d19116ac4308e434dbf6d95bbdd"}, + {file = "aiohttp-3.9.5-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:8d1964eb7617907c792ca00b341b5ec3e01ae8c280825deadbbd678447b127e1"}, + {file = "aiohttp-3.9.5-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:d5ab8e1f6bee051a4bf6195e38a5c13e5e161cb7bad83d8854524798bd9fcd6e"}, + {file = "aiohttp-3.9.5-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:52c27110f3862a1afbcb2af4281fc9fdc40327fa286c4625dfee247c3ba90156"}, + {file = "aiohttp-3.9.5-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:7f64cbd44443e80094309875d4f9c71d0401e966d191c3d469cde4642bc2e031"}, + {file = "aiohttp-3.9.5-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:8b4f72fbb66279624bfe83fd5eb6aea0022dad8eec62b71e7bf63ee1caadeafe"}, + {file = "aiohttp-3.9.5-cp38-cp38-win32.whl", hash = "sha256:6380c039ec52866c06d69b5c7aad5478b24ed11696f0e72f6b807cfb261453da"}, + {file = "aiohttp-3.9.5-cp38-cp38-win_amd64.whl", hash = "sha256:da22dab31d7180f8c3ac7c7635f3bcd53808f374f6aa333fe0b0b9e14b01f91a"}, + {file = "aiohttp-3.9.5-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:1732102949ff6087589408d76cd6dea656b93c896b011ecafff418c9661dc4ed"}, + {file = "aiohttp-3.9.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:c6021d296318cb6f9414b48e6a439a7f5d1f665464da507e8ff640848ee2a58a"}, + {file = "aiohttp-3.9.5-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:239f975589a944eeb1bad26b8b140a59a3a320067fb3cd10b75c3092405a1372"}, + {file = "aiohttp-3.9.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3b7b30258348082826d274504fbc7c849959f1989d86c29bc355107accec6cfb"}, + {file = "aiohttp-3.9.5-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cd2adf5c87ff6d8b277814a28a535b59e20bfea40a101db6b3bdca7e9926bc24"}, + {file = "aiohttp-3.9.5-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e9a3d838441bebcf5cf442700e3963f58b5c33f015341f9ea86dcd7d503c07e2"}, + {file = "aiohttp-3.9.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9e3a1ae66e3d0c17cf65c08968a5ee3180c5a95920ec2731f53343fac9bad106"}, + {file = "aiohttp-3.9.5-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9c69e77370cce2d6df5d12b4e12bdcca60c47ba13d1cbbc8645dd005a20b738b"}, + {file = "aiohttp-3.9.5-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:0cbf56238f4bbf49dab8c2dc2e6b1b68502b1e88d335bea59b3f5b9f4c001475"}, + {file = "aiohttp-3.9.5-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:d1469f228cd9ffddd396d9948b8c9cd8022b6d1bf1e40c6f25b0fb90b4f893ed"}, + {file = "aiohttp-3.9.5-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:45731330e754f5811c314901cebdf19dd776a44b31927fa4b4dbecab9e457b0c"}, + {file = "aiohttp-3.9.5-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:3fcb4046d2904378e3aeea1df51f697b0467f2aac55d232c87ba162709478c46"}, + {file = "aiohttp-3.9.5-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:8cf142aa6c1a751fcb364158fd710b8a9be874b81889c2bd13aa8893197455e2"}, + {file = "aiohttp-3.9.5-cp39-cp39-win32.whl", hash = "sha256:7b179eea70833c8dee51ec42f3b4097bd6370892fa93f510f76762105568cf09"}, + {file = "aiohttp-3.9.5-cp39-cp39-win_amd64.whl", hash = "sha256:38d80498e2e169bc61418ff36170e0aad0cd268da8b38a17c4cf29d254a8b3f1"}, + {file = "aiohttp-3.9.5.tar.gz", hash = "sha256:edea7d15772ceeb29db4aff55e482d4bcfb6ae160ce144f2682de02f6d693551"}, ] [package.dependencies] @@ -173,33 +173,181 @@ tests-no-zope = ["cloudpickle", "coverage[toml] (>=5.0.2)", "hypothesis", "mypy" [[package]] name = "black" -version = "21.12b0" +version = "24.3.0" description = "The uncompromising code formatter." optional = false -python-versions = ">=3.6.2" +python-versions = ">=3.8" files = [ - {file = "black-21.12b0-py3-none-any.whl", hash = "sha256:a615e69ae185e08fdd73e4715e260e2479c861b5740057fde6e8b4e3b7dd589f"}, - {file = "black-21.12b0.tar.gz", hash = "sha256:77b80f693a569e2e527958459634f18df9b0ba2625ba4e0c2d5da5be42e6f2b3"}, + {file = "black-24.3.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:7d5e026f8da0322b5662fa7a8e752b3fa2dac1c1cbc213c3d7ff9bdd0ab12395"}, + {file = "black-24.3.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9f50ea1132e2189d8dff0115ab75b65590a3e97de1e143795adb4ce317934995"}, + {file = "black-24.3.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e2af80566f43c85f5797365077fb64a393861a3730bd110971ab7a0c94e873e7"}, + {file = "black-24.3.0-cp310-cp310-win_amd64.whl", hash = "sha256:4be5bb28e090456adfc1255e03967fb67ca846a03be7aadf6249096100ee32d0"}, + {file = "black-24.3.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4f1373a7808a8f135b774039f61d59e4be7eb56b2513d3d2f02a8b9365b8a8a9"}, + {file = "black-24.3.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:aadf7a02d947936ee418777e0247ea114f78aff0d0959461057cae8a04f20597"}, + {file = "black-24.3.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:65c02e4ea2ae09d16314d30912a58ada9a5c4fdfedf9512d23326128ac08ac3d"}, + {file = "black-24.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:bf21b7b230718a5f08bd32d5e4f1db7fc8788345c8aea1d155fc17852b3410f5"}, + {file = "black-24.3.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:2818cf72dfd5d289e48f37ccfa08b460bf469e67fb7c4abb07edc2e9f16fb63f"}, + {file = "black-24.3.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4acf672def7eb1725f41f38bf6bf425c8237248bb0804faa3965c036f7672d11"}, + {file = "black-24.3.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c7ed6668cbbfcd231fa0dc1b137d3e40c04c7f786e626b405c62bcd5db5857e4"}, + {file = "black-24.3.0-cp312-cp312-win_amd64.whl", hash = "sha256:56f52cfbd3dabe2798d76dbdd299faa046a901041faf2cf33288bc4e6dae57b5"}, + {file = "black-24.3.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:79dcf34b33e38ed1b17434693763301d7ccbd1c5860674a8f871bd15139e7837"}, + {file = "black-24.3.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:e19cb1c6365fd6dc38a6eae2dcb691d7d83935c10215aef8e6c38edee3f77abd"}, + {file = "black-24.3.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:65b76c275e4c1c5ce6e9870911384bff5ca31ab63d19c76811cb1fb162678213"}, + {file = "black-24.3.0-cp38-cp38-win_amd64.whl", hash = "sha256:b5991d523eee14756f3c8d5df5231550ae8993e2286b8014e2fdea7156ed0959"}, + {file = "black-24.3.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:c45f8dff244b3c431b36e3224b6be4a127c6aca780853574c00faf99258041eb"}, + {file = "black-24.3.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:6905238a754ceb7788a73f02b45637d820b2f5478b20fec82ea865e4f5d4d9f7"}, + {file = "black-24.3.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d7de8d330763c66663661a1ffd432274a2f92f07feeddd89ffd085b5744f85e7"}, + {file = "black-24.3.0-cp39-cp39-win_amd64.whl", hash = "sha256:7bb041dca0d784697af4646d3b62ba4a6b028276ae878e53f6b4f74ddd6db99f"}, + {file = "black-24.3.0-py3-none-any.whl", hash = "sha256:41622020d7120e01d377f74249e677039d20e6344ff5851de8a10f11f513bf93"}, + {file = "black-24.3.0.tar.gz", hash = "sha256:a0c9c4a0771afc6919578cec71ce82a3e31e054904e7197deacbc9382671c41f"}, ] [package.dependencies] -click = ">=7.1.2" +click = ">=8.0.0" mypy-extensions = ">=0.4.3" -pathspec = ">=0.9.0,<1" +packaging = ">=22.0" +pathspec = ">=0.9.0" platformdirs = ">=2" -tomli = ">=0.2.6,<2.0.0" -typing-extensions = [ - {version = ">=3.10.0.0,<3.10.0.1 || >3.10.0.1", markers = "python_version >= \"3.10\""}, - {version = ">=3.10.0.0", markers = "python_version < \"3.10\""}, -] +tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} +typing-extensions = {version = ">=4.0.1", markers = "python_version < \"3.11\""} [package.extras] colorama = ["colorama (>=0.4.3)"] -d = ["aiohttp (>=3.7.4)"] +d = ["aiohttp (>=3.7.4)", "aiohttp (>=3.7.4,!=3.9.0)"] jupyter = ["ipython (>=7.8.0)", "tokenize-rt (>=3.2.0)"] -python2 = ["typed-ast (>=1.4.3)"] uvloop = ["uvloop (>=0.15.2)"] +[[package]] +name = "brotli" +version = "1.1.0" +description = "Python bindings for the Brotli compression library" +optional = false +python-versions = "*" +files = [ + {file = "Brotli-1.1.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:e1140c64812cb9b06c922e77f1c26a75ec5e3f0fb2bf92cc8c58720dec276752"}, + {file = "Brotli-1.1.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c8fd5270e906eef71d4a8d19b7c6a43760c6abcfcc10c9101d14eb2357418de9"}, + {file = "Brotli-1.1.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1ae56aca0402a0f9a3431cddda62ad71666ca9d4dc3a10a142b9dce2e3c0cda3"}, + {file = "Brotli-1.1.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:43ce1b9935bfa1ede40028054d7f48b5469cd02733a365eec8a329ffd342915d"}, + {file = "Brotli-1.1.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:7c4855522edb2e6ae7fdb58e07c3ba9111e7621a8956f481c68d5d979c93032e"}, + {file = "Brotli-1.1.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:38025d9f30cf4634f8309c6874ef871b841eb3c347e90b0851f63d1ded5212da"}, + {file = "Brotli-1.1.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:e6a904cb26bfefc2f0a6f240bdf5233be78cd2488900a2f846f3c3ac8489ab80"}, + {file = "Brotli-1.1.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:a37b8f0391212d29b3a91a799c8e4a2855e0576911cdfb2515487e30e322253d"}, + {file = "Brotli-1.1.0-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:e84799f09591700a4154154cab9787452925578841a94321d5ee8fb9a9a328f0"}, + {file = "Brotli-1.1.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:f66b5337fa213f1da0d9000bc8dc0cb5b896b726eefd9c6046f699b169c41b9e"}, + {file = "Brotli-1.1.0-cp310-cp310-win32.whl", hash = "sha256:be36e3d172dc816333f33520154d708a2657ea63762ec16b62ece02ab5e4daf2"}, + {file = "Brotli-1.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:0c6244521dda65ea562d5a69b9a26120769b7a9fb3db2fe9545935ed6735b128"}, + {file = "Brotli-1.1.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:a3daabb76a78f829cafc365531c972016e4aa8d5b4bf60660ad8ecee19df7ccc"}, + {file = "Brotli-1.1.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c8146669223164fc87a7e3de9f81e9423c67a79d6b3447994dfb9c95da16e2d6"}, + {file = "Brotli-1.1.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:30924eb4c57903d5a7526b08ef4a584acc22ab1ffa085faceb521521d2de32dd"}, + {file = "Brotli-1.1.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ceb64bbc6eac5a140ca649003756940f8d6a7c444a68af170b3187623b43bebf"}, + {file = "Brotli-1.1.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a469274ad18dc0e4d316eefa616d1d0c2ff9da369af19fa6f3daa4f09671fd61"}, + {file = "Brotli-1.1.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:524f35912131cc2cabb00edfd8d573b07f2d9f21fa824bd3fb19725a9cf06327"}, + {file = "Brotli-1.1.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:5b3cc074004d968722f51e550b41a27be656ec48f8afaeeb45ebf65b561481dd"}, + {file = "Brotli-1.1.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:19c116e796420b0cee3da1ccec3b764ed2952ccfcc298b55a10e5610ad7885f9"}, + {file = "Brotli-1.1.0-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:510b5b1bfbe20e1a7b3baf5fed9e9451873559a976c1a78eebaa3b86c57b4265"}, + {file = "Brotli-1.1.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:a1fd8a29719ccce974d523580987b7f8229aeace506952fa9ce1d53a033873c8"}, + {file = "Brotli-1.1.0-cp311-cp311-win32.whl", hash = "sha256:39da8adedf6942d76dc3e46653e52df937a3c4d6d18fdc94a7c29d263b1f5b50"}, + {file = "Brotli-1.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:aac0411d20e345dc0920bdec5548e438e999ff68d77564d5e9463a7ca9d3e7b1"}, + {file = "Brotli-1.1.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:316cc9b17edf613ac76b1f1f305d2a748f1b976b033b049a6ecdfd5612c70409"}, + {file = "Brotli-1.1.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:caf9ee9a5775f3111642d33b86237b05808dafcd6268faa492250e9b78046eb2"}, + {file = "Brotli-1.1.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:70051525001750221daa10907c77830bc889cb6d865cc0b813d9db7fefc21451"}, + {file = "Brotli-1.1.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7f4bf76817c14aa98cc6697ac02f3972cb8c3da93e9ef16b9c66573a68014f91"}, + {file = "Brotli-1.1.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d0c5516f0aed654134a2fc936325cc2e642f8a0e096d075209672eb321cff408"}, + {file = "Brotli-1.1.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6c3020404e0b5eefd7c9485ccf8393cfb75ec38ce75586e046573c9dc29967a0"}, + {file = "Brotli-1.1.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:4ed11165dd45ce798d99a136808a794a748d5dc38511303239d4e2363c0695dc"}, + {file = "Brotli-1.1.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:4093c631e96fdd49e0377a9c167bfd75b6d0bad2ace734c6eb20b348bc3ea180"}, + {file = "Brotli-1.1.0-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:7e4c4629ddad63006efa0ef968c8e4751c5868ff0b1c5c40f76524e894c50248"}, + {file = "Brotli-1.1.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:861bf317735688269936f755fa136a99d1ed526883859f86e41a5d43c61d8966"}, + {file = "Brotli-1.1.0-cp312-cp312-win32.whl", hash = "sha256:5f4d5ea15c9382135076d2fb28dde923352fe02951e66935a9efaac8f10e81b0"}, + {file = "Brotli-1.1.0-cp312-cp312-win_amd64.whl", hash = "sha256:906bc3a79de8c4ae5b86d3d75a8b77e44404b0f4261714306e3ad248d8ab0951"}, + {file = "Brotli-1.1.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:a090ca607cbb6a34b0391776f0cb48062081f5f60ddcce5d11838e67a01928d1"}, + {file = "Brotli-1.1.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2de9d02f5bda03d27ede52e8cfe7b865b066fa49258cbab568720aa5be80a47d"}, + {file = "Brotli-1.1.0-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2333e30a5e00fe0fe55903c8832e08ee9c3b1382aacf4db26664a16528d51b4b"}, + {file = "Brotli-1.1.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:4d4a848d1837973bf0f4b5e54e3bec977d99be36a7895c61abb659301b02c112"}, + {file = "Brotli-1.1.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:fdc3ff3bfccdc6b9cc7c342c03aa2400683f0cb891d46e94b64a197910dc4064"}, + {file = "Brotli-1.1.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:5eeb539606f18a0b232d4ba45adccde4125592f3f636a6182b4a8a436548b914"}, + {file = "Brotli-1.1.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:fd5f17ff8f14003595ab414e45fce13d073e0762394f957182e69035c9f3d7c2"}, + {file = "Brotli-1.1.0-cp36-cp36m-musllinux_1_1_ppc64le.whl", hash = "sha256:069a121ac97412d1fe506da790b3e69f52254b9df4eb665cd42460c837193354"}, + {file = "Brotli-1.1.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:e93dfc1a1165e385cc8239fab7c036fb2cd8093728cbd85097b284d7b99249a2"}, + {file = "Brotli-1.1.0-cp36-cp36m-win32.whl", hash = "sha256:a599669fd7c47233438a56936988a2478685e74854088ef5293802123b5b2460"}, + {file = "Brotli-1.1.0-cp36-cp36m-win_amd64.whl", hash = "sha256:d143fd47fad1db3d7c27a1b1d66162e855b5d50a89666af46e1679c496e8e579"}, + {file = "Brotli-1.1.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:11d00ed0a83fa22d29bc6b64ef636c4552ebafcef57154b4ddd132f5638fbd1c"}, + {file = "Brotli-1.1.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f733d788519c7e3e71f0855c96618720f5d3d60c3cb829d8bbb722dddce37985"}, + {file = "Brotli-1.1.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:929811df5462e182b13920da56c6e0284af407d1de637d8e536c5cd00a7daf60"}, + {file = "Brotli-1.1.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:0b63b949ff929fbc2d6d3ce0e924c9b93c9785d877a21a1b678877ffbbc4423a"}, + {file = "Brotli-1.1.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:d192f0f30804e55db0d0e0a35d83a9fead0e9a359a9ed0285dbacea60cc10a84"}, + {file = "Brotli-1.1.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:f296c40e23065d0d6650c4aefe7470d2a25fffda489bcc3eb66083f3ac9f6643"}, + {file = "Brotli-1.1.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:919e32f147ae93a09fe064d77d5ebf4e35502a8df75c29fb05788528e330fe74"}, + {file = "Brotli-1.1.0-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:23032ae55523cc7bccb4f6a0bf368cd25ad9bcdcc1990b64a647e7bbcce9cb5b"}, + {file = "Brotli-1.1.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:224e57f6eac61cc449f498cc5f0e1725ba2071a3d4f48d5d9dffba42db196438"}, + {file = "Brotli-1.1.0-cp37-cp37m-win32.whl", hash = "sha256:587ca6d3cef6e4e868102672d3bd9dc9698c309ba56d41c2b9c85bbb903cdb95"}, + {file = "Brotli-1.1.0-cp37-cp37m-win_amd64.whl", hash = "sha256:2954c1c23f81c2eaf0b0717d9380bd348578a94161a65b3a2afc62c86467dd68"}, + {file = "Brotli-1.1.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:efa8b278894b14d6da122a72fefcebc28445f2d3f880ac59d46c90f4c13be9a3"}, + {file = "Brotli-1.1.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:03d20af184290887bdea3f0f78c4f737d126c74dc2f3ccadf07e54ceca3bf208"}, + {file = "Brotli-1.1.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6172447e1b368dcbc458925e5ddaf9113477b0ed542df258d84fa28fc45ceea7"}, + {file = "Brotli-1.1.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a743e5a28af5f70f9c080380a5f908d4d21d40e8f0e0c8901604d15cfa9ba751"}, + {file = "Brotli-1.1.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:0541e747cce78e24ea12d69176f6a7ddb690e62c425e01d31cc065e69ce55b48"}, + {file = "Brotli-1.1.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:cdbc1fc1bc0bff1cef838eafe581b55bfbffaed4ed0318b724d0b71d4d377619"}, + {file = "Brotli-1.1.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:890b5a14ce214389b2cc36ce82f3093f96f4cc730c1cffdbefff77a7c71f2a97"}, + {file = "Brotli-1.1.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:1ab4fbee0b2d9098c74f3057b2bc055a8bd92ccf02f65944a241b4349229185a"}, + {file = "Brotli-1.1.0-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:141bd4d93984070e097521ed07e2575b46f817d08f9fa42b16b9b5f27b5ac088"}, + {file = "Brotli-1.1.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:fce1473f3ccc4187f75b4690cfc922628aed4d3dd013d047f95a9b3919a86596"}, + {file = "Brotli-1.1.0-cp38-cp38-win32.whl", hash = "sha256:db85ecf4e609a48f4b29055f1e144231b90edc90af7481aa731ba2d059226b1b"}, + {file = "Brotli-1.1.0-cp38-cp38-win_amd64.whl", hash = "sha256:3d7954194c36e304e1523f55d7042c59dc53ec20dd4e9ea9d151f1b62b4415c0"}, + {file = "Brotli-1.1.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:5fb2ce4b8045c78ebbc7b8f3c15062e435d47e7393cc57c25115cfd49883747a"}, + {file = "Brotli-1.1.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:7905193081db9bfa73b1219140b3d315831cbff0d8941f22da695832f0dd188f"}, + {file = "Brotli-1.1.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a77def80806c421b4b0af06f45d65a136e7ac0bdca3c09d9e2ea4e515367c7e9"}, + {file = "Brotli-1.1.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8dadd1314583ec0bf2d1379f7008ad627cd6336625d6679cf2f8e67081b83acf"}, + {file = "Brotli-1.1.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:901032ff242d479a0efa956d853d16875d42157f98951c0230f69e69f9c09bac"}, + {file = "Brotli-1.1.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:22fc2a8549ffe699bfba2256ab2ed0421a7b8fadff114a3d201794e45a9ff578"}, + {file = "Brotli-1.1.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:ae15b066e5ad21366600ebec29a7ccbc86812ed267e4b28e860b8ca16a2bc474"}, + {file = "Brotli-1.1.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:949f3b7c29912693cee0afcf09acd6ebc04c57af949d9bf77d6101ebb61e388c"}, + {file = "Brotli-1.1.0-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:89f4988c7203739d48c6f806f1e87a1d96e0806d44f0fba61dba81392c9e474d"}, + {file = "Brotli-1.1.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:de6551e370ef19f8de1807d0a9aa2cdfdce2e85ce88b122fe9f6b2b076837e59"}, + {file = "Brotli-1.1.0-cp39-cp39-win32.whl", hash = "sha256:f0d8a7a6b5983c2496e364b969f0e526647a06b075d034f3297dc66f3b360c64"}, + {file = "Brotli-1.1.0-cp39-cp39-win_amd64.whl", hash = "sha256:cdad5b9014d83ca68c25d2e9444e28e967ef16e80f6b436918c700c117a85467"}, + {file = "Brotli-1.1.0.tar.gz", hash = "sha256:81de08ac11bcb85841e440c13611c00b67d3bf82698314928d0b676362546724"}, +] + +[[package]] +name = "brotlicffi" +version = "1.1.0.0" +description = "Python CFFI bindings to the Brotli library" +optional = false +python-versions = ">=3.7" +files = [ + {file = "brotlicffi-1.1.0.0-cp37-abi3-macosx_10_9_x86_64.whl", hash = "sha256:9b7ae6bd1a3f0df532b6d67ff674099a96d22bc0948955cb338488c31bfb8851"}, + {file = "brotlicffi-1.1.0.0-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:19ffc919fa4fc6ace69286e0a23b3789b4219058313cf9b45625016bf7ff996b"}, + {file = "brotlicffi-1.1.0.0-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9feb210d932ffe7798ee62e6145d3a757eb6233aa9a4e7db78dd3690d7755814"}, + {file = "brotlicffi-1.1.0.0-cp37-abi3-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:84763dbdef5dd5c24b75597a77e1b30c66604725707565188ba54bab4f114820"}, + {file = "brotlicffi-1.1.0.0-cp37-abi3-win32.whl", hash = "sha256:1b12b50e07c3911e1efa3a8971543e7648100713d4e0971b13631cce22c587eb"}, + {file = "brotlicffi-1.1.0.0-cp37-abi3-win_amd64.whl", hash = "sha256:994a4f0681bb6c6c3b0925530a1926b7a189d878e6e5e38fae8efa47c5d9c613"}, + {file = "brotlicffi-1.1.0.0-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:2e4aeb0bd2540cb91b069dbdd54d458da8c4334ceaf2d25df2f4af576d6766ca"}, + {file = "brotlicffi-1.1.0.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4b7b0033b0d37bb33009fb2fef73310e432e76f688af76c156b3594389d81391"}, + {file = "brotlicffi-1.1.0.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:54a07bb2374a1eba8ebb52b6fafffa2afd3c4df85ddd38fcc0511f2bb387c2a8"}, + {file = "brotlicffi-1.1.0.0-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7901a7dc4b88f1c1475de59ae9be59799db1007b7d059817948d8e4f12e24e35"}, + {file = "brotlicffi-1.1.0.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:ce01c7316aebc7fce59da734286148b1d1b9455f89cf2c8a4dfce7d41db55c2d"}, + {file = "brotlicffi-1.1.0.0-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:246f1d1a90279bb6069de3de8d75a8856e073b8ff0b09dcca18ccc14cec85979"}, + {file = "brotlicffi-1.1.0.0-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cc4bc5d82bc56ebd8b514fb8350cfac4627d6b0743382e46d033976a5f80fab6"}, + {file = "brotlicffi-1.1.0.0-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:37c26ecb14386a44b118ce36e546ce307f4810bc9598a6e6cb4f7fca725ae7e6"}, + {file = "brotlicffi-1.1.0.0-pp37-pypy37_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ca72968ae4eaf6470498d5c2887073f7efe3b1e7d7ec8be11a06a79cc810e990"}, + {file = "brotlicffi-1.1.0.0-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:add0de5b9ad9e9aa293c3aa4e9deb2b61e99ad6c1634e01d01d98c03e6a354cc"}, + {file = "brotlicffi-1.1.0.0-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:9b6068e0f3769992d6b622a1cd2e7835eae3cf8d9da123d7f51ca9c1e9c333e5"}, + {file = "brotlicffi-1.1.0.0-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8557a8559509b61e65083f8782329188a250102372576093c88930c875a69838"}, + {file = "brotlicffi-1.1.0.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2a7ae37e5d79c5bdfb5b4b99f2715a6035e6c5bf538c3746abc8e26694f92f33"}, + {file = "brotlicffi-1.1.0.0-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:391151ec86bb1c683835980f4816272a87eaddc46bb91cbf44f62228b84d8cca"}, + {file = "brotlicffi-1.1.0.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:2f3711be9290f0453de8eed5275d93d286abe26b08ab4a35d7452caa1fef532f"}, + {file = "brotlicffi-1.1.0.0-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:1a807d760763e398bbf2c6394ae9da5815901aa93ee0a37bca5efe78d4ee3171"}, + {file = "brotlicffi-1.1.0.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fa8ca0623b26c94fccc3a1fdd895be1743b838f3917300506d04aa3346fd2a14"}, + {file = "brotlicffi-1.1.0.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3de0cf28a53a3238b252aca9fed1593e9d36c1d116748013339f0949bfc84112"}, + {file = "brotlicffi-1.1.0.0-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6be5ec0e88a4925c91f3dea2bb0013b3a2accda6f77238f76a34a1ea532a1cb0"}, + {file = "brotlicffi-1.1.0.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:d9eb71bb1085d996244439154387266fd23d6ad37161f6f52f1cd41dd95a3808"}, + {file = "brotlicffi-1.1.0.0.tar.gz", hash = "sha256:b77827a689905143f87915310b93b273ab17888fd43ef350d4832c4a71083c13"}, +] + +[package.dependencies] +cffi = ">=1.0.0" + [[package]] name = "certifi" version = "2023.7.22" @@ -409,47 +557,56 @@ files = [ [[package]] name = "cryptography" -version = "41.0.6" +version = "42.0.4" description = "cryptography is a package which provides cryptographic recipes and primitives to Python developers." optional = false python-versions = ">=3.7" files = [ - {file = "cryptography-41.0.6-cp37-abi3-macosx_10_12_universal2.whl", hash = "sha256:0f27acb55a4e77b9be8d550d762b0513ef3fc658cd3eb15110ebbcbd626db12c"}, - {file = "cryptography-41.0.6-cp37-abi3-macosx_10_12_x86_64.whl", hash = "sha256:ae236bb8760c1e55b7a39b6d4d32d2279bc6c7c8500b7d5a13b6fb9fc97be35b"}, - {file = "cryptography-41.0.6-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:afda76d84b053923c27ede5edc1ed7d53e3c9f475ebaf63c68e69f1403c405a8"}, - {file = "cryptography-41.0.6-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:da46e2b5df770070412c46f87bac0849b8d685c5f2679771de277a422c7d0b86"}, - {file = "cryptography-41.0.6-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:ff369dd19e8fe0528b02e8df9f2aeb2479f89b1270d90f96a63500afe9af5cae"}, - {file = "cryptography-41.0.6-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:b648fe2a45e426aaee684ddca2632f62ec4613ef362f4d681a9a6283d10e079d"}, - {file = "cryptography-41.0.6-cp37-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:5daeb18e7886a358064a68dbcaf441c036cbdb7da52ae744e7b9207b04d3908c"}, - {file = "cryptography-41.0.6-cp37-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:068bc551698c234742c40049e46840843f3d98ad7ce265fd2bd4ec0d11306596"}, - {file = "cryptography-41.0.6-cp37-abi3-win32.whl", hash = "sha256:2132d5865eea673fe6712c2ed5fb4fa49dba10768bb4cc798345748380ee3660"}, - {file = "cryptography-41.0.6-cp37-abi3-win_amd64.whl", hash = "sha256:48783b7e2bef51224020efb61b42704207dde583d7e371ef8fc2a5fb6c0aabc7"}, - {file = "cryptography-41.0.6-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:8efb2af8d4ba9dbc9c9dd8f04d19a7abb5b49eab1f3694e7b5a16a5fc2856f5c"}, - {file = "cryptography-41.0.6-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:c5a550dc7a3b50b116323e3d376241829fd326ac47bc195e04eb33a8170902a9"}, - {file = "cryptography-41.0.6-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:85abd057699b98fce40b41737afb234fef05c67e116f6f3650782c10862c43da"}, - {file = "cryptography-41.0.6-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:f39812f70fc5c71a15aa3c97b2bbe213c3f2a460b79bd21c40d033bb34a9bf36"}, - {file = "cryptography-41.0.6-pp38-pypy38_pp73-macosx_10_12_x86_64.whl", hash = "sha256:742ae5e9a2310e9dade7932f9576606836ed174da3c7d26bc3d3ab4bd49b9f65"}, - {file = "cryptography-41.0.6-pp38-pypy38_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:35f3f288e83c3f6f10752467c48919a7a94b7d88cc00b0668372a0d2ad4f8ead"}, - {file = "cryptography-41.0.6-pp38-pypy38_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:4d03186af98b1c01a4eda396b137f29e4e3fb0173e30f885e27acec8823c1b09"}, - {file = "cryptography-41.0.6-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:b27a7fd4229abef715e064269d98a7e2909ebf92eb6912a9603c7e14c181928c"}, - {file = "cryptography-41.0.6-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:398ae1fc711b5eb78e977daa3cbf47cec20f2c08c5da129b7a296055fbb22aed"}, - {file = "cryptography-41.0.6-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:7e00fb556bda398b99b0da289ce7053639d33b572847181d6483ad89835115f6"}, - {file = "cryptography-41.0.6-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:60e746b11b937911dc70d164060d28d273e31853bb359e2b2033c9e93e6f3c43"}, - {file = "cryptography-41.0.6-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:3288acccef021e3c3c10d58933f44e8602cf04dba96d9796d70d537bb2f4bbc4"}, - {file = "cryptography-41.0.6.tar.gz", hash = "sha256:422e3e31d63743855e43e5a6fcc8b4acab860f560f9321b0ee6269cc7ed70cc3"}, + {file = "cryptography-42.0.4-cp37-abi3-macosx_10_12_universal2.whl", hash = "sha256:ffc73996c4fca3d2b6c1c8c12bfd3ad00def8621da24f547626bf06441400449"}, + {file = "cryptography-42.0.4-cp37-abi3-macosx_10_12_x86_64.whl", hash = "sha256:db4b65b02f59035037fde0998974d84244a64c3265bdef32a827ab9b63d61b18"}, + {file = "cryptography-42.0.4-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dad9c385ba8ee025bb0d856714f71d7840020fe176ae0229de618f14dae7a6e2"}, + {file = "cryptography-42.0.4-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:69b22ab6506a3fe483d67d1ed878e1602bdd5912a134e6202c1ec672233241c1"}, + {file = "cryptography-42.0.4-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:e09469a2cec88fb7b078e16d4adec594414397e8879a4341c6ace96013463d5b"}, + {file = "cryptography-42.0.4-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:3e970a2119507d0b104f0a8e281521ad28fc26f2820687b3436b8c9a5fcf20d1"}, + {file = "cryptography-42.0.4-cp37-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:e53dc41cda40b248ebc40b83b31516487f7db95ab8ceac1f042626bc43a2f992"}, + {file = "cryptography-42.0.4-cp37-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:c3a5cbc620e1e17009f30dd34cb0d85c987afd21c41a74352d1719be33380885"}, + {file = "cryptography-42.0.4-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:6bfadd884e7280df24d26f2186e4e07556a05d37393b0f220a840b083dc6a824"}, + {file = "cryptography-42.0.4-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:01911714117642a3f1792c7f376db572aadadbafcd8d75bb527166009c9f1d1b"}, + {file = "cryptography-42.0.4-cp37-abi3-win32.whl", hash = "sha256:fb0cef872d8193e487fc6bdb08559c3aa41b659a7d9be48b2e10747f47863925"}, + {file = "cryptography-42.0.4-cp37-abi3-win_amd64.whl", hash = "sha256:c1f25b252d2c87088abc8bbc4f1ecbf7c919e05508a7e8628e6875c40bc70923"}, + {file = "cryptography-42.0.4-cp39-abi3-macosx_10_12_universal2.whl", hash = "sha256:15a1fb843c48b4a604663fa30af60818cd28f895572386e5f9b8a665874c26e7"}, + {file = "cryptography-42.0.4-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a1327f280c824ff7885bdeef8578f74690e9079267c1c8bd7dc5cc5aa065ae52"}, + {file = "cryptography-42.0.4-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6ffb03d419edcab93b4b19c22ee80c007fb2d708429cecebf1dd3258956a563a"}, + {file = "cryptography-42.0.4-cp39-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:1df6fcbf60560d2113b5ed90f072dc0b108d64750d4cbd46a21ec882c7aefce9"}, + {file = "cryptography-42.0.4-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:44a64043f743485925d3bcac548d05df0f9bb445c5fcca6681889c7c3ab12764"}, + {file = "cryptography-42.0.4-cp39-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:3c6048f217533d89f2f8f4f0fe3044bf0b2090453b7b73d0b77db47b80af8dff"}, + {file = "cryptography-42.0.4-cp39-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:6d0fbe73728c44ca3a241eff9aefe6496ab2656d6e7a4ea2459865f2e8613257"}, + {file = "cryptography-42.0.4-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:887623fe0d70f48ab3f5e4dbf234986b1329a64c066d719432d0698522749929"}, + {file = "cryptography-42.0.4-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:ce8613beaffc7c14f091497346ef117c1798c202b01153a8cc7b8e2ebaaf41c0"}, + {file = "cryptography-42.0.4-cp39-abi3-win32.whl", hash = "sha256:810bcf151caefc03e51a3d61e53335cd5c7316c0a105cc695f0959f2c638b129"}, + {file = "cryptography-42.0.4-cp39-abi3-win_amd64.whl", hash = "sha256:a0298bdc6e98ca21382afe914c642620370ce0470a01e1bef6dd9b5354c36854"}, + {file = "cryptography-42.0.4-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:5f8907fcf57392cd917892ae83708761c6ff3c37a8e835d7246ff0ad251d9298"}, + {file = "cryptography-42.0.4-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:12d341bd42cdb7d4937b0cabbdf2a94f949413ac4504904d0cdbdce4a22cbf88"}, + {file = "cryptography-42.0.4-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:1cdcdbd117681c88d717437ada72bdd5be9de117f96e3f4d50dab3f59fd9ab20"}, + {file = "cryptography-42.0.4-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:0e89f7b84f421c56e7ff69f11c441ebda73b8a8e6488d322ef71746224c20fce"}, + {file = "cryptography-42.0.4-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:f1e85a178384bf19e36779d91ff35c7617c885da487d689b05c1366f9933ad74"}, + {file = "cryptography-42.0.4-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:d2a27aca5597c8a71abbe10209184e1a8e91c1fd470b5070a2ea60cafec35bcd"}, + {file = "cryptography-42.0.4-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:4e36685cb634af55e0677d435d425043967ac2f3790ec652b2b88ad03b85c27b"}, + {file = "cryptography-42.0.4-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:f47be41843200f7faec0683ad751e5ef11b9a56a220d57f300376cd8aba81660"}, + {file = "cryptography-42.0.4.tar.gz", hash = "sha256:831a4b37accef30cccd34fcb916a5d7b5be3cbbe27268a02832c3e450aea39cb"}, ] [package.dependencies] -cffi = ">=1.12" +cffi = {version = ">=1.12", markers = "platform_python_implementation != \"PyPy\""} [package.extras] docs = ["sphinx (>=5.3.0)", "sphinx-rtd-theme (>=1.1.1)"] -docstest = ["pyenchant (>=1.6.11)", "sphinxcontrib-spelling (>=4.0.1)", "twine (>=1.12.0)"] +docstest = ["pyenchant (>=1.6.11)", "readme-renderer", "sphinxcontrib-spelling (>=4.0.1)"] nox = ["nox"] -pep8test = ["black", "check-sdist", "mypy", "ruff"] +pep8test = ["check-sdist", "click", "mypy", "ruff"] sdist = ["build"] ssh = ["bcrypt (>=3.1.5)"] -test = ["pretend", "pytest (>=6.2.0)", "pytest-benchmark", "pytest-cov", "pytest-xdist"] +test = ["certifi", "pretend", "pytest (>=6.2.0)", "pytest-benchmark", "pytest-cov", "pytest-xdist"] test-randomorder = ["pytest-randomly"] [[package]] @@ -566,200 +723,217 @@ SQLAlchemy = ">=0.8.0" [[package]] name = "frozenlist" -version = "1.4.0" +version = "1.4.1" description = "A list-like structure which implements collections.abc.MutableSequence" optional = false python-versions = ">=3.8" files = [ - {file = "frozenlist-1.4.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:764226ceef3125e53ea2cb275000e309c0aa5464d43bd72abd661e27fffc26ab"}, - {file = "frozenlist-1.4.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d6484756b12f40003c6128bfcc3fa9f0d49a687e171186c2d85ec82e3758c559"}, - {file = "frozenlist-1.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9ac08e601308e41eb533f232dbf6b7e4cea762f9f84f6357136eed926c15d12c"}, - {file = "frozenlist-1.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d081f13b095d74b67d550de04df1c756831f3b83dc9881c38985834387487f1b"}, - {file = "frozenlist-1.4.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:71932b597f9895f011f47f17d6428252fc728ba2ae6024e13c3398a087c2cdea"}, - {file = "frozenlist-1.4.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:981b9ab5a0a3178ff413bca62526bb784249421c24ad7381e39d67981be2c326"}, - {file = "frozenlist-1.4.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e41f3de4df3e80de75845d3e743b3f1c4c8613c3997a912dbf0229fc61a8b963"}, - {file = "frozenlist-1.4.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6918d49b1f90821e93069682c06ffde41829c346c66b721e65a5c62b4bab0300"}, - {file = "frozenlist-1.4.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:0e5c8764c7829343d919cc2dfc587a8db01c4f70a4ebbc49abde5d4b158b007b"}, - {file = "frozenlist-1.4.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:8d0edd6b1c7fb94922bf569c9b092ee187a83f03fb1a63076e7774b60f9481a8"}, - {file = "frozenlist-1.4.0-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:e29cda763f752553fa14c68fb2195150bfab22b352572cb36c43c47bedba70eb"}, - {file = "frozenlist-1.4.0-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:0c7c1b47859ee2cac3846fde1c1dc0f15da6cec5a0e5c72d101e0f83dcb67ff9"}, - {file = "frozenlist-1.4.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:901289d524fdd571be1c7be054f48b1f88ce8dddcbdf1ec698b27d4b8b9e5d62"}, - {file = "frozenlist-1.4.0-cp310-cp310-win32.whl", hash = "sha256:1a0848b52815006ea6596c395f87449f693dc419061cc21e970f139d466dc0a0"}, - {file = "frozenlist-1.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:b206646d176a007466358aa21d85cd8600a415c67c9bd15403336c331a10d956"}, - {file = "frozenlist-1.4.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:de343e75f40e972bae1ef6090267f8260c1446a1695e77096db6cfa25e759a95"}, - {file = "frozenlist-1.4.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ad2a9eb6d9839ae241701d0918f54c51365a51407fd80f6b8289e2dfca977cc3"}, - {file = "frozenlist-1.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:bd7bd3b3830247580de99c99ea2a01416dfc3c34471ca1298bccabf86d0ff4dc"}, - {file = "frozenlist-1.4.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bdf1847068c362f16b353163391210269e4f0569a3c166bc6a9f74ccbfc7e839"}, - {file = "frozenlist-1.4.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:38461d02d66de17455072c9ba981d35f1d2a73024bee7790ac2f9e361ef1cd0c"}, - {file = "frozenlist-1.4.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d5a32087d720c608f42caed0ef36d2b3ea61a9d09ee59a5142d6070da9041b8f"}, - {file = "frozenlist-1.4.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dd65632acaf0d47608190a71bfe46b209719bf2beb59507db08ccdbe712f969b"}, - {file = "frozenlist-1.4.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:261b9f5d17cac914531331ff1b1d452125bf5daa05faf73b71d935485b0c510b"}, - {file = "frozenlist-1.4.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:b89ac9768b82205936771f8d2eb3ce88503b1556324c9f903e7156669f521472"}, - {file = "frozenlist-1.4.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:008eb8b31b3ea6896da16c38c1b136cb9fec9e249e77f6211d479db79a4eaf01"}, - {file = "frozenlist-1.4.0-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:e74b0506fa5aa5598ac6a975a12aa8928cbb58e1f5ac8360792ef15de1aa848f"}, - {file = "frozenlist-1.4.0-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:490132667476f6781b4c9458298b0c1cddf237488abd228b0b3650e5ecba7467"}, - {file = "frozenlist-1.4.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:76d4711f6f6d08551a7e9ef28c722f4a50dd0fc204c56b4bcd95c6cc05ce6fbb"}, - {file = "frozenlist-1.4.0-cp311-cp311-win32.whl", hash = "sha256:a02eb8ab2b8f200179b5f62b59757685ae9987996ae549ccf30f983f40602431"}, - {file = "frozenlist-1.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:515e1abc578dd3b275d6a5114030b1330ba044ffba03f94091842852f806f1c1"}, - {file = "frozenlist-1.4.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:f0ed05f5079c708fe74bf9027e95125334b6978bf07fd5ab923e9e55e5fbb9d3"}, - {file = "frozenlist-1.4.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:ca265542ca427bf97aed183c1676e2a9c66942e822b14dc6e5f42e038f92a503"}, - {file = "frozenlist-1.4.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:491e014f5c43656da08958808588cc6c016847b4360e327a62cb308c791bd2d9"}, - {file = "frozenlist-1.4.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:17ae5cd0f333f94f2e03aaf140bb762c64783935cc764ff9c82dff626089bebf"}, - {file = "frozenlist-1.4.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1e78fb68cf9c1a6aa4a9a12e960a5c9dfbdb89b3695197aa7064705662515de2"}, - {file = "frozenlist-1.4.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d5655a942f5f5d2c9ed93d72148226d75369b4f6952680211972a33e59b1dfdc"}, - {file = "frozenlist-1.4.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c11b0746f5d946fecf750428a95f3e9ebe792c1ee3b1e96eeba145dc631a9672"}, - {file = "frozenlist-1.4.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e66d2a64d44d50d2543405fb183a21f76b3b5fd16f130f5c99187c3fb4e64919"}, - {file = "frozenlist-1.4.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:88f7bc0fcca81f985f78dd0fa68d2c75abf8272b1f5c323ea4a01a4d7a614efc"}, - {file = "frozenlist-1.4.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:5833593c25ac59ede40ed4de6d67eb42928cca97f26feea219f21d0ed0959b79"}, - {file = "frozenlist-1.4.0-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:fec520865f42e5c7f050c2a79038897b1c7d1595e907a9e08e3353293ffc948e"}, - {file = "frozenlist-1.4.0-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:b826d97e4276750beca7c8f0f1a4938892697a6bcd8ec8217b3312dad6982781"}, - {file = "frozenlist-1.4.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:ceb6ec0a10c65540421e20ebd29083c50e6d1143278746a4ef6bcf6153171eb8"}, - {file = "frozenlist-1.4.0-cp38-cp38-win32.whl", hash = "sha256:2b8bcf994563466db019fab287ff390fffbfdb4f905fc77bc1c1d604b1c689cc"}, - {file = "frozenlist-1.4.0-cp38-cp38-win_amd64.whl", hash = "sha256:a6c8097e01886188e5be3e6b14e94ab365f384736aa1fca6a0b9e35bd4a30bc7"}, - {file = "frozenlist-1.4.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:6c38721585f285203e4b4132a352eb3daa19121a035f3182e08e437cface44bf"}, - {file = "frozenlist-1.4.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:a0c6da9aee33ff0b1a451e867da0c1f47408112b3391dd43133838339e410963"}, - {file = "frozenlist-1.4.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:93ea75c050c5bb3d98016b4ba2497851eadf0ac154d88a67d7a6816206f6fa7f"}, - {file = "frozenlist-1.4.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f61e2dc5ad442c52b4887f1fdc112f97caeff4d9e6ebe78879364ac59f1663e1"}, - {file = "frozenlist-1.4.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:aa384489fefeb62321b238e64c07ef48398fe80f9e1e6afeff22e140e0850eef"}, - {file = "frozenlist-1.4.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:10ff5faaa22786315ef57097a279b833ecab1a0bfb07d604c9cbb1c4cdc2ed87"}, - {file = "frozenlist-1.4.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:007df07a6e3eb3e33e9a1fe6a9db7af152bbd8a185f9aaa6ece10a3529e3e1c6"}, - {file = "frozenlist-1.4.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f4f399d28478d1f604c2ff9119907af9726aed73680e5ed1ca634d377abb087"}, - {file = "frozenlist-1.4.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:c5374b80521d3d3f2ec5572e05adc94601985cc526fb276d0c8574a6d749f1b3"}, - {file = "frozenlist-1.4.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:ce31ae3e19f3c902de379cf1323d90c649425b86de7bbdf82871b8a2a0615f3d"}, - {file = "frozenlist-1.4.0-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:7211ef110a9194b6042449431e08c4d80c0481e5891e58d429df5899690511c2"}, - {file = "frozenlist-1.4.0-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:556de4430ce324c836789fa4560ca62d1591d2538b8ceb0b4f68fb7b2384a27a"}, - {file = "frozenlist-1.4.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:7645a8e814a3ee34a89c4a372011dcd817964ce8cb273c8ed6119d706e9613e3"}, - {file = "frozenlist-1.4.0-cp39-cp39-win32.whl", hash = "sha256:19488c57c12d4e8095a922f328df3f179c820c212940a498623ed39160bc3c2f"}, - {file = "frozenlist-1.4.0-cp39-cp39-win_amd64.whl", hash = "sha256:6221d84d463fb110bdd7619b69cb43878a11d51cbb9394ae3105d082d5199167"}, - {file = "frozenlist-1.4.0.tar.gz", hash = "sha256:09163bdf0b2907454042edb19f887c6d33806adc71fbd54afc14908bfdc22251"}, + {file = "frozenlist-1.4.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:f9aa1878d1083b276b0196f2dfbe00c9b7e752475ed3b682025ff20c1c1f51ac"}, + {file = "frozenlist-1.4.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:29acab3f66f0f24674b7dc4736477bcd4bc3ad4b896f5f45379a67bce8b96868"}, + {file = "frozenlist-1.4.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:74fb4bee6880b529a0c6560885fce4dc95936920f9f20f53d99a213f7bf66776"}, + {file = "frozenlist-1.4.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:590344787a90ae57d62511dd7c736ed56b428f04cd8c161fcc5e7232c130c69a"}, + {file = "frozenlist-1.4.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:068b63f23b17df8569b7fdca5517edef76171cf3897eb68beb01341131fbd2ad"}, + {file = "frozenlist-1.4.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5c849d495bf5154cd8da18a9eb15db127d4dba2968d88831aff6f0331ea9bd4c"}, + {file = "frozenlist-1.4.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9750cc7fe1ae3b1611bb8cfc3f9ec11d532244235d75901fb6b8e42ce9229dfe"}, + {file = "frozenlist-1.4.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a9b2de4cf0cdd5bd2dee4c4f63a653c61d2408055ab77b151c1957f221cabf2a"}, + {file = "frozenlist-1.4.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:0633c8d5337cb5c77acbccc6357ac49a1770b8c487e5b3505c57b949b4b82e98"}, + {file = "frozenlist-1.4.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:27657df69e8801be6c3638054e202a135c7f299267f1a55ed3a598934f6c0d75"}, + {file = "frozenlist-1.4.1-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:f9a3ea26252bd92f570600098783d1371354d89d5f6b7dfd87359d669f2109b5"}, + {file = "frozenlist-1.4.1-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:4f57dab5fe3407b6c0c1cc907ac98e8a189f9e418f3b6e54d65a718aaafe3950"}, + {file = "frozenlist-1.4.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:e02a0e11cf6597299b9f3bbd3f93d79217cb90cfd1411aec33848b13f5c656cc"}, + {file = "frozenlist-1.4.1-cp310-cp310-win32.whl", hash = "sha256:a828c57f00f729620a442881cc60e57cfcec6842ba38e1b19fd3e47ac0ff8dc1"}, + {file = "frozenlist-1.4.1-cp310-cp310-win_amd64.whl", hash = "sha256:f56e2333dda1fe0f909e7cc59f021eba0d2307bc6f012a1ccf2beca6ba362439"}, + {file = "frozenlist-1.4.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:a0cb6f11204443f27a1628b0e460f37fb30f624be6051d490fa7d7e26d4af3d0"}, + {file = "frozenlist-1.4.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:b46c8ae3a8f1f41a0d2ef350c0b6e65822d80772fe46b653ab6b6274f61d4a49"}, + {file = "frozenlist-1.4.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:fde5bd59ab5357e3853313127f4d3565fc7dad314a74d7b5d43c22c6a5ed2ced"}, + {file = "frozenlist-1.4.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:722e1124aec435320ae01ee3ac7bec11a5d47f25d0ed6328f2273d287bc3abb0"}, + {file = "frozenlist-1.4.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2471c201b70d58a0f0c1f91261542a03d9a5e088ed3dc6c160d614c01649c106"}, + {file = "frozenlist-1.4.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c757a9dd70d72b076d6f68efdbb9bc943665ae954dad2801b874c8c69e185068"}, + {file = "frozenlist-1.4.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f146e0911cb2f1da549fc58fc7bcd2b836a44b79ef871980d605ec392ff6b0d2"}, + {file = "frozenlist-1.4.1-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4f9c515e7914626b2a2e1e311794b4c35720a0be87af52b79ff8e1429fc25f19"}, + {file = "frozenlist-1.4.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:c302220494f5c1ebeb0912ea782bcd5e2f8308037b3c7553fad0e48ebad6ad82"}, + {file = "frozenlist-1.4.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:442acde1e068288a4ba7acfe05f5f343e19fac87bfc96d89eb886b0363e977ec"}, + {file = "frozenlist-1.4.1-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:1b280e6507ea8a4fa0c0a7150b4e526a8d113989e28eaaef946cc77ffd7efc0a"}, + {file = "frozenlist-1.4.1-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:fe1a06da377e3a1062ae5fe0926e12b84eceb8a50b350ddca72dc85015873f74"}, + {file = "frozenlist-1.4.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:db9e724bebd621d9beca794f2a4ff1d26eed5965b004a97f1f1685a173b869c2"}, + {file = "frozenlist-1.4.1-cp311-cp311-win32.whl", hash = "sha256:e774d53b1a477a67838a904131c4b0eef6b3d8a651f8b138b04f748fccfefe17"}, + {file = "frozenlist-1.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:fb3c2db03683b5767dedb5769b8a40ebb47d6f7f45b1b3e3b4b51ec8ad9d9825"}, + {file = "frozenlist-1.4.1-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:1979bc0aeb89b33b588c51c54ab0161791149f2461ea7c7c946d95d5f93b56ae"}, + {file = "frozenlist-1.4.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:cc7b01b3754ea68a62bd77ce6020afaffb44a590c2289089289363472d13aedb"}, + {file = "frozenlist-1.4.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:c9c92be9fd329ac801cc420e08452b70e7aeab94ea4233a4804f0915c14eba9b"}, + {file = "frozenlist-1.4.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5c3894db91f5a489fc8fa6a9991820f368f0b3cbdb9cd8849547ccfab3392d86"}, + {file = "frozenlist-1.4.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ba60bb19387e13597fb059f32cd4d59445d7b18b69a745b8f8e5db0346f33480"}, + {file = "frozenlist-1.4.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8aefbba5f69d42246543407ed2461db31006b0f76c4e32dfd6f42215a2c41d09"}, + {file = "frozenlist-1.4.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:780d3a35680ced9ce682fbcf4cb9c2bad3136eeff760ab33707b71db84664e3a"}, + {file = "frozenlist-1.4.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9acbb16f06fe7f52f441bb6f413ebae6c37baa6ef9edd49cdd567216da8600cd"}, + {file = "frozenlist-1.4.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:23b701e65c7b36e4bf15546a89279bd4d8675faabc287d06bbcfac7d3c33e1e6"}, + {file = "frozenlist-1.4.1-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:3e0153a805a98f5ada7e09826255ba99fb4f7524bb81bf6b47fb702666484ae1"}, + {file = "frozenlist-1.4.1-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:dd9b1baec094d91bf36ec729445f7769d0d0cf6b64d04d86e45baf89e2b9059b"}, + {file = "frozenlist-1.4.1-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:1a4471094e146b6790f61b98616ab8e44f72661879cc63fa1049d13ef711e71e"}, + {file = "frozenlist-1.4.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:5667ed53d68d91920defdf4035d1cdaa3c3121dc0b113255124bcfada1cfa1b8"}, + {file = "frozenlist-1.4.1-cp312-cp312-win32.whl", hash = "sha256:beee944ae828747fd7cb216a70f120767fc9f4f00bacae8543c14a6831673f89"}, + {file = "frozenlist-1.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:64536573d0a2cb6e625cf309984e2d873979709f2cf22839bf2d61790b448ad5"}, + {file = "frozenlist-1.4.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:20b51fa3f588ff2fe658663db52a41a4f7aa6c04f6201449c6c7c476bd255c0d"}, + {file = "frozenlist-1.4.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:410478a0c562d1a5bcc2f7ea448359fcb050ed48b3c6f6f4f18c313a9bdb1826"}, + {file = "frozenlist-1.4.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:c6321c9efe29975232da3bd0af0ad216800a47e93d763ce64f291917a381b8eb"}, + {file = "frozenlist-1.4.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:48f6a4533887e189dae092f1cf981f2e3885175f7a0f33c91fb5b7b682b6bab6"}, + {file = "frozenlist-1.4.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6eb73fa5426ea69ee0e012fb59cdc76a15b1283d6e32e4f8dc4482ec67d1194d"}, + {file = "frozenlist-1.4.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:fbeb989b5cc29e8daf7f976b421c220f1b8c731cbf22b9130d8815418ea45887"}, + {file = "frozenlist-1.4.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:32453c1de775c889eb4e22f1197fe3bdfe457d16476ea407472b9442e6295f7a"}, + {file = "frozenlist-1.4.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:693945278a31f2086d9bf3df0fe8254bbeaef1fe71e1351c3bd730aa7d31c41b"}, + {file = "frozenlist-1.4.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:1d0ce09d36d53bbbe566fe296965b23b961764c0bcf3ce2fa45f463745c04701"}, + {file = "frozenlist-1.4.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:3a670dc61eb0d0eb7080890c13de3066790f9049b47b0de04007090807c776b0"}, + {file = "frozenlist-1.4.1-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:dca69045298ce5c11fd539682cff879cc1e664c245d1c64da929813e54241d11"}, + {file = "frozenlist-1.4.1-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:a06339f38e9ed3a64e4c4e43aec7f59084033647f908e4259d279a52d3757d09"}, + {file = "frozenlist-1.4.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:b7f2f9f912dca3934c1baec2e4585a674ef16fe00218d833856408c48d5beee7"}, + {file = "frozenlist-1.4.1-cp38-cp38-win32.whl", hash = "sha256:e7004be74cbb7d9f34553a5ce5fb08be14fb33bc86f332fb71cbe5216362a497"}, + {file = "frozenlist-1.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:5a7d70357e7cee13f470c7883a063aae5fe209a493c57d86eb7f5a6f910fae09"}, + {file = "frozenlist-1.4.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:bfa4a17e17ce9abf47a74ae02f32d014c5e9404b6d9ac7f729e01562bbee601e"}, + {file = "frozenlist-1.4.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:b7e3ed87d4138356775346e6845cccbe66cd9e207f3cd11d2f0b9fd13681359d"}, + {file = "frozenlist-1.4.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c99169d4ff810155ca50b4da3b075cbde79752443117d89429595c2e8e37fed8"}, + {file = "frozenlist-1.4.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:edb678da49d9f72c9f6c609fbe41a5dfb9a9282f9e6a2253d5a91e0fc382d7c0"}, + {file = "frozenlist-1.4.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6db4667b187a6742b33afbbaf05a7bc551ffcf1ced0000a571aedbb4aa42fc7b"}, + {file = "frozenlist-1.4.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:55fdc093b5a3cb41d420884cdaf37a1e74c3c37a31f46e66286d9145d2063bd0"}, + {file = "frozenlist-1.4.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:82e8211d69a4f4bc360ea22cd6555f8e61a1bd211d1d5d39d3d228b48c83a897"}, + {file = "frozenlist-1.4.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:89aa2c2eeb20957be2d950b85974b30a01a762f3308cd02bb15e1ad632e22dc7"}, + {file = "frozenlist-1.4.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:9d3e0c25a2350080e9319724dede4f31f43a6c9779be48021a7f4ebde8b2d742"}, + {file = "frozenlist-1.4.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:7268252af60904bf52c26173cbadc3a071cece75f873705419c8681f24d3edea"}, + {file = "frozenlist-1.4.1-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:0c250a29735d4f15321007fb02865f0e6b6a41a6b88f1f523ca1596ab5f50bd5"}, + {file = "frozenlist-1.4.1-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:96ec70beabbd3b10e8bfe52616a13561e58fe84c0101dd031dc78f250d5128b9"}, + {file = "frozenlist-1.4.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:23b2d7679b73fe0e5a4560b672a39f98dfc6f60df63823b0a9970525325b95f6"}, + {file = "frozenlist-1.4.1-cp39-cp39-win32.whl", hash = "sha256:a7496bfe1da7fb1a4e1cc23bb67c58fab69311cc7d32b5a99c2007b4b2a0e932"}, + {file = "frozenlist-1.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:e6a20a581f9ce92d389a8c7d7c3dd47c81fd5d6e655c8dddf341e14aa48659d0"}, + {file = "frozenlist-1.4.1-py3-none-any.whl", hash = "sha256:04ced3e6a46b4cfffe20f9ae482818e34eba9b5fb0ce4056e4cc9b6e212d09b7"}, + {file = "frozenlist-1.4.1.tar.gz", hash = "sha256:c037a86e8513059a2613aaba4d817bb90b9d9b6b69aace3ce9c877e8c8ed402b"}, ] [[package]] name = "greenlet" -version = "3.0.1" +version = "3.0.3" description = "Lightweight in-process concurrent programming" optional = false python-versions = ">=3.7" files = [ - {file = "greenlet-3.0.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:f89e21afe925fcfa655965ca8ea10f24773a1791400989ff32f467badfe4a064"}, - {file = "greenlet-3.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:28e89e232c7593d33cac35425b58950789962011cc274aa43ef8865f2e11f46d"}, - {file = "greenlet-3.0.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b8ba29306c5de7717b5761b9ea74f9c72b9e2b834e24aa984da99cbfc70157fd"}, - {file = "greenlet-3.0.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:19bbdf1cce0346ef7341705d71e2ecf6f41a35c311137f29b8a2dc2341374565"}, - {file = "greenlet-3.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:599daf06ea59bfedbec564b1692b0166a0045f32b6f0933b0dd4df59a854caf2"}, - {file = "greenlet-3.0.1-cp310-cp310-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b641161c302efbb860ae6b081f406839a8b7d5573f20a455539823802c655f63"}, - {file = "greenlet-3.0.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:d57e20ba591727da0c230ab2c3f200ac9d6d333860d85348816e1dca4cc4792e"}, - {file = "greenlet-3.0.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:5805e71e5b570d490938d55552f5a9e10f477c19400c38bf1d5190d760691846"}, - {file = "greenlet-3.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:52e93b28db27ae7d208748f45d2db8a7b6a380e0d703f099c949d0f0d80b70e9"}, - {file = "greenlet-3.0.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:f7bfb769f7efa0eefcd039dd19d843a4fbfbac52f1878b1da2ed5793ec9b1a65"}, - {file = "greenlet-3.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:91e6c7db42638dc45cf2e13c73be16bf83179f7859b07cfc139518941320be96"}, - {file = "greenlet-3.0.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1757936efea16e3f03db20efd0cd50a1c86b06734f9f7338a90c4ba85ec2ad5a"}, - {file = "greenlet-3.0.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:19075157a10055759066854a973b3d1325d964d498a805bb68a1f9af4aaef8ec"}, - {file = "greenlet-3.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e9d21aaa84557d64209af04ff48e0ad5e28c5cca67ce43444e939579d085da72"}, - {file = "greenlet-3.0.1-cp311-cp311-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2847e5d7beedb8d614186962c3d774d40d3374d580d2cbdab7f184580a39d234"}, - {file = "greenlet-3.0.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:97e7ac860d64e2dcba5c5944cfc8fa9ea185cd84061c623536154d5a89237884"}, - {file = "greenlet-3.0.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:b2c02d2ad98116e914d4f3155ffc905fd0c025d901ead3f6ed07385e19122c94"}, - {file = "greenlet-3.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:22f79120a24aeeae2b4471c711dcf4f8c736a2bb2fabad2a67ac9a55ea72523c"}, - {file = "greenlet-3.0.1-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:100f78a29707ca1525ea47388cec8a049405147719f47ebf3895e7509c6446aa"}, - {file = "greenlet-3.0.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:60d5772e8195f4e9ebf74046a9121bbb90090f6550f81d8956a05387ba139353"}, - {file = "greenlet-3.0.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:daa7197b43c707462f06d2c693ffdbb5991cbb8b80b5b984007de431493a319c"}, - {file = "greenlet-3.0.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ea6b8aa9e08eea388c5f7a276fabb1d4b6b9d6e4ceb12cc477c3d352001768a9"}, - {file = "greenlet-3.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8d11ebbd679e927593978aa44c10fc2092bc454b7d13fdc958d3e9d508aba7d0"}, - {file = "greenlet-3.0.1-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:dbd4c177afb8a8d9ba348d925b0b67246147af806f0b104af4d24f144d461cd5"}, - {file = "greenlet-3.0.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:20107edf7c2c3644c67c12205dc60b1bb11d26b2610b276f97d666110d1b511d"}, - {file = "greenlet-3.0.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8bef097455dea90ffe855286926ae02d8faa335ed8e4067326257cb571fc1445"}, - {file = "greenlet-3.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:b2d3337dcfaa99698aa2377c81c9ca72fcd89c07e7eb62ece3f23a3fe89b2ce4"}, - {file = "greenlet-3.0.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:80ac992f25d10aaebe1ee15df45ca0d7571d0f70b645c08ec68733fb7a020206"}, - {file = "greenlet-3.0.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:337322096d92808f76ad26061a8f5fccb22b0809bea39212cd6c406f6a7060d2"}, - {file = "greenlet-3.0.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b9934adbd0f6e476f0ecff3c94626529f344f57b38c9a541f87098710b18af0a"}, - {file = "greenlet-3.0.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dc4d815b794fd8868c4d67602692c21bf5293a75e4b607bb92a11e821e2b859a"}, - {file = "greenlet-3.0.1-cp37-cp37m-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:41bdeeb552d814bcd7fb52172b304898a35818107cc8778b5101423c9017b3de"}, - {file = "greenlet-3.0.1-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:6e6061bf1e9565c29002e3c601cf68569c450be7fc3f7336671af7ddb4657166"}, - {file = "greenlet-3.0.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:fa24255ae3c0ab67e613556375a4341af04a084bd58764731972bcbc8baeba36"}, - {file = "greenlet-3.0.1-cp37-cp37m-win32.whl", hash = "sha256:b489c36d1327868d207002391f662a1d163bdc8daf10ab2e5f6e41b9b96de3b1"}, - {file = "greenlet-3.0.1-cp37-cp37m-win_amd64.whl", hash = "sha256:f33f3258aae89da191c6ebaa3bc517c6c4cbc9b9f689e5d8452f7aedbb913fa8"}, - {file = "greenlet-3.0.1-cp38-cp38-macosx_11_0_universal2.whl", hash = "sha256:d2905ce1df400360463c772b55d8e2518d0e488a87cdea13dd2c71dcb2a1fa16"}, - {file = "greenlet-3.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0a02d259510b3630f330c86557331a3b0e0c79dac3d166e449a39363beaae174"}, - {file = "greenlet-3.0.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:55d62807f1c5a1682075c62436702aaba941daa316e9161e4b6ccebbbf38bda3"}, - {file = "greenlet-3.0.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3fcc780ae8edbb1d050d920ab44790201f027d59fdbd21362340a85c79066a74"}, - {file = "greenlet-3.0.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4eddd98afc726f8aee1948858aed9e6feeb1758889dfd869072d4465973f6bfd"}, - {file = "greenlet-3.0.1-cp38-cp38-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:eabe7090db68c981fca689299c2d116400b553f4b713266b130cfc9e2aa9c5a9"}, - {file = "greenlet-3.0.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:f2f6d303f3dee132b322a14cd8765287b8f86cdc10d2cb6a6fae234ea488888e"}, - {file = "greenlet-3.0.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d923ff276f1c1f9680d32832f8d6c040fe9306cbfb5d161b0911e9634be9ef0a"}, - {file = "greenlet-3.0.1-cp38-cp38-win32.whl", hash = "sha256:0b6f9f8ca7093fd4433472fd99b5650f8a26dcd8ba410e14094c1e44cd3ceddd"}, - {file = "greenlet-3.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:990066bff27c4fcf3b69382b86f4c99b3652bab2a7e685d968cd4d0cfc6f67c6"}, - {file = "greenlet-3.0.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:ce85c43ae54845272f6f9cd8320d034d7a946e9773c693b27d620edec825e376"}, - {file = "greenlet-3.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:89ee2e967bd7ff85d84a2de09df10e021c9b38c7d91dead95b406ed6350c6997"}, - {file = "greenlet-3.0.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:87c8ceb0cf8a5a51b8008b643844b7f4a8264a2c13fcbcd8a8316161725383fe"}, - {file = "greenlet-3.0.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d6a8c9d4f8692917a3dc7eb25a6fb337bff86909febe2f793ec1928cd97bedfc"}, - {file = "greenlet-3.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9fbc5b8f3dfe24784cee8ce0be3da2d8a79e46a276593db6868382d9c50d97b1"}, - {file = "greenlet-3.0.1-cp39-cp39-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:85d2b77e7c9382f004b41d9c72c85537fac834fb141b0296942d52bf03fe4a3d"}, - {file = "greenlet-3.0.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:696d8e7d82398e810f2b3622b24e87906763b6ebfd90e361e88eb85b0e554dc8"}, - {file = "greenlet-3.0.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:329c5a2e5a0ee942f2992c5e3ff40be03e75f745f48847f118a3cfece7a28546"}, - {file = "greenlet-3.0.1-cp39-cp39-win32.whl", hash = "sha256:cf868e08690cb89360eebc73ba4be7fb461cfbc6168dd88e2fbbe6f31812cd57"}, - {file = "greenlet-3.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:ac4a39d1abae48184d420aa8e5e63efd1b75c8444dd95daa3e03f6c6310e9619"}, - {file = "greenlet-3.0.1.tar.gz", hash = "sha256:816bd9488a94cba78d93e1abb58000e8266fa9cc2aa9ccdd6eb0696acb24005b"}, + {file = "greenlet-3.0.3-cp310-cp310-macosx_11_0_universal2.whl", hash = "sha256:9da2bd29ed9e4f15955dd1595ad7bc9320308a3b766ef7f837e23ad4b4aac31a"}, + {file = "greenlet-3.0.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d353cadd6083fdb056bb46ed07e4340b0869c305c8ca54ef9da3421acbdf6881"}, + {file = "greenlet-3.0.3-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dca1e2f3ca00b84a396bc1bce13dd21f680f035314d2379c4160c98153b2059b"}, + {file = "greenlet-3.0.3-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3ed7fb269f15dc662787f4119ec300ad0702fa1b19d2135a37c2c4de6fadfd4a"}, + {file = "greenlet-3.0.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd4f49ae60e10adbc94b45c0b5e6a179acc1736cf7a90160b404076ee283cf83"}, + {file = "greenlet-3.0.3-cp310-cp310-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:73a411ef564e0e097dbe7e866bb2dda0f027e072b04da387282b02c308807405"}, + {file = "greenlet-3.0.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:7f362975f2d179f9e26928c5b517524e89dd48530a0202570d55ad6ca5d8a56f"}, + {file = "greenlet-3.0.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:649dde7de1a5eceb258f9cb00bdf50e978c9db1b996964cd80703614c86495eb"}, + {file = "greenlet-3.0.3-cp310-cp310-win_amd64.whl", hash = "sha256:68834da854554926fbedd38c76e60c4a2e3198c6fbed520b106a8986445caaf9"}, + {file = "greenlet-3.0.3-cp311-cp311-macosx_11_0_universal2.whl", hash = "sha256:b1b5667cced97081bf57b8fa1d6bfca67814b0afd38208d52538316e9422fc61"}, + {file = "greenlet-3.0.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:52f59dd9c96ad2fc0d5724107444f76eb20aaccb675bf825df6435acb7703559"}, + {file = "greenlet-3.0.3-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:afaff6cf5200befd5cec055b07d1c0a5a06c040fe5ad148abcd11ba6ab9b114e"}, + {file = "greenlet-3.0.3-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:fe754d231288e1e64323cfad462fcee8f0288654c10bdf4f603a39ed923bef33"}, + {file = "greenlet-3.0.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2797aa5aedac23af156bbb5a6aa2cd3427ada2972c828244eb7d1b9255846379"}, + {file = "greenlet-3.0.3-cp311-cp311-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b7f009caad047246ed379e1c4dbcb8b020f0a390667ea74d2387be2998f58a22"}, + {file = "greenlet-3.0.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:c5e1536de2aad7bf62e27baf79225d0d64360d4168cf2e6becb91baf1ed074f3"}, + {file = "greenlet-3.0.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:894393ce10ceac937e56ec00bb71c4c2f8209ad516e96033e4b3b1de270e200d"}, + {file = "greenlet-3.0.3-cp311-cp311-win_amd64.whl", hash = "sha256:1ea188d4f49089fc6fb283845ab18a2518d279c7cd9da1065d7a84e991748728"}, + {file = "greenlet-3.0.3-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:70fb482fdf2c707765ab5f0b6655e9cfcf3780d8d87355a063547b41177599be"}, + {file = "greenlet-3.0.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d4d1ac74f5c0c0524e4a24335350edad7e5f03b9532da7ea4d3c54d527784f2e"}, + {file = "greenlet-3.0.3-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:149e94a2dd82d19838fe4b2259f1b6b9957d5ba1b25640d2380bea9c5df37676"}, + {file = "greenlet-3.0.3-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:15d79dd26056573940fcb8c7413d84118086f2ec1a8acdfa854631084393efcc"}, + {file = "greenlet-3.0.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:881b7db1ebff4ba09aaaeae6aa491daeb226c8150fc20e836ad00041bcb11230"}, + {file = "greenlet-3.0.3-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fcd2469d6a2cf298f198f0487e0a5b1a47a42ca0fa4dfd1b6862c999f018ebbf"}, + {file = "greenlet-3.0.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:1f672519db1796ca0d8753f9e78ec02355e862d0998193038c7073045899f305"}, + {file = "greenlet-3.0.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:2516a9957eed41dd8f1ec0c604f1cdc86758b587d964668b5b196a9db5bfcde6"}, + {file = "greenlet-3.0.3-cp312-cp312-win_amd64.whl", hash = "sha256:bba5387a6975598857d86de9eac14210a49d554a77eb8261cc68b7d082f78ce2"}, + {file = "greenlet-3.0.3-cp37-cp37m-macosx_11_0_universal2.whl", hash = "sha256:5b51e85cb5ceda94e79d019ed36b35386e8c37d22f07d6a751cb659b180d5274"}, + {file = "greenlet-3.0.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:daf3cb43b7cf2ba96d614252ce1684c1bccee6b2183a01328c98d36fcd7d5cb0"}, + {file = "greenlet-3.0.3-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:99bf650dc5d69546e076f413a87481ee1d2d09aaaaaca058c9251b6d8c14783f"}, + {file = "greenlet-3.0.3-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2dd6e660effd852586b6a8478a1d244b8dc90ab5b1321751d2ea15deb49ed414"}, + {file = "greenlet-3.0.3-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e3391d1e16e2a5a1507d83e4a8b100f4ee626e8eca43cf2cadb543de69827c4c"}, + {file = "greenlet-3.0.3-cp37-cp37m-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e1f145462f1fa6e4a4ae3c0f782e580ce44d57c8f2c7aae1b6fa88c0b2efdb41"}, + {file = "greenlet-3.0.3-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:1a7191e42732df52cb5f39d3527217e7ab73cae2cb3694d241e18f53d84ea9a7"}, + {file = "greenlet-3.0.3-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:0448abc479fab28b00cb472d278828b3ccca164531daab4e970a0458786055d6"}, + {file = "greenlet-3.0.3-cp37-cp37m-win32.whl", hash = "sha256:b542be2440edc2d48547b5923c408cbe0fc94afb9f18741faa6ae970dbcb9b6d"}, + {file = "greenlet-3.0.3-cp37-cp37m-win_amd64.whl", hash = "sha256:01bc7ea167cf943b4c802068e178bbf70ae2e8c080467070d01bfa02f337ee67"}, + {file = "greenlet-3.0.3-cp38-cp38-macosx_11_0_universal2.whl", hash = "sha256:1996cb9306c8595335bb157d133daf5cf9f693ef413e7673cb07e3e5871379ca"}, + {file = "greenlet-3.0.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3ddc0f794e6ad661e321caa8d2f0a55ce01213c74722587256fb6566049a8b04"}, + {file = "greenlet-3.0.3-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c9db1c18f0eaad2f804728c67d6c610778456e3e1cc4ab4bbd5eeb8e6053c6fc"}, + {file = "greenlet-3.0.3-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7170375bcc99f1a2fbd9c306f5be8764eaf3ac6b5cb968862cad4c7057756506"}, + {file = "greenlet-3.0.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6b66c9c1e7ccabad3a7d037b2bcb740122a7b17a53734b7d72a344ce39882a1b"}, + {file = "greenlet-3.0.3-cp38-cp38-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:098d86f528c855ead3479afe84b49242e174ed262456c342d70fc7f972bc13c4"}, + {file = "greenlet-3.0.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:81bb9c6d52e8321f09c3d165b2a78c680506d9af285bfccbad9fb7ad5a5da3e5"}, + {file = "greenlet-3.0.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:fd096eb7ffef17c456cfa587523c5f92321ae02427ff955bebe9e3c63bc9f0da"}, + {file = "greenlet-3.0.3-cp38-cp38-win32.whl", hash = "sha256:d46677c85c5ba00a9cb6f7a00b2bfa6f812192d2c9f7d9c4f6a55b60216712f3"}, + {file = "greenlet-3.0.3-cp38-cp38-win_amd64.whl", hash = "sha256:419b386f84949bf0e7c73e6032e3457b82a787c1ab4a0e43732898a761cc9dbf"}, + {file = "greenlet-3.0.3-cp39-cp39-macosx_11_0_universal2.whl", hash = "sha256:da70d4d51c8b306bb7a031d5cff6cc25ad253affe89b70352af5f1cb68e74b53"}, + {file = "greenlet-3.0.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:086152f8fbc5955df88382e8a75984e2bb1c892ad2e3c80a2508954e52295257"}, + {file = "greenlet-3.0.3-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d73a9fe764d77f87f8ec26a0c85144d6a951a6c438dfe50487df5595c6373eac"}, + {file = "greenlet-3.0.3-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b7dcbe92cc99f08c8dd11f930de4d99ef756c3591a5377d1d9cd7dd5e896da71"}, + {file = "greenlet-3.0.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1551a8195c0d4a68fac7a4325efac0d541b48def35feb49d803674ac32582f61"}, + {file = "greenlet-3.0.3-cp39-cp39-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:64d7675ad83578e3fc149b617a444fab8efdafc9385471f868eb5ff83e446b8b"}, + {file = "greenlet-3.0.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:b37eef18ea55f2ffd8f00ff8fe7c8d3818abd3e25fb73fae2ca3b672e333a7a6"}, + {file = "greenlet-3.0.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:77457465d89b8263bca14759d7c1684df840b6811b2499838cc5b040a8b5b113"}, + {file = "greenlet-3.0.3-cp39-cp39-win32.whl", hash = "sha256:57e8974f23e47dac22b83436bdcf23080ade568ce77df33159e019d161ce1d1e"}, + {file = "greenlet-3.0.3-cp39-cp39-win_amd64.whl", hash = "sha256:c5ee858cfe08f34712f548c3c363e807e7186f03ad7a5039ebadb29e8c6be067"}, + {file = "greenlet-3.0.3.tar.gz", hash = "sha256:43374442353259554ce33599da8b692d5aa96f8976d567d4badf263371fbe491"}, ] [package.extras] -docs = ["Sphinx"] +docs = ["Sphinx", "furo"] test = ["objgraph", "psutil"] [[package]] name = "grpcio" -version = "1.53.0" +version = "1.53.2" description = "HTTP/2-based RPC framework" optional = false python-versions = ">=3.7" files = [ - {file = "grpcio-1.53.0-cp310-cp310-linux_armv7l.whl", hash = "sha256:752d2949b40e12e6ad3ed8cc552a65b54d226504f6b1fb67cab2ccee502cc06f"}, - {file = "grpcio-1.53.0-cp310-cp310-macosx_12_0_universal2.whl", hash = "sha256:8a48fd3a7222be226bb86b7b413ad248f17f3101a524018cdc4562eeae1eb2a3"}, - {file = "grpcio-1.53.0-cp310-cp310-manylinux_2_17_aarch64.whl", hash = "sha256:f3e837d29f0e1b9d6e7b29d569e2e9b0da61889e41879832ea15569c251c303a"}, - {file = "grpcio-1.53.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:aef7d30242409c3aa5839b501e877e453a2c8d3759ca8230dd5a21cda029f046"}, - {file = "grpcio-1.53.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e6f90698b5d1c5dd7b3236cd1fa959d7b80e17923f918d5be020b65f1c78b173"}, - {file = "grpcio-1.53.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:a96c3c7f564b263c5d7c0e49a337166c8611e89c4c919f66dba7b9a84abad137"}, - {file = "grpcio-1.53.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:ee81349411648d1abc94095c68cd25e3c2812e4e0367f9a9355be1e804a5135c"}, - {file = "grpcio-1.53.0-cp310-cp310-win32.whl", hash = "sha256:fdc6191587de410a184550d4143e2b24a14df495c86ca15e59508710681690ac"}, - {file = "grpcio-1.53.0-cp310-cp310-win_amd64.whl", hash = "sha256:658ffe1e39171be00490db5bd3b966f79634ac4215a1eb9a85c6cd6783bf7f6e"}, - {file = "grpcio-1.53.0-cp311-cp311-linux_armv7l.whl", hash = "sha256:1b172e6d497191940c4b8d75b53de82dc252e15b61de2951d577ec5b43316b29"}, - {file = "grpcio-1.53.0-cp311-cp311-macosx_10_10_universal2.whl", hash = "sha256:82434ba3a5935e47908bc861ce1ebc43c2edfc1001d235d6e31e5d3ed55815f7"}, - {file = "grpcio-1.53.0-cp311-cp311-manylinux_2_17_aarch64.whl", hash = "sha256:1c734a2d4843e4e14ececf5600c3c4750990ec319e1299db7e4f0d02c25c1467"}, - {file = "grpcio-1.53.0-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b6a2ead3de3b2d53119d473aa2f224030257ef33af1e4ddabd4afee1dea5f04c"}, - {file = "grpcio-1.53.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a34d6e905f071f9b945cabbcc776e2055de1fdb59cd13683d9aa0a8f265b5bf9"}, - {file = "grpcio-1.53.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:eaf8e3b97caaf9415227a3c6ca5aa8d800fecadd526538d2bf8f11af783f1550"}, - {file = "grpcio-1.53.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:da95778d37be8e4e9afca771a83424f892296f5dfb2a100eda2571a1d8bbc0dc"}, - {file = "grpcio-1.53.0-cp311-cp311-win32.whl", hash = "sha256:e4f513d63df6336fd84b74b701f17d1bb3b64e9d78a6ed5b5e8a198bbbe8bbfa"}, - {file = "grpcio-1.53.0-cp311-cp311-win_amd64.whl", hash = "sha256:ddb2511fbbb440ed9e5c9a4b9b870f2ed649b7715859fd6f2ebc585ee85c0364"}, - {file = "grpcio-1.53.0-cp37-cp37m-linux_armv7l.whl", hash = "sha256:2a912397eb8d23c177d6d64e3c8bc46b8a1c7680b090d9f13a640b104aaec77c"}, - {file = "grpcio-1.53.0-cp37-cp37m-macosx_10_10_universal2.whl", hash = "sha256:55930c56b8f5b347d6c8c609cc341949a97e176c90f5cbb01d148d778f3bbd23"}, - {file = "grpcio-1.53.0-cp37-cp37m-manylinux_2_17_aarch64.whl", hash = "sha256:6601d812105583948ab9c6e403a7e2dba6e387cc678c010e74f2d6d589d1d1b3"}, - {file = "grpcio-1.53.0-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c705e0c21acb0e8478a00e7e773ad0ecdb34bd0e4adc282d3d2f51ba3961aac7"}, - {file = "grpcio-1.53.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba074af9ca268ad7b05d3fc2b920b5fb3c083da94ab63637aaf67f4f71ecb755"}, - {file = "grpcio-1.53.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:14817de09317dd7d3fbc8272864288320739973ef0f4b56bf2c0032349da8cdf"}, - {file = "grpcio-1.53.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:c7ad9fbedb93f331c2e9054e202e95cf825b885811f1bcbbdfdc301e451442db"}, - {file = "grpcio-1.53.0-cp37-cp37m-win_amd64.whl", hash = "sha256:dad5b302a4c21c604d88a5d441973f320134e6ff6a84ecef9c1139e5ffd466f6"}, - {file = "grpcio-1.53.0-cp38-cp38-linux_armv7l.whl", hash = "sha256:fa8eaac75d3107e3f5465f2c9e3bbd13db21790c6e45b7de1756eba16b050aca"}, - {file = "grpcio-1.53.0-cp38-cp38-macosx_10_10_universal2.whl", hash = "sha256:104a2210edd3776c38448b4f76c2f16e527adafbde171fc72a8a32976c20abc7"}, - {file = "grpcio-1.53.0-cp38-cp38-manylinux_2_17_aarch64.whl", hash = "sha256:dbc1ba968639c1d23476f75c356e549e7bbf2d8d6688717dcab5290e88e8482b"}, - {file = "grpcio-1.53.0-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:95952d3fe795b06af29bb8ec7bbf3342cdd867fc17b77cc25e6733d23fa6c519"}, - {file = "grpcio-1.53.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f144a790f14c51b8a8e591eb5af40507ffee45ea6b818c2482f0457fec2e1a2e"}, - {file = "grpcio-1.53.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:0698c094688a2dd4c7c2f2c0e3e142cac439a64d1cef6904c97f6cde38ba422f"}, - {file = "grpcio-1.53.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:6b6d60b0958be711bab047e9f4df5dbbc40367955f8651232bfdcdd21450b9ab"}, - {file = "grpcio-1.53.0-cp38-cp38-win32.whl", hash = "sha256:1948539ce78805d4e6256ab0e048ec793956d54787dc9d6777df71c1d19c7f81"}, - {file = "grpcio-1.53.0-cp38-cp38-win_amd64.whl", hash = "sha256:df9ba1183b3f649210788cf80c239041dddcb375d6142d8bccafcfdf549522cd"}, - {file = "grpcio-1.53.0-cp39-cp39-linux_armv7l.whl", hash = "sha256:19caa5b7282a89b799e63776ff602bb39604f7ca98db6df27e2de06756ae86c3"}, - {file = "grpcio-1.53.0-cp39-cp39-macosx_10_10_universal2.whl", hash = "sha256:b5bd026ac928c96cc23149e6ef79183125542062eb6d1ccec34c0a37e02255e7"}, - {file = "grpcio-1.53.0-cp39-cp39-manylinux_2_17_aarch64.whl", hash = "sha256:7dc8584ca6c015ad82e186e82f4c0fe977394588f66b8ecfc4ec873285314619"}, - {file = "grpcio-1.53.0-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2eddaae8af625e45b5c8500dcca1043264d751a6872cde2eda5022df8a336959"}, - {file = "grpcio-1.53.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c5fb6f3d7824696c1c9f2ad36ddb080ba5a86f2d929ef712d511b4d9972d3d27"}, - {file = "grpcio-1.53.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:8270d1dc2c98ab57e6dbf36fa187db8df4c036f04a398e5d5e25b4e01a766d70"}, - {file = "grpcio-1.53.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:976a7f24eb213e8429cab78d5e120500dfcdeb01041f1f5a77b17b9101902615"}, - {file = "grpcio-1.53.0-cp39-cp39-win32.whl", hash = "sha256:9c84a481451e7174f3a764a44150f93b041ab51045aa33d7b5b68b6979114e48"}, - {file = "grpcio-1.53.0-cp39-cp39-win_amd64.whl", hash = "sha256:6beb84f83360ff29a3654f43f251ec11b809dcb5524b698d711550243debd289"}, - {file = "grpcio-1.53.0.tar.gz", hash = "sha256:a4952899b4931a6ba12951f9a141ef3e74ff8a6ec9aa2dc602afa40f63595e33"}, + {file = "grpcio-1.53.2-cp310-cp310-linux_armv7l.whl", hash = "sha256:18afdda2bbe0c615da4daff754cab0df9bbd859c415d85e7e741a2975b3208b4"}, + {file = "grpcio-1.53.2-cp310-cp310-macosx_12_0_universal2.whl", hash = "sha256:33f7678287ac330c94e25f96cdb951e0861e206115ba4d8ea66cf6546b1a09d0"}, + {file = "grpcio-1.53.2-cp310-cp310-manylinux_2_17_aarch64.whl", hash = "sha256:1af074f28a56425e4f4d99761708981543a27ae963f5b4b0a36ff71f3483479d"}, + {file = "grpcio-1.53.2-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:df07843c8c0dc71a56d3af3dfe19165fb0d3af7d3354a72185f6fa1b4ac05cab"}, + {file = "grpcio-1.53.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5b403c4ad22f3ba37c7720547d8888a1e4b74ad980a94332bbbc50330b623abc"}, + {file = "grpcio-1.53.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:6275a54b41d6b1ec539b019bc3affaf6d05b0a0ba36af1a65b8a2810ef69e07d"}, + {file = "grpcio-1.53.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:0e92dc6a85cd1de42527812ef1276095e62169d002d86c888b6e889fcda1dd29"}, + {file = "grpcio-1.53.2-cp310-cp310-win32.whl", hash = "sha256:6be86e8d5cf47415968588e5dfbfb92ee8757fb41139584192b67050d1a72c58"}, + {file = "grpcio-1.53.2-cp310-cp310-win_amd64.whl", hash = "sha256:5b49f372df33f5f84865aef5d46cacd23180b586c80e8cbe0ce149b96dfa8c4c"}, + {file = "grpcio-1.53.2-cp311-cp311-linux_armv7l.whl", hash = "sha256:8166ac6671472d172cc0db50323b7a7504bd534de54aa31354465a00ca44409d"}, + {file = "grpcio-1.53.2-cp311-cp311-macosx_10_10_universal2.whl", hash = "sha256:f7e66d8b31ef2bada7029275debbe12c97397ec7ac70a659837a7b8a6a9dc916"}, + {file = "grpcio-1.53.2-cp311-cp311-manylinux_2_17_aarch64.whl", hash = "sha256:712113946b303db9ae4245a13de213710367850a6c3c53530b70e87989feb8e0"}, + {file = "grpcio-1.53.2-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f3761f9a6817e32898eaa5aecd0b0ad69d0c68ab45ea7bf206e8dc4548f025f0"}, + {file = "grpcio-1.53.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:24c63592103fded38b258f1e520ba8b0a7a0bbc397cddd6520a1f74dc4b5dec0"}, + {file = "grpcio-1.53.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:53d34cbf212f03634d74ba366d595b4a06a3b60fcc731eddbd6fd7ebe4acf981"}, + {file = "grpcio-1.53.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3b789472e9ef75d179295d0c6a1f7f0aefd08189cd1c822b068b0523365a1dbe"}, + {file = "grpcio-1.53.2-cp311-cp311-win32.whl", hash = "sha256:7b44ed75b9d67d17e5a098a0f99a8fd3e5861fd3c4eb54212277a0acdf298434"}, + {file = "grpcio-1.53.2-cp311-cp311-win_amd64.whl", hash = "sha256:1d1a320230e0d020880178b8eb453300bd57700b44c3744268370502e7376a9b"}, + {file = "grpcio-1.53.2-cp37-cp37m-linux_armv7l.whl", hash = "sha256:69e99fe6bdc2cdacd04cef6b6585b00630d958c98e36d825de3eea406e15fb31"}, + {file = "grpcio-1.53.2-cp37-cp37m-macosx_10_10_universal2.whl", hash = "sha256:590c7206f764cfe37a65003a75977358e20919ed488f970935f54efa2741b497"}, + {file = "grpcio-1.53.2-cp37-cp37m-manylinux_2_17_aarch64.whl", hash = "sha256:1fcced1abb13cdb6a5d8b105765d30212a6cb29ab0dfb01eedecf2ff6c84371b"}, + {file = "grpcio-1.53.2-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:07b83c06e7d113044cf3da15ca52f578c5f3dca299af711e9a589c1b71eb8be5"}, + {file = "grpcio-1.53.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a3bee217bda6b2c81d9e2866f523217135a03a007a89043eee074e93d76706b0"}, + {file = "grpcio-1.53.2-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:9efbedc737ba342d8a2459afc9bd5c5df31adcdf774b772a4e663739f2cf0d06"}, + {file = "grpcio-1.53.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:0f76287d98ec79a38cba8292d0bdcd6ab9b9daf568dce1d53b9eb0135fc14d26"}, + {file = "grpcio-1.53.2-cp37-cp37m-win_amd64.whl", hash = "sha256:d406cf2f6ccf39883a24b048c448a37bac16939408c1b6fbb4d021f3cd961448"}, + {file = "grpcio-1.53.2-cp38-cp38-linux_armv7l.whl", hash = "sha256:f9f7c0dd17f24e1774cc3a8df738246772994e853c28b28ed6ba7711ccf0abb4"}, + {file = "grpcio-1.53.2-cp38-cp38-macosx_10_10_universal2.whl", hash = "sha256:f14a82d12d53eb93298c35edf88d8c3ef37243b95f94dd3c75fddcba575d34ab"}, + {file = "grpcio-1.53.2-cp38-cp38-manylinux_2_17_aarch64.whl", hash = "sha256:1deeb84bb344351434f999cea4704ac6f1e07b3d861e34c44b50d8afa06caaa1"}, + {file = "grpcio-1.53.2-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7cbf1e3aaec3edf734ef90182363a395d234cd4790544be914cedbe1b9fec99a"}, + {file = "grpcio-1.53.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7ea235cecb9df14b49a75cbd27a634683a96bb76576363407ec820ae454ce2b2"}, + {file = "grpcio-1.53.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:1df931fbb4c36363d2cb985c2c26fda8f060b541a89c6c1191fdb59151a8c934"}, + {file = "grpcio-1.53.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:7734d1b91f1f3b1f186debf8ec4d168ee088a54e8186c14d89a95f7e51d3198d"}, + {file = "grpcio-1.53.2-cp38-cp38-win32.whl", hash = "sha256:b16258a31269b97e26a08d71b5deb56499e86077d26e453fad8f6ec4c06fe666"}, + {file = "grpcio-1.53.2-cp38-cp38-win_amd64.whl", hash = "sha256:b676c4365a5753bc8c49f922a5f88bdb5df6746c670a9d859d2ba2f5f97d9269"}, + {file = "grpcio-1.53.2-cp39-cp39-linux_armv7l.whl", hash = "sha256:8fc7667564c8c15748354dea1bb4035c5118df4e9dc5154ccdb6e62a3e5a2bac"}, + {file = "grpcio-1.53.2-cp39-cp39-macosx_10_10_universal2.whl", hash = "sha256:80a8867746cff41c2db436dd9eea18ebbfcd0449d65b64b3ed3c995207898971"}, + {file = "grpcio-1.53.2-cp39-cp39-manylinux_2_17_aarch64.whl", hash = "sha256:431f864f2642a97d0aa8c6b606c307f03d22f919b1a226af90488426aed35809"}, + {file = "grpcio-1.53.2-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bea6a20c5a732a27b64623d43614b3022e6fcfc081a75236b7f9aa069d2eaa4d"}, + {file = "grpcio-1.53.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:504af9e86ab01c9c33d8a452fe846aa931d024945f2e897537ccb8f7d76778ee"}, + {file = "grpcio-1.53.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:2b4f5671f9e88b7f51f54adda37a23277b7fdebd1557c47543b3e8a8044dd510"}, + {file = "grpcio-1.53.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:d9c51ca201326b49cfee38336c6e7dd1cb8a6b6d0dcf84aeaecbae310a736dbc"}, + {file = "grpcio-1.53.2-cp39-cp39-win32.whl", hash = "sha256:7e6885a8431939f1ee547e965fa3cb801a518b83d3d3509e90dbef78f0b5fd29"}, + {file = "grpcio-1.53.2-cp39-cp39-win_amd64.whl", hash = "sha256:ea84becb5cbd6a94a810c5214eb263ae57e915a9ed1bdcd5b4a6baf13d8c5177"}, + {file = "grpcio-1.53.2.tar.gz", hash = "sha256:0c9e42f2499c8603af1d88771dc97e2c6b0310c278337058fd7fd1ddb35ab853"}, ] [package.extras] -protobuf = ["grpcio-tools (>=1.53.0)"] +protobuf = ["grpcio-tools (>=1.53.2)"] [[package]] name = "grpcio-tools" @@ -821,43 +995,43 @@ setuptools = "*" [[package]] name = "idna" -version = "3.6" +version = "3.7" description = "Internationalized Domain Names in Applications (IDNA)" optional = false python-versions = ">=3.5" files = [ - {file = "idna-3.6-py3-none-any.whl", hash = "sha256:c05567e9c24a6b9faaa835c4821bad0590fbb9d5779e7caa6e1cc4978e7eb24f"}, - {file = "idna-3.6.tar.gz", hash = "sha256:9ecdbbd083b06798ae1e86adcbfe8ab1479cf864e4ee30fe4e46a003d12491ca"}, + {file = "idna-3.7-py3-none-any.whl", hash = "sha256:82fee1fc78add43492d3a1898bfa6d8a904cc97d8427f683ed8e798d07761aa0"}, + {file = "idna-3.7.tar.gz", hash = "sha256:028ff3aadf0609c1fd278d8ea3089299412a7a8b9bd005dd08b9f8285bcb5cfc"}, ] [[package]] name = "importlib-metadata" -version = "7.0.0" +version = "7.1.0" description = "Read metadata from Python packages" optional = false python-versions = ">=3.8" files = [ - {file = "importlib_metadata-7.0.0-py3-none-any.whl", hash = "sha256:d97503976bb81f40a193d41ee6570868479c69d5068651eb039c40d850c59d67"}, - {file = "importlib_metadata-7.0.0.tar.gz", hash = "sha256:7fc841f8b8332803464e5dc1c63a2e59121f46ca186c0e2e182e80bf8c1319f7"}, + {file = "importlib_metadata-7.1.0-py3-none-any.whl", hash = "sha256:30962b96c0c223483ed6cc7280e7f0199feb01a0e40cfae4d4450fc6fab1f570"}, + {file = "importlib_metadata-7.1.0.tar.gz", hash = "sha256:b78938b926ee8d5f020fc4772d487045805a55ddbad2ecf21c6d60938dc7fcd2"}, ] [package.dependencies] zipp = ">=0.5" [package.extras] -docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (<7.2.5)", "sphinx (>=3.5)", "sphinx-lint"] +docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] perf = ["ipython"] -testing = ["flufl.flake8", "importlib-resources (>=1.3)", "packaging", "pyfakefs", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy (>=0.9.1)", "pytest-perf (>=0.9.2)", "pytest-ruff"] +testing = ["flufl.flake8", "importlib-resources (>=1.3)", "jaraco.test (>=5.4)", "packaging", "pyfakefs", "pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy", "pytest-perf (>=0.9.2)", "pytest-ruff (>=0.2.1)"] [[package]] name = "importlib-resources" -version = "6.1.1" +version = "6.4.0" description = "Read resources from Python packages" optional = false python-versions = ">=3.8" files = [ - {file = "importlib_resources-6.1.1-py3-none-any.whl", hash = "sha256:e8bf90d8213b486f428c9c39714b920041cb02c184686a3dee24905aaa8105d6"}, - {file = "importlib_resources-6.1.1.tar.gz", hash = "sha256:3893a00122eafde6894c59914446a512f728a0c1a45f9bb9b63721b6bacf0b4a"}, + {file = "importlib_resources-6.4.0-py3-none-any.whl", hash = "sha256:50d10f043df931902d4194ea07ec57960f66a80449ff867bfe782b4c486ba78c"}, + {file = "importlib_resources-6.4.0.tar.gz", hash = "sha256:cdb2b453b8046ca4e3798eb1d84f3cce1446a0e8e7b5ef4efb600f19fc398145"}, ] [package.dependencies] @@ -865,7 +1039,74 @@ zipp = {version = ">=3.1.0", markers = "python_version < \"3.10\""} [package.extras] docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (<7.2.5)", "sphinx (>=3.5)", "sphinx-lint"] -testing = ["pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy (>=0.9.1)", "pytest-ruff", "zipp (>=3.17)"] +testing = ["jaraco.test (>=5.4)", "pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy", "pytest-ruff (>=0.2.1)", "zipp (>=3.17)"] + +[[package]] +name = "inflate64" +version = "1.0.0" +description = "deflate64 compression/decompression library" +optional = false +python-versions = ">=3.8" +files = [ + {file = "inflate64-1.0.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:a90c0bdf4a7ecddd8a64cc977181810036e35807f56b0bcacee9abb0fcfd18dc"}, + {file = "inflate64-1.0.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:57fe7c14aebf1c5a74fc3b70d355be1280a011521a76aa3895486e62454f4242"}, + {file = "inflate64-1.0.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:d90730165f471d61a1a694a5e354f3ffa938227e8dcecb62d5d728e8069cee94"}, + {file = "inflate64-1.0.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:543f400201f5c101141af3c79c82059e1aa6ef4f1584a7f1fa035fb2e465097f"}, + {file = "inflate64-1.0.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6ceca14f7ec19fb44b047f56c50efb7521b389d222bba2b0a10286a0caeb03fa"}, + {file = "inflate64-1.0.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:b559937a42f0c175b4d2dfc7eb53b97bdc87efa9add15ed5549c6abc1e89d02f"}, + {file = "inflate64-1.0.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:5ff8bd2a562343fcbc4eea26fdc368904a3b5f6bb8262344274d3d74a1de15bb"}, + {file = "inflate64-1.0.0-cp310-cp310-win_amd64.whl", hash = "sha256:0fe481f31695d35a433c3044ac8fd5d9f5069aaad03a0c04b570eb258ce655aa"}, + {file = "inflate64-1.0.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:35a45f6979ad5874d4d4898c2fc770b136e61b96b850118fdaec5a5af1b9123a"}, + {file = "inflate64-1.0.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:022ca1cc928e7365a05f7371ff06af143c6c667144965e2cf9a9236a2ae1c291"}, + {file = "inflate64-1.0.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:46792ecf3565d64fd2c519b0a780c03a57e195613c9954ef94e739a057b3fd06"}, + {file = "inflate64-1.0.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3a70ea2e456c15f7aa7c74b8ab8f20b4f8940ec657604c9f0a9de3342f280fff"}, + {file = "inflate64-1.0.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3e243ea9bd36a035059f2365bd6d156ff59717fbafb0255cb0c75bf151bf6904"}, + {file = "inflate64-1.0.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:4dc392dec1cd11cacda3d2637214ca45e38202e8a4f31d4a4e566d6e90625fc4"}, + {file = "inflate64-1.0.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:8b402a50eda7ee75f342fc346d33a41bca58edc222a4b17f9be0db1daed459fa"}, + {file = "inflate64-1.0.0-cp311-cp311-win_amd64.whl", hash = "sha256:f5924499dc8800928c0ee4580fa8eb4ffa880b2cce4431537d0390e503a9c9ee"}, + {file = "inflate64-1.0.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:0c644bf7208e20825ca3bbb5fb1f7f495cfcb49eb01a5f67338796d44a42f2bf"}, + {file = "inflate64-1.0.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:9964a4eaf26a9d36f82a1d9b12c28e35800dd3d99eb340453ed12ac90c2976a8"}, + {file = "inflate64-1.0.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2cccded63865640d03253897be7232b2bbac295fe43914c61f86a57aa23bb61d"}, + {file = "inflate64-1.0.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d491f104fb3701926ebd82b8c9250dfba0ddcab584504e26f1e4adb26730378d"}, + {file = "inflate64-1.0.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5ebad4a6cd2a2c1d81be0b09d4006479f3b258803c49a9224ef8ca0b649072fa"}, + {file = "inflate64-1.0.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:6823b2c0cff3a8159140f3b17ec64fb8ec0e663b45a6593618ecdde8aeecb5b2"}, + {file = "inflate64-1.0.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:228d504239d27958e71fc77e3119a6ac4528127df38468a0c95a5bd3927204b8"}, + {file = "inflate64-1.0.0-cp312-cp312-win_amd64.whl", hash = "sha256:ae2572e06bcfe15e3bbf77d4e4a6d6c55e2a70d6abceaaf60c5c3653ddb96dfd"}, + {file = "inflate64-1.0.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:c10ca61212a753bbce6d341e7cfa779c161b839281f1f9fdc15cf1f324ce7c5b"}, + {file = "inflate64-1.0.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:a982dc93920f9450da4d4f25c5e5c1288ef053b1d618cedc91adb67e035e35f5"}, + {file = "inflate64-1.0.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:ca0310b2c55bc40394c5371db2a22f705fd594226cc09432e1eb04d3aed83930"}, + {file = "inflate64-1.0.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e95044ae55a161144445527a2efad550851fecc699066423d24b2634a6a83710"}, + {file = "inflate64-1.0.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:34de6902c39d9225459583d5034182d371fc694bc3cfd6c0fc89aa62e9809faf"}, + {file = "inflate64-1.0.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:ebafbd813213dc470719cd0a2bcb53aab89d9059f4e75386048b4c4dcdb2fd99"}, + {file = "inflate64-1.0.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:75448c7b414dadaeeb11dab9f75e022aa1e0ee19b00f570e9f58e933603d71ac"}, + {file = "inflate64-1.0.0-cp38-cp38-win_amd64.whl", hash = "sha256:2be4e01c1b04761874cb44b35b6103ca5846bc36c18fc3ff5e8cbcd8bfc15e9f"}, + {file = "inflate64-1.0.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:bf2981b95c1f26242bb084d9a07f3feb0cfe3d6d0a8d90f42389803bc1252c4a"}, + {file = "inflate64-1.0.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9373ccf0661cc72ac84a0ad622634144da5ce7d57c9572ed0723d67a149feed2"}, + {file = "inflate64-1.0.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:e4650c6f65011ec57cf5cd96b92d5b7c6f59e502930c86eb8227c93cf02dc270"}, + {file = "inflate64-1.0.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a475e8822f1a74c873e60b8f270773757ade024097ca39e43402d47c049c67d4"}, + {file = "inflate64-1.0.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d4367480733ac8daf368f6fc704b7c9db85521ee745eb5bd443f4b97d2051acc"}, + {file = "inflate64-1.0.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:6c5775c91f94f5eced9160fb0af12a09f3e030194f91a6a46e706a79350bd056"}, + {file = "inflate64-1.0.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:d76d205b844d78ce04768060084ef20e64dcc63a3e9166674f857acaf4d140ed"}, + {file = "inflate64-1.0.0-cp39-cp39-win_amd64.whl", hash = "sha256:92f0dc6af0e8e97324981178dc442956cbff1247a56d1e201af8d865244653f8"}, + {file = "inflate64-1.0.0-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:f79542478e49e471e8b23556700e6f688a40dc93e9a746f77a546c13251b59b1"}, + {file = "inflate64-1.0.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9a270be6b10cde01258c0097a663a307c62d12c78eb8f62f8e29f205335942c9"}, + {file = "inflate64-1.0.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1616a87ff04f583e9558cc247ec0b72a30d540ee0c17cc77823be175c0ec92f0"}, + {file = "inflate64-1.0.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:137ca6b315f0157a786c3a755a09395ca69aed8bcf42ad3437cb349f5ebc86d2"}, + {file = "inflate64-1.0.0-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:8140942d1614bdeb5a9ddd7559348c5c77f884a42424aef7ccf149ccfb93aa08"}, + {file = "inflate64-1.0.0-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9fe3f9051338bb7d07b5e7d88420d666b5109f33ae39aa55ecd1a053c0f22b1b"}, + {file = "inflate64-1.0.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:36342338e957c790fc630d4afcdcc3926beb2ecaea0b302336079e8fa37e57a0"}, + {file = "inflate64-1.0.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:9b65cc701ef33ab20dbfd1d64088ffd89a8c265b356d2c21ba0ec565661645ef"}, + {file = "inflate64-1.0.0-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:dd6d3e7d47df43210a995fd1f5989602b64de3f2a17cf4cbff553518b3577fd4"}, + {file = "inflate64-1.0.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8f033b2879696b855200cde5ca4e293132c7499df790acb2c0dacb336d5e83b1"}, + {file = "inflate64-1.0.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5f816d1c8a0593375c289e285c96deaee9c2d8742cb0edbd26ee05588a9ae657"}, + {file = "inflate64-1.0.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:1facd35319b6a391ee4c3d709c7c650bcada8cd7141d86cd8c2257287f45e6e6"}, + {file = "inflate64-1.0.0.tar.gz", hash = "sha256:3278827b803cf006a1df251f3e13374c7d26db779e5a33329cc11789b804bc2d"}, +] + +[package.extras] +check = ["check-manifest", "flake8", "flake8-black", "flake8-deprecated", "isort (>=5.0.3)", "mypy (>=0.940)", "mypy-extensions (>=0.4.1)", "pygments", "readme-renderer", "twine"] +docs = ["docutils", "sphinx (>=5.0)"] +test = ["pyannotate", "pytest"] [[package]] name = "isort" @@ -886,24 +1127,24 @@ requirements-deprecated-finder = ["pip-api", "pipreqs"] [[package]] name = "itsdangerous" -version = "2.1.2" +version = "2.2.0" description = "Safely pass data to untrusted environments and back." optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "itsdangerous-2.1.2-py3-none-any.whl", hash = "sha256:2c2349112351b88699d8d4b6b075022c0808887cb7ad10069318a8b0bc88db44"}, - {file = "itsdangerous-2.1.2.tar.gz", hash = "sha256:5dbbc68b317e5e42f327f9021763545dc3fc3bfe22e6deb96aaf1fc38874156a"}, + {file = "itsdangerous-2.2.0-py3-none-any.whl", hash = "sha256:c6242fc49e35958c8b15141343aa660db5fc54d4f13a1db01a3f5891b98700ef"}, + {file = "itsdangerous-2.2.0.tar.gz", hash = "sha256:e0050c0b7da1eea53ffaf149c0cfbb5c6e2e2b69c4bef22c81fa6eb73e5f6173"}, ] [[package]] name = "jinja2" -version = "3.1.2" +version = "3.1.3" description = "A very fast and expressive template engine." optional = false python-versions = ">=3.7" files = [ - {file = "Jinja2-3.1.2-py3-none-any.whl", hash = "sha256:6088930bfe239f0e6710546ab9c19c9ef35e29792895fed6e6e31a023a182a61"}, - {file = "Jinja2-3.1.2.tar.gz", hash = "sha256:31351a702a408a9e7595a8fc6150fc3f43bb6bf7e319770cbc0db9df9437e852"}, + {file = "Jinja2-3.1.3-py3-none-any.whl", hash = "sha256:7d6d50dd97d52cbc355597bd845fabfbac3f551e1f99619e39a35ce8c370b5fa"}, + {file = "Jinja2-3.1.3.tar.gz", hash = "sha256:ac8bd6544d4bb2c9792bf3a159e80bba8fda7f07e81bc3aed565432d5925ba90"}, ] [package.dependencies] @@ -1013,71 +1254,71 @@ testing = ["pytest"] [[package]] name = "markupsafe" -version = "2.1.3" +version = "2.1.5" description = "Safely add untrusted strings to HTML/XML markup." optional = false python-versions = ">=3.7" files = [ - {file = "MarkupSafe-2.1.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:cd0f502fe016460680cd20aaa5a76d241d6f35a1c3350c474bac1273803893fa"}, - {file = "MarkupSafe-2.1.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e09031c87a1e51556fdcb46e5bd4f59dfb743061cf93c4d6831bf894f125eb57"}, - {file = "MarkupSafe-2.1.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:68e78619a61ecf91e76aa3e6e8e33fc4894a2bebe93410754bd28fce0a8a4f9f"}, - {file = "MarkupSafe-2.1.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:65c1a9bcdadc6c28eecee2c119465aebff8f7a584dd719facdd9e825ec61ab52"}, - {file = "MarkupSafe-2.1.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:525808b8019e36eb524b8c68acdd63a37e75714eac50e988180b169d64480a00"}, - {file = "MarkupSafe-2.1.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:962f82a3086483f5e5f64dbad880d31038b698494799b097bc59c2edf392fce6"}, - {file = "MarkupSafe-2.1.3-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:aa7bd130efab1c280bed0f45501b7c8795f9fdbeb02e965371bbef3523627779"}, - {file = "MarkupSafe-2.1.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c9c804664ebe8f83a211cace637506669e7890fec1b4195b505c214e50dd4eb7"}, - {file = "MarkupSafe-2.1.3-cp310-cp310-win32.whl", hash = "sha256:10bbfe99883db80bdbaff2dcf681dfc6533a614f700da1287707e8a5d78a8431"}, - {file = "MarkupSafe-2.1.3-cp310-cp310-win_amd64.whl", hash = "sha256:1577735524cdad32f9f694208aa75e422adba74f1baee7551620e43a3141f559"}, - {file = "MarkupSafe-2.1.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:ad9e82fb8f09ade1c3e1b996a6337afac2b8b9e365f926f5a61aacc71adc5b3c"}, - {file = "MarkupSafe-2.1.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3c0fae6c3be832a0a0473ac912810b2877c8cb9d76ca48de1ed31e1c68386575"}, - {file = "MarkupSafe-2.1.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b076b6226fb84157e3f7c971a47ff3a679d837cf338547532ab866c57930dbee"}, - {file = "MarkupSafe-2.1.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bfce63a9e7834b12b87c64d6b155fdd9b3b96191b6bd334bf37db7ff1fe457f2"}, - {file = "MarkupSafe-2.1.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:338ae27d6b8745585f87218a3f23f1512dbf52c26c28e322dbe54bcede54ccb9"}, - {file = "MarkupSafe-2.1.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e4dd52d80b8c83fdce44e12478ad2e85c64ea965e75d66dbeafb0a3e77308fcc"}, - {file = "MarkupSafe-2.1.3-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:df0be2b576a7abbf737b1575f048c23fb1d769f267ec4358296f31c2479db8f9"}, - {file = "MarkupSafe-2.1.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:5bbe06f8eeafd38e5d0a4894ffec89378b6c6a625ff57e3028921f8ff59318ac"}, - {file = "MarkupSafe-2.1.3-cp311-cp311-win32.whl", hash = "sha256:dd15ff04ffd7e05ffcb7fe79f1b98041b8ea30ae9234aed2a9168b5797c3effb"}, - {file = "MarkupSafe-2.1.3-cp311-cp311-win_amd64.whl", hash = "sha256:134da1eca9ec0ae528110ccc9e48041e0828d79f24121a1a146161103c76e686"}, - {file = "MarkupSafe-2.1.3-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:f698de3fd0c4e6972b92290a45bd9b1536bffe8c6759c62471efaa8acb4c37bc"}, - {file = "MarkupSafe-2.1.3-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:aa57bd9cf8ae831a362185ee444e15a93ecb2e344c8e52e4d721ea3ab6ef1823"}, - {file = "MarkupSafe-2.1.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ffcc3f7c66b5f5b7931a5aa68fc9cecc51e685ef90282f4a82f0f5e9b704ad11"}, - {file = "MarkupSafe-2.1.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:47d4f1c5f80fc62fdd7777d0d40a2e9dda0a05883ab11374334f6c4de38adffd"}, - {file = "MarkupSafe-2.1.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1f67c7038d560d92149c060157d623c542173016c4babc0c1913cca0564b9939"}, - {file = "MarkupSafe-2.1.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:9aad3c1755095ce347e26488214ef77e0485a3c34a50c5a5e2471dff60b9dd9c"}, - {file = "MarkupSafe-2.1.3-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:14ff806850827afd6b07a5f32bd917fb7f45b046ba40c57abdb636674a8b559c"}, - {file = "MarkupSafe-2.1.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8f9293864fe09b8149f0cc42ce56e3f0e54de883a9de90cd427f191c346eb2e1"}, - {file = "MarkupSafe-2.1.3-cp312-cp312-win32.whl", hash = "sha256:715d3562f79d540f251b99ebd6d8baa547118974341db04f5ad06d5ea3eb8007"}, - {file = "MarkupSafe-2.1.3-cp312-cp312-win_amd64.whl", hash = "sha256:1b8dd8c3fd14349433c79fa8abeb573a55fc0fdd769133baac1f5e07abf54aeb"}, - {file = "MarkupSafe-2.1.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:8e254ae696c88d98da6555f5ace2279cf7cd5b3f52be2b5cf97feafe883b58d2"}, - {file = "MarkupSafe-2.1.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cb0932dc158471523c9637e807d9bfb93e06a95cbf010f1a38b98623b929ef2b"}, - {file = "MarkupSafe-2.1.3-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9402b03f1a1b4dc4c19845e5c749e3ab82d5078d16a2a4c2cd2df62d57bb0707"}, - {file = "MarkupSafe-2.1.3-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ca379055a47383d02a5400cb0d110cef0a776fc644cda797db0c5696cfd7e18e"}, - {file = "MarkupSafe-2.1.3-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:b7ff0f54cb4ff66dd38bebd335a38e2c22c41a8ee45aa608efc890ac3e3931bc"}, - {file = "MarkupSafe-2.1.3-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:c011a4149cfbcf9f03994ec2edffcb8b1dc2d2aede7ca243746df97a5d41ce48"}, - {file = "MarkupSafe-2.1.3-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:56d9f2ecac662ca1611d183feb03a3fa4406469dafe241673d521dd5ae92a155"}, - {file = "MarkupSafe-2.1.3-cp37-cp37m-win32.whl", hash = "sha256:8758846a7e80910096950b67071243da3e5a20ed2546e6392603c096778d48e0"}, - {file = "MarkupSafe-2.1.3-cp37-cp37m-win_amd64.whl", hash = "sha256:787003c0ddb00500e49a10f2844fac87aa6ce977b90b0feaaf9de23c22508b24"}, - {file = "MarkupSafe-2.1.3-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:2ef12179d3a291be237280175b542c07a36e7f60718296278d8593d21ca937d4"}, - {file = "MarkupSafe-2.1.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:2c1b19b3aaacc6e57b7e25710ff571c24d6c3613a45e905b1fde04d691b98ee0"}, - {file = "MarkupSafe-2.1.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8afafd99945ead6e075b973fefa56379c5b5c53fd8937dad92c662da5d8fd5ee"}, - {file = "MarkupSafe-2.1.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8c41976a29d078bb235fea9b2ecd3da465df42a562910f9022f1a03107bd02be"}, - {file = "MarkupSafe-2.1.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d080e0a5eb2529460b30190fcfcc4199bd7f827663f858a226a81bc27beaa97e"}, - {file = "MarkupSafe-2.1.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:69c0f17e9f5a7afdf2cc9fb2d1ce6aabdb3bafb7f38017c0b77862bcec2bbad8"}, - {file = "MarkupSafe-2.1.3-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:504b320cd4b7eff6f968eddf81127112db685e81f7e36e75f9f84f0df46041c3"}, - {file = "MarkupSafe-2.1.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:42de32b22b6b804f42c5d98be4f7e5e977ecdd9ee9b660fda1a3edf03b11792d"}, - {file = "MarkupSafe-2.1.3-cp38-cp38-win32.whl", hash = "sha256:ceb01949af7121f9fc39f7d27f91be8546f3fb112c608bc4029aef0bab86a2a5"}, - {file = "MarkupSafe-2.1.3-cp38-cp38-win_amd64.whl", hash = "sha256:1b40069d487e7edb2676d3fbdb2b0829ffa2cd63a2ec26c4938b2d34391b4ecc"}, - {file = "MarkupSafe-2.1.3-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:8023faf4e01efadfa183e863fefde0046de576c6f14659e8782065bcece22198"}, - {file = "MarkupSafe-2.1.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6b2b56950d93e41f33b4223ead100ea0fe11f8e6ee5f641eb753ce4b77a7042b"}, - {file = "MarkupSafe-2.1.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9dcdfd0eaf283af041973bff14a2e143b8bd64e069f4c383416ecd79a81aab58"}, - {file = "MarkupSafe-2.1.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:05fb21170423db021895e1ea1e1f3ab3adb85d1c2333cbc2310f2a26bc77272e"}, - {file = "MarkupSafe-2.1.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:282c2cb35b5b673bbcadb33a585408104df04f14b2d9b01d4c345a3b92861c2c"}, - {file = "MarkupSafe-2.1.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:ab4a0df41e7c16a1392727727e7998a467472d0ad65f3ad5e6e765015df08636"}, - {file = "MarkupSafe-2.1.3-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:7ef3cb2ebbf91e330e3bb937efada0edd9003683db6b57bb108c4001f37a02ea"}, - {file = "MarkupSafe-2.1.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:0a4e4a1aff6c7ac4cd55792abf96c915634c2b97e3cc1c7129578aa68ebd754e"}, - {file = "MarkupSafe-2.1.3-cp39-cp39-win32.whl", hash = "sha256:fec21693218efe39aa7f8599346e90c705afa52c5b31ae019b2e57e8f6542bb2"}, - {file = "MarkupSafe-2.1.3-cp39-cp39-win_amd64.whl", hash = "sha256:3fd4abcb888d15a94f32b75d8fd18ee162ca0c064f35b11134be77050296d6ba"}, - {file = "MarkupSafe-2.1.3.tar.gz", hash = "sha256:af598ed32d6ae86f1b747b82783958b1a4ab8f617b06fe68795c7f026abbdcad"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:a17a92de5231666cfbe003f0e4b9b3a7ae3afb1ec2845aadc2bacc93ff85febc"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:72b6be590cc35924b02c78ef34b467da4ba07e4e0f0454a2c5907f473fc50ce5"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e61659ba32cf2cf1481e575d0462554625196a1f2fc06a1c777d3f48e8865d46"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2174c595a0d73a3080ca3257b40096db99799265e1c27cc5a610743acd86d62f"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ae2ad8ae6ebee9d2d94b17fb62763125f3f374c25618198f40cbb8b525411900"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:075202fa5b72c86ad32dc7d0b56024ebdbcf2048c0ba09f1cde31bfdd57bcfff"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:598e3276b64aff0e7b3451b72e94fa3c238d452e7ddcd893c3ab324717456bad"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fce659a462a1be54d2ffcacea5e3ba2d74daa74f30f5f143fe0c58636e355fdd"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-win32.whl", hash = "sha256:d9fad5155d72433c921b782e58892377c44bd6252b5af2f67f16b194987338a4"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-win_amd64.whl", hash = "sha256:bf50cd79a75d181c9181df03572cdce0fbb75cc353bc350712073108cba98de5"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:629ddd2ca402ae6dbedfceeba9c46d5f7b2a61d9749597d4307f943ef198fc1f"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:5b7b716f97b52c5a14bffdf688f971b2d5ef4029127f1ad7a513973cfd818df2"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6ec585f69cec0aa07d945b20805be741395e28ac1627333b1c5b0105962ffced"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b91c037585eba9095565a3556f611e3cbfaa42ca1e865f7b8015fe5c7336d5a5"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7502934a33b54030eaf1194c21c692a534196063db72176b0c4028e140f8f32c"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:0e397ac966fdf721b2c528cf028494e86172b4feba51d65f81ffd65c63798f3f"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:c061bb86a71b42465156a3ee7bd58c8c2ceacdbeb95d05a99893e08b8467359a"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3a57fdd7ce31c7ff06cdfbf31dafa96cc533c21e443d57f5b1ecc6cdc668ec7f"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-win32.whl", hash = "sha256:397081c1a0bfb5124355710fe79478cdbeb39626492b15d399526ae53422b906"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-win_amd64.whl", hash = "sha256:2b7c57a4dfc4f16f7142221afe5ba4e093e09e728ca65c51f5620c9aaeb9a617"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:8dec4936e9c3100156f8a2dc89c4b88d5c435175ff03413b443469c7c8c5f4d1"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:3c6b973f22eb18a789b1460b4b91bf04ae3f0c4234a0a6aa6b0a92f6f7b951d4"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ac07bad82163452a6884fe8fa0963fb98c2346ba78d779ec06bd7a6262132aee"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f5dfb42c4604dddc8e4305050aa6deb084540643ed5804d7455b5df8fe16f5e5"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ea3d8a3d18833cf4304cd2fc9cbb1efe188ca9b5efef2bdac7adc20594a0e46b"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:d050b3361367a06d752db6ead6e7edeb0009be66bc3bae0ee9d97fb326badc2a"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:bec0a414d016ac1a18862a519e54b2fd0fc8bbfd6890376898a6c0891dd82e9f"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:58c98fee265677f63a4385256a6d7683ab1832f3ddd1e66fe948d5880c21a169"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-win32.whl", hash = "sha256:8590b4ae07a35970728874632fed7bd57b26b0102df2d2b233b6d9d82f6c62ad"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-win_amd64.whl", hash = "sha256:823b65d8706e32ad2df51ed89496147a42a2a6e01c13cfb6ffb8b1e92bc910bb"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c8b29db45f8fe46ad280a7294f5c3ec36dbac9491f2d1c17345be8e69cc5928f"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ec6a563cff360b50eed26f13adc43e61bc0c04d94b8be985e6fb24b81f6dcfdf"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a549b9c31bec33820e885335b451286e2969a2d9e24879f83fe904a5ce59d70a"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4f11aa001c540f62c6166c7726f71f7573b52c68c31f014c25cc7901deea0b52"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:7b2e5a267c855eea6b4283940daa6e88a285f5f2a67f2220203786dfa59b37e9"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:2d2d793e36e230fd32babe143b04cec8a8b3eb8a3122d2aceb4a371e6b09b8df"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:ce409136744f6521e39fd8e2a24c53fa18ad67aa5bc7c2cf83645cce5b5c4e50"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-win32.whl", hash = "sha256:4096e9de5c6fdf43fb4f04c26fb114f61ef0bf2e5604b6ee3019d51b69e8c371"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-win_amd64.whl", hash = "sha256:4275d846e41ecefa46e2015117a9f491e57a71ddd59bbead77e904dc02b1bed2"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:656f7526c69fac7f600bd1f400991cc282b417d17539a1b228617081106feb4a"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:97cafb1f3cbcd3fd2b6fbfb99ae11cdb14deea0736fc2b0952ee177f2b813a46"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f3fbcb7ef1f16e48246f704ab79d79da8a46891e2da03f8783a5b6fa41a9532"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fa9db3f79de01457b03d4f01b34cf91bc0048eb2c3846ff26f66687c2f6d16ab"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffee1f21e5ef0d712f9033568f8344d5da8cc2869dbd08d87c84656e6a2d2f68"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:5dedb4db619ba5a2787a94d877bc8ffc0566f92a01c0ef214865e54ecc9ee5e0"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:30b600cf0a7ac9234b2638fbc0fb6158ba5bdcdf46aeb631ead21248b9affbc4"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:8dd717634f5a044f860435c1d8c16a270ddf0ef8588d4887037c5028b859b0c3"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-win32.whl", hash = "sha256:daa4ee5a243f0f20d528d939d06670a298dd39b1ad5f8a72a4275124a7819eff"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-win_amd64.whl", hash = "sha256:619bc166c4f2de5caa5a633b8b7326fbe98e0ccbfacabd87268a2b15ff73a029"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:7a68b554d356a91cce1236aa7682dc01df0edba8d043fd1ce607c49dd3c1edcf"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:db0b55e0f3cc0be60c1f19efdde9a637c32740486004f20d1cff53c3c0ece4d2"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3e53af139f8579a6d5f7b76549125f0d94d7e630761a2111bc431fd820e163b8"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:17b950fccb810b3293638215058e432159d2b71005c74371d784862b7e4683f3"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4c31f53cdae6ecfa91a77820e8b151dba54ab528ba65dfd235c80b086d68a465"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:bff1b4290a66b490a2f4719358c0cdcd9bafb6b8f061e45c7a2460866bf50c2e"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:bc1667f8b83f48511b94671e0e441401371dfd0f0a795c7daa4a3cd1dde55bea"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5049256f536511ee3f7e1b3f87d1d1209d327e818e6ae1365e8653d7e3abb6a6"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-win32.whl", hash = "sha256:00e046b6dd71aa03a41079792f8473dc494d564611a8f89bbbd7cb93295ebdcf"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-win_amd64.whl", hash = "sha256:fa173ec60341d6bb97a89f5ea19c85c5643c1e7dedebc22f5181eb73573142c5"}, + {file = "MarkupSafe-2.1.5.tar.gz", hash = "sha256:d283d37a890ba4c1ae73ffadf8046435c76e7bc2247bbb63c00bd1a709c6544b"}, ] [[package]] @@ -1093,87 +1334,119 @@ files = [ [[package]] name = "multidict" -version = "6.0.4" +version = "6.0.5" description = "multidict implementation" optional = false python-versions = ">=3.7" files = [ - {file = "multidict-6.0.4-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:0b1a97283e0c85772d613878028fec909f003993e1007eafa715b24b377cb9b8"}, - {file = "multidict-6.0.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:eeb6dcc05e911516ae3d1f207d4b0520d07f54484c49dfc294d6e7d63b734171"}, - {file = "multidict-6.0.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:d6d635d5209b82a3492508cf5b365f3446afb65ae7ebd755e70e18f287b0adf7"}, - {file = "multidict-6.0.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c048099e4c9e9d615545e2001d3d8a4380bd403e1a0578734e0d31703d1b0c0b"}, - {file = "multidict-6.0.4-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ea20853c6dbbb53ed34cb4d080382169b6f4554d394015f1bef35e881bf83547"}, - {file = "multidict-6.0.4-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:16d232d4e5396c2efbbf4f6d4df89bfa905eb0d4dc5b3549d872ab898451f569"}, - {file = "multidict-6.0.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:36c63aaa167f6c6b04ef2c85704e93af16c11d20de1d133e39de6a0e84582a93"}, - {file = "multidict-6.0.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:64bdf1086b6043bf519869678f5f2757f473dee970d7abf6da91ec00acb9cb98"}, - {file = "multidict-6.0.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:43644e38f42e3af682690876cff722d301ac585c5b9e1eacc013b7a3f7b696a0"}, - {file = "multidict-6.0.4-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:7582a1d1030e15422262de9f58711774e02fa80df0d1578995c76214f6954988"}, - {file = "multidict-6.0.4-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:ddff9c4e225a63a5afab9dd15590432c22e8057e1a9a13d28ed128ecf047bbdc"}, - {file = "multidict-6.0.4-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:ee2a1ece51b9b9e7752e742cfb661d2a29e7bcdba2d27e66e28a99f1890e4fa0"}, - {file = "multidict-6.0.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:a2e4369eb3d47d2034032a26c7a80fcb21a2cb22e1173d761a162f11e562caa5"}, - {file = "multidict-6.0.4-cp310-cp310-win32.whl", hash = "sha256:574b7eae1ab267e5f8285f0fe881f17efe4b98c39a40858247720935b893bba8"}, - {file = "multidict-6.0.4-cp310-cp310-win_amd64.whl", hash = "sha256:4dcbb0906e38440fa3e325df2359ac6cb043df8e58c965bb45f4e406ecb162cc"}, - {file = "multidict-6.0.4-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0dfad7a5a1e39c53ed00d2dd0c2e36aed4650936dc18fd9a1826a5ae1cad6f03"}, - {file = "multidict-6.0.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:64da238a09d6039e3bd39bb3aee9c21a5e34f28bfa5aa22518581f910ff94af3"}, - {file = "multidict-6.0.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ff959bee35038c4624250473988b24f846cbeb2c6639de3602c073f10410ceba"}, - {file = "multidict-6.0.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:01a3a55bd90018c9c080fbb0b9f4891db37d148a0a18722b42f94694f8b6d4c9"}, - {file = "multidict-6.0.4-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c5cb09abb18c1ea940fb99360ea0396f34d46566f157122c92dfa069d3e0e982"}, - {file = "multidict-6.0.4-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:666daae833559deb2d609afa4490b85830ab0dfca811a98b70a205621a6109fe"}, - {file = "multidict-6.0.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:11bdf3f5e1518b24530b8241529d2050014c884cf18b6fc69c0c2b30ca248710"}, - {file = "multidict-6.0.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7d18748f2d30f94f498e852c67d61261c643b349b9d2a581131725595c45ec6c"}, - {file = "multidict-6.0.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:458f37be2d9e4c95e2d8866a851663cbc76e865b78395090786f6cd9b3bbf4f4"}, - {file = "multidict-6.0.4-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:b1a2eeedcead3a41694130495593a559a668f382eee0727352b9a41e1c45759a"}, - {file = "multidict-6.0.4-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:7d6ae9d593ef8641544d6263c7fa6408cc90370c8cb2bbb65f8d43e5b0351d9c"}, - {file = "multidict-6.0.4-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:5979b5632c3e3534e42ca6ff856bb24b2e3071b37861c2c727ce220d80eee9ed"}, - {file = "multidict-6.0.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:dcfe792765fab89c365123c81046ad4103fcabbc4f56d1c1997e6715e8015461"}, - {file = "multidict-6.0.4-cp311-cp311-win32.whl", hash = "sha256:3601a3cece3819534b11d4efc1eb76047488fddd0c85a3948099d5da4d504636"}, - {file = "multidict-6.0.4-cp311-cp311-win_amd64.whl", hash = "sha256:81a4f0b34bd92df3da93315c6a59034df95866014ac08535fc819f043bfd51f0"}, - {file = "multidict-6.0.4-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:67040058f37a2a51ed8ea8f6b0e6ee5bd78ca67f169ce6122f3e2ec80dfe9b78"}, - {file = "multidict-6.0.4-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:853888594621e6604c978ce2a0444a1e6e70c8d253ab65ba11657659dcc9100f"}, - {file = "multidict-6.0.4-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:39ff62e7d0f26c248b15e364517a72932a611a9b75f35b45be078d81bdb86603"}, - {file = "multidict-6.0.4-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:af048912e045a2dc732847d33821a9d84ba553f5c5f028adbd364dd4765092ac"}, - {file = "multidict-6.0.4-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b1e8b901e607795ec06c9e42530788c45ac21ef3aaa11dbd0c69de543bfb79a9"}, - {file = "multidict-6.0.4-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:62501642008a8b9871ddfccbf83e4222cf8ac0d5aeedf73da36153ef2ec222d2"}, - {file = "multidict-6.0.4-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:99b76c052e9f1bc0721f7541e5e8c05db3941eb9ebe7b8553c625ef88d6eefde"}, - {file = "multidict-6.0.4-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:509eac6cf09c794aa27bcacfd4d62c885cce62bef7b2c3e8b2e49d365b5003fe"}, - {file = "multidict-6.0.4-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:21a12c4eb6ddc9952c415f24eef97e3e55ba3af61f67c7bc388dcdec1404a067"}, - {file = "multidict-6.0.4-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:5cad9430ab3e2e4fa4a2ef4450f548768400a2ac635841bc2a56a2052cdbeb87"}, - {file = "multidict-6.0.4-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:ab55edc2e84460694295f401215f4a58597f8f7c9466faec545093045476327d"}, - {file = "multidict-6.0.4-cp37-cp37m-win32.whl", hash = "sha256:5a4dcf02b908c3b8b17a45fb0f15b695bf117a67b76b7ad18b73cf8e92608775"}, - {file = "multidict-6.0.4-cp37-cp37m-win_amd64.whl", hash = "sha256:6ed5f161328b7df384d71b07317f4d8656434e34591f20552c7bcef27b0ab88e"}, - {file = "multidict-6.0.4-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:5fc1b16f586f049820c5c5b17bb4ee7583092fa0d1c4e28b5239181ff9532e0c"}, - {file = "multidict-6.0.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1502e24330eb681bdaa3eb70d6358e818e8e8f908a22a1851dfd4e15bc2f8161"}, - {file = "multidict-6.0.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:b692f419760c0e65d060959df05f2a531945af31fda0c8a3b3195d4efd06de11"}, - {file = "multidict-6.0.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:45e1ecb0379bfaab5eef059f50115b54571acfbe422a14f668fc8c27ba410e7e"}, - {file = "multidict-6.0.4-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ddd3915998d93fbcd2566ddf9cf62cdb35c9e093075f862935573d265cf8f65d"}, - {file = "multidict-6.0.4-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:59d43b61c59d82f2effb39a93c48b845efe23a3852d201ed2d24ba830d0b4cf2"}, - {file = "multidict-6.0.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cc8e1d0c705233c5dd0c5e6460fbad7827d5d36f310a0fadfd45cc3029762258"}, - {file = "multidict-6.0.4-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d6aa0418fcc838522256761b3415822626f866758ee0bc6632c9486b179d0b52"}, - {file = "multidict-6.0.4-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6748717bb10339c4760c1e63da040f5f29f5ed6e59d76daee30305894069a660"}, - {file = "multidict-6.0.4-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:4d1a3d7ef5e96b1c9e92f973e43aa5e5b96c659c9bc3124acbbd81b0b9c8a951"}, - {file = "multidict-6.0.4-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:4372381634485bec7e46718edc71528024fcdc6f835baefe517b34a33c731d60"}, - {file = "multidict-6.0.4-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:fc35cb4676846ef752816d5be2193a1e8367b4c1397b74a565a9d0389c433a1d"}, - {file = "multidict-6.0.4-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:4b9d9e4e2b37daddb5c23ea33a3417901fa7c7b3dee2d855f63ee67a0b21e5b1"}, - {file = "multidict-6.0.4-cp38-cp38-win32.whl", hash = "sha256:e41b7e2b59679edfa309e8db64fdf22399eec4b0b24694e1b2104fb789207779"}, - {file = "multidict-6.0.4-cp38-cp38-win_amd64.whl", hash = "sha256:d6c254ba6e45d8e72739281ebc46ea5eb5f101234f3ce171f0e9f5cc86991480"}, - {file = "multidict-6.0.4-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:16ab77bbeb596e14212e7bab8429f24c1579234a3a462105cda4a66904998664"}, - {file = "multidict-6.0.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:bc779e9e6f7fda81b3f9aa58e3a6091d49ad528b11ed19f6621408806204ad35"}, - {file = "multidict-6.0.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:4ceef517eca3e03c1cceb22030a3e39cb399ac86bff4e426d4fc6ae49052cc60"}, - {file = "multidict-6.0.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:281af09f488903fde97923c7744bb001a9b23b039a909460d0f14edc7bf59706"}, - {file = "multidict-6.0.4-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:52f2dffc8acaba9a2f27174c41c9e57f60b907bb9f096b36b1a1f3be71c6284d"}, - {file = "multidict-6.0.4-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b41156839806aecb3641f3208c0dafd3ac7775b9c4c422d82ee2a45c34ba81ca"}, - {file = "multidict-6.0.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d5e3fc56f88cc98ef8139255cf8cd63eb2c586531e43310ff859d6bb3a6b51f1"}, - {file = "multidict-6.0.4-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8316a77808c501004802f9beebde51c9f857054a0c871bd6da8280e718444449"}, - {file = "multidict-6.0.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:f70b98cd94886b49d91170ef23ec5c0e8ebb6f242d734ed7ed677b24d50c82cf"}, - {file = "multidict-6.0.4-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:bf6774e60d67a9efe02b3616fee22441d86fab4c6d335f9d2051d19d90a40063"}, - {file = "multidict-6.0.4-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:e69924bfcdda39b722ef4d9aa762b2dd38e4632b3641b1d9a57ca9cd18f2f83a"}, - {file = "multidict-6.0.4-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:6b181d8c23da913d4ff585afd1155a0e1194c0b50c54fcfe286f70cdaf2b7176"}, - {file = "multidict-6.0.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:52509b5be062d9eafc8170e53026fbc54cf3b32759a23d07fd935fb04fc22d95"}, - {file = "multidict-6.0.4-cp39-cp39-win32.whl", hash = "sha256:27c523fbfbdfd19c6867af7346332b62b586eed663887392cff78d614f9ec313"}, - {file = "multidict-6.0.4-cp39-cp39-win_amd64.whl", hash = "sha256:33029f5734336aa0d4c0384525da0387ef89148dc7191aae00ca5fb23d7aafc2"}, - {file = "multidict-6.0.4.tar.gz", hash = "sha256:3666906492efb76453c0e7b97f2cf459b0682e7402c0489a95484965dbc1da49"}, + {file = "multidict-6.0.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:228b644ae063c10e7f324ab1ab6b548bdf6f8b47f3ec234fef1093bc2735e5f9"}, + {file = "multidict-6.0.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:896ebdcf62683551312c30e20614305f53125750803b614e9e6ce74a96232604"}, + {file = "multidict-6.0.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:411bf8515f3be9813d06004cac41ccf7d1cd46dfe233705933dd163b60e37600"}, + {file = "multidict-6.0.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1d147090048129ce3c453f0292e7697d333db95e52616b3793922945804a433c"}, + {file = "multidict-6.0.5-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:215ed703caf15f578dca76ee6f6b21b7603791ae090fbf1ef9d865571039ade5"}, + {file = "multidict-6.0.5-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7c6390cf87ff6234643428991b7359b5f59cc15155695deb4eda5c777d2b880f"}, + {file = "multidict-6.0.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:21fd81c4ebdb4f214161be351eb5bcf385426bf023041da2fd9e60681f3cebae"}, + {file = "multidict-6.0.5-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3cc2ad10255f903656017363cd59436f2111443a76f996584d1077e43ee51182"}, + {file = "multidict-6.0.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:6939c95381e003f54cd4c5516740faba40cf5ad3eeff460c3ad1d3e0ea2549bf"}, + {file = "multidict-6.0.5-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:220dd781e3f7af2c2c1053da9fa96d9cf3072ca58f057f4c5adaaa1cab8fc442"}, + {file = "multidict-6.0.5-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:766c8f7511df26d9f11cd3a8be623e59cca73d44643abab3f8c8c07620524e4a"}, + {file = "multidict-6.0.5-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:fe5d7785250541f7f5019ab9cba2c71169dc7d74d0f45253f8313f436458a4ef"}, + {file = "multidict-6.0.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c1c1496e73051918fcd4f58ff2e0f2f3066d1c76a0c6aeffd9b45d53243702cc"}, + {file = "multidict-6.0.5-cp310-cp310-win32.whl", hash = "sha256:7afcdd1fc07befad18ec4523a782cde4e93e0a2bf71239894b8d61ee578c1319"}, + {file = "multidict-6.0.5-cp310-cp310-win_amd64.whl", hash = "sha256:99f60d34c048c5c2fabc766108c103612344c46e35d4ed9ae0673d33c8fb26e8"}, + {file = "multidict-6.0.5-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:f285e862d2f153a70586579c15c44656f888806ed0e5b56b64489afe4a2dbfba"}, + {file = "multidict-6.0.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:53689bb4e102200a4fafa9de9c7c3c212ab40a7ab2c8e474491914d2305f187e"}, + {file = "multidict-6.0.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:612d1156111ae11d14afaf3a0669ebf6c170dbb735e510a7438ffe2369a847fd"}, + {file = "multidict-6.0.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7be7047bd08accdb7487737631d25735c9a04327911de89ff1b26b81745bd4e3"}, + {file = "multidict-6.0.5-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:de170c7b4fe6859beb8926e84f7d7d6c693dfe8e27372ce3b76f01c46e489fcf"}, + {file = "multidict-6.0.5-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:04bde7a7b3de05732a4eb39c94574db1ec99abb56162d6c520ad26f83267de29"}, + {file = "multidict-6.0.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:85f67aed7bb647f93e7520633d8f51d3cbc6ab96957c71272b286b2f30dc70ed"}, + {file = "multidict-6.0.5-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:425bf820055005bfc8aa9a0b99ccb52cc2f4070153e34b701acc98d201693733"}, + {file = "multidict-6.0.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d3eb1ceec286eba8220c26f3b0096cf189aea7057b6e7b7a2e60ed36b373b77f"}, + {file = "multidict-6.0.5-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:7901c05ead4b3fb75113fb1dd33eb1253c6d3ee37ce93305acd9d38e0b5f21a4"}, + {file = "multidict-6.0.5-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:e0e79d91e71b9867c73323a3444724d496c037e578a0e1755ae159ba14f4f3d1"}, + {file = "multidict-6.0.5-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:29bfeb0dff5cb5fdab2023a7a9947b3b4af63e9c47cae2a10ad58394b517fddc"}, + {file = "multidict-6.0.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e030047e85cbcedbfc073f71836d62dd5dadfbe7531cae27789ff66bc551bd5e"}, + {file = "multidict-6.0.5-cp311-cp311-win32.whl", hash = "sha256:2f4848aa3baa109e6ab81fe2006c77ed4d3cd1e0ac2c1fbddb7b1277c168788c"}, + {file = "multidict-6.0.5-cp311-cp311-win_amd64.whl", hash = "sha256:2faa5ae9376faba05f630d7e5e6be05be22913782b927b19d12b8145968a85ea"}, + {file = "multidict-6.0.5-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:51d035609b86722963404f711db441cf7134f1889107fb171a970c9701f92e1e"}, + {file = "multidict-6.0.5-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:cbebcd5bcaf1eaf302617c114aa67569dd3f090dd0ce8ba9e35e9985b41ac35b"}, + {file = "multidict-6.0.5-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2ffc42c922dbfddb4a4c3b438eb056828719f07608af27d163191cb3e3aa6cc5"}, + {file = "multidict-6.0.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ceb3b7e6a0135e092de86110c5a74e46bda4bd4fbfeeb3a3bcec79c0f861e450"}, + {file = "multidict-6.0.5-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:79660376075cfd4b2c80f295528aa6beb2058fd289f4c9252f986751a4cd0496"}, + {file = "multidict-6.0.5-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e4428b29611e989719874670fd152b6625500ad6c686d464e99f5aaeeaca175a"}, + {file = "multidict-6.0.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d84a5c3a5f7ce6db1f999fb9438f686bc2e09d38143f2d93d8406ed2dd6b9226"}, + {file = "multidict-6.0.5-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:76c0de87358b192de7ea9649beb392f107dcad9ad27276324c24c91774ca5271"}, + {file = "multidict-6.0.5-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:79a6d2ba910adb2cbafc95dad936f8b9386e77c84c35bc0add315b856d7c3abb"}, + {file = "multidict-6.0.5-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:92d16a3e275e38293623ebf639c471d3e03bb20b8ebb845237e0d3664914caef"}, + {file = "multidict-6.0.5-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:fb616be3538599e797a2017cccca78e354c767165e8858ab5116813146041a24"}, + {file = "multidict-6.0.5-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:14c2976aa9038c2629efa2c148022ed5eb4cb939e15ec7aace7ca932f48f9ba6"}, + {file = "multidict-6.0.5-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:435a0984199d81ca178b9ae2c26ec3d49692d20ee29bc4c11a2a8d4514c67eda"}, + {file = "multidict-6.0.5-cp312-cp312-win32.whl", hash = "sha256:9fe7b0653ba3d9d65cbe7698cca585bf0f8c83dbbcc710db9c90f478e175f2d5"}, + {file = "multidict-6.0.5-cp312-cp312-win_amd64.whl", hash = "sha256:01265f5e40f5a17f8241d52656ed27192be03bfa8764d88e8220141d1e4b3556"}, + {file = "multidict-6.0.5-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:19fe01cea168585ba0f678cad6f58133db2aa14eccaf22f88e4a6dccadfad8b3"}, + {file = "multidict-6.0.5-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6bf7a982604375a8d49b6cc1b781c1747f243d91b81035a9b43a2126c04766f5"}, + {file = "multidict-6.0.5-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:107c0cdefe028703fb5dafe640a409cb146d44a6ae201e55b35a4af8e95457dd"}, + {file = "multidict-6.0.5-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:403c0911cd5d5791605808b942c88a8155c2592e05332d2bf78f18697a5fa15e"}, + {file = "multidict-6.0.5-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aeaf541ddbad8311a87dd695ed9642401131ea39ad7bc8cf3ef3967fd093b626"}, + {file = "multidict-6.0.5-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e4972624066095e52b569e02b5ca97dbd7a7ddd4294bf4e7247d52635630dd83"}, + {file = "multidict-6.0.5-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:d946b0a9eb8aaa590df1fe082cee553ceab173e6cb5b03239716338629c50c7a"}, + {file = "multidict-6.0.5-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:b55358304d7a73d7bdf5de62494aaf70bd33015831ffd98bc498b433dfe5b10c"}, + {file = "multidict-6.0.5-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:a3145cb08d8625b2d3fee1b2d596a8766352979c9bffe5d7833e0503d0f0b5e5"}, + {file = "multidict-6.0.5-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:d65f25da8e248202bd47445cec78e0025c0fe7582b23ec69c3b27a640dd7a8e3"}, + {file = "multidict-6.0.5-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:c9bf56195c6bbd293340ea82eafd0071cb3d450c703d2c93afb89f93b8386ccc"}, + {file = "multidict-6.0.5-cp37-cp37m-win32.whl", hash = "sha256:69db76c09796b313331bb7048229e3bee7928eb62bab5e071e9f7fcc4879caee"}, + {file = "multidict-6.0.5-cp37-cp37m-win_amd64.whl", hash = "sha256:fce28b3c8a81b6b36dfac9feb1de115bab619b3c13905b419ec71d03a3fc1423"}, + {file = "multidict-6.0.5-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:76f067f5121dcecf0d63a67f29080b26c43c71a98b10c701b0677e4a065fbd54"}, + {file = "multidict-6.0.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:b82cc8ace10ab5bd93235dfaab2021c70637005e1ac787031f4d1da63d493c1d"}, + {file = "multidict-6.0.5-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:5cb241881eefd96b46f89b1a056187ea8e9ba14ab88ba632e68d7a2ecb7aadf7"}, + {file = "multidict-6.0.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e8e94e6912639a02ce173341ff62cc1201232ab86b8a8fcc05572741a5dc7d93"}, + {file = "multidict-6.0.5-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:09a892e4a9fb47331da06948690ae38eaa2426de97b4ccbfafbdcbe5c8f37ff8"}, + {file = "multidict-6.0.5-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:55205d03e8a598cfc688c71ca8ea5f66447164efff8869517f175ea632c7cb7b"}, + {file = "multidict-6.0.5-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:37b15024f864916b4951adb95d3a80c9431299080341ab9544ed148091b53f50"}, + {file = "multidict-6.0.5-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f2a1dee728b52b33eebff5072817176c172050d44d67befd681609b4746e1c2e"}, + {file = "multidict-6.0.5-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:edd08e6f2f1a390bf137080507e44ccc086353c8e98c657e666c017718561b89"}, + {file = "multidict-6.0.5-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:60d698e8179a42ec85172d12f50b1668254628425a6bd611aba022257cac1386"}, + {file = "multidict-6.0.5-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:3d25f19500588cbc47dc19081d78131c32637c25804df8414463ec908631e453"}, + {file = "multidict-6.0.5-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:4cc0ef8b962ac7a5e62b9e826bd0cd5040e7d401bc45a6835910ed699037a461"}, + {file = "multidict-6.0.5-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:eca2e9d0cc5a889850e9bbd68e98314ada174ff6ccd1129500103df7a94a7a44"}, + {file = "multidict-6.0.5-cp38-cp38-win32.whl", hash = "sha256:4a6a4f196f08c58c59e0b8ef8ec441d12aee4125a7d4f4fef000ccb22f8d7241"}, + {file = "multidict-6.0.5-cp38-cp38-win_amd64.whl", hash = "sha256:0275e35209c27a3f7951e1ce7aaf93ce0d163b28948444bec61dd7badc6d3f8c"}, + {file = "multidict-6.0.5-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:e7be68734bd8c9a513f2b0cfd508802d6609da068f40dc57d4e3494cefc92929"}, + {file = "multidict-6.0.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:1d9ea7a7e779d7a3561aade7d596649fbecfa5c08a7674b11b423783217933f9"}, + {file = "multidict-6.0.5-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ea1456df2a27c73ce51120fa2f519f1bea2f4a03a917f4a43c8707cf4cbbae1a"}, + {file = "multidict-6.0.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cf590b134eb70629e350691ecca88eac3e3b8b3c86992042fb82e3cb1830d5e1"}, + {file = "multidict-6.0.5-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5c0631926c4f58e9a5ccce555ad7747d9a9f8b10619621f22f9635f069f6233e"}, + {file = "multidict-6.0.5-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dce1c6912ab9ff5f179eaf6efe7365c1f425ed690b03341911bf4939ef2f3046"}, + {file = "multidict-6.0.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c0868d64af83169e4d4152ec612637a543f7a336e4a307b119e98042e852ad9c"}, + {file = "multidict-6.0.5-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:141b43360bfd3bdd75f15ed811850763555a251e38b2405967f8e25fb43f7d40"}, + {file = "multidict-6.0.5-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:7df704ca8cf4a073334e0427ae2345323613e4df18cc224f647f251e5e75a527"}, + {file = "multidict-6.0.5-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:6214c5a5571802c33f80e6c84713b2c79e024995b9c5897f794b43e714daeec9"}, + {file = "multidict-6.0.5-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:cd6c8fca38178e12c00418de737aef1261576bd1b6e8c6134d3e729a4e858b38"}, + {file = "multidict-6.0.5-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:e02021f87a5b6932fa6ce916ca004c4d441509d33bbdbeca70d05dff5e9d2479"}, + {file = "multidict-6.0.5-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:ebd8d160f91a764652d3e51ce0d2956b38efe37c9231cd82cfc0bed2e40b581c"}, + {file = "multidict-6.0.5-cp39-cp39-win32.whl", hash = "sha256:04da1bb8c8dbadf2a18a452639771951c662c5ad03aefe4884775454be322c9b"}, + {file = "multidict-6.0.5-cp39-cp39-win_amd64.whl", hash = "sha256:d6f6d4f185481c9669b9447bf9d9cf3b95a0e9df9d169bbc17e363b7d5487755"}, + {file = "multidict-6.0.5-py3-none-any.whl", hash = "sha256:0d63c74e3d7ab26de115c49bffc92cc77ed23395303d496eae515d4204a625e7"}, + {file = "multidict-6.0.5.tar.gz", hash = "sha256:f7e301075edaf50500f0b341543c41194d8df3ae5caf4702f2095f3ca73dd8da"}, +] + +[[package]] +name = "multivolumefile" +version = "0.2.3" +description = "multi volume file wrapper library" +optional = false +python-versions = ">=3.6" +files = [ + {file = "multivolumefile-0.2.3-py3-none-any.whl", hash = "sha256:237f4353b60af1703087cf7725755a1f6fcaeeea48421e1896940cd1c920d678"}, + {file = "multivolumefile-0.2.3.tar.gz", hash = "sha256:a0648d0aafbc96e59198d5c17e9acad7eb531abea51035d08ce8060dcad709d6"}, ] +[package.extras] +check = ["check-manifest", "flake8", "flake8-black", "isort (>=5.0.3)", "pygments", "readme-renderer", "twine"] +test = ["coverage[toml] (>=5.2)", "coveralls (>=2.1.1)", "hypothesis", "pyannotate", "pytest", "pytest-cov"] +type = ["mypy", "mypy-extensions"] + [[package]] name = "mypy-extensions" version = "0.4.3" @@ -1185,6 +1458,17 @@ files = [ {file = "mypy_extensions-0.4.3.tar.gz", hash = "sha256:2d82818f5bb3e369420cb3c4060a7970edba416647068eb4c5343488a6c604a8"}, ] +[[package]] +name = "packaging" +version = "24.0" +description = "Core utilities for Python packages" +optional = false +python-versions = ">=3.7" +files = [ + {file = "packaging-24.0-py3-none-any.whl", hash = "sha256:2ddfb553fdf02fb784c234c7ba6ccc288296ceabec964ad2eae3777778130bc5"}, + {file = "packaging-24.0.tar.gz", hash = "sha256:eb82c5e3e56209074766e6885bb04b8c38a0c015d0a30036ebe7ece34c9989e9"}, +] + [[package]] name = "paste" version = "3.5.2" @@ -1260,74 +1544,142 @@ files = [ {file = "protobuf-3.18.3.tar.gz", hash = "sha256:196a153e487c0e20d62259872bbf2e1c4fa18e2ce97e20984fcbf9d8b151058d"}, ] +[[package]] +name = "psutil" +version = "5.9.8" +description = "Cross-platform lib for process and system monitoring in Python." +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*" +files = [ + {file = "psutil-5.9.8-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:26bd09967ae00920df88e0352a91cff1a78f8d69b3ecabbfe733610c0af486c8"}, + {file = "psutil-5.9.8-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:05806de88103b25903dff19bb6692bd2e714ccf9e668d050d144012055cbca73"}, + {file = "psutil-5.9.8-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:611052c4bc70432ec770d5d54f64206aa7203a101ec273a0cd82418c86503bb7"}, + {file = "psutil-5.9.8-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:50187900d73c1381ba1454cf40308c2bf6f34268518b3f36a9b663ca87e65e36"}, + {file = "psutil-5.9.8-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:02615ed8c5ea222323408ceba16c60e99c3f91639b07da6373fb7e6539abc56d"}, + {file = "psutil-5.9.8-cp27-none-win32.whl", hash = "sha256:36f435891adb138ed3c9e58c6af3e2e6ca9ac2f365efe1f9cfef2794e6c93b4e"}, + {file = "psutil-5.9.8-cp27-none-win_amd64.whl", hash = "sha256:bd1184ceb3f87651a67b2708d4c3338e9b10c5df903f2e3776b62303b26cb631"}, + {file = "psutil-5.9.8-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:aee678c8720623dc456fa20659af736241f575d79429a0e5e9cf88ae0605cc81"}, + {file = "psutil-5.9.8-cp36-abi3-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8cb6403ce6d8e047495a701dc7c5bd788add903f8986d523e3e20b98b733e421"}, + {file = "psutil-5.9.8-cp36-abi3-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d06016f7f8625a1825ba3732081d77c94589dca78b7a3fc072194851e88461a4"}, + {file = "psutil-5.9.8-cp36-cp36m-win32.whl", hash = "sha256:7d79560ad97af658a0f6adfef8b834b53f64746d45b403f225b85c5c2c140eee"}, + {file = "psutil-5.9.8-cp36-cp36m-win_amd64.whl", hash = "sha256:27cc40c3493bb10de1be4b3f07cae4c010ce715290a5be22b98493509c6299e2"}, + {file = "psutil-5.9.8-cp37-abi3-win32.whl", hash = "sha256:bc56c2a1b0d15aa3eaa5a60c9f3f8e3e565303b465dbf57a1b730e7a2b9844e0"}, + {file = "psutil-5.9.8-cp37-abi3-win_amd64.whl", hash = "sha256:8db4c1b57507eef143a15a6884ca10f7c73876cdf5d51e713151c1236a0e68cf"}, + {file = "psutil-5.9.8-cp38-abi3-macosx_11_0_arm64.whl", hash = "sha256:d16bbddf0693323b8c6123dd804100241da461e41d6e332fb0ba6058f630f8c8"}, + {file = "psutil-5.9.8.tar.gz", hash = "sha256:6be126e3225486dff286a8fb9a06246a5253f4c7c53b475ea5f5ac934e64194c"}, +] + +[package.extras] +test = ["enum34", "ipaddress", "mock", "pywin32", "wmi"] + [[package]] name = "psycopg2-binary" -version = "2.9.4" +version = "2.9.9" description = "psycopg2 - Python-PostgreSQL Database Adapter" optional = false -python-versions = ">=3.6" +python-versions = ">=3.7" files = [ - {file = "psycopg2-binary-2.9.4.tar.gz", hash = "sha256:a6a2d3d75d8698dee492f4af7ad07606d0734e581edf9e2ce2f74b6fce90f42e"}, - {file = "psycopg2_binary-2.9.4-cp310-cp310-macosx_10_15_x86_64.macosx_10_9_intel.macosx_10_9_x86_64.macosx_10_10_intel.macosx_10_10_x86_64.whl", hash = "sha256:e72491d72870c3cb2f0d6f4174485533caec0e9ed7e717e2859b7cc7ff2ae1c4"}, - {file = "psycopg2_binary-2.9.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2903bf90b1e6bfc9bbfc94a1db0b50ffa9830a0ca4c042fbc38d93890c02ce08"}, - {file = "psycopg2_binary-2.9.4-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:15e0ac0ed8a85f6049e836e95ddee627766561c85be8d23f4b3edb6ddbaa7310"}, - {file = "psycopg2_binary-2.9.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:edf0a66ce9517365c7dcfed597894d8dd1f27b59e550b77a089054101435213b"}, - {file = "psycopg2_binary-2.9.4-cp310-cp310-manylinux_2_24_aarch64.whl", hash = "sha256:61c6a258469c66412ae8358a0501df6ccb3bb48aa9c43b56624571ff9767f91d"}, - {file = "psycopg2_binary-2.9.4-cp310-cp310-manylinux_2_24_ppc64le.whl", hash = "sha256:704f1fcdc5b606b70563ea696c69bda90caee3a2f45ffc9cee60a901b394a79f"}, - {file = "psycopg2_binary-2.9.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:30200b07779446760813eef06098ec6d084131e4365b4e023eb43100de758b11"}, - {file = "psycopg2_binary-2.9.4-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:f5fbb3b325c65010e04af206a9243e2df8606736c510c7f268aca6a93e5294a9"}, - {file = "psycopg2_binary-2.9.4-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:52383e932e6de5595963f9178cf2af7b9e1f3daacf5135b9c0e21aabbc5bf7c4"}, - {file = "psycopg2_binary-2.9.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:0d8e0c9eec79fe1ae66691e06e3cc714da6fbd77981209bf32fa823c03dbaff8"}, - {file = "psycopg2_binary-2.9.4-cp310-cp310-win32.whl", hash = "sha256:161dc52a617f0bb610a87d391cb2e77fe65b89ebfbd752f4f3217dde701ea196"}, - {file = "psycopg2_binary-2.9.4-cp310-cp310-win_amd64.whl", hash = "sha256:33ac8b4754e6b6b21f3ee180da169d8526d91aee9408ec1fc573c16ab32b0207"}, - {file = "psycopg2_binary-2.9.4-cp36-cp36m-macosx_10_14_x86_64.macosx_10_9_intel.macosx_10_9_x86_64.macosx_10_10_intel.macosx_10_10_x86_64.whl", hash = "sha256:7751b11cd7f6b952b4b5ec5b93b5be9ce20faba786c18c25c354f5d8717a173c"}, - {file = "psycopg2_binary-2.9.4-cp36-cp36m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b216a15e13f6e763db40ac3beb74b588650bc030d10a78fde182b88d273b82b5"}, - {file = "psycopg2_binary-2.9.4-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0eae72190be519bf2629062eab7ac8d4ceec5bd132953cefa1596584d86964fe"}, - {file = "psycopg2_binary-2.9.4-cp36-cp36m-manylinux_2_24_aarch64.whl", hash = "sha256:fb639a0e65dce4a9cccbcbdd8ddd0c8c6ab10bca317b827a5c52ac3c3a4ad60a"}, - {file = "psycopg2_binary-2.9.4-cp36-cp36m-manylinux_2_24_ppc64le.whl", hash = "sha256:80ed219ce6cb21a5b53ead0edf5b56b6d23de4cb95389ac606f47670474f4816"}, - {file = "psycopg2_binary-2.9.4-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:f78cafa25731e0b5aa16fe20bea1abf643d4e853f6bfb8a64421b06b878e2b88"}, - {file = "psycopg2_binary-2.9.4-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:34fd249275faa782c3a2016e86ac2330636ac58d731a1580e7d686e3976b9536"}, - {file = "psycopg2_binary-2.9.4-cp36-cp36m-musllinux_1_1_ppc64le.whl", hash = "sha256:24d627ed69e754c48dd142a914124858c600b4108c92546eb0ba822e63c0c6e2"}, - {file = "psycopg2_binary-2.9.4-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:65d5f4e70a2d3fbaa1349236968792611088f3f2dccead36c1626e1d183cc327"}, - {file = "psycopg2_binary-2.9.4-cp36-cp36m-win32.whl", hash = "sha256:ae5b41dbf7731b838021923edfbe3b5ccdec84d92d5795f5229c0d08d32509d9"}, - {file = "psycopg2_binary-2.9.4-cp36-cp36m-win_amd64.whl", hash = "sha256:97e4f3d9b17d12e7c00cb1c29c0040044135cd5146838da4274615dbe0baae78"}, - {file = "psycopg2_binary-2.9.4-cp37-cp37m-macosx_10_15_x86_64.macosx_10_9_intel.macosx_10_9_x86_64.macosx_10_10_intel.macosx_10_10_x86_64.whl", hash = "sha256:8660112e9127a019969a23c878e1b4a419e8a6427f9a9050c19830f152628c8a"}, - {file = "psycopg2_binary-2.9.4-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ea8d5cd689fa7225d81ae0a049ba03e0165f4ed9ca083b19a405be9ad0b36845"}, - {file = "psycopg2_binary-2.9.4-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:63edc507f8cbfbb5903adb75bad8a99f9798981c854df9119dbebab2ec3ee0e1"}, - {file = "psycopg2_binary-2.9.4-cp37-cp37m-manylinux_2_24_aarch64.whl", hash = "sha256:25e0517ad7ee3c5c3c69dbe3c1d95504c811e42f452b39a3505d0763b1f6caa0"}, - {file = "psycopg2_binary-2.9.4-cp37-cp37m-manylinux_2_24_ppc64le.whl", hash = "sha256:0a9465f0aa36480c8e7614991cbe8ca8aa16b0517c5398a49648ce345e446c19"}, - {file = "psycopg2_binary-2.9.4-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:aff258af03dda9a990960a53759d10c3a9b936837c71fe2f3b581acd356b9121"}, - {file = "psycopg2_binary-2.9.4-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:576b9dfbcd154a0e8b5d9dae6316d037450e64a3b31df87dec71d88e2a2d5e5f"}, - {file = "psycopg2_binary-2.9.4-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:044b6ab68613de7ea1e63856627deea091bfea09dea5ab4f050b13250fd18cab"}, - {file = "psycopg2_binary-2.9.4-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:7b47643c45e7619788c081d42e1d9d98c7c8a4933010a9967d097cc3c4c29f41"}, - {file = "psycopg2_binary-2.9.4-cp37-cp37m-win32.whl", hash = "sha256:82df4a8600999c4c0cb7d6614df1bbdb3c74732f63e79f78487893ffbed3d083"}, - {file = "psycopg2_binary-2.9.4-cp37-cp37m-win_amd64.whl", hash = "sha256:8d7bc25729bb6d96b44f49ad78fde0e27a1a867cb205322b7e5f5b49e04d6f1f"}, - {file = "psycopg2_binary-2.9.4-cp38-cp38-macosx_10_15_x86_64.macosx_10_9_intel.macosx_10_9_x86_64.macosx_10_10_intel.macosx_10_10_x86_64.whl", hash = "sha256:2f1ded23d17af0d738e7e78087f0b88a53228887845b1989b03af4dfd3fef703"}, - {file = "psycopg2_binary-2.9.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:f225784812b2b57d340f2eb0d2cebef989dcc82c288f5553e28ee9767c7c8344"}, - {file = "psycopg2_binary-2.9.4-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:89a86c2b35460700d04b4d6461153ab39ee85af5a5385acac9563a8310e6320a"}, - {file = "psycopg2_binary-2.9.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:59a3010d566a48b919490a982f6807f68842686941dc12d568e129d9cd7703d6"}, - {file = "psycopg2_binary-2.9.4-cp38-cp38-manylinux_2_24_aarch64.whl", hash = "sha256:02cde837df012fa5d579b9cf4bc8e1feb460f38d61f7a4ab4a919d55a9f6eeef"}, - {file = "psycopg2_binary-2.9.4-cp38-cp38-manylinux_2_24_ppc64le.whl", hash = "sha256:226f11be577b70a57f4910c0ee28591d4d9fcb3d455e966267179156ae2e0c41"}, - {file = "psycopg2_binary-2.9.4-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:181ac372a5a5308b4076933601a9b5f0cd139b389b0aa5e164786a2abbcdb978"}, - {file = "psycopg2_binary-2.9.4-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:d5f27b1d1b56470385faa2b2636fcb823e7ac5b5b734e0aa76b14637c66eb3b7"}, - {file = "psycopg2_binary-2.9.4-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:55137faec669c4277c5687c6ce7c1fbc4dece0e2f14256ee808f4a652f0a2170"}, - {file = "psycopg2_binary-2.9.4-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:ffb2f288f577a748cc23c65a818290755a4c2da1f87a40d7055b61a096d31e20"}, - {file = "psycopg2_binary-2.9.4-cp38-cp38-win32.whl", hash = "sha256:451550e0bb5889bbabbf92575a6d6eafced941cc28c86be6ae4667f81bf32d67"}, - {file = "psycopg2_binary-2.9.4-cp38-cp38-win_amd64.whl", hash = "sha256:b23b25b1243576b952689966205ef7d4285688068b966a1ca0e620bcb390d483"}, - {file = "psycopg2_binary-2.9.4-cp39-cp39-macosx_10_15_x86_64.macosx_10_9_intel.macosx_10_9_x86_64.macosx_10_10_intel.macosx_10_10_x86_64.whl", hash = "sha256:7ad9d032dc1a31a86ca7b059f43554a049a2bfda8fe32d1492ad25f6686aff03"}, - {file = "psycopg2_binary-2.9.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:7b01d07006a0ac2216921b69a220b9f0974345d0b1b36efaeabdc7550b1cc4f8"}, - {file = "psycopg2_binary-2.9.4-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eb5341fc7c53fdd95ac2415be77b1de854ab266488cff71174ebb007baf0e675"}, - {file = "psycopg2_binary-2.9.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a431deb6ffdfa551f7400b3a94fa4b964837e67f49e3c37aa26d90dc75970816"}, - {file = "psycopg2_binary-2.9.4-cp39-cp39-manylinux_2_24_aarch64.whl", hash = "sha256:d6ba33f39436191ece7ea2b3d0b4dff00af71acd5c6e6f1d6b7563aa7286e9f2"}, - {file = "psycopg2_binary-2.9.4-cp39-cp39-manylinux_2_24_ppc64le.whl", hash = "sha256:d6c5e1df6f427d7a82606cf8f07cf3ba9fb3f366804b01e65f1f00f8df6b54f1"}, - {file = "psycopg2_binary-2.9.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:1c22c59ab7d9dc110d409445f111f58556bf699b0548f3fc5176684a29c629c4"}, - {file = "psycopg2_binary-2.9.4-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:b896637091cde69d170a89253dde9aee814b25ca204b7e213fd0a6462e666638"}, - {file = "psycopg2_binary-2.9.4-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:2535f44b00f26f6af0e949c825e6aecb9adcb56c965c17af5b97137fb69f00c0"}, - {file = "psycopg2_binary-2.9.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:6a1618260a112a9c93504511f0b6254b4402a8c41b7130dc6d4c9e39aff3aa0c"}, - {file = "psycopg2_binary-2.9.4-cp39-cp39-win32.whl", hash = "sha256:e02f77b620ad6b36564fe41980865436912e21a3b1138cdde175cf24afde1bc5"}, - {file = "psycopg2_binary-2.9.4-cp39-cp39-win_amd64.whl", hash = "sha256:44f5dc9b4384bafca8429759ce76c8960ffc2b583fcad9e5dfb3e5f4894269e4"}, + {file = "psycopg2-binary-2.9.9.tar.gz", hash = "sha256:7f01846810177d829c7692f1f5ada8096762d9172af1b1a28d4ab5b77c923c1c"}, + {file = "psycopg2_binary-2.9.9-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c2470da5418b76232f02a2fcd2229537bb2d5a7096674ce61859c3229f2eb202"}, + {file = "psycopg2_binary-2.9.9-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c6af2a6d4b7ee9615cbb162b0738f6e1fd1f5c3eda7e5da17861eacf4c717ea7"}, + {file = "psycopg2_binary-2.9.9-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:75723c3c0fbbf34350b46a3199eb50638ab22a0228f93fb472ef4d9becc2382b"}, + {file = "psycopg2_binary-2.9.9-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:83791a65b51ad6ee6cf0845634859d69a038ea9b03d7b26e703f94c7e93dbcf9"}, + {file = "psycopg2_binary-2.9.9-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0ef4854e82c09e84cc63084a9e4ccd6d9b154f1dbdd283efb92ecd0b5e2b8c84"}, + {file = "psycopg2_binary-2.9.9-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ed1184ab8f113e8d660ce49a56390ca181f2981066acc27cf637d5c1e10ce46e"}, + {file = "psycopg2_binary-2.9.9-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:d2997c458c690ec2bc6b0b7ecbafd02b029b7b4283078d3b32a852a7ce3ddd98"}, + {file = "psycopg2_binary-2.9.9-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:b58b4710c7f4161b5e9dcbe73bb7c62d65670a87df7bcce9e1faaad43e715245"}, + {file = "psycopg2_binary-2.9.9-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:0c009475ee389757e6e34611d75f6e4f05f0cf5ebb76c6037508318e1a1e0d7e"}, + {file = "psycopg2_binary-2.9.9-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:8dbf6d1bc73f1d04ec1734bae3b4fb0ee3cb2a493d35ede9badbeb901fb40f6f"}, + {file = "psycopg2_binary-2.9.9-cp310-cp310-win32.whl", hash = "sha256:3f78fd71c4f43a13d342be74ebbc0666fe1f555b8837eb113cb7416856c79682"}, + {file = "psycopg2_binary-2.9.9-cp310-cp310-win_amd64.whl", hash = "sha256:876801744b0dee379e4e3c38b76fc89f88834bb15bf92ee07d94acd06ec890a0"}, + {file = "psycopg2_binary-2.9.9-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ee825e70b1a209475622f7f7b776785bd68f34af6e7a46e2e42f27b659b5bc26"}, + {file = "psycopg2_binary-2.9.9-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1ea665f8ce695bcc37a90ee52de7a7980be5161375d42a0b6c6abedbf0d81f0f"}, + {file = "psycopg2_binary-2.9.9-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:143072318f793f53819048fdfe30c321890af0c3ec7cb1dfc9cc87aa88241de2"}, + {file = "psycopg2_binary-2.9.9-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c332c8d69fb64979ebf76613c66b985414927a40f8defa16cf1bc028b7b0a7b0"}, + {file = "psycopg2_binary-2.9.9-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f7fc5a5acafb7d6ccca13bfa8c90f8c51f13d8fb87d95656d3950f0158d3ce53"}, + {file = "psycopg2_binary-2.9.9-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:977646e05232579d2e7b9c59e21dbe5261f403a88417f6a6512e70d3f8a046be"}, + {file = "psycopg2_binary-2.9.9-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:b6356793b84728d9d50ead16ab43c187673831e9d4019013f1402c41b1db9b27"}, + {file = "psycopg2_binary-2.9.9-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:bc7bb56d04601d443f24094e9e31ae6deec9ccb23581f75343feebaf30423359"}, + {file = "psycopg2_binary-2.9.9-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:77853062a2c45be16fd6b8d6de2a99278ee1d985a7bd8b103e97e41c034006d2"}, + {file = "psycopg2_binary-2.9.9-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:78151aa3ec21dccd5cdef6c74c3e73386dcdfaf19bced944169697d7ac7482fc"}, + {file = "psycopg2_binary-2.9.9-cp311-cp311-win32.whl", hash = "sha256:dc4926288b2a3e9fd7b50dc6a1909a13bbdadfc67d93f3374d984e56f885579d"}, + {file = "psycopg2_binary-2.9.9-cp311-cp311-win_amd64.whl", hash = "sha256:b76bedd166805480ab069612119ea636f5ab8f8771e640ae103e05a4aae3e417"}, + {file = "psycopg2_binary-2.9.9-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:8532fd6e6e2dc57bcb3bc90b079c60de896d2128c5d9d6f24a63875a95a088cf"}, + {file = "psycopg2_binary-2.9.9-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8f8544b092a29a6ddd72f3556a9fcf249ec412e10ad28be6a0c0d948924f2212"}, + {file = "psycopg2_binary-2.9.9-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2d423c8d8a3c82d08fe8af900ad5b613ce3632a1249fd6a223941d0735fce493"}, + {file = "psycopg2_binary-2.9.9-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2e5afae772c00980525f6d6ecf7cbca55676296b580c0e6abb407f15f3706996"}, + {file = "psycopg2_binary-2.9.9-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e6f98446430fdf41bd36d4faa6cb409f5140c1c2cf58ce0bbdaf16af7d3f119"}, + {file = "psycopg2_binary-2.9.9-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:c77e3d1862452565875eb31bdb45ac62502feabbd53429fdc39a1cc341d681ba"}, + {file = "psycopg2_binary-2.9.9-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:cb16c65dcb648d0a43a2521f2f0a2300f40639f6f8c1ecbc662141e4e3e1ee07"}, + {file = "psycopg2_binary-2.9.9-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:911dda9c487075abd54e644ccdf5e5c16773470a6a5d3826fda76699410066fb"}, + {file = "psycopg2_binary-2.9.9-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:57fede879f08d23c85140a360c6a77709113efd1c993923c59fde17aa27599fe"}, + {file = "psycopg2_binary-2.9.9-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:2293b001e319ab0d869d660a704942c9e2cce19745262a8aba2115ef41a0a42a"}, + {file = "psycopg2_binary-2.9.9-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:03ef7df18daf2c4c07e2695e8cfd5ee7f748a1d54d802330985a78d2a5a6dca9"}, + {file = "psycopg2_binary-2.9.9-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0a602ea5aff39bb9fac6308e9c9d82b9a35c2bf288e184a816002c9fae930b77"}, + {file = "psycopg2_binary-2.9.9-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8359bf4791968c5a78c56103702000105501adb557f3cf772b2c207284273984"}, + {file = "psycopg2_binary-2.9.9-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:275ff571376626195ab95a746e6a04c7df8ea34638b99fc11160de91f2fef503"}, + {file = "psycopg2_binary-2.9.9-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:f9b5571d33660d5009a8b3c25dc1db560206e2d2f89d3df1cb32d72c0d117d52"}, + {file = "psycopg2_binary-2.9.9-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:420f9bbf47a02616e8554e825208cb947969451978dceb77f95ad09c37791dae"}, + {file = "psycopg2_binary-2.9.9-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:4154ad09dac630a0f13f37b583eae260c6aa885d67dfbccb5b02c33f31a6d420"}, + {file = "psycopg2_binary-2.9.9-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:a148c5d507bb9b4f2030a2025c545fccb0e1ef317393eaba42e7eabd28eb6041"}, + {file = "psycopg2_binary-2.9.9-cp37-cp37m-win32.whl", hash = "sha256:68fc1f1ba168724771e38bee37d940d2865cb0f562380a1fb1ffb428b75cb692"}, + {file = "psycopg2_binary-2.9.9-cp37-cp37m-win_amd64.whl", hash = "sha256:281309265596e388ef483250db3640e5f414168c5a67e9c665cafce9492eda2f"}, + {file = "psycopg2_binary-2.9.9-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:60989127da422b74a04345096c10d416c2b41bd7bf2a380eb541059e4e999980"}, + {file = "psycopg2_binary-2.9.9-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:246b123cc54bb5361588acc54218c8c9fb73068bf227a4a531d8ed56fa3ca7d6"}, + {file = "psycopg2_binary-2.9.9-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:34eccd14566f8fe14b2b95bb13b11572f7c7d5c36da61caf414d23b91fcc5d94"}, + {file = "psycopg2_binary-2.9.9-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:18d0ef97766055fec15b5de2c06dd8e7654705ce3e5e5eed3b6651a1d2a9a152"}, + {file = "psycopg2_binary-2.9.9-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d3f82c171b4ccd83bbaf35aa05e44e690113bd4f3b7b6cc54d2219b132f3ae55"}, + {file = "psycopg2_binary-2.9.9-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ead20f7913a9c1e894aebe47cccf9dc834e1618b7aa96155d2091a626e59c972"}, + {file = "psycopg2_binary-2.9.9-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:ca49a8119c6cbd77375ae303b0cfd8c11f011abbbd64601167ecca18a87e7cdd"}, + {file = "psycopg2_binary-2.9.9-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:323ba25b92454adb36fa425dc5cf6f8f19f78948cbad2e7bc6cdf7b0d7982e59"}, + {file = "psycopg2_binary-2.9.9-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:1236ed0952fbd919c100bc839eaa4a39ebc397ed1c08a97fc45fee2a595aa1b3"}, + {file = "psycopg2_binary-2.9.9-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:729177eaf0aefca0994ce4cffe96ad3c75e377c7b6f4efa59ebf003b6d398716"}, + {file = "psycopg2_binary-2.9.9-cp38-cp38-win32.whl", hash = "sha256:804d99b24ad523a1fe18cc707bf741670332f7c7412e9d49cb5eab67e886b9b5"}, + {file = "psycopg2_binary-2.9.9-cp38-cp38-win_amd64.whl", hash = "sha256:a6cdcc3ede532f4a4b96000b6362099591ab4a3e913d70bcbac2b56c872446f7"}, + {file = "psycopg2_binary-2.9.9-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:72dffbd8b4194858d0941062a9766f8297e8868e1dd07a7b36212aaa90f49472"}, + {file = "psycopg2_binary-2.9.9-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:30dcc86377618a4c8f3b72418df92e77be4254d8f89f14b8e8f57d6d43603c0f"}, + {file = "psycopg2_binary-2.9.9-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:31a34c508c003a4347d389a9e6fcc2307cc2150eb516462a7a17512130de109e"}, + {file = "psycopg2_binary-2.9.9-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:15208be1c50b99203fe88d15695f22a5bed95ab3f84354c494bcb1d08557df67"}, + {file = "psycopg2_binary-2.9.9-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1873aade94b74715be2246321c8650cabf5a0d098a95bab81145ffffa4c13876"}, + {file = "psycopg2_binary-2.9.9-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3a58c98a7e9c021f357348867f537017057c2ed7f77337fd914d0bedb35dace7"}, + {file = "psycopg2_binary-2.9.9-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:4686818798f9194d03c9129a4d9a702d9e113a89cb03bffe08c6cf799e053291"}, + {file = "psycopg2_binary-2.9.9-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:ebdc36bea43063116f0486869652cb2ed7032dbc59fbcb4445c4862b5c1ecf7f"}, + {file = "psycopg2_binary-2.9.9-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:ca08decd2697fdea0aea364b370b1249d47336aec935f87b8bbfd7da5b2ee9c1"}, + {file = "psycopg2_binary-2.9.9-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:ac05fb791acf5e1a3e39402641827780fe44d27e72567a000412c648a85ba860"}, + {file = "psycopg2_binary-2.9.9-cp39-cp39-win32.whl", hash = "sha256:9dba73be7305b399924709b91682299794887cbbd88e38226ed9f6712eabee90"}, + {file = "psycopg2_binary-2.9.9-cp39-cp39-win_amd64.whl", hash = "sha256:f7ae5d65ccfbebdfa761585228eb4d0df3a8b15cfb53bd953e713e09fbb12957"}, +] + +[[package]] +name = "py7zr" +version = "0.21.0" +description = "Pure python 7-zip library" +optional = false +python-versions = ">=3.7" +files = [ + {file = "py7zr-0.21.0-py3-none-any.whl", hash = "sha256:ea6ded2e5c6d8539e3406cb3b0317192b32af59cff13eaf87702acc36a274da6"}, + {file = "py7zr-0.21.0.tar.gz", hash = "sha256:213a9cc46940fb8f63b4163643a8f5b36bbc798134746c3992d3bc6b14edab87"}, ] +[package.dependencies] +brotli = {version = ">=1.1.0", markers = "platform_python_implementation == \"CPython\""} +brotlicffi = {version = ">=1.1.0.0", markers = "platform_python_implementation == \"PyPy\""} +inflate64 = ">=1.0.0,<1.1.0" +multivolumefile = ">=0.2.3" +psutil = {version = "*", markers = "sys_platform != \"cygwin\""} +pybcj = ">=1.0.0,<1.1.0" +pycryptodomex = ">=3.16.0" +pyppmd = ">=1.1.0,<1.2.0" +pyzstd = ">=0.15.9" +texttable = "*" + +[package.extras] +check = ["black (>=23.1.0)", "check-manifest", "flake8 (<8)", "flake8-black (>=0.3.6)", "flake8-deprecated", "flake8-isort", "isort (>=5.0.3)", "lxml", "mypy (>=0.940)", "mypy-extensions (>=0.4.1)", "pygments", "readme-renderer", "twine", "types-psutil"] +debug = ["pytest", "pytest-leaks", "pytest-profiling"] +docs = ["docutils", "sphinx (>=5.0)", "sphinx-a4doc", "sphinx-py3doc-enhanced-theme"] +test = ["coverage[toml] (>=5.2)", "coveralls (>=2.1.1)", "py-cpuinfo", "pyannotate", "pytest", "pytest-benchmark", "pytest-cov", "pytest-remotedata", "pytest-timeout"] +test-compat = ["libarchive-c"] + [[package]] name = "pyasn1" version = "0.4.8" @@ -1339,6 +1691,60 @@ files = [ {file = "pyasn1-0.4.8.tar.gz", hash = "sha256:aef77c9fb94a3ac588e87841208bdec464471d9871bd5050a287cc9a475cd0ba"}, ] +[[package]] +name = "pybcj" +version = "1.0.2" +description = "bcj filter library" +optional = false +python-versions = ">=3.8" +files = [ + {file = "pybcj-1.0.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:7bff28d97e47047d69a4ac6bf59adda738cf1d00adde8819117fdb65d966bdbc"}, + {file = "pybcj-1.0.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:198e0b4768b4025eb3309273d7e81dc53834b9a50092be6e0d9b3983cfd35c35"}, + {file = "pybcj-1.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:fa26415b4a118ea790de9d38f244312f2510a9bb5c65e560184d241a6f391a2d"}, + {file = "pybcj-1.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fabb2be57e4ca28ea36c13146cdf97d73abd27c51741923fc6ba1e8cd33e255c"}, + {file = "pybcj-1.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:75d6d613bae6f27678d5e44e89d61018779726aa6aa950c516d33a04b8af8c59"}, + {file = "pybcj-1.0.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:3ffae79ef8a1ea81ea2748ad7b7ad9b882aa88ddf65ce90f9e944df639eccc61"}, + {file = "pybcj-1.0.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:bdb4d8ff5cba3e0bd1adee7d20dbb2b4d80cb31ac04d6ea1cd06cfc02d2ecd0d"}, + {file = "pybcj-1.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:a29be917fbc99eca204b08407e0971e0205bfdad4b74ec915930675f352b669d"}, + {file = "pybcj-1.0.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:a2562ebe5a0abec4da0229f8abb5e90ee97b178f19762eb925c1159be36828b3"}, + {file = "pybcj-1.0.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:af19bc61ded933001cd68f004ae2042bf1a78eb498a3c685ebd655fa1be90dbe"}, + {file = "pybcj-1.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f3f4a447800850aba7724a2274ea0a4800724520c1caf38f7d0dabf2f89a5e15"}, + {file = "pybcj-1.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ce1c8af7a4761d2b1b531864d84113948daa0c4245775c63bd9874cb955f4662"}, + {file = "pybcj-1.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8007371f6f2b462f5aa05d5c2135d0a1bcf5b7bdd9bd15d86c730f588d10b7d3"}, + {file = "pybcj-1.0.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:1079ca63ff8da5c936b76863690e0bd2489e8d4e0a3a340e032095dae805dd91"}, + {file = "pybcj-1.0.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e9a785eb26884429d9b9f6326e68c3638828c83bf6d42d2463c97ad5385caff2"}, + {file = "pybcj-1.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:9ea46e2d45469d13b7f25b08efcdb140220bab1ac5a850db0954591715b8caaa"}, + {file = "pybcj-1.0.2-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:21b5f2460629167340403d359289a173e0729ce8e84e3ce99462009d5d5e01a4"}, + {file = "pybcj-1.0.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:2940fb85730b9869254559c491cd83cf777e56c76a8a60df60e4be4f2a4248d7"}, + {file = "pybcj-1.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f40f3243139d675f43793a4e35c410c370f7b91ccae74e70c8b2f4877869f90e"}, + {file = "pybcj-1.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9c2b3e60b65c7ac73e44335934e1e122da8d56db87840984601b3c5dc0ae4c19"}, + {file = "pybcj-1.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:746550dc7b5af4d04bb5fa4d065f18d39c925bcb5dee30db75747cd9a58bb6e8"}, + {file = "pybcj-1.0.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:8ce9b62b6aaa5b08773be8a919ecc4e865396c969f982b685eeca6e80c82abb7"}, + {file = "pybcj-1.0.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:493eab2b1f6f546730a6de0c5ceb75ce16f3767154e8ae30e2b70d41b928b7d2"}, + {file = "pybcj-1.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:ef55b96b7f2ed823e0b924de902065ec42ade856366c287dbb073fabd6b90ec1"}, + {file = "pybcj-1.0.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:2ed5b3dd9c209fe7b90990dee4ef21870dca39db1cd326553c314ee1b321c1cc"}, + {file = "pybcj-1.0.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:22a94885723f8362d4cb468e68910eef92d3e2b1293de82b8eacb4198ef6655f"}, + {file = "pybcj-1.0.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:b8f9368036c9e658d8e3b3534086d298a5349c864542b34657cbe57c260daa49"}, + {file = "pybcj-1.0.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:87108181c7a6ac4d3fc1e4551cab5db5eea7f9fdca611175243234cd94bcc59b"}, + {file = "pybcj-1.0.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:db57f26b8c0162cfddb52b869efb1741b8c5e67fc536994f743074985f714c55"}, + {file = "pybcj-1.0.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:bdf5bcac4f1da36ad43567ea6f6ef404347658dbbe417c87cdb1699f327d6337"}, + {file = "pybcj-1.0.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:5c3171bb95c9b45cbcad25589e1ae4f4ca4ea99dc1724c4e0671eb6b9055514e"}, + {file = "pybcj-1.0.2-cp38-cp38-win_amd64.whl", hash = "sha256:f9a2585e0da9cf343ea27421995b881736a1eb604a7c1d4ca74126af94c3d4a8"}, + {file = "pybcj-1.0.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:fdb7cd8271471a5979d84915c1ee57eea7e0a69c893225fc418db66883b0e2a7"}, + {file = "pybcj-1.0.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:e96ae14062bdcddc3197300e6ee4efa6fbc6749be917db934eac66d0daaecb68"}, + {file = "pybcj-1.0.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a54ebdc8423ba99d75372708a882fcfc3b14d9d52cf195295ad53e5a47dab37f"}, + {file = "pybcj-1.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3602be737c6e9553c45ae89e6b0e556f64f34dabf27d5260317d1824d31b79d3"}, + {file = "pybcj-1.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:63dd2ca52a48841f561bfec0fa3f208d375b0a8dcd3d7b236459e683ae29221d"}, + {file = "pybcj-1.0.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:8204a714029784b1a08a3d790430d80b423b68615c5b1e67aabca5bd5419b77d"}, + {file = "pybcj-1.0.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:fde2376b180ae2620c102fbc3ef06638d306feae83964aaa5051ecbdda54845a"}, + {file = "pybcj-1.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:3b8d7810fb587adbffba025330cf212d9bbed8f29559656d05cb6609673f306a"}, + {file = "pybcj-1.0.2.tar.gz", hash = "sha256:c7f5bef7f47723c53420e377bc64d2553843bee8bcac5f0ad076ab1524780018"}, +] + +[package.extras] +check = ["check-manifest", "flake8 (<5)", "flake8-black", "flake8-colors", "flake8-isort", "flake8-pyi", "flake8-typing-imports", "mypy (>=0.812)", "mypy-extensions (>=0.4.3)", "pygments", "readme-renderer"] +test = ["coverage[toml] (>=5.2)", "hypothesis", "pytest (>=6.0)", "pytest-cov"] + [[package]] name = "pycparser" version = "2.20" @@ -1350,6 +1756,47 @@ files = [ {file = "pycparser-2.20.tar.gz", hash = "sha256:2d475327684562c3a96cc71adf7dc8c4f0565175cf86b6d7a404ff4c771f15f0"}, ] +[[package]] +name = "pycryptodomex" +version = "3.20.0" +description = "Cryptographic library for Python" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +files = [ + {file = "pycryptodomex-3.20.0-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:645bd4ca6f543685d643dadf6a856cc382b654cc923460e3a10a49c1b3832aeb"}, + {file = "pycryptodomex-3.20.0-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:ff5c9a67f8a4fba4aed887216e32cbc48f2a6fb2673bb10a99e43be463e15913"}, + {file = "pycryptodomex-3.20.0-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:8ee606964553c1a0bc74057dd8782a37d1c2bc0f01b83193b6f8bb14523b877b"}, + {file = "pycryptodomex-3.20.0-cp27-cp27m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7805830e0c56d88f4d491fa5ac640dfc894c5ec570d1ece6ed1546e9df2e98d6"}, + {file = "pycryptodomex-3.20.0-cp27-cp27m-musllinux_1_1_aarch64.whl", hash = "sha256:bc3ee1b4d97081260d92ae813a83de4d2653206967c4a0a017580f8b9548ddbc"}, + {file = "pycryptodomex-3.20.0-cp27-cp27m-win32.whl", hash = "sha256:8af1a451ff9e123d0d8bd5d5e60f8e3315c3a64f3cdd6bc853e26090e195cdc8"}, + {file = "pycryptodomex-3.20.0-cp27-cp27m-win_amd64.whl", hash = "sha256:cbe71b6712429650e3883dc81286edb94c328ffcd24849accac0a4dbcc76958a"}, + {file = "pycryptodomex-3.20.0-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:76bd15bb65c14900d98835fcd10f59e5e0435077431d3a394b60b15864fddd64"}, + {file = "pycryptodomex-3.20.0-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:653b29b0819605fe0898829c8ad6400a6ccde096146730c2da54eede9b7b8baa"}, + {file = "pycryptodomex-3.20.0-cp27-cp27mu-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:62a5ec91388984909bb5398ea49ee61b68ecb579123694bffa172c3b0a107079"}, + {file = "pycryptodomex-3.20.0-cp27-cp27mu-musllinux_1_1_aarch64.whl", hash = "sha256:108e5f1c1cd70ffce0b68739c75734437c919d2eaec8e85bffc2c8b4d2794305"}, + {file = "pycryptodomex-3.20.0-cp35-abi3-macosx_10_9_universal2.whl", hash = "sha256:59af01efb011b0e8b686ba7758d59cf4a8263f9ad35911bfe3f416cee4f5c08c"}, + {file = "pycryptodomex-3.20.0-cp35-abi3-macosx_10_9_x86_64.whl", hash = "sha256:82ee7696ed8eb9a82c7037f32ba9b7c59e51dda6f105b39f043b6ef293989cb3"}, + {file = "pycryptodomex-3.20.0-cp35-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:91852d4480a4537d169c29a9d104dda44094c78f1f5b67bca76c29a91042b623"}, + {file = "pycryptodomex-3.20.0-cp35-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bca649483d5ed251d06daf25957f802e44e6bb6df2e8f218ae71968ff8f8edc4"}, + {file = "pycryptodomex-3.20.0-cp35-abi3-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6e186342cfcc3aafaad565cbd496060e5a614b441cacc3995ef0091115c1f6c5"}, + {file = "pycryptodomex-3.20.0-cp35-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:25cd61e846aaab76d5791d006497134602a9e451e954833018161befc3b5b9ed"}, + {file = "pycryptodomex-3.20.0-cp35-abi3-musllinux_1_1_i686.whl", hash = "sha256:9c682436c359b5ada67e882fec34689726a09c461efd75b6ea77b2403d5665b7"}, + {file = "pycryptodomex-3.20.0-cp35-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:7a7a8f33a1f1fb762ede6cc9cbab8f2a9ba13b196bfaf7bc6f0b39d2ba315a43"}, + {file = "pycryptodomex-3.20.0-cp35-abi3-win32.whl", hash = "sha256:c39778fd0548d78917b61f03c1fa8bfda6cfcf98c767decf360945fe6f97461e"}, + {file = "pycryptodomex-3.20.0-cp35-abi3-win_amd64.whl", hash = "sha256:2a47bcc478741b71273b917232f521fd5704ab4b25d301669879e7273d3586cc"}, + {file = "pycryptodomex-3.20.0-pp27-pypy_73-manylinux2010_x86_64.whl", hash = "sha256:1be97461c439a6af4fe1cf8bf6ca5936d3db252737d2f379cc6b2e394e12a458"}, + {file = "pycryptodomex-3.20.0-pp27-pypy_73-win32.whl", hash = "sha256:19764605feea0df966445d46533729b645033f134baeb3ea26ad518c9fdf212c"}, + {file = "pycryptodomex-3.20.0-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:f2e497413560e03421484189a6b65e33fe800d3bd75590e6d78d4dfdb7accf3b"}, + {file = "pycryptodomex-3.20.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e48217c7901edd95f9f097feaa0388da215ed14ce2ece803d3f300b4e694abea"}, + {file = "pycryptodomex-3.20.0-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d00fe8596e1cc46b44bf3907354e9377aa030ec4cd04afbbf6e899fc1e2a7781"}, + {file = "pycryptodomex-3.20.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:88afd7a3af7ddddd42c2deda43d53d3dfc016c11327d0915f90ca34ebda91499"}, + {file = "pycryptodomex-3.20.0-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:d3584623e68a5064a04748fb6d76117a21a7cb5eaba20608a41c7d0c61721794"}, + {file = "pycryptodomex-3.20.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0daad007b685db36d977f9de73f61f8da2a7104e20aca3effd30752fd56f73e1"}, + {file = "pycryptodomex-3.20.0-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5dcac11031a71348faaed1f403a0debd56bf5404232284cf8c761ff918886ebc"}, + {file = "pycryptodomex-3.20.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:69138068268127cd605e03438312d8f271135a33140e2742b417d027a0539427"}, + {file = "pycryptodomex-3.20.0.tar.gz", hash = "sha256:7a710b79baddd65b806402e14766c721aee8fb83381769c27920f26476276c1e"}, +] + [[package]] name = "pyjwt" version = "2.4.0" @@ -1367,71 +1814,6 @@ dev = ["coverage[toml] (==5.0.4)", "cryptography (>=3.3.1)", "mypy", "pre-commit docs = ["sphinx", "sphinx-rtd-theme", "zope.interface"] tests = ["coverage[toml] (==5.0.4)", "pytest (>=6.0.0,<7.0.0)"] -[[package]] -name = "pylint" -version = "2.12.2" -description = "python code static checker" -optional = false -python-versions = ">=3.6.2" -files = [ - {file = "pylint-2.12.2-py3-none-any.whl", hash = "sha256:daabda3f7ed9d1c60f52d563b1b854632fd90035bcf01443e234d3dc794e3b74"}, - {file = "pylint-2.12.2.tar.gz", hash = "sha256:9d945a73640e1fec07ee34b42f5669b770c759acd536ec7b16d7e4b87a9c9ff9"}, -] - -[package.dependencies] -astroid = ">=2.9.0,<2.10" -colorama = {version = "*", markers = "sys_platform == \"win32\""} -isort = ">=4.2.5,<6" -mccabe = ">=0.6,<0.7" -platformdirs = ">=2.2.0" -toml = ">=0.9.2" -typing-extensions = {version = ">=3.10.0", markers = "python_version < \"3.10\""} - -[[package]] -name = "pylint-flask" -version = "0.6" -description = "pylint-flask is a Pylint plugin to aid Pylint in recognizing and understanding errors caused when using Flask" -optional = false -python-versions = "*" -files = [ - {file = "pylint-flask-0.6.tar.gz", hash = "sha256:f4d97de2216bf7bfce07c9c08b166e978fe9f2725de2a50a9845a97de7e31517"}, -] - -[package.dependencies] -pylint-plugin-utils = ">=0.2.1" - -[[package]] -name = "pylint-flask-sqlalchemy" -version = "0.2.0" -description = "A Pylint plugin for improving code analysis when editing code using Flask-SQLAlchemy" -optional = false -python-versions = ">=3.5" -files = [ - {file = "pylint_flask_sqlalchemy-0.2.0-py3-none-any.whl", hash = "sha256:27f1fffb940adc9ac8f00ff7eb91ec39ca070c0f3bcec0d7f1c702a993d40505"}, - {file = "pylint_flask_sqlalchemy-0.2.0.tar.gz", hash = "sha256:8ede5baba1a465d8ba39d8383ffcf0889d7a6afeff44bd24177fcf529ba8aa81"}, -] - -[package.dependencies] -Flask-SQLAlchemy = ">=2" -pylint = "*" - -[package.extras] -dev = ["black", "bump2version", "gitchangelog", "mypy", "pystache"] - -[[package]] -name = "pylint-plugin-utils" -version = "0.7" -description = "Utilities and helpers for writing Pylint plugins" -optional = false -python-versions = ">=3.6.2" -files = [ - {file = "pylint-plugin-utils-0.7.tar.gz", hash = "sha256:ce48bc0516ae9415dd5c752c940dfe601b18fe0f48aa249f2386adfa95a004dd"}, - {file = "pylint_plugin_utils-0.7-py3-none-any.whl", hash = "sha256:b3d43e85ab74c4f48bb46ae4ce771e39c3a20f8b3d56982ab17aa73b4f98d535"}, -] - -[package.dependencies] -pylint = ">=1.7" - [[package]] name = "pyopenssl" version = "20.0.1" @@ -1451,6 +1833,92 @@ six = ">=1.5.2" docs = ["sphinx", "sphinx-rtd-theme"] test = ["flaky", "pretend", "pytest (>=3.0.1)"] +[[package]] +name = "pyppmd" +version = "1.1.0" +description = "PPMd compression/decompression library" +optional = false +python-versions = ">=3.8" +files = [ + {file = "pyppmd-1.1.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:c5cd428715413fe55abf79dc9fc54924ba7e518053e1fc0cbdf80d0d99cf1442"}, + {file = "pyppmd-1.1.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0e96cc43f44b7658be2ea764e7fa99c94cb89164dbb7cdf209178effc2168319"}, + {file = "pyppmd-1.1.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:dd20142869094bceef5ab0b160f4fff790ad1f612313a1e3393a51fc3ba5d57e"}, + {file = "pyppmd-1.1.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a4f9b51e45c11e805e74ea6f6355e98a6423b5bbd92f45aceee24761bdc3d3b8"}, + {file = "pyppmd-1.1.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:459f85e928fb968d0e34fb6191fd8c4e710012d7d884fa2b317b2e11faac7c59"}, + {file = "pyppmd-1.1.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f73cf2aaf60477eef17f5497d14b6099d8be9748390ad2b83d1c88214d050c05"}, + {file = "pyppmd-1.1.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:2ea3ae0e92c0b5345cd3a4e145e01bbd79c2d95355481ea5d833b5c0cb202a2d"}, + {file = "pyppmd-1.1.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:775172c740133c0162a01c1a5443d0e312246881cdd6834421b644d89a634b91"}, + {file = "pyppmd-1.1.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:14421030f1d46f69829698bdd960698a3b3df0925e3c470e82cfcdd4446b7bc1"}, + {file = "pyppmd-1.1.0-cp310-cp310-win32.whl", hash = "sha256:b691264f9962532aca3bba5be848b6370e596d0a2ca722c86df388be08d0568a"}, + {file = "pyppmd-1.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:216b0d969a3f06e35fbfef979706d987d105fcb1e37b0b1324f01ee143719c4a"}, + {file = "pyppmd-1.1.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:1f8c51044ee4df1b004b10bf6b3c92f95ea86cfe1111210d303dca44a56e4282"}, + {file = "pyppmd-1.1.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ac25b3a13d1ac9b8f0bde46952e10848adc79d932f2b548a6491ef8825ae0045"}, + {file = "pyppmd-1.1.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:c8d3003eebe6aabe22ba744a38a146ed58a25633420d5da882b049342b7c8036"}, + {file = "pyppmd-1.1.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7c520656bc12100aa6388df27dd7ac738577f38bf43f4a4bea78e1861e579ea5"}, + {file = "pyppmd-1.1.0-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8c2a3e807028159a705951f5cb5d005f94caed11d0984e59cc50506de543e22d"}, + {file = "pyppmd-1.1.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ec8a2447e69444703e2b273247bfcd4b540ec601780eff07da16344c62d2993d"}, + {file = "pyppmd-1.1.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:b9e0c8053e69cad6a92a0889b3324f567afc75475b4f54727de553ac4fc85780"}, + {file = "pyppmd-1.1.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:5938d256e8d2a2853dc3af8bb58ae6b4a775c46fc891dbe1826a0b3ceb624031"}, + {file = "pyppmd-1.1.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:1ce5822d8bea920856232ccfb3c26b56b28b6846ea1b0eb3d5cb9592a026649e"}, + {file = "pyppmd-1.1.0-cp311-cp311-win32.whl", hash = "sha256:2a9e894750f2a52b03e3bc0d7cf004d96c3475a59b1af7e797d808d7d29c9ffe"}, + {file = "pyppmd-1.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:969555c72e72fe2b4dd944127521a8f2211caddb5df452bbc2506b5adfac539e"}, + {file = "pyppmd-1.1.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:9d6ef8fd818884e914bc209f7961c9400a4da50d178bba25efcef89f09ec9169"}, + {file = "pyppmd-1.1.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:95f28e2ecf3a9656bd7e766aaa1162b6872b575627f18715f8b046e8617c124a"}, + {file = "pyppmd-1.1.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:37f3557ea65ee417abcdf5f49d35df00bb9f6f252639cae57aeefcd0dd596133"}, + {file = "pyppmd-1.1.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6e84b25d088d7727d50218f57f92127cdb839acd6ec3de670b6680a4cf0b2d2a"}, + {file = "pyppmd-1.1.0-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:99ed42891986dac8c2ecf52bddfb777900233d867aa18849dbba6f3335600466"}, + {file = "pyppmd-1.1.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c6fe69b82634488ada75ba07efb90cd5866fa3d64a2c12932b6e8ae207a14e5f"}, + {file = "pyppmd-1.1.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:60981ffde1fe6ade750b690b35318c41a1160a8505597fda2c39a74409671217"}, + {file = "pyppmd-1.1.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:46e8240315476f57aac23d71e6de003e122b65feba7c68f4cc46a089a82a7cd4"}, + {file = "pyppmd-1.1.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:c0308e2e76ecb4c878a18c2d7a7c61dbca89b4ef138f65d5f5ead139154dcdea"}, + {file = "pyppmd-1.1.0-cp312-cp312-win32.whl", hash = "sha256:b4fa4c27dc1314d019d921f2aa19e17f99250557e7569eeb70e180558f46af74"}, + {file = "pyppmd-1.1.0-cp312-cp312-win_amd64.whl", hash = "sha256:c269d21e15f4175df27cf00296476097af76941f948734c642d7fb6e85b9b3b9"}, + {file = "pyppmd-1.1.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:a04ef5fd59818b035855723af85ce008c8191d31216706ffcbeedc505efca269"}, + {file = "pyppmd-1.1.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1e3ebcf5f95142268afa5cc46457d9dab2d29a3ccfd020a1129dd9d6bd021be1"}, + {file = "pyppmd-1.1.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:4ad046a9525d1f52e93bc642a4cec0bf344a3ba1a15923e424e7a50f8ca003d8"}, + {file = "pyppmd-1.1.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:169e5023c86ed1f7587961900f58aa78ad8a3d59de1e488a2228b5ba3de52402"}, + {file = "pyppmd-1.1.0-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:baf798e76edd9da975cc536f943756a1b1755eb8ed87371f86f76d7c16e8d034"}, + {file = "pyppmd-1.1.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d63be8c068879194c1e7548d0c57f54a4d305ba204cd0c7499b678f0aee893ef"}, + {file = "pyppmd-1.1.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:d5fc178a3c21af78858acbac9782fca6a927267694c452e0882c55fec6e78319"}, + {file = "pyppmd-1.1.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:28a1ab1ef0a31adce9b4c837b7b9acb01ce8f1f702ff3ff884f03d21c2f6b9bb"}, + {file = "pyppmd-1.1.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:5fef43bfe98ada0a608adf03b2d205e071259027ab50523954c42eef7adcef67"}, + {file = "pyppmd-1.1.0-cp38-cp38-win32.whl", hash = "sha256:6b980902797eab821299a1c9f42fa78eff2826a6b0b0f6bde8a621f9765ffd55"}, + {file = "pyppmd-1.1.0-cp38-cp38-win_amd64.whl", hash = "sha256:80cde69013f357483abe0c3ff30c55dc5e6b4f72b068f91792ce282c51dc0bff"}, + {file = "pyppmd-1.1.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:2aeea1bf585c6b8771fa43a6abd704da92f8a46a6d0020953af15d7f3c82e48c"}, + {file = "pyppmd-1.1.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:7759bdb137694d4ab0cfa5ff2c75c212d90714c7da93544694f68001a0c38e12"}, + {file = "pyppmd-1.1.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:db64a4fe956a2e700a737a1d019f526e6ccece217c163b28b354a43464cc495b"}, + {file = "pyppmd-1.1.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3f788ae8f5a9e79cd777b7969d3401b2a2b87f47abe306c2a03baca30595e9bd"}, + {file = "pyppmd-1.1.0-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:324a178935c140210fca2043c688b77e79281da8172d2379a06e094f41735851"}, + {file = "pyppmd-1.1.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:363030bbcb7902fb9eeb59ffc262581ca5dd7790ba950328242fd2491c54d99b"}, + {file = "pyppmd-1.1.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:31b882584f86440b0ff7906385c9f9d9853e5799197abaafdae2245f87d03f01"}, + {file = "pyppmd-1.1.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:b991b4501492ec3380b605fe30bee0b61480d305e98519d81c2a658b2de01593"}, + {file = "pyppmd-1.1.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:b6108044d943b826f97a9e79201242f61392d6c1fadba463b2069c4e6bc961e1"}, + {file = "pyppmd-1.1.0-cp39-cp39-win32.whl", hash = "sha256:c45ce2968b7762d2cacf622b0a8f260295c6444e0883fd21a21017e3eaef16ed"}, + {file = "pyppmd-1.1.0-cp39-cp39-win_amd64.whl", hash = "sha256:f5289f32ab4ec5f96a95da51309abd1769f928b0bff62047b3bc25c878c16ccb"}, + {file = "pyppmd-1.1.0-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:ad5da9f7592158e6b6b51d7cd15e536d8b23afbb4d22cba4e5744c7e0a3548b1"}, + {file = "pyppmd-1.1.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bc6543e7d12ef0a1466d291d655e3d6bca59c7336dbb53b62ccdd407822fb52b"}, + {file = "pyppmd-1.1.0-pp310-pypy310_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a5e4008a45910e3c8c227f6f240de67eb14454c015dc3d8060fc41e230f395d3"}, + {file = "pyppmd-1.1.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9301fa39d1fb0ed09a10b4c5d7f0074113e96a1ead16ba7310bedf95f7ef660c"}, + {file = "pyppmd-1.1.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:59521a3c6028da0cb5780ba16880047b00163432a6b975da2f6123adfc1b0be8"}, + {file = "pyppmd-1.1.0-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:d7ec02f1778dd68547e497625d66d7858ce10ea199146eb1d80ee23ba42954be"}, + {file = "pyppmd-1.1.0-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f062ca743f9b99fe88d417b4d351af9b4ff1a7cbd3d765c058bb97de976d57f1"}, + {file = "pyppmd-1.1.0-pp38-pypy38_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:088e326b180a0469ac936849f5e1e5320118c22c9d9e673e9c8551153b839c84"}, + {file = "pyppmd-1.1.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:897fa9ab5ff588a1000b8682835c5acf219329aa2bbfec478100e57d1204eeab"}, + {file = "pyppmd-1.1.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:3af4338cc48cd59ee213af61d936419774a0f8600b9aa2013cd1917b108424f0"}, + {file = "pyppmd-1.1.0-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:cce8cd2d4ceebe2dbf41db6dfebe4c2e621314b3af8a2df2cba5eb5fa277f122"}, + {file = "pyppmd-1.1.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:62e57927dbcb91fb6290a41cd83743b91b9d85858efb16a0dd34fac208ee1c6b"}, + {file = "pyppmd-1.1.0-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:435317949a6f35e54cdf08e0af6916ace427351e7664ac1593980114668f0aaa"}, + {file = "pyppmd-1.1.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4f66b0d0e32b8fb8707f1d2552f13edfc2917e8ed0bdf4d62e2ce190d2c70834"}, + {file = "pyppmd-1.1.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:650a663a591e06fb8096c213f4070b158981c8c3bf9c166ce7e4c360873f2750"}, + {file = "pyppmd-1.1.0.tar.gz", hash = "sha256:1d38ce2e4b7eb84b53bc8a52380b94f66ba6c39328b8800b30c2b5bf31693973"}, +] + +[package.extras] +check = ["check-manifest", "flake8 (<5)", "flake8-black", "flake8-isort", "isort (>=5.0.3)", "mypy (>=0.812)", "mypy-extensions (>=0.4.3)", "pygments", "readme-renderer"] +docs = ["sphinx (>=2.3)", "sphinx-rtd-theme"] +fuzzer = ["atheris", "hypothesis"] +test = ["coverage[toml] (>=5.2)", "hypothesis", "pytest (>=6.0)", "pytest-benchmark", "pytest-cov", "pytest-timeout"] + [[package]] name = "pyrsistent" version = "0.18.0" @@ -1521,6 +1989,161 @@ files = [ {file = "python_editor-1.0.4-py3-none-any.whl", hash = "sha256:1bf6e860a8ad52a14c3ee1252d5dc25b2030618ed80c022598f00176adc8367d"}, ] +[[package]] +name = "python-magic" +version = "0.4.27" +description = "File type identification using libmagic" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +files = [ + {file = "python-magic-0.4.27.tar.gz", hash = "sha256:c1ba14b08e4a5f5c31a302b7721239695b2f0f058d125bd5ce1ee36b9d9d3c3b"}, + {file = "python_magic-0.4.27-py2.py3-none-any.whl", hash = "sha256:c212960ad306f700aa0d01e5d7a325d20548ff97eb9920dcd29513174f0294d3"}, +] + +[[package]] +name = "pyzstd" +version = "0.15.10" +description = "Python bindings to Zstandard (zstd) compression library." +optional = false +python-versions = ">=3.5" +files = [ + {file = "pyzstd-0.15.10-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:4ff57d2a67aaff47eb60c37c5476af2a5056319aa2a5cab4b276f78b764be785"}, + {file = "pyzstd-0.15.10-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8195b3fe2ed91db03f969c3c5cf6a9bcb3a961749caec94479e9e7a96d7af14f"}, + {file = "pyzstd-0.15.10-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4ea6a794b8a4e0590bea1599e724d4877d34640058caf5c0b3f916ded06fc3a1"}, + {file = "pyzstd-0.15.10-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:deb41298fb0c916875413373e5eba162e39309d8730be736b3a206d9b73afebf"}, + {file = "pyzstd-0.15.10-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e0f1f590a66769caea6cf47c3c5d06d004f01659449595d4bc737a42d4670bf0"}, + {file = "pyzstd-0.15.10-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4dfd0d97ac231c08551543d61d123cf44bdd2fc20ba5ebce1fb0c466036be15a"}, + {file = "pyzstd-0.15.10-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c20a4ee0706db5c9f403e4c459fc81145f48cb20fccc1a64acfb6143f1a7b1fb"}, + {file = "pyzstd-0.15.10-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:e7c4530ec6bf3a27c3cba229026fa3669e6e1832fdc37cf74c73b113f884cb2d"}, + {file = "pyzstd-0.15.10-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:cccfb03f829ecde3ee126befb4fe827e2228a50e8d9eaa0275c4dd21a0e59765"}, + {file = "pyzstd-0.15.10-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:1e045dc688bb618cf2a2e33cb487c0d8af5e31a4eaec18c9399b34e2aed58777"}, + {file = "pyzstd-0.15.10-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:a22c4b26fb6134ece45e875515961bc9c1777df775f3488800bea55a381df91e"}, + {file = "pyzstd-0.15.10-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:0779ccd652113d75cd461fa6581149550b0da55e72b1a6e28e6f49e9978c2d41"}, + {file = "pyzstd-0.15.10-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:150a7c7004b9df00f7cbb6dad0bdbab5d77c8c54b0857b8b3e50beae2810a041"}, + {file = "pyzstd-0.15.10-cp310-cp310-win32.whl", hash = "sha256:50186fa41c72929d21727dcc6cb87bef0adf09df9e982325a0ae5bfd20a9456b"}, + {file = "pyzstd-0.15.10-cp310-cp310-win_amd64.whl", hash = "sha256:8e3dff90b6abc56331a886b5067c3b6bc3fad1b6df5766247197b699afd013b7"}, + {file = "pyzstd-0.15.10-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:51c644157319e2ca87521bd9694df7f651aac3273e015f35cdfb47cb8597ce37"}, + {file = "pyzstd-0.15.10-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:85582502d3df1db8077475d88d0bf5f35b8ddb8abf9badd8625781024da5f346"}, + {file = "pyzstd-0.15.10-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:adb895a0081a932132aa3a233cfeba682a07ac0dc36b062152f240406eecfba1"}, + {file = "pyzstd-0.15.10-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f0822c9f4852f9f6b1458f8fbf011bb887cefba792b0c7c10659e2c9c997d1c9"}, + {file = "pyzstd-0.15.10-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2e6fd189c85f2efe94d3945dfbb85cdbc4e213757be75aa9a45e186625498ddf"}, + {file = "pyzstd-0.15.10-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6d6f7fcfef9166670df4b6710d1105b891efba68ec523f56c64cc8c7aa6c8e88"}, + {file = "pyzstd-0.15.10-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:527bfd3e01b8dafa1c24cba1a0455a85bbcdb41a3eefe59e2849634f9206d4f0"}, + {file = "pyzstd-0.15.10-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:330d54a0e5886fa5ca21e3960b9352a7b21f8dd85f98d4b7c4e8a7d48ade6998"}, + {file = "pyzstd-0.15.10-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:a900a3dcda64b289cf35acfb6c90246b5ae9f2dd4bc05da8dcb8fbd04c91e37b"}, + {file = "pyzstd-0.15.10-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:e21208605759dc2eeebf607a002e1ddc09548c12f25886d2a2dd8efdf35535a3"}, + {file = "pyzstd-0.15.10-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:015a6794196fcb75ddaaae8186f0dbdcbda4e84451361a808b3e96c8c8a63296"}, + {file = "pyzstd-0.15.10-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:b856928e99a1d3080929b0f194c7922c7a7979b0eb21ad9d057f000dcf1a6ac7"}, + {file = "pyzstd-0.15.10-cp311-cp311-win32.whl", hash = "sha256:39a912430c73aa585ede2dc7c9f09c5334862953f26a9a86ac048c3805ed6bb1"}, + {file = "pyzstd-0.15.10-cp311-cp311-win_amd64.whl", hash = "sha256:4cd0bd21e0c7721e9f4ea54d533d9196771ab1d6ae0a83a96564dc46147a26eb"}, + {file = "pyzstd-0.15.10-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:13515a6abca6751482396b656e5b72279bd405fd6c71b5bc899fcb526d40e564"}, + {file = "pyzstd-0.15.10-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:62a1614558478f7d1014eec94a9ae3bf21c95766ecbe0a4a1ab16d2f1e4a6b67"}, + {file = "pyzstd-0.15.10-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d62a54dd438b51dd9f94bd88dd2f7c9d4093aadc44892143182d51f8488ab5f6"}, + {file = "pyzstd-0.15.10-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9fa20eb8f710a9d36801451d1cbcfc83d1dd9e400527ad9aba7e7cc635c2729b"}, + {file = "pyzstd-0.15.10-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3443df2dcdfe6e57c2600617e8f377772703b7f907fe065b49948c05ace80fd7"}, + {file = "pyzstd-0.15.10-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:db3d4e991ee727f6c0a54fe975ebe169be3a463ce810cfd8e6edbe8a90ddeb8f"}, + {file = "pyzstd-0.15.10-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:53172f0781b3db9321a1286bb274121668c3fe560d3bddfa82f585475f7145fa"}, + {file = "pyzstd-0.15.10-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:6217f30c4341619c6066a044ca118f53a3121b5813a56257b1f9818e24450584"}, + {file = "pyzstd-0.15.10-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:cfa03e12c0c1bd357a0e1f20adae9c32bc166dcc6ed3be65885134830899b6ba"}, + {file = "pyzstd-0.15.10-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:455d2258f247968d18a9eaeb11e214e048acc976a61f72a0282d4c40051458b8"}, + {file = "pyzstd-0.15.10-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:e0262bba03bb4d38b697c2039a8e48a9e889fb9ae9b727903e8d9c49d32883a4"}, + {file = "pyzstd-0.15.10-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:c7f7a398bcb0f4cfbaf0ddb3e831c43857701c63c66f48eb30011326ed03b0fa"}, + {file = "pyzstd-0.15.10-cp312-cp312-win32.whl", hash = "sha256:ce8e8a4aa8246c615693b9d0504e1df98157ae48907a044baa80f80abecc44ad"}, + {file = "pyzstd-0.15.10-cp312-cp312-win_amd64.whl", hash = "sha256:0561710b88d4895a7bb202335e802125da6a71c556b1292fd620224b2652f496"}, + {file = "pyzstd-0.15.10-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:62b8c3801d739a9592c0503dd294fab7f8cd2b1d637429babe13671bedf7d6f7"}, + {file = "pyzstd-0.15.10-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d2cc02e94ff4df6a4a871bbd69149ba5fbc5150108a208c6cdd9bc728000995b"}, + {file = "pyzstd-0.15.10-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3f174c47c370641c5dba74d4fd99374ca0eadd47e43e7f76ee8b76dacdfa2406"}, + {file = "pyzstd-0.15.10-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b1752344c77dbb137244e6ab5af5a7576b8e8b8e5d440c58d935e69f83606e0d"}, + {file = "pyzstd-0.15.10-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:94973e29acf813a572adf3ed2342a0998a41331781d7be82a0a1b02646181e34"}, + {file = "pyzstd-0.15.10-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e71bb03c754934d7792aa0559b16f9effe1d4196f5834715c115363809f00c37"}, + {file = "pyzstd-0.15.10-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:b19cdecdc19ad863673709d27ddb0adc104b9ad341f2785ab23c51c9ab39cf3f"}, + {file = "pyzstd-0.15.10-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:6aed97ef51e20ea4fd7e12c4b9e3199cd8e4664054f5d84c3d83e6f4d3144055"}, + {file = "pyzstd-0.15.10-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:4094ea7b80081bb024eb887c80eeb6bd8ae24dc2862cc61ae9eadb5bca11dcd6"}, + {file = "pyzstd-0.15.10-cp36-cp36m-musllinux_1_1_ppc64le.whl", hash = "sha256:65e99e57f5fb42ed391fc2f7ffa4b8cce5a32dfd74f52e03bd36bb2ac3b56536"}, + {file = "pyzstd-0.15.10-cp36-cp36m-musllinux_1_1_s390x.whl", hash = "sha256:957751dd7bba26e651c689fc5f41bb269712efcbf19a97ad4f912f0f792e6e95"}, + {file = "pyzstd-0.15.10-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:ba0f1c0201845b769c92b2b3e7666010abe14d6e9dbf4214d04cdf23cbdcd1ae"}, + {file = "pyzstd-0.15.10-cp36-cp36m-win32.whl", hash = "sha256:ad30429f499c30e8e19ed389b8e25116d43c63cafdb97d4f5617e94e671209c5"}, + {file = "pyzstd-0.15.10-cp36-cp36m-win_amd64.whl", hash = "sha256:49c99120f9ea0c512019948e55ba17e60dadb1d3578890d53b2a09858da4e1dd"}, + {file = "pyzstd-0.15.10-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:eb4d96fe5d6d8bf5c8c64d8a37edff55e6d9abbf84d9b8fd0fe8e0db1a557625"}, + {file = "pyzstd-0.15.10-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:80ca483ee2084d36dc570004b6793f99c58d2df201c630f60518bca3518faa5d"}, + {file = "pyzstd-0.15.10-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7bb791f16c810c98865c373202a44b7b313d01a2a7a6186c9dcc0ac1a0d156dc"}, + {file = "pyzstd-0.15.10-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:94d970caaaf3f59d6c7aa0aaf38e755641351f99452c400fc06b7e365ab1620c"}, + {file = "pyzstd-0.15.10-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a15a3ef14cb929b07e0a98639f2ebcd69a0038d6e31367157018ec841a54d8fa"}, + {file = "pyzstd-0.15.10-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e69d3d5257607a3b29f12192ad7bc9fdbdc8aa5f7e11c6f536cb61ee02dcd698"}, + {file = "pyzstd-0.15.10-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:ca80bb0b8400888e16e8eaa01b506de7d1bbdc8cc78c9ff75272526fd36fcb8a"}, + {file = "pyzstd-0.15.10-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:99902df14861e4f40ed1eb403a17356188428d12bb10d53de10d1ea24996b838"}, + {file = "pyzstd-0.15.10-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:be591f405d82f40acbe2a081f1dee5478a3cf1b694013cc5712e84159311e36a"}, + {file = "pyzstd-0.15.10-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:c867d446b22a7288229a812da6f211d86934beb47edf8098e2e0dbe9e2529f86"}, + {file = "pyzstd-0.15.10-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:c6f67ac9d3ff65ca466821d573b3cb2fb01f0cd9eb082e92f49dfd88fa828a77"}, + {file = "pyzstd-0.15.10-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:5ae5f8ab4accc980fa8e6696a402176e20a717ab2b296cd8d62b6a86cafc5f9c"}, + {file = "pyzstd-0.15.10-cp37-cp37m-win32.whl", hash = "sha256:013b206c22b85512d59dd05f6684c02bf9db45e93f637facb5ce165c2447fbc4"}, + {file = "pyzstd-0.15.10-cp37-cp37m-win_amd64.whl", hash = "sha256:357e6545203754e83a0431663aa86cae873abe160923bdf3db07e88f03100b05"}, + {file = "pyzstd-0.15.10-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:9593a76f516312ec59dbeb73a9f1915d1f67610c054a7b488912b972cbfbcb7e"}, + {file = "pyzstd-0.15.10-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:d55d9e1e22ebfa9cde606a7967eb21fbc65d0d3be600e550c38a1c05094c8015"}, + {file = "pyzstd-0.15.10-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8f356263a898b2c9961a2661ebb975f2fd20868d2c4fc4a165226fa7d36e1c76"}, + {file = "pyzstd-0.15.10-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5494515f3d0df1eb54c9f4ce7b9ea0b285bc1ba87eba295604da5f8de711bdea"}, + {file = "pyzstd-0.15.10-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9dca0cde0f02e08e11431fff0e5408ac46420912165d828bc148a3c8cedc8852"}, + {file = "pyzstd-0.15.10-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:91e8a0852784c758b8de4179c61e80abae997155aa2b324cbee28dcaf9084b6f"}, + {file = "pyzstd-0.15.10-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d62f357845f90d5327bdd3286ebd79c40b23b8e7c36772fc2949ef54a92bc6de"}, + {file = "pyzstd-0.15.10-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:7b2ac847e8d2ca55be038d29d20d6bfe86c03e66ac2d9741701e4f9eef2abda9"}, + {file = "pyzstd-0.15.10-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:c2d2a7324fbd118dc951b63b1fc553aec0fc0c430474a6ab7b33608b9606658a"}, + {file = "pyzstd-0.15.10-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:609cc4bed06942e51ebdfa9cc74629e1d19de2339161b65d555d01b9820aec46"}, + {file = "pyzstd-0.15.10-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:b62c408ddac3ae113b9dc4867fd2bb32a2ef669c68f256eb5486c02b31603afa"}, + {file = "pyzstd-0.15.10-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:18167c8a16709631eaa2f4fd27e2a7570b4c37ec460b65ff098e948af2d37f33"}, + {file = "pyzstd-0.15.10-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:801ab496766a858cc54b37a66f9d0169d590628e69bde2166f76c35dfc20f64f"}, + {file = "pyzstd-0.15.10-cp38-cp38-win32.whl", hash = "sha256:846050f1d7520350d26076df12b8a78b540780d7d3478845be79d57e2e6d3612"}, + {file = "pyzstd-0.15.10-cp38-cp38-win_amd64.whl", hash = "sha256:d077f76179de41cdd5ae39b0a6f16f033b077f27fa54a9e038d03e3f5ddeff23"}, + {file = "pyzstd-0.15.10-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:e2dbb36017e5c7d7499dfc05f8d6ed781fce9fbfa45cc7bd888ec5f871aba3d3"}, + {file = "pyzstd-0.15.10-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:41e0da402bf0d68067be2f16f65b9d1d7d7e6d726f27762226cba7a8badd618a"}, + {file = "pyzstd-0.15.10-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a62e98375385ade756d1ea4975f79ec103c515b412884d146c98295c5300fb4a"}, + {file = "pyzstd-0.15.10-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8575d340ffcd89e4558448eec23c252da584f0de4528a73ed45a01f12d6700fd"}, + {file = "pyzstd-0.15.10-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6bfb81f36fd56664dbbd64a0af241797424c76861faa2682aca89de110fce5d4"}, + {file = "pyzstd-0.15.10-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:965e04aeb83f594577ea4e8c975765d0953a75c8d6e3cd193ae25ef574bd83ee"}, + {file = "pyzstd-0.15.10-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:793077870191d54889cc472eda3bfd84c8cae5ed61c9fa9fb2ce29c31e23f812"}, + {file = "pyzstd-0.15.10-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:468f12eb61cbef394ff412c86d8bc85b90f24dff19f675c864df88a1a398a3a3"}, + {file = "pyzstd-0.15.10-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:92abe38cdd7ea3f98a0f1a4521e9e7e70aa001713bff62a5b97fae41b0a39d0d"}, + {file = "pyzstd-0.15.10-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:6fa6495ec52ff29b097e6d1b619588ab61e998b198882ec622d947856d4a85b4"}, + {file = "pyzstd-0.15.10-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:1c3d0e784ea9b66b06c7b76895aa4c1a90975980b1ae136fa8bbd8fb2b93e9b3"}, + {file = "pyzstd-0.15.10-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:bafef40c8b521ef9df81a118e278d5759c0127395883dcc10bf80ee32a46da39"}, + {file = "pyzstd-0.15.10-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:81154db47a9aa901d09a8cebcd1f6559dbbd02a93a16bc203dc3f94c06bea25a"}, + {file = "pyzstd-0.15.10-cp39-cp39-win32.whl", hash = "sha256:6ed32af20eeeb7f8307b091fdd0ee8f5f8733dde7e8f560a3115c98a6ac33a61"}, + {file = "pyzstd-0.15.10-cp39-cp39-win_amd64.whl", hash = "sha256:8e4123de14a8dd7bccb1faed374c1f6c87111766279bbba5d6c4c52e39c383d9"}, + {file = "pyzstd-0.15.10-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:0691e54fb29a4d1f4f2a0064afaf5d1525824bf139d83f403e5ba5ee630ac4f5"}, + {file = "pyzstd-0.15.10-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:656107ef6ff0966df2a58828f165a17b0b40977358512ade259c52c18bff0a13"}, + {file = "pyzstd-0.15.10-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ea1fe83079c67c3f1549a735f11060350c87453bd86a8442bccb1f9b14c26aef"}, + {file = "pyzstd-0.15.10-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:502ec85cb2c0a35350a196e25d5e1350d400102706eba05d7926eadb64ffa976"}, + {file = "pyzstd-0.15.10-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:a07742d42409c3ce98c58f2b155e2d8acdcd8ff49955062f5155dae94b24060a"}, + {file = "pyzstd-0.15.10-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:6023de5cc800c073cbf6a10a7aad0cbae0c1849c759bb5263a78d9ac774b167b"}, + {file = "pyzstd-0.15.10-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:63a90494aeea75d3298941b0b8ddd505cbb54d6b915e579368db21d93454e41d"}, + {file = "pyzstd-0.15.10-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:91da52897e5219dc440d3b9d290fdee66fb70c65ae594555c8d2c887df77f2de"}, + {file = "pyzstd-0.15.10-pp37-pypy37_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dc917e488a9bdc681cb4a9b0ed3d0c8b81816bc1a6b1f85ec4050c827ffa9e76"}, + {file = "pyzstd-0.15.10-pp37-pypy37_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:3b9105a4977247ea8664b113345e66bf4b3ffd321a07797efc6b020ff363b39e"}, + {file = "pyzstd-0.15.10-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:50079bcfd087c8a8822c9fe940c887244cf2276ca0a4f0b55bec006b564b9541"}, + {file = "pyzstd-0.15.10-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:3aa0ad903da666cf88d8a993e5fe9b1bfa0e5792a53212335af0a89baa268911"}, + {file = "pyzstd-0.15.10-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5942e8b7ad869ea5f44d928053d3eda16e877b5fed5326786388f6a377545ab3"}, + {file = "pyzstd-0.15.10-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e9d44c5cfe2516a652131ddd91c3a48924e34f4a7b85640cda44694afbeee6cb"}, + {file = "pyzstd-0.15.10-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ca3df18c269f9c11b40dde85336d3fc4a879867b05c74efdd4d5f8e64ac7e179"}, + {file = "pyzstd-0.15.10-pp38-pypy38_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:4a5b54ebec1e606821192c86a3b85c05c3f789d33bf44f383fd245f148f8f93b"}, + {file = "pyzstd-0.15.10-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:6e742a691f4fa73cadbe7f866b33e33161ede5bc777eee443a62504adcadd65f"}, + {file = "pyzstd-0.15.10-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:88e8cbd8fdd2af2f94615c32ab113c5cff4dbd188454394c4cac9941d2f72204"}, + {file = "pyzstd-0.15.10-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c309d50ee6a41053ad4c284295e5c5eedfd084ff94a5ee1148cf0dc64e3223fb"}, + {file = "pyzstd-0.15.10-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dec319cdbba5ed3dfb2a8798364a8899751e732127c6ae74bc41276899e0311a"}, + {file = "pyzstd-0.15.10-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:24d061047634971801649ff9aced68bb8403c6220b07c82aa2c0e90d8a61acd0"}, + {file = "pyzstd-0.15.10-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:330062103d25e0d67681fcf5ef8692c71cd979dc17ed98f6cee3b3ba8bd86622"}, + {file = "pyzstd-0.15.10.tar.gz", hash = "sha256:83603a97fdbcf2139f475c940789f09e32703f931f29f4a8ddf3551e6700108b"}, +] + +[[package]] +name = "rarfile" +version = "4.2" +description = "RAR archive reader for Python" +optional = false +python-versions = ">=3.6" +files = [ + {file = "rarfile-4.2-py3-none-any.whl", hash = "sha256:8757e1e3757e32962e229cab2432efc1f15f210823cc96ccba0f6a39d17370c9"}, + {file = "rarfile-4.2.tar.gz", hash = "sha256:8e1c8e72d0845ad2b32a47ab11a719bc2e41165ec101fd4d3fe9e92aa3f469ef"}, +] + [[package]] name = "requests" version = "2.31.0" @@ -1544,19 +2167,19 @@ use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] [[package]] name = "setuptools" -version = "69.0.2" +version = "69.5.1" description = "Easily download, build, install, upgrade, and uninstall Python packages" optional = false python-versions = ">=3.8" files = [ - {file = "setuptools-69.0.2-py3-none-any.whl", hash = "sha256:1e8fdff6797d3865f37397be788a4e3cba233608e9b509382a2777d25ebde7f2"}, - {file = "setuptools-69.0.2.tar.gz", hash = "sha256:735896e78a4742605974de002ac60562d286fa8051a7e2299445e8e8fbb01aa6"}, + {file = "setuptools-69.5.1-py3-none-any.whl", hash = "sha256:c636ac361bc47580504644275c9ad802c50415c7522212252c033bd15f301f32"}, + {file = "setuptools-69.5.1.tar.gz", hash = "sha256:6c1fccdac05a97e598fb0ae3bbed5904ccb317337a51139dcd51453611bbb987"}, ] [package.extras] -docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "rst.linker (>=1.9)", "sphinx (<7.2.5)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier"] -testing = ["build[virtualenv]", "filelock (>=3.4.0)", "flake8-2020", "ini2toml[lite] (>=0.9)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pip (>=19.1)", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy (>=0.9.1)", "pytest-perf", "pytest-ruff", "pytest-timeout", "pytest-xdist", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] -testing-integration = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "packaging (>=23.1)", "pytest", "pytest-enabler", "pytest-xdist", "tomli", "virtualenv (>=13.0.0)", "wheel"] +docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier"] +testing = ["build[virtualenv]", "filelock (>=3.4.0)", "importlib-metadata", "ini2toml[lite] (>=0.9)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "mypy (==1.9)", "packaging (>=23.2)", "pip (>=19.1)", "pytest (>=6,!=8.1.1)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-home (>=0.5)", "pytest-mypy", "pytest-perf", "pytest-ruff (>=0.2.1)", "pytest-timeout", "pytest-xdist (>=3)", "tomli", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] +testing-integration = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "packaging (>=23.2)", "pytest", "pytest-enabler", "pytest-xdist", "tomli", "virtualenv (>=13.0.0)", "wheel"] [[package]] name = "six" @@ -1646,6 +2269,17 @@ files = [ six = "*" sqlalchemy = ">=0.7" +[[package]] +name = "texttable" +version = "1.7.0" +description = "module to create simple ASCII tables" +optional = false +python-versions = "*" +files = [ + {file = "texttable-1.7.0-py2.py3-none-any.whl", hash = "sha256:72227d592c82b3d7f672731ae73e4d1f88cd8e2ef5b075a7a7f01a23a3743917"}, + {file = "texttable-1.7.0.tar.gz", hash = "sha256:2d2068fb55115807d3ac77a4ca68fa48803e84ebb0ee2340f858107a36522638"}, +] + [[package]] name = "toml" version = "0.10.2" @@ -1697,13 +2331,13 @@ socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"] [[package]] name = "vt-py" -version = "0.17.5" +version = "0.18.0" description = "The official Python client library for VirusTotal" optional = false -python-versions = ">=3.6.0" +python-versions = ">=3.7.0" files = [ - {file = "vt-py-0.17.5.tar.gz", hash = "sha256:b21fd1fc70be0d21f0f7e5ba45e3fe3a2201132d6d073bb8265c88ad1dcb695a"}, - {file = "vt_py-0.17.5-py3-none-any.whl", hash = "sha256:aaa7bc825e01ee75ee5146b7e8c0f259adaf67308120770cd539834c9406063e"}, + {file = "vt-py-0.18.0.tar.gz", hash = "sha256:aa1d481e85028bd2134ee6fb8885efb73256c659e2a125d7772fe68c2b0c7f6f"}, + {file = "vt_py-0.18.0-py3-none-any.whl", hash = "sha256:a2cfaf523e906e6f0d833ffa627858ed9fdfa22ed27dc99d9bb46a2a4fe0c2f0"}, ] [package.dependencies] @@ -1729,13 +2363,13 @@ testing = ["coverage (>=5.0)", "pytest", "pytest-cover"] [[package]] name = "werkzeug" -version = "3.0.1" +version = "3.0.2" description = "The comprehensive WSGI web application library." optional = false python-versions = ">=3.8" files = [ - {file = "werkzeug-3.0.1-py3-none-any.whl", hash = "sha256:90a285dc0e42ad56b34e696398b8122ee4c681833fb35b8334a095d82c56da10"}, - {file = "werkzeug-3.0.1.tar.gz", hash = "sha256:507e811ecea72b18a404947aded4b3390e1db8f826b494d76550ef45bb3b1dcc"}, + {file = "werkzeug-3.0.2-py3-none-any.whl", hash = "sha256:3aac3f5da756f93030740bc235d3e09449efcf65f2f55e3602e1d851b8f48795"}, + {file = "werkzeug-3.0.2.tar.gz", hash = "sha256:e39b645a6ac92822588e7b39a692e7828724ceae0b0d702ef96701f90e70128d"}, ] [package.dependencies] @@ -1806,101 +2440,101 @@ files = [ [[package]] name = "yarl" -version = "1.9.3" +version = "1.9.4" description = "Yet another URL library" optional = false python-versions = ">=3.7" files = [ - {file = "yarl-1.9.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:32435d134414e01d937cd9d6cc56e8413a8d4741dea36af5840c7750f04d16ab"}, - {file = "yarl-1.9.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:9a5211de242754b5e612557bca701f39f8b1a9408dff73c6db623f22d20f470e"}, - {file = "yarl-1.9.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:525cd69eff44833b01f8ef39aa33a9cc53a99ff7f9d76a6ef6a9fb758f54d0ff"}, - {file = "yarl-1.9.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fc94441bcf9cb8c59f51f23193316afefbf3ff858460cb47b5758bf66a14d130"}, - {file = "yarl-1.9.3-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e36021db54b8a0475805acc1d6c4bca5d9f52c3825ad29ae2d398a9d530ddb88"}, - {file = "yarl-1.9.3-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e0f17d1df951336a02afc8270c03c0c6e60d1f9996fcbd43a4ce6be81de0bd9d"}, - {file = "yarl-1.9.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c5f3faeb8100a43adf3e7925d556801d14b5816a0ac9e75e22948e787feec642"}, - {file = "yarl-1.9.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:aed37db837ecb5962469fad448aaae0f0ee94ffce2062cf2eb9aed13328b5196"}, - {file = "yarl-1.9.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:721ee3fc292f0d069a04016ef2c3a25595d48c5b8ddc6029be46f6158d129c92"}, - {file = "yarl-1.9.3-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:b8bc5b87a65a4e64bc83385c05145ea901b613d0d3a434d434b55511b6ab0067"}, - {file = "yarl-1.9.3-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:dd952b9c64f3b21aedd09b8fe958e4931864dba69926d8a90c90d36ac4e28c9a"}, - {file = "yarl-1.9.3-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:c405d482c320a88ab53dcbd98d6d6f32ada074f2d965d6e9bf2d823158fa97de"}, - {file = "yarl-1.9.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:9df9a0d4c5624790a0dea2e02e3b1b3c69aed14bcb8650e19606d9df3719e87d"}, - {file = "yarl-1.9.3-cp310-cp310-win32.whl", hash = "sha256:d34c4f80956227f2686ddea5b3585e109c2733e2d4ef12eb1b8b4e84f09a2ab6"}, - {file = "yarl-1.9.3-cp310-cp310-win_amd64.whl", hash = "sha256:cf7a4e8de7f1092829caef66fd90eaf3710bc5efd322a816d5677b7664893c93"}, - {file = "yarl-1.9.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:d61a0ca95503867d4d627517bcfdc28a8468c3f1b0b06c626f30dd759d3999fd"}, - {file = "yarl-1.9.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:73cc83f918b69110813a7d95024266072d987b903a623ecae673d1e71579d566"}, - {file = "yarl-1.9.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d81657b23e0edb84b37167e98aefb04ae16cbc5352770057893bd222cdc6e45f"}, - {file = "yarl-1.9.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:26a1a8443091c7fbc17b84a0d9f38de34b8423b459fb853e6c8cdfab0eacf613"}, - {file = "yarl-1.9.3-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fe34befb8c765b8ce562f0200afda3578f8abb159c76de3ab354c80b72244c41"}, - {file = "yarl-1.9.3-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2c757f64afe53a422e45e3e399e1e3cf82b7a2f244796ce80d8ca53e16a49b9f"}, - {file = "yarl-1.9.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:72a57b41a0920b9a220125081c1e191b88a4cdec13bf9d0649e382a822705c65"}, - {file = "yarl-1.9.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:632c7aeb99df718765adf58eacb9acb9cbc555e075da849c1378ef4d18bf536a"}, - {file = "yarl-1.9.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:b0b8c06afcf2bac5a50b37f64efbde978b7f9dc88842ce9729c020dc71fae4ce"}, - {file = "yarl-1.9.3-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:1d93461e2cf76c4796355494f15ffcb50a3c198cc2d601ad8d6a96219a10c363"}, - {file = "yarl-1.9.3-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:4003f380dac50328c85e85416aca6985536812c082387255c35292cb4b41707e"}, - {file = "yarl-1.9.3-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:4d6d74a97e898c1c2df80339aa423234ad9ea2052f66366cef1e80448798c13d"}, - {file = "yarl-1.9.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:b61e64b06c3640feab73fa4ff9cb64bd8182de52e5dc13038e01cfe674ebc321"}, - {file = "yarl-1.9.3-cp311-cp311-win32.whl", hash = "sha256:29beac86f33d6c7ab1d79bd0213aa7aed2d2f555386856bb3056d5fdd9dab279"}, - {file = "yarl-1.9.3-cp311-cp311-win_amd64.whl", hash = "sha256:f7271d6bd8838c49ba8ae647fc06469137e1c161a7ef97d778b72904d9b68696"}, - {file = "yarl-1.9.3-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:dd318e6b75ca80bff0b22b302f83a8ee41c62b8ac662ddb49f67ec97e799885d"}, - {file = "yarl-1.9.3-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:c4b1efb11a8acd13246ffb0bee888dd0e8eb057f8bf30112e3e21e421eb82d4a"}, - {file = "yarl-1.9.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:c6f034386e5550b5dc8ded90b5e2ff7db21f0f5c7de37b6efc5dac046eb19c10"}, - {file = "yarl-1.9.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cd49a908cb6d387fc26acee8b7d9fcc9bbf8e1aca890c0b2fdfd706057546080"}, - {file = "yarl-1.9.3-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:aa4643635f26052401750bd54db911b6342eb1a9ac3e74f0f8b58a25d61dfe41"}, - {file = "yarl-1.9.3-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e741bd48e6a417bdfbae02e088f60018286d6c141639359fb8df017a3b69415a"}, - {file = "yarl-1.9.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7c86d0d0919952d05df880a1889a4f0aeb6868e98961c090e335671dea5c0361"}, - {file = "yarl-1.9.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3d5434b34100b504aabae75f0622ebb85defffe7b64ad8f52b8b30ec6ef6e4b9"}, - {file = "yarl-1.9.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:79e1df60f7c2b148722fb6cafebffe1acd95fd8b5fd77795f56247edaf326752"}, - {file = "yarl-1.9.3-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:44e91a669c43f03964f672c5a234ae0d7a4d49c9b85d1baa93dec28afa28ffbd"}, - {file = "yarl-1.9.3-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:3cfa4dbe17b2e6fca1414e9c3bcc216f6930cb18ea7646e7d0d52792ac196808"}, - {file = "yarl-1.9.3-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:88d2c3cc4b2f46d1ba73d81c51ec0e486f59cc51165ea4f789677f91a303a9a7"}, - {file = "yarl-1.9.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:cccdc02e46d2bd7cb5f38f8cc3d9db0d24951abd082b2f242c9e9f59c0ab2af3"}, - {file = "yarl-1.9.3-cp312-cp312-win32.whl", hash = "sha256:96758e56dceb8a70f8a5cff1e452daaeff07d1cc9f11e9b0c951330f0a2396a7"}, - {file = "yarl-1.9.3-cp312-cp312-win_amd64.whl", hash = "sha256:c4472fe53ebf541113e533971bd8c32728debc4c6d8cc177f2bff31d011ec17e"}, - {file = "yarl-1.9.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:126638ab961633f0940a06e1c9d59919003ef212a15869708dcb7305f91a6732"}, - {file = "yarl-1.9.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c99ddaddb2fbe04953b84d1651149a0d85214780e4d0ee824e610ab549d98d92"}, - {file = "yarl-1.9.3-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8dab30b21bd6fb17c3f4684868c7e6a9e8468078db00f599fb1c14e324b10fca"}, - {file = "yarl-1.9.3-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:828235a2a169160ee73a2fcfb8a000709edf09d7511fccf203465c3d5acc59e4"}, - {file = "yarl-1.9.3-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fc391e3941045fd0987c77484b2799adffd08e4b6735c4ee5f054366a2e1551d"}, - {file = "yarl-1.9.3-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:51382c72dd5377861b573bd55dcf680df54cea84147c8648b15ac507fbef984d"}, - {file = "yarl-1.9.3-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:28a108cb92ce6cf867690a962372996ca332d8cda0210c5ad487fe996e76b8bb"}, - {file = "yarl-1.9.3-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:8f18a7832ff85dfcd77871fe677b169b1bc60c021978c90c3bb14f727596e0ae"}, - {file = "yarl-1.9.3-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:7eaf13af79950142ab2bbb8362f8d8d935be9aaf8df1df89c86c3231e4ff238a"}, - {file = "yarl-1.9.3-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:66a6dbf6ca7d2db03cc61cafe1ee6be838ce0fbc97781881a22a58a7c5efef42"}, - {file = "yarl-1.9.3-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:1a0a4f3aaa18580038cfa52a7183c8ffbbe7d727fe581300817efc1e96d1b0e9"}, - {file = "yarl-1.9.3-cp37-cp37m-win32.whl", hash = "sha256:946db4511b2d815979d733ac6a961f47e20a29c297be0d55b6d4b77ee4b298f6"}, - {file = "yarl-1.9.3-cp37-cp37m-win_amd64.whl", hash = "sha256:2dad8166d41ebd1f76ce107cf6a31e39801aee3844a54a90af23278b072f1ccf"}, - {file = "yarl-1.9.3-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:bb72d2a94481e7dc7a0c522673db288f31849800d6ce2435317376a345728225"}, - {file = "yarl-1.9.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:9a172c3d5447b7da1680a1a2d6ecdf6f87a319d21d52729f45ec938a7006d5d8"}, - {file = "yarl-1.9.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:2dc72e891672343b99db6d497024bf8b985537ad6c393359dc5227ef653b2f17"}, - {file = "yarl-1.9.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b8d51817cf4b8d545963ec65ff06c1b92e5765aa98831678d0e2240b6e9fd281"}, - {file = "yarl-1.9.3-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:53ec65f7eee8655bebb1f6f1607760d123c3c115a324b443df4f916383482a67"}, - {file = "yarl-1.9.3-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cfd77e8e5cafba3fb584e0f4b935a59216f352b73d4987be3af51f43a862c403"}, - {file = "yarl-1.9.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e73db54c967eb75037c178a54445c5a4e7461b5203b27c45ef656a81787c0c1b"}, - {file = "yarl-1.9.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:09c19e5f4404574fcfb736efecf75844ffe8610606f3fccc35a1515b8b6712c4"}, - {file = "yarl-1.9.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6280353940f7e5e2efaaabd686193e61351e966cc02f401761c4d87f48c89ea4"}, - {file = "yarl-1.9.3-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:c25ec06e4241e162f5d1f57c370f4078797ade95c9208bd0c60f484834f09c96"}, - {file = "yarl-1.9.3-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:7217234b10c64b52cc39a8d82550342ae2e45be34f5bff02b890b8c452eb48d7"}, - {file = "yarl-1.9.3-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:4ce77d289f8d40905c054b63f29851ecbfd026ef4ba5c371a158cfe6f623663e"}, - {file = "yarl-1.9.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:5f74b015c99a5eac5ae589de27a1201418a5d9d460e89ccb3366015c6153e60a"}, - {file = "yarl-1.9.3-cp38-cp38-win32.whl", hash = "sha256:8a2538806be846ea25e90c28786136932ec385c7ff3bc1148e45125984783dc6"}, - {file = "yarl-1.9.3-cp38-cp38-win_amd64.whl", hash = "sha256:6465d36381af057d0fab4e0f24ef0e80ba61f03fe43e6eeccbe0056e74aadc70"}, - {file = "yarl-1.9.3-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:2f3c8822bc8fb4a347a192dd6a28a25d7f0ea3262e826d7d4ef9cc99cd06d07e"}, - {file = "yarl-1.9.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:b7831566595fe88ba17ea80e4b61c0eb599f84c85acaa14bf04dd90319a45b90"}, - {file = "yarl-1.9.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ff34cb09a332832d1cf38acd0f604c068665192c6107a439a92abfd8acf90fe2"}, - {file = "yarl-1.9.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fe8080b4f25dfc44a86bedd14bc4f9d469dfc6456e6f3c5d9077e81a5fedfba7"}, - {file = "yarl-1.9.3-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8535e111a064f3bdd94c0ed443105934d6f005adad68dd13ce50a488a0ad1bf3"}, - {file = "yarl-1.9.3-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0d155a092bf0ebf4a9f6f3b7a650dc5d9a5bbb585ef83a52ed36ba46f55cc39d"}, - {file = "yarl-1.9.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:778df71c8d0c8c9f1b378624b26431ca80041660d7be7c3f724b2c7a6e65d0d6"}, - {file = "yarl-1.9.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b9f9cafaf031c34d95c1528c16b2fa07b710e6056b3c4e2e34e9317072da5d1a"}, - {file = "yarl-1.9.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:ca6b66f69e30f6e180d52f14d91ac854b8119553b524e0e28d5291a724f0f423"}, - {file = "yarl-1.9.3-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:e0e7e83f31e23c5d00ff618045ddc5e916f9e613d33c5a5823bc0b0a0feb522f"}, - {file = "yarl-1.9.3-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:af52725c7c39b0ee655befbbab5b9a1b209e01bb39128dce0db226a10014aacc"}, - {file = "yarl-1.9.3-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:0ab5baaea8450f4a3e241ef17e3d129b2143e38a685036b075976b9c415ea3eb"}, - {file = "yarl-1.9.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:6d350388ba1129bc867c6af1cd17da2b197dff0d2801036d2d7d83c2d771a682"}, - {file = "yarl-1.9.3-cp39-cp39-win32.whl", hash = "sha256:e2a16ef5fa2382af83bef4a18c1b3bcb4284c4732906aa69422cf09df9c59f1f"}, - {file = "yarl-1.9.3-cp39-cp39-win_amd64.whl", hash = "sha256:d92d897cb4b4bf915fbeb5e604c7911021a8456f0964f3b8ebbe7f9188b9eabb"}, - {file = "yarl-1.9.3-py3-none-any.whl", hash = "sha256:271d63396460b6607b588555ea27a1a02b717ca2e3f2cf53bdde4013d7790929"}, - {file = "yarl-1.9.3.tar.gz", hash = "sha256:4a14907b597ec55740f63e52d7fee0e9ee09d5b9d57a4f399a7423268e457b57"}, + {file = "yarl-1.9.4-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:a8c1df72eb746f4136fe9a2e72b0c9dc1da1cbd23b5372f94b5820ff8ae30e0e"}, + {file = "yarl-1.9.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a3a6ed1d525bfb91b3fc9b690c5a21bb52de28c018530ad85093cc488bee2dd2"}, + {file = "yarl-1.9.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c38c9ddb6103ceae4e4498f9c08fac9b590c5c71b0370f98714768e22ac6fa66"}, + {file = "yarl-1.9.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d9e09c9d74f4566e905a0b8fa668c58109f7624db96a2171f21747abc7524234"}, + {file = "yarl-1.9.4-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b8477c1ee4bd47c57d49621a062121c3023609f7a13b8a46953eb6c9716ca392"}, + {file = "yarl-1.9.4-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d5ff2c858f5f6a42c2a8e751100f237c5e869cbde669a724f2062d4c4ef93551"}, + {file = "yarl-1.9.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:357495293086c5b6d34ca9616a43d329317feab7917518bc97a08f9e55648455"}, + {file = "yarl-1.9.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:54525ae423d7b7a8ee81ba189f131054defdb122cde31ff17477951464c1691c"}, + {file = "yarl-1.9.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:801e9264d19643548651b9db361ce3287176671fb0117f96b5ac0ee1c3530d53"}, + {file = "yarl-1.9.4-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:e516dc8baf7b380e6c1c26792610230f37147bb754d6426462ab115a02944385"}, + {file = "yarl-1.9.4-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:7d5aaac37d19b2904bb9dfe12cdb08c8443e7ba7d2852894ad448d4b8f442863"}, + {file = "yarl-1.9.4-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:54beabb809ffcacbd9d28ac57b0db46e42a6e341a030293fb3185c409e626b8b"}, + {file = "yarl-1.9.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:bac8d525a8dbc2a1507ec731d2867025d11ceadcb4dd421423a5d42c56818541"}, + {file = "yarl-1.9.4-cp310-cp310-win32.whl", hash = "sha256:7855426dfbddac81896b6e533ebefc0af2f132d4a47340cee6d22cac7190022d"}, + {file = "yarl-1.9.4-cp310-cp310-win_amd64.whl", hash = "sha256:848cd2a1df56ddbffeb375535fb62c9d1645dde33ca4d51341378b3f5954429b"}, + {file = "yarl-1.9.4-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:35a2b9396879ce32754bd457d31a51ff0a9d426fd9e0e3c33394bf4b9036b099"}, + {file = "yarl-1.9.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4c7d56b293cc071e82532f70adcbd8b61909eec973ae9d2d1f9b233f3d943f2c"}, + {file = "yarl-1.9.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d8a1c6c0be645c745a081c192e747c5de06e944a0d21245f4cf7c05e457c36e0"}, + {file = "yarl-1.9.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4b3c1ffe10069f655ea2d731808e76e0f452fc6c749bea04781daf18e6039525"}, + {file = "yarl-1.9.4-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:549d19c84c55d11687ddbd47eeb348a89df9cb30e1993f1b128f4685cd0ebbf8"}, + {file = "yarl-1.9.4-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a7409f968456111140c1c95301cadf071bd30a81cbd7ab829169fb9e3d72eae9"}, + {file = "yarl-1.9.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e23a6d84d9d1738dbc6e38167776107e63307dfc8ad108e580548d1f2c587f42"}, + {file = "yarl-1.9.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d8b889777de69897406c9fb0b76cdf2fd0f31267861ae7501d93003d55f54fbe"}, + {file = "yarl-1.9.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:03caa9507d3d3c83bca08650678e25364e1843b484f19986a527630ca376ecce"}, + {file = "yarl-1.9.4-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:4e9035df8d0880b2f1c7f5031f33f69e071dfe72ee9310cfc76f7b605958ceb9"}, + {file = "yarl-1.9.4-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:c0ec0ed476f77db9fb29bca17f0a8fcc7bc97ad4c6c1d8959c507decb22e8572"}, + {file = "yarl-1.9.4-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:ee04010f26d5102399bd17f8df8bc38dc7ccd7701dc77f4a68c5b8d733406958"}, + {file = "yarl-1.9.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:49a180c2e0743d5d6e0b4d1a9e5f633c62eca3f8a86ba5dd3c471060e352ca98"}, + {file = "yarl-1.9.4-cp311-cp311-win32.whl", hash = "sha256:81eb57278deb6098a5b62e88ad8281b2ba09f2f1147c4767522353eaa6260b31"}, + {file = "yarl-1.9.4-cp311-cp311-win_amd64.whl", hash = "sha256:d1d2532b340b692880261c15aee4dc94dd22ca5d61b9db9a8a361953d36410b1"}, + {file = "yarl-1.9.4-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:0d2454f0aef65ea81037759be5ca9947539667eecebca092733b2eb43c965a81"}, + {file = "yarl-1.9.4-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:44d8ffbb9c06e5a7f529f38f53eda23e50d1ed33c6c869e01481d3fafa6b8142"}, + {file = "yarl-1.9.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:aaaea1e536f98754a6e5c56091baa1b6ce2f2700cc4a00b0d49eca8dea471074"}, + {file = "yarl-1.9.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3777ce5536d17989c91696db1d459574e9a9bd37660ea7ee4d3344579bb6f129"}, + {file = "yarl-1.9.4-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9fc5fc1eeb029757349ad26bbc5880557389a03fa6ada41703db5e068881e5f2"}, + {file = "yarl-1.9.4-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ea65804b5dc88dacd4a40279af0cdadcfe74b3e5b4c897aa0d81cf86927fee78"}, + {file = "yarl-1.9.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aa102d6d280a5455ad6a0f9e6d769989638718e938a6a0a2ff3f4a7ff8c62cc4"}, + {file = "yarl-1.9.4-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:09efe4615ada057ba2d30df871d2f668af661e971dfeedf0c159927d48bbeff0"}, + {file = "yarl-1.9.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:008d3e808d03ef28542372d01057fd09168419cdc8f848efe2804f894ae03e51"}, + {file = "yarl-1.9.4-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:6f5cb257bc2ec58f437da2b37a8cd48f666db96d47b8a3115c29f316313654ff"}, + {file = "yarl-1.9.4-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:992f18e0ea248ee03b5a6e8b3b4738850ae7dbb172cc41c966462801cbf62cf7"}, + {file = "yarl-1.9.4-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:0e9d124c191d5b881060a9e5060627694c3bdd1fe24c5eecc8d5d7d0eb6faabc"}, + {file = "yarl-1.9.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:3986b6f41ad22988e53d5778f91855dc0399b043fc8946d4f2e68af22ee9ff10"}, + {file = "yarl-1.9.4-cp312-cp312-win32.whl", hash = "sha256:4b21516d181cd77ebd06ce160ef8cc2a5e9ad35fb1c5930882baff5ac865eee7"}, + {file = "yarl-1.9.4-cp312-cp312-win_amd64.whl", hash = "sha256:a9bd00dc3bc395a662900f33f74feb3e757429e545d831eef5bb280252631984"}, + {file = "yarl-1.9.4-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:63b20738b5aac74e239622d2fe30df4fca4942a86e31bf47a81a0e94c14df94f"}, + {file = "yarl-1.9.4-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d7d7f7de27b8944f1fee2c26a88b4dabc2409d2fea7a9ed3df79b67277644e17"}, + {file = "yarl-1.9.4-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c74018551e31269d56fab81a728f683667e7c28c04e807ba08f8c9e3bba32f14"}, + {file = "yarl-1.9.4-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ca06675212f94e7a610e85ca36948bb8fc023e458dd6c63ef71abfd482481aa5"}, + {file = "yarl-1.9.4-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5aef935237d60a51a62b86249839b51345f47564208c6ee615ed2a40878dccdd"}, + {file = "yarl-1.9.4-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2b134fd795e2322b7684155b7855cc99409d10b2e408056db2b93b51a52accc7"}, + {file = "yarl-1.9.4-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:d25039a474c4c72a5ad4b52495056f843a7ff07b632c1b92ea9043a3d9950f6e"}, + {file = "yarl-1.9.4-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:f7d6b36dd2e029b6bcb8a13cf19664c7b8e19ab3a58e0fefbb5b8461447ed5ec"}, + {file = "yarl-1.9.4-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:957b4774373cf6f709359e5c8c4a0af9f6d7875db657adb0feaf8d6cb3c3964c"}, + {file = "yarl-1.9.4-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:d7eeb6d22331e2fd42fce928a81c697c9ee2d51400bd1a28803965883e13cead"}, + {file = "yarl-1.9.4-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:6a962e04b8f91f8c4e5917e518d17958e3bdee71fd1d8b88cdce74dd0ebbf434"}, + {file = "yarl-1.9.4-cp37-cp37m-win32.whl", hash = "sha256:f3bc6af6e2b8f92eced34ef6a96ffb248e863af20ef4fde9448cc8c9b858b749"}, + {file = "yarl-1.9.4-cp37-cp37m-win_amd64.whl", hash = "sha256:ad4d7a90a92e528aadf4965d685c17dacff3df282db1121136c382dc0b6014d2"}, + {file = "yarl-1.9.4-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:ec61d826d80fc293ed46c9dd26995921e3a82146feacd952ef0757236fc137be"}, + {file = "yarl-1.9.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:8be9e837ea9113676e5754b43b940b50cce76d9ed7d2461df1af39a8ee674d9f"}, + {file = "yarl-1.9.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:bef596fdaa8f26e3d66af846bbe77057237cb6e8efff8cd7cc8dff9a62278bbf"}, + {file = "yarl-1.9.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2d47552b6e52c3319fede1b60b3de120fe83bde9b7bddad11a69fb0af7db32f1"}, + {file = "yarl-1.9.4-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:84fc30f71689d7fc9168b92788abc977dc8cefa806909565fc2951d02f6b7d57"}, + {file = "yarl-1.9.4-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4aa9741085f635934f3a2583e16fcf62ba835719a8b2b28fb2917bb0537c1dfa"}, + {file = "yarl-1.9.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:206a55215e6d05dbc6c98ce598a59e6fbd0c493e2de4ea6cc2f4934d5a18d130"}, + {file = "yarl-1.9.4-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:07574b007ee20e5c375a8fe4a0789fad26db905f9813be0f9fef5a68080de559"}, + {file = "yarl-1.9.4-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:5a2e2433eb9344a163aced6a5f6c9222c0786e5a9e9cac2c89f0b28433f56e23"}, + {file = "yarl-1.9.4-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:6ad6d10ed9b67a382b45f29ea028f92d25bc0bc1daf6c5b801b90b5aa70fb9ec"}, + {file = "yarl-1.9.4-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:6fe79f998a4052d79e1c30eeb7d6c1c1056ad33300f682465e1b4e9b5a188b78"}, + {file = "yarl-1.9.4-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:a825ec844298c791fd28ed14ed1bffc56a98d15b8c58a20e0e08c1f5f2bea1be"}, + {file = "yarl-1.9.4-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:8619d6915b3b0b34420cf9b2bb6d81ef59d984cb0fde7544e9ece32b4b3043c3"}, + {file = "yarl-1.9.4-cp38-cp38-win32.whl", hash = "sha256:686a0c2f85f83463272ddffd4deb5e591c98aac1897d65e92319f729c320eece"}, + {file = "yarl-1.9.4-cp38-cp38-win_amd64.whl", hash = "sha256:a00862fb23195b6b8322f7d781b0dc1d82cb3bcac346d1e38689370cc1cc398b"}, + {file = "yarl-1.9.4-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:604f31d97fa493083ea21bd9b92c419012531c4e17ea6da0f65cacdcf5d0bd27"}, + {file = "yarl-1.9.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:8a854227cf581330ffa2c4824d96e52ee621dd571078a252c25e3a3b3d94a1b1"}, + {file = "yarl-1.9.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ba6f52cbc7809cd8d74604cce9c14868306ae4aa0282016b641c661f981a6e91"}, + {file = "yarl-1.9.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a6327976c7c2f4ee6816eff196e25385ccc02cb81427952414a64811037bbc8b"}, + {file = "yarl-1.9.4-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8397a3817d7dcdd14bb266283cd1d6fc7264a48c186b986f32e86d86d35fbac5"}, + {file = "yarl-1.9.4-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e0381b4ce23ff92f8170080c97678040fc5b08da85e9e292292aba67fdac6c34"}, + {file = "yarl-1.9.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:23d32a2594cb5d565d358a92e151315d1b2268bc10f4610d098f96b147370136"}, + {file = "yarl-1.9.4-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ddb2a5c08a4eaaba605340fdee8fc08e406c56617566d9643ad8bf6852778fc7"}, + {file = "yarl-1.9.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:26a1dc6285e03f3cc9e839a2da83bcbf31dcb0d004c72d0730e755b33466c30e"}, + {file = "yarl-1.9.4-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:18580f672e44ce1238b82f7fb87d727c4a131f3a9d33a5e0e82b793362bf18b4"}, + {file = "yarl-1.9.4-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:29e0f83f37610f173eb7e7b5562dd71467993495e568e708d99e9d1944f561ec"}, + {file = "yarl-1.9.4-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:1f23e4fe1e8794f74b6027d7cf19dc25f8b63af1483d91d595d4a07eca1fb26c"}, + {file = "yarl-1.9.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:db8e58b9d79200c76956cefd14d5c90af54416ff5353c5bfd7cbe58818e26ef0"}, + {file = "yarl-1.9.4-cp39-cp39-win32.whl", hash = "sha256:c7224cab95645c7ab53791022ae77a4509472613e839dab722a72abe5a684575"}, + {file = "yarl-1.9.4-cp39-cp39-win_amd64.whl", hash = "sha256:824d6c50492add5da9374875ce72db7a0733b29c2394890aef23d533106e2b15"}, + {file = "yarl-1.9.4-py3-none-any.whl", hash = "sha256:928cecb0ef9d5a7946eb6ff58417ad2fe9375762382f1bf5c55e61645f2c43ad"}, + {file = "yarl-1.9.4.tar.gz", hash = "sha256:566db86717cf8080b99b58b083b773a908ae40f06681e87e589a976faf8246bf"}, ] [package.dependencies] @@ -1909,20 +2543,20 @@ multidict = ">=4.0" [[package]] name = "zipp" -version = "3.17.0" +version = "3.18.1" description = "Backport of pathlib-compatible object wrapper for zip files" optional = false python-versions = ">=3.8" files = [ - {file = "zipp-3.17.0-py3-none-any.whl", hash = "sha256:0e923e726174922dce09c53c59ad483ff7bbb8e572e00c7f7c46b88556409f31"}, - {file = "zipp-3.17.0.tar.gz", hash = "sha256:84e64a1c28cf7e91ed2078bb8cc8c259cb19b76942096c8d7b84947690cabaf0"}, + {file = "zipp-3.18.1-py3-none-any.whl", hash = "sha256:206f5a15f2af3dbaee80769fb7dc6f249695e940acca08dfb2a4769fe61e538b"}, + {file = "zipp-3.18.1.tar.gz", hash = "sha256:2884ed22e7d8961de1c9a05142eb69a247f120291bc0206a00a7642f09b5b715"}, ] [package.extras] -docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (<7.2.5)", "sphinx (>=3.5)", "sphinx-lint"] -testing = ["big-O", "jaraco.functools", "jaraco.itertools", "more-itertools", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-ignore-flaky", "pytest-mypy (>=0.9.1)", "pytest-ruff"] +docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] +testing = ["big-O", "jaraco.functools", "jaraco.itertools", "more-itertools", "pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-ignore-flaky", "pytest-mypy", "pytest-ruff (>=0.2.1)"] [metadata] lock-version = "2.0" python-versions = "^3.8" -content-hash = "3d7d922bc36f0d3543e63600228958e26705f189f9e62e9dd8ee6b9f55547dc2" +content-hash = "1fa0750faa22cd3df810c84b5c657753b0f05bc48fe70a565f279a807437b8a9" diff --git a/app/pyproject.toml b/app/pyproject.toml index 5612480..cb144be 100644 --- a/app/pyproject.toml +++ b/app/pyproject.toml @@ -1,13 +1,21 @@ [tool.poetry] name = "strelka-ui" -version = "0.1.0" +version = "2.43" description = "Strelka's File Submission Portal" authors = [ "Paul Hutelmyer ", ] [tool.poetry.dependencies] -python = "^3.8" +Alembic = "1.6.2" +Astroid = "2.9.2" +Attrs = "21.4.0" +Black = "24.3.0" +Certifi = "2023.7.22" +Chardet = "4.0.0" +Click = "8.0.0" +Cffi = "1.14.5" +Cryptography = "42.0.4" Flask = "^2.2" Flask-Caching = "1.10.1" Flask-Cors = "3.0.10" @@ -15,52 +23,43 @@ Flask-Expects-Json = "1.7.0" Flask-Migrate = "2.7.0" Flask-Script = "2.0.6" Flask-SQLAlchemy = "2.5.1" -Paste = "3.5.2" -Alembic = "1.6.2" -SQLAlchemy = "1.4.15" -SQLAlchemy-JSON = "0.4.0" -Psycopg2-Binary = "2.9.4" -grpcio = "1.53.0" -grpcio-tools = "1.41.0" -Cryptography = "41.0.6" -PyJWT = "2.4.0" -PyOpenSSL = "20.0.1" -Click = "8.0.0" +Grpcio = "1.53.2" +Grpcio-tools = "1.41.0" Isort = "5.10.1" -Mypy-Extensions = "0.4.3" -Pylint = "2.12.2" -Pylint-Flask = "0.6" -Pylint-Flask-SQLAlchemy = "0.2.0" -Pylint-Plugin-Utils = "0.7" -Python-Dotenv = "0.17.1" -Waitress = "2.1.2" -Astroid = "2.9.2" -Attrs = "21.4.0" -Black = "21.12b0" -Certifi = "2023.7.22" -Cffi = "1.14.5" -Chardet = "4.0.0" Jsonschema = "4.3.3" -Lazy-Object-Proxy = "1.7.1" Ldap3 = "2.9.1" +Lazy-Object-Proxy = "1.7.1" Mako = "1.2.2" MarkupSafe = "^2.0.0" Mccabe = "0.6.1" +Mypy-Extensions = "0.4.3" Pathspec = "0.9.0" +Paste = "3.5.2" Platformdirs = "2.4.1" Protobuf = "3.18.3" +Psycopg2-Binary = "2.9.9" Pyasn1 = "0.4.8" +PyJWT = "2.4.0" +PyOpenSSL = "20.0.1" Pycparser = "2.20" Pyrsistent = "0.18.0" +python = "^3.8" +Python-Dotenv = "0.17.1" Python-Dateutil = "2.8.1" +rarfile = "^4.2" Requests = "2.31.0" Six = "1.16.0" +SQLAlchemy = "1.4.15" +SQLAlchemy-JSON = "0.4.0" Toml = "0.10.2" Tomli = "1.2.3" Typing-Extensions = "4.0.1" Urllib3 = "1.26.18" +Waitress = "2.1.2" Wrapt = "1.13.3" -vt-py = "0.17.5" +vt-py = "0.18.0" +py7zr = "^0.21.0" +python-magic = "^0.4.27" [tool.poetry.dev-dependencies] diff --git a/app/services/virustotal.py b/app/services/virustotal.py deleted file mode 100644 index 3858f9b..0000000 --- a/app/services/virustotal.py +++ /dev/null @@ -1,86 +0,0 @@ -import logging -from io import BytesIO -import requests -import time - -import vt - - -def get_virustotal_positives(api_key: str, file_hash: str) -> int: - """ - Queries the VirusTotal API for a given file hash and returns the count of - positive detections and total scans. - - Parameters: - api_key (str): VirusTotal API key. - file_hash (str): The hash of the file to be queried. - - Returns: - int: Count of positives (malicious) - """ - with vt.Client(api_key) as client: - try: - # Retrieve the file analysis report from VirusTotal - file_analysis = client.get_object(f"/files/{file_hash}") - - # Return positives count - return file_analysis.last_analysis_stats["malicious"] - - except vt.error.APIError as e: - logging.warning(f"VirusTotal Response: {e}") - return -1 - - -def create_vt_zip_and_download(api_key, file_hashes, password, max_attempts=3): - # Step 1: Create a password-protected ZIP with VirusTotal files - create_zip_url = "https://www.virustotal.com/api/v3/intelligence/zip_files" - payload = {"data": {"password": password, "hashes": file_hashes}} - headers = { - "x-apikey": api_key, - "accept": "application/json", - "content-type": "application/json", - } - response = requests.post(create_zip_url, json=payload, headers=headers) - - if not response.ok: - return Exception(f"Error creating ZIP: {response.text}") - - zip_id = response.json()["data"]["id"] - - # Step 2: Poll for the ZIP file’s status, up to max_attempts times - check_zip_url = f"https://www.virustotal.com/api/v3/intelligence/zip_files/{zip_id}" - attempts = 0 - while attempts < max_attempts: - response = requests.get(check_zip_url, headers=headers) - if not response.ok: - return Exception(f"Error checking ZIP status: {response.text}") - - if response.json()["data"]["attributes"]["status"] == "finished": - break - - time.sleep(10) # Wait before polling again - attempts += 1 - - if attempts == max_attempts: - return Exception( - "Error: Maximum polling attempts reached, ZIP file may not be ready." - ) - - # Step 3: Get the ZIP file’s download URL - get_download_url = f"{check_zip_url}/download_url" - response = requests.get(get_download_url, headers=headers) - - if not response.ok: - return Exception(f"Error getting download URL: {response.text}") - - download_url = response.json()["data"] - - # Step 4: Download the ZIP file into a BytesIO buffer - response = requests.get(download_url, headers={"x-apikey": api_key}) - - if not response.ok: - return Exception(f"Error downloading ZIP: {response.text}") - - # Return a file-like object containing the downloaded ZIP file - file_buffer = BytesIO(response.content) - return file_buffer diff --git a/app/strelka/__init__.py b/app/strelka/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/app/app.py b/app/strelka_ui/__main__.py similarity index 74% rename from app/app.py rename to app/strelka_ui/__main__.py index 78f9da7..2cd6e4e 100644 --- a/app/app.py +++ b/app/strelka_ui/__main__.py @@ -14,11 +14,10 @@ from paste.translogger import TransLogger from waitress import serve -from blueprints.auth import auth -from blueprints.strelka import strelka -from blueprints.ui import ui -from models import db - +from strelka_ui.blueprints.auth import auth +from strelka_ui.blueprints.strelka import strelka +from strelka_ui.blueprints.ui import ui +from strelka_ui.models import db def create_app() -> Flask: """Start and serve app assets and API endpoints""" @@ -32,9 +31,9 @@ def create_app() -> Flask: app.logger.info("Serving app static assets from %s", ui_folder) if app.config["ENV"] == "production": - app.config.from_object("config.config.ProductionConfig") + app.config.from_object("strelka_ui.config.config.ProductionConfig") else: - app.config.from_object("config.config.DevelopmentConfig") + app.config.from_object("strelka_ui.config.config.DevelopmentConfig") app.logger.info( "Using %s configuration", @@ -60,9 +59,13 @@ def create_app() -> Flask: if __name__ == "__main__": logging.basicConfig(stream=sys.stdout, level=logging.INFO) + # Suppress thread wait warnings for Waitress + waitress_logger = logging.getLogger("waitress.queue") + waitress_logger.setLevel(logging.ERROR) + main_app: Flask = create_app() serve(TransLogger(main_app, setup_console_handler=False), host="0.0.0.0", port=8080) # uncomment below for local flask app development with hot reloading - main_app.run(host="0.0.0.0", port=80, threaded=True) + # main_app.run(host="0.0.0.0", port=80, threaded=True) diff --git a/app/blueprints/auth.py b/app/strelka_ui/blueprints/auth.py similarity index 96% rename from app/blueprints/auth.py rename to app/strelka_ui/blueprints/auth.py index 1be5f26..9ce55a7 100644 --- a/app/blueprints/auth.py +++ b/app/strelka_ui/blueprints/auth.py @@ -8,9 +8,9 @@ from flask import Blueprint, current_app, jsonify, request, session from jsonschema import ValidationError, validate -from database import db -from models import ApiKey, User -from services.auth import auth_required, check_credentials +from strelka_ui.database import db +from strelka_ui.models import ApiKey, User +from strelka_ui.services.auth import auth_required, check_credentials auth = Blueprint("auth", __name__, url_prefix="/auth") diff --git a/app/blueprints/strelka.py b/app/strelka_ui/blueprints/strelka.py similarity index 53% rename from app/blueprints/strelka.py rename to app/strelka_ui/blueprints/strelka.py index e8750ea..2c5ad45 100644 --- a/app/blueprints/strelka.py +++ b/app/strelka_ui/blueprints/strelka.py @@ -4,23 +4,72 @@ import os from collections import defaultdict -from io import BytesIO -from typing import Dict, Tuple +from typing import Dict, Tuple, Union -from flask import Blueprint, current_app, jsonify, request, session, Response -from sqlalchemy import or_, desc, asc, func, case -from sqlalchemy.dialects.postgresql import JSON +from flask import Blueprint, jsonify, request, session, Response +from sqlalchemy import or_, desc, asc, func, case, cast, String from sqlalchemy.orm import joinedload -from database import db -from models import FileSubmission, User -from services.auth import auth_required -from services.strelka import get_db_status, get_frontend_status, submit_data -from services.virustotal import get_virustotal_positives, create_vt_zip_and_download -from services.insights import get_insights +from strelka_ui.database import db +from strelka_ui.models import FileSubmission, User +from strelka_ui.services.auth import auth_required +from strelka_ui.services.files import decrypt_file, check_file_size, convert_bytesio_to_filestorage +from strelka_ui.services.strelka import get_db_status, get_frontend_status, submit_data +from strelka_ui.services.virustotal import ( + get_virustotal_positives, + create_vt_zip_and_download, + get_virustotal_widget_url, +) +from strelka_ui.services.insights import get_insights strelka = Blueprint("strelka", __name__, url_prefix="/strelka") +# Define the priority of each mimetype (For VirusTotal Scanning Priorization) +MIMETYPE_PRIORITY = { + "application/x-dosexec": 1, # Executables + "application/x-executable": 1, + "application/vnd.microsoft.portable-executable": 1, + "application/x-elf": 1, + "application/zip": 2, # Archives + "application/x-rar-compressed": 2, + "application/x-msi": 2, + "application/x-7z-compressed": 2, + "application/vnd.ms-cab-compressed": 2, + "application/x-tar": 2, + "application/gzip": 2, + "application/octet-stream": 2, # Unknown streams + "text/plain": 3, # Scripts and source code + "text/x-script": 3, + "text/javascript": 3, + "application/x-bat": 3, + "application/x-sh": 3, + "application/x-python": 3, + "text/x-python": 3, + "text/html": 4, # Web files + "application/xhtml+xml": 4, + "application/xml": 4, + "text/xml": 4, + "text/css": 4, + "application/pdf": 5, # Documents + "application/msword": 5, + "application/vnd.ms-excel": 5, + "application/vnd.ms-powerpoint": 5, + "application/vnd.openxmlformats-officedocument.wordprocessingml.document": 5, + "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet": 5, + "application/vnd.openxmlformats-officedocument.presentationml.presentation": 5, + # Images + "image/jpeg": 10, + "image/png": 10, + "image/gif": 10, + "image/webp": 10, + "image/tiff": 10, + "image/bmp": 10, + "image/svg+xml": 10, + # Other file types + "application/json": 20, # Data formats + "application/xml": 20, +} + @strelka.route("/status/strelka", methods=["GET"]) def get_server_status() -> Tuple[Response, int]: @@ -60,7 +109,9 @@ def get_database_status() -> Tuple[Response, int]: @strelka.route("/upload", methods=["POST"]) @auth_required -def submit_file(user: User) -> Tuple[Response, int]: +def submit_file( + user: User, +) -> Union[tuple[Response, int], tuple[dict[str, Union[Response, str]], int]]: """ Submit a file (or hash) to the Strelka file analysis engine and save the analysis results to the database. @@ -92,6 +143,7 @@ def submit_file(user: User) -> Tuple[Response, int]: if "file" in request.files: file = request.files["file"] submitted_description = request.form["description"] + submitted_password = request.form.get("password", "") submitted_type = "api" # Check if the submitted filename is empty. @@ -106,6 +158,37 @@ def submit_file(user: User) -> Tuple[Response, int]: 400, ) + # Check to see if size of file is greater than 150MB + is_valid_size, file_size = check_file_size(file.stream) + if not is_valid_size: + return ( + jsonify( + { + "error": "Strelka submission was not successful.", + "details": f"File submitted cannot be larger than 150MB. Actual size: {file_size} bytes.", + } + ), + 400, + ) + + # If a password was provided, we must attempt to unpack it. + if submitted_password: + try: + # Assume all uploads should be attempted to be unpacked + file, message = decrypt_file(file, submitted_password) + if not file: + return ( + jsonify({"error": "Failed to unpack file", "details": message}), + 400, + ) + else: + file = message + except Exception as e: + return ( + jsonify({"error": "Failed to unpack file", "details": str(e)}), + 400, + ) + # VirusTotal Upload Function else: submission = json.loads(request.data) @@ -114,145 +197,228 @@ def submit_file(user: User) -> Tuple[Response, int]: submitted_type = "virustotal" if os.environ.get("VIRUSTOTAL_API_KEY"): - file = create_vt_zip_and_download( - api_key=os.environ.get("VIRUSTOTAL_API_KEY"), - file_hashes=[submitted_hash], - password="infected", - ) - if "Error" in str(file): + try: + file = create_vt_zip_and_download( + api_key=os.environ.get("VIRUSTOTAL_API_KEY"), + file_hash=[submitted_hash], + password="infected", + ) + + # Check if response is successful + file = convert_bytesio_to_filestorage(file, submission["hash"]) + + # Decrypt to file prior to submission to Strelka + file, message = decrypt_file(file, "infected") + + if file: + file = message + + except Exception: return ( jsonify( { "error": "VirusTotal request was not successful.", - "details": str(file.args[0]), + "details": "Hash not found on VirusTotal.", } ), 400, ) - file.filename = submitted_hash + else: + return ( + jsonify( + { + "error": "VirusTotal request was not successful.", + "details": "No VirusTotal API key has been loaded. Check the README for details.", + } + ), + 400, + ) + if file: + response = "" + if isinstance(file, list): + for f in file: + r = submit_to_strelka( + f, user, submitted_hash, submitted_description, submitted_type + ) + if not response: + response = r + else: + response = submit_to_strelka( + file, user, submitted_hash, submitted_description, submitted_type + ) + return response + + +def submit_to_strelka( + file, user, submitted_hash, submitted_description, submitted_type +): + """ + Submit file to Strelka for analysis and save results to the database. + Args: + file: File object to be submitted. + user: User object representing the authenticated user. + submitted_hash: Hash of the submitted file. + submitted_description: Description of the submitted file. + submitted_type: Type of submission (e.g., 'api', 'virustotal'). + + Returns: + Analysis results and a 200 status code if successful. + Error message and a 415 status code if unsuccessful. + """ + total_scanned_with_hits = [] # Submit the file to the Strelka analysis engine. - if file: - try: - # Get the current timestamp and the file description from the request. - submitted_at = str(datetime.datetime.utcnow()) - - # Submit the file to Strelka and get the analysis results. - succeeded, response, file_size = submit_data( - file, - {"source": "fileshot-webui", "user_name": user.user_cn}, - submitted_hash, + try: + # Get the current timestamp and the file description from the request. + submitted_at = str(datetime.datetime.utcnow()) + + # Submit the file to Strelka and get the analysis results. + succeeded, response, file_size = submit_data( + file, + { + "user_name": user.user_cn, + "client_user_name": user.user_cn, + }, + submitted_hash, + ) + + # If the Strelka submission was not successful, return an error message. + if not succeeded: + return ( + jsonify({"error": "Failed to submit file", "details": str(response)}), + 415, ) - # If the Strelka submission was not successful, return an error message. - if not succeeded: - return ( - jsonify( - {"error": "Failed to submit file", "details": str(response)} - ), - 415, - ) + # If the Strelka submission was successful, save the analysis results to the database. + # Get the submitted file object from the analysis results. + submitted_file = response[0] + + def get_mimetype_priority(mime_list): + # Return the highest priority of the mimetypes in the list + return min(MIMETYPE_PRIORITY.get(mime, 9999) for mime in mime_list) - # If the Strelka submission was successful, save the analysis results to the database. - # Get the submitted file object from the analysis results. - submitted_file = response[0] - - # If VirusTotal API key provided, get positives (VIRUSTOTAL_API_LIMIT determined Max Scans per Request) - # -1 = VirusTotal Lookup Error - # -2 = VirusTotal API Key Not Provided - # >= 0 = Response Positives from VirusTotal - if os.environ.get("VIRUSTOTAL_API_KEY"): - total_scanned = 0 - try: - for scanned_file in response: - if total_scanned <= int(os.environ.get("VIRUSTOTAL_API_LIMIT")): - scanned_file["enrichment"] = {"virustotal": -2} - scanned_file["enrichment"][ - "virustotal" - ] = get_virustotal_positives( + # If VirusTotal API key provided, get positives (VIRUSTOTAL_API_LIMIT determined Max Scans per Request) + # -1 = VirusTotal Lookup Error + # -2 = VirusTotal API Key Not Provided + # >= 0 = Response Positives from VirusTotal + if os.environ.get("VIRUSTOTAL_API_KEY"): + total_scanned = 0 + try: + # Sort files by the priority of their mimetypes + sorted_files = sorted( + response, + key=lambda x: get_mimetype_priority(x["file"]["flavors"]["mime"]), + ) + for scanned_file in sorted_files: + if total_scanned <= int(os.environ.get("VIRUSTOTAL_API_LIMIT")): + scanned_file["enrichment"] = {"virustotal": -2} + scanned_file["enrichment"]["virustotal"] = ( + get_virustotal_positives( api_key=os.environ.get("VIRUSTOTAL_API_KEY"), file_hash=scanned_file["scan"]["hash"]["sha256"], ) - total_scanned += 1 - else: - scanned_file["enrichment"] = {"virustotal": -3} - except Exception as e: - logging.warning( - f"Could not process VirusTotal search with error: {e} " - ) - - # Get Strelka Submission IoCs - # Store a set of IoCs in IoCs field - try: - iocs = set() - for scanned_file in response: - if "iocs" in scanned_file: - for ioc in scanned_file["iocs"]: - iocs.add(ioc["ioc"]) + ) + total_scanned += 1.0 + if scanned_file["enrichment"]["virustotal"] > 0: + total_scanned_with_hits.append( + { + "file_sha256": scanned_file["scan"]["hash"][ + "sha256" + ], + "positives": scanned_file["enrichment"][ + "virustotal" + ], + } + ) else: - pass + scanned_file["enrichment"] = {"virustotal": -3} except Exception as e: - logging.warning(f"Could not process Insights search with error: {e} ") + logging.warning(f"Could not process VirusTotal search with error: {e} ") - # Get Strelka Submission Insights - # Store a set of insights in Insights field - # Store a set of insights at the file level - try: - insights = set() - for index, scanned_file in enumerate(response): - file_insights = get_insights(scanned_file) - if file_insights: - response[index]["insights"] = list(file_insights) - insights.update(file_insights) - else: - pass - except Exception as e: - logging.warning(f"Could not process Insights search with error: {e} ") - - # Create a new submission object and add it to the database. - new_submission = FileSubmission( - get_request_id(submitted_file), - file.filename, - file_size, - response, - get_mimetypes(response), - get_yara_hits(response), - len(response), - get_scanners_run(response), - get_hashes(submitted_file), - list(insights), - list(iocs), - submitted_type, - request.remote_addr, - request.headers.get("User-Agent"), - user.id, - submitted_description, - submitted_at, - get_request_time(submitted_file), - ) + # Get Strelka Submission IoCs + # Store a set of IoCs in IoCs field + try: + iocs = set() + for scanned_file in response: + if "iocs" in scanned_file: + for ioc in scanned_file["iocs"]: + iocs.add(ioc["ioc"]) + else: + pass + except Exception as e: + logging.warning(f"Could not process Insights search with error: {e} ") - db.session.add(new_submission) + # Get Strelka Submission Insights + # Store a set of insights in Insights field + # Store a set of insights at the file level + try: + insights = set() + for index, scanned_file in enumerate(response): + file_insights = get_insights(scanned_file) + if file_insights: + response[index]["insights"] = list(file_insights) + insights.update(file_insights) + else: + pass + except Exception as e: + logging.warning(f"Could not process Insights search with error: {e} ") + + # Create a new submission object and add it to the database. + new_submission = FileSubmission( + get_request_id(submitted_file), + file.filename, + file_size, + response, + get_mimetypes(response), + get_yara_hits(response), + len(response), + get_scanners_run(response), + get_hashes(submitted_file), + list(insights), + list(iocs), + submitted_type, + request.remote_addr, + request.headers.get("User-Agent"), + user.id, + submitted_description, + submitted_at, + get_request_time(submitted_file), + ) - # Increase the user's submission count. - user.files_submitted += 1 + db.session.add(new_submission) - db.session.flush() - db.session.commit() + # Increase the user's submission count. + user.files_submitted += 1 - # Return the analysis results and a 200 status code. - return jsonify(response), 200 + db.session.flush() + db.session.commit() - # If an exception occurs, log the error and return an error message. - except Exception as e: - return ( - jsonify( - { - "error": "Strelka submission was not successful.", - "details": str(e), - } - ), - 500, - ) + # Return the analysis results and a 200 status code. + return ( + jsonify( + { + "file_id": str(new_submission.file_id), + "response": response, + "meta": { + "file_size": int(file_size), + "iocs": list(iocs), + "vt_positives": list(total_scanned_with_hits), + }, + } + ), + 200, + ) + # If an exception occurs, log the error and return an error message. + except Exception as e: + return ( + jsonify( + { + "error": "Strelka submission was not successful.", + "details": str(e), + } + ), + 500, + ) def get_request_id(response: dict) -> str: @@ -498,8 +664,10 @@ def view(user: User) -> Tuple[Dict[str, any], int]: # Apply the search filter if there is a search query if search_query: search_filter = or_( - FileSubmission.file_name.like(f"%{search_query}%"), - FileSubmission.submitted_description.like(f"%{search_query}%"), + FileSubmission.file_name.ilike(f"%{search_query}%"), + FileSubmission.submitted_description.ilike(f"%{search_query}%"), + cast(FileSubmission.yara_hits, String).ilike(f"%{search_query}%"), + User.user_cn.ilike(f"%{search_query}%"), ) base_query = base_query.filter(search_filter) @@ -622,6 +790,51 @@ def get_mime_type_stats(user: User) -> Tuple[Response, int]: return jsonify(stats), 200 +@strelka.route("/virustotal/widget-url", methods=["POST"]) +@auth_required +def get_vt_widget_url(resource: str) -> Tuple[Response, int]: + """ + Route to get a VirusTotal widget url with customized theme colors. + + Returns: + A JSON response containing the VirusTotal widget url or an error message. + """ + data = request.get_json() + if not data or "resource" not in data: + return jsonify({"error": "Resource identifier is required"}), 400 + + # Strelka UI Defaults + fg1 = data.get("fg1", "333333") # Dark text color + bg1 = data.get("bg1", "FFFFFF") # Light background color + bg2 = data.get("bg2", "F5F5F5") # Slightly grey background for differentiation + bd1 = data.get("bd1", "E8E8E8") # Light grey border color + + api_key = os.getenv("VIRUSTOTAL_API_KEY") + if not api_key: + return jsonify({"error": "VirusTotal API key is not available."}), 500 + + try: + # Pass the theme colors to the function + widget_url = get_virustotal_widget_url( + api_key, data["resource"], fg1, bg1, bg2, bd1 + ) + return jsonify({"widget_url": widget_url}), 200 + except Exception as e: + return jsonify({"error": str(e)}), 500 + + +@strelka.route("/check_vt_api_key", methods=["GET"]) +def check_vt_api_key(): + """ + Endpoint to check if the VirusTotal API key is available. + + Returns: + A boolean response containing the VirusTotal widget url or an error message. + """ + api_key_exists = bool(os.environ.get("VIRUSTOTAL_API_KEY")) + return jsonify({"apiKeyAvailable": api_key_exists}), 200 + + def submissions_to_json(submission: FileSubmission) -> Dict[str, any]: """ Converts the given submission to a dictionary representation that can be diff --git a/app/blueprints/ui.py b/app/strelka_ui/blueprints/ui.py similarity index 94% rename from app/blueprints/ui.py rename to app/strelka_ui/blueprints/ui.py index 34d4000..5fedb02 100644 --- a/app/blueprints/ui.py +++ b/app/strelka_ui/blueprints/ui.py @@ -24,6 +24,8 @@ def serve(path: str) -> Any: """ static_folder: str = current_app.static_folder + print(os.path.join(static_folder, path)) + if path and os.path.exists(os.path.join(static_folder, path)): return send_from_directory(static_folder, path) else: diff --git a/app/config/config.py b/app/strelka_ui/config/config.py similarity index 97% rename from app/config/config.py rename to app/strelka_ui/config/config.py index f241193..c8827d2 100644 --- a/app/config/config.py +++ b/app/strelka_ui/config/config.py @@ -61,7 +61,6 @@ class Config(object): # Formatted for ease of use with flask-sqlalchemy SQLALCHEMY_DATABASE_URI = f"postgresql://{DATABASE_USERNAME}:{DATABASE_PASSWORD}@{DATABASE_HOST}:{DATABASE_PORT}/{DATABASE_DBNAME}" - logging.info(f"connecting to database with {SQLALCHEMY_DATABASE_URI}") class ProductionConfig(Config): diff --git a/app/database.py b/app/strelka_ui/database.py similarity index 100% rename from app/database.py rename to app/strelka_ui/database.py diff --git a/app/example.env b/app/strelka_ui/example.env similarity index 88% rename from app/example.env rename to app/strelka_ui/example.env index c1cbf3e..16d3f27 100644 --- a/app/example.env +++ b/app/strelka_ui/example.env @@ -1,6 +1,6 @@ # Strelka connection information (OPTIONAL / HAS DEFAULTS). -export STRELKA_HOST=strelka_frontend_1 -export STRELKA_PORT=57314 +export STRELKA_HOST= +export STRELKA_PORT= export STRELKA_CERT= # Fully qualified postgres db url (with protocol, user, pass, host and db) (OPTIONAL / HAS DEFAULTS). @@ -28,4 +28,4 @@ export VIRUSTOTAL_API_KEY= export VIRUSTOTAL_API_LIMIT= # Default Submission Exclusions -export DEFAULT_EXCLUDED_SUBMITTERS=["ExcludeUser"] \ No newline at end of file +export DEFAULT_EXCLUDED_SUBMITTERS=["ExcludeUser"] diff --git a/app/models.py b/app/strelka_ui/models.py similarity index 99% rename from app/models.py rename to app/strelka_ui/models.py index e593673..b2a07da 100644 --- a/app/models.py +++ b/app/strelka_ui/models.py @@ -4,7 +4,7 @@ from sqlalchemy.orm import relationship from sqlalchemy.sql import func -from database import db +from strelka_ui.database import db class FileSubmission(db.Model): diff --git a/app/services/auth.py b/app/strelka_ui/services/auth.py similarity index 99% rename from app/services/auth.py rename to app/strelka_ui/services/auth.py index 9e36754..6320f01 100644 --- a/app/services/auth.py +++ b/app/strelka_ui/services/auth.py @@ -4,7 +4,7 @@ from flask import current_app, request, session import ldap3 -from models import ApiKey, User +from strelka_ui.models import ApiKey, User # Define constants or configuration values diff --git a/app/strelka_ui/services/files.py b/app/strelka_ui/services/files.py new file mode 100644 index 0000000..64f0c67 --- /dev/null +++ b/app/strelka_ui/services/files.py @@ -0,0 +1,155 @@ +import os +import tempfile +import zipfile +import rarfile +import py7zr +import mimetypes +import magic + +from io import BytesIO +from werkzeug.datastructures import FileStorage +from typing import Tuple, List, Union + + +def decrypt_file( + file_storage: FileStorage, password: str +) -> Tuple[bool, Union[str, List[FileStorage]]]: + """ + Attempts to decrypt and unpack a file from an encrypted archive using the provided password. + This function supports zip, rar, and 7z formats. + + Args: + file_storage (FileStorage): The uploaded file storage from Flask. + password (str): The password to attempt decryption with. + + Returns: + Tuple[bool, Union[str, List[FileStorage]]]: A tuple containing a boolean indicating success, + and either a list of FileStorage objects for each extracted file or an error message string. + """ + try: + # Save the uploaded file to a temporary file to handle it with different archive handlers + temp_file = tempfile.NamedTemporaryFile(delete=False) + file_storage.save(temp_file.name) + temp_file.close() + + # Use the python-magic library to identify the MIME type of the file + magic_obj = magic.Magic(mime=True) + mime_type = magic_obj.from_file(temp_file.name) + + # Handling different archive types using appropriate libraries + if mime_type == "application/zip": + with zipfile.ZipFile(temp_file.name, "r") as zfile: + zfile.extractall( + path=os.path.dirname(temp_file.name), pwd=password.encode() + ) + extracted_files = [ + os.path.join(os.path.dirname(temp_file.name), name) + for name in zfile.namelist() + ] + + elif mime_type in [ + "application/x-rar", + "application/vnd.rar", + "application/x-rar-compressed", + ]: + with rarfile.RarFile(temp_file.name, "r") as rfile: + rfile.extractall(path=os.path.dirname(temp_file.name), pwd=password) + extracted_files = [ + os.path.join(os.path.dirname(temp_file.name), name) + for name in rfile.namelist() + ] + + elif mime_type == "application/x-7z-compressed": + with py7zr.SevenZipFile( + temp_file.name, mode="r", password=password + ) as zfile: + zfile.extractall(path=os.path.dirname(temp_file.name)) + extracted_files = [ + os.path.join(os.path.dirname(temp_file.name), name) + for name in zfile.getnames() + ] + + # Unsupported filetype + else: + return ( + False, + f"Failed to extract files: file type {mime_type} is not supported for password extraction.", + ) + + # Prepare the extracted files as FileStorage objects for further processing + return True, [prepare_decrypted_file(path) for path in extracted_files] + + except Exception as e: + # Return a detailed error message if extraction fails + return False, f"Failed to extract files: {str(e)}" + finally: + # Ensure that the temporary file is deleted after processing + os.unlink(temp_file.name) + + +def prepare_decrypted_file(extracted_file_path: str) -> FileStorage: + """ + Prepare a FileStorage object from an extracted file path. + + Args: + extracted_file_path: Path to the extracted file. + + Returns: + A FileStorage object. + """ + with open(extracted_file_path, "rb") as file: + buffer = BytesIO(file.read()) + mime_type, _ = mimetypes.guess_type(extracted_file_path) + return FileStorage( + stream=buffer, + filename=os.path.basename(extracted_file_path), + content_type=mime_type, + ) + + +def check_file_size(file_storage, max_size=150 * 1024 * 1024) -> Tuple[bool, int]: + """ + Check if the file size exceeds the maximum allowed size. + + Args: + file_storage: FileStorage object. + max_size: Maximum file size in bytes. + + Returns: + A tuple (is_valid, size) where is_valid is a boolean indicating if the file size is within the limit, + and size is the size of the file. + """ + # Move the cursor to the end of the file + file_storage.seek(0, os.SEEK_END) + + # Get the position of the cursor, which is the size of the file + file_size = file_storage.tell() + + # Rewind the cursor back to the start of the file for future operations + file_storage.seek(0) + + return file_size <= max_size, file_size + + +def convert_bytesio_to_filestorage(file_bytes: BytesIO, filename: str) -> FileStorage: + """ + Converts a BytesIO object into a FileStorage object to mimic file upload in Flask. + + Args: + file_bytes (BytesIO): The byte stream of the file. + filename (str): The name of the file, used to help identify the content type. + + Returns: + FileStorage: A FileStorage object with the content of the byte stream. + """ + # Guess the MIME type of the file based on the filename + content_type, _ = mimetypes.guess_type(filename) + + # Create a FileStorage object + file_storage = FileStorage( + stream=file_bytes, + filename=filename, + content_type=content_type or "application/octet-stream", + ) + + return file_storage diff --git a/app/services/insights.py b/app/strelka_ui/services/insights.py similarity index 100% rename from app/services/insights.py rename to app/strelka_ui/services/insights.py diff --git a/app/services/strelka.py b/app/strelka_ui/services/strelka.py similarity index 98% rename from app/services/strelka.py rename to app/strelka_ui/services/strelka.py index 5d1f509..39abde8 100644 --- a/app/services/strelka.py +++ b/app/strelka_ui/services/strelka.py @@ -5,7 +5,7 @@ from flask import current_app -from strelka.submit_to_strelka import submit_file_to_strelka +from strelka_ui.strelka.submit_to_strelka import submit_file_to_strelka def get_frontend_status() -> bool: diff --git a/app/strelka_ui/services/virustotal.py b/app/strelka_ui/services/virustotal.py new file mode 100644 index 0000000..a0fe5c6 --- /dev/null +++ b/app/strelka_ui/services/virustotal.py @@ -0,0 +1,167 @@ +import logging +from io import BytesIO +import os +import requests +import time + + +def get_virustotal_positives(api_key: str, file_hash: str) -> int: + """ + Retrieves the count of malicious detections for a specific file from VirusTotal using the requests library. + + Args: + api_key (str): The API key used to authenticate with the VirusTotal API. + file_hash (str): The hash of the file (MD5, SHA1, or SHA256) to query for detections. + + Returns: + int: The number of malicious detections found for the file. Returns -1 if an error occurs. + """ + url = f"https://www.virustotal.com/api/v3/files/{file_hash}" + headers = {"x-apikey": api_key} + + try: + response = requests.get(url, headers=headers) + if response.ok: + file_analysis = response.json() + logging.info(f"VirusTotal response: {str(response.json().get('data').get('id'))}") + return ( + file_analysis.get("data", {}) + .get("attributes", {}) + .get("last_analysis_stats", {}) + .get("malicious", 0) + ) + else: + if response.status_code == 404: + logging.info(f"Not found querying VirusTotal: {' '.join(response.text.split(os.linesep))}") + else: + logging.error(f"Error querying VirusTotal: {' '.join(response.text.split(os.linesep))}") + + return -1 + except Exception as e: + logging.error(f"Exception querying VirusTotal: {e}") + return -1 + + +def create_vt_zip_and_download(api_key, file_hash, password, max_attempts=3): + """ + Creates a password-protected ZIP file containing the specified file from VirusTotal, + then downloads and returns it. + + Args: + api_key (str): The API key for VirusTotal. + file_hash (list): The hash of the file to download. + password (str): The password to set for the ZIP file. + max_attempts (int): The maximum number of attempts to check for ZIP readiness. + + Returns: + BytesIO: A buffer containing the downloaded ZIP file. + + Raises: + Exception: If any step in the process fails. + """ + create_zip_url = "https://www.virustotal.com/api/v3/intelligence/zip_files" + payload = { + "data": {"password": password, "hashes": file_hash} + } # Assuming file_hash should be a list + headers = { + "x-apikey": api_key, + "accept": "application/json", + "content-type": "application/json", + } + response = requests.post(create_zip_url, json=payload, headers=headers) + + if not response.ok: + raise Exception(f"Error creating ZIP: {response.text}") + + zip_id = response.json()["data"]["id"] + + check_zip_url = f"https://www.virustotal.com/api/v3/intelligence/zip_files/{zip_id}" + attempts = 0 + while attempts < max_attempts: + response = requests.get(check_zip_url, headers=headers) + if not response.ok: + raise Exception(f"Error checking ZIP status: {response.text}") + + if response.json()["data"]["attributes"]["status"] == "finished": + break + + time.sleep(10) + attempts += 1 + + if attempts == max_attempts: + raise Exception("Maximum polling attempts reached, ZIP file may not be ready.") + + get_download_url = f"{check_zip_url}/download_url" + response = requests.get(get_download_url, headers=headers) + + if not response.ok: + raise Exception(f"Error getting download URL: {response.text}") + + download_url = response.json()["data"] + + response = requests.get(download_url, headers={"x-apikey": api_key}) + if not response.ok: + raise Exception(f"Error downloading ZIP: {response.text}") + + return BytesIO(response.content) + + +def download_vt_bytes(api_key: str, file_hash: str) -> BytesIO: + """ + Downloads a file from VirusTotal and returns it as a byte stream using the requests library. + + Args: + api_key (str): The API key for accessing VirusTotal. + file_hash (str): The hash of the file to be downloaded. + + Returns: + BytesIO: A buffer containing the downloaded file. + + Raises: + Exception: If the download fails. + """ + download_url = f"https://www.virustotal.com/api/v3/files/{file_hash}/download" + headers = {"x-apikey": api_key} + + response = requests.get(download_url, headers=headers, stream=True) + + if response.ok: + file_buffer = BytesIO(response.content) + return file_buffer + else: + error_msg = f"Error downloading file from VirusTotal: {response.text}" + logging.error(error_msg) + raise Exception(error_msg) + + +def get_virustotal_widget_url( + api_key: str, resource: str, fg1: str, bg1: str, bg2: str, bd1: str +) -> str: + """ + Retrieves a URL for embedding the VirusTotal widget with customized theme colors. + + Args: + api_key (str): The API key for accessing VirusTotal. + resource (str): The resource identifier (file hash, URL, IP, or domain). + fg1 (str): Theme primary foreground color in hex notation. + bg1 (str): Theme primary background color in hex notation. + bg2 (str): Theme secondary background color in hex notation. + bd1 (str): Theme border color. + + Returns: + str: A URL for embedding the VirusTotal widget with the specified theme. + """ + url = f"https://www.virustotal.com/api/v3/widget/url?query={resource}&fg1={fg1}&bg1={bg1}&bg2={bg2}&bd1={bd1}" + headers = {"x-apikey": api_key} + + try: + response = requests.get(url, headers=headers) + response.raise_for_status() + widget_data = response.json() + return widget_data.get("data", {}).get("url", "") + except requests.HTTPError as http_err: + logging.error(f"HTTP error occurred: {http_err}") + raise + except Exception as err: + logging.error(f"An error occurred: {err}") + raise diff --git a/app/strelka/fileshot_config.txt b/app/strelka_ui/strelka/fileshot_config.txt similarity index 100% rename from app/strelka/fileshot_config.txt rename to app/strelka_ui/strelka/fileshot_config.txt diff --git a/app/strelka/strelka_pb2.py b/app/strelka_ui/strelka/strelka_pb2.py similarity index 100% rename from app/strelka/strelka_pb2.py rename to app/strelka_ui/strelka/strelka_pb2.py diff --git a/app/strelka/strelka_pb2_grpc.py b/app/strelka_ui/strelka/strelka_pb2_grpc.py similarity index 96% rename from app/strelka/strelka_pb2_grpc.py rename to app/strelka_ui/strelka/strelka_pb2_grpc.py index 8735dfc..219b524 100644 --- a/app/strelka/strelka_pb2_grpc.py +++ b/app/strelka_ui/strelka/strelka_pb2_grpc.py @@ -1,7 +1,7 @@ # Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT! import grpc -from strelka.strelka_pb2 import * +from strelka_ui.strelka.strelka_pb2 import * class FrontendStub(object): diff --git a/app/strelka/submit_to_strelka.py b/app/strelka_ui/strelka/submit_to_strelka.py similarity index 84% rename from app/strelka/submit_to_strelka.py rename to app/strelka_ui/strelka/submit_to_strelka.py index 088b256..c3a2bd2 100644 --- a/app/strelka/submit_to_strelka.py +++ b/app/strelka_ui/strelka/submit_to_strelka.py @@ -1,12 +1,14 @@ +from importlib.metadata import version import json import os +import socket from typing import Dict, List, Union import grpc from flask import current_app -import strelka.strelka_pb2 as strelka_pb2 -import strelka.strelka_pb2_grpc as strelka_pb2_grpc +import strelka_ui.strelka.strelka_pb2 as strelka_pb2 +import strelka_ui.strelka.strelka_pb2_grpc as strelka_pb2_grpc def yield_file( @@ -24,6 +26,18 @@ def yield_file( Yields: strelka_pb2.ScanFileRequest: A ScanFileRequest object for each chunk of file data. """ + + metadata.update({ + "client_name": "fileshot-webui", + "client_hostname": socket.gethostname(), + "client_version": version("strelka-ui"), + }) + + if os.environ.get("ENV"): + metadata.update({ + "client_environment": os.environ.get("ENV"), + }) + for c in range(0, len(data), chunk): yield strelka_pb2.ScanFileRequest( data=data[c : c + chunk], diff --git a/entrypoint.sh b/entrypoint.sh index fef173c..e354aae 100644 --- a/entrypoint.sh +++ b/entrypoint.sh @@ -1,6 +1,7 @@ #!/bin/sh -export FLASK_APP=/app/app.py +cd /app/strelka_ui || exit +export FLASK_APP=strelka_ui.__main__:create_app flask db init flask db migrate flask db upgrade -python app.py +poetry run python -m strelka_ui diff --git a/misc/examples/api_examples.py b/misc/examples/api_examples.py index 14ee48e..0277419 100644 --- a/misc/examples/api_examples.py +++ b/misc/examples/api_examples.py @@ -1,10 +1,11 @@ -from typing import Optional - +import json import requests +from typing import Optional +from os import getenv -# Set API key and base URL -api_key = "" -url_base = "http://0.0.0.0:8080/api/strelka" +# Environment variables for configuration +api_base = getenv("STRELKA_API_BASE", "http://localhost:8080/api/strelka") +api_key = getenv("STRELKA_API_KEY", "") # Define headers headers = { @@ -14,82 +15,53 @@ } -def get_scans_list(page: int = 1, per_page: int = 10) -> Optional[str]: - """ - Get list of scans from the Strelka UI API. - - Args: - page (int): The page number to retrieve. Defaults to 1. - per_page (int): The number of items per page. Defaults to 10. - - Returns: - Optional[str]: The list of scans as a JSON string if the request is successful, None otherwise. - """ - url_route = f"/scans?page={page}&per_page={per_page}" +# Helper function to handle requests +def make_request(method: str, url: str, **kwargs) -> Optional[str]: try: - response = requests.get(url_base + url_route, headers=headers) + response = requests.request(method, url, headers=headers, **kwargs) response.raise_for_status() return response.text + except requests.exceptions.HTTPError as e: + print(f"HTTP Error: {e.response.status_code} for {url}: {e.response.text}") except requests.exceptions.RequestException as e: - print(f"Error: {e}") - return None + print(f"Request Error: {e}") + return None -def get_scan_by_id(scan_id: str) -> Optional[str]: - """ - Get scan details by ID from the Strelka UI API. +# Endpoints +def get_scans_list(page: int = 1, per_page: int = 10) -> Optional[str]: + return make_request("GET", f"{api_base}/scans?page={page}&per_page={per_page}") - Args: - scan_id (str): The ID of the scan to retrieve. - Returns: - Optional[str]: The scan details as a JSON string if the request is successful, None otherwise. - """ - url_route = f"/scans/{scan_id}" - try: - response = requests.get(url_base + url_route, headers=headers) - response.raise_for_status() - return response.text - except requests.exceptions.RequestException as e: - print(f"Error: {e}") - return None +def get_scan_by_id(scan_id: str) -> Optional[str]: + return make_request("GET", f"{api_base}/scans/{scan_id}") def upload_file(filename: str, description: str) -> Optional[str]: - """ - Upload a file to the Strelka UI API. + with open(filename, "rb") as f: + files = {"file": (filename, f)} + data = {"description": description, "password": ""} + return make_request("POST", f"{api_base}/upload", files=files, data=data) - Args: - filename (str): The file path of the file to upload. - description (str): The description of the file. - Returns: - Optional[str]: The response as a JSON string if the upload is successful, None otherwise. +def upload_file_to_vt(file_hash: str, description: str) -> Optional[str]: """ - url_route = "/upload" - upload_headers = { - "X-API-KEY": api_key, + Sample Response: + {"file_id":"07538964-b156-4ed3-93b4-85bcd07b5fbc", + "results":[{"enrichment":{"virustotal":-1},"file":{"depth":0,"flavors":{"mime":["application/zip"],"yara":["encrypted_zip","zip_file"]}... } - - try: - with open(filename, "rb") as f: - file_data = f.read() - - files = [("file", (filename, file_data))] - data = {"description": description} - - response = requests.post( - url_base + url_route, files=files, data=data, headers=upload_headers - ) - response.raise_for_status() - return response.text - except requests.exceptions.RequestException as e: - print(f"Error: {e}") - return None + """ + payload = json.dumps({"description": description, "hash": file_hash}) + return make_request("POST", f"{api_base}/upload", data=payload) if __name__ == "__main__": # Example usage - print(get_scans_list()) - print(get_scan_by_id("")) - print(upload_file("", "This is a test file")) + # print(get_scans_list()) + # print(get_scan_by_id("")) + # print(upload_file("", "This is a test file")) + print( + upload_file_to_vt( + "5da8c98136d98dfec4716edd79c7145f", "VirusTotal Upload - Calc.exe" + ) + ) diff --git a/ui/package.json b/ui/package.json index fe56e27..c3476ac 100644 --- a/ui/package.json +++ b/ui/package.json @@ -4,19 +4,21 @@ "private": true, "homepage": "/", "dependencies": { - "@ant-design/pro-form": "^2.23.1", - "@ant-design/pro-layout": "^7.17.16", + "@ant-design/pro-form": "^2.25.1", + "@ant-design/pro-layout": "^7.19.0", "@testing-library/jest-dom": "^5.16.4", "@testing-library/react": "^11.1.0", "@testing-library/user-event": "^13.5.0", + "@ant-design/icons": "^5.3.6", "ansi-regex": "^6.0.1", - "antd": "^5.3.0", + "antd": "^5.16.1", "browserslist": "^4.20.4", "chroma-js": "^2.4.2", "css-what": "^5.1.0", "dagre": "^0.8.5", "dns-packet": "^5.4.0", "ejs": "^3.1.8", + "follow-redirects": "1.15.6", "glob-parent": "^6.0.2", "html-to-image": "^1.11.11", "loader-utils": "^2.0.4", @@ -32,7 +34,7 @@ "recharts": "^2.10.3", "styled-components": "^6.1.1", "web-vitals": "^1.0.1", - "ws": "^8.8.0" + "ws": "^8.17.1" }, "devDependencies": { "react-scripts": "^5.0.1" diff --git a/ui/src/App.css b/ui/src/App.css index a037310..b8d35e8 100644 --- a/ui/src/App.css +++ b/ui/src/App.css @@ -11,6 +11,11 @@ body { text-align: center; } +html, body { + overflow-y: auto !important; + width: 100% !important; +} + /* Header Styles */ .App-header { background-color: #f5f5f5; @@ -79,9 +84,9 @@ body { .ant-card, .submission-card-height, .ant-collapse-item { - border-radius: 20px; - box-shadow: 0px 4px 6px -1px rgba(0, 0, 0, 0.1), - 0px 2px 4px -1px rgba(0, 0, 0, 0.06); + border-radius: 0px; + box-shadow: -1px 4px 6px -1px rgba(0, 0, 0, 0.1), + -1px -2px 4px -1px rgba(0, 0, 0, 0.06); } /* Collapse Styles */ @@ -92,10 +97,10 @@ body { .ant-collapse > .ant-collapse-item > .ant-collapse-content > .ant-collapse-content-box, .ant-collapse-content, .ant-collapse-content-box { - border-radius: 20px !important; + border-radius: 0px !important; background-color: #ffffff; border: 0; - padding-top: 5px; + padding-bottom: 5px; } diff --git a/ui/src/components/Dropzone.js b/ui/src/components/Dropzone.js index fc31036..1f8a5ab 100644 --- a/ui/src/components/Dropzone.js +++ b/ui/src/components/Dropzone.js @@ -14,7 +14,10 @@ const Dropzone = (props) => {

Click or drag file to this area to upload

-

Support for a single or bulk upload.

+

Support for a single or bulk upload.

+

File size limited to 150MB.

+

Password encrypted samples support ZIP, RAR, and 7z.

+ ); }; diff --git a/ui/src/components/FileComponents/OcrOverviewCard.js b/ui/src/components/FileComponents/OcrOverviewCard.js deleted file mode 100644 index 2dd74d9..0000000 --- a/ui/src/components/FileComponents/OcrOverviewCard.js +++ /dev/null @@ -1,120 +0,0 @@ -import React, { useState } from "react"; -import { Checkbox, Input, Row, Col, Modal } from "antd"; -import "../../styles/OcrOverviewCard.css"; - -const OcrOverviewCard = ({ data }) => { - const [isModalVisible, setIsModalVisible] = useState(false); - const [wrapText, setWrapText] = useState(false); - const [trimText, setTrimText] = useState(true); - const [filter, setFilter] = useState(""); - - const showModal = () => setIsModalVisible(true); - const handleCancel = () => setIsModalVisible(false); - - let texts = Array.isArray(data.scan.ocr?.text) - ? data.scan.ocr.text - : [data.scan.ocr?.text || ""]; - const base64Thumbnail = data.scan.ocr?.base64_thumbnail; - - // Function to trim trailing whitespace or empty lines from a single line of text - const trimLine = (line) => (trimText ? line.replace(/\s+$/, "") : line); - - // Function to trim all text content if it's not already an array - texts = texts.map(trimLine); - - // Placeholder for Thumbnail in case its disabled / not functioning - const ThumbnailPlaceholder = () => { - return
; - }; - - // Function to create line numbers and corresponding text - const renderTextLines = (texts) => { - let lineNumber = 1; // Initialize line number - return texts.flatMap((textContent) => { - // Split each text block by new lines and filter based on the user's input - const lines = textContent - .split(/\r?\n/) - .filter((line) => !filter || line.includes(filter)); - // Map over each line and return a table row while incrementing the line number - return lines.map((line) => ( - - {lineNumber++} - - {line} - - - )); - }); - }; - - return ( -
- - - setFilter(e.target.value)} - style={{ width: "100%" }} - /> - - - setWrapText(e.target.checked)} - > - Wrap - - setTrimText(e.target.checked)} - > - Trim - - - - - - - {renderTextLines(texts)} -
- - - {base64Thumbnail ? ( - <> - Email Preview - - Email Preview (Expanded) - - - ) : ( - - )} - -
-
- ); -}; - -export default OcrOverviewCard; diff --git a/ui/src/components/FileComponents/VirusTotalUploader.js b/ui/src/components/FileComponents/VirusTotalUploader.js deleted file mode 100644 index 5e0d1b8..0000000 --- a/ui/src/components/FileComponents/VirusTotalUploader.js +++ /dev/null @@ -1,79 +0,0 @@ -import React, { useState } from "react"; -import { Input, Button, message, Typography } from "antd"; -import { MessageOutlined } from "@ant-design/icons"; -import { APP_CONFIG } from "../../config"; -import { fetchWithTimeout } from "../../util"; - -const { Text } = Typography; - -const VirusTotalUploader = ({ onUploadSuccess }) => { - const [fileDescription, setFileDescription] = useState("No Description Provided"); - const [vtHash, setVtHash] = useState(""); - const [loading, setLoading] = useState(false); // State to manage button loading - - const handleVtHashChange = (e) => setVtHash(e.target.value); - const handleDescriptionChange = (e) => setFileDescription(e.target.value); - - const handleSubmitVtHash = () => { - setLoading(true); // Start loading when submission starts - const payload = { description: fileDescription, hash: vtHash }; - - fetchWithTimeout(`${APP_CONFIG.BACKEND_URL}/strelka/upload`, { - method: "POST", - headers: { "Content-Type": "application/json" }, - body: JSON.stringify(payload), - mode: "cors", - credentials: "include", - timeout: APP_CONFIG.API_TIMEOUT, - }) - .then((response) => { - if (!response.ok) { - return response.json().then((errorData) => { - throw new Error(errorData.details || 'Error occurred while submitting hash'); - }); - } - return response.json(); - }) - .then((data) => { - onUploadSuccess(); // Trigger table refresh - setVtHash(""); // Reset hash input - message.success(`${vtHash} analyzed successfully via VirusTotal!`); - setLoading(false); // Stop loading - }) - .catch((error) => { - message.error(`Error submitting hash: ${error.message}`); - setLoading(false); // Stop loading - }); - }; - - return ( -
-
- } - /> -
-
- -
-
- -
-
- ); -}; - -export default VirusTotalUploader; diff --git a/ui/src/components/FileFlow/EdgeTypes/IndexConnectEdge.js b/ui/src/components/FileFlow/EdgeTypes/IndexConnectEdge.js index dbe7aac..ca2b2d6 100644 --- a/ui/src/components/FileFlow/EdgeTypes/IndexConnectEdge.js +++ b/ui/src/components/FileFlow/EdgeTypes/IndexConnectEdge.js @@ -1,10 +1,21 @@ import React from "react"; -import { - BaseEdge, - EdgeLabelRenderer, - getBezierPath, -} from "reactflow"; +import { BaseEdge, EdgeLabelRenderer, getBezierPath } from "reactflow"; +import styled from "styled-components"; +import { antdColors } from "../../../utils/colors"; +const EdgeLabel = styled.div` + position: absolute; + transform: translate(-50%, -50%); + font-size: 11px; + font-weight: ${(props) => (props.$markerColor !== antdColors.lightGray ? "700" : "500")}; + line-height: 12px; + color: ${(props) => props.$markerColor}; + background: white; + padding: 2px 4px; + border-radius: 3px; + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3); + pointer-events: all; +`; export default function CustomEdge({ id, @@ -15,8 +26,8 @@ export default function CustomEdge({ sourcePosition, targetPosition, style = {}, - markerEnd, label, + isHighlighted, }) { const [edgePath, labelX, labelY] = getBezierPath({ sourceX, @@ -27,21 +38,49 @@ export default function CustomEdge({ targetPosition, }); + // Move label closer to the target node + const labelOffsetX = (targetX - sourceX) * 0.3; + const labelOffsetY = (targetY - sourceY) * 0.3; + + const markerColor = isHighlighted ? antdColors.darkGray : style.stroke; return ( <> - + -
-
+ {label} +
+ + + + + + + ); } diff --git a/ui/src/components/FileComponents/FileTreeCard.js b/ui/src/components/FileFlow/FileTreeCard.js similarity index 69% rename from ui/src/components/FileComponents/FileTreeCard.js rename to ui/src/components/FileFlow/FileTreeCard.js index cd09e18..491ec10 100644 --- a/ui/src/components/FileComponents/FileTreeCard.js +++ b/ui/src/components/FileFlow/FileTreeCard.js @@ -1,6 +1,3 @@ -// ------------------------- -// Imports -// ------------------------- import { useCallback, useEffect, useMemo, useState, useRef } from "react"; import ReactFlow, { Background, @@ -13,25 +10,22 @@ import ReactFlow, { MiniMap, useReactFlow, } from "reactflow"; -import EventNode from "../FileFlow/NodeTypes/EventNode.js"; -import IndexConnectEdge from "../FileFlow/EdgeTypes/IndexConnectEdge.js"; +import EventNode from "./NodeTypes/EventNode.js"; +import IndexConnectEdge from "./EdgeTypes/IndexConnectEdge.js"; import { initialNodes, initialEdges } from "../../data/initialData.js"; import "reactflow/dist/style.css"; import { getDagreLayout } from "../../utils/dagreLayout.js"; -import DownloadImage from "../../utils/downloadImage"; -import ShowFileListing from "../../utils/ShowFileListing"; -import NodeSearchPanel from "../../utils/NodeSearchPanel"; -import ClickGuide from "../../utils/ClickGuide"; +import DownloadImage from "../../utils/downloadImage.js"; +import ShowFileListing from "../../utils/ShowFileListing.js"; +import NodeSearchPanel from "../../utils/NodeSearchPanel.js"; +import ClickGuide from "../../utils/ClickGuide.js"; import ExceededGuide from "../../utils/ExceededGuide.js"; - import { toggleChildrenVisibility, transformElasticSearchDataToElements, } from "../../utils/layoutUtils.js"; +import { antdColors } from "../../utils/colors"; -// ------------------------- -// Node & Edge Definitions -// ------------------------- const nodeTypes = { event: EventNode, }; @@ -39,24 +33,20 @@ const nodeTypes = { const edgeTypes = { indexedge: IndexConnectEdge, }; + const snapGrid = [16, 16]; -// ------------------------- -// Main Component -// ------------------------- const FileTreeCard = ({ data, alertId, onNodeSelect, fileTypeFilter, fileYaraFilter, + fileIocFilter, fileNameFilter, selectedNodeData, setSelectedNodeData, }) => { - // ------------------------- - // State Definitions - // ------------------------- const [searchTerm, setSearchTerm] = useState(""); const { fitView } = useReactFlow(); @@ -72,11 +62,9 @@ const FileTreeCard = ({ const [showExceededGuide, setShowExceededGuide] = useState(false); const ref = useRef(null); - // ------------------------- - // Callbacks - // ------------------------- + const [highlightedEdge, setHighlightedEdge] = useState(null); + const [highlightedNode, setHighlightedNode] = useState(null); - // Handler for updating showVtExceededGuide based on data useEffect(() => { const vtExceeded = data.some((item) => { return item?.enrichment?.virustotal === -3; @@ -84,12 +72,10 @@ const FileTreeCard = ({ setShowExceededGuide(vtExceeded); }, [data]); - // Handler to use the setSearchTerm / search filter const onSearchChange = (search) => { setSearchTerm(search); }; - // Handler to update nodes when they change. const onNodesChange = useCallback( (changes) => { setNodes((currentNodes) => applyNodeChanges(changes, currentNodes)); @@ -97,7 +83,6 @@ const FileTreeCard = ({ [setNodes] ); - // Handler to update edges when they change. const onEdgesChange = useCallback( (changes) => { setEdges((currentEdges) => applyEdgeChanges(changes, currentEdges)); @@ -106,26 +91,27 @@ const FileTreeCard = ({ ); const filteredNodes = useMemo(() => { - // Start with all nodes or nodes that match the file type filter let nodesToFilter = fileTypeFilter ? nodes.filter((node) => node.data.nodeMain.includes(fileTypeFilter)) : nodes; - // Apply the file name filter if it's set if (fileNameFilter) { nodesToFilter = nodesToFilter.filter((node) => node.data.nodeRelationshipId?.includes(fileNameFilter) ); } - - // Apply the yara filter if it's set if (fileYaraFilter) { nodesToFilter = nodesToFilter.filter((node) => node.data.nodeYaraList?.includes(fileYaraFilter) ); } - // If the search term is not empty, further filter the nodes + if (fileIocFilter) { + nodesToFilter = nodesToFilter.filter((node) => + node.data.nodeIocList?.includes(fileIocFilter) + ); + } + if (searchTerm.trim()) { nodesToFilter = nodesToFilter.filter( (node) => @@ -134,28 +120,29 @@ const FileTreeCard = ({ ); } return nodesToFilter; - }, [nodes, searchTerm, fileTypeFilter, fileYaraFilter, fileNameFilter]); + }, [ + nodes, + searchTerm, + fileTypeFilter, + fileIocFilter, + fileYaraFilter, + fileNameFilter, + ]); - // Reset View when filters are applied useEffect(() => { fitView({ padding: 0.2 }); }, [fileTypeFilter, fileYaraFilter, fileNameFilter, fitView]); - // Handler for when a node is clicked. const handleNodeClick = (event, node) => { if (node.type === "index") { - // Gather all nodes of type 'index'. This type I'm using as a "root" node for now. const rootNodeIds = nodes .filter((n) => n.type === "index") .map((n) => n.id); - // Gather all edges related to the clicked node. const relatedEdges = edges.filter((edge) => edge.source === node.id); - // Identify the nodes connected to the clicked node through the edges. const relatedNodes = relatedEdges.map((edge) => edge.target); - // Determine if the first related node is hidden. const firstRelatedNode = nodes.find((n) => n.id === relatedNodes[0]); const shouldBeHidden = firstRelatedNode && !firstRelatedNode.hidden; @@ -163,7 +150,6 @@ const FileTreeCard = ({ let updatedEdges = [...edges]; const rootNodeIdsSet = new Set(rootNodeIds); - // Update visibility of the edges connected to the clicked node. updatedEdges = updatedEdges.map((edge) => { if (edge.source === node.id && !rootNodeIdsSet.has(edge.target)) { return { ...edge, hidden: shouldBeHidden }; @@ -171,7 +157,6 @@ const FileTreeCard = ({ return edge; }); - // Update visibility for nodes related to the clicked node. relatedNodes.forEach((relatedNodeId) => { const result = toggleChildrenVisibility( relatedNodeId, @@ -187,57 +172,84 @@ const FileTreeCard = ({ setNodes(updatedNodes); setEdges(updatedEdges); } else { - // If node type is not 'index', display node data in a modal. setSelectedNodeData(node.data); onNodeSelect(node.data.record); } }; - // Effect to layout nodes and edges based on the API data. + const handleNodeMouseEnter = useCallback( + (event, node) => { + const relatedEdge = edges.find((edge) => edge.target === node.id); + if (relatedEdge) { + setHighlightedEdge(relatedEdge.id); + setHighlightedNode(node.id); + } + }, + [edges] + ); + + const handleNodeMouseLeave = useCallback(() => { + setHighlightedEdge(null); + setHighlightedNode(null); + }, []); + + const highlightedEdges = edges.map((edge) => { + const isHighlighted = edge.id === highlightedEdge; + return { + ...edge, + style: { + ...edge.style, + stroke: isHighlighted ? antdColors.darkGray : antdColors.lightGray, + strokeWidth: isHighlighted ? 2 : 2, + }, + data: { ...edge.data, isHighlighted }, + }; + }); + + const highlightedNodes = filteredNodes.map((node) => { + if (node.id === highlightedNode) { + return { + ...node, + style: { + ...node.style, + boxShadow: "0 0 10px 3px rgba(1,1,0,0.5)", + }, + }; + } + return node; + }); + useEffect(() => { - // Transform the raw API data to nodes and edges. const { nodes: transformedNodes, edges: transformedEdges } = transformElasticSearchDataToElements(data, alertId); - // Separate nodes and edges for layout. const nodesToLayout = transformedNodes.filter(isNode); const edgesToLayout = transformedEdges.filter((el) => !isNode(el)); - // Apply a layout algorithm (e.g., Dagre) to position nodes and edges. const layoutedData = getDagreLayout(nodesToLayout, edgesToLayout); - // Find the first node and store its index - // const firstNode = layoutedData.find(isNode); - - // Update state with the positioned nodes and edges and select the first node setNodes(layoutedData.filter(isNode)); setEdges(layoutedData.filter((el) => !isNode(el))); - - // // Select the first node by calling handleNodeClick - // if (firstNode) { - // handleNodeClick(null, firstNode); - // } }, [alertId, data, setEdges, setNodes]); - // ------------------------- - // Render - // ------------------------- return (
(hasImage ? "40px" : "10px")}; + width: 24px; + height: 24px; + border-radius: 20%; + background-color: #ff7a45; + display: flex; + justify-content: center; + align-items: center; + box-shadow: 0px 4px 6px -1px rgba(0, 0, 0, 0.1); + cursor: pointer; +`; + const PulsatingAnimation = createGlobalStyle` @keyframes pulsate { 0% { @@ -94,18 +149,21 @@ const ImageTooltip = styled(Tooltip)` padding: 0 !important; overflow: hidden; } + .ant-tooltip-inner img { + pointer-events: auto; + } `; const PreviewImage = styled.img` - max-width: 100%; - max-height: 100%; - width: auto; - height: auto; + max-width: 100%; + max-height: 100%; + width: auto; + height: auto; `; const TagWrapper = styled.div` - display: inline-block; - margin-right: 10px; + display: inline-block; + margin-right: 10px; position: absolute; top: -15px; z-index: 10; @@ -142,18 +200,6 @@ const NodeWrapper = styled.div` align-items: center; `; -const Arrow = styled.div` - width: 0; - height: 0; - border-top: 6px solid transparent; - border-bottom: 6px solid transparent; - border-left: 10px solid #aaa; /* Arrow color */ - position: absolute; - left: -10px; /* Adjust as needed */ - top: 50%; - transform: translateY(-50%); -`; - const LeftWrapper = styled.div` width: 44px; height: 44px; @@ -195,7 +241,7 @@ const RightWrapper = styled.div` white-space: nowrap; overflow: hidden; text-overflow: ellipsis; - max-width: 450px; + max-width: 350px; } .node-label { color: #3d3a3b; @@ -205,7 +251,7 @@ const RightWrapper = styled.div` white-space: nowrap; overflow: hidden; text-overflow: ellipsis; - max-width: 375px; + max-width: 350px; } .node-sub { color: ${({ $acColor }) => $acColor}; @@ -225,17 +271,30 @@ const RightWrapper = styled.div` // ------------------------- const EventNode = memo(({ data, selected }) => { + // Initialize isBlurred based on the presence of data.nodeQrData + const [isBlurred] = useState(!!data.nodeQrData); + + // Example of conditional styling for blur effect + const previewStyle = isBlurred ? { filter: "blur(4px)" } : {}; + const handleStyle = { backgroundColor: "#aaa", width: 12, height: 12, - borderRadius: 12, - border: `1px solid bbb`, + borderRadius: "50%", + border: `1px solid #bbb`, }; - const mappingEntry = getIconConfig("strelka", data.nodeMain.toLowerCase()); + + const mappingEntry = getIconConfig( + "strelka", + data.nodeMain[0]?.toLowerCase() || "" + ); const IconComponent = mappingEntry?.icon; const color = mappingEntry?.color || data.color; + const hasImage = Boolean(data.nodeImage); const virusTotalResponse = data.nodeVirustotal; + const tlshResponse = data.nodeTlshData?.family; + data.nodeAlert = typeof virusTotalResponse === "number" && virusTotalResponse > 5; @@ -258,7 +317,6 @@ const EventNode = memo(({ data, selected }) => { )} {data.nodeDepth !== 0 && ( <> - { {IconComponent ? ( ) : ( -

{data.nodeMain}

+

{data.nodeMain[0]}

)} -

{data.nodeMain}

-

{data.nodeLabel}

+ +

{data.nodeMain.join(", ")}

+
+ +

{data.nodeLabel}

+
+

{data.nodeSub}

{data.nodeMetric} {data.nodeMetricLabel} + {tlshResponse && ( + + TLSH Related Match:{" "} + {`${tlshResponse.slice(0, 10)}${ + tlshResponse.length > 10 ? "..." : "" + }`} + + )}
{ {getVirusTotalStatus(data.nodeVirustotal)} + {data.nodeDecryptionSuccess === false && ( + + + + + + )} + {data.nodeDecryptionSuccess === true && ( + + + + + + )} + {data.nodeQrData && ( + + + + + + )} {data.nodeImage && ( { } > diff --git a/ui/src/components/FileComponents/EmailOverviewCard.js b/ui/src/components/FileOverviews/EmailOverview/EmailOverviewCard.js similarity index 93% rename from ui/src/components/FileComponents/EmailOverviewCard.js rename to ui/src/components/FileOverviews/EmailOverview/EmailOverviewCard.js index 26c7dc0..9d61378 100644 --- a/ui/src/components/FileComponents/EmailOverviewCard.js +++ b/ui/src/components/FileOverviews/EmailOverview/EmailOverviewCard.js @@ -1,9 +1,8 @@ import React, { useState } from "react"; import { Row, Col, Modal, Typography, List, Tag } from "antd"; -import "../../styles/OcrOverviewCard.css"; +import "../../../styles/OcrOverviewCard.css"; const EmailOverviewCard = ({ data }) => { - const [isModalVisible, setIsModalVisible] = useState(false); const { Text } = Typography; @@ -49,7 +48,7 @@ const EmailOverviewCard = ({ data }) => { { title: "Sender", description: from || "No Sender", tag: "Informational" }, { title: "Recipients", - description: to.map((name) => ({ name })) || [], + description: to?.map((name) => ({ name })) || "No Recipients", tag: "Informational", }, { @@ -62,8 +61,8 @@ const EmailOverviewCard = ({ data }) => { description: message_id || "No Message ID", tag: "Informational", }, - // Conditionally add "Attachment Names" row only if filenames is not empty - ...(filenames.length > 0 + // Check if filenames exist and is an array before trying to map over it + ...(Array.isArray(filenames) && filenames.length > 0 ? [ { title: "Attachment Names", @@ -74,7 +73,8 @@ const EmailOverviewCard = ({ data }) => { : []), { title: "Domains in Header", - description: received_domain.map((domain) => ({ domain })) || [], + description: + received_domain.map((domain) => ({ domain })) || "No Domains", tag: "Informational", }, { title: "Body", description: body || "No Body", tag: "Informational" }, diff --git a/ui/src/components/FileOverviews/EmailOverview/EmailOverviewLanding.js b/ui/src/components/FileOverviews/EmailOverview/EmailOverviewLanding.js new file mode 100644 index 0000000..062bdfc --- /dev/null +++ b/ui/src/components/FileOverviews/EmailOverview/EmailOverviewLanding.js @@ -0,0 +1,65 @@ +import React, { useState, useEffect } from 'react'; +import { Collapse, Typography, Tag } from 'antd'; +import EmailOverviewCard from './EmailOverviewCard'; + +const { Text } = Typography; + +const EmailOverviewLanding = ({ selectedNodeData, expandAll }) => { + const [activeKey, setActiveKey] = useState([]); + + useEffect(() => { + setActiveKey(expandAll ? ["1"] : []); + }, [expandAll]); + + if (!selectedNodeData || !selectedNodeData.scan || !selectedNodeData.scan.email) { + return null; + } + + const emailData = selectedNodeData.scan.email; + const subjectPreview = emailData.subject && emailData.subject.length > 0 + ? `${emailData.subject.substring(0, 47)}...` + : "No Subject"; + const attachmentsCount = emailData.total && emailData.total.attachments; + + return ( + setActiveKey(keys)} + style={{ width: "100%", marginBottom: "10px" }} + > + +
+
+ Email +
{subjectPreview}
+
+
+
+ + Attachments: {attachmentsCount} + + + {emailData.base64_thumbnail ? "Preview Available" : "No Preview"} + +
+
+ } + key="1" + > + + + + ); +}; + +export default EmailOverviewLanding; diff --git a/ui/src/components/FileOverviews/EncryptedZipOverview/EncryptedZipOverviewCard.js b/ui/src/components/FileOverviews/EncryptedZipOverview/EncryptedZipOverviewCard.js new file mode 100644 index 0000000..d119feb --- /dev/null +++ b/ui/src/components/FileOverviews/EncryptedZipOverview/EncryptedZipOverviewCard.js @@ -0,0 +1,104 @@ +import React from "react"; +import { Typography, Row, Col, Tag, Descriptions, Card } from "antd"; +import { antdColors } from "../../../utils/colors"; + +const { Text } = Typography; + +// Function to determine extraction color based on extracted and total files +const getExtractionColor = (extracted, total) => { + if (extracted === total && total > 0) { + return { color: antdColors.darkGreen }; + } else if (extracted > 0 && extracted < total) { + return { color: antdColors.deepOrange }; + } else { + return { color: antdColors.red }; + } +}; + +const EncryptedZipOverviewCard = ({ data }) => { + const extracted = data.scan.encrypted_zip.total.extracted; + const total = data.scan.encrypted_zip.total.files; + const extractionColor = getExtractionColor(extracted, total); + + return ( +
+ Extraction Details + + + +
Extracted Files
+
+ {extracted}/{total} +
+
+ + + + + {total} + + + {extracted} + + + + {data.scan.encrypted_zip?.cracked_password || "Not available"} + + + + + {data.scan.encrypted_zip.elapsed.toFixed(3)} seconds + + + {data.scan.encrypted_zip.flags && ( + + {data.scan.encrypted_zip.flags.map((flag, index) => ( + + {flag} + + ))} + + )} + + +
+
+ ); +}; + +export default EncryptedZipOverviewCard; diff --git a/ui/src/components/FileOverviews/EncryptedZipOverview/EncryptedZipOverviewLanding.js b/ui/src/components/FileOverviews/EncryptedZipOverview/EncryptedZipOverviewLanding.js new file mode 100644 index 0000000..025cf6b --- /dev/null +++ b/ui/src/components/FileOverviews/EncryptedZipOverview/EncryptedZipOverviewLanding.js @@ -0,0 +1,68 @@ +import React, { useState, useEffect } from "react"; +import { Collapse, Typography, Tag } from "antd"; +import EncryptedZipOverviewCard from "./EncryptedZipOverviewCard"; + +const { Text } = Typography; + +const EncryptedZipOverviewLanding = ({ selectedNodeData, expandAll }) => { + const [activeKey, setActiveKey] = useState([]); + + useEffect(() => { + setActiveKey(expandAll ? ["1"] : []); + }, [expandAll]); + + if ( + !selectedNodeData || + !selectedNodeData.scan || + !selectedNodeData.scan.encrypted_zip + ) { + return null; + } + + const encryptedZipData = selectedNodeData.scan.encrypted_zip; + const fileCount = encryptedZipData.total.files || 0; + const extractedCount = encryptedZipData.total.extracted || 0; + const extractionStatus = + fileCount > 0 && extractedCount === 0 + ? "Could Not Extract Files" + : "Extracted Files"; + + return ( + + +
+ Encrypted Zip Details +
+ Total Files: {fileCount} +
+
+ + {extractionStatus} + +
+ } + key="1" + > + + + + ); +}; + +export default EncryptedZipOverviewLanding; diff --git a/ui/src/components/FileComponents/ExiftoolOverviewCard.js b/ui/src/components/FileOverviews/ExiftoolOverview/ExiftoolOverviewCard.js similarity index 98% rename from ui/src/components/FileComponents/ExiftoolOverviewCard.js rename to ui/src/components/FileOverviews/ExiftoolOverview/ExiftoolOverviewCard.js index 90da180..035bfeb 100644 --- a/ui/src/components/FileComponents/ExiftoolOverviewCard.js +++ b/ui/src/components/FileOverviews/ExiftoolOverview/ExiftoolOverviewCard.js @@ -1,6 +1,6 @@ import React, { useState } from "react"; import { Input, Checkbox, Typography, Row, Col } from "antd"; -import "../../styles/ExiftoolOverviewCard.css" +import "../../../styles/ExiftoolOverviewCard.css" const { Text } = Typography; diff --git a/ui/src/components/FileOverviews/ExiftoolOverview/ExiftoolOverviewLanding.js b/ui/src/components/FileOverviews/ExiftoolOverview/ExiftoolOverviewLanding.js new file mode 100644 index 0000000..3fac2ec --- /dev/null +++ b/ui/src/components/FileOverviews/ExiftoolOverview/ExiftoolOverviewLanding.js @@ -0,0 +1,43 @@ +import React, { useState, useEffect } from 'react'; +import { Collapse, Typography } from 'antd'; +import FileExiftoolCard from './ExiftoolOverviewCard'; + +const { Text } = Typography; + +const ExiftoolOverviewLanding = ({ selectedNodeData, expandAll }) => { + const [activeKey, setActiveKey] = useState([]); + + useEffect(() => { + setActiveKey(expandAll ? ["1"] : []); + }, [expandAll]); + + if (!selectedNodeData || !selectedNodeData.scan || !selectedNodeData.scan.exiftool) { + return null; + } + + const metadataCount = Object.keys(selectedNodeData.scan.exiftool).length; + + return ( + setActiveKey(keys)} + style={{ width: "100%", marginBottom: "10px" }} + > + + File Metadata +
+ Metadata Count: {metadataCount} +
+ + } + key="1" + > + +
+
+ ); +}; + +export default ExiftoolOverviewLanding; diff --git a/ui/src/components/FileOverviews/FileInsights/FileInsightsLanding.js b/ui/src/components/FileOverviews/FileInsights/FileInsightsLanding.js new file mode 100644 index 0000000..124a667 --- /dev/null +++ b/ui/src/components/FileOverviews/FileInsights/FileInsightsLanding.js @@ -0,0 +1,40 @@ +import React, { useState, useEffect } from "react"; +import { Collapse, Tag, Typography } from "antd"; +import InsightsCard from './FileInsightsOverviewCard'; + +const { Text } = Typography; + +const InsightsLanding = ({ selectedNodeData, expandAll }) => { + const insightsData = selectedNodeData?.insights || []; + const [activeKey, setActiveKey] = useState([]); + + useEffect(() => { + setActiveKey(expandAll ? ["1"] : []); + }, [expandAll]); + + return ( + setActiveKey(keys)} + style={{ width: "100%", marginBottom: "10px" }} + > + + Insights +
+ + Matches: {insightsData.length} + +
+ + } + key="1" + > + +
+
+ ); +}; + +export default InsightsLanding; diff --git a/ui/src/components/FileComponents/InsightsCard.js b/ui/src/components/FileOverviews/FileInsights/FileInsightsOverviewCard.js similarity index 100% rename from ui/src/components/FileComponents/InsightsCard.js rename to ui/src/components/FileOverviews/FileInsights/FileInsightsOverviewCard.js diff --git a/ui/src/components/FileOverviews/FileIocsOverview/FileIocsOverviewCard.js b/ui/src/components/FileOverviews/FileIocsOverview/FileIocsOverviewCard.js new file mode 100644 index 0000000..e0faed2 --- /dev/null +++ b/ui/src/components/FileOverviews/FileIocsOverview/FileIocsOverviewCard.js @@ -0,0 +1,200 @@ +import React, { useState } from "react"; +import { Tag, Tooltip, Typography, Space } from "antd"; +import { getIconConfig } from "../../../utils/iconMappingTable"; +import { antdColors } from "../../../utils/colors"; + +const { Text } = Typography; + +/** + * Displays an overview of IOC matches for files, categorized into IOC types. + * @param {{ data: Object, onFileIocSelect: Function }} props + */ +const FileIocsOverviewCard = ({ data, onFileIocSelect }) => { + const [selectedIoc, setSelectedIoc] = useState(null); + const [showMore, setShowMore] = useState(false); // State to control showing more IOCs + + // Initialize an object to store details for each unique IOC value + const iocCounts = {}; + + // Helper function descriptions + /** + * Handles selection of a IOC match. + * @param {string} ioc The selected IOC match. + */ + const selectIoc = (ioc) => { + const newSelectedioc = ioc === selectedIoc ? null : ioc; + setSelectedIoc(newSelectedioc); + onFileIocSelect(newSelectedioc); + }; + + // Mapping from IOC type to user-friendly label + const iocTypeLabels = { + domain: "Domains", + url: "URLs", + md5: "MD5 Hashes", + sha1: "SHA-1 Hashes", + sha256: "SHA-256 Hashes", + email: "Email Addresses", + ip: "IP Addresses", + }; + + // Aggregate IOCs and their file counts from strelka_response + data.strelka_response.forEach((response) => { + const iocs = response?.iocs || []; + iocs.forEach((ioc) => { + const iocValue = ioc.ioc; + if (!iocCounts[iocValue]) { + // If this is the first time we've seen this IOC, initialize its details + iocCounts[iocValue] = { + type: ioc.ioc_type, + count: 0, + files: new Set(), + }; + } + // Increment the count and add the file to the set + iocCounts[iocValue].count++; + iocCounts[iocValue].files.add( + response.file.name || response.scan.hash.md5 + ); + }); + }); + + // Now transform the counts into an array suitable for rendering + const iocData = Object.entries(iocCounts) + .map(([value, details]) => ({ + value, + type: details.type, + count: details.count, + files: Array.from(details.files), // Convert the set of files to an array + })) + .sort((a, b) => b.count - a.count); // Sort by count descending + + const hasIocs = iocData.length > 0; + + // Render tags for each IOC within the type using Space for consistent layout + const renderIocTag = (iocType, value, count, files) => { + // Get the icon configuration for the current IOC type + const iconConfig = getIconConfig("strelka", iocType); + const IconComponent = iconConfig?.icon; + const iconColor = iconConfig?.color || antdColors.darkPurple; // Default to darkPurple if no color is provided + + return ( + + selectIoc(value)} + color="default" + style={{ + cursor: "pointer", + width: "100%", + justifyContent: "space-between", + alignItems: "center", + background: + selectedIoc === value + ? `${antdColors.blue}10` + : "none", + border: + selectedIoc === value + ? `1px solid ${antdColors.blue}` + : "none", + }} + > +
+ {IconComponent && ( +
+ +
+ )} + + {value} + + + {count} + +
+
+
+ ); + }; + + // Helper function to render a section for an IOC type + const renderSection = (iocType, iocs) => { + // Display a limited number of IOCs initially + const displayedIocs = showMore ? iocs : iocs.slice(0, 5); + + const label = iocTypeLabels[iocType.toLowerCase()] || iocType; + + return ( + + + {label}: + + {displayedIocs.map((iocData) => + renderIocTag( + iocData.type, + iocData.value, + iocData.count, + iocData.files + ) + )} + {!showMore && iocs.length > 5 && ( + setShowMore(true)} + style={{ + cursor: "pointer", + color: "#1890ff", + marginLeft: "30px", + fontSize: "12px", + }} + > + ... and {iocs.length - 5} more + + )} + + ); + }; + + // Render the complete list of IOC sections + return ( +
+ {!hasIocs ? ( +
+

+ No IOCs Not Found +

+
+ ) : ( + <> + {Object.entries(iocTypeLabels) + .filter(([iocType]) => iocData.some((ioc) => ioc.type === iocType)) // Filter out the IOC types that have no data + .map(([iocType, label]) => { + const iocsForType = iocData.filter( + (iocData) => iocData.type === iocType + ); + return renderSection(iocType, iocsForType); + })} + + )} +
+ ); +}; + +export default FileIocsOverviewCard; diff --git a/ui/src/components/FileOverviews/FileIocsOverview/FileIocsOverviewLanding.js b/ui/src/components/FileOverviews/FileIocsOverview/FileIocsOverviewLanding.js new file mode 100644 index 0000000..3662004 --- /dev/null +++ b/ui/src/components/FileOverviews/FileIocsOverview/FileIocsOverviewLanding.js @@ -0,0 +1,64 @@ +import React, { useState } from "react"; +import { Collapse, Tag, Typography } from "antd"; +import FileIocsOverviewCard from "./FileIocsOverviewCard"; +import { antdColors } from "../../../utils/colors"; + +const { Text } = Typography; + +const FileIocsOverviewLanding = ({ data, onFileIocSelect }) => { + const [filterApplied, setFilterApplied] = useState(false); + + const handleIocSelect = (selectedIoc) => { + setFilterApplied(!!selectedIoc); + onFileIocSelect(selectedIoc); + }; + + const borderStyle = filterApplied + ? { + // Styles when the filter is applied + border: `2px solid ${antdColors.blue}50`, + borderRadius: "8px", + boxShadow: "0 2px 8px rgba(0, 0, 0, 0.1)", + padding: "3px", + transition: "all 0.3s", // Transition for both applying and removing the filter + } + : { + // Styles when the filter is not applied (could potentially add styles for the normal state if needed) + transition: "all 0.3s", + }; + + return ( + + + Potential IOCs + {filterApplied && ( + + Filter Applied + + )} + + } + key="1" + > + + + + ); +}; + +export default FileIocsOverviewLanding; diff --git a/ui/src/components/FileComponents/FileOverviewCard.js b/ui/src/components/FileOverviews/FileOverview/FileOverviewCard.js similarity index 51% rename from ui/src/components/FileComponents/FileOverviewCard.js rename to ui/src/components/FileOverviews/FileOverview/FileOverviewCard.js index 4a2fca4..29b882c 100644 --- a/ui/src/components/FileComponents/FileOverviewCard.js +++ b/ui/src/components/FileOverviews/FileOverview/FileOverviewCard.js @@ -1,20 +1,58 @@ import React from "react"; -import { Row, Col, Typography, Tooltip } from "antd"; +import { Row, Col, Typography, Tooltip, Tag } from "antd"; import { InfoCircleOutlined } from "@ant-design/icons"; +import styled from "styled-components"; +import useVirusTotalApiKey from '../../../utils/useVirusTotalApiKey'; + const { Text } = Typography; +const VirusTotalInfoContent = styled(({ isclickable, ...props }) =>
)` + display: flex; + align-items: center; + cursor: ${({ isclickable }) => (isclickable ? "pointer" : "default")}; +`; + +const VirusTotalTag = styled(Tag)` + fontSize: "10px", + fontWeight: "bold", + width: "80%", + textAlignLast: "center", + maxWidth: "75px", +`; + +const InfoRow = styled.div` + display: flex; + align-items: center; + font-size: small; + color: #888; +`; + +const getVirusTotalTagProps = (positives) => { + if (positives > 5) { + return "red"; // Color "volcano" from Ant Design for a red tone + } else if (positives === 0) { + return "success"; // Green color for benign + } + return "default"; // Default for not available or not applicable cases +}; + /** * Component that displays an overview of a file's properties. * * @param {Object} props - Component properties. + * @param {Object} onOpenVt - Resource for VT Augment * @param {Object} props.data - The data object containing file and scan information. * @returns {JSX.Element} A JSX element representing the card. */ -const FileOverviewCard = ({ data }) => { +const FileOverviewCard = ({ data, onOpenVT }) => { + const virustotalData = data?.enrichment?.virustotal; + const vtColor = getVirusTotalTagProps(virustotalData); + const { isApiKeyAvailable } = useVirusTotalApiKey(); + // Helper function to format the text row for display. const renderTextRow = (label, content, isCode = false, copyable = false) => ( - + {label} @@ -25,6 +63,13 @@ const FileOverviewCard = ({ data }) => { ); + // Helper function to open VT Augment if exists + const handleVirusTotalClick = () => { + if (isApiKeyAvailable) { + onOpenVT(data.scan.hash.sha256); + } + }; + // Function to handle entropy styling const getEntropyStyle = (entropy) => { if (entropy > 6.5) { @@ -48,7 +93,7 @@ const FileOverviewCard = ({ data }) => { return ( - + Entropy: @@ -67,7 +112,7 @@ const FileOverviewCard = ({ data }) => {
{renderTextRow("File Name:", data.file.name)} {renderTextRow("MIME Type:", data.file.flavors.mime?.join(", "), true)} - {renderTextRow("YARA Flavors:", data.file.flavors.yara?.join(", "), true)} + {renderTextRow("YARA Flavors:", data.file.flavors.yara?.join(", ") || "N/A", true)} {renderTextRow("MD5:", data.scan.hash.md5, true, true)} {renderTextRow("SHA1:", data.scan.hash.sha1, true, true)} {renderTextRow("SHA256:", data.scan.hash.sha256, true, true)} @@ -79,28 +124,46 @@ const FileOverviewCard = ({ data }) => { )} {data.scan?.entropy && renderEntropy(data.scan.entropy.entropy)} - + VirusTotal: - {data["enrichment"]?.["virustotal"] !== undefined && - data["enrichment"]["virustotal"] !== -1 ? ( - - {data["enrichment"]?.["virustotal"]} Positives - - ) : ( - - Not Found - + {typeof virustotalData !== "undefined" && virustotalData > -1 && ( + + + VirusTotal + + {virustotalData} Positives + + + + )} + {(typeof virustotalData == "undefined" || virustotalData < 0) && ( + + + VirusTotal + + N/A + + + )} diff --git a/ui/src/components/FileOverviews/FileOverview/FileOverviewLanding.js b/ui/src/components/FileOverviews/FileOverview/FileOverviewLanding.js new file mode 100644 index 0000000..dda2dcc --- /dev/null +++ b/ui/src/components/FileOverviews/FileOverview/FileOverviewLanding.js @@ -0,0 +1,53 @@ +// FileOverviews/FileOverview/FileOverviewLanding.js +import React from "react"; +import { Collapse, Button, Typography } from "antd"; +import FileOverviewCard from "./FileOverviewCard"; + +const { Panel } = Collapse; +const { Text } = Typography; + +const FileOverviewLanding = ({ + selectedNodeData, + onOpenVT, + expandAll, + onToggleAllSections, +}) => { + if (!selectedNodeData) { + return null; + } + + return ( + + +
+ File Overview +
+ Size: {(selectedNodeData.file.size / 1024).toFixed(2)} KB ( + {selectedNodeData.file.size} bytes) +
+
+ +
+ } + key="1" + > + + + + ); +}; + +export default FileOverviewLanding; diff --git a/ui/src/components/FileComponents/FileTypeOverviewCard.js b/ui/src/components/FileOverviews/FileTypeOverview/FileTypeOverviewCard.js similarity index 93% rename from ui/src/components/FileComponents/FileTypeOverviewCard.js rename to ui/src/components/FileOverviews/FileTypeOverview/FileTypeOverviewCard.js index bfcad8b..004a3e0 100644 --- a/ui/src/components/FileComponents/FileTypeOverviewCard.js +++ b/ui/src/components/FileOverviews/FileTypeOverview/FileTypeOverviewCard.js @@ -1,7 +1,7 @@ import React, { useState } from "react"; import { Tag, Tooltip, Typography, Space } from "antd"; -import { getIconConfig } from "../../utils/iconMappingTable"; -import { antdColors } from "../../utils/colors"; +import { getIconConfig } from "../../../utils/iconMappingTable"; +import { antdColors } from "../../../utils/colors"; const { Text } = Typography; @@ -60,11 +60,13 @@ const FileTypeOverviewCard = ({ data, onFileTypeSelect }) => { width: "100%", justifyContent: "space-between", alignItems: "center", - background: "none", + background: selectedFileType === item.mimeType + ? `${antdColors.blue}20` + : "none", cursor: "pointer", border: selectedFileType === item.mimeType - ? `1px solid ${bgColor}` + ? `1px solid ${antdColors.blue}` : "none", }} > diff --git a/ui/src/components/FileOverviews/FileTypeOverview/FileTypeOverviewLanding.js b/ui/src/components/FileOverviews/FileTypeOverview/FileTypeOverviewLanding.js new file mode 100644 index 0000000..588a00d --- /dev/null +++ b/ui/src/components/FileOverviews/FileTypeOverview/FileTypeOverviewLanding.js @@ -0,0 +1,67 @@ +import React, { useState } from "react"; +import { Collapse, Typography, Tag } from "antd"; +import FileTypeOverviewCard from "./FileTypeOverviewCard"; +import { antdColors } from "../../../utils/colors"; + +const { Text } = Typography; + +const FileTypeOverviewLanding = ({ data, onFileTypeSelect }) => { + const [filterApplied, setFilterApplied] = useState(false); + + const handleFileTypeSelect = (selectedFileType) => { + setFilterApplied(!!selectedFileType); + onFileTypeSelect(selectedFileType); + }; + + const borderStyle = filterApplied + ? { + // Styles when the filter is applied + border: `2px solid ${antdColors.blue}50`, + borderRadius: "8px", + boxShadow: "0 2px 8px rgba(0, 0, 0, 0.1)", + padding: "3px", + transition: "all 0.3s", // Transition for both applying and removing the filter + } + : { + // Styles when the filter is not applied (could potentially add styles for the normal state if needed) + transition: "all 0.3s", + }; + + return ( + + + File Types + {filterApplied && ( + + Filter Applied + + )} +
+ } + key="1" + > + + + + ); +}; + +export default FileTypeOverviewLanding; diff --git a/ui/src/components/FileOverviews/FileYara/FileYaraLanding.js b/ui/src/components/FileOverviews/FileYara/FileYaraLanding.js new file mode 100644 index 0000000..0135164 --- /dev/null +++ b/ui/src/components/FileOverviews/FileYara/FileYaraLanding.js @@ -0,0 +1,44 @@ +import React, { useState, useEffect } from "react"; +import { Collapse, Tag, Typography } from "antd"; +import YaraOverviewCard from './YaraOverviewCard'; + +const { Text } = Typography; + +const YaraOverviewLanding = ({ selectedNodeData, expandAll }) => { + const yaraMatches = selectedNodeData?.scan?.yara?.matches || []; + const [activeKey, setActiveKey] = useState([]); + + useEffect(() => { + setActiveKey(expandAll ? ["1"] : []); + }, [expandAll]); + + return ( + setActiveKey(keys)} + style={{ width: "100%", marginBottom: "10px" }} + > + + YARA Signatures +
+ + Matches: {yaraMatches.length} + +
+ + } + key="1" + > + {yaraMatches.length > 0 ? ( + + ) : ( + "No YARA Matches" + )} +
+
+ ); +}; + +export default YaraOverviewLanding; diff --git a/ui/src/components/FileComponents/YaraOverviewCard.js b/ui/src/components/FileOverviews/FileYara/YaraOverviewCard.js similarity index 100% rename from ui/src/components/FileComponents/YaraOverviewCard.js rename to ui/src/components/FileOverviews/FileYara/YaraOverviewCard.js diff --git a/ui/src/components/FileComponents/FileHeaderFooterCard.js b/ui/src/components/FileOverviews/HeaderFooterOverview/HeaderFooterCard.js similarity index 100% rename from ui/src/components/FileComponents/FileHeaderFooterCard.js rename to ui/src/components/FileOverviews/HeaderFooterOverview/HeaderFooterCard.js diff --git a/ui/src/components/FileOverviews/HeaderFooterOverview/HeaderFooterLanding.js b/ui/src/components/FileOverviews/HeaderFooterOverview/HeaderFooterLanding.js new file mode 100644 index 0000000..b14eb9d --- /dev/null +++ b/ui/src/components/FileOverviews/HeaderFooterOverview/HeaderFooterLanding.js @@ -0,0 +1,46 @@ +import React, { useState, useEffect } from "react"; +import { Collapse, Typography } from "antd"; +import FileHeaderFooterCard from "./HeaderFooterCard"; + +const { Text } = Typography; + +const FileHeaderFooterLanding = ({ selectedNodeData, expandAll }) => { + const header = selectedNodeData?.scan?.header; + const footer = selectedNodeData?.scan?.footer; + const [activeKey, setActiveKey] = useState([]); + + useEffect(() => { + setActiveKey(expandAll ? ["1"] : []); + }, [expandAll]); + + if (!header || !footer) { + return null; + } + + return ( + setActiveKey(keys)} + style={{ width: "100%", marginBottom: "10px" }} + > + + Header / Footer +
+ Header: {header.header} +
+
+ Footer: {footer.footer} +
+ + } + key="1" + > + +
+
+ ); +}; + +export default FileHeaderFooterLanding; diff --git a/ui/src/components/FileOverviews/HeaderOverview/HeaderLanding.js b/ui/src/components/FileOverviews/HeaderOverview/HeaderLanding.js new file mode 100644 index 0000000..9a2cc13 --- /dev/null +++ b/ui/src/components/FileOverviews/HeaderOverview/HeaderLanding.js @@ -0,0 +1,16 @@ +// FileOverviews/FileHeaderOverview/FileHeaderOverviewLanding.js +import React from 'react'; +import { Row, Col } from 'antd'; +import FileHeaderOverviewCard from './HeaderOverviewCard'; + +const FileHeaderOverviewLanding = ({ data, onOpenVT }) => { + return ( + + + + + + ); +}; + +export default FileHeaderOverviewLanding; diff --git a/ui/src/components/FileComponents/FileHeaderOverviewCard.js b/ui/src/components/FileOverviews/HeaderOverview/HeaderOverviewCard.js similarity index 76% rename from ui/src/components/FileComponents/FileHeaderOverviewCard.js rename to ui/src/components/FileOverviews/HeaderOverview/HeaderOverviewCard.js index c84dea0..9d107b8 100644 --- a/ui/src/components/FileComponents/FileHeaderOverviewCard.js +++ b/ui/src/components/FileOverviews/HeaderOverview/HeaderOverviewCard.js @@ -1,9 +1,10 @@ import React from "react"; import { Card, Row, Tooltip, Button, Tag, Typography } from "antd"; -import { getIconConfig } from "../../utils/iconMappingTable"; +import { getIconConfig } from "../../../utils/iconMappingTable"; -import { APP_CONFIG } from "../../config"; +import { APP_CONFIG } from "../../../config"; import styled from "styled-components"; +import useVirusTotalApiKey from "../../../utils/useVirusTotalApiKey"; const { Text } = Typography; @@ -18,6 +19,23 @@ const StyledText = styled(Text)` margin-right: 8px; `; +const VirusTotalInfoContent = styled.div` + cursor: ${({ isApiKeyAvailable }) => + !isApiKeyAvailable ? "default" : "pointer"}; + display: flex; + align-items: center; + pointer-events: ${({ isApiKeyAvailable }) => + !isApiKeyAvailable ? "none" : "auto"}; +`; + +const VirusTotalTag = styled(Tag)` + fontSize: "10px", + fontWeight: "bold", + width: "80%", + textAlignLast: "center", + maxWidth: "75px", +`; + const LeftWrapper = styled.div` margin-right: 15px; width: 44px; @@ -70,6 +88,15 @@ const formatFileSize = (size) => { } }; +const getVirusTotalTagProps = (positives) => { + if (positives > 5) { + return "red"; // Color "volcano" from Ant Design for a red tone + } else if (positives === 0) { + return "success"; // Green color for benign + } + return "default"; // Default for not available or not applicable cases +}; + const getDisposition = (data) => { let text = "Not Found on VirusTotal"; // Default text let color = "default"; // Default color @@ -117,8 +144,12 @@ const getRandomColor = () => { const getColorForMimetypes = () => getRandomColor(); -const FileHeaderOverviewCard = ({ data }) => { +const FileHeaderOverviewCard = ({ data, onOpenVT }) => { const sortedScannersRun = [...(data?.scanners_run || [])].sort(); + const virustotalData = data.strelka_response[0]?.enrichment?.virustotal; + const vtColor = getVirusTotalTagProps(virustotalData); + const { isApiKeyAvailable } = useVirusTotalApiKey(); + const mappingEntry = getIconConfig( "strelka", data.strelka_response[0].file.flavors.mime[0].toLowerCase() @@ -126,8 +157,15 @@ const FileHeaderOverviewCard = ({ data }) => { const IconComponent = mappingEntry?.icon; const color = mappingEntry?.color || data.color; + const handleVirusTotalClick = () => { + if (isApiKeyAvailable) { + const sha256Hash = data.strelka_response[0]?.scan?.hash?.sha256; + onOpenVT(sha256Hash); + } + }; + return ( -
+
{ Insights: {data.insights.length} )} - - {getDisposition(data)} - + {getDisposition(data)} {[ - APP_CONFIG.SEARCH_URL && APP_CONFIG.SEARCH_NAME && ( - ", - data.file_id - )}`} - target="_blank" - rel="noreferrer" - > - - - ), - ]} + APP_CONFIG.SEARCH_URL && APP_CONFIG.SEARCH_NAME && ( + ", + data.file_id + )}`} + target="_blank" + rel="noreferrer" + > + + + ), + ]}
@@ -227,9 +265,9 @@ const FileHeaderOverviewCard = ({ data }) => { > {`... and ${ @@ -327,6 +365,29 @@ const FileHeaderOverviewCard = ({ data }) => { + {typeof virustotalData !== "undefined" && virustotalData > -1 && ( + + VirusTotal: + + VirusTotal + + {virustotalData} Positives + + + + )}
{sortedScannersRun.map((tag) => ( diff --git a/ui/src/components/FileComponents/FileHighlightsOverviewCard.js b/ui/src/components/FileOverviews/HighlightsOverview/HighlightsOverviewCard.js similarity index 78% rename from ui/src/components/FileComponents/FileHighlightsOverviewCard.js rename to ui/src/components/FileOverviews/HighlightsOverview/HighlightsOverviewCard.js index 58829e4..ac81b42 100644 --- a/ui/src/components/FileComponents/FileHighlightsOverviewCard.js +++ b/ui/src/components/FileOverviews/HighlightsOverview/HighlightsOverviewCard.js @@ -6,20 +6,41 @@ import { RightOutlined, WarningOutlined, } from "@ant-design/icons"; -import { getIconConfig } from "../../utils/iconMappingTable"; -import { antdColors } from "../../utils/colors"; +import { getIconConfig } from "../../../utils/iconMappingTable"; +import { antdColors } from "../../../utils/colors"; const { Text } = Typography; const FileHighlightsOverviewCard = ({ data, onFileNameSelect }) => { const [expandedNodes, setExpandedNodes] = useState(new Set()); const [selectedNodeId, setSelectedNodeId] = useState(null); + const [visibleNodeCount, setVisibleNodeCount] = useState(20); // start with 20 nodes visible + const LOAD_MORE_COUNT = 10; // number of nodes to load on each click const insightsByNode = {}; const iocsByNode = {}; const mimeTypeByNode = {}; const filenameByNode = {}; + // Function to load more nodes + const loadMoreNodes = () => { + setVisibleNodeCount((prevCount) => prevCount + LOAD_MORE_COUNT); + }; + + const getVTPositivesInfo = (response) => { + const vtCount = response?.enrichment?.virustotal; + if (typeof vtCount === "number") { + if (vtCount < 0) { + return null; // No box if VT data is not available + } + return { + count: vtCount, + color: vtCount > 3 ? "volcano" : "green", // Red if > 3, green if 0-3 + }; + } + return null; // No box if VT data is not available + }; + // Populate insights, iocs, mime types, and filenames by node data.strelka_response.forEach((response) => { if (response.insights?.length > 0 || response.iocs?.length > 0) { @@ -39,11 +60,25 @@ const FileHighlightsOverviewCard = ({ data, onFileNameSelect }) => { const sortedNodeIds = Object.keys(filenameByNode) .map((nodeId) => ({ nodeId, - filename: filenameByNode[nodeId] || 'No Filename', + filename: filenameByNode[nodeId] || "No Filename", iocCount: iocsByNode[nodeId]?.length || 0, insightCount: insightsByNode[nodeId]?.length || 0, })) .sort((a, b) => { + // Get VT positives or assign a default for comparison + const vtPositivesA = + getVTPositivesInfo( + data.strelka_response.find((res) => res.file.tree.node === a.nodeId) + )?.count || 0; + const vtPositivesB = + getVTPositivesInfo( + data.strelka_response.find((res) => res.file.tree.node === b.nodeId) + )?.count || 0; + + // Descending sort for VT positives + if (vtPositivesA !== vtPositivesB) { + return vtPositivesB - vtPositivesA; + } if (a.iocCount !== b.iocCount) { return b.iocCount - a.iocCount; } else if (a.insightCount !== b.insightCount) { @@ -53,19 +88,8 @@ const FileHighlightsOverviewCard = ({ data, onFileNameSelect }) => { }) .map((sortedItem) => sortedItem.nodeId); - const getVTPositivesInfo = (response) => { - const vtCount = response?.enrichment?.virustotal; - if (typeof vtCount === "number") { - if (vtCount < 0) { - return null; // No box if VT data is not available - } - return { - count: vtCount, - color: vtCount > 3 ? "volcano" : "green", // Red if > 3, green if 0-3 - }; - } - return null; // No box if VT data is not available - }; + // Only show the nodes that are within the visibleNodeCount + const visibleNodeIds = sortedNodeIds.slice(0, visibleNodeCount); // Check if there are any highlights const hasHighlights = sortedNodeIds.length > 0; @@ -91,7 +115,7 @@ const FileHighlightsOverviewCard = ({ data, onFileNameSelect }) => { setExpandedNodes(newExpandedNodes); }; - const nodeList = sortedNodeIds.map((nodeId) => { + const nodeList = visibleNodeIds.map((nodeId) => { const isExpanded = expandedNodes.has(nodeId); const filename = filenameByNode[nodeId] || "No Filename"; const insights = insightsByNode[nodeId] || []; @@ -114,10 +138,14 @@ const FileHighlightsOverviewCard = ({ data, onFileNameSelect }) => { marginBottom: "8px", overflow: "hidden", cursor: "pointer", + background: + selectedNodeId === nodeId + ? `${antdColors.blue}10` + : "none", borderRadius: "5px", border: selectedNodeId === nodeId - ? `1px solid ${antdColors.lightGray}` + ? `1px solid ${antdColors.blue}` : "none", }} > @@ -252,21 +280,35 @@ const FileHighlightsOverviewCard = ({ data, onFileNameSelect }) => { return (
{hasHighlights ? ( - nodeList + <> + {nodeList} + {visibleNodeCount < sortedNodeIds.length && ( + + ...and {sortedNodeIds.length - visibleNodeCount} more (show next{" "} + {Math.min( + LOAD_MORE_COUNT, + sortedNodeIds.length - visibleNodeCount + )} + ) + + )} + ) : ( -
- - {" "} - No Highlights for this Submission - -
+ + No Highlights for this Submission + )}
); diff --git a/ui/src/components/FileOverviews/HighlightsOverview/HighlightsOverviewLanding.js b/ui/src/components/FileOverviews/HighlightsOverview/HighlightsOverviewLanding.js new file mode 100644 index 0000000..0200cfd --- /dev/null +++ b/ui/src/components/FileOverviews/HighlightsOverview/HighlightsOverviewLanding.js @@ -0,0 +1,65 @@ +import React, { useState } from "react"; +import { Collapse, Tag } from "antd"; +import FileHighlightsOverviewCard from "./HighlightsOverviewCard"; +import { antdColors } from "../../../utils/colors"; + +const FileHighlightsOverviewLanding = ({ data, onFileNameSelect }) => { + const [filterApplied, setFilterApplied] = useState(false); + + const handleFileNameSelect = (selectedFileName) => { + setFilterApplied(!!selectedFileName); + onFileNameSelect(selectedFileName); + }; + + const borderStyle = filterApplied + ? { + // Styles when the filter is applied + border: `2px solid ${antdColors.blue}50`, + borderRadius: "8px", + boxShadow: "0 2px 8px rgba(0, 0, 0, 0.1)", + padding: "3px", + transition: "all 0.3s", // Transition for both applying and removing the filter + } + : { + // Styles when the filter is not applied (could potentially add styles for the normal state if needed) + transition: "all 0.3s", + }; + + return ( + + + File Highlights + {filterApplied && ( + + Filter Applied + + )}{" "} +
+ } + key="1" + > + + + + ); +}; + +export default FileHighlightsOverviewLanding; diff --git a/ui/src/components/FileComponents/JavascriptOverviewCard.js b/ui/src/components/FileOverviews/JavascriptOverview/JavascriptOverviewCard.js similarity index 98% rename from ui/src/components/FileComponents/JavascriptOverviewCard.js rename to ui/src/components/FileOverviews/JavascriptOverview/JavascriptOverviewCard.js index 5a33174..e3793a4 100644 --- a/ui/src/components/FileComponents/JavascriptOverviewCard.js +++ b/ui/src/components/FileOverviews/JavascriptOverview/JavascriptOverviewCard.js @@ -1,6 +1,6 @@ import React, { useState } from "react"; import { Input, Checkbox, Typography, Row, Col } from "antd"; -import "../../styles/ExiftoolOverviewCard.css" +import "../../../styles/ExiftoolOverviewCard.css" const { Text } = Typography; diff --git a/ui/src/components/FileOverviews/JavascriptOverview/JavascriptOverviewLanding.js b/ui/src/components/FileOverviews/JavascriptOverview/JavascriptOverviewLanding.js new file mode 100644 index 0000000..af843f0 --- /dev/null +++ b/ui/src/components/FileOverviews/JavascriptOverview/JavascriptOverviewLanding.js @@ -0,0 +1,46 @@ +import React, { useState, useEffect } from 'react'; +import { Collapse, Typography } from 'antd'; +import JavascriptOverviewCard from './JavascriptOverviewCard'; + +const { Text } = Typography; + +const JavascriptOverviewLanding = ({ selectedNodeData, expandAll }) => { + const [activeKey, setActiveKey] = useState([]); + + useEffect(() => { + setActiveKey(expandAll ? ["1"] : []); + }, [expandAll]); + + if (!selectedNodeData || !selectedNodeData.scan || !selectedNodeData.scan.javascript) { + return null; + } + + const jsData = selectedNodeData.scan.javascript; + const scriptLength = jsData.script_length_bytes + ? `${jsData.script_length_bytes} bytes` + : "(Length calculation not supported by this release of Strelka)"; + + return ( + setActiveKey(keys)} + style={{ width: "100%", marginBottom: "10px" }} + > + + JavaScript +
+ Script Length: {scriptLength} +
+
+ } + key="1" + > + + + + ); +}; + +export default JavascriptOverviewLanding; diff --git a/ui/src/components/FileOverviews/JsonView/JsonViewLanding.js b/ui/src/components/FileOverviews/JsonView/JsonViewLanding.js new file mode 100644 index 0000000..fa08735 --- /dev/null +++ b/ui/src/components/FileOverviews/JsonView/JsonViewLanding.js @@ -0,0 +1,90 @@ +import React, { useState } from "react"; + +import { Collapse, Typography, Input } from "antd"; +import ReactJson from "react-json-view"; + +const { Text } = Typography; + +const JsonViewLanding = ({ jsonData }) => { + const [filterQuery, setFilterQuery] = useState(""); + + const filterValues = (json, query) => { + if (!query) return json; + + let result = Array.isArray(json) ? [] : {}; + + if (typeof json === "object") { + for (const key of Object.keys(json)) { + const value = json[key]; + // Recursively find matches in nested objects/arrays + if (typeof value === 'object') { + const filteredChild = filterValues(value, query); + if (filteredChild && Object.keys(filteredChild).length !== 0) { + // If there is a match in children, include this key in the result + result[key] = filteredChild; + } + } else if (typeof value === 'string' && value.toLowerCase().includes(query.toLowerCase())) { + // Direct matches with the string representation of the value are included + result[key] = value; + } + } + } else if (typeof json === 'string' && json.toLowerCase().includes(query.toLowerCase())) { + // If this is a string and it matches, return it directly. + return json; + } + + // If we're working with an array after filtering, filter out any empty objects or arrays. + if (Array.isArray(result)) { + result = result.filter(item => typeof item === 'object' ? Object.keys(item).length > 0 : true); + } + + // Return an empty object/array if no matches found, + // or an object/array only containing matching keys/values. + return result; + }; + + const filteredJsonData = filterValues(jsonData, filterQuery); + + return ( + + + JSON View +
+ Raw Strelka data, including scanners not yet available in Card + view. +
+ + } + key="1" + > + setFilterQuery(e.target.value)} + style={{ + width: "100%", + padding: "10px", + margin: "0 0 20px 0", + }} + /> + { + if (field.name === "scan") { + return false; + } + if (typeof field.src !== "object" || Array.isArray(field.src)) { + return false; + } + return field.level > 2; + }} + /> +
+
+ ); +}; + +export default JsonViewLanding; diff --git a/ui/src/components/FileOverviews/OcrOverview/OcrOverviewCard.js b/ui/src/components/FileOverviews/OcrOverview/OcrOverviewCard.js new file mode 100644 index 0000000..d8e3bfb --- /dev/null +++ b/ui/src/components/FileOverviews/OcrOverview/OcrOverviewCard.js @@ -0,0 +1,167 @@ +import React, { useState } from "react"; +import { Checkbox, Input, Row, Col, Modal, Button, Tooltip, Typography } from "antd"; +import "../../../styles/OcrOverviewCard.css"; + +const { Text } = Typography; + +const OcrOverviewCard = ({ data }) => { + const [isModalVisible, setIsModalVisible] = useState(false); + const [wrapText, setWrapText] = useState(false); + const [trimText, setTrimText] = useState(true); + const [filter, setFilter] = useState(""); + const [isBlurred, setIsBlurred] = useState(data.scan.qr ? true : false); // State to manage blur for QR codes + const [useHumanReadable, setUseHumanReadable] = useState(true); // State to toggle between text array and string_text + + const showModal = () => { + // Only show modal if the image is not blurred + if (!isBlurred) { + setIsModalVisible(true); + } + }; + const handleCancel = () => setIsModalVisible(false); + const toggleBlur = () => setIsBlurred(!isBlurred); + + let texts = !useHumanReadable + ? Array.isArray(data.scan.ocr?.text) + ? data.scan.ocr.text + : [data.scan.ocr?.text || ""] + : [data.scan.ocr?.string_text || ""]; + const base64Thumbnail = data.scan.ocr?.base64_thumbnail; + + // Function to trim trailing whitespace or empty lines from a single line of text + const trimLine = (line) => (trimText ? line.replace(/\s+$/, "") : line); + + // Function to trim all text content if it's not already an array + texts = texts.map(trimLine); + + // Placeholder for Thumbnail in case its disabled / not functioning + const ThumbnailPlaceholder = () => { + return
; + }; + + // Conditional styling for blurred image (QR codes) + const imageStyle = isBlurred + ? { + filter: "blur(4px)", + cursor: "pointer", + } + : { + cursor: "pointer", + }; + + // Function to create line numbers and corresponding text + const renderTextLines = (texts) => { + let lineNumber = 1; // Initialize line number + const lowerCaseFilter = filter.toLowerCase(); // Convert filter to lower case + return texts.flatMap((textContent) => { + // Split each text block by new lines and filter based on the user's input + const lines = textContent + .split(/\r?\n/) + .filter((line) => !filter || line.toLowerCase().includes(lowerCaseFilter)); // Convert line to lower case + // Map over each line and return a table row while incrementing the line number + return lines.map((line) => ( + + {lineNumber++} + + {line} + + + )); + }); + }; + + + return ( +
+ + + setFilter(e.target.value)} + style={{ width: "100%" }} + /> + + + {data.scan.ocr?.string_text && ( + + setUseHumanReadable(e.target.checked)} + style={{ marginLeft: "10px" }} + > + Original + + + )} + + setWrapText(e.target.checked)} + > + Wrap + + + + setTrimText(e.target.checked)} + > + Trim + + + + + + + + {renderTextLines(texts)} +
+ + + {base64Thumbnail ? ( +
+ Email Preview + {isBlurred && ( +
+ + + +
+ )} + + Email Preview (Expanded) + +
+ ) : ( + + )} + +
+
+ ); +}; + +export default OcrOverviewCard; diff --git a/ui/src/components/FileOverviews/OcrOverview/OcrOverviewLanding.js b/ui/src/components/FileOverviews/OcrOverview/OcrOverviewLanding.js new file mode 100644 index 0000000..13eea70 --- /dev/null +++ b/ui/src/components/FileOverviews/OcrOverview/OcrOverviewLanding.js @@ -0,0 +1,75 @@ +import React, { useState, useEffect } from 'react'; +import { Collapse, Typography, Tag } from 'antd'; +import OcrOverviewCard from './OcrOverviewCard'; + +const { Text } = Typography; + +const OcrOverviewLanding = ({ selectedNodeData, expandAll }) => { + const [activeKey, setActiveKey] = useState([]); + + useEffect(() => { + setActiveKey(expandAll ? ["1"] : []); + }, [expandAll]); + + if (!selectedNodeData || !selectedNodeData.scan || !selectedNodeData.scan.ocr) { + return null; + } + + const ocrData = selectedNodeData.scan.ocr; + const ocrText = ocrData.text; + const textSummary = Array.isArray(ocrText) + ? ocrText.join(" ").substring(0, 47) + "..." + : typeof ocrText === "string" && ocrText.length > 0 + ? ocrText.substring(0, 47) + "..." + : "No Text"; + + const wordsCount = Array.isArray(ocrText) + ? ocrText.length + : typeof ocrText === "string" + ? ocrText.split(" ").length + : 0; + + const hasPreview = !!ocrData.base64_thumbnail; + + return ( + setActiveKey(keys)} + style={{ width: "100%", marginBottom: "10px" }} + > + +
+
+ Optical Character Recognition +
+ {textSummary} +
+
+
+
+ + Words Extracted: {wordsCount} + + + {hasPreview ? "Preview Available" : "No Preview"} + +
+
+ } + key="1" + > + + + + ); +}; + +export default OcrOverviewLanding; diff --git a/ui/src/components/FileComponents/PeOverviewCard.js b/ui/src/components/FileOverviews/PeOverview/PeOverviewCard.js similarity index 98% rename from ui/src/components/FileComponents/PeOverviewCard.js rename to ui/src/components/FileOverviews/PeOverview/PeOverviewCard.js index ce4d737..d1ddb0b 100644 --- a/ui/src/components/FileComponents/PeOverviewCard.js +++ b/ui/src/components/FileOverviews/PeOverview/PeOverviewCard.js @@ -8,7 +8,7 @@ import { } from "antd"; import { WarningOutlined, CheckCircleOutlined } from "@ant-design/icons"; -import "../../styles/PeOverviewCard.css"; +import "../../../styles/PeOverviewCard.css"; const { Text } = Typography; @@ -217,7 +217,7 @@ const PeOverviewCard = ({ data }) => { ( {item} @@ -232,7 +232,7 @@ const PeOverviewCard = ({ data }) => { ( {item} diff --git a/ui/src/components/FileOverviews/PeOverview/PeOverviewLanding.js b/ui/src/components/FileOverviews/PeOverview/PeOverviewLanding.js new file mode 100644 index 0000000..e08d1fc --- /dev/null +++ b/ui/src/components/FileOverviews/PeOverview/PeOverviewLanding.js @@ -0,0 +1,61 @@ +import React, { useState, useEffect } from 'react'; +import { Collapse, Typography, Tag } from 'antd'; +import PeOverviewCard from './PeOverviewCard'; + +const { Text } = Typography; + +const PeOverviewLanding = ({ selectedNodeData, expandAll }) => { + const [activeKey, setActiveKey] = useState([]); + + useEffect(() => { + setActiveKey(expandAll ? ["1"] : []); + }, [expandAll]); + + if (!selectedNodeData || !selectedNodeData.scan || !selectedNodeData.scan.pe) { + return null; + } + + const { file_info, compile_time, security } = selectedNodeData.scan.pe; + const productName = file_info?.product_name; + const isSigned = security ? "Signed" : "Not Signed"; + + return ( + setActiveKey(keys)} + style={{ width: "100%", marginBottom: "10px" }} + > + +
+ Executable Information +
+ Product: {productName} +
+ Compiled: {compile_time} +
+
+ + {isSigned} + + + } + key="1" + > + +
+
+ ); +}; + +export default PeOverviewLanding; diff --git a/ui/src/components/FileOverviews/QrOverview/QrOverviewCard.js b/ui/src/components/FileOverviews/QrOverview/QrOverviewCard.js new file mode 100644 index 0000000..ddfaa8a --- /dev/null +++ b/ui/src/components/FileOverviews/QrOverview/QrOverviewCard.js @@ -0,0 +1,56 @@ +import React, { useState } from "react"; +import { Input, Table, Typography } from "antd"; +import "../../../styles/IocOverviewCard.css"; + +const { Text } = Typography; + +const QrOverviewCard = ({ data }) => { + const [filter, setFilter] = useState(""); + + const columns = [ + { + title: "Data", + dataIndex: "data", + key: "data", + render: (text) => ( + + {text} + + ), + }, + ]; + + const processQrData = () => { + // Assuming data.scan.qr.data is an array of strings (URLs) + return data.scan.qr.data + .filter((url) => { + const searchTerm = filter.toLowerCase(); + return !filter || url.toLowerCase().includes(searchTerm); + }) + .map((data, index) => ({ + key: index, + data: data, + })); + }; + + const filteredQrData = processQrData(); + + return ( +
+ setFilter(e.target.value)} + style={{ width: "100%", marginBottom: 16 }} + /> + + + ); +}; + +export default QrOverviewCard; diff --git a/ui/src/components/FileOverviews/QrOverview/QrOverviewLanding.js b/ui/src/components/FileOverviews/QrOverview/QrOverviewLanding.js new file mode 100644 index 0000000..8f9092f --- /dev/null +++ b/ui/src/components/FileOverviews/QrOverview/QrOverviewLanding.js @@ -0,0 +1,55 @@ +import React, { useState, useEffect } from 'react'; +import { Collapse, Typography } from 'antd'; +import QrOverviewCard from './QrOverviewCard'; + +const { Text } = Typography; + +const QrOverviewLanding = ({ selectedNodeData, expandAll }) => { + const [activeKey, setActiveKey] = useState([]); + + useEffect(() => { + setActiveKey(expandAll ? ["1"] : []); + }, [expandAll]); + + if (!selectedNodeData || !selectedNodeData.scan || !selectedNodeData.scan.qr || !selectedNodeData.scan.qr.data) { + return null; + } + + const qrData = selectedNodeData.scan.qr.data; + const qrDataCount = qrData.length; + + return ( + setActiveKey(keys)} + defaultActiveKey={[]} + style={{ width: "100%", marginBottom: "10px" }} + > + +
+
+ QR Code Data +
+ {qrDataCount > 0 ? `QR Data Count: ${qrDataCount}` : "No QR Data"} +
+
+
+ + } + key="1" + > + +
+
+ ); +}; + +export default QrOverviewLanding; diff --git a/ui/src/components/FileOverviews/RarOverview/RarOverviewCard.js b/ui/src/components/FileOverviews/RarOverview/RarOverviewCard.js new file mode 100644 index 0000000..1a90330 --- /dev/null +++ b/ui/src/components/FileOverviews/RarOverview/RarOverviewCard.js @@ -0,0 +1,248 @@ +import React, { useState } from "react"; +import { + Table, + Typography, + Row, + Col, + Input, + Divider, + Tag, + Descriptions, + Card, +} from "antd"; +import { antdColors } from "../../../utils/colors"; + +const { Text } = Typography; + +// Utility function to format bytes into more readable formats +const formatBytes = (bytes, decimals = 2) => { + if (bytes === 0) return "0 Bytes"; + const k = 1024; + const dm = decimals < 0 ? 0 : decimals; + const sizes = ["B", "KB", "MB"]; + const i = Math.floor(Math.log(bytes) / Math.log(k)); + return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + " " + sizes[i]; +}; + +// Function to determine extraction color based on extracted and total files +const getExtractionColor = (extracted, total) => { + if (extracted === total && total > 0) { + return { color: antdColors.darkGreen }; + } else if (extracted > 0 && extracted < total) { + return { color: antdColors.deepOrange }; + } else { + return { color: antdColors.red }; + } +}; + +const RarOverviewCard = ({ data }) => { + const [filter, setFilter] = useState(""); + + // Check if files exist and filter based on user input + const files = data.scan.rar.files || []; + const filteredFiles = files + .filter( + (file) => + !filter || file.file_name.toLowerCase().includes(filter.toLowerCase()) + ) + .sort((a, b) => a.file_name.localeCompare(b.file_name)); // Initial sort by filename + + const columns = [ + { + title:
File Name
, + dataIndex: "file_name", + key: "file_name", + render: (text) => {text}, + sorter: (a, b) => a.file_name.localeCompare(b.file_name), + defaultSortOrder: "ascend", + width: 300, + }, + { + title:
File Size
, + dataIndex: "file_size", + key: "file_size", + render: (size) => ( + + {formatBytes(parseInt(size))} + + ), + sorter: (a, b) => parseInt(a.file_size) - parseInt(b.file_size), + width: 100, + }, + { + title:
Compression Rate
, + dataIndex: "compression_rate", + key: "compression_rate", + render: (rate) => ( + {rate.toFixed(2)}% + ), + sorter: (a, b) => a.compression_rate - b.compression_rate, + width: 150, + }, + { + title:
Encrypted
, + dataIndex: "encrypted", + key: "encrypted", + render: (encrypted) => ( + + {encrypted ? "Encrypted" : "Not Encrypted"} + + ), + sorter: (a, b) => a.encrypted - b.encrypted, + width: 120, + align: "center", + }, + { + title:
Extracted
, + dataIndex: "extracted", + key: "extracted", + render: (extracted) => ( + + {extracted ? "Yes" : "No"} + + ), + sorter: (a, b) => a.extracted - b.extracted, + width: 120, + align: "center", + }, + { + title:
Last Modified
, + dataIndex: "datetime", + key: "datetime", + render: (datetime) => ( + {datetime} + ), + sorter: (a, b) => new Date(a.datetime) - new Date(b.datetime), + width: 200, + }, + ]; + + const extracted = data.scan.rar.total.extracted; + const total = data.scan.rar.total.files; + const extractionColor = getExtractionColor(extracted, total); + + return ( +
+ Extraction Details + +
+ +
Extracted Files
+
+ {extracted}/{total} +
+
+ + + + + {total} + + + {extracted} + + + {data.scan.rar.compression_rate}% + + + {data.scan.rar.host_os} + + + + {data.scan.rar.elapsed.toFixed(3)} seconds + + + {data.scan.rar.flags && ( + + {data.scan.rar.flags.map((flag, index) => ( + + {flag} + + ))} + + )} + + + + + File Listing + + + setFilter(e.target.value)} + style={{ width: "100%", marginTop: "10px" }} + /> + + +
({ + ...file, + key: file.file_name + index, + }))} + pagination={{ pageSize: 10 }} + scroll={{ y: 240 }} + style={{ marginTop: "20px" }} + /> + + ); +}; + +export default RarOverviewCard; diff --git a/ui/src/components/FileOverviews/RarOverview/RarOverviewLanding.js b/ui/src/components/FileOverviews/RarOverview/RarOverviewLanding.js new file mode 100644 index 0000000..136479f --- /dev/null +++ b/ui/src/components/FileOverviews/RarOverview/RarOverviewLanding.js @@ -0,0 +1,61 @@ +import React, { useState, useEffect } from "react"; +import { Collapse, Typography, Tag } from "antd"; +import RarOverviewCard from "./RarOverviewCard"; + +const { Text } = Typography; + +const RarOverviewLanding = ({ selectedNodeData, expandAll }) => { + const [activeKey, setActiveKey] = useState([]); + + useEffect(() => { + setActiveKey(expandAll ? ['1'] : []); + }, [expandAll]); + + if (!selectedNodeData || !selectedNodeData.scan || !selectedNodeData.scan.rar) { + return null; + } + + const rarData = selectedNodeData.scan.rar; + const fileCount = rarData.total.files || 0; + const extractedCount = rarData.total.extracted || 0; + const extractionStatus = fileCount > 0 && extractedCount === 0 ? "Could Not Extract Files" : "Extracted Files"; + + return ( + + +
+ RAR Details +
+ Total Files: {fileCount} +
+
+ + {extractionStatus} + + + } + key="1" + > + +
+
+ ); +}; + +export default RarOverviewLanding; diff --git a/ui/src/components/FileOverviews/SevenZipOverview/SevenZipOverviewCard.js b/ui/src/components/FileOverviews/SevenZipOverview/SevenZipOverviewCard.js new file mode 100644 index 0000000..3894d35 --- /dev/null +++ b/ui/src/components/FileOverviews/SevenZipOverview/SevenZipOverviewCard.js @@ -0,0 +1,193 @@ +import React, { useState } from "react"; +import { + Table, + Typography, + Row, + Col, + Input, + Divider, + Tag, + Descriptions, + Card, +} from "antd"; +import { antdColors } from "../../../utils/colors"; + +const { Text } = Typography; + +// Utility function to format bytes into more readable formats +const formatBytes = (bytes, decimals = 2) => { + if (bytes === 0) return "0 Bytes"; + const k = 1024; + const dm = decimals < 0 ? 0 : decimals; + const sizes = ["B", "KB", "MB"]; + const i = Math.floor(Math.log(bytes) / Math.log(k)); + return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + " " + sizes[i]; +}; + +// Function to determine extraction color based on extracted and total files +const getExtractionColor = (extracted, total) => { + if (extracted === total && total > 0) { + return { color: antdColors.darkGreen }; + } else if (extracted > 0 && extracted < total) { + return { color: antdColors.deepOrange }; + } else { + return { color: antdColors.red }; + } +}; + +const SevenZipOverviewCard = ({ data }) => { + const [filter, setFilter] = useState(""); + + // Check if files exist and filter based on user input + const files = data.scan.seven_zip.files || []; + const filteredFiles = files + .filter( + (file) => + !filter || file.filename.toLowerCase().includes(filter.toLowerCase()) + ) + .sort((a, b) => a.filename.localeCompare(b.filename)); // Initial sort by filename + + const columns = [ + { + title:
File Name
, + dataIndex: "filename", + key: "filename", + render: (text) => {text}, + sorter: (a, b) => a.filename.localeCompare(b.filename), + defaultSortOrder: "ascend", + width: 300, + }, + { + title:
File Size
, + dataIndex: "size", + key: "size", + render: (size) => ( + + {formatBytes(parseInt(size))} + + ), + sorter: (a, b) => parseInt(a.size) - parseInt(b.size), + width: 100, + }, + { + title:
Last Modified
, + dataIndex: "datetime", + key: "datetime", + render: (datetime) => ( + {datetime} + ), + sorter: (a, b) => new Date(a.datetime) - new Date(b.datetime), + width: 200, + }, + ]; + + const extracted = data.scan.seven_zip.total.extracted; + const total = data.scan.seven_zip.total.files; + const extractionColor = getExtractionColor(extracted, total); + + return ( +
+ Extraction Details + +
+ +
Extracted Files
+
+ {extracted}/{total} +
+
+ + + + + {total} + + + {extracted} + + + + {data.scan.seven_zip?.meta?.["7zip_version"] || "Not available"} + + + + + {data.scan.seven_zip.elapsed.toFixed(3)} seconds + + + + {data.scan.seven_zip?.flags?.map((flag, index) => ( + + {flag} + + )) || + No Additional Details + } + + + + + + + File Listing + + + setFilter(e.target.value)} + style={{ width: "100%", marginTop: "10px" }} + /> + + +
({ + ...file, + key: file.filename + index, + }))} + pagination={{ pageSize: 10 }} + scroll={{ y: 240 }} + style={{ marginTop: "20px" }} + /> + + ); +}; + +export default SevenZipOverviewCard; diff --git a/ui/src/components/FileOverviews/SevenZipOverview/SevenZipOverviewLanding.js b/ui/src/components/FileOverviews/SevenZipOverview/SevenZipOverviewLanding.js new file mode 100644 index 0000000..052bc29 --- /dev/null +++ b/ui/src/components/FileOverviews/SevenZipOverview/SevenZipOverviewLanding.js @@ -0,0 +1,61 @@ +import React, { useState, useEffect } from 'react'; +import { Collapse, Typography, Tag } from 'antd'; +import SevenZipOverviewCard from './SevenZipOverviewCard'; + +const { Text } = Typography; + +const SevenZipOverviewLanding = ({ selectedNodeData, expandAll }) => { + const [activeKey, setActiveKey] = useState([]); + + useEffect(() => { + setActiveKey(expandAll ? ['1'] : []); + }, [expandAll]); + + if (!selectedNodeData || !selectedNodeData.scan || !selectedNodeData.scan.seven_zip) { + return null; + } + + const sevenZipData = selectedNodeData.scan.seven_zip; + const fileCount = sevenZipData.total.files || 0; + const extractedCount = sevenZipData.total.extracted || 0; + const extractionStatus = extractedCount === 0 ? "Could Not Extract Files" : "Extracted Files"; + + return ( + + +
+ 7-Zip Details +
+ Total Files: {fileCount} +
+
+ + {extractionStatus} + + + } + key="1" + > + +
+
+ ); +}; + +export default SevenZipOverviewLanding; diff --git a/ui/src/components/FileComponents/IocOverviewCard.js b/ui/src/components/FileOverviews/SubmissionIocs/SubmissionIocOverviewCard.js similarity index 82% rename from ui/src/components/FileComponents/IocOverviewCard.js rename to ui/src/components/FileOverviews/SubmissionIocs/SubmissionIocOverviewCard.js index 7a6f8a6..4e67ac7 100644 --- a/ui/src/components/FileComponents/IocOverviewCard.js +++ b/ui/src/components/FileOverviews/SubmissionIocs/SubmissionIocOverviewCard.js @@ -1,11 +1,12 @@ import React, { useState } from "react"; import { Input, Table, Typography } from "antd"; -import "../../styles/IocOverviewCard.css"; +import "../../../styles/IocOverviewCard.css"; const { Text } = Typography; const IocOverviewCard = ({ data }) => { const [filter, setFilter] = useState(""); + const [pageSize, setPageSize] = useState(10); const columns = [ { @@ -54,11 +55,16 @@ const IocOverviewCard = ({ data }) => { })); }; + const handleTableChange = (pagination) => { + // Update pageSize when table pagination changes + setPageSize(pagination.pageSize); + }; + + const filteredIocs = processIocData(); return (
- {" "} setFilter(e.target.value)} @@ -67,9 +73,10 @@ const IocOverviewCard = ({ data }) => {
); diff --git a/ui/src/components/FileOverviews/SubmissionIocs/SubmissionIocsLanding.js b/ui/src/components/FileOverviews/SubmissionIocs/SubmissionIocsLanding.js new file mode 100644 index 0000000..4caddea --- /dev/null +++ b/ui/src/components/FileOverviews/SubmissionIocs/SubmissionIocsLanding.js @@ -0,0 +1,58 @@ +import React, { useState, useEffect } from "react"; +import { Collapse, Typography, Tag } from "antd"; +import IocOverviewCard from "./SubmissionIocOverviewCard"; + +const { Text } = Typography; + +const FilePotentialIocsOverview = ({ selectedNodeData, expandAll }) => { + const iocs = selectedNodeData?.iocs; + const [activeKey, setActiveKey] = useState([]); + + useEffect(() => { + setActiveKey(expandAll ? ["1"] : []); + }, [expandAll]); + + if (!iocs || iocs.length === 0) { + return null; + } + + const firstIoc = iocs[0]?.ioc || "N/A"; + const iocsCount = iocs.length; + const additionalIocs = iocsCount > 1 ? ` and ${iocsCount - 1} more` : ""; + + return ( + setActiveKey(keys)} + style={{ width: "100%", marginBottom: "10px" }} + > + +
+ Indicators of Compromise (IOCs) +
+ {firstIoc} + {additionalIocs} +
+
+ + {iocsCount} Potential IOCs Extracted + + + } + key="1" + > + +
+
+ ); +}; + +export default FilePotentialIocsOverview; diff --git a/ui/src/components/FileOverviews/TlshOverview/TlshLanding.js b/ui/src/components/FileOverviews/TlshOverview/TlshLanding.js new file mode 100644 index 0000000..6bcfbfb --- /dev/null +++ b/ui/src/components/FileOverviews/TlshOverview/TlshLanding.js @@ -0,0 +1,50 @@ +import React, { useState, useEffect } from "react"; +import { Collapse, Tag, Typography } from "antd"; +import TlshOverviewCard from "./TlshOverviewCard"; + +const { Text } = Typography; + +const FileTlshLanding = ({ selectedNodeData, expandAll }) => { + const [activeKey, setActiveKey] = useState([]); + + useEffect(() => { + setActiveKey(expandAll ? ["1"] : []); + }, [expandAll]); + + const tlshData = selectedNodeData?.scan?.tlsh?.match; + + const getTlshRating = (score) => { + if (score <= 30) return { label: "Very Similar", color: "red" }; + if (score <= 60) return { label: "Somewhat Similar", color: "volcano" }; + if (score <= 120) return { label: "Moderately Different", color: "orange" }; + if (score <= 180) return { label: "Quite Different", color: "gold" }; + return { label: "Very Different", color: "green" }; + }; + + return tlshData ? ( + + + TLSH Related Match +
+ + {getTlshRating(tlshData.score).label} + +
+ + } + key="1" + > + +
+
+ ) : null; +}; + +export default FileTlshLanding; diff --git a/ui/src/components/FileOverviews/TlshOverview/TlshOverviewCard.js b/ui/src/components/FileOverviews/TlshOverview/TlshOverviewCard.js new file mode 100644 index 0000000..0c7a065 --- /dev/null +++ b/ui/src/components/FileOverviews/TlshOverview/TlshOverviewCard.js @@ -0,0 +1,161 @@ +import React from "react"; +import { Typography, Tag } from "antd"; +import { antdColors } from "../../../utils/colors"; +import "../../../styles/TlshOverviewCard.css"; + +const { Text } = Typography; + +const TlshOverviewCard = ({ data }) => { + const { match } = data.scan.tlsh; + const score = match.score; + const family = match.family; + const matchedTlsh = match.tlsh; + + // Define the indexes where we want to show the scores + const scorePositions = { + 0: ["0", "Very Similar"], + 6: ["75", "Somewhat Similar"], + 14: ["150", "Moderately Different"], + 22: ["225", "Quite Different"], + 29: ["300+", "Very Different"], + }; + + // Logic to determine the similarity description based on the score + const getSimilarityDescription = (score) => { + if (score < 30) return "Very Similar"; + if (score < 75) return "Somewhat Similar"; + if (score < 150) return "Moderately Different"; + if (score < 225) return "Quite Different"; + return "Very Different"; // Assuming scores higher than 225 are 'Very Different' + }; + + // Function to get color based on similarity description + const getColorForDescription = (description) => { + const colorMapping = { + "Very Similar": "red", + "Somewhat Similar": "volcano", + "Moderately Different": "orange", + "Quite Different": "gold", + "Very Different": "lime", + }; + return colorMapping[description] || antdColors.gray; + }; + + // Construct the sentence with the provided values + const tlshDescriptionSentence = ( + + This file has a TLSH match against the family{" "} + + {family} + {" "} + with the TLSH{" "} + + {matchedTlsh} + +

+ The TLSH for this file was given a comparison score of{" "} + + {score} + + which indicates the two files may be{" "} + + {getSimilarityDescription(score)} + +

+
+ + The results provided are an estimation of similarity and may not be completely accurate. The accuracy of the TLSH comparison can vary significantly between different types of files, typically providing more reliable results for executable files than for text files. + +
+
+ ); + + // antd color gradient + const colorGradient = [ + antdColors.red, // Very Similar + antdColors.volcano, + antdColors.orange, + antdColors.gold, + antdColors.lime, + antdColors.green, // Very Different + ]; + + // Assume 300 is the highest score for TLSH comparison (It's not, but let's pretend) + const maxScore = 300; + // Divide the slider into 'n' parts + const numberOfParts = 30; + + // Calculate the appropriate index for the actual score to be displayed + const scoreIndex = + score >= maxScore + ? numberOfParts - 1 + : Math.floor((score / maxScore) * numberOfParts); + // Define the keys where we want to show the scores + const scoreKeys = Object.keys(scorePositions).map(Number); + + // Update the color gradient logic to handle scores of 300 or higher + const getColorForIndex = (index) => { + if (index === numberOfParts - 1 && score >= maxScore) { + return antdColors.green; + } + return index <= scoreIndex + ? colorGradient[ + Math.floor((colorGradient.length - 1) * (index / (numberOfParts - 1))) + ] + : antdColors.lightGray; + }; + + return ( +
+
+ + TLSH Comparison Scale + + (Lower = More Similar) +
+
+ {Array.from({ length: numberOfParts }).map((_, index) => { + const isActive = index <= scoreIndex; + const backgroundColor = getColorForIndex(index); + const boxClass = `slider-box ${isActive ? "active" : ""} ${ + index === scoreIndex ? "score-box" : "" + }`; + + return ( +
+ {/* Render the actual score inside the box where it resides */} + {index === scoreIndex && ( + {score} + )} + {/* Render the tick values underneath the box its aligned to */} + {scoreKeys.includes(index) && ( +
+ {scorePositions[index][0]} +
+ {scorePositions[index][1]} +
+ )} +
+ ); + })} +
+
+
+ {tlshDescriptionSentence} +
+
+
+ ); +}; + +export default TlshOverviewCard; \ No newline at end of file diff --git a/ui/src/components/FileComponents/VbOverviewCard.js b/ui/src/components/FileOverviews/VbOverview/VbOverviewCard.js similarity index 98% rename from ui/src/components/FileComponents/VbOverviewCard.js rename to ui/src/components/FileOverviews/VbOverview/VbOverviewCard.js index 61f5b65..5e390fb 100644 --- a/ui/src/components/FileComponents/VbOverviewCard.js +++ b/ui/src/components/FileOverviews/VbOverview/VbOverviewCard.js @@ -1,6 +1,6 @@ import React, { useState } from "react"; import { Input, Checkbox, Typography, Row, Col } from "antd"; -import "../../styles/ExiftoolOverviewCard.css"; +import "../../../styles/ExiftoolOverviewCard.css"; const { Text } = Typography; diff --git a/ui/src/components/FileOverviews/VbOverview/VbOverviewLanding.js b/ui/src/components/FileOverviews/VbOverview/VbOverviewLanding.js new file mode 100644 index 0000000..8d577bd --- /dev/null +++ b/ui/src/components/FileOverviews/VbOverview/VbOverviewLanding.js @@ -0,0 +1,45 @@ +import React, { useState, useEffect } from 'react'; +import { Collapse, Typography } from 'antd'; +import VbOverviewCard from './VbOverviewCard'; + +const { Text } = Typography; + +const VbOverviewLanding = ({ selectedNodeData, expandAll }) => { + const [activeKey, setActiveKey] = useState([]); + + useEffect(() => { + setActiveKey(expandAll ? ['1'] : []); + }, [expandAll]); + + if (!selectedNodeData || !selectedNodeData.scan || !selectedNodeData.scan.vb) { + return null; + } + + const vbData = selectedNodeData.scan.vb; + const scriptLength = vbData.script_length_bytes || 0; + + return ( + + + Visual Basic +
+ Script Length: {scriptLength} bytes +
+ + } + key="1" + > + +
+
+ ); +}; + +export default VbOverviewLanding; diff --git a/ui/src/components/FileOverviews/XmlOverview/XmlOverviewCard.js b/ui/src/components/FileOverviews/XmlOverview/XmlOverviewCard.js new file mode 100644 index 0000000..92bafdb --- /dev/null +++ b/ui/src/components/FileOverviews/XmlOverview/XmlOverviewCard.js @@ -0,0 +1,147 @@ +import React, { useState } from "react"; +import { Descriptions, Typography, List, Input, Row, Col } from "antd"; +import "../../../styles/ExiftoolOverviewCard.css"; + +const { Text } = Typography; + +const XmlOverviewCard = ({ xmlData }) => { + const [filter, setFilter] = useState(""); + + // Handles filtering and processing of list items (objects or strings) + const filterData = (dataSource) => { + const searchTerm = filter.toLowerCase(); + return dataSource.filter((item) => { + const content = typeof item === "object" ? JSON.stringify(item) : item; + return !filter || content.toLowerCase().includes(searchTerm); + }); + }; + + // Function to render item content based on whether it is a string or object + const renderItemContent = (item) => { + if (typeof item === "object") { + return ( +
+ {Object.entries(item).map(([key, value], index) => { + // Exclude standalone "Type" entries from being displayed + if ( + key.toLowerCase() === "type" && + Object.keys(item).length === 1 + ) { + return null; + } + return ( + +
+ {key}: + + + + {value.toString()} + + + + ); + })} + + ); + } + return ( + + {item} + + ); + }; + + return ( +
+ setFilter(e.target.value)} + style={{ marginBottom: "10px" }} + /> + + + {xmlData.doc_type && ( + + + {xmlData.doc_type} + + + )} + {xmlData.version && ( + + + {xmlData.version} + + + )} + {xmlData.namespaces?.length > 0 && ( + + {xmlData.namespaces.map((ns, index) => ( + + {ns} + + ))} + + )} + {xmlData.total && ( + + {xmlData.total.tags} + + )} + {xmlData.total && ( + + {xmlData.total.extracted} + + )} + + + {xmlData.emitted_content && xmlData.emitted_content.length > 0 ? ( + ( + {renderItemContent(item)} + )} + style={{ maxHeight: "200px", overflow: "auto" }} + /> + ) : ( + No Data + )} + + + + {xmlData.tags && xmlData.tags.length > 0 ? ( + ( + {renderItemContent(item)} + )} + style={{ maxHeight: "200px", overflow: "auto" }} + /> + ) : ( + No Data + )} + + + + {xmlData.tag_data && xmlData.tag_data.length > 0 ? ( + ( + {renderItemContent(item)} + )} + style={{ maxHeight: "200px", overflow: "auto" }} + /> + ) : ( + No Data + )} + + +
+ ); +}; + +export default XmlOverviewCard; diff --git a/ui/src/components/FileOverviews/XmlOverview/XmlOverviewLanding.js b/ui/src/components/FileOverviews/XmlOverview/XmlOverviewLanding.js new file mode 100644 index 0000000..c362bb5 --- /dev/null +++ b/ui/src/components/FileOverviews/XmlOverview/XmlOverviewLanding.js @@ -0,0 +1,45 @@ +import React, { useState, useEffect } from 'react'; +import { Collapse, Typography } from 'antd'; +import XmlOverviewCard from './XmlOverviewCard'; + +const { Text } = Typography; + +const XmlOverviewLanding = ({ selectedNodeData, expandAll }) => { + const [activeKey, setActiveKey] = useState([]); + + useEffect(() => { + setActiveKey(expandAll ? ['1'] : []); + }, [expandAll]); + + if (!selectedNodeData || !selectedNodeData.scan || !selectedNodeData.scan.xml) { + return null; + } + + const xmlData = selectedNodeData.scan.xml; + const emittedContentCount = xmlData.emitted_content ? xmlData.emitted_content.length : 0; + + return ( + + + XML +
+ Emitted Content Count: {emittedContentCount} +
+ + } + key="1" + > + +
+
+ ); +}; + +export default XmlOverviewLanding; diff --git a/ui/src/components/FileOverviews/YaraOverview/YaraOverviewLanding.js b/ui/src/components/FileOverviews/YaraOverview/YaraOverviewLanding.js new file mode 100644 index 0000000..e0b0f94 --- /dev/null +++ b/ui/src/components/FileOverviews/YaraOverview/YaraOverviewLanding.js @@ -0,0 +1,64 @@ +import React, { useState } from "react"; +import { Collapse, Tag, Typography } from "antd"; +import YaraTypeOverviewCard from "./YaraTypeOverviewCard"; +import { antdColors } from "../../../utils/colors"; + +const { Text } = Typography; + +const FileYaraOverviewLanding = ({ data, onFileYaraSelect }) => { + const [filterApplied, setFilterApplied] = useState(false); + + const handleYaraSelect = (selectedYara) => { + setFilterApplied(!!selectedYara); + onFileYaraSelect(selectedYara); + }; + + const borderStyle = filterApplied + ? { + // Styles when the filter is applied + border: `2px solid ${antdColors.purple}50`, + borderRadius: "8px", + boxShadow: "0 2px 8px rgba(0, 0, 0, 0.1)", + padding: "3px", + transition: "all 0.3s", // Transition for both applying and removing the filter + } + : { + // Styles when the filter is not applied (could potentially add styles for the normal state if needed) + transition: "all 0.3s", + }; + + return ( + + + File YARA Matches + {filterApplied && ( + + Filter Applied + + )} + + } + key="1" + > + + + + ); +}; + +export default FileYaraOverviewLanding; diff --git a/ui/src/components/FileComponents/YaraTypeOverviewCard.js b/ui/src/components/FileOverviews/YaraOverview/YaraTypeOverviewCard.js similarity index 92% rename from ui/src/components/FileComponents/YaraTypeOverviewCard.js rename to ui/src/components/FileOverviews/YaraOverview/YaraTypeOverviewCard.js index e83c255..76bdebd 100644 --- a/ui/src/components/FileComponents/YaraTypeOverviewCard.js +++ b/ui/src/components/FileOverviews/YaraOverview/YaraTypeOverviewCard.js @@ -1,7 +1,7 @@ import React, { useState } from "react"; import { Tag, Tooltip, Typography, Row } from "antd"; import { WarningOutlined, BookOutlined } from "@ant-design/icons"; -import { antdColors } from "../../utils/colors"; +import { antdColors } from "../../../utils/colors"; const { Text } = Typography; @@ -48,9 +48,14 @@ const YaraTypeOverviewCard = ({ data, onFileYaraSelect }) => { yaraMatches.forEach((match) => { if (yaraCounts[match]) { yaraCounts[match].count++; - yaraCounts[match].files.push(response.file.name || response.scan.hash.md5); + yaraCounts[match].files.push( + response.file.name || response.scan.hash.md5 + ); } else { - yaraCounts[match] = { count: 1, files: [response.file.name || response.scan.hash.md5] }; + yaraCounts[match] = { + count: 1, + files: [response.file.name || response.scan.hash.md5], + }; } }); }); @@ -79,12 +84,17 @@ const YaraTypeOverviewCard = ({ data, onFileYaraSelect }) => { width: "95%", justifyContent: "space-between", alignItems: "center", - background: "none", + background: + selectedYara === item.yara + ? isSuspicious + ? `${antdColors.deepOrange}20` + : `${antdColors.blue}20` + : "none", cursor: "pointer", border: selectedYara === item.yara ? `1px solid ${ - isSuspicious ? antdColors.deepOrange : antdColors.darkGray + isSuspicious ? antdColors.deepOrange : antdColors.blue }` : "none", }} diff --git a/ui/src/components/FileOverviews/ZipOverview/ZipOverviewCard.js b/ui/src/components/FileOverviews/ZipOverview/ZipOverviewCard.js new file mode 100644 index 0000000..9adaa20 --- /dev/null +++ b/ui/src/components/FileOverviews/ZipOverview/ZipOverviewCard.js @@ -0,0 +1,251 @@ +import React, { useState } from "react"; +import { + Table, + Typography, + Row, + Col, + Input, + Divider, + Tag, + Descriptions, + Card, +} from "antd"; +import { antdColors } from "../../../utils/colors"; + +const { Text } = Typography; + +// Utility function to format bytes into more readable formats +const formatBytes = (bytes, decimals = 2) => { + if (bytes === 0) return "0 Bytes"; + const k = 1024; + const dm = decimals < 0 ? 0 : decimals; + const sizes = ["B", "KB", "MB"]; + const i = Math.floor(Math.log(bytes) / Math.log(k)); + return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + " " + sizes[i]; +}; + +// Function to determine style based on compression rate +const getCompressionRateStyle = (rate) => { + if (rate > 90) { + return { color: antdColors.red, fontWeight: "bold" }; + } else { + return { color: antdColors.darkGreen, fontWeight: "bold" }; + } +}; + +// Function to determine extraction color based on extracted and total files +const getExtractionColor = (extracted, total) => { + if (extracted === total) { + return { color: antdColors.darkGreen }; + } else if (extracted > 0 && extracted < total) { + return { color: antdColors.deepOrange }; + } else { + return { color: antdColors.red }; + } +}; + +const ZipOverviewCard = ({ data }) => { + const [filter, setFilter] = useState(""); + + // Filter files based on user input + const filteredFiles = data.scan.zip.files + .filter( + (file) => + !filter || file.file_name.toLowerCase().includes(filter.toLowerCase()) + ) + .sort((a, b) => a.file_name.localeCompare(b.file_name)); // Initial sort by filename + + const columns = [ + { + title:
File Name
, + dataIndex: "file_name", + key: "file_name", + render: (text) => {text}, + sorter: (a, b) => a.file_name.localeCompare(b.file_name), + defaultSortOrder: "ascend", + width: 200, + }, + { + title:
File Size
, + dataIndex: "file_size", + key: "file_size", + render: (size) => ( + + {formatBytes(size)} + + ), + sorter: (a, b) => a.file_size - b.file_size, + width: 100, + }, + { + title:
Compression Size
, + dataIndex: "compression_size", + key: "compression_size", + render: (size) => ( + + {formatBytes(size)} + + ), + sorter: (a, b) => a.compression_size - b.compression_size, + width: 150, + }, + { + title:
Compression Rate
, + dataIndex: "compression_rate", + key: "compression_rate", + render: (rate) => ( + + {rate.toFixed(2)}% + + ), + sorter: (a, b) => a.compression_rate - b.compression_rate, + width: 150, + }, + { + title:
Extracted
, + dataIndex: "extracted", + key: "extracted", + render: (extracted) => ( + + {extracted ? "Extracted" : "Not Extracted"} + + ), + sorter: (a, b) => a.extracted - b.extracted, + width: 120, + align: "center", + }, + { + title:
Encrypted
, + dataIndex: "encrypted", + key: "encrypted", + render: (encrypted) => ( + + {encrypted ? "Encrypted" : "Not Encrypted"} + + ), + sorter: (a, b) => a.encrypted - b.encrypted, + width: 120, + align: "center", + }, + ]; + + + const extracted = data.scan.zip.total.extracted; + const total = data.scan.zip.total.files; + const extractionColor = getExtractionColor(extracted, total); + + return ( +
+ Extraction Details + +
+ +
Extracted Files
+
+ {extracted}/{total} +
+
+ + + + + {total} + + + {extracted} + + + + {data.scan.zip.compression_rate}% + + + + + {data.scan.zip.elapsed.toFixed(3)} seconds + + + + + + + File Listing + + + setFilter(e.target.value)} + style={{ width: "100%", marginTop: "10px" }} + /> + + +
({ + ...file, + key: file.file_name + index, + }))} + pagination={{ pageSize: 10 }} + scroll={{ y: 240 }} + style={{ marginTop: "20px" }} + /> + + ); +}; + +export default ZipOverviewCard; diff --git a/ui/src/components/FileOverviews/ZipOverview/ZipOverviewLanding.js b/ui/src/components/FileOverviews/ZipOverview/ZipOverviewLanding.js new file mode 100644 index 0000000..45ce73f --- /dev/null +++ b/ui/src/components/FileOverviews/ZipOverview/ZipOverviewLanding.js @@ -0,0 +1,61 @@ +import React, { useState, useEffect } from 'react'; +import { Collapse, Typography, Tag } from 'antd'; +import ZipOverviewCard from './ZipOverviewCard'; + +const { Text } = Typography; + +const ZipOverviewLanding = ({ selectedNodeData, expandAll }) => { + const [activeKey, setActiveKey] = useState([]); + + useEffect(() => { + setActiveKey(expandAll ? ['1'] : []); + }, [expandAll]); + + if (!selectedNodeData || !selectedNodeData.scan || !selectedNodeData.scan.zip) { + return null; + } + + const zipData = selectedNodeData.scan.zip; + const fileCount = zipData.total.files || 0; + const extractedCount = zipData.total.extracted || 0; + const extractionStatus = fileCount > 0 && extractedCount === 0 ? "Could Not Extract Files" : "Extracted Files"; + + return ( + + +
+ Zip Details +
+ Total Files: {fileCount} +
+
+ + {extractionStatus} + + + } + key="1" + > + +
+
+ ); +}; + +export default ZipOverviewLanding; diff --git a/ui/src/components/GenericLogo.js b/ui/src/components/GenericLogo.js index f25d0e9..100d8fc 100644 --- a/ui/src/components/GenericLogo.js +++ b/ui/src/components/GenericLogo.js @@ -1,6 +1,14 @@ -import React from "react"; +import React, { useState } from "react"; const GenericLogo = () => { + const [darkMode] = useState(() => { + const savedMode = localStorage.getItem('darkMode'); + return savedMode === 'true' ? true : false; + }); + + const imageStyle = darkMode ? { filter: 'invert(100%) hue-rotate(180deg)' } : {}; + + return ( { height="129" x="0" y="0" + style={imageStyle} href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIEAAACBCAYAAADnoNlQAAAABGdBTUEAALGPC/xhBQAAACBjSFJN AAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAABmJLR0QA/wD/AP+gvaeTAAAA CXBIWXMAAAsSAAALEgHS3X78AAAd0klEQVR42u19eXRb133m9xZsBAiA4E5wF0mRWmnZlko7jmn3 diff --git a/ui/src/components/SubmissionTable.js b/ui/src/components/SubmissionTable.js index 95ecfdf..f7dd0ae 100644 --- a/ui/src/components/SubmissionTable.js +++ b/ui/src/components/SubmissionTable.js @@ -20,6 +20,9 @@ import { import { Link } from "react-router-dom"; import { getIconConfig } from "../utils/iconMappingTable"; +import useVirusTotalApiKey from '../utils/useVirusTotalApiKey'; +import VirusTotalAugmentDrawer from "./VirusTotal/VirusTotalAugmentDrawer.js"; + import { debounce } from "lodash"; import AuthCtx from "../contexts/auth"; @@ -27,7 +30,6 @@ import { fetchWithTimeout } from "../util.js"; import { APP_CONFIG } from "../config"; const { Text } = Typography; - /** * A table component for displaying submission data. */ @@ -42,6 +44,18 @@ const SubmissionTable = () => { const defaultSorter = { field: "submitted_at", order: "descend" }; const [sorter, setSorter] = useState(defaultSorter); const [pagination, setPagination] = useState({ current: 1, pageSize: 10 }); + const [vtDrawerVisible, setVtDrawerVisible] = useState(false); + const [selectedResource, setSelectedResource] = useState(null); + const { isApiKeyAvailable } = useVirusTotalApiKey(); + + + // Function to handle opening the VT Augment + const handleVtOpen = (sha256Hash) => { + if (isApiKeyAvailable) { + setSelectedResource(sha256Hash); + setVtDrawerVisible(true); + } + }; // Fetches Data from the Strelka UP API const fetchData = useCallback(async () => { @@ -208,18 +222,20 @@ const SubmissionTable = () => { }, { - title: "VT +", + title: ( + + + VT + + + + + ), dataIndex: "strelka_response", key: "vt", width: 1, render: (strelkaResponse) => { - // Find the highest VirusTotal enrichment number in the responses - const highestVtEnrichment = strelkaResponse.reduce((max, response) => { - const enrichmentNumber = response?.enrichment?.virustotal; - return enrichmentNumber > max ? enrichmentNumber : max; - }, -1); // Start with -1 to handle cases where there are no positive numbers - const tagStyle = { + const defaultTagStyle = { fontSize: "10px", fontWeight: "bold", width: "80%", @@ -227,24 +243,55 @@ const SubmissionTable = () => { maxWidth: "75px", }; - let tagColor = "default"; - let vtText = - highestVtEnrichment >= 0 ? highestVtEnrichment.toString() : "N/A"; + const VtTagStyle = { + fontSize: "10px", + fontWeight: "bold", + width: "80%", + textAlignLast: "center", + maxWidth: "75px", + cursor: "pointer" + }; - if (highestVtEnrichment >= 5) { - tagColor = "error"; // red - } else if (highestVtEnrichment >= 0) { - tagColor = "success"; // green + // Initialize the object to store the highest VT enrichment and SHA256 + const highestVt = { + enrichment: -1, + sha256: null, + }; + + // Iterate over strelkaResponse to find the highest VT enrichment and its SHA256 + strelkaResponse.forEach((response) => { + const enrichmentNumber = response?.enrichment?.virustotal; + if (enrichmentNumber > highestVt.enrichment) { + highestVt.enrichment = enrichmentNumber; + highestVt.sha256 = response.scan.hash.sha256; + } + }); + + // Determine color based on enrichment value + let vtColor = "default"; + if (highestVt.enrichment > 5) { + vtColor = "volcano"; // Ant Design's volcano color for high enrichment + } else if (highestVt.enrichment >= 0) { + vtColor = "green"; // Ant Design's green color for low enrichment } - - return ( - - {vtText} + + // Check if enrichment value is "N/A", then return a non-clickable tag without an icon + if (highestVt.enrichment === -1) { + return N/A; + } else { + // Enrichment value exists, so return a clickable tag with the VirusTotal icon + return ( + !isApiKeyAvailable ? null : handleVtOpen(highestVt.sha256)} + > + {highestVt.enrichment} - ); + ); + } }, }, - { title: "Filename", dataIndex: "file_id", @@ -473,6 +520,7 @@ const SubmissionTable = () => { // If the type is virustotal, remove the first item in strelka_response if ( full.submitted_type === "virustotal" && + strelkaResponse[0].file.flavors.mime[0] === "application/zip" && strelkaResponse.length > 0 ) { strelkaResponse.shift(); @@ -482,8 +530,8 @@ const SubmissionTable = () => { if (strelkaResponse.length > 0) { const response = strelkaResponse[0]; mimeType = - response.file.flavors?.yara?.[0] || response.file.flavors?.mime?.[0] || + response.file.flavors?.yara?.[0] || mimeType; } @@ -649,13 +697,18 @@ const SubmissionTable = () => { return (
+ setVtDrawerVisible(false)} + open={vtDrawerVisible} + />
Search Filter debouncedSearchChange(e)} style={{ fontSize: "12px" }} /> diff --git a/ui/src/components/VirusTotal/VirusTotalAugmentDrawer.js b/ui/src/components/VirusTotal/VirusTotalAugmentDrawer.js new file mode 100644 index 0000000..cdd8a7c --- /dev/null +++ b/ui/src/components/VirusTotal/VirusTotalAugmentDrawer.js @@ -0,0 +1,81 @@ +import React, { useState, useEffect } from "react"; +import { Drawer, message } from "antd"; +import { APP_CONFIG } from "../../config"; +import { fetchWithTimeout } from "../../util"; + +const VirusTotalAugmentDrawer = ({ resource, onClose, open }) => { + const [widgetUrl, setWidgetUrl] = useState(null); + + useEffect(() => { + if (!open) { + return; + } + + const fetchWidgetUrl = () => { + const payload = { resource }; + + fetchWithTimeout( + `${APP_CONFIG.BACKEND_URL}/strelka/virustotal/widget-url`, + { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify(payload), + mode: "cors", + credentials: "include", + timeout: APP_CONFIG.API_TIMEOUT, + } + ) + .then((response) => { + if (!response.ok) { + return response.json().then((errorData) => { + throw new Error( + errorData.details || + "Error occurred while retrieving VirusTotal widget token" + ); + }); + } + return response.json(); + }) + .then((data) => { + setWidgetUrl(data.widget_url); + }) + .catch((error) => { + message.error(`Error retrieving widget token: ${error.message}`); + }); + }; + + fetchWidgetUrl(); + }, [open, resource]); + + return ( + + {widgetUrl ? ( +