├── .circleci
└── config.yml
├── .flake8
├── .gitattributes
├── .gitignore
├── .pre-commit-config.yaml
├── LICENSE
├── README.md
├── cmus_osx
├── __init__.py
├── constants.py
├── env.py
├── payload
│ ├── media_keys.py
│ └── notify.py
├── resource
│ └── icon.png
└── util.py
├── poetry.lock
└── pyproject.toml
/.circleci/config.yml:
--------------------------------------------------------------------------------
1 | version: 2
2 | jobs:
3 | build:
4 | docker:
5 | - image: circleci/python:3.7.5
6 | environment:
7 | POETRY_VERSION: 1.0.0b9
8 | steps:
9 | - checkout
10 | - run:
11 | command: |
12 | sudo chown -R circleci:circleci /usr/local/bin
13 | sudo chown -R circleci:circleci /usr/local/lib/python3.7/site-packages
14 | - run:
15 | name: Setup
16 | command: |
17 | sudo pip install poetry==${POETRY_VERSION}
18 | sudo pip install pre-commit
19 | mkdir -p /home/circleci/.config/pypoetry/
20 | echo "[repositories]" > /home/circleci/.config/pypoetry/config.toml
21 | poetry config virtualenvs.create false
22 | pre-commit install-hooks
23 | - run:
24 | name: Lint
25 | command: pre-commit run --all-files
26 | - run:
27 | name: Build
28 | command: |
29 | poetry build
30 | - store_artifacts:
31 | path: dist
32 |
--------------------------------------------------------------------------------
/.flake8:
--------------------------------------------------------------------------------
1 | [flake8]
2 | ignore = E501,W503,E203,E402
3 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | *.png filter=lfs diff=lfs merge=lfs -text
2 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 |
2 | # Byte-compiled / optimized / DLL files
3 | __pycache__/
4 | *.py[cod]
5 | *$py.class
6 |
7 | # C extensions
8 | *.so
9 |
10 | # Distribution / packaging
11 | .Python
12 | env/
13 | build/
14 | develop-eggs/
15 | dist/
16 | downloads/
17 | eggs/
18 | .eggs/
19 | lib/
20 | lib64/
21 | parts/
22 | sdist/
23 | var/
24 | wheels/
25 | *.egg-info/
26 | .installed.cfg
27 | *.egg
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 | .coverage
43 | .coverage.*
44 | .cache
45 | nosetests.xml
46 | coverage.xml
47 | *,cover
48 | .hypothesis/
49 |
50 | # Translations
51 | *.mo
52 | *.pot
53 |
54 | # Django stuff:
55 | *.log
56 | local_settings.py
57 |
58 | # Flask stuff:
59 | instance/
60 | .webassets-cache
61 |
62 | # Scrapy stuff:
63 | .scrapy
64 |
65 | # Sphinx documentation
66 | docs/_build/
67 |
68 | # PyBuilder
69 | target/
70 |
71 | # Jupyter Notebook
72 | .ipynb_checkpoints
73 |
74 | # pyenv
75 | .python-version
76 |
77 | # celery beat schedule file
78 | celerybeat-schedule
79 |
80 | # dotenv
81 | .env
82 |
83 | # virtualenv
84 | .venv/
85 | venv/
86 | ENV/
87 |
88 | # Spyder project settings
89 | .spyderproject
90 |
91 | # Rope project settings
92 | .ropeproject
93 |
94 | .mypy_cache
--------------------------------------------------------------------------------
/.pre-commit-config.yaml:
--------------------------------------------------------------------------------
1 | repos:
2 | - repo: https://github.com/ambv/black
3 | rev: 18.9b0
4 | hooks:
5 | - id: black
6 | - repo: https://github.com/asottile/blacken-docs
7 | rev: v0.3.0
8 | hooks:
9 | - id: blacken-docs
10 | additional_dependencies: [black==18.9b0]
11 | - repo: https://github.com/pre-commit/pre-commit-hooks
12 | rev: v2.1.0
13 | hooks:
14 | - id: trailing-whitespace
15 | args: [--markdown-linebreak-ext=md]
16 | - id: check-ast
17 | - id: check-added-large-files
18 | - repo: https://github.com/asottile/reorder_python_imports
19 | rev: v1.3.4
20 | hooks:
21 | - id: reorder-python-imports
22 | - repo: https://gitlab.com/pycqa/flake8
23 | rev: '3.7.6'
24 | hooks:
25 | - id: flake8
26 | - repo: https://github.com/pre-commit/mirrors-mypy
27 | rev: 'v0.670'
28 | hooks:
29 | - id: mypy
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2019 Philip Trauner
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy of
6 | this software and associated documentation files (the "Software"), to deal in
7 | the Software without restriction, including without limitation the rights to
8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9 | the Software, and to permit persons to whom the Software is furnished to do so,
10 | 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, FITNESS
17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | ▶ cmus-osx
6 |
7 | 
8 | [](https://badge.fury.io/py/cmus-osx)
9 | 
10 | [](https://circleci.com/gh/PhilipTrauner/cmus-osx)
11 |
12 | **cmus-osx** adds track change notifications, and media key support to [*cmus*](https://cmus.github.io/) (*macOS* only).
13 |
14 | ## Installation
15 | macOS automatically launches iTunes on media key presses.
16 | Installing [noTunes](https://github.com/tombonez/noTunes/releases/tag/v2.0) is the recommended solution to prevent this from happening.
17 |
18 | ```bash
19 | pip3 install cmus-osx
20 | cmus-osx install
21 | ```
22 |
23 | **cmus-osx** supports virtual environments natively, so installing it via `pipx` (or basically any other virtual environment manager) works just as well.
24 |
25 | ### Uninstall
26 | ```
27 | cmus-osx uninstall
28 | pip3 uninstall cmus-osx
29 | ```
30 |
31 | #### pyenv
32 | Framework building has to be enabled, otherwise notifications cannot be created.
33 | ```bash
34 | export PYTHON_CONFIGURE_OPTS="--enable-framework"
35 | ```
36 |
37 | ## Configuration
38 | ```
39 | cmus-osx config
40 | ```
41 |
42 | ### Credits
43 | * [azadkuh](https://github.com/azadkuh): all versions up to and including v1.2.0
44 | * [PhilipTrauner](https://github.com/PhilipTrauner): all following versions
45 |
--------------------------------------------------------------------------------
/cmus_osx/__init__.py:
--------------------------------------------------------------------------------
1 | from dataclasses import dataclass
2 | from os import chmod
3 | from os import kill
4 | from os import remove
5 | from os import rename
6 | from pathlib import Path
7 | from shutil import rmtree
8 | from signal import SIGTERM
9 | from subprocess import call
10 | from tempfile import NamedTemporaryFile
11 | from typing import Optional
12 |
13 | import click
14 | from click import echo
15 | from click import style
16 |
17 | from .constants import AUTOSAVE_MISSING
18 | from .constants import CMUS_OSX_FOLDER_NAME
19 | from .constants import CONFIG_NAME
20 | from .constants import COULD_NOT_LOCATED_CMUS_DIRECTORY
21 | from .constants import ENV
22 | from .constants import ENV_VAR_PREFIX
23 | from .constants import RC_ENTRY_REGEX
24 | from .constants import RC_SCRIPT_NAME
25 | from .constants import SCRIPTS
26 | from .constants import SDP_SCRIPT_NAME
27 | from .constants import STATUS_DISPLAY_PROGRAM_REGEX
28 | from .env import template
29 | from .util import get_cmus_instances
30 | from .util import locate_cmus_base_path
31 | from .util import locate_editor
32 | from .util import unexpanduser
33 |
34 |
35 | class CmusConfig:
36 | @dataclass
37 | class _CmusConfig:
38 | base_path: Path
39 | # File that holds cmus commands that are executed on startup
40 | rc_path: Path
41 | # cmus config file
42 | autosave_path: Path
43 |
44 | def __new__(self) -> Optional["CmusConfig._CmusConfig"]: # type: ignore
45 | base_path = locate_cmus_base_path()
46 | if base_path is not None:
47 | return CmusConfig._CmusConfig(
48 | base_path, base_path / "rc", base_path / "autosave"
49 | )
50 | else:
51 | return None
52 |
53 |
54 | @click.group()
55 | @click.pass_context
56 | def entrypoint(ctx):
57 | # Entrypoint is called directly
58 | ctx.ensure_object(dict)
59 |
60 | cmus_config = CmusConfig()
61 |
62 | if cmus_config is not None:
63 | cmus_osx_base_path = cmus_config.base_path / CMUS_OSX_FOLDER_NAME
64 | cmus_osx_base_path.mkdir(exist_ok=True)
65 |
66 | config_path = cmus_osx_base_path / CONFIG_NAME
67 | if not config_path.is_file():
68 | with open(config_path, "w") as f:
69 | f.write(template(ENV_VAR_PREFIX, ENV))
70 |
71 | if not cmus_config.rc_path.is_file():
72 | cmus_config.rc_path.touch()
73 |
74 | if not cmus_config.autosave_path.is_file():
75 | echo(
76 | f"{style('ERROR', fg='red')}: cmus config file missing (launch cmus at least once "
77 | "before attempting installation)"
78 | )
79 | exit(AUTOSAVE_MISSING)
80 |
81 | rc_script_path = cmus_config.base_path / CMUS_OSX_FOLDER_NAME / RC_SCRIPT_NAME
82 | sdp_script_path = cmus_config.base_path / CMUS_OSX_FOLDER_NAME / SDP_SCRIPT_NAME
83 |
84 | locals_ = locals()
85 | for local in (local for local in locals_ if local != "ctx"):
86 | ctx.obj[local] = locals_[local]
87 | else:
88 | echo(f"{style('ERROR', fg='red')}: Could not locate cmus config directory")
89 |
90 | exit(COULD_NOT_LOCATED_CMUS_DIRECTORY)
91 |
92 |
93 | @entrypoint.command()
94 | @click.option("-f", "--force", is_flag=True)
95 | @click.pass_context
96 | def install(ctx, force):
97 | cmus_config = ctx.obj["cmus_config"]
98 | cmus_osx_base_path = ctx.obj["cmus_osx_base_path"]
99 | rc_script_path = ctx.obj["rc_script_path"]
100 | sdp_script_path = ctx.obj["sdp_script_path"]
101 |
102 | cmus_osx_base_path.mkdir(exist_ok=True)
103 |
104 | for script_name in SCRIPTS:
105 | script_path = cmus_osx_base_path / script_name
106 | with open(script_path, "w") as f:
107 | f.write(f"{SCRIPTS[script_name]}\n")
108 | chmod(script_path, 0o744)
109 |
110 | write_rc = True
111 |
112 | unexpanded_rc_script_path = unexpanduser(rc_script_path)
113 |
114 | tmp_rc_file = NamedTemporaryFile("w", delete=False)
115 | with open(cmus_config.rc_path, "r") as f:
116 | for line in f:
117 | match = RC_ENTRY_REGEX.match(line)
118 | # Found invocation of 'rc' script
119 | if match is not None and Path(match.group(1)) in (
120 | rc_script_path,
121 | unexpanded_rc_script_path,
122 | ):
123 | write_rc = False
124 | tmp_rc_file.write(line)
125 |
126 | if write_rc:
127 | tmp_rc_file.write(f"shell {str(unexpanded_rc_script_path)} &\n")
128 | rename(tmp_rc_file.name, cmus_config.rc_path)
129 | else:
130 | remove(tmp_rc_file.name)
131 |
132 | write_autosave = False
133 |
134 | unexpand_sdp_script_path = unexpanduser(sdp_script_path)
135 |
136 | tmp_autosave_file = NamedTemporaryFile("w", delete=False)
137 | with open(cmus_config.autosave_path, "r") as f:
138 | for line in f:
139 | match = STATUS_DISPLAY_PROGRAM_REGEX.match(line)
140 | if match is not None:
141 | sdp_value = match.group(1)
142 | # 'status_display_program' is not set
143 | if sdp_value == "":
144 | # Write 'status_display_program' without asking for permission
145 | write_autosave = True
146 | elif Path(sdp_value) not in (sdp_script_path, unexpand_sdp_script_path):
147 | # Ask for permission
148 | if force or click.confirm(
149 | f"{style('WARNING', fg='yellow')}: "
150 | f"'status_display_program' currently set to '{sdp_value}', "
151 | "override?"
152 | ):
153 | write_autosave = True
154 | else:
155 | echo(
156 | f"{style('WARNING', fg='yellow')}: Manually set "
157 | "'status_display_program' to "
158 | f"'{str(unexpand_sdp_script_path)}'"
159 | )
160 | if write_autosave:
161 | tmp_autosave_file.write(
162 | f"set status_display_program={str(unexpand_sdp_script_path)}\n"
163 | )
164 | else:
165 | tmp_autosave_file.write(line)
166 |
167 | # No need to replace 'autosave' if no changes were written
168 | if write_autosave:
169 | rename(tmp_autosave_file.name, cmus_config.autosave_path)
170 | else:
171 | remove(tmp_autosave_file.name)
172 |
173 | if not write_rc and not write_autosave:
174 | echo(f"{style('NOTE', fg='magenta')}: Already installed.")
175 | else:
176 | echo(f"{style('SUCCESS', fg='green')}: Successfully installed.")
177 |
178 |
179 | @entrypoint.command()
180 | @click.pass_context
181 | def uninstall(ctx):
182 | cmus_config = ctx.obj["cmus_config"]
183 | cmus_osx_base_path = ctx.obj["cmus_osx_base_path"]
184 | rc_script_path = ctx.obj["rc_script_path"]
185 | sdp_script_path = ctx.obj["sdp_script_path"]
186 |
187 | try:
188 | rmtree(cmus_osx_base_path)
189 | except FileNotFoundError:
190 | pass
191 |
192 | cmus_instances = get_cmus_instances()
193 |
194 | if cmus_instances is not None:
195 | for pid in cmus_instances:
196 | kill(pid, SIGTERM)
197 |
198 | write_rc = False
199 |
200 | tmp_rc_file = NamedTemporaryFile("w", delete=False)
201 | with open(cmus_config.rc_path, "r") as f:
202 | for line in f:
203 | match = RC_ENTRY_REGEX.match(line)
204 | # Exclude invocations of 'rc' script
205 | if not (match is not None and Path(match.group(1)) == rc_script_path):
206 | tmp_rc_file.write(line)
207 | else:
208 | write_rc = True
209 |
210 | if write_rc:
211 | rename(tmp_rc_file.name, cmus_config.rc_path)
212 | else:
213 | remove(tmp_rc_file.name)
214 |
215 | write_autosave = False
216 |
217 | tmp_autosave_file = NamedTemporaryFile("w", delete=False)
218 | with open(cmus_config.autosave_path, "r") as f:
219 | for line in f:
220 | match = STATUS_DISPLAY_PROGRAM_REGEX.match(line)
221 | # Exclude invocations of 'status_display_program' script
222 | if not (match is not None and Path(match.group(1)) == sdp_script_path):
223 | tmp_autosave_file.write(line)
224 | else:
225 | tmp_autosave_file.write("set status_display_program=\n")
226 | write_autosave = True
227 |
228 | # No need to replace 'autosave' if no changes were written
229 | if write_autosave:
230 | rename(tmp_autosave_file.name, cmus_config.autosave_path)
231 | else:
232 | remove(tmp_autosave_file.name)
233 |
234 | if not write_rc and not write_autosave:
235 | echo(f"{style('NOTE', fg='magenta')}: Already uninstalled.")
236 | else:
237 | echo(f"{style('SUCCESS', fg='green')}: Successfully uninstalled.")
238 |
239 |
240 | @entrypoint.command()
241 | @click.pass_context
242 | def config(ctx):
243 | cmus_osx_base_path = ctx.obj["cmus_osx_base_path"]
244 |
245 | config_path = cmus_osx_base_path / CONFIG_NAME
246 |
247 | editor = locate_editor()
248 |
249 | if editor is None:
250 | echo(
251 | f"{style('ERROR', fg='red')}: Could not locate editor, "
252 | f"manually edit '{str(config_path)}'"
253 | )
254 | else:
255 | call([str(editor), str(config_path)])
256 |
--------------------------------------------------------------------------------
/cmus_osx/constants.py:
--------------------------------------------------------------------------------
1 | from pathlib import Path
2 | from re import compile as re_compile
3 | from sys import executable
4 | from sys import modules
5 | from typing import Dict
6 |
7 | from .env import Default
8 | from .util import unexpanduser
9 |
10 | STATUS_DISPLAY_PROGRAM_REGEX = re_compile(r"set status_display_program=(.*)")
11 | RC_ENTRY_REGEX = re_compile(r"shell\s(.*)\s&")
12 |
13 | INTERPRETER_PATH = unexpanduser(Path(executable))
14 | MODULE_BASE_PATH = Path(modules[__name__].__file__).parent
15 |
16 | RESOURCE_PATH = MODULE_BASE_PATH / "resource"
17 | PAYLOAD_PATH = MODULE_BASE_PATH / "payload"
18 |
19 | APP_ICON_NAME = "icon.png"
20 | RC_SCRIPT_NAME = "rc_entry.sh"
21 | SDP_SCRIPT_NAME = "status_display_program.sh"
22 |
23 | APP_ICON_PATH = unexpanduser(RESOURCE_PATH) / APP_ICON_NAME
24 |
25 | RC_PATH = unexpanduser(PAYLOAD_PATH) / "media_keys.py"
26 | # (s)tatus_(d)isplay_(p)rogram
27 | SDP_PATH = unexpanduser(PAYLOAD_PATH) / "notify.py"
28 |
29 | CMUS_OSX_FOLDER_NAME = "cmus-osx"
30 | CONFIG_NAME = "cmus-osx.conf"
31 |
32 | SCRIPTS: Dict[str, str] = {
33 | RC_SCRIPT_NAME: f"#!/bin/sh\n\nexec {str(INTERPRETER_PATH)} {str(RC_PATH)}",
34 | SDP_SCRIPT_NAME: f'#!/bin/sh\n\nexec {str(INTERPRETER_PATH)} {str(SDP_PATH)} "${{@}}"',
35 | }
36 |
37 | COULD_NOT_LOCATED_CMUS_DIRECTORY = 1
38 | AUTOSAVE_MISSING = 2
39 |
40 | ENV_VAR_PREFIX = "CMUS_OSX"
41 | ENV: Dict[str, Default] = {
42 | "NOTIFICATION_ON_PAUSE": Default(
43 | False,
44 | validator=lambda value: type(value) is bool,
45 | hint="Controls if a notification should be display on pause",
46 | ),
47 | "ITUNES_STYLE_NOTIFICATION": Default(
48 | True,
49 | validator=lambda value: type(value) is bool,
50 | hint="Display album artwork as app icon instead of notification badge",
51 | ),
52 | "APP_ICON": Default(
53 | APP_ICON_PATH,
54 | validator=lambda value: value.expanduser().is_file(),
55 | transformer=lambda value: Path(value),
56 | hint="Fallback icon if album artwork extraction fails",
57 | ),
58 | "THROTTLE_INTERVAL": Default(
59 | 0.0,
60 | validator=lambda value: value >= 0,
61 | hint="Throttle interval (adjust if experiencing duplicated key-pressses)",
62 | ),
63 | }
64 |
--------------------------------------------------------------------------------
/cmus_osx/env.py:
--------------------------------------------------------------------------------
1 | from ast import literal_eval
2 | from os import environ
3 | from types import SimpleNamespace
4 | from typing import Any
5 | from typing import Callable
6 | from typing import Dict
7 | from typing import List
8 | from typing import Optional
9 |
10 | from .util import remove_prefix
11 | from .util import safe_execute
12 |
13 | NEWLINE = "\n"
14 |
15 |
16 | class ValidationError(ValueError):
17 | def __init__(self, var_name: str, hint: Optional[str]):
18 | self.var_name = var_name
19 | self.hint = hint
20 |
21 | super().__init__(
22 | f"contents of var '{var_name}' invalid"
23 | f"{f' (hint: {hint})' if hint is not None else ''}"
24 | )
25 |
26 |
27 | class MissingEnvVarError(ValueError):
28 | def __init__(self, vars_: List[str]):
29 | self.vars_ = vars_
30 | super().__init__(
31 | f"env variable{'s' if len(vars_) > 1 else ''} missing: {', '.join(vars_)}"
32 | )
33 |
34 |
35 | class TransformationError(ValueError):
36 | def __init__(self, var_name: str, hint: Optional[str], exception: Exception):
37 | self.var_name = var_name
38 | self.hint = hint
39 | self.exception = exception
40 |
41 | super().__init__(
42 | f"could not transform '{var_name}': {str(exception)} "
43 | f"(hint: {hint if hint is not None else ''})"
44 | )
45 |
46 |
47 | class InvalidDefault:
48 | pass
49 |
50 |
51 | INVALID_DEFAULT = InvalidDefault()
52 |
53 |
54 | class Default:
55 | def __init__(
56 | self,
57 | value: Any,
58 | validator: Optional[Callable[[Any], bool]] = None,
59 | transformer: Optional[Callable[[Any], Any]] = None,
60 | hint: Optional[str] = None,
61 | ):
62 | self.value = value
63 | self.validator = validator
64 | self.transformer = transformer
65 | self.hint = hint
66 |
67 | def validate(self, value):
68 | return (
69 | False
70 | if value is INVALID_DEFAULT
71 | else self.validator(value)
72 | if callable(self.validator)
73 | else True
74 | )
75 |
76 | def transform(self, value):
77 | return self.transformer(value) if callable(self.transformer) else value
78 |
79 |
80 | def check_prefix(env_var_prefix: str) -> str:
81 | return env_var_prefix if env_var_prefix[-1] == "_" else f"{env_var_prefix}_"
82 |
83 |
84 | def template(env_var_prefix: str, defaults: Dict[str, Default]) -> Optional[str]:
85 | template = ""
86 |
87 | env_var_prefix = check_prefix(env_var_prefix)
88 | for name in defaults:
89 | default = defaults[name]
90 | template = (
91 | f"{template}{f'# {default.hint}{NEWLINE}' if default.hint is not None else ''}"
92 | f"export {env_var_prefix}{name}="
93 | f"{default.value if default.value not in [None, InvalidDefault] else ''}\n"
94 | )
95 |
96 | return template
97 |
98 |
99 | def build_env(env_var_prefix: str, defaults: Dict[str, Default]):
100 | # Make sure the environment variable prefix ends with a underscore ('_')
101 | env_var_prefix = check_prefix(env_var_prefix)
102 | env = SimpleNamespace()
103 |
104 | for var in defaults:
105 | value = defaults[var].value
106 | prefix_less = remove_prefix(var, env_var_prefix)
107 | if defaults[prefix_less].validate(value):
108 | # Transformations are not applied for default values
109 | setattr(env, var.lower(), value)
110 | else:
111 | env_var = f"{env_var_prefix}{var}"
112 | # Invalid default might be substituted later
113 | if env_var not in environ:
114 | raise ValidationError(env_var, defaults[prefix_less].hint)
115 | for var in environ:
116 | if var.startswith(env_var_prefix):
117 | prefix_less = remove_prefix(var, env_var_prefix)
118 | if prefix_less in defaults:
119 | # Safely evaluate value
120 | value = safe_execute(
121 | environ[var],
122 | (ValueError, SyntaxError),
123 | lambda: literal_eval(environ[var]),
124 | )
125 | # Apply transformation
126 | try:
127 | transformed_value = defaults[prefix_less].transform(value)
128 | except Exception as e:
129 | raise TransformationError(
130 | prefix_less, defaults[prefix_less].hint, e
131 | )
132 | if defaults[prefix_less].validate(transformed_value):
133 | setattr(env, prefix_less.lower(), transformed_value)
134 | else:
135 | raise ValidationError(var, defaults[prefix_less].hint)
136 | else:
137 | # To-Do: User feedback
138 | pass
139 |
140 | missing_vars = []
141 |
142 | for var in defaults:
143 | if var.lower() not in env.__dict__:
144 | missing_vars.append(var)
145 |
146 | if len(missing_vars) > 0:
147 | raise MissingEnvVarError(missing_vars)
148 |
149 | return env
150 |
--------------------------------------------------------------------------------
/cmus_osx/payload/media_keys.py:
--------------------------------------------------------------------------------
1 | from os import _exit as exit
2 | from subprocess import call as call_
3 | from subprocess import CalledProcessError
4 | from subprocess import check_output
5 | from threading import Thread
6 | from time import sleep
7 | from typing import List
8 | from typing import Optional
9 |
10 | from AppKit import NSApplication
11 | from AppKit import NSApplicationActivationPolicyProhibited
12 | from AppKit import NSKeyUp
13 | from AppKit import NSSystemDefined
14 | from PyObjCTools import AppHelper
15 |
16 | from cmus_osx.constants import CMUS_OSX_FOLDER_NAME
17 | from cmus_osx.constants import CONFIG_NAME
18 | from cmus_osx.constants import ENV
19 | from cmus_osx.constants import ENV_VAR_PREFIX
20 | from cmus_osx.env import build_env
21 | from cmus_osx.util import locate_cmus_base_path
22 | from cmus_osx.util import source_env_file
23 | from cmus_osx.util import throttle
24 |
25 | cmus_base_path = locate_cmus_base_path()
26 |
27 | if cmus_base_path is not None:
28 | source_env_file(cmus_base_path / CMUS_OSX_FOLDER_NAME / CONFIG_NAME)
29 |
30 | # Use defaults values if config file can't be located
31 | env = build_env(ENV_VAR_PREFIX, ENV)
32 |
33 | call = throttle(env.throttle_interval)(call_)
34 |
35 |
36 | class KeySocketApp(NSApplication):
37 | repeated = False
38 |
39 | def sendEvent_(self, event):
40 | if event.type() is NSSystemDefined and event.subtype() == 8:
41 | data = event.data1()
42 | key_code = (data & 0xFFFF0000) >> 16
43 | key_flags = data & 0x0000FFFF
44 | key_state = (key_flags & 0xFF00) >> 8
45 | key_repeat = key_flags & 0x1
46 |
47 | if key_repeat and key_state is not NSKeyUp:
48 | if key_code == 20:
49 | self.repeated = True
50 | call(["cmus-remote", "-k", "-10"])
51 | elif key_code == 19:
52 | self.repeated = True
53 | call(["cmus-remote", "-k", "+10"])
54 |
55 | if key_state is NSKeyUp:
56 | if self.repeated:
57 | self.repeated = False
58 | elif key_code in (20, 18):
59 | call(["cmus-remote", "-r"])
60 | elif key_code == 16:
61 | call(["cmus-remote", "-u"])
62 | elif key_code in (19, 17):
63 | call(["cmus-remote", "-n"])
64 |
65 |
66 | class SingleInstanceChecker(Thread):
67 | def __init__(self):
68 | Thread.__init__(self)
69 | self.daemon = True
70 | self.running = False
71 |
72 | def run(self):
73 | self.running = True
74 | while self.running:
75 | cmus_instances = get_cmus_instances()
76 | if cmus_instances is not None:
77 | if len(cmus_instances) == 0:
78 | exit(0)
79 | elif len(cmus_instances) > 1:
80 | call(
81 | [
82 | "cmus-remote",
83 | "--raw",
84 | "echo Media key support disabled "
85 | "because more than one cmus instance is running.",
86 | ]
87 | )
88 | exit(1)
89 | else:
90 | call(
91 | [
92 | "cmus-remote",
93 | "--raw",
94 | "echo Media key support disabled because "
95 | "enumerating cmus instances failed.",
96 | ]
97 | )
98 | exit(1)
99 | sleep(1)
100 |
101 | def stop(self):
102 | self.running = False
103 |
104 |
105 | def get_cmus_instances() -> Optional[List[int]]:
106 | try:
107 | return [
108 | int(pid)
109 | for pid in check_output(["pgrep", "-x", "cmus"]).decode().split("\n")
110 | if pid != ""
111 | ]
112 | except CalledProcessError:
113 | return None
114 |
115 |
116 | cmus_instances = get_cmus_instances()
117 | if cmus_instances is not None and len(cmus_instances) == 1:
118 | app = KeySocketApp.sharedApplication()
119 | app.setActivationPolicy_(NSApplicationActivationPolicyProhibited)
120 | single_instance_checker = SingleInstanceChecker()
121 | single_instance_checker.start()
122 | AppHelper.runEventLoop()
123 | else:
124 | exit(1)
125 |
--------------------------------------------------------------------------------
/cmus_osx/payload/notify.py:
--------------------------------------------------------------------------------
1 | import sys
2 | from io import BytesIO
3 | from os.path import isfile
4 | from pathlib import Path
5 | from platform import mac_ver
6 | from subprocess import call
7 |
8 | from AppKit import NSBitmapImageRep
9 | from AppKit import NSData
10 | from AppKit import NSImage
11 | from AppKit import NSMakeSize
12 | from Foundation import NSUserNotification
13 | from Foundation import NSUserNotificationCenter
14 | from mutagen import File
15 | from PIL import Image
16 |
17 | from cmus_osx.constants import CMUS_OSX_FOLDER_NAME
18 | from cmus_osx.constants import CONFIG_NAME
19 | from cmus_osx.constants import ENV
20 | from cmus_osx.constants import ENV_VAR_PREFIX
21 | from cmus_osx.env import build_env
22 | from cmus_osx.util import locate_cmus_base_path
23 | from cmus_osx.util import source_env_file
24 |
25 |
26 | def exception_hook(exc_type, exc_value, exc_traceback):
27 | call(["cmus-remote", "--raw", "echo cmus-osx error: %s" % str(exc_value)])
28 |
29 |
30 | sys.excepthook = exception_hook
31 |
32 | cmus_base_path = locate_cmus_base_path()
33 |
34 | if cmus_base_path is not None:
35 | source_env_file(cmus_base_path / CMUS_OSX_FOLDER_NAME / CONFIG_NAME)
36 |
37 | # Use defaults values if config file can't be located
38 | env = build_env(ENV_VAR_PREFIX, ENV)
39 |
40 | status_raw = sys.argv[1:]
41 | status = dict(zip(status_raw[0::2], status_raw[1::2]))
42 |
43 | # Quickly exit if paused
44 | if "status" in status:
45 | if not env.notification_on_pause:
46 | if status["status"] != "playing":
47 | exit(0)
48 |
49 | cover = None
50 |
51 | if "url" in status:
52 | status["status"] = "(streaming ...)"
53 | # the title may contain both the artist and the song name
54 | if "title" in status:
55 | title_pair = status["title"].split(" - ")
56 | if len(title_pair) > 1:
57 | status["artist"] = title_pair[0]
58 | status["title"] = title_pair[1]
59 | else:
60 | status["title"] = status["url"]
61 | elif "file" in status and isfile(status["file"]):
62 | file = File(status["file"])
63 | if file is not None:
64 | # id3
65 | if "APIC:" in file:
66 | cover = file["APIC:"]
67 | cover = cover.data
68 | # mp4
69 | elif "covr" in file:
70 | covers = file["covr"]
71 | if len(covers) > 0:
72 | cover = covers[0]
73 | # flac
74 | elif hasattr(file, "pictures") and len(file.pictures) > 0:
75 | cover = file.pictures[0].data
76 |
77 | if env.notification_on_pause:
78 | title = "cmus %s" % status["status"]
79 | else:
80 | title = "cmus"
81 | subtitle = ""
82 | message = ""
83 |
84 | if "tracknumber" in status and status["tracknumber"].isnumeric():
85 | subtitle += "%s. " % status["tracknumber"]
86 |
87 | if "title" in status:
88 | subtitle += status["title"]
89 |
90 | if "artist" in status:
91 | message += status["artist"]
92 | elif "albumartist" in status:
93 | message += status["albumartist"]
94 |
95 | if "album" in status:
96 | message += " – %s" % status["album"]
97 |
98 | if "date" in status and status["date"].isnumeric():
99 | message += " (%s)" % status["date"]
100 |
101 | # If no metadata is found, use filename instead
102 | if not subtitle or not message:
103 | filename = Path(status["file"]).name
104 | subtitle = filename
105 |
106 | center = NSUserNotificationCenter.defaultUserNotificationCenter()
107 | notification = NSUserNotification.alloc().init()
108 |
109 | notification.setTitle_(title)
110 | notification.setSubtitle_(subtitle)
111 | notification.setInformativeText_(message)
112 |
113 | # To-Do: Data allocation currently doesn't work in Catalina
114 | if mac_ver()[0] != "10.15":
115 | if cover is not None: # the song has an embedded cover image
116 | data = NSData.alloc().initWithBytes_length_(cover, len(cover))
117 | image_rep = NSBitmapImageRep.alloc().initWithData_(data)
118 |
119 | # CGImageGetWidth started returning bogus values in macOS 10.14 ->
120 | # Use Pillow to extract the image dimensions
121 | size = NSMakeSize(*Image.open(BytesIO(cover)).size)
122 |
123 | image = NSImage.alloc().initWithSize_(size)
124 | image.addRepresentation_(image_rep)
125 | if env.itunes_style_notification:
126 |
127 | notification.setValue_forKey_(image, "_identityImage")
128 | else:
129 | notification.setValue_forKey_(
130 | NSImage.alloc().initByReferencingFile_(str(env.app_icon)),
131 | "_identityImage",
132 | )
133 | notification.setContentImage_(image)
134 | else: # song has no cover image, show an icon
135 | notification.setValue_forKey_(
136 | NSImage.alloc().initByReferencingFile_(str(env.app_icon)), "_identityImage"
137 | )
138 |
139 | center.removeAllDeliveredNotifications()
140 |
141 | center.deliverNotification_(notification)
142 |
--------------------------------------------------------------------------------
/cmus_osx/resource/icon.png:
--------------------------------------------------------------------------------
1 | version https://git-lfs.github.com/spec/v1
2 | oid sha256:ba682125e5985e805b77c4ffc088810e08e38129f236a31878396e5858708839
3 | size 851
4 |
--------------------------------------------------------------------------------
/cmus_osx/util.py:
--------------------------------------------------------------------------------
1 | from os import environ
2 | from os import getenv
3 | from pathlib import Path
4 | from shutil import which
5 | from subprocess import CalledProcessError
6 | from subprocess import check_output
7 | from subprocess import PIPE
8 | from subprocess import Popen
9 | from time import time
10 | from typing import Any
11 | from typing import Callable
12 | from typing import List
13 | from typing import Optional
14 | from typing import Sequence
15 | from typing import Type
16 | from typing import Union
17 |
18 |
19 | def locate_cmus_base_path() -> Optional[Path]:
20 | for path in (
21 | path.expanduser() for path in (Path("~/.config/cmus/"), Path("~/.cmus/"))
22 | ):
23 | if path.is_dir():
24 | return path
25 | return None
26 |
27 |
28 | def locate_editor() -> Optional[Path]:
29 | for editor in (getenv("VISUAL", None), getenv("EDITOR", None), "nano", "vim", "vi"):
30 | if editor is not None:
31 | # Might be absolute path to editor
32 | editor_path = Path(editor).expanduser()
33 | # Might also be just the binary name
34 | editor_which = which(editor)
35 |
36 | if editor_path.is_file():
37 | return editor_path
38 | elif editor_which is not None:
39 | return Path(editor_which)
40 | return None
41 |
42 |
43 | def safe_execute(
44 | default: Any,
45 | exception: Union[Type[BaseException], Sequence[Type[BaseException]]],
46 | function: Callable,
47 | *args: Any,
48 | **kwargs: Any,
49 | ):
50 | try:
51 | return function(*args, **kwargs)
52 | except exception: # type: ignore
53 | return default
54 |
55 |
56 | def remove_prefix(text: str, prefix: str):
57 | return text[len(prefix) :] if text.startswith(prefix) else text
58 |
59 |
60 | # https://stackoverflow.com/a/3505826
61 | def source_env_file(env_file: Path):
62 | proc = Popen(
63 | ["/bin/sh", "-c", f"set -a && source {str(env_file)} && env"], stdout=PIPE
64 | )
65 | for line in (line.decode() for line in proc.stdout):
66 | (key, _, value) = line.partition("=")
67 | environ[key] = value.rstrip()
68 | proc.communicate()
69 |
70 |
71 | def get_cmus_instances() -> Optional[List[int]]:
72 | try:
73 | return [
74 | int(pid)
75 | for pid in check_output(["pgrep", "-x", "cmus"]).decode().split("\n")
76 | if pid != ""
77 | ]
78 | except CalledProcessError:
79 | return None
80 |
81 |
82 | # https://gist.github.com/walkermatt/2871026#gistcomment-2280711
83 | def throttle(interval: Union[float, int]):
84 | """Decorator ensures function that can only be called once every `s` seconds.
85 | """
86 |
87 | def decorate(fn: Callable) -> Callable:
88 | t = None
89 |
90 | def wrapped(*args, **kwargs):
91 | nonlocal t
92 | t_ = time()
93 | if t is None or t_ - t >= interval:
94 | result = fn(*args, **kwargs)
95 | t = time()
96 | return result
97 |
98 | return wrapped
99 |
100 | return decorate
101 |
102 |
103 | def unexpanduser(path: Path) -> Path:
104 | try:
105 | return Path("~") / path.relative_to(Path.home())
106 | except ValueError:
107 | return path
108 |
--------------------------------------------------------------------------------
/poetry.lock:
--------------------------------------------------------------------------------
1 | [[package]]
2 | category = "dev"
3 | description = "A small Python module for determining appropriate platform-specific dirs, e.g. a \"user data dir\"."
4 | name = "appdirs"
5 | optional = false
6 | python-versions = "*"
7 | version = "1.4.4"
8 |
9 | [[package]]
10 | category = "dev"
11 | description = "A few extensions to pyyaml."
12 | name = "aspy.yaml"
13 | optional = false
14 | python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
15 | version = "1.3.0"
16 |
17 | [package.dependencies]
18 | pyyaml = "*"
19 |
20 | [[package]]
21 | category = "dev"
22 | description = "Validate configuration and produce human readable error messages."
23 | name = "cfgv"
24 | optional = false
25 | python-versions = ">=3.6.1"
26 | version = "3.2.0"
27 |
28 | [[package]]
29 | category = "main"
30 | description = "Composable command line interface toolkit"
31 | name = "click"
32 | optional = false
33 | python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
34 | version = "7.1.2"
35 |
36 | [[package]]
37 | category = "dev"
38 | description = "Distribution utilities"
39 | name = "distlib"
40 | optional = false
41 | python-versions = "*"
42 | version = "0.3.1"
43 |
44 | [[package]]
45 | category = "dev"
46 | description = "A platform independent file lock."
47 | name = "filelock"
48 | optional = false
49 | python-versions = "*"
50 | version = "3.0.12"
51 |
52 | [[package]]
53 | category = "dev"
54 | description = "File identification library for Python"
55 | name = "identify"
56 | optional = false
57 | python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7"
58 | version = "1.5.9"
59 |
60 | [package.extras]
61 | license = ["editdistance"]
62 |
63 | [[package]]
64 | category = "dev"
65 | description = "Read metadata from Python packages"
66 | marker = "python_version < \"3.8\""
67 | name = "importlib-metadata"
68 | optional = false
69 | python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7"
70 | version = "2.0.0"
71 |
72 | [package.dependencies]
73 | zipp = ">=0.5"
74 |
75 | [package.extras]
76 | docs = ["sphinx", "rst.linker"]
77 | testing = ["packaging", "pep517", "importlib-resources (>=1.3)"]
78 |
79 | [[package]]
80 | category = "main"
81 | description = "read and write audio tags for many formats"
82 | name = "mutagen"
83 | optional = false
84 | python-versions = ">=3.5, <4"
85 | version = "1.45.1"
86 |
87 | [[package]]
88 | category = "dev"
89 | description = "Node.js virtual environment builder"
90 | name = "nodeenv"
91 | optional = false
92 | python-versions = "*"
93 | version = "1.5.0"
94 |
95 | [[package]]
96 | category = "main"
97 | description = "Python Imaging Library (Fork)"
98 | name = "pillow"
99 | optional = false
100 | python-versions = ">=3.6"
101 | version = "8.0.1"
102 |
103 | [[package]]
104 | category = "dev"
105 | description = "A framework for managing and maintaining multi-language pre-commit hooks."
106 | name = "pre-commit"
107 | optional = false
108 | python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7"
109 | version = "1.21.0"
110 |
111 | [package.dependencies]
112 | "aspy.yaml" = "*"
113 | cfgv = ">=2.0.0"
114 | identify = ">=1.0.0"
115 | nodeenv = ">=0.11.1"
116 | pyyaml = "*"
117 | six = "*"
118 | toml = "*"
119 | virtualenv = ">=15.2"
120 |
121 | [package.dependencies.importlib-metadata]
122 | python = "<3.8"
123 | version = "*"
124 |
125 | [[package]]
126 | category = "main"
127 | description = "Python<->ObjC Interoperability Module"
128 | name = "pyobjc"
129 | optional = false
130 | python-versions = ">=3.6"
131 | version = "6.2.2"
132 |
133 | [package.dependencies]
134 | pyobjc-core = "6.2.2"
135 | pyobjc-framework-AVFoundation = "6.2.2"
136 | pyobjc-framework-AVKit = "6.2.2"
137 | pyobjc-framework-Accounts = "6.2.2"
138 | pyobjc-framework-AdSupport = "6.2.2"
139 | pyobjc-framework-AddressBook = "6.2.2"
140 | pyobjc-framework-AppleScriptKit = "6.2.2"
141 | pyobjc-framework-AppleScriptObjC = "6.2.2"
142 | pyobjc-framework-ApplicationServices = "6.2.2"
143 | pyobjc-framework-AuthenticationServices = "6.2.2"
144 | pyobjc-framework-AutomaticAssessmentConfiguration = "6.2.2"
145 | pyobjc-framework-Automator = "6.2.2"
146 | pyobjc-framework-BusinessChat = "6.2.2"
147 | pyobjc-framework-CFNetwork = "6.2.2"
148 | pyobjc-framework-CalendarStore = "6.2.2"
149 | pyobjc-framework-CloudKit = "6.2.2"
150 | pyobjc-framework-Cocoa = "6.2.2"
151 | pyobjc-framework-Collaboration = "6.2.2"
152 | pyobjc-framework-ColorSync = "6.2.2"
153 | pyobjc-framework-Contacts = "6.2.2"
154 | pyobjc-framework-ContactsUI = "6.2.2"
155 | pyobjc-framework-CoreAudio = "6.2.2"
156 | pyobjc-framework-CoreAudioKit = "6.2.2"
157 | pyobjc-framework-CoreBluetooth = "6.2.2"
158 | pyobjc-framework-CoreData = "6.2.2"
159 | pyobjc-framework-CoreHaptics = "6.2.2"
160 | pyobjc-framework-CoreLocation = "6.2.2"
161 | pyobjc-framework-CoreML = "6.2.2"
162 | pyobjc-framework-CoreMedia = "6.2.2"
163 | pyobjc-framework-CoreMediaIO = "6.2.2"
164 | pyobjc-framework-CoreMotion = "6.2.2"
165 | pyobjc-framework-CoreServices = "6.2.2"
166 | pyobjc-framework-CoreSpotlight = "6.2.2"
167 | pyobjc-framework-CoreText = "6.2.2"
168 | pyobjc-framework-CoreWLAN = "6.2.2"
169 | pyobjc-framework-CryptoTokenKit = "6.2.2"
170 | pyobjc-framework-DVDPlayback = "6.2.2"
171 | pyobjc-framework-DeviceCheck = "6.2.2"
172 | pyobjc-framework-DictionaryServices = "6.2.2"
173 | pyobjc-framework-DiscRecording = "6.2.2"
174 | pyobjc-framework-DiscRecordingUI = "6.2.2"
175 | pyobjc-framework-DiskArbitration = "6.2.2"
176 | pyobjc-framework-EventKit = "6.2.2"
177 | pyobjc-framework-ExceptionHandling = "6.2.2"
178 | pyobjc-framework-ExecutionPolicy = "6.2.2"
179 | pyobjc-framework-ExternalAccessory = "6.2.2"
180 | pyobjc-framework-FSEvents = "6.2.2"
181 | pyobjc-framework-FileProvider = "6.2.2"
182 | pyobjc-framework-FileProviderUI = "6.2.2"
183 | pyobjc-framework-FinderSync = "6.2.2"
184 | pyobjc-framework-GameCenter = "6.2.2"
185 | pyobjc-framework-GameController = "6.2.2"
186 | pyobjc-framework-GameKit = "6.2.2"
187 | pyobjc-framework-GameplayKit = "6.2.2"
188 | pyobjc-framework-IMServicePlugIn = "6.2.2"
189 | pyobjc-framework-IOSurface = "6.2.2"
190 | pyobjc-framework-ImageCaptureCore = "6.2.2"
191 | pyobjc-framework-InputMethodKit = "6.2.2"
192 | pyobjc-framework-InstallerPlugins = "6.2.2"
193 | pyobjc-framework-InstantMessage = "6.2.2"
194 | pyobjc-framework-Intents = "6.2.2"
195 | pyobjc-framework-InterfaceBuilderKit = "6.2.2"
196 | pyobjc-framework-LatentSemanticMapping = "6.2.2"
197 | pyobjc-framework-LaunchServices = "6.2.2"
198 | pyobjc-framework-LinkPresentation = "6.2.2"
199 | pyobjc-framework-LocalAuthentication = "6.2.2"
200 | pyobjc-framework-MapKit = "6.2.2"
201 | pyobjc-framework-MediaAccessibility = "6.2.2"
202 | pyobjc-framework-MediaLibrary = "6.2.2"
203 | pyobjc-framework-MediaPlayer = "6.2.2"
204 | pyobjc-framework-MediaToolbox = "6.2.2"
205 | pyobjc-framework-Message = "6.2.2"
206 | pyobjc-framework-Metal = "6.2.2"
207 | pyobjc-framework-MetalKit = "6.2.2"
208 | pyobjc-framework-ModelIO = "6.2.2"
209 | pyobjc-framework-MultipeerConnectivity = "6.2.2"
210 | pyobjc-framework-NaturalLanguage = "6.2.2"
211 | pyobjc-framework-NetFS = "6.2.2"
212 | pyobjc-framework-Network = "6.2.2"
213 | pyobjc-framework-NetworkExtension = "6.2.2"
214 | pyobjc-framework-NotificationCenter = "6.2.2"
215 | pyobjc-framework-OSAKit = "6.2.2"
216 | pyobjc-framework-OSLog = "6.2.2"
217 | pyobjc-framework-OpenDirectory = "6.2.2"
218 | pyobjc-framework-PencilKit = "6.2.2"
219 | pyobjc-framework-Photos = "6.2.2"
220 | pyobjc-framework-PhotosUI = "6.2.2"
221 | pyobjc-framework-PreferencePanes = "6.2.2"
222 | pyobjc-framework-PubSub = "6.2.2"
223 | pyobjc-framework-PushKit = "6.2.2"
224 | pyobjc-framework-QTKit = "6.2.2"
225 | pyobjc-framework-Quartz = "6.2.2"
226 | pyobjc-framework-QuickLookThumbnailing = "6.2.2"
227 | pyobjc-framework-SafariServices = "6.2.2"
228 | pyobjc-framework-SceneKit = "6.2.2"
229 | pyobjc-framework-ScreenSaver = "6.2.2"
230 | pyobjc-framework-ScriptingBridge = "6.2.2"
231 | pyobjc-framework-SearchKit = "6.2.2"
232 | pyobjc-framework-Security = "6.2.2"
233 | pyobjc-framework-SecurityFoundation = "6.2.2"
234 | pyobjc-framework-SecurityInterface = "6.2.2"
235 | pyobjc-framework-ServerNotification = "6.2.2"
236 | pyobjc-framework-ServiceManagement = "6.2.2"
237 | pyobjc-framework-Social = "6.2.2"
238 | pyobjc-framework-SoundAnalysis = "6.2.2"
239 | pyobjc-framework-Speech = "6.2.2"
240 | pyobjc-framework-SpriteKit = "6.2.2"
241 | pyobjc-framework-StoreKit = "6.2.2"
242 | pyobjc-framework-SyncServices = "6.2.2"
243 | pyobjc-framework-SystemConfiguration = "6.2.2"
244 | pyobjc-framework-SystemExtensions = "6.2.2"
245 | pyobjc-framework-UserNotifications = "6.2.2"
246 | pyobjc-framework-VideoSubscriberAccount = "6.2.2"
247 | pyobjc-framework-VideoToolbox = "6.2.2"
248 | pyobjc-framework-Vision = "6.2.2"
249 | pyobjc-framework-WebKit = "6.2.2"
250 | pyobjc-framework-XgridFoundation = "6.2.2"
251 | pyobjc-framework-iTunesLibrary = "6.2.2"
252 | pyobjc-framework-libdispatch = "6.2.2"
253 |
254 | [[package]]
255 | category = "main"
256 | description = "Python<->ObjC Interoperability Module"
257 | name = "pyobjc-core"
258 | optional = false
259 | python-versions = ">=3.6"
260 | version = "6.2.2"
261 |
262 | [[package]]
263 | category = "main"
264 | description = "Wrappers for the framework Accounts on macOS"
265 | marker = "platform_release >= \"12.0\" or platform_release >= \"14.0\""
266 | name = "pyobjc-framework-accounts"
267 | optional = false
268 | python-versions = ">=3.6"
269 | version = "6.2.2"
270 |
271 | [package.dependencies]
272 | pyobjc-core = ">=6.2.2"
273 | pyobjc-framework-Cocoa = ">=6.2.2"
274 |
275 | [[package]]
276 | category = "main"
277 | description = "Wrappers for the framework AddressBook on macOS"
278 | name = "pyobjc-framework-addressbook"
279 | optional = false
280 | python-versions = ">=3.6"
281 | version = "6.2.2"
282 |
283 | [package.dependencies]
284 | pyobjc-core = ">=6.2.2"
285 | pyobjc-framework-Cocoa = ">=6.2.2"
286 |
287 | [[package]]
288 | category = "main"
289 | description = "Wrappers for the framework AdSupport on macOS"
290 | marker = "platform_release >= \"18.0\""
291 | name = "pyobjc-framework-adsupport"
292 | optional = false
293 | python-versions = ">=3.6"
294 | version = "6.2.2"
295 |
296 | [package.dependencies]
297 | pyobjc-core = ">=6.2.2"
298 | pyobjc-framework-Cocoa = ">=6.2.2"
299 |
300 | [[package]]
301 | category = "main"
302 | description = "Wrappers for the framework AppleScriptKit on macOS"
303 | name = "pyobjc-framework-applescriptkit"
304 | optional = false
305 | python-versions = ">=3.6"
306 | version = "6.2.2"
307 |
308 | [package.dependencies]
309 | pyobjc-core = ">=6.2.2"
310 | pyobjc-framework-Cocoa = ">=6.2.2"
311 |
312 | [[package]]
313 | category = "main"
314 | description = "Wrappers for the framework AppleScriptObjC on macOS"
315 | marker = "platform_release >= \"10.0\""
316 | name = "pyobjc-framework-applescriptobjc"
317 | optional = false
318 | python-versions = ">=3.6"
319 | version = "6.2.2"
320 |
321 | [package.dependencies]
322 | pyobjc-core = ">=6.2.2"
323 | pyobjc-framework-Cocoa = ">=6.2.2"
324 |
325 | [[package]]
326 | category = "main"
327 | description = "Wrappers for the framework ApplicationServices on macOS"
328 | name = "pyobjc-framework-applicationservices"
329 | optional = false
330 | python-versions = ">=3.6"
331 | version = "6.2.2"
332 |
333 | [package.dependencies]
334 | pyobjc-core = ">=6.2.2"
335 | pyobjc-framework-Cocoa = ">=6.2.2"
336 | pyobjc-framework-Quartz = ">=6.2.2"
337 |
338 | [[package]]
339 | category = "main"
340 | description = "Wrappers for the framework AuthenticationServices on macOS"
341 | marker = "platform_release >= \"19.0\""
342 | name = "pyobjc-framework-authenticationservices"
343 | optional = false
344 | python-versions = ">=3.6"
345 | version = "6.2.2"
346 |
347 | [package.dependencies]
348 | pyobjc-core = ">=6.2.2"
349 | pyobjc-framework-Cocoa = ">=6.2.2"
350 |
351 | [[package]]
352 | category = "main"
353 | description = "Wrappers for the framework AutomaticAssessmentConfiguration on macOS"
354 | marker = "platform_release >= \"19.0\""
355 | name = "pyobjc-framework-automaticassessmentconfiguration"
356 | optional = false
357 | python-versions = ">=3.6"
358 | version = "6.2.2"
359 |
360 | [package.dependencies]
361 | pyobjc-core = ">=6.2.2"
362 | pyobjc-framework-Cocoa = ">=6.2.2"
363 |
364 | [[package]]
365 | category = "main"
366 | description = "Wrappers for the framework Automator on macOS"
367 | name = "pyobjc-framework-automator"
368 | optional = false
369 | python-versions = ">=3.6"
370 | version = "6.2.2"
371 |
372 | [package.dependencies]
373 | pyobjc-core = ">=6.2.2"
374 | pyobjc-framework-Cocoa = ">=6.2.2"
375 |
376 | [[package]]
377 | category = "main"
378 | description = "Wrappers for the framework AVFoundation on macOS"
379 | marker = "platform_release >= \"11.0\" or platform_release >= \"16.0\""
380 | name = "pyobjc-framework-avfoundation"
381 | optional = false
382 | python-versions = ">=3.6"
383 | version = "6.2.2"
384 |
385 | [package.dependencies]
386 | pyobjc-core = ">=6.2.2"
387 | pyobjc-framework-Cocoa = ">=6.2.2"
388 | pyobjc-framework-CoreMedia = ">=6.2.2"
389 | pyobjc-framework-Quartz = ">=6.2.2"
390 |
391 | [[package]]
392 | category = "main"
393 | description = "Wrappers for the framework AVKit on macOS"
394 | marker = "platform_release >= \"13.0\""
395 | name = "pyobjc-framework-avkit"
396 | optional = false
397 | python-versions = ">=3.6"
398 | version = "6.2.2"
399 |
400 | [package.dependencies]
401 | pyobjc-core = ">=6.2.2"
402 | pyobjc-framework-Cocoa = ">=6.2.2"
403 | pyobjc-framework-Quartz = ">=6.2.2"
404 |
405 | [[package]]
406 | category = "main"
407 | description = "Wrappers for the framework BusinessChat on macOS"
408 | marker = "platform_release >= \"18.0\""
409 | name = "pyobjc-framework-businesschat"
410 | optional = false
411 | python-versions = ">=3.6"
412 | version = "6.2.2"
413 |
414 | [package.dependencies]
415 | pyobjc-core = ">=6.2.2"
416 | pyobjc-framework-Cocoa = ">=6.2.2"
417 |
418 | [[package]]
419 | category = "main"
420 | description = "Wrappers for the framework CalendarStore on macOS"
421 | marker = "platform_release >= \"9.0\""
422 | name = "pyobjc-framework-calendarstore"
423 | optional = false
424 | python-versions = ">=3.6"
425 | version = "6.2.2"
426 |
427 | [package.dependencies]
428 | pyobjc-core = ">=6.2.2"
429 | pyobjc-framework-Cocoa = ">=6.2.2"
430 |
431 | [[package]]
432 | category = "main"
433 | description = "Wrappers for the framework CFNetwork on macOS"
434 | name = "pyobjc-framework-cfnetwork"
435 | optional = false
436 | python-versions = ">=3.6"
437 | version = "6.2.2"
438 |
439 | [package.dependencies]
440 | pyobjc-core = ">=6.2.2"
441 | pyobjc-framework-Cocoa = ">=6.2.2"
442 |
443 | [[package]]
444 | category = "main"
445 | description = "Wrappers for the framework CloudKit on macOS"
446 | marker = "platform_release >= \"14.0\""
447 | name = "pyobjc-framework-cloudkit"
448 | optional = false
449 | python-versions = ">=3.6"
450 | version = "6.2.2"
451 |
452 | [package.dependencies]
453 | pyobjc-core = ">=6.2.2"
454 | pyobjc-framework-Accounts = ">=6.2.2"
455 | pyobjc-framework-Cocoa = ">=6.2.2"
456 | pyobjc-framework-CoreData = ">=6.2.2"
457 | pyobjc-framework-CoreLocation = ">=6.2.2"
458 |
459 | [[package]]
460 | category = "main"
461 | description = "Wrappers for the Cocoa frameworks on macOS"
462 | name = "pyobjc-framework-cocoa"
463 | optional = false
464 | python-versions = ">=3.6"
465 | version = "6.2.2"
466 |
467 | [package.dependencies]
468 | pyobjc-core = ">=6.2.2"
469 |
470 | [[package]]
471 | category = "main"
472 | description = "Wrappers for the framework Collaboration on macOS"
473 | marker = "platform_release >= \"9.0\""
474 | name = "pyobjc-framework-collaboration"
475 | optional = false
476 | python-versions = ">=3.6"
477 | version = "6.2.2"
478 |
479 | [package.dependencies]
480 | pyobjc-core = ">=6.2.2"
481 | pyobjc-framework-Cocoa = ">=6.2.2"
482 |
483 | [[package]]
484 | category = "main"
485 | description = "Wrappers for the framework ColorSync on Mac OS X"
486 | marker = "platform_release >= \"17.0\""
487 | name = "pyobjc-framework-colorsync"
488 | optional = false
489 | python-versions = ">=3.6"
490 | version = "6.2.2"
491 |
492 | [package.dependencies]
493 | pyobjc-core = ">=6.2.2"
494 | pyobjc-framework-Cocoa = ">=6.2.2"
495 |
496 | [[package]]
497 | category = "main"
498 | description = "Wrappers for the framework Contacts on macOS"
499 | marker = "platform_release >= \"15.0\""
500 | name = "pyobjc-framework-contacts"
501 | optional = false
502 | python-versions = ">=3.6"
503 | version = "6.2.2"
504 |
505 | [package.dependencies]
506 | pyobjc-core = ">=6.2.2"
507 | pyobjc-framework-Cocoa = ">=6.2.2"
508 |
509 | [[package]]
510 | category = "main"
511 | description = "Wrappers for the framework ContactsUI on macOS"
512 | marker = "platform_release >= \"15.0\""
513 | name = "pyobjc-framework-contactsui"
514 | optional = false
515 | python-versions = ">=3.6"
516 | version = "6.2.2"
517 |
518 | [package.dependencies]
519 | pyobjc-core = ">=6.2.2"
520 | pyobjc-framework-Cocoa = ">=6.2.2"
521 | pyobjc-framework-Contacts = ">=6.2.2"
522 |
523 | [[package]]
524 | category = "main"
525 | description = "Wrappers for the framework CoreAudio on macOS"
526 | name = "pyobjc-framework-coreaudio"
527 | optional = false
528 | python-versions = ">=3.6"
529 | version = "6.2.2"
530 |
531 | [package.dependencies]
532 | pyobjc-core = ">=6.2.2"
533 | pyobjc-framework-Cocoa = ">=6.2.2"
534 |
535 | [[package]]
536 | category = "main"
537 | description = "Wrappers for the framework CoreAudioKit on macOS"
538 | name = "pyobjc-framework-coreaudiokit"
539 | optional = false
540 | python-versions = ">=3.6"
541 | version = "6.2.2"
542 |
543 | [package.dependencies]
544 | pyobjc-core = ">=6.2.2"
545 | pyobjc-framework-Cocoa = ">=6.2.2"
546 | pyobjc-framework-CoreAudio = ">=6.2.2"
547 |
548 | [[package]]
549 | category = "main"
550 | description = "Wrappers for the framework CoreBluetooth on macOS"
551 | marker = "platform_release >= \"14.0\""
552 | name = "pyobjc-framework-corebluetooth"
553 | optional = false
554 | python-versions = ">=3.6"
555 | version = "6.2.2"
556 |
557 | [package.dependencies]
558 | pyobjc-core = ">=6.2.2"
559 | pyobjc-framework-Cocoa = ">=6.2.2"
560 |
561 | [[package]]
562 | category = "main"
563 | description = "Wrappers for the framework CoreData on macOS"
564 | name = "pyobjc-framework-coredata"
565 | optional = false
566 | python-versions = ">=3.6"
567 | version = "6.2.2"
568 |
569 | [package.dependencies]
570 | pyobjc-core = ">=6.2.2"
571 | pyobjc-framework-Cocoa = ">=6.2.2"
572 |
573 | [[package]]
574 | category = "main"
575 | description = "Wrappers for the framework CoreHaptics on macOS"
576 | marker = "platform_release >= \"19.0\""
577 | name = "pyobjc-framework-corehaptics"
578 | optional = false
579 | python-versions = ">=3.6"
580 | version = "6.2.2"
581 |
582 | [package.dependencies]
583 | pyobjc-core = ">=6.2.2"
584 | pyobjc-framework-Cocoa = ">=6.2.2"
585 |
586 | [[package]]
587 | category = "main"
588 | description = "Wrappers for the framework CoreLocation on macOS"
589 | marker = "platform_release >= \"10.0\" or platform_release >= \"13.0\" or platform_release >= \"14.0\""
590 | name = "pyobjc-framework-corelocation"
591 | optional = false
592 | python-versions = ">=3.6"
593 | version = "6.2.2"
594 |
595 | [package.dependencies]
596 | pyobjc-core = ">=6.2.2"
597 | pyobjc-framework-Cocoa = ">=6.2.2"
598 |
599 | [[package]]
600 | category = "main"
601 | description = "Wrappers for the framework CoreMedia on macOS"
602 | marker = "platform_release >= \"11.0\" or platform_release >= \"12.0\" or platform_release >= \"16.0\" or platform_release >= \"19.0\""
603 | name = "pyobjc-framework-coremedia"
604 | optional = false
605 | python-versions = ">=3.6"
606 | version = "6.2.2"
607 |
608 | [package.dependencies]
609 | pyobjc-core = ">=6.2.2"
610 | pyobjc-framework-Cocoa = ">=6.2.2"
611 |
612 | [[package]]
613 | category = "main"
614 | description = "Wrappers for the framework CoreMediaIO on macOS"
615 | marker = "platform_release >= \"11.0\""
616 | name = "pyobjc-framework-coremediaio"
617 | optional = false
618 | python-versions = ">=3.6"
619 | version = "6.2.2"
620 |
621 | [package.dependencies]
622 | pyobjc-core = ">=6.2.2"
623 | pyobjc-framework-Cocoa = ">=6.2.2"
624 |
625 | [[package]]
626 | category = "main"
627 | description = "Wrappers for the framework CoreML on macOS"
628 | marker = "platform_release >= \"17.0\""
629 | name = "pyobjc-framework-coreml"
630 | optional = false
631 | python-versions = ">=3.6"
632 | version = "6.2.2"
633 |
634 | [package.dependencies]
635 | pyobjc-core = ">=6.2.2"
636 | pyobjc-framework-Cocoa = ">=6.2.2"
637 |
638 | [[package]]
639 | category = "main"
640 | description = "Wrappers for the framework CoreMotion on macOS"
641 | marker = "platform_release >= \"19.0\""
642 | name = "pyobjc-framework-coremotion"
643 | optional = false
644 | python-versions = ">=3.6"
645 | version = "6.2.2"
646 |
647 | [package.dependencies]
648 | pyobjc-core = ">=6.2.2"
649 | pyobjc-framework-Cocoa = ">=6.2.2"
650 |
651 | [[package]]
652 | category = "main"
653 | description = "Wrappers for the framework CoreServices on macOS"
654 | name = "pyobjc-framework-coreservices"
655 | optional = false
656 | python-versions = ">=3.6"
657 | version = "6.2.2"
658 |
659 | [package.dependencies]
660 | pyobjc-core = ">=6.2.2"
661 | pyobjc-framework-FSEvents = ">=6.2.2"
662 |
663 | [[package]]
664 | category = "main"
665 | description = "Wrappers for the framework CoreSpotlight on macOS"
666 | marker = "platform_release >= \"17.0\""
667 | name = "pyobjc-framework-corespotlight"
668 | optional = false
669 | python-versions = ">=3.6"
670 | version = "6.2.2"
671 |
672 | [package.dependencies]
673 | pyobjc-core = ">=6.2.2"
674 | pyobjc-framework-Cocoa = ">=6.2.2"
675 |
676 | [[package]]
677 | category = "main"
678 | description = "Wrappers for the framework CoreText on macOS"
679 | name = "pyobjc-framework-coretext"
680 | optional = false
681 | python-versions = ">=3.6"
682 | version = "6.2.2"
683 |
684 | [package.dependencies]
685 | pyobjc-core = ">=6.2.2"
686 | pyobjc-framework-Cocoa = ">=6.2.2"
687 | pyobjc-framework-Quartz = ">=6.2.2"
688 |
689 | [[package]]
690 | category = "main"
691 | description = "Wrappers for the framework CoreWLAN on macOS"
692 | marker = "platform_release >= \"10.0\""
693 | name = "pyobjc-framework-corewlan"
694 | optional = false
695 | python-versions = ">=3.6"
696 | version = "6.2.2"
697 |
698 | [package.dependencies]
699 | pyobjc-core = ">=6.2.2"
700 | pyobjc-framework-Cocoa = ">=6.2.2"
701 |
702 | [[package]]
703 | category = "main"
704 | description = "Wrappers for the framework CryptoTokenKit on macOS"
705 | marker = "platform_release >= \"14.0\""
706 | name = "pyobjc-framework-cryptotokenkit"
707 | optional = false
708 | python-versions = ">=3.6"
709 | version = "6.2.2"
710 |
711 | [package.dependencies]
712 | pyobjc-core = ">=6.2.2"
713 | pyobjc-framework-Cocoa = ">=6.2.2"
714 |
715 | [[package]]
716 | category = "main"
717 | description = "Wrappers for the framework DeviceCheck on macOS"
718 | marker = "platform_release >= \"19.0\""
719 | name = "pyobjc-framework-devicecheck"
720 | optional = false
721 | python-versions = ">=3.6"
722 | version = "6.2.2"
723 |
724 | [package.dependencies]
725 | pyobjc-core = ">=6.2.2"
726 | pyobjc-framework-Cocoa = ">=6.2.2"
727 |
728 | [[package]]
729 | category = "main"
730 | description = "Wrappers for the framework DictionaryServices on macOS"
731 | marker = "platform_release >= \"9.0\""
732 | name = "pyobjc-framework-dictionaryservices"
733 | optional = false
734 | python-versions = ">=3.6"
735 | version = "6.2.2"
736 |
737 | [package.dependencies]
738 | pyobjc-core = ">=6.2.2"
739 | pyobjc-framework-CoreServices = ">=6.2.2"
740 |
741 | [[package]]
742 | category = "main"
743 | description = "Wrappers for the framework DiscRecording on macOS"
744 | name = "pyobjc-framework-discrecording"
745 | optional = false
746 | python-versions = ">=3.6"
747 | version = "6.2.2"
748 |
749 | [package.dependencies]
750 | pyobjc-core = ">=6.2.2"
751 | pyobjc-framework-Cocoa = ">=6.2.2"
752 |
753 | [[package]]
754 | category = "main"
755 | description = "Wrappers for the framework DiscRecordingUI on macOS"
756 | name = "pyobjc-framework-discrecordingui"
757 | optional = false
758 | python-versions = ">=3.6"
759 | version = "6.2.2"
760 |
761 | [package.dependencies]
762 | pyobjc-core = ">=6.2.2"
763 | pyobjc-framework-Cocoa = ">=6.2.2"
764 | pyobjc-framework-DiscRecording = ">=6.2.2"
765 |
766 | [[package]]
767 | category = "main"
768 | description = "Wrappers for the framework DiskArbitration on macOS"
769 | name = "pyobjc-framework-diskarbitration"
770 | optional = false
771 | python-versions = ">=3.6"
772 | version = "6.2.2"
773 |
774 | [package.dependencies]
775 | pyobjc-core = ">=6.2.2"
776 | pyobjc-framework-Cocoa = ">=6.2.2"
777 |
778 | [[package]]
779 | category = "main"
780 | description = "Wrappers for the framework DVDPlayback on macOS"
781 | name = "pyobjc-framework-dvdplayback"
782 | optional = false
783 | python-versions = ">=3.6"
784 | version = "6.2.2"
785 |
786 | [package.dependencies]
787 | pyobjc-core = ">=6.2.2"
788 | pyobjc-framework-Cocoa = ">=6.2.2"
789 |
790 | [[package]]
791 | category = "main"
792 | description = "Wrappers for the framework Accounts on macOS"
793 | marker = "platform_release >= \"12.0\""
794 | name = "pyobjc-framework-eventkit"
795 | optional = false
796 | python-versions = ">=3.6"
797 | version = "6.2.2"
798 |
799 | [package.dependencies]
800 | pyobjc-core = ">=6.2.2"
801 | pyobjc-framework-Cocoa = ">=6.2.2"
802 |
803 | [[package]]
804 | category = "main"
805 | description = "Wrappers for the framework ExceptionHandling on macOS"
806 | name = "pyobjc-framework-exceptionhandling"
807 | optional = false
808 | python-versions = ">=3.6"
809 | version = "6.2.2"
810 |
811 | [package.dependencies]
812 | pyobjc-core = ">=6.2.2"
813 | pyobjc-framework-Cocoa = ">=6.2.2"
814 |
815 | [[package]]
816 | category = "main"
817 | description = "Wrappers for the framework ExecutionPolicy on macOS"
818 | marker = "platform_release >= \"19.0\""
819 | name = "pyobjc-framework-executionpolicy"
820 | optional = false
821 | python-versions = ">=3.6"
822 | version = "6.2.2"
823 |
824 | [package.dependencies]
825 | pyobjc-core = ">=6.2.2"
826 | pyobjc-framework-Cocoa = ">=6.2.2"
827 |
828 | [[package]]
829 | category = "main"
830 | description = "Wrappers for the framework ExternalAccessory on macOS"
831 | marker = "platform_release >= \"17.0\""
832 | name = "pyobjc-framework-externalaccessory"
833 | optional = false
834 | python-versions = ">=3.6"
835 | version = "6.2.2"
836 |
837 | [package.dependencies]
838 | pyobjc-core = ">=6.2.2"
839 | pyobjc-framework-Cocoa = ">=6.2.2"
840 |
841 | [[package]]
842 | category = "main"
843 | description = "Wrappers for the framework FileProvider on macOS"
844 | marker = "platform_release >= \"19.0\""
845 | name = "pyobjc-framework-fileprovider"
846 | optional = false
847 | python-versions = ">=3.6"
848 | version = "6.2.2"
849 |
850 | [package.dependencies]
851 | pyobjc-core = ">=6.2.2"
852 | pyobjc-framework-Cocoa = ">=6.2.2"
853 |
854 | [[package]]
855 | category = "main"
856 | description = "Wrappers for the framework FileProviderUI on macOS"
857 | marker = "platform_release >= \"19.0\""
858 | name = "pyobjc-framework-fileproviderui"
859 | optional = false
860 | python-versions = ">=3.6"
861 | version = "6.2.2"
862 |
863 | [package.dependencies]
864 | pyobjc-core = ">=6.2.2"
865 | pyobjc-framework-FileProvider = ">=6.2.2"
866 |
867 | [[package]]
868 | category = "main"
869 | description = "Wrappers for the framework FinderSync on macOS"
870 | marker = "platform_release >= \"14.0\""
871 | name = "pyobjc-framework-findersync"
872 | optional = false
873 | python-versions = ">=3.6"
874 | version = "6.2.2"
875 |
876 | [package.dependencies]
877 | pyobjc-core = ">=6.2.2"
878 | pyobjc-framework-Cocoa = ">=6.2.2"
879 |
880 | [[package]]
881 | category = "main"
882 | description = "Wrappers for the framework FSEvents on macOS"
883 | name = "pyobjc-framework-fsevents"
884 | optional = false
885 | python-versions = ">=3.6"
886 | version = "6.2.2"
887 |
888 | [package.dependencies]
889 | pyobjc-core = ">=6.2.2"
890 | pyobjc-framework-Cocoa = ">=6.2.2"
891 |
892 | [[package]]
893 | category = "main"
894 | description = "Wrappers for the framework GameCenter on macOS"
895 | marker = "platform_release >= \"12.0\""
896 | name = "pyobjc-framework-gamecenter"
897 | optional = false
898 | python-versions = ">=3.6"
899 | version = "6.2.2"
900 |
901 | [package.dependencies]
902 | pyobjc-core = ">=6.2.2"
903 | pyobjc-framework-Cocoa = ">=6.2.2"
904 |
905 | [[package]]
906 | category = "main"
907 | description = "Wrappers for the framework GameController on macOS"
908 | marker = "platform_release >= \"13.0\""
909 | name = "pyobjc-framework-gamecontroller"
910 | optional = false
911 | python-versions = ">=3.6"
912 | version = "6.2.2"
913 |
914 | [package.dependencies]
915 | pyobjc-core = ">=6.2.2"
916 | pyobjc-framework-Cocoa = ">=6.2.2"
917 |
918 | [[package]]
919 | category = "main"
920 | description = "Wrappers for the framework GameKit on macOS"
921 | marker = "platform_release >= \"12.0\""
922 | name = "pyobjc-framework-gamekit"
923 | optional = false
924 | python-versions = ">=3.6"
925 | version = "6.2.2"
926 |
927 | [package.dependencies]
928 | pyobjc-core = ">=6.2.2"
929 | pyobjc-framework-Cocoa = ">=6.2.2"
930 | pyobjc-framework-Quartz = ">=6.2.2"
931 |
932 | [[package]]
933 | category = "main"
934 | description = "Wrappers for the framework GameplayKit on macOS"
935 | marker = "platform_release >= \"15.0\""
936 | name = "pyobjc-framework-gameplaykit"
937 | optional = false
938 | python-versions = ">=3.6"
939 | version = "6.2.2"
940 |
941 | [package.dependencies]
942 | pyobjc-core = ">=6.2.2"
943 | pyobjc-framework-Cocoa = ">=6.2.2"
944 | pyobjc-framework-SpriteKit = ">=6.2.2"
945 |
946 | [[package]]
947 | category = "main"
948 | description = "Wrappers for the framework ImageCaptureCore on macOS"
949 | marker = "platform_release >= \"10.0\""
950 | name = "pyobjc-framework-imagecapturecore"
951 | optional = false
952 | python-versions = ">=3.6"
953 | version = "6.2.2"
954 |
955 | [package.dependencies]
956 | pyobjc-core = ">=6.2.2"
957 | pyobjc-framework-Cocoa = ">=6.2.2"
958 |
959 | [[package]]
960 | category = "main"
961 | description = "Wrappers for the framework IMServicePlugIn on macOS"
962 | marker = "platform_release >= \"11.0\""
963 | name = "pyobjc-framework-imserviceplugin"
964 | optional = false
965 | python-versions = ">=3.6"
966 | version = "6.2.2"
967 |
968 | [package.dependencies]
969 | pyobjc-core = ">=6.2.2"
970 | pyobjc-framework-Cocoa = ">=6.2.2"
971 |
972 | [[package]]
973 | category = "main"
974 | description = "Wrappers for the framework InputMethodKit on macOS"
975 | marker = "platform_release >= \"9.0\""
976 | name = "pyobjc-framework-inputmethodkit"
977 | optional = false
978 | python-versions = ">=3.6"
979 | version = "6.2.2"
980 |
981 | [package.dependencies]
982 | pyobjc-core = ">=6.2.2"
983 | pyobjc-framework-Cocoa = ">=6.2.2"
984 |
985 | [[package]]
986 | category = "main"
987 | description = "Wrappers for the framework InstallerPlugins on macOS"
988 | name = "pyobjc-framework-installerplugins"
989 | optional = false
990 | python-versions = ">=3.6"
991 | version = "6.2.2"
992 |
993 | [package.dependencies]
994 | pyobjc-core = ">=6.2.2"
995 | pyobjc-framework-Cocoa = ">=6.2.2"
996 |
997 | [[package]]
998 | category = "main"
999 | description = "Wrappers for the framework InstantMessage on macOS"
1000 | marker = "platform_release >= \"9.0\""
1001 | name = "pyobjc-framework-instantmessage"
1002 | optional = false
1003 | python-versions = ">=3.6"
1004 | version = "6.2.2"
1005 |
1006 | [package.dependencies]
1007 | pyobjc-core = ">=6.2.2"
1008 | pyobjc-framework-Cocoa = ">=6.2.2"
1009 | pyobjc-framework-Quartz = ">=6.2.2"
1010 |
1011 | [[package]]
1012 | category = "main"
1013 | description = "Wrappers for the framework Intents on macOS"
1014 | marker = "platform_release >= \"16.0\""
1015 | name = "pyobjc-framework-intents"
1016 | optional = false
1017 | python-versions = ">=3.6"
1018 | version = "6.2.2"
1019 |
1020 | [package.dependencies]
1021 | pyobjc-core = ">=6.2.2"
1022 | pyobjc-framework-Cocoa = ">=6.2.2"
1023 |
1024 | [[package]]
1025 | category = "main"
1026 | description = "Wrappers for the framework InterfaceBuilderKit on macOS"
1027 | marker = "platform_release >= \"9.0\" and platform_release < \"11.0\""
1028 | name = "pyobjc-framework-interfacebuilderkit"
1029 | optional = false
1030 | python-versions = ">=3.6"
1031 | version = "6.2.2"
1032 |
1033 | [package.dependencies]
1034 | pyobjc-core = ">=6.2.2"
1035 | pyobjc-framework-Cocoa = ">=6.2.2"
1036 |
1037 | [[package]]
1038 | category = "main"
1039 | description = "Wrappers for the framework IOSurface on macOS"
1040 | marker = "platform_release >= \"10.0\""
1041 | name = "pyobjc-framework-iosurface"
1042 | optional = false
1043 | python-versions = ">=3.6"
1044 | version = "6.2.2"
1045 |
1046 | [package.dependencies]
1047 | pyobjc-core = ">=6.2.2"
1048 | pyobjc-framework-Cocoa = ">=6.2.2"
1049 |
1050 | [[package]]
1051 | category = "main"
1052 | description = "Wrappers for the framework iTunesLibrary on macOS"
1053 | marker = "platform_release >= \"10.0\""
1054 | name = "pyobjc-framework-ituneslibrary"
1055 | optional = false
1056 | python-versions = ">=3.6"
1057 | version = "6.2.2"
1058 |
1059 | [package.dependencies]
1060 | pyobjc-core = ">=6.2.2"
1061 | pyobjc-framework-Cocoa = ">=6.2.2"
1062 |
1063 | [[package]]
1064 | category = "main"
1065 | description = "Wrappers for the framework LatentSemanticMapping on macOS"
1066 | name = "pyobjc-framework-latentsemanticmapping"
1067 | optional = false
1068 | python-versions = ">=3.6"
1069 | version = "6.2.2"
1070 |
1071 | [package.dependencies]
1072 | pyobjc-core = ">=6.2.2"
1073 | pyobjc-framework-Cocoa = ">=6.2.2"
1074 |
1075 | [[package]]
1076 | category = "main"
1077 | description = "Wrappers for the framework LaunchServices on macOS"
1078 | name = "pyobjc-framework-launchservices"
1079 | optional = false
1080 | python-versions = ">=3.6"
1081 | version = "6.2.2"
1082 |
1083 | [package.dependencies]
1084 | pyobjc-core = ">=6.2.2"
1085 | pyobjc-framework-CoreServices = ">=6.2.2"
1086 |
1087 | [[package]]
1088 | category = "main"
1089 | description = "Wrappers for libdispatch on macOS"
1090 | marker = "platform_release >= \"12.0\""
1091 | name = "pyobjc-framework-libdispatch"
1092 | optional = false
1093 | python-versions = ">=3.6"
1094 | version = "6.2.2"
1095 |
1096 | [package.dependencies]
1097 | pyobjc-core = ">=6.2.2"
1098 |
1099 | [[package]]
1100 | category = "main"
1101 | description = "Wrappers for the framework LinkPresentation on macOS"
1102 | marker = "platform_release >= \"19.0\""
1103 | name = "pyobjc-framework-linkpresentation"
1104 | optional = false
1105 | python-versions = ">=3.6"
1106 | version = "6.2.2"
1107 |
1108 | [package.dependencies]
1109 | pyobjc-core = ">=6.2.2"
1110 | pyobjc-framework-Cocoa = ">=6.2.2"
1111 | pyobjc-framework-Quartz = ">=6.2.2"
1112 |
1113 | [[package]]
1114 | category = "main"
1115 | description = "Wrappers for the framework LocalAuthentication on macOS"
1116 | marker = "platform_release >= \"14.0\""
1117 | name = "pyobjc-framework-localauthentication"
1118 | optional = false
1119 | python-versions = ">=3.6"
1120 | version = "6.2.2"
1121 |
1122 | [package.dependencies]
1123 | pyobjc-core = ">=6.2.2"
1124 | pyobjc-framework-Cocoa = ">=6.2.2"
1125 |
1126 | [[package]]
1127 | category = "main"
1128 | description = "Wrappers for the framework MapKit on macOS"
1129 | marker = "platform_release >= \"13.0\""
1130 | name = "pyobjc-framework-mapkit"
1131 | optional = false
1132 | python-versions = ">=3.6"
1133 | version = "6.2.2"
1134 |
1135 | [package.dependencies]
1136 | pyobjc-core = ">=6.2.2"
1137 | pyobjc-framework-Cocoa = ">=6.2.2"
1138 | pyobjc-framework-CoreLocation = ">=6.2.2"
1139 | pyobjc-framework-Quartz = ">=6.2.2"
1140 |
1141 | [[package]]
1142 | category = "main"
1143 | description = "Wrappers for the framework MediaAccessibility on macOS"
1144 | marker = "platform_release >= \"13.0\""
1145 | name = "pyobjc-framework-mediaaccessibility"
1146 | optional = false
1147 | python-versions = ">=3.6"
1148 | version = "6.2.2"
1149 |
1150 | [package.dependencies]
1151 | pyobjc-core = ">=6.2.2"
1152 | pyobjc-framework-Cocoa = ">=6.2.2"
1153 |
1154 | [[package]]
1155 | category = "main"
1156 | description = "Wrappers for the framework MediaLibrary on macOS"
1157 | marker = "platform_release >= \"13.0\""
1158 | name = "pyobjc-framework-medialibrary"
1159 | optional = false
1160 | python-versions = ">=3.6"
1161 | version = "6.2.2"
1162 |
1163 | [package.dependencies]
1164 | pyobjc-core = ">=6.2.2"
1165 | pyobjc-framework-Cocoa = ">=6.2.2"
1166 | pyobjc-framework-Quartz = ">=6.2.2"
1167 |
1168 | [[package]]
1169 | category = "main"
1170 | description = "Wrappers for the framework MediaPlayer on macOS"
1171 | marker = "platform_release >= \"16.0\""
1172 | name = "pyobjc-framework-mediaplayer"
1173 | optional = false
1174 | python-versions = ">=3.6"
1175 | version = "6.2.2"
1176 |
1177 | [package.dependencies]
1178 | pyobjc-core = ">=6.2.2"
1179 | pyobjc-framework-AVFoundation = ">=6.2.2"
1180 |
1181 | [[package]]
1182 | category = "main"
1183 | description = "Wrappers for the framework MediaToolbox on macOS"
1184 | marker = "platform_release >= \"13.0\""
1185 | name = "pyobjc-framework-mediatoolbox"
1186 | optional = false
1187 | python-versions = ">=3.6"
1188 | version = "6.2.2"
1189 |
1190 | [package.dependencies]
1191 | pyobjc-core = ">=6.2.2"
1192 | pyobjc-framework-Cocoa = ">=6.2.2"
1193 |
1194 | [[package]]
1195 | category = "main"
1196 | description = "Wrappers for the framework Message on macOS"
1197 | marker = "platform_release < \"13.0\""
1198 | name = "pyobjc-framework-message"
1199 | optional = false
1200 | python-versions = ">=3.6"
1201 | version = "6.2.2"
1202 |
1203 | [package.dependencies]
1204 | pyobjc-core = ">=6.2.2"
1205 | pyobjc-framework-Cocoa = ">=6.2.2"
1206 |
1207 | [[package]]
1208 | category = "main"
1209 | description = "Wrappers for the framework Metal on macOS"
1210 | marker = "platform_release >= \"15.0\""
1211 | name = "pyobjc-framework-metal"
1212 | optional = false
1213 | python-versions = ">=3.6"
1214 | version = "6.2.2"
1215 |
1216 | [package.dependencies]
1217 | pyobjc-core = ">=6.2.2"
1218 | pyobjc-framework-Cocoa = ">=6.2.2"
1219 |
1220 | [[package]]
1221 | category = "main"
1222 | description = "Wrappers for the framework MetalKit on macOS"
1223 | marker = "platform_release >= \"15.0\""
1224 | name = "pyobjc-framework-metalkit"
1225 | optional = false
1226 | python-versions = ">=3.6"
1227 | version = "6.2.2"
1228 |
1229 | [package.dependencies]
1230 | pyobjc-core = ">=6.2.2"
1231 | pyobjc-framework-Cocoa = ">=6.2.2"
1232 | pyobjc-framework-Metal = ">=6.2.2"
1233 |
1234 | [[package]]
1235 | category = "main"
1236 | description = "Wrappers for the framework ModelIO on macOS"
1237 | marker = "platform_release >= \"15.0\""
1238 | name = "pyobjc-framework-modelio"
1239 | optional = false
1240 | python-versions = ">=3.6"
1241 | version = "6.2.2"
1242 |
1243 | [package.dependencies]
1244 | pyobjc-core = ">=6.2.2"
1245 | pyobjc-framework-Cocoa = ">=6.2.2"
1246 | pyobjc-framework-Quartz = ">=6.2.2"
1247 |
1248 | [[package]]
1249 | category = "main"
1250 | description = "Wrappers for the framework MultipeerConnectivity on macOS"
1251 | marker = "platform_release >= \"14.0\""
1252 | name = "pyobjc-framework-multipeerconnectivity"
1253 | optional = false
1254 | python-versions = ">=3.6"
1255 | version = "6.2.2"
1256 |
1257 | [package.dependencies]
1258 | pyobjc-core = ">=6.2.2"
1259 | pyobjc-framework-Cocoa = ">=6.2.2"
1260 |
1261 | [[package]]
1262 | category = "main"
1263 | description = "Wrappers for the framework NaturalLanguage on macOS"
1264 | marker = "platform_release >= \"18.0\""
1265 | name = "pyobjc-framework-naturallanguage"
1266 | optional = false
1267 | python-versions = ">=3.6"
1268 | version = "6.2.2"
1269 |
1270 | [package.dependencies]
1271 | pyobjc-core = ">=6.2.2"
1272 | pyobjc-framework-Cocoa = ">=6.2.2"
1273 |
1274 | [[package]]
1275 | category = "main"
1276 | description = "Wrappers for the framework NetFS on macOS"
1277 | marker = "platform_release >= \"10.0\""
1278 | name = "pyobjc-framework-netfs"
1279 | optional = false
1280 | python-versions = ">=3.6"
1281 | version = "6.2.2"
1282 |
1283 | [package.dependencies]
1284 | pyobjc-core = ">=6.2.2"
1285 | pyobjc-framework-Cocoa = ">=6.2.2"
1286 |
1287 | [[package]]
1288 | category = "main"
1289 | description = "Wrappers for the framework Network on macOS"
1290 | marker = "platform_release >= \"18.0\""
1291 | name = "pyobjc-framework-network"
1292 | optional = false
1293 | python-versions = ">=3.6"
1294 | version = "6.2.2"
1295 |
1296 | [package.dependencies]
1297 | pyobjc-core = ">=6.2.2"
1298 | pyobjc-framework-Cocoa = ">=6.2.2"
1299 |
1300 | [[package]]
1301 | category = "main"
1302 | description = "Wrappers for the framework NetworkExtension on macOS"
1303 | marker = "platform_release >= \"15.0\""
1304 | name = "pyobjc-framework-networkextension"
1305 | optional = false
1306 | python-versions = ">=3.6"
1307 | version = "6.2.2"
1308 |
1309 | [package.dependencies]
1310 | pyobjc-core = ">=6.2.2"
1311 | pyobjc-framework-Cocoa = ">=6.2.2"
1312 |
1313 | [[package]]
1314 | category = "main"
1315 | description = "Wrappers for the framework NotificationCenter on macOS"
1316 | marker = "platform_release >= \"14.0\""
1317 | name = "pyobjc-framework-notificationcenter"
1318 | optional = false
1319 | python-versions = ">=3.6"
1320 | version = "6.2.2"
1321 |
1322 | [package.dependencies]
1323 | pyobjc-core = ">=6.2.2"
1324 | pyobjc-framework-Cocoa = ">=6.2.2"
1325 |
1326 | [[package]]
1327 | category = "main"
1328 | description = "Wrappers for the framework OpenDirectory on macOS"
1329 | marker = "platform_release >= \"10.0\""
1330 | name = "pyobjc-framework-opendirectory"
1331 | optional = false
1332 | python-versions = ">=3.6"
1333 | version = "6.2.2"
1334 |
1335 | [package.dependencies]
1336 | pyobjc-core = ">=6.2.2"
1337 | pyobjc-framework-Cocoa = ">=6.2.2"
1338 |
1339 | [[package]]
1340 | category = "main"
1341 | description = "Wrappers for the framework OSAKit on macOS"
1342 | name = "pyobjc-framework-osakit"
1343 | optional = false
1344 | python-versions = ">=3.6"
1345 | version = "6.2.2"
1346 |
1347 | [package.dependencies]
1348 | pyobjc-core = ">=6.2.2"
1349 | pyobjc-framework-Cocoa = ">=6.2.2"
1350 |
1351 | [[package]]
1352 | category = "main"
1353 | description = "Wrappers for the framework OSLog on macOS"
1354 | marker = "platform_release >= \"19.0\""
1355 | name = "pyobjc-framework-oslog"
1356 | optional = false
1357 | python-versions = ">=3.6"
1358 | version = "6.2.2"
1359 |
1360 | [package.dependencies]
1361 | pyobjc-core = ">=6.2.2"
1362 | pyobjc-framework-Cocoa = ">=6.2.2"
1363 | pyobjc-framework-CoreMedia = ">=6.2.2"
1364 | pyobjc-framework-Quartz = ">=6.2.2"
1365 |
1366 | [[package]]
1367 | category = "main"
1368 | description = "Wrappers for the framework PencilKit on macOS"
1369 | marker = "platform_release >= \"19.0\""
1370 | name = "pyobjc-framework-pencilkit"
1371 | optional = false
1372 | python-versions = ">=3.6"
1373 | version = "6.2.2"
1374 |
1375 | [package.dependencies]
1376 | pyobjc-core = ">=6.2.2"
1377 | pyobjc-framework-Cocoa = ">=6.2.2"
1378 |
1379 | [[package]]
1380 | category = "main"
1381 | description = "Wrappers for the framework Photos on macOS"
1382 | marker = "platform_release >= \"15.0\""
1383 | name = "pyobjc-framework-photos"
1384 | optional = false
1385 | python-versions = ">=3.6"
1386 | version = "6.2.2"
1387 |
1388 | [package.dependencies]
1389 | pyobjc-core = ">=6.2.2"
1390 | pyobjc-framework-Cocoa = ">=6.2.2"
1391 |
1392 | [[package]]
1393 | category = "main"
1394 | description = "Wrappers for the framework PhotosUI on macOS"
1395 | marker = "platform_release >= \"15.0\""
1396 | name = "pyobjc-framework-photosui"
1397 | optional = false
1398 | python-versions = ">=3.6"
1399 | version = "6.2.2"
1400 |
1401 | [package.dependencies]
1402 | pyobjc-core = ">=6.2.2"
1403 | pyobjc-framework-Cocoa = ">=6.2.2"
1404 |
1405 | [[package]]
1406 | category = "main"
1407 | description = "Wrappers for the framework PreferencePanes on macOS"
1408 | name = "pyobjc-framework-preferencepanes"
1409 | optional = false
1410 | python-versions = ">=3.6"
1411 | version = "6.2.2"
1412 |
1413 | [package.dependencies]
1414 | pyobjc-core = ">=6.2.2"
1415 | pyobjc-framework-Cocoa = ">=6.2.2"
1416 |
1417 | [[package]]
1418 | category = "main"
1419 | description = "Wrappers for the framework PubSub on macOS"
1420 | marker = "platform_release >= \"9.0\" and platform_release < \"18.0\""
1421 | name = "pyobjc-framework-pubsub"
1422 | optional = false
1423 | python-versions = ">=3.6"
1424 | version = "6.2.2"
1425 |
1426 | [package.dependencies]
1427 | pyobjc-core = ">=6.2.2"
1428 | pyobjc-framework-Cocoa = ">=6.2.2"
1429 |
1430 | [[package]]
1431 | category = "main"
1432 | description = "Wrappers for the framework PushKit on macOS"
1433 | marker = "platform_release >= \"19.0\""
1434 | name = "pyobjc-framework-pushkit"
1435 | optional = false
1436 | python-versions = ">=3.6"
1437 | version = "6.2.2"
1438 |
1439 | [package.dependencies]
1440 | pyobjc-core = ">=6.2.2"
1441 | pyobjc-framework-Cocoa = ">=6.2.2"
1442 |
1443 | [[package]]
1444 | category = "main"
1445 | description = "Wrappers for the framework QTKit on macOS"
1446 | marker = "platform_release >= \"9.0\" and platform_release < \"19.0\""
1447 | name = "pyobjc-framework-qtkit"
1448 | optional = false
1449 | python-versions = ">=3.6"
1450 | version = "6.2.2"
1451 |
1452 | [package.dependencies]
1453 | pyobjc-core = ">=6.2.2"
1454 | pyobjc-framework-Cocoa = ">=6.2.2"
1455 | pyobjc-framework-Quartz = ">=6.2.2"
1456 |
1457 | [[package]]
1458 | category = "main"
1459 | description = "Wrappers for the Quartz frameworks on macOS"
1460 | name = "pyobjc-framework-quartz"
1461 | optional = false
1462 | python-versions = ">=3.6"
1463 | version = "6.2.2"
1464 |
1465 | [package.dependencies]
1466 | pyobjc-core = ">=6.2.2"
1467 | pyobjc-framework-Cocoa = ">=6.2.2"
1468 |
1469 | [[package]]
1470 | category = "main"
1471 | description = "Wrappers for the framework QuickLookThumbnailing on macOS"
1472 | marker = "platform_release >= \"19.0\""
1473 | name = "pyobjc-framework-quicklookthumbnailing"
1474 | optional = false
1475 | python-versions = ">=3.6"
1476 | version = "6.2.2"
1477 |
1478 | [package.dependencies]
1479 | pyobjc-core = ">=6.2.2"
1480 | pyobjc-framework-Cocoa = ">=6.2.2"
1481 | pyobjc-framework-Quartz = ">=6.2.2"
1482 |
1483 | [[package]]
1484 | category = "main"
1485 | description = "Wrappers for the framework SafariServices on macOS"
1486 | marker = "platform_release >= \"15.0\""
1487 | name = "pyobjc-framework-safariservices"
1488 | optional = false
1489 | python-versions = ">=3.6"
1490 | version = "6.2.2"
1491 |
1492 | [package.dependencies]
1493 | pyobjc-core = ">=6.2.2"
1494 | pyobjc-framework-Cocoa = ">=6.2.2"
1495 |
1496 | [[package]]
1497 | category = "main"
1498 | description = "Wrappers for the framework SceneKit on macOS"
1499 | marker = "platform_release >= \"11.0\""
1500 | name = "pyobjc-framework-scenekit"
1501 | optional = false
1502 | python-versions = ">=3.6"
1503 | version = "6.2.2"
1504 |
1505 | [package.dependencies]
1506 | pyobjc-core = ">=6.2.2"
1507 | pyobjc-framework-Cocoa = ">=6.2.2"
1508 | pyobjc-framework-Quartz = ">=6.2.2"
1509 |
1510 | [[package]]
1511 | category = "main"
1512 | description = "Wrappers for the framework ScreenSaver on macOS"
1513 | name = "pyobjc-framework-screensaver"
1514 | optional = false
1515 | python-versions = ">=3.6"
1516 | version = "6.2.2"
1517 |
1518 | [package.dependencies]
1519 | pyobjc-core = ">=6.2.2"
1520 | pyobjc-framework-Cocoa = ">=6.2.2"
1521 |
1522 | [[package]]
1523 | category = "main"
1524 | description = "Wrappers for the framework ScriptingBridge on macOS"
1525 | marker = "platform_release >= \"9.0\""
1526 | name = "pyobjc-framework-scriptingbridge"
1527 | optional = false
1528 | python-versions = ">=3.6"
1529 | version = "6.2.2"
1530 |
1531 | [package.dependencies]
1532 | pyobjc-core = ">=6.2.2"
1533 | pyobjc-framework-Cocoa = ">=6.2.2"
1534 |
1535 | [[package]]
1536 | category = "main"
1537 | description = "Wrappers for the framework SearchKit on macOS"
1538 | name = "pyobjc-framework-searchkit"
1539 | optional = false
1540 | python-versions = ">=3.6"
1541 | version = "6.2.2"
1542 |
1543 | [package.dependencies]
1544 | pyobjc-core = ">=6.2.2"
1545 | pyobjc-framework-CoreServices = ">=6.2.2"
1546 |
1547 | [[package]]
1548 | category = "main"
1549 | description = "Wrappers for the framework Security on macOS"
1550 | name = "pyobjc-framework-security"
1551 | optional = false
1552 | python-versions = ">=3.6"
1553 | version = "6.2.2"
1554 |
1555 | [package.dependencies]
1556 | pyobjc-core = ">=6.2.2"
1557 | pyobjc-framework-Cocoa = ">=6.2.2"
1558 |
1559 | [[package]]
1560 | category = "main"
1561 | description = "Wrappers for the framework SecurityFoundation on macOS"
1562 | name = "pyobjc-framework-securityfoundation"
1563 | optional = false
1564 | python-versions = ">=3.6"
1565 | version = "6.2.2"
1566 |
1567 | [package.dependencies]
1568 | pyobjc-core = ">=6.2.2"
1569 | pyobjc-framework-Cocoa = ">=6.2.2"
1570 | pyobjc-framework-Security = ">=6.2.2"
1571 |
1572 | [[package]]
1573 | category = "main"
1574 | description = "Wrappers for the framework SecurityInterface on macOS"
1575 | name = "pyobjc-framework-securityinterface"
1576 | optional = false
1577 | python-versions = ">=3.6"
1578 | version = "6.2.2"
1579 |
1580 | [package.dependencies]
1581 | pyobjc-core = ">=6.2.2"
1582 | pyobjc-framework-Cocoa = ">=6.2.2"
1583 | pyobjc-framework-Security = ">=6.2.2"
1584 |
1585 | [[package]]
1586 | category = "main"
1587 | description = "Wrappers for the framework ServerNotification on macOS"
1588 | marker = "platform_release >= \"10.0\" and platform_release < \"13.0\""
1589 | name = "pyobjc-framework-servernotification"
1590 | optional = false
1591 | python-versions = ">=3.6"
1592 | version = "6.2.2"
1593 |
1594 | [package.dependencies]
1595 | pyobjc-core = ">=6.2.2"
1596 | pyobjc-framework-Cocoa = ">=6.2.2"
1597 |
1598 | [[package]]
1599 | category = "main"
1600 | description = "Wrappers for the framework ServiceManagement on macOS"
1601 | marker = "platform_release >= \"10.0\""
1602 | name = "pyobjc-framework-servicemanagement"
1603 | optional = false
1604 | python-versions = ">=3.6"
1605 | version = "6.2.2"
1606 |
1607 | [package.dependencies]
1608 | pyobjc-core = ">=6.2.2"
1609 | pyobjc-framework-Cocoa = ">=6.2.2"
1610 |
1611 | [[package]]
1612 | category = "main"
1613 | description = "Wrappers for the framework Social on macOS"
1614 | marker = "platform_release >= \"12.0\""
1615 | name = "pyobjc-framework-social"
1616 | optional = false
1617 | python-versions = ">=3.6"
1618 | version = "6.2.2"
1619 |
1620 | [package.dependencies]
1621 | pyobjc-core = ">=6.2.2"
1622 | pyobjc-framework-Cocoa = ">=6.2.2"
1623 |
1624 | [[package]]
1625 | category = "main"
1626 | description = "Wrappers for the framework SoundAnalysis on macOS"
1627 | marker = "platform_release >= \"19.0\""
1628 | name = "pyobjc-framework-soundanalysis"
1629 | optional = false
1630 | python-versions = ">=3.6"
1631 | version = "6.2.2"
1632 |
1633 | [package.dependencies]
1634 | pyobjc-core = ">=6.2.2"
1635 | pyobjc-framework-Cocoa = ">=6.2.2"
1636 |
1637 | [[package]]
1638 | category = "main"
1639 | description = "Wrappers for the framework Speech on macOS"
1640 | marker = "platform_release >= \"19.0\""
1641 | name = "pyobjc-framework-speech"
1642 | optional = false
1643 | python-versions = ">=3.6"
1644 | version = "6.2.2"
1645 |
1646 | [package.dependencies]
1647 | pyobjc-core = ">=6.2.2"
1648 | pyobjc-framework-Cocoa = ">=6.2.2"
1649 |
1650 | [[package]]
1651 | category = "main"
1652 | description = "Wrappers for the framework SpriteKit on macOS"
1653 | marker = "platform_release >= \"13.0\" or platform_release >= \"15.0\""
1654 | name = "pyobjc-framework-spritekit"
1655 | optional = false
1656 | python-versions = ">=3.6"
1657 | version = "6.2.2"
1658 |
1659 | [package.dependencies]
1660 | pyobjc-core = ">=6.2.2"
1661 | pyobjc-framework-Cocoa = ">=6.2.2"
1662 | pyobjc-framework-Quartz = ">=6.2.2"
1663 |
1664 | [[package]]
1665 | category = "main"
1666 | description = "Wrappers for the framework StoreKit on macOS"
1667 | marker = "platform_release >= \"11.0\""
1668 | name = "pyobjc-framework-storekit"
1669 | optional = false
1670 | python-versions = ">=3.6"
1671 | version = "6.2.2"
1672 |
1673 | [package.dependencies]
1674 | pyobjc-core = ">=6.2.2"
1675 | pyobjc-framework-Cocoa = ">=6.2.2"
1676 |
1677 | [[package]]
1678 | category = "main"
1679 | description = "Wrappers for the framework SyncServices on macOS"
1680 | name = "pyobjc-framework-syncservices"
1681 | optional = false
1682 | python-versions = ">=3.6"
1683 | version = "6.2.2"
1684 |
1685 | [package.dependencies]
1686 | pyobjc-core = ">=6.2.2"
1687 | pyobjc-framework-Cocoa = ">=6.2.2"
1688 | pyobjc-framework-CoreData = ">=6.2.2"
1689 |
1690 | [[package]]
1691 | category = "main"
1692 | description = "Wrappers for the framework SystemConfiguration on macOS"
1693 | name = "pyobjc-framework-systemconfiguration"
1694 | optional = false
1695 | python-versions = ">=3.6"
1696 | version = "6.2.2"
1697 |
1698 | [package.dependencies]
1699 | pyobjc-core = ">=6.2.2"
1700 | pyobjc-framework-Cocoa = ">=6.2.2"
1701 |
1702 | [[package]]
1703 | category = "main"
1704 | description = "Wrappers for the framework SystemExtensions on macOS"
1705 | marker = "platform_release >= \"19.0\""
1706 | name = "pyobjc-framework-systemextensions"
1707 | optional = false
1708 | python-versions = ">=3.6"
1709 | version = "6.2.2"
1710 |
1711 | [package.dependencies]
1712 | pyobjc-core = ">=6.2.2"
1713 | pyobjc-framework-Cocoa = ">=6.2.2"
1714 |
1715 | [[package]]
1716 | category = "main"
1717 | description = "Wrappers for the framework UserNotifications on macOS"
1718 | marker = "platform_release >= \"18.0\""
1719 | name = "pyobjc-framework-usernotifications"
1720 | optional = false
1721 | python-versions = ">=3.6"
1722 | version = "6.2.2"
1723 |
1724 | [package.dependencies]
1725 | pyobjc-core = ">=6.2.2"
1726 | pyobjc-framework-Cocoa = ">=6.2.2"
1727 |
1728 | [[package]]
1729 | category = "main"
1730 | description = "Wrappers for the framework VideoSubscriberAccount on macOS"
1731 | marker = "platform_release >= \"18.0\""
1732 | name = "pyobjc-framework-videosubscriberaccount"
1733 | optional = false
1734 | python-versions = ">=3.6"
1735 | version = "6.2.2"
1736 |
1737 | [package.dependencies]
1738 | pyobjc-core = ">=6.2.2"
1739 | pyobjc-framework-Cocoa = ">=6.2.2"
1740 |
1741 | [[package]]
1742 | category = "main"
1743 | description = "Wrappers for the framework VideoToolbox on macOS"
1744 | marker = "platform_release >= \"12.0\""
1745 | name = "pyobjc-framework-videotoolbox"
1746 | optional = false
1747 | python-versions = ">=3.6"
1748 | version = "6.2.2"
1749 |
1750 | [package.dependencies]
1751 | pyobjc-core = ">=6.2.2"
1752 | pyobjc-framework-Cocoa = ">=6.2.2"
1753 | pyobjc-framework-CoreMedia = ">=6.2.2"
1754 | pyobjc-framework-Quartz = ">=6.2.2"
1755 |
1756 | [[package]]
1757 | category = "main"
1758 | description = "Wrappers for the framework Vision on macOS"
1759 | marker = "platform_release >= \"17.0\""
1760 | name = "pyobjc-framework-vision"
1761 | optional = false
1762 | python-versions = ">=3.6"
1763 | version = "6.2.2"
1764 |
1765 | [package.dependencies]
1766 | pyobjc-core = ">=6.2.2"
1767 | pyobjc-framework-Cocoa = ">=6.2.2"
1768 | pyobjc-framework-CoreML = ">=6.2.2"
1769 | pyobjc-framework-Quartz = ">=6.2.2"
1770 |
1771 | [[package]]
1772 | category = "main"
1773 | description = "Wrappers for the framework WebKit on macOS"
1774 | name = "pyobjc-framework-webkit"
1775 | optional = false
1776 | python-versions = ">=3.6"
1777 | version = "6.2.2"
1778 |
1779 | [package.dependencies]
1780 | pyobjc-core = ">=6.2.2"
1781 | pyobjc-framework-Cocoa = ">=6.2.2"
1782 |
1783 | [[package]]
1784 | category = "main"
1785 | description = "Wrappers for the framework XgridFoundation on macOS"
1786 | marker = "platform_release < \"12.0\""
1787 | name = "pyobjc-framework-xgridfoundation"
1788 | optional = false
1789 | python-versions = ">=3.6"
1790 | version = "6.2.2"
1791 |
1792 | [package.dependencies]
1793 | pyobjc-core = ">=6.2.2"
1794 | pyobjc-framework-Cocoa = ">=6.2.2"
1795 |
1796 | [[package]]
1797 | category = "dev"
1798 | description = "YAML parser and emitter for Python"
1799 | name = "pyyaml"
1800 | optional = false
1801 | python-versions = "*"
1802 | version = "5.3.1"
1803 |
1804 | [[package]]
1805 | category = "dev"
1806 | description = "Python 2 and 3 compatibility utilities"
1807 | name = "six"
1808 | optional = false
1809 | python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*"
1810 | version = "1.15.0"
1811 |
1812 | [[package]]
1813 | category = "dev"
1814 | description = "Python Library for Tom's Obvious, Minimal Language"
1815 | name = "toml"
1816 | optional = false
1817 | python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*"
1818 | version = "0.10.2"
1819 |
1820 | [[package]]
1821 | category = "dev"
1822 | description = "Virtual Python Environment builder"
1823 | name = "virtualenv"
1824 | optional = false
1825 | python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7"
1826 | version = "20.1.0"
1827 |
1828 | [package.dependencies]
1829 | appdirs = ">=1.4.3,<2"
1830 | distlib = ">=0.3.1,<1"
1831 | filelock = ">=3.0.0,<4"
1832 | six = ">=1.9.0,<2"
1833 |
1834 | [package.dependencies.importlib-metadata]
1835 | python = "<3.8"
1836 | version = ">=0.12,<3"
1837 |
1838 | [package.extras]
1839 | docs = ["proselint (>=0.10.2)", "sphinx (>=3)", "sphinx-argparse (>=0.2.5)", "sphinx-rtd-theme (>=0.4.3)", "towncrier (>=19.9.0rc1)"]
1840 | testing = ["coverage (>=4)", "coverage-enable-subprocess (>=1)", "flaky (>=3)", "pytest (>=4)", "pytest-env (>=0.6.2)", "pytest-freezegun (>=0.4.1)", "pytest-mock (>=2)", "pytest-randomly (>=1)", "pytest-timeout (>=1)", "pytest-xdist (>=1.31.0)", "packaging (>=20.0)", "xonsh (>=0.9.16)"]
1841 |
1842 | [[package]]
1843 | category = "dev"
1844 | description = "Backport of pathlib-compatible object wrapper for zip files"
1845 | marker = "python_version < \"3.8\""
1846 | name = "zipp"
1847 | optional = false
1848 | python-versions = ">=3.6"
1849 | version = "3.4.0"
1850 |
1851 | [package.extras]
1852 | docs = ["sphinx", "jaraco.packaging (>=3.2)", "rst.linker (>=1.9)"]
1853 | testing = ["pytest (>=3.5,<3.7.3 || >3.7.3)", "pytest-checkdocs (>=1.2.3)", "pytest-flake8", "pytest-cov", "jaraco.test (>=3.2.0)", "jaraco.itertools", "func-timeout", "pytest-black (>=0.3.7)", "pytest-mypy"]
1854 |
1855 | [metadata]
1856 | content-hash = "52a303f8a3758c1a102f432f4f212b645646a0a5970689df387c8d4c3533d5b4"
1857 | python-versions = "^3.7"
1858 |
1859 | [metadata.files]
1860 | appdirs = [
1861 | {file = "appdirs-1.4.4-py2.py3-none-any.whl", hash = "sha256:a841dacd6b99318a741b166adb07e19ee71a274450e68237b4650ca1055ab128"},
1862 | {file = "appdirs-1.4.4.tar.gz", hash = "sha256:7d5d0167b2b1ba821647616af46a749d1c653740dd0d2415100fe26e27afdf41"},
1863 | ]
1864 | "aspy.yaml" = [
1865 | {file = "aspy.yaml-1.3.0-py2.py3-none-any.whl", hash = "sha256:463372c043f70160a9ec950c3f1e4c3a82db5fca01d334b6bc89c7164d744bdc"},
1866 | {file = "aspy.yaml-1.3.0.tar.gz", hash = "sha256:e7c742382eff2caed61f87a39d13f99109088e5e93f04d76eb8d4b28aa143f45"},
1867 | ]
1868 | cfgv = [
1869 | {file = "cfgv-3.2.0-py2.py3-none-any.whl", hash = "sha256:32e43d604bbe7896fe7c248a9c2276447dbef840feb28fe20494f62af110211d"},
1870 | {file = "cfgv-3.2.0.tar.gz", hash = "sha256:cf22deb93d4bcf92f345a5c3cd39d3d41d6340adc60c78bbbd6588c384fda6a1"},
1871 | ]
1872 | click = [
1873 | {file = "click-7.1.2-py2.py3-none-any.whl", hash = "sha256:dacca89f4bfadd5de3d7489b7c8a566eee0d3676333fbb50030263894c38c0dc"},
1874 | {file = "click-7.1.2.tar.gz", hash = "sha256:d2b5255c7c6349bc1bd1e59e08cd12acbbd63ce649f2588755783aa94dfb6b1a"},
1875 | ]
1876 | distlib = [
1877 | {file = "distlib-0.3.1-py2.py3-none-any.whl", hash = "sha256:8c09de2c67b3e7deef7184574fc060ab8a793e7adbb183d942c389c8b13c52fb"},
1878 | {file = "distlib-0.3.1.zip", hash = "sha256:edf6116872c863e1aa9d5bb7cb5e05a022c519a4594dc703843343a9ddd9bff1"},
1879 | ]
1880 | filelock = [
1881 | {file = "filelock-3.0.12-py3-none-any.whl", hash = "sha256:929b7d63ec5b7d6b71b0fa5ac14e030b3f70b75747cef1b10da9b879fef15836"},
1882 | {file = "filelock-3.0.12.tar.gz", hash = "sha256:18d82244ee114f543149c66a6e0c14e9c4f8a1044b5cdaadd0f82159d6a6ff59"},
1883 | ]
1884 | identify = [
1885 | {file = "identify-1.5.9-py2.py3-none-any.whl", hash = "sha256:5dd84ac64a9a115b8e0b27d1756b244b882ad264c3c423f42af8235a6e71ca12"},
1886 | {file = "identify-1.5.9.tar.gz", hash = "sha256:c9504ba6a043ee2db0a9d69e43246bc138034895f6338d5aed1b41e4a73b1513"},
1887 | ]
1888 | importlib-metadata = [
1889 | {file = "importlib_metadata-2.0.0-py2.py3-none-any.whl", hash = "sha256:cefa1a2f919b866c5beb7c9f7b0ebb4061f30a8a9bf16d609b000e2dfaceb9c3"},
1890 | {file = "importlib_metadata-2.0.0.tar.gz", hash = "sha256:77a540690e24b0305878c37ffd421785a6f7e53c8b5720d211b211de8d0e95da"},
1891 | ]
1892 | mutagen = [
1893 | {file = "mutagen-1.45.1-py3-none-any.whl", hash = "sha256:9c9f243fcec7f410f138cb12c21c84c64fde4195481a30c9bfb05b5f003adfed"},
1894 | {file = "mutagen-1.45.1.tar.gz", hash = "sha256:6397602efb3c2d7baebd2166ed85731ae1c1d475abca22090b7141ff5034b3e1"},
1895 | ]
1896 | nodeenv = [
1897 | {file = "nodeenv-1.5.0-py2.py3-none-any.whl", hash = "sha256:5304d424c529c997bc888453aeaa6362d242b6b4631e90f3d4bf1b290f1c84a9"},
1898 | {file = "nodeenv-1.5.0.tar.gz", hash = "sha256:ab45090ae383b716c4ef89e690c41ff8c2b257b85b309f01f3654df3d084bd7c"},
1899 | ]
1900 | pillow = [
1901 | {file = "Pillow-8.0.1-cp36-cp36m-macosx_10_10_x86_64.whl", hash = "sha256:b63d4ff734263ae4ce6593798bcfee6dbfb00523c82753a3a03cbc05555a9cc3"},
1902 | {file = "Pillow-8.0.1-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:5f9403af9c790cc18411ea398a6950ee2def2a830ad0cfe6dc9122e6d528b302"},
1903 | {file = "Pillow-8.0.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:6b4a8fd632b4ebee28282a9fef4c341835a1aa8671e2770b6f89adc8e8c2703c"},
1904 | {file = "Pillow-8.0.1-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:cc3ea6b23954da84dbee8025c616040d9aa5eaf34ea6895a0a762ee9d3e12e11"},
1905 | {file = "Pillow-8.0.1-cp36-cp36m-win32.whl", hash = "sha256:d8a96747df78cda35980905bf26e72960cba6d355ace4780d4bdde3b217cdf1e"},
1906 | {file = "Pillow-8.0.1-cp36-cp36m-win_amd64.whl", hash = "sha256:7ba0ba61252ab23052e642abdb17fd08fdcfdbbf3b74c969a30c58ac1ade7cd3"},
1907 | {file = "Pillow-8.0.1-cp37-cp37m-macosx_10_10_x86_64.whl", hash = "sha256:795e91a60f291e75de2e20e6bdd67770f793c8605b553cb6e4387ce0cb302e09"},
1908 | {file = "Pillow-8.0.1-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:0a2e8d03787ec7ad71dc18aec9367c946ef8ef50e1e78c71f743bc3a770f9fae"},
1909 | {file = "Pillow-8.0.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:006de60d7580d81f4a1a7e9f0173dc90a932e3905cc4d47ea909bc946302311a"},
1910 | {file = "Pillow-8.0.1-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:bd7bf289e05470b1bc74889d1466d9ad4a56d201f24397557b6f65c24a6844b8"},
1911 | {file = "Pillow-8.0.1-cp37-cp37m-win32.whl", hash = "sha256:95edb1ed513e68bddc2aee3de66ceaf743590bf16c023fb9977adc4be15bd3f0"},
1912 | {file = "Pillow-8.0.1-cp37-cp37m-win_amd64.whl", hash = "sha256:e38d58d9138ef972fceb7aeec4be02e3f01d383723965bfcef14d174c8ccd039"},
1913 | {file = "Pillow-8.0.1-cp38-cp38-macosx_10_10_x86_64.whl", hash = "sha256:d3d07c86d4efa1facdf32aa878bd508c0dc4f87c48125cc16b937baa4e5b5e11"},
1914 | {file = "Pillow-8.0.1-cp38-cp38-manylinux1_i686.whl", hash = "sha256:fbd922f702582cb0d71ef94442bfca57624352622d75e3be7a1e7e9360b07e72"},
1915 | {file = "Pillow-8.0.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:92c882b70a40c79de9f5294dc99390671e07fc0b0113d472cbea3fde15db1792"},
1916 | {file = "Pillow-8.0.1-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:7c9401e68730d6c4245b8e361d3d13e1035cbc94db86b49dc7da8bec235d0015"},
1917 | {file = "Pillow-8.0.1-cp38-cp38-win32.whl", hash = "sha256:6c1aca8231625115104a06e4389fcd9ec88f0c9befbabd80dc206c35561be271"},
1918 | {file = "Pillow-8.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:cc9ec588c6ef3a1325fa032ec14d97b7309db493782ea8c304666fb10c3bd9a7"},
1919 | {file = "Pillow-8.0.1-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:eb472586374dc66b31e36e14720747595c2b265ae962987261f044e5cce644b5"},
1920 | {file = "Pillow-8.0.1-cp39-cp39-manylinux1_i686.whl", hash = "sha256:0eeeae397e5a79dc088d8297a4c2c6f901f8fb30db47795113a4a605d0f1e5ce"},
1921 | {file = "Pillow-8.0.1-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:81f812d8f5e8a09b246515fac141e9d10113229bc33ea073fec11403b016bcf3"},
1922 | {file = "Pillow-8.0.1-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:895d54c0ddc78a478c80f9c438579ac15f3e27bf442c2a9aa74d41d0e4d12544"},
1923 | {file = "Pillow-8.0.1-cp39-cp39-win32.whl", hash = "sha256:2fb113757a369a6cdb189f8df3226e995acfed0a8919a72416626af1a0a71140"},
1924 | {file = "Pillow-8.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:59e903ca800c8cfd1ebe482349ec7c35687b95e98cefae213e271c8c7fffa021"},
1925 | {file = "Pillow-8.0.1-pp36-pypy36_pp73-macosx_10_10_x86_64.whl", hash = "sha256:5abd653a23c35d980b332bc0431d39663b1709d64142e3652890df4c9b6970f6"},
1926 | {file = "Pillow-8.0.1-pp36-pypy36_pp73-manylinux2010_x86_64.whl", hash = "sha256:4b0ef2470c4979e345e4e0cc1bbac65fda11d0d7b789dbac035e4c6ce3f98adb"},
1927 | {file = "Pillow-8.0.1-pp37-pypy37_pp73-win32.whl", hash = "sha256:8de332053707c80963b589b22f8e0229f1be1f3ca862a932c1bcd48dafb18dd8"},
1928 | {file = "Pillow-8.0.1.tar.gz", hash = "sha256:11c5c6e9b02c9dac08af04f093eb5a2f84857df70a7d4a6a6ad461aca803fb9e"},
1929 | ]
1930 | pre-commit = [
1931 | {file = "pre_commit-1.21.0-py2.py3-none-any.whl", hash = "sha256:f92a359477f3252452ae2e8d3029de77aec59415c16ae4189bcfba40b757e029"},
1932 | {file = "pre_commit-1.21.0.tar.gz", hash = "sha256:8f48d8637bdae6fa70cc97db9c1dd5aa7c5c8bf71968932a380628c25978b850"},
1933 | ]
1934 | pyobjc = [
1935 | {file = "pyobjc-6.2.2-py3-none-any.whl", hash = "sha256:dc2e4fb96bc48770c1b5810eb65bf446c50fbf2faf6a6a398c31556b404e015c"},
1936 | {file = "pyobjc-6.2.2.tar.gz", hash = "sha256:d5b87e9fa4cc9b51bf37f9a461887e2d8b9ae7e6bb45675f8edbe35ea6770455"},
1937 | ]
1938 | pyobjc-core = [
1939 | {file = "pyobjc-core-6.2.2.tar.gz", hash = "sha256:38e7b15a042439dadd18b28b78229e52fb882460fc16ddbae342b9972d5a827c"},
1940 | {file = "pyobjc_core-6.2.2-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:73938398559b718595076fce4921022f21983dd85ebace3ecbe6182697abe164"},
1941 | {file = "pyobjc_core-6.2.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:60d0c57de915b6ed91a9a26e3bdefdcaeb1288623c69f291338208c5a227d190"},
1942 | {file = "pyobjc_core-6.2.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:be312b7a0edb45dd8ea68e70f2b411b59677d4ceb513c48eace73cb78dbfd85f"},
1943 | {file = "pyobjc_core-6.2.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:47a89171d218905dbf13011b1a7d698c246cb66fb5f14119bc0d9e039d0486fa"},
1944 | ]
1945 | pyobjc-framework-accounts = [
1946 | {file = "pyobjc-framework-Accounts-6.2.2.tar.gz", hash = "sha256:9ecf1d03f856617b3ace091bd844ab8ae3f6122ed83cffd4a2c067da19ea2386"},
1947 | {file = "pyobjc_framework_Accounts-6.2.2-py2.py3-none-any.whl", hash = "sha256:2dfe6c2d02f0f4d8912cf5dffd66812789daff5e46ac08675505ac1a9979c442"},
1948 | ]
1949 | pyobjc-framework-addressbook = [
1950 | {file = "pyobjc-framework-AddressBook-6.2.2.tar.gz", hash = "sha256:d6f410dc4ac0465b678b2c3d04c870fad387019a5aa2cb27101f43e488e935f0"},
1951 | {file = "pyobjc_framework_AddressBook-6.2.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:6b17571fe93b20a1649928a644013ef6daf3d4835d7ff4f1cc1fca8070f29513"},
1952 | ]
1953 | pyobjc-framework-adsupport = [
1954 | {file = "pyobjc-framework-AdSupport-6.2.2.tar.gz", hash = "sha256:91851a170b1b2bd9392bdb6cf4cbb9e449950596b5244d4d8098933ab68c5b87"},
1955 | {file = "pyobjc_framework_AdSupport-6.2.2-py2.py3-none-any.whl", hash = "sha256:92fc08e7089568f67b8bab11aabc60c9287f1aefefee0736ea580d8ff37bccfd"},
1956 | ]
1957 | pyobjc-framework-applescriptkit = [
1958 | {file = "pyobjc-framework-AppleScriptKit-6.2.2.tar.gz", hash = "sha256:fa7821d67503997db4e6b77f0d3e855a6564a627e2e2f3e99a83110365971492"},
1959 | {file = "pyobjc_framework_AppleScriptKit-6.2.2-py2.py3-none-any.whl", hash = "sha256:4d81cc4d0703cc4ad8a4e4e38958e1ccb1fad951efc801b6753883d4f76c984b"},
1960 | ]
1961 | pyobjc-framework-applescriptobjc = [
1962 | {file = "pyobjc-framework-AppleScriptObjC-6.2.2.tar.gz", hash = "sha256:581c51e102a266c57bccd3c56625e5fe9f9069c88f9b6510e3f6bf47cc92ddb2"},
1963 | {file = "pyobjc_framework_AppleScriptObjC-6.2.2-py2.py3-none-any.whl", hash = "sha256:7466ef8b6726f66eae102c77d59fdce3961b4b74a87f331f14683092203d2609"},
1964 | ]
1965 | pyobjc-framework-applicationservices = [
1966 | {file = "pyobjc-framework-ApplicationServices-6.2.2.tar.gz", hash = "sha256:f9d74f1d72713180638fc441c072eaaa8e59ccabb04bac18b21d137e9c0cb5e6"},
1967 | {file = "pyobjc_framework_ApplicationServices-6.2.2-py2.py3-none-any.whl", hash = "sha256:9018463ad698e6bb4f4dfb01cd3157b521b68ace447df8cceff17c2b99d0ebc9"},
1968 | ]
1969 | pyobjc-framework-authenticationservices = [
1970 | {file = "pyobjc-framework-AuthenticationServices-6.2.2.tar.gz", hash = "sha256:a5229d9a7d878e8287a518a1ad9f7e4a2efccd19d952561498292f3e0037a08d"},
1971 | {file = "pyobjc_framework_AuthenticationServices-6.2.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:45ae3dc42f233bb810d94da2438821ac2849ad0fa7eb0f4cf25f4d4c77326381"},
1972 | ]
1973 | pyobjc-framework-automaticassessmentconfiguration = [
1974 | {file = "pyobjc-framework-AutomaticAssessmentConfiguration-6.2.2.tar.gz", hash = "sha256:9b9488f23e31ec4b217777eae4f46e64d85479c0b0250c59aaa7b47342462a83"},
1975 | {file = "pyobjc_framework_AutomaticAssessmentConfiguration-6.2.2-py2.py3-none-any.whl", hash = "sha256:07650b5975ade6cf21e65eba74029fecceb36982fd2b9896b2bc282a2964988e"},
1976 | ]
1977 | pyobjc-framework-automator = [
1978 | {file = "pyobjc-framework-Automator-6.2.2.tar.gz", hash = "sha256:bd071eb8d9a3286b92713afb24792e5b777c6deb57c1deaca4236503256b5971"},
1979 | {file = "pyobjc_framework_Automator-6.2.2-py2.py3-none-any.whl", hash = "sha256:53d257d6a0ae7fa78d9c2d7cfbdb27b5bcf87576c3be0f2d61d560f34e00ab5b"},
1980 | ]
1981 | pyobjc-framework-avfoundation = [
1982 | {file = "pyobjc-framework-AVFoundation-6.2.2.tar.gz", hash = "sha256:9d347c71b99f900770b7fb93881fa30a43d61bd8b9390b432878acff0edfe2fb"},
1983 | {file = "pyobjc_framework_AVFoundation-6.2.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:f7ab7f751127af71b99e043c4bfb028e7f5cd62675c211d878ef1d6a6096ff01"},
1984 | ]
1985 | pyobjc-framework-avkit = [
1986 | {file = "pyobjc-framework-AVKit-6.2.2.tar.gz", hash = "sha256:3095b626fd9a50efe22af67597f0af8e4409f47edf4527b355822c074c28a122"},
1987 | {file = "pyobjc_framework_AVKit-6.2.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:2b3dfe6c2aa4bb084e4d82c8633bf3c40be18f32c698caae4e806124d9eb5739"},
1988 | ]
1989 | pyobjc-framework-businesschat = [
1990 | {file = "pyobjc-framework-BusinessChat-6.2.2.tar.gz", hash = "sha256:7772ca33d394adfd85685a80371d367d09098ebb3fb0712d1649f504e05975a6"},
1991 | {file = "pyobjc_framework_BusinessChat-6.2.2-py2.py3-none-any.whl", hash = "sha256:ad520cc0790acb3adfaf606ac930e9b822faf1066afb3b4b2df18fd66666e32c"},
1992 | ]
1993 | pyobjc-framework-calendarstore = [
1994 | {file = "pyobjc-framework-CalendarStore-6.2.2.tar.gz", hash = "sha256:1ec03bc5bbef9cdbf4e8520774da28d1f6d0e1581905f15d639211926ec5f884"},
1995 | {file = "pyobjc_framework_CalendarStore-6.2.2-py2.py3-none-any.whl", hash = "sha256:c5c215cc2ed762d94e8f40b18ff907561e2dc604acd2d40d370fb5edd2ccb7d7"},
1996 | ]
1997 | pyobjc-framework-cfnetwork = [
1998 | {file = "pyobjc-framework-CFNetwork-6.2.2.tar.gz", hash = "sha256:fbf1064e642a593f1001c86f9497a1b0627d8583354576e95f8e1e240a3cd553"},
1999 | {file = "pyobjc_framework_CFNetwork-6.2.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:2dab65518831570efb830b9005c6775ae040de7c70a0c5b2110c86f5cd45b905"},
2000 | ]
2001 | pyobjc-framework-cloudkit = [
2002 | {file = "pyobjc-framework-CloudKit-6.2.2.tar.gz", hash = "sha256:351335710aed1f04cb73b3d4a983835a8b40f04b625937c81a13a52a5dfe9313"},
2003 | {file = "pyobjc_framework_CloudKit-6.2.2-py2.py3-none-any.whl", hash = "sha256:1a730fcf1f09bf914011e4534cbfa8f25c7a4f598754a0076140537434f8e66d"},
2004 | ]
2005 | pyobjc-framework-cocoa = [
2006 | {file = "pyobjc-framework-Cocoa-6.2.2.tar.gz", hash = "sha256:75821b98fb789d240bea7034c4f96396b2eac3e7b02428b4be9101fc899b7fc3"},
2007 | {file = "pyobjc_framework_Cocoa-6.2.2-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:779299f73b8b5a1dd0973b3b16bd706e1f67df44edfb3f3ca6e5e873591c0efc"},
2008 | {file = "pyobjc_framework_Cocoa-6.2.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:45e3011efbd8ab4eb4c7ee1f55a8b5ecb41cf66fa797aff0e9454060781645a0"},
2009 | {file = "pyobjc_framework_Cocoa-6.2.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:2a5ab2e33cafe577592c31b2663f3b23f6e142fd717c8cf3826394a380cc4353"},
2010 | {file = "pyobjc_framework_Cocoa-6.2.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6f5e1d59f6e1f4be40dedf051925b8d90c561657c9ec2453652af033fe5c2bf0"},
2011 | ]
2012 | pyobjc-framework-collaboration = [
2013 | {file = "pyobjc-framework-Collaboration-6.2.2.tar.gz", hash = "sha256:3751f1895b2e1cc92674fbdad2b64f6cce1cb5aab50730b7bb8c6c282c76b7ec"},
2014 | {file = "pyobjc_framework_Collaboration-6.2.2-py2.py3-none-any.whl", hash = "sha256:f703b36dba48b73f81695fd8908a82e5d7c292e7a2cab2142dbb979bff0b8ef3"},
2015 | ]
2016 | pyobjc-framework-colorsync = [
2017 | {file = "pyobjc-framework-ColorSync-6.2.2.tar.gz", hash = "sha256:c87f186ad71af827fa11799318680167de292de580f2da0c9bfb3097ab61523f"},
2018 | {file = "pyobjc_framework_ColorSync-6.2.2-py2.py3-none-any.whl", hash = "sha256:a2010756da26940001f4162588927d5cab3da559f0d06f0b7f1d3ffea91deed0"},
2019 | ]
2020 | pyobjc-framework-contacts = [
2021 | {file = "pyobjc-framework-Contacts-6.2.2.tar.gz", hash = "sha256:92dcd6bd63e07214fcb20b37906b0bd468cb94dc317d3ae8f140a712eea83c2d"},
2022 | {file = "pyobjc_framework_Contacts-6.2.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:78dd356c81edf32b341595121a6192a0a5c66de97068a0c825200c50f1319cf4"},
2023 | ]
2024 | pyobjc-framework-contactsui = [
2025 | {file = "pyobjc-framework-ContactsUI-6.2.2.tar.gz", hash = "sha256:b6a649ebae15d7cb36a06003fbd0cb5fa948f5ce92652a753b1cb1beda47e409"},
2026 | {file = "pyobjc_framework_ContactsUI-6.2.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:a66628723ea5cee14e0fe983db2f550e96c1be5d4a8809a6f0596629ba40fe4e"},
2027 | ]
2028 | pyobjc-framework-coreaudio = [
2029 | {file = "pyobjc-framework-CoreAudio-6.2.2.tar.gz", hash = "sha256:a9259be2ed59e436c75b76d3ca918330c3c91ddb1e8358ff3bc1a76c2e7bda04"},
2030 | {file = "pyobjc_framework_CoreAudio-6.2.2-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:2193854657219a10f5967b8f1dc4ae3139522e48b2f0ca4235a57957cb287e00"},
2031 | {file = "pyobjc_framework_CoreAudio-6.2.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:109bd194283a77983c817d121e1b47b1fea5a2122267e00ec62e902227f388ce"},
2032 | {file = "pyobjc_framework_CoreAudio-6.2.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:7fa34ba6bc3a69d08ca3964a8223a48a0ac60ae6961a0e5854e66cfa5eb28d57"},
2033 | {file = "pyobjc_framework_CoreAudio-6.2.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:7733d9be922f3de5801143247ed25cbd443dcf04717e9d2fc94e40b8be24e569"},
2034 | ]
2035 | pyobjc-framework-coreaudiokit = [
2036 | {file = "pyobjc-framework-CoreAudioKit-6.2.2.tar.gz", hash = "sha256:5df22ce5dab4c02676825c4c30024d693efc81e04d822c5bf4e02d6baea75dd7"},
2037 | {file = "pyobjc_framework_CoreAudioKit-6.2.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:6ad19c1194b4bbbc35118420400822e0640450ca02289f41f839020581d1da02"},
2038 | ]
2039 | pyobjc-framework-corebluetooth = [
2040 | {file = "pyobjc-framework-CoreBluetooth-6.2.2.tar.gz", hash = "sha256:4454375b76ec1487dcc24f09ee8a2db8c284de548ce67c41bd489e93093e4896"},
2041 | {file = "pyobjc_framework_CoreBluetooth-6.2.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:b6be6eac503ceeae04027824773f2ca317dc824a8ac89b8908412624cc6a83c8"},
2042 | ]
2043 | pyobjc-framework-coredata = [
2044 | {file = "pyobjc-framework-CoreData-6.2.2.tar.gz", hash = "sha256:ae89b11608ffa13d2b8475274c63ab7d22e856978dd3a70a5c21893085c6fdcb"},
2045 | {file = "pyobjc_framework_CoreData-6.2.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:6e71a881d7f51165d96527a28f6a597fe63e87036efcc08f73fc993cb0785c77"},
2046 | ]
2047 | pyobjc-framework-corehaptics = [
2048 | {file = "pyobjc-framework-CoreHaptics-6.2.2.tar.gz", hash = "sha256:21f9a9ea2295258220056f9152e8fd996ac8b2f33b110b662ab525304ede95c5"},
2049 | {file = "pyobjc_framework_CoreHaptics-6.2.2-py2.py3-none-any.whl", hash = "sha256:209767b1a4daba13bb13cdc6bf8fbd75f5de422105217461662fd79fc3496838"},
2050 | ]
2051 | pyobjc-framework-corelocation = [
2052 | {file = "pyobjc-framework-CoreLocation-6.2.2.tar.gz", hash = "sha256:237722c1a9d90ce1fc0cc7b988375a816e9489bec2e0ddc6c83205ed1e7eb8bf"},
2053 | {file = "pyobjc_framework_CoreLocation-6.2.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:fe5900e5d3d7cb9e7652fc9389d92edf71da2f57b305edf9dc0642bcdfaf56da"},
2054 | ]
2055 | pyobjc-framework-coremedia = [
2056 | {file = "pyobjc-framework-CoreMedia-6.2.2.tar.gz", hash = "sha256:962d0bb705a7c3934a37e5e128c82e153fe9261246897d366bc5b5c6f3de2a69"},
2057 | {file = "pyobjc_framework_CoreMedia-6.2.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:cece414593e301cd3c24959bc2ff375d0891a6c051b2bc0d0fbf1c53bc637a08"},
2058 | ]
2059 | pyobjc-framework-coremediaio = [
2060 | {file = "pyobjc-framework-CoreMediaIO-6.2.2.tar.gz", hash = "sha256:2e656a6d101e7ee3fa213636c879e22f78230631b800029d243f1ba04cdef9df"},
2061 | {file = "pyobjc_framework_CoreMediaIO-6.2.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:49e4cd70d295895da0032594d5f40d0be6c19a3d749c6a9fb27ad8225a1a1463"},
2062 | ]
2063 | pyobjc-framework-coreml = [
2064 | {file = "pyobjc-framework-CoreML-6.2.2.tar.gz", hash = "sha256:c7d11d7b590556a811c6139d603f2cb0c17e3bf92b5f1d01b711b10f87fc8ada"},
2065 | {file = "pyobjc_framework_CoreML-6.2.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:ca87242e73a4d0a9ab8db210893dda08402e44bcdd917d209a707346c579e15c"},
2066 | ]
2067 | pyobjc-framework-coremotion = [
2068 | {file = "pyobjc-framework-CoreMotion-6.2.2.tar.gz", hash = "sha256:121612fc4d6aa0b13af8dcf3623175e543c38960f916ad06739fefad9f1c71e3"},
2069 | {file = "pyobjc_framework_CoreMotion-6.2.2-py2.py3-none-any.whl", hash = "sha256:2a32cc8a7a5aa3a6fb4f6f3a44fb82fa69755bba6d1d24a4b7269ef102669be5"},
2070 | ]
2071 | pyobjc-framework-coreservices = [
2072 | {file = "pyobjc-framework-CoreServices-6.2.2.tar.gz", hash = "sha256:00c3106fa9541385a280856a07ec13498efb9f22a7d58979753c98f993e15ae8"},
2073 | {file = "pyobjc_framework_CoreServices-6.2.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:d00e5fe9759a312f7a508771ee8dbb57433c9519e8675c77a07b18bad59820b9"},
2074 | ]
2075 | pyobjc-framework-corespotlight = [
2076 | {file = "pyobjc-framework-CoreSpotlight-6.2.2.tar.gz", hash = "sha256:bb8f21db764a141ed97423869883700ab567253c73158f002548eec9a1e2a151"},
2077 | {file = "pyobjc_framework_CoreSpotlight-6.2.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:26123a2cf9bc3b627346a7a58c2ce257e4b4f7baa5aead7df8b43ab402e2379b"},
2078 | ]
2079 | pyobjc-framework-coretext = [
2080 | {file = "pyobjc-framework-CoreText-6.2.2.tar.gz", hash = "sha256:944fda1bd9c2827e36907216a930fcaf429788132616bed3d687ba0e80405d34"},
2081 | {file = "pyobjc_framework_CoreText-6.2.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:0a5f2288b1e29d93d00d708d0e10d8ca49af1116772d48d0623cc62ffad12918"},
2082 | ]
2083 | pyobjc-framework-corewlan = [
2084 | {file = "pyobjc-framework-CoreWLAN-6.2.2.tar.gz", hash = "sha256:49d14a82541f0ddbf5ecfd7d1fec9a2103e4a76964e0840f21257c7043a6c4d5"},
2085 | {file = "pyobjc_framework_CoreWLAN-6.2.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:10a6d761c90fee293b5638375a095214673b5d14fca9d494f287ea9d0168148d"},
2086 | ]
2087 | pyobjc-framework-cryptotokenkit = [
2088 | {file = "pyobjc-framework-CryptoTokenKit-6.2.2.tar.gz", hash = "sha256:a7ee19dfae514ff6871648cb182b33d50fb2a19a44475e7e9c93cab7078a76d7"},
2089 | {file = "pyobjc_framework_CryptoTokenKit-6.2.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:a71a366a38255ed3867119c37c7c853000e8dc4839f74186a7c2930952b63d17"},
2090 | ]
2091 | pyobjc-framework-devicecheck = [
2092 | {file = "pyobjc-framework-DeviceCheck-6.2.2.tar.gz", hash = "sha256:eec96526096f4b5d6f447bac4d88587a8b1d0281e8378665c08a55d0a28ae7b8"},
2093 | {file = "pyobjc_framework_DeviceCheck-6.2.2-py2.py3-none-any.whl", hash = "sha256:e4ef8cd4f30f0149e53efb6ee0a0324b6db9ec35530893182facfa496ed60fa9"},
2094 | ]
2095 | pyobjc-framework-dictionaryservices = [
2096 | {file = "pyobjc-framework-DictionaryServices-6.2.2.tar.gz", hash = "sha256:be01129d642ac516622c1f4998fec37a7969b992271757aadaeeef2b3d601bdc"},
2097 | {file = "pyobjc_framework_DictionaryServices-6.2.2-py2.py3-none-any.whl", hash = "sha256:a99797dfa22687e27a41fda42def812bb4f45ed99c5d4a254a54338ee15b77e6"},
2098 | ]
2099 | pyobjc-framework-discrecording = [
2100 | {file = "pyobjc-framework-DiscRecording-6.2.2.tar.gz", hash = "sha256:445a18666d126da878d456558a43dd43990dcee9516cddb9807a37d60a6327d8"},
2101 | {file = "pyobjc_framework_DiscRecording-6.2.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:dd0b9b2d58de77caa700396d73a9358fea7de2c2fe1c9e061f20b3f0833b4cac"},
2102 | ]
2103 | pyobjc-framework-discrecordingui = [
2104 | {file = "pyobjc-framework-DiscRecordingUI-6.2.2.tar.gz", hash = "sha256:569a462566538c737c57c41987e8bafd07fa4cd91eb668b846dd18dbf2aa68fd"},
2105 | {file = "pyobjc_framework_DiscRecordingUI-6.2.2-py2.py3-none-any.whl", hash = "sha256:b9937c119f0bc021187f0e2c923972feee0a64b7e32d99736c6013e9e0d15043"},
2106 | ]
2107 | pyobjc-framework-diskarbitration = [
2108 | {file = "pyobjc-framework-DiskArbitration-6.2.2.tar.gz", hash = "sha256:efcf0e270d4a28f61fc12fa04204d61fb70ff3eaa975606a8e8cf7efba0bcd2c"},
2109 | {file = "pyobjc_framework_DiskArbitration-6.2.2-py2.py3-none-any.whl", hash = "sha256:18ddc54b99c55f1970f3f50a1a2e3760931ca039350f015ce92e9f2bd256f48f"},
2110 | ]
2111 | pyobjc-framework-dvdplayback = [
2112 | {file = "pyobjc-framework-DVDPlayback-6.2.2.tar.gz", hash = "sha256:13d456dddeeec5bee406b701ace1c2f977dded7ea79b65f83d2699a3d2618513"},
2113 | {file = "pyobjc_framework_DVDPlayback-6.2.2-py2.py3-none-any.whl", hash = "sha256:4daa2fa86842101231adc793a2951badaf068630268be7c1f82b7507fed6eb46"},
2114 | ]
2115 | pyobjc-framework-eventkit = [
2116 | {file = "pyobjc-framework-EventKit-6.2.2.tar.gz", hash = "sha256:da75124d740f4f993461773e4f40f7be5f5da544e21dc7b037fa64a5eb2071c2"},
2117 | {file = "pyobjc_framework_EventKit-6.2.2-py2.py3-none-any.whl", hash = "sha256:10b4c1971dc8d0fcd7dac3f5f2f956fdd102c88dded8f21733c843e6e04798a6"},
2118 | ]
2119 | pyobjc-framework-exceptionhandling = [
2120 | {file = "pyobjc-framework-ExceptionHandling-6.2.2.tar.gz", hash = "sha256:e65a43a809f792fd27280fb6dcc8e11726571aa3bfd9650aedd0f17f229383f4"},
2121 | {file = "pyobjc_framework_ExceptionHandling-6.2.2-py2.py3-none-any.whl", hash = "sha256:9e2c345a5de0b6451d4e8b257be798f7cc555c15c29c3dcdef1131127e7e9f73"},
2122 | ]
2123 | pyobjc-framework-executionpolicy = [
2124 | {file = "pyobjc-framework-ExecutionPolicy-6.2.2.tar.gz", hash = "sha256:7dc7565531140a408dd26fabb3274176e0e7f7f718f4fe6518e5b64f0988213b"},
2125 | {file = "pyobjc_framework_ExecutionPolicy-6.2.2-py2.py3-none-any.whl", hash = "sha256:5f6278f196b53834c04e74a7c36c50f94e7cd8964bfa2dcd8db2eef534e72c77"},
2126 | ]
2127 | pyobjc-framework-externalaccessory = [
2128 | {file = "pyobjc-framework-ExternalAccessory-6.2.2.tar.gz", hash = "sha256:7a1e93f54c40b6d277c8b0579b497ae4b42e0704388ccf4bd44b7caee0d63fec"},
2129 | {file = "pyobjc_framework_ExternalAccessory-6.2.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:7e716b7be0d86e0a3892646f74b3fe7a06c4584839fbd6e07784ac95ab5b68b3"},
2130 | ]
2131 | pyobjc-framework-fileprovider = [
2132 | {file = "pyobjc-framework-FileProvider-6.2.2.tar.gz", hash = "sha256:1502e27999dcc489502a02ca2bf8620c9e93e7f65007041605ce5da12d777be8"},
2133 | {file = "pyobjc_framework_FileProvider-6.2.2-py2.py3-none-any.whl", hash = "sha256:619a12a186e2ac5264bf2b6ebbbcdee6d355a1c60521a40b1db90b0a892808b5"},
2134 | ]
2135 | pyobjc-framework-fileproviderui = [
2136 | {file = "pyobjc-framework-FileProviderUI-6.2.2.tar.gz", hash = "sha256:1b22dc8a1dad2e8569aa46f4e978c05028425528ba466a6b3cb47115a68492b6"},
2137 | {file = "pyobjc_framework_FileProviderUI-6.2.2-py2.py3-none-any.whl", hash = "sha256:efec0801d67a006feb404a60ab3966bbc6e933856f368b3565304a44e9ab0299"},
2138 | ]
2139 | pyobjc-framework-findersync = [
2140 | {file = "pyobjc-framework-FinderSync-6.2.2.tar.gz", hash = "sha256:3a31aec9bfcb97374550a8689b6379983aa21753a07f9d9d9fae8083b205d629"},
2141 | {file = "pyobjc_framework_FinderSync-6.2.2-py2.py3-none-any.whl", hash = "sha256:5b72a80e4a262cb0525dc9e96d2791d86343c37c8a76583afe5141c3a6c0b153"},
2142 | ]
2143 | pyobjc-framework-fsevents = [
2144 | {file = "pyobjc-framework-FSEvents-6.2.2.tar.gz", hash = "sha256:8e2cdfb48e1bca53dc67fc4b219a891ec6c07b2a422f7e3da0ce4ccff258f2b7"},
2145 | {file = "pyobjc_framework_FSEvents-6.2.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:d92526e5f0a1763088dd609072b7337a9e58ea698697a1500ad95409c32b64ce"},
2146 | ]
2147 | pyobjc-framework-gamecenter = [
2148 | {file = "pyobjc-framework-GameCenter-6.2.2.tar.gz", hash = "sha256:d961ac6ea9a39f55d8e5b3726794adc0fc88df4117631509a1372ffb2dad5a5c"},
2149 | {file = "pyobjc_framework_GameCenter-6.2.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:f9cffd8d1c88d890c7e9a359d4d37eccbad384096cd223811cf9c23fa283e168"},
2150 | ]
2151 | pyobjc-framework-gamecontroller = [
2152 | {file = "pyobjc-framework-GameController-6.2.2.tar.gz", hash = "sha256:6d96356e00c63437871cec3d881b849a2d635ef29a240bfa07ee74fbe5ce048e"},
2153 | {file = "pyobjc_framework_GameController-6.2.2-py2.py3-none-any.whl", hash = "sha256:368f1ffad8aefe6378477157e941a853053a380984e1854206f3dbefc86dafb6"},
2154 | ]
2155 | pyobjc-framework-gamekit = [
2156 | {file = "pyobjc-framework-GameKit-6.2.2.tar.gz", hash = "sha256:1d9c8d54a5b803076cf39140db5626e7d1a3233c8f45e5c222e455bae857dd93"},
2157 | {file = "pyobjc_framework_GameKit-6.2.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:610166712a08ebd25c0a990ed2c2a8288db5f7d25ead352488ae2dfbe6b169ee"},
2158 | ]
2159 | pyobjc-framework-gameplaykit = [
2160 | {file = "pyobjc-framework-GameplayKit-6.2.2.tar.gz", hash = "sha256:b7b4752090d7fbbb92af8123d65fc7a1c3a751f048bdff0109e418654d4edfa5"},
2161 | {file = "pyobjc_framework_GameplayKit-6.2.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:6229038def1269260da5a3743151366bebef20d0c0369a2c9f8fd811f1f1906e"},
2162 | ]
2163 | pyobjc-framework-imagecapturecore = [
2164 | {file = "pyobjc-framework-ImageCaptureCore-6.2.2.tar.gz", hash = "sha256:7540191fb1941452ce17502fcc83896437150c3c084e26c346c00a34360cc2f8"},
2165 | {file = "pyobjc_framework_ImageCaptureCore-6.2.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:1789726d4421dfac49920a2a385c31a756dfcc009baf3b123265a0582a85f5f1"},
2166 | ]
2167 | pyobjc-framework-imserviceplugin = [
2168 | {file = "pyobjc-framework-IMServicePlugIn-6.2.2.tar.gz", hash = "sha256:756afb6d6c5f6adaf86f3c61268fd506adf16698cd0800cc708c859130ca43ca"},
2169 | {file = "pyobjc_framework_IMServicePlugIn-6.2.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:e70ae537c5f628a3be96b6112ceaeb44744d8cea8c761c0c86cdc848db3503a4"},
2170 | ]
2171 | pyobjc-framework-inputmethodkit = [
2172 | {file = "pyobjc-framework-InputMethodKit-6.2.2.tar.gz", hash = "sha256:5de9d3fd0a260d53a567294d0713adec7c0d32dc6db0c7b32606932e3398eb60"},
2173 | {file = "pyobjc_framework_InputMethodKit-6.2.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:b0167d9b0cdca5b329dd5fd50c5a797e5f073a3b23b09201e91ae82a0a646696"},
2174 | ]
2175 | pyobjc-framework-installerplugins = [
2176 | {file = "pyobjc-framework-InstallerPlugins-6.2.2.tar.gz", hash = "sha256:309c21c10d9a61206cc71238cf4d44a382362688a8983a390020903b649b55c9"},
2177 | {file = "pyobjc_framework_InstallerPlugins-6.2.2-py2.py3-none-any.whl", hash = "sha256:38a509c661e2b592b75870ac3da746208505898b6faa0a8c338d1512aa309b40"},
2178 | ]
2179 | pyobjc-framework-instantmessage = [
2180 | {file = "pyobjc-framework-InstantMessage-6.2.2.tar.gz", hash = "sha256:c1043d4c9ab1aaf53941ec9a6e05d6c2dd46fdc2a5aeb79f8f40097616aefb99"},
2181 | {file = "pyobjc_framework_InstantMessage-6.2.2-py2.py3-none-any.whl", hash = "sha256:41d933dcbd0fe758f12a4bc384b16fc0718e2f1c45043fe4c5f0c971c20433cc"},
2182 | ]
2183 | pyobjc-framework-intents = [
2184 | {file = "pyobjc-framework-Intents-6.2.2.tar.gz", hash = "sha256:fa85f74e13b350d1331ed65548edfa9271308b90decac6c440a7d34cafff5057"},
2185 | {file = "pyobjc_framework_Intents-6.2.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:c272fe36404b18199b08bced8acb2f63b0f1b61f35a0b8fa37a6cd46f2b1a1c4"},
2186 | ]
2187 | pyobjc-framework-interfacebuilderkit = [
2188 | {file = "pyobjc-framework-InterfaceBuilderKit-6.2.2.tar.gz", hash = "sha256:5a600137127aad32f73d5a4f98e9356a5d782e01fdbd7deba8cef1f44db1a748"},
2189 | {file = "pyobjc_framework_InterfaceBuilderKit-6.2.2-py2.py3-none-any.whl", hash = "sha256:9e6813d4be3d7defb1ec962906042e31a961d7299bd0d4f14a488392acbc5b3b"},
2190 | ]
2191 | pyobjc-framework-iosurface = [
2192 | {file = "pyobjc-framework-IOSurface-6.2.2.tar.gz", hash = "sha256:e97af910e2dc6fb7918f503c03b6f66cb99f477d968502dd9c96b4fdb86cba92"},
2193 | {file = "pyobjc_framework_IOSurface-6.2.2-py2.py3-none-any.whl", hash = "sha256:04be56c8be967dcbce31d0d5babec19107536db566590962b228894a620eefff"},
2194 | ]
2195 | pyobjc-framework-ituneslibrary = [
2196 | {file = "pyobjc-framework-iTunesLibrary-6.2.2.tar.gz", hash = "sha256:3e5f6f6013cd333954fc3439a044181b7179b379a2868103ed067e3f964bafb2"},
2197 | {file = "pyobjc_framework_iTunesLibrary-6.2.2-py2.py3-none-any.whl", hash = "sha256:61038c8c65ba9d804ad831c64e0874095e0557a2826bfec920e5153f869197fc"},
2198 | ]
2199 | pyobjc-framework-latentsemanticmapping = [
2200 | {file = "pyobjc-framework-LatentSemanticMapping-6.2.2.tar.gz", hash = "sha256:48d20ca24540c1385d64a898a4aa87be398e707232a9ea01a3432a4a78ebcf5e"},
2201 | {file = "pyobjc_framework_LatentSemanticMapping-6.2.2-py2.py3-none-any.whl", hash = "sha256:5f6ce54438f755e87c7dbc6a7baf1c92cef7d09c994873793bd0caf1973f5823"},
2202 | ]
2203 | pyobjc-framework-launchservices = [
2204 | {file = "pyobjc-framework-LaunchServices-6.2.2.tar.gz", hash = "sha256:d9c2ae16a113adaa5b8a86481402a6dceb381c1419d33bf5b98fa615975beda2"},
2205 | {file = "pyobjc_framework_LaunchServices-6.2.2-py2.py3-none-any.whl", hash = "sha256:edc09a001f343b459c130a8518e18b9b7b5006428e152d4dc711e52d5ad76b12"},
2206 | ]
2207 | pyobjc-framework-libdispatch = [
2208 | {file = "pyobjc-framework-libdispatch-6.2.2.tar.gz", hash = "sha256:a69aa6d4b6d396c9006ee9b10b2cfb678005ba4f68e3306e58bb7f92b39d3a24"},
2209 | {file = "pyobjc_framework_libdispatch-6.2.2-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:d8c2d74565e0a0fdf68bfeb2a26bccbbcf326f7dbb165fec4d429501959e81ff"},
2210 | {file = "pyobjc_framework_libdispatch-6.2.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:aa2543dcab0d5694381619852bfad78d83e3673054c4e72134f7cf15c1c2ad7b"},
2211 | {file = "pyobjc_framework_libdispatch-6.2.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:a1430080682893dd39a4ba415f4ab889a3d2c3f50156476052de872bc26bc711"},
2212 | {file = "pyobjc_framework_libdispatch-6.2.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6e30681fd6a20c53f569e454e80a4ecb58aeca1ee79e42733c3901917fcd8627"},
2213 | ]
2214 | pyobjc-framework-linkpresentation = [
2215 | {file = "pyobjc-framework-LinkPresentation-6.2.2.tar.gz", hash = "sha256:3f01e167aebc07a1db3d2d4fbb5dfaf70d8e5f07596148027243101c1d049835"},
2216 | {file = "pyobjc_framework_LinkPresentation-6.2.2-py2.py3-none-any.whl", hash = "sha256:f941a701b38f248a8aea281eb1dde8a23891824da563e9ed1a88a56c1f5b0489"},
2217 | ]
2218 | pyobjc-framework-localauthentication = [
2219 | {file = "pyobjc-framework-LocalAuthentication-6.2.2.tar.gz", hash = "sha256:8f4ab9fe232ad583061ed161568253445aab55c41df293bfbe1605cabe80818d"},
2220 | {file = "pyobjc_framework_LocalAuthentication-6.2.2-py2.py3-none-any.whl", hash = "sha256:d547c15770d5c5774815beae4b8a2c133a453cd2d7cb0eea21d2abf44e39a055"},
2221 | ]
2222 | pyobjc-framework-mapkit = [
2223 | {file = "pyobjc-framework-MapKit-6.2.2.tar.gz", hash = "sha256:2b7ceaf77c9b9126ac71b2d7549e997047d34375e48ca91a3099ae32e1d342f7"},
2224 | {file = "pyobjc_framework_MapKit-6.2.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:0968591c62439aaa01a88d0fdef906313338c103264b63c21f5a66b5fb6e8f4f"},
2225 | ]
2226 | pyobjc-framework-mediaaccessibility = [
2227 | {file = "pyobjc-framework-MediaAccessibility-6.2.2.tar.gz", hash = "sha256:893245c1731aa4a5b8568adb78025bed3c5c1e314e27f663a6f35db23175d0df"},
2228 | {file = "pyobjc_framework_MediaAccessibility-6.2.2-py2.py3-none-any.whl", hash = "sha256:2c2b3feabe241bf93811a0bd586af6120e92705201a54ab2868e66d6725093ea"},
2229 | ]
2230 | pyobjc-framework-medialibrary = [
2231 | {file = "pyobjc-framework-MediaLibrary-6.2.2.tar.gz", hash = "sha256:6c2e76290903ae25dc591e86a489283f79ae1aad67de8b31c88ca3ede3de27dc"},
2232 | {file = "pyobjc_framework_MediaLibrary-6.2.2-py2.py3-none-any.whl", hash = "sha256:d312618aa9bec856f9c22d1f95330f1c63212e342235f4c7be673fcac9f747c6"},
2233 | ]
2234 | pyobjc-framework-mediaplayer = [
2235 | {file = "pyobjc-framework-MediaPlayer-6.2.2.tar.gz", hash = "sha256:8b2e8d432a71c9f265d1db69ebe22b98a34f93543083369f07d694f3a6a3d6f4"},
2236 | {file = "pyobjc_framework_MediaPlayer-6.2.2-py2.py3-none-any.whl", hash = "sha256:fc9272dbb6fecf82165ae99aec2a9105478316a475b88b120ecb86e74e5465d0"},
2237 | ]
2238 | pyobjc-framework-mediatoolbox = [
2239 | {file = "pyobjc-framework-MediaToolbox-6.2.2.tar.gz", hash = "sha256:742140302bf848fb25971fe0922269088ca498346d1fa5d078260aa976cb63c5"},
2240 | {file = "pyobjc_framework_MediaToolbox-6.2.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:1160fe5fe0425ae7d0adb462d260700bf26e15b54ef268868b0017f2ff24e4b9"},
2241 | ]
2242 | pyobjc-framework-message = [
2243 | {file = "pyobjc-framework-Message-6.2.2.tar.gz", hash = "sha256:8128d1bec5204e808fbb867f6a96fe3a26b94b93613bbe5f9d2dc0c0d994a33b"},
2244 | {file = "pyobjc_framework_Message-6.2.2-py2.py3-none-any.whl", hash = "sha256:ebe14dfabd34f8af8f255bff110113fdbbf33c2aaf384264f00cbbadcddb9137"},
2245 | ]
2246 | pyobjc-framework-metal = [
2247 | {file = "pyobjc-framework-Metal-6.2.2.tar.gz", hash = "sha256:ca916bc103aeec79507c4d79ce35e853f109e0581965293eaedb9e517d8db2e8"},
2248 | {file = "pyobjc_framework_Metal-6.2.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:77dd2c2c0a7e3cc04121c07af8bbe48daadd22b5517e3a70ad619fcc9b1ea66a"},
2249 | ]
2250 | pyobjc-framework-metalkit = [
2251 | {file = "pyobjc-framework-MetalKit-6.2.2.tar.gz", hash = "sha256:825fc2e49f61df8ddf9ac74035c0aae696eaa9b8f797a107ba8bdd824f0312aa"},
2252 | {file = "pyobjc_framework_MetalKit-6.2.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:02aa2ac1c2b0efcbe361c4796a3c1083029726faa7a0b2ac1412fb86bf033c98"},
2253 | ]
2254 | pyobjc-framework-modelio = [
2255 | {file = "pyobjc-framework-ModelIO-6.2.2.tar.gz", hash = "sha256:fae52369376bfe9d197abc36bdd84d934aec058cdd0a1afa9cad533d975f70cb"},
2256 | {file = "pyobjc_framework_ModelIO-6.2.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:171f8803e39cd6cb9262347931077c8eecb583cbfaecaf5c9fec17d877f8654b"},
2257 | ]
2258 | pyobjc-framework-multipeerconnectivity = [
2259 | {file = "pyobjc-framework-MultipeerConnectivity-6.2.2.tar.gz", hash = "sha256:8545d8210e645aa9752d07eafdea006972e9efc3575083368768f8ac872711cc"},
2260 | {file = "pyobjc_framework_MultipeerConnectivity-6.2.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:a9672361448d42d16b12763e573c8d768e7de1b10e4a9dbaa521ab1527dd03ba"},
2261 | ]
2262 | pyobjc-framework-naturallanguage = [
2263 | {file = "pyobjc-framework-NaturalLanguage-6.2.2.tar.gz", hash = "sha256:45ffea5d3b8ff9c85c4bf3e6de1714daae675ac3fd1abd957a0e57af8f90a260"},
2264 | {file = "pyobjc_framework_NaturalLanguage-6.2.2-py2.py3-none-any.whl", hash = "sha256:056326f51e242aaf33978bf09974b8cca1dc13903b944a28c4481317626038a9"},
2265 | ]
2266 | pyobjc-framework-netfs = [
2267 | {file = "pyobjc-framework-NetFS-6.2.2.tar.gz", hash = "sha256:7f385f9d7ecab82800ccda7c6684e9c4e1cf932f78c0c75f5daa1ec469a51086"},
2268 | {file = "pyobjc_framework_NetFS-6.2.2-py2.py3-none-any.whl", hash = "sha256:9934f64fcb06fb372166f1f08f5b84ef363dfd98467e6f4b32569d65fefb9ed5"},
2269 | ]
2270 | pyobjc-framework-network = [
2271 | {file = "pyobjc-framework-Network-6.2.2.tar.gz", hash = "sha256:91eed661d55293ed935a24c83a1745fa966b443d280ad85b41ec7046621917b6"},
2272 | {file = "pyobjc_framework_Network-6.2.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:89de1d32f0435b69d6183fc2991b543f8a894f46ad22391c42cfa5a45794c330"},
2273 | ]
2274 | pyobjc-framework-networkextension = [
2275 | {file = "pyobjc-framework-NetworkExtension-6.2.2.tar.gz", hash = "sha256:1d413d445e6736c5594615260816d1ebbf04e5d202c988be3042f842e172f76e"},
2276 | {file = "pyobjc_framework_NetworkExtension-6.2.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:ef6c7dda2efdf61ec32fb4c79b017996d37fa5f274b06e9cfb950ef62c10f197"},
2277 | ]
2278 | pyobjc-framework-notificationcenter = [
2279 | {file = "pyobjc-framework-NotificationCenter-6.2.2.tar.gz", hash = "sha256:79241e13b692f126544e149c3316ac766092e573e47f62f80b28a6c1060a05a1"},
2280 | {file = "pyobjc_framework_NotificationCenter-6.2.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:dd1d8a9a81d4ac29f1f0c12ba46884536622ed89b2e22bff8b82d1a4080cf17e"},
2281 | ]
2282 | pyobjc-framework-opendirectory = [
2283 | {file = "pyobjc-framework-OpenDirectory-6.2.2.tar.gz", hash = "sha256:c78b403848be3f72528845818d767e29db425f391602f41c76a873fb9a133d50"},
2284 | {file = "pyobjc_framework_OpenDirectory-6.2.2-py2.py3-none-any.whl", hash = "sha256:dce16813f5b72fd6fb536c289ae6d6e618843af9ed44dba57c5d6f7bbabd8e09"},
2285 | ]
2286 | pyobjc-framework-osakit = [
2287 | {file = "pyobjc-framework-OSAKit-6.2.2.tar.gz", hash = "sha256:8a7432023304d7b6b5b130182e29d9b67294ec73d2b0572966186db6bee9f61b"},
2288 | {file = "pyobjc_framework_OSAKit-6.2.2-py2.py3-none-any.whl", hash = "sha256:4ec4f0589fa863a0b0c242f5bc4f13e306d1b0412bd650bba4b36e924c1c87c3"},
2289 | ]
2290 | pyobjc-framework-oslog = [
2291 | {file = "pyobjc-framework-OSLog-6.2.2.tar.gz", hash = "sha256:574b05bdfb6913c0089c937af9f1fd8a88810701ed86e7bca4385376f47fe487"},
2292 | {file = "pyobjc_framework_OSLog-6.2.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:087839d1db5df76a922b054ea67262f4b9a132935129619d44e938426fa8081f"},
2293 | ]
2294 | pyobjc-framework-pencilkit = [
2295 | {file = "pyobjc-framework-PencilKit-6.2.2.tar.gz", hash = "sha256:2edb6e88f9d0093cf20a6b20bd8b646d918d246f1a9b523d176ba360c47f6e91"},
2296 | {file = "pyobjc_framework_PencilKit-6.2.2-py2.py3-none-any.whl", hash = "sha256:305fa33989294c97e0ec70ac9c9782883f40fbe3c45452a8f9fdd04e743b100f"},
2297 | ]
2298 | pyobjc-framework-photos = [
2299 | {file = "pyobjc-framework-Photos-6.2.2.tar.gz", hash = "sha256:6dd3598f9f3428641d8f95c5d64b87a5d83ee95a7cb5937284514626042cf275"},
2300 | {file = "pyobjc_framework_Photos-6.2.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:ffff560b7eb4f5abdacbae1d7568c02abd9cd63c30591b5328887d3b01572c39"},
2301 | ]
2302 | pyobjc-framework-photosui = [
2303 | {file = "pyobjc-framework-PhotosUI-6.2.2.tar.gz", hash = "sha256:6129cd970cba8f37dd8ee1c57484b7263470b7faf0a20341e5bb99b0ecf911f2"},
2304 | {file = "pyobjc_framework_PhotosUI-6.2.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:65f975301c3d9b193e56c0a60a1e0ecfd38a376f6b72abfd31a05a905f5e389c"},
2305 | ]
2306 | pyobjc-framework-preferencepanes = [
2307 | {file = "pyobjc-framework-PreferencePanes-6.2.2.tar.gz", hash = "sha256:8bda7a9cb9cd2844dedc79869fd7cd9275b7bf9c4845cf6ab6d64205172b4376"},
2308 | {file = "pyobjc_framework_PreferencePanes-6.2.2-py2.py3-none-any.whl", hash = "sha256:5e6cf700e0315c9ae75b56c4c528af6607044f147f2dcd58e0af7954955b2eaa"},
2309 | ]
2310 | pyobjc-framework-pubsub = [
2311 | {file = "pyobjc-framework-PubSub-6.2.2.tar.gz", hash = "sha256:519f6402a10f666f624cdcbbed35ec3919da5d0be77fb56d92e1b5be12f35ef1"},
2312 | {file = "pyobjc_framework_PubSub-6.2.2-py2.py3-none-any.whl", hash = "sha256:5307d630572905cbfeecf120875104d21f714cd32d7ce24c209edd1a72c0ffa6"},
2313 | ]
2314 | pyobjc-framework-pushkit = [
2315 | {file = "pyobjc-framework-PushKit-6.2.2.tar.gz", hash = "sha256:6454d70fb0140b7943027ae9e33f1bfd0a6dbd6c6a24b37e0e4a3f6a884c3c82"},
2316 | {file = "pyobjc_framework_PushKit-6.2.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:0018f99f713f1b2387db21f9a25e129bf90e9d2e55dd613051d2066fdb15226c"},
2317 | ]
2318 | pyobjc-framework-qtkit = [
2319 | {file = "pyobjc-framework-QTKit-6.2.2.tar.gz", hash = "sha256:fa750f227d6f32a5314d80b261fe77fa085ada31cf8865e4bfbbe828d22f84a2"},
2320 | {file = "pyobjc_framework_QTKit-6.2.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:ce01d41a21e4d6feaa2c00c6f022660aad5548bcf78bc3414e426e9f93eabef2"},
2321 | ]
2322 | pyobjc-framework-quartz = [
2323 | {file = "pyobjc-framework-Quartz-6.2.2.tar.gz", hash = "sha256:5a56cfc0289061eaf33f04e3c73e749e04f177b0c1ee8749aa46e87d1e897cda"},
2324 | {file = "pyobjc_framework_Quartz-6.2.2-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:56d183dc32b11f15ceb0833a2a24953d1212264f07c274e2b8878e691eb72472"},
2325 | {file = "pyobjc_framework_Quartz-6.2.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a57c7f50286d96ee7b9051c657a8607f0449949891cf0697be3efac76a97be7e"},
2326 | {file = "pyobjc_framework_Quartz-6.2.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:552b15eb409f87d34870345feabe6695375a031d8c4063f175dbaa3422005160"},
2327 | {file = "pyobjc_framework_Quartz-6.2.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:15f3c7b50d0543f66b927e28cd336c1a6962d58c9808799f49dcf30e4a1a13c2"},
2328 | ]
2329 | pyobjc-framework-quicklookthumbnailing = [
2330 | {file = "pyobjc-framework-QuickLookThumbnailing-6.2.2.tar.gz", hash = "sha256:2a34eb83813a2aa5fbe072cbe03d5557b8e80449fbc788e7008994b22417d580"},
2331 | {file = "pyobjc_framework_QuickLookThumbnailing-6.2.2-py2.py3-none-any.whl", hash = "sha256:fb66393583f4e3a3a7b56d0d209d5dd590f59c3133d5ccd5a9fced3b314e9d44"},
2332 | ]
2333 | pyobjc-framework-safariservices = [
2334 | {file = "pyobjc-framework-SafariServices-6.2.2.tar.gz", hash = "sha256:396a7fca2d5ff039a9031b9d1f54080a334e26b2cf10664e5568b49487c32e9a"},
2335 | {file = "pyobjc_framework_SafariServices-6.2.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:9624e27795b28419486a461b2a5f84e100eb4c1ce74fca88d31c4133c77329b9"},
2336 | ]
2337 | pyobjc-framework-scenekit = [
2338 | {file = "pyobjc-framework-SceneKit-6.2.2.tar.gz", hash = "sha256:b0a0a5866220aa9972248556f9a09e4f14f316870f9f4e12c3d666594a7cb33b"},
2339 | {file = "pyobjc_framework_SceneKit-6.2.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:991fa198396af69200dad314258c3f3aeec7028a0a09e50333c0e4d392c0626d"},
2340 | ]
2341 | pyobjc-framework-screensaver = [
2342 | {file = "pyobjc-framework-ScreenSaver-6.2.2.tar.gz", hash = "sha256:f0479f1c6ce1bdbc8723a9194b9ee9a3c87ddd82dbc16e59dc1bb9a58326453b"},
2343 | {file = "pyobjc_framework_ScreenSaver-6.2.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:eb057b5c1c6a82c5ba9e7c64c93f07ffed18b8e4432c7c56da4df97940bba5b1"},
2344 | ]
2345 | pyobjc-framework-scriptingbridge = [
2346 | {file = "pyobjc-framework-ScriptingBridge-6.2.2.tar.gz", hash = "sha256:f3f659351f6686ebabafce955a2d55e4f32c791c755f27641b37b5cd9974c037"},
2347 | {file = "pyobjc_framework_ScriptingBridge-6.2.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:a0e03297e404bbdbcc4a51a1dfa271ce9b9a7dd9a123ae5e9b303668be246e6a"},
2348 | ]
2349 | pyobjc-framework-searchkit = [
2350 | {file = "pyobjc-framework-SearchKit-6.2.2.tar.gz", hash = "sha256:2830e820a6edff87712973f015e888188b1a16256e58bec10497725da1a907f3"},
2351 | {file = "pyobjc_framework_SearchKit-6.2.2-py2.py3-none-any.whl", hash = "sha256:1bb41f5c7c1a0885d7039acc024c4ec94140b639b27f3302ce4c8162f096e3ca"},
2352 | ]
2353 | pyobjc-framework-security = [
2354 | {file = "pyobjc-framework-Security-6.2.2.tar.gz", hash = "sha256:c53d9f6d83edeb9a55e793f01a6d1b7d8d1a6a23f023db05cac86cde327f829c"},
2355 | {file = "pyobjc_framework_Security-6.2.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:1c38a5df00e1547431ab072ba0e4e942c43da14be505cac9502a8c6fde6671ac"},
2356 | ]
2357 | pyobjc-framework-securityfoundation = [
2358 | {file = "pyobjc-framework-SecurityFoundation-6.2.2.tar.gz", hash = "sha256:dd2a8f0ca051d756a8c7a7272de7d44e426ba76a417b947fc49cc3c3c8427aa3"},
2359 | {file = "pyobjc_framework_SecurityFoundation-6.2.2-py2.py3-none-any.whl", hash = "sha256:b9b01a4228dadf82d86feabcea8c08facaadf59fbe22a0881025db88318916e9"},
2360 | ]
2361 | pyobjc-framework-securityinterface = [
2362 | {file = "pyobjc-framework-SecurityInterface-6.2.2.tar.gz", hash = "sha256:f5e379789cedc96908e9be021033d2228dd36c30dc804e59495854e443db8e16"},
2363 | {file = "pyobjc_framework_SecurityInterface-6.2.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:3645e11780b45ec819354e593895f7eb7c81ac968fb3e3984dfafe0ea4fbc0bf"},
2364 | ]
2365 | pyobjc-framework-servernotification = [
2366 | {file = "pyobjc-framework-ServerNotification-6.2.2.tar.gz", hash = "sha256:e7a745f9d43fed99d1b06b2e06cc0e651aaca74a7905fbe3860f27f6e485801a"},
2367 | {file = "pyobjc_framework_ServerNotification-6.2.2-py2.py3-none-any.whl", hash = "sha256:9bbbfaaa3023318a11faa0bf246e64bd13c380bb08b31fab61d83487383e17a6"},
2368 | ]
2369 | pyobjc-framework-servicemanagement = [
2370 | {file = "pyobjc-framework-ServiceManagement-6.2.2.tar.gz", hash = "sha256:c2483005f132c8ec6912662505d2962d72e37f966388d482a87c1344c25eedd4"},
2371 | {file = "pyobjc_framework_ServiceManagement-6.2.2-py2.py3-none-any.whl", hash = "sha256:20690aa93a8476d6b6b7693679c8288383cef45c6483a79a0880e69f86acab59"},
2372 | ]
2373 | pyobjc-framework-social = [
2374 | {file = "pyobjc-framework-Social-6.2.2.tar.gz", hash = "sha256:95a4e33bbe30c7fa627dc8f5a5b726a8354ea24005ddffacb2d477648b263077"},
2375 | {file = "pyobjc_framework_Social-6.2.2-py2.py3-none-any.whl", hash = "sha256:7331dd9084728d8b5df53bb38ccc77672e45c52726020e63e7c1c00263a85fcd"},
2376 | ]
2377 | pyobjc-framework-soundanalysis = [
2378 | {file = "pyobjc-framework-SoundAnalysis-6.2.2.tar.gz", hash = "sha256:31a3d3e6c12468f5840c7ea66f2b571bd3443634868e57f6038c9e60b07fd43b"},
2379 | {file = "pyobjc_framework_SoundAnalysis-6.2.2-py2.py3-none-any.whl", hash = "sha256:80edaa071e9d880751bc67293679a235cf6083b713f0a362a29376f42efb5370"},
2380 | ]
2381 | pyobjc-framework-speech = [
2382 | {file = "pyobjc-framework-Speech-6.2.2.tar.gz", hash = "sha256:6ff32726896b56dbf26990dbf1cadd64c2066865331ba926ff580a837f9a57d9"},
2383 | {file = "pyobjc_framework_Speech-6.2.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:95b8c6cc380ca33835343ec66b3d97279a03ed1eeb5609f0e5178a53aa61b146"},
2384 | ]
2385 | pyobjc-framework-spritekit = [
2386 | {file = "pyobjc-framework-SpriteKit-6.2.2.tar.gz", hash = "sha256:5523cd33bb3b906fbb354a4bfd910629863014004aab0ed1764083fdf5c91eeb"},
2387 | {file = "pyobjc_framework_SpriteKit-6.2.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:c63c700f03cae3861895d9d78fae2bd477d1440f8595ece2dde68b140ac2dc75"},
2388 | ]
2389 | pyobjc-framework-storekit = [
2390 | {file = "pyobjc-framework-StoreKit-6.2.2.tar.gz", hash = "sha256:3fdbcd185c4452f102af9e1d9e3d37757f5afcdac6ef315bc0f73f2a9db8146d"},
2391 | {file = "pyobjc_framework_StoreKit-6.2.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:0e64ae84c4b8af354b51a5f784f1e2b4eb2f51ec1a9969775e676543901e81df"},
2392 | ]
2393 | pyobjc-framework-syncservices = [
2394 | {file = "pyobjc-framework-SyncServices-6.2.2.tar.gz", hash = "sha256:645490178ee95d9bb554cde8e9180e6c490ed112f3691a3fe258b34a9b5d3deb"},
2395 | {file = "pyobjc_framework_SyncServices-6.2.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:fc4c00da0cb2f838e798c88208994eee5cdc4fc2ce11fbd72189acff96a89ae6"},
2396 | ]
2397 | pyobjc-framework-systemconfiguration = [
2398 | {file = "pyobjc-framework-SystemConfiguration-6.2.2.tar.gz", hash = "sha256:1611f6c561669beff0bad18a9f4fe0724424acc92ed47cc8fc3949532402c95d"},
2399 | {file = "pyobjc_framework_SystemConfiguration-6.2.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:cef76b15fe09f3a3457a1de97cdcd619953d22b416f46c74b927909bf988f361"},
2400 | ]
2401 | pyobjc-framework-systemextensions = [
2402 | {file = "pyobjc-framework-SystemExtensions-6.2.2.tar.gz", hash = "sha256:386586e9d7d87a9b8ccb267d62fb7f950de063f890c89c7e4728f22289a892fe"},
2403 | {file = "pyobjc_framework_SystemExtensions-6.2.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:35e06352764f5b2c6fc10c589990feb56c6ae0efdc35cf6e9c63a49cba741ff2"},
2404 | ]
2405 | pyobjc-framework-usernotifications = [
2406 | {file = "pyobjc-framework-UserNotifications-6.2.2.tar.gz", hash = "sha256:40b0cad22ba3f55ed1d25248abcfcb2f3c15064c3c00027e3dcf8ce7be832b22"},
2407 | {file = "pyobjc_framework_UserNotifications-6.2.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:aba54a959e129e186467ea5f55e47484cd7244507a0494d73c28906b3c44fdcd"},
2408 | ]
2409 | pyobjc-framework-videosubscriberaccount = [
2410 | {file = "pyobjc-framework-VideoSubscriberAccount-6.2.2.tar.gz", hash = "sha256:2a4d38e6a5b2de5493c5836b24de06a288b7ed1973a36a209553b789d466774a"},
2411 | {file = "pyobjc_framework_VideoSubscriberAccount-6.2.2-py2.py3-none-any.whl", hash = "sha256:0d73209cca77d5e63f783914942766cac94cf06c59467ad085dc62c3edadbb0d"},
2412 | ]
2413 | pyobjc-framework-videotoolbox = [
2414 | {file = "pyobjc-framework-VideoToolbox-6.2.2.tar.gz", hash = "sha256:ae60fcfc3f9e8c2e38882b34c87df71b5585c2a7e37dfbf3a23e32c406f95e86"},
2415 | {file = "pyobjc_framework_VideoToolbox-6.2.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:0336cc8bcdff16ab6f537286334339cb390731b3d98aa9810e34727ee2155674"},
2416 | ]
2417 | pyobjc-framework-vision = [
2418 | {file = "pyobjc-framework-Vision-6.2.2.tar.gz", hash = "sha256:dc03fea57cc52ba15a2b39be6e834cfd49a6e28daf9b862a578a8002a6fc5207"},
2419 | {file = "pyobjc_framework_Vision-6.2.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:b78028ab15c3758af1a2f3f82b69880b7db481a29ab6defe0fcf839f39c83554"},
2420 | ]
2421 | pyobjc-framework-webkit = [
2422 | {file = "pyobjc-framework-WebKit-6.2.2.tar.gz", hash = "sha256:87e9409ace6d2e29c776bd76df75fe922a1f2a225eef815640c6047d25da8dab"},
2423 | {file = "pyobjc_framework_WebKit-6.2.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:b04e08ad08720a87934ba57005fb561d081fbb7f4c12b20e78d0e740e433d06f"},
2424 | ]
2425 | pyobjc-framework-xgridfoundation = [
2426 | {file = "pyobjc-framework-XgridFoundation-6.2.2.tar.gz", hash = "sha256:02033b88ed90133f1e17fe3c6c0c305b698ea701e9ed8967bce186e69b1e6c7c"},
2427 | {file = "pyobjc_framework_XgridFoundation-6.2.2-py2.py3-none-any.whl", hash = "sha256:27f44ff1f2776d4596b5d99076d2458c1576d7cc73b8c1f740eab4f7256836e7"},
2428 | ]
2429 | pyyaml = [
2430 | {file = "PyYAML-5.3.1-cp27-cp27m-win32.whl", hash = "sha256:74809a57b329d6cc0fdccee6318f44b9b8649961fa73144a98735b0aaf029f1f"},
2431 | {file = "PyYAML-5.3.1-cp27-cp27m-win_amd64.whl", hash = "sha256:240097ff019d7c70a4922b6869d8a86407758333f02203e0fc6ff79c5dcede76"},
2432 | {file = "PyYAML-5.3.1-cp35-cp35m-win32.whl", hash = "sha256:4f4b913ca1a7319b33cfb1369e91e50354d6f07a135f3b901aca02aa95940bd2"},
2433 | {file = "PyYAML-5.3.1-cp35-cp35m-win_amd64.whl", hash = "sha256:cc8955cfbfc7a115fa81d85284ee61147059a753344bc51098f3ccd69b0d7e0c"},
2434 | {file = "PyYAML-5.3.1-cp36-cp36m-win32.whl", hash = "sha256:7739fc0fa8205b3ee8808aea45e968bc90082c10aef6ea95e855e10abf4a37b2"},
2435 | {file = "PyYAML-5.3.1-cp36-cp36m-win_amd64.whl", hash = "sha256:69f00dca373f240f842b2931fb2c7e14ddbacd1397d57157a9b005a6a9942648"},
2436 | {file = "PyYAML-5.3.1-cp37-cp37m-win32.whl", hash = "sha256:d13155f591e6fcc1ec3b30685d50bf0711574e2c0dfffd7644babf8b5102ca1a"},
2437 | {file = "PyYAML-5.3.1-cp37-cp37m-win_amd64.whl", hash = "sha256:73f099454b799e05e5ab51423c7bcf361c58d3206fa7b0d555426b1f4d9a3eaf"},
2438 | {file = "PyYAML-5.3.1-cp38-cp38-win32.whl", hash = "sha256:06a0d7ba600ce0b2d2fe2e78453a470b5a6e000a985dd4a4e54e436cc36b0e97"},
2439 | {file = "PyYAML-5.3.1-cp38-cp38-win_amd64.whl", hash = "sha256:95f71d2af0ff4227885f7a6605c37fd53d3a106fcab511b8860ecca9fcf400ee"},
2440 | {file = "PyYAML-5.3.1.tar.gz", hash = "sha256:b8eac752c5e14d3eca0e6dd9199cd627518cb5ec06add0de9d32baeee6fe645d"},
2441 | ]
2442 | six = [
2443 | {file = "six-1.15.0-py2.py3-none-any.whl", hash = "sha256:8b74bedcbbbaca38ff6d7491d76f2b06b3592611af620f8426e82dddb04a5ced"},
2444 | {file = "six-1.15.0.tar.gz", hash = "sha256:30639c035cdb23534cd4aa2dd52c3bf48f06e5f4a941509c8bafd8ce11080259"},
2445 | ]
2446 | toml = [
2447 | {file = "toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b"},
2448 | {file = "toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"},
2449 | ]
2450 | virtualenv = [
2451 | {file = "virtualenv-20.1.0-py2.py3-none-any.whl", hash = "sha256:b0011228208944ce71052987437d3843e05690b2f23d1c7da4263fde104c97a2"},
2452 | {file = "virtualenv-20.1.0.tar.gz", hash = "sha256:b8d6110f493af256a40d65e29846c69340a947669eec8ce784fcf3dd3af28380"},
2453 | ]
2454 | zipp = [
2455 | {file = "zipp-3.4.0-py3-none-any.whl", hash = "sha256:102c24ef8f171fd729d46599845e95c7ab894a4cf45f5de11a44cc7444fb1108"},
2456 | {file = "zipp-3.4.0.tar.gz", hash = "sha256:ed5eee1974372595f9e416cc7bbeeb12335201d8081ca8a0743c954d4446e5cb"},
2457 | ]
2458 |
--------------------------------------------------------------------------------
/pyproject.toml:
--------------------------------------------------------------------------------
1 | [tool.poetry]
2 | name = "cmus-osx"
3 | version = "3.0.6"
4 | description = "Adds track change notifications, and media key support to cmus."
5 | authors = ["Philip Trauner "]
6 | license = "MIT"
7 | readme = "README.md"
8 |
9 | [tool.poetry.dependencies]
10 | python = "^3.7"
11 | mutagen = "^1.42"
12 | pyobjc = "^6.2"
13 | click = "^7.0"
14 | Pillow = "^8.0"
15 |
16 | [tool.poetry.dev-dependencies]
17 | pre-commit = "^1.18"
18 |
19 | [tool.poetry.scripts]
20 | cmus-osx = "cmus_osx:entrypoint"
21 |
22 | [build-system]
23 | requires = ["poetry>=0.12"]
24 | build-backend = "poetry.masonry.api"
25 |
--------------------------------------------------------------------------------