From 386ccd847b446f899cc3d76044d38ca5d2bdce48 Mon Sep 17 00:00:00 2001 From: Tobias Reber Date: Mon, 8 Jan 2024 17:18:47 +0100 Subject: [PATCH 1/5] PB-91: Added script to Makefile to convert svg images to pngs --- Makefile | 3 - Pipfile | 4 +- Pipfile.lock | 706 +++++++++++++++++++++++++-------------------- README.md | 19 ++ app/routes.py | 16 +- scripts/svg2png.py | 160 ++++++++++ 6 files changed, 587 insertions(+), 321 deletions(-) create mode 100644 scripts/svg2png.py diff --git a/Makefile b/Makefile index f60cba7..3153dd3 100644 --- a/Makefile +++ b/Makefile @@ -14,11 +14,9 @@ GIT_DIRTY = `git status --porcelain` GIT_TAG = `git describe --tags || echo "no version info"` AUTHOR = $(USER) - # general targets LOGS_DIR = $(PWD)/logs - # Docker variables DOCKER_REGISTRY = 974517877189.dkr.ecr.eu-central-1.amazonaws.com DOCKER_IMG_LOCAL_TAG := $(DOCKER_REGISTRY)/$(SERVICE_NAME):local-$(USER)-$(GIT_HASH_SHORT) @@ -128,7 +126,6 @@ format-lint: format lint test: ENV_FILE=.env.test $(NOSE) -c tests/unittest.cfg --verbose -s tests/ -# Serve targets. Using these will run the application on your local machine. You can either serve with a wsgi front (like it would be within the container), or without. .PHONY: serve serve: clean_logs $(LOGS_DIR) diff --git a/Pipfile b/Pipfile index 7dbea05..810508e 100644 --- a/Pipfile +++ b/Pipfile @@ -11,12 +11,14 @@ Flask = "~=2.0.1" Pillow = "~=9.0.1" python-dotenv = "~=0.17.0" logging-utilities = "~=3.0" +werkzeug = "~=2.2" [dev-packages] yapf = "*" nose2 = "*" pylint = "*" pylint-flask = "*" +cairosvg = "*" [requires] -python_version = "3.9" \ No newline at end of file +python_version = "3.9" diff --git a/Pipfile.lock b/Pipfile.lock index c1e84dd..2c99006 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "2941cf694ef49903d7e23429d3123a40423a3d14e1e68b61b4b003b7bc06f016" + "sha256": "da0e78733155855f71e19159971e66fcfc8e4eba40d9854881a799ce8f86bb74" }, "pipfile-spec": 6, "requires": { @@ -18,10 +18,11 @@ "default": { "click": { "hashes": [ - "sha256:7682dc8afb30297001674575ea00d1814d808d6a36af415a82bd481d37ba7b8e", - "sha256:bb4d8133cb15a609f44e8213d9b391b0809795062913b383c62be0ee95b1db48" + "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28", + "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de" ], - "version": "==8.1.3" + "markers": "python_version >= '3.7'", + "version": "==8.1.7" }, "flask": { "hashes": [ @@ -67,63 +68,75 @@ }, "greenlet": { "hashes": [ - "sha256:0118817c9341ef2b0f75f5af79ac377e4da6ff637e5ee4ac91802c0e379dadb4", - "sha256:048d2bed76c2aa6de7af500ae0ea51dd2267aec0e0f2a436981159053d0bc7cc", - "sha256:07c58e169bbe1e87b8bbf15a5c1b779a7616df9fd3e61cadc9d691740015b4f8", - "sha256:095a980288fe05adf3d002fbb180c99bdcf0f930e220aa66fcd56e7914a38202", - "sha256:0b181e9aa6cb2f5ec0cacc8cee6e5a3093416c841ba32c185c30c160487f0380", - "sha256:1626185d938d7381631e48e6f7713e8d4b964be246073e1a1d15c2f061ac9f08", - "sha256:184416e481295832350a4bf731ba619a92f5689bf5d0fa4341e98b98b1265bd7", - "sha256:1dd51d2650e70c6c4af37f454737bf4a11e568945b27f74b471e8e2a9fd21268", - "sha256:1ec2779774d8e42ed0440cf8bc55540175187e8e934f2be25199bf4ed948cd9e", - "sha256:2cf45e339cabea16c07586306a31cfcc5a3b5e1626d365714d283732afed6809", - "sha256:2fb0aa7f6996879551fd67461d5d3ab0c3c0245da98be90c89fcb7a18d437403", - "sha256:44b4817c34c9272c65550b788913620f1fdc80362b209bc9d7dd2f40d8793080", - "sha256:466ce0928e33421ee84ae04c4ac6f253a3a3e6b8d600a79bd43fd4403e0a7a76", - "sha256:4f166b4aca8d7d489e82d74627a7069ab34211ef5ebb57c300ec4b9337b60fc0", - "sha256:510c3b15587afce9800198b4b142202b323bf4b4b5f9d6c79cb9a35e5e3c30d2", - "sha256:5b756e6730ea59b2745072e28ad27f4c837084688e6a6b3633c8b1e509e6ae0e", - "sha256:5fbe1ab72b998ca77ceabbae63a9b2e2dc2d963f4299b9b278252ddba142d3f1", - "sha256:6200a11f003ec26815f7e3d2ded01b43a3810be3528dd760d2f1fa777490c3cd", - "sha256:65ad1a7a463a2a6f863661329a944a5802c7129f7ad33583dcc11069c17e622c", - "sha256:694ffa7144fa5cc526c8f4512665003a39fa09ef00d19bbca5c8d3406db72fbe", - "sha256:6f5d4b2280ceea76c55c893827961ed0a6eadd5a584a7c4e6e6dd7bc10dfdd96", - "sha256:7532a46505470be30cbf1dbadb20379fb481244f1ca54207d7df3bf0bbab6a20", - "sha256:76a53bfa10b367ee734b95988bd82a9a5f0038a25030f9f23bbbc005010ca600", - "sha256:77e41db75f9958f2083e03e9dd39da12247b3430c92267df3af77c83d8ff9eed", - "sha256:7a43bbfa9b6cfdfaeefbd91038dde65ea2c421dc387ed171613df340650874f2", - "sha256:7b41d19c0cfe5c259fe6c539fd75051cd39a5d33d05482f885faf43f7f5e7d26", - "sha256:7c5227963409551ae4a6938beb70d56bf1918c554a287d3da6853526212fbe0a", - "sha256:870a48007872d12e95a996fca3c03a64290d3ea2e61076aa35d3b253cf34cd32", - "sha256:88b04e12c9b041a1e0bcb886fec709c488192638a9a7a3677513ac6ba81d8e79", - "sha256:8c287ae7ac921dfde88b1c125bd9590b7ec3c900c2d3db5197f1286e144e712b", - "sha256:903fa5716b8fbb21019268b44f73f3748c41d1a30d71b4a49c84b642c2fed5fa", - "sha256:9537e4baf0db67f382eb29255a03154fcd4984638303ff9baaa738b10371fa57", - "sha256:9951dcbd37850da32b2cb6e391f621c1ee456191c6ae5528af4a34afe357c30e", - "sha256:9b2f7d0408ddeb8ea1fd43d3db79a8cefaccadd2a812f021333b338ed6b10aba", - "sha256:9c88e134d51d5e82315a7c32b914a58751b7353eb5268dbd02eabf020b4c4700", - "sha256:9fae214f6c43cd47f7bef98c56919b9222481e833be2915f6857a1e9e8a15318", - "sha256:a3a669f11289a8995d24fbfc0e63f8289dd03c9aaa0cc8f1eab31d18ca61a382", - "sha256:aa741c1a8a8cc25eb3a3a01a62bdb5095a773d8c6a86470bde7f607a447e7905", - "sha256:b0877a9a2129a2c56a2eae2da016743db7d9d6a05d5e1c198f1b7808c602a30e", - "sha256:bcb6c6dd1d6be6d38d6db283747d07fda089ff8c559a835236560a4410340455", - "sha256:caff52cb5cd7626872d9696aee5b794abe172804beb7db52eed1fd5824b63910", - "sha256:cbc1eb55342cbac8f7ec159088d54e2cfdd5ddf61c87b8bbe682d113789331b2", - "sha256:cd16a89efe3a003029c87ff19e9fba635864e064da646bc749fc1908a4af18f3", - "sha256:ce5b64dfe8d0cca407d88b0ee619d80d4215a2612c1af8c98a92180e7109f4b5", - "sha256:d58a5a71c4c37354f9e0c24c9c8321f0185f6945ef027460b809f4bb474bfe41", - "sha256:db41f3845eb579b544c962864cce2c2a0257fe30f0f1e18e51b1e8cbb4e0ac6d", - "sha256:db5b25265010a1b3dca6a174a443a0ed4c4ab12d5e2883a11c97d6e6d59b12f9", - "sha256:dd0404d154084a371e6d2bafc787201612a1359c2dee688ae334f9118aa0bf47", - "sha256:de431765bd5fe62119e0bc6bc6e7b17ac53017ae1782acf88fcf6b7eae475a49", - "sha256:df02fdec0c533301497acb0bc0f27f479a3a63dcdc3a099ae33a902857f07477", - "sha256:e8533f5111704d75de3139bf0b8136d3a6c1642c55c067866fa0a51c2155ee33", - "sha256:f2f908239b7098799b8845e5936c2ccb91d8c2323be02e82f8dcb4a80dcf4a25", - "sha256:f8bfd36f368efe0ab2a6aa3db7f14598aac454b06849fb633b762ddbede1db90", - "sha256:ffe73f9e7aea404722058405ff24041e59d31ca23d1da0895af48050a07b6932" + "sha256:0120a879aa2b1ac5118bce959ea2492ba18783f65ea15821680a256dfad04754", + "sha256:025b8de2273d2809f027d347aa2541651d2e15d593bbce0d5f502ca438c54136", + "sha256:05ae7383f968bba4211b1fbfc90158f8e3da86804878442b4fb6c16ccbcaa519", + "sha256:0914f02fcaa8f84f13b2df4a81645d9e82de21ed95633765dd5cc4d3af9d7403", + "sha256:0971d37ae0eaf42344e8610d340aa0ad3d06cd2eee381891a10fe771879791f9", + "sha256:0a954002064ee919b444b19c1185e8cce307a1f20600f47d6f4b6d336972c809", + "sha256:0aa1845944e62f358d63fcc911ad3b415f585612946b8edc824825929b40e59e", + "sha256:104f29dd822be678ef6b16bf0035dcd43206a8a48668a6cae4d2fe9c7a7abdeb", + "sha256:11fc7692d95cc7a6a8447bb160d98671ab291e0a8ea90572d582d57361360f05", + "sha256:17a69967561269b691747e7f436d75a4def47e5efcbc3c573180fc828e176d80", + "sha256:2794eef1b04b5ba8948c72cc606aab62ac4b0c538b14806d9c0d88afd0576d6b", + "sha256:2c6e942ca9835c0b97814d14f78da453241837419e0d26f7403058e8db3e38f8", + "sha256:2ccdc818cc106cc238ff7eba0d71b9c77be868fdca31d6c3b1347a54c9b187b2", + "sha256:325f272eb997916b4a3fc1fea7313a8adb760934c2140ce13a2117e1b0a8095d", + "sha256:39464518a2abe9c505a727af7c0b4efff2cf242aa168be5f0daa47649f4d7ca8", + "sha256:3a24f3213579dc8459e485e333330a921f579543a5214dbc935bc0763474ece3", + "sha256:3aeac044c324c1a4027dca0cde550bd83a0c0fbff7ef2c98df9e718a5086c194", + "sha256:3c22998bfef3fcc1b15694818fc9b1b87c6cc8398198b96b6d355a7bcb8c934e", + "sha256:467b73ce5dcd89e381292fb4314aede9b12906c18fab903f995b86034d96d5c8", + "sha256:4a8b58232f5b72973350c2b917ea3df0bebd07c3c82a0a0e34775fc2c1f857e9", + "sha256:4f74aa0092602da2069df0bc6553919a15169d77bcdab52a21f8c5242898f519", + "sha256:5662492df0588a51d5690f6578f3bbbd803e7f8d99a99f3bf6128a401be9c269", + "sha256:5c2d21c2b768d8c86ad935e404cc78c30d53dea009609c3ef3a9d49970c864b5", + "sha256:5edf75e7fcfa9725064ae0d8407c849456553a181ebefedb7606bac19aa1478b", + "sha256:60839ab4ea7de6139a3be35b77e22e0398c270020050458b3d25db4c7c394df5", + "sha256:62723e7eb85fa52e536e516ee2ac91433c7bb60d51099293671815ff49ed1c21", + "sha256:64e10f303ea354500c927da5b59c3802196a07468332d292aef9ddaca08d03dd", + "sha256:66aa4e9a726b70bcbfcc446b7ba89c8cec40f405e51422c39f42dfa206a96a05", + "sha256:695d0d8b5ae42c800f1763c9fce9d7b94ae3b878919379150ee5ba458a460d57", + "sha256:70048d7b2c07c5eadf8393e6398595591df5f59a2f26abc2f81abca09610492f", + "sha256:7afa706510ab079fd6d039cc6e369d4535a48e202d042c32e2097f030a16450f", + "sha256:7cf37343e43404699d58808e51f347f57efd3010cc7cee134cdb9141bd1ad9ea", + "sha256:8149a6865b14c33be7ae760bcdb73548bb01e8e47ae15e013bf7ef9290ca309a", + "sha256:814f26b864ed2230d3a7efe0336f5766ad012f94aad6ba43a7c54ca88dd77cba", + "sha256:82a38d7d2077128a017094aff334e67e26194f46bd709f9dcdacbf3835d47ef5", + "sha256:83a7a6560df073ec9de2b7cb685b199dfd12519bc0020c62db9d1bb522f989fa", + "sha256:8415239c68b2ec9de10a5adf1130ee9cb0ebd3e19573c55ba160ff0ca809e012", + "sha256:88720794390002b0c8fa29e9602b395093a9a766b229a847e8d88349e418b28a", + "sha256:890f633dc8cb307761ec566bc0b4e350a93ddd77dc172839be122be12bae3e10", + "sha256:8926a78192b8b73c936f3e87929931455a6a6c6c385448a07b9f7d1072c19ff3", + "sha256:8c0581077cf2734569f3e500fab09c0ff6a2ab99b1afcacbad09b3c2843ae743", + "sha256:8fda1139d87ce5f7bd80e80e54f9f2c6fe2f47983f1a6f128c47bf310197deb6", + "sha256:91a84faf718e6f8b888ca63d0b2d6d185c8e2a198d2a7322d75c303e7097c8b7", + "sha256:924df1e7e5db27d19b1359dc7d052a917529c95ba5b8b62f4af611176da7c8ad", + "sha256:949c9061b8c6d3e6e439466a9be1e787208dec6246f4ec5fffe9677b4c19fcc3", + "sha256:9649891ab4153f217f319914455ccf0b86986b55fc0573ce803eb998ad7d6854", + "sha256:96656c5f7c95fc02c36d4f6ef32f4e94bb0b6b36e6a002c21c39785a4eec5f5d", + "sha256:a812df7282a8fc717eafd487fccc5ba40ea83bb5b13eb3c90c446d88dbdfd2be", + "sha256:a8d24eb5cb67996fb84633fdc96dbc04f2d8b12bfcb20ab3222d6be271616b67", + "sha256:bef49c07fcb411c942da6ee7d7ea37430f830c482bf6e4b72d92fd506dd3a427", + "sha256:bffba15cff4802ff493d6edcf20d7f94ab1c2aee7cfc1e1c7627c05f1102eee8", + "sha256:c0643250dd0756f4960633f5359884f609a234d4066686754e834073d84e9b51", + "sha256:c6f90234e4438062d6d09f7d667f79edcc7c5e354ba3a145ff98176f974b8132", + "sha256:c8c9301e3274276d3d20ab6335aa7c5d9e5da2009cccb01127bddb5c951f8870", + "sha256:c8ece5d1a99a2adcb38f69af2f07d96fb615415d32820108cd340361f590d128", + "sha256:cb863057bed786f6622982fb8b2c122c68e6e9eddccaa9fa98fd937e45ee6c4f", + "sha256:ccbe7129a282ec5797df0451ca1802f11578be018a32979131065565da89b392", + "sha256:d25cdedd72aa2271b984af54294e9527306966ec18963fd032cc851a725ddc1b", + "sha256:d75afcbb214d429dacdf75e03a1d6d6c5bd1fa9c35e360df8ea5b6270fb2211c", + "sha256:d7815e1519a8361c5ea2a7a5864945906f8e386fa1bc26797b4d443ab11a4589", + "sha256:eb6ac495dccb1520667cfea50d89e26f9ffb49fa28496dea2b95720d8b45eb54", + "sha256:ec615d2912b9ad807afd3be80bf32711c0ff9c2b00aa004a45fd5d5dde7853d9", + "sha256:f5e09dc5c6e1796969fd4b775ea1417d70e49a5df29aaa8e5d10675d9e11872c", + "sha256:f6661b58412879a2aa099abb26d3c93e91dedaba55a6394d1fb1512a77e85de9", + "sha256:f7d20c3267385236b4ce54575cc8e9f43e7673fc761b069c820097092e318e3b", + "sha256:fe7c51f8a2ab616cb34bc33d810c887e89117771028e1e3d3b77ca25ddeace04" ], "markers": "platform_python_implementation == 'CPython'", - "version": "==1.1.3" + "version": "==1.1.3.post0" }, "gunicorn": { "hashes": [ @@ -138,6 +151,7 @@ "sha256:2c2349112351b88699d8d4b6b075022c0808887cb7ad10069318a8b0bc88db44", "sha256:5dbbc68b317e5e42f327f9021763545dc3fc3bfe22e6deb96aaf1fc38874156a" ], + "markers": "python_version >= '3.7'", "version": "==2.1.2" }, "jinja2": { @@ -145,60 +159,82 @@ "sha256:31351a702a408a9e7595a8fc6150fc3f43bb6bf7e319770cbc0db9df9437e852", "sha256:6088930bfe239f0e6710546ab9c19c9ef35e29792895fed6e6e31a023a182a61" ], + "markers": "python_version >= '3.7'", "version": "==3.1.2" }, "logging-utilities": { "hashes": [ - "sha256:41df287a05968e37bdc68d593a9ec77046f75906c56bd8f83e51fb5ed12fb3b3", - "sha256:ecc50c8b4eea8c9ffe856945f3ab619d1d28cbd21078a994264418d0a2db0697" + "sha256:39ca6b4d840a17c81cfbd21540cf57d4a1c134ae307ffa538c6a619565967284", + "sha256:5545d2208b4ffe72ebc50d469297f0b40bd000765bfb6f4a9b6976335e82bc27" ], "index": "pypi", - "version": "==3.0.0" + "version": "==3.1.3" }, "markupsafe": { "hashes": [ - "sha256:0212a68688482dc52b2d45013df70d169f542b7394fc744c02a57374a4207003", - "sha256:089cf3dbf0cd6c100f02945abeb18484bd1ee57a079aefd52cffd17fba910b88", - "sha256:10c1bfff05d95783da83491be968e8fe789263689c02724e0c691933c52994f5", - "sha256:33b74d289bd2f5e527beadcaa3f401e0df0a89927c1559c8566c066fa4248ab7", - "sha256:3799351e2336dc91ea70b034983ee71cf2f9533cdff7c14c90ea126bfd95d65a", - "sha256:3ce11ee3f23f79dbd06fb3d63e2f6af7b12db1d46932fe7bd8afa259a5996603", - "sha256:421be9fbf0ffe9ffd7a378aafebbf6f4602d564d34be190fc19a193232fd12b1", - "sha256:43093fb83d8343aac0b1baa75516da6092f58f41200907ef92448ecab8825135", - "sha256:46d00d6cfecdde84d40e572d63735ef81423ad31184100411e6e3388d405e247", - "sha256:4a33dea2b688b3190ee12bd7cfa29d39c9ed176bda40bfa11099a3ce5d3a7ac6", - "sha256:4b9fe39a2ccc108a4accc2676e77da025ce383c108593d65cc909add5c3bd601", - "sha256:56442863ed2b06d19c37f94d999035e15ee982988920e12a5b4ba29b62ad1f77", - "sha256:671cd1187ed5e62818414afe79ed29da836dde67166a9fac6d435873c44fdd02", - "sha256:694deca8d702d5db21ec83983ce0bb4b26a578e71fbdbd4fdcd387daa90e4d5e", - "sha256:6a074d34ee7a5ce3effbc526b7083ec9731bb3cbf921bbe1d3005d4d2bdb3a63", - "sha256:6d0072fea50feec76a4c418096652f2c3238eaa014b2f94aeb1d56a66b41403f", - "sha256:6fbf47b5d3728c6aea2abb0589b5d30459e369baa772e0f37a0320185e87c980", - "sha256:7f91197cc9e48f989d12e4e6fbc46495c446636dfc81b9ccf50bb0ec74b91d4b", - "sha256:86b1f75c4e7c2ac2ccdaec2b9022845dbb81880ca318bb7a0a01fbf7813e3812", - "sha256:8dc1c72a69aa7e082593c4a203dcf94ddb74bb5c8a731e4e1eb68d031e8498ff", - "sha256:8e3dcf21f367459434c18e71b2a9532d96547aef8a871872a5bd69a715c15f96", - "sha256:8e576a51ad59e4bfaac456023a78f6b5e6e7651dcd383bcc3e18d06f9b55d6d1", - "sha256:96e37a3dc86e80bf81758c152fe66dbf60ed5eca3d26305edf01892257049925", - "sha256:97a68e6ada378df82bc9f16b800ab77cbf4b2fada0081794318520138c088e4a", - "sha256:99a2a507ed3ac881b975a2976d59f38c19386d128e7a9a18b7df6fff1fd4c1d6", - "sha256:a49907dd8420c5685cfa064a1335b6754b74541bbb3706c259c02ed65b644b3e", - "sha256:b09bf97215625a311f669476f44b8b318b075847b49316d3e28c08e41a7a573f", - "sha256:b7bd98b796e2b6553da7225aeb61f447f80a1ca64f41d83612e6139ca5213aa4", - "sha256:b87db4360013327109564f0e591bd2a3b318547bcef31b468a92ee504d07ae4f", - "sha256:bcb3ed405ed3222f9904899563d6fc492ff75cce56cba05e32eff40e6acbeaa3", - "sha256:d4306c36ca495956b6d568d276ac11fdd9c30a36f1b6eb928070dc5360b22e1c", - "sha256:d5ee4f386140395a2c818d149221149c54849dfcfcb9f1debfe07a8b8bd63f9a", - "sha256:dda30ba7e87fbbb7eab1ec9f58678558fd9a6b8b853530e176eabd064da81417", - "sha256:e04e26803c9c3851c931eac40c695602c6295b8d432cbe78609649ad9bd2da8a", - "sha256:e1c0b87e09fa55a220f058d1d49d3fb8df88fbfab58558f1198e08c1e1de842a", - "sha256:e72591e9ecd94d7feb70c1cbd7be7b3ebea3f548870aa91e2732960fa4d57a37", - "sha256:e8c843bbcda3a2f1e3c2ab25913c80a3c5376cd00c6e8c4a86a89a28c8dc5452", - "sha256:efc1913fd2ca4f334418481c7e595c00aad186563bbc1ec76067848c7ca0a933", - "sha256:f121a1420d4e173a5d96e47e9a0c0dcff965afdf1626d28de1460815f7c4ee7a", - "sha256:fc7b548b17d238737688817ab67deebb30e8073c95749d55538ed473130ec0c7" - ], - "version": "==2.1.1" + "sha256:05fb21170423db021895e1ea1e1f3ab3adb85d1c2333cbc2310f2a26bc77272e", + "sha256:0a4e4a1aff6c7ac4cd55792abf96c915634c2b97e3cc1c7129578aa68ebd754e", + "sha256:10bbfe99883db80bdbaff2dcf681dfc6533a614f700da1287707e8a5d78a8431", + "sha256:134da1eca9ec0ae528110ccc9e48041e0828d79f24121a1a146161103c76e686", + "sha256:14ff806850827afd6b07a5f32bd917fb7f45b046ba40c57abdb636674a8b559c", + "sha256:1577735524cdad32f9f694208aa75e422adba74f1baee7551620e43a3141f559", + "sha256:1b40069d487e7edb2676d3fbdb2b0829ffa2cd63a2ec26c4938b2d34391b4ecc", + "sha256:1b8dd8c3fd14349433c79fa8abeb573a55fc0fdd769133baac1f5e07abf54aeb", + "sha256:1f67c7038d560d92149c060157d623c542173016c4babc0c1913cca0564b9939", + "sha256:282c2cb35b5b673bbcadb33a585408104df04f14b2d9b01d4c345a3b92861c2c", + "sha256:2c1b19b3aaacc6e57b7e25710ff571c24d6c3613a45e905b1fde04d691b98ee0", + "sha256:2ef12179d3a291be237280175b542c07a36e7f60718296278d8593d21ca937d4", + "sha256:338ae27d6b8745585f87218a3f23f1512dbf52c26c28e322dbe54bcede54ccb9", + "sha256:3c0fae6c3be832a0a0473ac912810b2877c8cb9d76ca48de1ed31e1c68386575", + "sha256:3fd4abcb888d15a94f32b75d8fd18ee162ca0c064f35b11134be77050296d6ba", + "sha256:42de32b22b6b804f42c5d98be4f7e5e977ecdd9ee9b660fda1a3edf03b11792d", + "sha256:47d4f1c5f80fc62fdd7777d0d40a2e9dda0a05883ab11374334f6c4de38adffd", + "sha256:504b320cd4b7eff6f968eddf81127112db685e81f7e36e75f9f84f0df46041c3", + "sha256:525808b8019e36eb524b8c68acdd63a37e75714eac50e988180b169d64480a00", + "sha256:56d9f2ecac662ca1611d183feb03a3fa4406469dafe241673d521dd5ae92a155", + "sha256:5bbe06f8eeafd38e5d0a4894ffec89378b6c6a625ff57e3028921f8ff59318ac", + "sha256:65c1a9bcdadc6c28eecee2c119465aebff8f7a584dd719facdd9e825ec61ab52", + "sha256:68e78619a61ecf91e76aa3e6e8e33fc4894a2bebe93410754bd28fce0a8a4f9f", + "sha256:69c0f17e9f5a7afdf2cc9fb2d1ce6aabdb3bafb7f38017c0b77862bcec2bbad8", + "sha256:6b2b56950d93e41f33b4223ead100ea0fe11f8e6ee5f641eb753ce4b77a7042b", + "sha256:715d3562f79d540f251b99ebd6d8baa547118974341db04f5ad06d5ea3eb8007", + "sha256:787003c0ddb00500e49a10f2844fac87aa6ce977b90b0feaaf9de23c22508b24", + "sha256:7ef3cb2ebbf91e330e3bb937efada0edd9003683db6b57bb108c4001f37a02ea", + "sha256:8023faf4e01efadfa183e863fefde0046de576c6f14659e8782065bcece22198", + "sha256:8758846a7e80910096950b67071243da3e5a20ed2546e6392603c096778d48e0", + "sha256:8afafd99945ead6e075b973fefa56379c5b5c53fd8937dad92c662da5d8fd5ee", + "sha256:8c41976a29d078bb235fea9b2ecd3da465df42a562910f9022f1a03107bd02be", + "sha256:8e254ae696c88d98da6555f5ace2279cf7cd5b3f52be2b5cf97feafe883b58d2", + "sha256:8f9293864fe09b8149f0cc42ce56e3f0e54de883a9de90cd427f191c346eb2e1", + "sha256:9402b03f1a1b4dc4c19845e5c749e3ab82d5078d16a2a4c2cd2df62d57bb0707", + "sha256:962f82a3086483f5e5f64dbad880d31038b698494799b097bc59c2edf392fce6", + "sha256:9aad3c1755095ce347e26488214ef77e0485a3c34a50c5a5e2471dff60b9dd9c", + "sha256:9dcdfd0eaf283af041973bff14a2e143b8bd64e069f4c383416ecd79a81aab58", + "sha256:aa57bd9cf8ae831a362185ee444e15a93ecb2e344c8e52e4d721ea3ab6ef1823", + "sha256:aa7bd130efab1c280bed0f45501b7c8795f9fdbeb02e965371bbef3523627779", + "sha256:ab4a0df41e7c16a1392727727e7998a467472d0ad65f3ad5e6e765015df08636", + "sha256:ad9e82fb8f09ade1c3e1b996a6337afac2b8b9e365f926f5a61aacc71adc5b3c", + "sha256:af598ed32d6ae86f1b747b82783958b1a4ab8f617b06fe68795c7f026abbdcad", + "sha256:b076b6226fb84157e3f7c971a47ff3a679d837cf338547532ab866c57930dbee", + "sha256:b7ff0f54cb4ff66dd38bebd335a38e2c22c41a8ee45aa608efc890ac3e3931bc", + "sha256:bfce63a9e7834b12b87c64d6b155fdd9b3b96191b6bd334bf37db7ff1fe457f2", + "sha256:c011a4149cfbcf9f03994ec2edffcb8b1dc2d2aede7ca243746df97a5d41ce48", + "sha256:c9c804664ebe8f83a211cace637506669e7890fec1b4195b505c214e50dd4eb7", + "sha256:ca379055a47383d02a5400cb0d110cef0a776fc644cda797db0c5696cfd7e18e", + "sha256:cb0932dc158471523c9637e807d9bfb93e06a95cbf010f1a38b98623b929ef2b", + "sha256:cd0f502fe016460680cd20aaa5a76d241d6f35a1c3350c474bac1273803893fa", + "sha256:ceb01949af7121f9fc39f7d27f91be8546f3fb112c608bc4029aef0bab86a2a5", + "sha256:d080e0a5eb2529460b30190fcfcc4199bd7f827663f858a226a81bc27beaa97e", + "sha256:dd15ff04ffd7e05ffcb7fe79f1b98041b8ea30ae9234aed2a9168b5797c3effb", + "sha256:df0be2b576a7abbf737b1575f048c23fb1d769f267ec4358296f31c2479db8f9", + "sha256:e09031c87a1e51556fdcb46e5bd4f59dfb743061cf93c4d6831bf894f125eb57", + "sha256:e4dd52d80b8c83fdce44e12478ad2e85c64ea965e75d66dbeafb0a3e77308fcc", + "sha256:f698de3fd0c4e6972b92290a45bd9b1536bffe8c6759c62471efaa8acb4c37bc", + "sha256:fec21693218efe39aa7f8599346e90c705afa52c5b31ae019b2e57e8f6542bb2", + "sha256:ffcc3f7c66b5f5b7931a5aa68fc9cecc51e685ef90282f4a82f0f5e9b704ad11" + ], + "markers": "python_version >= '3.7'", + "version": "==2.1.3" }, "pillow": { "hashes": [ @@ -284,170 +320,275 @@ "index": "pypi", "version": "==5.4.1" }, + "setuptools": { + "hashes": [ + "sha256:385eb4edd9c9d5c17540511303e39a147ce2fc04bc55289c322b9e5904fe2c05", + "sha256:be1af57fc409f93647f2e8e4573a142ed38724b8cdd389706a867bb4efcf1e78" + ], + "markers": "python_version >= '3.8'", + "version": "==69.0.3" + }, "werkzeug": { "hashes": [ - "sha256:7ea2d48322cc7c0f8b3a215ed73eabd7b5d75d0b50e31ab006286ccff9e00b8f", - "sha256:f979ab81f58d7318e064e99c4506445d60135ac5cd2e177a2de0089bfd4c9bd5" + "sha256:554b257c74bbeb7a0d254160a4f8ffe185243f52a52035060b761ca62d977f03", + "sha256:bba1f19f8ec89d4d607a3bd62f1904bd2e609472d93cd85e9d4e178f472c3748" ], - "version": "==2.2.2" + "index": "pypi", + "version": "==2.3.8" }, "zope.event": { "hashes": [ - "sha256:2666401939cdaa5f4e0c08cf7f20c9b21423b95e88f4675b1443973bdb080c42", - "sha256:5e76517f5b9b119acf37ca8819781db6c16ea433f7e2062c4afc2b6fbedb1330" + "sha256:2832e95014f4db26c47a13fdaef84cef2f4df37e66b59d8f1f4a8f319a632c26", + "sha256:bac440d8d9891b4068e2b5a2c5e2c9765a9df762944bda6955f96bb9b91e67cd" ], - "version": "==4.5.0" + "markers": "python_version >= '3.7'", + "version": "==5.0" }, "zope.interface": { "hashes": [ - "sha256:08f9636e99a9d5410181ba0729e0408d3d8748026ea938f3b970a0249daa8192", - "sha256:0b465ae0962d49c68aa9733ba92a001b2a0933c317780435f00be7ecb959c702", - "sha256:0cba8477e300d64a11a9789ed40ee8932b59f9ee05f85276dbb4b59acee5dd09", - "sha256:0cee5187b60ed26d56eb2960136288ce91bcf61e2a9405660d271d1f122a69a4", - "sha256:0ea1d73b7c9dcbc5080bb8aaffb776f1c68e807767069b9ccdd06f27a161914a", - "sha256:0f91b5b948686659a8e28b728ff5e74b1be6bf40cb04704453617e5f1e945ef3", - "sha256:15e7d1f7a6ee16572e21e3576d2012b2778cbacf75eb4b7400be37455f5ca8bf", - "sha256:17776ecd3a1fdd2b2cd5373e5ef8b307162f581c693575ec62e7c5399d80794c", - "sha256:194d0bcb1374ac3e1e023961610dc8f2c78a0f5f634d0c737691e215569e640d", - "sha256:1c0e316c9add0db48a5b703833881351444398b04111188069a26a61cfb4df78", - "sha256:205e40ccde0f37496904572035deea747390a8b7dc65146d30b96e2dd1359a83", - "sha256:273f158fabc5ea33cbc936da0ab3d4ba80ede5351babc4f577d768e057651531", - "sha256:2876246527c91e101184f63ccd1d716ec9c46519cc5f3d5375a3351c46467c46", - "sha256:2c98384b254b37ce50eddd55db8d381a5c53b4c10ee66e1e7fe749824f894021", - "sha256:2e5a26f16503be6c826abca904e45f1a44ff275fdb7e9d1b75c10671c26f8b94", - "sha256:334701327f37c47fa628fc8b8d28c7d7730ce7daaf4bda1efb741679c2b087fc", - "sha256:3748fac0d0f6a304e674955ab1365d515993b3a0a865e16a11ec9d86fb307f63", - "sha256:3c02411a3b62668200910090a0dff17c0b25aaa36145082a5a6adf08fa281e54", - "sha256:3dd4952748521205697bc2802e4afac5ed4b02909bb799ba1fe239f77fd4e117", - "sha256:3f24df7124c323fceb53ff6168da70dbfbae1442b4f3da439cd441681f54fe25", - "sha256:469e2407e0fe9880ac690a3666f03eb4c3c444411a5a5fddfdabc5d184a79f05", - "sha256:4de4bc9b6d35c5af65b454d3e9bc98c50eb3960d5a3762c9438df57427134b8e", - "sha256:5208ebd5152e040640518a77827bdfcc73773a15a33d6644015b763b9c9febc1", - "sha256:52de7fc6c21b419078008f697fd4103dbc763288b1406b4562554bd47514c004", - "sha256:5bb3489b4558e49ad2c5118137cfeaf59434f9737fa9c5deefc72d22c23822e2", - "sha256:5dba5f530fec3f0988d83b78cc591b58c0b6eb8431a85edd1569a0539a8a5a0e", - "sha256:5dd9ca406499444f4c8299f803d4a14edf7890ecc595c8b1c7115c2342cadc5f", - "sha256:5f931a1c21dfa7a9c573ec1f50a31135ccce84e32507c54e1ea404894c5eb96f", - "sha256:63b82bb63de7c821428d513607e84c6d97d58afd1fe2eb645030bdc185440120", - "sha256:66c0061c91b3b9cf542131148ef7ecbecb2690d48d1612ec386de9d36766058f", - "sha256:6f0c02cbb9691b7c91d5009108f975f8ffeab5dff8f26d62e21c493060eff2a1", - "sha256:71aace0c42d53abe6fc7f726c5d3b60d90f3c5c055a447950ad6ea9cec2e37d9", - "sha256:7d97a4306898b05404a0dcdc32d9709b7d8832c0c542b861d9a826301719794e", - "sha256:7df1e1c05304f26faa49fa752a8c690126cf98b40b91d54e6e9cc3b7d6ffe8b7", - "sha256:8270252effc60b9642b423189a2fe90eb6b59e87cbee54549db3f5562ff8d1b8", - "sha256:867a5ad16892bf20e6c4ea2aab1971f45645ff3102ad29bd84c86027fa99997b", - "sha256:877473e675fdcc113c138813a5dd440da0769a2d81f4d86614e5d62b69497155", - "sha256:8892f89999ffd992208754851e5a052f6b5db70a1e3f7d54b17c5211e37a98c7", - "sha256:9a9845c4c6bb56e508651f005c4aeb0404e518c6f000d5a1123ab077ab769f5c", - "sha256:a1e6e96217a0f72e2b8629e271e1b280c6fa3fe6e59fa8f6701bec14e3354325", - "sha256:a8156e6a7f5e2a0ff0c5b21d6bcb45145efece1909efcbbbf48c56f8da68221d", - "sha256:a9506a7e80bcf6eacfff7f804c0ad5350c8c95b9010e4356a4b36f5322f09abb", - "sha256:af310ec8335016b5e52cae60cda4a4f2a60a788cbb949a4fbea13d441aa5a09e", - "sha256:b0297b1e05fd128d26cc2460c810d42e205d16d76799526dfa8c8ccd50e74959", - "sha256:bf68f4b2b6683e52bec69273562df15af352e5ed25d1b6641e7efddc5951d1a7", - "sha256:d0c1bc2fa9a7285719e5678584f6b92572a5b639d0e471bb8d4b650a1a910920", - "sha256:d4d9d6c1a455d4babd320203b918ccc7fcbefe308615c521062bc2ba1aa4d26e", - "sha256:db1fa631737dab9fa0b37f3979d8d2631e348c3b4e8325d6873c2541d0ae5a48", - "sha256:dd93ea5c0c7f3e25335ab7d22a507b1dc43976e1345508f845efc573d3d779d8", - "sha256:f44e517131a98f7a76696a7b21b164bcb85291cee106a23beccce454e1f433a4", - "sha256:f7ee479e96f7ee350db1cf24afa5685a5899e2b34992fb99e1f7c1b0b758d263" - ], - "version": "==5.4.0" + "sha256:0c8cf55261e15590065039696607f6c9c1aeda700ceee40c70478552d323b3ff", + "sha256:13b7d0f2a67eb83c385880489dbb80145e9d344427b4262c49fbf2581677c11c", + "sha256:1f294a15f7723fc0d3b40701ca9b446133ec713eafc1cc6afa7b3d98666ee1ac", + "sha256:239a4a08525c080ff833560171d23b249f7f4d17fcbf9316ef4159f44997616f", + "sha256:2f8d89721834524a813f37fa174bac074ec3d179858e4ad1b7efd4401f8ac45d", + "sha256:2fdc7ccbd6eb6b7df5353012fbed6c3c5d04ceaca0038f75e601060e95345309", + "sha256:34c15ca9248f2e095ef2e93af2d633358c5f048c49fbfddf5fdfc47d5e263736", + "sha256:387545206c56b0315fbadb0431d5129c797f92dc59e276b3ce82db07ac1c6179", + "sha256:43b576c34ef0c1f5a4981163b551a8781896f2a37f71b8655fd20b5af0386abb", + "sha256:57d0a8ce40ce440f96a2c77824ee94bf0d0925e6089df7366c2272ccefcb7941", + "sha256:5a804abc126b33824a44a7aa94f06cd211a18bbf31898ba04bd0924fbe9d282d", + "sha256:67be3ca75012c6e9b109860820a8b6c9a84bfb036fbd1076246b98e56951ca92", + "sha256:6af47f10cfc54c2ba2d825220f180cc1e2d4914d783d6fc0cd93d43d7bc1c78b", + "sha256:6dc998f6de015723196a904045e5a2217f3590b62ea31990672e31fbc5370b41", + "sha256:70d2cef1bf529bff41559be2de9d44d47b002f65e17f43c73ddefc92f32bf00f", + "sha256:7ebc4d34e7620c4f0da7bf162c81978fce0ea820e4fa1e8fc40ee763839805f3", + "sha256:964a7af27379ff4357dad1256d9f215047e70e93009e532d36dcb8909036033d", + "sha256:97806e9ca3651588c1baaebb8d0c5ee3db95430b612db354c199b57378312ee8", + "sha256:9b9bc671626281f6045ad61d93a60f52fd5e8209b1610972cf0ef1bbe6d808e3", + "sha256:9ffdaa5290422ac0f1688cb8adb1b94ca56cee3ad11f29f2ae301df8aecba7d1", + "sha256:a0da79117952a9a41253696ed3e8b560a425197d4e41634a23b1507efe3273f1", + "sha256:a41f87bb93b8048fe866fa9e3d0c51e27fe55149035dcf5f43da4b56732c0a40", + "sha256:aa6fd016e9644406d0a61313e50348c706e911dca29736a3266fc9e28ec4ca6d", + "sha256:ad54ed57bdfa3254d23ae04a4b1ce405954969c1b0550cc2d1d2990e8b439de1", + "sha256:b012d023b4fb59183909b45d7f97fb493ef7a46d2838a5e716e3155081894605", + "sha256:b51b64432eed4c0744241e9ce5c70dcfecac866dff720e746d0a9c82f371dfa7", + "sha256:bbe81def9cf3e46f16ce01d9bfd8bea595e06505e51b7baf45115c77352675fd", + "sha256:c9559138690e1bd4ea6cd0954d22d1e9251e8025ce9ede5d0af0ceae4a401e43", + "sha256:e30506bcb03de8983f78884807e4fd95d8db6e65b69257eea05d13d519b83ac0", + "sha256:e33e86fd65f369f10608b08729c8f1c92ec7e0e485964670b4d2633a4812d36b", + "sha256:e441e8b7d587af0414d25e8d05e27040d78581388eed4c54c30c0c91aad3a379", + "sha256:e8bb9c990ca9027b4214fa543fd4025818dc95f8b7abce79d61dc8a2112b561a", + "sha256:ef43ee91c193f827e49599e824385ec7c7f3cd152d74cb1dfe02cb135f264d83", + "sha256:ef467d86d3cfde8b39ea1b35090208b0447caaabd38405420830f7fd85fbdd56", + "sha256:f89b28772fc2562ed9ad871c865f5320ef761a7fcc188a935e21fe8b31a38ca9", + "sha256:fddbab55a2473f1d3b8833ec6b7ac31e8211b0aa608df5ab09ce07f3727326de" + ], + "markers": "python_version >= '3.7'", + "version": "==6.1" } }, "develop": { "astroid": { "hashes": [ - "sha256:39fa822c82dc112f5072a208ddf01c58184043aa90e3e469786fa0520c71aaa7", - "sha256:af71cdc0775b6e4d88076746620e2c8cd1bf4533a9977cfdd00eeea97d95530c" + "sha256:4a61cf0a59097c7bb52689b0fd63717cd2a8a14dc9f1eee97b82d814881c8c91", + "sha256:d6e62862355f60e716164082d6b4b041d38e2a8cf1c7cd953ded5108bac8ff5c" ], - "version": "==2.12.4" + "markers": "python_full_version >= '3.8.0'", + "version": "==3.0.2" + }, + "cairocffi": { + "hashes": [ + "sha256:78e6bbe47357640c453d0be929fa49cd05cce2e1286f3d2a1ca9cbda7efdb8b7", + "sha256:aa78ee52b9069d7475eeac457389b6275aa92111895d78fbaa2202a52dac112e" + ], + "markers": "python_version >= '3.7'", + "version": "==1.6.1" + }, + "cairosvg": { + "hashes": [ + "sha256:432531d72347291b9a9ebfb6777026b607563fd8719c46ee742db0aef7271ba0", + "sha256:8a5222d4e6c3f86f1f7046b63246877a63b49923a1cd202184c3a634ef546b3b" + ], + "index": "pypi", + "version": "==2.7.1" + }, + "cffi": { + "hashes": [ + "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" + }, + "cssselect2": { + "hashes": [ + "sha256:1ccd984dab89fc68955043aca4e1b03e0cf29cad9880f6e28e3ba7a74b14aa5a", + "sha256:fd23a65bfd444595913f02fc71f6b286c29261e354c41d722ca7a261a49b5969" + ], + "markers": "python_version >= '3.7'", + "version": "==0.7.0" + }, + "defusedxml": { + "hashes": [ + "sha256:1bb3032db185915b62d7c6209c5a8792be6a32ab2fedacc84e01b52c51aa3e69", + "sha256:a352e7e428770286cc899e2542b6cdaedb2b4953ff269a210103ec58f6198a61" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", + "version": "==0.7.1" }, "dill": { "hashes": [ - "sha256:33501d03270bbe410c72639b350e941882a8b0fd55357580fbc873fba0c59302", - "sha256:d75e41f3eff1eee599d738e76ba8f4ad98ea229db8b085318aa2b3333a208c86" + "sha256:76b122c08ef4ce2eedcd4d1abd8e641114bfc6c2867f49f3c41facf65bf19f5e", + "sha256:cc1c8b182eb3013e24bd475ff2e9295af86c1a38eb1aff128dac8962a9ce3c03" + ], + "markers": "python_version < '3.11'", + "version": "==0.3.7" + }, + "importlib-metadata": { + "hashes": [ + "sha256:4805911c3a4ec7c3966410053e9ec6a1fecd629117df5adee56dfc9432a1081e", + "sha256:f238736bb06590ae52ac1fab06a3a9ef1d8dce2b7a35b5ab329371d6c8f5d2cc" ], - "version": "==0.3.5.1" + "markers": "python_version >= '3.8'", + "version": "==7.0.1" }, "isort": { "hashes": [ - "sha256:6f62d78e2f89b4500b080fe3a81690850cd254227f27f75c3a0c491a1f351ba7", - "sha256:e8443a5e7a020e9d7f97f1d7d9cd17c88bcb3bc7e218bf9cf5095fe550be2951" - ], - "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" - ], - "version": "==1.7.1" + "sha256:48fdfcb9face5d58a4f6dde2e72a1fb8dcaf8ab26f95ab49fab84c2ddefb0109", + "sha256:8ca5e72a8d85860d5a3fa69b8745237f2939afe12dbf656afbcb47fe72d947a6" + ], + "markers": "python_full_version >= '3.8.0'", + "version": "==5.13.2" }, "mccabe": { "hashes": [ "sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325", "sha256:6c2d30ab6be0e4a46919781807b4f0d834ebdd6c6e3dca0bda5a15f863427b6e" ], + "markers": "python_version >= '3.6'", "version": "==0.7.0" }, "nose2": { "hashes": [ - "sha256:956e79b9bd558ee08b6200c05ad2c76465b7e3860c0c0537686089285c320113", - "sha256:da7eb5e3cbe2abb693a053e17b4fbefca98ea9ea79fc729b0b0f41e8b4196304" + "sha256:5c28d770a0b9a702862bd6c3755ba2cd2f7994dd518c982e5ce298d7f37466a4", + "sha256:86993e9243c744df29c1ec237aecee33e2f59abb4bdd25a313f2e806b99228a1" ], "index": "pypi", - "version": "==0.12.0" + "version": "==0.14.0" + }, + "pillow": { + "hashes": [ + "sha256:011233e0c42a4a7836498e98c1acf5e744c96a67dd5032a6f666cc1fb97eab97", + "sha256:0f29d831e2151e0b7b39981756d201f7108d3d215896212ffe2e992d06bfe049", + "sha256:12875d118f21cf35604176872447cdb57b07126750a33748bac15e77f90f1f9c", + "sha256:14d4b1341ac07ae07eb2cc682f459bec932a380c3b122f5540432d8977e64eae", + "sha256:1c3c33ac69cf059bbb9d1a71eeaba76781b450bc307e2291f8a4764d779a6b28", + "sha256:1d19397351f73a88904ad1aee421e800fe4bbcd1aeee6435fb62d0a05ccd1030", + "sha256:253e8a302a96df6927310a9d44e6103055e8fb96a6822f8b7f514bb7ef77de56", + "sha256:2632d0f846b7c7600edf53c48f8f9f1e13e62f66a6dbc15191029d950bfed976", + "sha256:335ace1a22325395c4ea88e00ba3dc89ca029bd66bd5a3c382d53e44f0ccd77e", + "sha256:413ce0bbf9fc6278b2d63309dfeefe452835e1c78398efb431bab0672fe9274e", + "sha256:5100b45a4638e3c00e4d2320d3193bdabb2d75e79793af7c3eb139e4f569f16f", + "sha256:514ceac913076feefbeaf89771fd6febde78b0c4c1b23aaeab082c41c694e81b", + "sha256:528a2a692c65dd5cafc130de286030af251d2ee0483a5bf50c9348aefe834e8a", + "sha256:6295f6763749b89c994fcb6d8a7f7ce03c3992e695f89f00b741b4580b199b7e", + "sha256:6c8bc8238a7dfdaf7a75f5ec5a663f4173f8c367e5a39f87e720495e1eed75fa", + "sha256:718856856ba31f14f13ba885ff13874be7fefc53984d2832458f12c38205f7f7", + "sha256:7f7609a718b177bf171ac93cea9fd2ddc0e03e84d8fa4e887bdfc39671d46b00", + "sha256:80ca33961ced9c63358056bd08403ff866512038883e74f3a4bf88ad3eb66838", + "sha256:80fe64a6deb6fcfdf7b8386f2cf216d329be6f2781f7d90304351811fb591360", + "sha256:81c4b81611e3a3cb30e59b0cf05b888c675f97e3adb2c8672c3154047980726b", + "sha256:855c583f268edde09474b081e3ddcd5cf3b20c12f26e0d434e1386cc5d318e7a", + "sha256:9bfdb82cdfeccec50aad441afc332faf8606dfa5e8efd18a6692b5d6e79f00fd", + "sha256:a5d24e1d674dd9d72c66ad3ea9131322819ff86250b30dc5821cbafcfa0b96b4", + "sha256:a9f44cd7e162ac6191491d7249cceb02b8116b0f7e847ee33f739d7cb1ea1f70", + "sha256:b5b3f092fe345c03bca1e0b687dfbb39364b21ebb8ba90e3fa707374b7915204", + "sha256:b9618823bd237c0d2575283f2939655f54d51b4527ec3972907a927acbcc5bfc", + "sha256:cef9c85ccbe9bee00909758936ea841ef12035296c748aaceee535969e27d31b", + "sha256:d21237d0cd37acded35154e29aec853e945950321dd2ffd1a7d86fe686814669", + "sha256:d3c5c79ab7dfce6d88f1ba639b77e77a17ea33a01b07b99840d6ed08031cb2a7", + "sha256:d9d7942b624b04b895cb95af03a23407f17646815495ce4547f0e60e0b06f58e", + "sha256:db6d9fac65bd08cea7f3540b899977c6dee9edad959fa4eaf305940d9cbd861c", + "sha256:ede5af4a2702444a832a800b8eb7f0a7a1c0eed55b644642e049c98d589e5092", + "sha256:effb7749713d5317478bb3acb3f81d9d7c7f86726d41c1facca068a04cf5bb4c", + "sha256:f154d173286a5d1863637a7dcd8c3437bb557520b01bddb0be0258dcb72696b5", + "sha256:f25ed6e28ddf50de7e7ea99d7a976d6a9c415f03adcaac9c41ff6ff41b6d86ac" + ], + "index": "pypi", + "version": "==9.0.1" }, "platformdirs": { "hashes": [ - "sha256:027d8e83a2d7de06bbac4e5ef7e023c02b863d7ea5d079477e722bb41ab25788", - "sha256:58c8abb07dcb441e6ee4b11d8df0ac856038f944ab98b7be6b27b2a3c7feef19" + "sha256:11c8f37bcca40db96d8144522d925583bdb7a31f7b0e37e3ed4318400a8e2380", + "sha256:906d548203468492d432bcb294d4bc2fff751bf84971fbb2c10918cc206ee420" + ], + "markers": "python_version >= '3.8'", + "version": "==4.1.0" + }, + "pycparser": { + "hashes": [ + "sha256:8ee45429555515e1f6b185e78100aea234072576aa43ab53aefcae078162fca9", + "sha256:e644fdec12f7872f86c58ff790da456218b10f863970249516d60a5eaca77206" ], - "version": "==2.5.2" + "version": "==2.21" }, "pylint": { "hashes": [ - "sha256:4b124affc198b7f7c9b5f9ab690d85db48282a025ef9333f51d2d7281b92a6c3", - "sha256:4f3f7e869646b0bd63b3dfb79f3c0f28fc3d2d923ea220d52620fd625aed92b0" + "sha256:58c2398b0301e049609a8429789ec6edf3aabe9b6c5fec916acd18639c16de8b", + "sha256:7a1585285aefc5165db81083c3e06363a27448f6b467b3b0f30dbd0ac1f73810" ], "index": "pypi", - "version": "==2.15.0" + "version": "==3.0.3" }, "pylint-flask": { "hashes": [ @@ -458,10 +599,19 @@ }, "pylint-plugin-utils": { "hashes": [ - "sha256:b3d43e85ab74c4f48bb46ae4ce771e39c3a20f8b3d56982ab17aa73b4f98d535", - "sha256:ce48bc0516ae9415dd5c752c940dfe601b18fe0f48aa249f2386adfa95a004dd" + "sha256:ae11664737aa2effbf26f973a9e0b6779ab7106ec0adc5fe104b0907ca04e507", + "sha256:d3cebf68a38ba3fba23a873809155562571386d4c1b03e5b4c4cc26c3eee93e4" ], - "version": "==0.7" + "markers": "python_version >= '3.7' and python_version < '4.0'", + "version": "==0.8.2" + }, + "tinycss2": { + "hashes": [ + "sha256:2b80a96d41e7c3914b8cda8bc7f705a4d9c49275616e886103dd839dfc847847", + "sha256:8cff3a8f066c2ec677c06dbc7b45619804a6938478d9d73c284b29d14ecb0627" + ], + "markers": "python_version >= '3.7'", + "version": "==1.2.1" }, "tomli": { "hashes": [ @@ -473,96 +623,42 @@ }, "tomlkit": { "hashes": [ - "sha256:25d4e2e446c453be6360c67ddfb88838cfc42026322770ba13d1fbd403a93a5c", - "sha256:3235a9010fae54323e727c3ac06fb720752fe6635b3426e379daec60fbd44a83" + "sha256:75baf5012d06501f07bee5bf8e801b9f343e7aac5a92581f20f80ce632e6b5a4", + "sha256:b0a645a9156dc7cb5d3a1f0d4bab66db287fcb8e0430bdd4664a095ea16414ba" ], - "version": "==0.11.4" + "markers": "python_version >= '3.7'", + "version": "==0.12.3" }, "typing-extensions": { "hashes": [ - "sha256:25642c956049920a5aa49edcdd6ab1e06d7e5d467fc00e0506c44ac86fbfca02", - "sha256:e6d2677a32f47fc7eb2795db1dd15c1f34eff616bcaf2cfb5e997f854fa1c4a6" + "sha256:23478f88c37f27d76ac8aee6c905017a143b0b1b886c3c9f66bc2fd94f9f5783", + "sha256:af72aea155e91adfc61c3ae9e0e342dbc0cba726d6cba4b6c72c1f34e47291cd" ], "markers": "python_version < '3.10'", - "version": "==4.3.0" - }, - "wrapt": { - "hashes": [ - "sha256:00b6d4ea20a906c0ca56d84f93065b398ab74b927a7a3dbd470f6fc503f95dc3", - "sha256:01c205616a89d09827986bc4e859bcabd64f5a0662a7fe95e0d359424e0e071b", - "sha256:02b41b633c6261feff8ddd8d11c711df6842aba629fdd3da10249a53211a72c4", - "sha256:07f7a7d0f388028b2df1d916e94bbb40624c59b48ecc6cbc232546706fac74c2", - "sha256:11871514607b15cfeb87c547a49bca19fde402f32e2b1c24a632506c0a756656", - "sha256:1b376b3f4896e7930f1f772ac4b064ac12598d1c38d04907e696cc4d794b43d3", - "sha256:21ac0156c4b089b330b7666db40feee30a5d52634cc4560e1905d6529a3897ff", - "sha256:257fd78c513e0fb5cdbe058c27a0624c9884e735bbd131935fd49e9fe719d310", - "sha256:2b39d38039a1fdad98c87279b48bc5dce2c0ca0d73483b12cb72aa9609278e8a", - "sha256:2cf71233a0ed05ccdabe209c606fe0bac7379fdcf687f39b944420d2a09fdb57", - "sha256:2fe803deacd09a233e4762a1adcea5db5d31e6be577a43352936179d14d90069", - "sha256:3232822c7d98d23895ccc443bbdf57c7412c5a65996c30442ebe6ed3df335383", - "sha256:34aa51c45f28ba7f12accd624225e2b1e5a3a45206aa191f6f9aac931d9d56fe", - "sha256:36f582d0c6bc99d5f39cd3ac2a9062e57f3cf606ade29a0a0d6b323462f4dd87", - "sha256:380a85cf89e0e69b7cfbe2ea9f765f004ff419f34194018a6827ac0e3edfed4d", - "sha256:40e7bc81c9e2b2734ea4bc1aceb8a8f0ceaac7c5299bc5d69e37c44d9081d43b", - "sha256:43ca3bbbe97af00f49efb06e352eae40434ca9d915906f77def219b88e85d907", - "sha256:4fcc4649dc762cddacd193e6b55bc02edca674067f5f98166d7713b193932b7f", - "sha256:5a0f54ce2c092aaf439813735584b9537cad479575a09892b8352fea5e988dc0", - "sha256:5a9a0d155deafd9448baff28c08e150d9b24ff010e899311ddd63c45c2445e28", - "sha256:5b02d65b9ccf0ef6c34cba6cf5bf2aab1bb2f49c6090bafeecc9cd81ad4ea1c1", - "sha256:60db23fa423575eeb65ea430cee741acb7c26a1365d103f7b0f6ec412b893853", - "sha256:642c2e7a804fcf18c222e1060df25fc210b9c58db7c91416fb055897fc27e8cc", - "sha256:6a9a25751acb379b466ff6be78a315e2b439d4c94c1e99cb7266d40a537995d3", - "sha256:6b1a564e6cb69922c7fe3a678b9f9a3c54e72b469875aa8018f18b4d1dd1adf3", - "sha256:6d323e1554b3d22cfc03cd3243b5bb815a51f5249fdcbb86fda4bf62bab9e164", - "sha256:6e743de5e9c3d1b7185870f480587b75b1cb604832e380d64f9504a0535912d1", - "sha256:709fe01086a55cf79d20f741f39325018f4df051ef39fe921b1ebe780a66184c", - "sha256:7b7c050ae976e286906dd3f26009e117eb000fb2cf3533398c5ad9ccc86867b1", - "sha256:7d2872609603cb35ca513d7404a94d6d608fc13211563571117046c9d2bcc3d7", - "sha256:7ef58fb89674095bfc57c4069e95d7a31cfdc0939e2a579882ac7d55aadfd2a1", - "sha256:80bb5c256f1415f747011dc3604b59bc1f91c6e7150bd7db03b19170ee06b320", - "sha256:81b19725065dcb43df02b37e03278c011a09e49757287dca60c5aecdd5a0b8ed", - "sha256:833b58d5d0b7e5b9832869f039203389ac7cbf01765639c7309fd50ef619e0b1", - "sha256:88bd7b6bd70a5b6803c1abf6bca012f7ed963e58c68d76ee20b9d751c74a3248", - "sha256:8ad85f7f4e20964db4daadcab70b47ab05c7c1cf2a7c1e51087bfaa83831854c", - "sha256:8c0ce1e99116d5ab21355d8ebe53d9460366704ea38ae4d9f6933188f327b456", - "sha256:8d649d616e5c6a678b26d15ece345354f7c2286acd6db868e65fcc5ff7c24a77", - "sha256:903500616422a40a98a5a3c4ff4ed9d0066f3b4c951fa286018ecdf0750194ef", - "sha256:9736af4641846491aedb3c3f56b9bc5568d92b0692303b5a305301a95dfd38b1", - "sha256:988635d122aaf2bdcef9e795435662bcd65b02f4f4c1ae37fbee7401c440b3a7", - "sha256:9cca3c2cdadb362116235fdbd411735de4328c61425b0aa9f872fd76d02c4e86", - "sha256:9e0fd32e0148dd5dea6af5fee42beb949098564cc23211a88d799e434255a1f4", - "sha256:9f3e6f9e05148ff90002b884fbc2a86bd303ae847e472f44ecc06c2cd2fcdb2d", - "sha256:a85d2b46be66a71bedde836d9e41859879cc54a2a04fad1191eb50c2066f6e9d", - "sha256:a9a52172be0b5aae932bef82a79ec0a0ce87288c7d132946d645eba03f0ad8a8", - "sha256:aa31fdcc33fef9eb2552cbcbfee7773d5a6792c137b359e82879c101e98584c5", - "sha256:b014c23646a467558be7da3d6b9fa409b2c567d2110599b7cf9a0c5992b3b471", - "sha256:b21bb4c09ffabfa0e85e3a6b623e19b80e7acd709b9f91452b8297ace2a8ab00", - "sha256:b5901a312f4d14c59918c221323068fad0540e34324925c8475263841dbdfe68", - "sha256:b9b7a708dd92306328117d8c4b62e2194d00c365f18eff11a9b53c6f923b01e3", - "sha256:d1967f46ea8f2db647c786e78d8cc7e4313dbd1b0aca360592d8027b8508e24d", - "sha256:d52a25136894c63de15a35bc0bdc5adb4b0e173b9c0d07a2be9d3ca64a332735", - "sha256:d77c85fedff92cf788face9bfa3ebaa364448ebb1d765302e9af11bf449ca36d", - "sha256:d79d7d5dc8a32b7093e81e97dad755127ff77bcc899e845f41bf71747af0c569", - "sha256:dbcda74c67263139358f4d188ae5faae95c30929281bc6866d00573783c422b7", - "sha256:ddaea91abf8b0d13443f6dac52e89051a5063c7d014710dcb4d4abb2ff811a59", - "sha256:dee0ce50c6a2dd9056c20db781e9c1cfd33e77d2d569f5d1d9321c641bb903d5", - "sha256:dee60e1de1898bde3b238f18340eec6148986da0455d8ba7848d50470a7a32fb", - "sha256:e2f83e18fe2f4c9e7db597e988f72712c0c3676d337d8b101f6758107c42425b", - "sha256:e3fb1677c720409d5f671e39bac6c9e0e422584e5f518bfd50aa4cbbea02433f", - "sha256:ee2b1b1769f6707a8a445162ea16dddf74285c3964f605877a20e38545c3c462", - "sha256:ee6acae74a2b91865910eef5e7de37dc6895ad96fa23603d1d27ea69df545015", - "sha256:ef3f72c9666bba2bab70d2a8b79f2c6d2c1a42a7f7e2b0ec83bb2f9e383950af" + "version": "==4.9.0" + }, + "webencodings": { + "hashes": [ + "sha256:a0af1213f3c2226497a97e2b3aa01a7e4bee4f403f95be16fc9acd2947514a78", + "sha256:b36a1c245f2d304965eb4e0a82848379241dc04b865afcc4aab16748587e1923" ], - "markers": "python_version < '3.11'", - "version": "==1.14.1" + "version": "==0.5.1" }, "yapf": { "hashes": [ - "sha256:8fea849025584e486fd06d6ba2bed717f396080fd3cc236ba10cb97c4c51cf32", - "sha256:a3f5085d37ef7e3e004c4ba9f9b3e40c54ff1901cd111f05145ae313a7c67d1b" + "sha256:4dab8a5ed7134e26d57c1647c7483afb3f136878b579062b786c9ba16b94637b", + "sha256:adc8b5dd02c0143108878c499284205adb258aad6db6634e5b869e7ee2bd548b" ], "index": "pypi", - "version": "==0.32.0" + "version": "==0.40.2" + }, + "zipp": { + "hashes": [ + "sha256:0e923e726174922dce09c53c59ad483ff7bbb8e572e00c7f7c46b88556409f31", + "sha256:84e64a1c28cf7e91ed2078bb8cc8c259cb19b76942096c8d7b84947690cabaf0" + ], + "markers": "python_version >= '3.8'", + "version": "==3.17.0" } } } diff --git a/README.md b/README.md index 51c6767..4f93a81 100644 --- a/README.md +++ b/README.md @@ -18,6 +18,8 @@ - [Linting and formatting your work](#linting-and-formatting-your-work) - [Test your work](#test-your-work) - [Docker](#docker) +- [Maintenance](#maintenance) + - [Convert Symbols from svg to png](#convert-symbols-from-svg-to-png) - [Deployment](#deployment) - [Deployment configuration](#deployment-configuration) @@ -156,6 +158,23 @@ You can also check these metadata on a running container as follows docker ps --format="table {{.ID}}\t{{.Image}}\t{{.Labels}}" ``` +## Maintenance + +### Convert Symbols from svg to png + +Sometimes it may happen, that we get a new set of icons. In general these icons have to be quadratic in a resolution of 48px x 48px in the format .png. Neverthanless there is a script to convert .svg images towards .png images. This script is located in the folder `scripts/svg2png.py`. There is a help provided + +```bash +pipenv run python scripts/svg2png.py --help +``` + +Here is an example of such a convertion + +```bash +pipenv run python scripts/svg2png.py --help +```pipenv run python scripts/svg2png.py -I ./tmp/new-icons -O ./static/images/babs2 -W 48 -H 48 +``` + ## Deployment ### Deployment configuration diff --git a/app/routes.py b/app/routes.py index d42194e..20b0c6c 100644 --- a/app/routes.py +++ b/app/routes.py @@ -65,18 +65,10 @@ def icon_metadata(icon_set_name, icon_name): return make_api_compliant_response(icon) -@app.route( - '/sets//icons/.png', -) -@app.route( - '/sets//icons/-,,.png', -) -@app.route( - '/sets//icons/@.png', -) -@app.route( - '/sets//icons/@-,,.png', -) +@app.route('/sets//icons/.png',) +@app.route('/sets//icons/-,,.png',) +@app.route('/sets//icons/@.png',) +@app.route('/sets//icons/@-,,.png',) def colorized_icon( icon_set_name, icon_name, diff --git a/scripts/svg2png.py b/scripts/svg2png.py new file mode 100644 index 0000000..230e933 --- /dev/null +++ b/scripts/svg2png.py @@ -0,0 +1,160 @@ +import argparse as ap +import logging +import os +import sys +from textwrap import dedent + +import cairosvg + +logger = logging.getLogger() +logger.setLevel(logging.DEBUG) + +handler = logging.StreamHandler(sys.stdout) +handler.setLevel(logging.DEBUG) +formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') +handler.setFormatter(formatter) +logger.addHandler(handler) + + +def create_parser(): + parser = ap.ArgumentParser( + description=dedent( + """\ + Purpose: + This script is used to transform svg images into png + + Example usage: + + Transforming svg images into png using a source and a destination folder: + svg2png.py + --width 48 + --height 48 + --input /tmp/babs2 + --output ../app/static/images/babs2 + """ + ), + formatter_class=ap.RawDescriptionHelpFormatter + ) + + option_group = parser.add_argument_group('Program options') + option_group.add_argument( + '-I', + '--input', + dest='input', + action='store', + type=the_dir, + required=True, + help='The dir where the svg images are located' + ) + + option_group.add_argument( + '-O', + '--output', + dest='output', + action='store', + type=the_dir, + required=True, + help='The dir where the png images will be stored' + ) + + option_group.add_argument( + '-W', + '--width', + dest='width', + action='store', + default=None, + type=pixel_size, + help='The width in pixel of the png image' + ) + + option_group.add_argument( + '-H', + '--height', + dest='height', + action='store', + default=None, + type=pixel_size, + help='The width in pixel of the png image' + ) + + option_group.add_argument( + '-R', + '--dpi', + dest='dpi', + action='store', + default=92, + type=dpi, + help='The resolution of the png image' + ) + + option_group.add_argument( + '-D', + '--dryrun', + dest='dryrun', + action='store_false', + default=True, + help='The width in pixel of the png image' + ) + + return parser + + +def dpi(d): + d = float(d) # this may lead to an error, but that is ok + if d > 20: + return d + logger.error("The resolution has to be bigger than 20 dpi") + sys.exit(1) + + +def pixel_size(size): + size = float(size) # this may lead to an error, but that is ok + if size > 0.0: + return size + logger.error("size (width and heigh) has to be > 0") + sys.exit(1) + + +def the_dir(d): + if len(d) > 0: + return d + logger.error("the path has to be specified") + sys.exit(1) + + +def validate_args(argv): + parser = create_parser() + the_opts = parser.parse_args(argv[1:]) + return the_opts + + +def svg2png(): + # create output folder if not exists + if not os.path.exists(opts.output): + os.makedirs(opts.output) + + for file in os.listdir(opts.input): + if file.endswith(".svg"): + svg_image = os.path.join(opts.input, file) + png_image = os.path.join(opts.output, file[:-3] + 'png') + if opts.dryrun: + logger.debug("Treating image: %s > %s", svg_image, png_image) + cairosvg.svg2png( + dpi=opts.dpi, + file_obj=open(svg_image, "rb"), # pylint: disable=consider-using-with + write_to=png_image, + output_height=opts.height, + output_width=opts.width + ) + else: + logger.debug("dryrun image: %s > %s", svg_image, png_image) + + +def main(): + global opts # pylint: disable=global-variable-undefined + opts = validate_args(sys.argv) + svg2png() + + +if __name__ == '__main__': + main() From 07ac660450d914a6520df003b5c81d7da061d948 Mon Sep 17 00:00:00 2001 From: Lukas Joss Date: Wed, 31 Jan 2024 18:26:10 +0100 Subject: [PATCH 2/5] PB-264: Remove origin validation and make CORS header accept all origins --- app/__init__.py | 43 +------------------------------------------ 1 file changed, 1 insertion(+), 42 deletions(-) diff --git a/app/__init__.py b/app/__init__.py index bdb48a3..c1f079b 100644 --- a/app/__init__.py +++ b/app/__init__.py @@ -44,9 +44,7 @@ def add_cors_header(response): if request.endpoint == 'checker': return response - response.headers['Access-Control-Allow-Origin'] = request.host_url - if 'Origin' in request.headers and is_domain_allowed(request.headers['Origin']): - response.headers['Access-Control-Allow-Origin'] = request.headers['Origin'] + response.headers['Access-Control-Allow-Origin'] = "*" response.headers['Vary'] = 'Origin' response.headers['Access-Control-Allow-Methods'] = 'GET, HEAD, OPTIONS' response.headers['Access-Control-Allow-Headers'] = '*' @@ -62,45 +60,6 @@ def add_cache_control_header(response): response.headers.set('Cache-Control', CACHE_CONTROL) return response - -# Reject request from non allowed origins -@app.before_request -def validate_origin(): - # The Origin headers is automatically set by the browser and cannot be changed by the javascript - # application. Unfortunately this header is only set if the request comes from another origin. - # Sec-Fetch-Site header is set to `same-origin` by most of the browser except by Safari ! - # The best protection would be to use the Sec-Fetch-Site and Origin header, however this is - # not supported by Safari. Therefore we added a fallback to the Referer header for Safari. - sec_fetch_site = request.headers.get('Sec-Fetch-Site', None) - origin = request.headers.get('Origin', None) - referrer = request.headers.get('Referer', None) - - if origin is not None: - if is_domain_allowed(origin): - return - logger.error('Origin=%s does not match %s', origin, ALLOWED_DOMAINS_PATTERN) - abort(403, 'Permission denied') - - # BGDIINF_SB-3115: Apparently IOS 16 has a bug and set Sec-Fetch-Site=cross-site even if the - # request is originated (same origin and/or referrer) from the same site ! Therefore to avoid - # issue on IOS we first checks the referrer before checking Sec-Fetch-Site even if this not - # correct. - if referrer is not None: - if is_domain_allowed(referrer): - return - logger.error('Referer=%s does not match %s', referrer, ALLOWED_DOMAINS_PATTERN) - abort(403, 'Permission denied') - - if sec_fetch_site is not None: - if sec_fetch_site in ['same-origin', 'same-site']: - return - logger.error('Sec-Fetch-Site=%s is not allowed', sec_fetch_site) - abort(403, 'Permission denied') - - logger.error('Referer and/or Origin and/or Sec-Fetch-Site headers not set') - abort(403, 'Permission denied') - - @app.after_request def log_response(response): logger.info( From 5ba8f1e9a4f1a137db837260e7232bb94e61475d Mon Sep 17 00:00:00 2001 From: Lukas Joss Date: Wed, 31 Jan 2024 18:35:06 +0100 Subject: [PATCH 3/5] PB-264: Remove origin validation tests --- tests/unit_tests/test_all_icons.py | 19 ------------------- tests/unit_tests/test_checker.py | 6 ------ tests/unit_tests/test_icons.py | 10 ---------- 3 files changed, 35 deletions(-) diff --git a/tests/unit_tests/test_all_icons.py b/tests/unit_tests/test_all_icons.py index 3a261eb..0fd8bdd 100644 --- a/tests/unit_tests/test_all_icons.py +++ b/tests/unit_tests/test_all_icons.py @@ -109,25 +109,6 @@ def check_image( blue, average_color[2], delta=acceptable_color_delta, msg=error_message ) - @params( - None, - {'Origin': 'www.example'}, - { - 'Origin': 'www.example', 'Sec-Fetch-Site': 'cross-site' - }, - { - 'Origin': 'www.example', 'Sec-Fetch-Site': 'same-site' - }, - { - 'Origin': 'www.example', 'Sec-Fetch-Site': 'same-origin' - }, - {'Referer': 'http://www.example'}, - ) - def test_icon_set_origin_not_allowed(self, headers): - response = self.app.get(url_for('all_icon_sets'), headers=headers) - self.assertEqual(response.status_code, 403, msg="Domain restriction not applied") - self.assertCors(response) - @params( {'Origin': 'map.geo.admin.ch'}, { diff --git a/tests/unit_tests/test_checker.py b/tests/unit_tests/test_checker.py index 98fbca3..021193c 100644 --- a/tests/unit_tests/test_checker.py +++ b/tests/unit_tests/test_checker.py @@ -12,9 +12,3 @@ def test_checker(self): self.assertEqual(response.content_type, "application/json") self.assertNotIn('Cache-Control', response.headers) self.assertEqual(response.json, {"message": "OK", "success": True, "version": APP_VERSION}) - - def test_checker_denied_without_origin(self): - response = self.app.get(url_for('checker'), headers={"Origin": ""}) - self.check_response_not_allowed( - response, msg="Should return HTTP 403 when origin is not authorized", is_checker=True - ) diff --git a/tests/unit_tests/test_icons.py b/tests/unit_tests/test_icons.py index b75c1c4..d58cab8 100644 --- a/tests/unit_tests/test_icons.py +++ b/tests/unit_tests/test_icons.py @@ -81,16 +81,6 @@ def test_colorized_icon_non_existent_icon_name(self): } ) - def test_colorized_icon_http_header_origin_restriction(self): - response = self.request_colorized_icon(origin="www.dummy.com") - self.check_response_not_allowed( - response, msg="Should return HTTP 403 when origin is not authorized" - ) - response = self.request_colorized_icon(origin="") - self.check_response_not_allowed( - response, msg="Should return HTTP 403 when origin is not authorized" - ) - def test_colorized_icon_no_http_post_method_allowed_on_endpoint(self): response = self.app.post( url_for( From 32adf4e39325aeeac08fac4d7a699ede08ae2c70 Mon Sep 17 00:00:00 2001 From: Lukas Joss Date: Thu, 1 Feb 2024 09:32:58 +0100 Subject: [PATCH 4/5] PB-264: Remove CORS origin test --- app/__init__.py | 12 ++---------- app/settings.py | 1 - tests/unit_tests/base_test.py | 8 +------- 3 files changed, 3 insertions(+), 18 deletions(-) diff --git a/app/__init__.py b/app/__init__.py index c1f079b..db0250b 100644 --- a/app/__init__.py +++ b/app/__init__.py @@ -1,17 +1,14 @@ import logging -import re import time from werkzeug.exceptions import HTTPException from flask import Flask -from flask import abort from flask import g from flask import request from app.helpers import make_error_msg from app.helpers.service_icon_custom_serializer import CustomJSONEncoder -from app.settings import ALLOWED_DOMAINS_PATTERN from app.settings import CACHE_CONTROL from app.settings import CACHE_CONTROL_4XX @@ -25,12 +22,6 @@ app.json_encoder = CustomJSONEncoder -def is_domain_allowed(domain): - return re.match(ALLOWED_DOMAINS_PATTERN, domain) is not None - - -# NOTE it is better to have this method registered first (before validate_origin) otherwise -# the route might not be logged if another method reject the request. @app.before_request def log_route(): g.setdefault('started', time.time()) @@ -44,7 +35,7 @@ def add_cors_header(response): if request.endpoint == 'checker': return response - response.headers['Access-Control-Allow-Origin'] = "*" + response.headers['Access-Control-Allow-Origin'] = '*' response.headers['Vary'] = 'Origin' response.headers['Access-Control-Allow-Methods'] = 'GET, HEAD, OPTIONS' response.headers['Access-Control-Allow-Headers'] = '*' @@ -60,6 +51,7 @@ def add_cache_control_header(response): response.headers.set('Cache-Control', CACHE_CONTROL) return response + @app.after_request def log_response(response): logger.info( diff --git a/app/settings.py b/app/settings.py index de6f149..4d90c9d 100644 --- a/app/settings.py +++ b/app/settings.py @@ -20,6 +20,5 @@ # Definition of the allowed domains for CORS implementation ALLOWED_DOMAINS = os.getenv('ALLOWED_DOMAINS', r'.*').split(',') -ALLOWED_DOMAINS_PATTERN = f"({'|'.join(ALLOWED_DOMAINS)})" CACHE_CONTROL = os.getenv('CACHE_CONTROL', 'public, max-age=86400') CACHE_CONTROL_4XX = os.getenv('CACHE_CONTROL_4XX', 'public, max-age=3600') diff --git a/tests/unit_tests/base_test.py b/tests/unit_tests/base_test.py index 16e9c93..ebba20c 100644 --- a/tests/unit_tests/base_test.py +++ b/tests/unit_tests/base_test.py @@ -1,10 +1,8 @@ -import re import unittest from flask import url_for from app import app -from app.settings import ALLOWED_DOMAINS_PATTERN ORIGIN_FOR_TESTING = "some_random_domain" @@ -28,11 +26,7 @@ def tearDown(self): def assertCors(self, response): # pylint: disable=invalid-name self.assertIn('Access-Control-Allow-Origin', response.headers) - self.assertIsNotNone( - re.match(ALLOWED_DOMAINS_PATTERN, response.headers['Access-Control-Allow-Origin']), - msg=f"Access-Control-Allow-Origin={response.headers['Access-Control-Allow-Origin']} " - f"doesn't match {ALLOWED_DOMAINS_PATTERN}" - ) + self.assertEqual(response.headers['Access-Control-Allow-Origin'], '*') self.assertIn('Access-Control-Allow-Methods', response.headers) self.assertListEqual( sorted(['GET', 'HEAD', 'OPTIONS']), From 63034213c0873f143145584ce7983ea7eb95a6ab Mon Sep 17 00:00:00 2001 From: Lukas Joss Date: Thu, 1 Feb 2024 16:27:16 +0100 Subject: [PATCH 5/5] PB-264: Update Readme --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index 4f93a81..16044c5 100644 --- a/README.md +++ b/README.md @@ -184,7 +184,6 @@ The service is configured by Environment Variable: | Env | Default | Description | | ----------- | --------------------- | -------------------------- | | LOGGING_CFG | `logging-cfg-local.yml` | Logging configuration file | -| ALLOWED_DOMAINS | `.*` | Comma separated list of regex that are allowed as domain in Origin header | | CACHE_CONTROL | `public, max-age=86400` | Cache Control header value of the `GET /*` endpoints | | CACHE_CONTROL_4XX | `public, max-age=3600` | Cache Control header for 4XX responses | | FORWARED_ALLOW_IPS | `*` | Sets the gunicorn `forwarded_allow_ips`. See [Gunicorn Doc](https://docs.gunicorn.org/en/stable/settings.html#forwarded-allow-ips). This setting is required in order to `secure_scheme_headers` to work. |