Repository: KyleKing/calcipy (language: python)

Issue:
build: automated dependency upgrades
Full log: https://github.com/KyleKing/calcipy/actions/runs/2806655051


Discussion / hints:

Fix patch:
diff --git a/.calcipy_packaging.lock b/.calcipy_packaging.lock
index f00e17af..0f359f04 100644
--- a/.calcipy_packaging.lock
+++ b/.calcipy_packaging.lock
@@ -1,1688 +1,1704 @@
 {
+    "Babel": {
+        "datetime": "2022-06-16T06:31:20.746156+00:00",
+        "domain": "https://pypi.org/pypi/{name}/json",
+        "latest_datetime": "2022-06-16T06:31:20.746156+00:00",
+        "latest_version": "2.10.3",
+        "name": "Babel",
+        "version": "2.10.3"
+    },
+    "GitPython": {
+        "datetime": "2022-02-20T01:15:38.026645+00:00",
+        "domain": "https://pypi.org/pypi/{name}/json",
+        "latest_datetime": "2022-02-20T01:15:38.026645+00:00",
+        "latest_version": "3.1.27",
+        "name": "GitPython",
+        "version": "3.1.27"
+    },
+    "Jinja2": {
+        "datetime": "2022-04-28T17:21:25.336093+00:00",
+        "domain": "https://pypi.org/pypi/{name}/json",
+        "latest_datetime": "2022-04-28T17:21:25.336093+00:00",
+        "latest_version": "3.1.2",
+        "name": "Jinja2",
+        "version": "3.1.2"
+    },
+    "Mako": {
+        "datetime": "2022-08-29T18:03:52.207596+00:00",
+        "domain": "https://pypi.org/pypi/{name}/json",
+        "latest_datetime": "2022-08-29T18:03:52.207596+00:00",
+        "latest_version": "1.2.2",
+        "name": "Mako",
+        "version": "1.2.2"
+    },
+    "Markdown": {
+        "datetime": "2022-07-15T19:15:37.044395+00:00",
+        "domain": "https://pypi.org/pypi/{name}/json",
+        "latest_datetime": "2022-07-15T19:15:37.044395+00:00",
+        "latest_version": "3.4.1",
+        "name": "Markdown",
+        "version": "3.4.1"
+    },
+    "MarkupSafe": {
+        "datetime": "2022-03-15T13:22:05.942273+00:00",
+        "domain": "https://pypi.org/pypi/{name}/json",
+        "latest_datetime": "2022-03-15T13:22:05.942273+00:00",
+        "latest_version": "2.1.1",
+        "name": "MarkupSafe",
+        "version": "2.1.1"
+    },
+    "Pillow": {
+        "datetime": "2022-07-01T18:28:52.815507+00:00",
+        "domain": "https://pypi.org/pypi/{name}/json",
+        "latest_datetime": "2022-07-01T18:28:52.815507+00:00",
+        "latest_version": "9.2.0",
+        "name": "Pillow",
+        "version": "9.2.0"
+    },
+    "PyYAML": {
+        "datetime": "2021-10-13T19:39:42.916039+00:00",
+        "domain": "https://pypi.org/pypi/{name}/json",
+        "latest_datetime": "2021-10-13T19:39:42.916039+00:00",
+        "latest_version": "6.0",
+        "name": "PyYAML",
+        "version": "6.0"
+    },
+    "Pygments": {
+        "datetime": "2022-08-15T16:03:20.040931+00:00",
+        "domain": "https://pypi.org/pypi/{name}/json",
+        "latest_datetime": "2022-08-15T16:03:20.040931+00:00",
+        "latest_version": "2.13.0",
+        "name": "Pygments",
+        "version": "2.13.0"
+    },
     "absolufy-imports": {
-        "datetime": "2022-01-20T14:48:51.718037Z",
+        "datetime": "2022-01-20T14:48:51.718037+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2022-01-20T14:48:51.718037Z",
+        "latest_datetime": "2022-01-20T14:48:51.718037+00:00",
         "latest_version": "0.3.1",
         "name": "absolufy-imports",
         "version": "0.3.1"
     },
     "add-trailing-comma": {
-        "datetime": "2022-04-17T13:58:01.414145Z",
+        "datetime": "2022-04-17T13:58:01.414145+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2022-04-17T13:58:01.414145Z",
+        "latest_datetime": "2022-04-17T13:58:01.414145+00:00",
         "latest_version": "2.2.3",
         "name": "add-trailing-comma",
         "version": "2.2.3"
     },
     "argcomplete": {
-        "datetime": "2021-04-19T15:48:18.241321Z",
+        "datetime": "2021-04-19T15:48:18.241321+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2022-01-03T17:29:35.127698Z",
+        "latest_datetime": "2022-01-03T17:29:35.127698+00:00",
         "latest_version": "2.0.0",
         "name": "argcomplete",
         "version": "1.12.3"
     },
+    "arrow": {
+        "datetime": "2022-09-03T19:35:29.660994+00:00",
+        "domain": "https://pypi.org/pypi/{name}/json",
+        "latest_datetime": "2022-09-03T19:35:29.660994+00:00",
+        "latest_version": "1.2.3",
+        "name": "arrow",
+        "version": "1.2.3"
+    },
     "astor": {
-        "datetime": "2019-12-10T01:50:33.628982Z",
+        "datetime": "2019-12-10T01:50:33.628982+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2019-12-10T01:50:33.628982Z",
+        "latest_datetime": "2019-12-10T01:50:33.628982+00:00",
         "latest_version": "0.8.1",
         "name": "astor",
         "version": "0.8.1"
     },
     "astpretty": {
-        "datetime": "2022-05-16T23:41:23.422340Z",
+        "datetime": "2022-05-16T23:41:23.422340+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2022-05-16T23:41:23.422340Z",
+        "latest_datetime": "2022-05-16T23:41:23.422340+00:00",
         "latest_version": "3.0.0",
         "name": "astpretty",
         "version": "3.0.0"
     },
     "astroid": {
-        "datetime": "2022-07-09T14:50:59.226898Z",
+        "datetime": "2022-09-07T10:47:31.942794+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2022-07-12T08:26:33.483179Z",
-        "latest_version": "2.12.2",
+        "latest_datetime": "2022-09-07T10:47:31.942794+00:00",
+        "latest_version": "2.12.9",
         "name": "astroid",
-        "version": "2.11.7"
+        "version": "2.12.9"
     },
     "asttokens": {
-        "datetime": "2021-04-19T15:38:24.570187Z",
+        "datetime": "2022-08-15T10:49:50.230336+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2021-04-19T15:38:24.570187Z",
-        "latest_version": "2.0.5",
+        "latest_datetime": "2022-08-15T10:49:50.230336+00:00",
+        "latest_version": "2.0.8",
         "name": "asttokens",
-        "version": "2.0.5"
-    },
-    "atomicwrites": {
-        "datetime": "2022-07-08T18:31:40.459492Z",
-        "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2022-07-09T04:09:09.073080Z",
-        "latest_version": "1.4.0",
-        "name": "atomicwrites",
-        "version": "1.4.1"
+        "version": "2.0.8"
     },
     "attrs": {
-        "datetime": "2021-12-29T13:15:06.703351Z",
+        "datetime": "2021-12-29T13:15:06.703351+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2021-12-29T13:15:06.703351Z",
+        "latest_datetime": "2021-12-29T13:15:06.703351+00:00",
         "latest_version": "21.4.0",
         "name": "attrs",
         "version": "21.4.0"
     },
     "attrs-strict": {
-        "datetime": "2021-12-28T23:10:02.878548Z",
+        "datetime": "2021-12-28T23:10:02.878548+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2021-12-28T23:10:02.878548Z",
+        "latest_datetime": "2021-12-28T23:10:02.878548+00:00",
         "latest_version": "1.0.0",
         "name": "attrs-strict",
         "version": "1.0.0"
     },
     "autoflake": {
-        "datetime": "2020-08-23T01:20:55.487533Z",
+        "datetime": "2022-09-01T05:07:53.791347+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2020-08-23T01:20:55.487533Z",
-        "latest_version": "1.4",
+        "latest_datetime": "2022-09-01T05:07:53.791347+00:00",
+        "latest_version": "1.5.3",
         "name": "autoflake",
-        "version": "1.4"
+        "version": "1.5.3"
     },
     "autopep8": {
-        "datetime": "2021-10-24T06:47:35.952397Z",
+        "datetime": "2022-08-09T12:55:25.914554+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2021-10-24T06:47:35.952397Z",
-        "latest_version": "1.6.0",
+        "latest_datetime": "2022-08-09T12:55:25.914554+00:00",
+        "latest_version": "1.7.0",
         "name": "autopep8",
-        "version": "1.6.0"
-    },
-    "babel": {
-        "datetime": "2022-06-16T06:31:20.746156Z",
-        "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2022-06-16T06:31:20.746156Z",
-        "latest_version": "2.10.3",
-        "name": "babel",
-        "version": "2.10.3"
+        "version": "1.7.0"
     },
     "bandit": {
-        "datetime": "2022-03-04T07:43:44.165084Z",
+        "datetime": "2022-03-04T07:43:44.165084+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2022-03-04T07:43:44.165084Z",
+        "latest_datetime": "2022-03-04T07:43:44.165084+00:00",
         "latest_version": "1.7.4",
         "name": "bandit",
         "version": "1.7.4"
     },
     "beartype": {
-        "datetime": "2022-03-15T06:06:23.515331Z",
+        "datetime": "2022-03-15T06:06:23.515331+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2022-03-15T06:06:23.515331Z",
+        "latest_datetime": "2022-03-15T06:06:23.515331+00:00",
         "latest_version": "0.10.4",
         "name": "beartype",
         "version": "0.10.4"
     },
     "better-exceptions": {
-        "datetime": "2021-01-29T16:48:55.897166Z",
+        "datetime": "2021-01-29T16:48:55.897166+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2021-01-29T16:48:55.897166Z",
+        "latest_datetime": "2021-01-29T16:48:55.897166+00:00",
         "latest_version": "0.3.3",
         "name": "better-exceptions",
         "version": "0.3.3"
     },
     "bidict": {
-        "datetime": "2022-03-23T22:21:10.919267Z",
+        "datetime": "2022-03-23T22:21:10.919267+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2022-03-23T22:21:10.919267Z",
+        "latest_datetime": "2022-03-23T22:21:10.919267+00:00",
         "latest_version": "0.22.0",
         "name": "bidict",
         "version": "0.22.0"
     },
     "black": {
-        "datetime": "2022-06-28T02:24:58.717280Z",
+        "datetime": "2022-08-31T23:09:52.640122+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2022-06-28T02:24:58.717280Z",
-        "latest_version": "22.6.0",
+        "latest_datetime": "2022-08-31T23:09:52.640122+00:00",
+        "latest_version": "22.8.0",
         "name": "black",
-        "version": "22.6.0"
+        "version": "22.8.0"
     },
     "cement": {
-        "datetime": "2021-12-18T18:27:13.099741Z",
+        "datetime": "2022-08-18T19:10:40.137300+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2021-12-18T18:27:13.099741Z",
-        "latest_version": "3.0.6",
+        "latest_datetime": "2022-08-18T19:10:40.137300+00:00",
+        "latest_version": "3.0.8",
         "name": "cement",
-        "version": "3.0.6"
+        "version": "3.0.8"
     },
     "certifi": {
-        "datetime": "2022-06-15T18:09:18.491288Z",
+        "datetime": "2022-09-14T19:48:47.436198+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2022-06-15T18:09:18.491288Z",
-        "latest_version": "2022.6.15",
+        "latest_datetime": "2022-09-14T19:48:47.436198+00:00",
+        "latest_version": "2022.9.14",
         "name": "certifi",
-        "version": "2022.6.15"
+        "version": "2022.9.14"
     },
     "cfgv": {
-        "datetime": "2021-08-25T14:18:47.770979Z",
+        "datetime": "2021-08-25T14:18:47.770979+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2021-08-25T14:18:47.770979Z",
+        "latest_datetime": "2021-08-25T14:18:47.770979+00:00",
         "latest_version": "3.3.1",
         "name": "cfgv",
         "version": "3.3.1"
     },
     "chardet": {
-        "datetime": "2022-06-25T04:27:55.457436Z",
+        "datetime": "2022-06-25T04:27:55.457436+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2022-06-25T04:27:55.457436Z",
+        "latest_datetime": "2022-06-25T04:27:55.457436+00:00",
         "latest_version": "5.0.0",
         "name": "chardet",
         "version": "5.0.0"
     },
     "charset-normalizer": {
-        "datetime": "2022-06-19T22:03:21.542597Z",
+        "datetime": "2022-08-19T22:13:46.702012+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2022-06-19T22:03:21.542597Z",
-        "latest_version": "2.1.0",
+        "latest_datetime": "2022-08-21T20:43:15.502309+00:00",
+        "latest_version": "3.0.0b2",
         "name": "charset-normalizer",
-        "version": "2.1.0"
+        "version": "2.1.1"
     },
     "click": {
-        "datetime": "2022-04-28T17:36:06.952869Z",
+        "datetime": "2022-04-28T17:36:06.952869+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2022-04-28T17:36:06.952869Z",
+        "latest_datetime": "2022-04-28T17:36:06.952869+00:00",
         "latest_version": "8.1.3",
         "name": "click",
         "version": "8.1.3"
     },
     "cloudpickle": {
-        "datetime": "2022-05-20T15:36:32.997460Z",
+        "datetime": "2022-09-07T16:12:56.619702+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2022-05-20T15:36:32.997460Z",
-        "latest_version": "2.1.0",
+        "latest_datetime": "2022-09-07T16:12:56.619702+00:00",
+        "latest_version": "2.2.0",
         "name": "cloudpickle",
-        "version": "2.1.0"
+        "version": "2.2.0"
     },
     "cognitive-complexity": {
-        "datetime": "2020-07-22T05:41:30.898464Z",
+        "datetime": "2022-08-09T07:07:52.952140+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2020-07-22T05:41:30.898464Z",
-        "latest_version": "1.2.0",
+        "latest_datetime": "2022-08-09T07:07:52.952140+00:00",
+        "latest_version": "1.3.0",
         "name": "cognitive-complexity",
-        "version": "1.2.0"
+        "version": "1.3.0"
     },
     "cohesion": {
-        "datetime": "2019-07-10T16:08:05.792036Z",
+        "datetime": "2019-07-10T16:08:05.792036+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2019-07-10T16:08:05.792036Z",
+        "latest_datetime": "2019-07-10T16:08:05.792036+00:00",
         "latest_version": "1.0.0",
         "name": "cohesion",
         "version": "1.0.0"
     },
     "colorama": {
-        "datetime": "2022-06-16T12:34:45.998806Z",
+        "datetime": "2022-06-16T12:34:45.998806+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2022-06-16T12:34:45.998806Z",
+        "latest_datetime": "2022-06-16T12:34:45.998806+00:00",
         "latest_version": "0.4.5",
         "name": "colorama",
         "version": "0.4.5"
     },
     "colorlog": {
-        "datetime": "2021-11-08T16:56:43.532533Z",
+        "datetime": "2022-08-29T14:51:26.426268+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2021-11-08T16:56:43.532533Z",
-        "latest_version": "6.6.0",
+        "latest_datetime": "2022-08-29T14:51:26.426268+00:00",
+        "latest_version": "6.7.0",
         "name": "colorlog",
-        "version": "6.6.0"
+        "version": "6.7.0"
     },
     "commitizen": {
-        "datetime": "2022-08-02T16:11:27.933712Z",
+        "datetime": "2022-09-15T13:26:53.162927+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2022-08-02T16:11:27.933712Z",
-        "latest_version": "2.29.3",
+        "latest_datetime": "2022-09-15T13:26:53.162927+00:00",
+        "latest_version": "2.33.0",
         "name": "commitizen",
-        "version": "2.29.3"
+        "version": "2.33.0"
     },
     "commonmark": {
-        "datetime": "2019-10-04T15:37:37.674968Z",
+        "datetime": "2019-10-04T15:37:37.674968+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2019-10-04T15:37:37.674968Z",
+        "latest_datetime": "2019-10-04T15:37:37.674968+00:00",
         "latest_version": "0.9.1",
         "name": "commonmark",
         "version": "0.9.1"
     },
     "coverage": {
-        "datetime": "2022-07-12T13:42:03.736645Z",
+        "datetime": "2022-08-16T14:39:11.951468+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2022-07-12T13:42:03.736645Z",
-        "latest_version": "6.4.2",
+        "latest_datetime": "2022-08-16T14:39:11.951468+00:00",
+        "latest_version": "6.4.4",
         "name": "coverage",
-        "version": "6.4.2"
+        "version": "6.4.4"
     },
     "cycler": {
-        "datetime": "2021-10-29T03:40:55.140371Z",
+        "datetime": "2021-10-29T03:40:55.140371+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2021-10-29T03:40:55.140371Z",
+        "latest_datetime": "2021-10-29T03:40:55.140371+00:00",
         "latest_version": "0.11.0",
         "name": "cycler",
         "version": "0.11.0"
     },
     "cz-legacy": {
-        "datetime": "2022-02-18T21:01:09.403199Z",
+        "datetime": "2022-02-18T21:01:09.403199+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2022-02-18T21:01:09.403199Z",
+        "latest_datetime": "2022-02-18T21:01:09.403199+00:00",
         "latest_version": "0.1.6",
         "name": "cz-legacy",
         "version": "0.1.6"
     },
     "darglint": {
-        "datetime": "2021-10-18T03:40:35.034675Z",
+        "datetime": "2021-10-18T03:40:35.034675+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2021-10-18T03:40:35.034675Z",
+        "latest_datetime": "2021-10-18T03:40:35.034675+00:00",
         "latest_version": "1.8.1",
         "name": "darglint",
         "version": "1.8.1"
     },
     "decli": {
-        "datetime": "2020-07-26T08:29:41.079082Z",
+        "datetime": "2020-07-26T08:29:41.079082+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2020-07-26T08:29:41.079082Z",
+        "latest_datetime": "2020-07-26T08:29:41.079082+00:00",
         "latest_version": "0.5.2",
         "name": "decli",
         "version": "0.5.2"
     },
     "decorator": {
-        "datetime": "2022-01-07T08:20:03.734182Z",
+        "datetime": "2022-01-07T08:20:03.734182+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2022-01-07T08:20:03.734182Z",
+        "latest_datetime": "2022-01-07T08:20:03.734182+00:00",
         "latest_version": "5.1.1",
         "name": "decorator",
         "version": "5.1.1"
     },
     "dictdiffer": {
-        "datetime": "2021-07-22T13:24:26.783705Z",
+        "datetime": "2021-07-22T13:24:26.783705+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2021-07-22T13:24:26.783705Z",
+        "latest_datetime": "2021-07-22T13:24:26.783705+00:00",
         "latest_version": "0.9.0",
         "name": "dictdiffer",
         "version": "0.9.0"
     },
     "diff-cover": {
-        "datetime": "2022-06-22T22:07:50.268916Z",
+        "datetime": "2022-06-22T22:07:50.268916+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2022-06-22T22:07:50.268916Z",
+        "latest_datetime": "2022-06-22T22:07:50.268916+00:00",
         "latest_version": "6.5.1",
         "name": "diff-cover",
         "version": "6.5.1"
     },
     "dill": {
-        "datetime": "2022-05-20T11:21:11.969466Z",
+        "datetime": "2022-05-20T11:21:11.969466+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2022-05-20T11:21:11.969466Z",
+        "latest_datetime": "2022-05-20T11:21:11.969466+00:00",
         "latest_version": "0.3.5.1",
         "name": "dill",
         "version": "0.3.5.1"
     },
     "distlib": {
-        "datetime": "2022-07-14T14:28:17.414852Z",
+        "datetime": "2022-08-26T10:01:06.957924+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2022-07-14T14:28:17.414852Z",
-        "latest_version": "0.3.5",
+        "latest_datetime": "2022-08-26T10:01:06.957924+00:00",
+        "latest_version": "0.3.6",
         "name": "distlib",
-        "version": "0.3.5"
+        "version": "0.3.6"
     },
     "dlint": {
-        "datetime": "2021-10-27T13:15:42.845122Z",
+        "datetime": "2022-08-09T19:13:47.552744+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2021-10-27T13:15:42.845122Z",
-        "latest_version": "0.12.0",
+        "latest_datetime": "2022-08-09T19:13:47.552744+00:00",
+        "latest_version": "0.13.0",
         "name": "dlint",
-        "version": "0.12.0"
+        "version": "0.13.0"
     },
     "docstring-parser": {
-        "datetime": "2020-09-19T11:51:11.452731Z",
+        "datetime": "2020-09-19T11:51:11.452731+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2022-04-27T08:32:40.566840Z",
+        "latest_datetime": "2022-04-27T08:32:40.566840+00:00",
         "latest_version": "0.14.1",
         "name": "docstring-parser",
         "version": "0.7.3"
     },
     "doit": {
-        "datetime": "2022-04-22T15:33:23.165732Z",
+        "datetime": "2022-04-22T15:33:23.165732+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2022-04-22T15:33:23.165732Z",
+        "latest_datetime": "2022-04-22T15:33:23.165732+00:00",
         "latest_version": "0.36.0",
         "name": "doit",
         "version": "0.36.0"
     },
     "eradicate": {
-        "datetime": "2022-04-06T09:47:11.609069Z",
+        "datetime": "2022-04-06T09:47:11.609069+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2022-04-06T09:47:11.609069Z",
+        "latest_datetime": "2022-04-06T09:47:11.609069+00:00",
         "latest_version": "2.1.0",
         "name": "eradicate",
         "version": "2.1.0"
     },
     "exceptiongroup": {
-        "datetime": "2022-06-08T07:39:07.055347Z",
+        "datetime": "2022-08-28T12:51:21.543031+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2022-06-08T07:39:07.055347Z",
-        "latest_version": "1.0.0rc8",
+        "latest_datetime": "2022-08-28T12:51:21.543031+00:00",
+        "latest_version": "1.0.0rc9",
         "name": "exceptiongroup",
-        "version": "1.0.0rc8"
+        "version": "1.0.0rc9"
     },
     "falcon": {
-        "datetime": "2019-04-26T18:26:34.046785Z",
+        "datetime": "2019-04-26T18:26:34.046785+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2022-03-25T16:21:09.243363Z",
+        "latest_datetime": "2022-03-25T16:21:09.243363+00:00",
         "latest_version": "3.1.0",
         "name": "falcon",
         "version": "2.0.0"
     },
     "fancycompleter": {
-        "datetime": "2020-02-04T13:30:08.106140Z",
+        "datetime": "2020-02-04T13:30:08.106140+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2020-02-04T13:30:08.106140Z",
+        "latest_datetime": "2020-02-04T13:30:08.106140+00:00",
         "latest_version": "0.9.1",
         "name": "fancycompleter",
         "version": "0.9.1"
     },
     "fhconfparser": {
-        "datetime": "2022-01-27T23:43:18.076209Z",
+        "datetime": "2022-01-27T23:43:18.076209+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2022-01-27T23:43:18.076209Z",
+        "latest_datetime": "2022-01-27T23:43:18.076209+00:00",
         "latest_version": "2022",
         "name": "fhconfparser",
         "version": "2022"
     },
     "filelock": {
-        "datetime": "2022-05-31T20:21:36.753203Z",
+        "datetime": "2022-08-10T06:44:31.148232+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2022-05-31T20:21:36.753203Z",
-        "latest_version": "3.7.1",
+        "latest_datetime": "2022-08-10T06:44:31.148232+00:00",
+        "latest_version": "3.8.0",
         "name": "filelock",
-        "version": "3.7.1"
+        "version": "3.8.0"
     },
     "flake8": {
-        "datetime": "2021-10-11T12:42:47.401147Z",
+        "datetime": "2022-08-03T23:21:25.027788+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2022-08-03T23:21:25.027788Z",
+        "latest_datetime": "2022-08-03T23:21:25.027788+00:00",
         "latest_version": "5.0.4",
         "name": "flake8",
-        "version": "4.0.1"
+        "version": "5.0.4"
     },
     "flake8-2020": {
-        "datetime": "2021-11-30T01:32:26.232768Z",
+        "datetime": "2022-08-01T16:36:11.135730+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2021-11-30T01:32:26.232768Z",
-        "latest_version": "1.6.1",
+        "latest_datetime": "2022-08-01T16:36:11.135730+00:00",
+        "latest_version": "1.7.0",
         "name": "flake8-2020",
-        "version": "1.6.1"
+        "version": "1.7.0"
+    },
+    "flake8-SQL": {
+        "datetime": "2020-06-27T20:18:47.766579+00:00",
+        "domain": "https://pypi.org/pypi/{name}/json",
+        "latest_datetime": "2020-06-27T20:18:47.766579+00:00",
+        "latest_version": "0.4.1",
+        "name": "flake8-SQL",
+        "version": "0.4.1"
     },
     "flake8-aaa": {
-        "datetime": "2022-01-02T20:48:16.423427Z",
+        "datetime": "2022-01-02T20:48:16.423427+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2022-01-02T20:48:16.423427Z",
+        "latest_datetime": "2022-01-02T20:48:16.423427+00:00",
         "latest_version": "0.12.2",
         "name": "flake8-aaa",
         "version": "0.12.2"
     },
     "flake8-annotations": {
-        "datetime": "2022-08-01T19:01:19.932257Z",
+        "datetime": "2022-08-01T19:01:19.932257+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2022-08-01T19:01:19.932257Z",
+        "latest_datetime": "2022-08-01T19:01:19.932257+00:00",
         "latest_version": "2.9.1",
         "name": "flake8-annotations",
         "version": "2.9.1"
     },
     "flake8-assertive": {
-        "datetime": "2022-03-15T22:37:33.137191Z",
+        "datetime": "2022-03-15T22:37:33.137191+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2022-03-15T22:37:33.137191Z",
+        "latest_datetime": "2022-03-15T22:37:33.137191+00:00",
         "latest_version": "2.1.0",
         "name": "flake8-assertive",
         "version": "2.1.0"
     },
     "flake8-bandit": {
-        "datetime": "2022-03-11T03:32:21.684665Z",
+        "datetime": "2022-08-29T13:48:39.737386+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2022-03-11T03:32:21.684665Z",
-        "latest_version": "3.0.0",
+        "latest_datetime": "2022-08-29T13:48:39.737386+00:00",
+        "latest_version": "4.1.1",
         "name": "flake8-bandit",
-        "version": "3.0.0"
+        "version": "4.1.1"
     },
     "flake8-blind-except": {
-        "datetime": "2022-03-18T16:49:13.002213Z",
+        "datetime": "2022-03-18T16:49:13.002213+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2022-03-18T16:49:13.002213Z",
+        "latest_datetime": "2022-03-18T16:49:13.002213+00:00",
         "latest_version": "0.2.1",
         "name": "flake8-blind-except",
         "version": "0.2.1"
     },
     "flake8-breakpoint": {
-        "datetime": "2019-05-23T11:41:37.151630Z",
+        "datetime": "2019-05-23T11:41:37.151630+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2019-05-23T11:41:37.151630Z",
+        "latest_datetime": "2019-05-23T11:41:37.151630+00:00",
         "latest_version": "1.1.0",
         "name": "flake8-breakpoint",
         "version": "1.1.0"
     },
     "flake8-broken-line": {
-        "datetime": "2021-10-19T12:54:12.064681Z",
+        "datetime": "2022-08-11T07:10:07.447259+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2021-10-19T12:54:12.064681Z",
-        "latest_version": "0.4.0",
+        "latest_datetime": "2022-08-11T07:10:07.447259+00:00",
+        "latest_version": "0.5.0",
         "name": "flake8-broken-line",
-        "version": "0.4.0"
+        "version": "0.5.0"
     },
     "flake8-bugbear": {
-        "datetime": "2022-07-01T18:02:11.046963Z",
+        "datetime": "2022-09-11T19:15:31.013333+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2022-07-01T18:02:11.046963Z",
-        "latest_version": "22.7.1",
+        "latest_datetime": "2022-09-11T19:15:31.013333+00:00",
+        "latest_version": "22.9.11",
         "name": "flake8-bugbear",
-        "version": "22.7.1"
+        "version": "22.9.11"
     },
     "flake8-builtins": {
-        "datetime": "2020-05-14T10:45:01.642922Z",
+        "datetime": "2020-05-14T10:45:01.642922+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2020-05-14T10:45:01.642922Z",
+        "latest_datetime": "2020-05-14T10:45:01.642922+00:00",
         "latest_version": "1.5.3",
         "name": "flake8-builtins",
         "version": "1.5.3"
     },
     "flake8-cognitive-complexity": {
-        "datetime": "2020-08-01T05:49:18.353486Z",
+        "datetime": "2020-08-01T05:49:18.353486+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2020-08-01T05:49:18.353486Z",
+        "latest_datetime": "2020-08-01T05:49:18.353486+00:00",
         "latest_version": "0.1.0",
         "name": "flake8-cognitive-complexity",
         "version": "0.1.0"
     },
     "flake8-comprehensions": {
-        "datetime": "2022-05-19T09:53:53.883664Z",
+        "datetime": "2022-05-19T09:53:53.883664+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2022-05-19T09:53:53.883664Z",
+        "latest_datetime": "2022-05-19T09:53:53.883664+00:00",
         "latest_version": "3.10.0",
         "name": "flake8-comprehensions",
         "version": "3.10.0"
     },
     "flake8-debugger": {
-        "datetime": "2022-04-30T16:50:57.294514Z",
+        "datetime": "2022-04-30T16:50:57.294514+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2022-04-30T16:50:57.294514Z",
+        "latest_datetime": "2022-04-30T16:50:57.294514+00:00",
         "latest_version": "4.1.2",
         "name": "flake8-debugger",
         "version": "4.1.2"
     },
     "flake8-docstrings": {
-        "datetime": "2021-03-19T00:57:12.120470Z",
+        "datetime": "2021-03-19T00:57:12.120470+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2021-03-19T00:57:12.120470Z",
+        "latest_datetime": "2021-03-19T00:57:12.120470+00:00",
         "latest_version": "1.6.0",
         "name": "flake8-docstrings",
         "version": "1.6.0"
     },
     "flake8-eradicate": {
-        "datetime": "2022-04-26T07:35:19.944044Z",
+        "datetime": "2022-08-11T07:16:46.028643+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2022-04-26T07:35:19.944044Z",
-        "latest_version": "1.2.1",
+        "latest_datetime": "2022-08-11T07:16:46.028643+00:00",
+        "latest_version": "1.3.0",
         "name": "flake8-eradicate",
-        "version": "1.2.1"
+        "version": "1.3.0"
     },
     "flake8-expression-complexity": {
-        "datetime": "2022-03-19T07:13:03.128527Z",
+        "datetime": "2022-03-19T07:13:03.128527+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2022-03-19T07:13:03.128527Z",
+        "latest_datetime": "2022-03-19T07:13:03.128527+00:00",
         "latest_version": "0.0.11",
         "name": "flake8-expression-complexity",
         "version": "0.0.11"
     },
     "flake8-fixme": {
-        "datetime": "2019-05-06T19:06:44.658390Z",
+        "datetime": "2019-05-06T19:06:44.658390+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2019-05-06T19:06:44.658390Z",
+        "latest_datetime": "2019-05-06T19:06:44.658390+00:00",
         "latest_version": "1.1.1",
         "name": "flake8-fixme",
         "version": "1.1.1"
     },
     "flake8-functions": {
-        "datetime": "2022-02-24T10:34:11.139289Z",
+        "datetime": "2022-02-24T10:34:11.139289+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2022-02-24T10:34:11.139289Z",
+        "latest_datetime": "2022-02-24T10:34:11.139289+00:00",
         "latest_version": "0.0.7",
         "name": "flake8-functions",
         "version": "0.0.7"
     },
     "flake8-isort": {
-        "datetime": "2022-08-04T16:53:10.852639Z",
+        "datetime": "2022-08-04T16:53:10.852639+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2022-08-04T16:53:10.852639Z",
+        "latest_datetime": "2022-08-04T16:53:10.852639+00:00",
         "latest_version": "4.2.0",
         "name": "flake8-isort",
         "version": "4.2.0"
     },
     "flake8-logging-format": {
-        "datetime": "2019-01-10T17:24:16.976076Z",
+        "datetime": "2022-08-18T16:12:15.323433+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2019-01-10T17:24:16.976076Z",
-        "latest_version": "0.6.0",
+        "latest_datetime": "2022-08-18T16:12:15.323433+00:00",
+        "latest_version": "0.7.5",
         "name": "flake8-logging-format",
-        "version": "0.6.0"
+        "version": "0.7.5"
     },
     "flake8-markdown": {
-        "datetime": "2021-10-20T01:32:56.721125Z",
+        "datetime": "2022-09-11T16:18:40.876213+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2021-10-20T01:32:56.721125Z",
-        "latest_version": "0.3.0",
+        "latest_datetime": "2022-09-11T16:18:40.876213+00:00",
+        "latest_version": "0.4.0",
         "name": "flake8-markdown",
-        "version": "0.3.0"
+        "version": "0.4.0"
     },
     "flake8-pep3101": {
-        "datetime": "2019-12-14T23:32:14.814800Z",
+        "datetime": "2019-12-14T23:32:14.814800+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2019-12-14T23:32:14.814800Z",
+        "latest_datetime": "2019-12-14T23:32:14.814800+00:00",
         "latest_version": "1.3.0",
         "name": "flake8-pep3101",
         "version": "1.3.0"
     },
     "flake8-plone-hasattr": {
-        "datetime": "2017-05-31T21:17:18.249556Z",
+        "datetime": "2017-05-31T21:17:18.249556+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2017-05-31T21:17:18.249556Z",
+        "latest_datetime": "2017-05-31T21:17:18.249556+00:00",
         "latest_version": "0.2.post0",
         "name": "flake8-plone-hasattr",
         "version": "0.2.post0"
     },
     "flake8-plugin-utils": {
-        "datetime": "2021-05-05T08:48:55.106877Z",
+        "datetime": "2021-05-05T08:48:55.106877+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2021-05-05T08:48:55.106877Z",
+        "latest_datetime": "2021-05-05T08:48:55.106877+00:00",
         "latest_version": "1.3.2",
         "name": "flake8-plugin-utils",
         "version": "1.3.2"
     },
-    "flake8-polyfill": {
-        "datetime": "2017-12-30T13:46:54.790861Z",
-        "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2017-12-30T13:46:54.790861Z",
-        "latest_version": "1.0.2",
-        "name": "flake8-polyfill",
-        "version": "1.0.2"
-    },
     "flake8-print": {
-        "datetime": "2022-04-30T16:19:24.307875Z",
+        "datetime": "2022-04-30T16:19:24.307875+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2022-04-30T16:19:24.307875Z",
+        "latest_datetime": "2022-04-30T16:19:24.307875+00:00",
         "latest_version": "5.0.0",
         "name": "flake8-print",
         "version": "5.0.0"
     },
     "flake8-printf-formatting": {
-        "datetime": "2021-02-01T02:14:58.801285Z",
+        "datetime": "2021-02-01T02:14:58.801285+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2021-02-01T02:14:58.801285Z",
+        "latest_datetime": "2021-02-01T02:14:58.801285+00:00",
         "latest_version": "1.1.2",
         "name": "flake8-printf-formatting",
         "version": "1.1.2"
     },
     "flake8-pytest-style": {
-        "datetime": "2021-12-22T21:21:36.504893Z",
+        "datetime": "2021-12-22T21:21:36.504893+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2021-12-22T21:21:36.504893Z",
+        "latest_datetime": "2021-12-22T21:21:36.504893+00:00",
         "latest_version": "1.6.0",
         "name": "flake8-pytest-style",
         "version": "1.6.0"
     },
     "flake8-quotes": {
-        "datetime": "2021-10-19T07:07:05.060916Z",
+        "datetime": "2021-10-19T07:07:05.060916+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2021-10-19T07:07:05.060916Z",
+        "latest_datetime": "2021-10-19T07:07:05.060916+00:00",
         "latest_version": "3.3.1",
         "name": "flake8-quotes",
         "version": "3.3.1"
     },
     "flake8-return": {
-        "datetime": "2021-05-05T09:22:16.053801Z",
+        "datetime": "2021-05-05T09:22:16.053801+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2021-05-05T09:22:16.053801Z",
+        "latest_datetime": "2021-05-05T09:22:16.053801+00:00",
         "latest_version": "1.1.3",
         "name": "flake8-return",
         "version": "1.1.3"
     },
     "flake8-simplify": {
-        "datetime": "2022-07-28T16:32:34.948924Z",
+        "datetime": "2022-07-28T16:32:34.948924+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2022-07-28T16:32:34.948924Z",
+        "latest_datetime": "2022-07-28T16:32:34.948924+00:00",
         "latest_version": "0.19.3",
         "name": "flake8-simplify",
         "version": "0.19.3"
     },
-    "flake8-sql": {
-        "datetime": "2020-06-27T20:18:47.766579Z",
-        "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2020-06-27T20:18:47.766579Z",
-        "latest_version": "0.4.1",
-        "name": "flake8-sql",
-        "version": "0.4.1"
-    },
     "flake8-string-format": {
-        "datetime": "2020-02-16T15:27:49.327646Z",
+        "datetime": "2020-02-16T15:27:49.327646+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2020-02-16T15:27:49.327646Z",
+        "latest_datetime": "2020-02-16T15:27:49.327646+00:00",
         "latest_version": "0.3.0",
         "name": "flake8-string-format",
         "version": "0.3.0"
     },
     "flake8-tuple": {
-        "datetime": "2020-11-15T20:00:10.175970Z",
+        "datetime": "2020-11-15T20:00:10.175970+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2020-11-15T20:00:10.175970Z",
+        "latest_datetime": "2020-11-15T20:00:10.175970+00:00",
         "latest_version": "0.4.1",
         "name": "flake8-tuple",
         "version": "0.4.1"
     },
     "flake8-variables-names": {
-        "datetime": "2022-02-24T12:39:55.482580Z",
+        "datetime": "2022-02-24T12:39:55.482580+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2022-02-24T12:39:55.482580Z",
+        "latest_datetime": "2022-02-24T12:39:55.482580+00:00",
         "latest_version": "0.0.5",
         "name": "flake8-variables-names",
         "version": "0.0.5"
     },
     "fonttools": {
-        "datetime": "2022-07-07T21:39:06.454991Z",
+        "datetime": "2022-09-15T17:30:00.764022+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2022-07-07T21:39:06.454991Z",
-        "latest_version": "4.34.4",
+        "latest_datetime": "2022-09-15T17:30:00.764022+00:00",
+        "latest_version": "4.37.2",
         "name": "fonttools",
-        "version": "4.34.4"
+        "version": "4.37.2"
     },
     "future": {
-        "datetime": "2019-10-31T00:58:13.043307Z",
+        "datetime": "2019-10-31T00:58:13.043307+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2020-11-24T01:25:44.581618Z",
+        "latest_datetime": "2020-11-24T01:25:44.581618+00:00",
         "latest_version": "0.18.0",
         "name": "future",
         "version": "0.18.2"
     },
     "ghp-import": {
-        "datetime": "2022-05-02T15:47:14.552377Z",
+        "datetime": "2022-05-02T15:47:14.552377+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2022-05-02T15:47:14.552377Z",
+        "latest_datetime": "2022-05-02T15:47:14.552377+00:00",
         "latest_version": "2.1.0",
         "name": "ghp-import",
         "version": "2.1.0"
     },
     "gitdb": {
-        "datetime": "2021-10-24T13:40:41.887593Z",
+        "datetime": "2021-10-24T13:40:41.887593+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2021-10-24T13:40:41.887593Z",
+        "latest_datetime": "2021-10-24T13:40:41.887593+00:00",
         "latest_version": "4.0.9",
         "name": "gitdb",
         "version": "4.0.9"
     },
-    "gitpython": {
-        "datetime": "2022-02-20T01:15:38.026645Z",
-        "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2022-02-20T01:15:38.026645Z",
-        "latest_version": "3.1.27",
-        "name": "gitpython",
-        "version": "3.1.27"
-    },
     "hug": {
-        "datetime": "2020-02-06T18:13:37.987522Z",
+        "datetime": "2020-02-06T18:13:37.987522+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2020-02-06T18:13:37.987522Z",
+        "latest_datetime": "2020-02-06T18:13:37.987522+00:00",
         "latest_version": "2.6.1",
         "name": "hug",
         "version": "2.6.1"
     },
     "hypothesis": {
-        "datetime": "2022-08-02T07:05:22.323135Z",
+        "datetime": "2022-09-05T04:51:17.605468+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2022-08-02T07:05:22.323135Z",
-        "latest_version": "6.54.1",
+        "latest_datetime": "2022-09-05T04:51:17.605468+00:00",
+        "latest_version": "6.54.5",
         "name": "hypothesis",
-        "version": "6.54.1"
+        "version": "6.54.5"
     },
     "identify": {
-        "datetime": "2022-08-03T22:51:39.028061Z",
+        "datetime": "2022-09-06T12:37:06.753575+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2022-08-03T22:51:39.028061Z",
-        "latest_version": "2.5.3",
+        "latest_datetime": "2022-09-06T12:37:06.753575+00:00",
+        "latest_version": "2.5.5",
         "name": "identify",
-        "version": "2.5.3"
+        "version": "2.5.5"
     },
     "idna": {
-        "datetime": "2021-10-12T23:33:38.020888Z",
+        "datetime": "2022-09-14T00:24:23.220218+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2021-10-12T23:33:38.020888Z",
-        "latest_version": "3.3",
+        "latest_datetime": "2022-09-14T00:24:23.220218+00:00",
+        "latest_version": "3.4",
         "name": "idna",
-        "version": "3.3"
+        "version": "3.4"
     },
     "implements": {
-        "datetime": "2021-02-17T14:40:03.034474Z",
+        "datetime": "2021-02-17T14:40:03.034474+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2021-02-17T14:40:03.034474Z",
+        "latest_datetime": "2021-02-17T14:40:03.034474+00:00",
         "latest_version": "0.3.0",
         "name": "implements",
         "version": "0.3.0"
     },
     "importlib-metadata": {
-        "datetime": "2022-06-25T17:01:22.940893Z",
+        "datetime": "2022-06-25T17:01:22.940893+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2022-06-25T17:01:22.940893Z",
+        "latest_datetime": "2022-06-25T17:01:22.940893+00:00",
         "latest_version": "4.12.0",
         "name": "importlib-metadata",
         "version": "4.12.0"
     },
     "iniconfig": {
-        "datetime": "2020-10-16T17:37:23.050185Z",
+        "datetime": "2020-10-16T17:37:23.050185+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2020-10-16T17:37:23.050185Z",
+        "latest_datetime": "2020-10-16T17:37:23.050185+00:00",
         "latest_version": "1.1.1",
         "name": "iniconfig",
         "version": "1.1.1"
     },
     "isort": {
-        "datetime": "2021-11-09T05:42:44.651721Z",
+        "datetime": "2021-11-09T05:42:44.651721+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2021-11-09T05:42:44.651721Z",
+        "latest_datetime": "2021-11-09T05:42:44.651721+00:00",
         "latest_version": "5.10.1",
         "name": "isort",
         "version": "5.10.1"
     },
-    "jinja2": {
-        "datetime": "2022-04-28T17:21:25.336093Z",
-        "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2022-04-28T17:21:25.336093Z",
-        "latest_version": "3.1.2",
-        "name": "jinja2",
-        "version": "3.1.2"
-    },
     "kiwisolver": {
-        "datetime": "2022-07-15T20:37:00.009703Z",
+        "datetime": "2022-07-15T20:37:00.009703+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2022-07-15T20:37:00.009703Z",
+        "latest_datetime": "2022-07-15T20:37:00.009703+00:00",
         "latest_version": "1.4.4",
         "name": "kiwisolver",
         "version": "1.4.4"
     },
     "lazy-object-proxy": {
-        "datetime": "2021-12-15T16:56:08.192891Z",
+        "datetime": "2021-12-15T16:56:08.192891+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2021-12-15T16:56:08.192891Z",
+        "latest_datetime": "2021-12-15T16:56:08.192891+00:00",
         "latest_version": "1.7.1",
         "name": "lazy-object-proxy",
         "version": "1.7.1"
     },
     "libcst": {
-        "datetime": "2022-07-12T15:12:04.492477Z",
+        "datetime": "2022-07-12T15:12:04.492477+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2022-07-12T15:12:04.492477Z",
+        "latest_datetime": "2022-07-12T15:12:04.492477+00:00",
         "latest_version": "0.4.7",
         "name": "libcst",
         "version": "0.4.7"
     },
     "licensecheck": {
-        "datetime": "2022-04-09T17:01:30.268809Z",
+        "datetime": "2022-04-09T17:01:30.268809+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2022-04-09T17:01:30.268809Z",
+        "latest_datetime": "2022-04-09T17:01:30.268809+00:00",
         "latest_version": "2022.1.1",
         "name": "licensecheck",
         "version": "2022.1.1"
     },
     "loguru": {
-        "datetime": "2022-01-29T13:47:29.921115Z",
+        "datetime": "2022-01-29T13:47:29.921115+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2022-01-29T13:47:29.921115Z",
+        "latest_datetime": "2022-01-29T13:47:29.921115+00:00",
         "latest_version": "0.6.0",
         "name": "loguru",
         "version": "0.6.0"
     },
     "lxml": {
-        "datetime": "2022-07-01T20:09:49.309086Z",
+        "datetime": "2022-07-01T20:09:49.309086+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2022-07-01T20:09:49.309086Z",
+        "latest_datetime": "2022-07-01T20:09:49.309086+00:00",
         "latest_version": "4.9.1",
         "name": "lxml",
         "version": "4.9.1"
     },
-    "mako": {
-        "datetime": "2022-06-30T15:46:37.401060Z",
-        "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2022-06-30T15:46:37.401060Z",
-        "latest_version": "1.2.1",
-        "name": "mako",
-        "version": "1.2.1"
-    },
     "mando": {
-        "datetime": "2017-06-05T07:02:57.728157Z",
+        "datetime": "2017-06-05T07:02:57.728157+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2022-02-24T08:12:25.240897Z",
+        "latest_datetime": "2022-02-24T08:12:25.240897+00:00",
         "latest_version": "0.7.1",
         "name": "mando",
         "version": "0.6.4"
     },
-    "markdown": {
-        "datetime": "2022-07-15T19:15:37.044395Z",
-        "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2022-07-15T19:15:37.044395Z",
-        "latest_version": "3.4.1",
-        "name": "markdown",
-        "version": "3.4.1"
-    },
-    "markupsafe": {
-        "datetime": "2022-03-15T13:22:05.942273Z",
-        "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2022-03-15T13:22:05.942273Z",
-        "latest_version": "2.1.1",
-        "name": "markupsafe",
-        "version": "2.1.1"
-    },
     "matplotlib": {
-        "datetime": "2022-05-03T06:44:48.926822Z",
+        "datetime": "2022-08-11T06:59:22.238447+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2022-05-03T06:44:48.926822Z",
-        "latest_version": "3.5.2",
+        "latest_datetime": "2022-08-27T07:38:00.613868+00:00",
+        "latest_version": "3.6.0rc2",
         "name": "matplotlib",
-        "version": "3.5.2"
+        "version": "3.5.3"
     },
     "mccabe": {
-        "datetime": "2017-01-26T22:13:14.360350Z",
+        "datetime": "2022-01-24T01:14:49.620723+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2022-01-24T01:14:49.620723Z",
+        "latest_datetime": "2022-01-24T01:14:49.620723+00:00",
         "latest_version": "0.7.0",
         "name": "mccabe",
-        "version": "0.6.1"
+        "version": "0.7.0"
     },
     "mergedeep": {
-        "datetime": "2021-02-05T18:55:29.583731Z",
+        "datetime": "2021-02-05T18:55:29.583731+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2021-02-05T18:55:29.583731Z",
+        "latest_datetime": "2021-02-05T18:55:29.583731+00:00",
         "latest_version": "1.3.4",
         "name": "mergedeep",
         "version": "1.3.4"
     },
     "mkdocs": {
-        "datetime": "2022-03-26T19:53:18.459672Z",
+        "datetime": "2022-03-26T19:53:18.459672+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2022-07-19T07:24:33.424540Z",
+        "latest_datetime": "2022-07-19T07:24:33.424540+00:00",
         "latest_version": "1.3.1",
         "name": "mkdocs",
         "version": "1.3.0"
     },
     "mkdocs-git-revision-date-localized-plugin": {
-        "datetime": "2022-07-02T11:14:43.680107Z",
+        "datetime": "2022-07-02T11:14:43.680107+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2022-07-02T11:14:43.680107Z",
+        "latest_datetime": "2022-07-02T11:14:43.680107+00:00",
         "latest_version": "1.1.0",
         "name": "mkdocs-git-revision-date-localized-plugin",
         "version": "1.1.0"
     },
     "mkdocs-material": {
-        "datetime": "2022-07-04T11:30:27.455652Z",
+        "datetime": "2022-09-15T17:10:56.242220+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2022-07-20T15:40:08.193155Z",
-        "latest_version": "8.4.0rc1",
+        "latest_datetime": "2022-09-15T17:10:56.242220+00:00",
+        "latest_version": "8.5.1",
         "name": "mkdocs-material",
-        "version": "8.3.9"
+        "version": "8.5.1"
     },
     "mkdocs-material-extensions": {
-        "datetime": "2021-09-03T20:49:40.072718Z",
+        "datetime": "2021-09-03T20:49:40.072718+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2021-09-03T20:49:40.072718Z",
+        "latest_datetime": "2021-09-03T20:49:40.072718+00:00",
         "latest_version": "1.0.3",
         "name": "mkdocs-material-extensions",
         "version": "1.0.3"
     },
     "mr-proper": {
-        "datetime": "2021-10-27T13:06:01.852589Z",
+        "datetime": "2021-10-27T13:06:01.852589+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2021-10-27T13:06:01.852589Z",
+        "latest_datetime": "2021-10-27T13:06:01.852589+00:00",
         "latest_version": "0.0.7",
         "name": "mr-proper",
         "version": "0.0.7"
     },
     "multidict": {
-        "datetime": "2022-01-24T16:56:02.773820Z",
+        "datetime": "2022-01-24T16:56:02.773820+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2022-01-24T16:56:02.773820Z",
+        "latest_datetime": "2022-01-24T16:56:02.773820+00:00",
         "latest_version": "6.0.2",
         "name": "multidict",
         "version": "6.0.2"
     },
     "mypy": {
-        "datetime": "2022-07-19T15:03:09.188215Z",
+        "datetime": "2022-07-19T15:03:09.188215+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2022-07-19T15:03:09.188215Z",
+        "latest_datetime": "2022-07-19T15:03:09.188215+00:00",
         "latest_version": "0.971",
         "name": "mypy",
         "version": "0.971"
     },
     "mypy-extensions": {
-        "datetime": "2019-10-17T22:38:56.922784Z",
+        "datetime": "2019-10-17T22:38:56.922784+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2019-10-17T22:38:56.922784Z",
+        "latest_datetime": "2019-10-17T22:38:56.922784+00:00",
         "latest_version": "0.4.3",
         "name": "mypy-extensions",
         "version": "0.4.3"
     },
     "nodeenv": {
-        "datetime": "2022-06-25T15:38:17.819693Z",
+        "datetime": "2022-06-25T15:38:17.819693+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2022-06-25T15:38:17.819693Z",
+        "latest_datetime": "2022-06-25T15:38:17.819693+00:00",
         "latest_version": "1.7.0",
         "name": "nodeenv",
         "version": "1.7.0"
     },
     "nox": {
-        "datetime": "2022-01-07T23:34:01.412728Z",
+        "datetime": "2022-08-08T00:27:27.574073+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2022-01-07T23:34:01.412728Z",
-        "latest_version": "2022.1.7",
+        "latest_datetime": "2022-08-08T00:27:27.574073+00:00",
+        "latest_version": "2022.8.7",
         "name": "nox",
-        "version": "2022.1.7"
+        "version": "2022.8.7"
     },
     "nox-poetry": {
-        "datetime": "2022-06-24T20:42:24.066267Z",
+        "datetime": "2022-06-24T20:42:24.066267+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2022-06-24T20:42:24.066267Z",
+        "latest_datetime": "2022-06-24T20:42:24.066267+00:00",
         "latest_version": "1.0.1",
         "name": "nox-poetry",
         "version": "1.0.1"
     },
     "numpy": {
-        "datetime": "2022-07-09T01:07:24.593590Z",
+        "datetime": "2022-09-09T17:48:27.159123+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2022-07-09T01:07:24.593590Z",
-        "latest_version": "1.23.1",
+        "latest_datetime": "2022-09-09T17:48:27.159123+00:00",
+        "latest_version": "1.23.3",
         "name": "numpy",
-        "version": "1.23.1"
+        "version": "1.23.3"
     },
     "packaging": {
-        "datetime": "2021-11-18T00:39:10.932370Z",
+        "datetime": "2021-11-18T00:39:10.932370+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2021-11-18T00:39:10.932370Z",
+        "latest_datetime": "2021-11-18T00:39:10.932370+00:00",
         "latest_version": "21.3",
         "name": "packaging",
         "version": "21.3"
     },
     "pandas": {
-        "datetime": "2022-06-23T13:30:09.536882Z",
+        "datetime": "2022-08-31T12:18:07.039749+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2022-06-23T13:30:09.536882Z",
-        "latest_version": "1.4.3",
+        "latest_datetime": "2022-08-31T12:18:07.039749+00:00",
+        "latest_version": "1.4.4",
         "name": "pandas",
-        "version": "1.4.3"
+        "version": "1.4.4"
     },
     "pandas-vet": {
-        "datetime": "2022-02-09T02:48:57.434022Z",
+        "datetime": "2022-02-09T02:48:57.434022+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2022-02-09T02:48:57.434022Z",
+        "latest_datetime": "2022-02-09T02:48:57.434022+00:00",
         "latest_version": "0.2.3",
         "name": "pandas-vet",
         "version": "0.2.3"
     },
     "pathspec": {
-        "datetime": "2021-07-18T00:27:58.275389Z",
+        "datetime": "2021-07-18T00:27:58.275389+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2021-07-18T00:27:58.275389Z",
+        "latest_datetime": "2021-07-18T00:27:58.275389+00:00",
         "latest_version": "0.9.0",
         "name": "pathspec",
         "version": "0.9.0"
     },
     "pbr": {
-        "datetime": "2022-05-05T09:53:36.071744Z",
+        "datetime": "2022-08-11T14:03:17.458277+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2022-05-05T09:53:36.071744Z",
-        "latest_version": "5.9.0",
+        "latest_datetime": "2022-08-11T14:03:17.458277+00:00",
+        "latest_version": "5.10.0",
         "name": "pbr",
-        "version": "5.9.0"
+        "version": "5.10.0"
     },
     "pdbpp": {
-        "datetime": "2021-07-09T22:22:20.271179Z",
+        "datetime": "2021-07-09T22:22:20.271179+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2021-07-09T22:22:20.271179Z",
+        "latest_datetime": "2021-07-09T22:22:20.271179+00:00",
         "latest_version": "0.10.3",
         "name": "pdbpp",
         "version": "0.10.3"
     },
     "pdocs": {
-        "datetime": "2021-01-29T08:14:55.588161Z",
+        "datetime": "2021-01-29T08:14:55.588161+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2021-01-29T08:14:55.588161Z",
+        "latest_datetime": "2021-01-29T08:14:55.588161+00:00",
         "latest_version": "1.1.1",
         "name": "pdocs",
         "version": "1.1.1"
     },
     "pendulum": {
-        "datetime": "2020-07-24T18:16:40.817569Z",
+        "datetime": "2020-07-24T18:16:40.817569+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2020-07-24T18:16:40.817569Z",
+        "latest_datetime": "2020-07-24T18:16:40.817569+00:00",
         "latest_version": "2.1.2",
         "name": "pendulum",
         "version": "2.1.2"
     },
     "pep8-naming": {
-        "datetime": "2022-07-15T19:54:08.859869Z",
+        "datetime": "2022-08-19T19:24:22.900666+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2022-07-15T19:54:08.859869Z",
-        "latest_version": "0.13.1",
+        "latest_datetime": "2022-08-19T19:24:22.900666+00:00",
+        "latest_version": "0.13.2",
         "name": "pep8-naming",
-        "version": "0.13.1"
+        "version": "0.13.2"
     },
-    "pillow": {
-        "datetime": "2022-07-01T18:28:52.815507Z",
+    "pip": {
+        "datetime": "2022-08-03T18:56:21.845282+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2022-07-01T18:28:52.815507Z",
-        "latest_version": "9.2.0",
-        "name": "pillow",
-        "version": "9.2.0"
+        "latest_datetime": "2022-08-03T18:56:21.845282+00:00",
+        "latest_version": "22.2.2",
+        "name": "pip",
+        "version": "22.2.2"
     },
     "pip-check": {
-        "datetime": "2021-11-16T21:10:44.740100Z",
+        "datetime": "2021-11-16T21:10:44.740100+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2021-11-16T21:10:44.740100Z",
+        "latest_datetime": "2021-11-16T21:10:44.740100+00:00",
         "latest_version": "2.7",
         "name": "pip-check",
         "version": "2.7"
     },
     "platformdirs": {
-        "datetime": "2022-04-18T08:48:47.670933Z",
+        "datetime": "2022-04-18T08:48:47.670933+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2022-04-18T08:48:47.670933Z",
+        "latest_datetime": "2022-04-18T08:48:47.670933+00:00",
         "latest_version": "2.5.2",
         "name": "platformdirs",
         "version": "2.5.2"
     },
     "pluggy": {
-        "datetime": "2021-08-25T16:25:59.674784Z",
+        "datetime": "2021-08-25T16:25:59.674784+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2021-08-25T16:25:59.674784Z",
+        "latest_datetime": "2021-08-25T16:25:59.674784+00:00",
         "latest_version": "1.0.0",
         "name": "pluggy",
         "version": "1.0.0"
     },
     "pre-commit": {
-        "datetime": "2022-07-11T00:55:29.799163Z",
+        "datetime": "2022-07-11T00:55:29.799163+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2022-07-11T00:55:29.799163Z",
+        "latest_datetime": "2022-07-11T00:55:29.799163+00:00",
         "latest_version": "2.20.0",
         "name": "pre-commit",
         "version": "2.20.0"
     },
     "prompt-toolkit": {
-        "datetime": "2022-06-27T09:43:39.392899Z",
+        "datetime": "2022-09-02T09:01:28.121821+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2022-06-27T09:43:39.392899Z",
-        "latest_version": "3.0.30",
+        "latest_datetime": "2022-09-02T09:01:28.121821+00:00",
+        "latest_version": "3.0.31",
         "name": "prompt-toolkit",
-        "version": "3.0.30"
+        "version": "3.0.31"
     },
     "proselint": {
-        "datetime": "2021-11-07T02:02:04.531115Z",
+        "datetime": "2021-11-07T02:02:04.531115+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2021-11-07T02:02:04.531115Z",
+        "latest_datetime": "2021-11-07T02:02:04.531115+00:00",
         "latest_version": "0.13.0",
         "name": "proselint",
         "version": "0.13.0"
     },
     "punq": {
-        "datetime": "2022-02-17T09:16:12.094458Z",
+        "datetime": "2022-02-17T09:16:12.094458+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2022-02-17T09:16:12.094458Z",
+        "latest_datetime": "2022-02-17T09:16:12.094458+00:00",
         "latest_version": "0.6.2",
         "name": "punq",
         "version": "0.6.2"
     },
     "py": {
-        "datetime": "2021-11-04T17:17:00.152107Z",
+        "datetime": "2021-11-04T17:17:00.152107+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2021-11-04T17:17:00.152107Z",
+        "latest_datetime": "2021-11-04T17:17:00.152107+00:00",
         "latest_version": "1.11.0",
         "name": "py",
         "version": "1.11.0"
     },
     "py-cpuinfo": {
-        "datetime": "2021-04-14T16:53:43.394219Z",
+        "datetime": "2021-04-14T16:53:43.394219+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2021-04-14T16:53:43.394219Z",
+        "latest_datetime": "2021-04-14T16:53:43.394219+00:00",
         "latest_version": "8.0.0",
         "name": "py-cpuinfo",
         "version": "8.0.0"
     },
     "pycln": {
-        "datetime": "2022-07-28T09:23:15.908881Z",
+        "datetime": "2022-07-28T09:23:15.908881+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2022-07-28T09:23:15.908881Z",
+        "latest_datetime": "2022-07-28T09:23:15.908881+00:00",
         "latest_version": "2.1.1",
         "name": "pycln",
         "version": "2.1.1"
     },
     "pycodestyle": {
-        "datetime": "2021-10-11T00:56:25.599776Z",
+        "datetime": "2022-08-03T23:13:27.416880+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2022-08-03T23:13:27.416880Z",
+        "latest_datetime": "2022-08-03T23:13:27.416880+00:00",
         "latest_version": "2.9.1",
         "name": "pycodestyle",
-        "version": "2.8.0"
+        "version": "2.9.1"
+    },
+    "pydantic": {
+        "datetime": "2022-09-05T18:37:50.309248+00:00",
+        "domain": "https://pypi.org/pypi/{name}/json",
+        "latest_datetime": "2022-09-05T18:37:50.309248+00:00",
+        "latest_version": "1.10.2",
+        "name": "pydantic",
+        "version": "1.10.2"
     },
     "pydocstyle": {
-        "datetime": "2021-05-17T20:37:45.262782Z",
+        "datetime": "2021-05-17T20:37:45.262782+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2021-05-17T20:37:45.262782Z",
+        "latest_datetime": "2021-05-17T20:37:45.262782+00:00",
         "latest_version": "6.1.1",
         "name": "pydocstyle",
         "version": "6.1.1"
     },
     "pyflakes": {
-        "datetime": "2021-10-06T20:39:49.185151Z",
+        "datetime": "2022-07-30T17:29:04.179569+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2022-07-30T17:29:04.179569Z",
+        "latest_datetime": "2022-07-30T17:29:04.179569+00:00",
         "latest_version": "2.5.0",
         "name": "pyflakes",
-        "version": "2.4.0"
-    },
-    "pygments": {
-        "datetime": "2022-04-24T13:37:38.352532Z",
-        "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2022-04-24T13:37:38.352532Z",
-        "latest_version": "2.12.0",
-        "name": "pygments",
-        "version": "2.12.0"
+        "version": "2.5.0"
     },
     "pylint": {
-        "datetime": "2022-07-17T19:45:51.432760Z",
+        "datetime": "2022-09-07T13:02:02.802242+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2022-07-17T19:45:51.432760Z",
-        "latest_version": "2.14.5",
+        "latest_datetime": "2022-09-07T13:02:02.802242+00:00",
+        "latest_version": "2.15.2",
         "name": "pylint",
-        "version": "2.14.5"
+        "version": "2.15.2"
     },
     "pymdown-extensions": {
-        "datetime": "2022-06-06T14:22:57.204037Z",
+        "datetime": "2022-06-06T14:22:57.204037+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2022-06-06T14:22:57.204037Z",
+        "latest_datetime": "2022-06-06T14:22:57.204037+00:00",
         "latest_version": "9.5",
         "name": "pymdown-extensions",
         "version": "9.5"
     },
     "pyparsing": {
-        "datetime": "2022-05-10T23:26:03.201008Z",
+        "datetime": "2022-05-10T23:26:03.201008+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2022-05-10T23:26:03.201008Z",
+        "latest_datetime": "2022-05-10T23:26:03.201008+00:00",
         "latest_version": "3.0.9",
         "name": "pyparsing",
         "version": "3.0.9"
     },
     "pyrate-limiter": {
-        "datetime": "2022-04-12T06:05:20.346448Z",
+        "datetime": "2022-04-12T06:05:20.346448+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2022-04-12T06:05:20.346448Z",
+        "latest_datetime": "2022-04-12T06:05:20.346448+00:00",
         "latest_version": "2.8.1",
         "name": "pyrate-limiter",
         "version": "2.8.1"
     },
     "pyreadline": {
-        "datetime": "2015-09-16T08:27:16.911586Z",
+        "datetime": "2015-09-16T08:27:16.911586+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2015-09-16T08:27:16.911586Z",
+        "latest_datetime": "2015-09-16T08:27:16.911586+00:00",
         "latest_version": "2.1",
         "name": "pyreadline",
         "version": "2.1"
     },
     "pyrepl": {
-        "datetime": "2019-04-16T14:16:21.663525Z",
+        "datetime": "2019-04-16T14:16:21.663525+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2019-04-16T14:16:21.663525Z",
+        "latest_datetime": "2019-04-16T14:16:21.663525+00:00",
         "latest_version": "0.9.0",
         "name": "pyrepl",
         "version": "0.9.0"
     },
     "pytest": {
-        "datetime": "2022-04-23T14:35:55.107169Z",
+        "datetime": "2022-09-02T11:13:13.780124+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2022-04-23T14:35:55.107169Z",
-        "latest_version": "7.1.2",
+        "latest_datetime": "2022-09-02T11:13:13.780124+00:00",
+        "latest_version": "7.1.3",
         "name": "pytest",
-        "version": "7.1.2"
+        "version": "7.1.3"
     },
     "pytest-benchmark": {
-        "datetime": "2021-04-17T19:47:26.558700Z",
+        "datetime": "2021-04-17T19:47:26.558700+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2021-04-17T19:47:26.558700Z",
+        "latest_datetime": "2021-04-17T19:47:26.558700+00:00",
         "latest_version": "3.4.1",
         "name": "pytest-benchmark",
         "version": "3.4.1"
     },
     "pytest-cache-assert": {
-        "datetime": "2022-05-02T02:57:46.765001Z",
+        "datetime": "2022-05-02T02:57:46.765001+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2022-05-02T02:57:46.765001Z",
+        "latest_datetime": "2022-05-02T02:57:46.765001+00:00",
         "latest_version": "2.0.0",
         "name": "pytest-cache-assert",
         "version": "2.0.0"
     },
     "pytest-html": {
-        "datetime": "2020-12-13T15:24:58.788568Z",
+        "datetime": "2020-12-13T15:24:58.788568+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2020-12-13T15:24:58.788568Z",
+        "latest_datetime": "2020-12-13T15:24:58.788568+00:00",
         "latest_version": "3.1.1",
         "name": "pytest-html",
         "version": "3.1.1"
     },
     "pytest-metadata": {
-        "datetime": "2022-07-15T12:23:50.102470Z",
+        "datetime": "2022-07-15T12:23:50.102470+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2022-07-15T12:23:50.102470Z",
+        "latest_datetime": "2022-07-15T12:23:50.102470+00:00",
         "latest_version": "2.0.2",
         "name": "pytest-metadata",
         "version": "2.0.2"
     },
     "pytest-randomly": {
-        "datetime": "2022-05-11T17:35:06.578594Z",
+        "datetime": "2022-05-11T17:35:06.578594+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2022-05-11T17:35:06.578594Z",
+        "latest_datetime": "2022-05-11T17:35:06.578594+00:00",
         "latest_version": "3.12.0",
         "name": "pytest-randomly",
         "version": "3.12.0"
     },
     "pytest-recording": {
-        "datetime": "2022-06-20T18:05:33.272976Z",
+        "datetime": "2022-06-20T18:05:33.272976+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2022-06-20T18:05:33.272976Z",
+        "latest_datetime": "2022-06-20T18:05:33.272976+00:00",
         "latest_version": "0.12.1",
         "name": "pytest-recording",
         "version": "0.12.1"
     },
     "pytest-subprocess": {
-        "datetime": "2022-02-09T06:22:20.070875Z",
+        "datetime": "2022-02-09T06:22:20.070875+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2022-02-09T06:22:20.070875Z",
+        "latest_datetime": "2022-02-09T06:22:20.070875+00:00",
         "latest_version": "1.4.1",
         "name": "pytest-subprocess",
         "version": "1.4.1"
     },
     "pytest-watcher": {
-        "datetime": "2021-12-30T21:05:34.961291Z",
+        "datetime": "2021-12-30T21:05:34.961291+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2021-12-30T21:05:34.961291Z",
+        "latest_datetime": "2021-12-30T21:05:34.961291+00:00",
         "latest_version": "0.2.3",
         "name": "pytest-watcher",
         "version": "0.2.3"
     },
     "python-box": {
-        "datetime": "2022-04-02T02:29:07.939019Z",
+        "datetime": "2022-04-02T02:29:07.939019+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2022-04-02T02:29:07.939019Z",
+        "latest_datetime": "2022-04-02T02:29:07.939019+00:00",
         "latest_version": "6.0.2",
         "name": "python-box",
         "version": "6.0.2"
     },
     "python-dateutil": {
-        "datetime": "2021-07-14T08:19:18.161589Z",
+        "datetime": "2021-07-14T08:19:18.161589+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2021-07-14T08:19:18.161589Z",
+        "latest_datetime": "2021-07-14T08:19:18.161589+00:00",
         "latest_version": "2.8.2",
         "name": "python-dateutil",
         "version": "2.8.2"
     },
     "pytz": {
-        "datetime": "2022-03-20T00:37:06.783063Z",
+        "datetime": "2022-08-13T02:07:57.135432+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2022-03-20T00:37:06.783063Z",
-        "latest_version": "2022.1",
+        "latest_datetime": "2022-08-13T02:07:57.135432+00:00",
+        "latest_version": "2022.2.1",
         "name": "pytz",
-        "version": "2022.1"
+        "version": "2022.2.1"
     },
     "pytzdata": {
-        "datetime": "2020-07-13T10:42:10.122147Z",
+        "datetime": "2020-07-13T10:42:10.122147+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2020-07-13T10:42:10.122147Z",
+        "latest_datetime": "2020-07-13T10:42:10.122147+00:00",
         "latest_version": "2020.1",
         "name": "pytzdata",
         "version": "2020.1"
     },
     "pyupgrade": {
-        "datetime": "2022-07-26T16:55:54.891881Z",
+        "datetime": "2022-09-15T16:27:40.383646+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2022-07-26T16:55:54.891881Z",
-        "latest_version": "2.37.3",
+        "latest_datetime": "2022-09-15T16:27:40.383646+00:00",
+        "latest_version": "2.38.0",
         "name": "pyupgrade",
-        "version": "2.37.3"
+        "version": "2.38.0"
     },
-    "pyyaml": {
-        "datetime": "2021-10-13T19:39:42.916039Z",
+    "pyyaml_env_tag": {
+        "datetime": "2020-11-12T02:38:24.638742+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2021-10-13T19:39:42.916039Z",
-        "latest_version": "6.0",
-        "name": "pyyaml",
-        "version": "6.0"
-    },
-    "pyyaml-env-tag": {
-        "datetime": "2020-11-12T02:38:24.638742Z",
-        "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2020-11-12T02:38:24.638742Z",
+        "latest_datetime": "2020-11-12T02:38:24.638742+00:00",
         "latest_version": "0.1",
-        "name": "pyyaml-env-tag",
+        "name": "pyyaml_env_tag",
         "version": "0.1"
     },
     "questionary": {
-        "datetime": "2021-07-15T10:11:00.246126Z",
+        "datetime": "2021-07-15T10:11:00.246126+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2021-07-15T10:11:00.246126Z",
+        "latest_datetime": "2021-07-15T10:11:00.246126+00:00",
         "latest_version": "1.10.0",
         "name": "questionary",
         "version": "1.10.0"
     },
     "radon": {
-        "datetime": "2021-08-08T13:25:20.919161Z",
+        "datetime": "2021-08-08T13:25:20.919161+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2021-08-08T13:25:20.919161Z",
+        "latest_datetime": "2021-08-08T13:25:20.919161+00:00",
         "latest_version": "5.1.0",
         "name": "radon",
         "version": "5.1.0"
     },
     "requests": {
-        "datetime": "2022-06-29T15:13:40.685859Z",
+        "datetime": "2022-06-29T15:13:40.685859+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2022-06-29T15:13:40.685859Z",
+        "latest_datetime": "2022-06-29T15:13:40.685859+00:00",
         "latest_version": "2.28.1",
         "name": "requests",
         "version": "2.28.1"
     },
     "requirements-parser": {
-        "datetime": "2022-01-20T08:52:07.321242Z",
+        "datetime": "2022-01-20T08:52:07.321242+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2022-01-20T08:52:07.321242Z",
+        "latest_datetime": "2022-01-20T08:52:07.321242+00:00",
         "latest_version": "0.5.0",
         "name": "requirements-parser",
         "version": "0.5.0"
     },
     "rich": {
-        "datetime": "2022-07-11T14:36:45.638667Z",
+        "datetime": "2022-07-11T14:36:45.638667+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2022-07-11T14:36:45.638667Z",
+        "latest_datetime": "2022-07-11T14:36:45.638667+00:00",
         "latest_version": "12.5.1",
         "name": "rich",
         "version": "12.5.1"
     },
+    "setuptools": {
+        "datetime": "2022-08-24T11:09:27.546037+00:00",
+        "domain": "https://pypi.org/pypi/{name}/json",
+        "latest_datetime": "2022-08-24T11:09:27.546037+00:00",
+        "latest_version": "65.3.0",
+        "name": "setuptools",
+        "version": "65.3.0"
+    },
     "setuptools-scm": {
-        "datetime": "2022-07-11T12:51:57.671747Z",
+        "datetime": "2022-01-19T10:42:56.561004+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2022-07-11T12:51:57.671747Z",
+        "latest_datetime": "2022-07-11T12:51:57.671747+00:00",
         "latest_version": "7.0.5",
         "name": "setuptools-scm",
-        "version": "7.0.5"
+        "version": "6.4.2"
     },
     "six": {
-        "datetime": "2021-05-05T14:18:17.237677Z",
+        "datetime": "2021-05-05T14:18:17.237677+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2021-05-05T14:18:17.237677Z",
+        "latest_datetime": "2021-05-05T14:18:17.237677+00:00",
         "latest_version": "1.16.0",
         "name": "six",
         "version": "1.16.0"
     },
     "smmap": {
-        "datetime": "2021-10-15T13:19:45.436893Z",
+        "datetime": "2021-10-15T13:19:45.436893+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2021-10-15T13:19:45.436893Z",
+        "latest_datetime": "2021-10-15T13:19:45.436893+00:00",
         "latest_version": "5.0.0",
         "name": "smmap",
         "version": "5.0.0"
     },
     "snowballstemmer": {
-        "datetime": "2021-11-16T18:38:34.792729Z",
+        "datetime": "2021-11-16T18:38:34.792729+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2021-11-16T18:38:34.792729Z",
+        "latest_datetime": "2021-11-16T18:38:34.792729+00:00",
         "latest_version": "2.2.0",
         "name": "snowballstemmer",
         "version": "2.2.0"
     },
     "sortedcontainers": {
-        "datetime": "2021-05-16T22:03:41.177807Z",
+        "datetime": "2021-05-16T22:03:41.177807+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2021-05-16T22:03:41.177807Z",
+        "latest_datetime": "2021-05-16T22:03:41.177807+00:00",
         "latest_version": "2.4.0",
         "name": "sortedcontainers",
         "version": "2.4.0"
     },
     "sqlparse": {
-        "datetime": "2021-09-10T06:51:56.892895Z",
+        "datetime": "2021-09-10T06:51:56.892895+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2021-09-10T06:51:56.892895Z",
+        "latest_datetime": "2021-09-10T06:51:56.892895+00:00",
         "latest_version": "0.4.2",
         "name": "sqlparse",
         "version": "0.4.2"
     },
     "stdlib-list": {
-        "datetime": "2020-11-19T14:11:08.070691Z",
+        "datetime": "2020-11-19T14:11:08.070691+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2020-11-19T14:11:08.070691Z",
+        "latest_datetime": "2020-11-19T14:11:08.070691+00:00",
         "latest_version": "0.8.0",
         "name": "stdlib-list",
         "version": "0.8.0"
     },
     "stevedore": {
-        "datetime": "2022-07-12T09:06:44.671713Z",
+        "datetime": "2022-07-12T09:06:44.671713+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2022-07-12T09:06:44.671713Z",
+        "latest_datetime": "2022-07-12T09:06:44.671713+00:00",
         "latest_version": "4.0.0",
         "name": "stevedore",
         "version": "4.0.0"
     },
     "sty": {
-        "datetime": "2022-02-05T13:11:22.693545Z",
+        "datetime": "2022-02-05T13:11:22.693545+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2022-02-05T13:11:22.693545Z",
+        "latest_datetime": "2022-02-05T13:11:22.693545+00:00",
         "latest_version": "1.0.4",
         "name": "sty",
         "version": "1.0.4"
     },
     "tabulate": {
-        "datetime": "2022-06-21T16:26:40.167441Z",
+        "datetime": "2022-06-21T16:26:40.167441+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2022-06-21T16:26:40.167441Z",
+        "latest_datetime": "2022-06-21T16:26:40.167441+00:00",
         "latest_version": "0.8.10",
         "name": "tabulate",
         "version": "0.8.10"
     },
     "termcolor": {
-        "datetime": "2011-01-13T18:45:33.979856Z",
+        "datetime": "2011-01-13T18:45:33.979856+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2011-01-13T18:45:33.979856Z",
+        "latest_datetime": "2011-01-13T18:45:33.979856+00:00",
         "latest_version": "1.1.0",
         "name": "termcolor",
         "version": "1.1.0"
     },
     "terminaltables": {
-        "datetime": "2021-12-07T19:03:34.013333Z",
+        "datetime": "2021-12-07T19:03:34.013333+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2021-12-07T19:03:34.013333Z",
+        "latest_datetime": "2021-12-07T19:03:34.013333+00:00",
         "latest_version": "3.1.10",
         "name": "terminaltables",
         "version": "3.1.10"
     },
     "tokenize-rt": {
-        "datetime": "2021-10-21T15:20:18.870116Z",
+        "datetime": "2021-10-21T15:20:18.870116+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2021-10-21T15:20:18.870116Z",
+        "latest_datetime": "2021-10-21T15:20:18.870116+00:00",
         "latest_version": "4.2.1",
         "name": "tokenize-rt",
         "version": "4.2.1"
     },
     "toml": {
-        "datetime": "2020-11-01T01:40:20.672915Z",
+        "datetime": "2020-11-01T01:40:20.672915+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2020-11-01T01:40:20.672915Z",
+        "latest_datetime": "2020-11-01T01:40:20.672915+00:00",
         "latest_version": "0.10.2",
         "name": "toml",
         "version": "0.10.2"
     },
     "tomli": {
-        "datetime": "2022-02-08T10:54:02.017593Z",
+        "datetime": "2022-02-08T10:54:02.017593+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2022-02-08T10:54:02.017593Z",
+        "latest_datetime": "2022-02-08T10:54:02.017593+00:00",
         "latest_version": "2.0.1",
         "name": "tomli",
         "version": "2.0.1"
     },
     "tomlkit": {
-        "datetime": "2022-07-07T02:46:24.664209Z",
+        "datetime": "2022-08-13T04:07:15.428684+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2022-07-07T02:46:24.664209Z",
-        "latest_version": "0.11.1",
+        "latest_datetime": "2022-08-13T04:07:15.428684+00:00",
+        "latest_version": "0.11.4",
         "name": "tomlkit",
-        "version": "0.11.1"
+        "version": "0.11.4"
     },
     "transitions": {
-        "datetime": "2022-02-24T09:28:15.477234Z",
+        "datetime": "2022-09-02T09:48:52.135381+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2022-02-24T09:28:15.477234Z",
-        "latest_version": "0.8.11",
+        "latest_datetime": "2022-09-02T09:48:52.135381+00:00",
+        "latest_version": "0.9.0",
         "name": "transitions",
-        "version": "0.8.11"
+        "version": "0.9.0"
     },
     "typer": {
-        "datetime": "2022-07-12T20:30:38.849829Z",
+        "datetime": "2022-07-12T20:30:38.849829+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2022-07-12T20:30:38.849829Z",
+        "latest_datetime": "2022-07-12T20:30:38.849829+00:00",
         "latest_version": "0.6.1",
         "name": "typer",
         "version": "0.6.1"
     },
     "types-setuptools": {
-        "datetime": "2022-08-05T01:54:39.805071Z",
+        "datetime": "2022-08-26T04:46:51.427377+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2022-08-05T01:54:39.805071Z",
-        "latest_version": "63.4.0",
+        "latest_datetime": "2022-08-26T04:46:51.427377+00:00",
+        "latest_version": "65.3.0",
         "name": "types-setuptools",
-        "version": "63.4.0"
+        "version": "65.3.0"
     },
     "typing-extensions": {
-        "datetime": "2022-07-01T14:56:11.904033Z",
+        "datetime": "2022-07-01T14:56:11.904033+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2022-07-01T14:56:11.904033Z",
+        "latest_datetime": "2022-07-01T14:56:11.904033+00:00",
         "latest_version": "4.3.0",
         "name": "typing-extensions",
         "version": "4.3.0"
     },
     "typing-inspect": {
-        "datetime": "2021-06-07T16:12:08.580739Z",
+        "datetime": "2022-08-17T14:00:03.093116+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2021-06-07T16:12:08.580739Z",
-        "latest_version": "0.7.1",
+        "latest_datetime": "2022-08-17T14:00:03.093116+00:00",
+        "latest_version": "0.8.0",
         "name": "typing-inspect",
-        "version": "0.7.1"
+        "version": "0.8.0"
     },
     "ujson": {
-        "datetime": "2022-07-02T05:31:48.518065Z",
+        "datetime": "2022-09-15T18:12:05.034324+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2022-07-02T05:31:48.518065Z",
-        "latest_version": "5.4.0",
+        "latest_datetime": "2022-09-15T18:12:05.034324+00:00",
+        "latest_version": "5.5.0",
         "name": "ujson",
-        "version": "5.4.0"
+        "version": "5.5.0"
     },
     "urllib3": {
-        "datetime": "2022-07-25T13:02:21.294138Z",
+        "datetime": "2022-08-22T13:27:19.719799+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2022-07-25T13:02:21.294138Z",
-        "latest_version": "1.26.11",
+        "latest_datetime": "2022-08-22T13:27:19.719799+00:00",
+        "latest_version": "1.26.12",
         "name": "urllib3",
-        "version": "1.26.11"
+        "version": "1.26.12"
     },
     "vcrpy": {
-        "datetime": "2022-06-29T21:56:42.103213Z",
+        "datetime": "2022-08-31T19:18:15.869354+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2022-06-29T21:56:42.103213Z",
-        "latest_version": "4.2.0",
+        "latest_datetime": "2022-08-31T19:18:15.869354+00:00",
+        "latest_version": "4.2.1",
         "name": "vcrpy",
-        "version": "4.2.0"
+        "version": "4.2.1"
     },
     "virtualenv": {
-        "datetime": "2022-08-04T16:18:03.678283Z",
+        "datetime": "2022-09-08T02:19:11.397202+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2022-08-04T16:18:03.678283Z",
-        "latest_version": "20.16.3",
+        "latest_datetime": "2022-09-08T02:19:11.397202+00:00",
+        "latest_version": "20.16.5",
         "name": "virtualenv",
-        "version": "20.16.3"
+        "version": "20.16.5"
     },
     "vulture": {
-        "datetime": "2022-07-03T20:36:20.968411Z",
+        "datetime": "2022-07-03T20:36:20.968411+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2022-07-03T20:36:20.968411Z",
+        "latest_datetime": "2022-07-03T20:36:20.968411+00:00",
         "latest_version": "2.5",
         "name": "vulture",
         "version": "2.5"
     },
     "watchdog": {
-        "datetime": "2022-06-10T10:28:22.716530Z",
+        "datetime": "2022-06-10T10:28:22.716530+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2022-06-10T10:28:22.716530Z",
+        "latest_datetime": "2022-06-10T10:28:22.716530+00:00",
         "latest_version": "2.1.9",
         "name": "watchdog",
         "version": "2.1.9"
     },
     "wcwidth": {
-        "datetime": "2020-06-23T16:10:28.529454Z",
+        "datetime": "2020-06-23T16:10:28.529454+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2020-06-23T16:10:28.529454Z",
+        "latest_datetime": "2020-06-23T16:10:28.529454+00:00",
         "latest_version": "0.2.5",
         "name": "wcwidth",
         "version": "0.2.5"
     },
     "win32-setctime": {
-        "datetime": "2022-01-22T17:51:51.975557Z",
+        "datetime": "2022-01-22T17:51:51.975557+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2022-01-22T17:51:51.975557Z",
+        "latest_datetime": "2022-01-22T17:51:51.975557+00:00",
         "latest_version": "1.1.0",
         "name": "win32-setctime",
         "version": "1.1.0"
     },
     "wmctrl": {
-        "datetime": "2021-04-23T16:38:44.238436Z",
+        "datetime": "2021-04-23T16:38:44.238436+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2021-04-23T16:38:44.238436Z",
+        "latest_datetime": "2021-04-23T16:38:44.238436+00:00",
         "latest_version": "0.4",
         "name": "wmctrl",
         "version": "0.4"
     },
     "wrapt": {
-        "datetime": "2022-05-02T05:26:13.235405Z",
+        "datetime": "2022-05-02T05:26:13.235405+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2022-05-02T05:26:13.235405Z",
+        "latest_datetime": "2022-05-02T05:26:13.235405+00:00",
         "latest_version": "1.14.1",
         "name": "wrapt",
         "version": "1.14.1"
     },
     "xenon": {
-        "datetime": "2022-02-24T08:21:17.992203Z",
+        "datetime": "2022-02-24T08:21:17.992203+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2022-02-24T08:21:17.992203Z",
+        "latest_datetime": "2022-02-24T08:21:17.992203+00:00",
         "latest_version": "0.9.0",
         "name": "xenon",
         "version": "0.9.0"
     },
     "yamllint": {
-        "datetime": "2022-07-08T16:07:39.590701Z",
+        "datetime": "2022-09-12T12:38:56.464090+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2022-07-08T16:07:39.590701Z",
-        "latest_version": "1.27.1",
+        "latest_datetime": "2022-09-12T12:38:56.464090+00:00",
+        "latest_version": "1.28.0",
         "name": "yamllint",
-        "version": "1.27.1"
+        "version": "1.28.0"
     },
     "yarl": {
-        "datetime": "2022-08-02T07:12:14.936535Z",
+        "datetime": "2022-08-02T07:12:14.936535+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2022-08-02T07:12:14.936535Z",
+        "latest_datetime": "2022-08-02T07:12:14.936535+00:00",
         "latest_version": "1.8.1",
         "name": "yarl",
         "version": "1.8.1"
     },
     "zipp": {
-        "datetime": "2022-07-12T14:21:20.506913Z",
+        "datetime": "2022-07-12T14:21:20.506913+00:00",
         "domain": "https://pypi.org/pypi/{name}/json",
-        "latest_datetime": "2022-07-12T14:21:20.506913Z",
+        "latest_datetime": "2022-07-12T14:21:20.506913+00:00",
         "latest_version": "3.8.1",
         "name": "zipp",
         "version": "3.8.1"
diff --git a/.copier-answers.yml b/.copier-answers.yml
index 7d0fcd78..9c8d7d8a 100644
--- a/.copier-answers.yml
+++ b/.copier-answers.yml
@@ -1,19 +1,19 @@
 # yamllint disable-file
 # Answer file maintained by Copier for: https://github.com/KyleKing/calcipy_template
 # Check into version control. Edit by re-running copier and changing responses to the questions
-_commit: 0.6.0
+_commit: 0.9.1
 _src_path: gh:KyleKing/calcipy_template
 author_email: dev.act.kyle@gmail.com
 author_name: Kyle King
 author_username: kyleking
 cname: calcipy.kyleking.me
-codecov_token: d414dacb-5b8d-4c0b-94e1-42fe8393187d
 copyright_date: '2021'
 doc_dir: docs
 install_extras: -E dev -E lint -E test -E commitizen_legacy
+minimum_python: 3.8.4
 package_name_py: calcipy
 project_description: Python package to simplify development. Includes functionality
-  for task running, testing, linting, documenting, and more
+    for task running, testing, linting, documenting, and more
 project_name: calcipy
 repository_namespace: kyleking
 repository_provider: https://github.com
diff --git a/.flake8 b/.flake8
index 75858767..080dc00d 100644
--- a/.flake8
+++ b/.flake8
@@ -23,6 +23,6 @@ max-expression-complexity = 7
 max-function-length = 55
 max-line-length = 120
 max-parameters-amount = 6
-min-python-version = 3.8
+min-python-version = 3.8.4
 per-file-ignores=test_*.py:ANN001,ANN201,DAR101,DAR201,E800,S101
 select = A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z
diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md
index cd2cbdfc..69be597e 100644
--- a/.github/ISSUE_TEMPLATE/bug_report.md
+++ b/.github/ISSUE_TEMPLATE/bug_report.md
@@ -2,7 +2,7 @@
 name: Bug report
 about: Found a problem, us know!
 title: ''
-labels: 'Type: Bug, Needs Discussion'
+labels: 'Type: Bug'
 assignees: kyleking
 ---
 
diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md
index 324567b9..32968ad3 100644
--- a/.github/ISSUE_TEMPLATE/feature_request.md
+++ b/.github/ISSUE_TEMPLATE/feature_request.md
@@ -2,7 +2,7 @@
 name: Feature request
 about: Let us know if  an idea for this project
 title: ''
-labels: 'Type: Feature, Needs Discussion, Type: Idea'
+labels: 'Type: Feature'
 assignees: kyleking
 ---
 
diff --git a/.github/ISSUE_TEMPLATE/question.md b/.github/ISSUE_TEMPLATE/question.md
index 466d817b..59a585ba 100644
--- a/.github/ISSUE_TEMPLATE/question.md
+++ b/.github/ISSUE_TEMPLATE/question.md
@@ -2,7 +2,7 @@
 name: Question
 about: Ask a question here (or use the "Github Discussion" instead)
 title: ''
-labels: 'Type: Documentation, Type: Idea'
+labels: ''
 assignees: kyleking
 ---
 
diff --git a/.github/actions/setup/action.yml b/.github/actions/setup/action.yml
index 49010b4e..2f9a0ff2 100644
--- a/.github/actions/setup/action.yml
+++ b/.github/actions/setup/action.yml
@@ -21,18 +21,22 @@ runs:
     - name: Install Poetry ${{ inputs.poetry-version }}
       run: pipx install poetry==${{ inputs.poetry-version }}
       shell: bash
+
     - name: Setup Python ${{ inputs.python-version }}
       uses: actions/setup-python@v4
       with:
         python-version: ${{ inputs.python-version }}
         cache: poetry
-    - uses: actions/cache@v2
+
+    - uses: actions/cache@v3
       id: cache
       with:
         path: .nox
         # yamllint disable-line rule:line-length
-        key: ${{inputs.os}}-${{inputs.python-version}}-${{hashFiles('**/poetry.lock')}}
+        key: ${{ inputs.os }}-${{ inputs.python-version }}-${{ hashFiles('**/poetry.lock')
+          }}
+
     - name: Install Project and Dependencies
-      run: |
+      run: |-
         poetry install -E dev -E lint -E test -E commitizen_legacy
       shell: bash
diff --git a/.github/workflows/ci_pipeline.yml b/.github/workflows/ci_pipeline.yml
index bb0ea44b..7a980a6b 100644
--- a/.github/workflows/ci_pipeline.yml
+++ b/.github/workflows/ci_pipeline.yml
@@ -17,9 +17,9 @@ jobs:
     strategy:
       matrix:
         os: [ubuntu-latest]
-        python-version: ['3.8']
+        python-version: [3.8.4]
     steps:
-      - uses: actions/checkout@v2
+      - uses: actions/checkout@v3
       - uses: ./.github/actions/setup
         with:
           os: ${{ matrix.os }}
@@ -33,10 +33,10 @@ jobs:
     strategy:
       matrix:
         os: [ubuntu-latest, macos-latest, windows-latest]
-        python-version: ['3.8', '3.10']
+        python-version: [3.8.4, '3.10']
     continue-on-error: ${{ matrix.python-version == '3.10' }}
     steps:
-      - uses: actions/checkout@v2
+      - uses: actions/checkout@v3
       - uses: ./.github/actions/setup
         with:
           os: ${{ matrix.os }}
diff --git a/.github/workflows/labels.yml b/.github/workflows/labels.yml
index 97462b1d..1ea64515 100644
--- a/.github/workflows/labels.yml
+++ b/.github/workflows/labels.yml
@@ -13,7 +13,7 @@ jobs:
   labeler:
     runs-on: ubuntu-latest
     steps:
-      - uses: actions/checkout@v2
+      - uses: actions/checkout@v3
       - name: Run Labeler
         if: success()
         uses: crazy-max/ghaction-github-labeler@v3
diff --git a/.github/workflows/update_docs.yml b/.github/workflows/update_docs.yml
index 3f69cec4..b0639faf 100644
--- a/.github/workflows/update_docs.yml
+++ b/.github/workflows/update_docs.yml
@@ -15,9 +15,9 @@ jobs:
     strategy:
       matrix:
         os: [ubuntu-latest]
-        python-version: ['3.8']
+        python-version: [3.8.4]
     steps:
-      - uses: actions/checkout@v2
+      - uses: actions/checkout@v3
         with:
           fetch-depth: 0  # For git-revision-date-localized-plugin
       - uses: ./.github/actions/setup
@@ -30,7 +30,7 @@ jobs:
         # https://github.com/mkdocs/mkdocs/discussions/2369#discussioncomment-625475
         # yamllint disable-line rule:line-length
       - name: Configure git user
-        run: |
+        run: |-
           git config user.name 'github-actions[bot]'
           git config user.email 'github-actions[bot]@users.noreply.github.com'
       - name: Build and deploy documentation
diff --git a/.github/workflows/upgrade-dependencies.yml b/.github/workflows/upgrade-dependencies.yml
index c58c7b46..6c4288b6 100644
--- a/.github/workflows/upgrade-dependencies.yml
+++ b/.github/workflows/upgrade-dependencies.yml
@@ -5,8 +5,8 @@ name: Upgrade Dependencies
 on:
   workflow_dispatch:
   schedule:
-    # Runs every Monday at 8:00 UTC (4:00 Eastern)
-    - cron: 0 8 * * 1
+    # First day of every month at 08:00 UTC
+    - cron: 0 8 1 * *
 
 jobs:
   upgrade:
@@ -15,11 +15,7 @@ jobs:
     strategy:
       matrix:
         os: [ubuntu-latest]
-        python-version: ['3.8']
-    env:
-      # This branch will receive updates each time the workflow runs
-      # It doesn't matter if it's deleted when merged, it'll be re-created
-      BRANCH_NAME: auto-dependency-upgrades
+        python-version: [3.8.4]
     steps:
       - uses: actions/checkout@v3
       - uses: ./.github/actions/setup
@@ -28,31 +24,11 @@ jobs:
       - name: Upgrade Python dependencies
         run: poetry update
 
-      - name: Detect changes
-        id: changes
-        # This output boolean tells us if the dependencies have actually changed
-        run: echo "::set-output name=count::$(git status --short | wc -l)"
-      - name: Commit & push changes
-        # Only push if changes exist
-        if: steps.changes.outputs.count > 0
-        run: |
-          git config user.name 'github-actions[bot]'
-          git config user.email 'github-actions[bot]@users.noreply.github.com'
-          git add .
-          git commit -m "Automated dependency upgrades"
-          git push -f origin ${{ github.ref_name }}:$BRANCH_NAME
-      - name: Open pull request if needed
-        if: steps.changes.outputs.count > 0
-        env:
-          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
-        # Only open a PR if the branch is not attached to an existing one
-        run: |-
-          PR=$(gh pr list --head $BRANCH_NAME --json number -q '.[0].number')
-          if [ -z $PR ]; then
-            gh pr create \
-            --head $BRANCH_NAME \
-            --title "Automated dependency upgrades" \
-            --body "Full log: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}"
-          else
-            echo "Pull request already exists, won't create a new one."
-          fi
+      - name: Create Pull Request
+        uses: peter-evans/create-pull-request@v4
+        with:
+          title: 'build: automated dependency upgrades'
+          body: 'Full log: https://github.com/${{ github.repository }}/actions/runs/${{
+            github.run_id }}'
+          branch: auto-dependency-upgrades
+          delete-branch: true
diff --git a/.gitignore b/.gitignore
index b1636f5d..02a6c5d4 100644
--- a/.gitignore
+++ b/.gitignore
@@ -195,6 +195,9 @@ coverage.json
 !supporting/**
 !tests/data/**
 
+# Ensure that system files don't appear in the Allow List
+.DS_Store
+
 # Ensure *.pyc files are still ignored even if in tests/data directory
 *.pyc
 
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 0c55a446..95fc8030 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -38,7 +38,7 @@ repos:
     hooks:
       - id: beautysh
   - repo: https://github.com/commitizen-tools/commitizen
-    rev: v2.29.3
+    rev: v2.33.0
     hooks:
       - id: commitizen
         additional_dependencies: [cz_legacy]
@@ -77,7 +77,7 @@ repos:
         # args: ["--baseline", ".secrets.baseline"]
         exclude: poetry\.lock|.*/cassettes/.*\.yaml
   - repo: https://github.com/lyz-code/yamlfix/
-    rev: 1.0.1
+    rev: 1.1.0
     hooks:
       - id: yamlfix
         exclude: \.copier-answers\.yml|.*/cassettes/.*\.yaml
@@ -101,12 +101,12 @@ repos:
         name: Python Auto-Formatter
         description: Apply calcipy formatting
         language: system
-        entry: poetry run doit run --db-file='.doit.tmp-py' format_py
+        entry: poetry run doit run --db-file=./.doit.tmp-py format_py
         types: [python]
       - id: toml-formatter
         name: Optional TOML Auto-Formatter
         description: Install taplo with 'npm install -g @taplo/cli'
         language: system
-        entry: poetry run doit run --db-file='.doit.tmp-toml' format_toml
+        entry: poetry run doit run --db-file=./.doit.tmp-toml format_toml
         types: [toml]
         exclude: poetry\.lock
diff --git a/.pylintrc b/.pylintrc
index 1d8433cc..144b7939 100644
--- a/.pylintrc
+++ b/.pylintrc
@@ -1,3 +1,5 @@
+# TODO: Update from: https://github.com/PyCQA/pylint/blob/main/examples/pylintrc
+
 [MASTER]
 
 # A comma-separated list of package or module names from where C extensions may
diff --git a/.sourcery.yaml b/.sourcery.yaml
new file mode 100644
index 00000000..e0a0738a
--- /dev/null
+++ b/.sourcery.yaml
@@ -0,0 +1,923 @@
+---
+# See: https://docs.sourcery.ai/Configuration/
+refactor:
+  python_version: '3.7'
+
+# Full Google Style Set from: https://sourcery.ai/blog/google-python-style-guide/
+rules:
+# Import Rules
+  - id: no-wildcard-imports
+    pattern: from ... import *
+    description: Do not use wildcard imports
+    explanation: |
+      Use import statements for packages and modules only, not for individual classes or functions.
+      - Use `import x` for importing packages and modules.
+      - Use `from x import y` where `x` is the package prefix and `y` is the module name with no prefix.
+      - Use `from x import y as z` if two modules named `y` are to be imported, if `y` conflicts with a top-level name defined in the current module, or if `y` is an inconveniently long name.
+      - Use `import y as z` only when `z` is a standard abbreviation (e.g., np for numpy).
+      From: Google Style Guide [2.2.4](https://google.github.io/styleguide/pyguide.html#224-decision)
+    tests:
+      - match: from numpy import *
+      - match: from pandas.series import *
+      - match: from .something import *
+      - no-match: from math import sin
+
+  - id: no-relative-imports
+    description: Always use absolute imports instead of relative imports
+    explanation: |
+      Do not use relative names in imports. Even if the module is in the same package, use the full package name. This helps prevent unintentionally importing a package twice.
+      From Google Style Guide [2.2.4](https://google.github.io/styleguide/pyguide.html#224-decision)
+    pattern: from ${module} import ...
+    condition: module.matches_regex(r"^\.")
+    tests:
+      - match: from . import important_function
+      - match: from .my_module import important_function
+      - match: from ..my_module import important_function, unimportant_function
+      - no-match: from my_company.my_module import important_function
+      - no-match: from pathlib import Path
+
+  - id: use-standard-name-for-aliases-pandas
+    description: Import `pandas` as `pd`
+    explanation: |
+      Use `import y as z` only when `z` is a standard abbreviation.
+      From Google Style Guide [2.2.4](https://google.github.io/styleguide/pyguide.html#224-decision)
+    pattern: import ..., pandas as ${alias}, ...
+    condition: not alias.equals("pd")
+    tests:
+      - no-match: import pandas
+      - no-match: from pandas import DataFrame
+      - no-match: import pandas as pd
+      - no-match: import numpy, pandas as pd, tensorflow
+      - no-match: from modin import pandas as pds
+      - no-match: import modin.pandas as pds
+      - match: import pandas as pds
+      - match: import pandas as np
+      - match: import numpy, pandas as pds, tensorflow
+
+  - id: use-standard-name-for-aliases-numpy
+    description: Import `numpy` as `np`
+    explanation: |
+      Use `import y as z` only when `z` is a standard abbreviation.
+      From Google Style Guide [2.2.4](https://google.github.io/styleguide/pyguide.html#224-decision)
+    pattern: import ..., numpy as ${alias}, ...
+    condition: not alias.equals("np")
+    tests:
+      - no-match: import numpy
+      - no-match: from numpy import ndarray
+      - no-match: import numpy as np
+      - no-match: import pandas, numpy as np, tensorflow
+      - match: import numpy as numpie
+      - match: import numpy as pd
+      - match: import pandas, numpy as numpie, tensorflow
+
+  - id: use-standard-name-for-aliases-matplotlib-pyplot
+    description: Import `matplotlib.pyplot` as `plt`
+    explanation: |
+      Use `import y as z` only when `z` is a standard abbreviation.
+      From Google Style Guide [2.2.4](https://google.github.io/styleguide/pyguide.html#224-decision)
+    pattern: import ..., matplotlib.pyplot as ${alias}, ...
+    condition: not alias.equals("plt")
+    tests:
+      - no-match: import matplotlib.pyplot
+      - no-match: from matplotlib.pyplot import Figure
+      - no-match: import matplotlib.pyplot as plt
+      - no-match: import pandas, matplotlib.pyplot as plt, tensorflow
+      - match: import matplotlib.pyplot as mplplot
+      - match: import pandas, matplotlib.pyplot as mplplot, tensorflow
+
+  - id: use-standard-name-for-aliases-tensorflow
+    description: Import `tensorflow` as `tf`
+    explanation: |
+      Use `import y as z` only when `z` is a standard abbreviation.
+      From Google Style Guide [2.2.4](https://google.github.io/styleguide/pyguide.html#224-decision)
+    pattern: import ..., tensorflow as ${alias}, ...
+    condition: not alias.equals("tf")
+    tests:
+      - no-match: import tensorflow
+      - no-match: from tensorflow import keras
+      - no-match: import tensorflow as tf
+      - no-match: import pandas, tensorflow as tf
+      - match: import tensorflow as tflow
+      - match: import pandas, tensorflow as tflow
+
+  - id: use-standard-name-for-aliases-datetime
+    description: Import `datetime` as `dt`
+    explanation: |
+      Use `import y as z` only when `z` is a standard abbreviation.
+      From Google Style Guide [2.2.4](https://google.github.io/styleguide/pyguide.html#224-decision)
+    pattern: import ..., datetime as ${alias}, ...
+    condition: not alias.equals("dt")
+    tests:
+      - no-match: import datetime
+      - no-match: from datetime import datetime
+      - no-match: import datetime as dt
+      - no-match: import pandas, datetime as dt
+      - match: import datetime as dtime
+      - match: import pandas, datetime as dtime, tensorflow
+
+  - id: use-standard-name-for-aliases-tkinter
+    description: Import `tkinter` as `tk`
+    explanation: |
+      Use `import y as z` only when `z` is a standard abbreviation.
+      From Google Style Guide [2.2.4](https://google.github.io/styleguide/pyguide.html#224-decision)
+    pattern: import ..., tkinter as ${alias}, ...
+    condition: not alias.equals("tk")
+    tests:
+      - no-match: import tkinter
+      - no-match: from tkinter import ttk
+      - no-match: import tkinter as tk
+      - no-match: import pandas, tkinter as tk
+      - match: import tkinter as t
+      - match: import pandas, tkinter as t, tensorflow
+
+  - id: use-standard-name-for-aliases-multiprocessing
+    description: Import `multiprocessing` as `mp`
+    explanation: |
+      Use `import y as z` only when `z` is a standard abbreviation.
+      From Google Style Guide [2.2.4](https://google.github.io/styleguide/pyguide.html#224-decision)
+    pattern: import ..., multiprocessing as ${alias}, ...
+    condition: not alias.equals("mp")
+    tests:
+      - no-match: import multiprocessing
+      - no-match: from multiprocessing import Pool
+      - no-match: import multiprocessing as mp
+      - no-match: import pandas, multiprocessing as mp
+      - match: import multiprocessing as multi
+      - match: import pandas, multiprocessing as multi, tensorflow
+
+# Naming Rules
+
+  - id: avoid-single-character-names-variables
+    pattern: ${var} = ${value}
+    condition: var.character_count() == 1
+    description: Avoid single character names
+    explanation: |
+      Avoid single character names, except for specifically allowed cases:
+      - counters or iterators (e.g. `i`, `j`, `k`, `v`, et al.)
+      - `e` as an exception identifier in `try`/`except` statements.
+      - `f` as a file handle in `with` statements
+      - private `TypeVar`s with no constraints (e.g. `_T`, `_U`, `_V`)
+      From Google Style Guide [3.16.1](https://google.github.io/styleguide/pyguide.html#3161-names-to-avoid)
+    tests:
+      - match: i = 0
+      - no-match: initial_value = 0
+      - match: A = get_account()
+      - no-match: account = get_account()
+      - no-match: |
+          for i in range(10):
+              print(i)
+      - no-match: |
+          try:
+              explode_computer()
+          except ExplosionError as e:
+              pass
+      - no-match: |
+          with open("file.txt") as f:
+              contents = f.read()
+      - no-match: |
+          from typing import TypeVar
+          _T = TypeVar("_T")
+
+  - id: avoid-single-character-names-functions
+    pattern: |
+      def ${function_name}(...):
+        ...
+    condition: function_name.character_count() == 1
+    description: Avoid single character names
+    explanation: |
+      Avoid single character names, except for specifically allowed cases:
+      - counters or iterators (e.g. `i`, `j`, `k`, `v`, et al.)
+      - `e` as an exception identifier in `try`/`except` statements.
+      - `f` as a file handle in `with` statements
+      - private `TypeVar`s with no constraints (e.g. `_T`, `_U`, `_V`)
+      From Google Style Guide [3.16.1](https://google.github.io/styleguide/pyguide.html#3161-names-to-avoid)
+    tests:
+      - match: |
+          def f():
+              pass
+      - match: |
+          async def f():
+              pass
+      - no-match: |
+          def function_with_good_and_descriptive_name():
+              pass
+      - match: |
+          def g(a, b: int = 0, **kwargs) -> str:
+              if b > 5:
+                return str(a) + str(b) + str(kwargs)
+              return "b <= 4"
+      - no-match: |
+          def perform_calculation(a, b: int = 0, **kwargs) -> str:
+              if b > 5:
+                return str(a) + str(b) + str(kwargs)
+              return "b <= 4"
+      - match: |
+          class MyClass:
+            def m(self, a: int, b: float) -> str:
+              print(a)
+              return repr(b)
+      - no-match: |
+          class MyClass:
+            def good_method(self, a: int, b: float) -> str:
+              print(a)
+              return repr(b)
+
+  - id: name-type-suffix
+    pattern: ${name} = ${value}
+    condition: |
+      name.ends_with("_dict")
+      or name.ends_with("_list")
+      or name.ends_with("_set")
+      or name.ends_with("_int")
+      or name.ends_with("_float")
+      or name.ends_with("_str")
+    description: Don't use the type of a variable as a suffix
+    explanation: |
+      Names shouldn't needlessly include the type of the variable.
+      Such suffix might be OK for more complex types,
+      e.g. first_account, advanced_account.
+      But it's rarely necessary for built-in types.
+      From Google Style Guide [3.16.1](https://google.github.io/styleguide/pyguide.html#s3.16-naming)
+    tests:
+      - match: magic_int = 42
+      - match: magic_int = 42.00
+      - match: magic_float = 42
+      - match: magic_float = 42.00
+      - match: custom_notes_dict = {}
+
+  - id: errors-named-error
+    pattern: |
+      class ${error}(${base}):
+        ${statements*}
+    condition: (base.is_exception_type() or base.matches_regex("[A-Z][a-zA-Z]*Error"))
+      and not error.matches_regex("[A-Z][a-zA-Z]*Error")
+    description: Exception names must end in Error
+    explanation: |
+      From Google Style Guide [2.4.4](https://google.github.io/styleguide/pyguide.html#244-decision)
+    tests:
+      - match: |
+          class Foo(ValueError):
+            ...
+      - match: |
+          class ExampleException(CustomError):
+            def __init__(self, msg):
+              ...
+      - match: |
+          class InvalidName(Exception):
+            ...
+      - match: |
+          class InvalidName(BaseException):
+            ...
+      - no-match: |
+          class MyError(Exception):
+            def __init__(self, msg):
+              ...
+      - no-match: |
+          class NameError(AttributeError):
+            ...
+      - no-match: |
+          class Dog(Mammal):
+            ...
+
+  - id: snake-case-variable-declarations
+    pattern: |
+      ${var}: ${type_annotation}
+    condition: not var.is_snake_case() and not var.in_module_scope()
+    description: Use snake case for variable names
+    explanation: |
+      Use snake case for variables.
+      This rule catches only variables that were declared with a type annotation.
+      From Google Style Guide [3.16.2](https://google.github.io/styleguide/pyguide.html#s3.16.2-naming-conventions) and [PEP 8](https://peps.python.org/pep-0008/#function-and-variable-names)
+    tests:
+      - match: |
+          def some_function():
+            miXed: int
+      - match: |
+          def some_function():
+            CamelCase: int
+      - match: |
+          def some_function():
+            CamelCase42: int
+      - match: |
+          def some_function():
+            mixed_and_underScore: int
+      - match: |
+          def some_function():
+            too__many__underscores: str
+      - match: |
+          def some_function():
+            _too__many__underscores: str
+      - match: |
+          def some_function():
+            ___3_underscores_prefix: str
+      - match: |
+          def some_function():
+            double_underscore_suffix__: str
+      - no-match: |
+          def some_function():
+            nr: int = 42
+      - no-match: |
+          def some_function():
+            miXed: int = 42
+      - no-match: |
+          def some_function():
+            snake_nr: int = 42
+      - no-match: simple_NR = 42
+      - no-match: CONTEXT = "whatever"
+      - no-match: |
+          def some_function():
+            _initial_value: int = 0
+      - no-match: |
+          def some_function():
+            __initial_value: int = 0
+      - no-match: __version__ = "3.14"
+
+  - id: snake-case-arguments
+    pattern: |
+      def ...(...,${arg_name}: ${type?} = ${default_value?},...):
+        ...
+    condition: not arg_name.is_snake_case() or arg_name.is_dunder_name()
+    description: Use snake case for arguments
+    explanation: |
+      Use snake case for function and method arguments.
+      From Google Style Guide [3.16.2](https://google.github.io/styleguide/pyguide.html#s3.16.2-naming-conventions) and [PEP 8](https://peps.python.org/pep-0008/#function-and-method-arguments)
+    tests:
+      - match: |
+          def placeholder(miXed):
+            pass
+      - match: |
+          def placeholder(randomWord):
+            pass
+      - match: |
+          def placeholder(randomWord: str):
+            pass
+      - match: |
+          def placeholder(randomWord: str = "random"):
+            pass
+      - match: |
+          def placeholder(randomWord, other):
+            pass
+      - match: |
+          class Something:
+            def placeholder(self,myCamelWord):
+              pass
+      - match: |
+          def placeholder(too__many__underscores):
+            pass
+      - match: |
+          def placeholder(double_underscore_suffix__):
+            pass
+      - match: |
+          def placeholder(mixed_and_underScore):
+            pass
+      - match: |
+          def placeholder(__dunder_arg__):
+            pass
+      - no-match: |
+          def placeholder(nice_arg_name):
+            pass
+      - no-match: |
+          def placeholder(nice_arg_name: str):
+            pass
+      - no-match: |
+          def placeholder(nice_arg_name: str = "random"):
+            pass
+      - no-match: |
+          def placeholder(simple):
+            pass
+      - no-match: |
+          def placeholder(simple: bool = False):
+            pass
+      - no-match: |
+          def placeholder(nr, other_nr, sth_completely_different):
+            pass
+      - no-match: |
+          class Something:
+            def placeholder(self,simple: bool = False):
+              pass
+
+  - id: snake-case-functions
+    pattern: |
+      def ${function_name}(...):
+        ...
+    condition: not function_name.is_snake_case()
+    description: Use snake case for function names
+    explanation: |
+      Use snake case for function and method names.
+      From Google Style Guide [3.16.2](https://google.github.io/styleguide/pyguide.html#s3.16.2-naming-conventions) and [PEP 8](https://peps.python.org/pep-0008/#function-and-variable-names)
+    tests:
+      - match: |
+          def miXed():
+            pass
+      - match: |
+          def CamelCase():
+            pass
+      - match: |
+          class Something:
+            def CamelCase(self):
+              pass
+      - match: |
+          def too__many__underscores():
+            pass
+      - match: |
+          def double_underscore_suffix__():
+            pass
+      - match: |
+          def mixed_and_underScore():
+            pass
+      - no-match: |
+          def nice_function_name():
+            pass
+      - no-match: |
+          def _private():
+            pass
+      - no-match: |
+          def __very_private():
+            pass
+      - no-match: |
+          class Something:
+            def single(self):
+              pass
+      - no-match: |
+          class Something:
+            def __init__(self):
+              pass
+
+  - id: camel-case-classes
+    pattern: |
+      class ${class_name}(...):
+        ...
+    condition: not class_name.is_upper_camel_case()
+    description: Use camel case for class names
+    explanation: |
+      Use camel case for class names
+      From Google Style Guide [3.16.2](https://google.github.io/styleguide/pyguide.html#s3.16.2-naming-conventions) and [PEP 8](https://peps.python.org/pep-0008/#class-names)
+    tests:
+      - match: |
+          class lower:
+            pass
+      - match: |
+          class UPPER:
+            pass
+      - match: |
+          class snake_case:
+            pass
+      - match: |
+          class UPPER_UNDERSCORE:
+            pass
+      - match: |
+          class CamelCase_WithUnderscore:
+            pass
+      - no-match: |
+          class CamelCase:
+            pass
+      - no-match: |
+          class CamelCase42:
+            pass
+      - no-match: |
+          class B:
+            pass
+
+# Structural Rules
+
+  - id: do-not-use-staticmethod
+    pattern: |
+      @staticmethod
+      def ${name}(...):
+        ...
+    description: Do not use the staticmethod decorator
+    explanation: |
+      Never use staticmethod unless forced to in order to integrate with an API defined in an existing library. Write a module level function instead.
+      From: Google Style Guide [2.17.4](https://google.github.io/styleguide/pyguide.html#2174-decision)
+    tests:
+      - match: |
+          @staticmethod
+          def suggested_event(new_suggestion) -> str:
+              pass
+      - match: |
+          @staticmethod
+          def suggested_event(new_suggestion: bool) -> str:
+              pass
+      - no-match: |
+          def suggested_event(new_suggestion) -> str:
+              pass
+      - no-match: |
+          @staticmethod  # Note that this will not currently trigger where there are other decorators
+          @other_decorator
+          def suggested_event(new_suggestion) -> str:
+              pass
+
+  - id: no-complex-if-expressions
+    description: Only use conditional expressions for simple cases
+    explanation: |
+      Each portion [of the conditional expression] must fit on one line: `true-expression`, `if-expression`, `else-expression`. Use a complete if statement when things get more complicated.
+      From Google Style Guide [2.11.4](https://google.github.io/styleguide/pyguide.html#2114-decision)
+    pattern: ${value} if ${test} else ${default}
+    condition: value.character_count() > 80 or test.character_count() > 80 or default.character_count()
+      > 80
+    tests:
+      - no-match: a = 1 if cond else 2
+      - match: a = 1 if this_is_an_incredibly_long_condition_that_is_more_than_80_characters_long_no_joking_around
+          else 2
+      - match: a = this_is_an_incredibly_long_value_that_is_more_than_80_characters_long_no_joking_around
+          if cond else 2
+      - match: a = 1 if cond else this_is_an_incredibly_long_value_that_is_more_than_80_characters_long_no_joking_around
+      - match: a = 1 if cond else this_is_an_incredibly_long_value + is_more_than_80_characters_long_no_joking_around()
+
+  - id: lambdas-should-be-short
+    description: Lambda functions should be kept to a single line
+    explanation: |
+      Okay to use them for one-liners.
+      If the code inside the lambda function is longer than 60-80 chars, it’s probably better to define it as a regular nested function.
+      From Google Style Guide [2.10.4](https://google.github.io/styleguide/pyguide.html#2104-decision)
+    pattern: 'lambda ...: ${body}'
+    condition: body.character_count() > 80
+    tests:
+      - no-match: 'lambda x: x**2'
+      - no-match: 'lambda x, y: x**y'
+      - match: 'lambda x: do_something_very_long_and_involved_with(x) - do_other_very_long_and_involved_things_with(x)'
+      - match: 'lambda x, y, z: do_something_very_long_and_involved_with(x) - do_other_very_long_and_involved_things_with(y,
+          z)'
+
+  - id: map-lambda-to-generator
+    pattern: 'map(lambda ${arg}: ${expr}, ${items})'
+    replacement: (${expr} for ${arg} in ${items})
+    description: Replace mapping a lambda with a generator expression
+    explanation: |
+      Prefer generator expressions over map() or filter() with a lambda.
+      From Google Style Guide [2.10](https://google.github.io/styleguide/pyguide.html#210-lambda-functions)
+    tests:
+      - match: 'transformed_things = map(lambda x: x**2, things)'
+        expect: transformed_things = (x**2 for x in things)
+      - match: 'list(map(lambda x: x**2, things))'
+        expect: list(x**2 for x in things)
+      - no-match: 'filter(lambda x: x > x**2, things)'
+
+  - id: filter-lambda-to-generator
+    pattern: 'filter(lambda ${arg}: ${expr}, ${items})'
+    replacement: (${arg} for ${arg} in ${items} if ${expr})
+    description: Replace filtering with a lambda with a generator expression
+    explanation: |
+      Prefer generator expressions over map() or filter() with a lambda.
+      From Google Style Guide [2.10](https://google.github.io/styleguide/pyguide.html#210-lambda-functions)
+    tests:
+      - match: 'filtered_things = filter(lambda x: x > x**2, things)'
+        expect: filtered_things = (x for x in things if x > x**2)
+      - match: 'list(filter(lambda x: x > x**2, things))'
+        expect: list(x for x in things if x > x**2)
+      - no-match: 'map(lambda x: x**2, things)'
+
+  - id: avoid-global-variables
+    pattern: ${var} = ${value}
+    condition: pattern.in_module_scope() and var.is_lower_case() and not var.starts_with("_")
+      and var.is_identifier()
+    description: Do not define variables at the module level - (found variable ${var})
+    explanation: |
+      Avoid global variables.
+      If needed, global variables should be declared at the module level and made internal to the module by prepending an `_` to the name. External access to global variables must be done through public module-level functions.
+      While module-level constants are technically variables, they are permitted and encouraged. For example: `MAX_HOLY_HANDGRENADE_COUNT = 3`. Constants must be named using all caps with underscores.
+      From Google Style Guide [2.5.4](https://google.github.io/styleguide/pyguide.html#254-decision)
+    tests:
+      - match: max_holy_handgrenade_count = 3
+      - match: 'max_holy_handgrenade_count: int = 3'
+      - no-match: holy_handgrenade[1] = 3
+      - no-match: _max_holy_handgrenade_count = 3
+      - no-match: HolyGrenades = Dict[str, Grenade]
+      - no-match: MAX_HOLY_HANDGRENADE_COUNT = 3
+      - no-match: |
+          def f():
+              max_holy_handgrenade_count = 3
+
+  - id: avoid-trivial-properties
+    description: Avoid defining trivial properties
+    explanation: |
+      Getter and setter functions (also called accessors and mutators) should be used when
+      they provide a meaningful role or behavior for getting or setting a variable's
+      value.
+      In particular, they should be used when getting or setting the variable is complex
+      or the cost is significant, either currently or in a reasonable future.
+      If, for example, a pair of getters/setters simply read and write an internal
+      attribute, the internal attribute should be made public instead. By comparison, if
+      setting a variable means some state is invalidated or rebuilt, it should be a setter
+      function. The function invocation hints that a potentially non-trivial operation is
+      occurring. Alternatively, properties may be an option when simple logic is needed,
+      or refactoring to no longer need getters and setters.
+      From Google Style Guide [3.15](https://google.github.io/styleguide/pyguide#315-getters-and-setters)
+    pattern: |
+      @property
+      def ${f}(self):
+        return self.${value}
+      ...
+      @${f}.setter
+      def ${setter}(self, ${other}):
+        self.${value} = ${other}
+    tests:
+      - match: |
+          class Student:
+            def __init__(self, name):
+              self._name = name
+            @property
+            def name(self):
+              return self._name
+            @name.setter
+            def name(self, new_name):
+              self._name = new_name
+      - match: |
+          class Student:
+            def __init__(self, name, grade):
+              self._name = name
+              self._grade = grade
+            @property
+            def name(self):
+              return self._name
+            def get_grade(self):
+              return self._grade
+            @name.setter
+            def name(self, new_name):
+              self._name = new_name
+      - match: |
+          class Student:
+            def __init__(self, name: str) -> None:
+              self._name: str = name
+            @property
+            def name(self) -> str:
+              return self._name
+            @name.setter
+            def name(self, new_name: str) -> None:
+              self._name = new_name
+      - no-match: |
+          class Student:
+            def __init__(self, name: str) -> None:
+              self._name: str = name
+            @property
+            def name(self) -> str:
+              return self._name.title()  # perform computation on name
+            @name.setter
+            def name(self, new_name: str) -> None:
+              self._name = new_name
+      - no-match: |
+          class Student:
+            def __init__(self, name: str) -> None:
+              self._name: str = name
+            @property
+            def name(self) -> str:
+              return self._name.title()  # perform computation on name
+            # no setter: this means that `Student.name` is read-only
+
+  - id: no-long-functions
+    pattern: |
+      def ${name}(...):
+          ${statements+}
+    condition: statements.statement_count() > 40
+    description: Functions should be less than 40 lines
+    explanation: |
+      Prefer small and focused functions.
+      We recognize that long functions are sometimes appropriate, so no hard limit is placed on function length. If a function exceeds about 40 lines, think about whether it can be broken up without harming the structure of the program.
+      Even if your long function works perfectly now, someone modifying it in a few months may add new behavior. This could result in bugs that are hard to find. Keeping your functions short and simple makes it easier for other people to read and modify your code.
+      From Google Style Guide [3.18](https://google.github.io/styleguide/pyguide.html#318-function-length)
+    tests:
+      - no-match: |
+          def f(a, b) -> int:
+              x()
+
+  - id: do-not-use-has-key
+    pattern: ${d}.has_key(${key})
+    condition: d.has_type("dict")
+    replacement: ${key} in ${d}
+    description: Replace Python 2 syntax `dict.has_key` with a Python 3 membership
+      test
+    explanation: |
+      Use default iterators and operators for types that support them, like lists, dictionaries, and files. The built-in types define iterator methods, too. Prefer these methods to methods that return lists, except that you should not mutate a container while iterating over it.
+      From Google Style Guide [2.8.4](https://google.github.io/styleguide/pyguide.html#284-decision)
+      Note that the method `dict.has_key` is only available in Python 2, but Sourcery only
+      works with Python 3 code. Hence, this rule prevents programmers from erroneously
+      checking membership with `dictionary.has_key(key)`, suggesting instead the use of
+      the correct Python 3 syntax `key in dictionary`.
+    tests:
+      - match: |
+          tasks_for_today: dict[str, Task] = get_tasks("today")
+          is_week_day = tasks_for_today.has_key("work")
+        expect: |
+          tasks_for_today: dict[str, Task] = get_tasks("today")
+          is_week_day = "work" in tasks_for_today
+      - match: |
+          def is_movie_in_database(movie: Movie, movies: Dict[Movie, MovieSpec]) -> bool:
+            return movies.has_key(movie)
+        expect: |
+          def is_movie_in_database(movie: Movie, movies: Dict[Movie, MovieSpec]) -> bool:
+            return movie in movies
+      - match: |
+          pro_users = {
+            user.name: user
+            for user in database.fetch(User)
+          }
+          if pro_users.has_key(get_current_user().name):
+            print("You've signed in under the PRO subscription")
+          else:
+            print("Please sign up for PRO to use this awesome feature!")
+        expect: |
+          pro_users = {
+            user.name: user
+            for user in database.fetch(User)
+          }
+          if get_current_user().name in pro_users:
+            print("You've signed in under the PRO subscription")
+          else:
+            print("Please sign up for PRO to use this awesome feature!")
+      - no-match: |
+          # Not sure of `random_object` is a dictionary
+          random_object.has_key(random_key)
+      - no-match: |
+          # Custom type `Database` is not a dictionary
+          database: Database = get_database()
+          print(database.has_key("dinosaur"))
+
+# Typing Rules
+
+  - id: require-parameter-annotation
+    pattern: |
+      def ${name}(..., ${arg}: !!!=${default?}, ...):
+          ...
+    condition: not name.starts_with("_") and not arg.equals("self") and not arg.equals("cls")
+    paths:
+      exclude:
+        - test/
+        - tests/
+    description: Annotate parameter `${arg}` in public function/method `${name}` with
+      a type annotation
+    explanation: |
+      Adding type annotations has several benefits:
+      1. It improves the documentation of the function
+      2. It allows the function to be checked for correctness
+      3. It allows checking that the function callers are passing the correct params
+      These [mypy docs](https://mypy.readthedocs.io/en/stable/cheat_sheet_py3.html#functions) describe how to
+      annotate function arguments and return types.
+      From Google Style Guide [2.21](https://google.github.io/styleguide/pyguide#221-type-annotated-code)
+    tests:
+      - match: |
+          def add(a, b: int):
+            return a + b
+      - match: |
+          def f(a=1):
+            return a * 2
+      - no-match: |
+          def f() -> int:
+              pass
+      - no-match: |
+          def f(a: int, b: str):
+              pass
+      - no-match: |
+          def f(self, a: int, b: str):
+              pass
+      - no-match: |
+          def f(cls, a: int, b: str):
+              pass
+
+  - id: require-return-annotation
+    pattern: |
+      def ${name}(...) -> !!!:
+          ...
+    condition: not name.starts_with("_")
+    paths:
+      exclude:
+        - test/
+        - tests/
+    description: Annotate public function/method `${name}` with a return type annotation
+    explanation: |
+      Adding type annotations has several benefits:
+      1. It improves the documentation of the function
+      2. It allows the function to be checked for correctness
+      3. It allows checking that the function callers are passing the correct params
+      These [mypy docs](https://mypy.readthedocs.io/en/stable/cheat_sheet_py3.html#functions) describe how to
+      annotate function arguments and return types.
+      From Google Style Guide [2.21](https://google.github.io/styleguide/pyguide#221-type-annotated-code)
+    tests:
+      - match: |
+          def f():
+              x()
+      - no-match: |
+          def f() -> int:
+              x()
+      - match: |
+          def f(a: int, b: str):
+              x()
+      - no-match: |
+          def f(something) -> int:
+              x()
+
+# Docstring Rules
+
+  - id: docstrings-for-classes
+    pattern: |
+      class ${c}(...):
+        """!!!"""
+        ...
+    description: Public classes should have docstrings
+    explanation: |
+      All public classes should have a docstring describing the class.
+      The class docstring should also document the class' public attributes.
+      From Google Style Guide [3.8.4](https://google.github.io/styleguide/pyguide.html#384-classes)
+    condition: not c.starts_with("_")
+    paths:
+      exclude:
+        - test/
+        - tests/
+    tests:
+      - match: |
+          class CheeseShopAddress:
+            ...
+      - match: |
+          class CheeseShopAddress(Address):
+            ...
+      - match: |
+          class OutOfCheeseError(Exception):
+            def __str__(self):
+              ...
+      - no-match: |
+          class CheeseShopAddress:
+            """The address of a cheese shop."""
+      - no-match: |
+          class OutOfCheeseError(Exception):
+            """No more cheese is available."""
+            def __str__(self):
+              ...
+      - no-match: |
+          class _BrieCounter:
+            limit: 500
+
+  - id: docstrings-for-functions
+    pattern: |
+      def ${f}(...):
+        """!!!"""
+        ${body*}
+    description: Functions should have docstrings
+    explanation: |
+      A function must have a docstring, unless it meets all of the following criteria:
+      - not externally visible
+      - very short
+      - obvious
+      From Google Style Guide [3.8.3](https://google.github.io/styleguide/pyguide.html#383-functions-and-methods)
+    condition: not ((f.starts_with("_") and body.statement_count() < 5) or pattern.in_function_scope())
+    paths:
+      exclude:
+        - test/
+        - tests/
+    tests:
+      - match: |
+          def grow(plant):
+            assert plant.is_alive()
+            _grow(plant)
+      - match: |
+          def _grow(plant):
+            pot = plant.owner.get_empty_pot()
+            pot.contents.add("soil", fraction=0.5)
+            pot.contents.add(plant, orientation="vertical")
+            for day in range(0, plant.__class__.gestation_time, plant.__class__.watering_interval):
+              pot.contents.add("water", amount="200ml")
+      - no-match: |
+          class PotContents:
+            def add(item, fraction=None, amount=None, **kwargs):
+              """Adds `item` to the pot.
+              The pot can be filled to either a `fraction` of its volume, or by an `amount` specified.
+              """
+              ...
+      - no-match: |
+          def _log_growth(plant):
+            logger.info("plant size: %s", plant.size)
+      - no-match: |
+          def log_growth_error(f):
+            """Captures and logs any growth errors inside `f`"""
+            def wrapped(*args, **kwargs):
+              try:
+                return f(*args, **kwargs)
+              except GrowthError:
+                logger.warning("growth error")
+            return wrapped
+
+  - id: docstrings-for-modules
+    pattern: |
+      '''!!!'''
+      ...
+    condition: pattern.in_module_scope()
+    paths:
+      exclude:
+        - test/
+        - tests/
+    description: Modules should have docstrings
+    explanation: |
+      Modules (Python files) should start with docstrings describing the contents and usage of the module.
+      From Google Style Guide [3.8.2](https://google.github.io/styleguide/pyguide.html#382-modules)
+    tests:
+      - match: |
+          def hello():
+            print("hello")
+      - match: |
+          class Hello:
+            """Hello"""
+            def hello():
+              """Prints 'hello'"""
+              print("hello")
+      - no-match: |-
+          """Hello module"""
+          def hello():
+            print("hello")
diff --git a/calcipy/code_tag_collector.py b/calcipy/code_tag_collector.py
index cbd86a59..fdf59bf9 100644
--- a/calcipy/code_tag_collector.py
+++ b/calcipy/code_tag_collector.py
@@ -6,13 +6,12 @@
 from pathlib import Path
 from subprocess import CalledProcessError  # nosec
 
+import arrow
 import pandas as pd
-import pendulum
-from attrs import field, frozen
-from attrs_strict import type_validator
 from beartype import beartype
 from beartype.typing import Dict, List, Optional, Pattern, Sequence, Tuple
 from loguru import logger
+from pydantic import BaseModel
 
 from .file_helpers import read_lines
 from .log_helpers import log_fun
@@ -34,21 +33,25 @@
 """
 
 
-@frozen
-class _CodeTag:
+class _CodeTag(BaseModel):
     """Code Tag (FIXME,TODO,etc) with contextual information."""  # noqa: T100,T101
 
-    lineno: int = field(validator=type_validator())
-    tag: str = field(validator=type_validator())
-    text: str = field(validator=type_validator())
+    lineno: int
+    tag: str
+    text: str
 
+    class Config:
+        frozen = True
 
-@frozen
-class _Tags:
+
+class _Tags(BaseModel):
     """Collection of code tags with additional contextual information."""
 
-    path_source: Path = field(validator=type_validator())
-    code_tags: List[_CodeTag] = field(validator=type_validator())
+    path_source: Path
+    code_tags: List[_CodeTag]
+
+    class Config:
+        frozen = True
 
 
 @beartype
@@ -76,7 +79,7 @@ def _search_lines(
         if match:
             if len(line) <= 400:  # FYI: Suppress long lines
                 group = match.groupdict()
-                comments.append(_CodeTag(lineno + 1, tag=group['tag'], text=group['text']))
+                comments.append(_CodeTag(lineno=lineno + 1, tag=group['tag'], text=group['text']))
             else:
                 logger.debug('Skipping long line {lineno}: `{line}`', lineno=lineno, line=line[:200])
     return comments
@@ -104,7 +107,7 @@ def _search_files(paths_source: Sequence[Path], regex_compiled: Pattern[str]) ->
 
         comments = _search_lines(lines, regex_compiled)
         if comments:
-            matches.append(_Tags(path_source, comments))
+            matches.append(_Tags(path_source=path_source, code_tags=comments))
 
     return matches
 
@@ -174,9 +177,9 @@ def _format_record(base_dir: Path, file_path: Path, comment: _CodeTag) -> Dict[s
         }
         # Handle uncommitted files that only have author-time and author-tz
         user = 'committer' if 'committer-tz' in blame_dict else 'author'
-        dt = pendulum.from_timestamp(int(blame_dict[f'{user}-time']))
+        dt = arrow.get(int(blame_dict[f'{user}-time']))
         tz = blame_dict[f'{user}-tz'][:3] + ':' + blame_dict[f'{user}-tz'][-2:]
-        ts = pendulum.parse(dt.isoformat()[:-6] + tz).format('YYYY-MM-DD')
+        ts = arrow.get(dt.isoformat()[:-6] + tz).format('YYYY-MM-DD')
         # Filename may not be present if uncommitted. Use local path as fallback
         remote_file_path = blame_dict.get('filename', rel_path.as_posix())
         # PLANNED: Consider making "blame" configurable
@@ -216,7 +219,7 @@ def _format_report(
                 counter[comment.tag] += 1
     if records:
         df_tags = pd.DataFrame(records)
-        output += df_tags.to_markdown(index=False, tablefmt='github')
+        output += df_tags.to_markdown(index=False, tablefmt='github') or ''
     logger.debug('counter={counter}', counter=counter)
 
     sorted_counter = {tag: counter[tag] for tag in tag_order if tag in counter}
diff --git a/calcipy/dev/noxfile.py b/calcipy/dev/noxfile.py
index 2cd09fae..590d4d77 100644
--- a/calcipy/dev/noxfile.py
+++ b/calcipy/dev/noxfile.py
@@ -6,12 +6,12 @@
 poetry run nox -l
 poetry run nox --list-sessions
 
-poetry run nox -s build_check-3.9 build_dist-3.9 check_safety-3.9
-poetry run nox --session check_safety-3.9
+poetry run nox -s build_check-3.9 build_dist-3.9 check_security-3.9
+poetry run nox --session check_security-3.9
 
 poetry run nox --python 3.8
 
-poetry run nox -k "not tests and not check_safety"
+poetry run nox -k "not tests and not check_security"
 ```
 
 Useful nox snippets
@@ -32,7 +32,6 @@
 
 """
 
-import json
 import re
 import shlex
 from contextlib import suppress
@@ -44,7 +43,7 @@
 from beartype.typing import Callable, Dict, List
 from loguru import logger
 
-from ..doit_tasks.doit_globals import DG, DoitAction, DoitTask
+from ..doit_tasks.doit_globals import DoitAction, DoitTask, get_dg
 from ..doit_tasks.test import task_coverage, task_test
 from ..file_helpers import if_found_unlink
 
@@ -97,7 +96,7 @@ def _install_calcipy_extras(session: Session, extras: List[str]) -> None:
             extras: list of extras to install
 
         """
-        if DG.meta.pkg_name == 'calcipy':
+        if get_dg().meta.pkg_name == 'calcipy':
             session.poetry.installroot(extras=extras)
         else:  # pragma: no cover
             session.install('.', f'calcipy[{",".join(extras)}]')
@@ -152,7 +151,7 @@ def _run_doit_task(session: Session, task_fun: Callable[[], DoitTask]) -> None:
             else:
                 raise NotImplementedError(f'Unable to run {action} ({type(action)})')
 
-    @nox_session(python=DG.test.pythons, reuse_venv=True)
+    @nox_session(python=get_dg().test.pythons, reuse_venv=True)
     def tests(session: Session) -> None:
         """Run doit test task for specified python versions.
 
@@ -164,7 +163,7 @@ def tests(session: Session) -> None:
         _install_pinned(session, key=_DEV_KEY)
         _run_doit_task(session, task_test)
 
-    @nox_session(python=DG.test.pythons[-1:], reuse_venv=True)
+    @nox_session(python=get_dg().test.pythons[-1:], reuse_venv=True)
     def coverage(session: Session) -> None:
         """Run doit test task for specified python versions.
 
@@ -176,7 +175,7 @@ def coverage(session: Session) -> None:
         _install_pinned(session, key=_DEV_KEY)
         _run_doit_task(session, task_coverage)
 
-    @nox_session(python=DG.test.pythons[-1:], reuse_venv=False)
+    @nox_session(python=get_dg().test.pythons[-1:], reuse_venv=False)
     def build_dist(session: Session) -> None:
         """Build the project files within a controlled environment for repeatability.
 
@@ -184,14 +183,14 @@ def build_dist(session: Session) -> None:
             session: nox_poetry Session
 
         """
-        if_found_unlink(DG.meta.path_project / 'dist')
+        if_found_unlink(get_dg().meta.path_project / 'dist')
         path_wheel = session.poetry.build_package()
         logger.info(f'Created wheel: {path_wheel}')
         # Install the wheel and check that imports without any of the optional dependencies
         session.install(path_wheel)
         session.run(*shlex.split('python scripts/check_imports.py'), stdout=True)
 
-    @nox_session(python=DG.test.pythons[-1:], reuse_venv=True)
+    @nox_session(python=get_dg().test.pythons[-1:], reuse_venv=True)
     def build_check(session: Session) -> None:
         """Check that the built output meets all checks.
 
@@ -209,30 +208,7 @@ def build_check(session: Session) -> None:
         session.install('poetry>=1.2.0b3')  # required for "poetry.core.masonry.api" build backend
         session.run('pyroma', '--file', path_sdist.as_posix(), '--min=9', stdout=True)
 
-    @nox_session(python=DG.test.pythons[-1:], reuse_venv=True)
-    def check_safety(session: Session) -> None:
-        """Check for known vulnerabilities with safety.
-
-        Based on: https://github.com/pyupio/safety/issues/201#issuecomment-632627366
-
-        Args:
-            session: nox_poetry Session
-
-        Raises:
-            RuntimeError: if safety exited with errors, but not caught by session
-
-        """
-        session.install('safety>=2.1.1', '--upgrade')
-        path_requirements = session.poetry.export_requirements().resolve()
-        path_report = Path('insecure_report.json').resolve()
-        logger.info(f'Creating safety report: {path_report}')
-        session.run(*shlex.split(f'safety check --file {path_requirements} --save-json {path_report}'), stdout=True)
-        report_data = json.loads(path_report.read_text())
-        if report_data['vulnerabilities']:
-            raise RuntimeError(f'Found safety warnings in {path_report}: {report_data}')
-        path_report.unlink()
-
-    @nox_session(python=DG.test.pythons[-1:], reuse_venv=True)
+    @nox_session(python=get_dg().test.pythons[-1:], reuse_venv=True)
     def check_security(session: Session) -> None:
         """More general checks for common security issues.
 
@@ -240,8 +216,7 @@ def check_security(session: Session) -> None:
             session: nox_poetry Session
 
         """
-        session.install('semgrep>=0.106.0', '--upgrade')  # Runs "safety" and other tools
-        allow_py_rules = '--dangerously-allow-arbitrary-code-execution-from-rules'
+        session.install('semgrep>=0.112.1', '--upgrade')  # Runs "safety" and other tools
         # TODO: Implement semgrep - what are a good ruleset to start with? Currently only a nox-session (no doit task)
         #   https://github.com/returntocorp/semgrep-rules/tree/develop/python
         #   https://awesomeopensource.com/project/returntocorp/semgrep-rules?categorypage=45
@@ -269,10 +244,10 @@ def check_security(session: Session) -> None:
             # dlukeomalley:flask-set-cookie
             # clintgibler:no-exec
         ])
-        session.run(*shlex.split(f'semgrep {DG.meta.pkg_name} {allow_py_rules} {configs}'), stdout=True)
+        session.run(*shlex.split(f'semgrep {get_dg().meta.pkg_name} {configs}'), stdout=True)
 
     # TODO: https://github.com/tonybaloney/wily/blob/e72b7d95228bbe5538a072dc5d1186daa318bb03/src/wily/__main__.py#L261
-    @nox_session(python=DG.test.pythons[-1:], reuse_venv=True)
+    @nox_session(python=get_dg().test.pythons[-1:], reuse_venv=True)
     def check_wily(session: Session) -> None:
         """Run `wily` separately because of dependency constraints.
 
@@ -289,13 +264,13 @@ def check_wily(session: Session) -> None:
         #     'halstead.h1', 'halstead.vocabulary', 'halstead.length', 'halstead.volume', 'halstead.difficulty', 'halstead.effort',
         # ])
         build_args = '--max-revisions 50'
-        report_args = f'--output {DG.meta.path_project}/report.txt --message --number 50'
+        report_args = f'--output {get_dg().meta.path_project}/report.txt --message --number 50'
         with suppress(Exception):
-            session.run(*shlex.split(f'wily build {DG.meta.pkg_name} {build_args}'), stdout=True)
-            session.run(*shlex.split(f'wily report {DG.meta.pkg_name} {report_args}'), stdout=True)
+            session.run(*shlex.split(f'wily build {get_dg().meta.pkg_name} {build_args}'), stdout=True)
+            session.run(*shlex.split(f'wily report {get_dg().meta.pkg_name} {report_args}'), stdout=True)
 
             # FYI: Opens plotly graph in web browser and not necessary to run "wily" again
             # metric = 'raw.loc'  # 'cyclomatic.complexity' 'maintainability.mi' 'halstead.h1'
-            # session.run(*shlex.split(f'wily graph {DG.meta.pkg_name} {metric}'), stdout=True)
+            # session.run(*shlex.split(f'wily graph {get_dg().meta.pkg_name} {metric}'), stdout=True)
 
         # TODO: Could use file archiver instead of git when the above fails?
diff --git a/calcipy/doit_tasks/base.py b/calcipy/doit_tasks/base.py
index e0d63c99..0e10ccaa 100755
--- a/calcipy/doit_tasks/base.py
+++ b/calcipy/doit_tasks/base.py
@@ -12,7 +12,7 @@
 from sty import fg
 
 from ..file_helpers import if_found_unlink
-from .doit_globals import DG, DoitAction, DoitTask
+from .doit_globals import DoitAction, DoitTask, get_dg
 
 
 @beartype
@@ -27,7 +27,7 @@ def _show_cmd(task: Task) -> str:
 
     """
     def clean_action(action: str) -> str:
-        action = action.replace(f'{DG.meta.path_project.as_posix()}/', '')
+        action = action.replace(f'{get_dg().meta.path_project.as_posix()}/', '')
         if 'password' in action:
             action = action.split('password')[0] + '...password-redacted...'
         return action  # noqa: R504
@@ -115,7 +115,7 @@ def _zip_release() -> List[DoitAction]:
 
     """
     actions = []
-    for path_dir in [DG.test.path_out, DG.doc.path_out]:
+    for path_dir in [get_dg().test.path_out, get_dg().doc.path_out]:
         if path_dir.is_dir():
             path_zip = path_dir.with_suffix('.zip')
             actions.extend([
diff --git a/calcipy/doit_tasks/code_tags.py b/calcipy/doit_tasks/code_tags.py
index 1eb993e3..e5a2fc7f 100644
--- a/calcipy/doit_tasks/code_tags.py
+++ b/calcipy/doit_tasks/code_tags.py
@@ -5,7 +5,7 @@
 from ..code_tag_collector import write_code_tag_file
 from ..file_helpers import get_relative
 from .base import debug_task
-from .doit_globals import DG, DoitTask
+from .doit_globals import DoitTask, get_dg
 
 
 @beartype
@@ -17,13 +17,13 @@ def task_collect_code_tags() -> DoitTask:
 
     """
     # Filter out any files that are auto-generated and would have duplicate code tags, such as the documentation
-    user_files = [pth for pth in DG.meta.paths if not get_relative(pth, DG.doc.auto_doc_path)]
+    user_files = [pth for pth in get_dg().meta.paths if not get_relative(pth, get_dg().doc.auto_doc_path)]
     kwargs = {
-        'path_tag_summary': DG.tags.path_code_tag_summary,
+        'path_tag_summary': get_dg().tags.path_code_tag_summary,
         'paths_source': user_files,
-        'base_dir': DG.meta.path_project,
-        'regex_compiled': DG.tags.compile_issue_regex(),
-        'header': f'# Task Summary\n\nAuto-Generated by `{DG.meta.pkg_name}`',
-        'tag_order': DG.tags.tags,
+        'base_dir': get_dg().meta.path_project,
+        'regex_compiled': get_dg().tags.compile_issue_regex(),
+        'header': f'# Task Summary\n\nAuto-Generated by `calcipy`',
+        'tag_order': get_dg().tags.tags,
     }
     return debug_task([(write_code_tag_file, (), kwargs)])
diff --git a/calcipy/doit_tasks/doc.py b/calcipy/doit_tasks/doc.py
index e6902561..8a65ab92 100644
--- a/calcipy/doit_tasks/doc.py
+++ b/calcipy/doit_tasks/doc.py
@@ -14,7 +14,7 @@
 
 from ..file_helpers import _MKDOCS_CONFIG_NAME, _read_yaml_file, delete_dir, read_lines, trim_trailing_whitespace
 from .base import debug_task, echo, open_in_browser, write_text
-from .doit_globals import DG, DoitAction, DoitTask
+from .doit_globals import DoitAction, DoitTask, get_dg
 
 # ----------------------------------------------------------------------------------------------------------------------
 # Manage Changelog
@@ -28,10 +28,10 @@ def _move_cl() -> None:
         FileNotFoundError: if the changelog was not found
 
     """
-    path_cl = DG.meta.path_project / 'CHANGELOG.md'
+    path_cl = get_dg().meta.path_project / 'CHANGELOG.md'
     if not path_cl.is_file():
         raise FileNotFoundError(f'Could not locate the changelog at: {path_cl}')
-    path_cl.replace(DG.doc.doc_sub_dir / path_cl.name)
+    path_cl.replace(get_dg().doc.doc_sub_dir / path_cl.name)
 
 
 @beartype
@@ -244,7 +244,7 @@ def _handle_source_file(line: str, path_file: Path) -> List[str]:
 
     """
     key, path_rel = [*_parse_var_comment(line).items()][0]
-    path_base = DG.meta.path_project if path_rel.startswith('/') else path_file.resolve().parent
+    path_base = get_dg().meta.path_project if path_rel.startswith('/') else path_file.resolve().parent
     path_source = path_base / path_rel.lstrip('/')
     language = path_source.suffix.lstrip('.')
     lines_source = [f'```{language}', *read_lines(path_source), '```']
@@ -307,7 +307,7 @@ def _handle_coverage(line: str, _path_file: Path) -> List[str]:
         _ParseSkipError: if the "coverage.json" file is not available
 
     """
-    path_coverage = DG.meta.path_project / 'coverage.json'  # Created by "task_coverage"
+    path_coverage = get_dg().meta.path_project / 'coverage.json'  # Created by "task_coverage"
     if not path_coverage.is_file():
         raise _ParseSkipError(f'Could not locate: {path_coverage}')
     coverage_data = json.loads(path_coverage.read_text())
@@ -321,15 +321,15 @@ def write_autoformatted_md_sections() -> None:
     """Populate the auto-formatted sections of markdown files with user-configured logic.
 
     Raises:
-        RuntimeError: if `DG.doc.handler_lookup` hasn't ben configured. See `_ensure_handler_lookup`
+        RuntimeError: if `get_dg().doc.handler_lookup` hasn't ben configured. See `_ensure_handler_lookup`
 
     """
-    if DG.doc.handler_lookup is None:
-        raise RuntimeError('The "DG.doc.handler_lookup" dictionary has not been created')
+    if get_dg().doc.handler_lookup is None:
+        raise RuntimeError('The "get_dg().doc.handler_lookup" dictionary has not been created')
 
-    logger.info('> {paths_md}', paths_md=DG.doc.paths_md)
-    for path_md in DG.doc.paths_md:
-        md_lines = _ReplacementMachine().parse(read_lines(path_md), DG.doc.handler_lookup, path_md)
+    logger.info('> {paths_md}', paths_md=get_dg().doc.paths_md)
+    for path_md in get_dg().doc.paths_md:
+        md_lines = _ReplacementMachine().parse(read_lines(path_md), get_dg().doc.handler_lookup, path_md)
         path_md.write_text('\n'.join(md_lines))
 
 
@@ -368,10 +368,12 @@ def _diagram_tasks(pdoc_out_path: Path) -> List[DoitAction]:
 
 [Full Size](./classes.svg)
 """
-    path_diagram = pdoc_out_path / DG.meta.pkg_name / '_code_diagrams.md'
+    path_diagram = pdoc_out_path / get_dg().meta.pkg_name / '_code_diagrams.md'
     return [
         (write_text, (path_diagram, diagram_md)),
-        Interactive(f'poetry run pyreverse {DG.meta.pkg_name} --output svg --output-directory {path_diagram.parent}'),
+        Interactive(
+            f'poetry run pyreverse {get_dg().meta.pkg_name} --output svg --output-directory {path_diagram.parent}',
+        ),
     ]
 
 
@@ -382,8 +384,8 @@ def _diagram_tasks(pdoc_out_path: Path) -> List[DoitAction]:
 @beartype
 def _ensure_handler_lookup() -> None:
     """Configure the handler lookup if not already configured."""
-    if DG.doc.handler_lookup is None:
-        DG.doc.handler_lookup = {
+    if get_dg().doc.handler_lookup is None:
+        get_dg().doc.handler_lookup = {
             'COVERAGE ': _handle_coverage,
             'SOURCE_FILE=': _handle_source_file,
         }
@@ -405,16 +407,16 @@ def task_document() -> DoitTask:
 
     """
     _ensure_handler_lookup()
-    pdoc_out_path = DG.doc.auto_doc_path
+    pdoc_out_path = get_dg().doc.auto_doc_path
     pdoc_out = f'--output_dir {pdoc_out_path} --overwrite'
-    pdoc_template = f'--template_dir {DG.calcipy_dir}/doit_tasks/templates'
+    pdoc_template = f'--template_dir {get_dg().calcipy_dir}/doit_tasks/templates'
     return debug_task([
         (write_autoformatted_md_sections, ()),
         (delete_dir, (pdoc_out_path,)),
-        Interactive(f'poetry run pdocs as_markdown {DG.meta.pkg_name} {pdoc_out} {pdoc_template}'),
+        Interactive(f'poetry run pdocs as_markdown {get_dg().meta.pkg_name} {pdoc_out} {pdoc_template}'),
         *_diagram_tasks(pdoc_out_path),
         (_find_and_trim_trailing_whitespace, (pdoc_out_path,)),
-        Interactive(f'poetry run mkdocs build --site-dir {DG.doc.path_out}'),
+        Interactive(f'poetry run mkdocs build --site-dir {get_dg().doc.path_out}'),
     ])
 
 
@@ -429,7 +431,7 @@ def _is_mkdocs_local() -> bool:
         bool: True if configured for local file output rather than hosted
 
     """
-    mkdocs_config = _read_yaml_file(DG.meta.path_project / _MKDOCS_CONFIG_NAME)
+    mkdocs_config = _read_yaml_file(get_dg().meta.path_project / _MKDOCS_CONFIG_NAME)
     return mkdocs_config.get('use_directory_urls') is False
 
 
@@ -442,7 +444,7 @@ def task_open_docs() -> DoitTask:
 
     """
     if _is_mkdocs_local():  # pragma: no cover
-        path_doc_index = DG.doc.path_out / 'index.html'
+        path_doc_index = get_dg().doc.path_out / 'index.html'
         return debug_task([
             (open_in_browser, (path_doc_index,)),
         ])
diff --git a/calcipy/doit_tasks/doit_globals.py b/calcipy/doit_tasks/doit_globals.py
index f31694b3..08190eef 100644
--- a/calcipy/doit_tasks/doit_globals.py
+++ b/calcipy/doit_tasks/doit_globals.py
@@ -5,16 +5,18 @@
 import warnings
 from functools import partial
 from pathlib import Path
+from typing import ClassVar
+from uuid import uuid4
 
 import doit
 import tomli
-from attrs import field, mutable
-from attrs_strict import type_validator
 from beartype import beartype
 from beartype.typing import Any, Callable, Dict, Iterable, List, Optional, Pattern, Set, Tuple, Union
 from doit.action import BaseAction
 from doit.task import Task
 from loguru import logger
+from pydantic import BaseModel, Field
+from pydantic.dataclasses import dataclass
 
 from ..code_tag_collector import CODE_TAG_RE, COMMON_CODE_TAGS
 from ..file_helpers import _MKDOCS_CONFIG_NAME, _read_yaml_file, get_doc_dir
@@ -30,12 +32,13 @@
 DoitAction = Union[str, BaseAction, Tuple[Callable, _DoitCallableArgs]]  # type: ignore[type-arg]
 """Type: individual doit action."""
 
+# TODO: Better differentiate Task vs. Dict when typing and a dictionary is expected
 DoitTask = Union[Task, Dict[str, DoitAction]]
 """Type: full doit task."""
 
 
 @beartype
-def _make_full_path(raw: Union[Path, str], path_base: Path) -> Path:
+def _make_full_path(raw: Union[Path, str], *, path_base: Path) -> Path:
     """Return a full path by determining if the source path is an absolute path. If not combines with base path.
 
     Args:
@@ -64,23 +67,20 @@ def _member_filter(member: Any, instance_type: Any) -> bool:
     return instance_type is None or isinstance(member, instance_type)
 
 
-@mutable(kw_only=True)
+@dataclass(kw_only=True)
 class _PathAttrBase:
 
-    path_project: Path = field(validator=type_validator())
+    path_project: Path
     """Path to the package directory."""
 
-    def __attrs_post_init__(self) -> None:
+    def __post_init__(self) -> None:
         """Initialize full paths with the package base directory if necessary.
 
         Raises:
             RuntimeError: if any paths are None
 
         """
-        if self.path_project is None:
-            raise RuntimeError('Missing keyword argument "path_project"')  # pragma: no cover
         self._resolve_class_paths(self.path_project)
-        self._verify_initialized_paths()
 
     @beartype
     def _get_members(self, prefix: Optional[str], **kwargs: Any) -> List[Tuple[str, Any]]:
@@ -113,49 +113,37 @@ def _resolve_class_paths(self, base_path: Path) -> None:
 
         """
         for name, path_raw in self._get_members(instance_type=type(Path()), prefix=None):
-            if not path_raw.is_absolute():  # type: ignore[attr-defined]
+            if not path_raw.is_absolute():
                 setattr(self, name, base_path / path_raw)  # type: ignore[operator]
                 logger.debug(f'Mutated: self.{name}={path_raw} (now: {getattr(self, name)})')
 
-    @beartype
-    def _verify_initialized_paths(self) -> None:
-        """Verify that all paths are not None.
-
-        WARN: will not raise on error the class attribute
-
-        Raises:
-            RuntimeError: if any paths are None
-
-        """
-        missing = [name for name, _m in self._get_members(instance_type=type(None), prefix='path_')]
-        if missing:
-            kwargs = ', '.join(missing)
-            raise RuntimeError(f'Missing keyword arguments for: {kwargs}')
-
 
-@mutable(kw_only=True)
+@dataclass(kw_only=True)
 class PackageMeta(_PathAttrBase):
     """Package Meta-Information."""
 
-    path_toml: Path = field(validator=type_validator(), default=Path('pyproject.toml'))
-    """Relative path to the poetry toml file."""
-
-    ignore_patterns: List[str] = field(validator=type_validator(), factory=list)
+    ignore_patterns: List[str] = Field(default_factory=list)
     """List of glob patterns to ignore from all analysis."""
 
-    paths: List[Path] = field(validator=type_validator(), init=False)
+    paths: ClassVar[List[Path]]
     """Paths to all tracked files that were not ignored with specified patterns `find_project_files`."""
 
-    paths_by_suffix: Dict[str, List[Path]] = field(validator=type_validator(), init=False)
-    """Paths to all tracked files that were not ignored with specified patterns `find_project_files_by_suffix`."""
+    path_toml: ClassVar[Path]
+    """Path to the poetry toml file."""
 
-    pkg_name: str = field(validator=type_validator(), init=False)
+    pkg_name: ClassVar[str]
     """Package string name."""
 
-    pkg_version: str = field(validator=type_validator(), init=False)
+    pkg_version: ClassVar[str]
     """Package version."""
 
-    def __attrs_post_init__(self) -> None:
+    min_pyhon: ClassVar[Tuple[str]]
+    """Minimum Python version from pyproject.toml file."""
+
+    paths_by_suffix: ClassVar[Dict[str, List[Path]]]
+    """Paths to all tracked files that were not ignored with specified patterns `find_project_files_by_suffix`."""
+
+    def __post_init__(self) -> None:
         """Finish initializing class attributes.
 
         Raises:
@@ -163,18 +151,23 @@ def __attrs_post_init__(self) -> None:
             FileNotFoundError: if the toml could not be located
 
         """
-        super().__attrs_post_init__()
+        super().__post_init__()
 
         # Note: toml is an optional dependency required only when using the `doit_tasks` in development
         if tomli is None:  # pragma: no cover
             raise RuntimeError(_DOIT_TASK_IMPORT_ERROR)
 
+        self.path_toml = self.path_project / 'pyproject.toml'
         if not self.path_toml.is_file():
-            raise RuntimeError(f'Check "{self.path_project}". Could not find: "{self.path_toml}"')
+            raise RuntimeError(f'Check "path_project". Could not find: "{self.path_toml}"')
 
         poetry_config = tomli.loads(self.path_toml.read_text())['tool']['poetry']
         self.pkg_name = poetry_config['name']
         self.pkg_version = poetry_config['version']
+        py_constraint = poetry_config['dependencies']['python']
+        self.min_python = py_constraint.split(',')[0].lstrip('^>=').split('.')
+        if len(self.min_python) != 3 and self.min_python[0] != '3':
+            raise ValueError(f'Could not parse a valid minimum Python 3 version from {py_constraint}')
 
         if '-' in self.pkg_name:  # pragma: no cover
             warnings.warn(f'Replace dashes in name with underscores ({self.pkg_name}) in {self.path_toml}')
@@ -183,19 +176,19 @@ def __attrs_post_init__(self) -> None:
         self.paths_by_suffix = find_project_files_by_suffix(self.path_project, self.ignore_patterns)
 
     @beartype
-    def __shorted_path_list(self) -> Set[str]:  # pragma: no cover
+    def _shorten_path_lists(self) -> Set[Path]:
         """Shorten the list of directories common to the specified paths.
 
-        > Not currently needed, but could be useful
+        > FYI: Not currently needed, but could be useful
 
         Returns:
-            Set[str]: set of most common top-level directories relative to the project dir
+            Set[Path]: set of unique paths relative to project
 
         """
         return {
-            pth.parent.relative_to(self.path_project).as_posix()
+            pth.parent.relative_to(self.path_project)
             for pth in self.paths
-        }  # type: ignore[attr-defined]
+        }
 
 
 _DEF_IGNORE_LIST = [
@@ -216,72 +209,70 @@ def __shorted_path_list(self) -> Set[str]:  # pragma: no cover
 """Default list of excluded flake8 rules for the pre-commit check (additional to .flake8)."""
 
 
-@mutable(kw_only=True)
+@dataclass(kw_only=True)
 class LintConfig(_PathAttrBase):
     """Lint Config."""
 
-    path_flake8: Union[Path, str] = field(validator=type_validator(), default=Path('.flake8'))
+    paths_py: List[Path]
+    """Paths to the Python files used when linting. Created with `find_project_files_by_suffix`."""
+
+    path_flake8: Path = Field(default=Path('.flake8'))
     """Relative path to the flake8 configuration file. Default is ".flake8" created by calcipy_template."""
 
-    path_isort: Union[Path, str] = field(validator=type_validator(), default=Path('pyproject.toml'))
+    path_isort: Path = Field(default=Path('pyproject.toml'))
     """Relative path to the isort configuration file. Default is "pyproject.toml" created by calcipy_template."""
 
-    ignore_errors: List[str] = field(validator=type_validator(), factory=lambda: _DEF_IGNORE_LIST)
+    ignore_errors: List[str] = Field(default_factory=lambda: _DEF_IGNORE_LIST)
     """List of additional excluded flake8 rules for the pre-commit check."""
 
-    paths_py: List[Path] = field(validator=type_validator(), init=False)
-    """Paths to the Python files used when linting. Created with `find_project_files_by_suffix`."""
-
-    def __attrs_post_init__(self) -> None:
+    def __post_init__(self) -> None:
         """Finish initializing class attributes."""
-        super().__attrs_post_init__()
-        self.path_flake8 = _make_full_path(self.path_flake8, self.path_project)
-        self.path_isort = _make_full_path(self.path_isort, self.path_project)
-        self.paths_py = DG.meta.paths_by_suffix.get('py', [])
+        super().__post_init__()
+        self.path_flake8 = _make_full_path(self.path_flake8, path_base=self.path_project)
+        self.path_isort = _make_full_path(self.path_isort, path_base=self.path_project)
 
 
-@mutable(kw_only=True)
+@dataclass(kw_only=True)
 class TestingConfig(_PathAttrBase):  # pylint: disable=too-many-instance-attributes
     """Test Config."""
 
-    pythons: List[str] = field(validator=type_validator(), factory=lambda: ['3.8', '3.9'])
+    pythons: List[str] = Field(default_factory=lambda: ['3.8', '3.9'])
     """Python versions to test against. Default is `['3.8', '3.9']`."""
 
-    path_out: Union[Path, str] = field(validator=type_validator(), default=Path('releases/tests'))
+    path_out: Path = Field(default=Path('releases/tests'))
     """Relative path to the report output directory. Default is `releases/tests`."""
 
-    path_tests: Union[Path, str] = field(validator=type_validator(), default=Path('tests'))
+    path_tests: Path = Field(default=Path('tests'))
     """Relative path to the tests directory. Default is `tests`."""
 
-    args_pytest: str = field(
-        validator=type_validator(),
+    args_pytest: str = Field(
         default='--exitfirst --showlocals --failed-first --new-first --verbose --doctest-modules',
     )
     """Default arguments to Pytest. In short form, the defaults are `-x -l --ff --nf -vv`."""
 
-    args_diff: str = field(validator=type_validator(), default='--fail-under=65 --compare-branch=origin/main')
+    args_diff: str = Field(default='--fail-under=65 --compare-branch=origin/main')
     """Default arguments to diff-cover."""
 
-    path_test_report: Path = field(validator=type_validator(), init=False)
+    path_test_report: ClassVar[Path]
     """Path to the self-contained test HTML report."""
 
-    path_diff_test_report: Path = field(validator=type_validator(), init=False)
+    path_diff_test_report: ClassVar[Path]
     """Path to the self-contained diff-test HTML report."""
 
-    path_diff_lint_report: Path = field(validator=type_validator(), init=False)
+    path_diff_lint_report: ClassVar[Path]
     """Path to the self-contained diff-lint HTML report."""
 
-    path_coverage_index: Path = field(validator=type_validator(), init=False)
+    path_coverage_index: ClassVar[Path]
     """Path to the coverage HTML index file within the report directory."""
 
-    path_mypy_index: Path = field(validator=type_validator(), init=False)
+    path_mypy_index: ClassVar[Path]
     """Path to the mypy HTML index file within the report directory."""
 
-    def __attrs_post_init__(self) -> None:
+    def __post_init__(self) -> None:
         """Finish initializing class attributes."""
-        super().__attrs_post_init__()
-        self.path_out = _make_full_path(self.path_out, self.path_project)
-        self.path_tests = _make_full_path(self.path_tests, self.path_project)
+        super().__post_init__()
+        self.path_out = _make_full_path(self.path_out, path_base=self.path_project)
+        self.path_tests = _make_full_path(self.path_tests, path_base=self.path_project)
         self.path_out.mkdir(exist_ok=True, parents=True)
         # Configure the paths to the report HTML and coverage HTML files
         self.path_test_report = self.path_out / 'test_report.html'
@@ -291,28 +282,28 @@ def __attrs_post_init__(self) -> None:
         self.path_mypy_index = self.path_out / 'mypy_html/index.html'
 
 
-@mutable(kw_only=True)
+@dataclass(kw_only=True)
 class CodeTagConfig(_PathAttrBase):
     """Code Tag Config."""
 
-    doc_sub_dir: Path = field(validator=type_validator(), default=Path('docs/docs'))
+    doc_sub_dir: Path = Field(default=Path('docs/docs'))
     """Relative path to the source documentation directory."""
 
-    code_tag_summary_filename: str = field(validator=type_validator(), default='CODE_TAG_SUMMARY.md')
+    code_tag_summary_filename: str = Field(default='CODE_TAG_SUMMARY.md')
     """Name of the code tag summary file."""
 
-    tags: List[str] = field(validator=type_validator(), factory=lambda: COMMON_CODE_TAGS)
+    tags: List[str] = Field(default_factory=lambda: COMMON_CODE_TAGS)
     """List of ordered tag names to match."""
 
-    re_raw: str = field(validator=type_validator(), default=CODE_TAG_RE)
+    re_raw: str = Field(default=CODE_TAG_RE)
     """string regular expression that contains `{tag}`."""
 
-    path_code_tag_summary: Path = field(validator=type_validator(), init=False)
+    path_code_tag_summary: ClassVar[Path]
     """Path to the code tag summary file. Uses `code_tag_summary_filename`."""
 
-    def __attrs_post_init__(self) -> None:
+    def __post_init__(self) -> None:
         """Finish initializing class attributes."""
-        super().__attrs_post_init__()
+        super().__post_init__()
         # Configure full path to the code tag summary file
         self.path_code_tag_summary = self.path_project / self.doc_sub_dir / self.code_tag_summary_filename
 
@@ -327,140 +318,173 @@ def compile_issue_regex(self) -> Pattern[str]:
         return re.compile(self.re_raw.format(tag='|'.join(self.tags)))
 
 
-@mutable(kw_only=True)
+@dataclass(kw_only=True)
 class DocConfig(_PathAttrBase):
     """Documentation Config."""
 
-    doc_sub_dir: Path = field(validator=type_validator(), default=Path('docs/docs'))
+    paths_md: List[Path]
+    """Paths to Markdown files used when documenting. Created with `find_project_files_by_suffix`."""
+
+    doc_sub_dir: Path = Field(default=Path('docs/docs'))
     """Relative path to the source documentation directory."""
 
-    auto_doc_path: Optional[Path] = field(validator=type_validator(), default=None)
+    auto_doc_path: ClassVar[Path]
     """Auto-calculated based on `self.doc_sub_dir`."""
 
     handler_lookup: Optional[
         Dict[str, Callable[[str, Path], List[str]]]
-    ] = field(validator=type_validator(), default=None)
+    ] = Field(default=None)
     """Lookup dictionary for autoformatted sections of the project's markdown files."""
 
-    path_out: Path = field(validator=type_validator(), init=False)
+    path_out: ClassVar[Path]
     """The documentation output directory. Specified in `mkdocs.yml`."""
 
-    paths_md: List[Path] = field(validator=type_validator(), init=False)
-    """Paths to Markdown files used when documenting. Created with `find_project_files_by_suffix`."""
-
-    def __attrs_post_init__(self) -> None:
+    def __post_init__(self) -> None:
         """Finish initializing class attributes."""
-        super().__attrs_post_init__()
+        super().__post_init__()
         mkdocs_config = _read_yaml_file(self.path_project / _MKDOCS_CONFIG_NAME)
         self.path_out = Path(mkdocs_config.get('site_dir', 'releases/site'))
-        self.path_out = _make_full_path(self.path_out, self.path_project)
+        self.path_out = _make_full_path(self.path_out, path_base=self.path_project)
         self.path_out.mkdir(exist_ok=True, parents=True)
-        self.paths_md = DG.meta.paths_by_suffix.get('md', [])
         self.auto_doc_path = self.doc_sub_dir.parent / 'modules'
 
 
-@mutable(kw_only=True)
-class DoitGlobals:  # pylint: disable=too-many-instance-attributes
+class DoitGlobals(BaseModel):
     """Global Variables for doit."""
 
-    calcipy_dir: Path = field(validator=type_validator(), init=False, default=Path(__file__).resolve().parents[1])
-    """The calcipy directory (likely within `.venv`)."""
-
-    meta: PackageMeta = field(validator=type_validator(), init=False)
+    meta: PackageMeta
     """Package Meta-Information."""
 
-    lint: LintConfig = field(validator=type_validator(), init=False)
+    lint: LintConfig
     """Lint Config."""
 
-    test: TestingConfig = field(validator=type_validator(), init=False)
+    test: TestingConfig
     """Test Config."""
 
-    tags: CodeTagConfig = field(validator=type_validator(), init=False)
+    tags: CodeTagConfig
     """Documentation Config."""
 
-    doc: DocConfig = field(validator=type_validator(), init=False)
+    doc: DocConfig
     """Documentation Config."""
 
-    _is_set: bool = field(validator=type_validator(), default=False)
-    """Internal flag to check if already set."""
+    calcipy_dir: Path = Field(default=Path(__file__).resolve().parents[1])
+    """The calcipy directory (likely within `.venv`)."""
 
-    @log_fun
-    def set_paths(
-        self, *, path_project: Optional[Path] = None,
-    ) -> None:
-        """Configure `DoitGlobals` based on project directory.
 
-        Args:
-            path_project: optional project base directory Path. Defaults to the current working directory
+@beartype
+def _set_meta(path_project: Path, calcipy_config: Dict[str, Any]) -> PackageMeta:
+    """Initialize the meta submodules.
 
-        Raises:
-            RuntimeError: if `set_paths` is called twice. This can cause unexpected behavior, so if
-                absolutely necessary, set `DG._is_set = False`, then try `DG.set_paths()`
+    Args:
+        path_project: project base directory Path
+        calcipy_config: custom calcipy configuration from toml file
 
-        """
-        if self._is_set:
-            raise RuntimeError('DoitGlobals has already been configured and cannot be reconfigured')
+    """
+    ignore_patterns = calcipy_config.get('ignore_patterns', [])
+    return PackageMeta(path_project=path_project, ignore_patterns=ignore_patterns)
 
-        logger.info(f'Setting DG path: {path_project}', path_project=path_project, cwd=Path.cwd())
-        path_project = path_project or Path.cwd()
 
-        # Read the optional toml configuration
-        # > Note: could allow LintConfig/.../DocConfig kwargs to be set in toml, but may be difficult to maintain
-        data = (path_project / 'pyproject.toml').read_text()
-        calcipy_config = tomli.loads(data).get('tool', {}).get('calcipy', {})
+@beartype
+def _set_submodules(
+    meta: PackageMeta, calcipy_config: Dict[str, Any],
+) -> Dict[str, Union[LintConfig, TestingConfig, CodeTagConfig, DocConfig]]:
+    """Initialize the rest of the submodules.
+
+    Args:
+        calcipy_config: custom calcipy configuration from toml file
 
-        self._set_meta(path_project, calcipy_config)
-        self._set_submodules(calcipy_config)
+    Raises:
+        RuntimeError: if problems in formatting of the toml file
 
-        self._is_set = True
+    """
+    # Configure global options
+    section_keys = ['lint', 'test', 'code_tag', 'doc']
+    supported_keys = section_keys + ['ignore_patterns']
+    unexpected_keys = [key for key in calcipy_config if key not in supported_keys]
+    if unexpected_keys:
+        raise RuntimeError(f'Found unexpected key(s) {unexpected_keys} (i.e. not in {supported_keys})')
+
+    # Parse the Copier file for configuration information
+    doc_sub_dir = get_doc_dir(meta.path_project) / 'docs'  # Note: subdirectory is important
+    doc_sub_dir.mkdir(exist_ok=True, parents=True)
+
+    # Configure submodules
+    meta_kwargs = {'path_project': meta.path_project}
+    lint_k, test_k, code_k, doc_k = (calcipy_config.get(key, {}) for key in section_keys)
+    paths_py = meta.paths_by_suffix.get('py', [])
+    paths_md = meta.paths_by_suffix.get('md', [])
+    return {
+        'lint': LintConfig(**meta_kwargs, paths_py=paths_py, **lint_k),
+        'test': TestingConfig(**meta_kwargs, **test_k),
+        'tags': CodeTagConfig(**meta_kwargs, doc_sub_dir=doc_sub_dir, **code_k),
+        'doc': DocConfig(**meta_kwargs, paths_md=paths_md, doc_sub_dir=doc_sub_dir, **doc_k),
+    }
+
+
+@log_fun
+def create_dg(*, path_project: Path) -> DoitGlobals:
+    """Configure `DoitGlobals` based on project directory.
+
+    Args:
+        path_project: optional project base directory Path. Defaults to the current working directory
+
+    """
+    logger.info('Setting DG path: {path_project}', path_project=path_project)
+
+    # Read the optional toml configuration
+    # > Note: could allow LintConfig/.../DocConfig kwargs to be set in toml, but may be difficult to maintain
+    data = (path_project / 'pyproject.toml').read_text()
+    calcipy_config = tomli.loads(data).get('tool', {}).get('calcipy', {})
+
+    meta = _set_meta(path_project, calcipy_config)
+    kwargs = _set_submodules(meta, calcipy_config)
+    return DoitGlobals(meta=meta, **kwargs)
+
+
+class _DGContainer(BaseModel):
+    """Manage state of DoitGlobals. Only used for unit testing."""
+
+    key: str = Field(default='')
+    data: Dict[str, DoitGlobals] = Field(default_factory=dict)
 
     @beartype
-    def _set_meta(self, path_project: Path, calcipy_config: Dict[str, Any]) -> None:
-        """Initialize the meta submodules.
+    def set_dg(self, dg: DoitGlobals) -> None:
+        """Registers a DG instance.
 
         Args:
-            path_project: project base directory Path
-            calcipy_config: custom calcipy configuration from toml file
+            dg: Global doit 'Globals' class for management of global variables
 
         """
-        ignore_patterns = calcipy_config.get('ignore_patterns', [])
-        self.meta = PackageMeta(path_project=path_project, ignore_patterns=ignore_patterns)
+        self.key = str(uuid4())
+        self.data[self.key] = dg
 
     @beartype
-    def _set_submodules(self, calcipy_config: Dict[str, Any]) -> None:
-        """Initialize the rest of the submodules.
+    def get_dg(self) -> DoitGlobals:
+        """Retrieves the registered DG instance.
 
         Args:
-            calcipy_config: custom calcipy configuration from toml file
-
-        Raises:
-            RuntimeError: if problems in formatting of the toml file
+            dg: Global doit 'Globals' class for management of global variables
 
         """
-        # Configure global options
-        section_keys = ['lint', 'test', 'code_tag', 'doc']
-        supported_keys = section_keys + ['ignore_patterns']
-        unexpected_keys = [key for key in calcipy_config if key not in supported_keys]
-        if unexpected_keys:
-            raise RuntimeError(f'Found unexpected key(s) {unexpected_keys} (i.e. not in {supported_keys})')
+        return self.data[self.key]
 
-        # Parse the Copier file for configuration information
-        doc_sub_dir = get_doc_dir(self.meta.path_project) / 'docs'  # Note: subdirectory is important
-        doc_sub_dir.mkdir(exist_ok=True, parents=True)
 
-        # Configure submodules
-        meta_kwargs = {'path_project': self.meta.path_project}
-        lint_k, test_k, code_k, doc_k = (calcipy_config.get(key, {}) for key in section_keys)
-        self.lint = LintConfig(**meta_kwargs, **lint_k)  # type: ignore[arg-type]
-        self.test = TestingConfig(**meta_kwargs, **test_k)  # type: ignore[arg-type]
-        self.tags = CodeTagConfig(**meta_kwargs, doc_sub_dir=doc_sub_dir, **code_k)  # type: ignore[arg-type]
-        self.doc = DocConfig(**meta_kwargs, doc_sub_dir=doc_sub_dir, **doc_k)  # type: ignore[arg-type]
+_DG_CONTAINER = _DGContainer()
+"""Single instance."""
 
+set_dg = _DG_CONTAINER.set_dg
+get_dg = _DG_CONTAINER.get_dg
+"""Alias for exported function."""
 
-DG = DoitGlobals()
-"""Global doit Globals class used to manage global variables."""
 
-_WORK_DIR = doit.get_initial_workdir()
-"""Work directory identified by doit."""
+@beartype
+def init_dg():
+    """Initialize the global DG instance."""
+    work_dir = doit.get_initial_workdir()
+    path_project = (Path(work_dir) if work_dir else Path.cwd()).resolve()
+    dg = create_dg(path_project=path_project)
+    set_dg(dg)
+
 
-DG.set_paths(path_project=(Path(_WORK_DIR) if _WORK_DIR else Path.cwd()).resolve())
+# Eagerly initialize at least one global DG instance
+init_dg()
diff --git a/calcipy/doit_tasks/lint.py b/calcipy/doit_tasks/lint.py
index 9319d3f0..922e128c 100755
--- a/calcipy/doit_tasks/lint.py
+++ b/calcipy/doit_tasks/lint.py
@@ -9,7 +9,7 @@
 
 from ..file_helpers import if_found_unlink
 from .base import debug_task, echo
-from .doit_globals import DG, DoitAction, DoitTask
+from .doit_globals import DoitAction, DoitTask, get_dg
 
 # ----------------------------------------------------------------------------------------------------------------------
 # Linting
@@ -77,17 +77,17 @@ def _lint_python(
     """
     # Flake8 appends to the log file. Ensure that an existing file is deleted so that Flake8 creates a fresh file
     run_m = 'poetry run python -m'
-    flake8_log_path = DG.meta.path_project / 'flake8.log'
+    flake8_log_path = get_dg().meta.path_project / 'flake8.log'
     flake8_flags = f'--config={path_flake8}  --output-file={flake8_log_path} --exit-zero'
     diff_params = f'--compare-branch={diff_branch} --fail-under={diff_fail_under}'
-    diff_report = f'--html-report {DG.test.path_diff_lint_report}'
+    diff_report = f'--html-report {get_dg().test.path_diff_lint_report}'
     return [
         (if_found_unlink, (flake8_log_path,)),
         Interactive(f'{run_m} flake8 {flake8_flags} ' + ' '.join(f'"{pth}"' for pth in lint_paths)),
         (_check_linting_errors, (flake8_log_path, ignore_errors)),
         # FIXME" Need to check if the branch is available first! Will fail on GHA
         Interactive(f'echo "poetry run diff-quality --violations=flake8 {diff_params} {diff_report}"'),
-        Interactive(f'{run_m} xenon {DG.meta.pkg_name} {xenon_args}'),
+        Interactive(f'{run_m} xenon {get_dg().meta.pkg_name} {xenon_args}'),
     ]
 
 
@@ -100,7 +100,7 @@ def _lint_non_python() -> List[DoitAction]:
 
     """
     actions = []
-    pbs = DG.meta.paths_by_suffix
+    pbs = get_dg().meta.paths_by_suffix
     paths_yaml = pbs.get('yml', []) + pbs.get('yaml', [])
     if paths_yaml:
         yamllint_args = '-d "{rules: {line-length: {max: 120}}}"'
@@ -111,7 +111,7 @@ def _lint_non_python() -> List[DoitAction]:
     # From: https://github.com/pre-commit/pre-commit-hooks/blob/0d261aaf84419c0c8fe70ff4a23f6a99655868de/
     #   lint: ./pre_commit_hooks/check_json.py
     #   format: ./pre_commit_hooks/pretty_format_json.py
-    # > if paths_json := DG.meta.paths_by_suffix.get('json', []):
+    # > if paths_json := get_dg().meta.paths_by_suffix.get('json', []):
     # >     actions.extend(Interactive(f'poetry run jsonlint "{pth}"') for pth in paths_json)
 
     return actions
@@ -125,7 +125,7 @@ def task_lint_python() -> DoitTask:
         DoitTask: doit task
 
     """
-    actions = _lint_python(DG.lint.paths_py, path_flake8=DG.lint.path_flake8)
+    actions = _lint_python(get_dg().lint.paths_py, path_flake8=get_dg().lint.path_flake8)
     return debug_task(actions)
 
 
@@ -137,7 +137,8 @@ def task_lint_project() -> DoitTask:
         DoitTask: doit task
 
     """
-    actions = _lint_python(DG.lint.paths_py, path_flake8=DG.lint.path_flake8)
+    dg = get_dg()
+    actions = _lint_python(dg.lint.paths_py, path_flake8=dg.lint.path_flake8)
     actions.extend(_lint_non_python())
     return debug_task(actions)
 
@@ -150,8 +151,9 @@ def task_lint_critical_only() -> DoitTask:
         DoitTask: doit task
 
     """
+    dg = get_dg()
     actions = _lint_python(
-        DG.lint.paths_py, path_flake8=DG.lint.path_flake8, ignore_errors=DG.lint.ignore_errors,
+        dg.lint.paths_py, path_flake8=dg.lint.path_flake8, ignore_errors=dg.lint.ignore_errors,
         xenon_args='--max-absolute C --max-modules A --max-average A',
     )
     actions.extend(_lint_non_python())
@@ -173,7 +175,7 @@ def task_radon_lint() -> DoitTask:
 
     """
     actions: List[DoitAction] = []
-    paths = ' '.join(map(Path.as_posix, DG.lint.paths_py))
+    paths = ' '.join(map(Path.as_posix, get_dg().lint.paths_py))
     for args in ['mi --show --min B', 'cc --total-average --min B', 'hal', 'raw --summary']:
         actions.extend([
             (echo, (f'# Radon with args: {args}',)),
@@ -191,7 +193,7 @@ def task_static_checks() -> DoitTask:
         DoitTask: doit task
 
     """
-    paths = ' '.join(map(Path.as_posix, DG.lint.paths_py))
+    paths = ' '.join(map(Path.as_posix, get_dg().lint.paths_py))
     return debug_task([
         Interactive(f'poetry run vulture {paths} --min-confidence 70 --sort-by-size'),
     ])
@@ -206,8 +208,8 @@ def task_security_checks() -> DoitTask:
 
     """
     return debug_task([
-        Interactive(f'poetry run bandit --recursive {DG.meta.pkg_name}'),
-        Interactive('poetry run nox --session check_safety'),
+        Interactive(f'poetry run bandit --recursive {get_dg().meta.pkg_name}'),
+        Interactive('poetry run nox --session check_security'),
     ])
 
 
@@ -234,13 +236,18 @@ def _gen_format_actions(paths: str) -> List[str]:
         '--in-place --remove-all-unused-imports --remove-unused-variables --ignore-init-module-imports'
         ' --remove-duplicate-keys'
     )
+    # pyupgrade only supports py36 to py311 at this time
+    pyup_ver = ''.join(get_dg().meta.min_python[:2])
+    pyup_flag = ''
+    if pyup_ver in [f'3{ix}' for ix in range(6, 12)]:
+        pyup_flag = f'--py{pyup_ver}-plus'
     return [
-        f'{run} pyupgrade {paths} --py38-plus --keep-runtime-typing',
+        f'{run} pyupgrade {paths} {pyup_flag} --keep-runtime-typing',
         f'{run_mod} autoflake {paths} {autoflake_args}',
         f'{run_mod} autopep8 {paths} --in-place --aggressive',
         f'{run} pycln --quiet {paths}',
         f'{run} absolufy-imports {paths} --never',
-        f'{run_mod} isort {paths} --settings-path "{DG.lint.path_isort}"',
+        f'{run_mod} isort {paths} --settings-path "{get_dg().lint.path_isort}"',
         f'{run} add-trailing-comma {paths} --py36-plus --exit-zero-even-if-changed',
     ]
 
@@ -308,15 +315,15 @@ def task_auto_format() -> DoitTask:
     @beartype
     def get_short_path(_pth: Path) -> Path:
         try:
-            return _pth.relative_to(DG.meta.path_project)
+            return _pth.relative_to(get_dg().meta.path_project)
         except Exception as exc:
             logger.warning(
                 '{pth} is not relative to {rel_path}. Error: {exc}',
-                pth=_pth, rel_path=DG.meta.path_project, exc=exc,
+                pth=_pth, rel_path=get_dg().meta.path_project, exc=exc,
             )
             return _pth
 
-    paths = ' '.join(f'"{get_short_path(pth)}"' for pth in DG.lint.paths_py)
+    paths = ' '.join(f'"{get_short_path(pth)}"' for pth in get_dg().lint.paths_py)
     return debug_task(_gen_format_actions(paths))
 
 
diff --git a/calcipy/doit_tasks/packaging.py b/calcipy/doit_tasks/packaging.py
index b058fcd6..9e4bd0be 100755
--- a/calcipy/doit_tasks/packaging.py
+++ b/calcipy/doit_tasks/packaging.py
@@ -3,23 +3,21 @@
 import json
 from pathlib import Path
 
-import attrs
+import arrow
 import numpy as np
-import pendulum
 import requests
 import tomli
-from attrs import field, mutable
-from attrs_strict import type_validator
+from arrow import Arrow
 from beartype import beartype
-from beartype.typing import Dict, List, Optional
+from beartype.typing import Dict, List, Optional, Union
 from bidict import bidict
 from doit.tools import Interactive
 from loguru import logger
-from pendulum import DateTime
+from pydantic import BaseModel, Field
 from pyrate_limiter import Duration, Limiter, RequestRate
 
 from .base import debug_task
-from .doit_globals import DG, DoitTask
+from .doit_globals import DoitTask, get_dg
 
 # ----------------------------------------------------------------------------------------------------------------------
 # Publish releases
@@ -49,8 +47,8 @@ def task_lock() -> DoitTask:
 
     """
     task = debug_task(['poetry lock --no-update'])
-    task['file_dep'].append(DG.meta.path_toml)
-    task['targets'].extend([DG.meta.path_project / 'poetry.lock'])
+    task['file_dep'].append(get_dg().meta.path_toml)
+    task['targets'].extend([get_dg().meta.path_project / 'poetry.lock'])
     return task
 
 
@@ -65,7 +63,6 @@ def _publish_task(publish_args: str = '') -> DoitTask:
         DoitTask: doit task
 
     """
-    # FIXME: Pyroma doesn't have the poetry requirement it needs...
     return debug_task([
         Interactive('poetry run nox --session build_dist build_check'),
         f'poetry publish {publish_args}',
@@ -101,47 +98,48 @@ def task_publish_test_pypi() -> DoitTask:
 # Check for stale packages
 
 
-def _auto_convert(_cls, fields):  # type: ignore # noqa: ANN001, ANN202, CCR001
-    """Auto convert datetime attributes from string.
+class ArrowType(Arrow):
+    """Create a type for pydantic use of Arrow."""
 
-    Based on: https://www.attrs.org/en/stable/extending.html#automatic-field-transformation-and-modification
+    @classmethod
+    def __get_validators__(cls):
+        yield cls.validate
 
-    Args:
-        _cls: unused class argument
-        fields: `_HostedPythonPackageAttribtues`
-
-    Returns:
-        results
-
-    """
-    results = []
-    for fld in fields:
-        if fld.converter is not None:  # pragma: no cover
-            results.append(fld)
-            continue
+    @classmethod
+    def validate(cls, value):
+        @beartype
+        def arrow_converter(date: Optional[Union[str, Arrow]]) -> Optional[Arrow]:
+            return arrow.get(date) if date else date
 
-        converter: Optional[DateTime] = None
-        if fld.type in {Optional[DateTime], DateTime, 'datetime'}:
-            converter = (lambda d: pendulum.parse(d) if isinstance(d, str) else d)
-        results.append(fld.evolve(converter=converter))
+        return arrow_converter(value)
 
-    return results
 
-
-@mutable(kw_only=True, field_transformer=_auto_convert)
-class _HostedPythonPackage():
+class _HostedPythonPackage(BaseModel):
     """Representative information for a python package hosted on some domain."""
 
     # Note: "releases" was removed from the versioned URL: https://warehouse.pypa.io/api-reference/json.html#release
-    domain: str = field(validator=type_validator(), default='https://pypi.org/pypi/{name}/json')
-    name: str = field(validator=type_validator())
-    version: str = field(validator=type_validator())
-    datetime: Optional[DateTime] = field(validator=type_validator(), default=None)
-    latest_version: str = field(validator=type_validator(), default='')
-    latest_datetime: Optional[DateTime] = field(validator=type_validator(), default=None)
+    domain: str = Field(default='https://pypi.org/pypi/{name}/json')
+    name: str
+    version: str
+    datetime: Optional[ArrowType] = Field(default=None)
+    latest_version: str = Field(default='')
+    latest_datetime: Optional[ArrowType] = Field(default=None)
+
+    # HACK: See pending pydantic changes: https://github.com/pydantic/pydantic/discussions/4456
+    def _iter(self, *args, **kwargs):
+        """Hack to serialize Arrow types.
+
+        Based on: https://github.com/pydantic/pydantic/issues/2277#issuecomment-764132528
+
+        """
+        for key, v in super()._iter(*args, **kwargs):
+            if 'datetime' in key:
+                yield key, str(v)
+            else:
+                yield key, v
 
 
-_PATH_PACK_LOCK = DG.meta.path_project / '.calcipy_packaging.lock'
+_PATH_PACK_LOCK = get_dg().meta.path_project / '.calcipy_packaging.lock'
 """Path to the packaging lock file."""
 
 # HACK: Check that this works then refactor (shouldn't be global)
@@ -175,7 +173,7 @@ def _get_release_date(package: _HostedPythonPackage) -> _HostedPythonPackage:
 
     # Also retrieve the latest release date of the package looking through all releases
     release_dates = bidict({
-        pendulum.parse(release_data[0]['upload_time_iso_8601']): version
+        arrow.get(release_data[0]['upload_time_iso_8601']): version
         for version, release_data in releases.items()
         if release_data
     })
@@ -249,10 +247,7 @@ def _write_cache(updated_packages: List[_HostedPythonPackage], path_pack_lock: P
         path_pack_lock: Path to the lock file. Default is `_PATH_PACK_LOCK`
 
     """
-    def serialize(_inst, _field, value):  # noqa: ANN001, ANN201
-        return value.to_iso8601_string() if isinstance(value, DateTime) else value
-
-    new_cache = {pack.name: attrs.asdict(pack, value_serializer=serialize) for pack in updated_packages}
+    new_cache = {pack.name: json.loads(pack.json()) for pack in updated_packages}
     pretty_json = json.dumps(new_cache, indent=4, separators=(',', ': '), sort_keys=True)
     path_pack_lock.write_text(pretty_json + '\n')
 
@@ -294,32 +289,35 @@ def _check_for_stale_packages(packages: List[_HostedPythonPackage], *, stale_mon
 
     """
     def format_package(pack: _HostedPythonPackage) -> str:
-        delta = f'{now.diff(pack.datetime).in_months()} months ago:'
+        delta = pack.datetime.humanize()
         latest = '' if pack.version == pack.latest_version else f' (*New version available: {pack.latest_version}*)'
-        return f'- {delta} {pack.name} {pack.version}{latest}'
+        return f'- {delta}: {pack.name} {pack.version}{latest}'
 
-    now = pendulum.now()
-    stale_cutoff = now.subtract(months=stale_months)
+    now = arrow.now()
+    stale_cutoff = now.shift(months=-1 * stale_months)
     stale_packages = [pack for pack in packages if pack.datetime < stale_cutoff]
     if stale_packages:
         stale_list = '\n'.join(map(format_package, sorted(stale_packages, key=lambda x: x.datetime)))
         logger.warning(f'Found stale packages that may be a dependency risk:\n\n{stale_list}\n\n')
     else:
-        max_months = np.amax([now.diff(pack.datetime).in_months() for pack in packages])
-        logger.warning(f'The oldest package was released {max_months} months ago (stale is >{stale_months} months)\n')
+        oldest_date = np.amin([pack.datetime for pack in packages])
+        logger.warning(f'The oldest package was released {oldest_date.humanize()} (stale is >{stale_months} months)\n')
+
+
+_DEF_STALE_M = 48
 
 
 @beartype
 def find_stale_packages(
     path_lock: Path, path_pack_lock: Path = _PATH_PACK_LOCK,
-    *, stale_months: int = 48,
+    *, stale_months: int = _DEF_STALE_M,
 ) -> None:
     """Read the cached packaging information.
 
     Args:
         path_lock: Path to the lock file to parse
         path_pack_lock: Path to the lock file. Default is `_PATH_PACK_LOCK`
-        stale_months: cutoff in months for when a package might be stale enough to be a risk. Default is 48
+        stale_months: cutoff in months for when a package might be stale enough to be a risk. Default is _DEF_STALE_M
 
     """
     packages = _read_packages(path_lock)
@@ -337,10 +335,10 @@ def task_check_for_stale_packages() -> DoitTask:
         DoitTask: doit task
 
     """
-    path_lock = DG.meta.path_project / 'poetry.lock'
+    path_lock = get_dg().meta.path_project / 'poetry.lock'
     path_pack_lock = _PATH_PACK_LOCK
     task = debug_task([
-        (find_stale_packages, (path_lock, path_pack_lock), {'stale_months': 48}),
+        (find_stale_packages, (path_lock, path_pack_lock), {'stale_months': _DEF_STALE_M}),
         Interactive('poetry run pip-check --cmd="poetry run pip" --hide-unchanged'),
     ])
     task['file_dep'].append(path_lock)
diff --git a/calcipy/doit_tasks/summary_reporter.py b/calcipy/doit_tasks/summary_reporter.py
index b7927ae7..d2aee663 100644
--- a/calcipy/doit_tasks/summary_reporter.py
+++ b/calcipy/doit_tasks/summary_reporter.py
@@ -7,12 +7,11 @@
 
 from enum import IntEnum
 
-from attrs import field, mutable
-from attrs_strict import type_validator
 from beartype import beartype
 from beartype.typing import Any, List, OrderedDict
 from doit.reporter import ConsoleReporter
 from doit.task import Task
+from pydantic import BaseModel
 from sty import fg
 
 
@@ -26,12 +25,11 @@ class _TaskExitCode(IntEnum):
     SKIP_UP_TO_DATE = 4
 
 
-@mutable(kw_only=True)
-class _TaskSummary:
+class _TaskSummary(BaseModel):
     """Task Summary."""
 
-    name: str = field(validator=type_validator())
-    exit_code: _TaskExitCode = field(validator=type_validator())
+    name: str
+    exit_code: _TaskExitCode
 
 
 @beartype
diff --git a/calcipy/file_search.py b/calcipy/file_search.py
index 159c69ea..e5dfddf1 100644
--- a/calcipy/file_search.py
+++ b/calcipy/file_search.py
@@ -53,7 +53,7 @@ def find_project_files(path_project: Path, ignore_patterns: List[str]) -> List[P
     > Note: uses the relative project directory and verifies that each file exists
 
     Args:
-        path_project: Path to the project directory. Typically `DG.meta.path_project`
+        path_project: Path to the project directory. Typically `get_dg().meta.path_project`
         ignore_patterns: glob ignore patterns
 
     Returns:
@@ -79,7 +79,7 @@ def find_project_files_by_suffix(path_project: Path, ignore_patterns: List[str])
     > Note: uses the relative project directory and verifies that each file exists
 
     Args:
-        path_project: Path to the project directory. Typically `DG.meta.path_project`
+        path_project: Path to the project directory. Typically `get_dg().meta.path_project`
         ignore_patterns: glob ignore patterns
 
     Returns:
diff --git a/docs/Calcipy.sketch b/docs/Calcipy.sketch
new file mode 100644
index 00000000..c5e2dec8
Binary files /dev/null and b/docs/Calcipy.sketch differ
diff --git a/docs/adr/README.md b/docs/adr/README.md
index 0de17e54..a1b83cee 100644
--- a/docs/adr/README.md
+++ b/docs/adr/README.md
@@ -1,6 +1,6 @@
 # ADR Documentation
 
-*ADR*: Architectural Design Records
+*ADR*: Architectural Design Record
 
 ## ADRs
 
diff --git a/docs/docs/CHANGELOG.md b/docs/docs/CHANGELOG.md
index cf1be979..c2e302c3 100644
--- a/docs/docs/CHANGELOG.md
+++ b/docs/docs/CHANGELOG.md
@@ -2,6 +2,26 @@
 
 ### Feat
 
+- replace pendulum with arrow
+- update to latest copier
+
+### Fix
+
+- hack together a dictionary instead of punq
+- drop safety because of false positives on Calcipy CalVer
+
+### Refactor
+
+- try to fix punq by switching to functions
+- fix one test, refactor a little, but punq is still not working
+- begin replacing attrs with pydantic
+- update semgrep nox task
+- upgrade copier with linting fixes
+
+## 0.16.0 (2022-08-04)
+
+### Feat
+
 - add flake8-simplify
 
 ### Fix
diff --git a/docs/docs/CODE_TAG_SUMMARY.md b/docs/docs/CODE_TAG_SUMMARY.md
index acde56ca..b1985af1 100644
--- a/docs/docs/CODE_TAG_SUMMARY.md
+++ b/docs/docs/CODE_TAG_SUMMARY.md
@@ -8,22 +8,23 @@ Auto-Generated by `calcipy`
 | PLANNED | newest version fails on positional argument errors: https://github.com/tox-dev/pyproject-fmt                | 2022-05-30  | [.pre-commit-config.yaml:65](https://github.com/KyleKing/calcipy/blame/dfb2845414e2823fe10a03b24675a7c6a5293fe7/.pre-commit-config.yaml#L65)                                   |
 | PLANNED | Take a look at a few useful issues for cement:                                                              | 2021-12-31  | [calcipy/cli/__init__.py:3](https://github.com/KyleKing/calcipy/blame/91236083605413540509f142ff80dd7aae3fd513/calcipy/cli/__init__.py#L3)                                     |
 | PLANNED | Consider additional commands to add, such as `check-for-stale-packages` or to wrap copier                   | 2022-01-17  | [calcipy/cli/main.py:29](https://github.com/KyleKing/calcipy/blame/ed231ee5dae2d65a4b6696ef795d8984e7698c47/calcipy/cli/main.py#L29)                                           |
-| PLANNED | Consider making "blame" configurable                                                                        | 2022-01-17  | [calcipy/code_tag_collector.py:182](https://github.com/KyleKing/calcipy/blame/ccc2e30c4c859c416ca87585cc56324228632016/calcipy/code_tag_collector.py#L180)                     |
-| TODO    | Make this auto-resolve based on pyproject.toml                                                              | 2021-10-30  | [calcipy/dev/noxfile.py:71](https://github.com/KyleKing/calcipy/blame/004df806a85aa9d1a6d0bbb5ab5b1f98ac263a3f/calcipy/dev/noxfile.py#L66)                                     |
-| TODO    | Implement semgrep - what are a good ruleset to start with? Currently only a nox-session (no doit task)      | 2021-06-08  | [calcipy/dev/noxfile.py:245](https://github.com/KyleKing/calcipy/blame/2822d0915aa092e099ccf31bc480c47dc2fb42a6/calcipy/dev/noxfile.py#L205)                                   |
-| TODO    | https://github.com/tonybaloney/wily/blob/e72b7d95228bbe5538a072dc5d1186daa318bb03/src/wily/__main__.py#L261 | 2021-12-09  | [calcipy/dev/noxfile.py:274](https://github.com/KyleKing/calcipy/blame/16463ec8d6dcd828106df039a41ac82dc5726790/calcipy/dev/noxfile.py#L270)                                   |
-| TODO    | How are the additional metrics configured?                                                                  | 2021-12-31  | [calcipy/dev/noxfile.py:286](https://github.com/KyleKing/calcipy/blame/29459cfa64e77c2ee291c522230094d84f3ad647/calcipy/dev/noxfile.py#L282)                                   |
-| TODO    | Could use file archiver instead of git when the above fails?                                                | 2021-12-09  | [calcipy/dev/noxfile.py:301](https://github.com/KyleKing/calcipy/blame/16463ec8d6dcd828106df039a41ac82dc5726790/calcipy/dev/noxfile.py#L296)                                   |
+| PLANNED | Consider making "blame" configurable                                                                        | 2022-01-17  | [calcipy/code_tag_collector.py:185](https://github.com/KyleKing/calcipy/blame/ccc2e30c4c859c416ca87585cc56324228632016/calcipy/code_tag_collector.py#L180)                     |
+| TODO    | Make this auto-resolve based on pyproject.toml                                                              | 2021-10-30  | [calcipy/dev/noxfile.py:70](https://github.com/KyleKing/calcipy/blame/004df806a85aa9d1a6d0bbb5ab5b1f98ac263a3f/calcipy/dev/noxfile.py#L66)                                     |
+| TODO    | Implement semgrep - what are a good ruleset to start with? Currently only a nox-session (no doit task)      | 2021-06-08  | [calcipy/dev/noxfile.py:220](https://github.com/KyleKing/calcipy/blame/2822d0915aa092e099ccf31bc480c47dc2fb42a6/calcipy/dev/noxfile.py#L205)                                   |
+| TODO    | https://github.com/tonybaloney/wily/blob/e72b7d95228bbe5538a072dc5d1186daa318bb03/src/wily/__main__.py#L261 | 2021-12-09  | [calcipy/dev/noxfile.py:249](https://github.com/KyleKing/calcipy/blame/16463ec8d6dcd828106df039a41ac82dc5726790/calcipy/dev/noxfile.py#L270)                                   |
+| TODO    | How are the additional metrics configured?                                                                  | 2021-12-31  | [calcipy/dev/noxfile.py:261](https://github.com/KyleKing/calcipy/blame/29459cfa64e77c2ee291c522230094d84f3ad647/calcipy/dev/noxfile.py#L282)                                   |
+| TODO    | Could use file archiver instead of git when the above fails?                                                | 2021-12-09  | [calcipy/dev/noxfile.py:276](https://github.com/KyleKing/calcipy/blame/16463ec8d6dcd828106df039a41ac82dc5726790/calcipy/dev/noxfile.py#L296)                                   |
 | FIXME   | Refactor "cl_bump*" functions. Make "which $(..) >> /dev/null && " a function                               | 2022-01-19  | [calcipy/doit_tasks/doc.py:79](https://github.com/KyleKing/calcipy/blame/88a59195792115e9328dc418f24ab73970e0fffe/calcipy/doit_tasks/doc.py#L79)                               |
 | FIXME   | Refactor "cl_bump*" functions. Make "which $(..) >> /dev/null && " a function                               | 2022-01-19  | [calcipy/doit_tasks/doc.py:99](https://github.com/KyleKing/calcipy/blame/88a59195792115e9328dc418f24ab73970e0fffe/calcipy/doit_tasks/doc.py#L99)                               |
-| PLANNED | Simplify and choose one way of using Radon                                                                  | 2021-06-08  | [calcipy/doit_tasks/lint.py:167](https://github.com/KyleKing/calcipy/blame/b7f0f8d3b2a6c659511d690a1125a101c3945de8/calcipy/doit_tasks/lint.py#L153)                           |
-| PLANNED | Considering splitting paths on commas if above some maximum character length?                               | 2022-01-16  | [calcipy/doit_tasks/lint.py:222](https://github.com/KyleKing/calcipy/blame/f51fc70c2f237deef0d039c2a1f616ff1b901427/calcipy/doit_tasks/lint.py#L225)                           |
-| FIXME   | Add bulk toml formatting to the auto_format task!                                                           | 2022-01-16  | [calcipy/doit_tasks/lint.py:267](https://github.com/KyleKing/calcipy/blame/f51fc70c2f237deef0d039c2a1f616ff1b901427/calcipy/doit_tasks/lint.py#L270)                           |
-| PLANNED | Could provide more hooks for configuring taplo options. See:                                                | 2022-01-16  | [calcipy/doit_tasks/lint.py:281](https://github.com/KyleKing/calcipy/blame/f51fc70c2f237deef0d039c2a1f616ff1b901427/calcipy/doit_tasks/lint.py#L284)                           |
-| FIXME   | capturing to /dev/null doesn't seem to work reliably                                                        | 2022-02-23  | [calcipy/doit_tasks/lint.py:284](https://github.com/KyleKing/calcipy/blame/81c0adea275d4ed227d8ca95e6d752ae54577fed/calcipy/doit_tasks/lint.py#L289)                           |
-| FIXME   | Pyroma doesn't have the poetry requirement it needs...                                                      | 2022-05-30  | [calcipy/doit_tasks/packaging.py:68](https://github.com/KyleKing/calcipy/blame/2cff5da146fc08a45daf91faa684bac7ead491fa/calcipy/doit_tasks/packaging.py#L67)                   |
-| HACK    | Check that this works then refactor (shouldn't be global)                                                   | 2021-06-11  | [calcipy/doit_tasks/packaging.py:147](https://github.com/KyleKing/calcipy/blame/bbf19e63cbe0fc891dc76d686d7e113fa15be4ab/calcipy/doit_tasks/packaging.py#L146)                 |
-| TBD     | Handle non-pypi domains and format the URL accordingly (i.e. TestPyPi, etc.)                                | 2021-06-03  | [calcipy/doit_tasks/packaging.py:278](https://github.com/KyleKing/calcipy/blame/adaf2a6b09bfaa1cd4c55792fadf1ea0adeacd76/calcipy/doit_tasks/packaging.py#L157)                 |
+| TODO    | Better differentiate Task vs. Dict when typing and a dictionary is expected                                 | 2022-09-15  | [calcipy/doit_tasks/doit_globals.py:35](https://github.com/KyleKing/calcipy/blame/af48411a58a6bad447c8eb2a3e07cf842bb3a3a7/calcipy/doit_tasks/doit_globals.py#L35)             |
+| PLANNED | Simplify and choose one way of using Radon                                                                  | 2021-06-08  | [calcipy/doit_tasks/lint.py:169](https://github.com/KyleKing/calcipy/blame/b7f0f8d3b2a6c659511d690a1125a101c3945de8/calcipy/doit_tasks/lint.py#L153)                           |
+| PLANNED | Considering splitting paths on commas if above some maximum character length?                               | 2022-01-16  | [calcipy/doit_tasks/lint.py:224](https://github.com/KyleKing/calcipy/blame/f51fc70c2f237deef0d039c2a1f616ff1b901427/calcipy/doit_tasks/lint.py#L225)                           |
+| FIXME   | Add bulk toml formatting to the auto_format task!                                                           | 2022-01-16  | [calcipy/doit_tasks/lint.py:269](https://github.com/KyleKing/calcipy/blame/f51fc70c2f237deef0d039c2a1f616ff1b901427/calcipy/doit_tasks/lint.py#L270)                           |
+| PLANNED | Could provide more hooks for configuring taplo options. See:                                                | 2022-01-16  | [calcipy/doit_tasks/lint.py:283](https://github.com/KyleKing/calcipy/blame/f51fc70c2f237deef0d039c2a1f616ff1b901427/calcipy/doit_tasks/lint.py#L284)                           |
+| FIXME   | capturing to /dev/null doesn't seem to work reliably                                                        | 2022-02-23  | [calcipy/doit_tasks/lint.py:286](https://github.com/KyleKing/calcipy/blame/81c0adea275d4ed227d8ca95e6d752ae54577fed/calcipy/doit_tasks/lint.py#L289)                           |
+| HACK    | See pending pydantic changes: https://github.com/pydantic/pydantic/discussions/4456                         | 2022-09-15  | [calcipy/doit_tasks/packaging.py:128](https://github.com/KyleKing/calcipy/blame/af48411a58a6bad447c8eb2a3e07cf842bb3a3a7/calcipy/doit_tasks/packaging.py#L128)                 |
+| HACK    | Check that this works then refactor (shouldn't be global)                                                   | 2021-06-11  | [calcipy/doit_tasks/packaging.py:145](https://github.com/KyleKing/calcipy/blame/bbf19e63cbe0fc891dc76d686d7e113fa15be4ab/calcipy/doit_tasks/packaging.py#L146)                 |
+| TBD     | Handle non-pypi domains and format the URL accordingly (i.e. TestPyPi, etc.)                                | 2021-06-03  | [calcipy/doit_tasks/packaging.py:273](https://github.com/KyleKing/calcipy/blame/adaf2a6b09bfaa1cd4c55792fadf1ea0adeacd76/calcipy/doit_tasks/packaging.py#L157)                 |
 | PLANNED | handle multiline descriptions                                                                               | 2021-06-05  | [calcipy/doit_tasks/templates/text.mako:82](https://github.com/KyleKing/calcipy/blame/b0da1f50be6f40a8b083056c96b96e989449610f/calcipy/doit_tasks/templates/text.mako#L80)     |
 | PLANNED | handle multiline descriptions                                                                               | 2021-06-05  | [calcipy/doit_tasks/templates/text.mako:92](https://github.com/KyleKing/calcipy/blame/b0da1f50be6f40a8b083056c96b96e989449610f/calcipy/doit_tasks/templates/text.mako#L90)     |
 | PLANNED | add meta (example and notes)                                                                                | 2021-06-05  | [calcipy/doit_tasks/templates/text.mako:217](https://github.com/KyleKing/calcipy/blame/b0da1f50be6f40a8b083056c96b96e989449610f/calcipy/doit_tasks/templates/text.mako#L215)   |
@@ -32,7 +33,7 @@ Auto-Generated by `calcipy`
 | PLANNED | consider a STDOUT format like https://pypi.org/project/readable-log-formatter                               | 2021-06-08  | [calcipy/log_helpers.py:3](https://github.com/KyleKing/calcipy/blame/d459ba077570bce60b39233c1c771359a4c14316/calcipy/log_helpers.py#L3)                                       |
 | TODO    | Add documentation on configuration items in `pyproject.toml`                                                | 2021-06-08  | [docs/Advanced_Configuration.md:3](https://github.com/KyleKing/calcipy/blame/d459ba077570bce60b39233c1c771359a4c14316/docs/Advanced_Configuration.md#L3)                       |
 | TODO    | Add documentation on how to change DG within limited bounds (i.e. `handler_lookup` in `recipes`)            | 2021-06-08  | [docs/Advanced_Configuration.md:4](https://github.com/KyleKing/calcipy/blame/d459ba077570bce60b39233c1c771359a4c14316/docs/Advanced_Configuration.md#L4)                       |
-| TODO    | Implement fully optional imports with: https://github.com/KyleKing/calcipy/issues/19#issuecomment-807886404 | 2021-12-08  | [pyproject.toml:95](https://github.com/KyleKing/calcipy/blame/561583f54114efa41dec220bba6a8fb7ae0af80b/pyproject.toml#L82)                                                     |
+| TODO    | Implement fully optional imports with: https://github.com/KyleKing/calcipy/issues/19#issuecomment-807886404 | 2021-12-08  | [pyproject.toml:93](https://github.com/KyleKing/calcipy/blame/561583f54114efa41dec220bba6a8fb7ae0af80b/pyproject.toml#L82)                                                     |
 | FIXME   | Replace with programmatic imports? Maybe explicit imports to check backward compatibility of public API?    | 2021-05-27  | [scripts/check_imports.py:7](https://github.com/KyleKing/calcipy/blame/ac4e3e2887a77953237e498b9d1fba750be49c7e/scripts/check_imports.py#L7)                                   |
 | TODO    | Convert to function arguments - see example from code_tag_collector                                         | 2022-07-25  | [sync_toml_minimums.py:22](https://github.com/KyleKing/calcipy/blame/ff8bf04d2672fabc4f3e95706d2ec023f6f85dee/sync_toml_minimums.py#L22)                                       |
 | TODO    | Merge with user list                                                                                        | 2022-07-22  | [sync_toml_minimums.py:26](https://github.com/KyleKing/calcipy/blame/6f5f1ff88a93e9725272e9814966546b0a3c500c/sync_toml_minimums.py#L17)                                       |
@@ -40,12 +41,10 @@ Auto-Generated by `calcipy`
 | TODO    | Consider using pip-pi instead!                                                                              | 2022-07-23  | [sync_toml_minimums.py:46](https://github.com/KyleKing/calcipy/blame/04cecda5422277c0f0570c6bd110b0582f2210b5/sync_toml_minimums.py#L46)                                       |
 | PLANNED | Not yet used. From cement boilerplate                                                                       | 2021-12-31  | [tests/cli/test_main.py:22](https://github.com/KyleKing/calcipy/blame/21c5b446fca11d83dce8d2daedc2027c3d58b221/tests/cli/test_main.py#L22)                                     |
 | TODO    | Replace magic numbers in tests with meta-data about the "test_calcipy_project"                              | 2022-02-27  | [tests/configuration.py:24](https://github.com/KyleKing/calcipy/blame/ae7a371c863f742aed94fe4c86e0b5ac0499bc2a/tests/configuration.py#L24)                                     |
-| FIXME   | Replace DG with a magic property that calls the punq-registered DG rather than this workaround              | 2022-02-27  | [tests/configuration.py:42](https://github.com/KyleKing/calcipy/blame/ae7a371c863f742aed94fe4c86e0b5ac0499bc2a/tests/configuration.py#L42)                                     |
-| FIXME   | would be something like: container.register(TBD, instance=DG.set_paths(path_project=path_project))          | 2022-02-27  | [tests/configuration.py:62](https://github.com/KyleKing/calcipy/blame/ae7a371c863f742aed94fe4c86e0b5ac0499bc2a/tests/configuration.py#L62)                                     |
 | FIXME   | Replace MockLogger with a more generic alternative. See:                                                    | 2021-06-05  | [tests/test_doit_tasks/test_packaging.py:20](https://github.com/KyleKing/calcipy/blame/b0da1f50be6f40a8b083056c96b96e989449610f/tests/test_doit_tasks/test_packaging.py#L20)   |
 | TODO    | Capture logging output and check...                                                                         | 2021-06-08  | [tests/test_doit_tasks/test_packaging.py:132](https://github.com/KyleKing/calcipy/blame/f5ae6a5d029efa6cbc7ad6d26f2f61c6e28427f2/tests/test_doit_tasks/test_packaging.py#L132) |
 | TODO    | Convert to hypothesis test!                                                                                 | 2022-02-27  | [tests/test_dot_dict.py:9](https://github.com/KyleKing/calcipy/blame/884ff912d5716f91fc36a41be0eb492740335f24/tests/test_dot_dict.py#L9)                                       |
 
-Found code tags for FIXME (9), TODO (15), PLANNED (14), HACK (2), TBD (1)
+Found code tags for FIXME (6), TODO (16), PLANNED (14), HACK (3), TBD (1)
 
 <!-- calcipy:skip_tags -->
diff --git a/docs/docs/DEVELOPER_GUIDE.md b/docs/docs/DEVELOPER_GUIDE.md
index 1c4a72d0..fb0a2622 100644
--- a/docs/docs/DEVELOPER_GUIDE.md
+++ b/docs/docs/DEVELOPER_GUIDE.md
@@ -57,25 +57,25 @@ poetry run doit run lock document deploy_docs publish
 | `calcipy/cli/core/exceptions.py`                           |            2 |         0 |          0 | 100.0%     |
 | `calcipy/cli/core/version.py`                              |            8 |         8 |          0 | 0.0%       |
 | `calcipy/cli/main.py`                                      |           38 |        19 |          0 | 50.0%      |
-| `calcipy/code_tag_collector.py`                            |          119 |        23 |          0 | 80.7%      |
+| `calcipy/code_tag_collector.py`                            |          120 |        23 |          0 | 80.8%      |
 | `calcipy/dev/__init__.py`                                  |            0 |         0 |          0 | 100.0%     |
 | `calcipy/dev/conftest.py`                                  |           16 |         0 |         23 | 100.0%     |
-| `calcipy/dev/noxfile.py`                                   |           24 |         1 |         93 | 95.8%      |
+| `calcipy/dev/noxfile.py`                                   |           23 |         1 |         80 | 95.7%      |
 | `calcipy/doit_tasks/__init__.py`                           |           13 |         0 |          0 | 100.0%     |
 | `calcipy/doit_tasks/base.py`                               |           50 |        10 |          3 | 80.0%      |
 | `calcipy/doit_tasks/code_tags.py`                          |           10 |         0 |          0 | 100.0%     |
-| `calcipy/doit_tasks/doc.py`                                |          145 |        10 |          5 | 93.1%      |
-| `calcipy/doit_tasks/doit_globals.py`                       |          173 |         5 |          8 | 97.1%      |
-| `calcipy/doit_tasks/lint.py`                               |           96 |         8 |          0 | 91.7%      |
-| `calcipy/doit_tasks/packaging.py`                          |          137 |        12 |          3 | 91.2%      |
-| `calcipy/doit_tasks/summary_reporter.py`                   |           23 |         0 |         40 | 100.0%     |
+| `calcipy/doit_tasks/doc.py`                                |          146 |        10 |          5 | 93.2%      |
+| `calcipy/doit_tasks/doit_globals.py`                       |          180 |         4 |          4 | 97.8%      |
+| `calcipy/doit_tasks/lint.py`                               |           98 |         8 |          0 | 91.8%      |
+| `calcipy/doit_tasks/packaging.py`                          |          140 |        12 |          0 | 91.4%      |
+| `calcipy/doit_tasks/summary_reporter.py`                   |           21 |         0 |         40 | 100.0%     |
 | `calcipy/doit_tasks/test.py`                               |           61 |        10 |          0 | 83.6%      |
 | `calcipy/dot_dict.py`                                      |            7 |         0 |          0 | 100.0%     |
-| `calcipy/file_helpers.py`                                  |           76 |         7 |          3 | 90.8%      |
+| `calcipy/file_helpers.py`                                  |           76 |         6 |          3 | 92.1%      |
 | `calcipy/file_search.py`                                   |           34 |         0 |          2 | 100.0%     |
 | `calcipy/log_helpers.py`                                   |           62 |         6 |          0 | 90.3%      |
 | `calcipy/proc_helpers.py`                                  |           21 |         1 |          0 | 95.2%      |
-| **Totals**                                                 |         1147 |       132 |        180 | 88.5%      |
+| **Totals**                                                 |         1158 |       130 |        160 | 88.8%      |
 
-Generated on: 2022-08-04
+Generated on: 2022-09-15
 <!-- {cte} -->
diff --git a/ideas-toml.md b/ideas-toml.md
deleted file mode 100644
index 74ef57ec..00000000
--- a/ideas-toml.md
+++ /dev/null
@@ -1,2 +0,0 @@
-For stale packages, could also include a metric of packages that have low download counts for flagging niche packages?
-https://pypistats.org/api/
diff --git a/noxfile.py b/noxfile.py
index 8e5634e6..b53b2138 100644
--- a/noxfile.py
+++ b/noxfile.py
@@ -1,5 +1,3 @@
 """nox-poetry configuration file."""
 
-from calcipy.dev.noxfile import (  # noqa: F401
-    build_check, build_dist, check_safety, check_security, coverage, pin_dev_dependencies, tests,
-)
+from calcipy.dev.noxfile import build_check, build_dist, check_security, coverage, tests  # noqa: F401
diff --git a/poetry.lock b/poetry.lock
index 80e0dc67..0a778786 100644
--- a/poetry.lock
+++ b/poetry.lock
@@ -28,6 +28,17 @@ python-versions = "*"
 [package.extras]
 test = ["coverage", "flake8", "pexpect", "wheel"]
 
+[[package]]
+name = "arrow"
+version = "1.2.3"
+description = "Better dates & times for Python"
+category = "main"
+optional = false
+python-versions = ">=3.6"
+
+[package.dependencies]
+python-dateutil = ">=2.7.0"
+
 [[package]]
 name = "astor"
 version = "0.8.1"
@@ -46,20 +57,23 @@ python-versions = ">=3.8"
 
 [[package]]
 name = "astroid"
-version = "2.11.7"
+version = "2.12.9"
 description = "An abstract syntax tree for Python with inference support."
 category = "main"
 optional = true
-python-versions = ">=3.6.2"
+python-versions = ">=3.7.2"
 
 [package.dependencies]
 lazy-object-proxy = ">=1.4.0"
 typing-extensions = {version = ">=3.10", markers = "python_version < \"3.10\""}
-wrapt = ">=1.11,<2"
+wrapt = [
+    {version = ">=1.11,<2", markers = "python_version < \"3.11\""},
+    {version = ">=1.14,<2", markers = "python_version >= \"3.11\""},
+]
 
 [[package]]
 name = "asttokens"
-version = "2.0.5"
+version = "2.0.8"
 description = "Annotate AST trees with source code positions"
 category = "main"
 optional = true
@@ -69,70 +83,63 @@ python-versions = "*"
 six = "*"
 
 [package.extras]
-test = ["astroid", "pytest"]
-
-[[package]]
-name = "atomicwrites"
-version = "1.4.1"
-description = "Atomic file writes."
-category = "main"
-optional = true
-python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
+test = ["astroid (<=2.5.3)", "pytest"]
 
 [[package]]
 name = "attrs"
 version = "21.4.0"
 description = "Classes Without Boilerplate"
 category = "main"
-optional = false
+optional = true
 python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
 
 [package.extras]
-dev = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins", "zope.interface", "furo", "sphinx", "sphinx-notfound-page", "pre-commit", "cloudpickle"]
-docs = ["furo", "sphinx", "zope.interface", "sphinx-notfound-page"]
-tests = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins", "zope.interface", "cloudpickle"]
-tests_no_zope = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins", "cloudpickle"]
+dev = ["cloudpickle", "coverage[toml] (>=5.0.2)", "furo", "hypothesis", "mypy", "pre-commit", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "six", "sphinx", "sphinx-notfound-page", "zope.interface"]
+docs = ["furo", "sphinx", "sphinx-notfound-page", "zope.interface"]
+tests = ["cloudpickle", "coverage[toml] (>=5.0.2)", "hypothesis", "mypy", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "six", "zope.interface"]
+tests_no_zope = ["cloudpickle", "coverage[toml] (>=5.0.2)", "hypothesis", "mypy", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "six"]
 
 [[package]]
 name = "attrs-strict"
 version = "1.0.0"
 description = "Runtime validators for attrs"
 category = "main"
-optional = false
+optional = true
 python-versions = ">=3.7"
 
 [package.dependencies]
 attrs = ">=19.1.0"
 
 [package.extras]
-test = ["pytest-cov (>=3)", "pytest (>=6)", "covdefaults (>=2)"]
 docs = ["Sphinx (>=3)"]
+test = ["covdefaults (>=2)", "pytest (>=6)", "pytest-cov (>=3)"]
 
 [[package]]
 name = "autoflake"
-version = "1.4"
+version = "1.5.3"
 description = "Removes unused imports and unused variables"
 category = "main"
 optional = true
-python-versions = "*"
+python-versions = ">=3.7"
 
 [package.dependencies]
 pyflakes = ">=1.1.0"
+toml = ">=0.10.2"
 
 [[package]]
 name = "autopep8"
-version = "1.6.0"
+version = "1.7.0"
 description = "A tool that automatically formats Python code to conform to the PEP 8 style guide"
 category = "main"
 optional = true
 python-versions = "*"
 
 [package.dependencies]
-pycodestyle = ">=2.8.0"
+pycodestyle = ">=2.9.1"
 toml = "*"
 
 [[package]]
-name = "babel"
+name = "Babel"
 version = "2.10.3"
 description = "Internationalization utilities"
 category = "main"
@@ -157,9 +164,9 @@ PyYAML = ">=5.3.1"
 stevedore = ">=1.20.0"
 
 [package.extras]
-test = ["coverage (>=4.5.4)", "fixtures (>=3.0.0)", "flake8 (>=4.0.0)", "stestr (>=2.5.0)", "testscenarios (>=0.5.0)", "testtools (>=2.3.0)", "toml", "beautifulsoup4 (>=4.8.0)", "pylint (==1.9.4)"]
+test = ["beautifulsoup4 (>=4.8.0)", "coverage (>=4.5.4)", "fixtures (>=3.0.0)", "flake8 (>=4.0.0)", "pylint (==1.9.4)", "stestr (>=2.5.0)", "testscenarios (>=0.5.0)", "testtools (>=2.3.0)", "toml"]
 toml = ["toml"]
-yaml = ["pyyaml"]
+yaml = ["PyYAML"]
 
 [[package]]
 name = "beartype"
@@ -171,9 +178,9 @@ python-versions = ">=3.6.0"
 
 [package.extras]
 all = ["typing-extensions (>=3.10.0.0)"]
-dev = ["coverage (>=5.5)", "sphinx", "pytest (>=4.0.0)", "tox (>=3.20.1)", "sphinx (>=4.1.0)", "mypy (>=0.800)", "typing-extensions", "numpy"]
+dev = ["coverage (>=5.5)", "mypy (>=0.800)", "numpy", "pytest (>=4.0.0)", "sphinx", "sphinx (>=4.1.0)", "tox (>=3.20.1)", "typing-extensions"]
 doc-rtd = ["sphinx (==4.1.0)", "sphinx-rtd-theme (==0.5.1)"]
-test-tox = ["sphinx", "pytest (>=4.0.0)", "mypy (>=0.800)", "typing-extensions", "numpy"]
+test-tox = ["mypy (>=0.800)", "numpy", "pytest (>=4.0.0)", "sphinx", "typing-extensions"]
 test-tox-coverage = ["coverage (>=5.5)"]
 
 [[package]]
@@ -197,7 +204,7 @@ python-versions = ">=3.7"
 
 [[package]]
 name = "black"
-version = "22.6.0"
+version = "22.8.0"
 description = "The uncompromising code formatter."
 category = "main"
 optional = true
@@ -219,15 +226,26 @@ uvloop = ["uvloop (>=0.15.2)"]
 
 [[package]]
 name = "cement"
-version = "3.0.6"
+version = "3.0.8"
 description = "Application Framework for Python"
 category = "main"
 optional = false
 python-versions = ">=3.5"
 
+[package.extras]
+colorlog = ["colorlog"]
+generate = ["pyYaml"]
+jinja2 = ["jinja2"]
+memcached = ["pylibmc"]
+mustache = ["pystache"]
+redis = ["redis"]
+tabulate = ["tabulate"]
+watchdog = ["watchdog"]
+yaml = ["pyYaml"]
+
 [[package]]
 name = "certifi"
-version = "2022.6.15"
+version = "2022.9.14"
 description = "Python package for providing Mozilla's CA Bundle."
 category = "main"
 optional = false
@@ -251,7 +269,7 @@ python-versions = ">=3.6"
 
 [[package]]
 name = "charset-normalizer"
-version = "2.1.0"
+version = "2.1.1"
 description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet."
 category = "main"
 optional = false
@@ -273,7 +291,7 @@ colorama = {version = "*", markers = "platform_system == \"Windows\""}
 
 [[package]]
 name = "cloudpickle"
-version = "2.1.0"
+version = "2.2.0"
 description = "Extended pickling support for Python objects"
 category = "main"
 optional = false
@@ -281,12 +299,15 @@ python-versions = ">=3.6"
 
 [[package]]
 name = "cognitive-complexity"
-version = "1.2.0"
+version = "1.3.0"
 description = "Library to calculate Python functions cognitive complexity via code"
 category = "main"
 optional = true
 python-versions = ">=3.6"
 
+[package.dependencies]
+setuptools = "*"
+
 [[package]]
 name = "cohesion"
 version = "1.0.0"
@@ -305,7 +326,7 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
 
 [[package]]
 name = "colorlog"
-version = "6.6.0"
+version = "6.7.0"
 description = "Add colours to the output of Python's logging module."
 category = "main"
 optional = true
@@ -319,7 +340,7 @@ development = ["black", "flake8", "mypy", "pytest", "types-colorama"]
 
 [[package]]
 name = "commitizen"
-version = "2.29.5"
+version = "2.33.0"
 description = "Python commitizen client tool"
 category = "main"
 optional = true
@@ -347,11 +368,11 @@ optional = true
 python-versions = "*"
 
 [package.extras]
-test = ["hypothesis (==3.55.3)", "flake8 (==3.7.8)"]
+test = ["flake8 (==3.7.8)", "hypothesis (==3.55.3)"]
 
 [[package]]
 name = "coverage"
-version = "6.4.3"
+version = "6.4.4"
 description = "Code coverage measurement for Python"
 category = "main"
 optional = true
@@ -412,10 +433,10 @@ optional = true
 python-versions = "*"
 
 [package.extras]
-tests = ["pytest-pydocstyle (>=2.2.0)", "pytest-pycodestyle (>=2.2.0)", "pytest (>=6)", "pytest-pydocstyle (>=2)", "pytest-pycodestyle (>=2)", "pytest (==5.4.3)", "tox (>=3.7.0)", "sphinx (>=3)", "pytest-isort (>=1.2.0)", "pytest-cov (>=2.10.1)", "mock (>=1.3.0)", "check-manifest (>=0.42)"]
-numpy = ["numpy (>=1.20.0)", "numpy (>=1.18.0)", "numpy (>=1.15.0)", "numpy (>=1.13.0)"]
-docs = ["sphinx-rtd-theme (>=0.2)", "Sphinx (>=3)"]
-all = ["numpy (>=1.20.0)", "pytest-pydocstyle (>=2.2.0)", "pytest-pycodestyle (>=2.2.0)", "pytest (>=6)", "pytest-pydocstyle (>=2)", "pytest-pycodestyle (>=2)", "pytest (==5.4.3)", "numpy (>=1.18.0)", "numpy (>=1.15.0)", "numpy (>=1.13.0)", "tox (>=3.7.0)", "sphinx (>=3)", "pytest-isort (>=1.2.0)", "pytest-cov (>=2.10.1)", "mock (>=1.3.0)", "check-manifest (>=0.42)", "sphinx-rtd-theme (>=0.2)", "Sphinx (>=3)"]
+all = ["Sphinx (>=3)", "check-manifest (>=0.42)", "mock (>=1.3.0)", "numpy (>=1.13.0)", "numpy (>=1.15.0)", "numpy (>=1.18.0)", "numpy (>=1.20.0)", "pytest (==5.4.3)", "pytest (>=6)", "pytest-cov (>=2.10.1)", "pytest-isort (>=1.2.0)", "pytest-pycodestyle (>=2)", "pytest-pycodestyle (>=2.2.0)", "pytest-pydocstyle (>=2)", "pytest-pydocstyle (>=2.2.0)", "sphinx (>=3)", "sphinx-rtd-theme (>=0.2)", "tox (>=3.7.0)"]
+docs = ["Sphinx (>=3)", "sphinx-rtd-theme (>=0.2)"]
+numpy = ["numpy (>=1.13.0)", "numpy (>=1.15.0)", "numpy (>=1.18.0)", "numpy (>=1.20.0)"]
+tests = ["check-manifest (>=0.42)", "mock (>=1.3.0)", "pytest (==5.4.3)", "pytest (>=6)", "pytest-cov (>=2.10.1)", "pytest-isort (>=1.2.0)", "pytest-pycodestyle (>=2)", "pytest-pycodestyle (>=2.2.0)", "pytest-pydocstyle (>=2)", "pytest-pydocstyle (>=2.2.0)", "sphinx (>=3)", "tox (>=3.7.0)"]
 
 [[package]]
 name = "diff-cover"
@@ -447,7 +468,7 @@ graph = ["objgraph (>=1.7.2)"]
 
 [[package]]
 name = "distlib"
-version = "0.3.5"
+version = "0.3.6"
 description = "Distribution utilities"
 category = "main"
 optional = false
@@ -455,14 +476,14 @@ python-versions = "*"
 
 [[package]]
 name = "dlint"
-version = "0.12.0"
+version = "0.13.0"
 description = "Dlint is a tool for encouraging best coding practices and helping ensure Python code is secure."
 category = "main"
 optional = true
 python-versions = "*"
 
 [package.dependencies]
-flake8 = ">=3.6.0,<5.0.0"
+flake8 = ">=3.6.0,<6.0.0"
 
 [[package]]
 name = "docstring-parser"
@@ -497,7 +518,7 @@ python-versions = "*"
 
 [[package]]
 name = "exceptiongroup"
-version = "1.0.0rc8"
+version = "1.0.0rc9"
 description = "Backport of PEP 654 (exception groups)"
 category = "main"
 optional = true
@@ -540,39 +561,39 @@ tomli = ">=2.0.0,<3"
 
 [[package]]
 name = "filelock"
-version = "3.7.1"
+version = "3.8.0"
 description = "A platform independent file lock."
 category = "main"
 optional = false
 python-versions = ">=3.7"
 
 [package.extras]
-docs = ["furo (>=2021.8.17b43)", "sphinx (>=4.1)", "sphinx-autodoc-typehints (>=1.12)"]
-testing = ["covdefaults (>=1.2.0)", "coverage (>=4)", "pytest (>=4)", "pytest-cov", "pytest-timeout (>=1.4.2)"]
+docs = ["furo (>=2022.6.21)", "sphinx (>=5.1.1)", "sphinx-autodoc-typehints (>=1.19.1)"]
+testing = ["covdefaults (>=2.2)", "coverage (>=6.4.2)", "pytest (>=7.1.2)", "pytest-cov (>=3)", "pytest-timeout (>=2.1)"]
 
 [[package]]
 name = "flake8"
-version = "4.0.1"
+version = "5.0.4"
 description = "the modular source code checker: pep8 pyflakes and co"
 category = "main"
 optional = true
-python-versions = ">=3.6"
+python-versions = ">=3.6.1"
 
 [package.dependencies]
-mccabe = ">=0.6.0,<0.7.0"
-pycodestyle = ">=2.8.0,<2.9.0"
-pyflakes = ">=2.4.0,<2.5.0"
+mccabe = ">=0.7.0,<0.8.0"
+pycodestyle = ">=2.9.0,<2.10.0"
+pyflakes = ">=2.5.0,<2.6.0"
 
 [[package]]
 name = "flake8-2020"
-version = "1.6.1"
+version = "1.7.0"
 description = "flake8 plugin which checks for misuse of `sys.version` or `sys.version_info`"
 category = "main"
 optional = true
-python-versions = ">=3.6.1"
+python-versions = ">=3.7"
 
 [package.dependencies]
-flake8 = ">=3.7"
+flake8 = ">=5"
 
 [[package]]
 name = "flake8-aaa"
@@ -610,7 +631,7 @@ flake8 = ">=3.0.0"
 
 [[package]]
 name = "flake8-bandit"
-version = "3.0.0"
+version = "4.1.1"
 description = "Automated security testing with bandit and flake8."
 category = "main"
 optional = true
@@ -618,9 +639,7 @@ python-versions = ">=3.6"
 
 [package.dependencies]
 bandit = ">=1.7.3"
-flake8 = "*"
-flake8-polyfill = "*"
-pycodestyle = "*"
+flake8 = ">=5.0.0"
 
 [[package]]
 name = "flake8-blind-except"
@@ -643,18 +662,18 @@ flake8-plugin-utils = ">=1.0,<2.0"
 
 [[package]]
 name = "flake8-broken-line"
-version = "0.4.0"
+version = "0.5.0"
 description = "Flake8 plugin to forbid backslashes for line breaks"
 category = "main"
 optional = true
 python-versions = ">=3.6,<4.0"
 
 [package.dependencies]
-flake8 = ">=3.5,<5"
+flake8 = ">=3.5,<6"
 
 [[package]]
 name = "flake8-bugbear"
-version = "22.7.1"
+version = "22.9.11"
 description = "A plugin for flake8 finding likely bugs and design problems in your program. Contains warnings that don't belong in pyflakes and pycodestyle."
 category = "main"
 optional = true
@@ -691,6 +710,7 @@ python-versions = ">=3.6"
 
 [package.dependencies]
 cognitive_complexity = "*"
+setuptools = "*"
 
 [[package]]
 name = "flake8-comprehensions"
@@ -729,7 +749,7 @@ pydocstyle = ">=2.1"
 
 [[package]]
 name = "flake8-eradicate"
-version = "1.2.1"
+version = "1.3.0"
 description = "Flake8 plugin to find commented out code"
 category = "main"
 optional = true
@@ -738,7 +758,8 @@ python-versions = ">=3.6,<4.0"
 [package.dependencies]
 attrs = "*"
 eradicate = ">=2.0,<3.0"
-flake8 = ">=3.5,<5"
+flake8 = ">=3.5,<6"
+setuptools = "*"
 
 [[package]]
 name = "flake8-expression-complexity"
@@ -770,6 +791,7 @@ python-versions = "*"
 
 [package.dependencies]
 mr-proper = "*"
+setuptools = "*"
 
 [[package]]
 name = "flake8-isort"
@@ -788,22 +810,26 @@ test = ["pytest-cov"]
 
 [[package]]
 name = "flake8-logging-format"
-version = "0.6.0"
-description = "Flake8 extension to validate (lack of) logging format strings"
+version = "0.7.5"
+description = ""
 category = "main"
 optional = true
 python-versions = "*"
 
+[package.extras]
+lint = ["flake8"]
+test = ["PyHamcrest", "pytest", "pytest-cov"]
+
 [[package]]
 name = "flake8-markdown"
-version = "0.3.0"
+version = "0.4.0"
 description = "Lints Python code blocks in Markdown files using flake8"
 category = "main"
 optional = true
-python-versions = ">=3.6,<4.0"
+python-versions = ">=3.7"
 
 [package.dependencies]
-flake8 = ">=3.0,<5.0"
+flake8 = ">=5.0.0"
 
 [[package]]
 name = "flake8-pep3101"
@@ -817,7 +843,7 @@ python-versions = "*"
 flake8 = ">=3.0"
 
 [package.extras]
-test = ["testfixtures", "pytest"]
+test = ["pytest", "testfixtures"]
 
 [[package]]
 name = "flake8-plone-hasattr"
@@ -838,17 +864,6 @@ category = "main"
 optional = true
 python-versions = ">=3.6,<4.0"
 
-[[package]]
-name = "flake8-polyfill"
-version = "1.0.2"
-description = "Polyfill package for Flake8 plugins"
-category = "main"
-optional = true
-python-versions = "*"
-
-[package.dependencies]
-flake8 = "*"
-
 [[package]]
 name = "flake8-print"
 version = "5.0.0"
@@ -918,7 +933,7 @@ astor = ">=0.1"
 flake8 = ">=3.7"
 
 [[package]]
-name = "flake8-sql"
+name = "flake8-SQL"
 version = "0.4.1"
 description = "Flake8 plugin that checks SQL code against opinionated style rules"
 category = "main"
@@ -927,6 +942,7 @@ python-versions = "*"
 
 [package.dependencies]
 flake8 = "*"
+setuptools = "*"
 sqlparse = "*"
 
 [[package]]
@@ -962,16 +978,16 @@ python-versions = ">=3.7"
 
 [[package]]
 name = "fonttools"
-version = "4.34.4"
+version = "4.37.2"
 description = "Tools to manipulate font files"
 category = "dev"
 optional = false
 python-versions = ">=3.7"
 
 [package.extras]
-all = ["fs (>=2.2.0,<3)", "lxml (>=4.0,<5)", "zopfli (>=0.1.4)", "lz4 (>=1.7.4.2)", "matplotlib", "sympy", "skia-pathops (>=0.5.0)", "uharfbuzz (>=0.23.0)", "brotlicffi (>=0.8.0)", "scipy", "brotli (>=1.0.1)", "munkres", "unicodedata2 (>=14.0.0)", "xattr"]
+all = ["brotli (>=1.0.1)", "brotlicffi (>=0.8.0)", "fs (>=2.2.0,<3)", "lxml (>=4.0,<5)", "lz4 (>=1.7.4.2)", "matplotlib", "munkres", "scipy", "skia-pathops (>=0.5.0)", "sympy", "uharfbuzz (>=0.23.0)", "unicodedata2 (>=14.0.0)", "xattr", "zopfli (>=0.1.4)"]
 graphite = ["lz4 (>=1.7.4.2)"]
-interpolatable = ["scipy", "munkres"]
+interpolatable = ["munkres", "scipy"]
 lxml = ["lxml (>=4.0,<5)"]
 pathops = ["skia-pathops (>=0.5.0)"]
 plot = ["matplotlib"]
@@ -980,7 +996,7 @@ symfont = ["sympy"]
 type1 = ["xattr"]
 ufo = ["fs (>=2.2.0,<3)"]
 unicode = ["unicodedata2 (>=14.0.0)"]
-woff = ["zopfli (>=0.1.4)", "brotlicffi (>=0.8.0)", "brotli (>=1.0.1)"]
+woff = ["brotli (>=1.0.1)", "brotlicffi (>=0.8.0)", "zopfli (>=0.1.4)"]
 
 [[package]]
 name = "future"
@@ -1002,7 +1018,7 @@ python-versions = "*"
 python-dateutil = ">=2.8.1"
 
 [package.extras]
-dev = ["wheel", "flake8", "markdown", "twine"]
+dev = ["flake8", "markdown", "twine", "wheel"]
 
 [[package]]
 name = "gitdb"
@@ -1016,7 +1032,7 @@ python-versions = ">=3.6"
 smmap = ">=3.0.1,<6"
 
 [[package]]
-name = "gitpython"
+name = "GitPython"
 version = "3.1.27"
 description = "GitPython is a python library used to interact with Git repositories"
 category = "main"
@@ -1040,7 +1056,7 @@ requests = "*"
 
 [[package]]
 name = "hypothesis"
-version = "6.54.1"
+version = "6.54.5"
 description = "A library for property-based testing"
 category = "main"
 optional = true
@@ -1055,11 +1071,11 @@ rich = {version = ">=9.0.0", optional = true, markers = "extra == \"cli\""}
 sortedcontainers = ">=2.1.0,<3.0.0"
 
 [package.extras]
-all = ["black (>=19.10b0)", "click (>=7.0)", "django (>=2.2)", "dpcontracts (>=0.4)", "lark-parser (>=0.6.5)", "libcst (>=0.3.16)", "numpy (>=1.9.0)", "pandas (>=1.0)", "pytest (>=4.6)", "python-dateutil (>=1.4)", "pytz (>=2014.1)", "redis (>=3.0.0)", "rich (>=9.0.0)", "importlib-metadata (>=3.6)", "backports.zoneinfo (>=0.2.1)", "tzdata (>=2022.1)"]
-cli = ["click (>=7.0)", "black (>=19.10b0)", "rich (>=9.0.0)"]
+all = ["backports.zoneinfo (>=0.2.1)", "black (>=19.10b0)", "click (>=7.0)", "django (>=3.2)", "dpcontracts (>=0.4)", "importlib-metadata (>=3.6)", "lark-parser (>=0.6.5)", "libcst (>=0.3.16)", "numpy (>=1.9.0)", "pandas (>=1.0)", "pytest (>=4.6)", "python-dateutil (>=1.4)", "pytz (>=2014.1)", "redis (>=3.0.0)", "rich (>=9.0.0)", "tzdata (>=2022.2)"]
+cli = ["black (>=19.10b0)", "click (>=7.0)", "rich (>=9.0.0)"]
 codemods = ["libcst (>=0.3.16)"]
 dateutil = ["python-dateutil (>=1.4)"]
-django = ["django (>=2.2)"]
+django = ["django (>=3.2)"]
 dpcontracts = ["dpcontracts (>=0.4)"]
 ghostwriter = ["black (>=19.10b0)"]
 lark = ["lark-parser (>=0.6.5)"]
@@ -1068,11 +1084,11 @@ pandas = ["pandas (>=1.0)"]
 pytest = ["pytest (>=4.6)"]
 pytz = ["pytz (>=2014.1)"]
 redis = ["redis (>=3.0.0)"]
-zoneinfo = ["backports.zoneinfo (>=0.2.1)", "tzdata (>=2022.1)"]
+zoneinfo = ["backports.zoneinfo (>=0.2.1)", "tzdata (>=2022.2)"]
 
 [[package]]
 name = "identify"
-version = "2.5.3"
+version = "2.5.5"
 description = "File identification library for Python"
 category = "main"
 optional = false
@@ -1083,7 +1099,7 @@ license = ["ukkonen"]
 
 [[package]]
 name = "idna"
-version = "3.3"
+version = "3.4"
 description = "Internationalized Domain Names in Applications (IDNA)"
 category = "main"
 optional = false
@@ -1112,9 +1128,9 @@ python-versions = ">=3.7"
 zipp = ">=0.5"
 
 [package.extras]
-docs = ["sphinx", "jaraco.packaging (>=9)", "rst.linker (>=1.9)"]
+docs = ["jaraco.packaging (>=9)", "rst.linker (>=1.9)", "sphinx"]
 perf = ["ipython"]
-testing = ["pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest-cov", "pytest-enabler (>=1.3)", "packaging", "pyfakefs", "flufl.flake8", "pytest-perf (>=0.9.2)", "pytest-black (>=0.3.7)", "pytest-mypy (>=0.9.1)", "importlib-resources (>=1.3)"]
+testing = ["flufl.flake8", "importlib-resources (>=1.3)", "packaging", "pyfakefs", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)", "pytest-perf (>=0.9.2)"]
 
 [[package]]
 name = "iniconfig"
@@ -1133,13 +1149,13 @@ optional = true
 python-versions = ">=3.6.1,<4.0"
 
 [package.extras]
-pipfile_deprecated_finder = ["pipreqs", "requirementslib"]
-requirements_deprecated_finder = ["pipreqs", "pip-api"]
 colors = ["colorama (>=0.4.3,<0.5.0)"]
+pipfile_deprecated_finder = ["pipreqs", "requirementslib"]
 plugins = ["setuptools"]
+requirements_deprecated_finder = ["pip-api", "pipreqs"]
 
 [[package]]
-name = "jinja2"
+name = "Jinja2"
 version = "3.1.2"
 description = "A very fast and expressive template engine."
 category = "main"
@@ -1182,7 +1198,7 @@ typing-extensions = ">=3.7.4.2"
 typing-inspect = ">=0.4.0"
 
 [package.extras]
-dev = ["black (==22.3.0)", "coverage (>=4.5.4)", "fixit (==0.1.1)", "flake8 (>=3.7.8)", "hypothesis (>=4.36.0)", "hypothesmith (>=0.0.4)", "jupyter (>=1.0.0)", "maturin (>=0.8.3,<0.9)", "nbsphinx (>=0.4.2)", "prompt-toolkit (>=2.0.9)", "setuptools-scm (>=6.0.1)", "sphinx-rtd-theme (>=0.4.3)", "ufmt (==1.3)", "usort (==1.0.0rc1)", "setuptools-rust (>=0.12.1)", "slotscheck (>=0.7.1)", "jinja2 (==3.0.3)", "pyre-check (==0.9.9)"]
+dev = ["black (==22.3.0)", "coverage (>=4.5.4)", "fixit (==0.1.1)", "flake8 (>=3.7.8)", "hypothesis (>=4.36.0)", "hypothesmith (>=0.0.4)", "jinja2 (==3.0.3)", "jupyter (>=1.0.0)", "maturin (>=0.8.3,<0.9)", "nbsphinx (>=0.4.2)", "prompt-toolkit (>=2.0.9)", "pyre-check (==0.9.9)", "setuptools-rust (>=0.12.1)", "setuptools-scm (>=6.0.1)", "slotscheck (>=0.7.1)", "sphinx-rtd-theme (>=0.4.3)", "ufmt (==1.3)", "usort (==1.0.0rc1)"]
 
 [[package]]
 name = "licensecheck"
@@ -1211,7 +1227,7 @@ colorama = {version = ">=0.3.4", markers = "sys_platform == \"win32\""}
 win32-setctime = {version = ">=1.0.0", markers = "sys_platform == \"win32\""}
 
 [package.extras]
-dev = ["sphinx-rtd-theme (>=0.4.3)", "sphinx-autobuild (>=0.7.1)", "Sphinx (>=4.1.1)", "isort (>=5.1.1)", "black (>=19.10b0)", "pytest-cov (>=2.7.1)", "pytest (>=4.6.2)", "tox (>=3.9.0)", "flake8 (>=3.7.7)", "docutils (==0.16)", "colorama (>=0.3.4)"]
+dev = ["Sphinx (>=4.1.1)", "black (>=19.10b0)", "colorama (>=0.3.4)", "docutils (==0.16)", "flake8 (>=3.7.7)", "isort (>=5.1.1)", "pytest (>=4.6.2)", "pytest-cov (>=2.7.1)", "sphinx-autobuild (>=0.7.1)", "sphinx-rtd-theme (>=0.4.3)", "tox (>=3.9.0)"]
 
 [[package]]
 name = "lxml"
@@ -1224,12 +1240,12 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, != 3.4.*"
 [package.extras]
 cssselect = ["cssselect (>=0.7)"]
 html5 = ["html5lib"]
-htmlsoup = ["beautifulsoup4"]
+htmlsoup = ["BeautifulSoup4"]
 source = ["Cython (>=0.29.7)"]
 
 [[package]]
-name = "mako"
-version = "1.2.1"
+name = "Mako"
+version = "1.2.2"
 description = "A super-fast templating language that borrows the best ideas from the existing templating languages."
 category = "main"
 optional = true
@@ -1239,7 +1255,7 @@ python-versions = ">=3.7"
 MarkupSafe = ">=0.9.2"
 
 [package.extras]
-babel = ["babel"]
+babel = ["Babel"]
 lingua = ["lingua"]
 testing = ["pytest"]
 
@@ -1258,7 +1274,7 @@ six = "*"
 restructuredText = ["rst2ansi"]
 
 [[package]]
-name = "markdown"
+name = "Markdown"
 version = "3.4.1"
 description = "Python implementation of Markdown."
 category = "main"
@@ -1272,7 +1288,7 @@ importlib-metadata = {version = ">=4.4", markers = "python_version < \"3.10\""}
 testing = ["coverage", "pyyaml"]
 
 [[package]]
-name = "markupsafe"
+name = "MarkupSafe"
 version = "2.1.1"
 description = "Safely add untrusted strings to HTML/XML markup."
 category = "main"
@@ -1281,7 +1297,7 @@ python-versions = ">=3.7"
 
 [[package]]
 name = "matplotlib"
-version = "3.5.2"
+version = "3.5.3"
 description = "Python plotting package"
 category = "dev"
 optional = false
@@ -1296,15 +1312,15 @@ packaging = ">=20.0"
 pillow = ">=6.2.0"
 pyparsing = ">=2.2.1"
 python-dateutil = ">=2.7"
-setuptools_scm = ">=4"
+setuptools_scm = ">=4,<7"
 
 [[package]]
 name = "mccabe"
-version = "0.6.1"
+version = "0.7.0"
 description = "McCabe checker, plugin for flake8"
 category = "main"
 optional = true
-python-versions = "*"
+python-versions = ">=3.6"
 
 [[package]]
 name = "mergedeep"
@@ -1352,7 +1368,7 @@ mkdocs = ">=1.0"
 
 [[package]]
 name = "mkdocs-material"
-version = "8.3.9"
+version = "8.5.1"
 description = "Documentation that simply works"
 category = "main"
 optional = true
@@ -1365,6 +1381,7 @@ mkdocs = ">=1.3.0"
 mkdocs-material-extensions = ">=1.0.3"
 pygments = ">=2.12"
 pymdown-extensions = ">=9.4"
+requests = ">=2.26"
 
 [[package]]
 name = "mkdocs-material-extensions"
@@ -1384,6 +1401,7 @@ python-versions = "*"
 
 [package.dependencies]
 click = ">=7.1.2"
+setuptools = "*"
 stdlib-list = ">=0.5.0"
 
 [[package]]
@@ -1428,6 +1446,9 @@ category = "main"
 optional = false
 python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*"
 
+[package.dependencies]
+setuptools = "*"
+
 [[package]]
 name = "nox"
 version = "2022.8.7"
@@ -1461,7 +1482,7 @@ tomlkit = ">=0.7"
 
 [[package]]
 name = "numpy"
-version = "1.23.1"
+version = "1.23.3"
 description = "NumPy is the fundamental package for array computing with Python."
 category = "main"
 optional = false
@@ -1480,7 +1501,7 @@ pyparsing = ">=2.0.2,<3.0.5 || >3.0.5"
 
 [[package]]
 name = "pandas"
-version = "1.4.3"
+version = "1.4.4"
 description = "Powerful data structures for data analysis, time series, and statistics"
 category = "main"
 optional = false
@@ -1521,7 +1542,7 @@ python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7"
 
 [[package]]
 name = "pbr"
-version = "5.9.0"
+version = "5.10.0"
 description = "Python Build Reasonableness"
 category = "main"
 optional = true
@@ -1563,7 +1584,7 @@ name = "pendulum"
 version = "2.1.2"
 description = "Python datetimes made easy"
 category = "main"
-optional = false
+optional = true
 python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
 
 [package.dependencies]
@@ -1572,17 +1593,17 @@ pytzdata = ">=2020.1"
 
 [[package]]
 name = "pep8-naming"
-version = "0.13.1"
+version = "0.13.2"
 description = "Check PEP-8 naming conventions, plugin for flake8"
 category = "main"
 optional = true
-python-versions = "*"
+python-versions = ">=3.7"
 
 [package.dependencies]
 flake8 = ">=3.9.1"
 
 [[package]]
-name = "pillow"
+name = "Pillow"
 version = "9.2.0"
 description = "Python Imaging Library (Fork)"
 category = "dev"
@@ -1593,6 +1614,14 @@ python-versions = ">=3.7"
 docs = ["furo", "olefile", "sphinx (>=2.4)", "sphinx-copybutton", "sphinx-issues (>=3.0.1)", "sphinx-removed-in", "sphinxext-opengraph"]
 tests = ["check-manifest", "coverage", "defusedxml", "markdown2", "olefile", "packaging", "pyroma", "pytest", "pytest-cov", "pytest-timeout"]
 
+[[package]]
+name = "pip"
+version = "22.2.2"
+description = "The PyPA recommended tool for installing Python packages."
+category = "main"
+optional = true
+python-versions = ">=3.7"
+
 [[package]]
 name = "pip-check"
 version = "2.7"
@@ -1602,6 +1631,7 @@ optional = true
 python-versions = ">=3.5"
 
 [package.dependencies]
+pip = ">=9"
 terminaltables = "*"
 
 [[package]]
@@ -1613,8 +1643,8 @@ optional = false
 python-versions = ">=3.7"
 
 [package.extras]
-docs = ["furo (>=2021.7.5b38)", "proselint (>=0.10.2)", "sphinx-autodoc-typehints (>=1.12)", "sphinx (>=4)"]
-test = ["appdirs (==1.4.4)", "pytest-cov (>=2.7)", "pytest-mock (>=3.6)", "pytest (>=6)"]
+docs = ["furo (>=2021.7.5b38)", "proselint (>=0.10.2)", "sphinx (>=4)", "sphinx-autodoc-typehints (>=1.12)"]
+test = ["appdirs (==1.4.4)", "pytest (>=6)", "pytest-cov (>=2.7)", "pytest-mock (>=3.6)"]
 
 [[package]]
 name = "pluggy"
@@ -1625,8 +1655,8 @@ optional = true
 python-versions = ">=3.6"
 
 [package.extras]
-testing = ["pytest-benchmark", "pytest"]
-dev = ["tox", "pre-commit"]
+dev = ["pre-commit", "tox"]
+testing = ["pytest", "pytest-benchmark"]
 
 [[package]]
 name = "pre-commit"
@@ -1646,7 +1676,7 @@ virtualenv = ">=20.0.8"
 
 [[package]]
 name = "prompt-toolkit"
-version = "3.0.30"
+version = "3.0.31"
 description = "Library for building powerful interactive command lines in Python"
 category = "main"
 optional = true
@@ -1673,7 +1703,7 @@ name = "punq"
 version = "0.6.2"
 description = "An IOC Container for Python 3.6+"
 category = "main"
-optional = false
+optional = true
 python-versions = ">=3.6.2,<4.0.0"
 
 [[package]]
@@ -1709,11 +1739,26 @@ typer = ">=0.4.1,<0.7.0"
 
 [[package]]
 name = "pycodestyle"
-version = "2.8.0"
+version = "2.9.1"
 description = "Python style guide checker"
 category = "main"
 optional = true
-python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
+python-versions = ">=3.6"
+
+[[package]]
+name = "pydantic"
+version = "1.10.2"
+description = "Data validation and settings management using python type hints"
+category = "main"
+optional = false
+python-versions = ">=3.7"
+
+[package.dependencies]
+typing-extensions = ">=4.1.0"
+
+[package.extras]
+dotenv = ["python-dotenv (>=0.10.4)"]
+email = ["email-validator (>=1.0.3)"]
 
 [[package]]
 name = "pydocstyle"
@@ -1731,30 +1776,33 @@ toml = ["toml"]
 
 [[package]]
 name = "pyflakes"
-version = "2.4.0"
+version = "2.5.0"
 description = "passive checker of Python programs"
 category = "main"
 optional = true
-python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
+python-versions = ">=3.6"
 
 [[package]]
-name = "pygments"
-version = "2.12.0"
+name = "Pygments"
+version = "2.13.0"
 description = "Pygments is a syntax highlighting package written in Python."
 category = "main"
 optional = true
 python-versions = ">=3.6"
 
+[package.extras]
+plugins = ["importlib-metadata"]
+
 [[package]]
 name = "pylint"
-version = "2.14.5"
+version = "2.15.2"
 description = "python code static checker"
 category = "main"
 optional = true
 python-versions = ">=3.7.2"
 
 [package.dependencies]
-astroid = ">=2.11.6,<=2.12.0-dev0"
+astroid = ">=2.12.9,<=2.14.0-dev0"
 colorama = {version = ">=0.4.5", markers = "sys_platform == \"win32\""}
 dill = ">=0.2"
 isort = ">=4.2.5,<6"
@@ -1788,7 +1836,7 @@ optional = false
 python-versions = ">=3.6.8"
 
 [package.extras]
-diagrams = ["railroad-diagrams", "jinja2"]
+diagrams = ["jinja2", "railroad-diagrams"]
 
 [[package]]
 name = "pyrate-limiter"
@@ -1820,14 +1868,13 @@ python-versions = "*"
 
 [[package]]
 name = "pytest"
-version = "7.1.2"
+version = "7.1.3"
 description = "pytest: simple powerful testing with Python"
 category = "main"
 optional = true
 python-versions = ">=3.7"
 
 [package.dependencies]
-atomicwrites = {version = ">=1.0", markers = "sys_platform == \"win32\""}
 attrs = ">=19.2.0"
 colorama = {version = "*", markers = "sys_platform == \"win32\""}
 iniconfig = "*"
@@ -1934,9 +1981,9 @@ python-versions = ">=3.6"
 pytest = ">=4.0.0"
 
 [package.extras]
-dev = ["nox", "changelogd"]
-docs = ["sphinx", "furo", "sphinxcontrib-napoleon", "sphinx-autodoc-typehints", "changelogd"]
-test = ["pytest (>=4.0)", "coverage", "docutils (>=0.12)", "Pygments (>=2.0)", "pytest-rerunfailures", "pytest-asyncio (>=0.15.1)", "anyio"]
+dev = ["changelogd", "nox"]
+docs = ["changelogd", "furo", "sphinx", "sphinx-autodoc-typehints", "sphinxcontrib-napoleon"]
+test = ["Pygments (>=2.0)", "anyio", "coverage", "docutils (>=0.12)", "pytest (>=4.0)", "pytest-asyncio (>=0.15.1)", "pytest-rerunfailures"]
 
 [[package]]
 name = "pytest-watcher"
@@ -1958,9 +2005,9 @@ optional = false
 python-versions = ">=3.6"
 
 [package.extras]
-pyyaml = ["pyyaml"]
-all = ["ruamel.yaml (>=0.17)", "toml", "msgpack"]
+all = ["msgpack", "ruamel.yaml (>=0.17)", "toml"]
 msgpack = ["msgpack"]
+pyyaml = ["PyYAML"]
 "ruamel.yaml" = ["ruamel.yaml (>=0.17)"]
 toml = ["toml"]
 yaml = ["ruamel.yaml (>=0.17)"]
@@ -1978,7 +2025,7 @@ six = ">=1.5"
 
 [[package]]
 name = "pytz"
-version = "2022.1"
+version = "2022.2.1"
 description = "World timezone definitions, modern and historical"
 category = "main"
 optional = false
@@ -1989,12 +2036,12 @@ name = "pytzdata"
 version = "2020.1"
 description = "The Olson timezone database for Python."
 category = "main"
-optional = false
+optional = true
 python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
 
 [[package]]
 name = "pyupgrade"
-version = "2.37.3"
+version = "2.38.0"
 description = "A tool to automatically upgrade syntax for newer versions."
 category = "main"
 optional = true
@@ -2004,7 +2051,7 @@ python-versions = ">=3.7"
 tokenize-rt = ">=3.2.0"
 
 [[package]]
-name = "pyyaml"
+name = "PyYAML"
 version = "6.0"
 description = "YAML parser and emitter for Python"
 category = "main"
@@ -2012,7 +2059,7 @@ optional = false
 python-versions = ">=3.6"
 
 [[package]]
-name = "pyyaml-env-tag"
+name = "pyyaml_env_tag"
 version = "0.1"
 description = "A custom YAML tag for referencing environment variables in YAML files. "
 category = "main"
@@ -2034,7 +2081,7 @@ python-versions = ">=3.6,<4.0"
 prompt_toolkit = ">=2.0,<4.0"
 
 [package.extras]
-docs = ["Sphinx (>=3.3,<4.0)", "sphinx-rtd-theme (>=0.5.0,<0.6.0)", "sphinx-autobuild (>=2020.9.1,<2021.0.0)", "sphinx-copybutton (>=0.3.1,<0.4.0)", "sphinx-autodoc-typehints (>=1.11.1,<2.0.0)"]
+docs = ["Sphinx (>=3.3,<4.0)", "sphinx-autobuild (>=2020.9.1,<2021.0.0)", "sphinx-autodoc-typehints (>=1.11.1,<2.0.0)", "sphinx-copybutton (>=0.3.1,<0.4.0)", "sphinx-rtd-theme (>=0.5.0,<0.6.0)"]
 
 [[package]]
 name = "radon"
@@ -2094,18 +2141,31 @@ typing-extensions = {version = ">=4.0.0,<5.0", markers = "python_version < \"3.9
 [package.extras]
 jupyter = ["ipywidgets (>=7.5.1,<8.0.0)"]
 
+[[package]]
+name = "setuptools"
+version = "65.3.0"
+description = "Easily download, build, install, upgrade, and uninstall Python packages"
+category = "main"
+optional = false
+python-versions = ">=3.7"
+
+[package.extras]
+docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "rst.linker (>=1.9)", "sphinx", "sphinx-favicon", "sphinx-hoverxref (<2)", "sphinx-inline-tabs", "sphinx-notfound-page (==0.8.3)", "sphinx-reredirects", "sphinxcontrib-towncrier"]
+testing = ["build[virtualenv]", "filelock (>=3.4.0)", "flake8 (<5)", "flake8-2020", "ini2toml[lite] (>=0.9)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "mock", "pip (>=19.1)", "pip-run (>=8.8)", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)", "pytest-perf", "pytest-xdist", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"]
+testing-integration = ["build[virtualenv]", "filelock (>=3.4.0)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pytest", "pytest-enabler", "pytest-xdist", "tomli", "virtualenv (>=13.0.0)", "wheel"]
+
 [[package]]
 name = "setuptools-scm"
-version = "7.0.5"
+version = "6.4.2"
 description = "the blessed package to manage your versions by scm tags"
 category = "main"
 optional = false
-python-versions = ">=3.7"
+python-versions = ">=3.6"
 
 [package.dependencies]
 packaging = ">=20.0"
+setuptools = "*"
 tomli = ">=1.0.0"
-typing-extensions = "*"
 
 [package.extras]
 test = ["pytest (>=6.2)", "virtualenv (>20)"]
@@ -2234,7 +2294,7 @@ python-versions = ">=3.7"
 
 [[package]]
 name = "tomlkit"
-version = "0.11.2"
+version = "0.11.4"
 description = "Style preserving TOML library"
 category = "main"
 optional = true
@@ -2242,7 +2302,7 @@ python-versions = ">=3.6,<4.0"
 
 [[package]]
 name = "transitions"
-version = "0.8.11"
+version = "0.9.0"
 description = "A lightweight, object-oriented Python state machine implementation with many extensions."
 category = "main"
 optional = false
@@ -2267,14 +2327,14 @@ python-versions = ">=3.6"
 click = ">=7.1.1,<9.0.0"
 
 [package.extras]
-test = ["rich (>=10.11.0,<13.0.0)", "isort (>=5.0.6,<6.0.0)", "black (>=22.3.0,<23.0.0)", "mypy (==0.910)", "pytest-sugar (>=0.9.4,<0.10.0)", "pytest-xdist (>=1.32.0,<2.0.0)", "coverage (>=5.2,<6.0)", "pytest-cov (>=2.10.0,<3.0.0)", "pytest (>=4.4.0,<5.4.0)", "shellingham (>=1.3.0,<2.0.0)"]
-doc = ["mdx-include (>=1.4.1,<2.0.0)", "mkdocs-material (>=8.1.4,<9.0.0)", "mkdocs (>=1.1.2,<2.0.0)"]
-dev = ["pre-commit (>=2.17.0,<3.0.0)", "flake8 (>=3.8.3,<4.0.0)", "autoflake (>=1.3.1,<2.0.0)"]
-all = ["rich (>=10.11.0,<13.0.0)", "shellingham (>=1.3.0,<2.0.0)", "colorama (>=0.4.3,<0.5.0)"]
+all = ["colorama (>=0.4.3,<0.5.0)", "rich (>=10.11.0,<13.0.0)", "shellingham (>=1.3.0,<2.0.0)"]
+dev = ["autoflake (>=1.3.1,<2.0.0)", "flake8 (>=3.8.3,<4.0.0)", "pre-commit (>=2.17.0,<3.0.0)"]
+doc = ["mdx-include (>=1.4.1,<2.0.0)", "mkdocs (>=1.1.2,<2.0.0)", "mkdocs-material (>=8.1.4,<9.0.0)"]
+test = ["black (>=22.3.0,<23.0.0)", "coverage (>=5.2,<6.0)", "isort (>=5.0.6,<6.0.0)", "mypy (==0.910)", "pytest (>=4.4.0,<5.4.0)", "pytest-cov (>=2.10.0,<3.0.0)", "pytest-sugar (>=0.9.4,<0.10.0)", "pytest-xdist (>=1.32.0,<2.0.0)", "rich (>=10.11.0,<13.0.0)", "shellingham (>=1.3.0,<2.0.0)"]
 
 [[package]]
 name = "types-setuptools"
-version = "63.4.0"
+version = "65.3.0"
 description = "Typing stubs for setuptools"
 category = "main"
 optional = true
@@ -2290,7 +2350,7 @@ python-versions = ">=3.7"
 
 [[package]]
 name = "typing-inspect"
-version = "0.7.1"
+version = "0.8.0"
 description = "Runtime inspection utilities for typing module."
 category = "main"
 optional = true
@@ -2302,7 +2362,7 @@ typing-extensions = ">=3.7.4"
 
 [[package]]
 name = "ujson"
-version = "5.4.0"
+version = "5.5.0"
 description = "Ultra fast JSON encoder and decoder for Python"
 category = "main"
 optional = true
@@ -2310,20 +2370,20 @@ python-versions = ">=3.7"
 
 [[package]]
 name = "urllib3"
-version = "1.26.11"
+version = "1.26.12"
 description = "HTTP library with thread-safe connection pooling, file post, and more."
 category = "main"
 optional = false
 python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*, <4"
 
 [package.extras]
-brotli = ["brotlicffi (>=0.8.0)", "brotli (>=1.0.9)", "brotlipy (>=0.6.0)"]
-secure = ["pyOpenSSL (>=0.14)", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "certifi", "ipaddress"]
+brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)", "brotlipy (>=0.6.0)"]
+secure = ["certifi", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "ipaddress", "pyOpenSSL (>=0.14)", "urllib3-secure-extra"]
 socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"]
 
 [[package]]
 name = "vcrpy"
-version = "4.2.0"
+version = "4.2.1"
 description = "Automatically mock your HTTP interactions to simplify and speed up testing"
 category = "main"
 optional = true
@@ -2337,7 +2397,7 @@ yarl = "*"
 
 [[package]]
 name = "virtualenv"
-version = "20.16.3"
+version = "20.16.5"
 description = "Virtual Python Environment builder"
 category = "main"
 optional = false
@@ -2424,7 +2484,7 @@ requests = ">=2.0,<3.0"
 
 [[package]]
 name = "yamllint"
-version = "1.27.1"
+version = "1.28.0"
 description = "A linter for YAML files."
 category = "main"
 optional = true
@@ -2433,6 +2493,7 @@ python-versions = ">=3.6"
 [package.dependencies]
 pathspec = ">=0.5.3"
 pyyaml = "*"
+setuptools = "*"
 
 [[package]]
 name = "yarl"
@@ -2455,8 +2516,8 @@ optional = false
 python-versions = ">=3.7"
 
 [package.extras]
-docs = ["sphinx", "jaraco.packaging (>=9)", "rst.linker (>=1.9)", "jaraco.tidelift (>=1.4)"]
-testing = ["pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest-cov", "pytest-enabler (>=1.3)", "jaraco.itertools", "func-timeout", "pytest-black (>=0.3.7)", "pytest-mypy (>=0.9.1)"]
+docs = ["jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx"]
+testing = ["func-timeout", "jaraco.itertools", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)"]
 
 [extras]
 commitizen_legacy = ["cz_legacy"]
@@ -2467,7 +2528,7 @@ test = ["coverage", "diff-cover", "hypothesis", "lxml", "mypy", "nox-poetry", "p
 [metadata]
 lock-version = "1.1"
 python-versions = "^3.8.4"
-content-hash = "996df169550be67492d155bfd9ebbd7cd2edc79cf6b21fdab4b2ca7f5436c7d6"
+content-hash = "8ef38c35d1995442164214f3ee88629bce499586fbdf1da189e523afd28697c5"
 
 [metadata.files]
 absolufy-imports = [
@@ -2482,6 +2543,10 @@ argcomplete = [
     {file = "argcomplete-1.12.3-py2.py3-none-any.whl", hash = "sha256:291f0beca7fd49ce285d2f10e4c1c77e9460cf823eef2de54df0c0fec88b0d81"},
     {file = "argcomplete-1.12.3.tar.gz", hash = "sha256:2c7dbffd8c045ea534921e63b0be6fe65e88599990d8dc408ac8c542b72a5445"},
 ]
+arrow = [
+    {file = "arrow-1.2.3-py3-none-any.whl", hash = "sha256:5a49ab92e3b7b71d96cd6bfcc4df14efefc9dfa96ea19045815914a6ab6b1fe2"},
+    {file = "arrow-1.2.3.tar.gz", hash = "sha256:3934b30ca1b9f292376d9db15b19446088d12ec58629bc3f0da28fd55fb633a1"},
+]
 astor = [
     {file = "astor-0.8.1-py2.py3-none-any.whl", hash = "sha256:070a54e890cefb5b3739d19f30f5a5ec840ffc9c50ffa7d23cc9fc1a38ebbfc5"},
     {file = "astor-0.8.1.tar.gz", hash = "sha256:6a6effda93f4e1ce9f618779b2dd1d9d84f1e32812c23a29b3fff6fd7f63fa5e"},
@@ -2491,15 +2556,12 @@ astpretty = [
     {file = "astpretty-3.0.0.tar.gz", hash = "sha256:b08c95f32e5994454ea99882ff3c4a0afc8254c38998a0ed4b479dba448dc581"},
 ]
 astroid = [
-    {file = "astroid-2.11.7-py3-none-any.whl", hash = "sha256:86b0a340a512c65abf4368b80252754cda17c02cdbbd3f587dddf98112233e7b"},
-    {file = "astroid-2.11.7.tar.gz", hash = "sha256:bb24615c77f4837c707669d16907331374ae8a964650a66999da3f5ca68dc946"},
+    {file = "astroid-2.12.9-py3-none-any.whl", hash = "sha256:27a22f40e45af6d362498647a0940e8ae9c35f71cb572a1b6f8f810122a11918"},
+    {file = "astroid-2.12.9.tar.gz", hash = "sha256:0dafbfcf4ebdecd3c8f6d742c9d9c88508229ca823d5c98ab872d964f3321e56"},
 ]
 asttokens = [
-    {file = "asttokens-2.0.5-py2.py3-none-any.whl", hash = "sha256:0844691e88552595a6f4a4281a9f7f79b8dd45ca4ccea82e5e05b4bbdb76705c"},
-    {file = "asttokens-2.0.5.tar.gz", hash = "sha256:9a54c114f02c7a9480d56550932546a3f1fe71d8a02f1bc7ccd0ee3ee35cf4d5"},
-]
-atomicwrites = [
-    {file = "atomicwrites-1.4.1.tar.gz", hash = "sha256:81b2c9071a49367a7f770170e5eec8cb66567cfbbc8c73d20ce5ca4a8d71cf11"},
+    {file = "asttokens-2.0.8-py2.py3-none-any.whl", hash = "sha256:e3305297c744ae53ffa032c45dc347286165e4ffce6875dc662b205db0623d86"},
+    {file = "asttokens-2.0.8.tar.gz", hash = "sha256:c61e16246ecfb2cde2958406b4c8ebc043c9e6d73aaa83c941673b35e5d3a76b"},
 ]
 attrs = [
     {file = "attrs-21.4.0-py2.py3-none-any.whl", hash = "sha256:2d27e3784d7a565d36ab851fe94887c5eccd6a463168875832a1be79c82828b4"},
@@ -2510,13 +2572,14 @@ attrs-strict = [
     {file = "attrs_strict-1.0.0.tar.gz", hash = "sha256:6326c1e51c4fd2fffc9dd607dec06c31add64eedbd37a651ea88f663a37c3f18"},
 ]
 autoflake = [
-    {file = "autoflake-1.4.tar.gz", hash = "sha256:61a353012cff6ab94ca062823d1fb2f692c4acda51c76ff83a8d77915fba51ea"},
+    {file = "autoflake-1.5.3-py2.py3-none-any.whl", hash = "sha256:90eb8d3f625bd72068eb670338ea7efcddbc5c6e822d3601e3dc9404c06ea8da"},
+    {file = "autoflake-1.5.3.tar.gz", hash = "sha256:44f7d7eb2c1c49505b513c0e93a5dfd3f7b4218283f50c5ca0af4df6b975d470"},
 ]
 autopep8 = [
-    {file = "autopep8-1.6.0-py2.py3-none-any.whl", hash = "sha256:ed77137193bbac52d029a52c59bec1b0629b5a186c495f1eb21b126ac466083f"},
-    {file = "autopep8-1.6.0.tar.gz", hash = "sha256:44f0932855039d2c15c4510d6df665e4730f2b8582704fa48f9c55bd3e17d979"},
+    {file = "autopep8-1.7.0-py2.py3-none-any.whl", hash = "sha256:6f09e90a2be784317e84dc1add17ebfc7abe3924239957a37e5040e27d812087"},
+    {file = "autopep8-1.7.0.tar.gz", hash = "sha256:ca9b1a83e53a7fad65d731dc7a2a2d50aa48f43850407c59f6a1a306c4201142"},
 ]
-babel = [
+Babel = [
     {file = "Babel-2.10.3-py3-none-any.whl", hash = "sha256:ff56f4892c1c4bf0d814575ea23471c230d544203c7748e8c68f0089478d48eb"},
     {file = "Babel-2.10.3.tar.gz", hash = "sha256:7614553711ee97490f732126dc077f8d0ae084ebc6a96e23db1482afabdb2c51"},
 ]
@@ -2538,37 +2601,37 @@ bidict = [
     {file = "bidict-0.22.0.tar.gz", hash = "sha256:5c826b3e15e97cc6e615de295756847c282a79b79c5430d3bfc909b1ac9f5bd8"},
 ]
 black = [
-    {file = "black-22.6.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:f586c26118bc6e714ec58c09df0157fe2d9ee195c764f630eb0d8e7ccce72e69"},
-    {file = "black-22.6.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b270a168d69edb8b7ed32c193ef10fd27844e5c60852039599f9184460ce0807"},
-    {file = "black-22.6.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:6797f58943fceb1c461fb572edbe828d811e719c24e03375fd25170ada53825e"},
-    {file = "black-22.6.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c85928b9d5f83b23cee7d0efcb310172412fbf7cb9d9ce963bd67fd141781def"},
-    {file = "black-22.6.0-cp310-cp310-win_amd64.whl", hash = "sha256:f6fe02afde060bbeef044af7996f335fbe90b039ccf3f5eb8f16df8b20f77666"},
-    {file = "black-22.6.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:cfaf3895a9634e882bf9d2363fed5af8888802d670f58b279b0bece00e9a872d"},
-    {file = "black-22.6.0-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:94783f636bca89f11eb5d50437e8e17fbc6a929a628d82304c80fa9cd945f256"},
-    {file = "black-22.6.0-cp36-cp36m-win_amd64.whl", hash = "sha256:2ea29072e954a4d55a2ff58971b83365eba5d3d357352a07a7a4df0d95f51c78"},
-    {file = "black-22.6.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:e439798f819d49ba1c0bd9664427a05aab79bfba777a6db94fd4e56fae0cb849"},
-    {file = "black-22.6.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:187d96c5e713f441a5829e77120c269b6514418f4513a390b0499b0987f2ff1c"},
-    {file = "black-22.6.0-cp37-cp37m-win_amd64.whl", hash = "sha256:074458dc2f6e0d3dab7928d4417bb6957bb834434516f21514138437accdbe90"},
-    {file = "black-22.6.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:a218d7e5856f91d20f04e931b6f16d15356db1c846ee55f01bac297a705ca24f"},
-    {file = "black-22.6.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:568ac3c465b1c8b34b61cd7a4e349e93f91abf0f9371eda1cf87194663ab684e"},
-    {file = "black-22.6.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:6c1734ab264b8f7929cef8ae5f900b85d579e6cbfde09d7387da8f04771b51c6"},
-    {file = "black-22.6.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c9a3ac16efe9ec7d7381ddebcc022119794872abce99475345c5a61aa18c45ad"},
-    {file = "black-22.6.0-cp38-cp38-win_amd64.whl", hash = "sha256:b9fd45787ba8aa3f5e0a0a98920c1012c884622c6c920dbe98dbd05bc7c70fbf"},
-    {file = "black-22.6.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:7ba9be198ecca5031cd78745780d65a3f75a34b2ff9be5837045dce55db83d1c"},
-    {file = "black-22.6.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:a3db5b6409b96d9bd543323b23ef32a1a2b06416d525d27e0f67e74f1446c8f2"},
-    {file = "black-22.6.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:560558527e52ce8afba936fcce93a7411ab40c7d5fe8c2463e279e843c0328ee"},
-    {file = "black-22.6.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b154e6bbde1e79ea3260c4b40c0b7b3109ffcdf7bc4ebf8859169a6af72cd70b"},
-    {file = "black-22.6.0-cp39-cp39-win_amd64.whl", hash = "sha256:4af5bc0e1f96be5ae9bd7aaec219c901a94d6caa2484c21983d043371c733fc4"},
-    {file = "black-22.6.0-py3-none-any.whl", hash = "sha256:ac609cf8ef5e7115ddd07d85d988d074ed00e10fbc3445aee393e70164a2219c"},
-    {file = "black-22.6.0.tar.gz", hash = "sha256:6c6d39e28aed379aec40da1c65434c77d75e65bb59a1e1c283de545fb4e7c6c9"},
+    {file = "black-22.8.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:ce957f1d6b78a8a231b18e0dd2d94a33d2ba738cd88a7fe64f53f659eea49fdd"},
+    {file = "black-22.8.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:5107ea36b2b61917956d018bd25129baf9ad1125e39324a9b18248d362156a27"},
+    {file = "black-22.8.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e8166b7bfe5dcb56d325385bd1d1e0f635f24aae14b3ae437102dedc0c186747"},
+    {file = "black-22.8.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd82842bb272297503cbec1a2600b6bfb338dae017186f8f215c8958f8acf869"},
+    {file = "black-22.8.0-cp310-cp310-win_amd64.whl", hash = "sha256:d839150f61d09e7217f52917259831fe2b689f5c8e5e32611736351b89bb2a90"},
+    {file = "black-22.8.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:a05da0430bd5ced89176db098567973be52ce175a55677436a271102d7eaa3fe"},
+    {file = "black-22.8.0-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4a098a69a02596e1f2a58a2a1c8d5a05d5a74461af552b371e82f9fa4ada8342"},
+    {file = "black-22.8.0-cp36-cp36m-win_amd64.whl", hash = "sha256:5594efbdc35426e35a7defa1ea1a1cb97c7dbd34c0e49af7fb593a36bd45edab"},
+    {file = "black-22.8.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a983526af1bea1e4cf6768e649990f28ee4f4137266921c2c3cee8116ae42ec3"},
+    {file = "black-22.8.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3b2c25f8dea5e8444bdc6788a2f543e1fb01494e144480bc17f806178378005e"},
+    {file = "black-22.8.0-cp37-cp37m-win_amd64.whl", hash = "sha256:78dd85caaab7c3153054756b9fe8c611efa63d9e7aecfa33e533060cb14b6d16"},
+    {file = "black-22.8.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:cea1b2542d4e2c02c332e83150e41e3ca80dc0fb8de20df3c5e98e242156222c"},
+    {file = "black-22.8.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:5b879eb439094751185d1cfdca43023bc6786bd3c60372462b6f051efa6281a5"},
+    {file = "black-22.8.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:0a12e4e1353819af41df998b02c6742643cfef58282915f781d0e4dd7a200411"},
+    {file = "black-22.8.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c3a73f66b6d5ba7288cd5d6dad9b4c9b43f4e8a4b789a94bf5abfb878c663eb3"},
+    {file = "black-22.8.0-cp38-cp38-win_amd64.whl", hash = "sha256:e981e20ec152dfb3e77418fb616077937378b322d7b26aa1ff87717fb18b4875"},
+    {file = "black-22.8.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:8ce13ffed7e66dda0da3e0b2eb1bdfc83f5812f66e09aca2b0978593ed636b6c"},
+    {file = "black-22.8.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:32a4b17f644fc288c6ee2bafdf5e3b045f4eff84693ac069d87b1a347d861497"},
+    {file = "black-22.8.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:0ad827325a3a634bae88ae7747db1a395d5ee02cf05d9aa7a9bd77dfb10e940c"},
+    {file = "black-22.8.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:53198e28a1fb865e9fe97f88220da2e44df6da82b18833b588b1883b16bb5d41"},
+    {file = "black-22.8.0-cp39-cp39-win_amd64.whl", hash = "sha256:bc4d4123830a2d190e9cc42a2e43570f82ace35c3aeb26a512a2102bce5af7ec"},
+    {file = "black-22.8.0-py3-none-any.whl", hash = "sha256:d2c21d439b2baf7aa80d6dd4e3659259be64c6f49dfd0f32091063db0e006db4"},
+    {file = "black-22.8.0.tar.gz", hash = "sha256:792f7eb540ba9a17e8656538701d3eb1afcb134e3b45b71f20b25c77a8db7e6e"},
 ]
 cement = [
-    {file = "cement-3.0.6-py3-none-any.whl", hash = "sha256:79c9655e68e4393bf8898d28fc806cc5187c1fc493a75f1af396bd30c6170cc4"},
-    {file = "cement-3.0.6.tar.gz", hash = "sha256:fccec41eab3f15a03445b1ce24c8a7e106d4d5520f6507a7145698ce68923d31"},
+    {file = "cement-3.0.8-py3-none-any.whl", hash = "sha256:6bea33b89d3329c405ca4119b7da402b53b7c2c402e98cda371e882d5a2f485e"},
+    {file = "cement-3.0.8.tar.gz", hash = "sha256:ad11a694665e2ad28457c560494f4f8c36a25fc58e500d608a9d91e04e1d3093"},
 ]
 certifi = [
-    {file = "certifi-2022.6.15-py3-none-any.whl", hash = "sha256:fe86415d55e84719d75f8b69414f6438ac3547d2078ab91b67e779ef69378412"},
-    {file = "certifi-2022.6.15.tar.gz", hash = "sha256:84c85a9078b11105f04f3036a9482ae10e4621616db313fe045dd24743a0820d"},
+    {file = "certifi-2022.9.14-py3-none-any.whl", hash = "sha256:e232343de1ab72c2aa521b625c80f699e356830fd0e2c620b465b304b17b0516"},
+    {file = "certifi-2022.9.14.tar.gz", hash = "sha256:36973885b9542e6bd01dea287b2b4b3b21236307c56324fcc3f1160f2d655ed5"},
 ]
 cfgv = [
     {file = "cfgv-3.3.1-py2.py3-none-any.whl", hash = "sha256:c6a0883f3917a037485059700b9e75da2464e6c27051014ad85ba6aaa5884426"},
@@ -2579,19 +2642,19 @@ chardet = [
     {file = "chardet-5.0.0.tar.gz", hash = "sha256:0368df2bfd78b5fc20572bb4e9bb7fb53e2c094f60ae9993339e8671d0afb8aa"},
 ]
 charset-normalizer = [
-    {file = "charset-normalizer-2.1.0.tar.gz", hash = "sha256:575e708016ff3a5e3681541cb9d79312c416835686d054a23accb873b254f413"},
-    {file = "charset_normalizer-2.1.0-py3-none-any.whl", hash = "sha256:5189b6f22b01957427f35b6a08d9a0bc45b46d3788ef5a92e978433c7a35f8a5"},
+    {file = "charset-normalizer-2.1.1.tar.gz", hash = "sha256:5a3d016c7c547f69d6f81fb0db9449ce888b418b5b9952cc5e6e66843e9dd845"},
+    {file = "charset_normalizer-2.1.1-py3-none-any.whl", hash = "sha256:83e9a75d1911279afd89352c68b45348559d1fc0506b054b346651b5e7fee29f"},
 ]
 click = [
     {file = "click-8.1.3-py3-none-any.whl", hash = "sha256:bb4d8133cb15a609f44e8213d9b391b0809795062913b383c62be0ee95b1db48"},
     {file = "click-8.1.3.tar.gz", hash = "sha256:7682dc8afb30297001674575ea00d1814d808d6a36af415a82bd481d37ba7b8e"},
 ]
 cloudpickle = [
-    {file = "cloudpickle-2.1.0-py3-none-any.whl", hash = "sha256:b5c434f75c34624eedad3a14f2be5ac3b5384774d5b0e3caf905c21479e6c4b1"},
-    {file = "cloudpickle-2.1.0.tar.gz", hash = "sha256:bb233e876a58491d9590a676f93c7a5473a08f747d5ab9df7f9ce564b3e7938e"},
+    {file = "cloudpickle-2.2.0-py3-none-any.whl", hash = "sha256:7428798d5926d8fcbfd092d18d01a2a03daf8237d8fcdc8095d256b8490796f0"},
+    {file = "cloudpickle-2.2.0.tar.gz", hash = "sha256:3f4219469c55453cfe4737e564b67c2a149109dabf7f242478948b895f61106f"},
 ]
 cognitive-complexity = [
-    {file = "cognitive_complexity-1.2.0.tar.gz", hash = "sha256:3c2b433a9e41502932f6aa629e1f57a5e8f145956c54facbb5241a9492af6fb7"},
+    {file = "cognitive_complexity-1.3.0.tar.gz", hash = "sha256:a0cfbd47dee0b19f4056f892389f501694b205c3af69fb703cc744541e03dde5"},
 ]
 cohesion = [
     {file = "cohesion-1.0.0-py2.py3-none-any.whl", hash = "sha256:a33a526eb8922c7dbfef19257b3532d16e6246c4ece3ab3b492b290d9d3f2d4b"},
@@ -2601,59 +2664,68 @@ colorama = [
     {file = "colorama-0.4.5.tar.gz", hash = "sha256:e6c6b4334fc50988a639d9b98aa429a0b57da6e17b9a44f0451f930b6967b7a4"},
 ]
 colorlog = [
-    {file = "colorlog-6.6.0-py2.py3-none-any.whl", hash = "sha256:351c51e866c86c3217f08e4b067a7974a678be78f07f85fc2d55b8babde6d94e"},
-    {file = "colorlog-6.6.0.tar.gz", hash = "sha256:344f73204009e4c83c5b6beb00b3c45dc70fcdae3c80db919e0a4171d006fde8"},
+    {file = "colorlog-6.7.0-py2.py3-none-any.whl", hash = "sha256:0d33ca236784a1ba3ff9c532d4964126d8a2c44f1f0cb1d2b0728196f512f662"},
+    {file = "colorlog-6.7.0.tar.gz", hash = "sha256:bd94bd21c1e13fac7bd3153f4bc3a7dc0eb0974b8bc2fdf1a989e474f6e582e5"},
 ]
 commitizen = [
-    {file = "commitizen-2.29.5-py3-none-any.whl", hash = "sha256:07f1708232dd14a839af82df62fcd53e0adb5b807cc55f4faab6c86b9a63ef12"},
-    {file = "commitizen-2.29.5.tar.gz", hash = "sha256:a6ab0b9f6cffbc49b2a4d2b940cbcc1715a9373f04604653a64677ef20a6ba7f"},
+    {file = "commitizen-2.33.0-py3-none-any.whl", hash = "sha256:cddc897537d523aaef583ab3d1b694a50d8178790c899b773e5013270deb7a2c"},
+    {file = "commitizen-2.33.0.tar.gz", hash = "sha256:dbbef5518402343fd2f1ac689f5754f85f94a4bf59b06af663d04ca113e66d92"},
 ]
 commonmark = [
     {file = "commonmark-0.9.1-py2.py3-none-any.whl", hash = "sha256:da2f38c92590f83de410ba1a3cbceafbc74fee9def35f9251ba9a971d6d66fd9"},
     {file = "commonmark-0.9.1.tar.gz", hash = "sha256:452f9dc859be7f06631ddcb328b6919c67984aca654e5fefb3914d54691aed60"},
 ]
 coverage = [
-    {file = "coverage-6.4.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:f50d3a822947572496ea922ee7825becd8e3ae6fbd2400cd8236b7d64b17f285"},
-    {file = "coverage-6.4.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:d5191d53afbe5b6059895fa7f58223d3751c42b8101fb3ce767e1a0b1a1d8f87"},
-    {file = "coverage-6.4.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:04010af3c06ce2bfeb3b1e4e05d136f88d88c25f76cd4faff5d1fd84d11581ea"},
-    {file = "coverage-6.4.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6630d8d943644ea62132789940ca97d05fac83f73186eaf0930ffa715fbdab6b"},
-    {file = "coverage-6.4.3-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:05de0762c1caed4a162b3e305f36cf20a548ff4da0be6766ad5c870704be3660"},
-    {file = "coverage-6.4.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:0e3a41aad5919613483aad9ebd53336905cab1bd6788afd3995c2a972d89d795"},
-    {file = "coverage-6.4.3-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:a2738ba1ee544d6f294278cfb6de2dc1f9a737a780469b5366e662a218f806c3"},
-    {file = "coverage-6.4.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:a0d2df4227f645a879010461df2cea6b7e3fb5a97d7eafa210f7fb60345af9e8"},
-    {file = "coverage-6.4.3-cp310-cp310-win32.whl", hash = "sha256:73a10939dc345460ca0655356a470dd3de9759919186a82383c87b6eb315faf2"},
-    {file = "coverage-6.4.3-cp310-cp310-win_amd64.whl", hash = "sha256:53c8edd3b83a4ddba3d8c506f1359401e7770b30f2188f15c17a338adf5a14db"},
-    {file = "coverage-6.4.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:f1eda5cae434282712e40b42aaf590b773382afc3642786ac3ed39053973f61f"},
-    {file = "coverage-6.4.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:59fc88bc13e30f25167e807b8cad3c41b7218ef4473a20c86fd98a7968733083"},
-    {file = "coverage-6.4.3-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d75314b00825d70e1e34b07396e23f47ed1d4feedc0122748f9f6bd31a544840"},
-    {file = "coverage-6.4.3-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:52f8b9fcf3c5e427d51bbab1fb92b575a9a9235d516f175b24712bcd4b5be917"},
-    {file = "coverage-6.4.3-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:5a559aab40c716de80c7212295d0dc96bc1b6c719371c20dd18c5187c3155518"},
-    {file = "coverage-6.4.3-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:306788fd019bb90e9cbb83d3f3c6becad1c048dd432af24f8320cf38ac085684"},
-    {file = "coverage-6.4.3-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:920a734fe3d311ca01883b4a19aa386c97b82b69fbc023458899cff0a0d621b9"},
-    {file = "coverage-6.4.3-cp37-cp37m-win32.whl", hash = "sha256:ab9ef0187d6c62b09dec83a84a3b94f71f9690784c84fd762fb3cf2d2b44c914"},
-    {file = "coverage-6.4.3-cp37-cp37m-win_amd64.whl", hash = "sha256:39ebd8e120cb77a06ee3d5fc26f9732670d1c397d7cd3acf02f6f62693b89b80"},
-    {file = "coverage-6.4.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:bc698580216050b5f4a34d2cdd2838b429c53314f1c4835fab7338200a8396f2"},
-    {file = "coverage-6.4.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:877ee5478fd78e100362aed56db47ccc5f23f6e7bb035a8896855f4c3e49bc9b"},
-    {file = "coverage-6.4.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:555a498999c44f5287cc95500486cd0d4f021af9162982cbe504d4cb388f73b5"},
-    {file = "coverage-6.4.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eff095a5aac7011fdb51a2c82a8fae9ec5211577f4b764e1e59cfa27ceeb1b59"},
-    {file = "coverage-6.4.3-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5de1e9335e2569974e20df0ce31493d315a830d7987e71a24a2a335a8d8459d3"},
-    {file = "coverage-6.4.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:7856ea39059d75f822ff0df3a51ea6d76307c897048bdec3aad1377e4e9dca20"},
-    {file = "coverage-6.4.3-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:411fdd9f4203afd93b056c0868c8f9e5e16813e765de962f27e4e5798356a052"},
-    {file = "coverage-6.4.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:cdf7b83f04a313a21afb1f8730fe4dd09577fefc53bbdfececf78b2006f4268e"},
-    {file = "coverage-6.4.3-cp38-cp38-win32.whl", hash = "sha256:ab2b1a89d2bc7647622e9eaf06128a5b5451dccf7c242deaa31420b055716481"},
-    {file = "coverage-6.4.3-cp38-cp38-win_amd64.whl", hash = "sha256:0e34247274bde982bbc613894d33f9e36358179db2ed231dd101c48dd298e7b0"},
-    {file = "coverage-6.4.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:b104b6b1827d6a22483c469e3983a204bcf9c6bf7544bf90362c4654ebc2edf3"},
-    {file = "coverage-6.4.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:adf1a0d272633b21d645dd6e02e3293429c1141c7d65a58e4cbcd592d53b8e01"},
-    {file = "coverage-6.4.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ff9832434a9193fbd716fbe05f9276484e18d26cc4cf850853594bb322807ac3"},
-    {file = "coverage-6.4.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:923f9084d7e1d31b5f74c92396b05b18921ed01ee5350402b561a79dce3ea48d"},
-    {file = "coverage-6.4.3-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e4d64304acf79766e650f7acb81d263a3ea6e2d0d04c5172b7189180ff2c023c"},
-    {file = "coverage-6.4.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:fc294de50941d3da66a09dca06e206297709332050973eca17040278cb0918ff"},
-    {file = "coverage-6.4.3-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:a42eaaae772f14a5194f181740a67bfd48e8806394b8c67aa4399e09d0d6b5db"},
-    {file = "coverage-6.4.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:4822327b35cb032ff16af3bec27f73985448f08e874146b5b101e0e558b613dd"},
-    {file = "coverage-6.4.3-cp39-cp39-win32.whl", hash = "sha256:f217850ac0e046ede611312703423767ca032a7b952b5257efac963942c055de"},
-    {file = "coverage-6.4.3-cp39-cp39-win_amd64.whl", hash = "sha256:0a84376e4fd13cebce2c0ef8c2f037929c8307fb94af1e5dbe50272a1c651b5d"},
-    {file = "coverage-6.4.3-pp36.pp37.pp38-none-any.whl", hash = "sha256:068d6f2a893af838291b8809c876973d885543411ea460f3e6886ac0ee941732"},
-    {file = "coverage-6.4.3.tar.gz", hash = "sha256:ec2ae1f398e5aca655b7084392d23e80efb31f7a660d2eecf569fb9f79b3fb94"},
+    {file = "coverage-6.4.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e7b4da9bafad21ea45a714d3ea6f3e1679099e420c8741c74905b92ee9bfa7cc"},
+    {file = "coverage-6.4.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:fde17bc42e0716c94bf19d92e4c9f5a00c5feb401f5bc01101fdf2a8b7cacf60"},
+    {file = "coverage-6.4.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cdbb0d89923c80dbd435b9cf8bba0ff55585a3cdb28cbec65f376c041472c60d"},
+    {file = "coverage-6.4.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:67f9346aeebea54e845d29b487eb38ec95f2ecf3558a3cffb26ee3f0dcc3e760"},
+    {file = "coverage-6.4.4-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:42c499c14efd858b98c4e03595bf914089b98400d30789511577aa44607a1b74"},
+    {file = "coverage-6.4.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:c35cca192ba700979d20ac43024a82b9b32a60da2f983bec6c0f5b84aead635c"},
+    {file = "coverage-6.4.4-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:9cc4f107009bca5a81caef2fca843dbec4215c05e917a59dec0c8db5cff1d2aa"},
+    {file = "coverage-6.4.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:5f444627b3664b80d078c05fe6a850dd711beeb90d26731f11d492dcbadb6973"},
+    {file = "coverage-6.4.4-cp310-cp310-win32.whl", hash = "sha256:66e6df3ac4659a435677d8cd40e8eb1ac7219345d27c41145991ee9bf4b806a0"},
+    {file = "coverage-6.4.4-cp310-cp310-win_amd64.whl", hash = "sha256:35ef1f8d8a7a275aa7410d2f2c60fa6443f4a64fae9be671ec0696a68525b875"},
+    {file = "coverage-6.4.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c1328d0c2f194ffda30a45f11058c02410e679456276bfa0bbe0b0ee87225fac"},
+    {file = "coverage-6.4.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:61b993f3998ee384935ee423c3d40894e93277f12482f6e777642a0141f55782"},
+    {file = "coverage-6.4.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d5dd4b8e9cd0deb60e6fcc7b0647cbc1da6c33b9e786f9c79721fd303994832f"},
+    {file = "coverage-6.4.4-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7026f5afe0d1a933685d8f2169d7c2d2e624f6255fb584ca99ccca8c0e966fd7"},
+    {file = "coverage-6.4.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:9c7b9b498eb0c0d48b4c2abc0e10c2d78912203f972e0e63e3c9dc21f15abdaa"},
+    {file = "coverage-6.4.4-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:ee2b2fb6eb4ace35805f434e0f6409444e1466a47f620d1d5763a22600f0f892"},
+    {file = "coverage-6.4.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:ab066f5ab67059d1f1000b5e1aa8bbd75b6ed1fc0014559aea41a9eb66fc2ce0"},
+    {file = "coverage-6.4.4-cp311-cp311-win32.whl", hash = "sha256:9d6e1f3185cbfd3d91ac77ea065d85d5215d3dfa45b191d14ddfcd952fa53796"},
+    {file = "coverage-6.4.4-cp311-cp311-win_amd64.whl", hash = "sha256:e3d3c4cc38b2882f9a15bafd30aec079582b819bec1b8afdbde8f7797008108a"},
+    {file = "coverage-6.4.4-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a095aa0a996ea08b10580908e88fbaf81ecf798e923bbe64fb98d1807db3d68a"},
+    {file = "coverage-6.4.4-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ef6f44409ab02e202b31a05dd6666797f9de2aa2b4b3534e9d450e42dea5e817"},
+    {file = "coverage-6.4.4-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4b7101938584d67e6f45f0015b60e24a95bf8dea19836b1709a80342e01b472f"},
+    {file = "coverage-6.4.4-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:14a32ec68d721c3d714d9b105c7acf8e0f8a4f4734c811eda75ff3718570b5e3"},
+    {file = "coverage-6.4.4-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:6a864733b22d3081749450466ac80698fe39c91cb6849b2ef8752fd7482011f3"},
+    {file = "coverage-6.4.4-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:08002f9251f51afdcc5e3adf5d5d66bb490ae893d9e21359b085f0e03390a820"},
+    {file = "coverage-6.4.4-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:a3b2752de32c455f2521a51bd3ffb53c5b3ae92736afde67ce83477f5c1dd928"},
+    {file = "coverage-6.4.4-cp37-cp37m-win32.whl", hash = "sha256:f855b39e4f75abd0dfbcf74a82e84ae3fc260d523fcb3532786bcbbcb158322c"},
+    {file = "coverage-6.4.4-cp37-cp37m-win_amd64.whl", hash = "sha256:ee6ae6bbcac0786807295e9687169fba80cb0617852b2fa118a99667e8e6815d"},
+    {file = "coverage-6.4.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:564cd0f5b5470094df06fab676c6d77547abfdcb09b6c29c8a97c41ad03b103c"},
+    {file = "coverage-6.4.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:cbbb0e4cd8ddcd5ef47641cfac97d8473ab6b132dd9a46bacb18872828031685"},
+    {file = "coverage-6.4.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6113e4df2fa73b80f77663445be6d567913fb3b82a86ceb64e44ae0e4b695de1"},
+    {file = "coverage-6.4.4-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8d032bfc562a52318ae05047a6eb801ff31ccee172dc0d2504614e911d8fa83e"},
+    {file = "coverage-6.4.4-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e431e305a1f3126477abe9a184624a85308da8edf8486a863601d58419d26ffa"},
+    {file = "coverage-6.4.4-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:cf2afe83a53f77aec067033199797832617890e15bed42f4a1a93ea24794ae3e"},
+    {file = "coverage-6.4.4-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:783bc7c4ee524039ca13b6d9b4186a67f8e63d91342c713e88c1865a38d0892a"},
+    {file = "coverage-6.4.4-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:ff934ced84054b9018665ca3967fc48e1ac99e811f6cc99ea65978e1d384454b"},
+    {file = "coverage-6.4.4-cp38-cp38-win32.whl", hash = "sha256:e1fabd473566fce2cf18ea41171d92814e4ef1495e04471786cbc943b89a3781"},
+    {file = "coverage-6.4.4-cp38-cp38-win_amd64.whl", hash = "sha256:4179502f210ebed3ccfe2f78bf8e2d59e50b297b598b100d6c6e3341053066a2"},
+    {file = "coverage-6.4.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:98c0b9e9b572893cdb0a00e66cf961a238f8d870d4e1dc8e679eb8bdc2eb1b86"},
+    {file = "coverage-6.4.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:fc600f6ec19b273da1d85817eda339fb46ce9eef3e89f220055d8696e0a06908"},
+    {file = "coverage-6.4.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7a98d6bf6d4ca5c07a600c7b4e0c5350cd483c85c736c522b786be90ea5bac4f"},
+    {file = "coverage-6.4.4-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:01778769097dbd705a24e221f42be885c544bb91251747a8a3efdec6eb4788f2"},
+    {file = "coverage-6.4.4-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dfa0b97eb904255e2ab24166071b27408f1f69c8fbda58e9c0972804851e0558"},
+    {file = "coverage-6.4.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:fcbe3d9a53e013f8ab88734d7e517eb2cd06b7e689bedf22c0eb68db5e4a0a19"},
+    {file = "coverage-6.4.4-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:15e38d853ee224e92ccc9a851457fb1e1f12d7a5df5ae44544ce7863691c7a0d"},
+    {file = "coverage-6.4.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:6913dddee2deff8ab2512639c5168c3e80b3ebb0f818fed22048ee46f735351a"},
+    {file = "coverage-6.4.4-cp39-cp39-win32.whl", hash = "sha256:354df19fefd03b9a13132fa6643527ef7905712109d9c1c1903f2133d3a4e145"},
+    {file = "coverage-6.4.4-cp39-cp39-win_amd64.whl", hash = "sha256:1238b08f3576201ebf41f7c20bf59baa0d05da941b123c6656e42cdb668e9827"},
+    {file = "coverage-6.4.4-pp36.pp37.pp38-none-any.whl", hash = "sha256:f67cf9f406cf0d2f08a3515ce2db5b82625a7257f88aad87904674def6ddaec1"},
+    {file = "coverage-6.4.4.tar.gz", hash = "sha256:e16c45b726acb780e1e6f88b286d3c10b3914ab03438f32117c4aa52d7f30d58"},
 ]
 cycler = [
     {file = "cycler-0.11.0-py3-none-any.whl", hash = "sha256:3a27e95f763a428a739d2add979fa7494c912a32c17c4c38c4d5f082cad165a3"},
@@ -2688,11 +2760,11 @@ dill = [
     {file = "dill-0.3.5.1.tar.gz", hash = "sha256:d75e41f3eff1eee599d738e76ba8f4ad98ea229db8b085318aa2b3333a208c86"},
 ]
 distlib = [
-    {file = "distlib-0.3.5-py2.py3-none-any.whl", hash = "sha256:b710088c59f06338ca514800ad795a132da19fda270e3ce4affc74abf955a26c"},
-    {file = "distlib-0.3.5.tar.gz", hash = "sha256:a7f75737c70be3b25e2bee06288cec4e4c221de18455b2dd037fe2a795cab2fe"},
+    {file = "distlib-0.3.6-py2.py3-none-any.whl", hash = "sha256:f35c4b692542ca110de7ef0bea44d73981caeb34ca0b9b6b2e6d7790dda8f80e"},
+    {file = "distlib-0.3.6.tar.gz", hash = "sha256:14bad2d9b04d3a36127ac97f30b12a19268f211063d8f8ee4f47108896e11b46"},
 ]
 dlint = [
-    {file = "dlint-0.12.0-py3-none-any.whl", hash = "sha256:344823d299439aa94fe276b2b3b90733026787d25713c664e137cf5f7d0645f7"},
+    {file = "dlint-0.13.0-py3-none-any.whl", hash = "sha256:72094f35711a338eed4b8f95cbbaade5ec1d784bec516933bdbc2863676c4298"},
 ]
 docstring-parser = [
     {file = "docstring_parser-0.7.3.tar.gz", hash = "sha256:cde5fbf8b846433dfbde1e0f96b7f909336a634d5df34a38cb75050c7346734a"},
@@ -2706,8 +2778,8 @@ eradicate = [
     {file = "eradicate-2.1.0.tar.gz", hash = "sha256:aac7384ab25b1bf21c4c012de9b4bf8398945a14c98c911545b2ea50ab558014"},
 ]
 exceptiongroup = [
-    {file = "exceptiongroup-1.0.0rc8-py3-none-any.whl", hash = "sha256:ab0a968e1ef769e55d9a596f4a89f7be9ffedbc9fdefdb77cc68cf5c33ce1035"},
-    {file = "exceptiongroup-1.0.0rc8.tar.gz", hash = "sha256:6990c24f06b8d33c8065cfe43e5e8a4bfa384e0358be036af9cc60b6321bd11a"},
+    {file = "exceptiongroup-1.0.0rc9-py3-none-any.whl", hash = "sha256:2e3c3fc1538a094aab74fad52d6c33fc94de3dfee3ee01f187c0e0c72aec5337"},
+    {file = "exceptiongroup-1.0.0rc9.tar.gz", hash = "sha256:9086a4a21ef9b31c72181c77c040a074ba0889ee56a7b289ff0afb0d97655f96"},
 ]
 falcon = [
     {file = "falcon-2.0.0-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:733033ec80c896e30a43ab3e776856096836787197a44eb21022320a61311983"},
@@ -2734,16 +2806,16 @@ fhconfparser = [
     {file = "fhconfparser-2022.tar.gz", hash = "sha256:6d35be95f88dc874ab6c984fdc22f52c61092fe422671f3417fb55139668206b"},
 ]
 filelock = [
-    {file = "filelock-3.7.1-py3-none-any.whl", hash = "sha256:37def7b658813cda163b56fc564cdc75e86d338246458c4c28ae84cabefa2404"},
-    {file = "filelock-3.7.1.tar.gz", hash = "sha256:3a0fd85166ad9dbab54c9aec96737b744106dc5f15c0b09a6744a445299fcf04"},
+    {file = "filelock-3.8.0-py3-none-any.whl", hash = "sha256:617eb4e5eedc82fc5f47b6d61e4d11cb837c56cb4544e39081099fa17ad109d4"},
+    {file = "filelock-3.8.0.tar.gz", hash = "sha256:55447caa666f2198c5b6b13a26d2084d26fa5b115c00d065664b2124680c4edc"},
 ]
 flake8 = [
-    {file = "flake8-4.0.1-py2.py3-none-any.whl", hash = "sha256:479b1304f72536a55948cb40a32dce8bb0ffe3501e26eaf292c7e60eb5e0428d"},
-    {file = "flake8-4.0.1.tar.gz", hash = "sha256:806e034dda44114815e23c16ef92f95c91e4c71100ff52813adf7132a6ad870d"},
+    {file = "flake8-5.0.4-py2.py3-none-any.whl", hash = "sha256:7a1cf6b73744f5806ab95e526f6f0d8c01c66d7bbe349562d22dfca20610b248"},
+    {file = "flake8-5.0.4.tar.gz", hash = "sha256:6fbe320aad8d6b95cec8b8e47bc933004678dc63095be98528b7bdd2a9f510db"},
 ]
 flake8-2020 = [
-    {file = "flake8_2020-1.6.1-py2.py3-none-any.whl", hash = "sha256:efcc056fb723e1ea5307e3b663c7c328f1c23a5ff0a0fd3be695a918d8245c3a"},
-    {file = "flake8_2020-1.6.1.tar.gz", hash = "sha256:db523e3383befc17c895219551ff6c9b2f6e0a5cae4c7739ea65a2238bdc6f74"},
+    {file = "flake8_2020-1.7.0-py2.py3-none-any.whl", hash = "sha256:e3e89e2fd4077c66ac8b8739e2af7c791258ba4023037e401f825284435c7dbb"},
+    {file = "flake8_2020-1.7.0.tar.gz", hash = "sha256:9342902563a7d0b0233128c395be1372b8a3e8072805931639760bfe8a3935f9"},
 ]
 flake8-aaa = [
     {file = "flake8-aaa-0.12.2.tar.gz", hash = "sha256:38b5009248d8bc1e9568c8cc6f00870582f0e6b1be168d2f880a404796029e83"},
@@ -2758,8 +2830,8 @@ flake8-assertive = [
     {file = "flake8_assertive-2.1.0-py3-none-any.whl", hash = "sha256:dc0c561010b2c00f7314f7fbf3b3de302efb24154316deb338d07e083fa30b26"},
 ]
 flake8-bandit = [
-    {file = "flake8_bandit-3.0.0-py2.py3-none-any.whl", hash = "sha256:61b617f4f7cdaa0e2b1e6bf7b68afb2b619a227bb3e3ae00dd36c213bd17900a"},
-    {file = "flake8_bandit-3.0.0.tar.gz", hash = "sha256:54d19427e6a8d50322a7b02e1841c0a7c22d856975f3459803320e0e18e2d6a1"},
+    {file = "flake8_bandit-4.1.1-py3-none-any.whl", hash = "sha256:4c8a53eb48f23d4ef1e59293657181a3c989d0077c9952717e98a0eace43e06d"},
+    {file = "flake8_bandit-4.1.1.tar.gz", hash = "sha256:068e09287189cbfd7f986e92605adea2067630b75380c6b5733dab7d87f9a84e"},
 ]
 flake8-blind-except = [
     {file = "flake8-blind-except-0.2.1.tar.gz", hash = "sha256:f25a575a9dcb3eeb3c760bf9c22db60b8b5a23120224ed1faa9a43f75dd7dd16"},
@@ -2769,12 +2841,12 @@ flake8-breakpoint = [
     {file = "flake8_breakpoint-1.1.0-py3-none-any.whl", hash = "sha256:27e0cb132647f9ef348b4a3c3126e7350bedbb22e8e221cd11712a223855ea0b"},
 ]
 flake8-broken-line = [
-    {file = "flake8-broken-line-0.4.0.tar.gz", hash = "sha256:771aab5aa0997666796fed249d0e48e6c01cdfeca8c95521eea28a38b7ced4c7"},
-    {file = "flake8_broken_line-0.4.0-py3-none-any.whl", hash = "sha256:e9c522856862239a2c7ef2c1de0276fa598572aa864bd4e9c7efc2a827538515"},
+    {file = "flake8-broken-line-0.5.0.tar.gz", hash = "sha256:7c98de9dd1385b71e888709c7f2aee3f0514107ecb5875bc95d0c03392191c97"},
+    {file = "flake8_broken_line-0.5.0-py3-none-any.whl", hash = "sha256:daafb19b67eead0410ce7ba155d51a15b9d020ebe7630d87de9c2b93cedb6703"},
 ]
 flake8-bugbear = [
-    {file = "flake8-bugbear-22.7.1.tar.gz", hash = "sha256:e450976a07e4f9d6c043d4f72b17ec1baf717fe37f7997009c8ae58064f88305"},
-    {file = "flake8_bugbear-22.7.1-py3-none-any.whl", hash = "sha256:db5d7a831ef4412a224b26c708967ff816818cabae415e76b8c58df156c4b8e5"},
+    {file = "flake8-bugbear-22.9.11.tar.gz", hash = "sha256:39236c0e97160d1ab05d9f87422173d16e925a6220b3635bfc4aee766bf8194a"},
+    {file = "flake8_bugbear-22.9.11-py3-none-any.whl", hash = "sha256:e74350a4cfc670e184f3433c223b1e7378f1cf8345ded6c8f12ac1a50c5df22b"},
 ]
 flake8-builtins = [
     {file = "flake8-builtins-1.5.3.tar.gz", hash = "sha256:09998853b2405e98e61d2ff3027c47033adbdc17f9fe44ca58443d876eb00f3b"},
@@ -2796,8 +2868,8 @@ flake8-docstrings = [
     {file = "flake8_docstrings-1.6.0-py2.py3-none-any.whl", hash = "sha256:99cac583d6c7e32dd28bbfbef120a7c0d1b6dde4adb5a9fd441c4227a6534bde"},
 ]
 flake8-eradicate = [
-    {file = "flake8-eradicate-1.2.1.tar.gz", hash = "sha256:e486f8ab7e2dba3667223688e9239158fbf4ecaa88125e2283bcda81171412b7"},
-    {file = "flake8_eradicate-1.2.1-py3-none-any.whl", hash = "sha256:00d77faefb64cef18b3c1b48a004c3a2ad663aa3cf85650f422437d25ece6441"},
+    {file = "flake8-eradicate-1.3.0.tar.gz", hash = "sha256:e4c98f00d17dc8653e3388cac2624cd81e9735de2fd4a8dcf99029633ebd7a63"},
+    {file = "flake8_eradicate-1.3.0-py3-none-any.whl", hash = "sha256:85a71e0c5f4e07f7c6c5fec520483561fd6bd295417d622855bdeade99242e3d"},
 ]
 flake8-expression-complexity = [
     {file = "flake8_expression_complexity-0.0.11-py3-none-any.whl", hash = "sha256:b56bac37f7dd5d3d102a7111c89f6579c2cbd897b868147794c9ed12aadc627c"},
@@ -2816,11 +2888,11 @@ flake8-isort = [
     {file = "flake8_isort-4.2.0-py3-none-any.whl", hash = "sha256:5b87630fb3719bf4c1833fd11e0d9534f43efdeba524863e15d8f14a7ef6adbf"},
 ]
 flake8-logging-format = [
-    {file = "flake8-logging-format-0.6.0.tar.gz", hash = "sha256:ca5f2b7fc31c3474a0aa77d227e022890f641a025f0ba664418797d979a779f8"},
+    {file = "flake8-logging-format-0.7.5.tar.gz", hash = "sha256:54f7e349c934ce5c594f251885bc2240e99f6b48752a672a8fc7e3d1388352bb"},
 ]
 flake8-markdown = [
-    {file = "flake8-markdown-0.3.0.tar.gz", hash = "sha256:5b54f143c9568da11a9d74ce5e580e96685fe758a14933f140c6d7006041fafd"},
-    {file = "flake8_markdown-0.3.0-py3-none-any.whl", hash = "sha256:122705b8b26b1523c5a225a728743393d254394e142680e4af17f930cdd87386"},
+    {file = "flake8-markdown-0.4.0.tar.gz", hash = "sha256:c1d1f2c5055df2d6af22597aca401e6693a3d1389d06d2105272cb80478e686c"},
+    {file = "flake8_markdown-0.4.0-py3-none-any.whl", hash = "sha256:d03dfd75605e7346416de0adaedfbfa0f50833a1f8a3aec634065a577f90a950"},
 ]
 flake8-pep3101 = [
     {file = "flake8-pep3101-1.3.0.tar.gz", hash = "sha256:86e3eb4e42de8326dcd98ebdeaf9a3c6854203a48f34aeb3e7e8ed948107f512"},
@@ -2834,10 +2906,6 @@ flake8-plugin-utils = [
     {file = "flake8-plugin-utils-1.3.2.tar.gz", hash = "sha256:20fa2a8ca2decac50116edb42e6af0a1253ef639ad79941249b840531889c65a"},
     {file = "flake8_plugin_utils-1.3.2-py3-none-any.whl", hash = "sha256:1fe43e3e9acf3a7c0f6b88f5338cad37044d2f156c43cb6b080b5f9da8a76f06"},
 ]
-flake8-polyfill = [
-    {file = "flake8-polyfill-1.0.2.tar.gz", hash = "sha256:e44b087597f6da52ec6393a709e7108b2905317d0c0b744cdca6208e670d8eda"},
-    {file = "flake8_polyfill-1.0.2-py2.py3-none-any.whl", hash = "sha256:12be6a34ee3ab795b19ca73505e7b55826d5f6ad7230d31b18e106400169b9e9"},
-]
 flake8-print = [
     {file = "flake8-print-5.0.0.tar.gz", hash = "sha256:76915a2a389cc1c0879636c219eb909c38501d3a43cc8dae542081c9ba48bdf9"},
     {file = "flake8_print-5.0.0-py3-none-any.whl", hash = "sha256:84a1a6ea10d7056b804221ac5e62b1cee1aefc897ce16f2e5c42d3046068f5d8"},
@@ -2861,7 +2929,7 @@ flake8-simplify = [
     {file = "flake8_simplify-0.19.3-py3-none-any.whl", hash = "sha256:1057320e9312d75849541fee822900d27bcad05b2405edc84713affee635629e"},
     {file = "flake8_simplify-0.19.3.tar.gz", hash = "sha256:2fb083bf5142a98d9c9554755cf2f56f8926eb4a33eae30c0809041b1546879e"},
 ]
-flake8-sql = [
+flake8-SQL = [
     {file = "flake8-SQL-0.4.1.tar.gz", hash = "sha256:a8cdd689a5549c6ec73b4478aae152d5e3199270d23a371653f260f7a0e9dedd"},
     {file = "flake8_SQL-0.4.1-py2.py3-none-any.whl", hash = "sha256:25cd0485ba5feb5b1abfdd0c5b607e014300bcc3fa2a416a18cf62ecdbaaea96"},
 ]
@@ -2878,8 +2946,8 @@ flake8-variables-names = [
     {file = "flake8_variables_names-0.0.5.tar.gz", hash = "sha256:30133e14ee2300e13a60393a00f74d98110c76070ac67d1ab91606f02824a7e1"},
 ]
 fonttools = [
-    {file = "fonttools-4.34.4-py3-none-any.whl", hash = "sha256:d73f25b283cd8033367451122aa868a23de0734757a01984e4b30b18b9050c72"},
-    {file = "fonttools-4.34.4.zip", hash = "sha256:9a1c52488045cd6c6491fd07711a380f932466e317cb8e016fc4e99dc7eac2f0"},
+    {file = "fonttools-4.37.2-py3-none-any.whl", hash = "sha256:88d48ef24486137c864dc56707b4b54ef8a97ab9162c2721ec61434baf1c4d13"},
+    {file = "fonttools-4.37.2.zip", hash = "sha256:b6d86ffd0a5f83d3da6a34d5f99a90398638e423cd6a8d93c5808af703432c7f"},
 ]
 future = [
     {file = "future-0.18.2.tar.gz", hash = "sha256:b1bead90b70cf6ec3f0710ae53a525360fa360d306a86583adc6bf83a4db537d"},
@@ -2892,7 +2960,7 @@ gitdb = [
     {file = "gitdb-4.0.9-py3-none-any.whl", hash = "sha256:8033ad4e853066ba6ca92050b9df2f89301b8fc8bf7e9324d412a63f8bf1a8fd"},
     {file = "gitdb-4.0.9.tar.gz", hash = "sha256:bac2fd45c0a1c9cf619e63a90d62bdc63892ef92387424b855792a6cabe789aa"},
 ]
-gitpython = [
+GitPython = [
     {file = "GitPython-3.1.27-py3-none-any.whl", hash = "sha256:5b68b000463593e05ff2b261acff0ff0972df8ab1b70d3cdbd41b546c8b8fc3d"},
     {file = "GitPython-3.1.27.tar.gz", hash = "sha256:1c885ce809e8ba2d88a29befeb385fcea06338d3640712b59ca623c220bb5704"},
 ]
@@ -2901,16 +2969,16 @@ hug = [
     {file = "hug-2.6.1.tar.gz", hash = "sha256:b0edace2acb618873779c9ce6ecf9165db54fef95c22262f5700fcdd9febaec9"},
 ]
 hypothesis = [
-    {file = "hypothesis-6.54.1-py3-none-any.whl", hash = "sha256:b60b59d36e76626a38cf893d70d0c3c39c5fa02c6c5895966ff5fead8fb9ff0a"},
-    {file = "hypothesis-6.54.1.tar.gz", hash = "sha256:de63c34309181875e71d0f5d1c1051c9320a1fe0517ea6733af8cedf818191f4"},
+    {file = "hypothesis-6.54.5-py3-none-any.whl", hash = "sha256:d8d2e18139be18e5c95593f1e2d87dbcd21534a32022a1db6e8ac2d458ee1d1a"},
+    {file = "hypothesis-6.54.5.tar.gz", hash = "sha256:8a9056825695f415bfad4e808ae719fc01383a9ab659775319724365afcc7ec7"},
 ]
 identify = [
-    {file = "identify-2.5.3-py2.py3-none-any.whl", hash = "sha256:25851c8c1370effb22aaa3c987b30449e9ff0cece408f810ae6ce408fdd20893"},
-    {file = "identify-2.5.3.tar.gz", hash = "sha256:887e7b91a1be152b0d46bbf072130235a8117392b9f1828446079a816a05ef44"},
+    {file = "identify-2.5.5-py2.py3-none-any.whl", hash = "sha256:ef78c0d96098a3b5fe7720be4a97e73f439af7cf088ebf47b620aeaa10fadf97"},
+    {file = "identify-2.5.5.tar.gz", hash = "sha256:322a5699daecf7c6fd60e68852f36f2ecbb6a36ff6e6e973e0d2bb6fca203ee6"},
 ]
 idna = [
-    {file = "idna-3.3-py3-none-any.whl", hash = "sha256:84d9dd047ffa80596e0f246e2eab0b391788b0503584e8945f2368256d2735ff"},
-    {file = "idna-3.3.tar.gz", hash = "sha256:9d643ff0a55b762d5cdb124b8eaa99c66322e2157b69160bc32796e824360e6d"},
+    {file = "idna-3.4-py3-none-any.whl", hash = "sha256:90b77e79eaa3eba6de819a0c442c0b4ceefc341a7a2ab77d7562bf49f425c5c2"},
+    {file = "idna-3.4.tar.gz", hash = "sha256:814f528e8dead7d329833b91c5faa87d60bf71824cd12a7530b5526063d02cb4"},
 ]
 implements = [
     {file = "implements-0.3.0-py2.py3-none-any.whl", hash = "sha256:937be7f9183dc2f098e224b1ff7f9c2fdc76f9b622e46d72e481e57356eec959"},
@@ -2928,7 +2996,7 @@ isort = [
     {file = "isort-5.10.1-py3-none-any.whl", hash = "sha256:6f62d78e2f89b4500b080fe3a81690850cd254227f27f75c3a0c491a1f351ba7"},
     {file = "isort-5.10.1.tar.gz", hash = "sha256:e8443a5e7a020e9d7f97f1d7d9cd17c88bcb3bc7e218bf9cf5095fe550be2951"},
 ]
-jinja2 = [
+Jinja2 = [
     {file = "Jinja2-3.1.2-py3-none-any.whl", hash = "sha256:6088930bfe239f0e6710546ab9c19c9ef35e29792895fed6e6e31a023a182a61"},
     {file = "Jinja2-3.1.2.tar.gz", hash = "sha256:31351a702a408a9e7595a8fc6150fc3f43bb6bf7e319770cbc0db9df9437e852"},
 ]
@@ -2943,6 +3011,21 @@ kiwisolver = [
     {file = "kiwisolver-1.4.4-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a68b62a02953b9841730db7797422f983935aeefceb1679f0fc85cbfbd311c32"},
     {file = "kiwisolver-1.4.4-cp310-cp310-win32.whl", hash = "sha256:e92a513161077b53447160b9bd8f522edfbed4bd9759e4c18ab05d7ef7e49408"},
     {file = "kiwisolver-1.4.4-cp310-cp310-win_amd64.whl", hash = "sha256:3fe20f63c9ecee44560d0e7f116b3a747a5d7203376abeea292ab3152334d004"},
+    {file = "kiwisolver-1.4.4-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:e0ea21f66820452a3f5d1655f8704a60d66ba1191359b96541eaf457710a5fc6"},
+    {file = "kiwisolver-1.4.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:bc9db8a3efb3e403e4ecc6cd9489ea2bac94244f80c78e27c31dcc00d2790ac2"},
+    {file = "kiwisolver-1.4.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d5b61785a9ce44e5a4b880272baa7cf6c8f48a5180c3e81c59553ba0cb0821ca"},
+    {file = "kiwisolver-1.4.4-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c2dbb44c3f7e6c4d3487b31037b1bdbf424d97687c1747ce4ff2895795c9bf69"},
+    {file = "kiwisolver-1.4.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6295ecd49304dcf3bfbfa45d9a081c96509e95f4b9d0eb7ee4ec0530c4a96514"},
+    {file = "kiwisolver-1.4.4-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4bd472dbe5e136f96a4b18f295d159d7f26fd399136f5b17b08c4e5f498cd494"},
+    {file = "kiwisolver-1.4.4-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:bf7d9fce9bcc4752ca4a1b80aabd38f6d19009ea5cbda0e0856983cf6d0023f5"},
+    {file = "kiwisolver-1.4.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:78d6601aed50c74e0ef02f4204da1816147a6d3fbdc8b3872d263338a9052c51"},
+    {file = "kiwisolver-1.4.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:877272cf6b4b7e94c9614f9b10140e198d2186363728ed0f701c6eee1baec1da"},
+    {file = "kiwisolver-1.4.4-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:db608a6757adabb32f1cfe6066e39b3706d8c3aa69bbc353a5b61edad36a5cb4"},
+    {file = "kiwisolver-1.4.4-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:5853eb494c71e267912275e5586fe281444eb5e722de4e131cddf9d442615626"},
+    {file = "kiwisolver-1.4.4-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:f0a1dbdb5ecbef0d34eb77e56fcb3e95bbd7e50835d9782a45df81cc46949750"},
+    {file = "kiwisolver-1.4.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:283dffbf061a4ec60391d51e6155e372a1f7a4f5b15d59c8505339454f8989e4"},
+    {file = "kiwisolver-1.4.4-cp311-cp311-win32.whl", hash = "sha256:d06adcfa62a4431d404c31216f0f8ac97397d799cd53800e9d3efc2fbb3cf14e"},
+    {file = "kiwisolver-1.4.4-cp311-cp311-win_amd64.whl", hash = "sha256:e7da3fec7408813a7cebc9e4ec55afed2d0fd65c4754bc376bf03498d4e92686"},
     {file = "kiwisolver-1.4.4-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:62ac9cc684da4cf1778d07a89bf5f81b35834cb96ca523d3a7fb32509380cbf6"},
     {file = "kiwisolver-1.4.4-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:41dae968a94b1ef1897cb322b39360a0812661dba7c682aa45098eb8e193dbdf"},
     {file = "kiwisolver-1.4.4-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:02f79693ec433cb4b5f51694e8477ae83b3205768a6fb48ffba60549080e295b"},
@@ -2975,6 +3058,16 @@ kiwisolver = [
     {file = "kiwisolver-1.4.4-pp37-pypy37_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:787518a6789009c159453da4d6b683f468ef7a65bbde796bcea803ccf191058d"},
     {file = "kiwisolver-1.4.4-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da152d8cdcab0e56e4f45eb08b9aea6455845ec83172092f09b0e077ece2cf7a"},
     {file = "kiwisolver-1.4.4-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:ecb1fa0db7bf4cff9dac752abb19505a233c7f16684c5826d1f11ebd9472b871"},
+    {file = "kiwisolver-1.4.4-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:28bc5b299f48150b5f822ce68624e445040595a4ac3d59251703779836eceff9"},
+    {file = "kiwisolver-1.4.4-pp38-pypy38_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:81e38381b782cc7e1e46c4e14cd997ee6040768101aefc8fa3c24a4cc58e98f8"},
+    {file = "kiwisolver-1.4.4-pp38-pypy38_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:2a66fdfb34e05b705620dd567f5a03f239a088d5a3f321e7b6ac3239d22aa286"},
+    {file = "kiwisolver-1.4.4-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:872b8ca05c40d309ed13eb2e582cab0c5a05e81e987ab9c521bf05ad1d5cf5cb"},
+    {file = "kiwisolver-1.4.4-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:70e7c2e7b750585569564e2e5ca9845acfaa5da56ac46df68414f29fea97be9f"},
+    {file = "kiwisolver-1.4.4-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:9f85003f5dfa867e86d53fac6f7e6f30c045673fa27b603c397753bebadc3008"},
+    {file = "kiwisolver-1.4.4-pp39-pypy39_pp73-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2e307eb9bd99801f82789b44bb45e9f541961831c7311521b13a6c85afc09767"},
+    {file = "kiwisolver-1.4.4-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b1792d939ec70abe76f5054d3f36ed5656021dcad1322d1cc996d4e54165cef9"},
+    {file = "kiwisolver-1.4.4-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f6cb459eea32a4e2cf18ba5fcece2dbdf496384413bc1bae15583f19e567f3b2"},
+    {file = "kiwisolver-1.4.4-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:36dafec3d6d6088d34e2de6b85f9d8e2324eb734162fba59d2ba9ed7a2043d5b"},
     {file = "kiwisolver-1.4.4.tar.gz", hash = "sha256:d41997519fcba4a1e46eb4a2fe31bc12f0ff957b2b81bac28db24744f333e955"},
 ]
 lazy-object-proxy = [
@@ -3122,19 +3215,19 @@ lxml = [
     {file = "lxml-4.9.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:287605bede6bd36e930577c5925fcea17cb30453d96a7b4c63c14a257118dbb9"},
     {file = "lxml-4.9.1.tar.gz", hash = "sha256:fe749b052bb7233fe5d072fcb549221a8cb1a16725c47c37e42b0b9cb3ff2c3f"},
 ]
-mako = [
-    {file = "Mako-1.2.1-py3-none-any.whl", hash = "sha256:df3921c3081b013c8a2d5ff03c18375651684921ae83fd12e64800b7da923257"},
-    {file = "Mako-1.2.1.tar.gz", hash = "sha256:f054a5ff4743492f1aa9ecc47172cb33b42b9d993cffcc146c9de17e717b0307"},
+Mako = [
+    {file = "Mako-1.2.2-py3-none-any.whl", hash = "sha256:8efcb8004681b5f71d09c983ad5a9e6f5c40601a6ec469148753292abc0da534"},
+    {file = "Mako-1.2.2.tar.gz", hash = "sha256:3724869b363ba630a272a5f89f68c070352137b8fd1757650017b7e06fda163f"},
 ]
 mando = [
     {file = "mando-0.6.4-py2.py3-none-any.whl", hash = "sha256:4ce09faec7e5192ffc3c57830e26acba0fd6cd11e1ee81af0d4df0657463bd1c"},
     {file = "mando-0.6.4.tar.gz", hash = "sha256:79feb19dc0f097daa64a1243db578e7674909b75f88ac2220f1c065c10a0d960"},
 ]
-markdown = [
+Markdown = [
     {file = "Markdown-3.4.1-py3-none-any.whl", hash = "sha256:08fb8465cffd03d10b9dd34a5c3fea908e20391a2a90b88d66362cb05beed186"},
     {file = "Markdown-3.4.1.tar.gz", hash = "sha256:3b809086bb6efad416156e00a0da66fe47618a5d6918dd688f53f40c8e4cfeff"},
 ]
-markupsafe = [
+MarkupSafe = [
     {file = "MarkupSafe-2.1.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:86b1f75c4e7c2ac2ccdaec2b9022845dbb81880ca318bb7a0a01fbf7813e3812"},
     {file = "MarkupSafe-2.1.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:f121a1420d4e173a5d96e47e9a0c0dcff965afdf1626d28de1460815f7c4ee7a"},
     {file = "MarkupSafe-2.1.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a49907dd8420c5685cfa064a1335b6754b74541bbb3706c259c02ed65b644b3e"},
@@ -3177,45 +3270,45 @@ markupsafe = [
     {file = "MarkupSafe-2.1.1.tar.gz", hash = "sha256:7f91197cc9e48f989d12e4e6fbc46495c446636dfc81b9ccf50bb0ec74b91d4b"},
 ]
 matplotlib = [
-    {file = "matplotlib-3.5.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:03bbb3f5f78836855e127b5dab228d99551ad0642918ccbf3067fcd52ac7ac5e"},
-    {file = "matplotlib-3.5.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:49a5938ed6ef9dda560f26ea930a2baae11ea99e1c2080c8714341ecfda72a89"},
-    {file = "matplotlib-3.5.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:77157be0fc4469cbfb901270c205e7d8adb3607af23cef8bd11419600647ceed"},
-    {file = "matplotlib-3.5.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5844cea45d804174bf0fac219b4ab50774e504bef477fc10f8f730ce2d623441"},
-    {file = "matplotlib-3.5.2-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c87973ddec10812bddc6c286b88fdd654a666080fbe846a1f7a3b4ba7b11ab78"},
-    {file = "matplotlib-3.5.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4a05f2b37222319753a5d43c0a4fd97ed4ff15ab502113e3f2625c26728040cf"},
-    {file = "matplotlib-3.5.2-cp310-cp310-win32.whl", hash = "sha256:9776e1a10636ee5f06ca8efe0122c6de57ffe7e8c843e0fb6e001e9d9256ec95"},
-    {file = "matplotlib-3.5.2-cp310-cp310-win_amd64.whl", hash = "sha256:b4fedaa5a9aa9ce14001541812849ed1713112651295fdddd640ea6620e6cf98"},
-    {file = "matplotlib-3.5.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:ee175a571e692fc8ae8e41ac353c0e07259113f4cb063b0ec769eff9717e84bb"},
-    {file = "matplotlib-3.5.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2e8bda1088b941ead50caabd682601bece983cadb2283cafff56e8fcddbf7d7f"},
-    {file = "matplotlib-3.5.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:9480842d5aadb6e754f0b8f4ebeb73065ac8be1855baa93cd082e46e770591e9"},
-    {file = "matplotlib-3.5.2-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:6c623b355d605a81c661546af7f24414165a8a2022cddbe7380a31a4170fa2e9"},
-    {file = "matplotlib-3.5.2-cp37-cp37m-win32.whl", hash = "sha256:a91426ae910819383d337ba0dc7971c7cefdaa38599868476d94389a329e599b"},
-    {file = "matplotlib-3.5.2-cp37-cp37m-win_amd64.whl", hash = "sha256:c4b82c2ae6d305fcbeb0eb9c93df2602ebd2f174f6e8c8a5d92f9445baa0c1d3"},
-    {file = "matplotlib-3.5.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:ebc27ad11df3c1661f4677a7762e57a8a91dd41b466c3605e90717c9a5f90c82"},
-    {file = "matplotlib-3.5.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:5a32ea6e12e80dedaca2d4795d9ed40f97bfa56e6011e14f31502fdd528b9c89"},
-    {file = "matplotlib-3.5.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:2a0967d4156adbd0d46db06bc1a877f0370bce28d10206a5071f9ecd6dc60b79"},
-    {file = "matplotlib-3.5.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e2b696699386766ef171a259d72b203a3c75d99d03ec383b97fc2054f52e15cf"},
-    {file = "matplotlib-3.5.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:7f409716119fa39b03da3d9602bd9b41142fab7a0568758cd136cd80b1bf36c8"},
-    {file = "matplotlib-3.5.2-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:b8d3f4e71e26307e8c120b72c16671d70c5cd08ae412355c11254aa8254fb87f"},
-    {file = "matplotlib-3.5.2-cp38-cp38-win32.whl", hash = "sha256:b6c63cd01cad0ea8704f1fd586e9dc5777ccedcd42f63cbbaa3eae8dd41172a1"},
-    {file = "matplotlib-3.5.2-cp38-cp38-win_amd64.whl", hash = "sha256:75c406c527a3aa07638689586343f4b344fcc7ab1f79c396699eb550cd2b91f7"},
-    {file = "matplotlib-3.5.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:4a44cdfdb9d1b2f18b1e7d315eb3843abb097869cd1ef89cfce6a488cd1b5182"},
-    {file = "matplotlib-3.5.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:3d8e129af95b156b41cb3be0d9a7512cc6d73e2b2109f82108f566dbabdbf377"},
-    {file = "matplotlib-3.5.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:364e6bca34edc10a96aa3b1d7cd76eb2eea19a4097198c1b19e89bee47ed5781"},
-    {file = "matplotlib-3.5.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ea75df8e567743207e2b479ba3d8843537be1c146d4b1e3e395319a4e1a77fe9"},
-    {file = "matplotlib-3.5.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:44c6436868186564450df8fd2fc20ed9daaef5caad699aa04069e87099f9b5a8"},
-    {file = "matplotlib-3.5.2-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:7d7705022df2c42bb02937a2a824f4ec3cca915700dd80dc23916af47ff05f1a"},
-    {file = "matplotlib-3.5.2-cp39-cp39-win32.whl", hash = "sha256:ee0b8e586ac07f83bb2950717e66cb305e2859baf6f00a9c39cc576e0ce9629c"},
-    {file = "matplotlib-3.5.2-cp39-cp39-win_amd64.whl", hash = "sha256:c772264631e5ae61f0bd41313bbe48e1b9bcc95b974033e1118c9caa1a84d5c6"},
-    {file = "matplotlib-3.5.2-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:751d3815b555dcd6187ad35b21736dc12ce6925fc3fa363bbc6dc0f86f16484f"},
-    {file = "matplotlib-3.5.2-pp37-pypy37_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:31fbc2af27ebb820763f077ec7adc79b5a031c2f3f7af446bd7909674cd59460"},
-    {file = "matplotlib-3.5.2-pp37-pypy37_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:4fa28ca76ac5c2b2d54bc058b3dad8e22ee85d26d1ee1b116a6fd4d2277b6a04"},
-    {file = "matplotlib-3.5.2-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:24173c23d1bcbaed5bf47b8785d27933a1ac26a5d772200a0f3e0e38f471b001"},
-    {file = "matplotlib-3.5.2.tar.gz", hash = "sha256:48cf850ce14fa18067f2d9e0d646763681948487a8080ec0af2686468b4607a2"},
+    {file = "matplotlib-3.5.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:a206a1b762b39398efea838f528b3a6d60cdb26fe9d58b48265787e29cd1d693"},
+    {file = "matplotlib-3.5.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:cd45a6f3e93a780185f70f05cf2a383daed13c3489233faad83e81720f7ede24"},
+    {file = "matplotlib-3.5.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:d62880e1f60e5a30a2a8484432bcb3a5056969dc97258d7326ad465feb7ae069"},
+    {file = "matplotlib-3.5.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9ab29589cef03bc88acfa3a1490359000c18186fc30374d8aa77d33cc4a51a4a"},
+    {file = "matplotlib-3.5.3-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2886cc009f40e2984c083687251821f305d811d38e3df8ded414265e4583f0c5"},
+    {file = "matplotlib-3.5.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c995f7d9568f18b5db131ab124c64e51b6820a92d10246d4f2b3f3a66698a15b"},
+    {file = "matplotlib-3.5.3-cp310-cp310-win32.whl", hash = "sha256:6bb93a0492d68461bd458eba878f52fdc8ac7bdb6c4acdfe43dba684787838c2"},
+    {file = "matplotlib-3.5.3-cp310-cp310-win_amd64.whl", hash = "sha256:2e6d184ebe291b9e8f7e78bbab7987d269c38ea3e062eace1fe7d898042ef804"},
+    {file = "matplotlib-3.5.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:6ea6aef5c4338e58d8d376068e28f80a24f54e69f09479d1c90b7172bad9f25b"},
+    {file = "matplotlib-3.5.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:839d47b8ead7ad9669aaacdbc03f29656dc21f0d41a6fea2d473d856c39c8b1c"},
+    {file = "matplotlib-3.5.3-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:3b4fa56159dc3c7f9250df88f653f085068bcd32dcd38e479bba58909254af7f"},
+    {file = "matplotlib-3.5.3-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:94ff86af56a3869a4ae26a9637a849effd7643858a1a04dd5ee50e9ab75069a7"},
+    {file = "matplotlib-3.5.3-cp37-cp37m-win32.whl", hash = "sha256:35a8ad4dddebd51f94c5d24bec689ec0ec66173bf614374a1244c6241c1595e0"},
+    {file = "matplotlib-3.5.3-cp37-cp37m-win_amd64.whl", hash = "sha256:43e9d3fa077bf0cc95ded13d331d2156f9973dce17c6f0c8b49ccd57af94dbd9"},
+    {file = "matplotlib-3.5.3-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:22227c976ad4dc8c5a5057540421f0d8708c6560744ad2ad638d48e2984e1dbc"},
+    {file = "matplotlib-3.5.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:bf618a825deb6205f015df6dfe6167a5d9b351203b03fab82043ae1d30f16511"},
+    {file = "matplotlib-3.5.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:9befa5954cdbc085e37d974ff6053da269474177921dd61facdad8023c4aeb51"},
+    {file = "matplotlib-3.5.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f3840c280ebc87a48488a46f760ea1c0c0c83fcf7abbe2e6baf99d033fd35fd8"},
+    {file = "matplotlib-3.5.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:dacddf5bfcec60e3f26ec5c0ae3d0274853a258b6c3fc5ef2f06a8eb23e042be"},
+    {file = "matplotlib-3.5.3-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:b428076a55fb1c084c76cb93e68006f27d247169f056412607c5c88828d08f88"},
+    {file = "matplotlib-3.5.3-cp38-cp38-win32.whl", hash = "sha256:874df7505ba820e0400e7091199decf3ff1fde0583652120c50cd60d5820ca9a"},
+    {file = "matplotlib-3.5.3-cp38-cp38-win_amd64.whl", hash = "sha256:b28de401d928890187c589036857a270a032961411934bdac4cf12dde3d43094"},
+    {file = "matplotlib-3.5.3-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:3211ba82b9f1518d346f6309df137b50c3dc4421b4ed4815d1d7eadc617f45a1"},
+    {file = "matplotlib-3.5.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6fe807e8a22620b4cd95cfbc795ba310dc80151d43b037257250faf0bfcd82bc"},
+    {file = "matplotlib-3.5.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:5c096363b206a3caf43773abebdbb5a23ea13faef71d701b21a9c27fdcef72f4"},
+    {file = "matplotlib-3.5.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0bcdfcb0f976e1bac6721d7d457c17be23cf7501f977b6a38f9d38a3762841f7"},
+    {file = "matplotlib-3.5.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:1e64ac9be9da6bfff0a732e62116484b93b02a0b4d4b19934fb4f8e7ad26ad6a"},
+    {file = "matplotlib-3.5.3-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:73dd93dc35c85dece610cca8358003bf0760d7986f70b223e2306b4ea6d1406b"},
+    {file = "matplotlib-3.5.3-cp39-cp39-win32.whl", hash = "sha256:879c7e5fce4939c6aa04581dfe08d57eb6102a71f2e202e3314d5fbc072fd5a0"},
+    {file = "matplotlib-3.5.3-cp39-cp39-win_amd64.whl", hash = "sha256:ab8d26f07fe64f6f6736d635cce7bfd7f625320490ed5bfc347f2cdb4fae0e56"},
+    {file = "matplotlib-3.5.3-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:99482b83ebf4eb6d5fc6813d7aacdefdd480f0d9c0b52dcf9f1cc3b2c4b3361a"},
+    {file = "matplotlib-3.5.3-pp37-pypy37_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:f814504e459c68118bf2246a530ed953ebd18213dc20e3da524174d84ed010b2"},
+    {file = "matplotlib-3.5.3-pp37-pypy37_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:57f1b4e69f438a99bb64d7f2c340db1b096b41ebaa515cf61ea72624279220ce"},
+    {file = "matplotlib-3.5.3-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:d2484b350bf3d32cae43f85dcfc89b3ed7bd2bcd781ef351f93eb6fb2cc483f9"},
+    {file = "matplotlib-3.5.3.tar.gz", hash = "sha256:339cac48b80ddbc8bfd05daae0a3a73414651a8596904c2a881cfd1edb65f26c"},
 ]
 mccabe = [
-    {file = "mccabe-0.6.1-py2.py3-none-any.whl", hash = "sha256:ab8a6258860da4b6677da4bd2fe5dc2c659cff31b3ee4f7f5d64e79735b80d42"},
-    {file = "mccabe-0.6.1.tar.gz", hash = "sha256:dd8d182285a0fe56bace7f45b5e7d1a6ebcbf524e8f3bd87eb0f125271b8831f"},
+    {file = "mccabe-0.7.0-py2.py3-none-any.whl", hash = "sha256:6c2d30ab6be0e4a46919781807b4f0d834ebdd6c6e3dca0bda5a15f863427b6e"},
+    {file = "mccabe-0.7.0.tar.gz", hash = "sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325"},
 ]
 mergedeep = [
     {file = "mergedeep-1.3.4-py3-none-any.whl", hash = "sha256:70775750742b25c0d8f36c55aed03d24c3384d17c951b3175d898bd778ef0307"},
@@ -3230,8 +3323,8 @@ mkdocs-git-revision-date-localized-plugin = [
     {file = "mkdocs_git_revision_date_localized_plugin-1.1.0-py3-none-any.whl", hash = "sha256:4ba0e49abea3e9f6ee26e2623ff7283873da657471c61f1d0cfbb986f403316d"},
 ]
 mkdocs-material = [
-    {file = "mkdocs-material-8.3.9.tar.gz", hash = "sha256:dc82b667d2a83f0de581b46a6d0949732ab77e7638b87ea35b770b33bc02e75a"},
-    {file = "mkdocs_material-8.3.9-py2.py3-none-any.whl", hash = "sha256:263f2721f3abe533b61f7c8bed435a0462620912742c919821ac2d698b4bfe67"},
+    {file = "mkdocs-material-8.5.1.tar.gz", hash = "sha256:2daf604d00d554d5496c02b4c4d14dfa57dd689c90f639da5020601baef4b235"},
+    {file = "mkdocs_material-8.5.1-py2.py3-none-any.whl", hash = "sha256:79e9b65e481edb539eda6a3a939a0e02609a5c54afc315c3b05f57ff40db3188"},
 ]
 mkdocs-material-extensions = [
     {file = "mkdocs-material-extensions-1.0.3.tar.gz", hash = "sha256:bfd24dfdef7b41c312ede42648f9eb83476ea168ec163b613f9abd12bbfddba2"},
@@ -3344,55 +3437,61 @@ nox-poetry = [
     {file = "nox_poetry-1.0.1-py3-none-any.whl", hash = "sha256:6ed30e33b782cecba081dbb79626f60c3acf517c535b89ef8699071fd70567cd"},
 ]
 numpy = [
-    {file = "numpy-1.23.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b15c3f1ed08df4980e02cc79ee058b788a3d0bef2fb3c9ca90bb8cbd5b8a3a04"},
-    {file = "numpy-1.23.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9ce242162015b7e88092dccd0e854548c0926b75c7924a3495e02c6067aba1f5"},
-    {file = "numpy-1.23.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e0d7447679ae9a7124385ccf0ea990bb85bb869cef217e2ea6c844b6a6855073"},
-    {file = "numpy-1.23.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3119daed207e9410eaf57dcf9591fdc68045f60483d94956bee0bfdcba790953"},
-    {file = "numpy-1.23.1-cp310-cp310-win32.whl", hash = "sha256:3ab67966c8d45d55a2bdf40701536af6443763907086c0a6d1232688e27e5447"},
-    {file = "numpy-1.23.1-cp310-cp310-win_amd64.whl", hash = "sha256:1865fdf51446839ca3fffaab172461f2b781163f6f395f1aed256b1ddc253622"},
-    {file = "numpy-1.23.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:aeba539285dcf0a1ba755945865ec61240ede5432df41d6e29fab305f4384db2"},
-    {file = "numpy-1.23.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:7e8229f3687cdadba2c4faef39204feb51ef7c1a9b669247d49a24f3e2e1617c"},
-    {file = "numpy-1.23.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:68b69f52e6545af010b76516f5daaef6173e73353e3295c5cb9f96c35d755641"},
-    {file = "numpy-1.23.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1408c3527a74a0209c781ac82bde2182b0f0bf54dea6e6a363fe0cc4488a7ce7"},
-    {file = "numpy-1.23.1-cp38-cp38-win32.whl", hash = "sha256:47f10ab202fe4d8495ff484b5561c65dd59177949ca07975663f4494f7269e3e"},
-    {file = "numpy-1.23.1-cp38-cp38-win_amd64.whl", hash = "sha256:37e5ebebb0eb54c5b4a9b04e6f3018e16b8ef257d26c8945925ba8105008e645"},
-    {file = "numpy-1.23.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:173f28921b15d341afadf6c3898a34f20a0569e4ad5435297ba262ee8941e77b"},
-    {file = "numpy-1.23.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:876f60de09734fbcb4e27a97c9a286b51284df1326b1ac5f1bf0ad3678236b22"},
-    {file = "numpy-1.23.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:35590b9c33c0f1c9732b3231bb6a72d1e4f77872390c47d50a615686ae7ed3fd"},
-    {file = "numpy-1.23.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a35c4e64dfca659fe4d0f1421fc0f05b8ed1ca8c46fb73d9e5a7f175f85696bb"},
-    {file = "numpy-1.23.1-cp39-cp39-win32.whl", hash = "sha256:c2f91f88230042a130ceb1b496932aa717dcbd665350beb821534c5c7e15881c"},
-    {file = "numpy-1.23.1-cp39-cp39-win_amd64.whl", hash = "sha256:37ece2bd095e9781a7156852e43d18044fd0d742934833335599c583618181b9"},
-    {file = "numpy-1.23.1-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:8002574a6b46ac3b5739a003b5233376aeac5163e5dcd43dd7ad062f3e186129"},
-    {file = "numpy-1.23.1-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5d732d17b8a9061540a10fda5bfeabca5785700ab5469a5e9b93aca5e2d3a5fb"},
-    {file = "numpy-1.23.1-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:55df0f7483b822855af67e38fb3a526e787adf189383b4934305565d71c4b148"},
-    {file = "numpy-1.23.1.tar.gz", hash = "sha256:d748ef349bfef2e1194b59da37ed5a29c19ea8d7e6342019921ba2ba4fd8b624"},
+    {file = "numpy-1.23.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c9f707b5bb73bf277d812ded9896f9512a43edff72712f31667d0a8c2f8e71ee"},
+    {file = "numpy-1.23.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ffcf105ecdd9396e05a8e58e81faaaf34d3f9875f137c7372450baa5d77c9a54"},
+    {file = "numpy-1.23.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ea3f98a0ffce3f8f57675eb9119f3f4edb81888b6874bc1953f91e0b1d4f440"},
+    {file = "numpy-1.23.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:004f0efcb2fe1c0bd6ae1fcfc69cc8b6bf2407e0f18be308612007a0762b4089"},
+    {file = "numpy-1.23.3-cp310-cp310-win32.whl", hash = "sha256:98dcbc02e39b1658dc4b4508442a560fe3ca5ca0d989f0df062534e5ca3a5c1a"},
+    {file = "numpy-1.23.3-cp310-cp310-win_amd64.whl", hash = "sha256:39a664e3d26ea854211867d20ebcc8023257c1800ae89773cbba9f9e97bae036"},
+    {file = "numpy-1.23.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1f27b5322ac4067e67c8f9378b41c746d8feac8bdd0e0ffede5324667b8a075c"},
+    {file = "numpy-1.23.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:2ad3ec9a748a8943e6eb4358201f7e1c12ede35f510b1a2221b70af4bb64295c"},
+    {file = "numpy-1.23.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bdc9febce3e68b697d931941b263c59e0c74e8f18861f4064c1f712562903411"},
+    {file = "numpy-1.23.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:301c00cf5e60e08e04d842fc47df641d4a181e651c7135c50dc2762ffe293dbd"},
+    {file = "numpy-1.23.3-cp311-cp311-win32.whl", hash = "sha256:7cd1328e5bdf0dee621912f5833648e2daca72e3839ec1d6695e91089625f0b4"},
+    {file = "numpy-1.23.3-cp311-cp311-win_amd64.whl", hash = "sha256:8355fc10fd33a5a70981a5b8a0de51d10af3688d7a9e4a34fcc8fa0d7467bb7f"},
+    {file = "numpy-1.23.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:bc6e8da415f359b578b00bcfb1d08411c96e9a97f9e6c7adada554a0812a6cc6"},
+    {file = "numpy-1.23.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:22d43376ee0acd547f3149b9ec12eec2f0ca4a6ab2f61753c5b29bb3e795ac4d"},
+    {file = "numpy-1.23.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a64403f634e5ffdcd85e0b12c08f04b3080d3e840aef118721021f9b48fc1460"},
+    {file = "numpy-1.23.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:efd9d3abe5774404becdb0748178b48a218f1d8c44e0375475732211ea47c67e"},
+    {file = "numpy-1.23.3-cp38-cp38-win32.whl", hash = "sha256:f8c02ec3c4c4fcb718fdf89a6c6f709b14949408e8cf2a2be5bfa9c49548fd85"},
+    {file = "numpy-1.23.3-cp38-cp38-win_amd64.whl", hash = "sha256:e868b0389c5ccfc092031a861d4e158ea164d8b7fdbb10e3b5689b4fc6498df6"},
+    {file = "numpy-1.23.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:09f6b7bdffe57fc61d869a22f506049825d707b288039d30f26a0d0d8ea05164"},
+    {file = "numpy-1.23.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:8c79d7cf86d049d0c5089231a5bcd31edb03555bd93d81a16870aa98c6cfb79d"},
+    {file = "numpy-1.23.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e5d5420053bbb3dd64c30e58f9363d7a9c27444c3648e61460c1237f9ec3fa14"},
+    {file = "numpy-1.23.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d5422d6a1ea9b15577a9432e26608c73a78faf0b9039437b075cf322c92e98e7"},
+    {file = "numpy-1.23.3-cp39-cp39-win32.whl", hash = "sha256:c1ba66c48b19cc9c2975c0d354f24058888cdc674bebadceb3cdc9ec403fb5d1"},
+    {file = "numpy-1.23.3-cp39-cp39-win_amd64.whl", hash = "sha256:78a63d2df1d947bd9d1b11d35564c2f9e4b57898aae4626638056ec1a231c40c"},
+    {file = "numpy-1.23.3-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:17c0e467ade9bda685d5ac7f5fa729d8d3e76b23195471adae2d6a6941bd2c18"},
+    {file = "numpy-1.23.3-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:91b8d6768a75247026e951dce3b2aac79dc7e78622fc148329135ba189813584"},
+    {file = "numpy-1.23.3-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:94c15ca4e52671a59219146ff584488907b1f9b3fc232622b47e2cf832e94fb8"},
+    {file = "numpy-1.23.3.tar.gz", hash = "sha256:51bf49c0cd1d52be0a240aa66f3458afc4b95d8993d2d04f0d91fa60c10af6cd"},
 ]
 packaging = [
     {file = "packaging-21.3-py3-none-any.whl", hash = "sha256:ef103e05f519cdc783ae24ea4e2e0f508a9c99b2d4969652eed6a2e1ea5bd522"},
     {file = "packaging-21.3.tar.gz", hash = "sha256:dd47c42927d89ab911e606518907cc2d3a1f38bbd026385970643f9c5b8ecfeb"},
 ]
 pandas = [
-    {file = "pandas-1.4.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:d51674ed8e2551ef7773820ef5dab9322be0828629f2cbf8d1fc31a0c4fed640"},
-    {file = "pandas-1.4.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:16ad23db55efcc93fa878f7837267973b61ea85d244fc5ff0ccbcfa5638706c5"},
-    {file = "pandas-1.4.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:958a0588149190c22cdebbc0797e01972950c927a11a900fe6c2296f207b1d6f"},
-    {file = "pandas-1.4.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e48fbb64165cda451c06a0f9e4c7a16b534fcabd32546d531b3c240ce2844112"},
-    {file = "pandas-1.4.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6f803320c9da732cc79210d7e8cc5c8019aad512589c910c66529eb1b1818230"},
-    {file = "pandas-1.4.3-cp310-cp310-win_amd64.whl", hash = "sha256:2893e923472a5e090c2d5e8db83e8f907364ec048572084c7d10ef93546be6d1"},
-    {file = "pandas-1.4.3-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:24ea75f47bbd5574675dae21d51779a4948715416413b30614c1e8b480909f81"},
-    {file = "pandas-1.4.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:d5ebc990bd34f4ac3c73a2724c2dcc9ee7bf1ce6cf08e87bb25c6ad33507e318"},
-    {file = "pandas-1.4.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:d6c0106415ff1a10c326c49bc5dd9ea8b9897a6ca0c8688eb9c30ddec49535ef"},
-    {file = "pandas-1.4.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:78b00429161ccb0da252229bcda8010b445c4bf924e721265bec5a6e96a92e92"},
-    {file = "pandas-1.4.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6dfbf16b1ea4f4d0ee11084d9c026340514d1d30270eaa82a9f1297b6c8ecbf0"},
-    {file = "pandas-1.4.3-cp38-cp38-win32.whl", hash = "sha256:48350592665ea3cbcd07efc8c12ff12d89be09cd47231c7925e3b8afada9d50d"},
-    {file = "pandas-1.4.3-cp38-cp38-win_amd64.whl", hash = "sha256:605d572126eb4ab2eadf5c59d5d69f0608df2bf7bcad5c5880a47a20a0699e3e"},
-    {file = "pandas-1.4.3-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:a3924692160e3d847e18702bb048dc38e0e13411d2b503fecb1adf0fcf950ba4"},
-    {file = "pandas-1.4.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:07238a58d7cbc8a004855ade7b75bbd22c0db4b0ffccc721556bab8a095515f6"},
-    {file = "pandas-1.4.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:755679c49460bd0d2f837ab99f0a26948e68fa0718b7e42afbabd074d945bf84"},
-    {file = "pandas-1.4.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:41fc406e374590a3d492325b889a2686b31e7a7780bec83db2512988550dadbf"},
-    {file = "pandas-1.4.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1d9382f72a4f0e93909feece6fef5500e838ce1c355a581b3d8f259839f2ea76"},
-    {file = "pandas-1.4.3-cp39-cp39-win32.whl", hash = "sha256:0daf876dba6c622154b2e6741f29e87161f844e64f84801554f879d27ba63c0d"},
-    {file = "pandas-1.4.3-cp39-cp39-win_amd64.whl", hash = "sha256:721a3dd2f06ef942f83a819c0f3f6a648b2830b191a72bbe9451bcd49c3bd42e"},
-    {file = "pandas-1.4.3.tar.gz", hash = "sha256:2ff7788468e75917574f080cd4681b27e1a7bf36461fe968b49a87b5a54d007c"},
+    {file = "pandas-1.4.4-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:799e6a25932df7e6b1f8dabf63de064e2205dc309abb75956126a0453fd88e97"},
+    {file = "pandas-1.4.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:7cd1d69a387f7d5e1a5a06a87574d9ef2433847c0e78113ab51c84d3a8bcaeaa"},
+    {file = "pandas-1.4.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:94f2ed1fd51e545ebf71da1e942fe1822ee01e10d3dd2a7276d01351333b7c6b"},
+    {file = "pandas-1.4.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4591cadd06fbbbd16fafc2de6e840c1aaefeae3d5864b688004777ef1bbdede3"},
+    {file = "pandas-1.4.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d0022fe6a313df1c4869b5edc012d734c6519a6fffa3cf70930f32e6a1078e49"},
+    {file = "pandas-1.4.4-cp310-cp310-win_amd64.whl", hash = "sha256:785e878a6e6d8ddcdb8c181e600855402750052497d7fc6d6b508894f6b8830b"},
+    {file = "pandas-1.4.4-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:c4bb8b0ab9f94207d07e401d24baebfc63057246b1a5e0cd9ee50df85a656871"},
+    {file = "pandas-1.4.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:51c424ca134fdaeac9a4acd719d1ab48046afc60943a489028f0413fdbe9ef1c"},
+    {file = "pandas-1.4.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:ce35f947202b0b99c660221d82beb91d2e6d553d55a40b30128204e3e2c63848"},
+    {file = "pandas-1.4.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ee6f1848148ed3204235967613b0a32be2d77f214e9623f554511047705c1e04"},
+    {file = "pandas-1.4.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e7cc960959be28d064faefc0cb2aef854d46b827c004ebea7e79b5497ed83e7d"},
+    {file = "pandas-1.4.4-cp38-cp38-win32.whl", hash = "sha256:9d805bce209714b1c1fa29bfb1e42ad87e4c0a825e4b390c56a3e71593b7e8d8"},
+    {file = "pandas-1.4.4-cp38-cp38-win_amd64.whl", hash = "sha256:afbddad78a98ec4d2ce08b384b81730de1ccc975b99eb663e6dac43703f36d98"},
+    {file = "pandas-1.4.4-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:a08ceb59db499864c58a9bf85ab6219d527d91f14c0240cc25fa2c261032b2a7"},
+    {file = "pandas-1.4.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:0959c41004e3d2d16f39c828d6da66ebee329836a7ecee49fb777ac9ad8a7501"},
+    {file = "pandas-1.4.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:87b4194f344dcd14c0f885cecb22005329b38bda10f1aaf7b9596a00ec8a4768"},
+    {file = "pandas-1.4.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9d2a7a3c1fea668d56bd91edbd5f2732e0af8feb9d2bf8d9bfacb2dea5fa9536"},
+    {file = "pandas-1.4.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a981cfabf51c318a562deb4ae7deec594c07aee7cf18b4594a92c23718ec8275"},
+    {file = "pandas-1.4.4-cp39-cp39-win32.whl", hash = "sha256:050aada67a5ec6699a7879e769825b510018a95fb9ac462bb1867483d0974a97"},
+    {file = "pandas-1.4.4-cp39-cp39-win_amd64.whl", hash = "sha256:8d4d2fe2863ecddb0ba1979bdda26c8bc2ea138f5a979abe3ba80c0fa4015c91"},
+    {file = "pandas-1.4.4.tar.gz", hash = "sha256:ab6c0d738617b675183e5f28db32b5148b694ad9bba0a40c3ea26d96b431db67"},
 ]
 pandas-vet = [
     {file = "pandas-vet-0.2.3.tar.gz", hash = "sha256:58b64027a4c192b4b62272c1d8fdecc1733352452401282b697c1a32abe4656a"},
@@ -3403,8 +3502,8 @@ pathspec = [
     {file = "pathspec-0.9.0.tar.gz", hash = "sha256:e564499435a2673d586f6b2130bb5b95f04a3ba06f81b8f895b651a3c76aabb1"},
 ]
 pbr = [
-    {file = "pbr-5.9.0-py2.py3-none-any.whl", hash = "sha256:e547125940bcc052856ded43be8e101f63828c2d94239ffbe2b327ba3d5ccf0a"},
-    {file = "pbr-5.9.0.tar.gz", hash = "sha256:e8dca2f4b43560edef58813969f52a56cef023146cbb8931626db80e6c1c4308"},
+    {file = "pbr-5.10.0-py2.py3-none-any.whl", hash = "sha256:da3e18aac0a3c003e9eea1a81bd23e5a3a75d745670dcf736317b7d966887fdf"},
+    {file = "pbr-5.10.0.tar.gz", hash = "sha256:cfcc4ff8e698256fc17ea3ff796478b050852585aa5bae79ecd05b2ab7b39b9a"},
 ]
 pdbpp = [
     {file = "pdbpp-0.10.3-py2.py3-none-any.whl", hash = "sha256:79580568e33eb3d6f6b462b1187f53e10cd8e4538f7d31495c9181e2cf9665d1"},
@@ -3438,10 +3537,10 @@ pendulum = [
     {file = "pendulum-2.1.2.tar.gz", hash = "sha256:b06a0ca1bfe41c990bbf0c029f0b6501a7f2ec4e38bfec730712015e8860f207"},
 ]
 pep8-naming = [
-    {file = "pep8-naming-0.13.1.tar.gz", hash = "sha256:3af77cdaa9c7965f7c85a56cd579354553c9bbd3fdf3078a776f12db54dd6944"},
-    {file = "pep8_naming-0.13.1-py3-none-any.whl", hash = "sha256:f7867c1a464fe769be4f972ef7b79d6df1d9aff1b1f04ecf738d471963d3ab9c"},
+    {file = "pep8-naming-0.13.2.tar.gz", hash = "sha256:93eef62f525fd12a6f8c98f4dcc17fa70baae2f37fa1f73bec00e3e44392fa48"},
+    {file = "pep8_naming-0.13.2-py3-none-any.whl", hash = "sha256:59e29e55c478db69cffbe14ab24b5bd2cd615c0413edf790d47d3fb7ba9a4e23"},
 ]
-pillow = [
+Pillow = [
     {file = "Pillow-9.2.0-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:a9c9bc489f8ab30906d7a85afac4b4944a572a7432e00698a7239f44a44e6efb"},
     {file = "Pillow-9.2.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:510cef4a3f401c246cfd8227b300828715dd055463cdca6176c2e4036df8bd4f"},
     {file = "Pillow-9.2.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7888310f6214f19ab2b6df90f3f06afa3df7ef7355fc025e78a3044737fab1f5"},
@@ -3452,8 +3551,8 @@ pillow = [
     {file = "Pillow-9.2.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:37ff6b522a26d0538b753f0b4e8e164fdada12db6c6f00f62145d732d8a3152e"},
     {file = "Pillow-9.2.0-cp310-cp310-win32.whl", hash = "sha256:c79698d4cd9318d9481d89a77e2d3fcaeff5486be641e60a4b49f3d2ecca4e28"},
     {file = "Pillow-9.2.0-cp310-cp310-win_amd64.whl", hash = "sha256:254164c57bab4b459f14c64e93df11eff5ded575192c294a0c49270f22c5d93d"},
-    {file = "Pillow-9.2.0-cp311-cp311-macosx_10_10_universal2.whl", hash = "sha256:408673ed75594933714482501fe97e055a42996087eeca7e5d06e33218d05aa8"},
-    {file = "Pillow-9.2.0-cp311-cp311-macosx_11_0_universal2.whl", hash = "sha256:727dd1389bc5cb9827cbd1f9d40d2c2a1a0c9b32dd2261db522d22a604a6eec9"},
+    {file = "Pillow-9.2.0-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:adabc0bce035467fb537ef3e5e74f2847c8af217ee0be0455d4fec8adc0462fc"},
+    {file = "Pillow-9.2.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:336b9036127eab855beec9662ac3ea13a4544a523ae273cbf108b228ecac8437"},
     {file = "Pillow-9.2.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:50dff9cc21826d2977ef2d2a205504034e3a4563ca6f5db739b0d1026658e004"},
     {file = "Pillow-9.2.0-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cb6259196a589123d755380b65127ddc60f4c64b21fc3bb46ce3a6ea663659b0"},
     {file = "Pillow-9.2.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7b0554af24df2bf96618dac71ddada02420f946be943b181108cac55a7a2dcd4"},
@@ -3501,6 +3600,10 @@ pillow = [
     {file = "Pillow-9.2.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:0030fdbd926fb85844b8b92e2f9449ba89607231d3dd597a21ae72dc7fe26927"},
     {file = "Pillow-9.2.0.tar.gz", hash = "sha256:75e636fd3e0fb872693f23ccb8a5ff2cd578801251f3a4f6854c6a5d437d3c04"},
 ]
+pip = [
+    {file = "pip-22.2.2-py3-none-any.whl", hash = "sha256:b61a374b5bc40a6e982426aede40c9b5a08ff20e640f5b56977f4f91fed1e39a"},
+    {file = "pip-22.2.2.tar.gz", hash = "sha256:3fd1929db052f056d7a998439176d3333fa1b3f6c1ad881de1885c0717608a4b"},
+]
 pip-check = [
     {file = "pip-check-2.7.tar.gz", hash = "sha256:17d1612af84fecfebdf8f8c60b9eaa9c389814a49affdcd88a1d4fd98fd17aee"},
     {file = "pip_check-2.7-py2.py3-none-any.whl", hash = "sha256:f14ba13b0a66cd9d4732f958fa79d0b0ed2ef7833239927ef4336266265b72fa"},
@@ -3518,8 +3621,8 @@ pre-commit = [
     {file = "pre_commit-2.20.0.tar.gz", hash = "sha256:a978dac7bc9ec0bcee55c18a277d553b0f419d259dadb4b9418ff2d00eb43959"},
 ]
 prompt-toolkit = [
-    {file = "prompt_toolkit-3.0.30-py3-none-any.whl", hash = "sha256:d8916d3f62a7b67ab353a952ce4ced6a1d2587dfe9ef8ebc30dd7c386751f289"},
-    {file = "prompt_toolkit-3.0.30.tar.gz", hash = "sha256:859b283c50bde45f5f97829f77a4674d1c1fcd88539364f1b28a37805cfd89c0"},
+    {file = "prompt_toolkit-3.0.31-py3-none-any.whl", hash = "sha256:9696f386133df0fc8ca5af4895afe5d78f5fcfe5258111c2a79a1c3e41ffa96d"},
+    {file = "prompt_toolkit-3.0.31.tar.gz", hash = "sha256:9ada952c9d1787f52ff6d5f3484d0b4df8952787c087edf6a1f7c2cb1ea88148"},
 ]
 proselint = [
     {file = "proselint-0.13.0-py3-none-any.whl", hash = "sha256:5799a26c79e52aed18a1b7671f74381c035b3f62a565b478306298fb134c80c4"},
@@ -3541,24 +3644,62 @@ pycln = [
     {file = "pycln-2.1.1.tar.gz", hash = "sha256:255a135935796761958dd3349822ccc71ce3052464c4d81e119df0106bbaf882"},
 ]
 pycodestyle = [
-    {file = "pycodestyle-2.8.0-py2.py3-none-any.whl", hash = "sha256:720f8b39dde8b293825e7ff02c475f3077124006db4f440dcbc9a20b76548a20"},
-    {file = "pycodestyle-2.8.0.tar.gz", hash = "sha256:eddd5847ef438ea1c7870ca7eb78a9d47ce0cdb4851a5523949f2601d0cbbe7f"},
+    {file = "pycodestyle-2.9.1-py2.py3-none-any.whl", hash = "sha256:d1735fc58b418fd7c5f658d28d943854f8a849b01a5d0a1e6f3f3fdd0166804b"},
+    {file = "pycodestyle-2.9.1.tar.gz", hash = "sha256:2c9607871d58c76354b697b42f5d57e1ada7d261c261efac224b664affdc5785"},
+]
+pydantic = [
+    {file = "pydantic-1.10.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:bb6ad4489af1bac6955d38ebcb95079a836af31e4c4f74aba1ca05bb9f6027bd"},
+    {file = "pydantic-1.10.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a1f5a63a6dfe19d719b1b6e6106561869d2efaca6167f84f5ab9347887d78b98"},
+    {file = "pydantic-1.10.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:352aedb1d71b8b0736c6d56ad2bd34c6982720644b0624462059ab29bd6e5912"},
+    {file = "pydantic-1.10.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:19b3b9ccf97af2b7519c42032441a891a5e05c68368f40865a90eb88833c2559"},
+    {file = "pydantic-1.10.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:e9069e1b01525a96e6ff49e25876d90d5a563bc31c658289a8772ae186552236"},
+    {file = "pydantic-1.10.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:355639d9afc76bcb9b0c3000ddcd08472ae75318a6eb67a15866b87e2efa168c"},
+    {file = "pydantic-1.10.2-cp310-cp310-win_amd64.whl", hash = "sha256:ae544c47bec47a86bc7d350f965d8b15540e27e5aa4f55170ac6a75e5f73b644"},
+    {file = "pydantic-1.10.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:a4c805731c33a8db4b6ace45ce440c4ef5336e712508b4d9e1aafa617dc9907f"},
+    {file = "pydantic-1.10.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d49f3db871575e0426b12e2f32fdb25e579dea16486a26e5a0474af87cb1ab0a"},
+    {file = "pydantic-1.10.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:37c90345ec7dd2f1bcef82ce49b6235b40f282b94d3eec47e801baf864d15525"},
+    {file = "pydantic-1.10.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7b5ba54d026c2bd2cb769d3468885f23f43710f651688e91f5fb1edcf0ee9283"},
+    {file = "pydantic-1.10.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:05e00dbebbe810b33c7a7362f231893183bcc4251f3f2ff991c31d5c08240c42"},
+    {file = "pydantic-1.10.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:2d0567e60eb01bccda3a4df01df677adf6b437958d35c12a3ac3e0f078b0ee52"},
+    {file = "pydantic-1.10.2-cp311-cp311-win_amd64.whl", hash = "sha256:c6f981882aea41e021f72779ce2a4e87267458cc4d39ea990729e21ef18f0f8c"},
+    {file = "pydantic-1.10.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c4aac8e7103bf598373208f6299fa9a5cfd1fc571f2d40bf1dd1955a63d6eeb5"},
+    {file = "pydantic-1.10.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:81a7b66c3f499108b448f3f004801fcd7d7165fb4200acb03f1c2402da73ce4c"},
+    {file = "pydantic-1.10.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bedf309630209e78582ffacda64a21f96f3ed2e51fbf3962d4d488e503420254"},
+    {file = "pydantic-1.10.2-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:9300fcbebf85f6339a02c6994b2eb3ff1b9c8c14f502058b5bf349d42447dcf5"},
+    {file = "pydantic-1.10.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:216f3bcbf19c726b1cc22b099dd409aa371f55c08800bcea4c44c8f74b73478d"},
+    {file = "pydantic-1.10.2-cp37-cp37m-win_amd64.whl", hash = "sha256:dd3f9a40c16daf323cf913593083698caee97df2804aa36c4b3175d5ac1b92a2"},
+    {file = "pydantic-1.10.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:b97890e56a694486f772d36efd2ba31612739bc6f3caeee50e9e7e3ebd2fdd13"},
+    {file = "pydantic-1.10.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:9cabf4a7f05a776e7793e72793cd92cc865ea0e83a819f9ae4ecccb1b8aa6116"},
+    {file = "pydantic-1.10.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:06094d18dd5e6f2bbf93efa54991c3240964bb663b87729ac340eb5014310624"},
+    {file = "pydantic-1.10.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cc78cc83110d2f275ec1970e7a831f4e371ee92405332ebfe9860a715f8336e1"},
+    {file = "pydantic-1.10.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:1ee433e274268a4b0c8fde7ad9d58ecba12b069a033ecc4645bb6303c062d2e9"},
+    {file = "pydantic-1.10.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:7c2abc4393dea97a4ccbb4ec7d8658d4e22c4765b7b9b9445588f16c71ad9965"},
+    {file = "pydantic-1.10.2-cp38-cp38-win_amd64.whl", hash = "sha256:0b959f4d8211fc964772b595ebb25f7652da3f22322c007b6fed26846a40685e"},
+    {file = "pydantic-1.10.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:c33602f93bfb67779f9c507e4d69451664524389546bacfe1bee13cae6dc7488"},
+    {file = "pydantic-1.10.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:5760e164b807a48a8f25f8aa1a6d857e6ce62e7ec83ea5d5c5a802eac81bad41"},
+    {file = "pydantic-1.10.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6eb843dcc411b6a2237a694f5e1d649fc66c6064d02b204a7e9d194dff81eb4b"},
+    {file = "pydantic-1.10.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4b8795290deaae348c4eba0cebb196e1c6b98bdbe7f50b2d0d9a4a99716342fe"},
+    {file = "pydantic-1.10.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:e0bedafe4bc165ad0a56ac0bd7695df25c50f76961da29c050712596cf092d6d"},
+    {file = "pydantic-1.10.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:2e05aed07fa02231dbf03d0adb1be1d79cabb09025dd45aa094aa8b4e7b9dcda"},
+    {file = "pydantic-1.10.2-cp39-cp39-win_amd64.whl", hash = "sha256:c1ba1afb396148bbc70e9eaa8c06c1716fdddabaf86e7027c5988bae2a829ab6"},
+    {file = "pydantic-1.10.2-py3-none-any.whl", hash = "sha256:1b6ee725bd6e83ec78b1aa32c5b1fa67a3a65badddde3976bca5fe4568f27709"},
+    {file = "pydantic-1.10.2.tar.gz", hash = "sha256:91b8e218852ef6007c2b98cd861601c6a09f1aa32bbbb74fab5b1c33d4a1e410"},
 ]
 pydocstyle = [
     {file = "pydocstyle-6.1.1-py3-none-any.whl", hash = "sha256:6987826d6775056839940041beef5c08cc7e3d71d63149b48e36727f70144dc4"},
     {file = "pydocstyle-6.1.1.tar.gz", hash = "sha256:1d41b7c459ba0ee6c345f2eb9ae827cab14a7533a88c5c6f7e94923f72df92dc"},
 ]
 pyflakes = [
-    {file = "pyflakes-2.4.0-py2.py3-none-any.whl", hash = "sha256:3bb3a3f256f4b7968c9c788781e4ff07dce46bdf12339dcda61053375426ee2e"},
-    {file = "pyflakes-2.4.0.tar.gz", hash = "sha256:05a85c2872edf37a4ed30b0cce2f6093e1d0581f8c19d7393122da7e25b2b24c"},
+    {file = "pyflakes-2.5.0-py2.py3-none-any.whl", hash = "sha256:4579f67d887f804e67edb544428f264b7b24f435b263c4614f384135cea553d2"},
+    {file = "pyflakes-2.5.0.tar.gz", hash = "sha256:491feb020dca48ccc562a8c0cbe8df07ee13078df59813b83959cbdada312ea3"},
 ]
-pygments = [
-    {file = "Pygments-2.12.0-py3-none-any.whl", hash = "sha256:dc9c10fb40944260f6ed4c688ece0cd2048414940f1cea51b8b226318411c519"},
-    {file = "Pygments-2.12.0.tar.gz", hash = "sha256:5eb116118f9612ff1ee89ac96437bb6b49e8f04d8a13b514ba26f620208e26eb"},
+Pygments = [
+    {file = "Pygments-2.13.0-py3-none-any.whl", hash = "sha256:f643f331ab57ba3c9d89212ee4a2dabc6e94f117cf4eefde99a0574720d14c42"},
+    {file = "Pygments-2.13.0.tar.gz", hash = "sha256:56a8508ae95f98e2b9bdf93a6be5ae3f7d8af858b43e02c5a2ff083726be40c1"},
 ]
 pylint = [
-    {file = "pylint-2.14.5-py3-none-any.whl", hash = "sha256:fabe30000de7d07636d2e82c9a518ad5ad7908590fe135ace169b44839c15f90"},
-    {file = "pylint-2.14.5.tar.gz", hash = "sha256:487ce2192eee48211269a0e976421f334cf94de1806ca9d0a99449adcdf0285e"},
+    {file = "pylint-2.15.2-py3-none-any.whl", hash = "sha256:cc3da458ba810c49d330e09013dec7ced5217772dec8f043ccdd34dae648fde8"},
+    {file = "pylint-2.15.2.tar.gz", hash = "sha256:f63404a2547edb5247da263748771ac9a806ed1de4174cda01293c08ddbc2999"},
 ]
 pymdown-extensions = [
     {file = "pymdown_extensions-9.5-py3-none-any.whl", hash = "sha256:ec141c0f4983755349f0c8710416348d1a13753976c028186ed14f190c8061c4"},
@@ -3580,8 +3721,8 @@ pyrepl = [
     {file = "pyrepl-0.9.0.tar.gz", hash = "sha256:292570f34b5502e871bbb966d639474f2b57fbfcd3373c2d6a2f3d56e681a775"},
 ]
 pytest = [
-    {file = "pytest-7.1.2-py3-none-any.whl", hash = "sha256:13d0e3ccfc2b6e26be000cb6568c832ba67ba32e719443bfe725814d3c42433c"},
-    {file = "pytest-7.1.2.tar.gz", hash = "sha256:a06a0425453864a270bc45e71f783330a7428defb4230fb5e6a731fde06ecd45"},
+    {file = "pytest-7.1.3-py3-none-any.whl", hash = "sha256:1377bda3466d70b55e3f5cecfa55bb7cfcf219c7964629b967c37cf0bda818b7"},
+    {file = "pytest-7.1.3.tar.gz", hash = "sha256:4f365fec2dff9c1162f834d9f18af1ba13062db0c708bf7b946f8a5c76180c39"},
 ]
 pytest-benchmark = [
     {file = "pytest-benchmark-3.4.1.tar.gz", hash = "sha256:40e263f912de5a81d891619032983557d62a3d85843f9a9f30b98baea0cd7b47"},
@@ -3636,18 +3777,18 @@ python-dateutil = [
     {file = "python_dateutil-2.8.2-py2.py3-none-any.whl", hash = "sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9"},
 ]
 pytz = [
-    {file = "pytz-2022.1-py2.py3-none-any.whl", hash = "sha256:e68985985296d9a66a881eb3193b0906246245294a881e7c8afe623866ac6a5c"},
-    {file = "pytz-2022.1.tar.gz", hash = "sha256:1e760e2fe6a8163bc0b3d9a19c4f84342afa0a2affebfaa84b01b978a02ecaa7"},
+    {file = "pytz-2022.2.1-py2.py3-none-any.whl", hash = "sha256:220f481bdafa09c3955dfbdddb7b57780e9a94f5127e35456a48589b9e0c0197"},
+    {file = "pytz-2022.2.1.tar.gz", hash = "sha256:cea221417204f2d1a2aa03ddae3e867921971d0d76f14d87abb4414415bbdcf5"},
 ]
 pytzdata = [
     {file = "pytzdata-2020.1-py2.py3-none-any.whl", hash = "sha256:e1e14750bcf95016381e4d472bad004eef710f2d6417240904070b3d6654485f"},
     {file = "pytzdata-2020.1.tar.gz", hash = "sha256:3efa13b335a00a8de1d345ae41ec78dd11c9f8807f522d39850f2dd828681540"},
 ]
 pyupgrade = [
-    {file = "pyupgrade-2.37.3-py2.py3-none-any.whl", hash = "sha256:9746efd064dbf53d7f86d6f88a1d48120f58dbfc378f517768634740ea2225e2"},
-    {file = "pyupgrade-2.37.3.tar.gz", hash = "sha256:1414c7a7c558004cf610e6180716b876814b639b5a5789c3da023c5cdaebcd49"},
+    {file = "pyupgrade-2.38.0-py2.py3-none-any.whl", hash = "sha256:e68e033603de3b4b675c7bd733723fb2bb7930a1898b6da61fb503643322e2f9"},
+    {file = "pyupgrade-2.38.0.tar.gz", hash = "sha256:7d03766fb5d68e9b0ec86b7d48c3cc29462b0031ff48ceece34bd224708553c0"},
 ]
-pyyaml = [
+PyYAML = [
     {file = "PyYAML-6.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d4db7c7aef085872ef65a8fd7d6d09a14ae91f691dec3e87ee5ee0539d516f53"},
     {file = "PyYAML-6.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9df7ed3b3d2e0ecfe09e14741b857df43adb5a3ddadc919a2d94fbdf78fea53c"},
     {file = "PyYAML-6.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:77f396e6ef4c73fdc33a9157446466f1cff553d979bd00ecb64385760c6babdc"},
@@ -3682,7 +3823,7 @@ pyyaml = [
     {file = "PyYAML-6.0-cp39-cp39-win_amd64.whl", hash = "sha256:b3d267842bf12586ba6c734f89d1f5b871df0273157918b0ccefa29deb05c21c"},
     {file = "PyYAML-6.0.tar.gz", hash = "sha256:68fb519c14306fec9720a2a5b45bc9f0c8d1b9c72adf45c37baedfcd949c35a2"},
 ]
-pyyaml-env-tag = [
+pyyaml_env_tag = [
     {file = "pyyaml_env_tag-0.1-py3-none-any.whl", hash = "sha256:af31106dec8a4d68c60207c1886031cbf839b68aa7abccdb19868200532c2069"},
     {file = "pyyaml_env_tag-0.1.tar.gz", hash = "sha256:70092675bda14fdec33b31ba77e7543de9ddc88f2e5b99160396572d11525bdb"},
 ]
@@ -3706,9 +3847,13 @@ rich = [
     {file = "rich-12.5.1-py3-none-any.whl", hash = "sha256:2eb4e6894cde1e017976d2975ac210ef515d7548bc595ba20e195fb9628acdeb"},
     {file = "rich-12.5.1.tar.gz", hash = "sha256:63a5c5ce3673d3d5fbbf23cd87e11ab84b6b451436f1b7f19ec54b6bc36ed7ca"},
 ]
+setuptools = [
+    {file = "setuptools-65.3.0-py3-none-any.whl", hash = "sha256:2e24e0bec025f035a2e72cdd1961119f557d78ad331bb00ff82efb2ab8da8e82"},
+    {file = "setuptools-65.3.0.tar.gz", hash = "sha256:7732871f4f7fa58fb6bdcaeadb0161b2bd046c85905dbaa066bdcbcc81953b57"},
+]
 setuptools-scm = [
-    {file = "setuptools_scm-7.0.5-py3-none-any.whl", hash = "sha256:7930f720905e03ccd1e1d821db521bff7ec2ac9cf0ceb6552dd73d24a45d3b02"},
-    {file = "setuptools_scm-7.0.5.tar.gz", hash = "sha256:031e13af771d6f892b941adb6ea04545bbf91ebc5ce68c78aaf3fff6e1fb4844"},
+    {file = "setuptools_scm-6.4.2-py3-none-any.whl", hash = "sha256:acea13255093849de7ccb11af9e1fb8bde7067783450cee9ef7a93139bddf6d4"},
+    {file = "setuptools_scm-6.4.2.tar.gz", hash = "sha256:6833ac65c6ed9711a4d5d2266f8024cfa07c533a0e55f4c12f6eff280a5a9e30"},
 ]
 six = [
     {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"},
@@ -3766,93 +3911,107 @@ tomli = [
     {file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"},
 ]
 tomlkit = [
-    {file = "tomlkit-0.11.2-py3-none-any.whl", hash = "sha256:69e0675671a2eed1c08a53f342c955c4ead5d373a10f756219bf39f3d4f0018a"},
-    {file = "tomlkit-0.11.2.tar.gz", hash = "sha256:d1b49c3e460f5910b22d799b13513504acb4f5fcaee01660ee66f07bd45a271c"},
+    {file = "tomlkit-0.11.4-py3-none-any.whl", hash = "sha256:25d4e2e446c453be6360c67ddfb88838cfc42026322770ba13d1fbd403a93a5c"},
+    {file = "tomlkit-0.11.4.tar.gz", hash = "sha256:3235a9010fae54323e727c3ac06fb720752fe6635b3426e379daec60fbd44a83"},
 ]
 transitions = [
-    {file = "transitions-0.8.11-py2.py3-none-any.whl", hash = "sha256:9525dd9b708b0a54bb4562a06a483d237e75c94547ba9831c81c6872d0ea1522"},
-    {file = "transitions-0.8.11.tar.gz", hash = "sha256:7b20d32906ea4d60ee6f6c1f5dc9c9f178802425c5b155213eb0f25c277f04e4"},
+    {file = "transitions-0.9.0-py2.py3-none-any.whl", hash = "sha256:5687ee8c6a3200830e44f988d16b0045f53293f7a873002d7bff70852331a078"},
+    {file = "transitions-0.9.0.tar.gz", hash = "sha256:2f54d11bdb225779d7e729011e93a9fb717668ce3dc65f8d4f5a5d7ba2f48e10"},
 ]
 typer = [
     {file = "typer-0.6.1-py3-none-any.whl", hash = "sha256:54b19e5df18654070a82f8c2aa1da456a4ac16a2a83e6dcd9f170e291c56338e"},
     {file = "typer-0.6.1.tar.gz", hash = "sha256:2d5720a5e63f73eaf31edaa15f6ab87f35f0690f8ca233017d7d23d743a91d73"},
 ]
 types-setuptools = [
-    {file = "types-setuptools-63.4.0.tar.gz", hash = "sha256:f954044034066cd3d8ceccc87e2d5cebe7a96c9f87996f61c3c6a92cd56cc8a4"},
-    {file = "types_setuptools-63.4.0-py3-none-any.whl", hash = "sha256:f568830d82b48783a0df00646bc84effeddb4886bf0f19708fbbadeb552b6ece"},
+    {file = "types-setuptools-65.3.0.tar.gz", hash = "sha256:c26779cbba3947823c260354adaab4e91ca8c18888aa2b740f503844b88f1813"},
+    {file = "types_setuptools-65.3.0-py3-none-any.whl", hash = "sha256:f69210049580939c70386252b776eb75ff4b6de488e7d766b9398669b7de68af"},
 ]
 typing-extensions = [
     {file = "typing_extensions-4.3.0-py3-none-any.whl", hash = "sha256:25642c956049920a5aa49edcdd6ab1e06d7e5d467fc00e0506c44ac86fbfca02"},
     {file = "typing_extensions-4.3.0.tar.gz", hash = "sha256:e6d2677a32f47fc7eb2795db1dd15c1f34eff616bcaf2cfb5e997f854fa1c4a6"},
 ]
 typing-inspect = [
-    {file = "typing_inspect-0.7.1-py2-none-any.whl", hash = "sha256:b1f56c0783ef0f25fb064a01be6e5407e54cf4a4bf4f3ba3fe51e0bd6dcea9e5"},
-    {file = "typing_inspect-0.7.1-py3-none-any.whl", hash = "sha256:3cd7d4563e997719a710a3bfe7ffb544c6b72069b6812a02e9b414a8fa3aaa6b"},
-    {file = "typing_inspect-0.7.1.tar.gz", hash = "sha256:047d4097d9b17f46531bf6f014356111a1b6fb821a24fe7ac909853ca2a782aa"},
+    {file = "typing_inspect-0.8.0-py3-none-any.whl", hash = "sha256:5fbf9c1e65d4fa01e701fe12a5bca6c6e08a4ffd5bc60bfac028253a447c5188"},
+    {file = "typing_inspect-0.8.0.tar.gz", hash = "sha256:8b1ff0c400943b6145df8119c41c244ca8207f1f10c9c057aeed1560e4806e3d"},
 ]
 ujson = [
-    {file = "ujson-5.4.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:511aa641a5b91d19280183b134fb6c473039d4dd82e987ac810cffba783521ac"},
-    {file = "ujson-5.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:b045ca5497a950cc3492840adb3bcb3b9e305ed6599ed14c6aeaa08011aa463f"},
-    {file = "ujson-5.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aa00b746138835271653b0c3da171d2a8b510c579381f71e8b8e03484d50d825"},
-    {file = "ujson-5.4.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:91edcf9978ee401119e9c8589376ae37fd3e6e75ee365c49385cb005eaff1535"},
-    {file = "ujson-5.4.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:05e411627e5d6ee773232960ca7307e66017f78e3fa74f7e95c3a8cc5cb05415"},
-    {file = "ujson-5.4.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:7d4c9ccd30e621e714ec24ca911ad8873567dc1ac1e5e914405ea9dd16b9d40c"},
-    {file = "ujson-5.4.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:dd0d4ec694cab8a0a4d85f45f81ae0065465c4670f0db72ba48d6c4e7ae42834"},
-    {file = "ujson-5.4.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:aaa77af91df3f71858a1f792c74d3f2d3abf3875f93ab1a2b9a24b3797743b02"},
-    {file = "ujson-5.4.0-cp310-cp310-win32.whl", hash = "sha256:fbea46c0fbc1c3bc8f957afd8dbb25b4ea3a356e18ee6dd79ace6cf32bd4cff7"},
-    {file = "ujson-5.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:2d98248f1df1e1aab67e0374ab98945dd36bc1764753d71fd8aea5f296360b76"},
-    {file = "ujson-5.4.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:f5c547d49a7e9d3f231e9323171bbbbcef63173fb007a2787cd4f05ac6269315"},
-    {file = "ujson-5.4.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:39bb702ca1612253b5e4b6004e0f20208c98a446606aa351f9a7ba5ceaff0eb8"},
-    {file = "ujson-5.4.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:381c97d326d1ec569d318cc0ae83940ea2df125ede1000871680fefd5b7fdea9"},
-    {file = "ujson-5.4.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3a0707f381f97e1287c0dbf94d95bd6c0bbf6e4eeeaa656f0076b7883010c818"},
-    {file = "ujson-5.4.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:6a20f2f6e8818c1ab89dd4be6bbad3fc2ddb15287f89e7ea35f3eb849afebbd9"},
-    {file = "ujson-5.4.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:8cd6117e33233f2de6bc896eea6a5a59b58a37db08f371157264e0ec5e51c76a"},
-    {file = "ujson-5.4.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:31bdb6d771d5ef6d37134b42211500bfe176c55d399f3317e569783dc42ed38e"},
-    {file = "ujson-5.4.0-cp37-cp37m-win32.whl", hash = "sha256:baa76a6f707a6d22437fe9c7ec9719672fb04d4d9435a3e80ee9b1aaeb2089d9"},
-    {file = "ujson-5.4.0-cp37-cp37m-win_amd64.whl", hash = "sha256:ee29cf5cfc1e841708297633e1ce749aa851fb96830bbe51f2e5940741ff2441"},
-    {file = "ujson-5.4.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:7e12272361e9722777c83b3f5b0bb91d402531f36e80c6e5fafb6acb89e897e3"},
-    {file = "ujson-5.4.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:3212847d3885bfd4f5fd56cdc37645a8f8e8a80d6cb569505da22fd9eb0e1a02"},
-    {file = "ujson-5.4.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0bcde3135265ecdd5714a7de4fdc167925390d7b17ca325e59980f4114c962b8"},
-    {file = "ujson-5.4.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0551c1ba0bc9e05b69d9c18266dbc93252b5fa3cd9940051bc88a0dd33607b19"},
-    {file = "ujson-5.4.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:13297a7d501f9c8c53e409d4fa57cc574e4fbfbe8807ef2c4c7ce2e3ec933a85"},
-    {file = "ujson-5.4.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:2974b17bc522ef86d98b498959d82f03c02e07d9eb08746026415298f4a4bca3"},
-    {file = "ujson-5.4.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:5df8b6369ee5ee2685fcc917f6c46b34e599c6e9a512fada6dfd752b909fa06a"},
-    {file = "ujson-5.4.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:754f422aba8db8201a1073f25e2f732effc6471f8755708b16e6ebf19dd23634"},
-    {file = "ujson-5.4.0-cp38-cp38-win32.whl", hash = "sha256:ea7fbc540bc04d5b05e5cd54e60ee8745ac665eedf2bad2ba9d12d5c7a7b7d2e"},
-    {file = "ujson-5.4.0-cp38-cp38-win_amd64.whl", hash = "sha256:8d472efa9c92e1b2933a22d2f1dbd5237087997136b24ac2b913bf4e8be03135"},
-    {file = "ujson-5.4.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:e2a9ddb5c6d1427056b8d62a1a172a18ae522b14d9ba5996b8281b09cba87edd"},
-    {file = "ujson-5.4.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:1120c8263f7d85e89533a2b46d80cc6def15114772010ede4d197739e111dba6"},
-    {file = "ujson-5.4.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:400e4ca8a59f71398e8fa56c4d2d6f535e2a121ddb57284ec15752ffce2dd63a"},
-    {file = "ujson-5.4.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e844be0831042aa91e847e5ab03bddd1089ab1a8dd0a1bf90411abf864f058b2"},
-    {file = "ujson-5.4.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0b46aee21e5d75426c4058dfdb42f7e7b1d130c664ee5027a8dbbc50872dc32b"},
-    {file = "ujson-5.4.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:326a96324ed9215b0bc9f1a5af324fb33900b6b0901516bcc421475d6596de0d"},
-    {file = "ujson-5.4.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:fd82932aaa224abd7d01e823b77aef9970f5ac1695027331d99e7f5fda9d37f5"},
-    {file = "ujson-5.4.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:8cce79ce47c37132373fbdf55b683883c262a3a60763130e080b8394c1201d32"},
-    {file = "ujson-5.4.0-cp39-cp39-win32.whl", hash = "sha256:191f88d5865740497b9827ef9b7c12f37a79872ac984e09f0901a10024019380"},
-    {file = "ujson-5.4.0-cp39-cp39-win_amd64.whl", hash = "sha256:68c7f753aec490c6566fd3cd301887c413ac3a588316e446f30a4134ac665668"},
-    {file = "ujson-5.4.0-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:1a2e645325f844f9c890c9d956fc2d35ca91f38c857278238ef6516c2f99cf7c"},
-    {file = "ujson-5.4.0-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cec010d318a0238b1333ea9f40d5603d374cc026c29c4471e2661712c6682da1"},
-    {file = "ujson-5.4.0-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b40a3757a563ef77c3f2f9ea1732c2924e8b3b2bda3fa89513f949472ad40b6e"},
-    {file = "ujson-5.4.0-pp37-pypy37_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:67f4e2fa81e1d99c01e7b1978ab0cbf3c9a8b663f683a709f87baad110d5b940"},
-    {file = "ujson-5.4.0-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:9ae1d0094ce730e39e09656bc14074d9573cdd80adec1a55b06d8bf1f9613a01"},
-    {file = "ujson-5.4.0-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:784dbd12925845a3f0757a956447e2fd31418abb5aeaebf3aca1203195f16fd1"},
-    {file = "ujson-5.4.0-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:422653083c6df6cec17fdb5d6106c209aad9b0c94131c53b073980403db22167"},
-    {file = "ujson-5.4.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e91947fda8354ea7faf698b084ebcdbabd239e7b15d8436fb74394f59a207ac9"},
-    {file = "ujson-5.4.0-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ef985eb2770900a485431910bd3f333b56d1a34b65f8c26a6ed8e8adf55f98d9"},
-    {file = "ujson-5.4.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:025758cf6561af6986d77cd4af9367ab56dde5c7c50f13f59e6964b4b25df73e"},
-    {file = "ujson-5.4.0.tar.gz", hash = "sha256:6b953e09441e307504130755e5bd6b15850178d591f66292bba4608c4f7f9b00"},
+    {file = "ujson-5.5.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ff4928dc1e9704b567171c16787238201fdbf023665573c12c02146fe1e02eec"},
+    {file = "ujson-5.5.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:1dc2f46c31ef22b0aaa28cd71be897bea271e700636658d573df9c43c49ebbd0"},
+    {file = "ujson-5.5.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6019e3480d933d3698f2ecb4b46d64bfadd64e718f04fac36e681f3254b49a93"},
+    {file = "ujson-5.5.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f5179088ef6487c475604b7898731a6ddeeada7702cfb2162155b016703a8475"},
+    {file = "ujson-5.5.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c04ae27e076d81a3839047d8eed57c1e17e361640616fd520d752375e3ba8f0c"},
+    {file = "ujson-5.5.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:60a4b481978ea2aad8fe8af1ecc271624d01b3cf4b09e9b643dd2fe19c07634c"},
+    {file = "ujson-5.5.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:7a09d203983104918c62f2eef9406f24c355511f9217967df23e70fa7f5b54ff"},
+    {file = "ujson-5.5.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:6b9812638d7aa8ecda2e8e1513fb4da999249603bffab7439a5f8f0bb362b0db"},
+    {file = "ujson-5.5.0-cp310-cp310-win32.whl", hash = "sha256:33cd9084fefc74cbacf88c92fd260b61211e00bcde38d640c369e5dc34a2b4e1"},
+    {file = "ujson-5.5.0-cp310-cp310-win_amd64.whl", hash = "sha256:765d46f3d5e7a1d48075035e2d1a9164f683e3fccde834ca04602e6c588835bc"},
+    {file = "ujson-5.5.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:278aa9d7cb56435c96d19f5d702e026bcf69f824e24b41e9b52706abd3565837"},
+    {file = "ujson-5.5.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:9585892091ae86045135d6a6129a644142d6a51b23e1428bb5de6d10bc0ce0c7"},
+    {file = "ujson-5.5.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9cdc46859024501c20ab74ad542cdf2f08b94b5ce384f2f569483fa3ed926d04"},
+    {file = "ujson-5.5.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d5bea13c73f36c4346808df3fa806596163a7962b6d28001ca2a391cab856089"},
+    {file = "ujson-5.5.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3f3f4240d99d55eb97cb012e9adf401f5ed9cd827af0341ac44603832202b0d2"},
+    {file = "ujson-5.5.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d93940664a5ccfd79f72dcb939b0c31a3479889f14f0eb95ec52976f8c0cae7d"},
+    {file = "ujson-5.5.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:880c84ce59f49776cf120f77e7ca04877c97c6887917078dbc369eb47004d7cf"},
+    {file = "ujson-5.5.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:977bf5be704a88d46bf5b228df8b44521b1f3119d741062191608b3a6a38f224"},
+    {file = "ujson-5.5.0-cp311-cp311-win32.whl", hash = "sha256:e0b36257dc90194784531c3b922d8d31fb2b4d8e5adfd27aff4eee7174176365"},
+    {file = "ujson-5.5.0-cp311-cp311-win_amd64.whl", hash = "sha256:a34a5f034b339f69ef7f6a134c22d04b92e07b6ddc1dd65382e7e4ec65d6437d"},
+    {file = "ujson-5.5.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:f26544bc10c83a2ff9aa2e093500c1b473f327faae31fb468d591e5823333376"},
+    {file = "ujson-5.5.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5fd797a4837ba10671954e7c09010cec7aca67e09d193f4920a16beea5f66f65"},
+    {file = "ujson-5.5.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7d7cfac2547c93389fa303fc0c0eb6698825564e8389c41c9b60009c746207b6"},
+    {file = "ujson-5.5.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f4875cafc9a6482c04c7df52a725d1c41beb74913c0ff4ec8f189f1954a2afe9"},
+    {file = "ujson-5.5.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:0762a4fdf86e01f3f8d8b6b7158d01fdd870799ff3f402b676e358fcd879e7eb"},
+    {file = "ujson-5.5.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:6c7ae6e0778ab9610f5e80e0595957d101ab8de18c32a8c053a19943ef4831d0"},
+    {file = "ujson-5.5.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:94874584b733a18b310b0e954d53168e62cd4a0fd9db85b1903f0902a7eb33e8"},
+    {file = "ujson-5.5.0-cp37-cp37m-win32.whl", hash = "sha256:3b74467564814fbce322427a5664e6bcc7dae6dbc8acbef76300fe43ca4072ab"},
+    {file = "ujson-5.5.0-cp37-cp37m-win_amd64.whl", hash = "sha256:59cdcd934385f36e8bd76aedc234371cc75c848d95bdce804ac8aa8744cfeffa"},
+    {file = "ujson-5.5.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:2e506ecf89b6b9d304362ccef770831ec242a52c89dab1b4aabf1ab0eb1d5ed6"},
+    {file = "ujson-5.5.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:10095160dbe6bba8059ad6677a01da251431f4c68041bf796dcac0956b34f8f7"},
+    {file = "ujson-5.5.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5035bb997d163f346c22abcec75190e7e756a5349e7c708bd3d5fd7066a9a854"},
+    {file = "ujson-5.5.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a7d12f2d2df195c8c4e49d2cdbad640353a856c62ca2c624d8b47aa33b65a2a2"},
+    {file = "ujson-5.5.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1a485117f97312bef45f5d79d2ff97eff4da503b8a04f3691f59d31141686459"},
+    {file = "ujson-5.5.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:21678d7e068707e4d54bdfeb8c250ebc548b51e499aed778b22112ca31a79669"},
+    {file = "ujson-5.5.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:5a9b1320d8363a42d857fae8065a2174d38217cdd58cd8dc4f48d54e0591271e"},
+    {file = "ujson-5.5.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:701e81e047f5c0cffd4ac828efca68b0bd270c616654966a051e9a5f836b385e"},
+    {file = "ujson-5.5.0-cp38-cp38-win32.whl", hash = "sha256:1cef44ea4973344baed3d50a5da4a8843de3a6af7dea7fadf0a594e53ce5892f"},
+    {file = "ujson-5.5.0-cp38-cp38-win_amd64.whl", hash = "sha256:e510d288e613d6927796dfb728e13e4530fc83b9ccac5888a21f7860486eab21"},
+    {file = "ujson-5.5.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:e1135264bcd40965cd35b0869e36952f54825024befdc7a923df9a7d83cfd800"},
+    {file = "ujson-5.5.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:703fd69d9cb21d6ec2086789df9be2cf8140a76ff127050c24007ea8940dcd3b"},
+    {file = "ujson-5.5.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:849f2ff40264152f25589cb48ddb4a43d14db811f841ec73989bfc0c8c4853fa"},
+    {file = "ujson-5.5.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bf416a93e1331820c77e3429df26946dbd4fe105e9b487cd2d1b7298b75784a8"},
+    {file = "ujson-5.5.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:593a0f6fb0e186c5ba65465ed6f6215a30d1efa898c25e74de1c8577a1bff6d0"},
+    {file = "ujson-5.5.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:7c20cc83b0df47129ec6ed8a47fa7dcfc309c5bad029464004162738502568bb"},
+    {file = "ujson-5.5.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:6f83be8257b2f2dd6dea5ee62cd28db90584da7a7af1fba77a2102fc7943638a"},
+    {file = "ujson-5.5.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:8141f654432cf75144d6103bfac2286b8adf23467201590b173a74535d6be22d"},
+    {file = "ujson-5.5.0-cp39-cp39-win32.whl", hash = "sha256:3fe1aea596f9539fc20cd9e52f098c842afc090168824fd4ca9744fe13151a03"},
+    {file = "ujson-5.5.0-cp39-cp39-win_amd64.whl", hash = "sha256:a655f7b755cfc5c07f2116b6dcf0ba148c89adef9a6d40c1b0f1fada878c4345"},
+    {file = "ujson-5.5.0-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:f19f11055ba2961eb39bdb1ff15763a53fca4fa0b5b624da3c7a528e83cdd09c"},
+    {file = "ujson-5.5.0-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7d87c817b292efb748f1974f37e8bb8a8772ef92f05f84e507159360814bcc3f"},
+    {file = "ujson-5.5.0-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5f9681ec4c60d0da590552427d770636d9079038c30b265f507ccde23caa7823"},
+    {file = "ujson-5.5.0-pp37-pypy37_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f63d1ae1ca17bb2c847e298c7bcf084a73d56d434b4c50509fb93a4b4300b0b2"},
+    {file = "ujson-5.5.0-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:95603eff711b8f3b9596e1c961dbeb745a792ba1904141612f194e07edd71e5f"},
+    {file = "ujson-5.5.0-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:2d90414e3b4b44b39825049185959488e084ea7fcaf6124afd5c00893938b09d"},
+    {file = "ujson-5.5.0-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7471d4486f23518cff343f1eec6c68d1b977ed74c3e6cc3e1ac896b9b7d68645"},
+    {file = "ujson-5.5.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ee9a2c9a4b2421e77f8fe33ed0621dea03c66c710707553020b1e32f3afb6240"},
+    {file = "ujson-5.5.0-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4a8cb3c8637006c5bd8237ebb5992a76ba06e39988ad5cff2096227443e8fd6a"},
+    {file = "ujson-5.5.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:d9c89c521dc90c7564358e525f849b93ad1d710553c1491f66b8cce8113bc901"},
+    {file = "ujson-5.5.0-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:2ab011e3556a9a1d9461bd686870c527327765ed02fe53550531d6609a8a33ff"},
+    {file = "ujson-5.5.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:603607f56a0ee84d9cd2c7e9b1d29b18a70684b94ee34f07b9ffe8dc9c8a9f81"},
+    {file = "ujson-5.5.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d75bef34e69e7effb7b4849e3f830e3174d2cc6ec7273503fdde111c222dc9b3"},
+    {file = "ujson-5.5.0-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:abfe83e082c9208891e2158c1b5044a650ecec408b823bf6bf16cd7f8085cafa"},
+    {file = "ujson-5.5.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:4ef4ab8352861b99bd7fedb1fc6df3ea7f7d5216c789ba6d859e4ea06f1a4c45"},
+    {file = "ujson-5.5.0.tar.gz", hash = "sha256:b25077a971c7da47bd6846a912a747f6963776d90720c88603b1b55d81790780"},
 ]
 urllib3 = [
-    {file = "urllib3-1.26.11-py2.py3-none-any.whl", hash = "sha256:c33ccba33c819596124764c23a97d25f32b28433ba0dedeb77d873a38722c9bc"},
-    {file = "urllib3-1.26.11.tar.gz", hash = "sha256:ea6e8fb210b19d950fab93b60c9009226c63a28808bc8386e05301e25883ac0a"},
+    {file = "urllib3-1.26.12-py2.py3-none-any.whl", hash = "sha256:b930dd878d5a8afb066a637fbb35144fe7901e3b209d1cd4f524bd0e9deee997"},
+    {file = "urllib3-1.26.12.tar.gz", hash = "sha256:3fa96cf423e6987997fc326ae8df396db2a8b7c667747d47ddd8ecba91f4a74e"},
 ]
 vcrpy = [
-    {file = "vcrpy-4.2.0-py2.py3-none-any.whl", hash = "sha256:7ec280c8d5385652f1117fe32a200e6676614007d9f946af9f07df1e5f92254c"},
-    {file = "vcrpy-4.2.0.tar.gz", hash = "sha256:94520b86fb765925adc8c77ff934e89a5e156c28e74a314320217ef1b454afe0"},
+    {file = "vcrpy-4.2.1-py2.py3-none-any.whl", hash = "sha256:efac3e2e0b2af7686f83a266518180af7a048619b2f696e7bad9520f5e2eac09"},
+    {file = "vcrpy-4.2.1.tar.gz", hash = "sha256:7cd3e81a2c492e01c281f180bcc2a86b520b173d2b656cb5d89d99475423e013"},
 ]
 virtualenv = [
-    {file = "virtualenv-20.16.3-py2.py3-none-any.whl", hash = "sha256:4193b7bc8a6cd23e4eb251ac64f29b4398ab2c233531e66e40b19a6b7b0d30c1"},
-    {file = "virtualenv-20.16.3.tar.gz", hash = "sha256:d86ea0bb50e06252d79e6c241507cb904fcd66090c3271381372d6221a3970f9"},
+    {file = "virtualenv-20.16.5-py3-none-any.whl", hash = "sha256:d07dfc5df5e4e0dbc92862350ad87a36ed505b978f6c39609dc489eadd5b0d27"},
+    {file = "virtualenv-20.16.5.tar.gz", hash = "sha256:227ea1b9994fdc5ea31977ba3383ef296d7472ea85be9d6732e42a91c04e80da"},
 ]
 vulture = [
     {file = "vulture-2.5-py2.py3-none-any.whl", hash = "sha256:a7c7e7a23b11e78840fdd821509d05a6134aa9fd60418fe39d60b3026fe698d9"},
@@ -3967,7 +4126,7 @@ xenon = [
     {file = "xenon-0.9.0.tar.gz", hash = "sha256:d2b9cb6c6260f771a432c1e588e51fddb17858f88f73ef641e7532f7a5f58fb8"},
 ]
 yamllint = [
-    {file = "yamllint-1.27.1.tar.gz", hash = "sha256:e688324b58560ab68a1a3cff2c0a474e3fed371dfe8da5d1b9817b7df55039ce"},
+    {file = "yamllint-1.28.0.tar.gz", hash = "sha256:9e3d8ddd16d0583214c5fdffe806c9344086721f107435f68bad990e5a88826b"},
 ]
 yarl = [
     {file = "yarl-1.8.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:abc06b97407868ef38f3d172762f4069323de52f2b70d133d096a48d72215d28"},
diff --git a/pyproject.toml b/pyproject.toml
index 5e378ce1..6a11731b 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -79,16 +79,14 @@ calcipy = "calcipy:run"
 
 [tool.poetry.dependencies]
 python = "^3.8.4"
-attrs = ">=21.4.0"
-attrs_strict = ">=1.0.0"
+arrow = ">=1.2.3"
 beartype = ">=0.10.4"    # dyce has nice no-op decorator for beartype, but shouldn't be optional
 bidict = ">=0.22.0"
 cement = ">=3.0.6"
 decorator = ">=5.1.1"
 loguru = ">=0.6.0"
 pandas = ">=1.3.5"
-pendulum = ">=2.1.2"
-punq = ">=0.6.2"
+pydantic = ">=1.10.2"
 python-box = ">=6.0.2"
 tabulate = ">=0.8.10"    # Required for pandas.to_markdown
 
@@ -124,7 +122,7 @@ autopep8 = { version = ">=1.5.5", optional = true }
 cohesion = { version = ">=1.0.0", optional = true }
 darglint = { version = ">=1.8.1", optional = true }
 dlint = { version = ">=0.12.0", optional = true }
-flake8 = { version = ">=4.0.1", optional = true }
+flake8 = { version = ">=5.0.4", optional = true }
 flake8-2020 = { version = ">=1.6.1", optional = true }
 flake8-aaa = { version = ">=0.12.2", optional = true }
 flake8-annotations = { version = ">=2.9.0", optional = true }


Test patch:
diff --git a/.test_calcipy_project/noxfile.py b/.test_calcipy_project/noxfile.py
index 37ad536e..599ab11b 100644
--- a/.test_calcipy_project/noxfile.py
+++ b/.test_calcipy_project/noxfile.py
@@ -1,3 +1,3 @@
 """nox-poetry configuration file."""
 
-from calcipy.dev.noxfile import build_check, build_dist, check_safety, coverage, tests  # noqa: F401
+from calcipy.dev.noxfile import build_check, build_dist, coverage, tests  # noqa: F401
diff --git a/calcipy/doit_tasks/test.py b/calcipy/doit_tasks/test.py
index a04a338f..547ecab4 100755
--- a/calcipy/doit_tasks/test.py
+++ b/calcipy/doit_tasks/test.py
@@ -4,7 +4,7 @@
 from doit.tools import Interactive
 
 from .base import debug_task, open_in_browser
-from .doit_globals import DG, DoitTask
+from .doit_globals import DoitTask, get_dg
 
 # ----------------------------------------------------------------------------------------------------------------------
 # Manage Testing with Nox
@@ -76,7 +76,7 @@ def task_test() -> DoitTask:
 
     """
     return debug_task([
-        Interactive(f'poetry run python -m pytest "{DG.test.path_tests}" {DG.test.args_pytest}'),
+        Interactive(f'poetry run python -m pytest "{get_dg().test.path_tests}" {get_dg().test.args_pytest}'),
     ])
 
 
@@ -89,7 +89,7 @@ def task_test_all() -> DoitTask:
 
     """
     return debug_task([
-        Interactive(f'poetry run python -m pytest "{DG.test.path_tests}" --ff -vv'),
+        Interactive(f'poetry run python -m pytest "{get_dg().test.path_tests}" --ff -vv'),
     ])
 
 
@@ -104,7 +104,11 @@ def task_test_marker() -> DoitTask:
 
     """
     task = debug_task(
-        [Interactive(f'poetry run python -m pytest "{DG.test.path_tests}" {DG.test.args_pytest} -m "%(marker)s"')],
+        [
+            Interactive(
+                f'poetry run python -m pytest "{get_dg().test.path_tests}" {get_dg().test.args_pytest} -m "%(marker)s"',
+            ),
+        ],
     )
     task['params'] = [{
         'name': 'marker', 'short': 'm', 'long': 'marker', 'default': '',
@@ -128,7 +132,9 @@ def task_test_keyword() -> DoitTask:
     """
     return {
         'actions': [
-            Interactive(f'poetry run python -m pytest "{DG.test.path_tests}" {DG.test.args_pytest} -k "%(keyword)s"'),
+            Interactive(
+                f'poetry run python -m pytest "{get_dg().test.path_tests}" {get_dg().test.args_pytest} -k "%(keyword)s"',
+            ),
         ],
         'params': [{
             'name': 'keyword', 'short': 'k', 'long': 'keyword', 'default': '',
@@ -149,20 +155,20 @@ def task_coverage() -> DoitTask:
         DoitTask: doit task
 
     """
-    path_tests = DG.test.path_tests
-    cov_dir = DG.test.path_coverage_index.parent
-    test_html = f'--html="{DG.test.path_test_report}" --self-contained-html'
-    diff_html = f'--html-report {DG.test.path_diff_test_report}'
+    path_tests = get_dg().test.path_tests
+    cov_dir = get_dg().test.path_coverage_index.parent
+    test_html = f'--html="{get_dg().test.path_test_report}" --self-contained-html'
+    diff_html = f'--html-report {get_dg().test.path_diff_test_report}'
     return debug_task([
         Interactive(
-            f'poetry run coverage run --source={DG.meta.pkg_name} --module'
-            f' pytest "{path_tests}" {DG.test.args_pytest} {test_html}',
+            f'poetry run coverage run --source={get_dg().meta.pkg_name} --module'
+            + f' pytest "{path_tests}" {get_dg().test.args_pytest} {test_html}',
         ),
         'poetry run python -m coverage report --show-missing',
         f'poetry run python -m coverage html --directory={cov_dir}',
         'poetry run python -m coverage json',  # Create coverage.json file for "_write_coverage_to_md"
         'poetry run python -m coverage xml',
-        Interactive(f'poetry run diff-cover coverage.xml {DG.test.args_diff} {diff_html}'),
+        Interactive(f'poetry run diff-cover coverage.xml {get_dg().test.args_diff} {diff_html}'),
     ])
 
 
@@ -179,7 +185,7 @@ def task_check_types() -> DoitTask:
 
     """
     return debug_task([
-        Interactive(f'poetry run mypy {DG.meta.pkg_name} --show-error-codes'),
+        Interactive(f'poetry run mypy {get_dg().meta.pkg_name} --show-error-codes'),
     ])
 
 
@@ -196,11 +202,11 @@ def task_open_test_docs() -> DoitTask:
 
     """
     paths = [
-        DG.test.path_test_report,
-        DG.test.path_diff_test_report,
-        DG.test.path_diff_lint_report,
-        DG.test.path_coverage_index,
-        DG.test.path_mypy_index,
+        get_dg().test.path_test_report,
+        get_dg().test.path_diff_test_report,
+        get_dg().test.path_diff_lint_report,
+        get_dg().test.path_coverage_index,
+        get_dg().test.path_mypy_index,
     ]
     return debug_task([(open_in_browser, (pth,)) for pth in paths if pth.is_file()])
 
@@ -221,7 +227,7 @@ def ptw_task(cli_args: str) -> DoitTask:
 
     """
     return {
-        'actions': [Interactive(f'poetry run ptw "{DG.meta.path_project}" {cli_args}')],
+        'actions': [Interactive(f'poetry run ptw "{get_dg().meta.path_project}" {cli_args}')],
         'verbosity': 2,
     }
 
diff --git a/tests/configuration.py b/tests/configuration.py
index b75534c3..b87d7438 100755
--- a/tests/configuration.py
+++ b/tests/configuration.py
@@ -6,7 +6,7 @@
 from decorator import contextmanager
 
 from calcipy import __pkg_name__
-from calcipy.doit_tasks.doit_globals import DG
+from calcipy.doit_tasks.doit_globals import create_dg, get_dg, set_dg
 from calcipy.file_helpers import delete_dir, ensure_dir
 from calcipy.log_helpers import activate_debug_logging
 
@@ -39,11 +39,9 @@ def clear_test_cache() -> None:
     ensure_dir(TEST_TMP_CACHE)
 
 
-# FIXME: Replace DG with a magic property that calls the punq-registered DG rather than this workaround
-#
 # Set the DoitGlobals instance to use the Test Project for all tests
-DG._is_set = False
-DG.set_paths(path_project=PATH_TEST_PROJECT)
+set_dg(create_dg(path_project=PATH_TEST_PROJECT))
+assert get_dg().meta.path_project == PATH_TEST_PROJECT
 
 
 @contextmanager
@@ -57,11 +55,10 @@ def _temp_dg(path_project: Path = PATH_TEST_PROJECT) -> Generator[None, None, No
         None: continues execution with DG set to the specified `path_project`
 
     """
-    path_original = DG.meta.path_project
+    path_original = get_dg().meta.path_project
     if path_original != path_project:
-        # FIXME: would be something like: container.register(TBD, instance=DG.set_paths(path_project=path_project))
-        DG._is_set = False
-        DG.set_paths(path_project=path_project)
+        set_dg(create_dg(path_project=path_project))
+        assert get_dg().meta.path_project == path_project
         yield
-        DG._is_set = False
-        DG.set_paths(path_project=path_original)
+        set_dg(create_dg(path_project=path_original))
+        assert get_dg().meta.path_project == path_original
diff --git a/tests/conftest.py b/tests/conftest.py
index 26e6164e..bec8839f 100644
--- a/tests/conftest.py
+++ b/tests/conftest.py
@@ -37,7 +37,7 @@ def __temp_chdir(path_tmp: Path) -> Generator[None, None, None]:
     > Not currently used because setting `cwd` for a modified version of `_get_all_files` is more robust
 
     ```python3
-    with _temp_chdir(DG.meta.path_project):
+    with _temp_chdir(get_dg().meta.path_project):
         print(f'Current in: {Path.cwd()}')
     ```
 
diff --git a/tests/dev/test_noxfile.py b/tests/dev/test_noxfile.py
index b1fc5b2c..33e9ecb7 100644
--- a/tests/dev/test_noxfile.py
+++ b/tests/dev/test_noxfile.py
@@ -1,6 +1,6 @@
 """Test noxfile."""
 
-from calcipy.dev.noxfile import build_check, build_dist, check_safety, coverage  # noqa: F401
+from calcipy.dev.noxfile import build_check, build_dist, coverage  # noqa: F401
 from calcipy.dev.noxfile import tests as nox_tests  # noqa: F401
 
 # WARN: the noxfile is only tested for imports
diff --git a/tests/test_code_tag_collector.py b/tests/test_code_tag_collector.py
index 613debf3..afdad77d 100644
--- a/tests/test_code_tag_collector.py
+++ b/tests/test_code_tag_collector.py
@@ -2,8 +2,6 @@
 
 import re
 
-import attrs
-
 from calcipy.code_tag_collector import CODE_TAG_RE, _CodeTag, _format_report, _search_lines, _Tags, write_code_tag_file
 
 from .configuration import PATH_TEST_PROJECT
@@ -35,7 +33,7 @@ def test_search_lines(assert_against_cache, benchmark):
     assert comments[0].lineno == 2
     assert comments[0].tag == 'FIXME'  # noqa: T100
     assert comments[0].text == 'Show README.md in the documentation (may need to update paths?)")'
-    assert_against_cache([*map(attrs.asdict, comments)])
+    assert_against_cache([comment.dict() for comment in comments])
 
 
 def test_format_report(assert_against_cache, benchmark, fake_process):
@@ -43,7 +41,10 @@ def test_format_report(assert_against_cache, benchmark, fake_process):
     fake_process.pass_command([fake_process.any()])  # Allow "git blame" and other commands to run unregistered
     fake_process.keep_last_process(True)
     lines = ['# DEBUG: Example 1', '# TODO: Example 2']  # noqa: T101
-    comments = [_CodeTag(lineno, *line.split('# ')[1].split(': ')) for lineno, line in enumerate(lines)]
+    comments = [
+        _CodeTag(lineno=lineno, **dict(zip(('tag', 'text'), line.split('# ')[1].split(': '))))
+        for lineno, line in enumerate(lines)
+    ]
     tagged_collection = [_Tags(path_source=PATH_TEST_PROJECT, code_tags=comments)]
     tag_order = ['TODO']  # noqa: T101
 
diff --git a/tests/test_doit_tasks/test_doc.py b/tests/test_doit_tasks/test_doc.py
index 04413593..80fdffa9 100644
--- a/tests/test_doit_tasks/test_doc.py
+++ b/tests/test_doit_tasks/test_doc.py
@@ -15,16 +15,16 @@
     _move_cl, _parse_var_comment, task_cl_bump, task_cl_bump_pre, task_cl_write,
     task_deploy_docs, task_document, task_open_docs, write_autoformatted_md_sections,
 )
-from calcipy.doit_tasks.doit_globals import DG
+from calcipy.doit_tasks.doit_globals import get_dg
 
 from ..configuration import TEST_DATA_DIR
 
 
 def test_move_cl():
     """Test _move_cl."""
-    path_cl = DG.meta.path_project / 'CHANGELOG.md'
+    path_cl = get_dg().meta.path_project / 'CHANGELOG.md'
     path_cl.write_text('# CHANGELOG')
-    path_cl_dest = DG.doc.doc_sub_dir / path_cl.name
+    path_cl_dest = get_dg().doc.doc_sub_dir / path_cl.name
 
     _move_cl()  # act
 
@@ -113,7 +113,7 @@ def test_format_cov_table():
         '| `calcipy/doit_tasks/code_tags.py` |           75 |        44 |          0 | 41.3%      |',
         '| **Totals**                        |           97 |        46 |          3 | 52.6%      |',
         '',
-        'Generated on: 2021-06-03T19:37:11.980123',
+        'Generated on: 2021-06-03',
     ]
 
 
@@ -122,13 +122,13 @@ def test_write_autoformatted_md_sections(fix_test_cache):
     path_md_file = TEST_DATA_DIR / 'sample_doc_files' / 'README.md'
     path_new_readme = fix_test_cache / path_md_file.name
     shutil.copyfile(path_md_file, path_new_readme)
-    (DG.meta.path_project / 'coverage.json').write_text(json.dumps(_COVERAGE_SAMPLE_DATA))
+    (get_dg().meta.path_project / 'coverage.json').write_text(json.dumps(_COVERAGE_SAMPLE_DATA))
     #
-    paths_original = DG.doc.paths_md
-    lookup_original = deepcopy(DG.doc.handler_lookup)
+    paths_original = get_dg().doc.paths_md
+    lookup_original = deepcopy(get_dg().doc.handler_lookup)
     #
-    DG.doc.paths_md = [path_new_readme]
-    DG.doc.handler_lookup = {
+    get_dg().doc.paths_md = [path_new_readme]
+    get_dg().doc.handler_lookup = {
         'SOURCE_FILE_TEST': _handle_source_file,
         'COVERAGE_TEST': _handle_coverage,
     }
@@ -140,8 +140,8 @@ def test_write_autoformatted_md_sections(fix_test_cache):
     assert '<!-- {cts} SOURCE_FILE_TEST=/tests/conftest.py; -->\n```py\n"""PyTest configuration."""\n' in text
     assert '<!-- {cts} COVERAGE_TEST -->\n| File                  ' in text
     #
-    DG.doc.paths_md = paths_original
-    DG.doc.handler_lookup = lookup_original
+    get_dg().doc.paths_md = paths_original
+    get_dg().doc.handler_lookup = lookup_original
 
 
 @pytest.mark.parametrize(
@@ -169,11 +169,11 @@ def test_write_autoformatted_md_sections_custom(fix_test_cache):
     path_new_readme = fix_test_cache / path_md_file.name
     shutil.copyfile(path_md_file, path_new_readme)
     #
-    paths_original = DG.doc.paths_md
-    lookup_original = deepcopy(DG.doc.handler_lookup)
+    paths_original = get_dg().doc.paths_md
+    lookup_original = deepcopy(get_dg().doc.handler_lookup)
     #
-    DG.doc.paths_md = [path_new_readme]
-    DG.doc.handler_lookup = {
+    get_dg().doc.paths_md = [path_new_readme]
+    get_dg().doc.handler_lookup = {
         'rating': _star_parser,
     }
 
@@ -187,8 +187,8 @@ def test_write_autoformatted_md_sections_custom(fix_test_cache):
 <!-- Capture image -->
 <!-- {cte} -->""" in text
     #
-    DG.doc.paths_md = paths_original
-    DG.doc.handler_lookup = lookup_original
+    get_dg().doc.paths_md = paths_original
+    get_dg().doc.handler_lookup = lookup_original
 
 
 def test_task_document():
diff --git a/tests/test_doit_tasks/test_doit_globals.py b/tests/test_doit_tasks/test_doit_globals.py
index 27bd3650..4a19977f 100644
--- a/tests/test_doit_tasks/test_doit_globals.py
+++ b/tests/test_doit_tasks/test_doit_globals.py
@@ -2,32 +2,14 @@
 
 from pathlib import Path
 
-from beartype.typing import List
-
-from calcipy.doit_tasks.doit_globals import DG, DocConfig, DoitGlobals
+from calcipy.doit_tasks.doit_globals import TestingConfig, create_dg, get_dg
 
 from ..configuration import PATH_TEST_PROJECT
 
 
-def _get_public_props(obj) -> List[str]:
-    """Return the list of public props from an object."""
-    return [prop for prop in dir(obj) if not prop.startswith('_')]
-
-
-def test_dg_props():
-    """Test the DG global variable from DoitGlobals."""
-    public_props = ['calcipy_dir', 'set_paths', 'meta', 'tags', 'lint', 'test', 'doc']
-
-    dg = DoitGlobals()  # act
-
-    assert _get_public_props(dg) == sorted(public_props)
-
-
 def test_dg_paths():
     """Test the DG global variable from DoitGlobals."""
-    dg = DoitGlobals()
-
-    dg.set_paths(path_project=PATH_TEST_PROJECT)  # act
+    dg = create_dg(path_project=PATH_TEST_PROJECT)  # act
 
     # Test the properties set by default
     assert dg.calcipy_dir.name == 'calcipy'
@@ -45,15 +27,18 @@ def test_path_attr_base_path_resolver():
     """Test the _PathAttrBase class."""
     base_path = Path().resolve()
 
-    doc = DocConfig(path_project=base_path)  # act
+    doc = TestingConfig(path_project=base_path)  # act
 
     assert doc.path_out.is_absolute()
 
 
 def test_doit_configurable():
     """Test configurable items from TOML file."""
-    dg = DG  # act
+    dg = get_dg()  # act
+
+    dg.meta._shorten_path_lists()
 
+    assert dg.meta.path_project.name == PATH_TEST_PROJECT.name
     assert dg.tags.tags == ['FIXME', 'TODO', 'PLANNED']  # noqa: T101, T103
     assert dg.tags.code_tag_summary_filename == 'CODE_TAG_SUMMARY.md'
     assert dg.test.path_out == PATH_TEST_PROJECT / 'releases/tests'
diff --git a/tests/test_doit_tasks/test_lint.py b/tests/test_doit_tasks/test_lint.py
index ad50a391..a4b519df 100644
--- a/tests/test_doit_tasks/test_lint.py
+++ b/tests/test_doit_tasks/test_lint.py
@@ -5,7 +5,7 @@
 import pytest
 
 from calcipy.doit_tasks.base import echo
-from calcipy.doit_tasks.doit_globals import DG
+from calcipy.doit_tasks.doit_globals import get_dg
 from calcipy.doit_tasks.lint import (
     _check_linting_errors, _lint_python, task_auto_format, task_lint_critical_only,
     task_lint_project, task_lint_python, task_pre_commit_hooks, task_radon_lint,
@@ -19,7 +19,7 @@ def test_lint_python():
     """Test _lint_python."""
     result = _lint_python(
         lint_paths=[PATH_TEST_PROJECT / 'test_file.py', PATH_TEST_PROJECT / 'tests/test_file_2.py'],
-        path_flake8=DG.lint.path_flake8,
+        path_flake8=get_dg().lint.path_flake8,
         ignore_errors=['F401', 'E800', 'I001', 'I003'],
     )
 
diff --git a/tests/test_doit_tasks/test_packaging.py b/tests/test_doit_tasks/test_packaging.py
index d8f00b78..ba571cb6 100644
--- a/tests/test_doit_tasks/test_packaging.py
+++ b/tests/test_doit_tasks/test_packaging.py
@@ -4,8 +4,8 @@
 import re
 from collections import defaultdict
 
+import arrow
 import loguru
-import pendulum
 import pytest
 
 from calcipy.doit_tasks.packaging import (
@@ -98,14 +98,14 @@ def test_find_stale_packages(fix_test_cache, monkeypatch):
     fake_pack_lock = {
         'z_package': {
             'name': 'z_package', 'version': '1.2.3',
-            'datetime': pendulum.now().to_iso8601_string(),
+            'datetime': str(arrow.now()),
         },
     }
     path_lock = fix_test_cache / 'poetry.lock'
     path_lock.write_text(fake_lock)
     path_pack_lock = fix_test_cache / _PATH_PACK_LOCK.name
     path_pack_lock.write_text(json.dumps(fake_pack_lock))
-    expected_err = r'Found stale packages that may be a dependency risk:\s+- \d+ months ago: twine 2\.0\.0[^\n]+'
+    expected_err = r'Found stale packages that may be a dependency risk:\s+- \d+ [^:]+ ago: twine 2\.0\.0[^\n]+'
     mock_logger = MockLogger()
     monkeypatch.setattr(loguru.logger, 'warning', mock_logger.warning)
 
@@ -122,8 +122,8 @@ def test_check_for_stale_packages():
     packages = [
         _HostedPythonPackage(
             name='twine',
-            datetime=pendulum.now(), version='1.11.0rc1',
-            latest_datetime=pendulum.now(), latest_version='1.11.0rc1',
+            datetime=arrow.now(), version='1.11.0rc1',
+            latest_datetime=arrow.now(), latest_version='1.11.0rc1',
         ),
     ]
 
diff --git a/tests/test_dot_dict.py b/tests/test_dot_dict.py
index 226a4cf9..94960f35 100644
--- a/tests/test_dot_dict.py
+++ b/tests/test_dot_dict.py
@@ -1,6 +1,6 @@
 """Test dot_dict."""
 
-import pendulum
+import arrow
 import pytest
 
 from calcipy.dot_dict import ddict
@@ -13,7 +13,7 @@
         ('number', -1.23),
         ('unicode', '✓'),
         ('is_bool', False),
-        ('datetime', pendulum.now()),
+        ('datetime', arrow.now()),
     ],
 )
 def test_ddict(key, value):
diff --git a/tests/test_file_search.py b/tests/test_file_search.py
index 20161161..6c3db0d0 100644
--- a/tests/test_file_search.py
+++ b/tests/test_file_search.py
@@ -1,6 +1,6 @@
 """Test file_search.py."""
 
-from calcipy.doit_tasks.doit_globals import DG
+from calcipy.doit_tasks.doit_globals import get_dg
 from calcipy.file_search import find_project_files_by_suffix
 
 
@@ -8,9 +8,9 @@ def test_find_project_files_by_suffix():
     """Test find_project_files_by_suffix."""
     expected_suffixes = ['', 'ini', 'js', 'json', 'lock', 'md', 'py', 'toml', 'yaml', 'yml']
 
-    result = find_project_files_by_suffix(DG.meta.path_project, DG.meta.ignore_patterns)
+    result = find_project_files_by_suffix(get_dg().meta.path_project, get_dg().meta.ignore_patterns)
 
-    assert len(result) != 0, f'Error: see {DG.meta.path_project}/README.md for configuring the directory'
+    assert len(result) != 0, f'Error: see {get_dg().meta.path_project}/README.md for configuring the directory'
     assert sorted(result.keys()) == expected_suffixes
     assert result[''][0].name == '.flake8'
-    assert result['md'][-1].relative_to(DG.meta.path_project).as_posix() == 'tests/data/README.md'
+    assert result['md'][-1].relative_to(get_dg().meta.path_project).as_posix() == 'tests/data/README.md'