diff --git a/DrissionPage/configs/chromium_options.py b/DrissionPage/configs/chromium_options.py
index 4d42d3b..1fe9603 100644
--- a/DrissionPage/configs/chromium_options.py
+++ b/DrissionPage/configs/chromium_options.py
@@ -274,10 +274,9 @@ class ChromiumOptions(object):
def set_page_load_strategy(self, value):
"""设置page_load_strategy,可接收 'normal', 'eager', 'none'
- selenium4以上版本才支持此功能
normal:默认情况下使用, 等待所有资源下载完成
eager:DOM访问已准备就绪, 但其他资源 (如图像) 可能仍在加载中
- none:完全不阻塞WebDriver
+ none:完全不阻塞
:param value: 可接收 'normal', 'eager', 'none'
:return: 当前对象
"""
diff --git a/MANIFEST.in b/MANIFEST.in
index 11a494f..4c619d1 100644
--- a/MANIFEST.in
+++ b/MANIFEST.in
@@ -1,6 +1,4 @@
include DrissionPage/configs/configs.ini
include DrissionPage/*.pyi
-include DrissionPage/configs/*.py
-include DrissionPage/configs/*.pyi
-include DrissionPage/functions/*.py
-include DrissionPage/functions/*.pyi
\ No newline at end of file
+include DrissionPage/*/*.py
+include DrissionPage/*/*.pyi
\ No newline at end of file
diff --git a/docs/README.md b/docs/README.md
index bc47ef2..9ff72b4 100644
--- a/docs/README.md
+++ b/docs/README.md
@@ -10,6 +10,16 @@ DrissionPage 是一个基于 python 的网页自动化工具。
它的语法简洁而优雅,代码量少,对新手友好。
+***
+
+支持系统:Windows、Linux、Mac
+
+python 版本:3.6 及以上
+
+支持浏览器:Chromium 内核(如 Chrome 和 edge)
+
+***
+
项目地址:[gitee](https://gitee.com/g1879/DrissionPage) | [github](https://github.com/g1879/DrissionPage)
@@ -24,8 +34,9 @@ DrissionPage 是一个基于 python 的网页自动化工具。
使用浏览器,可以很大程度上绕过这些坑,但浏览器运行效率不高。
因此,这个库设计初衷,是将它们合而为一,能够在不同须要时切换相应模式,并提供一种人性化的使用方法,提高开发和运行效率。
-除了合并两者,本库还以网页为单位封装了常用功能,提供非常简便的操作和语句,在用于网页自动化操作时,减少考虑细节,专注功能实现,使用更方便。
-一切从简,尽量提供简单直接的使用方法,对新手更友好。
+除了合并两者,本库还以网页为单位封装了常用功能,提供非常简便的操作和语句,在用于网页自动化操作时,减少考虑细节,专注功能实现,使用更方便。 一切从简,尽量提供简单直接的使用方法,使代码更优雅。
+
+以前的版本是对 selenium 进行重新封装实现的。从 3.0 开始,作者另起炉灶,对底层进行了重新开发,摆脱对 selenium 的依赖,增强了功能,提升了运行效率。
# 💡 理念
diff --git a/docs/WebPage使用方法/3.10动作链.md b/docs/WebPage使用方法/3.10动作链.md
index ee8bd3a..b89a64b 100644
--- a/docs/WebPage使用方法/3.10动作链.md
+++ b/docs/WebPage使用方法/3.10动作链.md
@@ -32,13 +32,9 @@ from DrissionPage import ActionChains
创建动作链对象非常简单,只要把`WebPage`对象或`ChromiumPage`对象传入即可。动作链只在这个页面上生效。
-**◽ 参数:**
-
-| 名称 | 类型 | 默认 | 说明 |
-| ------ | ---------------------------- | --- | ------------ |
-| `page` | `WebPage`对象或`ChromiumPage`对象 | 无 | 动作链要操作的浏览器页面 |
-
-**◽ 示例:**
+| 初始化参数 | 类型 | 默认值 | 说明 |
+|:------:|:---------------------------:|:---:| ------------ |
+| `page` | `WebPage`
`ChromiumPage` | 无 | 动作链要操作的浏览器页面 |
```python
from DrissionPage import WebPage, ActionChains
@@ -53,215 +49,215 @@ ac = ActionChains(page)
此方法用于移动鼠标到元素中点,或页面上的某个绝对坐标。可设置偏移量,当带偏移量时,偏移量相对于元素左上角坐标。
-**◽ 参数:**
+| 初始化参数 | 类型 | 默认值 | 说明 |
+|:------------:|:-----------------------------------------------:|:---:| --------------------------------------- |
+| `ele_or_loc` | `ChrmoiumElement`
`str`
`Tuple[int, int]` | 无 | 元素对象、文本定位符或绝对坐标,坐标为`tuple`(int, int) 形式 |
+| `offset_x` | `int` | 0 | x 轴偏移量,向右为正,向左为负 |
+| `offset_y` | `int` | 0 | y 轴偏移量,向下为正,向上为负 |
-| 名称 | 类型 | 默认 | 说明 |
-| ------------ | ----------------------------------------- | --- | --------------------------------------- |
-| `ele_or_loc` | `ChrmoiumElement`、`str`、`Tuple[int, int]` | 无 | 元素对象、文本定位符或绝对坐标,坐标为`tuple`(int, int) 形式 |
-| `offset_x` | `int` | 0 | x 轴偏移量,向右为正,向左为负 |
-| `offset_y` | `int` | 0 | y 轴偏移量,向下为正,向上为负 |
-
-**◽ 返回:**
-
-| 类型 | 说明 |
+| 返回类型 | 说明 |
| -------------- | ------- |
| `ActionChains` | 动作链对象本身 |
-**◽ 示例:**
+**示例:** 使鼠标移动到 ele 元素上
```python
ele = page('tag:a')
-ac.move_to(ele_or_loc=ele) # 使鼠标移动过到 ele 元素上
+ac.move_to(ele_or_loc=ele)
```
## 📍 `move()`
此方法用于使鼠标相对当前位置移动若干距离。
-**◽ 参数:**
-
-| 名称 | 类型 | 默认 | 说明 |
-| ---------- | ----- | --- | ---------------- |
+| 参数名称 | 类型 | 默认值 | 说明 |
+|:----------:|:-----:|:---:| ---------------- |
| `offset_x` | `int` | 0 | x 轴偏移量,向右为正,向左为负 |
| `offset_y` | `int` | 0 | y 轴偏移量,向下为正,向上为负 |
-**◽ 返回:**
-
-| 类型 | 说明 |
+| 返回类型 | 说明 |
| -------------- | ------- |
| `ActionChains` | 动作链对象本身 |
-**◽ 示例:**
+**示例:** 鼠标向右移动 300 像素
```python
-ac.move(300, 0) # 鼠标向右移动 300 像素
+ac.move(300, 0)
```
## 📍 `up()`
此方法用于使鼠标相对当前位置向上移动若干距离。
-**◽ 参数:**
-
-| 名称 | 类型 | 默认 | 说明 |
-| ------- | ----- | --- | -------- |
+| 参数名称 | 类型 | 默认值 | 说明 |
+|:-------:|:-----:|:---:| -------- |
| `pixel` | `int` | 无 | 鼠标移动的像素值 |
-**◽ 返回:**
-
-| 类型 | 说明 |
+| 返回类型 | 说明 |
| -------------- | ------- |
| `ActionChains` | 动作链对象本身 |
-**◽ 示例:**
+**示例:** 鼠标向上移动 50 像素
```python
-ac.up(50) # 鼠标向上移动 50 像素
+ac.up(50)
```
## 📍 `down()`
此方法用于使鼠标相对当前位置向下移动若干距离。
-**◽ 参数:**
-
-| 名称 | 类型 | 默认 | 说明 |
-| ------- | ----- | --- | -------- |
+| 参数名称 | 类型 | 默认值 | 说明 |
+|:-------:|:-----:|:---:| -------- |
| `pixel` | `int` | 无 | 鼠标移动的像素值 |
-**◽ 返回:**
-
-| 类型 | 说明 |
+| 返回类型 | 说明 |
| -------------- | ------- |
| `ActionChains` | 动作链对象本身 |
+**示例:**
+
+```python
+ac.down(50)
+```
+
## 📍 `left()`
此方法用于使鼠标相对当前位置向左移动若干距离。
-**◽ 参数:**
-
-| 名称 | 类型 | 默认 | 说明 |
-| ------- | ----- | --- | -------- |
+| 参数名称 | 类型 | 默认值 | 说明 |
+|:-------:|:-----:|:---:| -------- |
| `pixel` | `int` | 无 | 鼠标移动的像素值 |
-**◽ 返回:**
-
-| 类型 | 说明 |
+| 返回类型 | 说明 |
| -------------- | ------- |
| `ActionChains` | 动作链对象本身 |
+**示例:**
+
+```python
+ac.left(50)
+```
+
## 📍 `right()`
此方法用于使鼠标相对当前位置向右移动若干距离。
-**◽ 参数:**
-
-| 名称 | 类型 | 默认 | 说明 |
-| ------- | ----- | --- | -------- |
+| 参数名称 | 类型 | 默认值 | 说明 |
+|:-------:|:-----:|:---:| -------- |
| `pixel` | `int` | 无 | 鼠标移动的像素值 |
-**◽ 返回:**
-
-| 类型 | 说明 |
+| 返回类型 | 说明 |
| -------------- | ------- |
| `ActionChains` | 动作链对象本身 |
+**示例:**
+
+```python
+ac.right(50)
+```
+
# ✔ 鼠标按键
## 📍 `click()`
此方法用于单击鼠标左键,单击前可先移动到元素上。
-**◽ 参数:**
+| 参数名称 | 类型 | 默认值 | 说明 |
+|:--------:|:--------------------------:|:------:| -------------- |
+| `on_ele` | `ChromiumElement`
`str` | `None` | 要点击的元素对象或文本定位符 |
-| 名称 | 类型 | 默认 | 说明 |
-| -------- | ----------------------- | ------ | -------------- |
-| `on_ele` | `ChromiumElement`、`str` | `None` | 要点击的元素对象或文本定位符 |
-
-**◽ 返回:**
-
-| 类型 | 说明 |
+| 返回类型 | 说明 |
| -------------- | ------- |
| `ActionChains` | 动作链对象本身 |
+**示例:**
+
+```python
+ac.click('#div1')
+```
+
## 📍 `r_click()`
此方法用于单击鼠标右键,单击前可先移动到元素上。
-**◽ 参数:**
+| 参数名称 | 类型 | 默认值 | 说明 |
+|:--------:|:--------------------------:|:------:| -------------- |
+| `on_ele` | `ChromiumElement`
`str` | `None` | 要点击的元素对象或文本定位符 |
-| 名称 | 类型 | 默认 | 说明 |
-| -------- | ----------------------- | ------ | -------------- |
-| `on_ele` | `ChromiumElement`、`str` | `None` | 要点击的元素对象或文本定位符 |
-
-**◽ 返回:**
-
-| 类型 | 说明 |
+| 返回类型 | 说明 |
| -------------- | ------- |
| `ActionChains` | 动作链对象本身 |
+**示例:**
+
+```python
+ac.r_click('#div1')
+```
+
## 📍 `m_click()`
此方法用于单击鼠标中键,单击前可先移动到元素上。
-**◽ 参数:**
+| 参数名称 | 类型 | 默认值 | 说明 |
+|:--------:|:--------------------------:|:------:| -------------- |
+| `on_ele` | `ChromiumElement`
`str` | `None` | 要点击的元素对象或文本定位符 |
-| 名称 | 类型 | 默认 | 说明 |
-| -------- | ----------------------- | ------ | -------------- |
-| `on_ele` | `ChromiumElement`、`str` | `None` | 要点击的元素对象或文本定位符 |
-
-**◽ 返回:**
-
-| 类型 | 说明 |
+| 返回类型 | 说明 |
| -------------- | ------- |
| `ActionChains` | 动作链对象本身 |
+**示例:**
+
+```python
+ac.m_click('#div1')
+```
+
## 📍 `hold()`
此方法用于按住鼠标左键不放,按住前可先移动到元素上。
-**◽ 参数:**
+| 参数名称 | 类型 | 默认值 | 说明 |
+|:--------:|:--------------------------:|:------:| -------------- |
+| `on_ele` | `ChromiumElement`
`str` | `None` | 要按住的元素对象或文本定位符 |
-| 名称 | 类型 | 默认 | 说明 |
-| -------- | ----------------------- | ------ | -------------- |
-| `on_ele` | `ChromiumElement`、`str` | `None` | 要按住的元素对象或文本定位符 |
-
-**◽ 返回:**
-
-| 类型 | 说明 |
+| 返回类型 | 说明 |
| -------------- | ------- |
| `ActionChains` | 动作链对象本身 |
+**示例:**
+
+```python
+ac.hold('#div1')
+```
+
## 📍 `release()`
此方法用于释放鼠标左键,释放前可先移动到元素上。
-**◽ 参数:**
+| 参数名称 | 类型 | 默认值 | 说明 |
+|:--------:|:--------------------------:|:------:| -------------- |
+| `on_ele` | `ChromiumElement`
`str` | `None` | 要释放的元素对象或文本定位符 |
-| 名称 | 类型 | 默认 | 说明 |
-| -------- | ----------------------- | ------ | -------------- |
-| `on_ele` | `ChromiumElement`、`str` | `None` | 要释放的元素对象或文本定位符 |
-
-**◽ 返回:**
-
-| 类型 | 说明 |
+| 返回类型 | 说明 |
| -------------- | ------- |
| `ActionChains` | 动作链对象本身 |
+**示例:** 移动到某元素上然后释放鼠标左键
+
+```python
+ac.release('#div1')
+```
+
## 📍 `r_hold()`
此方法用于按住鼠标右键不放,按住前可先移动到元素上。
-**◽ 参数:**
+| 参数名称 | 类型 | 默认值 | 说明 |
+|:--------:|:--------------------------:|:------:| -------------- |
+| `on_ele` | `ChromiumElement`
`str` | `None` | 要按住的元素对象或文本定位符 |
-| 名称 | 类型 | 默认 | 说明 |
-| -------- | ----------------------- | ------ | -------------- |
-| `on_ele` | `ChromiumElement`、`str` | `None` | 要按住的元素对象或文本定位符 |
-
-**◽ 返回:**
-
-| 类型 | 说明 |
+| 返回类型 | 说明 |
| -------------- | ------- |
| `ActionChains` | 动作链对象本身 |
@@ -269,15 +265,11 @@ ac.up(50) # 鼠标向上移动 50 像素
此方法用于释放鼠标右键,释放前可先移动到元素上。
-**◽ 参数:**
+| 参数名称 | 类型 | 默认值 | 说明 |
+|:--------:|:--------------------------:|:------:| -------------- |
+| `on_ele` | `ChromiumElement`
`str` | `None` | 要释放的元素对象或文本定位符 |
-| 名称 | 类型 | 默认 | 说明 |
-| -------- | ----------------------- | ------ | -------------- |
-| `on_ele` | `ChromiumElement`、`str` | `None` | 要释放的元素对象或文本定位符 |
-
-**◽ 返回:**
-
-| 类型 | 说明 |
+| 返回类型 | 说明 |
| -------------- | ------- |
| `ActionChains` | 动作链对象本身 |
@@ -285,15 +277,11 @@ ac.up(50) # 鼠标向上移动 50 像素
此方法用于按住鼠标中键不放,按住前可先移动到元素上。
-**◽ 参数:**
+| 参数名称 | 类型 | 默认值 | 说明 |
+|:--------:|:--------------------------:|:------:| -------------- |
+| `on_ele` | `ChromiumElement`
`str` | `None` | 要按住的元素对象或文本定位符 |
-| 名称 | 类型 | 默认 | 说明 |
-| -------- | ----------------------- | ------ | -------------- |
-| `on_ele` | `ChromiumElement`、`str` | `None` | 要按住的元素对象或文本定位符 |
-
-**◽ 返回:**
-
-| 类型 | 说明 |
+| 返回类型 | 说明 |
| -------------- | ------- |
| `ActionChains` | 动作链对象本身 |
@@ -301,13 +289,9 @@ ac.up(50) # 鼠标向上移动 50 像素
此方法用于释放鼠标中键,释放前可先移动到元素上。
-**◽ 参数:**
-
-| 名称 | 类型 | 默认 | 说明 |
-| -------- | ----------------------- | ------ | -------------- |
-| `on_ele` | `ChromiumElement`、`str` | `None` | 要释放的元素对象或文本定位符 |
-
-**◽ 返回:**
+| 参数名称 | 类型 | 默认值 | 说明 |
+|:--------:|:--------------------------:|:------:| -------------- |
+| `on_ele` | `ChromiumElement`
`str` | `None` | 要释放的元素对象或文本定位符 |
| 类型 | 说明 |
| -------------- | ------- |
@@ -319,17 +303,13 @@ ac.up(50) # 鼠标向上移动 50 像素
此方法用于滚动鼠标滚轮,滚动前可先移动到元素上。
-**◽ 参数:**
+| 参数名称 | 类型 | 默认值 | 说明 |
+|:---------:|:--------------------------:|:------:| ------------------- |
+| `delta_x` | `int` | 0 | 滚轮 x 轴变化值,向右为正,向左为负 |
+| `delta_y` | `str` | 0 | 滚轮 y 轴变化值,向下为正,向上为负 |
+| `on_ele` | `ChromiumElement`
`str` | `None` | 要滚动的元素对象或文本定位符 |
-| 名称 | 类型 | 默认 | 说明 |
-| --------- | ----------------------- | ------ | ------------------- |
-| `delta_x` | `int` | 0 | 滚轮 x 轴变化值,向右为正,向左为负 |
-| `delta_y` | `str` | 0 | 滚轮 y 轴变化值,向下为正,向上为负 |
-| `on_ele` | `ChromiumElement`、`str` | `None` | 要滚动的元素对象或文本定位符 |
-
-**◽ 返回:**
-
-| 类型 | 说明 |
+| 返回类型 | 说明 |
| -------------- | ------- |
| `ActionChains` | 动作链对象本身 |
@@ -339,80 +319,78 @@ ac.up(50) # 鼠标向上移动 50 像素
此方法用于按下键盘按键,特殊字符见 Keys。
-**◽ 参数:**
-
-| 名称 | 类型 | 默认 | 说明 |
-| ----- | ----- | --- | ---- |
+| 参数名称 | 类型 | 默认值 | 说明 |
+|:-----:|:-----:|:---:| ---- |
| `key` | `str` | 无 | 按键键值 |
-**◽ 返回:**
-
-| 类型 | 说明 |
+| 返回类型 | 说明 |
| -------------- | ------- |
| `ActionChains` | 动作链对象本身 |
-**◽ 示例:**
+**示例:** 按下 ctrl 键
```python
from DrissionPage.keys import Keys
-ac.key_down(Keys.CTRL) # 按下 ctrl 键
+ac.key_down(Keys.CTRL)
```
## 📍 `key_up()`
此方法用于提起键盘按键,特殊字符见 Keys。
-**◽ 参数:**
-
-| 名称 | 类型 | 默认 | 说明 |
-| ----- | ----- | --- | ---- |
+| 参数名称 | 类型 | 默认值 | 说明 |
+|:-----:|:-----:|:---:| ---- |
| `key` | `str` | 无 | 按键键值 |
-**◽ 返回:**
-
-| 类型 | 说明 |
+| 返回类型 | 说明 |
| -------------- | ------- |
| `ActionChains` | 动作链对象本身 |
+**示例:** 提起 ctrl 键
+
+```python
+from DrissionPage.keys import Keys
+
+ac.key_up(Keys.CTRL)
+```
+
## 📍 `type()`
此方法用于输入一段文本。
-**◽ 参数:**
-
-| 名称 | 类型 | 默认 | 说明 |
-| ------ | ----- | --- | ------ |
+| 参数名称 | 类型 | 默认值 | 说明 |
+|:------:|:-----:|:---:| ------ |
| `text` | `str` | 无 | 要输入的文本 |
-**◽ 返回:**
-
-| 类型 | 说明 |
+| 返回类型 | 说明 |
| -------------- | ------- |
| `ActionChains` | 动作链对象本身 |
+**示例:**
+
+```python
+ac.type('text')
+```
+
# ✔ 等待
## 📍 `wait()`
此方法用于在动作链中插入停顿。
-**◽ 参数:**
-
-| 名称 | 类型 | 默认 | 说明 |
-| -------- | ------- | --- | ---- |
+| 参数名称 | 类型 | 默认值 | 说明 |
+|:--------:|:-------:|:---:| ---- |
| `second` | `float` | 无 | 等待秒数 |
- **◽ 返回:**
-
-| 类型 | 说明 |
+| 返回类型 | 说明 |
| -------------- | ------- |
| `ActionChains` | 动作链对象本身 |
-**◽ 示例:**
+**示例:** 停顿 3 秒
```python
-ac.wait(3) # 停顿 3 秒
+ac.wait(3)
```
# ✔ 示例
@@ -420,8 +398,7 @@ ac.wait(3) # 停顿 3 秒
## 📍 模拟输入 ctrl+a
```python
-from DrissionPage import ChromiumPage, ActionChains
-from DrissionPage.keys import Keys
+from DrissionPage import ChromiumPage, ActionChains, Keys
# 创建页面
page = ChromiumPage()
@@ -440,11 +417,18 @@ ac.type('a')
ac.key_up(Keys.CTRL)
```
+链式写法:
+
+```python
+ac.click('tag:input').key_down(Keys.CTRL).type('a').key_up(Keys.CTRL)
+```
+
## 📍 拖拽元素
+把一个元素向右拖拽 300 像素:
+
```python
from DrissionPage import ChromiumPage, ActionChains
-from DrissionPage.keys import Keys
# 创建页面
page = ChromiumPage()
@@ -458,3 +442,9 @@ ac.right(300)
# 释放左键
ac.release()
```
+
+把一个元素拖拽到另一个元素上:
+
+```python
+ac.hold('#div1').release('#div2')
+```
diff --git a/docs/WebPage使用方法/3.1创建页面对象.md b/docs/WebPage使用方法/3.1创建页面对象.md
index 1ea0304..bc43c21 100644
--- a/docs/WebPage使用方法/3.1创建页面对象.md
+++ b/docs/WebPage使用方法/3.1创建页面对象.md
@@ -43,9 +43,7 @@ page = SessionPage()
`DriverOptions`用于管理创建浏览器时的配置,内置了常用的配置,并能实现链式操作。详细使用方法见“启动配置”一节。
-**◽ 初始化参数:**
-
-| 名称 | 类型 | 默认 | 说明 |
+| 初始化参数 | 类型 | 默认值 | 说明 |
| ----------- | ------ | ------ | ------------------------ |
| `read_file` | `bool` | `True` | 是否从 ini 文件中读取配置信息 |
| `ini_path` | `str` | `None` | 文件路径,为`None`则读取默认 ini 文件 |
@@ -66,9 +64,7 @@ page = WebPage(driver_or_options=do)
`SessionOptions`用于管理创建`Session`对象时的配置,内置了常用的配置,并能实现链式操作。详细使用方法见“启动配置”一节。
-**◽ 初始化参数:**
-
-| 名称 | 类型 | 默认 | 说明 |
+| 初始化参数 | 类型 | 默认值 | 说明 |
| ----------- | ------ | ------ | ------------------------ |
| `read_file` | `bool` | `True` | 是否从 ini 文件中读取配置信息 |
| `ini_path` | `str` | `None` | 文件路径,为`None`则读取默认 ini 文件 |
@@ -77,7 +73,7 @@ page = WebPage(driver_or_options=do)
```python
# 导入 SessionOptions
-from DrissionPage import SessionPage, SessionOptions
+from DrissionPage import SessionPage, SessionOptions
proxies = {'http': 'http://127.0.0.1:1080',
'https': 'http://127.0.0.1:1080'}
@@ -121,10 +117,34 @@ page = WebPage(driver_or_options=do)
当须要使用多个页面对象共同操作一个页面时,可在对象间传递驱动器。
-```python
-from DrissionPage import WebPage
+这也可以实现多个页面对象共同控制一个浏览器。
-# 创建第一个页面
+## 📍 `ChromiumPage`传递驱动器
+
+```python
+# 创建一个页面
+page1 = ChormiumPage()
+# 获取页面对象的浏览器控制器
+driver = page1.driver
+# 把控制器对象在第二个页面对象初始化时传递进去
+page2 = ChormiumPage(driver_or_options=driver)
+```
+
+## 📍 `SessionPage`传递`Session`对象
+
+```python
+# 创建一个页面
+page1 = SessionPage()
+# 获取页面对象内置的Session对象
+session = page1.session
+# 在第二个页面对象初始化时传递该对象
+page2 = SessionPage(session_or_options=session)
+```
+
+## 📍 `WebPage`传递两种模式控制权
+
+```python
+# 创建一个页面
page1 = WebPage()
# 获取页面对象的浏览器控制器
driver = page1.driver
@@ -240,7 +260,7 @@ from DrissionPage import ChromiumPage, DriverOptions
do1 = DriverOptions().set_paths(local_port=9111)
do2 = DriverOptions().set_paths(local_port=9222)
-page1 = ChromiumPage(driver_or_options=do1)
+page1 = ChromiumPage(addr_driver_opts=do1)
page2 = ChromiumPage(driver_or_options=do2)
```
@@ -250,38 +270,32 @@ page2 = ChromiumPage(driver_or_options=do2)
`ChroumiumPage`对象纯粹用于操作浏览器,不能切换模式。一个该对象对应的是浏览器上一个标签页。
-**◽ 初始化参数:**
-
-| 名称 | 类型 | 默认 | 说明 |
-| ------------------ | -------------------------------------- | ------ | ----------------------------------------------------------------------------------------------------- |
-| `addr_driver_opts` | `str`、`ChromiumDriver`、`DriverOptions` | `None` | 浏览器启动配置或接管信息;传入' ip:port' 字符串或`ChromiumDriver`时接管浏览器,传入`DriverOptions`时按配置启动浏览器,为`None`时使用配置文件配置启动浏览器 |
-| `tab_id` | `str` | `None` | 要控制的标签页id,用于 d 模式,为`None`则控制激活的标签页 |
-| `timeout` | `float` | `None` | 整体超时时间,为`None`则从配置文件中读取 |
+| 初始化参数 | 类型 | 默认值 | 说明 |
+| ------------------ | -------------------------------------------- | ------ | ----------------------------------------------------------------------------------------------------- |
+| `addr_driver_opts` | `str`
`ChromiumDriver`
`DriverOptions` | `None` | 浏览器启动配置或接管信息。传入' ip:port' 字符串或`ChromiumDriver`时接管浏览器;传入`DriverOptions`时按配置启动浏览器;为`None`时使用配置文件配置启动浏览器 |
+| `tab_id` | `str` | `None` | 要控制的标签页id,用于 d 模式,为`None`则控制激活的标签页 |
+| `timeout` | `float` | `None` | 整体超时时间,为`None`则从配置文件中读取 |
## 📍 `SessionPage`
`SessionPage`对象纯粹用于收发数据包,不能切换模式,产生的元素对象为`SessionElement`。
-**◽ 初始化参数:**
-
-| 名称 | 类型 | 默认 | 说明 |
-| -------------------- | -------------------------- | ------ | --------------------------------------------------------------- |
-| `session_or_options` | `Session`、`SessionOptions` | `None` | 传入`Session`对象时使用该对象收发数据包;传入`SessionOptions`对象时用该配置创建`Session`对象 |
-| `timeout` | `float` | `None` | 连接超时时间, |
+| 初始化参数 | 类型 | 默认值 | 说明 |
+| -------------------- | ----------------------------- | ------ | --------------------------------------------------------------- |
+| `session_or_options` | `Session`
`SessionOptions` | `None` | 传入`Session`对象时使用该对象收发数据包;传入`SessionOptions`对象时用该配置创建`Session`对象 |
+| `timeout` | `float` | `None` | 连接超时时间,为`None`则从配置文件中读取 |
## 📍 `WebPage`
`WebPage`对象封装了常用的网页操作,并实现在浏览器和 requests 两种模式之间的切换。
-**◽ 初始化参数:**
-
-| 名称 | 类型 | 默认 | 说明 |
-| -------------------- | --------------------------------------- | ------ | ---------------------------------------------------------------- |
-| `mode` | `str` | `'d'` | 启动时的模式,只能传入`'d'`或`'s'` |
-| `timeout` | `float` | `None` | 整体超时时间,为`None`则从配置文件中读取 |
-| `tab_id` | `str` | `None` | 要控制的标签页id,用于 d 模式,为`None`则控制激活的标签页 |
-| `driver_or_options` | `ChromiumDriver`、`DriverOptions`、`bool` | `None` | 浏览器控制对象或浏览器启动配置对象;为`None`时使用 ini 文件配置;为`False`时不读取 ini 文件。 |
-| `session_or_options` | `Session`、`SessionOptions`、`bool` | `None` | 收发数据包对象或`Session`启动配置对象;为`None`时使用 ini 文件配置;为`False`时不读取 ini 文件。 |
+| 初始化参数 | 类型 | 默认值 | 说明 |
+| -------------------- | --------------------------------------------- | ------ | ---------------------------------------------------------------- |
+| `mode` | `str` | `'d'` | 启动时的模式,只能传入`'d'`或`'s'` |
+| `timeout` | `float` | `None` | 整体超时时间,为`None`则从配置文件中读取 |
+| `tab_id` | `str` | `None` | 要控制的标签页id,用于 d 模式,为`None`则控制激活的标签页 |
+| `driver_or_options` | `ChromiumDriver`
`DriverOptions`
`bool` | `None` | 浏览器控制对象或浏览器启动配置对象;为`None`时使用 ini 文件配置;为`False`时不读取 ini 文件。 |
+| `session_or_options` | `Session`
`SessionOptions`
`bool` | `None` | 收发数据包对象或`Session`启动配置对象;为`None`时使用 ini 文件配置;为`False`时不读取 ini 文件。 |
**◽ 说明:**
diff --git a/docs/WebPage使用方法/下载文件.md b/docs/WebPage使用方法/下载文件.md
new file mode 100644
index 0000000..98f9289
--- /dev/null
+++ b/docs/WebPage使用方法/下载文件.md
@@ -0,0 +1,429 @@
+浏览器没有为下载功能提供方便的程序接口,难以实现有效的下载管理,如检测下载状态、重命名、失败管理等。使用 requests 下载文件能较好实现以上功能,但代码较为繁琐。
+因此 DrissionPage 内置了高效可靠的下载工具,提供任务管理、多线程、大文件分块、自动重连、文件名冲突处理等功能。
+
+无论是控制浏览器,还是收发数据包的场景,都可以使用它。甚至可以拦截浏览器的下载动作,转用内置下载器进行下载。使用方式简洁高效。
+
+?> 该工具名为 DownloadKit,现已独立打包成一个库,详细用法见:[DownloadKit](https://gitee.com/g1879/DownloadKit)。这里只介绍和页面对象有关的用法。
+
+# ✔️ 功能简介
+
+`SessionPage`、`ChromiumPage`、`WebPage`都可以使用`download()`方法进行下载,还可以使用`download_set`属性对下载参数进行配置。内置下载器功能如下:
+
+- 支持多线程同时下载多个文件
+- 大文件自动分块使用多线程下载
+- 可拦截浏览器下载动作,自动调用下载器下载
+- 自动创建目标路径
+- 自动去除路径中的非法字符
+- 下载时支持文件重命名
+- 自动处理文件名冲突
+- 自动去除文件名非法字符
+- 支持 post 方式
+- 支持自定义连接参数
+- 任务失败自动重试
+
+# ✔️ 简单示例
+
+下载一个文件(单线程):
+
+```python
+page.download('https://xxxxxx/file.pdf')
+```
+
+添加下载任务,以多线程方式下载:
+
+```python
+page.download.add('https://xxxxxx/file.pdf')
+```
+
+拦截浏览器下载动作,改用 DwonloadKit 下载:
+
+```python
+page.download_set.by_DownloadKit()
+page('#download_btn').click()
+```
+
+下载设置:
+
+```python
+# 设置默认保存路径
+page.download_set.save_path('...')
+# 设置存在同名文件时处理方式
+page.download_set.if_file_exists.skip()
+# 设置使用浏览器或DownloadKit下载
+page.download_set.by_DownloadKit()
+page.download_set.by_browser()
+# 设置使用DownloadKit下载时是否允许多线程同时下载一个文件
+page.download_set.split(True)
+```
+
+# ✔️ 单线程下载
+
+直接调用页面对象的`download()`方法,可下载一个文件,该方法是阻塞式的,会等待下载完成再往下操作。下载时默认打印下载进度。
+
+### 🔸 `download()`
+
+| 参数名称 | 类型 | 默认值 | 说明 |
+|:-------------:|:---------------:|:------:| ------------------------------------------------ |
+| `file_url` | `str` | 无 | 文件网址 |
+| `goal_path` | `str`
`Path` | `None` | 保存文件夹路径,为`None`则保存在当前目录 |
+| `rename` | `str` | `None` | 重命名文件名,可不包含后缀 |
+| `file_exists` | `str` | `None` | 遇到同名文件时的处理方式,可选`'skip'`、`'overwrite'`、`'rename'` |
+| `data` | `str`
`dict` | `None` | post 方式使用的数据,如不为`None`,使用 post 方式发送请求 |
+| `show_msg` | `bool` | `True` | 是否显示下载进度 |
+| `**kwargs` | - | 无 | requests的`get()`方法参数 |
+
+| 返回类型 | 返回格式 | 说明 |
+|:-------:|:------------:| ------------------- |
+| `tuple` | (任务结果, 任务信息) | 返回任务结果和信息组成的`tuple` |
+
+任务结果可能出现以下值:
+
+- `'success'`:表示下载成功
+
+- `'skip'`:表示存在同名文件,跳过任务
+
+- `'cancel'`:表示任务下载途中被取消
+
+- `False`:表示下载失败
+
+任务信息成功时返回文件绝对路径,其它情况返回相应说明。
+
+**示例:**
+
+```python
+from DrissionPage import WebPage
+
+page = WebPage('s')
+# 文件 url
+url = 'https://www.baidu.com/img/flexible/logo/pc/result.png'
+# 存放路径
+save_path = r'C:\download'
+
+# 重命名为img.png,存在重名时自动在文件名末尾加上序号,显示下载进度
+res = page.download(url, save_path, 'img', 'rename', show_msg=True)
+# 打印结果
+print(res)
+```
+
+显示:
+
+```shell
+url:https://www.baidu.com/img/flexible/logo/pc/result.png
+文件名:img.png
+目标路径:C:\download
+100% 下载完成 C:\download\img.png
+
+('success', 'C:\\download\\img.png')
+```
+
+# ✔️ 多线程并发下载
+
+您可以添加数量不限的下载任务,程序会自动调配线程去完成这些任务。
+
+默认设置下,页面对象最多使用 10 个下载线程,如进程已满,新任务会进入等待队列排队,待有空线程时自动开始。
+
+添加多线程任务的方法是调用页面对象`donwload`属性的`add()`方法。
+
+### 🔸 `download.add()`
+
+| 参数名称 | 类型 | 默认值 | 说明 |
+|:-------------:|:---------------:|:------:| ----------------------------------------------------------------- |
+| `file_url` | `str` | 无 | 文件网址 |
+| `goal_path` | `str`
`Path` | `None` | 保存文件夹路径,为`None`则保存在当前目录 |
+| `rename` | `str` | `None` | 重命名文件名,可不包含后缀 |
+| `file_exists` | `str` | `None` | 遇到同名文件时的处理方式,可选`'skip'`、`'overwrite'`、`'rename'` |
+| `data` | `str`
`dict` | `None` | post 方式使用的数据,如不为`None`,使用 post 方式发送请求 |
+| `split` | `bool` | `None` | 是否允许多线程分块下载,为`None`则使用下载器内置设置,默认为`True`
默认大于 50MB 的文件使用多线程分块下载 |
+| `**kwargs` | - | 无 | requests的`get()`方法参数 |
+
+| 返回类型 | 说明 |
+|:---------:| ---------------------------------------------------------------------------- |
+| `Mission` | 返回任务对象,任务对象具体属性及方法详见 [DownloadKit](https://gitee.com/g1879/DownloadKit) 相关说明 |
+
+**示例:**
+
+```python
+from DrissionPage import WebPage
+
+page = WebPage('s')
+# 文件 url
+url = 'https://www.baidu.com/img/flexible/logo/pc/result.png'
+# 存放路径
+save_path = r'C:\download'
+
+# 返回一个任务对象
+mission = page.download.add(url, save_path)
+
+# 通过任务对象查看状态
+print(mission.rate, mission.info)
+```
+
+输出:
+
+```shell
+90% '下载中'
+```
+
+# ✔️ 接管浏览器下载任务
+
+## 📍 切换下载方式
+
+很多时候,网站会用某些非显式的方式触发浏览器下载,因此不能很好地获取文件 url,下载依赖浏览器功能。,页面对象可以设置用`DownloadKit`拦截浏览器的下载任务,使下载更快,下载过程更可控。
+
+方法是使用`download_set.by_DownloadKit()`方法,指定使用`DownloadKit`接管浏览器的下载动作。
+
+```python
+page.download_set.by_DownloadKit()
+```
+
+事实上,页面对象创建时就默认开启了此功能,如果想用浏览器本身的下载功能,可以这样写:
+
+```python
+page.download_set.by_browser()
+```
+
+!>**注意:**
接管浏览器下载任务后会使用 get 方式下载,如果是需要 post 的请求,可能不能正确下载。
+
+## 📍 等待下载开始
+
+在浏览器中点击下载按钮后,有时下载不会立即触发,这时如果过快进行其它操作,可能导致一些意想不到的问题。因此设计了`wait_download_begin()`
+方法,用于等待下载动作的开始,以便正确接管。可控制浏览器的页面对象`ChromiumPage`和`WebPage`拥有此方法。
+
+### 🔸 `wait_download_begin()`
+
+此方法会阻塞程序,等待下载动作触发。如到达超时时间仍未触发,则返回`False`。
+
+| 参数名称 | 类型 | 默认值 | 说明 |
+|:---------:|:----------------:|:------:| ------------------------------------- |
+| `timeout` | `int`
`float` | `None` | 等待下载开始的超时时间,为`None`则使用页面对象`timeout`属性 |
+
+| 返回类型 | 说明 |
+| ------ | -------- |
+| `bool` | 是否等到下载开始 |
+
+**示例:**
+
+```python
+page('#download_btn').click()
+page.wait_download_begin()
+```
+
+# ✔️ 查看任务信息
+
+用单线程方式下载,会阻塞程序直到下载完成,因此无须查看任务信息。
+
+用多线程或接管浏览器下载任务的方式下载,可用以下方式查看任务信息。
+
+## 📍 获取单个任务对象
+
+使用`download.add()`
+添加任务时,会返回一个任务对象,后续程序可以使用该对象查询该任务下载进度、结果,也可以取消任务。这里不对该对象作详细说明,详情请移步:[DownloadKit](https://gitee.com/g1879/DownloadKit)。
+
+**示例:**
+
+```python
+mission = page.download.add('http://xxxx.pdf')
+print(mission.id) # 获取任务id
+print(mission.rate) # 打印下载进度(百分比)
+print(mission.state) # 打印任务状态,'waiting'、'running'、'done'
+print(mission.info) # 打印任务信息
+print(mission.result) # 打印任务结果,'success'表示成功,False表示失败,'skip'表示跳过,'cancel'表示取消
+```
+
+除添加任务时获取对象,也可以使用`download.get_mission()`获取。在上一个示例中可以看到,任务对象有`id`属性,把任务的`id`传入此方法,会返回该任务对象。
+
+**示例:**
+
+```python
+mission_id = mission.id
+mission = page.download.get_mission(mission_id)
+```
+
+## 📍 获取全部任务对象
+
+使用页面对象的`download.missions`属性,可以获取所有下载任务。该属性返回一个`dict`,保存了所有下载任务。以任务对象的`id`为 key。
+
+```python
+page.download_set.save_path(r'D:\download')
+page.download('http://xxxxx/xxx1.pdf')
+page.download('http://xxxxx/xxx1.pdf')
+print(page.download.missions)
+```
+
+输出:
+
+```
+{
+ 1:
+ 2:
+ ...
+}
+```
+
+## 📍 获取下载失败的任务
+
+使用`download.get_failed_missions()`方法,可以获取下载失败的任务列表。
+
+```python
+page.download_set.save_path(r'D:\download')
+page.download('http://xxxxx/xxx1.pdf')
+page.download('http://xxxxx/xxx1.pdf')
+print(page.download.get_failed_missions()
+```
+
+输出:
+
+```
+[
+ ,
+
+ ...
+]
+```
+
+?>**Tips:**
获取失败任务对象后,可从其`data`属性读取任务内容,以便记录日志或择机重试。
+
+# ✔️ 下载设置
+
+主要的下载设置使用`download_set`内置方法进行,更多运行参数使用`download`属性的子属性进行。
+
+## 📍 设置文件保存路径
+
+### 🔸 `download_set.save_path()`
+
+此方法用于设置文件下载默认保存路径。
+
+| 参数名称 | 类型 | 默认值 | 说明 |
+|:------:|:---------------:|:---:| ------------------ |
+| `path` | `str`
`Path` | 无 | 文件保存路径,绝对路径和相对路径均可 |
+
+**返回:**`None`
+
+**示例:**
+
+```python
+page.download_set.save_path(r'D:\tmp')
+```
+
+?>**Tips:**
- 保存路径可指定不存在的文件夹,程序会自动创建。
- 设置默认保存路径后,每个任务仍可在创建时指定自己的保存路径,以覆盖默认设置。
+
+## 📍 设置下载方式
+
+### 🔸 `download_set.by_DownloadKit()`
+
+此方法用于设置当前页面对象使用`DownloadKit`下载文件。
+
+### 🔸 `download_set.by_browser()`
+
+此方法用于设置当前页面对象使用浏览器下载工具下载文件。
+
+## 📍 设置重名文件处理方法
+
+下载过程中可能遇到保存路径已存在同名文件,`DownloadKit`提供 3 种处理方法。
+
+!>**注意:**
这个设置只有在使用`DownloadKit`作为下载工具时有效。
+
+### 🔸 `download_set.if_file_exists.rename()`
+
+此方式会对新文件进行重命名,在文件名后加上序号。
+
+假如,保存路径已存在`abc.txt`文件,新的`abc.txt`文件会自动重命名为`abc_1.txt`,再下载一个`abc.txt`时,会命名为`abc_2.txt`,如此类推。
+
+**示例:** 3 次下载同一个文件
+
+```python
+page.download_set.if_file_exists.rename()
+page.download('http://xxxxx/xxx.pdf')
+page.download('http://xxxxx/xxx.pdf')
+page.download('http://xxxxx/xxx.pdf')
+```
+
+在文件夹会生成如下 3 个文件:
+
+```
+xxx.pdf
+xxx_1.pdf
+xxx_2.pdf
+```
+
+### 🔸 `download_set.if_file_exists.skip()`
+
+遇到同名文件时,跳过。同时任务对象的`result`属性设置为`'skip'`。
+
+**示例:** 3 次下载同一个文件
+
+```python
+page.download_set.if_file_exists.skip()
+page.download('http://xxxxx/xxx.pdf')
+page.download('http://xxxxx/xxx.pdf')
+page.download('http://xxxxx/xxx.pdf')
+```
+
+在文件夹只会生成如下 1 个文件:
+
+```
+xxx.pdf
+```
+
+### 🔸 `download_set.if_file_exists.overwrite()`
+
+遇到同名文件时,覆盖。
+
+!>**注意:**
这个方式在多线程下载时要慎用,万一多个任务下载多个同名文件,会导致互相覆盖的现象。
+
+?>**Tips:**
除了整体设置,还可以在创建任务时单独设置该任务的处理方式。
+
+?>**Tips:**
文件名如遇到`'?'`、`'\'`等非法字符,会自动替换为空格。
+
+## 📍 设置大文件是否分块
+
+`DownloadKit`具备多线程下载大文件功能,在文件超过指定大小时(默认 50MB),可对文件进行多线程分块下载,每个线程负责 50MB 的下载,以提高下载速度。这个功能默认是关闭的,您可以设置是否开启。
+
+!>**注意:**
+这个设置只有在使用`DownloadKit`作为下载工具时有效。
+
+### 🔸 `download_set.split()`
+
+```python
+# 使用分块下载
+page.download_set.split(on_off=True)
+# 禁用分块下载
+page.download_set.split(on_off=False)
+```
+
+?>**Tips:**
+除了整体设置,还可以在创建任务时单独设置该任务是否使用分块下载。
+
+## 📍运行参数设置
+
+运行参数主要包括可使用线程上限、连接失败重试次数、重试间隔。
+
+### 🔸 `download.roads`
+
+此参数设置整个`DownloadKit`对象允许使用的线程数上限,默认为 10。
+
+默认设置下,页面对象最多使用 10 个下载线程,如进程已满,新任务会进入等待队列排队,待有空线程时自动开始。
+
+这个属性只能在没有任务在运行的时候设置。
+
+```python
+page.download.roads = 20 # 允许最多使用20个线程进行下载
+```
+
+### 🔸 `download.retry`
+
+此属性用于设置连接失败时重试次数,默认为 3。
+
+```python
+page.download.roads = 5 # 设置连接失败时重试5次
+```
+
+### 🔸 `download.interval`
+
+此属性用于设置连接失败时重试间隔,默认为 5 秒。
+
+```python
+page.download.interval = 10 # 设置连接失败时等待10秒再重试
+```
+
+?> **Tips:**
重试次数和间隔在初始化时继承页面对象的`retry_times`和`retry_interval`属性,可用上面例子的方法对下载的重试次数和间隔进行设置,设置后不会影响页面对象的设置。
diff --git a/docs/_sidebar.md b/docs/_sidebar.md
index c9bc7ca..47faefd 100644
--- a/docs/_sidebar.md
+++ b/docs/_sidebar.md
@@ -33,6 +33,7 @@
* [🔨 4.8 标签页操作](WebPage使用方法\3.8标签页操作.md)
* [🔨 4.9 iframe操作](WebPage使用方法\3.9iframe操作.md)
* [🔨 4.10 动作链](WebPage使用方法\3.10动作链.md)
+ * [🔨 4.11 下载文件](WebPage使用方法\下载文件.md)
* [📝 5 启动配置](#)
diff --git a/docs/index.html b/docs/index.html
index 053e538..ea06810 100644
--- a/docs/index.html
+++ b/docs/index.html
@@ -8,6 +8,7 @@
+
diff --git a/docs/scripts/theme-simple-dark.css b/docs/scripts/theme-simple-dark.css
index 4bd9fec..43128f8 100644
--- a/docs/scripts/theme-simple-dark.css
+++ b/docs/scripts/theme-simple-dark.css
@@ -1,2 +1,6 @@
-.github-corner{position:absolute;z-index:40;top:0;right:0;border-bottom:0;text-decoration:none}.github-corner svg{height:70px;width:70px;fill:var(--theme-color);color:var(--base-background-color)}.github-corner:hover .octo-arm{-webkit-animation:octocat-wave 560ms ease-in-out;animation:octocat-wave 560ms ease-in-out}@-webkit-keyframes octocat-wave{0%,100%{transform:rotate(0)}20%,60%{transform:rotate(-25deg)}40%,80%{transform:rotate(10deg)}}@keyframes octocat-wave{0%,100%{transform:rotate(0)}20%,60%{transform:rotate(-25deg)}40%,80%{transform:rotate(10deg)}}.progress{position:fixed;z-index:2147483647;top:0;left:0;right:0;height:3px;width:0;background-color:var(--theme-color);transition:width var(--duration-fast),opacity calc(var(--duration-fast) * 2)}body.ready-transition:after,body.ready-transition>*:not(.progress){opacity:0;transition:opacity var(--spinner-transition-duration)}body.ready-transition:after{content:'';position:absolute;z-index:1000;top:calc(50% - (var(--spinner-size) / 2));left:calc(50% - (var(--spinner-size) / 2));height:var(--spinner-size);width:var(--spinner-size);border:var(--spinner-track-width, 0) solid var(--spinner-track-color);border-left-color:var(--theme-color);border-left-color:var(--theme-color);border-radius:50%;-webkit-animation:spinner var(--duration-slow) infinite linear;animation:spinner var(--duration-slow) infinite linear}body.ready-transition.ready-spinner:after{opacity:1}body.ready-transition.ready-fix:after{opacity:0}body.ready-transition.ready-fix>*:not(.progress){opacity:1;transition-delay:var(--spinner-transition-duration)}@-webkit-keyframes spinner{0%{transform:rotate(0deg)}100%{transform:rotate(360deg)}}@keyframes spinner{0%{transform:rotate(0deg)}100%{transform:rotate(360deg)}}*,*:before,*:after{box-sizing:inherit;font-size:inherit;-webkit-overflow-scrolling:touch;-webkit-tap-highlight-color:rgba(0,0,0,0);-webkit-text-size-adjust:none;-webkit-touch-callout:none}:root{box-sizing:border-box;background-color:var(--base-background-color);font-size:var(--base-font-size);font-weight:var(--base-font-weight);line-height:var(--base-line-height);letter-spacing:var(--base-letter-spacing);color:var(--base-color);-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;font-smoothing:antialiased}html,button,input,optgroup,select,textarea{font-family:var(--base-font-family)}button,input,optgroup,select,textarea{font-size:100%;margin:0}a{text-decoration:none;-webkit-text-decoration-skip:ink;text-decoration-skip-ink:auto}body{margin:0}hr{height:0;margin:2em 0;border:none;border-bottom:var(--hr-border, 0)}img{max-width:100%;border:0}main{display:block}main.hidden{display:none}mark{background:var(--mark-background);color:var(--mark-color)}pre{font-family:var(--pre-font-family);font-size:var(--pre-font-size);font-weight:var(--pre-font-weight);line-height:var(--pre-line-height)}small{display:inline-block;font-size:var(--small-font-size)}strong{font-weight:var(--strong-font-weight);color:var(--strong-color, currentColor)}sub,sup{font-size:var(--subsup-font-size);line-height:0;position:relative;vertical-align:baseline}sub{bottom:-0.25em}sup{top:-0.5em}body:not([data-platform^="Mac"]) *{scrollbar-color:hsla(var(--mono-hue), var(--mono-saturation), 50%, 0.3) hsla(var(--mono-hue), var(--mono-saturation), 50%, 0.1);scrollbar-width:thin}body:not([data-platform^="Mac"]) * ::-webkit-scrollbar{width:5px;height:5px}body:not([data-platform^="Mac"]) * ::-webkit-scrollbar-thumb{background:hsla(var(--mono-hue), var(--mono-saturation), 50%, 0.3)}body:not([data-platform^="Mac"]) * ::-webkit-scrollbar-track{background:hsla(var(--mono-hue), var(--mono-saturation), 50%, 0.1)}::-moz-selection{background:var(--selection-color)}::selection{background:var(--selection-color)}.emoji{height:var(--emoji-size);vertical-align:middle}.task-list-item{list-style:none}.task-list-item input{margin-right:0.5em;margin-left:0;vertical-align:0.075em}.markdown-section code[class*="lang-"],.markdown-section pre[data-lang]{font-family:var(--code-font-family);font-size:var(--code-font-size);font-weight:var(--code-font-weight);letter-spacing:normal;line-height:var(--code-block-line-height);-moz-tab-size:var(--code-tab-size);-o-tab-size:var(--code-tab-size);tab-size:var(--code-tab-size);text-align:left;white-space:pre;word-spacing:normal;word-wrap:normal;word-break:normal;-webkit-hyphens:none;-ms-hyphens:none;hyphens:none}.markdown-section pre[data-lang]{position:relative;overflow:hidden;margin:var(--code-block-margin);padding:0;border-radius:var(--code-block-border-radius)}.markdown-section pre[data-lang]::after{content:attr(data-lang);position:absolute;top:0.75em;right:0.75em;opacity:0.6;color:inherit;font-size:var(--font-size-s);line-height:1}.markdown-section pre[data-lang] code{display:block;overflow:auto;padding:var(--code-block-padding)}code[class*="lang-"],pre[data-lang]{color:var(--code-theme-text)}pre[data-lang]::-moz-selection,pre[data-lang] ::-moz-selection,code[class*="lang-"]::-moz-selection,code[class*="lang-"] ::-moz-selection{background:var(--code-theme-selection, var(--selection-color))}pre[data-lang]::-moz-selection, pre[data-lang] ::-moz-selection, code[class*="lang-"]::-moz-selection, code[class*="lang-"] ::-moz-selection{background:var(--code-theme-selection, var(--selection-color))}pre[data-lang]::selection,pre[data-lang] ::selection,code[class*="lang-"]::selection,code[class*="lang-"] ::selection{background:var(--code-theme-selection, var(--selection-color))}:not(pre)>code[class*="lang-"],pre[data-lang]{background:var(--code-theme-background)}.namespace{opacity:0.7}.token.comment,.token.prolog,.token.doctype,.token.cdata{color:var(--code-theme-comment)}.token.punctuation{color:var(--code-theme-punctuation)}.token.property,.token.tag,.token.boolean,.token.number,.token.constant,.token.symbol,.token.deleted{color:var(--code-theme-tag)}.token.selector,.token.attr-name,.token.string,.token.char,.token.builtin,.token.inserted{color:var(--code-theme-selector)}.token.operator,.token.entity,.token.url,.language-css .token.string,.style .token.string{color:var(--code-theme-operator)}.token.atrule,.token.attr-value,.token.keyword{color:var(--code-theme-keyword)}.token.function{color:var(--code-theme-function)}.token.regex,.token.important,.token.variable{color:var(--code-theme-variable)}.token.important,.token.bold{font-weight:bold}.token.italic{font-style:italic}.token.entity{cursor:help}.markdown-section{position:relative;max-width:var(--content-max-width);margin:0 auto;padding:2rem 45px}.app-nav:not(:empty) ~ main .markdown-section{padding-top:3.5rem}.markdown-section figure,.markdown-section p,.markdown-section ol,.markdown-section ul{margin:1em 0}.markdown-section ol,.markdown-section ul{padding-left:1.5rem}.markdown-section ol ol,.markdown-section ol ul,.markdown-section ul ol,.markdown-section ul ul{margin-top:0.15rem;margin-bottom:0.15rem}.markdown-section a{border-bottom:var(--link-border-bottom);color:var(--link-color);-webkit-text-decoration:var(--link-text-decoration);text-decoration:var(--link-text-decoration);-webkit-text-decoration-color:var(--link-text-decoration-color);text-decoration-color:var(--link-text-decoration-color)}.markdown-section a:hover{border-bottom:var(--link-border-bottom--hover, var(--link-border-bottom, 0));color:var(--link-color--hover, var(--link-color));-webkit-text-decoration:var(--link-text-decoration--hover, var(--link-text-decoration));text-decoration:var(--link-text-decoration--hover, var(--link-text-decoration));-webkit-text-decoration-color:var(--link-text-decoration-color--hover, var(--link-text-decoration-color));text-decoration-color:var(--link-text-decoration-color--hover, var(--link-text-decoration-color))}.markdown-section a.anchor{border-bottom:0;color:inherit;text-decoration:none}.markdown-section a.anchor:hover{text-decoration:underline}.markdown-section blockquote{overflow:visible;margin:2em 0;padding:1.5em;border-width:var(--blockquote-border-width, 0);border-style:var(--blockquote-border-style);border-color:var(--blockquote-border-color);border-radius:var(--blockquote-border-radius);background:var(--blockquote-background);color:var(--blockquote-color);font-family:var(--blockquote-font-family);font-size:var(--blockquote-font-size);font-style:var(--blockquote-font-style);font-weight:var(--blockquote-font-weight);quotes:"“" "”" "‘" "’"}.markdown-section blockquote em{font-family:var(--blockquote-em-font-family);font-size:var(--blockquote-em-font-size);font-style:var(--blockquote-em-font-style);font-weight:var(--blockquote-em-font-weight)}.markdown-section blockquote p:first-child{margin-top:0}.markdown-section blockquote p:first-child:before,.markdown-section blockquote p:first-child:after{color:var(--blockquote-quotes-color);font-family:var(--blockquote-quotes-font-family);font-size:var(--blockquote-quotes-font-size);line-height:0}.markdown-section blockquote p:first-child:before{content:var(--blockquote-quotes-open);margin-right:0.15em;vertical-align:-0.45em}.markdown-section blockquote p:first-child:after{content:var(--blockquote-quotes-close);margin-left:0.15em;vertical-align:-0.55em}.markdown-section blockquote p:last-child{margin-bottom:0}.markdown-section code{font-family:var(--code-font-family);font-size:var(--code-font-size);font-weight:var(--code-font-weight);line-height:inherit}.markdown-section code:not([class*="lang-"]):not([class*="language-"]){margin:var(--code-inline-margin);padding:var(--code-inline-padding);border-radius:var(--code-inline-border-radius);background:var(--code-inline-background);color:var(--code-inline-color, currentColor);white-space:nowrap}.markdown-section h1:first-child,.markdown-section h2:first-child,.markdown-section h3:first-child,.markdown-section h4:first-child,.markdown-section h5:first-child,.markdown-section h6:first-child{margin-top:0}.markdown-section h1 a[data-id],.markdown-section h2 a[data-id],.markdown-section h3 a[data-id],.markdown-section h4 a[data-id],.markdown-section h5 a[data-id],.markdown-section h6 a[data-id]{display:inline-block}.markdown-section h1 code,.markdown-section h2 code,.markdown-section h3 code,.markdown-section h4 code,.markdown-section h5 code,.markdown-section h6 code{font-size:0.875em}.markdown-section h1+h2,.markdown-section h1+h3,.markdown-section h1+h4,.markdown-section h1+h5,.markdown-section h1+h6,.markdown-section h2+h3,.markdown-section h2+h4,.markdown-section h2+h5,.markdown-section h2+h6,.markdown-section h3+h4,.markdown-section h3+h5,.markdown-section h3+h6,.markdown-section h4+h5,.markdown-section h4+h6,.markdown-section h5+h6{margin-top:1rem}.markdown-section h1{margin:var(--heading-h1-margin, var(--heading-margin));padding:var(--heading-h1-padding, var(--heading-padding));border-width:var(--heading-h1-border-width, 0);border-style:var(--heading-h1-border-style);border-color:var(--heading-h1-border-color);font-family:var(--heading-h1-font-family, var(--heading-font-family));font-size:var(--heading-h1-font-size);font-weight:var(--heading-h1-font-weight, var(--heading-font-weight));line-height:var(--base-line-height);color:var(--heading-h1-color, var(--heading-color))}.markdown-section h2{margin:var(--heading-h2-margin, var(--heading-margin));padding:var(--heading-h2-padding, var(--heading-padding));border-width:var(--heading-h2-border-width, 0);border-style:var(--heading-h2-border-style);border-color:var(--heading-h2-border-color);font-family:var(--heading-h2-font-family, var(--heading-font-family));font-size:var(--heading-h2-font-size);font-weight:var(--heading-h2-font-weight, var(--heading-font-weight));line-height:var(--base-line-height);color:var(--heading-h2-color, var(--heading-color))}.markdown-section h3{margin:var(--heading-h3-margin, var(--heading-margin));padding:var(--heading-h3-padding, var(--heading-padding));border-width:var(--heading-h3-border-width, 0);border-style:var(--heading-h3-border-style);border-color:var(--heading-h3-border-color);font-family:var(--heading-h3-font-family, var(--heading-font-family));font-size:var(--heading-h3-font-size);font-weight:var(--heading-h3-font-weight, var(--heading-font-weight));color:var(--heading-h3-color, var(--heading-color))}.markdown-section h4{margin:var(--heading-h4-margin, var(--heading-margin));padding:var(--heading-h4-padding, var(--heading-padding));border-width:var(--heading-h4-border-width, 0);border-style:var(--heading-h4-border-style);border-color:var(--heading-h4-border-color);font-family:var(--heading-h4-font-family, var(--heading-font-family));font-size:var(--heading-h4-font-size);font-weight:var(--heading-h4-font-weight, var(--heading-font-weight));color:var(--heading-h4-color, var(--heading-color))}.markdown-section h5{margin:var(--heading-h5-margin, var(--heading-margin));padding:var(--heading-h5-padding, var(--heading-padding));border-width:var(--heading-h5-border-width, 0);border-style:var(--heading-h5-border-style);border-color:var(--heading-h5-border-color);font-family:var(--heading-h5-font-family, var(--heading-font-family));font-size:var(--heading-h5-font-size);font-weight:var(--heading-h5-font-weight, var(--heading-font-weight));color:var(--heading-h5-color, var(--heading-color))}.markdown-section h6{margin:var(--heading-h6-margin, var(--heading-margin));padding:var(--heading-h6-padding, var(--heading-padding));border-width:var(--heading-h6-border-width, 0);border-style:var(--heading-h6-border-style);border-color:var(--heading-h6-border-color);font-family:var(--heading-h6-font-family, var(--heading-font-family));font-size:var(--heading-h6-font-size);font-weight:var(--heading-h6-font-weight, var(--heading-font-weight));color:var(--heading-h6-color, var(--heading-color))}.markdown-section iframe{margin:1em 0}.markdown-section img{max-width:100%}.markdown-section kbd{display:inline-block;min-width:var(--kbd-min-width);margin:var(--kbd-margin);padding:var(--kbd-padding);border:var(--kbd-border);border-radius:var(--kbd-border-radius);background:var(--kbd-background);font-family:inherit;font-size:var(--kbd-font-size);text-align:center;letter-spacing:0;line-height:1;color:var(--kbd-color)}.markdown-section kbd+kbd{margin-left:-0.15em}.markdown-section table{display:block;overflow:auto;margin:1rem 0;border-spacing:0;border-collapse:collapse}.markdown-section th,.markdown-section td{padding:var(--table-cell-padding)}.markdown-section th:not([align]){text-align:left}.markdown-section thead{border-color:var(--table-head-border-color);border-style:solid;border-width:var(--table-head-border-width, 0);background:var(--table-head-background)}.markdown-section th{font-weight:var(--table-head-font-weight);color:var(--strong-color)}.markdown-section td{border-color:var(--table-cell-border-color);border-style:solid;border-width:var(--table-cell-border-width, 0)}.markdown-section tbody{border-color:var(--table-body-border-color);border-style:solid;border-width:var(--table-body-border-width, 0)}.markdown-section tbody tr:nth-child(odd){background:var(--table-row-odd-background)}.markdown-section tbody tr:nth-child(even){background:var(--table-row-even-background)}.markdown-section>ul .task-list-item{margin-left:-1.25em}.markdown-section>ul .task-list-item .task-list-item{margin-left:0}.markdown-section .table-wrapper{overflow-x:auto}.markdown-section .table-wrapper table{display:table;width:100%}.markdown-section .table-wrapper td::before{display:none}@media (max-width: 30em){.markdown-section .table-wrapper tbody,.markdown-section .table-wrapper tr,.markdown-section .table-wrapper td{display:block}.markdown-section .table-wrapper th,.markdown-section .table-wrapper td{border:none}.markdown-section .table-wrapper thead{display:none}.markdown-section .table-wrapper tr{border-color:var(--table-cell-border-color);border-style:solid;border-width:var(--table-cell-border-width, 0);padding:var(--table-cell-padding)}.markdown-section .table-wrapper tr:not(:last-child){border-bottom:0}.markdown-section .table-wrapper td{padding:0.15em 0 0.15em 8em}.markdown-section .table-wrapper td::before{display:inline-block;float:left;width:8em;margin-left:-8em;font-weight:bold;text-align:left}}.markdown-section .tip,.markdown-section .warn{position:relative;margin:2em 0;padding:var(--notice-padding);border-width:var(--notice-border-width, 0);border-style:var(--notice-border-style);border-color:var(--notice-border-color);border-radius:var(--notice-border-radius);background:var(--notice-background);font-family:var(--notice-font-family);font-weight:var(--notice-font-weight);color:var(--notice-color)}.markdown-section .tip:before,.markdown-section .warn:before{display:inline-block;position:var(--notice-before-position, relative);top:var(--notice-before-top);left:var(--notice-before-left);height:var(--notice-before-height);width:var(--notice-before-width);margin:var(--notice-before-margin);padding:var(--notice-before-padding);border-radius:var(--notice-before-border-radius);line-height:var(--notice-before-line-height);font-family:var(--notice-before-font-family);font-size:var(--notice-before-font-size);font-weight:var(--notice-before-font-weight);text-align:center}.markdown-section .tip{border-width:var(--notice-important-border-width, var(--notice-border-width, 0));border-style:var(--notice-important-border-style, var(--notice-border-style));border-color:var(--notice-important-border-color, var(--notice-border-color));background:var(--notice-important-background, var(--notice-background));color:var(--notice-important-color, var(--notice-color))}.markdown-section .tip:before{content:var(--notice-important-before-content, var(--notice-before-content));background:var(--notice-important-before-background, var(--notice-before-background));color:var(--notice-important-before-color, var(--notice-before-color))}.markdown-section .warn{border-width:var(--notice-tip-border-width, var(--notice-border-width, 0));border-style:var(--notice-tip-border-style, var(--notice-border-style));border-color:var(--notice-tip-border-color, var(--notice-border-color));background:var(--notice-tip-background, var(--notice-background));color:var(--notice-tip-color, var(--notice-color))}.markdown-section .warn:before{content:var(--notice-tip-before-content, var(--notice-before-content));background:var(--notice-tip-before-background, var(--notice-before-background));color:var(--notice-tip-before-color, var(--notice-before-color))}.cover{display:none;position:relative;z-index:20;min-height:100vh;flex-direction:column;align-items:center;justify-content:center;padding:calc(var(--cover-border-inset, 0px) + var(--cover-border-width, 0px));color:var(--cover-color);text-align:var(--cover-text-align)}@media screen and (-ms-high-contrast: active), screen and (-ms-high-contrast: none){.cover{height:100vh}}.cover:before,.cover:after{content:'';position:absolute}.cover:before{top:0;bottom:0;left:0;right:0;background-blend-mode:var(--cover-background-blend-mode);background-color:var(--cover-background-color);background-image:var(--cover-background-image);background-position:var(--cover-background-position);background-repeat:var(--cover-background-repeat);background-size:var(--cover-background-size)}.cover:after{top:var(--cover-border-inset, 0);bottom:var(--cover-border-inset, 0);left:var(--cover-border-inset, 0);right:var(--cover-border-inset, 0);border-width:var(--cover-border-width, 0);border-style:solid;border-color:var(--cover-border-color)}.cover a{border-bottom:var(--cover-link-border-bottom);color:var(--cover-link-color);-webkit-text-decoration:var(--cover-link-text-decoration);text-decoration:var(--cover-link-text-decoration);-webkit-text-decoration-color:var(--cover-link-text-decoration-color);text-decoration-color:var(--cover-link-text-decoration-color)}.cover a:hover{border-bottom:var(--cover-link-border-bottom--hover, var(--cover-link-border-bottom));color:var(--cover-link-color--hover, var(--cover-link-color));-webkit-text-decoration:var(--cover-link-text-decoration--hover, var(--cover-link-text-decoration));text-decoration:var(--cover-link-text-decoration--hover, var(--cover-link-text-decoration));-webkit-text-decoration-color:var(--cover-link-text-decoration-color--hover, var(--cover-link-text-decoration-color));text-decoration-color:var(--cover-link-text-decoration-color--hover, var(--cover-link-text-decoration-color))}.cover h1{color:var(--cover-heading-color);position:relative;margin:0;font-size:var(--cover-heading-font-size);font-weight:var(--cover-heading-font-weight);line-height:1.2}.cover h1 a,.cover h1 a:hover{display:block;border-bottom:none;color:inherit;text-decoration:none}.cover h1 small{position:absolute;bottom:0;margin-left:0.5em}.cover h1 span{font-size:calc(var(--cover-heading-font-size-min) * 1px)}@media (min-width: 26em){.cover h1 span{font-size:calc((var(--cover-heading-font-size-min) * 1px) + (var(--cover-heading-font-size-max) - var(--cover-heading-font-size-min)) * ((100vw - 420px) / (1024 - 420)))}}@media (min-width: 64em){.cover h1 span{font-size:calc(var(--cover-heading-font-size-max) * 1px)}}.cover blockquote{margin:0;color:var(--cover-blockquote-color);font-size:var(--cover-blockquote-font-size)}.cover blockquote a{color:inherit}.cover ul{padding:0;list-style-type:none}.cover .cover-main{position:relative;z-index:1;max-width:var(--cover-max-width);margin:var(--cover-margin);padding:0 45px}.cover .cover-main>p:last-child{margin:1.25em -.25em}.cover .cover-main>p:last-child a{display:block;margin:.375em .25em;padding:var(--cover-button-padding);border:var(--cover-button-border);border-radius:var(--cover-button-border-radius);box-shadow:var(--cover-button-box-shadow);background:var(--cover-button-background);text-align:center;-webkit-text-decoration:var(--cover-button-text-decoration);text-decoration:var(--cover-button-text-decoration);-webkit-text-decoration-color:var(--cover-button-text-decoration-color);text-decoration-color:var(--cover-button-text-decoration-color);color:var(--cover-button-color);white-space:nowrap;transition:var(--cover-button-transition)}.cover .cover-main>p:last-child a:hover{border:var(--cover-button-border--hover, var(--cover-button-border));box-shadow:var(--cover-button-box-shadow--hover, var(--cover-button-box-shadow));background:var(--cover-button-background--hover, var(--cover-button-background));-webkit-text-decoration:var(--cover-button-text-decoration--hover, var(--cover-button-text-decoration));text-decoration:var(--cover-button-text-decoration--hover, var(--cover-button-text-decoration));-webkit-text-decoration-color:var(--cover-button-text-decoration-color--hover, var(--cover-button-text-decoration-color));text-decoration-color:var(--cover-button-text-decoration-color--hover, var(--cover-button-text-decoration-color));color:var(--cover-button-color--hover, var(--cover-button-color))}.cover .cover-main>p:last-child a:first-child{border:var(--cover-button-primary-border, var(--cover-button-border));box-shadow:var(--cover-button-primary-box-shadow, var(--cover-button-box-shadow));background:var(--cover-button-primary-background, var(--cover-button-background));-webkit-text-decoration:var(--cover-button-primary-text-decoration, var(--cover-button-text-decoration));text-decoration:var(--cover-button-primary-text-decoration, var(--cover-button-text-decoration));-webkit-text-decoration-color:var(--cover-button-primary-text-decoration-color, var(--cover-button-text-decoration-color));text-decoration-color:var(--cover-button-primary-text-decoration-color, var(--cover-button-text-decoration-color));color:var(--cover-button-primary-color, var(--cover-button-color))}.cover .cover-main>p:last-child a:first-child:hover{border:var(--cover-button-primary-border--hover, var(--cover-button-border--hover, var(--cover-button-primary-border, var(--cover-button-border))));box-shadow:var(--cover-button-primary-box-shadow--hover, var(--cover-button-box-shadow--hover, var(--cover-button-primary-box-shadow, var(--cover-button-box-shadow))));background:var(--cover-button-primary-background--hover, var(--cover-button-background--hover, var(--cover-button-primary-background, var(--cover-button-background))));-webkit-text-decoration:var(--cover-button-primary-text-decoration--hover, var(--cover-button-text-decoration--hover, var(--cover-button-primary-text-decoration, var(--cover-button-text-decoration))));text-decoration:var(--cover-button-primary-text-decoration--hover, var(--cover-button-text-decoration--hover, var(--cover-button-primary-text-decoration, var(--cover-button-text-decoration))));-webkit-text-decoration-color:var(--cover-button-primary-text-decoration-color--hover, var(--cover-button-text-decoration-color--hover, var(--cover-button-primary-text-decoration-color, var(--cover-button-text-decoration-color))));text-decoration-color:var(--cover-button-primary-text-decoration-color--hover, var(--cover-button-text-decoration-color--hover, var(--cover-button-primary-text-decoration-color, var(--cover-button-text-decoration-color))));color:var(--cover-button-primary-color--hover, var(--cover-button-color--hover, var(--cover-button-primary-color, var(--cover-button-color))))}@media (min-width: 30.01em){.cover .cover-main>p:last-child a{display:inline-block}}.cover .mask{visibility:var(--cover-background-mask-visibility, hidden);position:absolute;top:0;bottom:0;left:0;right:0;background-color:var(--cover-background-mask-color);opacity:var(--cover-background-mask-opacity)}.cover.has-mask .mask{visibility:visible}.cover.show{display:flex}.app-nav{position:absolute;z-index:30;top:calc(35px - (0.5em * var(--base-line-height)));left:45px;right:80px;text-align:right}.app-nav.no-badge{right:45px}.app-nav li>img,.app-nav li>a>img{margin-top:-0.25em;vertical-align:middle}.app-nav li>img:first-child,.app-nav li>a>img:first-child{margin-right:0.5em}.app-nav ul,.app-nav li{margin:0;padding:0;list-style:none}.app-nav li{position:relative}.app-nav li a{display:block;line-height:1;transition:var(--navbar-root-transition)}.app-nav>ul>li{display:inline-block;margin:var(--navbar-root-margin)}.app-nav>ul>li:first-child{margin-left:0}.app-nav>ul>li:last-child{margin-right:0}.app-nav>ul>li>a,.app-nav>ul>li>span{padding:var(--navbar-root-padding);border-width:var(--navbar-root-border-width, 0);border-style:var(--navbar-root-border-style);border-color:var(--navbar-root-border-color);border-radius:var(--navbar-root-border-radius);background:var(--navbar-root-background);color:var(--navbar-root-color);-webkit-text-decoration:var(--navbar-root-text-decoration);text-decoration:var(--navbar-root-text-decoration);-webkit-text-decoration-color:var(--navbar-root-text-decoration-color);text-decoration-color:var(--navbar-root-text-decoration-color)}.app-nav>ul>li>a:hover,.app-nav>ul>li>span:hover{background:var(--navbar-root-background--hover, var(--navbar-root-background));border-style:var(--navbar-root-border-style--hover, var(--navbar-root-border-style));border-color:var(--navbar-root-border-color--hover, var(--navbar-root-border-color));color:var(--navbar-root-color--hover, var(--navbar-root-color));-webkit-text-decoration:var(--navbar-root-text-decoration--hover, var(--navbar-root-text-decoration));text-decoration:var(--navbar-root-text-decoration--hover, var(--navbar-root-text-decoration));-webkit-text-decoration-color:var(--navbar-root-text-decoration-color--hover, var(--navbar-root-text-decoration-color));text-decoration-color:var(--navbar-root-text-decoration-color--hover, var(--navbar-root-text-decoration-color))}.app-nav>ul>li>a:not(:last-child),.app-nav>ul>li>span:not(:last-child){padding:var(--navbar-menu-root-padding, var(--navbar-root-padding));background:var(--navbar-menu-root-background, var(--navbar-root-background))}.app-nav>ul>li>a:not(:last-child):hover,.app-nav>ul>li>span:not(:last-child):hover{background:var(--navbar-menu-root-background--hover, var(--navbar-menu-root-background, var(--navbar-root-background--hover, var(--navbar-root-background))))}.app-nav>ul>li>a.active{background:var(--navbar-root-background--active, var(--navbar-root-background));border-style:var(--navbar-root-border-style--active, var(--navbar-root-border-style));border-color:var(--navbar-root-border-color--active, var(--navbar-root-border-color));color:var(--navbar-root-color--active, var(--navbar-root-color));-webkit-text-decoration:var(--navbar-root-text-decoration--active, var(--navbar-root-text-decoration));text-decoration:var(--navbar-root-text-decoration--active, var(--navbar-root-text-decoration));-webkit-text-decoration-color:var(--navbar-root-text-decoration-color--active, var(--navbar-root-text-decoration-color));text-decoration-color:var(--navbar-root-text-decoration-color--active, var(--navbar-root-text-decoration-color))}.app-nav>ul>li>a.active:not(:last-child):hover{background:var(--navbar-menu-root-background--active, var(--navbar-menu-root-background, var(--navbar-root-background--active, var(--navbar-root-background))))}.app-nav>ul>li ul{visibility:hidden;position:absolute;top:100%;right:50%;overflow-y:auto;box-sizing:border-box;max-height:calc(50vh);padding:var(--navbar-menu-padding);border-width:var(--navbar-menu-border-width, 0);border-style:solid;border-color:var(--navbar-menu-border-color);border-radius:var(--navbar-menu-border-radius);background:var(--navbar-menu-background);box-shadow:var(--navbar-menu-box-shadow);text-align:left;white-space:nowrap;opacity:0;transform:translate(50%, -0.35em);transition:var(--navbar-menu-transition)}.app-nav>ul>li ul li{white-space:nowrap}.app-nav>ul>li ul a{margin:var(--navbar-menu-link-margin);padding:var(--navbar-menu-link-padding);border-width:var(--navbar-menu-link-border-width, 0);border-style:var(--navbar-menu-link-border-style);border-color:var(--navbar-menu-link-border-color);border-radius:var(--navbar-menu-link-border-radius);background:var(--navbar-menu-link-background);color:var(--navbar-menu-link-color);-webkit-text-decoration:var(--navbar-menu-link-text-decoration);text-decoration:var(--navbar-menu-link-text-decoration);-webkit-text-decoration-color:var(--navbar-menu-link-text-decoration-color);text-decoration-color:var(--navbar-menu-link-text-decoration-color)}.app-nav>ul>li ul a:hover{background:var(--navbar-menu-link-background--hover, var(--navbar-menu-link-background));border-style:var(--navbar-menu-link-border-style--hover, var(--navbar-menu-link-border-style));border-color:var(--navbar-menu-link-border-color--hover, var(--navbar-menu-link-border-color));color:var(--navbar-menu-link-color--hover, var(--navbar-menu-link-color));-webkit-text-decoration:var(--navbar-menu-link-text-decoration--hover, var(--navbar-menu-link-text-decoration));text-decoration:var(--navbar-menu-link-text-decoration--hover, var(--navbar-menu-link-text-decoration));-webkit-text-decoration-color:var(--navbar-menu-link-text-decoration-color--hover, var(--navbar-menu-link-text-decoration-color));text-decoration-color:var(--navbar-menu-link-text-decoration-color--hover, var(--navbar-menu-link-text-decoration-color))}.app-nav>ul>li ul a.active{background:var(--navbar-menu-link-background--active, var(--navbar-menu-link-background));border-style:var(--navbar-menu-link-border-style--active, var(--navbar-menu-link-border-style));border-color:var(--navbar-menu-link-border-color--active, var(--navbar-menu-link-border-color));color:var(--navbar-menu-link-color--active, var(--navbar-menu-link-color));-webkit-text-decoration:var(--navbar-menu-link-text-decoration--active, var(--navbar-menu-link-text-decoration));text-decoration:var(--navbar-menu-link-text-decoration--active, var(--navbar-menu-link-text-decoration));-webkit-text-decoration-color:var(--navbar-menu-link-text-decoration-color--active, var(--navbar-menu-link-text-decoration-color));text-decoration-color:var(--navbar-menu-link-text-decoration-color--active, var(--navbar-menu-link-text-decoration-color))}.app-nav>ul>li:hover ul,.app-nav>ul>li:focus ul,.app-nav>ul>li.focus-within ul{visibility:visible;opacity:1;transform:translate(50%, 0)}@media (min-width: 48em){nav.app-nav{margin-left:var(--sidebar-width)}}main{position:relative;overflow-x:hidden;min-height:100vh}.sidebar,.sidebar-toggle,.sidebar+.content{transition:all var(--sidebar-transition-duration) ease-out}@media (min-width: 48em){.sidebar+.content{margin-left:var(--sidebar-width)}}.sidebar{display:flex;flex-direction:column;position:fixed;z-index:10;top:0;right:100%;overflow-x:hidden;overflow-y:auto;height:100vh;width:var(--sidebar-width);padding:var(--sidebar-padding);border-width:var(--sidebar-border-width);border-style:solid;border-color:var(--sidebar-border-color);background:var(--sidebar-background)}.sidebar>h1{margin:0;margin:var(--sidebar-name-margin);padding:var(--sidebar-name-padding);background:var(--sidebar-name-background);color:var(--sidebar-name-color);font-family:var(--sidebar-name-font-family);font-size:var(--sidebar-name-font-size);font-weight:var(--sidebar-name-font-weight);text-align:var(--sidebar-name-text-align)}.sidebar>h1 img{max-width:100%}.sidebar>h1 .app-name-link{color:var(--sidebar-name-color)}body:not([data-platform^="Mac"]) .sidebar::-webkit-scrollbar{width:5px}body:not([data-platform^="Mac"]) .sidebar::-webkit-scrollbar-thumb{border-radius:50vw}@media (min-width: 48em){.sidebar{position:absolute;transform:translateX(var(--sidebar-width))}}@media print{.sidebar{display:none}}.sidebar-nav,.sidebar nav{order:1;margin:var(--sidebar-nav-margin);padding:var(--sidebar-nav-padding);background:var(--sidebar-nav-background)}.sidebar-nav ul,.sidebar nav ul{margin:0;padding:0;list-style:none}.sidebar-nav ul ul,.sidebar nav ul ul{margin-left:var(--sidebar-nav-indent)}.sidebar-nav a,.sidebar nav a{display:block;overflow:hidden;margin:var(--sidebar-nav-link-margin);padding:var(--sidebar-nav-link-padding);border-width:var(--sidebar-nav-link-border-width, 0);border-style:var(--sidebar-nav-link-border-style);border-color:var(--sidebar-nav-link-border-color);border-radius:var(--sidebar-nav-link-border-radius);background-color:var(--sidebar-nav-link-background-color);background-image:var(--sidebar-nav-link-background-image);background-position:var(--sidebar-nav-link-background-position);background-repeat:var(--sidebar-nav-link-background-repeat);background-size:var(--sidebar-nav-link-background-size);color:var(--sidebar-nav-link-color);font-weight:var(--sidebar-nav-link-font-weight);white-space:nowrap;-webkit-text-decoration:var(--sidebar-nav-link-text-decoration);text-decoration:var(--sidebar-nav-link-text-decoration);-webkit-text-decoration-color:var(--sidebar-nav-link-text-decoration-color);text-decoration-color:var(--sidebar-nav-link-text-decoration-color);text-overflow:ellipsis;transition:var(--sidebar-nav-link-transition)}.sidebar-nav a img,.sidebar nav a img{margin-top:-0.25em;vertical-align:middle}.sidebar-nav a img:first-child,.sidebar nav a img:first-child{margin-right:0.5em}.sidebar-nav a:hover,.sidebar nav a:hover{border-width:var(--sidebar-nav-link-border-width--hover, var(--sidebar-nav-link-border-width, 0));border-style:var(--sidebar-nav-link-border-style--hover, var(--sidebar-nav-link-border-style));border-color:var(--sidebar-nav-link-border-color--hover, var(--sidebar-nav-link-border-color));background-color:var(--sidebar-nav-link-background-color--hover, var(--sidebar-nav-link-background-color));background-image:var(--sidebar-nav-link-background-image--hover, var(--sidebar-nav-link-background-image));background-position:var(--sidebar-nav-link-background-position--hover, var(--sidebar-nav-link-background-position));background-size:var(--sidebar-nav-link-background-size--hover, var(--sidebar-nav-link-background-size));color:var(--sidebar-nav-link-color--hover, var(--sidebar-nav-link-color));font-weight:var(--sidebar-nav-link-font-weight--hover, var(--sidebar-nav-link-font-weight));-webkit-text-decoration:var(--sidebar-nav-link-text-decoration--hover, var(--sidebar-nav-link-text-decoration));text-decoration:var(--sidebar-nav-link-text-decoration--hover, var(--sidebar-nav-link-text-decoration));-webkit-text-decoration-color:var(--sidebar-nav-link-text-decoration-color);text-decoration-color:var(--sidebar-nav-link-text-decoration-color)}.sidebar-nav ul>li>span,.sidebar-nav ul>li>strong,.sidebar nav ul>li>span,.sidebar nav ul>li>strong{display:block;margin:var(--sidebar-nav-strong-margin);padding:var(--sidebar-nav-strong-padding);border-width:var(--sidebar-nav-strong-border-width, 0);border-style:solid;border-color:var(--sidebar-nav-strong-border-color);color:var(--sidebar-nav-strong-color);font-size:var(--sidebar-nav-strong-font-size);font-weight:var(--sidebar-nav-strong-font-weight);text-transform:var(--sidebar-nav-strong-text-transform)}.sidebar-nav ul>li>span+ul,.sidebar-nav ul>li>strong+ul,.sidebar nav ul>li>span+ul,.sidebar nav ul>li>strong+ul{margin-left:0}.sidebar-nav ul>li:first-child>span,.sidebar-nav ul>li:first-child>strong,.sidebar nav ul>li:first-child>span,.sidebar nav ul>li:first-child>strong{margin-top:0}.sidebar-nav::-webkit-scrollbar,.sidebar nav::-webkit-scrollbar{width:0}@supports (width: env(safe-area-inset)){@media only screen and (orientation: landscape){.sidebar-nav,.sidebar nav{margin-left:calc(env(safe-area-inset-left) / 2)}}}.sidebar-nav li>a:before,.sidebar-nav li>strong:before{display:inline-block}.sidebar-nav li>a{background-repeat:var(--sidebar-nav-pagelink-background-repeat);background-size:var(--sidebar-nav-pagelink-background-size)}.sidebar-nav li>a[href^="/"]:not([href*="?id="]),.sidebar-nav li>a[href^="#/"]:not([href*="?id="]){transition:var(--sidebar-nav-pagelink-transition)}.sidebar-nav li>a[href^="/"]:not([href*="?id="]),.sidebar-nav li>a[href^="/"]:not([href*="?id="]) ~ ul a,.sidebar-nav li>a[href^="#/"]:not([href*="?id="]),.sidebar-nav li>a[href^="#/"]:not([href*="?id="]) ~ ul a{padding:var(--sidebar-nav-pagelink-padding, var(--sidebar-nav-link-padding))}.sidebar-nav li>a[href^="/"]:not([href*="?id="]):only-child,.sidebar-nav li>a[href^="#/"]:not([href*="?id="]):only-child{background-image:var(--sidebar-nav-pagelink-background-image);background-position:var(--sidebar-nav-pagelink-background-position)}.sidebar-nav li>a[href^="/"]:not([href*="?id="]):not(:only-child),.sidebar-nav li>a[href^="#/"]:not([href*="?id="]):not(:only-child){background-image:var(--sidebar-nav-pagelink-background-image--loaded, var(--sidebar-nav-pagelink-background-image));background-position:var(--sidebar-nav-pagelink-background-position--loaded, var(--sidebar-nav-pagelink-background-image))}.sidebar-nav li.active>a,.sidebar-nav li.collapse>a{border-width:var(--sidebar-nav-link-border-width--active, var(--sidebar-nav-link-border-width));border-style:var(--sidebar-nav-link-border-style--active, var(--sidebar-nav-link-border-style));border-color:var(--sidebar-nav-link-border-color--active, var(--sidebar-nav-link-border-color));background-color:var(--sidebar-nav-link-background-color--active, var(--sidebar-nav-link-background-color));background-image:var(--sidebar-nav-link-background-image--active, var(--sidebar-nav-link-background-image));background-position:var(--sidebar-nav-link-background-position--active, var(--sidebar-nav-link-background-position));background-size:var(--sidebar-nav-link-background-size--active, var(--sidebar-nav-link-background-size));color:var(--sidebar-nav-link-color--active, var(--sidebar-nav-link-color));font-weight:var(--sidebar-nav-link-font-weight--active, var(--sidebar-nav-link-font-weight));-webkit-text-decoration:var(--sidebar-nav-link-text-decoration--active, var(--sidebar-nav-link-text-decoration));text-decoration:var(--sidebar-nav-link-text-decoration--active, var(--sidebar-nav-link-text-decoration));-webkit-text-decoration-color:var(--sidebar-nav-link-text-decoration-color);text-decoration-color:var(--sidebar-nav-link-text-decoration-color)}.sidebar-nav li.active>a[href^="/"]:not([href*="?id="]):not(:only-child),.sidebar-nav li.active>a[href^="#/"]:not([href*="?id="]):not(:only-child){background-image:var(--sidebar-nav-pagelink-background-image--active, var(--sidebar-nav-pagelink-background-image--loaded, var(--sidebar-nav-pagelink-background-image)));background-position:var(--sidebar-nav-pagelink-background-position--active, var(--sidebar-nav-pagelink-background-position--loaded, var(--sidebar-nav-pagelink-background-image)))}.sidebar-nav li.collapse>a[href^="/"]:not([href*="?id="]):not(:only-child),.sidebar-nav li.collapse>a[href^="#/"]:not([href*="?id="]):not(:only-child){background-image:var(--sidebar-nav-pagelink-background-image--collapse, var(--sidebar-nav-pagelink-background-image--loaded, var(--sidebar-nav-pagelink-background-image)));background-position:var(--sidebar-nav-pagelink-background-position--collapse, var(--sidebar-nav-pagelink-background-position--loaded, var(--sidebar-nav-pagelink-background-image)))}.sidebar-nav li.collapse .app-sub-sidebar{display:none}.sidebar-nav>ul>li>a:before{content:var(--sidebar-nav-link-before-content-l1, var(--sidebar-nav-link-before-content));margin:var(--sidebar-nav-link-before-margin-l1, var(--sidebar-nav-link-before-margin));color:var(--sidebar-nav-link-before-color-l1, var(--sidebar-nav-link-before-color))}.sidebar-nav>ul>li.active>a:before{content:var(--sidebar-nav-link-before-content-l1--active, var(--sidebar-nav-link-before-content--active, var(--sidebar-nav-link-before-content-l1, var(--sidebar-nav-link-before-content))));color:var(--sidebar-nav-link-before-color-l1--active, var(--sidebar-nav-link-before-color--active, var(--sidebar-nav-link-before-color-l1, var(--sidebar-nav-link-before-color))))}.sidebar-nav>ul>li>ul>li>a:before{content:var(--sidebar-nav-link-before-content-l2, var(--sidebar-nav-link-before-content));margin:var(--sidebar-nav-link-before-margin-l2, var(--sidebar-nav-link-before-margin));color:var(--sidebar-nav-link-before-color-l2, var(--sidebar-nav-link-before-color))}.sidebar-nav>ul>li>ul>li.active>a:before{content:var(--sidebar-nav-link-before-content-l2--active, var(--sidebar-nav-link-before-content--active, var(--sidebar-nav-link-before-content-l2, var(--sidebar-nav-link-before-content))));color:var(--sidebar-nav-link-before-color-l2--active, var(--sidebar-nav-link-before-color--active, var(--sidebar-nav-link-before-color-l2, var(--sidebar-nav-link-before-color))))}.sidebar-nav>ul>li>ul>li>ul>li>a:before{content:var(--sidebar-nav-link-before-content-l3, var(--sidebar-nav-link-before-content));margin:var(--sidebar-nav-link-before-margin-l3, var(--sidebar-nav-link-before-margin));color:var(--sidebar-nav-link-before-color-l3, var(--sidebar-nav-link-before-color))}.sidebar-nav>ul>li>ul>li>ul>li.active>a:before{content:var(--sidebar-nav-link-before-content-l3--active, var(--sidebar-nav-link-before-content--active, var(--sidebar-nav-link-before-content-l3, var(--sidebar-nav-link-before-content))));color:var(--sidebar-nav-link-before-color-l3--active, var(--sidebar-nav-link-before-color--active, var(--sidebar-nav-link-before-color-l3, var(--sidebar-nav-link-before-color))))}.sidebar-nav>ul>li>ul>li>ul>li>ul>li>a:before{content:var(--sidebar-nav-link-before-content-l4, var(--sidebar-nav-link-before-content));margin:var(--sidebar-nav-link-before-margin-l4, var(--sidebar-nav-link-before-margin));color:var(--sidebar-nav-link-before-color-l4, var(--sidebar-nav-link-before-color))}.sidebar-nav>ul>li>ul>li>ul>li>ul>li.active>a:before{content:var(--sidebar-nav-link-before-content-l4--active, var(--sidebar-nav-link-before-content--active, var(--sidebar-nav-link-before-content-l4, var(--sidebar-nav-link-before-content))));color:var(--sidebar-nav-link-before-color-l4--active, var(--sidebar-nav-link-before-color--active, var(--sidebar-nav-link-before-color-l4, var(--sidebar-nav-link-before-color))))}.sidebar-nav>:last-child{margin-bottom:2rem}.sidebar-toggle,.sidebar-toggle-button{width:var(--sidebar-toggle-width);outline:none}.sidebar-toggle{position:fixed;z-index:11;top:0;bottom:0;left:0;max-width:40px;margin:0;padding:0;border:0;background:transparent;-webkit-appearance:none;-moz-appearance:none;appearance:none;cursor:pointer}.sidebar-toggle .sidebar-toggle-button{position:absolute;top:var(--sidebar-toggle-offset-top);left:var(--sidebar-toggle-offset-left);height:var(--sidebar-toggle-height);border-radius:var(--sidebar-toggle-border-radius);border-width:var(--sidebar-toggle-border-width);border-style:var(--sidebar-toggle-border-style);border-color:var(--sidebar-toggle-border-color);background:var(--sidebar-toggle-background, transparent);color:var(--sidebar-toggle-icon-color)}.sidebar-toggle span{position:absolute;top:calc(50% - (var(--sidebar-toggle-icon-stroke-width) / 2));left:calc(50% - (var(--sidebar-toggle-icon-width) / 2));height:var(--sidebar-toggle-icon-stroke-width);width:var(--sidebar-toggle-icon-width);background-color:currentColor}.sidebar-toggle span:nth-child(1){margin-top:calc(0px - (var(--sidebar-toggle-icon-height) / 2))}.sidebar-toggle span:nth-child(3){margin-top:calc((var(--sidebar-toggle-icon-height) / 2))}@media (min-width: 48em){.sidebar-toggle{position:absolute;overflow:visible;top:var(--sidebar-toggle-offset-top);bottom:auto;left:0;height:var(--sidebar-toggle-height);transform:translateX(var(--sidebar-width))}.sidebar-toggle .sidebar-toggle-button{top:0}}@media print{.sidebar-toggle{display:none}}@media (max-width: 47.99em){body.close .sidebar,body.close .sidebar-toggle,body.close .sidebar+.content{transform:translateX(var(--sidebar-width))}}@media (min-width: 48em){body.close .sidebar+.content{transform:translateX(0)}}@media (max-width: 47.99em){body.close nav.app-nav,body.close .github-corner{display:none}}@media (min-width: 48em){body.close .sidebar,body.close .sidebar-toggle{transform:translateX(0)}}@media (min-width: 48em){body.close nav.app-nav{margin-left:0}}@media (max-width: 47.99em){body.close .sidebar-toggle{width:100%;max-width:none}body.close .sidebar-toggle span{margin-top:0}body.close .sidebar-toggle span:nth-child(1){transform:rotate(45deg)}body.close .sidebar-toggle span:nth-child(2){display:none}body.close .sidebar-toggle span:nth-child(3){transform:rotate(-45deg)}}@media (min-width: 48em){body.close .sidebar+.content{margin-left:0}}@media (min-width: 48em){body.sticky .sidebar,body.sticky .sidebar-toggle{position:fixed}}body .docsify-copy-code-button,body .docsify-copy-code-button:after{border-radius:var(--border-radius-m, 0);border-top-left-radius:0;border-bottom-right-radius:0;background:var(--copycode-background);color:var(--copycode-color)}body .docsify-copy-code-button span{border-radius:var(--border-radius-s, 0)}body .docsify-pagination-container{border-top:var(--pagination-border-top);color:var(--pagination-color)}body .pagination-item-label{font-size:var(--pagination-label-font-size)}body .pagination-item-label svg{color:var(--pagination-label-color);height:var(--pagination-chevron-height);stroke:var(--pagination-chevron-stroke);stroke-linecap:var(--pagination-chevron-stroke-linecap);stroke-linejoin:var(--pagination-chevron-stroke-linecap);stroke-width:var(--pagination-chevron-stroke-width)}body .pagination-item-title{color:var(--pagination-title-color);font-size:var(--pagination-title-font-size)}body .app-name.hide{display:block}body .sidebar{padding:var(--sidebar-padding)}.sidebar .search{margin:0;padding:0;border:0}.sidebar .search input{padding:0;line-height:1;font-size:inherit}.sidebar .search .clear-button{width:auto}.sidebar .search .clear-button svg{transform:scale(1)}.sidebar .search .matching-post{border:none}.sidebar .search p{font-size:inherit}.sidebar .search{order:var(--search-flex-order);margin:var(--search-margin);padding:var(--search-padding);background:var(--search-background)}.sidebar .search a{color:inherit}.sidebar .search h2{margin:var(--search-result-heading-margin);font-size:var(--search-result-heading-font-size);font-weight:var(--search-result-heading-font-weight);color:var(--search-result-heading-color)}.sidebar .search .input-wrap{align-items:stretch;margin:var(--search-input-margin);background-color:var(--search-input-background-color);border-width:var(--search-input-border-width, 0);border-style:solid;border-color:var(--search-input-border-color);border-radius:var(--search-input-border-radius)}.sidebar .search input[type="search"]{min-width:0;padding:var(--search-input-padding);border:none;background-color:transparent;background-image:var(--search-input-background-image);background-position:var(--search-input-background-position);background-repeat:var(--search-input-background-repeat);background-size:var(--search-input-background-size);font-size:var(--search-input-font-size);color:var(--search-input-color);transition:var(--search-input-transition)}.sidebar .search input[type="search"]::-ms-clear{display:none}.sidebar .search input[type="search"]::-moz-placeholder{color:var(--search-input-placeholder-color, gray)}.sidebar .search input[type="search"]:-ms-input-placeholder{color:var(--search-input-placeholder-color, gray)}.sidebar .search input[type="search"]::placeholder{color:var(--search-input-placeholder-color, gray)}.sidebar .search input[type="search"]::-webkit-input-placeholder{line-height:normal}.sidebar .search input[type="search"]:focus{background-color:var(--search-input-background-color--focus, var(--search-input-background-color));background-image:var(--search-input-background-image--focus, var(--search-input-background-image));background-position:var(--search-input-background-position--focus, var(--search-input-background-position));background-size:var(--search-input-background-size--focus, var(--search-input-background-size))}@supports (width: env(safe-area-inset)){@media only screen and (orientation: landscape){.sidebar .search input[type="search"]{margin-left:calc(env(safe-area-inset-left) / 2)}}}.sidebar .search p{overflow:hidden;text-overflow:ellipsis;-webkit-box-orient:vertical;-webkit-line-clamp:2}.sidebar .search p:empty{text-align:center}.sidebar .search .clear-button{margin:0;padding:0 10px;border:none;line-height:1;background:transparent;cursor:pointer}.sidebar .search .clear-button svg circle{fill:var(--search-clear-icon-color1, gray)}.sidebar .search .clear-button svg path{stroke:var(--search-clear-icon-color2, #fff)}.sidebar .search.show ~ *:not(h1){display:none}.sidebar .search .results-panel{display:none;color:var(--search-result-item-color);font-size:var(--search-result-item-font-size);font-weight:var(--search-result-item-font-weight)}.sidebar .search .results-panel.show{display:block}.sidebar .search .matching-post{margin:var(--search-result-item-margin);padding:var(--search-result-item-padding)}.sidebar .search .matching-post,.sidebar .search .matching-post:last-child{border-width:var(--search-result-item-border-width, 0) !important;border-style:var(--search-result-item-border-style);border-color:var(--search-result-item-border-color)}.sidebar .search .matching-post p{margin:0}.sidebar .search .search-keyword{margin:var(--search-result-keyword-margin);padding:var(--search-result-keyword-padding);border-radius:var(--search-result-keyword-border-radius);background-color:var(--search-result-keyword-background);color:var(--search-result-keyword-color, currentColor);font-style:normal;font-weight:var(--search-result-keyword-font-weight)}.medium-zoom-overlay,.medium-zoom-image--open,.medium-zoom-image--opened{z-index:2147483646 !important}.medium-zoom-overlay{background:var(--zoomimage-overlay-background) !important}:root{--mono-hue: 113;--mono-saturation: 0%;--mono-shade3: hsl(var(--mono-hue), var(--mono-saturation), 20%);--mono-shade2: hsl(var(--mono-hue), var(--mono-saturation), 30%);--mono-shade1: hsl(var(--mono-hue), var(--mono-saturation), 40%);--mono-base: hsl(var(--mono-hue), var(--mono-saturation), 50%);--mono-tint1: hsl(var(--mono-hue), var(--mono-saturation), 70%);--mono-tint2: hsl(var(--mono-hue), var(--mono-saturation), 89%);--mono-tint3: hsl(var(--mono-hue), var(--mono-saturation), 97%);--theme-hue: 204;--theme-saturation: 90%;--theme-lightness: 45%;--theme-color: hsl(var(--theme-hue), var(--theme-saturation), var(--theme-lightness));--modular-scale: 1.333;--modular-scale--2: calc(var(--modular-scale--1) / var(--modular-scale));--modular-scale--1: calc(var(--modular-scale-1) / var(--modular-scale));--modular-scale-1: 1rem;--modular-scale-2: calc(var(--modular-scale-1) * var(--modular-scale));--modular-scale-3: calc(var(--modular-scale-2) * var(--modular-scale));--modular-scale-4: calc(var(--modular-scale-3) * var(--modular-scale));--modular-scale-5: calc(var(--modular-scale-4) * var(--modular-scale));--font-size-xxxl: var(--modular-scale-5);--font-size-xxl: var(--modular-scale-4);--font-size-xl: var(--modular-scale-3);--font-size-l: var(--modular-scale-2);--font-size-m: var(--modular-scale-1);--font-size-s: var(--modular-scale--1);--font-size-xs: var(--modular-scale--2);--duration-slow: 1s;--duration-medium: 0.5s;--duration-fast: 0.25s;--spinner-size: 60px;--spinner-track-width: 4px;--spinner-track-color: rgba(0, 0, 0, 0.15);--spinner-transition-duration: var(--duration-medium)}:root{--base-background-color: #fff;--base-color: var(--mono-shade2);--base-font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";--base-font-size: 16px;--base-font-weight: normal;--base-line-height: 1.7;--emoji-size: calc(var(--base-line-height) * 1em);--hr-border: 1px solid var(--mono-tint2);--mark-background: #ffecb3;--pre-font-family: var(--code-font-family);--pre-font-size: var(--code-font-size);--pre-font-weight: normal;--selection-color: #b4d5fe;--small-font-size: var(--font-size-s);--strong-color: var(--heading-color);--strong-font-weight: 600;--subsup-font-size: var(--font-size-s)}:root{--content-max-width: 55em;--blockquote-background: var(--mono-tint3);--blockquote-border-style: solid;--blockquote-border-radius: var(--border-radius-m);--blockquote-em-font-weight: normal;--blockquote-font-weight: normal;--code-font-family: Inconsolata, Consolas, Menlo, Monaco, "Andale Mono WT", "Andale Mono", "Lucida Console", "DejaVu Sans Mono", "Bitstream Vera Sans Mono", "Courier New", Courier, monospace;--code-font-size: calc(var(--font-size-m) * 0.95);--code-font-weight: normal;--code-tab-size: 4;--code-block-border-radius: var(--border-radius-m);--code-block-line-height: var(--base-line-height);--code-block-margin: 1em 0;--code-block-padding: 1.75em 1.5em 1.5em 1.5em;--code-inline-background: var(--code-theme-background);--code-inline-border-radius: var(--border-radius-s);--code-inline-color: var(--code-theme-text);--code-inline-margin: 0 0.15em;--code-inline-padding: 0.125em 0.4em;--code-theme-background: var(--mono-tint3);--heading-color: var(--mono-shade3);--heading-margin: 2.5rem 0 0;--heading-h1-border-style: solid;--heading-h1-font-size: var(--font-size-xxl);--heading-h2-border-style: solid;--heading-h2-font-size: var(--font-size-xl);--heading-h3-border-style: solid;--heading-h3-font-size: var(--font-size-l);--heading-h4-border-style: solid;--heading-h4-font-size: var(--font-size-m);--heading-h5-border-style: solid;--heading-h5-font-size: var(--font-size-s);--heading-h6-border-style: solid;--heading-h6-font-size: var(--font-size-xs);--kbd-background: var(--mono-tint3);--kbd-border-radius: var(--border-radius-m);--kbd-margin: 0 0.3em;--kbd-min-width: 2.5em;--kbd-padding: 0.65em 0.5em;--link-text-decoration: underline;--notice-background: var(--mono-tint3);--notice-border-radius: var(--border-radius-m);--notice-border-style: solid;--notice-font-weight: normal;--notice-padding: 1em 1.5em;--notice-before-font-weight: normal;--table-cell-padding: 0.75em 0.5em;--table-head-border-color: var(--table-cell-border-color);--table-head-font-weight: var(--strong-font-weight);--table-row-odd-background: var(--mono-tint3)}:root{--cover-margin: 0 auto;--cover-max-width: 40em;--cover-text-align: center;--cover-background-color: var(--base-background-color);--cover-background-mask-color: var(--base-background-color);--cover-background-mask-opacity: 0.8;--cover-background-position: center center;--cover-background-repeat: no-repeat;--cover-background-size: cover;--cover-blockquote-font-size: var(--font-size-l);--cover-border-color: var(--theme-color);--cover-button-border: 1px solid var(--theme-color);--cover-button-border-radius: var(--border-radius-m);--cover-button-color: var(--theme-color);--cover-button-padding: 0.5em 2rem;--cover-button-text-decoration: none;--cover-button-transition: all var(--duration-fast) ease-in-out;--cover-button-primary-background: var(--theme-color);--cover-button-primary-border: 1px solid var(--theme-color);--cover-button-primary-color: #fff;--cover-heading-color: var(--theme-color);--cover-heading-font-size: var(--font-size-xxl);--cover-heading-font-weight: normal;--cover-link-text-decoration: underline }:root{--navbar-root-border-style: solid;--navbar-root-margin: 0 0 0 1.5em;--navbar-root-transition: all var(--duration-fast);--navbar-menu-background: var(--base-background-color);--navbar-menu-border-radius: var(--border-radius-m);--navbar-menu-box-shadow: rgba(45,45,45,0.05) 0px 0px 1px, rgba(49,49,49,0.05) 0px 1px 2px, rgba(42,42,42,0.05) 0px 2px 4px, rgba(32,32,32,0.05) 0px 4px 8px, rgba(49,49,49,0.05) 0px 8px 16px, rgba(35,35,35,0.05) 0px 16px 32px;--navbar-menu-padding: 0.5em;--navbar-menu-transition: all var(--duration-fast);--navbar-menu-link-border-style: solid;--navbar-menu-link-margin: 0.75em 0.5em;--navbar-menu-link-padding: 0.2em 0 }:root{--copycode-background: #808080;--copycode-color: #fff}:root{--docsifytabs-border-color: var(--mono-tint2);--docsifytabs-border-radius-px: var(--border-radius-s);--docsifytabs-tab-background: var(--mono-tint3);--docsifytabs-tab-color: var(--mono-tint1)}:root{--pagination-border-top: 1px solid var(--mono-tint2);--pagination-chevron-height: 0.8em;--pagination-chevron-stroke: currentColor;--pagination-chevron-stroke-linecap: round;--pagination-chevron-stroke-width: 1px;--pagination-label-font-size: var(--font-size-s);--pagination-title-font-size: var(--font-size-l)}:root{--search-margin: 1.5rem 0 0;--search-input-background-repeat: no-repeat;--search-input-border-color: var(--mono-tint1);--search-input-border-width: 1px;--search-input-padding: 0.5em;--search-flex-order: 1;--search-result-heading-color: var(--heading-color);--search-result-heading-font-size: var(--base-font-size);--search-result-heading-font-weight: normal;--search-result-heading-margin: 0 0 0.25em;--search-result-item-border-color: var(--mono-tint2);--search-result-item-border-style: solid;--search-result-item-border-width: 0 0 1px 0;--search-result-item-font-weight: normal;--search-result-item-padding: 1em 0;--search-result-keyword-background: var(--mark-background);--search-result-keyword-border-radius: var(--border-radius-s);--search-result-keyword-color: var(--mark-color);--search-result-keyword-font-weight: normal;--search-result-keyword-margin: 0 0.1em;--search-result-keyword-padding: 0.2em 0}:root{--zoomimage-overlay-background: rgba(0, 0, 0, 0.875)}:root{--sidebar-background: var(--base-background-color);--sidebar-border-width: 0;--sidebar-padding: 0 25px;--sidebar-transition-duration: var(--duration-fast);--sidebar-width: 17rem;--sidebar-name-font-size: var(--font-size-l);--sidebar-name-font-weight: normal;--sidebar-name-margin: 1.5rem 0 0;--sidebar-name-text-align: center;--sidebar-nav-strong-border-color: var(--sidebar-border-color);--sidebar-nav-strong-color: var(--heading-color);--sidebar-nav-strong-font-weight: var(--strong-font-weight);--sidebar-nav-strong-margin: 1.5em 0 0.5em;--sidebar-nav-strong-padding: 0.25em 0;--sidebar-nav-indent: 1em;--sidebar-nav-margin: 1.5rem 0 0;--sidebar-nav-link-border-style: solid;--sidebar-nav-link-border-width: 0;--sidebar-nav-link-color: var(--base-color);--sidebar-nav-link-font-weight: normal;--sidebar-nav-link-padding: 0.25em 0;--sidebar-nav-link-text-decoration--active: underline;--sidebar-nav-link-text-decoration--hover: underline;--sidebar-nav-link-before-margin: 0 0.35em 0 0;--sidebar-nav-pagelink-background-repeat: no-repeat;--sidebar-nav-pagelink-transition: var(--sidebar-nav-link-transition);--sidebar-toggle-border-radius: var(--border-radius-s);--sidebar-toggle-border-style: solid;--sidebar-toggle-border-width: 0;--sidebar-toggle-height: 36px;--sidebar-toggle-icon-color: var(--base-color);--sidebar-toggle-icon-height: 10px;--sidebar-toggle-icon-stroke-width: 1px;--sidebar-toggle-icon-width: 16px;--sidebar-toggle-offset-left: 0;--sidebar-toggle-offset-top: calc(35px - (var(--sidebar-toggle-height) / 2));--sidebar-toggle-width: 44px}:root{--code-theme-background: #f3f3f3;--code-theme-comment: #6e8090;--code-theme-function: #dd4a68;--code-theme-keyword: #07a;--code-theme-operator: #a67f59;--code-theme-punctuation: #999;--code-theme-selector: #690;--code-theme-tag: #905;--code-theme-text: #333;--code-theme-variable: #e90}:root{--border-radius-s: 2px;--border-radius-m: 4px;--border-radius-l: 8px;--strong-font-weight: 600;--blockquote-border-color: var(--theme-color);--blockquote-border-radius: 0 var(--border-radius-m) var(--border-radius-m) 0;--blockquote-border-width: 0 0 0 4px;--code-inline-background: var(--mono-tint2);--code-theme-background: var(--mono-tint3);--heading-font-weight: var(--strong-font-weight);--heading-h1-font-weight: 400;--heading-h2-font-weight: 400;--heading-h2-border-color: var(--mono-tint2);--heading-h2-border-width: 0 0 1px 0;--heading-h2-margin: 2.5rem 0 1.5rem;--heading-h2-padding: 0 0 1rem 0;--kbd-border: 1px solid var(--mono-tint2);--notice-border-radius: 0 var(--border-radius-m) var(--border-radius-m) 0;--notice-border-width: 0 0 0 4px;--notice-padding: 1em 1.5em 1em 3em;--notice-before-border-radius: 100%;--notice-before-font-weight: bold;--notice-before-height: 1.5em;--notice-before-left: 0.75em;--notice-before-line-height: 1.5;--notice-before-margin: 0 0.25em 0 0;--notice-before-position: absolute;--notice-before-width: var(--notice-before-height);--notice-important-background: hsl(340, 60%, 96%);--notice-important-border-color: hsl(340, 90%, 45%);--notice-important-before-background: var(--notice-important-border-color) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23fff'%3E%3Cpath d='M10 14C10 15.1 9.1 16 8 16 6.9 16 6 15.1 6 14 6 12.9 6.9 12 8 12 9.1 12 10 12.9 10 14Z'/%3E%3Cpath d='M10 1.6C10 1.2 9.8 0.9 9.6 0.7 9.2 0.3 8.6 0 8 0 7.4 0 6.8 0.2 6.5 0.6 6.2 0.9 6 1.2 6 1.6 6 1.7 6 1.8 6 1.9L6.8 9.6C6.9 9.9 7 10.1 7.2 10.2 7.4 10.4 7.7 10.5 8 10.5 8.3 10.5 8.6 10.4 8.8 10.3 9 10.1 9.1 9.9 9.2 9.6L10 1.9C10 1.8 10 1.7 10 1.6Z'/%3E%3C/svg%3E") center / 0.875em no-repeat;--notice-important-before-color: #fff;--notice-important-before-content: "";--notice-tip-background: hsl(204, 60%, 96%);--notice-tip-border-color: hsl(204, 90%, 45%);--notice-tip-before-background: var(--notice-tip-border-color) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23fff'%3E%3Cpath d='M9.1 0C10.2 0 10.7 0.7 10.7 1.6 10.7 2.6 9.8 3.6 8.6 3.6 7.6 3.6 7 3 7 2 7 1.1 7.7 0 9.1 0Z'/%3E%3Cpath d='M5.8 16C5 16 4.4 15.5 5 13.2L5.9 9.1C6.1 8.5 6.1 8.2 5.9 8.2 5.7 8.2 4.6 8.6 3.9 9.1L3.5 8.4C5.6 6.6 7.9 5.6 8.9 5.6 9.8 5.6 9.9 6.6 9.5 8.2L8.4 12.5C8.2 13.2 8.3 13.5 8.5 13.5 8.7 13.5 9.6 13.2 10.4 12.5L10.9 13.2C8.9 15.2 6.7 16 5.8 16Z'/%3E%3C/svg%3E") center / 0.875em no-repeat;--notice-tip-before-color: #fff;--notice-tip-before-content: "";--table-cell-border-color: var(--mono-tint2);--table-cell-border-width: 1px 0;--cover-background-color: hsl(var(--theme-hue), 25%, 60%);--cover-background-image: radial-gradient(ellipse at center 115%, rgba(255, 255, 255, 0.9), transparent);--cover-blockquote-color: var(--strong-color);--cover-heading-color: #fff;--cover-heading-font-size-max: 56;--cover-heading-font-size-min: 34;--cover-heading-font-weight: 200;--navbar-root-color--active: var(--theme-color);--navbar-menu-border-radius: var(--border-radius-m);--navbar-menu-root-background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='9.6' height='6' viewBox='0 0 9.6 6'%3E%3Cpath d='M1.5 1.5l3.3 3 3.3-3' stroke-width='1.5' stroke='rgb%28179, 179, 179%29' fill='none' stroke-linecap='square' stroke-linejoin='miter' vector-effect='non-scaling-stroke'/%3E%3C/svg%3E") right no-repeat;--navbar-menu-root-padding: 0 18px 0 0;--search-input-background-color: #fff;--search-input-background-image: url("data:image/svg+xml,%3Csvg height='20px' width='20px' viewBox='0 0 24 24' fill='none' stroke='rgba(0, 0, 0, 0.3)' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round' preserveAspectRatio='xMidYMid meet' xmlns='http://www.w3.org/2000/svg'%3E%3Ccircle cx='10.5' cy='10.5' r='7.5' vector-effect='non-scaling-stroke'%3E%3C/circle%3E%3Cline x1='21' y1='21' x2='15.8' y2='15.8' vector-effect='non-scaling-stroke'%3E%3C/line%3E%3C/svg%3E");--search-input-background-position: 21px center;--search-input-border-color: var(--sidebar-border-color);--search-input-border-width: 1px 0;--search-input-margin: 0 -25px;--search-input-padding: 0.65em 1em 0.65em 50px;--search-input-placeholder-color: rgba(0, 0, 0, 0.4);--search-clear-icon-color1: rgba(0, 0, 0, 0.3);--search-result-heading-font-weight: var(--strong-font-weight);--search-result-item-border-color: var(--sidebar-border-color);--search-result-keyword-border-radius: var(--border-radius-s);--sidebar-background: var(--mono-tint3);--sidebar-border-color: var(--mono-tint2);--sidebar-border-width: 0 1px 0 0;--sidebar-name-color: var(--theme-color);--sidebar-name-font-weight: 300;--sidebar-nav-strong-border-width: 0 0 1px 0;--sidebar-nav-strong-font-size: smaller;--sidebar-nav-strong-margin: 2em -25px 0.75em 0;--sidebar-nav-strong-padding: 0.25em 0 0.75em 0;--sidebar-nav-strong-text-transform: uppercase;--sidebar-nav-link-border-color: transparent;--sidebar-nav-link-border-color--active: var(--theme-color);--sidebar-nav-link-border-width: 0 4px 0 0;--sidebar-nav-link-color--active: var(--theme-color);--sidebar-nav-link-margin: 0 -25px 0 0;--sidebar-nav-link-text-decoration: none;--sidebar-nav-link-text-decoration--active: none;--sidebar-nav-link-text-decoration--hover: underline;--sidebar-nav-link-before-content-l3: '-';--sidebar-nav-pagelink-background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='7' height='11.2' viewBox='0 0 7 11.2'%3E%3Cpath d='M1.5 1.5l4 4.1 -4 4.1' stroke-width='1.5' stroke='rgb%28179, 179, 179%29' fill='none' stroke-linecap='square' stroke-linejoin='miter' vector-effect='non-scaling-stroke'/%3E%3C/svg%3E");--sidebar-nav-pagelink-background-image--active: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='11.2' height='7' viewBox='0 0 11.2 7'%3E%3Cpath d='M1.5 1.5l4.1 4 4.1-4' stroke-width='1.5' stroke='rgb%2811, 135, 218%29' fill='none' stroke-linecap='square' stroke-linejoin='miter' vector-effect='non-scaling-stroke'/%3E%3C/svg%3E");--sidebar-nav-pagelink-background-image--collapse: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='7' height='11.2' viewBox='0 0 7 11.2'%3E%3Cpath d='M1.5 1.5l4 4.1 -4 4.1' stroke-width='1.5' stroke='rgb%2811, 135, 218%29' fill='none' stroke-linecap='square' stroke-linejoin='miter' vector-effect='non-scaling-stroke'/%3E%3C/svg%3E");--sidebar-nav-pagelink-background-image--loaded: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='11.2' height='7' viewBox='0 0 11.2 7'%3E%3Cpath d='M1.5 1.5l4.1 4 4.1-4' stroke-width='1.5' stroke='rgb%2811, 135, 218%29' fill='none' stroke-linecap='square' stroke-linejoin='miter' vector-effect='non-scaling-stroke'/%3E%3C/svg%3E");--sidebar-nav-pagelink-background-position: 3px center;--sidebar-nav-pagelink-background-position--active: left center;--sidebar-nav-pagelink-background-position--collapse: var(--sidebar-nav-pagelink-background-position);--sidebar-nav-pagelink-background-position--loaded: var(--sidebar-nav-pagelink-background-position--active);--sidebar-nav-pagelink-padding: 0.25em 0 0.25em 20px;--sidebar-nav-pagelink-transition: none;--sidebar-toggle-background: var(--sidebar-border-color);--sidebar-toggle-border-radius: 0 var(--border-radius-s) var(--border-radius-s) 0;--sidebar-toggle-width: 32px}:root{--code-theme-background: #222;--code-theme-comment: #516e7a;--code-theme-function: #f07178;--code-theme-keyword: #c2e78c;--code-theme-operator: #ffcb6b;--code-theme-punctuation: #89ddff;--code-theme-selector: #ffcb6b;--code-theme-tag: #f07178;--code-theme-text: #f3f3f3;--code-theme-variable: #ffcb6b}:root{--mono-hue: 201;--mono-saturation: 18%;--mono-shade3: hsl(var(--mono-hue), var(--mono-saturation), 13%);--mono-shade2: hsl(var(--mono-hue), var(--mono-saturation), 15%);--mono-shade1: hsl(var(--mono-hue), var(--mono-saturation), 17%);--mono-base: hsl(var(--mono-hue), var(--mono-saturation), 19%);--mono-tint1: hsl(var(--mono-hue), var(--mono-saturation), 25%);--mono-tint2: hsl(var(--mono-hue), var(--mono-saturation), 35%);--mono-tint3: hsl(var(--mono-hue), var(--mono-saturation), 43%);--spinner-track-color: rgba(255, 255, 255, 0.15);--base-background-color: var(--mono-base);--base-color: #d3d3d3;--hr-border: 1px solid var(--mono-tint2);--mark-background: #ffcb6b;--mark-color: var(--base-background-color);--selection-color: rgba(94, 131, 175, 0.75);--blockquote-background: var(--mono-shade2);--code-inline-background: var(--mono-tint1);--code-theme-background: var(--mono-shade2);--heading-color: #fff;--heading-h2-border-color: var(--mono-tint2);--kbd-background: var(--mono-shade2);--kbd-border: none;--kbd-color: var(--strong-color);--notice-important-background: var(--mono-shade2);--notice-tip-background: var(--mono-shade2);--table-cell-border-color: var(--mono-tint1);--table-row-odd-background: var(--mono-shade2);--cover-background-color: var(--base-background-color);--cover-background-image: radial-gradient(ellipse at center bottom, var(--mono-tint3), transparent);--cover-blockquote-color: var(--mark-background);--cover-button-border: 1px solid var(--mono-tint3);--cover-button-color: #fff;--navbar-menu-background: var(--mono-tint1);--navbar-menu-box-shadow: rgba(0,0,0,0.05) 0px 0px 1px, rgba(0,0,0,0.05) 0px 1px 2px, rgba(0,0,0,0.05) 0px 2px 4px, rgba(0,0,0,0.05) 0px 4px 8px, rgba(0,0,0,0.05) 0px 8px 16px, rgba(0,0,0,0.05) 0px 16px 32px;--copycode-background: var(--mono-tint1);--copycode-color: #fff;--docsifytabs-border-color: var(--mono-tint2);--docsifytabs-tab-background: var(--mono-shade1);--docsifytabs-tab-color: var(--mono-tint2);--pagination-border-top: 1px solid var(--mono-tint2);--pagination-title-color: #fff;--search-input-background-color: var(--mono-shade2);--search-input-background-image: url("data:image/svg+xml,%3Csvg height='20px' width='20px' viewBox='0 0 24 24' fill='none' stroke='rgba(255, 255, 255, 0.3)' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round' preserveAspectRatio='xMidYMid meet' xmlns='http://www.w3.org/2000/svg'%3E%3Ccircle cx='10.5' cy='10.5' r='7.5' vector-effect='non-scaling-stroke'%3E%3C/circle%3E%3Cline x1='21' y1='21' x2='15.8' y2='15.8' vector-effect='non-scaling-stroke'%3E%3C/line%3E%3C/svg%3E");--search-input-border-color: var(--mono-tint1);--search-input-placeholder-color: rgba(255, 255, 255, 0.4);--search-clear-icon-color1: rgba(255, 255, 255, 0.3);--sidebar-background: var(--mono-shade1);--sidebar-border-color: var(--mono-tint1);--sidebar-nav-pagelink-background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='7' height='11.2' viewBox='0 0 7 11.2'%3E%3Cpath d='M1.5 1.5l4 4.1 -4 4.1' stroke-width='1.5' stroke='rgb%2873, 93, 104%29' fill='none' stroke-linecap='square' stroke-linejoin='miter' vector-effect='non-scaling-stroke'/%3E%3C/svg%3E")}
+.github-corner{position:absolute;z-index:40;top:0;right:0;border-bottom:0;text-decoration:none}.github-corner svg{height:70px;width:70px;fill:var(--theme-color);color:var(--base-background-color)}.github-corner:hover .octo-arm{-webkit-animation:octocat-wave 560ms ease-in-out;animation:octocat-wave 560ms ease-in-out}@-webkit-keyframes octocat-wave{0%,100%{transform:rotate(0)}20%,60%{transform:rotate(-25deg)}40%,80%{transform:rotate(10deg)}}@keyframes octocat-wave{0%,100%{transform:rotate(0)}20%,60%{transform:rotate(-25deg)}40%,80%{transform:rotate(10deg)}}.progress{position:fixed;z-index:2147483647;top:0;left:0;right:0;height:3px;width:0;background-color:var(--theme-color);transition:width var(--duration-fast),opacity calc(var(--duration-fast) * 2)}body.ready-transition:after,body.ready-transition>*:not(.progress){opacity:0;transition:opacity var(--spinner-transition-duration)}body.ready-transition:after{content:'';position:absolute;z-index:1000;top:calc(50% - (var(--spinner-size) / 2));left:calc(50% - (var(--spinner-size) / 2));height:var(--spinner-size);width:var(--spinner-size);border:var(--spinner-track-width, 0) solid var(--spinner-track-color);border-left-color:var(--theme-color);border-left-color:var(--theme-color);border-radius:50%;-webkit-animation:spinner var(--duration-slow) infinite linear;animation:spinner var(--duration-slow) infinite linear}body.ready-transition.ready-spinner:after{opacity:1}body.ready-transition.ready-fix:after{opacity:0}body.ready-transition.ready-fix>*:not(.progress){opacity:1;transition-delay:var(--spinner-transition-duration)}@-webkit-keyframes spinner{0%{transform:rotate(0deg)}100%{transform:rotate(360deg)}}@keyframes spinner{0%{transform:rotate(0deg)}100%{transform:rotate(360deg)}}*,*:before,*:after{box-sizing:inherit;font-size:inherit;-webkit-overflow-scrolling:touch;-webkit-tap-highlight-color:rgba(0,0,0,0);-webkit-text-size-adjust:none;-webkit-touch-callout:none}:root{box-sizing:border-box;background-color:var(--base-background-color);font-size:var(--base-font-size);font-weight:var(--base-font-weight);line-height:var(--base-line-height);letter-spacing:var(--base-letter-spacing);color:var(--base-color);-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;font-smoothing:antialiased}html,button,input,optgroup,select,textarea{font-family:var(--base-font-family)}button,input,optgroup,select,textarea{font-size:100%;margin:0}a{text-decoration:none;-webkit-text-decoration-skip:ink;text-decoration-skip-ink:auto}body{margin:0}hr{height:0;margin:2em 0;border:none;border-bottom:var(--hr-border, 0)}img{max-width:100%;border:0}main{display:block}main.hidden{display:none}mark{background:var(--mark-background);color:var(--mark-color)}pre{font-family:var(--pre-font-family);font-size:var(--pre-font-size);font-weight:var(--pre-font-weight);line-height:var(--pre-line-height)}small{display:inline-block;font-size:var(--small-font-size)}strong{font-weight:var(--strong-font-weight);color:var(--strong-color, currentColor)}sub,sup{font-size:var(--subsup-font-size);line-height:0;position:relative;vertical-align:baseline}sub{bottom:-0.25em}sup{top:-0.5em}body:not([data-platform^="Mac"]) *{scrollbar-color:hsla(var(--mono-hue), var(--mono-saturation), 50%, 0.3) hsla(var(--mono-hue), var(--mono-saturation), 50%, 0.1);scrollbar-width:thin}body:not([data-platform^="Mac"]) * ::-webkit-scrollbar{width:5px;height:5px}body:not([data-platform^="Mac"]) * ::-webkit-scrollbar-thumb{background:hsla(var(--mono-hue), var(--mono-saturation), 50%, 0.3)}body:not([data-platform^="Mac"]) * ::-webkit-scrollbar-track{background:hsla(var(--mono-hue), var(--mono-saturation), 50%, 0.1)}::-moz-selection{background:var(--selection-color)}::selection{background:var(--selection-color)}.emoji{height:var(--emoji-size);vertical-align:middle}.task-list-item{list-style:none}.task-list-item input{margin-right:0.5em;margin-left:0;vertical-align:0.075em}.markdown-section code[class*="lang-"],.markdown-section pre[data-lang]{font-family:var(--code-font-family);font-size:var(--code-font-size);font-weight:var(--code-font-weight);letter-spacing:normal;line-height:var(--code-block-line-height);-moz-tab-size:var(--code-tab-size);-o-tab-size:var(--code-tab-size);tab-size:var(--code-tab-size);text-align:left;white-space:pre;word-spacing:normal;word-wrap:normal;word-break:normal;-webkit-hyphens:none;-ms-hyphens:none;hyphens:none}.markdown-section pre[data-lang]{position:relative;overflow:hidden;margin:var(--code-block-margin);padding:0;border-radius:var(--code-block-border-radius)}.markdown-section pre[data-lang]::after{content:attr(data-lang);position:absolute;top:0.75em;right:0.75em;opacity:0.6;color:inherit;font-size:var(--font-size-s);line-height:1}.markdown-section pre[data-lang] code{display:block;overflow:auto;padding:var(--code-block-padding)}code[class*="lang-"],pre[data-lang]{color:var(--code-theme-text)}pre[data-lang]::-moz-selection,pre[data-lang] ::-moz-selection,code[class*="lang-"]::-moz-selection,code[class*="lang-"] ::-moz-selection{background:var(--code-theme-selection, var(--selection-color))}pre[data-lang]::-moz-selection, pre[data-lang] ::-moz-selection, code[class*="lang-"]::-moz-selection, code[class*="lang-"] ::-moz-selection{background:var(--code-theme-selection, var(--selection-color))}pre[data-lang]::selection,pre[data-lang] ::selection,code[class*="lang-"]::selection,code[class*="lang-"] ::selection{background:var(--code-theme-selection, var(--selection-color))}:not(pre)>code[class*="lang-"],pre[data-lang]{background:var(--code-theme-background)}.namespace{opacity:0.7}.token.comment,.token.prolog,.token.doctype,.token.cdata{color:var(--code-theme-comment)}.token.punctuation{color:var(--code-theme-punctuation)}.token.property,.token.tag,.token.boolean,.token.number,.token.constant,.token.symbol,.token.deleted{color:var(--code-theme-tag)}.token.selector,.token.attr-name,.token.string,.token.char,.token.builtin,.token.inserted{color:var(--code-theme-selector)}.token.operator,.token.entity,.token.url,.language-css .token.string,.style .token.string{color:var(--code-theme-operator)}.token.atrule,.token.attr-value,.token.keyword{color:var(--code-theme-keyword)}.token.function{color:var(--code-theme-function)}.token.regex,.token.important,.token.variable{color:var(--code-theme-variable)}.token.important,.token.bold{font-weight:bold}.token.italic{font-style:italic}.token.entity{cursor:help}.markdown-section{position:relative;max-width:var(--content-max-width);margin:0 auto;padding:2rem 45px}.app-nav:not(:empty) ~ main .markdown-section{padding-top:3.5rem}.markdown-section figure,.markdown-section p,.markdown-section ol,.markdown-section ul{margin:1em 0}.markdown-section ol,.markdown-section ul{padding-left:1.5rem}.markdown-section ol ol,.markdown-section ol ul,.markdown-section ul ol,.markdown-section ul ul{margin-top:0.15rem;margin-bottom:0.15rem}.markdown-section a{border-bottom:var(--link-border-bottom);color:var(--link-color);-webkit-text-decoration:var(--link-text-decoration);text-decoration:var(--link-text-decoration);-webkit-text-decoration-color:var(--link-text-decoration-color);text-decoration-color:var(--link-text-decoration-color)}.markdown-section a:hover{border-bottom:var(--link-border-bottom--hover, var(--link-border-bottom, 0));color:var(--link-color--hover, var(--link-color));-webkit-text-decoration:var(--link-text-decoration--hover, var(--link-text-decoration));text-decoration:var(--link-text-decoration--hover, var(--link-text-decoration));-webkit-text-decoration-color:var(--link-text-decoration-color--hover, var(--link-text-decoration-color));text-decoration-color:var(--link-text-decoration-color--hover, var(--link-text-decoration-color))}.markdown-section a.anchor{border-bottom:0;color:inherit;text-decoration:none}.markdown-section a.anchor:hover{text-decoration:underline}.markdown-section blockquote{overflow:visible;margin:2em 0;padding:1.5em;border-width:var(--blockquote-border-width, 0);border-style:var(--blockquote-border-style);border-color:var(--blockquote-border-color);border-radius:var(--blockquote-border-radius);background:var(--blockquote-background);color:var(--blockquote-color);font-family:var(--blockquote-font-family);font-size:var(--blockquote-font-size);font-style:var(--blockquote-font-style);font-weight:var(--blockquote-font-weight);quotes:"“" "”" "‘" "’"}.markdown-section blockquote em{font-family:var(--blockquote-em-font-family);font-size:var(--blockquote-em-font-size);font-style:var(--blockquote-em-font-style);font-weight:var(--blockquote-em-font-weight)}.markdown-section blockquote p:first-child{margin-top:0}.markdown-section blockquote p:first-child:before,.markdown-section blockquote p:first-child:after{color:var(--blockquote-quotes-color);font-family:var(--blockquote-quotes-font-family);font-size:var(--blockquote-quotes-font-size);line-height:0}.markdown-section blockquote p:first-child:before{content:var(--blockquote-quotes-open);margin-right:0.15em;vertical-align:-0.45em}.markdown-section blockquote p:first-child:after{content:var(--blockquote-quotes-close);margin-left:0.15em;vertical-align:-0.55em}.markdown-section blockquote p:last-child{margin-bottom:0}.markdown-section code{font-family:var(--code-font-family);font-size:var(--code-font-size);font-weight:var(--code-font-weight);line-height:inherit}.markdown-section code:not([class*="lang-"]):not([class*="language-"]){margin:var(--code-inline-margin);padding:var(--code-inline-padding);border-radius:var(--code-inline-border-radius);background:var(--code-inline-background);color:var(--code-inline-color, currentColor);white-space:nowrap}.markdown-section h1:first-child,.markdown-section h2:first-child,.markdown-section h3:first-child,.markdown-section h4:first-child,.markdown-section h5:first-child,.markdown-section h6:first-child{margin-top:0}.markdown-section h1 a[data-id],.markdown-section h2 a[data-id],.markdown-section h3 a[data-id],.markdown-section h4 a[data-id],.markdown-section h5 a[data-id],.markdown-section h6 a[data-id]{display:inline-block}.markdown-section h1 code,.markdown-section h2 code,.markdown-section h3 code,.markdown-section h4 code,.markdown-section h5 code,.markdown-section h6 code{font-size:0.875em}.markdown-section h1+h2,.markdown-section h1+h3,.markdown-section h1+h4,.markdown-section h1+h5,.markdown-section h1+h6,.markdown-section h2+h3,.markdown-section h2+h4,.markdown-section h2+h5,.markdown-section h2+h6,.markdown-section h3+h4,.markdown-section h3+h5,.markdown-section h3+h6,.markdown-section h4+h5,.markdown-section h4+h6,.markdown-section h5+h6{margin-top:1rem}.markdown-section h1{margin:var(--heading-h1-margin, var(--heading-margin));padding:var(--heading-h1-padding, var(--heading-padding));border-width:var(--heading-h1-border-width, 0);border-style:var(--heading-h1-border-style);border-color:var(--heading-h1-border-color);font-family:var(--heading-h1-font-family, var(--heading-font-family));font-size:var(--heading-h1-font-size);font-weight:var(--heading-h1-font-weight, var(--heading-font-weight));line-height:var(--base-line-height);color:var(--heading-h1-color, var(--heading-color))}.markdown-section h2{margin:var(--heading-h2-margin, var(--heading-margin));padding:var(--heading-h2-padding, var(--heading-padding));border-width:var(--heading-h2-border-width, 0);border-style:var(--heading-h2-border-style);border-color:var(--heading-h2-border-color);font-family:var(--heading-h2-font-family, var(--heading-font-family));font-size:var(--heading-h2-font-size);font-weight:var(--heading-h2-font-weight, var(--heading-font-weight));line-height:var(--base-line-height);color:var(--heading-h2-color, var(--heading-color))}.markdown-section h3{margin:var(--heading-h3-margin, var(--heading-margin));padding:var(--heading-h3-padding, var(--heading-padding));border-width:var(--heading-h3-border-width, 0);border-style:var(--heading-h3-border-style);border-color:var(--heading-h3-border-color);font-family:var(--heading-h3-font-family, var(--heading-font-family));font-size:var(--heading-h3-font-size);font-weight:var(--heading-h3-font-weight, var(--heading-font-weight));color:var(--heading-h3-color, var(--heading-color))}.markdown-section h4{margin:var(--heading-h4-margin, var(--heading-margin));padding:var(--heading-h4-padding, var(--heading-padding));border-width:var(--heading-h4-border-width, 0);border-style:var(--heading-h4-border-style);border-color:var(--heading-h4-border-color);font-family:var(--heading-h4-font-family, var(--heading-font-family));font-size:var(--heading-h4-font-size);font-weight:var(--heading-h4-font-weight, var(--heading-font-weight));color:var(--heading-h4-color, var(--heading-color))}.markdown-section h5{margin:var(--heading-h5-margin, var(--heading-margin));padding:var(--heading-h5-padding, var(--heading-padding));border-width:var(--heading-h5-border-width, 0);border-style:var(--heading-h5-border-style);border-color:var(--heading-h5-border-color);font-family:var(--heading-h5-font-family, var(--heading-font-family));font-size:var(--heading-h5-font-size);font-weight:var(--heading-h5-font-weight, var(--heading-font-weight));color:var(--heading-h5-color, var(--heading-color))}.markdown-section h6{margin:var(--heading-h6-margin, var(--heading-margin));padding:var(--heading-h6-padding, var(--heading-padding));border-width:var(--heading-h6-border-width, 0);border-style:var(--heading-h6-border-style);border-color:var(--heading-h6-border-color);font-family:var(--heading-h6-font-family, var(--heading-font-family));font-size:var(--heading-h6-font-size);font-weight:var(--heading-h6-font-weight, var(--heading-font-weight));color:var(--heading-h6-color, var(--heading-color))}.markdown-section iframe{margin:1em 0}.markdown-section img{max-width:100%}.markdown-section kbd{display:inline-block;min-width:var(--kbd-min-width);margin:var(--kbd-margin);padding:var(--kbd-padding);border:var(--kbd-border);border-radius:var(--kbd-border-radius);background:var(--kbd-background);font-family:inherit;font-size:var(--kbd-font-size);text-align:center;letter-spacing:0;line-height:1;color:var(--kbd-color)}.markdown-section kbd+kbd{margin-left:-0.15em}.markdown-section table{display:block;overflow:auto;margin:1rem 0;}.markdown-section th,.markdown-section td{padding:var(--table-cell-padding)}.markdown-section th:not([align]){text-align:center;white-space: nowrap;}.markdown-section thead{border-color:var(--table-head-border-color);border-style:solid;border-width:var(--table-head-border-width, 0);background:var(--table-head-background)}.markdown-section th{font-weight:var(--table-head-font-weight);color:var(--strong-color)}.markdown-section td{border-color:var(--table-cell-border-color);}.markdown-section tbody{border-color:var(--table-body-border-color);border-style:solid;border-width:var(--table-body-border-width, 0)}.markdown-section tbody tr:nth-child(odd){background:var(--table-row-odd-background)}.markdown-section tbody tr:nth-child(even){background:var(--table-row-even-background)}.markdown-section>ul .task-list-item{margin-left:-1.25em}.markdown-section>ul .task-list-item .task-list-item{margin-left:0}.markdown-section .table-wrapper{overflow-x:auto}.markdown-section .table-wrapper table{display:table;width:100%}.markdown-section .table-wrapper td::before{display:none}@media (max-width: 30em){.markdown-section .table-wrapper tbody,.markdown-section .table-wrapper tr,.markdown-section .table-wrapper td{display:block}.markdown-section .table-wrapper th,.markdown-section .table-wrapper td{border:none}.markdown-section .table-wrapper thead{display:none}.markdown-section .table-wrapper tr{border-color:var(--table-cell-border-color);border-style:solid;border-width:var(--table-cell-border-width, 0);padding:var(--table-cell-padding)}.markdown-section .table-wrapper tr:not(:last-child){border-bottom:0}.markdown-section .table-wrapper td{padding:0.15em 0 0.15em 8em}.markdown-section .table-wrapper td::before{display:inline-block;float:left;width:8em;margin-left:-8em;font-weight:bold;text-align:left}}.markdown-section .tip,.markdown-section .warn{position:relative;margin:2em 0;padding:var(--notice-padding);border-width:var(--notice-border-width, 0);border-style:var(--notice-border-style);border-color:var(--notice-border-color);border-radius:var(--notice-border-radius);background:var(--notice-background);font-family:var(--notice-font-family);font-weight:var(--notice-font-weight);color:var(--notice-color)}.markdown-section .tip:before,.markdown-section .warn:before{display:inline-block;position:var(--notice-before-position, relative);top:var(--notice-before-top);left:var(--notice-before-left);height:var(--notice-before-height);width:var(--notice-before-width);margin:var(--notice-before-margin);padding:var(--notice-before-padding);border-radius:var(--notice-before-border-radius);line-height:var(--notice-before-line-height);font-family:var(--notice-before-font-family);font-size:var(--notice-before-font-size);font-weight:var(--notice-before-font-weight);text-align:center}.markdown-section .tip{border-width:var(--notice-important-border-width, var(--notice-border-width, 0));border-style:var(--notice-important-border-style, var(--notice-border-style));border-color:var(--notice-important-border-color, var(--notice-border-color));background:var(--notice-important-background, var(--notice-background));color:var(--notice-important-color, var(--notice-color))}.markdown-section .tip:before{content:var(--notice-important-before-content, var(--notice-before-content));background:var(--notice-important-before-background, var(--notice-before-background));color:var(--notice-important-before-color, var(--notice-before-color))}.markdown-section .warn{border-width:var(--notice-tip-border-width, var(--notice-border-width, 0));border-style:var(--notice-tip-border-style, var(--notice-border-style));border-color:var(--notice-tip-border-color, var(--notice-border-color));background:var(--notice-tip-background, var(--notice-background));color:var(--notice-tip-color, var(--notice-color))}.markdown-section .warn:before{content:var(--notice-tip-before-content, var(--notice-before-content));background:var(--notice-tip-before-background, var(--notice-before-background));color:var(--notice-tip-before-color, var(--notice-before-color))}.cover{display:none;position:relative;z-index:20;min-height:100vh;flex-direction:column;align-items:center;justify-content:center;padding:calc(var(--cover-border-inset, 0px) + var(--cover-border-width, 0px));color:var(--cover-color);text-align:var(--cover-text-align)}@media screen and (-ms-high-contrast: active), screen and (-ms-high-contrast: none){.cover{height:100vh}}.cover:before,.cover:after{content:'';position:absolute}.cover:before{top:0;bottom:0;left:0;right:0;background-blend-mode:var(--cover-background-blend-mode);background-color:var(--cover-background-color);background-image:var(--cover-background-image);background-position:var(--cover-background-position);background-repeat:var(--cover-background-repeat);background-size:var(--cover-background-size)}.cover:after{top:var(--cover-border-inset, 0);bottom:var(--cover-border-inset, 0);left:var(--cover-border-inset, 0);right:var(--cover-border-inset, 0);border-width:var(--cover-border-width, 0);border-style:solid;border-color:var(--cover-border-color)}.cover a{border-bottom:var(--cover-link-border-bottom);color:var(--cover-link-color);-webkit-text-decoration:var(--cover-link-text-decoration);text-decoration:var(--cover-link-text-decoration);-webkit-text-decoration-color:var(--cover-link-text-decoration-color);text-decoration-color:var(--cover-link-text-decoration-color)}.cover a:hover{border-bottom:var(--cover-link-border-bottom--hover, var(--cover-link-border-bottom));color:var(--cover-link-color--hover, var(--cover-link-color));-webkit-text-decoration:var(--cover-link-text-decoration--hover, var(--cover-link-text-decoration));text-decoration:var(--cover-link-text-decoration--hover, var(--cover-link-text-decoration));-webkit-text-decoration-color:var(--cover-link-text-decoration-color--hover, var(--cover-link-text-decoration-color));text-decoration-color:var(--cover-link-text-decoration-color--hover, var(--cover-link-text-decoration-color))}.cover h1{color:var(--cover-heading-color);position:relative;margin:0;font-size:var(--cover-heading-font-size);font-weight:var(--cover-heading-font-weight);line-height:1.2}.cover h1 a,.cover h1 a:hover{display:block;border-bottom:none;color:inherit;text-decoration:none}.cover h1 small{position:absolute;bottom:0;margin-left:0.5em}.cover h1 span{font-size:calc(var(--cover-heading-font-size-min) * 1px)}@media (min-width: 26em){.cover h1 span{font-size:calc((var(--cover-heading-font-size-min) * 1px) + (var(--cover-heading-font-size-max) - var(--cover-heading-font-size-min)) * ((100vw - 420px) / (1024 - 420)))}}@media (min-width: 64em){.cover h1 span{font-size:calc(var(--cover-heading-font-size-max) * 1px)}}.cover blockquote{margin:0;color:var(--cover-blockquote-color);font-size:var(--cover-blockquote-font-size)}.cover blockquote a{color:inherit}.cover ul{padding:0;list-style-type:none}.cover .cover-main{position:relative;z-index:1;max-width:var(--cover-max-width);margin:var(--cover-margin);padding:0 45px}.cover .cover-main>p:last-child{margin:1.25em -.25em}.cover .cover-main>p:last-child a{display:block;margin:.375em .25em;padding:var(--cover-button-padding);border:var(--cover-button-border);border-radius:var(--cover-button-border-radius);box-shadow:var(--cover-button-box-shadow);background:var(--cover-button-background);text-align:center;-webkit-text-decoration:var(--cover-button-text-decoration);text-decoration:var(--cover-button-text-decoration);-webkit-text-decoration-color:var(--cover-button-text-decoration-color);text-decoration-color:var(--cover-button-text-decoration-color);color:var(--cover-button-color);white-space:nowrap;transition:var(--cover-button-transition)}.cover .cover-main>p:last-child a:hover{border:var(--cover-button-border--hover, var(--cover-button-border));box-shadow:var(--cover-button-box-shadow--hover, var(--cover-button-box-shadow));background:var(--cover-button-background--hover, var(--cover-button-background));-webkit-text-decoration:var(--cover-button-text-decoration--hover, var(--cover-button-text-decoration));text-decoration:var(--cover-button-text-decoration--hover, var(--cover-button-text-decoration));-webkit-text-decoration-color:var(--cover-button-text-decoration-color--hover, var(--cover-button-text-decoration-color));text-decoration-color:var(--cover-button-text-decoration-color--hover, var(--cover-button-text-decoration-color));color:var(--cover-button-color--hover, var(--cover-button-color))}.cover .cover-main>p:last-child a:first-child{border:var(--cover-button-primary-border, var(--cover-button-border));box-shadow:var(--cover-button-primary-box-shadow, var(--cover-button-box-shadow));background:var(--cover-button-primary-background, var(--cover-button-background));-webkit-text-decoration:var(--cover-button-primary-text-decoration, var(--cover-button-text-decoration));text-decoration:var(--cover-button-primary-text-decoration, var(--cover-button-text-decoration));-webkit-text-decoration-color:var(--cover-button-primary-text-decoration-color, var(--cover-button-text-decoration-color));text-decoration-color:var(--cover-button-primary-text-decoration-color, var(--cover-button-text-decoration-color));color:var(--cover-button-primary-color, var(--cover-button-color))}.cover .cover-main>p:last-child a:first-child:hover{border:var(--cover-button-primary-border--hover, var(--cover-button-border--hover, var(--cover-button-primary-border, var(--cover-button-border))));box-shadow:var(--cover-button-primary-box-shadow--hover, var(--cover-button-box-shadow--hover, var(--cover-button-primary-box-shadow, var(--cover-button-box-shadow))));background:var(--cover-button-primary-background--hover, var(--cover-button-background--hover, var(--cover-button-primary-background, var(--cover-button-background))));-webkit-text-decoration:var(--cover-button-primary-text-decoration--hover, var(--cover-button-text-decoration--hover, var(--cover-button-primary-text-decoration, var(--cover-button-text-decoration))));text-decoration:var(--cover-button-primary-text-decoration--hover, var(--cover-button-text-decoration--hover, var(--cover-button-primary-text-decoration, var(--cover-button-text-decoration))));-webkit-text-decoration-color:var(--cover-button-primary-text-decoration-color--hover, var(--cover-button-text-decoration-color--hover, var(--cover-button-primary-text-decoration-color, var(--cover-button-text-decoration-color))));text-decoration-color:var(--cover-button-primary-text-decoration-color--hover, var(--cover-button-text-decoration-color--hover, var(--cover-button-primary-text-decoration-color, var(--cover-button-text-decoration-color))));color:var(--cover-button-primary-color--hover, var(--cover-button-color--hover, var(--cover-button-primary-color, var(--cover-button-color))))}@media (min-width: 30.01em){.cover .cover-main>p:last-child a{display:inline-block}}.cover .mask{visibility:var(--cover-background-mask-visibility, hidden);position:absolute;top:0;bottom:0;left:0;right:0;background-color:var(--cover-background-mask-color);opacity:var(--cover-background-mask-opacity)}.cover.has-mask .mask{visibility:visible}.cover.show{display:flex}.app-nav{position:absolute;z-index:30;top:calc(35px - (0.5em * var(--base-line-height)));left:45px;right:80px;text-align:right}.app-nav.no-badge{right:45px}.app-nav li>img,.app-nav li>a>img{margin-top:-0.25em;vertical-align:middle}.app-nav li>img:first-child,.app-nav li>a>img:first-child{margin-right:0.5em}.app-nav ul,.app-nav li{margin:0;padding:0;list-style:none}.app-nav li{position:relative}.app-nav li a{display:block;line-height:1;transition:var(--navbar-root-transition)}.app-nav>ul>li{display:inline-block;margin:var(--navbar-root-margin)}.app-nav>ul>li:first-child{margin-left:0}.app-nav>ul>li:last-child{margin-right:0}.app-nav>ul>li>a,.app-nav>ul>li>span{padding:var(--navbar-root-padding);border-width:var(--navbar-root-border-width, 0);border-style:var(--navbar-root-border-style);border-color:var(--navbar-root-border-color);border-radius:var(--navbar-root-border-radius);background:var(--navbar-root-background);color:var(--navbar-root-color);-webkit-text-decoration:var(--navbar-root-text-decoration);text-decoration:var(--navbar-root-text-decoration);-webkit-text-decoration-color:var(--navbar-root-text-decoration-color);text-decoration-color:var(--navbar-root-text-decoration-color)}.app-nav>ul>li>a:hover,.app-nav>ul>li>span:hover{background:var(--navbar-root-background--hover, var(--navbar-root-background));border-style:var(--navbar-root-border-style--hover, var(--navbar-root-border-style));border-color:var(--navbar-root-border-color--hover, var(--navbar-root-border-color));color:var(--navbar-root-color--hover, var(--navbar-root-color));-webkit-text-decoration:var(--navbar-root-text-decoration--hover, var(--navbar-root-text-decoration));text-decoration:var(--navbar-root-text-decoration--hover, var(--navbar-root-text-decoration));-webkit-text-decoration-color:var(--navbar-root-text-decoration-color--hover, var(--navbar-root-text-decoration-color));text-decoration-color:var(--navbar-root-text-decoration-color--hover, var(--navbar-root-text-decoration-color))}.app-nav>ul>li>a:not(:last-child),.app-nav>ul>li>span:not(:last-child){padding:var(--navbar-menu-root-padding, var(--navbar-root-padding));background:var(--navbar-menu-root-background, var(--navbar-root-background))}.app-nav>ul>li>a:not(:last-child):hover,.app-nav>ul>li>span:not(:last-child):hover{background:var(--navbar-menu-root-background--hover, var(--navbar-menu-root-background, var(--navbar-root-background--hover, var(--navbar-root-background))))}.app-nav>ul>li>a.active{background:var(--navbar-root-background--active, var(--navbar-root-background));border-style:var(--navbar-root-border-style--active, var(--navbar-root-border-style));border-color:var(--navbar-root-border-color--active, var(--navbar-root-border-color));color:var(--navbar-root-color--active, var(--navbar-root-color));-webkit-text-decoration:var(--navbar-root-text-decoration--active, var(--navbar-root-text-decoration));text-decoration:var(--navbar-root-text-decoration--active, var(--navbar-root-text-decoration));-webkit-text-decoration-color:var(--navbar-root-text-decoration-color--active, var(--navbar-root-text-decoration-color));text-decoration-color:var(--navbar-root-text-decoration-color--active, var(--navbar-root-text-decoration-color))}.app-nav>ul>li>a.active:not(:last-child):hover{background:var(--navbar-menu-root-background--active, var(--navbar-menu-root-background, var(--navbar-root-background--active, var(--navbar-root-background))))}.app-nav>ul>li ul{visibility:hidden;position:absolute;top:100%;right:50%;overflow-y:auto;box-sizing:border-box;max-height:calc(50vh);padding:var(--navbar-menu-padding);border-width:var(--navbar-menu-border-width, 0);border-style:solid;border-color:var(--navbar-menu-border-color);border-radius:var(--navbar-menu-border-radius);background:var(--navbar-menu-background);box-shadow:var(--navbar-menu-box-shadow);text-align:left;white-space:nowrap;opacity:0;transform:translate(50%, -0.35em);transition:var(--navbar-menu-transition)}.app-nav>ul>li ul li{white-space:nowrap}.app-nav>ul>li ul a{margin:var(--navbar-menu-link-margin);padding:var(--navbar-menu-link-padding);border-width:var(--navbar-menu-link-border-width, 0);border-style:var(--navbar-menu-link-border-style);border-color:var(--navbar-menu-link-border-color);border-radius:var(--navbar-menu-link-border-radius);background:var(--navbar-menu-link-background);color:var(--navbar-menu-link-color);-webkit-text-decoration:var(--navbar-menu-link-text-decoration);text-decoration:var(--navbar-menu-link-text-decoration);-webkit-text-decoration-color:var(--navbar-menu-link-text-decoration-color);text-decoration-color:var(--navbar-menu-link-text-decoration-color)}.app-nav>ul>li ul a:hover{background:var(--navbar-menu-link-background--hover, var(--navbar-menu-link-background));border-style:var(--navbar-menu-link-border-style--hover, var(--navbar-menu-link-border-style));border-color:var(--navbar-menu-link-border-color--hover, var(--navbar-menu-link-border-color));color:var(--navbar-menu-link-color--hover, var(--navbar-menu-link-color));-webkit-text-decoration:var(--navbar-menu-link-text-decoration--hover, var(--navbar-menu-link-text-decoration));text-decoration:var(--navbar-menu-link-text-decoration--hover, var(--navbar-menu-link-text-decoration));-webkit-text-decoration-color:var(--navbar-menu-link-text-decoration-color--hover, var(--navbar-menu-link-text-decoration-color));text-decoration-color:var(--navbar-menu-link-text-decoration-color--hover, var(--navbar-menu-link-text-decoration-color))}.app-nav>ul>li ul a.active{background:var(--navbar-menu-link-background--active, var(--navbar-menu-link-background));border-style:var(--navbar-menu-link-border-style--active, var(--navbar-menu-link-border-style));border-color:var(--navbar-menu-link-border-color--active, var(--navbar-menu-link-border-color));color:var(--navbar-menu-link-color--active, var(--navbar-menu-link-color));-webkit-text-decoration:var(--navbar-menu-link-text-decoration--active, var(--navbar-menu-link-text-decoration));text-decoration:var(--navbar-menu-link-text-decoration--active, var(--navbar-menu-link-text-decoration));-webkit-text-decoration-color:var(--navbar-menu-link-text-decoration-color--active, var(--navbar-menu-link-text-decoration-color));text-decoration-color:var(--navbar-menu-link-text-decoration-color--active, var(--navbar-menu-link-text-decoration-color))}.app-nav>ul>li:hover ul,.app-nav>ul>li:focus ul,.app-nav>ul>li.focus-within ul{visibility:visible;opacity:1;transform:translate(50%, 0)}@media (min-width: 48em){nav.app-nav{margin-left:var(--sidebar-width)}}main{position:relative;overflow-x:hidden;min-height:100vh}.sidebar,.sidebar-toggle,.sidebar+.content{transition:all var(--sidebar-transition-duration) ease-out}@media (min-width: 48em){.sidebar+.content{margin-left:var(--sidebar-width)}}.sidebar{display:flex;flex-direction:column;position:fixed;z-index:10;top:0;right:100%;overflow-x:hidden;overflow-y:auto;height:100vh;width:var(--sidebar-width);padding:var(--sidebar-padding);border-width:var(--sidebar-border-width);border-style:solid;border-color:var(--sidebar-border-color);background:var(--sidebar-background)}.sidebar>h1{margin:0;margin:var(--sidebar-name-margin);padding:var(--sidebar-name-padding);background:var(--sidebar-name-background);color:var(--sidebar-name-color);font-family:var(--sidebar-name-font-family);font-size:var(--sidebar-name-font-size);font-weight:var(--sidebar-name-font-weight);text-align:var(--sidebar-name-text-align)}.sidebar>h1 img{max-width:100%}.sidebar>h1 .app-name-link{color:var(--sidebar-name-color)}body:not([data-platform^="Mac"]) .sidebar::-webkit-scrollbar{width:5px}body:not([data-platform^="Mac"]) .sidebar::-webkit-scrollbar-thumb{border-radius:50vw}@media (min-width: 48em){.sidebar{position:absolute;transform:translateX(var(--sidebar-width))}}@media print{.sidebar{display:none}}.sidebar-nav,.sidebar nav{order:1;margin:var(--sidebar-nav-margin);padding:var(--sidebar-nav-padding);background:var(--sidebar-nav-background)}.sidebar-nav ul,.sidebar nav ul{margin:0;padding:0;list-style:none}.sidebar-nav ul ul,.sidebar nav ul ul{margin-left:var(--sidebar-nav-indent)}.sidebar-nav a,.sidebar nav a{display:block;overflow:hidden;margin:var(--sidebar-nav-link-margin);padding:var(--sidebar-nav-link-padding);border-width:var(--sidebar-nav-link-border-width, 0);border-style:var(--sidebar-nav-link-border-style);border-color:var(--sidebar-nav-link-border-color);border-radius:var(--sidebar-nav-link-border-radius);background-color:var(--sidebar-nav-link-background-color);background-image:var(--sidebar-nav-link-background-image);background-position:var(--sidebar-nav-link-background-position);background-repeat:var(--sidebar-nav-link-background-repeat);background-size:var(--sidebar-nav-link-background-size);color:var(--sidebar-nav-link-color);font-weight:var(--sidebar-nav-link-font-weight);white-space:nowrap;-webkit-text-decoration:var(--sidebar-nav-link-text-decoration);text-decoration:var(--sidebar-nav-link-text-decoration);-webkit-text-decoration-color:var(--sidebar-nav-link-text-decoration-color);text-decoration-color:var(--sidebar-nav-link-text-decoration-color);text-overflow:ellipsis;transition:var(--sidebar-nav-link-transition)}.sidebar-nav a img,.sidebar nav a img{margin-top:-0.25em;vertical-align:middle}.sidebar-nav a img:first-child,.sidebar nav a img:first-child{margin-right:0.5em}.sidebar-nav a:hover,.sidebar nav a:hover{border-width:var(--sidebar-nav-link-border-width--hover, var(--sidebar-nav-link-border-width, 0));border-style:var(--sidebar-nav-link-border-style--hover, var(--sidebar-nav-link-border-style));border-color:var(--sidebar-nav-link-border-color--hover, var(--sidebar-nav-link-border-color));background-color:var(--sidebar-nav-link-background-color--hover, var(--sidebar-nav-link-background-color));background-image:var(--sidebar-nav-link-background-image--hover, var(--sidebar-nav-link-background-image));background-position:var(--sidebar-nav-link-background-position--hover, var(--sidebar-nav-link-background-position));background-size:var(--sidebar-nav-link-background-size--hover, var(--sidebar-nav-link-background-size));color:var(--sidebar-nav-link-color--hover, var(--sidebar-nav-link-color));font-weight:var(--sidebar-nav-link-font-weight--hover, var(--sidebar-nav-link-font-weight));-webkit-text-decoration:var(--sidebar-nav-link-text-decoration--hover, var(--sidebar-nav-link-text-decoration));text-decoration:var(--sidebar-nav-link-text-decoration--hover, var(--sidebar-nav-link-text-decoration));-webkit-text-decoration-color:var(--sidebar-nav-link-text-decoration-color);text-decoration-color:var(--sidebar-nav-link-text-decoration-color)}.sidebar-nav ul>li>span,.sidebar-nav ul>li>strong,.sidebar nav ul>li>span,.sidebar nav ul>li>strong{display:block;margin:var(--sidebar-nav-strong-margin);padding:var(--sidebar-nav-strong-padding);border-width:var(--sidebar-nav-strong-border-width, 0);border-style:solid;border-color:var(--sidebar-nav-strong-border-color);color:var(--sidebar-nav-strong-color);font-size:var(--sidebar-nav-strong-font-size);font-weight:var(--sidebar-nav-strong-font-weight);text-transform:var(--sidebar-nav-strong-text-transform)}.sidebar-nav ul>li>span+ul,.sidebar-nav ul>li>strong+ul,.sidebar nav ul>li>span+ul,.sidebar nav ul>li>strong+ul{margin-left:0}.sidebar-nav ul>li:first-child>span,.sidebar-nav ul>li:first-child>strong,.sidebar nav ul>li:first-child>span,.sidebar nav ul>li:first-child>strong{margin-top:0}.sidebar-nav::-webkit-scrollbar,.sidebar nav::-webkit-scrollbar{width:0}@supports (width: env(safe-area-inset)){@media only screen and (orientation: landscape){.sidebar-nav,.sidebar nav{margin-left:calc(env(safe-area-inset-left) / 2)}}}.sidebar-nav li>a:before,.sidebar-nav li>strong:before{display:inline-block}.sidebar-nav li>a{background-repeat:var(--sidebar-nav-pagelink-background-repeat);background-size:var(--sidebar-nav-pagelink-background-size)}.sidebar-nav li>a[href^="/"]:not([href*="?id="]),.sidebar-nav li>a[href^="#/"]:not([href*="?id="]){transition:var(--sidebar-nav-pagelink-transition)}.sidebar-nav li>a[href^="/"]:not([href*="?id="]),.sidebar-nav li>a[href^="/"]:not([href*="?id="]) ~ ul a,.sidebar-nav li>a[href^="#/"]:not([href*="?id="]),.sidebar-nav li>a[href^="#/"]:not([href*="?id="]) ~ ul a{padding:var(--sidebar-nav-pagelink-padding, var(--sidebar-nav-link-padding))}.sidebar-nav li>a[href^="/"]:not([href*="?id="]):only-child,.sidebar-nav li>a[href^="#/"]:not([href*="?id="]):only-child{background-image:var(--sidebar-nav-pagelink-background-image);background-position:var(--sidebar-nav-pagelink-background-position)}.sidebar-nav li>a[href^="/"]:not([href*="?id="]):not(:only-child),.sidebar-nav li>a[href^="#/"]:not([href*="?id="]):not(:only-child){background-image:var(--sidebar-nav-pagelink-background-image--loaded, var(--sidebar-nav-pagelink-background-image));background-position:var(--sidebar-nav-pagelink-background-position--loaded, var(--sidebar-nav-pagelink-background-image))}.sidebar-nav li.active>a,.sidebar-nav li.collapse>a{border-width:var(--sidebar-nav-link-border-width--active, var(--sidebar-nav-link-border-width));border-style:var(--sidebar-nav-link-border-style--active, var(--sidebar-nav-link-border-style));border-color:var(--sidebar-nav-link-border-color--active, var(--sidebar-nav-link-border-color));background-color:var(--sidebar-nav-link-background-color--active, var(--sidebar-nav-link-background-color));background-image:var(--sidebar-nav-link-background-image--active, var(--sidebar-nav-link-background-image));background-position:var(--sidebar-nav-link-background-position--active, var(--sidebar-nav-link-background-position));background-size:var(--sidebar-nav-link-background-size--active, var(--sidebar-nav-link-background-size));color:var(--sidebar-nav-link-color--active, var(--sidebar-nav-link-color));font-weight:var(--sidebar-nav-link-font-weight--active, var(--sidebar-nav-link-font-weight));-webkit-text-decoration:var(--sidebar-nav-link-text-decoration--active, var(--sidebar-nav-link-text-decoration));text-decoration:var(--sidebar-nav-link-text-decoration--active, var(--sidebar-nav-link-text-decoration));-webkit-text-decoration-color:var(--sidebar-nav-link-text-decoration-color);text-decoration-color:var(--sidebar-nav-link-text-decoration-color)}.sidebar-nav li.active>a[href^="/"]:not([href*="?id="]):not(:only-child),.sidebar-nav li.active>a[href^="#/"]:not([href*="?id="]):not(:only-child){background-image:var(--sidebar-nav-pagelink-background-image--active, var(--sidebar-nav-pagelink-background-image--loaded, var(--sidebar-nav-pagelink-background-image)));background-position:var(--sidebar-nav-pagelink-background-position--active, var(--sidebar-nav-pagelink-background-position--loaded, var(--sidebar-nav-pagelink-background-image)))}.sidebar-nav li.collapse>a[href^="/"]:not([href*="?id="]):not(:only-child),.sidebar-nav li.collapse>a[href^="#/"]:not([href*="?id="]):not(:only-child){background-image:var(--sidebar-nav-pagelink-background-image--collapse, var(--sidebar-nav-pagelink-background-image--loaded, var(--sidebar-nav-pagelink-background-image)));background-position:var(--sidebar-nav-pagelink-background-position--collapse, var(--sidebar-nav-pagelink-background-position--loaded, var(--sidebar-nav-pagelink-background-image)))}.sidebar-nav li.collapse .app-sub-sidebar{display:none}.sidebar-nav>ul>li>a:before{content:var(--sidebar-nav-link-before-content-l1, var(--sidebar-nav-link-before-content));margin:var(--sidebar-nav-link-before-margin-l1, var(--sidebar-nav-link-before-margin));color:var(--sidebar-nav-link-before-color-l1, var(--sidebar-nav-link-before-color))}.sidebar-nav>ul>li.active>a:before{content:var(--sidebar-nav-link-before-content-l1--active, var(--sidebar-nav-link-before-content--active, var(--sidebar-nav-link-before-content-l1, var(--sidebar-nav-link-before-content))));color:var(--sidebar-nav-link-before-color-l1--active, var(--sidebar-nav-link-before-color--active, var(--sidebar-nav-link-before-color-l1, var(--sidebar-nav-link-before-color))))}.sidebar-nav>ul>li>ul>li>a:before{content:var(--sidebar-nav-link-before-content-l2, var(--sidebar-nav-link-before-content));margin:var(--sidebar-nav-link-before-margin-l2, var(--sidebar-nav-link-before-margin));color:var(--sidebar-nav-link-before-color-l2, var(--sidebar-nav-link-before-color))}.sidebar-nav>ul>li>ul>li.active>a:before{content:var(--sidebar-nav-link-before-content-l2--active, var(--sidebar-nav-link-before-content--active, var(--sidebar-nav-link-before-content-l2, var(--sidebar-nav-link-before-content))));color:var(--sidebar-nav-link-before-color-l2--active, var(--sidebar-nav-link-before-color--active, var(--sidebar-nav-link-before-color-l2, var(--sidebar-nav-link-before-color))))}.sidebar-nav>ul>li>ul>li>ul>li>a:before{content:var(--sidebar-nav-link-before-content-l3, var(--sidebar-nav-link-before-content));margin:var(--sidebar-nav-link-before-margin-l3, var(--sidebar-nav-link-before-margin));color:var(--sidebar-nav-link-before-color-l3, var(--sidebar-nav-link-before-color))}.sidebar-nav>ul>li>ul>li>ul>li.active>a:before{content:var(--sidebar-nav-link-before-content-l3--active, var(--sidebar-nav-link-before-content--active, var(--sidebar-nav-link-before-content-l3, var(--sidebar-nav-link-before-content))));color:var(--sidebar-nav-link-before-color-l3--active, var(--sidebar-nav-link-before-color--active, var(--sidebar-nav-link-before-color-l3, var(--sidebar-nav-link-before-color))))}.sidebar-nav>ul>li>ul>li>ul>li>ul>li>a:before{content:var(--sidebar-nav-link-before-content-l4, var(--sidebar-nav-link-before-content));margin:var(--sidebar-nav-link-before-margin-l4, var(--sidebar-nav-link-before-margin));color:var(--sidebar-nav-link-before-color-l4, var(--sidebar-nav-link-before-color))}.sidebar-nav>ul>li>ul>li>ul>li>ul>li.active>a:before{content:var(--sidebar-nav-link-before-content-l4--active, var(--sidebar-nav-link-before-content--active, var(--sidebar-nav-link-before-content-l4, var(--sidebar-nav-link-before-content))));color:var(--sidebar-nav-link-before-color-l4--active, var(--sidebar-nav-link-before-color--active, var(--sidebar-nav-link-before-color-l4, var(--sidebar-nav-link-before-color))))}.sidebar-nav>:last-child{margin-bottom:2rem}.sidebar-toggle,.sidebar-toggle-button{width:var(--sidebar-toggle-width);outline:none}.sidebar-toggle{position:fixed;z-index:11;top:0;bottom:0;left:0;max-width:40px;margin:0;padding:0;border:0;background:transparent;-webkit-appearance:none;-moz-appearance:none;appearance:none;cursor:pointer}.sidebar-toggle .sidebar-toggle-button{position:absolute;top:var(--sidebar-toggle-offset-top);left:var(--sidebar-toggle-offset-left);height:var(--sidebar-toggle-height);border-radius:var(--sidebar-toggle-border-radius);border-width:var(--sidebar-toggle-border-width);border-style:var(--sidebar-toggle-border-style);border-color:var(--sidebar-toggle-border-color);background:var(--sidebar-toggle-background, transparent);color:var(--sidebar-toggle-icon-color)}.sidebar-toggle span{position:absolute;top:calc(50% - (var(--sidebar-toggle-icon-stroke-width) / 2));left:calc(50% - (var(--sidebar-toggle-icon-width) / 2));height:var(--sidebar-toggle-icon-stroke-width);width:var(--sidebar-toggle-icon-width);background-color:currentColor}.sidebar-toggle span:nth-child(1){margin-top:calc(0px - (var(--sidebar-toggle-icon-height) / 2))}.sidebar-toggle span:nth-child(3){margin-top:calc((var(--sidebar-toggle-icon-height) / 2))}@media (min-width: 48em){.sidebar-toggle{position:absolute;overflow:visible;top:var(--sidebar-toggle-offset-top);bottom:auto;left:0;height:var(--sidebar-toggle-height);transform:translateX(var(--sidebar-width))}.sidebar-toggle .sidebar-toggle-button{top:0}}@media print{.sidebar-toggle{display:none}}@media (max-width: 47.99em){body.close .sidebar,body.close .sidebar-toggle,body.close .sidebar+.content{transform:translateX(var(--sidebar-width))}}@media (min-width: 48em){body.close .sidebar+.content{transform:translateX(0)}}@media (max-width: 47.99em){body.close nav.app-nav,body.close .github-corner{display:none}}@media (min-width: 48em){body.close .sidebar,body.close .sidebar-toggle{transform:translateX(0)}}@media (min-width: 48em){body.close nav.app-nav{margin-left:0}}@media (max-width: 47.99em){body.close .sidebar-toggle{width:100%;max-width:none}body.close .sidebar-toggle span{margin-top:0}body.close .sidebar-toggle span:nth-child(1){transform:rotate(45deg)}body.close .sidebar-toggle span:nth-child(2){display:none}body.close .sidebar-toggle span:nth-child(3){transform:rotate(-45deg)}}@media (min-width: 48em){body.close .sidebar+.content{margin-left:0}}@media (min-width: 48em){body.sticky .sidebar,body.sticky .sidebar-toggle{position:fixed}}body .docsify-copy-code-button,body .docsify-copy-code-button:after{border-radius:var(--border-radius-m, 0);border-top-left-radius:0;border-bottom-right-radius:0;background:var(--copycode-background);color:var(--copycode-color)}body .docsify-copy-code-button span{border-radius:var(--border-radius-s, 0)}body .docsify-pagination-container{border-top:var(--pagination-border-top);color:var(--pagination-color)}body .pagination-item-label{font-size:var(--pagination-label-font-size)}body .pagination-item-label svg{color:var(--pagination-label-color);height:var(--pagination-chevron-height);stroke:var(--pagination-chevron-stroke);stroke-linecap:var(--pagination-chevron-stroke-linecap);stroke-linejoin:var(--pagination-chevron-stroke-linecap);stroke-width:var(--pagination-chevron-stroke-width)}body .pagination-item-title{color:var(--pagination-title-color);font-size:var(--pagination-title-font-size)}body .app-name.hide{display:block}body .sidebar{padding:var(--sidebar-padding)}.sidebar .search{margin:0;padding:0;border:0}.sidebar .search input{padding:0;line-height:1;font-size:inherit}.sidebar .search .clear-button{width:auto}.sidebar .search .clear-button svg{transform:scale(1)}.sidebar .search .matching-post{border:none}.sidebar .search p{font-size:inherit}.sidebar .search{order:var(--search-flex-order);margin:var(--search-margin);padding:var(--search-padding);background:var(--search-background)}.sidebar .search a{color:inherit}.sidebar .search h2{margin:var(--search-result-heading-margin);font-size:var(--search-result-heading-font-size);font-weight:var(--search-result-heading-font-weight);color:var(--search-result-heading-color)}.sidebar .search .input-wrap{align-items:stretch;margin:var(--search-input-margin);background-color:var(--search-input-background-color);border-width:var(--search-input-border-width, 0);border-style:solid;border-color:var(--search-input-border-color);border-radius:var(--search-input-border-radius)}.sidebar .search input[type="search"]{min-width:0;padding:var(--search-input-padding);border:none;background-color:transparent;background-image:var(--search-input-background-image);background-position:var(--search-input-background-position);background-repeat:var(--search-input-background-repeat);background-size:var(--search-input-background-size);font-size:var(--search-input-font-size);color:var(--search-input-color);transition:var(--search-input-transition)}.sidebar .search input[type="search"]::-ms-clear{display:none}.sidebar .search input[type="search"]::-moz-placeholder{color:var(--search-input-placeholder-color, gray)}.sidebar .search input[type="search"]:-ms-input-placeholder{color:var(--search-input-placeholder-color, gray)}.sidebar .search input[type="search"]::placeholder{color:var(--search-input-placeholder-color, gray)}.sidebar .search input[type="search"]::-webkit-input-placeholder{line-height:normal}.sidebar .search input[type="search"]:focus{background-color:var(--search-input-background-color--focus, var(--search-input-background-color));background-image:var(--search-input-background-image--focus, var(--search-input-background-image));background-position:var(--search-input-background-position--focus, var(--search-input-background-position));background-size:var(--search-input-background-size--focus, var(--search-input-background-size))}@supports (width: env(safe-area-inset)){@media only screen and (orientation: landscape){.sidebar .search input[type="search"]{margin-left:calc(env(safe-area-inset-left) / 2)}}}.sidebar .search p{overflow:hidden;text-overflow:ellipsis;-webkit-box-orient:vertical;-webkit-line-clamp:2}.sidebar .search p:empty{text-align:center}.sidebar .search .clear-button{margin:0;padding:0 10px;border:none;line-height:1;background:transparent;cursor:pointer}.sidebar .search .clear-button svg circle{fill:var(--search-clear-icon-color1, gray)}.sidebar .search .clear-button svg path{stroke:var(--search-clear-icon-color2, #fff)}.sidebar .search.show ~ *:not(h1){display:none}.sidebar .search .results-panel{display:none;color:var(--search-result-item-color);font-size:var(--search-result-item-font-size);font-weight:var(--search-result-item-font-weight)}.sidebar .search .results-panel.show{display:block}.sidebar .search .matching-post{margin:var(--search-result-item-margin);padding:var(--search-result-item-padding)}.sidebar .search .matching-post,.sidebar .search .matching-post:last-child{border-width:var(--search-result-item-border-width, 0) !important;border-style:var(--search-result-item-border-style);border-color:var(--search-result-item-border-color)}.sidebar .search .matching-post p{margin:0}.sidebar .search .search-keyword{margin:var(--search-result-keyword-margin);padding:var(--search-result-keyword-padding);border-radius:var(--search-result-keyword-border-radius);background-color:var(--search-result-keyword-background);color:var(--search-result-keyword-color, currentColor);font-style:normal;font-weight:var(--search-result-keyword-font-weight)}.medium-zoom-overlay,.medium-zoom-image--open,.medium-zoom-image--opened{z-index:2147483646 !important}.medium-zoom-overlay{background:var(--zoomimage-overlay-background) !important}:root{--mono-hue: 113;--mono-saturation: 0%;--mono-shade3: hsl(var(--mono-hue), var(--mono-saturation), 20%);--mono-shade2: hsl(var(--mono-hue), var(--mono-saturation), 30%);--mono-shade1: hsl(var(--mono-hue), var(--mono-saturation), 40%);--mono-base: hsl(var(--mono-hue), var(--mono-saturation), 50%);--mono-tint1: hsl(var(--mono-hue), var(--mono-saturation), 70%);--mono-tint2: hsl(var(--mono-hue), var(--mono-saturation), 89%);--mono-tint3: hsl(var(--mono-hue), var(--mono-saturation), 97%);--theme-hue: 204;--theme-saturation: 90%;--theme-lightness: 45%;--theme-color: hsl(var(--theme-hue), var(--theme-saturation), var(--theme-lightness));--modular-scale: 1.333;--modular-scale--2: calc(var(--modular-scale--1) / var(--modular-scale));--modular-scale--1: calc(var(--modular-scale-1) / var(--modular-scale));--modular-scale-1: 1rem;--modular-scale-2: calc(var(--modular-scale-1) * var(--modular-scale));--modular-scale-3: calc(var(--modular-scale-2) * var(--modular-scale));--modular-scale-4: calc(var(--modular-scale-3) * var(--modular-scale));--modular-scale-5: calc(var(--modular-scale-4) * var(--modular-scale));--font-size-xxxl: var(--modular-scale-5);--font-size-xxl: var(--modular-scale-4);--font-size-xl: var(--modular-scale-3);--font-size-l: var(--modular-scale-2);--font-size-m: var(--modular-scale-1);--font-size-s: var(--modular-scale--1);--font-size-xs: var(--modular-scale--2);--duration-slow: 1s;--duration-medium: 0.5s;--duration-fast: 0.25s;--spinner-size: 60px;--spinner-track-width: 4px;--spinner-track-color: rgba(0, 0, 0, 0.15);--spinner-transition-duration: var(--duration-medium)}:root{--base-background-color: #fff;--base-color: var(--mono-shade2);--base-font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";--base-font-size: 16px;--base-font-weight: normal;--base-line-height: 1.7;--emoji-size: calc(var(--base-line-height) * 1em);--hr-border: 1px solid var(--mono-tint2);--mark-background: #ffecb3;--pre-font-family: var(--code-font-family);--pre-font-size: var(--code-font-size);--pre-font-weight: normal;--selection-color: #b4d5fe;--small-font-size: var(--font-size-s);--strong-color: var(--heading-color);--strong-font-weight: 600;--subsup-font-size: var(--font-size-s)}:root{--content-max-width: 55em;--blockquote-background: var(--mono-tint3);--blockquote-border-style: solid;--blockquote-border-radius: var(--border-radius-m);--blockquote-em-font-weight: normal;--blockquote-font-weight: normal;--code-font-family: Inconsolata, Consolas, Menlo, Monaco, "Andale Mono WT", "Andale Mono", "Lucida Console", "DejaVu Sans Mono", "Bitstream Vera Sans Mono", "Courier New", Courier, monospace;--code-font-size: calc(var(--font-size-m) * 0.95);--code-font-weight: normal;--code-tab-size: 4;--code-block-border-radius: var(--border-radius-m);--code-block-line-height: var(--base-line-height);--code-block-margin: 1em 0;--code-block-padding: 1.75em 1.5em 1.5em 1.5em;--code-inline-background: var(--code-theme-background);--code-inline-border-radius: var(--border-radius-s);--code-inline-color: var(--code-theme-text);--code-inline-margin: 0 0.15em;--code-inline-padding: 0.125em 0.4em;--code-theme-background: var(--mono-tint3);--heading-color: var(--mono-shade3);--heading-margin: 2.5rem 0 0;--heading-h1-border-style: solid;--heading-h1-font-size: var(--font-size-xxl);--heading-h2-border-style: solid;--heading-h2-font-size: var(--font-size-xl);--heading-h3-border-style: solid;--heading-h3-font-size: var(--font-size-l);--heading-h4-border-style: solid;--heading-h4-font-size: var(--font-size-m);--heading-h5-border-style: solid;--heading-h5-font-size: var(--font-size-s);--heading-h6-border-style: solid;--heading-h6-font-size: var(--font-size-xs);--kbd-background: var(--mono-tint3);--kbd-border-radius: var(--border-radius-m);--kbd-margin: 0 0.3em;--kbd-min-width: 2.5em;--kbd-padding: 0.65em 0.5em;--link-text-decoration: underline;--notice-background: var(--mono-tint3);--notice-border-radius: var(--border-radius-m);--notice-border-style: solid;--notice-font-weight: normal;--notice-padding: 1em 1.5em;--notice-before-font-weight: normal;--table-cell-padding: 0.75em 0.5em;--table-head-border-color: var(--table-cell-border-color);--table-head-font-weight: var(--strong-font-weight);--table-row-odd-background: var(--mono-tint3)}:root{--cover-margin: 0 auto;--cover-max-width: 40em;--cover-text-align: center;--cover-background-color: var(--base-background-color);--cover-background-mask-color: var(--base-background-color);--cover-background-mask-opacity: 0.8;--cover-background-position: center center;--cover-background-repeat: no-repeat;--cover-background-size: cover;--cover-blockquote-font-size: var(--font-size-l);--cover-border-color: var(--theme-color);--cover-button-border: 1px solid var(--theme-color);--cover-button-border-radius: var(--border-radius-m);--cover-button-color: var(--theme-color);--cover-button-padding: 0.5em 2rem;--cover-button-text-decoration: none;--cover-button-transition: all var(--duration-fast) ease-in-out;--cover-button-primary-background: var(--theme-color);--cover-button-primary-border: 1px solid var(--theme-color);--cover-button-primary-color: #fff;--cover-heading-color: var(--theme-color);--cover-heading-font-size: var(--font-size-xxl);--cover-heading-font-weight: normal;--cover-link-text-decoration: underline }:root{--navbar-root-border-style: solid;--navbar-root-margin: 0 0 0 1.5em;--navbar-root-transition: all var(--duration-fast);--navbar-menu-background: var(--base-background-color);--navbar-menu-border-radius: var(--border-radius-m);--navbar-menu-box-shadow: rgba(45,45,45,0.05) 0px 0px 1px, rgba(49,49,49,0.05) 0px 1px 2px, rgba(42,42,42,0.05) 0px 2px 4px, rgba(32,32,32,0.05) 0px 4px 8px, rgba(49,49,49,0.05) 0px 8px 16px, rgba(35,35,35,0.05) 0px 16px 32px;--navbar-menu-padding: 0.5em;--navbar-menu-transition: all var(--duration-fast);--navbar-menu-link-border-style: solid;--navbar-menu-link-margin: 0.75em 0.5em;--navbar-menu-link-padding: 0.2em 0 }:root{--copycode-background: #808080;--copycode-color: #fff}:root{--docsifytabs-border-color: var(--mono-tint2);--docsifytabs-border-radius-px: var(--border-radius-s);--docsifytabs-tab-background: var(--mono-tint3);--docsifytabs-tab-color: var(--mono-tint1)}:root{--pagination-border-top: 1px solid var(--mono-tint2);--pagination-chevron-height: 0.8em;--pagination-chevron-stroke: currentColor;--pagination-chevron-stroke-linecap: round;--pagination-chevron-stroke-width: 1px;--pagination-label-font-size: var(--font-size-s);--pagination-title-font-size: var(--font-size-l)}:root{--search-margin: 1.5rem 0 0;--search-input-background-repeat: no-repeat;--search-input-border-color: var(--mono-tint1);--search-input-border-width: 1px;--search-input-padding: 0.5em;--search-flex-order: 1;--search-result-heading-color: var(--heading-color);--search-result-heading-font-size: var(--base-font-size);--search-result-heading-font-weight: normal;--search-result-heading-margin: 0 0 0.25em;--search-result-item-border-color: var(--mono-tint2);--search-result-item-border-style: solid;--search-result-item-border-width: 0 0 1px 0;--search-result-item-font-weight: normal;--search-result-item-padding: 1em 0;--search-result-keyword-background: var(--mark-background);--search-result-keyword-border-radius: var(--border-radius-s);--search-result-keyword-color: var(--mark-color);--search-result-keyword-font-weight: normal;--search-result-keyword-margin: 0 0.1em;--search-result-keyword-padding: 0.2em 0}:root{--zoomimage-overlay-background: rgba(0, 0, 0, 0.875)}:root{--sidebar-background: var(--base-background-color);--sidebar-border-width: 0;--sidebar-padding: 0 25px;--sidebar-transition-duration: var(--duration-fast);--sidebar-width: 17rem;--sidebar-name-font-size: var(--font-size-l);--sidebar-name-font-weight: normal;--sidebar-name-margin: 1.5rem 0 0;--sidebar-name-text-align: center;--sidebar-nav-strong-border-color: var(--sidebar-border-color);--sidebar-nav-strong-color: var(--heading-color);--sidebar-nav-strong-font-weight: var(--strong-font-weight);--sidebar-nav-strong-margin: 1.5em 0 0.5em;--sidebar-nav-strong-padding: 0.25em 0;--sidebar-nav-indent: 1em;--sidebar-nav-margin: 1.5rem 0 0;--sidebar-nav-link-border-style: solid;--sidebar-nav-link-border-width: 0;--sidebar-nav-link-color: var(--base-color);--sidebar-nav-link-font-weight: normal;--sidebar-nav-link-padding: 0.25em 0;--sidebar-nav-link-text-decoration--active: underline;--sidebar-nav-link-text-decoration--hover: underline;--sidebar-nav-link-before-margin: 0 0.35em 0 0;--sidebar-nav-pagelink-background-repeat: no-repeat;--sidebar-nav-pagelink-transition: var(--sidebar-nav-link-transition);--sidebar-toggle-border-radius: var(--border-radius-s);--sidebar-toggle-border-style: solid;--sidebar-toggle-border-width: 0;--sidebar-toggle-height: 36px;--sidebar-toggle-icon-color: var(--base-color);--sidebar-toggle-icon-height: 10px;--sidebar-toggle-icon-stroke-width: 1px;--sidebar-toggle-icon-width: 16px;--sidebar-toggle-offset-left: 0;--sidebar-toggle-offset-top: calc(35px - (var(--sidebar-toggle-height) / 2));--sidebar-toggle-width: 44px}:root{--code-theme-background: #f3f3f3;--code-theme-comment: #6e8090;--code-theme-function: #dd4a68;--code-theme-keyword: #07a;--code-theme-operator: #a67f59;--code-theme-punctuation: #999;--code-theme-selector: #690;--code-theme-tag: #905;--code-theme-text: #333;--code-theme-variable: #e90}:root{--border-radius-s: 2px;--border-radius-m: 4px;--border-radius-l: 8px;--strong-font-weight: 600;--blockquote-border-color: var(--theme-color);--blockquote-border-radius: 0 var(--border-radius-m) var(--border-radius-m) 0;--blockquote-border-width: 0 0 0 4px;--code-inline-background: var(--mono-tint2);--code-theme-background: var(--mono-tint3);--heading-font-weight: var(--strong-font-weight);--heading-h1-font-weight: 400;--heading-h2-font-weight: 400;--heading-h2-border-color: var(--mono-tint2);--heading-h2-border-width: 0 0 1px 0;--heading-h2-margin: 2.5rem 0 1.5rem;--heading-h2-padding: 0 0 1rem 0;--kbd-border: 1px solid var(--mono-tint2);--notice-border-radius: 0 var(--border-radius-m) var(--border-radius-m) 0;--notice-border-width: 0 0 0 4px;--notice-padding: 1em 1.5em 1em 3em;--notice-before-border-radius: 100%;--notice-before-font-weight: bold;--notice-before-height: 1.5em;--notice-before-left: 0.75em;--notice-before-line-height: 1.5;--notice-before-margin: 0 0.25em 0 0;--notice-before-position: absolute;--notice-before-width: var(--notice-before-height);--notice-important-background: hsl(340, 60%, 96%);--notice-important-border-color: hsl(340, 90%, 45%);--notice-important-before-background: var(--notice-important-border-color) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23fff'%3E%3Cpath d='M10 14C10 15.1 9.1 16 8 16 6.9 16 6 15.1 6 14 6 12.9 6.9 12 8 12 9.1 12 10 12.9 10 14Z'/%3E%3Cpath d='M10 1.6C10 1.2 9.8 0.9 9.6 0.7 9.2 0.3 8.6 0 8 0 7.4 0 6.8 0.2 6.5 0.6 6.2 0.9 6 1.2 6 1.6 6 1.7 6 1.8 6 1.9L6.8 9.6C6.9 9.9 7 10.1 7.2 10.2 7.4 10.4 7.7 10.5 8 10.5 8.3 10.5 8.6 10.4 8.8 10.3 9 10.1 9.1 9.9 9.2 9.6L10 1.9C10 1.8 10 1.7 10 1.6Z'/%3E%3C/svg%3E") center / 0.875em no-repeat;--notice-important-before-color: #fff;--notice-important-before-content: "";--notice-tip-background: hsl(204, 60%, 96%);--notice-tip-border-color: hsl(204, 90%, 45%);--notice-tip-before-background: var(--notice-tip-border-color) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23fff'%3E%3Cpath d='M9.1 0C10.2 0 10.7 0.7 10.7 1.6 10.7 2.6 9.8 3.6 8.6 3.6 7.6 3.6 7 3 7 2 7 1.1 7.7 0 9.1 0Z'/%3E%3Cpath d='M5.8 16C5 16 4.4 15.5 5 13.2L5.9 9.1C6.1 8.5 6.1 8.2 5.9 8.2 5.7 8.2 4.6 8.6 3.9 9.1L3.5 8.4C5.6 6.6 7.9 5.6 8.9 5.6 9.8 5.6 9.9 6.6 9.5 8.2L8.4 12.5C8.2 13.2 8.3 13.5 8.5 13.5 8.7 13.5 9.6 13.2 10.4 12.5L10.9 13.2C8.9 15.2 6.7 16 5.8 16Z'/%3E%3C/svg%3E") center / 0.875em no-repeat;--notice-tip-before-color: #fff;--notice-tip-before-content: "";--table-cell-border-color: var(--mono-tint2);--table-cell-border-width: 1px 0;--cover-background-color: hsl(var(--theme-hue), 25%, 60%);--cover-background-image: radial-gradient(ellipse at center 115%, rgba(255, 255, 255, 0.9), transparent);--cover-blockquote-color: var(--strong-color);--cover-heading-color: #fff;--cover-heading-font-size-max: 56;--cover-heading-font-size-min: 34;--cover-heading-font-weight: 200;--navbar-root-color--active: var(--theme-color);--navbar-menu-border-radius: var(--border-radius-m);--navbar-menu-root-background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='9.6' height='6' viewBox='0 0 9.6 6'%3E%3Cpath d='M1.5 1.5l3.3 3 3.3-3' stroke-width='1.5' stroke='rgb%28179, 179, 179%29' fill='none' stroke-linecap='square' stroke-linejoin='miter' vector-effect='non-scaling-stroke'/%3E%3C/svg%3E") right no-repeat;--navbar-menu-root-padding: 0 18px 0 0;--search-input-background-color: #fff;--search-input-background-image: url("data:image/svg+xml,%3Csvg height='20px' width='20px' viewBox='0 0 24 24' fill='none' stroke='rgba(0, 0, 0, 0.3)' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round' preserveAspectRatio='xMidYMid meet' xmlns='http://www.w3.org/2000/svg'%3E%3Ccircle cx='10.5' cy='10.5' r='7.5' vector-effect='non-scaling-stroke'%3E%3C/circle%3E%3Cline x1='21' y1='21' x2='15.8' y2='15.8' vector-effect='non-scaling-stroke'%3E%3C/line%3E%3C/svg%3E");--search-input-background-position: 21px center;--search-input-border-color: var(--sidebar-border-color);--search-input-border-width: 1px 0;--search-input-margin: 0 -25px;--search-input-padding: 0.65em 1em 0.65em 50px;--search-input-placeholder-color: rgba(0, 0, 0, 0.4);--search-clear-icon-color1: rgba(0, 0, 0, 0.3);--search-result-heading-font-weight: var(--strong-font-weight);--search-result-item-border-color: var(--sidebar-border-color);--search-result-keyword-border-radius: var(--border-radius-s);--sidebar-background: var(--mono-tint3);--sidebar-border-color: var(--mono-tint2);--sidebar-border-width: 0 1px 0 0;--sidebar-name-color: var(--theme-color);--sidebar-name-font-weight: 300;--sidebar-nav-strong-border-width: 0 0 1px 0;--sidebar-nav-strong-font-size: smaller;--sidebar-nav-strong-margin: 2em -25px 0.75em 0;--sidebar-nav-strong-padding: 0.25em 0 0.75em 0;--sidebar-nav-strong-text-transform: uppercase;--sidebar-nav-link-border-color: transparent;--sidebar-nav-link-border-color--active: var(--theme-color);--sidebar-nav-link-border-width: 0 4px 0 0;--sidebar-nav-link-color--active: var(--theme-color);--sidebar-nav-link-margin: 0 -25px 0 0;--sidebar-nav-link-text-decoration: none;--sidebar-nav-link-text-decoration--active: none;--sidebar-nav-link-text-decoration--hover: underline;--sidebar-nav-link-before-content-l3: '-';--sidebar-nav-pagelink-background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='7' height='11.2' viewBox='0 0 7 11.2'%3E%3Cpath d='M1.5 1.5l4 4.1 -4 4.1' stroke-width='1.5' stroke='rgb%28179, 179, 179%29' fill='none' stroke-linecap='square' stroke-linejoin='miter' vector-effect='non-scaling-stroke'/%3E%3C/svg%3E");--sidebar-nav-pagelink-background-image--active: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='11.2' height='7' viewBox='0 0 11.2 7'%3E%3Cpath d='M1.5 1.5l4.1 4 4.1-4' stroke-width='1.5' stroke='rgb%2811, 135, 218%29' fill='none' stroke-linecap='square' stroke-linejoin='miter' vector-effect='non-scaling-stroke'/%3E%3C/svg%3E");--sidebar-nav-pagelink-background-image--collapse: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='7' height='11.2' viewBox='0 0 7 11.2'%3E%3Cpath d='M1.5 1.5l4 4.1 -4 4.1' stroke-width='1.5' stroke='rgb%2811, 135, 218%29' fill='none' stroke-linecap='square' stroke-linejoin='miter' vector-effect='non-scaling-stroke'/%3E%3C/svg%3E");--sidebar-nav-pagelink-background-image--loaded: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='11.2' height='7' viewBox='0 0 11.2 7'%3E%3Cpath d='M1.5 1.5l4.1 4 4.1-4' stroke-width='1.5' stroke='rgb%2811, 135, 218%29' fill='none' stroke-linecap='square' stroke-linejoin='miter' vector-effect='non-scaling-stroke'/%3E%3C/svg%3E");--sidebar-nav-pagelink-background-position: 3px center;--sidebar-nav-pagelink-background-position--active: left center;--sidebar-nav-pagelink-background-position--collapse: var(--sidebar-nav-pagelink-background-position);--sidebar-nav-pagelink-background-position--loaded: var(--sidebar-nav-pagelink-background-position--active);--sidebar-nav-pagelink-padding: 0.25em 0 0.25em 20px;--sidebar-nav-pagelink-transition: none;--sidebar-toggle-background: var(--sidebar-border-color);--sidebar-toggle-border-radius: 0 var(--border-radius-s) var(--border-radius-s) 0;--sidebar-toggle-width: 32px}:root{--code-theme-background: #222;--code-theme-comment: #516e7a;--code-theme-function: #f07178;--code-theme-keyword: #c2e78c;--code-theme-operator: #ffcb6b;--code-theme-punctuation: #89ddff;--code-theme-selector: #ffcb6b;--code-theme-tag: #f07178;--code-theme-text: #f3f3f3;--code-theme-variable: #ffcb6b}:root{--mono-hue: 201;--mono-saturation: 18%;--mono-shade3: hsl(var(--mono-hue), var(--mono-saturation), 13%);--mono-shade2: hsl(var(--mono-hue), var(--mono-saturation), 15%);--mono-shade1: hsl(var(--mono-hue), var(--mono-saturation), 17%);--mono-base: hsl(var(--mono-hue), var(--mono-saturation), 19%);--mono-tint1: hsl(var(--mono-hue), var(--mono-saturation), 25%);--mono-tint2: hsl(var(--mono-hue), var(--mono-saturation), 35%);--mono-tint3: hsl(var(--mono-hue), var(--mono-saturation), 43%);--spinner-track-color: rgba(255, 255, 255, 0.15);--base-background-color: var(--mono-base);--base-color: #d3d3d3;--hr-border: 1px solid var(--mono-tint2);--mark-background: #ffcb6b;--mark-color: var(--base-background-color);--selection-color: rgba(94, 131, 175, 0.75);--blockquote-background: var(--mono-shade2);--code-inline-background: var(--mono-tint1);--code-theme-background: var(--mono-shade2);--heading-color: #fff;--heading-h2-border-color: var(--mono-tint2);--kbd-background: var(--mono-shade2);--kbd-border: none;--kbd-color: var(--strong-color);--notice-important-background: var(--mono-shade2);--notice-tip-background: var(--mono-shade2);--table-cell-border-color: var(--mono-tint1);--table-row-odd-background: var(--mono-shade2);--cover-background-color: var(--base-background-color);--cover-background-image: radial-gradient(ellipse at center bottom, var(--mono-tint3), transparent);--cover-blockquote-color: var(--mark-background);--cover-button-border: 1px solid var(--mono-tint3);--cover-button-color: #fff;--navbar-menu-background: var(--mono-tint1);--navbar-menu-box-shadow: rgba(0,0,0,0.05) 0px 0px 1px, rgba(0,0,0,0.05) 0px 1px 2px, rgba(0,0,0,0.05) 0px 2px 4px, rgba(0,0,0,0.05) 0px 4px 8px, rgba(0,0,0,0.05) 0px 8px 16px, rgba(0,0,0,0.05) 0px 16px 32px;--copycode-background: var(--mono-tint1);--copycode-color: #fff;--docsifytabs-border-color: var(--mono-tint2);--docsifytabs-tab-background: var(--mono-shade1);--docsifytabs-tab-color: var(--mono-tint2);--pagination-border-top: 1px solid var(--mono-tint2);--pagination-title-color: #fff;--search-input-background-color: var(--mono-shade2);--search-input-background-image: url("data:image/svg+xml,%3Csvg height='20px' width='20px' viewBox='0 0 24 24' fill='none' stroke='rgba(255, 255, 255, 0.3)' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round' preserveAspectRatio='xMidYMid meet' xmlns='http://www.w3.org/2000/svg'%3E%3Ccircle cx='10.5' cy='10.5' r='7.5' vector-effect='non-scaling-stroke'%3E%3C/circle%3E%3Cline x1='21' y1='21' x2='15.8' y2='15.8' vector-effect='non-scaling-stroke'%3E%3C/line%3E%3C/svg%3E");--search-input-border-color: var(--mono-tint1);--search-input-placeholder-color: rgba(255, 255, 255, 0.4);--search-clear-icon-color1: rgba(255, 255, 255, 0.3);--sidebar-background: var(--mono-shade1);--sidebar-border-color: var(--mono-tint1);--sidebar-nav-pagelink-background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='7' height='11.2' viewBox='0 0 7 11.2'%3E%3Cpath d='M1.5 1.5l4 4.1 -4 4.1' stroke-width='1.5' stroke='rgb%2873, 93, 104%29' fill='none' stroke-linecap='square' stroke-linejoin='miter' vector-effect='non-scaling-stroke'/%3E%3C/svg%3E")}
+table {
+ display: table !important;
+ width: 100%;
+}
/*# sourceMappingURL=theme-simple-dark.css.map */
\ No newline at end of file
diff --git a/docs/入门指南/安装和导入.md b/docs/入门指南/安装和导入.md
index 09b791a..d22614d 100644
--- a/docs/入门指南/安装和导入.md
+++ b/docs/入门指南/安装和导入.md
@@ -1,16 +1,10 @@
# ✔️运行环境
-## 📍 操作系统
+操作系统:Windows、Linux 或 Mac。
-Windows 或 Linux。
+python 版本:3.6 及以上
-作者没有 Mac,没测试过,估计是可以的。
-
-
-
-## 📍 python 版本
-
-支持 python 3.6 及以上版本。
+支持浏览器:Chromium 内核(如 Chrome 和 edge)
# ✔️ 安装
diff --git a/docs/启动配置/Session启动配置.md b/docs/启动配置/Session启动配置.md
index 3e20a54..0a925ab 100644
--- a/docs/启动配置/Session启动配置.md
+++ b/docs/启动配置/Session启动配置.md
@@ -62,6 +62,16 @@ print(so.headers)
**返回:** 当前对象
+## 📍 `set_timeout()`
+
+此方法用于设置超时属性。
+
+**参数:**
+
+- `second`:秒数
+
+**返回:** 当前对象
+
## 📍 `cookies`
此属性返回`cookies`设置信息,可赋值。
diff --git a/docs/启动配置/使用配置文件.md b/docs/启动配置/使用配置文件.md
index ddc24c0..4127431 100644
--- a/docs/启动配置/使用配置文件.md
+++ b/docs/启动配置/使用配置文件.md
@@ -71,6 +71,7 @@ headers = {
"Connection": "keep-alive",
"Accept-Charset": "utf-8;q=0.7,*;q=0.7"
}
+timeout = 10
```
# ✔️ 文件位置
diff --git a/docs/启动配置/浏览器启动配置.md b/docs/启动配置/浏览器启动配置.md
index 72d6f88..f8f454a 100644
--- a/docs/启动配置/浏览器启动配置.md
+++ b/docs/启动配置/浏览器启动配置.md
@@ -1,179 +1,523 @@
-为使浏览器设置更便利,本库使用`DriverOptions`类,专门用于管理浏览器的启动配置。
+浏览器的启动配置非常繁杂,本库使用`ChromiumOptions`类管理启动配置,并且内置了常用配置的设置接口。
-!> **注意:**
1、`DriverOptions`仅用于管理启动配置,浏览器启动后再修改无效。
2、若接管已打开的浏览器,则所有启动配置均无效。
+需要注意的是,该对象只能用于浏览器的启动,浏览器启动后,再修改该配置没有任何效果。接管已打开的浏览器时,启动配置也是无效的。
-# ✔️ `DriverOptions`类
+# ✔️ 创建对象
-`DriverOptions`类继承自 selenium 的`Options` 类,保留了原来所有功能,原生功能不在这里叙述,只介绍增加的功能。
-对象创建时,可从配置文件中读取配置来进行初始化,不从文件读取则创建一个空配置对象。
-该类绝大部分方法都支持链式操作。
+## 📍 导入
-**初始化参数:**
+```python
+from DrissionPage import ChromiumOptions
+```
-- `read_file`:是否从默认 ini 文件中读取配置信息
-- `ini_path`:ini 文件路径,为`None`则读取默认 ini 文件
+## 📍 `ChromiumOptions`
-## 📍 `driver_path`
+`ChromiumOptions`对象用于管理浏览器初始化配置。可从配置文件中读取配置来进行初始化。
-此属性返回 chromedriver 文件路径。`MixPage`使用,`WebPage`不需要。
+| 初始化参数 | 类型 | 默认值 | 说明 |
+|:-----------:|:---------------:|:------:| ---------------------------------- |
+| `read_file` | `bool` | `True` | 是否从 ini 文件中读取配置信息,为`False`则用默认配置创建 |
+| `ini_path` | `Path`
`str` | `None` | 指定 ini 文件路径,为`None`则读取内置 ini 文件 |
-## 📍 `chrome_path`
+创建配置对象:
-此属性返回 Chrome 浏览器启动文件路径,为空时程序会根据注册表或系统路径查找。
+```python
+from DrissionPage import ChromiumOptions
-## 📍 `set_paths()`
+co = ChromiumOptions()
+```
-该方法用于设置浏览器用到的几种路径信息。
+默认情况下,`ChromiumOptions`对象会从 ini 文件中读取配置信息,当指定`read_file`参数为`False`时,则以默认配置创建。
-**参数:**
+***
-- `driver_path`:chromedriver.exe 路径
-- `chrome_path`:chrome.exe 路径
-- `local_port`:本地端口号
-- `debugger_address`:调试浏览器地址,会覆盖`local_port`设置,例:127.0.0.1:9222
-- `download_path`:下载文件路径
-- `user_data_path`:用户数据路径
-- `cache_path`:缓存路径
+# ✔️ 使用方法
-**返回:**`None`
+创建配置对象后,可调整配置内容,然后在页面对象创建时以参数形式把配置对象传递进去,页面对象会根据配置对象的内容对浏览器进行初始化。
-## 📍 `save()`
+```python
+from DrissionPage import WebPage, ChromiumOptions
-此方法用于保存当前配置对象的信息到配置文件。
+# 创建配置对象(默认从 ini 文件中读取配置)
+co = ChromiumOptions()
+# 设置不加载图片、静音
+co.set_no_imgs(True).set_mute(True)
-**参数:**
+# 以该配置创建页面对象
+page = WebPage(driver_or_options=co)
+```
-- `path`:配置文件的路径,默认保存到当前读取的配置文件,传入`'default'`保存到默认 ini 文件
+***
-**返回:**配置文件绝对路径
+# ✔️ 浏览器地址
-## 📍 `save_to_default()`
+## 📍 `debugger_address`
-此方法用于保存当前配置对象的信息到默认 ini 文件。
+该属性为要控制的浏览器地址,格式为 ip:port,默认为`'127.0.0.0:9222'`。可对其赋值进行设置。也可以用后文介绍的`set_paths()`方法设置。
-**参数:** 无
+```python
+co.debugger_address = 'localhost:9333'
+```
-**返回:** 配置文件绝对路径
+***
-## 📍 `remove_argument()`
+# ✔️ 启动参数配置
-此方法用于移除一个`argument`项。
+Chromium 内核浏览器有一系列的启动配置,以`--`开头,可在浏览器创建时传入。如`--headless`无界面模式,`--disable-images`禁用图像等。有些参数只有参数名,有些会带有值。
-**参数:**
+启动参数非常多,详见:[List of Chromium Command Line Switches « Peter Beverloo](https://peter.sh/experiments/chromium-command-line-switches/)
-- `value`:设置项名称,带有值的设置项传入设置名称即可
-
-**返回:** 当前对象
-
-## 📍 `remove_experimental_option()`
-
-此方法用于移除一个实验设置,传入 key 值删除。
-
-**参数:**
-
-- `key`:实验设置的名称
-
-**返回:** 当前对象
-
-## 📍 `remove_all_extensions()`
-
-此方法用于移除所有插件。
-
-**参数:** 无
-
-**返回:** 当前对象
+`set_argument()`和`remove_argument()`方法用于设置浏览器启动命令行参数。
## 📍 `set_argument()`
-此方法用于设置浏览器配置的`argument`属性。
+此方法用于设置启动参数,带值和不带值的参数项都可以。
-**参数:**
+| 参数名称 | 类型 | 默认值 | 说明 |
+|:-------:|:--------------------------:|:------:| ------------------------------------------------- |
+| `arg` | `str` | 无 | 启动参数名称 |
+| `value` | `str`
`None`
`False` | `None` | 参数的值。带值的参数传入属性值,没有的传入`None`。
如传入`False`,删除该参数。 |
-- `arg`:属性名
-- `value`:属性值,有值的属性传入值,没有的传入`bool`类型表示开关
+| 返回类型 | 说明 |
+| ----------------- | ------ |
+| `ChromiumOptions` | 配置对象本身 |
-**返回:** 当前对象
+**示例:** 无值和有值的参数设置
+
+```python
+# 设置用无头模式启动浏览器
+co.set_argument('--headless')
+# 设置浏览器默认 user agent
+co.set_argument('--user-agent', 'Mozilla/5.0 (Macintos.....')
+```
+
+***
+
+## 📍 `remove_argument()`
+
+此方法用于在启动配置中删除一个启动参数,只要传入参数名称即可,不需要传入值。
+
+| 参数名称 | 类型 | 默认值 | 说明 |
+|:-----:|:-----:|:---:| ------------------- |
+| `arg` | `str` | 无 | 参数名称,有值的设置项传入设置名称即可 |
+
+| 返回类型 | 说明 |
+| ----------------- | ------ |
+| `ChromiumOptions` | 配置对象自身 |
+
+**示例:** 删除无值和有值的参数设置
+
+```python
+# 删除--headless参数
+co.remove_argument('--headless')
+# 删除--user-agent参数
+co.remove_argument('--user-agent')
+```
+
+***
+
+# ✔️ 插件配置
+
+`add_extension()`和`remove_extensions()`用于设置浏览器启动时要加载的插件。可以指定数量不限的插件。
+
+## 📍 `add_extension()`
+
+此方法用于添加一个插件到浏览器。
+
+| 参数名称 | 类型 | 默认值 | 说明 |
+|:------:|:---------------:|:---:| ---- |
+| `path` | `str`
`Path` | 无 | 插件路径 |
+
+| 返回类型 | 说明 |
+| ----------------- | ------ |
+| `ChromiumOptions` | 配置对象本身 |
+
+?>**Tips:**
根据作者的经验,把插件文件解压到一个独立文件夹,然后把插件路径指向这个文件夹,会比较稳定。
+
+**示例:**
+
+```python
+co.add_extension(r'D:\SwitchyOmega')
+```
+
+***
+
+## 📍 `remove_extensions()`
+
+此方法用于移除配置对象中保存的所有插件路径。如须移除部分插件,请移除全部后再重新添加需要的插件。
+
+**参数:** 无
+
+**返回:** 配置对象自身
+
+```python
+co.remove_extensions()
+```
+
+***
+
+# ✔️ 用户文件配置
+
+除了启动参数,还有大量配置信息保存在 preferences 文件,以下方法用于对用户文件进行设置。
+
+## 📍 `set_user()`
+
+Chromium 浏览器支持多用户配置,我们可以选择使用哪一个。默认为`'Default'`。
+
+| 参数名称 | 类型 | 默认值 | 说明 |
+|:------:|:-----:|:-----------:| --------- |
+| `user` | `str` | `'Default'` | 用户配置文件夹名称 |
+
+| 返回类型 | 说明 |
+| ----------------- | ------ |
+| `ChromiumOptions` | 配置对象本身 |
+
+**示例:**
+
+```python
+co.set_user(user='Profile 1')
+```
+
+***
+
+## 📍 `set_pref()`
+
+此方法用于设置用户配置文件里的一个配置项。
+
+在哪里可以查到所有的配置项?作者也没找到,知道的请告知。谢谢。
+
+| 参数名称 | 类型 | 默认值 | 说明 |
+|:-------:|:-----:|:---:| ----- |
+| `arg` | `str` | 无 | 设置项名称 |
+| `value` | `str` | 无 | 设置项值 |
+
+| 返回类型 | 说明 |
+| ----------------- | ------ |
+| `ChromiumOptions` | 配置对象本身 |
+
+**示例:**
+
+```python
+co.set_pref(arg='profile.default_content_settings.popups', value='0')
+```
+
+***
+
+## 📍 `remove_pref()`
+
+此方法用于在当前配置对象中删除一个`pref`配置项。
+
+| 参数名称 | 类型 | 默认值 | 说明 |
+|:-----:|:-----:|:---:| ----- |
+| `arg` | `str` | 无 | 设置项名称 |
+
+| 返回类型 | 说明 |
+| ----------------- | ------ |
+| `ChromiumOptions` | 配置对象本身 |
+
+**示例:**
+
+```python
+co.remove_pref(arg='profile.default_content_settings.popups')
+```
+
+***
+
+## 📍 `remove_pref_from_file()`
+
+此方法用于在用户配置文件删除一个配置项。注意与上一个方法不一样,如果用户配置文件中已经存在某个项,用`remove_pref()`是不能删除的,只能用`remove_pref_from_file()`删除。
+
+| 参数名称 | 类型 | 默认值 | 说明 |
+|:-----:|:-----:|:---:| ----- |
+| `arg` | `str` | 无 | 设置项名称 |
+
+| 返回类型 | 说明 |
+| ----------------- | ------ |
+| `ChromiumOptions` | 配置对象本身 |
+
+**示例:**
+
+```python
+co.remove_pref_from_file(arg='profile.default_content_settings.popups')
+```
+
+***
+
+# ✔️ 运行参数配置
+
+页面对象运行时需要用到的参数,也可以在`ChromiumOptions`中设置。
+
+## 📍 `set_paths()`
+
+此方法用于设置各种路径信息。对有传入值的路径进行设置,为`None`的则无视。
+
+| 参数名称 | 类型 | 默认值 | 说明 |
+|:------------------:|:---------------:|:------:| ----------------------------------------------------------- |
+| `browser_path` | `str`
`Path` | `None` | 浏览器可执行文件路径 |
+| `local_port` | `str`
`int` | `None` | 浏览器要使用的本地端口号 |
+| `debugger_address` | `str` | `None` | 浏览器地址,例:127.0.0.1:9222,如与`local_port`一起设置,会覆盖`local_port`的值 |
+| `download_path` | `str`
`Path` | `None` | 下载文件默认保存路径 |
+| `user_data_path` | `str`
`Path` | `None` | 用户数据文件夹路径 |
+| `cache_path` | `str`
`Path` | `None` | 缓存路径 |
+
+| 返回类型 | 说明 |
+| ----------------- | ------ |
+| `ChromiumOptions` | 配置对象本身 |
+
+**示例:**
+
+```python
+co.set_paths(local_port=9333, user_data_path=r'D:\tmp')
+```
+
+***
+
+## 📍 `auto_port()`
+
+此方法用于设置是否使用自动分配的端口。
+
+如果设置为`True`,程序会自动寻找一个可用端口,并在系统临时文件夹创建一个文件夹,用于储存浏览器数据。由于端口和用户文件夹都是唯一的,所以用这种方式启动的浏览器不会产生冲突,但也无法多次启动程序时重复接管同一个浏览器。
+
+`set_paths()`方法中`local_port`和`user_data_path`参数,会和`auto_port()`互相覆盖,即以后调用的为准。
+
+| 参数名称 | 类型 | 默认值 | 说明 |
+|:--------:|:------:|:------:| ---------------- |
+| `on_off` | `bool` | `True` | 是否开启自动分配端口和用户文件夹 |
+
+| 返回类型 | 说明 |
+| ----------------- | ------ |
+| `ChromiumOptions` | 配置对象本身 |
+
+**示例:**
+
+```python
+co.auto_port(True)
+```
+
+!>**注意:**
启用此功能后即会获取端口和新建临时用户数据文件夹,若此时用`save()`方法保存配置到 ini 文件,ini 文件中的设置会被该端口和文件夹路径覆盖。这个覆盖对使用并没有很大影响。
+
+***
## 📍 `set_timeouts()`
-此方法用于设置三种超时时间。
+此方法用于设置几种超时时间,以秒为单位。超时用法详见使用方法章节。
-**参数:**
+| 参数名称 | 类型 | 默认值 | 说明 |
+|:----------:|:----------------:|:------:| ------------------------------------------------------------- |
+| `implicit` | `int`
`float` | `None` | 默认超时时间,用于元素等待、alert 等待、`WebPage`的 s 模式连接等等,除以下两个参数的场景,都使用这个设置 |
+| `pageLoad` | `int`
`float` | `None` | 页面加载超时时间 |
+| `script` | `int`
`float` | `None` | JavaScript 运行超时时间 |
-- `implicit`:查找元素超时时间
-- `pageLoad`:页面加载超时时间
-- `script`:脚本运行超时时间
+| 返回类型 | 说明 |
+| ----------------- | ------ |
+| `ChromiumOptions` | 配置对象本身 |
-**返回:** 当前对象
+**示例:**
+
+```python
+co.set_timeouts(implicit=10)
+```
+
+***
+
+## 📍 `set_page_load_strategy()`
+
+此方法用于设置网页加载策略。
+
+加载策略是指强制页面停止加载的时机,如加载完 DOM 即停止,不加载图片资源等,以提高自动化效率。
+
+无论设置哪种策略,加载时间都不会超过`set_timeouts()`中`pageLoad`参数设置的时间。
+
+加载策略:
+
+- `'normal'`:阻塞进程,等待所有资源下载完成(默认)
+
+- `'eager'`:DOM 就绪即停止加载
+
+- `'none'`:网页连接成功即停止加载
+
+| 参数名称 | 类型 | 默认值 | 说明 |
+|:-------:|:-----:|:---:| -------------------------------- |
+| `value` | `str` | 无 | 可接收`'normal'`、`'eager'`、`'none'` |
+
+| 返回类型 | 说明 |
+| ----------------- | ------ |
+| `ChromiumOptions` | 配置对象本身 |
+
+**示例:**
+
+```python
+co.set_page_load_strategy('eager')
+```
+
+***
+
+## 📍 `set_proxy()`
+
+该方法用于设置浏览器代理。
+
+| 参数名称 | 类型 | 默认值 | 说明 |
+|:-------:|:-----:|:---:| --------------------------------------- |
+| `proxy` | `str` | 无 | 格式:协议://ip:port
当不指定协议时,默认使用 http 代理 |
+
+| 返回类型 | 说明 |
+| ----------------- | ------ |
+| `ChromiumOptions` | 配置对象本身 |
+
+**示例:**
+
+```python
+co.set_proxy('http://localhost:1080')
+```
+
+***
+
+# ✔️ 其它配置
+
+作者将一些常用的配置封装成方法,可以直接调用。
## 📍 `set_headless()`
-该方法用于设置是否已无头模式启动浏览器。
+该方法用于设置是否已无界面模式启动浏览器。
-**参数:**
+| 参数名称 | 类型 | 默认值 | 说明 |
+|:--------:|:------:|:------:| ------------------- |
+| `on_off` | `bool` | `True` | `True`和`False`表示开或关 |
-- `on_off`:`bool`类型,表示开或关
+| 返回类型 | 说明 |
+| ----------------- | ------ |
+| `ChromiumOptions` | 配置对象本身 |
-**返回:**`None`
+**示例:**
+
+```python
+co.set_headless(True)
+```
+
+!>**注意:**
经实测,Chrome 使用无界面模式时,由 js 生成的元素可能不能加载。
+
+***
## 📍 `set_no_imgs()`
该方法用于设置是否禁止加载图片。
-**参数:**
+| 参数名称 | 类型 | 默认值 | 说明 |
+|:--------:|:------:|:------:| ------------------- |
+| `on_off` | `bool` | `True` | `True`和`False`表示开或关 |
-- `on_off`:`bool`类型,表示开或关
+| 返回类型 | 说明 |
+| ----------------- | ------ |
+| `ChromiumOptions` | 配置对象本身 |
-**返回:**`None`
+**示例:**
+
+```python
+co.set_no_imgs(True)
+```
+
+***
+
+## 📍 `set_no_js()`
+
+该方法用于设置是否禁用 JavaScript。
+
+| 参数名称 | 类型 | 默认值 | 说明 |
+|:--------:|:------:|:------:| ------------------- |
+| `on_off` | `bool` | `True` | `True`和`False`表示开或关 |
+
+| 返回类型 | 说明 |
+| ----------------- | ------ |
+| `ChromiumOptions` | 配置对象本身 |
+
+**示例:**
+
+```python
+co.set_no_js(True)
+```
+
+***
## 📍 `set_mute()`
该方法用于设置是否静音。
-**参数:**
+| 参数名称 | 类型 | 默认值 | 说明 |
+|:--------:|:------:|:------:| ------------------- |
+| `on_off` | `bool` | `True` | `True`和`False`表示开或关 |
-- `on_off`:`bool`类型,表示开或关
+| 返回类型 | 说明 |
+| ----------------- | ------ |
+| `ChromiumOptions` | 配置对象本身 |
-**返回:**`None`
+**示例:**
-## 📍 `set_proxy()`
+```python
+co.set_mute(True)
+```
-该方法用于设置代理。
-
-**参数:**
-
-- `proxy`:代理网址和端口,如 127.0.0.1:1080
-
-**返回:**`None`
+***
## 📍 `set_user_agent()`
该方法用于设置 user agent。
-**参数:**
+| 参数名称 | 类型 | 默认值 | 说明 |
+|:------------:|:-----:|:---:| ------------ |
+| `user_agent` | `str` | 无 | user agent文本 |
-- `user_agent`:user agent 文本
+| 返回类型 | 说明 |
+| ----------------- | ------ |
+| `ChromiumOptions` | 配置对象本身 |
-**返回:**`None`
+**示例:**
-## 📍 `as_dict()`
+```python
+co.set_user_agent(user_agent='Mozilla/5.0 (Macintos.....')
+```
-该方法以`dict`方式返回所有配置信息。
+***
+
+# ✔️ 保存设置到文件
+
+您可以把不同的配置保存到各自的 ini 文件,以便适应不同的场景。
+
+## 📍 `save()`
+
+此方法用于保存配置项到一个 ini 文件。
+
+| 参数名称 | 类型 | 默认值 | 说明 |
+|:------:|:---------------:|:------:| ------------------------------- |
+| `path` | `str`
`Path` | `None` | ini 文件的路径, 传入`None`保存到当前读取的配置文件 |
+
+| 返回类型 | 说明 |
+| ----- | -------------- |
+| `str` | 保存的 ini 文件绝对路径 |
+
+**示例:**
+
+```python
+# 保存当前读取的ini文件
+co.save()
+
+# 把当前配置保存到指定的路径
+co.save(path=r'D:\tmp')
+```
+
+***
+
+## 📍 `save_to_default()`
+
+此方法用于保存配置项到固定的默认 ini 文件。默认 ini 文件是指随`DrissionPage`内置的那个。
**参数:** 无
-**返回:** 配置信息
+| 返回类型 | 说明 |
+| ----- | -------------- |
+| `str` | 保存的 ini 文件绝对路径 |
-# ✔️ 简单示例
+**示例:**
```python
-from DrissionPage import WebPage, DriverOptions
-
-# 创建配置对象(默认从 ini 文件中读取配置)
-do = DriverOptions()
-# 设置不加载图片、静音
-do.set_no_imgs(True).set_mute(True)
-
-# 以该配置创建页面对象
-page = WebPage(driver_or_options=do)
+co.save_to_default()
```
diff --git a/docs/版本历史.md b/docs/版本历史.md
index b2239d4..0e32d6d 100644
--- a/docs/版本历史.md
+++ b/docs/版本历史.md
@@ -1,14 +1,71 @@
-# v3.0.33
+# v3.1.0
+
+- 增强下载功能
+
+ - `ChromiumPage`也可以使用内置下载器下载文件
+
+ - 可拦截并接管浏览器下载任务
+
+ - 新增`download_set`属性对下载参数进行设置
+
+ - 增加`wait_download_begin()`方法
+
+ - 重构部分代码
+
+- 改进浏览器启动设置
+
+ - 优化 ini 文件结构
+
+ - 新增`ChromiumOptions`取代`DriverOptions`,完全摆脱对 selenium 的依赖
+
+ - 新增自动分配端口功能
+
+ - 优化`SessionOptions`设计,增加一系列设置参数的方法
+
+ - 改进对用户配置文件的设置
+
+- 对部分代码进行重构
+
+ - 优化页面对象启动逻辑
+
+ - 优化配置类逻辑
+
+ - 优化项目结构
+
+- 细节
+
+ - 上传文件时支持传入相对路径
+
+- bug 修复
+
+ - 修复`get_tab()`出错问题
+
+ - 修复新浏览器第一次新建标签页时不正确切换的问题
+
+ - 修复关闭当前标签页出错问题
+
+ - 修复改变浏览器窗口大小出错问题
+
+# v3.0.34
- `WebPage`删除`check_page()`方法
+
- `DriverOptions`和`easy_set`的`set_paths()`增加`browser_path`参数
+
- `DriverOptions`增加`browser_path`属性
+
- `ChromiumFrame`现在支持页面滚动
+
- 改进滚动到元素功能
+
- 修改`SessionElement`相对定位参数顺序
+
- `SessionPage`也可以从 ini 文件读取 timeout 设置
-- ini 文件中`session_options`增加`timeout`项
-- `SessionOptions`增加`timeout`属性
+
+- ini 文件中`session_options`增加`timeout`项
+
+- `SessionOptions`增加`timeout`属性、`set_timeout()`方法
+
- 优化和修复一些问题
# v3.0.31
@@ -72,8 +129,8 @@
# v2.7.1
- DriverPage
- - 增加`get_session_storage()`、`get_local_storage()`、`set_session_storage()`、`set_local_storage()`、`clean_cache()`方法
- - `run_cdp()`的`cmd_args`参数改为`**cmd_args`
+ - 增加`get_session_storage()`、`get_local_storage()`、`set_session_storage()`、`set_local_storage()`、`clean_cache()`方法
+ - `run_cdp()`的`cmd_args`参数改为`**cmd_args`
- 关闭 driver 时会主动关闭 chromedriver.exe 的进程
- 优化关闭浏览器进程逻辑
@@ -85,9 +142,9 @@
# v2.6.0
- 新增`Listener`类
- - 可监听浏览器数据包
- - 可异步监听
- - 可实现每监听到若干数据包执行操作
+ - 可监听浏览器数据包
+ - 可异步监听
+ - 可实现每监听到若干数据包执行操作
- 放弃对selenium4.1以下的支持
- 解决使用新版浏览器时出现的一些问题
diff --git a/docs/进阶使用/加速浏览器数据采集.md b/docs/进阶使用/加速浏览器数据采集.md
new file mode 100644
index 0000000..e69de29
diff --git a/requirements.txt b/requirements.txt
index 36f1173..801a504 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -3,6 +3,6 @@ requests
tldextract
lxml
cssselect
-DownloadKit>=0.4.4
+DownloadKit>=0.5.0
FlowViewer>=0.2.1
websocket-client
\ No newline at end of file
diff --git a/setup.py b/setup.py
index 72f5947..b7788ca 100644
--- a/setup.py
+++ b/setup.py
@@ -22,7 +22,7 @@ setup(
"lxml",
"tldextract",
"requests",
- "DownloadKit>=0.4.4",
+ "DownloadKit>=0.5.0",
"FlowViewer",
"websocket-client"
],