├── video_maker ├── entities │ ├── __init__.py │ ├── match_data.py │ └── data_scrapper.py ├── usecases │ ├── __init__.py │ ├── data.py │ ├── record_video.py │ ├── create_thumbnail.py │ ├── upload_youtube.py │ └── scrap_lol_data.py ├── __init__.py └── main.py ├── docs └── images │ ├── match.png │ ├── thumb.png │ └── channel.jpg ├── credentials └── client_secrets.example.json ├── pyproject.toml ├── LICENSE ├── assets ├── match_data.json └── thumbnail.html ├── README.md ├── README_pt_br.md ├── .gitignore └── poetry.lock /video_maker/entities/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /video_maker/usecases/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /video_maker/__init__.py: -------------------------------------------------------------------------------- 1 | __version__ = '0.1.0' 2 | -------------------------------------------------------------------------------- /docs/images/match.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joaomaranhao/video-maker/HEAD/docs/images/match.png -------------------------------------------------------------------------------- /docs/images/thumb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joaomaranhao/video-maker/HEAD/docs/images/thumb.png -------------------------------------------------------------------------------- /docs/images/channel.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joaomaranhao/video-maker/HEAD/docs/images/channel.jpg -------------------------------------------------------------------------------- /video_maker/usecases/data.py: -------------------------------------------------------------------------------- 1 | import json 2 | from entities.match_data import MatchData 3 | 4 | 5 | def save(data: MatchData) -> None: 6 | with open('./assets/match_data.json', 'w') as data_file: 7 | json.dump(data, data_file) 8 | 9 | 10 | def load() -> MatchData: 11 | with open('./assets/match_data.json', 'r') as data_file: 12 | match_data = json.load(data_file) 13 | return match_data 14 | -------------------------------------------------------------------------------- /credentials/client_secrets.example.json: -------------------------------------------------------------------------------- 1 | { 2 | "web": { 3 | "client_id": "your_id", 4 | "project_id": "your_id", 5 | "auth_uri": "https://accounts.google.com/o/oauth2/auth", 6 | "token_uri": "https://oauth2.googleapis.com/token", 7 | "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs", 8 | "client_secret": "your_secret", 9 | "redirect_uris": [ 10 | "http://localhost:8080" 11 | ] 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /video_maker/entities/match_data.py: -------------------------------------------------------------------------------- 1 | from dataclasses import dataclass 2 | 3 | 4 | @dataclass 5 | class Player: 6 | champion: str 7 | kda: str 8 | name: str 9 | rank: str 10 | 11 | 12 | @dataclass 13 | class Team: 14 | players: list[Player] 15 | result: str 16 | 17 | 18 | @dataclass 19 | class MatchData: 20 | duration: str 21 | loser: str 22 | mvp: Player 23 | patch: str 24 | region: str 25 | team1: Team 26 | team2: Team 27 | player_role: str 28 | player_index: str 29 | -------------------------------------------------------------------------------- /pyproject.toml: -------------------------------------------------------------------------------- 1 | [tool.poetry] 2 | name = "video-maker" 3 | version = "0.1.0" 4 | description = "" 5 | authors = ["João Maranhão "] 6 | 7 | [tool.poetry.dependencies] 8 | python = "^3.9" 9 | selenium = "^4.3.0" 10 | webdriver-manager = "^3.7.1" 11 | google-api-python-client = "^2.52.0" 12 | oauth2client = "^4.1.3" 13 | PyAutoGUI = "^0.9.53" 14 | PyDirectInput = "^1.0.4" 15 | 16 | [tool.poetry.dev-dependencies] 17 | pytest = "^5.2" 18 | autopep8 = "^1.6.0" 19 | 20 | [build-system] 21 | requires = ["poetry-core>=1.0.0"] 22 | build-backend = "poetry.core.masonry.api" 23 | -------------------------------------------------------------------------------- /video_maker/main.py: -------------------------------------------------------------------------------- 1 | from usecases.data import load 2 | from entities.match_data import MatchData 3 | from entities.data_scrapper import DataScrapper 4 | from usecases.scrap_lol_data import ScrapLolData 5 | from usecases.create_thumbnail import CreateThumbnail 6 | from usecases.record_video import RecordVideo 7 | from usecases.upload_youtube import UploadYoutube 8 | 9 | lol_data_scrapper = ScrapLolData() 10 | lol_data_scrapper.get_match_data_and_download_replay() 11 | lol_data: MatchData = load() 12 | thumb_creator = CreateThumbnail(data_scrapper=DataScrapper(), data=lol_data) 13 | thumb_creator.create_thumbnail() 14 | video_recorder = RecordVideo(lol_data) 15 | video_file_name = video_recorder.record() 16 | youtube_uploader = UploadYoutube(lol_data, video_file_name) 17 | youtube_uploader.upload_video() 18 | video_recorder.remove_video_file() 19 | -------------------------------------------------------------------------------- /video_maker/entities/data_scrapper.py: -------------------------------------------------------------------------------- 1 | from selenium import webdriver 2 | from selenium.webdriver.firefox.service import Service as FirefoxService 3 | from webdriver_manager.firefox import GeckoDriverManager 4 | from selenium.webdriver.firefox.options import Options 5 | 6 | 7 | class DataScrapper: 8 | def __init__(self) -> None: 9 | self.__download_path = r'C:\youtube\lol\replays' 10 | # SELENIUM 11 | self.__options = Options() 12 | self.__options.headless = True 13 | self.__options.set_preference( 14 | 'browser.download.dir', self.__download_path) 15 | self.__options.set_preference("browser.download.folderList", 2) 16 | self.__options.add_argument('--log-level=3') 17 | self.driver = webdriver.Firefox(service=FirefoxService( 18 | GeckoDriverManager().install()), options=self.__options) 19 | 20 | def quit(self): 21 | self.driver.quit() 22 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 João Maranhão 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /assets/match_data.json: -------------------------------------------------------------------------------- 1 | {"team1": {"players": [{"name": "zl\uc874\uc77c\uc9f1123", "kda": "0 / 10 / 2", "rank": "GrandMaster", "champion": "Nasus"}, {"name": "fenglingyuxiu", "kda": "5 / 11 / 8", "rank": "Master", "champion": "Viego"}, {"name": "\ubb34\uac10\uc815\uc194\ub7ad\uae30\uacc4", "kda": "4 / 7 / 5", "rank": "GrandMaster", "champion": "Sylas"}, {"name": "Casta1", "kda": "6 / 7 / 3", "rank": "Master", "champion": "Ezreal"}, {"name": "\uadc0\uc694\uba54", "kda": "2 / 8 / 10", "rank": "GrandMaster", "champion": "Karma"}], "result": "Defeat"}, "team2": {"players": [{"name": "\ubb34\ubb34\uacf5\uc8fc\ub2d8", "kda": "10 / 5 / 1", "rank": "Master", "champion": "Kayle"}, {"name": "ggp5", "kda": "9 / 4 / 8", "rank": "GrandMaster", "champion": "Wukong"}, {"name": "\ub9c8\ub798\ub9ac\ud2b8", "kda": "13 / 3 / 5", "rank": "GrandMaster", "champion": "Ahri"}, {"name": "DK Celina", "kda": "8 / 4 / 10", "rank": "Master", "champion": "Kalista"}, {"name": "\ub18d\uc2ec \ube14\ub808\uc2f1", "kda": "3 / 1 / 24", "rank": "GrandMaster", "champion": "Rakan"}], "result": "Victory"}, "duration": "21:49", "patch": "12.12", "mvp": {"name": "\ub9c8\ub798\ub9ac\ud2b8", "kda": "13 / 3 / 5", "rank": "GrandMaster", "champion": "Ahri"}, "loser": "Sylas", "player_role": "Mid", "player_index": "3", "region": "KR"} -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Youtube channel automation 2 | 3 |
pt-BR
4 | 5 | # 6 | 7 | The idea of ​​this project is to automate the creation of videos, thumbnails and uploading this material to Youtube. 8 | 9 | It is a channel of replays of matches of a game called League of Legends. 10 | 11 | The entire process is automated. Once the script is started, it manages, through small steps, to programmatically create content. 12 | 13 | The channel can be viewed at this link: [League of Legends Replays](https://www.youtube.com/channel/UC-C_dsVX2-G2UYA9IoD5i3Q) 14 | 15 | # 16 | 17 | ![League of Legends Replays](./docs/images/channel.jpg) 18 | 19 | # 20 | 21 | ## Prerequisites 22 | 23 | - [Python](https://www.python.org/downloads/) >=3.9 ; 24 | - [Poetry](https://python-poetry.org/docs/) ; 25 | - [Firefox](https://www.mozilla.org/pt-BR/firefox/new/) >=102 ; 26 | - [OBS](https://obsproject.com/pt-br/download) (Open Broadcaster Software) ; 27 | - Google Account ; 28 | 29 | ## Technologies 30 | 31 | - Web scraping with [Selenium](https://selenium-python.readthedocs.io/) ; 32 | - HTML and CSS for thumbnail creation ; 33 | - RPA (Robotic Process Automation) with [PyAutoGUI](https://pyautogui.readthedocs.io/en/latest/) ; 34 | - [Youtube API](https://developers.google.com/youtube/v3/quickstart/python) ; 35 | - OAuth 2 ; 36 | 37 | ## How it works 38 | 39 | The project was created with 5 separate modules, each with its own responsibility. 40 | 41 | The modules are in the folder `videomaker/usecases`: 42 | 43 | - scrap_lol_data (web scrapper) 44 | 45 | Enter the website, select the match, collect all the necessary data and download the replay (game executable) 46 | 47 | ![League of Legends Replays](./docs/images/match.png) 48 | 49 | # 50 | 51 | - data 52 | 53 | Responsible for saving and loading the information received by the web scrapper in a json file 54 | 55 | # 56 | 57 | - create_thumbnail 58 | 59 | This module creates a custom thumbnail with HTML and CSS using the information obtained by the web scrapper 60 | 61 | ![League of Legends Replays](./docs/images/thumb.png) 62 | 63 | # 64 | 65 | - record_video 66 | 67 | Use PyAutoGUI and PyDirectInput to control the game and OBS to record the game 68 | 69 | # 70 | 71 | - upload_youtube 72 | 73 | Responsible for filling information such as title, description and keywords, uploading the video and thumbnail 74 | -------------------------------------------------------------------------------- /README_pt_br.md: -------------------------------------------------------------------------------- 1 | # Automatização de canal de Youtube 2 | 3 |
en-US
4 | 5 | # 6 | 7 | A ideia desse projeto é automatizar a criação de vídeos, thumbnails e upload desse material para o Youtube. 8 | 9 | É um canal de replays de partidas de um jogo chamado League of Legends. 10 | 11 | Todo o processo é automatizado. Uma vez que o script é iniciado, ele consegue através de pequenos passos, criar conteúdo de forma programática. 12 | 13 | O canal pode ser visualizado nesse link: [League of Legends Replays](https://www.youtube.com/channel/UC-C_dsVX2-G2UYA9IoD5i3Q) 14 | 15 | # 16 | 17 | ![League of Legends Replays](./docs/images/channel.jpg) 18 | 19 | # 20 | 21 | ## Pré-Requisitos 22 | 23 | - [Python](https://www.python.org/downloads/) 3.9 ou superior ; 24 | - [Poetry](https://python-poetry.org/docs/) ; 25 | - [Firefox](https://www.mozilla.org/pt-BR/firefox/new/) 102 ou superior ; 26 | - [OBS](https://obsproject.com/pt-br/download) (Open Broadcaster Software) ; 27 | - Conta Google ; 28 | 29 | ## Tecnologias 30 | 31 | - Web scraping com [Selenium](https://selenium-python.readthedocs.io/) ; 32 | - HTML e CSS para a criação da thumbnail ; 33 | - RPA (Robotic Process Automation) com [PyAutoGUI](https://pyautogui.readthedocs.io/en/latest/) ; 34 | - [API do Youtube](https://developers.google.com/youtube/v3/quickstart/python) ; 35 | - OAuth 2 ; 36 | 37 | ## Como funciona 38 | 39 | O projeto foi criado com 5 módulos separados, cada um com sua responsabilidade. 40 | 41 | Os módulos estão na pasta `videomaker/usecases`: 42 | 43 | - scrap_lol_data (web scrapper) 44 | 45 | Entra no site, seleciona a partida, coleta todas as informações necessárias e baixa o replay (executável do jogo) 46 | 47 | ![League of Legends Replays](./docs/images/match.png) 48 | 49 | # 50 | 51 | - data 52 | 53 | Responsável por salvar e carregar as informações recebidas pelo web scrapper em um arquivo json 54 | 55 | # 56 | 57 | - create_thumbnail 58 | 59 | Esse módulo cria uma thumbnail personalizada com HTML e CSS utilizando as informações obtidas pelo web scrapper 60 | 61 | ![League of Legends Replays](./docs/images/thumb.png) 62 | 63 | # 64 | 65 | - record_video 66 | 67 | Utiliza o PyAutoGUI e o PyDirectInput para controlar o jogo e o OBS para gravar a partida 68 | 69 | # 70 | 71 | - upload_youtube 72 | 73 | Responsável por preencher informações como título, descrição e palavras-chave, fazer upload do vídeo e da thumbnail 74 | -------------------------------------------------------------------------------- /assets/thumbnail.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 68 | 69 | 70 |
71 |
72 |
73 |

13 / 3 / 5

74 |
75 |
76 |

Ahri

77 |

vs

78 |

Sylas

79 |
80 |
81 |

KR

82 |
83 |
84 |

Patch 12.12

85 |
86 |
87 |
88 | 89 | 90 | -------------------------------------------------------------------------------- /video_maker/usecases/record_video.py: -------------------------------------------------------------------------------- 1 | import os 2 | from time import sleep 3 | import subprocess 4 | import pyautogui 5 | import pydirectinput 6 | from entities.match_data import MatchData 7 | 8 | 9 | class RecordVideo: 10 | def __init__(self, match_data: MatchData) -> None: 11 | self.__video_file_dir = r'C:\Users\Joao\Videos' 12 | self.__replay_file_dir = r'C:\youtube\lol\replays' 13 | self.__match_data = match_data 14 | 15 | def record(self): 16 | # self.__show_mouse_position() 17 | print('Iniciando gravação da partida...') 18 | self.__run_game() 19 | self.__run_obs() 20 | sleep(50) 21 | self.__select_player() 22 | pydirectinput.keyDown('o') 23 | pydirectinput.keyUp('o') 24 | pydirectinput.keyDown('u') 25 | pydirectinput.keyUp('u') 26 | sleep(5) 27 | self.__start_stop_recording() 28 | sleep(self.__duration_in_seconds()) 29 | self.__start_stop_recording() 30 | sleep(10) 31 | pydirectinput.click(962, 641) 32 | pyautogui.click(962, 641) 33 | sleep(1) 34 | pydirectinput.leftClick(962, 641) 35 | pyautogui.click(962, 641) 36 | sleep(5) 37 | print('Partida gravada') 38 | return self.__select_video_file() 39 | 40 | def __run_game(self): 41 | file = os.listdir(self.__replay_file_dir)[0] 42 | subprocess.call( 43 | ['start', fr'{self.__replay_file_dir}\{file}'], shell=True) 44 | 45 | def __run_obs(self): 46 | pyautogui.hotkey('super', '4') 47 | 48 | def __select_player(self): 49 | if self.__match_data['team1']['result'] == 'Victory': 50 | pydirectinput.keyDown('f1') 51 | pydirectinput.keyUp('f1') 52 | pydirectinput.keyDown(self.__match_data['player_index']) 53 | pydirectinput.keyUp(self.__match_data['player_index']) 54 | pydirectinput.keyDown(self.__match_data['player_index']) 55 | pydirectinput.keyUp(self.__match_data['player_index']) 56 | else: 57 | keys = ['q', 'w', 'e', 'r', 't'] 58 | pydirectinput.keyDown('f2') 59 | pydirectinput.keyUp('f2') 60 | pydirectinput.keyDown( 61 | keys[int(self.__match_data['player_index']) - 1]) 62 | pydirectinput.keyUp( 63 | keys[int(self.__match_data['player_index']) - 1]) 64 | pydirectinput.keyDown( 65 | keys[int(self.__match_data['player_index']) - 1]) 66 | pydirectinput.keyUp( 67 | keys[int(self.__match_data['player_index']) - 1]) 68 | 69 | def __start_stop_recording(self): 70 | pyautogui.keyDown('shiftleft') 71 | pyautogui.keyDown('x') 72 | pyautogui.keyUp('shiftleft') 73 | pyautogui.keyUp('x') 74 | 75 | def __duration_in_seconds(self) -> int: 76 | array = self.__match_data['duration'].split(':') 77 | return (int(array[0]) * 60) + int(array[1]) - 15 78 | 79 | def __show_mouse_position(self): 80 | while True: 81 | print(pyautogui.position()) 82 | sleep(1) 83 | 84 | def __select_video_file(self): 85 | file = os.listdir(self.__video_file_dir) 86 | return file[0] 87 | 88 | def remove_video_file(self): 89 | file = os.listdir(self.__video_file_dir) 90 | os.rename(os.path.join(self.__video_file_dir, file[0]), os.path.join( 91 | self.__video_file_dir, 'shorts', file[0])) 92 | -------------------------------------------------------------------------------- /.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.toml 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 | 162 | # Credentials 163 | client_secrets.json 164 | storage-oauth2.json -------------------------------------------------------------------------------- /video_maker/usecases/create_thumbnail.py: -------------------------------------------------------------------------------- 1 | import os 2 | from time import sleep 3 | from entities.data_scrapper import DataScrapper 4 | from entities.match_data import MatchData 5 | 6 | 7 | class CreateThumbnail: 8 | def __init__(self, data_scrapper: DataScrapper, data: MatchData) -> None: 9 | self.scrapper = data_scrapper 10 | self.lol_data = data 11 | self.__thumb_path = r'C:\youtube\lol\thumb\thumb.png' 12 | 13 | def create_thumbnail(self): 14 | print('Criando thumbnail...') 15 | champion = self.lol_data['mvp']['champion'].replace( 16 | "'", "").capitalize() 17 | champion = self.lol_data['mvp']['champion'].replace( 18 | " ", "") 19 | self.__create_html( 20 | kda=self.lol_data['mvp']['kda'], 21 | imgUrl=f'https://ddragon.leagueoflegends.com/cdn/img/champion/splash/{champion}_0.jpg', 22 | mvp=self.lol_data['mvp']['champion'], 23 | vs=self.lol_data['loser'], 24 | region=self.lol_data['region'], 25 | patch=self.lol_data['patch'] 26 | ) 27 | html_path = os.path.abspath('assets/thumbnail.html') 28 | self.scrapper.driver.get('file://' + html_path) 29 | sleep(2) 30 | self.scrapper.driver.set_window_size(1280, 805) 31 | self.scrapper.driver.save_screenshot(self.__thumb_path) 32 | print('Thumbnail criada!') 33 | self.scrapper.driver.quit() 34 | 35 | def __create_html(self, kda: str, mvp: str, vs: str, region: str, patch: str, imgUrl: str): 36 | HTML = """ 37 | 38 | 39 | 40 | 41 | 42 | 43 | 103 | """ + f""" 104 | 105 |
106 |
107 |
108 |

{kda}

109 |
110 |
111 |

{mvp}

112 |

vs

113 |

{vs}

114 |
115 |
116 |

{region}

117 |
118 |
119 |

Patch {patch}

120 |
121 |
122 |
123 | 124 | 125 | """ 126 | with open("./assets/thumbnail.html", "w") as f: 127 | f.write(HTML) 128 | -------------------------------------------------------------------------------- /video_maker/usecases/upload_youtube.py: -------------------------------------------------------------------------------- 1 | import httplib2 2 | import os 3 | import random 4 | import time 5 | 6 | from googleapiclient.discovery import build 7 | from googleapiclient.errors import HttpError 8 | from googleapiclient.http import MediaFileUpload 9 | from oauth2client.client import flow_from_clientsecrets 10 | from oauth2client.file import Storage 11 | from oauth2client.tools import run_flow 12 | 13 | from video_maker.entities.match_data import MatchData 14 | 15 | 16 | class UploadYoutube: 17 | def __init__(self, match_data: MatchData, video_file_name: str) -> None: 18 | self.__thumb_file = r'C:\youtube\lol\thumb\thumb.png' 19 | self.__file = fr'C:\Users\Joao\Videos\{video_file_name}' 20 | self.__title = ( 21 | f"{match_data['mvp']['champion']} {match_data['player_role']} vs {match_data['loser']} - {match_data['region']} {match_data['mvp']['rank']} Patch {match_data['patch']}") 22 | self.__description = f""" 23 | {match_data['mvp']['champion']} {match_data['player_role']} played by {match_data['mvp']['name']} at #{match_data['region']}{match_data['mvp']['rank']} 24 | 25 | Data provided by https://leagueofgraphs.com 26 | """ 27 | self.__category = "20" 28 | self.__keywords = [f"{match_data['mvp']['champion']}", "challenger", 29 | "leagueoflegends", "replay", "high kda", 30 | f"{match_data['region']}"] 31 | httplib2.RETRIES = 1 32 | self.__MAX_RETRIES = 10 33 | self.__RETRIABLE_EXCEPTIONS = (httplib2.HttpLib2Error) 34 | self.__RETRIABLE_STATUS_CODES = [500, 502, 503, 504] 35 | self.__CLIENT_SECRETS_FILE = "./credentials/client_secrets.json" 36 | self.__YOUTUBE_UPLOAD_SCOPE = "https://www.googleapis.com/auth/youtube.upload" 37 | self.__YOUTUBE_API_SERVICE_NAME = "youtube" 38 | self.__YOUTUBE_API_VERSION = "v3" 39 | self.__VALID_PRIVACY_STATUSES = ("public", "private", "unlisted") 40 | self.__MISSING_CLIENT_SECRETS_MESSAGE = f""" 41 | WARNING: Please configure OAuth 2.0 42 | 43 | To make this sample run you will need to populate the client_secrets.json file 44 | found at: 45 | 46 | {os.path.abspath(os.path.join(os.path.dirname(__file__), 47 | self.__CLIENT_SECRETS_FILE))} 48 | 49 | with information from the API Console 50 | https://console.developers.google.com/ 51 | 52 | For more information about the client_secrets.json file format, please visit: 53 | https://developers.google.com/api-client-library/python/guide/aaa_client_secrets 54 | """ 55 | 56 | def upload_video(self): 57 | try: 58 | self.__initialize_upload() 59 | except HttpError as e: 60 | print(f"An HTTP error {e.resp.status} occurred:\n{e.content}") 61 | 62 | def __upload_thumbnail(self, youtube, video_id): 63 | print('Fazendo upload da thumbnail') 64 | youtube.thumbnails().set( 65 | videoId=video_id, 66 | media_body=self.__thumb_file 67 | ).execute() 68 | 69 | def __build_video_data(self): 70 | return { 71 | "file": self.__file, 72 | "title": self.__title, 73 | "description": self.__description, 74 | "category": self.__category, 75 | "keywords": self.__keywords, 76 | "privacyStatus": self.__VALID_PRIVACY_STATUSES[0] 77 | } 78 | 79 | def __get_authenticated_service(self): 80 | flow = flow_from_clientsecrets(self.__CLIENT_SECRETS_FILE, 81 | scope=self.__YOUTUBE_UPLOAD_SCOPE, 82 | message=self.__MISSING_CLIENT_SECRETS_MESSAGE) 83 | 84 | storage = Storage("./credentials/storage-oauth2.json") 85 | credentials = storage.get() 86 | 87 | if credentials is None or credentials.invalid: 88 | credentials = run_flow(flow, storage) 89 | 90 | return build(self.__YOUTUBE_API_SERVICE_NAME, self.__YOUTUBE_API_VERSION, 91 | http=credentials.authorize(httplib2.Http())) 92 | 93 | def __initialize_upload(self): 94 | print('Fazendo upload do vídeo') 95 | youtube = self.__get_authenticated_service() 96 | options = self.__build_video_data() 97 | tags = None 98 | if options['keywords']: 99 | tags = options['keywords'] 100 | 101 | body = dict( 102 | snippet=dict( 103 | title=options['title'], 104 | description=options['description'], 105 | tags=tags, 106 | categoryId=options['category'] 107 | ), 108 | status=dict( 109 | privacyStatus=options['privacyStatus'] 110 | ) 111 | ) 112 | 113 | # Call the API's videos.insert method to create and upload the video. 114 | insert_request = youtube.videos().insert( 115 | part=",".join(body.keys()), 116 | body=body, 117 | media_body=MediaFileUpload( 118 | options['file'], chunksize=-1, resumable=True) 119 | ) 120 | 121 | video_id = self.__resumable_upload(insert_request) 122 | self.__upload_thumbnail(youtube, video_id) 123 | 124 | def __resumable_upload(self, insert_request): 125 | response = None 126 | error = None 127 | retry = 0 128 | while response is None: 129 | try: 130 | print("Uploading file...") 131 | status, response = insert_request.next_chunk() 132 | if response is not None: 133 | if 'id' in response: 134 | print( 135 | f"Video id {response['id']} was successfully uploaded.") 136 | return response['id'] 137 | else: 138 | exit( 139 | f"The upload failed with an unexpected response: {response}") 140 | except HttpError as e: 141 | if e.resp.status in self.__RETRIABLE_STATUS_CODES: 142 | error = f"A retriable HTTP error {e.resp.status} occurred:\n{e.content}" 143 | else: 144 | raise 145 | except self.__RETRIABLE_EXCEPTIONS as e: 146 | error = f"A retriable error occurred: {e}" 147 | 148 | if error is not None: 149 | print(error) 150 | retry += 1 151 | if retry > self.__MAX_RETRIES: 152 | exit("No longer attempting to retry.") 153 | 154 | max_sleep = 2 ** retry 155 | sleep_seconds = random.random() * max_sleep 156 | print(f"Sleeping {sleep_seconds} seconds and then retrying...") 157 | time.sleep(sleep_seconds) 158 | -------------------------------------------------------------------------------- /video_maker/usecases/scrap_lol_data.py: -------------------------------------------------------------------------------- 1 | import os 2 | from time import sleep 3 | from selenium.webdriver.common.by import By 4 | from entities.data_scrapper import DataScrapper 5 | from entities.match_data import MatchData, Player 6 | from usecases.data import save 7 | 8 | 9 | class ScrapLolData(DataScrapper): 10 | def __init__(self) -> None: 11 | super().__init__() 12 | # URL 13 | self.__replay_file_dir = r'C:\youtube\lol\replays' 14 | self.__url = 'https://www.leagueofgraphs.com/replays/with-high-kda/grandmaster/sr-ranked' 15 | self.__champions_xpath_selector = '//*[contains(concat( " ", @class, " " ), concat( " ", "relative", " " ))]//img' 16 | self.__match_table_selector = '//*[contains(concat( " ", @class, " " ), concat( " ", "matchTable", " " ))]' 17 | self.__region_xpath = '//*[(@id = "mainContent")]//a' 18 | self.__watch_xpath = '//*[contains(concat( " ", @class, " " ), concat( " ", "replay_watch_button", " " ))]' 19 | self.__download_xpath = '//*[contains(concat( " ", @class, " " ), concat( " ", "replayDownloadButton", " " ))]' 20 | self.match_data: MatchData = { 21 | "team1": { 22 | "players": [] 23 | }, 24 | "team2": { 25 | "players": [] 26 | } 27 | } 28 | 29 | def get_match_data_and_download_replay(self) -> None: 30 | print('Acessando site e salvando informações...') 31 | self.driver.get(self.__url) 32 | table = self.driver.find_element( 33 | by=By.XPATH, value=self.__match_table_selector) 34 | text_list = table.text.split('\n') 35 | self.match_data['team1']['result'] = text_list[0].split(' ')[0] 36 | self.match_data['team2']['result'] = text_list[0].split(' ')[-1] 37 | duration = text_list[0].split(' ')[3][1:-1] 38 | self.match_data['duration'] = duration 39 | patch = text_list[-1].split(' ')[1][1:-1] 40 | self.match_data['patch'] = patch 41 | elements = self.driver.find_elements( 42 | by=By.XPATH, value=self.__champions_xpath_selector) 43 | elements[0].get_dom_attribute('title') 44 | champions = self.__get_champions_names(elements=elements) 45 | self.match_data['team1']['players'] = self.__create_team_one( 46 | text_list=text_list, champions=champions) 47 | self.match_data['team2']['players'] = self.__create_team_two( 48 | text_list=text_list, champions=champions) 49 | mvp_data = self.__get_mvp_data(self.match_data) 50 | self.match_data['mvp'] = self.match_data[mvp_data['team'] 51 | ]['players'][mvp_data['player_index']] 52 | self.match_data['loser'] = self.match_data[mvp_data['loser_team'] 53 | ]['players'][mvp_data['player_index']]['champion'] 54 | self.match_data['player_role'] = mvp_data['player_role'] 55 | self.match_data['player_index'] = str( 56 | int(mvp_data['player_index']) + 1) 57 | region_link = self.driver.find_element( 58 | by=By.XPATH, value=self.__region_xpath) 59 | link_array = region_link.get_property('href').split('/') 60 | self.match_data['region'] = link_array[4].upper() 61 | # Save Data 62 | save(self.match_data) 63 | print('Informações salvas') 64 | print('Iniciando download da partida') 65 | self.__remove_match() 66 | self.__download_match() 67 | self.quit() 68 | 69 | def __get_champions_names(self, elements: list) -> list[str]: 70 | champions = [] 71 | for i in range(0, 38): 72 | if elements[i].get_dom_attribute('title') is not None: 73 | champions.append(elements[i].get_dom_attribute('title')) 74 | return champions 75 | 76 | def __create_player(self, name: str, kda: str, rank: str, champion: str) -> Player: 77 | return { 78 | "name": name, 79 | "kda": kda, 80 | "rank": rank, 81 | "champion": champion 82 | } 83 | 84 | def __create_team_one(self, text_list: list, champions: list) -> list[Player]: 85 | team_one = [] 86 | team_one.append(self.__create_player( 87 | name=text_list[1], kda=text_list[3], rank=text_list[2], champion=champions[0])) 88 | team_one.append(self.__create_player( 89 | name=text_list[9], kda=text_list[11], rank=text_list[10], champion=champions[2])) 90 | team_one.append(self.__create_player( 91 | name=text_list[17], kda=text_list[19], rank=text_list[18], champion=champions[4])) 92 | team_one.append(self.__create_player( 93 | name=text_list[25], kda=text_list[27], rank=text_list[26], champion=champions[6])) 94 | team_one.append(self.__create_player( 95 | name=text_list[33], kda=text_list[35], rank=text_list[34], champion=champions[8])) 96 | return team_one 97 | 98 | def __create_team_two(self, text_list: list, champions: list) -> list[Player]: 99 | team_two = [] 100 | team_two.append(self.__create_player( 101 | name=text_list[7], kda=text_list[5], rank=text_list[8], champion=champions[1])) 102 | team_two.append(self.__create_player( 103 | name=text_list[15], kda=text_list[13], rank=text_list[16], champion=champions[3])) 104 | team_two.append(self.__create_player( 105 | name=text_list[23], kda=text_list[21], rank=text_list[24], champion=champions[5])) 106 | team_two.append(self.__create_player( 107 | name=text_list[31], kda=text_list[29], rank=text_list[32], champion=champions[7])) 108 | team_two.append(self.__create_player( 109 | name=text_list[39], kda=text_list[37], rank=text_list[40], champion=champions[9])) 110 | return team_two 111 | 112 | def __get_mvp_data(self, match_data): 113 | team = '' 114 | kdas = [] 115 | if match_data['team1']['result'] == 'Victory': 116 | for player in match_data['team1']['players']: 117 | team = 'team1' 118 | loser_team = 'team2' 119 | kdas.append(int(player['kda'].split(' ')[0])) 120 | else: 121 | for player in match_data['team2']['players']: 122 | team = 'team2' 123 | loser_team = 'team1' 124 | kdas.append(int(player['kda'].split(' ')[0])) 125 | player_index = kdas.index(max(kdas)) 126 | roles = ['Top', 'Jungle', 'Mid', 'ADC', 'Support'] 127 | return { 128 | "team": team, 129 | "player_index": player_index, 130 | "loser_team": loser_team, 131 | "player_role": roles[player_index] 132 | } 133 | 134 | def __download_match(self): 135 | watch_button = self.driver.find_element( 136 | by=By.XPATH, value=self.__watch_xpath) 137 | download_button = self.driver.find_element( 138 | by=By.XPATH, value=self.__download_xpath) 139 | self.driver.execute_script("arguments[0].click();", watch_button) 140 | sleep(1) 141 | self.driver.execute_script("arguments[0].click();", download_button) 142 | sleep(2) 143 | 144 | def __remove_match(self): 145 | file = os.listdir(self.__replay_file_dir) 146 | if file: 147 | os.remove(os.path.join(self.__replay_file_dir, file[0])) 148 | -------------------------------------------------------------------------------- /poetry.lock: -------------------------------------------------------------------------------- 1 | [[package]] 2 | name = "async-generator" 3 | version = "1.10" 4 | description = "Async generators and context managers for Python 3.5+" 5 | category = "main" 6 | optional = false 7 | python-versions = ">=3.5" 8 | 9 | [[package]] 10 | name = "atomicwrites" 11 | version = "1.4.0" 12 | description = "Atomic file writes." 13 | category = "dev" 14 | optional = false 15 | python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" 16 | 17 | [[package]] 18 | name = "attrs" 19 | version = "21.4.0" 20 | description = "Classes Without Boilerplate" 21 | category = "main" 22 | optional = false 23 | python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" 24 | 25 | [package.extras] 26 | dev = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins", "zope.interface", "furo", "sphinx", "sphinx-notfound-page", "pre-commit", "cloudpickle"] 27 | docs = ["furo", "sphinx", "zope.interface", "sphinx-notfound-page"] 28 | tests = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins", "zope.interface", "cloudpickle"] 29 | tests_no_zope = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins", "cloudpickle"] 30 | 31 | [[package]] 32 | name = "autopep8" 33 | version = "1.6.0" 34 | description = "A tool that automatically formats Python code to conform to the PEP 8 style guide" 35 | category = "dev" 36 | optional = false 37 | python-versions = "*" 38 | 39 | [package.dependencies] 40 | pycodestyle = ">=2.8.0" 41 | toml = "*" 42 | 43 | [[package]] 44 | name = "cachetools" 45 | version = "5.2.0" 46 | description = "Extensible memoizing collections and decorators" 47 | category = "main" 48 | optional = false 49 | python-versions = "~=3.7" 50 | 51 | [[package]] 52 | name = "certifi" 53 | version = "2022.6.15" 54 | description = "Python package for providing Mozilla's CA Bundle." 55 | category = "main" 56 | optional = false 57 | python-versions = ">=3.6" 58 | 59 | [[package]] 60 | name = "cffi" 61 | version = "1.15.1" 62 | description = "Foreign Function Interface for Python calling C code." 63 | category = "main" 64 | optional = false 65 | python-versions = "*" 66 | 67 | [package.dependencies] 68 | pycparser = "*" 69 | 70 | [[package]] 71 | name = "charset-normalizer" 72 | version = "2.1.0" 73 | description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." 74 | category = "main" 75 | optional = false 76 | python-versions = ">=3.6.0" 77 | 78 | [package.extras] 79 | unicode_backport = ["unicodedata2"] 80 | 81 | [[package]] 82 | name = "colorama" 83 | version = "0.4.5" 84 | description = "Cross-platform colored terminal text." 85 | category = "dev" 86 | optional = false 87 | python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" 88 | 89 | [[package]] 90 | name = "cryptography" 91 | version = "37.0.3" 92 | description = "cryptography is a package which provides cryptographic recipes and primitives to Python developers." 93 | category = "main" 94 | optional = false 95 | python-versions = ">=3.6" 96 | 97 | [package.dependencies] 98 | cffi = ">=1.12" 99 | 100 | [package.extras] 101 | docs = ["sphinx (>=1.6.5,!=1.8.0,!=3.1.0,!=3.1.1)", "sphinx-rtd-theme"] 102 | docstest = ["pyenchant (>=1.6.11)", "twine (>=1.12.0)", "sphinxcontrib-spelling (>=4.0.1)"] 103 | pep8test = ["black", "flake8", "flake8-import-order", "pep8-naming"] 104 | sdist = ["setuptools_rust (>=0.11.4)"] 105 | ssh = ["bcrypt (>=3.1.5)"] 106 | test = ["pytest (>=6.2.0)", "pytest-benchmark", "pytest-cov", "pytest-subtests", "pytest-xdist", "pretend", "iso8601", "pytz", "hypothesis (>=1.11.4,!=3.79.2)"] 107 | 108 | [[package]] 109 | name = "google-api-core" 110 | version = "2.8.2" 111 | description = "Google API client core library" 112 | category = "main" 113 | optional = false 114 | python-versions = ">=3.6" 115 | 116 | [package.dependencies] 117 | google-auth = ">=1.25.0,<3.0dev" 118 | googleapis-common-protos = ">=1.56.2,<2.0dev" 119 | protobuf = ">=3.15.0,<5.0.0dev" 120 | requests = ">=2.18.0,<3.0.0dev" 121 | 122 | [package.extras] 123 | grpc = ["grpcio (>=1.33.2,<2.0dev)", "grpcio-status (>=1.33.2,<2.0dev)"] 124 | 125 | [[package]] 126 | name = "google-api-python-client" 127 | version = "2.52.0" 128 | description = "Google API Client Library for Python" 129 | category = "main" 130 | optional = false 131 | python-versions = ">=3.6" 132 | 133 | [package.dependencies] 134 | google-api-core = ">=1.31.5,<2.0.0 || >2.3.0,<3.0.0dev" 135 | google-auth = ">=1.19.0,<3.0.0dev" 136 | google-auth-httplib2 = ">=0.1.0" 137 | httplib2 = ">=0.15.0,<1dev" 138 | uritemplate = ">=3.0.1,<5" 139 | 140 | [[package]] 141 | name = "google-auth" 142 | version = "2.9.0" 143 | description = "Google Authentication Library" 144 | category = "main" 145 | optional = false 146 | python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*" 147 | 148 | [package.dependencies] 149 | cachetools = ">=2.0.0,<6.0" 150 | pyasn1-modules = ">=0.2.1" 151 | rsa = {version = ">=3.1.4,<5", markers = "python_version >= \"3.6\""} 152 | six = ">=1.9.0" 153 | 154 | [package.extras] 155 | aiohttp = ["requests (>=2.20.0,<3.0.0dev)", "aiohttp (>=3.6.2,<4.0.0dev)"] 156 | enterprise_cert = ["cryptography (==36.0.2)", "pyopenssl (==22.0.0)"] 157 | pyopenssl = ["pyopenssl (>=20.0.0)"] 158 | reauth = ["pyu2f (>=0.1.5)"] 159 | 160 | [[package]] 161 | name = "google-auth-httplib2" 162 | version = "0.1.0" 163 | description = "Google Authentication Library: httplib2 transport" 164 | category = "main" 165 | optional = false 166 | python-versions = "*" 167 | 168 | [package.dependencies] 169 | google-auth = "*" 170 | httplib2 = ">=0.15.0" 171 | six = "*" 172 | 173 | [[package]] 174 | name = "googleapis-common-protos" 175 | version = "1.56.3" 176 | description = "Common protobufs used in Google APIs" 177 | category = "main" 178 | optional = false 179 | python-versions = ">=3.6" 180 | 181 | [package.dependencies] 182 | protobuf = ">=3.15.0,<5.0.0dev" 183 | 184 | [package.extras] 185 | grpc = ["grpcio (>=1.0.0,<2.0.0dev)"] 186 | 187 | [[package]] 188 | name = "h11" 189 | version = "0.13.0" 190 | description = "A pure-Python, bring-your-own-I/O implementation of HTTP/1.1" 191 | category = "main" 192 | optional = false 193 | python-versions = ">=3.6" 194 | 195 | [[package]] 196 | name = "httplib2" 197 | version = "0.20.4" 198 | description = "A comprehensive HTTP client library." 199 | category = "main" 200 | optional = false 201 | python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" 202 | 203 | [package.dependencies] 204 | pyparsing = {version = ">=2.4.2,<3.0.0 || >3.0.0,<3.0.1 || >3.0.1,<3.0.2 || >3.0.2,<3.0.3 || >3.0.3,<4", markers = "python_version > \"3.0\""} 205 | 206 | [[package]] 207 | name = "idna" 208 | version = "3.3" 209 | description = "Internationalized Domain Names in Applications (IDNA)" 210 | category = "main" 211 | optional = false 212 | python-versions = ">=3.5" 213 | 214 | [[package]] 215 | name = "more-itertools" 216 | version = "8.13.0" 217 | description = "More routines for operating on iterables, beyond itertools" 218 | category = "dev" 219 | optional = false 220 | python-versions = ">=3.5" 221 | 222 | [[package]] 223 | name = "mouseinfo" 224 | version = "0.1.3" 225 | description = "An application to display XY position and RGB color information for the pixel currently under the mouse. Works on Python 2 and 3." 226 | category = "main" 227 | optional = false 228 | python-versions = "*" 229 | 230 | [package.dependencies] 231 | pyperclip = "*" 232 | python3-Xlib = {version = "*", markers = "platform_system == \"Linux\" and python_version >= \"3.0\""} 233 | rubicon-objc = {version = "*", markers = "platform_system == \"Darwin\""} 234 | 235 | [[package]] 236 | name = "oauth2client" 237 | version = "4.1.3" 238 | description = "OAuth 2.0 client library" 239 | category = "main" 240 | optional = false 241 | python-versions = "*" 242 | 243 | [package.dependencies] 244 | httplib2 = ">=0.9.1" 245 | pyasn1 = ">=0.1.7" 246 | pyasn1-modules = ">=0.0.5" 247 | rsa = ">=3.1.4" 248 | six = ">=1.6.1" 249 | 250 | [[package]] 251 | name = "outcome" 252 | version = "1.2.0" 253 | description = "Capture the outcome of Python function calls." 254 | category = "main" 255 | optional = false 256 | python-versions = ">=3.7" 257 | 258 | [package.dependencies] 259 | attrs = ">=19.2.0" 260 | 261 | [[package]] 262 | name = "packaging" 263 | version = "21.3" 264 | description = "Core utilities for Python packages" 265 | category = "dev" 266 | optional = false 267 | python-versions = ">=3.6" 268 | 269 | [package.dependencies] 270 | pyparsing = ">=2.0.2,<3.0.5 || >3.0.5" 271 | 272 | [[package]] 273 | name = "pluggy" 274 | version = "0.13.1" 275 | description = "plugin and hook calling mechanisms for python" 276 | category = "dev" 277 | optional = false 278 | python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" 279 | 280 | [package.extras] 281 | dev = ["pre-commit", "tox"] 282 | 283 | [[package]] 284 | name = "protobuf" 285 | version = "4.21.2" 286 | description = "" 287 | category = "main" 288 | optional = false 289 | python-versions = ">=3.7" 290 | 291 | [[package]] 292 | name = "py" 293 | version = "1.11.0" 294 | description = "library with cross-python path, ini-parsing, io, code, log facilities" 295 | category = "dev" 296 | optional = false 297 | python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" 298 | 299 | [[package]] 300 | name = "pyasn1" 301 | version = "0.4.8" 302 | description = "ASN.1 types and codecs" 303 | category = "main" 304 | optional = false 305 | python-versions = "*" 306 | 307 | [[package]] 308 | name = "pyasn1-modules" 309 | version = "0.2.8" 310 | description = "A collection of ASN.1-based protocols modules." 311 | category = "main" 312 | optional = false 313 | python-versions = "*" 314 | 315 | [package.dependencies] 316 | pyasn1 = ">=0.4.6,<0.5.0" 317 | 318 | [[package]] 319 | name = "pyautogui" 320 | version = "0.9.53" 321 | description = "PyAutoGUI lets Python control the mouse and keyboard, and other GUI automation tasks. For Windows, macOS, and Linux, on Python 3 and 2." 322 | category = "main" 323 | optional = false 324 | python-versions = "*" 325 | 326 | [package.dependencies] 327 | mouseinfo = "*" 328 | pygetwindow = ">=0.0.5" 329 | pymsgbox = "*" 330 | pyobjc = {version = "*", markers = "platform_system == \"Darwin\""} 331 | pyobjc-core = {version = "*", markers = "platform_system == \"Darwin\""} 332 | pyscreeze = ">=0.1.21" 333 | python3-Xlib = {version = "*", markers = "platform_system == \"Linux\" and python_version >= \"3.0\""} 334 | PyTweening = ">=1.0.1" 335 | 336 | [[package]] 337 | name = "pycodestyle" 338 | version = "2.8.0" 339 | description = "Python style guide checker" 340 | category = "dev" 341 | optional = false 342 | python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" 343 | 344 | [[package]] 345 | name = "pycparser" 346 | version = "2.21" 347 | description = "C parser in Python" 348 | category = "main" 349 | optional = false 350 | python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" 351 | 352 | [[package]] 353 | name = "pydirectinput" 354 | version = "1.0.4" 355 | description = "Python mouse and keyboard input automation for Windows using Direct Input." 356 | category = "main" 357 | optional = false 358 | python-versions = ">=3.4" 359 | 360 | [[package]] 361 | name = "pygetwindow" 362 | version = "0.0.9" 363 | description = "A simple, cross-platform module for obtaining GUI information on application's windows." 364 | category = "main" 365 | optional = false 366 | python-versions = "*" 367 | 368 | [package.dependencies] 369 | pyrect = "*" 370 | 371 | [[package]] 372 | name = "pymsgbox" 373 | version = "1.0.9" 374 | description = "A simple, cross-platform, pure Python module for JavaScript-like message boxes." 375 | category = "main" 376 | optional = false 377 | python-versions = "*" 378 | 379 | [[package]] 380 | name = "pyobjc" 381 | version = "8.5" 382 | description = "Python<->ObjC Interoperability Module" 383 | category = "main" 384 | optional = false 385 | python-versions = ">=3.6" 386 | 387 | [package.dependencies] 388 | pyobjc-core = "8.5" 389 | pyobjc-framework-Accessibility = {version = "8.5", markers = "platform_release >= \"20.0\""} 390 | pyobjc-framework-Accounts = {version = "8.5", markers = "platform_release >= \"12.0\""} 391 | pyobjc-framework-AddressBook = "8.5" 392 | pyobjc-framework-AdServices = {version = "8.5", markers = "platform_release >= \"20.0\""} 393 | pyobjc-framework-AdSupport = {version = "8.5", markers = "platform_release >= \"18.0\""} 394 | pyobjc-framework-AppleScriptKit = "8.5" 395 | pyobjc-framework-AppleScriptObjC = {version = "8.5", markers = "platform_release >= \"10.0\""} 396 | pyobjc-framework-ApplicationServices = "8.5" 397 | pyobjc-framework-AppTrackingTransparency = {version = "8.5", markers = "platform_release >= \"20.0\""} 398 | pyobjc-framework-AudioVideoBridging = {version = "8.5", markers = "platform_release >= \"12.0\""} 399 | pyobjc-framework-AuthenticationServices = {version = "8.5", markers = "platform_release >= \"19.0\""} 400 | pyobjc-framework-AutomaticAssessmentConfiguration = {version = "8.5", markers = "platform_release >= \"19.0\""} 401 | pyobjc-framework-Automator = "8.5" 402 | pyobjc-framework-AVFoundation = {version = "8.5", markers = "platform_release >= \"11.0\""} 403 | pyobjc-framework-AVKit = {version = "8.5", markers = "platform_release >= \"13.0\""} 404 | pyobjc-framework-BusinessChat = {version = "8.5", markers = "platform_release >= \"18.0\""} 405 | pyobjc-framework-CalendarStore = {version = "8.5", markers = "platform_release >= \"9.0\""} 406 | pyobjc-framework-CallKit = {version = "8.5", markers = "platform_release >= \"20.0\""} 407 | pyobjc-framework-CFNetwork = "8.5" 408 | pyobjc-framework-ClassKit = {version = "8.5", markers = "platform_release >= \"20.0\""} 409 | pyobjc-framework-CloudKit = {version = "8.5", markers = "platform_release >= \"14.0\""} 410 | pyobjc-framework-Cocoa = "8.5" 411 | pyobjc-framework-Collaboration = {version = "8.5", markers = "platform_release >= \"9.0\""} 412 | pyobjc-framework-ColorSync = {version = "8.5", markers = "platform_release >= \"17.0\""} 413 | pyobjc-framework-Contacts = {version = "8.5", markers = "platform_release >= \"15.0\""} 414 | pyobjc-framework-ContactsUI = {version = "8.5", markers = "platform_release >= \"15.0\""} 415 | pyobjc-framework-CoreAudio = "8.5" 416 | pyobjc-framework-CoreAudioKit = "8.5" 417 | pyobjc-framework-CoreBluetooth = {version = "8.5", markers = "platform_release >= \"14.0\""} 418 | pyobjc-framework-CoreData = "8.5" 419 | pyobjc-framework-CoreHaptics = {version = "8.5", markers = "platform_release >= \"19.0\""} 420 | pyobjc-framework-CoreLocation = {version = "8.5", markers = "platform_release >= \"10.0\""} 421 | pyobjc-framework-CoreMedia = {version = "8.5", markers = "platform_release >= \"11.0\""} 422 | pyobjc-framework-CoreMediaIO = {version = "8.5", markers = "platform_release >= \"11.0\""} 423 | pyobjc-framework-CoreMIDI = "8.5" 424 | pyobjc-framework-CoreML = {version = "8.5", markers = "platform_release >= \"17.0\""} 425 | pyobjc-framework-CoreMotion = {version = "8.5", markers = "platform_release >= \"19.0\""} 426 | pyobjc-framework-CoreServices = "8.5" 427 | pyobjc-framework-CoreSpotlight = {version = "8.5", markers = "platform_release >= \"17.0\""} 428 | pyobjc-framework-CoreText = "8.5" 429 | pyobjc-framework-CoreWLAN = {version = "8.5", markers = "platform_release >= \"10.0\""} 430 | pyobjc-framework-CryptoTokenKit = {version = "8.5", markers = "platform_release >= \"14.0\""} 431 | pyobjc-framework-DataDetection = {version = "8.5", markers = "platform_release >= \"21.0\""} 432 | pyobjc-framework-DeviceCheck = {version = "8.5", markers = "platform_release >= \"19.0\""} 433 | pyobjc-framework-DictionaryServices = {version = "8.5", markers = "platform_release >= \"9.0\""} 434 | pyobjc-framework-DiscRecording = "8.5" 435 | pyobjc-framework-DiscRecordingUI = "8.5" 436 | pyobjc-framework-DiskArbitration = "8.5" 437 | pyobjc-framework-DVDPlayback = "8.5" 438 | pyobjc-framework-EventKit = {version = "8.5", markers = "platform_release >= \"12.0\""} 439 | pyobjc-framework-ExceptionHandling = "8.5" 440 | pyobjc-framework-ExecutionPolicy = {version = "8.5", markers = "platform_release >= \"19.0\""} 441 | pyobjc-framework-ExternalAccessory = {version = "8.5", markers = "platform_release >= \"17.0\""} 442 | pyobjc-framework-FileProvider = {version = "8.5", markers = "platform_release >= \"19.0\""} 443 | pyobjc-framework-FileProviderUI = {version = "8.5", markers = "platform_release >= \"19.0\""} 444 | pyobjc-framework-FinderSync = {version = "8.5", markers = "platform_release >= \"14.0\""} 445 | pyobjc-framework-FSEvents = {version = "8.5", markers = "platform_release >= \"9.0\""} 446 | pyobjc-framework-GameCenter = {version = "8.5", markers = "platform_release >= \"12.0\""} 447 | pyobjc-framework-GameController = {version = "8.5", markers = "platform_release >= \"13.0\""} 448 | pyobjc-framework-GameKit = {version = "8.5", markers = "platform_release >= \"12.0\""} 449 | pyobjc-framework-GameplayKit = {version = "8.5", markers = "platform_release >= \"15.0\""} 450 | pyobjc-framework-ImageCaptureCore = {version = "8.5", markers = "platform_release >= \"10.0\""} 451 | pyobjc-framework-IMServicePlugIn = {version = "8.5", markers = "platform_release >= \"11.0\""} 452 | pyobjc-framework-InputMethodKit = {version = "8.5", markers = "platform_release >= \"9.0\""} 453 | pyobjc-framework-InstallerPlugins = "8.5" 454 | pyobjc-framework-InstantMessage = {version = "8.5", markers = "platform_release >= \"9.0\""} 455 | pyobjc-framework-Intents = {version = "8.5", markers = "platform_release >= \"16.0\""} 456 | pyobjc-framework-IntentsUI = {version = "8.5", markers = "platform_release >= \"21.0\""} 457 | pyobjc-framework-IOSurface = {version = "8.5", markers = "platform_release >= \"10.0\""} 458 | pyobjc-framework-iTunesLibrary = {version = "8.5", markers = "platform_release >= \"10.0\""} 459 | pyobjc-framework-KernelManagement = {version = "8.5", markers = "platform_release >= \"20.0\""} 460 | pyobjc-framework-LatentSemanticMapping = "8.5" 461 | pyobjc-framework-LaunchServices = "8.5" 462 | pyobjc-framework-libdispatch = {version = "8.5", markers = "platform_release >= \"12.0\""} 463 | pyobjc-framework-LinkPresentation = {version = "8.5", markers = "platform_release >= \"19.0\""} 464 | pyobjc-framework-LocalAuthentication = {version = "8.5", markers = "platform_release >= \"14.0\""} 465 | pyobjc-framework-LocalAuthenticationEmbeddedUI = {version = "8.5", markers = "platform_release >= \"21.0\""} 466 | pyobjc-framework-MailKit = {version = "8.5", markers = "platform_release >= \"21.0\""} 467 | pyobjc-framework-MapKit = {version = "8.5", markers = "platform_release >= \"13.0\""} 468 | pyobjc-framework-MediaAccessibility = {version = "8.5", markers = "platform_release >= \"13.0\""} 469 | pyobjc-framework-MediaLibrary = {version = "8.5", markers = "platform_release >= \"13.0\""} 470 | pyobjc-framework-MediaPlayer = {version = "8.5", markers = "platform_release >= \"16.0\""} 471 | pyobjc-framework-MediaToolbox = {version = "8.5", markers = "platform_release >= \"13.0\""} 472 | pyobjc-framework-Message = {version = "8.5", markers = "platform_release < \"13.0\""} 473 | pyobjc-framework-Metal = {version = "8.5", markers = "platform_release >= \"15.0\""} 474 | pyobjc-framework-MetalKit = {version = "8.5", markers = "platform_release >= \"15.0\""} 475 | pyobjc-framework-MetalPerformanceShaders = {version = "8.5", markers = "platform_release >= \"17.0\""} 476 | pyobjc-framework-MetalPerformanceShadersGraph = {version = "8.5", markers = "platform_release >= \"20.0\""} 477 | pyobjc-framework-MetricKit = {version = "8.5", markers = "platform_release >= \"21.0\""} 478 | pyobjc-framework-MLCompute = {version = "8.5", markers = "platform_release >= \"20.0\""} 479 | pyobjc-framework-ModelIO = {version = "8.5", markers = "platform_release >= \"15.0\""} 480 | pyobjc-framework-MultipeerConnectivity = {version = "8.5", markers = "platform_release >= \"14.0\""} 481 | pyobjc-framework-NaturalLanguage = {version = "8.5", markers = "platform_release >= \"18.0\""} 482 | pyobjc-framework-NetFS = {version = "8.5", markers = "platform_release >= \"10.0\""} 483 | pyobjc-framework-Network = {version = "8.5", markers = "platform_release >= \"18.0\""} 484 | pyobjc-framework-NetworkExtension = {version = "8.5", markers = "platform_release >= \"15.0\""} 485 | pyobjc-framework-NotificationCenter = {version = "8.5", markers = "platform_release >= \"14.0\""} 486 | pyobjc-framework-OpenDirectory = {version = "8.5", markers = "platform_release >= \"10.0\""} 487 | pyobjc-framework-OSAKit = "8.5" 488 | pyobjc-framework-OSLog = {version = "8.5", markers = "platform_release >= \"19.0\""} 489 | pyobjc-framework-PassKit = {version = "8.5", markers = "platform_release >= \"20.0\""} 490 | pyobjc-framework-PencilKit = {version = "8.5", markers = "platform_release >= \"19.0\""} 491 | pyobjc-framework-Photos = {version = "8.5", markers = "platform_release >= \"15.0\""} 492 | pyobjc-framework-PhotosUI = {version = "8.5", markers = "platform_release >= \"15.0\""} 493 | pyobjc-framework-PreferencePanes = "8.5" 494 | pyobjc-framework-PubSub = {version = "8.5", markers = "platform_release >= \"9.0\" and platform_release < \"18.0\""} 495 | pyobjc-framework-PushKit = {version = "8.5", markers = "platform_release >= \"19.0\""} 496 | pyobjc-framework-Quartz = "8.5" 497 | pyobjc-framework-QuickLookThumbnailing = {version = "8.5", markers = "platform_release >= \"19.0\""} 498 | pyobjc-framework-ReplayKit = {version = "8.5", markers = "platform_release >= \"20.0\""} 499 | pyobjc-framework-SafariServices = {version = "8.5", markers = "platform_release >= \"15.0\""} 500 | pyobjc-framework-SceneKit = {version = "8.5", markers = "platform_release >= \"11.0\""} 501 | pyobjc-framework-ScreenCaptureKit = {version = "8.5", markers = "platform_release >= \"21.4\""} 502 | pyobjc-framework-ScreenSaver = "8.5" 503 | pyobjc-framework-ScreenTime = {version = "8.5", markers = "platform_release >= \"20.0\""} 504 | pyobjc-framework-ScriptingBridge = {version = "8.5", markers = "platform_release >= \"9.0\""} 505 | pyobjc-framework-SearchKit = "8.5" 506 | pyobjc-framework-Security = "8.5" 507 | pyobjc-framework-SecurityFoundation = "8.5" 508 | pyobjc-framework-SecurityInterface = "8.5" 509 | pyobjc-framework-ServerNotification = {version = "8.5", markers = "platform_release >= \"10.0\" and platform_release < \"13.0\""} 510 | pyobjc-framework-ServiceManagement = {version = "8.5", markers = "platform_release >= \"10.0\""} 511 | pyobjc-framework-ShazamKit = {version = "8.5", markers = "platform_release >= \"21.0\""} 512 | pyobjc-framework-Social = {version = "8.5", markers = "platform_release >= \"12.0\""} 513 | pyobjc-framework-SoundAnalysis = {version = "8.5", markers = "platform_release >= \"19.0\""} 514 | pyobjc-framework-Speech = {version = "8.5", markers = "platform_release >= \"19.0\""} 515 | pyobjc-framework-SpriteKit = {version = "8.5", markers = "platform_release >= \"13.0\""} 516 | pyobjc-framework-StoreKit = {version = "8.5", markers = "platform_release >= \"11.0\""} 517 | pyobjc-framework-SyncServices = "8.5" 518 | pyobjc-framework-SystemConfiguration = "8.5" 519 | pyobjc-framework-SystemExtensions = {version = "8.5", markers = "platform_release >= \"19.0\""} 520 | pyobjc-framework-UniformTypeIdentifiers = {version = "8.5", markers = "platform_release >= \"20.0\""} 521 | pyobjc-framework-UserNotifications = {version = "8.5", markers = "platform_release >= \"18.0\""} 522 | pyobjc-framework-UserNotificationsUI = {version = "8.5", markers = "platform_release >= \"20.0\""} 523 | pyobjc-framework-VideoSubscriberAccount = {version = "8.5", markers = "platform_release >= \"18.0\""} 524 | pyobjc-framework-VideoToolbox = {version = "8.5", markers = "platform_release >= \"12.0\""} 525 | pyobjc-framework-Virtualization = {version = "8.5", markers = "platform_release >= \"20.0\""} 526 | pyobjc-framework-Vision = {version = "8.5", markers = "platform_release >= \"17.0\""} 527 | pyobjc-framework-WebKit = "8.5" 528 | 529 | [package.extras] 530 | allbindings = ["pyobjc-core (==8.5)", "pyobjc-framework-libdispatch (==8.5)", "pyobjc-framework-Accessibility (==8.5)", "pyobjc-framework-AdServices (==8.5)", "pyobjc-framework-AdSupport (==8.5)", "pyobjc-framework-AppTrackingTransparency (==8.5)", "pyobjc-framework-AudioVideoBridging (==8.5)", "pyobjc-framework-AuthenticationServices (==8.5)", "pyobjc-framework-AutomaticAssessmentConfiguration (==8.5)", "pyobjc-framework-AVKit (==8.5)", "pyobjc-framework-AVFoundation (==8.5)", "pyobjc-framework-Accounts (==8.5)", "pyobjc-framework-AddressBook (==8.5)", "pyobjc-framework-AppleScriptKit (==8.5)", "pyobjc-framework-AppleScriptObjC (==8.5)", "pyobjc-framework-ApplicationServices (==8.5)", "pyobjc-framework-Automator (==8.5)", "pyobjc-framework-BusinessChat (==8.5)", "pyobjc-framework-CFNetwork (==8.5)", "pyobjc-framework-CalendarStore (==8.5)", "pyobjc-framework-CallKit (==8.5)", "pyobjc-framework-ClassKit (==8.5)", "pyobjc-framework-CloudKit (==8.5)", "pyobjc-framework-Cocoa (==8.5)", "pyobjc-framework-Collaboration (==8.5)", "pyobjc-framework-ColorSync (==8.5)", "pyobjc-framework-Contacts (==8.5)", "pyobjc-framework-ContactsUI (==8.5)", "pyobjc-framework-CoreAudio (==8.5)", "pyobjc-framework-CoreAudioKit (==8.5)", "pyobjc-framework-CoreBluetooth (==8.5)", "pyobjc-framework-CoreData (==8.5)", "pyobjc-framework-CoreHaptics (==8.5)", "pyobjc-framework-CoreLocation (==8.5)", "pyobjc-framework-CoreMedia (==8.5)", "pyobjc-framework-CoreMediaIO (==8.5)", "pyobjc-framework-CoreMIDI (==8.5)", "pyobjc-framework-CoreML (==8.5)", "pyobjc-framework-CoreMotion (==8.5)", "pyobjc-framework-CoreServices (==8.5)", "pyobjc-framework-CoreSpotlight (==8.5)", "pyobjc-framework-CoreText (==8.5)", "pyobjc-framework-CoreWLAN (==8.5)", "pyobjc-framework-CryptoTokenKit (==8.5)", "pyobjc-framework-DataDetection (==8.5)", "pyobjc-framework-DeviceCheck (==8.5)", "pyobjc-framework-DictionaryServices (==8.5)", "pyobjc-framework-DiscRecording (==8.5)", "pyobjc-framework-DiscRecordingUI (==8.5)", "pyobjc-framework-DiskArbitration (==8.5)", "pyobjc-framework-DVDPlayback (==8.5)", "pyobjc-framework-EventKit (==8.5)", "pyobjc-framework-ExceptionHandling (==8.5)", "pyobjc-framework-ExecutionPolicy (==8.5)", "pyobjc-framework-ExternalAccessory (==8.5)", "pyobjc-framework-FileProvider (==8.5)", "pyobjc-framework-FileProviderUI (==8.5)", "pyobjc-framework-FSEvents (==8.5)", "pyobjc-framework-FinderSync (==8.5)", "pyobjc-framework-GameCenter (==8.5)", "pyobjc-framework-GameController (==8.5)", "pyobjc-framework-IMServicePlugIn (==8.5)", "pyobjc-framework-InputMethodKit (==8.5)", "pyobjc-framework-ImageCaptureCore (==8.5)", "pyobjc-framework-Intents (==8.5)", "pyobjc-framework-IntentsUI (==8.5)", "pyobjc-framework-InstallerPlugins (==8.5)", "pyobjc-framework-InstantMessage (==8.5)", "pyobjc-framework-IOSurface (==8.5)", "pyobjc-framework-KernelManagement (==8.5)", "pyobjc-framework-LatentSemanticMapping (==8.5)", "pyobjc-framework-LaunchServices (==8.5)", "pyobjc-framework-LinkPresentation (==8.5)", "pyobjc-framework-LocalAuthentication (==8.5)", "pyobjc-framework-LocalAuthenticationEmbeddedUI (==8.5)", "pyobjc-framework-MailKit (==8.5)", "pyobjc-framework-MapKit (==8.5)", "pyobjc-framework-MediaAccessibility (==8.5)", "pyobjc-framework-MediaLibrary (==8.5)", "pyobjc-framework-MediaPlayer (==8.5)", "pyobjc-framework-MediaToolbox (==8.5)", "pyobjc-framework-Message (==8.5)", "pyobjc-framework-Metal (==8.5)", "pyobjc-framework-MetalKit (==8.5)", "pyobjc-framework-MetalPerformanceShaders (==8.5)", "pyobjc-framework-MetalPerformanceShadersGraph (==8.5)", "pyobjc-framework-MetricKit (==8.5)", "pyobjc-framework-MLCompute (==8.5)", "pyobjc-framework-ModelIO (==8.5)", "pyobjc-framework-MultipeerConnectivity (==8.5)", "pyobjc-framework-NaturalLanguage (==8.5)", "pyobjc-framework-NetFS (==8.5)", "pyobjc-framework-Network (==8.5)", "pyobjc-framework-NetworkExtension (==8.5)", "pyobjc-framework-NotificationCenter (==8.5)", "pyobjc-framework-OpenDirectory (==8.5)", "pyobjc-framework-OSAKit (==8.5)", "pyobjc-framework-OSLog (==8.5)", "pyobjc-framework-PassKit (==8.5)", "pyobjc-framework-PencilKit (==8.5)", "pyobjc-framework-Photos (==8.5)", "pyobjc-framework-PhotosUI (==8.5)", "pyobjc-framework-PreferencePanes (==8.5)", "pyobjc-framework-PubSub (==8.5)", "pyobjc-framework-PushKit (==8.5)", "pyobjc-framework-Quartz (==8.5)", "pyobjc-framework-QuickLookThumbnailing (==8.5)", "pyobjc-framework-ReplayKit (==8.5)", "pyobjc-framework-SafariServices (==8.5)", "pyobjc-framework-ScreenSaver (==8.5)", "pyobjc-framework-ScreenTime (==8.5)", "pyobjc-framework-ScriptingBridge (==8.5)", "pyobjc-framework-Security (==8.5)", "pyobjc-framework-SecurityFoundation (==8.5)", "pyobjc-framework-SecurityInterface (==8.5)", "pyobjc-framework-SearchKit (==8.5)", "pyobjc-framework-ServerNotification (==8.5)", "pyobjc-framework-ServiceManagement (==8.5)", "pyobjc-framework-ShazamKit (==8.5)", "pyobjc-framework-Social (==8.5)", "pyobjc-framework-Speech (==8.5)", "pyobjc-framework-SpriteKit (==8.5)", "pyobjc-framework-StoreKit (==8.5)", "pyobjc-framework-SyncServices (==8.5)", "pyobjc-framework-SystemConfiguration (==8.5)", "pyobjc-framework-WebKit (==8.5)", "pyobjc-framework-GameKit (==8.5)", "pyobjc-framework-GameplayKit (==8.5)", "pyobjc-framework-SceneKit (==8.5)", "pyobjc-framework-SoundAnalysis (==8.5)", "pyobjc-framework-ScreenCaptureKit (==8.5)", "pyobjc-framework-SystemExtensions (==8.5)", "pyobjc-framework-UniformTypeIdentifiers (==8.5)", "pyobjc-framework-UserNotifications (==8.5)", "pyobjc-framework-UserNotificationsUI (==8.5)", "pyobjc-framework-VideoSubscriberAccount (==8.5)", "pyobjc-framework-VideoToolbox (==8.5)", "pyobjc-framework-Virtualization (==8.5)", "pyobjc-framework-Vision (==8.5)", "pyobjc-framework-iTunesLibrary (==8.5)"] 531 | 532 | [[package]] 533 | name = "pyobjc-core" 534 | version = "8.5" 535 | description = "Python<->ObjC Interoperability Module" 536 | category = "main" 537 | optional = false 538 | python-versions = ">=3.6" 539 | 540 | [[package]] 541 | name = "pyobjc-framework-accessibility" 542 | version = "8.5" 543 | description = "Wrappers for the framework Accessibility on macOS" 544 | category = "main" 545 | optional = false 546 | python-versions = ">=3.6" 547 | 548 | [package.dependencies] 549 | pyobjc-core = ">=8.5" 550 | pyobjc-framework-Cocoa = ">=8.5" 551 | pyobjc-framework-Quartz = ">=8.5" 552 | 553 | [[package]] 554 | name = "pyobjc-framework-accounts" 555 | version = "8.5" 556 | description = "Wrappers for the framework Accounts on macOS" 557 | category = "main" 558 | optional = false 559 | python-versions = ">=3.6" 560 | 561 | [package.dependencies] 562 | pyobjc-core = ">=8.5" 563 | pyobjc-framework-Cocoa = ">=8.5" 564 | 565 | [[package]] 566 | name = "pyobjc-framework-addressbook" 567 | version = "8.5" 568 | description = "Wrappers for the framework AddressBook on macOS" 569 | category = "main" 570 | optional = false 571 | python-versions = ">=3.6" 572 | 573 | [package.dependencies] 574 | pyobjc-core = ">=8.5" 575 | pyobjc-framework-Cocoa = ">=8.5" 576 | 577 | [[package]] 578 | name = "pyobjc-framework-adservices" 579 | version = "8.5" 580 | description = "Wrappers for the framework AdServices on macOS" 581 | category = "main" 582 | optional = false 583 | python-versions = ">=3.6" 584 | 585 | [package.dependencies] 586 | pyobjc-core = ">=8.5" 587 | pyobjc-framework-Cocoa = ">=8.5" 588 | 589 | [[package]] 590 | name = "pyobjc-framework-adsupport" 591 | version = "8.5" 592 | description = "Wrappers for the framework AdSupport on macOS" 593 | category = "main" 594 | optional = false 595 | python-versions = ">=3.6" 596 | 597 | [package.dependencies] 598 | pyobjc-core = ">=8.5" 599 | pyobjc-framework-Cocoa = ">=8.5" 600 | 601 | [[package]] 602 | name = "pyobjc-framework-applescriptkit" 603 | version = "8.5" 604 | description = "Wrappers for the framework AppleScriptKit on macOS" 605 | category = "main" 606 | optional = false 607 | python-versions = ">=3.6" 608 | 609 | [package.dependencies] 610 | pyobjc-core = ">=8.5" 611 | pyobjc-framework-Cocoa = ">=8.5" 612 | 613 | [[package]] 614 | name = "pyobjc-framework-applescriptobjc" 615 | version = "8.5" 616 | description = "Wrappers for the framework AppleScriptObjC on macOS" 617 | category = "main" 618 | optional = false 619 | python-versions = ">=3.6" 620 | 621 | [package.dependencies] 622 | pyobjc-core = ">=8.5" 623 | pyobjc-framework-Cocoa = ">=8.5" 624 | 625 | [[package]] 626 | name = "pyobjc-framework-applicationservices" 627 | version = "8.5" 628 | description = "Wrappers for the framework ApplicationServices on macOS" 629 | category = "main" 630 | optional = false 631 | python-versions = ">=3.6" 632 | 633 | [package.dependencies] 634 | pyobjc-core = ">=8.5" 635 | pyobjc-framework-Cocoa = ">=8.5" 636 | pyobjc-framework-Quartz = ">=8.5" 637 | 638 | [[package]] 639 | name = "pyobjc-framework-apptrackingtransparency" 640 | version = "8.5" 641 | description = "Wrappers for the framework AppTrackingTransparency on macOS" 642 | category = "main" 643 | optional = false 644 | python-versions = ">=3.6" 645 | 646 | [package.dependencies] 647 | pyobjc-core = ">=8.5" 648 | pyobjc-framework-Cocoa = ">=8.5" 649 | 650 | [[package]] 651 | name = "pyobjc-framework-audiovideobridging" 652 | version = "8.5" 653 | description = "Wrappers for the framework AudioVideoBridging on macOS" 654 | category = "main" 655 | optional = false 656 | python-versions = ">=3.6" 657 | 658 | [package.dependencies] 659 | pyobjc-core = ">=8.5" 660 | pyobjc-framework-Cocoa = ">=8.5" 661 | 662 | [[package]] 663 | name = "pyobjc-framework-authenticationservices" 664 | version = "8.5" 665 | description = "Wrappers for the framework AuthenticationServices on macOS" 666 | category = "main" 667 | optional = false 668 | python-versions = ">=3.6" 669 | 670 | [package.dependencies] 671 | pyobjc-core = ">=8.5" 672 | pyobjc-framework-Cocoa = ">=8.5" 673 | 674 | [[package]] 675 | name = "pyobjc-framework-automaticassessmentconfiguration" 676 | version = "8.5" 677 | description = "Wrappers for the framework AutomaticAssessmentConfiguration on macOS" 678 | category = "main" 679 | optional = false 680 | python-versions = ">=3.6" 681 | 682 | [package.dependencies] 683 | pyobjc-core = ">=8.5" 684 | pyobjc-framework-Cocoa = ">=8.5" 685 | 686 | [[package]] 687 | name = "pyobjc-framework-automator" 688 | version = "8.5" 689 | description = "Wrappers for the framework Automator on macOS" 690 | category = "main" 691 | optional = false 692 | python-versions = ">=3.6" 693 | 694 | [package.dependencies] 695 | pyobjc-core = ">=8.5" 696 | pyobjc-framework-Cocoa = ">=8.5" 697 | 698 | [[package]] 699 | name = "pyobjc-framework-avfoundation" 700 | version = "8.5" 701 | description = "Wrappers for the framework AVFoundation on macOS" 702 | category = "main" 703 | optional = false 704 | python-versions = ">=3.6" 705 | 706 | [package.dependencies] 707 | pyobjc-core = ">=8.5" 708 | pyobjc-framework-Cocoa = ">=8.5" 709 | pyobjc-framework-CoreAudio = ">=8.5" 710 | pyobjc-framework-CoreMedia = ">=8.5" 711 | pyobjc-framework-Quartz = ">=8.5" 712 | 713 | [[package]] 714 | name = "pyobjc-framework-avkit" 715 | version = "8.5" 716 | description = "Wrappers for the framework AVKit on macOS" 717 | category = "main" 718 | optional = false 719 | python-versions = ">=3.6" 720 | 721 | [package.dependencies] 722 | pyobjc-core = ">=8.5" 723 | pyobjc-framework-Cocoa = ">=8.5" 724 | pyobjc-framework-Quartz = ">=8.5" 725 | 726 | [[package]] 727 | name = "pyobjc-framework-businesschat" 728 | version = "8.5" 729 | description = "Wrappers for the framework BusinessChat on macOS" 730 | category = "main" 731 | optional = false 732 | python-versions = ">=3.6" 733 | 734 | [package.dependencies] 735 | pyobjc-core = ">=8.5" 736 | pyobjc-framework-Cocoa = ">=8.5" 737 | 738 | [[package]] 739 | name = "pyobjc-framework-calendarstore" 740 | version = "8.5" 741 | description = "Wrappers for the framework CalendarStore on macOS" 742 | category = "main" 743 | optional = false 744 | python-versions = ">=3.6" 745 | 746 | [package.dependencies] 747 | pyobjc-core = ">=8.5" 748 | pyobjc-framework-Cocoa = ">=8.5" 749 | 750 | [[package]] 751 | name = "pyobjc-framework-callkit" 752 | version = "8.5" 753 | description = "Wrappers for the framework CallKit on macOS" 754 | category = "main" 755 | optional = false 756 | python-versions = ">=3.6" 757 | 758 | [package.dependencies] 759 | pyobjc-core = ">=8.5" 760 | pyobjc-framework-Cocoa = ">=8.5" 761 | 762 | [[package]] 763 | name = "pyobjc-framework-cfnetwork" 764 | version = "8.5" 765 | description = "Wrappers for the framework CFNetwork on macOS" 766 | category = "main" 767 | optional = false 768 | python-versions = ">=3.6" 769 | 770 | [package.dependencies] 771 | pyobjc-core = ">=8.5" 772 | pyobjc-framework-Cocoa = ">=8.5" 773 | 774 | [[package]] 775 | name = "pyobjc-framework-classkit" 776 | version = "8.5" 777 | description = "Wrappers for the framework ClassKit on macOS" 778 | category = "main" 779 | optional = false 780 | python-versions = ">=3.6" 781 | 782 | [package.dependencies] 783 | pyobjc-core = ">=8.5" 784 | pyobjc-framework-Cocoa = ">=8.5" 785 | 786 | [[package]] 787 | name = "pyobjc-framework-cloudkit" 788 | version = "8.5" 789 | description = "Wrappers for the framework CloudKit on macOS" 790 | category = "main" 791 | optional = false 792 | python-versions = ">=3.6" 793 | 794 | [package.dependencies] 795 | pyobjc-core = ">=8.5" 796 | pyobjc-framework-Accounts = ">=8.5" 797 | pyobjc-framework-Cocoa = ">=8.5" 798 | pyobjc-framework-CoreData = ">=8.5" 799 | pyobjc-framework-CoreLocation = ">=8.5" 800 | 801 | [[package]] 802 | name = "pyobjc-framework-cocoa" 803 | version = "8.5" 804 | description = "Wrappers for the Cocoa frameworks on macOS" 805 | category = "main" 806 | optional = false 807 | python-versions = ">=3.6" 808 | 809 | [package.dependencies] 810 | pyobjc-core = ">=8.5" 811 | 812 | [[package]] 813 | name = "pyobjc-framework-collaboration" 814 | version = "8.5" 815 | description = "Wrappers for the framework Collaboration on macOS" 816 | category = "main" 817 | optional = false 818 | python-versions = ">=3.6" 819 | 820 | [package.dependencies] 821 | pyobjc-core = ">=8.5" 822 | pyobjc-framework-Cocoa = ">=8.5" 823 | 824 | [[package]] 825 | name = "pyobjc-framework-colorsync" 826 | version = "8.5" 827 | description = "Wrappers for the framework ColorSync on Mac OS X" 828 | category = "main" 829 | optional = false 830 | python-versions = ">=3.6" 831 | 832 | [package.dependencies] 833 | pyobjc-core = ">=8.5" 834 | pyobjc-framework-Cocoa = ">=8.5" 835 | 836 | [[package]] 837 | name = "pyobjc-framework-contacts" 838 | version = "8.5" 839 | description = "Wrappers for the framework Contacts on macOS" 840 | category = "main" 841 | optional = false 842 | python-versions = ">=3.6" 843 | 844 | [package.dependencies] 845 | pyobjc-core = ">=8.5" 846 | pyobjc-framework-Cocoa = ">=8.5" 847 | 848 | [[package]] 849 | name = "pyobjc-framework-contactsui" 850 | version = "8.5" 851 | description = "Wrappers for the framework ContactsUI on macOS" 852 | category = "main" 853 | optional = false 854 | python-versions = ">=3.6" 855 | 856 | [package.dependencies] 857 | pyobjc-core = ">=8.5" 858 | pyobjc-framework-Cocoa = ">=8.5" 859 | pyobjc-framework-Contacts = ">=8.5" 860 | 861 | [[package]] 862 | name = "pyobjc-framework-coreaudio" 863 | version = "8.5" 864 | description = "Wrappers for the framework CoreAudio on macOS" 865 | category = "main" 866 | optional = false 867 | python-versions = ">=3.6" 868 | 869 | [package.dependencies] 870 | pyobjc-core = ">=8.5" 871 | pyobjc-framework-Cocoa = ">=8.5" 872 | 873 | [[package]] 874 | name = "pyobjc-framework-coreaudiokit" 875 | version = "8.5" 876 | description = "Wrappers for the framework CoreAudioKit on macOS" 877 | category = "main" 878 | optional = false 879 | python-versions = ">=3.6" 880 | 881 | [package.dependencies] 882 | pyobjc-core = ">=8.5" 883 | pyobjc-framework-Cocoa = ">=8.5" 884 | pyobjc-framework-CoreAudio = ">=8.5" 885 | 886 | [[package]] 887 | name = "pyobjc-framework-corebluetooth" 888 | version = "8.5" 889 | description = "Wrappers for the framework CoreBluetooth on macOS" 890 | category = "main" 891 | optional = false 892 | python-versions = ">=3.6" 893 | 894 | [package.dependencies] 895 | pyobjc-core = ">=8.5" 896 | pyobjc-framework-Cocoa = ">=8.5" 897 | 898 | [[package]] 899 | name = "pyobjc-framework-coredata" 900 | version = "8.5" 901 | description = "Wrappers for the framework CoreData on macOS" 902 | category = "main" 903 | optional = false 904 | python-versions = ">=3.6" 905 | 906 | [package.dependencies] 907 | pyobjc-core = ">=8.5" 908 | pyobjc-framework-Cocoa = ">=8.5" 909 | 910 | [[package]] 911 | name = "pyobjc-framework-corehaptics" 912 | version = "8.5" 913 | description = "Wrappers for the framework CoreHaptics on macOS" 914 | category = "main" 915 | optional = false 916 | python-versions = ">=3.6" 917 | 918 | [package.dependencies] 919 | pyobjc-core = ">=8.5" 920 | pyobjc-framework-Cocoa = ">=8.5" 921 | 922 | [[package]] 923 | name = "pyobjc-framework-corelocation" 924 | version = "8.5" 925 | description = "Wrappers for the framework CoreLocation on macOS" 926 | category = "main" 927 | optional = false 928 | python-versions = ">=3.6" 929 | 930 | [package.dependencies] 931 | pyobjc-core = ">=8.5" 932 | pyobjc-framework-Cocoa = ">=8.5" 933 | 934 | [[package]] 935 | name = "pyobjc-framework-coremedia" 936 | version = "8.5" 937 | description = "Wrappers for the framework CoreMedia on macOS" 938 | category = "main" 939 | optional = false 940 | python-versions = ">=3.6" 941 | 942 | [package.dependencies] 943 | pyobjc-core = ">=8.5" 944 | pyobjc-framework-Cocoa = ">=8.5" 945 | 946 | [[package]] 947 | name = "pyobjc-framework-coremediaio" 948 | version = "8.5" 949 | description = "Wrappers for the framework CoreMediaIO on macOS" 950 | category = "main" 951 | optional = false 952 | python-versions = ">=3.6" 953 | 954 | [package.dependencies] 955 | pyobjc-core = ">=8.5" 956 | pyobjc-framework-Cocoa = ">=8.5" 957 | 958 | [[package]] 959 | name = "pyobjc-framework-coremidi" 960 | version = "8.5" 961 | description = "Wrappers for the framework CoreMIDI on macOS" 962 | category = "main" 963 | optional = false 964 | python-versions = ">=3.6" 965 | 966 | [package.dependencies] 967 | pyobjc-core = ">=8.5" 968 | pyobjc-framework-Cocoa = ">=8.5" 969 | 970 | [[package]] 971 | name = "pyobjc-framework-coreml" 972 | version = "8.5" 973 | description = "Wrappers for the framework CoreML on macOS" 974 | category = "main" 975 | optional = false 976 | python-versions = ">=3.6" 977 | 978 | [package.dependencies] 979 | pyobjc-core = ">=8.5" 980 | pyobjc-framework-Cocoa = ">=8.5" 981 | 982 | [[package]] 983 | name = "pyobjc-framework-coremotion" 984 | version = "8.5" 985 | description = "Wrappers for the framework CoreMotion on macOS" 986 | category = "main" 987 | optional = false 988 | python-versions = ">=3.6" 989 | 990 | [package.dependencies] 991 | pyobjc-core = ">=8.5" 992 | pyobjc-framework-Cocoa = ">=8.5" 993 | 994 | [[package]] 995 | name = "pyobjc-framework-coreservices" 996 | version = "8.5" 997 | description = "Wrappers for the framework CoreServices on macOS" 998 | category = "main" 999 | optional = false 1000 | python-versions = ">=3.6" 1001 | 1002 | [package.dependencies] 1003 | pyobjc-core = ">=8.5" 1004 | pyobjc-framework-FSEvents = ">=8.5" 1005 | 1006 | [[package]] 1007 | name = "pyobjc-framework-corespotlight" 1008 | version = "8.5" 1009 | description = "Wrappers for the framework CoreSpotlight on macOS" 1010 | category = "main" 1011 | optional = false 1012 | python-versions = ">=3.6" 1013 | 1014 | [package.dependencies] 1015 | pyobjc-core = ">=8.5" 1016 | pyobjc-framework-Cocoa = ">=8.5" 1017 | 1018 | [[package]] 1019 | name = "pyobjc-framework-coretext" 1020 | version = "8.5" 1021 | description = "Wrappers for the framework CoreText on macOS" 1022 | category = "main" 1023 | optional = false 1024 | python-versions = ">=3.6" 1025 | 1026 | [package.dependencies] 1027 | pyobjc-core = ">=8.5" 1028 | pyobjc-framework-Cocoa = ">=8.5" 1029 | pyobjc-framework-Quartz = ">=8.5" 1030 | 1031 | [[package]] 1032 | name = "pyobjc-framework-corewlan" 1033 | version = "8.5" 1034 | description = "Wrappers for the framework CoreWLAN on macOS" 1035 | category = "main" 1036 | optional = false 1037 | python-versions = ">=3.6" 1038 | 1039 | [package.dependencies] 1040 | pyobjc-core = ">=8.5" 1041 | pyobjc-framework-Cocoa = ">=8.5" 1042 | 1043 | [[package]] 1044 | name = "pyobjc-framework-cryptotokenkit" 1045 | version = "8.5" 1046 | description = "Wrappers for the framework CryptoTokenKit on macOS" 1047 | category = "main" 1048 | optional = false 1049 | python-versions = ">=3.6" 1050 | 1051 | [package.dependencies] 1052 | pyobjc-core = ">=8.5" 1053 | pyobjc-framework-Cocoa = ">=8.5" 1054 | 1055 | [[package]] 1056 | name = "pyobjc-framework-datadetection" 1057 | version = "8.5" 1058 | description = "Wrappers for the framework DataDetection on macOS" 1059 | category = "main" 1060 | optional = false 1061 | python-versions = ">=3.6" 1062 | 1063 | [package.dependencies] 1064 | pyobjc-core = ">=8.5" 1065 | pyobjc-framework-Cocoa = ">=8.5" 1066 | 1067 | [[package]] 1068 | name = "pyobjc-framework-devicecheck" 1069 | version = "8.5" 1070 | description = "Wrappers for the framework DeviceCheck on macOS" 1071 | category = "main" 1072 | optional = false 1073 | python-versions = ">=3.6" 1074 | 1075 | [package.dependencies] 1076 | pyobjc-core = ">=8.5" 1077 | pyobjc-framework-Cocoa = ">=8.5" 1078 | 1079 | [[package]] 1080 | name = "pyobjc-framework-dictionaryservices" 1081 | version = "8.5" 1082 | description = "Wrappers for the framework DictionaryServices on macOS" 1083 | category = "main" 1084 | optional = false 1085 | python-versions = ">=3.6" 1086 | 1087 | [package.dependencies] 1088 | pyobjc-core = ">=8.5" 1089 | pyobjc-framework-CoreServices = ">=8.5" 1090 | 1091 | [[package]] 1092 | name = "pyobjc-framework-discrecording" 1093 | version = "8.5" 1094 | description = "Wrappers for the framework DiscRecording on macOS" 1095 | category = "main" 1096 | optional = false 1097 | python-versions = ">=3.6" 1098 | 1099 | [package.dependencies] 1100 | pyobjc-core = ">=8.5" 1101 | pyobjc-framework-Cocoa = ">=8.5" 1102 | 1103 | [[package]] 1104 | name = "pyobjc-framework-discrecordingui" 1105 | version = "8.5" 1106 | description = "Wrappers for the framework DiscRecordingUI on macOS" 1107 | category = "main" 1108 | optional = false 1109 | python-versions = ">=3.6" 1110 | 1111 | [package.dependencies] 1112 | pyobjc-core = ">=8.5" 1113 | pyobjc-framework-Cocoa = ">=8.5" 1114 | pyobjc-framework-DiscRecording = ">=8.5" 1115 | 1116 | [[package]] 1117 | name = "pyobjc-framework-diskarbitration" 1118 | version = "8.5" 1119 | description = "Wrappers for the framework DiskArbitration on macOS" 1120 | category = "main" 1121 | optional = false 1122 | python-versions = ">=3.6" 1123 | 1124 | [package.dependencies] 1125 | pyobjc-core = ">=8.5" 1126 | pyobjc-framework-Cocoa = ">=8.5" 1127 | 1128 | [[package]] 1129 | name = "pyobjc-framework-dvdplayback" 1130 | version = "8.5" 1131 | description = "Wrappers for the framework DVDPlayback on macOS" 1132 | category = "main" 1133 | optional = false 1134 | python-versions = ">=3.6" 1135 | 1136 | [package.dependencies] 1137 | pyobjc-core = ">=8.5" 1138 | pyobjc-framework-Cocoa = ">=8.5" 1139 | 1140 | [[package]] 1141 | name = "pyobjc-framework-eventkit" 1142 | version = "8.5" 1143 | description = "Wrappers for the framework Accounts on macOS" 1144 | category = "main" 1145 | optional = false 1146 | python-versions = ">=3.6" 1147 | 1148 | [package.dependencies] 1149 | pyobjc-core = ">=8.5" 1150 | pyobjc-framework-Cocoa = ">=8.5" 1151 | 1152 | [[package]] 1153 | name = "pyobjc-framework-exceptionhandling" 1154 | version = "8.5" 1155 | description = "Wrappers for the framework ExceptionHandling on macOS" 1156 | category = "main" 1157 | optional = false 1158 | python-versions = ">=3.6" 1159 | 1160 | [package.dependencies] 1161 | pyobjc-core = ">=8.5" 1162 | pyobjc-framework-Cocoa = ">=8.5" 1163 | 1164 | [[package]] 1165 | name = "pyobjc-framework-executionpolicy" 1166 | version = "8.5" 1167 | description = "Wrappers for the framework ExecutionPolicy on macOS" 1168 | category = "main" 1169 | optional = false 1170 | python-versions = ">=3.6" 1171 | 1172 | [package.dependencies] 1173 | pyobjc-core = ">=8.5" 1174 | pyobjc-framework-Cocoa = ">=8.5" 1175 | 1176 | [[package]] 1177 | name = "pyobjc-framework-externalaccessory" 1178 | version = "8.5" 1179 | description = "Wrappers for the framework ExternalAccessory on macOS" 1180 | category = "main" 1181 | optional = false 1182 | python-versions = ">=3.6" 1183 | 1184 | [package.dependencies] 1185 | pyobjc-core = ">=8.5" 1186 | pyobjc-framework-Cocoa = ">=8.5" 1187 | 1188 | [[package]] 1189 | name = "pyobjc-framework-fileprovider" 1190 | version = "8.5" 1191 | description = "Wrappers for the framework FileProvider on macOS" 1192 | category = "main" 1193 | optional = false 1194 | python-versions = ">=3.6" 1195 | 1196 | [package.dependencies] 1197 | pyobjc-core = ">=8.5" 1198 | pyobjc-framework-Cocoa = ">=8.5" 1199 | 1200 | [[package]] 1201 | name = "pyobjc-framework-fileproviderui" 1202 | version = "8.5" 1203 | description = "Wrappers for the framework FileProviderUI on macOS" 1204 | category = "main" 1205 | optional = false 1206 | python-versions = ">=3.6" 1207 | 1208 | [package.dependencies] 1209 | pyobjc-core = ">=8.5" 1210 | pyobjc-framework-FileProvider = ">=8.5" 1211 | 1212 | [[package]] 1213 | name = "pyobjc-framework-findersync" 1214 | version = "8.5" 1215 | description = "Wrappers for the framework FinderSync on macOS" 1216 | category = "main" 1217 | optional = false 1218 | python-versions = ">=3.6" 1219 | 1220 | [package.dependencies] 1221 | pyobjc-core = ">=8.5" 1222 | pyobjc-framework-Cocoa = ">=8.5" 1223 | 1224 | [[package]] 1225 | name = "pyobjc-framework-fsevents" 1226 | version = "8.5" 1227 | description = "Wrappers for the framework FSEvents on macOS" 1228 | category = "main" 1229 | optional = false 1230 | python-versions = ">=3.6" 1231 | 1232 | [package.dependencies] 1233 | pyobjc-core = ">=8.5" 1234 | pyobjc-framework-Cocoa = ">=8.5" 1235 | 1236 | [[package]] 1237 | name = "pyobjc-framework-gamecenter" 1238 | version = "8.5" 1239 | description = "Wrappers for the framework GameCenter on macOS" 1240 | category = "main" 1241 | optional = false 1242 | python-versions = ">=3.6" 1243 | 1244 | [package.dependencies] 1245 | pyobjc-core = ">=8.5" 1246 | pyobjc-framework-Cocoa = ">=8.5" 1247 | 1248 | [[package]] 1249 | name = "pyobjc-framework-gamecontroller" 1250 | version = "8.5" 1251 | description = "Wrappers for the framework GameController on macOS" 1252 | category = "main" 1253 | optional = false 1254 | python-versions = ">=3.6" 1255 | 1256 | [package.dependencies] 1257 | pyobjc-core = ">=8.5" 1258 | pyobjc-framework-Cocoa = ">=8.5" 1259 | 1260 | [[package]] 1261 | name = "pyobjc-framework-gamekit" 1262 | version = "8.5" 1263 | description = "Wrappers for the framework GameKit on macOS" 1264 | category = "main" 1265 | optional = false 1266 | python-versions = ">=3.6" 1267 | 1268 | [package.dependencies] 1269 | pyobjc-core = ">=8.5" 1270 | pyobjc-framework-Cocoa = ">=8.5" 1271 | pyobjc-framework-Quartz = ">=8.5" 1272 | 1273 | [[package]] 1274 | name = "pyobjc-framework-gameplaykit" 1275 | version = "8.5" 1276 | description = "Wrappers for the framework GameplayKit on macOS" 1277 | category = "main" 1278 | optional = false 1279 | python-versions = ">=3.6" 1280 | 1281 | [package.dependencies] 1282 | pyobjc-core = ">=8.5" 1283 | pyobjc-framework-Cocoa = ">=8.5" 1284 | pyobjc-framework-SpriteKit = ">=8.5" 1285 | 1286 | [[package]] 1287 | name = "pyobjc-framework-imagecapturecore" 1288 | version = "8.5" 1289 | description = "Wrappers for the framework ImageCaptureCore on macOS" 1290 | category = "main" 1291 | optional = false 1292 | python-versions = ">=3.6" 1293 | 1294 | [package.dependencies] 1295 | pyobjc-core = ">=8.5" 1296 | pyobjc-framework-Cocoa = ">=8.5" 1297 | 1298 | [[package]] 1299 | name = "pyobjc-framework-imserviceplugin" 1300 | version = "8.5" 1301 | description = "Wrappers for the framework IMServicePlugIn on macOS" 1302 | category = "main" 1303 | optional = false 1304 | python-versions = ">=3.6" 1305 | 1306 | [package.dependencies] 1307 | pyobjc-core = ">=8.5" 1308 | pyobjc-framework-Cocoa = ">=8.5" 1309 | 1310 | [[package]] 1311 | name = "pyobjc-framework-inputmethodkit" 1312 | version = "8.5" 1313 | description = "Wrappers for the framework InputMethodKit on macOS" 1314 | category = "main" 1315 | optional = false 1316 | python-versions = ">=3.6" 1317 | 1318 | [package.dependencies] 1319 | pyobjc-core = ">=8.5" 1320 | pyobjc-framework-Cocoa = ">=8.5" 1321 | 1322 | [[package]] 1323 | name = "pyobjc-framework-installerplugins" 1324 | version = "8.5" 1325 | description = "Wrappers for the framework InstallerPlugins on macOS" 1326 | category = "main" 1327 | optional = false 1328 | python-versions = ">=3.6" 1329 | 1330 | [package.dependencies] 1331 | pyobjc-core = ">=8.5" 1332 | pyobjc-framework-Cocoa = ">=8.5" 1333 | 1334 | [[package]] 1335 | name = "pyobjc-framework-instantmessage" 1336 | version = "8.5" 1337 | description = "Wrappers for the framework InstantMessage on macOS" 1338 | category = "main" 1339 | optional = false 1340 | python-versions = ">=3.6" 1341 | 1342 | [package.dependencies] 1343 | pyobjc-core = ">=8.5" 1344 | pyobjc-framework-Cocoa = ">=8.5" 1345 | pyobjc-framework-Quartz = ">=8.5" 1346 | 1347 | [[package]] 1348 | name = "pyobjc-framework-intents" 1349 | version = "8.5" 1350 | description = "Wrappers for the framework Intents on macOS" 1351 | category = "main" 1352 | optional = false 1353 | python-versions = ">=3.6" 1354 | 1355 | [package.dependencies] 1356 | pyobjc-core = ">=8.5" 1357 | pyobjc-framework-Cocoa = ">=8.5" 1358 | 1359 | [[package]] 1360 | name = "pyobjc-framework-intentsui" 1361 | version = "8.5" 1362 | description = "Wrappers for the framework Intents on macOS" 1363 | category = "main" 1364 | optional = false 1365 | python-versions = ">=3.6" 1366 | 1367 | [package.dependencies] 1368 | pyobjc-core = ">=8.5" 1369 | pyobjc-framework-Intents = ">=8.5" 1370 | 1371 | [[package]] 1372 | name = "pyobjc-framework-iosurface" 1373 | version = "8.5" 1374 | description = "Wrappers for the framework IOSurface on macOS" 1375 | category = "main" 1376 | optional = false 1377 | python-versions = ">=3.6" 1378 | 1379 | [package.dependencies] 1380 | pyobjc-core = ">=8.5" 1381 | pyobjc-framework-Cocoa = ">=8.5" 1382 | 1383 | [[package]] 1384 | name = "pyobjc-framework-ituneslibrary" 1385 | version = "8.5" 1386 | description = "Wrappers for the framework iTunesLibrary on macOS" 1387 | category = "main" 1388 | optional = false 1389 | python-versions = ">=3.6" 1390 | 1391 | [package.dependencies] 1392 | pyobjc-core = ">=8.5" 1393 | pyobjc-framework-Cocoa = ">=8.5" 1394 | 1395 | [[package]] 1396 | name = "pyobjc-framework-kernelmanagement" 1397 | version = "8.5" 1398 | description = "Wrappers for the framework KernelManagement on macOS" 1399 | category = "main" 1400 | optional = false 1401 | python-versions = ">=3.6" 1402 | 1403 | [package.dependencies] 1404 | pyobjc-core = ">=8.5" 1405 | pyobjc-framework-Cocoa = ">=8.5" 1406 | 1407 | [[package]] 1408 | name = "pyobjc-framework-latentsemanticmapping" 1409 | version = "8.5" 1410 | description = "Wrappers for the framework LatentSemanticMapping on macOS" 1411 | category = "main" 1412 | optional = false 1413 | python-versions = ">=3.6" 1414 | 1415 | [package.dependencies] 1416 | pyobjc-core = ">=8.5" 1417 | pyobjc-framework-Cocoa = ">=8.5" 1418 | 1419 | [[package]] 1420 | name = "pyobjc-framework-launchservices" 1421 | version = "8.5" 1422 | description = "Wrappers for the framework LaunchServices on macOS" 1423 | category = "main" 1424 | optional = false 1425 | python-versions = ">=3.6" 1426 | 1427 | [package.dependencies] 1428 | pyobjc-core = ">=8.5" 1429 | pyobjc-framework-CoreServices = ">=8.5" 1430 | 1431 | [[package]] 1432 | name = "pyobjc-framework-libdispatch" 1433 | version = "8.5" 1434 | description = "Wrappers for libdispatch on macOS" 1435 | category = "main" 1436 | optional = false 1437 | python-versions = ">=3.6" 1438 | 1439 | [package.dependencies] 1440 | pyobjc-core = ">=8.5" 1441 | 1442 | [[package]] 1443 | name = "pyobjc-framework-linkpresentation" 1444 | version = "8.5" 1445 | description = "Wrappers for the framework LinkPresentation on macOS" 1446 | category = "main" 1447 | optional = false 1448 | python-versions = ">=3.6" 1449 | 1450 | [package.dependencies] 1451 | pyobjc-core = ">=8.5" 1452 | pyobjc-framework-Cocoa = ">=8.5" 1453 | pyobjc-framework-Quartz = ">=8.5" 1454 | 1455 | [[package]] 1456 | name = "pyobjc-framework-localauthentication" 1457 | version = "8.5" 1458 | description = "Wrappers for the framework LocalAuthentication on macOS" 1459 | category = "main" 1460 | optional = false 1461 | python-versions = ">=3.6" 1462 | 1463 | [package.dependencies] 1464 | pyobjc-core = ">=8.5" 1465 | pyobjc-framework-Cocoa = ">=8.5" 1466 | pyobjc-framework-Security = ">=8.5" 1467 | 1468 | [[package]] 1469 | name = "pyobjc-framework-localauthenticationembeddedui" 1470 | version = "8.5" 1471 | description = "Wrappers for the framework LocalAuthenticationEmbeddedUI on macOS" 1472 | category = "main" 1473 | optional = false 1474 | python-versions = ">=3.6" 1475 | 1476 | [package.dependencies] 1477 | pyobjc-core = ">=8.5" 1478 | pyobjc-framework-Cocoa = ">=8.5" 1479 | pyobjc-framework-LocalAuthentication = ">=8.5" 1480 | 1481 | [[package]] 1482 | name = "pyobjc-framework-mailkit" 1483 | version = "8.5" 1484 | description = "Wrappers for the framework MailKit on macOS" 1485 | category = "main" 1486 | optional = false 1487 | python-versions = ">=3.6" 1488 | 1489 | [package.dependencies] 1490 | pyobjc-core = ">=8.5" 1491 | pyobjc-framework-Cocoa = ">=8.5" 1492 | 1493 | [[package]] 1494 | name = "pyobjc-framework-mapkit" 1495 | version = "8.5" 1496 | description = "Wrappers for the framework MapKit on macOS" 1497 | category = "main" 1498 | optional = false 1499 | python-versions = ">=3.6" 1500 | 1501 | [package.dependencies] 1502 | pyobjc-core = ">=8.5" 1503 | pyobjc-framework-Cocoa = ">=8.5" 1504 | pyobjc-framework-CoreLocation = ">=8.5" 1505 | pyobjc-framework-Quartz = ">=8.5" 1506 | 1507 | [[package]] 1508 | name = "pyobjc-framework-mediaaccessibility" 1509 | version = "8.5" 1510 | description = "Wrappers for the framework MediaAccessibility on macOS" 1511 | category = "main" 1512 | optional = false 1513 | python-versions = ">=3.6" 1514 | 1515 | [package.dependencies] 1516 | pyobjc-core = ">=8.5" 1517 | pyobjc-framework-Cocoa = ">=8.5" 1518 | 1519 | [[package]] 1520 | name = "pyobjc-framework-medialibrary" 1521 | version = "8.5" 1522 | description = "Wrappers for the framework MediaLibrary on macOS" 1523 | category = "main" 1524 | optional = false 1525 | python-versions = ">=3.6" 1526 | 1527 | [package.dependencies] 1528 | pyobjc-core = ">=8.5" 1529 | pyobjc-framework-Cocoa = ">=8.5" 1530 | pyobjc-framework-Quartz = ">=8.5" 1531 | 1532 | [[package]] 1533 | name = "pyobjc-framework-mediaplayer" 1534 | version = "8.5" 1535 | description = "Wrappers for the framework MediaPlayer on macOS" 1536 | category = "main" 1537 | optional = false 1538 | python-versions = ">=3.6" 1539 | 1540 | [package.dependencies] 1541 | pyobjc-core = ">=8.5" 1542 | pyobjc-framework-AVFoundation = ">=8.5" 1543 | 1544 | [[package]] 1545 | name = "pyobjc-framework-mediatoolbox" 1546 | version = "8.5" 1547 | description = "Wrappers for the framework MediaToolbox on macOS" 1548 | category = "main" 1549 | optional = false 1550 | python-versions = ">=3.6" 1551 | 1552 | [package.dependencies] 1553 | pyobjc-core = ">=8.5" 1554 | pyobjc-framework-Cocoa = ">=8.5" 1555 | 1556 | [[package]] 1557 | name = "pyobjc-framework-message" 1558 | version = "8.5" 1559 | description = "Wrappers for the framework Message on macOS" 1560 | category = "main" 1561 | optional = false 1562 | python-versions = ">=3.6" 1563 | 1564 | [package.dependencies] 1565 | pyobjc-core = ">=8.5" 1566 | pyobjc-framework-Cocoa = ">=8.5" 1567 | 1568 | [[package]] 1569 | name = "pyobjc-framework-metal" 1570 | version = "8.5" 1571 | description = "Wrappers for the framework Metal on macOS" 1572 | category = "main" 1573 | optional = false 1574 | python-versions = ">=3.6" 1575 | 1576 | [package.dependencies] 1577 | pyobjc-core = ">=8.5" 1578 | pyobjc-framework-Cocoa = ">=8.5" 1579 | 1580 | [[package]] 1581 | name = "pyobjc-framework-metalkit" 1582 | version = "8.5" 1583 | description = "Wrappers for the framework MetalKit on macOS" 1584 | category = "main" 1585 | optional = false 1586 | python-versions = ">=3.6" 1587 | 1588 | [package.dependencies] 1589 | pyobjc-core = ">=8.5" 1590 | pyobjc-framework-Cocoa = ">=8.5" 1591 | pyobjc-framework-Metal = ">=8.5" 1592 | 1593 | [[package]] 1594 | name = "pyobjc-framework-metalperformanceshaders" 1595 | version = "8.5" 1596 | description = "Wrappers for the framework MetalPerformanceShaders on macOS" 1597 | category = "main" 1598 | optional = false 1599 | python-versions = ">=3.6" 1600 | 1601 | [package.dependencies] 1602 | pyobjc-core = ">=8.5" 1603 | pyobjc-framework-Metal = ">=8.5" 1604 | 1605 | [[package]] 1606 | name = "pyobjc-framework-metalperformanceshadersgraph" 1607 | version = "8.5" 1608 | description = "Wrappers for the framework MetalPerformanceShadersGraph on macOS" 1609 | category = "main" 1610 | optional = false 1611 | python-versions = ">=3.6" 1612 | 1613 | [package.dependencies] 1614 | pyobjc-core = ">=8.5" 1615 | pyobjc-framework-MetalPerformanceShaders = ">=8.5" 1616 | 1617 | [[package]] 1618 | name = "pyobjc-framework-metrickit" 1619 | version = "8.5" 1620 | description = "Wrappers for the framework MetricKit on macOS" 1621 | category = "main" 1622 | optional = false 1623 | python-versions = ">=3.6" 1624 | 1625 | [package.dependencies] 1626 | pyobjc-core = ">=8.5" 1627 | pyobjc-framework-Cocoa = ">=8.5" 1628 | 1629 | [[package]] 1630 | name = "pyobjc-framework-mlcompute" 1631 | version = "8.5" 1632 | description = "Wrappers for the framework MLCompute on macOS" 1633 | category = "main" 1634 | optional = false 1635 | python-versions = ">=3.6" 1636 | 1637 | [package.dependencies] 1638 | pyobjc-core = ">=8.5" 1639 | pyobjc-framework-Cocoa = ">=8.5" 1640 | 1641 | [[package]] 1642 | name = "pyobjc-framework-modelio" 1643 | version = "8.5" 1644 | description = "Wrappers for the framework ModelIO on macOS" 1645 | category = "main" 1646 | optional = false 1647 | python-versions = ">=3.6" 1648 | 1649 | [package.dependencies] 1650 | pyobjc-core = ">=8.5" 1651 | pyobjc-framework-Cocoa = ">=8.5" 1652 | pyobjc-framework-Quartz = ">=8.5" 1653 | 1654 | [[package]] 1655 | name = "pyobjc-framework-multipeerconnectivity" 1656 | version = "8.5" 1657 | description = "Wrappers for the framework MultipeerConnectivity on macOS" 1658 | category = "main" 1659 | optional = false 1660 | python-versions = ">=3.6" 1661 | 1662 | [package.dependencies] 1663 | pyobjc-core = ">=8.5" 1664 | pyobjc-framework-Cocoa = ">=8.5" 1665 | 1666 | [[package]] 1667 | name = "pyobjc-framework-naturallanguage" 1668 | version = "8.5" 1669 | description = "Wrappers for the framework NaturalLanguage on macOS" 1670 | category = "main" 1671 | optional = false 1672 | python-versions = ">=3.6" 1673 | 1674 | [package.dependencies] 1675 | pyobjc-core = ">=8.5" 1676 | pyobjc-framework-Cocoa = ">=8.5" 1677 | 1678 | [[package]] 1679 | name = "pyobjc-framework-netfs" 1680 | version = "8.5" 1681 | description = "Wrappers for the framework NetFS on macOS" 1682 | category = "main" 1683 | optional = false 1684 | python-versions = ">=3.6" 1685 | 1686 | [package.dependencies] 1687 | pyobjc-core = ">=8.5" 1688 | pyobjc-framework-Cocoa = ">=8.5" 1689 | 1690 | [[package]] 1691 | name = "pyobjc-framework-network" 1692 | version = "8.5" 1693 | description = "Wrappers for the framework Network on macOS" 1694 | category = "main" 1695 | optional = false 1696 | python-versions = ">=3.6" 1697 | 1698 | [package.dependencies] 1699 | pyobjc-core = ">=8.5" 1700 | pyobjc-framework-Cocoa = ">=8.5" 1701 | 1702 | [[package]] 1703 | name = "pyobjc-framework-networkextension" 1704 | version = "8.5" 1705 | description = "Wrappers for the framework NetworkExtension on macOS" 1706 | category = "main" 1707 | optional = false 1708 | python-versions = ">=3.6" 1709 | 1710 | [package.dependencies] 1711 | pyobjc-core = ">=8.5" 1712 | pyobjc-framework-Cocoa = ">=8.5" 1713 | 1714 | [[package]] 1715 | name = "pyobjc-framework-notificationcenter" 1716 | version = "8.5" 1717 | description = "Wrappers for the framework NotificationCenter on macOS" 1718 | category = "main" 1719 | optional = false 1720 | python-versions = ">=3.6" 1721 | 1722 | [package.dependencies] 1723 | pyobjc-core = ">=8.5" 1724 | pyobjc-framework-Cocoa = ">=8.5" 1725 | 1726 | [[package]] 1727 | name = "pyobjc-framework-opendirectory" 1728 | version = "8.5" 1729 | description = "Wrappers for the framework OpenDirectory on macOS" 1730 | category = "main" 1731 | optional = false 1732 | python-versions = ">=3.6" 1733 | 1734 | [package.dependencies] 1735 | pyobjc-core = ">=8.5" 1736 | pyobjc-framework-Cocoa = ">=8.5" 1737 | 1738 | [[package]] 1739 | name = "pyobjc-framework-osakit" 1740 | version = "8.5" 1741 | description = "Wrappers for the framework OSAKit on macOS" 1742 | category = "main" 1743 | optional = false 1744 | python-versions = ">=3.6" 1745 | 1746 | [package.dependencies] 1747 | pyobjc-core = ">=8.5" 1748 | pyobjc-framework-Cocoa = ">=8.5" 1749 | 1750 | [[package]] 1751 | name = "pyobjc-framework-oslog" 1752 | version = "8.5" 1753 | description = "Wrappers for the framework OSLog on macOS" 1754 | category = "main" 1755 | optional = false 1756 | python-versions = ">=3.6" 1757 | 1758 | [package.dependencies] 1759 | pyobjc-core = ">=8.5" 1760 | pyobjc-framework-Cocoa = ">=8.5" 1761 | pyobjc-framework-CoreMedia = ">=8.5" 1762 | pyobjc-framework-Quartz = ">=8.5" 1763 | 1764 | [[package]] 1765 | name = "pyobjc-framework-passkit" 1766 | version = "8.5" 1767 | description = "Wrappers for the framework PassKit on macOS" 1768 | category = "main" 1769 | optional = false 1770 | python-versions = ">=3.6" 1771 | 1772 | [package.dependencies] 1773 | pyobjc-core = ">=8.5" 1774 | pyobjc-framework-Cocoa = ">=8.5" 1775 | 1776 | [[package]] 1777 | name = "pyobjc-framework-pencilkit" 1778 | version = "8.5" 1779 | description = "Wrappers for the framework PencilKit on macOS" 1780 | category = "main" 1781 | optional = false 1782 | python-versions = ">=3.6" 1783 | 1784 | [package.dependencies] 1785 | pyobjc-core = ">=8.5" 1786 | pyobjc-framework-Cocoa = ">=8.5" 1787 | 1788 | [[package]] 1789 | name = "pyobjc-framework-photos" 1790 | version = "8.5" 1791 | description = "Wrappers for the framework Photos on macOS" 1792 | category = "main" 1793 | optional = false 1794 | python-versions = ">=3.6" 1795 | 1796 | [package.dependencies] 1797 | pyobjc-core = ">=8.5" 1798 | pyobjc-framework-Cocoa = ">=8.5" 1799 | 1800 | [[package]] 1801 | name = "pyobjc-framework-photosui" 1802 | version = "8.5" 1803 | description = "Wrappers for the framework PhotosUI on macOS" 1804 | category = "main" 1805 | optional = false 1806 | python-versions = ">=3.6" 1807 | 1808 | [package.dependencies] 1809 | pyobjc-core = ">=8.5" 1810 | pyobjc-framework-Cocoa = ">=8.5" 1811 | 1812 | [[package]] 1813 | name = "pyobjc-framework-preferencepanes" 1814 | version = "8.5" 1815 | description = "Wrappers for the framework PreferencePanes on macOS" 1816 | category = "main" 1817 | optional = false 1818 | python-versions = ">=3.6" 1819 | 1820 | [package.dependencies] 1821 | pyobjc-core = ">=8.5" 1822 | pyobjc-framework-Cocoa = ">=8.5" 1823 | 1824 | [[package]] 1825 | name = "pyobjc-framework-pubsub" 1826 | version = "8.5" 1827 | description = "Wrappers for the framework PubSub on macOS" 1828 | category = "main" 1829 | optional = false 1830 | python-versions = ">=3.6" 1831 | 1832 | [package.dependencies] 1833 | pyobjc-core = ">=8.5" 1834 | pyobjc-framework-Cocoa = ">=8.5" 1835 | 1836 | [[package]] 1837 | name = "pyobjc-framework-pushkit" 1838 | version = "8.5" 1839 | description = "Wrappers for the framework PushKit on macOS" 1840 | category = "main" 1841 | optional = false 1842 | python-versions = ">=3.6" 1843 | 1844 | [package.dependencies] 1845 | pyobjc-core = ">=8.5" 1846 | pyobjc-framework-Cocoa = ">=8.5" 1847 | 1848 | [[package]] 1849 | name = "pyobjc-framework-quartz" 1850 | version = "8.5" 1851 | description = "Wrappers for the Quartz frameworks on macOS" 1852 | category = "main" 1853 | optional = false 1854 | python-versions = ">=3.6" 1855 | 1856 | [package.dependencies] 1857 | pyobjc-core = ">=8.5" 1858 | pyobjc-framework-Cocoa = ">=8.5" 1859 | 1860 | [[package]] 1861 | name = "pyobjc-framework-quicklookthumbnailing" 1862 | version = "8.5" 1863 | description = "Wrappers for the framework QuickLookThumbnailing on macOS" 1864 | category = "main" 1865 | optional = false 1866 | python-versions = ">=3.6" 1867 | 1868 | [package.dependencies] 1869 | pyobjc-core = ">=8.5" 1870 | pyobjc-framework-Cocoa = ">=8.5" 1871 | pyobjc-framework-Quartz = ">=8.5" 1872 | 1873 | [[package]] 1874 | name = "pyobjc-framework-replaykit" 1875 | version = "8.5" 1876 | description = "Wrappers for the framework ReplayKit on macOS" 1877 | category = "main" 1878 | optional = false 1879 | python-versions = ">=3.6" 1880 | 1881 | [package.dependencies] 1882 | pyobjc-core = ">=8.5" 1883 | pyobjc-framework-Cocoa = ">=8.5" 1884 | 1885 | [[package]] 1886 | name = "pyobjc-framework-safariservices" 1887 | version = "8.5" 1888 | description = "Wrappers for the framework SafariServices on macOS" 1889 | category = "main" 1890 | optional = false 1891 | python-versions = ">=3.6" 1892 | 1893 | [package.dependencies] 1894 | pyobjc-core = ">=8.5" 1895 | pyobjc-framework-Cocoa = ">=8.5" 1896 | 1897 | [[package]] 1898 | name = "pyobjc-framework-scenekit" 1899 | version = "8.5" 1900 | description = "Wrappers for the framework SceneKit on macOS" 1901 | category = "main" 1902 | optional = false 1903 | python-versions = ">=3.6" 1904 | 1905 | [package.dependencies] 1906 | pyobjc-core = ">=8.5" 1907 | pyobjc-framework-Cocoa = ">=8.5" 1908 | pyobjc-framework-Quartz = ">=8.5" 1909 | 1910 | [[package]] 1911 | name = "pyobjc-framework-screencapturekit" 1912 | version = "8.5" 1913 | description = "Wrappers for the framework ScreenCaptureKit on macOS" 1914 | category = "main" 1915 | optional = false 1916 | python-versions = ">=3.6" 1917 | 1918 | [package.dependencies] 1919 | pyobjc-core = ">=8.5" 1920 | pyobjc-framework-CoreMedia = ">=8.5" 1921 | 1922 | [[package]] 1923 | name = "pyobjc-framework-screensaver" 1924 | version = "8.5" 1925 | description = "Wrappers for the framework ScreenSaver on macOS" 1926 | category = "main" 1927 | optional = false 1928 | python-versions = ">=3.6" 1929 | 1930 | [package.dependencies] 1931 | pyobjc-core = ">=8.5" 1932 | pyobjc-framework-Cocoa = ">=8.5" 1933 | 1934 | [[package]] 1935 | name = "pyobjc-framework-screentime" 1936 | version = "8.5" 1937 | description = "Wrappers for the framework ScreenTime on macOS" 1938 | category = "main" 1939 | optional = false 1940 | python-versions = ">=3.6" 1941 | 1942 | [package.dependencies] 1943 | pyobjc-core = ">=8.5" 1944 | pyobjc-framework-Cocoa = ">=8.5" 1945 | 1946 | [[package]] 1947 | name = "pyobjc-framework-scriptingbridge" 1948 | version = "8.5" 1949 | description = "Wrappers for the framework ScriptingBridge on macOS" 1950 | category = "main" 1951 | optional = false 1952 | python-versions = ">=3.6" 1953 | 1954 | [package.dependencies] 1955 | pyobjc-core = ">=8.5" 1956 | pyobjc-framework-Cocoa = ">=8.5" 1957 | 1958 | [[package]] 1959 | name = "pyobjc-framework-searchkit" 1960 | version = "8.5" 1961 | description = "Wrappers for the framework SearchKit on macOS" 1962 | category = "main" 1963 | optional = false 1964 | python-versions = ">=3.6" 1965 | 1966 | [package.dependencies] 1967 | pyobjc-core = ">=8.5" 1968 | pyobjc-framework-CoreServices = ">=8.5" 1969 | 1970 | [[package]] 1971 | name = "pyobjc-framework-security" 1972 | version = "8.5" 1973 | description = "Wrappers for the framework Security on macOS" 1974 | category = "main" 1975 | optional = false 1976 | python-versions = ">=3.6" 1977 | 1978 | [package.dependencies] 1979 | pyobjc-core = ">=8.5" 1980 | pyobjc-framework-Cocoa = ">=8.5" 1981 | 1982 | [[package]] 1983 | name = "pyobjc-framework-securityfoundation" 1984 | version = "8.5" 1985 | description = "Wrappers for the framework SecurityFoundation on macOS" 1986 | category = "main" 1987 | optional = false 1988 | python-versions = ">=3.6" 1989 | 1990 | [package.dependencies] 1991 | pyobjc-core = ">=8.5" 1992 | pyobjc-framework-Cocoa = ">=8.5" 1993 | pyobjc-framework-Security = ">=8.5" 1994 | 1995 | [[package]] 1996 | name = "pyobjc-framework-securityinterface" 1997 | version = "8.5" 1998 | description = "Wrappers for the framework SecurityInterface on macOS" 1999 | category = "main" 2000 | optional = false 2001 | python-versions = ">=3.6" 2002 | 2003 | [package.dependencies] 2004 | pyobjc-core = ">=8.5" 2005 | pyobjc-framework-Cocoa = ">=8.5" 2006 | pyobjc-framework-Security = ">=8.5" 2007 | 2008 | [[package]] 2009 | name = "pyobjc-framework-servernotification" 2010 | version = "8.5" 2011 | description = "Wrappers for the framework ServerNotification on macOS" 2012 | category = "main" 2013 | optional = false 2014 | python-versions = ">=3.6" 2015 | 2016 | [package.dependencies] 2017 | pyobjc-core = ">=8.5" 2018 | pyobjc-framework-Cocoa = ">=8.5" 2019 | 2020 | [[package]] 2021 | name = "pyobjc-framework-servicemanagement" 2022 | version = "8.5" 2023 | description = "Wrappers for the framework ServiceManagement on macOS" 2024 | category = "main" 2025 | optional = false 2026 | python-versions = ">=3.6" 2027 | 2028 | [package.dependencies] 2029 | pyobjc-core = ">=8.5" 2030 | pyobjc-framework-Cocoa = ">=8.5" 2031 | 2032 | [[package]] 2033 | name = "pyobjc-framework-shazamkit" 2034 | version = "8.5" 2035 | description = "Wrappers for the framework ShazamKit on macOS" 2036 | category = "main" 2037 | optional = false 2038 | python-versions = ">=3.6" 2039 | 2040 | [package.dependencies] 2041 | pyobjc-core = ">=8.5" 2042 | pyobjc-framework-Cocoa = ">=8.5" 2043 | 2044 | [[package]] 2045 | name = "pyobjc-framework-social" 2046 | version = "8.5" 2047 | description = "Wrappers for the framework Social on macOS" 2048 | category = "main" 2049 | optional = false 2050 | python-versions = ">=3.6" 2051 | 2052 | [package.dependencies] 2053 | pyobjc-core = ">=8.5" 2054 | pyobjc-framework-Cocoa = ">=8.5" 2055 | 2056 | [[package]] 2057 | name = "pyobjc-framework-soundanalysis" 2058 | version = "8.5" 2059 | description = "Wrappers for the framework SoundAnalysis on macOS" 2060 | category = "main" 2061 | optional = false 2062 | python-versions = ">=3.6" 2063 | 2064 | [package.dependencies] 2065 | pyobjc-core = ">=8.5" 2066 | pyobjc-framework-Cocoa = ">=8.5" 2067 | 2068 | [[package]] 2069 | name = "pyobjc-framework-speech" 2070 | version = "8.5" 2071 | description = "Wrappers for the framework Speech on macOS" 2072 | category = "main" 2073 | optional = false 2074 | python-versions = ">=3.6" 2075 | 2076 | [package.dependencies] 2077 | pyobjc-core = ">=8.5" 2078 | pyobjc-framework-Cocoa = ">=8.5" 2079 | 2080 | [[package]] 2081 | name = "pyobjc-framework-spritekit" 2082 | version = "8.5" 2083 | description = "Wrappers for the framework SpriteKit on macOS" 2084 | category = "main" 2085 | optional = false 2086 | python-versions = ">=3.6" 2087 | 2088 | [package.dependencies] 2089 | pyobjc-core = ">=8.5" 2090 | pyobjc-framework-Cocoa = ">=8.5" 2091 | pyobjc-framework-Quartz = ">=8.5" 2092 | 2093 | [[package]] 2094 | name = "pyobjc-framework-storekit" 2095 | version = "8.5" 2096 | description = "Wrappers for the framework StoreKit on macOS" 2097 | category = "main" 2098 | optional = false 2099 | python-versions = ">=3.6" 2100 | 2101 | [package.dependencies] 2102 | pyobjc-core = ">=8.5" 2103 | pyobjc-framework-Cocoa = ">=8.5" 2104 | 2105 | [[package]] 2106 | name = "pyobjc-framework-syncservices" 2107 | version = "8.5" 2108 | description = "Wrappers for the framework SyncServices on macOS" 2109 | category = "main" 2110 | optional = false 2111 | python-versions = ">=3.6" 2112 | 2113 | [package.dependencies] 2114 | pyobjc-core = ">=8.5" 2115 | pyobjc-framework-Cocoa = ">=8.5" 2116 | pyobjc-framework-CoreData = ">=8.5" 2117 | 2118 | [[package]] 2119 | name = "pyobjc-framework-systemconfiguration" 2120 | version = "8.5" 2121 | description = "Wrappers for the framework SystemConfiguration on macOS" 2122 | category = "main" 2123 | optional = false 2124 | python-versions = ">=3.6" 2125 | 2126 | [package.dependencies] 2127 | pyobjc-core = ">=8.5" 2128 | pyobjc-framework-Cocoa = ">=8.5" 2129 | 2130 | [[package]] 2131 | name = "pyobjc-framework-systemextensions" 2132 | version = "8.5" 2133 | description = "Wrappers for the framework SystemExtensions on macOS" 2134 | category = "main" 2135 | optional = false 2136 | python-versions = ">=3.6" 2137 | 2138 | [package.dependencies] 2139 | pyobjc-core = ">=8.5" 2140 | pyobjc-framework-Cocoa = ">=8.5" 2141 | 2142 | [[package]] 2143 | name = "pyobjc-framework-uniformtypeidentifiers" 2144 | version = "8.5" 2145 | description = "Wrappers for the framework UniformTypeIdentifiers on macOS" 2146 | category = "main" 2147 | optional = false 2148 | python-versions = ">=3.6" 2149 | 2150 | [package.dependencies] 2151 | pyobjc-core = ">=8.5" 2152 | pyobjc-framework-Cocoa = ">=8.5" 2153 | 2154 | [[package]] 2155 | name = "pyobjc-framework-usernotifications" 2156 | version = "8.5" 2157 | description = "Wrappers for the framework UserNotifications on macOS" 2158 | category = "main" 2159 | optional = false 2160 | python-versions = ">=3.6" 2161 | 2162 | [package.dependencies] 2163 | pyobjc-core = ">=8.5" 2164 | pyobjc-framework-Cocoa = ">=8.5" 2165 | 2166 | [[package]] 2167 | name = "pyobjc-framework-usernotificationsui" 2168 | version = "8.5" 2169 | description = "Wrappers for the framework UserNotificationsUI on macOS" 2170 | category = "main" 2171 | optional = false 2172 | python-versions = ">=3.6" 2173 | 2174 | [package.dependencies] 2175 | pyobjc-core = ">=8.5" 2176 | pyobjc-framework-Cocoa = ">=8.5" 2177 | pyobjc-framework-UserNotifications = ">=8.5" 2178 | 2179 | [[package]] 2180 | name = "pyobjc-framework-videosubscriberaccount" 2181 | version = "8.5" 2182 | description = "Wrappers for the framework VideoSubscriberAccount on macOS" 2183 | category = "main" 2184 | optional = false 2185 | python-versions = ">=3.6" 2186 | 2187 | [package.dependencies] 2188 | pyobjc-core = ">=8.5" 2189 | pyobjc-framework-Cocoa = ">=8.5" 2190 | 2191 | [[package]] 2192 | name = "pyobjc-framework-videotoolbox" 2193 | version = "8.5" 2194 | description = "Wrappers for the framework VideoToolbox on macOS" 2195 | category = "main" 2196 | optional = false 2197 | python-versions = ">=3.6" 2198 | 2199 | [package.dependencies] 2200 | pyobjc-core = ">=8.5" 2201 | pyobjc-framework-Cocoa = ">=8.5" 2202 | pyobjc-framework-CoreMedia = ">=8.5" 2203 | pyobjc-framework-Quartz = ">=8.5" 2204 | 2205 | [[package]] 2206 | name = "pyobjc-framework-virtualization" 2207 | version = "8.5" 2208 | description = "Wrappers for the framework Virtualization on macOS" 2209 | category = "main" 2210 | optional = false 2211 | python-versions = ">=3.6" 2212 | 2213 | [package.dependencies] 2214 | pyobjc-core = ">=8.5" 2215 | pyobjc-framework-Cocoa = ">=8.5" 2216 | 2217 | [[package]] 2218 | name = "pyobjc-framework-vision" 2219 | version = "8.5" 2220 | description = "Wrappers for the framework Vision on macOS" 2221 | category = "main" 2222 | optional = false 2223 | python-versions = ">=3.6" 2224 | 2225 | [package.dependencies] 2226 | pyobjc-core = ">=8.5" 2227 | pyobjc-framework-Cocoa = ">=8.5" 2228 | pyobjc-framework-CoreML = ">=8.5" 2229 | pyobjc-framework-Quartz = ">=8.5" 2230 | 2231 | [[package]] 2232 | name = "pyobjc-framework-webkit" 2233 | version = "8.5" 2234 | description = "Wrappers for the framework WebKit on macOS" 2235 | category = "main" 2236 | optional = false 2237 | python-versions = ">=3.6" 2238 | 2239 | [package.dependencies] 2240 | pyobjc-core = ">=8.5" 2241 | pyobjc-framework-Cocoa = ">=8.5" 2242 | 2243 | [[package]] 2244 | name = "pyopenssl" 2245 | version = "22.0.0" 2246 | description = "Python wrapper module around the OpenSSL library" 2247 | category = "main" 2248 | optional = false 2249 | python-versions = ">=3.6" 2250 | 2251 | [package.dependencies] 2252 | cryptography = ">=35.0" 2253 | 2254 | [package.extras] 2255 | docs = ["sphinx", "sphinx-rtd-theme"] 2256 | test = ["flaky", "pretend", "pytest (>=3.0.1)"] 2257 | 2258 | [[package]] 2259 | name = "pyparsing" 2260 | version = "3.0.9" 2261 | description = "pyparsing module - Classes and methods to define and execute parsing grammars" 2262 | category = "main" 2263 | optional = false 2264 | python-versions = ">=3.6.8" 2265 | 2266 | [package.extras] 2267 | diagrams = ["railroad-diagrams", "jinja2"] 2268 | 2269 | [[package]] 2270 | name = "pyperclip" 2271 | version = "1.8.2" 2272 | description = "A cross-platform clipboard module for Python. (Only handles plain text for now.)" 2273 | category = "main" 2274 | optional = false 2275 | python-versions = "*" 2276 | 2277 | [[package]] 2278 | name = "pyrect" 2279 | version = "0.2.0" 2280 | description = "PyRect is a simple module with a Rect class for Pygame-like rectangular areas." 2281 | category = "main" 2282 | optional = false 2283 | python-versions = "*" 2284 | 2285 | [[package]] 2286 | name = "pyscreeze" 2287 | version = "0.1.28" 2288 | description = "A simple, cross-platform screenshot module for Python 2 and 3." 2289 | category = "main" 2290 | optional = false 2291 | python-versions = "*" 2292 | 2293 | [[package]] 2294 | name = "pysocks" 2295 | version = "1.7.1" 2296 | description = "A Python SOCKS client module. See https://github.com/Anorov/PySocks for more information." 2297 | category = "main" 2298 | optional = false 2299 | python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" 2300 | 2301 | [[package]] 2302 | name = "pytest" 2303 | version = "5.4.3" 2304 | description = "pytest: simple powerful testing with Python" 2305 | category = "dev" 2306 | optional = false 2307 | python-versions = ">=3.5" 2308 | 2309 | [package.dependencies] 2310 | atomicwrites = {version = ">=1.0", markers = "sys_platform == \"win32\""} 2311 | attrs = ">=17.4.0" 2312 | colorama = {version = "*", markers = "sys_platform == \"win32\""} 2313 | more-itertools = ">=4.0.0" 2314 | packaging = "*" 2315 | pluggy = ">=0.12,<1.0" 2316 | py = ">=1.5.0" 2317 | wcwidth = "*" 2318 | 2319 | [package.extras] 2320 | checkqa-mypy = ["mypy (==v0.761)"] 2321 | testing = ["argcomplete", "hypothesis (>=3.56)", "mock", "nose", "requests", "xmlschema"] 2322 | 2323 | [[package]] 2324 | name = "python-dotenv" 2325 | version = "0.20.0" 2326 | description = "Read key-value pairs from a .env file and set them as environment variables" 2327 | category = "main" 2328 | optional = false 2329 | python-versions = ">=3.5" 2330 | 2331 | [package.extras] 2332 | cli = ["click (>=5.0)"] 2333 | 2334 | [[package]] 2335 | name = "python3-xlib" 2336 | version = "0.15" 2337 | description = "Python3 X Library" 2338 | category = "main" 2339 | optional = false 2340 | python-versions = "*" 2341 | 2342 | [[package]] 2343 | name = "pytweening" 2344 | version = "1.0.4" 2345 | description = "A collection of tweening / easing functions." 2346 | category = "main" 2347 | optional = false 2348 | python-versions = "*" 2349 | 2350 | [[package]] 2351 | name = "requests" 2352 | version = "2.28.1" 2353 | description = "Python HTTP for Humans." 2354 | category = "main" 2355 | optional = false 2356 | python-versions = ">=3.7, <4" 2357 | 2358 | [package.dependencies] 2359 | certifi = ">=2017.4.17" 2360 | charset-normalizer = ">=2,<3" 2361 | idna = ">=2.5,<4" 2362 | urllib3 = ">=1.21.1,<1.27" 2363 | 2364 | [package.extras] 2365 | socks = ["PySocks (>=1.5.6,!=1.5.7)"] 2366 | use_chardet_on_py3 = ["chardet (>=3.0.2,<6)"] 2367 | 2368 | [[package]] 2369 | name = "rsa" 2370 | version = "4.8" 2371 | description = "Pure-Python RSA implementation" 2372 | category = "main" 2373 | optional = false 2374 | python-versions = ">=3.6,<4" 2375 | 2376 | [package.dependencies] 2377 | pyasn1 = ">=0.1.3" 2378 | 2379 | [[package]] 2380 | name = "rubicon-objc" 2381 | version = "0.4.2" 2382 | description = "A bridge between an Objective C runtime environment and Python." 2383 | category = "main" 2384 | optional = false 2385 | python-versions = ">=3.5" 2386 | 2387 | [[package]] 2388 | name = "selenium" 2389 | version = "4.3.0" 2390 | description = "" 2391 | category = "main" 2392 | optional = false 2393 | python-versions = "~=3.7" 2394 | 2395 | [package.dependencies] 2396 | trio = ">=0.17,<1.0" 2397 | trio-websocket = ">=0.9,<1.0" 2398 | urllib3 = {version = ">=1.26,<2.0", extras = ["secure", "socks"]} 2399 | 2400 | [[package]] 2401 | name = "six" 2402 | version = "1.16.0" 2403 | description = "Python 2 and 3 compatibility utilities" 2404 | category = "main" 2405 | optional = false 2406 | python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" 2407 | 2408 | [[package]] 2409 | name = "sniffio" 2410 | version = "1.2.0" 2411 | description = "Sniff out which async library your code is running under" 2412 | category = "main" 2413 | optional = false 2414 | python-versions = ">=3.5" 2415 | 2416 | [[package]] 2417 | name = "sortedcontainers" 2418 | version = "2.4.0" 2419 | description = "Sorted Containers -- Sorted List, Sorted Dict, Sorted Set" 2420 | category = "main" 2421 | optional = false 2422 | python-versions = "*" 2423 | 2424 | [[package]] 2425 | name = "toml" 2426 | version = "0.10.2" 2427 | description = "Python Library for Tom's Obvious, Minimal Language" 2428 | category = "dev" 2429 | optional = false 2430 | python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" 2431 | 2432 | [[package]] 2433 | name = "trio" 2434 | version = "0.21.0" 2435 | description = "A friendly Python library for async concurrency and I/O" 2436 | category = "main" 2437 | optional = false 2438 | python-versions = ">=3.7" 2439 | 2440 | [package.dependencies] 2441 | async-generator = ">=1.9" 2442 | attrs = ">=19.2.0" 2443 | cffi = {version = ">=1.14", markers = "os_name == \"nt\" and implementation_name != \"pypy\""} 2444 | idna = "*" 2445 | outcome = "*" 2446 | sniffio = "*" 2447 | sortedcontainers = "*" 2448 | 2449 | [[package]] 2450 | name = "trio-websocket" 2451 | version = "0.9.2" 2452 | description = "WebSocket library for Trio" 2453 | category = "main" 2454 | optional = false 2455 | python-versions = ">=3.5" 2456 | 2457 | [package.dependencies] 2458 | async-generator = ">=1.10" 2459 | trio = ">=0.11" 2460 | wsproto = ">=0.14" 2461 | 2462 | [[package]] 2463 | name = "uritemplate" 2464 | version = "4.1.1" 2465 | description = "Implementation of RFC 6570 URI Templates" 2466 | category = "main" 2467 | optional = false 2468 | python-versions = ">=3.6" 2469 | 2470 | [[package]] 2471 | name = "urllib3" 2472 | version = "1.26.9" 2473 | description = "HTTP library with thread-safe connection pooling, file post, and more." 2474 | category = "main" 2475 | optional = false 2476 | python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, <4" 2477 | 2478 | [package.dependencies] 2479 | certifi = {version = "*", optional = true, markers = "extra == \"secure\""} 2480 | cryptography = {version = ">=1.3.4", optional = true, markers = "extra == \"secure\""} 2481 | idna = {version = ">=2.0.0", optional = true, markers = "extra == \"secure\""} 2482 | pyOpenSSL = {version = ">=0.14", optional = true, markers = "extra == \"secure\""} 2483 | PySocks = {version = ">=1.5.6,<1.5.7 || >1.5.7,<2.0", optional = true, markers = "extra == \"socks\""} 2484 | 2485 | [package.extras] 2486 | brotli = ["brotlicffi (>=0.8.0)", "brotli (>=1.0.9)", "brotlipy (>=0.6.0)"] 2487 | secure = ["pyOpenSSL (>=0.14)", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "certifi", "ipaddress"] 2488 | socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"] 2489 | 2490 | [[package]] 2491 | name = "wcwidth" 2492 | version = "0.2.5" 2493 | description = "Measures the displayed width of unicode strings in a terminal" 2494 | category = "dev" 2495 | optional = false 2496 | python-versions = "*" 2497 | 2498 | [[package]] 2499 | name = "webdriver-manager" 2500 | version = "3.7.1" 2501 | description = "Library provides the way to automatically manage drivers for different browsers" 2502 | category = "main" 2503 | optional = false 2504 | python-versions = ">=3.6" 2505 | 2506 | [package.dependencies] 2507 | python-dotenv = "*" 2508 | requests = "*" 2509 | 2510 | [[package]] 2511 | name = "wsproto" 2512 | version = "1.1.0" 2513 | description = "WebSockets state-machine based protocol implementation" 2514 | category = "main" 2515 | optional = false 2516 | python-versions = ">=3.7.0" 2517 | 2518 | [package.dependencies] 2519 | h11 = ">=0.9.0,<1" 2520 | 2521 | [metadata] 2522 | lock-version = "1.1" 2523 | python-versions = "^3.9" 2524 | content-hash = "0575cb3b43e80d5e62804d663ab6719d2b668dbfad199e741eb6476043b444e4" 2525 | 2526 | [metadata.files] 2527 | async-generator = [] 2528 | atomicwrites = [] 2529 | attrs = [] 2530 | autopep8 = [] 2531 | cachetools = [] 2532 | certifi = [] 2533 | cffi = [] 2534 | charset-normalizer = [] 2535 | colorama = [] 2536 | cryptography = [] 2537 | google-api-core = [] 2538 | google-api-python-client = [] 2539 | google-auth = [] 2540 | google-auth-httplib2 = [] 2541 | googleapis-common-protos = [] 2542 | h11 = [] 2543 | httplib2 = [] 2544 | idna = [] 2545 | more-itertools = [] 2546 | mouseinfo = [] 2547 | oauth2client = [] 2548 | outcome = [] 2549 | packaging = [] 2550 | pluggy = [] 2551 | protobuf = [] 2552 | py = [] 2553 | pyasn1 = [] 2554 | pyasn1-modules = [] 2555 | pyautogui = [] 2556 | pycodestyle = [] 2557 | pycparser = [] 2558 | pydirectinput = [] 2559 | pygetwindow = [] 2560 | pymsgbox = [] 2561 | pyobjc = [] 2562 | pyobjc-core = [] 2563 | pyobjc-framework-accessibility = [] 2564 | pyobjc-framework-accounts = [] 2565 | pyobjc-framework-addressbook = [] 2566 | pyobjc-framework-adservices = [] 2567 | pyobjc-framework-adsupport = [] 2568 | pyobjc-framework-applescriptkit = [] 2569 | pyobjc-framework-applescriptobjc = [] 2570 | pyobjc-framework-applicationservices = [] 2571 | pyobjc-framework-apptrackingtransparency = [] 2572 | pyobjc-framework-audiovideobridging = [] 2573 | pyobjc-framework-authenticationservices = [] 2574 | pyobjc-framework-automaticassessmentconfiguration = [] 2575 | pyobjc-framework-automator = [] 2576 | pyobjc-framework-avfoundation = [] 2577 | pyobjc-framework-avkit = [] 2578 | pyobjc-framework-businesschat = [] 2579 | pyobjc-framework-calendarstore = [] 2580 | pyobjc-framework-callkit = [] 2581 | pyobjc-framework-cfnetwork = [] 2582 | pyobjc-framework-classkit = [] 2583 | pyobjc-framework-cloudkit = [] 2584 | pyobjc-framework-cocoa = [] 2585 | pyobjc-framework-collaboration = [] 2586 | pyobjc-framework-colorsync = [] 2587 | pyobjc-framework-contacts = [] 2588 | pyobjc-framework-contactsui = [] 2589 | pyobjc-framework-coreaudio = [] 2590 | pyobjc-framework-coreaudiokit = [] 2591 | pyobjc-framework-corebluetooth = [] 2592 | pyobjc-framework-coredata = [] 2593 | pyobjc-framework-corehaptics = [] 2594 | pyobjc-framework-corelocation = [] 2595 | pyobjc-framework-coremedia = [] 2596 | pyobjc-framework-coremediaio = [] 2597 | pyobjc-framework-coremidi = [] 2598 | pyobjc-framework-coreml = [] 2599 | pyobjc-framework-coremotion = [] 2600 | pyobjc-framework-coreservices = [] 2601 | pyobjc-framework-corespotlight = [] 2602 | pyobjc-framework-coretext = [] 2603 | pyobjc-framework-corewlan = [] 2604 | pyobjc-framework-cryptotokenkit = [] 2605 | pyobjc-framework-datadetection = [] 2606 | pyobjc-framework-devicecheck = [] 2607 | pyobjc-framework-dictionaryservices = [] 2608 | pyobjc-framework-discrecording = [] 2609 | pyobjc-framework-discrecordingui = [] 2610 | pyobjc-framework-diskarbitration = [] 2611 | pyobjc-framework-dvdplayback = [] 2612 | pyobjc-framework-eventkit = [] 2613 | pyobjc-framework-exceptionhandling = [] 2614 | pyobjc-framework-executionpolicy = [] 2615 | pyobjc-framework-externalaccessory = [] 2616 | pyobjc-framework-fileprovider = [] 2617 | pyobjc-framework-fileproviderui = [] 2618 | pyobjc-framework-findersync = [] 2619 | pyobjc-framework-fsevents = [] 2620 | pyobjc-framework-gamecenter = [] 2621 | pyobjc-framework-gamecontroller = [] 2622 | pyobjc-framework-gamekit = [] 2623 | pyobjc-framework-gameplaykit = [] 2624 | pyobjc-framework-imagecapturecore = [] 2625 | pyobjc-framework-imserviceplugin = [] 2626 | pyobjc-framework-inputmethodkit = [] 2627 | pyobjc-framework-installerplugins = [] 2628 | pyobjc-framework-instantmessage = [] 2629 | pyobjc-framework-intents = [] 2630 | pyobjc-framework-intentsui = [] 2631 | pyobjc-framework-iosurface = [] 2632 | pyobjc-framework-ituneslibrary = [] 2633 | pyobjc-framework-kernelmanagement = [] 2634 | pyobjc-framework-latentsemanticmapping = [] 2635 | pyobjc-framework-launchservices = [] 2636 | pyobjc-framework-libdispatch = [] 2637 | pyobjc-framework-linkpresentation = [] 2638 | pyobjc-framework-localauthentication = [] 2639 | pyobjc-framework-localauthenticationembeddedui = [] 2640 | pyobjc-framework-mailkit = [] 2641 | pyobjc-framework-mapkit = [] 2642 | pyobjc-framework-mediaaccessibility = [] 2643 | pyobjc-framework-medialibrary = [] 2644 | pyobjc-framework-mediaplayer = [] 2645 | pyobjc-framework-mediatoolbox = [] 2646 | pyobjc-framework-message = [] 2647 | pyobjc-framework-metal = [] 2648 | pyobjc-framework-metalkit = [] 2649 | pyobjc-framework-metalperformanceshaders = [] 2650 | pyobjc-framework-metalperformanceshadersgraph = [] 2651 | pyobjc-framework-metrickit = [] 2652 | pyobjc-framework-mlcompute = [] 2653 | pyobjc-framework-modelio = [] 2654 | pyobjc-framework-multipeerconnectivity = [] 2655 | pyobjc-framework-naturallanguage = [] 2656 | pyobjc-framework-netfs = [] 2657 | pyobjc-framework-network = [] 2658 | pyobjc-framework-networkextension = [] 2659 | pyobjc-framework-notificationcenter = [] 2660 | pyobjc-framework-opendirectory = [] 2661 | pyobjc-framework-osakit = [] 2662 | pyobjc-framework-oslog = [] 2663 | pyobjc-framework-passkit = [] 2664 | pyobjc-framework-pencilkit = [] 2665 | pyobjc-framework-photos = [] 2666 | pyobjc-framework-photosui = [] 2667 | pyobjc-framework-preferencepanes = [] 2668 | pyobjc-framework-pubsub = [] 2669 | pyobjc-framework-pushkit = [] 2670 | pyobjc-framework-quartz = [] 2671 | pyobjc-framework-quicklookthumbnailing = [] 2672 | pyobjc-framework-replaykit = [] 2673 | pyobjc-framework-safariservices = [] 2674 | pyobjc-framework-scenekit = [] 2675 | pyobjc-framework-screencapturekit = [] 2676 | pyobjc-framework-screensaver = [] 2677 | pyobjc-framework-screentime = [] 2678 | pyobjc-framework-scriptingbridge = [] 2679 | pyobjc-framework-searchkit = [] 2680 | pyobjc-framework-security = [] 2681 | pyobjc-framework-securityfoundation = [] 2682 | pyobjc-framework-securityinterface = [] 2683 | pyobjc-framework-servernotification = [] 2684 | pyobjc-framework-servicemanagement = [] 2685 | pyobjc-framework-shazamkit = [] 2686 | pyobjc-framework-social = [] 2687 | pyobjc-framework-soundanalysis = [] 2688 | pyobjc-framework-speech = [] 2689 | pyobjc-framework-spritekit = [] 2690 | pyobjc-framework-storekit = [] 2691 | pyobjc-framework-syncservices = [] 2692 | pyobjc-framework-systemconfiguration = [] 2693 | pyobjc-framework-systemextensions = [] 2694 | pyobjc-framework-uniformtypeidentifiers = [] 2695 | pyobjc-framework-usernotifications = [] 2696 | pyobjc-framework-usernotificationsui = [] 2697 | pyobjc-framework-videosubscriberaccount = [] 2698 | pyobjc-framework-videotoolbox = [] 2699 | pyobjc-framework-virtualization = [] 2700 | pyobjc-framework-vision = [] 2701 | pyobjc-framework-webkit = [] 2702 | pyopenssl = [] 2703 | pyparsing = [] 2704 | pyperclip = [] 2705 | pyrect = [] 2706 | pyscreeze = [] 2707 | pysocks = [] 2708 | pytest = [] 2709 | python-dotenv = [] 2710 | python3-xlib = [] 2711 | pytweening = [] 2712 | requests = [] 2713 | rsa = [] 2714 | rubicon-objc = [] 2715 | selenium = [] 2716 | six = [] 2717 | sniffio = [] 2718 | sortedcontainers = [] 2719 | toml = [] 2720 | trio = [] 2721 | trio-websocket = [] 2722 | uritemplate = [] 2723 | urllib3 = [] 2724 | wcwidth = [] 2725 | webdriver-manager = [] 2726 | wsproto = [] 2727 | --------------------------------------------------------------------------------