mirror of
https://github.com/Textualize/textual.git
synced 2025-10-17 02:38:12 +03:00
docs and refactor
This commit is contained in:
1
docs/api/markdown.md
Normal file
1
docs/api/markdown.md
Normal file
@@ -0,0 +1 @@
|
||||
::: textual.widgets.Markdown
|
||||
1
docs/api/markdown_viewer.md
Normal file
1
docs/api/markdown_viewer.md
Normal file
@@ -0,0 +1 @@
|
||||
::: textual.widgets.MarkdownViewer
|
||||
28
docs/examples/widgets/markdown.py
Normal file
28
docs/examples/widgets/markdown.py
Normal file
@@ -0,0 +1,28 @@
|
||||
from textual.app import App, ComposeResult
|
||||
from textual.widgets import Markdown
|
||||
|
||||
EXAMPLE_MARKDOWN = """\
|
||||
# Markdown Document
|
||||
|
||||
This is an example of Textual's `Markdown` widget.
|
||||
|
||||
## Features
|
||||
|
||||
Markdown syntax and extensions are supported.
|
||||
|
||||
- Typography *emphasis*, **strong**, `inline code` etc.
|
||||
- Headers
|
||||
- Lists (bullet and ordered)
|
||||
- Syntax highlighted code blocks
|
||||
- Tables!
|
||||
"""
|
||||
|
||||
|
||||
class MarkdownExampleApp(App):
|
||||
def compose(self) -> ComposeResult:
|
||||
yield Markdown(EXAMPLE_MARKDOWN)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
app = MarkdownExampleApp()
|
||||
app.run()
|
||||
60
docs/examples/widgets/markdown_viewer.py
Normal file
60
docs/examples/widgets/markdown_viewer.py
Normal file
@@ -0,0 +1,60 @@
|
||||
from textual.app import App, ComposeResult
|
||||
from textual.widgets import MarkdownViewer
|
||||
|
||||
EXAMPLE_MARKDOWN = """\
|
||||
# Markdown Viewer
|
||||
|
||||
This is an example of Textual's `MarkdownViewer` widget.
|
||||
|
||||
|
||||
## Features
|
||||
|
||||
Markdown syntax and extensions are supported.
|
||||
|
||||
- Typography *emphasis*, **strong**, `inline code` etc.
|
||||
- Headers
|
||||
- Lists (bullet and ordered)
|
||||
- Syntax highlighted code blocks
|
||||
- Tables!
|
||||
|
||||
## Tables
|
||||
|
||||
Tables are displayed in a DataTable widget.
|
||||
|
||||
| Name | Type | Default | Description |
|
||||
| --------------- | ------ | ------- | ---------------------------------- |
|
||||
| `show_header` | `bool` | `True` | Show the table header |
|
||||
| `fixed_rows` | `int` | `0` | Number of fixed rows |
|
||||
| `fixed_columns` | `int` | `0` | Number of fixed columns |
|
||||
| `zebra_stripes` | `bool` | `False` | Display alternating colors on rows |
|
||||
| `header_height` | `int` | `1` | Height of header row |
|
||||
| `show_cursor` | `bool` | `True` | Show a cell cursor |
|
||||
|
||||
|
||||
## Code Blocks
|
||||
|
||||
Code blocks are syntax highlighted, with guidelines.
|
||||
|
||||
```python
|
||||
class ListViewExample(App):
|
||||
def compose(self) -> ComposeResult:
|
||||
yield ListView(
|
||||
ListItem(Label("One")),
|
||||
ListItem(Label("Two")),
|
||||
ListItem(Label("Three")),
|
||||
)
|
||||
yield Footer()
|
||||
```
|
||||
|
||||
|
||||
"""
|
||||
|
||||
|
||||
class MarkdownExampleApp(App):
|
||||
def compose(self) -> ComposeResult:
|
||||
yield MarkdownViewer(EXAMPLE_MARKDOWN, show_toc=True)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
app = MarkdownExampleApp()
|
||||
app.run()
|
||||
40
docs/widgets/markdown.md
Normal file
40
docs/widgets/markdown.md
Normal file
@@ -0,0 +1,40 @@
|
||||
# Markdown
|
||||
|
||||
A widget to display a Markdown document.
|
||||
|
||||
- [x] Focusable
|
||||
- [ ] Container
|
||||
|
||||
|
||||
!!! tip
|
||||
|
||||
See [MarkdownViewer](./markdown_viewer.md) for a widget that adds additional features such as a Table of Contents.
|
||||
|
||||
## Example
|
||||
|
||||
The following example displays Markdown from a string.
|
||||
|
||||
=== "Output"
|
||||
|
||||
```{.textual path="docs/examples/widgets/markdown.py"}
|
||||
```
|
||||
|
||||
=== "markdown.py"
|
||||
|
||||
~~~python
|
||||
--8<-- "docs/examples/widgets/markdown.py"
|
||||
~~~
|
||||
|
||||
## Messages
|
||||
|
||||
### ::: textual.widgets.Markdown.TOCUpdated
|
||||
|
||||
### ::: textual.widgets.Markdown.TOCSelected
|
||||
|
||||
### ::: textual.widgets.Markdown.LinkClicked
|
||||
|
||||
|
||||
## See Also
|
||||
|
||||
* [Markdown][textual.widgets.Markdown] code reference
|
||||
* [MarkdownViewer][textual.widgets.MarkdownViewer] code reference
|
||||
37
docs/widgets/markdown_viewer.md
Normal file
37
docs/widgets/markdown_viewer.md
Normal file
@@ -0,0 +1,37 @@
|
||||
# Markdown Viewer
|
||||
|
||||
A Widget to display Markdown content with an optional Table of Contents.
|
||||
|
||||
- [x] Focusable
|
||||
- [ ] Container
|
||||
|
||||
!!! note
|
||||
|
||||
This Widget adds browser-like functionality on top of the [Markdown](./markdown.md) widget.
|
||||
|
||||
|
||||
## Example
|
||||
|
||||
The following example displays Markdown from a string and a Table of Contents.
|
||||
|
||||
=== "Output"
|
||||
|
||||
```{.textual path="docs/examples/widgets/markdown_viewer.py" columns="100" lines="42"}
|
||||
```
|
||||
|
||||
=== "markdown.py"
|
||||
|
||||
~~~python
|
||||
--8<-- "docs/examples/widgets/markdown_viewer.py"
|
||||
~~~
|
||||
|
||||
## Reactive Attributes
|
||||
|
||||
| Name | Type | Default | Description |
|
||||
| ---------- | ---- | ------- | ----------------------------------------------------------------- |
|
||||
| `show_toc` | bool | True | Wether a Table of Contents should be displayed with the Markdown. |
|
||||
|
||||
## See Also
|
||||
|
||||
* [MarkdownViewer][textual.widgets.MarkdownViewer] code reference
|
||||
* [Markdown][textual.widgets.Markdown] code reference
|
||||
9
examples/demo.md
Normal file
9
examples/demo.md
Normal file
@@ -0,0 +1,9 @@
|
||||
# Textual Markdown Browser
|
||||
|
||||
Welcome fellow adventurer! If you ran `markdown.py` from the terminal you are viewing `demo.md` with Textual's built in Markdown widget.
|
||||
|
||||
The widget supports much of the Markdown spec. THere is also an optional Table of Contents sidebar which you will see to your left.
|
||||
|
||||
## Do You Want to Know More?
|
||||
|
||||
See [example.md](./example.md) for more examples of what this can do.
|
||||
129
examples/example.md
Normal file
129
examples/example.md
Normal file
@@ -0,0 +1,129 @@
|
||||
# Textual Markdown Browser - Demo
|
||||
|
||||
This Markdown file contains some examples of Markdown widgets.
|
||||
|
||||
## Headers
|
||||
|
||||
Headers levels 1 through 6 are supported.
|
||||
|
||||
### This is H3
|
||||
|
||||
This is H3 Content
|
||||
|
||||
#### This is H4
|
||||
|
||||
Header level 4 content. Drilling down in to finer headings.
|
||||
|
||||
##### This is H5
|
||||
|
||||
Header level 5 content.
|
||||
|
||||
###### This is H6
|
||||
|
||||
Header level 6 content.
|
||||
|
||||
## Typography
|
||||
|
||||
The usual Markdown typography is supported. The exact output depends on your terminal, although most are fairly consistent.
|
||||
|
||||
### Emphasis
|
||||
|
||||
Emphasis is rendered with `*asterisks*`, and looks *like this*;
|
||||
|
||||
### Strong
|
||||
|
||||
Use two asterisks to indicate strong which renders in bold, e.g. `**strong**` render **strong**.
|
||||
|
||||
### Strikethrough
|
||||
|
||||
Two tildes indicates strikethrough, e.g. `~~cross out~~` render ~~cross out~~.
|
||||
|
||||
### Inline code ###
|
||||
|
||||
Inline cod is indicated by backticks. e.g. `import this`.
|
||||
|
||||
## Fences
|
||||
|
||||
Fenced code blocks are introduced with three back-ticks and the optional parser. Here we are rendering the code in a sub-widget with syntax highlighting and indent guides.
|
||||
|
||||
In the future I think we could add controls to export the code, copy to the clipboard. Heck, even run it and show the output?
|
||||
|
||||
```python
|
||||
@lru_cache(maxsize=1024)
|
||||
def split(self, cut_x: int, cut_y: int) -> tuple[Region, Region, Region, Region]:
|
||||
"""Split a region in to 4 from given x and y offsets (cuts).
|
||||
|
||||
```
|
||||
cut_x ↓
|
||||
┌────────┐ ┌───┐
|
||||
│ │ │ │
|
||||
│ 0 │ │ 1 │
|
||||
│ │ │ │
|
||||
cut_y → └────────┘ └───┘
|
||||
┌────────┐ ┌───┐
|
||||
│ 2 │ │ 3 │
|
||||
└────────┘ └───┘
|
||||
```
|
||||
|
||||
Args:
|
||||
cut_x (int): Offset from self.x where the cut should be made. If negative, the cut
|
||||
is taken from the right edge.
|
||||
cut_y (int): Offset from self.y where the cut should be made. If negative, the cut
|
||||
is taken from the lower edge.
|
||||
|
||||
Returns:
|
||||
tuple[Region, Region, Region, Region]: Four new regions which add up to the original (self).
|
||||
"""
|
||||
|
||||
x, y, width, height = self
|
||||
if cut_x < 0:
|
||||
cut_x = width + cut_x
|
||||
if cut_y < 0:
|
||||
cut_y = height + cut_y
|
||||
|
||||
_Region = Region
|
||||
return (
|
||||
_Region(x, y, cut_x, cut_y),
|
||||
_Region(x + cut_x, y, width - cut_x, cut_y),
|
||||
_Region(x, y + cut_y, cut_x, height - cut_y),
|
||||
_Region(x + cut_x, y + cut_y, width - cut_x, height - cut_y),
|
||||
)
|
||||
```
|
||||
|
||||
## Quote
|
||||
|
||||
Quotes are introduced with a chevron, and render like this:
|
||||
|
||||
> I must not fear.
|
||||
> Fear is the mind-killer.
|
||||
> Fear is the little-death that brings total obliteration.
|
||||
> I will face my fear.
|
||||
> I will permit it to pass over me and through me.
|
||||
> And when it has gone past, I will turn the inner eye to see its path.
|
||||
> Where the fear has gone there will be nothing. Only I will remain."
|
||||
|
||||
Quotes nest nicely. Here's what quotes within quotes look like:
|
||||
|
||||
> I must not fear.
|
||||
> > Fear is the mind-killer.
|
||||
> > Fear is the little-death that brings total obliteration.
|
||||
> > I will face my fear.
|
||||
> > > I will permit it to pass over me and through me.
|
||||
> > > And when it has gone past, I will turn the inner eye to see its path.
|
||||
> > > Where the fear has gone there will be nothing. Only I will remain.
|
||||
|
||||
## Tables
|
||||
|
||||
Tables are supported, and render with a DataTable.
|
||||
|
||||
I would like to add controls to these widgets to export the table as CSV, which I think would be a nice feature. In the future we might also have sortable columns by clicking on the headers.
|
||||
|
||||
|
||||
| Name | Type | Default | Description |
|
||||
| --------------- | ------ | ------- | ---------------------------------- |
|
||||
| `show_header` | `bool` | `True` | Show the table header |
|
||||
| `fixed_rows` | `int` | `0` | Number of fixed rows |
|
||||
| `fixed_columns` | `int` | `0` | Number of fixed columns |
|
||||
| `zebra_stripes` | `bool` | `False` | Display alternating colors on rows |
|
||||
| `header_height` | `int` | `1` | Height of header row |
|
||||
| `show_cursor` | `bool` | `True` | Show a cell cursor |
|
||||
41
examples/markdown.py
Normal file
41
examples/markdown.py
Normal file
@@ -0,0 +1,41 @@
|
||||
from textual.app import App, ComposeResult
|
||||
from textual.reactive import var
|
||||
from textual.widgets import Footer, MarkdownViewer
|
||||
|
||||
|
||||
class MarkdownApp(App):
|
||||
BINDINGS = [
|
||||
("t", "toggle_toc", "TOC"),
|
||||
("b", "back", "Back"),
|
||||
("f", "forward", "Forward"),
|
||||
]
|
||||
|
||||
path = var("demo.md")
|
||||
|
||||
@property
|
||||
def markdown_viewer(self) -> MarkdownViewer:
|
||||
"""Get the Markdown widget."""
|
||||
return self.query_one(MarkdownViewer)
|
||||
|
||||
def compose(self) -> ComposeResult:
|
||||
yield Footer()
|
||||
yield MarkdownViewer()
|
||||
|
||||
async def on_mount(self) -> None:
|
||||
self.markdown_viewer.focus()
|
||||
if not await self.markdown_viewer.go(self.path):
|
||||
self.exit(message=f"Unable to load {self.path!r}")
|
||||
|
||||
def action_toggle_toc(self) -> None:
|
||||
self.markdown_viewer.show_toc = not self.markdown_viewer.show_toc
|
||||
|
||||
async def action_back(self) -> None:
|
||||
await self.markdown_viewer.back()
|
||||
|
||||
async def action_forward(self) -> None:
|
||||
await self.markdown_viewer.forward()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
app = MarkdownApp()
|
||||
app.run()
|
||||
@@ -130,13 +130,14 @@ nav:
|
||||
- "widgets/label.md"
|
||||
- "widgets/list_item.md"
|
||||
- "widgets/list_view.md"
|
||||
- "widgets/markdown_viewer.md"
|
||||
- "widgets/markdown.md"
|
||||
- "widgets/placeholder.md"
|
||||
- "widgets/static.md"
|
||||
- "widgets/switch.md"
|
||||
- "widgets/text_log.md"
|
||||
- "widgets/tree.md"
|
||||
- API:
|
||||
- "api/index.md"
|
||||
- "api/app.md"
|
||||
- "api/binding.md"
|
||||
- "api/button.md"
|
||||
@@ -150,10 +151,13 @@ nav:
|
||||
- "api/footer.md"
|
||||
- "api/geometry.md"
|
||||
- "api/header.md"
|
||||
- "api/index.md"
|
||||
- "api/input.md"
|
||||
- "api/label.md"
|
||||
- "api/list_view.md"
|
||||
- "api/list_item.md"
|
||||
- "api/list_view.md"
|
||||
- "api/markdown_viewer.md"
|
||||
- "api/markdown.md"
|
||||
- "api/message_pump.md"
|
||||
- "api/message.md"
|
||||
- "api/pilot.md"
|
||||
@@ -167,8 +171,8 @@ nav:
|
||||
- "api/switch.md"
|
||||
- "api/text_log.md"
|
||||
- "api/timer.md"
|
||||
- "api/tree.md"
|
||||
- "api/tree_node.md"
|
||||
- "api/tree.md"
|
||||
- "api/walk.md"
|
||||
- "api/widget.md"
|
||||
- "Blog":
|
||||
|
||||
365
poetry.lock
generated
365
poetry.lock
generated
@@ -1,6 +1,6 @@
|
||||
[[package]]
|
||||
name = "aiohttp"
|
||||
version = "3.8.3"
|
||||
version = "3.8.4"
|
||||
description = "Async http client/server framework (asyncio)"
|
||||
category = "main"
|
||||
optional = false
|
||||
@@ -11,7 +11,7 @@ aiosignal = ">=1.1.2"
|
||||
async-timeout = ">=4.0.0a3,<5.0"
|
||||
asynctest = {version = "0.13.0", markers = "python_version < \"3.8\""}
|
||||
attrs = ">=17.3.0"
|
||||
charset-normalizer = ">=2.0,<3.0"
|
||||
charset-normalizer = ">=2.0,<4.0"
|
||||
frozenlist = ">=1.1.1"
|
||||
multidict = ">=4.5,<7.0"
|
||||
typing-extensions = {version = ">=3.7.4", markers = "python_version < \"3.8\""}
|
||||
@@ -133,14 +133,11 @@ python-versions = ">=3.6.1"
|
||||
|
||||
[[package]]
|
||||
name = "charset-normalizer"
|
||||
version = "2.1.1"
|
||||
version = "3.0.1"
|
||||
description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet."
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.6.0"
|
||||
|
||||
[package.extras]
|
||||
unicode-backport = ["unicodedata2"]
|
||||
python-versions = "*"
|
||||
|
||||
[[package]]
|
||||
name = "click"
|
||||
@@ -323,7 +320,7 @@ socks = ["socksio (>=1.0.0,<2.0.0)"]
|
||||
|
||||
[[package]]
|
||||
name = "identify"
|
||||
version = "2.5.17"
|
||||
version = "2.5.18"
|
||||
description = "File identification library for Python"
|
||||
category = "dev"
|
||||
optional = false
|
||||
@@ -379,6 +376,23 @@ MarkupSafe = ">=2.0"
|
||||
[package.extras]
|
||||
i18n = ["Babel (>=2.7)"]
|
||||
|
||||
[[package]]
|
||||
name = "linkify-it-py"
|
||||
version = "1.0.3"
|
||||
description = "Links recognition library with FULL unicode support."
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.6"
|
||||
|
||||
[package.dependencies]
|
||||
uc-micro-py = "*"
|
||||
|
||||
[package.extras]
|
||||
benchmark = ["pytest", "pytest-benchmark"]
|
||||
dev = ["black", "flake8", "isort", "pre-commit"]
|
||||
doc = ["myst-parser", "sphinx", "sphinx-book-theme"]
|
||||
test = ["coverage", "pytest", "pytest-cov"]
|
||||
|
||||
[[package]]
|
||||
name = "markdown"
|
||||
version = "3.3.7"
|
||||
@@ -402,6 +416,8 @@ optional = false
|
||||
python-versions = ">=3.7"
|
||||
|
||||
[package.dependencies]
|
||||
linkify-it-py = {version = ">=1.0,<2.0", optional = true, markers = "extra == \"linkify\""}
|
||||
mdit-py-plugins = {version = "*", optional = true, markers = "extra == \"plugins\""}
|
||||
mdurl = ">=0.1,<1.0"
|
||||
typing_extensions = {version = ">=3.7.4", markers = "python_version < \"3.8\""}
|
||||
|
||||
@@ -423,6 +439,22 @@ category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
|
||||
[[package]]
|
||||
name = "mdit-py-plugins"
|
||||
version = "0.3.3"
|
||||
description = "Collection of plugins for markdown-it-py"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
|
||||
[package.dependencies]
|
||||
markdown-it-py = ">=1.0.0,<3.0.0"
|
||||
|
||||
[package.extras]
|
||||
code-style = ["pre-commit"]
|
||||
rtd = ["attrs", "myst-parser (>=0.16.1,<0.17.0)", "sphinx-book-theme (>=0.1.0,<0.2.0)"]
|
||||
testing = ["coverage", "pytest", "pytest-cov", "pytest-regressions"]
|
||||
|
||||
[[package]]
|
||||
name = "mdurl"
|
||||
version = "0.1.2"
|
||||
@@ -490,7 +522,7 @@ mkdocs = "*"
|
||||
|
||||
[[package]]
|
||||
name = "mkdocs-material"
|
||||
version = "9.0.11"
|
||||
version = "9.0.12"
|
||||
description = "Documentation that simply works"
|
||||
category = "dev"
|
||||
optional = false
|
||||
@@ -619,14 +651,6 @@ category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.5"
|
||||
|
||||
[[package]]
|
||||
name = "nanoid"
|
||||
version = "2.0.0"
|
||||
description = "A tiny, secure, URL-friendly, unique string ID generator for Python"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
|
||||
[[package]]
|
||||
name = "nodeenv"
|
||||
version = "1.7.0"
|
||||
@@ -887,7 +911,7 @@ jupyter = ["ipywidgets (>=7.5.1,<9)"]
|
||||
|
||||
[[package]]
|
||||
name = "setuptools"
|
||||
version = "67.2.0"
|
||||
version = "67.3.1"
|
||||
description = "Easily download, build, install, upgrade, and uninstall Python packages"
|
||||
category = "dev"
|
||||
optional = false
|
||||
@@ -1004,6 +1028,17 @@ category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=2"
|
||||
|
||||
[[package]]
|
||||
name = "uc-micro-py"
|
||||
version = "1.0.1"
|
||||
description = "Micro subset of unicode data files for linkify-it-py projects."
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.6"
|
||||
|
||||
[package.extras]
|
||||
test = ["coverage", "pytest", "pytest-cov"]
|
||||
|
||||
[[package]]
|
||||
name = "urllib3"
|
||||
version = "1.26.14"
|
||||
@@ -1077,97 +1112,97 @@ dev = ["aiohttp", "click", "msgpack"]
|
||||
[metadata]
|
||||
lock-version = "1.1"
|
||||
python-versions = "^3.7"
|
||||
content-hash = "857b1469b81d325df7d76ed9c727e8e0943514be4dae1c0989b65d8e655ab2f2"
|
||||
content-hash = "f8df51e445d727e92cc87f81cb435575e9b0b1286a189b244fd19c4376ae2cc4"
|
||||
|
||||
[metadata.files]
|
||||
aiohttp = [
|
||||
{file = "aiohttp-3.8.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:ba71c9b4dcbb16212f334126cc3d8beb6af377f6703d9dc2d9fb3874fd667ee9"},
|
||||
{file = "aiohttp-3.8.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d24b8bb40d5c61ef2d9b6a8f4528c2f17f1c5d2d31fed62ec860f6006142e83e"},
|
||||
{file = "aiohttp-3.8.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:f88df3a83cf9df566f171adba39d5bd52814ac0b94778d2448652fc77f9eb491"},
|
||||
{file = "aiohttp-3.8.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b97decbb3372d4b69e4d4c8117f44632551c692bb1361b356a02b97b69e18a62"},
|
||||
{file = "aiohttp-3.8.3-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:309aa21c1d54b8ef0723181d430347d7452daaff93e8e2363db8e75c72c2fb2d"},
|
||||
{file = "aiohttp-3.8.3-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ad5383a67514e8e76906a06741febd9126fc7c7ff0f599d6fcce3e82b80d026f"},
|
||||
{file = "aiohttp-3.8.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:20acae4f268317bb975671e375493dbdbc67cddb5f6c71eebdb85b34444ac46b"},
|
||||
{file = "aiohttp-3.8.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:05a3c31c6d7cd08c149e50dc7aa2568317f5844acd745621983380597f027a18"},
|
||||
{file = "aiohttp-3.8.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:d6f76310355e9fae637c3162936e9504b4767d5c52ca268331e2756e54fd4ca5"},
|
||||
{file = "aiohttp-3.8.3-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:256deb4b29fe5e47893fa32e1de2d73c3afe7407738bd3c63829874661d4822d"},
|
||||
{file = "aiohttp-3.8.3-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:5c59fcd80b9049b49acd29bd3598cada4afc8d8d69bd4160cd613246912535d7"},
|
||||
{file = "aiohttp-3.8.3-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:059a91e88f2c00fe40aed9031b3606c3f311414f86a90d696dd982e7aec48142"},
|
||||
{file = "aiohttp-3.8.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:2feebbb6074cdbd1ac276dbd737b40e890a1361b3cc30b74ac2f5e24aab41f7b"},
|
||||
{file = "aiohttp-3.8.3-cp310-cp310-win32.whl", hash = "sha256:5bf651afd22d5f0c4be16cf39d0482ea494f5c88f03e75e5fef3a85177fecdeb"},
|
||||
{file = "aiohttp-3.8.3-cp310-cp310-win_amd64.whl", hash = "sha256:653acc3880459f82a65e27bd6526e47ddf19e643457d36a2250b85b41a564715"},
|
||||
{file = "aiohttp-3.8.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:86fc24e58ecb32aee09f864cb11bb91bc4c1086615001647dbfc4dc8c32f4008"},
|
||||
{file = "aiohttp-3.8.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:75e14eac916f024305db517e00a9252714fce0abcb10ad327fb6dcdc0d060f1d"},
|
||||
{file = "aiohttp-3.8.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d1fde0f44029e02d02d3993ad55ce93ead9bb9b15c6b7ccd580f90bd7e3de476"},
|
||||
{file = "aiohttp-3.8.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4ab94426ddb1ecc6a0b601d832d5d9d421820989b8caa929114811369673235c"},
|
||||
{file = "aiohttp-3.8.3-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:89d2e02167fa95172c017732ed7725bc8523c598757f08d13c5acca308e1a061"},
|
||||
{file = "aiohttp-3.8.3-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:02f9a2c72fc95d59b881cf38a4b2be9381b9527f9d328771e90f72ac76f31ad8"},
|
||||
{file = "aiohttp-3.8.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9c7149272fb5834fc186328e2c1fa01dda3e1fa940ce18fded6d412e8f2cf76d"},
|
||||
{file = "aiohttp-3.8.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:512bd5ab136b8dc0ffe3fdf2dfb0c4b4f49c8577f6cae55dca862cd37a4564e2"},
|
||||
{file = "aiohttp-3.8.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:7018ecc5fe97027214556afbc7c502fbd718d0740e87eb1217b17efd05b3d276"},
|
||||
{file = "aiohttp-3.8.3-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:88c70ed9da9963d5496d38320160e8eb7e5f1886f9290475a881db12f351ab5d"},
|
||||
{file = "aiohttp-3.8.3-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:da22885266bbfb3f78218dc40205fed2671909fbd0720aedba39b4515c038091"},
|
||||
{file = "aiohttp-3.8.3-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:e65bc19919c910127c06759a63747ebe14f386cda573d95bcc62b427ca1afc73"},
|
||||
{file = "aiohttp-3.8.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:08c78317e950e0762c2983f4dd58dc5e6c9ff75c8a0efeae299d363d439c8e34"},
|
||||
{file = "aiohttp-3.8.3-cp311-cp311-win32.whl", hash = "sha256:45d88b016c849d74ebc6f2b6e8bc17cabf26e7e40c0661ddd8fae4c00f015697"},
|
||||
{file = "aiohttp-3.8.3-cp311-cp311-win_amd64.whl", hash = "sha256:96372fc29471646b9b106ee918c8eeb4cca423fcbf9a34daa1b93767a88a2290"},
|
||||
{file = "aiohttp-3.8.3-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:c971bf3786b5fad82ce5ad570dc6ee420f5b12527157929e830f51c55dc8af77"},
|
||||
{file = "aiohttp-3.8.3-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ff25f48fc8e623d95eca0670b8cc1469a83783c924a602e0fbd47363bb54aaca"},
|
||||
{file = "aiohttp-3.8.3-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e381581b37db1db7597b62a2e6b8b57c3deec95d93b6d6407c5b61ddc98aca6d"},
|
||||
{file = "aiohttp-3.8.3-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:db19d60d846283ee275d0416e2a23493f4e6b6028825b51290ac05afc87a6f97"},
|
||||
{file = "aiohttp-3.8.3-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:25892c92bee6d9449ffac82c2fe257f3a6f297792cdb18ad784737d61e7a9a85"},
|
||||
{file = "aiohttp-3.8.3-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:398701865e7a9565d49189f6c90868efaca21be65c725fc87fc305906be915da"},
|
||||
{file = "aiohttp-3.8.3-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:4a4fbc769ea9b6bd97f4ad0b430a6807f92f0e5eb020f1e42ece59f3ecfc4585"},
|
||||
{file = "aiohttp-3.8.3-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:b29bfd650ed8e148f9c515474a6ef0ba1090b7a8faeee26b74a8ff3b33617502"},
|
||||
{file = "aiohttp-3.8.3-cp36-cp36m-musllinux_1_1_ppc64le.whl", hash = "sha256:1e56b9cafcd6531bab5d9b2e890bb4937f4165109fe98e2b98ef0dcfcb06ee9d"},
|
||||
{file = "aiohttp-3.8.3-cp36-cp36m-musllinux_1_1_s390x.whl", hash = "sha256:ec40170327d4a404b0d91855d41bfe1fe4b699222b2b93e3d833a27330a87a6d"},
|
||||
{file = "aiohttp-3.8.3-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:2df5f139233060578d8c2c975128fb231a89ca0a462b35d4b5fcf7c501ebdbe1"},
|
||||
{file = "aiohttp-3.8.3-cp36-cp36m-win32.whl", hash = "sha256:f973157ffeab5459eefe7b97a804987876dd0a55570b8fa56b4e1954bf11329b"},
|
||||
{file = "aiohttp-3.8.3-cp36-cp36m-win_amd64.whl", hash = "sha256:437399385f2abcd634865705bdc180c8314124b98299d54fe1d4c8990f2f9494"},
|
||||
{file = "aiohttp-3.8.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:09e28f572b21642128ef31f4e8372adb6888846f32fecb288c8b0457597ba61a"},
|
||||
{file = "aiohttp-3.8.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6f3553510abdbec67c043ca85727396ceed1272eef029b050677046d3387be8d"},
|
||||
{file = "aiohttp-3.8.3-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e168a7560b7c61342ae0412997b069753f27ac4862ec7867eff74f0fe4ea2ad9"},
|
||||
{file = "aiohttp-3.8.3-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:db4c979b0b3e0fa7e9e69ecd11b2b3174c6963cebadeecfb7ad24532ffcdd11a"},
|
||||
{file = "aiohttp-3.8.3-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e164e0a98e92d06da343d17d4e9c4da4654f4a4588a20d6c73548a29f176abe2"},
|
||||
{file = "aiohttp-3.8.3-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e8a78079d9a39ca9ca99a8b0ac2fdc0c4d25fc80c8a8a82e5c8211509c523363"},
|
||||
{file = "aiohttp-3.8.3-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:21b30885a63c3f4ff5b77a5d6caf008b037cb521a5f33eab445dc566f6d092cc"},
|
||||
{file = "aiohttp-3.8.3-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:4b0f30372cef3fdc262f33d06e7b411cd59058ce9174ef159ad938c4a34a89da"},
|
||||
{file = "aiohttp-3.8.3-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:8135fa153a20d82ffb64f70a1b5c2738684afa197839b34cc3e3c72fa88d302c"},
|
||||
{file = "aiohttp-3.8.3-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:ad61a9639792fd790523ba072c0555cd6be5a0baf03a49a5dd8cfcf20d56df48"},
|
||||
{file = "aiohttp-3.8.3-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:978b046ca728073070e9abc074b6299ebf3501e8dee5e26efacb13cec2b2dea0"},
|
||||
{file = "aiohttp-3.8.3-cp37-cp37m-win32.whl", hash = "sha256:0d2c6d8c6872df4a6ec37d2ede71eff62395b9e337b4e18efd2177de883a5033"},
|
||||
{file = "aiohttp-3.8.3-cp37-cp37m-win_amd64.whl", hash = "sha256:21d69797eb951f155026651f7e9362877334508d39c2fc37bd04ff55b2007091"},
|
||||
{file = "aiohttp-3.8.3-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:2ca9af5f8f5812d475c5259393f52d712f6d5f0d7fdad9acdb1107dd9e3cb7eb"},
|
||||
{file = "aiohttp-3.8.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1d90043c1882067f1bd26196d5d2db9aa6d268def3293ed5fb317e13c9413ea4"},
|
||||
{file = "aiohttp-3.8.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:d737fc67b9a970f3234754974531dc9afeea11c70791dcb7db53b0cf81b79784"},
|
||||
{file = "aiohttp-3.8.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ebf909ea0a3fc9596e40d55d8000702a85e27fd578ff41a5500f68f20fd32e6c"},
|
||||
{file = "aiohttp-3.8.3-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5835f258ca9f7c455493a57ee707b76d2d9634d84d5d7f62e77be984ea80b849"},
|
||||
{file = "aiohttp-3.8.3-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:da37dcfbf4b7f45d80ee386a5f81122501ec75672f475da34784196690762f4b"},
|
||||
{file = "aiohttp-3.8.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:87f44875f2804bc0511a69ce44a9595d5944837a62caecc8490bbdb0e18b1342"},
|
||||
{file = "aiohttp-3.8.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:527b3b87b24844ea7865284aabfab08eb0faf599b385b03c2aa91fc6edd6e4b6"},
|
||||
{file = "aiohttp-3.8.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:d5ba88df9aa5e2f806650fcbeedbe4f6e8736e92fc0e73b0400538fd25a4dd96"},
|
||||
{file = "aiohttp-3.8.3-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:e7b8813be97cab8cb52b1375f41f8e6804f6507fe4660152e8ca5c48f0436017"},
|
||||
{file = "aiohttp-3.8.3-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:2dea10edfa1a54098703cb7acaa665c07b4e7568472a47f4e64e6319d3821ccf"},
|
||||
{file = "aiohttp-3.8.3-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:713d22cd9643ba9025d33c4af43943c7a1eb8547729228de18d3e02e278472b6"},
|
||||
{file = "aiohttp-3.8.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:2d252771fc85e0cf8da0b823157962d70639e63cb9b578b1dec9868dd1f4f937"},
|
||||
{file = "aiohttp-3.8.3-cp38-cp38-win32.whl", hash = "sha256:66bd5f950344fb2b3dbdd421aaa4e84f4411a1a13fca3aeb2bcbe667f80c9f76"},
|
||||
{file = "aiohttp-3.8.3-cp38-cp38-win_amd64.whl", hash = "sha256:84b14f36e85295fe69c6b9789b51a0903b774046d5f7df538176516c3e422446"},
|
||||
{file = "aiohttp-3.8.3-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:16c121ba0b1ec2b44b73e3a8a171c4f999b33929cd2397124a8c7fcfc8cd9e06"},
|
||||
{file = "aiohttp-3.8.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:8d6aaa4e7155afaf994d7924eb290abbe81a6905b303d8cb61310a2aba1c68ba"},
|
||||
{file = "aiohttp-3.8.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:43046a319664a04b146f81b40e1545d4c8ac7b7dd04c47e40bf09f65f2437346"},
|
||||
{file = "aiohttp-3.8.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:599418aaaf88a6d02a8c515e656f6faf3d10618d3dd95866eb4436520096c84b"},
|
||||
{file = "aiohttp-3.8.3-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:92a2964319d359f494f16011e23434f6f8ef0434acd3cf154a6b7bec511e2fb7"},
|
||||
{file = "aiohttp-3.8.3-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:73a4131962e6d91109bca6536416aa067cf6c4efb871975df734f8d2fd821b37"},
|
||||
{file = "aiohttp-3.8.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:598adde339d2cf7d67beaccda3f2ce7c57b3b412702f29c946708f69cf8222aa"},
|
||||
{file = "aiohttp-3.8.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:75880ed07be39beff1881d81e4a907cafb802f306efd6d2d15f2b3c69935f6fb"},
|
||||
{file = "aiohttp-3.8.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:a0239da9fbafd9ff82fd67c16704a7d1bccf0d107a300e790587ad05547681c8"},
|
||||
{file = "aiohttp-3.8.3-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:4e3a23ec214e95c9fe85a58470b660efe6534b83e6cbe38b3ed52b053d7cb6ad"},
|
||||
{file = "aiohttp-3.8.3-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:47841407cc89a4b80b0c52276f3cc8138bbbfba4b179ee3acbd7d77ae33f7ac4"},
|
||||
{file = "aiohttp-3.8.3-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:54d107c89a3ebcd13228278d68f1436d3f33f2dd2af5415e3feaeb1156e1a62c"},
|
||||
{file = "aiohttp-3.8.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:c37c5cce780349d4d51739ae682dec63573847a2a8dcb44381b174c3d9c8d403"},
|
||||
{file = "aiohttp-3.8.3-cp39-cp39-win32.whl", hash = "sha256:f178d2aadf0166be4df834c4953da2d7eef24719e8aec9a65289483eeea9d618"},
|
||||
{file = "aiohttp-3.8.3-cp39-cp39-win_amd64.whl", hash = "sha256:88e5be56c231981428f4f506c68b6a46fa25c4123a2e86d156c58a8369d31ab7"},
|
||||
{file = "aiohttp-3.8.3.tar.gz", hash = "sha256:3828fb41b7203176b82fe5d699e0d845435f2374750a44b480ea6b930f6be269"},
|
||||
{file = "aiohttp-3.8.4-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:5ce45967538fb747370308d3145aa68a074bdecb4f3a300869590f725ced69c1"},
|
||||
{file = "aiohttp-3.8.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b744c33b6f14ca26b7544e8d8aadff6b765a80ad6164fb1a430bbadd593dfb1a"},
|
||||
{file = "aiohttp-3.8.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:1a45865451439eb320784918617ba54b7a377e3501fb70402ab84d38c2cd891b"},
|
||||
{file = "aiohttp-3.8.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a86d42d7cba1cec432d47ab13b6637bee393a10f664c425ea7b305d1301ca1a3"},
|
||||
{file = "aiohttp-3.8.4-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ee3c36df21b5714d49fc4580247947aa64bcbe2939d1b77b4c8dcb8f6c9faecc"},
|
||||
{file = "aiohttp-3.8.4-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:176a64b24c0935869d5bbc4c96e82f89f643bcdf08ec947701b9dbb3c956b7dd"},
|
||||
{file = "aiohttp-3.8.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c844fd628851c0bc309f3c801b3a3d58ce430b2ce5b359cd918a5a76d0b20cb5"},
|
||||
{file = "aiohttp-3.8.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5393fb786a9e23e4799fec788e7e735de18052f83682ce2dfcabaf1c00c2c08e"},
|
||||
{file = "aiohttp-3.8.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:e4b09863aae0dc965c3ef36500d891a3ff495a2ea9ae9171e4519963c12ceefd"},
|
||||
{file = "aiohttp-3.8.4-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:adfbc22e87365a6e564c804c58fc44ff7727deea782d175c33602737b7feadb6"},
|
||||
{file = "aiohttp-3.8.4-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:147ae376f14b55f4f3c2b118b95be50a369b89b38a971e80a17c3fd623f280c9"},
|
||||
{file = "aiohttp-3.8.4-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:eafb3e874816ebe2a92f5e155f17260034c8c341dad1df25672fb710627c6949"},
|
||||
{file = "aiohttp-3.8.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c6cc15d58053c76eacac5fa9152d7d84b8d67b3fde92709195cb984cfb3475ea"},
|
||||
{file = "aiohttp-3.8.4-cp310-cp310-win32.whl", hash = "sha256:59f029a5f6e2d679296db7bee982bb3d20c088e52a2977e3175faf31d6fb75d1"},
|
||||
{file = "aiohttp-3.8.4-cp310-cp310-win_amd64.whl", hash = "sha256:fe7ba4a51f33ab275515f66b0a236bcde4fb5561498fe8f898d4e549b2e4509f"},
|
||||
{file = "aiohttp-3.8.4-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:3d8ef1a630519a26d6760bc695842579cb09e373c5f227a21b67dc3eb16cfea4"},
|
||||
{file = "aiohttp-3.8.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:5b3f2e06a512e94722886c0827bee9807c86a9f698fac6b3aee841fab49bbfb4"},
|
||||
{file = "aiohttp-3.8.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:3a80464982d41b1fbfe3154e440ba4904b71c1a53e9cd584098cd41efdb188ef"},
|
||||
{file = "aiohttp-3.8.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8b631e26df63e52f7cce0cce6507b7a7f1bc9b0c501fcde69742130b32e8782f"},
|
||||
{file = "aiohttp-3.8.4-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3f43255086fe25e36fd5ed8f2ee47477408a73ef00e804cb2b5cba4bf2ac7f5e"},
|
||||
{file = "aiohttp-3.8.4-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4d347a172f866cd1d93126d9b239fcbe682acb39b48ee0873c73c933dd23bd0f"},
|
||||
{file = "aiohttp-3.8.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a3fec6a4cb5551721cdd70473eb009d90935b4063acc5f40905d40ecfea23e05"},
|
||||
{file = "aiohttp-3.8.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:80a37fe8f7c1e6ce8f2d9c411676e4bc633a8462844e38f46156d07a7d401654"},
|
||||
{file = "aiohttp-3.8.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d1e6a862b76f34395a985b3cd39a0d949ca80a70b6ebdea37d3ab39ceea6698a"},
|
||||
{file = "aiohttp-3.8.4-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:cd468460eefef601ece4428d3cf4562459157c0f6523db89365202c31b6daebb"},
|
||||
{file = "aiohttp-3.8.4-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:618c901dd3aad4ace71dfa0f5e82e88b46ef57e3239fc7027773cb6d4ed53531"},
|
||||
{file = "aiohttp-3.8.4-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:652b1bff4f15f6287550b4670546a2947f2a4575b6c6dff7760eafb22eacbf0b"},
|
||||
{file = "aiohttp-3.8.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:80575ba9377c5171407a06d0196b2310b679dc752d02a1fcaa2bc20b235dbf24"},
|
||||
{file = "aiohttp-3.8.4-cp311-cp311-win32.whl", hash = "sha256:bbcf1a76cf6f6dacf2c7f4d2ebd411438c275faa1dc0c68e46eb84eebd05dd7d"},
|
||||
{file = "aiohttp-3.8.4-cp311-cp311-win_amd64.whl", hash = "sha256:6e74dd54f7239fcffe07913ff8b964e28b712f09846e20de78676ce2a3dc0bfc"},
|
||||
{file = "aiohttp-3.8.4-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:880e15bb6dad90549b43f796b391cfffd7af373f4646784795e20d92606b7a51"},
|
||||
{file = "aiohttp-3.8.4-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bb96fa6b56bb536c42d6a4a87dfca570ff8e52de2d63cabebfd6fb67049c34b6"},
|
||||
{file = "aiohttp-3.8.4-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4a6cadebe132e90cefa77e45f2d2f1a4b2ce5c6b1bfc1656c1ddafcfe4ba8131"},
|
||||
{file = "aiohttp-3.8.4-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f352b62b45dff37b55ddd7b9c0c8672c4dd2eb9c0f9c11d395075a84e2c40f75"},
|
||||
{file = "aiohttp-3.8.4-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7ab43061a0c81198d88f39aaf90dae9a7744620978f7ef3e3708339b8ed2ef01"},
|
||||
{file = "aiohttp-3.8.4-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c9cb1565a7ad52e096a6988e2ee0397f72fe056dadf75d17fa6b5aebaea05622"},
|
||||
{file = "aiohttp-3.8.4-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:1b3ea7edd2d24538959c1c1abf97c744d879d4e541d38305f9bd7d9b10c9ec41"},
|
||||
{file = "aiohttp-3.8.4-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:7c7837fe8037e96b6dd5cfcf47263c1620a9d332a87ec06a6ca4564e56bd0f36"},
|
||||
{file = "aiohttp-3.8.4-cp36-cp36m-musllinux_1_1_ppc64le.whl", hash = "sha256:3b90467ebc3d9fa5b0f9b6489dfb2c304a1db7b9946fa92aa76a831b9d587e99"},
|
||||
{file = "aiohttp-3.8.4-cp36-cp36m-musllinux_1_1_s390x.whl", hash = "sha256:cab9401de3ea52b4b4c6971db5fb5c999bd4260898af972bf23de1c6b5dd9d71"},
|
||||
{file = "aiohttp-3.8.4-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:d1f9282c5f2b5e241034a009779e7b2a1aa045f667ff521e7948ea9b56e0c5ff"},
|
||||
{file = "aiohttp-3.8.4-cp36-cp36m-win32.whl", hash = "sha256:5e14f25765a578a0a634d5f0cd1e2c3f53964553a00347998dfdf96b8137f777"},
|
||||
{file = "aiohttp-3.8.4-cp36-cp36m-win_amd64.whl", hash = "sha256:4c745b109057e7e5f1848c689ee4fb3a016c8d4d92da52b312f8a509f83aa05e"},
|
||||
{file = "aiohttp-3.8.4-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:aede4df4eeb926c8fa70de46c340a1bc2c6079e1c40ccf7b0eae1313ffd33519"},
|
||||
{file = "aiohttp-3.8.4-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4ddaae3f3d32fc2cb4c53fab020b69a05c8ab1f02e0e59665c6f7a0d3a5be54f"},
|
||||
{file = "aiohttp-3.8.4-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c4eb3b82ca349cf6fadcdc7abcc8b3a50ab74a62e9113ab7a8ebc268aad35bb9"},
|
||||
{file = "aiohttp-3.8.4-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9bcb89336efa095ea21b30f9e686763f2be4478f1b0a616969551982c4ee4c3b"},
|
||||
{file = "aiohttp-3.8.4-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c08e8ed6fa3d477e501ec9db169bfac8140e830aa372d77e4a43084d8dd91ab"},
|
||||
{file = "aiohttp-3.8.4-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c6cd05ea06daca6ad6a4ca3ba7fe7dc5b5de063ff4daec6170ec0f9979f6c332"},
|
||||
{file = "aiohttp-3.8.4-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:b7a00a9ed8d6e725b55ef98b1b35c88013245f35f68b1b12c5cd4100dddac333"},
|
||||
{file = "aiohttp-3.8.4-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:de04b491d0e5007ee1b63a309956eaed959a49f5bb4e84b26c8f5d49de140fa9"},
|
||||
{file = "aiohttp-3.8.4-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:40653609b3bf50611356e6b6554e3a331f6879fa7116f3959b20e3528783e699"},
|
||||
{file = "aiohttp-3.8.4-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:dbf3a08a06b3f433013c143ebd72c15cac33d2914b8ea4bea7ac2c23578815d6"},
|
||||
{file = "aiohttp-3.8.4-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:854f422ac44af92bfe172d8e73229c270dc09b96535e8a548f99c84f82dde241"},
|
||||
{file = "aiohttp-3.8.4-cp37-cp37m-win32.whl", hash = "sha256:aeb29c84bb53a84b1a81c6c09d24cf33bb8432cc5c39979021cc0f98c1292a1a"},
|
||||
{file = "aiohttp-3.8.4-cp37-cp37m-win_amd64.whl", hash = "sha256:db3fc6120bce9f446d13b1b834ea5b15341ca9ff3f335e4a951a6ead31105480"},
|
||||
{file = "aiohttp-3.8.4-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:fabb87dd8850ef0f7fe2b366d44b77d7e6fa2ea87861ab3844da99291e81e60f"},
|
||||
{file = "aiohttp-3.8.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:91f6d540163f90bbaef9387e65f18f73ffd7c79f5225ac3d3f61df7b0d01ad15"},
|
||||
{file = "aiohttp-3.8.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:d265f09a75a79a788237d7f9054f929ced2e69eb0bb79de3798c468d8a90f945"},
|
||||
{file = "aiohttp-3.8.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3d89efa095ca7d442a6d0cbc755f9e08190ba40069b235c9886a8763b03785da"},
|
||||
{file = "aiohttp-3.8.4-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4dac314662f4e2aa5009977b652d9b8db7121b46c38f2073bfeed9f4049732cd"},
|
||||
{file = "aiohttp-3.8.4-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:fe11310ae1e4cd560035598c3f29d86cef39a83d244c7466f95c27ae04850f10"},
|
||||
{file = "aiohttp-3.8.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6ddb2a2026c3f6a68c3998a6c47ab6795e4127315d2e35a09997da21865757f8"},
|
||||
{file = "aiohttp-3.8.4-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e75b89ac3bd27d2d043b234aa7b734c38ba1b0e43f07787130a0ecac1e12228a"},
|
||||
{file = "aiohttp-3.8.4-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6e601588f2b502c93c30cd5a45bfc665faaf37bbe835b7cfd461753068232074"},
|
||||
{file = "aiohttp-3.8.4-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:a5d794d1ae64e7753e405ba58e08fcfa73e3fad93ef9b7e31112ef3c9a0efb52"},
|
||||
{file = "aiohttp-3.8.4-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:a1f4689c9a1462f3df0a1f7e797791cd6b124ddbee2b570d34e7f38ade0e2c71"},
|
||||
{file = "aiohttp-3.8.4-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:3032dcb1c35bc330134a5b8a5d4f68c1a87252dfc6e1262c65a7e30e62298275"},
|
||||
{file = "aiohttp-3.8.4-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:8189c56eb0ddbb95bfadb8f60ea1b22fcfa659396ea36f6adcc521213cd7b44d"},
|
||||
{file = "aiohttp-3.8.4-cp38-cp38-win32.whl", hash = "sha256:33587f26dcee66efb2fff3c177547bd0449ab7edf1b73a7f5dea1e38609a0c54"},
|
||||
{file = "aiohttp-3.8.4-cp38-cp38-win_amd64.whl", hash = "sha256:e595432ac259af2d4630008bf638873d69346372d38255774c0e286951e8b79f"},
|
||||
{file = "aiohttp-3.8.4-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:5a7bdf9e57126dc345b683c3632e8ba317c31d2a41acd5800c10640387d193ed"},
|
||||
{file = "aiohttp-3.8.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:22f6eab15b6db242499a16de87939a342f5a950ad0abaf1532038e2ce7d31567"},
|
||||
{file = "aiohttp-3.8.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:7235604476a76ef249bd64cb8274ed24ccf6995c4a8b51a237005ee7a57e8643"},
|
||||
{file = "aiohttp-3.8.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ea9eb976ffdd79d0e893869cfe179a8f60f152d42cb64622fca418cd9b18dc2a"},
|
||||
{file = "aiohttp-3.8.4-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:92c0cea74a2a81c4c76b62ea1cac163ecb20fb3ba3a75c909b9fa71b4ad493cf"},
|
||||
{file = "aiohttp-3.8.4-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:493f5bc2f8307286b7799c6d899d388bbaa7dfa6c4caf4f97ef7521b9cb13719"},
|
||||
{file = "aiohttp-3.8.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0a63f03189a6fa7c900226e3ef5ba4d3bd047e18f445e69adbd65af433add5a2"},
|
||||
{file = "aiohttp-3.8.4-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:10c8cefcff98fd9168cdd86c4da8b84baaa90bf2da2269c6161984e6737bf23e"},
|
||||
{file = "aiohttp-3.8.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:bca5f24726e2919de94f047739d0a4fc01372801a3672708260546aa2601bf57"},
|
||||
{file = "aiohttp-3.8.4-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:03baa76b730e4e15a45f81dfe29a8d910314143414e528737f8589ec60cf7391"},
|
||||
{file = "aiohttp-3.8.4-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:8c29c77cc57e40f84acef9bfb904373a4e89a4e8b74e71aa8075c021ec9078c2"},
|
||||
{file = "aiohttp-3.8.4-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:03543dcf98a6619254b409be2d22b51f21ec66272be4ebda7b04e6412e4b2e14"},
|
||||
{file = "aiohttp-3.8.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:17b79c2963db82086229012cff93ea55196ed31f6493bb1ccd2c62f1724324e4"},
|
||||
{file = "aiohttp-3.8.4-cp39-cp39-win32.whl", hash = "sha256:34ce9f93a4a68d1272d26030655dd1b58ff727b3ed2a33d80ec433561b03d67a"},
|
||||
{file = "aiohttp-3.8.4-cp39-cp39-win_amd64.whl", hash = "sha256:41a86a69bb63bb2fc3dc9ad5ea9f10f1c9c8e282b471931be0268ddd09430b04"},
|
||||
{file = "aiohttp-3.8.4.tar.gz", hash = "sha256:bf2e1a9162c1e441bf805a1fd166e249d574ca04e03b34f97e2928769e91ab5c"},
|
||||
]
|
||||
aiosignal = [
|
||||
{file = "aiosignal-1.3.1-py3-none-any.whl", hash = "sha256:f8376fb07dd1e86a584e4fcdec80b36b7f81aac666ebc724e2c090300dd83b17"},
|
||||
@@ -1229,8 +1264,94 @@ cfgv = [
|
||||
{file = "cfgv-3.3.1.tar.gz", hash = "sha256:f5a830efb9ce7a445376bb66ec94c638a9787422f96264c98edc6bdeed8ab736"},
|
||||
]
|
||||
charset-normalizer = [
|
||||
{file = "charset-normalizer-2.1.1.tar.gz", hash = "sha256:5a3d016c7c547f69d6f81fb0db9449ce888b418b5b9952cc5e6e66843e9dd845"},
|
||||
{file = "charset_normalizer-2.1.1-py3-none-any.whl", hash = "sha256:83e9a75d1911279afd89352c68b45348559d1fc0506b054b346651b5e7fee29f"},
|
||||
{file = "charset-normalizer-3.0.1.tar.gz", hash = "sha256:ebea339af930f8ca5d7a699b921106c6e29c617fe9606fa7baa043c1cdae326f"},
|
||||
{file = "charset_normalizer-3.0.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:88600c72ef7587fe1708fd242b385b6ed4b8904976d5da0893e31df8b3480cb6"},
|
||||
{file = "charset_normalizer-3.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c75ffc45f25324e68ab238cb4b5c0a38cd1c3d7f1fb1f72b5541de469e2247db"},
|
||||
{file = "charset_normalizer-3.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:db72b07027db150f468fbada4d85b3b2729a3db39178abf5c543b784c1254539"},
|
||||
{file = "charset_normalizer-3.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:62595ab75873d50d57323a91dd03e6966eb79c41fa834b7a1661ed043b2d404d"},
|
||||
{file = "charset_normalizer-3.0.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ff6f3db31555657f3163b15a6b7c6938d08df7adbfc9dd13d9d19edad678f1e8"},
|
||||
{file = "charset_normalizer-3.0.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:772b87914ff1152b92a197ef4ea40efe27a378606c39446ded52c8f80f79702e"},
|
||||
{file = "charset_normalizer-3.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70990b9c51340e4044cfc394a81f614f3f90d41397104d226f21e66de668730d"},
|
||||
{file = "charset_normalizer-3.0.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:292d5e8ba896bbfd6334b096e34bffb56161c81408d6d036a7dfa6929cff8783"},
|
||||
{file = "charset_normalizer-3.0.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:2edb64ee7bf1ed524a1da60cdcd2e1f6e2b4f66ef7c077680739f1641f62f555"},
|
||||
{file = "charset_normalizer-3.0.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:31a9ddf4718d10ae04d9b18801bd776693487cbb57d74cc3458a7673f6f34639"},
|
||||
{file = "charset_normalizer-3.0.1-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:44ba614de5361b3e5278e1241fda3dc1838deed864b50a10d7ce92983797fa76"},
|
||||
{file = "charset_normalizer-3.0.1-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:12db3b2c533c23ab812c2b25934f60383361f8a376ae272665f8e48b88e8e1c6"},
|
||||
{file = "charset_normalizer-3.0.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c512accbd6ff0270939b9ac214b84fb5ada5f0409c44298361b2f5e13f9aed9e"},
|
||||
{file = "charset_normalizer-3.0.1-cp310-cp310-win32.whl", hash = "sha256:502218f52498a36d6bf5ea77081844017bf7982cdbe521ad85e64cabee1b608b"},
|
||||
{file = "charset_normalizer-3.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:601f36512f9e28f029d9481bdaf8e89e5148ac5d89cffd3b05cd533eeb423b59"},
|
||||
{file = "charset_normalizer-3.0.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0298eafff88c99982a4cf66ba2efa1128e4ddaca0b05eec4c456bbc7db691d8d"},
|
||||
{file = "charset_normalizer-3.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:a8d0fc946c784ff7f7c3742310cc8a57c5c6dc31631269876a88b809dbeff3d3"},
|
||||
{file = "charset_normalizer-3.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:87701167f2a5c930b403e9756fab1d31d4d4da52856143b609e30a1ce7160f3c"},
|
||||
{file = "charset_normalizer-3.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:14e76c0f23218b8f46c4d87018ca2e441535aed3632ca134b10239dfb6dadd6b"},
|
||||
{file = "charset_normalizer-3.0.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0c0a590235ccd933d9892c627dec5bc7511ce6ad6c1011fdf5b11363022746c1"},
|
||||
{file = "charset_normalizer-3.0.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8c7fe7afa480e3e82eed58e0ca89f751cd14d767638e2550c77a92a9e749c317"},
|
||||
{file = "charset_normalizer-3.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:79909e27e8e4fcc9db4addea88aa63f6423ebb171db091fb4373e3312cb6d603"},
|
||||
{file = "charset_normalizer-3.0.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8ac7b6a045b814cf0c47f3623d21ebd88b3e8cf216a14790b455ea7ff0135d18"},
|
||||
{file = "charset_normalizer-3.0.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:72966d1b297c741541ca8cf1223ff262a6febe52481af742036a0b296e35fa5a"},
|
||||
{file = "charset_normalizer-3.0.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:f9d0c5c045a3ca9bedfc35dca8526798eb91a07aa7a2c0fee134c6c6f321cbd7"},
|
||||
{file = "charset_normalizer-3.0.1-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:5995f0164fa7df59db4746112fec3f49c461dd6b31b841873443bdb077c13cfc"},
|
||||
{file = "charset_normalizer-3.0.1-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:4a8fcf28c05c1f6d7e177a9a46a1c52798bfe2ad80681d275b10dcf317deaf0b"},
|
||||
{file = "charset_normalizer-3.0.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:761e8904c07ad053d285670f36dd94e1b6ab7f16ce62b9805c475b7aa1cffde6"},
|
||||
{file = "charset_normalizer-3.0.1-cp311-cp311-win32.whl", hash = "sha256:71140351489970dfe5e60fc621ada3e0f41104a5eddaca47a7acb3c1b851d6d3"},
|
||||
{file = "charset_normalizer-3.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:9ab77acb98eba3fd2a85cd160851816bfce6871d944d885febf012713f06659c"},
|
||||
{file = "charset_normalizer-3.0.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:84c3990934bae40ea69a82034912ffe5a62c60bbf6ec5bc9691419641d7d5c9a"},
|
||||
{file = "charset_normalizer-3.0.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:74292fc76c905c0ef095fe11e188a32ebd03bc38f3f3e9bcb85e4e6db177b7ea"},
|
||||
{file = "charset_normalizer-3.0.1-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c95a03c79bbe30eec3ec2b7f076074f4281526724c8685a42872974ef4d36b72"},
|
||||
{file = "charset_normalizer-3.0.1-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f4c39b0e3eac288fedc2b43055cfc2ca7a60362d0e5e87a637beac5d801ef478"},
|
||||
{file = "charset_normalizer-3.0.1-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:df2c707231459e8a4028eabcd3cfc827befd635b3ef72eada84ab13b52e1574d"},
|
||||
{file = "charset_normalizer-3.0.1-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:93ad6d87ac18e2a90b0fe89df7c65263b9a99a0eb98f0a3d2e079f12a0735837"},
|
||||
{file = "charset_normalizer-3.0.1-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:59e5686dd847347e55dffcc191a96622f016bc0ad89105e24c14e0d6305acbc6"},
|
||||
{file = "charset_normalizer-3.0.1-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:cd6056167405314a4dc3c173943f11249fa0f1b204f8b51ed4bde1a9cd1834dc"},
|
||||
{file = "charset_normalizer-3.0.1-cp36-cp36m-musllinux_1_1_ppc64le.whl", hash = "sha256:083c8d17153ecb403e5e1eb76a7ef4babfc2c48d58899c98fcaa04833e7a2f9a"},
|
||||
{file = "charset_normalizer-3.0.1-cp36-cp36m-musllinux_1_1_s390x.whl", hash = "sha256:f5057856d21e7586765171eac8b9fc3f7d44ef39425f85dbcccb13b3ebea806c"},
|
||||
{file = "charset_normalizer-3.0.1-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:7eb33a30d75562222b64f569c642ff3dc6689e09adda43a082208397f016c39a"},
|
||||
{file = "charset_normalizer-3.0.1-cp36-cp36m-win32.whl", hash = "sha256:95dea361dd73757c6f1c0a1480ac499952c16ac83f7f5f4f84f0658a01b8ef41"},
|
||||
{file = "charset_normalizer-3.0.1-cp36-cp36m-win_amd64.whl", hash = "sha256:eaa379fcd227ca235d04152ca6704c7cb55564116f8bc52545ff357628e10602"},
|
||||
{file = "charset_normalizer-3.0.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:3e45867f1f2ab0711d60c6c71746ac53537f1684baa699f4f668d4c6f6ce8e14"},
|
||||
{file = "charset_normalizer-3.0.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cadaeaba78750d58d3cc6ac4d1fd867da6fc73c88156b7a3212a3cd4819d679d"},
|
||||
{file = "charset_normalizer-3.0.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:911d8a40b2bef5b8bbae2e36a0b103f142ac53557ab421dc16ac4aafee6f53dc"},
|
||||
{file = "charset_normalizer-3.0.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:503e65837c71b875ecdd733877d852adbc465bd82c768a067badd953bf1bc5a3"},
|
||||
{file = "charset_normalizer-3.0.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a60332922359f920193b1d4826953c507a877b523b2395ad7bc716ddd386d866"},
|
||||
{file = "charset_normalizer-3.0.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:16a8663d6e281208d78806dbe14ee9903715361cf81f6d4309944e4d1e59ac5b"},
|
||||
{file = "charset_normalizer-3.0.1-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:a16418ecf1329f71df119e8a65f3aa68004a3f9383821edcb20f0702934d8087"},
|
||||
{file = "charset_normalizer-3.0.1-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:9d9153257a3f70d5f69edf2325357251ed20f772b12e593f3b3377b5f78e7ef8"},
|
||||
{file = "charset_normalizer-3.0.1-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:02a51034802cbf38db3f89c66fb5d2ec57e6fe7ef2f4a44d070a593c3688667b"},
|
||||
{file = "charset_normalizer-3.0.1-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:2e396d70bc4ef5325b72b593a72c8979999aa52fb8bcf03f701c1b03e1166918"},
|
||||
{file = "charset_normalizer-3.0.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:11b53acf2411c3b09e6af37e4b9005cba376c872503c8f28218c7243582df45d"},
|
||||
{file = "charset_normalizer-3.0.1-cp37-cp37m-win32.whl", hash = "sha256:0bf2dae5291758b6f84cf923bfaa285632816007db0330002fa1de38bfcb7154"},
|
||||
{file = "charset_normalizer-3.0.1-cp37-cp37m-win_amd64.whl", hash = "sha256:2c03cc56021a4bd59be889c2b9257dae13bf55041a3372d3295416f86b295fb5"},
|
||||
{file = "charset_normalizer-3.0.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:024e606be3ed92216e2b6952ed859d86b4cfa52cd5bc5f050e7dc28f9b43ec42"},
|
||||
{file = "charset_normalizer-3.0.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:4b0d02d7102dd0f997580b51edc4cebcf2ab6397a7edf89f1c73b586c614272c"},
|
||||
{file = "charset_normalizer-3.0.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:358a7c4cb8ba9b46c453b1dd8d9e431452d5249072e4f56cfda3149f6ab1405e"},
|
||||
{file = "charset_normalizer-3.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:81d6741ab457d14fdedc215516665050f3822d3e56508921cc7239f8c8e66a58"},
|
||||
{file = "charset_normalizer-3.0.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8b8af03d2e37866d023ad0ddea594edefc31e827fee64f8de5611a1dbc373174"},
|
||||
{file = "charset_normalizer-3.0.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9cf4e8ad252f7c38dd1f676b46514f92dc0ebeb0db5552f5f403509705e24753"},
|
||||
{file = "charset_normalizer-3.0.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e696f0dd336161fca9adbb846875d40752e6eba585843c768935ba5c9960722b"},
|
||||
{file = "charset_normalizer-3.0.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c22d3fe05ce11d3671297dc8973267daa0f938b93ec716e12e0f6dee81591dc1"},
|
||||
{file = "charset_normalizer-3.0.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:109487860ef6a328f3eec66f2bf78b0b72400280d8f8ea05f69c51644ba6521a"},
|
||||
{file = "charset_normalizer-3.0.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:37f8febc8ec50c14f3ec9637505f28e58d4f66752207ea177c1d67df25da5aed"},
|
||||
{file = "charset_normalizer-3.0.1-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:f97e83fa6c25693c7a35de154681fcc257c1c41b38beb0304b9c4d2d9e164479"},
|
||||
{file = "charset_normalizer-3.0.1-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:a152f5f33d64a6be73f1d30c9cc82dfc73cec6477ec268e7c6e4c7d23c2d2291"},
|
||||
{file = "charset_normalizer-3.0.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:39049da0ffb96c8cbb65cbf5c5f3ca3168990adf3551bd1dee10c48fce8ae820"},
|
||||
{file = "charset_normalizer-3.0.1-cp38-cp38-win32.whl", hash = "sha256:4457ea6774b5611f4bed5eaa5df55f70abde42364d498c5134b7ef4c6958e20e"},
|
||||
{file = "charset_normalizer-3.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:e62164b50f84e20601c1ff8eb55620d2ad25fb81b59e3cd776a1902527a788af"},
|
||||
{file = "charset_normalizer-3.0.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:8eade758719add78ec36dc13201483f8e9b5d940329285edcd5f70c0a9edbd7f"},
|
||||
{file = "charset_normalizer-3.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:8499ca8f4502af841f68135133d8258f7b32a53a1d594aa98cc52013fff55678"},
|
||||
{file = "charset_normalizer-3.0.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:3fc1c4a2ffd64890aebdb3f97e1278b0cc72579a08ca4de8cd2c04799a3a22be"},
|
||||
{file = "charset_normalizer-3.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:00d3ffdaafe92a5dc603cb9bd5111aaa36dfa187c8285c543be562e61b755f6b"},
|
||||
{file = "charset_normalizer-3.0.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c2ac1b08635a8cd4e0cbeaf6f5e922085908d48eb05d44c5ae9eabab148512ca"},
|
||||
{file = "charset_normalizer-3.0.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f6f45710b4459401609ebebdbcfb34515da4fc2aa886f95107f556ac69a9147e"},
|
||||
{file = "charset_normalizer-3.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ae1de54a77dc0d6d5fcf623290af4266412a7c4be0b1ff7444394f03f5c54e3"},
|
||||
{file = "charset_normalizer-3.0.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3b590df687e3c5ee0deef9fc8c547d81986d9a1b56073d82de008744452d6541"},
|
||||
{file = "charset_normalizer-3.0.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:ab5de034a886f616a5668aa5d098af2b5385ed70142090e2a31bcbd0af0fdb3d"},
|
||||
{file = "charset_normalizer-3.0.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:9cb3032517f1627cc012dbc80a8ec976ae76d93ea2b5feaa9d2a5b8882597579"},
|
||||
{file = "charset_normalizer-3.0.1-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:608862a7bf6957f2333fc54ab4399e405baad0163dc9f8d99cb236816db169d4"},
|
||||
{file = "charset_normalizer-3.0.1-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:0f438ae3532723fb6ead77e7c604be7c8374094ef4ee2c5e03a3a17f1fca256c"},
|
||||
{file = "charset_normalizer-3.0.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:356541bf4381fa35856dafa6a965916e54bed415ad8a24ee6de6e37deccf2786"},
|
||||
{file = "charset_normalizer-3.0.1-cp39-cp39-win32.whl", hash = "sha256:39cf9ed17fe3b1bc81f33c9ceb6ce67683ee7526e65fde1447c772afc54a1bb8"},
|
||||
{file = "charset_normalizer-3.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:0a11e971ed097d24c534c037d298ad32c6ce81a45736d31e0ff0ad37ab437d59"},
|
||||
{file = "charset_normalizer-3.0.1-py3-none-any.whl", hash = "sha256:7e189e2e1d3ed2f4aebabd2d5b0f931e883676e51c7624826e0a4e5fe8a0bf24"},
|
||||
]
|
||||
click = [
|
||||
{file = "click-8.1.3-py3-none-any.whl", hash = "sha256:bb4d8133cb15a609f44e8213d9b391b0809795062913b383c62be0ee95b1db48"},
|
||||
@@ -1413,8 +1534,8 @@ httpx = [
|
||||
{file = "httpx-0.23.3.tar.gz", hash = "sha256:9818458eb565bb54898ccb9b8b251a28785dd4a55afbc23d0eb410754fe7d0f9"},
|
||||
]
|
||||
identify = [
|
||||
{file = "identify-2.5.17-py2.py3-none-any.whl", hash = "sha256:7d526dd1283555aafcc91539acc061d8f6f59adb0a7bba462735b0a318bff7ed"},
|
||||
{file = "identify-2.5.17.tar.gz", hash = "sha256:93cc61a861052de9d4c541a7acb7e3dcc9c11b398a2144f6e52ae5285f5f4f06"},
|
||||
{file = "identify-2.5.18-py2.py3-none-any.whl", hash = "sha256:93aac7ecf2f6abf879b8f29a8002d3c6de7086b8c28d88e1ad15045a15ab63f9"},
|
||||
{file = "identify-2.5.18.tar.gz", hash = "sha256:89e144fa560cc4cffb6ef2ab5e9fb18ed9f9b3cb054384bab4b95c12f6c309fe"},
|
||||
]
|
||||
idna = [
|
||||
{file = "idna-3.4-py3-none-any.whl", hash = "sha256:90b77e79eaa3eba6de819a0c442c0b4ceefc341a7a2ab77d7562bf49f425c5c2"},
|
||||
@@ -1432,6 +1553,10 @@ jinja2 = [
|
||||
{file = "Jinja2-3.0.3-py3-none-any.whl", hash = "sha256:077ce6014f7b40d03b47d1f1ca4b0fc8328a692bd284016f806ed0eaca390ad8"},
|
||||
{file = "Jinja2-3.0.3.tar.gz", hash = "sha256:611bb273cd68f3b993fabdc4064fc858c5b47a973cb5aa7999ec1ba405c87cd7"},
|
||||
]
|
||||
linkify-it-py = [
|
||||
{file = "linkify-it-py-1.0.3.tar.gz", hash = "sha256:2b3f168d5ce75e3a425e34b341a6b73e116b5d9ed8dbbbf5dc7456843b7ce2ee"},
|
||||
{file = "linkify_it_py-1.0.3-py3-none-any.whl", hash = "sha256:11e29f00150cddaa8f434153f103c14716e7e097a8fd372d9eb1ed06ed91524d"},
|
||||
]
|
||||
markdown = [
|
||||
{file = "Markdown-3.3.7-py3-none-any.whl", hash = "sha256:f5da449a6e1c989a4cea2631aa8ee67caa5a2ef855d551c88f9e309f4634c621"},
|
||||
{file = "Markdown-3.3.7.tar.gz", hash = "sha256:cbb516f16218e643d8e0a95b309f77eb118cb138d39a4f27851e6a63581db874"},
|
||||
@@ -1492,6 +1617,10 @@ markupsafe = [
|
||||
{file = "MarkupSafe-2.1.2-cp39-cp39-win_amd64.whl", hash = "sha256:0576fe974b40a400449768941d5d0858cc624e3249dfd1e0c33674e5c7ca7aed"},
|
||||
{file = "MarkupSafe-2.1.2.tar.gz", hash = "sha256:abcabc8c2b26036d62d4c746381a6f7cf60aafcc653198ad678306986b09450d"},
|
||||
]
|
||||
mdit-py-plugins = [
|
||||
{file = "mdit-py-plugins-0.3.3.tar.gz", hash = "sha256:5cfd7e7ac582a594e23ba6546a2f406e94e42eb33ae596d0734781261c251260"},
|
||||
{file = "mdit_py_plugins-0.3.3-py3-none-any.whl", hash = "sha256:36d08a29def19ec43acdcd8ba471d3ebab132e7879d442760d963f19913e04b9"},
|
||||
]
|
||||
mdurl = [
|
||||
{file = "mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8"},
|
||||
{file = "mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba"},
|
||||
@@ -1512,8 +1641,8 @@ mkdocs-exclude = [
|
||||
{file = "mkdocs-exclude-1.0.2.tar.gz", hash = "sha256:ba6fab3c80ddbe3fd31d3e579861fd3124513708271180a5f81846da8c7e2a51"},
|
||||
]
|
||||
mkdocs-material = [
|
||||
{file = "mkdocs_material-9.0.11-py3-none-any.whl", hash = "sha256:90a1e1ed41e90de5d0ab97c874b7bf6af488d0faf4aaea8e5868e01f3f1ed923"},
|
||||
{file = "mkdocs_material-9.0.11.tar.gz", hash = "sha256:aff49e4ce622a107ed563b3a6a37dc3660a45a0e4d9e7d4d2c13ce9dc02a7faf"},
|
||||
{file = "mkdocs_material-9.0.12-py3-none-any.whl", hash = "sha256:ff4233e4f4da0c879db0dbcb532a690a3f86f5a66a0cfcce99a124e82a462afb"},
|
||||
{file = "mkdocs_material-9.0.12.tar.gz", hash = "sha256:4da07b1390c6b78844f1566d723dd045572e645f31b108a1b5062fa7d11aa241"},
|
||||
]
|
||||
mkdocs-material-extensions = [
|
||||
{file = "mkdocs_material_extensions-1.1.1-py3-none-any.whl", hash = "sha256:e41d9f38e4798b6617ad98ca8f7f1157b1e4385ac1459ca1e4ea219b556df945"},
|
||||
@@ -1697,10 +1826,6 @@ mypy-extensions = [
|
||||
{file = "mypy_extensions-1.0.0-py3-none-any.whl", hash = "sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d"},
|
||||
{file = "mypy_extensions-1.0.0.tar.gz", hash = "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782"},
|
||||
]
|
||||
nanoid = [
|
||||
{file = "nanoid-2.0.0-py3-none-any.whl", hash = "sha256:90aefa650e328cffb0893bbd4c236cfd44c48bc1f2d0b525ecc53c3187b653bb"},
|
||||
{file = "nanoid-2.0.0.tar.gz", hash = "sha256:5a80cad5e9c6e9ae3a41fa2fb34ae189f7cb420b2a5d8f82bd9d23466e4efa68"},
|
||||
]
|
||||
nodeenv = [
|
||||
{file = "nodeenv-1.7.0-py2.py3-none-any.whl", hash = "sha256:27083a7b96a25f2f5e1d8cb4b6317ee8aeda3bdd121394e5ac54e498028a042e"},
|
||||
{file = "nodeenv-1.7.0.tar.gz", hash = "sha256:e0e7f7dfb85fc5394c6fe1e8fa98131a2473e04311a45afb6508f7cf1836fa2b"},
|
||||
@@ -1906,8 +2031,8 @@ rich = [
|
||||
{file = "rich-13.3.1.tar.gz", hash = "sha256:125d96d20c92b946b983d0d392b84ff945461e5a06d3867e9f9e575f8697b67f"},
|
||||
]
|
||||
setuptools = [
|
||||
{file = "setuptools-67.2.0-py3-none-any.whl", hash = "sha256:16ccf598aab3b506593c17378473978908a2734d7336755a8769b480906bec1c"},
|
||||
{file = "setuptools-67.2.0.tar.gz", hash = "sha256:b440ee5f7e607bb8c9de15259dba2583dd41a38879a7abc1d43a71c59524da48"},
|
||||
{file = "setuptools-67.3.1-py3-none-any.whl", hash = "sha256:23c86b4e44432bfd8899384afc08872ec166a24f48a3f99f293b0a557e6a6b5d"},
|
||||
{file = "setuptools-67.3.1.tar.gz", hash = "sha256:daec07fd848d80676694d6bf69c009d28910aeece68a38dbe88b7e1bb6dba12e"},
|
||||
]
|
||||
six = [
|
||||
{file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"},
|
||||
@@ -2030,6 +2155,10 @@ tzdata = [
|
||||
{file = "tzdata-2022.7-py2.py3-none-any.whl", hash = "sha256:2b88858b0e3120792a3c0635c23daf36a7d7eeeca657c323da299d2094402a0d"},
|
||||
{file = "tzdata-2022.7.tar.gz", hash = "sha256:fe5f866eddd8b96e9fcba978f8e503c909b19ea7efda11e52e39494bad3a7bfa"},
|
||||
]
|
||||
uc-micro-py = [
|
||||
{file = "uc-micro-py-1.0.1.tar.gz", hash = "sha256:b7cdf4ea79433043ddfe2c82210208f26f7962c0cfbe3bacb05ee879a7fdb596"},
|
||||
{file = "uc_micro_py-1.0.1-py3-none-any.whl", hash = "sha256:316cfb8b6862a0f1d03540f0ae6e7b033ff1fa0ddbe60c12cbe0d4cec846a69f"},
|
||||
]
|
||||
urllib3 = [
|
||||
{file = "urllib3-1.26.14-py2.py3-none-any.whl", hash = "sha256:75edcdc2f7d85b137124a6c3c9fc3933cdeaa12ecb9a6a959f22797a0feca7e1"},
|
||||
{file = "urllib3-1.26.14.tar.gz", hash = "sha256:076907bf8fd355cde77728471316625a4d2f7e713c125f51953bb5b3eecf4f72"},
|
||||
|
||||
@@ -39,6 +39,7 @@ textual = "textual.cli.cli:run"
|
||||
[tool.poetry.dependencies]
|
||||
python = "^3.7"
|
||||
rich = ">12.6.0"
|
||||
markdown-it-py = {extras = ["plugins", "linkify"], version = "^2.1.0"}
|
||||
#rich = {path="../rich", develop=true}
|
||||
importlib-metadata = "^4.11.3"
|
||||
typing-extensions = "^4.0.0"
|
||||
|
||||
@@ -19,6 +19,7 @@ if typing.TYPE_CHECKING:
|
||||
from ._label import Label
|
||||
from ._list_item import ListItem
|
||||
from ._list_view import ListView
|
||||
from ._markdown import Markdown, MarkdownViewer
|
||||
from ._placeholder import Placeholder
|
||||
from ._pretty import Pretty
|
||||
from ._static import Static
|
||||
@@ -30,7 +31,6 @@ if typing.TYPE_CHECKING:
|
||||
|
||||
__all__ = [
|
||||
"Button",
|
||||
"Switch",
|
||||
"DataTable",
|
||||
"DirectoryTree",
|
||||
"Footer",
|
||||
@@ -39,9 +39,12 @@ __all__ = [
|
||||
"Label",
|
||||
"ListItem",
|
||||
"ListView",
|
||||
"Markdown",
|
||||
"MarkdownViewer",
|
||||
"Placeholder",
|
||||
"Pretty",
|
||||
"Static",
|
||||
"Switch",
|
||||
"TextLog",
|
||||
"Tree",
|
||||
"Welcome",
|
||||
|
||||
@@ -8,6 +8,8 @@ from ._input import Input as Input
|
||||
from ._label import Label as Label
|
||||
from ._list_item import ListItem as ListItem
|
||||
from ._list_view import ListView as ListView
|
||||
from ._markdown import Markdown as Markdown
|
||||
from ._markdown import MarkdownViewer as MarkdownViewer
|
||||
from ._placeholder import Placeholder as Placeholder
|
||||
from ._pretty import Pretty as Pretty
|
||||
from ._static import Static as Static
|
||||
|
||||
772
src/textual/widgets/_markdown.py
Normal file
772
src/textual/widgets/_markdown.py
Normal file
@@ -0,0 +1,772 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from pathlib import Path
|
||||
from typing import Iterable, TypeAlias
|
||||
|
||||
from markdown_it import MarkdownIt
|
||||
from rich.style import Style
|
||||
from rich.syntax import Syntax
|
||||
from rich.text import Text
|
||||
|
||||
from ..app import ComposeResult
|
||||
from ..containers import Vertical
|
||||
from ..message import Message
|
||||
from ..reactive import reactive, var
|
||||
from ..widget import Widget
|
||||
from ..widgets import DataTable, Static, Tree
|
||||
|
||||
TOC: TypeAlias = "list[tuple[int, str, str | None]]"
|
||||
|
||||
|
||||
class Navigator:
|
||||
"""Manages a stack of paths like a browser."""
|
||||
|
||||
def __init__(self) -> None:
|
||||
self.stack: list[Path] = []
|
||||
self.index = 0
|
||||
|
||||
@property
|
||||
def location(self) -> Path:
|
||||
"""The current location.
|
||||
|
||||
Returns:
|
||||
A path for the current document.
|
||||
"""
|
||||
if not self.stack:
|
||||
return Path(".")
|
||||
return self.stack[self.index]
|
||||
|
||||
def go(self, path: str) -> Path:
|
||||
"""Go to a new document.
|
||||
|
||||
Args:
|
||||
path: Path to new document.
|
||||
|
||||
Returns:
|
||||
Path: New location.
|
||||
"""
|
||||
new_path = self.location.parent / Path(path)
|
||||
self.stack = self.stack[: self.index + 1]
|
||||
new_path = new_path.absolute()
|
||||
self.stack.append(new_path)
|
||||
self.index = len(self.stack) - 1
|
||||
return new_path
|
||||
|
||||
def back(self) -> bool:
|
||||
"""Go back in the stack.
|
||||
|
||||
Returns:
|
||||
True if the location changed, otherwise False.
|
||||
"""
|
||||
if self.index:
|
||||
self.index -= 1
|
||||
return True
|
||||
return False
|
||||
|
||||
def forward(self) -> bool:
|
||||
"""Go forward in the stack.
|
||||
|
||||
Returns:
|
||||
True if the location changed, otherwise False.
|
||||
"""
|
||||
if self.index < len(self.stack) - 1:
|
||||
self.index += 1
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
class Block(Static):
|
||||
"""The base class for a Markdown Element."""
|
||||
|
||||
DEFAULT_CSS = """
|
||||
Block {
|
||||
height: auto;
|
||||
}
|
||||
"""
|
||||
|
||||
def __init__(self, *args, **kwargs) -> None:
|
||||
self.text = Text()
|
||||
self.blocks: list[Block] = []
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
def compose(self) -> ComposeResult:
|
||||
yield from self.blocks
|
||||
self.blocks.clear()
|
||||
|
||||
def set_content(self, text: Text) -> None:
|
||||
self.text = text
|
||||
self.update(text)
|
||||
|
||||
async def action_link(self, href: str) -> None:
|
||||
await self.post_message(Markdown.LinkClicked(href, sender=self))
|
||||
|
||||
|
||||
class Header(Block):
|
||||
"""Base class for a Markdown header."""
|
||||
|
||||
DEFAULT_CSS = """
|
||||
Header {
|
||||
color: $text;
|
||||
}
|
||||
"""
|
||||
|
||||
|
||||
class H1(Header):
|
||||
"""An H1 Markdown header."""
|
||||
|
||||
DEFAULT_CSS = """
|
||||
|
||||
H1 {
|
||||
background: $accent-darken-2;
|
||||
border: wide $background;
|
||||
content-align: center middle;
|
||||
|
||||
padding: 1;
|
||||
text-style: bold;
|
||||
color: $text;
|
||||
}
|
||||
|
||||
"""
|
||||
|
||||
|
||||
class H2(Header):
|
||||
"""An H2 Markdown header."""
|
||||
|
||||
DEFAULT_CSS = """
|
||||
|
||||
H2 {
|
||||
background: $panel;
|
||||
border: wide $background;
|
||||
text-align: center;
|
||||
text-style: underline;
|
||||
color: $text;
|
||||
padding: 1;
|
||||
text-style: bold;
|
||||
}
|
||||
|
||||
"""
|
||||
|
||||
|
||||
class H3(Header):
|
||||
"""An H3 Markdown header."""
|
||||
|
||||
DEFAULT_CSS = """
|
||||
H3 {
|
||||
background: $surface;
|
||||
text-style: bold;
|
||||
color: $text;
|
||||
border-bottom: wide $foreground;
|
||||
width: auto;
|
||||
}
|
||||
"""
|
||||
|
||||
|
||||
class H4(Header):
|
||||
"""An H4 Markdown header."""
|
||||
|
||||
DEFAULT_CSS = """
|
||||
H4 {
|
||||
text-style: underline;
|
||||
margin: 1 0;
|
||||
}
|
||||
|
||||
"""
|
||||
|
||||
|
||||
class H5(Header):
|
||||
"""An H5 Markdown header."""
|
||||
|
||||
DEFAULT_CSS = """
|
||||
H5 {
|
||||
text-style: bold;
|
||||
color: $text;
|
||||
margin: 1 0;
|
||||
}
|
||||
|
||||
"""
|
||||
|
||||
|
||||
class H6(Header):
|
||||
"""An H6 Markdown header."""
|
||||
|
||||
DEFAULT_CSS = """
|
||||
H6 {
|
||||
text-style: bold;
|
||||
color: $text-muted;
|
||||
margin: 1 0;
|
||||
}
|
||||
|
||||
"""
|
||||
|
||||
|
||||
class Paragraph(Block):
|
||||
"""A paragraph Markdown block."""
|
||||
|
||||
DEFAULT_CSS = """
|
||||
Markdown > Paragraph {
|
||||
margin: 0 0 1 0;
|
||||
}
|
||||
"""
|
||||
|
||||
|
||||
class BlockQuote(Block):
|
||||
"""A block quote Markdown block."""
|
||||
|
||||
DEFAULT_CSS = """
|
||||
BlockQuote {
|
||||
background: $boost;
|
||||
border-left: outer $success;
|
||||
margin: 1 0;
|
||||
padding: 0 1;
|
||||
}
|
||||
BlockQuote > BlockQuote {
|
||||
margin-left: 2;
|
||||
margin-top: 1;
|
||||
}
|
||||
|
||||
"""
|
||||
|
||||
|
||||
class BulletList(Block):
|
||||
"""A Bullet list Markdown block."""
|
||||
|
||||
DEFAULT_CSS = """
|
||||
|
||||
BulletList {
|
||||
margin: 0;
|
||||
padding: 0 0;
|
||||
}
|
||||
|
||||
BulletList BulletList {
|
||||
margin: 0;
|
||||
padding-top: 0;
|
||||
}
|
||||
|
||||
"""
|
||||
|
||||
|
||||
class OrderedList(Block):
|
||||
"""An ordered list Markdown block."""
|
||||
|
||||
DEFAULT_CSS = """
|
||||
|
||||
OrderedList {
|
||||
margin: 0;
|
||||
padding: 0 0;
|
||||
}
|
||||
|
||||
OrderedList OrderedList {
|
||||
margin: 0;
|
||||
padding-top: 0;
|
||||
}
|
||||
|
||||
"""
|
||||
|
||||
|
||||
class Table(Block):
|
||||
"""A Table markdown Block."""
|
||||
|
||||
DEFAULT_CSS = """
|
||||
Table {
|
||||
margin: 1 0;
|
||||
}
|
||||
Table > DataTable {
|
||||
width: 100%;
|
||||
height: auto;
|
||||
}
|
||||
"""
|
||||
|
||||
def compose(self) -> ComposeResult:
|
||||
def flatten(block: Block) -> Iterable[Block]:
|
||||
for block in block.blocks:
|
||||
if block.blocks:
|
||||
yield from flatten(block)
|
||||
yield block
|
||||
|
||||
headers: list[Text] = []
|
||||
rows: list[list[Text]] = []
|
||||
for block in flatten(self):
|
||||
if isinstance(block, TH):
|
||||
headers.append(block.text)
|
||||
elif isinstance(block, TR):
|
||||
rows.append([])
|
||||
elif isinstance(block, TD):
|
||||
rows[-1].append(block.text)
|
||||
|
||||
table: DataTable = DataTable(zebra_stripes=True)
|
||||
table.can_focus = False
|
||||
table.add_columns(*headers)
|
||||
table.add_rows([row for row in rows if row])
|
||||
yield table
|
||||
self.blocks.clear()
|
||||
|
||||
|
||||
class TBody(Block):
|
||||
"""A table body Markdown block."""
|
||||
|
||||
DEFAULT_CSS = """
|
||||
|
||||
"""
|
||||
|
||||
|
||||
class THead(Block):
|
||||
"""A table head Markdown block."""
|
||||
|
||||
DEFAULT_CSS = """
|
||||
|
||||
"""
|
||||
|
||||
|
||||
class TR(Block):
|
||||
"""A table row Markdown block."""
|
||||
|
||||
DEFAULT_CSS = """
|
||||
|
||||
"""
|
||||
|
||||
|
||||
class TH(Block):
|
||||
"""A table header Markdown block."""
|
||||
|
||||
DEFAULT_CSS = """
|
||||
|
||||
"""
|
||||
|
||||
|
||||
class TD(Block):
|
||||
"""A table data Markdown block."""
|
||||
|
||||
DEFAULT_CSS = """
|
||||
|
||||
"""
|
||||
|
||||
|
||||
class Bullet(Widget):
|
||||
"""A bullet widget."""
|
||||
|
||||
DEFAULT_CSS = """
|
||||
Bullet {
|
||||
width: auto;
|
||||
}
|
||||
"""
|
||||
|
||||
symbol = reactive("● ")
|
||||
|
||||
def render(self) -> Text:
|
||||
return Text(self.symbol)
|
||||
|
||||
|
||||
class ListItem(Block):
|
||||
"""A list item Markdown block."""
|
||||
|
||||
DEFAULT_CSS = """
|
||||
|
||||
ListItem {
|
||||
layout: horizontal;
|
||||
margin-right: 1;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
ListItem > Vertical {
|
||||
width: 1fr;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self, bullet: str) -> None:
|
||||
self.bullet = bullet
|
||||
super().__init__()
|
||||
|
||||
def compose(self) -> ComposeResult:
|
||||
bullet = Bullet()
|
||||
bullet.symbol = self.bullet
|
||||
yield bullet
|
||||
yield Vertical(*self.blocks)
|
||||
|
||||
self.blocks.clear()
|
||||
|
||||
|
||||
class Fence(Block):
|
||||
"""A fence Markdown block."""
|
||||
|
||||
DEFAULT_CSS = """
|
||||
Fence {
|
||||
margin: 1 0;
|
||||
overflow: auto;
|
||||
width: 100%;
|
||||
height: auto;
|
||||
max-height: 20;
|
||||
}
|
||||
|
||||
Fence > * {
|
||||
width: auto;
|
||||
}
|
||||
"""
|
||||
|
||||
def __init__(self, code: str, lexer: str) -> None:
|
||||
self.code = code
|
||||
self.lexer = lexer
|
||||
super().__init__()
|
||||
|
||||
def compose(self) -> ComposeResult:
|
||||
yield Static(
|
||||
Syntax(
|
||||
self.code,
|
||||
lexer=self.lexer,
|
||||
word_wrap=False,
|
||||
indent_guides=True,
|
||||
padding=(1, 2),
|
||||
theme="material",
|
||||
),
|
||||
expand=True,
|
||||
shrink=False,
|
||||
)
|
||||
|
||||
|
||||
HEADINGS = {"h1": H1, "h2": H2, "h3": H3, "h4": H4, "h5": H5, "h6": H6}
|
||||
|
||||
NUMERALS = " ⅠⅡⅢⅣⅤⅥ"
|
||||
|
||||
|
||||
class Markdown(Widget):
|
||||
DEFAULT_CSS = """
|
||||
Markdown {
|
||||
height: auto;
|
||||
margin: 0 4 1 4;
|
||||
layout: vertical;
|
||||
}
|
||||
.em {
|
||||
text-style: italic;
|
||||
}
|
||||
.strong {
|
||||
text-style: bold;
|
||||
}
|
||||
.s {
|
||||
text-style: strike;
|
||||
}
|
||||
.code_inline {
|
||||
text-style: bold dim;
|
||||
}
|
||||
"""
|
||||
COMPONENT_CLASSES = {"em", "strong", "s", "code_inline"}
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
markdown: str | None = None,
|
||||
*,
|
||||
name: str | None = None,
|
||||
id: str | None = None,
|
||||
classes: str | None = None,
|
||||
):
|
||||
super().__init__(name=name, id=id, classes=classes)
|
||||
self._markdown = markdown
|
||||
|
||||
class TOCUpdated(Message, bubble=True):
|
||||
"""The table of contents was updated."""
|
||||
|
||||
def __init__(self, toc: TOC, *, sender: Widget) -> None:
|
||||
super().__init__(sender=sender)
|
||||
self.toc = toc
|
||||
|
||||
class TOCSelected(Message, bubble=True):
|
||||
"""An item in the TOC was selected."""
|
||||
|
||||
def __init__(self, block_id: str, *, sender: Widget) -> None:
|
||||
super().__init__(sender=sender)
|
||||
self.block_id = block_id
|
||||
|
||||
class LinkClicked(Message, bubble=True):
|
||||
"""A link in the document was clicked."""
|
||||
|
||||
def __init__(self, href: str, *, sender: Widget) -> None:
|
||||
super().__init__(sender=sender)
|
||||
self.href: str = href
|
||||
"""The link that was selected."""
|
||||
|
||||
async def on_mount(self) -> None:
|
||||
if self._markdown is not None:
|
||||
await self.update(self._markdown)
|
||||
|
||||
async def load(self, path: Path) -> bool:
|
||||
"""Load a new Markdown document.
|
||||
|
||||
Args:
|
||||
path: Path to the document.
|
||||
|
||||
Returns:
|
||||
True on success, or False if the document could not be read.
|
||||
"""
|
||||
try:
|
||||
markdown = path.read_text(encoding="utf-8")
|
||||
except Exception:
|
||||
return False
|
||||
await self.query("Block").remove()
|
||||
await self.update(markdown)
|
||||
return True
|
||||
|
||||
async def update(self, markdown: str) -> None:
|
||||
"""Update the document with new Markdown.
|
||||
|
||||
Args:
|
||||
markdown: A string containing Markdown.
|
||||
"""
|
||||
output: list[Block] = []
|
||||
stack: list[Block] = []
|
||||
parser = MarkdownIt("gfm-like")
|
||||
|
||||
content = Text()
|
||||
block_id: int = 0
|
||||
|
||||
toc: TOC = []
|
||||
|
||||
for token in parser.parse(markdown):
|
||||
if token.type == "heading_open":
|
||||
block_id += 1
|
||||
stack.append(HEADINGS[token.tag](id=f"block{block_id}"))
|
||||
elif token.type == "paragraph_open":
|
||||
stack.append(Paragraph())
|
||||
elif token.type == "blockquote_open":
|
||||
stack.append(BlockQuote())
|
||||
elif token.type == "bullet_list_open":
|
||||
stack.append(BulletList())
|
||||
elif token.type == "ordered_list_open":
|
||||
stack.append(OrderedList())
|
||||
elif token.type == "list_item_open":
|
||||
stack.append(ListItem(f"{token.info}. " if token.info else "● "))
|
||||
elif token.type == "table_open":
|
||||
stack.append(Table())
|
||||
elif token.type == "tbody_open":
|
||||
stack.append(TBody())
|
||||
elif token.type == "thead_open":
|
||||
stack.append(THead())
|
||||
elif token.type == "tr_open":
|
||||
stack.append(TR())
|
||||
elif token.type == "th_open":
|
||||
stack.append(TH())
|
||||
elif token.type == "td_open":
|
||||
stack.append(TD())
|
||||
elif token.type.endswith("_close"):
|
||||
block = stack.pop()
|
||||
if token.type == "heading_close":
|
||||
heading = block.text.plain
|
||||
level = int(token.tag[1:])
|
||||
toc.append((level, heading, block.id))
|
||||
if stack:
|
||||
stack[-1].blocks.append(block)
|
||||
else:
|
||||
output.append(block)
|
||||
elif token.type == "inline":
|
||||
style_stack: list[Style] = [Style()]
|
||||
content = Text()
|
||||
if token.children:
|
||||
for child in token.children:
|
||||
if child.type == "text":
|
||||
content.append(child.content, style_stack[-1])
|
||||
elif child.type == "code_inline":
|
||||
content.append(
|
||||
child.content,
|
||||
style_stack[-1]
|
||||
+ self.get_component_rich_style(
|
||||
"code_inline", partial=True
|
||||
),
|
||||
)
|
||||
elif child.type == "em_open":
|
||||
style_stack.append(
|
||||
style_stack[-1]
|
||||
+ self.get_component_rich_style("em", partial=True)
|
||||
)
|
||||
elif child.type == "strong_open":
|
||||
style_stack.append(
|
||||
style_stack[-1]
|
||||
+ self.get_component_rich_style("strong", partial=True)
|
||||
)
|
||||
elif child.type == "s_open":
|
||||
style_stack.append(
|
||||
style_stack[-1]
|
||||
+ self.get_component_rich_style("s", partial=True)
|
||||
)
|
||||
elif child.type == "link_open":
|
||||
href = child.attrs.get("href", "")
|
||||
action = f"link({href!r})"
|
||||
style_stack.append(
|
||||
style_stack[-1] + Style.from_meta({"@click": action})
|
||||
)
|
||||
elif child.type == "image":
|
||||
href = child.attrs.get("src", "")
|
||||
alt = child.attrs.get("alt", "")
|
||||
|
||||
action = f"link({href!r})"
|
||||
style_stack.append(
|
||||
style_stack[-1] + Style.from_meta({"@click": action})
|
||||
)
|
||||
|
||||
content.append("🖼 ", style_stack[-1])
|
||||
if alt:
|
||||
content.append(f"({alt})", style_stack[-1])
|
||||
if child.children is not None:
|
||||
for grandchild in child.children:
|
||||
content.append(grandchild.content, style_stack[-1])
|
||||
|
||||
style_stack.pop()
|
||||
|
||||
elif child.type.endswith("_close"):
|
||||
style_stack.pop()
|
||||
|
||||
stack[-1].set_content(content)
|
||||
elif token.type == "fence":
|
||||
output.append(
|
||||
Fence(
|
||||
token.content.rstrip(),
|
||||
token.info,
|
||||
)
|
||||
)
|
||||
|
||||
await self.post_message(Markdown.TOCUpdated(toc, sender=self))
|
||||
await self.mount(*output)
|
||||
|
||||
|
||||
class MarkdownTOC(Widget, can_focus_children=True):
|
||||
DEFAULT_CSS = """
|
||||
MarkdownTOC {
|
||||
width: auto;
|
||||
background: $panel;
|
||||
border-right: wide $background;
|
||||
}
|
||||
MarkdownTOC > Tree {
|
||||
padding: 1;
|
||||
width: auto;
|
||||
}
|
||||
"""
|
||||
|
||||
toc: reactive[TOC | None] = reactive(None, init=False)
|
||||
|
||||
def compose(self) -> ComposeResult:
|
||||
tree: Tree = Tree("TOC")
|
||||
tree.show_root = False
|
||||
tree.show_guides = True
|
||||
tree.guide_depth = 4
|
||||
tree.auto_expand = False
|
||||
yield tree
|
||||
|
||||
def watch_toc(self, toc: TOC) -> None:
|
||||
"""Triggered when the TOC changes."""
|
||||
self.set_toc(toc)
|
||||
|
||||
def set_toc(self, toc: TOC) -> None:
|
||||
"""Set the Table of Contents.
|
||||
|
||||
Args:
|
||||
toc: Table of contents.
|
||||
"""
|
||||
tree = self.query_one(Tree)
|
||||
tree.clear()
|
||||
root = tree.root
|
||||
for level, name, block_id in toc:
|
||||
node = root
|
||||
for _ in range(level - 1):
|
||||
if node._children:
|
||||
node = node._children[-1]
|
||||
node.expand()
|
||||
node.allow_expand = True
|
||||
else:
|
||||
node = node.add(NUMERALS[level], expand=True)
|
||||
node.add_leaf(f"[dim]{NUMERALS[level]}[/] {name}", {"block_id": block_id})
|
||||
|
||||
async def on_tree_node_selected(self, message: Tree.NodeSelected) -> None:
|
||||
node_data = message.node.data
|
||||
if node_data is not None:
|
||||
await self.post_message(
|
||||
Markdown.TOCSelected(node_data["block_id"], sender=self)
|
||||
)
|
||||
|
||||
|
||||
class MarkdownViewer(Vertical, can_focus=True, can_focus_children=True):
|
||||
"""A Markdown viewer widget."""
|
||||
|
||||
DEFAULT_CSS = """
|
||||
MarkdownViewer {
|
||||
height: 1fr;
|
||||
scrollbar-gutter: stable;
|
||||
}
|
||||
|
||||
MarkdownTOC {
|
||||
dock:left;
|
||||
}
|
||||
|
||||
MarkdownViewer > MarkdownTOC {
|
||||
display: none;
|
||||
}
|
||||
|
||||
MarkdownViewer.-show-toc > MarkdownTOC {
|
||||
display: block;
|
||||
}
|
||||
|
||||
"""
|
||||
|
||||
show_toc = reactive(True)
|
||||
top_block = reactive("")
|
||||
|
||||
navigator: var[Navigator] = var(Navigator)
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
markdown: str | None = None,
|
||||
*,
|
||||
show_toc: bool = True,
|
||||
name: str | None = None,
|
||||
id: str | None = None,
|
||||
classes: str | None = None,
|
||||
):
|
||||
super().__init__(name=name, id=id, classes=classes)
|
||||
self.show_toc = show_toc
|
||||
self._markdown = markdown
|
||||
|
||||
@property
|
||||
def document(self) -> Markdown:
|
||||
"""The Markdown document object."""
|
||||
return self.query_one(Markdown)
|
||||
|
||||
@property
|
||||
def toc(self) -> MarkdownTOC:
|
||||
"""The Table of Contents widget"""
|
||||
return self.query_one(MarkdownTOC)
|
||||
|
||||
async def on_mount(self) -> None:
|
||||
if self._markdown is not None:
|
||||
await self.document.update(self._markdown)
|
||||
|
||||
async def go(self, location: str) -> bool:
|
||||
"""Navigate to a new document path."""
|
||||
return await self.document.load(self.navigator.go(location))
|
||||
|
||||
async def back(self) -> None:
|
||||
"""Go back one level in the history."""
|
||||
if self.navigator.back():
|
||||
await self.document.load(self.navigator.location)
|
||||
|
||||
async def forward(self) -> None:
|
||||
"""Go forward one level in the history."""
|
||||
if self.navigator.forward():
|
||||
await self.document.load(self.navigator.location)
|
||||
|
||||
async def on_markdown_link_clicked(self, message: Markdown.LinkClicked) -> None:
|
||||
message.stop()
|
||||
await self.go(message.href)
|
||||
|
||||
def watch_show_toc(self, show_toc: bool) -> None:
|
||||
self.set_class(show_toc, "-show-toc")
|
||||
|
||||
def compose(self) -> ComposeResult:
|
||||
yield MarkdownTOC()
|
||||
yield Markdown()
|
||||
|
||||
def on_markdown_tocupdated(self, message: Markdown.TOCUpdated) -> None:
|
||||
self.query_one(MarkdownTOC).toc = message.toc
|
||||
message.stop()
|
||||
|
||||
def on_markdown_tocselected(self, message: Markdown.TOCSelected) -> None:
|
||||
block_selector = f"#{message.block_id}"
|
||||
block = self.query_one(block_selector, Block)
|
||||
self.scroll_to_widget(block, top=True)
|
||||
message.stop()
|
||||
3
src/textual/widgets/_markdown_viewer.py
Normal file
3
src/textual/widgets/_markdown_viewer.py
Normal file
@@ -0,0 +1,3 @@
|
||||
from ._markdown import MarkdownViewer
|
||||
|
||||
__all__ = ["MarkdownViewer"]
|
||||
@@ -51,7 +51,13 @@ class _TreeLine(Generic[TreeDataType]):
|
||||
Returns:
|
||||
Width in cells.
|
||||
"""
|
||||
guides = max(0, len(self.path) - (1 if show_root else 2)) * guide_depth
|
||||
if show_root:
|
||||
return 2 + (max(0, len(self.path) - 1)) * guide_depth
|
||||
else:
|
||||
guides = 2
|
||||
if len(self.path) > 1:
|
||||
guides += (len(self.path) - 1) * guide_depth
|
||||
|
||||
return guides
|
||||
|
||||
|
||||
|
||||
57
src/textual/widgets/browser_app.py
Normal file
57
src/textual/widgets/browser_app.py
Normal file
@@ -0,0 +1,57 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import sys
|
||||
|
||||
from textual.app import App, ComposeResult
|
||||
from textual.reactive import var
|
||||
from textual.widgets import Footer
|
||||
|
||||
from ._markdown import MarkdownBrowser
|
||||
|
||||
|
||||
class BrowserApp(App):
|
||||
BINDINGS = [
|
||||
("t", "toggle_toc", "TOC"),
|
||||
("b", "back", "Back"),
|
||||
("f", "forward", "Forward"),
|
||||
]
|
||||
|
||||
path = var("")
|
||||
|
||||
def compose(self) -> ComposeResult:
|
||||
yield Footer()
|
||||
yield MarkdownBrowser()
|
||||
|
||||
@property
|
||||
def browser(self) -> MarkdownBrowser:
|
||||
return self.query_one(MarkdownBrowser)
|
||||
|
||||
def on_load(self) -> None:
|
||||
try:
|
||||
path = sys.argv[1]
|
||||
except IndexError:
|
||||
self.exit(message="Usage: python -m textual_markdown PATH")
|
||||
else:
|
||||
self.path = path
|
||||
|
||||
async def on_mount(self) -> None:
|
||||
self.browser.focus()
|
||||
if not await self.browser.go(self.path):
|
||||
self.exit(message=f"Unable to load {self.path!r}")
|
||||
|
||||
async def load(self, path: str) -> None:
|
||||
await self.browser.go(path)
|
||||
|
||||
def action_toggle_toc(self) -> None:
|
||||
self.browser.show_toc = not self.browser.show_toc
|
||||
|
||||
async def action_back(self) -> None:
|
||||
await self.browser.back()
|
||||
|
||||
async def action_forward(self) -> None:
|
||||
await self.browser.forward()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
app = BrowserApp()
|
||||
app.run()
|
||||
3
src/textual/widgets/markdown.py
Normal file
3
src/textual/widgets/markdown.py
Normal file
@@ -0,0 +1,3 @@
|
||||
from ._markdown import Markdown, MarkdownTOC
|
||||
|
||||
__all__ = ["MarkdownTOC", "Markdown"]
|
||||
Reference in New Issue
Block a user