diff --git a/.dockerignore b/.dockerignore index 74003e7e30..a3de147db4 100644 --- a/.dockerignore +++ b/.dockerignore @@ -138,11 +138,15 @@ temp/ test.py # Other stuff +.dockerignore .env.example +.git/ .gitignore .github/ app.json CHANGELOG.md +Dockerfile +docker-compose.yml Procfile pyproject.toml README.md diff --git a/.env.example b/.env.example index 44c91c59c7..14bdf060bf 100644 --- a/.env.example +++ b/.env.example @@ -1,6 +1,5 @@ TOKEN=MyBotToken LOG_URL=https://logviewername.herokuapp.com/ GUILD_ID=1234567890 -MODMAIL_GUILD_ID=1234567890 OWNERS=Owner1ID,Owner2ID,Owner3ID CONNECTION_URI=mongodb+srv://mongodburi diff --git a/.github/workflows/lints.yml b/.github/workflows/lints.yml index eaad52221f..b283dff078 100644 --- a/.github/workflows/lints.yml +++ b/.github/workflows/lints.yml @@ -7,7 +7,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: ['3.9', '3.10'] + python-version: ['3.10', '3.11'] name: Python ${{ matrix.python-version }} on ubuntu-latest diff --git a/CHANGELOG.md b/CHANGELOG.md index e191fafb5c..cb334e4e8e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,17 +6,45 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). This project mostly adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html); however, insignificant breaking changes do not guarantee a major version bump, see the reasoning [here](https://github.com/modmail-dev/modmail/issues/319). If you're a plugin developer, note the "BREAKING" section. +# v4.1.0 -# [UNRELEASED] +Drops support for Python 3.9. Python 3.10 and Python 3.11 are now the only supported versions. + +### Fixed +- GIF stickers no longer cause the bot to crash. +- `?alias make/create` as aliases to `?alias add`. This improves continuity between the bot and its command structure. ([PR #3195](https://github.com/kyb3r/modmail/pull/3195)) +- Loading the blocked list with the `?blocked` command takes a long time when the list is large. ([PR #3242](https://github.com/kyb3r/modmail/pull/3242)) +- Reply not being forwarded from DM. (PR [#3239](https://github.com/modmail-dev/modmail/pull/3239)) +- Cleanup imports after removing/unloading a plugin. ([PR #3226](https://github.com/modmail-dev/Modmail/pull/3226)) +- Fixed a syntactic error in the close message when a thread is closed after a certain duration. ([PR #3233](https://github.com/modmail-dev/Modmail/pull/3233)) +- Removed an extra space in the help command title when the command has no parameters. ([PR #3271](https://github.com/modmail-dev/Modmail/pull/3271)) +- Corrected some incorrect config help descriptions. ([PR #3277](https://github.com/modmail-dev/Modmail/pull/3277)) +- Rate limit issue when fetch the messages due to reaction linking. ([PR #3306](https://github.com/modmail-dev/Modmail/pull/3306)) +- Update command fails when the plugin is invalid. ([PR #3295](https://github.com/modmail-dev/Modmail/pull/3295)) ### Added -- New .env config option: `REGISTRY_PLUGINS_ONLY`, restricts to only allow adding registry plugins. ([PR #3247](https://github.com/modmail-dev/modmail/pull/3247)) +- `?log key ` to retrieve the log link and view a preview using a log key. ([PR #3196](https://github.com/modmail-dev/Modmail/pull/3196)) +- `REGISTRY_PLUGINS_ONLY`, environment variable, when set, restricts to only allow adding registry plugins. ([PR #3247](https://github.com/modmail-dev/modmail/pull/3247)) +- `DISCORD_LOG_LEVEL` environment variable to set the log level of discord.py. ([PR #3216](https://github.com/modmail-dev/Modmail/pull/3216)) +- `STREAM_LOG_FORMAT` and `FILE_LOG_FORMAT` environment variable to set the log format of the stream and file handlers respectively. Possible options are `json` and `plain` (default). ([PR #3305](https://github.com/modmail-dev/Modmail/pull/3305)) +- `LOG_EXPIRATION` environment variable to set the expiration time of logs. ([PR #3257](https://github.com/modmail-dev/Modmail/pull/3257)) +- New registry plugins: [`autoreact`](https://github.com/martinbndr/kyb3r-modmail-plugins/tree/master/autoreact) and [`rename`](https://github.com/Nicklaus-s/modmail-plugins/tree/main/rename). +- Improved join/leave message for multiple servers. ### Changed - Repo moved to https://github.com/modmail-dev/modmail. +- Channel name no longer shows `-0` if the user has migrated to the new username system. +- `?note` and `?reply` now allows you to send a sticker without any message. +- Guild icons in embed footers and author urls now have a fixed size of 128. ([PR #3261](https://github.com/modmail-dev/modmail/pull/3261)) +- Discord.py internal logging is now enabled by default. ([PR #3216](https://github.com/modmail-dev/Modmail/pull/3216)) +- The confirm-thread-creation dialog now uses buttons instead of reactions. ([PR #3273](https://github.com/modmail-dev/Modmail/pull/3273)) +- `?disable all` no longer overrides `?disable new`. ([PR #3278](https://github.com/modmail-dev/Modmail/pull/3278)) +- Dropped root privileges for Modmail running under Docker. ([PR #3284](https://github.com/modmail-dev/Modmail/pull/3284)) ### Internal +- Renamed `Bot.log_file_name` to `Bot.log_file_path`. Log files are now created at `temp/logs/modmail.log`. ([PR #3216](https://github.com/modmail-dev/Modmail/pull/3216)) - `ConfigManager.get` no longer accepts two positional arguments: the `convert` argument is now keyword-only. +- Various dependencies have been updated to their latest versions. # v4.0.2 diff --git a/Dockerfile b/Dockerfile index 3c88a0e7ca..96a398fad4 100644 --- a/Dockerfile +++ b/Dockerfile @@ -3,14 +3,18 @@ FROM python:3.10 as py FROM py as build RUN apt update && apt install -y g++ git + COPY requirements.txt / RUN pip install --prefix=/inst -U -r /requirements.txt FROM py -ENV USING_DOCKER yes COPY --from=build /inst /usr/local +ENV USING_DOCKER yes +RUN useradd --system --no-create-home modmail +USER modmail + WORKDIR /modmailbot CMD ["python", "bot.py"] -COPY . /modmailbot +COPY --chown=modmail:modmail . /modmailbot diff --git a/Pipfile b/Pipfile index e61e3b9288..21205b36f5 100644 --- a/Pipfile +++ b/Pipfile @@ -4,26 +4,27 @@ url = "https://pypi.org/simple" verify_ssl = true [dev-packages] -bandit = "~=1.7.0" -black = "==22.3.0" -pylint = "~=2.9.3" -typing-extensions = "==4.2.0" +bandit = ">=1.7.5" +black = "==23.11.0" +pylint = "==3.0.2" +typing-extensions = "==4.8.0" [packages] -aiohttp = "==3.8.1" -colorama = "~=0.4.5" -"discord.py" = "==2.0.1" -emoji = "==1.7.0" -isodate = "~=0.6.0" -motor = "==2.5.1" -natural = "~=0.2.0" -parsedatetime = "~=2.6" +aiohttp = "==3.9.0" +colorama = "==0.4.6" +"discord.py" = {version = "==2.3.2", extras = ["speed"]} +emoji = "==2.8.0" +isodate = "==0.6.1" +motor = "==3.3.2" +natural = "==0.2.0" # Why is this needed? +packaging = "==23.2" +parsedatetime = "==2.6" pymongo = {extras = ["srv"], version = "*"} # Required by motor -python-dateutil = "~=2.8.1" -python-dotenv = "==0.20.0" -uvloop = {version = ">=0.15.2", markers = "sys_platform != 'win32'"} -lottie = {version = "==0.6.11", extras = ["pdf"]} -requests = "==2.28.1" +python-dateutil = "==2.8.2" +python-dotenv = "==1.0.0" +uvloop = {version = ">=0.19.0", markers = "sys_platform != 'win32'"} +lottie = {version = "==0.7.0", extras = ["pdf"]} +requests = "==2.31.0" [scripts] bot = "python bot.py" diff --git a/Pipfile.lock b/Pipfile.lock index e1c531856e..5f07c7b131 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "9d1171901e036b1f78a2e89855d564e9f559736ca076128fa27eb14ee8f917a4" + "sha256": "7fee393ea9ea4c0b923033f0da0fdc590ba3f75c6072812062cdc458b84bf9ae" }, "pipfile-spec": 6, "requires": {}, @@ -14,214 +14,394 @@ ] }, "default": { + "aiodns": { + "hashes": [ + "sha256:1073eac48185f7a4150cad7f96a5192d6911f12b4fb894de80a088508c9b3a99", + "sha256:a387b63da4ced6aad35b1dda2d09620ad608a1c7c0fb71efa07ebb4cd511928d" + ], + "version": "==3.1.1" + }, "aiohttp": { "hashes": [ - "sha256:01d7bdb774a9acc838e6b8f1d114f45303841b89b95984cbb7d80ea41172a9e3", - "sha256:03a6d5349c9ee8f79ab3ff3694d6ce1cfc3ced1c9d36200cb8f08ba06bd3b782", - "sha256:04d48b8ce6ab3cf2097b1855e1505181bdd05586ca275f2505514a6e274e8e75", - "sha256:0770e2806a30e744b4e21c9d73b7bee18a1cfa3c47991ee2e5a65b887c49d5cf", - "sha256:07b05cd3305e8a73112103c834e91cd27ce5b4bd07850c4b4dbd1877d3f45be7", - "sha256:086f92daf51a032d062ec5f58af5ca6a44d082c35299c96376a41cbb33034675", - "sha256:099ebd2c37ac74cce10a3527d2b49af80243e2a4fa39e7bce41617fbc35fa3c1", - "sha256:0c7ebbbde809ff4e970824b2b6cb7e4222be6b95a296e46c03cf050878fc1785", - "sha256:102e487eeb82afac440581e5d7f8f44560b36cf0bdd11abc51a46c1cd88914d4", - "sha256:11691cf4dc5b94236ccc609b70fec991234e7ef8d4c02dd0c9668d1e486f5abf", - "sha256:11a67c0d562e07067c4e86bffc1553f2cf5b664d6111c894671b2b8712f3aba5", - "sha256:12de6add4038df8f72fac606dff775791a60f113a725c960f2bab01d8b8e6b15", - "sha256:13487abd2f761d4be7c8ff9080de2671e53fff69711d46de703c310c4c9317ca", - "sha256:15b09b06dae900777833fe7fc4b4aa426556ce95847a3e8d7548e2d19e34edb8", - "sha256:1c182cb873bc91b411e184dab7a2b664d4fea2743df0e4d57402f7f3fa644bac", - "sha256:1ed0b6477896559f17b9eaeb6d38e07f7f9ffe40b9f0f9627ae8b9926ae260a8", - "sha256:28d490af82bc6b7ce53ff31337a18a10498303fe66f701ab65ef27e143c3b0ef", - "sha256:2e5d962cf7e1d426aa0e528a7e198658cdc8aa4fe87f781d039ad75dcd52c516", - "sha256:2ed076098b171573161eb146afcb9129b5ff63308960aeca4b676d9d3c35e700", - "sha256:2f2f69dca064926e79997f45b2f34e202b320fd3782f17a91941f7eb85502ee2", - "sha256:31560d268ff62143e92423ef183680b9829b1b482c011713ae941997921eebc8", - "sha256:31d1e1c0dbf19ebccbfd62eff461518dcb1e307b195e93bba60c965a4dcf1ba0", - "sha256:37951ad2f4a6df6506750a23f7cbabad24c73c65f23f72e95897bb2cecbae676", - "sha256:3af642b43ce56c24d063325dd2cf20ee012d2b9ba4c3c008755a301aaea720ad", - "sha256:44db35a9e15d6fe5c40d74952e803b1d96e964f683b5a78c3cc64eb177878155", - "sha256:473d93d4450880fe278696549f2e7aed8cd23708c3c1997981464475f32137db", - "sha256:477c3ea0ba410b2b56b7efb072c36fa91b1e6fc331761798fa3f28bb224830dd", - "sha256:4a4a4e30bf1edcad13fb0804300557aedd07a92cabc74382fdd0ba6ca2661091", - "sha256:4aed991a28ea3ce320dc8ce655875e1e00a11bdd29fe9444dd4f88c30d558602", - "sha256:51467000f3647d519272392f484126aa716f747859794ac9924a7aafa86cd411", - "sha256:55c3d1072704d27401c92339144d199d9de7b52627f724a949fc7d5fc56d8b93", - "sha256:589c72667a5febd36f1315aa6e5f56dd4aa4862df295cb51c769d16142ddd7cd", - "sha256:5bfde62d1d2641a1f5173b8c8c2d96ceb4854f54a44c23102e2ccc7e02f003ec", - "sha256:5c23b1ad869653bc818e972b7a3a79852d0e494e9ab7e1a701a3decc49c20d51", - "sha256:61bfc23df345d8c9716d03717c2ed5e27374e0fe6f659ea64edcd27b4b044cf7", - "sha256:6ae828d3a003f03ae31915c31fa684b9890ea44c9c989056fea96e3d12a9fa17", - "sha256:6c7cefb4b0640703eb1069835c02486669312bf2f12b48a748e0a7756d0de33d", - "sha256:6d69f36d445c45cda7b3b26afef2fc34ef5ac0cdc75584a87ef307ee3c8c6d00", - "sha256:6f0d5f33feb5f69ddd57a4a4bd3d56c719a141080b445cbf18f238973c5c9923", - "sha256:6f8b01295e26c68b3a1b90efb7a89029110d3a4139270b24fda961893216c440", - "sha256:713ac174a629d39b7c6a3aa757b337599798da4c1157114a314e4e391cd28e32", - "sha256:718626a174e7e467f0558954f94af117b7d4695d48eb980146016afa4b580b2e", - "sha256:7187a76598bdb895af0adbd2fb7474d7f6025d170bc0a1130242da817ce9e7d1", - "sha256:71927042ed6365a09a98a6377501af5c9f0a4d38083652bcd2281a06a5976724", - "sha256:7d08744e9bae2ca9c382581f7dce1273fe3c9bae94ff572c3626e8da5b193c6a", - "sha256:7dadf3c307b31e0e61689cbf9e06be7a867c563d5a63ce9dca578f956609abf8", - "sha256:81e3d8c34c623ca4e36c46524a3530e99c0bc95ed068fd6e9b55cb721d408fb2", - "sha256:844a9b460871ee0a0b0b68a64890dae9c415e513db0f4a7e3cab41a0f2fedf33", - "sha256:8b7ef7cbd4fec9a1e811a5de813311ed4f7ac7d93e0fda233c9b3e1428f7dd7b", - "sha256:97ef77eb6b044134c0b3a96e16abcb05ecce892965a2124c566af0fd60f717e2", - "sha256:99b5eeae8e019e7aad8af8bb314fb908dd2e028b3cdaad87ec05095394cce632", - "sha256:a25fa703a527158aaf10dafd956f7d42ac6d30ec80e9a70846253dd13e2f067b", - "sha256:a2f635ce61a89c5732537a7896b6319a8fcfa23ba09bec36e1b1ac0ab31270d2", - "sha256:a79004bb58748f31ae1cbe9fa891054baaa46fb106c2dc7af9f8e3304dc30316", - "sha256:a996d01ca39b8dfe77440f3cd600825d05841088fd6bc0144cc6c2ec14cc5f74", - "sha256:b0e20cddbd676ab8a64c774fefa0ad787cc506afd844de95da56060348021e96", - "sha256:b6613280ccedf24354406caf785db748bebbddcf31408b20c0b48cb86af76866", - "sha256:b9d00268fcb9f66fbcc7cd9fe423741d90c75ee029a1d15c09b22d23253c0a44", - "sha256:bb01ba6b0d3f6c68b89fce7305080145d4877ad3acaed424bae4d4ee75faa950", - "sha256:c2aef4703f1f2ddc6df17519885dbfa3514929149d3ff900b73f45998f2532fa", - "sha256:c34dc4958b232ef6188c4318cb7b2c2d80521c9a56c52449f8f93ab7bc2a8a1c", - "sha256:c3630c3ef435c0a7c549ba170a0633a56e92629aeed0e707fec832dee313fb7a", - "sha256:c3d6a4d0619e09dcd61021debf7059955c2004fa29f48788a3dfaf9c9901a7cd", - "sha256:d15367ce87c8e9e09b0f989bfd72dc641bcd04ba091c68cd305312d00962addd", - "sha256:d2f9b69293c33aaa53d923032fe227feac867f81682f002ce33ffae978f0a9a9", - "sha256:e999f2d0e12eea01caeecb17b653f3713d758f6dcc770417cf29ef08d3931421", - "sha256:ea302f34477fda3f85560a06d9ebdc7fa41e82420e892fc50b577e35fc6a50b2", - "sha256:eaba923151d9deea315be1f3e2b31cc39a6d1d2f682f942905951f4e40200922", - "sha256:ef9612483cb35171d51d9173647eed5d0069eaa2ee812793a75373447d487aa4", - "sha256:f5315a2eb0239185af1bddb1abf472d877fede3cc8d143c6cddad37678293237", - "sha256:fa0ffcace9b3aa34d205d8130f7873fcfefcb6a4dd3dd705b0dab69af6712642", - "sha256:fc5471e1a54de15ef71c1bc6ebe80d4dc681ea600e68bfd1cbce40427f0b7578" + "sha256:05857848da443c8c12110d99285d499b4e84d59918a21132e45c3f0804876994", + "sha256:05a183f1978802588711aed0dea31e697d760ce9055292db9dc1604daa9a8ded", + "sha256:09f23292d29135025e19e8ff4f0a68df078fe4ee013bca0105b2e803989de92d", + "sha256:11ca808f9a6b63485059f5f6e164ef7ec826483c1212a44f268b3653c91237d8", + "sha256:1736d87dad8ef46a8ec9cddd349fa9f7bd3a064c47dd6469c0d6763d3d49a4fc", + "sha256:1df43596b826022b14998f0460926ce261544fedefe0d2f653e1b20f49e96454", + "sha256:23170247ef89ffa842a02bbfdc425028574d9e010611659abeb24d890bc53bb8", + "sha256:2779f5e7c70f7b421915fd47db332c81de365678180a9f3ab404088f87ba5ff9", + "sha256:28185e36a78d247c55e9fbea2332d16aefa14c5276a582ce7a896231c6b1c208", + "sha256:2cbc14a13fb6b42d344e4f27746a4b03a2cb0c1c3c5b932b0d6ad8881aa390e3", + "sha256:2d71abc15ff7047412ef26bf812dfc8d0d1020d664617f4913df2df469f26b76", + "sha256:2d820162c8c2bdbe97d328cd4f417c955ca370027dce593345e437b2e9ffdc4d", + "sha256:317719d7f824eba55857fe0729363af58e27c066c731bc62cd97bc9c3d9c7ea4", + "sha256:35a68cd63ca6aaef5707888f17a70c36efe62b099a4e853d33dc2e9872125be8", + "sha256:3607375053df58ed6f23903aa10cf3112b1240e8c799d243bbad0f7be0666986", + "sha256:366bc870d7ac61726f32a489fbe3d1d8876e87506870be66b01aeb84389e967e", + "sha256:3abf0551874fecf95f93b58f25ef4fc9a250669a2257753f38f8f592db85ddea", + "sha256:3d7f6235c7475658acfc1769d968e07ab585c79f6ca438ddfecaa9a08006aee2", + "sha256:3dd8119752dd30dd7bca7d4bc2a92a59be6a003e4e5c2cf7e248b89751b8f4b7", + "sha256:42fe4fd9f0dfcc7be4248c162d8056f1d51a04c60e53366b0098d1267c4c9da8", + "sha256:45820ddbb276113ead8d4907a7802adb77548087ff5465d5c554f9aa3928ae7d", + "sha256:4790e44f46a4aa07b64504089def5744d3b6780468c4ec3a1a36eb7f2cae9814", + "sha256:4afa8f71dba3a5a2e1e1282a51cba7341ae76585345c43d8f0e624882b622218", + "sha256:4b777c9286b6c6a94f50ddb3a6e730deec327e9e2256cb08b5530db0f7d40fd8", + "sha256:4ee1b4152bc3190cc40ddd6a14715e3004944263ea208229ab4c297712aa3075", + "sha256:51a4cd44788ea0b5e6bb8fa704597af3a30be75503a7ed1098bc5b8ffdf6c982", + "sha256:536b01513d67d10baf6f71c72decdf492fb7433c5f2f133e9a9087379d4b6f31", + "sha256:571760ad7736b34d05597a1fd38cbc7d47f7b65deb722cb8e86fd827404d1f6b", + "sha256:5a2eb5311a37fe105aa35f62f75a078537e1a9e4e1d78c86ec9893a3c97d7a30", + "sha256:5ab16c254e2312efeb799bc3c06897f65a133b38b69682bf75d1f1ee1a9c43a9", + "sha256:65b0a70a25456d329a5e1426702dde67be0fb7a4ead718005ba2ca582d023a94", + "sha256:673343fbc0c1ac44d0d2640addc56e97a052504beacd7ade0dc5e76d3a4c16e8", + "sha256:6777a390e41e78e7c45dab43a4a0196c55c3b8c30eebe017b152939372a83253", + "sha256:6896b8416be9ada4d22cd359d7cb98955576ce863eadad5596b7cdfbf3e17c6c", + "sha256:694df243f394629bcae2d8ed94c589a181e8ba8604159e6e45e7b22e58291113", + "sha256:70e851f596c00f40a2f00a46126c95c2e04e146015af05a9da3e4867cfc55911", + "sha256:7276fe0017664414fdc3618fca411630405f1aaf0cc3be69def650eb50441787", + "sha256:76a86a9989ebf82ee61e06e2bab408aec4ea367dc6da35145c3352b60a112d11", + "sha256:7a94bde005a8f926d0fa38b88092a03dea4b4875a61fbcd9ac6f4351df1b57cd", + "sha256:7ae5f99a32c53731c93ac3075abd3e1e5cfbe72fc3eaac4c27c9dd64ba3b19fe", + "sha256:7e8a3b79b6d186a9c99761fd4a5e8dd575a48d96021f220ac5b5fa856e5dd029", + "sha256:816f4db40555026e4cdda604a1088577c1fb957d02f3f1292e0221353403f192", + "sha256:8303531e2c17b1a494ffaeba48f2da655fe932c4e9a2626c8718403c83e5dd2b", + "sha256:8488519aa05e636c5997719fe543c8daf19f538f4fa044f3ce94bee608817cff", + "sha256:87c8b0a6487e8109427ccf638580865b54e2e3db4a6e0e11c02639231b41fc0f", + "sha256:8c9e5f4d7208cda1a2bb600e29069eecf857e6980d0ccc922ccf9d1372c16f4b", + "sha256:94697c7293199c2a2551e3e3e18438b4cba293e79c6bc2319f5fd652fccb7456", + "sha256:9623cfd9e85b76b83ef88519d98326d4731f8d71869867e47a0b979ffec61c73", + "sha256:98d21092bf2637c5fa724a428a69e8f5955f2182bff61f8036827cf6ce1157bf", + "sha256:99ae01fb13a618b9942376df77a1f50c20a281390dad3c56a6ec2942e266220d", + "sha256:9c196b30f1b1aa3363a69dd69079ae9bec96c2965c4707eaa6914ba099fb7d4f", + "sha256:a00ce44c21612d185c5275c5cba4bab8d7c1590f248638b667ed8a782fa8cd6f", + "sha256:a1b66dbb8a7d5f50e9e2ea3804b01e766308331d0cac76eb30c563ac89c95985", + "sha256:a1d7edf74a36de0e5ca50787e83a77cf352f5504eb0ffa3f07000a911ba353fb", + "sha256:a1e3b3c107ccb0e537f309f719994a55621acd2c8fdf6d5ce5152aed788fb940", + "sha256:a486ddf57ab98b6d19ad36458b9f09e6022de0381674fe00228ca7b741aacb2f", + "sha256:ac9669990e2016d644ba8ae4758688534aabde8dbbc81f9af129c3f5f01ca9cd", + "sha256:b1a2ea8252cacc7fd51df5a56d7a2bb1986ed39be9397b51a08015727dfb69bd", + "sha256:c5b7bf8fe4d39886adc34311a233a2e01bc10eb4e842220235ed1de57541a896", + "sha256:c67a51ea415192c2e53e4e048c78bab82d21955b4281d297f517707dc836bf3d", + "sha256:ca4fddf84ac7d8a7d0866664936f93318ff01ee33e32381a115b19fb5a4d1202", + "sha256:d5b9345ab92ebe6003ae11d8092ce822a0242146e6fa270889b9ba965457ca40", + "sha256:d97c3e286d0ac9af6223bc132dc4bad6540b37c8d6c0a15fe1e70fb34f9ec411", + "sha256:db04d1de548f7a62d1dd7e7cdf7c22893ee168e22701895067a28a8ed51b3735", + "sha256:dcf71c55ec853826cd70eadb2b6ac62ec577416442ca1e0a97ad875a1b3a0305", + "sha256:de3cc86f4ea8b4c34a6e43a7306c40c1275e52bfa9748d869c6b7d54aa6dad80", + "sha256:deac0a32aec29608eb25d730f4bc5a261a65b6c48ded1ed861d2a1852577c932", + "sha256:e18d92c3e9e22553a73e33784fcb0ed484c9874e9a3e96c16a8d6a1e74a0217b", + "sha256:eb6dfd52063186ac97b4caa25764cdbcdb4b10d97f5c5f66b0fa95052e744eb7", + "sha256:f09960b5bb1017d16c0f9e9f7fc42160a5a49fa1e87a175fd4a2b1a1833ea0af", + "sha256:f1e4f254e9c35d8965d377e065c4a8a55d396fe87c8e7e8429bcfdeeb229bfb3", + "sha256:f32c86dc967ab8c719fd229ce71917caad13cc1e8356ee997bf02c5b368799bf", + "sha256:f50b4663c3e0262c3a361faf440761fbef60ccdde5fe8545689a4b3a3c149fb4", + "sha256:f8e05f5163528962ce1d1806fce763ab893b1c5b7ace0a3538cd81a90622f844", + "sha256:f929f4c9b9a00f3e6cc0587abb95ab9c05681f8b14e0fe1daecfa83ea90f8318", + "sha256:f9e09a1c83521d770d170b3801eea19b89f41ccaa61d53026ed111cb6f088887" ], "index": "pypi", - "version": "==3.8.1" + "markers": "python_version >= '3.8'", + "version": "==3.9.0" }, "aiosignal": { "hashes": [ - "sha256:26e62109036cd181df6e6ad646f91f0dcfd05fe16d0cb924138ff2ab75d64e3a", - "sha256:78ed67db6c7b7ced4f98e495e572106d5c432a93e1ddd1bf475e1dc05f5b7df2" + "sha256:54cd96e15e1649b75d6c87526a6ff0b6c1b0dd3459f43d9ca11d48c339b68cfc", + "sha256:f8376fb07dd1e86a584e4fcdec80b36b7f81aac666ebc724e2c090300dd83b17" ], - "markers": "python_version >= '3.6'", - "version": "==1.2.0" + "markers": "python_version >= '3.7'", + "version": "==1.3.1" }, "async-timeout": { "hashes": [ - "sha256:2163e1640ddb52b7a8c80d0a67a08587e5d245cc9c553a74a847056bc2976b15", - "sha256:8ca1e4fcf50d07413d66d1a5e416e42cfdf5851c981d679a09851a6853383b3c" + "sha256:4640d96be84d82d02ed59ea2b7105a0f7b33abe8703703cd0ab0bf87c427522f", + "sha256:7405140ff1230c310e51dc27b3145b9092d659ce68ff733fb0cefe3ee42be028" ], - "markers": "python_version >= '3.6'", - "version": "==4.0.2" + "markers": "python_version < '3.11'", + "version": "==4.0.3" }, "attrs": { "hashes": [ - "sha256:29adc2665447e5191d0e7c568fde78b21f9672d344281d0c6e1ab085429b22b6", - "sha256:86efa402f67bf2df34f51a335487cf46b1ec130d02b8d39fd248abfd30da551c" + "sha256:1f28b4522cdc2fb4256ac1a020c78acf9cba2c6b461ccd2c126f3aa8e8335d04", + "sha256:6279836d581513a26f1bf235f9acd333bc9115683f14f7e8fae46c98fc50e015" ], - "markers": "python_version >= '3.5'", - "version": "==22.1.0" + "markers": "python_version >= '3.7'", + "version": "==23.1.0" + }, + "brotli": { + "hashes": [ + "sha256:03d20af184290887bdea3f0f78c4f737d126c74dc2f3ccadf07e54ceca3bf208", + "sha256:0541e747cce78e24ea12d69176f6a7ddb690e62c425e01d31cc065e69ce55b48", + "sha256:069a121ac97412d1fe506da790b3e69f52254b9df4eb665cd42460c837193354", + "sha256:0b63b949ff929fbc2d6d3ce0e924c9b93c9785d877a21a1b678877ffbbc4423a", + "sha256:0c6244521dda65ea562d5a69b9a26120769b7a9fb3db2fe9545935ed6735b128", + "sha256:11d00ed0a83fa22d29bc6b64ef636c4552ebafcef57154b4ddd132f5638fbd1c", + "sha256:141bd4d93984070e097521ed07e2575b46f817d08f9fa42b16b9b5f27b5ac088", + "sha256:19c116e796420b0cee3da1ccec3b764ed2952ccfcc298b55a10e5610ad7885f9", + "sha256:1ab4fbee0b2d9098c74f3057b2bc055a8bd92ccf02f65944a241b4349229185a", + "sha256:1ae56aca0402a0f9a3431cddda62ad71666ca9d4dc3a10a142b9dce2e3c0cda3", + "sha256:224e57f6eac61cc449f498cc5f0e1725ba2071a3d4f48d5d9dffba42db196438", + "sha256:22fc2a8549ffe699bfba2256ab2ed0421a7b8fadff114a3d201794e45a9ff578", + "sha256:23032ae55523cc7bccb4f6a0bf368cd25ad9bcdcc1990b64a647e7bbcce9cb5b", + "sha256:2333e30a5e00fe0fe55903c8832e08ee9c3b1382aacf4db26664a16528d51b4b", + "sha256:2954c1c23f81c2eaf0b0717d9380bd348578a94161a65b3a2afc62c86467dd68", + "sha256:2de9d02f5bda03d27ede52e8cfe7b865b066fa49258cbab568720aa5be80a47d", + "sha256:30924eb4c57903d5a7526b08ef4a584acc22ab1ffa085faceb521521d2de32dd", + "sha256:316cc9b17edf613ac76b1f1f305d2a748f1b976b033b049a6ecdfd5612c70409", + "sha256:38025d9f30cf4634f8309c6874ef871b841eb3c347e90b0851f63d1ded5212da", + "sha256:39da8adedf6942d76dc3e46653e52df937a3c4d6d18fdc94a7c29d263b1f5b50", + "sha256:3d7954194c36e304e1523f55d7042c59dc53ec20dd4e9ea9d151f1b62b4415c0", + "sha256:4093c631e96fdd49e0377a9c167bfd75b6d0bad2ace734c6eb20b348bc3ea180", + "sha256:43ce1b9935bfa1ede40028054d7f48b5469cd02733a365eec8a329ffd342915d", + "sha256:4d4a848d1837973bf0f4b5e54e3bec977d99be36a7895c61abb659301b02c112", + "sha256:4ed11165dd45ce798d99a136808a794a748d5dc38511303239d4e2363c0695dc", + "sha256:510b5b1bfbe20e1a7b3baf5fed9e9451873559a976c1a78eebaa3b86c57b4265", + "sha256:524f35912131cc2cabb00edfd8d573b07f2d9f21fa824bd3fb19725a9cf06327", + "sha256:587ca6d3cef6e4e868102672d3bd9dc9698c309ba56d41c2b9c85bbb903cdb95", + "sha256:5b3cc074004d968722f51e550b41a27be656ec48f8afaeeb45ebf65b561481dd", + "sha256:5eeb539606f18a0b232d4ba45adccde4125592f3f636a6182b4a8a436548b914", + "sha256:5f4d5ea15c9382135076d2fb28dde923352fe02951e66935a9efaac8f10e81b0", + "sha256:5fb2ce4b8045c78ebbc7b8f3c15062e435d47e7393cc57c25115cfd49883747a", + "sha256:6172447e1b368dcbc458925e5ddaf9113477b0ed542df258d84fa28fc45ceea7", + "sha256:6c3020404e0b5eefd7c9485ccf8393cfb75ec38ce75586e046573c9dc29967a0", + "sha256:70051525001750221daa10907c77830bc889cb6d865cc0b813d9db7fefc21451", + "sha256:7905193081db9bfa73b1219140b3d315831cbff0d8941f22da695832f0dd188f", + "sha256:7c4855522edb2e6ae7fdb58e07c3ba9111e7621a8956f481c68d5d979c93032e", + "sha256:7e4c4629ddad63006efa0ef968c8e4751c5868ff0b1c5c40f76524e894c50248", + "sha256:7f4bf76817c14aa98cc6697ac02f3972cb8c3da93e9ef16b9c66573a68014f91", + "sha256:81de08ac11bcb85841e440c13611c00b67d3bf82698314928d0b676362546724", + "sha256:861bf317735688269936f755fa136a99d1ed526883859f86e41a5d43c61d8966", + "sha256:890b5a14ce214389b2cc36ce82f3093f96f4cc730c1cffdbefff77a7c71f2a97", + "sha256:89f4988c7203739d48c6f806f1e87a1d96e0806d44f0fba61dba81392c9e474d", + "sha256:8dadd1314583ec0bf2d1379f7008ad627cd6336625d6679cf2f8e67081b83acf", + "sha256:901032ff242d479a0efa956d853d16875d42157f98951c0230f69e69f9c09bac", + "sha256:906bc3a79de8c4ae5b86d3d75a8b77e44404b0f4261714306e3ad248d8ab0951", + "sha256:919e32f147ae93a09fe064d77d5ebf4e35502a8df75c29fb05788528e330fe74", + "sha256:929811df5462e182b13920da56c6e0284af407d1de637d8e536c5cd00a7daf60", + "sha256:949f3b7c29912693cee0afcf09acd6ebc04c57af949d9bf77d6101ebb61e388c", + "sha256:a090ca607cbb6a34b0391776f0cb48062081f5f60ddcce5d11838e67a01928d1", + "sha256:a1fd8a29719ccce974d523580987b7f8229aeace506952fa9ce1d53a033873c8", + "sha256:a37b8f0391212d29b3a91a799c8e4a2855e0576911cdfb2515487e30e322253d", + "sha256:a3daabb76a78f829cafc365531c972016e4aa8d5b4bf60660ad8ecee19df7ccc", + "sha256:a469274ad18dc0e4d316eefa616d1d0c2ff9da369af19fa6f3daa4f09671fd61", + "sha256:a599669fd7c47233438a56936988a2478685e74854088ef5293802123b5b2460", + "sha256:a743e5a28af5f70f9c080380a5f908d4d21d40e8f0e0c8901604d15cfa9ba751", + "sha256:a77def80806c421b4b0af06f45d65a136e7ac0bdca3c09d9e2ea4e515367c7e9", + "sha256:aac0411d20e345dc0920bdec5548e438e999ff68d77564d5e9463a7ca9d3e7b1", + "sha256:ae15b066e5ad21366600ebec29a7ccbc86812ed267e4b28e860b8ca16a2bc474", + "sha256:be36e3d172dc816333f33520154d708a2657ea63762ec16b62ece02ab5e4daf2", + "sha256:c8146669223164fc87a7e3de9f81e9423c67a79d6b3447994dfb9c95da16e2d6", + "sha256:c8fd5270e906eef71d4a8d19b7c6a43760c6abcfcc10c9101d14eb2357418de9", + "sha256:caf9ee9a5775f3111642d33b86237b05808dafcd6268faa492250e9b78046eb2", + "sha256:cdad5b9014d83ca68c25d2e9444e28e967ef16e80f6b436918c700c117a85467", + "sha256:cdbc1fc1bc0bff1cef838eafe581b55bfbffaed4ed0318b724d0b71d4d377619", + "sha256:ceb64bbc6eac5a140ca649003756940f8d6a7c444a68af170b3187623b43bebf", + "sha256:d0c5516f0aed654134a2fc936325cc2e642f8a0e096d075209672eb321cff408", + "sha256:d143fd47fad1db3d7c27a1b1d66162e855b5d50a89666af46e1679c496e8e579", + "sha256:d192f0f30804e55db0d0e0a35d83a9fead0e9a359a9ed0285dbacea60cc10a84", + "sha256:db85ecf4e609a48f4b29055f1e144231b90edc90af7481aa731ba2d059226b1b", + "sha256:de6551e370ef19f8de1807d0a9aa2cdfdce2e85ce88b122fe9f6b2b076837e59", + "sha256:e1140c64812cb9b06c922e77f1c26a75ec5e3f0fb2bf92cc8c58720dec276752", + "sha256:e6a904cb26bfefc2f0a6f240bdf5233be78cd2488900a2f846f3c3ac8489ab80", + "sha256:e84799f09591700a4154154cab9787452925578841a94321d5ee8fb9a9a328f0", + "sha256:e93dfc1a1165e385cc8239fab7c036fb2cd8093728cbd85097b284d7b99249a2", + "sha256:efa8b278894b14d6da122a72fefcebc28445f2d3f880ac59d46c90f4c13be9a3", + "sha256:f0d8a7a6b5983c2496e364b969f0e526647a06b075d034f3297dc66f3b360c64", + "sha256:f296c40e23065d0d6650c4aefe7470d2a25fffda489bcc3eb66083f3ac9f6643", + "sha256:f66b5337fa213f1da0d9000bc8dc0cb5b896b726eefd9c6046f699b169c41b9e", + "sha256:f733d788519c7e3e71f0855c96618720f5d3d60c3cb829d8bbb722dddce37985", + "sha256:fce1473f3ccc4187f75b4690cfc922628aed4d3dd013d047f95a9b3919a86596", + "sha256:fd5f17ff8f14003595ab414e45fce13d073e0762394f957182e69035c9f3d7c2", + "sha256:fdc3ff3bfccdc6b9cc7c342c03aa2400683f0cb891d46e94b64a197910dc4064" + ], + "version": "==1.1.0" }, "cairocffi": { "hashes": [ - "sha256:108a3a7cb09e203bdd8501d9baad91d786d204561bd71e9364e8b34897c47b91" + "sha256:78e6bbe47357640c453d0be929fa49cd05cce2e1286f3d2a1ca9cbda7efdb8b7", + "sha256:aa78ee52b9069d7475eeac457389b6275aa92111895d78fbaa2202a52dac112e" ], "markers": "python_version >= '3.7'", - "version": "==1.3.0" + "version": "==1.6.1" }, "cairosvg": { "hashes": [ - "sha256:98c276b7e4f0caf01e5c7176765c104ffa1aa1461d63b2053b04ab663cf7052b", - "sha256:b0b9929cf5dba005178d746a8036fcf0025550f498ca54db61873322384783bc" + "sha256:432531d72347291b9a9ebfb6777026b607563fd8719c46ee742db0aef7271ba0", + "sha256:8a5222d4e6c3f86f1f7046b63246877a63b49923a1cd202184c3a634ef546b3b" ], - "version": "==2.5.2" + "markers": "python_version >= '3.5'", + "version": "==2.7.1" }, "certifi": { "hashes": [ - "sha256:36973885b9542e6bd01dea287b2b4b3b21236307c56324fcc3f1160f2d655ed5", - "sha256:e232343de1ab72c2aa521b625c80f699e356830fd0e2c620b465b304b17b0516" + "sha256:9b469f3a900bf28dc19b8cfbf8019bf47f7fdd1a65a1d4ffb98fc14166beb4d1", + "sha256:e036ab49d5b79556f99cfc2d9320b34cfbe5be05c5871b51de9329f0603b0474" ], "markers": "python_version >= '3.6'", - "version": "==2022.9.14" + "version": "==2023.11.17" }, "cffi": { "hashes": [ - "sha256:00a9ed42e88df81ffae7a8ab6d9356b371399b91dbdf0c3cb1e84c03a13aceb5", - "sha256:03425bdae262c76aad70202debd780501fabeaca237cdfddc008987c0e0f59ef", - "sha256:04ed324bda3cda42b9b695d51bb7d54b680b9719cfab04227cdd1e04e5de3104", - "sha256:0e2642fe3142e4cc4af0799748233ad6da94c62a8bec3a6648bf8ee68b1c7426", - "sha256:173379135477dc8cac4bc58f45db08ab45d228b3363adb7af79436135d028405", - "sha256:198caafb44239b60e252492445da556afafc7d1e3ab7a1fb3f0584ef6d742375", - "sha256:1e74c6b51a9ed6589199c787bf5f9875612ca4a8a0785fb2d4a84429badaf22a", - "sha256:2012c72d854c2d03e45d06ae57f40d78e5770d252f195b93f581acf3ba44496e", - "sha256:21157295583fe8943475029ed5abdcf71eb3911894724e360acff1d61c1d54bc", - "sha256:2470043b93ff09bf8fb1d46d1cb756ce6132c54826661a32d4e4d132e1977adf", - "sha256:285d29981935eb726a4399badae8f0ffdff4f5050eaa6d0cfc3f64b857b77185", - "sha256:30d78fbc8ebf9c92c9b7823ee18eb92f2e6ef79b45ac84db507f52fbe3ec4497", - "sha256:320dab6e7cb2eacdf0e658569d2575c4dad258c0fcc794f46215e1e39f90f2c3", - "sha256:33ab79603146aace82c2427da5ca6e58f2b3f2fb5da893ceac0c42218a40be35", - "sha256:3548db281cd7d2561c9ad9984681c95f7b0e38881201e157833a2342c30d5e8c", - "sha256:3799aecf2e17cf585d977b780ce79ff0dc9b78d799fc694221ce814c2c19db83", - "sha256:39d39875251ca8f612b6f33e6b1195af86d1b3e60086068be9cc053aa4376e21", - "sha256:3b926aa83d1edb5aa5b427b4053dc420ec295a08e40911296b9eb1b6170f6cca", - "sha256:3bcde07039e586f91b45c88f8583ea7cf7a0770df3a1649627bf598332cb6984", - "sha256:3d08afd128ddaa624a48cf2b859afef385b720bb4b43df214f85616922e6a5ac", - "sha256:3eb6971dcff08619f8d91607cfc726518b6fa2a9eba42856be181c6d0d9515fd", - "sha256:40f4774f5a9d4f5e344f31a32b5096977b5d48560c5592e2f3d2c4374bd543ee", - "sha256:4289fc34b2f5316fbb762d75362931e351941fa95fa18789191b33fc4cf9504a", - "sha256:470c103ae716238bbe698d67ad020e1db9d9dba34fa5a899b5e21577e6d52ed2", - "sha256:4f2c9f67e9821cad2e5f480bc8d83b8742896f1242dba247911072d4fa94c192", - "sha256:50a74364d85fd319352182ef59c5c790484a336f6db772c1a9231f1c3ed0cbd7", - "sha256:54a2db7b78338edd780e7ef7f9f6c442500fb0d41a5a4ea24fff1c929d5af585", - "sha256:5635bd9cb9731e6d4a1132a498dd34f764034a8ce60cef4f5319c0541159392f", - "sha256:59c0b02d0a6c384d453fece7566d1c7e6b7bae4fc5874ef2ef46d56776d61c9e", - "sha256:5d598b938678ebf3c67377cdd45e09d431369c3b1a5b331058c338e201f12b27", - "sha256:5df2768244d19ab7f60546d0c7c63ce1581f7af8b5de3eb3004b9b6fc8a9f84b", - "sha256:5ef34d190326c3b1f822a5b7a45f6c4535e2f47ed06fec77d3d799c450b2651e", - "sha256:6975a3fac6bc83c4a65c9f9fcab9e47019a11d3d2cf7f3c0d03431bf145a941e", - "sha256:6c9a799e985904922a4d207a94eae35c78ebae90e128f0c4e521ce339396be9d", - "sha256:70df4e3b545a17496c9b3f41f5115e69a4f2e77e94e1d2a8e1070bc0c38c8a3c", - "sha256:7473e861101c9e72452f9bf8acb984947aa1661a7704553a9f6e4baa5ba64415", - "sha256:8102eaf27e1e448db915d08afa8b41d6c7ca7a04b7d73af6514df10a3e74bd82", - "sha256:87c450779d0914f2861b8526e035c5e6da0a3199d8f1add1a665e1cbc6fc6d02", - "sha256:8b7ee99e510d7b66cdb6c593f21c043c248537a32e0bedf02e01e9553a172314", - "sha256:91fc98adde3d7881af9b59ed0294046f3806221863722ba7d8d120c575314325", - "sha256:94411f22c3985acaec6f83c6df553f2dbe17b698cc7f8ae751ff2237d96b9e3c", - "sha256:98d85c6a2bef81588d9227dde12db8a7f47f639f4a17c9ae08e773aa9c697bf3", - "sha256:9ad5db27f9cabae298d151c85cf2bad1d359a1b9c686a275df03385758e2f914", - "sha256:a0b71b1b8fbf2b96e41c4d990244165e2c9be83d54962a9a1d118fd8657d2045", - "sha256:a0f100c8912c114ff53e1202d0078b425bee3649ae34d7b070e9697f93c5d52d", - "sha256:a591fe9e525846e4d154205572a029f653ada1a78b93697f3b5a8f1f2bc055b9", - "sha256:a5c84c68147988265e60416b57fc83425a78058853509c1b0629c180094904a5", - "sha256:a66d3508133af6e8548451b25058d5812812ec3798c886bf38ed24a98216fab2", - "sha256:a8c4917bd7ad33e8eb21e9a5bbba979b49d9a97acb3a803092cbc1133e20343c", - "sha256:b3bbeb01c2b273cca1e1e0c5df57f12dce9a4dd331b4fa1635b8bec26350bde3", - "sha256:cba9d6b9a7d64d4bd46167096fc9d2f835e25d7e4c121fb2ddfc6528fb0413b2", - "sha256:cc4d65aeeaa04136a12677d3dd0b1c0c94dc43abac5860ab33cceb42b801c1e8", - "sha256:ce4bcc037df4fc5e3d184794f27bdaab018943698f4ca31630bc7f84a7b69c6d", - "sha256:cec7d9412a9102bdc577382c3929b337320c4c4c4849f2c5cdd14d7368c5562d", - "sha256:d400bfb9a37b1351253cb402671cea7e89bdecc294e8016a707f6d1d8ac934f9", - "sha256:d61f4695e6c866a23a21acab0509af1cdfd2c013cf256bbf5b6b5e2695827162", - "sha256:db0fbb9c62743ce59a9ff687eb5f4afbe77e5e8403d6697f7446e5f609976f76", - "sha256:dd86c085fae2efd48ac91dd7ccffcfc0571387fe1193d33b6394db7ef31fe2a4", - "sha256:e00b098126fd45523dd056d2efba6c5a63b71ffe9f2bbe1a4fe1716e1d0c331e", - "sha256:e229a521186c75c8ad9490854fd8bbdd9a0c9aa3a524326b55be83b54d4e0ad9", - "sha256:e263d77ee3dd201c3a142934a086a4450861778baaeeb45db4591ef65550b0a6", - "sha256:ed9cb427ba5504c1dc15ede7d516b84757c3e3d7868ccc85121d9310d27eed0b", - "sha256:fa6693661a4c91757f4412306191b6dc88c1703f780c8234035eac011922bc01", - "sha256:fcd131dd944808b5bdb38e6f5b53013c5aa4f334c5cad0c72742f6eba4b73db0" - ], - "version": "==1.15.1" + "sha256:0c9ef6ff37e974b73c25eecc13952c55bceed9112be2d9d938ded8e856138bcc", + "sha256:131fd094d1065b19540c3d72594260f118b231090295d8c34e19a7bbcf2e860a", + "sha256:1b8ebc27c014c59692bb2664c7d13ce7a6e9a629be20e54e7271fa696ff2b417", + "sha256:2c56b361916f390cd758a57f2e16233eb4f64bcbeee88a4881ea90fca14dc6ab", + "sha256:2d92b25dbf6cae33f65005baf472d2c245c050b1ce709cc4588cdcdd5495b520", + "sha256:31d13b0f99e0836b7ff893d37af07366ebc90b678b6664c955b54561fc36ef36", + "sha256:32c68ef735dbe5857c810328cb2481e24722a59a2003018885514d4c09af9743", + "sha256:3686dffb02459559c74dd3d81748269ffb0eb027c39a6fc99502de37d501faa8", + "sha256:582215a0e9adbe0e379761260553ba11c58943e4bbe9c36430c4ca6ac74b15ed", + "sha256:5b50bf3f55561dac5438f8e70bfcdfd74543fd60df5fa5f62d94e5867deca684", + "sha256:5bf44d66cdf9e893637896c7faa22298baebcd18d1ddb6d2626a6e39793a1d56", + "sha256:6602bc8dc6f3a9e02b6c22c4fc1e47aa50f8f8e6d3f78a5e16ac33ef5fefa324", + "sha256:673739cb539f8cdaa07d92d02efa93c9ccf87e345b9a0b556e3ecc666718468d", + "sha256:68678abf380b42ce21a5f2abde8efee05c114c2fdb2e9eef2efdb0257fba1235", + "sha256:68e7c44931cc171c54ccb702482e9fc723192e88d25a0e133edd7aff8fcd1f6e", + "sha256:6b3d6606d369fc1da4fd8c357d026317fbb9c9b75d36dc16e90e84c26854b088", + "sha256:748dcd1e3d3d7cd5443ef03ce8685043294ad6bd7c02a38d1bd367cfd968e000", + "sha256:7651c50c8c5ef7bdb41108b7b8c5a83013bfaa8a935590c5d74627c047a583c7", + "sha256:7b78010e7b97fef4bee1e896df8a4bbb6712b7f05b7ef630f9d1da00f6444d2e", + "sha256:7e61e3e4fa664a8588aa25c883eab612a188c725755afff6289454d6362b9673", + "sha256:80876338e19c951fdfed6198e70bc88f1c9758b94578d5a7c4c91a87af3cf31c", + "sha256:8895613bcc094d4a1b2dbe179d88d7fb4a15cee43c052e8885783fac397d91fe", + "sha256:88e2b3c14bdb32e440be531ade29d3c50a1a59cd4e51b1dd8b0865c54ea5d2e2", + "sha256:8f8e709127c6c77446a8c0a8c8bf3c8ee706a06cd44b1e827c3e6a2ee6b8c098", + "sha256:9cb4a35b3642fc5c005a6755a5d17c6c8b6bcb6981baf81cea8bfbc8903e8ba8", + "sha256:9f90389693731ff1f659e55c7d1640e2ec43ff725cc61b04b2f9c6d8d017df6a", + "sha256:a09582f178759ee8128d9270cd1344154fd473bb77d94ce0aeb2a93ebf0feaf0", + "sha256:a6a14b17d7e17fa0d207ac08642c8820f84f25ce17a442fd15e27ea18d67c59b", + "sha256:a72e8961a86d19bdb45851d8f1f08b041ea37d2bd8d4fd19903bc3083d80c896", + "sha256:abd808f9c129ba2beda4cfc53bde801e5bcf9d6e0f22f095e45327c038bfe68e", + "sha256:ac0f5edd2360eea2f1daa9e26a41db02dd4b0451b48f7c318e217ee092a213e9", + "sha256:b29ebffcf550f9da55bec9e02ad430c992a87e5f512cd63388abb76f1036d8d2", + "sha256:b2ca4e77f9f47c55c194982e10f058db063937845bb2b7a86c84a6cfe0aefa8b", + "sha256:b7be2d771cdba2942e13215c4e340bfd76398e9227ad10402a8767ab1865d2e6", + "sha256:b84834d0cf97e7d27dd5b7f3aca7b6e9263c56308ab9dc8aae9784abb774d404", + "sha256:b86851a328eedc692acf81fb05444bdf1891747c25af7529e39ddafaf68a4f3f", + "sha256:bcb3ef43e58665bbda2fb198698fcae6776483e0c4a631aa5647806c25e02cc0", + "sha256:c0f31130ebc2d37cdd8e44605fb5fa7ad59049298b3f745c74fa74c62fbfcfc4", + "sha256:c6a164aa47843fb1b01e941d385aab7215563bb8816d80ff3a363a9f8448a8dc", + "sha256:d8a9d3ebe49f084ad71f9269834ceccbf398253c9fac910c4fd7053ff1386936", + "sha256:db8e577c19c0fda0beb7e0d4e09e0ba74b1e4c092e0e40bfa12fe05b6f6d75ba", + "sha256:dc9b18bf40cc75f66f40a7379f6a9513244fe33c0e8aa72e2d56b0196a7ef872", + "sha256:e09f3ff613345df5e8c3667da1d918f9149bd623cd9070c983c013792a9a62eb", + "sha256:e4108df7fe9b707191e55f33efbcb2d81928e10cea45527879a4749cbe472614", + "sha256:e6024675e67af929088fda399b2094574609396b1decb609c55fa58b028a32a1", + "sha256:e70f54f1796669ef691ca07d046cd81a29cb4deb1e5f942003f401c0c4a2695d", + "sha256:e715596e683d2ce000574bae5d07bd522c781a822866c20495e52520564f0969", + "sha256:e760191dd42581e023a68b758769e2da259b5d52e3103c6060ddc02c9edb8d7b", + "sha256:ed86a35631f7bfbb28e108dd96773b9d5a6ce4811cf6ea468bb6a359b256b1e4", + "sha256:ee07e47c12890ef248766a6e55bd38ebfb2bb8edd4142d56db91b21ea68b7627", + "sha256:fa3a0128b152627161ce47201262d3140edb5a5c3da88d73a1b790a959126956", + "sha256:fcc8eb6d5902bb1cf6dc4f187ee3ea80a1eba0a89aba40a5cb20a5087d961357" + ], + "markers": "python_version >= '3.8'", + "version": "==1.16.0" }, "charset-normalizer": { "hashes": [ - "sha256:5a3d016c7c547f69d6f81fb0db9449ce888b418b5b9952cc5e6e66843e9dd845", - "sha256:83e9a75d1911279afd89352c68b45348559d1fc0506b054b346651b5e7fee29f" + "sha256:06435b539f889b1f6f4ac1758871aae42dc3a8c0e24ac9e60c2384973ad73027", + "sha256:06a81e93cd441c56a9b65d8e1d043daeb97a3d0856d177d5c90ba85acb3db087", + "sha256:0a55554a2fa0d408816b3b5cedf0045f4b8e1a6065aec45849de2d6f3f8e9786", + "sha256:0b2b64d2bb6d3fb9112bafa732def486049e63de9618b5843bcdd081d8144cd8", + "sha256:10955842570876604d404661fbccbc9c7e684caf432c09c715ec38fbae45ae09", + "sha256:122c7fa62b130ed55f8f285bfd56d5f4b4a5b503609d181f9ad85e55c89f4185", + "sha256:1ceae2f17a9c33cb48e3263960dc5fc8005351ee19db217e9b1bb15d28c02574", + "sha256:1d3193f4a680c64b4b6a9115943538edb896edc190f0b222e73761716519268e", + "sha256:1f79682fbe303db92bc2b1136016a38a42e835d932bab5b3b1bfcfbf0640e519", + "sha256:2127566c664442652f024c837091890cb1942c30937add288223dc895793f898", + "sha256:22afcb9f253dac0696b5a4be4a1c0f8762f8239e21b99680099abd9b2b1b2269", + "sha256:25baf083bf6f6b341f4121c2f3c548875ee6f5339300e08be3f2b2ba1721cdd3", + "sha256:2e81c7b9c8979ce92ed306c249d46894776a909505d8f5a4ba55b14206e3222f", + "sha256:3287761bc4ee9e33561a7e058c72ac0938c4f57fe49a09eae428fd88aafe7bb6", + "sha256:34d1c8da1e78d2e001f363791c98a272bb734000fcef47a491c1e3b0505657a8", + "sha256:37e55c8e51c236f95b033f6fb391d7d7970ba5fe7ff453dad675e88cf303377a", + "sha256:3d47fa203a7bd9c5b6cee4736ee84ca03b8ef23193c0d1ca99b5089f72645c73", + "sha256:3e4d1f6587322d2788836a99c69062fbb091331ec940e02d12d179c1d53e25fc", + "sha256:42cb296636fcc8b0644486d15c12376cb9fa75443e00fb25de0b8602e64c1714", + "sha256:45485e01ff4d3630ec0d9617310448a8702f70e9c01906b0d0118bdf9d124cf2", + "sha256:4a78b2b446bd7c934f5dcedc588903fb2f5eec172f3d29e52a9096a43722adfc", + "sha256:4ab2fe47fae9e0f9dee8c04187ce5d09f48eabe611be8259444906793ab7cbce", + "sha256:4d0d1650369165a14e14e1e47b372cfcb31d6ab44e6e33cb2d4e57265290044d", + "sha256:549a3a73da901d5bc3ce8d24e0600d1fa85524c10287f6004fbab87672bf3e1e", + "sha256:55086ee1064215781fff39a1af09518bc9255b50d6333f2e4c74ca09fac6a8f6", + "sha256:572c3763a264ba47b3cf708a44ce965d98555f618ca42c926a9c1616d8f34269", + "sha256:573f6eac48f4769d667c4442081b1794f52919e7edada77495aaed9236d13a96", + "sha256:5b4c145409bef602a690e7cfad0a15a55c13320ff7a3ad7ca59c13bb8ba4d45d", + "sha256:6463effa3186ea09411d50efc7d85360b38d5f09b870c48e4600f63af490e56a", + "sha256:65f6f63034100ead094b8744b3b97965785388f308a64cf8d7c34f2f2e5be0c4", + "sha256:663946639d296df6a2bb2aa51b60a2454ca1cb29835324c640dafb5ff2131a77", + "sha256:6897af51655e3691ff853668779c7bad41579facacf5fd7253b0133308cf000d", + "sha256:68d1f8a9e9e37c1223b656399be5d6b448dea850bed7d0f87a8311f1ff3dabb0", + "sha256:6ac7ffc7ad6d040517be39eb591cac5ff87416c2537df6ba3cba3bae290c0fed", + "sha256:6b3251890fff30ee142c44144871185dbe13b11bab478a88887a639655be1068", + "sha256:6c4caeef8fa63d06bd437cd4bdcf3ffefe6738fb1b25951440d80dc7df8c03ac", + "sha256:6ef1d82a3af9d3eecdba2321dc1b3c238245d890843e040e41e470ffa64c3e25", + "sha256:753f10e867343b4511128c6ed8c82f7bec3bd026875576dfd88483c5c73b2fd8", + "sha256:7cd13a2e3ddeed6913a65e66e94b51d80a041145a026c27e6bb76c31a853c6ab", + "sha256:7ed9e526742851e8d5cc9e6cf41427dfc6068d4f5a3bb03659444b4cabf6bc26", + "sha256:7f04c839ed0b6b98b1a7501a002144b76c18fb1c1850c8b98d458ac269e26ed2", + "sha256:802fe99cca7457642125a8a88a084cef28ff0cf9407060f7b93dca5aa25480db", + "sha256:80402cd6ee291dcb72644d6eac93785fe2c8b9cb30893c1af5b8fdd753b9d40f", + "sha256:8465322196c8b4d7ab6d1e049e4c5cb460d0394da4a27d23cc242fbf0034b6b5", + "sha256:86216b5cee4b06df986d214f664305142d9c76df9b6512be2738aa72a2048f99", + "sha256:87d1351268731db79e0f8e745d92493ee2841c974128ef629dc518b937d9194c", + "sha256:8bdb58ff7ba23002a4c5808d608e4e6c687175724f54a5dade5fa8c67b604e4d", + "sha256:8c622a5fe39a48f78944a87d4fb8a53ee07344641b0562c540d840748571b811", + "sha256:8d756e44e94489e49571086ef83b2bb8ce311e730092d2c34ca8f7d925cb20aa", + "sha256:8f4a014bc36d3c57402e2977dada34f9c12300af536839dc38c0beab8878f38a", + "sha256:9063e24fdb1e498ab71cb7419e24622516c4a04476b17a2dab57e8baa30d6e03", + "sha256:90d558489962fd4918143277a773316e56c72da56ec7aa3dc3dbbe20fdfed15b", + "sha256:923c0c831b7cfcb071580d3f46c4baf50f174be571576556269530f4bbd79d04", + "sha256:95f2a5796329323b8f0512e09dbb7a1860c46a39da62ecb2324f116fa8fdc85c", + "sha256:96b02a3dc4381e5494fad39be677abcb5e6634bf7b4fa83a6dd3112607547001", + "sha256:9f96df6923e21816da7e0ad3fd47dd8f94b2a5ce594e00677c0013018b813458", + "sha256:a10af20b82360ab00827f916a6058451b723b4e65030c5a18577c8b2de5b3389", + "sha256:a50aebfa173e157099939b17f18600f72f84eed3049e743b68ad15bd69b6bf99", + "sha256:a981a536974bbc7a512cf44ed14938cf01030a99e9b3a06dd59578882f06f985", + "sha256:a9a8e9031d613fd2009c182b69c7b2c1ef8239a0efb1df3f7c8da66d5dd3d537", + "sha256:ae5f4161f18c61806f411a13b0310bea87f987c7d2ecdbdaad0e94eb2e404238", + "sha256:aed38f6e4fb3f5d6bf81bfa990a07806be9d83cf7bacef998ab1a9bd660a581f", + "sha256:b01b88d45a6fcb69667cd6d2f7a9aeb4bf53760d7fc536bf679ec94fe9f3ff3d", + "sha256:b261ccdec7821281dade748d088bb6e9b69e6d15b30652b74cbbac25e280b796", + "sha256:b2b0a0c0517616b6869869f8c581d4eb2dd83a4d79e0ebcb7d373ef9956aeb0a", + "sha256:b4a23f61ce87adf89be746c8a8974fe1c823c891d8f86eb218bb957c924bb143", + "sha256:bd8f7df7d12c2db9fab40bdd87a7c09b1530128315d047a086fa3ae3435cb3a8", + "sha256:beb58fe5cdb101e3a055192ac291b7a21e3b7ef4f67fa1d74e331a7f2124341c", + "sha256:c002b4ffc0be611f0d9da932eb0f704fe2602a9a949d1f738e4c34c75b0863d5", + "sha256:c083af607d2515612056a31f0a8d9e0fcb5876b7bfc0abad3ecd275bc4ebc2d5", + "sha256:c180f51afb394e165eafe4ac2936a14bee3eb10debc9d9e4db8958fe36afe711", + "sha256:c235ebd9baae02f1b77bcea61bce332cb4331dc3617d254df3323aa01ab47bd4", + "sha256:cd70574b12bb8a4d2aaa0094515df2463cb429d8536cfb6c7ce983246983e5a6", + "sha256:d0eccceffcb53201b5bfebb52600a5fb483a20b61da9dbc885f8b103cbe7598c", + "sha256:d965bba47ddeec8cd560687584e88cf699fd28f192ceb452d1d7ee807c5597b7", + "sha256:db364eca23f876da6f9e16c9da0df51aa4f104a972735574842618b8c6d999d4", + "sha256:ddbb2551d7e0102e7252db79ba445cdab71b26640817ab1e3e3648dad515003b", + "sha256:deb6be0ac38ece9ba87dea880e438f25ca3eddfac8b002a2ec3d9183a454e8ae", + "sha256:e06ed3eb3218bc64786f7db41917d4e686cc4856944f53d5bdf83a6884432e12", + "sha256:e27ad930a842b4c5eb8ac0016b0a54f5aebbe679340c26101df33424142c143c", + "sha256:e537484df0d8f426ce2afb2d0f8e1c3d0b114b83f8850e5f2fbea0e797bd82ae", + "sha256:eb00ed941194665c332bf8e078baf037d6c35d7c4f3102ea2d4f16ca94a26dc8", + "sha256:eb6904c354526e758fda7167b33005998fb68c46fbc10e013ca97f21ca5c8887", + "sha256:eb8821e09e916165e160797a6c17edda0679379a4be5c716c260e836e122f54b", + "sha256:efcb3f6676480691518c177e3b465bcddf57cea040302f9f4e6e191af91174d4", + "sha256:f27273b60488abe721a075bcca6d7f3964f9f6f067c8c4c605743023d7d3944f", + "sha256:f30c3cb33b24454a82faecaf01b19c18562b1e89558fb6c56de4d9118a032fd5", + "sha256:fb69256e180cb6c8a894fee62b3afebae785babc1ee98b81cdf68bbca1987f33", + "sha256:fd1abc0d89e30cc4e02e4064dc67fcc51bd941eb395c502aac3ec19fab46b519", + "sha256:ff8fa367d09b717b2a17a052544193ad76cd49979c805768879cb63d9ca50561" ], - "markers": "python_version >= '3.6'", - "version": "==2.1.1" + "markers": "python_full_version >= '3.7.0'", + "version": "==3.3.2" }, "colorama": { "hashes": [ - "sha256:854bf444933e37f5824ae7bfc1e98d5bce2ebe4160d46b5edf346a89358e99da", - "sha256:e6c6b4334fc50988a639d9b98aa429a0b57da6e17b9a44f0451f930b6967b7a4" + "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", + "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6" ], "index": "pypi", - "version": "==0.4.5" + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5, 3.6'", + "version": "==0.4.6" }, "cssselect2": { "hashes": [ @@ -240,92 +420,99 @@ "version": "==0.7.1" }, "discord.py": { + "extras": [ + "speed" + ], "hashes": [ - "sha256:309146476e986cb8faf038cd5d604d4b3834ef15c2d34df697ce5064bf5cd779", - "sha256:aeb186348bf011708b085b2715cf92bbb72c692eb4f59c4c0b488130cc4c4b7e" + "sha256:4560f70f2eddba7e83370ecebd237ac09fbb4980dc66507482b0c0e5b8f76b9c", + "sha256:9da4679fc3cb10c64b388284700dc998663e0e57328283bbfcfc2525ec5960a6" ], - "index": "pypi", - "version": "==2.0.1" + "markers": "python_full_version >= '3.8.0'", + "version": "==2.3.2" }, "dnspython": { "hashes": [ - "sha256:0f7569a4a6ff151958b64304071d370daa3243d15941a7beedf0c9fe5105603e", - "sha256:a851e51367fb93e9e1361732c1d60dab63eff98712e503ea7d92e6eccb109b4f" + "sha256:57c6fbaaeaaf39c891292012060beb141791735dbb4004798328fc2c467402d8", + "sha256:8dcfae8c7460a2f84b4072e26f1c9f4101ca20c071649cb7c34e8b6a93d58984" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==2.2.1" + "markers": "python_version >= '3.8' and python_version < '4.0'", + "version": "==2.4.2" }, "emoji": { "hashes": [ - "sha256:65c54533ea3c78f30d0729288998715f418d7467de89ec258a31c0ce8660a1d1" + "sha256:8d8b5dec3c507444b58890e598fc895fcec022b3f5acb49497c6ccc5208b8b00", + "sha256:a8468fd836b7ecb6d1eac054c9a591701ce0ccd6c6f7779ad71b66f76664df90" ], "index": "pypi", - "version": "==1.7.0" + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "version": "==2.8.0" }, "frozenlist": { "hashes": [ - "sha256:022178b277cb9277d7d3b3f2762d294f15e85cd2534047e68a118c2bb0058f3e", - "sha256:086ca1ac0a40e722d6833d4ce74f5bf1aba2c77cbfdc0cd83722ffea6da52a04", - "sha256:0bc75692fb3770cf2b5856a6c2c9de967ca744863c5e89595df64e252e4b3944", - "sha256:0dde791b9b97f189874d654c55c24bf7b6782343e14909c84beebd28b7217845", - "sha256:12607804084d2244a7bd4685c9d0dca5df17a6a926d4f1967aa7978b1028f89f", - "sha256:19127f8dcbc157ccb14c30e6f00392f372ddb64a6ffa7106b26ff2196477ee9f", - "sha256:1b51eb355e7f813bcda00276b0114c4172872dc5fb30e3fea059b9367c18fbcb", - "sha256:1e1cf7bc8cbbe6ce3881863671bac258b7d6bfc3706c600008925fb799a256e2", - "sha256:219a9676e2eae91cb5cc695a78b4cb43d8123e4160441d2b6ce8d2c70c60e2f3", - "sha256:2743bb63095ef306041c8f8ea22bd6e4d91adabf41887b1ad7886c4c1eb43d5f", - "sha256:2af6f7a4e93f5d08ee3f9152bce41a6015b5cf87546cb63872cc19b45476e98a", - "sha256:31b44f1feb3630146cffe56344704b730c33e042ffc78d21f2125a6a91168131", - "sha256:31bf9539284f39ff9398deabf5561c2b0da5bb475590b4e13dd8b268d7a3c5c1", - "sha256:35c3d79b81908579beb1fb4e7fcd802b7b4921f1b66055af2578ff7734711cfa", - "sha256:3a735e4211a04ccfa3f4833547acdf5d2f863bfeb01cfd3edaffbc251f15cec8", - "sha256:42719a8bd3792744c9b523674b752091a7962d0d2d117f0b417a3eba97d1164b", - "sha256:49459f193324fbd6413e8e03bd65789e5198a9fa3095e03f3620dee2f2dabff2", - "sha256:4c0c99e31491a1d92cde8648f2e7ccad0e9abb181f6ac3ddb9fc48b63301808e", - "sha256:52137f0aea43e1993264a5180c467a08a3e372ca9d378244c2d86133f948b26b", - "sha256:526d5f20e954d103b1d47232e3839f3453c02077b74203e43407b962ab131e7b", - "sha256:53b2b45052e7149ee8b96067793db8ecc1ae1111f2f96fe1f88ea5ad5fd92d10", - "sha256:572ce381e9fe027ad5e055f143763637dcbac2542cfe27f1d688846baeef5170", - "sha256:58fb94a01414cddcdc6839807db77ae8057d02ddafc94a42faee6004e46c9ba8", - "sha256:5e77a8bd41e54b05e4fb2708dc6ce28ee70325f8c6f50f3df86a44ecb1d7a19b", - "sha256:5f271c93f001748fc26ddea409241312a75e13466b06c94798d1a341cf0e6989", - "sha256:5f63c308f82a7954bf8263a6e6de0adc67c48a8b484fab18ff87f349af356efd", - "sha256:61d7857950a3139bce035ad0b0945f839532987dfb4c06cfe160254f4d19df03", - "sha256:61e8cb51fba9f1f33887e22488bad1e28dd8325b72425f04517a4d285a04c519", - "sha256:625d8472c67f2d96f9a4302a947f92a7adbc1e20bedb6aff8dbc8ff039ca6189", - "sha256:6e19add867cebfb249b4e7beac382d33215d6d54476bb6be46b01f8cafb4878b", - "sha256:717470bfafbb9d9be624da7780c4296aa7935294bd43a075139c3d55659038ca", - "sha256:74140933d45271c1a1283f708c35187f94e1256079b3c43f0c2267f9db5845ff", - "sha256:74e6b2b456f21fc93ce1aff2b9728049f1464428ee2c9752a4b4f61e98c4db96", - "sha256:9494122bf39da6422b0972c4579e248867b6b1b50c9b05df7e04a3f30b9a413d", - "sha256:94e680aeedc7fd3b892b6fa8395b7b7cc4b344046c065ed4e7a1e390084e8cb5", - "sha256:97d9e00f3ac7c18e685320601f91468ec06c58acc185d18bb8e511f196c8d4b2", - "sha256:9c6ef8014b842f01f5d2b55315f1af5cbfde284eb184075c189fd657c2fd8204", - "sha256:a027f8f723d07c3f21963caa7d585dcc9b089335565dabe9c814b5f70c52705a", - "sha256:a718b427ff781c4f4e975525edb092ee2cdef6a9e7bc49e15063b088961806f8", - "sha256:ab386503f53bbbc64d1ad4b6865bf001414930841a870fc97f1546d4d133f141", - "sha256:ab6fa8c7871877810e1b4e9392c187a60611fbf0226a9e0b11b7b92f5ac72792", - "sha256:b47d64cdd973aede3dd71a9364742c542587db214e63b7529fbb487ed67cddd9", - "sha256:b499c6abe62a7a8d023e2c4b2834fce78a6115856ae95522f2f974139814538c", - "sha256:bbb1a71b1784e68870800b1bc9f3313918edc63dbb8f29fbd2e767ce5821696c", - "sha256:c3b31180b82c519b8926e629bf9f19952c743e089c41380ddca5db556817b221", - "sha256:c56c299602c70bc1bb5d1e75f7d8c007ca40c9d7aebaf6e4ba52925d88ef826d", - "sha256:c92deb5d9acce226a501b77307b3b60b264ca21862bd7d3e0c1f3594022f01bc", - "sha256:cc2f3e368ee5242a2cbe28323a866656006382872c40869b49b265add546703f", - "sha256:d82bed73544e91fb081ab93e3725e45dd8515c675c0e9926b4e1f420a93a6ab9", - "sha256:da1cdfa96425cbe51f8afa43e392366ed0b36ce398f08b60de6b97e3ed4affef", - "sha256:da5ba7b59d954f1f214d352308d1d86994d713b13edd4b24a556bcc43d2ddbc3", - "sha256:e0c8c803f2f8db7217898d11657cb6042b9b0553a997c4a0601f48a691480fab", - "sha256:ee4c5120ddf7d4dd1eaf079af3af7102b56d919fa13ad55600a4e0ebe532779b", - "sha256:eee0c5ecb58296580fc495ac99b003f64f82a74f9576a244d04978a7e97166db", - "sha256:f5abc8b4d0c5b556ed8cd41490b606fe99293175a82b98e652c3f2711b452988", - "sha256:f810e764617b0748b49a731ffaa525d9bb36ff38332411704c2400125af859a6", - "sha256:f89139662cc4e65a4813f4babb9ca9544e42bddb823d2ec434e18dad582543bc", - "sha256:fa47319a10e0a076709644a0efbcaab9e91902c8bd8ef74c6adb19d320f69b83", - "sha256:fabb953ab913dadc1ff9dcc3a7a7d3dc6a92efab3a0373989b8063347f8705be" + "sha256:007df07a6e3eb3e33e9a1fe6a9db7af152bbd8a185f9aaa6ece10a3529e3e1c6", + "sha256:008eb8b31b3ea6896da16c38c1b136cb9fec9e249e77f6211d479db79a4eaf01", + "sha256:09163bdf0b2907454042edb19f887c6d33806adc71fbd54afc14908bfdc22251", + "sha256:0c7c1b47859ee2cac3846fde1c1dc0f15da6cec5a0e5c72d101e0f83dcb67ff9", + "sha256:0e5c8764c7829343d919cc2dfc587a8db01c4f70a4ebbc49abde5d4b158b007b", + "sha256:10ff5faaa22786315ef57097a279b833ecab1a0bfb07d604c9cbb1c4cdc2ed87", + "sha256:17ae5cd0f333f94f2e03aaf140bb762c64783935cc764ff9c82dff626089bebf", + "sha256:19488c57c12d4e8095a922f328df3f179c820c212940a498623ed39160bc3c2f", + "sha256:1a0848b52815006ea6596c395f87449f693dc419061cc21e970f139d466dc0a0", + "sha256:1e78fb68cf9c1a6aa4a9a12e960a5c9dfbdb89b3695197aa7064705662515de2", + "sha256:261b9f5d17cac914531331ff1b1d452125bf5daa05faf73b71d935485b0c510b", + "sha256:2b8bcf994563466db019fab287ff390fffbfdb4f905fc77bc1c1d604b1c689cc", + "sha256:38461d02d66de17455072c9ba981d35f1d2a73024bee7790ac2f9e361ef1cd0c", + "sha256:490132667476f6781b4c9458298b0c1cddf237488abd228b0b3650e5ecba7467", + "sha256:491e014f5c43656da08958808588cc6c016847b4360e327a62cb308c791bd2d9", + "sha256:515e1abc578dd3b275d6a5114030b1330ba044ffba03f94091842852f806f1c1", + "sha256:556de4430ce324c836789fa4560ca62d1591d2538b8ceb0b4f68fb7b2384a27a", + "sha256:5833593c25ac59ede40ed4de6d67eb42928cca97f26feea219f21d0ed0959b79", + "sha256:6221d84d463fb110bdd7619b69cb43878a11d51cbb9394ae3105d082d5199167", + "sha256:6918d49b1f90821e93069682c06ffde41829c346c66b721e65a5c62b4bab0300", + "sha256:6c38721585f285203e4b4132a352eb3daa19121a035f3182e08e437cface44bf", + "sha256:71932b597f9895f011f47f17d6428252fc728ba2ae6024e13c3398a087c2cdea", + "sha256:7211ef110a9194b6042449431e08c4d80c0481e5891e58d429df5899690511c2", + "sha256:764226ceef3125e53ea2cb275000e309c0aa5464d43bd72abd661e27fffc26ab", + "sha256:7645a8e814a3ee34a89c4a372011dcd817964ce8cb273c8ed6119d706e9613e3", + "sha256:76d4711f6f6d08551a7e9ef28c722f4a50dd0fc204c56b4bcd95c6cc05ce6fbb", + "sha256:7f4f399d28478d1f604c2ff9119907af9726aed73680e5ed1ca634d377abb087", + "sha256:88f7bc0fcca81f985f78dd0fa68d2c75abf8272b1f5c323ea4a01a4d7a614efc", + "sha256:8d0edd6b1c7fb94922bf569c9b092ee187a83f03fb1a63076e7774b60f9481a8", + "sha256:901289d524fdd571be1c7be054f48b1f88ce8dddcbdf1ec698b27d4b8b9e5d62", + "sha256:93ea75c050c5bb3d98016b4ba2497851eadf0ac154d88a67d7a6816206f6fa7f", + "sha256:981b9ab5a0a3178ff413bca62526bb784249421c24ad7381e39d67981be2c326", + "sha256:9ac08e601308e41eb533f232dbf6b7e4cea762f9f84f6357136eed926c15d12c", + "sha256:a02eb8ab2b8f200179b5f62b59757685ae9987996ae549ccf30f983f40602431", + "sha256:a0c6da9aee33ff0b1a451e867da0c1f47408112b3391dd43133838339e410963", + "sha256:a6c8097e01886188e5be3e6b14e94ab365f384736aa1fca6a0b9e35bd4a30bc7", + "sha256:aa384489fefeb62321b238e64c07ef48398fe80f9e1e6afeff22e140e0850eef", + "sha256:ad2a9eb6d9839ae241701d0918f54c51365a51407fd80f6b8289e2dfca977cc3", + "sha256:b206646d176a007466358aa21d85cd8600a415c67c9bd15403336c331a10d956", + "sha256:b826d97e4276750beca7c8f0f1a4938892697a6bcd8ec8217b3312dad6982781", + "sha256:b89ac9768b82205936771f8d2eb3ce88503b1556324c9f903e7156669f521472", + "sha256:bd7bd3b3830247580de99c99ea2a01416dfc3c34471ca1298bccabf86d0ff4dc", + "sha256:bdf1847068c362f16b353163391210269e4f0569a3c166bc6a9f74ccbfc7e839", + "sha256:c11b0746f5d946fecf750428a95f3e9ebe792c1ee3b1e96eeba145dc631a9672", + "sha256:c5374b80521d3d3f2ec5572e05adc94601985cc526fb276d0c8574a6d749f1b3", + "sha256:ca265542ca427bf97aed183c1676e2a9c66942e822b14dc6e5f42e038f92a503", + "sha256:ce31ae3e19f3c902de379cf1323d90c649425b86de7bbdf82871b8a2a0615f3d", + "sha256:ceb6ec0a10c65540421e20ebd29083c50e6d1143278746a4ef6bcf6153171eb8", + "sha256:d081f13b095d74b67d550de04df1c756831f3b83dc9881c38985834387487f1b", + "sha256:d5655a942f5f5d2c9ed93d72148226d75369b4f6952680211972a33e59b1dfdc", + "sha256:d5a32087d720c608f42caed0ef36d2b3ea61a9d09ee59a5142d6070da9041b8f", + "sha256:d6484756b12f40003c6128bfcc3fa9f0d49a687e171186c2d85ec82e3758c559", + "sha256:dd65632acaf0d47608190a71bfe46b209719bf2beb59507db08ccdbe712f969b", + "sha256:de343e75f40e972bae1ef6090267f8260c1446a1695e77096db6cfa25e759a95", + "sha256:e29cda763f752553fa14c68fb2195150bfab22b352572cb36c43c47bedba70eb", + "sha256:e41f3de4df3e80de75845d3e743b3f1c4c8613c3997a912dbf0229fc61a8b963", + "sha256:e66d2a64d44d50d2543405fb183a21f76b3b5fd16f130f5c99187c3fb4e64919", + "sha256:e74b0506fa5aa5598ac6a975a12aa8928cbb58e1f5ac8360792ef15de1aa848f", + "sha256:f0ed05f5079c708fe74bf9027e95125334b6978bf07fd5ab923e9e55e5fbb9d3", + "sha256:f61e2dc5ad442c52b4887f1fdc112f97caeff4d9e6ebe78879364ac59f1663e1", + "sha256:fec520865f42e5c7f050c2a79038897b1c7d1595e907a9e08e3353293ffc948e" ], - "markers": "python_version >= '3.7'", - "version": "==1.3.1" + "markers": "python_version >= '3.8'", + "version": "==1.4.0" }, "idna": { "hashes": [ @@ -348,83 +535,99 @@ "pdf" ], "hashes": [ - "sha256:d53e96265887aa9187c7c707fd612b3d52f38da64c81ea82297783efb47f7e3f" + "sha256:a3242f8ba37051fbdd7503ecd168203a08e4af26f17be2ecca08a64af1e7d3c1" ], - "index": "pypi", - "version": "==0.6.11" + "markers": "python_version >= '3'", + "version": "==0.7.0" }, "motor": { "hashes": [ - "sha256:663473f4498f955d35db7b6f25651cb165514c247136f368b84419cb7635f6b8", - "sha256:961fdceacaae2c7236c939166f66415be81be8bbb762da528386738de3a0f509" + "sha256:6fe7e6f0c4f430b9e030b9d22549b732f7c2226af3ab71ecc309e4a1b7d19953", + "sha256:d2fc38de15f1c8058f389c1a44a4d4105c0405c48c061cd492a654496f7bc26a" ], "index": "pypi", - "version": "==2.5.1" + "markers": "python_version >= '3.7'", + "version": "==3.3.2" }, "multidict": { "hashes": [ - "sha256:0327292e745a880459ef71be14e709aaea2f783f3537588fb4ed09b6c01bca60", - "sha256:041b81a5f6b38244b34dc18c7b6aba91f9cdaf854d9a39e5ff0b58e2b5773b9c", - "sha256:0556a1d4ea2d949efe5fd76a09b4a82e3a4a30700553a6725535098d8d9fb672", - "sha256:05f6949d6169878a03e607a21e3b862eaf8e356590e8bdae4227eedadacf6e51", - "sha256:07a017cfa00c9890011628eab2503bee5872f27144936a52eaab449be5eaf032", - "sha256:0b9e95a740109c6047602f4db4da9949e6c5945cefbad34a1299775ddc9a62e2", - "sha256:19adcfc2a7197cdc3987044e3f415168fc5dc1f720c932eb1ef4f71a2067e08b", - "sha256:19d9bad105dfb34eb539c97b132057a4e709919ec4dd883ece5838bcbf262b80", - "sha256:225383a6603c086e6cef0f2f05564acb4f4d5f019a4e3e983f572b8530f70c88", - "sha256:23b616fdc3c74c9fe01d76ce0d1ce872d2d396d8fa8e4899398ad64fb5aa214a", - "sha256:2957489cba47c2539a8eb7ab32ff49101439ccf78eab724c828c1a54ff3ff98d", - "sha256:2d36e929d7f6a16d4eb11b250719c39560dd70545356365b494249e2186bc389", - "sha256:2e4a0785b84fb59e43c18a015ffc575ba93f7d1dbd272b4cdad9f5134b8a006c", - "sha256:3368bf2398b0e0fcbf46d85795adc4c259299fec50c1416d0f77c0a843a3eed9", - "sha256:373ba9d1d061c76462d74e7de1c0c8e267e9791ee8cfefcf6b0b2495762c370c", - "sha256:4070613ea2227da2bfb2c35a6041e4371b0af6b0be57f424fe2318b42a748516", - "sha256:45183c96ddf61bf96d2684d9fbaf6f3564d86b34cb125761f9a0ef9e36c1d55b", - "sha256:4571f1beddff25f3e925eea34268422622963cd8dc395bb8778eb28418248e43", - "sha256:47e6a7e923e9cada7c139531feac59448f1f47727a79076c0b1ee80274cd8eee", - "sha256:47fbeedbf94bed6547d3aa632075d804867a352d86688c04e606971595460227", - "sha256:497988d6b6ec6ed6f87030ec03280b696ca47dbf0648045e4e1d28b80346560d", - "sha256:4bae31803d708f6f15fd98be6a6ac0b6958fcf68fda3c77a048a4f9073704aae", - "sha256:50bd442726e288e884f7be9071016c15a8742eb689a593a0cac49ea093eef0a7", - "sha256:514fe2b8d750d6cdb4712346a2c5084a80220821a3e91f3f71eec11cf8d28fd4", - "sha256:5774d9218d77befa7b70d836004a768fb9aa4fdb53c97498f4d8d3f67bb9cfa9", - "sha256:5fdda29a3c7e76a064f2477c9aab1ba96fd94e02e386f1e665bca1807fc5386f", - "sha256:5ff3bd75f38e4c43f1f470f2df7a4d430b821c4ce22be384e1459cb57d6bb013", - "sha256:626fe10ac87851f4cffecee161fc6f8f9853f0f6f1035b59337a51d29ff3b4f9", - "sha256:6701bf8a5d03a43375909ac91b6980aea74b0f5402fbe9428fc3f6edf5d9677e", - "sha256:684133b1e1fe91eda8fa7447f137c9490a064c6b7f392aa857bba83a28cfb693", - "sha256:6f3cdef8a247d1eafa649085812f8a310e728bdf3900ff6c434eafb2d443b23a", - "sha256:75bdf08716edde767b09e76829db8c1e5ca9d8bb0a8d4bd94ae1eafe3dac5e15", - "sha256:7c40b7bbece294ae3a87c1bc2abff0ff9beef41d14188cda94ada7bcea99b0fb", - "sha256:8004dca28e15b86d1b1372515f32eb6f814bdf6f00952699bdeb541691091f96", - "sha256:8064b7c6f0af936a741ea1efd18690bacfbae4078c0c385d7c3f611d11f0cf87", - "sha256:89171b2c769e03a953d5969b2f272efa931426355b6c0cb508022976a17fd376", - "sha256:8cbf0132f3de7cc6c6ce00147cc78e6439ea736cee6bca4f068bcf892b0fd658", - "sha256:9cc57c68cb9139c7cd6fc39f211b02198e69fb90ce4bc4a094cf5fe0d20fd8b0", - "sha256:a007b1638e148c3cfb6bf0bdc4f82776cef0ac487191d093cdc316905e504071", - "sha256:a2c34a93e1d2aa35fbf1485e5010337c72c6791407d03aa5f4eed920343dd360", - "sha256:a45e1135cb07086833ce969555df39149680e5471c04dfd6a915abd2fc3f6dbc", - "sha256:ac0e27844758d7177989ce406acc6a83c16ed4524ebc363c1f748cba184d89d3", - "sha256:aef9cc3d9c7d63d924adac329c33835e0243b5052a6dfcbf7732a921c6e918ba", - "sha256:b9d153e7f1f9ba0b23ad1568b3b9e17301e23b042c23870f9ee0522dc5cc79e8", - "sha256:bfba7c6d5d7c9099ba21f84662b037a0ffd4a5e6b26ac07d19e423e6fdf965a9", - "sha256:c207fff63adcdf5a485969131dc70e4b194327666b7e8a87a97fbc4fd80a53b2", - "sha256:d0509e469d48940147e1235d994cd849a8f8195e0bca65f8f5439c56e17872a3", - "sha256:d16cce709ebfadc91278a1c005e3c17dd5f71f5098bfae1035149785ea6e9c68", - "sha256:d48b8ee1d4068561ce8033d2c344cf5232cb29ee1a0206a7b828c79cbc5982b8", - "sha256:de989b195c3d636ba000ee4281cd03bb1234635b124bf4cd89eeee9ca8fcb09d", - "sha256:e07c8e79d6e6fd37b42f3250dba122053fddb319e84b55dd3a8d6446e1a7ee49", - "sha256:e2c2e459f7050aeb7c1b1276763364884595d47000c1cddb51764c0d8976e608", - "sha256:e5b20e9599ba74391ca0cfbd7b328fcc20976823ba19bc573983a25b32e92b57", - "sha256:e875b6086e325bab7e680e4316d667fc0e5e174bb5611eb16b3ea121c8951b86", - "sha256:f4f052ee022928d34fe1f4d2bc743f32609fb79ed9c49a1710a5ad6b2198db20", - "sha256:fcb91630817aa8b9bc4a74023e4198480587269c272c58b3279875ed7235c293", - "sha256:fd9fc9c4849a07f3635ccffa895d57abce554b467d611a5009ba4f39b78a8849", - "sha256:feba80698173761cddd814fa22e88b0661e98cb810f9f986c54aa34d281e4937", - "sha256:feea820722e69451743a3d56ad74948b68bf456984d63c1a92e8347b7b88452d" + "sha256:01a3a55bd90018c9c080fbb0b9f4891db37d148a0a18722b42f94694f8b6d4c9", + "sha256:0b1a97283e0c85772d613878028fec909f003993e1007eafa715b24b377cb9b8", + "sha256:0dfad7a5a1e39c53ed00d2dd0c2e36aed4650936dc18fd9a1826a5ae1cad6f03", + "sha256:11bdf3f5e1518b24530b8241529d2050014c884cf18b6fc69c0c2b30ca248710", + "sha256:1502e24330eb681bdaa3eb70d6358e818e8e8f908a22a1851dfd4e15bc2f8161", + "sha256:16ab77bbeb596e14212e7bab8429f24c1579234a3a462105cda4a66904998664", + "sha256:16d232d4e5396c2efbbf4f6d4df89bfa905eb0d4dc5b3549d872ab898451f569", + "sha256:21a12c4eb6ddc9952c415f24eef97e3e55ba3af61f67c7bc388dcdec1404a067", + "sha256:27c523fbfbdfd19c6867af7346332b62b586eed663887392cff78d614f9ec313", + "sha256:281af09f488903fde97923c7744bb001a9b23b039a909460d0f14edc7bf59706", + "sha256:33029f5734336aa0d4c0384525da0387ef89148dc7191aae00ca5fb23d7aafc2", + "sha256:3601a3cece3819534b11d4efc1eb76047488fddd0c85a3948099d5da4d504636", + "sha256:3666906492efb76453c0e7b97f2cf459b0682e7402c0489a95484965dbc1da49", + "sha256:36c63aaa167f6c6b04ef2c85704e93af16c11d20de1d133e39de6a0e84582a93", + "sha256:39ff62e7d0f26c248b15e364517a72932a611a9b75f35b45be078d81bdb86603", + "sha256:43644e38f42e3af682690876cff722d301ac585c5b9e1eacc013b7a3f7b696a0", + "sha256:4372381634485bec7e46718edc71528024fcdc6f835baefe517b34a33c731d60", + "sha256:458f37be2d9e4c95e2d8866a851663cbc76e865b78395090786f6cd9b3bbf4f4", + "sha256:45e1ecb0379bfaab5eef059f50115b54571acfbe422a14f668fc8c27ba410e7e", + "sha256:4b9d9e4e2b37daddb5c23ea33a3417901fa7c7b3dee2d855f63ee67a0b21e5b1", + "sha256:4ceef517eca3e03c1cceb22030a3e39cb399ac86bff4e426d4fc6ae49052cc60", + "sha256:4d1a3d7ef5e96b1c9e92f973e43aa5e5b96c659c9bc3124acbbd81b0b9c8a951", + "sha256:4dcbb0906e38440fa3e325df2359ac6cb043df8e58c965bb45f4e406ecb162cc", + "sha256:509eac6cf09c794aa27bcacfd4d62c885cce62bef7b2c3e8b2e49d365b5003fe", + "sha256:52509b5be062d9eafc8170e53026fbc54cf3b32759a23d07fd935fb04fc22d95", + "sha256:52f2dffc8acaba9a2f27174c41c9e57f60b907bb9f096b36b1a1f3be71c6284d", + "sha256:574b7eae1ab267e5f8285f0fe881f17efe4b98c39a40858247720935b893bba8", + "sha256:5979b5632c3e3534e42ca6ff856bb24b2e3071b37861c2c727ce220d80eee9ed", + "sha256:59d43b61c59d82f2effb39a93c48b845efe23a3852d201ed2d24ba830d0b4cf2", + "sha256:5a4dcf02b908c3b8b17a45fb0f15b695bf117a67b76b7ad18b73cf8e92608775", + "sha256:5cad9430ab3e2e4fa4a2ef4450f548768400a2ac635841bc2a56a2052cdbeb87", + "sha256:5fc1b16f586f049820c5c5b17bb4ee7583092fa0d1c4e28b5239181ff9532e0c", + "sha256:62501642008a8b9871ddfccbf83e4222cf8ac0d5aeedf73da36153ef2ec222d2", + "sha256:64bdf1086b6043bf519869678f5f2757f473dee970d7abf6da91ec00acb9cb98", + "sha256:64da238a09d6039e3bd39bb3aee9c21a5e34f28bfa5aa22518581f910ff94af3", + "sha256:666daae833559deb2d609afa4490b85830ab0dfca811a98b70a205621a6109fe", + "sha256:67040058f37a2a51ed8ea8f6b0e6ee5bd78ca67f169ce6122f3e2ec80dfe9b78", + "sha256:6748717bb10339c4760c1e63da040f5f29f5ed6e59d76daee30305894069a660", + "sha256:6b181d8c23da913d4ff585afd1155a0e1194c0b50c54fcfe286f70cdaf2b7176", + "sha256:6ed5f161328b7df384d71b07317f4d8656434e34591f20552c7bcef27b0ab88e", + "sha256:7582a1d1030e15422262de9f58711774e02fa80df0d1578995c76214f6954988", + "sha256:7d18748f2d30f94f498e852c67d61261c643b349b9d2a581131725595c45ec6c", + "sha256:7d6ae9d593ef8641544d6263c7fa6408cc90370c8cb2bbb65f8d43e5b0351d9c", + "sha256:81a4f0b34bd92df3da93315c6a59034df95866014ac08535fc819f043bfd51f0", + "sha256:8316a77808c501004802f9beebde51c9f857054a0c871bd6da8280e718444449", + "sha256:853888594621e6604c978ce2a0444a1e6e70c8d253ab65ba11657659dcc9100f", + "sha256:99b76c052e9f1bc0721f7541e5e8c05db3941eb9ebe7b8553c625ef88d6eefde", + "sha256:a2e4369eb3d47d2034032a26c7a80fcb21a2cb22e1173d761a162f11e562caa5", + "sha256:ab55edc2e84460694295f401215f4a58597f8f7c9466faec545093045476327d", + "sha256:af048912e045a2dc732847d33821a9d84ba553f5c5f028adbd364dd4765092ac", + "sha256:b1a2eeedcead3a41694130495593a559a668f382eee0727352b9a41e1c45759a", + "sha256:b1e8b901e607795ec06c9e42530788c45ac21ef3aaa11dbd0c69de543bfb79a9", + "sha256:b41156839806aecb3641f3208c0dafd3ac7775b9c4c422d82ee2a45c34ba81ca", + "sha256:b692f419760c0e65d060959df05f2a531945af31fda0c8a3b3195d4efd06de11", + "sha256:bc779e9e6f7fda81b3f9aa58e3a6091d49ad528b11ed19f6621408806204ad35", + "sha256:bf6774e60d67a9efe02b3616fee22441d86fab4c6d335f9d2051d19d90a40063", + "sha256:c048099e4c9e9d615545e2001d3d8a4380bd403e1a0578734e0d31703d1b0c0b", + "sha256:c5cb09abb18c1ea940fb99360ea0396f34d46566f157122c92dfa069d3e0e982", + "sha256:cc8e1d0c705233c5dd0c5e6460fbad7827d5d36f310a0fadfd45cc3029762258", + "sha256:d5e3fc56f88cc98ef8139255cf8cd63eb2c586531e43310ff859d6bb3a6b51f1", + "sha256:d6aa0418fcc838522256761b3415822626f866758ee0bc6632c9486b179d0b52", + "sha256:d6c254ba6e45d8e72739281ebc46ea5eb5f101234f3ce171f0e9f5cc86991480", + "sha256:d6d635d5209b82a3492508cf5b365f3446afb65ae7ebd755e70e18f287b0adf7", + "sha256:dcfe792765fab89c365123c81046ad4103fcabbc4f56d1c1997e6715e8015461", + "sha256:ddd3915998d93fbcd2566ddf9cf62cdb35c9e093075f862935573d265cf8f65d", + "sha256:ddff9c4e225a63a5afab9dd15590432c22e8057e1a9a13d28ed128ecf047bbdc", + "sha256:e41b7e2b59679edfa309e8db64fdf22399eec4b0b24694e1b2104fb789207779", + "sha256:e69924bfcdda39b722ef4d9aa762b2dd38e4632b3641b1d9a57ca9cd18f2f83a", + "sha256:ea20853c6dbbb53ed34cb4d080382169b6f4554d394015f1bef35e881bf83547", + "sha256:ee2a1ece51b9b9e7752e742cfb661d2a29e7bcdba2d27e66e28a99f1890e4fa0", + "sha256:eeb6dcc05e911516ae3d1f207d4b0520d07f54484c49dfc294d6e7d63b734171", + "sha256:f70b98cd94886b49d91170ef23ec5c0e8ebb6f242d734ed7ed677b24d50c82cf", + "sha256:fc35cb4676846ef752816d5be2193a1e8367b4c1397b74a565a9d0389c433a1d", + "sha256:ff959bee35038c4624250473988b24f846cbeb2c6639de3602c073f10410ceba" ], "markers": "python_version >= '3.7'", - "version": "==6.0.2" + "version": "==6.0.4" }, "natural": { "hashes": [ @@ -433,6 +636,70 @@ "index": "pypi", "version": "==0.2.0" }, + "orjson": { + "hashes": [ + "sha256:06ad5543217e0e46fd7ab7ea45d506c76f878b87b1b4e369006bdb01acc05a83", + "sha256:0a73160e823151f33cdc05fe2cea557c5ef12fdf276ce29bb4f1c571c8368a60", + "sha256:1234dc92d011d3554d929b6cf058ac4a24d188d97be5e04355f1b9223e98bbe9", + "sha256:1d0dc4310da8b5f6415949bd5ef937e60aeb0eb6b16f95041b5e43e6200821fb", + "sha256:2a11b4b1a8415f105d989876a19b173f6cdc89ca13855ccc67c18efbd7cbd1f8", + "sha256:2e2ecd1d349e62e3960695214f40939bbfdcaeaaa62ccc638f8e651cf0970e5f", + "sha256:3a2ce5ea4f71681623f04e2b7dadede3c7435dfb5e5e2d1d0ec25b35530e277b", + "sha256:3e892621434392199efb54e69edfff9f699f6cc36dd9553c5bf796058b14b20d", + "sha256:3fb205ab52a2e30354640780ce4587157a9563a68c9beaf52153e1cea9aa0921", + "sha256:4689270c35d4bb3102e103ac43c3f0b76b169760aff8bcf2d401a3e0e58cdb7f", + "sha256:49f8ad582da6e8d2cf663c4ba5bf9f83cc052570a3a767487fec6af839b0e777", + "sha256:4bd176f528a8151a6efc5359b853ba3cc0e82d4cd1fab9c1300c5d957dc8f48c", + "sha256:4cf7837c3b11a2dfb589f8530b3cff2bd0307ace4c301e8997e95c7468c1378e", + "sha256:4fd72fab7bddce46c6826994ce1e7de145ae1e9e106ebb8eb9ce1393ca01444d", + "sha256:5148bab4d71f58948c7c39d12b14a9005b6ab35a0bdf317a8ade9a9e4d9d0bd5", + "sha256:5869e8e130e99687d9e4be835116c4ebd83ca92e52e55810962446d841aba8de", + "sha256:602a8001bdf60e1a7d544be29c82560a7b49319a0b31d62586548835bbe2c862", + "sha256:61804231099214e2f84998316f3238c4c2c4aaec302df12b21a64d72e2a135c7", + "sha256:666c6fdcaac1f13eb982b649e1c311c08d7097cbda24f32612dae43648d8db8d", + "sha256:674eb520f02422546c40401f4efaf8207b5e29e420c17051cddf6c02783ff5ca", + "sha256:7ec960b1b942ee3c69323b8721df2a3ce28ff40e7ca47873ae35bfafeb4555ca", + "sha256:7f433be3b3f4c66016d5a20e5b4444ef833a1f802ced13a2d852c637f69729c1", + "sha256:7f8fb7f5ecf4f6355683ac6881fd64b5bb2b8a60e3ccde6ff799e48791d8f864", + "sha256:81a3a3a72c9811b56adf8bcc829b010163bb2fc308877e50e9910c9357e78521", + "sha256:858379cbb08d84fe7583231077d9a36a1a20eb72f8c9076a45df8b083724ad1d", + "sha256:8b9ba0ccd5a7f4219e67fbbe25e6b4a46ceef783c42af7dbc1da548eb28b6531", + "sha256:92af0d00091e744587221e79f68d617b432425a7e59328ca4c496f774a356071", + "sha256:9ebbdbd6a046c304b1845e96fbcc5559cd296b4dfd3ad2509e33c4d9ce07d6a1", + "sha256:9edd2856611e5050004f4722922b7b1cd6268da34102667bd49d2a2b18bafb81", + "sha256:a353bf1f565ed27ba71a419b2cd3db9d6151da426b61b289b6ba1422a702e643", + "sha256:b5b7d4a44cc0e6ff98da5d56cde794385bdd212a86563ac321ca64d7f80c80d1", + "sha256:b90f340cb6397ec7a854157fac03f0c82b744abdd1c0941a024c3c29d1340aff", + "sha256:c18a4da2f50050a03d1da5317388ef84a16013302a5281d6f64e4a3f406aabc4", + "sha256:c338ed69ad0b8f8f8920c13f529889fe0771abbb46550013e3c3d01e5174deef", + "sha256:c5a02360e73e7208a872bf65a7554c9f15df5fe063dc047f79738998b0506a14", + "sha256:c62b6fa2961a1dcc51ebe88771be5319a93fd89bd247c9ddf732bc250507bc2b", + "sha256:c812312847867b6335cfb264772f2a7e85b3b502d3a6b0586aa35e1858528ab1", + "sha256:c943b35ecdf7123b2d81d225397efddf0bce2e81db2f3ae633ead38e85cd5ade", + "sha256:ce0a29c28dfb8eccd0f16219360530bc3cfdf6bf70ca384dacd36e6c650ef8e8", + "sha256:cf80b550092cc480a0cbd0750e8189247ff45457e5a023305f7ef1bcec811616", + "sha256:cff7570d492bcf4b64cc862a6e2fb77edd5e5748ad715f487628f102815165e9", + "sha256:d2c1e559d96a7f94a4f581e2a32d6d610df5840881a8cba8f25e446f4d792df3", + "sha256:deeb3922a7a804755bbe6b5be9b312e746137a03600f488290318936c1a2d4dc", + "sha256:e28a50b5be854e18d54f75ef1bb13e1abf4bc650ab9d635e4258c58e71eb6ad5", + "sha256:e99c625b8c95d7741fe057585176b1b8783d46ed4b8932cf98ee145c4facf499", + "sha256:ec6f18f96b47299c11203edfbdc34e1b69085070d9a3d1f302810cc23ad36bf3", + "sha256:ed8bc367f725dfc5cabeed1ae079d00369900231fbb5a5280cf0736c30e2adf7", + "sha256:ee5926746232f627a3be1cc175b2cfad24d0170d520361f4ce3fa2fd83f09e1d", + "sha256:f295efcd47b6124b01255d1491f9e46f17ef40d3d7eabf7364099e463fb45f0f", + "sha256:fb0b361d73f6b8eeceba47cd37070b5e6c9de5beaeaa63a1cb35c7e1a73ef088" + ], + "version": "==3.9.10" + }, + "packaging": { + "hashes": [ + "sha256:048fb0e9405036518eaaf48a55953c750c11e1a1b68e0dd1a9d62ed0c092cfc5", + "sha256:8c491190033a9af7e1d931d0b5dacc2ef47509b34dd0de67ed209b5203fc88c7" + ], + "index": "pypi", + "markers": "python_version >= '3.7'", + "version": "==23.2" + }, "parsedatetime": { "hashes": [ "sha256:4cb368fbb18a0b7231f4d76119165451c8d2e35951455dfee97c62a87b04d455", @@ -443,69 +710,120 @@ }, "pillow": { "hashes": [ - "sha256:0030fdbd926fb85844b8b92e2f9449ba89607231d3dd597a21ae72dc7fe26927", - "sha256:030e3460861488e249731c3e7ab59b07c7853838ff3b8e16aac9561bb345da14", - "sha256:0ed2c4ef2451de908c90436d6e8092e13a43992f1860275b4d8082667fbb2ffc", - "sha256:136659638f61a251e8ed3b331fc6ccd124590eeff539de57c5f80ef3a9594e58", - "sha256:13b725463f32df1bfeacbf3dd197fb358ae8ebcd8c5548faa75126ea425ccb60", - "sha256:1536ad017a9f789430fb6b8be8bf99d2f214c76502becc196c6f2d9a75b01b76", - "sha256:15928f824870535c85dbf949c09d6ae7d3d6ac2d6efec80f3227f73eefba741c", - "sha256:17d4cafe22f050b46d983b71c707162d63d796a1235cdf8b9d7a112e97b15bac", - "sha256:1802f34298f5ba11d55e5bb09c31997dc0c6aed919658dfdf0198a2fe75d5490", - "sha256:1cc1d2451e8a3b4bfdb9caf745b58e6c7a77d2e469159b0d527a4554d73694d1", - "sha256:1fd6f5e3c0e4697fa7eb45b6e93996299f3feee73a3175fa451f49a74d092b9f", - "sha256:254164c57bab4b459f14c64e93df11eff5ded575192c294a0c49270f22c5d93d", - "sha256:2ad0d4df0f5ef2247e27fc790d5c9b5a0af8ade9ba340db4a73bb1a4a3e5fb4f", - "sha256:2c58b24e3a63efd22554c676d81b0e57f80e0a7d3a5874a7e14ce90ec40d3069", - "sha256:2d33a11f601213dcd5718109c09a52c2a1c893e7461f0be2d6febc2879ec2402", - "sha256:336b9036127eab855beec9662ac3ea13a4544a523ae273cbf108b228ecac8437", - "sha256:337a74fd2f291c607d220c793a8135273c4c2ab001b03e601c36766005f36885", - "sha256:37ff6b522a26d0538b753f0b4e8e164fdada12db6c6f00f62145d732d8a3152e", - "sha256:3d1f14f5f691f55e1b47f824ca4fdcb4b19b4323fe43cc7bb105988cad7496be", - "sha256:408673ed75594933714482501fe97e055a42996087eeca7e5d06e33218d05aa8", - "sha256:4134d3f1ba5f15027ff5c04296f13328fecd46921424084516bdb1b2548e66ff", - "sha256:4ad2f835e0ad81d1689f1b7e3fbac7b01bb8777d5a985c8962bedee0cc6d43da", - "sha256:50dff9cc21826d2977ef2d2a205504034e3a4563ca6f5db739b0d1026658e004", - "sha256:510cef4a3f401c246cfd8227b300828715dd055463cdca6176c2e4036df8bd4f", - "sha256:5aed7dde98403cd91d86a1115c78d8145c83078e864c1de1064f52e6feb61b20", - "sha256:69bd1a15d7ba3694631e00df8de65a8cb031911ca11f44929c97fe05eb9b6c1d", - "sha256:6bf088c1ce160f50ea40764f825ec9b72ed9da25346216b91361eef8ad1b8f8c", - "sha256:6e8c66f70fb539301e064f6478d7453e820d8a2c631da948a23384865cd95544", - "sha256:727dd1389bc5cb9827cbd1f9d40d2c2a1a0c9b32dd2261db522d22a604a6eec9", - "sha256:74a04183e6e64930b667d321524e3c5361094bb4af9083db5c301db64cd341f3", - "sha256:75e636fd3e0fb872693f23ccb8a5ff2cd578801251f3a4f6854c6a5d437d3c04", - "sha256:7761afe0126d046974a01e030ae7529ed0ca6a196de3ec6937c11df0df1bc91c", - "sha256:7888310f6214f19ab2b6df90f3f06afa3df7ef7355fc025e78a3044737fab1f5", - "sha256:7b0554af24df2bf96618dac71ddada02420f946be943b181108cac55a7a2dcd4", - "sha256:7c7b502bc34f6e32ba022b4a209638f9e097d7a9098104ae420eb8186217ebbb", - "sha256:808add66ea764ed97d44dda1ac4f2cfec4c1867d9efb16a33d158be79f32b8a4", - "sha256:831e648102c82f152e14c1a0938689dbb22480c548c8d4b8b248b3e50967b88c", - "sha256:93689632949aff41199090eff5474f3990b6823404e45d66a5d44304e9cdc467", - "sha256:96b5e6874431df16aee0c1ba237574cb6dff1dcb173798faa6a9d8b399a05d0e", - "sha256:9a54614049a18a2d6fe156e68e188da02a046a4a93cf24f373bffd977e943421", - "sha256:a138441e95562b3c078746a22f8fca8ff1c22c014f856278bdbdd89ca36cff1b", - "sha256:a647c0d4478b995c5e54615a2e5360ccedd2f85e70ab57fbe817ca613d5e63b8", - "sha256:a9c9bc489f8ab30906d7a85afac4b4944a572a7432e00698a7239f44a44e6efb", - "sha256:ad2277b185ebce47a63f4dc6302e30f05762b688f8dc3de55dbae4651872cdf3", - "sha256:adabc0bce035467fb537ef3e5e74f2847c8af217ee0be0455d4fec8adc0462fc", - "sha256:b6d5e92df2b77665e07ddb2e4dbd6d644b78e4c0d2e9272a852627cdba0d75cf", - "sha256:bc431b065722a5ad1dfb4df354fb9333b7a582a5ee39a90e6ffff688d72f27a1", - "sha256:bdd0de2d64688ecae88dd8935012c4a72681e5df632af903a1dca8c5e7aa871a", - "sha256:c79698d4cd9318d9481d89a77e2d3fcaeff5486be641e60a4b49f3d2ecca4e28", - "sha256:cb6259196a589123d755380b65127ddc60f4c64b21fc3bb46ce3a6ea663659b0", - "sha256:d5b87da55a08acb586bad5c3aa3b86505f559b84f39035b233d5bf844b0834b1", - "sha256:dcd7b9c7139dc8258d164b55696ecd16c04607f1cc33ba7af86613881ffe4ac8", - "sha256:dfe4c1fedfde4e2fbc009d5ad420647f7730d719786388b7de0999bf32c0d9fd", - "sha256:ea98f633d45f7e815db648fd7ff0f19e328302ac36427343e4432c84432e7ff4", - "sha256:ec52c351b35ca269cb1f8069d610fc45c5bd38c3e91f9ab4cbbf0aebc136d9c8", - "sha256:eef7592281f7c174d3d6cbfbb7ee5984a671fcd77e3fc78e973d492e9bf0eb3f", - "sha256:f07f1f00e22b231dd3d9b9208692042e29792d6bd4f6639415d2f23158a80013", - "sha256:f3fac744f9b540148fa7715a435d2283b71f68bfb6d4aae24482a890aed18b59", - "sha256:fa768eff5f9f958270b081bb33581b4b569faabf8774726b283edb06617101dc", - "sha256:fac2d65901fb0fdf20363fbd345c01958a742f2dc62a8dd4495af66e3ff502a4" + "sha256:00f438bb841382b15d7deb9a05cc946ee0f2c352653c7aa659e75e592f6fa17d", + "sha256:0248f86b3ea061e67817c47ecbe82c23f9dd5d5226200eb9090b3873d3ca32de", + "sha256:04f6f6149f266a100374ca3cc368b67fb27c4af9f1cc8cb6306d849dcdf12616", + "sha256:062a1610e3bc258bff2328ec43f34244fcec972ee0717200cb1425214fe5b839", + "sha256:0a026c188be3b443916179f5d04548092e253beb0c3e2ee0a4e2cdad72f66099", + "sha256:0f7c276c05a9767e877a0b4c5050c8bee6a6d960d7f0c11ebda6b99746068c2a", + "sha256:1a8413794b4ad9719346cd9306118450b7b00d9a15846451549314a58ac42219", + "sha256:1ab05f3db77e98f93964697c8efc49c7954b08dd61cff526b7f2531a22410106", + "sha256:1c3ac5423c8c1da5928aa12c6e258921956757d976405e9467c5f39d1d577a4b", + "sha256:1c41d960babf951e01a49c9746f92c5a7e0d939d1652d7ba30f6b3090f27e412", + "sha256:1fafabe50a6977ac70dfe829b2d5735fd54e190ab55259ec8aea4aaea412fa0b", + "sha256:1fb29c07478e6c06a46b867e43b0bcdb241b44cc52be9bc25ce5944eed4648e7", + "sha256:24fadc71218ad2b8ffe437b54876c9382b4a29e030a05a9879f615091f42ffc2", + "sha256:2cdc65a46e74514ce742c2013cd4a2d12e8553e3a2563c64879f7c7e4d28bce7", + "sha256:2ef6721c97894a7aa77723740a09547197533146fba8355e86d6d9a4a1056b14", + "sha256:3b834f4b16173e5b92ab6566f0473bfb09f939ba14b23b8da1f54fa63e4b623f", + "sha256:3d929a19f5469b3f4df33a3df2983db070ebb2088a1e145e18facbc28cae5b27", + "sha256:41f67248d92a5e0a2076d3517d8d4b1e41a97e2df10eb8f93106c89107f38b57", + "sha256:47e5bf85b80abc03be7455c95b6d6e4896a62f6541c1f2ce77a7d2bb832af262", + "sha256:4d0152565c6aa6ebbfb1e5d8624140a440f2b99bf7afaafbdbf6430426497f28", + "sha256:50d08cd0a2ecd2a8657bd3d82c71efd5a58edb04d9308185d66c3a5a5bed9610", + "sha256:61f1a9d247317fa08a308daaa8ee7b3f760ab1809ca2da14ecc88ae4257d6172", + "sha256:6932a7652464746fcb484f7fc3618e6503d2066d853f68a4bd97193a3996e273", + "sha256:7a7e3daa202beb61821c06d2517428e8e7c1aab08943e92ec9e5755c2fc9ba5e", + "sha256:7dbaa3c7de82ef37e7708521be41db5565004258ca76945ad74a8e998c30af8d", + "sha256:7df5608bc38bd37ef585ae9c38c9cd46d7c81498f086915b0f97255ea60c2818", + "sha256:806abdd8249ba3953c33742506fe414880bad78ac25cc9a9b1c6ae97bedd573f", + "sha256:883f216eac8712b83a63f41b76ddfb7b2afab1b74abbb413c5df6680f071a6b9", + "sha256:912e3812a1dbbc834da2b32299b124b5ddcb664ed354916fd1ed6f193f0e2d01", + "sha256:937bdc5a7f5343d1c97dc98149a0be7eb9704e937fe3dc7140e229ae4fc572a7", + "sha256:9882a7451c680c12f232a422730f986a1fcd808da0fd428f08b671237237d651", + "sha256:9a92109192b360634a4489c0c756364c0c3a2992906752165ecb50544c251312", + "sha256:9d7bc666bd8c5a4225e7ac71f2f9d12466ec555e89092728ea0f5c0c2422ea80", + "sha256:a5f63b5a68daedc54c7c3464508d8c12075e56dcfbd42f8c1bf40169061ae666", + "sha256:a646e48de237d860c36e0db37ecaecaa3619e6f3e9d5319e527ccbc8151df061", + "sha256:a89b8312d51715b510a4fe9fc13686283f376cfd5abca8cd1c65e4c76e21081b", + "sha256:a92386125e9ee90381c3369f57a2a50fa9e6aa8b1cf1d9c4b200d41a7dd8e992", + "sha256:ae88931f93214777c7a3aa0a8f92a683f83ecde27f65a45f95f22d289a69e593", + "sha256:afc8eef765d948543a4775f00b7b8c079b3321d6b675dde0d02afa2ee23000b4", + "sha256:b0eb01ca85b2361b09480784a7931fc648ed8b7836f01fb9241141b968feb1db", + "sha256:b1c25762197144e211efb5f4e8ad656f36c8d214d390585d1d21281f46d556ba", + "sha256:b4005fee46ed9be0b8fb42be0c20e79411533d1fd58edabebc0dd24626882cfd", + "sha256:b920e4d028f6442bea9a75b7491c063f0b9a3972520731ed26c83e254302eb1e", + "sha256:baada14941c83079bf84c037e2d8b7506ce201e92e3d2fa0d1303507a8538212", + "sha256:bb40c011447712d2e19cc261c82655f75f32cb724788df315ed992a4d65696bb", + "sha256:c0949b55eb607898e28eaccb525ab104b2d86542a85c74baf3a6dc24002edec2", + "sha256:c9aeea7b63edb7884b031a35305629a7593272b54f429a9869a4f63a1bf04c34", + "sha256:cfe96560c6ce2f4c07d6647af2d0f3c54cc33289894ebd88cfbb3bcd5391e256", + "sha256:d27b5997bdd2eb9fb199982bb7eb6164db0426904020dc38c10203187ae2ff2f", + "sha256:d921bc90b1defa55c9917ca6b6b71430e4286fc9e44c55ead78ca1a9f9eba5f2", + "sha256:e6bf8de6c36ed96c86ea3b6e1d5273c53f46ef518a062464cd7ef5dd2cf92e38", + "sha256:eaed6977fa73408b7b8a24e8b14e59e1668cfc0f4c40193ea7ced8e210adf996", + "sha256:fa1d323703cfdac2036af05191b969b910d8f115cf53093125e4058f62012c9a", + "sha256:fe1e26e1ffc38be097f0ba1d0d07fcade2bcfd1d023cda5b29935ae8052bd793" ], - "markers": "python_version >= '3.7'", - "version": "==9.2.0" + "markers": "python_version >= '3.8'", + "version": "==10.1.0" + }, + "pycares": { + "hashes": [ + "sha256:112a4979c695b1c86f6782163d7dec58d57a3b9510536dcf4826550f9053dd9a", + "sha256:1168a48a834813aa80f412be2df4abaf630528a58d15c704857448b20b1675c0", + "sha256:21a5a0468861ec7df7befa69050f952da13db5427ae41ffe4713bc96291d1d95", + "sha256:229a1675eb33bc9afb1fc463e73ee334950ccc485bc83a43f6ae5839fb4d5fa3", + "sha256:22c00bf659a9fa44d7b405cf1cd69b68b9d37537899898d8cbe5dffa4016b273", + "sha256:23aa3993a352491a47fcf17867f61472f32f874df4adcbb486294bd9fbe8abee", + "sha256:24da119850841d16996713d9c3374ca28a21deee056d609fbbed29065d17e1f6", + "sha256:2eeec144bcf6a7b6f2d74d6e70cbba7886a84dd373c886f06cb137a07de4954c", + "sha256:34736a2ffaa9c08ca9c707011a2d7b69074bbf82d645d8138bba771479b2362f", + "sha256:3aebc73e5ad70464f998f77f2da2063aa617cbd8d3e8174dd7c5b4518f967153", + "sha256:3eaa6681c0a3e3f3868c77aca14b7760fed35fdfda2fe587e15c701950e7bc69", + "sha256:4afc2644423f4eef97857a9fd61be9758ce5e336b4b0bd3d591238bb4b8b03e0", + "sha256:52084961262232ec04bd75f5043aed7e5d8d9695e542ff691dfef0110209f2d4", + "sha256:56cf3349fa3a2e67ed387a7974c11d233734636fe19facfcda261b411af14d80", + "sha256:5ed4e04af4012f875b78219d34434a6d08a67175150ac1b79eb70ab585d4ba8c", + "sha256:64965dc19c578a683ea73487a215a8897276224e004d50eeb21f0bc7a0b63c88", + "sha256:6ef64649eba56448f65e26546d85c860709844d2fc22ef14d324fe0b27f761a9", + "sha256:77cf5a2fd5583c670de41a7f4a7b46e5cbabe7180d8029f728571f4d2e864084", + "sha256:7bddc6adba8f699728f7fc1c9ce8cef359817ad78e2ed52b9502cb5f8dc7f741", + "sha256:813d661cbe2e37d87da2d16b7110a6860e93ddb11735c6919c8a3545c7b9c8d8", + "sha256:82bba2ab77eb5addbf9758d514d9bdef3c1bfe7d1649a47bd9a0d55a23ef478b", + "sha256:8bf2eaa83a5987e48fa63302f0fe7ce3275cfda87b34d40fef9ce703fb3ac002", + "sha256:8d186dafccdaa3409194c0f94db93c1a5d191145a275f19da6591f9499b8e7b8", + "sha256:8f64cb58729689d4d0e78f0bfb4c25ce2f851d0274c0273ac751795c04b8798a", + "sha256:902461a92b6a80fd5041a2ec5235680c7cc35e43615639ec2a40e63fca2dfb51", + "sha256:917f08f0b5d9324e9a34211e68d27447c552b50ab967044776bbab7e42a553a2", + "sha256:94d6962db81541eb0396d2f0dfcbb18cdb8c8b251d165efc2d974ae652c547d4", + "sha256:97892cced5794d721fb4ff8765764aa4ea48fe8b2c3820677505b96b83d4ef47", + "sha256:9a0303428d013ccf5c51de59c83f9127aba6200adb7fd4be57eddb432a1edd2a", + "sha256:9dc04c54c6ea615210c1b9e803d0e2d2255f87a3d5d119b6482c8f0dfa15b26b", + "sha256:a0c5368206057884cde18602580083aeaad9b860e2eac14fd253543158ce1e93", + "sha256:ad58e284a658a8a6a84af2e0b62f2f961f303cedfe551854d7bd40c3cbb61912", + "sha256:afb91792f1556f97be7f7acb57dc7756d89c5a87bd8b90363a77dbf9ea653817", + "sha256:b61579cecf1f4d616e5ea31a6e423a16680ab0d3a24a2ffe7bb1d4ee162477ff", + "sha256:b7af06968cbf6851566e806bf3e72825b0e6671832a2cbe840be1d2d65350710", + "sha256:bce8db2fc6f3174bd39b81405210b9b88d7b607d33e56a970c34a0c190da0490", + "sha256:bfb89ca9e3d0a9b5332deeb666b2ede9d3469107742158f4aeda5ce032d003f4", + "sha256:c680fef1b502ee680f8f0b95a41af4ec2c234e50e16c0af5bbda31999d3584bd", + "sha256:c6a8bde63106f162fca736e842a916853cad3c8d9d137e11c9ffa37efa818b02", + "sha256:cb49d5805cd347c404f928c5ae7c35e86ba0c58ffa701dbe905365e77ce7d641", + "sha256:ceb12974367b0a68a05d52f4162b29f575d241bd53de155efe632bf2c943c7f6", + "sha256:d33e2a1120887e89075f7f814ec144f66a6ce06a54f5722ccefc62fbeda83cff", + "sha256:db24c4e7fea4a052c6e869cbf387dd85d53b9736cfe1ef5d8d568d1ca925e977", + "sha256:e3a6f7cfdfd11eb5493d6d632e582408c8f3b429f295f8799c584c108b28db6f", + "sha256:eb66c30eb11e877976b7ead13632082a8621df648c408b8e15cdb91a452dd502", + "sha256:ed2a38e34bec6f2586435f6ff0bc5fe11d14bebd7ed492cf739a424e81681540", + "sha256:f36bdc1562142e3695555d2f4ac0cb69af165eddcefa98efc1c79495b533481f", + "sha256:f47579d508f2f56eddd16ce72045782ad3b1b3b678098699e2b6a1b30733e1c2", + "sha256:f5f646eec041db6ffdbcaf3e0756fb92018f7af3266138c756bb09d2b5baadec", + "sha256:fd644505a8cfd7f6584d33a9066d4e3d47700f050ef1490230c962de5dfb28c6", + "sha256:fff16b09042ba077f7b8aa5868d1d22456f0002574d0ba43462b10a009331677" + ], + "markers": "python_version >= '3.8'", + "version": "==4.4.0" }, "pycparser": { "hashes": [ @@ -519,117 +837,90 @@ "srv" ], "hashes": [ - "sha256:06b64cdf5121f86b78a84e61b8f899b6988732a8d304b503ea1f94a676221c06", - "sha256:07398d8a03545b98282f459f2603a6bb271f4448d484ed7f411121a519a7ea48", - "sha256:0a02313e71b7c370c43056f6b16c45effbb2d29a44d24403a3d5ba6ed322fa3f", - "sha256:0a89cadc0062a5e53664dde043f6c097172b8c1c5f0094490095282ff9995a5f", - "sha256:0be605bfb8461384a4cb81e80f51eb5ca1b89851f2d0e69a75458c788a7263a4", - "sha256:0d52a70350ec3dfc39b513df12b03b7f4c8f8ec6873bbf958299999db7b05eb1", - "sha256:0e7a5d0b9077e8c3e57727f797ee8adf12e1d5e7534642230d98980d160d1320", - "sha256:145d78c345a38011497e55aff22c0f8edd40ee676a6810f7e69563d68a125e83", - "sha256:14dee106a10b77224bba5efeeb6aee025aabe88eb87a2b850c46d3ee55bdab4a", - "sha256:176fdca18391e1206c32fb1d8265628a84d28333c20ad19468d91e3e98312cd1", - "sha256:1b4c535f524c9d8c86c3afd71d199025daa070859a2bdaf94a298120b0de16db", - "sha256:1b5cb75d2642ff7db823f509641f143f752c0d1ab03166cafea1e42e50469834", - "sha256:1c6c71e198b36f0f0dfe354f06d3655ecfa30d69493a1da125a9a54668aad652", - "sha256:1c771f1a8b3cd2d697baaf57e9cfa4ae42371cacfbea42ea01d9577c06d92f96", - "sha256:208a61db8b8b647fb5b1ff3b52b4ed6dbced01eac3b61009958adb203596ee99", - "sha256:2157d68f85c28688e8b723bbe70c8013e0aba5570e08c48b3562f74d33fc05c4", - "sha256:2301051701b27aff2cbdf83fae22b7ca883c9563dfd088033267291b46196643", - "sha256:2567885ff0c8c7c0887ba6cefe4ae4af96364a66a7069f924ce0cd12eb971d04", - "sha256:2577b8161eeae4dd376d13100b2137d883c10bb457dd08935f60c9f9d4b5c5f6", - "sha256:27e5ea64332385385b75414888ce9d1a9806be8616d7cef4ef409f4f256c6d06", - "sha256:28bfd5244d32faf3e49b5a8d1fab0631e922c26e8add089312e4be19fb05af50", - "sha256:295a5beaecb7bf054c1c6a28749ed72b19f4d4b61edcd8a0815d892424baf780", - "sha256:2c46a0afef69d61938a6fe32c3afd75b91dec3ab3056085dc72abbeedcc94166", - "sha256:3100a2352bdded6232b385ceda0c0a4624598c517d52c2d8cf014b7abbebd84d", - "sha256:320a1fe403dd83a35709fcf01083d14bc1462e9789b711201349a9158db3a87e", - "sha256:320f8734553c50cffe8a8e1ae36dfc7d7be1941c047489db20a814d2a170d7b5", - "sha256:33ab8c031f788609924e329003088831045f683931932a52a361d4a955b7dce2", - "sha256:3492ae1f97209c66af70e863e6420e6301cecb0a51a5efa701058aa73a8ca29e", - "sha256:351a2efe1c9566c348ad0076f4bf541f4905a0ebe2d271f112f60852575f3c16", - "sha256:3f0ac6e0203bd88863649e6ed9c7cfe53afab304bc8225f2597c4c0a74e4d1f0", - "sha256:3fedad05147b40ff8a93fcd016c421e6c159f149a2a481cfa0b94bfa3e473bab", - "sha256:4294f2c1cd069b793e31c2e6d7ac44b121cf7cedccd03ebcc30f3fc3417b314a", - "sha256:463b974b7f49d65a16ca1435bc1c25a681bb7d630509dd23b2e819ed36da0b7f", - "sha256:4e0a3ea7fd01cf0a36509f320226bd8491e0f448f00b8cb89f601c109f6874e1", - "sha256:514e78d20d8382d5b97f32b20c83d1d0452c302c9a135f0a9022236eb9940fda", - "sha256:517b09b1dd842390a965a896d1327c55dfe78199c9f5840595d40facbcd81854", - "sha256:51d1d061df3995c2332ae78f036492cc188cb3da8ef122caeab3631a67bb477e", - "sha256:5296669bff390135528001b4e48d33a7acaffcd361d98659628ece7f282f11aa", - "sha256:5296e5e69243ffd76bd919854c4da6630ae52e46175c804bc4c0e050d937b705", - "sha256:58db209da08a502ce6948841d522dcec80921d714024354153d00b054571993c", - "sha256:5b779e87300635b8075e8d5cfd4fdf7f46078cd7610c381d956bca5556bb8f97", - "sha256:5cf113a46d81cff0559d57aa66ffa473d57d1a9496f97426318b6b5b14fdec1c", - "sha256:5d20072d81cbfdd8e15e6a0c91fc7e3a4948c71e0adebfc67d3b4bcbe8602711", - "sha256:5d67dbc8da2dac1644d71c1839d12d12aa333e266a9964d5b1a49feed036bc94", - "sha256:5f530f35e1a57d4360eddcbed6945aecdaee2a491cd3f17025e7b5f2eea88ee7", - "sha256:5fdffb0cfeb4dc8646a5381d32ec981ae8472f29c695bf09e8f7a8edb2db12ca", - "sha256:602284e652bb56ca8760f8e88a5280636c5b63d7946fca1c2fe0f83c37dffc64", - "sha256:648fcfd8e019b122b7be0e26830a3a2224d57c3e934f19c1e53a77b8380e6675", - "sha256:64b9122be1c404ce4eb367ad609b590394587a676d84bfed8e03c3ce76d70560", - "sha256:6526933760ee1e6090db808f1690a111ec409699c1990efc96f134d26925c37f", - "sha256:6632b1c63d58cddc72f43ab9f17267354ddce563dd5e11eadabd222dcc808808", - "sha256:6f93dbfa5a461107bc3f5026e0d5180499e13379e9404f07a9f79eb5e9e1303d", - "sha256:71c0db2c313ea8a80825fb61b7826b8015874aec29ee6364ade5cb774fe4511b", - "sha256:71c5c200fd37a5322706080b09c3ec8907cf01c377a7187f354fc9e9e13abc73", - "sha256:7738147cd9dbd6d18d5593b3491b4620e13b61de975fd737283e4ad6c255c273", - "sha256:7a6e4dccae8ef5dd76052647d78f02d5d0ffaff1856277d951666c54aeba3ad2", - "sha256:7b4a9fcd95e978cd3c96cdc2096aa54705266551422cf0883c12a4044def31c6", - "sha256:80710d7591d579442c67a3bc7ae9dcba9ff95ea8414ac98001198d894fc4ff46", - "sha256:81a3ebc33b1367f301d1c8eda57eec4868e951504986d5d3fe437479dcdac5b2", - "sha256:8455176fd1b86de97d859fed4ae0ef867bf998581f584c7a1a591246dfec330f", - "sha256:845b178bd127bb074835d2eac635b980c58ec5e700ebadc8355062df708d5a71", - "sha256:858af7c2ab98f21ed06b642578b769ecfcabe4754648b033168a91536f7beef9", - "sha256:87e18f29bac4a6be76a30e74de9c9005475e27100acf0830679420ce1fd9a6fd", - "sha256:89d7baa847383b9814de640c6f1a8553d125ec65e2761ad146ea2e75a7ad197c", - "sha256:8c7ad5cab282f53b9d78d51504330d1c88c83fbe187e472c07e6908a0293142e", - "sha256:8d92c6bb9174d47c2257528f64645a00bbc6324a9ff45a626192797aff01dc14", - "sha256:9252c991e8176b5a2fa574c5ab9a841679e315f6e576eb7cf0bd958f3e39b0ad", - "sha256:93111fd4e08fa889c126aa8baf5c009a941880a539c87672e04583286517450a", - "sha256:95d15cf81cd2fb926f2a6151a9f94c7aacc102b415e72bc0e040e29332b6731c", - "sha256:9d5b66d457d2c5739c184a777455c8fde7ab3600a56d8bbebecf64f7c55169e1", - "sha256:a055d29f1302892a9389a382bed10a3f77708bcf3e49bfb76f7712fa5f391cc6", - "sha256:a1ba93be779a9b8e5e44f5c133dc1db4313661cead8a2fd27661e6cb8d942ee9", - "sha256:a283425e6a474facd73072d8968812d1d9058490a5781e022ccf8895500b83ce", - "sha256:a351986d6c9006308f163c359ced40f80b6cffb42069f3e569b979829951038d", - "sha256:a766157b195a897c64945d4ff87b050bb0e763bb78f3964e996378621c703b00", - "sha256:a8a3540e21213cb8ce232e68a7d0ee49cdd35194856c50b8bd87eeb572fadd42", - "sha256:a8e0a086dbbee406cc6f603931dfe54d1cb2fba585758e06a2de01037784b737", - "sha256:ab23b0545ec71ea346bf50a5d376d674f56205b729980eaa62cdb7871805014b", - "sha256:b0db9a4691074c347f5d7ee830ab3529bc5ad860939de21c1f9c403daf1eda9a", - "sha256:b1b5be40ebf52c3c67ee547e2c4435ed5bc6352f38d23e394520b686641a6be4", - "sha256:b3e08aef4ea05afbc0a70cd23c13684e7f5e074f02450964ec5cfa1c759d33d2", - "sha256:b7df0d99e189b7027d417d4bfd9b8c53c9c7ed5a0a1495d26a6f547d820eca88", - "sha256:be1f10145f7ea76e3e836fdc5c8429c605675bdcddb0bca9725ee6e26874c00c", - "sha256:bf254a1a95e95fdf4eaa25faa1ea450a6533ed7a997f9f8e49ab971b61ea514d", - "sha256:bfc2d763d05ec7211313a06e8571236017d3e61d5fef97fcf34ec4b36c0b6556", - "sha256:c164eda0be9048f83c24b9b2656900041e069ddf72de81c17d874d0c32f6079f", - "sha256:c22591cff80188dd8543be0b559d0c807f7288bd353dc0bcfe539b4588b3a5cd", - "sha256:c5f83bb59d0ff60c6fdb1f8a7b0288fbc4640b1f0fd56f5ae2387749c35d34e3", - "sha256:c7e8221278e5f9e2b6d3893cfc3a3e46c017161a57bb0e6f244826e4cee97916", - "sha256:c8d6bf6fcd42cde2f02efb8126812a010c297eacefcd090a609639d2aeda6185", - "sha256:c8f7dd025cb0bf19e2f60a64dfc24b513c8330e0cfe4a34ccf941eafd6194d9e", - "sha256:c9d212e2af72d5c8d082775a43eb726520e95bf1c84826440f74225843975136", - "sha256:cebb3d8bcac4a6b48be65ebbc5c9881ed4a738e27bb96c86d9d7580a1fb09e05", - "sha256:d3082e5c4d7b388792124f5e805b469109e58f1ab1eb1fbd8b998e8ab766ffb7", - "sha256:d81047341ab56061aa4b6823c54d4632579c3b16e675089e8f520e9b918a133b", - "sha256:d81299f63dc33cc172c26faf59cc54dd795fc6dd5821a7676cca112a5ee8bbd6", - "sha256:dfa217bf8cf3ff6b30c8e6a89014e0c0e7b50941af787b970060ae5ba04a4ce5", - "sha256:dfec57f15f53d677b8e4535695ff3f37df7f8fe431f2efa8c3c8c4025b53d1eb", - "sha256:e099b79ccf7c40f18b149a64d3d10639980035f9ceb223169dd806ff1bb0d9cc", - "sha256:e1fc4d3985868860b6585376e511bb32403c5ffb58b0ed913496c27fd791deea", - "sha256:e2b4c95c47fb81b19ea77dc1c50d23af3eba87c9628fcc2e03d44124a3d336ea", - "sha256:e4e5d163e6644c2bc84dd9f67bfa89288c23af26983d08fefcc2cbc22f6e57e6", - "sha256:e66b3c9f8b89d4fd58a59c04fdbf10602a17c914fbaaa5e6ea593f1d54b06362", - "sha256:ed7d11330e443aeecab23866055e08a5a536c95d2c25333aeb441af2dbac38d2", - "sha256:f340a2a908644ea6cccd399be0fb308c66e05d2800107345f9f0f0d59e1731c4", - "sha256:f38b35ecd2628bf0267761ed659e48af7e620a7fcccfccf5774e7308fb18325c", - "sha256:f6d5443104f89a840250087863c91484a72f254574848e951d1bdd7d8b2ce7c9", - "sha256:fc2048d13ff427605fea328cbe5369dce549b8c7657b0e22051a5b8831170af6" + "sha256:014e7049dd019a6663747ca7dae328943e14f7261f7c1381045dfc26a04fa330", + "sha256:055f5c266e2767a88bb585d01137d9c7f778b0195d3dbf4a487ef0638be9b651", + "sha256:05c30fd35cc97f14f354916b45feea535d59060ef867446b5c3c7f9b609dd5dc", + "sha256:0634994b026336195778e5693583c060418d4ab453eff21530422690a97e1ee8", + "sha256:09c7de516b08c57647176b9fc21d929d628e35bcebc7422220c89ae40b62126a", + "sha256:107a234dc55affc5802acb3b6d83cbb8c87355b38a9457fcd8806bdeb8bce161", + "sha256:10a379fb60f1b2406ae57b8899bacfe20567918c8e9d2d545e1b93628fcf2050", + "sha256:128b1485753106c54af481789cdfea12b90a228afca0b11fb3828309a907e10e", + "sha256:1394c4737b325166a65ae7c145af1ebdb9fb153ebedd37cf91d676313e4a67b8", + "sha256:1c63e3a2e8fb815c4b1f738c284a4579897e37c3cfd95fdb199229a1ccfb638a", + "sha256:1e4ed21029d80c4f62605ab16398fe1ce093fff4b5f22d114055e7d9fbc4adb0", + "sha256:1ec71ac633b126c0775ed4604ca8f56c3540f5c21a1220639f299e7a544b55f9", + "sha256:21812453354b151200034750cd30b0140e82ec2a01fd4357390f67714a1bfbde", + "sha256:256c503a75bd71cf7fb9ebf889e7e222d49c6036a48aad5a619f98a0adf0e0d7", + "sha256:2703a9f8f5767986b4f51c259ff452cc837c5a83c8ed5f5361f6e49933743b2f", + "sha256:288c21ab9531b037f7efa4e467b33176bc73a0c27223c141b822ab4a0e66ff2a", + "sha256:2972dd1f1285866aba027eff2f4a2bbf8aa98563c2ced14cb34ee5602b36afdf", + "sha256:2973f113e079fb98515722cd728e1820282721ec9fd52830e4b73cabdbf1eb28", + "sha256:2ca0ba501898b2ec31e6c3acf90c31910944f01d454ad8e489213a156ccf1bda", + "sha256:2d2be5c9c3488fa8a70f83ed925940f488eac2837a996708d98a0e54a861f212", + "sha256:2f8c04277d879146eacda920476e93d520eff8bec6c022ac108cfa6280d84348", + "sha256:325701ae7b56daa5b0692305b7cb505ca50f80a1288abb32ff420a8a209b01ca", + "sha256:3729b8db02063da50eeb3db88a27670d85953afb9a7f14c213ac9e3dca93034b", + "sha256:3919708594b86d0f5cdc713eb6fccd3f9b9532af09ea7a5d843c933825ef56c4", + "sha256:39a1cd5d383b37285641d5a7a86be85274466ae336a61b51117155936529f9b3", + "sha256:3ec6c20385c5a58e16b1ea60c5e4993ea060540671d7d12664f385f2fb32fe79", + "sha256:47aa128be2e66abd9d1a9b0437c62499d812d291f17b55185cb4aa33a5f710a4", + "sha256:49f2af6cf82509b15093ce3569229e0d53c90ad8ae2eef940652d4cf1f81e045", + "sha256:4a0269811661ba93c472c8a60ea82640e838c2eb148d252720a09b5123f2c2fe", + "sha256:518c90bdd6e842c446d01a766b9136fec5ec6cc94f3b8c3f8b4a332786ee6b64", + "sha256:5717a308a703dda2886a5796a07489c698b442f5e409cf7dc2ac93de8d61d764", + "sha256:5802acc012bbb4bce4dff92973dff76482f30ef35dd4cb8ab5b0e06aa8f08c80", + "sha256:5e63146dbdb1eac207464f6e0cfcdb640c9c5ff0f57b754fa96fe252314a1dc6", + "sha256:6695d7136a435c1305b261a9ddb9b3ecec9863e05aab3935b96038145fd3a977", + "sha256:680fa0fc719e1a3dcb81130858368f51d83667d431924d0bcf249644bce8f303", + "sha256:6b18276f14b4b6d92e707ab6db19b938e112bd2f1dc3f9f1a628df58e4fd3f0d", + "sha256:6bafea6061d63059d8bc2ffc545e2f049221c8a4457d236c5cd6a66678673eab", + "sha256:6d6a1b1361f118e7fefa17ae3114e77f10ee1b228b20d50c47c9f351346180c8", + "sha256:747c84f4e690fbe6999c90ac97246c95d31460d890510e4a3fa61b7d2b87aa34", + "sha256:79f41576b3022c2fe9780ae3e44202b2438128a25284a8ddfa038f0785d87019", + "sha256:7b0e6361754ac596cd16bfc6ed49f69ffcd9b60b7bc4bcd3ea65c6a83475e4ff", + "sha256:7e3b0127b260d4abae7b62203c4c7ef0874c901b55155692353db19de4b18bc4", + "sha256:7fc2bb8a74dcfcdd32f89528e38dcbf70a3a6594963d60dc9595e3b35b66e414", + "sha256:806e094e9e85d8badc978af8c95b69c556077f11844655cb8cd2d1758769e521", + "sha256:81dd1308bd5630d2bb5980f00aa163b986b133f1e9ed66c66ce2a5bc3572e891", + "sha256:82e620842e12e8cb4050d2643a81c8149361cd82c0a920fa5a15dc4ca8a4000f", + "sha256:85f2cdc400ee87f5952ebf2a117488f2525a3fb2e23863a8efe3e4ee9e54e4d1", + "sha256:8ab6bcc8e424e07c1d4ba6df96f7fb963bcb48f590b9456de9ebd03b88084fe8", + "sha256:8adf014f2779992eba3b513e060d06f075f0ab2fb3ad956f413a102312f65cdf", + "sha256:9b0f98481ad5dc4cb430a60bbb8869f05505283b9ae1c62bdb65eb5e020ee8e3", + "sha256:9bea9138b0fc6e2218147e9c6ce1ff76ff8e29dc00bb1b64842bd1ca107aee9f", + "sha256:a09bfb51953930e7e838972ddf646c5d5f984992a66d79da6ba7f6a8d8a890cd", + "sha256:a0be99b599da95b7a90a918dd927b20c434bea5e1c9b3efc6a3c6cd67c23f813", + "sha256:a49aca4d961823b2846b739380c847e8964ff7ae0f0a683992b9d926054f0d6d", + "sha256:a4dc1319d0c162919ee7f4ee6face076becae2abbd351cc14f1fe70af5fb20d9", + "sha256:a8273e1abbcff1d7d29cbbb1ea7e57d38be72f1af3c597c854168508b91516c2", + "sha256:a8f7f9feecae53fa18d6a3ea7c75f9e9a1d4d20e5c3f9ce3fba83f07bcc4eee2", + "sha256:ad4f66fbb893b55f96f03020e67dcab49ffde0177c6565ccf9dec4fdf974eb61", + "sha256:af425f323fce1b07755edd783581e7283557296946212f5b1a934441718e7528", + "sha256:b14dd73f595199f4275bed4fb509277470d9b9059310537e3b3daba12b30c157", + "sha256:b4ad70d7cac4ca0c7b31444a0148bd3af01a2662fa12b1ad6f57cd4a04e21766", + "sha256:b80a4ee19b3442c57c38afa978adca546521a8822d663310b63ae2a7d7b13f3a", + "sha256:ba51129fcc510824b6ca6e2ce1c27e3e4d048b6e35d3ae6f7e517bed1b8b25ce", + "sha256:c011bd5ad03cc096f99ffcfdd18a1817354132c1331bed7a837a25226659845f", + "sha256:cc94f9fea17a5af8cf1a343597711a26b0117c0b812550d99934acb89d526ed2", + "sha256:ccd785fafa1c931deff6a7116e9a0d402d59fabe51644b0d0c268295ff847b25", + "sha256:d16a534da0e39785687b7295e2fcf9a339f4a20689024983d11afaa4657f8507", + "sha256:d3077a31633beef77d057c6523f5de7271ddef7bde5e019285b00c0cc9cac1e3", + "sha256:d603edea1ff7408638b2504905c032193b7dcee7af269802dbb35bc8c3310ed5", + "sha256:db082f728160369d9a6ed2e722438291558fc15ce06d0a7d696a8dad735c236b", + "sha256:ddef295aaf80cefb0c1606f1995899efcb17edc6b327eb6589e234e614b87756", + "sha256:e16ade71c93f6814d095d25cd6d28a90d63511ea396bd96e9ffcb886b278baaa", + "sha256:e3db7d833a7c38c317dc95b54e27f1d27012e031b45a7c24e360b53197d5f6e7", + "sha256:e5e193f89f4f8c1fe273f9a6e6df915092c9f2af6db2d1afb8bd53855025c11f", + "sha256:eb438a8bf6b695bf50d57e6a059ff09652a07968b2041178b3744ea785fcef9b", + "sha256:ebf02c32afa6b67e5861a27183dd98ed88419a94a2ab843cc145fb0bafcc5b28", + "sha256:ecd9e1fa97aa11bf67472220285775fa15e896da108f425e55d23d7540a712ce", + "sha256:ef67fedd863ffffd4adfd46d9d992b0f929c7f61a8307366d664d93517f2c78e", + "sha256:f28ae33dc5a0b9cee06e95fd420e42155d83271ab75964baf747ce959cac5f52", + "sha256:fb1c56d891f9e34303c451998ef62ba52659648bb0d75b03c5e4ac223a3342c2", + "sha256:fe03bf25fae4b95d8afe40004a321df644400fdcba4c8e5e1a19c1085b740888" ], - "index": "pypi", - "version": "==3.12.3" + "markers": "python_version >= '3.7'", + "version": "==4.6.0" }, "python-dateutil": { "hashes": [ @@ -637,23 +928,26 @@ "sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9" ], "index": "pypi", + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", "version": "==2.8.2" }, "python-dotenv": { "hashes": [ - "sha256:b7e3b04a59693c42c36f9ab1cc2acc46fa5df8c78e178fc33a8d4cd05c8d498f", - "sha256:d92a187be61fe482e4fd675b6d52200e7be63a12b724abbf931a40ce4fa92938" + "sha256:a8df96034aae6d2d50a4ebe8216326c61c3eb64836776504fcca410e5937a3ba", + "sha256:f5971a9226b701070a4bf2c38c89e5a3f0d64de8debda981d1db98583009122a" ], "index": "pypi", - "version": "==0.20.0" + "markers": "python_version >= '3.8'", + "version": "==1.0.0" }, "requests": { "hashes": [ - "sha256:7c5599b102feddaa661c826c56ab4fee28bfd17f5abca1ebbe3e7f19d7c97983", - "sha256:8fefa2a1a1365bf5520aac41836fbee479da67864514bdb821f31ce07ce65349" + "sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f", + "sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1" ], "index": "pypi", - "version": "==2.28.1" + "markers": "python_version >= '3.7'", + "version": "==2.31.0" }, "six": { "hashes": [ @@ -665,55 +959,56 @@ }, "tinycss2": { "hashes": [ - "sha256:b2e44dd8883c360c35dd0d1b5aad0b610e5156c2cb3b33434634e539ead9d8bf", - "sha256:fe794ceaadfe3cf3e686b22155d0da5780dd0e273471a51846d0a02bc204fec8" + "sha256:2b80a96d41e7c3914b8cda8bc7f705a4d9c49275616e886103dd839dfc847847", + "sha256:8cff3a8f066c2ec677c06dbc7b45619804a6938478d9d73c284b29d14ecb0627" ], - "markers": "python_version >= '3.6'", - "version": "==1.1.1" + "markers": "python_version >= '3.7'", + "version": "==1.2.1" }, "urllib3": { "hashes": [ - "sha256:3fa96cf423e6987997fc326ae8df396db2a8b7c667747d47ddd8ecba91f4a74e", - "sha256:b930dd878d5a8afb066a637fbb35144fe7901e3b209d1cd4f524bd0e9deee997" + "sha256:55901e917a5896a349ff771be919f8bd99aff50b79fe58fec595eb37bbc56bb3", + "sha256:df7aa8afb0148fa78488e7899b2c59b5f4ffcfa82e6c54ccb9dd37c1d7b52d54" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5' and python_version < '4'", - "version": "==1.26.12" + "markers": "python_version >= '3.8'", + "version": "==2.1.0" }, "uvloop": { "hashes": [ - "sha256:0949caf774b9fcefc7c5756bacbbbd3fc4c05a6b7eebc7c7ad6f825b23998d6d", - "sha256:0ddf6baf9cf11a1a22c71487f39f15b2cf78eb5bde7e5b45fbb99e8a9d91b9e1", - "sha256:1436c8673c1563422213ac6907789ecb2b070f5939b9cbff9ef7113f2b531595", - "sha256:23609ca361a7fc587031429fa25ad2ed7242941adec948f9d10c045bfecab06b", - "sha256:2a6149e1defac0faf505406259561bc14b034cdf1d4711a3ddcdfbaa8d825a05", - "sha256:2deae0b0fb00a6af41fe60a675cec079615b01d68beb4cc7b722424406b126a8", - "sha256:307958f9fc5c8bb01fad752d1345168c0abc5d62c1b72a4a8c6c06f042b45b20", - "sha256:30babd84706115626ea78ea5dbc7dd8d0d01a2e9f9b306d24ca4ed5796c66ded", - "sha256:3378eb62c63bf336ae2070599e49089005771cc651c8769aaad72d1bd9385a7c", - "sha256:3d97672dc709fa4447ab83276f344a165075fd9f366a97b712bdd3fee05efae8", - "sha256:3db8de10ed684995a7f34a001f15b374c230f7655ae840964d51496e2f8a8474", - "sha256:3ebeeec6a6641d0adb2ea71dcfb76017602ee2bfd8213e3fcc18d8f699c5104f", - "sha256:45cea33b208971e87a31c17622e4b440cac231766ec11e5d22c76fab3bf9df62", - "sha256:6708f30db9117f115eadc4f125c2a10c1a50d711461699a0cbfaa45b9a78e376", - "sha256:68532f4349fd3900b839f588972b3392ee56042e440dd5873dfbbcd2cc67617c", - "sha256:6aafa5a78b9e62493539456f8b646f85abc7093dd997f4976bb105537cf2635e", - "sha256:7d37dccc7ae63e61f7b96ee2e19c40f153ba6ce730d8ba4d3b4e9738c1dccc1b", - "sha256:864e1197139d651a76c81757db5eb199db8866e13acb0dfe96e6fc5d1cf45fc4", - "sha256:8887d675a64cfc59f4ecd34382e5b4f0ef4ae1da37ed665adba0c2badf0d6578", - "sha256:8efcadc5a0003d3a6e887ccc1fb44dec25594f117a94e3127954c05cf144d811", - "sha256:9b09e0f0ac29eee0451d71798878eae5a4e6a91aa275e114037b27f7db72702d", - "sha256:a4aee22ece20958888eedbad20e4dbb03c37533e010fb824161b4f05e641f738", - "sha256:a5abddb3558d3f0a78949c750644a67be31e47936042d4f6c888dd6f3c95f4aa", - "sha256:c092a2c1e736086d59ac8e41f9c98f26bbf9b9222a76f21af9dfe949b99b2eb9", - "sha256:c686a47d57ca910a2572fddfe9912819880b8765e2f01dc0dd12a9bf8573e539", - "sha256:cbbe908fda687e39afd6ea2a2f14c2c3e43f2ca88e3a11964b297822358d0e6c", - "sha256:ce9f61938d7155f79d3cb2ffa663147d4a76d16e08f65e2c66b77bd41b356718", - "sha256:dbbaf9da2ee98ee2531e0c780455f2841e4675ff580ecf93fe5c48fe733b5667", - "sha256:f1e507c9ee39c61bfddd79714e4f85900656db1aec4d40c6de55648e85c2799c", - "sha256:ff3d00b70ce95adce264462c930fbaecb29718ba6563db354608f37e49e09024" + "sha256:0246f4fd1bf2bf702e06b0d45ee91677ee5c31242f39aab4ea6fe0c51aedd0fd", + "sha256:02506dc23a5d90e04d4f65c7791e65cf44bd91b37f24cfc3ef6cf2aff05dc7ec", + "sha256:13dfdf492af0aa0a0edf66807d2b465607d11c4fa48f4a1fd41cbea5b18e8e8b", + "sha256:2693049be9d36fef81741fddb3f441673ba12a34a704e7b4361efb75cf30befc", + "sha256:271718e26b3e17906b28b67314c45d19106112067205119dddbd834c2b7ce797", + "sha256:2df95fca285a9f5bfe730e51945ffe2fa71ccbfdde3b0da5772b4ee4f2e770d5", + "sha256:31e672bb38b45abc4f26e273be83b72a0d28d074d5b370fc4dcf4c4eb15417d2", + "sha256:34175c9fd2a4bc3adc1380e1261f60306344e3407c20a4d684fd5f3be010fa3d", + "sha256:45bf4c24c19fb8a50902ae37c5de50da81de4922af65baf760f7c0c42e1088be", + "sha256:472d61143059c84947aa8bb74eabbace30d577a03a1805b77933d6bd13ddebbd", + "sha256:47bf3e9312f63684efe283f7342afb414eea4d3011542155c7e625cd799c3b12", + "sha256:492e2c32c2af3f971473bc22f086513cedfc66a130756145a931a90c3958cb17", + "sha256:4ce6b0af8f2729a02a5d1575feacb2a94fc7b2e983868b009d51c9a9d2149bef", + "sha256:5138821e40b0c3e6c9478643b4660bd44372ae1e16a322b8fc07478f92684e24", + "sha256:5588bd21cf1fcf06bded085f37e43ce0e00424197e7c10e77afd4bbefffef428", + "sha256:570fc0ed613883d8d30ee40397b79207eedd2624891692471808a95069a007c1", + "sha256:5a05128d315e2912791de6088c34136bfcdd0c7cbc1cf85fd6fd1bb321b7c849", + "sha256:5daa304d2161d2918fa9a17d5635099a2f78ae5b5960e742b2fcfbb7aefaa593", + "sha256:5f17766fb6da94135526273080f3455a112f82570b2ee5daa64d682387fe0dcd", + "sha256:6e3d4e85ac060e2342ff85e90d0c04157acb210b9ce508e784a944f852a40e67", + "sha256:7010271303961c6f0fe37731004335401eb9075a12680738731e9c92ddd96ad6", + "sha256:7207272c9520203fea9b93843bb775d03e1cf88a80a936ce760f60bb5add92f3", + "sha256:78ab247f0b5671cc887c31d33f9b3abfb88d2614b84e4303f1a63b46c046c8bd", + "sha256:7b1fd71c3843327f3bbc3237bedcdb6504fd50368ab3e04d0410e52ec293f5b8", + "sha256:8ca4956c9ab567d87d59d49fa3704cf29e37109ad348f2d5223c9bf761a332e7", + "sha256:91ab01c6cd00e39cde50173ba4ec68a1e578fee9279ba64f5221810a9e786533", + "sha256:cd81bdc2b8219cb4b2556eea39d2e36bfa375a2dd021404f90a62e44efaaf957", + "sha256:da8435a3bd498419ee8c13c34b89b5005130a476bda1d6ca8cfdde3de35cd650", + "sha256:de4313d7f575474c8f5a12e163f6d89c0a878bc49219641d49e6f1444369a90e", + "sha256:e27f100e1ff17f6feeb1f33968bc185bf8ce41ca557deee9d9bbbffeb72030b7", + "sha256:f467a5fd23b4fc43ed86342641f3936a68ded707f4627622fa3f82a120e18256" ], "markers": "sys_platform != 'win32'", - "version": "==0.17.0" + "version": "==0.19.0" }, "webencodings": { "hashes": [ @@ -724,322 +1019,345 @@ }, "yarl": { "hashes": [ - "sha256:076eede537ab978b605f41db79a56cad2e7efeea2aa6e0fa8f05a26c24a034fb", - "sha256:07b21e274de4c637f3e3b7104694e53260b5fc10d51fb3ec5fed1da8e0f754e3", - "sha256:0ab5a138211c1c366404d912824bdcf5545ccba5b3ff52c42c4af4cbdc2c5035", - "sha256:0c03f456522d1ec815893d85fccb5def01ffaa74c1b16ff30f8aaa03eb21e453", - "sha256:12768232751689c1a89b0376a96a32bc7633c08da45ad985d0c49ede691f5c0d", - "sha256:19cd801d6f983918a3f3a39f3a45b553c015c5aac92ccd1fac619bd74beece4a", - "sha256:1ca7e596c55bd675432b11320b4eacc62310c2145d6801a1f8e9ad160685a231", - "sha256:1e4808f996ca39a6463f45182e2af2fae55e2560be586d447ce8016f389f626f", - "sha256:205904cffd69ae972a1707a1bd3ea7cded594b1d773a0ce66714edf17833cdae", - "sha256:20df6ff4089bc86e4a66e3b1380460f864df3dd9dccaf88d6b3385d24405893b", - "sha256:21ac44b763e0eec15746a3d440f5e09ad2ecc8b5f6dcd3ea8cb4773d6d4703e3", - "sha256:29e256649f42771829974e742061c3501cc50cf16e63f91ed8d1bf98242e5507", - "sha256:2d800b9c2eaf0684c08be5f50e52bfa2aa920e7163c2ea43f4f431e829b4f0fd", - "sha256:2d93a049d29df172f48bcb09acf9226318e712ce67374f893b460b42cc1380ae", - "sha256:31a9a04ecccd6b03e2b0e12e82131f1488dea5555a13a4d32f064e22a6003cfe", - "sha256:3d1a50e461615747dd93c099f297c1994d472b0f4d2db8a64e55b1edf704ec1c", - "sha256:449c957ffc6bc2309e1fbe67ab7d2c1efca89d3f4912baeb8ead207bb3cc1cd4", - "sha256:4a88510731cd8d4befaba5fbd734a7dd914de5ab8132a5b3dde0bbd6c9476c64", - "sha256:4c322cbaa4ed78a8aac89b2174a6df398faf50e5fc12c4c191c40c59d5e28357", - "sha256:5395da939ffa959974577eff2cbfc24b004a2fb6c346918f39966a5786874e54", - "sha256:5587bba41399854703212b87071c6d8638fa6e61656385875f8c6dff92b2e461", - "sha256:56c11efb0a89700987d05597b08a1efcd78d74c52febe530126785e1b1a285f4", - "sha256:5999c4662631cb798496535afbd837a102859568adc67d75d2045e31ec3ac497", - "sha256:59ddd85a1214862ce7c7c66457f05543b6a275b70a65de366030d56159a979f0", - "sha256:6347f1a58e658b97b0a0d1ff7658a03cb79bdbda0331603bed24dd7054a6dea1", - "sha256:6628d750041550c5d9da50bb40b5cf28a2e63b9388bac10fedd4f19236ef4957", - "sha256:6afb336e23a793cd3b6476c30f030a0d4c7539cd81649683b5e0c1b0ab0bf350", - "sha256:6c8148e0b52bf9535c40c48faebb00cb294ee577ca069d21bd5c48d302a83780", - "sha256:76577f13333b4fe345c3704811ac7509b31499132ff0181f25ee26619de2c843", - "sha256:7c0da7e44d0c9108d8b98469338705e07f4bb7dab96dbd8fa4e91b337db42548", - "sha256:7de89c8456525650ffa2bb56a3eee6af891e98f498babd43ae307bd42dca98f6", - "sha256:7ec362167e2c9fd178f82f252b6d97669d7245695dc057ee182118042026da40", - "sha256:7fce6cbc6c170ede0221cc8c91b285f7f3c8b9fe28283b51885ff621bbe0f8ee", - "sha256:85cba594433915d5c9a0d14b24cfba0339f57a2fff203a5d4fd070e593307d0b", - "sha256:8b0af1cf36b93cee99a31a545fe91d08223e64390c5ecc5e94c39511832a4bb6", - "sha256:9130ddf1ae9978abe63808b6b60a897e41fccb834408cde79522feb37fb72fb0", - "sha256:99449cd5366fe4608e7226c6cae80873296dfa0cde45d9b498fefa1de315a09e", - "sha256:9de955d98e02fab288c7718662afb33aab64212ecb368c5dc866d9a57bf48880", - "sha256:a0fb2cb4204ddb456a8e32381f9a90000429489a25f64e817e6ff94879d432fc", - "sha256:a165442348c211b5dea67c0206fc61366212d7082ba8118c8c5c1c853ea4d82e", - "sha256:ab2a60d57ca88e1d4ca34a10e9fb4ab2ac5ad315543351de3a612bbb0560bead", - "sha256:abc06b97407868ef38f3d172762f4069323de52f2b70d133d096a48d72215d28", - "sha256:af887845b8c2e060eb5605ff72b6f2dd2aab7a761379373fd89d314f4752abbf", - "sha256:b19255dde4b4f4c32e012038f2c169bb72e7f081552bea4641cab4d88bc409dd", - "sha256:b3ded839a5c5608eec8b6f9ae9a62cb22cd037ea97c627f38ae0841a48f09eae", - "sha256:c1445a0c562ed561d06d8cbc5c8916c6008a31c60bc3655cdd2de1d3bf5174a0", - "sha256:d0272228fabe78ce00a3365ffffd6f643f57a91043e119c289aaba202f4095b0", - "sha256:d0b51530877d3ad7a8d47b2fff0c8df3b8f3b8deddf057379ba50b13df2a5eae", - "sha256:d0f77539733e0ec2475ddcd4e26777d08996f8cd55d2aef82ec4d3896687abda", - "sha256:d2b8f245dad9e331540c350285910b20dd913dc86d4ee410c11d48523c4fd546", - "sha256:dd032e8422a52e5a4860e062eb84ac94ea08861d334a4bcaf142a63ce8ad4802", - "sha256:de49d77e968de6626ba7ef4472323f9d2e5a56c1d85b7c0e2a190b2173d3b9be", - "sha256:de839c3a1826a909fdbfe05f6fe2167c4ab033f1133757b5936efe2f84904c07", - "sha256:e80ed5a9939ceb6fda42811542f31c8602be336b1fb977bccb012e83da7e4936", - "sha256:ea30a42dc94d42f2ba4d0f7c0ffb4f4f9baa1b23045910c0c32df9c9902cb272", - "sha256:ea513a25976d21733bff523e0ca836ef1679630ef4ad22d46987d04b372d57fc", - "sha256:ed19b74e81b10b592084a5ad1e70f845f0aacb57577018d31de064e71ffa267a", - "sha256:f5af52738e225fcc526ae64071b7e5342abe03f42e0e8918227b38c9aa711e28", - "sha256:fae37373155f5ef9b403ab48af5136ae9851151f7aacd9926251ab26b953118b" + "sha256:09c19e5f4404574fcfb736efecf75844ffe8610606f3fccc35a1515b8b6712c4", + "sha256:0ab5baaea8450f4a3e241ef17e3d129b2143e38a685036b075976b9c415ea3eb", + "sha256:0d155a092bf0ebf4a9f6f3b7a650dc5d9a5bbb585ef83a52ed36ba46f55cc39d", + "sha256:126638ab961633f0940a06e1c9d59919003ef212a15869708dcb7305f91a6732", + "sha256:1a0a4f3aaa18580038cfa52a7183c8ffbbe7d727fe581300817efc1e96d1b0e9", + "sha256:1d93461e2cf76c4796355494f15ffcb50a3c198cc2d601ad8d6a96219a10c363", + "sha256:26a1a8443091c7fbc17b84a0d9f38de34b8423b459fb853e6c8cdfab0eacf613", + "sha256:271d63396460b6607b588555ea27a1a02b717ca2e3f2cf53bdde4013d7790929", + "sha256:28a108cb92ce6cf867690a962372996ca332d8cda0210c5ad487fe996e76b8bb", + "sha256:29beac86f33d6c7ab1d79bd0213aa7aed2d2f555386856bb3056d5fdd9dab279", + "sha256:2c757f64afe53a422e45e3e399e1e3cf82b7a2f244796ce80d8ca53e16a49b9f", + "sha256:2dad8166d41ebd1f76ce107cf6a31e39801aee3844a54a90af23278b072f1ccf", + "sha256:2dc72e891672343b99db6d497024bf8b985537ad6c393359dc5227ef653b2f17", + "sha256:2f3c8822bc8fb4a347a192dd6a28a25d7f0ea3262e826d7d4ef9cc99cd06d07e", + "sha256:32435d134414e01d937cd9d6cc56e8413a8d4741dea36af5840c7750f04d16ab", + "sha256:3cfa4dbe17b2e6fca1414e9c3bcc216f6930cb18ea7646e7d0d52792ac196808", + "sha256:3d5434b34100b504aabae75f0622ebb85defffe7b64ad8f52b8b30ec6ef6e4b9", + "sha256:4003f380dac50328c85e85416aca6985536812c082387255c35292cb4b41707e", + "sha256:44e91a669c43f03964f672c5a234ae0d7a4d49c9b85d1baa93dec28afa28ffbd", + "sha256:4a14907b597ec55740f63e52d7fee0e9ee09d5b9d57a4f399a7423268e457b57", + "sha256:4ce77d289f8d40905c054b63f29851ecbfd026ef4ba5c371a158cfe6f623663e", + "sha256:4d6d74a97e898c1c2df80339aa423234ad9ea2052f66366cef1e80448798c13d", + "sha256:51382c72dd5377861b573bd55dcf680df54cea84147c8648b15ac507fbef984d", + "sha256:525cd69eff44833b01f8ef39aa33a9cc53a99ff7f9d76a6ef6a9fb758f54d0ff", + "sha256:53ec65f7eee8655bebb1f6f1607760d123c3c115a324b443df4f916383482a67", + "sha256:5f74b015c99a5eac5ae589de27a1201418a5d9d460e89ccb3366015c6153e60a", + "sha256:6280353940f7e5e2efaaabd686193e61351e966cc02f401761c4d87f48c89ea4", + "sha256:632c7aeb99df718765adf58eacb9acb9cbc555e075da849c1378ef4d18bf536a", + "sha256:6465d36381af057d0fab4e0f24ef0e80ba61f03fe43e6eeccbe0056e74aadc70", + "sha256:66a6dbf6ca7d2db03cc61cafe1ee6be838ce0fbc97781881a22a58a7c5efef42", + "sha256:6d350388ba1129bc867c6af1cd17da2b197dff0d2801036d2d7d83c2d771a682", + "sha256:7217234b10c64b52cc39a8d82550342ae2e45be34f5bff02b890b8c452eb48d7", + "sha256:721ee3fc292f0d069a04016ef2c3a25595d48c5b8ddc6029be46f6158d129c92", + "sha256:72a57b41a0920b9a220125081c1e191b88a4cdec13bf9d0649e382a822705c65", + "sha256:73cc83f918b69110813a7d95024266072d987b903a623ecae673d1e71579d566", + "sha256:778df71c8d0c8c9f1b378624b26431ca80041660d7be7c3f724b2c7a6e65d0d6", + "sha256:79e1df60f7c2b148722fb6cafebffe1acd95fd8b5fd77795f56247edaf326752", + "sha256:7c86d0d0919952d05df880a1889a4f0aeb6868e98961c090e335671dea5c0361", + "sha256:7eaf13af79950142ab2bbb8362f8d8d935be9aaf8df1df89c86c3231e4ff238a", + "sha256:828235a2a169160ee73a2fcfb8a000709edf09d7511fccf203465c3d5acc59e4", + "sha256:8535e111a064f3bdd94c0ed443105934d6f005adad68dd13ce50a488a0ad1bf3", + "sha256:88d2c3cc4b2f46d1ba73d81c51ec0e486f59cc51165ea4f789677f91a303a9a7", + "sha256:8a2538806be846ea25e90c28786136932ec385c7ff3bc1148e45125984783dc6", + "sha256:8dab30b21bd6fb17c3f4684868c7e6a9e8468078db00f599fb1c14e324b10fca", + "sha256:8f18a7832ff85dfcd77871fe677b169b1bc60c021978c90c3bb14f727596e0ae", + "sha256:946db4511b2d815979d733ac6a961f47e20a29c297be0d55b6d4b77ee4b298f6", + "sha256:96758e56dceb8a70f8a5cff1e452daaeff07d1cc9f11e9b0c951330f0a2396a7", + "sha256:9a172c3d5447b7da1680a1a2d6ecdf6f87a319d21d52729f45ec938a7006d5d8", + "sha256:9a5211de242754b5e612557bca701f39f8b1a9408dff73c6db623f22d20f470e", + "sha256:9df9a0d4c5624790a0dea2e02e3b1b3c69aed14bcb8650e19606d9df3719e87d", + "sha256:aa4643635f26052401750bd54db911b6342eb1a9ac3e74f0f8b58a25d61dfe41", + "sha256:aed37db837ecb5962469fad448aaae0f0ee94ffce2062cf2eb9aed13328b5196", + "sha256:af52725c7c39b0ee655befbbab5b9a1b209e01bb39128dce0db226a10014aacc", + "sha256:b0b8c06afcf2bac5a50b37f64efbde978b7f9dc88842ce9729c020dc71fae4ce", + "sha256:b61e64b06c3640feab73fa4ff9cb64bd8182de52e5dc13038e01cfe674ebc321", + "sha256:b7831566595fe88ba17ea80e4b61c0eb599f84c85acaa14bf04dd90319a45b90", + "sha256:b8bc5b87a65a4e64bc83385c05145ea901b613d0d3a434d434b55511b6ab0067", + "sha256:b8d51817cf4b8d545963ec65ff06c1b92e5765aa98831678d0e2240b6e9fd281", + "sha256:b9f9cafaf031c34d95c1528c16b2fa07b710e6056b3c4e2e34e9317072da5d1a", + "sha256:bb72d2a94481e7dc7a0c522673db288f31849800d6ce2435317376a345728225", + "sha256:c25ec06e4241e162f5d1f57c370f4078797ade95c9208bd0c60f484834f09c96", + "sha256:c405d482c320a88ab53dcbd98d6d6f32ada074f2d965d6e9bf2d823158fa97de", + "sha256:c4472fe53ebf541113e533971bd8c32728debc4c6d8cc177f2bff31d011ec17e", + "sha256:c4b1efb11a8acd13246ffb0bee888dd0e8eb057f8bf30112e3e21e421eb82d4a", + "sha256:c5f3faeb8100a43adf3e7925d556801d14b5816a0ac9e75e22948e787feec642", + "sha256:c6f034386e5550b5dc8ded90b5e2ff7db21f0f5c7de37b6efc5dac046eb19c10", + "sha256:c99ddaddb2fbe04953b84d1651149a0d85214780e4d0ee824e610ab549d98d92", + "sha256:ca6b66f69e30f6e180d52f14d91ac854b8119553b524e0e28d5291a724f0f423", + "sha256:cccdc02e46d2bd7cb5f38f8cc3d9db0d24951abd082b2f242c9e9f59c0ab2af3", + "sha256:cd49a908cb6d387fc26acee8b7d9fcc9bbf8e1aca890c0b2fdfd706057546080", + "sha256:cf7a4e8de7f1092829caef66fd90eaf3710bc5efd322a816d5677b7664893c93", + "sha256:cfd77e8e5cafba3fb584e0f4b935a59216f352b73d4987be3af51f43a862c403", + "sha256:d34c4f80956227f2686ddea5b3585e109c2733e2d4ef12eb1b8b4e84f09a2ab6", + "sha256:d61a0ca95503867d4d627517bcfdc28a8468c3f1b0b06c626f30dd759d3999fd", + "sha256:d81657b23e0edb84b37167e98aefb04ae16cbc5352770057893bd222cdc6e45f", + "sha256:d92d897cb4b4bf915fbeb5e604c7911021a8456f0964f3b8ebbe7f9188b9eabb", + "sha256:dd318e6b75ca80bff0b22b302f83a8ee41c62b8ac662ddb49f67ec97e799885d", + "sha256:dd952b9c64f3b21aedd09b8fe958e4931864dba69926d8a90c90d36ac4e28c9a", + "sha256:e0e7e83f31e23c5d00ff618045ddc5e916f9e613d33c5a5823bc0b0a0feb522f", + "sha256:e0f17d1df951336a02afc8270c03c0c6e60d1f9996fcbd43a4ce6be81de0bd9d", + "sha256:e2a16ef5fa2382af83bef4a18c1b3bcb4284c4732906aa69422cf09df9c59f1f", + "sha256:e36021db54b8a0475805acc1d6c4bca5d9f52c3825ad29ae2d398a9d530ddb88", + "sha256:e73db54c967eb75037c178a54445c5a4e7461b5203b27c45ef656a81787c0c1b", + "sha256:e741bd48e6a417bdfbae02e088f60018286d6c141639359fb8df017a3b69415a", + "sha256:f7271d6bd8838c49ba8ae647fc06469137e1c161a7ef97d778b72904d9b68696", + "sha256:fc391e3941045fd0987c77484b2799adffd08e4b6735c4ee5f054366a2e1551d", + "sha256:fc94441bcf9cb8c59f51f23193316afefbf3ff858460cb47b5758bf66a14d130", + "sha256:fe34befb8c765b8ce562f0200afda3578f8abb159c76de3ab354c80b72244c41", + "sha256:fe8080b4f25dfc44a86bedd14bc4f9d469dfc6456e6f3c5d9077e81a5fedfba7", + "sha256:ff34cb09a332832d1cf38acd0f604c068665192c6107a439a92abfd8acf90fe2" ], "markers": "python_version >= '3.7'", - "version": "==1.8.1" + "version": "==1.9.3" } }, "develop": { "astroid": { "hashes": [ - "sha256:3975a0bd5373bdce166e60c851cfcbaf21ee96de80ec518c1f4cb3e94c3fb334", - "sha256:ab7f36e8a78b8e54a62028ba6beef7561db4cdb6f2a5009ecc44a6f42b5697ef" + "sha256:7d5895c9825e18079c5aeac0572bc2e4c83205c95d416e0b4fee8bc361d2d9ca", + "sha256:86b0bb7d7da0be1a7c4aedb7974e391b32d4ed89e33de6ed6902b4b15c97577e" ], - "markers": "python_version ~= '3.6'", - "version": "==2.6.6" + "markers": "python_full_version >= '3.8.0'", + "version": "==3.0.1" }, "bandit": { "hashes": [ - "sha256:2d63a8c573417bae338962d4b9b06fbc6080f74ecd955a092849e1e65c717bd2", - "sha256:412d3f259dab4077d0e7f0c11f50f650cc7d10db905d98f6520a95a18049658a" + "sha256:75665181dc1e0096369112541a056c59d1c5f66f9bb74a8d686c3c362b83f549", + "sha256:bdfc739baa03b880c2d15d0431b31c658ffc348e907fe197e54e0389dd59e11e" ], "index": "pypi", - "version": "==1.7.4" + "markers": "python_version >= '3.7'", + "version": "==1.7.5" }, "black": { "hashes": [ - "sha256:06f9d8846f2340dfac80ceb20200ea5d1b3f181dd0556b47af4e8e0b24fa0a6b", - "sha256:10dbe6e6d2988049b4655b2b739f98785a884d4d6b85bc35133a8fb9a2233176", - "sha256:2497f9c2386572e28921fa8bec7be3e51de6801f7459dffd6e62492531c47e09", - "sha256:30d78ba6bf080eeaf0b7b875d924b15cd46fec5fd044ddfbad38c8ea9171043a", - "sha256:328efc0cc70ccb23429d6be184a15ce613f676bdfc85e5fe8ea2a9354b4e9015", - "sha256:35020b8886c022ced9282b51b5a875b6d1ab0c387b31a065b84db7c33085ca79", - "sha256:5795a0375eb87bfe902e80e0c8cfaedf8af4d49694d69161e5bd3206c18618bb", - "sha256:5891ef8abc06576985de8fa88e95ab70641de6c1fca97e2a15820a9b69e51b20", - "sha256:637a4014c63fbf42a692d22b55d8ad6968a946b4a6ebc385c5505d9625b6a464", - "sha256:67c8301ec94e3bcc8906740fe071391bce40a862b7be0b86fb5382beefecd968", - "sha256:6d2fc92002d44746d3e7db7cf9313cf4452f43e9ea77a2c939defce3b10b5c82", - "sha256:6ee227b696ca60dd1c507be80a6bc849a5a6ab57ac7352aad1ffec9e8b805f21", - "sha256:863714200ada56cbc366dc9ae5291ceb936573155f8bf8e9de92aef51f3ad0f0", - "sha256:9b542ced1ec0ceeff5b37d69838106a6348e60db7b8fdd245294dc1d26136265", - "sha256:a6342964b43a99dbc72f72812bf88cad8f0217ae9acb47c0d4f141a6416d2d7b", - "sha256:ad4efa5fad66b903b4a5f96d91461d90b9507a812b3c5de657d544215bb7877a", - "sha256:bc58025940a896d7e5356952228b68f793cf5fcb342be703c3a2669a1488cb72", - "sha256:cc1e1de68c8e5444e8f94c3670bb48a2beef0e91dddfd4fcc29595ebd90bb9ce", - "sha256:cee3e11161dde1b2a33a904b850b0899e0424cc331b7295f2a9698e79f9a69a0", - "sha256:e3556168e2e5c49629f7b0f377070240bd5511e45e25a4497bb0073d9dda776a", - "sha256:e8477ec6bbfe0312c128e74644ac8a02ca06bcdb8982d4ee06f209be28cdf163", - "sha256:ee8f1f7228cce7dffc2b464f07ce769f478968bfb3dd1254a4c2eeed84928aad", - "sha256:fd57160949179ec517d32ac2ac898b5f20d68ed1a9c977346efbac9c2f1e779d" + "sha256:250d7e60f323fcfc8ea6c800d5eba12f7967400eb6c2d21ae85ad31c204fb1f4", + "sha256:2a9acad1451632021ee0d146c8765782a0c3846e0e0ea46659d7c4f89d9b212b", + "sha256:412f56bab20ac85927f3a959230331de5614aecda1ede14b373083f62ec24e6f", + "sha256:421f3e44aa67138ab1b9bfbc22ee3780b22fa5b291e4db8ab7eee95200726b07", + "sha256:45aa1d4675964946e53ab81aeec7a37613c1cb71647b5394779e6efb79d6d187", + "sha256:4c44b7211a3a0570cc097e81135faa5f261264f4dfaa22bd5ee2875a4e773bd6", + "sha256:4c68855825ff432d197229846f971bc4d6666ce90492e5b02013bcaca4d9ab05", + "sha256:5133f5507007ba08d8b7b263c7aa0f931af5ba88a29beacc4b2dc23fcefe9c06", + "sha256:54caaa703227c6e0c87b76326d0862184729a69b73d3b7305b6288e1d830067e", + "sha256:58e5f4d08a205b11800332920e285bd25e1a75c54953e05502052738fe16b3b5", + "sha256:698c1e0d5c43354ec5d6f4d914d0d553a9ada56c85415700b81dc90125aac244", + "sha256:6c1cac07e64433f646a9a838cdc00c9768b3c362805afc3fce341af0e6a9ae9f", + "sha256:760415ccc20f9e8747084169110ef75d545f3b0932ee21368f63ac0fee86b221", + "sha256:7f622b6822f02bfaf2a5cd31fdb7cd86fcf33dab6ced5185c35f5db98260b055", + "sha256:cf57719e581cfd48c4efe28543fea3d139c6b6f1238b3f0102a9c73992cbb479", + "sha256:d136ef5b418c81660ad847efe0e55c58c8208b77a57a28a503a5f345ccf01394", + "sha256:dbea0bb8575c6b6303cc65017b46351dc5953eea5c0a59d7b7e3a2d2f433a911", + "sha256:fc7f6a44d52747e65a02558e1d807c82df1d66ffa80a601862040a43ec2e3142" ], "index": "pypi", - "version": "==22.3.0" + "markers": "python_version >= '3.8'", + "version": "==23.11.0" }, "click": { "hashes": [ - "sha256:7682dc8afb30297001674575ea00d1814d808d6a36af415a82bd481d37ba7b8e", - "sha256:bb4d8133cb15a609f44e8213d9b391b0809795062913b383c62be0ee95b1db48" + "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28", + "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de" ], "markers": "python_version >= '3.7'", - "version": "==8.1.3" + "version": "==8.1.7" }, - "colorama": { + "dill": { "hashes": [ - "sha256:854bf444933e37f5824ae7bfc1e98d5bce2ebe4160d46b5edf346a89358e99da", - "sha256:e6c6b4334fc50988a639d9b98aa429a0b57da6e17b9a44f0451f930b6967b7a4" + "sha256:76b122c08ef4ce2eedcd4d1abd8e641114bfc6c2867f49f3c41facf65bf19f5e", + "sha256:cc1c8b182eb3013e24bd475ff2e9295af86c1a38eb1aff128dac8962a9ce3c03" ], - "index": "pypi", - "version": "==0.4.5" + "markers": "python_version < '3.11'", + "version": "==0.3.7" }, "gitdb": { "hashes": [ - "sha256:8033ad4e853066ba6ca92050b9df2f89301b8fc8bf7e9324d412a63f8bf1a8fd", - "sha256:bac2fd45c0a1c9cf619e63a90d62bdc63892ef92387424b855792a6cabe789aa" + "sha256:81a3407ddd2ee8df444cbacea00e2d038e40150acfa3001696fe0dcf1d3adfa4", + "sha256:bf5421126136d6d0af55bc1e7c1af1c397a34f5b7bd79e776cd3e89785c2b04b" ], - "markers": "python_version >= '3.6'", - "version": "==4.0.9" + "markers": "python_version >= '3.7'", + "version": "==4.0.11" }, "gitpython": { "hashes": [ - "sha256:1c885ce809e8ba2d88a29befeb385fcea06338d3640712b59ca623c220bb5704", - "sha256:5b68b000463593e05ff2b261acff0ff0972df8ab1b70d3cdbd41b546c8b8fc3d" + "sha256:22b126e9ffb671fdd0c129796343a02bf67bf2994b35449ffc9321aa755e18a4", + "sha256:cf14627d5a8049ffbf49915732e5eddbe8134c3bdb9d476e6182b676fc573f8a" ], "markers": "python_version >= '3.7'", - "version": "==3.1.27" + "version": "==3.1.40" }, "isort": { "hashes": [ - "sha256:6f62d78e2f89b4500b080fe3a81690850cd254227f27f75c3a0c491a1f351ba7", - "sha256:e8443a5e7a020e9d7f97f1d7d9cd17c88bcb3bc7e218bf9cf5095fe550be2951" - ], - "markers": "python_version < '4.0' and python_full_version >= '3.6.1'", - "version": "==5.10.1" - }, - "lazy-object-proxy": { - "hashes": [ - "sha256:043651b6cb706eee4f91854da4a089816a6606c1428fd391573ef8cb642ae4f7", - "sha256:07fa44286cda977bd4803b656ffc1c9b7e3bc7dff7d34263446aec8f8c96f88a", - "sha256:12f3bb77efe1367b2515f8cb4790a11cffae889148ad33adad07b9b55e0ab22c", - "sha256:2052837718516a94940867e16b1bb10edb069ab475c3ad84fd1e1a6dd2c0fcfc", - "sha256:2130db8ed69a48a3440103d4a520b89d8a9405f1b06e2cc81640509e8bf6548f", - "sha256:39b0e26725c5023757fc1ab2a89ef9d7ab23b84f9251e28f9cc114d5b59c1b09", - "sha256:46ff647e76f106bb444b4533bb4153c7370cdf52efc62ccfc1a28bdb3cc95442", - "sha256:4dca6244e4121c74cc20542c2ca39e5c4a5027c81d112bfb893cf0790f96f57e", - "sha256:553b0f0d8dbf21890dd66edd771f9b1b5f51bd912fa5f26de4449bfc5af5e029", - "sha256:677ea950bef409b47e51e733283544ac3d660b709cfce7b187f5ace137960d61", - "sha256:6a24357267aa976abab660b1d47a34aaf07259a0c3859a34e536f1ee6e76b5bb", - "sha256:6a6e94c7b02641d1311228a102607ecd576f70734dc3d5e22610111aeacba8a0", - "sha256:6aff3fe5de0831867092e017cf67e2750c6a1c7d88d84d2481bd84a2e019ec35", - "sha256:6ecbb350991d6434e1388bee761ece3260e5228952b1f0c46ffc800eb313ff42", - "sha256:7096a5e0c1115ec82641afbdd70451a144558ea5cf564a896294e346eb611be1", - "sha256:70ed0c2b380eb6248abdef3cd425fc52f0abd92d2b07ce26359fcbc399f636ad", - "sha256:8561da8b3dd22d696244d6d0d5330618c993a215070f473b699e00cf1f3f6443", - "sha256:85b232e791f2229a4f55840ed54706110c80c0a210d076eee093f2b2e33e1bfd", - "sha256:898322f8d078f2654d275124a8dd19b079080ae977033b713f677afcfc88e2b9", - "sha256:8f3953eb575b45480db6568306893f0bd9d8dfeeebd46812aa09ca9579595148", - "sha256:91ba172fc5b03978764d1df5144b4ba4ab13290d7bab7a50f12d8117f8630c38", - "sha256:9d166602b525bf54ac994cf833c385bfcc341b364e3ee71e3bf5a1336e677b55", - "sha256:a57d51ed2997e97f3b8e3500c984db50a554bb5db56c50b5dab1b41339b37e36", - "sha256:b9e89b87c707dd769c4ea91f7a31538888aad05c116a59820f28d59b3ebfe25a", - "sha256:bb8c5fd1684d60a9902c60ebe276da1f2281a318ca16c1d0a96db28f62e9166b", - "sha256:c19814163728941bb871240d45c4c30d33b8a2e85972c44d4e63dd7107faba44", - "sha256:c4ce15276a1a14549d7e81c243b887293904ad2d94ad767f42df91e75fd7b5b6", - "sha256:c7a683c37a8a24f6428c28c561c80d5f4fd316ddcf0c7cab999b15ab3f5c5c69", - "sha256:d609c75b986def706743cdebe5e47553f4a5a1da9c5ff66d76013ef396b5a8a4", - "sha256:d66906d5785da8e0be7360912e99c9188b70f52c422f9fc18223347235691a84", - "sha256:dd7ed7429dbb6c494aa9bc4e09d94b778a3579be699f9d67da7e6804c422d3de", - "sha256:df2631f9d67259dc9620d831384ed7732a198eb434eadf69aea95ad18c587a28", - "sha256:e368b7f7eac182a59ff1f81d5f3802161932a41dc1b1cc45c1f757dc876b5d2c", - "sha256:e40f2013d96d30217a51eeb1db28c9ac41e9d0ee915ef9d00da639c5b63f01a1", - "sha256:f769457a639403073968d118bc70110e7dce294688009f5c24ab78800ae56dc8", - "sha256:fccdf7c2c5821a8cbd0a9440a456f5050492f2270bd54e94360cac663398739b", - "sha256:fd45683c3caddf83abbb1249b653a266e7069a09f486daa8863fb0e7496a9fdb" + "sha256:8bef7dde241278824a6d83f44a544709b065191b95b6e50894bdc722fcba0504", + "sha256:f84c2818376e66cf843d497486ea8fed8700b340f308f076c6fb1229dff318b6" ], - "markers": "python_version >= '3.6'", - "version": "==1.7.1" + "markers": "python_full_version >= '3.8.0'", + "version": "==5.12.0" + }, + "markdown-it-py": { + "hashes": [ + "sha256:355216845c60bd96232cd8d8c40e8f9765cc86f46880e43a8fd22dc1a1a8cab1", + "sha256:e3f60a94fa066dc52ec76661e37c851cb232d92f9886b15cb560aaada2df8feb" + ], + "markers": "python_version >= '3.8'", + "version": "==3.0.0" }, "mccabe": { "hashes": [ - "sha256:ab8a6258860da4b6677da4bd2fe5dc2c659cff31b3ee4f7f5d64e79735b80d42", - "sha256:dd8d182285a0fe56bace7f45b5e7d1a6ebcbf524e8f3bd87eb0f125271b8831f" + "sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325", + "sha256:6c2d30ab6be0e4a46919781807b4f0d834ebdd6c6e3dca0bda5a15f863427b6e" ], - "version": "==0.6.1" + "markers": "python_version >= '3.6'", + "version": "==0.7.0" + }, + "mdurl": { + "hashes": [ + "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8", + "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba" + ], + "markers": "python_version >= '3.7'", + "version": "==0.1.2" }, "mypy-extensions": { "hashes": [ - "sha256:090fedd75945a69ae91ce1303b5824f428daf5a028d2f6ab8a299250a846f15d", - "sha256:2d82818f5bb3e369420cb3c4060a7970edba416647068eb4c5343488a6c604a8" + "sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d", + "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782" ], - "version": "==0.4.3" + "markers": "python_version >= '3.5'", + "version": "==1.0.0" + }, + "packaging": { + "hashes": [ + "sha256:048fb0e9405036518eaaf48a55953c750c11e1a1b68e0dd1a9d62ed0c092cfc5", + "sha256:8c491190033a9af7e1d931d0b5dacc2ef47509b34dd0de67ed209b5203fc88c7" + ], + "index": "pypi", + "markers": "python_version >= '3.7'", + "version": "==23.2" }, "pathspec": { "hashes": [ - "sha256:46846318467efc4556ccfd27816e004270a9eeeeb4d062ce5e6fc7a87c573f93", - "sha256:7ace6161b621d31e7902eb6b5ae148d12cfd23f4a249b9ffb6b9fee12084323d" + "sha256:1d6ed233af05e679efb96b1851550ea95bbb64b7c490b0f5aa52996c11e92a20", + "sha256:e0d8d0ac2f12da61956eb2306b69f9469b42f4deb0f3cb6ed47b9cce9996ced3" ], "markers": "python_version >= '3.7'", - "version": "==0.10.1" + "version": "==0.11.2" }, "pbr": { "hashes": [ - "sha256:cfcc4ff8e698256fc17ea3ff796478b050852585aa5bae79ecd05b2ab7b39b9a", - "sha256:da3e18aac0a3c003e9eea1a81bd23e5a3a75d745670dcf736317b7d966887fdf" + "sha256:4a7317d5e3b17a3dccb6a8cfe67dab65b20551404c52c8ed41279fa4f0cb4cda", + "sha256:d1377122a5a00e2f940ee482999518efe16d745d423a670c27773dfbc3c9a7d9" ], "markers": "python_version >= '2.6'", - "version": "==5.10.0" + "version": "==6.0.0" }, "platformdirs": { "hashes": [ - "sha256:027d8e83a2d7de06bbac4e5ef7e023c02b863d7ea5d079477e722bb41ab25788", - "sha256:58c8abb07dcb441e6ee4b11d8df0ac856038f944ab98b7be6b27b2a3c7feef19" + "sha256:118c954d7e949b35437270383a3f2531e99dd93cf7ce4dc8340d3356d30f173b", + "sha256:cb633b2bcf10c51af60beb0ab06d2f1d69064b43abf4c185ca6b28865f3f9731" ], "markers": "python_version >= '3.7'", - "version": "==2.5.2" + "version": "==4.0.0" + }, + "pygments": { + "hashes": [ + "sha256:b27c2826c47d0f3219f29554824c30c5e8945175d888647acd804ddd04af846c", + "sha256:da46cec9fd2de5be3a8a784f434e4c4ab670b4ff54d605c4c2717e9d49c4c367" + ], + "markers": "python_version >= '3.7'", + "version": "==2.17.2" }, "pylint": { "hashes": [ - "sha256:2e1a0eb2e8ab41d6b5dbada87f066492bb1557b12b76c47c2ee8aa8a11186594", - "sha256:8b838c8983ee1904b2de66cce9d0b96649a91901350e956d78f289c3bc87b48e" + "sha256:0d4c286ef6d2f66c8bfb527a7f8a629009e42c99707dec821a03e1b51a4c1496", + "sha256:60ed5f3a9ff8b61839ff0348b3624ceeb9e6c2a92c514d81c9cc273da3b6bcda" ], "index": "pypi", - "version": "==2.9.6" + "markers": "python_full_version >= '3.8.0'", + "version": "==3.0.2" }, "pyyaml": { "hashes": [ - "sha256:01b45c0191e6d66c470b6cf1b9531a771a83c1c4208272ead47a3ae4f2f603bf", - "sha256:0283c35a6a9fbf047493e3a0ce8d79ef5030852c51e9d911a27badfde0605293", - "sha256:055d937d65826939cb044fc8c9b08889e8c743fdc6a32b33e2390f66013e449b", - "sha256:07751360502caac1c067a8132d150cf3d61339af5691fe9e87803040dbc5db57", - "sha256:0b4624f379dab24d3725ffde76559cff63d9ec94e1736b556dacdfebe5ab6d4b", - "sha256:0ce82d761c532fe4ec3f87fc45688bdd3a4c1dc5e0b4a19814b9009a29baefd4", - "sha256:1e4747bc279b4f613a09eb64bba2ba602d8a6664c6ce6396a4d0cd413a50ce07", - "sha256:213c60cd50106436cc818accf5baa1aba61c0189ff610f64f4a3e8c6726218ba", - "sha256:231710d57adfd809ef5d34183b8ed1eeae3f76459c18fb4a0b373ad56bedcdd9", - "sha256:277a0ef2981ca40581a47093e9e2d13b3f1fbbeffae064c1d21bfceba2030287", - "sha256:2cd5df3de48857ed0544b34e2d40e9fac445930039f3cfe4bcc592a1f836d513", - "sha256:40527857252b61eacd1d9af500c3337ba8deb8fc298940291486c465c8b46ec0", - "sha256:432557aa2c09802be39460360ddffd48156e30721f5e8d917f01d31694216782", - "sha256:473f9edb243cb1935ab5a084eb238d842fb8f404ed2193a915d1784b5a6b5fc0", - "sha256:48c346915c114f5fdb3ead70312bd042a953a8ce5c7106d5bfb1a5254e47da92", - "sha256:50602afada6d6cbfad699b0c7bb50d5ccffa7e46a3d738092afddc1f9758427f", - "sha256:68fb519c14306fec9720a2a5b45bc9f0c8d1b9c72adf45c37baedfcd949c35a2", - "sha256:77f396e6ef4c73fdc33a9157446466f1cff553d979bd00ecb64385760c6babdc", - "sha256:81957921f441d50af23654aa6c5e5eaf9b06aba7f0a19c18a538dc7ef291c5a1", - "sha256:819b3830a1543db06c4d4b865e70ded25be52a2e0631ccd2f6a47a2822f2fd7c", - "sha256:897b80890765f037df3403d22bab41627ca8811ae55e9a722fd0392850ec4d86", - "sha256:98c4d36e99714e55cfbaaee6dd5badbc9a1ec339ebfc3b1f52e293aee6bb71a4", - "sha256:9df7ed3b3d2e0ecfe09e14741b857df43adb5a3ddadc919a2d94fbdf78fea53c", - "sha256:9fa600030013c4de8165339db93d182b9431076eb98eb40ee068700c9c813e34", - "sha256:a80a78046a72361de73f8f395f1f1e49f956c6be882eed58505a15f3e430962b", - "sha256:afa17f5bc4d1b10afd4466fd3a44dc0e245382deca5b3c353d8b757f9e3ecb8d", - "sha256:b3d267842bf12586ba6c734f89d1f5b871df0273157918b0ccefa29deb05c21c", - "sha256:b5b9eccad747aabaaffbc6064800670f0c297e52c12754eb1d976c57e4f74dcb", - "sha256:bfaef573a63ba8923503d27530362590ff4f576c626d86a9fed95822a8255fd7", - "sha256:c5687b8d43cf58545ade1fe3e055f70eac7a5a1a0bf42824308d868289a95737", - "sha256:cba8c411ef271aa037d7357a2bc8f9ee8b58b9965831d9e51baf703280dc73d3", - "sha256:d15a181d1ecd0d4270dc32edb46f7cb7733c7c508857278d3d378d14d606db2d", - "sha256:d4b0ba9512519522b118090257be113b9468d804b19d63c71dbcf4a48fa32358", - "sha256:d4db7c7aef085872ef65a8fd7d6d09a14ae91f691dec3e87ee5ee0539d516f53", - "sha256:d4eccecf9adf6fbcc6861a38015c2a64f38b9d94838ac1810a9023a0609e1b78", - "sha256:d67d839ede4ed1b28a4e8909735fc992a923cdb84e618544973d7dfc71540803", - "sha256:daf496c58a8c52083df09b80c860005194014c3698698d1a57cbcfa182142a3a", - "sha256:dbad0e9d368bb989f4515da330b88a057617d16b6a8245084f1b05400f24609f", - "sha256:e61ceaab6f49fb8bdfaa0f92c4b57bcfbea54c09277b1b4f7ac376bfb7a7c174", - "sha256:f84fbc98b019fef2ee9a1cb3ce93e3187a6df0b2538a651bfb890254ba9f90b5" + "sha256:04ac92ad1925b2cff1db0cfebffb6ffc43457495c9b3c39d3fcae417d7125dc5", + "sha256:062582fca9fabdd2c8b54a3ef1c978d786e0f6b3a1510e0ac93ef59e0ddae2bc", + "sha256:0d3304d8c0adc42be59c5f8a4d9e3d7379e6955ad754aa9d6ab7a398b59dd1df", + "sha256:1635fd110e8d85d55237ab316b5b011de701ea0f29d07611174a1b42f1444741", + "sha256:184c5108a2aca3c5b3d3bf9395d50893a7ab82a38004c8f61c258d4428e80206", + "sha256:18aeb1bf9a78867dc38b259769503436b7c72f7a1f1f4c93ff9a17de54319b27", + "sha256:1d4c7e777c441b20e32f52bd377e0c409713e8bb1386e1099c2415f26e479595", + "sha256:1e2722cc9fbb45d9b87631ac70924c11d3a401b2d7f410cc0e3bbf249f2dca62", + "sha256:1fe35611261b29bd1de0070f0b2f47cb6ff71fa6595c077e42bd0c419fa27b98", + "sha256:28c119d996beec18c05208a8bd78cbe4007878c6dd15091efb73a30e90539696", + "sha256:326c013efe8048858a6d312ddd31d56e468118ad4cdeda36c719bf5bb6192290", + "sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9", + "sha256:42f8152b8dbc4fe7d96729ec2b99c7097d656dc1213a3229ca5383f973a5ed6d", + "sha256:49a183be227561de579b4a36efbb21b3eab9651dd81b1858589f796549873dd6", + "sha256:4fb147e7a67ef577a588a0e2c17b6db51dda102c71de36f8549b6816a96e1867", + "sha256:50550eb667afee136e9a77d6dc71ae76a44df8b3e51e41b77f6de2932bfe0f47", + "sha256:510c9deebc5c0225e8c96813043e62b680ba2f9c50a08d3724c7f28a747d1486", + "sha256:5773183b6446b2c99bb77e77595dd486303b4faab2b086e7b17bc6bef28865f6", + "sha256:596106435fa6ad000c2991a98fa58eeb8656ef2325d7e158344fb33864ed87e3", + "sha256:6965a7bc3cf88e5a1c3bd2e0b5c22f8d677dc88a455344035f03399034eb3007", + "sha256:69b023b2b4daa7548bcfbd4aa3da05b3a74b772db9e23b982788168117739938", + "sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0", + "sha256:704219a11b772aea0d8ecd7058d0082713c3562b4e271b849ad7dc4a5c90c13c", + "sha256:7e07cbde391ba96ab58e532ff4803f79c4129397514e1413a7dc761ccd755735", + "sha256:81e0b275a9ecc9c0c0c07b4b90ba548307583c125f54d5b6946cfee6360c733d", + "sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28", + "sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4", + "sha256:9046c58c4395dff28dd494285c82ba00b546adfc7ef001486fbf0324bc174fba", + "sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8", + "sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5", + "sha256:afd7e57eddb1a54f0f1a974bc4391af8bcce0b444685d936840f125cf046d5bd", + "sha256:b1275ad35a5d18c62a7220633c913e1b42d44b46ee12554e5fd39c70a243d6a3", + "sha256:b786eecbdf8499b9ca1d697215862083bd6d2a99965554781d0d8d1ad31e13a0", + "sha256:ba336e390cd8e4d1739f42dfe9bb83a3cc2e80f567d8805e11b46f4a943f5515", + "sha256:baa90d3f661d43131ca170712d903e6295d1f7a0f595074f151c0aed377c9b9c", + "sha256:bc1bf2925a1ecd43da378f4db9e4f799775d6367bdb94671027b73b393a7c42c", + "sha256:bd4af7373a854424dabd882decdc5579653d7868b8fb26dc7d0e99f823aa5924", + "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34", + "sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43", + "sha256:c8098ddcc2a85b61647b2590f825f3db38891662cfc2fc776415143f599bb859", + "sha256:d2b04aac4d386b172d5b9692e2d2da8de7bfb6c387fa4f801fbf6fb2e6ba4673", + "sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54", + "sha256:d858aa552c999bc8a8d57426ed01e40bef403cd8ccdd0fc5f6f04a00414cac2a", + "sha256:e7d73685e87afe9f3b36c799222440d6cf362062f78be1013661b00c5c6f678b", + "sha256:f003ed9ad21d6a4713f0a9b5a7a0a79e08dd0f221aff4525a2be4c346ee60aab", + "sha256:f22ac1c3cac4dbc50079e965eba2c1058622631e526bd9afd45fedd49ba781fa", + "sha256:faca3bdcf85b2fc05d06ff3fbc1f83e1391b3e724afa3feba7d13eeab355484c", + "sha256:fca0e3a251908a499833aa292323f32437106001d436eca0e6e7833256674585", + "sha256:fd1592b3fdf65fff2ad0004b5e363300ef59ced41c2e6b3a99d4089fa8c5435d", + "sha256:fd66fc5d0da6d9815ba2cebeb4205f95818ff4b79c3ebe268e75d961704af52f" ], "markers": "python_version >= '3.6'", - "version": "==6.0" + "version": "==6.0.1" }, - "setuptools": { + "rich": { "hashes": [ - "sha256:2e24e0bec025f035a2e72cdd1961119f557d78ad331bb00ff82efb2ab8da8e82", - "sha256:7732871f4f7fa58fb6bdcaeadb0161b2bd046c85905dbaa066bdcbcc81953b57" + "sha256:5cb5123b5cf9ee70584244246816e9114227e0b98ad9176eede6ad54bf5403fa", + "sha256:6da14c108c4866ee9520bbffa71f6fe3962e193b7da68720583850cd4548e235" ], - "markers": "python_version >= '3.7'", - "version": "==65.3.0" + "markers": "python_full_version >= '3.7.0'", + "version": "==13.7.0" }, "smmap": { "hashes": [ - "sha256:2aba19d6a040e78d8b09de5c57e96207b09ed71d8e55ce0959eeee6c8e190d94", - "sha256:c840e62059cd3be204b0c9c9f74be2c09d5648eddd4580d9314c3ecde0b30936" + "sha256:dceeb6c0028fdb6734471eb07c0cd2aae706ccaecab45965ee83f11c8d3b1f62", + "sha256:e6d8668fa5f93e706934a62d7b4db19c8d9eb8cf2adbb75ef1b675aa332b69da" ], - "markers": "python_version >= '3.6'", - "version": "==5.0.0" + "markers": "python_version >= '3.7'", + "version": "==5.0.1" }, "stevedore": { "hashes": [ - "sha256:87e4d27fe96d0d7e4fc24f0cbe3463baae4ec51e81d95fbe60d2474636e0c7d8", - "sha256:f82cc99a1ff552310d19c379827c2c64dd9f85a38bcd5559db2470161867b786" + "sha256:8cc040628f3cea5d7128f2e76cf486b2251a4e543c7b938f58d9a377f6694a2d", + "sha256:a54534acf9b89bc7ed264807013b505bf07f74dbe4bcfa37d32bd063870b087c" ], "markers": "python_version >= '3.8'", - "version": "==4.0.0" - }, - "toml": { - "hashes": [ - "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b", - "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f" - ], - "markers": "python_version >= '2.6' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==0.10.2" + "version": "==5.1.0" }, "tomli": { "hashes": [ @@ -1049,19 +1367,22 @@ "markers": "python_version < '3.11'", "version": "==2.0.1" }, - "typing-extensions": { + "tomlkit": { "hashes": [ - "sha256:6657594ee297170d19f67d55c05852a874e7eb634f4f753dbd667855e07c1708", - "sha256:f1c24655a0da0d1b67f07e17a5e6b2a105894e6824b92096378bb3668ef02376" + "sha256:75baf5012d06501f07bee5bf8e801b9f343e7aac5a92581f20f80ce632e6b5a4", + "sha256:b0a645a9156dc7cb5d3a1f0d4bab66db287fcb8e0430bdd4664a095ea16414ba" ], - "index": "pypi", - "version": "==4.2.0" + "markers": "python_version >= '3.7'", + "version": "==0.12.3" }, - "wrapt": { + "typing-extensions": { "hashes": [ - "sha256:b62ffa81fb85f4332a4f609cab4ac40709470da05643a082ec1eb88e6d9b97d7" + "sha256:8f92fc8806f9a6b641eaa5318da32b44d401efaac0f6678c9bc448ba3605faa0", + "sha256:df8e4339e9cb77357558cbdbceca33c303714cf861d1eef15e1070055ae8b7ef" ], - "version": "==1.12.1" + "index": "pypi", + "markers": "python_version >= '3.8'", + "version": "==4.8.0" } } } diff --git a/README.md b/README.md index 319a9742cf..ea6cb3eae0 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@
- +
diff --git a/app.json b/app.json index eee99b54bf..decd58695c 100644 --- a/app.json +++ b/app.json @@ -11,10 +11,6 @@ "description": "The id for the server you are hosting this bot for.", "required": true }, - "MODMAIL_GUILD_ID": { - "description": "The ID of the discord server where the threads channels should be created (receiving server). Default to GUILD_ID.", - "required": false - }, "OWNERS": { "description": "Comma separated user IDs of people that are allowed to use owner only commands. (eval).", "required": true @@ -40,4 +36,4 @@ "required": false } } -} \ No newline at end of file +} diff --git a/bot.py b/bot.py index b23b2449b2..bb47c75283 100644 --- a/bot.py +++ b/bot.py @@ -1,4 +1,4 @@ -__version__ = "4.0.2" +__version__ = "4.1.0" import asyncio @@ -12,7 +12,7 @@ import sys import platform import typing -from datetime import datetime, timezone +from datetime import datetime, timezone, timedelta from subprocess import PIPE from types import SimpleNamespace @@ -21,8 +21,8 @@ from aiohttp import ClientSession, ClientResponseError from discord.ext import commands, tasks from discord.ext.commands.view import StringView -from emoji import UNICODE_EMOJI -from pkg_resources import parse_version +from emoji import is_emoji +from packaging.version import Version try: @@ -48,11 +48,10 @@ ) from core.thread import ThreadManager from core.time import human_timedelta -from core.utils import extract_block_timestamp, normalize_alias, parse_alias, truncate, tryint +from core.utils import extract_block_timestamp, normalize_alias, parse_alias, truncate, tryint, human_join logger = getLogger(__name__) - temp_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)), "temp") if not os.path.exists(temp_dir): os.mkdir(temp_dir) @@ -84,18 +83,25 @@ def __init__(self): self.threads = ThreadManager(self) - self.log_file_name = os.path.join(temp_dir, f"{self.token.split('.')[0]}.log") - self._configure_logging() + log_dir = os.path.join(temp_dir, "logs") + if not os.path.exists(log_dir): + os.mkdir(log_dir) + self.log_file_path = os.path.join(log_dir, "modmail.log") + configure_logging(self) self.plugin_db = PluginDatabaseClient(self) # Deprecated self.startup() - def get_guild_icon(self, guild: typing.Optional[discord.Guild]) -> str: + def get_guild_icon( + self, guild: typing.Optional[discord.Guild], *, size: typing.Optional[int] = None + ) -> str: if guild is None: guild = self.guild if guild.icon is None: return "https://cdn.discordapp.com/embed/avatars/0.png" - return guild.icon.url + if size is None: + return guild.icon.url + return guild.icon.with_size(size).url def _resolve_snippet(self, name: str) -> typing.Optional[str]: """ @@ -178,32 +184,9 @@ async def load_extensions(self): logger.exception("Failed to load %s.", cog) logger.line("debug") - def _configure_logging(self): - level_text = self.config["log_level"].upper() - logging_levels = { - "CRITICAL": logging.CRITICAL, - "ERROR": logging.ERROR, - "WARNING": logging.WARNING, - "INFO": logging.INFO, - "DEBUG": logging.DEBUG, - } - logger.line() - - log_level = logging_levels.get(level_text) - if log_level is None: - log_level = self.config.remove("log_level") - logger.warning("Invalid logging level set: %s.", level_text) - logger.warning("Using default logging level: INFO.") - else: - logger.info("Logging level: %s", level_text) - - logger.info("Log file: %s", self.log_file_name) - configure_logging(self.log_file_name, log_level) - logger.debug("Successfully configured logging.") - @property def version(self): - return parse_version(__version__) + return Version(__version__) @property def api(self) -> ApiClient: @@ -633,17 +616,18 @@ async def on_ready(self): self.post_metadata.start() self.autoupdate.start() + self.log_expiry.start() self._started = True async def convert_emoji(self, name: str) -> str: ctx = SimpleNamespace(bot=self, guild=self.modmail_guild) converter = commands.EmojiConverter() - if name not in UNICODE_EMOJI["en"]: + if not is_emoji(name): try: name = await converter.convert(ctx, name.strip(":")) except commands.BadArgument as e: - logger.warning("%s is not a valid emoji. %s.", name, e) + logger.warning("%s is not a valid emoji: %s", name, e) raise return name @@ -657,7 +641,6 @@ async def get_or_fetch_user(self, id: int) -> discord.User: return self.get_user(id) or await self.fetch_user(id) async def retrieve_emoji(self) -> typing.Tuple[str, str]: - sent_emoji = self.config["sent_emoji"] blocked_emoji = self.config["blocked_emoji"] @@ -731,7 +714,6 @@ def check_manual_blocked_roles(self, author: discord.Member) -> bool: if isinstance(author, discord.Member): for r in author.roles: if str(r.id) in self.blocked_roles: - blocked_reason = self.blocked_roles.get(str(r.id)) or "" try: @@ -790,7 +772,6 @@ async def is_blocked( channel: discord.TextChannel = None, send_message: bool = False, ) -> bool: - member = self.guild.get_member(author.id) if member is None: # try to find in other guilds @@ -888,7 +869,7 @@ async def process_dm_modmail(self, message: discord.Message) -> None: return sent_emoji, blocked_emoji = await self.retrieve_emoji() - if message.type != discord.MessageType.default: + if message.type not in [discord.MessageType.default, discord.MessageType.reply]: return thread = await self.threads.find(recipient=message.author) @@ -912,7 +893,7 @@ async def process_dm_modmail(self, message: discord.Message) -> None: ) embed.set_footer( text=self.config["disabled_new_thread_footer"], - icon_url=self.get_guild_icon(guild=message.guild), + icon_url=self.get_guild_icon(guild=message.guild, size=128), ) logger.info("A new thread was blocked from %s due to disabled Modmail.", message.author) await self.add_reaction(message, blocked_emoji) @@ -928,7 +909,7 @@ async def process_dm_modmail(self, message: discord.Message) -> None: ) embed.set_footer( text=self.config["disabled_current_thread_footer"], - icon_url=self.get_guild_icon(guild=message.guild), + icon_url=self.get_guild_icon(guild=message.guild, size=128), ) logger.info("A message was blocked from %s due to disabled Modmail.", message.author) await self.add_reaction(message, blocked_emoji) @@ -1239,25 +1220,36 @@ async def handle_reaction_events(self, payload): return channel = self.get_channel(payload.channel_id) - if not channel: # dm channel not in internal cache - _thread = await self.threads.find(recipient=user) - if not _thread: + thread = None + # dm channel not in internal cache + if not channel: + thread = await self.threads.find(recipient=user) + if not thread: return - channel = await _thread.recipient.create_dm() + channel = await thread.recipient.create_dm() + if channel.id != payload.channel_id: + return + + from_dm = isinstance(channel, discord.DMChannel) + from_txt = isinstance(channel, discord.TextChannel) + if not from_dm and not from_txt: + return + if not thread: + params = {"recipient": user} if from_dm else {"channel": channel} + thread = await self.threads.find(**params) + if not thread: + return + + # thread must exist before doing this API call try: message = await channel.fetch_message(payload.message_id) except (discord.NotFound, discord.Forbidden): return reaction = payload.emoji - close_emoji = await self.convert_emoji(self.config["close_emoji"]) - - if isinstance(channel, discord.DMChannel): - thread = await self.threads.find(recipient=user) - if not thread: - return + if from_dm: if ( payload.event_type == "REACTION_ADD" and message.embeds @@ -1265,7 +1257,7 @@ async def handle_reaction_events(self, payload): and self.config.get("recipient_thread_close") ): ts = message.embeds[0].timestamp - if thread and ts == thread.channel.created_at: + if ts == thread.channel.created_at: # the reacted message is the corresponding thread creation embed # closing thread return await thread.close(closer=user) @@ -1285,11 +1277,10 @@ async def handle_reaction_events(self, payload): logger.warning("Failed to find linked message for reactions: %s", e) return else: - thread = await self.threads.find(channel=channel) - if not thread: - return try: - _, *linked_messages = await thread.find_linked_messages(message.id, either_direction=True) + _, *linked_messages = await thread.find_linked_messages( + message1=message, either_direction=True + ) except ValueError as e: logger.warning("Failed to find linked message for reactions: %s", e) return @@ -1335,7 +1326,7 @@ async def handle_react_to_contact(self, payload): ) embed.set_footer( text=self.config["disabled_new_thread_footer"], - icon_url=self.get_guild_icon(guild=channel.guild), + icon_url=self.get_guild_icon(guild=channel.guild, size=128), ) logger.info( "A new thread using react to contact was blocked from %s due to disabled Modmail.", @@ -1397,28 +1388,44 @@ async def on_guild_channel_delete(self, channel): await thread.close(closer=mod, silent=True, delete_channel=False) async def on_member_remove(self, member): - if member.guild != self.guild: - return thread = await self.threads.find(recipient=member) if thread: - if self.config["close_on_leave"]: + if member.guild == self.guild and self.config["close_on_leave"]: await thread.close( closer=member.guild.me, message=self.config["close_on_leave_reason"], silent=True, ) else: - embed = discord.Embed( - description=self.config["close_on_leave_reason"], color=self.error_color - ) + if len(self.guilds) > 1: + guild_left = member.guild + remaining_guilds = member.mutual_guilds + + if remaining_guilds: + remaining_guild_names = [guild.name for guild in remaining_guilds] + leave_message = ( + f"The recipient has left {guild_left}. " + f"They are still in {human_join(remaining_guild_names, final='and')}." + ) + else: + leave_message = ( + f"The recipient has left {guild_left}. We no longer share any mutual servers." + ) + else: + leave_message = "The recipient has left the server." + + embed = discord.Embed(description=leave_message, color=self.error_color) await thread.channel.send(embed=embed) async def on_member_join(self, member): - if member.guild != self.guild: - return thread = await self.threads.find(recipient=member) if thread: - embed = discord.Embed(description="The recipient has joined the server.", color=self.mod_color) + if len(self.guilds) > 1: + guild_joined = member.guild + join_message = f"The recipient has joined {guild_joined}." + else: + join_message = "The recipient has joined the server." + embed = discord.Embed(description=join_message, color=self.mod_color) await thread.channel.send(embed=embed) async def on_message_delete(self, message): @@ -1595,7 +1602,7 @@ async def autoupdate(self): changelog = await Changelog.from_url(self) latest = changelog.latest_version - if self.version < parse_version(latest.version): + if self.version < Version(latest.version): error = None data = {} try: @@ -1714,6 +1721,20 @@ async def before_autoupdate(self): self.autoupdate.cancel() return + @tasks.loop(hours=1, reconnect=False) + async def log_expiry(self): + log_expire_after = self.config.get("log_expiration") + if log_expire_after == isodate.Duration(): + return self.log_expiry.stop() + + now = discord.utils.utcnow() + expiration_datetime = now - log_expire_after + # WARNING: comparison is done lexicographically, not by date. + # This is fine as long as the date is in zero-padded ISO format, which it should be. + expired_logs = await self.db.logs.delete_many({"closed_at": {"$lte": str(expiration_datetime)}}) + + logger.info(f"Deleted {expired_logs.deleted_count} expired logs.") + def format_channel_name(self, author, exclude_channel=None, force_null=False): """Sanitises a username for use with text channel names @@ -1741,9 +1762,10 @@ def format_channel_name(self, author, exclude_channel=None, force_null=False): if force_null: name = "null" - name = new_name = ( - "".join(l for l in name if l not in string.punctuation and l.isprintable()) or "null" - ) + f"-{author.discriminator}" + name = "".join(l for l in name if l not in string.punctuation and l.isprintable()) or "null" + if author.discriminator != "0": + name += f"-{author.discriminator}" + new_name = name counter = 1 existed = set(c.name for c in guild.text_channels if c != exclude_channel) @@ -1788,7 +1810,7 @@ def main(): sys.exit(0) # check discord version - discord_version = "2.0.1" + discord_version = "2.3.2" if discord.__version__ != discord_version: logger.error( "Dependencies are not updated, run pipenv install. discord.py version expected %s, received %s", @@ -1797,16 +1819,6 @@ def main(): ) sys.exit(0) - # Set up discord.py internal logging - if os.environ.get("LOG_DISCORD"): - logger.debug(f"Discord logging enabled: {os.environ['LOG_DISCORD'].upper()}") - d_logger = logging.getLogger("discord") - - d_logger.setLevel(os.environ["LOG_DISCORD"].upper()) - handler = logging.FileHandler(filename="discord.log", encoding="utf-8", mode="w") - handler.setFormatter(logging.Formatter("%(asctime)s:%(levelname)s:%(name)s: %(message)s")) - d_logger.addHandler(handler) - bot = ModmailBot() bot.run() diff --git a/cogs/modmail.py b/cogs/modmail.py index d620520487..ee27806177 100644 --- a/cogs/modmail.py +++ b/cogs/modmail.py @@ -3,7 +3,6 @@ from datetime import datetime, timezone from itertools import zip_longest from typing import Optional, Union, List, Tuple, Literal -from types import SimpleNamespace import discord from discord.ext import commands @@ -160,7 +159,7 @@ async def snippet(self, ctx, *, name: str.lower = None): color=self.bot.error_color, description="You dont have any snippets at the moment." ) embed.set_footer(text=f'Check "{self.bot.prefix}help snippet add" to add a snippet.') - embed.set_author(name="Snippets", icon_url=self.bot.get_guild_icon(guild=ctx.guild)) + embed.set_author(name="Snippets", icon_url=self.bot.get_guild_icon(guild=ctx.guild, size=128)) return await ctx.send(embed=embed) embeds = [] @@ -168,7 +167,7 @@ async def snippet(self, ctx, *, name: str.lower = None): for i, names in enumerate(zip_longest(*(iter(sorted(self.bot.snippets)),) * 15)): description = format_description(i, names) embed = discord.Embed(color=self.bot.main_color, description=description) - embed.set_author(name="Snippets", icon_url=self.bot.get_guild_icon(guild=ctx.guild)) + embed.set_author(name="Snippets", icon_url=self.bot.get_guild_icon(guild=ctx.guild, size=128)) embeds.append(embed) session = EmbedPaginatorSession(ctx, *embeds) @@ -444,11 +443,9 @@ async def move(self, ctx, *, arguments): async def send_scheduled_close_message(self, ctx, after, silent=False): human_delta = human_timedelta(after.dt) - silent = "*silently* " if silent else "" - embed = discord.Embed( title="Scheduled close", - description=f"This thread will close {silent}{human_delta}.", + description=f"This thread will{' silently' if silent else ''} close in {human_delta}.", color=self.bot.error_color, ) @@ -483,7 +480,7 @@ async def close( Silently close a thread (no message) - `{prefix}close silently` - - `{prefix}close in 10m silently` + - `{prefix}close silently in 10m` Stop a thread from closing: - `{prefix}close cancel` @@ -732,8 +729,9 @@ def format_log_embeds(self, logs, avatar_url): f"{self.bot.config['log_url'].strip('/')}{'/' + prefix if prefix else ''}/{entry['key']}" ) - username = entry["recipient"]["name"] + "#" - username += entry["recipient"]["discriminator"] + username = entry["recipient"]["name"] + if entry["recipient"]["discriminator"] != "0": + username += "#" + entry["recipient"]["discriminator"] embed = discord.Embed(color=self.bot.main_color, timestamp=created_at) embed.set_author(name=f"{title} - {username}", icon_url=avatar_url, url=log_url) @@ -1031,7 +1029,7 @@ async def anonadduser(self, ctx, *users_arg: Union[discord.Member, discord.Role, name = tag avatar_url = self.bot.config["anon_avatar_url"] if avatar_url is None: - avatar_url = self.bot.get_guild_icon(guild=ctx.guild) + avatar_url = self.bot.get_guild_icon(guild=ctx.guild, size=128) em.set_footer(text=name, icon_url=avatar_url) for u in users: @@ -1120,7 +1118,7 @@ async def anonremoveuser(self, ctx, *users_arg: Union[discord.Member, discord.Ro name = tag avatar_url = self.bot.config["anon_avatar_url"] if avatar_url is None: - avatar_url = self.bot.get_guild_icon(guild=ctx.guild) + avatar_url = self.bot.get_guild_icon(guild=ctx.guild, size=128) em.set_footer(text=name, icon_url=avatar_url) for u in users: @@ -1166,7 +1164,7 @@ async def logs(self, ctx, *, user: User = None): if not user: thread = ctx.thread if not thread: - raise commands.MissingRequiredArgument(SimpleNamespace(name="member")) + raise commands.MissingRequiredArgument(DummyParam("user")) user = thread.recipient or await self.bot.get_or_fetch_user(thread.id) default_avatar = "https://cdn.discordapp.com/embed/avatars/0.png" @@ -1212,6 +1210,28 @@ async def logs_closed_by(self, ctx, *, user: User = None): session = EmbedPaginatorSession(ctx, *embeds) await session.run() + @logs.command(name="key", aliases=["id"]) + @checks.has_permissions(PermissionLevel.SUPPORTER) + async def logs_key(self, ctx, key: str): + """ + Get the log link for the specified log key. + """ + icon_url = ctx.author.avatar.url + + logs = await self.bot.api.find_log_entry(key) + + if not logs: + embed = discord.Embed( + color=self.bot.error_color, + description=f"Log entry `{key}` not found.", + ) + return await ctx.send(embed=embed) + + embeds = self.format_log_embeds(logs, avatar_url=icon_url) + + session = EmbedPaginatorSession(ctx, *embeds) + await session.run() + @logs.command(name="delete", aliases=["wipe"]) @checks.has_permissions(PermissionLevel.OWNER) async def logs_delete(self, ctx, key_or_link: str): @@ -1665,13 +1685,7 @@ async def blocked(self, ctx): self.bot.blocked_users.pop(str(id_)) logger.debug("No longer blocked, user %s.", id_) continue - - try: - user = await self.bot.get_or_fetch_user(int(id_)) - except discord.NotFound: - users.append((id_, reason)) - else: - users.append((user.mention, reason)) + users.append((f"<@{id_}>", reason)) blocked_roles = list(self.bot.blocked_roles.items()) for id_, reason in blocked_roles: @@ -1825,7 +1839,7 @@ async def block( if thread: user_or_role = thread.recipient elif after is None: - raise commands.MissingRequiredArgument(SimpleNamespace(name="user or role")) + raise commands.MissingRequiredArgument(DummyParam("user or role")) else: raise commands.BadArgument(f'User or role "{after.arg}" not found.') @@ -1842,7 +1856,7 @@ async def block( ) return await ctx.send(embed=embed) - reason = f"by {escape_markdown(ctx.author.name)}#{ctx.author.discriminator}" + reason = f"by {escape_markdown(str(ctx.author))}" if after is not None: if "%" in reason: @@ -1905,7 +1919,7 @@ async def unblock(self, ctx, *, user_or_role: Union[User, Role] = None): if thread: user_or_role = thread.recipient else: - raise commands.MissingRequiredArgument(SimpleNamespace(name="user")) + raise commands.MissingRequiredArgument(DummyParam("user or role")) mention = getattr(user_or_role, "mention", f"`{user_or_role.id}`") name = getattr(user_or_role, "name", f"`{user_or_role.id}`") @@ -2041,11 +2055,12 @@ async def repair(self, ctx): # match username from channel name # username-1234, username-1234_1, username-1234_2 - m = re.match(r"^(.+)-(\d{4})(?:_\d+)?$", ctx.channel.name) + m = re.match(r"^(.+?)(?:-(\d{4}))?(?:_\d+)?$", ctx.channel.name) if m is not None: users = set( filter( - lambda member: member.name == m.group(1) and member.discriminator == m.group(2), + lambda member: member.name == m.group(1) + and (member.discriminator == "0" or member.discriminator == m.group(2)), ctx.guild.members, ) ) @@ -2138,7 +2153,7 @@ async def disable_new(self, ctx): description="Modmail will not create any new threads.", color=self.bot.main_color, ) - if self.bot.config["dm_disabled"] < DMDisabled.NEW_THREADS: + if self.bot.config["dm_disabled"] != DMDisabled.NEW_THREADS: self.bot.config["dm_disabled"] = DMDisabled.NEW_THREADS await self.bot.config.update() diff --git a/cogs/plugins.py b/cogs/plugins.py index 4fb8341c70..fc6e09f05d 100644 --- a/cogs/plugins.py +++ b/cogs/plugins.py @@ -16,7 +16,7 @@ import discord from discord.ext import commands -from pkg_resources import parse_version +from packaging.version import Version from core import checks from core.models import PermissionLevel, getLogger @@ -264,8 +264,18 @@ async def load_plugin(self, plugin): logger.error("Plugin load failure: %s", plugin.ext_string, exc_info=True) raise InvalidPluginError("Cannot load extension, plugin invalid.") from exc - async def parse_user_input(self, ctx, plugin_name, check_version=False): + async def unload_plugin(self, plugin: Plugin) -> None: + try: + await self.bot.unload_extension(plugin.ext_string) + except commands.ExtensionError as exc: + raise exc + + ext_parent = ".".join(plugin.ext_string.split(".")[:-1]) + for module in list(sys.modules.keys()): + if module == ext_parent or module.startswith(ext_parent + "."): + del sys.modules[module] + async def parse_user_input(self, ctx, plugin_name, check_version=False): if not self.bot.config["enable_plugins"]: embed = discord.Embed( description="Plugins are disabled, enable them by setting `ENABLE_PLUGINS=true`", @@ -290,7 +300,7 @@ async def parse_user_input(self, ctx, plugin_name, check_version=False): if check_version: required_version = details.get("bot_version", False) - if required_version and self.bot.version < parse_version(required_version): + if required_version and self.bot.version < Version(required_version): embed = discord.Embed( description="Your bot's version is too low. " f"This plugin requires version `{required_version}`.", @@ -305,7 +315,7 @@ async def parse_user_input(self, ctx, plugin_name, check_version=False): if self.bot.config.get("registry_plugins_only"): embed = discord.Embed( description="This plugin is not in the registry. To install this plugin, " - "you must set `REGISTRY_PLUGINS_ONLY=no` or remove this key in your .env file.", + "you must set `REGISTRY_PLUGINS_ONLY=no` or remove this key in your .env file.", color=self.bot.error_color, ) await ctx.send(embed=embed) @@ -378,7 +388,7 @@ async def plugins_add(self, ctx, *, plugin_name: str): logger.warning("Unable to download plugin %s.", plugin, exc_info=True) embed = discord.Embed( - description=f"Failed to download plugin, check logs for error.\n{type(e)}: {e}", + description=f"Failed to download plugin, check logs for error.\n{type(e).__name__}: {e}", color=self.bot.error_color, ) @@ -388,7 +398,6 @@ async def plugins_add(self, ctx, *, plugin_name: str): await self.bot.config.update() if self.bot.config.get("enable_plugins"): - invalidate_caches() try: @@ -397,7 +406,7 @@ async def plugins_add(self, ctx, *, plugin_name: str): logger.warning("Unable to load plugin %s.", plugin, exc_info=True) embed = discord.Embed( - description=f"Failed to download plugin, check logs for error.\n{type(e)}: {e}", + description=f"Failed to load plugin, check logs for error.\n{type(e).__name__}: {e}", color=self.bot.error_color, ) @@ -438,7 +447,7 @@ async def plugins_remove(self, ctx, *, plugin_name: str): if self.bot.config.get("enable_plugins"): try: - await self.bot.unload_extension(plugin.ext_string) + await self.unload_plugin(plugin) self.loaded_plugins.remove(plugin) except (commands.ExtensionNotLoaded, KeyError): logger.warning("Plugin was never loaded.") @@ -480,9 +489,10 @@ async def update_plugin(self, ctx, plugin_name): await self.download_plugin(plugin, force=True) if self.bot.config.get("enable_plugins"): try: - await self.bot.unload_extension(plugin.ext_string) + await self.unload_plugin(plugin) except commands.ExtensionError: logger.warning("Plugin unload fail.", exc_info=True) + try: await self.load_plugin(plugin) except Exception: @@ -490,12 +500,12 @@ async def update_plugin(self, ctx, plugin_name): description=f"Failed to update {plugin.name}. This plugin will now be removed from your bot.", color=self.bot.error_color, ) - self.bot.config["plugins"].remove(plugin_name) - logger.debug("Failed to update %s. Removed plugin from config.", plugin_name) + self.bot.config["plugins"].remove(str(plugin)) + logger.debug("Failed to update %s. Removed plugin from config.", plugin) else: - logger.debug("Updated %s.", plugin_name) + logger.debug("Updated %s.", plugin) else: - logger.debug("Updated %s.", plugin_name) + logger.debug("Updated %s.", plugin) return await ctx.send(embed=embed) @plugins.command(name="update") @@ -529,17 +539,20 @@ async def plugins_reset(self, ctx): for ext in list(self.bot.extensions): if not ext.startswith("plugins."): continue + logger.error("Unloading plugin: %s.", ext) try: - logger.error("Unloading plugin: %s.", ext) - await self.bot.unload_extension(ext) - except Exception: - logger.error("Failed to unload plugin: %s.", ext) - else: - if not self.loaded_plugins: - continue plugin = next((p for p in self.loaded_plugins if p.ext_string == ext), None) if plugin: + await self.unload_plugin(plugin) self.loaded_plugins.remove(plugin) + else: + await self.bot.unload_extension(ext) + except Exception: + logger.error("Failed to unload plugin: %s.", ext) + + for module in list(sys.modules.keys()): + if module.startswith("plugins."): + del sys.modules[module] self.bot.config["plugins"].clear() await self.bot.config.update() @@ -675,7 +688,7 @@ async def plugins_registry(self, ctx, *, plugin_name: typing.Union[int, str] = N embed.set_footer(text="This plugin is currently loaded.") else: required_version = details.get("bot_version", False) - if required_version and self.bot.version < parse_version(required_version): + if required_version and self.bot.version < Version(required_version): embed.set_footer( text="Your bot is unable to install this plugin, " f"minimum required version is v{required_version}." diff --git a/cogs/utility.py b/cogs/utility.py index bcc1ea951a..b892ffc01b 100644 --- a/cogs/utility.py +++ b/cogs/utility.py @@ -11,15 +11,15 @@ from json import JSONDecodeError, loads from subprocess import PIPE from textwrap import indent -from types import SimpleNamespace from typing import Union import discord -from aiohttp import ClientResponseError from discord.enums import ActivityType, Status from discord.ext import commands, tasks from discord.ext.commands.view import StringView -from pkg_resources import parse_version + +from aiohttp import ClientResponseError +from packaging.version import Version from core import checks, utils from core.changelog import Changelog @@ -30,7 +30,7 @@ UnseenFormatter, getLogger, ) -from core.utils import trigger_typing, truncate +from core.utils import trigger_typing, truncate, DummyParam from core.paginator import EmbedPaginatorSession, MessagePaginatorSession @@ -142,7 +142,7 @@ async def _get_help_embed(self, topic): perm_level = "NONE" embed = discord.Embed( - title=f"`{self.get_command_signature(topic)}`", + title=f"`{self.get_command_signature(topic).strip()}`", color=self.context.bot.main_color, description=self.process_help_msg(topic.help), ) @@ -342,9 +342,9 @@ async def about(self, ctx): latest = changelog.latest_version if self.bot.version.is_prerelease: - stable = next(filter(lambda v: not parse_version(v.version).is_prerelease, changelog.versions)) + stable = next(filter(lambda v: not Version(v.version).is_prerelease, changelog.versions)) footer = f"You are on the prerelease version • the latest version is v{stable.version}." - elif self.bot.version < parse_version(latest.version): + elif self.bot.version < Version(latest.version): footer = f"A newer version is available v{latest.version}." else: footer = "You are up to date with the latest version." @@ -352,7 +352,7 @@ async def about(self, ctx): embed.add_field( name="Want Modmail in Your Server?", value="Follow the installation guide on [GitHub](https://github.com/modmail-dev/modmail/) " - "and join our [Discord server](https://discord.gg/F34cRU8)!", + "and join our [Discord server](https://discord.gg/cnUpwrnpYb)!", inline=False, ) @@ -401,13 +401,7 @@ async def sponsors(self, ctx): async def debug(self, ctx): """Shows the recent application logs of the bot.""" - log_file_name = self.bot.token.split(".")[0] - - with open( - os.path.join(os.path.dirname(os.path.abspath(__file__)), f"../temp/{log_file_name}.log"), - "r+", - encoding="utf-8", - ) as f: + with open(self.bot.log_file_path, "r+", encoding="utf-8") as f: logs = f.read().strip() if not logs: @@ -416,7 +410,7 @@ async def debug(self, ctx): title="Debug Logs:", description="You don't have any logs at the moment.", ) - embed.set_footer(text="Go to Heroku to see your logs.") + embed.set_footer(text="Go to your console to see your logs.") return await ctx.send(embed=embed) messages = [] @@ -433,7 +427,7 @@ async def debug(self, ctx): msg = "```Haskell\n" msg += line if len(msg) + 3 > 2000: - msg = msg[:1993] + "[...]```" + msg = msg[:1992] + "[...]```" messages.append(msg) msg = "```Haskell\n" @@ -455,12 +449,8 @@ async def debug_hastebin(self, ctx): """Posts application-logs to Hastebin.""" haste_url = os.environ.get("HASTE_URL", "https://hastebin.cc") - log_file_name = self.bot.token.split(".")[0] - with open( - os.path.join(os.path.dirname(os.path.abspath(__file__)), f"../temp/{log_file_name}.log"), - "rb+", - ) as f: + with open(self.bot.log_file_path, "rb+") as f: logs = BytesIO(f.read().strip()) try: @@ -482,7 +472,7 @@ async def debug_hastebin(self, ctx): color=self.bot.main_color, description="Something's wrong. We're unable to upload your logs to hastebin.", ) - embed.set_footer(text="Go to Heroku to see your logs.") + embed.set_footer(text="Go to your console to see your logs.") await ctx.send(embed=embed) @debug.command(name="clear", aliases=["wipe"]) @@ -491,12 +481,7 @@ async def debug_hastebin(self, ctx): async def debug_clear(self, ctx): """Clears the locally cached logs.""" - log_file_name = self.bot.token.split(".")[0] - - with open( - os.path.join(os.path.dirname(os.path.abspath(__file__)), f"../temp/{log_file_name}.log"), - "w", - ): + with open(self.bot.log_file_path, "w"): pass await ctx.send( embed=discord.Embed(color=self.bot.main_color, description="Cached logs are now cleared.") @@ -537,12 +522,12 @@ async def activity(self, ctx, activity_type: str.lower, *, message: str = ""): return await ctx.send(embed=embed) if not message: - raise commands.MissingRequiredArgument(SimpleNamespace(name="message")) + raise commands.MissingRequiredArgument(DummyParam("message")) try: activity_type = ActivityType[activity_type] except KeyError: - raise commands.MissingRequiredArgument(SimpleNamespace(name="activity")) + raise commands.MissingRequiredArgument(DummyParam("activity")) activity, _ = await self.set_presence(activity_type=activity_type, activity_message=message) @@ -587,7 +572,7 @@ async def status(self, ctx, *, status_type: str.lower): try: status = Status[status_type] except KeyError: - raise commands.MissingRequiredArgument(SimpleNamespace(name="status")) + raise commands.MissingRequiredArgument(DummyParam("status")) _, status = await self.set_presence(status=status) @@ -599,7 +584,6 @@ async def status(self, ctx, *, status_type: str.lower): return await ctx.send(embed=embed) async def set_presence(self, *, status=None, activity_type=None, activity_message=None): - if status is None: status = self.bot.config.get("status") @@ -1020,7 +1004,7 @@ async def alias(self, ctx, *, name: str.lower = None): color=self.bot.error_color, description="You dont have any aliases at the moment." ) embed.set_footer(text=f'Do "{self.bot.prefix}help alias" for more commands.') - embed.set_author(name="Aliases", icon_url=self.bot.get_guild_icon(guild=ctx.guild)) + embed.set_author(name="Aliases", icon_url=self.bot.get_guild_icon(guild=ctx.guild, size=128)) return await ctx.send(embed=embed) embeds = [] @@ -1028,7 +1012,9 @@ async def alias(self, ctx, *, name: str.lower = None): for i, names in enumerate(zip_longest(*(iter(sorted(self.bot.aliases)),) * 15)): description = utils.format_description(i, names) embed = discord.Embed(color=self.bot.main_color, description=description) - embed.set_author(name="Command Aliases", icon_url=self.bot.get_guild_icon(guild=ctx.guild)) + embed.set_author( + name="Command Aliases", icon_url=self.bot.get_guild_icon(guild=ctx.guild, size=128) + ) embeds.append(embed) session = EmbedPaginatorSession(ctx, *embeds) @@ -1115,7 +1101,7 @@ async def make_alias(self, name, value, action): await self.bot.config.update() return embed - @alias.command(name="add") + @alias.command(name="add", aliases=["create", "make"]) @checks.has_permissions(PermissionLevel.MODERATOR) async def alias_add(self, ctx, name: str.lower, *, value): """ @@ -1612,7 +1598,8 @@ async def permissions_get( ) embed = discord.Embed(color=self.bot.main_color, description=description) embed.set_author( - name="Permission Overrides", icon_url=self.bot.get_guild_icon(guild=ctx.guild) + name="Permission Overrides", + icon_url=self.bot.get_guild_icon(guild=ctx.guild, size=128), ) embeds.append(embed) @@ -1944,7 +1931,7 @@ async def update(self, ctx, *, flag: str = ""): "(https://github.com/modmail-dev/modmail/blob/master/bot.py#L1)" ) - if self.bot.version >= parse_version(latest.version) and flag.lower() != "force": + if self.bot.version >= Version(latest.version) and flag.lower() != "force": embed = discord.Embed(title="Already up to date", description=desc, color=self.bot.main_color) data = await self.bot.api.get_user_info() diff --git a/core/clients.py b/core/clients.py index f504b7051d..61c39fdd4b 100644 --- a/core/clients.py +++ b/core/clients.py @@ -356,6 +356,9 @@ async def validate_database_connection(self): async def get_user_logs(self, user_id: Union[str, int]) -> list: return NotImplemented + async def find_log_entry(self, key: str) -> list: + return NotImplemented + async def get_latest_user_logs(self, user_id: Union[str, int]): return NotImplemented @@ -529,6 +532,13 @@ async def get_user_logs(self, user_id: Union[str, int]) -> list: return await self.logs.find(query, projection).to_list(None) + async def find_log_entry(self, key: str) -> list: + query = {"key": key} + projection = {"messages": {"$slice": 5}} + logger.debug(f"Retrieving log ID {key}.") + + return await self.logs.find(query, projection).to_list(None) + async def get_latest_user_logs(self, user_id: Union[str, int]): query = {"recipient.id": str(user_id), "guild_id": str(self.bot.guild_id), "open": False} projection = {"messages": {"$slice": 5}} diff --git a/core/config.py b/core/config.py index 9476352573..5c6b0dd09d 100644 --- a/core/config.py +++ b/core/config.py @@ -21,7 +21,6 @@ class ConfigManager: - public_keys = { # activity "twitch_url": "https://www.twitch.tv/discordmodmail/", @@ -37,6 +36,7 @@ class ConfigManager: "account_age": isodate.Duration(), "guild_age": isodate.Duration(), "thread_cooldown": isodate.Duration(), + "log_expiration": isodate.Duration(), "reply_without_command": False, "anon_reply_without_command": False, "plain_reply_without_command": False, @@ -123,7 +123,7 @@ class ConfigManager: # confirm thread creation "confirm_thread_creation": False, "confirm_thread_creation_title": "Confirm thread creation", - "confirm_thread_response": "React to confirm thread creation which will directly contact the moderators", + "confirm_thread_response": "Click the button to confirm thread creation which will directly contact the moderators.", "confirm_thread_creation_accept": "\N{WHITE HEAVY CHECK MARK}", "confirm_thread_creation_deny": "\N{NO ENTRY SIGN}", # regex @@ -178,13 +178,16 @@ class ConfigManager: "disable_updates": False, # Logging "log_level": "INFO", + "stream_log_format": "plain", + "file_log_format": "plain", + "discord_log_level": "INFO", # data collection "data_collection": True, } colors = {"mod_color", "recipient_color", "main_color", "error_color"} - time_deltas = {"account_age", "guild_age", "thread_auto_close", "thread_cooldown"} + time_deltas = {"account_age", "guild_age", "thread_auto_close", "thread_cooldown", "log_expiration"} booleans = { "use_user_id_channel_name", diff --git a/core/config_help.json b/core/config_help.json index e7ebb9590d..d301763fe4 100644 --- a/core/config_help.json +++ b/core/config_help.json @@ -131,7 +131,7 @@ "`{prefix}config set use_nickname_channel_name no`" ], "notes": [ - "This config is suitable for servers in Server Discovery to comply with channel name restrictions.", + "This config is NOT suitable for servers in Server Discovery to comply with channel name restrictions.", "This cannot be applied with `use_timestamp_channel_name`, `use_random_channel_name` or `use_user_id_channel_name`.", "See also: `use_timestamp_channel_name`, `use_user_id_channel_name`, `use_random_channel_name`." ] @@ -373,6 +373,17 @@ "To disable thread cooldown, do `{prefix}config del thread_cooldown`." ] }, + "log_expiration": { + "default": "Never", + "description": "The duration closed threads will be stored within the database before deletion. Logs that have been closed for longer than this duration will be deleted automatically.", + "examples": [ + "`{prefix}config set log_expiration P12DT3H` (stands for 12 days and 3 hours in [ISO-8601 Duration Format](https://en.wikipedia.org/wiki/ISO_8601#Durations))", + "`{prefix}config set log_expiration 3 days and 5 hours` (accepted readable time)" + ], + "notes": [ + "To disable log expiration, do `{prefix}config del log_expiration`." + ] + }, "thread_cancelled": { "default": "\"Cancelled\"", "description": "This is the message to display when a thread times out and creation is cancelled.", @@ -864,7 +875,7 @@ "default": "\"{{moderator.name}} has added you to a Modmail thread.\"", "description": "This is the message embed content sent to the recipient that is just added to a thread.", "examples": [ - "`{prefix}config set private_added_to_group_description Any message sent here will be sent to all otherthread recipients.`" + "`{prefix}config set private_added_to_group_response Any message sent here will be sent to all other thread recipients.`" ], "notes": [ "You may use the `{{moderator}}` variable for access to the [Member](https://discordpy.readthedocs.io/en/latest/api.html#discord.Member) that added the user.", @@ -936,7 +947,7 @@ "default": "\"{{moderator.name}} has removed you from the Modmail thread.\"", "description": "This is the message embed content sent to the recipient that is just removed from a thread.", "examples": [ - "`{prefix}config set private_removed_from_group_description Bye`" + "`{prefix}config set private_removed_from_group_response Bye`" ], "notes": [ "You may use the `{{moderator}}` variable for access to the [Member](https://discordpy.readthedocs.io/en/latest/api.html#discord.Member) that added the user.", @@ -1014,10 +1025,10 @@ ] }, "confirm_thread_response": { - "default": "React to confirm thread creation which will directly contact the moderators", + "default": "Click the button to confirm thread creation which will directly contact the moderators.", "description": "Description for the embed message sent to users to confirm a thread creation", "examples":[ - "`{prefix}config set confirm_thread_response React to confirm`" + "`{prefix}config set confirm_thread_response Click to confirm`" ], "notes": [ "See also: `confirm_thread_creation`, `confirm_thread_creation_title`, `confirm_thread_creation_accept`, `confirm_thread_creation_deny`" @@ -1129,6 +1140,33 @@ "This configuration can only to be set through `.env` file or environment (config) variables." ] }, + "stream_log_format": { + "default": "plain", + "description": "The logging format when through a stream, can be 'plain' or 'json'", + "examples": [ + ], + "notes": [ + "This configuration can only to be set through `.env` file or environment (config) variables." + ] + }, + "file_log_format": { + "default": "plain", + "description": "The logging format when logging to a file, can be 'plain' or 'json'", + "examples": [ + ], + "notes": [ + "This configuration can only to be set through `.env` file or environment (config) variables." + ] + }, + "discord_log_level": { + "default": "INFO", + "description": "The `discord.py` library logging level for logging to stdout.", + "examples": [ + ], + "notes": [ + "This configuration can only to be set through `.env` file or environment (config) variables." + ] + }, "enable_plugins": { "default": "Yes", "description": "Whether plugins should be enabled and loaded into Modmail.", diff --git a/core/models.py b/core/models.py index 2eab1ceebb..611db375f0 100644 --- a/core/models.py +++ b/core/models.py @@ -1,16 +1,20 @@ +import json import logging +import os import re import sys -import os +import _string + from difflib import get_close_matches from enum import IntEnum +from logging import FileHandler, StreamHandler, Handler from logging.handlers import RotatingFileHandler from string import Formatter +from typing import Dict, Optional import discord from discord.ext import commands -import _string try: from colorama import Fore, Style @@ -23,29 +27,6 @@ Fore = Style = type("Dummy", (object,), {"__getattr__": lambda self, item: ""})() -class PermissionLevel(IntEnum): - OWNER = 5 - ADMINISTRATOR = 4 - ADMIN = 4 - MODERATOR = 3 - MOD = 3 - SUPPORTER = 2 - RESPONDER = 2 - REGULAR = 1 - INVALID = -1 - - -class InvalidConfigError(commands.BadArgument): - def __init__(self, msg, *args): - super().__init__(msg, *args) - self.msg = msg - - @property - def embed(self): - # Single reference of Color.red() - return discord.Embed(title="Error", description=self.msg, color=discord.Color.red()) - - class ModmailLogger(logging.Logger): @staticmethod def _debug_(*msgs): @@ -94,18 +75,180 @@ def line(self, level="info"): ) -logging.setLoggerClass(ModmailLogger) -log_level = logging.INFO -loggers = set() +class JsonFormatter(logging.Formatter): + """ + Formatter that outputs JSON strings after parsing the LogRecord. + + Parameters + ---------- + fmt_dict : Optional[Dict[str, str]] + {key: logging format attribute} pairs. Defaults to {"message": "message"}. + time_format: str + time.strftime() format string. Default: "%Y-%m-%dT%H:%M:%S" + msec_format: str + Microsecond formatting. Appended at the end. Default: "%s.%03dZ" + """ + + def __init__( + self, + fmt_dict: Optional[Dict[str, str]] = None, + time_format: str = "%Y-%m-%dT%H:%M:%S", + msec_format: str = "%s.%03dZ", + ): + self.fmt_dict: Dict[str, str] = fmt_dict if fmt_dict is not None else {"message": "message"} + self.default_time_format: str = time_format + self.default_msec_format: str = msec_format + self.datefmt: Optional[str] = None + + def usesTime(self) -> bool: + """ + Overwritten to look for the attribute in the format dict values instead of the fmt string. + """ + return "asctime" in self.fmt_dict.values() + + def formatMessage(self, record) -> Dict[str, str]: + """ + Overwritten to return a dictionary of the relevant LogRecord attributes instead of a string. + KeyError is raised if an unknown attribute is provided in the fmt_dict. + """ + return {fmt_key: record.__dict__[fmt_val] for fmt_key, fmt_val in self.fmt_dict.items()} + + def format(self, record) -> str: + """ + Mostly the same as the parent's class method, the difference being that a dict is manipulated and dumped as JSON + instead of a string. + """ + record.message = record.getMessage() + + if self.usesTime(): + record.asctime = self.formatTime(record, self.datefmt) + + message_dict = self.formatMessage(record) + + if record.exc_info: + # Cache the traceback text to avoid converting it multiple times + # (it's constant anyway) + if not record.exc_text: + record.exc_text = self.formatException(record.exc_info) + + if record.exc_text: + message_dict["exc_info"] = record.exc_text + + if record.stack_info: + message_dict["stack_info"] = self.formatStack(record.stack_info) + + return json.dumps(message_dict, default=str) -ch = logging.StreamHandler(stream=sys.stdout) -ch.setLevel(log_level) -formatter = logging.Formatter( + +class FileFormatter(logging.Formatter): + ansi_escape = re.compile(r"\x1B\[[0-?]*[ -/]*[@-~]") + + def format(self, record): + record.msg = self.ansi_escape.sub("", record.msg) + return super().format(record) + + +log_stream_formatter = logging.Formatter( "%(asctime)s %(name)s[%(lineno)d] - %(levelname)s: %(message)s", datefmt="%m/%d/%y %H:%M:%S" ) -ch.setFormatter(formatter) -ch_debug = None +log_file_formatter = FileFormatter( + "%(asctime)s %(name)s[%(lineno)d] - %(levelname)s: %(message)s", + datefmt="%Y-%m-%d %H:%M:%S", +) + +json_formatter = JsonFormatter( + { + "level": "levelname", + "message": "message", + "loggerName": "name", + "processName": "processName", + "processID": "process", + "threadName": "threadName", + "threadID": "thread", + "timestamp": "asctime", + } +) + + +def create_log_handler( + filename: Optional[str] = None, + *, + rotating: bool = False, + level: int = logging.DEBUG, + mode: str = "a+", + encoding: str = "utf-8", + format: str = "plain", + maxBytes: int = 28000000, + backupCount: int = 1, + **kwargs, +) -> Handler: + """ + Creates a pre-configured log handler. This function is made for consistency's sake with + pre-defined default values for parameters and formatters to pass to handler class. + Additional keyword arguments also can be specified, just in case. + + Plugin developers should not use this and use `models.getLogger` instead. + + Parameters + ---------- + filename : Optional[Path] + Specifies that a `FileHandler` or `RotatingFileHandler` be created, using the specified filename, + rather than a `StreamHandler`. Defaults to `None`. + rotating : bool + Whether the file handler should be the `RotatingFileHandler`. Defaults to `False`. Note, this + argument only compatible if the `filename` is specified, otherwise `ValueError` will be raised. + level : int + The root logger level for the handler. Defaults to `logging.DEBUG`. + mode : str + If filename is specified, open the file in this mode. Defaults to 'a+'. + encoding : str + If this keyword argument is specified along with filename, its value is used when the `FileHandler` is created, + and thus used when opening the output file. Defaults to 'utf-8'. + format : str + The format to output with, can either be 'json' or 'plain'. Will apply to whichever handler is created, + based on other conditional logic. + maxBytes : int + The max file size before the rollover occurs. Defaults to 28000000 (28MB). Rollover occurs whenever the current + log file is nearly `maxBytes` in length; but if either of `maxBytes` or `backupCount` is zero, + rollover never occurs, so you generally want to set `backupCount` to at least 1. + backupCount : int + Max number of backup files. Defaults to 1. If this is set to zero, rollover will never occur. + + Returns + ------- + `StreamHandler` when `filename` is `None`, otherwise `FileHandler` or `RotatingFileHandler` + depending on the `rotating` value. + """ + if filename is None and rotating: + raise ValueError("`filename` must be set to instantiate a `RotatingFileHandler`.") + + if filename is None: + handler = StreamHandler(stream=sys.stdout, **kwargs) + formatter = log_stream_formatter + elif not rotating: + handler = FileHandler(filename, mode=mode, encoding=encoding, **kwargs) + formatter = log_file_formatter + else: + handler = RotatingFileHandler( + filename, mode=mode, encoding=encoding, maxBytes=maxBytes, backupCount=backupCount, **kwargs + ) + formatter = log_file_formatter + + if format == "json": + formatter = json_formatter + + handler.setLevel(level) + handler.setFormatter(formatter) + return handler + + +logging.setLoggerClass(ModmailLogger) +log_level = logging.INFO +loggers = set() + +ch = create_log_handler(level=log_level) +ch_debug: Optional[RotatingFileHandler] = None def getLogger(name=None) -> ModmailLogger: @@ -118,33 +261,82 @@ def getLogger(name=None) -> ModmailLogger: return logger -class FileFormatter(logging.Formatter): - ansi_escape = re.compile(r"\x1B\[[0-?]*[ -/]*[@-~]") +def configure_logging(bot) -> None: + global ch_debug, log_level, ch + + stream_log_format, file_log_format = bot.config["stream_log_format"], bot.config["file_log_format"] + if stream_log_format == "json": + ch.setFormatter(json_formatter) + + logger = getLogger(__name__) + level_text = bot.config["log_level"].upper() + logging_levels = { + "CRITICAL": logging.CRITICAL, + "ERROR": logging.ERROR, + "WARNING": logging.WARNING, + "INFO": logging.INFO, + "DEBUG": logging.DEBUG, + } + logger.line() + + level = logging_levels.get(level_text) + if level is None: + level = bot.config.remove("log_level") + logger.warning("Invalid logging level set: %s.", level_text) + logger.warning("Using default logging level: %s.", level) + level = logging_levels[level] + else: + logger.info("Logging level: %s", level_text) + log_level = level + + logger.info("Log file: %s", bot.log_file_path) + ch_debug = create_log_handler(bot.log_file_path, rotating=True) + + if file_log_format == "json": + ch_debug.setFormatter(json_formatter) - def format(self, record): - record.msg = self.ansi_escape.sub("", record.msg) - return super().format(record) - - -def configure_logging(name, level=None): - global ch_debug, log_level - ch_debug = RotatingFileHandler(name, mode="a+", maxBytes=48000, backupCount=1, encoding="utf-8") + ch.setLevel(log_level) - formatter_debug = FileFormatter( - "%(asctime)s %(name)s[%(lineno)d] - %(levelname)s: %(message)s", - datefmt="%Y-%m-%d %H:%M:%S", - ) - ch_debug.setFormatter(formatter_debug) - ch_debug.setLevel(logging.DEBUG) + logger.info("Stream log format: %s", stream_log_format) + logger.info("File log format: %s", file_log_format) + + for log in loggers: + log.setLevel(log_level) + log.addHandler(ch_debug) + + # Set up discord.py logging + d_level_text = bot.config["discord_log_level"].upper() + d_level = logging_levels.get(d_level_text) + if d_level is None: + d_level = bot.config.remove("discord_log_level") + logger.warning("Invalid discord logging level set: %s.", d_level_text) + logger.warning("Using default discord logging level: %s.", d_level) + d_level = logging_levels[d_level] + d_logger = logging.getLogger("discord") + d_logger.setLevel(d_level) + + non_verbose_log_level = max(d_level, logging.INFO) + stream_handler = create_log_handler(level=non_verbose_log_level) + if non_verbose_log_level != d_level: + logger.info("Discord logging level (stdout): %s.", logging.getLevelName(non_verbose_log_level)) + logger.info("Discord logging level (logfile): %s.", logging.getLevelName(d_level)) + else: + logger.info("Discord logging level: %s.", logging.getLevelName(d_level)) + d_logger.addHandler(stream_handler) + d_logger.addHandler(ch_debug) + + logger.debug("Successfully configured logging.") - if level is not None: - log_level = level - ch.setLevel(log_level) +class InvalidConfigError(commands.BadArgument): + def __init__(self, msg, *args): + super().__init__(msg, *args) + self.msg = msg - for logger in loggers: - logger.setLevel(log_level) - logger.addHandler(ch_debug) + @property + def embed(self): + # Single reference of Color.red() + return discord.Embed(title="Error", description=self.msg, color=discord.Color.red()) class _Default: @@ -202,7 +394,6 @@ async def convert(self, ctx, argument): try: return await super().convert(ctx, argument) except commands.ChannelNotFound: - if guild: categories = {c.name.casefold(): c for c in guild.categories} else: @@ -271,6 +462,18 @@ async def ack(self): return +class PermissionLevel(IntEnum): + OWNER = 5 + ADMINISTRATOR = 4 + ADMIN = 4 + MODERATOR = 3 + MOD = 3 + SUPPORTER = 2 + RESPONDER = 2 + REGULAR = 1 + INVALID = -1 + + class DMDisabled(IntEnum): NONE = 0 NEW_THREADS = 1 diff --git a/core/thread.py b/core/thread.py index 53cdd1d202..646c98a604 100644 --- a/core/thread.py +++ b/core/thread.py @@ -29,6 +29,10 @@ get_top_role, create_thread_channel, get_joint_id, + AcceptButton, + DenyButton, + ConfirmThreadCreationView, + DummyParam, ) logger = getLogger(__name__) @@ -228,7 +232,9 @@ async def send_recipient_genesis_message(): else: footer = self.bot.config["thread_creation_footer"] - embed.set_footer(text=footer, icon_url=self.bot.get_guild_icon(guild=self.bot.modmail_guild)) + embed.set_footer( + text=footer, icon_url=self.bot.get_guild_icon(guild=self.bot.modmail_guild, size=128) + ) embed.title = self.bot.config["thread_creation_title"] if creator is None or creator == recipient: @@ -521,7 +527,7 @@ async def _close(self, closer, silent=False, delete_channel=True, message=None, embed.description = message footer = self.bot.config["thread_close_footer"] - embed.set_footer(text=footer, icon_url=self.bot.get_guild_icon(guild=self.bot.guild)) + embed.set_footer(text=footer, icon_url=self.bot.get_guild_icon(guild=self.bot.guild, size=128)) if not silent: for user in self.recipients: @@ -716,7 +722,6 @@ async def delete_message( async def find_linked_message_from_dm( self, message, either_direction=False, get_thread_channel=False ) -> typing.List[discord.Message]: - joint_id = None if either_direction: joint_id = get_joint_id(message) @@ -795,8 +800,8 @@ async def edit_dm_message(self, message: discord.Message, content: str) -> None: async def note( self, message: discord.Message, persistent=False, thread_creation=False ) -> discord.Message: - if not message.content and not message.attachments: - raise MissingRequiredArgument(SimpleNamespace(name="msg")) + if not message.content and not message.attachments and not message.stickers: + raise MissingRequiredArgument(DummyParam("msg")) msg = await self.send( message, @@ -816,8 +821,8 @@ async def reply( self, message: discord.Message, anonymous: bool = False, plain: bool = False ) -> typing.Tuple[typing.List[discord.Message], discord.Message]: """Returns List[user_dm_msg] and thread_channel_msg""" - if not message.content and not message.attachments: - raise MissingRequiredArgument(SimpleNamespace(name="msg")) + if not message.content and not message.attachments and not message.stickers: + raise MissingRequiredArgument(DummyParam("msg")) if not any(g.get_member(self.id) for g in self.bot.guilds): return await message.channel.send( embed=discord.Embed( @@ -909,7 +914,6 @@ async def send( persistent_note: bool = False, thread_creation: bool = False, ) -> None: - if not note and from_mod: self.bot.loop.create_task(self._restart_close_timer()) # Start or restart thread auto close @@ -957,7 +961,7 @@ async def send( name = tag avatar_url = self.bot.config["anon_avatar_url"] if avatar_url is None: - avatar_url = self.bot.get_guild_icon(guild=self.bot.guild) + avatar_url = self.bot.get_guild_icon(guild=self.bot.guild, size=128) embed.set_author( name=name, icon_url=avatar_url, @@ -1016,8 +1020,14 @@ def lottie_to_png(data): return stream.read() for i in message.stickers: - if i.format in (discord.StickerFormatType.png, discord.StickerFormatType.apng): - images.append((i.url, i.name, True)) + if i.format in ( + discord.StickerFormatType.png, + discord.StickerFormatType.apng, + discord.StickerFormatType.gif, + ): + images.append( + (f"https://media.discordapp.net/stickers/{i.id}.{i.format.file_extension}", i.name, True) + ) elif i.format == discord.StickerFormatType.lottie: # save the json lottie representation try: @@ -1416,30 +1426,19 @@ async def create( destination = recipient else: destination = message.channel + view = ConfirmThreadCreationView() + view.add_item(AcceptButton(self.bot.config["confirm_thread_creation_accept"])) + view.add_item(DenyButton(self.bot.config["confirm_thread_creation_deny"])) confirm = await destination.send( embed=discord.Embed( title=self.bot.config["confirm_thread_creation_title"], description=self.bot.config["confirm_thread_response"], color=self.bot.main_color, - ) + ), + view=view, ) - accept_emoji = self.bot.config["confirm_thread_creation_accept"] - deny_emoji = self.bot.config["confirm_thread_creation_deny"] - emojis = [accept_emoji, deny_emoji] - for emoji in emojis: - await confirm.add_reaction(emoji) - await asyncio.sleep(0.2) - - try: - r, _ = await self.bot.wait_for( - "reaction_add", - check=lambda r, u: u.id == recipient.id - and r.message.id == confirm.id - and r.message.channel.id == confirm.channel.id - and str(r.emoji) in (accept_emoji, deny_emoji), - timeout=20, - ) - except asyncio.TimeoutError: + await view.wait() + if view.value is None: thread.cancelled = True self.bot.loop.create_task( destination.send( @@ -1450,23 +1449,16 @@ async def create( ) ) ) - else: - if str(r.emoji) == deny_emoji: - thread.cancelled = True - self.bot.loop.create_task( - destination.send( - embed=discord.Embed( - title=self.bot.config["thread_cancelled"], color=self.bot.error_color - ) + await confirm.edit(view=None) + if view.value is False: + thread.cancelled = True + self.bot.loop.create_task( + destination.send( + embed=discord.Embed( + title=self.bot.config["thread_cancelled"], color=self.bot.error_color ) ) - - async def remove_reactions(): - for emoji in emojis: - await confirm.remove_reaction(emoji, self.bot.user) - await asyncio.sleep(0.2) - - self.bot.loop.create_task(remove_reactions()) + ) if thread.cancelled: del self.cache[recipient.id] return thread diff --git a/core/utils.py b/core/utils.py index d8046ade5f..9f9f572f5a 100644 --- a/core/utils.py +++ b/core/utils.py @@ -39,6 +39,10 @@ "get_top_role", "get_joint_id", "extract_block_timestamp", + "AcceptButton", + "DenyButton", + "ConfirmThreadCreationView", + "DummyParam", ] @@ -123,7 +127,11 @@ def format_preview(messages: typing.List[typing.Dict[str, typing.Any]]): continue author = message["author"] content = str(message["content"]).replace("\n", " ") - name = author["name"] + "#" + str(author["discriminator"]) + + name = author["name"] + discriminator = str(author["discriminator"]) + if discriminator != "0": + name += "#" + discriminator prefix = "[M]" if author["mod"] else "[R]" out += truncate(f"`{prefix} {name}:` {content}", max=75) + "\n" @@ -144,13 +152,17 @@ def is_image_url(url: str, **kwargs) -> str: bool Whether the URL is a valid image URL. """ - if url.startswith("https://gyazo.com") or url.startswith("http://gyazo.com"): - # gyazo support - url = re.sub( - r"(http[s]?:\/\/)((?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!*(),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+)", - r"\1i.\2.png", - url, - ) + try: + result = parse.urlparse(url) + if result.netloc == "gyazo.com" and result.scheme in ["http", "https"]: + # gyazo support + url = re.sub( + r"(https?://)((?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!*(),]|%[0-9a-fA-F][0-9a-fA-F])+)", + r"\1i.\2.png", + url, + ) + except ValueError: + pass return parse_image_url(url, **kwargs) @@ -559,3 +571,39 @@ def extract_block_timestamp(reason, id_): raise return end_time, after + + +class AcceptButton(discord.ui.Button): + def __init__(self, emoji): + super().__init__(style=discord.ButtonStyle.gray, emoji=emoji) + + async def callback(self, interaction: discord.Interaction): + self.view.value = True + await interaction.response.edit_message(view=None) + self.view.stop() + + +class DenyButton(discord.ui.Button): + def __init__(self, emoji): + super().__init__(style=discord.ButtonStyle.gray, emoji=emoji) + + async def callback(self, interaction: discord.Interaction): + self.view.value = False + await interaction.response.edit_message(view=None) + self.view.stop() + + +class ConfirmThreadCreationView(discord.ui.View): + def __init__(self): + super().__init__(timeout=20) + self.value = None + + +class DummyParam: + """ + A dummy parameter that can be used for MissingRequiredArgument. + """ + + def __init__(self, name): + self.name = name + self.displayed_name = name diff --git a/plugins/registry.json b/plugins/registry.json index fe175ea58a..4079001a50 100644 --- a/plugins/registry.json +++ b/plugins/registry.json @@ -17,6 +17,15 @@ "icon_url": "https://github.com/Jerrie-Aries.png", "thumbnail_url": "https://raw.githubusercontent.com/Jerrie-Aries/modmail-plugins/master/.static/announcement.jpg" }, + "autoreact": { + "repository": "martinbndr/kyb3r-modmail-plugins", + "branch": "master", + "description": "Automatically reacts with emojis in certain channels.", + "bot_version": "4.0.0", + "title": "Autoreact", + "icon_url": "https://raw.githubusercontent.com/martinbndr/kyb3r-modmail-plugins/master/autoreact/logo.png", + "thumbnail_url": "https://raw.githubusercontent.com/martinbndr/kyb3r-modmail-plugins/master/autoreact/logo.png" + }, "giveaway": { "repository": "Jerrie-Aries/modmail-plugins", "branch": "master", @@ -115,5 +124,14 @@ "title": "Top Supporters", "icon_url": "https://i.imgur.com/Mo60CdK.png", "thumbnail_url": "https://i.imgur.com/Mo60CdK.png" + }, + "rename": { + "repository": "Nicklaus-s/modmail-plugins", + "branch": "master", + "description": "Set a thread channel name.", + "bot_version": "4.0.0", + "title": "Rename", + "icon_url": "https://i.imgur.com/A1auJ95.png", + "thumbnail_url": "https://i.imgur.com/A1auJ95.png" } } diff --git a/pyproject.toml b/pyproject.toml index 751cc5a75a..cc43b4a54c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.black] line-length = "110" -target-version = ['py39'] +target-version = ['py310'] include = '\.pyi?$' extend-exclude = ''' ( @@ -21,7 +21,7 @@ extend-exclude = ''' [tool.poetry] name = 'Modmail' -version = '4.0.2' +version = '4.1.0' description = "Modmail is similar to Reddit's Modmail, both in functionality and purpose. It serves as a shared inbox for server staff to communicate with their users in a seamless way." license = 'AGPL-3.0-only' authors = [ diff --git a/requirements.txt b/requirements.txt index 313426315e..2c7bdb7880 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,40 +1,41 @@ -# -# These requirements were autogenerated by pipenv -# To regenerate from the project's Pipfile, run: -# -# pipenv lock --requirements -# - -i https://pypi.org/simple -aiohttp==3.8.1 -aiosignal==1.2.0; python_version >= '3.6' -async-timeout==4.0.2; python_version >= '3.6' -attrs==21.4.0; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4' -cairocffi==1.3.0; python_version >= '3.7' -cairosvg==2.5.2 -cffi==1.15.0 -charset-normalizer==2.0.12; python_version >= '3.5' -colorama==0.4.4 -cssselect2==0.6.0; python_version >= '3.7' +aiodns==3.1.1 +aiohttp==3.9.0; python_version >= '3.8' +aiosignal==1.3.1; python_version >= '3.7' +async-timeout==4.0.3; python_version < '3.11' +attrs==23.1.0; python_version >= '3.7' +brotli==1.1.0 +cairocffi==1.6.1; python_version >= '3.7' +cairosvg==2.7.1; python_version >= '3.5' +certifi==2023.11.17; python_version >= '3.6' +cffi==1.16.0; python_version >= '3.8' +charset-normalizer==3.3.2; python_full_version >= '3.7.0' +colorama==0.4.6; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5, 3.6' +cssselect2==0.7.0; python_version >= '3.7' defusedxml==0.7.1; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4' -dnspython==2.2.1; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3' -emoji==1.7.0 -frozenlist==1.3.0; python_version >= '3.7' -discord.py==2.0.1 -idna==3.3; python_version >= '3.5' +discord.py[speed]==2.3.2; python_full_version >= '3.8.0' +dnspython==2.4.2; python_version >= '3.8' and python_version < '4.0' +emoji==2.8.0; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3' +frozenlist==1.4.0; python_version >= '3.8' +idna==3.4; python_version >= '3.5' isodate==0.6.1 -lottie[pdf]==0.6.11 -motor==2.5.1 -multidict==6.0.2; python_version >= '3.7' +lottie[pdf]==0.7.0; python_version >= '3' +motor==3.3.2; python_version >= '3.7' +multidict==6.0.4; python_version >= '3.7' natural==0.2.0 +orjson==3.9.10 +packaging==23.2; python_version >= '3.7' parsedatetime==2.6 -pillow==9.1.0; python_version >= '3.7' +pillow==10.1.0; python_version >= '3.8' +pycares==4.4.0; python_version >= '3.8' pycparser==2.21 -pymongo==3.12.3 -python-dateutil==2.8.2 -python-dotenv==0.20.0 +pymongo[srv]==4.6.0; python_version >= '3.7' +python-dateutil==2.8.2; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3' +python-dotenv==1.0.0; python_version >= '3.8' +requests==2.31.0; python_version >= '3.7' six==1.16.0; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3' -tinycss2==1.1.1; python_version >= '3.6' -uvloop==0.16.0; sys_platform != 'win32' +tinycss2==1.2.1; python_version >= '3.7' +urllib3==2.1.0; python_version >= '3.8' +uvloop==0.19.0; sys_platform != 'win32' webencodings==0.5.1 -yarl==1.7.2; python_version >= '3.6' +yarl==1.9.3; python_version >= '3.7'