├── .devcontainer ├── Dockerfile └── devcontainer.json ├── .env.defaults ├── .github ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── ISSUE_TEMPLATE │ ├── bug_report.md │ ├── custom.md │ └── feature_request.md ├── PULL_REQUEST_TEMPLATE.md └── workflows │ ├── build.yml │ └── deploy.yml ├── .gitignore ├── .pre-commit-config.yaml ├── .vscode ├── extensions.json ├── launch.json └── settings.json ├── LICENSE ├── README.rst ├── dev ├── __init__.py ├── manage.py ├── myapp │ ├── __init__.py │ ├── apps.py │ ├── forms.py │ ├── migrations │ │ ├── 0001_initial.py │ │ ├── 0002_insert_demo_event.py │ │ └── __init__.py │ ├── models.py │ ├── templates │ │ ├── layouts │ │ │ ├── main.html │ │ │ └── nav-bar.html │ │ └── myapp │ │ │ ├── crispy-form.html │ │ │ ├── custom-flatpickr-input.html │ │ │ ├── custom-form.html │ │ │ ├── custom-formset.html │ │ │ ├── event_filter.html │ │ │ └── event_form.html │ ├── urls.py │ └── views.py ├── mysite │ ├── __init__.py │ ├── context_processors.py │ ├── settings.py │ ├── urls.py │ └── wsgi.py └── pyproject.toml ├── poetry.lock ├── pyproject.toml ├── src └── django_flatpickr │ ├── __init__.py │ ├── _base.py │ ├── _config.py │ ├── _media.py │ ├── py.typed │ ├── schemas.py │ ├── settings.py │ ├── static │ └── django_flatpickr │ │ └── js │ │ └── django-flatpickr.js │ ├── templates │ └── django_flatpickr │ │ └── input.html │ └── widgets.py └── tests ├── __init__.py ├── conftest.py ├── pip-constraints.txt ├── test_demo.py ├── test_flatpickr_options.py ├── test_input_attrs.py └── test_media.py /.devcontainer/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM --platform=amd64 python:3.12 2 | 3 | RUN pip install "poetry>=1.2" 4 | -------------------------------------------------------------------------------- /.devcontainer/devcontainer.json: -------------------------------------------------------------------------------- 1 | { 2 | "build": { 3 | "dockerfile": "Dockerfile" 4 | }, 5 | "customizations": { 6 | "vscode": { 7 | "extensions": [ 8 | "ms-python.python", 9 | "ms-python.isort", 10 | "ms-python.black-formatter", 11 | "ms-python.mypy-type-checker", 12 | "mhutchie.git-graph" 13 | ] 14 | } 15 | } 16 | } -------------------------------------------------------------------------------- /.env.defaults: -------------------------------------------------------------------------------- 1 | DJANGO_FLATPICKR_APP_STATIC_URL="django_flatpickr/" -------------------------------------------------------------------------------- /.github/CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation. 6 | 7 | ## Our Standards 8 | 9 | Examples of behavior that contributes to creating a positive environment include: 10 | 11 | * Using welcoming and inclusive language 12 | * Being respectful of differing viewpoints and experiences 13 | * Gracefully accepting constructive criticism 14 | * Focusing on what is best for the community 15 | * Showing empathy towards other community members 16 | 17 | Examples of unacceptable behavior by participants include: 18 | 19 | * The use of sexualized language or imagery and unwelcome sexual attention or advances 20 | * Trolling, insulting/derogatory comments, and personal or political attacks 21 | * Public or private harassment 22 | * Publishing others' private information, such as a physical or electronic address, without explicit permission 23 | * Other conduct which could reasonably be considered inappropriate in a professional setting 24 | 25 | ## Our Responsibilities 26 | 27 | Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. 28 | 29 | Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. 30 | 31 | ## Scope 32 | 33 | This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers. 34 | 35 | ## Enforcement 36 | 37 | Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at test@test.com. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. 38 | 39 | Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership. 40 | 41 | ## Attribution 42 | 43 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version] 44 | 45 | [homepage]: http://contributor-covenant.org 46 | [version]: http://contributor-covenant.org/version/1/4/ 47 | -------------------------------------------------------------------------------- /.github/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to this Project 2 | 3 | Any contributions to this repository in the form of bug reports, bug fix, suggestions and feature requests 4 | are warmly welcomed as long as it does not hamper the tests and coverage report. 5 | 6 | 7 | ## Getting Started 8 | 9 | Follow the following steps to get started contributing to this project. 10 | 11 | 1. Fork the repository on GitHub. 12 | 2. Clone your fork to your computer: 13 | 14 | git clone https://github.com/your_username_here/django-flatpickr.git 15 | cd django-flatpickr 16 | git checkout -b name-of-your-bugfix-or-feature 17 | 18 | 3. Create a virtual environment of your choice and activate it. 19 | 4. Install yarn dev-dependencies. 20 | 21 | yarn install 22 | 23 | 5. Install the pip-dependencies and run migrations for dev project. 24 | 25 | yarn dev:install 26 | yarn dev:migrate 27 | 28 | 6. Now you can run the dev project on localhost:8000 to see the changes you make in action real-time. 29 | 30 | yarn dev 31 | 32 | 33 | ## Testing 34 | 35 | 1. Run the tests by the following command. 36 | 37 | yarn test 38 | 39 | 2. See the coverage report by the following command. 40 | 41 | yarn coverage 42 | 43 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | 5 | --- 6 | 7 | **Describe the bug** 8 | A clear and concise description of what the bug is. 9 | 10 | **To Reproduce** 11 | Steps to reproduce the behavior: 12 | 1. Go to '...' 13 | 2. Click on '....' 14 | 3. Scroll down to '....' 15 | 4. See error 16 | 17 | **Expected behavior** 18 | A clear and concise description of what you expected to happen. 19 | 20 | **Screenshots** 21 | If applicable, add screenshots to help explain your problem. 22 | 23 | **Setup Information (please complete the following information):** 24 | - OS: [e.g. Windows 10] 25 | - Browser [e.g. chrome, safari] 26 | - Browser version [e.g. 22] 27 | - Python version [e.g. 3.7] 28 | - Django version [e.g. 2.1] 29 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/custom.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Custom issue template 3 | about: Report something not surely a bug or any troubles using the package. 4 | 5 | --- 6 | 7 | **Describe the problem** 8 | A clear and concise description of what the scenario is. 9 | 10 | **To Reproduce** 11 | Steps to reproduce the behavior: 12 | 1. Go to '...' 13 | 2. Click on '....' 14 | 3. Scroll down to '....' 15 | 4. See error 16 | 17 | **Expected behavior** 18 | A clear and concise description of what you expected to happen. 19 | 20 | **Console errors** 21 | - No error on django console. 22 | - No error on JavaScript console. 23 | 24 | **Paste-bin** 25 | The page is showing up but the date-picker calendar is not. The paste-bin link 26 | of the HTML source of the page is http://... 27 | 28 | **Setup Information (please complete the following information):** 29 | - OS: [e.g. Windows 10] 30 | - Browser [e.g. chrome, safari] 31 | - Browser version [e.g. 22] 32 | - Python version [e.g. 3.7] 33 | - Django version [e.g. 2.1] 34 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | 5 | --- 6 | 7 | **Is your feature request related to a problem? Please describe.** 8 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 9 | 10 | **Describe the solution you'd like** 11 | A clear and concise description of what you want to happen. 12 | 13 | **Describe alternatives you've considered** 14 | A clear and concise description of any alternative solutions or features you've considered. 15 | 16 | **Additional context** 17 | Add any other context or screenshots about the feature request here. 18 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | # PR Description 2 | 3 | ## Purpose 4 | _Describe the problem or feature in addition to a link to the issues._ 5 | 6 | ## Approach 7 | _How does this change address the problem?_ 8 | 9 | #### Issues solved in this PR 10 | - [x] Issue 1 11 | - [x] Issue 2 12 | 13 | #### What has Changed 14 | - Change 1 15 | - Change 2 16 | 17 | #### Blog Posts 18 | - [How to Pull Request](https://github.com/flexyford/pull-request-template) Github Repo with Learning focused Pull Request Template. -------------------------------------------------------------------------------- /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | name: build 2 | 3 | on: 4 | push: 5 | branches: ["*"] 6 | pull_request: 7 | 8 | jobs: 9 | pre-build: 10 | runs-on: ubuntu-latest 11 | strategy: 12 | matrix: 13 | python-version: ["3.12"] 14 | steps: 15 | - uses: actions/checkout@v3 16 | 17 | - name: Install poetry 18 | run: pipx install poetry 19 | 20 | - uses: actions/setup-python@v4 21 | with: 22 | python-version: ${{ matrix.python-version }} 23 | cache: poetry 24 | 25 | - name: Check poetry.lock 26 | run: | 27 | poetry env use ${{ matrix.python-version }} 28 | poetry lock --check 29 | 30 | - name: Install dependencies 31 | run: | 32 | poetry env use ${{ matrix.python-version }} 33 | poetry install --no-root --only build --no-ansi --no-interaction 34 | poetry run pip install -c tests/pip-constraints.txt . 35 | 36 | - name: Lint 37 | run: poetry run poe lint 38 | 39 | - name: Test Coverage 40 | run: poetry run poe test-cov 41 | 42 | - name: Coveralls Parallel 43 | uses: coverallsapp/github-action@master 44 | with: 45 | github-token: ${{ secrets.GITHUB_TOKEN }} 46 | flag-name: run-${{ matrix.python-version }} 47 | parallel: true 48 | 49 | - name: Upload pages artifact 50 | uses: actions/upload-pages-artifact@v1 51 | if: github.event_name == 'push' && github.ref_name == 'master' && github.repository_owner == 'monim67' 52 | with: 53 | path: ./pages 54 | 55 | build: 56 | runs-on: ubuntu-latest 57 | needs: pre-build 58 | strategy: 59 | matrix: 60 | python-version: ["3.11", "3.10", "3.9", "3.8"] 61 | steps: 62 | - uses: actions/checkout@v3 63 | 64 | - name: Install poetry 65 | run: pipx install poetry 66 | 67 | - uses: actions/setup-python@v4 68 | with: 69 | python-version: ${{ matrix.python-version }} 70 | cache: poetry 71 | 72 | - name: Install dependencies 73 | run: | 74 | poetry env use ${{ matrix.python-version }} 75 | poetry install --no-root --only build --no-ansi --no-interaction 76 | poetry run pip install -c tests/pip-constraints.txt . 77 | 78 | - name: Test Coverage 79 | run: poetry run poe test-cov 80 | 81 | - name: Coveralls Parallel 82 | uses: coverallsapp/github-action@master 83 | with: 84 | github-token: ${{ secrets.GITHUB_TOKEN }} 85 | flag-name: run-${{ matrix.python-version }} 86 | parallel: true 87 | 88 | coveralls: 89 | runs-on: ubuntu-latest 90 | needs: build 91 | steps: 92 | - name: Coveralls Finished 93 | uses: coverallsapp/github-action@master 94 | with: 95 | github-token: ${{ secrets.GITHUB_TOKEN }} 96 | parallel-finished: true 97 | 98 | deploy-pages: 99 | runs-on: ubuntu-latest 100 | needs: build 101 | if: github.event_name == 'push' && github.ref_name == 'master' && github.repository_owner == 'monim67' 102 | permissions: 103 | contents: read 104 | pages: write 105 | id-token: write 106 | environment: 107 | name: github-pages 108 | url: ${{ steps.deployment.outputs.page_url }} 109 | steps: 110 | - name: Deploy to GitHub Pages 111 | id: deployment 112 | uses: actions/deploy-pages@v1 113 | -------------------------------------------------------------------------------- /.github/workflows/deploy.yml: -------------------------------------------------------------------------------- 1 | name: Deploy to PyPI 2 | 3 | on: 4 | release: 5 | types: [created] 6 | 7 | jobs: 8 | deploy: 9 | runs-on: ubuntu-latest 10 | permissions: 11 | id-token: write 12 | env: 13 | POETRY_VIRTUALENVS_CREATE: "false" 14 | steps: 15 | - uses: actions/checkout@v4 16 | 17 | - name: Install poetry 18 | run: | 19 | pipx install poetry 20 | poetry self add poetry-bumpversion 21 | 22 | - name: Build 23 | run: | 24 | poetry version ${{ github.ref_name }} 25 | poetry build 26 | 27 | - name: Publish package distributions to PyPI 28 | uses: pypa/gh-action-pypi-publish@release/v1 29 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .env 2 | /pages 3 | db.sqlite3 4 | docs/_build 5 | docs/pydoc.io/autoapi 6 | 7 | # Byte-compiled / optimized / DLL files 8 | __pycache__/ 9 | .pytest_cache/ 10 | *.py[cod] 11 | *$py.class 12 | .DS_Store 13 | 14 | # IDE - VSCode 15 | .vscode/* 16 | !.vscode/settings.json 17 | !.vscode/tasks.json 18 | !.vscode/launch.json 19 | !.vscode/extensions.json 20 | .history/* 21 | 22 | # Unit test / coverage reports 23 | htmlcov/ 24 | .tox/ 25 | .coverage 26 | .coverage.* 27 | coverage/* 28 | .cache 29 | nosetests.xml 30 | *.cover 31 | .hypothesis/ 32 | 33 | # Distribution / packaging 34 | .Python 35 | env/ 36 | build/ 37 | develop-eggs/ 38 | dist/ 39 | downloads/ 40 | eggs/ 41 | .eggs/ 42 | lib/ 43 | lib64/ 44 | parts/ 45 | sdist/ 46 | var/ 47 | wheels/ 48 | *.egg-info/ 49 | .installed.cfg 50 | *.egg 51 | -------------------------------------------------------------------------------- /.pre-commit-config.yaml: -------------------------------------------------------------------------------- 1 | repos: 2 | - repo: local 3 | hooks: 4 | - id: poetry-lock 5 | name: Check poetry.lock consistency 6 | language: system 7 | entry: poetry lock --check 8 | always_run: true 9 | pass_filenames: false 10 | - id: lint 11 | name: Run poe lint 12 | language: system 13 | entry: poetry run poe lint 14 | always_run: true 15 | pass_filenames: false 16 | -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": [ 3 | "ms-python.mypy-type-checker", 4 | "ms-python.black-formatter", 5 | "ms-python.isort", 6 | "ms-python.python" 7 | ] 8 | } -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "name": "Django: runserver", 9 | "type": "python", 10 | "request": "launch", 11 | "module": "poethepoet", 12 | "args": [ 13 | "start", 14 | ], 15 | "env": { 16 | "POETRY_ACTIVE": "1", 17 | }, 18 | "django": true, 19 | "justMyCode": true 20 | }, 21 | ] 22 | } -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "python.testing.pytestEnabled": true, 3 | "python.testing.unittestEnabled": false, 4 | "[python]": { 5 | "editor.formatOnSave": true, 6 | "editor.codeActionsOnSave": { 7 | "source.organizeImports": true, 8 | } 9 | }, 10 | "[javascript]": { 11 | "editor.tabSize": 2, 12 | "editor.detectIndentation": false, 13 | "editor.formatOnSave": true, 14 | }, 15 | "[html]": { 16 | "editor.tabSize": 2, 17 | "editor.detectIndentation": false, 18 | "editor.formatOnSave": true, 19 | }, 20 | "yaml.schemas": { 21 | "https://json.schemastore.org/github-workflow.json": ".github/workflows/*.yml" 22 | }, 23 | "esbonio.sphinx.confDir": "", 24 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Munim Munna 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.rst: -------------------------------------------------------------------------------- 1 | django-flatpickr 2 | ================ 3 | 4 | This django widget contains Date-Picker, Time-Picker, DateTime-Picker input 5 | widgets with date-range-picker functionality for django version >= 2.0. 6 | The widget implements `flatpickr `_ 7 | to display date-pickers in django model forms and custom forms which can be 8 | configured easily for date-range selection. For Bootstrap date-picker see 9 | `django-bootstrap-datepicker-plus `_. 10 | 11 | 12 | | |ci-status| |coverage| |pyversions| |djversions| 13 | 14 | | |flatpickr-red-theme| |flatpickr-default-theme| |flatpickr-dark-theme| 15 | 16 | 17 | 18 | Demo 19 | ---- 20 | - `Custom Form `_. 21 | - `Model Form `_. 22 | - `Generic View (without Model Form) `_. 23 | - `With django-crispy-forms `_. 24 | - `With django-filter `_. 25 | - `With dynamic formsets `_. 26 | 27 | 28 | 29 | Getting Started 30 | --------------- 31 | 32 | 33 | Prerequisites 34 | ^^^^^^^^^^^^^ 35 | - Python >= 3.8 36 | - Django >= 2.0 37 | 38 | 39 | Installing 40 | ^^^^^^^^^^ 41 | Install the PyPI package via pip. 42 | 43 | :: 44 | 45 | pip install django-flatpickr 46 | 47 | Add ``django_flatpickr`` to ``INSTALLED_APPS`` in your ``settings.py`` file. 48 | 49 | .. code:: python 50 | 51 | INSTALLED_APPS = [ 52 | # Add the following 53 | "django_flatpickr", 54 | ] 55 | 56 | 57 | 58 | Usage 59 | ----- 60 | 61 | The HTML template must have the following to render the flatpickr widget. 62 | A better example is `here `_. 63 | 64 | .. code:: html 65 | 66 | 67 | {{ form.media }} {# Adds all flatpickr JS/CSS files from CDN #} 68 | {{ form.as_p }} {# Renders the form #} 69 | 70 |
71 | {% csrf_token %} 72 | {% bootstrap_form form %} 73 |
74 | 75 | 76 | You can use it `with generic views without a model form `_. 77 | It can also be used with custom forms and model forms as below. 78 | 79 | 80 | Usage in Custom Form 81 | ^^^^^^^^^^^^^^^^^^^^ 82 | 83 | .. code:: python 84 | 85 | # File: forms.py 86 | from django_flatpickr.widgets import DatePickerInput, TimePickerInput, DateTimePickerInput 87 | from .models import Event 88 | from django import forms 89 | 90 | class ToDoForm(forms.Form): 91 | todo = forms.CharField(widget=forms.TextInput()) 92 | date = forms.DateField(widget=DatePickerInput()) 93 | time = forms.TimeField(widget=TimePickerInput()) 94 | datetime = forms.DateTimeField(widget=DateTimePickerInput()) 95 | 96 | 97 | # File: views.py 98 | class CustomFormView(generic.FormView): 99 | template_name = "myapp/custom-form.html" 100 | form_class = ToDoForm 101 | 102 | 103 | See `models.py `_, `forms.py `_, 104 | `views.py `_, `custom-form.html `_ 105 | for more details. 106 | 107 | Usage in Model Form 108 | ^^^^^^^^^^^^^^^^^^^^ 109 | 110 | .. code:: python 111 | 112 | # File: forms.py 113 | from django_flatpickr.widgets import DatePickerInput, TimePickerInput, DateTimePickerInput 114 | from .models import Event 115 | from django import forms 116 | 117 | class EventForm(forms.ModelForm): 118 | class Meta: 119 | model = Event 120 | fields = ["name", "start_date", "start_time", "start_datetime"] 121 | widgets = { 122 | "start_date": DatePickerInput(), 123 | "start_time": TimePickerInput(), 124 | "start_datetime": DateTimePickerInput(), 125 | } 126 | 127 | 128 | # File: views.py 129 | class UpdateView(generic.edit.UpdateView): 130 | model = Event 131 | form_class = EventForm 132 | 133 | 134 | See `models.py `_, `forms.py `_, 135 | `views.py `_, `event_form.html `_ 136 | for more details. 137 | 138 | Implement date-range-picker 139 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ 140 | 141 | DatePickers can be linked together to select a date-range, time-range or 142 | date-time-range **without writing a single line of JavaScript**. 143 | 144 | .. code:: python 145 | 146 | # File: forms.py 147 | from django_flatpickr.widgets import DatePickerInput, TimePickerInput 148 | from django import forms 149 | 150 | class EventForm(forms.ModelForm): 151 | class Meta: 152 | model = Event 153 | fields = ["name", "start_date", "end_date", "start_time", "end_time"] 154 | widgets = { 155 | "start_date": DatePickerInput(), 156 | "end_date": DatePickerInput(range_from="start_date"), 157 | "start_time": TimePickerInput(), 158 | "end_time": TimePickerInput(range_from="start_time"), 159 | } 160 | 161 | 162 | 163 | Customization 164 | ------------- 165 | 166 | To customize the look and features of flatpickr widget copy the 167 | `settings block `_ to your settings.py file and customize it. 168 | Settings applies globally to all flatpickr widgets used in your site. 169 | 170 | You can set date and event hook options using JavaScript. 171 | 172 | .. code:: javascript 173 | 174 | window.djangoFlatpickrOptions = { 175 | onChange: function (selectedDates) { console.log(selectedDates) } 176 | } 177 | 178 | 179 | Customize single input 180 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ 181 | 182 | .. code:: python 183 | 184 | from django_flatpickr.schemas import FlatpickrOptions 185 | 186 | class ToDoForm(forms.Form): 187 | todo = forms.CharField(widget=forms.TextInput()) 188 | start_date = forms.DateField(widget=DatePickerInput( 189 | attrs = {"class": "my-custom-class"}, # input element attributes 190 | options=FlatpickrOptions(altFormat="m/d/Y"), 191 | )) 192 | 193 | Similarly set date and event hook options using JavaScript. 194 | 195 | .. code:: javascript 196 | 197 | window.djangoFlatpickrOptions_start_date = { 198 | onChange: function (selectedDates) { console.log(selectedDates) } 199 | } 200 | 201 | 202 | Localization 203 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ 204 | 205 | Use locale option, see `available localization options `_. 206 | 207 | 208 | License 209 | ------- 210 | 211 | - `MIT LICENSE `_. 212 | - `CONTRIBUTING `_. 213 | - `CODE_OF_CONDUCT `_. 214 | 215 | 216 | .. |flatpickr-red-theme| image:: https://cloud.githubusercontent.com/assets/11352152/14549374/3cc01102-028d-11e6-9ff4-0cf208a310c4.PNG 217 | :alt: Flatpickr Red Theme 218 | 219 | .. |flatpickr-default-theme| image:: https://cloud.githubusercontent.com/assets/11352152/14549370/3cadb750-028d-11e6-818d-c6a1bc6349fc.PNG 220 | :alt: Flatpickr Default Theme 221 | 222 | .. |flatpickr-dark-theme| image:: https://cloud.githubusercontent.com/assets/11352152/14549372/3cbc8514-028d-11e6-8daf-ec1ba01c9d7e.PNG 223 | :alt: Flatpickr Dark Theme 224 | 225 | 226 | .. |ci-status| image:: https://github.com/monim67/django-flatpickr/actions/workflows/build.yml/badge.svg?event=push 227 | :target: https://github.com/monim67/django-flatpickr/actions/workflows/build.yml 228 | :alt: Build Status 229 | 230 | .. |coverage| image:: https://coveralls.io/repos/github/monim67/django-flatpickr/badge.svg?branch=master 231 | :target: https://coveralls.io/github/monim67/django-flatpickr?branch=master 232 | :alt: Coverage Status 233 | 234 | .. |pyversions| image:: https://img.shields.io/pypi/pyversions/django-flatpickr.svg 235 | :target: https://pypi.python.org/pypi/django-flatpickr 236 | :alt: Python Versions 237 | 238 | .. |djversions| image:: https://img.shields.io/pypi/djversions/django-flatpickr.svg 239 | :target: https://pypi.python.org/pypi/django-flatpickr 240 | :alt: DJango Versions 241 | 242 | 243 | 244 | .. _demo_custom_form: https://monim67.github.io/django-flatpickr/demo/custom-form.html 245 | .. _demo_model_form: https://monim67.github.io/django-flatpickr/demo/generic-view-with-model-form-1.html 246 | .. _demo_generic_view: https://monim67.github.io/django-flatpickr/demo/generic-view.html 247 | .. _demo_crispy_form: https://monim67.github.io/django-flatpickr/demo/crispy-form.html 248 | .. _demo_django_filter: https://monim67.github.io/django-flatpickr/demo/django-filter.html 249 | .. _demo_dynamic_formset: https://monim67.github.io/django-flatpickr/demo/dynamic-formset.html 250 | 251 | .. _generic_view_block: https://github.com/monim67/django-flatpickr/blob/2.0.0/dev/myapp/views.py#L31 252 | .. _settings_block: https://github.com/monim67/django-flatpickr/blob/2.0.0/dev/mysite/settings.py#L143-L200 253 | 254 | .. _file_custom_form_html: https://github.com/monim67/django-flatpickr/blob/2.0.0/dev/myapp/templates/myapp/custom-form.html 255 | .. _file_event_form_html: https://github.com/monim67/django-flatpickr/blob/2.0.0/dev/myapp/templates/myapp/event_form.html 256 | .. _file_forms_py: https://github.com/monim67/django-flatpickr/blob/2.0.0/dev/myapp/forms.py 257 | .. _file_views_py: https://github.com/monim67/django-flatpickr/blob/2.0.0/dev/myapp/views.py 258 | .. _file_models_py: https://github.com/monim67/django-flatpickr/blob/2.0.0/dev/myapp/models.py 259 | -------------------------------------------------------------------------------- /dev/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/monim67/django-flatpickr/1d96d524cc5924bd3f7f980ac0634fc0317eefff/dev/__init__.py -------------------------------------------------------------------------------- /dev/manage.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import os 3 | import sys 4 | 5 | if __name__ == "__main__": 6 | os.environ.setdefault("DJANGO_SETTINGS_MODULE", "mysite.settings") 7 | try: 8 | from django.core.management import execute_from_command_line 9 | except ImportError as exc: 10 | raise ImportError( 11 | "Couldn't import Django. Are you sure it's installed and " 12 | "available on your PYTHONPATH environment variable? Did you " 13 | "forget to activate a virtual environment?" 14 | ) from exc 15 | execute_from_command_line(sys.argv) 16 | -------------------------------------------------------------------------------- /dev/myapp/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/monim67/django-flatpickr/1d96d524cc5924bd3f7f980ac0634fc0317eefff/dev/myapp/__init__.py -------------------------------------------------------------------------------- /dev/myapp/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class MyappConfig(AppConfig): 5 | name = "dev.myapp" 6 | -------------------------------------------------------------------------------- /dev/myapp/forms.py: -------------------------------------------------------------------------------- 1 | from typing import Iterable 2 | 3 | from django import forms 4 | from django_filters import DateFilter, FilterSet 5 | 6 | from dev.myapp.models import Event 7 | from django_flatpickr.widgets import ( 8 | DatePickerInput, 9 | DateTimePickerInput, 10 | TimePickerInput, 11 | ) 12 | 13 | 14 | class MyDatePickerInput(DatePickerInput): 15 | template_name = "myapp/custom-flatpickr-input.html" 16 | 17 | 18 | class EventFilter(FilterSet): # type: ignore 19 | start_date__gt = DateFilter( 20 | field_name="start_date", 21 | lookup_expr="gt", 22 | widget=MyDatePickerInput(), 23 | ) 24 | start_date__lt = DateFilter( 25 | field_name="start_date", 26 | lookup_expr="lt", 27 | widget=MyDatePickerInput(range_from="start_date__gt"), 28 | ) 29 | 30 | class Meta: 31 | model = Event 32 | fields: Iterable[str] = [] 33 | 34 | 35 | class ToDoForm(forms.Form): 36 | start_date = forms.DateField(label="Start Date", widget=DatePickerInput()) 37 | end_date = forms.DateField( 38 | label="End Date", widget=DatePickerInput(range_from="start_date") 39 | ) 40 | 41 | 42 | class CustomInputTemplateToDoForm(forms.Form): 43 | start_date = forms.DateField(label="Start Date", widget=MyDatePickerInput()) 44 | end_date = forms.DateField( 45 | label="End Date", widget=MyDatePickerInput(range_from="start_date") 46 | ) 47 | 48 | 49 | class EventForm(forms.ModelForm[Event]): 50 | class Meta: 51 | model = Event 52 | fields = [ 53 | "start_date", 54 | "end_date", 55 | "start_time", 56 | "end_time", 57 | "start_datetime", 58 | "end_datetime", 59 | ] 60 | widgets = { 61 | "start_date": DatePickerInput(), 62 | "end_date": DatePickerInput(range_from="start_date"), 63 | "start_time": TimePickerInput(), 64 | "end_time": TimePickerInput(range_from="start_time"), 65 | "start_datetime": DateTimePickerInput(), 66 | "end_datetime": DateTimePickerInput(range_from="start_datetime"), 67 | } 68 | -------------------------------------------------------------------------------- /dev/myapp/migrations/0001_initial.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.1.7 on 2019-02-23 07:11 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | initial = True 9 | 10 | operations = [ 11 | migrations.CreateModel( 12 | name="Event", 13 | fields=[ 14 | ( 15 | "id", 16 | models.AutoField( 17 | auto_created=True, 18 | primary_key=True, 19 | serialize=False, 20 | verbose_name="ID", 21 | ), 22 | ), 23 | ("name", models.CharField(max_length=200)), 24 | ("start_date", models.DateField()), 25 | ("end_date", models.DateField()), 26 | ("start_time", models.TimeField()), 27 | ("end_time", models.TimeField()), 28 | ("start_datetime", models.DateTimeField()), 29 | ("end_datetime", models.DateTimeField()), 30 | ], 31 | ), 32 | ] 33 | -------------------------------------------------------------------------------- /dev/myapp/migrations/0002_insert_demo_event.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.1 on 2018-08-26 18:54 2 | 3 | from datetime import datetime, timezone 4 | 5 | from django.db import migrations 6 | 7 | 8 | def insert_demo_event(apps, schema_editor): # type: ignore 9 | event_datetime = datetime(2019, 2, 4, 0, 0, tzinfo=timezone.utc) 10 | 11 | event = apps.get_model("myapp", "Event")() 12 | event.name = "Event 01" 13 | event.start_date = datetime.date(event_datetime) 14 | event.end_date = datetime.date(event_datetime) 15 | event.start_time = datetime.time(event_datetime) 16 | event.end_time = datetime.time(event_datetime) 17 | event.start_datetime = event_datetime 18 | event.end_datetime = event_datetime 19 | event.save() 20 | 21 | 22 | class Migration(migrations.Migration): 23 | dependencies = [ 24 | ("myapp", "0001_initial"), 25 | ] 26 | 27 | operations = [ 28 | migrations.RunPython(insert_demo_event), 29 | ] 30 | -------------------------------------------------------------------------------- /dev/myapp/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/monim67/django-flatpickr/1d96d524cc5924bd3f7f980ac0634fc0317eefff/dev/myapp/migrations/__init__.py -------------------------------------------------------------------------------- /dev/myapp/models.py: -------------------------------------------------------------------------------- 1 | from django.db import models 2 | from django.urls import reverse 3 | 4 | 5 | class Event(models.Model): 6 | name = models.CharField(max_length=200) 7 | start_date = models.DateField() 8 | end_date = models.DateField() 9 | start_time = models.TimeField() 10 | end_time = models.TimeField() 11 | start_datetime = models.DateTimeField() 12 | end_datetime = models.DateTimeField() 13 | 14 | def __str__(self) -> str: 15 | return self.name 16 | 17 | def get_absolute_url(self) -> str: 18 | return reverse("myapp:model-form", kwargs={"pk": self.pk}) 19 | -------------------------------------------------------------------------------- /dev/myapp/templates/layouts/main.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | {% block page_title %}{% endblock %} 7 | 8 | {% block extra_css %} 9 | {% endblock %} 10 | 11 | 12 | 13 | {% include 'layouts/nav-bar.html' %} 14 |
15 | {% block content %} 16 | {% endblock %} 17 |
18 | 19 | 35 | {% block extra_js %} 36 | {% endblock %} 37 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /dev/myapp/templates/layouts/nav-bar.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /dev/myapp/templates/myapp/crispy-form.html: -------------------------------------------------------------------------------- 1 | {% extends 'layouts/main.html' %} 2 | 3 | {% block page_title %} 4 | django-flatpickr demo - custom form 5 | {% endblock %} 6 | 7 | {% block extra_css %} 8 | {{ form.media.css }} 9 | {% endblock %} 10 | 11 | {% block extra_js %} 12 | {{ form.media.js }} 13 | {% endblock %} 14 | 15 | 16 | {% block content %} 17 |
18 |

{{ title_text }}

19 |
20 | {% load crispy_forms_tags %} 21 |
22 |

Using {{ '{% crispy form %}' }}

23 |
24 | {# {% csrf_token %} #} 25 | {# csrf disabled for demo & version control purpose #} 26 | {% crispy form %} 27 |
28 |

Using {% verbatim doc %}{{ form | crispy }}{% endverbatim doc %}

29 |
30 | {# {% csrf_token %} #} 31 | {# csrf disabled for demo & version control purpose #} 32 | {{ form | crispy }} 33 |
34 |
35 | {% endblock %} -------------------------------------------------------------------------------- /dev/myapp/templates/myapp/custom-flatpickr-input.html: -------------------------------------------------------------------------------- 1 |
2 | 3 | 4 |
5 | {% include 'django/forms/widgets/text.html' %} 6 | 7 |
8 | 9 |
10 | 20 |
21 | 22 |
23 | 33 |
34 |
-------------------------------------------------------------------------------- /dev/myapp/templates/myapp/custom-form.html: -------------------------------------------------------------------------------- 1 | {% extends 'layouts/main.html' %} 2 | 3 | {% block page_title %} 4 | django-flatpickr demo - custom form 5 | {% endblock %} 6 | 7 | {% block extra_css %} 8 | {{ form.media.css }} 9 | {% endblock %} 10 | 11 | {% block extra_js %} 12 | {{ form.media.js }} 13 | 21 | {% endblock %} 22 | 23 | 24 | {% block content %} 25 |
26 |

{{ title_text }}

27 |
28 |
29 |
30 | {# {% csrf_token %} #} 31 | {# csrf disabled for demo & version control purpose #} 32 | {{ form.as_p }} 33 |
34 |
35 | {% endblock %} -------------------------------------------------------------------------------- /dev/myapp/templates/myapp/custom-formset.html: -------------------------------------------------------------------------------- 1 | {% extends 'layouts/main.html' %} 2 | 3 | {% block page_title %} 4 | django-flatpickr demo - custom form 5 | {% endblock %} 6 | 7 | {% block extra_css %} 8 | {{ form.media.css }} 9 | {% endblock %} 10 | 11 | {% block extra_js %} 12 | {{ form.media.js }} 13 | {% endblock %} 14 | 15 | 16 | {% block content %} 17 |
18 |

{{ title_text }}

19 |

20 | Manage formset with 21 | elo80ka/django-dynamic-formset 22 |

23 |
24 |
25 |
26 | {# {% csrf_token %} #} 27 | {# csrf disabled for demo & version control purpose #} 28 | {{ form.management_form }} 29 | {% for form in form %} 30 |
{{ form }}
31 | {% endfor %} 32 |
33 |
34 | 35 | 36 | 39 | {% endblock %} -------------------------------------------------------------------------------- /dev/myapp/templates/myapp/event_filter.html: -------------------------------------------------------------------------------- 1 | {% extends 'layouts/main.html' %} 2 | 3 | {% block page_title %} 4 | django-flatpickr demo - {{ title_text }} 5 | {% endblock %} 6 | 7 | {% block extra_css %} 8 | {{ filter.form.media.css }} 9 | {% endblock %} 10 | 11 | {% block extra_js %} 12 | {{ filter.form.media.js }} 13 | {% endblock %} 14 | 15 | 16 | {% block content %} 17 |
18 |

{{ title_text }}

19 |
20 |
21 |
22 |

Filter Events

23 |

Demo site is static HTML clone of django, filters won't work here

24 |
25 | {# {% csrf_token %} #} 26 | {# csrf disabled for demo & version control purpose #} 27 | {{ filter.form.as_p }} 28 | 29 |
30 |
31 |
32 | Clear Filters 33 | 34 |
35 |
36 |
37 |
38 |
39 |

Events

40 |
    41 | {% for event in object_list %} 42 |
  • {{ event.name }} ({{ event.start_date|date }} - {{ event.end_date|date }})
  • 43 | {% empty %} 44 |
  • No events found.
  • 45 | {% endfor %} 46 |
47 |
48 |
49 | {% endblock %} -------------------------------------------------------------------------------- /dev/myapp/templates/myapp/event_form.html: -------------------------------------------------------------------------------- 1 | {% extends 'layouts/main.html' %} 2 | 3 | {% block page_title %} 4 | django-flatpickr demo - {{ title_text }} 5 | {% endblock %} 6 | 7 | {% block extra_css %} 8 | {{ form.media.css }} 9 | {% endblock %} 10 | 11 | {% block extra_js %} 12 | {{ form.media.js }} 13 | {% endblock %} 14 | 15 | 16 | {% block content %} 17 |
18 |

{{ title_text }}

19 |
20 |
21 |
22 | {# {% csrf_token %} #} 23 | {# csrf disabled for demo & version control purpose #} 24 | {{ form.as_p }} 25 | 26 |
27 |
28 |
29 | 30 |
31 |
32 |
33 |
34 | {% endblock %} -------------------------------------------------------------------------------- /dev/myapp/urls.py: -------------------------------------------------------------------------------- 1 | from django.http import HttpResponse 2 | from django.urls import path 3 | 4 | from dev.myapp import views 5 | 6 | app_name = "myapp" 7 | 8 | urlpatterns = [ 9 | path( 10 | "", 11 | lambda _: HttpResponse( 12 | '' 13 | ), 14 | ), 15 | path("generic-view.html", views.CreateView.as_view(), name="generic-view"), 16 | path( 17 | "generic-view-with-model-form-.html", 18 | views.UpdateView.as_view(), 19 | name="model-form", 20 | ), 21 | path("custom-form.html", views.CustomFormView.as_view(), name="custom-form"), 22 | path("crispy-form.html", views.CrispyFormView.as_view(), name="crispy-form"), 23 | path("django-filter.html", views.EventListView.as_view(), name="django-filter"), 24 | path( 25 | "dynamic-formset.html", 26 | views.DynamicFormsetView.as_view(), 27 | name="dynamic-formset", 28 | ), 29 | ] 30 | -------------------------------------------------------------------------------- /dev/myapp/views.py: -------------------------------------------------------------------------------- 1 | from typing import Type 2 | 3 | from django.forms import BaseForm, ModelForm, formset_factory 4 | from django.forms.models import modelform_factory 5 | from django.http import HttpResponse, HttpResponseRedirect 6 | from django.views import generic 7 | from django_filters.views import FilterView 8 | 9 | from dev.myapp.forms import ( 10 | CustomInputTemplateToDoForm, 11 | EventFilter, 12 | EventForm, 13 | ToDoForm, 14 | ) 15 | from dev.myapp.models import Event 16 | from django_flatpickr.widgets import ( 17 | DatePickerInput, 18 | DateTimePickerInput, 19 | TimePickerInput, 20 | ) 21 | 22 | 23 | class EventListView(FilterView): # type: ignore 24 | filterset_class = EventFilter 25 | extra_context = { 26 | "title_text": "Generic View using model form", 27 | "submit_text": "Search", 28 | } 29 | 30 | 31 | class CreateView(generic.edit.CreateView[Event, ModelForm[Event]]): 32 | model = Event 33 | fields = [ 34 | "start_date", 35 | "end_date", 36 | "start_time", 37 | "end_time", 38 | "start_datetime", 39 | "end_datetime", 40 | ] 41 | extra_context = { 42 | "title_text": "Generic View without using model form", 43 | "submit_text": "Create Event", 44 | } 45 | 46 | def get_form_class(self) -> Type[ModelForm[Event]]: 47 | return modelform_factory( 48 | self.model, 49 | fields=self.fields, 50 | widgets={ 51 | "start_date": DatePickerInput(), 52 | "end_date": DatePickerInput(range_from="start_date"), 53 | "start_time": TimePickerInput(), 54 | "end_time": TimePickerInput(range_from="start_time"), 55 | "start_datetime": DateTimePickerInput(), 56 | "end_datetime": DateTimePickerInput(range_from="start_datetime"), 57 | }, 58 | ) 59 | 60 | 61 | class UpdateView(generic.edit.UpdateView[Event, EventForm]): 62 | model = Event 63 | form_class = EventForm 64 | extra_context = { 65 | "title_text": "Generic View using model form", 66 | "submit_text": "Update Event", 67 | } 68 | 69 | 70 | class CustomFormView(generic.FormView[CustomInputTemplateToDoForm]): 71 | template_name = "myapp/custom-form.html" 72 | form_class = CustomInputTemplateToDoForm 73 | extra_context = { 74 | "title_text": "Use customized input with addon clear button", 75 | } 76 | 77 | def form_valid(self, form: BaseForm) -> HttpResponse: 78 | return HttpResponseRedirect(self.request.META.get("HTTP_REFERER", "/")) 79 | 80 | 81 | class CrispyFormView(generic.FormView[ToDoForm]): 82 | template_name = "myapp/crispy-form.html" 83 | form_class = ToDoForm 84 | extra_context = { 85 | "title_text": "Use with django-crispy-forms", 86 | } 87 | 88 | def form_valid(self, form: BaseForm) -> HttpResponse: 89 | return HttpResponseRedirect(self.request.META.get("HTTP_REFERER", "/")) 90 | 91 | 92 | class DynamicFormsetView(generic.FormView[ToDoForm]): 93 | template_name = "myapp/custom-formset.html" 94 | form_class = formset_factory(ToDoForm, extra=2) # type: ignore 95 | extra_context = { 96 | "title_text": "Use with Formsets", 97 | } 98 | 99 | def form_valid(self, form: BaseForm) -> HttpResponse: 100 | return HttpResponseRedirect(self.request.META.get("HTTP_REFERER", "/")) 101 | -------------------------------------------------------------------------------- /dev/mysite/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/monim67/django-flatpickr/1d96d524cc5924bd3f7f980ac0634fc0317eefff/dev/mysite/__init__.py -------------------------------------------------------------------------------- /dev/mysite/context_processors.py: -------------------------------------------------------------------------------- 1 | from typing import Dict 2 | 3 | from django import VERSION as DJANGO_VERSION 4 | from django import get_version as get_django_version 5 | from django.http import HttpRequest 6 | 7 | 8 | def site_context(request: HttpRequest) -> Dict[str, str]: 9 | context = { 10 | "django_version": DJANGO_VERSION, 11 | "django_version_string": get_django_version(), 12 | } 13 | return context 14 | -------------------------------------------------------------------------------- /dev/mysite/settings.py: -------------------------------------------------------------------------------- 1 | """ 2 | Django settings for mysite project. 3 | 4 | Generated by 'django-admin startproject' using Django 2.1.7. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/2.1/topics/settings/ 8 | 9 | For the full list of settings and their values, see 10 | https://docs.djangoproject.com/en/2.1/ref/settings/ 11 | """ 12 | 13 | import os 14 | import sys 15 | from pathlib import Path 16 | 17 | import django_stubs_ext 18 | 19 | django_stubs_ext.monkeypatch() 20 | 21 | # Build paths inside the project like this: BASE_DIR / 'subdir'. 22 | BASE_DIR = Path(__file__).resolve().parent.parent.parent 23 | 24 | sys.path.insert(0, str(BASE_DIR)) 25 | 26 | # Quick-start development settings - unsuitable for production 27 | # See https://docs.djangoproject.com/en/2.1/howto/deployment/checklist/ 28 | 29 | # SECURITY WARNING: keep the secret key used in production secret! 30 | SECRET_KEY = "2%8tq3fn^3r$c0i18#jpkkg-@sf)hvc5cxwn04)**3=^(szm18" 31 | 32 | # SECURITY WARNING: don't run with debug turned on in production! 33 | DEBUG = True 34 | 35 | ALLOWED_HOSTS = ["localhost"] 36 | 37 | 38 | # Application definition 39 | 40 | INSTALLED_APPS = [ 41 | # 'django.contrib.admin', 42 | "django.contrib.auth", 43 | "django.contrib.contenttypes", 44 | # 'django.contrib.sessions', 45 | # 'django.contrib.messages', 46 | "django.contrib.staticfiles", 47 | "dev.myapp.apps.MyappConfig", 48 | "django_flatpickr", 49 | "crispy_forms", 50 | "crispy_bulma", 51 | "django_filters", 52 | ] 53 | 54 | MIDDLEWARE = [ 55 | "django.middleware.security.SecurityMiddleware", 56 | "django.contrib.sessions.middleware.SessionMiddleware", 57 | "django.middleware.common.CommonMiddleware", 58 | # 'django.middleware.csrf.CsrfViewMiddleware', 59 | "django.contrib.auth.middleware.AuthenticationMiddleware", 60 | "django.contrib.messages.middleware.MessageMiddleware", 61 | "django.middleware.clickjacking.XFrameOptionsMiddleware", 62 | ] 63 | 64 | ROOT_URLCONF = "dev.mysite.urls" 65 | 66 | TEMPLATES = [ 67 | { 68 | "BACKEND": "django.template.backends.django.DjangoTemplates", 69 | "DIRS": [], 70 | "APP_DIRS": True, 71 | "OPTIONS": { 72 | "context_processors": [ 73 | "django.template.context_processors.debug", 74 | "django.template.context_processors.request", 75 | "django.contrib.auth.context_processors.auth", 76 | "django.contrib.messages.context_processors.messages", 77 | "dev.mysite.context_processors.site_context", 78 | ], 79 | }, 80 | }, 81 | ] 82 | 83 | WSGI_APPLICATION = "mysite.wsgi.application" 84 | 85 | 86 | # Database 87 | # https://docs.djangoproject.com/en/2.1/ref/settings/#databases 88 | 89 | DATABASES = { 90 | "default": { 91 | "ENGINE": "django.db.backends.sqlite3", 92 | "NAME": os.path.join(BASE_DIR, "db.sqlite3"), 93 | } 94 | } 95 | 96 | 97 | # Password validation 98 | # https://docs.djangoproject.com/en/2.1/ref/settings/#auth-password-validators 99 | 100 | AUTH_PASSWORD_VALIDATORS = [ 101 | { 102 | "NAME": "django.contrib.auth.password_validation." 103 | "UserAttributeSimilarityValidator", 104 | }, 105 | { 106 | "NAME": "django.contrib.auth.password_validation." "MinimumLengthValidator", 107 | }, 108 | { 109 | "NAME": "django.contrib.auth.password_validation." "CommonPasswordValidator", 110 | }, 111 | { 112 | "NAME": "django.contrib.auth.password_validation." "NumericPasswordValidator", 113 | }, 114 | ] 115 | 116 | 117 | # Internationalization 118 | # https://docs.djangoproject.com/en/2.1/topics/i18n/ 119 | 120 | LANGUAGE_CODE = "en-us" 121 | 122 | TIME_ZONE = "UTC" 123 | 124 | USE_I18N = True 125 | 126 | USE_L10N = True 127 | 128 | USE_TZ = True 129 | 130 | 131 | # Static files (CSS, JavaScript, Images) 132 | # https://docs.djangoproject.com/en/2.1/howto/static-files/ 133 | 134 | STATIC_URL = "/static/" 135 | STATIC_ROOT = os.path.join(BASE_DIR, "staticfiles") 136 | MEDIA_ROOT = os.path.join(BASE_DIR, "media") 137 | SITE_ID = 1 138 | 139 | CRISPY_TEMPLATE_PACK = "bulma" 140 | CRISPY_ALLOWED_TEMPLATE_PACKS = ["bulma"] 141 | 142 | # GLobal settings for all django_flatpickr inputs 143 | DJANGO_FLATPICKR = { 144 | # Name of the theme to use 145 | # More themes: https://flatpickr.js.org/themes/ 146 | "theme_name": "dark", 147 | # 148 | # Complete URL of theme CSS file 149 | # theme_name is ignored if theme_url is provided 150 | # "theme_url": "https://..", 151 | # 152 | # Global HTML attributes for flatpickr element 153 | "attrs": { 154 | "class": "input", # input class of bulma 155 | }, 156 | # 157 | # Global options for flatpickr 158 | # More options: https://flatpickr.js.org/options/ 159 | # Some options are managed by this package e.g mode, dateFormat, altInput 160 | # "options": { 161 | # "locale": "bn", # locale option can be set here only 162 | # "altFormat": "m/d/Y H:i", # specify date format on the front-end 163 | # } 164 | # You can set date and event hook options using JavaScript, usage in README. 165 | # 166 | # HTML template to render the flatpickr input 167 | # Example: https://github.com/monim67/django-flatpickr/blob/2.0.0/dev/myapp/templates/myapp/custom-flatpickr-input.html 168 | # "template_name": "your-app/custom-flatpickr-input.html", 169 | # 170 | # Specify CDN roots. Choose where from static JS/CSS are served. 171 | # Can be set to localhost (offline setup) or any other preferred CDN. 172 | # The default values are: 173 | # "flatpickr_cdn_url": "https://cdn.jsdelivr.net/npm/flatpickr@4.6.13/dist/", 174 | # "app_static_url": "https://cdn.jsdelivr.net/gh/monim67/django-flatpickr@2.0.0/src/django_flatpickr/static/django_flatpickr/", 175 | # 176 | # Advanced: 177 | # If you want to serve static files yourself without CDN (from staticfiles) and 178 | # you know how to serve django static files on production server (DEBUG=False) 179 | # Then download and extract https://registry.npmjs.org/flatpickr/-/flatpickr-4.6.13.tgz 180 | # Copy the dist directory (package/dist) to any of your static directory and rename it to flatpickr 181 | # and use following options 182 | # "flatpickr_cdn_url": "flatpickr/", 183 | # "app_static_url": "django_flatpickr/", 184 | } 185 | -------------------------------------------------------------------------------- /dev/mysite/urls.py: -------------------------------------------------------------------------------- 1 | """mysite URL Configuration 2 | 3 | The `urlpatterns` list routes URLs to views. For more information please see: 4 | https://docs.djangoproject.com/en/2.1/topics/http/urls/ 5 | Examples: 6 | Function views 7 | 1. Add an import: from my_app import views 8 | 2. Add a URL to urlpatterns: path('', views.home, name='home') 9 | Class-based views 10 | 1. Add an import: from other_app.views import Home 11 | 2. Add a URL to urlpatterns: path('', Home.as_view(), name='home') 12 | Including another URLconf 13 | 1. Import the include() function: from django.urls import include, path 14 | 2. Add a URL to urlpatterns: path('blog/', include('blog.urls')) 15 | """ 16 | from django.urls import include, path 17 | 18 | urlpatterns = [ 19 | path("", include("dev.myapp.urls")), 20 | ] 21 | -------------------------------------------------------------------------------- /dev/mysite/wsgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | WSGI config for mysite project. 3 | 4 | It exposes the WSGI callable as a module-level variable named ``application``. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/2.1/howto/deployment/wsgi/ 8 | """ 9 | 10 | import os 11 | 12 | from django.core.wsgi import get_wsgi_application 13 | 14 | os.environ.setdefault("DJANGO_SETTINGS_MODULE", "mysite.settings") 15 | 16 | application = get_wsgi_application() 17 | -------------------------------------------------------------------------------- /dev/pyproject.toml: -------------------------------------------------------------------------------- 1 | [tool.pydocstyle] 2 | match = "nothing" 3 | -------------------------------------------------------------------------------- /poetry.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Poetry 1.7.1 and should not be changed by hand. 2 | 3 | [[package]] 4 | name = "annotated-types" 5 | version = "0.6.0" 6 | description = "Reusable constraint types to use with typing.Annotated" 7 | optional = false 8 | python-versions = ">=3.8" 9 | files = [ 10 | {file = "annotated_types-0.6.0-py3-none-any.whl", hash = "sha256:0641064de18ba7a25dee8f96403ebc39113d0cb953a01429249d5c7564666a43"}, 11 | {file = "annotated_types-0.6.0.tar.gz", hash = "sha256:563339e807e53ffd9c267e99fc6d9ea23eb8443c08f112651963e24e22f84a5d"}, 12 | ] 13 | 14 | [package.dependencies] 15 | typing-extensions = {version = ">=4.0.0", markers = "python_version < \"3.9\""} 16 | 17 | [[package]] 18 | name = "asgiref" 19 | version = "3.7.2" 20 | description = "ASGI specs, helper code, and adapters" 21 | optional = false 22 | python-versions = ">=3.7" 23 | files = [ 24 | {file = "asgiref-3.7.2-py3-none-any.whl", hash = "sha256:89b2ef2247e3b562a16eef663bc0e2e703ec6468e2fa8a5cd61cd449786d4f6e"}, 25 | {file = "asgiref-3.7.2.tar.gz", hash = "sha256:9e0ce3aa93a819ba5b45120216b23878cf6e8525eb3848653452b4192b92afed"}, 26 | ] 27 | 28 | [package.dependencies] 29 | typing-extensions = {version = ">=4", markers = "python_version < \"3.11\""} 30 | 31 | [package.extras] 32 | tests = ["mypy (>=0.800)", "pytest", "pytest-asyncio"] 33 | 34 | [[package]] 35 | name = "astroid" 36 | version = "2.11.7" 37 | description = "An abstract syntax tree for Python with inference support." 38 | optional = false 39 | python-versions = ">=3.6.2" 40 | files = [ 41 | {file = "astroid-2.11.7-py3-none-any.whl", hash = "sha256:86b0a340a512c65abf4368b80252754cda17c02cdbbd3f587dddf98112233e7b"}, 42 | {file = "astroid-2.11.7.tar.gz", hash = "sha256:bb24615c77f4837c707669d16907331374ae8a964650a66999da3f5ca68dc946"}, 43 | ] 44 | 45 | [package.dependencies] 46 | lazy-object-proxy = ">=1.4.0" 47 | setuptools = ">=20.0" 48 | typing-extensions = {version = ">=3.10", markers = "python_version < \"3.10\""} 49 | wrapt = ">=1.11,<2" 50 | 51 | [[package]] 52 | name = "attrs" 53 | version = "22.1.0" 54 | description = "Classes Without Boilerplate" 55 | optional = false 56 | python-versions = ">=3.5" 57 | files = [ 58 | {file = "attrs-22.1.0-py2.py3-none-any.whl", hash = "sha256:86efa402f67bf2df34f51a335487cf46b1ec130d02b8d39fd248abfd30da551c"}, 59 | {file = "attrs-22.1.0.tar.gz", hash = "sha256:29adc2665447e5191d0e7c568fde78b21f9672d344281d0c6e1ab085429b22b6"}, 60 | ] 61 | 62 | [package.extras] 63 | dev = ["cloudpickle", "coverage[toml] (>=5.0.2)", "furo", "hypothesis", "mypy (>=0.900,!=0.940)", "pre-commit", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "sphinx", "sphinx-notfound-page", "zope.interface"] 64 | docs = ["furo", "sphinx", "sphinx-notfound-page", "zope.interface"] 65 | tests = ["cloudpickle", "coverage[toml] (>=5.0.2)", "hypothesis", "mypy (>=0.900,!=0.940)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "zope.interface"] 66 | tests-no-zope = ["cloudpickle", "coverage[toml] (>=5.0.2)", "hypothesis", "mypy (>=0.900,!=0.940)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins"] 67 | 68 | [[package]] 69 | name = "backports-zoneinfo" 70 | version = "0.2.1" 71 | description = "Backport of the standard library zoneinfo module" 72 | optional = false 73 | python-versions = ">=3.6" 74 | files = [ 75 | {file = "backports.zoneinfo-0.2.1-cp36-cp36m-macosx_10_14_x86_64.whl", hash = "sha256:da6013fd84a690242c310d77ddb8441a559e9cb3d3d59ebac9aca1a57b2e18bc"}, 76 | {file = "backports.zoneinfo-0.2.1-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:89a48c0d158a3cc3f654da4c2de1ceba85263fafb861b98b59040a5086259722"}, 77 | {file = "backports.zoneinfo-0.2.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:1c5742112073a563c81f786e77514969acb58649bcdf6cdf0b4ed31a348d4546"}, 78 | {file = "backports.zoneinfo-0.2.1-cp36-cp36m-win32.whl", hash = "sha256:e8236383a20872c0cdf5a62b554b27538db7fa1bbec52429d8d106effbaeca08"}, 79 | {file = "backports.zoneinfo-0.2.1-cp36-cp36m-win_amd64.whl", hash = "sha256:8439c030a11780786a2002261569bdf362264f605dfa4d65090b64b05c9f79a7"}, 80 | {file = "backports.zoneinfo-0.2.1-cp37-cp37m-macosx_10_14_x86_64.whl", hash = "sha256:f04e857b59d9d1ccc39ce2da1021d196e47234873820cbeaad210724b1ee28ac"}, 81 | {file = "backports.zoneinfo-0.2.1-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:17746bd546106fa389c51dbea67c8b7c8f0d14b5526a579ca6ccf5ed72c526cf"}, 82 | {file = "backports.zoneinfo-0.2.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:5c144945a7752ca544b4b78c8c41544cdfaf9786f25fe5ffb10e838e19a27570"}, 83 | {file = "backports.zoneinfo-0.2.1-cp37-cp37m-win32.whl", hash = "sha256:e55b384612d93be96506932a786bbcde5a2db7a9e6a4bb4bffe8b733f5b9036b"}, 84 | {file = "backports.zoneinfo-0.2.1-cp37-cp37m-win_amd64.whl", hash = "sha256:a76b38c52400b762e48131494ba26be363491ac4f9a04c1b7e92483d169f6582"}, 85 | {file = "backports.zoneinfo-0.2.1-cp38-cp38-macosx_10_14_x86_64.whl", hash = "sha256:8961c0f32cd0336fb8e8ead11a1f8cd99ec07145ec2931122faaac1c8f7fd987"}, 86 | {file = "backports.zoneinfo-0.2.1-cp38-cp38-manylinux1_i686.whl", hash = "sha256:e81b76cace8eda1fca50e345242ba977f9be6ae3945af8d46326d776b4cf78d1"}, 87 | {file = "backports.zoneinfo-0.2.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:7b0a64cda4145548fed9efc10322770f929b944ce5cee6c0dfe0c87bf4c0c8c9"}, 88 | {file = "backports.zoneinfo-0.2.1-cp38-cp38-win32.whl", hash = "sha256:1b13e654a55cd45672cb54ed12148cd33628f672548f373963b0bff67b217328"}, 89 | {file = "backports.zoneinfo-0.2.1-cp38-cp38-win_amd64.whl", hash = "sha256:4a0f800587060bf8880f954dbef70de6c11bbe59c673c3d818921f042f9954a6"}, 90 | {file = "backports.zoneinfo-0.2.1.tar.gz", hash = "sha256:fadbfe37f74051d024037f223b8e001611eac868b5c5b06144ef4d8b799862f2"}, 91 | ] 92 | 93 | [package.extras] 94 | tzdata = ["tzdata"] 95 | 96 | [[package]] 97 | name = "black" 98 | version = "22.8.0" 99 | description = "The uncompromising code formatter." 100 | optional = false 101 | python-versions = ">=3.6.2" 102 | files = [ 103 | {file = "black-22.8.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:ce957f1d6b78a8a231b18e0dd2d94a33d2ba738cd88a7fe64f53f659eea49fdd"}, 104 | {file = "black-22.8.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:5107ea36b2b61917956d018bd25129baf9ad1125e39324a9b18248d362156a27"}, 105 | {file = "black-22.8.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e8166b7bfe5dcb56d325385bd1d1e0f635f24aae14b3ae437102dedc0c186747"}, 106 | {file = "black-22.8.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd82842bb272297503cbec1a2600b6bfb338dae017186f8f215c8958f8acf869"}, 107 | {file = "black-22.8.0-cp310-cp310-win_amd64.whl", hash = "sha256:d839150f61d09e7217f52917259831fe2b689f5c8e5e32611736351b89bb2a90"}, 108 | {file = "black-22.8.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:a05da0430bd5ced89176db098567973be52ce175a55677436a271102d7eaa3fe"}, 109 | {file = "black-22.8.0-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4a098a69a02596e1f2a58a2a1c8d5a05d5a74461af552b371e82f9fa4ada8342"}, 110 | {file = "black-22.8.0-cp36-cp36m-win_amd64.whl", hash = "sha256:5594efbdc35426e35a7defa1ea1a1cb97c7dbd34c0e49af7fb593a36bd45edab"}, 111 | {file = "black-22.8.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a983526af1bea1e4cf6768e649990f28ee4f4137266921c2c3cee8116ae42ec3"}, 112 | {file = "black-22.8.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3b2c25f8dea5e8444bdc6788a2f543e1fb01494e144480bc17f806178378005e"}, 113 | {file = "black-22.8.0-cp37-cp37m-win_amd64.whl", hash = "sha256:78dd85caaab7c3153054756b9fe8c611efa63d9e7aecfa33e533060cb14b6d16"}, 114 | {file = "black-22.8.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:cea1b2542d4e2c02c332e83150e41e3ca80dc0fb8de20df3c5e98e242156222c"}, 115 | {file = "black-22.8.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:5b879eb439094751185d1cfdca43023bc6786bd3c60372462b6f051efa6281a5"}, 116 | {file = "black-22.8.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:0a12e4e1353819af41df998b02c6742643cfef58282915f781d0e4dd7a200411"}, 117 | {file = "black-22.8.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c3a73f66b6d5ba7288cd5d6dad9b4c9b43f4e8a4b789a94bf5abfb878c663eb3"}, 118 | {file = "black-22.8.0-cp38-cp38-win_amd64.whl", hash = "sha256:e981e20ec152dfb3e77418fb616077937378b322d7b26aa1ff87717fb18b4875"}, 119 | {file = "black-22.8.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:8ce13ffed7e66dda0da3e0b2eb1bdfc83f5812f66e09aca2b0978593ed636b6c"}, 120 | {file = "black-22.8.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:32a4b17f644fc288c6ee2bafdf5e3b045f4eff84693ac069d87b1a347d861497"}, 121 | {file = "black-22.8.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:0ad827325a3a634bae88ae7747db1a395d5ee02cf05d9aa7a9bd77dfb10e940c"}, 122 | {file = "black-22.8.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:53198e28a1fb865e9fe97f88220da2e44df6da82b18833b588b1883b16bb5d41"}, 123 | {file = "black-22.8.0-cp39-cp39-win_amd64.whl", hash = "sha256:bc4d4123830a2d190e9cc42a2e43570f82ace35c3aeb26a512a2102bce5af7ec"}, 124 | {file = "black-22.8.0-py3-none-any.whl", hash = "sha256:d2c21d439b2baf7aa80d6dd4e3659259be64c6f49dfd0f32091063db0e006db4"}, 125 | {file = "black-22.8.0.tar.gz", hash = "sha256:792f7eb540ba9a17e8656538701d3eb1afcb134e3b45b71f20b25c77a8db7e6e"}, 126 | ] 127 | 128 | [package.dependencies] 129 | click = ">=8.0.0" 130 | mypy-extensions = ">=0.4.3" 131 | pathspec = ">=0.9.0" 132 | platformdirs = ">=2" 133 | tomli = {version = ">=1.1.0", markers = "python_full_version < \"3.11.0a7\""} 134 | typing-extensions = {version = ">=3.10.0.0", markers = "python_version < \"3.10\""} 135 | 136 | [package.extras] 137 | colorama = ["colorama (>=0.4.3)"] 138 | d = ["aiohttp (>=3.7.4)"] 139 | jupyter = ["ipython (>=7.8.0)", "tokenize-rt (>=3.2.0)"] 140 | uvloop = ["uvloop (>=0.15.2)"] 141 | 142 | [[package]] 143 | name = "CacheControl" 144 | version = "0.12.11" 145 | description = "httplib2 caching for requests" 146 | optional = false 147 | python-versions = ">=3.6" 148 | files = [ 149 | {file = "CacheControl-0.12.11-py2.py3-none-any.whl", hash = "sha256:2c75d6a8938cb1933c75c50184549ad42728a27e9f6b92fd677c3151aa72555b"}, 150 | {file = "CacheControl-0.12.11.tar.gz", hash = "sha256:a5b9fcc986b184db101aa280b42ecdcdfc524892596f606858e0b7a8b4d9e144"}, 151 | ] 152 | 153 | [package.dependencies] 154 | msgpack = ">=0.5.2" 155 | requests = "*" 156 | 157 | [package.extras] 158 | filecache = ["lockfile (>=0.9)"] 159 | redis = ["redis (>=2.10.5)"] 160 | 161 | [[package]] 162 | name = "certifi" 163 | version = "2022.9.14" 164 | description = "Python package for providing Mozilla's CA Bundle." 165 | optional = false 166 | python-versions = ">=3.6" 167 | files = [ 168 | {file = "certifi-2022.9.14-py3-none-any.whl", hash = "sha256:e232343de1ab72c2aa521b625c80f699e356830fd0e2c620b465b304b17b0516"}, 169 | {file = "certifi-2022.9.14.tar.gz", hash = "sha256:36973885b9542e6bd01dea287b2b4b3b21236307c56324fcc3f1160f2d655ed5"}, 170 | ] 171 | 172 | [[package]] 173 | name = "cfgv" 174 | version = "3.3.1" 175 | description = "Validate configuration and produce human readable error messages." 176 | optional = false 177 | python-versions = ">=3.6.1" 178 | files = [ 179 | {file = "cfgv-3.3.1-py2.py3-none-any.whl", hash = "sha256:c6a0883f3917a037485059700b9e75da2464e6c27051014ad85ba6aaa5884426"}, 180 | {file = "cfgv-3.3.1.tar.gz", hash = "sha256:f5a830efb9ce7a445376bb66ec94c638a9787422f96264c98edc6bdeed8ab736"}, 181 | ] 182 | 183 | [[package]] 184 | name = "charset-normalizer" 185 | version = "2.1.1" 186 | description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." 187 | optional = false 188 | python-versions = ">=3.6.0" 189 | files = [ 190 | {file = "charset-normalizer-2.1.1.tar.gz", hash = "sha256:5a3d016c7c547f69d6f81fb0db9449ce888b418b5b9952cc5e6e66843e9dd845"}, 191 | {file = "charset_normalizer-2.1.1-py3-none-any.whl", hash = "sha256:83e9a75d1911279afd89352c68b45348559d1fc0506b054b346651b5e7fee29f"}, 192 | ] 193 | 194 | [package.extras] 195 | unicode-backport = ["unicodedata2"] 196 | 197 | [[package]] 198 | name = "click" 199 | version = "8.1.3" 200 | description = "Composable command line interface toolkit" 201 | optional = false 202 | python-versions = ">=3.7" 203 | files = [ 204 | {file = "click-8.1.3-py3-none-any.whl", hash = "sha256:bb4d8133cb15a609f44e8213d9b391b0809795062913b383c62be0ee95b1db48"}, 205 | {file = "click-8.1.3.tar.gz", hash = "sha256:7682dc8afb30297001674575ea00d1814d808d6a36af415a82bd481d37ba7b8e"}, 206 | ] 207 | 208 | [package.dependencies] 209 | colorama = {version = "*", markers = "platform_system == \"Windows\""} 210 | 211 | [[package]] 212 | name = "colorama" 213 | version = "0.4.5" 214 | description = "Cross-platform colored terminal text." 215 | optional = false 216 | python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" 217 | files = [ 218 | {file = "colorama-0.4.5-py2.py3-none-any.whl", hash = "sha256:854bf444933e37f5824ae7bfc1e98d5bce2ebe4160d46b5edf346a89358e99da"}, 219 | {file = "colorama-0.4.5.tar.gz", hash = "sha256:e6c6b4334fc50988a639d9b98aa429a0b57da6e17b9a44f0451f930b6967b7a4"}, 220 | ] 221 | 222 | [[package]] 223 | name = "commonmark" 224 | version = "0.9.1" 225 | description = "Python parser for the CommonMark Markdown spec" 226 | optional = false 227 | python-versions = "*" 228 | files = [ 229 | {file = "commonmark-0.9.1-py2.py3-none-any.whl", hash = "sha256:da2f38c92590f83de410ba1a3cbceafbc74fee9def35f9251ba9a971d6d66fd9"}, 230 | {file = "commonmark-0.9.1.tar.gz", hash = "sha256:452f9dc859be7f06631ddcb328b6919c67984aca654e5fefb3914d54691aed60"}, 231 | ] 232 | 233 | [package.extras] 234 | test = ["flake8 (==3.7.8)", "hypothesis (==3.55.3)"] 235 | 236 | [[package]] 237 | name = "coverage" 238 | version = "6.5.0" 239 | description = "Code coverage measurement for Python" 240 | optional = false 241 | python-versions = ">=3.7" 242 | files = [ 243 | {file = "coverage-6.5.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ef8674b0ee8cc11e2d574e3e2998aea5df5ab242e012286824ea3c6970580e53"}, 244 | {file = "coverage-6.5.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:784f53ebc9f3fd0e2a3f6a78b2be1bd1f5575d7863e10c6e12504f240fd06660"}, 245 | {file = "coverage-6.5.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b4a5be1748d538a710f87542f22c2cad22f80545a847ad91ce45e77417293eb4"}, 246 | {file = "coverage-6.5.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:83516205e254a0cb77d2d7bb3632ee019d93d9f4005de31dca0a8c3667d5bc04"}, 247 | {file = "coverage-6.5.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:af4fffaffc4067232253715065e30c5a7ec6faac36f8fc8d6f64263b15f74db0"}, 248 | {file = "coverage-6.5.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:97117225cdd992a9c2a5515db1f66b59db634f59d0679ca1fa3fe8da32749cae"}, 249 | {file = "coverage-6.5.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:a1170fa54185845505fbfa672f1c1ab175446c887cce8212c44149581cf2d466"}, 250 | {file = "coverage-6.5.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:11b990d520ea75e7ee8dcab5bc908072aaada194a794db9f6d7d5cfd19661e5a"}, 251 | {file = "coverage-6.5.0-cp310-cp310-win32.whl", hash = "sha256:5dbec3b9095749390c09ab7c89d314727f18800060d8d24e87f01fb9cfb40b32"}, 252 | {file = "coverage-6.5.0-cp310-cp310-win_amd64.whl", hash = "sha256:59f53f1dc5b656cafb1badd0feb428c1e7bc19b867479ff72f7a9dd9b479f10e"}, 253 | {file = "coverage-6.5.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4a5375e28c5191ac38cca59b38edd33ef4cc914732c916f2929029b4bfb50795"}, 254 | {file = "coverage-6.5.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c4ed2820d919351f4167e52425e096af41bfabacb1857186c1ea32ff9983ed75"}, 255 | {file = "coverage-6.5.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:33a7da4376d5977fbf0a8ed91c4dffaaa8dbf0ddbf4c8eea500a2486d8bc4d7b"}, 256 | {file = "coverage-6.5.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a8fb6cf131ac4070c9c5a3e21de0f7dc5a0fbe8bc77c9456ced896c12fcdad91"}, 257 | {file = "coverage-6.5.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:a6b7d95969b8845250586f269e81e5dfdd8ff828ddeb8567a4a2eaa7313460c4"}, 258 | {file = "coverage-6.5.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:1ef221513e6f68b69ee9e159506d583d31aa3567e0ae84eaad9d6ec1107dddaa"}, 259 | {file = "coverage-6.5.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:cca4435eebea7962a52bdb216dec27215d0df64cf27fc1dd538415f5d2b9da6b"}, 260 | {file = "coverage-6.5.0-cp311-cp311-win32.whl", hash = "sha256:98e8a10b7a314f454d9eff4216a9a94d143a7ee65018dd12442e898ee2310578"}, 261 | {file = "coverage-6.5.0-cp311-cp311-win_amd64.whl", hash = "sha256:bc8ef5e043a2af066fa8cbfc6e708d58017024dc4345a1f9757b329a249f041b"}, 262 | {file = "coverage-6.5.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:4433b90fae13f86fafff0b326453dd42fc9a639a0d9e4eec4d366436d1a41b6d"}, 263 | {file = "coverage-6.5.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f4f05d88d9a80ad3cac6244d36dd89a3c00abc16371769f1340101d3cb899fc3"}, 264 | {file = "coverage-6.5.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:94e2565443291bd778421856bc975d351738963071e9b8839ca1fc08b42d4bef"}, 265 | {file = "coverage-6.5.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:027018943386e7b942fa832372ebc120155fd970837489896099f5cfa2890f79"}, 266 | {file = "coverage-6.5.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:255758a1e3b61db372ec2736c8e2a1fdfaf563977eedbdf131de003ca5779b7d"}, 267 | {file = "coverage-6.5.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:851cf4ff24062c6aec510a454b2584f6e998cada52d4cb58c5e233d07172e50c"}, 268 | {file = "coverage-6.5.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:12adf310e4aafddc58afdb04d686795f33f4d7a6fa67a7a9d4ce7d6ae24d949f"}, 269 | {file = "coverage-6.5.0-cp37-cp37m-win32.whl", hash = "sha256:b5604380f3415ba69de87a289a2b56687faa4fe04dbee0754bfcae433489316b"}, 270 | {file = "coverage-6.5.0-cp37-cp37m-win_amd64.whl", hash = "sha256:4a8dbc1f0fbb2ae3de73eb0bdbb914180c7abfbf258e90b311dcd4f585d44bd2"}, 271 | {file = "coverage-6.5.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:d900bb429fdfd7f511f868cedd03a6bbb142f3f9118c09b99ef8dc9bf9643c3c"}, 272 | {file = "coverage-6.5.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:2198ea6fc548de52adc826f62cb18554caedfb1d26548c1b7c88d8f7faa8f6ba"}, 273 | {file = "coverage-6.5.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6c4459b3de97b75e3bd6b7d4b7f0db13f17f504f3d13e2a7c623786289dd670e"}, 274 | {file = "coverage-6.5.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:20c8ac5386253717e5ccc827caad43ed66fea0efe255727b1053a8154d952398"}, 275 | {file = "coverage-6.5.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6b07130585d54fe8dff3d97b93b0e20290de974dc8177c320aeaf23459219c0b"}, 276 | {file = "coverage-6.5.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:dbdb91cd8c048c2b09eb17713b0c12a54fbd587d79adcebad543bc0cd9a3410b"}, 277 | {file = "coverage-6.5.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:de3001a203182842a4630e7b8d1a2c7c07ec1b45d3084a83d5d227a3806f530f"}, 278 | {file = "coverage-6.5.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:e07f4a4a9b41583d6eabec04f8b68076ab3cd44c20bd29332c6572dda36f372e"}, 279 | {file = "coverage-6.5.0-cp38-cp38-win32.whl", hash = "sha256:6d4817234349a80dbf03640cec6109cd90cba068330703fa65ddf56b60223a6d"}, 280 | {file = "coverage-6.5.0-cp38-cp38-win_amd64.whl", hash = "sha256:7ccf362abd726b0410bf8911c31fbf97f09f8f1061f8c1cf03dfc4b6372848f6"}, 281 | {file = "coverage-6.5.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:633713d70ad6bfc49b34ead4060531658dc6dfc9b3eb7d8a716d5873377ab745"}, 282 | {file = "coverage-6.5.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:95203854f974e07af96358c0b261f1048d8e1083f2de9b1c565e1be4a3a48cfc"}, 283 | {file = "coverage-6.5.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b9023e237f4c02ff739581ef35969c3739445fb059b060ca51771e69101efffe"}, 284 | {file = "coverage-6.5.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:265de0fa6778d07de30bcf4d9dc471c3dc4314a23a3c6603d356a3c9abc2dfcf"}, 285 | {file = "coverage-6.5.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f830ed581b45b82451a40faabb89c84e1a998124ee4212d440e9c6cf70083e5"}, 286 | {file = "coverage-6.5.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:7b6be138d61e458e18d8e6ddcddd36dd96215edfe5f1168de0b1b32635839b62"}, 287 | {file = "coverage-6.5.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:42eafe6778551cf006a7c43153af1211c3aaab658d4d66fa5fcc021613d02518"}, 288 | {file = "coverage-6.5.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:723e8130d4ecc8f56e9a611e73b31219595baa3bb252d539206f7bbbab6ffc1f"}, 289 | {file = "coverage-6.5.0-cp39-cp39-win32.whl", hash = "sha256:d9ecf0829c6a62b9b573c7bb6d4dcd6ba8b6f80be9ba4fc7ed50bf4ac9aecd72"}, 290 | {file = "coverage-6.5.0-cp39-cp39-win_amd64.whl", hash = "sha256:fc2af30ed0d5ae0b1abdb4ebdce598eafd5b35397d4d75deb341a614d333d987"}, 291 | {file = "coverage-6.5.0-pp36.pp37.pp38-none-any.whl", hash = "sha256:1431986dac3923c5945271f169f59c45b8802a114c8f548d611f2015133df77a"}, 292 | {file = "coverage-6.5.0.tar.gz", hash = "sha256:f642e90754ee3e06b0e7e51bce3379590e76b7f76b708e1a71ff043f87025c84"}, 293 | ] 294 | 295 | [package.dependencies] 296 | tomli = {version = "*", optional = true, markers = "python_full_version <= \"3.11.0a6\" and extra == \"toml\""} 297 | 298 | [package.extras] 299 | toml = ["tomli"] 300 | 301 | [[package]] 302 | name = "crispy-bulma" 303 | version = "0.8.0" 304 | description = "Bulma template pack for django-crispy-forms" 305 | optional = false 306 | python-versions = ">=3.7" 307 | files = [ 308 | {file = "crispy-bulma-0.8.0.tar.gz", hash = "sha256:d9bfb56636038becc3971fbd24c464cd9ee810db04667e9fd86fc58d299cc2b7"}, 309 | {file = "crispy_bulma-0.8.0-py3-none-any.whl", hash = "sha256:4f80291dfa38b738e44c21be43bffc9bb35540e54d9558186ea2fe958179b27f"}, 310 | ] 311 | 312 | [package.dependencies] 313 | Django = ">=2.2" 314 | django-crispy-forms = ">=1.12.0" 315 | 316 | [package.extras] 317 | test = ["pytest", "pytest-django"] 318 | 319 | [[package]] 320 | name = "dill" 321 | version = "0.3.5.1" 322 | description = "serialize all of python" 323 | optional = false 324 | python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*, !=3.6.*" 325 | files = [ 326 | {file = "dill-0.3.5.1-py2.py3-none-any.whl", hash = "sha256:33501d03270bbe410c72639b350e941882a8b0fd55357580fbc873fba0c59302"}, 327 | {file = "dill-0.3.5.1.tar.gz", hash = "sha256:d75e41f3eff1eee599d738e76ba8f4ad98ea229db8b085318aa2b3333a208c86"}, 328 | ] 329 | 330 | [package.extras] 331 | graph = ["objgraph (>=1.7.2)"] 332 | 333 | [[package]] 334 | name = "distlib" 335 | version = "0.3.6" 336 | description = "Distribution utilities" 337 | optional = false 338 | python-versions = "*" 339 | files = [ 340 | {file = "distlib-0.3.6-py2.py3-none-any.whl", hash = "sha256:f35c4b692542ca110de7ef0bea44d73981caeb34ca0b9b6b2e6d7790dda8f80e"}, 341 | {file = "distlib-0.3.6.tar.gz", hash = "sha256:14bad2d9b04d3a36127ac97f30b12a19268f211063d8f8ee4f47108896e11b46"}, 342 | ] 343 | 344 | [[package]] 345 | name = "django" 346 | version = "4.2.8" 347 | description = "A high-level Python web framework that encourages rapid development and clean, pragmatic design." 348 | optional = false 349 | python-versions = ">=3.8" 350 | files = [ 351 | {file = "Django-4.2.8-py3-none-any.whl", hash = "sha256:6cb5dcea9e3d12c47834d32156b8841f533a4493c688e2718cafd51aa430ba6d"}, 352 | {file = "Django-4.2.8.tar.gz", hash = "sha256:d69d5e36cc5d9f4eb4872be36c622878afcdce94062716cf3e25bcedcb168b62"}, 353 | ] 354 | 355 | [package.dependencies] 356 | asgiref = ">=3.6.0,<4" 357 | "backports.zoneinfo" = {version = "*", markers = "python_version < \"3.9\""} 358 | sqlparse = ">=0.3.1" 359 | tzdata = {version = "*", markers = "sys_platform == \"win32\""} 360 | 361 | [package.extras] 362 | argon2 = ["argon2-cffi (>=19.1.0)"] 363 | bcrypt = ["bcrypt"] 364 | 365 | [[package]] 366 | name = "django-crispy-forms" 367 | version = "1.14.0" 368 | description = "Best way to have Django DRY forms" 369 | optional = false 370 | python-versions = ">=3.7" 371 | files = [ 372 | {file = "django-crispy-forms-1.14.0.tar.gz", hash = "sha256:35887b8851a931374dd697207a8f56c57a9c5cb9dbf0b9fa54314da5666cea5b"}, 373 | {file = "django_crispy_forms-1.14.0-py3-none-any.whl", hash = "sha256:bc4d2037f6de602d39c0bc452ac3029d1f5d65e88458872cc4dbc01c3a400604"}, 374 | ] 375 | 376 | [[package]] 377 | name = "django-filter" 378 | version = "22.1" 379 | description = "Django-filter is a reusable Django application for allowing users to filter querysets dynamically." 380 | optional = false 381 | python-versions = ">=3.7" 382 | files = [ 383 | {file = "django-filter-22.1.tar.gz", hash = "sha256:ed473b76e84f7e83b2511bb2050c3efb36d135207d0128dfe3ae4b36e3594ba5"}, 384 | {file = "django_filter-22.1-py3-none-any.whl", hash = "sha256:ed429e34760127e3520a67f415bec4c905d4649fbe45d0d6da37e6ff5e0287eb"}, 385 | ] 386 | 387 | [package.dependencies] 388 | Django = ">=3.2" 389 | 390 | [[package]] 391 | name = "django-stubs" 392 | version = "1.12.0" 393 | description = "Mypy stubs for Django" 394 | optional = false 395 | python-versions = ">=3.7" 396 | files = [ 397 | {file = "django-stubs-1.12.0.tar.gz", hash = "sha256:ea8b35d0da49f7b2ee99a79125f1943e033431dd114726d6643cc35de619230e"}, 398 | {file = "django_stubs-1.12.0-py3-none-any.whl", hash = "sha256:0dff8ec0ba3abe046450b3d8a29ce9e72629893d2c1ef679189cc2bfdb6d2f64"}, 399 | ] 400 | 401 | [package.dependencies] 402 | django = "*" 403 | django-stubs-ext = ">=0.4.0" 404 | mypy = ">=0.930" 405 | tomli = "*" 406 | types-pytz = "*" 407 | types-PyYAML = "*" 408 | typing-extensions = "*" 409 | 410 | [package.extras] 411 | compatible-mypy = ["mypy (>=0.930,<0.970)"] 412 | 413 | [[package]] 414 | name = "django-stubs-ext" 415 | version = "0.5.0" 416 | description = "Monkey-patching and extensions for django-stubs" 417 | optional = false 418 | python-versions = ">=3.6" 419 | files = [ 420 | {file = "django-stubs-ext-0.5.0.tar.gz", hash = "sha256:9bd7418376ab00b7f88d6d56be9fece85bfa0c7c348ac621155fa4d7a91146f2"}, 421 | {file = "django_stubs_ext-0.5.0-py3-none-any.whl", hash = "sha256:c5d8db53d29c756e7e3d0820a5a079a43bc38d8fab0e1b8bd5df2f3366c54b5a"}, 422 | ] 423 | 424 | [package.dependencies] 425 | django = "*" 426 | typing-extensions = "*" 427 | 428 | [[package]] 429 | name = "docutils" 430 | version = "0.18.1" 431 | description = "Docutils -- Python Documentation Utilities" 432 | optional = false 433 | python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" 434 | files = [ 435 | {file = "docutils-0.18.1-py2.py3-none-any.whl", hash = "sha256:23010f129180089fbcd3bc08cfefccb3b890b0050e1ca00c867036e9d161b98c"}, 436 | {file = "docutils-0.18.1.tar.gz", hash = "sha256:679987caf361a7539d76e584cbeddc311e3aee937877c87346f31debc63e9d06"}, 437 | ] 438 | 439 | [[package]] 440 | name = "filelock" 441 | version = "3.8.0" 442 | description = "A platform independent file lock." 443 | optional = false 444 | python-versions = ">=3.7" 445 | files = [ 446 | {file = "filelock-3.8.0-py3-none-any.whl", hash = "sha256:617eb4e5eedc82fc5f47b6d61e4d11cb837c56cb4544e39081099fa17ad109d4"}, 447 | {file = "filelock-3.8.0.tar.gz", hash = "sha256:55447caa666f2198c5b6b13a26d2084d26fa5b115c00d065664b2124680c4edc"}, 448 | ] 449 | 450 | [package.extras] 451 | docs = ["furo (>=2022.6.21)", "sphinx (>=5.1.1)", "sphinx-autodoc-typehints (>=1.19.1)"] 452 | testing = ["covdefaults (>=2.2)", "coverage (>=6.4.2)", "pytest (>=7.1.2)", "pytest-cov (>=3)", "pytest-timeout (>=2.1)"] 453 | 454 | [[package]] 455 | name = "identify" 456 | version = "2.5.6" 457 | description = "File identification library for Python" 458 | optional = false 459 | python-versions = ">=3.7" 460 | files = [ 461 | {file = "identify-2.5.6-py2.py3-none-any.whl", hash = "sha256:b276db7ec52d7e89f5bc4653380e33054ddc803d25875952ad90b0f012cbcdaa"}, 462 | {file = "identify-2.5.6.tar.gz", hash = "sha256:6c32dbd747aa4ceee1df33f25fed0b0f6e0d65721b15bd151307ff7056d50245"}, 463 | ] 464 | 465 | [package.extras] 466 | license = ["ukkonen"] 467 | 468 | [[package]] 469 | name = "idna" 470 | version = "3.4" 471 | description = "Internationalized Domain Names in Applications (IDNA)" 472 | optional = false 473 | python-versions = ">=3.5" 474 | files = [ 475 | {file = "idna-3.4-py3-none-any.whl", hash = "sha256:90b77e79eaa3eba6de819a0c442c0b4ceefc341a7a2ab77d7562bf49f425c5c2"}, 476 | {file = "idna-3.4.tar.gz", hash = "sha256:814f528e8dead7d329833b91c5faa87d60bf71824cd12a7530b5526063d02cb4"}, 477 | ] 478 | 479 | [[package]] 480 | name = "importlib-metadata" 481 | version = "6.9.0" 482 | description = "Read metadata from Python packages" 483 | optional = false 484 | python-versions = ">=3.8" 485 | files = [ 486 | {file = "importlib_metadata-6.9.0-py3-none-any.whl", hash = "sha256:1c8dc6839ddc9771412596926f24cb5a553bbd40624ee2c7e55e531542bed3b8"}, 487 | {file = "importlib_metadata-6.9.0.tar.gz", hash = "sha256:e8acb523c335a91822674e149b46c0399ec4d328c4d1f6e49c273da5ff0201b9"}, 488 | ] 489 | 490 | [package.dependencies] 491 | zipp = ">=0.5" 492 | 493 | [package.extras] 494 | docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (<7.2.5)", "sphinx (>=3.5)", "sphinx-lint"] 495 | perf = ["ipython"] 496 | testing = ["flufl.flake8", "importlib-resources (>=1.3)", "packaging", "pyfakefs", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy (>=0.9.1)", "pytest-perf (>=0.9.2)", "pytest-ruff"] 497 | 498 | [[package]] 499 | name = "iniconfig" 500 | version = "1.1.1" 501 | description = "iniconfig: brain-dead simple config-ini parsing" 502 | optional = false 503 | python-versions = "*" 504 | files = [ 505 | {file = "iniconfig-1.1.1-py2.py3-none-any.whl", hash = "sha256:011e24c64b7f47f6ebd835bb12a743f2fbe9a26d4cecaa7f53bc4f35ee9da8b3"}, 506 | {file = "iniconfig-1.1.1.tar.gz", hash = "sha256:bc3af051d7d14b2ee5ef9969666def0cd1a000e121eaea580d4a313df4b37f32"}, 507 | ] 508 | 509 | [[package]] 510 | name = "isort" 511 | version = "5.10.1" 512 | description = "A Python utility / library to sort Python imports." 513 | optional = false 514 | python-versions = ">=3.6.1,<4.0" 515 | files = [ 516 | {file = "isort-5.10.1-py3-none-any.whl", hash = "sha256:6f62d78e2f89b4500b080fe3a81690850cd254227f27f75c3a0c491a1f351ba7"}, 517 | {file = "isort-5.10.1.tar.gz", hash = "sha256:e8443a5e7a020e9d7f97f1d7d9cd17c88bcb3bc7e218bf9cf5095fe550be2951"}, 518 | ] 519 | 520 | [package.extras] 521 | colors = ["colorama (>=0.4.3,<0.5.0)"] 522 | pipfile-deprecated-finder = ["pipreqs", "requirementslib"] 523 | plugins = ["setuptools"] 524 | requirements-deprecated-finder = ["pip-api", "pipreqs"] 525 | 526 | [[package]] 527 | name = "lazy-object-proxy" 528 | version = "1.7.1" 529 | description = "A fast and thorough lazy object proxy." 530 | optional = false 531 | python-versions = ">=3.6" 532 | files = [ 533 | {file = "lazy-object-proxy-1.7.1.tar.gz", hash = "sha256:d609c75b986def706743cdebe5e47553f4a5a1da9c5ff66d76013ef396b5a8a4"}, 534 | {file = "lazy_object_proxy-1.7.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:bb8c5fd1684d60a9902c60ebe276da1f2281a318ca16c1d0a96db28f62e9166b"}, 535 | {file = "lazy_object_proxy-1.7.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a57d51ed2997e97f3b8e3500c984db50a554bb5db56c50b5dab1b41339b37e36"}, 536 | {file = "lazy_object_proxy-1.7.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd45683c3caddf83abbb1249b653a266e7069a09f486daa8863fb0e7496a9fdb"}, 537 | {file = "lazy_object_proxy-1.7.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:8561da8b3dd22d696244d6d0d5330618c993a215070f473b699e00cf1f3f6443"}, 538 | {file = "lazy_object_proxy-1.7.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fccdf7c2c5821a8cbd0a9440a456f5050492f2270bd54e94360cac663398739b"}, 539 | {file = "lazy_object_proxy-1.7.1-cp310-cp310-win32.whl", hash = "sha256:898322f8d078f2654d275124a8dd19b079080ae977033b713f677afcfc88e2b9"}, 540 | {file = "lazy_object_proxy-1.7.1-cp310-cp310-win_amd64.whl", hash = "sha256:85b232e791f2229a4f55840ed54706110c80c0a210d076eee093f2b2e33e1bfd"}, 541 | {file = "lazy_object_proxy-1.7.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:46ff647e76f106bb444b4533bb4153c7370cdf52efc62ccfc1a28bdb3cc95442"}, 542 | {file = "lazy_object_proxy-1.7.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:12f3bb77efe1367b2515f8cb4790a11cffae889148ad33adad07b9b55e0ab22c"}, 543 | {file = "lazy_object_proxy-1.7.1-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c19814163728941bb871240d45c4c30d33b8a2e85972c44d4e63dd7107faba44"}, 544 | {file = "lazy_object_proxy-1.7.1-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:e40f2013d96d30217a51eeb1db28c9ac41e9d0ee915ef9d00da639c5b63f01a1"}, 545 | {file = "lazy_object_proxy-1.7.1-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:2052837718516a94940867e16b1bb10edb069ab475c3ad84fd1e1a6dd2c0fcfc"}, 546 | {file = "lazy_object_proxy-1.7.1-cp36-cp36m-win32.whl", hash = "sha256:6a24357267aa976abab660b1d47a34aaf07259a0c3859a34e536f1ee6e76b5bb"}, 547 | {file = "lazy_object_proxy-1.7.1-cp36-cp36m-win_amd64.whl", hash = "sha256:6aff3fe5de0831867092e017cf67e2750c6a1c7d88d84d2481bd84a2e019ec35"}, 548 | {file = "lazy_object_proxy-1.7.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:6a6e94c7b02641d1311228a102607ecd576f70734dc3d5e22610111aeacba8a0"}, 549 | {file = "lazy_object_proxy-1.7.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c4ce15276a1a14549d7e81c243b887293904ad2d94ad767f42df91e75fd7b5b6"}, 550 | {file = "lazy_object_proxy-1.7.1-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e368b7f7eac182a59ff1f81d5f3802161932a41dc1b1cc45c1f757dc876b5d2c"}, 551 | {file = "lazy_object_proxy-1.7.1-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:6ecbb350991d6434e1388bee761ece3260e5228952b1f0c46ffc800eb313ff42"}, 552 | {file = "lazy_object_proxy-1.7.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:553b0f0d8dbf21890dd66edd771f9b1b5f51bd912fa5f26de4449bfc5af5e029"}, 553 | {file = "lazy_object_proxy-1.7.1-cp37-cp37m-win32.whl", hash = "sha256:c7a683c37a8a24f6428c28c561c80d5f4fd316ddcf0c7cab999b15ab3f5c5c69"}, 554 | {file = "lazy_object_proxy-1.7.1-cp37-cp37m-win_amd64.whl", hash = "sha256:df2631f9d67259dc9620d831384ed7732a198eb434eadf69aea95ad18c587a28"}, 555 | {file = "lazy_object_proxy-1.7.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:07fa44286cda977bd4803b656ffc1c9b7e3bc7dff7d34263446aec8f8c96f88a"}, 556 | {file = "lazy_object_proxy-1.7.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4dca6244e4121c74cc20542c2ca39e5c4a5027c81d112bfb893cf0790f96f57e"}, 557 | {file = "lazy_object_proxy-1.7.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:91ba172fc5b03978764d1df5144b4ba4ab13290d7bab7a50f12d8117f8630c38"}, 558 | {file = "lazy_object_proxy-1.7.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:043651b6cb706eee4f91854da4a089816a6606c1428fd391573ef8cb642ae4f7"}, 559 | {file = "lazy_object_proxy-1.7.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:b9e89b87c707dd769c4ea91f7a31538888aad05c116a59820f28d59b3ebfe25a"}, 560 | {file = "lazy_object_proxy-1.7.1-cp38-cp38-win32.whl", hash = "sha256:9d166602b525bf54ac994cf833c385bfcc341b364e3ee71e3bf5a1336e677b55"}, 561 | {file = "lazy_object_proxy-1.7.1-cp38-cp38-win_amd64.whl", hash = "sha256:8f3953eb575b45480db6568306893f0bd9d8dfeeebd46812aa09ca9579595148"}, 562 | {file = "lazy_object_proxy-1.7.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:dd7ed7429dbb6c494aa9bc4e09d94b778a3579be699f9d67da7e6804c422d3de"}, 563 | {file = "lazy_object_proxy-1.7.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:70ed0c2b380eb6248abdef3cd425fc52f0abd92d2b07ce26359fcbc399f636ad"}, 564 | {file = "lazy_object_proxy-1.7.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7096a5e0c1115ec82641afbdd70451a144558ea5cf564a896294e346eb611be1"}, 565 | {file = "lazy_object_proxy-1.7.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:f769457a639403073968d118bc70110e7dce294688009f5c24ab78800ae56dc8"}, 566 | {file = "lazy_object_proxy-1.7.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:39b0e26725c5023757fc1ab2a89ef9d7ab23b84f9251e28f9cc114d5b59c1b09"}, 567 | {file = "lazy_object_proxy-1.7.1-cp39-cp39-win32.whl", hash = "sha256:2130db8ed69a48a3440103d4a520b89d8a9405f1b06e2cc81640509e8bf6548f"}, 568 | {file = "lazy_object_proxy-1.7.1-cp39-cp39-win_amd64.whl", hash = "sha256:677ea950bef409b47e51e733283544ac3d660b709cfce7b187f5ace137960d61"}, 569 | {file = "lazy_object_proxy-1.7.1-pp37.pp38-none-any.whl", hash = "sha256:d66906d5785da8e0be7360912e99c9188b70f52c422f9fc18223347235691a84"}, 570 | ] 571 | 572 | [[package]] 573 | name = "lxml" 574 | version = "4.9.3" 575 | description = "Powerful and Pythonic XML processing library combining libxml2/libxslt with the ElementTree API." 576 | optional = false 577 | python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, != 3.4.*" 578 | files = [ 579 | {file = "lxml-4.9.3-cp27-cp27m-macosx_11_0_x86_64.whl", hash = "sha256:b0a545b46b526d418eb91754565ba5b63b1c0b12f9bd2f808c852d9b4b2f9b5c"}, 580 | {file = "lxml-4.9.3-cp27-cp27m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:075b731ddd9e7f68ad24c635374211376aa05a281673ede86cbe1d1b3455279d"}, 581 | {file = "lxml-4.9.3-cp27-cp27m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:1e224d5755dba2f4a9498e150c43792392ac9b5380aa1b845f98a1618c94eeef"}, 582 | {file = "lxml-4.9.3-cp27-cp27m-win32.whl", hash = "sha256:2c74524e179f2ad6d2a4f7caf70e2d96639c0954c943ad601a9e146c76408ed7"}, 583 | {file = "lxml-4.9.3-cp27-cp27m-win_amd64.whl", hash = "sha256:4f1026bc732b6a7f96369f7bfe1a4f2290fb34dce00d8644bc3036fb351a4ca1"}, 584 | {file = "lxml-4.9.3-cp27-cp27mu-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c0781a98ff5e6586926293e59480b64ddd46282953203c76ae15dbbbf302e8bb"}, 585 | {file = "lxml-4.9.3-cp27-cp27mu-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:cef2502e7e8a96fe5ad686d60b49e1ab03e438bd9123987994528febd569868e"}, 586 | {file = "lxml-4.9.3-cp310-cp310-macosx_11_0_x86_64.whl", hash = "sha256:b86164d2cff4d3aaa1f04a14685cbc072efd0b4f99ca5708b2ad1b9b5988a991"}, 587 | {file = "lxml-4.9.3-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:42871176e7896d5d45138f6d28751053c711ed4d48d8e30b498da155af39aebd"}, 588 | {file = "lxml-4.9.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:ae8b9c6deb1e634ba4f1930eb67ef6e6bf6a44b6eb5ad605642b2d6d5ed9ce3c"}, 589 | {file = "lxml-4.9.3-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:411007c0d88188d9f621b11d252cce90c4a2d1a49db6c068e3c16422f306eab8"}, 590 | {file = "lxml-4.9.3-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:cd47b4a0d41d2afa3e58e5bf1f62069255aa2fd6ff5ee41604418ca925911d76"}, 591 | {file = "lxml-4.9.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:0e2cb47860da1f7e9a5256254b74ae331687b9672dfa780eed355c4c9c3dbd23"}, 592 | {file = "lxml-4.9.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:1247694b26342a7bf47c02e513d32225ededd18045264d40758abeb3c838a51f"}, 593 | {file = "lxml-4.9.3-cp310-cp310-win32.whl", hash = "sha256:cdb650fc86227eba20de1a29d4b2c1bfe139dc75a0669270033cb2ea3d391b85"}, 594 | {file = "lxml-4.9.3-cp310-cp310-win_amd64.whl", hash = "sha256:97047f0d25cd4bcae81f9ec9dc290ca3e15927c192df17331b53bebe0e3ff96d"}, 595 | {file = "lxml-4.9.3-cp311-cp311-macosx_11_0_universal2.whl", hash = "sha256:1f447ea5429b54f9582d4b955f5f1985f278ce5cf169f72eea8afd9502973dd5"}, 596 | {file = "lxml-4.9.3-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:57d6ba0ca2b0c462f339640d22882acc711de224d769edf29962b09f77129cbf"}, 597 | {file = "lxml-4.9.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:9767e79108424fb6c3edf8f81e6730666a50feb01a328f4a016464a5893f835a"}, 598 | {file = "lxml-4.9.3-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:71c52db65e4b56b8ddc5bb89fb2e66c558ed9d1a74a45ceb7dcb20c191c3df2f"}, 599 | {file = "lxml-4.9.3-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:d73d8ecf8ecf10a3bd007f2192725a34bd62898e8da27eb9d32a58084f93962b"}, 600 | {file = "lxml-4.9.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:0a3d3487f07c1d7f150894c238299934a2a074ef590b583103a45002035be120"}, 601 | {file = "lxml-4.9.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:9e28c51fa0ce5674be9f560c6761c1b441631901993f76700b1b30ca6c8378d6"}, 602 | {file = "lxml-4.9.3-cp311-cp311-win32.whl", hash = "sha256:0bfd0767c5c1de2551a120673b72e5d4b628737cb05414f03c3277bf9bed3305"}, 603 | {file = "lxml-4.9.3-cp311-cp311-win_amd64.whl", hash = "sha256:25f32acefac14ef7bd53e4218fe93b804ef6f6b92ffdb4322bb6d49d94cad2bc"}, 604 | {file = "lxml-4.9.3-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:d3ff32724f98fbbbfa9f49d82852b159e9784d6094983d9a8b7f2ddaebb063d4"}, 605 | {file = "lxml-4.9.3-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:48d6ed886b343d11493129e019da91d4039826794a3e3027321c56d9e71505be"}, 606 | {file = "lxml-4.9.3-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:9a92d3faef50658dd2c5470af249985782bf754c4e18e15afb67d3ab06233f13"}, 607 | {file = "lxml-4.9.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:b4e4bc18382088514ebde9328da057775055940a1f2e18f6ad2d78aa0f3ec5b9"}, 608 | {file = "lxml-4.9.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:fc9b106a1bf918db68619fdcd6d5ad4f972fdd19c01d19bdb6bf63f3589a9ec5"}, 609 | {file = "lxml-4.9.3-cp312-cp312-win_amd64.whl", hash = "sha256:d37017287a7adb6ab77e1c5bee9bcf9660f90ff445042b790402a654d2ad81d8"}, 610 | {file = "lxml-4.9.3-cp35-cp35m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:56dc1f1ebccc656d1b3ed288f11e27172a01503fc016bcabdcbc0978b19352b7"}, 611 | {file = "lxml-4.9.3-cp35-cp35m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:578695735c5a3f51569810dfebd05dd6f888147a34f0f98d4bb27e92b76e05c2"}, 612 | {file = "lxml-4.9.3-cp35-cp35m-win32.whl", hash = "sha256:704f61ba8c1283c71b16135caf697557f5ecf3e74d9e453233e4771d68a1f42d"}, 613 | {file = "lxml-4.9.3-cp35-cp35m-win_amd64.whl", hash = "sha256:c41bfca0bd3532d53d16fd34d20806d5c2b1ace22a2f2e4c0008570bf2c58833"}, 614 | {file = "lxml-4.9.3-cp36-cp36m-macosx_11_0_x86_64.whl", hash = "sha256:64f479d719dc9f4c813ad9bb6b28f8390360660b73b2e4beb4cb0ae7104f1c12"}, 615 | {file = "lxml-4.9.3-cp36-cp36m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:dd708cf4ee4408cf46a48b108fb9427bfa00b9b85812a9262b5c668af2533ea5"}, 616 | {file = "lxml-4.9.3-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5c31c7462abdf8f2ac0577d9f05279727e698f97ecbb02f17939ea99ae8daa98"}, 617 | {file = "lxml-4.9.3-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:e3cd95e10c2610c360154afdc2f1480aea394f4a4f1ea0a5eacce49640c9b190"}, 618 | {file = "lxml-4.9.3-cp36-cp36m-manylinux_2_28_x86_64.whl", hash = "sha256:4930be26af26ac545c3dffb662521d4e6268352866956672231887d18f0eaab2"}, 619 | {file = "lxml-4.9.3-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:4aec80cde9197340bc353d2768e2a75f5f60bacda2bab72ab1dc499589b3878c"}, 620 | {file = "lxml-4.9.3-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:14e019fd83b831b2e61baed40cab76222139926b1fb5ed0e79225bc0cae14584"}, 621 | {file = "lxml-4.9.3-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:0c0850c8b02c298d3c7006b23e98249515ac57430e16a166873fc47a5d549287"}, 622 | {file = "lxml-4.9.3-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:aca086dc5f9ef98c512bac8efea4483eb84abbf926eaeedf7b91479feb092458"}, 623 | {file = "lxml-4.9.3-cp36-cp36m-win32.whl", hash = "sha256:50baa9c1c47efcaef189f31e3d00d697c6d4afda5c3cde0302d063492ff9b477"}, 624 | {file = "lxml-4.9.3-cp36-cp36m-win_amd64.whl", hash = "sha256:bef4e656f7d98aaa3486d2627e7d2df1157d7e88e7efd43a65aa5dd4714916cf"}, 625 | {file = "lxml-4.9.3-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:46f409a2d60f634fe550f7133ed30ad5321ae2e6630f13657fb9479506b00601"}, 626 | {file = "lxml-4.9.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:4c28a9144688aef80d6ea666c809b4b0e50010a2aca784c97f5e6bf143d9f129"}, 627 | {file = "lxml-4.9.3-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:141f1d1a9b663c679dc524af3ea1773e618907e96075262726c7612c02b149a4"}, 628 | {file = "lxml-4.9.3-cp37-cp37m-manylinux_2_28_x86_64.whl", hash = "sha256:53ace1c1fd5a74ef662f844a0413446c0629d151055340e9893da958a374f70d"}, 629 | {file = "lxml-4.9.3-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:17a753023436a18e27dd7769e798ce302963c236bc4114ceee5b25c18c52c693"}, 630 | {file = "lxml-4.9.3-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:7d298a1bd60c067ea75d9f684f5f3992c9d6766fadbc0bcedd39750bf344c2f4"}, 631 | {file = "lxml-4.9.3-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:081d32421db5df44c41b7f08a334a090a545c54ba977e47fd7cc2deece78809a"}, 632 | {file = "lxml-4.9.3-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:23eed6d7b1a3336ad92d8e39d4bfe09073c31bfe502f20ca5116b2a334f8ec02"}, 633 | {file = "lxml-4.9.3-cp37-cp37m-win32.whl", hash = "sha256:1509dd12b773c02acd154582088820893109f6ca27ef7291b003d0e81666109f"}, 634 | {file = "lxml-4.9.3-cp37-cp37m-win_amd64.whl", hash = "sha256:120fa9349a24c7043854c53cae8cec227e1f79195a7493e09e0c12e29f918e52"}, 635 | {file = "lxml-4.9.3-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:4d2d1edbca80b510443f51afd8496be95529db04a509bc8faee49c7b0fb6d2cc"}, 636 | {file = "lxml-4.9.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:8d7e43bd40f65f7d97ad8ef5c9b1778943d02f04febef12def25f7583d19baac"}, 637 | {file = "lxml-4.9.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:71d66ee82e7417828af6ecd7db817913cb0cf9d4e61aa0ac1fde0583d84358db"}, 638 | {file = "lxml-4.9.3-cp38-cp38-manylinux_2_28_x86_64.whl", hash = "sha256:6fc3c450eaa0b56f815c7b62f2b7fba7266c4779adcf1cece9e6deb1de7305ce"}, 639 | {file = "lxml-4.9.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:65299ea57d82fb91c7f019300d24050c4ddeb7c5a190e076b5f48a2b43d19c42"}, 640 | {file = "lxml-4.9.3-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:eadfbbbfb41b44034a4c757fd5d70baccd43296fb894dba0295606a7cf3124aa"}, 641 | {file = "lxml-4.9.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:3e9bdd30efde2b9ccfa9cb5768ba04fe71b018a25ea093379c857c9dad262c40"}, 642 | {file = "lxml-4.9.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:fcdd00edfd0a3001e0181eab3e63bd5c74ad3e67152c84f93f13769a40e073a7"}, 643 | {file = "lxml-4.9.3-cp38-cp38-win32.whl", hash = "sha256:57aba1bbdf450b726d58b2aea5fe47c7875f5afb2c4a23784ed78f19a0462574"}, 644 | {file = "lxml-4.9.3-cp38-cp38-win_amd64.whl", hash = "sha256:92af161ecbdb2883c4593d5ed4815ea71b31fafd7fd05789b23100d081ecac96"}, 645 | {file = "lxml-4.9.3-cp39-cp39-macosx_11_0_x86_64.whl", hash = "sha256:9bb6ad405121241e99a86efff22d3ef469024ce22875a7ae045896ad23ba2340"}, 646 | {file = "lxml-4.9.3-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:8ed74706b26ad100433da4b9d807eae371efaa266ffc3e9191ea436087a9d6a7"}, 647 | {file = "lxml-4.9.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:fbf521479bcac1e25a663df882c46a641a9bff6b56dc8b0fafaebd2f66fb231b"}, 648 | {file = "lxml-4.9.3-cp39-cp39-manylinux_2_28_aarch64.whl", hash = "sha256:303bf1edce6ced16bf67a18a1cf8339d0db79577eec5d9a6d4a80f0fb10aa2da"}, 649 | {file = "lxml-4.9.3-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:5515edd2a6d1a5a70bfcdee23b42ec33425e405c5b351478ab7dc9347228f96e"}, 650 | {file = "lxml-4.9.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:690dafd0b187ed38583a648076865d8c229661ed20e48f2335d68e2cf7dc829d"}, 651 | {file = "lxml-4.9.3-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:b6420a005548ad52154c8ceab4a1290ff78d757f9e5cbc68f8c77089acd3c432"}, 652 | {file = "lxml-4.9.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:bb3bb49c7a6ad9d981d734ef7c7193bc349ac338776a0360cc671eaee89bcf69"}, 653 | {file = "lxml-4.9.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:d27be7405547d1f958b60837dc4c1007da90b8b23f54ba1f8b728c78fdb19d50"}, 654 | {file = "lxml-4.9.3-cp39-cp39-win32.whl", hash = "sha256:8df133a2ea5e74eef5e8fc6f19b9e085f758768a16e9877a60aec455ed2609b2"}, 655 | {file = "lxml-4.9.3-cp39-cp39-win_amd64.whl", hash = "sha256:4dd9a263e845a72eacb60d12401e37c616438ea2e5442885f65082c276dfb2b2"}, 656 | {file = "lxml-4.9.3-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:6689a3d7fd13dc687e9102a27e98ef33730ac4fe37795d5036d18b4d527abd35"}, 657 | {file = "lxml-4.9.3-pp37-pypy37_pp73-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:f6bdac493b949141b733c5345b6ba8f87a226029cbabc7e9e121a413e49441e0"}, 658 | {file = "lxml-4.9.3-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:05186a0f1346ae12553d66df1cfce6f251589fea3ad3da4f3ef4e34b2d58c6a3"}, 659 | {file = "lxml-4.9.3-pp37-pypy37_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:c2006f5c8d28dee289f7020f721354362fa304acbaaf9745751ac4006650254b"}, 660 | {file = "lxml-4.9.3-pp38-pypy38_pp73-macosx_11_0_x86_64.whl", hash = "sha256:5c245b783db29c4e4fbbbfc9c5a78be496c9fea25517f90606aa1f6b2b3d5f7b"}, 661 | {file = "lxml-4.9.3-pp38-pypy38_pp73-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:4fb960a632a49f2f089d522f70496640fdf1218f1243889da3822e0a9f5f3ba7"}, 662 | {file = "lxml-4.9.3-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:50670615eaf97227d5dc60de2dc99fb134a7130d310d783314e7724bf163f75d"}, 663 | {file = "lxml-4.9.3-pp38-pypy38_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:9719fe17307a9e814580af1f5c6e05ca593b12fb7e44fe62450a5384dbf61b4b"}, 664 | {file = "lxml-4.9.3-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:3331bece23c9ee066e0fb3f96c61322b9e0f54d775fccefff4c38ca488de283a"}, 665 | {file = "lxml-4.9.3-pp39-pypy39_pp73-macosx_11_0_x86_64.whl", hash = "sha256:ed667f49b11360951e201453fc3967344d0d0263aa415e1619e85ae7fd17b4e0"}, 666 | {file = "lxml-4.9.3-pp39-pypy39_pp73-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:8b77946fd508cbf0fccd8e400a7f71d4ac0e1595812e66025bac475a8e811694"}, 667 | {file = "lxml-4.9.3-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:e4da8ca0c0c0aea88fd46be8e44bd49716772358d648cce45fe387f7b92374a7"}, 668 | {file = "lxml-4.9.3-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:fe4bda6bd4340caa6e5cf95e73f8fea5c4bfc55763dd42f1b50a94c1b4a2fbd4"}, 669 | {file = "lxml-4.9.3-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:f3df3db1d336b9356dd3112eae5f5c2b8b377f3bc826848567f10bfddfee77e9"}, 670 | {file = "lxml-4.9.3.tar.gz", hash = "sha256:48628bd53a426c9eb9bc066a923acaa0878d1e86129fd5359aee99285f4eed9c"}, 671 | ] 672 | 673 | [package.extras] 674 | cssselect = ["cssselect (>=0.7)"] 675 | html5 = ["html5lib"] 676 | htmlsoup = ["BeautifulSoup4"] 677 | source = ["Cython (>=0.29.35)"] 678 | 679 | [[package]] 680 | name = "mccabe" 681 | version = "0.7.0" 682 | description = "McCabe checker, plugin for flake8" 683 | optional = false 684 | python-versions = ">=3.6" 685 | files = [ 686 | {file = "mccabe-0.7.0-py2.py3-none-any.whl", hash = "sha256:6c2d30ab6be0e4a46919781807b4f0d834ebdd6c6e3dca0bda5a15f863427b6e"}, 687 | {file = "mccabe-0.7.0.tar.gz", hash = "sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325"}, 688 | ] 689 | 690 | [[package]] 691 | name = "msgpack" 692 | version = "1.0.4" 693 | description = "MessagePack serializer" 694 | optional = false 695 | python-versions = "*" 696 | files = [ 697 | {file = "msgpack-1.0.4-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:4ab251d229d10498e9a2f3b1e68ef64cb393394ec477e3370c457f9430ce9250"}, 698 | {file = "msgpack-1.0.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:112b0f93202d7c0fef0b7810d465fde23c746a2d482e1e2de2aafd2ce1492c88"}, 699 | {file = "msgpack-1.0.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:002b5c72b6cd9b4bafd790f364b8480e859b4712e91f43014fe01e4f957b8467"}, 700 | {file = "msgpack-1.0.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:35bc0faa494b0f1d851fd29129b2575b2e26d41d177caacd4206d81502d4c6a6"}, 701 | {file = "msgpack-1.0.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4733359808c56d5d7756628736061c432ded018e7a1dff2d35a02439043321aa"}, 702 | {file = "msgpack-1.0.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eb514ad14edf07a1dbe63761fd30f89ae79b42625731e1ccf5e1f1092950eaa6"}, 703 | {file = "msgpack-1.0.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:c23080fdeec4716aede32b4e0ef7e213c7b1093eede9ee010949f2a418ced6ba"}, 704 | {file = "msgpack-1.0.4-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:49565b0e3d7896d9ea71d9095df15b7f75a035c49be733051c34762ca95bbf7e"}, 705 | {file = "msgpack-1.0.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:aca0f1644d6b5a73eb3e74d4d64d5d8c6c3d577e753a04c9e9c87d07692c58db"}, 706 | {file = "msgpack-1.0.4-cp310-cp310-win32.whl", hash = "sha256:0dfe3947db5fb9ce52aaea6ca28112a170db9eae75adf9339a1aec434dc954ef"}, 707 | {file = "msgpack-1.0.4-cp310-cp310-win_amd64.whl", hash = "sha256:4dea20515f660aa6b7e964433b1808d098dcfcabbebeaaad240d11f909298075"}, 708 | {file = "msgpack-1.0.4-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:e83f80a7fec1a62cf4e6c9a660e39c7f878f603737a0cdac8c13131d11d97f52"}, 709 | {file = "msgpack-1.0.4-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3c11a48cf5e59026ad7cb0dc29e29a01b5a66a3e333dc11c04f7e991fc5510a9"}, 710 | {file = "msgpack-1.0.4-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1276e8f34e139aeff1c77a3cefb295598b504ac5314d32c8c3d54d24fadb94c9"}, 711 | {file = "msgpack-1.0.4-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6c9566f2c39ccced0a38d37c26cc3570983b97833c365a6044edef3574a00c08"}, 712 | {file = "msgpack-1.0.4-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:fcb8a47f43acc113e24e910399376f7277cf8508b27e5b88499f053de6b115a8"}, 713 | {file = "msgpack-1.0.4-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:76ee788122de3a68a02ed6f3a16bbcd97bc7c2e39bd4d94be2f1821e7c4a64e6"}, 714 | {file = "msgpack-1.0.4-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:0a68d3ac0104e2d3510de90a1091720157c319ceeb90d74f7b5295a6bee51bae"}, 715 | {file = "msgpack-1.0.4-cp36-cp36m-win32.whl", hash = "sha256:85f279d88d8e833ec015650fd15ae5eddce0791e1e8a59165318f371158efec6"}, 716 | {file = "msgpack-1.0.4-cp36-cp36m-win_amd64.whl", hash = "sha256:c1683841cd4fa45ac427c18854c3ec3cd9b681694caf5bff04edb9387602d661"}, 717 | {file = "msgpack-1.0.4-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a75dfb03f8b06f4ab093dafe3ddcc2d633259e6c3f74bb1b01996f5d8aa5868c"}, 718 | {file = "msgpack-1.0.4-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9667bdfdf523c40d2511f0e98a6c9d3603be6b371ae9a238b7ef2dc4e7a427b0"}, 719 | {file = "msgpack-1.0.4-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:11184bc7e56fd74c00ead4f9cc9a3091d62ecb96e97653add7a879a14b003227"}, 720 | {file = "msgpack-1.0.4-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ac5bd7901487c4a1dd51a8c58f2632b15d838d07ceedaa5e4c080f7190925bff"}, 721 | {file = "msgpack-1.0.4-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:1e91d641d2bfe91ba4c52039adc5bccf27c335356055825c7f88742c8bb900dd"}, 722 | {file = "msgpack-1.0.4-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:2a2df1b55a78eb5f5b7d2a4bb221cd8363913830145fad05374a80bf0877cb1e"}, 723 | {file = "msgpack-1.0.4-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:545e3cf0cf74f3e48b470f68ed19551ae6f9722814ea969305794645da091236"}, 724 | {file = "msgpack-1.0.4-cp37-cp37m-win32.whl", hash = "sha256:2cc5ca2712ac0003bcb625c96368fd08a0f86bbc1a5578802512d87bc592fe44"}, 725 | {file = "msgpack-1.0.4-cp37-cp37m-win_amd64.whl", hash = "sha256:eba96145051ccec0ec86611fe9cf693ce55f2a3ce89c06ed307de0e085730ec1"}, 726 | {file = "msgpack-1.0.4-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:7760f85956c415578c17edb39eed99f9181a48375b0d4a94076d84148cf67b2d"}, 727 | {file = "msgpack-1.0.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:449e57cc1ff18d3b444eb554e44613cffcccb32805d16726a5494038c3b93dab"}, 728 | {file = "msgpack-1.0.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:d603de2b8d2ea3f3bcb2efe286849aa7a81531abc52d8454da12f46235092bcb"}, 729 | {file = "msgpack-1.0.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:48f5d88c99f64c456413d74a975bd605a9b0526293218a3b77220a2c15458ba9"}, 730 | {file = "msgpack-1.0.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6916c78f33602ecf0509cc40379271ba0f9ab572b066bd4bdafd7434dee4bc6e"}, 731 | {file = "msgpack-1.0.4-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:81fc7ba725464651190b196f3cd848e8553d4d510114a954681fd0b9c479d7e1"}, 732 | {file = "msgpack-1.0.4-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:d5b5b962221fa2c5d3a7f8133f9abffc114fe218eb4365e40f17732ade576c8e"}, 733 | {file = "msgpack-1.0.4-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:77ccd2af37f3db0ea59fb280fa2165bf1b096510ba9fe0cc2bf8fa92a22fdb43"}, 734 | {file = "msgpack-1.0.4-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:b17be2478b622939e39b816e0aa8242611cc8d3583d1cd8ec31b249f04623243"}, 735 | {file = "msgpack-1.0.4-cp38-cp38-win32.whl", hash = "sha256:2bb8cdf50dd623392fa75525cce44a65a12a00c98e1e37bf0fb08ddce2ff60d2"}, 736 | {file = "msgpack-1.0.4-cp38-cp38-win_amd64.whl", hash = "sha256:26b8feaca40a90cbe031b03d82b2898bf560027160d3eae1423f4a67654ec5d6"}, 737 | {file = "msgpack-1.0.4-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:462497af5fd4e0edbb1559c352ad84f6c577ffbbb708566a0abaaa84acd9f3ae"}, 738 | {file = "msgpack-1.0.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:2999623886c5c02deefe156e8f869c3b0aaeba14bfc50aa2486a0415178fce55"}, 739 | {file = "msgpack-1.0.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:f0029245c51fd9473dc1aede1160b0a29f4a912e6b1dd353fa6d317085b219da"}, 740 | {file = "msgpack-1.0.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ed6f7b854a823ea44cf94919ba3f727e230da29feb4a99711433f25800cf747f"}, 741 | {file = "msgpack-1.0.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0df96d6eaf45ceca04b3f3b4b111b86b33785683d682c655063ef8057d61fd92"}, 742 | {file = "msgpack-1.0.4-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6a4192b1ab40f8dca3f2877b70e63799d95c62c068c84dc028b40a6cb03ccd0f"}, 743 | {file = "msgpack-1.0.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:0e3590f9fb9f7fbc36df366267870e77269c03172d086fa76bb4eba8b2b46624"}, 744 | {file = "msgpack-1.0.4-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:1576bd97527a93c44fa856770197dec00d223b0b9f36ef03f65bac60197cedf8"}, 745 | {file = "msgpack-1.0.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:63e29d6e8c9ca22b21846234913c3466b7e4ee6e422f205a2988083de3b08cae"}, 746 | {file = "msgpack-1.0.4-cp39-cp39-win32.whl", hash = "sha256:fb62ea4b62bfcb0b380d5680f9a4b3f9a2d166d9394e9bbd9666c0ee09a3645c"}, 747 | {file = "msgpack-1.0.4-cp39-cp39-win_amd64.whl", hash = "sha256:4d5834a2a48965a349da1c5a79760d94a1a0172fbb5ab6b5b33cbf8447e109ce"}, 748 | {file = "msgpack-1.0.4.tar.gz", hash = "sha256:f5d869c18f030202eb412f08b28d2afeea553d6613aee89e200d7aca7ef01f5f"}, 749 | ] 750 | 751 | [[package]] 752 | name = "mypy" 753 | version = "1.0.1" 754 | description = "Optional static typing for Python" 755 | optional = false 756 | python-versions = ">=3.7" 757 | files = [ 758 | {file = "mypy-1.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:71a808334d3f41ef011faa5a5cd8153606df5fc0b56de5b2e89566c8093a0c9a"}, 759 | {file = "mypy-1.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:920169f0184215eef19294fa86ea49ffd4635dedfdea2b57e45cb4ee85d5ccaf"}, 760 | {file = "mypy-1.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:27a0f74a298769d9fdc8498fcb4f2beb86f0564bcdb1a37b58cbbe78e55cf8c0"}, 761 | {file = "mypy-1.0.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:65b122a993d9c81ea0bfde7689b3365318a88bde952e4dfa1b3a8b4ac05d168b"}, 762 | {file = "mypy-1.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:5deb252fd42a77add936b463033a59b8e48eb2eaec2976d76b6878d031933fe4"}, 763 | {file = "mypy-1.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:2013226d17f20468f34feddd6aae4635a55f79626549099354ce641bc7d40262"}, 764 | {file = "mypy-1.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:48525aec92b47baed9b3380371ab8ab6e63a5aab317347dfe9e55e02aaad22e8"}, 765 | {file = "mypy-1.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c96b8a0c019fe29040d520d9257d8c8f122a7343a8307bf8d6d4a43f5c5bfcc8"}, 766 | {file = "mypy-1.0.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:448de661536d270ce04f2d7dddaa49b2fdba6e3bd8a83212164d4174ff43aa65"}, 767 | {file = "mypy-1.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:d42a98e76070a365a1d1c220fcac8aa4ada12ae0db679cb4d910fabefc88b994"}, 768 | {file = "mypy-1.0.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:e64f48c6176e243ad015e995de05af7f22bbe370dbb5b32bd6988438ec873919"}, 769 | {file = "mypy-1.0.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5fdd63e4f50e3538617887e9aee91855368d9fc1dea30da743837b0df7373bc4"}, 770 | {file = "mypy-1.0.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:dbeb24514c4acbc78d205f85dd0e800f34062efcc1f4a4857c57e4b4b8712bff"}, 771 | {file = "mypy-1.0.1-cp37-cp37m-win_amd64.whl", hash = "sha256:a2948c40a7dd46c1c33765718936669dc1f628f134013b02ff5ac6c7ef6942bf"}, 772 | {file = "mypy-1.0.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:5bc8d6bd3b274dd3846597855d96d38d947aedba18776aa998a8d46fabdaed76"}, 773 | {file = "mypy-1.0.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:17455cda53eeee0a4adb6371a21dd3dbf465897de82843751cf822605d152c8c"}, 774 | {file = "mypy-1.0.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e831662208055b006eef68392a768ff83596035ffd6d846786578ba1714ba8f6"}, 775 | {file = "mypy-1.0.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:e60d0b09f62ae97a94605c3f73fd952395286cf3e3b9e7b97f60b01ddfbbda88"}, 776 | {file = "mypy-1.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:0af4f0e20706aadf4e6f8f8dc5ab739089146b83fd53cb4a7e0e850ef3de0bb6"}, 777 | {file = "mypy-1.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:24189f23dc66f83b839bd1cce2dfc356020dfc9a8bae03978477b15be61b062e"}, 778 | {file = "mypy-1.0.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:93a85495fb13dc484251b4c1fd7a5ac370cd0d812bbfc3b39c1bafefe95275d5"}, 779 | {file = "mypy-1.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5f546ac34093c6ce33f6278f7c88f0f147a4849386d3bf3ae193702f4fe31407"}, 780 | {file = "mypy-1.0.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:c6c2ccb7af7154673c591189c3687b013122c5a891bb5651eca3db8e6c6c55bd"}, 781 | {file = "mypy-1.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:15b5a824b58c7c822c51bc66308e759243c32631896743f030daf449fe3677f3"}, 782 | {file = "mypy-1.0.1-py3-none-any.whl", hash = "sha256:eda5c8b9949ed411ff752b9a01adda31afe7eae1e53e946dbdf9db23865e66c4"}, 783 | {file = "mypy-1.0.1.tar.gz", hash = "sha256:28cea5a6392bb43d266782983b5a4216c25544cd7d80be681a155ddcdafd152d"}, 784 | ] 785 | 786 | [package.dependencies] 787 | mypy-extensions = ">=0.4.3" 788 | tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} 789 | typing-extensions = ">=3.10" 790 | 791 | [package.extras] 792 | dmypy = ["psutil (>=4.0)"] 793 | install-types = ["pip"] 794 | python2 = ["typed-ast (>=1.4.0,<2)"] 795 | reports = ["lxml"] 796 | 797 | [[package]] 798 | name = "mypy-extensions" 799 | version = "1.0.0" 800 | description = "Type system extensions for programs checked with the mypy type checker." 801 | optional = false 802 | python-versions = ">=3.5" 803 | files = [ 804 | {file = "mypy_extensions-1.0.0-py3-none-any.whl", hash = "sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d"}, 805 | {file = "mypy_extensions-1.0.0.tar.gz", hash = "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782"}, 806 | ] 807 | 808 | [[package]] 809 | name = "nodeenv" 810 | version = "1.7.0" 811 | description = "Node.js virtual environment builder" 812 | optional = false 813 | python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*" 814 | files = [ 815 | {file = "nodeenv-1.7.0-py2.py3-none-any.whl", hash = "sha256:27083a7b96a25f2f5e1d8cb4b6317ee8aeda3bdd121394e5ac54e498028a042e"}, 816 | {file = "nodeenv-1.7.0.tar.gz", hash = "sha256:e0e7f7dfb85fc5394c6fe1e8fa98131a2473e04311a45afb6508f7cf1836fa2b"}, 817 | ] 818 | 819 | [package.dependencies] 820 | setuptools = "*" 821 | 822 | [[package]] 823 | name = "packaging" 824 | version = "21.3" 825 | description = "Core utilities for Python packages" 826 | optional = false 827 | python-versions = ">=3.6" 828 | files = [ 829 | {file = "packaging-21.3-py3-none-any.whl", hash = "sha256:ef103e05f519cdc783ae24ea4e2e0f508a9c99b2d4969652eed6a2e1ea5bd522"}, 830 | {file = "packaging-21.3.tar.gz", hash = "sha256:dd47c42927d89ab911e606518907cc2d3a1f38bbd026385970643f9c5b8ecfeb"}, 831 | ] 832 | 833 | [package.dependencies] 834 | pyparsing = ">=2.0.2,<3.0.5 || >3.0.5" 835 | 836 | [[package]] 837 | name = "pastel" 838 | version = "0.2.1" 839 | description = "Bring colors to your terminal." 840 | optional = false 841 | python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" 842 | files = [ 843 | {file = "pastel-0.2.1-py2.py3-none-any.whl", hash = "sha256:4349225fcdf6c2bb34d483e523475de5bb04a5c10ef711263452cb37d7dd4364"}, 844 | {file = "pastel-0.2.1.tar.gz", hash = "sha256:e6581ac04e973cac858828c6202c1e1e81fee1dc7de7683f3e1ffe0bfd8a573d"}, 845 | ] 846 | 847 | [[package]] 848 | name = "pathspec" 849 | version = "0.10.1" 850 | description = "Utility library for gitignore style pattern matching of file paths." 851 | optional = false 852 | python-versions = ">=3.7" 853 | files = [ 854 | {file = "pathspec-0.10.1-py3-none-any.whl", hash = "sha256:46846318467efc4556ccfd27816e004270a9eeeeb4d062ce5e6fc7a87c573f93"}, 855 | {file = "pathspec-0.10.1.tar.gz", hash = "sha256:7ace6161b621d31e7902eb6b5ae148d12cfd23f4a249b9ffb6b9fee12084323d"}, 856 | ] 857 | 858 | [[package]] 859 | name = "platformdirs" 860 | version = "2.5.2" 861 | description = "A small Python module for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." 862 | optional = false 863 | python-versions = ">=3.7" 864 | files = [ 865 | {file = "platformdirs-2.5.2-py3-none-any.whl", hash = "sha256:027d8e83a2d7de06bbac4e5ef7e023c02b863d7ea5d079477e722bb41ab25788"}, 866 | {file = "platformdirs-2.5.2.tar.gz", hash = "sha256:58c8abb07dcb441e6ee4b11d8df0ac856038f944ab98b7be6b27b2a3c7feef19"}, 867 | ] 868 | 869 | [package.extras] 870 | docs = ["furo (>=2021.7.5b38)", "proselint (>=0.10.2)", "sphinx (>=4)", "sphinx-autodoc-typehints (>=1.12)"] 871 | test = ["appdirs (==1.4.4)", "pytest (>=6)", "pytest-cov (>=2.7)", "pytest-mock (>=3.6)"] 872 | 873 | [[package]] 874 | name = "pluggy" 875 | version = "1.0.0" 876 | description = "plugin and hook calling mechanisms for python" 877 | optional = false 878 | python-versions = ">=3.6" 879 | files = [ 880 | {file = "pluggy-1.0.0-py2.py3-none-any.whl", hash = "sha256:74134bbf457f031a36d68416e1509f34bd5ccc019f0bcc952c7b909d06b37bd3"}, 881 | {file = "pluggy-1.0.0.tar.gz", hash = "sha256:4224373bacce55f955a878bf9cfa763c1e360858e330072059e10bad68531159"}, 882 | ] 883 | 884 | [package.extras] 885 | dev = ["pre-commit", "tox"] 886 | testing = ["pytest", "pytest-benchmark"] 887 | 888 | [[package]] 889 | name = "poethepoet" 890 | version = "0.15.0" 891 | description = "A task runner that works well with poetry." 892 | optional = false 893 | python-versions = ">=3.7" 894 | files = [ 895 | {file = "poethepoet-0.15.0-py3-none-any.whl", hash = "sha256:8ca49d8a9928a3ce1753315d6df0866888557eccb0fe37a8c88fea47454cfe12"}, 896 | {file = "poethepoet-0.15.0.tar.gz", hash = "sha256:5843260c9074b6c42bf2e51f21107efe37e230cf75da3dd3f4b43904f365b26c"}, 897 | ] 898 | 899 | [package.dependencies] 900 | pastel = ">=0.2.1,<0.3.0" 901 | tomli = ">=1.2.2" 902 | 903 | [package.extras] 904 | poetry-plugin = ["poetry (>=1.0,<2.0)"] 905 | 906 | [[package]] 907 | name = "pre-commit" 908 | version = "2.20.0" 909 | description = "A framework for managing and maintaining multi-language pre-commit hooks." 910 | optional = false 911 | python-versions = ">=3.7" 912 | files = [ 913 | {file = "pre_commit-2.20.0-py2.py3-none-any.whl", hash = "sha256:51a5ba7c480ae8072ecdb6933df22d2f812dc897d5fe848778116129a681aac7"}, 914 | {file = "pre_commit-2.20.0.tar.gz", hash = "sha256:a978dac7bc9ec0bcee55c18a277d553b0f419d259dadb4b9418ff2d00eb43959"}, 915 | ] 916 | 917 | [package.dependencies] 918 | cfgv = ">=2.0.0" 919 | identify = ">=1.0.0" 920 | nodeenv = ">=0.11.1" 921 | pyyaml = ">=5.1" 922 | toml = "*" 923 | virtualenv = ">=20.0.8" 924 | 925 | [[package]] 926 | name = "py" 927 | version = "1.11.0" 928 | description = "library with cross-python path, ini-parsing, io, code, log facilities" 929 | optional = false 930 | python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" 931 | files = [ 932 | {file = "py-1.11.0-py2.py3-none-any.whl", hash = "sha256:607c53218732647dff4acdfcd50cb62615cedf612e72d1724fb1a0cc6405b378"}, 933 | {file = "py-1.11.0.tar.gz", hash = "sha256:51c75c4126074b472f746a24399ad32f6053d1b34b68d2fa41e558e6f4a98719"}, 934 | ] 935 | 936 | [[package]] 937 | name = "pydantic" 938 | version = "2.5.2" 939 | description = "Data validation using Python type hints" 940 | optional = false 941 | python-versions = ">=3.7" 942 | files = [ 943 | {file = "pydantic-2.5.2-py3-none-any.whl", hash = "sha256:80c50fb8e3dcecfddae1adbcc00ec5822918490c99ab31f6cf6140ca1c1429f0"}, 944 | {file = "pydantic-2.5.2.tar.gz", hash = "sha256:ff177ba64c6faf73d7afa2e8cad38fd456c0dbe01c9954e71038001cd15a6edd"}, 945 | ] 946 | 947 | [package.dependencies] 948 | annotated-types = ">=0.4.0" 949 | pydantic-core = "2.14.5" 950 | typing-extensions = ">=4.6.1" 951 | 952 | [package.extras] 953 | email = ["email-validator (>=2.0.0)"] 954 | 955 | [[package]] 956 | name = "pydantic-core" 957 | version = "2.14.5" 958 | description = "" 959 | optional = false 960 | python-versions = ">=3.7" 961 | files = [ 962 | {file = "pydantic_core-2.14.5-cp310-cp310-macosx_10_7_x86_64.whl", hash = "sha256:7e88f5696153dc516ba6e79f82cc4747e87027205f0e02390c21f7cb3bd8abfd"}, 963 | {file = "pydantic_core-2.14.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:4641e8ad4efb697f38a9b64ca0523b557c7931c5f84e0fd377a9a3b05121f0de"}, 964 | {file = "pydantic_core-2.14.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:774de879d212db5ce02dfbf5b0da9a0ea386aeba12b0b95674a4ce0593df3d07"}, 965 | {file = "pydantic_core-2.14.5-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ebb4e035e28f49b6f1a7032920bb9a0c064aedbbabe52c543343d39341a5b2a3"}, 966 | {file = "pydantic_core-2.14.5-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b53e9ad053cd064f7e473a5f29b37fc4cc9dc6d35f341e6afc0155ea257fc911"}, 967 | {file = "pydantic_core-2.14.5-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8aa1768c151cf562a9992462239dfc356b3d1037cc5a3ac829bb7f3bda7cc1f9"}, 968 | {file = "pydantic_core-2.14.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eac5c82fc632c599f4639a5886f96867ffced74458c7db61bc9a66ccb8ee3113"}, 969 | {file = "pydantic_core-2.14.5-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d2ae91f50ccc5810b2f1b6b858257c9ad2e08da70bf890dee02de1775a387c66"}, 970 | {file = "pydantic_core-2.14.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:6b9ff467ffbab9110e80e8c8de3bcfce8e8b0fd5661ac44a09ae5901668ba997"}, 971 | {file = "pydantic_core-2.14.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:61ea96a78378e3bd5a0be99b0e5ed00057b71f66115f5404d0dae4819f495093"}, 972 | {file = "pydantic_core-2.14.5-cp310-none-win32.whl", hash = "sha256:bb4c2eda937a5e74c38a41b33d8c77220380a388d689bcdb9b187cf6224c9720"}, 973 | {file = "pydantic_core-2.14.5-cp310-none-win_amd64.whl", hash = "sha256:b7851992faf25eac90bfcb7bfd19e1f5ffa00afd57daec8a0042e63c74a4551b"}, 974 | {file = "pydantic_core-2.14.5-cp311-cp311-macosx_10_7_x86_64.whl", hash = "sha256:4e40f2bd0d57dac3feb3a3aed50f17d83436c9e6b09b16af271b6230a2915459"}, 975 | {file = "pydantic_core-2.14.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ab1cdb0f14dc161ebc268c09db04d2c9e6f70027f3b42446fa11c153521c0e88"}, 976 | {file = "pydantic_core-2.14.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aae7ea3a1c5bb40c93cad361b3e869b180ac174656120c42b9fadebf685d121b"}, 977 | {file = "pydantic_core-2.14.5-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:60b7607753ba62cf0739177913b858140f11b8af72f22860c28eabb2f0a61937"}, 978 | {file = "pydantic_core-2.14.5-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2248485b0322c75aee7565d95ad0e16f1c67403a470d02f94da7344184be770f"}, 979 | {file = "pydantic_core-2.14.5-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:823fcc638f67035137a5cd3f1584a4542d35a951c3cc68c6ead1df7dac825c26"}, 980 | {file = "pydantic_core-2.14.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:96581cfefa9123accc465a5fd0cc833ac4d75d55cc30b633b402e00e7ced00a6"}, 981 | {file = "pydantic_core-2.14.5-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a33324437018bf6ba1bb0f921788788641439e0ed654b233285b9c69704c27b4"}, 982 | {file = "pydantic_core-2.14.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:9bd18fee0923ca10f9a3ff67d4851c9d3e22b7bc63d1eddc12f439f436f2aada"}, 983 | {file = "pydantic_core-2.14.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:853a2295c00f1d4429db4c0fb9475958543ee80cfd310814b5c0ef502de24dda"}, 984 | {file = "pydantic_core-2.14.5-cp311-none-win32.whl", hash = "sha256:cb774298da62aea5c80a89bd58c40205ab4c2abf4834453b5de207d59d2e1651"}, 985 | {file = "pydantic_core-2.14.5-cp311-none-win_amd64.whl", hash = "sha256:e87fc540c6cac7f29ede02e0f989d4233f88ad439c5cdee56f693cc9c1c78077"}, 986 | {file = "pydantic_core-2.14.5-cp311-none-win_arm64.whl", hash = "sha256:57d52fa717ff445cb0a5ab5237db502e6be50809b43a596fb569630c665abddf"}, 987 | {file = "pydantic_core-2.14.5-cp312-cp312-macosx_10_7_x86_64.whl", hash = "sha256:e60f112ac88db9261ad3a52032ea46388378034f3279c643499edb982536a093"}, 988 | {file = "pydantic_core-2.14.5-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6e227c40c02fd873c2a73a98c1280c10315cbebe26734c196ef4514776120aeb"}, 989 | {file = "pydantic_core-2.14.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f0cbc7fff06a90bbd875cc201f94ef0ee3929dfbd5c55a06674b60857b8b85ed"}, 990 | {file = "pydantic_core-2.14.5-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:103ef8d5b58596a731b690112819501ba1db7a36f4ee99f7892c40da02c3e189"}, 991 | {file = "pydantic_core-2.14.5-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c949f04ecad823f81b1ba94e7d189d9dfb81edbb94ed3f8acfce41e682e48cef"}, 992 | {file = "pydantic_core-2.14.5-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c1452a1acdf914d194159439eb21e56b89aa903f2e1c65c60b9d874f9b950e5d"}, 993 | {file = "pydantic_core-2.14.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cb4679d4c2b089e5ef89756bc73e1926745e995d76e11925e3e96a76d5fa51fc"}, 994 | {file = "pydantic_core-2.14.5-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:cf9d3fe53b1ee360e2421be95e62ca9b3296bf3f2fb2d3b83ca49ad3f925835e"}, 995 | {file = "pydantic_core-2.14.5-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:70f4b4851dbb500129681d04cc955be2a90b2248d69273a787dda120d5cf1f69"}, 996 | {file = "pydantic_core-2.14.5-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:59986de5710ad9613ff61dd9b02bdd2f615f1a7052304b79cc8fa2eb4e336d2d"}, 997 | {file = "pydantic_core-2.14.5-cp312-none-win32.whl", hash = "sha256:699156034181e2ce106c89ddb4b6504c30db8caa86e0c30de47b3e0654543260"}, 998 | {file = "pydantic_core-2.14.5-cp312-none-win_amd64.whl", hash = "sha256:5baab5455c7a538ac7e8bf1feec4278a66436197592a9bed538160a2e7d11e36"}, 999 | {file = "pydantic_core-2.14.5-cp312-none-win_arm64.whl", hash = "sha256:e47e9a08bcc04d20975b6434cc50bf82665fbc751bcce739d04a3120428f3e27"}, 1000 | {file = "pydantic_core-2.14.5-cp37-cp37m-macosx_10_7_x86_64.whl", hash = "sha256:af36f36538418f3806048f3b242a1777e2540ff9efaa667c27da63d2749dbce0"}, 1001 | {file = "pydantic_core-2.14.5-cp37-cp37m-macosx_11_0_arm64.whl", hash = "sha256:45e95333b8418ded64745f14574aa9bfc212cb4fbeed7a687b0c6e53b5e188cd"}, 1002 | {file = "pydantic_core-2.14.5-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4e47a76848f92529879ecfc417ff88a2806438f57be4a6a8bf2961e8f9ca9ec7"}, 1003 | {file = "pydantic_core-2.14.5-cp37-cp37m-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d81e6987b27bc7d101c8597e1cd2bcaa2fee5e8e0f356735c7ed34368c471550"}, 1004 | {file = "pydantic_core-2.14.5-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:34708cc82c330e303f4ce87758828ef6e457681b58ce0e921b6e97937dd1e2a3"}, 1005 | {file = "pydantic_core-2.14.5-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:652c1988019752138b974c28f43751528116bcceadad85f33a258869e641d753"}, 1006 | {file = "pydantic_core-2.14.5-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e4d090e73e0725b2904fdbdd8d73b8802ddd691ef9254577b708d413bf3006e"}, 1007 | {file = "pydantic_core-2.14.5-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:5c7d5b5005f177764e96bd584d7bf28d6e26e96f2a541fdddb934c486e36fd59"}, 1008 | {file = "pydantic_core-2.14.5-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:a71891847f0a73b1b9eb86d089baee301477abef45f7eaf303495cd1473613e4"}, 1009 | {file = "pydantic_core-2.14.5-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:a717aef6971208f0851a2420b075338e33083111d92041157bbe0e2713b37325"}, 1010 | {file = "pydantic_core-2.14.5-cp37-none-win32.whl", hash = "sha256:de790a3b5aa2124b8b78ae5faa033937a72da8efe74b9231698b5a1dd9be3405"}, 1011 | {file = "pydantic_core-2.14.5-cp37-none-win_amd64.whl", hash = "sha256:6c327e9cd849b564b234da821236e6bcbe4f359a42ee05050dc79d8ed2a91588"}, 1012 | {file = "pydantic_core-2.14.5-cp38-cp38-macosx_10_7_x86_64.whl", hash = "sha256:ef98ca7d5995a82f43ec0ab39c4caf6a9b994cb0b53648ff61716370eadc43cf"}, 1013 | {file = "pydantic_core-2.14.5-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:c6eae413494a1c3f89055da7a5515f32e05ebc1a234c27674a6956755fb2236f"}, 1014 | {file = "pydantic_core-2.14.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dcf4e6d85614f7a4956c2de5a56531f44efb973d2fe4a444d7251df5d5c4dcfd"}, 1015 | {file = "pydantic_core-2.14.5-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:6637560562134b0e17de333d18e69e312e0458ee4455bdad12c37100b7cad706"}, 1016 | {file = "pydantic_core-2.14.5-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:77fa384d8e118b3077cccfcaf91bf83c31fe4dc850b5e6ee3dc14dc3d61bdba1"}, 1017 | {file = "pydantic_core-2.14.5-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:16e29bad40bcf97aac682a58861249ca9dcc57c3f6be22f506501833ddb8939c"}, 1018 | {file = "pydantic_core-2.14.5-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:531f4b4252fac6ca476fbe0e6f60f16f5b65d3e6b583bc4d87645e4e5ddde331"}, 1019 | {file = "pydantic_core-2.14.5-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:074f3d86f081ce61414d2dc44901f4f83617329c6f3ab49d2bc6c96948b2c26b"}, 1020 | {file = "pydantic_core-2.14.5-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:c2adbe22ab4babbca99c75c5d07aaf74f43c3195384ec07ccbd2f9e3bddaecec"}, 1021 | {file = "pydantic_core-2.14.5-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:0f6116a558fd06d1b7c2902d1c4cf64a5bd49d67c3540e61eccca93f41418124"}, 1022 | {file = "pydantic_core-2.14.5-cp38-none-win32.whl", hash = "sha256:fe0a5a1025eb797752136ac8b4fa21aa891e3d74fd340f864ff982d649691867"}, 1023 | {file = "pydantic_core-2.14.5-cp38-none-win_amd64.whl", hash = "sha256:079206491c435b60778cf2b0ee5fd645e61ffd6e70c47806c9ed51fc75af078d"}, 1024 | {file = "pydantic_core-2.14.5-cp39-cp39-macosx_10_7_x86_64.whl", hash = "sha256:a6a16f4a527aae4f49c875da3cdc9508ac7eef26e7977952608610104244e1b7"}, 1025 | {file = "pydantic_core-2.14.5-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:abf058be9517dc877227ec3223f0300034bd0e9f53aebd63cf4456c8cb1e0863"}, 1026 | {file = "pydantic_core-2.14.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:49b08aae5013640a3bfa25a8eebbd95638ec3f4b2eaf6ed82cf0c7047133f03b"}, 1027 | {file = "pydantic_core-2.14.5-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:c2d97e906b4ff36eb464d52a3bc7d720bd6261f64bc4bcdbcd2c557c02081ed2"}, 1028 | {file = "pydantic_core-2.14.5-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3128e0bbc8c091ec4375a1828d6118bc20404883169ac95ffa8d983b293611e6"}, 1029 | {file = "pydantic_core-2.14.5-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:88e74ab0cdd84ad0614e2750f903bb0d610cc8af2cc17f72c28163acfcf372a4"}, 1030 | {file = "pydantic_core-2.14.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c339dabd8ee15f8259ee0f202679b6324926e5bc9e9a40bf981ce77c038553db"}, 1031 | {file = "pydantic_core-2.14.5-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:3387277f1bf659caf1724e1afe8ee7dbc9952a82d90f858ebb931880216ea955"}, 1032 | {file = "pydantic_core-2.14.5-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:ba6b6b3846cfc10fdb4c971980a954e49d447cd215ed5a77ec8190bc93dd7bc5"}, 1033 | {file = "pydantic_core-2.14.5-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:ca61d858e4107ce5e1330a74724fe757fc7135190eb5ce5c9d0191729f033209"}, 1034 | {file = "pydantic_core-2.14.5-cp39-none-win32.whl", hash = "sha256:ec1e72d6412f7126eb7b2e3bfca42b15e6e389e1bc88ea0069d0cc1742f477c6"}, 1035 | {file = "pydantic_core-2.14.5-cp39-none-win_amd64.whl", hash = "sha256:c0b97ec434041827935044bbbe52b03d6018c2897349670ff8fe11ed24d1d4ab"}, 1036 | {file = "pydantic_core-2.14.5-pp310-pypy310_pp73-macosx_10_7_x86_64.whl", hash = "sha256:79e0a2cdbdc7af3f4aee3210b1172ab53d7ddb6a2d8c24119b5706e622b346d0"}, 1037 | {file = "pydantic_core-2.14.5-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:678265f7b14e138d9a541ddabbe033012a2953315739f8cfa6d754cc8063e8ca"}, 1038 | {file = "pydantic_core-2.14.5-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:95b15e855ae44f0c6341ceb74df61b606e11f1087e87dcb7482377374aac6abe"}, 1039 | {file = "pydantic_core-2.14.5-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:09b0e985fbaf13e6b06a56d21694d12ebca6ce5414b9211edf6f17738d82b0f8"}, 1040 | {file = "pydantic_core-2.14.5-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:3ad873900297bb36e4b6b3f7029d88ff9829ecdc15d5cf20161775ce12306f8a"}, 1041 | {file = "pydantic_core-2.14.5-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:2d0ae0d8670164e10accbeb31d5ad45adb71292032d0fdb9079912907f0085f4"}, 1042 | {file = "pydantic_core-2.14.5-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:d37f8ec982ead9ba0a22a996129594938138a1503237b87318392a48882d50b7"}, 1043 | {file = "pydantic_core-2.14.5-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:35613015f0ba7e14c29ac6c2483a657ec740e5ac5758d993fdd5870b07a61d8b"}, 1044 | {file = "pydantic_core-2.14.5-pp37-pypy37_pp73-macosx_10_7_x86_64.whl", hash = "sha256:ab4ea451082e684198636565224bbb179575efc1658c48281b2c866bfd4ddf04"}, 1045 | {file = "pydantic_core-2.14.5-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4ce601907e99ea5b4adb807ded3570ea62186b17f88e271569144e8cca4409c7"}, 1046 | {file = "pydantic_core-2.14.5-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fb2ed8b3fe4bf4506d6dab3b93b83bbc22237e230cba03866d561c3577517d18"}, 1047 | {file = "pydantic_core-2.14.5-pp37-pypy37_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:70f947628e074bb2526ba1b151cee10e4c3b9670af4dbb4d73bc8a89445916b5"}, 1048 | {file = "pydantic_core-2.14.5-pp37-pypy37_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:4bc536201426451f06f044dfbf341c09f540b4ebdb9fd8d2c6164d733de5e634"}, 1049 | {file = "pydantic_core-2.14.5-pp37-pypy37_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:f4791cf0f8c3104ac668797d8c514afb3431bc3305f5638add0ba1a5a37e0d88"}, 1050 | {file = "pydantic_core-2.14.5-pp38-pypy38_pp73-macosx_10_7_x86_64.whl", hash = "sha256:038c9f763e650712b899f983076ce783175397c848da04985658e7628cbe873b"}, 1051 | {file = "pydantic_core-2.14.5-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:27548e16c79702f1e03f5628589c6057c9ae17c95b4c449de3c66b589ead0520"}, 1052 | {file = "pydantic_core-2.14.5-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c97bee68898f3f4344eb02fec316db93d9700fb1e6a5b760ffa20d71d9a46ce3"}, 1053 | {file = "pydantic_core-2.14.5-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b9b759b77f5337b4ea024f03abc6464c9f35d9718de01cfe6bae9f2e139c397e"}, 1054 | {file = "pydantic_core-2.14.5-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:439c9afe34638ace43a49bf72d201e0ffc1a800295bed8420c2a9ca8d5e3dbb3"}, 1055 | {file = "pydantic_core-2.14.5-pp38-pypy38_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:ba39688799094c75ea8a16a6b544eb57b5b0f3328697084f3f2790892510d144"}, 1056 | {file = "pydantic_core-2.14.5-pp38-pypy38_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:ccd4d5702bb90b84df13bd491be8d900b92016c5a455b7e14630ad7449eb03f8"}, 1057 | {file = "pydantic_core-2.14.5-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:81982d78a45d1e5396819bbb4ece1fadfe5f079335dd28c4ab3427cd95389944"}, 1058 | {file = "pydantic_core-2.14.5-pp39-pypy39_pp73-macosx_10_7_x86_64.whl", hash = "sha256:7f8210297b04e53bc3da35db08b7302a6a1f4889c79173af69b72ec9754796b8"}, 1059 | {file = "pydantic_core-2.14.5-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:8c8a8812fe6f43a3a5b054af6ac2d7b8605c7bcab2804a8a7d68b53f3cd86e00"}, 1060 | {file = "pydantic_core-2.14.5-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:206ed23aecd67c71daf5c02c3cd19c0501b01ef3cbf7782db9e4e051426b3d0d"}, 1061 | {file = "pydantic_core-2.14.5-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c2027d05c8aebe61d898d4cffd774840a9cb82ed356ba47a90d99ad768f39789"}, 1062 | {file = "pydantic_core-2.14.5-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:40180930807ce806aa71eda5a5a5447abb6b6a3c0b4b3b1b1962651906484d68"}, 1063 | {file = "pydantic_core-2.14.5-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:615a0a4bff11c45eb3c1996ceed5bdaa2f7b432425253a7c2eed33bb86d80abc"}, 1064 | {file = "pydantic_core-2.14.5-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:f5e412d717366e0677ef767eac93566582518fe8be923361a5c204c1a62eaafe"}, 1065 | {file = "pydantic_core-2.14.5-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:513b07e99c0a267b1d954243845d8a833758a6726a3b5d8948306e3fe14675e3"}, 1066 | {file = "pydantic_core-2.14.5.tar.gz", hash = "sha256:6d30226dfc816dd0fdf120cae611dd2215117e4f9b124af8c60ab9093b6e8e71"}, 1067 | ] 1068 | 1069 | [package.dependencies] 1070 | typing-extensions = ">=4.6.0,<4.7.0 || >4.7.0" 1071 | 1072 | [[package]] 1073 | name = "pydantic-settings" 1074 | version = "2.1.0" 1075 | description = "Settings management using Pydantic" 1076 | optional = false 1077 | python-versions = ">=3.8" 1078 | files = [ 1079 | {file = "pydantic_settings-2.1.0-py3-none-any.whl", hash = "sha256:7621c0cb5d90d1140d2f0ef557bdf03573aac7035948109adf2574770b77605a"}, 1080 | {file = "pydantic_settings-2.1.0.tar.gz", hash = "sha256:26b1492e0a24755626ac5e6d715e9077ab7ad4fb5f19a8b7ed7011d52f36141c"}, 1081 | ] 1082 | 1083 | [package.dependencies] 1084 | pydantic = ">=2.3.0" 1085 | python-dotenv = ">=0.21.0" 1086 | 1087 | [[package]] 1088 | name = "pydocstyle" 1089 | version = "6.1.1" 1090 | description = "Python docstring style checker" 1091 | optional = false 1092 | python-versions = ">=3.6" 1093 | files = [ 1094 | {file = "pydocstyle-6.1.1-py3-none-any.whl", hash = "sha256:6987826d6775056839940041beef5c08cc7e3d71d63149b48e36727f70144dc4"}, 1095 | {file = "pydocstyle-6.1.1.tar.gz", hash = "sha256:1d41b7c459ba0ee6c345f2eb9ae827cab14a7533a88c5c6f7e94923f72df92dc"}, 1096 | ] 1097 | 1098 | [package.dependencies] 1099 | snowballstemmer = "*" 1100 | toml = {version = "*", optional = true, markers = "extra == \"toml\""} 1101 | 1102 | [package.extras] 1103 | toml = ["toml"] 1104 | 1105 | [[package]] 1106 | name = "Pygments" 1107 | version = "2.13.0" 1108 | description = "Pygments is a syntax highlighting package written in Python." 1109 | optional = false 1110 | python-versions = ">=3.6" 1111 | files = [ 1112 | {file = "Pygments-2.13.0-py3-none-any.whl", hash = "sha256:f643f331ab57ba3c9d89212ee4a2dabc6e94f117cf4eefde99a0574720d14c42"}, 1113 | {file = "Pygments-2.13.0.tar.gz", hash = "sha256:56a8508ae95f98e2b9bdf93a6be5ae3f7d8af858b43e02c5a2ff083726be40c1"}, 1114 | ] 1115 | 1116 | [package.extras] 1117 | plugins = ["importlib-metadata"] 1118 | 1119 | [[package]] 1120 | name = "pylint" 1121 | version = "2.13.9" 1122 | description = "python code static checker" 1123 | optional = false 1124 | python-versions = ">=3.6.2" 1125 | files = [ 1126 | {file = "pylint-2.13.9-py3-none-any.whl", hash = "sha256:705c620d388035bdd9ff8b44c5bcdd235bfb49d276d488dd2c8ff1736aa42526"}, 1127 | {file = "pylint-2.13.9.tar.gz", hash = "sha256:095567c96e19e6f57b5b907e67d265ff535e588fe26b12b5ebe1fc5645b2c731"}, 1128 | ] 1129 | 1130 | [package.dependencies] 1131 | astroid = ">=2.11.5,<=2.12.0-dev0" 1132 | colorama = {version = "*", markers = "sys_platform == \"win32\""} 1133 | dill = ">=0.2" 1134 | isort = ">=4.2.5,<6" 1135 | mccabe = ">=0.6,<0.8" 1136 | platformdirs = ">=2.2.0" 1137 | tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} 1138 | typing-extensions = {version = ">=3.10.0", markers = "python_version < \"3.10\""} 1139 | 1140 | [package.extras] 1141 | testutil = ["gitpython (>3)"] 1142 | 1143 | [[package]] 1144 | name = "pyparsing" 1145 | version = "3.0.9" 1146 | description = "pyparsing module - Classes and methods to define and execute parsing grammars" 1147 | optional = false 1148 | python-versions = ">=3.6.8" 1149 | files = [ 1150 | {file = "pyparsing-3.0.9-py3-none-any.whl", hash = "sha256:5026bae9a10eeaefb61dab2f09052b9f4307d44aee4eda64b309723d8d206bbc"}, 1151 | {file = "pyparsing-3.0.9.tar.gz", hash = "sha256:2b020ecf7d21b687f219b71ecad3631f644a47f01403fa1d1036b0c6416d70fb"}, 1152 | ] 1153 | 1154 | [package.extras] 1155 | diagrams = ["jinja2", "railroad-diagrams"] 1156 | 1157 | [[package]] 1158 | name = "pytest" 1159 | version = "7.1.3" 1160 | description = "pytest: simple powerful testing with Python" 1161 | optional = false 1162 | python-versions = ">=3.7" 1163 | files = [ 1164 | {file = "pytest-7.1.3-py3-none-any.whl", hash = "sha256:1377bda3466d70b55e3f5cecfa55bb7cfcf219c7964629b967c37cf0bda818b7"}, 1165 | {file = "pytest-7.1.3.tar.gz", hash = "sha256:4f365fec2dff9c1162f834d9f18af1ba13062db0c708bf7b946f8a5c76180c39"}, 1166 | ] 1167 | 1168 | [package.dependencies] 1169 | attrs = ">=19.2.0" 1170 | colorama = {version = "*", markers = "sys_platform == \"win32\""} 1171 | iniconfig = "*" 1172 | packaging = "*" 1173 | pluggy = ">=0.12,<2.0" 1174 | py = ">=1.8.2" 1175 | tomli = ">=1.0.0" 1176 | 1177 | [package.extras] 1178 | testing = ["argcomplete", "hypothesis (>=3.56)", "mock", "nose", "pygments (>=2.7.2)", "requests", "xmlschema"] 1179 | 1180 | [[package]] 1181 | name = "pytest-django" 1182 | version = "4.5.2" 1183 | description = "A Django plugin for pytest." 1184 | optional = false 1185 | python-versions = ">=3.5" 1186 | files = [ 1187 | {file = "pytest-django-4.5.2.tar.gz", hash = "sha256:d9076f759bb7c36939dbdd5ae6633c18edfc2902d1a69fdbefd2426b970ce6c2"}, 1188 | {file = "pytest_django-4.5.2-py3-none-any.whl", hash = "sha256:c60834861933773109334fe5a53e83d1ef4828f2203a1d6a0fa9972f4f75ab3e"}, 1189 | ] 1190 | 1191 | [package.dependencies] 1192 | pytest = ">=5.4.0" 1193 | 1194 | [package.extras] 1195 | docs = ["sphinx", "sphinx-rtd-theme"] 1196 | testing = ["Django", "django-configurations (>=2.0)"] 1197 | 1198 | [[package]] 1199 | name = "pytest-dotenv" 1200 | version = "0.5.2" 1201 | description = "A py.test plugin that parses environment files before running tests" 1202 | optional = false 1203 | python-versions = "*" 1204 | files = [ 1205 | {file = "pytest-dotenv-0.5.2.tar.gz", hash = "sha256:2dc6c3ac6d8764c71c6d2804e902d0ff810fa19692e95fe138aefc9b1aa73732"}, 1206 | {file = "pytest_dotenv-0.5.2-py3-none-any.whl", hash = "sha256:40a2cece120a213898afaa5407673f6bd924b1fa7eafce6bda0e8abffe2f710f"}, 1207 | ] 1208 | 1209 | [package.dependencies] 1210 | pytest = ">=5.0.0" 1211 | python-dotenv = ">=0.9.1" 1212 | 1213 | [[package]] 1214 | name = "python-dotenv" 1215 | version = "0.21.0" 1216 | description = "Read key-value pairs from a .env file and set them as environment variables" 1217 | optional = false 1218 | python-versions = ">=3.7" 1219 | files = [ 1220 | {file = "python-dotenv-0.21.0.tar.gz", hash = "sha256:b77d08274639e3d34145dfa6c7008e66df0f04b7be7a75fd0d5292c191d79045"}, 1221 | {file = "python_dotenv-0.21.0-py3-none-any.whl", hash = "sha256:1684eb44636dd462b66c3ee016599815514527ad99965de77f43e0944634a7e5"}, 1222 | ] 1223 | 1224 | [package.extras] 1225 | cli = ["click (>=5.0)"] 1226 | 1227 | [[package]] 1228 | name = "pywebcopy" 1229 | version = "7.0.2" 1230 | description = "Python library to clone/archive pages or sites from the Internet." 1231 | optional = false 1232 | python-versions = "*" 1233 | files = [ 1234 | {file = "pywebcopy-7.0.2-py2.py3-none-any.whl", hash = "sha256:68b89c0011e2675ab4120d9d4bebad0f77384e2199e86b0acd0631abeb146b9f"}, 1235 | {file = "pywebcopy-7.0.2.tar.gz", hash = "sha256:1f5d0688fc80bd7e9454ce5bcb84ea5becfab5cc0faac90c9d330bdc15897555"}, 1236 | ] 1237 | 1238 | [package.dependencies] 1239 | cachecontrol = "*" 1240 | lxml = "*" 1241 | requests = "*" 1242 | setuptools = "*" 1243 | six = "*" 1244 | 1245 | [[package]] 1246 | name = "pyyaml" 1247 | version = "6.0.1" 1248 | description = "YAML parser and emitter for Python" 1249 | optional = false 1250 | python-versions = ">=3.6" 1251 | files = [ 1252 | {file = "PyYAML-6.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d858aa552c999bc8a8d57426ed01e40bef403cd8ccdd0fc5f6f04a00414cac2a"}, 1253 | {file = "PyYAML-6.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:fd66fc5d0da6d9815ba2cebeb4205f95818ff4b79c3ebe268e75d961704af52f"}, 1254 | {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:69b023b2b4daa7548bcfbd4aa3da05b3a74b772db9e23b982788168117739938"}, 1255 | {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:81e0b275a9ecc9c0c0c07b4b90ba548307583c125f54d5b6946cfee6360c733d"}, 1256 | {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba336e390cd8e4d1739f42dfe9bb83a3cc2e80f567d8805e11b46f4a943f5515"}, 1257 | {file = "PyYAML-6.0.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:326c013efe8048858a6d312ddd31d56e468118ad4cdeda36c719bf5bb6192290"}, 1258 | {file = "PyYAML-6.0.1-cp310-cp310-win32.whl", hash = "sha256:bd4af7373a854424dabd882decdc5579653d7868b8fb26dc7d0e99f823aa5924"}, 1259 | {file = "PyYAML-6.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:fd1592b3fdf65fff2ad0004b5e363300ef59ced41c2e6b3a99d4089fa8c5435d"}, 1260 | {file = "PyYAML-6.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6965a7bc3cf88e5a1c3bd2e0b5c22f8d677dc88a455344035f03399034eb3007"}, 1261 | {file = "PyYAML-6.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f003ed9ad21d6a4713f0a9b5a7a0a79e08dd0f221aff4525a2be4c346ee60aab"}, 1262 | {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:42f8152b8dbc4fe7d96729ec2b99c7097d656dc1213a3229ca5383f973a5ed6d"}, 1263 | {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:062582fca9fabdd2c8b54a3ef1c978d786e0f6b3a1510e0ac93ef59e0ddae2bc"}, 1264 | {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d2b04aac4d386b172d5b9692e2d2da8de7bfb6c387fa4f801fbf6fb2e6ba4673"}, 1265 | {file = "PyYAML-6.0.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e7d73685e87afe9f3b36c799222440d6cf362062f78be1013661b00c5c6f678b"}, 1266 | {file = "PyYAML-6.0.1-cp311-cp311-win32.whl", hash = "sha256:1635fd110e8d85d55237ab316b5b011de701ea0f29d07611174a1b42f1444741"}, 1267 | {file = "PyYAML-6.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34"}, 1268 | {file = "PyYAML-6.0.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28"}, 1269 | {file = "PyYAML-6.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9"}, 1270 | {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a08c6f0fe150303c1c6b71ebcd7213c2858041a7e01975da3a99aed1e7a378ef"}, 1271 | {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0"}, 1272 | {file = "PyYAML-6.0.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4"}, 1273 | {file = "PyYAML-6.0.1-cp312-cp312-win32.whl", hash = "sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54"}, 1274 | {file = "PyYAML-6.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:0d3304d8c0adc42be59c5f8a4d9e3d7379e6955ad754aa9d6ab7a398b59dd1df"}, 1275 | {file = "PyYAML-6.0.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:50550eb667afee136e9a77d6dc71ae76a44df8b3e51e41b77f6de2932bfe0f47"}, 1276 | {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1fe35611261b29bd1de0070f0b2f47cb6ff71fa6595c077e42bd0c419fa27b98"}, 1277 | {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:704219a11b772aea0d8ecd7058d0082713c3562b4e271b849ad7dc4a5c90c13c"}, 1278 | {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:afd7e57eddb1a54f0f1a974bc4391af8bcce0b444685d936840f125cf046d5bd"}, 1279 | {file = "PyYAML-6.0.1-cp36-cp36m-win32.whl", hash = "sha256:fca0e3a251908a499833aa292323f32437106001d436eca0e6e7833256674585"}, 1280 | {file = "PyYAML-6.0.1-cp36-cp36m-win_amd64.whl", hash = "sha256:f22ac1c3cac4dbc50079e965eba2c1058622631e526bd9afd45fedd49ba781fa"}, 1281 | {file = "PyYAML-6.0.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:b1275ad35a5d18c62a7220633c913e1b42d44b46ee12554e5fd39c70a243d6a3"}, 1282 | {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:18aeb1bf9a78867dc38b259769503436b7c72f7a1f1f4c93ff9a17de54319b27"}, 1283 | {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:596106435fa6ad000c2991a98fa58eeb8656ef2325d7e158344fb33864ed87e3"}, 1284 | {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:baa90d3f661d43131ca170712d903e6295d1f7a0f595074f151c0aed377c9b9c"}, 1285 | {file = "PyYAML-6.0.1-cp37-cp37m-win32.whl", hash = "sha256:9046c58c4395dff28dd494285c82ba00b546adfc7ef001486fbf0324bc174fba"}, 1286 | {file = "PyYAML-6.0.1-cp37-cp37m-win_amd64.whl", hash = "sha256:4fb147e7a67ef577a588a0e2c17b6db51dda102c71de36f8549b6816a96e1867"}, 1287 | {file = "PyYAML-6.0.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1d4c7e777c441b20e32f52bd377e0c409713e8bb1386e1099c2415f26e479595"}, 1288 | {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5"}, 1289 | {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:28c119d996beec18c05208a8bd78cbe4007878c6dd15091efb73a30e90539696"}, 1290 | {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e07cbde391ba96ab58e532ff4803f79c4129397514e1413a7dc761ccd755735"}, 1291 | {file = "PyYAML-6.0.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:49a183be227561de579b4a36efbb21b3eab9651dd81b1858589f796549873dd6"}, 1292 | {file = "PyYAML-6.0.1-cp38-cp38-win32.whl", hash = "sha256:184c5108a2aca3c5b3d3bf9395d50893a7ab82a38004c8f61c258d4428e80206"}, 1293 | {file = "PyYAML-6.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:1e2722cc9fbb45d9b87631ac70924c11d3a401b2d7f410cc0e3bbf249f2dca62"}, 1294 | {file = "PyYAML-6.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8"}, 1295 | {file = "PyYAML-6.0.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c8098ddcc2a85b61647b2590f825f3db38891662cfc2fc776415143f599bb859"}, 1296 | {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5773183b6446b2c99bb77e77595dd486303b4faab2b086e7b17bc6bef28865f6"}, 1297 | {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b786eecbdf8499b9ca1d697215862083bd6d2a99965554781d0d8d1ad31e13a0"}, 1298 | {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc1bf2925a1ecd43da378f4db9e4f799775d6367bdb94671027b73b393a7c42c"}, 1299 | {file = "PyYAML-6.0.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:04ac92ad1925b2cff1db0cfebffb6ffc43457495c9b3c39d3fcae417d7125dc5"}, 1300 | {file = "PyYAML-6.0.1-cp39-cp39-win32.whl", hash = "sha256:faca3bdcf85b2fc05d06ff3fbc1f83e1391b3e724afa3feba7d13eeab355484c"}, 1301 | {file = "PyYAML-6.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:510c9deebc5c0225e8c96813043e62b680ba2f9c50a08d3724c7f28a747d1486"}, 1302 | {file = "PyYAML-6.0.1.tar.gz", hash = "sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43"}, 1303 | ] 1304 | 1305 | [[package]] 1306 | name = "requests" 1307 | version = "2.28.1" 1308 | description = "Python HTTP for Humans." 1309 | optional = false 1310 | python-versions = ">=3.7, <4" 1311 | files = [ 1312 | {file = "requests-2.28.1-py3-none-any.whl", hash = "sha256:8fefa2a1a1365bf5520aac41836fbee479da67864514bdb821f31ce07ce65349"}, 1313 | {file = "requests-2.28.1.tar.gz", hash = "sha256:7c5599b102feddaa661c826c56ab4fee28bfd17f5abca1ebbe3e7f19d7c97983"}, 1314 | ] 1315 | 1316 | [package.dependencies] 1317 | certifi = ">=2017.4.17" 1318 | charset-normalizer = ">=2,<3" 1319 | idna = ">=2.5,<4" 1320 | urllib3 = ">=1.21.1,<1.27" 1321 | 1322 | [package.extras] 1323 | socks = ["PySocks (>=1.5.6,!=1.5.7)"] 1324 | use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] 1325 | 1326 | [[package]] 1327 | name = "rich" 1328 | version = "12.5.1" 1329 | description = "Render rich text, tables, progress bars, syntax highlighting, markdown and more to the terminal" 1330 | optional = false 1331 | python-versions = ">=3.6.3,<4.0.0" 1332 | files = [ 1333 | {file = "rich-12.5.1-py3-none-any.whl", hash = "sha256:2eb4e6894cde1e017976d2975ac210ef515d7548bc595ba20e195fb9628acdeb"}, 1334 | {file = "rich-12.5.1.tar.gz", hash = "sha256:63a5c5ce3673d3d5fbbf23cd87e11ab84b6b451436f1b7f19ec54b6bc36ed7ca"}, 1335 | ] 1336 | 1337 | [package.dependencies] 1338 | commonmark = ">=0.9.0,<0.10.0" 1339 | pygments = ">=2.6.0,<3.0.0" 1340 | typing-extensions = {version = ">=4.0.0,<5.0", markers = "python_version < \"3.9\""} 1341 | 1342 | [package.extras] 1343 | jupyter = ["ipywidgets (>=7.5.1,<8.0.0)"] 1344 | 1345 | [[package]] 1346 | name = "rstcheck" 1347 | version = "6.2.0" 1348 | description = "Checks syntax of reStructuredText and code blocks nested within it" 1349 | optional = false 1350 | python-versions = ">=3.8" 1351 | files = [ 1352 | {file = "rstcheck-6.2.0-py3-none-any.whl", hash = "sha256:63262c8453489a6e3873113e16c1d234c86ca90a829e685263fd6c7aec0073fa"}, 1353 | {file = "rstcheck-6.2.0.tar.gz", hash = "sha256:4f47d1e136e8dc7e6fd54d9679dbc1ed7c4d87b12e17d00003fccf4734e9ffdf"}, 1354 | ] 1355 | 1356 | [package.dependencies] 1357 | importlib-metadata = {version = ">=1.6", markers = "python_version <= \"3.8\""} 1358 | rstcheck-core = ">=1.1" 1359 | typer = {version = ">=0.4.1", extras = ["all"]} 1360 | typing-extensions = {version = ">=3.7.4", markers = "python_version <= \"3.8\""} 1361 | 1362 | [package.extras] 1363 | dev = ["rstcheck[docs,sphinx,testing,toml,type-check]", "tox (>=3.15)"] 1364 | docs = ["m2r2 (>=0.3.2)", "sphinx (>=4.0)", "sphinx-autobuild (>=2021.3.14)", "sphinx-click (>=4.0.3)", "sphinx-rtd-theme (>=1.2)", "sphinxcontrib-spelling (>=7.3)"] 1365 | sphinx = ["sphinx (>=4.0)"] 1366 | testing = ["coverage-conditional-plugin (>=0.5)", "coverage[toml] (>=6.0)", "pytest (>=7.2)", "pytest-cov (>=3.0)", "pytest-randomly (>=3.0)", "pytest-sugar (>=0.9.5)"] 1367 | toml = ["tomli (>=2.0)"] 1368 | type-check = ["mypy (>=1.0)"] 1369 | 1370 | [[package]] 1371 | name = "rstcheck-core" 1372 | version = "1.2.0" 1373 | description = "Checks syntax of reStructuredText and code blocks nested within it" 1374 | optional = false 1375 | python-versions = ">=3.8" 1376 | files = [ 1377 | {file = "rstcheck-core-1.2.0.tar.gz", hash = "sha256:991678a86b604636d2461a97fb9339366d143eb799d22d51f49f84ed272121a9"}, 1378 | {file = "rstcheck_core-1.2.0-py3-none-any.whl", hash = "sha256:53478e4f9b1aca98dd9e892eff9f90fc8741b2be0e3213497585227c369db510"}, 1379 | ] 1380 | 1381 | [package.dependencies] 1382 | docutils = ">=0.7" 1383 | importlib-metadata = {version = ">=1.6", markers = "python_version <= \"3.8\""} 1384 | pydantic = ">=2" 1385 | typing-extensions = {version = ">=3.7.4", markers = "python_version <= \"3.8\""} 1386 | 1387 | [package.extras] 1388 | dev = ["rstcheck-core[docs,sphinx,testing,toml,type-check,yaml]", "tox (>=3.15)"] 1389 | docs = ["m2r2 (>=0.3.2)", "sphinx (>=4.0,!=7.2.5)", "sphinx-autobuild (>=2021.3.14)", "sphinx-autodoc-typehints (>=1.15)", "sphinx-rtd-theme (>=1.2)", "sphinxcontrib-apidoc (>=0.3)", "sphinxcontrib-spelling (>=7.3)"] 1390 | sphinx = ["sphinx (>=4.0)"] 1391 | testing = ["coverage-conditional-plugin (>=0.5)", "coverage[toml] (>=6.0)", "pytest (>=7.2)", "pytest-cov (>=3.0)", "pytest-mock (>=3.7)", "pytest-randomly (>=3.0)", "pytest-sugar (>=0.9.5)"] 1392 | toml = ["tomli (>=2.0)"] 1393 | type-check = ["mypy (>=1.0)", "types-PyYAML (>=6.0.0)", "types-docutils (>=0.18)"] 1394 | yaml = ["pyyaml (>=6.0.0)"] 1395 | 1396 | [[package]] 1397 | name = "setuptools" 1398 | version = "65.3.0" 1399 | description = "Easily download, build, install, upgrade, and uninstall Python packages" 1400 | optional = false 1401 | python-versions = ">=3.7" 1402 | files = [ 1403 | {file = "setuptools-65.3.0-py3-none-any.whl", hash = "sha256:2e24e0bec025f035a2e72cdd1961119f557d78ad331bb00ff82efb2ab8da8e82"}, 1404 | {file = "setuptools-65.3.0.tar.gz", hash = "sha256:7732871f4f7fa58fb6bdcaeadb0161b2bd046c85905dbaa066bdcbcc81953b57"}, 1405 | ] 1406 | 1407 | [package.extras] 1408 | docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "rst.linker (>=1.9)", "sphinx", "sphinx-favicon", "sphinx-hoverxref (<2)", "sphinx-inline-tabs", "sphinx-notfound-page (==0.8.3)", "sphinx-reredirects", "sphinxcontrib-towncrier"] 1409 | testing = ["build[virtualenv]", "filelock (>=3.4.0)", "flake8 (<5)", "flake8-2020", "ini2toml[lite] (>=0.9)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "mock", "pip (>=19.1)", "pip-run (>=8.8)", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)", "pytest-perf", "pytest-xdist", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] 1410 | testing-integration = ["build[virtualenv]", "filelock (>=3.4.0)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pytest", "pytest-enabler", "pytest-xdist", "tomli", "virtualenv (>=13.0.0)", "wheel"] 1411 | 1412 | [[package]] 1413 | name = "shellingham" 1414 | version = "1.5.4" 1415 | description = "Tool to Detect Surrounding Shell" 1416 | optional = false 1417 | python-versions = ">=3.7" 1418 | files = [ 1419 | {file = "shellingham-1.5.4-py2.py3-none-any.whl", hash = "sha256:7ecfff8f2fd72616f7481040475a65b2bf8af90a56c89140852d1120324e8686"}, 1420 | {file = "shellingham-1.5.4.tar.gz", hash = "sha256:8dbca0739d487e5bd35ab3ca4b36e11c4078f3a234bfce294b0a0291363404de"}, 1421 | ] 1422 | 1423 | [[package]] 1424 | name = "six" 1425 | version = "1.16.0" 1426 | description = "Python 2 and 3 compatibility utilities" 1427 | optional = false 1428 | python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" 1429 | files = [ 1430 | {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, 1431 | {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, 1432 | ] 1433 | 1434 | [[package]] 1435 | name = "snowballstemmer" 1436 | version = "2.2.0" 1437 | description = "This package provides 29 stemmers for 28 languages generated from Snowball algorithms." 1438 | optional = false 1439 | python-versions = "*" 1440 | files = [ 1441 | {file = "snowballstemmer-2.2.0-py2.py3-none-any.whl", hash = "sha256:c8e1716e83cc398ae16824e5572ae04e0d9fc2c6b985fb0f900f5f0c96ecba1a"}, 1442 | {file = "snowballstemmer-2.2.0.tar.gz", hash = "sha256:09b16deb8547d3412ad7b590689584cd0fe25ec8db3be37788be3810cbf19cb1"}, 1443 | ] 1444 | 1445 | [[package]] 1446 | name = "sqlparse" 1447 | version = "0.4.2" 1448 | description = "A non-validating SQL parser." 1449 | optional = false 1450 | python-versions = ">=3.5" 1451 | files = [ 1452 | {file = "sqlparse-0.4.2-py3-none-any.whl", hash = "sha256:48719e356bb8b42991bdbb1e8b83223757b93789c00910a616a071910ca4a64d"}, 1453 | {file = "sqlparse-0.4.2.tar.gz", hash = "sha256:0c00730c74263a94e5a9919ade150dfc3b19c574389985446148402998287dae"}, 1454 | ] 1455 | 1456 | [[package]] 1457 | name = "toml" 1458 | version = "0.10.2" 1459 | description = "Python Library for Tom's Obvious, Minimal Language" 1460 | optional = false 1461 | python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" 1462 | files = [ 1463 | {file = "toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b"}, 1464 | {file = "toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"}, 1465 | ] 1466 | 1467 | [[package]] 1468 | name = "tomli" 1469 | version = "2.0.1" 1470 | description = "A lil' TOML parser" 1471 | optional = false 1472 | python-versions = ">=3.7" 1473 | files = [ 1474 | {file = "tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc"}, 1475 | {file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"}, 1476 | ] 1477 | 1478 | [[package]] 1479 | name = "tox" 1480 | version = "3.28.0" 1481 | description = "tox is a generic virtualenv management and test command line tool" 1482 | optional = false 1483 | python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7" 1484 | files = [ 1485 | {file = "tox-3.28.0-py2.py3-none-any.whl", hash = "sha256:57b5ab7e8bb3074edc3c0c0b4b192a4f3799d3723b2c5b76f1fa9f2d40316eea"}, 1486 | {file = "tox-3.28.0.tar.gz", hash = "sha256:d0d28f3fe6d6d7195c27f8b054c3e99d5451952b54abdae673b71609a581f640"}, 1487 | ] 1488 | 1489 | [package.dependencies] 1490 | colorama = {version = ">=0.4.1", markers = "platform_system == \"Windows\""} 1491 | filelock = ">=3.0.0" 1492 | packaging = ">=14" 1493 | pluggy = ">=0.12.0" 1494 | py = ">=1.4.17" 1495 | six = ">=1.14.0" 1496 | tomli = {version = ">=2.0.1", markers = "python_version >= \"3.7\" and python_version < \"3.11\""} 1497 | virtualenv = ">=16.0.0,<20.0.0 || >20.0.0,<20.0.1 || >20.0.1,<20.0.2 || >20.0.2,<20.0.3 || >20.0.3,<20.0.4 || >20.0.4,<20.0.5 || >20.0.5,<20.0.6 || >20.0.6,<20.0.7 || >20.0.7" 1498 | 1499 | [package.extras] 1500 | docs = ["pygments-github-lexers (>=0.0.5)", "sphinx (>=2.0.0)", "sphinxcontrib-autoprogram (>=0.1.5)", "towncrier (>=18.5.0)"] 1501 | testing = ["flaky (>=3.4.0)", "freezegun (>=0.3.11)", "pathlib2 (>=2.3.3)", "psutil (>=5.6.1)", "pytest (>=4.0.0)", "pytest-cov (>=2.5.1)", "pytest-mock (>=1.10.0)", "pytest-randomly (>=1.0.0)"] 1502 | 1503 | [[package]] 1504 | name = "typer" 1505 | version = "0.6.1" 1506 | description = "Typer, build great CLIs. Easy to code. Based on Python type hints." 1507 | optional = false 1508 | python-versions = ">=3.6" 1509 | files = [ 1510 | {file = "typer-0.6.1-py3-none-any.whl", hash = "sha256:54b19e5df18654070a82f8c2aa1da456a4ac16a2a83e6dcd9f170e291c56338e"}, 1511 | {file = "typer-0.6.1.tar.gz", hash = "sha256:2d5720a5e63f73eaf31edaa15f6ab87f35f0690f8ca233017d7d23d743a91d73"}, 1512 | ] 1513 | 1514 | [package.dependencies] 1515 | click = ">=7.1.1,<9.0.0" 1516 | colorama = {version = ">=0.4.3,<0.5.0", optional = true, markers = "extra == \"all\""} 1517 | rich = {version = ">=10.11.0,<13.0.0", optional = true, markers = "extra == \"all\""} 1518 | shellingham = {version = ">=1.3.0,<2.0.0", optional = true, markers = "extra == \"all\""} 1519 | 1520 | [package.extras] 1521 | all = ["colorama (>=0.4.3,<0.5.0)", "rich (>=10.11.0,<13.0.0)", "shellingham (>=1.3.0,<2.0.0)"] 1522 | dev = ["autoflake (>=1.3.1,<2.0.0)", "flake8 (>=3.8.3,<4.0.0)", "pre-commit (>=2.17.0,<3.0.0)"] 1523 | doc = ["mdx-include (>=1.4.1,<2.0.0)", "mkdocs (>=1.1.2,<2.0.0)", "mkdocs-material (>=8.1.4,<9.0.0)"] 1524 | test = ["black (>=22.3.0,<23.0.0)", "coverage (>=5.2,<6.0)", "isort (>=5.0.6,<6.0.0)", "mypy (==0.910)", "pytest (>=4.4.0,<5.4.0)", "pytest-cov (>=2.10.0,<3.0.0)", "pytest-sugar (>=0.9.4,<0.10.0)", "pytest-xdist (>=1.32.0,<2.0.0)", "rich (>=10.11.0,<13.0.0)", "shellingham (>=1.3.0,<2.0.0)"] 1525 | 1526 | [[package]] 1527 | name = "types-pytz" 1528 | version = "2022.4.0.0" 1529 | description = "Typing stubs for pytz" 1530 | optional = false 1531 | python-versions = "*" 1532 | files = [ 1533 | {file = "types-pytz-2022.4.0.0.tar.gz", hash = "sha256:17d66e4b16e80ceae0787726f3a22288df7d3f9fdebeb091dc64b92c0e4ea09d"}, 1534 | {file = "types_pytz-2022.4.0.0-py3-none-any.whl", hash = "sha256:950b0f3d64ed5b03a3e29c1e38fe2be8371c933c8e97922d0352345336eb8af4"}, 1535 | ] 1536 | 1537 | [[package]] 1538 | name = "types-PyYAML" 1539 | version = "6.0.12" 1540 | description = "Typing stubs for PyYAML" 1541 | optional = false 1542 | python-versions = "*" 1543 | files = [ 1544 | {file = "types-PyYAML-6.0.12.tar.gz", hash = "sha256:f6f350418125872f3f0409d96a62a5a5ceb45231af5cc07ee0034ec48a3c82fa"}, 1545 | {file = "types_PyYAML-6.0.12-py3-none-any.whl", hash = "sha256:29228db9f82df4f1b7febee06bbfb601677882e98a3da98132e31c6874163e15"}, 1546 | ] 1547 | 1548 | [[package]] 1549 | name = "typing-extensions" 1550 | version = "4.8.0" 1551 | description = "Backported and Experimental Type Hints for Python 3.8+" 1552 | optional = false 1553 | python-versions = ">=3.8" 1554 | files = [ 1555 | {file = "typing_extensions-4.8.0-py3-none-any.whl", hash = "sha256:8f92fc8806f9a6b641eaa5318da32b44d401efaac0f6678c9bc448ba3605faa0"}, 1556 | {file = "typing_extensions-4.8.0.tar.gz", hash = "sha256:df8e4339e9cb77357558cbdbceca33c303714cf861d1eef15e1070055ae8b7ef"}, 1557 | ] 1558 | 1559 | [[package]] 1560 | name = "tzdata" 1561 | version = "2023.3" 1562 | description = "Provider of IANA time zone data" 1563 | optional = false 1564 | python-versions = ">=2" 1565 | files = [ 1566 | {file = "tzdata-2023.3-py2.py3-none-any.whl", hash = "sha256:7e65763eef3120314099b6939b5546db7adce1e7d6f2e179e3df563c70511eda"}, 1567 | {file = "tzdata-2023.3.tar.gz", hash = "sha256:11ef1e08e54acb0d4f95bdb1be05da659673de4acbd21bf9c69e94cc5e907a3a"}, 1568 | ] 1569 | 1570 | [[package]] 1571 | name = "urllib3" 1572 | version = "1.26.12" 1573 | description = "HTTP library with thread-safe connection pooling, file post, and more." 1574 | optional = false 1575 | python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*, <4" 1576 | files = [ 1577 | {file = "urllib3-1.26.12-py2.py3-none-any.whl", hash = "sha256:b930dd878d5a8afb066a637fbb35144fe7901e3b209d1cd4f524bd0e9deee997"}, 1578 | {file = "urllib3-1.26.12.tar.gz", hash = "sha256:3fa96cf423e6987997fc326ae8df396db2a8b7c667747d47ddd8ecba91f4a74e"}, 1579 | ] 1580 | 1581 | [package.extras] 1582 | brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)", "brotlipy (>=0.6.0)"] 1583 | secure = ["certifi", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "ipaddress", "pyOpenSSL (>=0.14)", "urllib3-secure-extra"] 1584 | socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"] 1585 | 1586 | [[package]] 1587 | name = "virtualenv" 1588 | version = "20.16.5" 1589 | description = "Virtual Python Environment builder" 1590 | optional = false 1591 | python-versions = ">=3.6" 1592 | files = [ 1593 | {file = "virtualenv-20.16.5-py3-none-any.whl", hash = "sha256:d07dfc5df5e4e0dbc92862350ad87a36ed505b978f6c39609dc489eadd5b0d27"}, 1594 | {file = "virtualenv-20.16.5.tar.gz", hash = "sha256:227ea1b9994fdc5ea31977ba3383ef296d7472ea85be9d6732e42a91c04e80da"}, 1595 | ] 1596 | 1597 | [package.dependencies] 1598 | distlib = ">=0.3.5,<1" 1599 | filelock = ">=3.4.1,<4" 1600 | platformdirs = ">=2.4,<3" 1601 | 1602 | [package.extras] 1603 | docs = ["proselint (>=0.13)", "sphinx (>=5.1.1)", "sphinx-argparse (>=0.3.1)", "sphinx-rtd-theme (>=1)", "towncrier (>=21.9)"] 1604 | testing = ["coverage (>=6.2)", "coverage-enable-subprocess (>=1)", "flaky (>=3.7)", "packaging (>=21.3)", "pytest (>=7.0.1)", "pytest-env (>=0.6.2)", "pytest-freezegun (>=0.4.2)", "pytest-mock (>=3.6.1)", "pytest-randomly (>=3.10.3)", "pytest-timeout (>=2.1)"] 1605 | 1606 | [[package]] 1607 | name = "wrapt" 1608 | version = "1.14.1" 1609 | description = "Module for decorators, wrappers and monkey patching." 1610 | optional = false 1611 | python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7" 1612 | files = [ 1613 | {file = "wrapt-1.14.1-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:1b376b3f4896e7930f1f772ac4b064ac12598d1c38d04907e696cc4d794b43d3"}, 1614 | {file = "wrapt-1.14.1-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:903500616422a40a98a5a3c4ff4ed9d0066f3b4c951fa286018ecdf0750194ef"}, 1615 | {file = "wrapt-1.14.1-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:5a9a0d155deafd9448baff28c08e150d9b24ff010e899311ddd63c45c2445e28"}, 1616 | {file = "wrapt-1.14.1-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:ddaea91abf8b0d13443f6dac52e89051a5063c7d014710dcb4d4abb2ff811a59"}, 1617 | {file = "wrapt-1.14.1-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:36f582d0c6bc99d5f39cd3ac2a9062e57f3cf606ade29a0a0d6b323462f4dd87"}, 1618 | {file = "wrapt-1.14.1-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:7ef58fb89674095bfc57c4069e95d7a31cfdc0939e2a579882ac7d55aadfd2a1"}, 1619 | {file = "wrapt-1.14.1-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:e2f83e18fe2f4c9e7db597e988f72712c0c3676d337d8b101f6758107c42425b"}, 1620 | {file = "wrapt-1.14.1-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:ee2b1b1769f6707a8a445162ea16dddf74285c3964f605877a20e38545c3c462"}, 1621 | {file = "wrapt-1.14.1-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:833b58d5d0b7e5b9832869f039203389ac7cbf01765639c7309fd50ef619e0b1"}, 1622 | {file = "wrapt-1.14.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:80bb5c256f1415f747011dc3604b59bc1f91c6e7150bd7db03b19170ee06b320"}, 1623 | {file = "wrapt-1.14.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:07f7a7d0f388028b2df1d916e94bbb40624c59b48ecc6cbc232546706fac74c2"}, 1624 | {file = "wrapt-1.14.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:02b41b633c6261feff8ddd8d11c711df6842aba629fdd3da10249a53211a72c4"}, 1625 | {file = "wrapt-1.14.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2fe803deacd09a233e4762a1adcea5db5d31e6be577a43352936179d14d90069"}, 1626 | {file = "wrapt-1.14.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:257fd78c513e0fb5cdbe058c27a0624c9884e735bbd131935fd49e9fe719d310"}, 1627 | {file = "wrapt-1.14.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:4fcc4649dc762cddacd193e6b55bc02edca674067f5f98166d7713b193932b7f"}, 1628 | {file = "wrapt-1.14.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:11871514607b15cfeb87c547a49bca19fde402f32e2b1c24a632506c0a756656"}, 1629 | {file = "wrapt-1.14.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:8ad85f7f4e20964db4daadcab70b47ab05c7c1cf2a7c1e51087bfaa83831854c"}, 1630 | {file = "wrapt-1.14.1-cp310-cp310-win32.whl", hash = "sha256:a9a52172be0b5aae932bef82a79ec0a0ce87288c7d132946d645eba03f0ad8a8"}, 1631 | {file = "wrapt-1.14.1-cp310-cp310-win_amd64.whl", hash = "sha256:6d323e1554b3d22cfc03cd3243b5bb815a51f5249fdcbb86fda4bf62bab9e164"}, 1632 | {file = "wrapt-1.14.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ecee4132c6cd2ce5308e21672015ddfed1ff975ad0ac8d27168ea82e71413f55"}, 1633 | {file = "wrapt-1.14.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:2020f391008ef874c6d9e208b24f28e31bcb85ccff4f335f15a3251d222b92d9"}, 1634 | {file = "wrapt-1.14.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2feecf86e1f7a86517cab34ae6c2f081fd2d0dac860cb0c0ded96d799d20b335"}, 1635 | {file = "wrapt-1.14.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:240b1686f38ae665d1b15475966fe0472f78e71b1b4903c143a842659c8e4cb9"}, 1636 | {file = "wrapt-1.14.1-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a9008dad07d71f68487c91e96579c8567c98ca4c3881b9b113bc7b33e9fd78b8"}, 1637 | {file = "wrapt-1.14.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:6447e9f3ba72f8e2b985a1da758767698efa72723d5b59accefd716e9e8272bf"}, 1638 | {file = "wrapt-1.14.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:acae32e13a4153809db37405f5eba5bac5fbe2e2ba61ab227926a22901051c0a"}, 1639 | {file = "wrapt-1.14.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:49ef582b7a1152ae2766557f0550a9fcbf7bbd76f43fbdc94dd3bf07cc7168be"}, 1640 | {file = "wrapt-1.14.1-cp311-cp311-win32.whl", hash = "sha256:358fe87cc899c6bb0ddc185bf3dbfa4ba646f05b1b0b9b5a27c2cb92c2cea204"}, 1641 | {file = "wrapt-1.14.1-cp311-cp311-win_amd64.whl", hash = "sha256:26046cd03936ae745a502abf44dac702a5e6880b2b01c29aea8ddf3353b68224"}, 1642 | {file = "wrapt-1.14.1-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:43ca3bbbe97af00f49efb06e352eae40434ca9d915906f77def219b88e85d907"}, 1643 | {file = "wrapt-1.14.1-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:6b1a564e6cb69922c7fe3a678b9f9a3c54e72b469875aa8018f18b4d1dd1adf3"}, 1644 | {file = "wrapt-1.14.1-cp35-cp35m-manylinux2010_i686.whl", hash = "sha256:00b6d4ea20a906c0ca56d84f93065b398ab74b927a7a3dbd470f6fc503f95dc3"}, 1645 | {file = "wrapt-1.14.1-cp35-cp35m-manylinux2010_x86_64.whl", hash = "sha256:a85d2b46be66a71bedde836d9e41859879cc54a2a04fad1191eb50c2066f6e9d"}, 1646 | {file = "wrapt-1.14.1-cp35-cp35m-win32.whl", hash = "sha256:dbcda74c67263139358f4d188ae5faae95c30929281bc6866d00573783c422b7"}, 1647 | {file = "wrapt-1.14.1-cp35-cp35m-win_amd64.whl", hash = "sha256:b21bb4c09ffabfa0e85e3a6b623e19b80e7acd709b9f91452b8297ace2a8ab00"}, 1648 | {file = "wrapt-1.14.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:9e0fd32e0148dd5dea6af5fee42beb949098564cc23211a88d799e434255a1f4"}, 1649 | {file = "wrapt-1.14.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9736af4641846491aedb3c3f56b9bc5568d92b0692303b5a305301a95dfd38b1"}, 1650 | {file = "wrapt-1.14.1-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5b02d65b9ccf0ef6c34cba6cf5bf2aab1bb2f49c6090bafeecc9cd81ad4ea1c1"}, 1651 | {file = "wrapt-1.14.1-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:21ac0156c4b089b330b7666db40feee30a5d52634cc4560e1905d6529a3897ff"}, 1652 | {file = "wrapt-1.14.1-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:9f3e6f9e05148ff90002b884fbc2a86bd303ae847e472f44ecc06c2cd2fcdb2d"}, 1653 | {file = "wrapt-1.14.1-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:6e743de5e9c3d1b7185870f480587b75b1cb604832e380d64f9504a0535912d1"}, 1654 | {file = "wrapt-1.14.1-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:d79d7d5dc8a32b7093e81e97dad755127ff77bcc899e845f41bf71747af0c569"}, 1655 | {file = "wrapt-1.14.1-cp36-cp36m-win32.whl", hash = "sha256:81b19725065dcb43df02b37e03278c011a09e49757287dca60c5aecdd5a0b8ed"}, 1656 | {file = "wrapt-1.14.1-cp36-cp36m-win_amd64.whl", hash = "sha256:b014c23646a467558be7da3d6b9fa409b2c567d2110599b7cf9a0c5992b3b471"}, 1657 | {file = "wrapt-1.14.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:88bd7b6bd70a5b6803c1abf6bca012f7ed963e58c68d76ee20b9d751c74a3248"}, 1658 | {file = "wrapt-1.14.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b5901a312f4d14c59918c221323068fad0540e34324925c8475263841dbdfe68"}, 1659 | {file = "wrapt-1.14.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d77c85fedff92cf788face9bfa3ebaa364448ebb1d765302e9af11bf449ca36d"}, 1660 | {file = "wrapt-1.14.1-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8d649d616e5c6a678b26d15ece345354f7c2286acd6db868e65fcc5ff7c24a77"}, 1661 | {file = "wrapt-1.14.1-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:7d2872609603cb35ca513d7404a94d6d608fc13211563571117046c9d2bcc3d7"}, 1662 | {file = "wrapt-1.14.1-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:ee6acae74a2b91865910eef5e7de37dc6895ad96fa23603d1d27ea69df545015"}, 1663 | {file = "wrapt-1.14.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:2b39d38039a1fdad98c87279b48bc5dce2c0ca0d73483b12cb72aa9609278e8a"}, 1664 | {file = "wrapt-1.14.1-cp37-cp37m-win32.whl", hash = "sha256:60db23fa423575eeb65ea430cee741acb7c26a1365d103f7b0f6ec412b893853"}, 1665 | {file = "wrapt-1.14.1-cp37-cp37m-win_amd64.whl", hash = "sha256:709fe01086a55cf79d20f741f39325018f4df051ef39fe921b1ebe780a66184c"}, 1666 | {file = "wrapt-1.14.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:8c0ce1e99116d5ab21355d8ebe53d9460366704ea38ae4d9f6933188f327b456"}, 1667 | {file = "wrapt-1.14.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:e3fb1677c720409d5f671e39bac6c9e0e422584e5f518bfd50aa4cbbea02433f"}, 1668 | {file = "wrapt-1.14.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:642c2e7a804fcf18c222e1060df25fc210b9c58db7c91416fb055897fc27e8cc"}, 1669 | {file = "wrapt-1.14.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7b7c050ae976e286906dd3f26009e117eb000fb2cf3533398c5ad9ccc86867b1"}, 1670 | {file = "wrapt-1.14.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ef3f72c9666bba2bab70d2a8b79f2c6d2c1a42a7f7e2b0ec83bb2f9e383950af"}, 1671 | {file = "wrapt-1.14.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:01c205616a89d09827986bc4e859bcabd64f5a0662a7fe95e0d359424e0e071b"}, 1672 | {file = "wrapt-1.14.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:5a0f54ce2c092aaf439813735584b9537cad479575a09892b8352fea5e988dc0"}, 1673 | {file = "wrapt-1.14.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:2cf71233a0ed05ccdabe209c606fe0bac7379fdcf687f39b944420d2a09fdb57"}, 1674 | {file = "wrapt-1.14.1-cp38-cp38-win32.whl", hash = "sha256:aa31fdcc33fef9eb2552cbcbfee7773d5a6792c137b359e82879c101e98584c5"}, 1675 | {file = "wrapt-1.14.1-cp38-cp38-win_amd64.whl", hash = "sha256:d1967f46ea8f2db647c786e78d8cc7e4313dbd1b0aca360592d8027b8508e24d"}, 1676 | {file = "wrapt-1.14.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:3232822c7d98d23895ccc443bbdf57c7412c5a65996c30442ebe6ed3df335383"}, 1677 | {file = "wrapt-1.14.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:988635d122aaf2bdcef9e795435662bcd65b02f4f4c1ae37fbee7401c440b3a7"}, 1678 | {file = "wrapt-1.14.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9cca3c2cdadb362116235fdbd411735de4328c61425b0aa9f872fd76d02c4e86"}, 1679 | {file = "wrapt-1.14.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d52a25136894c63de15a35bc0bdc5adb4b0e173b9c0d07a2be9d3ca64a332735"}, 1680 | {file = "wrapt-1.14.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:40e7bc81c9e2b2734ea4bc1aceb8a8f0ceaac7c5299bc5d69e37c44d9081d43b"}, 1681 | {file = "wrapt-1.14.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:b9b7a708dd92306328117d8c4b62e2194d00c365f18eff11a9b53c6f923b01e3"}, 1682 | {file = "wrapt-1.14.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:6a9a25751acb379b466ff6be78a315e2b439d4c94c1e99cb7266d40a537995d3"}, 1683 | {file = "wrapt-1.14.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:34aa51c45f28ba7f12accd624225e2b1e5a3a45206aa191f6f9aac931d9d56fe"}, 1684 | {file = "wrapt-1.14.1-cp39-cp39-win32.whl", hash = "sha256:dee0ce50c6a2dd9056c20db781e9c1cfd33e77d2d569f5d1d9321c641bb903d5"}, 1685 | {file = "wrapt-1.14.1-cp39-cp39-win_amd64.whl", hash = "sha256:dee60e1de1898bde3b238f18340eec6148986da0455d8ba7848d50470a7a32fb"}, 1686 | {file = "wrapt-1.14.1.tar.gz", hash = "sha256:380a85cf89e0e69b7cfbe2ea9f765f004ff419f34194018a6827ac0e3edfed4d"}, 1687 | ] 1688 | 1689 | [[package]] 1690 | name = "zipp" 1691 | version = "3.17.0" 1692 | description = "Backport of pathlib-compatible object wrapper for zip files" 1693 | optional = false 1694 | python-versions = ">=3.8" 1695 | files = [ 1696 | {file = "zipp-3.17.0-py3-none-any.whl", hash = "sha256:0e923e726174922dce09c53c59ad483ff7bbb8e572e00c7f7c46b88556409f31"}, 1697 | {file = "zipp-3.17.0.tar.gz", hash = "sha256:84e64a1c28cf7e91ed2078bb8cc8c259cb19b76942096c8d7b84947690cabaf0"}, 1698 | ] 1699 | 1700 | [package.extras] 1701 | docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (<7.2.5)", "sphinx (>=3.5)", "sphinx-lint"] 1702 | testing = ["big-O", "jaraco.functools", "jaraco.itertools", "more-itertools", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-ignore-flaky", "pytest-mypy (>=0.9.1)", "pytest-ruff"] 1703 | 1704 | [metadata] 1705 | lock-version = "2.0" 1706 | python-versions = "^3.8" 1707 | content-hash = "8dc06f51a3aa969e06d8497d2c07d36e0dbd5e83df7c78f09b4cbb6bdf9416d1" 1708 | -------------------------------------------------------------------------------- /pyproject.toml: -------------------------------------------------------------------------------- 1 | [tool.poetry] 2 | name = "django-flatpickr" 3 | version = "0.0.0" 4 | description = """\ 5 | Flatpickr based DatePickerInput, TimePickerInput and \ 6 | DateTimePickerInput with date-range-picker functionality \ 7 | for django >= 2.0\ 8 | """ 9 | authors = ["Munim Munna <6266677+monim67@users.noreply.github.com>"] 10 | repository = "https://github.com/monim67/django-flatpickr" 11 | license = "MIT" 12 | readme = "README.rst" 13 | packages = [{ include = "django_flatpickr", from = "src" }] 14 | keywords = [ 15 | "django", 16 | "flatpickr", 17 | "date-picker", 18 | "time-picker", 19 | "datetime-picker", 20 | "date-range-picker", 21 | ] 22 | classifiers = [ 23 | "Intended Audience :: Developers", 24 | "Topic :: Software Development :: Libraries", 25 | "Topic :: Utilities", 26 | "Environment :: Web Environment", 27 | "Operating System :: OS Independent", 28 | "Development Status :: 5 - Production/Stable", 29 | "Framework :: Django", 30 | "Framework :: Django :: 2.0", 31 | "Framework :: Django :: 3.0", 32 | "Framework :: Django :: 4.0", 33 | "Framework :: Django :: 5.0", 34 | ] 35 | 36 | [tool.poetry.dependencies] 37 | python = "^3.8" 38 | Django = ">=2,<6" 39 | pydantic = ">=1,<3" 40 | pydantic-settings = "*" 41 | typing-extensions = "*" 42 | 43 | [tool.poetry.group.build.dependencies] 44 | pytest-django = "^4.5.2" 45 | pytest-dotenv = "^0.5.2" 46 | black = "^22.6.0" 47 | isort = "^5.10.1" 48 | pydocstyle = {extras = ["toml"], version = "^6.1.1"} 49 | mypy = "^1.0.1" 50 | django-stubs = "^1.12.0" 51 | coverage = { extras = ["toml"], version = "^6.5.0" } 52 | pylint = "^2.12.0" 53 | rstcheck = "^6.1.0" 54 | pywebcopy = "^7.0.2" 55 | poethepoet = "^0.15.0" 56 | django-crispy-forms = "^1.14.0" 57 | crispy-bulma = "^0.8.0" 58 | django-filter = "^22.1" 59 | 60 | [tool.poetry.group.dev.dependencies] 61 | tox = "^3.24.5" 62 | pre-commit = "^2.20.0" 63 | 64 | [build-system] 65 | requires = ["poetry-core"] 66 | build-backend = "poetry.core.masonry.api" 67 | 68 | [tool.poetry_bumpversion.file."src/django_flatpickr/__init__.py"] 69 | 70 | [tool.pylint.master] 71 | disable = ["R", "C", "missing-docstring", "unused-argument"] 72 | 73 | [tool.pylint.format] 74 | max-line-length = 88 75 | 76 | [tool.isort] 77 | py_version = "38" 78 | profile = "black" 79 | 80 | [tool.pydocstyle] 81 | convention = "google" 82 | add_select = "D401,D404" 83 | 84 | [tool.mypy] 85 | python_version = "3.8" 86 | namespace_packages = true 87 | strict = true 88 | plugins = ["mypy_django_plugin.main"] 89 | 90 | [[tool.mypy.overrides]] 91 | module = ["pywebcopy.*", "django_filters.*", "importlib_metadata.*"] 92 | ignore_missing_imports = true 93 | 94 | [tool.django-stubs] 95 | django_settings_module = "dev.mysite.settings" 96 | 97 | [tool.pytest.ini_options] 98 | pythonpath = "." # pytest-django needs it to find dev module 99 | django_find_project = false 100 | DJANGO_SETTINGS_MODULE = "dev.mysite.settings" 101 | addopts = "--reuse-db" 102 | testpaths = ["tests"] 103 | env_files = [".env", ".env.defaults"] 104 | 105 | [tool.coverage.run] 106 | command_line = "-m pytest" 107 | source = ["django_flatpickr"] 108 | parallel = true 109 | 110 | [tool.coverage.paths] 111 | source = [ 112 | "src/django_flatpickr", 113 | "**/site-packages/django_flatpickr", 114 | ] 115 | 116 | [tool.tox] 117 | legacy_tox_ini = """ 118 | [tox] 119 | isolated_build = True 120 | envlist = py{311,310,39,38} 121 | 122 | [testenv] 123 | allowlist_externals = poetry 124 | skip_install = true 125 | commands = 126 | poetry install --no-root --only build 127 | pip install -c tests/pip-constraints.txt . 128 | pytest 129 | """ 130 | 131 | [tool.poe] 132 | envfile = [".env.defaults", ".env"] 133 | 134 | [tool.poe.tasks] 135 | start = { cmd = "python dev/manage.py runserver localhost:8000", help = "Start dev server (press F5 on vscode)" } 136 | lint = [ 137 | { cmd = "python -m black --check src tests dev" }, 138 | { cmd = "python -m isort --check-only src tests dev" }, 139 | { cmd = "mypy src tests dev" }, 140 | { cmd = "pydocstyle src" }, 141 | { cmd = "rstcheck --report-level warning README.rst" }, 142 | ] 143 | test-cov = [ 144 | { cmd = "coverage run" }, 145 | { cmd = "coverage combine" }, 146 | { cmd = "coverage lcov -o coverage/lcov.info" }, 147 | { cmd = "coverage report" }, 148 | ] 149 | -------------------------------------------------------------------------------- /src/django_flatpickr/__init__.py: -------------------------------------------------------------------------------- 1 | """Flatpickr widgets for Django.""" 2 | 3 | __version__ = "0.0.0" 4 | -------------------------------------------------------------------------------- /src/django_flatpickr/_base.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """Contains Base Date-Picker input class for widgets of this package.""" 3 | 4 | from typing import Any, Dict, Optional 5 | 6 | from django import forms 7 | from django.forms.widgets import DateTimeBaseInput 8 | 9 | from ._config import WidgetConfig 10 | from ._media import yield_css_files, yield_js_files 11 | from .schemas import FlatpickrOptions, InputAttrs 12 | from .settings import get_django_flatpickr_settings 13 | 14 | 15 | class BasePickerInput(DateTimeBaseInput): 16 | """Base Date-Picker input class for widgets of this package.""" 17 | 18 | picker_type = "DATE" 19 | datetime_format = "%Y-%m-%d" 20 | format_key = "DATE_INPUT_FORMATS" 21 | template_name = "django_flatpickr/input.html" 22 | options: Optional[FlatpickrOptions] = None 23 | _option_overrides: Optional[Dict[str, Any]] = None 24 | 25 | def __init__( 26 | self, 27 | attrs: Optional[InputAttrs] = None, 28 | *, 29 | options: Optional[FlatpickrOptions] = None, 30 | range_from: Optional[str] = None, 31 | ): 32 | """Initialize the Date-picker widget.""" 33 | if not isinstance(options, (FlatpickrOptions, type(None))): 34 | raise ValueError("options must be of type FlatpickrOptions") 35 | if not isinstance(self.options, (FlatpickrOptions, type(None))): 36 | raise ValueError("options must be of type FlatpickrOptions") 37 | settings = get_django_flatpickr_settings() 38 | self.template_name = settings.template_name or self.template_name 39 | self.config = WidgetConfig(picker_type=self.picker_type, range_from=range_from) 40 | self.config.update_options( 41 | settings.options, 42 | self.options, 43 | options, 44 | overrides=self._option_overrides, 45 | ) 46 | super().__init__(attrs, self.datetime_format) 47 | 48 | def build_attrs( 49 | self, base_attrs: InputAttrs, extra_attrs: Optional[InputAttrs] = None 50 | ) -> InputAttrs: 51 | """Build an attribute dictionary.""" 52 | settings = get_django_flatpickr_settings() 53 | attrs = { 54 | **settings.attrs, 55 | **base_attrs, 56 | **(extra_attrs or {}), 57 | "data-fpconfig": self.config.to_attr_value(), 58 | } 59 | if settings.debug: 60 | attrs["data-debug"] = "" 61 | return attrs 62 | 63 | @property 64 | def media(self) -> forms.Media: # type: ignore 65 | """Generate widget Media.""" 66 | settings = get_django_flatpickr_settings() 67 | return forms.Media( 68 | css={"all": tuple(yield_css_files(settings, self.config.options))}, 69 | js=tuple(yield_js_files(settings, self.config.options)), 70 | ) 71 | -------------------------------------------------------------------------------- /src/django_flatpickr/_config.py: -------------------------------------------------------------------------------- 1 | from typing import Any, Dict, Optional 2 | 3 | try: 4 | from pydantic.v1 import BaseModel, Field 5 | except ModuleNotFoundError: # pragma: no cover 6 | from pydantic import BaseModel, Field # type: ignore 7 | 8 | from .schemas import FlatpickrOptions 9 | 10 | 11 | class WidgetConfig(BaseModel): 12 | """Widget config which is passed to input on render.""" 13 | 14 | picker_type: str 15 | options: FlatpickrOptions = Field(default_factory=FlatpickrOptions) 16 | range_from: Optional[str] 17 | 18 | def update_options( 19 | self, 20 | *options_args: Optional[FlatpickrOptions], 21 | overrides: Optional[Dict[str, Any]] = None, 22 | ) -> None: 23 | """Update options merging FlatpickrOptions sequentially.""" 24 | for options_arg in options_args: 25 | if options_arg is not None: 26 | self.options = self.options.copy( 27 | update=options_arg.dict(exclude_unset=True) 28 | ) 29 | if overrides is not None: 30 | self.options = self.options.copy(update=overrides) 31 | 32 | def to_attr_value(self) -> str: 33 | """Convert to attr string value.""" 34 | return self.json(exclude_none=True) 35 | -------------------------------------------------------------------------------- /src/django_flatpickr/_media.py: -------------------------------------------------------------------------------- 1 | from typing import Iterable 2 | 3 | from django_flatpickr.schemas import FlatpickrOptions 4 | from django_flatpickr.settings import DjangoFlatpickrSettings 5 | 6 | 7 | def yield_js_files( 8 | settings: DjangoFlatpickrSettings, options: FlatpickrOptions 9 | ) -> Iterable[str]: 10 | """Yield JavaScript media files for the widget.""" 11 | yield settings.flatpickr_cdn_url + "flatpickr.min.js" 12 | yield settings.app_static_url + "js/django-flatpickr.js" 13 | if options.locale: 14 | yield settings.flatpickr_cdn_url + f"l10n/{options.locale}.js" 15 | 16 | 17 | def yield_css_files( 18 | settings: DjangoFlatpickrSettings, options: FlatpickrOptions 19 | ) -> Iterable[str]: 20 | """Yield CSS media files for the widget.""" 21 | yield settings.flatpickr_cdn_url + "flatpickr.min.css" 22 | if settings.theme_url: 23 | yield settings.theme_url 24 | elif settings.theme_name: 25 | yield settings.flatpickr_cdn_url + f"themes/{settings.theme_name.value}.css" 26 | -------------------------------------------------------------------------------- /src/django_flatpickr/py.typed: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/monim67/django-flatpickr/1d96d524cc5924bd3f7f980ac0634fc0317eefff/src/django_flatpickr/py.typed -------------------------------------------------------------------------------- /src/django_flatpickr/schemas.py: -------------------------------------------------------------------------------- 1 | """Datastructures of the package.""" 2 | 3 | from enum import Enum 4 | from typing import Any, Dict, List, NoReturn, Optional 5 | 6 | try: 7 | from pydantic.v1 import BaseModel, Extra, Field, validator 8 | except ModuleNotFoundError: # pragma: no cover 9 | from pydantic import BaseModel, Extra, Field, validator # type: ignore 10 | 11 | from typing_extensions import TypeAlias 12 | 13 | InputAttrs: TypeAlias = Dict[str, Any] 14 | 15 | 16 | class ThemeEnum(str, Enum): 17 | """Flatpickr theme options.""" 18 | 19 | dark = "dark" 20 | material_blue = "material_blue" 21 | material_green = "material_green" 22 | material_red = "material_red" 23 | material_orange = "material_orange" 24 | airbnb = "airbnb" 25 | confetti = "confetti" 26 | 27 | 28 | class FlatpickrOptions(BaseModel, extra=Extra.allow): 29 | """Flatpickr options to create flatpickr instance.""" 30 | 31 | allowInput: Optional[bool] 32 | allowInvalidPreload: Optional[bool] 33 | altFormat: Optional[str] 34 | altInput: bool = True 35 | altInputClass: Optional[str] 36 | ariaDateFormat: Optional[str] 37 | clickOpens: Optional[bool] 38 | dateFormat: Optional[str] 39 | defaultDate: Optional[str] 40 | defaultHour: Optional[int] = Field(ge=0, le=23) 41 | defaultMinute: Optional[int] = Field(ge=0, le=59) 42 | disable: Optional[List[str]] 43 | disableMobile: Optional[bool] 44 | enable: Optional[List[str]] 45 | enableSeconds: Optional[bool] 46 | enableTime: Optional[bool] 47 | hourIncrement: Optional[int] = Field(ge=1, le=12) 48 | inline: Optional[bool] 49 | locale: Optional[str] 50 | maxDate: Optional[str] 51 | minDate: Optional[str] 52 | minuteIncrement: Optional[int] = Field(ge=0, le=59) 53 | mode: Optional[str] 54 | monthSelectorType: Optional[str] 55 | nextArrow: Optional[str] 56 | noCalendar: Optional[bool] 57 | position: Optional[str] 58 | prevArrow: Optional[str] 59 | shorthandCurrentMonth: Optional[bool] 60 | showMonths: Optional[int] = Field(ge=1, le=12) 61 | static: Optional[bool] 62 | time_24hr: Optional[bool] 63 | weekNumbers: Optional[bool] 64 | wrap: bool = True 65 | 66 | @validator("mode") 67 | def _disallow_mode(cls, v: str) -> NoReturn: 68 | raise ValueError( 69 | "Option mode is reserved and always set to static." 70 | " For range mode see how to use range picker in django-flatpickr docs" 71 | ) 72 | 73 | @validator("dateFormat") 74 | def _disallow_dateFormat(cls, v: str) -> NoReturn: 75 | raise ValueError( 76 | "Option dateFormat is reserved and always set to Y-m-d." 77 | " Use altFormat to set date format selected by calendar" 78 | ) 79 | 80 | @validator("altInput") 81 | def _disallow_altInput(cls, v: str) -> NoReturn: 82 | raise ValueError("Option altInput is reserved and always set to True.") 83 | 84 | @validator("wrap") 85 | def _disallow_wrap(cls, v: str) -> NoReturn: 86 | raise ValueError("Option wrap is reserved and always set to True.") 87 | 88 | @validator("enableTime") 89 | def _disallow_enableTime(cls, v: str) -> NoReturn: 90 | raise ValueError("Option enableTime is reserved and set based on widget used.") 91 | 92 | @validator("noCalendar") 93 | def _disallow_noCalendar(cls, v: str) -> NoReturn: 94 | raise ValueError("Option noCalendar is reserved and set based on widget used.") 95 | -------------------------------------------------------------------------------- /src/django_flatpickr/settings.py: -------------------------------------------------------------------------------- 1 | """Package settings.""" 2 | import functools 3 | from typing import Any, Dict, Optional, Tuple 4 | 5 | from django.conf import settings as django_settings 6 | 7 | try: 8 | from pydantic.v1 import Field 9 | from pydantic.v1.env_settings import BaseSettings, SettingsSourceCallable 10 | except ModuleNotFoundError: # pragma: no cover 11 | from pydantic import Field # type: ignore 12 | from pydantic.env_settings import ( # type: ignore 13 | BaseSettings, 14 | SettingsSourceCallable, 15 | ) 16 | 17 | from .schemas import FlatpickrOptions, ThemeEnum 18 | 19 | 20 | def _django_settings_source(settings: BaseSettings) -> Dict[str, Any]: 21 | return getattr(django_settings, "DJANGO_FLATPICKR", {}) 22 | 23 | 24 | class DjangoFlatpickrSettings(BaseSettings): 25 | """Package settings to customize inputs.""" 26 | 27 | theme_name: Optional[ThemeEnum] 28 | theme_url: Optional[str] 29 | template_name: Optional[str] 30 | attrs: Dict[str, str] = {} 31 | options = FlatpickrOptions() 32 | flatpickr_cdn_url = "https://cdn.jsdelivr.net/npm/flatpickr@4.6.13/dist/" 33 | app_static_url = "https://cdn.jsdelivr.net/gh/monim67/django-flatpickr@2.0.0/src/django_flatpickr/static/django_flatpickr/" 34 | debug: bool = Field(default_factory=lambda: getattr(django_settings, "DEBUG", True)) 35 | 36 | class Config: 37 | """Customize pydantic config.""" 38 | 39 | env_prefix = "DJANGO_FLATPICKR_" 40 | 41 | @classmethod 42 | def customise_sources( 43 | cls, 44 | init_settings: SettingsSourceCallable, 45 | env_settings: SettingsSourceCallable, 46 | file_secret_settings: SettingsSourceCallable, 47 | ) -> Tuple[SettingsSourceCallable, ...]: 48 | """Add django settings as config source.""" 49 | return ( 50 | init_settings, 51 | env_settings, 52 | file_secret_settings, 53 | _django_settings_source, 54 | ) 55 | 56 | 57 | @functools.lru_cache(maxsize=1) 58 | def get_django_flatpickr_settings() -> DjangoFlatpickrSettings: 59 | """Initialize and return DjangoFlatpickrSettings.""" 60 | return DjangoFlatpickrSettings() 61 | -------------------------------------------------------------------------------- /src/django_flatpickr/static/django_flatpickr/js/django-flatpickr.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | (function () { 4 | if (window.isFlatpickrInitialized) return; 5 | window.isFlatpickrInitialized = true; 6 | /** 7 | * @typedef {object} FlatpickrInstance 8 | * @property {Date[]} selectedDates 9 | * @property {boolean} isMobile 10 | * @property {HTMLInputElement?} mobileInput 11 | * @property {FlatpickrOptions} config 12 | * 13 | * @typedef {object} FlatpickrOptions 14 | * @property {FlatpickrHookFunction[]} onChange 15 | * 16 | * @callback FlatpickrHookFunction 17 | * @param {Date[]} selectedDates 18 | * @param {string} dateStr 19 | * @param {FlatpickrInstance} instance 20 | * 21 | * @typedef {object} DjangoFlatpickrConfig 22 | * @property {string} range_from 23 | * @property {FlatpickrOptions} options 24 | */ 25 | 26 | /** @type {WeakMap} */ 27 | const flatpickrInstances = new WeakMap(); 28 | class DjangoFlatpickrError extends Error { 29 | /** 30 | * @param {HTMLInputElement} inputElement 31 | * @param {string} message 32 | */ 33 | constructor(inputElement, message) { 34 | super(`input name: ${inputElement.name}; ${message}`); 35 | this.name = "django-flatpickr error"; 36 | this.inputElement = inputElement 37 | } 38 | } 39 | 40 | /** 41 | * @param {DjangoFlatpickrError} err 42 | */ 43 | function handleError(err) { 44 | if (err.inputElement.hasAttribute('data-debug')) { 45 | const errDisplay = document.createElement("b"); 46 | errDisplay.innerHTML = "Check browser console for errors, Set django DEBUG=False to hide this error message"; 47 | errDisplay.style.color = "red"; 48 | err.inputElement.after(errDisplay); 49 | } 50 | throw err; 51 | } 52 | 53 | document.addEventListener('DOMContentLoaded', function (event) { 54 | findAndProcessFlatpickrInputs(document); 55 | document.addEventListener('DOMNodeInserted', function (event) { 56 | setTimeout(() => { 57 | if (event.target.querySelectorAll) findAndProcessFlatpickrInputs(event.target); 58 | }); 59 | }); 60 | }); 61 | 62 | /** 63 | * @param {HTMLElement} htmlElement 64 | */ 65 | function findAndProcessFlatpickrInputs(htmlElement) { 66 | /** @type {NodeListOf} */ 67 | const inputElements = htmlElement.querySelectorAll('[data-fpconfig]:not([disabled])') 68 | for (const inputElement of inputElements) { 69 | try { 70 | if (typeof flatpickr == 'function') { 71 | createFlatpickrInstance(inputElement); 72 | } else { 73 | throw Error('flatpickr js/css resources was not loaded, please check your CDN links'); 74 | } 75 | } 76 | catch (err) { 77 | handleError(new DjangoFlatpickrError(inputElement, err.message)); 78 | } 79 | } 80 | } 81 | 82 | /** 83 | * @param {HTMLInputElement} inputElement 84 | */ 85 | function createFlatpickrInstance(inputElement) { 86 | const config = getConfig(inputElement); 87 | const inputWrapper = inputElement.closest('.django-flatpickr'); 88 | if (!inputWrapper) throw Error('input must have a parent with class="django-flatpickr"') 89 | inputElement.setAttribute('data-input', ''); 90 | /** @type {FlatpickrInstance} */ 91 | const flatpickrInstance = flatpickr(inputWrapper, config.options); 92 | flatpickrInstances.set(inputElement, flatpickrInstance); 93 | 94 | if (config.range_from) { 95 | const flatpickrRangeFromInstance = getRangeFromInputElement(inputElement, config); 96 | if (flatpickrRangeFromInstance) { 97 | configureRangeSelection(flatpickrRangeFromInstance, flatpickrInstance); 98 | } 99 | } 100 | } 101 | 102 | /** 103 | * @param {HTMLInputElement} inputElement 104 | */ 105 | function getConfig(inputElement) { 106 | let /** @type {DjangoFlatpickrConfig} */ config; 107 | try { 108 | config = JSON.parse(inputElement.getAttribute('data-fpconfig')); 109 | } 110 | catch (err) { throw Error("Invalid config") } 111 | const optionKeyName = inputElement.name.replace(/^(.*-)?/, "djangoFlatpickrOptions_") 112 | config.options = { ...window.djangoFlatpickrOptions, ...window[optionKeyName], ...config.options }; 113 | return config; 114 | } 115 | 116 | /** 117 | * @param {HTMLInputElement} inputElement 118 | * @param {DjangoFlatpickrConfig} config 119 | */ 120 | function getRangeFromInputElement(inputElement, config) { 121 | const rangeFromInputName = inputElement.name.replace(/[^-]+$/, config.range_from); 122 | let fromInputElement = inputElement.form?.elements.namedItem(rangeFromInputName); 123 | if (!fromInputElement) { 124 | const elements = document.querySelectorAll(`input[name="${config.range_from}"]`); 125 | if (elements.length == 0) throw Error("range_from not found"); 126 | if (elements.length > 1) throw Error("Multiple range_from found"); 127 | fromInputElement = elements[0]; 128 | } 129 | if (flatpickrInstances.has(fromInputElement)) { 130 | return flatpickrInstances.get(fromInputElement); 131 | } else { 132 | throw Error(`range_from "${config.range_from}" is not a flatpickr input`); 133 | } 134 | } 135 | 136 | /** 137 | * @param {FlatpickrInstance} fromInstance 138 | * @param {FlatpickrInstance} toInstance 139 | */ 140 | function configureRangeSelection(fromInstance, toInstance) { 141 | registerOnTimeValueChange(fromInstance, function (selectedDates) { 142 | toInstance.set('minDate', selectedDates[0] || false); 143 | if (fromInstance.isMobile && toInstance.isMobile) { 144 | toInstance.mobileInput.min = fromInstance.mobileInput.value; 145 | } 146 | }); 147 | registerOnTimeValueChange(toInstance, function (selectedDates) { 148 | fromInstance.set('maxDate', selectedDates[0] || false); 149 | if (fromInstance.isMobile && toInstance.isMobile) { 150 | fromInstance.mobileInput.max = toInstance.mobileInput.value; 151 | } 152 | }); 153 | } 154 | 155 | /** 156 | * Fires onChange event only when there's change in the time value 157 | * of selectedDate[0], otherwise drops the onChange event 158 | * @param {FlatpickrInstance} instance 159 | * @param {FlatpickrHookFunction} hookFunction 160 | */ 161 | function registerOnTimeValueChange(instance, hookFunction) { 162 | let oldTimeValue = getTimeValue(instance.selectedDates); 163 | hookFunction(instance.selectedDates); 164 | instance.config.onChange.push(function (selectedDates) { 165 | const newTimeValue = getTimeValue(selectedDates); 166 | if (newTimeValue !== oldTimeValue) { 167 | oldTimeValue = newTimeValue; 168 | hookFunction(selectedDates); 169 | } 170 | }); 171 | } 172 | 173 | /** 174 | * Get time value of selectedDate[0] 175 | * @param {Date[]} selectedDates 176 | */ 177 | function getTimeValue(selectedDates) { 178 | return selectedDates.length ? selectedDates[0].getTime() : 0; 179 | } 180 | })(); 181 | -------------------------------------------------------------------------------- /src/django_flatpickr/templates/django_flatpickr/input.html: -------------------------------------------------------------------------------- 1 |
2 | {% include 'django/forms/widgets/text.html' %} 3 |
-------------------------------------------------------------------------------- /src/django_flatpickr/widgets.py: -------------------------------------------------------------------------------- 1 | """Widgets for flatpickr inputs.""" 2 | 3 | from django_flatpickr._base import BasePickerInput 4 | 5 | __all__ = ( 6 | "DatePickerInput", 7 | "TimePickerInput", 8 | "DateTimePickerInput", 9 | ) 10 | 11 | 12 | class DatePickerInput(BasePickerInput): 13 | """Widget for DateField to display a Date-Picker Calendar. 14 | 15 | Args: 16 | attrs: HTML attributes of rendered HTML input 17 | options: Options to customize the widget, see Docs 18 | range_from: Name of input to link for range selection 19 | """ 20 | 21 | picker_type = "DATE" 22 | datetime_format = "%Y-%m-%d" 23 | format_key = "DATE_INPUT_FORMATS" 24 | 25 | 26 | class TimePickerInput(BasePickerInput): 27 | """Widget for TimeField to display a Time-Picker Calendar. 28 | 29 | Args: 30 | attrs: HTML attributes of rendered HTML input 31 | options: Options to customize the widget, see Docs 32 | range_from: Name of input to link for range selection 33 | """ 34 | 35 | picker_type = "TIME" 36 | datetime_format = "%H:%M:%S" 37 | format_key = "TIME_INPUT_FORMATS" 38 | _option_overrides = { 39 | "dateFormat": "H:i:S", 40 | "enableTime": True, 41 | "noCalendar": True, 42 | } 43 | 44 | 45 | class DateTimePickerInput(BasePickerInput): 46 | """Widget for DateTimeField to display a DateTime-Picker Calendar. 47 | 48 | Args: 49 | attrs: HTML attributes of rendered HTML input 50 | options: Options to customize the widget, see Docs 51 | range_from: Name of input to link for range selection 52 | """ 53 | 54 | picker_type = "DATETIME" 55 | datetime_format = "%Y-%m-%d %H:%M:%S" 56 | format_key = "DATETIME_INPUT_FORMATS" 57 | _option_overrides = { 58 | "dateFormat": "Y-m-d H:i:S", 59 | "enableTime": True, 60 | } 61 | -------------------------------------------------------------------------------- /tests/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/monim67/django-flatpickr/1d96d524cc5924bd3f7f980ac0634fc0317eefff/tests/__init__.py -------------------------------------------------------------------------------- /tests/conftest.py: -------------------------------------------------------------------------------- 1 | """Fixtures for tests.""" 2 | 3 | from typing import Iterable 4 | 5 | import pytest 6 | from pytest_django.fixtures import SettingsWrapper 7 | 8 | from django_flatpickr.settings import get_django_flatpickr_settings 9 | 10 | 11 | @pytest.fixture 12 | def settings(settings: SettingsWrapper) -> Iterable[SettingsWrapper]: 13 | """Override pytest-django settings to clear get_django_flatpickr_settings cache.""" 14 | get_django_flatpickr_settings.cache_clear() 15 | yield settings 16 | get_django_flatpickr_settings.cache_clear() 17 | -------------------------------------------------------------------------------- /tests/pip-constraints.txt: -------------------------------------------------------------------------------- 1 | django==5.* ; python_version >= "3.11" 2 | django==4.* ; python_version >= "3.10" and python_version < "3.11" 3 | django==3.* ; python_version >= "3.9" and python_version < "3.10" 4 | django==2.* ; python_version < "3.9" 5 | -------------------------------------------------------------------------------- /tests/test_demo.py: -------------------------------------------------------------------------------- 1 | import shutil 2 | from pathlib import Path 3 | 4 | from pytest_django.live_server_helper import LiveServer 5 | from pywebcopy import save_website 6 | 7 | 8 | def test_build(live_server: LiveServer) -> None: 9 | pages = Path.cwd() / "pages" 10 | if pages.exists(): 11 | shutil.rmtree(pages) 12 | save_website( 13 | url=live_server.url, 14 | project_folder=str(pages.parent), 15 | project_name=pages.name, 16 | bypass_robots=True, 17 | ) 18 | pages.joinpath("localhost").replace(pages / "demo") 19 | url_replacements = [ 20 | ( 21 | "../github.com/monim67/django-flatpickr", 22 | "https://github.com/monim67/django-flatpickr", 23 | ), 24 | ( 25 | "../bulma.io/957351442", 26 | "https://bulma.io/", 27 | ), 28 | ( 29 | "/static/django_flatpickr/", 30 | "/django-flatpickr/demo/static/django_flatpickr/", 31 | ), 32 | ] 33 | mjs_file = pages / "demo/static/django_flatpickr/js/django-flatpickr.js.mjs" 34 | if mjs_file.exists(): 35 | mjs_file.rename(mjs_file.with_suffix("")) 36 | for file in pages.glob("demo/*.html"): 37 | file_text = file.read_text() 38 | for search_text, replace_text in url_replacements: 39 | file_text = file_text.replace(search_text, replace_text) 40 | file.write_text(file_text) 41 | -------------------------------------------------------------------------------- /tests/test_flatpickr_options.py: -------------------------------------------------------------------------------- 1 | import pytest 2 | 3 | from django_flatpickr._base import BasePickerInput 4 | from django_flatpickr.schemas import FlatpickrOptions 5 | 6 | 7 | def test_invalid_options_shouldnt_be_set_as_class_property() -> None: 8 | class TestInput(BasePickerInput): 9 | options = "Not a FlatpickrOptions instance" # type: ignore 10 | 11 | with pytest.raises(ValueError): 12 | TestInput() 13 | 14 | 15 | def test_invalid_options_shouldnt_be_passed_as_parameter() -> None: 16 | with pytest.raises(ValueError): 17 | BasePickerInput(options="Not a FlatpickrOptions instance") # type: ignore 18 | 19 | 20 | def test_reserved_options_shouldnt_be_set_by_user() -> None: 21 | with pytest.raises(ValueError): 22 | FlatpickrOptions(mode="range") 23 | with pytest.raises(ValueError): 24 | FlatpickrOptions(dateFormat="Y") 25 | with pytest.raises(ValueError): 26 | FlatpickrOptions(enableTime=False) 27 | with pytest.raises(ValueError): 28 | FlatpickrOptions(noCalendar=False) 29 | with pytest.raises(ValueError): 30 | FlatpickrOptions(altInput=False) 31 | with pytest.raises(ValueError): 32 | FlatpickrOptions(wrap=False) 33 | -------------------------------------------------------------------------------- /tests/test_input_attrs.py: -------------------------------------------------------------------------------- 1 | from pytest_django.fixtures import SettingsWrapper 2 | 3 | from django_flatpickr._base import BasePickerInput 4 | 5 | 6 | def test_fpconfig_passed_to_input_attr() -> None: 7 | fp_input = BasePickerInput() 8 | assert "data-fpconfig" in fp_input.build_attrs({}) 9 | 10 | 11 | def test_presence_of_debug_attr_when_debug_true(settings: SettingsWrapper) -> None: 12 | settings.DEBUG = True 13 | fp_input = BasePickerInput() 14 | assert "data-debug" in fp_input.build_attrs({}) 15 | 16 | 17 | def test_absence_of_debug_attr_when_debug_false(settings: SettingsWrapper) -> None: 18 | settings.DEBUG = False 19 | fp_input = BasePickerInput() 20 | assert "data-debug" not in fp_input.build_attrs({}) 21 | 22 | 23 | def test_absence_of_debug_attr_when_debug_overrides(settings: SettingsWrapper) -> None: 24 | settings.DEBUG = True 25 | settings.DJANGO_FLATPICKR = {"debug": False} 26 | fp_input = BasePickerInput() 27 | assert "data-debug" not in fp_input.build_attrs({}) 28 | -------------------------------------------------------------------------------- /tests/test_media.py: -------------------------------------------------------------------------------- 1 | from pytest_django.fixtures import SettingsWrapper 2 | 3 | from django_flatpickr._base import BasePickerInput 4 | from django_flatpickr.schemas import FlatpickrOptions 5 | 6 | 7 | def test_media_render_with_default_options() -> None: 8 | fp_input = BasePickerInput() 9 | fp_input.media.render() 10 | 11 | 12 | def test_presence_of_theme_url_in_rendered_media(settings: SettingsWrapper) -> None: 13 | theme_url = "http://localhost/xxxxxx" 14 | settings.DJANGO_FLATPICKR = {"theme_url": theme_url} 15 | fp_input = BasePickerInput() 16 | assert theme_url in fp_input.media.render() 17 | 18 | 19 | def test_presence_of_local_file_in_rendered_media() -> None: 20 | locale = "xxxxxx" 21 | fp_input = BasePickerInput(options=FlatpickrOptions(locale=locale)) 22 | assert locale in fp_input.media.render() 23 | --------------------------------------------------------------------------------