├── src └── graia │ └── scheduler │ ├── exception.py │ ├── saya │ ├── __init__.py │ ├── schema.py │ ├── behaviour.py │ └── shortcut.py │ ├── service.py │ ├── utilles.py │ ├── creator.py │ ├── __init__.py │ ├── timers.py │ └── task.py ├── docs ├── requirements.txt ├── assets │ ├── curtain.css │ ├── chat.css │ ├── admonition.js │ └── extra.css ├── overrides │ ├── partials │ │ ├── social.html │ │ └── copyright.html │ └── .icons │ │ └── netlify.svg └── gen_ref.py ├── .vscode └── settings.json ├── example.py ├── .github └── workflows │ ├── release.yml │ └── deploy-docs.yml ├── README.md ├── pyproject.toml ├── mkdocs.yml ├── .gitignore └── pdm.lock /src/graia/scheduler/exception.py: -------------------------------------------------------------------------------- 1 | class AlreadyStarted(Exception): 2 | """本 SchedulerTask 已经被启动了.""" 3 | 4 | pass 5 | -------------------------------------------------------------------------------- /src/graia/scheduler/saya/__init__.py: -------------------------------------------------------------------------------- 1 | from .behaviour import GraiaSchedulerBehaviour as GraiaSchedulerBehaviour 2 | from .schema import SchedulerSchema as SchedulerSchema 3 | -------------------------------------------------------------------------------- /docs/requirements.txt: -------------------------------------------------------------------------------- 1 | mkdocstrings[python]>=0.18.0 2 | mkdocs-gen-files>=0.3.0 3 | mkdocs-literate-nav>=0.4.0 4 | mkdocs-section-index>=0.3.0 5 | mkdocs-material>=8.2.0 6 | black>=22.3.0 7 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "python.pythonPath": "c:\\Users\\Elaina\\AppData\\Local\\pypoetry\\Cache\\virtualenvs\\graia-scheduler-ytw8Y8am-py3.8\\Scripts\\python.exe", 3 | "python.formatting.provider": "black" 4 | } -------------------------------------------------------------------------------- /docs/assets/curtain.css: -------------------------------------------------------------------------------- 1 | html .curtain 2 | { 3 | transition: 0.125s linear; 4 | background-color: var(--md-code-fg-color); 5 | color: var(--md-code-fg-color); 6 | text-shadow: none; 7 | text-decoration-line: none; 8 | border-radius: 0.18rem; 9 | } 10 | 11 | html .curtain:hover { 12 | transition: 0.125s linear; 13 | color: var(--md-code-bg-color); 14 | } 15 | -------------------------------------------------------------------------------- /docs/assets/chat.css: -------------------------------------------------------------------------------- 1 | html .chat { 2 | clear: both; 3 | padding: 10px; 4 | border-radius: 20px; 5 | margin-bottom: 2px; 6 | color: var(--md-default-bg-color); 7 | font-family: var(--md-code-font-family); 8 | } 9 | 10 | html .left { 11 | float: left; 12 | background: var(--md-code-hl-function-color); 13 | border-top-left-radius: 2px; 14 | } 15 | 16 | html .right { 17 | float: right; 18 | background: var(--md-code-hl-keyword-color); 19 | border-top-right-radius: 2px; 20 | } 21 | -------------------------------------------------------------------------------- /src/graia/scheduler/saya/schema.py: -------------------------------------------------------------------------------- 1 | from dataclasses import dataclass, field 2 | from typing import List 3 | 4 | from graia.broadcast.entities.decorator import Decorator 5 | from graia.broadcast.typing import T_Dispatcher 6 | from graia.saya.schema import BaseSchema 7 | 8 | from .. import Timer 9 | 10 | 11 | @dataclass 12 | class SchedulerSchema(BaseSchema): 13 | timer: Timer 14 | cancelable: bool = field(default=False) 15 | decorators: List[Decorator] = field(default_factory=list) 16 | dispatchers: List[T_Dispatcher] = field(default_factory=list) 17 | -------------------------------------------------------------------------------- /example.py: -------------------------------------------------------------------------------- 1 | from launart import Launart 2 | from graia.broadcast import Broadcast 3 | from graia.scheduler import GraiaScheduler 4 | from graia.scheduler.timers import crontabify 5 | from graia.scheduler.service import SchedulerService 6 | from creart import it 7 | 8 | bcc = it(Broadcast) 9 | scheduler = it(GraiaScheduler) 10 | 11 | 12 | @scheduler.schedule(crontabify("* * * * * *")) 13 | def something_scheduled(): 14 | print("print every second.") 15 | 16 | 17 | manager = Launart() 18 | manager.add_component(SchedulerService(scheduler)) 19 | 20 | manager.launch_blocking() 21 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: Python package 2 | on: 3 | push: 4 | tags: 5 | - "v*.*.*" 6 | jobs: 7 | build: 8 | runs-on: ubuntu-latest 9 | steps: 10 | - uses: actions/checkout@v2 11 | - uses: actions/setup-python@v3 12 | name: Ensure Python Runtime 13 | with: 14 | python-version: '3.x' 15 | architecture: 'x64' 16 | - name: Ensure PDM & twine 17 | run: | 18 | python3 -m pip install pdm twine 19 | - name: Build Package 20 | run: | 21 | pdm build 22 | - name: Publish to PyPI 23 | run: | 24 | twine upload dist/* --non-interactive -u __token__ -p ${{ secrets.PYPI_TOKEN }} -------------------------------------------------------------------------------- /docs/overrides/partials/social.html: -------------------------------------------------------------------------------- 1 | 2 |
3 | {% for social in config.extra.social %} 4 | {% set title = social.name %} 5 | {% if not title and "//" in social.link %} 6 | {% set _, url = social.link.split("//")%} 7 | {% set title = url.split("/")[0] %} 8 | {% endif %} 9 | 10 | 18 | 19 | {% endfor %} 20 |
21 | -------------------------------------------------------------------------------- /docs/overrides/partials/copyright.html: -------------------------------------------------------------------------------- 1 | 27 | -------------------------------------------------------------------------------- /docs/assets/admonition.js: -------------------------------------------------------------------------------- 1 | 2 | const admonition_titles = document.getElementsByClassName("admonition-title") 3 | for (let i = 0; i < admonition_titles.length; i++) { 4 | let color = window.getComputedStyle(admonition_titles[i]).borderColor 5 | admonition_titles[i].style.color = color 6 | } 7 | const admonition_summaries = document.getElementsByTagName("SUMMARY") 8 | for (let i = 0; i < admonition_summaries.length; i++) { 9 | let color = window.getComputedStyle(admonition_summaries[i]).borderColor 10 | admonition_summaries[i].style.color = color 11 | } 12 | 13 | function reload_color() { 14 | var p = localStorage.getItem("data-md-color-primary"); 15 | if (p) { 16 | document.body.setAttribute('data-md-color-primary', p); 17 | } 18 | var a = localStorage.getItem("data-md-color-accent"); 19 | if (a) { 20 | document.body.setAttribute('data-md-color-accent', a); 21 | } 22 | } 23 | 24 | window.addEventListener('change', reload_color, false); 25 | window.addEventListener('load', reload_color, false); 26 | -------------------------------------------------------------------------------- /docs/gen_ref.py: -------------------------------------------------------------------------------- 1 | """Generate the code reference pages and navigation.""" 2 | import sys 3 | from pathlib import Path 4 | 5 | import mkdocs_gen_files 6 | 7 | nav = mkdocs_gen_files.Nav() 8 | 9 | fe = mkdocs_gen_files.FilesEditor.current() 10 | 11 | root = Path(__file__).parent.parent 12 | 13 | src = (root / "src").resolve() 14 | 15 | sys.path.append(src.as_posix()) 16 | 17 | for path in sorted(Path(src, "graia").glob("**/*.py")): 18 | module_path = path.relative_to(src).with_suffix("") 19 | doc_path = path.relative_to(src).with_suffix(".md") 20 | full_doc_path = path.relative_to(src / "graia" / "scheduler").with_suffix(".md") 21 | 22 | parts = list(module_path.parts) 23 | if parts[-1] == "__init__": 24 | parts = parts[:-1] 25 | doc_path = doc_path.with_name("index.md") 26 | full_doc_path = full_doc_path.with_name("index.md") 27 | elif parts[-1] == "__main__" or parts[-1].startswith("_"): 28 | continue 29 | nav[parts] = full_doc_path 30 | 31 | with fe.open(full_doc_path, "w") as f: 32 | print(f"::: {'.'.join(parts)}", file=f) 33 | 34 | fe.set_edit_path(full_doc_path, path) 35 | 36 | with fe.open("NAV.md", "w") as nav_file: 37 | nav_file.writelines(nav.build_literate_nav()) 38 | -------------------------------------------------------------------------------- /src/graia/scheduler/service.py: -------------------------------------------------------------------------------- 1 | from typing import Literal, Set 2 | from launart import Service, Launart 3 | from . import GraiaScheduler 4 | import asyncio 5 | 6 | 7 | class SchedulerService(Service): 8 | """GraiaScheduler 的 Launart 服务 9 | 10 | Args: 11 | scheduler (GraiaScheduler): 任务计划器 12 | """ 13 | 14 | id = "scheduler.service" 15 | 16 | def __init__(self, scheduler: GraiaScheduler) -> None: 17 | super().__init__() 18 | self.scheduler = scheduler 19 | 20 | @property 21 | def required(self): 22 | return set() 23 | 24 | @property 25 | def stages(self) -> Set[Literal["preparing", "blocking", "cleanup"]]: 26 | return {"preparing", "blocking", "cleanup"} 27 | 28 | async def launch(self, manager: Launart): 29 | async with self.stage("preparing"): 30 | pass # Wait for preparation to complete, then we run tasks 31 | async with self.stage("blocking"): 32 | tsk = asyncio.create_task(self.scheduler.run()) 33 | await manager.status.wait_for_sigexit() 34 | async with self.stage("cleanup"): 35 | # Stop all schedule tasks 36 | self.scheduler.stop() 37 | await self.scheduler.join() 38 | await tsk 39 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Graia Scheduler 2 | 3 | 一个基于 `asyncio`, 设计简洁, 代码简单的计划任务库, 使用 `loop.create_task` 创建计划任务; 4 | 同时使用生成器特性与 `croniter` 的定时设计, 轻盈而强大. 5 | 6 | ## Install 7 | 8 | ```bash 9 | pip install graia-scheduler 10 | 11 | # or use pdm 12 | pdm add graia-scheduler 13 | ``` 14 | 15 | ## 使用 16 | 17 | **0.1以前的版本:** 18 | 19 | ```python 20 | import asyncio 21 | from graia.broadcast import Broadcast 22 | from graia.scheduler import GraiaScheduler 23 | from graia.scheduler.timers import crontabify 24 | 25 | loop = asyncio.new_event_loop() 26 | 27 | bcc = Broadcast(loop=loop) 28 | scheduler = GraiaScheduler(loop, bcc) 29 | 30 | 31 | @scheduler.schedule(crontabify("* * * * * *")) 32 | def something_scheduled(): 33 | print("print every second.") 34 | 35 | loop.run_forever() 36 | ``` 37 | 38 | **0.1及后续的版本:** 39 | 40 | ```python 41 | import asyncio 42 | from graia.broadcast import Broadcast 43 | from graia.scheduler import GraiaScheduler 44 | from graia.scheduler.timers import crontabify 45 | 46 | loop = asyncio.new_event_loop() 47 | 48 | bcc = Broadcast(loop=loop) 49 | scheduler = GraiaScheduler(loop, bcc) 50 | 51 | 52 | @scheduler.schedule(crontabify("* * * * * *")) 53 | def something_scheduled(): 54 | print("print every second.") 55 | 56 | 57 | loop.run_until_complete(scheduler.run()) 58 | ``` 59 | 60 | 因为基于 `BroadcastControl`, 你可以享受使用 `Dispatcher`, `Interrupt`, `Decorator` 的开发体验. 61 | -------------------------------------------------------------------------------- /pyproject.toml: -------------------------------------------------------------------------------- 1 | [project] 2 | # PEP 621 project metadata 3 | # See https://www.python.org/dev/peps/pep-0621/ 4 | authors = [ 5 | {name = "GreyElaina", email = "31543961+GreyElaina@users.noreply.github.com"}, 6 | ] 7 | license = {text = "MIT"} 8 | requires-python = ">=3.8,<4.0" 9 | dependencies = [ 10 | "graia-broadcast~=0.23.0", 11 | "croniter<2.0.0,>=1.0.0", 12 | "launart>=0.7.0", 13 | "creart~=0.3.0", 14 | ] 15 | name = "graia-scheduler" 16 | version = "0.3.1" 17 | description = "a scheduler for graia framework" 18 | readme = "README.md" 19 | [project.optional-dependencies] 20 | saya = ["graia-saya>=0.0.16,<0.1"] 21 | 22 | [project.entry-points."creart.creators"] 23 | scheduler = "graia.scheduler.creator:SchedulerCreator" 24 | scheduler_behaviour = "graia.scheduler.creator:SchedulerBehaviourCreator" 25 | 26 | [tool.pdm] 27 | 28 | [tool.pdm.dev-dependencies] 29 | dev = [ 30 | "black>=22.6.0", 31 | "isort>=5.10.1", 32 | "graia-saya>=0.0.16", 33 | ] 34 | docs = [ 35 | "mkdocs-material>=8.2.0", 36 | "mkdocstrings[python]>=0.18.0", 37 | "mkdocs-literate-nav>=0.4.0", 38 | "mkdocs-section-index>=0.3.0", 39 | "mkdocs-gen-files>=0.3.0", 40 | ] 41 | 42 | [tool.pdm.build] 43 | includes = ["src/graia"] 44 | 45 | [tool.isort] 46 | profile = "black" 47 | 48 | [build-system] 49 | requires = ["pdm-backend"] 50 | build-backend = "pdm.backend" 51 | 52 | [tool.pyright] 53 | ignore = ["docs/gen_ref.py"] 54 | -------------------------------------------------------------------------------- /src/graia/scheduler/saya/behaviour.py: -------------------------------------------------------------------------------- 1 | from typing import Any, Union 2 | 3 | from graia.saya.behaviour import Behaviour 4 | from graia.saya.cube import Cube 5 | 6 | from graia.scheduler import GraiaScheduler 7 | from graia.scheduler.saya.schema import SchedulerSchema 8 | 9 | 10 | class GraiaSchedulerBehaviour(Behaviour): 11 | scheduler: GraiaScheduler 12 | 13 | def __init__(self, scheduler: GraiaScheduler) -> None: 14 | self.scheduler = scheduler 15 | 16 | def allocate(self, cube: Cube[SchedulerSchema]): 17 | if isinstance(cube.metaclass, SchedulerSchema): 18 | self.scheduler.schedule( 19 | cube.metaclass.timer, 20 | cube.metaclass.cancelable, 21 | cube.metaclass.dispatchers, 22 | cube.metaclass.decorators, 23 | )(cube.content) 24 | else: 25 | return 26 | 27 | return True 28 | 29 | def release(self, cube: Cube) -> Any: 30 | if isinstance(cube.metaclass, SchedulerSchema): 31 | target_tasks = list( 32 | filter( 33 | lambda x: x.target is cube.content, self.scheduler.schedule_tasks 34 | ) 35 | ) 36 | if target_tasks: 37 | target = target_tasks[0] 38 | target.stop_gen_interval() 39 | target.stop() 40 | self.scheduler.schedule_tasks.remove(target) 41 | else: 42 | return 43 | 44 | return True 45 | 46 | uninstall = release 47 | -------------------------------------------------------------------------------- /.github/workflows/deploy-docs.yml: -------------------------------------------------------------------------------- 1 | name: Deploy Documentation 2 | on: 3 | push: 4 | branches: 5 | - "!dependabot/**" 6 | - "*" 7 | jobs: 8 | deploy-docs: 9 | runs-on: ubuntu-latest 10 | steps: 11 | - name: Checkout 12 | uses: actions/checkout@v3 13 | 14 | - name: Setup Python 15 | uses: actions/setup-python@v4 16 | with: 17 | python-version: 3.9 18 | 19 | - name: Setup Document Dependencies 20 | run: | 21 | pip install -r ./docs/requirements.txt 22 | 23 | - name: Build with MKDocs 24 | run: | 25 | mkdocs build 26 | 27 | - name: Deploy to Cloudflare Pages 28 | uses: cloudflare/pages-action@1 29 | with: 30 | apiToken: ${{ secrets.CF_PAGES_TOKEN }} 31 | accountId: ${{ secrets.CF_ACCOUNT_ID }} 32 | projectName: graia-scheduler 33 | directory: site 34 | gitHubToken: ${{ secrets.GITHUB_TOKEN }} 35 | 36 | - name: Deploy to Netlify 37 | uses: nwtgck/actions-netlify@v2 38 | with: 39 | publish-dir: './site' 40 | production-branch: master 41 | github-token: ${{ secrets.GITHUB_TOKEN }} 42 | deploy-message: "Deploy from GitHub Actions" 43 | github-deployment-environment: preview 44 | enable-pull-request-comment: true 45 | enable-commit-comment: false 46 | overwrites-pull-request-comment: true 47 | env: 48 | NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }} 49 | NETLIFY_SITE_ID: ${{ secrets.NETLIFY_SITE_ID }} 50 | timeout-minutes: 1 51 | -------------------------------------------------------------------------------- /src/graia/scheduler/utilles.py: -------------------------------------------------------------------------------- 1 | from datetime import datetime, time 2 | from typing import Union 3 | 4 | 5 | class EnteredRecord: 6 | def __init__(self) -> None: 7 | self.entered = False 8 | 9 | def __enter__(self) -> None: 10 | self.entered = True 11 | 12 | def __exit__(self, exc_type, exc_value, exc_traceback): 13 | self.entered = False 14 | 15 | 16 | def print_track_async(func): 17 | async def wrapper(*args, **kwargs): 18 | try: 19 | return await func(*args, **kwargs) 20 | except: 21 | import traceback 22 | 23 | traceback.print_exc() 24 | 25 | return wrapper 26 | 27 | 28 | TimeObject = Union[datetime, time, str, float] 29 | 30 | 31 | def to_datetime( 32 | base: TimeObject, 33 | ) -> datetime: 34 | """将适宜的对象转化为 datetime 类型. 35 | 36 | Args: 37 | base (TimeObject): 要转化的对象, 字符串应为 ISO 时间 / 日期格式, 浮点数为时间戳. 38 | 39 | Raises: 40 | ValueError: 字符串格式错误. 41 | 42 | Returns: 43 | datetime: 转化成的 datetime. 44 | """ 45 | start = datetime.now() 46 | if isinstance(base, datetime): 47 | return base 48 | elif isinstance(base, time): 49 | return datetime.fromisoformat(f"{start.date()} {base.isoformat()}") 50 | elif isinstance(base, float): 51 | return datetime.fromtimestamp(base) 52 | else: 53 | if "-" in base: # Base is from datetime.isoformat() 54 | return datetime.fromisoformat(base) 55 | elif ":" in base: # Base is from time.isoformat() 56 | return datetime.fromisoformat(f"{start.date()} {base}") 57 | else: 58 | raise ValueError("Expected an ISO style time string!") 59 | -------------------------------------------------------------------------------- /src/graia/scheduler/creator.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | import asyncio 4 | from typing import TYPE_CHECKING 5 | 6 | from creart import AbstractCreator, CreateTargetInfo, exists_module, it, mixin 7 | 8 | from . import GraiaScheduler 9 | 10 | if TYPE_CHECKING: 11 | from .saya.behaviour import GraiaSchedulerBehaviour 12 | 13 | 14 | class SchedulerCreator(AbstractCreator): 15 | targets = ( 16 | CreateTargetInfo( 17 | module="graia.scheduler", 18 | identify="GraiaScheduler", 19 | humanized_name="Graia Scheduler", 20 | description=" a simple but powerful scheduler based on asyncio & broadcast control", 21 | author=["GraiaProject@github"], 22 | ), 23 | ) 24 | 25 | @staticmethod 26 | def available() -> bool: 27 | return exists_module("graia.broadcast") 28 | 29 | @staticmethod 30 | def create(create_type: type[GraiaScheduler]) -> GraiaScheduler: 31 | from graia.broadcast import Broadcast 32 | 33 | return create_type(loop=it(asyncio.AbstractEventLoop), broadcast=it(Broadcast)) 34 | 35 | 36 | class SchedulerBehaviourCreator(AbstractCreator): 37 | targets = ( 38 | CreateTargetInfo( 39 | module="graia.scheduler.saya.behaviour", 40 | identify="GraiaSchedulerBehaviour", 41 | humanized_name="Saya for Graia Scheduler", 42 | description=" saya support for Graia Scheduler", 43 | author=["GraiaProject@github"], 44 | ), 45 | ) 46 | 47 | @staticmethod 48 | @mixin(SchedulerCreator) 49 | def available() -> bool: 50 | return exists_module("graia.saya") 51 | 52 | @staticmethod 53 | def create(create_type: type[GraiaSchedulerBehaviour]) -> GraiaSchedulerBehaviour: 54 | scheduler = it(GraiaScheduler) 55 | return create_type(scheduler) 56 | -------------------------------------------------------------------------------- /docs/assets/extra.css: -------------------------------------------------------------------------------- 1 | html .md-social a[title="QQ 群"] { 2 | color: #00acee; 3 | } 4 | 5 | html .md-social a[title="Graiax 社区"] { 6 | color: #ffc0cb; 7 | } 8 | 9 | html .md-social a[title="CloudFlare 镜像"] { 10 | color: #f78100; 11 | } 12 | 13 | html .md-social a[title="ReadTheDocs 镜像"] { 14 | color: #8ca1af; 15 | } 16 | 17 | html .md-social a[title="Netlify 镜像"] { 18 | color: #28afa0; 19 | } 20 | 21 | 22 | .md-social__link { 23 | font-size: auto; 24 | width: auto; 25 | } 26 | 27 | body { 28 | -webkit-font-smoothing: antialiased; 29 | -moz-osx-font-smoothing: grayscale; 30 | 31 | /* Font with fallback for code */ 32 | --md-code-font-family: var(--md-code-font, _), SFMono-Regular, Consolas, 33 | Menlo, var(--md-text-font, _); 34 | 35 | } 36 | 37 | ul.clear-list { 38 | list-style-type: none; 39 | margin: 0; 40 | padding: 0; 41 | } 42 | 43 | .mdx-switch button>code { 44 | cursor: pointer; 45 | transition: opacity 250ms; 46 | display: block; 47 | color: var(--md-primary-bg-color); 48 | background-color: var(--md-primary-fg-color); 49 | } 50 | 51 | :root { 52 | --md-admonition-icon--graiax: url('data:image/svg+xml;charset=utf-8,') 53 | } 54 | 55 | .md-typeset .admonition.graiax, 56 | .md-typeset details.graiax { 57 | border-color: #fd9bac; 58 | } 59 | 60 | .md-typeset .graiax>.admonition-title, 61 | .md-typeset .graiax>summary { 62 | background-color: #fd9bac0f; 63 | border-color: #fd9bac; 64 | } 65 | 66 | .md-typeset .graiax>.admonition-title::before, 67 | .md-typeset .graiax>summary::before { 68 | background-color: #fd9bac; 69 | -webkit-mask-image: var(--md-admonition-icon--graiax); 70 | mask-image: var(--md-admonition-icon--graiax); 71 | } 72 | 73 | /* Indentation. */ 74 | div.doc-contents:not(.first) { 75 | padding-left: 25px; 76 | border-left: .05rem solid var(--md-default-fg-color--lightest); 77 | margin-bottom: 80px; 78 | } 79 | 80 | 81 | .highlight .gp, 82 | .highlight .go { 83 | /* Generic.Prompt, Generic.Output */ 84 | user-select: none; 85 | } 86 | -------------------------------------------------------------------------------- /src/graia/scheduler/__init__.py: -------------------------------------------------------------------------------- 1 | from datetime import datetime 2 | from typing import Iterable, List, Optional 3 | 4 | from graia.broadcast.typing import T_Dispatcher 5 | 6 | Timer = Iterable[datetime] 7 | 8 | import asyncio 9 | from asyncio import AbstractEventLoop 10 | from typing import Callable, TypeVar 11 | 12 | from graia.broadcast import Broadcast 13 | from graia.broadcast.entities.decorator import Decorator 14 | 15 | from .task import SchedulerTask 16 | 17 | T_Callable = TypeVar("T_Callable", bound=Callable) 18 | 19 | 20 | class GraiaScheduler: 21 | """任务计划器""" 22 | 23 | loop: AbstractEventLoop 24 | schedule_tasks: List[SchedulerTask] 25 | broadcast: Broadcast 26 | 27 | def __init__(self, loop: AbstractEventLoop, broadcast: Broadcast) -> None: 28 | """初始化 29 | 30 | Args: 31 | loop (AbstractEventLoop): 事件循环 32 | broadcast (Broadcast): 事件总线 33 | """ 34 | self.schedule_tasks = [] 35 | self.loop = loop 36 | self.broadcast = broadcast 37 | 38 | def schedule( 39 | self, 40 | timer: Timer, 41 | cancelable: bool = False, 42 | dispatchers: Optional[List[T_Dispatcher]] = None, 43 | decorators: Optional[List[Decorator]] = None, 44 | ) -> Callable[[T_Callable], T_Callable]: 45 | """计划一个新任务. 46 | 47 | Args: 48 | timer (Timer): 该定时任务的计时器. 49 | cancelable (bool, optional): 能否取消该任务. 默认为 False. 50 | dispatchers (List[T_Dispatcher], optional): 该任务要使用的 Dispatchers. 默认为空列表. 51 | decorators (Optional[List[Decorator]], optional): 该任务要使用的 Decorators. 默认为空列表. 52 | 53 | Returns: 54 | Callable[[T_Callable], T_Callable]: 任务 函数/方法 包装器. 55 | """ 56 | 57 | def wrapper(func): 58 | task = SchedulerTask( 59 | func, 60 | timer, 61 | self.broadcast, 62 | self.loop, 63 | cancelable, 64 | dispatchers, 65 | decorators, 66 | ) 67 | self.schedule_tasks.append(task) 68 | return func 69 | 70 | return wrapper 71 | 72 | async def run(self) -> None: 73 | """开始所有计划任务, 在所有任务结束后返回""" 74 | await asyncio.gather(*(task.setup_task() for task in self.schedule_tasks)) 75 | 76 | async def join(self, stop: bool = False) -> None: 77 | """等待所有计划任务结束""" 78 | await asyncio.gather(*(task.join(stop=stop) for task in self.schedule_tasks)) 79 | 80 | def stop(self) -> None: 81 | """停止所有计划任务""" 82 | for task in self.schedule_tasks: 83 | task.stop() 84 | -------------------------------------------------------------------------------- /src/graia/scheduler/saya/shortcut.py: -------------------------------------------------------------------------------- 1 | """Saya 相关的工具""" 2 | from __future__ import annotations 3 | 4 | from datetime import datetime 5 | from typing import ( 6 | Dict, 7 | Generator, 8 | Literal, 9 | Optional, 10 | Protocol, 11 | Union, 12 | ) 13 | 14 | from graia.saya.factory import SchemaWrapper, factory 15 | 16 | from .. import Timer 17 | from ..timers import ( 18 | crontabify, 19 | every_custom_hours, 20 | every_custom_minutes, 21 | every_custom_seconds, 22 | ) 23 | from ..utilles import TimeObject 24 | from .schema import SchedulerSchema 25 | 26 | 27 | @factory 28 | def schedule(timer: Union[Timer, str], cancelable: bool = True) -> SchemaWrapper: 29 | """在当前 Saya Channel 中设置定时任务 30 | 31 | Args: 32 | timer (Union[Timer, str]): 定时器或者类似 crontab 的定时模板 33 | cancelable (bool): 是否能够取消定时任务, 默认为 True 34 | Returns: 35 | Callable[[T_Callable], T_Callable]: 装饰器 36 | """ 37 | 38 | return lambda _, buffer: SchedulerSchema( 39 | timer=crontabify(timer) if isinstance(timer, str) else timer, cancelable=cancelable, **buffer 40 | ) 41 | 42 | 43 | class _TimerProtocol(Protocol): 44 | def __call__(self, value: int, /, *, base: Optional[TimeObject] = None) -> Generator[datetime, None, None]: 45 | ... 46 | 47 | 48 | _TIMER_MAPPING: Dict[str, _TimerProtocol] = { 49 | "second": every_custom_seconds, 50 | "minute": every_custom_minutes, 51 | "hour": every_custom_hours, 52 | } 53 | 54 | 55 | @factory 56 | def every( 57 | value: int = 1, 58 | mode: Literal["second", "minute", "hour"] = "second", 59 | start: Optional[TimeObject] = None, 60 | cancelable: bool = True, 61 | ) -> SchemaWrapper: 62 | """在当前 Saya Channel 中设置基本的定时任务 63 | 64 | Args: 65 | value (int): 时间间隔, 默认为 1 66 | mode (Literal["second", "minute", "hour"]): 定时模式, 默认为 ’second‘ 67 | start (Optional[Union[datetime, time, str, float]]): 定时起始时间, 默认为 datetime.now() 68 | cancelable (bool): 是否能够取消定时任务, 默认为 True 69 | Returns: 70 | Callable[[T_Callable], T_Callable]: 装饰器 71 | """ 72 | 73 | return lambda _, buffer: SchedulerSchema( 74 | timer=_TIMER_MAPPING[mode](value, base=start), cancelable=cancelable, **buffer 75 | ) 76 | 77 | 78 | @factory 79 | def crontab(pattern: str, start: Optional[TimeObject] = None, cancelable: bool = True) -> SchemaWrapper: 80 | """在当前 Saya Channel 中设置类似于 crontab 模板的定时任务 81 | 82 | Args: 83 | pattern (str): 类似 crontab 的定时模板 84 | start (Optional[Union[datetime, time, str, float]]): 定时起始时间, 默认为 datetime.now() 85 | cancelable (bool): 是否能够取消定时任务, 默认为 True 86 | Returns: 87 | Callable[[T_Callable], T_Callable]: 装饰器 88 | """ 89 | 90 | return lambda _, buffer: SchedulerSchema(timer=crontabify(pattern, start), cancelable=cancelable, **buffer) 91 | 92 | 93 | on_timer = schedule 94 | -------------------------------------------------------------------------------- /mkdocs.yml: -------------------------------------------------------------------------------- 1 | site_name: Graia Scheduler API 参考 2 | 3 | watch: 4 | - src/graia 5 | 6 | theme: 7 | features: 8 | - navigation.tabs 9 | - navigation.tabs.sticky 10 | - navigation.expand 11 | - navigation.top 12 | 13 | name: material 14 | language: zh 15 | icon: 16 | repo: fontawesome/brands/git-alt 17 | logo: material/file-document-multiple-outline 18 | 19 | font: 20 | text: Noto Sans Simplified Chinese 21 | code: JetBrains Mono 22 | 23 | custom_dir: docs/overrides 24 | 25 | palette: 26 | - media: "(prefers-color-scheme: light)" 27 | scheme: default 28 | toggle: 29 | icon: material/toggle-switch-off-outline 30 | name: 黑暗模式 31 | - media: "(prefers-color-scheme: dark)" 32 | scheme: slate 33 | toggle: 34 | icon: material/toggle-switch 35 | name: 明亮模式 36 | 37 | extra_css: 38 | - "assets/chat.css" 39 | - "assets/extra.css" 40 | - "assets/curtain.css" 41 | 42 | extra_javascript: 43 | - "assets/admonition.js" 44 | 45 | repo_url: https://github.com/GraiaProject/Scheduler 46 | repo_name: GraiaProject/Scheduler 47 | edit_uri: blob/dev/ 48 | 49 | copyright: Copyright © Graia Project 2021-2022. 50 | 51 | extra: 52 | social: 53 | - icon: netlify 54 | link: https://scheduler.api.graia.cn/ 55 | name: Netlify 镜像 56 | - icon: fontawesome/brands/cloudflare 57 | link: https://graia-scheduler.pages.dev/ 58 | name: CloudFlare 镜像 59 | - icon: fontawesome/brands/qq 60 | link: https://jq.qq.com/?_wv=1027&k=VXp6plBD 61 | name: QQ 群 62 | - icon: material/compass 63 | link: https://graiax.cn/ 64 | name: Graiax 社区 65 | - icon: fontawesome/brands/github 66 | link: https://github.com/GraiaProject 67 | name: GitHub 组织 68 | 69 | markdown_extensions: 70 | - attr_list 71 | - md_in_html 72 | - admonition # 提示块 73 | - footnotes # 脚注 74 | - meta # 定义元数据, 通过文章上下文控制, 如disqus 75 | - pymdownx.caret # 下划线上标 76 | - pymdownx.tilde # 删除线下标 77 | - pymdownx.critic # 增加删除修改高亮注释, 可修饰行内或段落 78 | - pymdownx.details # 提示块可折叠 79 | - pymdownx.inlinehilite # 行内代码高亮 80 | - pymdownx.highlight 81 | - pymdownx.snippets 82 | - pymdownx.mark # 文本高亮 83 | - pymdownx.smartsymbols # 符号转换 84 | - pymdownx.superfences # 代码嵌套在列表里 85 | - pymdownx.keys 86 | - codehilite: # 代码高亮, 显示行号 87 | guess_lang: false 88 | linenums: true 89 | - toc: # 锚点 90 | permalink: 🔗 91 | - pymdownx.arithmatex # 数学公式 92 | - pymdownx.tasklist: # 复选框checklist 93 | custom_checkbox: true 94 | - pymdownx.tabbed: 95 | alternate_style: true 96 | 97 | plugins: 98 | - search 99 | - gen-files: 100 | scripts: 101 | - docs/gen_ref.py 102 | - mkdocstrings: 103 | handlers: 104 | python: 105 | paths: [src] 106 | import: 107 | - https://docs.python.org/zh-cn/3/objects.inv 108 | selection: 109 | docstring_style: google 110 | rendering: 111 | show_submodules: false 112 | show_signature_annotations: yes 113 | separate_signature: yes 114 | docstring_section_style: list 115 | line_length: 80 116 | 117 | - literate-nav: 118 | nav_file: NAV.md 119 | 120 | - section-index 121 | -------------------------------------------------------------------------------- /src/graia/scheduler/timers.py: -------------------------------------------------------------------------------- 1 | """该模块提供一些便捷的 Timer""" 2 | 3 | from datetime import datetime, timedelta 4 | from typing import Generator, Optional 5 | 6 | from croniter import croniter 7 | 8 | from graia.scheduler.utilles import TimeObject, to_datetime 9 | 10 | Ret = Generator[datetime, None, None] 11 | 12 | 13 | def every(*, base: Optional[TimeObject] = None, **kwargs) -> Ret: 14 | """一个简便的 datetime 生成器. 15 | 16 | Args: 17 | base (Optional[TimeObject], optional): 若为 None (默认), 则会相对于当前时间推算. 否则基于 base 推算. 18 | 19 | Yields: 20 | (datetime): 生成的 datetime. 21 | """ 22 | if base is None: 23 | while True: 24 | yield datetime.now() + timedelta(**kwargs) 25 | else: 26 | current = to_datetime(base) 27 | while True: 28 | current += timedelta(**kwargs) 29 | yield current 30 | 31 | 32 | def every_second(*, base: Optional[TimeObject] = None) -> Ret: 33 | """每秒钟执行一次 34 | 35 | Args: 36 | base (Optional[TimeObject], optional): 若为 None (默认), 则会相对于当前时间推算. 否则基于 base 推算. 37 | 38 | Yields: 39 | (datetime): 生成的 datetime. 40 | """ 41 | yield from every(seconds=1, base=base) 42 | 43 | 44 | def every_minute(*, base: Optional[TimeObject] = None) -> Ret: 45 | """每分钟执行一次. 46 | 47 | Args: 48 | base (Optional[TimeObject], optional): 若为 None (默认), 则会相对于当前时间推算. 否则基于 base 推算. 49 | 50 | Yields: 51 | (datetime): 生成的 datetime. 52 | """ 53 | yield from every(minutes=1, base=base) 54 | 55 | 56 | def every_hour(*, base: Optional[TimeObject] = None): 57 | """每小时执行一次. 58 | 59 | Args: 60 | base (Optional[TimeObject], optional): 若为 None (默认), 则会相对于当前时间推算. 否则基于 base 推算. 61 | 62 | Yields: 63 | (datetime): 生成的 datetime. 64 | """ 65 | yield from every(hours=1, base=base) 66 | 67 | 68 | every_hours = every_hour # Backward compatibility 69 | 70 | 71 | def every_custom_seconds(seconds: int, *, base: Optional[TimeObject] = None) -> Ret: 72 | """每 seconds 秒执行一次 73 | 74 | Args: 75 | seconds (int): 距离下一次执行的时间间隔, 单位为秒 76 | base (Optional[TimeObject], optional): 若为 None (默认), 则会相对于当前时间推算. 否则基于 base 推算. 77 | 78 | Yields: 79 | (datetime): 生成的 datetime. 80 | """ 81 | yield from every(seconds=seconds, base=base) 82 | 83 | 84 | def every_custom_minutes(minutes: int, *, base: Optional[TimeObject] = None) -> Ret: 85 | """每 minutes 分执行一次 86 | 87 | Args: 88 | minutes (int): 距离下一次执行的时间间隔, 单位为分 89 | base (Optional[TimeObject], optional): 若为 None (默认), 则会相对于当前时间推算. 否则基于 base 推算. 90 | 91 | Yields: 92 | (datetime): 生成的 datetime. 93 | """ 94 | yield from every(minutes=minutes, base=base) 95 | 96 | 97 | def every_custom_hours(hours: int, *, base: Optional[TimeObject] = None) -> Ret: 98 | """每 hours 小时执行一次 99 | 100 | Args: 101 | hours (int): 距离下一次执行的时间间隔, 单位为小时 102 | base (Optional[TimeObject], optional): 若为 None (默认), 则会相对于当前时间推算. 否则基于 base 推算. 103 | 104 | Yields: 105 | (datetime): 生成的 datetime. 106 | """ 107 | yield from every(hours=hours, base=base) 108 | 109 | 110 | def crontabify(pattern: str, base: Optional[TimeObject] = None) -> Ret: 111 | """使用类似 crontab 的方式生成计时器 112 | 113 | Args: 114 | pattern (str): 时间模式 115 | base (Optional[TimeObject], optional): 开始时间. 默认为 datetime.now(). 116 | 117 | Yields: 118 | (datetime): 生成的 datetime. 119 | """ 120 | base = to_datetime(base) if base else datetime.now() 121 | crontab_iter = croniter(pattern, base) 122 | while True: 123 | yield crontab_iter.get_next(datetime) 124 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | build/ 12 | develop-eggs/ 13 | dist/ 14 | downloads/ 15 | eggs/ 16 | .eggs/ 17 | lib/ 18 | lib64/ 19 | parts/ 20 | sdist/ 21 | var/ 22 | wheels/ 23 | share/python-wheels/ 24 | *.egg-info/ 25 | .installed.cfg 26 | *.egg 27 | MANIFEST 28 | 29 | # PyInstaller 30 | # Usually these files are written by a python script from a template 31 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 32 | *.manifest 33 | *.spec 34 | 35 | # Installer logs 36 | pip-log.txt 37 | pip-delete-this-directory.txt 38 | 39 | # Unit test / coverage reports 40 | htmlcov/ 41 | .tox/ 42 | .nox/ 43 | .coverage 44 | .coverage.* 45 | .cache 46 | nosetests.xml 47 | coverage.xml 48 | *.cover 49 | *.py,cover 50 | .hypothesis/ 51 | .pytest_cache/ 52 | cover/ 53 | 54 | # Translations 55 | *.mo 56 | *.pot 57 | 58 | # Django stuff: 59 | *.log 60 | local_settings.py 61 | db.sqlite3 62 | db.sqlite3-journal 63 | 64 | # Flask stuff: 65 | instance/ 66 | .webassets-cache 67 | 68 | # Scrapy stuff: 69 | .scrapy 70 | 71 | # Sphinx documentation 72 | docs/_build/ 73 | 74 | # PyBuilder 75 | .pybuilder/ 76 | target/ 77 | 78 | # Jupyter Notebook 79 | .ipynb_checkpoints 80 | 81 | # IPython 82 | profile_default/ 83 | ipython_config.py 84 | 85 | # pyenv 86 | # For a library or package, you might want to ignore these files since the code is 87 | # intended to run in multiple environments; otherwise, check them in: 88 | .python-version 89 | 90 | # pipenv 91 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 92 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 93 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 94 | # install all needed dependencies. 95 | #Pipfile.lock 96 | 97 | # poetry 98 | # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. 99 | # This is especially recommended for binary packages to ensure reproducibility, and is more 100 | # commonly ignored for libraries. 101 | # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control 102 | #poetry.lock 103 | 104 | # pdm 105 | # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control. 106 | #pdm.lock 107 | # pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it 108 | # in version control. 109 | # https://pdm.fming.dev/#use-with-ide 110 | .pdm-python 111 | 112 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm 113 | __pypackages__/ 114 | 115 | # Celery stuff 116 | celerybeat-schedule 117 | celerybeat.pid 118 | 119 | # SageMath parsed files 120 | *.sage.py 121 | 122 | # Environments 123 | .env 124 | .venv 125 | env/ 126 | venv/ 127 | ENV/ 128 | env.bak/ 129 | venv.bak/ 130 | 131 | # Spyder project settings 132 | .spyderproject 133 | .spyproject 134 | 135 | # Rope project settings 136 | .ropeproject 137 | 138 | # mkdocs documentation 139 | /site 140 | 141 | # mypy 142 | .mypy_cache/ 143 | .dmypy.json 144 | dmypy.json 145 | 146 | # Pyre type checker 147 | .pyre/ 148 | 149 | # pytype static type analyzer 150 | .pytype/ 151 | 152 | # Cython debug symbols 153 | cython_debug/ 154 | 155 | # PyCharm 156 | # JetBrains specific template is maintained in a separate JetBrains.gitignore that can 157 | # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore 158 | # and can be added to the global gitignore or merged into this file. For a more nuclear 159 | # option (not recommended) you can uncomment the following to ignore the entire idea folder. 160 | #.idea/ 161 | -------------------------------------------------------------------------------- /docs/overrides/.icons/netlify.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /src/graia/scheduler/task.py: -------------------------------------------------------------------------------- 1 | import asyncio 2 | import traceback 3 | from datetime import datetime 4 | from typing import Any, Callable, Generator, List, Optional, Tuple, Awaitable 5 | 6 | from graia.broadcast import Broadcast 7 | from graia.broadcast.entities.decorator import Decorator 8 | from graia.broadcast.entities.exectarget import ExecTarget 9 | from graia.broadcast.exceptions import ExecutionStop, PropagationCancelled 10 | from graia.broadcast.typing import T_Dispatcher 11 | from graia.broadcast.builtin.event import ExceptionThrown 12 | from graia.scheduler.exception import AlreadyStarted 13 | from graia.scheduler.utilles import EnteredRecord, print_track_async 14 | 15 | from . import Timer 16 | 17 | 18 | class SchedulerTask: 19 | target: Callable[..., Any] 20 | timer: Timer 21 | task: Optional[asyncio.Task] 22 | 23 | broadcast: Broadcast 24 | dispatchers: List[T_Dispatcher] 25 | decorators: List[Decorator] 26 | 27 | cancelable: bool 28 | stopped: bool 29 | 30 | sleep_record: EnteredRecord 31 | run_record: EnteredRecord 32 | 33 | loop: asyncio.AbstractEventLoop 34 | 35 | @property 36 | def is_sleeping(self) -> bool: 37 | return self.sleep_record.entered 38 | 39 | @property 40 | def is_executing(self) -> bool: 41 | return self.run_record.entered and not self.sleep_record.entered 42 | 43 | def __init__( 44 | self, 45 | target: Callable[..., Any], 46 | timer: Timer, 47 | broadcast: Broadcast, 48 | loop: Optional[asyncio.AbstractEventLoop] = None, 49 | cancelable: bool = False, 50 | dispatchers: Optional[List[T_Dispatcher]] = None, 51 | decorators: Optional[List[Decorator]] = None, 52 | ) -> None: 53 | self.target = target 54 | self.timer = timer 55 | self.broadcast = broadcast 56 | self.loop = loop or asyncio.get_running_loop() 57 | self.cancelable = cancelable 58 | self.task = None 59 | self.stopped = False 60 | self.dispatchers = dispatchers or [] 61 | self.decorators = decorators or [] 62 | self.sleep_record = EnteredRecord() 63 | self.run_record = EnteredRecord() 64 | 65 | def setup_task(self) -> asyncio.Task: 66 | """将本 SchedulerTask 作为 asyncio.Task 排入事件循环.""" 67 | if self.task: 68 | raise AlreadyStarted("the scheduler task has been started!") 69 | self.task = self.loop.create_task(self.run()) 70 | return self.task 71 | 72 | def sleep_interval_generator(self) -> Generator[float, None, None]: 73 | for next_execute_time in self.timer: 74 | if self.stopped: 75 | return 76 | now = datetime.now() 77 | if next_execute_time >= now: 78 | yield (next_execute_time - now).total_seconds() 79 | 80 | def coroutine_generator(self) -> Generator[Tuple[Awaitable[Any], bool], None, None]: 81 | for sleep_interval in self.sleep_interval_generator(): 82 | yield (asyncio.sleep(sleep_interval), True) 83 | yield ( 84 | self.broadcast.Executor( 85 | target=ExecTarget( 86 | callable=self.target, 87 | inline_dispatchers=self.dispatchers, 88 | decorators=self.decorators, 89 | ), 90 | ), 91 | False, 92 | ) 93 | 94 | @print_track_async 95 | async def run(self) -> None: 96 | if self.run_record.entered: 97 | raise AlreadyStarted("the scheduler task has been started!") 98 | with self.run_record: 99 | for coro, waiting in self.coroutine_generator(): 100 | if waiting: # 是否为 asyncio.sleep 的 coro 101 | with self.sleep_record: 102 | try: 103 | await coro 104 | continue 105 | except asyncio.CancelledError: 106 | return 107 | try: 108 | await (coro if self.cancelable else asyncio.shield(coro)) 109 | except asyncio.CancelledError: 110 | if self.cancelable: 111 | return 112 | raise 113 | except (ExecutionStop, PropagationCancelled): 114 | pass 115 | except Exception as e: 116 | traceback.print_exc() 117 | await self.broadcast.postEvent(ExceptionThrown(e, None)) 118 | 119 | def stop_gen_interval(self) -> None: 120 | if not self.stopped: 121 | self.stopped = True 122 | 123 | async def join(self, stop: bool = False) -> None: 124 | """阻塞直至当前 SchedulerTask 执行完毕. 125 | 126 | Args: 127 | stop (bool, optional): 是否停止当前 SchedulerTask 下一次运行. 默认为 False. 128 | """ 129 | if stop and not self.stopped: 130 | self.stop_gen_interval() 131 | 132 | if self.task: 133 | await self.task 134 | self.task = None 135 | 136 | def stop(self): 137 | """停止当前 SchedulerTask.""" 138 | if self.task and not self.task.cancelled(): 139 | self.task.cancel() 140 | -------------------------------------------------------------------------------- /pdm.lock: -------------------------------------------------------------------------------- 1 | # This file is @generated by PDM. 2 | # It is not intended for manual editing. 3 | 4 | [metadata] 5 | groups = ["default", "dev", "docs", "saya"] 6 | cross_platform = true 7 | static_urls = false 8 | lock_version = "4.3" 9 | content_hash = "sha256:1a0b387882e782d41908d0a24789e98e44b3b22b5dc5351701a31f2c98854233" 10 | 11 | [[package]] 12 | name = "black" 13 | version = "23.7.0" 14 | requires_python = ">=3.8" 15 | summary = "The uncompromising code formatter." 16 | dependencies = [ 17 | "click>=8.0.0", 18 | "mypy-extensions>=0.4.3", 19 | "packaging>=22.0", 20 | "pathspec>=0.9.0", 21 | "platformdirs>=2", 22 | "tomli>=1.1.0; python_version < \"3.11\"", 23 | "typing-extensions>=3.10.0.0; python_version < \"3.10\"", 24 | ] 25 | files = [ 26 | {file = "black-23.7.0-cp310-cp310-macosx_10_16_arm64.whl", hash = "sha256:5c4bc552ab52f6c1c506ccae05681fab58c3f72d59ae6e6639e8885e94fe2587"}, 27 | {file = "black-23.7.0-cp310-cp310-macosx_10_16_universal2.whl", hash = "sha256:552513d5cd5694590d7ef6f46e1767a4df9af168d449ff767b13b084c020e63f"}, 28 | {file = "black-23.7.0-cp310-cp310-macosx_10_16_x86_64.whl", hash = "sha256:86cee259349b4448adb4ef9b204bb4467aae74a386bce85d56ba4f5dc0da27be"}, 29 | {file = "black-23.7.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:501387a9edcb75d7ae8a4412bb8749900386eaef258f1aefab18adddea1936bc"}, 30 | {file = "black-23.7.0-cp310-cp310-win_amd64.whl", hash = "sha256:fb074d8b213749fa1d077d630db0d5f8cc3b2ae63587ad4116e8a436e9bbe995"}, 31 | {file = "black-23.7.0-cp311-cp311-macosx_10_16_arm64.whl", hash = "sha256:b5b0ee6d96b345a8b420100b7d71ebfdd19fab5e8301aff48ec270042cd40ac2"}, 32 | {file = "black-23.7.0-cp311-cp311-macosx_10_16_universal2.whl", hash = "sha256:893695a76b140881531062d48476ebe4a48f5d1e9388177e175d76234ca247cd"}, 33 | {file = "black-23.7.0-cp311-cp311-macosx_10_16_x86_64.whl", hash = "sha256:c333286dc3ddca6fdff74670b911cccedacb4ef0a60b34e491b8a67c833b343a"}, 34 | {file = "black-23.7.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:831d8f54c3a8c8cf55f64d0422ee875eecac26f5f649fb6c1df65316b67c8926"}, 35 | {file = "black-23.7.0-cp311-cp311-win_amd64.whl", hash = "sha256:7f3bf2dec7d541b4619b8ce526bda74a6b0bffc480a163fed32eb8b3c9aed8ad"}, 36 | {file = "black-23.7.0-cp38-cp38-macosx_10_16_arm64.whl", hash = "sha256:f9062af71c59c004cd519e2fb8f5d25d39e46d3af011b41ab43b9c74e27e236f"}, 37 | {file = "black-23.7.0-cp38-cp38-macosx_10_16_universal2.whl", hash = "sha256:01ede61aac8c154b55f35301fac3e730baf0c9cf8120f65a9cd61a81cfb4a0c3"}, 38 | {file = "black-23.7.0-cp38-cp38-macosx_10_16_x86_64.whl", hash = "sha256:327a8c2550ddc573b51e2c352adb88143464bb9d92c10416feb86b0f5aee5ff6"}, 39 | {file = "black-23.7.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6d1c6022b86f83b632d06f2b02774134def5d4d4f1dac8bef16d90cda18ba28a"}, 40 | {file = "black-23.7.0-cp38-cp38-win_amd64.whl", hash = "sha256:27eb7a0c71604d5de083757fbdb245b1a4fae60e9596514c6ec497eb63f95320"}, 41 | {file = "black-23.7.0-cp39-cp39-macosx_10_16_arm64.whl", hash = "sha256:8417dbd2f57b5701492cd46edcecc4f9208dc75529bcf76c514864e48da867d9"}, 42 | {file = "black-23.7.0-cp39-cp39-macosx_10_16_universal2.whl", hash = "sha256:47e56d83aad53ca140da0af87678fb38e44fd6bc0af71eebab2d1f59b1acf1d3"}, 43 | {file = "black-23.7.0-cp39-cp39-macosx_10_16_x86_64.whl", hash = "sha256:25cc308838fe71f7065df53aedd20327969d05671bac95b38fdf37ebe70ac087"}, 44 | {file = "black-23.7.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:642496b675095d423f9b8448243336f8ec71c9d4d57ec17bf795b67f08132a91"}, 45 | {file = "black-23.7.0-cp39-cp39-win_amd64.whl", hash = "sha256:ad0014efc7acf0bd745792bd0d8857413652979200ab924fbf239062adc12491"}, 46 | {file = "black-23.7.0-py3-none-any.whl", hash = "sha256:9fd59d418c60c0348505f2ddf9609c1e1de8e7493eab96198fc89d9f865e7a96"}, 47 | {file = "black-23.7.0.tar.gz", hash = "sha256:022a582720b0d9480ed82576c920a8c1dde97cc38ff11d8d8859b3bd6ca9eedb"}, 48 | ] 49 | 50 | [[package]] 51 | name = "certifi" 52 | version = "2023.7.22" 53 | requires_python = ">=3.6" 54 | summary = "Python package for providing Mozilla's CA Bundle." 55 | files = [ 56 | {file = "certifi-2023.7.22-py3-none-any.whl", hash = "sha256:92d6037539857d8206b8f6ae472e8b77db8058fec5937a1ef3f54304089edbb9"}, 57 | {file = "certifi-2023.7.22.tar.gz", hash = "sha256:539cc1d13202e33ca466e88b2807e29f4c13049d6d87031a3c110744495cb082"}, 58 | ] 59 | 60 | [[package]] 61 | name = "charset-normalizer" 62 | version = "3.2.0" 63 | requires_python = ">=3.7.0" 64 | summary = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." 65 | files = [ 66 | {file = "charset-normalizer-3.2.0.tar.gz", hash = "sha256:3bb3d25a8e6c0aedd251753a79ae98a093c7e7b471faa3aa9a93a81431987ace"}, 67 | {file = "charset_normalizer-3.2.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:0b87549028f680ca955556e3bd57013ab47474c3124dc069faa0b6545b6c9710"}, 68 | {file = "charset_normalizer-3.2.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:7c70087bfee18a42b4040bb9ec1ca15a08242cf5867c58726530bdf3945672ed"}, 69 | {file = "charset_normalizer-3.2.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a103b3a7069b62f5d4890ae1b8f0597618f628b286b03d4bc9195230b154bfa9"}, 70 | {file = "charset_normalizer-3.2.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:94aea8eff76ee6d1cdacb07dd2123a68283cb5569e0250feab1240058f53b623"}, 71 | {file = "charset_normalizer-3.2.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:db901e2ac34c931d73054d9797383d0f8009991e723dab15109740a63e7f902a"}, 72 | {file = "charset_normalizer-3.2.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b0dac0ff919ba34d4df1b6131f59ce95b08b9065233446be7e459f95554c0dc8"}, 73 | {file = "charset_normalizer-3.2.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:193cbc708ea3aca45e7221ae58f0fd63f933753a9bfb498a3b474878f12caaad"}, 74 | {file = "charset_normalizer-3.2.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:09393e1b2a9461950b1c9a45d5fd251dc7c6f228acab64da1c9c0165d9c7765c"}, 75 | {file = "charset_normalizer-3.2.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:baacc6aee0b2ef6f3d308e197b5d7a81c0e70b06beae1f1fcacffdbd124fe0e3"}, 76 | {file = "charset_normalizer-3.2.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:bf420121d4c8dce6b889f0e8e4ec0ca34b7f40186203f06a946fa0276ba54029"}, 77 | {file = "charset_normalizer-3.2.0-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:c04a46716adde8d927adb9457bbe39cf473e1e2c2f5d0a16ceb837e5d841ad4f"}, 78 | {file = "charset_normalizer-3.2.0-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:aaf63899c94de41fe3cf934601b0f7ccb6b428c6e4eeb80da72c58eab077b19a"}, 79 | {file = "charset_normalizer-3.2.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:d62e51710986674142526ab9f78663ca2b0726066ae26b78b22e0f5e571238dd"}, 80 | {file = "charset_normalizer-3.2.0-cp310-cp310-win32.whl", hash = "sha256:04e57ab9fbf9607b77f7d057974694b4f6b142da9ed4a199859d9d4d5c63fe96"}, 81 | {file = "charset_normalizer-3.2.0-cp310-cp310-win_amd64.whl", hash = "sha256:48021783bdf96e3d6de03a6e39a1171ed5bd7e8bb93fc84cc649d11490f87cea"}, 82 | {file = "charset_normalizer-3.2.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:4957669ef390f0e6719db3613ab3a7631e68424604a7b448f079bee145da6e09"}, 83 | {file = "charset_normalizer-3.2.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:46fb8c61d794b78ec7134a715a3e564aafc8f6b5e338417cb19fe9f57a5a9bf2"}, 84 | {file = "charset_normalizer-3.2.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f779d3ad205f108d14e99bb3859aa7dd8e9c68874617c72354d7ecaec2a054ac"}, 85 | {file = "charset_normalizer-3.2.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f25c229a6ba38a35ae6e25ca1264621cc25d4d38dca2942a7fce0b67a4efe918"}, 86 | {file = "charset_normalizer-3.2.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2efb1bd13885392adfda4614c33d3b68dee4921fd0ac1d3988f8cbb7d589e72a"}, 87 | {file = "charset_normalizer-3.2.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1f30b48dd7fa1474554b0b0f3fdfdd4c13b5c737a3c6284d3cdc424ec0ffff3a"}, 88 | {file = "charset_normalizer-3.2.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:246de67b99b6851627d945db38147d1b209a899311b1305dd84916f2b88526c6"}, 89 | {file = "charset_normalizer-3.2.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9bd9b3b31adcb054116447ea22caa61a285d92e94d710aa5ec97992ff5eb7cf3"}, 90 | {file = "charset_normalizer-3.2.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:8c2f5e83493748286002f9369f3e6607c565a6a90425a3a1fef5ae32a36d749d"}, 91 | {file = "charset_normalizer-3.2.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:3170c9399da12c9dc66366e9d14da8bf7147e1e9d9ea566067bbce7bb74bd9c2"}, 92 | {file = "charset_normalizer-3.2.0-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:7a4826ad2bd6b07ca615c74ab91f32f6c96d08f6fcc3902ceeedaec8cdc3bcd6"}, 93 | {file = "charset_normalizer-3.2.0-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:3b1613dd5aee995ec6d4c69f00378bbd07614702a315a2cf6c1d21461fe17c23"}, 94 | {file = "charset_normalizer-3.2.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:9e608aafdb55eb9f255034709e20d5a83b6d60c054df0802fa9c9883d0a937aa"}, 95 | {file = "charset_normalizer-3.2.0-cp311-cp311-win32.whl", hash = "sha256:f2a1d0fd4242bd8643ce6f98927cf9c04540af6efa92323e9d3124f57727bfc1"}, 96 | {file = "charset_normalizer-3.2.0-cp311-cp311-win_amd64.whl", hash = "sha256:681eb3d7e02e3c3655d1b16059fbfb605ac464c834a0c629048a30fad2b27489"}, 97 | {file = "charset_normalizer-3.2.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c57921cda3a80d0f2b8aec7e25c8aa14479ea92b5b51b6876d975d925a2ea346"}, 98 | {file = "charset_normalizer-3.2.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:41b25eaa7d15909cf3ac4c96088c1f266a9a93ec44f87f1d13d4a0e86c81b982"}, 99 | {file = "charset_normalizer-3.2.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f058f6963fd82eb143c692cecdc89e075fa0828db2e5b291070485390b2f1c9c"}, 100 | {file = "charset_normalizer-3.2.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a7647ebdfb9682b7bb97e2a5e7cb6ae735b1c25008a70b906aecca294ee96cf4"}, 101 | {file = "charset_normalizer-3.2.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eef9df1eefada2c09a5e7a40991b9fc6ac6ef20b1372abd48d2794a316dc0449"}, 102 | {file = "charset_normalizer-3.2.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e03b8895a6990c9ab2cdcd0f2fe44088ca1c65ae592b8f795c3294af00a461c3"}, 103 | {file = "charset_normalizer-3.2.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:ee4006268ed33370957f55bf2e6f4d263eaf4dc3cfc473d1d90baff6ed36ce4a"}, 104 | {file = "charset_normalizer-3.2.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:c4983bf937209c57240cff65906b18bb35e64ae872da6a0db937d7b4af845dd7"}, 105 | {file = "charset_normalizer-3.2.0-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:3bb7fda7260735efe66d5107fb7e6af6a7c04c7fce9b2514e04b7a74b06bf5dd"}, 106 | {file = "charset_normalizer-3.2.0-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:72814c01533f51d68702802d74f77ea026b5ec52793c791e2da806a3844a46c3"}, 107 | {file = "charset_normalizer-3.2.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:70c610f6cbe4b9fce272c407dd9d07e33e6bf7b4aa1b7ffb6f6ded8e634e3592"}, 108 | {file = "charset_normalizer-3.2.0-cp37-cp37m-win32.whl", hash = "sha256:a401b4598e5d3f4a9a811f3daf42ee2291790c7f9d74b18d75d6e21dda98a1a1"}, 109 | {file = "charset_normalizer-3.2.0-cp37-cp37m-win_amd64.whl", hash = "sha256:c0b21078a4b56965e2b12f247467b234734491897e99c1d51cee628da9786959"}, 110 | {file = "charset_normalizer-3.2.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:95eb302ff792e12aba9a8b8f8474ab229a83c103d74a750ec0bd1c1eea32e669"}, 111 | {file = "charset_normalizer-3.2.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1a100c6d595a7f316f1b6f01d20815d916e75ff98c27a01ae817439ea7726329"}, 112 | {file = "charset_normalizer-3.2.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:6339d047dab2780cc6220f46306628e04d9750f02f983ddb37439ca47ced7149"}, 113 | {file = "charset_normalizer-3.2.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e4b749b9cc6ee664a3300bb3a273c1ca8068c46be705b6c31cf5d276f8628a94"}, 114 | {file = "charset_normalizer-3.2.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a38856a971c602f98472050165cea2cdc97709240373041b69030be15047691f"}, 115 | {file = "charset_normalizer-3.2.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f87f746ee241d30d6ed93969de31e5ffd09a2961a051e60ae6bddde9ec3583aa"}, 116 | {file = "charset_normalizer-3.2.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:89f1b185a01fe560bc8ae5f619e924407efca2191b56ce749ec84982fc59a32a"}, 117 | {file = "charset_normalizer-3.2.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e1c8a2f4c69e08e89632defbfabec2feb8a8d99edc9f89ce33c4b9e36ab63037"}, 118 | {file = "charset_normalizer-3.2.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:2f4ac36d8e2b4cc1aa71df3dd84ff8efbe3bfb97ac41242fbcfc053c67434f46"}, 119 | {file = "charset_normalizer-3.2.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:a386ebe437176aab38c041de1260cd3ea459c6ce5263594399880bbc398225b2"}, 120 | {file = "charset_normalizer-3.2.0-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:ccd16eb18a849fd8dcb23e23380e2f0a354e8daa0c984b8a732d9cfaba3a776d"}, 121 | {file = "charset_normalizer-3.2.0-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:e6a5bf2cba5ae1bb80b154ed68a3cfa2fa00fde979a7f50d6598d3e17d9ac20c"}, 122 | {file = "charset_normalizer-3.2.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:45de3f87179c1823e6d9e32156fb14c1927fcc9aba21433f088fdfb555b77c10"}, 123 | {file = "charset_normalizer-3.2.0-cp38-cp38-win32.whl", hash = "sha256:1000fba1057b92a65daec275aec30586c3de2401ccdcd41f8a5c1e2c87078706"}, 124 | {file = "charset_normalizer-3.2.0-cp38-cp38-win_amd64.whl", hash = "sha256:8b2c760cfc7042b27ebdb4a43a4453bd829a5742503599144d54a032c5dc7e9e"}, 125 | {file = "charset_normalizer-3.2.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:855eafa5d5a2034b4621c74925d89c5efef61418570e5ef9b37717d9c796419c"}, 126 | {file = "charset_normalizer-3.2.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:203f0c8871d5a7987be20c72442488a0b8cfd0f43b7973771640fc593f56321f"}, 127 | {file = "charset_normalizer-3.2.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:e857a2232ba53ae940d3456f7533ce6ca98b81917d47adc3c7fd55dad8fab858"}, 128 | {file = "charset_normalizer-3.2.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5e86d77b090dbddbe78867a0275cb4df08ea195e660f1f7f13435a4649e954e5"}, 129 | {file = "charset_normalizer-3.2.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c4fb39a81950ec280984b3a44f5bd12819953dc5fa3a7e6fa7a80db5ee853952"}, 130 | {file = "charset_normalizer-3.2.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2dee8e57f052ef5353cf608e0b4c871aee320dd1b87d351c28764fc0ca55f9f4"}, 131 | {file = "charset_normalizer-3.2.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8700f06d0ce6f128de3ccdbc1acaea1ee264d2caa9ca05daaf492fde7c2a7200"}, 132 | {file = "charset_normalizer-3.2.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1920d4ff15ce893210c1f0c0e9d19bfbecb7983c76b33f046c13a8ffbd570252"}, 133 | {file = "charset_normalizer-3.2.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:c1c76a1743432b4b60ab3358c937a3fe1341c828ae6194108a94c69028247f22"}, 134 | {file = "charset_normalizer-3.2.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:f7560358a6811e52e9c4d142d497f1a6e10103d3a6881f18d04dbce3729c0e2c"}, 135 | {file = "charset_normalizer-3.2.0-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:c8063cf17b19661471ecbdb3df1c84f24ad2e389e326ccaf89e3fb2484d8dd7e"}, 136 | {file = "charset_normalizer-3.2.0-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:cd6dbe0238f7743d0efe563ab46294f54f9bc8f4b9bcf57c3c666cc5bc9d1299"}, 137 | {file = "charset_normalizer-3.2.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:1249cbbf3d3b04902ff081ffbb33ce3377fa6e4c7356f759f3cd076cc138d020"}, 138 | {file = "charset_normalizer-3.2.0-cp39-cp39-win32.whl", hash = "sha256:6c409c0deba34f147f77efaa67b8e4bb83d2f11c8806405f76397ae5b8c0d1c9"}, 139 | {file = "charset_normalizer-3.2.0-cp39-cp39-win_amd64.whl", hash = "sha256:7095f6fbfaa55defb6b733cfeb14efaae7a29f0b59d8cf213be4e7ca0b857b80"}, 140 | {file = "charset_normalizer-3.2.0-py3-none-any.whl", hash = "sha256:8e098148dd37b4ce3baca71fb394c81dc5d9c7728c95df695d2dca218edf40e6"}, 141 | ] 142 | 143 | [[package]] 144 | name = "click" 145 | version = "8.1.6" 146 | requires_python = ">=3.7" 147 | summary = "Composable command line interface toolkit" 148 | dependencies = [ 149 | "colorama; platform_system == \"Windows\"", 150 | ] 151 | files = [ 152 | {file = "click-8.1.6-py3-none-any.whl", hash = "sha256:fa244bb30b3b5ee2cae3da8f55c9e5e0c0e86093306301fb418eb9dc40fbded5"}, 153 | {file = "click-8.1.6.tar.gz", hash = "sha256:48ee849951919527a045bfe3bf7baa8a959c423134e1a5b98c05c20ba75a1cbd"}, 154 | ] 155 | 156 | [[package]] 157 | name = "colorama" 158 | version = "0.4.6" 159 | requires_python = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" 160 | summary = "Cross-platform colored terminal text." 161 | files = [ 162 | {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"}, 163 | {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, 164 | ] 165 | 166 | [[package]] 167 | name = "creart" 168 | version = "0.3.0" 169 | requires_python = ">=3.8" 170 | summary = "a universal, extensible class instantiation helper" 171 | dependencies = [ 172 | "importlib-metadata>=3.6", 173 | ] 174 | files = [ 175 | {file = "creart-0.3.0-py3-none-any.whl", hash = "sha256:43074f6f59430f41b72d3c04ba4d268af0f32842fbc94bbda4b81ae464be0ee1"}, 176 | {file = "creart-0.3.0.tar.gz", hash = "sha256:39fea77476d26d2bd5891aa3b5f16cab5567b37b855483e37f094ba005bf0d1f"}, 177 | ] 178 | 179 | [[package]] 180 | name = "croniter" 181 | version = "1.4.1" 182 | requires_python = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" 183 | summary = "croniter provides iteration for datetime object with cron like format" 184 | dependencies = [ 185 | "python-dateutil", 186 | ] 187 | files = [ 188 | {file = "croniter-1.4.1-py2.py3-none-any.whl", hash = "sha256:9595da48af37ea06ec3a9f899738f1b2c1c13da3c38cea606ef7cd03ea421128"}, 189 | {file = "croniter-1.4.1.tar.gz", hash = "sha256:1a6df60eacec3b7a0aa52a8f2ef251ae3dd2a7c7c8b9874e73e791636d55a361"}, 190 | ] 191 | 192 | [[package]] 193 | name = "ghp-import" 194 | version = "2.1.0" 195 | summary = "Copy your docs directly to the gh-pages branch." 196 | dependencies = [ 197 | "python-dateutil>=2.8.1", 198 | ] 199 | files = [ 200 | {file = "ghp-import-2.1.0.tar.gz", hash = "sha256:9c535c4c61193c2df8871222567d7fd7e5014d835f97dc7b7439069e2413d343"}, 201 | {file = "ghp_import-2.1.0-py3-none-any.whl", hash = "sha256:8337dd7b50877f163d4c0289bc1f1c7f127550241988d568c1db512c4324a619"}, 202 | ] 203 | 204 | [[package]] 205 | name = "graia-broadcast" 206 | version = "0.23.1" 207 | requires_python = "<4.0,>=3.8" 208 | summary = "a highly customizable, elegantly designed event system based on asyncio" 209 | dependencies = [ 210 | "creart~=0.3.0", 211 | "typing-extensions>=3.10.0; python_version < \"3.9\"", 212 | ] 213 | files = [ 214 | {file = "graia_broadcast-0.23.1-py3-none-any.whl", hash = "sha256:cbc18dd335e1679f94f726e04039611e86d688b72c42db3f97854f50f6ec0768"}, 215 | {file = "graia_broadcast-0.23.1.tar.gz", hash = "sha256:ed5293761ec3a496a90029de8fe60124dfed29a25ca06bb56dcb1f9a50c6a22d"}, 216 | ] 217 | 218 | [[package]] 219 | name = "graia-saya" 220 | version = "0.0.18" 221 | requires_python = "<4.0,>=3.8" 222 | summary = "a modular implementation with modern design and injection" 223 | dependencies = [ 224 | "importlib-metadata~=6.8; python_version < \"3.10\"", 225 | "loguru<0.7,>=0.5.3", 226 | ] 227 | files = [ 228 | {file = "graia_saya-0.0.18-py3-none-any.whl", hash = "sha256:2f72e455c69d418f1c867d39ee0abba41e96f7225148046c96ac8cf14a04f704"}, 229 | {file = "graia_saya-0.0.18.tar.gz", hash = "sha256:e6255aeeea5feaf7959c1e374512396768cb567995ad1eabc21cb0d40789317e"}, 230 | ] 231 | 232 | [[package]] 233 | name = "griffe" 234 | version = "0.32.3" 235 | requires_python = ">=3.8" 236 | summary = "Signatures for entire Python programs. Extract the structure, the frame, the skeleton of your project, to generate API documentation or find breaking changes in your API." 237 | dependencies = [ 238 | "colorama>=0.4", 239 | ] 240 | files = [ 241 | {file = "griffe-0.32.3-py3-none-any.whl", hash = "sha256:d9471934225818bf8f309822f70451cc6abb4b24e59e0bb27402a45f9412510f"}, 242 | {file = "griffe-0.32.3.tar.gz", hash = "sha256:14983896ad581f59d5ad7b6c9261ff12bdaa905acccc1129341d13e545da8521"}, 243 | ] 244 | 245 | [[package]] 246 | name = "idna" 247 | version = "3.4" 248 | requires_python = ">=3.5" 249 | summary = "Internationalized Domain Names in Applications (IDNA)" 250 | files = [ 251 | {file = "idna-3.4-py3-none-any.whl", hash = "sha256:90b77e79eaa3eba6de819a0c442c0b4ceefc341a7a2ab77d7562bf49f425c5c2"}, 252 | {file = "idna-3.4.tar.gz", hash = "sha256:814f528e8dead7d329833b91c5faa87d60bf71824cd12a7530b5526063d02cb4"}, 253 | ] 254 | 255 | [[package]] 256 | name = "importlib-metadata" 257 | version = "6.8.0" 258 | requires_python = ">=3.8" 259 | summary = "Read metadata from Python packages" 260 | dependencies = [ 261 | "zipp>=0.5", 262 | ] 263 | files = [ 264 | {file = "importlib_metadata-6.8.0-py3-none-any.whl", hash = "sha256:3ebb78df84a805d7698245025b975d9d67053cd94c79245ba4b3eb694abe68bb"}, 265 | {file = "importlib_metadata-6.8.0.tar.gz", hash = "sha256:dbace7892d8c0c4ac1ad096662232f831d4e64f4c4545bd53016a3e9d4654743"}, 266 | ] 267 | 268 | [[package]] 269 | name = "isort" 270 | version = "5.12.0" 271 | requires_python = ">=3.8.0" 272 | summary = "A Python utility / library to sort Python imports." 273 | files = [ 274 | {file = "isort-5.12.0-py3-none-any.whl", hash = "sha256:f84c2818376e66cf843d497486ea8fed8700b340f308f076c6fb1229dff318b6"}, 275 | {file = "isort-5.12.0.tar.gz", hash = "sha256:8bef7dde241278824a6d83f44a544709b065191b95b6e50894bdc722fcba0504"}, 276 | ] 277 | 278 | [[package]] 279 | name = "jinja2" 280 | version = "3.1.2" 281 | requires_python = ">=3.7" 282 | summary = "A very fast and expressive template engine." 283 | dependencies = [ 284 | "MarkupSafe>=2.0", 285 | ] 286 | files = [ 287 | {file = "Jinja2-3.1.2-py3-none-any.whl", hash = "sha256:6088930bfe239f0e6710546ab9c19c9ef35e29792895fed6e6e31a023a182a61"}, 288 | {file = "Jinja2-3.1.2.tar.gz", hash = "sha256:31351a702a408a9e7595a8fc6150fc3f43bb6bf7e319770cbc0db9df9437e852"}, 289 | ] 290 | 291 | [[package]] 292 | name = "launart" 293 | version = "0.7.0" 294 | requires_python = ">=3.8" 295 | summary = "Component lifetime manager for runtime." 296 | dependencies = [ 297 | "creart>=0.3.0", 298 | "loguru>=0.6.0", 299 | "statv>=0.2.2", 300 | ] 301 | files = [ 302 | {file = "launart-0.7.0-py3-none-any.whl", hash = "sha256:0b27f90a1ef01d00a2bb47b1f81da59a37f0936e1d7b3abe16f5188d0ed2c510"}, 303 | {file = "launart-0.7.0.tar.gz", hash = "sha256:c6c29175b584c18c89eec2c6353f99a279c1a4444c18cd259fe2ed8bbaab6f5d"}, 304 | ] 305 | 306 | [[package]] 307 | name = "loguru" 308 | version = "0.6.0" 309 | requires_python = ">=3.5" 310 | summary = "Python logging made (stupidly) simple" 311 | dependencies = [ 312 | "colorama>=0.3.4; sys_platform == \"win32\"", 313 | "win32-setctime>=1.0.0; sys_platform == \"win32\"", 314 | ] 315 | files = [ 316 | {file = "loguru-0.6.0-py3-none-any.whl", hash = "sha256:4e2414d534a2ab57573365b3e6d0234dfb1d84b68b7f3b948e6fb743860a77c3"}, 317 | {file = "loguru-0.6.0.tar.gz", hash = "sha256:066bd06758d0a513e9836fd9c6b5a75bfb3fd36841f4b996bc60b547a309d41c"}, 318 | ] 319 | 320 | [[package]] 321 | name = "markdown" 322 | version = "3.4.4" 323 | requires_python = ">=3.7" 324 | summary = "Python implementation of John Gruber's Markdown." 325 | dependencies = [ 326 | "importlib-metadata>=4.4; python_version < \"3.10\"", 327 | ] 328 | files = [ 329 | {file = "Markdown-3.4.4-py3-none-any.whl", hash = "sha256:a4c1b65c0957b4bd9e7d86ddc7b3c9868fb9670660f6f99f6d1bca8954d5a941"}, 330 | {file = "Markdown-3.4.4.tar.gz", hash = "sha256:225c6123522495d4119a90b3a3ba31a1e87a70369e03f14799ea9c0d7183a3d6"}, 331 | ] 332 | 333 | [[package]] 334 | name = "markupsafe" 335 | version = "2.1.3" 336 | requires_python = ">=3.7" 337 | summary = "Safely add untrusted strings to HTML/XML markup." 338 | files = [ 339 | {file = "MarkupSafe-2.1.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:cd0f502fe016460680cd20aaa5a76d241d6f35a1c3350c474bac1273803893fa"}, 340 | {file = "MarkupSafe-2.1.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e09031c87a1e51556fdcb46e5bd4f59dfb743061cf93c4d6831bf894f125eb57"}, 341 | {file = "MarkupSafe-2.1.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:68e78619a61ecf91e76aa3e6e8e33fc4894a2bebe93410754bd28fce0a8a4f9f"}, 342 | {file = "MarkupSafe-2.1.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:65c1a9bcdadc6c28eecee2c119465aebff8f7a584dd719facdd9e825ec61ab52"}, 343 | {file = "MarkupSafe-2.1.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:525808b8019e36eb524b8c68acdd63a37e75714eac50e988180b169d64480a00"}, 344 | {file = "MarkupSafe-2.1.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:962f82a3086483f5e5f64dbad880d31038b698494799b097bc59c2edf392fce6"}, 345 | {file = "MarkupSafe-2.1.3-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:aa7bd130efab1c280bed0f45501b7c8795f9fdbeb02e965371bbef3523627779"}, 346 | {file = "MarkupSafe-2.1.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c9c804664ebe8f83a211cace637506669e7890fec1b4195b505c214e50dd4eb7"}, 347 | {file = "MarkupSafe-2.1.3-cp310-cp310-win32.whl", hash = "sha256:10bbfe99883db80bdbaff2dcf681dfc6533a614f700da1287707e8a5d78a8431"}, 348 | {file = "MarkupSafe-2.1.3-cp310-cp310-win_amd64.whl", hash = "sha256:1577735524cdad32f9f694208aa75e422adba74f1baee7551620e43a3141f559"}, 349 | {file = "MarkupSafe-2.1.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:ad9e82fb8f09ade1c3e1b996a6337afac2b8b9e365f926f5a61aacc71adc5b3c"}, 350 | {file = "MarkupSafe-2.1.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3c0fae6c3be832a0a0473ac912810b2877c8cb9d76ca48de1ed31e1c68386575"}, 351 | {file = "MarkupSafe-2.1.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b076b6226fb84157e3f7c971a47ff3a679d837cf338547532ab866c57930dbee"}, 352 | {file = "MarkupSafe-2.1.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bfce63a9e7834b12b87c64d6b155fdd9b3b96191b6bd334bf37db7ff1fe457f2"}, 353 | {file = "MarkupSafe-2.1.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:338ae27d6b8745585f87218a3f23f1512dbf52c26c28e322dbe54bcede54ccb9"}, 354 | {file = "MarkupSafe-2.1.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e4dd52d80b8c83fdce44e12478ad2e85c64ea965e75d66dbeafb0a3e77308fcc"}, 355 | {file = "MarkupSafe-2.1.3-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:df0be2b576a7abbf737b1575f048c23fb1d769f267ec4358296f31c2479db8f9"}, 356 | {file = "MarkupSafe-2.1.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:5bbe06f8eeafd38e5d0a4894ffec89378b6c6a625ff57e3028921f8ff59318ac"}, 357 | {file = "MarkupSafe-2.1.3-cp311-cp311-win32.whl", hash = "sha256:dd15ff04ffd7e05ffcb7fe79f1b98041b8ea30ae9234aed2a9168b5797c3effb"}, 358 | {file = "MarkupSafe-2.1.3-cp311-cp311-win_amd64.whl", hash = "sha256:134da1eca9ec0ae528110ccc9e48041e0828d79f24121a1a146161103c76e686"}, 359 | {file = "MarkupSafe-2.1.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:8e254ae696c88d98da6555f5ace2279cf7cd5b3f52be2b5cf97feafe883b58d2"}, 360 | {file = "MarkupSafe-2.1.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cb0932dc158471523c9637e807d9bfb93e06a95cbf010f1a38b98623b929ef2b"}, 361 | {file = "MarkupSafe-2.1.3-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9402b03f1a1b4dc4c19845e5c749e3ab82d5078d16a2a4c2cd2df62d57bb0707"}, 362 | {file = "MarkupSafe-2.1.3-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ca379055a47383d02a5400cb0d110cef0a776fc644cda797db0c5696cfd7e18e"}, 363 | {file = "MarkupSafe-2.1.3-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:b7ff0f54cb4ff66dd38bebd335a38e2c22c41a8ee45aa608efc890ac3e3931bc"}, 364 | {file = "MarkupSafe-2.1.3-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:c011a4149cfbcf9f03994ec2edffcb8b1dc2d2aede7ca243746df97a5d41ce48"}, 365 | {file = "MarkupSafe-2.1.3-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:56d9f2ecac662ca1611d183feb03a3fa4406469dafe241673d521dd5ae92a155"}, 366 | {file = "MarkupSafe-2.1.3-cp37-cp37m-win32.whl", hash = "sha256:8758846a7e80910096950b67071243da3e5a20ed2546e6392603c096778d48e0"}, 367 | {file = "MarkupSafe-2.1.3-cp37-cp37m-win_amd64.whl", hash = "sha256:787003c0ddb00500e49a10f2844fac87aa6ce977b90b0feaaf9de23c22508b24"}, 368 | {file = "MarkupSafe-2.1.3-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:2ef12179d3a291be237280175b542c07a36e7f60718296278d8593d21ca937d4"}, 369 | {file = "MarkupSafe-2.1.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:2c1b19b3aaacc6e57b7e25710ff571c24d6c3613a45e905b1fde04d691b98ee0"}, 370 | {file = "MarkupSafe-2.1.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8afafd99945ead6e075b973fefa56379c5b5c53fd8937dad92c662da5d8fd5ee"}, 371 | {file = "MarkupSafe-2.1.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8c41976a29d078bb235fea9b2ecd3da465df42a562910f9022f1a03107bd02be"}, 372 | {file = "MarkupSafe-2.1.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d080e0a5eb2529460b30190fcfcc4199bd7f827663f858a226a81bc27beaa97e"}, 373 | {file = "MarkupSafe-2.1.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:69c0f17e9f5a7afdf2cc9fb2d1ce6aabdb3bafb7f38017c0b77862bcec2bbad8"}, 374 | {file = "MarkupSafe-2.1.3-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:504b320cd4b7eff6f968eddf81127112db685e81f7e36e75f9f84f0df46041c3"}, 375 | {file = "MarkupSafe-2.1.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:42de32b22b6b804f42c5d98be4f7e5e977ecdd9ee9b660fda1a3edf03b11792d"}, 376 | {file = "MarkupSafe-2.1.3-cp38-cp38-win32.whl", hash = "sha256:ceb01949af7121f9fc39f7d27f91be8546f3fb112c608bc4029aef0bab86a2a5"}, 377 | {file = "MarkupSafe-2.1.3-cp38-cp38-win_amd64.whl", hash = "sha256:1b40069d487e7edb2676d3fbdb2b0829ffa2cd63a2ec26c4938b2d34391b4ecc"}, 378 | {file = "MarkupSafe-2.1.3-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:8023faf4e01efadfa183e863fefde0046de576c6f14659e8782065bcece22198"}, 379 | {file = "MarkupSafe-2.1.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6b2b56950d93e41f33b4223ead100ea0fe11f8e6ee5f641eb753ce4b77a7042b"}, 380 | {file = "MarkupSafe-2.1.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9dcdfd0eaf283af041973bff14a2e143b8bd64e069f4c383416ecd79a81aab58"}, 381 | {file = "MarkupSafe-2.1.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:05fb21170423db021895e1ea1e1f3ab3adb85d1c2333cbc2310f2a26bc77272e"}, 382 | {file = "MarkupSafe-2.1.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:282c2cb35b5b673bbcadb33a585408104df04f14b2d9b01d4c345a3b92861c2c"}, 383 | {file = "MarkupSafe-2.1.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:ab4a0df41e7c16a1392727727e7998a467472d0ad65f3ad5e6e765015df08636"}, 384 | {file = "MarkupSafe-2.1.3-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:7ef3cb2ebbf91e330e3bb937efada0edd9003683db6b57bb108c4001f37a02ea"}, 385 | {file = "MarkupSafe-2.1.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:0a4e4a1aff6c7ac4cd55792abf96c915634c2b97e3cc1c7129578aa68ebd754e"}, 386 | {file = "MarkupSafe-2.1.3-cp39-cp39-win32.whl", hash = "sha256:fec21693218efe39aa7f8599346e90c705afa52c5b31ae019b2e57e8f6542bb2"}, 387 | {file = "MarkupSafe-2.1.3-cp39-cp39-win_amd64.whl", hash = "sha256:3fd4abcb888d15a94f32b75d8fd18ee162ca0c064f35b11134be77050296d6ba"}, 388 | {file = "MarkupSafe-2.1.3.tar.gz", hash = "sha256:af598ed32d6ae86f1b747b82783958b1a4ab8f617b06fe68795c7f026abbdcad"}, 389 | ] 390 | 391 | [[package]] 392 | name = "mergedeep" 393 | version = "1.3.4" 394 | requires_python = ">=3.6" 395 | summary = "A deep merge function for 🐍." 396 | files = [ 397 | {file = "mergedeep-1.3.4-py3-none-any.whl", hash = "sha256:70775750742b25c0d8f36c55aed03d24c3384d17c951b3175d898bd778ef0307"}, 398 | {file = "mergedeep-1.3.4.tar.gz", hash = "sha256:0096d52e9dad9939c3d975a774666af186eda617e6ca84df4c94dec30004f2a8"}, 399 | ] 400 | 401 | [[package]] 402 | name = "mkdocs" 403 | version = "1.5.2" 404 | requires_python = ">=3.7" 405 | summary = "Project documentation with Markdown." 406 | dependencies = [ 407 | "click>=7.0", 408 | "colorama>=0.4; platform_system == \"Windows\"", 409 | "ghp-import>=1.0", 410 | "importlib-metadata>=4.3; python_version < \"3.10\"", 411 | "jinja2>=2.11.1", 412 | "markdown>=3.2.1", 413 | "markupsafe>=2.0.1", 414 | "mergedeep>=1.3.4", 415 | "packaging>=20.5", 416 | "pathspec>=0.11.1", 417 | "platformdirs>=2.2.0", 418 | "pyyaml-env-tag>=0.1", 419 | "pyyaml>=5.1", 420 | "watchdog>=2.0", 421 | ] 422 | files = [ 423 | {file = "mkdocs-1.5.2-py3-none-any.whl", hash = "sha256:60a62538519c2e96fe8426654a67ee177350451616118a41596ae7c876bb7eac"}, 424 | {file = "mkdocs-1.5.2.tar.gz", hash = "sha256:70d0da09c26cff288852471be03c23f0f521fc15cf16ac89c7a3bfb9ae8d24f9"}, 425 | ] 426 | 427 | [[package]] 428 | name = "mkdocs-autorefs" 429 | version = "0.5.0" 430 | requires_python = ">=3.8" 431 | summary = "Automatically link across pages in MkDocs." 432 | dependencies = [ 433 | "Markdown>=3.3", 434 | "mkdocs>=1.1", 435 | ] 436 | files = [ 437 | {file = "mkdocs_autorefs-0.5.0-py3-none-any.whl", hash = "sha256:7930fcb8ac1249f10e683967aeaddc0af49d90702af111a5e390e8b20b3d97ff"}, 438 | {file = "mkdocs_autorefs-0.5.0.tar.gz", hash = "sha256:9a5054a94c08d28855cfab967ada10ed5be76e2bfad642302a610b252c3274c0"}, 439 | ] 440 | 441 | [[package]] 442 | name = "mkdocs-gen-files" 443 | version = "0.5.0" 444 | requires_python = ">=3.7" 445 | summary = "MkDocs plugin to programmatically generate documentation pages during the build" 446 | dependencies = [ 447 | "mkdocs>=1.0.3", 448 | ] 449 | files = [ 450 | {file = "mkdocs_gen_files-0.5.0-py3-none-any.whl", hash = "sha256:7ac060096f3f40bd19039e7277dd3050be9a453c8ac578645844d4d91d7978ea"}, 451 | {file = "mkdocs_gen_files-0.5.0.tar.gz", hash = "sha256:4c7cf256b5d67062a788f6b1d035e157fc1a9498c2399be9af5257d4ff4d19bc"}, 452 | ] 453 | 454 | [[package]] 455 | name = "mkdocs-literate-nav" 456 | version = "0.6.0" 457 | requires_python = ">=3.7" 458 | summary = "MkDocs plugin to specify the navigation in Markdown instead of YAML" 459 | dependencies = [ 460 | "mkdocs>=1.0.3", 461 | ] 462 | files = [ 463 | {file = "mkdocs_literate_nav-0.6.0-py3-none-any.whl", hash = "sha256:8c1b84714e5974da5e44e011ec0069275ae7647270c13a679662cf6ffce675a4"}, 464 | {file = "mkdocs_literate_nav-0.6.0.tar.gz", hash = "sha256:81ccbea18163ae8e10bd0bd39237fe70c32a1f2dff6c170779f5d52dd98a0470"}, 465 | ] 466 | 467 | [[package]] 468 | name = "mkdocs-material" 469 | version = "9.1.21" 470 | requires_python = ">=3.7" 471 | summary = "Documentation that simply works" 472 | dependencies = [ 473 | "colorama>=0.4", 474 | "jinja2>=3.0", 475 | "markdown>=3.2", 476 | "mkdocs-material-extensions>=1.1", 477 | "mkdocs>=1.5.0", 478 | "pygments>=2.14", 479 | "pymdown-extensions>=9.9.1", 480 | "regex>=2022.4.24", 481 | "requests>=2.26", 482 | ] 483 | files = [ 484 | {file = "mkdocs_material-9.1.21-py3-none-any.whl", hash = "sha256:58bb2f11ef240632e176d6f0f7d1cff06be1d11c696a5a1b553b808b4280ed47"}, 485 | {file = "mkdocs_material-9.1.21.tar.gz", hash = "sha256:71940cdfca84ab296b6362889c25395b1621273fb16c93deda257adb7ff44ec8"}, 486 | ] 487 | 488 | [[package]] 489 | name = "mkdocs-material-extensions" 490 | version = "1.1.1" 491 | requires_python = ">=3.7" 492 | summary = "Extension pack for Python Markdown and MkDocs Material." 493 | files = [ 494 | {file = "mkdocs_material_extensions-1.1.1-py3-none-any.whl", hash = "sha256:e41d9f38e4798b6617ad98ca8f7f1157b1e4385ac1459ca1e4ea219b556df945"}, 495 | {file = "mkdocs_material_extensions-1.1.1.tar.gz", hash = "sha256:9c003da71e2cc2493d910237448c672e00cefc800d3d6ae93d2fc69979e3bd93"}, 496 | ] 497 | 498 | [[package]] 499 | name = "mkdocs-section-index" 500 | version = "0.3.5" 501 | requires_python = ">=3.7" 502 | summary = "MkDocs plugin to allow clickable sections that lead to an index page" 503 | dependencies = [ 504 | "mkdocs>=1.0.3", 505 | ] 506 | files = [ 507 | {file = "mkdocs_section_index-0.3.5-py3-none-any.whl", hash = "sha256:1f6359287b0a823d6297cf1cb6c0a49ed75851d0d1cea8b425b207a45ce10141"}, 508 | {file = "mkdocs_section_index-0.3.5.tar.gz", hash = "sha256:fa8b1ce0649326b1873c6460c1df2bb0c4825fd21e3dd416f13ec212d31edf12"}, 509 | ] 510 | 511 | [[package]] 512 | name = "mkdocstrings" 513 | version = "0.22.0" 514 | requires_python = ">=3.7" 515 | summary = "Automatic documentation from sources, for MkDocs." 516 | dependencies = [ 517 | "Jinja2>=2.11.1", 518 | "Markdown>=3.3", 519 | "MarkupSafe>=1.1", 520 | "importlib-metadata>=4.6; python_version < \"3.10\"", 521 | "mkdocs-autorefs>=0.3.1", 522 | "mkdocs>=1.2", 523 | "pymdown-extensions>=6.3", 524 | "typing-extensions>=4.1; python_version < \"3.10\"", 525 | ] 526 | files = [ 527 | {file = "mkdocstrings-0.22.0-py3-none-any.whl", hash = "sha256:2d4095d461554ff6a778fdabdca3c00c468c2f1459d469f7a7f622a2b23212ba"}, 528 | {file = "mkdocstrings-0.22.0.tar.gz", hash = "sha256:82a33b94150ebb3d4b5c73bab4598c3e21468c79ec072eff6931c8f3bfc38256"}, 529 | ] 530 | 531 | [[package]] 532 | name = "mkdocstrings-python" 533 | version = "1.2.1" 534 | requires_python = ">=3.8" 535 | summary = "A Python handler for mkdocstrings." 536 | dependencies = [ 537 | "griffe>=0.30", 538 | "mkdocstrings>=0.20", 539 | ] 540 | files = [ 541 | {file = "mkdocstrings_python-1.2.1-py3-none-any.whl", hash = "sha256:7c08f33e9ba7b1655e9cf0608eba3ce7a9513bd8b42a68a8d24ffaf4a6a50cfc"}, 542 | {file = "mkdocstrings_python-1.2.1.tar.gz", hash = "sha256:ae40825b3b676a94626882901ed9c8fcf9a7f0330e466ffe37ce15c525987aa9"}, 543 | ] 544 | 545 | [[package]] 546 | name = "mkdocstrings" 547 | version = "0.22.0" 548 | extras = ["python"] 549 | requires_python = ">=3.7" 550 | summary = "Automatic documentation from sources, for MkDocs." 551 | dependencies = [ 552 | "mkdocstrings-python>=0.5.2", 553 | "mkdocstrings==0.22.0", 554 | ] 555 | files = [ 556 | {file = "mkdocstrings-0.22.0-py3-none-any.whl", hash = "sha256:2d4095d461554ff6a778fdabdca3c00c468c2f1459d469f7a7f622a2b23212ba"}, 557 | {file = "mkdocstrings-0.22.0.tar.gz", hash = "sha256:82a33b94150ebb3d4b5c73bab4598c3e21468c79ec072eff6931c8f3bfc38256"}, 558 | ] 559 | 560 | [[package]] 561 | name = "mypy-extensions" 562 | version = "1.0.0" 563 | requires_python = ">=3.5" 564 | summary = "Type system extensions for programs checked with the mypy type checker." 565 | files = [ 566 | {file = "mypy_extensions-1.0.0-py3-none-any.whl", hash = "sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d"}, 567 | {file = "mypy_extensions-1.0.0.tar.gz", hash = "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782"}, 568 | ] 569 | 570 | [[package]] 571 | name = "packaging" 572 | version = "23.1" 573 | requires_python = ">=3.7" 574 | summary = "Core utilities for Python packages" 575 | files = [ 576 | {file = "packaging-23.1-py3-none-any.whl", hash = "sha256:994793af429502c4ea2ebf6bf664629d07c1a9fe974af92966e4b8d2df7edc61"}, 577 | {file = "packaging-23.1.tar.gz", hash = "sha256:a392980d2b6cffa644431898be54b0045151319d1e7ec34f0cfed48767dd334f"}, 578 | ] 579 | 580 | [[package]] 581 | name = "pathspec" 582 | version = "0.11.2" 583 | requires_python = ">=3.7" 584 | summary = "Utility library for gitignore style pattern matching of file paths." 585 | files = [ 586 | {file = "pathspec-0.11.2-py3-none-any.whl", hash = "sha256:1d6ed233af05e679efb96b1851550ea95bbb64b7c490b0f5aa52996c11e92a20"}, 587 | {file = "pathspec-0.11.2.tar.gz", hash = "sha256:e0d8d0ac2f12da61956eb2306b69f9469b42f4deb0f3cb6ed47b9cce9996ced3"}, 588 | ] 589 | 590 | [[package]] 591 | name = "platformdirs" 592 | version = "3.10.0" 593 | requires_python = ">=3.7" 594 | summary = "A small Python package for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." 595 | files = [ 596 | {file = "platformdirs-3.10.0-py3-none-any.whl", hash = "sha256:d7c24979f292f916dc9cbf8648319032f551ea8c49a4c9bf2fb556a02070ec1d"}, 597 | {file = "platformdirs-3.10.0.tar.gz", hash = "sha256:b45696dab2d7cc691a3226759c0d3b00c47c8b6e293d96f6436f733303f77f6d"}, 598 | ] 599 | 600 | [[package]] 601 | name = "pygments" 602 | version = "2.15.1" 603 | requires_python = ">=3.7" 604 | summary = "Pygments is a syntax highlighting package written in Python." 605 | files = [ 606 | {file = "Pygments-2.15.1-py3-none-any.whl", hash = "sha256:db2db3deb4b4179f399a09054b023b6a586b76499d36965813c71aa8ed7b5fd1"}, 607 | {file = "Pygments-2.15.1.tar.gz", hash = "sha256:8ace4d3c1dd481894b2005f560ead0f9f19ee64fe983366be1a21e171d12775c"}, 608 | ] 609 | 610 | [[package]] 611 | name = "pymdown-extensions" 612 | version = "10.1" 613 | requires_python = ">=3.7" 614 | summary = "Extension pack for Python Markdown." 615 | dependencies = [ 616 | "markdown>=3.2", 617 | "pyyaml", 618 | ] 619 | files = [ 620 | {file = "pymdown_extensions-10.1-py3-none-any.whl", hash = "sha256:ef25dbbae530e8f67575d222b75ff0649b1e841e22c2ae9a20bad9472c2207dc"}, 621 | {file = "pymdown_extensions-10.1.tar.gz", hash = "sha256:508009b211373058debb8247e168de4cbcb91b1bff7b5e961b2c3e864e00b195"}, 622 | ] 623 | 624 | [[package]] 625 | name = "python-dateutil" 626 | version = "2.8.2" 627 | requires_python = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" 628 | summary = "Extensions to the standard Python datetime module" 629 | dependencies = [ 630 | "six>=1.5", 631 | ] 632 | files = [ 633 | {file = "python-dateutil-2.8.2.tar.gz", hash = "sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86"}, 634 | {file = "python_dateutil-2.8.2-py2.py3-none-any.whl", hash = "sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9"}, 635 | ] 636 | 637 | [[package]] 638 | name = "pyyaml" 639 | version = "6.0.1" 640 | requires_python = ">=3.6" 641 | summary = "YAML parser and emitter for Python" 642 | files = [ 643 | {file = "PyYAML-6.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d858aa552c999bc8a8d57426ed01e40bef403cd8ccdd0fc5f6f04a00414cac2a"}, 644 | {file = "PyYAML-6.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:fd66fc5d0da6d9815ba2cebeb4205f95818ff4b79c3ebe268e75d961704af52f"}, 645 | {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:69b023b2b4daa7548bcfbd4aa3da05b3a74b772db9e23b982788168117739938"}, 646 | {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:81e0b275a9ecc9c0c0c07b4b90ba548307583c125f54d5b6946cfee6360c733d"}, 647 | {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba336e390cd8e4d1739f42dfe9bb83a3cc2e80f567d8805e11b46f4a943f5515"}, 648 | {file = "PyYAML-6.0.1-cp310-cp310-win32.whl", hash = "sha256:bd4af7373a854424dabd882decdc5579653d7868b8fb26dc7d0e99f823aa5924"}, 649 | {file = "PyYAML-6.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:fd1592b3fdf65fff2ad0004b5e363300ef59ced41c2e6b3a99d4089fa8c5435d"}, 650 | {file = "PyYAML-6.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6965a7bc3cf88e5a1c3bd2e0b5c22f8d677dc88a455344035f03399034eb3007"}, 651 | {file = "PyYAML-6.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f003ed9ad21d6a4713f0a9b5a7a0a79e08dd0f221aff4525a2be4c346ee60aab"}, 652 | {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:42f8152b8dbc4fe7d96729ec2b99c7097d656dc1213a3229ca5383f973a5ed6d"}, 653 | {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:062582fca9fabdd2c8b54a3ef1c978d786e0f6b3a1510e0ac93ef59e0ddae2bc"}, 654 | {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d2b04aac4d386b172d5b9692e2d2da8de7bfb6c387fa4f801fbf6fb2e6ba4673"}, 655 | {file = "PyYAML-6.0.1-cp311-cp311-win32.whl", hash = "sha256:1635fd110e8d85d55237ab316b5b011de701ea0f29d07611174a1b42f1444741"}, 656 | {file = "PyYAML-6.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34"}, 657 | {file = "PyYAML-6.0.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:50550eb667afee136e9a77d6dc71ae76a44df8b3e51e41b77f6de2932bfe0f47"}, 658 | {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1fe35611261b29bd1de0070f0b2f47cb6ff71fa6595c077e42bd0c419fa27b98"}, 659 | {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:704219a11b772aea0d8ecd7058d0082713c3562b4e271b849ad7dc4a5c90c13c"}, 660 | {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:afd7e57eddb1a54f0f1a974bc4391af8bcce0b444685d936840f125cf046d5bd"}, 661 | {file = "PyYAML-6.0.1-cp36-cp36m-win32.whl", hash = "sha256:fca0e3a251908a499833aa292323f32437106001d436eca0e6e7833256674585"}, 662 | {file = "PyYAML-6.0.1-cp36-cp36m-win_amd64.whl", hash = "sha256:f22ac1c3cac4dbc50079e965eba2c1058622631e526bd9afd45fedd49ba781fa"}, 663 | {file = "PyYAML-6.0.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:b1275ad35a5d18c62a7220633c913e1b42d44b46ee12554e5fd39c70a243d6a3"}, 664 | {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:18aeb1bf9a78867dc38b259769503436b7c72f7a1f1f4c93ff9a17de54319b27"}, 665 | {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:596106435fa6ad000c2991a98fa58eeb8656ef2325d7e158344fb33864ed87e3"}, 666 | {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:baa90d3f661d43131ca170712d903e6295d1f7a0f595074f151c0aed377c9b9c"}, 667 | {file = "PyYAML-6.0.1-cp37-cp37m-win32.whl", hash = "sha256:9046c58c4395dff28dd494285c82ba00b546adfc7ef001486fbf0324bc174fba"}, 668 | {file = "PyYAML-6.0.1-cp37-cp37m-win_amd64.whl", hash = "sha256:4fb147e7a67ef577a588a0e2c17b6db51dda102c71de36f8549b6816a96e1867"}, 669 | {file = "PyYAML-6.0.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1d4c7e777c441b20e32f52bd377e0c409713e8bb1386e1099c2415f26e479595"}, 670 | {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5"}, 671 | {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:28c119d996beec18c05208a8bd78cbe4007878c6dd15091efb73a30e90539696"}, 672 | {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e07cbde391ba96ab58e532ff4803f79c4129397514e1413a7dc761ccd755735"}, 673 | {file = "PyYAML-6.0.1-cp38-cp38-win32.whl", hash = "sha256:184c5108a2aca3c5b3d3bf9395d50893a7ab82a38004c8f61c258d4428e80206"}, 674 | {file = "PyYAML-6.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:1e2722cc9fbb45d9b87631ac70924c11d3a401b2d7f410cc0e3bbf249f2dca62"}, 675 | {file = "PyYAML-6.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8"}, 676 | {file = "PyYAML-6.0.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c8098ddcc2a85b61647b2590f825f3db38891662cfc2fc776415143f599bb859"}, 677 | {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5773183b6446b2c99bb77e77595dd486303b4faab2b086e7b17bc6bef28865f6"}, 678 | {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b786eecbdf8499b9ca1d697215862083bd6d2a99965554781d0d8d1ad31e13a0"}, 679 | {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc1bf2925a1ecd43da378f4db9e4f799775d6367bdb94671027b73b393a7c42c"}, 680 | {file = "PyYAML-6.0.1-cp39-cp39-win32.whl", hash = "sha256:faca3bdcf85b2fc05d06ff3fbc1f83e1391b3e724afa3feba7d13eeab355484c"}, 681 | {file = "PyYAML-6.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:510c9deebc5c0225e8c96813043e62b680ba2f9c50a08d3724c7f28a747d1486"}, 682 | {file = "PyYAML-6.0.1.tar.gz", hash = "sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43"}, 683 | ] 684 | 685 | [[package]] 686 | name = "pyyaml-env-tag" 687 | version = "0.1" 688 | requires_python = ">=3.6" 689 | summary = "A custom YAML tag for referencing environment variables in YAML files. " 690 | dependencies = [ 691 | "pyyaml", 692 | ] 693 | files = [ 694 | {file = "pyyaml_env_tag-0.1-py3-none-any.whl", hash = "sha256:af31106dec8a4d68c60207c1886031cbf839b68aa7abccdb19868200532c2069"}, 695 | {file = "pyyaml_env_tag-0.1.tar.gz", hash = "sha256:70092675bda14fdec33b31ba77e7543de9ddc88f2e5b99160396572d11525bdb"}, 696 | ] 697 | 698 | [[package]] 699 | name = "regex" 700 | version = "2023.6.3" 701 | requires_python = ">=3.6" 702 | summary = "Alternative regular expression module, to replace re." 703 | files = [ 704 | {file = "regex-2023.6.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:824bf3ac11001849aec3fa1d69abcb67aac3e150a933963fb12bda5151fe1bfd"}, 705 | {file = "regex-2023.6.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:05ed27acdf4465c95826962528f9e8d41dbf9b1aa8531a387dee6ed215a3e9ef"}, 706 | {file = "regex-2023.6.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0b49c764f88a79160fa64f9a7b425620e87c9f46095ef9c9920542ab2495c8bc"}, 707 | {file = "regex-2023.6.3-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8e3f1316c2293e5469f8f09dc2d76efb6c3982d3da91ba95061a7e69489a14ef"}, 708 | {file = "regex-2023.6.3-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:43e1dd9d12df9004246bacb79a0e5886b3b6071b32e41f83b0acbf293f820ee8"}, 709 | {file = "regex-2023.6.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4959e8bcbfda5146477d21c3a8ad81b185cd252f3d0d6e4724a5ef11c012fb06"}, 710 | {file = "regex-2023.6.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:af4dd387354dc83a3bff67127a124c21116feb0d2ef536805c454721c5d7993d"}, 711 | {file = "regex-2023.6.3-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:2239d95d8e243658b8dbb36b12bd10c33ad6e6933a54d36ff053713f129aa536"}, 712 | {file = "regex-2023.6.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:890e5a11c97cf0d0c550eb661b937a1e45431ffa79803b942a057c4fb12a2da2"}, 713 | {file = "regex-2023.6.3-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:a8105e9af3b029f243ab11ad47c19b566482c150c754e4c717900a798806b222"}, 714 | {file = "regex-2023.6.3-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:25be746a8ec7bc7b082783216de8e9473803706723b3f6bef34b3d0ed03d57e2"}, 715 | {file = "regex-2023.6.3-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:3676f1dd082be28b1266c93f618ee07741b704ab7b68501a173ce7d8d0d0ca18"}, 716 | {file = "regex-2023.6.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:10cb847aeb1728412c666ab2e2000ba6f174f25b2bdc7292e7dd71b16db07568"}, 717 | {file = "regex-2023.6.3-cp310-cp310-win32.whl", hash = "sha256:dbbbfce33cd98f97f6bffb17801b0576e653f4fdb1d399b2ea89638bc8d08ae1"}, 718 | {file = "regex-2023.6.3-cp310-cp310-win_amd64.whl", hash = "sha256:c5f8037000eb21e4823aa485149f2299eb589f8d1fe4b448036d230c3f4e68e0"}, 719 | {file = "regex-2023.6.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c123f662be8ec5ab4ea72ea300359023a5d1df095b7ead76fedcd8babbedf969"}, 720 | {file = "regex-2023.6.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:9edcbad1f8a407e450fbac88d89e04e0b99a08473f666a3f3de0fd292badb6aa"}, 721 | {file = "regex-2023.6.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dcba6dae7de533c876255317c11f3abe4907ba7d9aa15d13e3d9710d4315ec0e"}, 722 | {file = "regex-2023.6.3-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:29cdd471ebf9e0f2fb3cac165efedc3c58db841d83a518b082077e612d3ee5df"}, 723 | {file = "regex-2023.6.3-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:12b74fbbf6cbbf9dbce20eb9b5879469e97aeeaa874145517563cca4029db65c"}, 724 | {file = "regex-2023.6.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0c29ca1bd61b16b67be247be87390ef1d1ef702800f91fbd1991f5c4421ebae8"}, 725 | {file = "regex-2023.6.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d77f09bc4b55d4bf7cc5eba785d87001d6757b7c9eec237fe2af57aba1a071d9"}, 726 | {file = "regex-2023.6.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:ea353ecb6ab5f7e7d2f4372b1e779796ebd7b37352d290096978fea83c4dba0c"}, 727 | {file = "regex-2023.6.3-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:10590510780b7541969287512d1b43f19f965c2ece6c9b1c00fc367b29d8dce7"}, 728 | {file = "regex-2023.6.3-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:e2fbd6236aae3b7f9d514312cdb58e6494ee1c76a9948adde6eba33eb1c4264f"}, 729 | {file = "regex-2023.6.3-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:6b2675068c8b56f6bfd5a2bda55b8accbb96c02fd563704732fd1c95e2083461"}, 730 | {file = "regex-2023.6.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:74419d2b50ecb98360cfaa2974da8689cb3b45b9deff0dcf489c0d333bcc1477"}, 731 | {file = "regex-2023.6.3-cp311-cp311-win32.whl", hash = "sha256:fb5ec16523dc573a4b277663a2b5a364e2099902d3944c9419a40ebd56a118f9"}, 732 | {file = "regex-2023.6.3-cp311-cp311-win_amd64.whl", hash = "sha256:09e4a1a6acc39294a36b7338819b10baceb227f7f7dbbea0506d419b5a1dd8af"}, 733 | {file = "regex-2023.6.3-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:0654bca0cdf28a5956c83839162692725159f4cda8d63e0911a2c0dc76166525"}, 734 | {file = "regex-2023.6.3-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:463b6a3ceb5ca952e66550a4532cef94c9a0c80dc156c4cc343041951aec1697"}, 735 | {file = "regex-2023.6.3-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:87b2a5bb5e78ee0ad1de71c664d6eb536dc3947a46a69182a90f4410f5e3f7dd"}, 736 | {file = "regex-2023.6.3-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6343c6928282c1f6a9db41f5fd551662310e8774c0e5ebccb767002fcf663ca9"}, 737 | {file = "regex-2023.6.3-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b6192d5af2ccd2a38877bfef086d35e6659566a335b1492786ff254c168b1693"}, 738 | {file = "regex-2023.6.3-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:74390d18c75054947e4194019077e243c06fbb62e541d8817a0fa822ea310c14"}, 739 | {file = "regex-2023.6.3-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:742e19a90d9bb2f4a6cf2862b8b06dea5e09b96c9f2df1779e53432d7275331f"}, 740 | {file = "regex-2023.6.3-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:8abbc5d54ea0ee80e37fef009e3cec5dafd722ed3c829126253d3e22f3846f1e"}, 741 | {file = "regex-2023.6.3-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:c2b867c17a7a7ae44c43ebbeb1b5ff406b3e8d5b3e14662683e5e66e6cc868d3"}, 742 | {file = "regex-2023.6.3-cp36-cp36m-musllinux_1_1_ppc64le.whl", hash = "sha256:d831c2f8ff278179705ca59f7e8524069c1a989e716a1874d6d1aab6119d91d1"}, 743 | {file = "regex-2023.6.3-cp36-cp36m-musllinux_1_1_s390x.whl", hash = "sha256:ee2d1a9a253b1729bb2de27d41f696ae893507c7db224436abe83ee25356f5c1"}, 744 | {file = "regex-2023.6.3-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:61474f0b41fe1a80e8dfa70f70ea1e047387b7cd01c85ec88fa44f5d7561d787"}, 745 | {file = "regex-2023.6.3-cp36-cp36m-win32.whl", hash = "sha256:0b71e63226e393b534105fcbdd8740410dc6b0854c2bfa39bbda6b0d40e59a54"}, 746 | {file = "regex-2023.6.3-cp36-cp36m-win_amd64.whl", hash = "sha256:bbb02fd4462f37060122e5acacec78e49c0fbb303c30dd49c7f493cf21fc5b27"}, 747 | {file = "regex-2023.6.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:b862c2b9d5ae38a68b92e215b93f98d4c5e9454fa36aae4450f61dd33ff48487"}, 748 | {file = "regex-2023.6.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:976d7a304b59ede34ca2921305b57356694f9e6879db323fd90a80f865d355a3"}, 749 | {file = "regex-2023.6.3-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:83320a09188e0e6c39088355d423aa9d056ad57a0b6c6381b300ec1a04ec3d16"}, 750 | {file = "regex-2023.6.3-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9427a399501818a7564f8c90eced1e9e20709ece36be701f394ada99890ea4b3"}, 751 | {file = "regex-2023.6.3-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7178bbc1b2ec40eaca599d13c092079bf529679bf0371c602edaa555e10b41c3"}, 752 | {file = "regex-2023.6.3-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:837328d14cde912af625d5f303ec29f7e28cdab588674897baafaf505341f2fc"}, 753 | {file = "regex-2023.6.3-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:2d44dc13229905ae96dd2ae2dd7cebf824ee92bc52e8cf03dcead37d926da019"}, 754 | {file = "regex-2023.6.3-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:d54af539295392611e7efbe94e827311eb8b29668e2b3f4cadcfe6f46df9c777"}, 755 | {file = "regex-2023.6.3-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:7117d10690c38a622e54c432dfbbd3cbd92f09401d622902c32f6d377e2300ee"}, 756 | {file = "regex-2023.6.3-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:bb60b503ec8a6e4e3e03a681072fa3a5adcbfa5479fa2d898ae2b4a8e24c4591"}, 757 | {file = "regex-2023.6.3-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:65ba8603753cec91c71de423a943ba506363b0e5c3fdb913ef8f9caa14b2c7e0"}, 758 | {file = "regex-2023.6.3-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:271f0bdba3c70b58e6f500b205d10a36fb4b58bd06ac61381b68de66442efddb"}, 759 | {file = "regex-2023.6.3-cp37-cp37m-win32.whl", hash = "sha256:9beb322958aaca059f34975b0df135181f2e5d7a13b84d3e0e45434749cb20f7"}, 760 | {file = "regex-2023.6.3-cp37-cp37m-win_amd64.whl", hash = "sha256:fea75c3710d4f31389eed3c02f62d0b66a9da282521075061ce875eb5300cf23"}, 761 | {file = "regex-2023.6.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:8f56fcb7ff7bf7404becdfc60b1e81a6d0561807051fd2f1860b0d0348156a07"}, 762 | {file = "regex-2023.6.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:d2da3abc88711bce7557412310dfa50327d5769a31d1c894b58eb256459dc289"}, 763 | {file = "regex-2023.6.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a99b50300df5add73d307cf66abea093304a07eb017bce94f01e795090dea87c"}, 764 | {file = "regex-2023.6.3-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5708089ed5b40a7b2dc561e0c8baa9535b77771b64a8330b684823cfd5116036"}, 765 | {file = "regex-2023.6.3-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:687ea9d78a4b1cf82f8479cab23678aff723108df3edeac098e5b2498879f4a7"}, 766 | {file = "regex-2023.6.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4d3850beab9f527f06ccc94b446c864059c57651b3f911fddb8d9d3ec1d1b25d"}, 767 | {file = "regex-2023.6.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e8915cc96abeb8983cea1df3c939e3c6e1ac778340c17732eb63bb96247b91d2"}, 768 | {file = "regex-2023.6.3-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:841d6e0e5663d4c7b4c8099c9997be748677d46cbf43f9f471150e560791f7ff"}, 769 | {file = "regex-2023.6.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:9edce5281f965cf135e19840f4d93d55b3835122aa76ccacfd389e880ba4cf82"}, 770 | {file = "regex-2023.6.3-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:b956231ebdc45f5b7a2e1f90f66a12be9610ce775fe1b1d50414aac1e9206c06"}, 771 | {file = "regex-2023.6.3-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:36efeba71c6539d23c4643be88295ce8c82c88bbd7c65e8a24081d2ca123da3f"}, 772 | {file = "regex-2023.6.3-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:cf67ca618b4fd34aee78740bea954d7c69fdda419eb208c2c0c7060bb822d747"}, 773 | {file = "regex-2023.6.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:b4598b1897837067a57b08147a68ac026c1e73b31ef6e36deeeb1fa60b2933c9"}, 774 | {file = "regex-2023.6.3-cp38-cp38-win32.whl", hash = "sha256:f415f802fbcafed5dcc694c13b1292f07fe0befdb94aa8a52905bd115ff41e88"}, 775 | {file = "regex-2023.6.3-cp38-cp38-win_amd64.whl", hash = "sha256:d4f03bb71d482f979bda92e1427f3ec9b220e62a7dd337af0aa6b47bf4498f72"}, 776 | {file = "regex-2023.6.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:ccf91346b7bd20c790310c4147eee6ed495a54ddb6737162a36ce9dbef3e4751"}, 777 | {file = "regex-2023.6.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:b28f5024a3a041009eb4c333863d7894d191215b39576535c6734cd88b0fcb68"}, 778 | {file = "regex-2023.6.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e0bb18053dfcfed432cc3ac632b5e5e5c5b7e55fb3f8090e867bfd9b054dbcbf"}, 779 | {file = "regex-2023.6.3-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9a5bfb3004f2144a084a16ce19ca56b8ac46e6fd0651f54269fc9e230edb5e4a"}, 780 | {file = "regex-2023.6.3-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5c6b48d0fa50d8f4df3daf451be7f9689c2bde1a52b1225c5926e3f54b6a9ed1"}, 781 | {file = "regex-2023.6.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:051da80e6eeb6e239e394ae60704d2b566aa6a7aed6f2890a7967307267a5dc6"}, 782 | {file = "regex-2023.6.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a4c3b7fa4cdaa69268748665a1a6ff70c014d39bb69c50fda64b396c9116cf77"}, 783 | {file = "regex-2023.6.3-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:457b6cce21bee41ac292d6753d5e94dcbc5c9e3e3a834da285b0bde7aa4a11e9"}, 784 | {file = "regex-2023.6.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:aad51907d74fc183033ad796dd4c2e080d1adcc4fd3c0fd4fd499f30c03011cd"}, 785 | {file = "regex-2023.6.3-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:0385e73da22363778ef2324950e08b689abdf0b108a7d8decb403ad7f5191938"}, 786 | {file = "regex-2023.6.3-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:c6a57b742133830eec44d9b2290daf5cbe0a2f1d6acee1b3c7b1c7b2f3606df7"}, 787 | {file = "regex-2023.6.3-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:3e5219bf9e75993d73ab3d25985c857c77e614525fac9ae02b1bebd92f7cecac"}, 788 | {file = "regex-2023.6.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:e5087a3c59eef624a4591ef9eaa6e9a8d8a94c779dade95d27c0bc24650261cd"}, 789 | {file = "regex-2023.6.3-cp39-cp39-win32.whl", hash = "sha256:20326216cc2afe69b6e98528160b225d72f85ab080cbdf0b11528cbbaba2248f"}, 790 | {file = "regex-2023.6.3-cp39-cp39-win_amd64.whl", hash = "sha256:bdff5eab10e59cf26bc479f565e25ed71a7d041d1ded04ccf9aee1d9f208487a"}, 791 | {file = "regex-2023.6.3.tar.gz", hash = "sha256:72d1a25bf36d2050ceb35b517afe13864865268dfb45910e2e17a84be6cbfeb0"}, 792 | ] 793 | 794 | [[package]] 795 | name = "requests" 796 | version = "2.31.0" 797 | requires_python = ">=3.7" 798 | summary = "Python HTTP for Humans." 799 | dependencies = [ 800 | "certifi>=2017.4.17", 801 | "charset-normalizer<4,>=2", 802 | "idna<4,>=2.5", 803 | "urllib3<3,>=1.21.1", 804 | ] 805 | files = [ 806 | {file = "requests-2.31.0-py3-none-any.whl", hash = "sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f"}, 807 | {file = "requests-2.31.0.tar.gz", hash = "sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1"}, 808 | ] 809 | 810 | [[package]] 811 | name = "six" 812 | version = "1.16.0" 813 | requires_python = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" 814 | summary = "Python 2 and 3 compatibility utilities" 815 | files = [ 816 | {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, 817 | {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, 818 | ] 819 | 820 | [[package]] 821 | name = "statv" 822 | version = "0.3.2" 823 | requires_python = ">=3.8" 824 | summary = "a uniform status implementation for graia project" 825 | files = [ 826 | {file = "statv-0.3.2-py3-none-any.whl", hash = "sha256:32e430b21ab6a62695c67ab6cae3dba6e01e9c3fdbc9344e3236ad7a1f51d0c7"}, 827 | {file = "statv-0.3.2.tar.gz", hash = "sha256:fb4df2a37bf7a792e36a6e657c74cbdef9e2cdb8de3a0762b28b35c9e13f0fdd"}, 828 | ] 829 | 830 | [[package]] 831 | name = "tomli" 832 | version = "2.0.1" 833 | requires_python = ">=3.7" 834 | summary = "A lil' TOML parser" 835 | files = [ 836 | {file = "tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc"}, 837 | {file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"}, 838 | ] 839 | 840 | [[package]] 841 | name = "typing-extensions" 842 | version = "4.7.1" 843 | requires_python = ">=3.7" 844 | summary = "Backported and Experimental Type Hints for Python 3.7+" 845 | files = [ 846 | {file = "typing_extensions-4.7.1-py3-none-any.whl", hash = "sha256:440d5dd3af93b060174bf433bccd69b0babc3b15b1a8dca43789fd7f61514b36"}, 847 | {file = "typing_extensions-4.7.1.tar.gz", hash = "sha256:b75ddc264f0ba5615db7ba217daeb99701ad295353c45f9e95963337ceeeffb2"}, 848 | ] 849 | 850 | [[package]] 851 | name = "urllib3" 852 | version = "2.0.4" 853 | requires_python = ">=3.7" 854 | summary = "HTTP library with thread-safe connection pooling, file post, and more." 855 | files = [ 856 | {file = "urllib3-2.0.4-py3-none-any.whl", hash = "sha256:de7df1803967d2c2a98e4b11bb7d6bd9210474c46e8a0401514e3a42a75ebde4"}, 857 | {file = "urllib3-2.0.4.tar.gz", hash = "sha256:8d22f86aae8ef5e410d4f539fde9ce6b2113a001bb4d189e0aed70642d602b11"}, 858 | ] 859 | 860 | [[package]] 861 | name = "watchdog" 862 | version = "3.0.0" 863 | requires_python = ">=3.7" 864 | summary = "Filesystem events monitoring" 865 | files = [ 866 | {file = "watchdog-3.0.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:336adfc6f5cc4e037d52db31194f7581ff744b67382eb6021c868322e32eef41"}, 867 | {file = "watchdog-3.0.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a70a8dcde91be523c35b2bf96196edc5730edb347e374c7de7cd20c43ed95397"}, 868 | {file = "watchdog-3.0.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:adfdeab2da79ea2f76f87eb42a3ab1966a5313e5a69a0213a3cc06ef692b0e96"}, 869 | {file = "watchdog-3.0.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:2b57a1e730af3156d13b7fdddfc23dea6487fceca29fc75c5a868beed29177ae"}, 870 | {file = "watchdog-3.0.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:7ade88d0d778b1b222adebcc0927428f883db07017618a5e684fd03b83342bd9"}, 871 | {file = "watchdog-3.0.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:7e447d172af52ad204d19982739aa2346245cc5ba6f579d16dac4bfec226d2e7"}, 872 | {file = "watchdog-3.0.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:9fac43a7466eb73e64a9940ac9ed6369baa39b3bf221ae23493a9ec4d0022674"}, 873 | {file = "watchdog-3.0.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:8ae9cda41fa114e28faf86cb137d751a17ffd0316d1c34ccf2235e8a84365c7f"}, 874 | {file = "watchdog-3.0.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:25f70b4aa53bd743729c7475d7ec41093a580528b100e9a8c5b5efe8899592fc"}, 875 | {file = "watchdog-3.0.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:4f94069eb16657d2c6faada4624c39464f65c05606af50bb7902e036e3219be3"}, 876 | {file = "watchdog-3.0.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:7c5f84b5194c24dd573fa6472685b2a27cc5a17fe5f7b6fd40345378ca6812e3"}, 877 | {file = "watchdog-3.0.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:3aa7f6a12e831ddfe78cdd4f8996af9cf334fd6346531b16cec61c3b3c0d8da0"}, 878 | {file = "watchdog-3.0.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:233b5817932685d39a7896b1090353fc8efc1ef99c9c054e46c8002561252fb8"}, 879 | {file = "watchdog-3.0.0-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:13bbbb462ee42ec3c5723e1205be8ced776f05b100e4737518c67c8325cf6100"}, 880 | {file = "watchdog-3.0.0-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:8f3ceecd20d71067c7fd4c9e832d4e22584318983cabc013dbf3f70ea95de346"}, 881 | {file = "watchdog-3.0.0-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:c9d8c8ec7efb887333cf71e328e39cffbf771d8f8f95d308ea4125bf5f90ba64"}, 882 | {file = "watchdog-3.0.0-py3-none-manylinux2014_aarch64.whl", hash = "sha256:0e06ab8858a76e1219e68c7573dfeba9dd1c0219476c5a44d5333b01d7e1743a"}, 883 | {file = "watchdog-3.0.0-py3-none-manylinux2014_armv7l.whl", hash = "sha256:d00e6be486affb5781468457b21a6cbe848c33ef43f9ea4a73b4882e5f188a44"}, 884 | {file = "watchdog-3.0.0-py3-none-manylinux2014_i686.whl", hash = "sha256:c07253088265c363d1ddf4b3cdb808d59a0468ecd017770ed716991620b8f77a"}, 885 | {file = "watchdog-3.0.0-py3-none-manylinux2014_ppc64.whl", hash = "sha256:5113334cf8cf0ac8cd45e1f8309a603291b614191c9add34d33075727a967709"}, 886 | {file = "watchdog-3.0.0-py3-none-manylinux2014_ppc64le.whl", hash = "sha256:51f90f73b4697bac9c9a78394c3acbbd331ccd3655c11be1a15ae6fe289a8c83"}, 887 | {file = "watchdog-3.0.0-py3-none-manylinux2014_s390x.whl", hash = "sha256:ba07e92756c97e3aca0912b5cbc4e5ad802f4557212788e72a72a47ff376950d"}, 888 | {file = "watchdog-3.0.0-py3-none-manylinux2014_x86_64.whl", hash = "sha256:d429c2430c93b7903914e4db9a966c7f2b068dd2ebdd2fa9b9ce094c7d459f33"}, 889 | {file = "watchdog-3.0.0-py3-none-win32.whl", hash = "sha256:3ed7c71a9dccfe838c2f0b6314ed0d9b22e77d268c67e015450a29036a81f60f"}, 890 | {file = "watchdog-3.0.0-py3-none-win_amd64.whl", hash = "sha256:4c9956d27be0bb08fc5f30d9d0179a855436e655f046d288e2bcc11adfae893c"}, 891 | {file = "watchdog-3.0.0-py3-none-win_ia64.whl", hash = "sha256:5d9f3a10e02d7371cd929b5d8f11e87d4bad890212ed3901f9b4d68767bee759"}, 892 | {file = "watchdog-3.0.0.tar.gz", hash = "sha256:4d98a320595da7a7c5a18fc48cb633c2e73cda78f93cac2ef42d42bf609a33f9"}, 893 | ] 894 | 895 | [[package]] 896 | name = "win32-setctime" 897 | version = "1.1.0" 898 | requires_python = ">=3.5" 899 | summary = "A small Python utility to set file creation time on Windows" 900 | files = [ 901 | {file = "win32_setctime-1.1.0-py3-none-any.whl", hash = "sha256:231db239e959c2fe7eb1d7dc129f11172354f98361c4fa2d6d2d7e278baa8aad"}, 902 | {file = "win32_setctime-1.1.0.tar.gz", hash = "sha256:15cf5750465118d6929ae4de4eb46e8edae9a5634350c01ba582df868e932cb2"}, 903 | ] 904 | 905 | [[package]] 906 | name = "zipp" 907 | version = "3.16.2" 908 | requires_python = ">=3.8" 909 | summary = "Backport of pathlib-compatible object wrapper for zip files" 910 | files = [ 911 | {file = "zipp-3.16.2-py3-none-any.whl", hash = "sha256:679e51dd4403591b2d6838a48de3d283f3d188412a9782faadf845f298736ba0"}, 912 | {file = "zipp-3.16.2.tar.gz", hash = "sha256:ebc15946aa78bd63458992fc81ec3b6f7b1e92d51c35e6de1c3804e73b799147"}, 913 | ] 914 | --------------------------------------------------------------------------------