diff --git a/.github/scripts/cleanup-tags.py b/.github/scripts/cleanup-tags.py index b89bd8ae0..9b299d048 100644 --- a/.github/scripts/cleanup-tags.py +++ b/.github/scripts/cleanup-tags.py @@ -249,10 +249,12 @@ class MainImageTagsCleaner(RegistryTagsCleaner): will be removed, if the corresponding branch no longer exists. """ + # Default to everything gets kept still + super().decide_what_tags_to_keep() + # Locate the feature branches feature_branches = {} for branch in self.branch_api.get_branches( - owner=self.repo_owner, repo=self.repo_name, ): if branch.name.startswith("feature-"): @@ -261,6 +263,10 @@ class MainImageTagsCleaner(RegistryTagsCleaner): logger.info(f"Located {len(feature_branches)} feature branches") + if not len(feature_branches): + # Our work here is done, delete nothing + return + # Filter to packages which are tagged with feature-* packages_tagged_feature: List[ContainerPackage] = [] for package in self.all_package_versions: diff --git a/.github/scripts/github.py b/.github/scripts/github.py index 63f34a1e9..b24e168f5 100644 --- a/.github/scripts/github.py +++ b/.github/scripts/github.py @@ -15,7 +15,7 @@ from typing import Dict from typing import List from typing import Optional -import requests +import httpx logger = logging.getLogger("github-api") @@ -28,15 +28,15 @@ class _GithubApiBase: def __init__(self, token: str) -> None: self._token = token - self._session: Optional[requests.Session] = None + self._client: Optional[httpx.Client] = None def __enter__(self) -> "_GithubApiBase": """ Sets up the required headers for auth and response type from the API """ - self._session = requests.Session() - self._session.headers.update( + self._client = httpx.Client() + self._client.headers.update( { "Accept": "application/vnd.github.v3+json", "Authorization": f"token {self._token}", @@ -49,14 +49,14 @@ class _GithubApiBase: Ensures the authorization token is cleaned up no matter the reason for the exit """ - if "Accept" in self._session.headers: - del self._session.headers["Accept"] - if "Authorization" in self._session.headers: - del self._session.headers["Authorization"] + if "Accept" in self._client.headers: + del self._client.headers["Accept"] + if "Authorization" in self._client.headers: + del self._client.headers["Authorization"] # Close the session as well - self._session.close() - self._session = None + self._client.close() + self._client = None def _read_all_pages(self, endpoint): """ @@ -66,7 +66,7 @@ class _GithubApiBase: internal_data = [] while True: - resp = self._session.get(endpoint) + resp = self._client.get(endpoint) if resp.status_code == 200: internal_data += resp.json() if "next" in resp.links: @@ -76,7 +76,7 @@ class _GithubApiBase: break else: logger.warning(f"Request to {endpoint} return HTTP {resp.status_code}") - break + resp.raise_for_status() return internal_data @@ -113,14 +113,15 @@ class GithubBranchApi(_GithubApiBase): def __init__(self, token: str) -> None: super().__init__(token) - self._ENDPOINT = "https://api.github.com/repos/{OWNER}/{REPO}/branches" + self._ENDPOINT = "https://api.github.com/repos/{REPO}/branches" - def get_branches(self, owner: str, repo: str) -> List[GithubBranch]: + def get_branches(self, repo: str) -> List[GithubBranch]: """ Returns all current branches of the given repository owned by the given owner or organization. """ - endpoint = self._ENDPOINT.format(OWNER=owner, REPO=repo) + # The environment GITHUB_REPOSITORY already contains the owner in the correct location + endpoint = self._ENDPOINT.format(REPO=repo) internal_data = self._read_all_pages(endpoint) return [GithubBranch(branch) for branch in internal_data] @@ -247,7 +248,7 @@ class GithubContainerRegistryApi(_GithubApiBase): """ Deletes the given package version from the GHCR """ - resp = self._session.delete(package_data.url) + resp = self._client.delete(package_data.url) if resp.status_code != 204: logger.warning( f"Request to delete {package_data.url} returned HTTP {resp.status_code}", @@ -266,7 +267,7 @@ class GithubContainerRegistryApi(_GithubApiBase): PACKAGE_VERSION_ID=package_data.id, ) - resp = self._session.post(endpoint) + resp = self._client.post(endpoint) if resp.status_code != 204: logger.warning( f"Request to delete {endpoint} returned HTTP {resp.status_code}", diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8e506c8aa..f075fbd9f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -139,7 +139,7 @@ jobs: - name: Get changed files id: changed-files-specific - uses: tj-actions/changed-files@v32 + uses: tj-actions/changed-files@v34 with: files: | src/** diff --git a/.github/workflows/cleanup-tags.yml b/.github/workflows/cleanup-tags.yml index 308b7f2ed..2b63b3000 100644 --- a/.github/workflows/cleanup-tags.yml +++ b/.github/workflows/cleanup-tags.yml @@ -64,9 +64,9 @@ jobs: with: python-version: "3.10" - - name: Install requests + name: Install httpx run: | - python -m pip install requests + python -m pip install httpx # # Clean up primary package # diff --git a/.github/workflows/installer-library.yml b/.github/workflows/installer-library.yml index 5569044e0..f761b0315 100644 --- a/.github/workflows/installer-library.yml +++ b/.github/workflows/installer-library.yml @@ -50,6 +50,11 @@ jobs: uses: actions/setup-python@v4 with: python-version: "3.9" + - + name: Install jq + run: | + sudo apt-get update + sudo apt-get install jq - name: Setup qpdf image id: qpdf-setup @@ -86,6 +91,18 @@ jobs: echo ${build_json} echo "jbig2enc-json=${build_json}" >> $GITHUB_OUTPUT + - + name: Setup other versions + id: cache-bust-setup + run: | + pillow_version=$(jq ".default.pillow.version" Pipfile.lock | sed 's/=//g' | sed 's/"//g') + lxml_version=$(jq ".default.lxml.version" Pipfile.lock | sed 's/=//g' | sed 's/"//g') + + echo "Pillow is ${pillow_version}" + echo "lxml is ${lxml_version}" + + echo "pillow-version=${pillow_version}" >> $GITHUB_OUTPUT + echo "lxml-version=${lxml_version}" >> $GITHUB_OUTPUT outputs: @@ -97,7 +114,11 @@ jobs: psycopg2-json: ${{ steps.psycopg2-setup.outputs.psycopg2-json }} - jbig2enc-json: ${{ steps.jbig2enc-setup.outputs.jbig2enc-json}} + jbig2enc-json: ${{ steps.jbig2enc-setup.outputs.jbig2enc-json }} + + pillow-version: ${{ steps.cache-bust-setup.outputs.pillow-version }} + + lxml-version: ${{ steps.cache-bust-setup.outputs.lxml-version }} build-qpdf-debs: name: qpdf @@ -145,3 +166,5 @@ jobs: REPO=${{ needs.prepare-docker-build.outputs.ghcr-repository }} QPDF_VERSION=${{ fromJSON(needs.prepare-docker-build.outputs.qpdf-json).version }} PIKEPDF_VERSION=${{ fromJSON(needs.prepare-docker-build.outputs.pikepdf-json).version }} + PILLOW_VERSION=${{ needs.prepare-docker-build.outputs.pillow-version }} + LXML_VERSION=${{ needs.prepare-docker-build.outputs.lxml-version }} diff --git a/Pipfile b/Pipfile index 62b70f12e..cf0e91c10 100644 --- a/Pipfile +++ b/Pipfile @@ -16,18 +16,18 @@ django-extensions = "*" django-filter = "~=22.1" djangorestframework = "~=3.13" filelock = "*" -fuzzywuzzy = {extras = ["speedup"], version = "*"} gunicorn = "*" imap-tools = "*" langdetect = "*" pathvalidate = "*" -pillow = "~=9.2" +pillow = "~=9.3" pikepdf = "*" python-gnupg = "*" python-dotenv = "*" python-dateutil = "*" python-magic = "*" psycopg2 = "*" +rapidfuzz = "*" redis = {extras = ["hiredis"], version = "*"} scikit-learn = "~=1.1" # Pin this until piwheels is building 1.9 (see https://www.piwheels.org/project/scipy/) diff --git a/Pipfile.lock b/Pipfile.lock index 2bb81496f..317a8cbda 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "5558c489e948de1779e547beae0dd36a2e551aa6be8505c26b651fd87eac2834" + "sha256": "f8bdb4da9007a887c66a7e0243c486419676aa1a053c9a78e3760abb1f60e0a0" }, "pipfile-spec": 6, "requires": {}, @@ -75,10 +75,10 @@ }, "automat": { "hashes": [ - "sha256:7979803c74610e11ef0c0d68a2942b152df52da55336e0c9d58daf1831cbdf33", - "sha256:b6feb6455337df834f6c9962d6ccf771515b7d939bca142b29c20c2376bc6111" + "sha256:c3164f8742b9dc440f3682482d32aaff7bb53f71740dd018533f9de286b64180", + "sha256:e56beb84edad19dcc11d30e8d9b895f75deeb5ef5e96b84a467066b3b84bb04e" ], - "version": "==20.2.0" + "version": "==22.10.0" }, "backports.zoneinfo": { "hashes": [ @@ -109,14 +109,6 @@ ], "version": "==3.6.4.0" }, - "bleach": { - "hashes": [ - "sha256:085f7f33c15bd408dd9b17a4ad77c577db66d76203e5984b1bd59baeee948b2a", - "sha256:0d03255c47eb9bd2f26aa9bb7f2107732e7e8fe195ca2f64709fcf3b0a4a085c" - ], - "index": "pypi", - "version": "==5.0.1" - }, "celery": { "extras": [ "redis" @@ -409,17 +401,6 @@ "index": "pypi", "version": "==1.2.0" }, - "fuzzywuzzy": { - "extras": [ - "speedup" - ], - "hashes": [ - "sha256:45016e92264780e58972dca1b3d939ac864b78437422beecebb3095f8efd00e8", - "sha256:928244b28db720d1e0ee7587acf660ea49d7e4c632569cad4f1cd7e68a5f0993" - ], - "index": "pypi", - "version": "==0.18.0" - }, "gunicorn": { "hashes": [ "sha256:9dcc4547dbb1cb284accfb15ab5667a0e5d1881cc443e0677b4882a4067a807e", @@ -630,114 +611,6 @@ "index": "pypi", "version": "==1.0.9" }, - "levenshtein": { - "hashes": [ - "sha256:019ae21de930d6077efa1eac746de4df5234e7c6c11ab10080c0935fc5abbecf", - "sha256:02688fff6d256afdd57da5359144ddab8e054b2ba98ddcf147fe191bdf996e88", - "sha256:0274b87df89d1dda8dce77cf05a9dfab7bd30045a09e0d9435ec8be622e374e6", - "sha256:0323e8dbeec4d63c27111796baa7e8a89b391c32d90e67d78f9404d0c8edeab4", - "sha256:053edbb52fe8b8a1a6698c4fee39590c9e44a602ace807291eb87e3b17f85f48", - "sha256:059027f5dd2aafb916301f46a619c7fe03ff5761cdb2d091cf80bf6dbc24bc29", - "sha256:05f11a4be4f668974238cff21208fbd9f629cab8a68b444b7d4a4cfd8081b1d6", - "sha256:0ab71cc5ea86f6685a7b2235edad65f1f2a4b6341109af259d758973d96eece5", - "sha256:0b439f4fb0b615bc0443cc83eaf5835bd480f680c69ed1be963bdb401b8159f8", - "sha256:0ec50d24a12e50857e94ac9035d3c06fd0827bb477b9ebcd83a2a49dd89e5e23", - "sha256:131fc50d52a52acc367ea8bccb028447b734243d00ba1cfc7d9ff8d0dc37fa38", - "sha256:17b5f1d1a4a5ac536283298c98cafc5632ae3897c8601fb2ec8babc6f47a1be9", - "sha256:183b8da9b870ad171a11a629c43e0587a228aea9d595a969231d59bf530b6c77", - "sha256:18888d50813b9df9b8dc8c1506ec40c783db25f130a6101eb89896b27076f751", - "sha256:25b88277832eb558305c3bb986ad61f19b5cb5a87aced289bce4a1701a92aa31", - "sha256:266cdab48e2242b6c010beb8b7af4164aa87f4ad8d6fbd9f4f531214f8ddb234", - "sha256:281bffb09b2e1620db4e99a9df96e38d939c341c7c43cd5191326fbdb4d42275", - "sha256:28cd002cf5a499e6e9bd69d992ffd501b8473948f3e97d6e075b774df1901e8e", - "sha256:2972c6c6a806e0c788f6ec39510abdb61b3a648fd141a5fa77becd2cc05ff551", - "sha256:2b4027b370cc46c4802ba32a979729209c0407d548723e809f19a50a9df27405", - "sha256:318c924e218be754427ce6bb4c630d9dcb5478eb00a8a3f8a0972086adc763b1", - "sha256:380accae56f8c9df99f34bc7e79d286fee37c3dd06b362c394b08ea96371b7c5", - "sha256:3c7784f9936292c9d3f92fc772d874edc071a16cd883ea0d997e5c4318f6362c", - "sha256:3ebd85fd6253abe89f852fc008294d490eb7a5f66913703148b8d263b048cc90", - "sha256:4126c8fe9d817ac3ab223ee5db41a09d0fa82dbd6bb59d207b6f7313d733f19b", - "sha256:4155f0ab246b6892110960f25989ab91073cd708b974f4732dca4d219a8be3e1", - "sha256:41f16267d8e6d916e06a6a1a0e151f643a6bab1277945a4bd494f359d4185dd2", - "sha256:4522f5d662d3ee55a072fad18e2af5dae480658d4e23b04b455c4b7542ce4327", - "sha256:46c900c807b0614c454ba89271ec6f59212403c54dc68ea493ab1ece2c510618", - "sha256:48291b25a904243f37c9aabbfed3eaba466c9a993f5f5946fe647163b7face07", - "sha256:5038a5e9e106087c117f0a7d6fd9d8a382b228da24bbd085b9f2b5d54ab11c3a", - "sha256:594a26bcf0cb720c16ac6db3fd4b3f411be756f9da7682f2f629089ff15aef18", - "sha256:59706135d3107939effe9f9263bd78c507f4abd7bfb96acc5a7f4176aa0a90d2", - "sha256:5a327d7581696c7a392a8f85cce7e54fa1303f5b79b3b2983abaab309b56cfd6", - "sha256:5eca8a45d38c916783c44e5da06a367b77234efa51d84dda8804654b99efecc9", - "sha256:5fa85f6789178ede5333568cbee5bac5fa9718d5f02406b65545e83368fa8fe9", - "sha256:65097e45ef7a942a9b92999b81d2e91fe80cbd0616215e625af39d2166692018", - "sha256:65cc9938cb9bd8862fc220e0719fd7f9c291d788f0a62bb8840820c46fa5a4d0", - "sha256:6a4c3607e2a0e66337d8ddf95ca7efe9b30ebf944119a4fb86503ea66f777263", - "sha256:72f11a136f148eb1218e7d1492749b8b5594302010db0cebd47423c4ac8c79ee", - "sha256:78b5a71de59e30c697a64c69fc48b032bb99c43b7437091b808a9ba20bb0235c", - "sha256:7b212edc9bf9d0c25cc3117483289b9e1a49a1ed134a02635baa987e9f0d89db", - "sha256:7e0f7045c420abdea249a28384baa846b87bad5c9f42af1957dc50c6e337fa1a", - "sha256:7e83cfec424f546dc3f0cc71896f8cc384a711f4116bc1abb0598302a9af3240", - "sha256:80c55bcc31d21bd07f7d1589e11f2ac1faf3359cf9f93026a1944ee76a40f954", - "sha256:863740d7f45adfd29b95658a680b16113721eaa89857c67e7e9573c61e87bbd8", - "sha256:88484b8c3f71dc9205d0d36da541e2cdcf4bc74474a2ee8d99c2e6411b659b89", - "sha256:8a08810e0bcc606d10cf1c5389c96fc92362244c0cf761358c495c2eb29df3dc", - "sha256:8c0637ae4fcb54d5c7fc9af24d348003b6f9dbaf7a06bf13f769d7b85903af39", - "sha256:8e9e3409338a42e3d4c30c224fdb678364542c77994f089fd6cc8131969eff48", - "sha256:902ea10ba85e014dc5d23a7bbb3ab70722349561e73783dd71571359e8867244", - "sha256:9533db74a2685169380db3db3ab59643453e7c486fffa9bf3ab60b73c4e174be", - "sha256:97f02ff49d1fa21308207a7743bec4fdd7aa90e8dd091539da660fc51e624c4d", - "sha256:9ea9a2a154dc7d8658930fa87cda0e6094235b5e130f037d9894eaf8722119a5", - "sha256:a0440d847b2c9986e4d27e8a59164714e5198530c69a5f9fb2e4620f9136d653", - "sha256:a6d39a27b542a781d691827b955d685d496fb6cccfc6eecc336a78b399032062", - "sha256:a7f4d3c478b1fcf412bf6c82914b02fed33ab359120df9172dda7bc855227461", - "sha256:ad297807bbdffce61b04e5e0c22f3c5d9e1905c1ee186f1f6d029f83bf0f18b8", - "sha256:add6778bb51efb80174937543754d2dfa0f4e504e7302d97896006a642c14f95", - "sha256:ae075ebf7bb5f48b3bd2fc9cd53346e4ff43e2515a4f822914bbc62a3cbd6e7e", - "sha256:b26fb439a7fbb522af63bbd781fbf51ec0c0659134a93f5bc8e9e68641df811e", - "sha256:b2bac59721d246939b21274229b9923aeae3db97b6118da739c658c17e110dd6", - "sha256:b314ad1f0667715e8d1b6197d5336ab579b13e801172721d62331bd40034a30c", - "sha256:b7317035875bd7c4705e2566848b2043b78e18f2f5675ea651f9f7805b5589eb", - "sha256:b8e936e620e5f336a207e08c0da9dace5d4dbcc8e64743ab1acaa77a64bbf060", - "sha256:b906da4e9a7ba4ec33ed2f7238343866932c1a6f84944c804252b2922708d0ee", - "sha256:ba690e4e33c360fcf0b8411ca90f8b9cc595e8deddd6a25a9a75a725b698cd6a", - "sha256:bb14da3d63da994c34cfa47cde469df8013ddf5f575455a22530c8c4a0ed8616", - "sha256:bbc2e1632f4a61fa171ddab3bc8368fb8475e7ce68733ca92fec862fdd8e0f60", - "sha256:bbdd3c896db09993b7879cd35e56da6ed8918d161d6e80f9d9c40d78d34e4784", - "sha256:bcaaa8e542cb7e1962d0a58ce6a25f6b4b6ca2e5ce743155fc1f6eb2fea52574", - "sha256:bee682ab1005aff597946234e47c95fcf0f44d2b1f38075f0aba26bbc4e7545a", - "sha256:bfec6543d60c57e7543d9cbccdd5dfcf562f2c05cd6b814df68108a20794e254", - "sha256:c2e50baf7be8831524a87beec6c1873539519a1948f907dc3d4b9be27ebacb80", - "sha256:c6c79a6138be017d85f3bab1df735669b669a38f9b3ff646a1f179afbacb7b63", - "sha256:c702fb7c8bfd87c9ce9c8bddfc9a5796a492bab35a52b1693adee413721e32f2", - "sha256:c9ba1725826f6571a6e4c1561bb1613711f0058b91927a147dc42c637ba087d9", - "sha256:cf205ac52cb6b45745c0a4891cdb6e709c10ad5b034aa736aff561fc4ce9828c", - "sha256:d0d03fc67499ee90feedfa2add4aaa1c091a7bf333535d847b10fffe390e58fe", - "sha256:d118d63f08fd6ac285cb8166e96c992a6ed0e7a1644e8790c39070b18779e688", - "sha256:d24c09f397c3ce55f20e0250da7ba5b0e5249cb5d21465e71ec15154a3a7e8e0", - "sha256:d41735c7a646dae8612e0552dfc53f45807eeb54364dfb1f0a65ac274bc56b3a", - "sha256:dd1696d91f2a37cece9bd22e507e7be7c37c59ecc61fd15f0d0f31e3b6888957", - "sha256:dfcad9c63a893c95ba1149481b9680ce68dd71211f08df0073ee62700790bc97", - "sha256:e384782608837d9aaf123e413679883091744664a2cd76f0ad0e0a1f12facc57", - "sha256:e5ea0abea338c617b753082f36f64c70ade853d88e91ab5732b301ae8ed16e3f", - "sha256:e6ff81c570413bcc35f1c16850eb66e2493a3259e68efe8672376533d2c82d38", - "sha256:e88951ad2831880405f3f055ab12a6aa72696c20a2815128eeccdc3bf914cd78", - "sha256:e98e16b6ce531b12100c01daac922e8ec5b991832a5f58003f13b7d45ea82dc0", - "sha256:eb0fd32e8e433797499571447d9f975b4744be79c0a3339413868d79517231ed", - "sha256:ee74a73e1f9e16b71f67329e99bb58aa4af9a2c3c4b3a5db9f26e92e7c39e161", - "sha256:f15ec5f825c283a5aa427d78759ab8f84e7b5441d15cfff476b548bce3764666", - "sha256:f296c7fe928ce0e29e313f85c43a5ab80542e096e1163c2605b8cc18aa2aff2b", - "sha256:f32df1b19f773bb41382e8b215955d248c9766e3d6ff5a1dd89709e7d96e4685", - "sha256:f3ed67279a4b317a808ac743d3a915f74187530c5f3d9c859e5d04d475b8c174", - "sha256:f5b972ca514898fb7131671c425a62ca38fdae2a8d6296e4b605ec8202349f8c", - "sha256:f961086c0dbba6c00cbd5c5b5646247efd0d0a4044444bfaa9efc7a6ba5e96a5", - "sha256:f9bd7d7a449667d6f17edd9045ec82a4ed2767afb91743d3d0b18c376a56dfe2", - "sha256:fbac4c8ffadb685189efa92fafdb2f5392e9cbd262eae3818bcdb1bd19acaaf2", - "sha256:fc43c8276d0a7c7b76f31d4f3f80f9eb820673628f1411770a70029c1d5f6a75", - "sha256:fcfded324f0710632e22050a2fd7b56b1cbcb2d21001630bcc26d536f54bffec", - "sha256:ff435abdcbfdf4a070f488830cd53aef77cf8649d0fd8ed76bf27d9566e80e78" - ], - "markers": "python_version >= '3.6'", - "version": "==0.20.7" - }, "lxml": { "hashes": [ "sha256:04da965dfebb5dac2619cb90fcf93efdb35b3c6994fea58a157a834f2f94b318", @@ -1028,69 +901,68 @@ }, "pillow": { "hashes": [ - "sha256:0030fdbd926fb85844b8b92e2f9449ba89607231d3dd597a21ae72dc7fe26927", - "sha256:030e3460861488e249731c3e7ab59b07c7853838ff3b8e16aac9561bb345da14", - "sha256:0ed2c4ef2451de908c90436d6e8092e13a43992f1860275b4d8082667fbb2ffc", - "sha256:136659638f61a251e8ed3b331fc6ccd124590eeff539de57c5f80ef3a9594e58", - "sha256:13b725463f32df1bfeacbf3dd197fb358ae8ebcd8c5548faa75126ea425ccb60", - "sha256:1536ad017a9f789430fb6b8be8bf99d2f214c76502becc196c6f2d9a75b01b76", - "sha256:15928f824870535c85dbf949c09d6ae7d3d6ac2d6efec80f3227f73eefba741c", - "sha256:17d4cafe22f050b46d983b71c707162d63d796a1235cdf8b9d7a112e97b15bac", - "sha256:1802f34298f5ba11d55e5bb09c31997dc0c6aed919658dfdf0198a2fe75d5490", - "sha256:1cc1d2451e8a3b4bfdb9caf745b58e6c7a77d2e469159b0d527a4554d73694d1", - "sha256:1fd6f5e3c0e4697fa7eb45b6e93996299f3feee73a3175fa451f49a74d092b9f", - "sha256:254164c57bab4b459f14c64e93df11eff5ded575192c294a0c49270f22c5d93d", - "sha256:2ad0d4df0f5ef2247e27fc790d5c9b5a0af8ade9ba340db4a73bb1a4a3e5fb4f", - "sha256:2c58b24e3a63efd22554c676d81b0e57f80e0a7d3a5874a7e14ce90ec40d3069", - "sha256:2d33a11f601213dcd5718109c09a52c2a1c893e7461f0be2d6febc2879ec2402", - "sha256:336b9036127eab855beec9662ac3ea13a4544a523ae273cbf108b228ecac8437", - "sha256:337a74fd2f291c607d220c793a8135273c4c2ab001b03e601c36766005f36885", - "sha256:37ff6b522a26d0538b753f0b4e8e164fdada12db6c6f00f62145d732d8a3152e", - "sha256:3d1f14f5f691f55e1b47f824ca4fdcb4b19b4323fe43cc7bb105988cad7496be", - "sha256:408673ed75594933714482501fe97e055a42996087eeca7e5d06e33218d05aa8", - "sha256:4134d3f1ba5f15027ff5c04296f13328fecd46921424084516bdb1b2548e66ff", - "sha256:4ad2f835e0ad81d1689f1b7e3fbac7b01bb8777d5a985c8962bedee0cc6d43da", - "sha256:50dff9cc21826d2977ef2d2a205504034e3a4563ca6f5db739b0d1026658e004", - "sha256:510cef4a3f401c246cfd8227b300828715dd055463cdca6176c2e4036df8bd4f", - "sha256:5aed7dde98403cd91d86a1115c78d8145c83078e864c1de1064f52e6feb61b20", - "sha256:69bd1a15d7ba3694631e00df8de65a8cb031911ca11f44929c97fe05eb9b6c1d", - "sha256:6bf088c1ce160f50ea40764f825ec9b72ed9da25346216b91361eef8ad1b8f8c", - "sha256:6e8c66f70fb539301e064f6478d7453e820d8a2c631da948a23384865cd95544", - "sha256:727dd1389bc5cb9827cbd1f9d40d2c2a1a0c9b32dd2261db522d22a604a6eec9", - "sha256:74a04183e6e64930b667d321524e3c5361094bb4af9083db5c301db64cd341f3", - "sha256:75e636fd3e0fb872693f23ccb8a5ff2cd578801251f3a4f6854c6a5d437d3c04", - "sha256:7761afe0126d046974a01e030ae7529ed0ca6a196de3ec6937c11df0df1bc91c", - "sha256:7888310f6214f19ab2b6df90f3f06afa3df7ef7355fc025e78a3044737fab1f5", - "sha256:7b0554af24df2bf96618dac71ddada02420f946be943b181108cac55a7a2dcd4", - "sha256:7c7b502bc34f6e32ba022b4a209638f9e097d7a9098104ae420eb8186217ebbb", - "sha256:808add66ea764ed97d44dda1ac4f2cfec4c1867d9efb16a33d158be79f32b8a4", - "sha256:831e648102c82f152e14c1a0938689dbb22480c548c8d4b8b248b3e50967b88c", - "sha256:93689632949aff41199090eff5474f3990b6823404e45d66a5d44304e9cdc467", - "sha256:96b5e6874431df16aee0c1ba237574cb6dff1dcb173798faa6a9d8b399a05d0e", - "sha256:9a54614049a18a2d6fe156e68e188da02a046a4a93cf24f373bffd977e943421", - "sha256:a138441e95562b3c078746a22f8fca8ff1c22c014f856278bdbdd89ca36cff1b", - "sha256:a647c0d4478b995c5e54615a2e5360ccedd2f85e70ab57fbe817ca613d5e63b8", - "sha256:a9c9bc489f8ab30906d7a85afac4b4944a572a7432e00698a7239f44a44e6efb", - "sha256:ad2277b185ebce47a63f4dc6302e30f05762b688f8dc3de55dbae4651872cdf3", - "sha256:adabc0bce035467fb537ef3e5e74f2847c8af217ee0be0455d4fec8adc0462fc", - "sha256:b6d5e92df2b77665e07ddb2e4dbd6d644b78e4c0d2e9272a852627cdba0d75cf", - "sha256:bc431b065722a5ad1dfb4df354fb9333b7a582a5ee39a90e6ffff688d72f27a1", - "sha256:bdd0de2d64688ecae88dd8935012c4a72681e5df632af903a1dca8c5e7aa871a", - "sha256:c79698d4cd9318d9481d89a77e2d3fcaeff5486be641e60a4b49f3d2ecca4e28", - "sha256:cb6259196a589123d755380b65127ddc60f4c64b21fc3bb46ce3a6ea663659b0", - "sha256:d5b87da55a08acb586bad5c3aa3b86505f559b84f39035b233d5bf844b0834b1", - "sha256:dcd7b9c7139dc8258d164b55696ecd16c04607f1cc33ba7af86613881ffe4ac8", - "sha256:dfe4c1fedfde4e2fbc009d5ad420647f7730d719786388b7de0999bf32c0d9fd", - "sha256:ea98f633d45f7e815db648fd7ff0f19e328302ac36427343e4432c84432e7ff4", - "sha256:ec52c351b35ca269cb1f8069d610fc45c5bd38c3e91f9ab4cbbf0aebc136d9c8", - "sha256:eef7592281f7c174d3d6cbfbb7ee5984a671fcd77e3fc78e973d492e9bf0eb3f", - "sha256:f07f1f00e22b231dd3d9b9208692042e29792d6bd4f6639415d2f23158a80013", - "sha256:f3fac744f9b540148fa7715a435d2283b71f68bfb6d4aae24482a890aed18b59", - "sha256:fa768eff5f9f958270b081bb33581b4b569faabf8774726b283edb06617101dc", - "sha256:fac2d65901fb0fdf20363fbd345c01958a742f2dc62a8dd4495af66e3ff502a4" + "sha256:03150abd92771742d4a8cd6f2fa6246d847dcd2e332a18d0c15cc75bf6703040", + "sha256:073adb2ae23431d3b9bcbcff3fe698b62ed47211d0716b067385538a1b0f28b8", + "sha256:0b07fffc13f474264c336298d1b4ce01d9c5a011415b79d4ee5527bb69ae6f65", + "sha256:0b7257127d646ff8676ec8a15520013a698d1fdc48bc2a79ba4e53df792526f2", + "sha256:12ce4932caf2ddf3e41d17fc9c02d67126935a44b86df6a206cf0d7161548627", + "sha256:15c42fb9dea42465dfd902fb0ecf584b8848ceb28b41ee2b58f866411be33f07", + "sha256:18498994b29e1cf86d505edcb7edbe814d133d2232d256db8c7a8ceb34d18cef", + "sha256:1c7c8ae3864846fc95f4611c78129301e203aaa2af813b703c55d10cc1628535", + "sha256:22b012ea2d065fd163ca096f4e37e47cd8b59cf4b0fd47bfca6abb93df70b34c", + "sha256:276a5ca930c913f714e372b2591a22c4bd3b81a418c0f6635ba832daec1cbcfc", + "sha256:2e0918e03aa0c72ea56edbb00d4d664294815aa11291a11504a377ea018330d3", + "sha256:3033fbe1feb1b59394615a1cafaee85e49d01b51d54de0cbf6aa8e64182518a1", + "sha256:3168434d303babf495d4ba58fc22d6604f6e2afb97adc6a423e917dab828939c", + "sha256:3dd6caf940756101205dffc5367babf288a30043d35f80936f9bfb37f8355b32", + "sha256:40e1ce476a7804b0fb74bcfa80b0a2206ea6a882938eaba917f7a0f004b42502", + "sha256:41e0051336807468be450d52b8edd12ac60bebaa97fe10c8b660f116e50b30e4", + "sha256:4390e9ce199fc1951fcfa65795f239a8a4944117b5935a9317fb320e7767b40f", + "sha256:502526a2cbfa431d9fc2a079bdd9061a2397b842bb6bc4239bb176da00993812", + "sha256:51e0e543a33ed92db9f5ef69a0356e0b1a7a6b6a71b80df99f1d181ae5875636", + "sha256:57751894f6618fd4308ed8e0c36c333e2f5469744c34729a27532b3db106ee20", + "sha256:5d77adcd56a42d00cc1be30843d3426aa4e660cab4a61021dc84467123f7a00c", + "sha256:655a83b0058ba47c7c52e4e2df5ecf484c1b0b0349805896dd350cbc416bdd91", + "sha256:68943d632f1f9e3dce98908e873b3a090f6cba1cbb1b892a9e8d97c938871fbe", + "sha256:6c738585d7a9961d8c2821a1eb3dcb978d14e238be3d70f0a706f7fa9316946b", + "sha256:73bd195e43f3fadecfc50c682f5055ec32ee2c933243cafbfdec69ab1aa87cad", + "sha256:772a91fc0e03eaf922c63badeca75e91baa80fe2f5f87bdaed4280662aad25c9", + "sha256:77ec3e7be99629898c9a6d24a09de089fa5356ee408cdffffe62d67bb75fdd72", + "sha256:7db8b751ad307d7cf238f02101e8e36a128a6cb199326e867d1398067381bff4", + "sha256:801ec82e4188e935c7f5e22e006d01611d6b41661bba9fe45b60e7ac1a8f84de", + "sha256:82409ffe29d70fd733ff3c1025a602abb3e67405d41b9403b00b01debc4c9a29", + "sha256:828989c45c245518065a110434246c44a56a8b2b2f6347d1409c787e6e4651ee", + "sha256:829f97c8e258593b9daa80638aee3789b7df9da5cf1336035016d76f03b8860c", + "sha256:871b72c3643e516db4ecf20efe735deb27fe30ca17800e661d769faab45a18d7", + "sha256:89dca0ce00a2b49024df6325925555d406b14aa3efc2f752dbb5940c52c56b11", + "sha256:90fb88843d3902fe7c9586d439d1e8c05258f41da473952aa8b328d8b907498c", + "sha256:97aabc5c50312afa5e0a2b07c17d4ac5e865b250986f8afe2b02d772567a380c", + "sha256:9aaa107275d8527e9d6e7670b64aabaaa36e5b6bd71a1015ddd21da0d4e06448", + "sha256:9f47eabcd2ded7698106b05c2c338672d16a6f2a485e74481f524e2a23c2794b", + "sha256:a0a06a052c5f37b4ed81c613a455a81f9a3a69429b4fd7bb913c3fa98abefc20", + "sha256:ab388aaa3f6ce52ac1cb8e122c4bd46657c15905904b3120a6248b5b8b0bc228", + "sha256:ad58d27a5b0262c0c19b47d54c5802db9b34d38bbf886665b626aff83c74bacd", + "sha256:ae5331c23ce118c53b172fa64a4c037eb83c9165aba3a7ba9ddd3ec9fa64a699", + "sha256:af0372acb5d3598f36ec0914deed2a63f6bcdb7b606da04dc19a88d31bf0c05b", + "sha256:afa4107d1b306cdf8953edde0534562607fe8811b6c4d9a486298ad31de733b2", + "sha256:b03ae6f1a1878233ac620c98f3459f79fd77c7e3c2b20d460284e1fb370557d4", + "sha256:b0915e734b33a474d76c28e07292f196cdf2a590a0d25bcc06e64e545f2d146c", + "sha256:b4012d06c846dc2b80651b120e2cdd787b013deb39c09f407727ba90015c684f", + "sha256:b472b5ea442148d1c3e2209f20f1e0bb0eb556538690fa70b5e1f79fa0ba8dc2", + "sha256:b59430236b8e58840a0dfb4099a0e8717ffb779c952426a69ae435ca1f57210c", + "sha256:b90f7616ea170e92820775ed47e136208e04c967271c9ef615b6fbd08d9af0e3", + "sha256:b9a65733d103311331875c1dca05cb4606997fd33d6acfed695b1232ba1df193", + "sha256:bac18ab8d2d1e6b4ce25e3424f709aceef668347db8637c2296bcf41acb7cf48", + "sha256:bca31dd6014cb8b0b2db1e46081b0ca7d936f856da3b39744aef499db5d84d02", + "sha256:be55f8457cd1eac957af0c3f5ece7bc3f033f89b114ef30f710882717670b2a8", + "sha256:c7025dce65566eb6e89f56c9509d4f628fddcedb131d9465cacd3d8bac337e7e", + "sha256:c935a22a557a560108d780f9a0fc426dd7459940dc54faa49d83249c8d3e760f", + "sha256:dbb8e7f2abee51cef77673be97760abff1674ed32847ce04b4af90f610144c7b", + "sha256:ebf2029c1f464c59b8bdbe5143c79fa2045a581ac53679733d3a91d400ff9efb", + "sha256:f1ff2ee69f10f13a9596480335f406dd1f70c3650349e2be67ca3139280cade0" ], "index": "pypi", - "version": "==9.2.0" + "version": "==9.3.0" }, "pluggy": { "hashes": [ @@ -1223,13 +1095,6 @@ "index": "pypi", "version": "==0.5.0" }, - "python-levenshtein": { - "hashes": [ - "sha256:88a58b95e3340a918489dac0c78f731323c0a4d8f5564f839ffea80155574e77", - "sha256:9228af5523f797f0798f045dc4a95ed1f46df72bc2186e52b530a33998a51b37" - ], - "version": "==0.20.7" - }, "python-magic": { "hashes": [ "sha256:c1ba14b08e4a5f5c31a302b7721239695b2f0f058d125bd5ce1ee36b9d9d3c3b", @@ -1240,10 +1105,10 @@ }, "pytz": { "hashes": [ - "sha256:335ab46900b1465e714b4fda4963d87363264eb662aab5e65da039c25f1f5b22", - "sha256:c4d88f472f54d615e9cd582a5004d1e5f624854a6a27a6211591c251f22a6914" + "sha256:222439474e9c98fced559f1709d89e6c9cbf8d79c794ff3eb9f8800064291427", + "sha256:e89512406b793ca39f5971bc999cc538ce125c0e51c27941bef4568b460095e2" ], - "version": "==2022.5" + "version": "==2022.6" }, "pytz-deprecation-shim": { "hashes": [ @@ -1309,111 +1174,98 @@ }, "rapidfuzz": { "hashes": [ - "sha256:036f904bcac16d726273eee7ec0636978af31d151f30c95b611240e22592ab79", - "sha256:0429a7a51d1372afaca969ee3170f9975f2fe6e187b485aeef55d3e8d7d934e0", - "sha256:09de4fd3dbcc73f61b85af006372f48fee7d4324de227702b9da0d2572445d26", - "sha256:0c8a5e65cab629ca5bb4b1d2b410f8444384b60364ab528508200acfdf9e659d", - "sha256:0e64ab58b19866ad3df53e651a429871d744f8794cca25c553396b25d679a1ac", - "sha256:0f09ff49b28e557615a9ad4d5eedbfd5b886fccb3ec35d85dd34c51348c4bf98", - "sha256:12e14b0c43e3bc0c679ef09bfcbcaf9397534e03b8854c417086779a79e08bb2", - "sha256:134a467692216e05a8806efe40e3bcae9aa81b9e051b209a4244b639a168c78e", - "sha256:13ce1019ddce7419502fac43b62ac166d3d6d290b727050e3de5bda79a6beb59", - "sha256:16a2edf3ea888c9d3582761a2bbaa734e03f6db25d96e73edd4dcef6883897ee", - "sha256:17ba5fb474515356608cdb8d750f95c12f3e4dc9a0e2c9d7caca3d4cee55048e", - "sha256:2183fc91971c0853f6170225577d24d81b865d416104b433de53e55a6d2a476a", - "sha256:24569412e1aac1ac008548cdcd40da771e14467f4bacab9f9abfe5bbb5dfe8be", - "sha256:254d5a800de54c416fa9b220e442a4861b272c1223139ae3dee0aea1c9f27c9c", - "sha256:2bc3ec87df5eaad59e6e02e6517047fb268a48866f3531c4b8b59c2c78069fe5", - "sha256:2d3652804ae17920eaa965b1e057ee0ea32d5bb02f50147c82a1d350a86fc3f1", - "sha256:30773e23bebe27ddcf7644d6ebb143bf7c9adeb18019a963172174ef522c0831", - "sha256:3b6573607568438dfc3d4341b0b00d326ac2cf86281df97e7f8c0348e2f89b5e", - "sha256:3d50a2ca8cd1cea13afd2ff8e052ba49860c64cc3e617398670fd6a8d11e450f", - "sha256:3f1c030e2d61d77cb14814640618e29cf13e4554340a3baa9191d162a4dfcd9e", - "sha256:40e8d37d67a6e4713ddb6053eb3007a3ca15eddd23f2e4a5039c39e666c10b3a", - "sha256:41c9e2acfa25c7667b70913d63887f76e981badc1e95a2878257d28b96f5a10c", - "sha256:42d18db6f7e1e6ef85a8e673b2fa3352727cc56e60e48e7c9268fe0286ab9f91", - "sha256:475aacad5d5c4f9ad920b4232cc196d79a1777fe1eada9122103c30154d18af4", - "sha256:47e163d6a6676be9a3a7e93d5a2c3c65a43c1530b680903ebdba951e07ee7999", - "sha256:5080ad715e39b8a2d82339cf4170785e9092c7625ec2095ff3590fdb0a532a41", - "sha256:52639268dffc8900892a5e57964228fb187512b0f249de9a45ba37c6f2bc52a5", - "sha256:54264d70af59224d6874fcc5828da50d99668055574fe254849cab96f3b80e43", - "sha256:553e8e3dce321ed33e8b437586e7765d78e6d8fbb236b02768b46e1b2b91b41e", - "sha256:56aa67bf938e8dcc5e940f183538f09041441f1c4c5a86abe748416950db9d27", - "sha256:578934d7524f8378175295e6411b737d35d393d91d4661c739daa8ea2b185836", - "sha256:588dd5f520683af53a9d9d0cabde0987788c0ea9adfda3b058a9c27f448b2b3f", - "sha256:5aff0ac1723f7c8d751869a51e6b12d703fd6e6153228d68d8773f19bd5bd968", - "sha256:5e3164736ed071dc743994b9228ead52b63010aba24b1621de81b3ac39d490b9", - "sha256:5e89f50f5f3be2b851e9714015e1a26c6546e6b42f3df69b86200af8eacf9d8c", - "sha256:61152fa1e3df04b4e748f09338f36ca32f7953829f4e630d26f7f564f4cb527b", - "sha256:64133c9f45cb88b508d52427339b796c76e1790300c7ea4d2ed210f224e0698d", - "sha256:65b8611c9f5385a2986e11e85137cdecf40610e5d5f250d96a9ed32b7e995c4a", - "sha256:6803ef01f4056d61120e37acba8953e6b3149363e85caaba40ee8d49753fe7bd", - "sha256:68d46ad148c9cb8be532b5dd7bc246b067e81d4cfabad19b4cb6ac4031cab124", - "sha256:6b12420d5b769cd7e1478a8085aeea1ad0ffc8f7fedc86c48b8d598e1602f5ad", - "sha256:705ccd8de2b7b5295c6a230a3919fc9db8da9d2a6347c15c871fcb2202abd237", - "sha256:7478341137e65a0227fda4f3e39b3d50e6ec7dd4f767077dd435b412c2f2c129", - "sha256:769cf4099f53507231ba04cbf9ee16bea3c193767efc9bdf5e6c59e67e6b5cea", - "sha256:7750b950a6987bce114b9f36413399712422f4f49b2ad43f4b4ee3af34968b99", - "sha256:7c457f779992a0f5527455cdc17c387268ae9f712d4e29d691704c83c6e58c2d", - "sha256:7dd6a439fb09dc9ba463de3f5c8e20f097225816b33a66380b68c8561a08045c", - "sha256:804c7c67dc316f77b01b9bef5e75f727b73ff1015ff0514972b59dc05eec4d81", - "sha256:86038b9777b2aa0ebf8c586b81cba166ccde7e6d744aad576cd98c1a07be4c53", - "sha256:86c34175830cacac1c16d2182a0f725afbd40042955b7572c8475e3b6a5d8ada", - "sha256:8a11b70ebb2d7317d69bdb1f692a0eda292a4cddfe9ccb760a8d1a9e763811dd", - "sha256:8b402e99593483a8b05a09fb2a20379ecaa9b0d1f1cf32957b42134bd3305731", - "sha256:8b480a78227457a0b65e0b23afbda9c152dee4e1b41ccc058db8c41ea7a82ab0", - "sha256:8bc00bd6b6407dc7a8eb31964bcc38862c25e7f5f5982f912f265eb3c4d83140", - "sha256:8d6fa1d009fcb9a9169548c29d65a1f05c0fcf1ac966f40e35035307d6a17050", - "sha256:9081542fea2baeebda8caa43a54ecd8a152a05ff3271c38ac8eae447377cef54", - "sha256:931a939ba5e5574f769507038fdf400dbbc46aab2866d4e5e96d83a29f081712", - "sha256:984d40ecda0bc0109c4239d782dfe87362d02b286548672f8a2468eabbf48a69", - "sha256:9924497dec6a30b5158ef7cc9c60a87c6c46d9f7b7bb7254d4f157b57b531fb8", - "sha256:a48ff6b6258a32f50f876a6c74fa2f506c1de3b11773d6bf31b6715255807a48", - "sha256:a7f5a77466c4701062469bce29358ca0797db2bc6d8f6c3cd4e13f418cca10bc", - "sha256:a98c63d1f5ec2c15adf5dc81c461c8d88c16395956f4518b78e2e04b3285b1e5", - "sha256:adc7c6cb3dde5c284d84c7c6f4602b1545ba89c6ebb857b337d0428befb344e5", - "sha256:b4f577ded3e40695d5e0796e8b7f4fa78577d873627e0d0692f7060ad73af314", - "sha256:b5c7b0a4929bfd3945d9c2022cff0b683a39accf5594897fa9004cee4f402b06", - "sha256:b5cd1ea9fa396243d34f7bac5bb5787f89310f13fd2b092d11940c6cd7bd0bd8", - "sha256:bafd18a27dbe3197e460809468a7c47d9d29d1ebab6a878d5bb5a71fda2056d6", - "sha256:bd595bd23a4e1c72d5f5ac416ea49b9a3d87e11fb2db4b960378038ce9bb12f7", - "sha256:bd7a1992e91c90197c34ccc674bd64262262627083c99896b79e2c9f5fe28075", - "sha256:bd8f36d8bd399c7d695182e467b4428adb940a157014ab605bbe4d0ab0a1976e", - "sha256:bf5277ff74c9980245697ea227057d0f05b31c96bc73bae2697c1a48d4980e45", - "sha256:bfabc6130752f4f77584b2ecbba2adf6fe469b06c52cb974ba8304f1f63bb24f", - "sha256:c10724490b87fcb86161e5ceb17893626d13363e31efee77aa8e251ee16dcdd5", - "sha256:c1477455b82d6db7336ef769f507a55bba9fe9f1c96dc531d7c2c510630307d6", - "sha256:c288e239fc3aaae3865e43e1f35b606f92ee687a0801e4d46c45d7849aebbe35", - "sha256:c305ea5405f8615e6ecd39cb28acc7a362713ba3c17c7737b591b377d1afd9ec", - "sha256:c77cec595dc80f97a1b32413fb1b618e4da8ba132697e075ad8e4025c4058575", - "sha256:c822853e9d54979eb5fcf9e54c1f90e5c18eeb399571383ac768cff47d6d6ada", - "sha256:cad5088f1adb9161f2def653908328cfa1dc9bc57e7e41ccdc9339d31cc576d1", - "sha256:cc3103e31d27352afe4c5a71702e09185850187d299145d5e98f9fb99a3be498", - "sha256:ced719fcae6f2a348ac596b67f6d7c26ff3d9d2b7378237953ac5e162d8a4e2e", - "sha256:d181889218d80f6beb5ae3838bc23e201d2a1fae688baaa40d82ef9080594315", - "sha256:d1d8192820d8489a8e3ef160cbe38f5ff974db5263c76438cf44e7574743353b", - "sha256:d24181dfdfcc3d9b37333fea2f5bf9f51e034bd9e0ba67a871f18686b797c739", - "sha256:d51b9183ebce60d4795ceaef24b8db2df3ed04307ee787d6adafcc196330a47c", - "sha256:dad6697c6b9e02dd45f73e22646913daad743afd27dadb0b6a430a1573fb4566", - "sha256:dafe8c6e74fea0fdcfec002bc77aee40b4891b14ea513e6092402609ac8dac00", - "sha256:dc0f695b32700b14f404cccaebc25eea6db323418385568297995aee8b5278f8", - "sha256:e2fe220d4b100b00734d9388e33296ac8f585c763548c372ca17b24affa178e0", - "sha256:e459287f0daaee3ee0108123d7e9a1c1c136e94d4382533a93cb509d54dc1ea3", - "sha256:ea4107a5cc00a05c92be47047662000296d2ccc7ba93aaa030cd5ecab8d5ffaf", - "sha256:ea4f0d056a95cfdabde667a1796f9ba5296d2776bce2fd4d4cb5674e0e10671f", - "sha256:ea5bc5bae1cf447b79be04f05e73b6ea39a5df63374f70cc5d6862337462d4d9", - "sha256:ecfe2fe942edabcd1553701237710de296d3eb45472f9128662c95da98e9ed43", - "sha256:eec5ad2f06701e57a2cb483c849704bdf8ea76195918550ab2fc4287970f1c76", - "sha256:f2f91b867d7eca3b99c25e06e7e3a6f84cd4ccb99f390721670ba956f79167c9", - "sha256:f5ed8d4e1545f08bd3745cc47742b3689f1a652b00590caeb32caf3297d01e06", - "sha256:f6e6395404b0239cff7873a18a94839343a44429624f2a70a27b914cc5059580", - "sha256:f71edc8503d08bc5d35187eb72f13b7ec78647f1c14bb90a758ae795b049f788", - "sha256:f72d33b0d76a658d8b692b3e42c45539939bac26ff5b71b516cb20fa6d8ff7f6", - "sha256:f9226824c132d38f2337d2c76e3009acc036f0b05f20e95e82f8195400e1e366", - "sha256:faba219b270b78e9494cfe3d955d7b45c10799c18ee47ec24b1ada93978d491b" + "sha256:028aa9edfa044629a0a9e924a168a01f61c8f570c9ea919e2ed214826ba1cdfb", + "sha256:02a5c8b780af49a4e5f08033450d3f7c696f6c04e57c67ecbb19c9944ea3ce20", + "sha256:07c623741958dd49d8c2c51f7c2e62472f41b8d795cc9c734e441e30de3f8330", + "sha256:0ae8c0c2f51f618d54579341c44ba198849d9cd845bb0dc85d1711fd8de9a159", + "sha256:129c93a76c4fed176b4eaaf78fecd290932971bca10315dee9feaf94a7b443b1", + "sha256:13ad87a539b13794292fb661b8c4f4c19e6c066400d9db991e3a1441f55fc29b", + "sha256:16426b441d28efb3b1fe10f2b81aa469020655cef068a32de6ec24433590ee5b", + "sha256:1a600b037a56a61111c01809b5e4c4b5aac12edf2769c094fefab02d496a95a4", + "sha256:1e0f6f878c20454a7e7ea2ed30970ae0334852c5e422e7014757821fa33c1588", + "sha256:20f2f0f0746ffc165168ca160c5b1a1485076bdde5b656cf3dbe532ef2ac57ff", + "sha256:2207927f42ae7b7fbcc1a4ff86f202647776200f3d8723603e7acf96af924e9f", + "sha256:22487992f4811c8aef449736f483514f0294d5593f5f9c95cbfb2474dbc363b9", + "sha256:22646f54d44d98d6f462fb3f1ac997ea53aaebdd1344039e8f75090f43e47a89", + "sha256:22e8b127abcf0b10ebf8a9b3351c3c980e5c27cb60a865632d90d6a698060a9a", + "sha256:238fddfb90fab858ced88d064608bff9aed83cec11a7630a4e95b7e49734d8b1", + "sha256:241912c4f7f232c7518384f8cea719cf2ff290f80735355a217e9c690d274f62", + "sha256:25db060ba8082c38f75da482ff15d3b60a4bc59f158b6d29a2c5bccadd2b71b0", + "sha256:2676f7ccd22a67638baff054a8e13924f20d87efb3a873f6ea248a395a80e2c8", + "sha256:27fa0e7d5e5291dc3e48c6512524f2f8e7ba3d397fa712a85a97639e3d6597e9", + "sha256:2c2cd1e01e8aef2bd1b5152e66e0b865f31eb2d00a8d28cbbbb802f42e2dbe43", + "sha256:2e9709a163ec3b890f9a4173261e9ef586046feee74bbece62595bf103421178", + "sha256:2fda8c003d9ae4f3674c783887b31ecb76f4ab58670a8f01b93efd0917c1e503", + "sha256:33cfd01cb7f8a48c8e057198e3814a120323c0360017dd5c4eba07d097b43b39", + "sha256:35737fd5766ca212d98e0598fb4d302f509e1cbf7b6dc42e2eddefd956150815", + "sha256:35b34f33a9f0a86fdba39053b203d8d517da76f3553230a55867c51f0d802b67", + "sha256:3abe9c25f9ba260a6828d24002a15112c5f21c6877c5f8c294ffe4b9d197c6d2", + "sha256:3c7f3c61e2d1530cf7e1647bdbb466f0f83fa30d2c579b6d75e444f88ff47913", + "sha256:3e8707e98b645f80834e24103e7cd67f1b772999bb979da6d61ca1fcdc07672a", + "sha256:3eae4c6880dbabee9f363950510c09d7e12dea8dbc6ebcd2ff58e594a78d9370", + "sha256:3f7b798807ac9c5f632e8f359adf1393f81d9211e4961eedb5e2d4ce311e0078", + "sha256:43398361d54fed476ccfdb52dc34d88c64461f0ec35f8abf10dd0413a3f19d8c", + "sha256:4581600ded8f37e8387d0eef93520fb33dafab6ccb37d005e20d05cd3fbdd9db", + "sha256:45def44f1140c6f5c7a5389645d02e8011d27a6e64f529f33cee687e7c25af07", + "sha256:475a551c43ba23b4ca328c9bbcae39205729f4751280eb9763da08d97d328953", + "sha256:4787d8e9f4b184d383ad000cdd48330ae75ec927c5832067a6b3617c5f6fb677", + "sha256:48539221026b0a84b6d2c2665c3dde784e3c0fac28975658c03fed352f8e1d7e", + "sha256:4f3f0ddfe3176e19c0a3cf6ad29e9ff216ff5fdec035b001ebabad91ef155107", + "sha256:4fc958b21416825c599e228278c69efb480169cd99d1a21787a54f53fbff026c", + "sha256:589464c49a332c644b750f2ebc3737d444427669323ace623bd4948e414a641a", + "sha256:5c6a9ada752149e23051852867596b35afc79015760e23676ac287bcad58e0b6", + "sha256:5dcd7bd175d870338fc9ae43d0184ecd45958f5ca2ee7ea0a7953eedc4d9718e", + "sha256:5e2c0a5a0346ce95a965ed6fa941edcf129cac22bf63314b684a3fe64078c95b", + "sha256:5fa88543c5744d725fc989afd79926c226e1c5f5c00904834851997f367da2b5", + "sha256:626eaa1b52a9dafa9bf377bcdcfdf1ea867dd51b5bb5dab1a05938c3303f317f", + "sha256:651664023726f28f7447e40fa2b8a015514f9db4b58654e9bf7d3729e2606eab", + "sha256:74f821370ac01f677b5a26e0606084f2eb671f7bb4f3e2e82d94a100b1c28457", + "sha256:7a67d93fd2e6e5a4e278eade2bbef16ba88d4efcb4eed106f075b0b21427a92f", + "sha256:7e34c996cc245a21f376c3b8eede1296339845f039c8c270297a455d3a1ad71b", + "sha256:7f2db0c684d9999c81084aa370e2e6b266b694e76c7e356bbeb3b282ca524475", + "sha256:7febf074f7de7ebc374100be0036fc592659af911b6efbc1135cdebfe939c57d", + "sha256:800b1498989bfb64118b219eeb42957b3d93ec7d6955dfc742a3cbf3be738f2f", + "sha256:8eadfb5394ab5b9c6e3d4bb00ef49e19f60a4e431190c103e647d4e4bff3332e", + "sha256:917e3e2ffc0e078cce4a632f65d32a339f18cad22b5536a32c641bf1900e7f96", + "sha256:96fe7da85d8721c3a5c362f6b1e7fd26ad74a76bebc369fb7ae62907cf069940", + "sha256:9836bea98f25a67c296f57cf6de420c88f46e430ee85d25ae5f397968c7adcdf", + "sha256:9c8295dd49582dfb6a29e5f9dfa1691a0edd2e0512377ceb2c8dd11e7fabd38a", + "sha256:9ceb8d6f1bd18a058cb8472c6e8cc84802413a65b029a7832589ba7b76c0eb11", + "sha256:9e239e404dbb9fec308409e174710b5e53ff8bd9647e8875e2ca245b1f762f89", + "sha256:9f849d4889a0f1bc2260b981b1ae8393938e8a2c92666e1757e69f947c6ce868", + "sha256:a6d78f967b7b162013fc85821a74cc7cd021fbf045f166629c9bd523799d8e51", + "sha256:a8d5787f5c52c00991032b976b69f5c1e181a3bddce76fd43c91b2c4901c96ce", + "sha256:a9a90ab26b12218d10d5f148e84e8facd62f562bc25d32e2c3cf3c743f7e0e67", + "sha256:ac6ce417174a086a496aefc7caa614640dc33d418a922ee0a184b093d84f2f6c", + "sha256:ac95a2ca4add04f349f8f5c05269d8b194a72ebdfc4f86a725c15d79a420d429", + "sha256:ad279e4892652583671a7ece977dd9b1eb17ae9752fbc9013c950095b044a315", + "sha256:ad5935f4a0ec3a2c3d19021fcd27addce4892ae00f71cc4180009bc4bed930ac", + "sha256:ae0519d01a05c6204c2d27ae49b2231787d9a6efc801d5dbf131b20065fd21e3", + "sha256:b1114da71974c86e64a98afff8d88cf3a3351b289d07f0218e67d56b506cb9e2", + "sha256:b2b81c6cb59b955b82a4853e3fbef7231da87c5522a69daaf9b01bd81d137ec3", + "sha256:b63402c5af2ad744c2c1ab2e7265eb317e75257fd27eb6f087fea76464b065db", + "sha256:b75fe7abf55e7da6d32174b5ac207a465d1bc69d777049c277776472c0b7d82c", + "sha256:c0006c6450d02efdfef8d3f81e6a87790572486046676fe29f4c5da8708ea11b", + "sha256:c1191a1c9f24134c6048770aabaa2f7def8d6d4c919da857d5e7dabdf63308f2", + "sha256:c43579c7a64f21c9b4d4c3106ace46a8ebfb8e704372e6c8cc45807d1b86462f", + "sha256:c62472a70c7f22f1ae9864c02554dbc234a1dfbac24388542bf87437a4169379", + "sha256:c6c4064b2324b86f7a035379928fe1f3aca4ca5ba75ebedc9ea0d821b0e05606", + "sha256:c6fa81c8d3c901d9f174482185f23b02052e71da015da3a613be98f28fd2672b", + "sha256:c74b960a1b93ac22e6cbf268ce509fb2c2338a29180c3d844df4a57bfff73273", + "sha256:c9c2b3b00033afdb745cc77b8c2ed858b08bb9a773c9a81a1160ece59a361545", + "sha256:c9fdbe8b1b32a731ee48a21a161358e55067c9cabd36ba0b8d844e5106056920", + "sha256:d0fc1e32353afef426488d2e19cd295f1f504323215275ec0871bdae2b052a70", + "sha256:d5b65d9f2860210087739adadc075bd9215b363d00c3c8e68369560683a4c3df", + "sha256:d6e6972c5bd1ee4f532029616dfe0f5133f7cc688ebc05dbbc03e19b4ec12199", + "sha256:e333bb6a69c515a1fce149002aaf7d8902fddab54db14fe14c89c6da402410d2", + "sha256:ef812c73fff460678defaab3a95ec9b7551ef14d424eb6af7b75e376050119d2", + "sha256:f030223aa618a48d2f8339fd674c4c03db88649313e2c65107e9c04e09edc7f2", + "sha256:f371453d0c1109e93ef569741a27171e602ef1fbea5c27a8f190f403234fd36b", + "sha256:f74636ca4a3ce700f4fe2dbe10d224ee4fb52ecab12ea3007a2bc2fcd0d53888", + "sha256:f96973d42caf0e4566882b6e7acbba753199d7acb4db486f14ab553c7b395cd5" ], - "markers": "python_version >= '3.6'", - "version": "==2.11.1" + "index": "pypi", + "version": "==2.12.0" }, "redis": { "extras": [ @@ -1508,45 +1360,54 @@ }, "reportlab": { "hashes": [ - "sha256:03501aa3cffb93ec35ca01d66a70d38090e88080b16eb4efb015a0fdc94a48c9", - "sha256:04fc4420f0548815d0623e031c86a1f7f3f3003e699d9af7148742e2d72b024a", - "sha256:06a9a9b04083529e4204e0c0f4574b7795cc8364a49e66dac25d94588fdaf24a", - "sha256:32b3e10acdbbd2b91a8bb94134ed011af8e5c32ef5fe69f5481f83bbc89fd40e", - "sha256:384e51906d710cec7721ee4f074bc59131dbed9ef3b8e45408432caa752c1d5d", - "sha256:3e53e8222afc535cfdad3d73786c570ec6567b48e3e09bfadca606b170f3f46d", - "sha256:456b9e245dacfa0f676f2864b8981a61bb50aa3fe690fe54885dc41b2b2b402c", - "sha256:4c183a28a44bc03c0ab825fceab4a07a8b36d7f67a208dcf9e561dc4e343aec9", - "sha256:4e97028ea070199955cb50dd1e321177f7fd2fefe89fb328d016e510d60bfc9e", - "sha256:5104000c1f84066c452022316faecb7382eae23a878547cacfa6511f9fddfe02", - "sha256:55df316e227f876e88ba5979c2456e3be47988056e0053d1139f9fbaff968d24", - "sha256:60bcdefa9246e9dd26708d53fe4a51dcef74f9a387b8daa557804adf856a4fd5", - "sha256:689ecf2eea098afb4bba39c97994c6e9ab65a1cf8e5ca7f897942f8692af9932", - "sha256:68d118d8f4dabfde284237901a24b22e7827695cc74c8184b57828eb10e28090", - "sha256:74ca4e4221bb68403753a595a9d24899b2a559d42fd573d00d8884e6a54d0ba1", - "sha256:89c9ba175f72a2fd91836c414a09f91459f2e53b648f69300de6f8e0709a2de2", - "sha256:89f486c48a06655a7aec92b593be60f70d4cfed0b205038acc0c3263df3d8b4a", - "sha256:8e4d4133a2be465aae0826ae8e11319e6411e3119d16b4d6f40079fa89835c43", - "sha256:93864be3ae1dabfa66607734113cc08ac9f839e2b49632df60ede1f0893864ee", - "sha256:a62a856d5c6168f07d2c18e725f577bda5d4bbd4bf535d5c7c99d03b335effe1", - "sha256:a71f6f231e94f2e543a255aa98bf8db2936f7b132be456c70ccf3c98cd60c160", - "sha256:abb5d98541fc89c0d94627d82c83bdd464120c3422333e0f9f37a236ca1c44c8", - "sha256:ad2d649197971c52a8c074739b3aae3cf3db99971561a371a54d429c19a49050", - "sha256:b36e27adeb36fcf2854f8d9951e5e99fa655b4f03d2d15ba321bae42d65e2535", - "sha256:b5f30124b0f5dab69fa56d12b94a50656f030e547bb09ab03936fd8708f04afc", - "sha256:b6450ebf6fbbe826dd4e4837e7cc906a256e1383883ef21a143a5d39c7ce35cc", - "sha256:b6d8979e7769cb860dfffd8d1c303501fea4820f592b5e6836cba1b64aa82f10", - "sha256:c3988595e57c114c2cc93dd21b08f917c3d868bf57fd52bbb20008e3c26f023e", - "sha256:c3a4bdb586e6649bd2b7d452b79c09a819bcb848ac408f1f4b00155c91469ffd", - "sha256:c3d774f1d522579398ebfb5ad9129cc4a409c35a14f412e1ae20c0a7d42561f0", - "sha256:c894990d87b0c8eae1f60a747c5180f9abcc525f1c71435cbdcb1f5ee420d675", - "sha256:ca40c72a6c07ebd35a1b85d8cb3069b43587a589fe2ff2d16e33ea53b1ffe40f", - "sha256:cf0e362917ca2c00627828fce077fe364b7e0f70e795fb98e97c8befe8f96289", - "sha256:ea3dc427b6be0eb0966732e9e30bccec1c8b395aba0484430bc72d811a9e84ea", - "sha256:f73970f8c4ccb2c32cf350f1b86171af27ed7df79dc0cc529875bc40610b6bbd", - "sha256:fe5c2fcbe8f130c8913dad56d2513afb809491ad8a17b5c49b3951cfa070d4a3" + "sha256:07fdd968df7941c2bfb67b9bb4532f424992dfafc71b72a4e4b291ff707e6b0e", + "sha256:090ea99ff829d918f7b6140594373b1340a34e1e6876eddae5aa06662ec10d64", + "sha256:109009b02fc225882ea766a5ed8be0ef473fa1356e252a3f651a6aa89b4a195f", + "sha256:1dd0307b2b13b0482ac8314fd793fbbce263a428b189371addf0466784e1d597", + "sha256:236a6483210049205f6180d7a7595d0ca2e4ce343d83cc94ca719a4145809c6f", + "sha256:26c25ea4afa8b92a2c14f4edc41c8fc30505745ce84cae86538e80cacadd7ae2", + "sha256:2a0bc7a1d64fe754b62e175ba0cf47a630b529c0488ec9ac4e4c7655e295ea4d", + "sha256:2c9b0861d8f40d7a24b094b8834f6a489b9e8c70bceaa7fa98237eed229671ce", + "sha256:39e92fa4ab2a8f0f2cc051d9c1e3acb881340c07ef59c0c8b627861343d653c0", + "sha256:3a62e51a4a47616896bd0f1e9cc3fbfb174b713794a5031a34b84f69dbe01775", + "sha256:3fd1ffdd5204301eb4c290a5752ac62f44d2d0b262e02e35a1e5234c13e14662", + "sha256:498b4ec7e73426de64c6bf6ec03c5b3f10dedf5db8a9e13fdf195f95a3d065aa", + "sha256:4c599645af9b5b2241a23e977a82c965a59c24cd94b2600b8d34373c66cad763", + "sha256:4fa3cdf490f3828b055381e8c7dc7819b3e5f7a442d7af7a8f90e9806a7fff51", + "sha256:55a070206580e161b6bbe1a96abf816c18d4c2c225d49916654714c93d842835", + "sha256:666bdba4958b348460a765c48b8c0640e7085540846ed9494f47d8651604b33c", + "sha256:69f41295d696c822224334f0994f1f107df7efed72211d45a1118696f1427c84", + "sha256:6dfcf7bd6db5d80711cbbd0996b6e7a79cc414ca81457960367df11d2860f92a", + "sha256:71cf73f9907c444ef663ea653dbac24af07c307079572c3ff8f20ad1463af3b7", + "sha256:72ec333f089b4fce5a6d740ed0a1963a3994146be195722da0d8e14d4a7e1600", + "sha256:759495c2b8c15cb0d6b539c246896029e4cde42a896c3956f77e311c5f6b0807", + "sha256:7a7c3369fa618eca79f9554ce06c618a5e738e592d61d96aa09b2457ca3ea410", + "sha256:8b1215facead57cc5325aef4229ef886e85d270b2ba02080fb5809ce9d2b81b4", + "sha256:907f7cd4832bb295d0c1573de15cc5aab5988282caf2ee7a2b1276fb6cdf502b", + "sha256:93e229519d046491b798f2c12dbbf2f3e237e89589aa5cbb5e1d8c1a978816db", + "sha256:a12049314497d872f6788f811e2b331654db207937f8a2fb34ff3e3cd9897faa", + "sha256:a8dddc52e0e486291be0ad39184da0607fae9cc665fdba1881211de9cfc0b332", + "sha256:adf78ccb2defad5b6ecb2e2e9f2a672719b0a8e2278592a7d77f6c220a042388", + "sha256:b13cebf4e397bba14542bcd023338b6ff2c151a3a12aabca89eecbf972cb361a", + "sha256:b3648f3c340b6b6aabf9352341478c708cee6f00c5cd5c902311fcf4ce870f3c", + "sha256:b6a1b685da0b9a8000bb980e02d9d5be202d0cc539af113b661c76c051fca6f1", + "sha256:b777ddc57b2d3366cbc540616034cdc1089ca0a31fefc907028e1dd62a6bf16c", + "sha256:bb83df8f7840321d34cb5b24c972c617a8c1716c8a36e5050fff56adf5891b8c", + "sha256:c07ec796a2a5d44bf787f2b623b6e668a389b0cafb78af34cf74554ff3bc532b", + "sha256:c40e108072379ff83dd7442159ebc249d12eb8eec15b70614953fecd2c403792", + "sha256:c4863c49602722237e35cbce5aa91af4539cc63a671f59504d2b3f3767d898cf", + "sha256:c56d701f7dc662e1d3d7fe364e66fa1339eafce54a488c2d16ec0ea49dc213c2", + "sha256:c84afd5bef6e407c80ba9f99b6abbe3ea78e8243b0f19897a871a7bcad1f749d", + "sha256:cdd206883e999278d2af656f988dfcc89eb0c175ce6d75e87b713cf1e792c0c4", + "sha256:ce85a204f46c871c8af6fa64b9bbed165456935c1d0bfb2f570a3194f6723ddb", + "sha256:cee3b6ebef5e4a8654ec5f0effeb1a2bb157ad87b0ac856871d25a805c0f2f90", + "sha256:d4cecfb48a6cfbfe2caf0fc280cecea999699e63bc98cb02254bd87b39eff677", + "sha256:db62bed0774778fdf82c609cb9efd0062f2fdcd285be527d01f6be9fd9755888", + "sha256:f51dcb39e910a853749250c0f82aced80bca3f7315e9c4ee14349eb7cab6a3f8", + "sha256:f5808e1dac6b66c109d6205ce2aebf84bb89e1a1493b7e6df38932df5ebfb9cf" ], "markers": "python_version >= '3.7' and python_version < '4'", - "version": "==3.6.11" + "version": "==3.6.12" }, "requests": { "hashes": [ @@ -1558,27 +1419,30 @@ }, "scikit-learn": { "hashes": [ - "sha256:1c8fecb7c9984d9ec2ea48898229f98aad681a0873e0935f2b7f724fbce4a047", - "sha256:2b8db962360c93554cab7bb3c096c4a24695da394dd4b3c3f13409f409b425bc", - "sha256:2f46c6e3ff1054a5ec701646dcfd61d43b8ecac4d416014daed8843cf4c33d4d", - "sha256:3e7d1fc817867a350133f937aaebcafbc06192517cbdf0cf7e5774ad4d1adb9f", - "sha256:407e9a1cb9e6ba458a539986a9bd25546a757088095b3aab91d465b79a760d37", - "sha256:567417dbbe6a6278399c3e6daf1654414a5a1a4d818d28f251fa7fc28730a1bf", - "sha256:589d46f28460469f444b898223b13d99db9463e1038dc581ba698111f612264b", - "sha256:5ec3ea40d467966821843210c02117d82b097b54276fdcfb50f4dfb5c60dbe39", - "sha256:6c840f662b5d3377c4ccb8be1fc21bb52cb5d8b8790f8d6bf021739f84e543cf", - "sha256:76800652fb6d6bf527bce36ecc2cc25738b28fe1a17bd294a218fff8e8bd6d50", - "sha256:7c22d1305b16f08d57751a4ea36071e2215efb4c09cb79183faa4e8e82a3dbf8", - "sha256:a682ec0f82b6f30fb07486daed1c8001b6683cc66b51877644dfc532bece6a18", - "sha256:a90ca42fe8242fd6ff56cda2fecc5fca586a88a24ab602d275d2d0dcc0b928fb", - "sha256:b1e706deca9b2ad87ae27dafd5ac4e8eff01b6db492ed5c12cef4735ec5f21ea", - "sha256:bbef6ea1c012ff9f3e6f6e9ca006b8772d8383e177b898091e68fbd9b3f840f9", - "sha256:c33e16e9a165af6012f5be530ccfbb672e2bc5f9b840238a05eb7f6694304e3f", - "sha256:d6f232779023c3b060b80b5c82e5823723bc424dcac1d1a148aa2492c54d245d", - "sha256:f94c0146bad51daef919c402a3da8c1c6162619653e1c00c92baa168fda292f2" + "sha256:23fb9e74b813cc2528b5167d82ed08950b11106ccf50297161875e45152fb311", + "sha256:250da993701da88bf475e7c5746abf1285ea0ae47e4d0917cd13afd6600bb162", + "sha256:28b2bd6a1419acd522ff45d282c8ba23dbccb5338802ab0ee12baa4ade0aba4c", + "sha256:2ee2c649f2231b68511aabb0dc827edd8936aad682acc6263c34aed11bc95dac", + "sha256:30e27721adc308e8fd9f419f43068e43490005f911edf4476a9e585059fa8a83", + "sha256:38814f66285318f2e241305cca545eaa9b4126c65aa5dd78c69371f235f78e2b", + "sha256:4d3a19166d4e1cdfcab975c68f471e046ce01e74c42a9a33fa89a14c2fcedf60", + "sha256:5699cded6c0685426433c7e5afe0fecad80ec831ec7fa264940e50c796775cc5", + "sha256:6785b8a3093329bf90ac01801be5525551728ae73edb11baa175df660820add4", + "sha256:6d1c1394e38a3319ace620381f6f23cc807d8780e9915c152449a86fc8f1db21", + "sha256:701181792a28c82fecae12adb5d15d0ecf57bffab7cf4bdbb52c7b3fd428d540", + "sha256:748f2bd632d6993e8918d43f1a26c380aeda4e122a88840d4c3a9af99d4239fe", + "sha256:8e9dd76c7274055d1acf4526b8efb16a3531c26dcda714a0c16da99bf9d41900", + "sha256:bef51978a51ec19977700fe7b86aecea49c825884f3811756b74a3b152bb4e35", + "sha256:cd55c6fbef7608dbce1f22baf289dfcc6eb323247daa3c3542f73d389c724786", + "sha256:da5a2e95fef9805b1750e4abda4e834bf8835d26fc709a391543b53feee7bd0e", + "sha256:ee47f68d973cee7009f06edb956f2f5588a0f230f24a2a70175fd0ecf36e2653", + "sha256:f4931f2a6c06e02c6c17a05f8ae397e2545965bc7a0a6cb38c8cd7d4fba8624d", + "sha256:f5644663987ee221f5d1f47a593271b966c271c236fe05634e6bdc06041b5a2b", + "sha256:f5d4231af7199531e77da1b78a4cc6b3d960a00b1ec672578ac818aae2b9c35d", + "sha256:fd3ee69d36d42a7dcbb17e355a5653af5fd241a7dfd9133080b3dde8d9e2aafb" ], "index": "pypi", - "version": "==1.1.2" + "version": "==1.1.3" }, "scipy": { "hashes": [ @@ -1759,11 +1623,11 @@ "tls" ], "hashes": [ - "sha256:8d4718d1e48dcc28933f8beb48dc71cfe77a125e37ad1eb7a3d0acc49baf6c99", - "sha256:e5b60de39f2d1da153fbe1874d885fe3fcbdb21fcc446fa759a53e8fc3513bed" + "sha256:32acbd40a94f5f46e7b42c109bfae2b302250945561783a8b7a059048f2d4d31", + "sha256:86c55f712cc5ab6f6d64e02503352464f0400f66d4f079096d744080afcccbd0" ], "markers": "python_full_version >= '3.7.1'", - "version": "==22.8.0" + "version": "==22.10.0" }, "txaio": { "hashes": [ @@ -1778,16 +1642,16 @@ "sha256:1511434bb92bf8dd198c12b1cc812e800d4181cfcb867674e0f8279cc93087aa", "sha256:16fa4864408f655d35ec496218b85f79b3437c829e93320c7c9215ccfd92489e" ], - "markers": "python_version < '3.10'", + "markers": "python_version >= '3.7'", "version": "==4.4.0" }, "tzdata": { "hashes": [ - "sha256:323161b22b7802fdc78f20ca5f6073639c64f1a7227c40cd3e19fd1d0ce6650a", - "sha256:e15b2b3005e2546108af42a0eb4ccab4d9e225e2dfbf4f77aad50c70a4b1f3ab" + "sha256:04a680bdc5b15750c39c12a448885a51134a27ec9af83667663f0b3a1bf3f342", + "sha256:91f11db4503385928c15598c98573e3af07e7229181bee5375bd30f1695ddcae" ], "markers": "python_version >= '3.6'", - "version": "==2022.5" + "version": "==2022.6" }, "tzlocal": { "hashes": [ @@ -1920,65 +1784,79 @@ ], "version": "==0.2.5" }, - "webencodings": { - "hashes": [ - "sha256:a0af1213f3c2226497a97e2b3aa01a7e4bee4f403f95be16fc9acd2947514a78", - "sha256:b36a1c245f2d304965eb4e0a82848379241dc04b865afcc4aab16748587e1923" - ], - "version": "==0.5.1" - }, "websockets": { "hashes": [ - "sha256:07cdc0a5b2549bcfbadb585ad8471ebdc7bdf91e32e34ae3889001c1c106a6af", - "sha256:210aad7fdd381c52e58777560860c7e6110b6174488ef1d4b681c08b68bf7f8c", - "sha256:28dd20b938a57c3124028680dc1600c197294da5db4292c76a0b48efb3ed7f76", - "sha256:2f94fa3ae454a63ea3a19f73b95deeebc9f02ba2d5617ca16f0bbdae375cda47", - "sha256:31564a67c3e4005f27815634343df688b25705cccb22bc1db621c781ddc64c69", - "sha256:347974105bbd4ea068106ec65e8e8ebd86f28c19e529d115d89bd8cc5cda3079", - "sha256:379e03422178436af4f3abe0aa8f401aa77ae2487843738542a75faf44a31f0c", - "sha256:3eda1cb7e9da1b22588cefff09f0951771d6ee9fa8dbe66f5ae04cc5f26b2b55", - "sha256:51695d3b199cd03098ae5b42833006a0f43dc5418d3102972addc593a783bc02", - "sha256:54c000abeaff6d8771a4e2cef40900919908ea7b6b6a30eae72752607c6db559", - "sha256:5b936bf552e4f6357f5727579072ff1e1324717902127ffe60c92d29b67b7be3", - "sha256:6075fd24df23133c1b078e08a9b04a3bc40b31a8def4ee0b9f2c8865acce913e", - "sha256:661f641b44ed315556a2fa630239adfd77bd1b11cb0b9d96ed8ad90b0b1e4978", - "sha256:6ea6b300a6bdd782e49922d690e11c3669828fe36fc2471408c58b93b5535a98", - "sha256:6ed1d6f791eabfd9808afea1e068f5e59418e55721db8b7f3bfc39dc831c42ae", - "sha256:7934e055fd5cd9dee60f11d16c8d79c4567315824bacb1246d0208a47eca9755", - "sha256:7ab36e17af592eec5747c68ef2722a74c1a4a70f3772bc661079baf4ae30e40d", - "sha256:7f6d96fdb0975044fdd7953b35d003b03f9e2bcf85f2d2cf86285ece53e9f991", - "sha256:83e5ca0d5b743cde3d29fda74ccab37bdd0911f25bd4cdf09ff8b51b7b4f2fa1", - "sha256:85506b3328a9e083cc0a0fb3ba27e33c8db78341b3eb12eb72e8afd166c36680", - "sha256:8af75085b4bc0b5c40c4a3c0e113fa95e84c60f4ed6786cbb675aeb1ee128247", - "sha256:8b1359aba0ff810d5830d5ab8e2c4a02bebf98a60aa0124fb29aa78cfdb8031f", - "sha256:8fbd7d77f8aba46d43245e86dd91a8970eac4fb74c473f8e30e9c07581f852b2", - "sha256:907e8247480f287aa9bbc9391bd6de23c906d48af54c8c421df84655eef66af7", - "sha256:93d5ea0b5da8d66d868b32c614d2b52d14304444e39e13a59566d4acb8d6e2e4", - "sha256:97bc9d41e69a7521a358f9b8e44871f6cdeb42af31815c17aed36372d4eec667", - "sha256:994cdb1942a7a4c2e10098d9162948c9e7b235df755de91ca33f6e0481366fdb", - "sha256:a141de3d5a92188234afa61653ed0bbd2dde46ad47b15c3042ffb89548e77094", - "sha256:a1e15b230c3613e8ea82c9fc6941b2093e8eb939dd794c02754d33980ba81e36", - "sha256:aad5e300ab32036eb3fdc350ad30877210e2f51bceaca83fb7fef4d2b6c72b79", - "sha256:b529fdfa881b69fe563dbd98acce84f3e5a67df13de415e143ef053ff006d500", - "sha256:b9c77f0d1436ea4b4dc089ed8335fa141e6a251a92f75f675056dac4ab47a71e", - "sha256:bb621ec2dbbbe8df78a27dbd9dd7919f9b7d32a73fafcb4d9252fc4637343582", - "sha256:c7250848ce69559756ad0086a37b82c986cd33c2d344ab87fea596c5ac6d9442", - "sha256:c8d1d14aa0f600b5be363077b621b1b4d1eb3fbf90af83f9281cda668e6ff7fd", - "sha256:d1655a6fc7aecd333b079d00fb3c8132d18988e47f19740c69303bf02e9883c6", - "sha256:d6353ba89cfc657a3f5beabb3b69be226adbb5c6c7a66398e17809b0ce3c4731", - "sha256:da4377904a3379f0c1b75a965fff23b28315bcd516d27f99a803720dfebd94d4", - "sha256:e49ea4c1a9543d2bd8a747ff24411509c29e4bdcde05b5b0895e2120cb1a761d", - "sha256:e4e08305bfd76ba8edab08dcc6496f40674f44eb9d5e23153efa0a35750337e8", - "sha256:e6fa05a680e35d0fcc1470cb070b10e6fe247af54768f488ed93542e71339d6f", - "sha256:e7e6f2d6fd48422071cc8a6f8542016f350b79cc782752de531577d35e9bd677", - "sha256:e904c0381c014b914136c492c8fa711ca4cced4e9b3d110e5e7d436d0fc289e8", - "sha256:ec2b0ab7edc8cd4b0eb428b38ed89079bdc20c6bdb5f889d353011038caac2f9", - "sha256:ef5ce841e102278c1c2e98f043db99d6755b1c58bde475516aef3a008ed7f28e", - "sha256:f351c7d7d92f67c0609329ab2735eee0426a03022771b00102816a72715bb00b", - "sha256:fab7c640815812ed5f10fbee7abbf58788d602046b7bb3af9b1ac753a6d5e916", - "sha256:fc06cc8073c8e87072138ba1e431300e2d408f054b27047d047b549455066ff4" + "sha256:00213676a2e46b6ebf6045bc11d0f529d9120baa6f58d122b4021ad92adabd41", + "sha256:00c870522cdb69cd625b93f002961ffb0c095394f06ba8c48f17eef7c1541f96", + "sha256:0154f7691e4fe6c2b2bc275b5701e8b158dae92a1ab229e2b940efe11905dff4", + "sha256:05a7233089f8bd355e8cbe127c2e8ca0b4ea55467861906b80d2ebc7db4d6b72", + "sha256:09a1814bb15eff7069e51fed0826df0bc0702652b5cb8f87697d469d79c23576", + "sha256:0cff816f51fb33c26d6e2b16b5c7d48eaa31dae5488ace6aae468b361f422b63", + "sha256:185929b4808b36a79c65b7865783b87b6841e852ef5407a2fb0c03381092fa3b", + "sha256:2fc8709c00704194213d45e455adc106ff9e87658297f72d544220e32029cd3d", + "sha256:33d69ca7612f0ddff3316b0c7b33ca180d464ecac2d115805c044bf0a3b0d032", + "sha256:389f8dbb5c489e305fb113ca1b6bdcdaa130923f77485db5b189de343a179393", + "sha256:38ea7b82bfcae927eeffc55d2ffa31665dc7fec7b8dc654506b8e5a518eb4d50", + "sha256:3d3cac3e32b2c8414f4f87c1b2ab686fa6284a980ba283617404377cd448f631", + "sha256:40e826de3085721dabc7cf9bfd41682dadc02286d8cf149b3ad05bff89311e4f", + "sha256:4239b6027e3d66a89446908ff3027d2737afc1a375f8fd3eea630a4842ec9a0c", + "sha256:45ec8e75b7dbc9539cbfafa570742fe4f676eb8b0d3694b67dabe2f2ceed8aa6", + "sha256:47a2964021f2110116cc1125b3e6d87ab5ad16dea161949e7244ec583b905bb4", + "sha256:48c08473563323f9c9debac781ecf66f94ad5a3680a38fe84dee5388cf5acaf6", + "sha256:4c6d2264f485f0b53adf22697ac11e261ce84805c232ed5dbe6b1bcb84b00ff0", + "sha256:4f72e5cd0f18f262f5da20efa9e241699e0cf3a766317a17392550c9ad7b37d8", + "sha256:56029457f219ade1f2fc12a6504ea61e14ee227a815531f9738e41203a429112", + "sha256:5c1289596042fad2cdceb05e1ebf7aadf9995c928e0da2b7a4e99494953b1b94", + "sha256:62e627f6b6d4aed919a2052efc408da7a545c606268d5ab5bfab4432734b82b4", + "sha256:74de2b894b47f1d21cbd0b37a5e2b2392ad95d17ae983e64727e18eb281fe7cb", + "sha256:7c584f366f46ba667cfa66020344886cf47088e79c9b9d39c84ce9ea98aaa331", + "sha256:7d27a7e34c313b3a7f91adcd05134315002aaf8540d7b4f90336beafaea6217c", + "sha256:7d3f0b61c45c3fa9a349cf484962c559a8a1d80dae6977276df8fd1fa5e3cb8c", + "sha256:82ff5e1cae4e855147fd57a2863376ed7454134c2bf49ec604dfe71e446e2193", + "sha256:84bc2a7d075f32f6ed98652db3a680a17a4edb21ca7f80fe42e38753a58ee02b", + "sha256:884be66c76a444c59f801ac13f40c76f176f1bfa815ef5b8ed44321e74f1600b", + "sha256:8a5cc00546e0a701da4639aa0bbcb0ae2bb678c87f46da01ac2d789e1f2d2038", + "sha256:8dc96f64ae43dde92530775e9cb169979f414dcf5cff670455d81a6823b42089", + "sha256:8f38706e0b15d3c20ef6259fd4bc1700cd133b06c3c1bb108ffe3f8947be15fa", + "sha256:90fcf8929836d4a0e964d799a58823547df5a5e9afa83081761630553be731f9", + "sha256:931c039af54fc195fe6ad536fde4b0de04da9d5916e78e55405436348cfb0e56", + "sha256:932af322458da7e4e35df32f050389e13d3d96b09d274b22a7aa1808f292fee4", + "sha256:942de28af58f352a6f588bc72490ae0f4ccd6dfc2bd3de5945b882a078e4e179", + "sha256:9bc42e8402dc5e9905fb8b9649f57efcb2056693b7e88faa8fb029256ba9c68c", + "sha256:a7a240d7a74bf8d5cb3bfe6be7f21697a28ec4b1a437607bae08ac7acf5b4882", + "sha256:a9f9a735deaf9a0cadc2d8c50d1a5bcdbae8b6e539c6e08237bc4082d7c13f28", + "sha256:ae5e95cfb53ab1da62185e23b3130e11d64431179debac6dc3c6acf08760e9b1", + "sha256:b029fb2032ae4724d8ae8d4f6b363f2cc39e4c7b12454df8df7f0f563ed3e61a", + "sha256:b0d15c968ea7a65211e084f523151dbf8ae44634de03c801b8bd070b74e85033", + "sha256:b343f521b047493dc4022dd338fc6db9d9282658862756b4f6fd0e996c1380e1", + "sha256:b627c266f295de9dea86bd1112ed3d5fafb69a348af30a2422e16590a8ecba13", + "sha256:b9968694c5f467bf67ef97ae7ad4d56d14be2751000c1207d31bf3bb8860bae8", + "sha256:ba089c499e1f4155d2a3c2a05d2878a3428cf321c848f2b5a45ce55f0d7d310c", + "sha256:bbccd847aa0c3a69b5f691a84d2341a4f8a629c6922558f2a70611305f902d74", + "sha256:bc0b82d728fe21a0d03e65f81980abbbcb13b5387f733a1a870672c5be26edab", + "sha256:c57e4c1349fbe0e446c9fa7b19ed2f8a4417233b6984277cce392819123142d3", + "sha256:c94ae4faf2d09f7c81847c63843f84fe47bf6253c9d60b20f25edfd30fb12588", + "sha256:c9b27d6c1c6cd53dc93614967e9ce00ae7f864a2d9f99fe5ed86706e1ecbf485", + "sha256:d210abe51b5da0ffdbf7b43eed0cfdff8a55a1ab17abbec4301c9ff077dd0342", + "sha256:d58804e996d7d2307173d56c297cf7bc132c52df27a3efaac5e8d43e36c21c48", + "sha256:d6a4162139374a49eb18ef5b2f4da1dd95c994588f5033d64e0bbfda4b6b6fcf", + "sha256:da39dd03d130162deb63da51f6e66ed73032ae62e74aaccc4236e30edccddbb0", + "sha256:db3c336f9eda2532ec0fd8ea49fef7a8df8f6c804cdf4f39e5c5c0d4a4ad9a7a", + "sha256:dd500e0a5e11969cdd3320935ca2ff1e936f2358f9c2e61f100a1660933320ea", + "sha256:dd9becd5fe29773d140d68d607d66a38f60e31b86df75332703757ee645b6faf", + "sha256:e0cb5cc6ece6ffa75baccfd5c02cffe776f3f5c8bf486811f9d3ea3453676ce8", + "sha256:e23173580d740bf8822fd0379e4bf30aa1d5a92a4f252d34e893070c081050df", + "sha256:e3a686ecb4aa0d64ae60c9c9f1a7d5d46cab9bfb5d91a2d303d00e2cd4c4c5cc", + "sha256:e789376b52c295c4946403bd0efecf27ab98f05319df4583d3c48e43c7342c2f", + "sha256:edc344de4dac1d89300a053ac973299e82d3db56330f3494905643bb68801269", + "sha256:eef610b23933c54d5d921c92578ae5f89813438fded840c2e9809d378dc765d3", + "sha256:f2c38d588887a609191d30e902df2a32711f708abfd85d318ca9b367258cfd0c", + "sha256:f55b5905705725af31ccef50e55391621532cd64fbf0bc6f4bac935f0fccec46", + "sha256:f5fc088b7a32f244c519a048c170f14cf2251b849ef0e20cbbb0fdf0fdaf556f", + "sha256:fe10ddc59b304cb19a1bdf5bd0a7719cbbc9fbdd57ac80ed436b709fcf889106", + "sha256:ff64a1d38d156d429404aaa84b27305e957fd10c30e5880d1765c9480bea490f" ], - "version": "==10.3" + "version": "==10.4" }, "whitenoise": { "hashes": [ @@ -2137,11 +2015,11 @@ }, "babel": { "hashes": [ - "sha256:7614553711ee97490f732126dc077f8d0ae084ebc6a96e23db1482afabdb2c51", - "sha256:ff56f4892c1c4bf0d814575ea23471c230d544203c7748e8c68f0089478d48eb" + "sha256:1ad3eca1c885218f6dce2ab67291178944f810a10a9b5f3cb8382a5a232b64fe", + "sha256:5ef4b3226b0180dedded4229651c8b0e1a3a6a2837d45a073272f313e4cf97f6" ], "markers": "python_version >= '3.6'", - "version": "==2.10.3" + "version": "==2.11.0" }, "black": { "hashes": [ @@ -2204,11 +2082,11 @@ }, "colorama": { "hashes": [ - "sha256:854bf444933e37f5824ae7bfc1e98d5bce2ebe4160d46b5edf346a89358e99da", - "sha256:e6c6b4334fc50988a639d9b98aa429a0b57da6e17b9a44f0451f930b6967b7a4" + "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", + "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", - "version": "==0.4.5" + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5, 3.6'", + "version": "==0.4.6" }, "coverage": { "extras": [ @@ -2298,6 +2176,14 @@ "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", "version": "==0.17.1" }, + "exceptiongroup": { + "hashes": [ + "sha256:2ac84b496be68464a2da60da518af3785fff8b7ec0d090a581604bc870bdee41", + "sha256:affbabf13fb6e98988c38d9c5650e701569fe3c1de3233cfb61c5f33774690ad" + ], + "markers": "python_version < '3.11'", + "version": "==1.0.0" + }, "execnet": { "hashes": [ "sha256:8f694f3ba9cc92cab508b152dcfe322153975c29bda272e2fd7f3f00f36e47c5", @@ -2332,11 +2218,11 @@ }, "identify": { "hashes": [ - "sha256:6c32dbd747aa4ceee1df33f25fed0b0f6e0d65721b15bd151307ff7056d50245", - "sha256:b276db7ec52d7e89f5bc4653380e33054ddc803d25875952ad90b0f012cbcdaa" + "sha256:48b7925fe122720088aeb7a6c34f17b27e706b72c61070f27fe3789094233440", + "sha256:7a214a10313b9489a0d61467db2856ae8d0b8306fc923e03a9effa53d8aedc58" ], "markers": "python_version >= '3.7'", - "version": "==2.5.6" + "version": "==2.5.8" }, "idna": { "hashes": [ @@ -2354,14 +2240,6 @@ "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", "version": "==1.4.1" }, - "importlib-metadata": { - "hashes": [ - "sha256:da31db32b304314d044d3c12c79bd59e307889b287ad12ff387b3500835fc2ab", - "sha256:ddb0e35065e8938f867ed4928d0ae5bf2a53b7773871bfe6bcc7e4fcdc7dea43" - ], - "markers": "python_version < '3.10'", - "version": "==5.0.0" - }, "iniconfig": { "hashes": [ "sha256:011e24c64b7f47f6ebd835bb12a743f2fbe9a26d4cecaa7f53bc4f35ee9da8b3", @@ -2550,11 +2428,11 @@ }, "pytest": { "hashes": [ - "sha256:1377bda3466d70b55e3f5cecfa55bb7cfcf219c7964629b967c37cf0bda818b7", - "sha256:4f365fec2dff9c1162f834d9f18af1ba13062db0c708bf7b946f8a5c76180c39" + "sha256:892f933d339f068883b6fd5a459f03d85bfcb355e4981e146d2c7616c21fef71", + "sha256:c4014eb40e10f11f355ad4e3c2fb2c6c6d1919c73f3b5a433de4708202cade59" ], "index": "pypi", - "version": "==7.1.3" + "version": "==7.2.0" }, "pytest-cov": { "hashes": [ @@ -2614,10 +2492,10 @@ }, "pytz": { "hashes": [ - "sha256:335ab46900b1465e714b4fda4963d87363264eb662aab5e65da039c25f1f5b22", - "sha256:c4d88f472f54d615e9cd582a5004d1e5f624854a6a27a6211591c251f22a6914" + "sha256:222439474e9c98fced559f1709d89e6c9cbf8d79c794ff3eb9f8800064291427", + "sha256:e89512406b793ca39f5971bc999cc538ce125c0e51c27941bef4568b460095e2" ], - "version": "==2022.5" + "version": "==2022.6" }, "pyyaml": { "hashes": [ @@ -2769,11 +2647,11 @@ }, "termcolor": { "hashes": [ - "sha256:6b2cf769e93364a2676e1de56a7c0cff2cf5bd07f37e9cc80b0dd6320ebfe388", - "sha256:7e597f9de8e001a3208c4132938597413b9da45382b6f1d150cff8d062b7aaa3" + "sha256:91dd04fdf661b89d7169cefd35f609b19ca931eb033687eaa647cef1ff177c49", + "sha256:b80df54667ce4f48c03fe35df194f052dc27a541ebbf2544e4d6b47b5d6949c4" ], "markers": "python_version >= '3.7'", - "version": "==2.0.1" + "version": "==2.1.0" }, "toml": { "hashes": [ @@ -2788,7 +2666,7 @@ "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc", "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f" ], - "markers": "python_version >= '3.7'", + "markers": "python_version < '3.11'", "version": "==2.0.1" }, "tornado": { @@ -2810,18 +2688,18 @@ }, "tox": { "hashes": [ - "sha256:44f3c347c68c2c68799d7d44f1808f9d396fc8a1a500cbc624253375c7ae107e", - "sha256:bf037662d7c740d15c9924ba23bb3e587df20598697bb985ac2b49bdc2d847f6" + "sha256:89e4bc6df3854e9fc5582462e328dd3660d7d865ba625ae5881bbc63836a6324", + "sha256:d2c945f02a03d4501374a3d5430877380deb69b218b1df9b7f1d2f2a10befaf9" ], "index": "pypi", - "version": "==3.26.0" + "version": "==3.27.0" }, "typing-extensions": { "hashes": [ "sha256:1511434bb92bf8dd198c12b1cc812e800d4181cfcb867674e0f8279cc93087aa", "sha256:16fa4864408f655d35ec496218b85f79b3437c829e93320c7c9215ccfd92489e" ], - "markers": "python_version < '3.10'", + "markers": "python_version >= '3.7'", "version": "==4.4.0" }, "urllib3": { @@ -2834,19 +2712,11 @@ }, "virtualenv": { "hashes": [ - "sha256:227ea1b9994fdc5ea31977ba3383ef296d7472ea85be9d6732e42a91c04e80da", - "sha256:d07dfc5df5e4e0dbc92862350ad87a36ed505b978f6c39609dc489eadd5b0d27" + "sha256:186ca84254abcbde98180fd17092f9628c5fe742273c02724972a1d8a2035108", + "sha256:530b850b523c6449406dfba859d6345e48ef19b8439606c5d74d7d3c9e14d76e" ], "markers": "python_version >= '3.6'", - "version": "==20.16.5" - }, - "zipp": { - "hashes": [ - "sha256:4fcb6f278987a6605757302a6e40e896257570d11c51628968ccb2a47e80c6c1", - "sha256:7a7262fd930bd3e36c50b9a64897aec3fafff3dfdeec9623ae22b40e93f99bb8" - ], - "markers": "python_version < '3.9'", - "version": "==3.10.0" + "version": "==20.16.6" } } } diff --git a/build-docker-image.sh b/build-docker-image.sh index 3c868344e..c43c9886b 100755 --- a/build-docker-image.sh +++ b/build-docker-image.sh @@ -23,6 +23,8 @@ fi # Parse what we can from Pipfile.lock pikepdf_version=$(jq ".default.pikepdf.version" Pipfile.lock | sed 's/=//g' | sed 's/"//g') psycopg2_version=$(jq ".default.psycopg2.version" Pipfile.lock | sed 's/=//g' | sed 's/"//g') +pillow_version=$(jq ".default.pillow.version" Pipfile.lock | sed 's/=//g' | sed 's/"//g') +lxml_version=$(jq ".default.lxml.version" Pipfile.lock | sed 's/=//g' | sed 's/"//g') # Read this from the other config file qpdf_version=$(jq ".qpdf.version" .build-config.json | sed 's/"//g') jbig2enc_version=$(jq ".jbig2enc.version" .build-config.json | sed 's/"//g') @@ -40,4 +42,6 @@ docker build --file "$1" \ --build-arg JBIG2ENC_VERSION="${jbig2enc_version}" \ --build-arg QPDF_VERSION="${qpdf_version}" \ --build-arg PIKEPDF_VERSION="${pikepdf_version}" \ + --build-arg PILLOW_VERSION="${pillow_version}" \ + --build-arg LXML_VERSION="${lxml_version}" \ --build-arg PSYCOPG2_VERSION="${psycopg2_version}" "${@:2}" . diff --git a/docker-builders/Dockerfile.frontend b/docker-builders/Dockerfile.frontend deleted file mode 100644 index e552ee184..000000000 --- a/docker-builders/Dockerfile.frontend +++ /dev/null @@ -1,14 +0,0 @@ -# This Dockerfile compiles the frontend -# Inputs: None - -FROM node:16-bullseye-slim AS compile-frontend - -COPY ./src /src/src -COPY ./src-ui /src/src-ui - -WORKDIR /src/src-ui -RUN set -eux \ - && npm update npm -g \ - && npm ci --omit=optional -RUN set -eux \ - && ./node_modules/.bin/ng build --configuration production diff --git a/docker-builders/Dockerfile.pikepdf b/docker-builders/Dockerfile.pikepdf index 750306360..2594f71f5 100644 --- a/docker-builders/Dockerfile.pikepdf +++ b/docker-builders/Dockerfile.pikepdf @@ -18,6 +18,10 @@ LABEL org.opencontainers.image.description="A intermediate image with pikepdf wh ARG DEBIAN_FRONTEND=noninteractive ARG PIKEPDF_VERSION +# These are not used, but will still bust the cache if one changes +# Otherwise, the main image will try to build thing (and fail) +ARG PILLOW_VERSION +ARG LXML_VERSION ARG BUILD_PACKAGES="\ build-essential \ diff --git a/docs/advanced_usage.rst b/docs/advanced_usage.rst index 844a73817..0dd7e9601 100644 --- a/docs/advanced_usage.rst +++ b/docs/advanced_usage.rst @@ -258,12 +258,18 @@ Paperless provides the following placeholders within filenames: * ``{tag_list}``: A comma separated list of all tags assigned to the document. * ``{title}``: The title of the document. * ``{created}``: The full date (ISO format) the document was created. -* ``{created_year}``: Year created only. +* ``{created_year}``: Year created only, formatted as the year with century. +* ``{created_year_short}``: Year created only, formatted as the year without century, zero padded. * ``{created_month}``: Month created only (number 01-12). +* ``{created_month_name}``: Month created name, as per locale +* ``{created_month_name_short}``: Month created abbreviated name, as per locale * ``{created_day}``: Day created only (number 01-31). * ``{added}``: The full date (ISO format) the document was added to paperless. * ``{added_year}``: Year added only. +* ``{added_year_short}``: Year added only, formatted as the year without century, zero padded. * ``{added_month}``: Month added only (number 01-12). +* ``{added_month_name}``: Month added name, as per locale +* ``{added_month_name_short}``: Month added abbreviated name, as per locale * ``{added_day}``: Day added only (number 01-31). diff --git a/src-ui/messages.xlf b/src-ui/messages.xlf index 8260dff93..bc043a5d9 100644 --- a/src-ui/messages.xlf +++ b/src-ui/messages.xlf @@ -464,7 +464,7 @@ src/app/components/document-list/document-list.component.ts - 65 + 88 src/app/components/manage/management-list/management-list.component.html @@ -727,14 +727,14 @@ Confirmation src/app/components/common/confirm-dialog/confirm-dialog.component.ts - 17 + 20 Confirm src/app/components/common/confirm-dialog/confirm-dialog.component.ts - 29 + 32 src/app/components/document-list/bulk-editor/bulk-editor.component.ts @@ -757,53 +757,53 @@ After src/app/components/common/date-dropdown/date-dropdown.component.html - 13 + 21 Clear src/app/components/common/date-dropdown/date-dropdown.component.html - 18 + 26 src/app/components/common/date-dropdown/date-dropdown.component.html - 41 + 49 Before src/app/components/common/date-dropdown/date-dropdown.component.html - 36 + 44 Last 7 days src/app/components/common/date-dropdown/date-dropdown.component.ts - 38 + 43 Last month src/app/components/common/date-dropdown/date-dropdown.component.ts - 39 + 47 Last 3 months src/app/components/common/date-dropdown/date-dropdown.component.ts - 40 + 51 Last year src/app/components/common/date-dropdown/date-dropdown.component.ts - 41 + 55 @@ -1240,7 +1240,7 @@ src/app/components/document-list/document-list.component.html - 88 + 93 src/app/components/manage/tasks/tasks.component.html @@ -1284,7 +1284,7 @@ src/app/components/document-list/document-list.component.html - 152 + 157 src/app/components/document-list/filter-editor/filter-editor.component.html @@ -1311,11 +1311,11 @@ src/app/components/document-list/document-list.component.html - 134 + 139 src/app/components/document-list/filter-editor/filter-editor.component.ts - 131 + 153 src/app/services/rest/document.service.ts @@ -1609,6 +1609,10 @@ src/app/components/document-detail/document-detail.component.html 43 + + src/app/guards/dirty-saved-view.guard.ts + 32 + Previous @@ -1657,7 +1661,7 @@ src/app/components/document-list/document-list.component.html - 128 + 133 src/app/components/document-list/filter-editor/filter-editor.component.html @@ -1680,7 +1684,7 @@ src/app/components/document-list/document-list.component.html - 140 + 145 src/app/components/document-list/filter-editor/filter-editor.component.html @@ -1703,7 +1707,7 @@ src/app/components/document-list/document-list.component.html - 146 + 151 src/app/components/document-list/filter-editor/filter-editor.component.html @@ -2235,7 +2239,7 @@ src/app/components/document-list/document-list.component.html - 173 + 178 @@ -2246,7 +2250,7 @@ src/app/components/document-list/document-list.component.html - 178 + 183 @@ -2307,7 +2311,7 @@ src/app/components/document-list/document-list.component.html - 182 + 187 @@ -2318,7 +2322,7 @@ src/app/components/document-list/document-list.component.html - 187 + 192 @@ -2421,60 +2425,60 @@ Views src/app/components/document-list/document-list.component.html - 63 + 64 Save "" src/app/components/document-list/document-list.component.html - 70 + 75 Save as... src/app/components/document-list/document-list.component.html - 71 + 76 {VAR_PLURAL, plural, =1 {Selected of one document} other {Selected of documents}} src/app/components/document-list/document-list.component.html - 90 + 95 {VAR_PLURAL, plural, =1 {One document} other { documents}} src/app/components/document-list/document-list.component.html - 92 + 97 (filtered) src/app/components/document-list/document-list.component.html - 92 + 97 Error while loading documents src/app/components/document-list/document-list.component.html - 105 + 110 ASN src/app/components/document-list/document-list.component.html - 122 + 127 src/app/components/document-list/filter-editor/filter-editor.component.ts - 136 + 158 src/app/services/rest/document.service.ts @@ -2485,11 +2489,11 @@ Added src/app/components/document-list/document-list.component.html - 158 + 163 src/app/components/document-list/filter-editor/filter-editor.component.html - 61 + 60 src/app/services/rest/document.service.ts @@ -2500,140 +2504,140 @@ Edit document src/app/components/document-list/document-list.component.html - 177 + 182 View "" saved successfully. src/app/components/document-list/document-list.component.ts - 170 + 196 View "" created successfully. src/app/components/document-list/document-list.component.ts - 210 + 237 Reset filters src/app/components/document-list/filter-editor/filter-editor.component.html - 71 + 73 Correspondent: src/app/components/document-list/filter-editor/filter-editor.component.ts - 72,74 + 94,96 Without correspondent src/app/components/document-list/filter-editor/filter-editor.component.ts - 76 + 98 Type: src/app/components/document-list/filter-editor/filter-editor.component.ts - 81,83 + 103,105 Without document type src/app/components/document-list/filter-editor/filter-editor.component.ts - 85 + 107 Tag: src/app/components/document-list/filter-editor/filter-editor.component.ts - 89,91 + 111,113 Without any tag src/app/components/document-list/filter-editor/filter-editor.component.ts - 95 + 117 Title: src/app/components/document-list/filter-editor/filter-editor.component.ts - 99 + 121 ASN: src/app/components/document-list/filter-editor/filter-editor.component.ts - 102 + 124 Title & content src/app/components/document-list/filter-editor/filter-editor.component.ts - 134 + 156 Advanced search src/app/components/document-list/filter-editor/filter-editor.component.ts - 139 + 161 More like src/app/components/document-list/filter-editor/filter-editor.component.ts - 145 + 167 equals src/app/components/document-list/filter-editor/filter-editor.component.ts - 164 + 186 is empty src/app/components/document-list/filter-editor/filter-editor.component.ts - 168 + 190 is not empty src/app/components/document-list/filter-editor/filter-editor.component.ts - 172 + 194 greater than src/app/components/document-list/filter-editor/filter-editor.component.ts - 176 + 198 less than src/app/components/document-list/filter-editor/filter-editor.component.ts - 180 + 202 @@ -3473,6 +3477,10 @@ src/app/guards/dirty-form.guard.ts 18 + + src/app/guards/dirty-saved-view.guard.ts + 24 + src/app/services/open-documents.service.ts 116 @@ -3507,6 +3515,27 @@ 22 + + You have unsaved changes to the saved view + + src/app/guards/dirty-saved-view.guard.ts + 26 + + + + Are you sure you want to close this saved view? + + src/app/guards/dirty-saved-view.guard.ts + 30 + + + + Save and close + + src/app/guards/dirty-saved-view.guard.ts + 34 + + (no title) diff --git a/src-ui/package-lock.json b/src-ui/package-lock.json index 274117558..b6b8051df 100644 --- a/src-ui/package-lock.json +++ b/src-ui/package-lock.json @@ -8,14 +8,14 @@ "name": "paperless-ui", "version": "0.0.0", "dependencies": { - "@angular/common": "~14.2.4", - "@angular/compiler": "~14.2.4", - "@angular/core": "~14.2.4", - "@angular/forms": "~14.2.4", - "@angular/localize": "~14.2.4", - "@angular/platform-browser": "~14.2.4", - "@angular/platform-browser-dynamic": "~14.2.4", - "@angular/router": "~14.2.4", + "@angular/common": "~14.2.8", + "@angular/compiler": "~14.2.8", + "@angular/core": "~14.2.8", + "@angular/forms": "~14.2.8", + "@angular/localize": "~14.2.8", + "@angular/platform-browser": "~14.2.8", + "@angular/platform-browser-dynamic": "~14.2.8", + "@angular/router": "~14.2.8", "@ng-bootstrap/ng-bootstrap": "^13.0.0", "@ng-select/ng-select": "^9.0.2", "@ngneat/dirty-check-forms": "^3.0.2", @@ -26,7 +26,7 @@ "ngx-color": "^8.0.3", "ngx-cookie-service": "^14.0.1", "ngx-file-drop": "^14.0.1", - "ngx-ui-tour-ng-bootstrap": "^11.0.0", + "ngx-ui-tour-ng-bootstrap": "^11.1.0", "rxjs": "~7.5.7", "tslib": "^2.3.1", "uuid": "^9.0.0", @@ -34,15 +34,15 @@ }, "devDependencies": { "@angular-builders/jest": "14.0.1", - "@angular-devkit/build-angular": "~14.2.4", - "@angular/cli": "~14.2.4", - "@angular/compiler-cli": "~14.2.4", + "@angular-devkit/build-angular": "~14.2.7", + "@angular/cli": "~14.2.7", + "@angular/compiler-cli": "~14.2.8", "@types/jest": "28.1.6", "@types/node": "^18.7.23", "codelyzer": "^6.0.2", "concurrently": "7.4.0", "jest": "28.1.3", - "jest-environment-jsdom": "^29.1.2", + "jest-environment-jsdom": "^29.2.2", "jest-preset-angular": "^12.2.2", "ts-node": "~10.9.1", "tslint": "~6.1.3", @@ -261,12 +261,12 @@ } }, "node_modules/@angular-devkit/architect": { - "version": "0.1402.4", - "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1402.4.tgz", - "integrity": "sha512-lOgyKJ+KjBYWzgcxJ3vAy3RFkqRmSw3RY4thNsWOHLvzT8o33u3USDuOr6cDAQW12NjX9K7JDuvNlPbadjQbSQ==", + "version": "0.1402.7", + "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1402.7.tgz", + "integrity": "sha512-YZchteri2iUq5JICSH0BQjOU3ehE57+CMU8PBigcJZiaLa/GPiCuwD9QOsnwSzHJNYYx5C94uhtZUjPwUtIAIw==", "devOptional": true, "dependencies": { - "@angular-devkit/core": "14.2.4", + "@angular-devkit/core": "14.2.7", "rxjs": "6.6.7" }, "engines": { @@ -294,15 +294,15 @@ "devOptional": true }, "node_modules/@angular-devkit/build-angular": { - "version": "14.2.4", - "resolved": "https://registry.npmjs.org/@angular-devkit/build-angular/-/build-angular-14.2.4.tgz", - "integrity": "sha512-VvwLmb5fiorcLO6Fko3GIeNDWsdoZxviHcHjq2IGkgTNMlvWwZhuSZ8kOhNIXUKFCZYpj7FiUm/ft8v0ilxFBg==", + "version": "14.2.7", + "resolved": "https://registry.npmjs.org/@angular-devkit/build-angular/-/build-angular-14.2.7.tgz", + "integrity": "sha512-Y58kcEmy8bSFyODtUFQzkuoZHNCji3fzRwGCiQYdAh/mkBf53CuVWoT9q7MrvGOc7Nmo2JiuwR/b7c543eVgfw==", "dev": true, "dependencies": { "@ampproject/remapping": "2.2.0", - "@angular-devkit/architect": "0.1402.4", - "@angular-devkit/build-webpack": "0.1402.4", - "@angular-devkit/core": "14.2.4", + "@angular-devkit/architect": "0.1402.7", + "@angular-devkit/build-webpack": "0.1402.7", + "@angular-devkit/core": "14.2.7", "@babel/core": "7.18.10", "@babel/generator": "7.18.12", "@babel/helper-annotate-as-pure": "7.18.6", @@ -313,7 +313,7 @@ "@babel/runtime": "7.18.9", "@babel/template": "7.18.10", "@discoveryjs/json-ext": "0.5.7", - "@ngtools/webpack": "14.2.4", + "@ngtools/webpack": "14.2.7", "ansi-colors": "4.1.3", "babel-loader": "8.2.5", "babel-plugin-istanbul": "6.1.1", @@ -420,12 +420,12 @@ "dev": true }, "node_modules/@angular-devkit/build-webpack": { - "version": "0.1402.4", - "resolved": "https://registry.npmjs.org/@angular-devkit/build-webpack/-/build-webpack-0.1402.4.tgz", - "integrity": "sha512-hj80twvKlscktH3bILS4+iQckTQzUWO/hTrG0auvJIXHWOmfJDQTDEyIgoMUzhnibh/8xwf96cFAsFZc2d5kFA==", + "version": "0.1402.7", + "resolved": "https://registry.npmjs.org/@angular-devkit/build-webpack/-/build-webpack-0.1402.7.tgz", + "integrity": "sha512-aDhS/ODt8BwgtnNN73R7SuMC1GgoT5Pajn1nnIWvvpGj8XchLUbguptyl2v7D2QeYXXsd34Gtx8cDOr9PxYFTA==", "dev": true, "dependencies": { - "@angular-devkit/architect": "0.1402.4", + "@angular-devkit/architect": "0.1402.7", "rxjs": "6.6.7" }, "engines": { @@ -457,9 +457,9 @@ "dev": true }, "node_modules/@angular-devkit/core": { - "version": "14.2.4", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-14.2.4.tgz", - "integrity": "sha512-NsvN1U42goBcibVR75vDp2NOFeSU+Wcekwf1r3Jbyz6a2l9Unf0v9BOWLXdigFY8xztbrOHJPSIbC+2rkvOUnw==", + "version": "14.2.7", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-14.2.7.tgz", + "integrity": "sha512-83SCYP3h6fglWMgAXFDc8HfOxk9t3ugK0onATXchctvA7blW4Vx8BSg3/DgbqCv+fF380SN8bYqqLJl8fQFdzg==", "devOptional": true, "dependencies": { "ajv": "8.11.0", @@ -501,12 +501,12 @@ "devOptional": true }, "node_modules/@angular-devkit/schematics": { - "version": "14.2.4", - "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-14.2.4.tgz", - "integrity": "sha512-Pm2C7HBNslQavsqXh6/rcyAavmgzTxU3x7NoWwSBH+fIplLJjEFzHdnW9JJp59A2ONfqO0wND3yWKtjIoDAUqw==", + "version": "14.2.7", + "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-14.2.7.tgz", + "integrity": "sha512-3e2dpFXWl2Z4Gfm+KgY3gAeqsyu8utJMcDIg5sWRAXDeJJdAPc5LweCa8YZEn33Zr9cl8oK+FxlOr15RCyWLcA==", "devOptional": true, "dependencies": { - "@angular-devkit/core": "14.2.4", + "@angular-devkit/core": "14.2.7", "jsonc-parser": "3.1.0", "magic-string": "0.26.2", "ora": "5.4.1", @@ -537,15 +537,15 @@ "devOptional": true }, "node_modules/@angular/cli": { - "version": "14.2.4", - "resolved": "https://registry.npmjs.org/@angular/cli/-/cli-14.2.4.tgz", - "integrity": "sha512-3YqwjPYlLzqQB0y6A7c3l9X1e0z418NjSQQD2e12N8y68V8nkTK4UcsDVpqb/7ce+xnQ7xGz2wb6DJddU4Wogw==", + "version": "14.2.7", + "resolved": "https://registry.npmjs.org/@angular/cli/-/cli-14.2.7.tgz", + "integrity": "sha512-RM4CJwtqD7cKFQ7hNGJ56s9YMeJxYqCN5Ss0SzsKN1nXYqz8HykMW8fhUbZQ9HFVy/Ml3LGoh1yGo/tXywAWcA==", "devOptional": true, "dependencies": { - "@angular-devkit/architect": "0.1402.4", - "@angular-devkit/core": "14.2.4", - "@angular-devkit/schematics": "14.2.4", - "@schematics/angular": "14.2.4", + "@angular-devkit/architect": "0.1402.7", + "@angular-devkit/core": "14.2.7", + "@angular-devkit/schematics": "14.2.7", + "@schematics/angular": "14.2.7", "@yarnpkg/lockfile": "1.1.0", "ansi-colors": "4.1.3", "debug": "4.3.4", @@ -582,9 +582,9 @@ } }, "node_modules/@angular/common": { - "version": "14.2.4", - "resolved": "https://registry.npmjs.org/@angular/common/-/common-14.2.4.tgz", - "integrity": "sha512-nzmRUhdyKomgsf1vUdx7KOXS7OXkvdpF/1CSagqsIGYVLbL8cGZ6ROrdEuxkSsE9GUt/OAIkC4How4/LLPut1A==", + "version": "14.2.8", + "resolved": "https://registry.npmjs.org/@angular/common/-/common-14.2.8.tgz", + "integrity": "sha512-JSPN2h1EcyWjHWtOzRQmoX48ZacTjLAYwW9ZRmBpYs6Ptw5xZ39ARTJfQNcNnJleqYju2E6BNkGnLpbtWQjNDA==", "dependencies": { "tslib": "^2.3.0" }, @@ -592,14 +592,14 @@ "node": "^14.15.0 || >=16.10.0" }, "peerDependencies": { - "@angular/core": "14.2.4", + "@angular/core": "14.2.8", "rxjs": "^6.5.3 || ^7.4.0" } }, "node_modules/@angular/compiler": { - "version": "14.2.4", - "resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-14.2.4.tgz", - "integrity": "sha512-fBvTPPWBYA65bAmrqKcnzUHAhZ/tfs+nG+IeDukn4TeyQplVjDYOlqjf84jYQubSIx8WTicZzRFn0dIGsPaSNw==", + "version": "14.2.8", + "resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-14.2.8.tgz", + "integrity": "sha512-lKwp3B4ZKNLgk/25Iyur8bjAwRL20auRoB4EuHrBf+928ftsjYUXTgi+0++DUjPENbpi59k6GcvMCNa6qccvIw==", "dependencies": { "tslib": "^2.3.0" }, @@ -607,7 +607,7 @@ "node": "^14.15.0 || >=16.10.0" }, "peerDependencies": { - "@angular/core": "14.2.4" + "@angular/core": "14.2.8" }, "peerDependenciesMeta": { "@angular/core": { @@ -616,9 +616,9 @@ } }, "node_modules/@angular/compiler-cli": { - "version": "14.2.4", - "resolved": "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-14.2.4.tgz", - "integrity": "sha512-8kHA/Ujzr5aXic7T3iEJiu0JMfXRs/uDoi8W8dYWFe+0naGhxwWmHBHc/hhS1tpv9/wW2WOcT51RDa4OYHKDKw==", + "version": "14.2.8", + "resolved": "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-14.2.8.tgz", + "integrity": "sha512-QTftNrAyXOWzKFGY6/i9jh0LB2cOxmykepG4c53wH9LblGvWFztlVOhcoU8tpQSSH8t3EYvGs2r8oUuxcYm5Cw==", "dependencies": { "@babel/core": "^7.17.2", "chokidar": "^3.0.0", @@ -640,14 +640,14 @@ "node": "^14.15.0 || >=16.10.0" }, "peerDependencies": { - "@angular/compiler": "14.2.4", + "@angular/compiler": "14.2.8", "typescript": ">=4.6.2 <4.9" } }, "node_modules/@angular/core": { - "version": "14.2.4", - "resolved": "https://registry.npmjs.org/@angular/core/-/core-14.2.4.tgz", - "integrity": "sha512-wB19wKmZE+X07mLbxYyqeg3v1JXy8m0+ShZD2oY3dmgk1mXOf5XVQxRZohGTrbPw83EdSWwx3vz+jjylGunVZQ==", + "version": "14.2.8", + "resolved": "https://registry.npmjs.org/@angular/core/-/core-14.2.8.tgz", + "integrity": "sha512-cgnII9vJGJDLsfr7KsBfU2l+QQUmQIRIP3ImKhBxicw2IHKCSb2mYwoeLV46jaLyHyUMTLRHKUYUR4XtSPnb8A==", "dependencies": { "tslib": "^2.3.0" }, @@ -660,9 +660,9 @@ } }, "node_modules/@angular/forms": { - "version": "14.2.4", - "resolved": "https://registry.npmjs.org/@angular/forms/-/forms-14.2.4.tgz", - "integrity": "sha512-m1asD8SazzMPzcli054zwLYz7hiXiaCXfqmQOFdQQd3OnPNKeCGDS8GFX7Yd/+3fz4REGeSon9YRhq7/W0TDlA==", + "version": "14.2.8", + "resolved": "https://registry.npmjs.org/@angular/forms/-/forms-14.2.8.tgz", + "integrity": "sha512-OaL7Gi6STxJza7yn0qgmh6+hV6NVbtGmunpzrn9cR1k5TeE4ZtXu1z7VZesbZ9kZ3F6U9CmygFt0csf7j1d+Ow==", "dependencies": { "tslib": "^2.3.0" }, @@ -670,16 +670,16 @@ "node": "^14.15.0 || >=16.10.0" }, "peerDependencies": { - "@angular/common": "14.2.4", - "@angular/core": "14.2.4", - "@angular/platform-browser": "14.2.4", + "@angular/common": "14.2.8", + "@angular/core": "14.2.8", + "@angular/platform-browser": "14.2.8", "rxjs": "^6.5.3 || ^7.4.0" } }, "node_modules/@angular/localize": { - "version": "14.2.4", - "resolved": "https://registry.npmjs.org/@angular/localize/-/localize-14.2.4.tgz", - "integrity": "sha512-35BKWV5y5aGGbnLIY9xcPs4i8KGqYBidPtqlU1tg585y0szzFBuHdF4jNrAYTwjGk7fnxYYLZQygM/GtxFwLUA==", + "version": "14.2.8", + "resolved": "https://registry.npmjs.org/@angular/localize/-/localize-14.2.8.tgz", + "integrity": "sha512-ph+ZLl1sXoNnw9AH4aHyI10T0sNCUTtZeGGDTPJnfOQgqfleOvgPxCNNNdi4z02XcLjVE9CKllcaOQY8zwKlZg==", "dependencies": { "@babel/core": "7.18.9", "glob": "8.0.3", @@ -694,8 +694,8 @@ "node": "^14.15.0 || >=16.10.0" }, "peerDependencies": { - "@angular/compiler": "14.2.4", - "@angular/compiler-cli": "14.2.4" + "@angular/compiler": "14.2.8", + "@angular/compiler-cli": "14.2.8" } }, "node_modules/@angular/localize/node_modules/@babel/core": { @@ -762,9 +762,9 @@ } }, "node_modules/@angular/platform-browser": { - "version": "14.2.4", - "resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-14.2.4.tgz", - "integrity": "sha512-/NAQXYLgyeb2L15EsaKgGEn50GH/O3t1FOjBvVZg6L423X0H6dIOL4bxbLcKAj9+bUDtdUzDiDoYyt6YEidH+g==", + "version": "14.2.8", + "resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-14.2.8.tgz", + "integrity": "sha512-tSASBLXoBE0/Gt6d2nC6BJ1DvbGY5wo2Lb+8WCLSvkfsgVqOh4uRuJ2a0wwjeLFd0ZNmpjG42Ijba4btmCpIjg==", "dependencies": { "tslib": "^2.3.0" }, @@ -772,9 +772,9 @@ "node": "^14.15.0 || >=16.10.0" }, "peerDependencies": { - "@angular/animations": "14.2.4", - "@angular/common": "14.2.4", - "@angular/core": "14.2.4" + "@angular/animations": "14.2.8", + "@angular/common": "14.2.8", + "@angular/core": "14.2.8" }, "peerDependenciesMeta": { "@angular/animations": { @@ -783,9 +783,9 @@ } }, "node_modules/@angular/platform-browser-dynamic": { - "version": "14.2.4", - "resolved": "https://registry.npmjs.org/@angular/platform-browser-dynamic/-/platform-browser-dynamic-14.2.4.tgz", - "integrity": "sha512-6jEVKzIqT9lipq4xZftBskHKl3jrL1pQbK8diirJH0mNeuj0wvE+fqfKtVVl898OI/iJ3aAKyQf5YmOe1k8PAw==", + "version": "14.2.8", + "resolved": "https://registry.npmjs.org/@angular/platform-browser-dynamic/-/platform-browser-dynamic-14.2.8.tgz", + "integrity": "sha512-CPK8wHnKke8AUKR92XrFuanaKNXDzDm3uVI3DD0NxBo+fLAkiuVaDVIGgO6n6SxQVtwjXJtMXqQuNdzUg4Q9uQ==", "dependencies": { "tslib": "^2.3.0" }, @@ -793,16 +793,16 @@ "node": "^14.15.0 || >=16.10.0" }, "peerDependencies": { - "@angular/common": "14.2.4", - "@angular/compiler": "14.2.4", - "@angular/core": "14.2.4", - "@angular/platform-browser": "14.2.4" + "@angular/common": "14.2.8", + "@angular/compiler": "14.2.8", + "@angular/core": "14.2.8", + "@angular/platform-browser": "14.2.8" } }, "node_modules/@angular/router": { - "version": "14.2.4", - "resolved": "https://registry.npmjs.org/@angular/router/-/router-14.2.4.tgz", - "integrity": "sha512-zjsiy/1zrZfZnfIbo2vVgZ+UhCo3okabVr43eIvJhBwcNKzM8Zv17oN9FFlWvSzKKkbsoNIgJkTI85L1YsKtjg==", + "version": "14.2.8", + "resolved": "https://registry.npmjs.org/@angular/router/-/router-14.2.8.tgz", + "integrity": "sha512-rbKLsa4/scPP8AxaDRQfkLqfg8CbZ163dPqHMixou90uK/dx00LjCyUeS38/otdAYNZhrD0i5nu+k65qwhLX8w==", "dependencies": { "tslib": "^2.3.0" }, @@ -810,9 +810,9 @@ "node": "^14.15.0 || >=16.10.0" }, "peerDependencies": { - "@angular/common": "14.2.4", - "@angular/core": "14.2.4", - "@angular/platform-browser": "14.2.4", + "@angular/common": "14.2.8", + "@angular/core": "14.2.8", + "@angular/platform-browser": "14.2.8", "rxjs": "^6.5.3 || ^7.4.0" } }, @@ -3839,9 +3839,9 @@ } }, "node_modules/@ngtools/webpack": { - "version": "14.2.4", - "resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-14.2.4.tgz", - "integrity": "sha512-rmoUTz3FNhQctsmsq1HM7OfoT+pJiI2dhK0u6SqKXkP3OJ+dGW7NHQ5jYR7IATa7wLFe0vDiEr8caxZ5JBAEsQ==", + "version": "14.2.7", + "resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-14.2.7.tgz", + "integrity": "sha512-I47BdEybpzjfFFMFB691o9C+69RexLTgSm/VCyDn4M8DrGrZpgYNhxN+AEr1uA6Bi6MaPG6w+TMac5tNIaO4Yw==", "dev": true, "engines": { "node": "^14.15.0 || >=16.10.0", @@ -3998,13 +3998,13 @@ } }, "node_modules/@schematics/angular": { - "version": "14.2.4", - "resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-14.2.4.tgz", - "integrity": "sha512-9n7HyxZvoSR+Ynyvr8oEQ3zy5trSjCQMTF+fZSTCzCBEVHKGxqMyisI6KO4qcGeIQYGXWeBYrMsy9jMQFgK8dQ==", + "version": "14.2.7", + "resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-14.2.7.tgz", + "integrity": "sha512-ujtLu0gWARtJsRbN+P+McDO0Y0ygJjUN5016SdbmYDMcDJkwi+GYHU8Yvh/UONtmNor3JdV8AnZ8OmWTlswTDA==", "devOptional": true, "dependencies": { - "@angular-devkit/core": "14.2.4", - "@angular-devkit/schematics": "14.2.4", + "@angular-devkit/core": "14.2.7", + "@angular-devkit/schematics": "14.2.7", "jsonc-parser": "3.1.0" }, "engines": { @@ -5410,9 +5410,9 @@ "optional": true }, "node_modules/body-parser": { - "version": "1.20.0", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.0.tgz", - "integrity": "sha512-DfJ+q6EPcGKZD1QWUjSpqp+Q7bDQTsQIF4zfUAtZ6qk+H/3/QRhg9CEp39ss+/T2vw0+HaidC0ecJj/DRLIaKg==", + "version": "1.20.1", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", + "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==", "dev": true, "dependencies": { "bytes": "3.1.2", @@ -5423,7 +5423,7 @@ "http-errors": "2.0.0", "iconv-lite": "0.4.24", "on-finished": "2.4.1", - "qs": "6.10.3", + "qs": "6.11.0", "raw-body": "2.5.1", "type-is": "~1.6.18", "unpipe": "1.0.0" @@ -5467,9 +5467,9 @@ "dev": true }, "node_modules/body-parser/node_modules/qs": { - "version": "6.10.3", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.3.tgz", - "integrity": "sha512-wr7M2E0OFRfIfJZjKGieI8lBKb7fRCH4Fv5KNPEs7gJ8jadvotdsS08PzOKR7opXhZ/Xkjtt3WF9g38drmyRqQ==", + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", + "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", "dev": true, "dependencies": { "side-channel": "^1.0.4" @@ -7996,14 +7996,14 @@ } }, "node_modules/express": { - "version": "4.18.1", - "resolved": "https://registry.npmjs.org/express/-/express-4.18.1.tgz", - "integrity": "sha512-zZBcOX9TfehHQhtupq57OF8lFZ3UZi08Y97dwFCkD8p9d/d2Y3M+ykKcwaMDEL+4qyUolgBDX6AblpR3fL212Q==", + "version": "4.18.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz", + "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==", "dev": true, "dependencies": { "accepts": "~1.3.8", "array-flatten": "1.1.1", - "body-parser": "1.20.0", + "body-parser": "1.20.1", "content-disposition": "0.5.4", "content-type": "~1.0.4", "cookie": "0.5.0", @@ -8022,7 +8022,7 @@ "parseurl": "~1.3.3", "path-to-regexp": "0.1.7", "proxy-addr": "~2.0.7", - "qs": "6.10.3", + "qs": "6.11.0", "range-parser": "~1.2.1", "safe-buffer": "5.2.1", "send": "0.18.0", @@ -8068,9 +8068,9 @@ "dev": true }, "node_modules/express/node_modules/qs": { - "version": "6.10.3", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.3.tgz", - "integrity": "sha512-wr7M2E0OFRfIfJZjKGieI8lBKb7fRCH4Fv5KNPEs7gJ8jadvotdsS08PzOKR7opXhZ/Xkjtt3WF9g38drmyRqQ==", + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", + "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", "dev": true, "dependencies": { "side-channel": "^1.0.4" @@ -10217,51 +10217,59 @@ } }, "node_modules/jest-environment-jsdom": { - "version": "29.1.2", - "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-29.1.2.tgz", - "integrity": "sha512-D+XNIKia5+uDjSMwL/G1l6N9MCb7LymKI8FpcLo7kkISjc/Sa9w+dXXEa7u1Wijo3f8sVLqfxdGqYtRhmca+Xw==", + "version": "29.2.2", + "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-29.2.2.tgz", + "integrity": "sha512-5mNtTcky1+RYv9kxkwMwt7fkzyX4EJUarV7iI+NQLigpV4Hz4sgfOdP4kOpCHXbkRWErV7tgXoXLm2CKtucr+A==", "dev": true, "dependencies": { - "@jest/environment": "^29.1.2", - "@jest/fake-timers": "^29.1.2", - "@jest/types": "^29.1.2", + "@jest/environment": "^29.2.2", + "@jest/fake-timers": "^29.2.2", + "@jest/types": "^29.2.1", "@types/jsdom": "^20.0.0", "@types/node": "*", - "jest-mock": "^29.1.2", - "jest-util": "^29.1.2", + "jest-mock": "^29.2.2", + "jest-util": "^29.2.1", "jsdom": "^20.0.0" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "canvas": "^2.5.0" + }, + "peerDependenciesMeta": { + "canvas": { + "optional": true + } } }, "node_modules/jest-environment-jsdom/node_modules/@jest/environment": { - "version": "29.1.2", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.1.2.tgz", - "integrity": "sha512-rG7xZ2UeOfvOVzoLIJ0ZmvPl4tBEQ2n73CZJSlzUjPw4or1oSWC0s0Rk0ZX+pIBJ04aVr6hLWFn1DFtrnf8MhQ==", + "version": "29.2.2", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.2.2.tgz", + "integrity": "sha512-OWn+Vhu0I1yxuGBJEFFekMYc8aGBGrY4rt47SOh/IFaI+D7ZHCk7pKRiSoZ2/Ml7b0Ony3ydmEHRx/tEOC7H1A==", "dev": true, "dependencies": { - "@jest/fake-timers": "^29.1.2", - "@jest/types": "^29.1.2", + "@jest/fake-timers": "^29.2.2", + "@jest/types": "^29.2.1", "@types/node": "*", - "jest-mock": "^29.1.2" + "jest-mock": "^29.2.2" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-environment-jsdom/node_modules/@jest/fake-timers": { - "version": "29.1.2", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.1.2.tgz", - "integrity": "sha512-GppaEqS+QQYegedxVMpCe2xCXxxeYwQ7RsNx55zc8f+1q1qevkZGKequfTASI7ejmg9WwI+SJCrHe9X11bLL9Q==", + "version": "29.2.2", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.2.2.tgz", + "integrity": "sha512-nqaW3y2aSyZDl7zQ7t1XogsxeavNpH6kkdq+EpXncIDvAkjvFD7hmhcIs1nWloengEWUoWqkqSA6MSbf9w6DgA==", "dev": true, "dependencies": { - "@jest/types": "^29.1.2", + "@jest/types": "^29.2.1", "@sinonjs/fake-timers": "^9.1.2", "@types/node": "*", - "jest-message-util": "^29.1.2", - "jest-mock": "^29.1.2", - "jest-util": "^29.1.2" + "jest-message-util": "^29.2.1", + "jest-mock": "^29.2.2", + "jest-util": "^29.2.1" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" @@ -10280,9 +10288,9 @@ } }, "node_modules/jest-environment-jsdom/node_modules/@jest/types": { - "version": "29.1.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.1.2.tgz", - "integrity": "sha512-DcXGtoTykQB5jiwCmVr8H4vdg2OJhQex3qPkG+ISyDO7xQXbt/4R6dowcRyPemRnkH7JoHvZuxPBdlq+9JxFCg==", + "version": "29.2.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.2.1.tgz", + "integrity": "sha512-O/QNDQODLnINEPAI0cl9U6zUIDXEWXt6IC1o2N2QENuos7hlGUIthlKyV4p6ki3TvXFX071blj8HUhgLGquPjw==", "dev": true, "dependencies": { "@jest/schemas": "^29.0.0", @@ -10355,18 +10363,18 @@ } }, "node_modules/jest-environment-jsdom/node_modules/jest-message-util": { - "version": "29.1.2", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.1.2.tgz", - "integrity": "sha512-9oJ2Os+Qh6IlxLpmvshVbGUiSkZVc2FK+uGOm6tghafnB2RyjKAxMZhtxThRMxfX1J1SOMhTn9oK3/MutRWQJQ==", + "version": "29.2.1", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.2.1.tgz", + "integrity": "sha512-Dx5nEjw9V8C1/Yj10S/8ivA8F439VS8vTq1L7hEgwHFn9ovSKNpYW/kwNh7UglaEgXO42XxzKJB+2x0nSglFVw==", "dev": true, "dependencies": { "@babel/code-frame": "^7.12.13", - "@jest/types": "^29.1.2", + "@jest/types": "^29.2.1", "@types/stack-utils": "^2.0.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.9", "micromatch": "^4.0.4", - "pretty-format": "^29.1.2", + "pretty-format": "^29.2.1", "slash": "^3.0.0", "stack-utils": "^2.0.3" }, @@ -10375,26 +10383,26 @@ } }, "node_modules/jest-environment-jsdom/node_modules/jest-mock": { - "version": "29.1.2", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.1.2.tgz", - "integrity": "sha512-PFDAdjjWbjPUtQPkQufvniXIS3N9Tv7tbibePEjIIprzjgo0qQlyUiVMrT4vL8FaSJo1QXifQUOuPH3HQC/aMA==", + "version": "29.2.2", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.2.2.tgz", + "integrity": "sha512-1leySQxNAnivvbcx0sCB37itu8f4OX2S/+gxLAV4Z62shT4r4dTG9tACDywUAEZoLSr36aYUTsVp3WKwWt4PMQ==", "dev": true, "dependencies": { - "@jest/types": "^29.1.2", + "@jest/types": "^29.2.1", "@types/node": "*", - "jest-util": "^29.1.2" + "jest-util": "^29.2.1" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-environment-jsdom/node_modules/jest-util": { - "version": "29.1.2", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.1.2.tgz", - "integrity": "sha512-vPCk9F353i0Ymx3WQq3+a4lZ07NXu9Ca8wya6o4Fe4/aO1e1awMMprZ3woPFpKwghEOW+UXgd15vVotuNN9ONQ==", + "version": "29.2.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.2.1.tgz", + "integrity": "sha512-P5VWDj25r7kj7kl4pN2rG/RN2c1TLfYYYZYULnS/35nFDjBai+hBeo3MDrYZS7p6IoY3YHZnt2vq4L6mKnLk0g==", "dev": true, "dependencies": { - "@jest/types": "^29.1.2", + "@jest/types": "^29.2.1", "@types/node": "*", "chalk": "^4.0.0", "ci-info": "^3.2.0", @@ -10406,9 +10414,9 @@ } }, "node_modules/jest-environment-jsdom/node_modules/pretty-format": { - "version": "29.1.2", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.1.2.tgz", - "integrity": "sha512-CGJ6VVGXVRP2o2Dorl4mAwwvDWT25luIsYhkyVQW32E4nL+TgW939J7LlKT/npq5Cpq6j3s+sy+13yk7xYpBmg==", + "version": "29.2.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.2.1.tgz", + "integrity": "sha512-Y41Sa4aLCtKAXvwuIpTvcFBkyeYp2gdFWzXGA+ZNES3VwURIB165XO/z7CjETwzCCS53MjW/rLMyyqEnTtaOfA==", "dev": true, "dependencies": { "@jest/schemas": "^29.0.0", @@ -12516,9 +12524,9 @@ } }, "node_modules/memfs": { - "version": "3.4.7", - "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.4.7.tgz", - "integrity": "sha512-ygaiUSNalBX85388uskeCyhSAoOSgzBbtVCr9jA2RROssFL9Q19/ZXFqS+2Th2sr1ewNIWgFdLzLC3Yl1Zv+lw==", + "version": "3.4.9", + "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.4.9.tgz", + "integrity": "sha512-3rm8kbrzpUGRyPKSGuk387NZOwQ90O4rI9tsWQkzNW7BLSnKGp23RsEsKK8N8QVCrtJoAMqy3spxHC4os4G6PQ==", "dev": true, "dependencies": { "fs-monkey": "^1.0.3" @@ -12937,10 +12945,25 @@ "@angular/core": ">=14.0.0" } }, - "node_modules/ngx-ui-tour-core": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/ngx-ui-tour-core/-/ngx-ui-tour-core-9.0.0.tgz", - "integrity": "sha512-3HvrprosDaZm9jHi/w+oA8N9bPeaV9k0Y70nsEkRPRQ1jM302JyjGYFuM6/FzbXU5FITGLChtrFJpBn/Q4yJIA==", + "node_modules/ngx-ui-tour-ng-bootstrap": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/ngx-ui-tour-ng-bootstrap/-/ngx-ui-tour-ng-bootstrap-11.1.0.tgz", + "integrity": "sha512-VQbQA+c4aYtUe/6yzY6BzawDHhIxwH0uck3SpJmlhhHLmydm1OCRjlmhVJHEIPggwxGOvO5h/Vs6iLmmwxn//g==", + "dependencies": { + "ngx-ui-tour-core": "9.1.0", + "tslib": "^2.0.0" + }, + "peerDependencies": { + "@angular/common": "^14.0.0", + "@angular/core": "^14.0.0", + "@ng-bootstrap/ng-bootstrap": "^13.0.0", + "typescript": ">=3.8.0" + } + }, + "node_modules/ngx-ui-tour-ng-bootstrap/node_modules/ngx-ui-tour-core": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/ngx-ui-tour-core/-/ngx-ui-tour-core-9.1.0.tgz", + "integrity": "sha512-9fSvSoh0wUpaVFNo/D0Vs9NreL0esFBY3MFycONZD8b5SE7nX2+CZLzPbIVnigmj/KH3op5Pw8Pzkg2VHmXTcg==", "dependencies": { "tslib": "^2.0.0" }, @@ -12952,21 +12975,6 @@ "typescript": ">=3.8.0" } }, - "node_modules/ngx-ui-tour-ng-bootstrap": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/ngx-ui-tour-ng-bootstrap/-/ngx-ui-tour-ng-bootstrap-11.0.0.tgz", - "integrity": "sha512-oF5ySZEiO4ib/RfYno81V2UBaX7EMzxSPwfCdedDr38e5BEPTOrcCufOaiOfuQzQftg+7CC/BbFY8Df9kmeL1A==", - "dependencies": { - "ngx-ui-tour-core": "9.0.0", - "tslib": "^2.0.0" - }, - "peerDependencies": { - "@angular/common": "^14.0.0", - "@angular/core": "^14.0.0", - "@ng-bootstrap/ng-bootstrap": "^13.0.0", - "typescript": ">=3.8.0" - } - }, "node_modules/nice-napi": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/nice-napi/-/nice-napi-1.0.2.tgz", @@ -17854,12 +17862,12 @@ } }, "@angular-devkit/architect": { - "version": "0.1402.4", - "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1402.4.tgz", - "integrity": "sha512-lOgyKJ+KjBYWzgcxJ3vAy3RFkqRmSw3RY4thNsWOHLvzT8o33u3USDuOr6cDAQW12NjX9K7JDuvNlPbadjQbSQ==", + "version": "0.1402.7", + "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1402.7.tgz", + "integrity": "sha512-YZchteri2iUq5JICSH0BQjOU3ehE57+CMU8PBigcJZiaLa/GPiCuwD9QOsnwSzHJNYYx5C94uhtZUjPwUtIAIw==", "devOptional": true, "requires": { - "@angular-devkit/core": "14.2.4", + "@angular-devkit/core": "14.2.7", "rxjs": "6.6.7" }, "dependencies": { @@ -17881,15 +17889,15 @@ } }, "@angular-devkit/build-angular": { - "version": "14.2.4", - "resolved": "https://registry.npmjs.org/@angular-devkit/build-angular/-/build-angular-14.2.4.tgz", - "integrity": "sha512-VvwLmb5fiorcLO6Fko3GIeNDWsdoZxviHcHjq2IGkgTNMlvWwZhuSZ8kOhNIXUKFCZYpj7FiUm/ft8v0ilxFBg==", + "version": "14.2.7", + "resolved": "https://registry.npmjs.org/@angular-devkit/build-angular/-/build-angular-14.2.7.tgz", + "integrity": "sha512-Y58kcEmy8bSFyODtUFQzkuoZHNCji3fzRwGCiQYdAh/mkBf53CuVWoT9q7MrvGOc7Nmo2JiuwR/b7c543eVgfw==", "dev": true, "requires": { "@ampproject/remapping": "2.2.0", - "@angular-devkit/architect": "0.1402.4", - "@angular-devkit/build-webpack": "0.1402.4", - "@angular-devkit/core": "14.2.4", + "@angular-devkit/architect": "0.1402.7", + "@angular-devkit/build-webpack": "0.1402.7", + "@angular-devkit/core": "14.2.7", "@babel/core": "7.18.10", "@babel/generator": "7.18.12", "@babel/helper-annotate-as-pure": "7.18.6", @@ -17900,7 +17908,7 @@ "@babel/runtime": "7.18.9", "@babel/template": "7.18.10", "@discoveryjs/json-ext": "0.5.7", - "@ngtools/webpack": "14.2.4", + "@ngtools/webpack": "14.2.7", "ansi-colors": "4.1.3", "babel-loader": "8.2.5", "babel-plugin-istanbul": "6.1.1", @@ -17971,12 +17979,12 @@ } }, "@angular-devkit/build-webpack": { - "version": "0.1402.4", - "resolved": "https://registry.npmjs.org/@angular-devkit/build-webpack/-/build-webpack-0.1402.4.tgz", - "integrity": "sha512-hj80twvKlscktH3bILS4+iQckTQzUWO/hTrG0auvJIXHWOmfJDQTDEyIgoMUzhnibh/8xwf96cFAsFZc2d5kFA==", + "version": "0.1402.7", + "resolved": "https://registry.npmjs.org/@angular-devkit/build-webpack/-/build-webpack-0.1402.7.tgz", + "integrity": "sha512-aDhS/ODt8BwgtnNN73R7SuMC1GgoT5Pajn1nnIWvvpGj8XchLUbguptyl2v7D2QeYXXsd34Gtx8cDOr9PxYFTA==", "dev": true, "requires": { - "@angular-devkit/architect": "0.1402.4", + "@angular-devkit/architect": "0.1402.7", "rxjs": "6.6.7" }, "dependencies": { @@ -17998,9 +18006,9 @@ } }, "@angular-devkit/core": { - "version": "14.2.4", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-14.2.4.tgz", - "integrity": "sha512-NsvN1U42goBcibVR75vDp2NOFeSU+Wcekwf1r3Jbyz6a2l9Unf0v9BOWLXdigFY8xztbrOHJPSIbC+2rkvOUnw==", + "version": "14.2.7", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-14.2.7.tgz", + "integrity": "sha512-83SCYP3h6fglWMgAXFDc8HfOxk9t3ugK0onATXchctvA7blW4Vx8BSg3/DgbqCv+fF380SN8bYqqLJl8fQFdzg==", "devOptional": true, "requires": { "ajv": "8.11.0", @@ -18028,12 +18036,12 @@ } }, "@angular-devkit/schematics": { - "version": "14.2.4", - "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-14.2.4.tgz", - "integrity": "sha512-Pm2C7HBNslQavsqXh6/rcyAavmgzTxU3x7NoWwSBH+fIplLJjEFzHdnW9JJp59A2ONfqO0wND3yWKtjIoDAUqw==", + "version": "14.2.7", + "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-14.2.7.tgz", + "integrity": "sha512-3e2dpFXWl2Z4Gfm+KgY3gAeqsyu8utJMcDIg5sWRAXDeJJdAPc5LweCa8YZEn33Zr9cl8oK+FxlOr15RCyWLcA==", "devOptional": true, "requires": { - "@angular-devkit/core": "14.2.4", + "@angular-devkit/core": "14.2.7", "jsonc-parser": "3.1.0", "magic-string": "0.26.2", "ora": "5.4.1", @@ -18058,15 +18066,15 @@ } }, "@angular/cli": { - "version": "14.2.4", - "resolved": "https://registry.npmjs.org/@angular/cli/-/cli-14.2.4.tgz", - "integrity": "sha512-3YqwjPYlLzqQB0y6A7c3l9X1e0z418NjSQQD2e12N8y68V8nkTK4UcsDVpqb/7ce+xnQ7xGz2wb6DJddU4Wogw==", + "version": "14.2.7", + "resolved": "https://registry.npmjs.org/@angular/cli/-/cli-14.2.7.tgz", + "integrity": "sha512-RM4CJwtqD7cKFQ7hNGJ56s9YMeJxYqCN5Ss0SzsKN1nXYqz8HykMW8fhUbZQ9HFVy/Ml3LGoh1yGo/tXywAWcA==", "devOptional": true, "requires": { - "@angular-devkit/architect": "0.1402.4", - "@angular-devkit/core": "14.2.4", - "@angular-devkit/schematics": "14.2.4", - "@schematics/angular": "14.2.4", + "@angular-devkit/architect": "0.1402.7", + "@angular-devkit/core": "14.2.7", + "@angular-devkit/schematics": "14.2.7", + "@schematics/angular": "14.2.7", "@yarnpkg/lockfile": "1.1.0", "ansi-colors": "4.1.3", "debug": "4.3.4", @@ -18094,25 +18102,25 @@ } }, "@angular/common": { - "version": "14.2.4", - "resolved": "https://registry.npmjs.org/@angular/common/-/common-14.2.4.tgz", - "integrity": "sha512-nzmRUhdyKomgsf1vUdx7KOXS7OXkvdpF/1CSagqsIGYVLbL8cGZ6ROrdEuxkSsE9GUt/OAIkC4How4/LLPut1A==", + "version": "14.2.8", + "resolved": "https://registry.npmjs.org/@angular/common/-/common-14.2.8.tgz", + "integrity": "sha512-JSPN2h1EcyWjHWtOzRQmoX48ZacTjLAYwW9ZRmBpYs6Ptw5xZ39ARTJfQNcNnJleqYju2E6BNkGnLpbtWQjNDA==", "requires": { "tslib": "^2.3.0" } }, "@angular/compiler": { - "version": "14.2.4", - "resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-14.2.4.tgz", - "integrity": "sha512-fBvTPPWBYA65bAmrqKcnzUHAhZ/tfs+nG+IeDukn4TeyQplVjDYOlqjf84jYQubSIx8WTicZzRFn0dIGsPaSNw==", + "version": "14.2.8", + "resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-14.2.8.tgz", + "integrity": "sha512-lKwp3B4ZKNLgk/25Iyur8bjAwRL20auRoB4EuHrBf+928ftsjYUXTgi+0++DUjPENbpi59k6GcvMCNa6qccvIw==", "requires": { "tslib": "^2.3.0" } }, "@angular/compiler-cli": { - "version": "14.2.4", - "resolved": "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-14.2.4.tgz", - "integrity": "sha512-8kHA/Ujzr5aXic7T3iEJiu0JMfXRs/uDoi8W8dYWFe+0naGhxwWmHBHc/hhS1tpv9/wW2WOcT51RDa4OYHKDKw==", + "version": "14.2.8", + "resolved": "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-14.2.8.tgz", + "integrity": "sha512-QTftNrAyXOWzKFGY6/i9jh0LB2cOxmykepG4c53wH9LblGvWFztlVOhcoU8tpQSSH8t3EYvGs2r8oUuxcYm5Cw==", "requires": { "@babel/core": "^7.17.2", "chokidar": "^3.0.0", @@ -18127,25 +18135,25 @@ } }, "@angular/core": { - "version": "14.2.4", - "resolved": "https://registry.npmjs.org/@angular/core/-/core-14.2.4.tgz", - "integrity": "sha512-wB19wKmZE+X07mLbxYyqeg3v1JXy8m0+ShZD2oY3dmgk1mXOf5XVQxRZohGTrbPw83EdSWwx3vz+jjylGunVZQ==", + "version": "14.2.8", + "resolved": "https://registry.npmjs.org/@angular/core/-/core-14.2.8.tgz", + "integrity": "sha512-cgnII9vJGJDLsfr7KsBfU2l+QQUmQIRIP3ImKhBxicw2IHKCSb2mYwoeLV46jaLyHyUMTLRHKUYUR4XtSPnb8A==", "requires": { "tslib": "^2.3.0" } }, "@angular/forms": { - "version": "14.2.4", - "resolved": "https://registry.npmjs.org/@angular/forms/-/forms-14.2.4.tgz", - "integrity": "sha512-m1asD8SazzMPzcli054zwLYz7hiXiaCXfqmQOFdQQd3OnPNKeCGDS8GFX7Yd/+3fz4REGeSon9YRhq7/W0TDlA==", + "version": "14.2.8", + "resolved": "https://registry.npmjs.org/@angular/forms/-/forms-14.2.8.tgz", + "integrity": "sha512-OaL7Gi6STxJza7yn0qgmh6+hV6NVbtGmunpzrn9cR1k5TeE4ZtXu1z7VZesbZ9kZ3F6U9CmygFt0csf7j1d+Ow==", "requires": { "tslib": "^2.3.0" } }, "@angular/localize": { - "version": "14.2.4", - "resolved": "https://registry.npmjs.org/@angular/localize/-/localize-14.2.4.tgz", - "integrity": "sha512-35BKWV5y5aGGbnLIY9xcPs4i8KGqYBidPtqlU1tg585y0szzFBuHdF4jNrAYTwjGk7fnxYYLZQygM/GtxFwLUA==", + "version": "14.2.8", + "resolved": "https://registry.npmjs.org/@angular/localize/-/localize-14.2.8.tgz", + "integrity": "sha512-ph+ZLl1sXoNnw9AH4aHyI10T0sNCUTtZeGGDTPJnfOQgqfleOvgPxCNNNdi4z02XcLjVE9CKllcaOQY8zwKlZg==", "requires": { "@babel/core": "7.18.9", "glob": "8.0.3", @@ -18202,25 +18210,25 @@ } }, "@angular/platform-browser": { - "version": "14.2.4", - "resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-14.2.4.tgz", - "integrity": "sha512-/NAQXYLgyeb2L15EsaKgGEn50GH/O3t1FOjBvVZg6L423X0H6dIOL4bxbLcKAj9+bUDtdUzDiDoYyt6YEidH+g==", + "version": "14.2.8", + "resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-14.2.8.tgz", + "integrity": "sha512-tSASBLXoBE0/Gt6d2nC6BJ1DvbGY5wo2Lb+8WCLSvkfsgVqOh4uRuJ2a0wwjeLFd0ZNmpjG42Ijba4btmCpIjg==", "requires": { "tslib": "^2.3.0" } }, "@angular/platform-browser-dynamic": { - "version": "14.2.4", - "resolved": "https://registry.npmjs.org/@angular/platform-browser-dynamic/-/platform-browser-dynamic-14.2.4.tgz", - "integrity": "sha512-6jEVKzIqT9lipq4xZftBskHKl3jrL1pQbK8diirJH0mNeuj0wvE+fqfKtVVl898OI/iJ3aAKyQf5YmOe1k8PAw==", + "version": "14.2.8", + "resolved": "https://registry.npmjs.org/@angular/platform-browser-dynamic/-/platform-browser-dynamic-14.2.8.tgz", + "integrity": "sha512-CPK8wHnKke8AUKR92XrFuanaKNXDzDm3uVI3DD0NxBo+fLAkiuVaDVIGgO6n6SxQVtwjXJtMXqQuNdzUg4Q9uQ==", "requires": { "tslib": "^2.3.0" } }, "@angular/router": { - "version": "14.2.4", - "resolved": "https://registry.npmjs.org/@angular/router/-/router-14.2.4.tgz", - "integrity": "sha512-zjsiy/1zrZfZnfIbo2vVgZ+UhCo3okabVr43eIvJhBwcNKzM8Zv17oN9FFlWvSzKKkbsoNIgJkTI85L1YsKtjg==", + "version": "14.2.8", + "resolved": "https://registry.npmjs.org/@angular/router/-/router-14.2.8.tgz", + "integrity": "sha512-rbKLsa4/scPP8AxaDRQfkLqfg8CbZ163dPqHMixou90uK/dx00LjCyUeS38/otdAYNZhrD0i5nu+k65qwhLX8w==", "requires": { "tslib": "^2.3.0" } @@ -20351,9 +20359,9 @@ } }, "@ngtools/webpack": { - "version": "14.2.4", - "resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-14.2.4.tgz", - "integrity": "sha512-rmoUTz3FNhQctsmsq1HM7OfoT+pJiI2dhK0u6SqKXkP3OJ+dGW7NHQ5jYR7IATa7wLFe0vDiEr8caxZ5JBAEsQ==", + "version": "14.2.7", + "resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-14.2.7.tgz", + "integrity": "sha512-I47BdEybpzjfFFMFB691o9C+69RexLTgSm/VCyDn4M8DrGrZpgYNhxN+AEr1uA6Bi6MaPG6w+TMac5tNIaO4Yw==", "dev": true, "requires": {} }, @@ -20464,13 +20472,13 @@ "integrity": "sha512-50/17A98tWUfQ176raKiOGXuYpLyyVMkxxG6oylzL3BPOlA6ADGdK7EYunSa4I064xerltq9TGXs8HmOk5E+vw==" }, "@schematics/angular": { - "version": "14.2.4", - "resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-14.2.4.tgz", - "integrity": "sha512-9n7HyxZvoSR+Ynyvr8oEQ3zy5trSjCQMTF+fZSTCzCBEVHKGxqMyisI6KO4qcGeIQYGXWeBYrMsy9jMQFgK8dQ==", + "version": "14.2.7", + "resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-14.2.7.tgz", + "integrity": "sha512-ujtLu0gWARtJsRbN+P+McDO0Y0ygJjUN5016SdbmYDMcDJkwi+GYHU8Yvh/UONtmNor3JdV8AnZ8OmWTlswTDA==", "devOptional": true, "requires": { - "@angular-devkit/core": "14.2.4", - "@angular-devkit/schematics": "14.2.4", + "@angular-devkit/core": "14.2.7", + "@angular-devkit/schematics": "14.2.7", "jsonc-parser": "3.1.0" } }, @@ -21661,9 +21669,9 @@ "optional": true }, "body-parser": { - "version": "1.20.0", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.0.tgz", - "integrity": "sha512-DfJ+q6EPcGKZD1QWUjSpqp+Q7bDQTsQIF4zfUAtZ6qk+H/3/QRhg9CEp39ss+/T2vw0+HaidC0ecJj/DRLIaKg==", + "version": "1.20.1", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", + "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==", "dev": true, "requires": { "bytes": "3.1.2", @@ -21674,7 +21682,7 @@ "http-errors": "2.0.0", "iconv-lite": "0.4.24", "on-finished": "2.4.1", - "qs": "6.10.3", + "qs": "6.11.0", "raw-body": "2.5.1", "type-is": "~1.6.18", "unpipe": "1.0.0" @@ -21708,9 +21716,9 @@ "dev": true }, "qs": { - "version": "6.10.3", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.3.tgz", - "integrity": "sha512-wr7M2E0OFRfIfJZjKGieI8lBKb7fRCH4Fv5KNPEs7gJ8jadvotdsS08PzOKR7opXhZ/Xkjtt3WF9g38drmyRqQ==", + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", + "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", "dev": true, "requires": { "side-channel": "^1.0.4" @@ -23488,14 +23496,14 @@ } }, "express": { - "version": "4.18.1", - "resolved": "https://registry.npmjs.org/express/-/express-4.18.1.tgz", - "integrity": "sha512-zZBcOX9TfehHQhtupq57OF8lFZ3UZi08Y97dwFCkD8p9d/d2Y3M+ykKcwaMDEL+4qyUolgBDX6AblpR3fL212Q==", + "version": "4.18.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz", + "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==", "dev": true, "requires": { "accepts": "~1.3.8", "array-flatten": "1.1.1", - "body-parser": "1.20.0", + "body-parser": "1.20.1", "content-disposition": "0.5.4", "content-type": "~1.0.4", "cookie": "0.5.0", @@ -23514,7 +23522,7 @@ "parseurl": "~1.3.3", "path-to-regexp": "0.1.7", "proxy-addr": "~2.0.7", - "qs": "6.10.3", + "qs": "6.11.0", "range-parser": "~1.2.1", "safe-buffer": "5.2.1", "send": "0.18.0", @@ -23554,9 +23562,9 @@ "dev": true }, "qs": { - "version": "6.10.3", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.3.tgz", - "integrity": "sha512-wr7M2E0OFRfIfJZjKGieI8lBKb7fRCH4Fv5KNPEs7gJ8jadvotdsS08PzOKR7opXhZ/Xkjtt3WF9g38drmyRqQ==", + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", + "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", "dev": true, "requires": { "side-channel": "^1.0.4" @@ -25146,45 +25154,45 @@ } }, "jest-environment-jsdom": { - "version": "29.1.2", - "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-29.1.2.tgz", - "integrity": "sha512-D+XNIKia5+uDjSMwL/G1l6N9MCb7LymKI8FpcLo7kkISjc/Sa9w+dXXEa7u1Wijo3f8sVLqfxdGqYtRhmca+Xw==", + "version": "29.2.2", + "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-29.2.2.tgz", + "integrity": "sha512-5mNtTcky1+RYv9kxkwMwt7fkzyX4EJUarV7iI+NQLigpV4Hz4sgfOdP4kOpCHXbkRWErV7tgXoXLm2CKtucr+A==", "dev": true, "requires": { - "@jest/environment": "^29.1.2", - "@jest/fake-timers": "^29.1.2", - "@jest/types": "^29.1.2", + "@jest/environment": "^29.2.2", + "@jest/fake-timers": "^29.2.2", + "@jest/types": "^29.2.1", "@types/jsdom": "^20.0.0", "@types/node": "*", - "jest-mock": "^29.1.2", - "jest-util": "^29.1.2", + "jest-mock": "^29.2.2", + "jest-util": "^29.2.1", "jsdom": "^20.0.0" }, "dependencies": { "@jest/environment": { - "version": "29.1.2", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.1.2.tgz", - "integrity": "sha512-rG7xZ2UeOfvOVzoLIJ0ZmvPl4tBEQ2n73CZJSlzUjPw4or1oSWC0s0Rk0ZX+pIBJ04aVr6hLWFn1DFtrnf8MhQ==", + "version": "29.2.2", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.2.2.tgz", + "integrity": "sha512-OWn+Vhu0I1yxuGBJEFFekMYc8aGBGrY4rt47SOh/IFaI+D7ZHCk7pKRiSoZ2/Ml7b0Ony3ydmEHRx/tEOC7H1A==", "dev": true, "requires": { - "@jest/fake-timers": "^29.1.2", - "@jest/types": "^29.1.2", + "@jest/fake-timers": "^29.2.2", + "@jest/types": "^29.2.1", "@types/node": "*", - "jest-mock": "^29.1.2" + "jest-mock": "^29.2.2" } }, "@jest/fake-timers": { - "version": "29.1.2", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.1.2.tgz", - "integrity": "sha512-GppaEqS+QQYegedxVMpCe2xCXxxeYwQ7RsNx55zc8f+1q1qevkZGKequfTASI7ejmg9WwI+SJCrHe9X11bLL9Q==", + "version": "29.2.2", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.2.2.tgz", + "integrity": "sha512-nqaW3y2aSyZDl7zQ7t1XogsxeavNpH6kkdq+EpXncIDvAkjvFD7hmhcIs1nWloengEWUoWqkqSA6MSbf9w6DgA==", "dev": true, "requires": { - "@jest/types": "^29.1.2", + "@jest/types": "^29.2.1", "@sinonjs/fake-timers": "^9.1.2", "@types/node": "*", - "jest-message-util": "^29.1.2", - "jest-mock": "^29.1.2", - "jest-util": "^29.1.2" + "jest-message-util": "^29.2.1", + "jest-mock": "^29.2.2", + "jest-util": "^29.2.1" } }, "@jest/schemas": { @@ -25197,9 +25205,9 @@ } }, "@jest/types": { - "version": "29.1.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.1.2.tgz", - "integrity": "sha512-DcXGtoTykQB5jiwCmVr8H4vdg2OJhQex3qPkG+ISyDO7xQXbt/4R6dowcRyPemRnkH7JoHvZuxPBdlq+9JxFCg==", + "version": "29.2.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.2.1.tgz", + "integrity": "sha512-O/QNDQODLnINEPAI0cl9U6zUIDXEWXt6IC1o2N2QENuos7hlGUIthlKyV4p6ki3TvXFX071blj8HUhgLGquPjw==", "dev": true, "requires": { "@jest/schemas": "^29.0.0", @@ -25251,40 +25259,40 @@ "dev": true }, "jest-message-util": { - "version": "29.1.2", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.1.2.tgz", - "integrity": "sha512-9oJ2Os+Qh6IlxLpmvshVbGUiSkZVc2FK+uGOm6tghafnB2RyjKAxMZhtxThRMxfX1J1SOMhTn9oK3/MutRWQJQ==", + "version": "29.2.1", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.2.1.tgz", + "integrity": "sha512-Dx5nEjw9V8C1/Yj10S/8ivA8F439VS8vTq1L7hEgwHFn9ovSKNpYW/kwNh7UglaEgXO42XxzKJB+2x0nSglFVw==", "dev": true, "requires": { "@babel/code-frame": "^7.12.13", - "@jest/types": "^29.1.2", + "@jest/types": "^29.2.1", "@types/stack-utils": "^2.0.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.9", "micromatch": "^4.0.4", - "pretty-format": "^29.1.2", + "pretty-format": "^29.2.1", "slash": "^3.0.0", "stack-utils": "^2.0.3" } }, "jest-mock": { - "version": "29.1.2", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.1.2.tgz", - "integrity": "sha512-PFDAdjjWbjPUtQPkQufvniXIS3N9Tv7tbibePEjIIprzjgo0qQlyUiVMrT4vL8FaSJo1QXifQUOuPH3HQC/aMA==", + "version": "29.2.2", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.2.2.tgz", + "integrity": "sha512-1leySQxNAnivvbcx0sCB37itu8f4OX2S/+gxLAV4Z62shT4r4dTG9tACDywUAEZoLSr36aYUTsVp3WKwWt4PMQ==", "dev": true, "requires": { - "@jest/types": "^29.1.2", + "@jest/types": "^29.2.1", "@types/node": "*", - "jest-util": "^29.1.2" + "jest-util": "^29.2.1" } }, "jest-util": { - "version": "29.1.2", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.1.2.tgz", - "integrity": "sha512-vPCk9F353i0Ymx3WQq3+a4lZ07NXu9Ca8wya6o4Fe4/aO1e1awMMprZ3woPFpKwghEOW+UXgd15vVotuNN9ONQ==", + "version": "29.2.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.2.1.tgz", + "integrity": "sha512-P5VWDj25r7kj7kl4pN2rG/RN2c1TLfYYYZYULnS/35nFDjBai+hBeo3MDrYZS7p6IoY3YHZnt2vq4L6mKnLk0g==", "dev": true, "requires": { - "@jest/types": "^29.1.2", + "@jest/types": "^29.2.1", "@types/node": "*", "chalk": "^4.0.0", "ci-info": "^3.2.0", @@ -25293,9 +25301,9 @@ } }, "pretty-format": { - "version": "29.1.2", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.1.2.tgz", - "integrity": "sha512-CGJ6VVGXVRP2o2Dorl4mAwwvDWT25luIsYhkyVQW32E4nL+TgW939J7LlKT/npq5Cpq6j3s+sy+13yk7xYpBmg==", + "version": "29.2.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.2.1.tgz", + "integrity": "sha512-Y41Sa4aLCtKAXvwuIpTvcFBkyeYp2gdFWzXGA+ZNES3VwURIB165XO/z7CjETwzCCS53MjW/rLMyyqEnTtaOfA==", "dev": true, "requires": { "@jest/schemas": "^29.0.0", @@ -26878,9 +26886,9 @@ "dev": true }, "memfs": { - "version": "3.4.7", - "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.4.7.tgz", - "integrity": "sha512-ygaiUSNalBX85388uskeCyhSAoOSgzBbtVCr9jA2RROssFL9Q19/ZXFqS+2Th2sr1ewNIWgFdLzLC3Yl1Zv+lw==", + "version": "3.4.9", + "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.4.9.tgz", + "integrity": "sha512-3rm8kbrzpUGRyPKSGuk387NZOwQ90O4rI9tsWQkzNW7BLSnKGp23RsEsKK8N8QVCrtJoAMqy3spxHC4os4G6PQ==", "dev": true, "requires": { "fs-monkey": "^1.0.3" @@ -27187,21 +27195,23 @@ "tslib": "^2.3.0" } }, - "ngx-ui-tour-core": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/ngx-ui-tour-core/-/ngx-ui-tour-core-9.0.0.tgz", - "integrity": "sha512-3HvrprosDaZm9jHi/w+oA8N9bPeaV9k0Y70nsEkRPRQ1jM302JyjGYFuM6/FzbXU5FITGLChtrFJpBn/Q4yJIA==", - "requires": { - "tslib": "^2.0.0" - } - }, "ngx-ui-tour-ng-bootstrap": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/ngx-ui-tour-ng-bootstrap/-/ngx-ui-tour-ng-bootstrap-11.0.0.tgz", - "integrity": "sha512-oF5ySZEiO4ib/RfYno81V2UBaX7EMzxSPwfCdedDr38e5BEPTOrcCufOaiOfuQzQftg+7CC/BbFY8Df9kmeL1A==", + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/ngx-ui-tour-ng-bootstrap/-/ngx-ui-tour-ng-bootstrap-11.1.0.tgz", + "integrity": "sha512-VQbQA+c4aYtUe/6yzY6BzawDHhIxwH0uck3SpJmlhhHLmydm1OCRjlmhVJHEIPggwxGOvO5h/Vs6iLmmwxn//g==", "requires": { - "ngx-ui-tour-core": "9.0.0", + "ngx-ui-tour-core": "9.1.0", "tslib": "^2.0.0" + }, + "dependencies": { + "ngx-ui-tour-core": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/ngx-ui-tour-core/-/ngx-ui-tour-core-9.1.0.tgz", + "integrity": "sha512-9fSvSoh0wUpaVFNo/D0Vs9NreL0esFBY3MFycONZD8b5SE7nX2+CZLzPbIVnigmj/KH3op5Pw8Pzkg2VHmXTcg==", + "requires": { + "tslib": "^2.0.0" + } + } } }, "nice-napi": { diff --git a/src-ui/package.json b/src-ui/package.json index 02afd7e79..39e14d274 100644 --- a/src-ui/package.json +++ b/src-ui/package.json @@ -13,14 +13,14 @@ }, "private": true, "dependencies": { - "@angular/common": "~14.2.4", - "@angular/compiler": "~14.2.4", - "@angular/core": "~14.2.4", - "@angular/forms": "~14.2.4", - "@angular/localize": "~14.2.4", - "@angular/platform-browser": "~14.2.4", - "@angular/platform-browser-dynamic": "~14.2.4", - "@angular/router": "~14.2.4", + "@angular/common": "~14.2.8", + "@angular/compiler": "~14.2.8", + "@angular/core": "~14.2.8", + "@angular/forms": "~14.2.8", + "@angular/localize": "~14.2.8", + "@angular/platform-browser": "~14.2.8", + "@angular/platform-browser-dynamic": "~14.2.8", + "@angular/router": "~14.2.8", "@ng-bootstrap/ng-bootstrap": "^13.0.0", "@ng-select/ng-select": "^9.0.2", "@ngneat/dirty-check-forms": "^3.0.2", @@ -31,7 +31,7 @@ "ngx-color": "^8.0.3", "ngx-cookie-service": "^14.0.1", "ngx-file-drop": "^14.0.1", - "ngx-ui-tour-ng-bootstrap": "^11.0.0", + "ngx-ui-tour-ng-bootstrap": "^11.1.0", "rxjs": "~7.5.7", "tslib": "^2.3.1", "uuid": "^9.0.0", @@ -39,15 +39,15 @@ }, "devDependencies": { "@angular-builders/jest": "14.0.1", - "@angular-devkit/build-angular": "~14.2.4", - "@angular/cli": "~14.2.4", - "@angular/compiler-cli": "~14.2.4", + "@angular-devkit/build-angular": "~14.2.7", + "@angular/cli": "~14.2.7", + "@angular/compiler-cli": "~14.2.8", "@types/jest": "28.1.6", "@types/node": "^18.7.23", "codelyzer": "^6.0.2", "concurrently": "7.4.0", "jest": "28.1.3", - "jest-environment-jsdom": "^29.1.2", + "jest-environment-jsdom": "^29.2.2", "jest-preset-angular": "^12.2.2", "ts-node": "~10.9.1", "tslint": "~6.1.3", diff --git a/src-ui/src/app/app-routing.module.ts b/src-ui/src/app/app-routing.module.ts index c62357c5d..4dad24c51 100644 --- a/src-ui/src/app/app-routing.module.ts +++ b/src-ui/src/app/app-routing.module.ts @@ -15,6 +15,7 @@ import { DirtyFormGuard } from './guards/dirty-form.guard' import { StoragePathListComponent } from './components/manage/storage-path-list/storage-path-list.component' import { TasksComponent } from './components/manage/tasks/tasks.component' import { DirtyDocGuard } from './guards/dirty-doc.guard' +import { DirtySavedViewGuard } from './guards/dirty-saved-view.guard' const routes: Routes = [ { path: '', redirectTo: 'dashboard', pathMatch: 'full' }, @@ -24,8 +25,16 @@ const routes: Routes = [ canDeactivate: [DirtyDocGuard], children: [ { path: 'dashboard', component: DashboardComponent }, - { path: 'documents', component: DocumentListComponent }, - { path: 'view/:id', component: DocumentListComponent }, + { + path: 'documents', + component: DocumentListComponent, + canDeactivate: [DirtySavedViewGuard], + }, + { + path: 'view/:id', + component: DocumentListComponent, + canDeactivate: [DirtySavedViewGuard], + }, { path: 'documents/:id', component: DocumentDetailComponent }, { path: 'asn/:id', component: DocumentAsnComponent }, { path: 'tags', component: TagListComponent }, diff --git a/src-ui/src/app/app.module.ts b/src-ui/src/app/app.module.ts index 02fd8ea66..3d0a7e3c7 100644 --- a/src-ui/src/app/app.module.ts +++ b/src-ui/src/app/app.module.ts @@ -24,6 +24,7 @@ import { CorrespondentEditDialogComponent } from './components/common/edit-dialo import { TagEditDialogComponent } from './components/common/edit-dialog/tag-edit-dialog/tag-edit-dialog.component' import { DocumentTypeEditDialogComponent } from './components/common/edit-dialog/document-type-edit-dialog/document-type-edit-dialog.component' import { TagComponent } from './components/common/tag/tag.component' +import { ClearableBadge } from './components/common/clearable-badge/clearable-badge.component' import { PageHeaderComponent } from './components/common/page-header/page-header.component' import { AppFrameComponent } from './components/app-frame/app-frame.component' import { ToastsComponent } from './components/common/toasts/toasts.component' @@ -69,6 +70,7 @@ import { ColorComponent } from './components/common/input/color/color.component' import { DocumentAsnComponent } from './components/document-asn/document-asn.component' import { DocumentCommentsComponent } from './components/document-comments/document-comments.component' import { DirtyDocGuard } from './guards/dirty-doc.guard' +import { DirtySavedViewGuard } from './guards/dirty-saved-view.guard' import { StoragePathListComponent } from './components/manage/storage-path-list/storage-path-list.component' import { StoragePathEditDialogComponent } from './components/common/edit-dialog/storage-path-edit-dialog/storage-path-edit-dialog.component' import { SettingsService } from './services/settings.service' @@ -141,6 +143,7 @@ function initializeApp(settings: SettingsService) { DocumentTypeEditDialogComponent, StoragePathEditDialogComponent, TagComponent, + ClearableBadge, PageHeaderComponent, AppFrameComponent, ToastsComponent, @@ -215,6 +218,7 @@ function initializeApp(settings: SettingsService) { { provide: NgbDateAdapter, useClass: ISODateAdapter }, { provide: NgbDateParserFormatter, useClass: LocalizedDateParserFormatter }, DirtyDocGuard, + DirtySavedViewGuard, ], bootstrap: [AppComponent], }) diff --git a/src-ui/src/app/components/app-frame/app-frame.component.html b/src-ui/src/app/components/app-frame/app-frame.component.html index 3700105f3..41bd50970 100644 --- a/src-ui/src/app/components/app-frame/app-frame.component.html +++ b/src-ui/src/app/components/app-frame/app-frame.component.html @@ -16,7 +16,12 @@ + [formControl]="searchField" [ngbTypeahead]="searchAutoComplete" (keyup)="searchFieldKeyup($event)" (selectItem)="itemSelected($event)" i18n-placeholder> +
    diff --git a/src-ui/src/app/components/app-frame/app-frame.component.scss b/src-ui/src/app/components/app-frame/app-frame.component.scss index 755f20696..0bd96f33e 100644 --- a/src-ui/src/app/components/app-frame/app-frame.component.scss +++ b/src-ui/src/app/components/app-frame/app-frame.component.scss @@ -243,17 +243,18 @@ main { form { position: relative; + + > svg { + position: absolute; + left: 0.6rem; + top: 0.5rem; + color: rgba(255, 255, 255, 0.6); + } } - svg { - position: absolute; - left: 0.6rem; - top: 0.5rem; - color: rgba(255, 255, 255, 0.6); - } &:focus-within { - svg { + form > svg { display: none; } diff --git a/src-ui/src/app/components/app-frame/app-frame.component.ts b/src-ui/src/app/components/app-frame/app-frame.component.ts index b189409a8..d637a32b6 100644 --- a/src-ui/src/app/components/app-frame/app-frame.component.ts +++ b/src-ui/src/app/components/app-frame/app-frame.component.ts @@ -93,6 +93,20 @@ export class AppFrameComponent implements OnInit, ComponentCanDeactivate { searchField = new FormControl('') + get searchFieldEmpty(): boolean { + return this.searchField.value.trim().length == 0 + } + + resetSearchField() { + this.searchField.reset('') + } + + searchFieldKeyup(event: KeyboardEvent) { + if (event.key == 'Escape') { + this.resetSearchField() + } + } + get openDocuments(): PaperlessDocument[] { return this.openDocumentsService.getOpenDocuments() } diff --git a/src-ui/src/app/components/common/clearable-badge/clearable-badge.component.html b/src-ui/src/app/components/common/clearable-badge/clearable-badge.component.html new file mode 100644 index 000000000..57b3ba39a --- /dev/null +++ b/src-ui/src/app/components/common/clearable-badge/clearable-badge.component.html @@ -0,0 +1,9 @@ + diff --git a/src-ui/src/app/components/common/clearable-badge/clearable-badge.component.scss b/src-ui/src/app/components/common/clearable-badge/clearable-badge.component.scss new file mode 100644 index 000000000..68f6478c4 --- /dev/null +++ b/src-ui/src/app/components/common/clearable-badge/clearable-badge.component.scss @@ -0,0 +1,28 @@ +.badge { + min-width: 20px; + min-height: 20px; +} + +.x { + display: none; +} + +.number { + min-width: 1em; + min-height: 1em; + display: inline-block; +} + +button:hover { + .check, + .number { + opacity: 0 !important; + } + + .x { + display: inline-block; + position: absolute; + top: 5px; + left: calc(50% - 4px); + } +} diff --git a/src-ui/src/app/components/common/clearable-badge/clearable-badge.component.ts b/src-ui/src/app/components/common/clearable-badge/clearable-badge.component.ts new file mode 100644 index 000000000..93f63d4d8 --- /dev/null +++ b/src-ui/src/app/components/common/clearable-badge/clearable-badge.component.ts @@ -0,0 +1,33 @@ +import { Component, Input, Output, EventEmitter } from '@angular/core' + +@Component({ + selector: 'app-clearable-badge', + templateUrl: './clearable-badge.component.html', + styleUrls: ['./clearable-badge.component.scss'], +}) +export class ClearableBadge { + constructor() {} + + @Input() + number: number + + @Input() + selected: boolean + + @Output() + cleared: EventEmitter = new EventEmitter() + + get active(): boolean { + return this.selected || this.number > -1 + } + + get isNumbered(): boolean { + return this.number > -1 + } + + onClick(event: PointerEvent) { + this.cleared.emit(true) + event.stopImmediatePropagation() + event.preventDefault() + } +} diff --git a/src-ui/src/app/components/common/confirm-dialog/confirm-dialog.component.html b/src-ui/src/app/components/common/confirm-dialog/confirm-dialog.component.html index 92e27e370..290581a47 100644 --- a/src-ui/src/app/components/common/confirm-dialog/confirm-dialog.component.html +++ b/src-ui/src/app/components/common/confirm-dialog/confirm-dialog.component.html @@ -16,4 +16,7 @@ {{ seconds | number: '1.0-0' }} seconds + diff --git a/src-ui/src/app/components/common/confirm-dialog/confirm-dialog.component.ts b/src-ui/src/app/components/common/confirm-dialog/confirm-dialog.component.ts index ddf0bfd7c..59d84bbe8 100644 --- a/src-ui/src/app/components/common/confirm-dialog/confirm-dialog.component.ts +++ b/src-ui/src/app/components/common/confirm-dialog/confirm-dialog.component.ts @@ -13,6 +13,9 @@ export class ConfirmDialogComponent { @Output() public confirmClicked = new EventEmitter() + @Output() + public alternativeClicked = new EventEmitter() + @Input() title = $localize`Confirmation` @@ -28,14 +31,22 @@ export class ConfirmDialogComponent { @Input() btnCaption = $localize`Confirm` + @Input() + alternativeBtnClass = 'btn-secondary' + + @Input() + alternativeBtnCaption + @Input() buttonsEnabled = true confirmButtonEnabled = true + alternativeButtonEnabled = true seconds = 0 secondsTotal = 0 confirmSubject: Subject + alternativeSubject: Subject delayConfirm(seconds: number) { const refreshInterval = 0.15 // s @@ -68,4 +79,10 @@ export class ConfirmDialogComponent { this.confirmSubject?.next(true) this.confirmSubject?.complete() } + + alternative() { + this.alternativeClicked.emit() + this.alternativeSubject?.next(true) + this.alternativeSubject?.complete() + } } diff --git a/src-ui/src/app/components/common/date-dropdown/date-dropdown.component.html b/src-ui/src/app/components/common/date-dropdown/date-dropdown.component.html index 6e5a7d928..58634b4d0 100644 --- a/src-ui/src/app/components/common/date-dropdown/date-dropdown.component.html +++ b/src-ui/src/app/components/common/date-dropdown/date-dropdown.component.html @@ -1,11 +1,17 @@
    @@ -54,12 +59,14 @@ title="Created" i18n-title (datesSet)="updateRules()" [(dateBefore)]="dateCreatedBefore" - [(dateAfter)]="dateCreatedAfter"> + [(dateAfter)]="dateCreatedAfter" + [(relativeDate)]="dateCreatedRelativeDate"> + [(relativeDate)]="dateAddedRelativeDate">
    diff --git a/src-ui/src/app/components/document-list/filter-editor/filter-editor.component.scss b/src-ui/src/app/components/document-list/filter-editor/filter-editor.component.scss index 0e8796b3d..82ad7e7a5 100644 --- a/src-ui/src/app/components/document-list/filter-editor/filter-editor.component.scss +++ b/src-ui/src/app/components/document-list/filter-editor/filter-editor.component.scss @@ -21,3 +21,7 @@ input[type="text"] { min-width: 120px; } + +.z-10 { + z-index: 10; +} diff --git a/src-ui/src/app/components/document-list/filter-editor/filter-editor.component.ts b/src-ui/src/app/components/document-list/filter-editor/filter-editor.component.ts index d5295f697..44f524149 100644 --- a/src-ui/src/app/components/document-list/filter-editor/filter-editor.component.ts +++ b/src-ui/src/app/components/document-list/filter-editor/filter-editor.component.ts @@ -44,6 +44,7 @@ import { DocumentService } from 'src/app/services/rest/document.service' import { PaperlessDocument } from 'src/app/data/paperless-document' import { PaperlessStoragePath } from 'src/app/data/paperless-storage-path' import { StoragePathService } from 'src/app/services/rest/storage-path.service' +import { RelativeDate } from '../../common/date-dropdown/date-dropdown.component' const TEXT_FILTER_TARGET_TITLE = 'title' const TEXT_FILTER_TARGET_TITLE_CONTENT = 'title-content' @@ -57,6 +58,27 @@ const TEXT_FILTER_MODIFIER_NOTNULL = 'not null' const TEXT_FILTER_MODIFIER_GT = 'greater' const TEXT_FILTER_MODIFIER_LT = 'less' +const RELATIVE_DATE_QUERY_REGEXP_CREATED = /created:\[([^\]]+)\]/g +const RELATIVE_DATE_QUERY_REGEXP_ADDED = /added:\[([^\]]+)\]/g +const RELATIVE_DATE_QUERYSTRINGS = [ + { + relativeDate: RelativeDate.LAST_7_DAYS, + dateQuery: '-1 week to now', + }, + { + relativeDate: RelativeDate.LAST_MONTH, + dateQuery: '-1 month to now', + }, + { + relativeDate: RelativeDate.LAST_3_MONTHS, + dateQuery: '-3 month to now', + }, + { + relativeDate: RelativeDate.LAST_YEAR, + dateQuery: '-1 year to now', + }, +] + @Component({ selector: 'app-filter-editor', templateUrl: './filter-editor.component.html', @@ -197,6 +219,8 @@ export class FilterEditorComponent implements OnInit, OnDestroy { dateCreatedAfter: string dateAddedBefore: string dateAddedAfter: string + dateCreatedRelativeDate: RelativeDate + dateAddedRelativeDate: RelativeDate _unmodifiedFilterRules: FilterRule[] = [] _filterRules: FilterRule[] = [] @@ -228,6 +252,8 @@ export class FilterEditorComponent implements OnInit, OnDestroy { this.dateAddedAfter = null this.dateCreatedBefore = null this.dateCreatedAfter = null + this.dateCreatedRelativeDate = null + this.dateAddedRelativeDate = null this.textFilterModifier = TEXT_FILTER_MODIFIER_EQUALS value.forEach((rule) => { @@ -245,8 +271,39 @@ export class FilterEditorComponent implements OnInit, OnDestroy { this.textFilterTarget = TEXT_FILTER_TARGET_ASN break case FILTER_FULLTEXT_QUERY: - this._textFilter = rule.value - this.textFilterTarget = TEXT_FILTER_TARGET_FULLTEXT_QUERY + let allQueryArgs = rule.value.split(',') + let textQueryArgs = [] + allQueryArgs.forEach((arg) => { + if (arg.match(RELATIVE_DATE_QUERY_REGEXP_CREATED)) { + ;[...arg.matchAll(RELATIVE_DATE_QUERY_REGEXP_CREATED)].forEach( + (match) => { + if (match[1]?.length) { + this.dateCreatedRelativeDate = + RELATIVE_DATE_QUERYSTRINGS.find( + (qS) => qS.dateQuery == match[1] + )?.relativeDate + } + } + ) + } else if (arg.match(RELATIVE_DATE_QUERY_REGEXP_ADDED)) { + ;[...arg.matchAll(RELATIVE_DATE_QUERY_REGEXP_ADDED)].forEach( + (match) => { + if (match[1]?.length) { + this.dateAddedRelativeDate = + RELATIVE_DATE_QUERYSTRINGS.find( + (qS) => qS.dateQuery == match[1] + )?.relativeDate + } + } + ) + } else { + textQueryArgs.push(arg) + } + }) + if (textQueryArgs.length) { + this._textFilter = textQueryArgs.join(',') + this.textFilterTarget = TEXT_FILTER_TARGET_FULLTEXT_QUERY + } break case FILTER_FULLTEXT_MORELIKE: this._moreLikeId = +rule.value @@ -471,6 +528,89 @@ export class FilterEditorComponent implements OnInit, OnDestroy { value: this.dateAddedAfter, }) } + if ( + this.dateAddedRelativeDate !== null || + this.dateCreatedRelativeDate !== null + ) { + let queryArgs: Array = [] + let existingRule = filterRules.find( + (fr) => fr.rule_type == FILTER_FULLTEXT_QUERY + ) + + // if had a title / content search and added a relative date we need to carry it over... + if ( + !existingRule && + this._textFilter?.length > 0 && + (this.textFilterTarget == TEXT_FILTER_TARGET_TITLE_CONTENT || + this.textFilterTarget == TEXT_FILTER_TARGET_TITLE) + ) { + existingRule = filterRules.find( + (fr) => + fr.rule_type == FILTER_TITLE_CONTENT || fr.rule_type == FILTER_TITLE + ) + existingRule.rule_type = FILTER_FULLTEXT_QUERY + } + + let existingRuleArgs = existingRule?.value.split(',') + if (this.dateCreatedRelativeDate !== null) { + queryArgs.push( + `created:[${ + RELATIVE_DATE_QUERYSTRINGS.find( + (qS) => qS.relativeDate == this.dateCreatedRelativeDate + ).dateQuery + }]` + ) + if (existingRule) { + queryArgs = existingRuleArgs + .filter((arg) => !arg.match(RELATIVE_DATE_QUERY_REGEXP_CREATED)) + .concat(queryArgs) + } + } + if (this.dateAddedRelativeDate !== null) { + queryArgs.push( + `added:[${ + RELATIVE_DATE_QUERYSTRINGS.find( + (qS) => qS.relativeDate == this.dateAddedRelativeDate + ).dateQuery + }]` + ) + if (existingRule) { + queryArgs = existingRuleArgs + .filter((arg) => !arg.match(RELATIVE_DATE_QUERY_REGEXP_ADDED)) + .concat(queryArgs) + } + } + + if (existingRule) { + existingRule.value = queryArgs.join(',') + } else { + filterRules.push({ + rule_type: FILTER_FULLTEXT_QUERY, + value: queryArgs.join(','), + }) + } + } + if ( + this.dateCreatedRelativeDate == null && + this.dateAddedRelativeDate == null + ) { + const existingRule = filterRules.find( + (fr) => fr.rule_type == FILTER_FULLTEXT_QUERY + ) + if ( + existingRule?.value.match(RELATIVE_DATE_QUERY_REGEXP_CREATED) || + existingRule?.value.match(RELATIVE_DATE_QUERY_REGEXP_ADDED) + ) { + // remove any existing date query + existingRule.value = existingRule.value + .replace(RELATIVE_DATE_QUERY_REGEXP_CREATED, '') + .replace(RELATIVE_DATE_QUERY_REGEXP_ADDED, '') + if (existingRule.value.replace(',', '').trim() === '') { + // if its empty now, remove it entirely + filterRules.splice(filterRules.indexOf(existingRule), 1) + } + } + } return filterRules } @@ -569,15 +709,23 @@ export class FilterEditorComponent implements OnInit, OnDestroy { this.updateRules() } - textFilterEnter() { - const filterString = ( - this.textFilterInput.nativeElement as HTMLInputElement - ).value - if (filterString.length) { - this.updateTextFilter(filterString) + textFilterKeyup(event: KeyboardEvent) { + if (event.key == 'Enter') { + const filterString = ( + this.textFilterInput.nativeElement as HTMLInputElement + ).value + if (filterString.length) { + this.updateTextFilter(filterString) + } + } else if (event.key == 'Escape') { + this.resetTextField() } } + resetTextField() { + this.updateTextFilter('') + } + changeTextFilterTarget(target) { if ( this.textFilterTarget == TEXT_FILTER_TARGET_FULLTEXT_MORELIKE && diff --git a/src-ui/src/app/guards/dirty-saved-view.guard.ts b/src-ui/src/app/guards/dirty-saved-view.guard.ts new file mode 100644 index 000000000..0044a2e78 --- /dev/null +++ b/src-ui/src/app/guards/dirty-saved-view.guard.ts @@ -0,0 +1,51 @@ +import { CanDeactivate } from '@angular/router' +import { Injectable } from '@angular/core' +import { first, Observable, Subject } from 'rxjs' +import { DocumentListComponent } from '../components/document-list/document-list.component' +import { NgbModal } from '@ng-bootstrap/ng-bootstrap' +import { ConfirmDialogComponent } from '../components/common/confirm-dialog/confirm-dialog.component' + +@Injectable() +export class DirtySavedViewGuard + implements CanDeactivate +{ + constructor(private modalService: NgbModal) {} + + canDeactivate( + component: DocumentListComponent + ): boolean | Observable { + return component.savedViewIsModified ? this.warn(component) : true + } + + warn(component: DocumentListComponent) { + let modal = this.modalService.open(ConfirmDialogComponent, { + backdrop: 'static', + }) + modal.componentInstance.title = $localize`Unsaved Changes` + modal.componentInstance.messageBold = + $localize`You have unsaved changes to the saved view` + + ' "' + + component.getTitle() + ;('".') + modal.componentInstance.message = $localize`Are you sure you want to close this saved view?` + modal.componentInstance.btnClass = 'btn-secondary' + modal.componentInstance.btnCaption = $localize`Close` + modal.componentInstance.alternativeBtnClass = 'btn-primary' + modal.componentInstance.alternativeBtnCaption = $localize`Save and close` + modal.componentInstance.alternativeClicked.pipe(first()).subscribe(() => { + modal.componentInstance.buttonsEnabled = false + component.saveViewConfig() + modal.close() + }) + modal.componentInstance.confirmClicked.pipe(first()).subscribe(() => { + modal.componentInstance.buttonsEnabled = false + modal.close() + }) + + const subject = new Subject() + modal.componentInstance.confirmSubject = subject + modal.componentInstance.alternativeSubject = subject + + return subject + } +} diff --git a/src-ui/src/app/services/document-list-view.service.ts b/src-ui/src/app/services/document-list-view.service.ts index 1dea011c0..3eb036710 100644 --- a/src-ui/src/app/services/document-list-view.service.ts +++ b/src-ui/src/app/services/document-list-view.service.ts @@ -171,15 +171,15 @@ export class DocumentListViewService { this.reduceSelectionToFilter() if (!this.router.routerState.snapshot.url.includes('/view/')) { - this.router.navigate([], { - queryParams: { view: view.id }, - }) + this.router.navigate(['view', view.id]) } } loadFromQueryParams(queryParams: ParamMap) { const paramsEmpty: boolean = queryParams.keys.length == 0 - let newState: ListViewState = this.listViewStates.get(null) + let newState: ListViewState = this.listViewStates.get( + this._activeSavedViewId + ) if (!paramsEmpty) newState = paramsToViewState(queryParams) if (newState == undefined) newState = this.defaultListViewState() // if nothing in local storage @@ -276,7 +276,6 @@ export class DocumentListViewService { ) { this.activeListViewState.sortField = 'created' } - this._activeSavedViewId = null this.activeListViewState.filterRules = filterRules this.reload() this.reduceSelectionToFilter() @@ -288,7 +287,6 @@ export class DocumentListViewService { } set sortField(field: string) { - this._activeSavedViewId = null this.activeListViewState.sortField = field this.reload() this.saveDocumentListView() @@ -299,7 +297,6 @@ export class DocumentListViewService { } set sortReverse(reverse: boolean) { - this._activeSavedViewId = null this.activeListViewState.sortReverse = reverse this.reload() this.saveDocumentListView() diff --git a/src-ui/src/styles.scss b/src-ui/src/styles.scss index f096e7a33..fcb69c913 100644 --- a/src-ui/src/styles.scss +++ b/src-ui/src/styles.scss @@ -372,6 +372,10 @@ textarea, &:hover, &:focus { background-color: var(--bs-body-bg); } + + &:focus { + color: var(--bs-body-color); + } } .dropdown-menu { @@ -393,6 +397,10 @@ textarea, background-color: var(--bs-primary); color: var(--pngx-primary-text-contrast); } + + &.disabled, &:disabled { + opacity: 50%; + } } } @@ -579,7 +587,7 @@ a.badge { border-radius: 0.15rem; } - > .btn:not(:first-child) { + > .btn:not(:first-child):not(:nth-child(2)) { border-top-left-radius: 0; border-bottom-left-radius: 0; } diff --git a/src/documents/consumer.py b/src/documents/consumer.py index 609ebed83..f542a1d98 100644 --- a/src/documents/consumer.py +++ b/src/documents/consumer.py @@ -405,6 +405,7 @@ class Consumer(LoggingMixin): # Don't save with the lock active. Saving will cause the file # renaming logic to acquire the lock as well. + # This triggers things like file renaming document.save() # Delete the file only if it was successfully consumed @@ -438,6 +439,9 @@ class Consumer(LoggingMixin): self._send_progress(100, 100, "SUCCESS", MESSAGE_FINISHED, document.id) + # Return the most up to date fields + document.refresh_from_db() + return document def _store(self, text, date, mime_type) -> Document: diff --git a/src/documents/file_handling.py b/src/documents/file_handling.py index e3f13c077..5947fe1b0 100644 --- a/src/documents/file_handling.py +++ b/src/documents/file_handling.py @@ -1,4 +1,3 @@ -import datetime import logging import os from collections import defaultdict @@ -172,7 +171,7 @@ def generate_filename(doc, counter=0, append_gpg=True, archive_filename=False): else: asn = "-none-" - # Convert UTC database date to localized date + # Convert UTC database datetime to localized date local_added = timezone.localdate(doc.added) local_created = timezone.localdate(doc.created) @@ -180,14 +179,20 @@ def generate_filename(doc, counter=0, append_gpg=True, archive_filename=False): title=pathvalidate.sanitize_filename(doc.title, replacement_text="-"), correspondent=correspondent, document_type=document_type, - created=datetime.date.isoformat(local_created), - created_year=local_created.year, - created_month=f"{local_created.month:02}", - created_day=f"{local_created.day:02}", - added=datetime.date.isoformat(local_added), - added_year=local_added.year, - added_month=f"{local_added.month:02}", - added_day=f"{local_added.day:02}", + created=local_created.isoformat(), + created_year=local_created.strftime("%Y"), + created_year_short=local_created.strftime("%y"), + created_month=local_created.strftime("%m"), + created_month_name=local_created.strftime("%B"), + created_month_name_short=local_created.strftime("%b"), + created_day=local_created.strftime("%d"), + added=local_added.isoformat(), + added_year=local_added.strftime("%Y"), + added_year_short=local_added.strftime("%y"), + added_month=local_added.strftime("%m"), + added_month_name=local_added.strftime("%B"), + added_month_name_short=local_added.strftime("%b"), + added_day=local_added.strftime("%d"), asn=asn, tags=tags, tag_list=tag_list, diff --git a/src/documents/matching.py b/src/documents/matching.py index ca6251c37..235263aa6 100644 --- a/src/documents/matching.py +++ b/src/documents/matching.py @@ -142,14 +142,14 @@ def matches(matching_model, document): return bool(match) elif matching_model.matching_algorithm == MatchingModel.MATCH_FUZZY: - from fuzzywuzzy import fuzz + from rapidfuzz import fuzz match = re.sub(r"[^\w\s]", "", matching_model.match) text = re.sub(r"[^\w\s]", "", document_content) if matching_model.is_insensitive: match = match.lower() text = text.lower() - if fuzz.partial_ratio(match, text) >= 90: + if fuzz.partial_ratio(match, text, score_cutoff=90): # TODO: make this better log_reason( matching_model, diff --git a/src/documents/signals/handlers.py b/src/documents/signals/handlers.py index 1b180626a..865c83935 100644 --- a/src/documents/signals/handlers.py +++ b/src/documents/signals/handlers.py @@ -400,6 +400,13 @@ def update_filename_and_move_files(sender, instance, **kwargs): with FileLock(settings.MEDIA_LOCK): try: + + # If this was waiting for the lock, the filename or archive_filename + # of this document may have been updated. This happens if multiple updates + # get queued from the UI for the same document + # So freshen up the data before doing anything + instance.refresh_from_db() + old_filename = instance.filename old_source_path = instance.source_path diff --git a/src/documents/tests/test_consumer.py b/src/documents/tests/test_consumer.py index 48f195903..3b94b889b 100644 --- a/src/documents/tests/test_consumer.py +++ b/src/documents/tests/test_consumer.py @@ -14,6 +14,7 @@ except ImportError: import backports.zoneinfo as zoneinfo from django.conf import settings +from django.utils import timezone from django.test import override_settings from django.test import TestCase @@ -326,6 +327,12 @@ class TestConsumer(DirectoriesMixin, TestCase): def testNormalOperation(self): filename = self.get_test_file() + + # Get the local time, as an aware datetime + # Roughly equal to file modification time + rough_create_date_local = timezone.localtime(timezone.now()) + + # Consume the file document = self.consumer.try_consume_file(filename) self.assertEqual(document.content, "The Text") @@ -351,7 +358,20 @@ class TestConsumer(DirectoriesMixin, TestCase): self._assert_first_last_send_progress() - self.assertEqual(document.created.tzinfo, zoneinfo.ZoneInfo("America/Chicago")) + # Convert UTC time from DB to local time + document_date_local = timezone.localtime(document.created) + + self.assertEqual( + document_date_local.tzinfo, + zoneinfo.ZoneInfo("America/Chicago"), + ) + self.assertEqual(document_date_local.tzinfo, rough_create_date_local.tzinfo) + self.assertEqual(document_date_local.year, rough_create_date_local.year) + self.assertEqual(document_date_local.month, rough_create_date_local.month) + self.assertEqual(document_date_local.day, rough_create_date_local.day) + self.assertEqual(document_date_local.hour, rough_create_date_local.hour) + self.assertEqual(document_date_local.minute, rough_create_date_local.minute) + # Skipping seconds and more precise @override_settings(FILENAME_FORMAT=None) def testDeleteMacFiles(self): diff --git a/src/documents/tests/test_file_handling.py b/src/documents/tests/test_file_handling.py index 400c17413..8d726b339 100644 --- a/src/documents/tests/test_file_handling.py +++ b/src/documents/tests/test_file_handling.py @@ -1036,6 +1036,34 @@ class TestFilenameGeneration(TestCase): self.assertEqual(generate_filename(doc_a), "0000002.pdf") self.assertEqual(generate_filename(doc_b), "SomeImportantNone/2020-07-25.pdf") + @override_settings( + FILENAME_FORMAT="{created_year_short}/{created_month_name_short}/{created_month_name}/{title}", + ) + def test_short_names_created(self): + doc = Document.objects.create( + title="The Title", + created=timezone.make_aware( + datetime.datetime(1989, 12, 21, 7, 36, 51, 153), + ), + mime_type="application/pdf", + pk=2, + checksum="2", + ) + self.assertEqual(generate_filename(doc), "89/Dec/December/The Title.pdf") + + @override_settings( + FILENAME_FORMAT="{added_year_short}/{added_month_name}/{added_month_name_short}/{title}", + ) + def test_short_names_added(self): + doc = Document.objects.create( + title="The Title", + added=timezone.make_aware(datetime.datetime(1984, 8, 21, 7, 36, 51, 153)), + mime_type="application/pdf", + pk=2, + checksum="2", + ) + self.assertEqual(generate_filename(doc), "84/August/Aug/The Title.pdf") + def run(): doc = Document.objects.create( diff --git a/src/paperless/settings.py b/src/paperless/settings.py index 1fb6ba913..5547d6c33 100644 --- a/src/paperless/settings.py +++ b/src/paperless/settings.py @@ -347,6 +347,13 @@ if os.getenv("PAPERLESS_DBHOST"): if os.getenv("PAPERLESS_DBENGINE") == "mariadb": engine = "django.db.backends.mysql" options = {"read_default_file": "/etc/mysql/my.cnf", "charset": "utf8mb4"} + + # Silence Django error on old MariaDB versions. + # VARCHAR can support > 255 in modern versions + # https://docs.djangoproject.com/en/4.1/ref/checks/#database + # https://mariadb.com/kb/en/innodb-system-variables/#innodb_large_prefix + SILENCED_SYSTEM_CHECKS = ["mysql.W003"] + else: # Default to PostgresDB engine = "django.db.backends.postgresql_psycopg2" options = {"sslmode": os.getenv("PAPERLESS_DBSSLMODE", "prefer")} diff --git a/src/paperless_tika/tests/test_live_tika.py b/src/paperless_tika/tests/test_live_tika.py index e1af7cf86..b5efc7cef 100644 --- a/src/paperless_tika/tests/test_live_tika.py +++ b/src/paperless_tika/tests/test_live_tika.py @@ -1,10 +1,11 @@ -import datetime import os +import time from pathlib import Path from typing import Final import pytest from django.test import TestCase +from documents.parsers import ParseError from paperless_tika.parsers import TikaDocumentParser @@ -24,6 +25,44 @@ class TestTikaParserAgainstServer(TestCase): def tearDown(self) -> None: self.parser.cleanup() + def try_parse_with_wait(self, test_file, mime_type): + """ + For whatever reason, the image started during the test pipeline likes to + segfault sometimes, when run with the exact files that usually pass. + + So, this function will retry the parsing up to 3 times, with larger backoff + periods between each attempt, in hopes the issue resolves itself during + one attempt to parse. + + This will wait the following: + - Attempt 1 - 20s following failure + - Attempt 2 - 40s following failure + - Attempt 3 - 80s following failure + + """ + succeeded = False + retry_time = 20.0 + retry_count = 0 + max_retry_count = 3 + + while retry_count < max_retry_count and not succeeded: + try: + self.parser.parse(test_file, mime_type) + + succeeded = True + except Exception as e: + print(f"{e} during try #{retry_count}", flush=True) + + retry_count = retry_count + 1 + + time.sleep(retry_time) + retry_time = retry_time * 2.0 + + self.assertTrue( + succeeded, + "Continued Tika server errors after multiple retries", + ) + def test_basic_parse_odt(self): """ GIVEN: @@ -36,7 +75,7 @@ class TestTikaParserAgainstServer(TestCase): """ test_file = self.SAMPLE_DIR / Path("sample.odt") - self.parser.parse(test_file, "application/vnd.oasis.opendocument.text") + self.try_parse_with_wait(test_file, "application/vnd.oasis.opendocument.text") self.assertEqual( self.parser.text, @@ -62,7 +101,7 @@ class TestTikaParserAgainstServer(TestCase): """ test_file = self.SAMPLE_DIR / Path("sample.docx") - self.parser.parse( + self.try_parse_with_wait( test_file, "application/vnd.openxmlformats-officedocument.wordprocessingml.document", )