pax_global_header 0000666 0000000 0000000 00000000064 14773556132 0014527 g ustar 00root root 0000000 0000000 52 comment=d8c108f73de9d4045c5308cf8eb77370c8d5a02d
dbus-fast-2.44.1/ 0000775 0000000 0000000 00000000000 14773556132 0013507 5 ustar 00root root 0000000 0000000 dbus-fast-2.44.1/.all-contributorsrc 0000664 0000000 0000000 00000000450 14773556132 0017337 0 ustar 00root root 0000000 0000000 {
"projectName": "dbus-fast",
"projectOwner": "bluetooth-devices",
"repoType": "github",
"repoHost": "https://github.com",
"files": ["README.md"],
"imageSize": 80,
"commit": true,
"commitConvention": "angular",
"contributors": [],
"contributorsPerLine": 7,
"skipCi": true
}
dbus-fast-2.44.1/.editorconfig 0000664 0000000 0000000 00000000444 14773556132 0016166 0 ustar 00root root 0000000 0000000 # http://editorconfig.org
root = true
[*]
indent_style = space
indent_size = 4
trim_trailing_whitespace = true
insert_final_newline = true
charset = utf-8
end_of_line = lf
[*.bat]
indent_style = tab
end_of_line = crlf
[LICENSE]
insert_final_newline = false
[Makefile]
indent_style = tab
dbus-fast-2.44.1/.flake8 0000664 0000000 0000000 00000000056 14773556132 0014663 0 ustar 00root root 0000000 0000000 [flake8]
exclude = docs
max-line-length = 180
dbus-fast-2.44.1/.github/ 0000775 0000000 0000000 00000000000 14773556132 0015047 5 ustar 00root root 0000000 0000000 dbus-fast-2.44.1/.github/ISSUE_TEMPLATE/ 0000775 0000000 0000000 00000000000 14773556132 0017232 5 ustar 00root root 0000000 0000000 dbus-fast-2.44.1/.github/ISSUE_TEMPLATE/1-bug_report.md 0000664 0000000 0000000 00000000422 14773556132 0022060 0 ustar 00root root 0000000 0000000 ---
name: Bug report
about: Create a report to help us improve
labels: bug
---
**Describe the bug**
A clear and concise description of what the bug is.
**To Reproduce**
Steps to reproduce the behavior:
**Additional context**
Add any other context about the problem here.
dbus-fast-2.44.1/.github/ISSUE_TEMPLATE/2-feature-request.md 0000664 0000000 0000000 00000000672 14773556132 0023041 0 ustar 00root root 0000000 0000000 ---
name: Feature request
about: Suggest an idea for this project
labels: enhancement
---
**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
**Describe the solution you'd like**
A clear and concise description of what you want to happen.
**Additional context**
Add any other context or screenshots about the feature request here.
dbus-fast-2.44.1/.github/dependabot.yml 0000664 0000000 0000000 00000001351 14773556132 0017677 0 ustar 00root root 0000000 0000000 # To get started with Dependabot version updates, you'll need to specify which
# package ecosystems to update and where the package manifests are located.
# Please see the documentation for all configuration options:
# https://docs.github.com/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file
version: 2
updates:
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "monthly"
commit-message:
prefix: "chore(deps-ci): "
groups:
github-actions:
patterns:
- "*"
- package-ecosystem: "pip" # See documentation for possible values
directory: "/" # Location of package manifests
schedule:
interval: "weekly"
dbus-fast-2.44.1/.github/labels.toml 0000664 0000000 0000000 00000003515 14773556132 0017212 0 ustar 00root root 0000000 0000000 [breaking]
color = "ffcc00"
name = "breaking"
description = "Breaking change."
[bug]
color = "d73a4a"
name = "bug"
description = "Something isn't working"
[dependencies]
color = "0366d6"
name = "dependencies"
description = "Pull requests that update a dependency file"
[github_actions]
color = "000000"
name = "github_actions"
description = "Update of github actions"
[documentation]
color = "1bc4a5"
name = "documentation"
description = "Improvements or additions to documentation"
[duplicate]
color = "cfd3d7"
name = "duplicate"
description = "This issue or pull request already exists"
[enhancement]
color = "a2eeef"
name = "enhancement"
description = "New feature or request"
["good first issue"]
color = "7057ff"
name = "good first issue"
description = "Good for newcomers"
["help wanted"]
color = "008672"
name = "help wanted"
description = "Extra attention is needed"
[invalid]
color = "e4e669"
name = "invalid"
description = "This doesn't seem right"
[nochangelog]
color = "555555"
name = "nochangelog"
description = "Exclude pull requests from changelog"
[question]
color = "d876e3"
name = "question"
description = "Further information is requested"
[removed]
color = "e99695"
name = "removed"
description = "Removed piece of functionalities."
[tests]
color = "bfd4f2"
name = "tests"
description = "CI, CD and testing related changes"
[wontfix]
color = "ffffff"
name = "wontfix"
description = "This will not be worked on"
[discussion]
color = "c2e0c6"
name = "discussion"
description = "Some discussion around the project"
[hacktoberfest]
color = "ffa663"
name = "hacktoberfest"
description = "Good issues for Hacktoberfest"
[answered]
color = "0ee2b6"
name = "answered"
description = "Automatically closes as answered after a delay"
[waiting]
color = "5f7972"
name = "waiting"
description = "Automatically closes if no answer after a delay"
dbus-fast-2.44.1/.github/workflows/ 0000775 0000000 0000000 00000000000 14773556132 0017104 5 ustar 00root root 0000000 0000000 dbus-fast-2.44.1/.github/workflows/ci.yml 0000664 0000000 0000000 00000020054 14773556132 0020223 0 ustar 00root root 0000000 0000000 name: CI
on:
push:
branches:
- main
pull_request:
concurrency:
group: ${{ github.head_ref || github.run_id }}
cancel-in-progress: true
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
- uses: actions/setup-python@8d9ed9ac5c53483de85588cdf95a591a75ab9f55 # v5
with:
python-version: "3.9"
- uses: pre-commit/action@2c7b3805fd2a0fd8c1884dcaebf91fc102a13ecd # v3.0.1
# Make sure commit messages follow the conventional commits convention:
# https://www.conventionalcommits.org
commitlint:
name: Lint Commit Messages
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
with:
fetch-depth: 0
- uses: wagoid/commitlint-github-action@b948419dd99f3fd78a6548d48f94e3df7f6bf3ed # v6
test:
strategy:
fail-fast: false
matrix:
python-version:
- "3.9"
- "3.10"
- "3.11"
- "3.12"
- "3.13"
os:
- ubuntu-latest
extension:
- "skip_cython"
- "use_cython"
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
- name: Install libs
run: sudo apt-get install -y dbus-daemon python3-gi libgirepository1.0-dev gcc libcairo2-dev pkg-config python3-dev gir1.2-gtk-3.0
- uses: snok/install-poetry@76e04a911780d5b312d89783f7b1cd627778900a # v1.4.1
- name: Set up Python
uses: actions/setup-python@8d9ed9ac5c53483de85588cdf95a591a75ab9f55 # v5
with:
python-version: ${{ matrix.python-version }}
cache: "poetry"
allow-prereleases: true
- name: Install Dependencies
run: |
if [ "${{ matrix.extension }}" = "skip_cython" ]; then
SKIP_CYTHON=1 poetry install --only=main,dev
else
REQUIRE_CYTHON=1 poetry install --only=main,dev
fi
- name: Test with Pytest
run: dbus-run-session -- poetry run pytest --cov-report=xml --timeout=5
- name: Upload coverage to Codecov
uses: codecov/codecov-action@0565863a31f2c772f9f0395002a31e3f06189574 # v5
with:
token: ${{ secrets.CODECOV_TOKEN }}
test_big_endian:
name: Big-endian s390x tests
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
- uses: uraimo/run-on-arch-action@1c358dc49363439f8c563ce8f93005f7fe76b849 # v3
name: Run commands
id: runcmd
with:
arch: s390x
distro: ubuntu_latest
run: |
apt-get -y update
apt-get -y install git python3-pip python3-venv python3-poetry dbus-daemon python3-gi libgirepository1.0-dev gcc libcairo2-dev pkg-config python3-dev gir1.2-gtk-3.0
git clone --depth 1 $GITHUB_SERVER_URL/$GITHUB_REPOSITORY
cd dbus-fast
git fetch origin --depth 1 $GITHUB_SHA
git checkout $GITHUB_SHA
REQUIRE_CYTHON=1 poetry install --only=main,dev
dbus-run-session -- poetry run pytest --no-cov --timeout=100
benchmark:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
- name: Install libs
run: sudo apt-get install -y dbus-daemon python3-gi libgirepository1.0-dev gcc libcairo2-dev pkg-config python3-dev gir1.2-gtk-3.0
- uses: snok/install-poetry@76e04a911780d5b312d89783f7b1cd627778900a # v1.4.1
- name: Setup Python 3.13
uses: actions/setup-python@8d9ed9ac5c53483de85588cdf95a591a75ab9f55 # v5
with:
python-version: 3.13
cache: "poetry"
- name: Install Dependencies
run: |
REQUIRE_CYTHON=1 poetry install --only=main,dev
shell: bash
- name: Run benchmarks
uses: CodSpeedHQ/action@0010eb0ca6e89b80c88e8edaaa07cfe5f3e6664d # v3
with:
token: ${{ secrets.CODSPEED_TOKEN }}
run: dbus-run-session -- poetry run pytest --no-cov -vvvvv --codspeed tests/benchmarks
release:
needs:
- test
- lint
- commitlint
runs-on: ubuntu-latest
environment: release
concurrency: release
permissions:
id-token: write
contents: write
outputs:
released: ${{ steps.release.outputs.released }}
newest_release_tag: ${{ steps.release_tag.outputs.newest_release_tag }}
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
with:
fetch-depth: 0
ref: ${{ github.head_ref || github.ref_name }}
# Do a dry run of PSR
- name: Test release
uses: python-semantic-release/python-semantic-release@26bb37cfab71a5a372e3db0f48a6eac57519a4a6 # v9.21.0
if: github.ref_name != 'main'
with:
root_options: --noop
# On main branch: actual PSR + upload to PyPI & GitHub
- name: Release
uses: python-semantic-release/python-semantic-release@26bb37cfab71a5a372e3db0f48a6eac57519a4a6 # v9.21.0
id: release
if: github.ref_name == 'main'
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
- name: Publish package distributions to PyPI
uses: pypa/gh-action-pypi-publish@76f52bc884231f62b9a034ebfe128415bbaabdfc # release/v1
if: steps.release.outputs.released == 'true'
- name: Publish package distributions to GitHub Releases
uses: python-semantic-release/upload-to-gh-release@0a92b5d7ebfc15a84f9801ebd1bf706343d43711 # main
if: steps.release.outputs.released == 'true'
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
- name: Install python-semantic-release
run: python3 -m pip install python-semantic-release==7.34.6
- name: Get Release Tag
id: release_tag
shell: bash
run: |
echo "newest_release_tag=$(semantic-release print-version --current)" >> $GITHUB_OUTPUT
build_wheels:
needs: [release]
if: needs.release.outputs.released == 'true'
name: Build wheels on ${{ matrix.os }} with arch ${{ matrix.arch }}
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-24.04-arm, ubuntu-latest, macos-latest]
musl: ["", "musllinux"]
exclude:
- os: macos-latest
musl: "musllinux"
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
with:
ref: "v${{ needs.release.outputs.newest_release_tag }}"
fetch-depth: 0
# Used to host cibuildwheel
- name: Set up Python
uses: actions/setup-python@8d9ed9ac5c53483de85588cdf95a591a75ab9f55 # v5
- name: Install cibuildwheel
run: python -m pip install cibuildwheel==2.22.0
- name: Build wheels
run: python -m cibuildwheel --output-dir wheelhouse
# to supply options, put them in 'env', like:
env:
CIBW_SKIP: "*p36-* *p37-* *p38-* ${{ matrix.musl == 'musllinux' && '*manylinux*' || '*musllinux*' }}"
CIBW_BEFORE_ALL_LINUX: apt-get install -y gcc || yum install -y gcc || apk add gcc
CIBW_BUILD_VERBOSITY: 3
REQUIRE_CYTHON: 1
CIBW_ARCHS_LINUX: ${{ matrix.os == 'ubuntu-24.04-arm' && 'aarch64' || 'auto' }}
- uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
with:
path: ./wheelhouse/*.whl
name: wheels-${{ matrix.os }}-${{ matrix.musl }}
upload_pypi:
needs: [build_wheels]
runs-on: ubuntu-latest
environment: release
permissions:
id-token: write
contents: write
steps:
- uses: actions/download-artifact@95815c38cf2ff2164869cbab79da8d1f422bc89e # v4
with:
# unpacks default artifact into dist/
# if `name: artifact` is omitted, the action will create extra parent dir
pattern: wheels-*
path: dist
merge-multiple: true
- uses: pypa/gh-action-pypi-publish@76f52bc884231f62b9a034ebfe128415bbaabdfc # v1.12.4
dbus-fast-2.44.1/.github/workflows/hacktoberfest.yml 0000664 0000000 0000000 00000000607 14773556132 0022456 0 ustar 00root root 0000000 0000000 name: Hacktoberfest
on:
schedule:
# Run every day in October
- cron: "0 0 * 10 *"
# Run on the 1st of November to revert
- cron: "0 13 1 11 *"
jobs:
hacktoberfest:
runs-on: ubuntu-latest
steps:
- uses: browniebroke/hacktoberfest-labeler-action@4b84e14a51c188ef9fb917854ae8310440c27bae # v2.3.0
with:
github_token: ${{ secrets.GH_PAT }}
dbus-fast-2.44.1/.github/workflows/issue-manager.yml 0000664 0000000 0000000 00000001413 14773556132 0022366 0 ustar 00root root 0000000 0000000 name: Issue Manager
on:
schedule:
- cron: "0 0 * * *"
issue_comment:
types:
- created
issues:
types:
- labeled
pull_request_target:
types:
- labeled
workflow_dispatch:
jobs:
issue-manager:
runs-on: ubuntu-latest
steps:
- uses: tiangolo/issue-manager@f94f76c8fa2c48bb2982a099c29a0caadb92917e # 0.5.1
with:
token: ${{ secrets.GITHUB_TOKEN }}
config: >
{
"answered": {
"message": "Assuming the original issue was solved, it will be automatically closed now."
},
"waiting": {
"message": "Automatically closing. To re-open, please provide the additional information requested."
}
}
dbus-fast-2.44.1/.github/workflows/labels.yml 0000664 0000000 0000000 00000001122 14773556132 0021065 0 ustar 00root root 0000000 0000000 name: Sync Github labels
on:
push:
branches:
- main
paths:
- ".github/**"
jobs:
labels:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
- name: Set up Python
uses: actions/setup-python@8d9ed9ac5c53483de85588cdf95a591a75ab9f55 # v5
with:
python-version: 3.8
- name: Install labels
run: pip install labels
- name: Sync config with Github
run: labels -u ${{ github.repository_owner }} -t ${{ secrets.GITHUB_TOKEN }} sync -f .github/labels.toml
dbus-fast-2.44.1/.gitignore 0000664 0000000 0000000 00000004066 14773556132 0015505 0 ustar 00root root 0000000 0000000 # Created by .ignore support plugin (hsz.mobi)
### Python template
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
# C extensions
*.so
# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
*.py,cover
.hypothesis/
.pytest_cache/
cover/
# Translations
*.mo
*.pot
# Django stuff:
*.log
local_settings.py
db.sqlite3
db.sqlite3-journal
# Flask stuff:
instance/
.webassets-cache
# Scrapy stuff:
.scrapy
# Sphinx documentation
docs/_build/
# PyBuilder
.pybuilder/
target/
# Jupyter Notebook
.ipynb_checkpoints
# IPython
profile_default/
ipython_config.py
# pyenv
# For a library or package, you might want to ignore these files since the code is
# intended to run in multiple environments; otherwise, check them in:
# .python-version
# pipenv
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
# However, in case of collaboration, if having platform-specific dependencies or dependencies
# having no cross-platform support, pipenv may install dependencies that don't work, or not
# install all needed dependencies.
#Pipfile.lock
# PEP 582; used by e.g. github.com/David-OConnor/pyflow
__pypackages__/
# Celery stuff
celerybeat-schedule
celerybeat.pid
# SageMath parsed files
*.sage.py
# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/
# Spyder project settings
.spyderproject
.spyproject
# Rope project settings
.ropeproject
# mkdocs documentation
/site
# mypy
.mypy_cache/
.dmypy.json
dmypy.json
# Pyre type checker
.pyre/
# pytype static type analyzer
.pytype/
# Cython debug symbols
cython_debug/
dbus-fast-2.44.1/.gitpod.yml 0000664 0000000 0000000 00000000306 14773556132 0015575 0 ustar 00root root 0000000 0000000 tasks:
- command: |
pip install poetry
PIP_USER=false poetry install
- command: |
pip install pre-commit
pre-commit install
PIP_USER=false pre-commit install-hooks
dbus-fast-2.44.1/.idea/ 0000775 0000000 0000000 00000000000 14773556132 0014467 5 ustar 00root root 0000000 0000000 dbus-fast-2.44.1/.idea/dbus-fast.iml 0000664 0000000 0000000 00000000515 14773556132 0017063 0 ustar 00root root 0000000 0000000
dbus-fast-2.44.1/.idea/watcherTasks.xml 0000664 0000000 0000000 00000005253 14773556132 0017661 0 ustar 00root root 0000000 0000000
dbus-fast-2.44.1/.idea/workspace.xml 0000664 0000000 0000000 00000002725 14773556132 0017215 0 ustar 00root root 0000000 0000000
dbus-fast-2.44.1/.pre-commit-config.yaml 0000664 0000000 0000000 00000003113 14773556132 0017766 0 ustar 00root root 0000000 0000000 # See https://pre-commit.com for more information
# See https://pre-commit.com/hooks.html for more hooks
exclude: "CHANGELOG.md"
default_stages: [pre-commit]
ci:
autofix_commit_msg: "chore(pre-commit.ci): auto fixes"
autoupdate_commit_msg: "chore(pre-commit.ci): pre-commit autoupdate"
repos:
- repo: https://github.com/commitizen-tools/commitizen
rev: v4.4.1
hooks:
- id: commitizen
stages: [commit-msg]
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v5.0.0
hooks:
- id: debug-statements
- id: check-builtin-literals
- id: check-case-conflict
- id: check-json
- id: check-toml
- id: check-xml
- id: check-yaml
- id: detect-private-key
- id: end-of-file-fixer
- id: trailing-whitespace
- id: debug-statements
- repo: https://github.com/pre-commit/mirrors-prettier
rev: v4.0.0-alpha.8
hooks:
- id: prettier
args: ["--tab-width", "2"]
- repo: https://github.com/asottile/pyupgrade
rev: v3.19.1
hooks:
- id: pyupgrade
args: [--py39-plus]
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.11.2
hooks:
- id: ruff
args: [--fix, --exit-non-zero-on-fix]
- id: ruff-format
# - repo: https://github.com/codespell-project/codespell
# rev: v2.2.1
# hooks:
# - id: codespell
# - repo: https://github.com/PyCQA/flake8
# rev: 5.0.4
# hooks:
# - id: flake8
# - repo: https://github.com/pre-commit/mirrors-mypy
# rev: v0.931
# hooks:
# - id: mypy
# additional_dependencies: []
dbus-fast-2.44.1/.readthedocs.yml 0000664 0000000 0000000 00000001006 14773556132 0016572 0 ustar 00root root 0000000 0000000 # Read the Docs configuration file
# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details
# Required
version: 2
# Build documentation in the docs/ directory with Sphinx
sphinx:
configuration: docs/source/conf.py
# Set the version of Python and other tools you might need
build:
os: ubuntu-20.04
tools:
python: "3.12"
# Optionally declare the Python requirements required to build your docs
python:
install:
- requirements: docs/requirements.txt
- method: pip
path: .
dbus-fast-2.44.1/CHANGELOG.md 0000664 0000000 0000000 00000304030 14773556132 0015320 0 ustar 00root root 0000000 0000000 # CHANGELOG
## v2.44.1 (2025-04-03)
### Bug Fixes
- Correct documentation URLs in README
([#446](https://github.com/Bluetooth-Devices/dbus-fast/pull/446),
[`0bd01fc`](https://github.com/Bluetooth-Devices/dbus-fast/commit/0bd01fc1aaab3509f5549f1b3eac322e7af6319b))
## v2.44.0 (2025-04-01)
### Chores
- Pin github actions to specific SHAs to mitigate supply chain attacks
([#442](https://github.com/Bluetooth-Devices/dbus-fast/pull/442),
[`b69c865`](https://github.com/Bluetooth-Devices/dbus-fast/commit/b69c865738af4e72f3e2113cf7362f41d13ce1ef))
- **deps-dev**: Bump pytest-asyncio from 0.25.3 to 0.26.0
([#443](https://github.com/Bluetooth-Devices/dbus-fast/pull/443),
[`3f63386`](https://github.com/Bluetooth-Devices/dbus-fast/commit/3f633862a7f4d1dd9ae0c2412ec9cef495b69058))
- **deps-dev**: Bump setuptools from 76.0.0 to 78.0.1
([#439](https://github.com/Bluetooth-Devices/dbus-fast/pull/439),
[`33332d9`](https://github.com/Bluetooth-Devices/dbus-fast/commit/33332d9ec0bc980a68916457bcb59c04a3673a01))
Signed-off-by: dependabot[bot]
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
- **deps-dev**: Bump setuptools from 78.0.1 to 78.1.0
([#444](https://github.com/Bluetooth-Devices/dbus-fast/pull/444),
[`f59d9f9`](https://github.com/Bluetooth-Devices/dbus-fast/commit/f59d9f92c795c7aa0c62000a0c7a6c0a86d89337))
- **pre-commit.ci**: Pre-commit autoupdate
([#440](https://github.com/Bluetooth-Devices/dbus-fast/pull/440),
[`f00f224`](https://github.com/Bluetooth-Devices/dbus-fast/commit/f00f224da36f5a4340ec6641853722f6d7243dfb))
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
### Features
- Use trusted publishing to upload wheels
([#445](https://github.com/Bluetooth-Devices/dbus-fast/pull/445),
[`19df266`](https://github.com/Bluetooth-Devices/dbus-fast/commit/19df2666ab599eecb254a7e0c874fc7a5e0a5b01))
## v2.43.0 (2025-03-23)
### Features
- Improve unmarshall performance for SignatureType
([#436](https://github.com/Bluetooth-Devices/dbus-fast/pull/436),
[`e0aeeac`](https://github.com/Bluetooth-Devices/dbus-fast/commit/e0aeeacf8db3819f7771be35880fbbc2696ef434))
## v2.42.0 (2025-03-23)
### Features
- Simplify code to unmarshall arrays
([#435](https://github.com/Bluetooth-Devices/dbus-fast/pull/435),
[`958115f`](https://github.com/Bluetooth-Devices/dbus-fast/commit/958115f77bee0b35fde11386f507d96ad26597cc))
## v2.41.1 (2025-03-23)
### Bug Fixes
- No change re-release ([#433](https://github.com/Bluetooth-Devices/dbus-fast/pull/433),
[`f79930d`](https://github.com/Bluetooth-Devices/dbus-fast/commit/f79930d0c41845e78978bfcef02c35bdcba7e391))
## v2.41.0 (2025-03-23)
### Chores
- Add benchmark for interfaces added message
([#432](https://github.com/Bluetooth-Devices/dbus-fast/pull/432),
[`1988984`](https://github.com/Bluetooth-Devices/dbus-fast/commit/1988984398dac14daf93f11005b647b646bdf00a))
### Features
- Improve performance of unmarshalling boolean Variants
([#431](https://github.com/Bluetooth-Devices/dbus-fast/pull/431),
[`888a3c3`](https://github.com/Bluetooth-Devices/dbus-fast/commit/888a3c3ea57e1d8c5f415f2efdf7aa6eed5c9fcd))
* feat: improve performance of boolean Variants
There are only two of these type and relatively common so we can use pre-constructed objects
* chore: tweaks
## v2.40.0 (2025-03-23)
### Chores
- Add socket unmarshall benchmark ([#428](https://github.com/Bluetooth-Devices/dbus-fast/pull/428),
[`1802f35`](https://github.com/Bluetooth-Devices/dbus-fast/commit/1802f35ce9267d8af728045ba47277779af7fea7))
* chore: add socket unmarshall benchmark
* chore: bench multiple messages
- Remove lower python bound from PyGObject
([#425](https://github.com/Bluetooth-Devices/dbus-fast/pull/425),
[`28615ee`](https://github.com/Bluetooth-Devices/dbus-fast/commit/28615ee7eb00d7e50f68818f8c9915a1f570c8e5))
- **pre-commit.ci**: Pre-commit autoupdate
([#427](https://github.com/Bluetooth-Devices/dbus-fast/pull/427),
[`bfc8151`](https://github.com/Bluetooth-Devices/dbus-fast/commit/bfc8151005e143c961421d4e2c5e05ac58964100))
* chore(pre-commit.ci): pre-commit autoupdate
updates: - [github.com/astral-sh/ruff-pre-commit: v0.1.0 →
v0.11.0](https://github.com/astral-sh/ruff-pre-commit/compare/v0.1.0...v0.11.0)
* chore(pre-commit.ci): auto fixes
* chore: fix violations
---------
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: J. Nick Koston
### Features
- Improve unmarshaller performance for byte strings
([#430](https://github.com/Bluetooth-Devices/dbus-fast/pull/430),
[`3b4bac5`](https://github.com/Bluetooth-Devices/dbus-fast/commit/3b4bac5524435e5669bd5f513a9175f71af7f7a9))
## v2.39.6 (2025-03-17)
### Bug Fixes
- Don't limit python upper bound ([#424](https://github.com/Bluetooth-Devices/dbus-fast/pull/424),
[`9cafbb6`](https://github.com/Bluetooth-Devices/dbus-fast/commit/9cafbb6a0b70d975b73889ded99e2e0a6af2b467))
This requires all projects that depend on dbus-fast to have to set the same limit, which is an
unnecessary burden.
* fix: adjust pygobject pin to required python < 4 (see
https://gitlab.gnome.org/GNOME/pygobject/-/merge_requests/418)
---------
Co-authored-by: J. Nick Koston
### Chores
- Remove workflow from previous failed attempt at testing big-endian
([#423](https://github.com/Bluetooth-Devices/dbus-fast/pull/423),
[`20e102c`](https://github.com/Bluetooth-Devices/dbus-fast/commit/20e102ca8f0606f6abe26fb35a30e94997740bcc))
## v2.39.5 (2025-03-13)
### Bug Fixes
- Upgrade to ruff 0.1.0 and fix violations
([#422](https://github.com/Bluetooth-Devices/dbus-fast/pull/422),
[`7e4cab6`](https://github.com/Bluetooth-Devices/dbus-fast/commit/7e4cab6778e8cfb2894e638a7d47eff1cc191bff))
## v2.39.4 (2025-03-13)
### Bug Fixes
- Multiple calls on the root logger instead of module logger
([#421](https://github.com/Bluetooth-Devices/dbus-fast/pull/421),
[`b7c4a31`](https://github.com/Bluetooth-Devices/dbus-fast/commit/b7c4a3117e5978cb712469f75f49d5e2002614b8))
### Chores
- **deps-dev**: Bump setuptools from 75.8.2 to 76.0.0
([#418](https://github.com/Bluetooth-Devices/dbus-fast/pull/418),
[`128ba12`](https://github.com/Bluetooth-Devices/dbus-fast/commit/128ba128586ea740fa60d6be8ba311791b6dabb6))
- **pre-commit.ci**: Pre-commit autoupdate
([#420](https://github.com/Bluetooth-Devices/dbus-fast/pull/420),
[`45acd54`](https://github.com/Bluetooth-Devices/dbus-fast/commit/45acd54868c12f784287fb19104a3bf6bc17d745))
## v2.39.3 (2025-03-07)
### Bug Fixes
- Ensure void methods that can raise exceptions are marked
([#417](https://github.com/Bluetooth-Devices/dbus-fast/pull/417),
[`c433dab`](https://github.com/Bluetooth-Devices/dbus-fast/commit/c433dab7b5622f3103607acb1acd7a91db841419))
### Chores
- Update aio package typing ([#416](https://github.com/Bluetooth-Devices/dbus-fast/pull/416),
[`28888b9`](https://github.com/Bluetooth-Devices/dbus-fast/commit/28888b9f49e063b122d6116309fbb3d0aec984f7))
## v2.39.2 (2025-03-07)
### Bug Fixes
- Correct size of uint32 with cython
([#415](https://github.com/Bluetooth-Devices/dbus-fast/pull/415),
[`f64eb58`](https://github.com/Bluetooth-Devices/dbus-fast/commit/f64eb58573e068ad731f6dc268dd903dee2e66af))
* chore: add more coverage for big endian systems
* chore: fix overflow
* fix: should have been unsigned int
## v2.39.1 (2025-03-07)
### Bug Fixes
- Ensure proxy object tasks do not get garbage collected prematurely
([#409](https://github.com/Bluetooth-Devices/dbus-fast/pull/409),
[`4fcdbed`](https://github.com/Bluetooth-Devices/dbus-fast/commit/4fcdbed1e5ab828e95b2a16ac0058ebbe0a64f78))
## v2.39.0 (2025-03-06)
### Chores
- Enable some more ruff rules ([#414](https://github.com/Bluetooth-Devices/dbus-fast/pull/414),
[`2bad648`](https://github.com/Bluetooth-Devices/dbus-fast/commit/2bad648c61f139e168c083b05e183ceaa29005f8))
- Sort imports ([#413](https://github.com/Bluetooth-Devices/dbus-fast/pull/413),
[`a589651`](https://github.com/Bluetooth-Devices/dbus-fast/commit/a589651511e1787f0025d7ab440ed1617b133b48))
### Features
- Improve performance of signature lookups
([#412](https://github.com/Bluetooth-Devices/dbus-fast/pull/412),
[`5068e41`](https://github.com/Bluetooth-Devices/dbus-fast/commit/5068e41488e71499265e1fc3ea7d4210821e09a2))
- Added `SignatureTree` type in a few more places to avoid python lookups - Improved performance and
reduced code to create `Variant` object
## v2.38.0 (2025-03-06)
### Chores
- Remove unused boilerplate cruft ([#411](https://github.com/Bluetooth-Devices/dbus-fast/pull/411),
[`a56381a`](https://github.com/Bluetooth-Devices/dbus-fast/commit/a56381a7a10b243061f29d0f90b3fd63d2e600e4))
### Features
- Improve performance of checking SignatureType tokens
([#410](https://github.com/Bluetooth-Devices/dbus-fast/pull/410),
[`4887160`](https://github.com/Bluetooth-Devices/dbus-fast/commit/488716020e275ef777454724d2ab41cfc050b40a))
* feat: improve performance of checking SignatureType tokens
* chore: fixes
## v2.37.1 (2025-03-06)
### Bug Fixes
- Correctly handle big endian data ([#405](https://github.com/Bluetooth-Devices/dbus-fast/pull/405),
[`0adab93`](https://github.com/Bluetooth-Devices/dbus-fast/commit/0adab935e3c5850647e640c777daf4273ea1efd9))
### Chores
- Add s390x tests ([#408](https://github.com/Bluetooth-Devices/dbus-fast/pull/408),
[`81ce030`](https://github.com/Bluetooth-Devices/dbus-fast/commit/81ce03058a64e9fd304981ef9e05bf6415dc1fb3))
- Add more coverage for marshall ([#406](https://github.com/Bluetooth-Devices/dbus-fast/pull/406),
[`ed38f69`](https://github.com/Bluetooth-Devices/dbus-fast/commit/ed38f690f5926b17354810c51ac0dee900d9f01e))
- Fix type for hello message constant
([#407](https://github.com/Bluetooth-Devices/dbus-fast/pull/407),
[`df5325a`](https://github.com/Bluetooth-Devices/dbus-fast/commit/df5325a7ef80de544e16783deec3ea183e02d6ba))
core: fix type for hello message constant
- Update deps ([#404](https://github.com/Bluetooth-Devices/dbus-fast/pull/404),
[`6dca98d`](https://github.com/Bluetooth-Devices/dbus-fast/commit/6dca98d68af494641c91cf53949fe207188b99a3))
dependabot is still broken with poetry 2
- Updating certifi (2024.12.14 -> 2025.1.31) - Updating babel (2.16.0 -> 2.17.0) - Updating jinja2
(3.1.5 -> 3.1.6) - Updating coverage (7.6.10 -> 7.6.12)
## v2.37.0 (2025-03-06)
### Features
- Add support for finding message handlers when interface is None
([#403](https://github.com/Bluetooth-Devices/dbus-fast/pull/403),
[`bfd48a3`](https://github.com/Bluetooth-Devices/dbus-fast/commit/bfd48a3a38cba0dc66d581eedd0da0b228bc1953))
## v2.36.0 (2025-03-05)
### Chores
- Add covdefaults ([#401](https://github.com/Bluetooth-Devices/dbus-fast/pull/401),
[`dc3d8e7`](https://github.com/Bluetooth-Devices/dbus-fast/commit/dc3d8e7609f37a2f064a45ae525c5ce5711ea272))
- Upgrade typing on private modules
([#402](https://github.com/Bluetooth-Devices/dbus-fast/pull/402),
[`640e1f8`](https://github.com/Bluetooth-Devices/dbus-fast/commit/640e1f8d87a753d6721dae77ee94ff8702a2f508))
* chore: upgrade typing on private modules
* chore: typing fixes
### Features
- Refactor service bus handler lookup to avoid linear searches
([#400](https://github.com/Bluetooth-Devices/dbus-fast/pull/400),
[`996659e`](https://github.com/Bluetooth-Devices/dbus-fast/commit/996659e1b5fefeda7eb01259714a4a17fc224b9f))
## v2.35.1 (2025-03-05)
### Bug Fixes
- Reduce size of wheels ([#399](https://github.com/Bluetooth-Devices/dbus-fast/pull/399),
[`6531b93`](https://github.com/Bluetooth-Devices/dbus-fast/commit/6531b93a5ba5447494818cf7f8c38454b1338052))
first attempt failed to change the correct constant in build_ext.py
## v2.35.0 (2025-03-05)
### Chores
- **deps-ci**: Bump python-semantic-release/python-semantic-release from 9.17.0 to 9.21.0 in the
github-actions group ([#394](https://github.com/Bluetooth-Devices/dbus-fast/pull/394),
[`a7e1a90`](https://github.com/Bluetooth-Devices/dbus-fast/commit/a7e1a907e360c1f3fc01a62a414693782f536e61))
chore(deps-ci): bump python-semantic-release/python-semantic-release
Bumps the github-actions group with 1 update:
[python-semantic-release/python-semantic-release](https://github.com/python-semantic-release/python-semantic-release).
Updates `python-semantic-release/python-semantic-release` from 9.17.0 to 9.21.0 - [Release
notes](https://github.com/python-semantic-release/python-semantic-release/releases) -
[Changelog](https://github.com/python-semantic-release/python-semantic-release/blob/master/CHANGELOG.rst)
-
[Commits](https://github.com/python-semantic-release/python-semantic-release/compare/v9.17.0...v9.21.0)
--- updated-dependencies: - dependency-name: python-semantic-release/python-semantic-release
dependency-type: direct:production
update-type: version-update:semver-minor
dependency-group: github-actions ...
Signed-off-by: dependabot[bot]
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
- **deps-dev**: Bump pytest from 8.3.4 to 8.3.5
([#395](https://github.com/Bluetooth-Devices/dbus-fast/pull/395),
[`0d0e600`](https://github.com/Bluetooth-Devices/dbus-fast/commit/0d0e600a940fa4cb82473fec7bfb8706ed7ff7f7))
- **deps-dev**: Bump setuptools from 75.8.0 to 75.8.2
([#396](https://github.com/Bluetooth-Devices/dbus-fast/pull/396),
[`2623a74`](https://github.com/Bluetooth-Devices/dbus-fast/commit/2623a7412afeb906b2863b05fefb0d94e8881dcb))
- **pre-commit.ci**: Pre-commit autoupdate
([#392](https://github.com/Bluetooth-Devices/dbus-fast/pull/392),
[`3ef89bf`](https://github.com/Bluetooth-Devices/dbus-fast/commit/3ef89bfbf45592401dae60bf93104e063f082160))
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
- **pre-commit.ci**: Pre-commit autoupdate
([#397](https://github.com/Bluetooth-Devices/dbus-fast/pull/397),
[`3dd7c35`](https://github.com/Bluetooth-Devices/dbus-fast/commit/3dd7c358fad92ef7dcb42c361ebac367f10e3ce2))
updates: - [github.com/commitizen-tools/commitizen: v4.2.2 →
v4.4.1](https://github.com/commitizen-tools/commitizen/compare/v4.2.2...v4.4.1) -
[github.com/astral-sh/ruff-pre-commit: v0.9.7 →
v0.9.9](https://github.com/astral-sh/ruff-pre-commit/compare/v0.9.7...v0.9.9)
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
### Features
- Reduce size of wheels ([#398](https://github.com/Bluetooth-Devices/dbus-fast/pull/398),
[`a4c2743`](https://github.com/Bluetooth-Devices/dbus-fast/commit/a4c2743420f619d8808413d8877b2c9badc5f3f0))
Compile with -g0 to reduce the binary size
## v2.34.0 (2025-02-24)
### Chores
- **deps-dev**: Bump cython from 3.0.11 to 3.0.12
([#391](https://github.com/Bluetooth-Devices/dbus-fast/pull/391),
[`5f26f5d`](https://github.com/Bluetooth-Devices/dbus-fast/commit/5f26f5d58c5e0ed6251c66ab4724f27a383500a0))
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
- **pre-commit.ci**: Pre-commit autoupdate
([#389](https://github.com/Bluetooth-Devices/dbus-fast/pull/389),
[`c713bf3`](https://github.com/Bluetooth-Devices/dbus-fast/commit/c713bf3de994564c92628f92bdf341fbf813c8f4))
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
### Features
- Resync generic D-Bus errors ([#393](https://github.com/Bluetooth-Devices/dbus-fast/pull/393),
[`e4f37ee`](https://github.com/Bluetooth-Devices/dbus-fast/commit/e4f37ee10bd2af64716de0bd389db90b47373b76))
## v2.33.0 (2025-02-05)
### Chores
- **deps-dev**: Bump pytest-asyncio from 0.25.2 to 0.25.3
([#385](https://github.com/Bluetooth-Devices/dbus-fast/pull/385),
[`e6c75a6`](https://github.com/Bluetooth-Devices/dbus-fast/commit/e6c75a61828e260830720cff36a010e54b7efebe))
- **deps-dev**: Bump pytest-codspeed from 3.1.2 to 3.2.0
([#384](https://github.com/Bluetooth-Devices/dbus-fast/pull/384),
[`9f966af`](https://github.com/Bluetooth-Devices/dbus-fast/commit/9f966af1dbeba8af6d7119877801e5140daf4002))
- **pre-commit.ci**: Pre-commit autoupdate
([#386](https://github.com/Bluetooth-Devices/dbus-fast/pull/386),
[`0a9e4c5`](https://github.com/Bluetooth-Devices/dbus-fast/commit/0a9e4c5a2140f20f580c67bed2a68ff0ac524b62))
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
### Features
- Build macos arm wheels ([#387](https://github.com/Bluetooth-Devices/dbus-fast/pull/387),
[`829e0fc`](https://github.com/Bluetooth-Devices/dbus-fast/commit/829e0fc149957b3bf0fc0f4a89bb2e676e584f84))
## v2.32.0 (2025-02-02)
### Features
- Speed up marshalling messages ([#383](https://github.com/Bluetooth-Devices/dbus-fast/pull/383),
[`d7213be`](https://github.com/Bluetooth-Devices/dbus-fast/commit/d7213be28578b3effa3aeea85bab5de92bba224d))
## v2.31.0 (2025-02-02)
### Features
- Speed up bytearray creation in unmarshaller
([#382](https://github.com/Bluetooth-Devices/dbus-fast/pull/382),
[`89026e3`](https://github.com/Bluetooth-Devices/dbus-fast/commit/89026e3b597bd1a318114b6cf50e27d29d9cbca8))
## v2.30.4 (2025-02-02)
### Bug Fixes
- Docs build ([#381](https://github.com/Bluetooth-Devices/dbus-fast/pull/381),
[`c21a2ac`](https://github.com/Bluetooth-Devices/dbus-fast/commit/c21a2ac15a09b2ebf79afa53439fbc45214d4dc0))
## v2.30.3 (2025-02-02)
### Bug Fixes
- Attempting to unmarshall some arrays twice
([#380](https://github.com/Bluetooth-Devices/dbus-fast/pull/380),
[`586dc23`](https://github.com/Bluetooth-Devices/dbus-fast/commit/586dc233fdb2ebc7d627cb94b55d80a77631416f))
### Chores
- Bump the github-actions group with 9 updates
([#372](https://github.com/Bluetooth-Devices/dbus-fast/pull/372),
[`94ba266`](https://github.com/Bluetooth-Devices/dbus-fast/commit/94ba26653987b7200cfb85ed92d46ea5d95a95a0))
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: J. Nick Koston
- Bump upload/download artifact to v4
([#370](https://github.com/Bluetooth-Devices/dbus-fast/pull/370),
[`29be224`](https://github.com/Bluetooth-Devices/dbus-fast/commit/29be224be7fd05970aa5473b8e86810c8978ab6c))
- Fix commitlint config ([#374](https://github.com/Bluetooth-Devices/dbus-fast/pull/374),
[`b13712f`](https://github.com/Bluetooth-Devices/dbus-fast/commit/b13712f4c51810d9384b1fc924e61ad984800719))
- Fix release process ([#375](https://github.com/Bluetooth-Devices/dbus-fast/pull/375),
[`de57a21`](https://github.com/Bluetooth-Devices/dbus-fast/commit/de57a21a3c22224032fd5e2672560a00e2fbcd12))
- Fix release upload ([#377](https://github.com/Bluetooth-Devices/dbus-fast/pull/377),
[`eb56b64`](https://github.com/Bluetooth-Devices/dbus-fast/commit/eb56b6464d9dc0c18465bf68030634f78a36fc5c))
- Fix semantic release fields ([#376](https://github.com/Bluetooth-Devices/dbus-fast/pull/376),
[`4fe13e8`](https://github.com/Bluetooth-Devices/dbus-fast/commit/4fe13e88d1b636136e88ff6eacec0d6293280868))
- Update dependabot.yml prefix
([`c4e37b0`](https://github.com/Bluetooth-Devices/dbus-fast/commit/c4e37b077cb27d2916150aa57a90633b3eea3489))
- Update dependabot.yml to include actions
([`56c1595`](https://github.com/Bluetooth-Devices/dbus-fast/commit/56c1595be9f8047fd8f983e4baca9a92d5de0772))
- **deps-ci**: Bump the github-actions group with 2 updates
([#379](https://github.com/Bluetooth-Devices/dbus-fast/pull/379),
[`1aab230`](https://github.com/Bluetooth-Devices/dbus-fast/commit/1aab2304398de8a3dd7789efe4f82fb04eb54e37))
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
- **deps-dev**: Bump pytest from 7.4.4 to 8.3.4
([#334](https://github.com/Bluetooth-Devices/dbus-fast/pull/334),
[`9ad3873`](https://github.com/Bluetooth-Devices/dbus-fast/commit/9ad38730d57d92bf621d5ed799369b63e15aa1c0))
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: J. Nick Koston
- **deps-dev**: Bump pytest-asyncio from 0.23.8 to 0.25.2
([#373](https://github.com/Bluetooth-Devices/dbus-fast/pull/373),
[`922840b`](https://github.com/Bluetooth-Devices/dbus-fast/commit/922840ba9d537a60b139f5becfd993fe84b1d50d))
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
- **pre-commit.ci**: Pre-commit autoupdate
([#369](https://github.com/Bluetooth-Devices/dbus-fast/pull/369),
[`9953959`](https://github.com/Bluetooth-Devices/dbus-fast/commit/995395953045969103361d08bf4f5de52ebe8790))
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
- **pre-commit.ci**: Pre-commit autoupdate
([#378](https://github.com/Bluetooth-Devices/dbus-fast/pull/378),
[`b58620a`](https://github.com/Bluetooth-Devices/dbus-fast/commit/b58620afd8e4981162677464689d2afd4474621d))
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
## v2.30.2 (2025-01-17)
### Bug Fixes
- Fetching release tag during build
([#368](https://github.com/Bluetooth-Devices/dbus-fast/pull/368),
[`5a80415`](https://github.com/Bluetooth-Devices/dbus-fast/commit/5a804159669c2caad9d1144120ebaeb602d9ad28))
## v2.30.1 (2025-01-17)
### Bug Fixes
- Wheel builds on aarch64 ([#367](https://github.com/Bluetooth-Devices/dbus-fast/pull/367),
[`18132b9`](https://github.com/Bluetooth-Devices/dbus-fast/commit/18132b99bcbada1f090ccfc1c0050caf0827cd11))
## v2.30.0 (2025-01-17)
### Features
- Migrate to using native arm runners for wheel builds
([#366](https://github.com/Bluetooth-Devices/dbus-fast/pull/366),
[`bdf08d2`](https://github.com/Bluetooth-Devices/dbus-fast/commit/bdf08d253bff9bc1edd7c9a5688b7d9e4eb73839))
## v2.29.0 (2025-01-15)
### Bug Fixes
- Void validate arguments/properties name
([#358](https://github.com/Bluetooth-Devices/dbus-fast/pull/358),
[`f58f1a6`](https://github.com/Bluetooth-Devices/dbus-fast/commit/f58f1a6466d7ffb3a600774f8c36b5c93279437b))
### Chores
- **deps**: Bump sphinx from 7.1.2 to 7.4.7
([#361](https://github.com/Bluetooth-Devices/dbus-fast/pull/361),
[`0487639`](https://github.com/Bluetooth-Devices/dbus-fast/commit/0487639ed702892a365f70991682f023aec29116))
- **deps-dev**: Bump pytest-codspeed from 3.1.1 to 3.1.2
([#362](https://github.com/Bluetooth-Devices/dbus-fast/pull/362),
[`e7750ca`](https://github.com/Bluetooth-Devices/dbus-fast/commit/e7750caed5791aef0cbb8c62e82ccabf02f65df7))
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
- **deps-dev**: Bump pytest-cov from 5.0.0 to 6.0.0
([#363](https://github.com/Bluetooth-Devices/dbus-fast/pull/363),
[`244ea83`](https://github.com/Bluetooth-Devices/dbus-fast/commit/244ea83a31631c54b3d97ad47b91786e1d02387f))
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
- **deps-dev**: Bump setuptools from 75.7.0 to 75.8.0
([#364](https://github.com/Bluetooth-Devices/dbus-fast/pull/364),
[`8eee3a8`](https://github.com/Bluetooth-Devices/dbus-fast/commit/8eee3a82fdf2f2fde2dac52c4854b16e8bf0ac8d))
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
- **pre-commit.ci**: Pre-commit autoupdate
([#365](https://github.com/Bluetooth-Devices/dbus-fast/pull/365),
[`e006a1e`](https://github.com/Bluetooth-Devices/dbus-fast/commit/e006a1e861df6c3368f10600f6c390becae15c5c))
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
### Features
- **introspect**: Implement annotations
([#359](https://github.com/Bluetooth-Devices/dbus-fast/pull/359),
[`5b61869`](https://github.com/Bluetooth-Devices/dbus-fast/commit/5b61869baec88cd1382419f4580c345473543493))
Co-authored-by: J. Nick Koston
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
## v2.28.0 (2025-01-07)
### Bug Fixes
- Revert avoid building wheels if a release is not made
([#357](https://github.com/Bluetooth-Devices/dbus-fast/pull/357),
[`ebdf07e`](https://github.com/Bluetooth-Devices/dbus-fast/commit/ebdf07ec9e875806c050c97027b6f7dca077bd7d))
### Features
- Improve performance of marshalling message headers
([#356](https://github.com/Bluetooth-Devices/dbus-fast/pull/356),
[`e1aaf0a`](https://github.com/Bluetooth-Devices/dbus-fast/commit/e1aaf0a3969d595bc9d789cb5e40dfd59ef232c9))
- Improve performance of unmarshalling variants
([#354](https://github.com/Bluetooth-Devices/dbus-fast/pull/354),
[`d376bb1`](https://github.com/Bluetooth-Devices/dbus-fast/commit/d376bb13ade9bac8b478a183a4a280d37d121ab9))
## v2.27.0 (2025-01-07)
### Chores
- Add marshall benchmark ([#353](https://github.com/Bluetooth-Devices/dbus-fast/pull/353),
[`1164ca5`](https://github.com/Bluetooth-Devices/dbus-fast/commit/1164ca55dd7bb915bcac61e8a9b15ae009d51b66))
- Avoid building wheels if a release is not made
([#355](https://github.com/Bluetooth-Devices/dbus-fast/pull/355),
[`f9ec254`](https://github.com/Bluetooth-Devices/dbus-fast/commit/f9ec25415064deb272e5664cd215f7dd31b869c0))
### Features
- Speed up marshalling messages ([#352](https://github.com/Bluetooth-Devices/dbus-fast/pull/352),
[`b1e6551`](https://github.com/Bluetooth-Devices/dbus-fast/commit/b1e6551de32bec5a8a5164540d44e1b1bfe86881))
## v2.26.0 (2025-01-07)
### Features
- Speed up constructing messages from the unmarshaller
([#344](https://github.com/Bluetooth-Devices/dbus-fast/pull/344),
[`b162494`](https://github.com/Bluetooth-Devices/dbus-fast/commit/b162494aa25fe4b23debdd9a44b49ea21c771ad1))
## v2.25.0 (2025-01-07)
### Bug Fixes
- Race in test_tcp_connection_with_forwarding
([#350](https://github.com/Bluetooth-Devices/dbus-fast/pull/350),
[`4116261`](https://github.com/Bluetooth-Devices/dbus-fast/commit/41162618d4a78c193d91fb9525eb7d2763f17587))
### Chores
- Add codspeed badge ([#351](https://github.com/Bluetooth-Devices/dbus-fast/pull/351),
[`1f7f52d`](https://github.com/Bluetooth-Devices/dbus-fast/commit/1f7f52dd89f7728c650f92182f14fe768f456621))
### Features
- Speed up unmarshalling headers ([#347](https://github.com/Bluetooth-Devices/dbus-fast/pull/347),
[`5825758`](https://github.com/Bluetooth-Devices/dbus-fast/commit/5825758991a5d5f476b082c0277e5ecb0767c7e5))
## v2.24.6 (2025-01-07)
### Bug Fixes
- Disable wheel builds for old python versions
([#346](https://github.com/Bluetooth-Devices/dbus-fast/pull/346),
[`a249777`](https://github.com/Bluetooth-Devices/dbus-fast/commit/a249777e03d71502cbbde5d20cab2f3685fb5adb))
### Chores
- Bump codecov action to v5 ([#343](https://github.com/Bluetooth-Devices/dbus-fast/pull/343),
[`d1298de`](https://github.com/Bluetooth-Devices/dbus-fast/commit/d1298de2a1e0f7aa6277835a55df1229c6552e8a))
## v2.24.5 (2025-01-07)
### Bug Fixes
- Ensure exceptions are logged when no reply is expected
([#342](https://github.com/Bluetooth-Devices/dbus-fast/pull/342),
[`1c20dcc`](https://github.com/Bluetooth-Devices/dbus-fast/commit/1c20dcc50471b453d9b55bc2be197fd5b0c38a9c))
### Chores
- Add codspeed benchmarks ([#340](https://github.com/Bluetooth-Devices/dbus-fast/pull/340),
[`5bf90b9`](https://github.com/Bluetooth-Devices/dbus-fast/commit/5bf90b9fb15e243801f7d39e7e57b52f5c694bcc))
- Drop Python 3.8 support as it has reached EOL
([#338](https://github.com/Bluetooth-Devices/dbus-fast/pull/338),
[`42a786b`](https://github.com/Bluetooth-Devices/dbus-fast/commit/42a786b23ff519d653d8accf7950b18604f3070a))
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
- Split wheel builds to speed up releases
([#341](https://github.com/Bluetooth-Devices/dbus-fast/pull/341),
[`439b2da`](https://github.com/Bluetooth-Devices/dbus-fast/commit/439b2da8789d7e0ca0a70e4d4c074666248bd492))
- Switch to ruff ([#339](https://github.com/Bluetooth-Devices/dbus-fast/pull/339),
[`eda3706`](https://github.com/Bluetooth-Devices/dbus-fast/commit/eda37061c4b4068a2fd6b051f9becfc8ae7bba10))
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
- **deps**: Bump sphinx-rtd-theme from 3.0.1 to 3.0.2
([#332](https://github.com/Bluetooth-Devices/dbus-fast/pull/332),
[`42ef44a`](https://github.com/Bluetooth-Devices/dbus-fast/commit/42ef44a4aa38491b7608f84d84a6349aa11703e6))
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
- **deps**: Bump sphinx-rtd-theme from 3.0.1 to 3.0.2
([#335](https://github.com/Bluetooth-Devices/dbus-fast/pull/335),
[`663b371`](https://github.com/Bluetooth-Devices/dbus-fast/commit/663b37136f1b75245292d6bc6633e3184ff3d228))
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
- **pre-commit.ci**: Pre-commit autoupdate
([#333](https://github.com/Bluetooth-Devices/dbus-fast/pull/333),
[`b5c01a9`](https://github.com/Bluetooth-Devices/dbus-fast/commit/b5c01a926c95d6e65c2c597846596373393c88a2))
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
- **pre-commit.ci**: Pre-commit autoupdate
([#336](https://github.com/Bluetooth-Devices/dbus-fast/pull/336),
[`ea24a86`](https://github.com/Bluetooth-Devices/dbus-fast/commit/ea24a86c1b2bb2b25da8e892a641bcd4e6b24b30))
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
- **pre-commit.ci**: Pre-commit autoupdate
([#337](https://github.com/Bluetooth-Devices/dbus-fast/pull/337),
[`471e680`](https://github.com/Bluetooth-Devices/dbus-fast/commit/471e68035470b2f6b29500347ec3e0443dc3648e))
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
## v2.24.4 (2024-11-15)
### Bug Fixes
- Exclude .c files from being shipped
([#331](https://github.com/Bluetooth-Devices/dbus-fast/pull/331),
[`9c73022`](https://github.com/Bluetooth-Devices/dbus-fast/commit/9c7302299ab002a1aec80062f0b9bd5c1bde46f9))
### Chores
- **deps**: Bump sphinx-rtd-theme from 2.0.0 to 3.0.0
([#319](https://github.com/Bluetooth-Devices/dbus-fast/pull/319),
[`f30bc57`](https://github.com/Bluetooth-Devices/dbus-fast/commit/f30bc57bbad6e3fa2c62956233d171dfc9e7f3d9))
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
- **deps**: Bump sphinx-rtd-theme from 2.0.0 to 3.0.1
([#322](https://github.com/Bluetooth-Devices/dbus-fast/pull/322),
[`3131841`](https://github.com/Bluetooth-Devices/dbus-fast/commit/31318414720ecaa4b86ac8afbdb20066c9f43e07))
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
- **deps**: Bump sphinx-rtd-theme from 3.0.0 to 3.0.1
([#326](https://github.com/Bluetooth-Devices/dbus-fast/pull/326),
[`2831f9c`](https://github.com/Bluetooth-Devices/dbus-fast/commit/2831f9cc3633d4c6e47232f741213da2adbaf71a))
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
- **deps-dev**: Bump setuptools from 75.1.0 to 75.2.0
([#324](https://github.com/Bluetooth-Devices/dbus-fast/pull/324),
[`fa3faa8`](https://github.com/Bluetooth-Devices/dbus-fast/commit/fa3faa86eec5568d74db2d1b8aa4c9af18b236f1))
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
- **deps-dev**: Bump setuptools from 75.2.0 to 75.3.0
([#328](https://github.com/Bluetooth-Devices/dbus-fast/pull/328),
[`83bb550`](https://github.com/Bluetooth-Devices/dbus-fast/commit/83bb5502ed17a1d8256d27ef86079c3688d5a3cd))
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
- **pre-commit.ci**: Pre-commit autoupdate
([#320](https://github.com/Bluetooth-Devices/dbus-fast/pull/320),
[`46bc330`](https://github.com/Bluetooth-Devices/dbus-fast/commit/46bc3304a31149c3a0c4fdc3aa2047ea2232a22d))
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: J. Nick Koston
- **pre-commit.ci**: Pre-commit autoupdate
([#323](https://github.com/Bluetooth-Devices/dbus-fast/pull/323),
[`9e2f17a`](https://github.com/Bluetooth-Devices/dbus-fast/commit/9e2f17a974fa7b2defdccc5038ace446567bb0b0))
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
- **pre-commit.ci**: Pre-commit autoupdate
([#327](https://github.com/Bluetooth-Devices/dbus-fast/pull/327),
[`4d3acc4`](https://github.com/Bluetooth-Devices/dbus-fast/commit/4d3acc49659779e6d3d2a57ed47ede49ce6b4208))
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
## v2.24.3 (2024-10-05)
### Bug Fixes
- Remove deprecated no_type_check_decorator
([#316](https://github.com/Bluetooth-Devices/dbus-fast/pull/316),
[`0f04a79`](https://github.com/Bluetooth-Devices/dbus-fast/commit/0f04a794f2e8b494c194e4f4856e43917bdda58a))
### Chores
- **deps**: Bump sphinx from 5.2.3 to 7.1.2
([#312](https://github.com/Bluetooth-Devices/dbus-fast/pull/312),
[`34d0d46`](https://github.com/Bluetooth-Devices/dbus-fast/commit/34d0d461c8764ae4aca0992909a22f03bf7d3133))
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
- **deps-dev**: Bump setuptools from 74.1.2 to 75.1.0
([#314](https://github.com/Bluetooth-Devices/dbus-fast/pull/314),
[`aaa1e1e`](https://github.com/Bluetooth-Devices/dbus-fast/commit/aaa1e1e0ea5a399897eaf185ce696f03d17ff4a9))
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
- **pre-commit.ci**: Pre-commit autoupdate
([#317](https://github.com/Bluetooth-Devices/dbus-fast/pull/317),
[`f2de447`](https://github.com/Bluetooth-Devices/dbus-fast/commit/f2de4472dde27ca7dc1a83f049fbb89e0b2c6bb9))
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
## v2.24.2 (2024-09-06)
### Bug Fixes
- Ensure build uses cython3 ([#311](https://github.com/Bluetooth-Devices/dbus-fast/pull/311),
[`2dabf2d`](https://github.com/Bluetooth-Devices/dbus-fast/commit/2dabf2ddcbbd7e46551521100734372a52458ce4))
## v2.24.1 (2024-09-06)
### Bug Fixes
- Add missing cython version pin to the build system
([#310](https://github.com/Bluetooth-Devices/dbus-fast/pull/310),
[`1b7d28c`](https://github.com/Bluetooth-Devices/dbus-fast/commit/1b7d28cd1f1b78631335cc9945be218aacf6e3f6))
### Chores
- **deps**: Bump myst-parser from 1.0.0 to 3.0.1
([#306](https://github.com/Bluetooth-Devices/dbus-fast/pull/306),
[`8b3e95c`](https://github.com/Bluetooth-Devices/dbus-fast/commit/8b3e95c6cc6d9e8396d2ee6b1883df700fb3f23b))
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
- **deps**: Bump sphinx from 5.2.3 to 7.1.2
([#307](https://github.com/Bluetooth-Devices/dbus-fast/pull/307),
[`e393611`](https://github.com/Bluetooth-Devices/dbus-fast/commit/e393611fbf44f5f0598c8f7762034356a893cdbb))
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
- **deps-dev**: Bump setuptools from 73.0.1 to 74.0.0
([#308](https://github.com/Bluetooth-Devices/dbus-fast/pull/308),
[`757a742`](https://github.com/Bluetooth-Devices/dbus-fast/commit/757a7424d20efc61f2de1f5f447277fd17eb94ed))
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
## v2.24.0 (2024-08-26)
### Chores
- **deps**: Bump myst-parser from 0.18.1 to 1.0.0
([#296](https://github.com/Bluetooth-Devices/dbus-fast/pull/296),
[`b225cca`](https://github.com/Bluetooth-Devices/dbus-fast/commit/b225cca97a60a8c05b892d438b461904efc42fa2))
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
- **deps**: Bump myst-parser from 0.18.1 to 1.0.0
([#304](https://github.com/Bluetooth-Devices/dbus-fast/pull/304),
[`0b372ea`](https://github.com/Bluetooth-Devices/dbus-fast/commit/0b372eac98e962c349d1933472d37085fb5abad7))
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
- **deps**: Bump myst-parser from 1.0.0 to 3.0.1
([#305](https://github.com/Bluetooth-Devices/dbus-fast/pull/305),
[`dae0088`](https://github.com/Bluetooth-Devices/dbus-fast/commit/dae00881a7922af67a5d1076a31bc295d43f5e14))
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
- **deps**: Bump sphinx from 5.2.3 to 6.2.1
([#300](https://github.com/Bluetooth-Devices/dbus-fast/pull/300),
[`ad1e078`](https://github.com/Bluetooth-Devices/dbus-fast/commit/ad1e078ee9d11ab8bcffe3df8e20f2d0337a2dd1))
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
- **deps**: Bump sphinx-rtd-theme from 1.0.0 to 2.0.0
([#293](https://github.com/Bluetooth-Devices/dbus-fast/pull/293),
[`95df9a6`](https://github.com/Bluetooth-Devices/dbus-fast/commit/95df9a6265b62d9e7f0c243f1cf5b0e64a18f369))
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
- **deps**: Bump sphinx-rtd-theme from 1.0.0 to 2.0.0
([#302](https://github.com/Bluetooth-Devices/dbus-fast/pull/302),
[`6e496eb`](https://github.com/Bluetooth-Devices/dbus-fast/commit/6e496eb222ed3c20627c0fc7c2c3f2e5f0dfb807))
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
- **deps-dev**: Bump pytest-cov from 3.0.0 to 5.0.0
([#301](https://github.com/Bluetooth-Devices/dbus-fast/pull/301),
[`84c7346`](https://github.com/Bluetooth-Devices/dbus-fast/commit/84c73467ac43218091320989b3e32f8a36840c23))
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
### Features
- Use dbus-run-session to drop X11 dependency
([#299](https://github.com/Bluetooth-Devices/dbus-fast/pull/299),
[`42f1d4a`](https://github.com/Bluetooth-Devices/dbus-fast/commit/42f1d4a3f2515a301c12f8f485457a878d7df2dc))
## v2.23.0 (2024-08-21)
### Chores
- **deps-dev**: Bump certifi from 2024.6.2 to 2024.7.4 in the pip group across 1 directory
([#298](https://github.com/Bluetooth-Devices/dbus-fast/pull/298),
[`705ad28`](https://github.com/Bluetooth-Devices/dbus-fast/commit/705ad28ce7bd5b455d643101ba9ad682d503360b))
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
- **deps-dev**: Bump cython from 0.29.37 to 3.0.11
([#292](https://github.com/Bluetooth-Devices/dbus-fast/pull/292),
[`8b4cdef`](https://github.com/Bluetooth-Devices/dbus-fast/commit/8b4cdefe3e20e8eccdbfbe6402e0593cc8134bbd))
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
- **deps-dev**: Bump pytest-asyncio from 0.19.0 to 0.23.8
([#294](https://github.com/Bluetooth-Devices/dbus-fast/pull/294),
[`f946183`](https://github.com/Bluetooth-Devices/dbus-fast/commit/f9461831f49a1172af5a77df3138bdffbd94c61b))
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
- **deps-dev**: Bump setuptools from 65.7.0 to 73.0.1
([#295](https://github.com/Bluetooth-Devices/dbus-fast/pull/295),
[`af4989b`](https://github.com/Bluetooth-Devices/dbus-fast/commit/af4989b7f71eb9f77e92832901aeeeee4c7f8504))
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
- **pre-commit.ci**: Pre-commit autoupdate
([#286](https://github.com/Bluetooth-Devices/dbus-fast/pull/286),
[`5d9bb92`](https://github.com/Bluetooth-Devices/dbus-fast/commit/5d9bb92da6e363320b8afa5942e6f0b4a4ecd4d0))
* chore(pre-commit.ci): pre-commit autoupdate
updates: - [github.com/commitizen-tools/commitizen: v2.32.4 →
v3.27.0](https://github.com/commitizen-tools/commitizen/compare/v2.32.4...v3.27.0) -
[github.com/pre-commit/pre-commit-hooks: v4.3.0 →
v4.6.0](https://github.com/pre-commit/pre-commit-hooks/compare/v4.3.0...v4.6.0) -
[github.com/pre-commit/mirrors-prettier: v2.7.1 →
v4.0.0-alpha.8](https://github.com/pre-commit/mirrors-prettier/compare/v2.7.1...v4.0.0-alpha.8) -
[github.com/asottile/pyupgrade: v2.37.3 →
v3.16.0](https://github.com/asottile/pyupgrade/compare/v2.37.3...v3.16.0) -
[github.com/PyCQA/isort: 5.12.0 → 5.13.2](https://github.com/PyCQA/isort/compare/5.12.0...5.13.2)
- [github.com/psf/black: 22.8.0 → 24.4.2](https://github.com/psf/black/compare/22.8.0...24.4.2)
* chore(pre-commit.ci): auto fixes
---------
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
- **pre-commit.ci**: Pre-commit autoupdate
([#287](https://github.com/Bluetooth-Devices/dbus-fast/pull/287),
[`b508e1f`](https://github.com/Bluetooth-Devices/dbus-fast/commit/b508e1fc5fbd4f5200b1fa46c913569fc02f6f4e))
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
- **pre-commit.ci**: Pre-commit autoupdate
([#288](https://github.com/Bluetooth-Devices/dbus-fast/pull/288),
[`c960552`](https://github.com/Bluetooth-Devices/dbus-fast/commit/c96055289d697b847e93ed4f4c7fc7c1893e1642))
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
- **pre-commit.ci**: Pre-commit autoupdate
([#289](https://github.com/Bluetooth-Devices/dbus-fast/pull/289),
[`398f643`](https://github.com/Bluetooth-Devices/dbus-fast/commit/398f643f718e15903183f480726d959e0d85c4da))
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
- **pre-commit.ci**: Pre-commit autoupdate
([#290](https://github.com/Bluetooth-Devices/dbus-fast/pull/290),
[`ee98f7c`](https://github.com/Bluetooth-Devices/dbus-fast/commit/ee98f7c4536e9020f1b28fc916c2bfeb52cc31ac))
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
### Features
- Python 3.13 support ([#291](https://github.com/Bluetooth-Devices/dbus-fast/pull/291),
[`45c0e74`](https://github.com/Bluetooth-Devices/dbus-fast/commit/45c0e7491da85ed754a86358bffa2260f96c240f))
## v2.22.1 (2024-06-26)
### Bug Fixes
- Wheel build exclude for pp37 ([#285](https://github.com/Bluetooth-Devices/dbus-fast/pull/285),
[`c44eb2c`](https://github.com/Bluetooth-Devices/dbus-fast/commit/c44eb2cabd8a7c5156d9cb2228f058140c004c36))
## v2.22.0 (2024-06-26)
### Chores
- Drop python 3.7 support ([#284](https://github.com/Bluetooth-Devices/dbus-fast/pull/284),
[`fa48bc0`](https://github.com/Bluetooth-Devices/dbus-fast/commit/fa48bc025c1edf30451a7c0fb4ec639d927d045c))
### Features
- Build wheels for aarch64 to allow use in embedded systems
([#283](https://github.com/Bluetooth-Devices/dbus-fast/pull/283),
[`d0ac990`](https://github.com/Bluetooth-Devices/dbus-fast/commit/d0ac990a7aa9eec14d8c9c9720e4894de6dcf9b5))
## v2.21.3 (2024-05-20)
### Bug Fixes
- Clear exception flag on disconnect future if its also sent to handlers
([#281](https://github.com/Bluetooth-Devices/dbus-fast/pull/281),
[`be68a79`](https://github.com/Bluetooth-Devices/dbus-fast/commit/be68a79c523e7ff360a4f9914b41956b5f430d93))
## v2.21.2 (2024-05-08)
### Bug Fixes
- Introspection bogus child paths ([#280](https://github.com/Bluetooth-Devices/dbus-fast/pull/280),
[`7da5d44`](https://github.com/Bluetooth-Devices/dbus-fast/commit/7da5d44caacecd9af2f8198e7403d7d043c87579))
## v2.21.1 (2024-01-16)
### Bug Fixes
- Avoid expensive runtime inspection of known callables
([#277](https://github.com/Bluetooth-Devices/dbus-fast/pull/277),
[`0271825`](https://github.com/Bluetooth-Devices/dbus-fast/commit/0271825e7338dd8422975d9289768363b5b6b9de))
## v2.21.0 (2023-12-12)
### Features
- Speed up message callbacks ([#276](https://github.com/Bluetooth-Devices/dbus-fast/pull/276),
[`2b8770b`](https://github.com/Bluetooth-Devices/dbus-fast/commit/2b8770b892ee75b851d5d58967e3a9e3149430dc))
## v2.20.0 (2023-12-04)
### Features
- Speed up run time constructed method handlers
([#275](https://github.com/Bluetooth-Devices/dbus-fast/pull/275),
[`9f54fc3`](https://github.com/Bluetooth-Devices/dbus-fast/commit/9f54fc3194370bb4c6fd51c158b577adce1b517f))
## v2.19.0 (2023-12-04)
### Features
- Speed up ServiceInterface callbacks with cython methods
([#274](https://github.com/Bluetooth-Devices/dbus-fast/pull/274),
[`0e57d79`](https://github.com/Bluetooth-Devices/dbus-fast/commit/0e57d798a2f171f804603cb5a3659de08092e74b))
## v2.18.0 (2023-12-04)
### Features
- Small speed up to the aio message reader
([#273](https://github.com/Bluetooth-Devices/dbus-fast/pull/273),
[`8ee18a1`](https://github.com/Bluetooth-Devices/dbus-fast/commit/8ee18a1355b247e3ef9c7ad5f561d7cc8f9cf4a2))
## v2.17.0 (2023-12-04)
### Features
- Reduce duplicate code in aio MessageBus
([#272](https://github.com/Bluetooth-Devices/dbus-fast/pull/272),
[`502ab0d`](https://github.com/Bluetooth-Devices/dbus-fast/commit/502ab0d47f667bb24cd7b3f1d8fa97e2d0345676))
## v2.16.0 (2023-12-04)
### Features
- Speed up sending messages with call on the MessageBus
([#271](https://github.com/Bluetooth-Devices/dbus-fast/pull/271),
[`6d7f522`](https://github.com/Bluetooth-Devices/dbus-fast/commit/6d7f522e1cc5181e75209e4c00109426baa335fc))
## v2.15.0 (2023-11-22)
### Features
- Make ErrorType enums compare as strings
([#269](https://github.com/Bluetooth-Devices/dbus-fast/pull/269),
[`c6a8301`](https://github.com/Bluetooth-Devices/dbus-fast/commit/c6a8301704162e1c4d07470c32ca0830f531b6d4))
The DBusError exception stores the error type as string. This makes the exception not directly
compare to the ErrorType members (for example DBusError(ErrorType.FAILED, "").type !=
ErrorType.FAILED). This makes ErrorType also a string to make this comparision work.
## v2.14.0 (2023-11-10)
### Features
- Add support for tuples to the marshaller
([#267](https://github.com/Bluetooth-Devices/dbus-fast/pull/267),
[`0ccb7c5`](https://github.com/Bluetooth-Devices/dbus-fast/commit/0ccb7c5d879fc787c12e35c659b0be88bcbed7fe))
## v2.13.1 (2023-11-07)
### Bug Fixes
- Re-release since the previous release ran out of space on PyPI
([#266](https://github.com/Bluetooth-Devices/dbus-fast/pull/266),
[`1586221`](https://github.com/Bluetooth-Devices/dbus-fast/commit/158622157f547aba80bbd06579915d7a5e145d58))
## v2.13.0 (2023-11-07)
### Features
- Improve marshaller performance ([#264](https://github.com/Bluetooth-Devices/dbus-fast/pull/264),
[`5bdb161`](https://github.com/Bluetooth-Devices/dbus-fast/commit/5bdb161c0a70074e0466e9332dce9c27b497916b))
## v2.12.1 (2023-11-07)
### Bug Fixes
- Send reply test failure with cython
([#265](https://github.com/Bluetooth-Devices/dbus-fast/pull/265),
[`e634fc2`](https://github.com/Bluetooth-Devices/dbus-fast/commit/e634fc2c701c25353f805dbe5fe52f67fa896b7d))
## v2.12.0 (2023-10-18)
### Bug Fixes
- Reduce size of wheels by excluding generated .c files
([#262](https://github.com/Bluetooth-Devices/dbus-fast/pull/262),
[`dca4599`](https://github.com/Bluetooth-Devices/dbus-fast/commit/dca459900e19e7340b68601d13422c83a7d67a19))
### Features
- Update for final cpython release ([#263](https://github.com/Bluetooth-Devices/dbus-fast/pull/263),
[`460a072`](https://github.com/Bluetooth-Devices/dbus-fast/commit/460a072652793829b217720846fbf10f8e2ebadb))
## v2.11.1 (2023-10-04)
### Bug Fixes
- Marshall multi-byte strings correctly
([#261](https://github.com/Bluetooth-Devices/dbus-fast/pull/261),
[`4de31a3`](https://github.com/Bluetooth-Devices/dbus-fast/commit/4de31a36463ff8e2d85225973c4553c15623afb6))
### Chores
- Add benchmark for GetValue ([#258](https://github.com/Bluetooth-Devices/dbus-fast/pull/258),
[`2fc723e`](https://github.com/Bluetooth-Devices/dbus-fast/commit/2fc723eacb24802b87ca712c89b76f6f95a64f1a))
- Add more unmarshall tests ([#259](https://github.com/Bluetooth-Devices/dbus-fast/pull/259),
[`4d3b666`](https://github.com/Bluetooth-Devices/dbus-fast/commit/4d3b666564fae3b813f57b446fb43dd27691e16e))
- Add more unmarshall tests ([#260](https://github.com/Bluetooth-Devices/dbus-fast/pull/260),
[`f9e5d1d`](https://github.com/Bluetooth-Devices/dbus-fast/commit/f9e5d1d02025fee50f641ee2bb82607a494c06dd))
## v2.11.0 (2023-09-27)
### Features
- Speed up unpacking arrays ([#257](https://github.com/Bluetooth-Devices/dbus-fast/pull/257),
[`5c8bfe5`](https://github.com/Bluetooth-Devices/dbus-fast/commit/5c8bfe5e15a1c5de150975ebdaf1677801397555))
## v2.10.0 (2023-09-25)
### Features
- Speed up constructing Variant objects
([#256](https://github.com/Bluetooth-Devices/dbus-fast/pull/256),
[`0d7a665`](https://github.com/Bluetooth-Devices/dbus-fast/commit/0d7a6652d797efcffaa0fa35039252c33522c15e))
## v2.9.0 (2023-09-20)
### Features
- Speed up unmarshalling message body
([#255](https://github.com/Bluetooth-Devices/dbus-fast/pull/255),
[`5aed075`](https://github.com/Bluetooth-Devices/dbus-fast/commit/5aed07516611692f935cac6fb612204c6f419fec))
## v2.8.0 (2023-09-20)
### Features
- Speed up unmarshalling Variants ([#254](https://github.com/Bluetooth-Devices/dbus-fast/pull/254),
[`dd74a84`](https://github.com/Bluetooth-Devices/dbus-fast/commit/dd74a8409db40abdaeba2fdcd578ae3998692470))
## v2.7.0 (2023-09-13)
### Features
- Speed up readers in the unmarshall path
([#253](https://github.com/Bluetooth-Devices/dbus-fast/pull/253),
[`f9b61b8`](https://github.com/Bluetooth-Devices/dbus-fast/commit/f9b61b8bc734b0179bde2c08e46c02de65f27e50))
## v2.6.0 (2023-09-12)
### Features
- Speed up first connection when using asyncio
([#251](https://github.com/Bluetooth-Devices/dbus-fast/pull/251),
[`0b6ba93`](https://github.com/Bluetooth-Devices/dbus-fast/commit/0b6ba93f733a78f1fb52ddfa24163de44f09df53))
## v2.5.0 (2023-09-12)
### Features
- Speed up unmarshaller ([#250](https://github.com/Bluetooth-Devices/dbus-fast/pull/250),
[`e4cae13`](https://github.com/Bluetooth-Devices/dbus-fast/commit/e4cae13e1a25356437658a03ee60522a68a56d56))
## v2.4.0 (2023-09-12)
### Chores
- Bump cpython CI version ([#249](https://github.com/Bluetooth-Devices/dbus-fast/pull/249),
[`16b31f9`](https://github.com/Bluetooth-Devices/dbus-fast/commit/16b31f91e50e8def4b7ee7066be0bd375b123f0a))
### Features
- Add cython typing for ServiceInterface.name
([#248](https://github.com/Bluetooth-Devices/dbus-fast/pull/248),
[`98c7e75`](https://github.com/Bluetooth-Devices/dbus-fast/commit/98c7e753755741967bad0618f056605bc2eaa743))
## v2.3.0 (2023-09-11)
### Features
- Speed up connect and disconnect ([#247](https://github.com/Bluetooth-Devices/dbus-fast/pull/247),
[`8f39ba3`](https://github.com/Bluetooth-Devices/dbus-fast/commit/8f39ba3ada1dfdec8d7230c77e52ef802e91b23d))
## v2.2.0 (2023-09-10)
### Features
- Speed up unmarshalling by skipping unused unix_fds header
([#246](https://github.com/Bluetooth-Devices/dbus-fast/pull/246),
[`5f5a150`](https://github.com/Bluetooth-Devices/dbus-fast/commit/5f5a150ca01810bf3a2a90043f77ee7100c8242d))
## v2.1.0 (2023-09-10)
### Features
- Reduce overhead to reset between messages
([#245](https://github.com/Bluetooth-Devices/dbus-fast/pull/245),
[`da30b04`](https://github.com/Bluetooth-Devices/dbus-fast/commit/da30b04a15aed08ba920fabd0abad372e953c394))
## v2.0.1 (2023-09-08)
### Bug Fixes
- Clean up address parsing and tests
([#244](https://github.com/Bluetooth-Devices/dbus-fast/pull/244),
[`370791d`](https://github.com/Bluetooth-Devices/dbus-fast/commit/370791da869040d4a0d92cde30c4d2d4d684bcdc))
## v2.0.0 (2023-09-07)
### Features
- Don't import backends by default ([#243](https://github.com/Bluetooth-Devices/dbus-fast/pull/243),
[`091d421`](https://github.com/Bluetooth-Devices/dbus-fast/commit/091d421a94752f749999858540000e0ab8a83da4))
## v1.95.2 (2023-09-07)
### Bug Fixes
- Handling of None messages from notify callback
([#236](https://github.com/Bluetooth-Devices/dbus-fast/pull/236),
[`14f52f2`](https://github.com/Bluetooth-Devices/dbus-fast/commit/14f52f216d49fb52bf223d5d96306465bb61e49c))
Co-authored-by: Remy Noel
Co-authored-by: J. Nick Koston
## v1.95.1 (2023-09-07)
### Bug Fixes
- Handle multiple flag bits when unmarshalling
([#241](https://github.com/Bluetooth-Devices/dbus-fast/pull/241),
[`6f6f5f8`](https://github.com/Bluetooth-Devices/dbus-fast/commit/6f6f5f86c020866a0c1ef5573547e25c63c8d3c3))
### Chores
- Add test coverage for issue 239 ([#240](https://github.com/Bluetooth-Devices/dbus-fast/pull/240),
[`0386dc2`](https://github.com/Bluetooth-Devices/dbus-fast/commit/0386dc232274c6de0717e9a3f280d98379acbf45))
## v1.95.0 (2023-09-06)
### Features
- Small speed up to the unmarshaller
([#238](https://github.com/Bluetooth-Devices/dbus-fast/pull/238),
[`b8d0e9b`](https://github.com/Bluetooth-Devices/dbus-fast/commit/b8d0e9be4c7eb7c16347e7bf57f8bf40d0c293d0))
## v1.94.1 (2023-08-27)
### Bug Fixes
- Rebuild wheels with cython 3.0.2 ([#235](https://github.com/Bluetooth-Devices/dbus-fast/pull/235),
[`e8901a8`](https://github.com/Bluetooth-Devices/dbus-fast/commit/e8901a8f7d82a93ed2e72576859fde8f942a8889))
## v1.94.0 (2023-08-24)
### Chores
- Bump cpython 3.12 version in CI ([#233](https://github.com/Bluetooth-Devices/dbus-fast/pull/233),
[`5364492`](https://github.com/Bluetooth-Devices/dbus-fast/commit/53644927b9a35d45cc07499d6bc5e6183f9239fb))
### Features
- Build cpython 3.12 wheels ([#234](https://github.com/Bluetooth-Devices/dbus-fast/pull/234),
[`b38aa58`](https://github.com/Bluetooth-Devices/dbus-fast/commit/b38aa58aa7b15cf4498edfefabf9a3df37804494))
## v1.93.1 (2023-08-24)
### Bug Fixes
- Avoid cythonizing SendReply ([#232](https://github.com/Bluetooth-Devices/dbus-fast/pull/232),
[`d12266d`](https://github.com/Bluetooth-Devices/dbus-fast/commit/d12266ddef920a6064c716c4e71ff8414094d0fd))
### Chores
- Add more coverage for send_reply ([#231](https://github.com/Bluetooth-Devices/dbus-fast/pull/231),
[`ed5c87f`](https://github.com/Bluetooth-Devices/dbus-fast/commit/ed5c87f49206d219e4d43d7091b1453ef9932ac4))
- Add send_reply tests ([#230](https://github.com/Bluetooth-Devices/dbus-fast/pull/230),
[`a8b9e72`](https://github.com/Bluetooth-Devices/dbus-fast/commit/a8b9e721d56c0b2283cd0cc3d3eb2a44d83bdc3d))
## v1.93.0 (2023-08-21)
### Features
- Improve performance of processing incoming messages
([#228](https://github.com/Bluetooth-Devices/dbus-fast/pull/228),
[`ce61aea`](https://github.com/Bluetooth-Devices/dbus-fast/commit/ce61aea37a55c9498f1800ec4bd68e8eaf7c7f48))
## v1.92.0 (2023-08-18)
### Features
- Reduce overhead to dispatch method handlers
([#227](https://github.com/Bluetooth-Devices/dbus-fast/pull/227),
[`b222552`](https://github.com/Bluetooth-Devices/dbus-fast/commit/b2225527ae57d1bccec21df950d621797d30732d))
## v1.91.4 (2023-08-17)
### Bug Fixes
- Subpath bad matching ([#202](https://github.com/Bluetooth-Devices/dbus-fast/pull/202),
[`5d6f90b`](https://github.com/Bluetooth-Devices/dbus-fast/commit/5d6f90ba32c61b14368f80b91e1d3d9a6279126f))
Co-authored-by: Remy Noel
Co-authored-by: J. Nick Koston
## v1.91.3 (2023-08-17)
### Bug Fixes
- Messages could be sent out of order if they had to queue
([#225](https://github.com/Bluetooth-Devices/dbus-fast/pull/225),
[`4051cf2`](https://github.com/Bluetooth-Devices/dbus-fast/commit/4051cf283f61bbfefc4d63c8933b3818483a2d1a))
## v1.91.2 (2023-08-09)
### Bug Fixes
- Avoid checking if a message expects a reply twice
([#223](https://github.com/Bluetooth-Devices/dbus-fast/pull/223),
[`823e85f`](https://github.com/Bluetooth-Devices/dbus-fast/commit/823e85fddc44ceff60558d490013b601ae4bdacd))
## v1.91.1 (2023-08-09)
### Bug Fixes
- Revert changes to _expects_reply from speed up to processing bluez passive data
([#222](https://github.com/Bluetooth-Devices/dbus-fast/pull/222),
[`dfa9053`](https://github.com/Bluetooth-Devices/dbus-fast/commit/dfa9053a03692d3e14032c7d4a4a375400262c78))
## v1.91.0 (2023-08-09)
### Features
- Speed up to processing bluez passive data
([#221](https://github.com/Bluetooth-Devices/dbus-fast/pull/221),
[`8e7432d`](https://github.com/Bluetooth-Devices/dbus-fast/commit/8e7432d31b38fecbbed585c2d5ae510d24ff5af7))
## v1.90.2 (2023-08-05)
### Bug Fixes
- Spelling of `dbus_fast.auth.AuthAnnonymous` to `dbus_fast.auth.AuthAnonymous`
([#220](https://github.com/Bluetooth-Devices/dbus-fast/pull/220),
[`6c2412f`](https://github.com/Bluetooth-Devices/dbus-fast/commit/6c2412f4ca214f1fc95046ab8118bf330aa646da))
## v1.90.1 (2023-08-02)
### Bug Fixes
- More cython3 optional fixes ([#219](https://github.com/Bluetooth-Devices/dbus-fast/pull/219),
[`5b6cbc5`](https://github.com/Bluetooth-Devices/dbus-fast/commit/5b6cbc560e6add5a0f3f20fc9d37716cb30e9121))
## v1.90.0 (2023-08-02)
### Features
- Remove async_timeout dependency ([#218](https://github.com/Bluetooth-Devices/dbus-fast/pull/218),
[`7826897`](https://github.com/Bluetooth-Devices/dbus-fast/commit/78268973591985695cb3fa76dd502bb1ef1895ec))
## v1.89.0 (2023-08-02)
### Features
- Speed up Message creation and callbacks
([#217](https://github.com/Bluetooth-Devices/dbus-fast/pull/217),
[`04d6451`](https://github.com/Bluetooth-Devices/dbus-fast/commit/04d64511579be08c7d416664c66d527a7d6d12b6))
## v1.88.0 (2023-08-02)
### Features
- Optimize passive bluez message unmarshaller
([#216](https://github.com/Bluetooth-Devices/dbus-fast/pull/216),
[`e0e87ec`](https://github.com/Bluetooth-Devices/dbus-fast/commit/e0e87ec16ce424dbae83114ca5da13406b913deb))
## v1.87.6 (2023-08-01)
### Bug Fixes
- Exception handler failure when exception is not DBusError
([#215](https://github.com/Bluetooth-Devices/dbus-fast/pull/215),
[`d771bcf`](https://github.com/Bluetooth-Devices/dbus-fast/commit/d771bcf6a2ed08486affe0e2c30bd8dd95ccbb5d))
## v1.87.5 (2023-07-28)
### Bug Fixes
- Result typing in ServiceInterface._handle_signal
([#214](https://github.com/Bluetooth-Devices/dbus-fast/pull/214),
[`5bda04b`](https://github.com/Bluetooth-Devices/dbus-fast/commit/5bda04b089b5f089c90c333ca0db02d40d38a8ca))
## v1.87.4 (2023-07-28)
### Bug Fixes
- Avoid double buffering when using asyncio reader without negotiate_unix_fd
([#213](https://github.com/Bluetooth-Devices/dbus-fast/pull/213),
[`c933be7`](https://github.com/Bluetooth-Devices/dbus-fast/commit/c933be709508e0504e97254247bec70eb9e8c6d4))
## v1.87.3 (2023-07-27)
### Bug Fixes
- Relax typing on _fn_result_to_body to allow Any
([#212](https://github.com/Bluetooth-Devices/dbus-fast/pull/212),
[`2f5fc38`](https://github.com/Bluetooth-Devices/dbus-fast/commit/2f5fc3800702f6eb680d94de94b997ed5d8b9b77))
## v1.87.2 (2023-07-24)
### Bug Fixes
- Typing on _fn_result_to_body was incorrect which was caused an exception with cython3
([#210](https://github.com/Bluetooth-Devices/dbus-fast/pull/210),
[`c40c7bc`](https://github.com/Bluetooth-Devices/dbus-fast/commit/c40c7bcc4a8bbbce73d4d090ac840f8fe95d943e))
## v1.87.1 (2023-07-24)
### Bug Fixes
- Cython3 compat ([#208](https://github.com/Bluetooth-Devices/dbus-fast/pull/208),
[`43b3d48`](https://github.com/Bluetooth-Devices/dbus-fast/commit/43b3d48c8934a5274e4fae9b2c65c8ce6477a65b))
## v1.87.0 (2023-07-24)
### Features
- Initial cpython 3.12 support ([#207](https://github.com/Bluetooth-Devices/dbus-fast/pull/207),
[`c755193`](https://github.com/Bluetooth-Devices/dbus-fast/commit/c755193ee038e4d35ad25d5d02e0a1a8cecd9d6d))
## v1.86.0 (2023-05-03)
### Chores
- Update deps via poetry ([#201](https://github.com/Bluetooth-Devices/dbus-fast/pull/201),
[`a17d6d0`](https://github.com/Bluetooth-Devices/dbus-fast/commit/a17d6d0fd08fde630942aa7f44a8fb452c48d761))
### Features
- Improve performance of reading from the socket during unmarshall
([#200](https://github.com/Bluetooth-Devices/dbus-fast/pull/200),
[`e5d355f`](https://github.com/Bluetooth-Devices/dbus-fast/commit/e5d355ff407baf58a8e5b03c3e9ca25213a95e05))
## v1.85.0 (2023-04-21)
### Features
- Improve unmarshall performance ([#199](https://github.com/Bluetooth-Devices/dbus-fast/pull/199),
[`3dc98be`](https://github.com/Bluetooth-Devices/dbus-fast/commit/3dc98be7e948d61cd98b326ece4bc9eef7803684))
## v1.84.2 (2023-02-20)
### Bug Fixes
- Corrects Variant documentation ([#197](https://github.com/Bluetooth-Devices/dbus-fast/pull/197),
[`9c6a472`](https://github.com/Bluetooth-Devices/dbus-fast/commit/9c6a472100a471c8f41d495707182eca8d5d25a1))
Co-authored-by: J. Nick Koston
## v1.84.1 (2023-02-14)
### Bug Fixes
- Missing c extensions with newer poetry
([#194](https://github.com/Bluetooth-Devices/dbus-fast/pull/194),
[`72ddb15`](https://github.com/Bluetooth-Devices/dbus-fast/commit/72ddb156f0ac0fe0910ea41360f32f75a13cc7e4))
### Chores
- Bump isort to 5.12.0 to fix ci ([#195](https://github.com/Bluetooth-Devices/dbus-fast/pull/195),
[`7b04136`](https://github.com/Bluetooth-Devices/dbus-fast/commit/7b04136822be9e2bc892c0d70d1eca40fe0634e8))
- Bump python-semantic-release to fix CI
([#196](https://github.com/Bluetooth-Devices/dbus-fast/pull/196),
[`6387f82`](https://github.com/Bluetooth-Devices/dbus-fast/commit/6387f821e012c0b43e1e0637e3a8d2311c298662))
## v1.84.0 (2023-01-07)
### Features
- Add support for EXTERNAL auth without uid
([#193](https://github.com/Bluetooth-Devices/dbus-fast/pull/193),
[`4939ef8`](https://github.com/Bluetooth-Devices/dbus-fast/commit/4939ef80e523af8a08900fe78abc2f3c54ec835e))
## v1.83.1 (2022-12-24)
### Bug Fixes
- Cleanup typing in marshaller and unmarshaller
([#190](https://github.com/Bluetooth-Devices/dbus-fast/pull/190),
[`830183e`](https://github.com/Bluetooth-Devices/dbus-fast/commit/830183e1887a7abb876813098f17e22550453569))
## v1.83.0 (2022-12-23)
### Features
- Allow hardcoding uid in auth ([#189](https://github.com/Bluetooth-Devices/dbus-fast/pull/189),
[`091c262`](https://github.com/Bluetooth-Devices/dbus-fast/commit/091c262e2747be5170596ea9e84b2cd884d01762))
Closes https://github.com/Bluetooth-Devices/dbus-fast/issues/188
## v1.82.0 (2022-12-09)
### Features
- Avoid enum dunder overhead in message_bus calls
([#187](https://github.com/Bluetooth-Devices/dbus-fast/pull/187),
[`b3c7d51`](https://github.com/Bluetooth-Devices/dbus-fast/commit/b3c7d5139d4cfa5bcea2435b6acdb6e1e059ceb4))
## v1.81.0 (2022-12-09)
### Chores
- Add passive unmarshall benchmark ([#185](https://github.com/Bluetooth-Devices/dbus-fast/pull/185),
[`5b0d9d0`](https://github.com/Bluetooth-Devices/dbus-fast/commit/5b0d9d024aa2e2b2378bc801607c63d6ca7b6bbe))
### Features
- Speed up processing bluez passive advertisements
([#186](https://github.com/Bluetooth-Devices/dbus-fast/pull/186),
[`fb0cc35`](https://github.com/Bluetooth-Devices/dbus-fast/commit/fb0cc3584888bd307db3eb689f0dd81a025a1396))
## v1.80.0 (2022-12-09)
### Features
- Speed up checking if a message needs a reply
([#181](https://github.com/Bluetooth-Devices/dbus-fast/pull/181),
[`d1366ac`](https://github.com/Bluetooth-Devices/dbus-fast/commit/d1366aca644d78f446f47b8fd607b82f73299fb8))
## v1.79.0 (2022-12-09)
### Features
- Add a cython pxd for services ([#180](https://github.com/Bluetooth-Devices/dbus-fast/pull/180),
[`f3c9250`](https://github.com/Bluetooth-Devices/dbus-fast/commit/f3c925079a1ea632ed850f71aaf26ba1e57f2ca8))
## v1.78.0 (2022-12-08)
### Chores
- Disable some more tests that segfault under py3.10
([#179](https://github.com/Bluetooth-Devices/dbus-fast/pull/179),
[`b23086b`](https://github.com/Bluetooth-Devices/dbus-fast/commit/b23086b25ddf57580cff4b86c8adb031e6203268))
### Features
- Simplify creation of SendReply in message_bus
([#178](https://github.com/Bluetooth-Devices/dbus-fast/pull/178),
[`24faa00`](https://github.com/Bluetooth-Devices/dbus-fast/commit/24faa00062237cbee83ea118e4c11f319899538f))
## v1.77.0 (2022-12-08)
### Features
- Avoid replacing unix_fds if there are no unix_fds
([#176](https://github.com/Bluetooth-Devices/dbus-fast/pull/176),
[`06647d7`](https://github.com/Bluetooth-Devices/dbus-fast/commit/06647d7e49aa29b40146c7655f0edd4979a5500d))
## v1.76.0 (2022-12-08)
### Chores
- Disable flakey glib test on newer python
([#173](https://github.com/Bluetooth-Devices/dbus-fast/pull/173),
[`7edfc38`](https://github.com/Bluetooth-Devices/dbus-fast/commit/7edfc38b6314337dd0cec2bf92e9e07f0dfdfeba))
- Disable one more flakey glib test on py3.10
([#174](https://github.com/Bluetooth-Devices/dbus-fast/pull/174),
[`2fa7cdb`](https://github.com/Bluetooth-Devices/dbus-fast/commit/2fa7cdb15653e8d6df079e24876419b2c896bf05))
### Features
- Only construct handlers once ([#175](https://github.com/Bluetooth-Devices/dbus-fast/pull/175),
[`fb4d540`](https://github.com/Bluetooth-Devices/dbus-fast/commit/fb4d5402ba254e62989cbd0e36c3ad510bb0d358))
## v1.75.1 (2022-11-23)
### Bug Fixes
- Fix remaining altdesktop links ([#169](https://github.com/Bluetooth-Devices/dbus-fast/pull/169),
[`67255f7`](https://github.com/Bluetooth-Devices/dbus-fast/commit/67255f7e01f7970e4acdd57c9a399f9452fc1d0c))
There were still a few links incorrectly pointing back to altdesktop/python-dbus-next on GitHub.
## v1.75.0 (2022-11-17)
### Features
- Add unmarshaller cython typing for SignatureType and SignatureTree
([#168](https://github.com/Bluetooth-Devices/dbus-fast/pull/168),
[`98d5c5a`](https://github.com/Bluetooth-Devices/dbus-fast/commit/98d5c5aec2c800351666921c14aaa64741ca2831))
## v1.74.2 (2022-11-17)
### Bug Fixes
- Small fixes for typing with older python versions
([#167](https://github.com/Bluetooth-Devices/dbus-fast/pull/167),
[`1e32f28`](https://github.com/Bluetooth-Devices/dbus-fast/commit/1e32f284cd7a15da81d278ffa9f5abe34563aafc))
## v1.74.1 (2022-11-16)
### Bug Fixes
- Building via PEP 517 ([#166](https://github.com/Bluetooth-Devices/dbus-fast/pull/166),
[`6694fda`](https://github.com/Bluetooth-Devices/dbus-fast/commit/6694fda49f966814ebc900a52812b4c5e4ff1980))
## v1.74.0 (2022-11-14)
### Features
- Improve cdef types for marshaller
([#164](https://github.com/Bluetooth-Devices/dbus-fast/pull/164),
[`9fb4440`](https://github.com/Bluetooth-Devices/dbus-fast/commit/9fb4440b805fa5bf432fa1b23d9b1fac1de31b96))
## v1.73.1 (2022-11-14)
### Bug Fixes
- Allow non-string objects to be marshalled by write_string
([#163](https://github.com/Bluetooth-Devices/dbus-fast/pull/163),
[`46f1d6b`](https://github.com/Bluetooth-Devices/dbus-fast/commit/46f1d6bbc09860185db04c7985b9fd7c23e7a1bf))
## v1.73.0 (2022-11-11)
### Chores
- Add a test for unmarshalling a big endian message
([#156](https://github.com/Bluetooth-Devices/dbus-fast/pull/156),
[`b329700`](https://github.com/Bluetooth-Devices/dbus-fast/commit/b3297008bc3776c6220b66a0036cfdf2b636157d))
- Add big endian github workflow ([#155](https://github.com/Bluetooth-Devices/dbus-fast/pull/155),
[`984738c`](https://github.com/Bluetooth-Devices/dbus-fast/commit/984738c8030aff5e0a614a2b398ec690d21636fb))
thanks to https://til.simonwillison.net/docker/emulate-s390x-with-qemu
- Make big endian workflow manual until we get it working properly
([#157](https://github.com/Bluetooth-Devices/dbus-fast/pull/157),
[`9240bfd`](https://github.com/Bluetooth-Devices/dbus-fast/commit/9240bfda6e280bc75d8f249ba3470202a0318913))
- Prepare marshaller to be able to generate big endian messages
([#154](https://github.com/Bluetooth-Devices/dbus-fast/pull/154),
[`b2327c0`](https://github.com/Bluetooth-Devices/dbus-fast/commit/b2327c08558ba6a785064788c5fe448784d56be0))
### Features
- Reduce latency to process messages
([#161](https://github.com/Bluetooth-Devices/dbus-fast/pull/161),
[`113f0c9`](https://github.com/Bluetooth-Devices/dbus-fast/commit/113f0c9a325d538592555ae89e1df1ea29398aa9))
Improve `message_bus.py` `_process_message` performance with a `pxd` file
## v1.72.0 (2022-11-04)
### Chores
- Add benchmark and tests for GetManagedObjects
([#150](https://github.com/Bluetooth-Devices/dbus-fast/pull/150),
[`2d56622`](https://github.com/Bluetooth-Devices/dbus-fast/commit/2d566224d34217cb720aacef1cc9a656f564901c))
### Features
- Add optimized reader for GetManagedObjects
([#152](https://github.com/Bluetooth-Devices/dbus-fast/pull/152),
[`7ed453f`](https://github.com/Bluetooth-Devices/dbus-fast/commit/7ed453f31a654f8cc9b99eb17f872370f4b06a4e))
## v1.71.0 (2022-11-04)
### Features
- Small speed up to _unpack_variants
([#148](https://github.com/Bluetooth-Devices/dbus-fast/pull/148),
[`ef7acdc`](https://github.com/Bluetooth-Devices/dbus-fast/commit/ef7acdcbe59123bfa3b17d5dafc9f8235ac0f360))
## v1.70.0 (2022-11-04)
### Features
- Use cimports for message marshalling
([#149](https://github.com/Bluetooth-Devices/dbus-fast/pull/149),
[`ef7d9d4`](https://github.com/Bluetooth-Devices/dbus-fast/commit/ef7d9d440775cf0ddcb6b3bc6115b3884be35792))
## v1.69.0 (2022-11-04)
### Features
- Refactor message_reader to avoid python wrappers
([#147](https://github.com/Bluetooth-Devices/dbus-fast/pull/147),
[`b81de45`](https://github.com/Bluetooth-Devices/dbus-fast/commit/b81de4553fc1414476ff8a1c2b73db7b1a497841))
## v1.68.0 (2022-11-04)
### Features
- Use cimports for unmarshaller Variant and Message
([#146](https://github.com/Bluetooth-Devices/dbus-fast/pull/146),
[`6418ed4`](https://github.com/Bluetooth-Devices/dbus-fast/commit/6418ed4bb69a835768596f66ab5b514ea48b82cc))
## v1.67.0 (2022-11-03)
### Features
- Optimize unmarshaller by dropping exception that was only used internally
([#145](https://github.com/Bluetooth-Devices/dbus-fast/pull/145),
[`79d52a5`](https://github.com/Bluetooth-Devices/dbus-fast/commit/79d52a50bd9651fa489e81935bda04d53285b2c1))
## v1.66.0 (2022-11-03)
### Features
- Speed up creating Variant objects
([#144](https://github.com/Bluetooth-Devices/dbus-fast/pull/144),
[`2ff84e3`](https://github.com/Bluetooth-Devices/dbus-fast/commit/2ff84e3ac56f4348c8276515ac398fcbda8a0657))
## v1.65.0 (2022-11-03)
### Features
- Add cython def for unmarshaller read_sock for fd passing
([#143](https://github.com/Bluetooth-Devices/dbus-fast/pull/143),
[`f438c36`](https://github.com/Bluetooth-Devices/dbus-fast/commit/f438c369bd86956f50fb839ec4a0a8069de7d018))
## v1.64.0 (2022-11-03)
### Features
- Speed up marshalling headers ([#142](https://github.com/Bluetooth-Devices/dbus-fast/pull/142),
[`7d6fb63`](https://github.com/Bluetooth-Devices/dbus-fast/commit/7d6fb63dc011404955fc1219924cd2c6f6634ccd))
## v1.63.0 (2022-11-03)
### Features
- Speed up marshall align ([#137](https://github.com/Bluetooth-Devices/dbus-fast/pull/137),
[`d7d301c`](https://github.com/Bluetooth-Devices/dbus-fast/commit/d7d301c773beb312be752accf7018a3dacecde02))
- Speed up marshall write_string and write_variant
([#138](https://github.com/Bluetooth-Devices/dbus-fast/pull/138),
[`71cf524`](https://github.com/Bluetooth-Devices/dbus-fast/commit/71cf52430bd3ece01083309c5f0f5d934dca3d59))
## v1.62.0 (2022-11-03)
### Chores
- Add explicit test for workaround of python/cpython#98976
([#135](https://github.com/Bluetooth-Devices/dbus-fast/pull/135),
[`b486e32`](https://github.com/Bluetooth-Devices/dbus-fast/commit/b486e3248baf7335f133ed3e67641df9a6beb091))
- Update pyproject.toml dependencies
([#136](https://github.com/Bluetooth-Devices/dbus-fast/pull/136),
[`4a23e0e`](https://github.com/Bluetooth-Devices/dbus-fast/commit/4a23e0e0c5a1f4f52670f59433855dd87bf36371))
### Features
- Speed up marshaller by pre-packing bools
([#139](https://github.com/Bluetooth-Devices/dbus-fast/pull/139),
[`c10a241`](https://github.com/Bluetooth-Devices/dbus-fast/commit/c10a241dc5e889fd58323789dc4af45ec1e5616a))
## v1.61.1 (2022-11-01)
### Bug Fixes
- Re-release due to pypi not seeing the new version
([#134](https://github.com/Bluetooth-Devices/dbus-fast/pull/134),
[`2f21ee8`](https://github.com/Bluetooth-Devices/dbus-fast/commit/2f21ee8b8d52975624c19b6593a96976fa19047b))
### Chores
- Adjust poetry for python 3.11 ([#133](https://github.com/Bluetooth-Devices/dbus-fast/pull/133),
[`6d7391a`](https://github.com/Bluetooth-Devices/dbus-fast/commit/6d7391a8f865ad377e3edd2b47b42c296b267cab))
## v1.61.0 (2022-11-01)
### Chores
- Drop async-timeout dependency on Python >= 3.11
([#132](https://github.com/Bluetooth-Devices/dbus-fast/pull/132),
[`1b5c9e1`](https://github.com/Bluetooth-Devices/dbus-fast/commit/1b5c9e1cb94d19925776d91196cf1b657264c494))
### Features
- Add support and workarounds for cpython3.11
([#31](https://github.com/Bluetooth-Devices/dbus-fast/pull/31),
[`b53a467`](https://github.com/Bluetooth-Devices/dbus-fast/commit/b53a4675d78f8e4e37be322ebda3eeec80f15723))
## v1.60.0 (2022-10-31)
### Features
- Speed up auth phase ([#131](https://github.com/Bluetooth-Devices/dbus-fast/pull/131),
[`3eef636`](https://github.com/Bluetooth-Devices/dbus-fast/commit/3eef6368268c2d46db3b31bf907959da36dbf2a4))
## v1.59.2 (2022-10-31)
### Bug Fixes
- Correctly fallback to pure python when cython is missing
([#130](https://github.com/Bluetooth-Devices/dbus-fast/pull/130),
[`8ab1f9d`](https://github.com/Bluetooth-Devices/dbus-fast/commit/8ab1f9d0b380293294a0f847664e0c459061c2d9))
## v1.59.1 (2022-10-29)
### Bug Fixes
- Pass return value to SendReply.__exit__
([#127](https://github.com/Bluetooth-Devices/dbus-fast/pull/127),
[`f8c67ed`](https://github.com/Bluetooth-Devices/dbus-fast/commit/f8c67ed00fa8fe58a85b6ba73b5fa5974f802004))
### Chores
- Add additional coverage for multiple messages in the same packet
([#126](https://github.com/Bluetooth-Devices/dbus-fast/pull/126),
[`8f6a431`](https://github.com/Bluetooth-Devices/dbus-fast/commit/8f6a431ea49fc168adf484732af5e10debdad93f))
## v1.59.0 (2022-10-29)
### Features
- Speed up decoding headers by avoiding unicode checks
([#125](https://github.com/Bluetooth-Devices/dbus-fast/pull/125),
[`6121781`](https://github.com/Bluetooth-Devices/dbus-fast/commit/61217819fbbe073007a44db69328008941d6bb4c))
## v1.58.0 (2022-10-29)
### Features
- Add optimized parser for properties changed messages with service data
([#124](https://github.com/Bluetooth-Devices/dbus-fast/pull/124),
[`c8a9452`](https://github.com/Bluetooth-Devices/dbus-fast/commit/c8a945210ae3ea8d25e4547f70b25d61b778ffe1))
## v1.57.0 (2022-10-29)
### Features
- Add optimized parser for InterfacesRemoved
([#123](https://github.com/Bluetooth-Devices/dbus-fast/pull/123),
[`09822a5`](https://github.com/Bluetooth-Devices/dbus-fast/commit/09822a59ffad07b8dcb6d216d98e6dccbe338b06))
## v1.56.0 (2022-10-29)
### Features
- Optimize for interfaces added messages
([#122](https://github.com/Bluetooth-Devices/dbus-fast/pull/122),
[`c05a27a`](https://github.com/Bluetooth-Devices/dbus-fast/commit/c05a27aef9395eb688385109c4ff7204d5103dda))
## v1.55.0 (2022-10-29)
### Features
- Add optimized reader for uint16 ([#121](https://github.com/Bluetooth-Devices/dbus-fast/pull/121),
[`52881d9`](https://github.com/Bluetooth-Devices/dbus-fast/commit/52881d9054e35ae3d727c4adafd7e0958b1c99af))
## v1.54.0 (2022-10-28)
### Features
- Speed up unmarshaller with common signature trees
([#120](https://github.com/Bluetooth-Devices/dbus-fast/pull/120),
[`5b32072`](https://github.com/Bluetooth-Devices/dbus-fast/commit/5b32072934a7269ffc7186aaaed77a0eb6872cd9))
Co-authored-by: David Lechner
## v1.53.0 (2022-10-28)
### Features
- Add additional pxd defs for message
([#118](https://github.com/Bluetooth-Devices/dbus-fast/pull/118),
[`3eb123b`](https://github.com/Bluetooth-Devices/dbus-fast/commit/3eb123b0366ed143d395e0609540c580398cd896))
## v1.52.0 (2022-10-28)
### Chores
- Fix ci ([#119](https://github.com/Bluetooth-Devices/dbus-fast/pull/119),
[`3c773e1`](https://github.com/Bluetooth-Devices/dbus-fast/commit/3c773e118c78e6bc336d432eab57e36a0ed7213d))
### Features
- Small speed up to unpack_variants
([#117](https://github.com/Bluetooth-Devices/dbus-fast/pull/117),
[`3c164a9`](https://github.com/Bluetooth-Devices/dbus-fast/commit/3c164a9291b9fb6e75aed0fc5aab1dfc7b79c376))
## v1.51.0 (2022-10-27)
### Features
- Inline cast uint32 and int16 to speed up unmarshall
([#115](https://github.com/Bluetooth-Devices/dbus-fast/pull/115),
[`24dd9d9`](https://github.com/Bluetooth-Devices/dbus-fast/commit/24dd9d9742e8c779b9c8aa751ba8b2815b61b15b))
## v1.50.0 (2022-10-27)
### Features
- Speed up unmarshall ([#114](https://github.com/Bluetooth-Devices/dbus-fast/pull/114),
[`e1836b2`](https://github.com/Bluetooth-Devices/dbus-fast/commit/e1836b2034ca4bfbb004027f98b42c68f6c6edce))
## v1.49.0 (2022-10-26)
### Features
- Speed up unmarshaller ([#113](https://github.com/Bluetooth-Devices/dbus-fast/pull/113),
[`8f7f982`](https://github.com/Bluetooth-Devices/dbus-fast/commit/8f7f982a75fe9c998e5a983090e361ba52e2e6a3))
## v1.48.0 (2022-10-20)
### Features
- Add typing to auth module ([#110](https://github.com/Bluetooth-Devices/dbus-fast/pull/110),
[`e07e281`](https://github.com/Bluetooth-Devices/dbus-fast/commit/e07e281ded44f9ded3002c34803f802146a9e3c9))
## v1.47.0 (2022-10-19)
### Features
- Speed up unmarshaller ([#109](https://github.com/Bluetooth-Devices/dbus-fast/pull/109),
[`2443cf9`](https://github.com/Bluetooth-Devices/dbus-fast/commit/2443cf99909af02db040caeeded7024a020c50a5))
## v1.46.0 (2022-10-19)
### Features
- Speed up marshaller and add typing
([#108](https://github.com/Bluetooth-Devices/dbus-fast/pull/108),
[`e8f568c`](https://github.com/Bluetooth-Devices/dbus-fast/commit/e8f568c074965bf7955f29cd89cf14f1b8dd5643))
## v1.45.0 (2022-10-13)
### Features
- Optimize signature readers for most common messages
([#107](https://github.com/Bluetooth-Devices/dbus-fast/pull/107),
[`d5fb4d9`](https://github.com/Bluetooth-Devices/dbus-fast/commit/d5fb4d9c8bf17c51762ea961d745c5db7d8d8a22))
## v1.44.0 (2022-10-12)
### Features
- Speed up unpack_variants ([#105](https://github.com/Bluetooth-Devices/dbus-fast/pull/105),
[`a4fdda2`](https://github.com/Bluetooth-Devices/dbus-fast/commit/a4fdda271f7a96e267826ffa3f268ec02078ba73))
## v1.43.0 (2022-10-12)
### Features
- Improve aio message reader performance
([#104](https://github.com/Bluetooth-Devices/dbus-fast/pull/104),
[`9fa697d`](https://github.com/Bluetooth-Devices/dbus-fast/commit/9fa697da65d449b7402aa7f2f26762b0d2e175c6))
## v1.42.0 (2022-10-12)
### Features
- Complete some more missing typing
([#103](https://github.com/Bluetooth-Devices/dbus-fast/pull/103),
[`5787032`](https://github.com/Bluetooth-Devices/dbus-fast/commit/5787032af7cae1ffffd1561390cdb02053776345))
## v1.41.0 (2022-10-11)
### Features
- Add more typing to unmarshaller ([#102](https://github.com/Bluetooth-Devices/dbus-fast/pull/102),
[`e7048fa`](https://github.com/Bluetooth-Devices/dbus-fast/commit/e7048fa38b63ea45e819930a51ca5744f86da73f))
## v1.40.0 (2022-10-10)
### Features
- Speed up unmarshaller ([#101](https://github.com/Bluetooth-Devices/dbus-fast/pull/101),
[`a6a248b`](https://github.com/Bluetooth-Devices/dbus-fast/commit/a6a248b3b1dbbb06784f700b49a7fe92b30cc7b5))
## v1.39.0 (2022-10-10)
### Features
- Add additional typing ([#100](https://github.com/Bluetooth-Devices/dbus-fast/pull/100),
[`cde1893`](https://github.com/Bluetooth-Devices/dbus-fast/commit/cde1893dca1872d8b482a145337ee3bbf47c35b4))
## v1.38.0 (2022-10-09)
### Features
- Optimize for reading a{sv} messages and headers
([#98](https://github.com/Bluetooth-Devices/dbus-fast/pull/98),
[`4648d29`](https://github.com/Bluetooth-Devices/dbus-fast/commit/4648d29df4b616f49c06ca9fcbfbc27717d97135))
## v1.37.0 (2022-10-09)
### Chores
- Adjust unmarshall benchmarks since they are now fast enough to hit the margin of error
([#97](https://github.com/Bluetooth-Devices/dbus-fast/pull/97),
[`0ee88e4`](https://github.com/Bluetooth-Devices/dbus-fast/commit/0ee88e4018d4c436ffedb1a00136088606ba3977))
### Features
- Speed up empty array unmarshall ([#96](https://github.com/Bluetooth-Devices/dbus-fast/pull/96),
[`2c6ee99`](https://github.com/Bluetooth-Devices/dbus-fast/commit/2c6ee99b73dcfb2e2d45d2610a3fa10a4ff2136a))
## v1.36.0 (2022-10-09)
### Features
- Add cdef to unpack_variants ([#95](https://github.com/Bluetooth-Devices/dbus-fast/pull/95),
[`dbf42c3`](https://github.com/Bluetooth-Devices/dbus-fast/commit/dbf42c370784236ff31e9324968f02a5efb58586))
## v1.35.0 (2022-10-09)
### Features
- Add unpack variants benchmark ([#94](https://github.com/Bluetooth-Devices/dbus-fast/pull/94),
[`eb966fd`](https://github.com/Bluetooth-Devices/dbus-fast/commit/eb966fd7cf3a3f05879c29f7eb98727dd117c317))
## v1.34.0 (2022-10-09)
### Features
- Add additional typing ([#93](https://github.com/Bluetooth-Devices/dbus-fast/pull/93),
[`7326bdf`](https://github.com/Bluetooth-Devices/dbus-fast/commit/7326bdf097310eafa21364dd46f6ebb72baa1a3d))
## v1.33.0 (2022-10-09)
### Features
- Improve performance of unmarshalling headers
([#88](https://github.com/Bluetooth-Devices/dbus-fast/pull/88),
[`b6d4069`](https://github.com/Bluetooth-Devices/dbus-fast/commit/b6d40691fd11ff8d4e46a57fd8cc97a9b6806089))
## v1.32.0 (2022-10-08)
### Features
- Speed up marshalling arrays ([#87](https://github.com/Bluetooth-Devices/dbus-fast/pull/87),
[`f554345`](https://github.com/Bluetooth-Devices/dbus-fast/commit/f554345b3640524300fbe406f4ac25dbf61a2274))
## v1.31.0 (2022-10-08)
### Features
- Speed up marshalling variants ([#86](https://github.com/Bluetooth-Devices/dbus-fast/pull/86),
[`7847e26`](https://github.com/Bluetooth-Devices/dbus-fast/commit/7847e26e6e6cfe172437544d7709dc0c87a65402))
## v1.30.0 (2022-10-08)
### Features
- Speed up aligning data during marshall
([#85](https://github.com/Bluetooth-Devices/dbus-fast/pull/85),
[`07e6886`](https://github.com/Bluetooth-Devices/dbus-fast/commit/07e68862d93cd5dc470ad2a3ae6f8eaf12808271))
## v1.29.1 (2022-10-07)
### Bug Fixes
- Remove unused unmarshaller code ([#83](https://github.com/Bluetooth-Devices/dbus-fast/pull/83),
[`3613ff8`](https://github.com/Bluetooth-Devices/dbus-fast/commit/3613ff846b8bb66000c65c778bb06596cd643b22))
## v1.29.0 (2022-10-07)
### Features
- Unpack header names as message kwargs
([#82](https://github.com/Bluetooth-Devices/dbus-fast/pull/82),
[`7398a3f`](https://github.com/Bluetooth-Devices/dbus-fast/commit/7398a3fc4726fa20b34840967a6c3777eef12f52))
## v1.28.1 (2022-10-07)
### Bug Fixes
- Disconnect race in tests ([#79](https://github.com/Bluetooth-Devices/dbus-fast/pull/79),
[`f2bb106`](https://github.com/Bluetooth-Devices/dbus-fast/commit/f2bb10680a5d4e363ff8e7762fef25ec75ef8b14))
## v1.28.0 (2022-10-07)
### Features
- Speed up unmarshalling int16 types ([#81](https://github.com/Bluetooth-Devices/dbus-fast/pull/81),
[`18213c0`](https://github.com/Bluetooth-Devices/dbus-fast/commit/18213c0a00f162cbf74fa7fc0bbcf12c1109c347))
## v1.27.0 (2022-10-07)
### Features
- Cythonize headers in unmarshaller ([#80](https://github.com/Bluetooth-Devices/dbus-fast/pull/80),
[`ae96be7`](https://github.com/Bluetooth-Devices/dbus-fast/commit/ae96be70f5e960d3feb726b7c769dff26b41c428))
## v1.26.0 (2022-10-06)
### Bug Fixes
- Incorrect pxd typing for for _marshall
([#75](https://github.com/Bluetooth-Devices/dbus-fast/pull/75),
[`cf1f012`](https://github.com/Bluetooth-Devices/dbus-fast/commit/cf1f0129baaac48d6a4804e8c6a0af5bc7ef8d16))
### Features
- Add cython defs for Variant class ([#74](https://github.com/Bluetooth-Devices/dbus-fast/pull/74),
[`cd08f06`](https://github.com/Bluetooth-Devices/dbus-fast/commit/cd08f063cc352c65d2330cbe09ca72a367c58806))
## v1.25.0 (2022-10-05)
### Features
- Add cython extension for messages ([#73](https://github.com/Bluetooth-Devices/dbus-fast/pull/73),
[`8676f12`](https://github.com/Bluetooth-Devices/dbus-fast/commit/8676f12a7e040d7c3f20584739a74ad1074a4717))
## v1.24.0 (2022-10-04)
### Features
- Add cython extension for signature ([#72](https://github.com/Bluetooth-Devices/dbus-fast/pull/72),
[`0ad8801`](https://github.com/Bluetooth-Devices/dbus-fast/commit/0ad8801215093cdbf0f62fce5b953d9b01e9d524))
## v1.23.0 (2022-10-04)
### Features
- Speed up unmarshall performance ([#71](https://github.com/Bluetooth-Devices/dbus-fast/pull/71),
[`f38e08f`](https://github.com/Bluetooth-Devices/dbus-fast/commit/f38e08fa7cc8d41e896663ab0f163aa37a472abe))
## v1.22.0 (2022-10-03)
### Features
- Speed up message bus matching ([#70](https://github.com/Bluetooth-Devices/dbus-fast/pull/70),
[`cccfea3`](https://github.com/Bluetooth-Devices/dbus-fast/commit/cccfea30b9ec5417eecef5093ee02f7b7a254c45))
## v1.21.17 (2022-10-02)
### Bug Fixes
- Install python-semantic-release in wheel workflow
([#68](https://github.com/Bluetooth-Devices/dbus-fast/pull/68),
[`cca0d6e`](https://github.com/Bluetooth-Devices/dbus-fast/commit/cca0d6e98a5934fee83ccafbd2ed47cf60a3ce99))
## v1.21.16 (2022-10-02)
### Bug Fixes
- Ensure we can get the latest version in the wheels build process
([#67](https://github.com/Bluetooth-Devices/dbus-fast/pull/67),
[`ecd5a70`](https://github.com/Bluetooth-Devices/dbus-fast/commit/ecd5a7036945ccdd79e3049a7f2904709544af51))
## v1.21.15 (2022-10-02)
### Bug Fixes
- Checkout main for wheels ([#66](https://github.com/Bluetooth-Devices/dbus-fast/pull/66),
[`3051a93`](https://github.com/Bluetooth-Devices/dbus-fast/commit/3051a9322cc711cee24583dedf25cee31a31c3b3))
## v1.21.14 (2022-10-02)
### Bug Fixes
- Use semantic-release to find the latest tag for wheels
([#65](https://github.com/Bluetooth-Devices/dbus-fast/pull/65),
[`b76eb97`](https://github.com/Bluetooth-Devices/dbus-fast/commit/b76eb97188c204996d049d326b4d21c74bc3f325))
## v1.21.13 (2022-10-02)
### Bug Fixes
- Build wheels from the sha saved after release
([#64](https://github.com/Bluetooth-Devices/dbus-fast/pull/64),
[`faee181`](https://github.com/Bluetooth-Devices/dbus-fast/commit/faee18172bb7bc72ade8a54f2a8bd0fae5e35018))
## v1.21.12 (2022-10-02)
### Bug Fixes
- Switch to on create instead of push
([#63](https://github.com/Bluetooth-Devices/dbus-fast/pull/63),
[`af0ed88`](https://github.com/Bluetooth-Devices/dbus-fast/commit/af0ed889985425b33fbbe35e8c8a4d0427643367))
## v1.21.11 (2022-10-02)
### Bug Fixes
- Accept any tag to build wheels ([#62](https://github.com/Bluetooth-Devices/dbus-fast/pull/62),
[`60fca54`](https://github.com/Bluetooth-Devices/dbus-fast/commit/60fca54d2a4da67e3211b9e3f421787154234041))
## v1.21.10 (2022-10-02)
### Bug Fixes
- Github action tag matching ([#61](https://github.com/Bluetooth-Devices/dbus-fast/pull/61),
[`b95d0b8`](https://github.com/Bluetooth-Devices/dbus-fast/commit/b95d0b8ce63e03c972fef72354cd67c2062bea94))
## v1.21.9 (2022-10-02)
### Bug Fixes
- Build wheels on tag instead ([#60](https://github.com/Bluetooth-Devices/dbus-fast/pull/60),
[`6166896`](https://github.com/Bluetooth-Devices/dbus-fast/commit/6166896c49a1358c951057fcc73d4b91ac92e08b))
## v1.21.8 (2022-10-02)
### Bug Fixes
- Publish wheels when release happens
([#59](https://github.com/Bluetooth-Devices/dbus-fast/pull/59),
[`45e8ac0`](https://github.com/Bluetooth-Devices/dbus-fast/commit/45e8ac00c6473c5329b36d4f19f5eb846db19d31))
## v1.21.7 (2022-10-02)
### Bug Fixes
- Seperate wheels back out so it builds after
([#58](https://github.com/Bluetooth-Devices/dbus-fast/pull/58),
[`c74c251`](https://github.com/Bluetooth-Devices/dbus-fast/commit/c74c2519a12a0f9cbb8c1b12b8871df22dda047d))
## v1.21.6 (2022-10-02)
### Bug Fixes
- Language_level warning when running cythonize
([#57](https://github.com/Bluetooth-Devices/dbus-fast/pull/57),
[`b7b441e`](https://github.com/Bluetooth-Devices/dbus-fast/commit/b7b441eeef8bfa1dc286c78435ff9bac9d072302))
## v1.21.5 (2022-10-02)
### Bug Fixes
- Cython build of unpack ([#56](https://github.com/Bluetooth-Devices/dbus-fast/pull/56),
[`5df01ac`](https://github.com/Bluetooth-Devices/dbus-fast/commit/5df01ac1ba3dc0515ffa8d0b01c1d386ef726e91))
## v1.21.4 (2022-10-02)
### Bug Fixes
- Increase verbosity of wheel builds ([#55](https://github.com/Bluetooth-Devices/dbus-fast/pull/55),
[`4779e7b`](https://github.com/Bluetooth-Devices/dbus-fast/commit/4779e7b825270268ae28b5fc1c4ddb45647c31c5))
## v1.21.3 (2022-10-02)
### Bug Fixes
- Make wheel build depend on release success
([#54](https://github.com/Bluetooth-Devices/dbus-fast/pull/54),
[`49d98d0`](https://github.com/Bluetooth-Devices/dbus-fast/commit/49d98d01c2a3736adcc5d088fdd447c45b9503de))
## v1.21.2 (2022-10-02)
### Bug Fixes
- Additional tweaks to publishing wheels
([#53](https://github.com/Bluetooth-Devices/dbus-fast/pull/53),
[`05b9453`](https://github.com/Bluetooth-Devices/dbus-fast/commit/05b945317380ad3d50b2f9d9114a61a2c57d99f0))
## v1.21.1 (2022-10-02)
### Bug Fixes
- Wheel builds on released ([#52](https://github.com/Bluetooth-Devices/dbus-fast/pull/52),
[`6259fb2`](https://github.com/Bluetooth-Devices/dbus-fast/commit/6259fb299722688ca19a41a61a7a783e9abdca8c))
## v1.21.0 (2022-10-02)
### Chores
- Add cibuildwheel action ([#50](https://github.com/Bluetooth-Devices/dbus-fast/pull/50),
[`f6e4c3c`](https://github.com/Bluetooth-Devices/dbus-fast/commit/f6e4c3c8aef5af04645a8249c27b9e51cfd5ad01))
### Features
- Cythonize unpack_variants ([#51](https://github.com/Bluetooth-Devices/dbus-fast/pull/51),
[`1587211`](https://github.com/Bluetooth-Devices/dbus-fast/commit/158721123fc56675f04b9081ef4107590a8c2b17))
## v1.20.0 (2022-10-02)
### Bug Fixes
- Add missing closes to tests ([#49](https://github.com/Bluetooth-Devices/dbus-fast/pull/49),
[`d2ce4a1`](https://github.com/Bluetooth-Devices/dbus-fast/commit/d2ce4a18462b5e304bc75983be3fffa3c426affc))
### Features
- Add additional cython types to the unmarshaller
([#45](https://github.com/Bluetooth-Devices/dbus-fast/pull/45),
[`0f279a5`](https://github.com/Bluetooth-Devices/dbus-fast/commit/0f279a5ea9cd440fdbdd7dbafc1a48b1cc3577d7))
## v1.19.0 (2022-10-02)
### Features
- Add additional cython types to marshaller
([#48](https://github.com/Bluetooth-Devices/dbus-fast/pull/48),
[`ddba96a`](https://github.com/Bluetooth-Devices/dbus-fast/commit/ddba96a73107644e31af591d8b726472a7deb85b))
## v1.18.0 (2022-10-01)
### Features
- Add optional cython extension ([#44](https://github.com/Bluetooth-Devices/dbus-fast/pull/44),
[`b737574`](https://github.com/Bluetooth-Devices/dbus-fast/commit/b737574cf04f5c6b6f881fbdce2663119a6dc404))
## v1.17.0 (2022-09-27)
### Features
- Improve unmarshaller performance ([#43](https://github.com/Bluetooth-Devices/dbus-fast/pull/43),
[`c4b4a03`](https://github.com/Bluetooth-Devices/dbus-fast/commit/c4b4a038f8822b6be7b062184b8092b6249878bc))
## v1.16.0 (2022-09-27)
### Features
- Add benchmark for bluez properties messages
([#42](https://github.com/Bluetooth-Devices/dbus-fast/pull/42),
[`076c5df`](https://github.com/Bluetooth-Devices/dbus-fast/commit/076c5df825221901d1565e45f8662d7d9009ffe9))
## v1.15.3 (2022-09-27)
### Bug Fixes
- Improve typing on proxy_object ([#41](https://github.com/Bluetooth-Devices/dbus-fast/pull/41),
[`ac955b5`](https://github.com/Bluetooth-Devices/dbus-fast/commit/ac955b50ea2921b114f6a89c2e1d3fbf34698deb))
## v1.15.2 (2022-09-27)
### Bug Fixes
- More typing fixes ([#40](https://github.com/Bluetooth-Devices/dbus-fast/pull/40),
[`a6b9581`](https://github.com/Bluetooth-Devices/dbus-fast/commit/a6b9581d6228bf2cb4b93531677acc959e2d4dd1))
## v1.15.1 (2022-09-26)
### Bug Fixes
- Loosen async-timeout pin to 3.0.0 ([#39](https://github.com/Bluetooth-Devices/dbus-fast/pull/39),
[`93b9a0a`](https://github.com/Bluetooth-Devices/dbus-fast/commit/93b9a0a6ca91adb6c64d9316bd977a359c3be007))
## v1.15.0 (2022-09-26)
### Features
- Use async_timeout instead of asyncio.wait_for
([#38](https://github.com/Bluetooth-Devices/dbus-fast/pull/38),
[`cb31780`](https://github.com/Bluetooth-Devices/dbus-fast/commit/cb317802d654bbff7b09233b4cce6188179f1d45))
## v1.14.0 (2022-09-25)
### Features
- Speed up unmarshaller read_array ([#37](https://github.com/Bluetooth-Devices/dbus-fast/pull/37),
[`18ea18d`](https://github.com/Bluetooth-Devices/dbus-fast/commit/18ea18d7d224764b7f529cb6238ac524f0bd8318))
## v1.13.0 (2022-09-24)
### Features
- Improve unmarshall performance ([#35](https://github.com/Bluetooth-Devices/dbus-fast/pull/35),
[`db436b7`](https://github.com/Bluetooth-Devices/dbus-fast/commit/db436b7a10a38438a9a7f50349ddb41b112c3312))
## v1.12.0 (2022-09-24)
### Features
- Speed up unmarshall ([#34](https://github.com/Bluetooth-Devices/dbus-fast/pull/34),
[`5a1e26f`](https://github.com/Bluetooth-Devices/dbus-fast/commit/5a1e26f4302ed1ff3a4582e6710e2c5f99cb4a32))
## v1.11.0 (2022-09-24)
### Features
- Speed up marshalling ([#32](https://github.com/Bluetooth-Devices/dbus-fast/pull/32),
[`afcf5fe`](https://github.com/Bluetooth-Devices/dbus-fast/commit/afcf5fe1d9c1c4a632edc60b5d48d8af32d13159))
## v1.10.0 (2022-09-24)
### Features
- Improve writer performance with a deque
([#30](https://github.com/Bluetooth-Devices/dbus-fast/pull/30),
[`09af56e`](https://github.com/Bluetooth-Devices/dbus-fast/commit/09af56e14397d9bdf183239c30683c76b7e34801))
## v1.9.0 (2022-09-24)
### Features
- Improve asyncio write performance ([#29](https://github.com/Bluetooth-Devices/dbus-fast/pull/29),
[`016e71e`](https://github.com/Bluetooth-Devices/dbus-fast/commit/016e71ef6d7de4d9295f3ca170d7352ae233d74a))
## v1.8.0 (2022-09-24)
### Features
- Small speed ups to unmarshall message creation
([#27](https://github.com/Bluetooth-Devices/dbus-fast/pull/27),
[`0bce72a`](https://github.com/Bluetooth-Devices/dbus-fast/commit/0bce72a76a6af0d7b3c731e08393652747e6c53a))
## v1.7.0 (2022-09-21)
### Features
- Handle kwargs in signal callback ([#26](https://github.com/Bluetooth-Devices/dbus-fast/pull/26),
[`2e8076b`](https://github.com/Bluetooth-Devices/dbus-fast/commit/2e8076b14abf297b83eb2c81b0cacff405845d95))
## v1.6.0 (2022-09-20)
### Bug Fixes
- Disconnect connected buses at end of tests
([#25](https://github.com/Bluetooth-Devices/dbus-fast/pull/25),
[`e438890`](https://github.com/Bluetooth-Devices/dbus-fast/commit/e43889091bf7b21f6ffd27544d74cc1d57db22d2))
### Features
- Add unpack variants option ([#20](https://github.com/Bluetooth-Devices/dbus-fast/pull/20),
[`cfad28b`](https://github.com/Bluetooth-Devices/dbus-fast/commit/cfad28bd2ba8dccf4c3a591461bb666871e4cbba))
## v1.5.1 (2022-09-20)
### Bug Fixes
- Marshall boolean correctly ([#23](https://github.com/Bluetooth-Devices/dbus-fast/pull/23),
[`ca2a3c1`](https://github.com/Bluetooth-Devices/dbus-fast/commit/ca2a3c1aa86f1f0b6372929f099e8594dab2697f))
## v1.5.0 (2022-09-19)
### Chores
- Run gi tests in the CI ([#21](https://github.com/Bluetooth-Devices/dbus-fast/pull/21),
[`f4d173e`](https://github.com/Bluetooth-Devices/dbus-fast/commit/f4d173e0426990cd0b8b1b813949cd5027684102))
### Features
- Allow varargs callback for signals ([#22](https://github.com/Bluetooth-Devices/dbus-fast/pull/22),
[`a3379c7`](https://github.com/Bluetooth-Devices/dbus-fast/commit/a3379c74ad8f8da1eb15b6cd941d9bea6867b5f9))
## v1.4.0 (2022-09-10)
### Features
- Improve unmarshalling performance ([#18](https://github.com/Bluetooth-Devices/dbus-fast/pull/18),
[`4362b93`](https://github.com/Bluetooth-Devices/dbus-fast/commit/4362b93fc84406adfa026b6573bc076327c71c5b))
## v1.3.0 (2022-09-09)
### Features
- Improve callback performance ([#16](https://github.com/Bluetooth-Devices/dbus-fast/pull/16),
[`aee3da9`](https://github.com/Bluetooth-Devices/dbus-fast/commit/aee3da9f20c36cf6379d1e69e63f33a88592f6fd))
## v1.2.0 (2022-09-09)
### Chores
- Add marshall benchmark ([#14](https://github.com/Bluetooth-Devices/dbus-fast/pull/14),
[`e386e22`](https://github.com/Bluetooth-Devices/dbus-fast/commit/e386e228c54914b0a1f8babe3659ea5629a3cb7d))
### Features
- Improve Marshaller performance ([#15](https://github.com/Bluetooth-Devices/dbus-fast/pull/15),
[`a9e8866`](https://github.com/Bluetooth-Devices/dbus-fast/commit/a9e8866c2a6a97227ff5f001cae5e2196260379c))
## v1.1.9 (2022-09-09)
### Bug Fixes
- Readme ([#13](https://github.com/Bluetooth-Devices/dbus-fast/pull/13),
[`6bc87e0`](https://github.com/Bluetooth-Devices/dbus-fast/commit/6bc87e0f0717d4a4382e4bb36d064e22ff131751))
## v1.1.8 (2022-09-09)
### Bug Fixes
- Ensure the underlying socket is closed on disconnect
([#12](https://github.com/Bluetooth-Devices/dbus-fast/pull/12),
[`6770a65`](https://github.com/Bluetooth-Devices/dbus-fast/commit/6770a656bdddf6e090ebb6858bd046e4365ea32e))
## v1.1.7 (2022-09-09)
### Bug Fixes
- Copyrights in docs ([#10](https://github.com/Bluetooth-Devices/dbus-fast/pull/10),
[`a97701e`](https://github.com/Bluetooth-Devices/dbus-fast/commit/a97701ec12e4049884af33abbde2b208c4e351d4))
## v1.1.6 (2022-09-09)
### Bug Fixes
- Docs deps not needed for production ([#9](https://github.com/Bluetooth-Devices/dbus-fast/pull/9),
[`01f8ce7`](https://github.com/Bluetooth-Devices/dbus-fast/commit/01f8ce77b945554f27723755caab550b6f246cb4))
## v1.1.5 (2022-09-09)
### Bug Fixes
- Readme ([#8](https://github.com/Bluetooth-Devices/dbus-fast/pull/8),
[`7396b5f`](https://github.com/Bluetooth-Devices/dbus-fast/commit/7396b5f475e4b9299cf96930153a01425bb5bd3b))
## v1.1.4 (2022-09-09)
### Bug Fixes
- More rename ([#7](https://github.com/Bluetooth-Devices/dbus-fast/pull/7),
[`116d5c6`](https://github.com/Bluetooth-Devices/dbus-fast/commit/116d5c6feb863deff95f811d79199b09c79552f9))
## v1.1.3 (2022-09-09)
### Bug Fixes
- Docs ([#6](https://github.com/Bluetooth-Devices/dbus-fast/pull/6),
[`ee473c0`](https://github.com/Bluetooth-Devices/dbus-fast/commit/ee473c05c5ff1ecc91f0c0167987e970eebf4c75))
## v1.1.2 (2022-09-09)
### Bug Fixes
- Docs ([#4](https://github.com/Bluetooth-Devices/dbus-fast/pull/4),
[`ba8e5f1`](https://github.com/Bluetooth-Devices/dbus-fast/commit/ba8e5f127f2a4e20254a8d652165c348d0b9884f))
- Readme ([#5](https://github.com/Bluetooth-Devices/dbus-fast/pull/5),
[`f628e87`](https://github.com/Bluetooth-Devices/dbus-fast/commit/f628e87a1b859966dac03143a7a14422ef0d79a1))
## v1.1.1 (2022-09-09)
### Bug Fixes
- Docs lang ([#3](https://github.com/Bluetooth-Devices/dbus-fast/pull/3),
[`538db98`](https://github.com/Bluetooth-Devices/dbus-fast/commit/538db98a3b7246e5d3ace256ac3b86c3dae5b63e))
## v1.1.0 (2022-09-09)
### Chores
- Build fixes
([`4927a1e`](https://github.com/Bluetooth-Devices/dbus-fast/commit/4927a1e79908dfc91b804475c80a59f13ded5c04))
- Ci fixes
([`fad09d6`](https://github.com/Bluetooth-Devices/dbus-fast/commit/fad09d60a8aea05efe1cf584da6c1b858227f272))
- Disable some linters
([`0ab9fab`](https://github.com/Bluetooth-Devices/dbus-fast/commit/0ab9fabe2fddec729dcac1bee1b2f671f6c3b539))
- Fix ci
([`d187573`](https://github.com/Bluetooth-Devices/dbus-fast/commit/d18757378bb55112a0f39c4c6a8b86c29b60574e))
- Fix ci
([`988ff05`](https://github.com/Bluetooth-Devices/dbus-fast/commit/988ff0599454ac65e192bbbef6f61534c14bf346))
- Fix ci
([`6e10c51`](https://github.com/Bluetooth-Devices/dbus-fast/commit/6e10c51d88b46e80fc9b10b082b5888167f9670b))
- Fix ci
([`2a2d486`](https://github.com/Bluetooth-Devices/dbus-fast/commit/2a2d486494bde0001891f71821f588c8a25d9c4c))
- Fix ci
([`61e00c1`](https://github.com/Bluetooth-Devices/dbus-fast/commit/61e00c1c0782288d1a12cefe784c4b860fd260d8))
- Initial commit
([`169581f`](https://github.com/Bluetooth-Devices/dbus-fast/commit/169581f69121ef66a326fd100656756aee1baed9))
- Initial port
([`495bfac`](https://github.com/Bluetooth-Devices/dbus-fast/commit/495bfac17fd7e56d292ddfde42e7e6570e04ab01))
- Rename
([`60308e0`](https://github.com/Bluetooth-Devices/dbus-fast/commit/60308e0b0cb14e7a26631f632123db16e4cb09c0))
- Rename
([`36b08af`](https://github.com/Bluetooth-Devices/dbus-fast/commit/36b08afbff9ead520ec237f7259354185e513a0d))
- Rename
([`7e9609b`](https://github.com/Bluetooth-Devices/dbus-fast/commit/7e9609b0f5f95ba9e146bd73242de4e2fe5ad124))
### Features
- Speed up unmarshaller ([#1](https://github.com/Bluetooth-Devices/dbus-fast/pull/1),
[`eca1d31`](https://github.com/Bluetooth-Devices/dbus-fast/commit/eca1d317818d2b938ec3ed3172b1be76a44a93a4))
dbus-fast-2.44.1/CONTRIBUTING.md 0000664 0000000 0000000 00000007422 14773556132 0015745 0 ustar 00root root 0000000 0000000 # Contributing
Contributions are welcome, and they are greatly appreciated! Every little helps, and credit will always be given.
You can contribute in many ways:
## Types of Contributions
### Report Bugs
Report bugs to [our issue page][gh-issues]. If you are reporting a bug, please include:
- Your operating system name and version.
- Any details about your local setup that might be helpful in troubleshooting.
- Detailed steps to reproduce the bug.
### Fix Bugs
Look through the GitHub issues for bugs. Anything tagged with "bug" and "help wanted" is open to whoever wants to implement it.
### Implement Features
Look through the GitHub issues for features. Anything tagged with "enhancement" and "help wanted" is open to whoever wants to implement it.
### Write Documentation
dbus-fast could always use more documentation, whether as part of the official dbus-fast docs, in docstrings, or even on the web in blog posts, articles, and such.
### Submit Feedback
The best way to send feedback [our issue page][gh-issues] on GitHub. If you are proposing a feature:
- Explain in detail how it would work.
- Keep the scope as narrow as possible, to make it easier to implement.
- Remember that this is a volunteer-driven project, and that contributions are welcome 😊
## Get Started!
Ready to contribute? Here's how to set yourself up for local development.
1. Fork the repo on GitHub.
2. Clone your fork locally:
```shell
$ git clone git@github.com:your_name_here/dbus-fast.git
```
3. Install the project dependencies with [Poetry](https://python-poetry.org):
```shell
$ poetry install
```
4. Create a branch for local development:
```shell
$ git checkout -b name-of-your-bugfix-or-feature
```
Now you can make your changes locally.
5. When you're done making changes, check that your changes pass our tests:
```shell
$ poetry run pytest
```
6. Linting is done through [pre-commit](https://pre-commit.com). Provided you have the tool installed globally, you can run them all as one-off:
```shell
$ pre-commit run -a
```
Or better, install the hooks once and have them run automatically each time you commit:
```shell
$ pre-commit install
```
7. Commit your changes and push your branch to GitHub:
```shell
$ git add .
$ git commit -m "feat(something): your detailed description of your changes"
$ git push origin name-of-your-bugfix-or-feature
```
Note: the commit message should follow [the conventional commits](https://www.conventionalcommits.org). We run [`commitlint` on CI](https://github.com/marketplace/actions/commit-linter) to validate it, and if you've installed pre-commit hooks at the previous step, the message will be checked at commit time.
8. Submit a pull request through the GitHub website or using the GitHub CLI (if you have it installed):
```shell
$ gh pr create --fill
```
## Pull Request Guidelines
We like to have the pull request open as soon as possible, that's a great place to discuss any piece of work, even unfinished. You can use draft pull request if it's still a work in progress. Here are a few guidelines to follow:
1. Include tests for feature or bug fixes.
2. Update the documentation for significant features.
3. Ensure tests are passing on CI.
## Tips
To run a subset of tests:
```shell
$ pytest tests
```
## Making a new release
The deployment should be automated and can be triggered from the Semantic Release workflow in GitHub. The next version will be based on [the commit logs](https://python-semantic-release.readthedocs.io/en/latest/commit-log-parsing.html#commit-log-parsing). This is done by [python-semantic-release](https://python-semantic-release.readthedocs.io/en/latest/index.html) via a GitHub action.
[gh-issues]: https://github.com/bluetooth-devices/dbus-fast/issues
dbus-fast-2.44.1/LICENSE 0000664 0000000 0000000 00000002073 14773556132 0014516 0 ustar 00root root 0000000 0000000
MIT License
Copyright (c) 2022 Bluetooth Devices Authors
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
dbus-fast-2.44.1/README.md 0000664 0000000 0000000 00000022561 14773556132 0014774 0 ustar 00root root 0000000 0000000 # dbus-fast
A faster version of dbus-next originally from the [great DBus next library](https://github.com/altdesktop/python-dbus-next) ❤️
## Installation
Install this via pip (or your favourite package manager):
`pip install dbus-fast`
[Documentation](https://dbus-fast.readthedocs.io/en/latest/)
dbus-fast is a Python library for DBus that aims to be a performant fully featured high level library primarily geared towards integration of applications into Linux desktop and mobile environments.
Desktop application developers can use this library for integrating their applications into desktop environments by implementing common DBus standard interfaces or creating custom plugin interfaces.
Desktop users can use this library to create their own scripts and utilities to interact with those interfaces for customization of their desktop environment.
dbus-fast plans to improve over other DBus libraries for Python in the following ways:
- Zero dependencies and pure Python 3
- An optional cython extension is available to speed up (un)marshalling
- Focus on performance
- Support for multiple IO backends including asyncio and the GLib main loop.
- Nonblocking IO suitable for GUI development.
- Target the latest language features of Python for beautiful services and clients.
- Complete implementation of the DBus type system without ever guessing types.
- Integration tests for all features of the library.
- Completely documented public API.
## Installing
This library is available on PyPi as [dbus-fast](https://pypi.org/project/dbus-fast/).
```
pip3 install dbus-fast
```
## The Client Interface
To use a service on the bus, the library constructs a proxy object you can use to call methods, get and set properties, and listen to signals.
For more information, see the [overview for the high-level client](https://dbus-fast.readthedocs.io/en/latest/high-level-client/index.html).
This example connects to a media player and controls it with the [MPRIS](https://specifications.freedesktop.org/mpris-spec/latest/) DBus interface.
```python
from dbus_fast.aio import MessageBus
import asyncio
async def main():
bus = await MessageBus().connect()
# the introspection xml would normally be included in your project, but
# this is convenient for development
introspection = await bus.introspect('org.mpris.MediaPlayer2.vlc', '/org/mpris/MediaPlayer2')
obj = bus.get_proxy_object('org.mpris.MediaPlayer2.vlc', '/org/mpris/MediaPlayer2', introspection)
player = obj.get_interface('org.mpris.MediaPlayer2.Player')
properties = obj.get_interface('org.freedesktop.DBus.Properties')
# call methods on the interface (this causes the media player to play)
await player.call_play()
volume = await player.get_volume()
print(f'current volume: {volume}, setting to 0.5')
await player.set_volume(0.5)
# listen to signals
def on_properties_changed(interface_name, changed_properties, invalidated_properties):
for changed, variant in changed_properties.items():
print(f'property changed: {changed} - {variant.value}')
properties.on_properties_changed(on_properties_changed)
await asyncio.Event().wait()
asyncio.run(main())
```
## The Service Interface
To define a service on the bus, use the `ServiceInterface` class and decorate class methods to specify DBus methods, properties, and signals with their type signatures.
For more information, see the [overview for the high-level service](https://dbus-fast.readthedocs.io/en/latest/high-level-service/index.html).
```python
from dbus_fast.service import ServiceInterface, method, dbus_property, signal, Variant
from dbus_fast.aio MessageBus
import asyncio
class ExampleInterface(ServiceInterface):
def __init__(self, name):
super().__init__(name)
self._string_prop = 'kevin'
@method()
def Echo(self, what: 's') -> 's':
return what
@method()
def GetVariantDict() -> 'a{sv}':
return {
'foo': Variant('s', 'bar'),
'bat': Variant('x', -55),
'a_list': Variant('as', ['hello', 'world'])
}
@dbus_property()
def string_prop(self) -> 's':
return self._string_prop
@string_prop.setter
def string_prop_setter(self, val: 's'):
self._string_prop = val
@signal()
def signal_simple(self) -> 's':
return 'hello'
async def main():
bus = await MessageBus().connect()
interface = ExampleInterface('test.interface')
bus.export('/test/path', interface)
# now that we are ready to handle requests, we can request name from D-Bus
await bus.request_name('test.name')
# wait indefinitely
await asyncio.Event().wait()
asyncio.run(main())
```
## The Low-Level Interface
The low-level interface works with DBus messages directly.
For more information, see the [overview for the low-level interface](https://dbus-fast.readthedocs.io/en/latest/low-level-interface/index.html).
```python
from dbus_fast.message import Message, MessageType
from dbus_fast.aio import MessageBus
import asyncio
import json
async def main():
bus = await MessageBus().connect()
reply = await bus.call(
Message(destination='org.freedesktop.DBus',
path='/org/freedesktop/DBus',
interface='org.freedesktop.DBus',
member='ListNames'))
if reply.message_type == MessageType.ERROR:
raise Exception(reply.body[0])
print(json.dumps(reply.body[0], indent=2))
asyncio.run(main())
```
## Projects that use dbus-fast
- [Bluetooth Adapters](https://github.com/bluetooth-devices/bluetooth-adapters)
## Contributing
Contributions are welcome. Development happens on [Github](https://github.com/Bluetooth-Devices/dbus-fast).
Before you commit, run `pre-commit run --all-files` to run the linter, code formatter, and the test suite.
## Copyright
You can use this code under an MIT license (see LICENSE).
- © 2019, Tony Crisci
- © 2022, Bluetooth Devices authors
## Contributors ✨
Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/docs/en/emoji-key)):
This project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind welcome!
## Credits
This package was created with
[Cookiecutter](https://github.com/audreyr/cookiecutter) and the
[browniebroke/cookiecutter-pypackage](https://github.com/browniebroke/cookiecutter-pypackage)
project template.
dbus-fast-2.44.1/bench/ 0000775 0000000 0000000 00000000000 14773556132 0014566 5 ustar 00root root 0000000 0000000 dbus-fast-2.44.1/bench/marshall.py 0000664 0000000 0000000 00000000710 14773556132 0016741 0 ustar 00root root 0000000 0000000 import timeit
from dbus_fast import Message
message = Message(
destination="org.bluez",
path="/",
interface="org.freedesktop.DBus.ObjectManager",
member="GetManagedObjects",
)
def marhsall_bluez_get_managed_objects_message():
message._marshall(False)
count = 1000000
time = timeit.Timer(marhsall_bluez_get_managed_objects_message).timeit(count)
print(f"Marshalling {count} bluez get managed objects messages took {time} seconds")
dbus-fast-2.44.1/bench/unmarshall.py 0000664 0000000 0000000 00000001764 14773556132 0017316 0 ustar 00root root 0000000 0000000 import io
import timeit
from dbus_fast._private.unmarshaller import Unmarshaller
# cythonize -X language_level=3 -a -i src/dbus_fast/_private/unmarshaller.py
bluez_rssi_message = (
"6c04010134000000e25389019500000001016f00250000002f6f72672f626c75657a2f686369302f6465"
"765f30385f33415f46325f31455f32425f3631000000020173001f0000006f72672e667265656465736b"
"746f702e444275732e50726f7065727469657300030173001100000050726f706572746965734368616e"
"67656400000000000000080167000873617b73767d617300000007017300040000003a312e3400000000"
"110000006f72672e626c75657a2e446576696365310000000e0000000000000004000000525353490001"
"6e00a7ff000000000000"
)
stream = io.BytesIO(bytes.fromhex(bluez_rssi_message))
unmarshaller = Unmarshaller(stream)
def unmarhsall_bluez_rssi_message():
stream.seek(0)
unmarshaller.unmarshall()
count = 3000000
time = timeit.Timer(unmarhsall_bluez_rssi_message).timeit(count)
print(f"Unmarshalling {count} bluetooth rssi messages took {time} seconds")
dbus-fast-2.44.1/bench/unmarshall_2.py 0000664 0000000 0000000 00000007321 14773556132 0017532 0 ustar 00root root 0000000 0000000 import io
import timeit
from dbus_fast._private.unmarshaller import Unmarshaller
bluez_properties_message = (
b"l\4\1\0014\0\0\0\16Q\16\0\225\0\0\0\1\1o\0%\0\0\0/org/bluez/hci2/dev_08_3A_F2_1E_28_89\0\0\0\2\1s\0\37\0\0\0"
b"org.freedesktop.DBus.Properties\0\3\1s\0\21\0\0\0PropertiesChanged\0\0\0\0\0\0\0\10\1g\0\10sa{sv}as\0\0\0\7\1"
b"s\0\4\0\0\0:1.5\0\0\0\0\21\0\0\0org.bluez.Device1\0\0\0\16\0\0\0\0\0\0\0\4\0\0\0RSSI\0\1n\0\242\377\0\0\0\0\0\0"
b"l\4\1\1\220\0\0\0\17Q\16\0\225\0\0\0\1\1o\0%\0\0\0/org/bluez/hci2/dev_A4_C1_38_6E_9F_7C\0\0\0\2\1s\0\37\0\0\0"
b"org.freedesktop.DBus.Properties\0\3\1s\0\21\0\0\0PropertiesChanged\0\0\0\0\0\0\0\10\1g\0\10sa{sv}as\0\0\0\7\1s"
b"\0\4\0\0\0:1.5\0\0\0\0\21\0\0\0org.bluez.Device1\0\0\0k\0\0\0\0\0\0\0\4\0\0\0RSSI\0\1n\0\250\377\0\0\20\0\0\0"
b"ManufacturerData\0\5a{qv}\0;\0\0\0\1\0\2ay\0\0\0\t\0\0\0\1\1\1\3\361\234\\\0\1\0\0\0L\0\2ay\0\0\0\27\0\0\0\2\25"
b"INTELLI_ROCKS_HWPu\362\377\302\0\0\0\0\0l\4\1\0014\0\0\0\20Q\16\0\225\0\0\0\1\1o\0%\0\0\0/org/bluez/hci2/dev_F8"
b"_04_2E_E1_9F_19\0\0\0\2\1s\0\37\0\0\0org.freedesktop.DBus.Properties\0\3\1s\0\21\0\0\0PropertiesChanged\0\0\0\0"
b"\0\0\0\10\1g\0\10sa{sv}as\0\0\0\7\1s\0\4\0\0\0:1.5\0\0\0\0\21\0\0\0org.bluez.Device1\0\0\0\16\0\0\0\0\0\0\0\4\0"
b"\0\0RSSI\0\1n\0\262\377\0\0\0\0\0\0l\4\1\0014\0\0\0\21Q\16\0\225\0\0\0\1\1o\0%\0\0\0/org/bluez/hci3/dev_54_E6_"
b"1B_F0_20_97\0\0\0\2\1s\0\37\0\0\0org.freedesktop.DBus.Properties\0\3\1s\0\21\0\0\0PropertiesChanged\0\0\0\0\0\0"
b"\0\10\1g\0\10sa{sv}as\0\0\0\7\1s\0\4\0\0\0:1.5\0\0\0\0\21\0\0\0org.bluez.Device1\0\0\0\16\0\0\0\0\0\0\0\4\0\0\0"
b"RSSI\0\1n\0\254\377\0\0\0\0\0\0l\4\1\0014\0\0\0\22Q\16\0\225\0\0\0\1\1o\0%\0\0\0/org/bluez/hci3/dev_D8_EF_2F_41"
b"_B1_34\0\0\0\2\1s\0\37\0\0\0org.freedesktop.DBus.Properties\0\3\1s\0\21\0\0\0PropertiesChanged\0\0\0\0\0\0\0\10"
b"\1g\0\10sa{sv}as\0\0\0\7\1s\0\4\0\0\0:1.5\0\0\0\0\21\0\0\0org.bluez.Device1\0\0\0\16\0\0\0\0\0\0\0\4\0\0\0RSSI\0"
b"\1n\0\244\377\0\0\0\0\0\0l\4\1\0014\0\0\0\23Q\16\0\225\0\0\0\1\1o\0%\0\0\0/org/bluez/hci3/dev_34_AB_95_85_66_6D\0"
b"\0\0\2\1s\0\37\0\0\0org.freedesktop.DBus.Properties\0\3\1s\0\21\0\0\0PropertiesChanged\0\0\0\0\0\0\0\10\1g\0\10"
b"sa{sv}as\0\0\0\7\1s\0\4\0\0\0:1.5\0\0\0\0\21\0\0\0org.bluez.Device1\0\0\0\16\0\0\0\0\0\0\0\4\0\0\0RSSI\0\1n\0\236"
b"\377\0\0\0\0\0\0l\4\1\0014\0\0\0\24Q\16\0\225\0\0\0\1\1o\0%\0\0\0/org/bluez/hci3/dev_08_3A_F2_1E_32_69\0\0\0\2\1s"
b"\0\37\0\0\0org.freedesktop.DBus.Properties\0\3\1s\0\21\0\0\0PropertiesChanged\0\0\0\0\0\0\0\10\1g\0\10sa{sv}as\0"
b"\0\0\7\1s\0\4\0\0\0:1.5\0\0\0\0\21\0\0\0org.bluez.Device1\0\0\0\16\0\0\0\0\0\0\0\4\0\0\0RSSI\0\1n\0\246\377\0\0\0"
b"\0\0\0l\4\1\0014\0\0\0\25Q\16\0\225\0\0\0\1\1o\0%\0\0\0/org/bluez/hci3/dev_34_AB_95_85_71_D1\0\0\0\2\1s\0\37\0\0\0"
b"org.freedesktop.DBus.Properties\0\3\1s\0\21\0\0\0PropertiesChanged\0\0\0\0\0\0\0\10\1g\0\10sa{sv}as\0\0\0\7\1s\0\4"
b"\0\0\0:1.5\0\0\0\0\21\0\0\0org.bluez.Device1\0\0\0\16\0\0\0\0\0\0\0\4\0\0\0RSSI\0\1n\0\232\377\0\0\0\0\0\0l\4\1\001"
b"4\0\0\0\26Q\16\0\225\0\0\0\1\1o\0%\0\0\0/org/bluez/hci3/dev_F8_04_2E_E1_9F_19\0\0\0\2\1s\0\37\0\0\0org.freedesktop.D"
b"Bus.Properties\0\3\1s\0\21\0\0\0PropertiesChanged\0\0\0\0\0\0\0\10\1g\0\10sa{sv}as\0\0\0\7\1s\0\4\0\0\0:1.5\0\0\0\0"
b"\21\0\0\0org.bluez.Device1\0\0\0\16\0\0\0\0\0\0\0\4\0\0\0RSSI\0\1n\0\306\377\0\0\0\0\0\0"
)
stream = io.BytesIO(bluez_properties_message)
unmarshaller = Unmarshaller(stream)
def unmarhsall_bluez_rssi_message():
stream.seek(0)
unmarshaller.unmarshall()
count = 3000000
time = timeit.Timer(unmarhsall_bluez_rssi_message).timeit(count)
print(
f"Unmarshalling {count} bluetooth properties changed messages took {time} seconds"
)
dbus-fast-2.44.1/bench/unmarshall_getmanagedobjects.py 0000664 0000000 0000000 00000001135 14773556132 0023034 0 ustar 00root root 0000000 0000000 import io
import timeit
from dbus_fast._private.unmarshaller import Unmarshaller
# cythonize -X language_level=3 -a -i src/dbus_fast/_private/unmarshaller.py
with open("tests/data/get_managed_objects.hex") as fp:
msg = fp.read()
stream = io.BytesIO(bytes.fromhex(msg))
unmarshaller = Unmarshaller(stream)
def unmarhsall_bluez_get_managed_objects_message():
stream.seek(0)
unmarshaller.unmarshall()
count = 10000
time = timeit.Timer(unmarhsall_bluez_get_managed_objects_message).timeit(count)
print(f"Unmarshalling {count} bluetooth GetManagedObjects messages took {time} seconds")
dbus-fast-2.44.1/bench/unmarshall_interfaces_added.py 0000664 0000000 0000000 00000003510 14773556132 0022631 0 ustar 00root root 0000000 0000000 import io
import timeit
from dbus_fast._private.unmarshaller import Unmarshaller
# cythonize -X language_level=3 -a -i src/dbus_fast/_private/unmarshaller.py
bluez_interfaces_added_message = (
b'l\4\1\1\240\2\0\0\227\272\23\0u\0\0\0\1\1o\0\1\0\0\0/\0\0\0\0\0\0\0\2\1s\0"\0\0\0'
b"org.freedesktop.DBus.ObjectManager\0\0\0\0\0\0\3\1s\0\17\0\0\0InterfacesAdded\0\10"
b"\1g\0\noa{sa{sv}}\0\7\1s\0\4\0\0\0:1.4\0\0\0\0%\0\0\0/org/bluez/hci1/dev_58_2D_34"
b"_60_26_36\0\0\0p\2\0\0#\0\0\0org.freedesktop.DBus.Introspectable\0\0\0\0\0\0\0\0\0"
b"\21\0\0\0org.bluez.Device1\0\0\0\364\1\0\0\0\0\0\0\7\0\0\0Address\0\1s\0\0\21\0\0"
b"\00058:2D:34:60:26:36\0\0\0\v\0\0\0AddressType\0\1s\0\0\6\0\0\0public\0\0\4\0\0\0"
b"Name\0\1s\0\33\0\0\0Qingping Door/Window Sensor\0\0\0\0\0\5\0\0\0Alias\0\1s\0\0\0"
b"\0\33\0\0\0Qingping Door/Window Sensor\0\6\0\0\0Paired\0\1b\0\0\0\0\0\0\0\0\0\0\0"
b"\7\0\0\0Trusted\0\1b\0\0\0\0\0\0\0\0\0\0\7\0\0\0Blocked\0\1b\0\0\0\0\0\0\0\0\0\0\r"
b"\0\0\0LegacyPairing\0\1b\0\0\0\0\0\0\0\0\0\0\0\0\4\0\0\0RSSI\0\1n\0\316\377\0\0\t"
b"\0\0\0Connected\0\1b\0\0\0\0\0\0\0\0\5\0\0\0UUIDs\0\2as\0\0\0\0\0\0\0\0\0\0\0\7\0"
b"\0\0Adapter\0\1o\0\0\17\0\0\0/org/bluez/hci1\0\0\0\0\0\v\0\0\0ServiceData\0\5a{sv}"
b"\0\0@\0\0\0\0\0\0\0$\0\0\0000000fe95-0000-1000-8000-00805f9b34fb\0\2ay\0\0\0\0\f\0"
b"\0\0000X\326\3\0026&`4-X\10\20\0\0\0ServicesResolved\0\1b\0\0\0\0\0\0\0\0\0\37\0\0"
b"\0org.freedesktop.DBus.Properties\0\0\0\0\0"
)
stream = io.BytesIO(bluez_interfaces_added_message)
unmarshaller = Unmarshaller(stream)
def unmarshall_interfaces_added_message():
stream.seek(0)
unmarshaller.unmarshall()
count = 3000000
time = timeit.Timer(unmarshall_interfaces_added_message).timeit(count)
print(f"Unmarshalling {count} bluetooth InterfacesAdded messages took {time} seconds")
dbus-fast-2.44.1/bench/unmarshall_interfaces_removed.py 0000664 0000000 0000000 00000001766 14773556132 0023244 0 ustar 00root root 0000000 0000000 import io
import timeit
from dbus_fast._private.unmarshaller import Unmarshaller
# cythonize -X language_level=3 -a -i src/dbus_fast/_private/unmarshaller.py
bluez_interfaces_removed_message = (
b'l\4\1\1\222\0\0\0\377@-\0~\0\0\0\1\1o\0\1\0\0\0/\0\0\0\0\0\0\0\2\1s\0"\0\0\0'
b"org.freedesktop.DBus.ObjectManager\0\0\0\0\0\0\3\1s\0\21\0\0\0InterfacesRemoved"
b"\0\0\0\0\0\0\0\10\1g\0\3oas\0\0\0\0\0\0\0\0\7\1s\0\5\0\0\0:1.12\0\0\0%\0\0\0"
b"/org/bluez/hci0/dev_5F_13_47_38_26_55\0\0\0b\0\0\0\37\0\0\0org.freedesktop.DBus"
b".Properties\0#\0\0\0org.freedesktop.DBus.Introspectable\0\21\0\0\0org.bluez.Dev"
b"ice1\0"
)
stream = io.BytesIO(bluez_interfaces_removed_message)
unmarshaller = Unmarshaller(stream)
def unmarshall_interfaces_removed_message():
stream.seek(0)
unmarshaller.unmarshall()
count = 3000000
time = timeit.Timer(unmarshall_interfaces_removed_message).timeit(count)
print(f"Unmarshalling {count} bluetooth InterfacesRemoved messages took {time} seconds")
dbus-fast-2.44.1/bench/unmarshall_manufacturerdata.py 0000664 0000000 0000000 00000002052 14773556132 0022713 0 ustar 00root root 0000000 0000000 import io
import timeit
from dbus_fast._private.unmarshaller import Unmarshaller
# cythonize -X language_level=3 -a -i src/dbus_fast/_private/unmarshaller.py
bluez_mfr_data_message = (
b"l\4\1\1x\0\0\0\232\312\n\0\225\0\0\0\1\1o\0%\0\0\0/org/bluez/hci0/dev_D0_C2_4E_08_AB_57\0\0\0\2\1s"
b"\0\37\0\0\0org.freedesktop.DBus.Properties\0\3\1s\0\21\0\0\0PropertiesChanged\0\0\0\0\0\0\0\10\1g\0"
b"\10sa{sv}as\0\0\0\7\1s\0\4\0\0\0:1.4\0\0\0\0\21\0\0\0org.bluez.Device1\0\0\0T\0\0\0\0\0\0\0\4\0\0\0"
b"RSSI\0\1n\0\252\377\0\0\20\0\0\0ManufacturerData\0\5a{qv}\0$\0\0\0u\0\2ay\0\0\0\30\0\0\0B\4\1\1p\320"
b"\302N\10\253W\322\302N\10\253V\1\0\0\0\0\0\0\0\0\0\0l\4\1\0014\0\0\0\233\312\n\0\225\0\0\0\1\1o\0%\0"
)
stream = io.BytesIO(bluez_mfr_data_message)
unmarshaller = Unmarshaller(stream)
def unmarshall_mfr_data_message():
stream.seek(0)
unmarshaller.unmarshall()
count = 3000000
time = timeit.Timer(unmarshall_mfr_data_message).timeit(count)
print(f"Unmarshalling {count} bluetooth ManufacturerData messages took {time} seconds")
dbus-fast-2.44.1/bench/unmarshall_passive.py 0000664 0000000 0000000 00000002077 14773556132 0021046 0 ustar 00root root 0000000 0000000 import io
import timeit
from dbus_fast._private.unmarshaller import Unmarshaller
bluez_passive_message = (
b"l\1\1\1*\0\0\0\205D\267\3\215\0\0\0\1\1o\0\35\0\0\0/org/bleak/61/281472597302272\0\0\0\6\1s\0\7\0\0"
b"\0:1.1450\0\2\1s\0\37\0\0\0org.bluez.AdvertisementMonitor1\0\3\1s\0\v\0\0\0DeviceFound\0\0\0\0\0\10"
b"\1g\0\1o\0\0\7\1s\0\4\0\0\0:1.4\0\0\0\0%\0\0\0/org/bluez/hci0/dev_58_D3_49_E6_02_6E\0l\1\1\1*\0\0\0"
b"\206D\267\3\215\0\0\0\1\1o\0\35\0\0\0/org/bleak/61/281472593362560\0\0\0\6\1s\0\7\0\0\0:1.1450\0\2"
b"\1s\0\37\0\0\0org.bluez.AdvertisementMonitor1\0\3\1s\0\v\0\0\0DeviceFound\0\0\0\0\0\10\1g\0\1o\0\0"
b"\7\1s\0\4\0\0\0:1.4\0\0\0\0%\0\0\0/org/bluez/hci1/dev_58_D3_49_E6_02_6E\0"
)
stream = io.BytesIO(bluez_passive_message)
unmarshaller = Unmarshaller(stream)
def unmarhsall_bluez_rssi_message():
stream.seek(0)
unmarshaller.unmarshall()
unmarshaller.unmarshall()
count = 3000000
time = timeit.Timer(unmarhsall_bluez_rssi_message).timeit(count)
print(f"Unmarshalling {count} bluetooth passive messages took {time} seconds")
dbus-fast-2.44.1/bench/unmarshall_servicedata.py 0000664 0000000 0000000 00000002271 14773556132 0021662 0 ustar 00root root 0000000 0000000 import io
import timeit
from dbus_fast._private.unmarshaller import Unmarshaller
# cythonize -X language_level=3 -a -i src/dbus_fast/_private/unmarshaller.py
bluez_properties_changed_message = (
b"l\4\1\1\334\0\0\0@\236.\0\226\0\0\0\1\1o\0%\0\0\0/org/bluez/hci0/dev_58_2D_34_60_DA_1F"
b"\0\0\0\2\1s\0\37\0\0\0org.freedesktop.DBus.Properties\0\3\1s\0\21\0\0\0PropertiesChanged"
b"\0\0\0\0\0\0\0\10\1g\0\10sa{sv}as\0\0\0\7\1s\0\5\0\0\0:1.12\0\0\0\21\0\0\0org.bluez.Devi"
b"ce1\0\0\0\270\0\0\0\0\0\0\0\4\0\0\0RSSI\0\1n\0\301\377\0\0\v\0\0\0ServiceData\0\5a{sv}"
b"\0\0\210\0\0\0\0\0\0\0$\0\0\0000000fdcd-0000-1000-8000-00805f9b34fb\0\2ay\0\0\0\0\24\0"
b"\0\0\10\22\37\332`4-X\2\1U\17\1\315\t\4\5\0\0\0$\0\0\0000000fe95-0000-1000-8000-00805f"
b"9b34fb\0\2ay\0\0\0\0\f\0\0\0000X\203\n\2\37\332`4-X\10\0\0\0\0"
)
stream = io.BytesIO(bluez_properties_changed_message)
unmarshaller = Unmarshaller(stream)
def unmarshall_properties_changed_message():
stream.seek(0)
unmarshaller.unmarshall()
count = 3000000
time = timeit.Timer(unmarshall_properties_changed_message).timeit(count)
print(f"Unmarshalling {count} bluetooth PropertiesChanged messages took {time} seconds")
dbus-fast-2.44.1/bench/unmarshall_write_value.py 0000664 0000000 0000000 00000001467 14773556132 0021724 0 ustar 00root root 0000000 0000000 import io
import timeit
from dbus_fast._private.unmarshaller import Unmarshaller
bluez_passive_message = (
b"l\1\0\1(\0\0\0F\1\0\0\255\0\0\0\1\1o\0:\0\0\0/org/bluez/hci0/dev_BD_24_6F_"
b"85_AA_61/service001a/char001b\0\0\0\0\0\0\2\1s\0\35\0\0\0org.bluez.GattCha"
b"racteristic1\0\0\0\3\1s\0\n\0\0\0WriteValue\0\0\0\0\0\0\6\1s\0\t\0\0\0org."
b"bluez\0\0\0\0\0\0\0\10\1g\0\7aya{sv}\0\0\0\0\3\0\0\0\357\1w\0\30\0\0\0\0\0"
b"\0\0\4\0\0\0type\0\1s\0\7\0\0\0command\0"
)
stream = io.BytesIO(bluez_passive_message)
unmarshaller = Unmarshaller(stream)
def unmarhsall_bluez_rssi_message():
stream.seek(0)
unmarshaller.unmarshall()
count = 3000000
time = timeit.Timer(unmarhsall_bluez_rssi_message).timeit(count)
print(f"Unmarshalling {count} bluetooth write value messages took {time} seconds")
dbus-fast-2.44.1/bench/unpack_variants.py 0000664 0000000 0000000 00000004465 14773556132 0020341 0 ustar 00root root 0000000 0000000 import timeit
from dbus_fast import Variant, unpack_variants
# cythonize -X language_level=3 -a -i src/dbus_fast/unpack.py
message = {
"/org/bluez/hci0": {
"org.bluez.Adapter1": {
"Address": Variant("s", "00:E0:4C:2A:25:63"),
"AddressType": Variant("s", "public"),
"Alias": Variant("s", "BlueZ 5.63"),
"Class": Variant("u", 2883584),
"Discoverable": Variant("b", False),
"DiscoverableTimeout": Variant("u", 180),
"Discovering": Variant("b", True),
"Modalias": Variant("s", "usb:v1D6Bp0246d053F"),
"Name": Variant("s", "BlueZ 5.63"),
"Pairable": Variant("b", False),
"PairableTimeout": Variant("u", 0),
"Powered": Variant("b", True),
"Roles": Variant("as", ["central", "peripheral"]),
"UUIDs": Variant(
"as",
[
"0000110e-0000-1000-8000-00805f9b34fb",
"0000110a-0000-1000-8000-00805f9b34fb",
"00001200-0000-1000-8000-00805f9b34fb",
"0000110b-0000-1000-8000-00805f9b34fb",
"00001108-0000-1000-8000-00805f9b34fb",
"0000110c-0000-1000-8000-00805f9b34fb",
"00001800-0000-1000-8000-00805f9b34fb",
"00001801-0000-1000-8000-00805f9b34fb",
"0000180a-0000-1000-8000-00805f9b34fb",
"00001112-0000-1000-8000-00805f9b34fb",
],
),
},
"org.bluez.GattManager1": {},
"org.bluez.LEAdvertisingManager1": {
"ActiveInstances": Variant("y", 0),
"SupportedIncludes": Variant(
"as", ["tx-power", "appearance", "local-name"]
),
"SupportedInstances": Variant("y", 4),
"SupportedSecondaryChannels": Variant("as", ["1M", "2M", "Coded"]),
},
"org.bluez.Media1": {},
"org.bluez.NetworkServer1": {},
"org.freedesktop.DBus.Introspectable": {},
"org.freedesktop.DBus.Properties": {},
},
}
def unpack_managed_objects():
unpack_variants(message)
count = 3000000
time = timeit.Timer(unpack_managed_objects).timeit(count)
print(f"Unpacked {count} get managed objects messages took {time} seconds")
dbus-fast-2.44.1/build_ext.py 0000664 0000000 0000000 00000003211 14773556132 0016035 0 ustar 00root root 0000000 0000000 """Build optional cython modules."""
import logging
import os
from distutils.command.build_ext import build_ext
_LOGGER = logging.getLogger(__name__)
try:
from setuptools import Extension
except ImportError:
from distutils.core import Extension
TO_CYTHONIZE = [
"src/dbus_fast/aio/message_reader.py",
"src/dbus_fast/message.py",
"src/dbus_fast/message_bus.py",
"src/dbus_fast/service.py",
"src/dbus_fast/signature.py",
"src/dbus_fast/unpack.py",
"src/dbus_fast/_private/address.py",
"src/dbus_fast/_private/marshaller.py",
"src/dbus_fast/_private/unmarshaller.py",
]
EXTENSIONS = [
Extension(
ext.removeprefix("src/").removesuffix(".py").replace("/", "."),
[ext],
language="c",
extra_compile_args=["-O3", "-g0"],
)
for ext in TO_CYTHONIZE
]
class BuildExt(build_ext):
def build_extensions(self):
try:
super().build_extensions()
except Exception:
_LOGGER.debug("Failed to build extensions", exc_info=True)
def build(setup_kwargs):
if os.environ.get("SKIP_CYTHON"):
return
try:
from Cython.Build import cythonize
setup_kwargs.update(
{
"ext_modules": cythonize(
EXTENSIONS,
compiler_directives={"language_level": "3"}, # Python 3
),
"cmdclass": {"build_ext": BuildExt},
}
)
setup_kwargs["exclude_package_data"] = {
pkg: ["*.c"] for pkg in setup_kwargs["packages"]
}
except Exception:
if os.environ.get("REQUIRE_CYTHON"):
raise
dbus-fast-2.44.1/commitlint.config.mjs 0000664 0000000 0000000 00000000362 14773556132 0017646 0 ustar 00root root 0000000 0000000 export default {
extends: ["@commitlint/config-conventional"],
rules: {
"header-max-length": [0, "always", Infinity],
"body-max-line-length": [0, "always", Infinity],
"footer-max-line-length": [0, "always", Infinity],
},
};
dbus-fast-2.44.1/docs/ 0000775 0000000 0000000 00000000000 14773556132 0014437 5 ustar 00root root 0000000 0000000 dbus-fast-2.44.1/docs/Makefile 0000664 0000000 0000000 00000001175 14773556132 0016103 0 ustar 00root root 0000000 0000000 # Minimal makefile for Sphinx documentation
#
# You can set these variables from the command line, and also
# from the environment for the first two.
SPHINXOPTS ?=
SPHINXBUILD ?= sphinx-build
SOURCEDIR = source
BUILDDIR = build
# Put it first so that "make" without argument is like "make help".
help:
@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
.PHONY: help Makefile
# Catch-all target: route all unknown targets to Sphinx using the new
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
%: Makefile
$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
dbus-fast-2.44.1/docs/make.bat 0000664 0000000 0000000 00000001374 14773556132 0016051 0 ustar 00root root 0000000 0000000 @ECHO OFF
pushd %~dp0
REM Command file for Sphinx documentation
if "%SPHINXBUILD%" == "" (
set SPHINXBUILD=sphinx-build
)
set SOURCEDIR=source
set BUILDDIR=build
if "%1" == "" goto help
%SPHINXBUILD% >NUL 2>NUL
if errorlevel 9009 (
echo.
echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
echo.installed, then set the SPHINXBUILD environment variable to point
echo.to the full path of the 'sphinx-build' executable. Alternatively you
echo.may add the Sphinx directory to PATH.
echo.
echo.If you don't have Sphinx installed, grab it from
echo.http://sphinx-doc.org/
exit /b 1
)
%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
goto end
:help
%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
:end
popd
dbus-fast-2.44.1/docs/requirements.txt 0000664 0000000 0000000 00000000126 14773556132 0017722 0 ustar 00root root 0000000 0000000 myst-parser==4.0.0
Sphinx==8.1.3
sphinx-rtd-theme==3.0.2
sphinxcontrib-fulltoc==1.2.0
dbus-fast-2.44.1/docs/source/ 0000775 0000000 0000000 00000000000 14773556132 0015737 5 ustar 00root root 0000000 0000000 dbus-fast-2.44.1/docs/source/Makefile 0000664 0000000 0000000 00000001137 14773556132 0017401 0 ustar 00root root 0000000 0000000 # Minimal makefile for Sphinx documentation
#
# You can set these variables from the command line.
SPHINXOPTS =
SPHINXBUILD = sphinx-build
SPHINXPROJ = dbus-fast
SOURCEDIR = .
BUILDDIR = _build
# Put it first so that "make" without argument is like "make help".
help:
@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
.PHONY: help Makefile
# Catch-all target: route all unknown targets to Sphinx using the new
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
%: Makefile
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
dbus-fast-2.44.1/docs/source/_static/ 0000775 0000000 0000000 00000000000 14773556132 0017365 5 ustar 00root root 0000000 0000000 dbus-fast-2.44.1/docs/source/_static/.gitignore 0000664 0000000 0000000 00000000000 14773556132 0021343 0 ustar 00root root 0000000 0000000 dbus-fast-2.44.1/docs/source/_static/.gitkeep 0000664 0000000 0000000 00000000000 14773556132 0021004 0 ustar 00root root 0000000 0000000 dbus-fast-2.44.1/docs/source/_templates/ 0000775 0000000 0000000 00000000000 14773556132 0020074 5 ustar 00root root 0000000 0000000 dbus-fast-2.44.1/docs/source/_templates/.gitignore 0000664 0000000 0000000 00000000000 14773556132 0022052 0 ustar 00root root 0000000 0000000 dbus-fast-2.44.1/docs/source/authentication.rst 0000664 0000000 0000000 00000000565 14773556132 0021516 0 ustar 00root root 0000000 0000000 Authentication
==============
Classes for the DBus `authentication protocol `_ for us with :class:`MessageBus ` implementations.
.. autoclass:: dbus_fast.auth.Authenticator
.. autoclass:: dbus_fast.auth.AuthExternal
.. autoclass:: dbus_fast.auth.AuthAnonymous
dbus-fast-2.44.1/docs/source/changelog.md 0000664 0000000 0000000 00000000045 14773556132 0020207 0 ustar 00root root 0000000 0000000 ```{include} ../../CHANGELOG.md
```
dbus-fast-2.44.1/docs/source/conf.py 0000664 0000000 0000000 00000011720 14773556132 0017237 0 ustar 00root root 0000000 0000000 #
# Configuration file for the Sphinx documentation builder.
#
# This file does only contain a selection of the most common options. For a
# full list see the documentation:
# http://www.sphinx-doc.org/en/master/config
# -- Path setup --------------------------------------------------------------
# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
#
import os
import sys
sys.path.insert(0, os.path.abspath(os.path.dirname(__file__) + "/.."))
from dbus_fast.__version__ import __author__, __copyright__, __title__, __version__
_project_slug = __title__.replace("_", "-")
# -- Project information -----------------------------------------------------
project = _project_slug
copyright = __copyright__
author = __author__
# The short X.Y version
version = __version__
# The full version, including alpha/beta/rc tags
release = __version__
# -- General configuration ---------------------------------------------------
# If your documentation needs a minimal Sphinx version, state it here.
#
# needs_sphinx = '1.0'
# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = [
"sphinx.ext.autodoc",
"sphinx.ext.githubpages",
"sphinxcontrib.fulltoc",
]
# Add any paths that contain templates here, relative to this directory.
templates_path = ["_templates"]
# The suffix(es) of source filenames.
# You can specify multiple suffix as a list of string:
#
# source_suffix = ['.rst', '.md']
source_suffix = ".rst"
# The master toctree document.
master_doc = "index"
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
#
# This is also used if you do content translation via gettext catalogs.
# Usually you set "language" from the command line for these cases.
language = "en"
# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
# This pattern also affects html_static_path and html_extra_path .
exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"]
# The name of the Pygments (syntax highlighting) style to use.
pygments_style = "sphinx"
# -- Options for HTML output -------------------------------------------------
# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
#
html_theme = "alabaster"
# Theme options are theme-specific and customize the look and feel of a theme
# further. For a list of options available for each theme, see the
# documentation.
#
# html_theme_options = {}
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ["_static"]
# Custom sidebar templates, must be a dictionary that maps document names
# to template names.
#
# The default sidebars (for documents that don't match any pattern) are
# defined by theme itself. Builtin themes are using these templates by
# default: ``['localtoc.html', 'relations.html', 'sourcelink.html',
# 'searchbox.html']``.
#
# html_sidebars = {}
# -- Options for HTMLHelp output ---------------------------------------------
# Output file base name for HTML help builder.
htmlhelp_basename = "dbus-fastdoc"
# -- Options for LaTeX output ------------------------------------------------
latex_elements = {
# The paper size ('letterpaper' or 'a4paper').
#
# 'papersize': 'letterpaper',
# The font size ('10pt', '11pt' or '12pt').
#
# 'pointsize': '10pt',
# Additional stuff for the LaTeX preamble.
#
# 'preamble': '',
# Latex figure (float) alignment
#
# 'figure_align': 'htbp',
}
# Grouping the document tree into LaTeX files. List of tuples
# (source start file, target name, title,
# author, documentclass [howto, manual, or own class]).
latex_documents = [
(master_doc, "dbus-fast.tex", "dbus-fast Documentation", __author__, "manual"),
]
# -- Options for manual page output ------------------------------------------
# One entry per manual page. List of tuples
# (source start file, name, description, authors, manual section).
man_pages = [(master_doc, _project_slug, "dbus-fast Documentation", [author], 1)]
# -- Options for Texinfo output ----------------------------------------------
# Grouping the document tree into Texinfo files. List of tuples
# (source start file, target name, title, author,
# dir menu entry, description, category)
texinfo_documents = [
(
master_doc,
_project_slug,
"dbus-fast Documentation",
author,
_project_slug,
"One line description of project.",
"Miscellaneous",
),
]
# -- Extension configuration -------------------------------------------------
dbus-fast-2.44.1/docs/source/constants.rst 0000664 0000000 0000000 00000001242 14773556132 0020504 0 ustar 00root root 0000000 0000000 Constants
=========
.. autoclass:: dbus_fast.BusType
:members:
:undoc-members:
.. autoclass:: dbus_fast.MessageType
:members:
:undoc-members:
.. autoclass:: dbus_fast.MessageFlag
:members:
:undoc-members:
.. autoclass:: dbus_fast.NameFlag
:members:
:undoc-members:
.. autoclass:: dbus_fast.RequestNameReply
:members:
:undoc-members:
.. autoclass:: dbus_fast.ReleaseNameReply
:members:
:undoc-members:
.. autoclass:: dbus_fast.PropertyAccess
:members:
:undoc-members:
.. autoclass:: dbus_fast.ArgDirection
:members:
:undoc-members:
.. autoclass:: dbus_fast.ErrorType
:members:
:undoc-members:
dbus-fast-2.44.1/docs/source/contributing.md 0000664 0000000 0000000 00000000050 14773556132 0020763 0 ustar 00root root 0000000 0000000 ```{include} ../../CONTRIBUTING.md
```
dbus-fast-2.44.1/docs/source/errors.rst 0000664 0000000 0000000 00000001205 14773556132 0020003 0 ustar 00root root 0000000 0000000 Errors
======
.. autoclass:: dbus_fast.DBusError
:members:
:undoc-members:
.. autoclass:: dbus_fast.SignatureBodyMismatchError
.. autoclass:: dbus_fast.InvalidSignatureError
.. autoclass:: dbus_fast.InvalidAddressError
.. autoclass:: dbus_fast.AuthError
.. autoclass:: dbus_fast.InvalidMessageError
.. autoclass:: dbus_fast.InvalidIntrospectionError
.. autoclass:: dbus_fast.InterfaceNotFoundError
.. autoclass:: dbus_fast.SignalDisabledError
.. autoclass:: dbus_fast.InvalidBusNameError
.. autoclass:: dbus_fast.InvalidObjectPathError
.. autoclass:: dbus_fast.InvalidInterfaceNameError
.. autoclass:: dbus_fast.InvalidMemberNameError
dbus-fast-2.44.1/docs/source/high-level-client/ 0000775 0000000 0000000 00000000000 14773556132 0021237 5 ustar 00root root 0000000 0000000 dbus-fast-2.44.1/docs/source/high-level-client/aio-proxy-interface.rst 0000664 0000000 0000000 00000000214 14773556132 0025653 0 ustar 00root root 0000000 0000000 aio.ProxyInterface
==================
.. autoclass:: dbus_fast.aio.ProxyInterface
:members:
:undoc-members:
:show-inheritance:
dbus-fast-2.44.1/docs/source/high-level-client/aio-proxy-object.rst 0000664 0000000 0000000 00000000203 14773556132 0025157 0 ustar 00root root 0000000 0000000 aio.ProxyObject
===============
.. autoclass:: dbus_fast.aio.ProxyObject
:members:
:undoc-members:
:show-inheritance:
dbus-fast-2.44.1/docs/source/high-level-client/base-proxy-interface.rst 0000664 0000000 0000000 00000000202 14773556132 0026012 0 ustar 00root root 0000000 0000000 BaseProxyInterface
==================
.. autoclass:: dbus_fast.proxy_object.BaseProxyInterface
:members:
:undoc-members:
dbus-fast-2.44.1/docs/source/high-level-client/base-proxy-object.rst 0000664 0000000 0000000 00000000171 14773556132 0025325 0 ustar 00root root 0000000 0000000 BaseProxyObject
===============
.. autoclass:: dbus_fast.proxy_object.BaseProxyObject
:members:
:undoc-members:
dbus-fast-2.44.1/docs/source/high-level-client/glib-proxy-interface.rst 0000664 0000000 0000000 00000000217 14773556132 0026023 0 ustar 00root root 0000000 0000000 glib.ProxyInterface
===================
.. autoclass:: dbus_fast.glib.ProxyInterface
:members:
:undoc-members:
:show-inheritance:
dbus-fast-2.44.1/docs/source/high-level-client/glib-proxy-object.rst 0000664 0000000 0000000 00000000206 14773556132 0025327 0 ustar 00root root 0000000 0000000 glib.ProxyObject
================
.. autoclass:: dbus_fast.glib.ProxyObject
:members:
:undoc-members:
:show-inheritance:
dbus-fast-2.44.1/docs/source/high-level-client/index.rst 0000664 0000000 0000000 00000011751 14773556132 0023105 0 ustar 00root root 0000000 0000000 The High Level Client
=====================
.. toctree::
:maxdepth: 2
base-proxy-object
base-proxy-interface
aio-proxy-object
aio-proxy-interface
glib-proxy-object
glib-proxy-interface
DBus interfaces are defined with an XML-based `introspection data format `_ which is exposed over the standard `org.freedesktop.DBus.Introspectable `_ interface. Calling the ``Introspect`` at a particular object path may return XML data similar to this:
.. code-block:: xml
The object at this path (a ``node``) may contain interfaces and child nodes. Nodes like this are represented in the library by a :class:`ProxyObject `. The interfaces contained in the nodes are represented by a :class:`ProxyInterface `. The proxy interface exposes the methods, signals, and properties specified by the interface definition.
The proxy object is obtained by the :class:`MessageBus ` through the :func:`get_proxy_object() ` method. This method takes the name of the client to send messages to, the path exported by that client that is expected to export the node, and the XML introspection data. If you can, it is recommended to include the XML in your project and pass it to that method as a string. But you may also use the :func:`introspect() ` method of the message bus to get this data dynamically at runtime.
Once you have a proxy object, use the :func:`get_proxy_interface() ` method to create an interface passing the name of the interface to get. Each message bus has its own implementation of the proxy interface which behaves slightly differently. This is an example of how to use a proxy interface for the asyncio :class:`MessageBus `.
If any file descriptors are sent or received (DBus type ``h``), the variable refers to the file descriptor itself. You are responsible for closing any file descriptors sent or received by the bus. You must set the ``negotiate_unix_fd`` flag to ``True`` in the ``MessageBus`` constructor to use unix file descriptors.
:example:
.. code-block:: python3
from dbus_fast.aio import MessageBus
from dbus_fast import Variant
bus = await MessageBus().connect()
with open('introspection.xml', 'r') as f:
introspection = f.read()
# alternatively, get the data dynamically:
# introspection = await bus.introspect('com.example.name',
# '/com/example/sample_object0')
proxy_object = bus.get_proxy_object('com.example.name',
'/com/example/sample_object0',
introspection)
interface = proxy_object.get_interface('com.example.SampleInterface0')
# Use call_[METHOD] in snake case to call methods, passing the
# in args and receiving the out args. The `baz` returned will
# be type 'a{us}' which translates to a Python dict with `int`
# keys and `str` values.
baz = await interface.call_frobate(5, 'hello')
# `bar` will be a Variant.
bar = await interface.call_bazify([-5, 5, 5])
await interface.call_mogrify([5, 5, [ Variant('s', 'foo') ])
# Listen to signals by defining a callback that takes the args
# specified by the signal definition and registering it on the
# interface with on_[SIGNAL] in snake case.
def changed_notify(new_value):
print(f'The new value is: {new_value}')
interface.on_changed(changed_notify)
# Use get_[PROPERTY] and set_[PROPERTY] with the property in
# snake case to get and set the property.
bar_value = await interface.get_bar()
await interface.set_bar(105)
await bus.wait_for_disconnect()
dbus-fast-2.44.1/docs/source/high-level-service/ 0000775 0000000 0000000 00000000000 14773556132 0021421 5 ustar 00root root 0000000 0000000 dbus-fast-2.44.1/docs/source/high-level-service/index.rst 0000664 0000000 0000000 00000012702 14773556132 0023264 0 ustar 00root root 0000000 0000000 The High Level Service
======================
.. toctree::
:maxdepth: 2
service-interface
The high level service interface provides everything you need to export interfaces on the bus. When you export an interface on your :class:`MessageBus `, clients can send you messages to call methods, get and set properties, and listen to your signals.
If you're exposing a service for general use, you can request a well-known name for your connection with :func:`MessageBus.request_name() ` so users have a predictable name to use to send messages your client.
Services are defined by subclassing :class:`ServiceInterface ` and definining members as methods on the class with the decorator methods :func:`@method() `, :func:`@dbus_property() `, and :func:`@signal() `. The parameters of the decorated class methods must be annotated with DBus type strings to indicate the types of values they expect. See the documentation on `the type system `_ for more information on how DBus types are mapped to Python values with signature strings. The decorator methods themselves take arguments that affect how the member is exported on the bus, such as the name of the member or the access permissions of a property.
A class method decorated with ``@method()`` will be called when a client calls the method over DBus. The parameters given to the class method will be provided by the calling client and will conform to the parameter type annotations. The value returned by the class method will be returned to the client and must conform to the return type annotation specified by the user. If the return annotation specifies more than one type, the values must be returned in a ``list``. When :class:`aio.MessageBus` is used, methods can be coroutines.
A class method decorated with ``@dbus_property()`` will be exposed as a DBus property getter. This decoration works the same as a standard Python ``@property``. The getter will be called when a client gets the property through the standard properties interface with ``org.freedesktop.DBus.Properties.Get``. Define a property setter with ``@method_name.setter`` taking the new value as a parameter. The setter will be called when the client sets the property through ``org.freedesktop.DBus.Properties.Set``. When :class:`aio.MessageBus` is used, property getters and setters can be coroutines, although this will cause some functionality of the Python ``@property`` annotation to be lost.
A class method decorated with ``@signal()`` will be exposed as a DBus signal. The value returned by the class method will be emitted as a signal and broadcast to clients who are listening to the signal. The returned value must conform to the return annotation of the class method as a DBus signature string. If the signal has more than one argument, they must be returned within a ``list``.
A class method decorated with ``@method()`` or ``@dbus_property()`` may throw a :class:`DBusError ` to return a detailed error to the client if something goes wrong.
After the service interface is defined, call :func:`MessageBus.export() ` on a connected message bus and the service will be made available on the given object path.
If any file descriptors are sent or received (DBus type ``h``), the variable refers to the file descriptor itself. You are responsible for closing any file descriptors sent or received by the bus. You must set the ``negotiate_unix_fd`` flag to ``True`` in the ``MessageBus`` constructor to use unix file descriptors.
:example:
.. code-block:: python3
from dbus_fast.aio import MessageBus
from dbus_fast.service import (ServiceInterface,
method, dbus_property, signal)
from dbus_fast import Variant, DBusError
import asyncio
class ExampleInterface(ServiceInterface):
def __init__(self):
super().__init__('com.example.SampleInterface0')
self._bar = 105
@method()
def Frobate(self, foo: 'i', bar: 's') -> 'a{us}':
print(f'called Frobate with foo={foo} and bar={bar}')
return {
1: 'one',
2: 'two'
}
@method()
async def Bazify(self, bar: '(iiu)') -> 'vv':
print(f'called Bazify with bar={bar}')
return [Variant('s', 'example'), Variant('s', 'bazify')]
@method()
def Mogrify(self, bar: '(iiav)'):
raise DBusError('com.example.error.CannotMogrify',
'it is not possible to mogrify')
@signal()
def Changed(self) -> 'b':
return True
@dbus_property()
def Bar(self) -> 'y':
return self._bar
@Bar.setter
def Bar(self, val: 'y'):
if self._bar == val:
return
self._bar = val
self.emit_properties_changed({'Bar': self._bar})
async def main():
bus = await MessageBus().connect()
interface = ExampleInterface()
bus.export('/com/example/sample0', interface)
await bus.request_name('com.example.name')
# emit the changed signal after two seconds.
await asyncio.sleep(2)
interface.changed()
await bus.wait_for_disconnect()
asyncio.run(main())
dbus-fast-2.44.1/docs/source/high-level-service/service-interface.rst 0000664 0000000 0000000 00000000405 14773556132 0025550 0 ustar 00root root 0000000 0000000 ServiceInterface
================
.. autoclass:: dbus_fast.service.ServiceInterface
:members:
:undoc-members:
.. autodecorator:: dbus_fast.service.dbus_property
.. autodecorator:: dbus_fast.service.method
.. autodecorator:: dbus_fast.service.signal
dbus-fast-2.44.1/docs/source/index.md 0000664 0000000 0000000 00000000351 14773556132 0017367 0 ustar 00root root 0000000 0000000 # Welcome to dbus-fast documentation!
```{toctree}
:caption: Installation & Usage
:maxdepth: 2
installation
usage
```
```{toctree}
:caption: Project Info
:maxdepth: 2
changelog
contributing
```
```{include} ../../README.md
```
dbus-fast-2.44.1/docs/source/index.rst 0000664 0000000 0000000 00000005177 14773556132 0017612 0 ustar 00root root 0000000 0000000 Python DBus-Fast Documentation
==============================
.. module:: dbus_fast
.. toctree::
:maxdepth: 3
:caption: Reference:
type-system/index.rst
high-level-client/index.rst
high-level-service/index.rst
low-level-interface/index.rst
message-bus/index.rst
introspection
validators
constants
errors
authentication
Overview
++++++++
Python DBus-Fast is a library for the `DBus message bus system `_ for interprocess communcation in a Linux desktop or mobile environment.
Desktop application developers can use this library for integrating their applications into desktop environments by implementing common DBus standard interfaces or creating custom plugin interfaces.
Desktop users can use this library to create their own scripts and utilities to interact with those interfaces for customization of their desktop environment.
While other libraries for DBus exist for Python, this library offers the following improvements:
- Zero dependencies and pure Python 3.
- Support for multiple main loop backends including asyncio and the GLib main loop.
- Nonblocking IO suitable for GUI development.
- Target the latest language features of Python for beautiful services and clients.
- Complete implementation of the DBus type system without ever guessing types.
- Integration tests for all features of the library.
- Completely documented public API.
The library offers three core interfaces:
- `The High Level Client `_ - Communicate with an existing interface exported on the bus by another client through a proxy object.
- `The High Level Service `_ - Export a service interface for your application other clients can connect to for interaction with your application at runtime.
- `The Low Level Interface `_ - Work with DBus messages directly for applications that work with the DBus daemon directly or to build your own high level abstractions.
Installation
++++++++++++
This library is available on PyPi as `dbus-fast `_.
.. code-block:: bash
pip3 install dbus-fast
Contributing
++++++++++++
Development for this library happens on `Github `_. Report bugs or request features there. Contributions are welcome.
License
++++++++
This library is available under an `MIT License `_.
© 2022, Bluetooth Devices authors
© 2019, Tony Crisci
Indices and tables
==================
* :ref:`genindex`
* :ref:`modindex`
* :ref:`search`
dbus-fast-2.44.1/docs/source/installation.md 0000664 0000000 0000000 00000000264 14773556132 0020764 0 ustar 00root root 0000000 0000000 # Installation
The package is published on [PyPI](https://pypi.org/project/deezer-python/) and can be installed with `pip` (or any equivalent):
```bash
pip install dbus-fast
```
dbus-fast-2.44.1/docs/source/introspection.rst 0000664 0000000 0000000 00000001002 14773556132 0021362 0 ustar 00root root 0000000 0000000 Introspection
=============
.. autoclass:: dbus_fast.introspection.Node
:members:
:undoc-members:
.. autoclass:: dbus_fast.introspection.Interface
:members:
:undoc-members:
.. autoclass:: dbus_fast.introspection.Property
:members:
:undoc-members:
.. autoclass:: dbus_fast.introspection.Method
:members:
:undoc-members:
.. autoclass:: dbus_fast.introspection.Signal
:members:
:undoc-members:
.. autoclass:: dbus_fast.introspection.Arg
:members:
:undoc-members:
dbus-fast-2.44.1/docs/source/low-level-interface/ 0000775 0000000 0000000 00000000000 14773556132 0021603 5 ustar 00root root 0000000 0000000 dbus-fast-2.44.1/docs/source/low-level-interface/index.rst 0000664 0000000 0000000 00000007430 14773556132 0023450 0 ustar 00root root 0000000 0000000 The Low Level Interface
=======================
.. toctree::
:maxdepth: 2
message
The low-level interface allows you to work with messages directly through the :class:`MessageBus ` with the :class:`Message ` class. This might be useful in the following cases:
- Implementing an application that works with DBus directly like ``dbus-send(1)`` or ``dbus-monitor(1)``.
- Creating a new implementation of the :class:`BaseMessageBus `.
- Creating clients or services that use an alternative to the standard DBus interfaces.
The primary methods and classes of the low-level interface are:
- :class:`Message `
- :func:`MessageBus.send() `
- :func:`MessageBus.add_message_handler() `
- :func:`MessageBus.remove_message_handler() `
- :func:`MessageBus.next_serial() `
- :func:`aio.MessageBus.call() `
- :func:`glib.MessageBus.call() `
- :func:`glib.MessageBus.call_sync() `
Mixed use of the low and high level interfaces on the same bus connection is not recommended.
:example: Call a standard interface
.. code-block:: python3
bus = await MessageBus().connect()
msg = Message(destination='org.freedesktop.DBus',
path='/org/freedesktop/DBus',
interface='org.freedesktop.DBus',
member='ListNames',
serial=bus.next_serial())
reply = await bus.call(msg)
assert reply.message_type == MessageType.METHOD_RETURN
print(reply.body[0])
:example: A custom method handler. Note that to receive these messages, you must `add a match rule `_ for the types of messages you want to receive.
.. code-block:: python3
bus = await MessageBus().connect()
reply = await bus.call(
Message(destination='org.freedesktop.DBus',
path='/org/freedesktop/DBus',
member='AddMatch',
signature='s',
body=["member='MyMember', interface='com.test.interface'"]))
assert reply.message_type == MessageType.METHOD_RETURN
def message_handler(msg):
if msg.interface == 'com.test.interface' and msg.member == 'MyMember':
return Message.new_method_return(msg, 's', ['got it'])
bus.add_message_handler(message_handler)
await bus.wait_for_disconnect()
:example: Emit a signal
.. code-block:: python3
bus = await MessageBus().connect()
await bus.send(Message.new_signal('/com/test/path',
'com.test.interface',
'SomeSignal',
's', ['a signal']))
:example: Send a file descriptor. The message format will be the same when
received on the client side. You are responsible for closing any file
descriptor that is sent or received by the bus. You must set the
``negotiate_unix_fd`` flag to ``True`` in the ``MessageBus``
constructor to use unix file descriptors.
.. code-block:: python3
bus = await MessageBus().connect(negotiate_unix_fd=True)
fd = os.open('/dev/null', os.O_RDONLY)
msg = Message(destination='org.test.destination',
path='/org/test/destination',
interface='org.test.interface',
member='TestMember',
signature='h',
body=[0],
unix_fds=[fd])
await bus.send(msg)
dbus-fast-2.44.1/docs/source/low-level-interface/message.rst 0000664 0000000 0000000 00000000124 14773556132 0023756 0 ustar 00root root 0000000 0000000 Message
=======
.. autoclass:: dbus_fast.Message
:members:
:undoc-members:
dbus-fast-2.44.1/docs/source/message-bus/ 0000775 0000000 0000000 00000000000 14773556132 0020152 5 ustar 00root root 0000000 0000000 dbus-fast-2.44.1/docs/source/message-bus/aio-message-bus.rst 0000664 0000000 0000000 00000000204 14773556132 0023661 0 ustar 00root root 0000000 0000000 aio.MessageBus
==============
.. autoclass:: dbus_fast.aio.MessageBus
:members:
:inherited-members:
:show-inheritance:
dbus-fast-2.44.1/docs/source/message-bus/base-message-bus.rst 0000664 0000000 0000000 00000000141 14773556132 0024023 0 ustar 00root root 0000000 0000000 BaseMessageBus
==============
.. autoclass:: dbus_fast.message_bus.BaseMessageBus
:members:
dbus-fast-2.44.1/docs/source/message-bus/glib-message-bus.rst 0000664 0000000 0000000 00000000207 14773556132 0024031 0 ustar 00root root 0000000 0000000 glib.MessageBus
===============
.. autoclass:: dbus_fast.glib.MessageBus
:members:
:inherited-members:
:show-inheritance:
dbus-fast-2.44.1/docs/source/message-bus/index.rst 0000664 0000000 0000000 00000002072 14773556132 0022014 0 ustar 00root root 0000000 0000000 The Message Bus
===============
.. toctree::
:maxdepth: 2
base-message-bus.rst
aio-message-bus.rst
glib-message-bus.rst
The message bus manages a connection to the DBus daemon. It's capable of sending and receiving messages and wiring up the classes of the high level interfaces.
There are currently two implementations of the message bus depending on what main loop implementation you want to use. Use :class:`aio.MessageBus ` if you are using an asyncio main loop. Use :class:`glib.MessageBus ` if you are using a GLib main loop.
For standalone applications, the asyncio message bus is preferable because it has a nice async/await api in place of the callback/synchronous interface of the GLib message bus. If your application is using other libraries that use the GLib main loop, such as a GTK application, the GLib implementation will be needed. However neither library is a requirement.
For more information on how to use the message bus, see the documentation for the specific interfaces you plan to use.
dbus-fast-2.44.1/docs/source/type-system/ 0000775 0000000 0000000 00000000000 14773556132 0020242 5 ustar 00root root 0000000 0000000 dbus-fast-2.44.1/docs/source/type-system/index.rst 0000664 0000000 0000000 00000023307 14773556132 0022110 0 ustar 00root root 0000000 0000000 The Type System
===============
.. toctree::
:maxdepth: 2
variant
signature-tree
signature-type
Values that are sent or received over the message bus always have an
associated signature that specifies the types of those values. For the
high-level client and service, these signatures are specified in XML
data which is advertised in a `standard DBus
interface `__.
The high-level client dynamically creates classes based on this
introspection data with methods and signals with arguments based on the
type signature. The high-level service does the inverse by introspecting
the class to create the introspection XML data which is advertised on
the bus for clients.
Each token in the signature is mapped to a Python type as shown in the table
below.
+-------------+-------+--------------------------------------+-------------------------------------------------------------------------+
| Name | Token | Python | Notes |
| | | Type | |
+-------------+-------+--------------------------------------+-------------------------------------------------------------------------+
| BYTE | y | int | An integer 0-255. In an array, it has type ``bytes``. |
+-------------+-------+--------------------------------------+-------------------------------------------------------------------------+
| BOOLEAN | b | bool | |
+-------------+-------+--------------------------------------+-------------------------------------------------------------------------+
| INT16 | n | int | |
+-------------+-------+--------------------------------------+-------------------------------------------------------------------------+
| UINT16 | q | int | |
+-------------+-------+--------------------------------------+-------------------------------------------------------------------------+
| INT32 | i | int | |
+-------------+-------+--------------------------------------+-------------------------------------------------------------------------+
| UINT32 | u | int | |
+-------------+-------+--------------------------------------+-------------------------------------------------------------------------+
| INT64 | x | int | |
+-------------+-------+--------------------------------------+-------------------------------------------------------------------------+
| UINT64 | t | int | |
+-------------+-------+--------------------------------------+-------------------------------------------------------------------------+
| DOUBLE | d | float | |
+-------------+-------+--------------------------------------+-------------------------------------------------------------------------+
| STRING | s | str | |
+-------------+-------+--------------------------------------+-------------------------------------------------------------------------+
| OBJECT_PATH | o | str | Must be a valid object path. |
+-------------+-------+--------------------------------------+-------------------------------------------------------------------------+
| SIGNATURE | g | str | Must be a valid signature. |
+-------------+-------+--------------------------------------+-------------------------------------------------------------------------+
| UNIX_FD | h | int | In the low-level interface, an index pointing to a file descriptor |
| | | | in the ``unix_fds`` member of the :class:`Message `. |
| | | | In the high-level interface, it is the file descriptor itself. |
+-------------+-------+--------------------------------------+-------------------------------------------------------------------------+
| ARRAY | a | list | Must be followed by a complete type which specifies the child type. |
+-------------+-------+--------------------------------------+-------------------------------------------------------------------------+
| STRUCT | ( | list | Types in the Python ``list`` must match the types between the parens. |
+-------------+-------+--------------------------------------+-------------------------------------------------------------------------+
| VARIANT | v | :class:`Variant ` | This class is provided by the library. |
| | | | |
+-------------+-------+--------------------------------------+-------------------------------------------------------------------------+
| DICT_ENTRY | { | dict | Must be included in an array to be a ``dict``. |
+-------------+-------+--------------------------------------+-------------------------------------------------------------------------+
The types ``a``, ``(``, ``v``, and ``{`` are container types that hold
other values. Examples of container types and Python examples are in the
table below.
+-----------+--------------------------------------+-------------------------------------------------------+
| Signature | Example | Notes |
+===========+======================================+=======================================================+
| ``(su)`` | ``[ 'foo', 5 ]`` | Each element in the array must match the |
| | | corresponding type of the struct member. |
+-----------+--------------------------------------+-------------------------------------------------------+
| ``as`` | ``[ 'foo', 'bar' ]`` | The child type comes immediately after the ``a``. |
| | | The array can have any number of elements, but |
| | | they all must match the child type. |
+-----------+--------------------------------------+-------------------------------------------------------+
| ``a{su}`` | ``{ 'foo': 5 }`` | An "array of dict entries" is represented by a |
| | | ``dict``. The type after ``{`` is the key type and |
| | | the type before the ``}`` is the value type. |
+-----------+--------------------------------------+-------------------------------------------------------+
| ``ay`` | ``b'\0x62\0x75\0x66'`` | Special case: an array of bytes is represented by |
| | | Python ``bytes``. |
| | | |
| | | |
| | | |
| | | |
+-----------+--------------------------------------+-------------------------------------------------------+
| ``v`` | ``Variant('as', ['hello'])`` | Signature must be a single type. A variant may hold a |
| | | container type. |
| | | |
| | | |
| | | |
+-----------+--------------------------------------+-------------------------------------------------------+
| ``(asv)`` | ``[ ['foo'], Variant('s', 'bar') ]`` | Containers may be nested. |
+-----------+--------------------------------------+-------------------------------------------------------+
For more information on the DBus type system, see `the
specification `__.
dbus-fast-2.44.1/docs/source/type-system/signature-tree.rst 0000664 0000000 0000000 00000000146 14773556132 0023733 0 ustar 00root root 0000000 0000000 SignatureTree
=============
.. autoclass:: dbus_fast.SignatureTree
:members:
:undoc-members:
dbus-fast-2.44.1/docs/source/type-system/signature-type.rst 0000664 0000000 0000000 00000000207 14773556132 0023753 0 ustar 00root root 0000000 0000000 SignatureType
==============
.. autoclass:: dbus_fast.SignatureType
:members:
:undoc-members:
:exclude-members: signature
dbus-fast-2.44.1/docs/source/type-system/variant.rst 0000664 0000000 0000000 00000000124 14773556132 0022435 0 ustar 00root root 0000000 0000000 Variant
=======
.. autoclass:: dbus_fast.Variant
:members:
:undoc-members:
dbus-fast-2.44.1/docs/source/usage.md 0000664 0000000 0000000 00000000137 14773556132 0017366 0 ustar 00root root 0000000 0000000 # Usage
To use this package, import it:
```python
import dbus_fast
```
TODO: Document usage
dbus-fast-2.44.1/docs/source/validators.rst 0000664 0000000 0000000 00000000657 14773556132 0020651 0 ustar 00root root 0000000 0000000 Validators
==========
.. autofunction:: dbus_fast.is_bus_name_valid
.. autofunction:: dbus_fast.is_member_name_valid
.. autofunction:: dbus_fast.is_object_path_valid
.. autofunction:: dbus_fast.is_interface_name_valid
.. autofunction:: dbus_fast.assert_bus_name_valid
.. autofunction:: dbus_fast.assert_member_name_valid
.. autofunction:: dbus_fast.assert_object_path_valid
.. autofunction:: dbus_fast.assert_interface_name_valid
dbus-fast-2.44.1/examples/ 0000775 0000000 0000000 00000000000 14773556132 0015325 5 ustar 00root root 0000000 0000000 dbus-fast-2.44.1/examples/aio-list-names.py 0000775 0000000 0000000 00000001235 14773556132 0020525 0 ustar 00root root 0000000 0000000 #!/usr/bin/env python3
import os
import sys
sys.path.append(os.path.abspath(os.path.dirname(__file__) + "/.."))
import asyncio
import json
from dbus_fast import Message, MessageType
from dbus_fast.aio import MessageBus
async def main():
bus = await MessageBus().connect()
reply = await bus.call(
Message(
destination="org.freedesktop.DBus",
path="/org/freedesktop/DBus",
interface="org.freedesktop.DBus",
member="ListNames",
)
)
if reply.message_type == MessageType.ERROR:
raise Exception(reply.body[0])
print(json.dumps(reply.body[0], indent=2))
asyncio.run(main())
dbus-fast-2.44.1/examples/aio-tcp-notification.py 0000775 0000000 0000000 00000002312 14773556132 0021720 0 ustar 00root root 0000000 0000000 #!/usr/bin/env python3
# In order for this to work a local tcp connection to the DBus a port
# must be opened to forward to the dbus socket file. The easiest way
# to achieve this is using "socat":
# socat TCP-LISTEN:55556,reuseaddr,fork,range=127.0.0.1/32 UNIX-CONNECT:$(echo $DBUS_SESSION_BUS_ADDRESS | sed 's/unix:path=//g')
# For actual DBus transport over network the authentication might
# be a further problem. More information here:
# https://dbus.freedesktop.org/doc/dbus-specification.html#auth-mechanisms
import os
import sys
sys.path.append(os.path.abspath(os.path.dirname(__file__) + "/.."))
import asyncio
from dbus_fast.aio import MessageBus
async def main():
bus = await MessageBus(bus_address="tcp:host=127.0.0.1,port=55556").connect()
introspection = await bus.introspect(
"org.freedesktop.Notifications", "/org/freedesktop/Notifications"
)
obj = bus.get_proxy_object(
"org.freedesktop.Notifications", "/org/freedesktop/Notifications", introspection
)
notification = obj.get_interface("org.freedesktop.Notifications")
await notification.call_notify(
"test.py", 0, "", "DBus Test", "Test notification", [""], dict(), 5000
)
asyncio.run(main())
dbus-fast-2.44.1/examples/dbus-next-send.py 0000775 0000000 0000000 00000006712 14773556132 0020550 0 ustar 00root root 0000000 0000000 #!/usr/bin/env python3
import os
import sys
sys.path.append(os.path.abspath(os.path.dirname(__file__) + "/.."))
import asyncio
import json
from argparse import OPTIONAL, ArgumentParser
from dbus_fast import BusType, Message, MessageType, Variant
from dbus_fast.aio import MessageBus
from dbus_fast.validators import (
is_bus_name_valid,
is_interface_name_valid,
is_member_name_valid,
is_object_path_valid,
)
parser = ArgumentParser()
parser.add_argument("--system", help="Use the system bus", action="store_true")
parser.add_argument("--session", help="Use the session bus", action="store_true")
parser.add_argument(
"--dest", help="The destination address for the message", required=True
)
parser.add_argument("--signature", help="The signature for the message body")
parser.add_argument(
"--type",
help="The type of message to send",
choices=[e.name for e in MessageType],
default=MessageType.METHOD_CALL.name,
nargs=OPTIONAL,
)
parser.add_argument("object_path", help="The object path for the message")
parser.add_argument("interface.member", help="The interface and member for the message")
parser.add_argument(
"body",
help="The JSON encoded body of the message. Must match the signature",
nargs=OPTIONAL,
)
args = parser.parse_args()
def exit_error(message):
parser.print_usage()
print()
print(message)
sys.exit(1)
interface_member = vars(args)["interface.member"].split(".")
if len(interface_member) < 2:
exit_error(
f"Expecting an interface and member separated by a dot: {vars(args)['interface.member']}"
)
destination = args.dest
member = interface_member[-1]
interface = ".".join(interface_member[: len(interface_member) - 1])
object_path = args.object_path
signature = args.signature
body = args.body
message_type = MessageType[args.type]
signature = args.signature
bus_type = BusType.SESSION
if args.system:
bus_type = BusType.SYSTEM
if message_type is not MessageType.METHOD_CALL:
exit_error("only message type METHOD_CALL is supported right now")
if not is_bus_name_valid(destination):
exit_error(f"got invalid bus name: {destination}")
if not is_object_path_valid(object_path):
exit_error(f"got invalid object path: {object_path}")
if not is_interface_name_valid(interface):
exit_error(f"got invalid interface name: {interface}")
if not is_member_name_valid(member):
exit_error(f"got invalid member name: {member}")
if body is None:
body = []
signature = ""
else:
try:
body = json.loads(body)
except json.JSONDecodeError as e:
exit_error(f"could not parse body as JSON: ({e})")
if type(body) is not list:
exit_error("body must be an array of arguments")
if not signature:
exit_error("--signature is a required argument when passing a message body")
async def main():
bus = await MessageBus(bus_type=bus_type).connect()
message = Message(
destination=destination,
member=member,
interface=interface,
path=object_path,
signature=signature,
body=body,
)
result = await bus.call(message)
ret = 0
if result.message_type is MessageType.ERROR:
print(f"Error: {result.error_name}", file=sys.stderr)
ret = 1
def default(o):
if type(o) is Variant:
return [o.signature, o.value]
raise json.JSONDecodeError()
print(json.dumps(result.body, indent=2, default=default))
sys.exit(ret)
asyncio.run(main())
dbus-fast-2.44.1/examples/example-service.py 0000775 0000000 0000000 00000003175 14773556132 0021001 0 ustar 00root root 0000000 0000000 #!/usr/bin/env python3
import os
import sys
sys.path.append(os.path.abspath(os.path.dirname(__file__) + "/.."))
import asyncio
from dbus_fast import Variant
from dbus_fast.aio.message_bus import MessageBus
from dbus_fast.service import ServiceInterface, dbus_property, method, signal
class ExampleInterface(ServiceInterface):
def __init__(self, name):
super().__init__(name)
self._string_prop = "kevin"
@method()
def Echo(self, what: "s") -> "s":
return what
@method()
def EchoMultiple(self, what1: "s", what2: "s") -> "ss":
return [what1, what2]
@method()
def GetVariantDict(self) -> "a{sv}": # noqa: F722
return {
"foo": Variant("s", "bar"),
"bat": Variant("x", -55),
"a_list": Variant("as", ["hello", "world"]),
}
@dbus_property(name="StringProp")
def string_prop(self) -> "s":
return self._string_prop
@string_prop.setter
def string_prop_setter(self, val: "s"):
self._string_prop = val
@signal()
def signal_simple(self) -> "s":
return "hello"
@signal()
def signal_multiple(self) -> "ss":
return ["hello", "world"]
async def main():
name = "dbus.next.example.service"
path = "/example/path"
interface_name = "example.interface"
bus = await MessageBus().connect()
interface = ExampleInterface(interface_name)
bus.export("/example/path", interface)
await bus.request_name(name)
print(
f'service up on name: "{name}", path: "{path}", interface: "{interface_name}"'
)
await bus.wait_for_disconnect()
asyncio.run(main())
dbus-fast-2.44.1/examples/glib-list-names.py 0000775 0000000 0000000 00000001217 14773556132 0020672 0 ustar 00root root 0000000 0000000 #!/usr/bin/env python3
import os
import sys
sys.path.append(os.path.abspath(os.path.dirname(__file__) + "/.."))
import json
import signal
from gi.repository import GLib
from dbus_fast import Message
from dbus_fast.glib import MessageBus
main = GLib.MainLoop()
bus = MessageBus().connect_sync()
def reply_handler(reply, err):
main.quit()
if err:
raise err
print(json.dumps(reply.body[0], indent=2))
bus.call(
Message(
"org.freedesktop.DBus",
"/org/freedesktop/DBus",
"org.freedesktop.DBus",
"ListNames",
),
reply_handler,
)
signal.signal(signal.SIGINT, signal.SIG_DFL)
main.run()
dbus-fast-2.44.1/examples/mpris.py 0000775 0000000 0000000 00000002447 14773556132 0017043 0 ustar 00root root 0000000 0000000 #!/usr/bin/env python3
import os
import sys
sys.path.append(os.path.abspath(os.path.dirname(__file__) + "/.."))
import asyncio
from dbus_fast.aio import MessageBus
async def main():
bus = await MessageBus().connect()
# the introspection xml would normally be included in your project, but
# this is convenient for development
introspection = await bus.introspect(
"org.mpris.MediaPlayer2.vlc", "/org/mpris/MediaPlayer2"
)
obj = bus.get_proxy_object(
"org.mpris.MediaPlayer2.vlc", "/org/mpris/MediaPlayer2", introspection
)
player = obj.get_interface("org.mpris.MediaPlayer2.Player")
properties = obj.get_interface("org.freedesktop.DBus.Properties")
# call methods on the interface (this causes the media player to play)
await player.call_play()
volume = await player.get_volume()
print(f"current volume: {volume}, setting to 0.5")
await player.set_volume(0.5)
# listen to signals
def on_properties_changed(
interface_name, changed_properties, invalidated_properties
):
for changed, variant in changed_properties.items():
print(f"property changed: {changed} - {variant.value}")
properties.on_properties_changed(on_properties_changed)
await bus.wait_for_disconnect()
asyncio.run(main())
dbus-fast-2.44.1/poetry.lock 0000664 0000000 0000000 00000310736 14773556132 0015715 0 ustar 00root root 0000000 0000000 # This file is automatically @generated by Poetry 2.1.1 and should not be changed by hand.
[[package]]
name = "alabaster"
version = "0.7.16"
description = "A light, configurable Sphinx theme"
optional = false
python-versions = ">=3.9"
groups = ["docs"]
files = [
{file = "alabaster-0.7.16-py3-none-any.whl", hash = "sha256:b46733c07dce03ae4e150330b975c75737fa60f0a7c591b6c8bf4928a28e2c92"},
{file = "alabaster-0.7.16.tar.gz", hash = "sha256:75a8b99c28a5dad50dd7f8ccdd447a121ddb3892da9e53d1ca5cca3106d58d65"},
]
[[package]]
name = "babel"
version = "2.17.0"
description = "Internationalization utilities"
optional = false
python-versions = ">=3.8"
groups = ["docs"]
files = [
{file = "babel-2.17.0-py3-none-any.whl", hash = "sha256:4d0b53093fdfb4b21c92b5213dba5a1b23885afa8383709427046b21c366e5f2"},
{file = "babel-2.17.0.tar.gz", hash = "sha256:0c54cffb19f690cdcc52a3b50bcbf71e07a808d1c80d549f2459b9d2cf0afb9d"},
]
[package.extras]
dev = ["backports.zoneinfo ; python_version < \"3.9\"", "freezegun (>=1.0,<2.0)", "jinja2 (>=3.0)", "pytest (>=6.0)", "pytest-cov", "pytz", "setuptools", "tzdata ; sys_platform == \"win32\""]
[[package]]
name = "certifi"
version = "2025.1.31"
description = "Python package for providing Mozilla's CA Bundle."
optional = false
python-versions = ">=3.6"
groups = ["docs"]
files = [
{file = "certifi-2025.1.31-py3-none-any.whl", hash = "sha256:ca78db4565a652026a4db2bcdf68f2fb589ea80d0be70e03929ed730746b84fe"},
{file = "certifi-2025.1.31.tar.gz", hash = "sha256:3d5da6925056f6f18f119200434a4780a94263f10d1c21d032a6f6b2baa20651"},
]
[[package]]
name = "cffi"
version = "1.17.1"
description = "Foreign Function Interface for Python calling C code."
optional = false
python-versions = ">=3.8"
groups = ["dev"]
files = [
{file = "cffi-1.17.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:df8b1c11f177bc2313ec4b2d46baec87a5f3e71fc8b45dab2ee7cae86d9aba14"},
{file = "cffi-1.17.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8f2cdc858323644ab277e9bb925ad72ae0e67f69e804f4898c070998d50b1a67"},
{file = "cffi-1.17.1-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:edae79245293e15384b51f88b00613ba9f7198016a5948b5dddf4917d4d26382"},
{file = "cffi-1.17.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:45398b671ac6d70e67da8e4224a065cec6a93541bb7aebe1b198a61b58c7b702"},
{file = "cffi-1.17.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ad9413ccdeda48c5afdae7e4fa2192157e991ff761e7ab8fdd8926f40b160cc3"},
{file = "cffi-1.17.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5da5719280082ac6bd9aa7becb3938dc9f9cbd57fac7d2871717b1feb0902ab6"},
{file = "cffi-1.17.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2bb1a08b8008b281856e5971307cc386a8e9c5b625ac297e853d36da6efe9c17"},
{file = "cffi-1.17.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:045d61c734659cc045141be4bae381a41d89b741f795af1dd018bfb532fd0df8"},
{file = "cffi-1.17.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:6883e737d7d9e4899a8a695e00ec36bd4e5e4f18fabe0aca0efe0a4b44cdb13e"},
{file = "cffi-1.17.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:6b8b4a92e1c65048ff98cfe1f735ef8f1ceb72e3d5f0c25fdb12087a23da22be"},
{file = "cffi-1.17.1-cp310-cp310-win32.whl", hash = "sha256:c9c3d058ebabb74db66e431095118094d06abf53284d9c81f27300d0e0d8bc7c"},
{file = "cffi-1.17.1-cp310-cp310-win_amd64.whl", hash = "sha256:0f048dcf80db46f0098ccac01132761580d28e28bc0f78ae0d58048063317e15"},
{file = "cffi-1.17.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:a45e3c6913c5b87b3ff120dcdc03f6131fa0065027d0ed7ee6190736a74cd401"},
{file = "cffi-1.17.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:30c5e0cb5ae493c04c8b42916e52ca38079f1b235c2f8ae5f4527b963c401caf"},
{file = "cffi-1.17.1-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f75c7ab1f9e4aca5414ed4d8e5c0e303a34f4421f8a0d47a4d019ceff0ab6af4"},
{file = "cffi-1.17.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a1ed2dd2972641495a3ec98445e09766f077aee98a1c896dcb4ad0d303628e41"},
{file = "cffi-1.17.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:46bf43160c1a35f7ec506d254e5c890f3c03648a4dbac12d624e4490a7046cd1"},
{file = "cffi-1.17.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a24ed04c8ffd54b0729c07cee15a81d964e6fee0e3d4d342a27b020d22959dc6"},
{file = "cffi-1.17.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:610faea79c43e44c71e1ec53a554553fa22321b65fae24889706c0a84d4ad86d"},
{file = "cffi-1.17.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:a9b15d491f3ad5d692e11f6b71f7857e7835eb677955c00cc0aefcd0669adaf6"},
{file = "cffi-1.17.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:de2ea4b5833625383e464549fec1bc395c1bdeeb5f25c4a3a82b5a8c756ec22f"},
{file = "cffi-1.17.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:fc48c783f9c87e60831201f2cce7f3b2e4846bf4d8728eabe54d60700b318a0b"},
{file = "cffi-1.17.1-cp311-cp311-win32.whl", hash = "sha256:85a950a4ac9c359340d5963966e3e0a94a676bd6245a4b55bc43949eee26a655"},
{file = "cffi-1.17.1-cp311-cp311-win_amd64.whl", hash = "sha256:caaf0640ef5f5517f49bc275eca1406b0ffa6aa184892812030f04c2abf589a0"},
{file = "cffi-1.17.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:805b4371bf7197c329fcb3ead37e710d1bca9da5d583f5073b799d5c5bd1eee4"},
{file = "cffi-1.17.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:733e99bc2df47476e3848417c5a4540522f234dfd4ef3ab7fafdf555b082ec0c"},
{file = "cffi-1.17.1-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1257bdabf294dceb59f5e70c64a3e2f462c30c7ad68092d01bbbfb1c16b1ba36"},
{file = "cffi-1.17.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da95af8214998d77a98cc14e3a3bd00aa191526343078b530ceb0bd710fb48a5"},
{file = "cffi-1.17.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d63afe322132c194cf832bfec0dc69a99fb9bb6bbd550f161a49e9e855cc78ff"},
{file = "cffi-1.17.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f79fc4fc25f1c8698ff97788206bb3c2598949bfe0fef03d299eb1b5356ada99"},
{file = "cffi-1.17.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b62ce867176a75d03a665bad002af8e6d54644fad99a3c70905c543130e39d93"},
{file = "cffi-1.17.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:386c8bf53c502fff58903061338ce4f4950cbdcb23e2902d86c0f722b786bbe3"},
{file = "cffi-1.17.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:4ceb10419a9adf4460ea14cfd6bc43d08701f0835e979bf821052f1805850fe8"},
{file = "cffi-1.17.1-cp312-cp312-win32.whl", hash = "sha256:a08d7e755f8ed21095a310a693525137cfe756ce62d066e53f502a83dc550f65"},
{file = "cffi-1.17.1-cp312-cp312-win_amd64.whl", hash = "sha256:51392eae71afec0d0c8fb1a53b204dbb3bcabcb3c9b807eedf3e1e6ccf2de903"},
{file = "cffi-1.17.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f3a2b4222ce6b60e2e8b337bb9596923045681d71e5a082783484d845390938e"},
{file = "cffi-1.17.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:0984a4925a435b1da406122d4d7968dd861c1385afe3b45ba82b750f229811e2"},
{file = "cffi-1.17.1-cp313-cp313-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d01b12eeeb4427d3110de311e1774046ad344f5b1a7403101878976ecd7a10f3"},
{file = "cffi-1.17.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:706510fe141c86a69c8ddc029c7910003a17353970cff3b904ff0686a5927683"},
{file = "cffi-1.17.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:de55b766c7aa2e2a3092c51e0483d700341182f08e67c63630d5b6f200bb28e5"},
{file = "cffi-1.17.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c59d6e989d07460165cc5ad3c61f9fd8f1b4796eacbd81cee78957842b834af4"},
{file = "cffi-1.17.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd398dbc6773384a17fe0d3e7eeb8d1a21c2200473ee6806bb5e6a8e62bb73dd"},
{file = "cffi-1.17.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:3edc8d958eb099c634dace3c7e16560ae474aa3803a5df240542b305d14e14ed"},
{file = "cffi-1.17.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:72e72408cad3d5419375fc87d289076ee319835bdfa2caad331e377589aebba9"},
{file = "cffi-1.17.1-cp313-cp313-win32.whl", hash = "sha256:e03eab0a8677fa80d646b5ddece1cbeaf556c313dcfac435ba11f107ba117b5d"},
{file = "cffi-1.17.1-cp313-cp313-win_amd64.whl", hash = "sha256:f6a16c31041f09ead72d69f583767292f750d24913dadacf5756b966aacb3f1a"},
{file = "cffi-1.17.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:636062ea65bd0195bc012fea9321aca499c0504409f413dc88af450b57ffd03b"},
{file = "cffi-1.17.1-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c7eac2ef9b63c79431bc4b25f1cd649d7f061a28808cbc6c47b534bd789ef964"},
{file = "cffi-1.17.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e221cf152cff04059d011ee126477f0d9588303eb57e88923578ace7baad17f9"},
{file = "cffi-1.17.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:31000ec67d4221a71bd3f67df918b1f88f676f1c3b535a7eb473255fdc0b83fc"},
{file = "cffi-1.17.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6f17be4345073b0a7b8ea599688f692ac3ef23ce28e5df79c04de519dbc4912c"},
{file = "cffi-1.17.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0e2b1fac190ae3ebfe37b979cc1ce69c81f4e4fe5746bb401dca63a9062cdaf1"},
{file = "cffi-1.17.1-cp38-cp38-win32.whl", hash = "sha256:7596d6620d3fa590f677e9ee430df2958d2d6d6de2feeae5b20e82c00b76fbf8"},
{file = "cffi-1.17.1-cp38-cp38-win_amd64.whl", hash = "sha256:78122be759c3f8a014ce010908ae03364d00a1f81ab5c7f4a7a5120607ea56e1"},
{file = "cffi-1.17.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:b2ab587605f4ba0bf81dc0cb08a41bd1c0a5906bd59243d56bad7668a6fc6c16"},
{file = "cffi-1.17.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:28b16024becceed8c6dfbc75629e27788d8a3f9030691a1dbf9821a128b22c36"},
{file = "cffi-1.17.1-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1d599671f396c4723d016dbddb72fe8e0397082b0a77a4fab8028923bec050e8"},
{file = "cffi-1.17.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ca74b8dbe6e8e8263c0ffd60277de77dcee6c837a3d0881d8c1ead7268c9e576"},
{file = "cffi-1.17.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f7f5baafcc48261359e14bcd6d9bff6d4b28d9103847c9e136694cb0501aef87"},
{file = "cffi-1.17.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:98e3969bcff97cae1b2def8ba499ea3d6f31ddfdb7635374834cf89a1a08ecf0"},
{file = "cffi-1.17.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cdf5ce3acdfd1661132f2a9c19cac174758dc2352bfe37d98aa7512c6b7178b3"},
{file = "cffi-1.17.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:9755e4345d1ec879e3849e62222a18c7174d65a6a92d5b346b1863912168b595"},
{file = "cffi-1.17.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:f1e22e8c4419538cb197e4dd60acc919d7696e5ef98ee4da4e01d3f8cfa4cc5a"},
{file = "cffi-1.17.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:c03e868a0b3bc35839ba98e74211ed2b05d2119be4e8a0f224fba9384f1fe02e"},
{file = "cffi-1.17.1-cp39-cp39-win32.whl", hash = "sha256:e31ae45bc2e29f6b2abd0de1cc3b9d5205aa847cafaecb8af1476a609a2f6eb7"},
{file = "cffi-1.17.1-cp39-cp39-win_amd64.whl", hash = "sha256:d016c76bdd850f3c626af19b0542c9677ba156e4ee4fccfdd7848803533ef662"},
{file = "cffi-1.17.1.tar.gz", hash = "sha256:1c39c6016c32bc48dd54561950ebd6836e1670f2ae46128f67cf49e789c52824"},
]
[package.dependencies]
pycparser = "*"
[[package]]
name = "charset-normalizer"
version = "3.4.1"
description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet."
optional = false
python-versions = ">=3.7"
groups = ["docs"]
files = [
{file = "charset_normalizer-3.4.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:91b36a978b5ae0ee86c394f5a54d6ef44db1de0815eb43de826d41d21e4af3de"},
{file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7461baadb4dc00fd9e0acbe254e3d7d2112e7f92ced2adc96e54ef6501c5f176"},
{file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e218488cd232553829be0664c2292d3af2eeeb94b32bea483cf79ac6a694e037"},
{file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:80ed5e856eb7f30115aaf94e4a08114ccc8813e6ed1b5efa74f9f82e8509858f"},
{file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b010a7a4fd316c3c484d482922d13044979e78d1861f0e0650423144c616a46a"},
{file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4532bff1b8421fd0a320463030c7520f56a79c9024a4e88f01c537316019005a"},
{file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d973f03c0cb71c5ed99037b870f2be986c3c05e63622c017ea9816881d2dd247"},
{file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:3a3bd0dcd373514dcec91c411ddb9632c0d7d92aed7093b8c3bbb6d69ca74408"},
{file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:d9c3cdf5390dcd29aa8056d13e8e99526cda0305acc038b96b30352aff5ff2bb"},
{file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:2bdfe3ac2e1bbe5b59a1a63721eb3b95fc9b6817ae4a46debbb4e11f6232428d"},
{file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:eab677309cdb30d047996b36d34caeda1dc91149e4fdca0b1a039b3f79d9a807"},
{file = "charset_normalizer-3.4.1-cp310-cp310-win32.whl", hash = "sha256:c0429126cf75e16c4f0ad00ee0eae4242dc652290f940152ca8c75c3a4b6ee8f"},
{file = "charset_normalizer-3.4.1-cp310-cp310-win_amd64.whl", hash = "sha256:9f0b8b1c6d84c8034a44893aba5e767bf9c7a211e313a9605d9c617d7083829f"},
{file = "charset_normalizer-3.4.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:8bfa33f4f2672964266e940dd22a195989ba31669bd84629f05fab3ef4e2d125"},
{file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:28bf57629c75e810b6ae989f03c0828d64d6b26a5e205535585f96093e405ed1"},
{file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f08ff5e948271dc7e18a35641d2f11a4cd8dfd5634f55228b691e62b37125eb3"},
{file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:234ac59ea147c59ee4da87a0c0f098e9c8d169f4dc2a159ef720f1a61bbe27cd"},
{file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd4ec41f914fa74ad1b8304bbc634b3de73d2a0889bd32076342a573e0779e00"},
{file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eea6ee1db730b3483adf394ea72f808b6e18cf3cb6454b4d86e04fa8c4327a12"},
{file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c96836c97b1238e9c9e3fe90844c947d5afbf4f4c92762679acfe19927d81d77"},
{file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4d86f7aff21ee58f26dcf5ae81a9addbd914115cdebcbb2217e4f0ed8982e146"},
{file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:09b5e6733cbd160dcc09589227187e242a30a49ca5cefa5a7edd3f9d19ed53fd"},
{file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:5777ee0881f9499ed0f71cc82cf873d9a0ca8af166dfa0af8ec4e675b7df48e6"},
{file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:237bdbe6159cff53b4f24f397d43c6336c6b0b42affbe857970cefbb620911c8"},
{file = "charset_normalizer-3.4.1-cp311-cp311-win32.whl", hash = "sha256:8417cb1f36cc0bc7eaba8ccb0e04d55f0ee52df06df3ad55259b9a323555fc8b"},
{file = "charset_normalizer-3.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:d7f50a1f8c450f3925cb367d011448c39239bb3eb4117c36a6d354794de4ce76"},
{file = "charset_normalizer-3.4.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:73d94b58ec7fecbc7366247d3b0b10a21681004153238750bb67bd9012414545"},
{file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dad3e487649f498dd991eeb901125411559b22e8d7ab25d3aeb1af367df5efd7"},
{file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c30197aa96e8eed02200a83fba2657b4c3acd0f0aa4bdc9f6c1af8e8962e0757"},
{file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2369eea1ee4a7610a860d88f268eb39b95cb588acd7235e02fd5a5601773d4fa"},
{file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc2722592d8998c870fa4e290c2eec2c1569b87fe58618e67d38b4665dfa680d"},
{file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffc9202a29ab3920fa812879e95a9e78b2465fd10be7fcbd042899695d75e616"},
{file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:804a4d582ba6e5b747c625bf1255e6b1507465494a40a2130978bda7b932c90b"},
{file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:0f55e69f030f7163dffe9fd0752b32f070566451afe180f99dbeeb81f511ad8d"},
{file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:c4c3e6da02df6fa1410a7680bd3f63d4f710232d3139089536310d027950696a"},
{file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:5df196eb874dae23dcfb968c83d4f8fdccb333330fe1fc278ac5ceeb101003a9"},
{file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e358e64305fe12299a08e08978f51fc21fac060dcfcddd95453eabe5b93ed0e1"},
{file = "charset_normalizer-3.4.1-cp312-cp312-win32.whl", hash = "sha256:9b23ca7ef998bc739bf6ffc077c2116917eabcc901f88da1b9856b210ef63f35"},
{file = "charset_normalizer-3.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:6ff8a4a60c227ad87030d76e99cd1698345d4491638dfa6673027c48b3cd395f"},
{file = "charset_normalizer-3.4.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:aabfa34badd18f1da5ec1bc2715cadc8dca465868a4e73a0173466b688f29dda"},
{file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22e14b5d70560b8dd51ec22863f370d1e595ac3d024cb8ad7d308b4cd95f8313"},
{file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8436c508b408b82d87dc5f62496973a1805cd46727c34440b0d29d8a2f50a6c9"},
{file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2d074908e1aecee37a7635990b2c6d504cd4766c7bc9fc86d63f9c09af3fa11b"},
{file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:955f8851919303c92343d2f66165294848d57e9bba6cf6e3625485a70a038d11"},
{file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:44ecbf16649486d4aebafeaa7ec4c9fed8b88101f4dd612dcaf65d5e815f837f"},
{file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:0924e81d3d5e70f8126529951dac65c1010cdf117bb75eb02dd12339b57749dd"},
{file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:2967f74ad52c3b98de4c3b32e1a44e32975e008a9cd2a8cc8966d6a5218c5cb2"},
{file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:c75cb2a3e389853835e84a2d8fb2b81a10645b503eca9bcb98df6b5a43eb8886"},
{file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:09b26ae6b1abf0d27570633b2b078a2a20419c99d66fb2823173d73f188ce601"},
{file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:fa88b843d6e211393a37219e6a1c1df99d35e8fd90446f1118f4216e307e48cd"},
{file = "charset_normalizer-3.4.1-cp313-cp313-win32.whl", hash = "sha256:eb8178fe3dba6450a3e024e95ac49ed3400e506fd4e9e5c32d30adda88cbd407"},
{file = "charset_normalizer-3.4.1-cp313-cp313-win_amd64.whl", hash = "sha256:b1ac5992a838106edb89654e0aebfc24f5848ae2547d22c2c3f66454daa11971"},
{file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f30bf9fd9be89ecb2360c7d94a711f00c09b976258846efe40db3d05828e8089"},
{file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:97f68b8d6831127e4787ad15e6757232e14e12060bec17091b85eb1486b91d8d"},
{file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7974a0b5ecd505609e3b19742b60cee7aa2aa2fb3151bc917e6e2646d7667dcf"},
{file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fc54db6c8593ef7d4b2a331b58653356cf04f67c960f584edb7c3d8c97e8f39e"},
{file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:311f30128d7d333eebd7896965bfcfbd0065f1716ec92bd5638d7748eb6f936a"},
{file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:7d053096f67cd1241601111b698f5cad775f97ab25d81567d3f59219b5f1adbd"},
{file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:807f52c1f798eef6cf26beb819eeb8819b1622ddfeef9d0977a8502d4db6d534"},
{file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:dccbe65bd2f7f7ec22c4ff99ed56faa1e9f785482b9bbd7c717e26fd723a1d1e"},
{file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:2fb9bd477fdea8684f78791a6de97a953c51831ee2981f8e4f583ff3b9d9687e"},
{file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:01732659ba9b5b873fc117534143e4feefecf3b2078b0a6a2e925271bb6f4cfa"},
{file = "charset_normalizer-3.4.1-cp37-cp37m-win32.whl", hash = "sha256:7a4f97a081603d2050bfaffdefa5b02a9ec823f8348a572e39032caa8404a487"},
{file = "charset_normalizer-3.4.1-cp37-cp37m-win_amd64.whl", hash = "sha256:7b1bef6280950ee6c177b326508f86cad7ad4dff12454483b51d8b7d673a2c5d"},
{file = "charset_normalizer-3.4.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:ecddf25bee22fe4fe3737a399d0d177d72bc22be6913acfab364b40bce1ba83c"},
{file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c60ca7339acd497a55b0ea5d506b2a2612afb2826560416f6894e8b5770d4a9"},
{file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b7b2d86dd06bfc2ade3312a83a5c364c7ec2e3498f8734282c6c3d4b07b346b8"},
{file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dd78cfcda14a1ef52584dbb008f7ac81c1328c0f58184bf9a84c49c605002da6"},
{file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e27f48bcd0957c6d4cb9d6fa6b61d192d0b13d5ef563e5f2ae35feafc0d179c"},
{file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:01ad647cdd609225c5350561d084b42ddf732f4eeefe6e678765636791e78b9a"},
{file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:619a609aa74ae43d90ed2e89bdd784765de0a25ca761b93e196d938b8fd1dbbd"},
{file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:89149166622f4db9b4b6a449256291dc87a99ee53151c74cbd82a53c8c2f6ccd"},
{file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:7709f51f5f7c853f0fb938bcd3bc59cdfdc5203635ffd18bf354f6967ea0f824"},
{file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:345b0426edd4e18138d6528aed636de7a9ed169b4aaf9d61a8c19e39d26838ca"},
{file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:0907f11d019260cdc3f94fbdb23ff9125f6b5d1039b76003b5b0ac9d6a6c9d5b"},
{file = "charset_normalizer-3.4.1-cp38-cp38-win32.whl", hash = "sha256:ea0d8d539afa5eb2728aa1932a988a9a7af94f18582ffae4bc10b3fbdad0626e"},
{file = "charset_normalizer-3.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:329ce159e82018d646c7ac45b01a430369d526569ec08516081727a20e9e4af4"},
{file = "charset_normalizer-3.4.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:b97e690a2118911e39b4042088092771b4ae3fc3aa86518f84b8cf6888dbdb41"},
{file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:78baa6d91634dfb69ec52a463534bc0df05dbd546209b79a3880a34487f4b84f"},
{file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1a2bc9f351a75ef49d664206d51f8e5ede9da246602dc2d2726837620ea034b2"},
{file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:75832c08354f595c760a804588b9357d34ec00ba1c940c15e31e96d902093770"},
{file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0af291f4fe114be0280cdd29d533696a77b5b49cfde5467176ecab32353395c4"},
{file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0167ddc8ab6508fe81860a57dd472b2ef4060e8d378f0cc555707126830f2537"},
{file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:2a75d49014d118e4198bcee5ee0a6f25856b29b12dbf7cd012791f8a6cc5c496"},
{file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:363e2f92b0f0174b2f8238240a1a30142e3db7b957a5dd5689b0e75fb717cc78"},
{file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:ab36c8eb7e454e34e60eb55ca5d241a5d18b2c6244f6827a30e451c42410b5f7"},
{file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:4c0907b1928a36d5a998d72d64d8eaa7244989f7aaaf947500d3a800c83a3fd6"},
{file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:04432ad9479fa40ec0f387795ddad4437a2b50417c69fa275e212933519ff294"},
{file = "charset_normalizer-3.4.1-cp39-cp39-win32.whl", hash = "sha256:3bed14e9c89dcb10e8f3a29f9ccac4955aebe93c71ae803af79265c9ca5644c5"},
{file = "charset_normalizer-3.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:49402233c892a461407c512a19435d1ce275543138294f7ef013f0b63d5d3765"},
{file = "charset_normalizer-3.4.1-py3-none-any.whl", hash = "sha256:d98b1668f06378c6dbefec3b92299716b931cd4e6061f3c875a71ced1780ab85"},
{file = "charset_normalizer-3.4.1.tar.gz", hash = "sha256:44251f18cd68a75b56585dd00dae26183e102cd5e0f9f1466e6df5da2ed64ea3"},
]
[[package]]
name = "colorama"
version = "0.4.6"
description = "Cross-platform colored terminal text."
optional = false
python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7"
groups = ["dev", "docs"]
markers = "sys_platform == \"win32\""
files = [
{file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"},
{file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"},
]
[[package]]
name = "covdefaults"
version = "2.3.0"
description = "A coverage plugin to provide sensible default settings"
optional = false
python-versions = ">=3.7"
groups = ["dev"]
files = [
{file = "covdefaults-2.3.0-py2.py3-none-any.whl", hash = "sha256:2832961f6ffcfe4b57c338bc3418a3526f495c26fb9c54565409c5532f7c41be"},
{file = "covdefaults-2.3.0.tar.gz", hash = "sha256:4e99f679f12d792bc62e5510fa3eb59546ed47bd569e36e4fddc4081c9c3ebf7"},
]
[package.dependencies]
coverage = ">=6.0.2"
[[package]]
name = "coverage"
version = "7.7.0"
description = "Code coverage measurement for Python"
optional = false
python-versions = ">=3.9"
groups = ["dev"]
files = [
{file = "coverage-7.7.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a538a23119d1e2e2ce077e902d02ea3d8e0641786ef6e0faf11ce82324743944"},
{file = "coverage-7.7.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:1586ad158523f4133499a4f322b230e2cfef9cc724820dbd58595a5a236186f4"},
{file = "coverage-7.7.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7b6c96d69928a3a6767fab8dc1ce8a02cf0156836ccb1e820c7f45a423570d98"},
{file = "coverage-7.7.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7f18d47641282664276977c604b5a261e51fefc2980f5271d547d706b06a837f"},
{file = "coverage-7.7.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f2a1e18a85bd066c7c556d85277a7adf4651f259b2579113844835ba1a74aafd"},
{file = "coverage-7.7.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:70f0925c4e2bfc965369f417e7cc72538fd1ba91639cf1e4ef4b1a6b50439b3b"},
{file = "coverage-7.7.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:b0fac2088ec4aaeb5468b814bd3ff5e5978364bfbce5e567c44c9e2854469f6c"},
{file = "coverage-7.7.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b3e212a894d8ae07fde2ca8b43d666a6d49bbbddb10da0f6a74ca7bd31f20054"},
{file = "coverage-7.7.0-cp310-cp310-win32.whl", hash = "sha256:f32b165bf6dfea0846a9c9c38b7e1d68f313956d60a15cde5d1709fddcaf3bee"},
{file = "coverage-7.7.0-cp310-cp310-win_amd64.whl", hash = "sha256:a2454b12a3f12cc4698f3508912e6225ec63682e2ca5a96f80a2b93cef9e63f3"},
{file = "coverage-7.7.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:a0a207c87a9f743c8072d059b4711f8d13c456eb42dac778a7d2e5d4f3c253a7"},
{file = "coverage-7.7.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:2d673e3add00048215c2cc507f1228a7523fd8bf34f279ac98334c9b07bd2656"},
{file = "coverage-7.7.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f81fe93dc1b8e5673f33443c0786c14b77e36f1025973b85e07c70353e46882b"},
{file = "coverage-7.7.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d8c7524779003d59948c51b4fcbf1ca4e27c26a7d75984f63488f3625c328b9b"},
{file = "coverage-7.7.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4c124025430249118d018dcedc8b7426f39373527c845093132196f2a483b6dd"},
{file = "coverage-7.7.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:e7f559c36d5cdc448ee13e7e56ed7b6b5d44a40a511d584d388a0f5d940977ba"},
{file = "coverage-7.7.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:37cbc7b0d93dfd133e33c7ec01123fbb90401dce174c3b6661d8d36fb1e30608"},
{file = "coverage-7.7.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:7d2a65876274acf544703e943c010b60bd79404e3623a1e5d52b64a6e2728de5"},
{file = "coverage-7.7.0-cp311-cp311-win32.whl", hash = "sha256:f5a2f71d6a91238e7628f23538c26aa464d390cbdedf12ee2a7a0fb92a24482a"},
{file = "coverage-7.7.0-cp311-cp311-win_amd64.whl", hash = "sha256:ae8006772c6b0fa53c33747913473e064985dac4d65f77fd2fdc6474e7cd54e4"},
{file = "coverage-7.7.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:056d3017ed67e7ddf266e6f57378ece543755a4c9231e997789ab3bd11392c94"},
{file = "coverage-7.7.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:33c1394d8407e2771547583b66a85d07ed441ff8fae5a4adb4237ad39ece60db"},
{file = "coverage-7.7.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4fbb7a0c3c21908520149d7751cf5b74eb9b38b54d62997b1e9b3ac19a8ee2fe"},
{file = "coverage-7.7.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bb356e7ae7c2da13f404bf8f75be90f743c6df8d4607022e759f5d7d89fe83f8"},
{file = "coverage-7.7.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bce730d484038e97f27ea2dbe5d392ec5c2261f28c319a3bb266f6b213650135"},
{file = "coverage-7.7.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:aa4dff57fc21a575672176d5ab0ef15a927199e775c5e8a3d75162ab2b0c7705"},
{file = "coverage-7.7.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:b667b91f4f714b17af2a18e220015c941d1cf8b07c17f2160033dbe1e64149f0"},
{file = "coverage-7.7.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:693d921621a0c8043bfdc61f7d4df5ea6d22165fe8b807cac21eb80dd94e4bbd"},
{file = "coverage-7.7.0-cp312-cp312-win32.whl", hash = "sha256:52fc89602cde411a4196c8c6894afb384f2125f34c031774f82a4f2608c59d7d"},
{file = "coverage-7.7.0-cp312-cp312-win_amd64.whl", hash = "sha256:0ce8cf59e09d31a4915ff4c3b94c6514af4c84b22c4cc8ad7c3c546a86150a92"},
{file = "coverage-7.7.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:4545485fef7a8a2d8f30e6f79ce719eb154aab7e44217eb444c1d38239af2072"},
{file = "coverage-7.7.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:1393e5aa9441dafb0162c36c8506c648b89aea9565b31f6bfa351e66c11bcd82"},
{file = "coverage-7.7.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:316f29cc3392fa3912493ee4c83afa4a0e2db04ff69600711f8c03997c39baaa"},
{file = "coverage-7.7.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e1ffde1d6bc2a92f9c9207d1ad808550873748ac2d4d923c815b866baa343b3f"},
{file = "coverage-7.7.0-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:416e2a8845eaff288f97eaf76ab40367deafb9073ffc47bf2a583f26b05e5265"},
{file = "coverage-7.7.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:5efdeff5f353ed3352c04e6b318ab05c6ce9249c25ed3c2090c6e9cadda1e3b2"},
{file = "coverage-7.7.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:57f3bd0d29bf2bd9325c0ff9cc532a175110c4bf8f412c05b2405fd35745266d"},
{file = "coverage-7.7.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:3ab7090f04b12dc6469882ce81244572779d3a4b67eea1c96fb9ecc8c607ef39"},
{file = "coverage-7.7.0-cp313-cp313-win32.whl", hash = "sha256:180e3fc68ee4dc5af8b33b6ca4e3bb8aa1abe25eedcb958ba5cff7123071af68"},
{file = "coverage-7.7.0-cp313-cp313-win_amd64.whl", hash = "sha256:55143aa13c49491f5606f05b49ed88663446dce3a4d3c5d77baa4e36a16d3573"},
{file = "coverage-7.7.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:cc41374d2f27d81d6558f8a24e5c114580ffefc197fd43eabd7058182f743322"},
{file = "coverage-7.7.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:89078312f06237417adda7c021c33f80f7a6d2db8572a5f6c330d89b080061ce"},
{file = "coverage-7.7.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5b2f144444879363ea8834cd7b6869d79ac796cb8f864b0cfdde50296cd95816"},
{file = "coverage-7.7.0-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:60e6347d1ed882b1159ffea172cb8466ee46c665af4ca397edbf10ff53e9ffaf"},
{file = "coverage-7.7.0-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cb203c0afffaf1a8f5b9659a013f8f16a1b2cad3a80a8733ceedc968c0cf4c57"},
{file = "coverage-7.7.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:ad0edaa97cb983d9f2ff48cadddc3e1fb09f24aa558abeb4dc9a0dbacd12cbb4"},
{file = "coverage-7.7.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:c5f8a5364fc37b2f172c26a038bc7ec4885f429de4a05fc10fdcb53fb5834c5c"},
{file = "coverage-7.7.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:c4e09534037933bf6eb31d804e72c52ec23219b32c1730f9152feabbd7499463"},
{file = "coverage-7.7.0-cp313-cp313t-win32.whl", hash = "sha256:1b336d06af14f8da5b1f391e8dec03634daf54dfcb4d1c4fb6d04c09d83cef90"},
{file = "coverage-7.7.0-cp313-cp313t-win_amd64.whl", hash = "sha256:b54a1ee4c6f1905a436cbaa04b26626d27925a41cbc3a337e2d3ff7038187f07"},
{file = "coverage-7.7.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:1c8fbce80b2b8bf135d105aa8f5b36eae0c57d702a1cc3ebdea2a6f03f6cdde5"},
{file = "coverage-7.7.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:d9710521f07f526de30ccdead67e6b236fe996d214e1a7fba8b36e2ba2cd8261"},
{file = "coverage-7.7.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7789e700f33f2b133adae582c9f437523cd5db8de845774988a58c360fc88253"},
{file = "coverage-7.7.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b8c36093aca722db73633cf2359026ed7782a239eb1c6db2abcff876012dc4cf"},
{file = "coverage-7.7.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c075d167a6ec99b798c1fdf6e391a1d5a2d054caffe9593ba0f97e3df2c04f0e"},
{file = "coverage-7.7.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:d013c07061751ae81861cae6ec3a4fe04e84781b11fd4b6b4201590234b25c7b"},
{file = "coverage-7.7.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:104bf640f408f4e115b85110047c7f27377e1a8b7ba86f7db4fa47aa49dc9a8e"},
{file = "coverage-7.7.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:39abcacd1ed54e2c33c54bdc488b310e8ef6705833f7148b6eb9a547199d375d"},
{file = "coverage-7.7.0-cp39-cp39-win32.whl", hash = "sha256:8e336b56301774ace6be0017ff85c3566c556d938359b61b840796a0202f805c"},
{file = "coverage-7.7.0-cp39-cp39-win_amd64.whl", hash = "sha256:8c938c6ae59be67ac19a7204e079efc94b38222cd7d0269f96e45e18cddeaa59"},
{file = "coverage-7.7.0-pp39.pp310.pp311-none-any.whl", hash = "sha256:3b0e6e54591ae0d7427def8a4d40fca99df6b899d10354bab73cd5609807261c"},
{file = "coverage-7.7.0-py3-none-any.whl", hash = "sha256:708f0a1105ef2b11c79ed54ed31f17e6325ac936501fc373f24be3e6a578146a"},
{file = "coverage-7.7.0.tar.gz", hash = "sha256:cd879d4646055a573775a1cec863d00c9ff8c55860f8b17f6d8eee9140c06166"},
]
[package.dependencies]
tomli = {version = "*", optional = true, markers = "python_full_version <= \"3.11.0a6\" and extra == \"toml\""}
[package.extras]
toml = ["tomli ; python_full_version <= \"3.11.0a6\""]
[[package]]
name = "cython"
version = "3.0.12"
description = "The Cython compiler for writing C extensions in the Python language."
optional = false
python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7"
groups = ["dev"]
files = [
{file = "Cython-3.0.12-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ba67eee9413b66dd9fbacd33f0bc2e028a2a120991d77b5fd4b19d0b1e4039b9"},
{file = "Cython-3.0.12-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bee2717e5b5f7d966d0c6e27d2efe3698c357aa4d61bb3201997c7a4f9fe485a"},
{file = "Cython-3.0.12-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7cffc3464f641c8d0dda942c7c53015291beea11ec4d32421bed2f13b386b819"},
{file = "Cython-3.0.12-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d3a8f81980ffbd74e52f9186d8f1654e347d0c44bfea6b5997028977f481a179"},
{file = "Cython-3.0.12-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:8d32856716c369d01f2385ad9177cdd1a11079ac89ea0932dc4882de1aa19174"},
{file = "Cython-3.0.12-cp310-cp310-win32.whl", hash = "sha256:712c3f31adec140dc60d064a7f84741f50e2c25a8edd7ae746d5eb4d3ef7072a"},
{file = "Cython-3.0.12-cp310-cp310-win_amd64.whl", hash = "sha256:d6945694c5b9170cfbd5f2c0d00ef7487a2de7aba83713a64ee4ebce7fad9e05"},
{file = "Cython-3.0.12-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:feb86122a823937cc06e4c029d80ff69f082ebb0b959ab52a5af6cdd271c5dc3"},
{file = "Cython-3.0.12-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dfdbea486e702c328338314adb8e80f5f9741f06a0ae83aaec7463bc166d12e8"},
{file = "Cython-3.0.12-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:563de1728c8e48869d2380a1b76bbc1b1b1d01aba948480d68c1d05e52d20c92"},
{file = "Cython-3.0.12-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:398d4576c1e1f6316282aa0b4a55139254fbed965cba7813e6d9900d3092b128"},
{file = "Cython-3.0.12-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:1e5eadef80143026944ea8f9904715a008f5108d1d644a89f63094cc37351e73"},
{file = "Cython-3.0.12-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:5a93cbda00a5451175b97dea5a9440a3fcee9e54b4cba7a7dbcba9a764b22aec"},
{file = "Cython-3.0.12-cp311-cp311-win32.whl", hash = "sha256:3109e1d44425a2639e9a677b66cd7711721a5b606b65867cb2d8ef7a97e2237b"},
{file = "Cython-3.0.12-cp311-cp311-win_amd64.whl", hash = "sha256:d4b70fc339adba1e2111b074ee6119fe9fd6072c957d8597bce9a0dd1c3c6784"},
{file = "Cython-3.0.12-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:fe030d4a00afb2844f5f70896b7f2a1a0d7da09bf3aa3d884cbe5f73fff5d310"},
{file = "Cython-3.0.12-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a7fec4f052b8fe173fe70eae75091389955b9a23d5cec3d576d21c5913b49d47"},
{file = "Cython-3.0.12-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0faa5e39e5c8cdf6f9c3b1c3f24972826e45911e7f5b99cf99453fca5432f45e"},
{file = "Cython-3.0.12-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2d53de996ed340e9ab0fc85a88aaa8932f2591a2746e1ab1c06e262bd4ec4be7"},
{file = "Cython-3.0.12-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:ea3a0e19ab77266c738aa110684a753a04da4e709472cadeff487133354d6ab8"},
{file = "Cython-3.0.12-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:c151082884be468f2f405645858a857298ac7f7592729e5b54788b5c572717ba"},
{file = "Cython-3.0.12-cp312-cp312-win32.whl", hash = "sha256:3083465749911ac3b2ce001b6bf17f404ac9dd35d8b08469d19dc7e717f5877a"},
{file = "Cython-3.0.12-cp312-cp312-win_amd64.whl", hash = "sha256:c0b91c7ebace030dd558ea28730de8c580680b50768e5af66db2904a3716c3e3"},
{file = "Cython-3.0.12-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:4ee6f1ea1bead8e6cbc4e64571505b5d8dbdb3b58e679d31f3a84160cebf1a1a"},
{file = "Cython-3.0.12-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:57aefa6d3341109e46ec1a13e3a763aaa2cbeb14e82af2485b318194be1d9170"},
{file = "Cython-3.0.12-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:879ae9023958d63c0675015369384642d0afb9c9d1f3473df9186c42f7a9d265"},
{file = "Cython-3.0.12-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:36fcd584dae547de6f095500a380f4a0cce72b7a7e409e9ff03cb9beed6ac7a1"},
{file = "Cython-3.0.12-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:62b79dcc0de49efe9e84b9d0e2ae0a6fc9b14691a65565da727aa2e2e63c6a28"},
{file = "Cython-3.0.12-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4aa255781b093a8401109d8f2104bbb2e52de7639d5896aefafddc85c30e0894"},
{file = "Cython-3.0.12-cp313-cp313-win32.whl", hash = "sha256:77d48f2d4bab9fe1236eb753d18f03e8b2619af5b6f05d51df0532a92dfb38ab"},
{file = "Cython-3.0.12-cp313-cp313-win_amd64.whl", hash = "sha256:86c304b20bd57c727c7357e90d5ba1a2b6f1c45492de2373814d7745ef2e63b4"},
{file = "Cython-3.0.12-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:ff5c0b6a65b08117d0534941d404833d516dac422eee88c6b4fd55feb409a5ed"},
{file = "Cython-3.0.12-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:680f1d6ed4436ae94805db264d6155ed076d2835d84f20dcb31a7a3ad7f8668c"},
{file = "Cython-3.0.12-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ebc24609613fa06d0d896309f7164ba168f7e8d71c1e490ed2a08d23351c3f41"},
{file = "Cython-3.0.12-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c1879c073e2b34924ce9b7ca64c212705dcc416af4337c45f371242b2e5f6d32"},
{file = "Cython-3.0.12-cp36-cp36m-musllinux_1_2_aarch64.whl", hash = "sha256:bfb75123dd4ff767baa37d7036da0de2dfb6781ff256eef69b11b88b9a0691d1"},
{file = "Cython-3.0.12-cp36-cp36m-musllinux_1_2_x86_64.whl", hash = "sha256:f39640f8df0400cde6882e23c734f15bb8196de0a008ae5dc6c8d1ec5957d7c8"},
{file = "Cython-3.0.12-cp36-cp36m-win32.whl", hash = "sha256:8c9efe9a0895abee3cadfdad4130b30f7b5e57f6e6a51ef2a44f9fc66a913880"},
{file = "Cython-3.0.12-cp36-cp36m-win_amd64.whl", hash = "sha256:63d840f2975e44d74512f8f34f1f7cb8121c9428e26a3f6116ff273deb5e60a2"},
{file = "Cython-3.0.12-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:75c5acd40b97cff16fadcf6901a91586cbca5dcdba81f738efaf1f4c6bc8dccb"},
{file = "Cython-3.0.12-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e62564457851db1c40399bd95a5346b9bb99e17a819bf583b362f418d8f3457a"},
{file = "Cython-3.0.12-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ccd1228cc203b1f1b8a3d403f5a20ad1c40e5879b3fbf5851ce09d948982f2c"},
{file = "Cython-3.0.12-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:25529ee948f44d9a165ff960c49d4903267c20b5edf2df79b45924802e4cca6e"},
{file = "Cython-3.0.12-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:90cf599372c5a22120609f7d3a963f17814799335d56dd0dcf8fe615980a8ae1"},
{file = "Cython-3.0.12-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:9f8c48748a9c94ea5d59c26ab49ad0fad514d36f894985879cf3c3ca0e600bf4"},
{file = "Cython-3.0.12-cp37-cp37m-win32.whl", hash = "sha256:3e4fa855d98bc7bd6a2049e0c7dc0dcf595e2e7f571a26e808f3efd84d2db374"},
{file = "Cython-3.0.12-cp37-cp37m-win_amd64.whl", hash = "sha256:120681093772bf3600caddb296a65b352a0d3556e962b9b147efcfb8e8c9801b"},
{file = "Cython-3.0.12-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:731d719423e041242c9303c80cae4327467299b90ffe62d4cc407e11e9ea3160"},
{file = "Cython-3.0.12-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c3238a29f37999e27494d120983eca90d14896b2887a0bd858a381204549137a"},
{file = "Cython-3.0.12-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b588c0a089a9f4dd316d2f9275230bad4a7271e5af04e1dc41d2707c816be44b"},
{file = "Cython-3.0.12-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8ab9f5198af74eb16502cc143cdde9ca1cbbf66ea2912e67440dd18a36e3b5fa"},
{file = "Cython-3.0.12-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:8ee841c0e114efa1e849c281ac9b8df8aa189af10b4a103b1c5fd71cbb799679"},
{file = "Cython-3.0.12-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:43c48b5789398b228ea97499f5b864843ba9b1ab837562a9227c6f58d16ede8b"},
{file = "Cython-3.0.12-cp38-cp38-win32.whl", hash = "sha256:5e5f17c48a4f41557fbcc7ee660ccfebe4536a34c557f553b6893c1b3c83df2d"},
{file = "Cython-3.0.12-cp38-cp38-win_amd64.whl", hash = "sha256:309c081057930bb79dc9ea3061a1af5086c679c968206e9c9c2ec90ab7cb471a"},
{file = "Cython-3.0.12-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:54115fcc126840926ff3b53cfd2152eae17b3522ae7f74888f8a41413bd32f25"},
{file = "Cython-3.0.12-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:629db614b9c364596d7c975fa3fb3978e8c5349524353dbe11429896a783fc1e"},
{file = "Cython-3.0.12-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:af081838b0f9e12a83ec4c3809a00a64c817f489f7c512b0e3ecaf5f90a2a816"},
{file = "Cython-3.0.12-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:34ce459808f7d8d5d4007bc5486fe50532529096b43957af6cbffcb4d9cc5c8d"},
{file = "Cython-3.0.12-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:d6c6cd6a75c8393e6805d17f7126b96a894f310a1a9ea91c47d141fb9341bfa8"},
{file = "Cython-3.0.12-cp39-cp39-win32.whl", hash = "sha256:a4032e48d4734d2df68235d21920c715c451ac9de15fa14c71b378e8986b83be"},
{file = "Cython-3.0.12-cp39-cp39-win_amd64.whl", hash = "sha256:dcdc3e5d4ce0e7a4af6903ed580833015641e968d18d528d8371e2435a34132c"},
{file = "Cython-3.0.12-py2.py3-none-any.whl", hash = "sha256:0038c9bae46c459669390e53a1ec115f8096b2e4647ae007ff1bf4e6dee92806"},
{file = "cython-3.0.12.tar.gz", hash = "sha256:b988bb297ce76c671e28c97d017b95411010f7c77fa6623dd0bb47eed1aee1bc"},
]
[[package]]
name = "docutils"
version = "0.21.2"
description = "Docutils -- Python Documentation Utilities"
optional = false
python-versions = ">=3.9"
groups = ["docs"]
files = [
{file = "docutils-0.21.2-py3-none-any.whl", hash = "sha256:dafca5b9e384f0e419294eb4d2ff9fa826435bf15f15b7bd45723e8ad76811b2"},
{file = "docutils-0.21.2.tar.gz", hash = "sha256:3a6b18732edf182daa3cd12775bbb338cf5691468f91eeeb109deff6ebfa986f"},
]
[[package]]
name = "exceptiongroup"
version = "1.2.2"
description = "Backport of PEP 654 (exception groups)"
optional = false
python-versions = ">=3.7"
groups = ["dev"]
markers = "python_version < \"3.11\""
files = [
{file = "exceptiongroup-1.2.2-py3-none-any.whl", hash = "sha256:3111b9d131c238bec2f8f516e123e14ba243563fb135d3fe885990585aa7795b"},
{file = "exceptiongroup-1.2.2.tar.gz", hash = "sha256:47c2edf7c6738fafb49fd34290706d1a1a2f4d1c6df275526b62cbb4aa5393cc"},
]
[package.extras]
test = ["pytest (>=6)"]
[[package]]
name = "idna"
version = "3.10"
description = "Internationalized Domain Names in Applications (IDNA)"
optional = false
python-versions = ">=3.6"
groups = ["docs"]
files = [
{file = "idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3"},
{file = "idna-3.10.tar.gz", hash = "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9"},
]
[package.extras]
all = ["flake8 (>=7.1.1)", "mypy (>=1.11.2)", "pytest (>=8.3.2)", "ruff (>=0.6.2)"]
[[package]]
name = "imagesize"
version = "1.4.1"
description = "Getting image size from png/jpeg/jpeg2000/gif file"
optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
groups = ["docs"]
files = [
{file = "imagesize-1.4.1-py2.py3-none-any.whl", hash = "sha256:0d8d18d08f840c19d0ee7ca1fd82490fdc3729b7ac93f49870406ddde8ef8d8b"},
{file = "imagesize-1.4.1.tar.gz", hash = "sha256:69150444affb9cb0d5cc5a92b3676f0b2fb7cd9ae39e947a5e11a36b4497cd4a"},
]
[[package]]
name = "importlib-metadata"
version = "8.6.1"
description = "Read metadata from Python packages"
optional = false
python-versions = ">=3.9"
groups = ["dev", "docs"]
markers = "python_version < \"3.10\""
files = [
{file = "importlib_metadata-8.6.1-py3-none-any.whl", hash = "sha256:02a89390c1e15fdfdc0d7c6b25cb3e62650d0494005c97d6f148bf5b9787525e"},
{file = "importlib_metadata-8.6.1.tar.gz", hash = "sha256:310b41d755445d74569f993ccfc22838295d9fe005425094fad953d7f15c8580"},
]
[package.dependencies]
zipp = ">=3.20"
[package.extras]
check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1) ; sys_platform != \"cygwin\""]
cover = ["pytest-cov"]
doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"]
enabler = ["pytest-enabler (>=2.2)"]
perf = ["ipython"]
test = ["flufl.flake8", "importlib_resources (>=1.3) ; python_version < \"3.9\"", "jaraco.test (>=5.4)", "packaging", "pyfakefs", "pytest (>=6,!=8.1.*)", "pytest-perf (>=0.9.2)"]
type = ["pytest-mypy"]
[[package]]
name = "iniconfig"
version = "2.0.0"
description = "brain-dead simple config-ini parsing"
optional = false
python-versions = ">=3.7"
groups = ["dev"]
files = [
{file = "iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374"},
{file = "iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3"},
]
[[package]]
name = "jinja2"
version = "3.1.6"
description = "A very fast and expressive template engine."
optional = false
python-versions = ">=3.7"
groups = ["docs"]
files = [
{file = "jinja2-3.1.6-py3-none-any.whl", hash = "sha256:85ece4451f492d0c13c5dd7c13a64681a86afae63a5f347908daf103ce6d2f67"},
{file = "jinja2-3.1.6.tar.gz", hash = "sha256:0137fb05990d35f1275a587e9aee6d56da821fc83491a0fb838183be43f66d6d"},
]
[package.dependencies]
MarkupSafe = ">=2.0"
[package.extras]
i18n = ["Babel (>=2.7)"]
[[package]]
name = "markdown-it-py"
version = "3.0.0"
description = "Python port of markdown-it. Markdown parsing, done right!"
optional = false
python-versions = ">=3.8"
groups = ["dev", "docs"]
files = [
{file = "markdown-it-py-3.0.0.tar.gz", hash = "sha256:e3f60a94fa066dc52ec76661e37c851cb232d92f9886b15cb560aaada2df8feb"},
{file = "markdown_it_py-3.0.0-py3-none-any.whl", hash = "sha256:355216845c60bd96232cd8d8c40e8f9765cc86f46880e43a8fd22dc1a1a8cab1"},
]
[package.dependencies]
mdurl = ">=0.1,<1.0"
[package.extras]
benchmarking = ["psutil", "pytest", "pytest-benchmark"]
code-style = ["pre-commit (>=3.0,<4.0)"]
compare = ["commonmark (>=0.9,<1.0)", "markdown (>=3.4,<4.0)", "mistletoe (>=1.0,<2.0)", "mistune (>=2.0,<3.0)", "panflute (>=2.3,<3.0)"]
linkify = ["linkify-it-py (>=1,<3)"]
plugins = ["mdit-py-plugins"]
profiling = ["gprof2dot"]
rtd = ["jupyter_sphinx", "mdit-py-plugins", "myst-parser", "pyyaml", "sphinx", "sphinx-copybutton", "sphinx-design", "sphinx_book_theme"]
testing = ["coverage", "pytest", "pytest-cov", "pytest-regressions"]
[[package]]
name = "markupsafe"
version = "3.0.2"
description = "Safely add untrusted strings to HTML/XML markup."
optional = false
python-versions = ">=3.9"
groups = ["docs"]
files = [
{file = "MarkupSafe-3.0.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:7e94c425039cde14257288fd61dcfb01963e658efbc0ff54f5306b06054700f8"},
{file = "MarkupSafe-3.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9e2d922824181480953426608b81967de705c3cef4d1af983af849d7bd619158"},
{file = "MarkupSafe-3.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:38a9ef736c01fccdd6600705b09dc574584b89bea478200c5fbf112a6b0d5579"},
{file = "MarkupSafe-3.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bbcb445fa71794da8f178f0f6d66789a28d7319071af7a496d4d507ed566270d"},
{file = "MarkupSafe-3.0.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:57cb5a3cf367aeb1d316576250f65edec5bb3be939e9247ae594b4bcbc317dfb"},
{file = "MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:3809ede931876f5b2ec92eef964286840ed3540dadf803dd570c3b7e13141a3b"},
{file = "MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:e07c3764494e3776c602c1e78e298937c3315ccc9043ead7e685b7f2b8d47b3c"},
{file = "MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b424c77b206d63d500bcb69fa55ed8d0e6a3774056bdc4839fc9298a7edca171"},
{file = "MarkupSafe-3.0.2-cp310-cp310-win32.whl", hash = "sha256:fcabf5ff6eea076f859677f5f0b6b5c1a51e70a376b0579e0eadef8db48c6b50"},
{file = "MarkupSafe-3.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:6af100e168aa82a50e186c82875a5893c5597a0c1ccdb0d8b40240b1f28b969a"},
{file = "MarkupSafe-3.0.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:9025b4018f3a1314059769c7bf15441064b2207cb3f065e6ea1e7359cb46db9d"},
{file = "MarkupSafe-3.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:93335ca3812df2f366e80509ae119189886b0f3c2b81325d39efdb84a1e2ae93"},
{file = "MarkupSafe-3.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2cb8438c3cbb25e220c2ab33bb226559e7afb3baec11c4f218ffa7308603c832"},
{file = "MarkupSafe-3.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a123e330ef0853c6e822384873bef7507557d8e4a082961e1defa947aa59ba84"},
{file = "MarkupSafe-3.0.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1e084f686b92e5b83186b07e8a17fc09e38fff551f3602b249881fec658d3eca"},
{file = "MarkupSafe-3.0.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d8213e09c917a951de9d09ecee036d5c7d36cb6cb7dbaece4c71a60d79fb9798"},
{file = "MarkupSafe-3.0.2-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:5b02fb34468b6aaa40dfc198d813a641e3a63b98c2b05a16b9f80b7ec314185e"},
{file = "MarkupSafe-3.0.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:0bff5e0ae4ef2e1ae4fdf2dfd5b76c75e5c2fa4132d05fc1b0dabcd20c7e28c4"},
{file = "MarkupSafe-3.0.2-cp311-cp311-win32.whl", hash = "sha256:6c89876f41da747c8d3677a2b540fb32ef5715f97b66eeb0c6b66f5e3ef6f59d"},
{file = "MarkupSafe-3.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:70a87b411535ccad5ef2f1df5136506a10775d267e197e4cf531ced10537bd6b"},
{file = "MarkupSafe-3.0.2-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:9778bd8ab0a994ebf6f84c2b949e65736d5575320a17ae8984a77fab08db94cf"},
{file = "MarkupSafe-3.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:846ade7b71e3536c4e56b386c2a47adf5741d2d8b94ec9dc3e92e5e1ee1e2225"},
{file = "MarkupSafe-3.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1c99d261bd2d5f6b59325c92c73df481e05e57f19837bdca8413b9eac4bd8028"},
{file = "MarkupSafe-3.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e17c96c14e19278594aa4841ec148115f9c7615a47382ecb6b82bd8fea3ab0c8"},
{file = "MarkupSafe-3.0.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:88416bd1e65dcea10bc7569faacb2c20ce071dd1f87539ca2ab364bf6231393c"},
{file = "MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:2181e67807fc2fa785d0592dc2d6206c019b9502410671cc905d132a92866557"},
{file = "MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:52305740fe773d09cffb16f8ed0427942901f00adedac82ec8b67752f58a1b22"},
{file = "MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ad10d3ded218f1039f11a75f8091880239651b52e9bb592ca27de44eed242a48"},
{file = "MarkupSafe-3.0.2-cp312-cp312-win32.whl", hash = "sha256:0f4ca02bea9a23221c0182836703cbf8930c5e9454bacce27e767509fa286a30"},
{file = "MarkupSafe-3.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:8e06879fc22a25ca47312fbe7c8264eb0b662f6db27cb2d3bbbc74b1df4b9b87"},
{file = "MarkupSafe-3.0.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ba9527cdd4c926ed0760bc301f6728ef34d841f405abf9d4f959c478421e4efd"},
{file = "MarkupSafe-3.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f8b3d067f2e40fe93e1ccdd6b2e1d16c43140e76f02fb1319a05cf2b79d99430"},
{file = "MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:569511d3b58c8791ab4c2e1285575265991e6d8f8700c7be0e88f86cb0672094"},
{file = "MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:15ab75ef81add55874e7ab7055e9c397312385bd9ced94920f2802310c930396"},
{file = "MarkupSafe-3.0.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f3818cb119498c0678015754eba762e0d61e5b52d34c8b13d770f0719f7b1d79"},
{file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:cdb82a876c47801bb54a690c5ae105a46b392ac6099881cdfb9f6e95e4014c6a"},
{file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:cabc348d87e913db6ab4aa100f01b08f481097838bdddf7c7a84b7575b7309ca"},
{file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:444dcda765c8a838eaae23112db52f1efaf750daddb2d9ca300bcae1039adc5c"},
{file = "MarkupSafe-3.0.2-cp313-cp313-win32.whl", hash = "sha256:bcf3e58998965654fdaff38e58584d8937aa3096ab5354d493c77d1fdd66d7a1"},
{file = "MarkupSafe-3.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:e6a2a455bd412959b57a172ce6328d2dd1f01cb2135efda2e4576e8a23fa3b0f"},
{file = "MarkupSafe-3.0.2-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:b5a6b3ada725cea8a5e634536b1b01c30bcdcd7f9c6fff4151548d5bf6b3a36c"},
{file = "MarkupSafe-3.0.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:a904af0a6162c73e3edcb969eeeb53a63ceeb5d8cf642fade7d39e7963a22ddb"},
{file = "MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4aa4e5faecf353ed117801a068ebab7b7e09ffb6e1d5e412dc852e0da018126c"},
{file = "MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c0ef13eaeee5b615fb07c9a7dadb38eac06a0608b41570d8ade51c56539e509d"},
{file = "MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d16a81a06776313e817c951135cf7340a3e91e8c1ff2fac444cfd75fffa04afe"},
{file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:6381026f158fdb7c72a168278597a5e3a5222e83ea18f543112b2662a9b699c5"},
{file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:3d79d162e7be8f996986c064d1c7c817f6df3a77fe3d6859f6f9e7be4b8c213a"},
{file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:131a3c7689c85f5ad20f9f6fb1b866f402c445b220c19fe4308c0b147ccd2ad9"},
{file = "MarkupSafe-3.0.2-cp313-cp313t-win32.whl", hash = "sha256:ba8062ed2cf21c07a9e295d5b8a2a5ce678b913b45fdf68c32d95d6c1291e0b6"},
{file = "MarkupSafe-3.0.2-cp313-cp313t-win_amd64.whl", hash = "sha256:e444a31f8db13eb18ada366ab3cf45fd4b31e4db1236a4448f68778c1d1a5a2f"},
{file = "MarkupSafe-3.0.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:eaa0a10b7f72326f1372a713e73c3f739b524b3af41feb43e4921cb529f5929a"},
{file = "MarkupSafe-3.0.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:48032821bbdf20f5799ff537c7ac3d1fba0ba032cfc06194faffa8cda8b560ff"},
{file = "MarkupSafe-3.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1a9d3f5f0901fdec14d8d2f66ef7d035f2157240a433441719ac9a3fba440b13"},
{file = "MarkupSafe-3.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:88b49a3b9ff31e19998750c38e030fc7bb937398b1f78cfa599aaef92d693144"},
{file = "MarkupSafe-3.0.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cfad01eed2c2e0c01fd0ecd2ef42c492f7f93902e39a42fc9ee1692961443a29"},
{file = "MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:1225beacc926f536dc82e45f8a4d68502949dc67eea90eab715dea3a21c1b5f0"},
{file = "MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:3169b1eefae027567d1ce6ee7cae382c57fe26e82775f460f0b2778beaad66c0"},
{file = "MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:eb7972a85c54febfb25b5c4b4f3af4dcc731994c7da0d8a0b4a6eb0640e1d178"},
{file = "MarkupSafe-3.0.2-cp39-cp39-win32.whl", hash = "sha256:8c4e8c3ce11e1f92f6536ff07154f9d49677ebaaafc32db9db4620bc11ed480f"},
{file = "MarkupSafe-3.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:6e296a513ca3d94054c2c881cc913116e90fd030ad1c656b3869762b754f5f8a"},
{file = "markupsafe-3.0.2.tar.gz", hash = "sha256:ee55d3edf80167e48ea11a923c7386f4669df67d7994554387f84e7d8b0a2bf0"},
]
[[package]]
name = "mdit-py-plugins"
version = "0.4.2"
description = "Collection of plugins for markdown-it-py"
optional = false
python-versions = ">=3.8"
groups = ["docs"]
files = [
{file = "mdit_py_plugins-0.4.2-py3-none-any.whl", hash = "sha256:0c673c3f889399a33b95e88d2f0d111b4447bdfea7f237dab2d488f459835636"},
{file = "mdit_py_plugins-0.4.2.tar.gz", hash = "sha256:5f2cd1fdb606ddf152d37ec30e46101a60512bc0e5fa1a7002c36647b09e26b5"},
]
[package.dependencies]
markdown-it-py = ">=1.0.0,<4.0.0"
[package.extras]
code-style = ["pre-commit"]
rtd = ["myst-parser", "sphinx-book-theme"]
testing = ["coverage", "pytest", "pytest-cov", "pytest-regressions"]
[[package]]
name = "mdurl"
version = "0.1.2"
description = "Markdown URL utilities"
optional = false
python-versions = ">=3.7"
groups = ["dev", "docs"]
files = [
{file = "mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8"},
{file = "mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba"},
]
[[package]]
name = "myst-parser"
version = "3.0.1"
description = "An extended [CommonMark](https://spec.commonmark.org/) compliant parser,"
optional = false
python-versions = ">=3.8"
groups = ["docs"]
files = [
{file = "myst_parser-3.0.1-py3-none-any.whl", hash = "sha256:6457aaa33a5d474aca678b8ead9b3dc298e89c68e67012e73146ea6fd54babf1"},
{file = "myst_parser-3.0.1.tar.gz", hash = "sha256:88f0cb406cb363b077d176b51c476f62d60604d68a8dcdf4832e080441301a87"},
]
[package.dependencies]
docutils = ">=0.18,<0.22"
jinja2 = "*"
markdown-it-py = ">=3.0,<4.0"
mdit-py-plugins = ">=0.4,<1.0"
pyyaml = "*"
sphinx = ">=6,<8"
[package.extras]
code-style = ["pre-commit (>=3.0,<4.0)"]
linkify = ["linkify-it-py (>=2.0,<3.0)"]
rtd = ["ipython", "sphinx (>=7)", "sphinx-autodoc2 (>=0.5.0,<0.6.0)", "sphinx-book-theme (>=1.1,<2.0)", "sphinx-copybutton", "sphinx-design", "sphinx-pyscript", "sphinx-tippy (>=0.4.3)", "sphinx-togglebutton", "sphinxext-opengraph (>=0.9.0,<0.10.0)", "sphinxext-rediraffe (>=0.2.7,<0.3.0)"]
testing = ["beautifulsoup4", "coverage[toml]", "defusedxml", "pytest (>=8,<9)", "pytest-cov", "pytest-param-files (>=0.6.0,<0.7.0)", "pytest-regressions", "sphinx-pytest"]
testing-docutils = ["pygments", "pytest (>=8,<9)", "pytest-param-files (>=0.6.0,<0.7.0)"]
[[package]]
name = "packaging"
version = "24.2"
description = "Core utilities for Python packages"
optional = false
python-versions = ">=3.8"
groups = ["dev", "docs"]
files = [
{file = "packaging-24.2-py3-none-any.whl", hash = "sha256:09abb1bccd265c01f4a3aa3f7a7db064b36514d2cba19a2f694fe6150451a759"},
{file = "packaging-24.2.tar.gz", hash = "sha256:c228a6dc5e932d346bc5739379109d49e8853dd8223571c7c5b55260edc0b97f"},
]
[[package]]
name = "pluggy"
version = "1.5.0"
description = "plugin and hook calling mechanisms for python"
optional = false
python-versions = ">=3.8"
groups = ["dev"]
files = [
{file = "pluggy-1.5.0-py3-none-any.whl", hash = "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669"},
{file = "pluggy-1.5.0.tar.gz", hash = "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1"},
]
[package.extras]
dev = ["pre-commit", "tox"]
testing = ["pytest", "pytest-benchmark"]
[[package]]
name = "pycairo"
version = "1.27.0"
description = "Python interface for cairo"
optional = false
python-versions = ">=3.9"
groups = ["dev"]
files = [
{file = "pycairo-1.27.0-cp310-cp310-win32.whl", hash = "sha256:e20f431244634cf244ab6b4c3a2e540e65746eed1324573cf291981c3e65fc05"},
{file = "pycairo-1.27.0-cp310-cp310-win_amd64.whl", hash = "sha256:03bf570e3919901572987bc69237b648fe0de242439980be3e606b396e3318c9"},
{file = "pycairo-1.27.0-cp311-cp311-win32.whl", hash = "sha256:9a9b79f92a434dae65c34c830bb9abdbd92654195e73d52663cbe45af1ad14b2"},
{file = "pycairo-1.27.0-cp311-cp311-win_amd64.whl", hash = "sha256:d40a6d80b15dacb3672dc454df4bc4ab3988c6b3f36353b24a255dc59a1c8aea"},
{file = "pycairo-1.27.0-cp312-cp312-win32.whl", hash = "sha256:e2239b9bb6c05edae5f3be97128e85147a155465e644f4d98ea0ceac7afc04ee"},
{file = "pycairo-1.27.0-cp312-cp312-win_amd64.whl", hash = "sha256:27cb4d3a80e3b9990af552818515a8e466e0317063a6e61585533f1a86f1b7d5"},
{file = "pycairo-1.27.0-cp313-cp313-win32.whl", hash = "sha256:01505c138a313df2469f812405963532fc2511fb9bca9bdc8e0ab94c55d1ced8"},
{file = "pycairo-1.27.0-cp313-cp313-win_amd64.whl", hash = "sha256:b0349d744c068b6644ae23da6ada111c8a8a7e323b56cbce3707cba5bdb474cc"},
{file = "pycairo-1.27.0-cp39-cp39-win32.whl", hash = "sha256:f9ca8430751f1fdcd3f072377560c9e15608b9a42d61375469db853566993c9b"},
{file = "pycairo-1.27.0-cp39-cp39-win_amd64.whl", hash = "sha256:1b1321652a6e27c4de3069709b1cae22aed2707fd8c5e889c04a95669228af2a"},
{file = "pycairo-1.27.0.tar.gz", hash = "sha256:5cb21e7a00a2afcafea7f14390235be33497a2cce53a98a19389492a60628430"},
]
[[package]]
name = "pycparser"
version = "2.22"
description = "C parser in Python"
optional = false
python-versions = ">=3.8"
groups = ["dev"]
files = [
{file = "pycparser-2.22-py3-none-any.whl", hash = "sha256:c3702b6d3dd8c7abc1afa565d7e63d53a1d0bd86cdc24edd75470f4de499cfcc"},
{file = "pycparser-2.22.tar.gz", hash = "sha256:491c8be9c040f5390f5bf44a5b07752bd07f56edf992381b05c701439eec10f6"},
]
[[package]]
name = "pygments"
version = "2.19.1"
description = "Pygments is a syntax highlighting package written in Python."
optional = false
python-versions = ">=3.8"
groups = ["dev", "docs"]
files = [
{file = "pygments-2.19.1-py3-none-any.whl", hash = "sha256:9ea1544ad55cecf4b8242fab6dd35a93bbce657034b0611ee383099054ab6d8c"},
{file = "pygments-2.19.1.tar.gz", hash = "sha256:61c16d2a8576dc0649d9f39e089b5f02bcd27fba10d8fb4dcc28173f7a45151f"},
]
[package.extras]
windows-terminal = ["colorama (>=0.4.6)"]
[[package]]
name = "pygobject"
version = "3.50.0"
description = "Python bindings for GObject Introspection"
optional = false
python-versions = "<4.0,>=3.9"
groups = ["dev"]
markers = "python_version < \"4\""
files = [
{file = "pygobject-3.50.0.tar.gz", hash = "sha256:4500ad3dbf331773d8dedf7212544c999a76fc96b63a91b3dcac1e5925a1d103"},
]
[package.dependencies]
pycairo = ">=1.16"
[[package]]
name = "pytest"
version = "8.3.5"
description = "pytest: simple powerful testing with Python"
optional = false
python-versions = ">=3.8"
groups = ["dev"]
files = [
{file = "pytest-8.3.5-py3-none-any.whl", hash = "sha256:c69214aa47deac29fad6c2a4f590b9c4a9fdb16a403176fe154b79c0b4d4d820"},
{file = "pytest-8.3.5.tar.gz", hash = "sha256:f4efe70cc14e511565ac476b57c279e12a855b11f48f212af1080ef2263d3845"},
]
[package.dependencies]
colorama = {version = "*", markers = "sys_platform == \"win32\""}
exceptiongroup = {version = ">=1.0.0rc8", markers = "python_version < \"3.11\""}
iniconfig = "*"
packaging = "*"
pluggy = ">=1.5,<2"
tomli = {version = ">=1", markers = "python_version < \"3.11\""}
[package.extras]
dev = ["argcomplete", "attrs (>=19.2)", "hypothesis (>=3.56)", "mock", "pygments (>=2.7.2)", "requests", "setuptools", "xmlschema"]
[[package]]
name = "pytest-asyncio"
version = "0.26.0"
description = "Pytest support for asyncio"
optional = false
python-versions = ">=3.9"
groups = ["dev"]
files = [
{file = "pytest_asyncio-0.26.0-py3-none-any.whl", hash = "sha256:7b51ed894f4fbea1340262bdae5135797ebbe21d8638978e35d31c6d19f72fb0"},
{file = "pytest_asyncio-0.26.0.tar.gz", hash = "sha256:c4df2a697648241ff39e7f0e4a73050b03f123f760673956cf0d72a4990e312f"},
]
[package.dependencies]
pytest = ">=8.2,<9"
typing-extensions = {version = ">=4.12", markers = "python_version < \"3.10\""}
[package.extras]
docs = ["sphinx (>=5.3)", "sphinx-rtd-theme (>=1)"]
testing = ["coverage (>=6.2)", "hypothesis (>=5.7.1)"]
[[package]]
name = "pytest-codspeed"
version = "3.2.0"
description = "Pytest plugin to create CodSpeed benchmarks"
optional = false
python-versions = ">=3.9"
groups = ["dev"]
files = [
{file = "pytest_codspeed-3.2.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c5165774424c7ab8db7e7acdb539763a0e5657996effefdf0664d7fd95158d34"},
{file = "pytest_codspeed-3.2.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9bd55f92d772592c04a55209950c50880413ae46876e66bd349ef157075ca26c"},
{file = "pytest_codspeed-3.2.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4cf6f56067538f4892baa8d7ab5ef4e45bb59033be1ef18759a2c7fc55b32035"},
{file = "pytest_codspeed-3.2.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:39a687b05c3d145642061b45ea78e47e12f13ce510104d1a2cda00eee0e36f58"},
{file = "pytest_codspeed-3.2.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:46a1afaaa1ac4c2ca5b0700d31ac46d80a27612961d031067d73c6ccbd8d3c2b"},
{file = "pytest_codspeed-3.2.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c48ce3af3dfa78413ed3d69d1924043aa1519048dbff46edccf8f35a25dab3c2"},
{file = "pytest_codspeed-3.2.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:66692506d33453df48b36a84703448cb8b22953eea51f03fbb2eb758dc2bdc4f"},
{file = "pytest_codspeed-3.2.0-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:479774f80d0bdfafa16112700df4dbd31bf2a6757fac74795fd79c0a7b3c389b"},
{file = "pytest_codspeed-3.2.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:109f9f4dd1088019c3b3f887d003b7d65f98a7736ca1d457884f5aa293e8e81c"},
{file = "pytest_codspeed-3.2.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e2f69a03b52c9bb041aec1b8ee54b7b6c37a6d0a948786effa4c71157765b6da"},
{file = "pytest_codspeed-3.2.0-py3-none-any.whl", hash = "sha256:54b5c2e986d6a28e7b0af11d610ea57bd5531cec8326abe486f1b55b09d91c39"},
{file = "pytest_codspeed-3.2.0.tar.gz", hash = "sha256:f9d1b1a3b2c69cdc0490a1e8b1ced44bffbd0e8e21d81a7160cfdd923f6e8155"},
]
[package.dependencies]
cffi = ">=1.17.1"
importlib-metadata = {version = ">=8.5.0", markers = "python_version < \"3.10\""}
pytest = ">=3.8"
rich = ">=13.8.1"
[package.extras]
compat = ["pytest-benchmark (>=5.0.0,<5.1.0)", "pytest-xdist (>=3.6.1,<3.7.0)"]
lint = ["mypy (>=1.11.2,<1.12.0)", "ruff (>=0.6.5,<0.7.0)"]
test = ["pytest (>=7.0,<8.0)", "pytest-cov (>=4.0.0,<4.1.0)"]
[[package]]
name = "pytest-cov"
version = "6.0.0"
description = "Pytest plugin for measuring coverage."
optional = false
python-versions = ">=3.9"
groups = ["dev"]
files = [
{file = "pytest-cov-6.0.0.tar.gz", hash = "sha256:fde0b595ca248bb8e2d76f020b465f3b107c9632e6a1d1705f17834c89dcadc0"},
{file = "pytest_cov-6.0.0-py3-none-any.whl", hash = "sha256:eee6f1b9e61008bd34975a4d5bab25801eb31898b032dd55addc93e96fcaaa35"},
]
[package.dependencies]
coverage = {version = ">=7.5", extras = ["toml"]}
pytest = ">=4.6"
[package.extras]
testing = ["fields", "hunter", "process-tests", "pytest-xdist", "virtualenv"]
[[package]]
name = "pytest-timeout"
version = "2.3.1"
description = "pytest plugin to abort hanging tests"
optional = false
python-versions = ">=3.7"
groups = ["dev"]
files = [
{file = "pytest-timeout-2.3.1.tar.gz", hash = "sha256:12397729125c6ecbdaca01035b9e5239d4db97352320af155b3f5de1ba5165d9"},
{file = "pytest_timeout-2.3.1-py3-none-any.whl", hash = "sha256:68188cb703edfc6a18fad98dc25a3c61e9f24d644b0b70f33af545219fc7813e"},
]
[package.dependencies]
pytest = ">=7.0.0"
[[package]]
name = "pyyaml"
version = "6.0.2"
description = "YAML parser and emitter for Python"
optional = false
python-versions = ">=3.8"
groups = ["docs"]
files = [
{file = "PyYAML-6.0.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0a9a2848a5b7feac301353437eb7d5957887edbf81d56e903999a75a3d743086"},
{file = "PyYAML-6.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:29717114e51c84ddfba879543fb232a6ed60086602313ca38cce623c1d62cfbf"},
{file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8824b5a04a04a047e72eea5cec3bc266db09e35de6bdfe34c9436ac5ee27d237"},
{file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7c36280e6fb8385e520936c3cb3b8042851904eba0e58d277dca80a5cfed590b"},
{file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ec031d5d2feb36d1d1a24380e4db6d43695f3748343d99434e6f5f9156aaa2ed"},
{file = "PyYAML-6.0.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:936d68689298c36b53b29f23c6dbb74de12b4ac12ca6cfe0e047bedceea56180"},
{file = "PyYAML-6.0.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:23502f431948090f597378482b4812b0caae32c22213aecf3b55325e049a6c68"},
{file = "PyYAML-6.0.2-cp310-cp310-win32.whl", hash = "sha256:2e99c6826ffa974fe6e27cdb5ed0021786b03fc98e5ee3c5bfe1fd5015f42b99"},
{file = "PyYAML-6.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:a4d3091415f010369ae4ed1fc6b79def9416358877534caf6a0fdd2146c87a3e"},
{file = "PyYAML-6.0.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:cc1c1159b3d456576af7a3e4d1ba7e6924cb39de8f67111c735f6fc832082774"},
{file = "PyYAML-6.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1e2120ef853f59c7419231f3bf4e7021f1b936f6ebd222406c3b60212205d2ee"},
{file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5d225db5a45f21e78dd9358e58a98702a0302f2659a3c6cd320564b75b86f47c"},
{file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5ac9328ec4831237bec75defaf839f7d4564be1e6b25ac710bd1a96321cc8317"},
{file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ad2a3decf9aaba3d29c8f537ac4b243e36bef957511b4766cb0057d32b0be85"},
{file = "PyYAML-6.0.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:ff3824dc5261f50c9b0dfb3be22b4567a6f938ccce4587b38952d85fd9e9afe4"},
{file = "PyYAML-6.0.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:797b4f722ffa07cc8d62053e4cff1486fa6dc094105d13fea7b1de7d8bf71c9e"},
{file = "PyYAML-6.0.2-cp311-cp311-win32.whl", hash = "sha256:11d8f3dd2b9c1207dcaf2ee0bbbfd5991f571186ec9cc78427ba5bd32afae4b5"},
{file = "PyYAML-6.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:e10ce637b18caea04431ce14fabcf5c64a1c61ec9c56b071a4b7ca131ca52d44"},
{file = "PyYAML-6.0.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:c70c95198c015b85feafc136515252a261a84561b7b1d51e3384e0655ddf25ab"},
{file = "PyYAML-6.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ce826d6ef20b1bc864f0a68340c8b3287705cae2f8b4b1d932177dcc76721725"},
{file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f71ea527786de97d1a0cc0eacd1defc0985dcf6b3f17bb77dcfc8c34bec4dc5"},
{file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9b22676e8097e9e22e36d6b7bda33190d0d400f345f23d4065d48f4ca7ae0425"},
{file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:80bab7bfc629882493af4aa31a4cfa43a4c57c83813253626916b8c7ada83476"},
{file = "PyYAML-6.0.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:0833f8694549e586547b576dcfaba4a6b55b9e96098b36cdc7ebefe667dfed48"},
{file = "PyYAML-6.0.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8b9c7197f7cb2738065c481a0461e50ad02f18c78cd75775628afb4d7137fb3b"},
{file = "PyYAML-6.0.2-cp312-cp312-win32.whl", hash = "sha256:ef6107725bd54b262d6dedcc2af448a266975032bc85ef0172c5f059da6325b4"},
{file = "PyYAML-6.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:7e7401d0de89a9a855c839bc697c079a4af81cf878373abd7dc625847d25cbd8"},
{file = "PyYAML-6.0.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:efdca5630322a10774e8e98e1af481aad470dd62c3170801852d752aa7a783ba"},
{file = "PyYAML-6.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:50187695423ffe49e2deacb8cd10510bc361faac997de9efef88badc3bb9e2d1"},
{file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ffe8360bab4910ef1b9e87fb812d8bc0a308b0d0eef8c8f44e0254ab3b07133"},
{file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:17e311b6c678207928d649faa7cb0d7b4c26a0ba73d41e99c4fff6b6c3276484"},
{file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70b189594dbe54f75ab3a1acec5f1e3faa7e8cf2f1e08d9b561cb41b845f69d5"},
{file = "PyYAML-6.0.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:41e4e3953a79407c794916fa277a82531dd93aad34e29c2a514c2c0c5fe971cc"},
{file = "PyYAML-6.0.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:68ccc6023a3400877818152ad9a1033e3db8625d899c72eacb5a668902e4d652"},
{file = "PyYAML-6.0.2-cp313-cp313-win32.whl", hash = "sha256:bc2fa7c6b47d6bc618dd7fb02ef6fdedb1090ec036abab80d4681424b84c1183"},
{file = "PyYAML-6.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:8388ee1976c416731879ac16da0aff3f63b286ffdd57cdeb95f3f2e085687563"},
{file = "PyYAML-6.0.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:24471b829b3bf607e04e88d79542a9d48bb037c2267d7927a874e6c205ca7e9a"},
{file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d7fded462629cfa4b685c5416b949ebad6cec74af5e2d42905d41e257e0869f5"},
{file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d84a1718ee396f54f3a086ea0a66d8e552b2ab2017ef8b420e92edbc841c352d"},
{file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9056c1ecd25795207ad294bcf39f2db3d845767be0ea6e6a34d856f006006083"},
{file = "PyYAML-6.0.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:82d09873e40955485746739bcb8b4586983670466c23382c19cffecbf1fd8706"},
{file = "PyYAML-6.0.2-cp38-cp38-win32.whl", hash = "sha256:43fa96a3ca0d6b1812e01ced1044a003533c47f6ee8aca31724f78e93ccc089a"},
{file = "PyYAML-6.0.2-cp38-cp38-win_amd64.whl", hash = "sha256:01179a4a8559ab5de078078f37e5c1a30d76bb88519906844fd7bdea1b7729ff"},
{file = "PyYAML-6.0.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:688ba32a1cffef67fd2e9398a2efebaea461578b0923624778664cc1c914db5d"},
{file = "PyYAML-6.0.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a8786accb172bd8afb8be14490a16625cbc387036876ab6ba70912730faf8e1f"},
{file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d8e03406cac8513435335dbab54c0d385e4a49e4945d2909a581c83647ca0290"},
{file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f753120cb8181e736c57ef7636e83f31b9c0d1722c516f7e86cf15b7aa57ff12"},
{file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3b1fdb9dc17f5a7677423d508ab4f243a726dea51fa5e70992e59a7411c89d19"},
{file = "PyYAML-6.0.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:0b69e4ce7a131fe56b7e4d770c67429700908fc0752af059838b1cfb41960e4e"},
{file = "PyYAML-6.0.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a9f8c2e67970f13b16084e04f134610fd1d374bf477b17ec1599185cf611d725"},
{file = "PyYAML-6.0.2-cp39-cp39-win32.whl", hash = "sha256:6395c297d42274772abc367baaa79683958044e5d3835486c16da75d2a694631"},
{file = "PyYAML-6.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:39693e1f8320ae4f43943590b49779ffb98acb81f788220ea932a6b6c51004d8"},
{file = "pyyaml-6.0.2.tar.gz", hash = "sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e"},
]
[[package]]
name = "requests"
version = "2.32.3"
description = "Python HTTP for Humans."
optional = false
python-versions = ">=3.8"
groups = ["docs"]
files = [
{file = "requests-2.32.3-py3-none-any.whl", hash = "sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6"},
{file = "requests-2.32.3.tar.gz", hash = "sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760"},
]
[package.dependencies]
certifi = ">=2017.4.17"
charset-normalizer = ">=2,<4"
idna = ">=2.5,<4"
urllib3 = ">=1.21.1,<3"
[package.extras]
socks = ["PySocks (>=1.5.6,!=1.5.7)"]
use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"]
[[package]]
name = "rich"
version = "13.9.4"
description = "Render rich text, tables, progress bars, syntax highlighting, markdown and more to the terminal"
optional = false
python-versions = ">=3.8.0"
groups = ["dev"]
files = [
{file = "rich-13.9.4-py3-none-any.whl", hash = "sha256:6049d5e6ec054bf2779ab3358186963bac2ea89175919d699e378b99738c2a90"},
{file = "rich-13.9.4.tar.gz", hash = "sha256:439594978a49a09530cff7ebc4b5c7103ef57baf48d5ea3184f21d9a2befa098"},
]
[package.dependencies]
markdown-it-py = ">=2.2.0"
pygments = ">=2.13.0,<3.0.0"
typing-extensions = {version = ">=4.0.0,<5.0", markers = "python_version < \"3.11\""}
[package.extras]
jupyter = ["ipywidgets (>=7.5.1,<9)"]
[[package]]
name = "setuptools"
version = "78.1.0"
description = "Easily download, build, install, upgrade, and uninstall Python packages"
optional = false
python-versions = ">=3.9"
groups = ["dev"]
files = [
{file = "setuptools-78.1.0-py3-none-any.whl", hash = "sha256:3e386e96793c8702ae83d17b853fb93d3e09ef82ec62722e61da5cd22376dcd8"},
{file = "setuptools-78.1.0.tar.gz", hash = "sha256:18fd474d4a82a5f83dac888df697af65afa82dec7323d09c3e37d1f14288da54"},
]
[package.extras]
check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1) ; sys_platform != \"cygwin\"", "ruff (>=0.8.0) ; sys_platform != \"cygwin\""]
core = ["importlib_metadata (>=6) ; python_version < \"3.10\"", "jaraco.functools (>=4)", "jaraco.text (>=3.7)", "more_itertools", "more_itertools (>=8.8)", "packaging (>=24.2)", "platformdirs (>=4.2.2)", "tomli (>=2.0.1) ; python_version < \"3.11\"", "wheel (>=0.43.0)"]
cover = ["pytest-cov"]
doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier", "towncrier (<24.7)"]
enabler = ["pytest-enabler (>=2.2)"]
test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21) ; python_version >= \"3.9\" and sys_platform != \"cygwin\"", "jaraco.envs (>=2.2)", "jaraco.path (>=3.7.2)", "jaraco.test (>=5.5)", "packaging (>=24.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf ; sys_platform != \"cygwin\"", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"]
type = ["importlib_metadata (>=7.0.2) ; python_version < \"3.10\"", "jaraco.develop (>=7.21) ; sys_platform != \"cygwin\"", "mypy (==1.14.*)", "pytest-mypy"]
[[package]]
name = "snowballstemmer"
version = "2.2.0"
description = "This package provides 29 stemmers for 28 languages generated from Snowball algorithms."
optional = false
python-versions = "*"
groups = ["docs"]
files = [
{file = "snowballstemmer-2.2.0-py2.py3-none-any.whl", hash = "sha256:c8e1716e83cc398ae16824e5572ae04e0d9fc2c6b985fb0f900f5f0c96ecba1a"},
{file = "snowballstemmer-2.2.0.tar.gz", hash = "sha256:09b16deb8547d3412ad7b590689584cd0fe25ec8db3be37788be3810cbf19cb1"},
]
[[package]]
name = "sphinx"
version = "7.4.7"
description = "Python documentation generator"
optional = false
python-versions = ">=3.9"
groups = ["docs"]
files = [
{file = "sphinx-7.4.7-py3-none-any.whl", hash = "sha256:c2419e2135d11f1951cd994d6eb18a1835bd8fdd8429f9ca375dc1f3281bd239"},
{file = "sphinx-7.4.7.tar.gz", hash = "sha256:242f92a7ea7e6c5b406fdc2615413890ba9f699114a9c09192d7dfead2ee9cfe"},
]
[package.dependencies]
alabaster = ">=0.7.14,<0.8.0"
babel = ">=2.13"
colorama = {version = ">=0.4.6", markers = "sys_platform == \"win32\""}
docutils = ">=0.20,<0.22"
imagesize = ">=1.3"
importlib-metadata = {version = ">=6.0", markers = "python_version < \"3.10\""}
Jinja2 = ">=3.1"
packaging = ">=23.0"
Pygments = ">=2.17"
requests = ">=2.30.0"
snowballstemmer = ">=2.2"
sphinxcontrib-applehelp = "*"
sphinxcontrib-devhelp = "*"
sphinxcontrib-htmlhelp = ">=2.0.0"
sphinxcontrib-jsmath = "*"
sphinxcontrib-qthelp = "*"
sphinxcontrib-serializinghtml = ">=1.1.9"
tomli = {version = ">=2", markers = "python_version < \"3.11\""}
[package.extras]
docs = ["sphinxcontrib-websupport"]
lint = ["flake8 (>=6.0)", "importlib-metadata (>=6.0)", "mypy (==1.10.1)", "pytest (>=6.0)", "ruff (==0.5.2)", "sphinx-lint (>=0.9)", "tomli (>=2)", "types-docutils (==0.21.0.20240711)", "types-requests (>=2.30.0)"]
test = ["cython (>=3.0)", "defusedxml (>=0.7.1)", "pytest (>=8.0)", "setuptools (>=70.0)", "typing_extensions (>=4.9)"]
[[package]]
name = "sphinx-rtd-theme"
version = "3.0.2"
description = "Read the Docs theme for Sphinx"
optional = false
python-versions = ">=3.8"
groups = ["docs"]
files = [
{file = "sphinx_rtd_theme-3.0.2-py2.py3-none-any.whl", hash = "sha256:422ccc750c3a3a311de4ae327e82affdaf59eb695ba4936538552f3b00f4ee13"},
{file = "sphinx_rtd_theme-3.0.2.tar.gz", hash = "sha256:b7457bc25dda723b20b086a670b9953c859eab60a2a03ee8eb2bb23e176e5f85"},
]
[package.dependencies]
docutils = ">0.18,<0.22"
sphinx = ">=6,<9"
sphinxcontrib-jquery = ">=4,<5"
[package.extras]
dev = ["bump2version", "transifex-client", "twine", "wheel"]
[[package]]
name = "sphinxcontrib-applehelp"
version = "2.0.0"
description = "sphinxcontrib-applehelp is a Sphinx extension which outputs Apple help books"
optional = false
python-versions = ">=3.9"
groups = ["docs"]
files = [
{file = "sphinxcontrib_applehelp-2.0.0-py3-none-any.whl", hash = "sha256:4cd3f0ec4ac5dd9c17ec65e9ab272c9b867ea77425228e68ecf08d6b28ddbdb5"},
{file = "sphinxcontrib_applehelp-2.0.0.tar.gz", hash = "sha256:2f29ef331735ce958efa4734873f084941970894c6090408b079c61b2e1c06d1"},
]
[package.extras]
lint = ["mypy", "ruff (==0.5.5)", "types-docutils"]
standalone = ["Sphinx (>=5)"]
test = ["pytest"]
[[package]]
name = "sphinxcontrib-asyncio"
version = "0.3.0"
description = "sphinx extension to support coroutines in markup"
optional = false
python-versions = "*"
groups = ["docs"]
files = [
{file = "sphinxcontrib-asyncio-0.3.0.tar.gz", hash = "sha256:99fd26e0fe7edf87244a71a99c316fd0c9b50856c2519acca927ebe74100722e"},
{file = "sphinxcontrib_asyncio-0.3.0-py2.py3-none-any.whl", hash = "sha256:c18d1f07a55b27e21c15d0f8cf2b940173f1b4566374d248bc4a8d256ee3ff24"},
]
[package.dependencies]
sphinx = ">=3.0"
[[package]]
name = "sphinxcontrib-devhelp"
version = "2.0.0"
description = "sphinxcontrib-devhelp is a sphinx extension which outputs Devhelp documents"
optional = false
python-versions = ">=3.9"
groups = ["docs"]
files = [
{file = "sphinxcontrib_devhelp-2.0.0-py3-none-any.whl", hash = "sha256:aefb8b83854e4b0998877524d1029fd3e6879210422ee3780459e28a1f03a8a2"},
{file = "sphinxcontrib_devhelp-2.0.0.tar.gz", hash = "sha256:411f5d96d445d1d73bb5d52133377b4248ec79db5c793ce7dbe59e074b4dd1ad"},
]
[package.extras]
lint = ["mypy", "ruff (==0.5.5)", "types-docutils"]
standalone = ["Sphinx (>=5)"]
test = ["pytest"]
[[package]]
name = "sphinxcontrib-fulltoc"
version = "1.2.0"
description = "Include a full table of contents in your Sphinx HTML sidebar"
optional = false
python-versions = "*"
groups = ["docs"]
files = [
{file = "sphinxcontrib-fulltoc-1.2.0.tar.gz", hash = "sha256:c845d62fc467f3135d4543e9f10e13ef91852683bd1c90fd19d07f9d36757cd9"},
]
[[package]]
name = "sphinxcontrib-htmlhelp"
version = "2.1.0"
description = "sphinxcontrib-htmlhelp is a sphinx extension which renders HTML help files"
optional = false
python-versions = ">=3.9"
groups = ["docs"]
files = [
{file = "sphinxcontrib_htmlhelp-2.1.0-py3-none-any.whl", hash = "sha256:166759820b47002d22914d64a075ce08f4c46818e17cfc9470a9786b759b19f8"},
{file = "sphinxcontrib_htmlhelp-2.1.0.tar.gz", hash = "sha256:c9e2916ace8aad64cc13a0d233ee22317f2b9025b9cf3295249fa985cc7082e9"},
]
[package.extras]
lint = ["mypy", "ruff (==0.5.5)", "types-docutils"]
standalone = ["Sphinx (>=5)"]
test = ["html5lib", "pytest"]
[[package]]
name = "sphinxcontrib-jquery"
version = "4.1"
description = "Extension to include jQuery on newer Sphinx releases"
optional = false
python-versions = ">=2.7"
groups = ["docs"]
files = [
{file = "sphinxcontrib-jquery-4.1.tar.gz", hash = "sha256:1620739f04e36a2c779f1a131a2dfd49b2fd07351bf1968ced074365933abc7a"},
{file = "sphinxcontrib_jquery-4.1-py2.py3-none-any.whl", hash = "sha256:f936030d7d0147dd026a4f2b5a57343d233f1fc7b363f68b3d4f1cb0993878ae"},
]
[package.dependencies]
Sphinx = ">=1.8"
[[package]]
name = "sphinxcontrib-jsmath"
version = "1.0.1"
description = "A sphinx extension which renders display math in HTML via JavaScript"
optional = false
python-versions = ">=3.5"
groups = ["docs"]
files = [
{file = "sphinxcontrib-jsmath-1.0.1.tar.gz", hash = "sha256:a9925e4a4587247ed2191a22df5f6970656cb8ca2bd6284309578f2153e0c4b8"},
{file = "sphinxcontrib_jsmath-1.0.1-py2.py3-none-any.whl", hash = "sha256:2ec2eaebfb78f3f2078e73666b1415417a116cc848b72e5172e596c871103178"},
]
[package.extras]
test = ["flake8", "mypy", "pytest"]
[[package]]
name = "sphinxcontrib-qthelp"
version = "2.0.0"
description = "sphinxcontrib-qthelp is a sphinx extension which outputs QtHelp documents"
optional = false
python-versions = ">=3.9"
groups = ["docs"]
files = [
{file = "sphinxcontrib_qthelp-2.0.0-py3-none-any.whl", hash = "sha256:b18a828cdba941ccd6ee8445dbe72ffa3ef8cbe7505d8cd1fa0d42d3f2d5f3eb"},
{file = "sphinxcontrib_qthelp-2.0.0.tar.gz", hash = "sha256:4fe7d0ac8fc171045be623aba3e2a8f613f8682731f9153bb2e40ece16b9bbab"},
]
[package.extras]
lint = ["mypy", "ruff (==0.5.5)", "types-docutils"]
standalone = ["Sphinx (>=5)"]
test = ["defusedxml (>=0.7.1)", "pytest"]
[[package]]
name = "sphinxcontrib-serializinghtml"
version = "2.0.0"
description = "sphinxcontrib-serializinghtml is a sphinx extension which outputs \"serialized\" HTML files (json and pickle)"
optional = false
python-versions = ">=3.9"
groups = ["docs"]
files = [
{file = "sphinxcontrib_serializinghtml-2.0.0-py3-none-any.whl", hash = "sha256:6e2cb0eef194e10c27ec0023bfeb25badbbb5868244cf5bc5bdc04e4464bf331"},
{file = "sphinxcontrib_serializinghtml-2.0.0.tar.gz", hash = "sha256:e9d912827f872c029017a53f0ef2180b327c3f7fd23c87229f7a8e8b70031d4d"},
]
[package.extras]
lint = ["mypy", "ruff (==0.5.5)", "types-docutils"]
standalone = ["Sphinx (>=5)"]
test = ["pytest"]
[[package]]
name = "tomli"
version = "2.2.1"
description = "A lil' TOML parser"
optional = false
python-versions = ">=3.8"
groups = ["dev", "docs"]
files = [
{file = "tomli-2.2.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:678e4fa69e4575eb77d103de3df8a895e1591b48e740211bd1067378c69e8249"},
{file = "tomli-2.2.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:023aa114dd824ade0100497eb2318602af309e5a55595f76b626d6d9f3b7b0a6"},
{file = "tomli-2.2.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ece47d672db52ac607a3d9599a9d48dcb2f2f735c6c2d1f34130085bb12b112a"},
{file = "tomli-2.2.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6972ca9c9cc9f0acaa56a8ca1ff51e7af152a9f87fb64623e31d5c83700080ee"},
{file = "tomli-2.2.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c954d2250168d28797dd4e3ac5cf812a406cd5a92674ee4c8f123c889786aa8e"},
{file = "tomli-2.2.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8dd28b3e155b80f4d54beb40a441d366adcfe740969820caf156c019fb5c7ec4"},
{file = "tomli-2.2.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:e59e304978767a54663af13c07b3d1af22ddee3bb2fb0618ca1593e4f593a106"},
{file = "tomli-2.2.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:33580bccab0338d00994d7f16f4c4ec25b776af3ffaac1ed74e0b3fc95e885a8"},
{file = "tomli-2.2.1-cp311-cp311-win32.whl", hash = "sha256:465af0e0875402f1d226519c9904f37254b3045fc5084697cefb9bdde1ff99ff"},
{file = "tomli-2.2.1-cp311-cp311-win_amd64.whl", hash = "sha256:2d0f2fdd22b02c6d81637a3c95f8cd77f995846af7414c5c4b8d0545afa1bc4b"},
{file = "tomli-2.2.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:4a8f6e44de52d5e6c657c9fe83b562f5f4256d8ebbfe4ff922c495620a7f6cea"},
{file = "tomli-2.2.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8d57ca8095a641b8237d5b079147646153d22552f1c637fd3ba7f4b0b29167a8"},
{file = "tomli-2.2.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4e340144ad7ae1533cb897d406382b4b6fede8890a03738ff1683af800d54192"},
{file = "tomli-2.2.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:db2b95f9de79181805df90bedc5a5ab4c165e6ec3fe99f970d0e302f384ad222"},
{file = "tomli-2.2.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:40741994320b232529c802f8bc86da4e1aa9f413db394617b9a256ae0f9a7f77"},
{file = "tomli-2.2.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:400e720fe168c0f8521520190686ef8ef033fb19fc493da09779e592861b78c6"},
{file = "tomli-2.2.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:02abe224de6ae62c19f090f68da4e27b10af2b93213d36cf44e6e1c5abd19fdd"},
{file = "tomli-2.2.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b82ebccc8c8a36f2094e969560a1b836758481f3dc360ce9a3277c65f374285e"},
{file = "tomli-2.2.1-cp312-cp312-win32.whl", hash = "sha256:889f80ef92701b9dbb224e49ec87c645ce5df3fa2cc548664eb8a25e03127a98"},
{file = "tomli-2.2.1-cp312-cp312-win_amd64.whl", hash = "sha256:7fc04e92e1d624a4a63c76474610238576942d6b8950a2d7f908a340494e67e4"},
{file = "tomli-2.2.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f4039b9cbc3048b2416cc57ab3bda989a6fcf9b36cf8937f01a6e731b64f80d7"},
{file = "tomli-2.2.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:286f0ca2ffeeb5b9bd4fcc8d6c330534323ec51b2f52da063b11c502da16f30c"},
{file = "tomli-2.2.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a92ef1a44547e894e2a17d24e7557a5e85a9e1d0048b0b5e7541f76c5032cb13"},
{file = "tomli-2.2.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9316dc65bed1684c9a98ee68759ceaed29d229e985297003e494aa825ebb0281"},
{file = "tomli-2.2.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e85e99945e688e32d5a35c1ff38ed0b3f41f43fad8df0bdf79f72b2ba7bc5272"},
{file = "tomli-2.2.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ac065718db92ca818f8d6141b5f66369833d4a80a9d74435a268c52bdfa73140"},
{file = "tomli-2.2.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:d920f33822747519673ee656a4b6ac33e382eca9d331c87770faa3eef562aeb2"},
{file = "tomli-2.2.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:a198f10c4d1b1375d7687bc25294306e551bf1abfa4eace6650070a5c1ae2744"},
{file = "tomli-2.2.1-cp313-cp313-win32.whl", hash = "sha256:d3f5614314d758649ab2ab3a62d4f2004c825922f9e370b29416484086b264ec"},
{file = "tomli-2.2.1-cp313-cp313-win_amd64.whl", hash = "sha256:a38aa0308e754b0e3c67e344754dff64999ff9b513e691d0e786265c93583c69"},
{file = "tomli-2.2.1-py3-none-any.whl", hash = "sha256:cb55c73c5f4408779d0cf3eef9f762b9c9f147a77de7b258bef0a5628adc85cc"},
{file = "tomli-2.2.1.tar.gz", hash = "sha256:cd45e1dc79c835ce60f7404ec8119f2eb06d38b1deba146f07ced3bbc44505ff"},
]
markers = {dev = "python_full_version <= \"3.11.0a6\"", docs = "python_version < \"3.11\""}
[[package]]
name = "typing-extensions"
version = "4.12.2"
description = "Backported and Experimental Type Hints for Python 3.8+"
optional = false
python-versions = ">=3.8"
groups = ["dev"]
markers = "python_version < \"3.11\""
files = [
{file = "typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d"},
{file = "typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8"},
]
[[package]]
name = "urllib3"
version = "2.3.0"
description = "HTTP library with thread-safe connection pooling, file post, and more."
optional = false
python-versions = ">=3.9"
groups = ["docs"]
files = [
{file = "urllib3-2.3.0-py3-none-any.whl", hash = "sha256:1cee9ad369867bfdbbb48b7dd50374c0967a0bb7710050facf0dd6911440e3df"},
{file = "urllib3-2.3.0.tar.gz", hash = "sha256:f8c5449b3cf0861679ce7e0503c7b44b5ec981bec0d1d3795a07f1ba96f0204d"},
]
[package.extras]
brotli = ["brotli (>=1.0.9) ; platform_python_implementation == \"CPython\"", "brotlicffi (>=0.8.0) ; platform_python_implementation != \"CPython\""]
h2 = ["h2 (>=4,<5)"]
socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"]
zstd = ["zstandard (>=0.18.0)"]
[[package]]
name = "zipp"
version = "3.21.0"
description = "Backport of pathlib-compatible object wrapper for zip files"
optional = false
python-versions = ">=3.9"
groups = ["dev", "docs"]
markers = "python_version < \"3.10\""
files = [
{file = "zipp-3.21.0-py3-none-any.whl", hash = "sha256:ac1bbe05fd2991f160ebce24ffbac5f6d11d83dc90891255885223d42b3cd931"},
{file = "zipp-3.21.0.tar.gz", hash = "sha256:2c9958f6430a2040341a52eb608ed6dd93ef4392e02ffe219417c1b28b5dd1f4"},
]
[package.extras]
check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1) ; sys_platform != \"cygwin\""]
cover = ["pytest-cov"]
doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"]
enabler = ["pytest-enabler (>=2.2)"]
test = ["big-O", "importlib-resources ; python_version < \"3.9\"", "jaraco.functools", "jaraco.itertools", "jaraco.test", "more-itertools", "pytest (>=6,!=8.1.*)", "pytest-ignore-flaky"]
type = ["pytest-mypy"]
[metadata]
lock-version = "2.1"
python-versions = ">=3.9"
content-hash = "0dda1b11d3ce779aee26661b76b4ff6986b88b6483c37ab596c45165d0addcdd"
dbus-fast-2.44.1/pyproject.toml 0000664 0000000 0000000 00000016077 14773556132 0016436 0 ustar 00root root 0000000 0000000 [tool.poetry]
name = "dbus-fast"
version = "2.44.1"
description = "A faster version of dbus-next"
authors = ["Bluetooth Devices Authors "]
license = "MIT"
readme = "README.md"
repository = "https://github.com/bluetooth-devices/dbus-fast"
documentation = "https://dbus-fast.readthedocs.io"
classifiers = [
"Development Status :: 5 - Production/Stable",
"Intended Audience :: Developers",
"Natural Language :: English",
"Operating System :: OS Independent",
"Topic :: Software Development :: Libraries",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
]
packages = [
{ include = "dbus_fast", from = "src" },
]
# Make sure we don't package temporary C files generated by the build process
exclude = [ "**/*.c" ]
[tool.poetry.build]
generate-setup-file = true
script = "build_ext.py"
[tool.poetry.urls]
"Bug Tracker" = "https://github.com/bluetooth-devices/dbus-fast/issues"
"Changelog" = "https://github.com/bluetooth-devices/dbus-fast/blob/main/CHANGELOG.md"
[tool.poetry.dependencies]
python = ">=3.9"
# duplicated in docs/requirements.txt for readthedocs compatibility
[tool.poetry.group.docs.dependencies]
myst-parser = ">=0.18,<3.1"
sphinx = ">=5.1.1,<8.0.0"
sphinx-rtd-theme = ">=1,<4"
sphinxcontrib-asyncio = "^0.3.0"
sphinxcontrib-fulltoc = "^1.2.0"
[tool.poetry.group.dev.dependencies]
pytest = ">=7,<9"
pytest-cov = ">=3,<7"
pytest-asyncio = ">=0.19,<0.27"
pycairo = "^1.21.0"
PyGObject = {version = ">=3.50,<3.51", python = "<4"}
Cython = ">=3,<3.1.0"
setuptools = ">=65.4.1,<79.0.0"
pytest-timeout = "^2.1.0"
pytest-codspeed = "^3.1.1"
covdefaults = "^2.3.0"
[tool.semantic_release]
branch = "main"
version_toml = ["pyproject.toml:tool.poetry.version"]
version_variables = ["src/dbus_fast/__version__.py:__version__"]
build_command = "pip install poetry && poetry build"
[tool.pytest.ini_options]
addopts = "-v -Wdefault --cov=dbus_fast --cov-report=term-missing:skip-covered"
pythonpath = ["src"]
[tool.coverage.run]
branch = true
plugins = ["covdefaults"]
[tool.coverage.report]
fail_under = 30 # cython version will have low cover because we do not have Cython tracing
exclude_also = [
"if cython.compiled:",
]
[tool.isort]
profile = "black"
known_first_party = ["dbus_fast", "tests"]
[tool.mypy]
check_untyped_defs = true
disallow_any_generics = false # turn this on when we drop 3.7/3.8 support
disallow_incomplete_defs = true
disallow_untyped_defs = true
mypy_path = "src/"
no_implicit_optional = true
show_error_codes = true
warn_unreachable = true
warn_unused_ignores = true
exclude = [
'docs/.*',
'setup.py',
]
[[tool.mypy.overrides]]
module = "tests.*"
allow_untyped_defs = true
[[tool.mypy.overrides]]
module = "docs.*"
ignore_errors = true
[build-system]
requires = ['setuptools>=65.4.1', 'wheel', 'Cython>=3,<3.1.0', "poetry-core>=1.0.0"]
build-backend = "poetry.core.masonry.api"
[tool.ruff]
target-version = "py39"
line-length = 88
[tool.ruff.lint]
ignore = [
"F821", # undefined names are used for decorators
"S101", # use of assert detected
"S105", # too many false positives
"SLF001", # intended
"SIM109", # intended for cython
"SIM102", # intended for cython
"E501", # too many to fix,
"TID252", # intended
"PLC0414", # intended
"TRY003", # too many to fix
"PLR2004", # way too many to fix right now
"PLR0911", # api is public
"PYI036", # too many to fix
"PYI034", # too many to fix
"E721", # many are as intended
## should fix these sooner
"B007", # too many to fix -- should fix sooner
"SIM103", # too many to fix -- should fix sooner
"SIM110", # too many to fix -- should fix sooner
"RUF012", # too many to fix -- should fix sooner
"TRY002", # too many to fix -- should fix sooner
"B904", # too many to fix -- should fix sooner
"PERF401", # too many to fix -- should fix sooner
"B904", # too many to fix -- should fix sooner
"B006", # too many to fix -- should fix sooner
"G004", # too many to fix -- should fix sooner
"PT015", # too many to fix -- should fix sooner
"B011", # too many to fix -- should fix sooner
"PLR1714", # too many to fix -- should fix sooner
"PLR0915", # too many to fix -- should fix sooner
"PERF102", # too many to fix -- should fix sooner
"TRY401", # too many to fix -- should fix sooner
"PLR0913", # too many to fix -- should fix sooner
"PLR0912", # too many to fix -- should fix sooner
"PERF203", # too many to fix -- should fix sooner
"G201", # too many to fix -- should fix sooner
"TRY301", # too many to fix -- should fix sooner
"B020", # too many to fix -- should fix sooner
"S314", # too many to fix -- should fix sooner
"RET504", # too many to fix -- should fix sooner
"SIM105", # too many to fix -- should fix sooner
"TRY300", # too many to fix -- should fix sooner
"PLW2901", # too many to fix -- should fix sooner
"PERF402", # too many to fix -- should fix sooner
]
select = [
"ASYNC", # async rules
"B", # flake8-bugbear
"C4", # flake8-comprehensions
"S", # flake8-bandit
"F", # pyflake
"E", # pycodestyle
"W", # pycodestyle
"UP", # pyupgrade
"I", # isort
"LOG", # log
"RUF", # ruff specific
"FLY", # flynt
"FURB", # refurb
"G", # flake8-logging-format ,
"PERF", # Perflint
"PGH", # pygrep-hooks
"PIE", # flake8-pie
"PL", # pylint
"PT", # flake8-pytest-style
"PYI", # flake8-pyi
"RET", # flake8-return
"RSE", # flake8-raise ,
"SIM", # flake8-simplify
"SLF", # flake8-self
"SLOT", # flake8-slots
"T100", # Trace found: {name} used
"T20", # flake8-print
"TID", # Tidy imports
"TRY", # tryceratops
]
[tool.ruff.lint.per-file-ignores]
"tests/**/*" = [
"D100",
"D101",
"D102",
"D103",
"D104",
"S101",
"S108",
"SLF001",
"PLW", # too many to fix
"TRY",# too many to fix right now
"PT",# too many to fix right now
"B",# too many to fix right now
"RET",# too many to fix right now
"PLR2004", # too many to fix right now
"PT011", # too many to fix right now
"PT006", # too many to fix right now
"PGH003", # too many to fix right now
"PT007", # too many to fix right now
"PT027", # too many to fix right now
"PLW0603" , # too many to fix right now
"PLR0915", # too many to fix right now
"FLY002", # too many to fix right now
"PT018", # too many to fix right now
"PLR0124", # too many to fix right now
"SIM202" , # too many to fix right now
"PT012" , # too many to fix right now
"TID252", # too many to fix right now
"PLR0913", # skip this one
"SIM102" , # too many to fix right now
"SIM108", # too many to fix right now
"T201", # too many to fix right now
]
"bench/**/*" = [
"T201", # intended
]
"examples/**/*" = [
"T201", # intended
"RSE102", # too many to fix
"C408", # too many to fix
"E402", # as intended
]
"docs/**/*" = [
"E402", # as intended
]
dbus-fast-2.44.1/renovate.json 0000664 0000000 0000000 00000000101 14773556132 0016215 0 ustar 00root root 0000000 0000000 {
"extends": ["github>browniebroke/renovate-configs:python"]
}
dbus-fast-2.44.1/src/ 0000775 0000000 0000000 00000000000 14773556132 0014276 5 ustar 00root root 0000000 0000000 dbus-fast-2.44.1/src/dbus_fast/ 0000775 0000000 0000000 00000000000 14773556132 0016250 5 ustar 00root root 0000000 0000000 dbus-fast-2.44.1/src/dbus_fast/__init__.py 0000664 0000000 0000000 00000003634 14773556132 0020367 0 ustar 00root root 0000000 0000000 from . import introspection, message_bus, proxy_object, service
from .constants import (
ArgDirection,
BusType,
ErrorType,
MessageFlag,
MessageType,
NameFlag,
PropertyAccess,
ReleaseNameReply,
RequestNameReply,
)
from .errors import (
AuthError,
DBusError,
InterfaceNotFoundError,
InvalidAddressError,
InvalidBusNameError,
InvalidInterfaceNameError,
InvalidIntrospectionError,
InvalidMemberNameError,
InvalidMessageError,
InvalidObjectPathError,
InvalidSignatureError,
SignalDisabledError,
SignatureBodyMismatchError,
)
from .message import Message
from .signature import SignatureTree, SignatureType, Variant
from .unpack import unpack_variants
from .validators import (
assert_bus_name_valid,
assert_interface_name_valid,
assert_member_name_valid,
assert_object_path_valid,
is_bus_name_valid,
is_interface_name_valid,
is_member_name_valid,
is_object_path_valid,
)
__all__ = [
"ArgDirection",
"AuthError",
"BusType",
"DBusError",
"ErrorType",
"InterfaceNotFoundError",
"InvalidAddressError",
"InvalidBusNameError",
"InvalidInterfaceNameError",
"InvalidIntrospectionError",
"InvalidMemberNameError",
"InvalidMessageError",
"InvalidObjectPathError",
"InvalidSignatureError",
"Message",
"MessageFlag",
"MessageType",
"NameFlag",
"PropertyAccess",
"ReleaseNameReply",
"RequestNameReply",
"SignalDisabledError",
"SignatureBodyMismatchError",
"SignatureTree",
"SignatureType",
"Variant",
"assert_bus_name_valid",
"assert_interface_name_valid",
"assert_member_name_valid",
"assert_object_path_valid",
"introspection",
"is_bus_name_valid",
"is_interface_name_valid",
"is_member_name_valid",
"is_object_path_valid",
"message_bus",
"proxy_object",
"service",
"unpack_variants",
]
dbus-fast-2.44.1/src/dbus_fast/__version__.py 0000664 0000000 0000000 00000000621 14773556132 0021102 0 ustar 00root root 0000000 0000000 __title__ = "dbus_fast"
__description__ = (
"A performant zero-dependency DBus library for Python with asyncio support"
)
__url__ = "https://github.com/bluetooth-devices/dbus-fast"
__version__ = "2.44.1"
__author__ = "Bluetooth Devices authors, Tony Crisci"
__author_email__ = "bluetooth@koston.org"
__license__ = "MIT"
__copyright__ = "Copyright 2022 Bluetooth Devices authors, 2019 Tony Crisci"
dbus-fast-2.44.1/src/dbus_fast/_private/ 0000775 0000000 0000000 00000000000 14773556132 0020061 5 ustar 00root root 0000000 0000000 dbus-fast-2.44.1/src/dbus_fast/_private/__init__.py 0000664 0000000 0000000 00000000043 14773556132 0022167 0 ustar 00root root 0000000 0000000 from __future__ import annotations
dbus-fast-2.44.1/src/dbus_fast/_private/_cython_compat.py 0000664 0000000 0000000 00000000367 14773556132 0023447 0 ustar 00root root 0000000 0000000 """Stub for when Cython is not available."""
from __future__ import annotations
class FakeCython:
"""Stub for when Cython is not available."""
@property
def compiled(self) -> bool:
return False
FAKE_CYTHON = FakeCython()
dbus-fast-2.44.1/src/dbus_fast/_private/address.pxd 0000664 0000000 0000000 00000000437 14773556132 0022227 0 ustar 00root root 0000000 0000000 """cdefs for address.py"""
import cython
cdef object unquote
@cython.locals(kv=cython.str, opt_string=cython.str, address=cython.str)
cpdef parse_address(cython.str address_str)
cpdef get_bus_address(object bus_type)
cpdef get_session_bus_address()
cpdef get_system_bus_address()
dbus-fast-2.44.1/src/dbus_fast/_private/address.py 0000664 0000000 0000000 00000007706 14773556132 0022072 0 ustar 00root root 0000000 0000000 from __future__ import annotations
import os
import re
from urllib.parse import unquote
from ..constants import BusType
from ..errors import InvalidAddressError
invalid_address_chars_re = re.compile(r"[^-0-9A-Za-z_/.%]")
str_ = str
def parse_address(address_str: str_) -> list[tuple[str, dict[str, str]]]:
"""Parse a dbus address string into a list of addresses."""
addresses: list[tuple[str, dict[str, str]]] = []
for address in address_str.split(";"):
if not address:
continue
if address.find(":") == -1:
raise InvalidAddressError("address did not contain a transport")
transport, opt_string = address.split(":", 1)
options: dict[str, str] = {}
for kv in opt_string.split(","):
if not kv:
continue
if kv.find("=") == -1:
raise InvalidAddressError("address option did not contain a value")
k, v = kv.split("=", 1)
if invalid_address_chars_re.search(v):
raise InvalidAddressError("address contains invalid characters")
# XXX the actual unquote rules are simpler than this
options[k] = unquote(v)
addresses.append((transport, options))
if not addresses:
raise InvalidAddressError(
f'address string contained no addresses: "{address_str}"'
)
return addresses
def get_system_bus_address() -> str:
"""Get the system bus address from the environment or return the default."""
return (
os.environ.get("DBUS_SYSTEM_BUS_ADDRESS")
or "unix:path=/var/run/dbus/system_bus_socket"
)
display_re = re.compile(r".*:([0-9]+)\.?.*")
remove_quotes_re = re.compile(r"""^['"]?(.*?)['"]?$""")
def get_session_bus_address() -> str:
"""Get the session bus address from the environment or return the default."""
dbus_session_bus_address = os.environ.get("DBUS_SESSION_BUS_ADDRESS")
if dbus_session_bus_address:
return dbus_session_bus_address
home = os.environ["HOME"]
if "DISPLAY" not in os.environ:
raise InvalidAddressError(
"DBUS_SESSION_BUS_ADDRESS not set and could not get DISPLAY environment variable to get bus address"
)
display = os.environ["DISPLAY"]
try:
display = display_re.search(display).group(1)
except Exception as ex:
raise InvalidAddressError(
f"DBUS_SESSION_BUS_ADDRESS not set and could not parse DISPLAY environment variable to get bus address: {display}"
) from ex
# XXX: this will block but they're very small files and fs operations
# should be fairly reliable. fix this by passing in an async func to read
# the file for each io backend.
machine_id = None
with open("/var/lib/dbus/machine-id") as f:
machine_id = f.read().rstrip()
dbus_info_file_name = f"{home}/.dbus/session-bus/{machine_id}-{display}"
dbus_info: str | None = None
try:
with open(dbus_info_file_name) as f:
dbus_info = f.read().rstrip()
except Exception as ex:
raise InvalidAddressError(
f"could not open dbus info file: {dbus_info_file_name}"
) from ex
for line in dbus_info.split("\n"):
if line.strip().startswith("DBUS_SESSION_BUS_ADDRESS="):
_, addr = line.split("=", 1)
if not addr:
raise InvalidAddressError(
f"DBUS_SESSION_BUS_ADDRESS variable not set correctly in dbus info file: {dbus_info_file_name}"
)
addr = remove_quotes_re.search(addr).group(1)
return addr
raise InvalidAddressError("could not find dbus session bus address")
def get_bus_address(bus_type: BusType) -> str:
"""Get the address of the bus specified by the bus type."""
if bus_type == BusType.SESSION:
return get_session_bus_address()
if bus_type == BusType.SYSTEM:
return get_system_bus_address()
raise Exception(f"got unknown bus type: {bus_type}")
dbus-fast-2.44.1/src/dbus_fast/_private/constants.py 0000664 0000000 0000000 00000000467 14773556132 0022456 0 ustar 00root root 0000000 0000000 from __future__ import annotations
from enum import Enum
PROTOCOL_VERSION = 1
LITTLE_ENDIAN = ord("l")
BIG_ENDIAN = ord("B")
class HeaderField(Enum):
PATH = 1
INTERFACE = 2
MEMBER = 3
ERROR_NAME = 4
REPLY_SERIAL = 5
DESTINATION = 6
SENDER = 7
SIGNATURE = 8
UNIX_FDS = 9
dbus-fast-2.44.1/src/dbus_fast/_private/marshaller.pxd 0000664 0000000 0000000 00000005155 14773556132 0022736 0 ustar 00root root 0000000 0000000 """cdefs for marshaller.py"""
import cython
from ..signature cimport SignatureTree, SignatureType, Variant
cdef object PACK_UINT32
cdef bytes PACKED_UINT32_ZERO
cdef bytes PACKED_BOOL_TRUE
cdef bytes PACKED_BOOL_FALSE
cdef get_signature_tree
cdef class Marshaller:
cdef SignatureTree signature_tree
cdef bytearray _buf
cdef cython.list body
cdef _buffer(self)
cpdef align(self, unsigned int n)
@cython.locals(
offset=cython.ulong,
)
cdef unsigned int _align(self, unsigned int n)
cpdef write_boolean(self, object boolean, SignatureType type_)
@cython.locals(
written=cython.uint,
)
cdef unsigned int _write_boolean(self, object boolean)
cpdef write_string(self, object value, SignatureType type_)
@cython.locals(
buf=cython.bytearray,
value_len=cython.uint,
signature_len=cython.uint,
written=cython.uint,
)
cdef unsigned int _write_string(self, object value)
@cython.locals(
signature_len=cython.uint,
)
cdef unsigned int _write_signature(self, bytes signature_bytes)
cpdef write_array(self, object array, SignatureType type_)
@cython.locals(
array_len=cython.uint,
buf=cython.bytearray,
written=cython.uint,
token=cython.str,
child_type=SignatureType,
array_len_packed=cython.bytes,
size=cython.uint,
writer=cython.object,
packer=cython.object,
i=cython.uint,
)
cdef unsigned int _write_array(self, object array, SignatureType type_)
cpdef write_struct(self, object array, SignatureType type_)
@cython.locals(
written=cython.uint,
i=cython.uint,
)
cdef unsigned int _write_struct(self, object array, SignatureType type_)
cpdef write_variant(self, Variant variant, SignatureType type_)
@cython.locals(
written=cython.uint,
signature=cython.str,
signature_bytes=cython.bytes,
)
cdef unsigned int _write_variant(self, Variant variant, SignatureType type_)
@cython.locals(
written=cython.uint,
size=cython.uint,
)
cdef unsigned int _write_single(self, SignatureType type_, object body)
@cython.locals(
written=cython.uint,
t=cython.str,
)
cpdef write_dict_entry(self, cython.list dict_entry, SignatureType type_)
cpdef marshall(self)
cdef _marshall(self)
@cython.locals(
offset=cython.ulong,
t=cython.str,
size=cython.uint,
writer=cython.object,
packer=cython.object,
type_=SignatureType,
)
cdef _construct_buffer(self)
dbus-fast-2.44.1/src/dbus_fast/_private/marshaller.py 0000664 0000000 0000000 00000017164 14773556132 0022576 0 ustar 00root root 0000000 0000000 from __future__ import annotations
from struct import Struct, error
from typing import Any, Callable
from ..signature import SignatureType, Variant, get_signature_tree
PACK_LITTLE_ENDIAN = "<"
PACK_UINT32 = Struct(f"{PACK_LITTLE_ENDIAN}I").pack
PACKED_UINT32_ZERO = PACK_UINT32(0)
PACKED_BOOL_FALSE = PACK_UINT32(0)
PACKED_BOOL_TRUE = PACK_UINT32(1)
_int = int
_bytes = bytes
_str = str
class Marshaller:
"""Marshall data for Dbus."""
__slots__ = ("_buf", "body", "signature_tree")
def __init__(self, signature: str, body: list[Any]) -> None:
"""Marshaller constructor."""
self.signature_tree = get_signature_tree(signature)
self._buf = bytearray()
self.body = body
@property
def buffer(self) -> bytearray:
return self._buf
def _buffer(self) -> bytearray:
return self._buf
def align(self, n: _int) -> int:
return self._align(n)
def _align(self, n: _int) -> _int:
offset = n - len(self._buf) % n
if offset == 0 or offset == n:
return 0
for _ in range(offset):
self._buf.append(0)
return offset
def write_boolean(self, boolean: bool, type_: SignatureType) -> int:
return self._write_boolean(boolean)
def _write_boolean(self, boolean: bool) -> int:
written = self._align(4)
self._buf += PACKED_BOOL_TRUE if boolean else PACKED_BOOL_FALSE
return written + 4
def write_signature(self, signature: str, type_: SignatureType) -> int:
return self._write_signature(signature.encode())
def _write_signature(self, signature_bytes: _bytes) -> int:
signature_len = len(signature_bytes)
buf = self._buf
buf.append(signature_len)
buf += signature_bytes
buf.append(0)
return signature_len + 2
def write_string(self, value: _str, type_: SignatureType) -> int:
return self._write_string(value)
def _write_string(self, value: _str) -> int:
value_bytes = value.encode()
value_len = len(value_bytes)
written = self._align(4) + 4
buf = self._buf
buf += PACK_UINT32(value_len)
buf += value_bytes
written += value_len
buf.append(0)
written += 1
return written
def write_variant(self, variant: Variant, type_: SignatureType) -> int:
return self._write_variant(variant, type_)
def _write_variant(self, variant: Variant, type_: SignatureType) -> int:
signature = variant.signature
signature_bytes = signature.encode()
written = self._write_signature(signature_bytes)
written += self._write_single(variant.type, variant.value)
return written
def write_array(
self, array: bytes | list[Any] | dict[Any, Any], type_: SignatureType
) -> int:
return self._write_array(array, type_)
def _write_array(
self, array: bytes | list[Any] | dict[Any, Any], type_: SignatureType
) -> int:
# TODO max array size is 64MiB (67108864 bytes)
written = self._align(4)
# length placeholder
buf: bytearray = self._buf
offset = len(buf)
written += self._align(4) + 4
buf += PACKED_UINT32_ZERO
child_type = type_.children[0]
token = child_type.token
if token in "xtd{(":
# the first alignment is not included in array size
written += self._align(8)
array_len = 0
if token == "{":
for key, value in array.items(): # type: ignore[union-attr]
array_len += self.write_dict_entry([key, value], child_type)
elif token == "y":
array_len = len(array)
buf += array # type: ignore[arg-type]
elif token == "(":
for value in array:
array_len += self._write_struct(value, child_type)
else:
writer, packer, size = self._writers[token]
if not writer:
for value in array:
array_len += self._align(size) + size
buf += packer(value) # type: ignore[misc]
else:
for value in array:
array_len += writer(self, value, child_type)
array_len_packed = PACK_UINT32(array_len)
for i in range(offset, offset + 4):
buf[i] = array_len_packed[i - offset]
return written + array_len
def write_struct(self, array: tuple[Any] | list[Any], type_: SignatureType) -> int:
return self._write_struct(array, type_)
def _write_struct(self, array: tuple[Any] | list[Any], type_: SignatureType) -> int:
written = self._align(8)
for i, value in enumerate(array):
written += self._write_single(type_.children[i], value)
return written
def write_dict_entry(self, dict_entry: list[Any], type_: SignatureType) -> int:
written = self._align(8)
written += self._write_single(type_.children[0], dict_entry[0])
written += self._write_single(type_.children[1], dict_entry[1])
return written
def _write_single(self, type_: SignatureType, body: Any) -> int:
t = type_.token
if t == "y":
self._buf.append(body)
return 1
if t == "u":
written = self._align(4)
self._buf += PACK_UINT32(body)
return written + 4
if t == "a":
return self._write_array(body, type_)
if t == "s" or t == "o":
return self._write_string(body)
if t == "v":
return self._write_variant(body, type_)
if t == "b":
return self._write_boolean(body)
writer, packer, size = self._writers[t]
if not writer:
written = self._align(size)
self._buf += packer(body) # type: ignore[misc]
return written + size
return writer(self, body, type_)
def marshall(self) -> bytearray:
"""Marshalls the body into a byte array"""
return self._marshall()
def _marshall(self) -> bytearray:
"""Marshalls the body into a byte array"""
try:
return self._construct_buffer()
except KeyError as ex:
raise NotImplementedError(
f'type is not implemented yet: "{ex.args}"'
) from ex
except error:
self.signature_tree.verify(self.body)
raise RuntimeError("should not reach here")
def _construct_buffer(self) -> bytearray:
self._buf.clear()
body = self.body
for i, type_ in enumerate(self.signature_tree.types):
self._write_single(type_, body[i])
return self._buf
_writers: dict[
str,
tuple[
Callable[[Any, Any, SignatureType], int] | None,
Callable[[Any], bytes] | None,
int,
],
] = {
"y": (None, Struct(f"{PACK_LITTLE_ENDIAN}B").pack, 1),
"b": (write_boolean, None, 0),
"n": (None, Struct(f"{PACK_LITTLE_ENDIAN}h").pack, 2),
"q": (None, Struct(f"{PACK_LITTLE_ENDIAN}H").pack, 2),
"i": (None, Struct(f"{PACK_LITTLE_ENDIAN}i").pack, 4),
"u": (None, PACK_UINT32, 4),
"x": (None, Struct(f"{PACK_LITTLE_ENDIAN}q").pack, 8),
"t": (None, Struct(f"{PACK_LITTLE_ENDIAN}Q").pack, 8),
"d": (None, Struct(f"{PACK_LITTLE_ENDIAN}d").pack, 8),
"h": (None, Struct(f"{PACK_LITTLE_ENDIAN}I").pack, 4),
"o": (write_string, None, 0),
"s": (write_string, None, 0),
"g": (write_signature, None, 0),
"a": (write_array, None, 0),
"(": (write_struct, None, 0),
"{": (write_dict_entry, None, 0),
"v": (write_variant, None, 0),
}
dbus-fast-2.44.1/src/dbus_fast/_private/unmarshaller.pxd 0000664 0000000 0000000 00000015664 14773556132 0023307 0 ustar 00root root 0000000 0000000 """cdefs for unmarshaller.py"""
import cython
from ..message cimport Message
from ..signature cimport SignatureTree, SignatureType, Variant
cdef bint TYPE_CHECKING
cdef object MAX_UNIX_FDS_SIZE
cdef object ARRAY
cdef object UNIX_FDS_CMSG_LENGTH
cdef object SOL_SOCKET
cdef object SCM_RIGHTS
cdef object MESSAGE_FLAG_INTENUM
cdef unsigned int UINT32_SIZE
cdef unsigned int INT16_SIZE
cdef unsigned int UINT16_SIZE
cdef unsigned int HEADER_ARRAY_OF_STRUCT_SIGNATURE_POSITION
cdef unsigned int HEADER_SIGNATURE_SIZE
cdef unsigned int LITTLE_ENDIAN
cdef unsigned int BIG_ENDIAN
cdef unsigned int PROTOCOL_VERSION
cdef unsigned int HEADER_PATH_IDX
cdef unsigned int HEADER_INTERFACE_IDX
cdef unsigned int HEADER_MEMBER_IDX
cdef unsigned int HEADER_ERROR_NAME_IDX
cdef unsigned int HEADER_REPLY_SERIAL_IDX
cdef unsigned int HEADER_DESTINATION_IDX
cdef unsigned int HEADER_SENDER_IDX
cdef unsigned int HEADER_SIGNATURE_IDX
cdef unsigned int HEADER_UNIX_FDS_IDX
cdef cython.list HEADER_IDX_TO_ARG_NAME
cdef str UINT32_CAST
cdef str INT16_CAST
cdef str UINT16_CAST
cdef bint SYS_IS_LITTLE_ENDIAN
cdef bint SYS_IS_BIG_ENDIAN
cdef object UNPACK_HEADER_LITTLE_ENDIAN
cdef object UNPACK_HEADER_BIG_ENDIAN
cdef object UINT32_UNPACK_LITTLE_ENDIAN
cdef object UINT32_UNPACK_BIG_ENDIAN
cdef object INT16_UNPACK_LITTLE_ENDIAN
cdef object INT16_UNPACK_BIG_ENDIAN
cdef object UINT16_UNPACK_LITTLE_ENDIAN
cdef object UINT16_UNPACK_BIG_ENDIAN
cdef cython.dict MESSAGE_TYPE_MAP
cdef cython.dict MESSAGE_FLAG_MAP
cdef dict HEADER_MESSAGE_ARG_NAME
cdef SignatureTree SIGNATURE_TREE_EMPTY
cdef SignatureTree SIGNATURE_TREE_B
cdef SignatureTree SIGNATURE_TREE_N
cdef SignatureTree SIGNATURE_TREE_O
cdef SignatureTree SIGNATURE_TREE_S
cdef SignatureTree SIGNATURE_TREE_U
cdef SignatureTree SIGNATURE_TREE_Y
cdef SignatureTree SIGNATURE_TREE_AS
cdef SignatureType SIGNATURE_TREE_AS_TYPES_0
cdef SignatureTree SIGNATURE_TREE_AO
cdef SignatureType SIGNATURE_TREE_AO_TYPES_0
cdef SignatureTree SIGNATURE_TREE_A_SV
cdef SignatureType SIGNATURE_TREE_A_SV_TYPES_0
cdef SignatureTree SIGNATURE_TREE_SA_SV_AS
cdef SignatureType SIGNATURE_TREE_SA_SV_AS_TYPES_1
cdef SignatureType SIGNATURE_TREE_SA_SV_AS_TYPES_2
cdef SignatureTree SIGNATURE_TREE_OAS
cdef SignatureType SIGNATURE_TREE_OAS_TYPES_1
cdef SignatureTree SIGNATURE_TREE_OA_SA_SV
cdef SignatureType SIGNATURE_TREE_OA_SA_SV_TYPES_1
cdef SignatureTree SIGNATURE_TREE_AY
cdef SignatureType SIGNATURE_TREE_AY_TYPES_0
cdef SignatureTree SIGNATURE_TREE_A_QV
cdef SignatureType SIGNATURE_TREE_A_QV_TYPES_0
cdef SignatureTree SIGNATURE_TREE_A_OA_SA_SV
cdef SignatureType SIGNATURE_TREE_A_OA_SA_SV_TYPES_0
cdef unsigned int TOKEN_B_AS_INT
cdef unsigned int TOKEN_U_AS_INT
cdef unsigned int TOKEN_Y_AS_INT
cdef unsigned int TOKEN_A_AS_INT
cdef unsigned int TOKEN_O_AS_INT
cdef unsigned int TOKEN_S_AS_INT
cdef unsigned int TOKEN_G_AS_INT
cdef unsigned int TOKEN_N_AS_INT
cdef unsigned int TOKEN_X_AS_INT
cdef unsigned int TOKEN_T_AS_INT
cdef unsigned int TOKEN_D_AS_INT
cdef unsigned int TOKEN_Q_AS_INT
cdef unsigned int TOKEN_V_AS_INT
cdef unsigned int TOKEN_LEFT_CURLY_AS_INT
cdef unsigned int TOKEN_LEFT_PAREN_AS_INT
cdef object MARSHALL_STREAM_END_ERROR
cdef object DEFAULT_BUFFER_SIZE
cdef Variant VARIANT_BOOL_TRUE
cdef Variant VARIANT_BOOL_FALSE
cdef list _EMPTY_HEADERS
cdef cython.uint EAGAIN
cdef cython.uint EWOULDBLOCK
cdef get_signature_tree
cdef unsigned int _ustr_uint32(const unsigned char * buf, unsigned int offset, unsigned int endian) noexcept
cdef short _ustr_int16(const unsigned char * buf, unsigned int offset, unsigned int endian) noexcept
cdef unsigned short _ustr_uint16(const unsigned char * buf, unsigned int offset, unsigned int endian) noexcept
cdef class Unmarshaller:
cdef list _unix_fds
cdef bytearray _buf
cdef Py_ssize_t _buf_len
cdef const unsigned char * _buf_ustr
cdef unsigned int _pos
cdef object _stream
cdef object _sock
cdef Message _message
cdef object _readers
cdef unsigned int _body_len
cdef unsigned int _serial
cdef unsigned int _header_len
cdef object _message_type
cdef object _flag
cdef unsigned int _msg_len
cdef object _uint32_unpack
cdef object _int16_unpack
cdef object _uint16_unpack
cdef object _stream_reader
cdef object _sock_with_fds_reader
cdef object _sock_without_fds_reader
cdef bint _negotiate_unix_fd
cdef bint _read_complete
cdef unsigned int _endian
@cython.locals(to_clear=Py_ssize_t)
cdef _next_message(self)
cdef bint _has_another_message_in_buffer(self)
@cython.locals(
msg=cython.bytes,
recv=cython.tuple,
errno=cython.uint
)
cdef void _read_sock_with_fds(self, unsigned int pos, unsigned int missing_bytes) except *
@cython.locals(
data=cython.bytes,
errno=cython.uint
)
cdef void _read_sock_without_fds(self, unsigned int pos) except *
@cython.locals(
data=cython.bytes
)
cdef void _read_stream(self, unsigned int pos, unsigned int missing_bytes) except *
cdef void _read_to_pos(self, unsigned int pos) except *
cpdef read_boolean(self, SignatureType type_)
cdef bint _read_boolean(self)
cpdef read_uint32_unpack(self, SignatureType type_)
cdef unsigned int _read_uint32_unpack(self)
cpdef read_int16_unpack(self, SignatureType type_)
cdef int _read_int16_unpack(self)
cpdef read_uint16_unpack(self, SignatureType type_)
cdef unsigned int _read_uint16_unpack(self)
cpdef read_string_unpack(self, SignatureType type_)
@cython.locals(
str_start=cython.uint,
)
cdef str _read_string_unpack(self)
@cython.locals(
tree=SignatureTree,
token_as_int=cython.uint,
var=Variant,
)
cdef Variant _read_variant(self)
@cython.locals(
beginning_pos=cython.ulong,
array_length=cython.uint,
children=cython.list,
child_type=SignatureType,
child_0=SignatureType,
child_1=SignatureType,
token_as_int=cython.uint,
)
cpdef object read_array(self, SignatureType type_)
cpdef read_signature(self, SignatureType type_)
@cython.locals(
o=cython.ulong,
signature_len=cython.uint,
)
cdef str _read_signature(self)
@cython.locals(
endian=cython.uint,
buffer=cython.bytearray,
protocol_version=cython.uint,
key=cython.str,
ustring="const unsigned char *",
)
cdef void _read_header(self) except *
@cython.locals(
body=list,
header_fields=list,
token_as_int="unsigned int",
signature=str,
tree=SignatureTree,
message=Message
)
cdef void _read_body(self) except *
cdef Message _unmarshall(self)
cpdef unmarshall(self)
@cython.locals(
beginning_pos=cython.ulong,
o=cython.ulong,
token_as_int=cython.uint,
signature_len=cython.uint,
headers=cython.list
)
cdef cython.list _header_fields(self, unsigned int header_length)
dbus-fast-2.44.1/src/dbus_fast/_private/unmarshaller.py 0000664 0000000 0000000 00000102674 14773556132 0023142 0 ustar 00root root 0000000 0000000 from __future__ import annotations
import array
import errno
import io
import socket
import sys
from collections.abc import Iterable
from struct import Struct
from typing import TYPE_CHECKING, Any, Callable
from ..constants import MESSAGE_FLAG_MAP, MESSAGE_TYPE_MAP, MessageFlag
from ..errors import InvalidMessageError
from ..message import Message
from ..signature import SignatureType, Variant, get_signature_tree
from .constants import BIG_ENDIAN, LITTLE_ENDIAN, PROTOCOL_VERSION
MESSAGE_FLAG_INTENUM = MessageFlag
MAX_UNIX_FDS = 16
MAX_UNIX_FDS_SIZE = array.array("i").itemsize
UNIX_FDS_CMSG_LENGTH = socket.CMSG_LEN(MAX_UNIX_FDS_SIZE)
UNPACK_SYMBOL = {LITTLE_ENDIAN: "<", BIG_ENDIAN: ">"}
UINT32_CAST = "I"
UINT32_SIZE = 4
UINT32_DBUS_TYPE = "u"
INT16_CAST = "h"
INT16_SIZE = 2
INT16_DBUS_TYPE = "n"
UINT16_CAST = "H"
UINT16_SIZE = 2
UINT16_DBUS_TYPE = "q"
SYS_IS_LITTLE_ENDIAN = sys.byteorder == "little"
SYS_IS_BIG_ENDIAN = sys.byteorder == "big"
DBUS_TO_CTYPE = {
"y": ("B", 1), # byte
INT16_DBUS_TYPE: (INT16_CAST, INT16_SIZE), # int16
UINT16_DBUS_TYPE: (UINT16_CAST, UINT16_SIZE), # uint16
"i": ("i", 4), # int32
UINT32_DBUS_TYPE: (UINT32_CAST, UINT32_SIZE), # uint32
"x": ("q", 8), # int64
"t": ("Q", 8), # uint64
"d": ("d", 8), # double
"h": (UINT32_CAST, UINT32_SIZE), # uint32
}
UNPACK_HEADER_LITTLE_ENDIAN = Struct("III").unpack_from
UINT32_UNPACK_LITTLE_ENDIAN = Struct(f"<{UINT32_CAST}").unpack_from
UINT32_UNPACK_BIG_ENDIAN = Struct(f">{UINT32_CAST}").unpack_from
INT16_UNPACK_LITTLE_ENDIAN = Struct(f"<{INT16_CAST}").unpack_from
INT16_UNPACK_BIG_ENDIAN = Struct(f">{INT16_CAST}").unpack_from
UINT16_UNPACK_LITTLE_ENDIAN = Struct(f"<{UINT16_CAST}").unpack_from
UINT16_UNPACK_BIG_ENDIAN = Struct(f">{UINT16_CAST}").unpack_from
HEADER_SIGNATURE_SIZE = 16
HEADER_ARRAY_OF_STRUCT_SIGNATURE_POSITION = 12
# Most common signatures
SIGNATURE_TREE_EMPTY = get_signature_tree("")
SIGNATURE_TREE_B = get_signature_tree("b")
SIGNATURE_TREE_N = get_signature_tree("n")
SIGNATURE_TREE_S = get_signature_tree("s")
SIGNATURE_TREE_O = get_signature_tree("o")
SIGNATURE_TREE_U = get_signature_tree("u")
SIGNATURE_TREE_Y = get_signature_tree("y")
SIGNATURE_TREE_AY = get_signature_tree("ay")
SIGNATURE_TREE_AS = get_signature_tree("as")
SIGNATURE_TREE_AS_TYPES_0 = SIGNATURE_TREE_AS.root_type
SIGNATURE_TREE_A_SV = get_signature_tree("a{sv}")
SIGNATURE_TREE_A_SV_TYPES_0 = SIGNATURE_TREE_A_SV.root_type
SIGNATURE_TREE_AO = get_signature_tree("ao")
SIGNATURE_TREE_AO_TYPES_0 = SIGNATURE_TREE_AO.root_type
SIGNATURE_TREE_OAS = get_signature_tree("oas")
SIGNATURE_TREE_OAS_TYPES_1 = SIGNATURE_TREE_OAS.types[1]
SIGNATURE_TREE_AY_TYPES_0 = SIGNATURE_TREE_AY.root_type
SIGNATURE_TREE_A_QV = get_signature_tree("a{qv}")
SIGNATURE_TREE_A_QV_TYPES_0 = SIGNATURE_TREE_A_QV.root_type
SIGNATURE_TREE_SA_SV_AS = get_signature_tree("sa{sv}as")
SIGNATURE_TREE_SA_SV_AS_TYPES_1 = SIGNATURE_TREE_SA_SV_AS.types[1]
SIGNATURE_TREE_SA_SV_AS_TYPES_2 = SIGNATURE_TREE_SA_SV_AS.types[2]
SIGNATURE_TREE_OA_SA_SV = get_signature_tree("oa{sa{sv}}")
SIGNATURE_TREE_OA_SA_SV_TYPES_1 = SIGNATURE_TREE_OA_SA_SV.types[1]
SIGNATURE_TREE_A_OA_SA_SV = get_signature_tree("a{oa{sa{sv}}}")
SIGNATURE_TREE_A_OA_SA_SV_TYPES_0 = SIGNATURE_TREE_A_OA_SA_SV.root_type
TOKEN_B_AS_INT = ord("b")
TOKEN_U_AS_INT = ord("u")
TOKEN_Y_AS_INT = ord("y")
TOKEN_A_AS_INT = ord("a")
TOKEN_O_AS_INT = ord("o")
TOKEN_S_AS_INT = ord("s")
TOKEN_G_AS_INT = ord("g")
TOKEN_N_AS_INT = ord("n")
TOKEN_X_AS_INT = ord("x")
TOKEN_T_AS_INT = ord("t")
TOKEN_D_AS_INT = ord("d")
TOKEN_Q_AS_INT = ord("q")
TOKEN_V_AS_INT = ord("v")
TOKEN_LEFT_CURLY_AS_INT = ord("{")
TOKEN_LEFT_PAREN_AS_INT = ord("(")
VARIANT_BOOL_TRUE = Variant._factory(SIGNATURE_TREE_B, True)
VARIANT_BOOL_FALSE = Variant._factory(SIGNATURE_TREE_B, False)
ARRAY = array.array
SOL_SOCKET = socket.SOL_SOCKET
SCM_RIGHTS = socket.SCM_RIGHTS
EAGAIN = errno.EAGAIN
EWOULDBLOCK = errno.EWOULDBLOCK
HEADER_IDX_TO_ARG_NAME = [
"",
"path",
"interface",
"member",
"error_name",
"reply_serial",
"destination",
"sender",
"signature",
"unix_fds",
]
HEADER_PATH_IDX = HEADER_IDX_TO_ARG_NAME.index("path")
HEADER_INTERFACE_IDX = HEADER_IDX_TO_ARG_NAME.index("interface")
HEADER_MEMBER_IDX = HEADER_IDX_TO_ARG_NAME.index("member")
HEADER_ERROR_NAME_IDX = HEADER_IDX_TO_ARG_NAME.index("error_name")
HEADER_REPLY_SERIAL_IDX = HEADER_IDX_TO_ARG_NAME.index("reply_serial")
HEADER_DESTINATION_IDX = HEADER_IDX_TO_ARG_NAME.index("destination")
HEADER_SENDER_IDX = HEADER_IDX_TO_ARG_NAME.index("sender")
HEADER_SIGNATURE_IDX = HEADER_IDX_TO_ARG_NAME.index("signature")
HEADER_UNIX_FDS_IDX = HEADER_IDX_TO_ARG_NAME.index("unix_fds")
_EMPTY_HEADERS: list[Any | None] = [None] * len(HEADER_IDX_TO_ARG_NAME)
_SignatureType = SignatureType
_int = int
READER_TYPE = Callable[["Unmarshaller", SignatureType], Any]
MARSHALL_STREAM_END_ERROR = BlockingIOError
DEFAULT_BUFFER_SIZE = io.DEFAULT_BUFFER_SIZE
def unpack_parser_factory(unpack_from: Callable, size: int) -> READER_TYPE:
"""Build a parser that unpacks the bytes using the given unpack_from function."""
def _unpack_from_parser(self: Unmarshaller, signature: SignatureType) -> Any:
self._pos += size + (-self._pos & (size - 1)) # align
return unpack_from(self._buf, self._pos - size)[0]
return _unpack_from_parser
def build_simple_parsers(
endian: int,
) -> dict[str, Callable[[Unmarshaller, SignatureType], Any]]:
"""Build a dict of parsers for simple types."""
parsers: dict[str, READER_TYPE] = {}
for dbus_type, ctype_size in DBUS_TO_CTYPE.items():
ctype, size = ctype_size
size = ctype_size[1]
parsers[dbus_type] = unpack_parser_factory(
Struct(f"{UNPACK_SYMBOL[endian]}{ctype}").unpack_from, size
)
return parsers
try:
import cython
except ImportError:
from ._cython_compat import FAKE_CYTHON as cython
int_ = int
bytearray_ = bytearray
def is_compiled() -> bool:
return cython.compiled
def _ustr_uint32(buf: bytearray_, pos: int_, endian: int_) -> int_:
if endian == LITTLE_ENDIAN:
return (
buf[pos] | (buf[pos + 1] << 8) | (buf[pos + 2] << 16) | (buf[pos + 3] << 24)
)
return buf[pos + 3] | (buf[pos + 2] << 8) | (buf[pos + 1] << 16) | (buf[pos] << 24)
def buffer_to_uint32(buf: bytearray, pos: int, endian: int) -> int:
return _ustr_uint32(buf, pos, endian)
def _ustr_int16(buf: bytearray_, pos: int_, endian: int_) -> int_:
# Caution: this function will only work with Cython
# because it relies on casting the result to a signed int
# and will return an unsigned int if not compiled.
if endian == LITTLE_ENDIAN:
return buf[pos] | (buf[pos + 1] << 8) # pragma: no cover
return buf[pos + 1] | (buf[pos] << 8) # pragma: no cover
def buffer_to_int16(buf: bytearray | bytes, pos: int, endian: int) -> int:
# Caution: this function will only work with Cython
# because it relies on casting the result to a signed int
# and will return an unsigned int if not compiled.
return _ustr_int16(buf, pos, endian)
def _ustr_uint16(buf: bytearray_, pos: int_, endian: int_) -> int_:
if endian == LITTLE_ENDIAN:
return buf[pos] | (buf[pos + 1] << 8)
return buf[pos + 1] | (buf[pos] << 8)
def buffer_to_uint16(buf: bytearray, pos: int, endian: int) -> int:
return _ustr_uint16(buf, pos, endian)
# Alignment padding is handled with the following formula below
#
# For any align value, the correct padding formula is:
#
# (align - (pos % align)) % align
#
# However, if align is a power of 2 (always the case here), the slow MOD
# operator can be replaced by a bitwise AND:
#
# (align - (pos & (align - 1))) & (align - 1)
#
# Which can be simplified to:
#
# (-pos) & (align - 1)
#
#
class Unmarshaller:
"""Unmarshall messages from a stream.
When calling with sock and _negotiate_unix_fd False, the unmashaller must
be called continuously for each new message as it will buffer the data
until a complete message is available.
"""
__slots__ = (
"_body_len",
"_buf",
"_buf_len",
"_buf_ustr",
"_endian",
"_flag",
"_header_len",
"_int16_unpack",
"_message",
"_message_type",
"_msg_len",
"_negotiate_unix_fd",
"_pos",
"_read_complete",
"_readers",
"_serial",
"_sock",
"_sock_with_fds_reader",
"_sock_without_fds_reader",
"_stream",
"_stream_reader",
"_uint16_unpack",
"_uint32_unpack",
"_unix_fds",
)
_stream_reader: Callable[[int], bytes]
def __init__(
self,
stream: io.BufferedRWPair | None = None,
sock: socket.socket | None = None,
negotiate_unix_fd: bool = True,
) -> None:
self._unix_fds: list[int] = []
self._buf: bytearray = bytearray.__new__(bytearray) # Actual buffer
self._buf_ustr = self._buf # Used to avoid type checks
self._buf_len = 0
self._stream = stream
self._sock = sock
self._message: Message | None = None
self._readers: dict[str, READER_TYPE] = {}
self._pos = 0
self._body_len = 0
self._serial = 0
self._header_len = 0
self._message_type = 0
self._flag = 0
self._msg_len = 0
self._uint32_unpack: Callable[[bytearray, int], tuple[int]] | None = None
self._int16_unpack: Callable[[bytearray, int], tuple[int]] | None = None
self._uint16_unpack: Callable[[bytearray, int], tuple[int]] | None = None
self._negotiate_unix_fd = negotiate_unix_fd
self._read_complete = False
if stream:
if isinstance(stream, io.BufferedRWPair) and hasattr(stream, "reader"):
self._stream_reader = stream.reader.read
else:
self._stream_reader = stream.read
elif self._negotiate_unix_fd:
if TYPE_CHECKING:
assert self._sock is not None
self._sock_with_fds_reader = self._sock.recvmsg
else:
if TYPE_CHECKING:
assert self._sock is not None
self._sock_without_fds_reader = self._sock.recv
self._endian = 0
def _next_message(self) -> None:
"""Reset the unmarshaller to its initial state.
Call this before processing a new message.
"""
if self._unix_fds:
self._unix_fds = []
to_clear = HEADER_SIGNATURE_SIZE + self._msg_len
if self._buf_len == to_clear:
self._buf = bytearray.__new__(bytearray)
self._buf_len = 0
else:
del self._buf[:to_clear]
self._buf_len -= to_clear
self._buf_ustr = self._buf
self._msg_len = 0 # used to check if we have ready the header
self._read_complete = False # used to check if we have ready the message
# No need to reset the unpack functions, they are set in _read_header
# every time a new message is processed.
@property
def message(self) -> Message | None:
"""Return the message that has been unmarshalled."""
if self._read_complete:
return self._message
return None
def _has_another_message_in_buffer(self) -> bool:
"""Check if there is another message in the buffer."""
return self._buf_len > HEADER_SIGNATURE_SIZE + self._msg_len
def _read_sock_with_fds(self, pos: _int, missing_bytes: _int) -> None:
"""reads from the socket, storing any fds sent and handling errors
from the read itself.
This function is greedy and will read as much data as possible
from the underlying socket.
"""
# This will raise BlockingIOError if there is no data to read
# which we store in the MARSHALL_STREAM_END_ERROR object
try:
recv = self._sock_with_fds_reader(missing_bytes, UNIX_FDS_CMSG_LENGTH)
except OSError as e:
errno = e.errno
if errno == EAGAIN or errno == EWOULDBLOCK:
raise MARSHALL_STREAM_END_ERROR
raise
msg = recv[0]
ancdata = recv[1]
if ancdata:
for level, type_, data in ancdata:
if not (level == SOL_SOCKET and type_ == SCM_RIGHTS):
continue
self._unix_fds.extend(
ARRAY("i", data[: len(data) - (len(data) % MAX_UNIX_FDS_SIZE)])
)
if not msg:
raise EOFError
self._buf += msg
self._buf_len = len(self._buf)
if self._buf_len < pos:
raise MARSHALL_STREAM_END_ERROR
def _read_sock_without_fds(self, pos: _int) -> None:
"""reads from the socket and handling errors from the read itself.
This function is greedy and will read as much data as possible
from the underlying socket.
"""
# This will raise BlockingIOError if there is no data to read
# which we store in the MARSHALL_STREAM_END_ERROR object
while True:
try:
data = self._sock_without_fds_reader(DEFAULT_BUFFER_SIZE)
except OSError as e:
errno = e.errno
if errno == EAGAIN or errno == EWOULDBLOCK:
raise MARSHALL_STREAM_END_ERROR
raise
if not data:
raise EOFError
self._buf += data
self._buf_len = len(self._buf)
if self._buf_len >= pos:
return
def _read_stream(self, pos: _int, missing_bytes: _int) -> None:
"""Read from the stream."""
data = self._stream_reader(missing_bytes)
if data is None:
raise MARSHALL_STREAM_END_ERROR
if not data:
raise EOFError
self._buf += data
self._buf_len = len(self._buf)
if self._buf_len < pos:
raise MARSHALL_STREAM_END_ERROR
def _read_to_pos(self, pos: _int) -> None:
"""
Read from underlying socket into buffer.
Raises BlockingIOError if there is not enough data to be read.
:arg pos:
The pos to read to. If not enough bytes are available in the
buffer, read more from it.
:returns:
None
"""
missing_bytes = pos - self._buf_len
if missing_bytes <= 0:
return
if self._sock is None:
self._read_stream(pos, missing_bytes)
elif self._negotiate_unix_fd:
self._read_sock_with_fds(pos, missing_bytes)
else:
self._read_sock_without_fds(pos)
self._buf_ustr = self._buf
def read_uint32_unpack(self, type_: _SignatureType) -> int:
return self._read_uint32_unpack()
def _read_uint32_unpack(self) -> int:
self._pos += UINT32_SIZE + (-self._pos & (UINT32_SIZE - 1)) # align
if cython.compiled:
if self._buf_len < self._pos:
raise IndexError("Not enough data to read uint32")
return _ustr_uint32(self._buf_ustr, self._pos - UINT32_SIZE, self._endian)
return self._uint32_unpack(self._buf, self._pos - UINT32_SIZE)[0]
def read_uint16_unpack(self, type_: _SignatureType) -> int:
return self._read_uint16_unpack()
def _read_uint16_unpack(self) -> int:
self._pos += UINT16_SIZE + (-self._pos & (UINT16_SIZE - 1)) # align
if cython.compiled:
if self._buf_len < self._pos:
raise IndexError("Not enough data to read uint16")
return _ustr_uint16(self._buf_ustr, self._pos - UINT16_SIZE, self._endian)
return self._uint16_unpack(self._buf, self._pos - UINT16_SIZE)[0]
def read_int16_unpack(self, type_: _SignatureType) -> int:
return self._read_int16_unpack()
def _read_int16_unpack(self) -> int:
self._pos += INT16_SIZE + (-self._pos & (INT16_SIZE - 1)) # align
if cython.compiled:
if self._buf_len < self._pos:
raise IndexError("Not enough data to read int16")
return _ustr_int16(self._buf_ustr, self._pos - INT16_SIZE, self._endian)
return self._int16_unpack(self._buf, self._pos - INT16_SIZE)[0]
def read_boolean(self, type_: _SignatureType) -> bool:
return self._read_boolean()
def _read_boolean(self) -> bool:
return bool(self._read_uint32_unpack())
def read_string_unpack(self, type_: _SignatureType) -> str:
return self._read_string_unpack()
def _read_string_unpack(self) -> str:
"""Read a string using unpack."""
self._pos += UINT32_SIZE + (-self._pos & (UINT32_SIZE - 1)) # align
str_start = self._pos
# read terminating '\0' byte as well (str_length + 1)
if cython.compiled:
if self._buf_len < self._pos:
raise IndexError("Not enough data to read uint32")
self._pos += (
_ustr_uint32(self._buf_ustr, str_start - UINT32_SIZE, self._endian) + 1
)
if self._buf_len < self._pos:
raise IndexError("Not enough data to read string")
else:
self._pos += self._uint32_unpack(self._buf, str_start - UINT32_SIZE)[0] + 1
return self._buf_ustr[str_start : self._pos - 1].decode()
def read_signature(self, type_: _SignatureType) -> str:
return self._read_signature()
def _read_signature(self) -> str:
if cython.compiled:
if self._buf_len < self._pos:
raise IndexError("Not enough data to read signature")
signature_len = self._buf_ustr[self._pos] # byte
o = self._pos + 1
# read terminating '\0' byte as well (str_length + 1)
self._pos = o + signature_len + 1
if cython.compiled:
if self._buf_len < self._pos:
raise IndexError("Not enough data to read signature")
return self._buf_ustr[o : o + signature_len].decode()
def read_variant(self, type_: _SignatureType) -> Variant:
return self._read_variant()
def _read_variant(self) -> Variant:
signature = self._read_signature()
token_as_int = ord(signature[0])
# verify in Variant is only useful on construction not unmarshalling
if len(signature) == 1:
if token_as_int == TOKEN_N_AS_INT:
return Variant._factory(SIGNATURE_TREE_N, self._read_int16_unpack())
if token_as_int == TOKEN_S_AS_INT:
return Variant._factory(SIGNATURE_TREE_S, self._read_string_unpack())
if token_as_int == TOKEN_B_AS_INT:
return VARIANT_BOOL_TRUE if self._read_boolean() else VARIANT_BOOL_FALSE
if token_as_int == TOKEN_O_AS_INT:
return Variant._factory(SIGNATURE_TREE_O, self._read_string_unpack())
if token_as_int == TOKEN_U_AS_INT:
return Variant._factory(SIGNATURE_TREE_U, self._read_uint32_unpack())
if token_as_int == TOKEN_Y_AS_INT:
if cython.compiled:
if self._buf_len < self._pos:
raise IndexError("Not enough data to read byte")
self._pos += 1
return Variant._factory(SIGNATURE_TREE_Y, self._buf_ustr[self._pos - 1])
elif token_as_int == TOKEN_A_AS_INT:
if signature == "ay":
return Variant._factory(
SIGNATURE_TREE_AY, self.read_array(SIGNATURE_TREE_AY_TYPES_0)
)
if signature == "a{qv}":
return Variant._factory(
SIGNATURE_TREE_A_QV, self.read_array(SIGNATURE_TREE_A_QV_TYPES_0)
)
if signature == "as":
return Variant._factory(
SIGNATURE_TREE_AS, self.read_array(SIGNATURE_TREE_AS_TYPES_0)
)
if signature == "a{sv}":
return Variant._factory(
SIGNATURE_TREE_A_SV, self.read_array(SIGNATURE_TREE_A_SV_TYPES_0)
)
if signature == "ao":
return Variant._factory(
SIGNATURE_TREE_AO, self.read_array(SIGNATURE_TREE_AO_TYPES_0)
)
tree = get_signature_tree(signature)
signature_type = tree.root_type
return Variant._factory(
tree, self._readers[signature_type.token](self, signature_type)
)
def read_struct(self, type_: _SignatureType) -> list[Any]:
self._pos += -self._pos & 7 # align 8
readers = self._readers
return [
readers[child_type.token](self, child_type) for child_type in type_.children
]
def read_dict_entry(self, type_: _SignatureType) -> tuple[Any, Any]:
self._pos += -self._pos & 7 # align 8
return self._readers[type_.children[0].token](
self, type_.children[0]
), self._readers[type_.children[1].token](self, type_.children[1])
def read_array(self, type_: _SignatureType) -> Iterable[Any]:
self._pos += -self._pos & 3 # align 4 for the array
self._pos += (
-self._pos & (UINT32_SIZE - 1)
) + UINT32_SIZE # align for the uint32
if cython.compiled:
if self._buf_len < self._pos:
raise IndexError("Not enough data to read uint32")
array_length = _ustr_uint32(
self._buf_ustr, self._pos - UINT32_SIZE, self._endian
)
else:
array_length = self._uint32_unpack(self._buf, self._pos - UINT32_SIZE)[0]
child_type = type_._child_0
token_as_int = child_type.token_as_int
if token_as_int in {
TOKEN_X_AS_INT,
TOKEN_T_AS_INT,
TOKEN_D_AS_INT,
TOKEN_LEFT_CURLY_AS_INT,
TOKEN_LEFT_PAREN_AS_INT,
}:
# the first alignment is not included in the array size
self._pos += -self._pos & 7 # align 8
if token_as_int == TOKEN_Y_AS_INT:
self._pos += array_length
if cython.compiled:
if self._buf_len < self._pos:
raise IndexError("Not enough data to read byte")
return self._buf_ustr[self._pos - array_length : self._pos]
if token_as_int == TOKEN_LEFT_CURLY_AS_INT:
result_dict: dict[Any, Any] = {}
key: str | int
beginning_pos = self._pos
child_0 = child_type._child_0
child_1 = child_type._child_1
child_0_token_as_int = child_0.token_as_int
child_1_token_as_int = child_1.token_as_int
# Strings with variant values are the most common case
# so we optimize for that by inlining the string reading
# and the variant reading here
if (
child_0_token_as_int in {TOKEN_O_AS_INT, TOKEN_S_AS_INT}
and child_1_token_as_int == TOKEN_V_AS_INT
):
while self._pos - beginning_pos < array_length:
self._pos += -self._pos & 7 # align 8
key = self._read_string_unpack()
result_dict[key] = self._read_variant()
elif (
child_0_token_as_int == TOKEN_Q_AS_INT
and child_1_token_as_int == TOKEN_V_AS_INT
):
while self._pos - beginning_pos < array_length:
self._pos += -self._pos & 7 # align 8
key = self._read_uint16_unpack()
result_dict[key] = self._read_variant()
elif (
child_0_token_as_int in {TOKEN_O_AS_INT, TOKEN_S_AS_INT}
and child_1_token_as_int == TOKEN_A_AS_INT
):
while self._pos - beginning_pos < array_length:
self._pos += -self._pos & 7 # align 8
key = self._read_string_unpack()
result_dict[key] = self.read_array(child_1)
else:
reader_1 = self._readers[child_1.token]
reader_0 = self._readers[child_0.token]
while self._pos - beginning_pos < array_length:
self._pos += -self._pos & 7 # align 8
key = reader_0(self, child_0)
result_dict[key] = reader_1(self, child_1)
return result_dict
if array_length == 0:
return []
result_list = []
beginning_pos = self._pos
if token_as_int == TOKEN_O_AS_INT or token_as_int == TOKEN_S_AS_INT:
while self._pos - beginning_pos < array_length:
result_list.append(self._read_string_unpack())
return result_list
reader = self._readers[child_type.token]
while self._pos - beginning_pos < array_length:
result_list.append(reader(self, child_type))
return result_list
def _header_fields(self, header_length: _int) -> list[Any]:
"""Header fields are always a(yv)."""
beginning_pos = self._pos
headers = _EMPTY_HEADERS.copy()
if cython.compiled:
if self._buf_len < self._pos + header_length:
raise IndexError("Not enough data to read header")
while self._pos - beginning_pos < header_length:
# Now read the y (byte) of struct (yv)
self._pos += (-self._pos & 7) + 1 # align 8 + 1 for 'y' byte
field_0 = self._buf_ustr[self._pos - 1]
# Now read the v (variant) of struct (yv)
# first we read the signature
signature_len = self._buf_ustr[self._pos] # byte
o = self._pos + 1
if cython.compiled:
if self._buf_len < o + signature_len:
raise IndexError("Not enough data to read signature")
self._pos += signature_len + 2 # one for the byte, one for the '\0'
if field_0 == HEADER_UNIX_FDS_IDX: # defined by self._unix_fds
continue
token_as_int = self._buf_ustr[o]
# Now that we have the token we can read the variant value
# Strings and signatures are the most common types
# so we inline them for performance
if token_as_int == TOKEN_O_AS_INT or token_as_int == TOKEN_S_AS_INT:
headers[field_0] = self._read_string_unpack()
elif token_as_int == TOKEN_G_AS_INT:
headers[field_0] = self._read_signature()
else:
token = self._buf_ustr[o : o + signature_len].decode()
# There shouldn't be any other types in the header
# but just in case, we'll read it using the slow path
headers[field_0] = self._readers[token](
self, get_signature_tree(token).root_type
)
return headers
def _read_header(self) -> None:
"""Read the header of the message."""
# Signature is of the header is
# BYTE, BYTE, BYTE, BYTE, UINT32, UINT32, ARRAY of STRUCT of (BYTE,VARIANT)
self._read_to_pos(HEADER_SIGNATURE_SIZE)
endian = self._buf_ustr[0]
self._message_type = self._buf_ustr[1]
self._flag = self._buf_ustr[2]
protocol_version = self._buf_ustr[3]
if protocol_version != PROTOCOL_VERSION:
raise InvalidMessageError(
f"got unknown protocol version: {protocol_version}"
)
if endian != LITTLE_ENDIAN and endian != BIG_ENDIAN:
raise InvalidMessageError(
f"Expecting endianness as the first byte, got {endian} from {self._buf}"
)
if cython.compiled:
self._body_len = _ustr_uint32(self._buf_ustr, 4, endian)
self._serial = _ustr_uint32(self._buf_ustr, 8, endian)
self._header_len = _ustr_uint32(self._buf_ustr, 12, endian)
elif endian == LITTLE_ENDIAN:
(
self._body_len,
self._serial,
self._header_len,
) = UNPACK_HEADER_LITTLE_ENDIAN(self._buf, 4)
self._uint32_unpack = UINT32_UNPACK_LITTLE_ENDIAN
self._int16_unpack = INT16_UNPACK_LITTLE_ENDIAN
self._uint16_unpack = UINT16_UNPACK_LITTLE_ENDIAN
else: # BIG_ENDIAN
self._body_len, self._serial, self._header_len = UNPACK_HEADER_BIG_ENDIAN(
self._buf, 4
)
self._uint32_unpack = UINT32_UNPACK_BIG_ENDIAN
self._int16_unpack = INT16_UNPACK_BIG_ENDIAN
self._uint16_unpack = UINT16_UNPACK_BIG_ENDIAN
# align 8
self._msg_len = self._header_len + (-self._header_len & 7) + self._body_len
if self._endian != endian:
self._readers = self._readers_by_type[endian]
self._endian = endian
def _read_body(self) -> None:
"""Read the body of the message."""
self._read_to_pos(HEADER_SIGNATURE_SIZE + self._msg_len)
self._pos = HEADER_ARRAY_OF_STRUCT_SIGNATURE_POSITION
header_fields = self._header_fields(self._header_len)
self._pos += -self._pos & 7 # align 8
signature: str = header_fields[HEADER_SIGNATURE_IDX]
if not self._body_len:
tree = SIGNATURE_TREE_EMPTY
body: list[Any] = []
else:
token_as_int = ord(signature[0])
if len(signature) == 1:
if token_as_int == TOKEN_O_AS_INT:
tree = SIGNATURE_TREE_O
body = [self._read_string_unpack()]
elif token_as_int == TOKEN_S_AS_INT:
tree = SIGNATURE_TREE_S
body = [self._read_string_unpack()]
else:
tree = get_signature_tree(signature)
body = [self._readers[t.token](self, t) for t in tree.types]
elif token_as_int == TOKEN_S_AS_INT and signature == "sa{sv}as":
tree = SIGNATURE_TREE_SA_SV_AS
body = [
self._read_string_unpack(),
self.read_array(SIGNATURE_TREE_SA_SV_AS_TYPES_1),
self.read_array(SIGNATURE_TREE_SA_SV_AS_TYPES_2),
]
elif token_as_int == TOKEN_O_AS_INT and signature == "oa{sa{sv}}":
tree = SIGNATURE_TREE_OA_SA_SV
body = [
self._read_string_unpack(),
self.read_array(SIGNATURE_TREE_OA_SA_SV_TYPES_1),
]
elif token_as_int == TOKEN_O_AS_INT and signature == "oas":
tree = SIGNATURE_TREE_OAS
body = [
self._read_string_unpack(),
self.read_array(SIGNATURE_TREE_OAS_TYPES_1),
]
elif token_as_int == TOKEN_A_AS_INT and signature == "a{oa{sa{sv}}}":
tree = SIGNATURE_TREE_A_OA_SA_SV
body = [self.read_array(SIGNATURE_TREE_A_OA_SA_SV_TYPES_0)]
else:
tree = get_signature_tree(signature)
body = [self._readers[t.token](self, t) for t in tree.types]
flags = MESSAGE_FLAG_MAP.get(self._flag)
if flags is None:
flags = MESSAGE_FLAG_INTENUM(self._flag)
message = Message.__new__(Message)
message._fast_init(
header_fields[HEADER_DESTINATION_IDX],
header_fields[HEADER_PATH_IDX],
header_fields[HEADER_INTERFACE_IDX],
header_fields[HEADER_MEMBER_IDX],
MESSAGE_TYPE_MAP[self._message_type],
flags,
header_fields[HEADER_ERROR_NAME_IDX],
header_fields[HEADER_REPLY_SERIAL_IDX] or 0,
header_fields[HEADER_SENDER_IDX],
self._unix_fds,
tree,
body,
self._serial,
# The D-Bus implementation already validates the message,
# so we don't need to do it again.
False,
)
self._message = message
self._read_complete = True
def unmarshall(self) -> Message | None:
"""Unmarshall the message.
The underlying read function will raise BlockingIOError if the
if there are not enough bytes in the buffer. This allows unmarshall
to be resumed when more data comes in over the wire.
"""
return self._unmarshall()
def _unmarshall(self) -> Message | None:
"""Unmarshall the message.
The underlying read function will raise BlockingIOError if the
if there are not enough bytes in the buffer. This allows unmarshall
to be resumed when more data comes in over the wire.
"""
if self._read_complete:
self._next_message()
try:
if not self._msg_len:
self._read_header()
self._read_body()
except MARSHALL_STREAM_END_ERROR:
return None
return self._message
_complex_parsers_unpack: dict[str, Callable[[Unmarshaller, SignatureType], Any]] = {
"b": read_boolean,
"o": read_string_unpack,
"s": read_string_unpack,
"g": read_signature,
"a": read_array,
"(": read_struct,
"{": read_dict_entry,
"v": read_variant,
"h": read_uint32_unpack,
UINT32_DBUS_TYPE: read_uint32_unpack,
INT16_DBUS_TYPE: read_int16_unpack,
UINT16_DBUS_TYPE: read_uint16_unpack,
}
_ctype_by_endian: dict[int, dict[str, READER_TYPE]] = {
endian: build_simple_parsers(endian) for endian in (LITTLE_ENDIAN, BIG_ENDIAN)
}
_readers_by_type: dict[int, dict[str, READER_TYPE]] = {
LITTLE_ENDIAN: {
**_ctype_by_endian[LITTLE_ENDIAN],
**_complex_parsers_unpack,
},
BIG_ENDIAN: {
**_ctype_by_endian[BIG_ENDIAN],
**_complex_parsers_unpack,
},
}
dbus-fast-2.44.1/src/dbus_fast/_private/util.py 0000664 0000000 0000000 00000013522 14773556132 0021413 0 ustar 00root root 0000000 0000000 from __future__ import annotations
import ast
import inspect
from typing import Any, Callable
from ..signature import SignatureTree, SignatureType, Variant, get_signature_tree
def signature_contains_type(
signature: str | SignatureTree, body: list[Any], token: str
) -> bool:
"""For a given signature and body, check to see if it contains any members
with the given token"""
if type(signature) is str:
signature = get_signature_tree(signature)
queue = list(signature.types) # type: ignore[union-attr]
contains_variants = False
while True:
if not queue:
break
st = queue.pop()
if st.token == token:
return True
if st.token == "v":
contains_variants = True
queue.extend(st.children)
if not contains_variants:
return False
for member in body:
queue.append(member)
while True:
if not queue:
return False
member = queue.pop()
if type(member) is Variant and signature_contains_type(
member.signature, [member.value], token
):
return True
if type(member) is list:
queue.extend(member)
elif type(member) is dict:
queue.extend(member.values())
def replace_fds_with_idx(
signature: str | SignatureTree, body: list[Any]
) -> tuple[list[Any], list[int]]:
"""Take the high level body format and convert it into the low level body
format. Type 'h' refers directly to the fd in the body. Replace that with
an index and return the corresponding list of unix fds that can be set on
the Message"""
if type(signature) is str:
signature = get_signature_tree(signature)
if not signature_contains_type(signature, body, "h"):
return body, []
unix_fds: list[Any] = []
def _replace(fd: Any) -> int:
try:
return unix_fds.index(fd)
except ValueError:
unix_fds.append(fd)
return len(unix_fds) - 1
_replace_fds(body, signature.types, _replace) # type: ignore[union-attr]
return body, unix_fds
def replace_idx_with_fds(
signature: str | SignatureTree, body: list[Any], unix_fds: list[Any]
) -> list[Any]:
"""Take the low level body format and return the high level body format.
Type 'h' refers to an index in the unix_fds array. Replace those with the
actual file descriptor or `None` if one does not exist."""
if type(signature) is str:
signature = get_signature_tree(signature)
if not signature_contains_type(signature, body, "h"):
return body
def _replace(idx: int) -> Any:
try:
return unix_fds[idx]
except IndexError:
return None
_replace_fds(body, signature.types, _replace) # type: ignore[union-attr]
return body
def parse_annotation(annotation: str) -> str:
"""
Because of PEP 563, if `from __future__ import annotations` is used in code
or on Python version >=3.10 where this is the default, return annotations
from the `inspect` module will return annotations as "forward definitions".
In this case, we must eval the result which we do only when given a string
constant.
"""
def raise_value_error() -> None:
raise ValueError(
f"service annotations must be a string constant (got {annotation})"
)
if not annotation or annotation is inspect.Signature.empty:
return ""
if type(annotation) is not str:
raise_value_error()
try:
body = ast.parse(annotation).body
if len(body) == 1 and type(body[0].value) is ast.Constant: # type: ignore[attr-defined]
if type(body[0].value.value) is not str: # type: ignore[attr-defined]
raise_value_error()
return body[0].value.value # type: ignore[attr-defined]
except SyntaxError:
pass
return annotation
def _replace_fds(
body_obj: dict[Any, Any] | list[Any],
children: list[SignatureType],
replace_fn: Callable[[Any], Any],
) -> None:
"""Replace any type 'h' with the value returned by replace_fn() given the
value of the fd field. This is used by the high level interfaces which
allow type 'h' to be the fd directly instead of an index in an external
array such as in the spec."""
for index, st in enumerate(children):
if not any(sig in st.signature for sig in "hv"):
continue
if st.signature == "h":
body_obj[index] = replace_fn(body_obj[index])
elif st.token == "a":
if st.children[0].token == "{":
_replace_fds(body_obj[index], st.children, replace_fn)
else:
for i, child in enumerate(body_obj[index]):
if st.signature == "ah":
body_obj[index][i] = replace_fn(child)
else:
_replace_fds([child], st.children, replace_fn)
elif st.token in "(":
_replace_fds(body_obj[index], st.children, replace_fn)
elif st.token in "{":
for key, value in list(body_obj.items()): # type: ignore[union-attr]
body_obj.pop(key)
if st.children[0].signature == "h":
key = replace_fn(key)
if st.children[1].signature == "h":
value = replace_fn(value)
else:
_replace_fds([value], [st.children[1]], replace_fn)
body_obj[key] = value
elif st.signature == "v":
if body_obj[index].signature == "h":
body_obj[index].value = replace_fn(body_obj[index].value)
else:
_replace_fds(
[body_obj[index].value], [body_obj[index].type], replace_fn
)
elif st.children:
_replace_fds(body_obj[index], st.children, replace_fn)
dbus-fast-2.44.1/src/dbus_fast/aio/ 0000775 0000000 0000000 00000000000 14773556132 0017020 5 ustar 00root root 0000000 0000000 dbus-fast-2.44.1/src/dbus_fast/aio/__init__.py 0000664 0000000 0000000 00000000306 14773556132 0021130 0 ustar 00root root 0000000 0000000 from __future__ import annotations
from .message_bus import MessageBus as MessageBus
from .proxy_object import ProxyInterface as ProxyInterface
from .proxy_object import ProxyObject as ProxyObject
dbus-fast-2.44.1/src/dbus_fast/aio/message_bus.py 0000664 0000000 0000000 00000051004 14773556132 0021667 0 ustar 00root root 0000000 0000000 from __future__ import annotations
import array
import asyncio
import contextlib
import logging
import socket
from collections import deque
from copy import copy
from functools import partial
from typing import Any, Callable
from .. import introspection as intr
from ..auth import Authenticator, AuthExternal
from ..constants import (
BusType,
MessageFlag,
MessageType,
NameFlag,
ReleaseNameReply,
RequestNameReply,
)
from ..errors import AuthError
from ..message import Message
from ..message_bus import BaseMessageBus, _block_unexpected_reply
from ..service import ServiceInterface, _Method
from .message_reader import build_message_reader
from .proxy_object import ProxyObject
NO_REPLY_EXPECTED_VALUE = MessageFlag.NO_REPLY_EXPECTED.value
_LOGGER = logging.getLogger(__name__)
def _generate_hello_serialized(next_serial: int) -> bytes:
return bytes(
Message(
destination="org.freedesktop.DBus",
path="/org/freedesktop/DBus",
interface="org.freedesktop.DBus",
member="Hello",
serial=next_serial,
)._marshall(False)
)
HELLO_1_SERIALIZED = _generate_hello_serialized(1)
def _future_set_exception(fut: asyncio.Future, exc: Exception) -> None:
if fut is not None and not fut.done():
fut.set_exception(exc)
def _future_set_result(fut: asyncio.Future, result: Any) -> None:
if fut is not None and not fut.done():
fut.set_result(result)
class _MessageWriter:
"""A class to handle writing messages to the message bus."""
def __init__(self, bus: MessageBus) -> None:
"""A class to handle writing messages to the message bus."""
self.messages: deque[
tuple[bytearray, list[int] | None, asyncio.Future | None]
] = deque()
self.negotiate_unix_fd = bus._negotiate_unix_fd
self.bus = bus
self.sock = bus._sock
self.loop = bus._loop
self.buf: memoryview | None = None
self.fd = bus._fd
self.offset = 0
self.unix_fds: list[int] | None = None
self.fut: asyncio.Future | None = None
def write_callback(self, remove_writer: bool = True) -> None:
"""The callback to write messages to the message bus."""
sock = self.sock
try:
while True:
if self.buf is None:
# If there is no buffer, get the next message
if not self.messages:
# nothing more to write
if remove_writer:
self.loop.remove_writer(self.fd)
return
# Get the next message
buf, unix_fds, fut = self.messages.popleft()
self.unix_fds = unix_fds
self.buf = memoryview(buf)
self.offset = 0
self.fut = fut
if self.unix_fds and self.negotiate_unix_fd:
ancdata = [
(
socket.SOL_SOCKET,
socket.SCM_RIGHTS,
array.array("i", self.unix_fds),
)
]
self.offset += sock.sendmsg([self.buf[self.offset :]], ancdata)
self.unix_fds = None
else:
self.offset += sock.send(self.buf[self.offset :])
if self.offset < len(self.buf):
# wait for writable
return
# finished writing
self.buf = None
_future_set_result(self.fut, None)
except Exception as e:
if self.bus._user_disconnect:
_future_set_result(self.fut, None)
else:
_future_set_exception(self.fut, e)
self.bus._finalize(e)
def buffer_message(
self, msg: Message, future: asyncio.Future | None = None
) -> None:
"""Buffer a message to be sent later."""
unix_fds = msg.unix_fds
self.messages.append(
(
msg._marshall(self.negotiate_unix_fd),
copy(unix_fds) if unix_fds else None,
future,
)
)
def _write_without_remove_writer(self) -> None:
"""Call the write callback without removing the writer."""
self.write_callback(remove_writer=False)
def schedule_write(
self, msg: Message | None = None, future: asyncio.Future | None = None
) -> None:
"""Schedule a message to be written."""
queue_is_empty = not self.messages
if msg is not None:
self.buffer_message(msg, future)
if self.bus.unique_name:
# Optimization: try to send now if the queue
# is empty. With bleak this usually means we
# can send right away 99% of the time which
# is a huge improvement in latency.
if queue_is_empty:
self._write_without_remove_writer()
if (
self.buf is not None
or self.messages
or not self.fut
or not self.fut.done()
):
self.loop.add_writer(self.fd, self.write_callback)
class MessageBus(BaseMessageBus):
"""The message bus implementation for use with asyncio.
The message bus class is the entry point into all the features of the
library. It sets up a connection to the DBus daemon and exposes an
interface to send and receive messages and expose services.
You must call :func:`connect() ` before
using this message bus.
:param bus_type: The type of bus to connect to. Affects the search path for
the bus address.
:type bus_type: :class:`BusType `
:param bus_address: A specific bus address to connect to. Should not be
used under normal circumstances.
:param auth: The authenticator to use, defaults to an instance of
:class:`AuthExternal `.
:type auth: :class:`Authenticator `
:param negotiate_unix_fd: Allow the bus to send and receive Unix file
descriptors (DBus type 'h'). This must be supported by the transport.
:type negotiate_unix_fd: bool
:ivar unique_name: The unique name of the message bus connection. It will
be :class:`None` until the message bus connects.
:vartype unique_name: str
:ivar connected: True if this message bus is expected to be able to send
and receive messages.
:vartype connected: bool
"""
__slots__ = ("_auth", "_disconnect_future", "_loop", "_pending_futures", "_writer")
def __init__(
self,
bus_address: str | None = None,
bus_type: BusType = BusType.SESSION,
auth: Authenticator | None = None,
negotiate_unix_fd: bool = False,
) -> None:
super().__init__(bus_address, bus_type, ProxyObject, negotiate_unix_fd)
self._loop = asyncio.get_running_loop()
self._writer = _MessageWriter(self)
if auth is None:
self._auth = AuthExternal()
else:
self._auth = auth
self._disconnect_future = self._loop.create_future()
self._pending_futures: set[asyncio.Future] = set()
async def connect(self) -> MessageBus:
"""Connect this message bus to the DBus daemon.
This method must be called before the message bus can be used.
:returns: This message bus for convenience.
:rtype: :class:`MessageBus `
:raises:
- :class:`AuthError ` - If authorization to \
the DBus daemon failed.
- :class:`Exception` - If there was a connection error.
"""
await self._authenticate()
future = self._loop.create_future()
self._loop.add_reader(
self._fd,
build_message_reader(
self._sock,
self._process_message,
self._finalize,
self._negotiate_unix_fd,
),
)
def on_hello(reply, err):
try:
if err:
raise err
self.unique_name = reply.body[0]
self._writer.schedule_write()
_future_set_result(future, self)
except Exception as e:
_future_set_exception(future, e)
self.disconnect()
self._finalize(err)
next_serial = self.next_serial()
self._method_return_handlers[next_serial] = on_hello
if next_serial == 1:
serialized = HELLO_1_SERIALIZED
else:
serialized = _generate_hello_serialized(next_serial)
self._stream.write(serialized)
self._stream.flush()
return await future
async def introspect(
self,
bus_name: str,
path: str,
timeout: float = 30.0,
validate_property_names: bool = True,
) -> intr.Node:
"""Get introspection data for the node at the given path from the given
bus name.
Calls the standard ``org.freedesktop.DBus.Introspectable.Introspect``
on the bus for the path.
:param bus_name: The name to introspect.
:type bus_name: str
:param path: The path to introspect.
:type path: str
:param timeout: The timeout to introspect.
:type timeout: float
:param validate_property_names: Whether to validate property names or not.
:type validate_property_names: bool
:returns: The introspection data for the name at the path.
:rtype: :class:`Node `
:raises:
- :class:`InvalidObjectPathError ` \
- If the given object path is not valid.
- :class:`InvalidBusNameError ` - If \
the given bus name is not valid.
- :class:`DBusError ` - If the service threw \
an error for the method call or returned an invalid result.
- :class:`Exception` - If a connection error occurred.
- :class:`asyncio.TimeoutError` - Waited for future but time run out.
"""
future = self._loop.create_future()
super().introspect(
bus_name,
path,
partial(self._reply_handler, future),
check_callback_type=False,
validate_property_names=validate_property_names,
)
timer_handle = self._loop.call_later(
timeout, _future_set_exception, future, asyncio.TimeoutError
)
try:
return await future
finally:
timer_handle.cancel()
async def request_name(
self, name: str, flags: NameFlag = NameFlag.NONE
) -> RequestNameReply:
"""Request that this message bus owns the given name.
:param name: The name to request.
:type name: str
:param flags: Name flags that affect the behavior of the name request.
:type flags: :class:`NameFlag `
:returns: The reply to the name request.
:rtype: :class:`RequestNameReply `
:raises:
- :class:`InvalidBusNameError ` - If \
the given bus name is not valid.
- :class:`DBusError ` - If the service threw \
an error for the method call or returned an invalid result.
- :class:`Exception` - If a connection error occurred.
"""
future = self._loop.create_future()
super().request_name(
name, flags, partial(self._reply_handler, future), check_callback_type=False
)
return await future
async def release_name(self, name: str) -> ReleaseNameReply:
"""Request that this message bus release the given name.
:param name: The name to release.
:type name: str
:returns: The reply to the release request.
:rtype: :class:`ReleaseNameReply `
:raises:
- :class:`InvalidBusNameError ` - If \
the given bus name is not valid.
- :class:`DBusError ` - If the service threw \
an error for the method call or returned an invalid result.
- :class:`Exception` - If a connection error occurred.
"""
future = self._loop.create_future()
super().release_name(
name, partial(self._reply_handler, future), check_callback_type=False
)
return await future
async def call(self, msg: Message) -> Message | None:
"""Send a method call and wait for a reply from the DBus daemon.
:param msg: The method call message to send.
:type msg: :class:`Message `
:returns: A message in reply to the message sent. If the message does
not expect a reply based on the message flags or type, returns
``None`` after the message is sent.
:rtype: :class:`Message ` or :class:`None` if no reply is expected.
:raises:
- :class:`Exception` - If a connection error occurred.
"""
if (
msg.flags.value & NO_REPLY_EXPECTED_VALUE
or msg.message_type is not MessageType.METHOD_CALL
):
await self.send(msg)
return None
future = self._loop.create_future()
self._call(msg, partial(self._reply_handler, future))
await future
return future.result()
def send(self, msg: Message) -> asyncio.Future:
"""Asynchronously send a message on the message bus.
.. note:: This method may change to a couroutine function in the 1.0
release of the library.
:param msg: The message to send.
:type msg: :class:`Message `
:returns: A future that resolves when the message is sent or a
connection error occurs.
:rtype: :class:`Future `
"""
if not msg.serial:
msg.serial = self.next_serial()
future = self._loop.create_future()
self._writer.schedule_write(msg, future)
return future
def get_proxy_object(
self, bus_name: str, path: str, introspection: intr.Node
) -> ProxyObject:
return super().get_proxy_object(bus_name, path, introspection)
async def wait_for_disconnect(self):
"""Wait for the message bus to disconnect.
:returns: :class:`None` when the message bus has disconnected.
:rtype: :class:`None`
:raises:
- :class:`Exception` - If connection was terminated unexpectedly or \
an internal error occurred in the library.
"""
return await self._disconnect_future
def _future_exception_no_reply(self, fut: asyncio.Future) -> None:
"""Log an exception from a future that was not expected."""
self._pending_futures.discard(fut)
try:
fut.result()
except asyncio.CancelledError:
pass
except Exception as e:
_LOGGER.exception("unexpected exception in future", exc_info=e)
def _make_method_handler(
self, interface: ServiceInterface, method: _Method
) -> Callable[[Message, Callable[[Message], None]], None]:
if not asyncio.iscoroutinefunction(method.fn):
return super()._make_method_handler(interface, method)
negotiate_unix_fd = self._negotiate_unix_fd
msg_body_to_args = ServiceInterface._msg_body_to_args
fn_result_to_body = ServiceInterface._fn_result_to_body
def _coroutine_method_handler(
msg: Message, send_reply: Callable[[Message], None]
) -> None:
"""A coroutine method handler."""
args = msg_body_to_args(msg) if msg.unix_fds else msg.body
fut: asyncio.Future = asyncio.ensure_future(method.fn(interface, *args))
# Hold a strong reference to the future to ensure
# it is not garbage collected before it is done.
self._pending_futures.add(fut)
if (
send_reply is _block_unexpected_reply
or msg.flags.value & NO_REPLY_EXPECTED_VALUE
):
fut.add_done_callback(self._future_exception_no_reply)
return
# We only create the closure function if we are actually going to reply
def _done(fut: asyncio.Future) -> None:
"""The callback for when the method is done."""
with send_reply:
result = fut.result()
body, unix_fds = fn_result_to_body(
result, method.out_signature_tree, replace_fds=negotiate_unix_fd
)
send_reply(
Message.new_method_return(
msg, method.out_signature, body, unix_fds
)
)
fut.add_done_callback(_done)
# Discard the future only after running the done callback
fut.add_done_callback(self._pending_futures.discard)
return _coroutine_method_handler
async def _auth_readline(self) -> str:
buf = b""
while buf[-2:] != b"\r\n":
# The auth protocol is line based, so we can read until we get a
# newline.
buf += await self._loop.sock_recv(self._sock, 1024)
return buf[:-2].decode()
async def _authenticate(self) -> None:
await self._loop.sock_sendall(self._sock, b"\0")
first_line = self._auth._authentication_start(
negotiate_unix_fd=self._negotiate_unix_fd
)
if first_line is not None:
if type(first_line) is not str:
raise AuthError("authenticator gave response not type str")
await self._loop.sock_sendall(
self._sock, Authenticator._format_line(first_line)
)
while True:
response = self._auth._receive_line(await self._auth_readline())
if response is not None:
await self._loop.sock_sendall(
self._sock, Authenticator._format_line(response)
)
self._stream.flush()
if response == "BEGIN":
# The first octet received by the server after the \r\n of the BEGIN command
# from the client must be the first octet of the authenticated/encrypted stream
# of D-Bus messages.
break
def disconnect(self) -> None:
"""Disconnect the message bus by closing the underlying connection asynchronously.
All pending and future calls will error with a connection error.
"""
super().disconnect()
try:
self._sock.close()
except Exception:
_LOGGER.warning("could not close socket", exc_info=True)
def _finalize(self, err: Exception | None = None) -> None:
try:
self._loop.remove_reader(self._fd)
except Exception:
_LOGGER.warning("could not remove message reader", exc_info=True)
try:
self._loop.remove_writer(self._fd)
except Exception:
_LOGGER.warning("could not remove message writer", exc_info=True)
had_handlers = bool(self._method_return_handlers or self._user_message_handlers)
super()._finalize(err)
if self._disconnect_future.done():
return
if err and not self._user_disconnect:
_future_set_exception(self._disconnect_future, err)
# If this happens during a reply, the message handlers
# will have the exception set and wait_for_disconnect will
# never be called so we need to manually set the exception
# as retrieved to avoid asyncio warnings when the future
# is garbage collected.
if had_handlers:
with contextlib.suppress(Exception):
self._disconnect_future.exception()
else:
_future_set_result(self._disconnect_future, None)
def _reply_handler(
self, future: asyncio.Future, reply: Any | None, err: Exception | None
) -> None:
"""The reply handler for method calls."""
if err:
_future_set_exception(future, err)
else:
_future_set_result(future, reply)
dbus-fast-2.44.1/src/dbus_fast/aio/message_reader.pxd 0000664 0000000 0000000 00000000342 14773556132 0022502 0 ustar 00root root 0000000 0000000 """cdefs for message_reader.py"""
import cython
from .._private.unmarshaller cimport Unmarshaller
cpdef _message_reader(
Unmarshaller unmarshaller,
object process,
object finalize,
bint negotiate_unix_fd
)
dbus-fast-2.44.1/src/dbus_fast/aio/message_reader.py 0000664 0000000 0000000 00000003205 14773556132 0022340 0 ustar 00root root 0000000 0000000 from __future__ import annotations
import logging
import socket
from functools import partial
from typing import Callable
from .._private.unmarshaller import Unmarshaller
from ..message import Message
_LOGGER = logging.getLogger(__name__)
def _message_reader(
unmarshaller: Unmarshaller,
process: Callable[[Message], None],
finalize: Callable[[Exception | None], None],
negotiate_unix_fd: bool,
) -> None:
"""Reads messages from the unmarshaller and passes them to the process function."""
try:
while True:
message = unmarshaller._unmarshall()
if message is None:
return
try:
process(message)
except Exception:
_LOGGER.error("Unexpected error processing message: %s", exc_info=True)
# If we are not negotiating unix fds, we can stop reading as soon as we have
# the buffer is empty as asyncio will call us again when there is more data.
if (
not negotiate_unix_fd
and not unmarshaller._has_another_message_in_buffer()
):
return
except Exception as e:
finalize(e)
def build_message_reader(
sock: socket.socket | None,
process: Callable[[Message], None],
finalize: Callable[[Exception | None], None],
negotiate_unix_fd: bool,
) -> Callable[[], None]:
"""Build a callable that reads messages from the unmarshaller and passes them to the process function."""
unmarshaller = Unmarshaller(None, sock, negotiate_unix_fd)
return partial(_message_reader, unmarshaller, process, finalize, negotiate_unix_fd)
dbus-fast-2.44.1/src/dbus_fast/aio/proxy_object.py 0000664 0000000 0000000 00000015623 14773556132 0022110 0 ustar 00root root 0000000 0000000 from __future__ import annotations
import xml.etree.ElementTree as ET
from typing import TYPE_CHECKING, Any
from .. import introspection as intr
from .._private.util import replace_fds_with_idx, replace_idx_with_fds
from ..constants import ErrorType, MessageFlag
from ..errors import DBusError
from ..message import Message
from ..message_bus import BaseMessageBus
from ..proxy_object import BaseProxyInterface, BaseProxyObject
from ..signature import Variant
from ..unpack import unpack_variants as unpack
if TYPE_CHECKING:
from .message_bus import MessageBus as AioMessageBus
NO_REPLY_EXPECTED_VALUE = MessageFlag.NO_REPLY_EXPECTED.value
class ProxyInterface(BaseProxyInterface):
"""A class representing a proxy to an interface exported on the bus by
another client for the asyncio :class:`MessageBus
` implementation.
This class is not meant to be constructed directly by the user. Use
:func:`ProxyObject.get_interface()
` on a asyncio proxy object to get
a proxy interface.
This class exposes methods to call DBus methods, listen to signals, and get
and set properties on the interface that are created dynamically based on
the introspection data passed to the proxy object that made this proxy
interface.
A *method call* takes this form:
.. code-block:: python3
result = await interface.call_[METHOD](*args)
Where ``METHOD`` is the name of the method converted to snake case.
DBus methods are exposed as coroutines that take arguments that correpond
to the *in args* of the interface method definition and return a ``result``
that corresponds to the *out arg*. If the method has more than one out arg,
they are returned within a :class:`list`.
To *listen to a signal* use this form:
.. code-block:: python3
interface.on_[SIGNAL](callback)
To *stop listening to a signal* use this form:
.. code-block:: python3
interface.off_[SIGNAL](callback)
Where ``SIGNAL`` is the name of the signal converted to snake case.
DBus signals are exposed with an event-callback interface. The provided
``callback`` will be called when the signal is emitted with arguments that
correspond to the *out args* of the interface signal definition.
To *get or set a property* use this form:
.. code-block:: python3
value = await interface.get_[PROPERTY]()
await interface.set_[PROPERTY](value)
Where ``PROPERTY`` is the name of the property converted to snake case.
DBus property getters and setters are exposed as coroutines. The ``value``
must correspond to the type of the property in the interface definition.
If the service returns an error for a DBus call, a :class:`DBusError
` will be raised with information about the error.
"""
bus: AioMessageBus
def _add_method(self, intr_method: intr.Method) -> None:
async def method_fn(
*args, flags=MessageFlag.NONE, unpack_variants: bool = False
):
input_body, unix_fds = replace_fds_with_idx(
intr_method.in_signature, list(args)
)
msg = await self.bus.call(
Message(
destination=self.bus_name,
path=self.path,
interface=self.introspection.name,
member=intr_method.name,
signature=intr_method.in_signature,
body=input_body,
flags=flags,
unix_fds=unix_fds,
)
)
if flags is not None and flags.value & NO_REPLY_EXPECTED_VALUE:
return None
BaseProxyInterface._check_method_return(msg, intr_method.out_signature)
out_len = len(intr_method.out_args)
body = replace_idx_with_fds(msg.signature_tree, msg.body, msg.unix_fds)
if not out_len:
return None
if unpack_variants:
body = unpack(body)
if out_len == 1:
return body[0]
return body
method_name = f"call_{BaseProxyInterface._to_snake_case(intr_method.name)}"
setattr(self, method_name, method_fn)
def _add_property(
self,
intr_property: intr.Property,
) -> None:
async def property_getter(
*, flags=MessageFlag.NONE, unpack_variants: bool = False
):
msg = await self.bus.call(
Message(
destination=self.bus_name,
path=self.path,
interface="org.freedesktop.DBus.Properties",
member="Get",
signature="ss",
body=[self.introspection.name, intr_property.name],
)
)
BaseProxyInterface._check_method_return(msg, "v")
variant = msg.body[0]
if variant.signature != intr_property.signature:
raise DBusError(
ErrorType.CLIENT_ERROR,
f'property returned unexpected signature "{variant.signature}"',
msg,
)
body = replace_idx_with_fds("v", msg.body, msg.unix_fds)[0].value
if unpack_variants:
return unpack(body)
return body
async def property_setter(val: Any) -> None:
variant = Variant(intr_property.signature, val)
body, unix_fds = replace_fds_with_idx(
"ssv", [self.introspection.name, intr_property.name, variant]
)
msg = await self.bus.call(
Message(
destination=self.bus_name,
path=self.path,
interface="org.freedesktop.DBus.Properties",
member="Set",
signature="ssv",
body=body,
unix_fds=unix_fds,
)
)
BaseProxyInterface._check_method_return(msg)
snake_case = BaseProxyInterface._to_snake_case(intr_property.name)
setattr(self, f"get_{snake_case}", property_getter)
setattr(self, f"set_{snake_case}", property_setter)
class ProxyObject(BaseProxyObject):
"""The proxy object implementation for the GLib :class:`MessageBus `.
For more information, see the :class:`BaseProxyObject `.
"""
def __init__(
self,
bus_name: str,
path: str,
introspection: intr.Node | str | ET.Element,
bus: BaseMessageBus,
) -> None:
super().__init__(bus_name, path, introspection, bus, ProxyInterface)
def get_interface(self, name: str) -> ProxyInterface:
return super().get_interface(name)
def get_children(self) -> list[ProxyObject]:
return super().get_children()
dbus-fast-2.44.1/src/dbus_fast/auth.py 0000664 0000000 0000000 00000010425 14773556132 0017565 0 ustar 00root root 0000000 0000000 import enum
import os
from typing import Optional
from .errors import AuthError
UID_NOT_SPECIFIED = -1
# The auth interface here is unstable. I would like to eventually open this up
# for people to define their own custom authentication protocols, but I'm not
# familiar with what's needed for that exactly. To work with any message bus
# implementation would require abstracting out all the IO. Async operations
# might be challenging because different IO backends have different ways of
# doing that. I might just end up giving the raw socket and leaving it all up
# to the user, but it would be nice to have a little guidance in the interface
# since a lot of it is strongly specified. If you have a need for this, contact
# the project maintainer to help stabilize this interface.
class _AuthResponse(enum.Enum):
OK = "OK"
REJECTED = "REJECTED"
DATA = "DATA"
ERROR = "ERROR"
AGREE_UNIX_FD = "AGREE_UNIX_FD"
@classmethod
def parse(klass, line: str) -> tuple["_AuthResponse", list[str]]:
args = line.split(" ")
response = klass(args[0])
return response, args[1:]
# UNSTABLE
class Authenticator:
"""The base class for authenticators for :class:`MessageBus ` authentication.
In the future, the library may allow extending this class for custom authentication protocols.
:seealso: https://dbus.freedesktop.org/doc/dbus-specification.html#auth-protocol
"""
def _authentication_start(self, negotiate_unix_fd: bool = False) -> str:
raise NotImplementedError(
"authentication_start() must be implemented in the inheriting class"
)
def _receive_line(self, line: str) -> str:
raise NotImplementedError(
"receive_line() must be implemented in the inheriting class"
)
@staticmethod
def _format_line(line: str) -> bytes:
return f"{line}\r\n".encode()
class AuthExternal(Authenticator):
"""An authenticator class for the external auth protocol for use with the
:class:`MessageBus `.
:param uid: The uid to use when connecting to the message bus. Use UID_NOT_SPECIFIED to use the uid known to the kernel.
:vartype uid: int
:sealso: https://dbus.freedesktop.org/doc/dbus-specification.html#auth-protocol
"""
def __init__(self, uid: Optional[int] = None) -> None:
self.negotiate_unix_fd: bool = False
self.negotiating_fds: bool = False
self.uid: Optional[int] = uid
def _authentication_start(self, negotiate_unix_fd: bool = False) -> str:
self.negotiate_unix_fd = negotiate_unix_fd
uid = self.uid
if uid == UID_NOT_SPECIFIED:
return "AUTH EXTERNAL"
if uid is None:
uid = os.getuid()
hex_uid = str(uid).encode().hex()
return f"AUTH EXTERNAL {hex_uid}"
def _receive_line(self, line: str) -> str:
response, args = _AuthResponse.parse(line)
if response is _AuthResponse.OK:
if self.negotiate_unix_fd:
self.negotiating_fds = True
return "NEGOTIATE_UNIX_FD"
return "BEGIN"
if response is _AuthResponse.AGREE_UNIX_FD:
return "BEGIN"
if response is _AuthResponse.DATA and self.uid == UID_NOT_SPECIFIED:
return "DATA"
raise AuthError(f"authentication failed: {response.value}: {args}")
class AuthAnonymous(Authenticator):
"""An authenticator class for the anonymous auth protocol for use with the
:class:`MessageBus `.
:sealso: https://dbus.freedesktop.org/doc/dbus-specification.html#auth-protocol
"""
def _authentication_start(self, negotiate_unix_fd: bool = False) -> str:
if negotiate_unix_fd:
raise AuthError(
"anonymous authentication does not support negotiating unix fds right now"
)
return "AUTH ANONYMOUS"
def _receive_line(self, line: str) -> str:
response, args = _AuthResponse.parse(line)
if response != _AuthResponse.OK:
raise AuthError(f"authentication failed: {response.value}: {args}")
return "BEGIN"
# The following line provides backwards compatibility, remove at some point? --jrd
AuthAnnonymous = AuthAnonymous
dbus-fast-2.44.1/src/dbus_fast/constants.py 0000664 0000000 0000000 00000013662 14773556132 0020646 0 ustar 00root root 0000000 0000000 from enum import Enum, IntFlag
from functools import cached_property
class BusType(Enum):
"""An enum that indicates a type of bus. On most systems, there are
normally two different kinds of buses running.
"""
SESSION = 1 #: A bus for the current graphical user session.
SYSTEM = 2 #: A persistent bus for the whole machine.
class MessageType(Enum):
"""An enum that indicates a type of message."""
METHOD_CALL = 1 #: An outgoing method call.
METHOD_RETURN = 2 #: A return to a previously sent method call
ERROR = 3 #: A return to a method call that has failed
SIGNAL = 4 #: A broadcast signal to subscribed connections
@cached_property
def value(self) -> int:
"""Return the value."""
return self._value_
MESSAGE_TYPE_MAP = {field.value: field for field in MessageType}
class MessageFlag(IntFlag):
"""Flags that affect the behavior of sent and received messages"""
NONE = 0
NO_REPLY_EXPECTED = 1 #: The method call does not expect a method return.
NO_AUTOSTART = 2
ALLOW_INTERACTIVE_AUTHORIZATION = 4
@cached_property
def value(self) -> int:
"""Return the value."""
return self._value_
# This is written out because of https://github.com/python/cpython/issues/98976
MESSAGE_FLAG_MAP = {
0: MessageFlag.NONE,
1: MessageFlag.NO_REPLY_EXPECTED,
2: MessageFlag.NO_AUTOSTART,
4: MessageFlag.ALLOW_INTERACTIVE_AUTHORIZATION,
}
class NameFlag(IntFlag):
"""A flag that affects the behavior of a name request."""
NONE = 0
ALLOW_REPLACEMENT = 1 #: If another client requests this name, let them have it.
REPLACE_EXISTING = 2 #: If another client owns this name, try to take it.
DO_NOT_QUEUE = 4 #: Name requests normally queue and wait for the owner to release the name. Do not enter this queue.
class RequestNameReply(Enum):
"""An enum that describes the result of a name request."""
PRIMARY_OWNER = 1 #: The bus owns the name.
IN_QUEUE = 2 #: The bus is in a queue and may receive the name after it is relased by the primary owner.
EXISTS = 3 #: The name has an owner and NameFlag.DO_NOT_QUEUE was given.
ALREADY_OWNER = 4 #: The bus already owns the name.
class ReleaseNameReply(Enum):
"""An enum that describes the result of a name release request"""
RELEASED = 1
NON_EXISTENT = 2
NOT_OWNER = 3
class PropertyAccess(Enum):
"""An enum that describes whether a DBus property can be gotten or set with
the ``org.freedesktop.DBus.Properties`` interface.
"""
READ = "read" #: The property is readonly.
WRITE = "write" #: The property is writeonly.
READWRITE = "readwrite" #: The property can be read or written to.
def readable(self) -> bool:
"""Get whether the property can be read."""
return self == PropertyAccess.READ or self == PropertyAccess.READWRITE
def writable(self) -> bool:
"""Get whether the property can be written to."""
return self == PropertyAccess.WRITE or self == PropertyAccess.READWRITE
class ArgDirection(Enum):
"""For an introspected argument, indicates whether it is an input parameter or a return value."""
IN = "in"
OUT = "out"
class ErrorType(str, Enum):
"""An enum for the type of an error for a message reply.
:seealso: http://man7.org/linux/man-pages/man3/sd-bus-errors.3.html
"""
SERVICE_ERROR = "com.dubstepdish.dbus.next.ServiceError" #: A custom error to indicate an exported service threw an exception.
INTERNAL_ERROR = "com.dubstepdish.dbus.next.InternalError" #: A custom error to indicate something went wrong with the library.
CLIENT_ERROR = "com.dubstepdish.dbus.next.ClientError" #: A custom error to indicate something went wrong with the client.
FAILED = "org.freedesktop.DBus.Error.Failed"
NO_MEMORY = "org.freedesktop.DBus.Error.NoMemory"
SERVICE_UNKNOWN = "org.freedesktop.DBus.Error.ServiceUnknown"
NAME_HAS_NO_OWNER = "org.freedesktop.DBus.Error.NameHasNoOwner"
NO_REPLY = "org.freedesktop.DBus.Error.NoReply"
IO_ERROR = "org.freedesktop.DBus.Error.IOError"
BAD_ADDRESS = "org.freedesktop.DBus.Error.BadAddress"
NOT_SUPPORTED = "org.freedesktop.DBus.Error.NotSupported"
LIMITS_EXCEEDED = "org.freedesktop.DBus.Error.LimitsExceeded"
ACCESS_DENIED = "org.freedesktop.DBus.Error.AccessDenied"
AUTH_FAILED = "org.freedesktop.DBus.Error.AuthFailed"
NO_SERVER = "org.freedesktop.DBus.Error.NoServer"
TIMEOUT = "org.freedesktop.DBus.Error.Timeout"
NO_NETWORK = "org.freedesktop.DBus.Error.NoNetwork"
ADDRESS_IN_USE = "org.freedesktop.DBus.Error.AddressInUse"
DISCONNECTED = "org.freedesktop.DBus.Error.Disconnected"
INVALID_ARGS = "org.freedesktop.DBus.Error.InvalidArgs"
FILE_NOT_FOUND = "org.freedesktop.DBus.Error.FileNotFound"
FILE_EXISTS = "org.freedesktop.DBus.Error.FileExists"
UNKNOWN_METHOD = "org.freedesktop.DBus.Error.UnknownMethod"
UNKNOWN_OBJECT = "org.freedesktop.DBus.Error.UnknownObject"
UNKNOWN_INTERFACE = "org.freedesktop.DBus.Error.UnknownInterface"
UNKNOWN_PROPERTY = "org.freedesktop.DBus.Error.UnknownProperty"
PROPERTY_READ_ONLY = "org.freedesktop.DBus.Error.PropertyReadOnly"
UNIX_PROCESS_ID_UNKNOWN = "org.freedesktop.DBus.Error.UnixProcessIdUnknown"
INVALID_SIGNATURE = "org.freedesktop.DBus.Error.InvalidSignature"
INCONSISTENT_MESSAGE = "org.freedesktop.DBus.Error.InconsistentMessage"
TIMED_OUT = "org.freedesktop.DBus.Error.TimedOut"
MATCH_RULE_NOT_FOUND = "org.freedesktop.DBus.Error.MatchRuleNotFound"
MATCH_RULE_INVALID = "org.freedesktop.DBus.Error.MatchRuleInvalid"
INTERACTIVE_AUTHORIZATION_REQUIRED = (
"org.freedesktop.DBus.Error.InteractiveAuthorizationRequired"
)
INVALID_FILE_CONTENT = "org.freedesktop.DBus.Error.InvalidFileContent"
SELINUX_SECURITY_CONTEXT_UNKNOWN = (
"org.freedesktop.DBus.Error.SELinuxSecurityContextUnknown"
)
OBJECT_PATH_IN_USE = "org.freedesktop.DBus.Error.ObjectPathInUse"
dbus-fast-2.44.1/src/dbus_fast/errors.py 0000664 0000000 0000000 00000003750 14773556132 0020143 0 ustar 00root root 0000000 0000000 from typing import Optional, Union
class SignatureBodyMismatchError(ValueError):
pass
class InvalidSignatureError(ValueError):
pass
class InvalidAddressError(ValueError):
pass
class AuthError(Exception):
pass
class InvalidMessageError(ValueError):
pass
class InvalidIntrospectionError(ValueError):
pass
class InterfaceNotFoundError(Exception):
pass
class SignalDisabledError(Exception):
pass
class InvalidBusNameError(TypeError):
def __init__(self, name: str) -> None:
super().__init__(f"invalid bus name: {name}")
class InvalidObjectPathError(TypeError):
def __init__(self, path: str) -> None:
super().__init__(f"invalid object path: {path}")
class InvalidInterfaceNameError(TypeError):
def __init__(self, name: str) -> None:
super().__init__(f"invalid interface name: {name}")
class InvalidMemberNameError(TypeError):
def __init__(self, member: str) -> None:
super().__init__(f"invalid member name: {member}")
from .constants import ErrorType, MessageType # noqa: E402
from .message import Message # noqa: E402
from .validators import assert_interface_name_valid # noqa: E402
class DBusError(Exception):
def __init__(
self, type_: Union[ErrorType, str], text: str, reply: Optional[Message] = None
) -> None:
super().__init__(text)
if type(type_) is ErrorType:
type_ = type_.value
assert_interface_name_valid(type_) # type: ignore[arg-type]
if reply is not None and type(reply) is not Message:
raise TypeError("reply must be of type Message")
self.type = type_
self.text = text
self.reply = reply
@staticmethod
def _from_message(msg: Message) -> "DBusError":
assert msg.message_type == MessageType.ERROR
return DBusError(msg.error_name or "unknown", msg.body[0], reply=msg)
def _as_message(self, msg: Message) -> Message:
return Message.new_error(msg, self.type, self.text)
dbus-fast-2.44.1/src/dbus_fast/glib/ 0000775 0000000 0000000 00000000000 14773556132 0017165 5 ustar 00root root 0000000 0000000 dbus-fast-2.44.1/src/dbus_fast/glib/__init__.py 0000664 0000000 0000000 00000000242 14773556132 0021274 0 ustar 00root root 0000000 0000000 from .message_bus import MessageBus as MessageBus
from .proxy_object import ProxyInterface as ProxyInterface
from .proxy_object import ProxyObject as ProxyObject
dbus-fast-2.44.1/src/dbus_fast/glib/message_bus.py 0000664 0000000 0000000 00000040125 14773556132 0022036 0 ustar 00root root 0000000 0000000 import io
import logging
import traceback
from typing import Callable, Optional
from .. import introspection as intr
from .._private.unmarshaller import Unmarshaller
from ..auth import Authenticator, AuthExternal
from ..constants import (
BusType,
MessageFlag,
MessageType,
NameFlag,
ReleaseNameReply,
RequestNameReply,
)
from ..errors import AuthError
from ..message import Message
from ..message_bus import BaseMessageBus
from .proxy_object import ProxyObject
_LOGGER = logging.getLogger(__name__)
# glib is optional
_import_error = None
try:
from gi.repository import GLib
_GLibSource = GLib.Source
except ImportError as e:
_import_error = e
class _GLibSource:
pass
class _MessageSource(_GLibSource):
def __init__(self, bus):
self.unmarshaller = None
self.bus = bus
def prepare(self):
return (False, -1)
def check(self):
return False
def dispatch(self, callback, user_data):
try:
while self.bus._stream.readable():
if not self.unmarshaller:
self.unmarshaller = Unmarshaller(self.bus._stream)
message = self.unmarshaller.unmarshall()
if message:
callback(message)
self.unmarshaller = None
else:
break
except Exception as e:
self.bus.disconnect()
self.bus._finalize(e)
return GLib.SOURCE_REMOVE
return GLib.SOURCE_CONTINUE
class _MessageWritableSource(_GLibSource):
def __init__(self, bus):
self.bus = bus
self.buf = b""
self.message_stream = None
self.chunk_size = 128
def prepare(self):
return (False, -1)
def check(self):
return False
def dispatch(self, callback, user_data):
try:
if self.buf:
self.bus._stream.write(self.buf)
self.buf = b""
if self.message_stream:
while True:
self.buf = self.message_stream.read(self.chunk_size)
if self.buf == b"":
break
self.bus._stream.write(self.buf)
if len(self.buf) < self.chunk_size:
self.buf = b""
break
self.buf = b""
self.bus._stream.flush()
if not self.bus._buffered_messages:
return GLib.SOURCE_REMOVE
message = self.bus._buffered_messages.pop(0)
self.message_stream = io.BytesIO(message._marshall(False))
return GLib.SOURCE_CONTINUE
except BlockingIOError:
return GLib.SOURCE_CONTINUE
except Exception as e:
self.bus._finalize(e)
return GLib.SOURCE_REMOVE
class _AuthLineSource(_GLibSource):
def __init__(self, stream):
self.stream = stream
self.buf = b""
def prepare(self):
return (False, -1)
def check(self):
return False
def dispatch(self, callback, user_data):
self.buf += self.stream.read()
if self.buf[-2:] == b"\r\n":
resp = callback(self.buf.decode()[:-2])
if resp:
return GLib.SOURCE_REMOVE
return GLib.SOURCE_CONTINUE
class MessageBus(BaseMessageBus):
"""The message bus implementation for use with the GLib main loop.
The message bus class is the entry point into all the features of the
library. It sets up a connection to the DBus daemon and exposes an
interface to send and receive messages and expose services.
You must call :func:`connect() ` or
:func:`connect_sync() ` before
using this message bus.
:param bus_type: The type of bus to connect to. Affects the search path for
the bus address.
:type bus_type: :class:`BusType `
:param bus_address: A specific bus address to connect to. Should not be
used under normal circumstances.
:param auth: The authenticator to use, defaults to an instance of
:class:`AuthExternal `.
:type auth: :class:`Authenticator `
:ivar connected: True if this message bus is expected to be able to send
and receive messages.
:vartype connected: bool
:ivar unique_name: The unique name of the message bus connection. It will
be :class:`None` until the message bus connects.
:vartype unique_name: str
"""
def __init__(
self,
bus_address: Optional[str] = None,
bus_type: BusType = BusType.SESSION,
auth: Optional[Authenticator] = None,
):
if _import_error:
raise _import_error
super().__init__(bus_address, bus_type, ProxyObject)
self._main_context = GLib.main_context_default()
# buffer messages until connect
self._buffered_messages = []
if auth is None:
self._auth = AuthExternal()
else:
self._auth = auth
def _on_message(self, msg: Message) -> None:
try:
self._process_message(msg)
except Exception as e:
_LOGGER.exception(
f"got unexpected error processing a message: {e}.\n{traceback.format_exc()}"
)
def connect(
self,
connect_notify: Optional[
Callable[["MessageBus", Optional[Exception]], None]
] = None,
):
"""Connect this message bus to the DBus daemon.
This method or the synchronous version must be called before the
message bus can be used.
:param connect_notify: A callback that will be called with this message
bus. May return an :class:`Exception` on connection errors or
:class:`AuthError ` on authorization errors.
:type callback: :class:`Callable`
"""
def authenticate_notify(exc):
if exc is not None:
if connect_notify is not None:
connect_notify(None, exc)
return
self.message_source = _MessageSource(self)
self.message_source.set_callback(self._on_message)
self.message_source.attach(self._main_context)
self.writable_source = None
self.message_source.add_unix_fd(self._fd, GLib.IO_IN)
def on_hello(reply, err):
if err:
if connect_notify:
connect_notify(reply, err)
return
self.unique_name = reply.body[0]
for m in self._buffered_messages:
self.send(m)
if connect_notify:
connect_notify(self, err)
hello_msg = Message(
destination="org.freedesktop.DBus",
path="/org/freedesktop/DBus",
interface="org.freedesktop.DBus",
member="Hello",
serial=self.next_serial(),
)
self._method_return_handlers[hello_msg.serial] = on_hello
self._stream.write(hello_msg._marshall(False))
self._stream.flush()
self._authenticate(authenticate_notify)
def connect_sync(self) -> "MessageBus":
"""Connect this message bus to the DBus daemon.
This method or the asynchronous version must be called before the
message bus can be used.
:returns: This message bus for convenience.
:rtype: :class:`MessageBus `
:raises:
- :class:`AuthError ` - If authorization to \
the DBus daemon failed.
- :class:`Exception` - If there was a connection error.
"""
main = GLib.MainLoop()
connection_error = None
def connect_notify(bus, err):
nonlocal connection_error
connection_error = err
main.quit()
self.connect(connect_notify)
main.run()
if connection_error:
raise connection_error
return self
def call(
self,
msg: Message,
reply_notify: Optional[
Callable[[Optional[Message], Optional[Exception]], None]
] = None,
):
"""Send a method call and asynchronously wait for a reply from the DBus
daemon.
:param msg: The method call message to send.
:type msg: :class:`Message `
:param reply_notify: A callback that will be called with the reply to
this message. May return an :class:`Exception` on connection errors.
:type reply_notify: Callable
"""
BaseMessageBus._check_callback_type(reply_notify)
self._call(msg, reply_notify)
def call_sync(self, msg: Message) -> Optional[Message]:
"""Send a method call and synchronously wait for a reply from the DBus
daemon.
:param msg: The method call message to send.
:type msg: :class:`Message `
:returns: A message in reply to the message sent. If the message does
not expect a reply based on the message flags or type, returns
``None`` immediately.
:rtype: :class:`Message `
:raises:
- :class:`DBusError ` - If the service threw \
an error for the method call or returned an invalid result.
- :class:`Exception` - If a connection error occurred.
"""
if (
msg.flags & MessageFlag.NO_REPLY_EXPECTED
or msg.message_type is not MessageType.METHOD_CALL
):
self.send(msg)
return None
if not msg.serial:
msg.serial = self.next_serial()
main = GLib.MainLoop()
handler_reply = None
connection_error = None
def reply_handler(reply, err):
nonlocal handler_reply
nonlocal connection_error
handler_reply = reply
connection_error = err
main.quit()
self._method_return_handlers[msg.serial] = reply_handler
self.send(msg)
main.run()
if connection_error:
raise connection_error
return handler_reply
def introspect_sync(self, bus_name: str, path: str) -> intr.Node:
"""Get introspection data for the node at the given path from the given
bus name.
Calls the standard ``org.freedesktop.DBus.Introspectable.Introspect``
on the bus for the path.
:param bus_name: The name to introspect.
:type bus_name: str
:param path: The path to introspect.
:type path: str
:returns: The introspection data for the name at the path.
:rtype: :class:`Node `
:raises:
- :class:`InvalidObjectPathError ` \
- If the given object path is not valid.
- :class:`InvalidBusNameError ` - If \
the given bus name is not valid.
- :class:`DBusError ` - If the service threw \
an error for the method call or returned an invalid result.
- :class:`Exception` - If a connection error occurred.
"""
main = GLib.MainLoop()
request_result = None
request_error = None
def reply_notify(result, err):
nonlocal request_result
nonlocal request_error
request_result = result
request_error = err
main.quit()
super().introspect(bus_name, path, reply_notify)
main.run()
if request_error:
raise request_error
return request_result
def request_name_sync(
self, name: str, flags: NameFlag = NameFlag.NONE
) -> RequestNameReply:
"""Request that this message bus owns the given name.
:param name: The name to request.
:type name: str
:param flags: Name flags that affect the behavior of the name request.
:type flags: :class:`NameFlag `
:returns: The reply to the name request.
:rtype: :class:`RequestNameReply `
:raises:
- :class:`InvalidBusNameError ` - If \
the given bus name is not valid.
- :class:`DBusError ` - If the service threw \
an error for the method call or returned an invalid result.
- :class:`Exception` - If a connection error occurred.
"""
main = GLib.MainLoop()
request_result = None
request_error = None
def reply_notify(result, err):
nonlocal request_result
nonlocal request_error
request_result = result
request_error = err
main.quit()
super().request_name(name, flags, reply_notify)
main.run()
if request_error:
raise request_error
return request_result
def release_name_sync(self, name: str) -> ReleaseNameReply:
"""Request that this message bus release the given name.
:param name: The name to release.
:type name: str
:returns: The reply to the release request.
:rtype: :class:`ReleaseNameReply `
:raises:
- :class:`InvalidBusNameError ` - If \
the given bus name is not valid.
- :class:`DBusError ` - If the service threw \
an error for the method call or returned an invalid result.
- :class:`Exception` - If a connection error occurred.
"""
main = GLib.MainLoop()
release_result = None
release_error = None
def reply_notify(result, err):
nonlocal release_result
nonlocal release_error
release_result = result
release_error = err
main.quit()
super().release_name(name, reply_notify)
main.run()
if release_error:
raise release_error
return release_result
def send(self, msg: Message):
if not msg.serial:
msg.serial = self.next_serial()
self._buffered_messages.append(msg)
if self.unique_name:
self._schedule_write()
def get_proxy_object(
self, bus_name: str, path: str, introspection: intr.Node
) -> ProxyObject:
return super().get_proxy_object(bus_name, path, introspection)
def _schedule_write(self):
if self.writable_source is None or self.writable_source.is_destroyed():
self.writable_source = _MessageWritableSource(self)
self.writable_source.attach(self._main_context)
self.writable_source.add_unix_fd(self._fd, GLib.IO_OUT)
def _authenticate(self, authenticate_notify):
self._stream.write(b"\0")
first_line = self._auth._authentication_start()
if first_line is not None:
if type(first_line) is not str:
raise AuthError("authenticator gave response not type str")
self._stream.write(f"{first_line}\r\n".encode())
self._stream.flush()
def line_notify(line):
try:
resp = self._auth._receive_line(line)
self._stream.write(Authenticator._format_line(resp))
self._stream.flush()
if resp == "BEGIN":
self._readline_source = None
authenticate_notify(None)
return True
except Exception as e:
authenticate_notify(e)
return True
readline_source = _AuthLineSource(self._stream)
readline_source.set_callback(line_notify)
readline_source.add_unix_fd(self._fd, GLib.IO_IN)
readline_source.attach(self._main_context)
# make sure it doesnt get cleaned up
self._readline_source = readline_source
dbus-fast-2.44.1/src/dbus_fast/glib/proxy_object.py 0000664 0000000 0000000 00000024720 14773556132 0022253 0 ustar 00root root 0000000 0000000 import xml.etree.ElementTree as ET
from typing import Union
from .. import introspection as intr
from ..constants import ErrorType
from ..errors import DBusError
from ..message import Message
from ..message_bus import BaseMessageBus
from ..proxy_object import BaseProxyInterface, BaseProxyObject
from ..signature import Variant
from ..unpack import unpack_variants as unpack
# glib is optional
try:
from gi.repository import GLib
except ImportError:
pass
class ProxyInterface(BaseProxyInterface):
"""A class representing a proxy to an interface exported on the bus by
another client for the GLib :class:`MessageBus `
implementation.
This class is not meant to be constructed directly by the user. Use
:func:`ProxyObject.get_interface()
` on a GLib proxy
object to get a proxy interface.
This class exposes methods to call DBus methods, listen to signals, and get
and set properties on the interface that are created dynamically based on
the introspection data passed to the proxy object that made this proxy
interface.
A *method call* takes this form:
.. code-block:: python3
def callback(error: Exception, result: list(Any)):
pass
interface.call_[METHOD](*args, callback)
result = interface.call_[METHOD]_sync(*args)
Where ``METHOD`` is the name of the method converted to snake case.
To call a method, provide ``*args`` that correspond to the *in args* of the
introspection method definition.
To *asynchronously* call a method, provide a callback that takes an error
as the first argument and a list as the second argument. If the call
completed successfully, ``error`` will be :class:`None`. If the service
returns an error, it will be a :class:`DBusError `
with information about the error returned from the bus. The result will be
a list of values that correspond to the *out args* of the introspection
method definition.
To *synchronously* call a method, use the ``call_[METHOD]_sync()`` form.
The ``result`` corresponds to the *out arg* of the introspection method
definition. If the method has more than one otu arg, they are returned
within a :class:`list`.
To *listen to a signal* use this form:
.. code-block:: python3
interface.on_[SIGNAL](callback)
To *stop listening to a signal* use this form:
.. code-block:: python3
interface.off_[SIGNAL](callback)
Where ``SIGNAL`` is the name of the signal converted to snake case.
DBus signals are exposed with an event-callback interface. The provided
``callback`` will be called when the signal is emitted with arguments that
correspond to the *out args* of the interface signal definition.
To *get or set a property* use this form:
.. code-block:: python3
def get_callback(error: Exception, value: Any):
pass
def set_callback(error: Exception)
pass
interface.get_[PROPERTY](get_callback)
value: Any = interface.get_[PROPERTY]_sync()
interface.set_[PROPERTY](set_callback)
interface.set_[PROPERTY]_sync(value)
Where ``PROPERTY`` is the name of the property converted to snake case.
The ``value`` must correspond to the type of the property in the interface
definition.
To asynchronously get or set a property, provide a callback that takes an
:class:`Exception` as the first argument. If the call completed
successfully, ``error`` will be :class:`None`. If the service returns an
error, it will be a :class:`DBusError ` with
information about the error returned from the bus.
If the service returns an error for a synchronous DBus call, a
:class:`DBusError ` will be raised with information
about the error.
"""
def _add_method(self, intr_method):
in_len = len(intr_method.in_args)
out_len = len(intr_method.out_args)
def method_fn(*args, unpack_variants: bool = False):
if len(args) != in_len + 1:
raise TypeError(
f"method {intr_method.name} expects {in_len} arguments and a callback (got {len(args)} args)"
)
args = list(args)
# TODO type check: this callback takes two parameters
# (MessageBus.check_callback(cb))
callback = args.pop()
def call_notify(msg, err):
if err:
callback([], err)
return
try:
BaseProxyInterface._check_method_return(
msg, intr_method.out_signature
)
except DBusError as e:
err = e
if unpack_variants:
callback(unpack(msg.body), err)
else:
callback(msg.body, err)
self.bus.call(
Message(
destination=self.bus_name,
path=self.path,
interface=self.introspection.name,
member=intr_method.name,
signature=intr_method.in_signature,
body=list(args),
),
call_notify,
)
def method_fn_sync(*args, unpack_variants: bool = False):
main = GLib.MainLoop()
call_error = None
call_body = None
def callback(body, err):
nonlocal call_error
nonlocal call_body
call_error = err
call_body = body
main.quit()
method_fn(*args, callback)
main.run()
if call_error:
raise call_error
if not out_len:
return None
if unpack_variants:
call_body = unpack(call_body)
if out_len == 1:
return call_body[0]
return call_body
method_name = f"call_{BaseProxyInterface._to_snake_case(intr_method.name)}"
method_name_sync = f"{method_name}_sync"
setattr(self, method_name, method_fn)
setattr(self, method_name_sync, method_fn_sync)
def _add_property(self, intr_property):
def property_getter(callback, *, unpack_variants: bool = False):
def call_notify(msg, err):
if err:
callback(None, err)
return
try:
BaseProxyInterface._check_method_return(msg)
except Exception as e:
callback(None, e)
return
variant = msg.body[0]
if variant.signature != intr_property.signature:
err = DBusError(
ErrorType.CLIENT_ERROR,
'property returned unexpected signature "{variant.signature}"',
msg,
)
callback(None, err)
return
if unpack_variants:
callback(unpack(variant.value), None)
else:
callback(variant.value, None)
self.bus.call(
Message(
destination=self.bus_name,
path=self.path,
interface="org.freedesktop.DBus.Properties",
member="Get",
signature="ss",
body=[self.introspection.name, intr_property.name],
),
call_notify,
)
def property_getter_sync(*, unpack_variants: bool = False):
property_value = None
reply_error = None
main = GLib.MainLoop()
def callback(value, err):
nonlocal property_value
nonlocal reply_error
property_value = value
reply_error = err
main.quit()
property_getter(callback)
main.run()
if reply_error:
raise reply_error
if unpack_variants:
return unpack(property_value)
return property_value
def property_setter(value, callback):
def call_notify(msg, err):
if err:
callback(None, err)
return None
try:
BaseProxyInterface._check_method_return(msg)
except Exception as e:
callback(None, e)
return None
return callback(None, None)
variant = Variant(intr_property.signature, value)
self.bus.call(
Message(
destination=self.bus_name,
path=self.path,
interface="org.freedesktop.DBus.Properties",
member="Set",
signature="ssv",
body=[self.introspection.name, intr_property.name, variant],
),
call_notify,
)
def property_setter_sync(val):
reply_error = None
main = GLib.MainLoop()
def callback(value, err):
nonlocal reply_error
reply_error = err
main.quit()
property_setter(val, callback)
main.run()
if reply_error:
raise reply_error
snake_case = super()._to_snake_case(intr_property.name)
setattr(self, f"get_{snake_case}", property_getter)
setattr(self, f"get_{snake_case}_sync", property_getter_sync)
setattr(self, f"set_{snake_case}", property_setter)
setattr(self, f"set_{snake_case}_sync", property_setter_sync)
class ProxyObject(BaseProxyObject):
"""The proxy object implementation for the asyncio :class:`MessageBus `.
For more information, see the :class:`BaseProxyObject `.
"""
def __init__(
self,
bus_name: str,
path: str,
introspection: Union[intr.Node, str, ET.Element],
bus: BaseMessageBus,
):
super().__init__(bus_name, path, introspection, bus, ProxyInterface)
def get_interface(self, name: str) -> ProxyInterface:
return super().get_interface(name)
def get_children(self) -> list["ProxyObject"]:
return super().get_children()
dbus-fast-2.44.1/src/dbus_fast/introspection.py 0000664 0000000 0000000 00000062105 14773556132 0021526 0 ustar 00root root 0000000 0000000 import xml.etree.ElementTree as ET
from typing import Optional, Union
from .constants import ArgDirection, PropertyAccess
from .errors import InvalidIntrospectionError
from .signature import SignatureType, get_signature_tree
from .validators import assert_interface_name_valid, assert_member_name_valid
# https://dbus.freedesktop.org/doc/dbus-specification.html#introspection-format
def _fetch_annotations(element: ET.Element) -> dict[str, str]:
annotations: dict[str, str] = {}
for child in element:
if child.tag != "annotation":
continue
annotation_name = child.attrib["name"]
annotation_value = child.attrib["value"]
annotations[annotation_name] = annotation_value
return annotations
def _extract_annotations(element: ET.Element, annotations: dict[str, str]) -> None:
for key, value in annotations.items():
annotation = ET.Element("annotation", {"name": key, "value": value})
element.append(annotation)
class Arg:
"""A class that represents an input or output argument to a signal or a method.
:ivar name: The name of this arg.
:vartype name: str
:ivar direction: Whether this is an input or an output argument.
:vartype direction: :class:`ArgDirection `
:ivar type: The parsed signature type of this argument.
:vartype type: :class:`SignatureType `
:ivar signature: The signature string of this argument.
:vartype signature: str
:ivar annotations: The annotations of this arg.
:vartype annotations: dict[str, str]
:raises:
- :class:`InvalidMemberNameError ` - If the name of the arg is not valid.
- :class:`InvalidSignatureError ` - If the signature is not valid.
- :class:`InvalidIntrospectionError ` - If the signature is not a single complete type.
"""
def __init__(
self,
signature: Union[SignatureType, str],
direction: Optional[ArgDirection] = None,
name: Optional[str] = None,
annotations: Optional[dict[str, str]] = None,
):
type_ = None
if type(signature) is SignatureType:
type_ = signature
signature = signature.signature
else:
tree = get_signature_tree(signature)
if len(tree.types) != 1:
raise InvalidIntrospectionError(
f"an argument must have a single complete type. (has {len(tree.types)} types)"
)
type_ = tree.types[0]
self.type = type_
self.signature = signature
self.name = name
self.direction = direction
self.annotations = annotations or {}
def from_xml(element: ET.Element, direction: ArgDirection) -> "Arg":
"""Convert a :class:`xml.etree.ElementTree.Element` into a
:class:`Arg`.
The element must be valid DBus introspection XML for an ``arg``.
:param element: The parsed XML element.
:type element: :class:`xml.etree.ElementTree.Element`
:param direction: The direction of this arg. Must be specified because it can default to different values depending on if it's in a method or signal.
:type direction: :class:`ArgDirection `
:raises:
- :class:`InvalidIntrospectionError ` - If the XML tree is not valid introspection data.
"""
name = element.attrib.get("name")
signature = element.attrib.get("type")
if not signature:
raise InvalidIntrospectionError(
'a method argument must have a "type" attribute'
)
annotations = _fetch_annotations(element)
return Arg(signature, direction, name, annotations)
def to_xml(self) -> ET.Element:
"""Convert this :class:`Arg` into an :class:`xml.etree.ElementTree.Element`."""
element = ET.Element("arg")
if self.name:
element.set("name", self.name)
if self.direction:
element.set("direction", self.direction.value)
element.set("type", self.signature)
_extract_annotations(element, self.annotations)
return element
class Signal:
"""A class that represents a signal exposed on an interface.
:ivar name: The name of this signal
:vartype name: str
:ivar args: A list of output arguments for this signal.
:vartype args: list(Arg)
:ivar signature: The collected signature of the output arguments.
:vartype signature: str
:ivar annotations: The annotations of this signal.
:vartype annotations: dict[str, str]
:raises:
- :class:`InvalidMemberNameError ` - If the name of the signal is not a valid member name.
"""
def __init__(
self,
name: Optional[str],
args: Optional[list[Arg]] = None,
annotations: Optional[dict[str, str]] = None,
):
if name is not None:
assert_member_name_valid(name)
self.name = name
self.args = args or []
self.signature = "".join(arg.signature for arg in self.args)
self.annotations = annotations or {}
def from_xml(element):
"""Convert an :class:`xml.etree.ElementTree.Element` to a :class:`Signal`.
The element must be valid DBus introspection XML for a ``signal``.
:param element: The parsed XML element.
:type element: :class:`xml.etree.ElementTree.Element`
:param is_root: Whether this is the root node
:type is_root: bool
:raises:
- :class:`InvalidIntrospectionError ` - If the XML tree is not valid introspection data.
"""
name = element.attrib.get("name")
if not name:
raise InvalidIntrospectionError('signals must have a "name" attribute')
args = []
for child in element:
if child.tag == "arg":
args.append(Arg.from_xml(child, ArgDirection.OUT))
annotations = _fetch_annotations(element)
signal = Signal(name, args, annotations)
return signal
def to_xml(self) -> ET.Element:
"""Convert this :class:`Signal` into an :class:`xml.etree.ElementTree.Element`."""
element = ET.Element("signal")
element.set("name", self.name)
for arg in self.args:
element.append(arg.to_xml())
_extract_annotations(element, self.annotations)
return element
class Method:
"""A class that represents a method exposed on an :class:`Interface`.
:ivar name: The name of this method.
:vartype name: str
:ivar in_args: A list of input arguments to this method.
:vartype in_args: list(Arg)
:ivar out_args: A list of output arguments to this method.
:vartype out_args: list(Arg)
:ivar in_signature: The collected signature string of the input arguments.
:vartype in_signature: str
:ivar out_signature: The collected signature string of the output arguments.
:vartype out_signature: str
:ivar annotations: The annotations of this method.
:vartype annotations: dict[str, str]
:raises:
- :class:`InvalidMemberNameError ` - If the name of this method is not valid.
"""
def __init__(
self,
name: str,
in_args: list[Arg] = [],
out_args: list[Arg] = [],
annotations: Optional[dict[str, str]] = None,
):
assert_member_name_valid(name)
self.name = name
self.in_args = in_args
self.out_args = out_args
self.in_signature = "".join(arg.signature for arg in in_args)
self.out_signature = "".join(arg.signature for arg in out_args)
self.annotations = annotations or {}
def from_xml(element: ET.Element) -> "Method":
"""Convert an :class:`xml.etree.ElementTree.Element` to a :class:`Method`.
The element must be valid DBus introspection XML for a ``method``.
:param element: The parsed XML element.
:type element: :class:`xml.etree.ElementTree.Element`
:param is_root: Whether this is the root node
:type is_root: bool
:raises:
- :class:`InvalidIntrospectionError ` - If the XML tree is not valid introspection data.
"""
name = element.attrib.get("name")
if not name:
raise InvalidIntrospectionError('interfaces must have a "name" attribute')
in_args = []
out_args = []
for child in element:
if child.tag == "arg":
direction = ArgDirection(child.attrib.get("direction", "in"))
arg = Arg.from_xml(child, direction)
if direction == ArgDirection.IN:
in_args.append(arg)
elif direction == ArgDirection.OUT:
out_args.append(arg)
annotations = _fetch_annotations(element)
return Method(name, in_args, out_args, annotations)
def to_xml(self) -> ET.Element:
"""Convert this :class:`Method` into an :class:`xml.etree.ElementTree.Element`."""
element = ET.Element("method")
element.set("name", self.name)
for arg in self.in_args:
element.append(arg.to_xml())
for arg in self.out_args:
element.append(arg.to_xml())
_extract_annotations(element, self.annotations)
return element
class Property:
"""A class that represents a DBus property exposed on an
:class:`Interface`.
:ivar name: The name of this property.
:vartype name: str
:ivar signature: The signature string for this property. Must be a single complete type.
:vartype signature: str
:ivar access: Whether this property is readable and writable.
:vartype access: :class:`PropertyAccess `
:ivar type: The parsed type of this property.
:vartype type: :class:`SignatureType `
:ivar annotations: The annotations of this property.
:vartype annotations: dict[str, str]
:raises:
- :class:`InvalidIntrospectionError ` - If the property is not a single complete type.
- :class `InvalidSignatureError ` - If the given signature is not valid.
- :class: `InvalidMemberNameError ` - If the member name is not valid.
"""
def __init__(
self,
name: str,
signature: str,
access: PropertyAccess = PropertyAccess.READWRITE,
annotations: Optional[dict[str, str]] = None,
validate: bool = True,
):
if validate:
assert_member_name_valid(name)
tree = get_signature_tree(signature)
if len(tree.types) != 1:
raise InvalidIntrospectionError(
f"properties must have a single complete type. (has {len(tree.types)} types)"
)
self.name = name
self.signature = signature
self.access = access
self.type = tree.types[0]
self.annotations = annotations or {}
def from_xml(element, validate: bool = True):
"""Convert an :class:`xml.etree.ElementTree.Element` to a :class:`Property`.
The element must be valid DBus introspection XML for a ``property``.
:param element: The parsed XML element.
:type element: :class:`xml.etree.ElementTree.Element`
:raises:
- :class:`InvalidIntrospectionError ` - If the XML tree is not valid introspection data.
"""
name = element.attrib.get("name")
signature = element.attrib.get("type")
access = PropertyAccess(element.attrib.get("access", "readwrite"))
if not name:
raise InvalidIntrospectionError('properties must have a "name" attribute')
if not signature:
raise InvalidIntrospectionError('properties must have a "type" attribute')
annotations = _fetch_annotations(element)
return Property(
name, signature, access, annotations=annotations, validate=validate
)
def to_xml(self) -> ET.Element:
"""Convert this :class:`Property` into an :class:`xml.etree.ElementTree.Element`."""
element = ET.Element("property")
element.set("name", self.name)
element.set("type", self.signature)
element.set("access", self.access.value)
_extract_annotations(element, self.annotations)
return element
class Interface:
"""A class that represents a DBus interface exported on on object path.
Contains information about the methods, signals, and properties exposed on
this interface.
:ivar name: The name of this interface.
:vartype name: str
:ivar methods: A list of methods exposed on this interface.
:vartype methods: list(:class:`Method`)
:ivar signals: A list of signals exposed on this interface.
:vartype signals: list(:class:`Signal`)
:ivar properties: A list of properties exposed on this interface.
:vartype properties: list(:class:`Property`)
:ivar annotations: The annotations of this interface.
:vartype annotations: dict[str, str]
:raises:
- :class:`InvalidInterfaceNameError ` - If the name is not a valid interface name.
"""
def __init__(
self,
name: str,
methods: Optional[list[Method]] = None,
signals: Optional[list[Signal]] = None,
properties: Optional[list[Property]] = None,
annotations: Optional[dict[str, str]] = None,
):
assert_interface_name_valid(name)
self.name = name
self.methods = methods if methods is not None else []
self.signals = signals if signals is not None else []
self.properties = properties if properties is not None else []
self.annotations = annotations or {}
@staticmethod
def from_xml(
element: ET.Element, validate_property_names: bool = True
) -> "Interface":
"""Convert a :class:`xml.etree.ElementTree.Element` into a
:class:`Interface`.
The element must be valid DBus introspection XML for an ``interface``.
:param element: The parsed XML element.
:type element: :class:`xml.etree.ElementTree.Element`
:raises:
- :class:`InvalidIntrospectionError ` - If the XML tree is not valid introspection data.
"""
name = element.attrib.get("name")
if not name:
raise InvalidIntrospectionError('interfaces must have a "name" attribute')
interface = Interface(name)
for child in element:
if child.tag == "method":
interface.methods.append(Method.from_xml(child))
elif child.tag == "signal":
interface.signals.append(Signal.from_xml(child))
elif child.tag == "property":
interface.properties.append(
Property.from_xml(child, validate=validate_property_names)
)
interface.annotations = _fetch_annotations(element)
return interface
def to_xml(self) -> ET.Element:
"""Convert this :class:`Interface` into an :class:`xml.etree.ElementTree.Element`."""
element = ET.Element("interface")
element.set("name", self.name)
for method in self.methods:
element.append(method.to_xml())
for signal in self.signals:
element.append(signal.to_xml())
for prop in self.properties:
element.append(prop.to_xml())
_extract_annotations(element, self.annotations)
return element
class Node:
"""A class that represents a node in an object path in introspection data.
A node contains information about interfaces exported on this path and
child nodes. A node can be converted to and from introspection XML exposed
through the ``org.freedesktop.DBus.Introspectable`` standard DBus
interface.
This class is an essential building block for a high-level DBus interface.
This is the underlying data structure for the :class:`ProxyObject
`. A :class:`ServiceInterface
` definition is converted to this class
to expose XML on the introspectable interface.
:ivar interfaces: A list of interfaces exposed on this node.
:vartype interfaces: list(:class:`Interface `)
:ivar nodes: A list of child nodes.
:vartype nodes: list(:class:`Node`)
:ivar name: The object path of this node.
:vartype name: str
:ivar is_root: Whether this is the root node. False if it is a child node.
:vartype is_root: bool
:raises:
- :class:`InvalidIntrospectionError ` - If the name is not a valid node name.
"""
def __init__(
self,
name: Optional[str] = None,
interfaces: Optional[list[Interface]] = None,
is_root: bool = True,
):
if not is_root and not name:
raise InvalidIntrospectionError('child nodes must have a "name" attribute')
self.interfaces = interfaces if interfaces is not None else []
self.nodes = []
self.name = name
self.is_root = is_root
@staticmethod
def from_xml(
element: ET.Element, is_root: bool = False, validate_property_names: bool = True
) -> "Node":
"""Convert an :class:`xml.etree.ElementTree.Element` to a :class:`Node`.
The element must be valid DBus introspection XML for a ``node``.
:param element: The parsed XML element.
:type element: :class:`xml.etree.ElementTree.Element`
:param is_root: Whether this is the root node
:type is_root: bool
:param validate_property_names: Whether to validate property names or not
:type validate_property_names: bool
:raises:
- :class:`InvalidIntrospectionError ` - If the XML tree is not valid introspection data.
"""
node = Node(element.attrib.get("name"), is_root=is_root)
for child in element:
if child.tag == "interface":
node.interfaces.append(
Interface.from_xml(
child, validate_property_names=validate_property_names
)
)
elif child.tag == "node":
node.nodes.append(
Node.from_xml(
child, validate_property_names=validate_property_names
)
)
return node
@staticmethod
def parse(data: str, validate_property_names: bool = True) -> "Node":
"""Parse XML data as a string into a :class:`Node`.
The string must be valid DBus introspection XML.
:param data: The XMl string.
:type data: str
:param validate_property_names: Whether to validate property names or not
:type validate_property_names: bool
:raises:
- :class:`InvalidIntrospectionError ` - If the string is not valid introspection data.
"""
element = ET.fromstring(data)
if element.tag != "node":
raise InvalidIntrospectionError(
'introspection data must have a "node" for the root element'
)
return Node.from_xml(
element, is_root=True, validate_property_names=validate_property_names
)
def to_xml(self) -> ET.Element:
"""Convert this :class:`Node` into an :class:`xml.etree.ElementTree.Element`."""
element = ET.Element("node")
if self.name:
element.set("name", self.name)
for interface in self.interfaces:
element.append(interface.to_xml())
for node in self.nodes:
element.append(node.to_xml())
return element
def tostring(self) -> str:
"""Convert this :class:`Node` into a DBus introspection XML string."""
header = '\n'
def indent(elem, level=0):
i = "\n" + level * " "
if len(elem):
if not elem.text or not elem.text.strip():
elem.text = i + " "
if not elem.tail or not elem.tail.strip():
elem.tail = i
for elem_ in elem:
indent(elem_, level + 1)
if not elem.tail or not elem.tail.strip():
elem.tail = i
elif level and (not elem.tail or not elem.tail.strip()):
elem.tail = i
xml = self.to_xml()
indent(xml)
return header + ET.tostring(xml, encoding="unicode").rstrip()
@staticmethod
def default(name: Optional[str] = None) -> "Node":
"""Create a :class:`Node` with the default interfaces supported by this library.
The default interfaces include:
* ``org.freedesktop.DBus.Introspectable``
* ``org.freedesktop.DBus.Peer``
* ``org.freedesktop.DBus.Properties``
* ``org.freedesktop.DBus.ObjectManager``
"""
return Node(
name,
is_root=True,
interfaces=[
Interface(
"org.freedesktop.DBus.Introspectable",
methods=[
Method(
"Introspect", out_args=[Arg("s", ArgDirection.OUT, "data")]
)
],
),
Interface(
"org.freedesktop.DBus.Peer",
methods=[
Method(
"GetMachineId",
out_args=[Arg("s", ArgDirection.OUT, "machine_uuid")],
),
Method("Ping"),
],
),
Interface(
"org.freedesktop.DBus.Properties",
methods=[
Method(
"Get",
in_args=[
Arg("s", ArgDirection.IN, "interface_name"),
Arg("s", ArgDirection.IN, "property_name"),
],
out_args=[Arg("v", ArgDirection.OUT, "value")],
),
Method(
"Set",
in_args=[
Arg("s", ArgDirection.IN, "interface_name"),
Arg("s", ArgDirection.IN, "property_name"),
Arg("v", ArgDirection.IN, "value"),
],
),
Method(
"GetAll",
in_args=[Arg("s", ArgDirection.IN, "interface_name")],
out_args=[Arg("a{sv}", ArgDirection.OUT, "props")],
),
],
signals=[
Signal(
"PropertiesChanged",
args=[
Arg("s", ArgDirection.OUT, "interface_name"),
Arg("a{sv}", ArgDirection.OUT, "changed_properties"),
Arg("as", ArgDirection.OUT, "invalidated_properties"),
],
)
],
),
Interface(
"org.freedesktop.DBus.ObjectManager",
methods=[
Method(
"GetManagedObjects",
out_args=[
Arg(
"a{oa{sa{sv}}}",
ArgDirection.OUT,
"objpath_interfaces_and_properties",
)
],
),
],
signals=[
Signal(
"InterfacesAdded",
args=[
Arg("o", ArgDirection.OUT, "object_path"),
Arg(
"a{sa{sv}}",
ArgDirection.OUT,
"interfaces_and_properties",
),
],
),
Signal(
"InterfacesRemoved",
args=[
Arg("o", ArgDirection.OUT, "object_path"),
Arg("as", ArgDirection.OUT, "interfaces"),
],
),
],
),
],
)
dbus-fast-2.44.1/src/dbus_fast/message.pxd 0000664 0000000 0000000 00000003451 14773556132 0020414 0 ustar 00root root 0000000 0000000 """cdefs for message.py"""
import cython
from ._private.marshaller cimport Marshaller
from .signature cimport Variant, SignatureTree, SignatureType
cdef object ErrorType
cdef object MessageType
cdef object HEADER_PATH
cdef object HEADER_INTERFACE
cdef object HEADER_MEMBER
cdef object HEADER_ERROR_NAME
cdef object HEADER_REPLY_SERIAL
cdef object HEADER_DESTINATION
cdef object HEADER_SENDER
cdef object HEADER_SIGNATURE
cdef object HEADER_UNIX_FDS
cdef object LITTLE_ENDIAN
cdef object PROTOCOL_VERSION
cdef object MESSAGE_FLAG
cdef object MESSAGE_FLAG_NONE
cdef object MESSAGE_TYPE_METHOD_CALL
cdef SignatureTree SIGNATURE_TREE_G
cdef SignatureTree SIGNATURE_TREE_O
cdef SignatureTree SIGNATURE_TREE_S
cdef SignatureTree SIGNATURE_TREE_U
cdef get_signature_tree
cdef class Message:
cdef public object destination
cdef public object path
cdef public object interface
cdef public object member
cdef public object message_type
cdef public object flags
cdef public object error_name
cdef public unsigned int reply_serial
cdef public object sender
cdef public list unix_fds
cdef public str signature
cdef public SignatureTree signature_tree
cdef public object body
cdef public unsigned int serial
@cython.locals(
body_buffer=bytearray,
header_buffer=bytearray,
var=Variant
)
cpdef _marshall(self, object negotiate_unix_fd)
cdef _fast_init(
self,
object destination,
object path,
object interface,
object member,
object message_type,
object flags,
object error_name,
unsigned int reply_serial,
object sender,
list unix_fds,
SignatureTree signature_tree,
object body,
unsigned int serial,
bint validate
)
dbus-fast-2.44.1/src/dbus_fast/message.py 0000664 0000000 0000000 00000033245 14773556132 0020255 0 ustar 00root root 0000000 0000000 from typing import Any, Optional, Union
from ._private.constants import LITTLE_ENDIAN, PROTOCOL_VERSION, HeaderField
from ._private.marshaller import Marshaller
from .constants import ErrorType, MessageFlag, MessageType
from .errors import InvalidMessageError
from .signature import SignatureTree, Variant, get_signature_tree
from .validators import (
assert_bus_name_valid,
assert_interface_name_valid,
assert_member_name_valid,
assert_object_path_valid,
)
REQUIRED_FIELDS = {
MessageType.METHOD_CALL.value: ("path", "member"),
MessageType.SIGNAL.value: ("path", "member", "interface"),
MessageType.ERROR.value: ("error_name", "reply_serial"),
MessageType.METHOD_RETURN.value: ("reply_serial",),
}
HEADER_PATH = HeaderField.PATH.value
HEADER_INTERFACE = HeaderField.INTERFACE.value
HEADER_MEMBER = HeaderField.MEMBER.value
HEADER_ERROR_NAME = HeaderField.ERROR_NAME.value
HEADER_REPLY_SERIAL = HeaderField.REPLY_SERIAL.value
HEADER_DESTINATION = HeaderField.DESTINATION.value
HEADER_SIGNATURE = HeaderField.SIGNATURE.value
HEADER_UNIX_FDS = HeaderField.UNIX_FDS.value
MESSAGE_FLAG = MessageFlag
MESSAGE_FLAG_NONE = MessageFlag.NONE
MESSAGE_TYPE_METHOD_CALL = MessageType.METHOD_CALL
SIGNATURE_TREE_G = get_signature_tree("g")
SIGNATURE_TREE_O = get_signature_tree("o")
SIGNATURE_TREE_S = get_signature_tree("s")
SIGNATURE_TREE_U = get_signature_tree("u")
_int = int
_str = str
_bool = bool
_MessageType = MessageType
_MessageFlag = MessageFlag
_list = list
class Message:
"""A class for sending and receiving messages through the
:class:`MessageBus ` with the
low-level api.
A ``Message`` can be constructed by the user to send over the message bus.
When messages are received, such as from method calls or signal emissions,
they will use this class as well.
:ivar destination: The address of the client for which this message is intended.
:vartype destination: str
:ivar path: The intended object path exported on the destination bus.
:vartype path: str
:ivar interface: The intended interface on the object path.
:vartype interface: str
:ivar member: The intended member on the interface.
:vartype member: str
:ivar message_type: The type of this message. A method call, signal, method return, or error.
:vartype message_type: :class:`MessageType`
:ivar flags: Flags that affect the behavior of this message.
:vartype flags: :class:`MessageFlag`
:ivar error_name: If this message is an error, the name of this error. Must be a valid interface name.
:vartype error_name: str
:ivar reply_serial: If this is a return type, the serial this message is in reply to.
:vartype reply_serial: int
:ivar sender: The address of the sender of this message. Will be a unique name.
:vartype sender: str
:ivar unix_fds: A list of unix fds that were sent in the header of this message.
:vartype unix_fds: list(int)
:ivar signature: The signature of the body of this message.
:vartype signature: str
:ivar signature_tree: The signature parsed as a signature tree.
:vartype signature_tree: :class:`SignatureTree`
:ivar body: The body of this message. Must match the signature.
:vartype body: list(Any)
:ivar serial: The serial of the message. Will be automatically set during message sending if not present. Use the ``new_serial()`` method of the bus to generate a serial.
:vartype serial: int
:raises:
- :class:`InvalidMessageError` - If the message is malformed or missing fields for the message type.
- :class:`InvalidSignatureError` - If the given signature is not valid.
- :class:`InvalidObjectPathError` - If ``path`` is not a valid object path.
- :class:`InvalidBusNameError` - If ``destination`` is not a valid bus name.
- :class:`InvalidMemberNameError` - If ``member`` is not a valid member name.
- :class:`InvalidInterfaceNameError` - If ``error_name`` or ``interface`` is not a valid interface name.
"""
__slots__ = (
"body",
"destination",
"error_name",
"flags",
"interface",
"member",
"message_type",
"path",
"reply_serial",
"sender",
"serial",
"signature",
"signature_tree",
"unix_fds",
)
def __init__(
self,
destination: Optional[str] = None,
path: Optional[str] = None,
interface: Optional[str] = None,
member: Optional[str] = None,
message_type: MessageType = MESSAGE_TYPE_METHOD_CALL,
flags: Union[MessageFlag, int] = MESSAGE_FLAG_NONE,
error_name: Optional[Union[str, ErrorType]] = None,
reply_serial: Optional[int] = None,
sender: Optional[str] = None,
unix_fds: list[int] = [],
signature: Optional[Union[SignatureTree, str]] = None,
body: list[Any] = [],
serial: Optional[int] = None,
validate: bool = True,
) -> None:
self._fast_init(
destination,
path,
interface,
member,
message_type,
flags if type(flags) is MESSAGE_FLAG else MESSAGE_FLAG(flags),
str(error_name.value) if type(error_name) is ErrorType else error_name,
reply_serial or 0,
sender,
unix_fds,
signature
if type(signature) is SignatureTree
else get_signature_tree(signature or ""),
body,
serial or 0,
validate,
)
def _fast_init(
self,
destination: Optional[_str],
path: Optional[_str],
interface: Optional[_str],
member: Optional[_str],
message_type: _MessageType,
flags: _MessageFlag,
error_name: Optional[_str],
reply_serial: _int,
sender: _str,
unix_fds: _list[int],
signature_tree: SignatureTree,
body: _list[Any],
serial: _int,
validate: _bool,
) -> None:
self.destination = destination
self.path = path
self.interface = interface
self.member = member
self.message_type = message_type
self.flags = flags
self.error_name = error_name
self.reply_serial = reply_serial
self.sender = sender
self.unix_fds = unix_fds
self.signature = signature_tree.signature
self.signature_tree = signature_tree
self.body = body
self.serial = serial
if not validate:
return
if self.destination is not None:
assert_bus_name_valid(self.destination)
if self.interface is not None:
assert_interface_name_valid(self.interface)
if self.path is not None:
assert_object_path_valid(self.path)
if self.member is not None:
assert_member_name_valid(self.member)
if self.error_name is not None:
assert_interface_name_valid(self.error_name) # type: ignore[arg-type]
required_fields = REQUIRED_FIELDS.get(self.message_type.value)
if not required_fields:
raise InvalidMessageError(f"got unknown message type: {self.message_type}")
for field in required_fields:
if not getattr(self, field):
raise InvalidMessageError(f"missing required field: {field}")
def __repr__(self) -> str:
"""Return a string representation of this message."""
return (
f""
)
@staticmethod
def new_error(
msg: "Message", error_name: Union[str, ErrorType], error_text: str
) -> "Message":
"""A convenience constructor to create an error message in reply to the given message.
:param msg: The message this error is in reply to.
:type msg: :class:`Message`
:param error_name: The name of this error. Must be a valid interface name.
:type error_name: str
:param error_text: Human-readable text for the error.
:returns: The error message.
:rtype: :class:`Message`
:raises:
- :class:`InvalidInterfaceNameError` - If the error_name is not a valid interface name.
"""
return Message(
message_type=MessageType.ERROR,
reply_serial=msg.serial,
destination=msg.sender,
error_name=error_name,
signature="s",
body=[error_text],
)
@staticmethod
def new_method_return(
msg: "Message",
signature: str = "",
body: list[Any] = [],
unix_fds: list[int] = [],
) -> "Message":
"""A convenience constructor to create a method return to the given method call message.
:param msg: The method call message this is a reply to.
:type msg: :class:`Message`
:param signature: The signature for the message body.
:type signature: str
:param body: The body of this message. Must match the signature.
:type body: list(Any)
:param unix_fds: List integer file descriptors to send with this message.
:type body: list(int)
:returns: The method return message
:rtype: :class:`Message`
:raises:
- :class:`InvalidSignatureError` - If the signature is not a valid signature.
"""
return Message(
message_type=MessageType.METHOD_RETURN,
reply_serial=msg.serial,
destination=msg.sender,
signature=signature,
body=body,
unix_fds=unix_fds,
)
@staticmethod
def new_signal(
path: str,
interface: str,
member: str,
signature: str = "",
body: Optional[list[Any]] = None,
unix_fds: Optional[list[int]] = None,
) -> "Message":
"""A convenience constructor to create a new signal message.
:param path: The path of this signal.
:type path: str
:param interface: The interface of this signal.
:type interface: str
:param member: The member name of this signal.
:type member: str
:param signature: The signature of the signal body.
:type signature: str
:param body: The body of this signal message.
:type body: list(Any)
:param unix_fds: List integer file descriptors to send with this message.
:type body: list(int)
:returns: The signal message.
:rtype: :class:`Message`
:raises:
- :class:`InvalidSignatureError` - If the signature is not a valid signature.
- :class:`InvalidObjectPathError` - If ``path`` is not a valid object path.
- :class:`InvalidInterfaceNameError` - If ``interface`` is not a valid interface name.
- :class:`InvalidMemberNameError` - If ``member`` is not a valid member name.
"""
return Message(
message_type=MessageType.SIGNAL,
interface=interface,
path=path,
member=member,
signature=signature,
body=body or [],
unix_fds=unix_fds or [],
)
def _marshall(self, negotiate_unix_fd: bool) -> bytearray:
"""Marshall this message into a byte array."""
# TODO maximum message size is 134217728 (128 MiB)
body_block = Marshaller(self.signature, self.body)
body_buffer = body_block._marshall()
fields = []
# No verify here since the marshaller will raise an exception if the
# Variant is invalid.
if self.path:
fields.append((HEADER_PATH, Variant._factory(SIGNATURE_TREE_O, self.path)))
if self.interface:
fields.append(
(HEADER_INTERFACE, Variant._factory(SIGNATURE_TREE_S, self.interface))
)
if self.member:
fields.append(
(HEADER_MEMBER, Variant._factory(SIGNATURE_TREE_S, self.member))
)
if self.error_name:
fields.append(
(
HEADER_ERROR_NAME,
Variant._factory(SIGNATURE_TREE_S, self.error_name),
)
)
if self.reply_serial:
fields.append(
(
HEADER_REPLY_SERIAL,
Variant._factory(SIGNATURE_TREE_U, self.reply_serial),
)
)
if self.destination:
fields.append(
(
HEADER_DESTINATION,
Variant._factory(SIGNATURE_TREE_S, self.destination),
)
)
if self.signature:
fields.append(
(HEADER_SIGNATURE, Variant._factory(SIGNATURE_TREE_G, self.signature))
)
if self.unix_fds and negotiate_unix_fd:
fields.append(
(
HEADER_UNIX_FDS,
Variant._factory(SIGNATURE_TREE_U, len(self.unix_fds)),
)
)
header_body = [
LITTLE_ENDIAN,
self.message_type.value,
self.flags.value,
PROTOCOL_VERSION,
len(body_buffer),
self.serial,
fields,
]
header_block = Marshaller("yyyyuua(yv)", header_body)
header_block._marshall()
header_block._align(8)
header_buffer = header_block._buffer()
return header_buffer + body_buffer
dbus-fast-2.44.1/src/dbus_fast/message_bus.pxd 0000664 0000000 0000000 00000004036 14773556132 0021265 0 ustar 00root root 0000000 0000000 import cython
from ._private.address cimport get_bus_address, parse_address
from .message cimport Message
from .service cimport ServiceInterface, _Method
cdef bint TYPE_CHECKING
cdef object MessageType
cdef object DBusError
cdef object MessageFlag
cdef object MESSAGE_TYPE_CALL
cdef object MESSAGE_TYPE_SIGNAL
cdef cython.uint NO_REPLY_EXPECTED_VALUE
cdef object NONE
cdef object NO_REPLY_EXPECTED
cdef object BLOCK_UNEXPECTED_REPLY
cdef object assert_object_path_valid
cdef object assert_bus_name_valid
@cython.locals(flag_value=cython.uint)
cdef bint _expects_reply(Message msg)
cdef class BaseMessageBus:
cdef public object unique_name
cdef public bint _disconnected
cdef public object _user_disconnect
cdef public cython.dict _method_return_handlers
cdef public object _serial
cdef public cython.dict _path_exports
cdef public cython.list _user_message_handlers
cdef public cython.dict _name_owners
cdef public object _bus_address
cdef public object _name_owner_match_rule
cdef public cython.dict _match_rules
cdef public object _high_level_client_initialized
cdef public object _ProxyObject
cdef public object _machine_id
cdef public bint _negotiate_unix_fd
cdef public object _sock
cdef public object _stream
cdef public object _fd
cpdef void _process_message(self, Message msg) except *
@cython.locals(exported_service_interface=ServiceInterface)
cpdef export(self, str path, ServiceInterface interface)
@cython.locals(
methods=cython.list,
method=_Method,
interface=ServiceInterface,
interfaces=dict,
)
cdef _find_message_handler(self, Message msg)
cdef _find_any_message_handler_matching_signature(self, dict interfaces, Message msg)
cdef _setup_socket(self)
cpdef _call(self, Message msg, object callback)
cpdef next_serial(self)
cpdef void _callback_method_handler(
self,
ServiceInterface interface,
_Method method,
Message msg,
object send_reply
) except *
dbus-fast-2.44.1/src/dbus_fast/message_bus.py 0000664 0000000 0000000 00000136375 14773556132 0021136 0 ustar 00root root 0000000 0000000 from __future__ import annotations
import inspect
import logging
import socket
import traceback
import xml.etree.ElementTree as ET
from functools import partial
from typing import TYPE_CHECKING, Any, Callable
from . import introspection as intr
from ._private.address import get_bus_address, parse_address
from ._private.util import replace_fds_with_idx, replace_idx_with_fds
from .constants import (
BusType,
ErrorType,
MessageFlag,
MessageType,
NameFlag,
ReleaseNameReply,
RequestNameReply,
)
from .errors import DBusError, InvalidAddressError
from .message import Message
from .proxy_object import BaseProxyObject
from .send_reply import SendReply
from .service import HandlerType, ServiceInterface, _Method, _Property
from .signature import Variant
from .validators import assert_bus_name_valid, assert_object_path_valid
MESSAGE_TYPE_CALL = MessageType.METHOD_CALL
MESSAGE_TYPE_SIGNAL = MessageType.SIGNAL
NO_REPLY_EXPECTED_VALUE = MessageFlag.NO_REPLY_EXPECTED.value
NO_REPLY_EXPECTED = MessageFlag.NO_REPLY_EXPECTED
NONE = MessageFlag.NONE
_LOGGER = logging.getLogger(__name__)
_Message = Message
def _expects_reply(msg: _Message) -> bool:
"""Whether a message expects a reply."""
if msg.flags is NO_REPLY_EXPECTED:
return False
if msg.flags is NONE:
return True
# Slow check for NO_REPLY_EXPECTED
flag_value = msg.flags.value
return not (flag_value & NO_REPLY_EXPECTED_VALUE)
def _block_unexpected_reply(reply: _Message) -> None:
"""Block a reply if it's not expected.
Previously we silently ignored replies that were not expected, but this
lead to implementation errors that were hard to debug. Now we log a
debug message instead.
"""
_LOGGER.debug(
"Blocked attempt to send a reply from handler "
"that received a message with flag "
"MessageFlag.NO_REPLY_EXPECTED: %s",
reply,
)
BLOCK_UNEXPECTED_REPLY = _block_unexpected_reply
class BaseMessageBus:
"""An abstract class to manage a connection to a DBus message bus.
The message bus class is the entry point into all the features of the
library. It sets up a connection to the DBus daemon and exposes an
interface to send and receive messages and expose services.
This class is not meant to be used directly by users. For more information,
see the documentation for the implementation of the message bus you plan to
use.
:param bus_type: The type of bus to connect to. Affects the search path for
the bus address.
:type bus_type: :class:`BusType `
:param bus_address: A specific bus address to connect to. Should not be
used under normal circumstances.
:type bus_address: str
:param ProxyObject: The proxy object implementation for this message bus.
Must be passed in by an implementation that supports the high-level client.
:type ProxyObject: Type[:class:`BaseProxyObject
`]
:ivar unique_name: The unique name of the message bus connection. It will
be :class:`None` until the message bus connects.
:vartype unique_name: str
:ivar connected: True if this message bus is expected to be able to send
and receive messages.
:vartype connected: bool
"""
__slots__ = (
"_ProxyObject",
"_bus_address",
"_disconnected",
"_fd",
"_high_level_client_initialized",
"_machine_id",
"_match_rules",
"_method_return_handlers",
"_name_owner_match_rule",
"_name_owners",
"_negotiate_unix_fd",
"_path_exports",
"_serial",
"_sock",
"_stream",
"_user_disconnect",
"_user_message_handlers",
"unique_name",
)
def __init__(
self,
bus_address: str | None = None,
bus_type: BusType = BusType.SESSION,
ProxyObject: type[BaseProxyObject] | None = None,
negotiate_unix_fd: bool = False,
) -> None:
self.unique_name: str | None = None
self._disconnected = False
self._negotiate_unix_fd = negotiate_unix_fd
# True if the user disconnected himself, so don't throw errors out of
# the main loop.
self._user_disconnect = False
self._method_return_handlers: dict[
int, Callable[[Message | None, Exception | None], None]
] = {}
self._serial = 0
self._user_message_handlers: list[
Callable[[Message], Message | bool | None]
] = []
# the key is the name and the value is the unique name of the owner.
# This cache is kept up to date by the NameOwnerChanged signal and is
# used to route messages to the correct proxy object. (used for the
# high level client only)
self._name_owners: dict[str, str] = {}
# used for the high level service
self._path_exports: dict[str, dict[str, ServiceInterface]] = {}
self._bus_address = (
parse_address(bus_address)
if bus_address
else parse_address(get_bus_address(bus_type))
)
# the bus implementations need this rule for the high level client to
# work correctly.
self._name_owner_match_rule = "sender='org.freedesktop.DBus',interface='org.freedesktop.DBus',path='/org/freedesktop/DBus',member='NameOwnerChanged'"
# _match_rules: the keys are match rules and the values are ref counts
# (used for the high level client only)
self._match_rules: dict[str, int] = {}
self._high_level_client_initialized = False
self._ProxyObject = ProxyObject
# machine id is lazy loaded
self._machine_id: int | None = None
self._sock: socket.socket | None = None
self._fd: int | None = None
self._stream: Any | None = None
self._setup_socket()
@property
def connected(self) -> bool:
if self.unique_name is None or self._disconnected or self._user_disconnect:
return False
return True
def export(self, path: str, interface: ServiceInterface) -> None:
"""Export the service interface on this message bus to make it available
to other clients.
:param path: The object path to export this interface on.
:type path: str
:param interface: The service interface to export.
:type interface: :class:`ServiceInterface
`
:raises:
- :class:`InvalidObjectPathError ` - If the given object path is not valid.
- :class:`ValueError` - If an interface with this name is already exported on the message bus at this path
"""
assert_object_path_valid(path)
if not isinstance(interface, ServiceInterface):
raise TypeError("interface must be a ServiceInterface")
if path not in self._path_exports:
self._path_exports[path] = {}
elif interface.name in self._path_exports[path]:
raise ValueError(
f'An interface with this name is already exported on this bus at path "{path}": "{interface.name}"'
)
self._path_exports[path][interface.name] = interface
ServiceInterface._add_bus(interface, self, self._make_method_handler)
self._emit_interface_added(path, interface)
def unexport(
self, path: str, interface: ServiceInterface | str | None = None
) -> None:
"""Unexport the path or service interface to make it no longer
available to clients.
:param path: The object path to unexport.
:type path: str
:param interface: The interface instance or the name of the interface
to unexport. If ``None``, unexport every interface on the path.
:type interface: :class:`ServiceInterface
` or str or None
:raises:
- :class:`InvalidObjectPathError ` - If the given object path is not valid.
"""
assert_object_path_valid(path)
interface_name: str | None
if interface is None:
interface_name = None
elif type(interface) is str:
interface_name = interface
elif isinstance(interface, ServiceInterface):
interface_name = interface.name
else:
raise TypeError(
f"interface must be a ServiceInterface or interface name not {type(interface)}"
)
if (interfaces := self._path_exports.get(path)) is None:
return
removed_interface_names: list[str] = []
if interface_name is not None:
if (removed_interface := interfaces.pop(interface_name, None)) is None:
return
removed_interface_names.append(interface_name)
if not interfaces:
del self._path_exports[path]
ServiceInterface._remove_bus(removed_interface, self)
else:
del self._path_exports[path]
for removed_interface in interfaces.values():
removed_interface_names.append(removed_interface.name)
ServiceInterface._remove_bus(removed_interface, self)
self._emit_interface_removed(path, removed_interface_names)
def introspect(
self,
bus_name: str,
path: str,
callback: Callable[[intr.Node | None, Exception | None], None],
check_callback_type: bool = True,
validate_property_names: bool = True,
) -> None:
"""Get introspection data for the node at the given path from the given
bus name.
Calls the standard ``org.freedesktop.DBus.Introspectable.Introspect``
on the bus for the path.
:param bus_name: The name to introspect.
:type bus_name: str
:param path: The path to introspect.
:type path: str
:param callback: A callback that will be called with the introspection
data as a :class:`Node `.
:type callback: :class:`Callable`
:param check_callback_type: Whether to check callback type or not.
:type check_callback_type: bool
:param validate_property_names: Whether to validate property names or not.
:type validate_property_names: bool
:raises:
- :class:`InvalidObjectPathError ` - If the given object path is not valid.
- :class:`InvalidBusNameError ` - If the given bus name is not valid.
"""
if check_callback_type:
BaseMessageBus._check_callback_type(callback)
def reply_notify(reply: Message | None, err: Exception | None) -> None:
try:
BaseMessageBus._check_method_return(reply, err, "s")
result = intr.Node.parse(
reply.body[0], # type: ignore[union-attr]
validate_property_names=validate_property_names,
)
except Exception as e:
callback(None, e)
return
callback(result, None)
self._call(
Message(
destination=bus_name,
path=path,
interface="org.freedesktop.DBus.Introspectable",
member="Introspect",
),
reply_notify,
)
def _emit_interface_added(self, path: str, interface: ServiceInterface) -> None:
"""Emit the ``org.freedesktop.DBus.ObjectManager.InterfacesAdded`` signal.
This signal is intended to be used to alert clients when
a new interface has been added.
:param path: Path of exported object.
:type path: str
:param interface: Exported service interface.
:type interface: :class:`ServiceInterface
`
"""
if self._disconnected:
return
def get_properties_callback(
interface: ServiceInterface,
result: Any,
user_data: Any,
e: Exception | None,
) -> None:
if e is not None:
try:
raise e
except Exception:
_LOGGER.error(
"An exception ocurred when emitting ObjectManager.InterfacesAdded for %s. "
"Some properties will not be included in the signal.",
interface.name,
exc_info=True,
)
body = {interface.name: result}
self.send(
Message.new_signal(
path=path,
interface="org.freedesktop.DBus.ObjectManager",
member="InterfacesAdded",
signature="oa{sa{sv}}",
body=[path, body],
)
)
ServiceInterface._get_all_property_values(interface, get_properties_callback)
def _emit_interface_removed(self, path: str, removed_interfaces: list[str]) -> None:
"""Emit the ``org.freedesktop.DBus.ObjectManager.InterfacesRemoved` signal.
This signal is intended to be used to alert clients when
a interface has been removed.
:param path: Path of removed (unexported) object.
:type path: str
:param removed_interfaces: List of unexported service interfaces.
:type removed_interfaces: list[str]
"""
if self._disconnected:
return
self.send(
Message.new_signal(
path=path,
interface="org.freedesktop.DBus.ObjectManager",
member="InterfacesRemoved",
signature="oas",
body=[path, removed_interfaces],
)
)
def request_name(
self,
name: str,
flags: NameFlag = NameFlag.NONE,
callback: None
| (Callable[[RequestNameReply | None, Exception | None], None]) = None,
check_callback_type: bool = True,
) -> None:
"""Request that this message bus owns the given name.
:param name: The name to request.
:type name: str
:param flags: Name flags that affect the behavior of the name request.
:type flags: :class:`NameFlag `
:param callback: A callback that will be called with the reply of the
request as a :class:`RequestNameReply `.
:type callback: :class:`Callable`
:raises:
- :class:`InvalidBusNameError ` - If the given bus name is not valid.
"""
assert_bus_name_valid(name)
if callback is not None and check_callback_type:
BaseMessageBus._check_callback_type(callback)
if type(flags) is not NameFlag:
flags = NameFlag(flags)
message = Message(
destination="org.freedesktop.DBus",
path="/org/freedesktop/DBus",
interface="org.freedesktop.DBus",
member="RequestName",
signature="su",
body=[name, flags],
)
if callback is None:
self._call(message, None)
return
def reply_notify(reply: Message | None, err: Exception | None) -> None:
try:
BaseMessageBus._check_method_return(reply, err, "u")
result = RequestNameReply(reply.body[0]) # type: ignore[union-attr]
except Exception as e:
callback(None, e)
return
callback(result, None)
self._call(message, reply_notify)
def release_name(
self,
name: str,
callback: None
| (Callable[[ReleaseNameReply | None, Exception | None], None]) = None,
check_callback_type: bool = True,
) -> None:
"""Request that this message bus release the given name.
:param name: The name to release.
:type name: str
:param callback: A callback that will be called with the reply of the
release request as a :class:`ReleaseNameReply
`.
:type callback: :class:`Callable`
:raises:
- :class:`InvalidBusNameError ` - If the given bus name is not valid.
"""
assert_bus_name_valid(name)
if callback is not None and check_callback_type:
BaseMessageBus._check_callback_type(callback)
message = Message(
destination="org.freedesktop.DBus",
path="/org/freedesktop/DBus",
interface="org.freedesktop.DBus",
member="ReleaseName",
signature="s",
body=[name],
)
if callback is None:
self._call(message, None)
return
def reply_notify(reply: Message | None, err: Exception | None) -> None:
try:
BaseMessageBus._check_method_return(reply, err, "u")
result = ReleaseNameReply(reply.body[0]) # type: ignore[union-attr]
except Exception as e:
callback(None, e)
return
callback(result, None)
self._call(message, reply_notify)
def get_proxy_object(
self, bus_name: str, path: str, introspection: intr.Node | str | ET.Element
) -> BaseProxyObject:
"""Get a proxy object for the path exported on the bus that owns the
name. The object is expected to export the interfaces and nodes
specified in the introspection data.
This is the entry point into the high-level client.
:param bus_name: The name on the bus to get the proxy object for.
:type bus_name: str
:param path: The path on the client for the proxy object.
:type path: str
:param introspection: XML introspection data used to build the
interfaces on the proxy object.
:type introspection: :class:`Node ` or str or :class:`ElementTree`
:returns: A proxy object for the given path on the given name.
:rtype: :class:`BaseProxyObject `
:raises:
- :class:`InvalidBusNameError ` - If the given bus name is not valid.
- :class:`InvalidObjectPathError ` - If the given object path is not valid.
- :class:`InvalidIntrospectionError ` - If the introspection data for the node is not valid.
"""
if self._ProxyObject is None:
raise Exception(
"the message bus implementation did not provide a proxy object class"
)
self._init_high_level_client()
return self._ProxyObject(bus_name, path, introspection, self)
def disconnect(self) -> None:
"""Disconnect the message bus by closing the underlying connection asynchronously.
All pending and future calls will error with a connection error.
"""
self._user_disconnect = True
if self._sock:
try:
self._sock.shutdown(socket.SHUT_RDWR)
except Exception:
_LOGGER.warning("could not shut down socket", exc_info=True)
def next_serial(self) -> int:
"""Get the next serial for this bus. This can be used as the ``serial``
attribute of a :class:`Message ` to manually handle
the serial of messages.
:returns: The next serial for the bus.
:rtype: int
"""
self._serial += 1
return self._serial
def add_message_handler(
self, handler: Callable[[Message], Message | bool | None]
) -> None:
"""Add a custom message handler for incoming messages.
The handler should be a callable that takes a :class:`Message
`. If the message is a method call, you may return
another Message as a reply and it will be marked as handled. You may
also return ``True`` to mark the message as handled without sending a
reply.
:param handler: A handler that will be run for every message the bus
connection received.
:type handler: :class:`Callable` or None
"""
error_text = "a message handler must be callable with a single parameter"
if not callable(handler):
raise TypeError(error_text)
handler_signature = inspect.signature(handler)
if len(handler_signature.parameters) != 1:
raise TypeError(error_text)
self._user_message_handlers.append(handler)
def remove_message_handler(
self, handler: Callable[[Message], Message | bool | None]
) -> None:
"""Remove a message handler that was previously added by
:func:`add_message_handler()
`.
:param handler: A message handler.
:type handler: :class:`Callable`
"""
for i, h in enumerate(self._user_message_handlers):
if h == handler:
del self._user_message_handlers[i]
return
def send(self, msg: Message) -> None:
"""Asynchronously send a message on the message bus.
:param msg: The message to send.
:type msg: :class:`Message `
"""
raise NotImplementedError(
'the "send" method must be implemented in the inheriting class'
)
def _finalize(self, err: Exception | None) -> None:
"""should be called after the socket disconnects with the disconnection
error to clean up resources and put the bus in a disconnected state"""
if self._disconnected:
return
self._disconnected = True
for handler in self._method_return_handlers.values():
try:
handler(None, err)
except Exception:
_LOGGER.warning(
"a message handler threw an exception on shutdown", exc_info=True
)
self._method_return_handlers.clear()
for path in list(self._path_exports):
self.unexport(path)
self._user_message_handlers.clear()
def _interface_signal_notify(
self,
interface: ServiceInterface,
interface_name: str,
member: str,
signature: str,
body: list[Any],
unix_fds: list[int] = [],
) -> None:
path: str | None = None
for p, ifaces in self._path_exports.items():
for i in ifaces.values():
if i is interface:
path = p
if path is None:
raise Exception(
"Could not find interface on bus (this is a bug in dbus-fast)"
)
self.send(
Message.new_signal(
path=path,
interface=interface_name,
member=member,
signature=signature,
body=body,
unix_fds=unix_fds,
)
)
def _introspect_export_path(self, path: str) -> intr.Node:
assert_object_path_valid(path)
if (interfaces := self._path_exports.get(path)) is not None:
node = intr.Node.default(path)
for interface in interfaces.values():
node.interfaces.append(interface.introspect())
else:
node = intr.Node(path)
children = set()
for export_path in self._path_exports:
if not export_path.startswith(path):
continue
child_path = export_path.split(path, maxsplit=1)[1]
if path != "/" and child_path and child_path[0] != "/":
continue
child_path = child_path.lstrip("/")
child_name = child_path.split("/", maxsplit=1)[0]
children.add(child_name)
node.nodes = [intr.Node(name) for name in children if name]
return node
def _setup_socket(self) -> None:
err = None
for transport, options in self._bus_address:
filename: bytes | str | None = None
ip_addr = ""
ip_port = 0
if transport == "unix":
self._sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
self._stream = self._sock.makefile("rwb")
self._fd = self._sock.fileno()
if "path" in options:
filename = options["path"]
elif "abstract" in options:
filename = b"\0" + options["abstract"].encode()
else:
raise InvalidAddressError(
"got unix transport with unknown path specifier"
)
try:
self._sock.connect(filename)
self._sock.setblocking(False)
break
except Exception as e:
err = e
elif transport == "tcp":
self._sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self._stream = self._sock.makefile("rwb")
self._fd = self._sock.fileno()
if "host" in options:
ip_addr = options["host"]
if "port" in options:
ip_port = int(options["port"])
try:
self._sock.connect((ip_addr, ip_port))
self._sock.setblocking(False)
break
except Exception as e:
err = e
else:
raise InvalidAddressError(f"got unknown address transport: {transport}")
if err:
raise err
def _reply_notify(
self,
msg: Message,
callback: Callable[[Message | None, Exception | None], None],
reply: Message | None,
err: Exception | None,
) -> None:
"""Callback on reply."""
if reply and msg.destination and reply.sender:
self._name_owners[msg.destination] = reply.sender
callback(reply, err)
def _call(
self,
msg: Message,
callback: Callable[[Message | None, Exception | None], None] | None,
) -> None:
if not msg.serial:
msg.serial = self.next_serial()
# Make sure the return reply handler is installed
# before sending the message to avoid a race condition
# where the reply is lost in case the backend can
# send it right away.
if (reply_expected := _expects_reply(msg)) and callback is not None:
self._method_return_handlers[msg.serial] = partial(
self._reply_notify, msg, callback
)
self.send(msg)
if not reply_expected and callback is not None:
callback(None, None)
@staticmethod
def _check_callback_type(callback: Callable) -> None:
"""Raise a TypeError if the user gives an invalid callback as a parameter"""
text = "a callback must be callable with two parameters"
if not callable(callback):
raise TypeError(text)
fn_signature = inspect.signature(callback)
if len(fn_signature.parameters) != 2:
raise TypeError(text)
@staticmethod
def _check_method_return(
msg: Message | None, err: Exception | None, signature: str
) -> None:
if err:
raise err
if msg is None:
raise DBusError(
ErrorType.INTERNAL_ERROR, "invalid message type for method call", msg
)
if msg.message_type == MessageType.METHOD_RETURN and msg.signature == signature:
return
if msg.message_type == MessageType.ERROR:
raise DBusError._from_message(msg)
raise DBusError(
ErrorType.INTERNAL_ERROR, "invalid message type for method call", msg
)
def _process_message(self, msg: _Message) -> None:
"""Process a message received from the message bus."""
handled = False
for user_handler in self._user_message_handlers:
try:
if result := user_handler(msg):
if type(result) is Message:
self.send(result)
handled = True
break
except DBusError as e:
if msg.message_type is MESSAGE_TYPE_CALL:
self.send(e._as_message(msg))
handled = True
break
_LOGGER.exception("A message handler raised an exception: %s", e)
except Exception as e:
_LOGGER.exception("A message handler raised an exception: %s", e)
if msg.message_type is MESSAGE_TYPE_CALL:
self.send(
Message.new_error(
msg,
ErrorType.INTERNAL_ERROR,
f"An internal error occurred: {e}.\n{traceback.format_exc()}",
)
)
handled = True
break
if msg.message_type is MESSAGE_TYPE_SIGNAL:
if (
msg.member == "NameOwnerChanged"
and msg.sender == "org.freedesktop.DBus"
and msg.path == "/org/freedesktop/DBus"
and msg.interface == "org.freedesktop.DBus"
):
name = msg.body[0]
if new_owner := msg.body[2]:
self._name_owners[name] = new_owner
elif name in self._name_owners:
del self._name_owners[name]
return
if msg.message_type is MESSAGE_TYPE_CALL:
if not handled:
handler = self._find_message_handler(msg)
if not _expects_reply(msg):
if handler:
handler(msg, BLOCK_UNEXPECTED_REPLY) # type: ignore[arg-type]
else:
_LOGGER.error(
'"%s.%s" with signature "%s" could not be found',
msg.interface,
msg.member,
msg.signature,
)
return
send_reply = SendReply(self, msg)
with send_reply:
if handler:
handler(msg, send_reply)
else:
send_reply(
Message.new_error(
msg,
ErrorType.UNKNOWN_METHOD,
f"{msg.interface}.{msg.member} with signature "
f'"{msg.signature}" could not be found',
)
)
return
# An ERROR or a METHOD_RETURN
return_handler = self._method_return_handlers.get(msg.reply_serial)
if return_handler is not None:
if not handled:
return_handler(msg, None)
del self._method_return_handlers[msg.reply_serial]
def _callback_method_handler(
self,
interface: ServiceInterface,
method: _Method,
msg: Message,
send_reply: SendReply,
) -> None:
"""This is the callback that will be called when a method call is."""
args = ServiceInterface._c_msg_body_to_args(msg) if msg.unix_fds else msg.body
result = method.fn(interface, *args)
if send_reply is BLOCK_UNEXPECTED_REPLY or _expects_reply(msg) is False:
return
body_fds = ServiceInterface._c_fn_result_to_body(
result,
method.out_signature_tree,
self._negotiate_unix_fd,
)
send_reply(
Message(
message_type=MessageType.METHOD_RETURN,
reply_serial=msg.serial,
destination=msg.sender,
signature=method.out_signature,
body=body_fds[0],
unix_fds=body_fds[1],
)
)
def _make_method_handler(
self, interface: ServiceInterface, method: _Method
) -> HandlerType:
return partial(self._callback_method_handler, interface, method)
def _find_message_handler(self, msg: _Message) -> HandlerType | None:
"""Find the message handler for for METHOD_CALL messages."""
if TYPE_CHECKING:
assert msg.member is not None
assert msg.path is not None
if msg.interface is not None and "org.freedesktop.DBus." in msg.interface:
if (
msg.interface == "org.freedesktop.DBus.Introspectable"
and msg.member == "Introspect"
and msg.signature == ""
):
return self._default_introspect_handler
if msg.interface == "org.freedesktop.DBus.Properties":
return self._default_properties_handler
if msg.interface == "org.freedesktop.DBus.Peer":
if msg.member == "Ping" and msg.signature == "":
return self._default_ping_handler
if msg.member == "GetMachineId" and msg.signature == "":
return self._default_get_machine_id_handler
if (
msg.interface == "org.freedesktop.DBus.ObjectManager"
and msg.member == "GetManagedObjects"
):
return self._default_get_managed_objects_handler
if (interfaces := self._path_exports.get(msg.path)) is None:
return None
if msg.interface is None:
return self._find_any_message_handler_matching_signature(interfaces, msg)
if (interface := interfaces.get(msg.interface)) is not None and (
handler := ServiceInterface._get_enabled_handler_by_name_signature(
interface, self, msg.member, msg.signature
)
) is not None:
return handler
return None
def _find_any_message_handler_matching_signature(
self, interfaces: dict[str, ServiceInterface], msg: _Message
) -> HandlerType | None:
# No interface, so we need to search all interfaces for the method
# with a matching signature
for interface in interfaces.values():
if (
handler := ServiceInterface._get_enabled_handler_by_name_signature(
interface, self, msg.member, msg.signature
)
) is not None:
return handler
return None
def _default_introspect_handler(self, msg: Message, send_reply: SendReply) -> None:
if TYPE_CHECKING:
assert msg.path is not None
introspection = self._introspect_export_path(msg.path).tostring()
send_reply(Message.new_method_return(msg, "s", [introspection]))
def _default_ping_handler(self, msg: Message, send_reply: SendReply) -> None:
send_reply(Message.new_method_return(msg))
def _send_machine_id_reply(self, msg: Message, send_reply: SendReply) -> None:
send_reply(Message.new_method_return(msg, "s", [self._machine_id]))
def _default_get_machine_id_handler(
self, msg: Message, send_reply: SendReply
) -> None:
if self._machine_id:
self._send_machine_id_reply(msg, send_reply)
return
def reply_handler(reply: Message | None, err: Exception | None) -> None:
if err or reply is None:
# the bus has been disconnected, cannot send a reply
return
if reply.message_type == MessageType.METHOD_RETURN:
self._machine_id = reply.body[0]
self._send_machine_id_reply(msg, send_reply)
elif (
reply.message_type == MessageType.ERROR and reply.error_name is not None
):
send_reply(Message.new_error(msg, reply.error_name, str(reply.body)))
else:
send_reply(
Message.new_error(msg, ErrorType.FAILED, "could not get machine_id")
)
self._call(
Message(
destination="org.freedesktop.DBus",
path="/org/freedesktop/DBus",
interface="org.freedesktop.DBus.Peer",
member="GetMachineId",
),
reply_handler,
)
def _default_get_managed_objects_handler(
self, msg: Message, send_reply: SendReply
) -> None:
result_signature = "a{oa{sa{sv}}}"
error_handled = False
def is_result_complete() -> bool:
if not result:
return True
for n, interfaces in result.items():
for value in interfaces.values():
if value is None:
return False
return True
if TYPE_CHECKING:
assert msg.path is not None
nodes = [
node
for node in self._path_exports
if msg.path == "/" or node.startswith(msg.path + "/")
]
# first build up the result object to know when it's complete
result: dict[str, dict[str, Any]] = {
node: dict.fromkeys(self._path_exports[node]) for node in nodes
}
if is_result_complete():
send_reply(Message.new_method_return(msg, result_signature, [result]))
return
def get_all_properties_callback(
interface: ServiceInterface, values: Any, node: str, err: Exception | None
) -> None:
nonlocal error_handled
if err is not None:
if not error_handled:
error_handled = True
send_reply.send_error(err)
return
result[node][interface.name] = values
if is_result_complete():
send_reply(Message.new_method_return(msg, result_signature, [result]))
for node in nodes:
for interface in self._path_exports[node].values():
ServiceInterface._get_all_property_values(
interface, get_all_properties_callback, node
)
def _default_properties_handler(self, msg: Message, send_reply: SendReply) -> None:
methods = {"Get": "ss", "Set": "ssv", "GetAll": "s"}
if msg.member not in methods or methods[msg.member] != msg.signature:
raise DBusError(
ErrorType.UNKNOWN_METHOD,
f'properties interface doesn\'t have method "{msg.member}" with signature "{msg.signature}"',
)
interface_name = msg.body[0]
if interface_name == "":
raise DBusError(
ErrorType.NOT_SUPPORTED,
"getting and setting properties with an empty interface string is not supported yet",
)
if msg.path not in self._path_exports:
raise DBusError(
ErrorType.UNKNOWN_OBJECT, f'no interfaces at path: "{msg.path}"'
)
if (interface := self._path_exports[msg.path].get(interface_name)) is None:
if interface_name in [
"org.freedesktop.DBus.Properties",
"org.freedesktop.DBus.Introspectable",
"org.freedesktop.DBus.Peer",
"org.freedesktop.DBus.ObjectManager",
]:
# the standard interfaces do not have properties
if msg.member == "Get" or msg.member == "Set":
prop_name = msg.body[1]
raise DBusError(
ErrorType.UNKNOWN_PROPERTY,
f'interface "{interface_name}" does not have property "{prop_name}"',
)
if msg.member == "GetAll":
send_reply(Message.new_method_return(msg, "a{sv}", [{}]))
return
assert False
raise DBusError(
ErrorType.UNKNOWN_INTERFACE,
f'could not find an interface "{interface_name}" at path: "{msg.path}"',
)
properties = ServiceInterface._get_properties(interface)
if msg.member == "Get" or msg.member == "Set":
prop_name = msg.body[1]
match = [
prop
for prop in properties
if prop.name == prop_name and not prop.disabled
]
if not match:
raise DBusError(
ErrorType.UNKNOWN_PROPERTY,
f'interface "{interface_name}" does not have property "{prop_name}"',
)
prop = match[0]
if msg.member == "Get":
if not prop.access.readable():
raise DBusError(
ErrorType.UNKNOWN_PROPERTY,
"the property does not have read access",
)
def get_property_callback(
interface: ServiceInterface,
prop: _Property,
prop_value: Any,
err: Exception | None,
) -> None:
try:
if err is not None:
send_reply.send_error(err)
return
body, unix_fds = replace_fds_with_idx(
prop.signature, [prop_value]
)
send_reply(
Message.new_method_return(
msg,
"v",
[Variant(prop.signature, body[0])],
unix_fds=unix_fds,
)
)
except Exception as e:
send_reply.send_error(e)
ServiceInterface._get_property_value(
interface, prop, get_property_callback
)
elif msg.member == "Set":
if not prop.access.writable():
raise DBusError(
ErrorType.PROPERTY_READ_ONLY, "the property is readonly"
)
value = msg.body[2]
if value.signature != prop.signature:
raise DBusError(
ErrorType.INVALID_SIGNATURE,
f'wrong signature for property. expected "{prop.signature}"',
)
assert prop.prop_setter
def set_property_callback(
interface: ServiceInterface, prop: _Property, err: Exception | None
) -> None:
if err is not None:
send_reply.send_error(err)
return
send_reply(Message.new_method_return(msg))
body = replace_idx_with_fds(
value.signature, [value.value], msg.unix_fds
)
ServiceInterface._set_property_value(
interface, prop, body[0], set_property_callback
)
elif msg.member == "GetAll":
def get_all_properties_callback(
interface: ServiceInterface,
values: Any,
user_data: Any,
err: Exception | None,
) -> None:
if err is not None:
send_reply.send_error(err)
return
body, unix_fds = replace_fds_with_idx("a{sv}", [values])
send_reply(
Message.new_method_return(msg, "a{sv}", body, unix_fds=unix_fds)
)
ServiceInterface._get_all_property_values(
interface, get_all_properties_callback
)
else:
assert False
def _init_high_level_client(self) -> None:
"""The high level client is initialized when the first proxy object is
gotten. Currently just sets up the match rules for the name owner cache
so signals can be routed to the right objects."""
if self._high_level_client_initialized:
return
self._high_level_client_initialized = True
def add_match_notify(msg: Message | None, err: Exception | None) -> None:
if err:
_LOGGER.error(
f'add match request failed. match="{self._name_owner_match_rule}", {err}'
)
elif msg is not None and msg.message_type == MessageType.ERROR:
_LOGGER.error(
f'add match request failed. match="{self._name_owner_match_rule}", {msg.body[0]}'
)
self._call(
Message(
destination="org.freedesktop.DBus",
interface="org.freedesktop.DBus",
path="/org/freedesktop/DBus",
member="AddMatch",
signature="s",
body=[self._name_owner_match_rule],
),
add_match_notify,
)
def _add_match_rule(self, match_rule: str) -> None:
"""Add a match rule. Match rules added by this function are refcounted
and must be removed by _remove_match_rule(). This is for use in the
high level client only."""
if match_rule == self._name_owner_match_rule:
return
if match_rule in self._match_rules:
self._match_rules[match_rule] += 1
return
self._match_rules[match_rule] = 1
def add_match_notify(msg: Message | None, err: Exception | None) -> None:
if err:
_LOGGER.error(f'add match request failed. match="{match_rule}", {err}')
elif msg is not None and msg.message_type == MessageType.ERROR:
_LOGGER.error(
f'add match request failed. match="{match_rule}", {msg.body[0]}'
)
self._call(
Message(
destination="org.freedesktop.DBus",
interface="org.freedesktop.DBus",
path="/org/freedesktop/DBus",
member="AddMatch",
signature="s",
body=[match_rule],
),
add_match_notify,
)
def _remove_match_rule(self, match_rule: str) -> None:
"""Remove a match rule added with _add_match_rule(). This is for use in
the high level client only."""
if match_rule == self._name_owner_match_rule:
return
if match_rule in self._match_rules:
self._match_rules[match_rule] -= 1
if self._match_rules[match_rule] > 0:
return
del self._match_rules[match_rule]
def remove_match_notify(msg: Message | None, err: Exception | None) -> None:
if self._disconnected:
return
if err:
_LOGGER.error(
f'remove match request failed. match="{match_rule}", {err}'
)
elif msg is not None and msg.message_type == MessageType.ERROR:
_LOGGER.error(
f'remove match request failed. match="{match_rule}", {msg.body[0]}'
)
self._call(
Message(
destination="org.freedesktop.DBus",
interface="org.freedesktop.DBus",
path="/org/freedesktop/DBus",
member="RemoveMatch",
signature="s",
body=[match_rule],
),
remove_match_notify,
)
dbus-fast-2.44.1/src/dbus_fast/proxy_object.py 0000664 0000000 0000000 00000034452 14773556132 0021341 0 ustar 00root root 0000000 0000000 from __future__ import annotations
import asyncio
import inspect
import logging
import re
import xml.etree.ElementTree as ET
from collections.abc import Coroutine
from dataclasses import dataclass
from functools import lru_cache
from typing import Callable
from . import introspection as intr
from . import message_bus
from ._private.util import replace_idx_with_fds
from .constants import ErrorType, MessageType
from .errors import DBusError, InterfaceNotFoundError
from .message import Message
from .unpack import unpack_variants as unpack
from .validators import assert_bus_name_valid, assert_object_path_valid
_LOGGER = logging.getLogger(__name__)
@dataclass
class SignalHandler:
"""Signal handler."""
fn: Callable | Coroutine
unpack_variants: bool
class BaseProxyInterface:
"""An abstract class representing a proxy to an interface exported on the bus by another client.
Implementations of this class are not meant to be constructed directly by
users. Use :func:`BaseProxyObject.get_interface` to get a proxy interface.
Each message bus implementation provides its own proxy interface
implementation that will be returned by that method.
Proxy interfaces can be used to call methods, get properties, and listen to
signals on the interface. Proxy interfaces are created dynamically with a
family of methods for each of these operations based on what members the
interface exposes. Each proxy interface implementation exposes these
members in a different way depending on the features of the backend. See
the documentation of the proxy interface implementation you use for more
details.
:ivar bus_name: The name of the bus this interface is exported on.
:vartype bus_name: str
:ivar path: The object path exported on the client that owns the bus name.
:vartype path: str
:ivar introspection: Parsed introspection data for the proxy interface.
:vartype introspection: :class:`Node `
:ivar bus: The message bus this proxy interface is connected to.
:vartype bus: :class:`BaseMessageBus `
"""
def __init__(
self,
bus_name: str,
path: str,
introspection: intr.Interface,
bus: message_bus.BaseMessageBus,
) -> None:
self.bus_name = bus_name
self.path = path
self.introspection = introspection
self.bus = bus
self._signal_handlers: dict[str, list[SignalHandler]] = {}
self._signal_match_rule = f"type='signal',sender={bus_name},interface={introspection.name},path={path}"
self._background_tasks: set[asyncio.Task] = set()
_underscorer1 = re.compile(r"(.)([A-Z][a-z]+)")
_underscorer2 = re.compile(r"([a-z0-9])([A-Z])")
@staticmethod
@lru_cache(maxsize=128)
def _to_snake_case(member: str) -> str:
subbed = BaseProxyInterface._underscorer1.sub(r"\1_\2", member)
return BaseProxyInterface._underscorer2.sub(r"\1_\2", subbed).lower()
@staticmethod
def _check_method_return(msg: Message, signature: str | None = None):
if msg.message_type == MessageType.ERROR:
raise DBusError._from_message(msg)
if msg.message_type != MessageType.METHOD_RETURN:
raise DBusError(
ErrorType.CLIENT_ERROR, "method call didnt return a method return", msg
)
if signature is not None and msg.signature != signature:
raise DBusError(
ErrorType.CLIENT_ERROR,
f'method call returned unexpected signature: "{msg.signature}"',
msg,
)
def _add_method(self, intr_method: intr.Method) -> None:
raise NotImplementedError("this must be implemented in the inheriting class")
def _add_property(self, intr_property: intr.Property) -> None:
raise NotImplementedError("this must be implemented in the inheriting class")
def _message_handler(self, msg: Message) -> None:
if (
msg.message_type != MessageType.SIGNAL
or msg.interface != self.introspection.name
or msg.path != self.path
or msg.member not in self._signal_handlers
):
return
if (
msg.sender != self.bus_name
and self.bus._name_owners.get(self.bus_name, "") != msg.sender
):
# The sender is always a unique name, but the bus name given might
# be a well known name. If the sender isn't an exact match, check
# to see if it owns the bus_name we were given from the cache kept
# on the bus for this purpose.
return
match = [s for s in self.introspection.signals if s.name == msg.member]
if not match:
return
intr_signal = match[0]
if intr_signal.signature != msg.signature:
_LOGGER.warning(
f'got signal "{self.introspection.name}.{msg.member}" with unexpected signature "{msg.signature}"'
)
return
body = replace_idx_with_fds(msg.signature, msg.body, msg.unix_fds)
no_sig = None
for handler in self._signal_handlers[msg.member]:
if handler.unpack_variants:
if not no_sig:
no_sig = unpack(body)
data = no_sig
else:
data = body
cb_result = handler.fn(*data)
if isinstance(cb_result, Coroutine):
# Save a strong reference to the task so it doesn't get garbage
# collected before it finishes.
task = asyncio.create_task(cb_result)
self._background_tasks.add(task)
task.add_done_callback(self._background_tasks.remove)
def _add_signal(self, intr_signal: intr.Signal, interface: intr.Interface) -> None:
def on_signal_fn(fn: Callable | Coroutine, *, unpack_variants: bool = False):
fn_signature = inspect.signature(fn)
if (
len(
[
par
for par in fn_signature.parameters.values()
if par.kind == inspect.Parameter.KEYWORD_ONLY
and par.default == inspect.Parameter.empty
]
)
> 0
):
raise TypeError(
"reply_notify cannot have required keyword only parameters"
)
positional_params = [
par.kind
for par in fn_signature.parameters.values()
if par.kind
not in [inspect.Parameter.KEYWORD_ONLY, inspect.Parameter.VAR_KEYWORD]
]
if len(positional_params) != len(intr_signal.args) and (
inspect.Parameter.VAR_POSITIONAL not in positional_params
or len(positional_params) - 1 > len(intr_signal.args)
):
raise TypeError(
f"reply_notify must be a function with {len(intr_signal.args)} positional parameters"
)
if not self._signal_handlers:
self.bus._add_match_rule(self._signal_match_rule)
self.bus.add_message_handler(self._message_handler)
if intr_signal.name not in self._signal_handlers:
self._signal_handlers[intr_signal.name] = []
self._signal_handlers[intr_signal.name].append(
SignalHandler(fn, unpack_variants)
)
def off_signal_fn(
fn: Callable | Coroutine, *, unpack_variants: bool = False
) -> None:
try:
i = self._signal_handlers[intr_signal.name].index(
SignalHandler(fn, unpack_variants)
)
del self._signal_handlers[intr_signal.name][i]
if not self._signal_handlers[intr_signal.name]:
del self._signal_handlers[intr_signal.name]
except (KeyError, ValueError):
return
if not self._signal_handlers:
self.bus._remove_match_rule(self._signal_match_rule)
self.bus.remove_message_handler(self._message_handler)
snake_case = BaseProxyInterface._to_snake_case(intr_signal.name)
setattr(interface, f"on_{snake_case}", on_signal_fn)
setattr(interface, f"off_{snake_case}", off_signal_fn)
class BaseProxyObject:
"""An abstract class representing a proxy to an object exported on the bus by another client.
Implementations of this class are not meant to be constructed directly. Use
:func:`BaseMessageBus.get_proxy_object()
` to get a proxy
object. Each message bus implementation provides its own proxy object
implementation that will be returned by that method.
The primary use of the proxy object is to select a proxy interface to act
on. Information on what interfaces are available is provided by
introspection data provided to this class. This introspection data can
either be included in your project as an XML file (recommended) or
retrieved from the ``org.freedesktop.DBus.Introspectable`` interface at
runtime.
:ivar bus_name: The name of the bus this object is exported on.
:vartype bus_name: str
:ivar path: The object path exported on the client that owns the bus name.
:vartype path: str
:ivar introspection: Parsed introspection data for the proxy object.
:vartype introspection: :class:`Node `
:ivar bus: The message bus this proxy object is connected to.
:vartype bus: :class:`BaseMessageBus `
:ivar ~.ProxyInterface: The proxy interface class this proxy object uses.
:vartype ~.ProxyInterface: Type[:class:`BaseProxyInterface `]
:ivar child_paths: A list of absolute object paths of the children of this object.
:vartype child_paths: list(str)
:raises:
- :class:`InvalidBusNameError ` - If the given bus name is not valid.
- :class:`InvalidObjectPathError ` - If the given object path is not valid.
- :class:`InvalidIntrospectionError ` - If the introspection data for the node is not valid.
"""
def __init__(
self,
bus_name: str,
path: str,
introspection: intr.Node | str | ET.Element,
bus: message_bus.BaseMessageBus,
ProxyInterface: type[BaseProxyInterface],
) -> None:
assert_object_path_valid(path)
assert_bus_name_valid(bus_name)
if not isinstance(bus, message_bus.BaseMessageBus):
raise TypeError("bus must be an instance of BaseMessageBus")
if not issubclass(ProxyInterface, BaseProxyInterface):
raise TypeError("ProxyInterface must be an instance of BaseProxyInterface")
if type(introspection) is intr.Node:
self.introspection = introspection
elif type(introspection) is str:
self.introspection = intr.Node.parse(introspection)
elif type(introspection) is ET.Element:
self.introspection = intr.Node.from_xml(introspection)
else:
raise TypeError(
"introspection must be xml node introspection or introspection.Node class"
)
self.bus_name = bus_name
self.path = path
self.bus = bus
self.ProxyInterface = ProxyInterface
self.child_paths = [f"{path}/{n.name}" for n in self.introspection.nodes]
self._interfaces = {}
# lazy loaded by get_children()
self._children = None
def get_interface(self, name: str) -> BaseProxyInterface:
"""Get an interface exported on this proxy object and connect it to the bus.
:param name: The name of the interface to retrieve.
:type name: str
:raises:
- :class:`InterfaceNotFoundError ` - If there is no interface by this name exported on the bus.
"""
if name in self._interfaces:
return self._interfaces[name]
try:
intr_interface = next(
i for i in self.introspection.interfaces if i.name == name
)
except StopIteration as ex:
raise InterfaceNotFoundError(
f"interface not found on this object: {name}"
) from ex
interface = self.ProxyInterface(
self.bus_name, self.path, intr_interface, self.bus
)
for intr_method in intr_interface.methods:
interface._add_method(intr_method)
for intr_property in intr_interface.properties:
interface._add_property(intr_property)
for intr_signal in intr_interface.signals:
interface._add_signal(intr_signal, interface)
def get_owner_notify(msg: Message, err: Exception | None) -> None:
if err:
_LOGGER.error(f'getting name owner for "{name}" failed, {err}')
return
if msg.message_type == MessageType.ERROR:
if msg.error_name != ErrorType.NAME_HAS_NO_OWNER.value:
_LOGGER.error(
f'getting name owner for "{name}" failed, {msg.body[0]}'
)
return
self.bus._name_owners[self.bus_name] = msg.body[0]
if self.bus_name[0] != ":" and not self.bus._name_owners.get(self.bus_name, ""):
self.bus._call(
Message(
destination="org.freedesktop.DBus",
interface="org.freedesktop.DBus",
path="/org/freedesktop/DBus",
member="GetNameOwner",
signature="s",
body=[self.bus_name],
),
get_owner_notify,
)
self._interfaces[name] = interface
return interface
def get_children(self) -> list[BaseProxyObject]:
"""Get the child nodes of this proxy object according to the introspection data."""
if self._children is None:
self._children = [
self.__class__(self.bus_name, self.path, child, self.bus)
for child in self.introspection.nodes
]
return self._children
dbus-fast-2.44.1/src/dbus_fast/py.typed 0000664 0000000 0000000 00000000000 14773556132 0017735 0 ustar 00root root 0000000 0000000 dbus-fast-2.44.1/src/dbus_fast/send_reply.py 0000664 0000000 0000000 00000003162 14773556132 0020770 0 ustar 00root root 0000000 0000000 from __future__ import annotations
import traceback
from types import TracebackType
from typing import TYPE_CHECKING
from .constants import ErrorType
from .errors import DBusError
from .message import Message
if TYPE_CHECKING:
from .message_bus import BaseMessageBus
class SendReply:
"""A context manager to send a reply to a message."""
__slots__ = ("_bus", "_msg")
def __init__(self, bus: BaseMessageBus, msg: Message) -> None:
"""Create a new reply context manager."""
self._bus = bus
self._msg = msg
def __enter__(self) -> SendReply:
return self
def __call__(self, reply: Message) -> None:
self._bus.send(reply)
def _exit(
self,
exc_type: type[Exception] | None,
exc_value: Exception | None,
tb: TracebackType | None,
) -> bool:
if exc_value:
if isinstance(exc_value, DBusError):
self(exc_value._as_message(self._msg))
else:
self(
Message.new_error(
self._msg,
ErrorType.SERVICE_ERROR,
f"The service interface raised an error: {exc_value}.\n{traceback.format_tb(tb)}",
)
)
return True
return False
def __exit__(
self,
exc_type: type[Exception] | None,
exc_value: Exception | None,
tb: TracebackType | None,
) -> bool:
return self._exit(exc_type, exc_value, tb)
def send_error(self, exc: Exception) -> None:
self._exit(exc.__class__, exc, exc.__traceback__)
dbus-fast-2.44.1/src/dbus_fast/service.pxd 0000664 0000000 0000000 00000002241 14773556132 0020424 0 ustar 00root root 0000000 0000000 """cdefs for service.py"""
import cython
from .message cimport Message
from .signature cimport SignatureTree
cdef class _Method:
cdef public str name
cdef public object fn
cdef public bint disabled
cdef public object introspection
cdef public str in_signature
cdef public str out_signature
cdef public SignatureTree in_signature_tree
cdef public SignatureTree out_signature_tree
cdef tuple _real_fn_result_to_body(
object result,
SignatureTree signature_tree,
bint replace_fds
)
cdef class ServiceInterface:
cdef public str name
cdef list __methods
cdef list __properties
cdef list __signals
cdef set __buses
cdef dict __handlers
cdef dict __enabled_handlers_by_name_signature
@cython.locals(handlers=dict,in_signature=str,method=_Method)
@staticmethod
cdef object _get_enabled_handler_by_name_signature(ServiceInterface interface, object bus, object name, object signature)
@staticmethod
cdef list _c_msg_body_to_args(Message msg)
@staticmethod
cdef tuple _c_fn_result_to_body(
object result,
SignatureTree signature_tree,
bint replace_fds,
)
dbus-fast-2.44.1/src/dbus_fast/service.py 0000664 0000000 0000000 00000057604 14773556132 0020276 0 ustar 00root root 0000000 0000000 from __future__ import annotations
import asyncio
import copy
import inspect
from functools import wraps
from typing import TYPE_CHECKING, Any, Callable, Protocol
from . import introspection as intr
from ._private.util import (
parse_annotation,
replace_fds_with_idx,
replace_idx_with_fds,
signature_contains_type,
)
from .constants import PropertyAccess
from .errors import SignalDisabledError
from .message import Message
from .send_reply import SendReply
from .signature import (
SignatureBodyMismatchError,
SignatureTree,
Variant,
get_signature_tree,
)
if TYPE_CHECKING:
from .message_bus import BaseMessageBus
str_ = str
HandlerType = Callable[[Message, SendReply], None]
class _MethodCallbackProtocol(Protocol):
def __call__(self, interface: ServiceInterface, *args: Any) -> Any: ...
class _Method:
def __init__(
self, fn: _MethodCallbackProtocol, name: str, disabled: bool = False
) -> None:
in_signature = ""
out_signature = ""
inspection = inspect.signature(fn)
in_args: list[intr.Arg] = []
for i, param in enumerate(inspection.parameters.values()):
if i == 0:
# first is self
continue
annotation = parse_annotation(param.annotation)
if not annotation:
raise ValueError(
"method parameters must specify the dbus type string as an annotation"
)
in_args.append(intr.Arg(annotation, intr.ArgDirection.IN, param.name))
in_signature += annotation
out_args: list[intr.Arg] = []
out_signature = parse_annotation(inspection.return_annotation)
if out_signature:
for type_ in get_signature_tree(out_signature).types:
out_args.append(intr.Arg(type_, intr.ArgDirection.OUT))
self.name = name
self.fn = fn
self.disabled = disabled
self.introspection = intr.Method(name, in_args, out_args)
self.in_signature = in_signature
self.out_signature = out_signature
self.in_signature_tree = get_signature_tree(in_signature)
self.out_signature_tree = get_signature_tree(out_signature)
def method(name: str | None = None, disabled: bool = False) -> Callable:
"""A decorator to mark a class method of a :class:`ServiceInterface` to be a DBus service method.
The parameters and return value must each be annotated with a signature
string of a single complete DBus type.
This class method will be called when a client calls the method on the DBus
interface. The parameters given to the function come from the calling
client and will conform to the dbus-fast type system. The parameters
returned will be returned to the calling client and must conform to the
dbus-fast type system. If multiple parameters are returned, they must be
contained within a :class:`list`.
The decorated method may raise a :class:`DBusError `
to return an error to the client.
:param name: The member name that DBus clients will use to call this method. Defaults to the name of the class method.
:type name: str
:param disabled: If set to true, the method will not be visible to clients.
:type disabled: bool
:example:
::
@method()
def echo(self, val: 's') -> 's':
return val
@method()
def echo_two(self, val1: 's', val2: 'u') -> 'su':
return [val1, val2]
"""
if name is not None and type(name) is not str:
raise TypeError("name must be a string")
if type(disabled) is not bool:
raise TypeError("disabled must be a bool")
def decorator(fn: Callable) -> Callable:
@wraps(fn)
def wrapped(*args: Any, **kwargs: Any) -> None:
fn(*args, **kwargs)
fn_name = name if name else fn.__name__
wrapped.__dict__["__DBUS_METHOD"] = _Method(fn, fn_name, disabled=disabled)
return wrapped
return decorator
class _Signal:
def __init__(self, fn: Callable, name: str, disabled: bool = False) -> None:
inspection = inspect.signature(fn)
args = []
signature = ""
signature_tree = None
return_annotation = parse_annotation(inspection.return_annotation)
if return_annotation:
signature = return_annotation
signature_tree = get_signature_tree(signature)
for type_ in signature_tree.types:
args.append(intr.Arg(type_, intr.ArgDirection.OUT))
else:
signature = ""
signature_tree = get_signature_tree("")
self.signature = signature
self.signature_tree = signature_tree
self.name = name
self.disabled = disabled
self.introspection = intr.Signal(self.name, args)
def signal(name: str | None = None, disabled: bool = False) -> Callable:
"""A decorator to mark a class method of a :class:`ServiceInterface` to be a DBus signal.
The signal is broadcast on the bus when the decorated class method is
called by the user.
If the signal has an out argument, the class method must have a return type
annotation with a signature string of a single complete DBus type and the
return value of the class method must conform to the dbus-fast type system.
If the signal has multiple out arguments, they must be returned within a
``list``.
:param name: The member name that will be used for this signal. Defaults to
the name of the class method.
:type name: str
:param disabled: If set to true, the signal will not be visible to clients.
:type disabled: bool
:example:
::
@signal()
def string_signal(self, val) -> 's':
return val
@signal()
def two_strings_signal(self, val1, val2) -> 'ss':
return [val1, val2]
"""
if name is not None and type(name) is not str:
raise TypeError("name must be a string")
if type(disabled) is not bool:
raise TypeError("disabled must be a bool")
def decorator(fn: Callable) -> Callable:
fn_name = name if name else fn.__name__
signal = _Signal(fn, fn_name, disabled)
@wraps(fn)
def wrapped(self, *args: Any, **kwargs: Any) -> Any:
if signal.disabled:
raise SignalDisabledError("Tried to call a disabled signal")
result = fn(self, *args, **kwargs)
ServiceInterface._handle_signal(self, signal, result)
return result
wrapped.__dict__["__DBUS_SIGNAL"] = signal
return wrapped
return decorator
class _Property(property):
def set_options(self, options: dict[str, Any]) -> None:
self.options = getattr(self, "options", {})
for k, v in options.items():
self.options[k] = v
if "name" in options and options["name"] is not None:
self.name = options["name"]
else:
self.name = self.prop_getter.__name__
if "access" in options:
self.access = PropertyAccess(options["access"])
else:
self.access = PropertyAccess.READWRITE
self.disabled = options.get("disabled", False)
self.introspection = intr.Property(self.name, self.signature, self.access)
self.__dict__["__DBUS_PROPERTY"] = True
def __init__(self, fn, *args, **kwargs):
self.prop_getter = fn
self.prop_setter = None
inspection = inspect.signature(fn)
if len(inspection.parameters) != 1:
raise ValueError('the property must only have the "self" input parameter')
return_annotation = parse_annotation(inspection.return_annotation)
if not return_annotation:
raise ValueError(
"the property must specify the dbus type string as a return annotation string"
)
self.signature = return_annotation
tree = get_signature_tree(return_annotation)
if len(tree.types) != 1:
raise ValueError("the property signature must be a single complete type")
self.type = tree.types[0]
if "options" in kwargs:
options = kwargs["options"]
self.set_options(options)
del kwargs["options"]
super().__init__(fn, *args, **kwargs)
def setter(self, fn, **kwargs):
# XXX The setter decorator seems to be recreating the class in the list
# of class members and clobbering the options so we need to reset them.
# Why does it do that?
result = super().setter(fn, **kwargs)
result.prop_setter = fn
result.set_options(self.options)
return result
def dbus_property(
access: PropertyAccess = PropertyAccess.READWRITE,
name: str | None = None,
disabled: bool = False,
) -> Callable:
"""A decorator to mark a class method of a :class:`ServiceInterface` to be a DBus property.
The class method must be a Python getter method with a return annotation
that is a signature string of a single complete DBus type. When a client
gets the property through the ``org.freedesktop.DBus.Properties``
interface, the getter will be called and the resulting value will be
returned to the client.
If the property is writable, it must have a setter method that takes a
single parameter that is annotated with the same signature. When a client
sets the property through the ``org.freedesktop.DBus.Properties``
interface, the setter will be called with the value from the calling
client.
The parameters of the getter and the setter must conform to the dbus-fast
type system. The getter or the setter may raise a :class:`DBusError
` to return an error to the client.
:param name: The name that DBus clients will use to interact with this
property on the bus.
:type name: str
:param disabled: If set to true, the property will not be visible to
clients.
:type disabled: bool
:example:
::
@dbus_property()
def string_prop(self) -> 's':
return self._string_prop
@string_prop.setter
def string_prop(self, val: 's'):
self._string_prop = val
"""
if type(access) is not PropertyAccess:
raise TypeError("access must be a PropertyAccess class")
if name is not None and type(name) is not str:
raise TypeError("name must be a string")
if type(disabled) is not bool:
raise TypeError("disabled must be a bool")
def decorator(fn: Callable) -> _Property:
options = {"name": name, "access": access, "disabled": disabled}
return _Property(fn, options=options)
return decorator
def _real_fn_result_to_body(
result: Any | None,
signature_tree: SignatureTree,
replace_fds: bool,
) -> tuple[list[Any], list[int]]:
out_len = len(signature_tree.types)
if result is None:
final_result = []
elif out_len == 1:
final_result = [result]
else:
result_type = type(result)
if result_type is not list and result_type is not tuple:
raise SignatureBodyMismatchError(
"Expected signal to return a list or tuple of arguments"
)
final_result = result
if out_len != len(final_result):
raise SignatureBodyMismatchError(
f"Signature and function return mismatch, expected "
f"{len(signature_tree.types)} arguments but got {len(result)}" # type: ignore[arg-type]
)
if not replace_fds:
return final_result, []
return replace_fds_with_idx(signature_tree, final_result)
class ServiceInterface:
"""An abstract class that can be extended by the user to define DBus services.
Instances of :class:`ServiceInterface` can be exported on a path of the bus
with the :class:`export `
method of a :class:`MessageBus `.
Use the :func:`@method `, :func:`@dbus_property
`, and :func:`@signal
` decorators to mark class methods as DBus
methods, properties, and signals respectively.
:ivar name: The name of this interface as it appears to clients. Must be a
valid interface name.
:vartype name: str
"""
def __init__(self, name: str) -> None:
# TODO cannot be overridden by a dbus member
self.name = name
self.__methods: list[_Method] = []
self.__properties: list[_Property] = []
self.__signals: list[_Signal] = []
self.__buses: set[BaseMessageBus] = set()
self.__handlers: dict[BaseMessageBus, dict[_Method, HandlerType]] = {}
# Map of methods by bus of name -> method, handler
self.__handlers_by_name_signature: dict[
BaseMessageBus, dict[str, tuple[_Method, HandlerType]]
] = {}
for _, member in inspect.getmembers(type(self)):
member_dict = getattr(member, "__dict__", {})
if type(member) is _Property:
# XXX The getter and the setter may show up as different
# members if they have different names. But if they have the
# same name, they will be the same member. So we try to merge
# them together here. I wish we could make this cleaner.
found = False
for prop in self.__properties:
if prop.prop_getter is member.prop_getter:
found = True
if member.prop_setter is not None:
prop.prop_setter = member.prop_setter
if not found:
self.__properties.append(member)
elif "__DBUS_METHOD" in member_dict:
method = member_dict["__DBUS_METHOD"]
assert type(method) is _Method
self.__methods.append(method)
elif "__DBUS_SIGNAL" in member_dict:
signal = member_dict["__DBUS_SIGNAL"]
assert type(signal) is _Signal
self.__signals.append(signal)
# validate that writable properties have a setter
for prop in self.__properties:
if prop.access.writable() and prop.prop_setter is None:
raise ValueError(
f'property "{prop.name}" is writable but does not have a setter'
)
def emit_properties_changed(
self, changed_properties: dict[str, Any], invalidated_properties: list[str] = []
) -> None:
"""Emit the ``org.freedesktop.DBus.Properties.PropertiesChanged`` signal.
This signal is intended to be used to alert clients when a property of
the interface has changed.
:param changed_properties: The keys must be the names of properties exposed by this bus. The values must be valid for the signature of those properties.
:type changed_properties: dict(str, Any)
:param invalidated_properties: A list of names of properties that are now invalid (presumably for clients who cache the value).
:type invalidated_properties: list(str)
"""
# TODO cannot be overridden by a dbus member
variant_dict = {}
for prop in ServiceInterface._get_properties(self):
if prop.name in changed_properties:
variant_dict[prop.name] = Variant(
prop.signature, changed_properties[prop.name]
)
body = [self.name, variant_dict, invalidated_properties]
for bus in ServiceInterface._get_buses(self):
bus._interface_signal_notify(
self,
"org.freedesktop.DBus.Properties",
"PropertiesChanged",
"sa{sv}as",
body,
)
def introspect(self) -> intr.Interface:
"""Get introspection information for this interface.
This might be useful for creating clients for the interface or examining the introspection output of an interface.
:returns: The introspection data for the interface.
:rtype: :class:`dbus_fast.introspection.Interface`
"""
# TODO cannot be overridden by a dbus member
return intr.Interface(
self.name,
methods=[
method.introspection
for method in ServiceInterface._get_methods(self)
if not method.disabled
],
signals=[
signal.introspection
for signal in ServiceInterface._get_signals(self)
if not signal.disabled
],
properties=[
prop.introspection
for prop in ServiceInterface._get_properties(self)
if not prop.disabled
],
)
@staticmethod
def _get_properties(interface: ServiceInterface) -> list[_Property]:
return interface.__properties
@staticmethod
def _get_methods(interface: ServiceInterface) -> list[_Method]:
return interface.__methods
@staticmethod
def _get_signals(interface: ServiceInterface) -> list[_Signal]:
return interface.__signals
@staticmethod
def _get_buses(interface: ServiceInterface) -> set[BaseMessageBus]:
return interface.__buses
@staticmethod
def _get_handler(
interface: ServiceInterface, method: _Method, bus: BaseMessageBus
) -> HandlerType:
return interface.__handlers[bus][method]
@staticmethod
def _get_enabled_handler_by_name_signature(
interface: ServiceInterface,
bus: BaseMessageBus,
name: str_,
signature: str_,
) -> HandlerType | None:
handlers = interface.__handlers_by_name_signature[bus]
if (method_handler := handlers.get(name)) is None:
return None
method = method_handler[0]
if method.disabled:
return None
return method_handler[1] if method.in_signature == signature else None
@staticmethod
def _add_bus(
interface: ServiceInterface,
bus: BaseMessageBus,
maker: Callable[[ServiceInterface, _Method], HandlerType],
) -> None:
interface.__buses.add(bus)
interface.__handlers[bus] = {
method: maker(interface, method) for method in interface.__methods
}
interface.__handlers_by_name_signature[bus] = {
method.name: (method, handler)
for method, handler in interface.__handlers[bus].items()
}
@staticmethod
def _remove_bus(interface: ServiceInterface, bus: BaseMessageBus) -> None:
interface.__buses.remove(bus)
del interface.__handlers[bus]
@staticmethod
def _msg_body_to_args(msg: Message) -> list[Any]:
return ServiceInterface._c_msg_body_to_args(msg)
@staticmethod
def _c_msg_body_to_args(msg: Message) -> list[Any]:
# https://github.com/cython/cython/issues/3327
if not signature_contains_type(msg.signature_tree, msg.body, "h"):
return msg.body
# XXX: This deep copy could be expensive if messages are very
# large. We could optimize this by only copying what we change
# here.
return replace_idx_with_fds(
msg.signature_tree, copy.deepcopy(msg.body), msg.unix_fds
)
@staticmethod
def _fn_result_to_body(
result: Any | None,
signature_tree: SignatureTree,
replace_fds: bool = True,
) -> tuple[list[Any], list[int]]:
return _real_fn_result_to_body(result, signature_tree, replace_fds)
@staticmethod
def _c_fn_result_to_body(
result: Any | None,
signature_tree: SignatureTree,
replace_fds: bool,
) -> tuple[list[Any], list[int]]:
"""The high level interfaces may return single values which may be
wrapped in a list to be a message body. Also they may return fds
directly for type 'h' which need to be put into an external list."""
# https://github.com/cython/cython/issues/3327
return _real_fn_result_to_body(result, signature_tree, replace_fds)
@staticmethod
def _handle_signal(
interface: ServiceInterface, signal: _Signal, result: Any | None
) -> None:
body, fds = ServiceInterface._fn_result_to_body(result, signal.signature_tree)
for bus in ServiceInterface._get_buses(interface):
bus._interface_signal_notify(
interface, interface.name, signal.name, signal.signature, body, fds
)
@staticmethod
def _get_property_value(
interface: ServiceInterface,
prop: _Property,
callback: Callable[[ServiceInterface, _Property, Any, Exception | None], None],
) -> None:
# XXX MUST CHECK TYPE RETURNED BY GETTER
try:
if asyncio.iscoroutinefunction(prop.prop_getter):
task: asyncio.Task = asyncio.ensure_future(prop.prop_getter(interface))
def get_property_callback(task_: asyncio.Task) -> None:
try:
result = task_.result()
except Exception as e:
callback(interface, prop, None, e)
return
callback(interface, prop, result, None)
task.add_done_callback(get_property_callback)
return
callback(
interface, prop, getattr(interface, prop.prop_getter.__name__), None
)
except Exception as e:
callback(interface, prop, None, e)
@staticmethod
def _set_property_value(
interface: ServiceInterface,
prop: _Property,
value: Any,
callback: Callable[[ServiceInterface, _Property, Exception | None], None],
) -> None:
# XXX MUST CHECK TYPE TO SET
try:
if asyncio.iscoroutinefunction(prop.prop_setter):
task: asyncio.Task = asyncio.ensure_future(
prop.prop_setter(interface, value)
)
def set_property_callback(task_: asyncio.Task) -> None:
try:
task_.result()
except Exception as e:
callback(interface, prop, e)
return
callback(interface, prop, None)
task.add_done_callback(set_property_callback)
return
setattr(interface, prop.prop_setter.__name__, value)
callback(interface, prop, None)
except Exception as e:
callback(interface, prop, e)
@staticmethod
def _get_all_property_values(
interface: ServiceInterface,
callback: Callable[[ServiceInterface, Any, Any, Exception | None], None],
user_data: Any | None = None,
) -> None:
result: dict[str, Variant | None] = {}
result_error = None
for prop in ServiceInterface._get_properties(interface):
if prop.disabled or not prop.access.readable():
continue
result[prop.name] = None
if not result:
callback(interface, result, user_data, None)
return
def get_property_callback(
interface: ServiceInterface,
prop: _Property,
value: Any,
e: Exception | None,
) -> None:
nonlocal result_error
if e is not None:
result_error = e
del result[prop.name]
else:
try:
result[prop.name] = Variant(prop.signature, value)
except SignatureBodyMismatchError as exc:
result_error = exc
del result[prop.name]
if any(v is None for v in result.values()):
return
callback(interface, result, user_data, result_error)
for prop in ServiceInterface._get_properties(interface):
if prop.disabled or not prop.access.readable():
continue
ServiceInterface._get_property_value(interface, prop, get_property_callback)
dbus-fast-2.44.1/src/dbus_fast/signature.pxd 0000664 0000000 0000000 00000001176 14773556132 0020773 0 ustar 00root root 0000000 0000000 """cdefs for signature.py"""
import cython
cdef class SignatureType:
cdef public str token
cdef public unsigned int token_as_int
cdef public list children
cdef str _signature
cdef public SignatureType _child_0
cdef public SignatureType _child_1
cdef class SignatureTree:
cdef public str signature
cdef public list types
cdef public SignatureType root_type
cdef class Variant:
cdef public SignatureType type
cdef public str signature
cdef public object value
@cython.locals(self=Variant)
@staticmethod
cdef Variant _factory(SignatureTree signature_tree, object value)
dbus-fast-2.44.1/src/dbus_fast/signature.py 0000664 0000000 0000000 00000042421 14773556132 0020626 0 ustar 00root root 0000000 0000000 from functools import lru_cache
from typing import Any, Callable, Optional, Union
from .errors import InvalidSignatureError, SignatureBodyMismatchError
from .validators import is_object_path_valid
class SignatureType:
"""A class that represents a single complete type within a signature.
This class is not meant to be constructed directly. Use the :class:`SignatureTree`
class to parse signatures.
:ivar ~.signature: The signature of this complete type.
:vartype ~.signature: str
:ivar children: A list of child types if this is a container type. Arrays \
have one child type, dict entries have two child types (key and value), and \
structs have child types equal to the number of struct members.
:vartype children: list(:class:`SignatureType`)
"""
_tokens = "ybnqiuxtdsogavh({"
__slots__ = (
"_child_0",
"_child_1",
"_signature",
"children",
"token",
"token_as_int",
)
def __init__(self, token: str) -> None:
"""Init a new SignatureType."""
self.token: str = token
self.token_as_int = ord(token)
self.children: list[SignatureType] = []
self._child_0: Optional[SignatureType] = None
self._child_1: Optional[SignatureType] = None
self._signature: Optional[str] = None
def __eq__(self, other: object) -> bool:
"""Compare this type to another type or signature string."""
if type(other) is SignatureType:
return self.signature == other.signature
return super().__eq__(other)
def _collapse(self) -> str:
"""Collapse this type into a signature string."""
if self.token not in "a({":
return self.token
signature = [self.token]
for child in self.children:
signature.append(child._collapse())
if self.token == "(":
signature.append(")")
elif self.token == "{":
signature.append("}")
return "".join(signature)
@property
def signature(self) -> str:
if self._signature is not None:
return self._signature
self._signature = self._collapse()
return self._signature
def _add_child(self, child: "SignatureType") -> None:
"""Add a child type to this type.
:param child: The child type to add.
:type child: :class:`SignatureType`
"""
if self._child_0 is None:
self._child_0 = child
elif self._child_1 is None:
self._child_1 = child
self.children.append(child)
@staticmethod
def _parse_next(signature: str) -> tuple["SignatureType", str]:
if not signature:
raise InvalidSignatureError("Cannot parse an empty signature")
token = signature[0]
if token not in SignatureType._tokens:
raise InvalidSignatureError(f'got unexpected token: "{token}"')
# container types
if token == "a":
self = SignatureType("a")
(child, signature) = SignatureType._parse_next(signature[1:])
if not child:
raise InvalidSignatureError("missing type for array")
self._add_child(child)
return (self, signature)
if token == "(":
self = SignatureType("(")
signature = signature[1:]
while True:
(child, signature) = SignatureType._parse_next(signature)
if not signature:
raise InvalidSignatureError('missing closing ")" for struct')
self._add_child(child)
if signature[0] == ")":
return (self, signature[1:])
elif token == "{":
self = SignatureType("{")
signature = signature[1:]
(key_child, signature) = SignatureType._parse_next(signature)
if not key_child or len(key_child.children):
raise InvalidSignatureError("expected a simple type for dict entry key")
self._add_child(key_child)
(value_child, signature) = SignatureType._parse_next(signature)
if not value_child:
raise InvalidSignatureError("expected a value for dict entry")
if not signature or signature[0] != "}":
raise InvalidSignatureError('missing closing "}" for dict entry')
self._add_child(value_child)
return (self, signature[1:])
# basic type
return (SignatureType(token), signature[1:])
def _verify_byte(self, body: Any) -> None:
BYTE_MIN = 0x00
BYTE_MAX = 0xFF
if not isinstance(body, int):
raise SignatureBodyMismatchError(
f'DBus BYTE type "y" must be Python type "int", got {type(body)}'
)
if body < BYTE_MIN or body > BYTE_MAX:
raise SignatureBodyMismatchError(
f"DBus BYTE type must be between {BYTE_MIN} and {BYTE_MAX}"
)
def _verify_boolean(self, body: Any) -> None:
if not isinstance(body, bool):
raise SignatureBodyMismatchError(
f'DBus BOOLEAN type "b" must be Python type "bool", got {type(body)}'
)
def _verify_int16(self, body: Any) -> None:
INT16_MIN = -0x7FFF - 1
INT16_MAX = 0x7FFF
if not isinstance(body, int):
raise SignatureBodyMismatchError(
f'DBus INT16 type "n" must be Python type "int", got {type(body)}'
)
if body > INT16_MAX or body < INT16_MIN:
raise SignatureBodyMismatchError(
f'DBus INT16 type "n" must be between {INT16_MIN} and {INT16_MAX}'
)
def _verify_uint16(self, body: Any) -> None:
UINT16_MIN = 0
UINT16_MAX = 0xFFFF
if not isinstance(body, int):
raise SignatureBodyMismatchError(
f'DBus UINT16 type "q" must be Python type "int", got {type(body)}'
)
if body > UINT16_MAX or body < UINT16_MIN:
raise SignatureBodyMismatchError(
f'DBus UINT16 type "q" must be between {UINT16_MIN} and {UINT16_MAX}'
)
def _verify_int32(self, body: int) -> None:
INT32_MIN = -0x7FFFFFFF - 1
INT32_MAX = 0x7FFFFFFF
if not isinstance(body, int):
raise SignatureBodyMismatchError(
f'DBus INT32 type "i" must be Python type "int", got {type(body)}'
)
if body > INT32_MAX or body < INT32_MIN:
raise SignatureBodyMismatchError(
f'DBus INT32 type "i" must be between {INT32_MIN} and {INT32_MAX}'
)
def _verify_uint32(self, body: Any) -> None:
UINT32_MIN = 0
UINT32_MAX = 0xFFFFFFFF
if not isinstance(body, int):
raise SignatureBodyMismatchError(
f'DBus UINT32 type "u" must be Python type "int", got {type(body)}'
)
if body > UINT32_MAX or body < UINT32_MIN:
raise SignatureBodyMismatchError(
f'DBus UINT32 type "u" must be between {UINT32_MIN} and {UINT32_MAX}'
)
def _verify_int64(self, body: Any) -> None:
INT64_MAX = 9223372036854775807
INT64_MIN = -INT64_MAX - 1
if not isinstance(body, int):
raise SignatureBodyMismatchError(
f'DBus INT64 type "x" must be Python type "int", got {type(body)}'
)
if body > INT64_MAX or body < INT64_MIN:
raise SignatureBodyMismatchError(
f'DBus INT64 type "x" must be between {INT64_MIN} and {INT64_MAX}'
)
def _verify_uint64(self, body: Any) -> None:
UINT64_MIN = 0
UINT64_MAX = 18446744073709551615
if not isinstance(body, int):
raise SignatureBodyMismatchError(
f'DBus UINT64 type "t" must be Python type "int", got {type(body)}'
)
if body > UINT64_MAX or body < UINT64_MIN:
raise SignatureBodyMismatchError(
f'DBus UINT64 type "t" must be between {UINT64_MIN} and {UINT64_MAX}'
)
def _verify_double(self, body: Any) -> None:
if not isinstance(body, (float, int)):
raise SignatureBodyMismatchError(
f'DBus DOUBLE type "d" must be Python type "float" or "int", got {type(body)}'
)
def _verify_unix_fd(self, body: Any) -> None:
try:
self._verify_uint32(body)
except SignatureBodyMismatchError as ex:
raise SignatureBodyMismatchError(
'DBus UNIX_FD type "h" must be a valid UINT32'
) from ex
def _verify_object_path(self, body: Any) -> None:
if not is_object_path_valid(body):
raise SignatureBodyMismatchError(
'DBus OBJECT_PATH type "o" must be a valid object path'
)
def _verify_string(self, body: Any) -> None:
if not isinstance(body, str):
raise SignatureBodyMismatchError(
f'DBus STRING type "s" must be Python type "str", got {type(body)}'
)
def _verify_signature(self, body: Any) -> None:
# I guess we could run it through the SignatureTree parser instead
if not isinstance(body, str):
raise SignatureBodyMismatchError(
f'DBus SIGNATURE type "g" must be Python type "str", got {type(body)}'
)
if len(body.encode()) > 0xFF:
raise SignatureBodyMismatchError(
'DBus SIGNATURE type "g" must be less than 256 bytes'
)
def _verify_array(self, body: Any) -> None:
child_type = self.children[0]
if child_type.token == "{":
if not isinstance(body, dict):
raise SignatureBodyMismatchError(
f'DBus ARRAY type "a" with DICT_ENTRY child must be Python type "dict", got {type(body)}'
)
for key, value in body.items():
child_type.children[0].verify(key)
child_type.children[1].verify(value)
elif child_type.token == "y":
if not isinstance(body, (bytearray, bytes)):
raise SignatureBodyMismatchError(
f'DBus ARRAY type "a" with BYTE child must be Python type "bytes", got {type(body)}'
)
# no need to verify children
else:
if not isinstance(body, list):
raise SignatureBodyMismatchError(
f'DBus ARRAY type "a" must be Python type "list", got {type(body)}'
)
for member in body:
child_type.verify(member)
def _verify_struct(self, body: Any) -> None:
if not isinstance(body, (list, tuple)):
raise SignatureBodyMismatchError(
f'DBus STRUCT type "(" must be Python type "list" or "tuple", got {type(body)}'
)
if len(body) != len(self.children):
raise SignatureBodyMismatchError(
'DBus STRUCT type "(" must have Python list members equal to the number of struct type members'
)
for i, member in enumerate(body):
self.children[i].verify(member)
def _verify_variant(self, body: Any) -> None:
# a variant signature and value is valid by construction
if not isinstance(body, Variant):
raise SignatureBodyMismatchError(
f'DBus VARIANT type "v" must be Python type "Variant", got {type(body)}'
)
def verify(self, body: Any) -> bool:
"""Verify that the body matches this type.
:returns: True if the body matches this type.
:raises:
:class:`SignatureBodyMismatchError` if the body does not match this type.
"""
if body is None:
raise SignatureBodyMismatchError('Cannot serialize Python type "None"')
validator = self.validators.get(self.token)
if validator:
validator(self, body)
else:
raise Exception(f"cannot verify type with token {self.token}")
return True
validators: dict[str, Callable[["SignatureType", Any], None]] = {
"y": _verify_byte,
"b": _verify_boolean,
"n": _verify_int16,
"q": _verify_uint16,
"i": _verify_int32,
"u": _verify_uint32,
"x": _verify_int64,
"t": _verify_uint64,
"d": _verify_double,
"h": _verify_uint32,
"o": _verify_string,
"s": _verify_string,
"g": _verify_signature,
"a": _verify_array,
"(": _verify_struct,
"v": _verify_variant,
}
class SignatureTree:
"""A class that represents a signature as a tree structure for conveniently
working with DBus signatures.
This class will not normally be used directly by the user.
:ivar types: A list of parsed complete types.
:vartype types: list(:class:`SignatureType`)
:ivar ~.signature: The signature of this signature tree.
:vartype ~.signature: str
:ivar root_type: The root type of this signature tree.
:vartype root_type: :class:`SignatureType
:raises:
:class:`InvalidSignatureError` if the given signature is not valid.
"""
__slots__ = ("root_type", "signature", "types")
def __init__(self, signature: str = "") -> None:
self.signature = signature
self.types: list[SignatureType] = []
if len(signature) > 0xFF:
raise InvalidSignatureError("A signature must be less than 256 characters")
while signature:
(type_, signature) = SignatureType._parse_next(signature)
self.types.append(type_)
self.root_type = self.types[0] if self.types else None
def __eq__(self, other: object) -> bool:
if type(other) is SignatureTree:
return self.signature == other.signature
return super().__eq__(other)
def verify(self, body: list[Any]) -> bool:
"""Verifies that the give body matches this signature tree
:param body: the body to verify for this tree
:type body: list(Any)
:returns: True if the signature matches the body or an exception if not.
:raises:
:class:`SignatureBodyMismatchError` if the signature does not match the body.
"""
if not isinstance(body, list):
raise SignatureBodyMismatchError(
f"The body must be a list (got {type(body)})"
)
if len(body) != len(self.types):
raise SignatureBodyMismatchError(
f"The body has the wrong number of types (got {len(body)}, expected {len(self.types)})"
)
for i, type_ in enumerate(self.types):
type_.verify(body[i])
return True
class Variant:
"""A class to represent a DBus variant (type "v").
This class is used in message bodies to represent variants. The user can
expect a value in the body with type "v" to use this class and can
construct this class directly for use in message bodies sent over the bus.
:ivar signature: The signature for this variant. Must be a single complete type.
:vartype signature: str or SignatureTree or SignatureType
:ivar value: The value of this variant. Must correspond to the signature.
:vartype value: Any
:raises:
:class:`InvalidSignatureError` if the signature is not valid.
:class:`SignatureBodyMismatchError` if the signature does not match the body.
"""
__slots__ = ("signature", "type", "value")
def __init__(
self,
signature: Union[str, SignatureTree, SignatureType],
value: Any,
verify: bool = True,
) -> None:
"""Init a new Variant."""
if type(signature) is SignatureTree:
signature_tree = signature
self.signature = signature_tree.signature
self.type = signature_tree.types[0]
elif type(signature) is SignatureType:
signature_tree = None
self.signature = signature.signature
self.type = signature
elif type(signature) is str:
signature_tree = get_signature_tree(signature)
self.signature = signature
self.type = signature_tree.types[0]
else:
raise TypeError(
"signature must be a SignatureTree, SignatureType, or a string"
)
self.value = value
if verify:
if signature_tree and len(signature_tree.types) != 1:
raise ValueError(
"variants must have a signature for a single complete type"
)
self.type.verify(value)
@staticmethod
def _factory(signature_tree: SignatureTree, value: Any) -> "Variant":
self = Variant.__new__(Variant)
self.signature = signature_tree.signature
self.type = signature_tree.root_type
self.value = value
return self
def __eq__(self, other: object) -> bool:
if type(other) is Variant:
return self.signature == other.signature and self.value == other.value
return super().__eq__(other)
def __repr__(self) -> str:
return f""
get_signature_tree = lru_cache(maxsize=None)(SignatureTree)
"""Get a signature tree for the given signature.
:param signature: The signature to get a tree for.
:type signature: str
:returns: The signature tree for the given signature.
:rtype: :class:`SignatureTree`
"""
dbus-fast-2.44.1/src/dbus_fast/unpack.pxd 0000664 0000000 0000000 00000000265 14773556132 0020251 0 ustar 00root root 0000000 0000000 """cdefs for unpack.py"""
import cython
from .signature cimport Variant
cpdef unpack_variants(object data)
@cython.locals(
var=Variant
)
cdef _unpack_variants(object data)
dbus-fast-2.44.1/src/dbus_fast/unpack.py 0000664 0000000 0000000 00000001156 14773556132 0020106 0 ustar 00root root 0000000 0000000 from typing import Any
from .signature import Variant
def unpack_variants(data: Any) -> Any:
"""Unpack variants and remove signature info.
This function should only be used to unpack
unmarshalled data as the checks are not
idiomatic.
"""
return _unpack_variants(data)
def _unpack_variants(data: Any) -> Any:
if type(data) is dict:
return {k: _unpack_variants(v) for k, v in data.items()}
if type(data) is list:
return [_unpack_variants(item) for item in data]
if type(data) is Variant:
var = data
return _unpack_variants(var.value)
return data
dbus-fast-2.44.1/src/dbus_fast/validators.py 0000664 0000000 0000000 00000012167 14773556132 0021001 0 ustar 00root root 0000000 0000000 import re
from functools import lru_cache
from .errors import (
InvalidBusNameError,
InvalidInterfaceNameError,
InvalidMemberNameError,
InvalidObjectPathError,
)
_bus_name_re = re.compile(r"^[A-Za-z_-][A-Za-z0-9_-]*$")
_path_re = re.compile(r"^[A-Za-z0-9_]+$")
_element_re = re.compile(r"^[A-Za-z_][A-Za-z0-9_]*$")
_member_re = re.compile(r"^[A-Za-z_][A-Za-z0-9_-]*$")
@lru_cache(maxsize=32)
def is_bus_name_valid(name: str) -> bool:
"""Whether this is a valid bus name.
.. seealso:: https://dbus.freedesktop.org/doc/dbus-specification.html#message-protocol-names-bus
:param name: The bus name to validate.
:type name: str
:returns: Whether the name is a valid bus name.
:rtype: bool
"""
if not isinstance(name, str):
return False # type: ignore[unreachable]
if not name or len(name) > 255:
return False
if name.startswith(":"):
# a unique bus name
return True
if name.startswith("."):
return False
if name.find(".") == -1:
return False
for element in name.split("."):
if _bus_name_re.search(element) is None:
return False
return True
@lru_cache(maxsize=1024)
def is_object_path_valid(path: str) -> bool:
"""Whether this is a valid object path.
.. seealso:: https://dbus.freedesktop.org/doc/dbus-specification.html#message-protocol-marshaling-object-path
:param path: The object path to validate.
:type path: str
:returns: Whether the object path is valid.
:rtype: bool
"""
if not isinstance(path, str):
return False # type: ignore[unreachable]
if not path:
return False
if not path.startswith("/"):
return False
if len(path) == 1:
return True
for element in path[1:].split("/"):
if _path_re.search(element) is None:
return False
return True
@lru_cache(maxsize=32)
def is_interface_name_valid(name: str) -> bool:
"""Whether this is a valid interface name.
.. seealso:: https://dbus.freedesktop.org/doc/dbus-specification.html#message-protocol-names-interface
:param name: The interface name to validate.
:type name: str
:returns: Whether the name is a valid interface name.
:rtype: bool
"""
if not isinstance(name, str):
return False # type: ignore[unreachable]
if not name or len(name) > 255:
return False
if name.startswith("."):
return False
if name.find(".") == -1:
return False
for element in name.split("."):
if _element_re.search(element) is None:
return False
return True
@lru_cache(maxsize=512)
def is_member_name_valid(member: str) -> bool:
"""Whether this is a valid member name.
.. seealso:: https://dbus.freedesktop.org/doc/dbus-specification.html#message-protocol-names-member
:param member: The member name to validate.
:type member: str
:returns: Whether the name is a valid member name.
:rtype: bool
"""
if not isinstance(member, str):
return False # type: ignore[unreachable]
if not member or len(member) > 255:
return False
if _member_re.search(member) is None:
return False
return True
@lru_cache(maxsize=32)
def assert_bus_name_valid(name: str) -> None:
"""Raise an error if this is not a valid bus name.
.. seealso:: https://dbus.freedesktop.org/doc/dbus-specification.html#message-protocol-names-bus
:param name: The bus name to validate.
:type name: str
:raises:
- :class:`InvalidBusNameError` - If this is not a valid bus name.
"""
if not is_bus_name_valid(name):
raise InvalidBusNameError(name)
@lru_cache(maxsize=1024)
def assert_object_path_valid(path: str) -> None:
"""Raise an error if this is not a valid object path.
.. seealso:: https://dbus.freedesktop.org/doc/dbus-specification.html#message-protocol-marshaling-object-path
:param path: The object path to validate.
:type path: str
:raises:
- :class:`InvalidObjectPathError` - If this is not a valid object path.
"""
if not is_object_path_valid(path):
raise InvalidObjectPathError(path)
@lru_cache(maxsize=32)
def assert_interface_name_valid(name: str) -> None:
"""Raise an error if this is not a valid interface name.
.. seealso:: https://dbus.freedesktop.org/doc/dbus-specification.html#message-protocol-names-interface
:param name: The interface name to validate.
:type name: str
:raises:
- :class:`InvalidInterfaceNameError` - If this is not a valid object path.
"""
if not is_interface_name_valid(name):
raise InvalidInterfaceNameError(name)
@lru_cache(maxsize=512)
def assert_member_name_valid(member: str) -> None:
"""Raise an error if this is not a valid member name.
.. seealso:: https://dbus.freedesktop.org/doc/dbus-specification.html#message-protocol-names-member
:param member: The member name to validate.
:type member: str
:raises:
- :class:`InvalidMemberNameError` - If this is not a valid object path.
"""
if not is_member_name_valid(member):
raise InvalidMemberNameError(member)
dbus-fast-2.44.1/tests/ 0000775 0000000 0000000 00000000000 14773556132 0014651 5 ustar 00root root 0000000 0000000 dbus-fast-2.44.1/tests/__init__.py 0000664 0000000 0000000 00000000000 14773556132 0016750 0 ustar 00root root 0000000 0000000 dbus-fast-2.44.1/tests/benchmarks/ 0000775 0000000 0000000 00000000000 14773556132 0016766 5 ustar 00root root 0000000 0000000 dbus-fast-2.44.1/tests/benchmarks/test_marshall.py 0000664 0000000 0000000 00000000652 14773556132 0022205 0 ustar 00root root 0000000 0000000 from pytest_codspeed import BenchmarkFixture
from dbus_fast import Message
message = Message(
destination="org.bluez",
path="/",
interface="org.freedesktop.DBus.ObjectManager",
member="GetManagedObjects",
)
def test_marshall_bluez_get_managed_objects_message(
benchmark: BenchmarkFixture,
) -> None:
@benchmark
def marhsall_bluez_get_managed_objects_message():
message._marshall(False)
dbus-fast-2.44.1/tests/benchmarks/test_unmarshall.py 0000664 0000000 0000000 00000015716 14773556132 0022557 0 ustar 00root root 0000000 0000000 import io
import socket
from pytest_codspeed import BenchmarkFixture
from dbus_fast._private.unmarshaller import Unmarshaller
def test_unmarshall_bluez_rssi_message(benchmark: BenchmarkFixture) -> None:
bluez_rssi_message = (
"6c04010134000000e25389019500000001016f00250000002f6f72672f626c75657a2f686369302f6465"
"765f30385f33415f46325f31455f32425f3631000000020173001f0000006f72672e667265656465736b"
"746f702e444275732e50726f7065727469657300030173001100000050726f706572746965734368616e"
"67656400000000000000080167000873617b73767d617300000007017300040000003a312e3400000000"
"110000006f72672e626c75657a2e446576696365310000000e0000000000000004000000525353490001"
"6e00a7ff000000000000"
)
stream = io.BytesIO(bytes.fromhex(bluez_rssi_message))
unmarshaller = Unmarshaller(stream)
@benchmark
def unmarhsall_bluez_rssi_message():
stream.seek(0)
unmarshaller.unmarshall()
bluez_properties_message = (
b"l\4\1\0014\0\0\0\16Q\16\0\225\0\0\0\1\1o\0%\0\0\0/org/bluez/hci2/dev_08_3A_F2_1E_28_89\0\0\0\2\1s\0\37\0\0\0"
b"org.freedesktop.DBus.Properties\0\3\1s\0\21\0\0\0PropertiesChanged\0\0\0\0\0\0\0\10\1g\0\10sa{sv}as\0\0\0\7\1"
b"s\0\4\0\0\0:1.5\0\0\0\0\21\0\0\0org.bluez.Device1\0\0\0\16\0\0\0\0\0\0\0\4\0\0\0RSSI\0\1n\0\242\377\0\0\0\0\0\0"
b"l\4\1\1\220\0\0\0\17Q\16\0\225\0\0\0\1\1o\0%\0\0\0/org/bluez/hci2/dev_A4_C1_38_6E_9F_7C\0\0\0\2\1s\0\37\0\0\0"
b"org.freedesktop.DBus.Properties\0\3\1s\0\21\0\0\0PropertiesChanged\0\0\0\0\0\0\0\10\1g\0\10sa{sv}as\0\0\0\7\1s"
b"\0\4\0\0\0:1.5\0\0\0\0\21\0\0\0org.bluez.Device1\0\0\0k\0\0\0\0\0\0\0\4\0\0\0RSSI\0\1n\0\250\377\0\0\20\0\0\0"
b"ManufacturerData\0\5a{qv}\0;\0\0\0\1\0\2ay\0\0\0\t\0\0\0\1\1\1\3\361\234\\\0\1\0\0\0L\0\2ay\0\0\0\27\0\0\0\2\25"
b"INTELLI_ROCKS_HWPu\362\377\302\0\0\0\0\0l\4\1\0014\0\0\0\20Q\16\0\225\0\0\0\1\1o\0%\0\0\0/org/bluez/hci2/dev_F8"
b"_04_2E_E1_9F_19\0\0\0\2\1s\0\37\0\0\0org.freedesktop.DBus.Properties\0\3\1s\0\21\0\0\0PropertiesChanged\0\0\0\0"
b"\0\0\0\10\1g\0\10sa{sv}as\0\0\0\7\1s\0\4\0\0\0:1.5\0\0\0\0\21\0\0\0org.bluez.Device1\0\0\0\16\0\0\0\0\0\0\0\4\0"
b"\0\0RSSI\0\1n\0\262\377\0\0\0\0\0\0l\4\1\0014\0\0\0\21Q\16\0\225\0\0\0\1\1o\0%\0\0\0/org/bluez/hci3/dev_54_E6_"
b"1B_F0_20_97\0\0\0\2\1s\0\37\0\0\0org.freedesktop.DBus.Properties\0\3\1s\0\21\0\0\0PropertiesChanged\0\0\0\0\0\0"
b"\0\10\1g\0\10sa{sv}as\0\0\0\7\1s\0\4\0\0\0:1.5\0\0\0\0\21\0\0\0org.bluez.Device1\0\0\0\16\0\0\0\0\0\0\0\4\0\0\0"
b"RSSI\0\1n\0\254\377\0\0\0\0\0\0l\4\1\0014\0\0\0\22Q\16\0\225\0\0\0\1\1o\0%\0\0\0/org/bluez/hci3/dev_D8_EF_2F_41"
b"_B1_34\0\0\0\2\1s\0\37\0\0\0org.freedesktop.DBus.Properties\0\3\1s\0\21\0\0\0PropertiesChanged\0\0\0\0\0\0\0\10"
b"\1g\0\10sa{sv}as\0\0\0\7\1s\0\4\0\0\0:1.5\0\0\0\0\21\0\0\0org.bluez.Device1\0\0\0\16\0\0\0\0\0\0\0\4\0\0\0RSSI\0"
b"\1n\0\244\377\0\0\0\0\0\0l\4\1\0014\0\0\0\23Q\16\0\225\0\0\0\1\1o\0%\0\0\0/org/bluez/hci3/dev_34_AB_95_85_66_6D\0"
b"\0\0\2\1s\0\37\0\0\0org.freedesktop.DBus.Properties\0\3\1s\0\21\0\0\0PropertiesChanged\0\0\0\0\0\0\0\10\1g\0\10"
b"sa{sv}as\0\0\0\7\1s\0\4\0\0\0:1.5\0\0\0\0\21\0\0\0org.bluez.Device1\0\0\0\16\0\0\0\0\0\0\0\4\0\0\0RSSI\0\1n\0\236"
b"\377\0\0\0\0\0\0l\4\1\0014\0\0\0\24Q\16\0\225\0\0\0\1\1o\0%\0\0\0/org/bluez/hci3/dev_08_3A_F2_1E_32_69\0\0\0\2\1s"
b"\0\37\0\0\0org.freedesktop.DBus.Properties\0\3\1s\0\21\0\0\0PropertiesChanged\0\0\0\0\0\0\0\10\1g\0\10sa{sv}as\0"
b"\0\0\7\1s\0\4\0\0\0:1.5\0\0\0\0\21\0\0\0org.bluez.Device1\0\0\0\16\0\0\0\0\0\0\0\4\0\0\0RSSI\0\1n\0\246\377\0\0\0"
b"\0\0\0l\4\1\0014\0\0\0\25Q\16\0\225\0\0\0\1\1o\0%\0\0\0/org/bluez/hci3/dev_34_AB_95_85_71_D1\0\0\0\2\1s\0\37\0\0\0"
b"org.freedesktop.DBus.Properties\0\3\1s\0\21\0\0\0PropertiesChanged\0\0\0\0\0\0\0\10\1g\0\10sa{sv}as\0\0\0\7\1s\0\4"
b"\0\0\0:1.5\0\0\0\0\21\0\0\0org.bluez.Device1\0\0\0\16\0\0\0\0\0\0\0\4\0\0\0RSSI\0\1n\0\232\377\0\0\0\0\0\0l\4\1\001"
b"4\0\0\0\26Q\16\0\225\0\0\0\1\1o\0%\0\0\0/org/bluez/hci3/dev_F8_04_2E_E1_9F_19\0\0\0\2\1s\0\37\0\0\0org.freedesktop.D"
b"Bus.Properties\0\3\1s\0\21\0\0\0PropertiesChanged\0\0\0\0\0\0\0\10\1g\0\10sa{sv}as\0\0\0\7\1s\0\4\0\0\0:1.5\0\0\0\0"
b"\21\0\0\0org.bluez.Device1\0\0\0\16\0\0\0\0\0\0\0\4\0\0\0RSSI\0\1n\0\306\377\0\0\0\0\0\0"
)
def test_unmarshall_bluez_properties_message(benchmark: BenchmarkFixture) -> None:
stream = io.BytesIO(bluez_properties_message)
unmarshaller = Unmarshaller(stream)
@benchmark
def unmarshall_bluez_properties_message():
stream.seek(0)
unmarshaller.unmarshall()
def test_unmarshall_multiple_bluez_properties_message(
benchmark: BenchmarkFixture,
) -> None:
stream = io.BytesIO(bluez_properties_message)
unmarshaller = Unmarshaller(stream)
@benchmark
def unmarshall_bluez_properties_message():
stream.seek(0)
for _ in range(9):
unmarshaller.unmarshall()
def test_unmarshall_multiple_bluez_properties_message_socket(
benchmark: BenchmarkFixture,
) -> None:
sock1, sock2 = socket.socketpair()
sock1.setblocking(False)
sock2.setblocking(False)
unmarshaller = Unmarshaller(None, sock1, False)
@benchmark
def unmarshall_bluez_properties_message():
sock2.send(bluez_properties_message)
for _ in range(9):
unmarshaller.unmarshall()
sock1.close()
sock2.close()
def test_unmarshall_bluez_interfaces_added_message(benchmark: BenchmarkFixture) -> None:
bluez_interfaces_added_message = (
b'l\4\1\1\240\2\0\0\227\272\23\0u\0\0\0\1\1o\0\1\0\0\0/\0\0\0\0\0\0\0\2\1s\0"\0\0\0'
b"org.freedesktop.DBus.ObjectManager\0\0\0\0\0\0\3\1s\0\17\0\0\0InterfacesAdded\0\10"
b"\1g\0\noa{sa{sv}}\0\7\1s\0\4\0\0\0:1.4\0\0\0\0%\0\0\0/org/bluez/hci1/dev_58_2D_34"
b"_60_26_36\0\0\0p\2\0\0#\0\0\0org.freedesktop.DBus.Introspectable\0\0\0\0\0\0\0\0\0"
b"\21\0\0\0org.bluez.Device1\0\0\0\364\1\0\0\0\0\0\0\7\0\0\0Address\0\1s\0\0\21\0\0"
b"\00058:2D:34:60:26:36\0\0\0\v\0\0\0AddressType\0\1s\0\0\6\0\0\0public\0\0\4\0\0\0"
b"Name\0\1s\0\33\0\0\0Qingping Door/Window Sensor\0\0\0\0\0\5\0\0\0Alias\0\1s\0\0\0"
b"\0\33\0\0\0Qingping Door/Window Sensor\0\6\0\0\0Paired\0\1b\0\0\0\0\0\0\0\0\0\0\0"
b"\7\0\0\0Trusted\0\1b\0\0\0\0\0\0\0\0\0\0\7\0\0\0Blocked\0\1b\0\0\0\0\0\0\0\0\0\0\r"
b"\0\0\0LegacyPairing\0\1b\0\0\0\0\0\0\0\0\0\0\0\0\4\0\0\0RSSI\0\1n\0\316\377\0\0\t"
b"\0\0\0Connected\0\1b\0\0\0\0\0\0\0\0\5\0\0\0UUIDs\0\2as\0\0\0\0\0\0\0\0\0\0\0\7\0"
b"\0\0Adapter\0\1o\0\0\17\0\0\0/org/bluez/hci1\0\0\0\0\0\v\0\0\0ServiceData\0\5a{sv}"
b"\0\0@\0\0\0\0\0\0\0$\0\0\0000000fe95-0000-1000-8000-00805f9b34fb\0\2ay\0\0\0\0\f\0"
b"\0\0000X\326\3\0026&`4-X\10\20\0\0\0ServicesResolved\0\1b\0\0\0\0\0\0\0\0\0\37\0\0"
b"\0org.freedesktop.DBus.Properties\0\0\0\0\0"
)
stream = io.BytesIO(bluez_interfaces_added_message)
unmarshaller = Unmarshaller(stream)
@benchmark
def unmarshall():
stream.seek(0)
unmarshaller.unmarshall()
dbus-fast-2.44.1/tests/client/ 0000775 0000000 0000000 00000000000 14773556132 0016127 5 ustar 00root root 0000000 0000000 dbus-fast-2.44.1/tests/client/__init__.py 0000664 0000000 0000000 00000000000 14773556132 0020226 0 ustar 00root root 0000000 0000000 dbus-fast-2.44.1/tests/client/test_aio.py 0000664 0000000 0000000 00000001370 14773556132 0020311 0 ustar 00root root 0000000 0000000 import pytest
from dbus_fast import aio
from dbus_fast.service import ServiceInterface
class ExampleInterface(ServiceInterface):
def __init__(self):
super().__init__("test.interface")
@pytest.mark.asyncio
async def test_fast_disconnect():
bus_name = "aio.client.test.methods"
bus = await aio.MessageBus().connect()
bus2 = await aio.MessageBus().connect()
await bus.request_name(bus_name)
service_interface = ExampleInterface()
bus.export("/test/path", service_interface)
introspection = await bus2.introspect(bus_name, "/test/path")
bus2.get_proxy_object(bus_name, "/test/path", introspection)
bus2.disconnect()
bus.disconnect()
await bus.wait_for_disconnect()
await bus2.wait_for_disconnect()
dbus-fast-2.44.1/tests/client/test_methods.py 0000664 0000000 0000000 00000013225 14773556132 0021206 0 ustar 00root root 0000000 0000000 import logging
import sys
from logging.handlers import QueueHandler
from queue import SimpleQueue
import pytest
import dbus_fast.introspection as intr
from dbus_fast import DBusError, aio, glib
from dbus_fast.message import MessageFlag
from dbus_fast.service import ServiceInterface, method
from dbus_fast.signature import Variant
from tests.util import check_gi_repository, skip_reason_no_gi
has_gi = check_gi_repository()
class ExampleInterface(ServiceInterface):
def __init__(self):
super().__init__("test.interface")
@method()
def Ping(self):
pass
@method()
def EchoInt64(self, what: "x") -> "x":
return what
@method()
def EchoString(self, what: "s") -> "s":
return what
@method()
def ConcatStrings(self, what1: "s", what2: "s") -> "s":
return what1 + what2
@method()
def EchoThree(self, what1: "s", what2: "s", what3: "s") -> "sss":
return [what1, what2, what3]
@method()
def GetComplex(self) -> "a{sv}": # noqa: F722
"""Return complex output."""
return {"hello": Variant("s", "world")}
@method()
def ThrowsError(self):
raise DBusError("test.error", "something went wrong")
@pytest.mark.asyncio
async def test_aio_proxy_object():
bus_name = "aio.client.test.methods"
bus = await aio.MessageBus().connect()
bus2 = await aio.MessageBus().connect()
await bus.request_name(bus_name)
service_interface = ExampleInterface()
bus.export("/test/path", service_interface)
# add some more to test nodes
bus.export("/test/path/child1", ExampleInterface())
bus.export("/test/path/child2", ExampleInterface())
introspection = await bus2.introspect(bus_name, "/test/path")
assert type(introspection) is intr.Node
obj = bus2.get_proxy_object(bus_name, "/test/path", introspection)
interface = obj.get_interface(service_interface.name)
children = obj.get_children()
assert len(children) == 2
for child in obj.get_children():
assert type(child) is aio.ProxyObject
result = await interface.call_ping()
assert result is None
result = await interface.call_echo_string("hello")
assert result == "hello"
result = await interface.call_concat_strings("hello ", "world")
assert result == "hello world"
result = await interface.call_echo_three("hello", "there", "world")
assert result == ["hello", "there", "world"]
result = await interface.call_echo_int64(-10000)
assert result == -10000
result = await interface.call_echo_string(
"no reply", flags=MessageFlag.NO_REPLY_EXPECTED
)
assert result is None
result = await interface.call_get_complex()
assert result == {"hello": Variant("s", "world")}
result = await interface.call_get_complex(unpack_variants=True)
assert result == {"hello": "world"}
# In addition to the exception passing through, we need to verify that
# the exception doesn't trigger logging errors.
log_error_queue = SimpleQueue()
log_handler = QueueHandler(log_error_queue)
logger = logging.getLogger()
logger.addHandler(log_handler)
try:
with pytest.raises(DBusError):
try:
await interface.call_throws_error()
except DBusError as e:
assert e.reply is not None
assert e.type == "test.error"
assert e.text == "something went wrong"
raise e
finally:
logger.removeHandler(log_handler)
assert log_error_queue.empty(), log_error_queue.get_nowait()
bus.disconnect()
bus2.disconnect()
await bus.wait_for_disconnect()
await bus2.wait_for_disconnect()
@pytest.mark.skipif(
sys.version_info[:3][1] in (10, 11, 12, 13), reason="segfaults on py3.10/py3.11"
)
@pytest.mark.skipif(not has_gi, reason=skip_reason_no_gi)
def test_glib_proxy_object():
bus_name = "glib.client.test.methods"
bus = glib.MessageBus().connect_sync()
bus.request_name_sync(bus_name)
service_interface = ExampleInterface()
bus.export("/test/path", service_interface)
bus2 = glib.MessageBus().connect_sync()
introspection = bus2.introspect_sync(bus_name, "/test/path")
assert type(introspection) is intr.Node
obj = bus.get_proxy_object(bus_name, "/test/path", introspection)
interface = obj.get_interface(service_interface.name)
result = interface.call_ping_sync()
assert result is None
result = interface.call_echo_string_sync("hello")
assert result == "hello"
result = interface.call_concat_strings_sync("hello ", "world")
assert result == "hello world"
result = interface.call_echo_three_sync("hello", "there", "world")
assert result == ["hello", "there", "world"]
result = interface.call_get_complex_sync()
assert result == {"hello": Variant("s", "world")}
result = interface.call_get_complex_sync(unpack_variants=True)
assert result == {"hello": "world"}
# In addition to the exception passing through, we need to verify that
# the exception doesn't trigger logging errors.
log_error_queue = SimpleQueue()
log_handler = QueueHandler(log_error_queue)
logger = logging.getLogger()
logger.addHandler(log_handler)
try:
with pytest.raises(DBusError):
try:
result = interface.call_throws_error_sync()
assert False, result
except DBusError as e:
assert e.reply is not None
assert e.type == "test.error"
assert e.text == "something went wrong"
raise e
finally:
logger.removeHandler(log_handler)
assert log_error_queue.empty()
bus.disconnect()
bus2.disconnect()
dbus-fast-2.44.1/tests/client/test_properties.py 0000664 0000000 0000000 00000011311 14773556132 0021731 0 ustar 00root root 0000000 0000000 import sys
import pytest
from dbus_fast import DBusError, Message, aio, glib
from dbus_fast.service import PropertyAccess, ServiceInterface, dbus_property
from dbus_fast.signature import Variant
from tests.util import check_gi_repository, skip_reason_no_gi
has_gi = check_gi_repository()
class ExampleInterface(ServiceInterface):
def __init__(self):
super().__init__("test.interface")
self._some_property = "foo"
self.error_name = "test.error"
self.error_text = "i am bad"
self._int64_property = -10000
@dbus_property()
def SomeProperty(self) -> "s":
return self._some_property
@SomeProperty.setter
def SomeProperty(self, val: "s"):
self._some_property = val
@dbus_property(access=PropertyAccess.READ)
def Int64Property(self) -> "x":
return self._int64_property
@dbus_property(access=PropertyAccess.READ)
def ComplexProperty(self) -> "a{sv}": # noqa: F722
"""Return complex output."""
return {"hello": Variant("s", "world")}
@dbus_property()
def ErrorThrowingProperty(self) -> "s":
raise DBusError(self.error_name, self.error_text)
@ErrorThrowingProperty.setter
def ErrorThrowingProperty(self, val: "s"):
raise DBusError(self.error_name, self.error_text)
@pytest.mark.asyncio
async def test_aio_properties():
service_bus = await aio.MessageBus().connect()
service_interface = ExampleInterface()
service_bus.export("/test/path", service_interface)
bus = await aio.MessageBus().connect()
obj = bus.get_proxy_object(
service_bus.unique_name,
"/test/path",
service_bus._introspect_export_path("/test/path"),
)
interface = obj.get_interface(service_interface.name)
prop = await interface.get_some_property()
assert prop == service_interface._some_property
prop = await interface.get_int64_property()
assert prop == service_interface._int64_property
await interface.set_some_property("different")
assert service_interface._some_property == "different"
prop = await interface.get_complex_property()
assert prop == {"hello": Variant("s", "world")}
prop = await interface.get_complex_property(unpack_variants=True)
assert prop == {"hello": "world"}
with pytest.raises(DBusError):
try:
prop = await interface.get_error_throwing_property()
assert False, prop
except DBusError as e:
assert e.type == service_interface.error_name
assert e.text == service_interface.error_text
assert type(e.reply) is Message
raise e
with pytest.raises(DBusError):
try:
await interface.set_error_throwing_property("different")
except DBusError as e:
assert e.type == service_interface.error_name
assert e.text == service_interface.error_text
assert type(e.reply) is Message
raise e
service_bus.disconnect()
bus.disconnect()
@pytest.mark.skipif(
sys.version_info[:3][1] in (10, 11, 12, 13),
reason="segfaults on py3.10,py3.11,py3.12,py3.13",
)
@pytest.mark.skipif(not has_gi, reason=skip_reason_no_gi)
def test_glib_properties():
service_bus = glib.MessageBus().connect_sync()
service_interface = ExampleInterface()
service_bus.export("/test/path", service_interface)
bus = glib.MessageBus().connect_sync()
obj = bus.get_proxy_object(
service_bus.unique_name,
"/test/path",
service_bus._introspect_export_path("/test/path"),
)
interface = obj.get_interface(service_interface.name)
prop = interface.get_some_property_sync()
assert prop == service_interface._some_property
interface.set_some_property_sync("different")
assert service_interface._some_property == "different"
prop = interface.get_complex_property_sync()
assert prop == {"hello": Variant("s", "world")}
prop = interface.get_complex_property_sync(unpack_variants=True)
assert prop == {"hello": "world"}
with pytest.raises(DBusError):
try:
prop = interface.get_error_throwing_property_sync()
assert False, prop
except DBusError as e:
assert e.type == service_interface.error_name
assert e.text == service_interface.error_text
assert type(e.reply) is Message
raise e
with pytest.raises(DBusError):
try:
interface.set_error_throwing_property_sync("different2")
except DBusError as e:
assert e.type == service_interface.error_name
assert e.text == service_interface.error_text
assert type(e.reply) is Message
raise e
service_bus.disconnect()
bus.disconnect()
dbus-fast-2.44.1/tests/client/test_signals.py 0000664 0000000 0000000 00000037123 14773556132 0021206 0 ustar 00root root 0000000 0000000 import asyncio
import pytest
from dbus_fast import Message
from dbus_fast.aio import MessageBus
from dbus_fast.constants import RequestNameReply
from dbus_fast.introspection import Node
from dbus_fast.service import ServiceInterface, signal
from dbus_fast.signature import Variant
class ExampleInterface(ServiceInterface):
def __init__(self):
super().__init__("test.interface")
@signal()
def SomeSignal(self) -> "s":
return "hello"
@signal()
def SignalMultiple(self) -> "ss":
return ["hello", "world"]
@signal()
def SignalComplex(self) -> "a{sv}": # noqa: F722
"""Broadcast a complex signal."""
return {"hello": Variant("s", "world")}
@pytest.mark.asyncio
async def test_signals():
bus1 = await MessageBus().connect()
bus2 = await MessageBus().connect()
bus_intr = await bus1.introspect("org.freedesktop.DBus", "/org/freedesktop/DBus")
bus_obj = bus1.get_proxy_object(
"org.freedesktop.DBus", "/org/freedesktop/DBus", bus_intr
)
stats = bus_obj.get_interface("org.freedesktop.DBus.Debug.Stats")
await bus1.request_name("test.signals.name")
service_interface = ExampleInterface()
bus1.export("/test/path", service_interface)
obj = bus2.get_proxy_object(
"test.signals.name", "/test/path", bus1._introspect_export_path("/test/path")
)
interface = obj.get_interface(service_interface.name)
async def ping():
await bus2.call(
Message(
destination=bus1.unique_name,
interface="org.freedesktop.DBus.Peer",
path="/test/path",
member="Ping",
)
)
err = None
single_counter = 0
def single_handler(value):
try:
nonlocal single_counter
nonlocal err
assert value == "hello"
single_counter += 1
except Exception as e:
err = e
multiple_counter = 0
def multiple_handler(value1, value2):
nonlocal multiple_counter
nonlocal err
try:
assert value1 == "hello"
assert value2 == "world"
multiple_counter += 1
except Exception as e:
err = e
await ping()
match_rules = await stats.call_get_all_match_rules()
assert bus2.unique_name in match_rules
bus_match_rules = match_rules[bus2.unique_name]
# the bus connection itself takes a rule on NameOwnerChange after the high
# level client is initialized
assert len(bus_match_rules) == 1
assert len(bus2._user_message_handlers) == 0
interface.on_some_signal(single_handler)
interface.on_signal_multiple(multiple_handler)
# Interlude: adding a signal handler with `on_[signal]` should add a match rule and
# message handler. Removing a signal handler with `off_[signal]` should
# remove the match rule and message handler to avoid memory leaks.
await ping()
match_rules = await stats.call_get_all_match_rules()
assert bus2.unique_name in match_rules
bus_match_rules = match_rules[bus2.unique_name]
# test the match rule and user handler has been added
assert len(bus_match_rules) == 2
assert (
"type='signal',interface='test.interface',path='/test/path',sender='test.signals.name'"
in bus_match_rules
)
assert len(bus2._user_message_handlers) == 1
service_interface.SomeSignal()
await ping()
assert err is None
assert single_counter == 1
service_interface.SignalMultiple()
await ping()
assert err is None
assert multiple_counter == 1
# special case: another bus with the same path and interface but on a
# different name and connection will trigger the match rule of the first
# (happens with mpris)
bus3 = await MessageBus().connect()
await bus3.request_name("test.signals.name2")
service_interface2 = ExampleInterface()
bus3.export("/test/path", service_interface2)
obj = bus2.get_proxy_object(
"test.signals.name2", "/test/path", bus3._introspect_export_path("/test/path")
)
# we have to add a dummy handler to add the match rule
iface2 = obj.get_interface(service_interface2.name)
def dummy_signal_handler(what):
pass
iface2.on_some_signal(dummy_signal_handler)
await ping()
service_interface2.SomeSignal()
await ping()
# single_counter is not incremented for signals of the second interface
assert single_counter == 1
interface.off_some_signal(single_handler)
interface.off_signal_multiple(multiple_handler)
iface2.off_some_signal(dummy_signal_handler)
# After `off_[signal]`, the match rule and user handler should be removed
await ping()
match_rules = await stats.call_get_all_match_rules()
assert bus2.unique_name in match_rules
bus_match_rules = match_rules[bus2.unique_name]
assert len(bus_match_rules) == 1
assert (
"type='signal',interface='test.interface',path='/test/path',sender='test.signals.name'"
not in bus_match_rules
)
assert len(bus2._user_message_handlers) == 0
bus1.disconnect()
bus2.disconnect()
bus3.disconnect()
@pytest.mark.asyncio
async def test_complex_signals():
"""Test complex signals with and without signature removal."""
bus1 = await MessageBus().connect()
bus2 = await MessageBus().connect()
await bus1.request_name("test.signals.name")
service_interface = ExampleInterface()
bus1.export("/test/path", service_interface)
obj = bus2.get_proxy_object(
"test.signals.name", "/test/path", bus1._introspect_export_path("/test/path")
)
interface = obj.get_interface(service_interface.name)
async def ping():
await bus2.call(
Message(
destination=bus1.unique_name,
interface="org.freedesktop.DBus.Peer",
path="/test/path",
member="Ping",
)
)
sig_handler_counter = 0
sig_handler_err = None
no_sig_handler_counter = 0
no_sig_handler_err = None
def complex_handler_with_sig(value):
nonlocal sig_handler_counter
nonlocal sig_handler_err
try:
assert value == {"hello": Variant("s", "world")}
sig_handler_counter += 1
except AssertionError as ex:
sig_handler_err = ex
def complex_handler_no_sig(value):
nonlocal no_sig_handler_counter
nonlocal no_sig_handler_err
try:
assert value == {"hello": "world"}
no_sig_handler_counter += 1
except AssertionError as ex:
no_sig_handler_err = ex
interface.on_signal_complex(complex_handler_with_sig)
interface.on_signal_complex(complex_handler_no_sig, unpack_variants=True)
await ping()
service_interface.SignalComplex()
await ping()
assert sig_handler_err is None
assert sig_handler_counter == 1
assert no_sig_handler_err is None
assert no_sig_handler_counter == 1
bus1.disconnect()
bus2.disconnect()
@pytest.mark.asyncio
async def test_varargs_callback():
"""Test varargs callback for signal."""
bus1 = await MessageBus().connect()
bus2 = await MessageBus().connect()
await bus1.request_name("test.signals.name")
service_interface = ExampleInterface()
bus1.export("/test/path", service_interface)
obj = bus2.get_proxy_object(
"test.signals.name", "/test/path", bus1._introspect_export_path("/test/path")
)
interface = obj.get_interface(service_interface.name)
async def ping():
await bus2.call(
Message(
destination=bus1.unique_name,
interface="org.freedesktop.DBus.Peer",
path="/test/path",
member="Ping",
)
)
varargs_handler_counter = 0
varargs_handler_err = None
varargs_plus_handler_counter = 0
varargs_plus_handler_err = None
def varargs_handler(*args):
nonlocal varargs_handler_counter
nonlocal varargs_handler_err
try:
assert args[0] == "hello"
varargs_handler_counter += 1
except AssertionError as ex:
varargs_handler_err = ex
def varargs_plus_handler(value, *_):
nonlocal varargs_plus_handler_counter
nonlocal varargs_plus_handler_err
try:
assert value == "hello"
varargs_plus_handler_counter += 1
except AssertionError as ex:
varargs_plus_handler_err = ex
interface.on_some_signal(varargs_handler)
interface.on_some_signal(varargs_plus_handler)
await ping()
service_interface.SomeSignal()
await ping()
assert varargs_handler_err is None
assert varargs_handler_counter == 1
assert varargs_plus_handler_err is None
assert varargs_plus_handler_counter == 1
bus1.disconnect()
bus2.disconnect()
@pytest.mark.asyncio
async def test_kwargs_callback():
"""Test callback for signal with kwargs."""
bus1 = await MessageBus().connect()
bus2 = await MessageBus().connect()
await bus1.request_name("test.signals.name")
service_interface = ExampleInterface()
bus1.export("/test/path", service_interface)
obj = bus2.get_proxy_object(
"test.signals.name", "/test/path", bus1._introspect_export_path("/test/path")
)
interface = obj.get_interface(service_interface.name)
async def ping():
await bus2.call(
Message(
destination=bus1.unique_name,
interface="org.freedesktop.DBus.Peer",
path="/test/path",
member="Ping",
)
)
kwargs_handler_counter = 0
kwargs_handler_err = None
kwarg_default_handler_counter = 0
kwarg_default_handler_err = None
def kwargs_handler(value, **_):
nonlocal kwargs_handler_counter
nonlocal kwargs_handler_err
try:
assert value == "hello"
kwargs_handler_counter += 1
except AssertionError as ex:
kwargs_handler_err = ex
def kwarg_default_handler(value, *, _=True):
nonlocal kwarg_default_handler_counter
nonlocal kwarg_default_handler_err
try:
assert value == "hello"
kwarg_default_handler_counter += 1
except AssertionError as ex:
kwarg_default_handler_err = ex
interface.on_some_signal(kwargs_handler)
interface.on_some_signal(kwarg_default_handler)
await ping()
service_interface.SomeSignal()
await ping()
assert kwargs_handler_err is None
assert kwargs_handler_counter == 1
assert kwarg_default_handler_err is None
assert kwarg_default_handler_counter == 1
def kwarg_bad_handler(value, *, bad_kwarg):
pass
with pytest.raises(TypeError):
interface.on_some_signal(kwarg_bad_handler)
bus1.disconnect()
bus2.disconnect()
@pytest.mark.asyncio
async def test_coro_callback():
"""Test callback for signal with a coroutine."""
bus1 = await MessageBus().connect()
bus2 = await MessageBus().connect()
await bus1.request_name("test.signals.name")
service_interface = ExampleInterface()
bus1.export("/test/path", service_interface)
obj = bus2.get_proxy_object(
"test.signals.name", "/test/path", bus1._introspect_export_path("/test/path")
)
interface = obj.get_interface(service_interface.name)
async def ping():
await bus2.call(
Message(
destination=bus1.unique_name,
interface="org.freedesktop.DBus.Peer",
path="/test/path",
member="Ping",
)
)
kwargs_handler_counter = 0
kwargs_handler_err = None
kwarg_default_handler_counter = 0
kwarg_default_handler_err = None
async def kwargs_handler(value, **_):
nonlocal kwargs_handler_counter
nonlocal kwargs_handler_err
try:
assert value == "hello"
kwargs_handler_counter += 1
except AssertionError as ex:
kwargs_handler_err = ex
async def kwarg_default_handler(value, *, _=True):
nonlocal kwarg_default_handler_counter
nonlocal kwarg_default_handler_err
try:
assert value == "hello"
kwarg_default_handler_counter += 1
except AssertionError as ex:
kwarg_default_handler_err = ex
interface.on_some_signal(kwargs_handler)
interface.on_some_signal(kwarg_default_handler)
await ping()
service_interface.SomeSignal()
await ping()
await asyncio.sleep(0)
assert kwargs_handler_err is None
assert kwargs_handler_counter == 1
assert kwarg_default_handler_err is None
assert kwarg_default_handler_counter == 1
def kwarg_bad_handler(value, *, bad_kwarg):
pass
with pytest.raises(TypeError):
interface.on_some_signal(kwarg_bad_handler)
bus1.disconnect()
bus2.disconnect()
@pytest.mark.asyncio
async def test_on_signal_type_error():
"""Test on callback raises type errors for invalid callbacks."""
bus1 = await MessageBus().connect()
bus2 = await MessageBus().connect()
await bus1.request_name("test.signals.name")
service_interface = ExampleInterface()
bus1.export("/test/path", service_interface)
obj = bus2.get_proxy_object(
"test.signals.name", "/test/path", bus1._introspect_export_path("/test/path")
)
interface = obj.get_interface(service_interface.name)
with pytest.raises(TypeError):
interface.on_some_signal("not_a_callable")
with pytest.raises(TypeError):
interface.on_some_signal(lambda a, b: "Too many parameters")
with pytest.raises(TypeError):
interface.on_some_signal(lambda: "Too few parameters")
with pytest.raises(TypeError):
interface.on_some_signal(lambda a, b, *args: "Too many before varargs")
bus1.disconnect()
bus2.disconnect()
@pytest.mark.asyncio
async def test_signals_with_changing_owners():
well_known_name = "test.signals.changing.name"
bus1 = await MessageBus().connect()
bus2 = await MessageBus().connect()
bus3 = await MessageBus().connect()
async def ping():
await bus1.call(
Message(
destination=bus1.unique_name,
interface="org.freedesktop.DBus.Peer",
path="/test/path",
member="Ping",
)
)
service_interface = ExampleInterface()
introspection = Node.default()
introspection.interfaces.append(service_interface.introspect())
# get the interface before export
obj = bus1.get_proxy_object(well_known_name, "/test/path", introspection)
iface = obj.get_interface("test.interface")
counter = 0
def handler(what):
nonlocal counter
counter += 1
iface.on_some_signal(handler)
await ping()
# now export and get the name
bus2.export("/test/path", service_interface)
result = await bus2.request_name(well_known_name)
assert result is RequestNameReply.PRIMARY_OWNER
# the signal should work
service_interface.SomeSignal()
await ping()
assert counter == 1
counter = 0
# now queue up a transfer of the name
service_interface2 = ExampleInterface()
bus3.export("/test/path", service_interface2)
result = await bus3.request_name(well_known_name)
assert result is RequestNameReply.IN_QUEUE
# if it doesn't own the name, the signal shouldn't work here
service_interface2.SomeSignal()
await ping()
assert counter == 0
# now transfer over the name and it should work
bus2.disconnect()
await ping()
service_interface2.SomeSignal()
await ping()
assert counter == 1
counter = 0
bus1.disconnect()
bus2.disconnect()
bus3.disconnect()
dbus-fast-2.44.1/tests/data/ 0000775 0000000 0000000 00000000000 14773556132 0015562 5 ustar 00root root 0000000 0000000 dbus-fast-2.44.1/tests/data/get_managed_objects.hex 0000664 0000000 0000000 00001635641 14773556132 0022254 0 ustar 00root root 0000000 0000000 6c020101809d030072056c003d00000006017300070000003a312e31373336000501750002000000080167000d617b6f617b73617b73767d7d7d00000000000007017300040000003a312e3400000000789d0300000000000a0000002f6f72672f626c75657a00007800000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000170000006f72672e626c75657a2e4167656e744d616e61676572310000000000190000006f72672e626c75657a2e50726f66696c654d616e616765723100000000000000000000000f0000002f6f72672f626c75657a2f6863693000ff040000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000120000006f72672e626c75657a2e416461707465723100006f03000000000000070000004164647265737300017300001100000030303a31413a37443a44413a37313a30340000000b00000041646472657373547970650001730000060000007075626c69630000040000004e616d65000173000d000000686f6d65617373697374616e7400000005000000416c696173000173000000000d000000686f6d65617373697374616e740000000000000005000000436c6173730001750000000000002c000000000007000000506f7765726564000162000001000000000000000c000000446973636f76657261626c65000162000000000013000000446973636f76657261626c6554696d656f75740001750000b4000000080000005061697261626c650001620000000000000000000f0000005061697261626c6554696d656f7574000175000000000000000000000b000000446973636f766572696e6700016200000100000005000000555549447300026173000000b50100002400000030303030313130652d303030302d313030302d383030302d303038303566396233346662000000002400000030303030313130612d303030302d313030302d383030302d303038303566396233346662000000002400000030303030313230302d303030302d313030302d383030302d303038303566396233346662000000002400000030303030313130622d303030302d313030302d383030302d303038303566396233346662000000002400000030303030313130382d303030302d313030302d383030302d303038303566396233346662000000002400000030303030313130632d303030302d313030302d383030302d303038303566396233346662000000002400000030303030313830302d303030302d313030302d383030302d303038303566396233346662000000002400000030303030313830312d303030302d313030302d383030302d303038303566396233346662000000002400000030303030313830612d303030302d313030302d383030302d303038303566396233346662000000002400000030303030313131322d303030302d313030302d383030302d3030383035663962333466620000000000000000080000004d6f64616c69617300017300130000007573623a7631443642703032343664303533460005000000526f6c6573000261730000001b0000000700000063656e7472616c000a0000007065726970686572616c00001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000160000006f72672e626c75657a2e476174744d616e6167657231000000000000100000006f72672e626c75657a2e4d6564696131000000000000000000000000180000006f72672e626c75657a2e4e6574776f726b536572766572310000000000000000000000001f0000006f72672e626c75657a2e4c454164766572746973696e674d616e616765723100870000000f000000416374697665496e7374616e636573000179000012000000537570706f72746564496e7374616e6365730001790005000000000011000000537570706f72746564496e636c75646573000261730000002f0000000800000074782d706f776572000000000a000000617070656172616e636500000a0000006c6f63616c2d6e616d650000250000002f6f72672f626c75657a2f686369302f6465765f31305f31465f45465f45355f34395f324500000020020000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000110000006f72672e626c75657a2e44657669636531000000a401000000000000070000004164647265737300017300001100000031303a31463a45463a45353a34393a32450000000b000000416464726573735479706500017300000600000072616e646f6d000005000000416c696173000173000000001100000031302d31462d45462d45352d34392d324500000006000000506169726564000162000000000000000000000007000000547275737465640001620000000000000000000007000000426c6f636b6564000162000000000000000000000d0000004c656761637950616972696e67000162000000000000000000000000040000005253534900016e00aaff000009000000436f6e6e65637465640001620000000000000000050000005555494473000261730000000000000000000000070000004164617074657200016f00000f0000002f6f72672f626c75657a2f686369300000000000100000004d616e756661637475726572446174610005617b71767d002700000006000261790000001b000000010f2002abd9b0f38e8e32c134801987f78703003aee68dde57466001000000053657276696365735265736f6c7665640001620000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000250000002f6f72672f626c75657a2f686369302f6465765f43425f36415f31325f45465f37455f413900000020020000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000110000006f72672e626c75657a2e44657669636531000000a401000000000000070000004164647265737300017300001100000043423a36413a31323a45463a37453a41390000000b000000416464726573735479706500017300000600000072616e646f6d000005000000416c696173000173000000001100000043422d36412d31322d45462d37452d413900000006000000506169726564000162000000000000000000000007000000547275737465640001620000000000000000000007000000426c6f636b6564000162000000000000000000000d0000004c656761637950616972696e67000162000000000000000000000000040000005253534900016e00adff000009000000436f6e6e65637465640001620000000000000000050000005555494473000261730000000000000000000000070000004164617074657200016f00000f0000002f6f72672f626c75657a2f686369300000000000100000004d616e756661637475726572446174610005617b71767d00270000004c000261790000001b00000012195075c129debb41163e049ade3f3f94f3498509a1bb70780045001000000053657276696365735265736f6c7665640001620000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000250000002f6f72672f626c75657a2f686369302f6465765f34395f46465f44395f35455f38445f313200000028020000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000110000006f72672e626c75657a2e44657669636531000000ac01000000000000070000004164647265737300017300001100000034393a46463a44393a35453a38443a31320000000b000000416464726573735479706500017300000600000072616e646f6d000005000000416c696173000173000000001100000034392d46462d44392d35452d38442d313200000006000000506169726564000162000000000000000000000007000000547275737465640001620000000000000000000007000000426c6f636b6564000162000000000000000000000d0000004c656761637950616972696e67000162000000000000000000000000040000005253534900016e00aaff000009000000436f6e6e65637465640001620000000000000000050000005555494473000261730000000000000000000000070000004164617074657200016f00000f0000002f6f72672f626c75657a2f686369300000000000100000004d616e756661637475726572446174610005617b71767d00140000004c00026179000000080000001006581d80929d8000000000070000005478506f77657200016e000007000000000000001000000053657276696365735265736f6c7665640001620000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000250000002f6f72672f626c75657a2f686369302f6465765f31335f38365f41365f42355f38425f304500000010020000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000110000006f72672e626c75657a2e446576696365310000009401000000000000070000004164647265737300017300001100000031333a38363a41363a42353a38423a30450000000b000000416464726573735479706500017300000600000072616e646f6d000005000000416c696173000173000000001100000031332d38362d41362d42352d38422d304500000006000000506169726564000162000000000000000000000007000000547275737465640001620000000000000000000007000000426c6f636b6564000162000000000000000000000d0000004c656761637950616972696e67000162000000000000000000000000040000005253534900016e00adff000009000000436f6e6e65637465640001620000000000000000050000005555494473000261730000000000000000000000070000004164617074657200016f00000f0000002f6f72672f626c75657a2f686369300000000000100000004d616e756661637475726572446174610005617b71767d00140000004c000261790000000800000009060385c0a8d3e4000000001000000053657276696365735265736f6c7665640001620000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000250000002f6f72672f626c75657a2f686369302f6465765f34325f38335f46395f44465f46425f444100000020020000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000110000006f72672e626c75657a2e44657669636531000000a401000000000000070000004164647265737300017300001100000034323a38333a46393a44463a46423a44410000000b000000416464726573735479706500017300000600000072616e646f6d000005000000416c696173000173000000001100000034322d38332d46392d44462d46422d444100000006000000506169726564000162000000000000000000000007000000547275737465640001620000000000000000000007000000426c6f636b6564000162000000000000000000000d0000004c656761637950616972696e67000162000000000000000000000000040000005253534900016e00aaff000009000000436f6e6e65637465640001620000000000000000050000005555494473000261730000000000000000000000070000004164617074657200016f00000f0000002f6f72672f626c75657a2f686369300000000000100000004d616e756661637475726572446174610005617b71767d00240000004c00026179000000180000000c0e0010214ca675ab775d9132fa401510067f1db9018a18000000001000000053657276696365735265736f6c7665640001620000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000250000002f6f72672f626c75657a2f686369302f6465765f45315f35315f45315f37385f38365f413800000008020000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000110000006f72672e626c75657a2e446576696365310000008c01000000000000070000004164647265737300017300001100000045313a35313a45313a37383a38363a41380000000b000000416464726573735479706500017300000600000072616e646f6d000005000000416c696173000173000000001100000045312d35312d45312d37382d38362d413800000006000000506169726564000162000000000000000000000007000000547275737465640001620000000000000000000007000000426c6f636b6564000162000000000000000000000d0000004c656761637950616972696e67000162000000000000000000000000040000005253534900016e00abff000009000000436f6e6e65637465640001620000000000000000050000005555494473000261730000000000000000000000070000004164617074657200016f00000f0000002f6f72672f626c75657a2f686369300000000000100000004d616e756661637475726572446174610005617b71767d00100000004c0002617900000004000000120200001000000053657276696365735265736f6c7665640001620000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000250000002f6f72672f626c75657a2f686369302f6465765f42345f45385f34325f44425f35365f354200000050020000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000110000006f72672e626c75657a2e44657669636531000000d401000000000000070000004164647265737300017300001100000042343a45383a34323a44423a35363a35420000000b00000041646472657373547970650001730000060000007075626c69630000040000004e616d6500017300140000004c45446e657457463031303039374442353635410000000005000000416c69617300017300000000140000004c45446e65745746303130303937444235363541000000000000000006000000506169726564000162000000000000000000000007000000547275737465640001620000000000000000000007000000426c6f636b6564000162000000000000000000000d0000004c656761637950616972696e67000162000000000000000000000000040000005253534900016e00b2ff000009000000436f6e6e65637465640001620000000000000000050000005555494473000261730000000000000000000000070000004164617074657200016f00000f0000002f6f72672f626c75657a2f686369300000000000100000004d616e756661637475726572446174610005617b71767d0027000000015a0261790000001b0000005202b4e842db565a00970b03010203040506070809a1a2a3a4a5a6001000000053657276696365735265736f6c7665640001620000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000250000002f6f72672f626c75657a2f686369302f6465765f34335f33335f41355f33455f42425f454400000028020000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000110000006f72672e626c75657a2e44657669636531000000ac01000000000000070000004164647265737300017300001100000034333a33333a41353a33453a42423a45440000000b000000416464726573735479706500017300000600000072616e646f6d000005000000416c696173000173000000001100000034332d33332d41352d33452d42422d454400000006000000506169726564000162000000000000000000000007000000547275737465640001620000000000000000000007000000426c6f636b6564000162000000000000000000000d0000004c656761637950616972696e67000162000000000000000000000000040000005253534900016e00b0ff000009000000436f6e6e65637465640001620000000000000000050000005555494473000261730000000000000000000000070000004164617074657200016f00000f0000002f6f72672f626c75657a2f686369300000000000100000004d616e756661637475726572446174610005617b71767d00140000004c000261790000000800000010060619a814a35800000000070000005478506f77657200016e000002000000000000001000000053657276696365735265736f6c7665640001620000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000250000002f6f72672f626c75657a2f686369302f6465765f35315f31345f35355f44315f37365f433100000028020000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000110000006f72672e626c75657a2e44657669636531000000ac01000000000000070000004164647265737300017300001100000035313a31343a35353a44313a37363a43310000000b000000416464726573735479706500017300000600000072616e646f6d000005000000416c696173000173000000001100000035312d31342d35352d44312d37362d433100000006000000506169726564000162000000000000000000000007000000547275737465640001620000000000000000000007000000426c6f636b6564000162000000000000000000000d0000004c656761637950616972696e67000162000000000000000000000000040000005253534900016e00b1ff000009000000436f6e6e65637465640001620000000000000000050000005555494473000261730000000000000000000000070000004164617074657200016f00000f0000002f6f72672f626c75657a2f686369300000000000100000004d616e756661637475726572446174610005617b71767d00140000004c000261790000000800000010060619a814a35800000000070000005478506f77657200016e000002000000000000001000000053657276696365735265736f6c7665640001620000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000250000002f6f72672f626c75657a2f686369302f6465765f30445f39465f45305f36335f46305f353600000010020000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000110000006f72672e626c75657a2e446576696365310000009401000000000000070000004164647265737300017300001100000030443a39463a45303a36333a46303a35360000000b000000416464726573735479706500017300000600000072616e646f6d000005000000416c696173000173000000001100000030442d39462d45302d36332d46302d353600000006000000506169726564000162000000000000000000000007000000547275737465640001620000000000000000000007000000426c6f636b6564000162000000000000000000000d0000004c656761637950616972696e67000162000000000000000000000000040000005253534900016e00b0ff000009000000436f6e6e65637465640001620000000000000000050000005555494473000261730000000000000000000000070000004164617074657200016f00000f0000002f6f72672f626c75657a2f686369300000000000100000004d616e756661637475726572446174610005617b71767d00140000004c00026179000000080000000906036fc0a8d326000000001000000053657276696365735265736f6c7665640001620000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000250000002f6f72672f626c75657a2f686369302f6465765f46415f31375f42365f32435f39385f314600000038020000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000110000006f72672e626c75657a2e44657669636531000000bc01000000000000070000004164647265737300017300001100000046413a31373a42363a32433a39383a31460000000b000000416464726573735479706500017300000600000072616e646f6d0000040000004e616d6500017300080000004641313742363243000000000000000005000000416c696173000173000000000800000046413137423632430000000006000000506169726564000162000000000000000000000007000000547275737465640001620000000000000000000007000000426c6f636b6564000162000000000000000000000d0000004c656761637950616972696e67000162000000000000000000000000040000005253534900016e00b3ff000009000000436f6e6e65637465640001620000000000000000050000005555494473000261730000000000000000000000070000004164617074657200016f00000f0000002f6f72672f626c75657a2f686369300000000000100000004d616e756661637475726572446174610005617b71767d0025000000330102617900000019000000011902ab00ab01be00c601d500c401ca00c401cf00000000000000001000000053657276696365735265736f6c7665640001620000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000250000002f6f72672f626c75657a2f686369302f6465765f36455f38465f46305f44425f44465f413200000028020000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000110000006f72672e626c75657a2e44657669636531000000ac01000000000000070000004164647265737300017300001100000036453a38463a46303a44423a44463a41320000000b000000416464726573735479706500017300000600000072616e646f6d000005000000416c696173000173000000001100000036452d38462d46302d44422d44462d413200000006000000506169726564000162000000000000000000000007000000547275737465640001620000000000000000000007000000426c6f636b6564000162000000000000000000000d0000004c656761637950616972696e67000162000000000000000000000000040000005253534900016e00b5ff000009000000436f6e6e65637465640001620000000000000000050000005555494473000261730000000000000000000000070000004164617074657200016f00000f0000002f6f72672f626c75657a2f686369300000000000100000004d616e756661637475726572446174610005617b71767d00170000004c000261790000000b0000000f05900032250c1002200400070000005478506f77657200016e000006000000000000001000000053657276696365735265736f6c7665640001620000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000250000002f6f72672f626c75657a2f686369302f6465765f32415f46325f46365f35455f44415f443400000020020000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000110000006f72672e626c75657a2e44657669636531000000a401000000000000070000004164647265737300017300001100000032413a46323a46363a35453a44413a44340000000b000000416464726573735479706500017300000600000072616e646f6d000005000000416c696173000173000000001100000032412d46322d46362d35452d44412d443400000006000000506169726564000162000000000000000000000007000000547275737465640001620000000000000000000007000000426c6f636b6564000162000000000000000000000d0000004c656761637950616972696e67000162000000000000000000000000040000005253534900016e00b4ff000009000000436f6e6e65637465640001620000000000000000050000005555494473000261730000000000000000000000070000004164617074657200016f00000f0000002f6f72672f626c75657a2f686369300000000000100000004d616e756661637475726572446174610005617b71767d00220000004c000261790000001600000009060325c0a8d172130c0acb212e8817a3010401030c0000000000001000000053657276696365735265736f6c7665640001620000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000250000002f6f72672f626c75657a2f686369302f6465765f37415f38465f45305f45315f34305f433700000050020000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000110000006f72672e626c75657a2e44657669636531000000d401000000000000070000004164647265737300017300001100000037413a38463a45303a45313a34303a43370000000b000000416464726573735479706500017300000600000072616e646f6d0000040000004e616d6500017300080000003966326164636632000000000000000005000000416c696173000173000000000800000039663261646366320000000006000000506169726564000162000000000000000000000007000000547275737465640001620000000000000000000007000000426c6f636b6564000162000000000000000000000d0000004c656761637950616972696e67000162000000000000000000000000040000005253534900016e00c9ff000009000000436f6e6e6563746564000162000000000000000005000000555549447300026173000000290000002400000033396436623333332d616461642d343563382d623665652d65616336633463643030303000000000070000004164617074657200016f00000f0000002f6f72672f626c75657a2f686369300000000000100000004d616e756661637475726572446174610005617b71767d0016000000f7030261790000000a0000001a0000000000486f6d6500001000000053657276696365735265736f6c7665640001620000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000250000002f6f72672f626c75657a2f686369302f6465765f44355f37365f39425f45425f41325f313100000020020000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000110000006f72672e626c75657a2e44657669636531000000a401000000000000070000004164647265737300017300001100000044353a37363a39423a45423a41323a31310000000b000000416464726573735479706500017300000600000072616e646f6d000005000000416c696173000173000000001100000044352d37362d39422d45422d41322d313100000006000000506169726564000162000000000000000000000007000000547275737465640001620000000000000000000007000000426c6f636b6564000162000000000000000000000d0000004c656761637950616972696e67000162000000000000000000000000040000005253534900016e00abff000009000000436f6e6e65637465640001620000000000000000050000005555494473000261730000000000000000000000070000004164617074657200016f00000f0000002f6f72672f626c75657a2f686369300000000000100000004d616e756661637475726572446174610005617b71767d00270000004c000261790000001b0000001219504890337fccd1171fe530454c57d260c7ac20f8f9478d0211001000000053657276696365735265736f6c7665640001620000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000250000002f6f72672f626c75657a2f686369302f6465765f36465f30375f39335f35455f35305f4544000000a0020000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000110000006f72672e626c75657a2e446576696365310000002402000000000000070000004164647265737300017300001100000036463a30373a39333a35453a35303a45440000000b000000416464726573735479706500017300000600000072616e646f6d000005000000416c696173000173000000001100000036462d30372d39332d35452d35302d454400000006000000506169726564000162000000000000000000000007000000547275737465640001620000000000000000000007000000426c6f636b6564000162000000000000000000000d0000004c656761637950616972696e67000162000000000000000000000000040000005253534900016e00afff000009000000436f6e6e6563746564000162000000000000000005000000555549447300026173000000290000002400000030303030666539662d303030302d313030302d383030302d30303830356639623334666200000000070000004164617074657200016f00000f0000002f6f72672f626c75657a2f686369300000000000100000004d616e756661637475726572446174610005617b71767d0012000000e000026179000000060000000145ca9ed45d0000000000000b00000053657276696365446174610005617b73767d000048000000000000002400000030303030666539662d303030302d313030302d383030302d3030383035663962333466620002617900000000140000000255795366316e5a796a347700000184435ed85c1000000053657276696365735265736f6c7665640001620000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000250000002f6f72672f626c75657a2f686369302f6465765f30415f37445f43325f32375f37455f364600000068020000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000110000006f72672e626c75657a2e44657669636531000000ec01000000000000070000004164647265737300017300001100000030413a37443a43323a32373a37453a36460000000b000000416464726573735479706500017300000600000072616e646f6d000005000000416c696173000173000000001100000030412d37442d43322d32372d37452d364600000006000000506169726564000162000000000000000000000007000000547275737465640001620000000000000000000007000000426c6f636b6564000162000000000000000000000d0000004c656761637950616972696e67000162000000000000000000000000040000005253534900016e00aaff000009000000436f6e6e6563746564000162000000000000000005000000555549447300026173000000290000002400000030303030666436662d303030302d313030302d383030302d30303830356639623334666200000000070000004164617074657200016f00000f0000002f6f72672f626c75657a2f6863693000000000000b00000053657276696365446174610005617b73767d000048000000000000002400000030303030666436662d303030302d313030302d383030302d30303830356639623334666200026179000000001400000064edc902d73adc4230c61b06978426a71dd9c2c71000000053657276696365735265736f6c7665640001620000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000250000002f6f72672f626c75657a2f686369302f6465765f36365f34365f34395f37305f44435f363000000028020000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000110000006f72672e626c75657a2e44657669636531000000ac01000000000000070000004164647265737300017300001100000036363a34363a34393a37303a44433a36300000000b000000416464726573735479706500017300000600000072616e646f6d000005000000416c696173000173000000001100000036362d34362d34392d37302d44432d363000000006000000506169726564000162000000000000000000000007000000547275737465640001620000000000000000000007000000426c6f636b6564000162000000000000000000000d0000004c656761637950616972696e67000162000000000000000000000000040000005253534900016e00abff000009000000436f6e6e65637465640001620000000000000000050000005555494473000261730000000000000000000000070000004164617074657200016f00000f0000002f6f72672f626c75657a2f686369300000000000100000004d616e756661637475726572446174610005617b71767d00150000004c00026179000000090000001007361f53834a3118000000070000005478506f77657200016e000007000000000000001000000053657276696365735265736f6c7665640001620000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000250000002f6f72672f626c75657a2f686369302f6465765f45435f31325f38375f44435f32395f314200000008020000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000110000006f72672e626c75657a2e446576696365310000008c01000000000000070000004164647265737300017300001100000045433a31323a38373a44433a32393a31420000000b000000416464726573735479706500017300000600000072616e646f6d000005000000416c696173000173000000001100000045432d31322d38372d44432d32392d314200000006000000506169726564000162000000000000000000000007000000547275737465640001620000000000000000000007000000426c6f636b6564000162000000000000000000000d0000004c656761637950616972696e67000162000000000000000000000000040000005253534900016e00b0ff000009000000436f6e6e65637465640001620000000000000000050000005555494473000261730000000000000000000000070000004164617074657200016f00000f0000002f6f72672f626c75657a2f686369300000000000100000004d616e756661637475726572446174610005617b71767d00100000004c0002617900000004000000120200001000000053657276696365735265736f6c7665640001620000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000250000002f6f72672f626c75657a2f686369302f6465765f35345f36445f45335f41465f33425f324300000020020000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000110000006f72672e626c75657a2e44657669636531000000a401000000000000070000004164647265737300017300001100000035343a36443a45333a41463a33423a32430000000b000000416464726573735479706500017300000600000072616e646f6d000005000000416c696173000173000000001100000035342d36442d45332d41462d33422d324300000006000000506169726564000162000000000000000000000007000000547275737465640001620000000000000000000007000000426c6f636b6564000162000000000000000000000d0000004c656761637950616972696e67000162000000000000000000000000040000005253534900016e00c5ff000009000000436f6e6e65637465640001620000000000000000050000005555494473000261730000000000000000000000070000004164617074657200016f00000f0000002f6f72672f626c75657a2f686369300000000000100000004d616e756661637475726572446174610005617b71767d00100000004c000261790000000400000010020200070000005478506f77657200016e000004000000000000001000000053657276696365735265736f6c7665640001620000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000250000002f6f72672f626c75657a2f686369302f6465765f45445f45445f32355f44345f44335f463100000080020000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000110000006f72672e626c75657a2e446576696365310000000402000000000000070000004164647265737300017300001100000045443a45443a32353a44343a44333a46310000000b000000416464726573735479706500017300000600000072616e646f6d0000040000004e616d65000173001200000038343642323146464141443033334139453900000000000005000000416c6961730001730000000012000000383436423231464641414430333341394539000006000000506169726564000162000000000000000000000007000000547275737465640001620000000000000000000007000000426c6f636b6564000162000000000000000000000d0000004c656761637950616972696e67000162000000000000000000000000040000005253534900016e00b5ff000009000000436f6e6e6563746564000162000000000000000005000000555549447300026173000000290000002400000030303030666530372d303030302d313030302d383030302d30303830356639623334666200000000070000004164617074657200016f00000f0000002f6f72672f626c75657a2f686369300000000000100000004d616e756661637475726572446174610005617b71767d0019000000a7050261790000000d000000051001000000000000012200ca00000000000000070000005478506f77657200016e000000000000000000001000000053657276696365735265736f6c7665640001620000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000250000002f6f72672f626c75657a2f686369302f6465765f32415f31365f31325f34415f34365f394300000010020000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000110000006f72672e626c75657a2e446576696365310000009401000000000000070000004164647265737300017300001100000032413a31363a31323a34413a34363a39430000000b000000416464726573735479706500017300000600000072616e646f6d000005000000416c696173000173000000001100000032412d31362d31322d34412d34362d394300000006000000506169726564000162000000000000000000000007000000547275737465640001620000000000000000000007000000426c6f636b6564000162000000000000000000000d0000004c656761637950616972696e67000162000000000000000000000000040000005253534900016e00beff000009000000436f6e6e65637465640001620000000000000000050000005555494473000261730000000000000000000000070000004164617074657200016f00000f0000002f6f72672f626c75657a2f686369300000000000100000004d616e756661637475726572446174610005617b71767d00140000004c00026179000000080000000906030bc0a8d16f000000001000000053657276696365735265736f6c7665640001620000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000250000002f6f72672f626c75657a2f686369302f6465765f31435f42335f43395f31315f31395f323200000028020000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000110000006f72672e626c75657a2e44657669636531000000ac01000000000000070000004164647265737300017300001100000031433a42333a43393a31313a31393a32320000000b00000041646472657373547970650001730000060000007075626c6963000005000000416c696173000173000000001100000031432d42332d43392d31312d31392d323200000006000000506169726564000162000000000000000000000007000000547275737465640001620000000000000000000007000000426c6f636b6564000162000000000000000000000d0000004c656761637950616972696e67000162000000000000000000000000040000005253534900016e00c4ff000009000000436f6e6e65637465640001620000000000000000050000005555494473000261730000000000000000000000070000004164617074657200016f00000f0000002f6f72672f626c75657a2f686369300000000000100000004d616e756661637475726572446174610005617b71767d00130000004c000261790000000700000010050e1040c47d0000000000070000005478506f77657200016e000004000000000000001000000053657276696365735265736f6c7665640001620000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000250000002f6f72672f626c75657a2f686369302f6465765f41345f43315f33385f31415f35375f373600000028020000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000110000006f72672e626c75657a2e44657669636531000000ac01000000000000070000004164647265737300017300001100000041343a43313a33383a31413a35373a37360000000b00000041646472657373547970650001730000060000007075626c69630000040000004e616d650001730004000000543330310000000005000000416c696173000173000000000400000054333031000000000000000006000000506169726564000162000000000000000000000007000000547275737465640001620000000000000000000007000000426c6f636b6564000162000000000000000000000d0000004c656761637950616972696e67000162000000000000000000000000040000005253534900016e00afff000009000000436f6e6e65637465640001620000000000000000050000005555494473000261730000000000000000000000070000004164617074657200016f00000f0000002f6f72672f626c75657a2f686369300000000000100000004d616e756661637475726572446174610005617b71767d001d00000055aa026179000000110000000105a4c1381a5776010707ee15184800010000001000000053657276696365735265736f6c7665640001620000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000250000002f6f72672f626c75657a2f686369302f6465765f41345f43315f33385f31325f44365f464200000078020000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000110000006f72672e626c75657a2e44657669636531000000fc01000000000000070000004164647265737300017300001100000041343a43313a33383a31323a44363a46420000000b00000041646472657373547970650001730000060000007075626c69630000040000004e616d6500017300090000004235313738443646420000000000000005000000416c696173000173000000000900000042353137384436464200000006000000506169726564000162000000000000000000000007000000547275737465640001620000000000000000000007000000426c6f636b6564000162000000000000000000000d0000004c656761637950616972696e67000162000000000000000000000000040000005253534900016e00cdff000009000000436f6e6e6563746564000162000000000000000005000000555549447300026173000000290000002400000030303030656338382d303030302d313030302d383030302d30303830356639623334666200000000070000004164617074657200016f00000f0000002f6f72672f626c75657a2f686369300000000000100000004d616e756661637475726572446174610005617b71767d003b00000001000261790000000900000001010103fac24600050000004c00026179000000170000000215494e54454c4c495f524f434b535f48575075f2ffc200000000001000000053657276696365735265736f6c7665640001620000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000250000002f6f72672f626c75657a2f686369302f6465765f41345f43315f33385f45445f32375f363200000080020000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000110000006f72672e626c75657a2e446576696365310000000402000000000000070000004164647265737300017300001100000041343a43313a33383a45443a32373a36320000000b00000041646472657373547970650001730000060000007075626c69630000040000004e616d65000173000c000000475648353037355f323736320000000005000000416c696173000173000000000c000000475648353037355f32373632000000000000000006000000506169726564000162000000000000000000000007000000547275737465640001620000000000000000000007000000426c6f636b6564000162000000000000000000000d0000004c656761637950616972696e67000162000000000000000000000000040000005253534900016e00b3ff000009000000436f6e6e6563746564000162000000000000000005000000555549447300026173000000290000002400000030303030656338382d303030302d313030302d383030302d30303830356639623334666200000000070000004164617074657200016f00000f0000002f6f72672f626c75657a2f686369300000000000100000004d616e756661637475726572446174610005617b71767d003b00000088ec0261790000000600000000030b185a000000000000004c00026179000000170000000215494e54454c4c495f524f434b535f48575075f2ff0c00000000001000000053657276696365735265736f6c7665640001620000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000250000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f3643000000c0030000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000110000006f72672e626c75657a2e446576696365310000004403000000000000070000004164647265737300017300001100000044303a37323a30453a34423a37463a36430000000b000000416464726573735479706500017300000600000072616e646f6d0000040000004e616d65000173000e00000057656d6f20537461676520303633000005000000416c696173000173000000000e00000057656d6f2053746167652030363300000000000006000000506169726564000162000000000000000000000007000000547275737465640001620000000000000000000007000000426c6f636b6564000162000000000000000000000d0000004c656761637950616972696e67000162000000000000000000000000040000005253534900016e00d4ff000009000000436f6e6e6563746564000162000000000000000005000000555549447300026173000000890100002400000030303030303033652d303030302d313030302d383030302d303032366262373635323931000000002400000030303030303035352d303030302d313030302d383030302d303032366262373635323931000000002400000030303030303038392d303030302d313030302d383030302d303032366262373635323931000000002400000030303030303039362d303030302d313030302d383030302d303032366262373635323931000000002400000030303030303061322d303030302d313030302d383030302d303032366262373635323931000000002400000030303030303063632d303030302d313030302d383030302d303032366262373635323931000000002400000030303030303132392d303030302d313030302d383030302d303032366262373635323931000000002400000030303030303233362d303030302d313030302d383030302d303032366262373635323931000000002400000030303030313830302d303030302d313030302d383030302d30303830356639623334666200000000070000004164617074657200016f00000f0000002f6f72672f626c75657a2f686369300000000000100000004d616e756661637475726572446174610005617b71767d001f0000004c000261790000001300000006310042154cf4b9de0f0063000102b533e54f001000000053657276696365735265736f6c7665640001620000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000310000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303039320000002001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000160000006f72672e626c75657a2e4761747453657276696365310000a80000000400000055554944000173002400000030303030303132392d303030302d313030302d383030302d303032366262373635323931000000000600000044657669636500016f000000250000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f364300000000000000070000005072696d6172790001620000010000000000000008000000496e636c756465730002616f00000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303039322f636861723030613400008801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000010100000400000055554944000173002400000030303030303133392d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303039320000000500000056616c7565000261790000001c000000d5b017879b0b3af2bd6e864f4b9445b35c8547af26c3517f1711d129090000004e6f74696679696e67000162000000000000000005000000466c616773000261730000002500000004000000726561640000000005000000777269746500000008000000696e64696361746500000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303039322f63686172303061342f6465736330306137002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303039322f636861723030613400000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303039322f63686172303061342f6465736330306136002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000030303030323930322d303030302d313030302d383030302d303038303566396233346662000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303039322f636861723030613400000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303039322f636861723030613100004801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000c20000000400000055554944000173002400000030303030303133382d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303039320000000500000056616c756500026179000000000000000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303039322f63686172303061312f6465736330306133002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303039322f636861723030613100000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303039322f636861723030396500006001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000da0000000400000055554944000173002400000030303030303033372d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303039320000000500000056616c7565000261790000001a000000ad14ff1e719e773d8b9546fee0f3b2866948726ca8ec673127ba000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303039322f63686172303039652f6465736330306130002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303039322f636861723030396500000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303039322f636861723030396200004801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000c20000000400000055554944000173002400000030303030303133312d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303039320000000500000056616c756500026179000000000000000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303039322f63686172303039622f6465736330303964002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303039322f636861723030396200000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303039322f636861723030393800006801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000e20000000400000055554944000173002400000030303030303133302d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303039320000000500000056616c756500026179000000220000007ce0e39be3df9a1872be3508d6285cf9b3a89c1c944474d8574a8de5f79544212e78000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303039322f63686172303039382f6465736330303961002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303039322f636861723030393800000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303039322f636861723030393500004801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000c20000000400000055554944000173002400000030303030303061352d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303039320000000500000056616c756500026179000000000000000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303039322f63686172303039352f6465736330303937002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303039322f636861723030393500000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303039322f636861723030393300003801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000b50000000400000055554944000173002400000065363034653935642d613735392d343831372d383764332d61613030353038336130643100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303039320000000500000056616c756500026179000000000000000000000005000000466c61677300026173000000090000000400000072656164000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000310000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303038340000002001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000160000006f72672e626c75657a2e4761747453657276696365310000a80000000400000055554944000173002400000030303030303233362d303030302d313030302d383030302d303032366262373635323931000000000600000044657669636500016f000000250000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f364300000000000000070000005072696d6172790001620000010000000000000008000000496e636c756465730002616f00000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303038342f636861723030386500009001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000090100000400000055554944000173002400000030303030303233352d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303038340000000500000056616c7565000261790000001e00000067ad136eceff732d130fdd259fd34caa0974749658745b2776a536ed0757000000000000090000004e6f74696679696e67000162000000000000000005000000466c616773000261730000002500000004000000726561640000000005000000777269746500000008000000696e64696361746500000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303038342f63686172303038652f6465736330303931002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303038342f636861723030386500000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303038342f63686172303038652f6465736330303930002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000030303030323930322d303030302d313030302d383030302d303038303566396233346662000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303038342f636861723030386500000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303038342f636861723030386100009001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000090100000400000055554944000173002400000030303030303233342d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303038340000000500000056616c7565000261790000001d000000847fb53cc7fe03a5fd2f6a3c1a286d07afff9f80b0deaf3d4a99b19a6d00000000000000090000004e6f74696679696e67000162000000000000000005000000466c616773000261730000002500000004000000726561640000000005000000777269746500000008000000696e64696361746500000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303038342f63686172303038612f6465736330303864002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303038342f636861723030386100000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303038342f63686172303038612f6465736330303863002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000030303030323930322d303030302d313030302d383030302d303038303566396233346662000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303038342f636861723030386100000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303038342f636861723030383700004801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000c20000000400000055554944000173002400000030303030303061352d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303038340000000500000056616c756500026179000000000000000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303038342f63686172303038372f6465736330303839002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303038342f636861723030383700000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303038342f636861723030383500003801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000b50000000400000055554944000173002400000065363034653935642d613735392d343831372d383764332d61613030353038336130643100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303038340000000500000056616c756500026179000000000000000000000005000000466c61677300026173000000090000000400000072656164000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000310000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303037360000002001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000160000006f72672e626c75657a2e4761747453657276696365310000a80000000400000055554944000173002400000030303030303039362d303030302d313030302d383030302d303032366262373635323931000000000600000044657669636500016f000000250000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f364300000000000000070000005072696d6172790001620000010000000000000008000000496e636c756465730002616f00000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303037362f636861723030383100006801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000e20000000400000055554944000173002400000030303030303032332d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303037360000000500000056616c7565000261790000001e000000a9de36c64b727b6fe27bf95c09557de53c621a65d3c80450730cc15e762b00000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303037362f63686172303038312f6465736330303833002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303037362f636861723030383100000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303037362f636861723030376400008801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000010100000400000055554944000173002400000030303030303037392d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303037360000000500000056616c756500026179000000180000006b4e4ec7f908a5cba38372b9dbdd5922d03f2c4e2891f25800000000090000004e6f74696679696e67000162000000000000000005000000466c616773000261730000002500000004000000726561640000000005000000777269746500000008000000696e64696361746500000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303037362f63686172303037642f6465736330303830002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303037362f636861723030376400000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303037362f63686172303037642f6465736330303766002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000030303030323930322d303030302d313030302d383030302d303038303566396233346662000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303037362f636861723030376400000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303037362f636861723030373900008801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000010100000400000055554944000173002400000030303030303036382d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303037360000000500000056616c75650002617900000018000000536f356f279e1733fdeefec426b73cf92d99305086e9f17300000000090000004e6f74696679696e67000162000000000000000005000000466c616773000261730000002500000004000000726561640000000005000000777269746500000008000000696e64696361746500000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303037362f63686172303037392f6465736330303763002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303037362f636861723030373900000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303037362f63686172303037392f6465736330303762002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000030303030323930322d303030302d313030302d383030302d303038303566396233346662000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303037362f636861723030373900000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303037362f636861723030373700003801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000b50000000400000055554944000173002400000065363034653935642d613735392d343831372d383764332d61613030353038336130643100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303037360000000500000056616c756500026179000000000000000000000005000000466c61677300026173000000090000000400000072656164000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000310000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303036360000002001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000160000006f72672e626c75657a2e4761747453657276696365310000a80000000400000055554944000173002400000030303030303038392d303030302d313030302d383030302d303032366262373635323931000000000600000044657669636500016f000000250000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f364300000000000000070000005072696d6172790001620000010000000000000008000000496e636c756465730002616f00000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303036362f636861723030373300006001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000da0000000400000055554944000173002400000030303030303063622d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303036360000000500000056616c75650002617900000018000000049d0c3c192f7343003107e73be7d4f95a372af3df3d66c90000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303036362f63686172303037332f6465736330303735002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a6000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303036362f636861723030373300000500000056616c75650002617900000002000000640000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303036362f636861723030366600008801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000010100000400000055554944000173002400000030303030303037332d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303036360000000500000056616c7565000261790000001c0000002fd32cdcac5c1454fe1b44ef67bbcd89805b4b687e4192bceaaef783090000004e6f74696679696e67000162000000000000000005000000466c616773000261730000002500000004000000726561640000000005000000777269746500000008000000696e64696361746500000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303036362f63686172303036662f6465736330303732002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a6000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303036362f636861723030366600000500000056616c75650002617900000002000000630000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303036362f63686172303036662f6465736330303731002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000030303030323930322d303030302d313030302d383030302d303038303566396233346662000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303036362f636861723030366600000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303036362f636861723030366300008001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000fa0000000400000055554944000173002400000030303030303032332d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303036360000000500000056616c756500026179000000360000008b777440ace1de1ac5ec4cf604f13f0ed6511bf96661a20ab07fef5fae73f4d9a4c3ecb4b2482d9e0b4e2e6f9da411a5d1f47e5f31b800000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303036362f63686172303036632f6465736330303665002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a6000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303036362f636861723030366300000500000056616c75650002617900000002000000620000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303036362f636861723030363900004801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000c20000000400000055554944000173002400000030303030303061352d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303036360000000500000056616c756500026179000000000000000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303036362f63686172303036392f6465736330303662002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303036362f636861723030363900000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303036362f636861723030363700003801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000b50000000400000055554944000173002400000065363034653935642d613735392d343831372d383764332d61613030353038336130643100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303036360000000500000056616c756500026179000000000000000000000005000000466c61677300026173000000090000000400000072656164000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000310000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303035360000002001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000160000006f72672e626c75657a2e4761747453657276696365310000a80000000400000055554944000173002400000030303030303038392d303030302d313030302d383030302d303032366262373635323931000000000600000044657669636500016f000000250000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f364300000000000000070000005072696d6172790001620000010000000000000008000000496e636c756465730002616f00000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303035362f636861723030363300006001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000da0000000400000055554944000173002400000030303030303063622d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303035360000000500000056616c756500026179000000180000009deaedc82ab8fb127d2014e823cd93fe5c4eaaeb5f80117d0000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303035362f63686172303036332f6465736330303635002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a6000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303035362f636861723030363300000500000056616c75650002617900000002000000540000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303035362f636861723030356600008801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000010100000400000055554944000173002400000030303030303037332d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303035360000000500000056616c7565000261790000001c0000004bdf0b05f0d9e6127a20d743ff2bb6125fb5d7848cb8313dffbe6d2c090000004e6f74696679696e67000162000000000000000005000000466c616773000261730000002500000004000000726561640000000005000000777269746500000008000000696e64696361746500000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303035362f63686172303035662f6465736330303632002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a6000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303035362f636861723030356600000500000056616c75650002617900000002000000530000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303035362f63686172303035662f6465736330303631002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000030303030323930322d303030302d313030302d383030302d303038303566396233346662000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303035362f636861723030356600000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303035362f636861723030356300008001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000fa0000000400000055554944000173002400000030303030303032332d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303035360000000500000056616c75650002617900000036000000ac47653d40f34ab0d6db002d56d92da92eb5dc2e77feecb5c2a0e30ef07d10888b7f7534751d6cdf2e2d128f455fbc92adc171534c7700000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303035362f63686172303035632f6465736330303565002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a6000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303035362f636861723030356300000500000056616c75650002617900000002000000520000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303035362f636861723030353900004801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000c20000000400000055554944000173002400000030303030303061352d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303035360000000500000056616c756500026179000000000000000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303035362f63686172303035392f6465736330303562002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303035362f636861723030353900000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303035362f636861723030353700003801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000b50000000400000055554944000173002400000065363034653935642d613735392d343831372d383764332d61613030353038336130643100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303035360000000500000056616c756500026179000000000000000000000005000000466c61677300026173000000090000000400000072656164000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000310000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303034360000002001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000160000006f72672e626c75657a2e4761747453657276696365310000a80000000400000055554944000173002400000030303030303038392d303030302d313030302d383030302d303032366262373635323931000000000600000044657669636500016f000000250000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f364300000000000000070000005072696d6172790001620000010000000000000008000000496e636c756465730002616f00000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303034362f636861723030353300006001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000da0000000400000055554944000173002400000030303030303063622d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303034360000000500000056616c75650002617900000018000000533044670d2038a235f96446a90c1bcc4d4cc1bc2f6845770000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303034362f63686172303035332f6465736330303535002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a6000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303034362f636861723030353300000500000056616c75650002617900000002000000440000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303034362f636861723030346600008801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000010100000400000055554944000173002400000030303030303037332d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303034360000000500000056616c756500026179000000170000000d99e75cc6f9eefd3d491c603ee0b0d8921da85ac433630000000000090000004e6f74696679696e67000162000000000000000005000000466c616773000261730000002500000004000000726561640000000005000000777269746500000008000000696e64696361746500000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303034362f63686172303034662f6465736330303532002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a6000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303034362f636861723030346600000500000056616c75650002617900000002000000430000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303034362f63686172303034662f6465736330303531002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000030303030323930322d303030302d313030302d383030302d303038303566396233346662000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303034362f636861723030346600000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303034362f636861723030346300008001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000fa0000000400000055554944000173002400000030303030303032332d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303034360000000500000056616c756500026179000000360000000f3bb1b485243439fd1f4fa5e7d5b801b8fe61fc80baaf9f63e4f76af0f7178943282eed8aefd0a728ce0a13fea2ccd318980990bac400000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303034362f63686172303034632f6465736330303465002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a6000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303034362f636861723030346300000500000056616c75650002617900000002000000420000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303034362f636861723030343900004801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000c20000000400000055554944000173002400000030303030303061352d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303034360000000500000056616c756500026179000000000000000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303034362f63686172303034392f6465736330303462002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303034362f636861723030343900000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303034362f636861723030343700003801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000b50000000400000055554944000173002400000065363034653935642d613735392d343831372d383764332d61613030353038336130643100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303034360000000500000056616c756500026179000000000000000000000005000000466c61677300026173000000090000000400000072656164000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000310000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303033640000002001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000160000006f72672e626c75657a2e4761747453657276696365310000a80000000400000055554944000173002400000030303030303063632d303030302d313030302d383030302d303032366262373635323931000000000600000044657669636500016f000000250000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f364300000000000000070000005072696d6172790001620000010000000000000008000000496e636c756465730002616f00000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303033642f636861723030343300006001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000da0000000400000055554944000173002400000030303030303063642d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303033640000000500000056616c75650002617900000018000000156e709a979ec0d41dd55d0802864b1d1a5e9f335a1dd5060000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303033642f63686172303034332f6465736330303435002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303033642f636861723030343300000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303033642f636861723030343000004801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000c20000000400000055554944000173002400000030303030303061352d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303033640000000500000056616c756500026179000000000000000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303033642f63686172303034302f6465736330303432002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303033642f636861723030343000000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303033642f636861723030336500003801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000b50000000400000055554944000173002400000065363034653935642d613735392d343831372d383764332d61613030353038336130643100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303033640000000500000056616c756500026179000000000000000000000005000000466c61677300026173000000090000000400000072656164000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000310000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303032650000002001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000160000006f72672e626c75657a2e4761747453657276696365310000a80000000400000055554944000173002400000030303030303035352d303030302d313030302d383030302d303032366262373635323931000000000600000044657669636500016f000000250000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f364300000000000000070000005072696d6172790001620000010000000000000008000000496e636c756465730002616f00000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303032652f636861723030336100004801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000c20000000400000055554944000173002400000030303030303035302d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303032650000000500000056616c756500026179000000000000000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303032652f63686172303033612f6465736330303363002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303032652f636861723030336100000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303032652f636861723030333700004801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000c20000000400000055554944000173002400000030303030303034662d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303032650000000500000056616c756500026179000000000000000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303032652f63686172303033372f6465736330303339002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303032652f636861723030333700000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303032652f636861723030333400005001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000ca0000000400000055554944000173002400000030303030303034652d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303032650000000500000056616c7565000261790000000a00000002080005000103060104000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303032652f63686172303033342f6465736330303336002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a6000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303032652f636861723030333400000500000056616c75650002617900000002000000230000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303032652f636861723030333100004801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000c20000000400000055554944000173002400000030303030303034632d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303032650000000500000056616c756500026179000000000000000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303032652f63686172303033312f6465736330303333002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303032652f636861723030333100000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303032652f636861723030326600003801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000b50000000400000055554944000173002400000065363034653935642d613735392d343831372d383764332d61613030353038336130643100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303032650000000500000056616c756500026179000000000000000000000005000000466c61677300026173000000090000000400000072656164000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000310000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303032350000002001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000160000006f72672e626c75657a2e4761747453657276696365310000a80000000400000055554944000173002400000030303030303061322d303030302d313030302d383030302d303032366262373635323931000000000600000044657669636500016f000000250000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f364300000000000000070000005072696d6172790001620000010000000000000008000000496e636c756465730002616f00000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303032352f636861723030326200006001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000da0000000400000055554944000173002400000030303030303033372d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303032350000000500000056616c7565000261790000001c000000547f62b362940b982c779db50ff9257f04feee0cc0adb9a18dd92df005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303032352f63686172303032622f6465736330303264002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303032352f636861723030326200000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303032352f636861723030323800009001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e476174744368617261637465726973746963310000000a0100000400000055554944000173002400000030303030303061352d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303032350000000500000056616c75650002617900000046000000dcd522b625a8c030c786c89102d997f3ebb53182d14a7b0afdcb7386a939ac51a028e2b610ad827dd6f05d805b6885327ddc2cdf4a13fe2aba80181558a4863c77b4ab55ea3a00000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303032352f63686172303032382f6465736330303261002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303032352f636861723030323800000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303032352f636861723030323600003801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000b50000000400000055554944000173002400000065363034653935642d613735392d343831372d383764332d61613030353038336130643100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303032350000000500000056616c756500026179000000000000000000000005000000466c61677300026173000000090000000400000072656164000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000310000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303030360000002001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000160000006f72672e626c75657a2e4761747453657276696365310000a80000000400000055554944000173002400000030303030303033652d303030302d313030302d383030302d303032366262373635323931000000000600000044657669636500016f000000250000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f364300000000000000070000005072696d6172790001620000010000000000000008000000496e636c756465730002616f00000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303030362f636861723030323200004801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000c20000000400000055554944000173002400000030303030303232302d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303030360000000500000056616c756500026179000000000000000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303030362f63686172303032322f6465736330303234002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303030362f636861723030323200000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303030362f636861723030316600004801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000c20000000400000055554944000173002400000033346162383831312d616337662d343334302d626163332d66643661383566393934336200000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303030360000000500000056616c756500026179000000000000000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303030362f63686172303031662f6465736330303231002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303030362f636861723030316600000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303030362f636861723030316300004801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000c20000000400000055554944000173002400000030303030303035332d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303030360000000500000056616c756500026179000000000000000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303030362f63686172303031632f6465736330303165002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303030362f636861723030316300000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303030362f636861723030313800007001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000e90000000400000055554944000173002400000030303030303035322d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303030360000000500000056616c7565000261790000000000000000000000090000004e6f74696679696e67000162000000000000000005000000466c616773000261730000002500000004000000726561640000000005000000777269746500000008000000696e64696361746500000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303030362f63686172303031382f6465736330303162002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303030362f636861723030313800000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303030362f63686172303031382f6465736330303161002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000030303030323930322d303030302d313030302d383030302d303038303566396233346662000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303030362f636861723030313800000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303030362f636861723030313500004801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000c20000000400000055554944000173002400000030303030303033302d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303030360000000500000056616c756500026179000000000000000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303030362f63686172303031352f6465736330303137002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303030362f636861723030313500000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303030362f636861723030313200004801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000c20000000400000055554944000173002400000030303030303032332d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303030360000000500000056616c756500026179000000000000000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303030362f63686172303031322f6465736330303134002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303030362f636861723030313200000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303030362f636861723030306600004801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000c20000000400000055554944000173002400000030303030303032312d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303030360000000500000056616c756500026179000000000000000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303030362f63686172303030662f6465736330303131002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303030362f636861723030306600000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303030362f636861723030306300004801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000c20000000400000055554944000173002400000030303030303032302d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303030360000000500000056616c756500026179000000000000000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303030362f63686172303030632f6465736330303065002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303030362f636861723030306300000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303030362f636861723030303900004801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000c20000000400000055554944000173002400000030303030303031342d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303030360000000500000056616c756500026179000000000000000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303030362f63686172303030392f6465736330303062002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303030362f636861723030303900000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303030362f636861723030303700003801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000b50000000400000055554944000173002400000065363034653935642d613735392d343831372d383764332d61613030353038336130643100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44305f37325f30455f34425f37465f36432f73657276696365303030360000000500000056616c756500026179000000000000000000000005000000466c61677300026173000000090000000400000072656164000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000250000002f6f72672f626c75657a2f686369302f6465765f43425f45375f37425f36385f45385f383000000038020000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000110000006f72672e626c75657a2e44657669636531000000bc01000000000000070000004164647265737300017300001100000043423a45373a37423a36383a45383a38300000000b000000416464726573735479706500017300000600000072616e646f6d0000040000004e616d65000173000f000000457665204d6f74696f6e20343141340005000000416c696173000173000000000f000000457665204d6f74696f6e2034314134000000000006000000506169726564000162000000000000000000000007000000547275737465640001620000000000000000000007000000426c6f636b6564000162000000000000000000000d0000004c656761637950616972696e67000162000000000000000000000000040000005253534900016e00d1ff000009000000436f6e6e65637465640001620000000000000000050000005555494473000261730000000000000000000000070000004164617074657200016f00000f0000002f6f72672f626c75657a2f686369300000000000100000004d616e756661637475726572446174610005617b71767d001f0000004c00026179000000130000000631006e35dc9fc1090a0019000102cbfa6fbb001000000053657276696365735265736f6c7665640001620000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000250000002f6f72672f626c75657a2f686369302f6465765f35385f32445f33345f36305f32365f3336000000b8020000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000110000006f72672e626c75657a2e446576696365310000003c02000000000000070000004164647265737300017300001100000035383a32443a33343a36303a32363a33360000000b00000041646472657373547970650001730000060000007075626c69630000040000004e616d65000173001b00000051696e6770696e6720446f6f722f57696e646f772053656e736f72000000000005000000416c696173000173000000001b00000051696e6770696e6720446f6f722f57696e646f772053656e736f720006000000506169726564000162000000000000000000000007000000547275737465640001620000000000000000000007000000426c6f636b6564000162000000000000000000000d0000004c656761637950616972696e67000162000000000000000000000000040000005253534900016e00d9ff000009000000436f6e6e65637465640001620000000000000000050000005555494473000261730000000000000000000000070000004164617074657200016f00000f0000002f6f72672f626c75657a2f6863693000000000000b00000053657276696365446174610005617b73767d000085000000000000002400000030303030666539352d303030302d313030302d383030302d30303830356639623334666200026179000000000c0000003058d60302362660342d58082400000030303030666463642d303030302d313030302d383030302d3030383035663962333466620002617900000000110000000804362660342d580201140f010c0f01010000001000000053657276696365735265736f6c7665640001620000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000250000002f6f72672f626c75657a2f686369302f6465765f41345f43315f33385f32455f43415f364500000028020000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000110000006f72672e626c75657a2e44657669636531000000ac01000000000000070000004164647265737300017300001100000041343a43313a33383a32453a43413a36450000000b00000041646472657373547970650001730000060000007075626c69630000040000004e616d650001730004000000543230310000000005000000416c696173000173000000000400000054323031000000000000000006000000506169726564000162000000000000000000000007000000547275737465640001620000000000000000000007000000426c6f636b6564000162000000000000000000000d0000004c656761637950616972696e67000162000000000000000000000000040000005253534900016e00c2ff000009000000436f6e6e65637465640001620000000000000000050000005555494473000261730000000000000000000000070000004164617074657200016f00000f0000002f6f72672f626c75657a2f686369300000000000100000004d616e756661637475726572446174610005617b71767d001d00000055aa026179000000110000000101a4c1382eca6e010707ec121d6200010000001000000053657276696365735265736f6c7665640001620000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000250000002f6f72672f626c75657a2f686369302f6465765f44425f30325f38305f31465f41445f314400000038020000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000110000006f72672e626c75657a2e44657669636531000000bc01000000000000070000004164647265737300017300001100000044423a30323a38303a31463a41443a31440000000b000000416464726573735479706500017300000600000072616e646f6d0000040000004e616d65000173000d00000045766520526f6f6d203038383100000005000000416c696173000173000000000d00000045766520526f6f6d20303838310000000000000006000000506169726564000162000000000000000000000007000000547275737465640001620000000000000000000007000000426c6f636b6564000162000000000000000000000d0000004c656761637950616972696e67000162000000000000000000000000040000005253534900016e00d4ff000009000000436f6e6e65637465640001620000000000000000050000005555494473000261730000000000000000000000070000004164617074657200016f00000f0000002f6f72672f626c75657a2f686369300000000000100000004d616e756661637475726572446174610005617b71767d001b0000004c000261790000000f00000006cd00fbbef0c7cf250a000e00010200000000001000000053657276696365735265736f6c7665640001620000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000250000002f6f72672f626c75657a2f686369302f6465765f31305f37365f33365f31345f39335f373600000038020000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000110000006f72672e626c75657a2e44657669636531000000bc01000000000000070000004164647265737300017300001100000031303a37363a33363a31343a39333a37360000000b00000041646472657373547970650001730000060000007075626c69630000040000004e616d65000173000c0000005450333933202839333736290000000005000000416c696173000173000000000c000000545033393320283933373629000000000000000006000000506169726564000162000000000000000000000007000000547275737465640001620000000000000000000007000000426c6f636b6564000162000000000000000000000d0000004c656761637950616972696e67000162000000000000000000000000040000005253534900016e00c2ff000009000000436f6e6e65637465640001620000000000000000050000005555494473000261730000000000000000000000070000004164617074657200016f00000f0000002f6f72672f626c75657a2f686369300000000000100000004d616e756661637475726572446174610005617b71767d0020000000c2c502617900000004000000002d022cc2c402617900000004000000002d022c1000000053657276696365735265736f6c7665640001620000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000250000002f6f72672f626c75657a2f686369302f6465765f30305f30365f38305f30385f44325f393500000050020000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000110000006f72672e626c75657a2e44657669636531000000d401000000000000070000004164647265737300017300001100000030303a30363a38303a30383a44323a39350000000b00000041646472657373547970650001730000060000007075626c69630000040000004e616d650001730008000000535a472034385344000000000000000005000000416c6961730001730000000008000000535a4720343853440000000006000000506169726564000162000000000000000000000007000000547275737465640001620000000000000000000007000000426c6f636b6564000162000000000000000000000d0000004c656761637950616972696e67000162000000000000000000000000040000005253534900016e00bdff000009000000436f6e6e6563746564000162000000000000000005000000555549447300026173000000290000002400000065323061333966342d373366352d346263342d613132662d31376431616430376139363100000000070000004164617074657200016f00000f0000002f6f72672f626c75657a2f686369300000000000100000004d616e756661637475726572446174610005617b71767d001200000010100261790000000600000000068008d2950000000000001000000053657276696365735265736f6c7665640001620000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000250000002f6f72672f626c75657a2f686369302f6465765f44355f30375f38455f45455f41365f4242000000f0020000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000110000006f72672e626c75657a2e446576696365310000007402000000000000070000004164647265737300017300001100000044353a30373a38453a45453a41363a42420000000b000000416464726573735479706500017300000600000072616e646f6d0000040000004e616d650001730001000000730000000000000005000000416c69617300017300000000010000007300000006000000506169726564000162000000000000000000000007000000547275737465640001620000000000000000000007000000426c6f636b6564000162000000000000000000000d0000004c656761637950616972696e67000162000000000000000000000000040000005253534900016e00bbff000009000000436f6e6e6563746564000162000000000000000005000000555549447300026173000000290000002400000065663039303030302d313164362d343262612d393362382d39646437656330393061613900000000070000004164617074657200016f00000f0000002f6f72672f626c75657a2f686369300000000000100000004d616e756661637475726572446174610005617b71767d00c600000062e6026179000000020000008c0500004c00026179000000170000000215ef09000011d642ba93b89dd7ec090aa900061e06c8000000000062f6026179000000020000008c0500006206026179000000020000008d0500006216026179000000020000008d0500006226026179000000020000008d0500006236026179000000020000008d0500006036026179000000020000008d0500006026026179000000020000008d0500006046026179000000020000008d0500006246026179000000020000008d0500001000000053657276696365735265736f6c7665640001620000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000250000002f6f72672f626c75657a2f686369302f6465765f44465f37395f45335f41365f31325f423300000048030000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000110000006f72672e626c75657a2e44657669636531000000cc02000000000000070000004164647265737300017300001100000044463a37393a45333a41363a31323a42330000000b000000416464726573735479706500017300000600000072616e646f6d0000040000004e616d6500017300070000004d6f61745f53320005000000416c69617300017300000000070000004d6f61745f5332000000000006000000506169726564000162000000000000000000000007000000547275737465640001620000000000000000000007000000426c6f636b6564000162000000000000000000000d0000004c656761637950616972696e67000162000000000000000000000000040000005253534900016e00beff000009000000436f6e6e6563746564000162000000000000000005000000555549447300026173000000550000002400000030303030313030302d303030302d313030302d383030302d303038303566396233346662000000002400000030303030323030302d303030302d313030302d383030302d3030383035663962333466620000000000000000070000004164617074657200016f00000f0000002f6f72672f626c75657a2f686369300000000000100000004d616e756661637475726572446174610005617b71767d00230000004c00026179000000170000000215f173a6a0acd811eabb370242ac130002d660407bcb00000000000b00000053657276696365446174610005617b73767d000084000000000000002400000030303030313030302d303030302d313030302d383030302d303038303566396233346662000261790000000012000000df79e3a612b3a534656318612869b90bffff00002400000030303030353030302d303030302d313030302d383030302d303038303566396233346662000261790000000008000000df79e3a612b3b90b00000000070000005478506f77657200016e000000000000000000001000000053657276696365735265736f6c7665640001620000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000250000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f353600000050040000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000110000006f72672e626c75657a2e44657669636531000000d403000000000000070000004164647265737300017300001100000043443a41333a46413a44313a35303a35360000000b000000416464726573735479706500017300000600000072616e646f6d0000040000004e616d6500017300110000004f6e7669732d534d53312d3362326431610000000000000005000000416c69617300017300000000110000004f6e7669732d534d53312d33623264316100000006000000506169726564000162000000000000000000000007000000547275737465640001620000000000000000000007000000426c6f636b6564000162000000000000000000000d0000004c656761637950616972696e67000162000000000000000000000000040000005253534900016e00d5ff000009000000436f6e6e65637465640001620000000000000000050000005555494473000261730000000d0200002400000030303030303033652d303030302d313030302d383030302d303032366262373635323931000000002400000030303030303035352d303030302d313030302d383030302d303032366262373635323931000000002400000030303030303038322d303030302d313030302d383030302d303032366262373635323931000000002400000030303030303038352d303030302d313030302d383030302d303032366262373635323931000000002400000030303030303038612d303030302d313030302d383030302d303032366262373635323931000000002400000030303030303039362d303030302d313030302d383030302d303032366262373635323931000000002400000030303030303061322d303030302d313030302d383030302d303032366262373635323931000000002400000030303030313533302d313231322d656664652d313532332d373835666561626364313233000000002400000030303030313830302d303030302d313030302d383030302d303038303566396233346662000000002400000030303030313830312d303030302d313030302d383030302d303038303566396233346662000000002400000034616161663936312d306465632d313165352d623933392d303830303230306339613636000000002400000034616161663964352d306465632d313165352d623933392d3038303032303063396136360000000000000000070000004164617074657200016f00000f0000002f6f72672f626c75657a2f686369300000000000100000004d616e756661637475726572446174610005617b71767d001f0000004c00026179000000130000000631008209820e65e00a001a1201021277e7d2001000000053657276696365735265736f6c7665640001620000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000310000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303061340000002001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000160000006f72672e626c75657a2e4761747453657276696365310000a80000000400000055554944000173002400000034616161663964352d306465632d313165352d623933392d303830303230306339613636000000000600000044657669636500016f000000250000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f353600000000000000070000005072696d6172790001620000010000000000000008000000496e636c756465730002616f00000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303061342f636861723030616100006001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000da0000000400000055554944000173002400000034616161663964372d306465632d313165352d623933392d30383030323030633961363600000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303061340000000500000056616c7565000261790000001b0000000201f1a6233f2ba1595de529129ee68fd2fbe13e1bc6c2a20152dd0005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303061342f63686172303061612f6465736330306163002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303061342f636861723030616100000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303061342f636861723030613700006001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000da0000000400000055554944000173002400000034616161663964362d306465632d313165352d623933392d30383030323030633961363600000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303061340000000500000056616c7565000261790000001b000000f773af102f37b1a155cc63eb74906ae165ab782b234fb1ec21a1c30005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303061342f63686172303061372f6465736330306139002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303061342f636861723030613700000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303061342f636861723030613500003801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000b50000000400000055554944000173002400000065363034653935642d613735392d343831372d383764332d61613030353038336130643100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303061340000000500000056616c756500026179000000000000000000000005000000466c61677300026173000000090000000400000072656164000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000310000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303039620000002001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000160000006f72672e626c75657a2e4761747453657276696365310000a80000000400000055554944000173002400000030303030313533302d313231322d656664652d313532332d373835666561626364313233000000000600000044657669636500016f000000250000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f353600000000000000070000005072696d6172790001620000010000000000000008000000496e636c756465730002616f00000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303039622f636861723030613100004801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000c20000000400000055554944000173002400000030303030313533312d313231322d656664652d313532332d37383566656162636431323300000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303039620000000500000056616c756500026179000000000000000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303039622f63686172303061312f6465736330306133002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303039622f636861723030613100000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303039622f636861723030396500004801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000c20000000400000055554944000173002400000030303030303061352d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303039620000000500000056616c756500026179000000000000000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303039622f63686172303039652f6465736330306130002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303039622f636861723030396500000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303039622f636861723030396300003801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000b50000000400000055554944000173002400000065363034653935642d613735392d343831372d383764332d61613030353038336130643100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303039620000000500000056616c756500026179000000000000000000000005000000466c61677300026173000000090000000400000072656164000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000310000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303038390000002001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000160000006f72672e626c75657a2e4761747453657276696365310000a80000000400000055554944000173002400000030303030303039362d303030302d313030302d383030302d303032366262373635323931000000000600000044657669636500016f000000250000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f353600000000000000070000005072696d6172790001620000010000000000000008000000496e636c756465730002616f00000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303038392f636861723030393700008801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000010100000400000055554944000173002400000030303030303038662d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303038390000000500000056616c7565000261790000001c000000fc25cd1a8ae8fdddd474a96e689b1f22a31ff5b3dfa41828314512c2090000004e6f74696679696e67000162000000000000000005000000466c616773000261730000002500000004000000726561640000000005000000777269746500000008000000696e64696361746500000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303038392f63686172303039372f6465736330303961002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303038392f636861723030393700000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303038392f63686172303039372f6465736330303939002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000030303030323930322d303030302d313030302d383030302d303038303566396233346662000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303038392f636861723030393700000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303038392f636861723030393400007001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000ea0000000400000055554944000173002400000030303030303032332d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303038390000000500000056616c756500026179000000260000001fa358c95f8d6f16f4f90b49f7277384df1b4aa5dba19925145e397fea9c1241197efe0979a500000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303038392f63686172303039342f6465736330303936002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303038392f636861723030393400000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303038392f636861723030393000008801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000010100000400000055554944000173002400000030303030303037392d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303038390000000500000056616c7565000261790000001c0000000a3a210659ac6698a9cb257e0f9534b4c32e4e78437697185af386b2090000004e6f74696679696e67000162000000000000000005000000466c616773000261730000002500000004000000726561640000000005000000777269746500000008000000696e64696361746500000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303038392f63686172303039302f6465736330303933002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303038392f636861723030393000000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303038392f63686172303039302f6465736330303932002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000030303030323930322d303030302d313030302d383030302d303038303566396233346662000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303038392f636861723030393000000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303038392f636861723030386300008801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000010100000400000055554944000173002400000030303030303036382d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303038390000000500000056616c7565000261790000001c000000fb84802fc059c3587335ef0b7d80b6119bf2c20ea0df8f0710fe39eb090000004e6f74696679696e67000162000000000000000005000000466c616773000261730000002500000004000000726561640000000005000000777269746500000008000000696e64696361746500000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303038392f63686172303038632f6465736330303866002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303038392f636861723030386300000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303038392f63686172303038632f6465736330303865002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000030303030323930322d303030302d313030302d383030302d303038303566396233346662000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303038392f636861723030386300000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303038392f636861723030386100003801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000b50000000400000055554944000173002400000065363034653935642d613735392d343831372d383764332d61613030353038336130643100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303038390000000500000056616c756500026179000000000000000000000005000000466c61677300026173000000090000000400000072656164000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000310000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303038300000002001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000160000006f72672e626c75657a2e4761747453657276696365310000a80000000400000055554944000173002400000034616161663936312d306465632d313165352d623933392d303830303230306339613636000000000600000044657669636500016f000000250000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f353600000000000000070000005072696d6172790001620000010000000000000008000000496e636c756465730002616f00000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303038302f636861723030383600006001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000da0000000400000055554944000173002400000034616161663936332d306465632d313165352d623933392d30383030323030633961363600000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303038300000000500000056616c7565000261790000001b00000051e4a221c6455f0339f4a5acb7fa6e6ea3308b2469d6a343df91b70005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303038302f63686172303038362f6465736330303838002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303038302f636861723030383600000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303038302f636861723030383300006001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000da0000000400000055554944000173002400000034616161663936322d306465632d313165352d623933392d30383030323030633961363600000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303038300000000500000056616c7565000261790000001b000000ee92725b7589873b89ae596e1c9c6c0fbc6e24512f77e814ae074c0005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303038302f63686172303038332f6465736330303835002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303038302f636861723030383300000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303038302f636861723030383100003801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000b50000000400000055554944000173002400000065363034653935642d613735392d343831372d383764332d61613030353038336130643100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303038300000000500000056616c756500026179000000000000000000000005000000466c61677300026173000000090000000400000072656164000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000310000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303037300000002001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000160000006f72672e626c75657a2e4761747453657276696365310000a80000000400000055554944000173002400000030303030303038322d303030302d313030302d383030302d303032366262373635323931000000000600000044657669636500016f000000250000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f353600000000000000070000005072696d6172790001620000010000000000000008000000496e636c756465730002616f00000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303037302f636861723030376400006001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000da0000000400000055554944000173002400000034616161663962392d306465632d313165352d623933392d30383030323030633961363600000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303037300000000500000056616c75650002617900000017000000f6bf4bec08843fa3f17f498f7f9375c738c2f3a3cf3cf1000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303037302f63686172303037642f6465736330303766002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303037302f636861723030376400000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303037302f636861723030376100007001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000ea0000000400000055554944000173002400000034616161663962382d306465632d313165352d623933392d30383030323030633961363600000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303037300000000500000056616c75650002617900000029000000f02cf675ea88f17fde55b3cac216130de4c23485bbfaca3ebd9438d9c301856dcd3c72c3e80087ac3200000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303037302f63686172303037612f6465736330303763002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303037302f636861723030376100000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303037302f636861723030373600008801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000010100000400000055554944000173002400000030303030303031302d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303037300000000500000056616c7565000261790000001c000000804b21b7b0a9d3a849c7365e17c43426cb6ba6664e77f3af0c5762e8090000004e6f74696679696e67000162000000000000000005000000466c616773000261730000002500000004000000726561640000000005000000777269746500000008000000696e64696361746500000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303037302f63686172303037362f6465736330303739002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303037302f636861723030373600000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303037302f63686172303037362f6465736330303738002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000030303030323930322d303030302d313030302d383030302d303038303566396233346662000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303037302f636861723030373600000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303037302f636861723030373300007001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000ea0000000400000055554944000173002400000030303030303032332d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303037300000000500000056616c7565000261790000002c00000099b82c95686e511795250db93f64b598e87f4c89d76388a3bf697a5aaa226d60dcd10c4eeecbdf431604f1f405000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303037302f63686172303037332f6465736330303735002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303037302f636861723030373300000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303037302f636861723030373100003801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000b50000000400000055554944000173002400000065363034653935642d613735392d343831372d383764332d61613030353038336130643100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303037300000000500000056616c756500026179000000000000000000000005000000466c61677300026173000000090000000400000072656164000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000310000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303036300000002001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000160000006f72672e626c75657a2e4761747453657276696365310000a80000000400000055554944000173002400000030303030303038612d303030302d313030302d383030302d303032366262373635323931000000000600000044657669636500016f000000250000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f353600000000000000070000005072696d6172790001620000010000000000000008000000496e636c756465730002616f00000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303036302f636861723030366400006001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000da0000000400000055554944000173002400000034616161663962642d306465632d313165352d623933392d30383030323030633961363600000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303036300000000500000056616c75650002617900000017000000d142febcf9065dff3079911ce72392e7afa630d3b29748000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303036302f63686172303036642f6465736330303666002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303036302f636861723030366400000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303036302f636861723030366100007001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000ea0000000400000055554944000173002400000034616161663962632d306465632d313165352d623933392d30383030323030633961363600000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303036300000000500000056616c756500026179000000290000001dabc2325704e8de64768f396e917e71a5c5724af6b4140d58893ab4297876c46fb86650b5d10f639f00000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303036302f63686172303036612f6465736330303663002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303036302f636861723030366100000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303036302f636861723030363600008801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000010100000400000055554944000173002400000030303030303031312d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303036300000000500000056616c7565000261790000001c0000003e59fd2dbcc2dc8dc58a593c4ed839a29fdef1944b406914006ab015090000004e6f74696679696e67000162000000000000000005000000466c616773000261730000002500000004000000726561640000000005000000777269746500000008000000696e64696361746500000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303036302f63686172303036362f6465736330303639002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303036302f636861723030363600000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303036302f63686172303036362f6465736330303638002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000030303030323930322d303030302d313030302d383030302d303038303566396233346662000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303036302f636861723030363600000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303036302f636861723030363300007801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000f20000000400000055554944000173002400000030303030303032332d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303036300000000500000056616c7565000261790000002f000000f3d36e0845882eba309a12bd2b31b9132a8af9c92cf29183109ee2db858117ba32ba9fc2654b624d78b7c1187381b4000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303036302f63686172303036332f6465736330303635002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303036302f636861723030363300000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303036302f636861723030363100003801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000b50000000400000055554944000173002400000065363034653935642d613735392d343831372d383764332d61613030353038336130643100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303036300000000500000056616c756500026179000000000000000000000005000000466c61677300026173000000090000000400000072656164000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000310000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303034310000002001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000160000006f72672e626c75657a2e4761747453657276696365310000a80000000400000055554944000173002400000030303030303038352d303030302d313030302d383030302d303032366262373635323931000000000600000044657669636500016f000000250000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f353600000000000000070000005072696d6172790001620000010000000000000008000000496e636c756465730002616f00000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303034312f636861723030356400006001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000da0000000400000055554944000173002400000034616161663939662d306465632d313165352d623933392d30383030323030633961363600000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303034310000000500000056616c7565000261790000001b000000dff36beb6be2224e4c9e1fc89767693e8723fb2c2bec32a54fa6390005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303034312f63686172303035642f6465736330303566002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303034312f636861723030356400000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303034312f636861723030356100006001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000da0000000400000055554944000173002400000034616161663938392d306465632d313165352d623933392d30383030323030633961363600000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303034310000000500000056616c756500026179000000190000003182232bc64172b4989010980aa2e048502b9cee1e9c85f71e00000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303034312f63686172303035612f6465736330303563002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303034312f636861723030356100000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303034312f636861723030353700006801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000e20000000400000055554944000173002400000034616161663938382d306465632d313165352d623933392d30383030323030633961363600000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303034310000000500000056616c7565000261790000001d000000d8d0d32123bc3b0c93ede75c39d953731e1c14823dac11e2cc04d727e60000000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303034312f63686172303035372f6465736330303539002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303034312f636861723030353700000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303034312f636861723030353400006001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000da0000000400000055554944000173002400000034616161663935652d306465632d313165352d623933392d30383030323030633961363600000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303034310000000500000056616c75650002617900000019000000b839722e7d846c51d270116f51a81e22c26bbf0f8783ef09ff00000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303034312f63686172303035342f6465736330303536002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303034312f636861723030353400000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303034312f636861723030353100006001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000da0000000400000055554944000173002400000034616161663935642d306465632d313165352d623933392d30383030323030633961363600000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303034310000000500000056616c75650002617900000019000000a46761f05a3cf9ae1c59dcbd009fae264aad7dda39efa0ec0e00000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303034312f63686172303035312f6465736330303533002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303034312f636861723030353100000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303034312f636861723030346500006001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000da0000000400000055554944000173002400000034616161663935632d306465632d313165352d623933392d30383030323030633961363600000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303034310000000500000056616c756500026179000000190000008e29a95862714e8c3198b33579e33a68a6b55893ccebf5e88a00000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303034312f63686172303034652f6465736330303530002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303034312f636861723030346500000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303034312f636861723030346100008801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000010100000400000055554944000173002400000030303030303032322d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303034310000000500000056616c7565000261790000001c000000646058aa8f4221083dc72066d86011ba371f83a81358742ad691e47f090000004e6f74696679696e67000162000000000000000005000000466c616773000261730000002500000004000000726561640000000005000000777269746500000008000000696e64696361746500000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303034312f63686172303034612f6465736330303464002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303034312f636861723030346100000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303034312f63686172303034612f6465736330303463002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000030303030323930322d303030302d313030302d383030302d303038303566396233346662000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303034312f636861723030346100000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303034312f636861723030343700007001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000ea0000000400000055554944000173002400000030303030303032332d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303034310000000500000056616c7565000261790000002a000000803ee8d1eaa2394ac69a3097a62cea51635faa64b2c702bc35134f61f173f11c1bda4aaf3ff01e5b47b5000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303034312f63686172303034372f6465736330303439002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303034312f636861723030343700000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303034312f636861723030343400004801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000c20000000400000055554944000173002400000030303030303061352d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303034310000000500000056616c756500026179000000000000000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303034312f63686172303034342f6465736330303436002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303034312f636861723030343400000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303034312f636861723030343200003801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000b50000000400000055554944000173002400000065363034653935642d613735392d343831372d383764332d61613030353038336130643100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303034310000000500000056616c756500026179000000000000000000000005000000466c61677300026173000000090000000400000072656164000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000310000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303033320000002001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000160000006f72672e626c75657a2e4761747453657276696365310000a80000000400000055554944000173002400000030303030303035352d303030302d313030302d383030302d303032366262373635323931000000000600000044657669636500016f000000250000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f353600000000000000070000005072696d6172790001620000010000000000000008000000496e636c756465730002616f00000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303033322f636861723030336500004801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000c20000000400000055554944000173002400000030303030303035302d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303033320000000500000056616c756500026179000000000000000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303033322f63686172303033652f6465736330303430002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303033322f636861723030336500000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303033322f636861723030336200004801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000c20000000400000055554944000173002400000030303030303034662d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303033320000000500000056616c756500026179000000000000000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303033322f63686172303033622f6465736330303364002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303033322f636861723030336200000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303033322f636861723030333800005001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000ca0000000400000055554944000173002400000030303030303034652d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303033320000000500000056616c7565000261790000000a000000025b0005000103060104000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303033322f63686172303033382f6465736330303361002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a6000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303033322f636861723030333800000500000056616c756500026179000000020000000b0000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303033322f636861723030333500004801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000c20000000400000055554944000173002400000030303030303034632d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303033320000000500000056616c756500026179000000000000000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303033322f63686172303033352f6465736330303337002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303033322f636861723030333500000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303033322f636861723030333300003801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000b50000000400000055554944000173002400000065363034653935642d613735392d343831372d383764332d61613030353038336130643100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303033320000000500000056616c756500026179000000000000000000000005000000466c61677300026173000000090000000400000072656164000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000310000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303032390000002001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000160000006f72672e626c75657a2e4761747453657276696365310000a80000000400000055554944000173002400000030303030303061322d303030302d313030302d383030302d303032366262373635323931000000000600000044657669636500016f000000250000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f353600000000000000070000005072696d6172790001620000010000000000000008000000496e636c756465730002616f00000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303032392f636861723030326600006001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000da0000000400000055554944000173002400000030303030303033372d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303032390000000500000056616c7565000261790000001c00000015ba6229c69f6dfc36fc2408e4f9040a054ca23becceb601e658088e05000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303032392f63686172303032662f6465736330303331002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303032392f636861723030326600000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303032392f636861723030326300009001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e476174744368617261637465726973746963310000000a0100000400000055554944000173002400000030303030303061352d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303032390000000500000056616c75650002617900000046000000b7b13b6b03c7d87dbc812023ecfaffa7944535b6eaf95832ffd3ecbdd0e8e247fe90551d6ad39fd9c7db8b419adad5037ae4b58eee609be557607cf03d533782a62a160869a900000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303032392f63686172303032632f6465736330303265002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303032392f636861723030326300000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303032392f636861723030326100003801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000b50000000400000055554944000173002400000065363034653935642d613735392d343831372d383764332d61613030353038336130643100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303032390000000500000056616c756500026179000000000000000000000005000000466c61677300026173000000090000000400000072656164000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000310000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303030620000002001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000160000006f72672e626c75657a2e4761747453657276696365310000a80000000400000055554944000173002400000030303030303033652d303030302d313030302d383030302d303032366262373635323931000000000600000044657669636500016f000000250000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f353600000000000000070000005072696d6172790001620000010000000000000008000000496e636c756465730002616f00000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303030622f636861723030323600004801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000c20000000400000055554944000173002400000030303030303232302d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303030620000000500000056616c756500026179000000000000000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303030622f63686172303032362f6465736330303238002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303030622f636861723030323600000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303030622f636861723030323300004801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000c20000000400000055554944000173002400000033346162383831312d616337662d343334302d626163332d66643661383566393934336200000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303030620000000500000056616c756500026179000000000000000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303030622f63686172303032332f6465736330303235002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303030622f636861723030323300000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303030622f636861723030323000004801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000c20000000400000055554944000173002400000030303030303035332d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303030620000000500000056616c756500026179000000000000000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303030622f63686172303032302f6465736330303232002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303030622f636861723030323000000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303030622f636861723030316400004801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000c20000000400000055554944000173002400000030303030303035322d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303030620000000500000056616c756500026179000000000000000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303030622f63686172303031642f6465736330303166002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303030622f636861723030316400000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303030622f636861723030316100004801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000c20000000400000055554944000173002400000030303030303033302d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303030620000000500000056616c756500026179000000000000000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303030622f63686172303031612f6465736330303163002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303030622f636861723030316100000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303030622f636861723030313700004801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000c20000000400000055554944000173002400000030303030303032332d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303030620000000500000056616c756500026179000000000000000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303030622f63686172303031372f6465736330303139002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303030622f636861723030313700000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303030622f636861723030313400004801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000c20000000400000055554944000173002400000030303030303032312d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303030620000000500000056616c756500026179000000000000000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303030622f63686172303031342f6465736330303136002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303030622f636861723030313400000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303030622f636861723030313100004801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000c20000000400000055554944000173002400000030303030303032302d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303030620000000500000056616c756500026179000000000000000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303030622f63686172303031312f6465736330303133002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303030622f636861723030313100000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303030622f636861723030306500004801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000c20000000400000055554944000173002400000030303030303031342d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303030620000000500000056616c756500026179000000000000000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303030622f63686172303030652f6465736330303130002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303030622f636861723030306500000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303030622f636861723030306300003801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000b50000000400000055554944000173002400000065363034653935642d613735392d343831372d383764332d61613030353038336130643100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303030620000000500000056616c756500026179000000000000000000000005000000466c61677300026173000000090000000400000072656164000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000310000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f35362f73657276696365303030610000002001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000160000006f72672e626c75657a2e4761747453657276696365310000a80000000400000055554944000173002400000030303030313830312d303030302d313030302d383030302d303038303566396233346662000000000600000044657669636500016f000000250000002f6f72672f626c75657a2f686369302f6465765f43445f41335f46415f44315f35305f353600000000000000070000005072696d6172790001620000010000000000000008000000496e636c756465730002616f00000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000250000002f6f72672f626c75657a2f686369302f6465765f35385f44335f34395f45365f30325f364500000028020000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000110000006f72672e626c75657a2e44657669636531000000ac01000000000000070000004164647265737300017300001100000035383a44333a34393a45363a30323a36450000000b00000041646472657373547970650001730000060000007075626c6963000005000000416c696173000173000000001100000035382d44332d34392d45362d30322d364500000006000000506169726564000162000000000000000000000007000000547275737465640001620000000000000000000007000000426c6f636b6564000162000000000000000000000d0000004c656761637950616972696e67000162000000000000000000000000040000005253534900016e00b9ff000009000000436f6e6e65637465640001620000000000000000050000005555494473000261730000000000000000000000070000004164617074657200016f00000f0000002f6f72672f626c75657a2f686369300000000000100000004d616e756661637475726572446174610005617b71767d00130000004c000261790000000700000010050e10b8832c0000000000070000005478506f77657200016e000004000000000000001000000053657276696365735265736f6c7665640001620000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000250000002f6f72672f626c75657a2f686369302f6465765f44435f30445f31355f33365f43445f433900000038030000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000110000006f72672e626c75657a2e44657669636531000000bc02000000000000070000004164647265737300017300001100000044433a30443a31353a33363a43443a43390000000b00000041646472657373547970650001730000060000007075626c69630000040000004e616d65000173000a0000004653432d42503130354e00000000000005000000416c696173000173000000000a0000004653432d42503130354e000006000000506169726564000162000000000000000000000007000000547275737465640001620000000000000000000007000000426c6f636b6564000162000000000000000000000d0000004c656761637950616972696e67000162000000000000000000000000040000005253534900016e00ddff000009000000436f6e6e6563746564000162000000000000000005000000555549447300026173000000550000002400000030303030666566352d303030302d313030302d383030302d303038303566396233346662000000002400000030303030666561612d303030302d313030302d383030302d3030383035663962333466620000000000000000070000004164617074657200016f00000f0000002f6f72672f626c75657a2f686369300000000000100000004d616e756661637475726572446174610005617b71767d00230000004c00026179000000170000000215fda50693a4e24fb1afcfc6eb07647825275165c1fd00000000000b00000053657276696365446174610005617b73767d000082000000000000002400000030303030666666302d303030302d313030302d383030302d30303830356639623334666200026179000000000b000000360216b2dc0d1536cdc964002400000030303030666561612d303030302d313030302d383030302d30303830356639623334666200026179000000000e00000020000bcd80000010e5e6117ee3030000000000001000000053657276696365735265736f6c7665640001620000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000250000002f6f72672f626c75657a2f686369302f6465765f44445f33345f30325f30365f44455f413100000018030000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000110000006f72672e626c75657a2e446576696365310000009c02000000000000070000004164647265737300017300001100000044443a33343a30323a30363a44453a41310000000b000000416464726573735479706500017300000600000072616e646f6d0000040000004e616d650001730010000000426c7565436861726d5f313737393939000000000000000005000000416c6961730001730000000010000000426c7565436861726d5f3137373939390000000006000000506169726564000162000000000000000000000007000000547275737465640001620000000000000000000007000000426c6f636b6564000162000000000000000000000d0000004c656761637950616972696e67000162000000000000000000000000040000005253534900016e00d7ff000009000000436f6e6e6563746564000162000000000000000005000000555549447300026173000000290000002400000030303030666561612d303030302d313030302d383030302d30303830356639623334666200000000070000004164617074657200016f00000f0000002f6f72672f626c75657a2f686369300000000000100000004d616e756661637475726572446174610005617b71767d00230000004c00026179000000170000000215426c7565436861726d426561636f6e730efe1355c500000000000b00000053657276696365446174610005617b73767d000082000000000000002400000030303030323038302d303030302d313030302d383030302d303038303566396233346662000261790000000006000000640c0efe13550000000000002400000030303030666561612d303030302d313030302d383030302d30303830356639623334666200026179000000000e00000020000bc61b00003db2380279a78a0000000000001000000053657276696365735265736f6c7665640001620000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000250000002f6f72672f626c75657a2f686369302f6465765f42435f31345f45465f37425f32325f324100000058020000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000110000006f72672e626c75657a2e44657669636531000000dc01000000000000070000004164647265737300017300001100000042433a31343a45463a37423a32323a32410000000b00000041646472657373547970650001730000060000007075626c69630000040000004e616d65000173000c0000004e41505f4650435f323232410000000005000000416c696173000173000000000c0000004e41505f4650435f32323241000000000000000006000000506169726564000162000000000000000000000007000000547275737465640001620000000000000000000007000000426c6f636b6564000162000000000000000000000d0000004c656761637950616972696e67000162000000000000000000000000040000005253534900016e00b5ff000009000000436f6e6e6563746564000162000000000000000005000000555549447300026173000000290000002400000030303030666630302d303030302d313030302d383030302d30303830356639623334666200000000070000004164617074657200016f00000f0000002f6f72672f626c75657a2f686369300000000000100000004d616e756661637475726572446174610005617b71767d00160000004e410261790000000a000000505f4650435f3232324100001000000053657276696365735265736f6c7665640001620000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000250000002f6f72672f626c75657a2f686369302f6465765f42345f45385f34325f44425f41465f364200000050020000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000110000006f72672e626c75657a2e44657669636531000000d401000000000000070000004164647265737300017300001100000042343a45383a34323a44423a41463a36420000000b00000041646472657373547970650001730000060000007075626c69630000040000004e616d6500017300140000004c45446e657457463031303039374442414636410000000005000000416c69617300017300000000140000004c45446e65745746303130303937444241463641000000000000000006000000506169726564000162000000000000000000000007000000547275737465640001620000000000000000000007000000426c6f636b6564000162000000000000000000000d0000004c656761637950616972696e67000162000000000000000000000000040000005253534900016e00acff000009000000436f6e6e65637465640001620000000000000000050000005555494473000261730000000000000000000000070000004164617074657200016f00000f0000002f6f72672f626c75657a2f686369300000000000100000004d616e756661637475726572446174610005617b71767d0027000000015a0261790000001b0000005202b4e842dbaf6a00970b03010203040506070809a1a2a3a4a5a6001000000053657276696365735265736f6c7665640001620000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000250000002f6f72672f626c75657a2f686369302f6465765f45305f34355f38315f31315f31335f463700000030020000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000110000006f72672e626c75657a2e44657669636531000000b401000000000000070000004164647265737300017300001100000045303a34353a38313a31313a31333a46370000000b000000416464726573735479706500017300000600000072616e646f6d000005000000416c696173000173000000001100000045302d34352d38312d31312d31332d463700000006000000506169726564000162000000000000000000000007000000547275737465640001620000000000000000000007000000426c6f636b6564000162000000000000000000000d0000004c656761637950616972696e67000162000000000000000000000000040000005253534900016e00b2ff000009000000436f6e6e65637465640001620000000000000000050000005555494473000261730000000000000000000000070000004164617074657200016f00000f0000002f6f72672f626c75657a2f6863693000000000000b00000053657276696365446174610005617b73767d000038000000000000002400000030303030666666652d303030302d313030302d383030302d3030383035663962333466620002617900000000040000000900ff001000000053657276696365735265736f6c7665640001620000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000250000002f6f72672f626c75657a2f686369302f6465765f35385f32445f33345f36305f44415f3146000000b0020000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000110000006f72672e626c75657a2e446576696365310000003402000000000000070000004164647265737300017300001100000035383a32443a33343a36303a44413a31460000000b00000041646472657373547970650001730000060000007075626c69630000040000004e616d65000173001700000051696e6770696e67204d6f74696f6e2026204c696768740005000000416c696173000173000000001700000051696e6770696e67204d6f74696f6e2026204c69676874000000000006000000506169726564000162000000000000000000000007000000547275737465640001620000000000000000000007000000426c6f636b6564000162000000000000000000000d0000004c656761637950616972696e67000162000000000000000000000000040000005253534900016e00c9ff000009000000436f6e6e65637465640001620000000000000000050000005555494473000261730000000000000000000000070000004164617074657200016f00000f0000002f6f72672f626c75657a2f6863693000000000000b00000053657276696365446174610005617b73767d000088000000000000002400000030303030666539352d303030302d313030302d383030302d30303830356639623334666200026179000000000c0000003058830a021fda60342d58082400000030303030666463642d303030302d313030302d383030302d30303830356639623334666200026179000000001400000008121fda60342d580201550f01e409040a0000001000000053657276696365735265736f6c7665640001620000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000250000002f6f72672f626c75657a2f686369302f6465765f44435f30445f33305f30465f41435f444100000038030000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000110000006f72672e626c75657a2e44657669636531000000bc02000000000000070000004164647265737300017300001100000044433a30443a33303a30463a41433a44410000000b00000041646472657373547970650001730000060000007075626c69630000040000004e616d65000173000a0000004653432d42503130334200000000000005000000416c696173000173000000000a0000004653432d425031303342000006000000506169726564000162000000000000000000000007000000547275737465640001620000000000000000000007000000426c6f636b6564000162000000000000000000000d0000004c656761637950616972696e67000162000000000000000000000000040000005253534900016e00caff000009000000436f6e6e6563746564000162000000000000000005000000555549447300026173000000550000002400000030303030666566352d303030302d313030302d383030302d303038303566396233346662000000002400000030303030666561612d303030302d313030302d383030302d3030383035663962333466620000000000000000070000004164617074657200016f00000f0000002f6f72672f626c75657a2f686369300000000000100000004d616e756661637475726572446174610005617b71767d00230000004c00026179000000170000000215d546df97475747efbe093e2dcbdd0c777775f4a5b500000000000b00000053657276696365446174610005617b73767d000084000000000000002400000030303030666666302d303030302d313030302d383030302d30303830356639623334666200026179000000000b00000029021792dc0d300facda61002400000030303030666561612d303030302d313030302d383030302d30303830356639623334666200026179000000001000000010eb03676f6f2e676c2f50484e53646d000000001000000053657276696365735265736f6c7665640001620000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000250000002f6f72672f626c75657a2f686369302f6465765f44375f45415f32375f44355f46465f373500000090020000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000110000006f72672e626c75657a2e446576696365310000001402000000000000070000004164647265737300017300001100000044373a45413a32373a44353a46463a37350000000b000000416464726573735479706500017300000600000072616e646f6d000005000000416c696173000173000000001100000044372d45412d32372d44352d46462d373500000006000000506169726564000162000000000000000000000007000000547275737465640001620000000000000000000007000000426c6f636b6564000162000000000000000000000d0000004c656761637950616972696e67000162000000000000000000000000040000005253534900016e00d3ff000009000000436f6e6e6563746564000162000000000000000005000000555549447300026173000000290000002400000063626132306430302d323234642d313165362d396662382d30303032613564356335316200000000070000004164617074657200016f00000f0000002f6f72672f626c75657a2f686369300000000000100000004d616e756661637475726572446174610005617b71767d0012000000590002617900000006000000d7ea27d5ff750000000000000b00000053657276696365446174610005617b73767d000038000000000000002400000030303030306430302d303030302d313030302d383030302d303038303566396233346662000261790000000004000000620062001000000053657276696365735265736f6c7665640001620000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000250000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f3133000000f8030000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000110000006f72672e626c75657a2e446576696365310000007c03000000000000070000004164647265737300017300001100000044333a32433a35413a35423a35333a31330000000b000000416464726573735479706500017300000600000072616e646f6d0000040000004e616d65000173001200000051696e6770696e672054656d70205248204800000000000005000000416c696173000173000000001200000051696e6770696e672054656d702052482048000006000000506169726564000162000000000000000000000007000000547275737465640001620000000000000000000007000000426c6f636b6564000162000000000000000000000d0000004c656761637950616972696e67000162000000000000000000000000040000005253534900016e00d0ff000009000000436f6e6e6563746564000162000000000000000005000000555549447300026173000000b50100002400000030303030303033652d303030302d313030302d383030302d303032366262373635323931000000002400000030303030303035352d303030302d313030302d383030302d303032366262373635323931000000002400000030303030303038322d303030302d313030302d383030302d303032366262373635323931000000002400000030303030303038612d303030302d313030302d383030302d303032366262373635323931000000002400000030303030303039362d303030302d313030302d383030302d303032366262373635323931000000002400000030303030303061322d303030302d313030302d383030302d303032366262373635323931000000002400000030303030313533302d313231322d656664652d313532332d373835666561626364313233000000002400000030303030313830302d303030302d313030302d383030302d303038303566396233346662000000002400000030303030313830312d303030302d313030302d383030302d303038303566396233346662000000002400000032323231303030302d353534612d343534362d353534322d3436353334343530343634640000000000000000070000004164617074657200016f00000f0000002f6f72672f626c75657a2f686369300000000000100000004d616e756661637475726572446174610005617b71767d001f0000004c0002617900000013000000063100cacc78de9d4d0a00b3020102648d8540001000000053657276696365735265736f6c7665640001620000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000310000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303036340000002001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000160000006f72672e626c75657a2e4761747453657276696365310000a80000000400000055554944000173002400000030303030303039362d303030302d313030302d383030302d303032366262373635323931000000000600000044657669636500016f000000250000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f313300000000000000070000005072696d6172790001620000010000000000000008000000496e636c756465730002616f00000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303036342f636861723030373200008801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000010100000400000055554944000173002400000030303030303038662d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303036340000000500000056616c75650002617900000019000000360cd8f589cd437c8e63e0ed4026ef8e23521c438cf9603846000000090000004e6f74696679696e67000162000000000000000005000000466c616773000261730000002500000004000000726561640000000005000000777269746500000008000000696e64696361746500000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303036342f63686172303037322f6465736330303735002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303036342f636861723030373200000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303036342f63686172303037322f6465736330303734002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000030303030323930322d303030302d313030302d383030302d303038303566396233346662000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303036342f636861723030373200000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303036342f636861723030366600007001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000ea0000000400000055554944000173002400000030303030303032332d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303036340000000500000056616c756500026179000000260000008acacfbede51497aa8314cd7d962914118939e7de11e0a0c72f2288299134c0bc6e32fb9eb9500000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303036342f63686172303036662f6465736330303731002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303036342f636861723030366600000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303036342f636861723030366200008801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000010100000400000055554944000173002400000030303030303037392d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303036340000000500000056616c7565000261790000001900000050f2de9cfe1dfe3a5429155f435a90ef698e2027ad8baf1b68000000090000004e6f74696679696e67000162000000000000000005000000466c616773000261730000002500000004000000726561640000000005000000777269746500000008000000696e64696361746500000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303036342f63686172303036622f6465736330303665002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303036342f636861723030366200000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303036342f63686172303036622f6465736330303664002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000030303030323930322d303030302d313030302d383030302d303038303566396233346662000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303036342f636861723030366200000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303036342f636861723030363700008801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000010100000400000055554944000173002400000030303030303036382d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303036340000000500000056616c75650002617900000019000000c054d735743526ea57788686e5bff568aff675f2e9a8befc1d000000090000004e6f74696679696e67000162000000000000000005000000466c616773000261730000002500000004000000726561640000000005000000777269746500000008000000696e64696361746500000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303036342f63686172303036372f6465736330303661002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303036342f636861723030363700000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303036342f63686172303036372f6465736330303639002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000030303030323930322d303030302d313030302d383030302d303038303566396233346662000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303036342f636861723030363700000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303036342f636861723030363500003801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000b50000000400000055554944000173002400000065363034653935642d613735392d343831372d383764332d61613030353038336130643100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303036340000000500000056616c756500026179000000000000000000000005000000466c61677300026173000000090000000400000072656164000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000310000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303035610000002001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000160000006f72672e626c75657a2e4761747453657276696365310000a80000000400000055554944000173002400000030303030303038322d303030302d313030302d383030302d303032366262373635323931000000000600000044657669636500016f000000250000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f313300000000000000070000005072696d6172790001620000010000000000000008000000496e636c756465730002616f00000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303035612f636861723030363000008801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000010100000400000055554944000173002400000030303030303031302d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303035610000000500000056616c75650002617900000019000000ce22ecd3258d6fa2c9051c49b3281fd3581ac02954f27a04f4000000090000004e6f74696679696e67000162000000000000000005000000466c616773000261730000002500000004000000726561640000000005000000777269746500000008000000696e64696361746500000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303035612f63686172303036302f6465736330303633002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303035612f636861723030363000000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303035612f63686172303036302f6465736330303632002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000030303030323930322d303030302d313030302d383030302d303038303566396233346662000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303035612f636861723030363000000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303035612f636861723030356400007001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000ea0000000400000055554944000173002400000030303030303032332d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303035610000000500000056616c756500026179000000280000004c1f1698d0d39c3321a5875685533f0e36cb215974814b62f533a39753351429ad985e524dbb71bc0000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303035612f63686172303035642f6465736330303566002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303035612f636861723030356400000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303035612f636861723030356200003801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000b50000000400000055554944000173002400000065363034653935642d613735392d343831372d383764332d61613030353038336130643100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303035610000000500000056616c756500026179000000000000000000000005000000466c61677300026173000000090000000400000072656164000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000310000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303035300000002001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000160000006f72672e626c75657a2e4761747453657276696365310000a80000000400000055554944000173002400000030303030303038612d303030302d313030302d383030302d303032366262373635323931000000000600000044657669636500016f000000250000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f313300000000000000070000005072696d6172790001620000010000000000000008000000496e636c756465730002616f00000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303035302f636861723030353600008801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000010100000400000055554944000173002400000030303030303031312d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303035300000000500000056616c756500026179000000190000004333a86ddd626c73ff065dc79e6bd65e403e5e6656ff37ac4a000000090000004e6f74696679696e67000162000000000000000005000000466c616773000261730000002500000004000000726561640000000005000000777269746500000008000000696e64696361746500000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303035302f63686172303035362f6465736330303539002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303035302f636861723030353600000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303035302f63686172303035362f6465736330303538002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000030303030323930322d303030302d313030302d383030302d303038303566396233346662000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303035302f636861723030353600000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303035302f636861723030353300007001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000ea0000000400000055554944000173002400000030303030303032332d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303035300000000500000056616c7565000261790000002b00000084460d1eb333851e7a6c7258498116fd93cb732431dd4a6f934e5387df41ac12cf7161e86238bdc518e1180005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303035302f63686172303035332f6465736330303535002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303035302f636861723030353300000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303035302f636861723030353100003801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000b50000000400000055554944000173002400000065363034653935642d613735392d343831372d383764332d61613030353038336130643100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303035300000000500000056616c756500026179000000000000000000000005000000466c61677300026173000000090000000400000072656164000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000310000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303034370000002001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000160000006f72672e626c75657a2e4761747453657276696365310000a80000000400000055554944000173002400000032323231303030302d353534612d343534362d353534322d343635333434353034363464000000000600000044657669636500016f000000250000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f313300000000000000070000005072696d6172790001620000010000000000000008000000496e636c756465730002616f00000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303034372f636861723030346400007001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000ea0000000400000055554944000173002400000030303030303032332d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303034370000000500000056616c75650002617900000027000000b0a8a34ea00c61b9660183c344acb37d9d23f31c1ce267783a149341ebae5d9dcd0548949ec468000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303034372f63686172303034642f6465736330303466002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303034372f636861723030346400000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303034372f636861723030346100006001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000da0000000400000055554944000173002400000032323231303030312d353534612d343534362d353534322d34363533343435303436346400000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303034370000000500000056616c75650002617900000017000000bf304d57146670a9539b6b2b108f59e89100fa97308b82000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303034372f63686172303034612f6465736330303463002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303034372f636861723030346100000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303034372f636861723030343800003801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000b50000000400000055554944000173002400000065363034653935642d613735392d343831372d383764332d61613030353038336130643100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303034370000000500000056616c756500026179000000000000000000000005000000466c61677300026173000000090000000400000072656164000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000310000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303033650000002001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000160000006f72672e626c75657a2e4761747453657276696365310000a80000000400000055554944000173002400000030303030313533302d313231322d656664652d313532332d373835666561626364313233000000000600000044657669636500016f000000250000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f313300000000000000070000005072696d6172790001620000010000000000000008000000496e636c756465730002616f00000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303033652f636861723030343400004801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000c20000000400000055554944000173002400000030303030313533312d313231322d656664652d313532332d37383566656162636431323300000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303033650000000500000056616c756500026179000000000000000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303033652f63686172303034342f6465736330303436002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303033652f636861723030343400000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303033652f636861723030343100004801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000c20000000400000055554944000173002400000030303030303061352d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303033650000000500000056616c756500026179000000000000000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303033652f63686172303034312f6465736330303433002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303033652f636861723030343100000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303033652f636861723030336600003801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000b50000000400000055554944000173002400000065363034653935642d613735392d343831372d383764332d61613030353038336130643100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303033650000000500000056616c756500026179000000000000000000000005000000466c61677300026173000000090000000400000072656164000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000310000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303032660000002001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000160000006f72672e626c75657a2e4761747453657276696365310000a80000000400000055554944000173002400000030303030303035352d303030302d313030302d383030302d303032366262373635323931000000000600000044657669636500016f000000250000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f313300000000000000070000005072696d6172790001620000010000000000000008000000496e636c756465730002616f00000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303032662f636861723030336200004801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000c20000000400000055554944000173002400000030303030303035302d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303032660000000500000056616c756500026179000000000000000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303032662f63686172303033622f6465736330303364002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303032662f636861723030336200000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303032662f636861723030333800004801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000c20000000400000055554944000173002400000030303030303034662d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303032660000000500000056616c756500026179000000000000000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303032662f63686172303033382f6465736330303361002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303032662f636861723030333800000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303032662f636861723030333500005001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000ca0000000400000055554944000173002400000030303030303034652d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303032660000000500000056616c7565000261790000000a00000002ea0005000103060104000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303032662f63686172303033352f6465736330303337002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a6000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303032662f636861723030333500000500000056616c756500026179000000020000000b0000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303032662f636861723030333200004801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000c20000000400000055554944000173002400000030303030303034632d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303032660000000500000056616c756500026179000000000000000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303032662f63686172303033322f6465736330303334002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303032662f636861723030333200000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303032662f636861723030333000003801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000b50000000400000055554944000173002400000065363034653935642d613735392d343831372d383764332d61613030353038336130643100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303032660000000500000056616c756500026179000000000000000000000005000000466c61677300026173000000090000000400000072656164000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000310000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303032360000002001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000160000006f72672e626c75657a2e4761747453657276696365310000a80000000400000055554944000173002400000030303030303061322d303030302d313030302d383030302d303032366262373635323931000000000600000044657669636500016f000000250000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f313300000000000000070000005072696d6172790001620000010000000000000008000000496e636c756465730002616f00000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303032362f636861723030326300006001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000da0000000400000055554944000173002400000030303030303033372d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303032360000000500000056616c7565000261790000001c0000008a5b51efc327b514b7cc70276f9e15a279d785a38c36e88959f98b3505000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303032362f63686172303032632f6465736330303265002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303032362f636861723030326300000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303032362f636861723030323900009001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e476174744368617261637465726973746963310000000a0100000400000055554944000173002400000030303030303061352d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303032360000000500000056616c75650002617900000046000000daf38c8555278d56e414620809dcf4edb6a7eabec4affc61392f26c3e5c5916a968e541d76fb18effa14ffeb35afae79307941f9a9bacf324e95013c2d41961c43c1c6b0917200000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303032362f63686172303032392f6465736330303262002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303032362f636861723030323900000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303032362f636861723030323700003801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000b50000000400000055554944000173002400000065363034653935642d613735392d343831372d383764332d61613030353038336130643100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303032360000000500000056616c756500026179000000000000000000000005000000466c61677300026173000000090000000400000072656164000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000310000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303030650000002001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000160000006f72672e626c75657a2e4761747453657276696365310000a80000000400000055554944000173002400000030303030303033652d303030302d313030302d383030302d303032366262373635323931000000000600000044657669636500016f000000250000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f313300000000000000070000005072696d6172790001620000010000000000000008000000496e636c756465730002616f00000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303030652f636861723030323300004801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000c20000000400000055554944000173002400000030303030303035332d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303030650000000500000056616c756500026179000000000000000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303030652f63686172303032332f6465736330303235002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303030652f636861723030323300000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303030652f636861723030323000004801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000c20000000400000055554944000173002400000030303030303035322d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303030650000000500000056616c756500026179000000000000000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303030652f63686172303032302f6465736330303232002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303030652f636861723030323000000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303030652f636861723030316400004801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000c20000000400000055554944000173002400000030303030303033302d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303030650000000500000056616c756500026179000000000000000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303030652f63686172303031642f6465736330303166002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303030652f636861723030316400000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303030652f636861723030316100004801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000c20000000400000055554944000173002400000030303030303032332d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303030650000000500000056616c756500026179000000000000000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303030652f63686172303031612f6465736330303163002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303030652f636861723030316100000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303030652f636861723030313700004801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000c20000000400000055554944000173002400000030303030303032312d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303030650000000500000056616c756500026179000000000000000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303030652f63686172303031372f6465736330303139002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303030652f636861723030313700000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303030652f636861723030313400004801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000c20000000400000055554944000173002400000030303030303032302d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303030650000000500000056616c756500026179000000000000000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303030652f63686172303031342f6465736330303136002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303030652f636861723030313400000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303030652f636861723030313100004801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000c20000000400000055554944000173002400000030303030303031342d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303030650000000500000056616c756500026179000000000000000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303030652f63686172303031312f6465736330303133002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303030652f636861723030313100000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303030652f636861723030306600003801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000b50000000400000055554944000173002400000065363034653935642d613735392d343831372d383764332d61613030353038336130643100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303030650000000500000056616c756500026179000000000000000000000005000000466c61677300026173000000090000000400000072656164000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000310000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303030610000002001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000160000006f72672e626c75657a2e4761747453657276696365310000a80000000400000055554944000173002400000030303030313830312d303030302d313030302d383030302d303038303566396233346662000000000600000044657669636500016f000000250000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f313300000000000000070000005072696d6172790001620000010000000000000008000000496e636c756465730002616f00000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303030612f636861723030306200005801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000d10000000400000055554944000173002400000030303030326130352d303030302d313030302d383030302d30303830356639623334666200000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303030610000000500000056616c7565000261790000000000000000000000090000004e6f74696679696e67000162000000000000000005000000466c616773000261730000000d00000008000000696e64696361746500000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303030612f63686172303030622f6465736330303064002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000030303030323930322d303030302d313030302d383030302d303038303566396233346662000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f44335f32435f35415f35425f35335f31332f73657276696365303030612f636861723030306200000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000250000002f6f72672f626c75657a2f686369302f6465765f43375f39355f35395f34385f45445f4430000000c0020000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000110000006f72672e626c75657a2e446576696365310000004402000000000000070000004164647265737300017300001100000043373a39353a35393a34383a45443a44300000000b000000416464726573735479706500017300000600000072616e646f6d0000040000004e616d6500017300080000004131333352445038000000000000000005000000416c696173000173000000000800000041313333524450380000000006000000506169726564000162000000000000000000000007000000547275737465640001620000000000000000000007000000426c6f636b6564000162000000000000000000000d0000004c656761637950616972696e67000162000000000000000000000000040000005253534900016e00d1ff000009000000436f6e6e6563746564000162000000000000000005000000555549447300026173000000290000002400000030303030666462662d303030302d313030302d383030302d30303830356639623334666200000000070000004164617074657200016f00000f0000002f6f72672f626c75657a2f686369300000000000100000004d616e756661637475726572446174610005617b71767d001f0000004c0002617900000013000000063100fe312467a4170600330001024e60e6a2000b00000053657276696365446174610005617b73767d000041000000000000002400000030303030666462662d303030302d313030302d383030302d30303830356639623334666200026179000000000d000000021a032db41ce3c06701009dba000000000000001000000053657276696365735265736f6c7665640001620000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000250000002f6f72672f626c75657a2f686369302f6465765f32325f32385f37305f33395f42315f443200000010020000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000110000006f72672e626c75657a2e446576696365310000009401000000000000070000004164647265737300017300001100000032323a32383a37303a33393a42313a44320000000b000000416464726573735479706500017300000600000072616e646f6d000005000000416c696173000173000000001100000032322d32382d37302d33392d42312d443200000006000000506169726564000162000000000000000000000007000000547275737465640001620000000000000000000007000000426c6f636b6564000162000000000000000000000d0000004c656761637950616972696e67000162000000000000000000000000040000005253534900016e00b0ff000009000000436f6e6e65637465640001620000000000000000050000005555494473000261730000000000000000000000070000004164617074657200016f00000f0000002f6f72672f626c75657a2f686369300000000000100000004d616e756661637475726572446174610005617b71767d00140000004c00026179000000080000000906030dc0a8d2a3000000001000000053657276696365735265736f6c7665640001620000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000250000002f6f72672f626c75657a2f686369302f6465765f37385f39435f38355f30415f39345f343000000070020000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000110000006f72672e626c75657a2e44657669636531000000f401000000000000070000004164647265737300017300001100000037383a39433a38353a30413a39343a34300000000b00000041646472657373547970650001730000060000007075626c69630000040000004e616d6500017300070000004c3330433457330005000000416c69617300017300000000070000004c333043345733000000000006000000506169726564000162000000000000000000000007000000547275737465640001620000000000000000000007000000426c6f636b6564000162000000000000000000000d0000004c656761637950616972696e67000162000000000000000000000000040000005253534900016e00b0ff000009000000436f6e6e6563746564000162000000000000000005000000555549447300026173000000290000002400000030303030666532342d303030302d313030302d383030302d30303830356639623334666200000000070000004164617074657200016f00000f0000002f6f72672f626c75657a2f686369300000000000100000004d616e756661637475726572446174610005617b71767d003b000000d101026179000000120000000000a04284a740c04fa88ad5e4917143475100004c000261790000000f000000068d003847f4f21d200600f610010200000000001000000053657276696365735265736f6c7665640001620000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000250000002f6f72672f626c75657a2f686369302f6465765f45445f31415f32355f32375f36435f384600000040020000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000110000006f72672e626c75657a2e44657669636531000000c401000000000000070000004164647265737300017300001100000045443a31413a32353a32373a36433a38460000000b000000416464726573735479706500017300000600000072616e646f6d0000040000004e616d6500017300130000004e616e6f6c6561662053747269702032443253000000000005000000416c69617300017300000000130000004e616e6f6c65616620537472697020324432530006000000506169726564000162000000000000000000000007000000547275737465640001620000000000000000000007000000426c6f636b6564000162000000000000000000000d0000004c656761637950616972696e67000162000000000000000000000000040000005253534900016e00d4ff000009000000436f6e6e65637465640001620000000000000000050000005555494473000261730000000000000000000000070000004164617074657200016f00000f0000002f6f72672f626c75657a2f686369300000000000100000004d616e756661637475726572446174610005617b71767d001f0000000b08026179000000130000004e4c353501041d01000400804b50fffe6c1238001000000053657276696365735265736f6c7665640001620000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000250000002f6f72672f626c75657a2f686369302f6465765f44385f33355f36375f41345f46355f4135000000a8020000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000110000006f72672e626c75657a2e446576696365310000002c02000000000000070000004164647265737300017300001100000044383a33353a36373a41343a46353a41350000000b000000416464726573735479706500017300000600000072616e646f6d0000040000004e616d65000173001500000050726f646967696f5f44383335363741344635413500000005000000416c696173000173000000001500000050726f646967696f5f4438333536374134463541350000000000000006000000506169726564000162000000000000000000000007000000547275737465640001620000000000000000000007000000426c6f636b6564000162000000000000000000000d0000004c656761637950616972696e67000162000000000000000000000000040000005253534900016e00b4ff000009000000436f6e6e6563746564000162000000000000000005000000555549447300026173000000290000002400000030366161313931302d663232612d313165332d396461612d30303032613564356335316200000000070000004164617074657200016f00000f0000002f6f72672f626c75657a2f686369300000000000100000004d616e756661637475726572446174610005617b71767d003b0000000225026179000000060000004409800700020000000000004c0002617900000017000000021506aa1910f22a11e39daa0002a5d5c51b071b700ec40000000000070000005478506f77657200016e000004000000000000001000000053657276696365735265736f6c7665640001620000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000250000002f6f72672f626c75657a2f686369302f6465765f44305f43325f34455f30385f41425f353700000020020000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000110000006f72672e626c75657a2e44657669636531000000a401000000000000070000004164647265737300017300001100000044303a43323a34453a30383a41423a35370000000b00000041646472657373547970650001730000060000007075626c6963000005000000416c696173000173000000001100000044302d43322d34452d30382d41422d353700000006000000506169726564000162000000000000000000000007000000547275737465640001620000000000000000000007000000426c6f636b6564000162000000000000000000000d0000004c656761637950616972696e67000162000000000000000000000000040000005253534900016e00bdff000009000000436f6e6e65637465640001620000000000000000050000005555494473000261730000000000000000000000070000004164617074657200016f00000f0000002f6f72672f626c75657a2f686369300000000000100000004d616e756661637475726572446174610005617b71767d0024000000750002617900000018000000420401806ed0c24e08ab57d2c24e08ab5601000000000000000000001000000053657276696365735265736f6c7665640001620000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000250000002f6f72672f626c75657a2f686369302f6465765f44305f30335f44465f42315f34325f364600000048020000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000110000006f72672e626c75657a2e44657669636531000000cc01000000000000070000004164647265737300017300001100000044303a30333a44463a42313a34323a36460000000b00000041646472657373547970650001730000060000007075626c69630000040000004e616d6500017300120000005b54565d204d61737465722062656420747600000000000005000000416c69617300017300000000120000005b54565d204d617374657220626564207476000006000000506169726564000162000000000000000000000007000000547275737465640001620000000000000000000007000000426c6f636b6564000162000000000000000000000d0000004c656761637950616972696e67000162000000000000000000000000040000005253534900016e00c6ff000009000000436f6e6e65637465640001620000000000000000050000005555494473000261730000000000000000000000070000004164617074657200016f00000f0000002f6f72672f626c75657a2f686369300000000000100000004d616e756661637475726572446174610005617b71767d0024000000750002617900000018000000420401017ed003dfb1426fd203dfb1426e01000000000000000000001000000053657276696365735265736f6c7665640001620000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000250000002f6f72672f626c75657a2f686369302f6465765f30425f30325f35455f34465f35435f393400000010020000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000110000006f72672e626c75657a2e446576696365310000009401000000000000070000004164647265737300017300001100000030423a30323a35453a34463a35433a39340000000b000000416464726573735479706500017300000600000072616e646f6d000005000000416c696173000173000000001100000030422d30322d35452d34462d35432d393400000006000000506169726564000162000000000000000000000007000000547275737465640001620000000000000000000007000000426c6f636b6564000162000000000000000000000d0000004c656761637950616972696e67000162000000000000000000000000040000005253534900016e00d3ff000009000000436f6e6e65637465640001620000000000000000050000005555494473000261730000000000000000000000070000004164617074657200016f00000f0000002f6f72672f626c75657a2f686369300000000000100000004d616e756661637475726572446174610005617b71767d00140000004c000261790000000800000009060312c0a8d208000000001000000053657276696365735265736f6c7665640001620000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000250000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f374300000098030000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000110000006f72672e626c75657a2e446576696365310000001c03000000000000070000004164647265737300017300001100000046463a44383a36363a35383a41353a37430000000b000000416464726573735479706500017300000600000072616e646f6d0000040000004e616d65000173000f00000045766520427574746f6e20464342410005000000416c696173000173000000000f00000045766520427574746f6e2046434241000000000006000000506169726564000162000000000000000000000007000000547275737465640001620000000000000000000007000000426c6f636b6564000162000000000000000000000d0000004c656761637950616972696e67000162000000000000000000000000040000005253534900016e00caff000009000000436f6e6e65637465640001620000000000000000050000005555494473000261730000005d0100002400000030303030303033652d303030302d313030302d383030302d303032366262373635323931000000002400000030303030303035352d303030302d313030302d383030302d303032366262373635323931000000002400000030303030303038392d303030302d313030302d383030302d303032366262373635323931000000002400000030303030303039362d303030302d313030302d383030302d303032366262373635323931000000002400000030303030303061322d303030302d313030302d383030302d303032366262373635323931000000002400000030303030313830302d303030302d313030302d383030302d303038303566396233346662000000002400000030303030313830312d303030302d313030302d383030302d303038303566396233346662000000002400000065383633663030372d303739652d343866662d386632372d3963323630356132396635320000000000000000070000004164617074657200016f00000f0000002f6f72672f626c75657a2f686369300000000000100000004d616e756661637475726572446174610005617b71767d001f0000004c0002617900000013000000063100f445fbc5aa1b0f00f000010231164ce5001000000053657276696365735265736f6c7665640001620000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000310000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303036370000002001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000160000006f72672e626c75657a2e4761747453657276696365310000a80000000400000055554944000173002400000030303030303039362d303030302d313030302d383030302d303032366262373635323931000000000600000044657669636500016f000000250000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f374300000000000000070000005072696d6172790001620000010000000000000008000000496e636c756465730002616f00000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303036372f636861723030373700003801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000b50000000400000055554944000173002400000065363034653935642d613735392d343831372d383764332d61613030353038336130643100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303036370000000500000056616c756500026179000000000000000000000005000000466c61677300026173000000090000000400000072656164000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303036372f636861723030373300008801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000010100000400000055554944000173002400000030303030303037392d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303036370000000500000056616c7565000261790000001c0000008cf98b58fff7d782824141107fdc63b6527a8a436061bcc68f7e6b0b090000004e6f74696679696e67000162000000000000000005000000466c616773000261730000002500000004000000726561640000000005000000777269746500000008000000696e64696361746500000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303036372f63686172303037332f6465736330303736002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000030303030323930322d303030302d313030302d383030302d303038303566396233346662000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303036372f636861723030373300000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303036372f63686172303037332f6465736330303735002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303036372f636861723030373300000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303036372f636861723030366600008801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000010100000400000055554944000173002400000030303030303038662d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303036370000000500000056616c7565000261790000001c0000001bbbedc69f899451c85a3cb18039e7b18ae4aae5cd91ce639f3eec24090000004e6f74696679696e67000162000000000000000005000000466c616773000261730000002500000004000000726561640000000005000000777269746500000008000000696e64696361746500000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303036372f63686172303036662f6465736330303732002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000030303030323930322d303030302d313030302d383030302d303038303566396233346662000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303036372f636861723030366600000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303036372f63686172303036662f6465736330303731002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303036372f636861723030366600000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303036372f636861723030366200008801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000010100000400000055554944000173002400000030303030303036382d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303036370000000500000056616c7565000261790000001c00000030d4c96faf74ec43c4767cabf1f33b21f1a75606d43ec61ffad112e3090000004e6f74696679696e67000162000000000000000005000000466c616773000261730000002500000004000000726561640000000005000000777269746500000008000000696e64696361746500000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303036372f63686172303036622f6465736330303665002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000030303030323930322d303030302d313030302d383030302d303038303566396233346662000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303036372f636861723030366200000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303036372f63686172303036622f6465736330303664002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303036372f636861723030366200000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303036372f636861723030363800006801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000e20000000400000055554944000173002400000030303030303032332d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303036370000000500000056616c7565000261790000001e00000068dc9a07f960f43eb92a5ea12b3bd46ea0360a9bc4b0ef4a1064c113f58a00000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303036372f63686172303036382f6465736330303661002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303036372f636861723030363800000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000310000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303034360000002001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000160000006f72672e626c75657a2e4761747453657276696365310000a80000000400000055554944000173002400000065383633663030372d303739652d343866662d386632372d396332363035613239663532000000000600000044657669636500016f000000250000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f374300000000000000070000005072696d6172790001620000010000000000000008000000496e636c756465730002616f00000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303034362f636861723030363500003801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000b50000000400000055554944000173002400000065363034653935642d613735392d343831372d383764332d61613030353038336130643100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303034360000000500000056616c756500026179000000000000000000000005000000466c61677300026173000000090000000400000072656164000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303034362f636861723030363200004801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000c20000000400000055554944000173002400000030303030303061352d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303034360000000500000056616c756500026179000000000000000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303034362f63686172303036322f6465736330303634002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303034362f636861723030363200000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303034362f636861723030356600004801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000c20000000400000055554944000173002400000065383633663131642d303739652d343866662d386632372d39633236303561323966353200000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303034360000000500000056616c756500026179000000000000000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303034362f63686172303035662f6465736330303631002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303034362f636861723030356600000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303034362f63686172303035630000b001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e476174744368617261637465726973746963310000002a0100000400000055554944000173002400000065383633663133312d303739652d343866662d386632372d39633236303561323966353200000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303034360000000500000056616c7565000261790000006b0000003ce7a58c4cc046586313cd5e7a9e95131ae166b4d689f6c9e98b33452ce7a4a64a12922f4e1b95f7b424101917aa58e03d0d96c383cfebed7134132fa6906be276fe4cb58acb5fdfb62334fcf284bfc4d75fd35ee558ba505d8107566a00621fc5810d9644fba101d48a8a0005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303034362f63686172303035632f6465736330303565002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303034362f636861723030356300000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303034362f636861723030353900006801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000e20000000400000055554944000173002400000065383633663131372d303739652d343866662d386632372d39633236303561323966353200000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303034360000000500000056616c7565000261790000002200000082fc818fc6b07331d1395f33a8564e77cc1ff3c07aa7a5086c876860b681ab6ed45c000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303034362f63686172303035392f6465736330303562002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303034362f636861723030353900000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303034362f636861723030353600007801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000f20000000400000055554944000173002400000065383633663131362d303739652d343866662d386632372d39633236303561323966353200000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303034360000000500000056616c75650002617900000034000000e8f9ff23d8034e61b3bca655238a0b31352bb2ac92a7dc917df918a504acfa7c65fdd59131eac4ea49136ff124793a3d8b84366905000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303034362f63686172303035362f6465736330303538002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303034362f636861723030353600000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303034362f636861723030353300004801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000c20000000400000055554944000173002400000065383633663132312d303739652d343866662d386632372d39633236303561323966353200000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303034360000000500000056616c756500026179000000000000000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303034362f63686172303035332f6465736330303535002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303034362f636861723030353300000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303034362f636861723030353000004801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000c20000000400000055554944000173002400000065383633663131632d303739652d343866662d386632372d39633236303561323966353200000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303034360000000500000056616c756500026179000000000000000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303034362f63686172303035302f6465736330303532002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303034362f636861723030353000000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303034362f636861723030346400006001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000da0000000400000055554944000173002400000065383633663131322d303739652d343866662d386632372d39633236303561323966353200000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303034360000000500000056616c7565000261790000001b000000f26d31c4b56c2e47c3906451ac615d841f1d9acba308c08f054dce0005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303034362f63686172303034642f6465736330303466002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303034362f636861723030346400000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303034362f636861723030346100007001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000ea0000000400000055554944000173002400000065383633663131652d303739652d343866662d386632372d39633236303561323966353200000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303034360000000500000056616c756500026179000000290000004f59cab057e9eceac3ee2548eb47ffe7bf531f61d64d4abf56ca117af439ad2185971b89a61eafdfa400000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303034362f63686172303034612f6465736330303463002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303034362f636861723030346100000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303034362f636861723030343700006801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000e20000000400000055554944000173002400000030303030303032332d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303034360000000500000056616c7565000261790000001e0000008648819bfcf041c81fcaf693fc2c2f4e8e8a7be5e35e3b455a2ac446342400000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303034362f63686172303034372f6465736330303439002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303034362f636861723030343700000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000310000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303033390000002001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000160000006f72672e626c75657a2e4761747453657276696365310000a80000000400000055554944000173002400000030303030303038392d303030302d313030302d383030302d303032366262373635323931000000000600000044657669636500016f000000250000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f374300000000000000070000005072696d6172790001620000010000000000000008000000496e636c756465730002616f00000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303033392f636861723030343400003801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000b50000000400000055554944000173002400000065363034653935642d613735392d343831372d383764332d61613030353038336130643100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303033390000000500000056616c756500026179000000000000000000000005000000466c61677300026173000000090000000400000072656164000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303033392f636861723030343100004801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000c20000000400000055554944000173002400000030303030303061352d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303033390000000500000056616c756500026179000000000000000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303033392f63686172303034312f6465736330303433002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303033392f636861723030343100000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303033392f636861723030336400008801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000010100000400000055554944000173002400000030303030303037332d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303033390000000500000056616c7565000261790000001c000000a1e5d72ab52fc742a78feae94ad2df30f39732bd455d2ad92fbb699f090000004e6f74696679696e67000162000000000000000005000000466c616773000261730000002500000004000000726561640000000005000000777269746500000008000000696e64696361746500000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303033392f63686172303033642f6465736330303430002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000030303030323930322d303030302d313030302d383030302d303038303566396233346662000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303033392f636861723030336400000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303033392f63686172303033642f6465736330303366002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303033392f636861723030336400000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303033392f636861723030336100006801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000e20000000400000055554944000173002400000030303030303032332d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303033390000000500000056616c75650002617900000021000000ff6fcae85d64504982b7a4752df8fb4452239352acfea5939a39e6c28c406c56a700000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303033392f63686172303033612f6465736330303363002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303033392f636861723030336100000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000310000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303032610000002001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000160000006f72672e626c75657a2e4761747453657276696365310000a80000000400000055554944000173002400000030303030303035352d303030302d313030302d383030302d303032366262373635323931000000000600000044657669636500016f000000250000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f374300000000000000070000005072696d6172790001620000010000000000000008000000496e636c756465730002616f00000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303032612f636861723030333700003801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000b50000000400000055554944000173002400000065363034653935642d613735392d343831372d383764332d61613030353038336130643100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303032610000000500000056616c756500026179000000000000000000000005000000466c61677300026173000000090000000400000072656164000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303032612f636861723030333400004801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000c20000000400000055554944000173002400000030303030303035302d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303032610000000500000056616c756500026179000000000000000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303032612f63686172303033342f6465736330303336002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303032612f636861723030333400000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303032612f636861723030333100004801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000c20000000400000055554944000173002400000030303030303034662d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303032610000000500000056616c756500026179000000000000000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303032612f63686172303033312f6465736330303333002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303032612f636861723030333100000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303032612f636861723030326500005001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000ca0000000400000055554944000173002400000030303030303034652d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303032610000000500000056616c7565000261790000000a000000024f0005000103060104000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303032612f63686172303032652f6465736330303330002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a6000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303032612f636861723030326500000500000056616c756500026179000000020000000e0000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303032612f636861723030326200004801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000c20000000400000055554944000173002400000030303030303034632d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303032610000000500000056616c756500026179000000000000000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303032612f63686172303032622f6465736330303264002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303032612f636861723030326200000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000310000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303032310000002001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000160000006f72672e626c75657a2e4761747453657276696365310000a80000000400000055554944000173002400000030303030303061322d303030302d313030302d383030302d303032366262373635323931000000000600000044657669636500016f000000250000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f374300000000000000070000005072696d6172790001620000010000000000000008000000496e636c756465730002616f00000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303032312f636861723030323800003801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000b50000000400000055554944000173002400000065363034653935642d613735392d343831372d383764332d61613030353038336130643100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303032310000000500000056616c756500026179000000000000000000000005000000466c61677300026173000000090000000400000072656164000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303032312f636861723030323500009001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e476174744368617261637465726973746963310000000a0100000400000055554944000173002400000030303030303061352d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303032310000000500000056616c756500026179000000460000004749c3506527b2a6154ef462499e14311039b0f3d228a44327ef1b62c28ae997802fb821a413211bc31145ee0c53680f3eda3bff825d0a78c67129d6851fd7098dffc6310b2200000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303032312f63686172303032352f6465736330303237002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303032312f636861723030323500000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303032312f636861723030323200006001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000da0000000400000055554944000173002400000030303030303033372d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303032310000000500000056616c7565000261790000001c00000006d1aeb01ac30545bac72d7233429346b8b3874c5b922b4ef677aabb05000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303032312f63686172303032322f6465736330303234002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303032312f636861723030323200000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000310000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303030390000002001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000160000006f72672e626c75657a2e4761747453657276696365310000a80000000400000055554944000173002400000030303030303033652d303030302d313030302d383030302d303032366262373635323931000000000600000044657669636500016f000000250000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f374300000000000000070000005072696d6172790001620000010000000000000008000000496e636c756465730002616f00000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303030392f636861723030316600003801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000b50000000400000055554944000173002400000065363034653935642d613735392d343831372d383764332d61613030353038336130643100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303030390000000500000056616c756500026179000000000000000000000005000000466c61677300026173000000090000000400000072656164000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303030392f636861723030316300004801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000c20000000400000055554944000173002400000030303030303035332d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303030390000000500000056616c756500026179000000000000000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303030392f63686172303031632f6465736330303165002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303030392f636861723030316300000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303030392f636861723030313900004801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000c20000000400000055554944000173002400000030303030303035322d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303030390000000500000056616c756500026179000000000000000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303030392f63686172303031392f6465736330303162002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303030392f636861723030313900000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303030392f636861723030313600004801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000c20000000400000055554944000173002400000030303030303033302d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303030390000000500000056616c756500026179000000000000000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303030392f63686172303031362f6465736330303138002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303030392f636861723030313600000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303030392f636861723030313300004801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000c20000000400000055554944000173002400000030303030303032312d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303030390000000500000056616c756500026179000000000000000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303030392f63686172303031332f6465736330303135002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303030392f636861723030313300000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303030392f636861723030313000004801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000c20000000400000055554944000173002400000030303030303032302d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303030390000000500000056616c756500026179000000000000000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303030392f63686172303031302f6465736330303132002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303030392f636861723030313000000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303030392f636861723030306400004801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000c20000000400000055554944000173002400000030303030303031342d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303030390000000500000056616c756500026179000000000000000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303030392f63686172303030642f6465736330303066002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303030392f636861723030306400000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303030392f636861723030306100004801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000c20000000400000055554944000173002400000030303030303032332d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303030390000000500000056616c756500026179000000000000000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303030392f63686172303030612f6465736330303063002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303030392f636861723030306100000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000310000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f37432f73657276696365303030380000002001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000160000006f72672e626c75657a2e4761747453657276696365310000a80000000400000055554944000173002400000030303030313830312d303030302d313030302d383030302d303038303566396233346662000000000600000044657669636500016f000000250000002f6f72672f626c75657a2f686369302f6465765f46465f44385f36365f35385f41355f374300000000000000070000005072696d6172790001620000010000000000000008000000496e636c756465730002616f00000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000250000002f6f72672f626c75657a2f686369302f6465765f42445f32345f36465f38355f41415f363100000038020000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000110000006f72672e626c75657a2e44657669636531000000bc01000000000000070000004164647265737300017300001100000042443a32343a36463a38353a41413a36310000000b00000041646472657373547970650001730000060000007075626c69630000040000004e616d650001730012000000447265616d7e42443234364638354141363100000000000005000000416c6961730001730000000012000000447265616d7e424432343646383541413631000006000000506169726564000162000000000000000000000007000000547275737465640001620000000000000000000007000000426c6f636b6564000162000000000000000000000d0000004c656761637950616972696e67000162000000000000000000000000040000005253534900016e00deff000009000000436f6e6e65637465640001620000000000000000050000005555494473000261730000000000000000000000070000004164617074657200016f00000f0000002f6f72672f626c75657a2f686369300000000000100000004d616e756661637475726572446174610005617b71767d00120000004851026179000000060000003336343635360000000000001000000053657276696365735265736f6c7665640001620000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000250000002f6f72672f626c75657a2f686369302f6465765f43315f43375f32375f37445f35355f414200000098020000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000110000006f72672e626c75657a2e446576696365310000001c02000000000000070000004164647265737300017300001100000043313a43373a32373a37443a35353a41420000000b000000416464726573735479706500017300000600000072616e646f6d000005000000416c696173000173000000001100000043312d43372d32372d37442d35352d414200000006000000506169726564000162000000000000000000000007000000547275737465640001620000000000000000000007000000426c6f636b6564000162000000000000000000000d0000004c656761637950616972696e67000162000000000000000000000000040000005253534900016e00deff000009000000436f6e6e6563746564000162000000000000000005000000555549447300026173000000290000002400000063626132306430302d323234642d313165362d396662382d30303032613564356335316200000000070000004164617074657200016f00000f0000002f6f72672f626c75657a2f686369300000000000100000004d616e756661637475726572446174610005617b71767d0012000000590002617900000006000000c1c7277d55ab0000000000000b00000053657276696365446174610005617b73767d00003a000000000000002400000030303030306430302d303030302d313030302d383030302d30303830356639623334666200026179000000000600000063d0d26411040000000000001000000053657276696365735265736f6c7665640001620000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000250000002f6f72672f626c75657a2f686369302f6465765f46305f42335f45435f32305f44345f373600000028020000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000110000006f72672e626c75657a2e44657669636531000000ac01000000000000070000004164647265737300017300001100000046303a42333a45433a32303a44343a37360000000b00000041646472657373547970650001730000060000007075626c6963000005000000416c696173000173000000001100000046302d42332d45432d32302d44342d373600000006000000506169726564000162000000000000000000000007000000547275737465640001620000000000000000000007000000426c6f636b6564000162000000000000000000000d0000004c656761637950616972696e67000162000000000000000000000000040000005253534900016e00ceff000009000000436f6e6e65637465640001620000000000000000050000005555494473000261730000000000000000000000070000004164617074657200016f00000f0000002f6f72672f626c75657a2f686369300000000000100000004d616e756661637475726572446174610005617b71767d00130000004c000261790000000700000010050714e02d0e0000000000070000005478506f77657200016e000004000000000000001000000053657276696365735265736f6c7665640001620000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000250000002f6f72672f626c75657a2f686369302f6465765f44305f30335f44465f39465f33305f353900000020020000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000110000006f72672e626c75657a2e44657669636531000000a401000000000000070000004164647265737300017300001100000044303a30333a44463a39463a33303a35390000000b00000041646472657373547970650001730000060000007075626c6963000005000000416c696173000173000000001100000044302d30332d44462d39462d33302d353900000006000000506169726564000162000000000000000000000007000000547275737465640001620000000000000000000007000000426c6f636b6564000162000000000000000000000d0000004c656761637950616972696e67000162000000000000000000000000040000005253534900016e00bcff000009000000436f6e6e65637465640001620000000000000000050000005555494473000261730000000000000000000000070000004164617074657200016f00000f0000002f6f72672f626c75657a2f686369300000000000100000004d616e756661637475726572446174610005617b71767d00240000007500026179000000180000004204018060d003df9f3059d203df9f305801000000000000000000001000000053657276696365735265736f6c7665640001620000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000250000002f6f72672f626c75657a2f686369302f6465765f42345f45385f34325f34415f37335f384200000050020000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000110000006f72672e626c75657a2e44657669636531000000d401000000000000070000004164647265737300017300001100000042343a45383a34323a34413a37333a38420000000b00000041646472657373547970650001730000060000007075626c69630000040000004e616d6500017300140000004c45446e657457463030303031433441373338410000000005000000416c69617300017300000000140000004c45446e65745746303030303143344137333841000000000000000006000000506169726564000162000000000000000000000007000000547275737465640001620000000000000000000007000000426c6f636b6564000162000000000000000000000d0000004c656761637950616972696e67000162000000000000000000000000040000005253534900016e00afff000009000000436f6e6e65637465640001620000000000000000050000005555494473000261730000000000000000000000070000004164617074657200016f00000f0000002f6f72672f626c75657a2f686369300000000000100000004d616e756661637475726572446174610005617b71767d0027000000005a0261790000001b0000005203b4e8424a738a001c1a03010203040506070809a1a2a3a4a5a6001000000053657276696365735265736f6c7665640001620000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000250000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f4143000000c8030000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000110000006f72672e626c75657a2e446576696365310000004c03000000000000070000004164647265737300017300001100000043463a44463a41353a43343a46343a41430000000b000000416464726573735479706500017300000600000072616e646f6d0000040000004e616d6500017300130000004e616e6f6c6561662053747269702032443253000000000005000000416c69617300017300000000130000004e616e6f6c65616620537472697020324432530006000000506169726564000162000000000000000000000007000000547275737465640001620000000000000000000007000000426c6f636b6564000162000000000000000000000d0000004c656761637950616972696e67000162000000000000000000000000040000005253534900016e00c4ff000009000000436f6e6e6563746564000162000000000000000005000000555549447300026173000000890100002400000030303030303033652d303030302d313030302d383030302d303032366262373635323931000000002400000030303030303034332d303030302d313030302d383030302d303032366262373635323931000000002400000030303030303035352d303030302d313030302d383030302d303032366262373635323931000000002400000030303030303061322d303030302d313030302d383030302d303032366262373635323931000000002400000030303030303233392d303030302d313030302d383030302d303032366262373635323931000000002400000030303030303730312d303030302d313030302d383030302d303032366262373635323931000000002400000030303030313830302d303030302d313030302d383030302d303038303566396233346662000000002400000030653963633637372d613731662d386238332d623834642d353638323738373930636233000000002400000036643261653163342d396165612d313165612d626233372d30323432616331333030303200000000070000004164617074657200016f00000f0000002f6f72672f626c75657a2f686369300000000000100000004d616e756661637475726572446174610005617b71767d001f0000004c0002617900000013000000063100eab2458702490500cf0001028f7cafd6001000000053657276696365735265736f6c7665640001620000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000310000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303039620000002001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000160000006f72672e626c75657a2e4761747453657276696365310000a80000000400000055554944000173002400000036643261653163342d396165612d313165612d626233372d303234326163313330303032000000000600000044657669636500016f000000250000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f414300000000000000070000005072696d6172790001620000010000000000000008000000496e636c756465730002616f00000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303039622f636861723030613100004801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000c20000000400000055554944000173002400000061396530613264652d396165612d313165612d626233372d30323432616331333030303200000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303039620000000500000056616c756500026179000000000000000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303039622f636861723030396500007001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000e90000000400000055554944000173002400000036643261646461302d396165612d313165612d626233372d30323432616331333030303200000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303039620000000500000056616c7565000261790000000000000000000000090000004e6f74696679696e67000162000000000000000005000000466c616773000261730000002500000004000000726561640000000005000000777269746500000008000000696e64696361746500000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303039622f63686172303039652f6465736330306130002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000030303030323930322d303030302d313030302d383030302d303038303566396233346662000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303039622f636861723030396500000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303039622f636861723030396300004801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000c20000000400000055554944000173002400000036643261646664612d396165612d313165612d626233372d30323432616331333030303200000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303039620000000500000056616c756500026179000000000000000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000310000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303039340000002001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000160000006f72672e626c75657a2e4761747453657276696365310000a80000000400000055554944000173002400000030653963633637372d613731662d386238332d623834642d353638323738373930636233000000000600000044657669636500016f000000250000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f414300000000000000070000005072696d6172790001620000010000000000000008000000496e636c756465730002616f00000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303039342f636861723030393900004801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000c20000000400000055554944000173002400000031333536333465362d336363312d303562382d306434392d34383432616435663933633900000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303039340000000500000056616c756500026179000000000000000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303039342f636861723030393700004801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000c20000000400000055554944000173002400000030393139393231632d633465372d386339342d353034622d64303461313436623831353700000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303039340000000500000056616c756500026179000000000000000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303039342f636861723030393500004801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000c20000000400000055554944000173002400000061356635623538312d663638662d343363362d383866312d38343136666263376335313300000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303039340000000500000056616c756500026179000000000000000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000310000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303038320000002001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000160000006f72672e626c75657a2e4761747453657276696365310000a80000000400000055554944000173002400000030303030303233392d303030302d313030302d383030302d303032366262373635323931000000000600000044657669636500016f000000250000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f414300000000000000070000005072696d6172790001620000010000000000000008000000496e636c756465730002616f00000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303038322f636861723030393000008801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000010100000400000055554944000173002400000030303030303234612d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303038320000000500000056616c7565000261790000001b000000e460312c7bc34b123a10a49d8059b122180dbc32d76a17e0cc1ede00090000004e6f74696679696e67000162000000000000000005000000466c616773000261730000002500000004000000726561640000000005000000777269746500000008000000696e64696361746500000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303038322f63686172303039302f6465736330303933002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303038322f636861723030393000000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303038322f63686172303039302f6465736330303932002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000030303030323930322d303030302d313030302d383030302d303038303566396233346662000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303038322f636861723030393000000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303038322f636861723030386300008801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000010100000400000055554944000173002400000030303030303233632d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303038320000000500000056616c756500026179000000170000001b19b57fe169eb38d1c9104328b0542156c964e57f508a0000000000090000004e6f74696679696e67000162000000000000000005000000466c616773000261730000002500000004000000726561640000000005000000777269746500000008000000696e64696361746500000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303038322f63686172303038632f6465736330303866002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303038322f636861723030386300000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303038322f63686172303038632f6465736330303865002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000030303030323930322d303030302d313030302d383030302d303038303566396233346662000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303038322f636861723030386300000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303038322f636861723030383800008801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000010100000400000055554944000173002400000030303030303233612d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303038320000000500000056616c7565000261790000001b000000e635fd8679a7e6020ccba38cd8614572a15b640a511ccf3b4af9d100090000004e6f74696679696e67000162000000000000000005000000466c616773000261730000002500000004000000726561640000000005000000777269746500000008000000696e64696361746500000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303038322f63686172303038382f6465736330303862002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303038322f636861723030383800000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303038322f63686172303038382f6465736330303861002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000030303030323930322d303030302d313030302d383030302d303038303566396233346662000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303038322f636861723030383800000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303038322f636861723030383500004801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000c20000000400000055554944000173002400000030303030303061352d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303038320000000500000056616c756500026179000000000000000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303038322f63686172303038352f6465736330303837002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303038322f636861723030383500000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303038322f636861723030383300003801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000b50000000400000055554944000173002400000065363034653935642d613735392d343831372d383764332d61613030353038336130643100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303038320000000500000056616c756500026179000000000000000000000005000000466c61677300026173000000090000000400000072656164000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000310000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303036390000002001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000160000006f72672e626c75657a2e4761747453657276696365310000a80000000400000055554944000173002400000030303030303730312d303030302d313030302d383030302d303032366262373635323931000000000600000044657669636500016f000000250000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f414300000000000000070000005072696d6172790001620000010000000000000008000000496e636c756465730002616f00000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303036392f636861723030376600006001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000da0000000400000055554944000173002400000030303030303730342d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303036390000000500000056616c7565000261790000001700000073ac012862d53de353b04377c9a2a7556206ff9b1aa111000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303036392f63686172303037662f6465736330303831002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303036392f636861723030376600000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303036392f636861723030376200008801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000010100000400000055554944000173002400000030303030303232622d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303036390000000500000056616c756500026179000000180000009ab83ec21e47d91d097e1fabcdbf7ca46509dfa93abc88fb00000000090000004e6f74696679696e67000162000000000000000005000000466c616773000261730000002500000004000000726561640000000005000000777269746500000008000000696e64696361746500000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303036392f63686172303037622f6465736330303765002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303036392f636861723030376200000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303036392f63686172303037622f6465736330303764002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000030303030323930322d303030302d313030302d383030302d303038303566396233346662000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303036392f636861723030376200000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303036392f636861723030373700008801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000010100000400000055554944000173002400000030303030303730332d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303036390000000500000056616c7565000261790000001900000081edc5e8a83b73820820794a72c67338209b0bfa6d661492db000000090000004e6f74696679696e67000162000000000000000005000000466c616773000261730000002500000004000000726561640000000005000000777269746500000008000000696e64696361746500000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303036392f63686172303037372f6465736330303761002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303036392f636861723030373700000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303036392f63686172303037372f6465736330303739002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000030303030323930322d303030302d313030302d383030302d303038303566396233346662000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303036392f636861723030373700000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303036392f636861723030373300008801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000010100000400000055554944000173002400000030303030303730322d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303036390000000500000056616c75650002617900000019000000813bc232fdc177d62806e74416de6807f5526c98cfe98f3b38000000090000004e6f74696679696e67000162000000000000000005000000466c616773000261730000002500000004000000726561640000000005000000777269746500000008000000696e64696361746500000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303036392f63686172303037332f6465736330303736002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303036392f636861723030373300000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303036392f63686172303037332f6465736330303735002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000030303030323930322d303030302d313030302d383030302d303038303566396233346662000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303036392f636861723030373300000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303036392f63686172303036660000d801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000510100000400000055554944000173002400000030303030303730362d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303036390000000500000056616c7565000261790000006800000081faf9feacc0e99c6447c9683b1faba564bf8cebb718a354d85c0bf1747296776b7be7ceee8e204c255e2d4971060b73da317ac7c38c1ddbdc593cb35c4e13e22e890b98c952e0ae21c22a42f6817ede89a2980f8301af0e2ca6f66110b8c352df3290d3ce132afb00000000090000004e6f74696679696e67000162000000000000000005000000466c616773000261730000002500000004000000726561640000000005000000777269746500000008000000696e64696361746500000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303036392f63686172303036662f6465736330303732002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303036392f636861723030366600000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303036392f63686172303036662f6465736330303731002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000030303030323930322d303030302d313030302d383030302d303038303566396233346662000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303036392f636861723030366600000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303036392f636861723030366300004801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000c20000000400000055554944000173002400000030303030303061352d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303036390000000500000056616c756500026179000000000000000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303036392f63686172303036632f6465736330303665002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303036392f636861723030366300000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303036392f636861723030366100003801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000b50000000400000055554944000173002400000065363034653935642d613735392d343831372d383764332d61613030353038336130643100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303036390000000500000056616c756500026179000000000000000000000005000000466c61677300026173000000090000000400000072656164000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000310000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303033630000002001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000160000006f72672e626c75657a2e4761747453657276696365310000a80000000400000055554944000173002400000030303030303034332d303030302d313030302d383030302d303032366262373635323931000000000600000044657669636500016f000000250000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f414300000000000000070000005072696d6172790001620000010000000000000008000000496e636c756465730002616f00000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303033632f636861723030363500008801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000010100000400000055554944000173002400000030303030303234622d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303033630000000500000056616c75650002617900000018000000e5fd94280f3d0a882d8f31986eebb2a63c63d61ae01b147c00000000090000004e6f74696679696e67000162000000000000000005000000466c616773000261730000002500000004000000726561640000000005000000777269746500000008000000696e64696361746500000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303033632f63686172303036352f6465736330303638002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303033632f636861723030363500000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303033632f63686172303036352f6465736330303637002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000030303030323930322d303030302d313030302d383030302d303038303566396233346662000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303033632f636861723030363500000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303033632f63686172303036310000a001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000190100000400000055554944000173002400000030303030303134342d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303033630000000500000056616c7565000261790000002f00000017c9379c7143b5a575b2dbf7c51531707018af85f2927959baa1d0d39c4a9566c4ef8286a5d3aadc225a80791ed0ff0000000000090000004e6f74696679696e67000162000000000000000005000000466c616773000261730000002500000004000000726561640000000005000000777269746500000008000000696e64696361746500000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303033632f63686172303036312f6465736330303634002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303033632f636861723030363100000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303033632f63686172303036312f6465736330303633002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000030303030323930322d303030302d313030302d383030302d303038303566396233346662000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303033632f636861723030363100000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303033632f636861723030356400008801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000010100000400000055554944000173002400000030303030303134332d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303033630000000500000056616c75650002617900000017000000f877f6e2d3f1253e82d145058a26f97683e8c598bef3200000000000090000004e6f74696679696e67000162000000000000000005000000466c616773000261730000002500000004000000726561640000000005000000777269746500000008000000696e64696361746500000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303033632f63686172303035642f6465736330303630002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303033632f636861723030356400000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303033632f63686172303035642f6465736330303566002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000030303030323930322d303030302d313030302d383030302d303038303566396233346662000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303033632f636861723030356400000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303033632f636861723030353900008801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000010100000400000055554944000173002400000061323865313930322d636661312d346433372d613130662d30303731636565656565626400000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303033630000000500000056616c75650002617900000017000000a8dec0db0cbafe9640bb2ed847eab37f535038c39a79800000000000090000004e6f74696679696e67000162000000000000000005000000466c616773000261730000002500000004000000726561640000000005000000777269746500000008000000696e64696361746500000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303033632f63686172303035392f6465736330303563002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303033632f636861723030353900000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303033632f63686172303035392f6465736330303562002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000030303030323930322d303030302d313030302d383030302d303038303566396233346662000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303033632f636861723030353900000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303033632f636861723030353500008801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000010100000400000055554944000173002400000030303030303032662d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303033630000000500000056616c7565000261790000001b00000093b47702465a8d4b59c0e7454e7e5a24a132c6f21b7395c2486f8a00090000004e6f74696679696e67000162000000000000000005000000466c616773000261730000002500000004000000726561640000000005000000777269746500000008000000696e64696361746500000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303033632f63686172303035352f6465736330303538002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303033632f636861723030353500000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303033632f63686172303035352f6465736330303537002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000030303030323930322d303030302d313030302d383030302d303038303566396233346662000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303033632f636861723030353500000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303033632f636861723030353100008801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000010100000400000055554944000173002400000030303030303031332d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303033630000000500000056616c7565000261790000001b00000055883ec1c266bf491feef70d66085b4d2bedcaa82de0c18b19920f00090000004e6f74696679696e67000162000000000000000005000000466c616773000261730000002500000004000000726561640000000005000000777269746500000008000000696e64696361746500000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303033632f63686172303035312f6465736330303534002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303033632f636861723030353100000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303033632f63686172303035312f6465736330303533002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000030303030323930322d303030302d313030302d383030302d303038303566396233346662000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303033632f636861723030353100000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303033632f636861723030346400008801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000010100000400000055554944000173002400000030303030303063652d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303033630000000500000056616c7565000261790000001b000000e5c8a04859451dd18a277908d63d85f762e3592889721e564d8d2800090000004e6f74696679696e67000162000000000000000005000000466c616773000261730000002500000004000000726561640000000005000000777269746500000008000000696e64696361746500000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303033632f63686172303034642f6465736330303530002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303033632f636861723030346400000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303033632f63686172303034642f6465736330303466002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000030303030323930322d303030302d313030302d383030302d303038303566396233346662000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303033632f636861723030346400000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303033632f636861723030343900008801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000010100000400000055554944000173002400000030303030303030382d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303033630000000500000056616c7565000261790000001b000000bea7cb3df9bae95486a0659d83edd4aa224a0116a3e12161a0f3f100090000004e6f74696679696e67000162000000000000000005000000466c616773000261730000002500000004000000726561640000000005000000777269746500000008000000696e64696361746500000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303033632f63686172303034392f6465736330303463002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303033632f636861723030343900000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303033632f63686172303034392f6465736330303462002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000030303030323930322d303030302d313030302d383030302d303038303566396233346662000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303033632f636861723030343900000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303033632f636861723030343600007001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000ea0000000400000055554944000173002400000030303030303032332d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303033630000000500000056616c7565000261790000002b0000009cf36d0b77ef915335391c1e9f3db4bf8b2f3adc329adbecf9b4a7d4a4394e359d7d62cd8559cd397202bf0005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303033632f63686172303034362f6465736330303438002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303033632f636861723030343600000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303033632f636861723030343200008801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000010100000400000055554944000173002400000030303030303032352d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303033630000000500000056616c75650002617900000018000000a18583ad4550c9909bb270a2f72af115b05031c193681e3700000000090000004e6f74696679696e67000162000000000000000005000000466c616773000261730000002500000004000000726561640000000005000000777269746500000008000000696e64696361746500000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303033632f63686172303034322f6465736330303435002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303033632f636861723030343200000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303033632f63686172303034322f6465736330303434002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000030303030323930322d303030302d313030302d383030302d303038303566396233346662000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303033632f636861723030343200000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303033632f636861723030336600004801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000c20000000400000055554944000173002400000030303030303061352d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303033630000000500000056616c756500026179000000000000000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303033632f63686172303033662f6465736330303431002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303033632f636861723030336600000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303033632f636861723030336400003801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000b50000000400000055554944000173002400000065363034653935642d613735392d343831372d383764332d61613030353038336130643100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303033630000000500000056616c756500026179000000000000000000000005000000466c61677300026173000000090000000400000072656164000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000310000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303033330000002001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000160000006f72672e626c75657a2e4761747453657276696365310000a80000000400000055554944000173002400000030303030303061322d303030302d313030302d383030302d303032366262373635323931000000000600000044657669636500016f000000250000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f414300000000000000070000005072696d6172790001620000010000000000000008000000496e636c756465730002616f00000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303033332f636861723030333900006001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000da0000000400000055554944000173002400000030303030303033372d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303033330000000500000056616c7565000261790000001c000000a20c37be2e21ddd9ff4ac736ce277e8e62d65a7f14a1172a4eb8084805000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303033332f63686172303033392f6465736330303362002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303033332f636861723030333900000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303033332f636861723030333600009001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e476174744368617261637465726973746963310000000a0100000400000055554944000173002400000030303030303061352d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303033330000000500000056616c75650002617900000046000000c74543f0f66c46def821a8929b07577f168e831270b53e876ca7c9ff17750470cbfaf3ca75251064ae9bbe58b8df51f927088d688c563df5905461b6c8cf9c633eb5e5990dd100000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303033332f63686172303033362f6465736330303338002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303033332f636861723030333600000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303033332f636861723030333400003801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000b50000000400000055554944000173002400000065363034653935642d613735392d343831372d383764332d61613030353038336130643100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303033330000000500000056616c756500026179000000000000000000000005000000466c61677300026173000000090000000400000072656164000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000310000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303032340000002001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000160000006f72672e626c75657a2e4761747453657276696365310000a80000000400000055554944000173002400000030303030303035352d303030302d313030302d383030302d303032366262373635323931000000000600000044657669636500016f000000250000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f414300000000000000070000005072696d6172790001620000010000000000000008000000496e636c756465730002616f00000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303032342f636861723030333000004801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000c20000000400000055554944000173002400000030303030303035302d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303032340000000500000056616c756500026179000000000000000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303032342f63686172303033302f6465736330303332002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303032342f636861723030333000000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303032342f636861723030326400004801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000c20000000400000055554944000173002400000030303030303034662d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303032340000000500000056616c756500026179000000000000000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303032342f63686172303032642f6465736330303266002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303032342f636861723030326400000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303032342f636861723030326100007001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000ea0000000400000055554944000173002400000030303030303034652d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303032340000000500000056616c75650002617900000029000000023b00240001220601020001060e08043b253a0ba2f9c105106f6214a6270b6a78349b3f6626b9a97a00000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303032342f63686172303032612f6465736330303263002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a6000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303032342f636861723030326100000500000056616c75650002617900000002000000230000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303032342f636861723030323700004801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000c20000000400000055554944000173002400000030303030303034632d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303032340000000500000056616c756500026179000000000000000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303032342f63686172303032372f6465736330303239002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303032342f636861723030323700000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303032342f636861723030323500003801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000b50000000400000055554944000173002400000065363034653935642d613735392d343831372d383764332d61613030353038336130643100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303032340000000500000056616c756500026179000000000000000000000005000000466c61677300026173000000090000000400000072656164000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000310000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303030360000002001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000160000006f72672e626c75657a2e4761747453657276696365310000a80000000400000055554944000173002400000030303030303033652d303030302d313030302d383030302d303032366262373635323931000000000600000044657669636500016f000000250000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f414300000000000000070000005072696d6172790001620000010000000000000008000000496e636c756465730002616f00000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303030362f636861723030323100004801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000c20000000400000055554944000173002400000030303030303232302d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303030360000000500000056616c756500026179000000000000000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303030362f63686172303032312f6465736330303233002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303030362f636861723030323100000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303030362f636861723030316500004801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000c20000000400000055554944000173002400000033346162383831312d616337662d343334302d626163332d66643661383566393934336200000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303030360000000500000056616c756500026179000000000000000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303030362f63686172303031652f6465736330303230002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303030362f636861723030316500000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303030362f636861723030316200004801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000c20000000400000055554944000173002400000030303030303035332d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303030360000000500000056616c756500026179000000000000000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303030362f63686172303031622f6465736330303164002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303030362f636861723030316200000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303030362f636861723030313800004801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000c20000000400000055554944000173002400000030303030303035322d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303030360000000500000056616c756500026179000000000000000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303030362f63686172303031382f6465736330303161002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303030362f636861723030313800000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303030362f636861723030313500004801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000c20000000400000055554944000173002400000030303030303033302d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303030360000000500000056616c756500026179000000000000000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303030362f63686172303031352f6465736330303137002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303030362f636861723030313500000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303030362f636861723030313200004801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000c20000000400000055554944000173002400000030303030303032332d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303030360000000500000056616c756500026179000000000000000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303030362f63686172303031322f6465736330303134002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303030362f636861723030313200000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303030362f636861723030306600004801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000c20000000400000055554944000173002400000030303030303032312d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303030360000000500000056616c756500026179000000000000000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303030362f63686172303030662f6465736330303131002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303030362f636861723030306600000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303030362f636861723030306300004801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000c20000000400000055554944000173002400000030303030303032302d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303030360000000500000056616c756500026179000000000000000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303030362f63686172303030632f6465736330303065002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303030362f636861723030306300000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303030362f636861723030303900004801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000c20000000400000055554944000173002400000030303030303031342d303030302d313030302d383030302d30303236626237363532393100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303030360000000500000056616c756500026179000000000000000000000005000000466c6167730002617300000016000000040000007265616400000000050000007772697465000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303030362f63686172303030392f6465736330303062002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000064633436663066652d383164322d343631362d623564392d366162646437393639333961000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303030362f636861723030303900000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303030362f636861723030303700003801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000b50000000400000055554944000173002400000065363034653935642d613735392d343831372d383764332d61613030353038336130643100000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f43465f44465f41355f43345f46345f41432f73657276696365303030360000000500000056616c756500026179000000000000000000000005000000466c61677300026173000000090000000400000072656164000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000250000002f6f72672f626c75657a2f686369302f6465765f36305f35355f46395f32425f33365f433200000000030000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000110000006f72672e626c75657a2e446576696365310000008402000000000000070000004164647265737300017300001100000036303a35353a46393a32423a33363a43320000000b00000041646472657373547970650001730000060000007075626c69630000040000004e616d650001730007000000576f53747269700005000000416c6961730001730000000007000000576f5374726970000000000006000000506169726564000162000000000000000000000007000000547275737465640001620000000000000000000007000000426c6f636b6564000162000000000000000000000d0000004c656761637950616972696e67000162000000000000000000000000040000005253534900016e00d6ff000009000000436f6e6e6563746564000162000000000000000005000000555549447300026173000000810000002400000030303030313830302d303030302d313030302d383030302d303038303566396233346662000000002400000030303030313830312d303030302d313030302d383030302d303038303566396233346662000000002400000063626132306430302d323234642d313165362d396662382d30303032613564356335316200000000070000004164617074657200016f00000f0000002f6f72672f626c75657a2f686369300000000000100000004d616e756661637475726572446174610005617b71767d001c0000006909026179000000100000006055f92b36c24d6422dc000000000000000000000b00000053657276696365446174610005617b73767d000037000000000000002400000030303030666433642d303030302d313030302d383030302d303038303566396233346662000261790000000003000000720064001000000053657276696365735265736f6c7665640001620000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000310000002f6f72672f626c75657a2f686369302f6465765f36305f35355f46395f32425f33365f43322f73657276696365303032380000002001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000160000006f72672e626c75657a2e4761747453657276696365310000a80000000400000055554944000173002400000063626132306430302d323234642d313165362d396662382d303030326135643563353162000000000600000044657669636500016f000000250000002f6f72672f626c75657a2f686369302f6465765f36305f35355f46395f32425f33365f433200000000000000070000005072696d6172790001620000010000000000000008000000496e636c756465730002616f00000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f36305f35355f46395f32425f33365f43322f73657276696365303032382f636861723030326300007801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000f40000000400000055554944000173002400000063626132303030322d323234642d313165362d396662382d30303032613564356335316200000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f36305f35355f46395f32425f33365f43322f73657276696365303032380000000500000056616c756500026179000000000000000000000005000000466c61677300026173000000260000001600000077726974652d776974686f75742d726573706f6e73650000050000007772697465000000000000000d000000577269746541637175697265640001620000000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f36305f35355f46395f32425f33365f43322f73657276696365303032382f636861723030323900007801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000f40000000400000055554944000173002400000063626132303030332d323234642d313165362d396662382d30303032613564356335316200000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f36305f35355f46395f32425f33365f43322f73657276696365303032380000000500000056616c7565000261790000000b000000010064ff60d7000000ff0200090000004e6f74696679696e67000162000000000000000005000000466c616773000261730000000b000000060000006e6f7469667900000e0000004e6f74696679416371756972656400016200000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f36305f35355f46395f32425f33365f43322f73657276696365303032382f63686172303032392f6465736330303262002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000030303030323930322d303030302d313030302d383030302d303038303566396233346662000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f36305f35355f46395f32425f33365f43322f73657276696365303032382f636861723030323900000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000310000002f6f72672f626c75657a2f686369302f6465765f36305f35355f46395f32425f33365f43322f73657276696365303030310000002001000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000160000006f72672e626c75657a2e4761747453657276696365310000a80000000400000055554944000173002400000030303030313830312d303030302d313030302d383030302d303038303566396233346662000000000600000044657669636500016f000000250000002f6f72672f626c75657a2f686369302f6465765f36305f35355f46395f32425f33365f433200000000000000070000005072696d6172790001620000010000000000000008000000496e636c756465730002616f00000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f7065727469657300000000003a0000002f6f72672f626c75657a2f686369302f6465765f36305f35355f46395f32425f33365f43322f73657276696365303030312f636861723030303200005801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c650000000000000000001d0000006f72672e626c75657a2e47617474436861726163746572697374696331000000d10000000400000055554944000173002400000030303030326130352d303030302d313030302d383030302d30303830356639623334666200000000070000005365727669636500016f0000310000002f6f72672f626c75657a2f686369302f6465765f36305f35355f46395f32425f33365f43322f73657276696365303030310000000500000056616c7565000261790000000000000000000000090000004e6f74696679696e67000162000000000000000005000000466c616773000261730000000d00000008000000696e64696361746500000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000430000002f6f72672f626c75657a2f686369302f6465765f36305f35355f46395f32425f33365f43322f73657276696365303030312f63686172303030322f6465736330303034002801000000000000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000190000006f72672e626c75657a2e4761747444657363726970746f7231000000a4000000000000000400000055554944000173002400000030303030323930322d303030302d313030302d383030302d303038303566396233346662000000000e000000436861726163746572697374696300016f0000003a0000002f6f72672f626c75657a2f686369302f6465765f36305f35355f46395f32425f33365f43322f73657276696365303030312f636861723030303200000500000056616c75650002617900000000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000250000002f6f72672f626c75657a2f686369302f6465765f36305f35355f46395f33435f33345f4441000000f8020000230000006f72672e667265656465736b746f702e444275732e496e74726f737065637461626c65000000000000000000110000006f72672e626c75657a2e446576696365310000007c02000000000000070000004164647265737300017300001100000036303a35353a46393a33433a33343a44410000000b00000041646472657373547970650001730000060000007075626c69630000040000004e616d650001730006000000576f506c7567000005000000416c6961730001730000000006000000576f506c756700000000000006000000506169726564000162000000000000000000000007000000547275737465640001620000000000000000000007000000426c6f636b6564000162000000000000000000000d0000004c656761637950616972696e67000162000000000000000000000000040000005253534900016e00dcff000009000000436f6e6e6563746564000162000000000000000005000000555549447300026173000000810000002400000030303030313830302d303030302d313030302d383030302d303038303566396233346662000000002400000030303030313830312d303030302d313030302d383030302d303038303566396233346662000000002400000063626132306430302d323234642d313165362d396662382d30303032613564356335316200000000070000004164617074657200016f00000f0000002f6f72672f626c75657a2f686369300000000000100000004d616e756661637475726572446174610005617b71767d001800000069090261790000000c0000006055f93c34daea00103400000b00000053657276696365446174610005617b73767d000037000000000000002400000030303030666433642d303030302d313030302d383030302d303038303566396233346662000261790000000003000000670064001000000053657276696365735265736f6c7665640001620000000000000000001f0000006f72672e667265656465736b746f702e444275732e50726f706572746965730000000000
dbus-fast-2.44.1/tests/data/messages.json 0000664 0000000 0000000 00000026356 14773556132 0020300 0 ustar 00root root 0000000 0000000 [
{
"message": {
"destination": "org.freedesktop.DBus",
"path": "/org/freedesktop/DBus",
"interface": "org.freedesktop.DBus",
"member": "Hello",
"serial": 1,
"signature": ""
},
"data": "6c01000100000000010000006d00000001016f00150000002f6f72672f667265656465736b746f702f4442757300000002017300140000006f72672e667265656465736b746f702e4442757300000000030173000500000048656c6c6f00000006017300140000006f72672e667265656465736b746f702e4442757300000000"
},
{
"message": {
"destination": "org.freedesktop.DBus",
"path": "/org/freedesktop/DBus",
"interface": "org.freedesktop.DBus",
"member": "Hello",
"serial": 1,
"signature": "as",
"body": [["hello", "world"]]
},
"data": "6c0100011a000000010000007800000001016f00150000002f6f72672f667265656465736b746f702f4442757300000002017300140000006f72672e667265656465736b746f702e4442757300000000030173000500000048656c6c6f00000006017300140000006f72672e667265656465736b746f702e44427573000000000801670002617300160000000500000068656c6c6f00000005000000776f726c6400"
},
{
"message": {
"destination": "org.freedesktop.DBus",
"path": "/org/freedesktop/DBus",
"interface": "org.freedesktop.DBus",
"member": "Hello",
"serial": 1,
"signature": "a(uu)",
"body": [
[
[1, 1],
[2, 2]
]
]
},
"data": "6c01000118000000010000007b00000001016f00150000002f6f72672f667265656465736b746f702f4442757300000002017300140000006f72672e667265656465736b746f702e4442757300000000030173000500000048656c6c6f00000006017300140000006f72672e667265656465736b746f702e444275730000000008016700056128757529000000000000100000000000000001000000010000000200000002000000"
},
{
"message": {
"destination": "org.freedesktop.DBus",
"path": "/org/freedesktop/DBus",
"interface": "org.freedesktop.DBus",
"member": "Hello",
"serial": 1,
"signature": "a{ss}",
"body": [
{
"foo": "bar",
"bat": "baz"
}
]
},
"data": "6c01000128000000010000007b00000001016f00150000002f6f72672f667265656465736b746f702f4442757300000002017300140000006f72672e667265656465736b746f702e4442757300000000030173000500000048656c6c6f00000006017300140000006f72672e667265656465736b746f702e44427573000000000801670005617b73737d000000000000200000000000000003000000666f6f00030000006261720003000000626174000300000062617a00"
},
{
"message": {
"destination": "org.freedesktop.DBus",
"path": "/org/freedesktop/DBus",
"interface": "org.freedesktop.DBus",
"member": "Hello",
"serial": 1,
"signature": "a(as(uu(a{ss})))",
"body": [
[
[
["hello", "there"],
[
5,
6,
[
{
"five": "six",
"seven": "eight"
}
]
]
],
[
["to", "the", "world"],
[
7,
8,
[
{
"seven": "eight",
"nine": "ten"
}
]
]
]
]
]
},
"data": "6c010001c4000000010000008600000001016f00150000002f6f72672f667265656465736b746f702f4442757300000002017300140000006f72672e667265656465736b746f702e4442757300000000030173000500000048656c6c6f00000006017300140000006f72672e667265656465736b746f702e444275730000000008016700106128617328757528617b73737d292929000000bc00000000000000160000000500000068656c6c6f0000000500000074686572650000000000000005000000060000002e0000000000000004000000666976650000000003000000736978000000000005000000736576656e0000000500000065696768740000001a00000002000000746f0000030000007468650005000000776f726c6400000007000000080000002c0000000000000005000000736576656e000000050000006569676874000000040000006e696e65000000000300000074656e00"
},
{
"message": {
"destination": "org.freedesktop.DBus",
"path": "/org/freedesktop/DBus",
"interface": "org.freedesktop.DBus",
"member": "Hello",
"serial": 1,
"signature": "t",
"body": [9007199254740988]
},
"data": "6c01000108000000010000007700000001016f00150000002f6f72672f667265656465736b746f702f4442757300000002017300140000006f72672e667265656465736b746f702e4442757300000000030173000500000048656c6c6f00000006017300140000006f72672e667265656465736b746f702e44427573000000000801670001740000fcffffffffff1f00"
},
{
"message": {
"destination": "org.freedesktop.DBus",
"path": "/org/freedesktop/DBus",
"interface": "org.freedesktop.DBus",
"member": "Hello",
"serial": 1,
"signature": "x",
"body": [-9007199254740988]
},
"data": "6c01000108000000010000007700000001016f00150000002f6f72672f667265656465736b746f702f4442757300000002017300140000006f72672e667265656465736b746f702e4442757300000000030173000500000048656c6c6f00000006017300140000006f72672e667265656465736b746f702e44427573000000000801670001780000040000000000e0ff"
},
{
"message": {
"destination": "org.freedesktop.DBus",
"path": "/org/freedesktop/DBus",
"interface": "org.freedesktop.DBus",
"member": "Hello",
"serial": 1,
"signature": "bnqiud",
"body": [true, -200, 150, -20000, 20000, 9083492084.4444]
},
"data": "6c01000118000000010000007c00000001016f00150000002f6f72672f667265656465736b746f702f4442757300000002017300140000006f72672e667265656465736b746f702e4442757300000000030173000500000048656c6c6f00000006017300140000006f72672e667265656465736b746f702e44427573000000000801670006626e7169756400000000000100000038ff9600e0b1ffff204e0000228ea3b758eb0042"
},
{
"message": {
"destination": "org.freedesktop.DBus",
"path": "/org/freedesktop/DBus",
"interface": "org.freedesktop.DBus",
"member": "Hello",
"serial": 1,
"signature": "v",
"body": [
{
"signature": "s",
"value": "hello world"
}
]
},
"data": "6c01000114000000010000007700000001016f00150000002f6f72672f667265656465736b746f702f4442757300000002017300140000006f72672e667265656465736b746f702e4442757300000000030173000500000048656c6c6f00000006017300140000006f72672e667265656465736b746f702e44427573000000000801670001760000017300000b00000068656c6c6f20776f726c6400"
},
{
"message": {
"destination": "org.freedesktop.DBus",
"path": "/org/freedesktop/DBus",
"interface": "org.freedesktop.DBus",
"member": "Hello",
"serial": 1,
"signature": "v",
"body": [
{
"signature": "v",
"value": {
"signature": "s",
"value": "hello"
}
}
]
},
"data": "6c01000112000000010000007700000001016f00150000002f6f72672f667265656465736b746f702f4442757300000002017300140000006f72672e667265656465736b746f702e4442757300000000030173000500000048656c6c6f00000006017300140000006f72672e667265656465736b746f702e4442757300000000080167000176000001760001730000000500000068656c6c6f00"
},
{
"message": {
"destination": "org.freedesktop.DBus",
"path": "/org/freedesktop/DBus",
"interface": "org.freedesktop.DBus",
"member": "Hello",
"serial": 1,
"signature": "a{sv}",
"body": [
{
"variant_key_1": {
"signature": "s",
"value": "variant_val_1"
},
"variant_key_2": {
"signature": "s",
"value": "variant_val_2"
}
}
]
},
"data": "6c01000162000000010000007b00000001016f00150000002f6f72672f667265656465736b746f702f4442757300000002017300140000006f72672e667265656465736b746f702e4442757300000000030173000500000048656c6c6f00000006017300140000006f72672e667265656465736b746f702e44427573000000000801670005617b73767d0000000000005a000000000000000d00000076617269616e745f6b65795f31000173000000000d00000076617269616e745f76616c5f31000000000000000d00000076617269616e745f6b65795f32000173000000000d00000076617269616e745f76616c5f3200"
},
{
"message": {
"destination": "org.freedesktop.DBus",
"path": "/org/freedesktop/DBus",
"interface": "org.freedesktop.DBus",
"member": "Hello",
"serial": 1,
"signature": "v",
"body": [
{
"signature": "as",
"value": ["foo", "bar"]
}
]
},
"data": "6c01000118000000010000007700000001016f00150000002f6f72672f667265656465736b746f702f4442757300000002017300140000006f72672e667265656465736b746f702e4442757300000000030173000500000048656c6c6f00000006017300140000006f72672e667265656465736b746f702e44427573000000000801670001760000026173001000000003000000666f6f000300000062617200"
},
{
"message": {
"destination": "org.freedesktop.DBus",
"path": "/org/freedesktop/DBus",
"interface": "org.freedesktop.DBus",
"member": "Hello",
"serial": 1,
"signature": "vas",
"body": [
{
"signature": "v",
"value": {
"signature": "s",
"value": "world"
}
},
["bar"]
]
},
"data": "6c01000120000000010000007900000001016f00150000002f6f72672f667265656465736b746f702f4442757300000002017300140000006f72672e667265656465736b746f702e4442757300000000030173000500000048656c6c6f00000006017300140000006f72672e667265656465736b746f702e444275730000000008016700037661730000000000000000017600017300000005000000776f726c64000000080000000300000062617200"
},
{
"message": {
"destination": "org.freedesktop.DBus",
"path": "/org/freedesktop/DBus",
"interface": "org.freedesktop.DBus",
"member": "Hello",
"serial": 1,
"signature": "asbbasbb",
"body": [["hello", "worl"], true, false, ["hello", "worl"], true, false]
},
"data": "6c01000148000000010000007e00000001016f00150000002f6f72672f667265656465736b746f702f4442757300000002017300140000006f72672e667265656465736b746f702e4442757300000000030173000500000048656c6c6f00000006017300140000006f72672e667265656465736b746f702e444275730000000008016700086173626261736262000000150000000500000068656c6c6f00000004000000776f726c000000000100000000000000150000000500000068656c6c6f00000004000000776f726c000000000100000000000000"
},
{
"message": {
"destination": "org.freedesktop.DBus",
"path": "/org/freedesktop/DBus",
"interface": "org.freedesktop.DBus",
"member": "Hello",
"serial": 1,
"signature": "as",
"body": [["//doesntmatter/über"]]
},
"data": "6c0100011d000000010000007800000001016f00150000002f6f72672f667265656465736b746f702f4442757300000002017300140000006f72672e667265656465736b746f702e4442757300000000030173000500000048656c6c6f00000006017300140000006f72672e667265656465736b746f702e4442757300000000080167000261730019000000140000002f2f646f65736e746d61747465722fc3bc62657200"
},
{
"message": {
"destination": "org.freedesktop.DBus",
"path": "/org/freedesktop/DBus",
"interface": "org.freedesktop.DBus",
"member": "Hello",
"serial": 1,
"signature": "an",
"body": [[-1024]]
},
"data": "6c01000106000000010000007800000001016f00150000002f6f72672f667265656465736b746f702f4442757300000002017300140000006f72672e667265656465736b746f702e4442757300000000030173000500000048656c6c6f00000006017300140000006f72672e667265656465736b746f702e44427573000000000801670002616e000200000000fc"
}
]
dbus-fast-2.44.1/tests/data/sloppy-introspection.xml 0000664 0000000 0000000 00000000665 14773556132 0022537 0 ustar 00root root 0000000 0000000
dbus-fast-2.44.1/tests/data/strict-introspection.xml 0000664 0000000 0000000 00000002314 14773556132 0022512 0 ustar 00root root 0000000 0000000
dbus-fast-2.44.1/tests/service/ 0000775 0000000 0000000 00000000000 14773556132 0016311 5 ustar 00root root 0000000 0000000 dbus-fast-2.44.1/tests/service/__init__.py 0000664 0000000 0000000 00000000000 14773556132 0020410 0 ustar 00root root 0000000 0000000 dbus-fast-2.44.1/tests/service/test_decorators.py 0000664 0000000 0000000 00000011150 14773556132 0022065 0 ustar 00root root 0000000 0000000 from dbus_fast import PropertyAccess
from dbus_fast import introspection as intr
from dbus_fast.service import ServiceInterface, dbus_property, method, signal
class ExampleInterface(ServiceInterface):
def __init__(self):
super().__init__("test.interface")
self._some_prop = 55
self._another_prop = 101
self._weird_prop = 500
@method()
def some_method(self, one: "s", two: "s") -> "s":
return "hello"
@method(name="renamed_method", disabled=True)
def another_method(self, eight: "o", six: "t"):
pass
@signal()
def some_signal(self) -> "as": # noqa: F722
return ["result"]
@signal(name="renamed_signal", disabled=True)
def another_signal(self) -> "(dodo)":
return [1, "/", 1, "/"]
@dbus_property(
name="renamed_readonly_property", access=PropertyAccess.READ, disabled=True
)
def another_prop(self) -> "t":
return self._another_prop
@dbus_property()
def some_prop(self) -> "u":
return self._some_prop
@some_prop.setter
def some_prop(self, val: "u"):
self._some_prop = val + 1
# for this one, the setter has a different name than the getter which is a
# special case in the code
@dbus_property()
def weird_prop(self) -> "t":
return self._weird_prop
@weird_prop.setter
def setter_for_weird_prop(self, val: "t"):
self._weird_prop = val
def test_method_decorator():
interface = ExampleInterface()
assert interface.name == "test.interface"
properties = ServiceInterface._get_properties(interface)
methods = ServiceInterface._get_methods(interface)
signals = ServiceInterface._get_signals(interface)
assert len(methods) == 2
method = methods[0]
assert method.name == "renamed_method"
assert method.in_signature == "ot"
assert method.out_signature == ""
assert method.disabled
assert type(method.introspection) is intr.Method
method = methods[1]
assert method.name == "some_method"
assert method.in_signature == "ss"
assert method.out_signature == "s"
assert not method.disabled
assert type(method.introspection) is intr.Method
assert len(signals) == 2
signal = signals[0]
assert signal.name == "renamed_signal"
assert signal.signature == "(dodo)"
assert signal.disabled
assert type(signal.introspection) is intr.Signal
signal = signals[1]
assert signal.name == "some_signal"
assert signal.signature == "as"
assert not signal.disabled
assert type(signal.introspection) is intr.Signal
assert len(properties) == 3
renamed_readonly_prop = properties[0]
assert renamed_readonly_prop.name == "renamed_readonly_property"
assert renamed_readonly_prop.signature == "t"
assert renamed_readonly_prop.access == PropertyAccess.READ
assert renamed_readonly_prop.disabled
assert type(renamed_readonly_prop.introspection) is intr.Property
weird_prop = properties[1]
assert weird_prop.name == "weird_prop"
assert weird_prop.access == PropertyAccess.READWRITE
assert weird_prop.signature == "t"
assert not weird_prop.disabled
assert weird_prop.prop_getter is not None
assert weird_prop.prop_getter.__name__ == "weird_prop"
assert weird_prop.prop_setter is not None
assert weird_prop.prop_setter.__name__ == "setter_for_weird_prop"
assert type(weird_prop.introspection) is intr.Property
prop = properties[2]
assert prop.name == "some_prop"
assert prop.access == PropertyAccess.READWRITE
assert prop.signature == "u"
assert not prop.disabled
assert prop.prop_getter is not None
assert prop.prop_setter is not None
assert type(prop.introspection) is intr.Property
# make sure the getter and setter actually work
assert interface._some_prop == 55
interface._some_prop = 555
assert interface.some_prop == 555
assert interface._weird_prop == 500
assert weird_prop.prop_getter(interface) == 500
interface._weird_prop = 1001
assert interface._weird_prop == 1001
weird_prop.prop_setter(interface, 600)
assert interface._weird_prop == 600
def test_interface_introspection():
interface = ExampleInterface()
intr_interface = interface.introspect()
assert type(intr_interface) is intr.Interface
xml = intr_interface.to_xml()
assert xml.tag == "interface"
assert xml.attrib.get("name", None) == "test.interface"
methods = xml.findall("method")
signals = xml.findall("signal")
properties = xml.findall("property")
assert len(xml) == 4
assert len(methods) == 1
assert len(signals) == 1
assert len(properties) == 2
dbus-fast-2.44.1/tests/service/test_export.py 0000664 0000000 0000000 00000007674 14773556132 0021261 0 ustar 00root root 0000000 0000000 import pytest
from dbus_fast import Message, MessageType
from dbus_fast import introspection as intr
from dbus_fast.aio import MessageBus
from dbus_fast.service import ServiceInterface, method
standard_interfaces_count = len(intr.Node.default().interfaces)
class ExampleInterface(ServiceInterface):
def __init__(self, name):
self._method_called = False
super().__init__(name)
@method()
def some_method(self):
self._method_called = True
@pytest.mark.asyncio
async def test_export_unexport():
interface = ExampleInterface("test.interface")
interface2 = ExampleInterface("test.interface2")
export_path = "/test/path"
export_path2 = "/test/path/child"
bus = await MessageBus().connect()
bus.export(export_path, interface)
with pytest.raises(ValueError):
# Already exported
bus.export(export_path, interface)
assert export_path in bus._path_exports
assert len(bus._path_exports[export_path]) == 1
assert bus._path_exports[export_path][interface.name] is interface
assert len(ServiceInterface._get_buses(interface)) == 1
bus.export(export_path2, interface2)
node = bus._introspect_export_path(export_path)
assert len(node.interfaces) == standard_interfaces_count + 1
assert len(node.nodes) == 1
# relative path
assert node.nodes[0].name == "child"
bus.unexport(export_path, interface)
assert export_path not in bus._path_exports
assert len(ServiceInterface._get_buses(interface)) == 0
bus.export(export_path2, interface)
assert len(bus._path_exports[export_path2]) == 2
# test unexporting the whole path
bus.unexport(export_path2)
assert not bus._path_exports
assert not ServiceInterface._get_buses(interface)
assert not ServiceInterface._get_buses(interface2)
# test unexporting by name
bus.export(export_path, interface)
bus.unexport(export_path, interface.name)
assert not bus._path_exports
assert not ServiceInterface._get_buses(interface)
# test unexporting by ServiceInterface
bus.export(export_path, interface)
bus.unexport(export_path, interface)
assert not bus._path_exports
assert not ServiceInterface._get_buses(interface)
with pytest.raises(TypeError):
bus.unexport(export_path, object())
node = bus._introspect_export_path("/path/doesnt/exist")
assert type(node) is intr.Node
assert not node.interfaces
assert not node.nodes
# Should to nothing
bus.unexport("/path/doesnt/exist", interface)
bus.disconnect()
@pytest.mark.asyncio
async def test_export_alias():
bus = await MessageBus().connect()
interface = ExampleInterface("test.interface")
export_path = "/test/path"
export_path2 = "/test/path/child"
bus.export(export_path, interface)
bus.export(export_path2, interface)
result = await bus.call(
Message(
destination=bus.unique_name,
path=export_path,
interface="test.interface",
member="some_method",
)
)
assert result.message_type is MessageType.METHOD_RETURN, result.body[0]
assert interface._method_called
interface._method_called = False
result = await bus.call(
Message(
destination=bus.unique_name,
path=export_path2,
interface="test.interface",
member="some_method",
)
)
assert result.message_type is MessageType.METHOD_RETURN, result.body[0]
assert interface._method_called
bus.disconnect()
@pytest.mark.asyncio
async def test_export_introspection():
interface = ExampleInterface("test.interface")
interface2 = ExampleInterface("test.interface2")
export_path = "/test/path"
export_path2 = "/test/path/child"
bus = await MessageBus().connect()
bus.export(export_path, interface)
bus.export(export_path2, interface2)
root = bus._introspect_export_path("/")
assert len(root.nodes) == 1
bus.disconnect()
dbus-fast-2.44.1/tests/service/test_methods.py 0000664 0000000 0000000 00000015602 14773556132 0021371 0 ustar 00root root 0000000 0000000 import pytest
from dbus_fast import (
DBusError,
ErrorType,
Message,
MessageFlag,
MessageType,
SignatureTree,
Variant,
)
from dbus_fast.aio import MessageBus
from dbus_fast.service import ServiceInterface, method
class ExampleInterface(ServiceInterface):
def __init__(self, name):
super().__init__(name)
@method()
def echo(self, what: "s") -> "s":
assert type(self) is ExampleInterface
return what
@method()
def echo_multiple(self, what1: "s", what2: "s") -> "ss":
assert type(self) is ExampleInterface
return [what1, what2]
@method()
def echo_containers(
self,
array: "as", # noqa: F722
variant: "v",
dict_entries: "a{sv}", # noqa: F722
struct: "(s(s(v)))",
) -> "asva{sv}(s(s(v)))": # noqa: F722
assert type(self) is ExampleInterface
return [array, variant, dict_entries, struct]
@method()
def ping(self):
assert type(self) is ExampleInterface
@method(name="renamed")
def original_name(self):
assert type(self) is ExampleInterface
@method(disabled=True)
def not_here(self):
assert type(self) is ExampleInterface
@method()
def throws_unexpected_error(self):
assert type(self) is ExampleInterface
raise Exception("oops")
@method()
def throws_dbus_error(self):
assert type(self) is ExampleInterface
raise DBusError("test.error", "an error occurred")
class AsyncInterface(ServiceInterface):
def __init__(self, name):
super().__init__(name)
@method()
async def echo(self, what: "s") -> "s":
assert type(self) is AsyncInterface
return what
@method()
async def echo_multiple(self, what1: "s", what2: "s") -> "ss":
assert type(self) is AsyncInterface
return [what1, what2]
@method()
async def echo_containers(
self,
array: "as", # noqa: F722
variant: "v",
dict_entries: "a{sv}", # noqa: F722
struct: "(s(s(v)))",
) -> "asva{sv}(s(s(v)))": # noqa: F722
assert type(self) is AsyncInterface
return [array, variant, dict_entries, struct]
@method()
async def ping(self):
assert type(self) is AsyncInterface
@method(name="renamed")
async def original_name(self):
assert type(self) is AsyncInterface
@method(disabled=True)
async def not_here(self):
assert type(self) is AsyncInterface
@method()
async def throws_unexpected_error(self):
assert type(self) is AsyncInterface
raise Exception("oops")
@method()
def throws_dbus_error(self):
assert type(self) is AsyncInterface
raise DBusError("test.error", "an error occurred")
@pytest.mark.parametrize("interface_class", [ExampleInterface, AsyncInterface])
@pytest.mark.asyncio
async def test_methods(interface_class):
bus1 = await MessageBus().connect()
bus2 = await MessageBus().connect()
interface = interface_class("test.interface")
export_path = "/test/path"
async def call(
member, signature="", body=[], flags=MessageFlag.NONE, interface=interface.name
):
return await bus2.call(
Message(
destination=bus1.unique_name,
path=export_path,
interface=interface,
member=member,
signature=signature,
body=body,
flags=flags,
)
)
bus1.export(export_path, interface)
body = ["hello world"]
reply = await call("echo", "s", body)
assert reply.message_type == MessageType.METHOD_RETURN, reply.body[0]
assert reply.signature == "s"
assert reply.body == body
body = ["hello", "world"]
reply = await call("echo_multiple", "ss", body)
assert reply.message_type == MessageType.METHOD_RETURN, reply.body[0]
assert reply.signature == "ss"
assert reply.body == body
body = [
["hello", "world"],
Variant("v", Variant("(ss)", ["hello", "world"])),
{"foo": Variant("t", 100)},
["one", ["two", [Variant("s", "three")]]],
]
signature = "asva{sv}(s(s(v)))"
SignatureTree(signature).verify(body)
reply = await call("echo_containers", signature, body)
assert reply.message_type == MessageType.METHOD_RETURN, reply.body[0]
assert reply.signature == signature
assert reply.body == body
# Wrong interface should be a failure
reply = await call(
"echo_containers", signature, body, interface="org.abc.xyz.Props"
)
assert reply.message_type == MessageType.ERROR, reply.body[0]
assert reply.error_name == "org.freedesktop.DBus.Error.UnknownMethod", reply.body[0]
assert reply.body == [
'org.abc.xyz.Props.echo_containers with signature "asva{sv}(s(s(v)))" could not be found'
]
# No interface should result in finding anything that matches the member name
# and the signature
reply = await call("echo_containers", signature, body, interface=None)
assert reply.message_type == MessageType.METHOD_RETURN, reply.body[0]
assert reply.signature == signature
assert reply.body == body
# No interface should result in finding anything that matches the member name
# and the signature, but in this case it will be nothing because
# the signature is wrong
reply = await call("echo_containers", "as", body, interface=None)
assert reply.message_type == MessageType.ERROR, reply.body[0]
assert reply.error_name == "org.freedesktop.DBus.Error.UnknownMethod", reply.body[0]
assert reply.body == ['None.echo_containers with signature "as" could not be found']
reply = await call("ping")
assert reply.message_type == MessageType.METHOD_RETURN, reply.body[0]
assert reply.signature == ""
assert reply.body == []
reply = await call("throws_unexpected_error")
assert reply.message_type == MessageType.ERROR, reply.body[0]
assert reply.error_name == ErrorType.SERVICE_ERROR.value, reply.body[0]
reply = await call("throws_dbus_error")
assert reply.message_type == MessageType.ERROR, reply.body[0]
assert reply.error_name == "test.error", reply.body[0]
assert reply.body == ["an error occurred"]
reply = await call("ping", flags=MessageFlag.NO_REPLY_EXPECTED)
assert reply is None
reply = await call("throws_unexpected_error", flags=MessageFlag.NO_REPLY_EXPECTED)
assert reply is None
reply = await call("throws_dbus_error", flags=MessageFlag.NO_REPLY_EXPECTED)
assert reply is None
reply = await call("does_not_exist")
assert reply.message_type == MessageType.ERROR, reply.body[0]
assert reply.error_name == "org.freedesktop.DBus.Error.UnknownMethod", reply.body[0]
assert reply.body == [
'test.interface.does_not_exist with signature "" could not be found'
]
bus1.disconnect()
bus2.disconnect()
bus1._sock.close()
bus2._sock.close()
dbus-fast-2.44.1/tests/service/test_properties.py 0000664 0000000 0000000 00000022777 14773556132 0022135 0 ustar 00root root 0000000 0000000 import asyncio
import pytest
from dbus_fast import (
DBusError,
ErrorType,
Message,
MessageType,
PropertyAccess,
Variant,
)
from dbus_fast.aio import MessageBus
from dbus_fast.service import ServiceInterface, dbus_property, method
class ExampleInterface(ServiceInterface):
def __init__(self, name):
super().__init__(name)
self._string_prop = "hi"
self._readonly_prop = 100
self._disabled_prop = "1234"
self._container_prop = [["hello", "world"]]
self._renamed_prop = "65"
@dbus_property()
def string_prop(self) -> "s":
return self._string_prop
@string_prop.setter
def string_prop_setter(self, val: "s"):
self._string_prop = val
@dbus_property(PropertyAccess.READ)
def readonly_prop(self) -> "t":
return self._readonly_prop
@dbus_property()
def container_prop(self) -> "a(ss)":
return self._container_prop
@container_prop.setter
def container_prop(self, val: "a(ss)"):
self._container_prop = val
@dbus_property(name="renamed_prop")
def original_name(self) -> "s":
return self._renamed_prop
@original_name.setter
def original_name_setter(self, val: "s"):
self._renamed_prop = val
@dbus_property(disabled=True)
def disabled_prop(self) -> "s":
return self._disabled_prop
@disabled_prop.setter
def disabled_prop(self, val: "s"):
self._disabled_prop = val
@dbus_property(disabled=True)
def throws_error(self) -> "s":
raise DBusError("test.error", "told you so")
@throws_error.setter
def throws_error(self, val: "s"):
raise DBusError("test.error", "told you so")
@dbus_property(PropertyAccess.READ, disabled=True)
def returns_wrong_type(self) -> "s":
return 5
@method()
def do_emit_properties_changed(self):
changed = {"string_prop": "asdf"}
invalidated = ["container_prop"]
self.emit_properties_changed(changed, invalidated)
class AsyncInterface(ServiceInterface):
def __init__(self, name):
super().__init__(name)
self._string_prop = "hi"
self._readonly_prop = 100
self._disabled_prop = "1234"
self._container_prop = [["hello", "world"]]
self._renamed_prop = "65"
@dbus_property()
async def string_prop(self) -> "s":
return self._string_prop
@string_prop.setter
async def string_prop_setter(self, val: "s"):
self._string_prop = val
@dbus_property(PropertyAccess.READ)
async def readonly_prop(self) -> "t":
return self._readonly_prop
@dbus_property()
async def container_prop(self) -> "a(ss)":
return self._container_prop
@container_prop.setter
async def container_prop(self, val: "a(ss)"):
self._container_prop = val
@dbus_property(name="renamed_prop")
async def original_name(self) -> "s":
return self._renamed_prop
@original_name.setter
async def original_name_setter(self, val: "s"):
self._renamed_prop = val
@dbus_property(disabled=True)
async def disabled_prop(self) -> "s":
return self._disabled_prop
@disabled_prop.setter
async def disabled_prop(self, val: "s"):
self._disabled_prop = val
@dbus_property(disabled=True)
async def throws_error(self) -> "s":
raise DBusError("test.error", "told you so")
@throws_error.setter
async def throws_error(self, val: "s"):
raise DBusError("test.error", "told you so")
@dbus_property(PropertyAccess.READ, disabled=True)
async def returns_wrong_type(self) -> "s":
return 5
@method()
def do_emit_properties_changed(self):
changed = {"string_prop": "asdf"}
invalidated = ["container_prop"]
self.emit_properties_changed(changed, invalidated)
@pytest.mark.parametrize("interface_class", [ExampleInterface, AsyncInterface])
@pytest.mark.asyncio
async def test_property_methods(interface_class):
bus1 = await MessageBus().connect()
bus2 = await MessageBus().connect()
interface = interface_class("test.interface")
export_path = "/test/path"
bus1.export(export_path, interface)
async def call_properties(member, signature, body):
return await bus2.call(
Message(
destination=bus1.unique_name,
path=export_path,
interface="org.freedesktop.DBus.Properties",
member=member,
signature=signature,
body=body,
)
)
result = await call_properties("GetAll", "s", [interface.name])
assert result.message_type == MessageType.METHOD_RETURN, result.body[0]
assert result.signature == "a{sv}"
assert result.body == [
{
"string_prop": Variant("s", interface._string_prop),
"readonly_prop": Variant("t", interface._readonly_prop),
"container_prop": Variant("a(ss)", interface._container_prop),
"renamed_prop": Variant("s", interface._renamed_prop),
}
]
result = await call_properties("Get", "ss", [interface.name, "string_prop"])
assert result.message_type == MessageType.METHOD_RETURN, result.body[0]
assert result.signature == "v"
assert result.body == [Variant("s", "hi")]
result = await call_properties(
"Set", "ssv", [interface.name, "string_prop", Variant("s", "ho")]
)
assert result.message_type == MessageType.METHOD_RETURN, result.body[0]
assert interface._string_prop == "ho"
if interface_class is AsyncInterface:
assert "ho", await interface.string_prop()
else:
assert "ho", interface.string_prop
result = await call_properties(
"Set", "ssv", [interface.name, "readonly_prop", Variant("t", 100)]
)
assert result.message_type == MessageType.ERROR, result.body[0]
assert result.error_name == ErrorType.PROPERTY_READ_ONLY.value, result.body[0]
result = await call_properties(
"Set", "ssv", [interface.name, "disabled_prop", Variant("s", "asdf")]
)
assert result.message_type == MessageType.ERROR, result.body[0]
assert result.error_name == ErrorType.UNKNOWN_PROPERTY.value
result = await call_properties(
"Set", "ssv", [interface.name, "not_a_prop", Variant("s", "asdf")]
)
assert result.message_type == MessageType.ERROR, result.body[0]
assert result.error_name == ErrorType.UNKNOWN_PROPERTY.value
# wrong type
result = await call_properties(
"Set", "ssv", [interface.name, "string_prop", Variant("t", 100)]
)
assert result.message_type == MessageType.ERROR
assert result.error_name == ErrorType.INVALID_SIGNATURE.value
# enable the erroring properties so we can test them
for prop in ServiceInterface._get_properties(interface):
if prop.name in ["throws_error", "returns_wrong_type"]:
prop.disabled = False
result = await call_properties("Get", "ss", [interface.name, "returns_wrong_type"])
assert result.message_type == MessageType.ERROR, result.body[0]
assert result.error_name == ErrorType.SERVICE_ERROR.value
result = await call_properties(
"Set", "ssv", [interface.name, "throws_error", Variant("s", "ho")]
)
assert result.message_type == MessageType.ERROR, result.body[0]
assert result.error_name == "test.error"
assert result.body == ["told you so"]
result = await call_properties("Get", "ss", [interface.name, "throws_error"])
assert result.message_type == MessageType.ERROR, result.body[0]
assert result.error_name == "test.error"
assert result.body == ["told you so"]
result = await call_properties("GetAll", "s", [interface.name])
assert result.message_type == MessageType.ERROR, result.body[0]
assert result.error_name == "test.error"
assert result.body == ["told you so"]
bus1.disconnect()
bus2.disconnect()
bus1._sock.close()
bus2._sock.close()
@pytest.mark.parametrize("interface_class", [ExampleInterface, AsyncInterface])
@pytest.mark.asyncio
async def test_property_changed_signal(interface_class):
bus1 = await MessageBus().connect()
bus2 = await MessageBus().connect()
await bus2.call(
Message(
destination="org.freedesktop.DBus",
path="/org/freedesktop/DBus",
interface="org.freedesktop.DBus",
member="AddMatch",
signature="s",
body=[f"sender={bus1.unique_name}"],
)
)
interface = interface_class("test.interface")
export_path = "/test/path"
bus1.export(export_path, interface)
async def wait_for_message():
# TODO timeout
future = asyncio.get_running_loop().create_future()
def message_handler(signal):
if signal.interface == "org.freedesktop.DBus.Properties":
bus2.remove_message_handler(message_handler)
future.set_result(signal)
bus2.add_message_handler(message_handler)
return await future
bus2.send(
Message(
destination=bus1.unique_name,
interface=interface.name,
path=export_path,
member="do_emit_properties_changed",
)
)
signal = await wait_for_message()
assert signal.interface == "org.freedesktop.DBus.Properties"
assert signal.member == "PropertiesChanged"
assert signal.signature == "sa{sv}as"
assert signal.body == [
interface.name,
{"string_prop": Variant("s", "asdf")},
["container_prop"],
]
bus1.disconnect()
bus2.disconnect()
bus1._sock.close()
bus2._sock.close()
dbus-fast-2.44.1/tests/service/test_signals.py 0000664 0000000 0000000 00000016703 14773556132 0021371 0 ustar 00root root 0000000 0000000 import asyncio
import pytest
from dbus_fast import Message, MessageType
from dbus_fast.aio import MessageBus
from dbus_fast.constants import PropertyAccess
from dbus_fast.service import (
ServiceInterface,
SignalDisabledError,
dbus_property,
signal,
)
from dbus_fast.signature import Variant
class ExampleInterface(ServiceInterface):
def __init__(self, name):
super().__init__(name)
@signal()
def signal_empty(self):
assert type(self) is ExampleInterface
@signal()
def signal_simple(self) -> "s":
assert type(self) is ExampleInterface
return "hello"
@signal()
def signal_multiple(self) -> "ss":
assert type(self) is ExampleInterface
return ["hello", "world"]
@signal(name="renamed")
def original_name(self):
assert type(self) is ExampleInterface
@signal(disabled=True)
def signal_disabled(self):
assert type(self) is ExampleInterface
@dbus_property(access=PropertyAccess.READ)
def test_prop(self) -> "i":
return 42
class SecondExampleInterface(ServiceInterface):
def __init__(self, name):
super().__init__(name)
@dbus_property(access=PropertyAccess.READ)
def str_prop(self) -> "s":
return "abc"
@dbus_property(access=PropertyAccess.READ)
def list_prop(self) -> "ai":
return [1, 2, 3]
class ExpectMessage:
def __init__(self, bus1, bus2, interface_name, timeout=1):
self.future = asyncio.get_running_loop().create_future()
self.bus1 = bus1
self.bus2 = bus2
self.interface_name = interface_name
self.timeout = timeout
self.timeout_task = None
def message_handler(self, msg):
if msg.sender == self.bus1.unique_name and msg.interface == self.interface_name:
self.timeout_task.cancel()
self.future.set_result(msg)
return True
def timeout_cb(self):
self.future.set_exception(TimeoutError)
async def __aenter__(self):
self.bus2.add_message_handler(self.message_handler)
self.timeout_task = asyncio.get_running_loop().call_later(
self.timeout, self.timeout_cb
)
return self.future
async def __aexit__(self, exc_type, exc_val, exc_tb):
self.bus2.remove_message_handler(self.message_handler)
def assert_signal_ok(signal, export_path, member, signature, body):
assert signal.message_type == MessageType.SIGNAL
assert signal.path == export_path
assert signal.member == member
assert signal.signature == signature
assert signal.body == body
@pytest.mark.asyncio
async def test_signals():
bus1 = await MessageBus().connect()
bus2 = await MessageBus().connect()
interface = ExampleInterface("test.interface")
export_path = "/test/path"
bus1.export(export_path, interface)
await bus2.call(
Message(
destination="org.freedesktop.DBus",
path="/org/freedesktop/DBus",
interface="org.freedesktop.DBus",
member="AddMatch",
signature="s",
body=[f"sender={bus1.unique_name}"],
)
)
async with ExpectMessage(bus1, bus2, interface.name) as expected_signal:
interface.signal_empty()
assert_signal_ok(
signal=await expected_signal,
export_path=export_path,
member="signal_empty",
signature="",
body=[],
)
async with ExpectMessage(bus1, bus2, interface.name) as expected_signal:
interface.original_name()
assert_signal_ok(
signal=await expected_signal,
export_path=export_path,
member="renamed",
signature="",
body=[],
)
async with ExpectMessage(bus1, bus2, interface.name) as expected_signal:
interface.signal_simple()
assert_signal_ok(
signal=await expected_signal,
export_path=export_path,
member="signal_simple",
signature="s",
body=["hello"],
)
async with ExpectMessage(bus1, bus2, interface.name) as expected_signal:
interface.signal_multiple()
assert_signal_ok(
signal=await expected_signal,
export_path=export_path,
member="signal_multiple",
signature="ss",
body=["hello", "world"],
)
with pytest.raises(SignalDisabledError):
interface.signal_disabled()
bus1.disconnect()
bus2.disconnect()
bus1._sock.close()
bus2._sock.close()
@pytest.mark.asyncio
async def test_interface_add_remove_signal():
bus1 = await MessageBus().connect()
bus2 = await MessageBus().connect()
await bus2.call(
Message(
destination="org.freedesktop.DBus",
path="/org/freedesktop/DBus",
interface="org.freedesktop.DBus",
member="AddMatch",
signature="s",
body=[f"sender={bus1.unique_name}"],
)
)
first_interface = ExampleInterface("test.interface.first")
second_interface = SecondExampleInterface("test.interface.second")
export_path = "/test/path"
# add first interface
async with ExpectMessage(
bus1, bus2, "org.freedesktop.DBus.ObjectManager"
) as expected_signal:
bus1.export(export_path, first_interface)
assert_signal_ok(
signal=await expected_signal,
export_path=export_path,
member="InterfacesAdded",
signature="oa{sa{sv}}",
body=[
export_path,
{"test.interface.first": {"test_prop": Variant("i", 42)}},
],
)
# add second interface
async with ExpectMessage(
bus1, bus2, "org.freedesktop.DBus.ObjectManager"
) as expected_signal:
bus1.export(export_path, second_interface)
assert_signal_ok(
signal=await expected_signal,
export_path=export_path,
member="InterfacesAdded",
signature="oa{sa{sv}}",
body=[
export_path,
{
"test.interface.second": {
"str_prop": Variant("s", "abc"),
"list_prop": Variant("ai", [1, 2, 3]),
}
},
],
)
# remove single interface
async with ExpectMessage(
bus1, bus2, "org.freedesktop.DBus.ObjectManager"
) as expected_signal:
bus1.unexport(export_path, second_interface)
assert_signal_ok(
signal=await expected_signal,
export_path=export_path,
member="InterfacesRemoved",
signature="oas",
body=[export_path, ["test.interface.second"]],
)
# add second interface again
async with ExpectMessage(
bus1, bus2, "org.freedesktop.DBus.ObjectManager"
) as expected_signal:
bus1.export(export_path, second_interface)
await expected_signal
# remove multiple interfaces
async with ExpectMessage(
bus1, bus2, "org.freedesktop.DBus.ObjectManager"
) as expected_signal:
bus1.unexport(export_path)
assert_signal_ok(
signal=await expected_signal,
export_path=export_path,
member="InterfacesRemoved",
signature="oas",
body=[export_path, ["test.interface.first", "test.interface.second"]],
)
bus1.disconnect()
bus2.disconnect()
bus1._sock.close()
bus2._sock.close()
dbus-fast-2.44.1/tests/service/test_standard_interfaces.py 0000664 0000000 0000000 00000021503 14773556132 0023726 0 ustar 00root root 0000000 0000000 import pytest
from dbus_fast import Message, MessageType
from dbus_fast import introspection as intr
from dbus_fast.aio import MessageBus
from dbus_fast.constants import ErrorType
from dbus_fast.service import PropertyAccess, ServiceInterface, dbus_property
from dbus_fast.signature import Variant
standard_interfaces_count = len(intr.Node.default().interfaces)
class ExampleInterface(ServiceInterface):
def __init__(self, name):
super().__init__(name)
class ExampleComplexInterface(ServiceInterface):
def __init__(self, name):
self._foo = 42
self._bar = "str"
self._async_prop = "async"
super().__init__(name)
@dbus_property(access=PropertyAccess.READ)
def Foo(self) -> "y":
return self._foo
@dbus_property(access=PropertyAccess.READ)
def Bar(self) -> "s":
return self._bar
@dbus_property(access=PropertyAccess.READ)
async def AsyncProp(self) -> "s":
return self._async_prop
@pytest.mark.asyncio
async def test_introspectable_interface():
bus1 = await MessageBus().connect()
bus2 = await MessageBus().connect()
interface = ExampleInterface("test.interface")
interface2 = ExampleInterface("test.interface2")
export_path = "/test/path"
bus1.export(export_path, interface)
bus1.export(export_path, interface2)
reply = await bus2.call(
Message(
destination=bus1.unique_name,
path=export_path,
interface="org.freedesktop.DBus.Introspectable",
member="Introspect",
)
)
assert reply.message_type == MessageType.METHOD_RETURN, reply.body[0]
assert reply.signature == "s"
node = intr.Node.parse(reply.body[0])
assert len(node.interfaces) == standard_interfaces_count + 2
assert node.interfaces[-1].name == "test.interface2"
assert node.interfaces[-2].name == "test.interface"
assert not node.nodes
# introspect works on every path
reply = await bus2.call(
Message(
destination=bus1.unique_name,
path="/path/doesnt/exist",
interface="org.freedesktop.DBus.Introspectable",
member="Introspect",
)
)
assert reply.message_type == MessageType.METHOD_RETURN, reply.body[0]
assert reply.signature == "s"
node = intr.Node.parse(reply.body[0])
assert not node.interfaces
assert not node.nodes
bus1.disconnect()
bus2.disconnect()
@pytest.mark.asyncio
async def test_introspect_matching_sub_paths():
bus1 = await MessageBus().connect()
bus2 = await MessageBus().connect()
interface = ExampleInterface("test.interface1")
bus1.export("/a/test/path1", interface)
bus1.export("/a/test/path10", interface)
bus1.export("/a/subpath/a/test/path2", interface)
async def introspect_subpath(path, expected_subnodes):
reply = await bus2.call(
Message(
destination=bus1.unique_name,
path=path,
interface="org.freedesktop.DBus.Introspectable",
member="Introspect",
)
)
assert reply.signature == "s"
node = intr.Node.parse(reply.body[0])
assert {n.name for n in node.nodes} == expected_subnodes
await introspect_subpath("/", {"a"})
await introspect_subpath("/a", {"test", "subpath"})
await introspect_subpath("/a/test", {"path1", "path10"})
await introspect_subpath("/a/test/path1", set())
await introspect_subpath("/a/test/path10", set())
await introspect_subpath("/a/subpath/a/test", {"path2"})
await introspect_subpath("/a/subpath/a/test/path2", set())
bus1.disconnect()
bus2.disconnect()
@pytest.mark.asyncio
async def test_peer_interface():
bus1 = await MessageBus().connect()
bus2 = await MessageBus().connect()
reply = await bus2.call(
Message(
destination=bus1.unique_name,
path="/path/doesnt/exist",
interface="org.freedesktop.DBus.Peer",
member="Ping",
)
)
assert reply.message_type == MessageType.METHOD_RETURN, reply.body[0]
assert reply.signature == ""
reply = await bus2.call(
Message(
destination=bus1.unique_name,
path="/path/doesnt/exist",
interface="org.freedesktop.DBus.Peer",
member="GetMachineId",
signature="",
)
)
assert reply.message_type == MessageType.METHOD_RETURN, reply.body[0]
assert reply.signature == "s"
reply2 = await bus2.call(
Message(
destination=bus1.unique_name,
path="/path/doesnt/exist",
interface="org.freedesktop.DBus.Peer",
member="GetMachineId",
signature="",
)
)
assert reply2.message_type == MessageType.METHOD_RETURN, reply.body[0]
assert reply2.signature == "s"
bus1.disconnect()
bus2.disconnect()
@pytest.mark.asyncio
async def test_object_manager():
expected_reply = {
"/test/path/deeper": {
"test.interface2": {
"Bar": Variant("s", "str"),
"Foo": Variant("y", 42),
"AsyncProp": Variant("s", "async"),
}
}
}
reply_ext = {
"/test/path": {
"test.interface1": {},
"test.interface2": {
"Bar": Variant("s", "str"),
"Foo": Variant("y", 42),
"AsyncProp": Variant("s", "async"),
},
}
}
bus1 = await MessageBus().connect()
bus2 = await MessageBus().connect()
interface = ExampleInterface("test.interface1")
interface2 = ExampleComplexInterface("test.interface2")
export_path = "/test/path"
bus1.export(export_path, interface)
bus1.export(export_path, interface2)
bus1.export(export_path + "/deeper", interface2)
reply_root = await bus2.call(
Message(
destination=bus1.unique_name,
path="/",
interface="org.freedesktop.DBus.ObjectManager",
member="GetManagedObjects",
)
)
reply_level1 = await bus2.call(
Message(
destination=bus1.unique_name,
path=export_path,
interface="org.freedesktop.DBus.ObjectManager",
member="GetManagedObjects",
)
)
reply_level2 = await bus2.call(
Message(
destination=bus1.unique_name,
path=export_path + "/deeper",
interface="org.freedesktop.DBus.ObjectManager",
member="GetManagedObjects",
)
)
assert reply_root.signature == "a{oa{sa{sv}}}", reply_root
assert reply_level1.signature == "a{oa{sa{sv}}}", reply_level1
assert reply_level2.signature == "a{oa{sa{sv}}}", reply_level2
assert reply_level2.body == [{}]
assert reply_level1.body == [expected_reply]
expected_reply.update(reply_ext)
assert reply_root.body == [expected_reply]
bus1.disconnect()
bus2.disconnect()
@pytest.mark.asyncio
async def test_standard_interface_properties():
# standard interfaces have no properties, but should still behave correctly
# when you try to call the methods anyway (#49)
bus1 = await MessageBus().connect()
bus2 = await MessageBus().connect()
interface = ExampleInterface("test.interface1")
export_path = "/test/path"
bus1.export(export_path, interface)
for iface in [
"org.freedesktop.DBus.Properties",
"org.freedesktop.DBus.Introspectable",
"org.freedesktop.DBus.Peer",
"org.freedesktop.DBus.ObjectManager",
]:
result = await bus2.call(
Message(
destination=bus1.unique_name,
path=export_path,
interface="org.freedesktop.DBus.Properties",
member="Get",
signature="ss",
body=[iface, "anything"],
)
)
assert result.message_type is MessageType.ERROR
assert result.error_name == ErrorType.UNKNOWN_PROPERTY.value
result = await bus2.call(
Message(
destination=bus1.unique_name,
path=export_path,
interface="org.freedesktop.DBus.Properties",
member="Set",
signature="ssv",
body=[iface, "anything", Variant("s", "new thing")],
)
)
assert result.message_type is MessageType.ERROR
assert result.error_name == ErrorType.UNKNOWN_PROPERTY.value
result = await bus2.call(
Message(
destination=bus1.unique_name,
path=export_path,
interface="org.freedesktop.DBus.Properties",
member="GetAll",
signature="s",
body=[iface],
)
)
assert result.message_type is MessageType.METHOD_RETURN
assert result.body == [{}]
bus1.disconnect()
bus2.disconnect()
dbus-fast-2.44.1/tests/test_address_parser.py 0000664 0000000 0000000 00000004723 14773556132 0021271 0 ustar 00root root 0000000 0000000 import os
from unittest.mock import patch
import pytest
from dbus_fast._private.address import (
get_bus_address,
get_session_bus_address,
get_system_bus_address,
parse_address,
)
from dbus_fast.constants import BusType
from dbus_fast.errors import InvalidAddressError
def test_valid_addresses():
valid_addresses = {
"unix:path=/run/user/1000/bus": [("unix", {"path": "/run/user/1000/bus"})],
"unix:abstract=/tmp/dbus-ft9sODWpZk,guid=a7b1d5912379c2d471165e9b5cb74a03": [
(
"unix",
{
"abstract": "/tmp/dbus-ft9sODWpZk",
"guid": "a7b1d5912379c2d471165e9b5cb74a03",
},
)
],
"unix1:key1=val1;unix2:key2=val2": [
("unix1", {"key1": "val1"}),
("unix2", {"key2": "val2"}),
],
"unix:escaped=hello%20world": [("unix", {"escaped": "hello world"})],
"tcp:host=127.0.0.1,port=55556": [
("tcp", {"host": "127.0.0.1", "port": "55556"})
],
"unix:tmpdir=/tmp,;": [("unix", {"tmpdir": "/tmp"})],
}
for address, parsed in valid_addresses.items():
assert parse_address(address) == parsed
def test_invalid_addresses():
with pytest.raises(InvalidAddressError):
assert parse_address("")
with pytest.raises(InvalidAddressError):
assert parse_address("unix")
with pytest.raises(InvalidAddressError):
assert parse_address("unix:tmpdir")
with pytest.raises(InvalidAddressError):
assert parse_address("unix:tmpdir=😁")
def test_get_system_bus_address():
with patch.dict(os.environ, DBUS_SYSTEM_BUS_ADDRESS="unix:path=/dog"):
assert get_system_bus_address() == "unix:path=/dog"
assert get_bus_address(BusType.SYSTEM) == "unix:path=/dog"
with patch.dict(os.environ, DBUS_SYSTEM_BUS_ADDRESS=""):
assert get_system_bus_address() == "unix:path=/var/run/dbus/system_bus_socket"
def test_get_session_bus_address():
with patch.dict(os.environ, DBUS_SESSION_BUS_ADDRESS="unix:path=/dog"):
assert get_session_bus_address() == "unix:path=/dog"
assert get_bus_address(BusType.SESSION) == "unix:path=/dog"
with (
patch.dict(os.environ, DBUS_SESSION_BUS_ADDRESS="", DISPLAY=""),
pytest.raises(InvalidAddressError),
):
assert get_session_bus_address()
def test_invalid_bus_address():
with pytest.raises(Exception):
assert get_bus_address(-1)
dbus-fast-2.44.1/tests/test_aio_low_level.py 0000664 0000000 0000000 00000012132 14773556132 0021101 0 ustar 00root root 0000000 0000000 import pytest
from dbus_fast import Message, MessageFlag, MessageType
from dbus_fast.aio import MessageBus
@pytest.mark.asyncio
async def test_standard_interfaces():
bus = await MessageBus().connect()
msg = Message(
destination="org.freedesktop.DBus",
path="/org/freedesktop/DBus",
interface="org.freedesktop.DBus",
member="ListNames",
serial=bus.next_serial(),
)
reply = await bus.call(msg)
assert reply.message_type == MessageType.METHOD_RETURN
assert reply.reply_serial == msg.serial
assert reply.signature == "as"
assert bus.unique_name in reply.body[0]
msg.interface = "org.freedesktop.DBus.Introspectable"
msg.member = "Introspect"
msg.serial = bus.next_serial()
reply = await bus.call(msg)
assert reply.message_type == MessageType.METHOD_RETURN
assert reply.reply_serial == msg.serial
assert reply.signature == "s"
assert type(reply.body[0]) is str
msg.member = "MemberDoesNotExist"
msg.serial = bus.next_serial()
reply = await bus.call(msg)
assert reply.message_type == MessageType.ERROR
assert reply.reply_serial == msg.serial
assert reply.error_name
assert reply.signature == "s"
assert type(reply.body[0]) is str
bus.disconnect()
@pytest.mark.asyncio
async def test_error_handling():
bus = await MessageBus().connect()
msg = Message(
destination="org.freedesktop.DBus",
path="/org/freedesktop/DBus",
interface="org.freedesktop.DBus",
member="InvalidMember",
serial=bus.next_serial(),
)
reply = await bus.call(msg)
assert reply.message_type == MessageType.ERROR
assert reply.reply_serial == msg.serial
assert reply.signature == "s"
bus.disconnect()
@pytest.mark.asyncio
async def test_sending_messages_between_buses():
bus1 = await MessageBus().connect()
bus2 = await MessageBus().connect()
msg = Message(
destination=bus1.unique_name,
path="/org/test/path",
interface="org.test.iface",
member="SomeMember",
serial=bus2.next_serial(),
)
def message_handler(sent):
if sent.sender == bus2.unique_name and sent.serial == msg.serial:
assert sent.path == msg.path
assert sent.serial == msg.serial
assert sent.interface == msg.interface
assert sent.member == msg.member
bus1.send(Message.new_method_return(sent, "s", ["got it"]))
bus1.remove_message_handler(message_handler)
return True
bus1.add_message_handler(message_handler)
reply = await bus2.call(msg)
assert reply.message_type == MessageType.METHOD_RETURN
assert reply.sender == bus1.unique_name
assert reply.signature == "s"
assert reply.body == ["got it"]
assert reply.reply_serial == msg.serial
def message_handler_error(sent):
if sent.sender == bus2.unique_name and sent.serial == msg.serial:
assert sent.path == msg.path
assert sent.serial == msg.serial
assert sent.interface == msg.interface
assert sent.member == msg.member
bus1.send(Message.new_error(sent, "org.test.Error", "throwing an error"))
bus1.remove_message_handler(message_handler_error)
return True
bus1.add_message_handler(message_handler_error)
msg.serial = bus2.next_serial()
reply = await bus2.call(msg)
assert reply.message_type == MessageType.ERROR
assert reply.sender == bus1.unique_name
assert reply.reply_serial == msg.serial
assert reply.error_name == "org.test.Error"
assert reply.signature == "s"
assert reply.body == ["throwing an error"]
msg.serial = bus2.next_serial()
msg.flags = MessageFlag.NO_REPLY_EXPECTED
reply = await bus2.call(msg)
assert reply is None
bus1.disconnect()
bus2.disconnect()
@pytest.mark.asyncio
async def test_sending_signals_between_buses(event_loop):
bus1 = await MessageBus().connect()
bus2 = await MessageBus().connect()
add_match_msg = Message(
destination="org.freedesktop.DBus",
path="/org/freedesktop/DBus",
interface="org.freedesktop.DBus",
member="AddMatch",
signature="s",
body=[f"sender={bus2.unique_name}"],
)
await bus1.call(add_match_msg)
async def wait_for_message():
future = event_loop.create_future()
def message_handler(signal):
if signal.sender == bus2.unique_name:
bus1.remove_message_handler(message_handler)
future.set_result(signal)
bus1.add_message_handler(message_handler)
return await future
bus2.send(
Message.new_signal(
"/org/test/path", "org.test.interface", "SomeSignal", "s", ["a signal"]
)
)
signal = await wait_for_message()
assert signal.message_type == MessageType.SIGNAL
assert signal.path == "/org/test/path"
assert signal.interface == "org.test.interface"
assert signal.member == "SomeSignal"
assert signal.signature == "s"
assert signal.body == ["a signal"]
bus1.disconnect()
bus2.disconnect()
dbus-fast-2.44.1/tests/test_aio_multi_flags.py 0000664 0000000 0000000 00000001132 14773556132 0021415 0 ustar 00root root 0000000 0000000 import pytest
from dbus_fast.aio import MessageBus
from dbus_fast.service import ServiceInterface, method
@pytest.mark.asyncio
async def test_multiple_flags_in_message():
class ExampleInterface(ServiceInterface):
def __init__(self, name):
super().__init__(name)
@method()
def Echo(self, what: "s") -> "s":
return what
bus = await MessageBus().connect()
interface = ExampleInterface("test.interface")
bus.export("/test/path", interface)
await bus.request_name("test.name")
bus.disconnect()
await bus.wait_for_disconnect()
dbus-fast-2.44.1/tests/test_auth.py 0000664 0000000 0000000 00000001400 14773556132 0017216 0 ustar 00root root 0000000 0000000 """This tests setting a hardcoded UID in AuthExternal"""
import pytest
from dbus_fast.auth import (
UID_NOT_SPECIFIED,
AuthAnnonymous,
AuthAnonymous,
AuthExternal,
)
from dbus_fast.errors import AuthError
def test_annonymous_backcompat():
auth = AuthAnnonymous()
assert isinstance(auth, AuthAnonymous)
def test_uid_is_set():
auth = AuthExternal(uid=999)
assert auth._authentication_start() == "AUTH EXTERNAL 393939"
def test_auth_external_no_uid():
"""Test AuthExternal with UID_NOT_SPECIFIED"""
auth = AuthExternal(uid=UID_NOT_SPECIFIED)
assert auth._authentication_start() == "AUTH EXTERNAL"
assert auth._receive_line("DATA") == "DATA"
with pytest.raises(AuthError):
auth._receive_line("REJECTED")
dbus-fast-2.44.1/tests/test_big_message.py 0000664 0000000 0000000 00000004126 14773556132 0020532 0 ustar 00root root 0000000 0000000 import sys
import pytest
from dbus_fast import Message, MessageType, aio, glib
from dbus_fast.service import ServiceInterface, method
from tests.util import check_gi_repository, skip_reason_no_gi
has_gi = check_gi_repository()
class ExampleInterface(ServiceInterface):
def __init__(self):
super().__init__("example.interface")
@method()
def echo_bytes(self, what: "ay") -> "ay":
return what
@pytest.mark.asyncio
async def test_aio_big_message():
"this tests that nonblocking reads and writes actually work for aio"
bus1 = await aio.MessageBus().connect()
bus2 = await aio.MessageBus().connect()
interface = ExampleInterface()
bus1.export("/test/path", interface)
# two megabytes
big_body = [bytes(1000000) * 2]
result = await bus2.call(
Message(
destination=bus1.unique_name,
path="/test/path",
interface=interface.name,
member="echo_bytes",
signature="ay",
body=big_body,
)
)
assert result.message_type == MessageType.METHOD_RETURN, result.body[0]
assert result.body[0] == big_body[0]
bus1.disconnect()
bus2.disconnect()
@pytest.mark.skipif(not has_gi, reason=skip_reason_no_gi)
@pytest.mark.skipif(
sys.version_info[:3][1] in (10, 11, 12, 13),
reason="segfaults on py3.10,py3.11,py3.12,py3.13",
)
def test_glib_big_message():
"this tests that nonblocking reads and writes actually work for glib"
bus1 = glib.MessageBus().connect_sync()
bus2 = glib.MessageBus().connect_sync()
interface = ExampleInterface()
bus1.export("/test/path", interface)
# two megabytes
big_body = [bytes(1000000) * 2]
result = bus2.call_sync(
Message(
destination=bus1.unique_name,
path="/test/path",
interface=interface.name,
member="echo_bytes",
signature="ay",
body=big_body,
)
)
assert result.message_type == MessageType.METHOD_RETURN, result.body[0]
assert result.body[0] == big_body[0]
bus1.disconnect()
bus2.disconnect()
dbus-fast-2.44.1/tests/test_constants.py 0000664 0000000 0000000 00000000513 14773556132 0020275 0 ustar 00root root 0000000 0000000 from dbus_fast.constants import MESSAGE_FLAG_MAP, ErrorType, MessageFlag
from dbus_fast.errors import DBusError
def test_message_flag_map():
assert 0 in MESSAGE_FLAG_MAP
assert MessageFlag.NONE in MESSAGE_FLAG_MAP
def test_error_type():
err = DBusError(ErrorType.FAILED, "")
assert err.type == ErrorType.FAILED
dbus-fast-2.44.1/tests/test_disconnect.py 0000664 0000000 0000000 00000004100 14773556132 0020406 0 ustar 00root root 0000000 0000000 import asyncio
from unittest.mock import patch
import pytest
from dbus_fast import Message
from dbus_fast.aio import MessageBus
@pytest.mark.asyncio
async def test_bus_disconnect_before_reply(event_loop):
"""In this test, the bus disconnects before the reply comes in. Make sure
the caller receives a reply with the error instead of hanging."""
bus = MessageBus()
assert not bus.connected
await bus.connect()
assert bus.connected
with patch.object(bus._writer, "_write_without_remove_writer"):
ping = bus.call(
Message(
destination="org.freedesktop.DBus",
path="/org/freedesktop/DBus",
interface="org.freedesktop.DBus",
member="Ping",
)
)
event_loop.call_soon(bus.disconnect)
with pytest.raises((EOFError, BrokenPipeError)):
await ping
assert bus._disconnected
assert not bus.connected
assert (await bus.wait_for_disconnect()) is None
# Let the exception propagate to the event loop
# so the next test does not fail
await asyncio.sleep(0)
await asyncio.sleep(0)
@pytest.mark.asyncio
async def test_unexpected_disconnect(event_loop):
bus = MessageBus()
class FakeSocket:
def send(self, *args, **kwargs):
raise OSError
assert not bus.connected
await bus.connect()
assert bus.connected
with (
patch.object(bus._writer, "_write_without_remove_writer"),
patch.object(bus._writer, "sock", FakeSocket()),
):
ping = bus.call(
Message(
destination="org.freedesktop.DBus",
path="/org/freedesktop/DBus",
interface="org.freedesktop.DBus",
member="Ping",
)
)
with pytest.raises(OSError):
await ping
assert bus._disconnected
assert not bus.connected
with pytest.raises(OSError):
await bus.wait_for_disconnect()
bus.disconnect()
with pytest.raises(OSError):
await bus.wait_for_disconnect()
dbus-fast-2.44.1/tests/test_fd_passing.py 0000664 0000000 0000000 00000025667 14773556132 0020417 0 ustar 00root root 0000000 0000000 """This tests the ability to send and receive file descriptors in dbus messages"""
import os
import pytest
from dbus_fast import Message, MessageType
from dbus_fast.aio import MessageBus
from dbus_fast.service import ServiceInterface, dbus_property, method, signal
from dbus_fast.signature import SignatureTree, Variant
def open_file():
return os.open(os.devnull, os.O_RDONLY)
class ExampleInterface(ServiceInterface):
def __init__(self, name):
super().__init__(name)
self.fds = []
@method()
def ReturnsFd(self) -> "h":
fd = open_file()
self.fds.append(fd)
return fd
@method()
def AcceptsFd(self, fd: "h"):
assert fd != 0
self.fds.append(fd)
def get_last_fd(self):
return self.fds[-1]
def cleanup(self):
for fd in self.fds:
os.close(fd)
self.fds.clear()
@signal()
def SignalFd(self) -> "h":
fd = open_file()
self.fds.append(fd)
return fd
@dbus_property()
def PropFd(self) -> "h":
if not self.fds:
fd = open_file()
self.fds.append(fd)
return self.fds[-1]
@PropFd.setter
def PropFd(self, fd: "h"):
assert fd
self.fds.append(fd)
def assert_fds_equal(fd1, fd2):
assert fd1
assert fd2
stat1 = os.fstat(fd1)
stat2 = os.fstat(fd2)
assert stat1.st_dev == stat2.st_dev
assert stat1.st_ino == stat2.st_ino
assert stat1.st_rdev == stat2.st_rdev
@pytest.mark.asyncio
async def test_sending_file_descriptor_low_level():
bus1 = await MessageBus(negotiate_unix_fd=True).connect()
bus2 = await MessageBus(negotiate_unix_fd=True).connect()
fd_before = open_file()
fd_after = None
msg = Message(
destination=bus1.unique_name,
path="/org/test/path",
interface="org.test.iface",
member="SomeMember",
body=[0],
signature="h",
unix_fds=[fd_before],
)
def message_handler(sent):
nonlocal fd_after
if sent.sender == bus2.unique_name and sent.serial == msg.serial:
assert sent.path == msg.path
assert sent.serial == msg.serial
assert sent.interface == msg.interface
assert sent.member == msg.member
assert sent.body == [0]
assert len(sent.unix_fds) == 1
fd_after = sent.unix_fds[0]
bus1.send(Message.new_method_return(sent, "s", ["got it"]))
bus1.remove_message_handler(message_handler)
return True
bus1.add_message_handler(message_handler)
reply = await bus2.call(msg)
assert reply.body == ["got it"]
assert fd_after is not None
assert_fds_equal(fd_before, fd_after)
for fd in [fd_before, fd_after]:
os.close(fd)
for bus in [bus1, bus2]:
bus.disconnect()
@pytest.mark.asyncio
async def test_high_level_service_fd_passing(event_loop):
bus1 = await MessageBus(negotiate_unix_fd=True).connect()
bus2 = await MessageBus(negotiate_unix_fd=True).connect()
interface_name = "test.interface"
interface = ExampleInterface(interface_name)
export_path = "/test/path"
async def call(member, signature="", body=[], unix_fds=[], iface=interface.name):
return await bus2.call(
Message(
destination=bus1.unique_name,
path=export_path,
interface=iface,
member=member,
signature=signature,
body=body,
unix_fds=unix_fds,
)
)
bus1.export(export_path, interface)
# test that an fd can be returned by the service
reply = await call("ReturnsFd")
assert reply.message_type == MessageType.METHOD_RETURN, reply.body
assert reply.signature == "h"
assert len(reply.unix_fds) == 1
assert_fds_equal(interface.get_last_fd(), reply.unix_fds[0])
interface.cleanup()
os.close(reply.unix_fds[0])
# test that an fd can be sent to the service
fd = open_file()
reply = await call("AcceptsFd", signature="h", body=[0], unix_fds=[fd])
assert reply.message_type == MessageType.METHOD_RETURN, reply.body
assert_fds_equal(interface.get_last_fd(), fd)
interface.cleanup()
os.close(fd)
# signals
fut = event_loop.create_future()
def fd_listener(msg):
if msg.sender == bus1.unique_name and msg.message_type == MessageType.SIGNAL:
fut.set_result(msg)
reply = await bus2.call(
Message(
destination="org.freedesktop.DBus",
path="/org/freedesktop/DBus",
member="AddMatch",
signature="s",
body=[f"sender='{bus1.unique_name}'"],
)
)
assert reply.message_type == MessageType.METHOD_RETURN
bus2.add_message_handler(fd_listener)
interface.SignalFd()
reply = await fut
assert len(reply.unix_fds) == 1
assert reply.body == [0]
assert_fds_equal(reply.unix_fds[0], interface.get_last_fd())
interface.cleanup()
os.close(reply.unix_fds[0])
# properties
reply = await call(
"Get", "ss", [interface_name, "PropFd"], iface="org.freedesktop.DBus.Properties"
)
assert reply.message_type == MessageType.METHOD_RETURN, reply.body
assert reply.body[0].signature == "h"
assert reply.body[0].value == 0
assert len(reply.unix_fds) == 1
assert_fds_equal(interface.get_last_fd(), reply.unix_fds[0])
interface.cleanup()
os.close(reply.unix_fds[0])
fd = open_file()
reply = await call(
"Set",
"ssv",
[interface_name, "PropFd", Variant("h", 0)],
iface="org.freedesktop.DBus.Properties",
unix_fds=[fd],
)
assert reply.message_type == MessageType.METHOD_RETURN, reply.body
assert_fds_equal(interface.get_last_fd(), fd)
interface.cleanup()
os.close(fd)
reply = await call(
"GetAll", "s", [interface_name], iface="org.freedesktop.DBus.Properties"
)
assert reply.message_type == MessageType.METHOD_RETURN, reply.body
assert reply.body[0]["PropFd"].signature == "h"
assert reply.body[0]["PropFd"].value == 0
assert len(reply.unix_fds) == 1
assert_fds_equal(interface.get_last_fd(), reply.unix_fds[0])
interface.cleanup()
os.close(reply.unix_fds[0])
for bus in [bus1, bus2]:
bus.disconnect()
@pytest.mark.asyncio
async def test_sending_file_descriptor_with_proxy(event_loop):
name = "dbus.next.test.service"
path = "/test/path"
interface_name = "test.interface"
bus = await MessageBus(negotiate_unix_fd=True).connect()
interface = ExampleInterface(interface_name)
bus.export(path, interface)
await bus.request_name(name)
intr = await bus.introspect(name, path)
proxy = bus.get_proxy_object(name, path, intr)
proxy_interface = proxy.get_interface(interface_name)
# test fds are replaced correctly in all high level interfaces
fd = await proxy_interface.call_returns_fd()
assert_fds_equal(interface.get_last_fd(), fd)
interface.cleanup()
os.close(fd)
fd = open_file()
await proxy_interface.call_accepts_fd(fd)
assert_fds_equal(interface.get_last_fd(), fd)
interface.cleanup()
os.close(fd)
fd = await proxy_interface.get_prop_fd()
assert_fds_equal(interface.get_last_fd(), fd)
interface.cleanup()
os.close(fd)
fd = open_file()
await proxy_interface.set_prop_fd(fd)
assert_fds_equal(interface.get_last_fd(), fd)
interface.cleanup()
os.close(fd)
fut = event_loop.create_future()
def on_signal_fd(fd):
fut.set_result(fd)
proxy_interface.off_signal_fd(on_signal_fd)
proxy_interface.on_signal_fd(on_signal_fd)
interface.SignalFd()
fd = await fut
assert_fds_equal(interface.get_last_fd(), fd)
interface.cleanup()
os.close(fd)
bus.disconnect()
@pytest.mark.asyncio
@pytest.mark.parametrize(
"result, out_signature, expected",
[
pytest.param(5, "h", ([0], [5]), id='Signature: "h"'),
pytest.param([5, "foo"], "hs", ([0, "foo"], [5]), id='Signature: "hs"'),
pytest.param([5, 7], "hh", ([0, 1], [5, 7]), id='Signature: "hh"'),
pytest.param([5, 7], "ah", ([[0, 1]], [5, 7]), id='Signature: "ah"'),
pytest.param([9], "ah", ([[0]], [9]), id='Signature: "ah"'),
pytest.param([3], "(h)", ([[0]], [3]), id='Signature: "(h)"'),
pytest.param([3, "foo"], "(hs)", ([[0, "foo"]], [3]), id='Signature: "(hs)"'),
pytest.param(
[[7, "foo"], [8, "bar"]],
"a(hs)",
([[[0, "foo"], [1, "bar"]]], [7, 8]),
id='Signature: "a(hs)"',
),
pytest.param({"foo": 3}, "a{sh}", ([{"foo": 0}], [3]), id='Signature: "a{sh}"'),
pytest.param(
{"foo": 3, "bar": 6},
"a{sh}",
([{"foo": 0, "bar": 1}], [3, 6]),
id='Signature: "a{sh}"',
),
pytest.param(
{"foo": [3, 8]},
"a{sah}",
([{"foo": [0, 1]}], [3, 8]),
id='Signature: "a{sah}"',
),
pytest.param(
{"foo": Variant("t", 100)},
"a{sv}",
([{"foo": Variant("t", 100)}], []),
id='Signature: "a{sv}"',
),
pytest.param(
["one", ["two", [Variant("s", "three")]]],
"(s(s(v)))",
([["one", ["two", [Variant("s", "three")]]]], []),
id='Signature: "(s(s(v)))"',
),
pytest.param(
Variant("h", 2), "v", ([Variant("h", 0)], [2]), id='Variant with: "h"'
),
pytest.param(
Variant("(hh)", [2, 8]),
"v",
([Variant("(hh)", [0, 1])], [2, 8]),
id='Variant with: "(hh)"',
),
pytest.param(
Variant("ah", [2, 4]),
"v",
([Variant("ah", [0, 1])], [2, 4]),
id='Variant with: "ah"',
),
pytest.param(
Variant("(ss)", ["hello", "world"]),
"v",
([Variant("(ss)", ["hello", "world"])], []),
id='Variant with: "(ss)"',
),
pytest.param(
Variant("v", Variant("t", 100)),
"v",
([Variant("v", Variant("t", 100))], []),
id='Variant with: "v"',
),
pytest.param(
[
Variant("v", Variant("(ss)", ["hello", "world"])),
{"foo": Variant("t", 100)},
["one", ["two", [Variant("s", "three")]]],
],
"va{sv}(s(s(v)))",
(
[
Variant("v", Variant("(ss)", ["hello", "world"])),
{"foo": Variant("t", 100)},
["one", ["two", [Variant("s", "three")]]],
],
[],
),
id='Variant with: "va{sv}(s(s(v)))"',
),
],
)
async def test_fn_result_to_body(result, out_signature, expected):
out_signature_tree = SignatureTree(out_signature)
assert ServiceInterface._fn_result_to_body(result, out_signature_tree) == expected
dbus-fast-2.44.1/tests/test_glib_low_level.py 0000664 0000000 0000000 00000012536 14773556132 0021256 0 ustar 00root root 0000000 0000000 import sys
import pytest
from dbus_fast import Message, MessageFlag, MessageType
from dbus_fast.glib import MessageBus
from tests.util import check_gi_repository, skip_reason_no_gi
has_gi = check_gi_repository()
if has_gi:
from gi.repository import GLib
@pytest.mark.skipif(not has_gi, reason=skip_reason_no_gi)
@pytest.mark.skipif(
sys.version_info[:3][1] in (10, 11, 12, 13),
reason="segfaults on py3.10,py3.11,py3.12,py3.13",
)
def test_standard_interfaces():
bus = MessageBus().connect_sync()
msg = Message(
destination="org.freedesktop.DBus",
path="/org/freedesktop/DBus",
interface="org.freedesktop.DBus",
member="ListNames",
serial=bus.next_serial(),
)
reply = bus.call_sync(msg)
assert reply.message_type == MessageType.METHOD_RETURN
assert reply.reply_serial == msg.serial
assert reply.signature == "as"
assert bus.unique_name in reply.body[0]
msg.interface = "org.freedesktop.DBus.Introspectable"
msg.member = "Introspect"
msg.serial = bus.next_serial()
reply = bus.call_sync(msg)
assert reply.message_type == MessageType.METHOD_RETURN
assert reply.reply_serial == msg.serial
assert reply.signature == "s"
assert type(reply.body[0]) is str
msg.member = "MemberDoesNotExist"
msg.serial = bus.next_serial()
reply = bus.call_sync(msg)
assert reply.message_type == MessageType.ERROR
assert reply.reply_serial == msg.serial
assert reply.error_name
assert reply.signature == "s"
assert type(reply.body[0]) is str
bus.disconnect()
@pytest.mark.skipif(not has_gi, reason=skip_reason_no_gi)
@pytest.mark.skipif(
sys.version_info[:3][1] in (10, 11, 12, 13),
reason="segfaults on py3.10,py3.11,py3.12,py3.13",
)
def test_sending_messages_between_buses():
bus1 = MessageBus().connect_sync()
bus2 = MessageBus().connect_sync()
msg = Message(
destination=bus1.unique_name,
path="/org/test/path",
interface="org.test.iface",
member="SomeMember",
serial=bus2.next_serial(),
)
def message_handler(sent):
if sent.sender == bus2.unique_name and sent.serial == msg.serial:
assert sent.path == msg.path
assert sent.serial == msg.serial
assert sent.interface == msg.interface
assert sent.member == msg.member
bus1.send(Message.new_method_return(sent, "s", ["got it"]))
bus1.remove_message_handler(message_handler)
return True
bus1.add_message_handler(message_handler)
reply = bus2.call_sync(msg)
assert reply.message_type == MessageType.METHOD_RETURN, reply.body[0]
assert reply.sender == bus1.unique_name
assert reply.signature == "s"
assert reply.body == ["got it"]
assert reply.reply_serial == msg.serial
def message_handler_error(sent):
if sent.sender == bus2.unique_name and sent.serial == msg.serial:
assert sent.path == msg.path
assert sent.serial == msg.serial
assert sent.interface == msg.interface
assert sent.member == msg.member
bus1.send(Message.new_error(sent, "org.test.Error", "throwing an error"))
bus1.remove_message_handler(message_handler_error)
return True
bus1.add_message_handler(message_handler_error)
msg.serial = bus2.next_serial()
reply = bus2.call_sync(msg)
assert reply.message_type == MessageType.ERROR
assert reply.sender == bus1.unique_name
assert reply.reply_serial == msg.serial
assert reply.error_name == "org.test.Error"
assert reply.signature == "s"
assert reply.body == ["throwing an error"]
msg.serial = bus2.next_serial()
msg.flags = MessageFlag.NO_REPLY_EXPECTED
reply = bus2.call_sync(msg)
assert reply is None
bus1.disconnect()
bus2.disconnect()
bus1._sock.close()
bus2._sock.close()
@pytest.mark.skipif(not has_gi, reason=skip_reason_no_gi)
@pytest.mark.skipif(
sys.version_info[:3][1] in (10, 11, 12, 13),
reason="segfaults on py3.10,py3.11,py3.12,py3.13",
)
def test_sending_signals_between_buses():
bus1 = MessageBus().connect_sync()
bus2 = MessageBus().connect_sync()
add_match_msg = Message(
destination="org.freedesktop.DBus",
path="/org/freedesktop/DBus",
interface="org.freedesktop.DBus",
member="AddMatch",
signature="s",
body=[f"sender={bus2.unique_name}"],
)
bus1.call_sync(add_match_msg)
main = GLib.MainLoop()
def wait_for_message():
ret = None
def message_handler(signal):
nonlocal ret
if signal.sender == bus2.unique_name:
ret = signal
bus1.remove_message_handler(message_handler)
main.quit()
bus1.add_message_handler(message_handler)
main.run()
return ret
bus2.send(
Message.new_signal(
"/org/test/path", "org.test.interface", "SomeSignal", "s", ["a signal"]
)
)
signal = wait_for_message()
assert signal.message_type == MessageType.SIGNAL
assert signal.path == "/org/test/path"
assert signal.interface == "org.test.interface"
assert signal.member == "SomeSignal"
assert signal.signature == "s"
assert signal.body == ["a signal"]
bus1.disconnect()
bus2.disconnect()
bus1._sock.close()
bus2._sock.close()
dbus-fast-2.44.1/tests/test_introspection.py 0000664 0000000 0000000 00000010442 14773556132 0021163 0 ustar 00root root 0000000 0000000 import os
from dbus_fast import (
ArgDirection,
InvalidMemberNameError,
PropertyAccess,
SignatureType,
)
from dbus_fast import introspection as intr
with open(f"{os.path.dirname(__file__)}/data/strict-introspection.xml") as f:
strict_data = f.read()
with open(f"{os.path.dirname(__file__)}/data/sloppy-introspection.xml") as f:
sloppy_data = f.read()
def test_introspection_from_xml_sloppy():
intr.Node.parse(sloppy_data, validate_property_names=False)
def test_introspection_from_xml_strict():
try:
node = intr.Node.parse(sloppy_data)
except InvalidMemberNameError:
pass
else:
assert False, "Expected an AssertionError"
node = intr.Node.parse(strict_data)
assert len(node.interfaces) == 1
interface = node.interfaces[0]
assert len(node.nodes) == 2
assert len(interface.methods) == 3
assert len(interface.signals) == 2
assert len(interface.properties) == 1
assert type(node.nodes[0]) is intr.Node
assert node.nodes[0].name == "child_of_sample_object"
assert type(node.nodes[1]) is intr.Node
assert node.nodes[1].name == "another_child_of_sample_object"
assert interface.name == "com.example.SampleInterface0"
frobate = interface.methods[0]
assert type(frobate) is intr.Method
assert frobate.name == "Frobate"
assert len(frobate.in_args) == 1
assert len(frobate.out_args) == 2
foo = frobate.in_args[0]
assert type(foo) is intr.Arg
assert foo.name == "foo"
assert foo.direction == ArgDirection.IN
assert foo.signature == "i"
assert type(foo.type) is SignatureType
assert foo.type.token == "i"
bar = frobate.out_args[0]
assert type(bar) is intr.Arg
assert bar.name == "bar"
assert bar.direction == ArgDirection.OUT
assert bar.signature == "s"
assert type(bar.type) is SignatureType
assert bar.type.token == "s"
prop = interface.properties[0]
assert type(prop) is intr.Property
assert prop.name == "Bar"
assert prop.signature == "y"
assert type(prop.type) is SignatureType
assert prop.type.token == "y"
assert prop.access == PropertyAccess.WRITE
changed = interface.signals[0]
assert type(changed) is intr.Signal
assert changed.name == "Changed"
assert len(changed.args) == 1
new_value = changed.args[0]
assert type(new_value) is intr.Arg
assert new_value.name == "0-new_value"
assert new_value.signature == "b"
def test_example_introspection_to_xml():
node = intr.Node.parse(strict_data)
tree = node.to_xml()
assert tree.tag == "node"
assert tree.attrib.get("name") == "/com/example/sample_object0"
assert len(tree) == 3
interface = tree[0]
assert interface.tag == "interface"
assert interface.get("name") == "com.example.SampleInterface0"
assert len(interface) == 6
method = interface[0]
assert method.tag == "method"
assert method.get("name") == "Frobate"
assert len(method) == 4
arg = method[0]
assert arg.tag == "arg"
assert arg.attrib.get("name") == "foo"
assert arg.attrib.get("type") == "i"
assert arg.attrib.get("direction") == "in"
annotation = method[3]
assert annotation.tag == "annotation"
assert annotation.attrib.get("name") == "org.freedesktop.DBus.Deprecated"
assert annotation.attrib.get("value") == "true"
signal = interface[3]
assert signal.tag == "signal"
assert signal.attrib.get("name") == "Changed"
assert len(signal) == 1
arg = signal[0]
assert arg.tag == "arg"
assert arg.attrib.get("name") == "0-new_value"
assert arg.attrib.get("type") == "b"
signal = interface[4]
assert signal.tag == "signal"
assert signal.attrib.get("name") == "ChangedMulti"
assert len(signal) == 2
arg = signal[0]
assert arg.tag == "arg"
assert arg.attrib.get("name") == "new_value1"
assert arg.attrib.get("type") == "b"
arg = signal[1]
assert arg.tag == "arg"
assert arg.attrib.get("name") == "0-new_value2"
assert arg.attrib.get("type") == "y"
prop = interface[5]
assert prop.attrib.get("name") == "Bar"
assert prop.attrib.get("type") == "y"
assert prop.attrib.get("access") == "write"
def test_default_interfaces():
# just make sure it doesn't throw
default = intr.Node.default()
assert type(default) is intr.Node
dbus-fast-2.44.1/tests/test_marshaller.py 0000664 0000000 0000000 00000074733 14773556132 0020432 0 ustar 00root root 0000000 0000000 import io
import json
import os
from enum import Enum
from typing import Any
import pytest
from dbus_fast import Message, MessageFlag, MessageType, SignatureTree, Variant
from dbus_fast._private._cython_compat import FakeCython
from dbus_fast._private.constants import BIG_ENDIAN, LITTLE_ENDIAN
from dbus_fast._private.unmarshaller import (
Unmarshaller,
buffer_to_int16,
buffer_to_uint16,
buffer_to_uint32,
is_compiled,
)
from dbus_fast.unpack import unpack_variants
def test_bytearray_to_uint32_big_end():
assert buffer_to_uint32(bytearray(b"\x01\x02\x03\x04"), 0, BIG_ENDIAN) == 16909060
assert (
buffer_to_uint32(
bytearray((0xFFFFFFFF).to_bytes(4, byteorder="big", signed=False)),
0,
BIG_ENDIAN,
)
== 0xFFFFFFFF
)
def test_bytearray_to_uint16_big_end():
assert buffer_to_uint16(bytearray(b"\x01\x02"), 0, BIG_ENDIAN) == 258
assert (
buffer_to_uint16(
bytearray((0xFFFF).to_bytes(2, byteorder="big", signed=False)),
0,
BIG_ENDIAN,
)
== 0xFFFF
)
def test_bytearray_to_int16_big_end():
assert buffer_to_int16(bytearray(b"\x01\x02"), 0, BIG_ENDIAN) == 258
assert (
buffer_to_int16(
bytearray((32767).to_bytes(2, byteorder="big", signed=True)), 0, BIG_ENDIAN
)
== 32767
)
@pytest.mark.skipif(not is_compiled(), reason="requires cython")
def test_bytearray_to_int16_big_end_signed():
assert buffer_to_int16(bytearray(b"\xff\xff"), 0, BIG_ENDIAN) == -1
assert (
buffer_to_int16(
bytearray((-32768).to_bytes(2, byteorder="big", signed=True)),
0,
BIG_ENDIAN,
)
== -32768
)
def test_bytearray_to_uint32_little_end():
assert (
buffer_to_uint32(bytearray(b"\x01\x02\x03\x04"), 0, LITTLE_ENDIAN) == 67305985
)
assert (
buffer_to_uint32(
bytearray((0xFFFFFFFF).to_bytes(4, byteorder="little", signed=False)),
0,
LITTLE_ENDIAN,
)
== 0xFFFFFFFF
)
def test_bytearray_to_uint16_little_end():
assert buffer_to_uint16(bytearray(b"\x01\x02"), 0, LITTLE_ENDIAN) == 513
assert (
buffer_to_uint16(
bytearray((0xFFFF).to_bytes(2, byteorder="little", signed=False)),
0,
LITTLE_ENDIAN,
)
== 0xFFFF
)
def test_bytearray_to_int16_little_end():
assert buffer_to_int16(bytearray(b"\x01\x02"), 0, LITTLE_ENDIAN) == 513
assert (
buffer_to_int16(
bytearray((32767).to_bytes(2, byteorder="little", signed=True)),
0,
LITTLE_ENDIAN,
)
== 32767
)
@pytest.mark.skipif(not is_compiled(), reason="requires cython")
def test_bytearray_to_int16_little_end_signed():
assert buffer_to_int16(bytearray(b"\xff\xff"), 0, LITTLE_ENDIAN) == -1
assert (
buffer_to_int16(
bytearray((-32768).to_bytes(2, byteorder="little", signed=True)),
0,
LITTLE_ENDIAN,
)
== -32768
)
def print_buf(buf):
i = 0
while True:
p = buf[i : i + 8]
if not p:
break
print(p)
i += 8
# these messages have been verified with another library
with open(os.path.dirname(__file__) + "/data/messages.json") as f:
table = json.load(f)
with open(os.path.dirname(__file__) + "/data/get_managed_objects.hex") as fp:
get_managed_objects_msg = fp.read()
def json_to_message(message: dict[str, Any]) -> Message:
copy = dict(message)
if "message_type" in copy:
copy["message_type"] = MessageType(copy["message_type"])
if "flags" in copy:
copy["flags"] = MessageFlag(copy["flags"])
return Message(**copy)
# variants are an object in the json
def replace_variants(type_, item):
if type_.token == "v" and type(item) is not Variant:
item = Variant(
item["signature"],
replace_variants(SignatureTree(item["signature"]).types[0], item["value"]),
)
elif type_.token == "a":
for i, item_child in enumerate(item):
if type_.children[0].token == "{":
for k, v in item.items():
item[k] = replace_variants(type_.children[0].children[1], v)
else:
item[i] = replace_variants(type_.children[0], item_child)
elif type_.token == "(":
for i, item_child in enumerate(item):
if type_.children[0].token == "{":
assert False
else:
item[i] = replace_variants(type_.children[i], item_child)
return item
def json_dump(what):
def dumper(obj):
try:
return obj.toJSON()
except Exception:
return obj.__dict__
return json.dumps(what, default=dumper, indent=2)
def test_marshalling_with_table():
for item in table:
message = json_to_message(item["message"])
body = []
for i, type_ in enumerate(message.signature_tree.types):
body.append(replace_variants(type_, message.body[i]))
message.body = body
buf = message._marshall(False)
data = bytes.fromhex(item["data"])
if buf != data:
print("message:")
print(json_dump(item["message"]))
print()
print("mine:")
print_buf(bytes(buf))
print()
print("theirs:")
print_buf(data)
assert buf == data
@pytest.mark.parametrize("unmarshall_table", (table,))
def test_unmarshalling_with_table(unmarshall_table):
for item in unmarshall_table:
stream = io.BytesIO(bytes.fromhex(item["data"]))
unmarshaller = Unmarshaller(stream)
try:
unmarshaller.unmarshall()
except Exception as e:
print("message failed to unmarshall:")
print(json_dump(item["message"]))
raise e
message = json_to_message(item["message"])
body = []
for i, type_ in enumerate(message.signature_tree.types):
body.append(replace_variants(type_, message.body[i]))
message.body = body
for attr in [
"body",
"signature",
"message_type",
"destination",
"path",
"interface",
"member",
"flags",
"serial",
]:
assert getattr(unmarshaller.message, attr) == getattr(message, attr), (
f"attr doesnt match: {attr}"
)
def test_unmarshall_can_resume():
"""Verify resume works."""
bluez_rssi_message = (
"6c04010134000000e25389019500000001016f00250000002f6f72672f626c75657a2f686369302f6465"
"765f30385f33415f46325f31455f32425f3631000000020173001f0000006f72672e667265656465736b"
"746f702e444275732e50726f7065727469657300030173001100000050726f706572746965734368616e"
"67656400000000000000080167000873617b73767d617300000007017300040000003a312e3400000000"
"110000006f72672e626c75657a2e446576696365310000000e0000000000000004000000525353490001"
"6e00a7ff000000000000"
)
message_bytes = bytes.fromhex(bluez_rssi_message)
class SlowStream(io.IOBase):
"""A fake stream that will only give us one byte at a time."""
def __init__(self):
self.data = message_bytes
self.pos = 0
def read(self, n) -> bytes:
data = self.data[self.pos : self.pos + 1]
self.pos += 1
return data
stream = SlowStream()
unmarshaller = Unmarshaller(stream)
for _ in range(len(bluez_rssi_message)):
if unmarshaller.unmarshall():
break
assert unmarshaller.message is not None
def test_unmarshall_bluez_message():
bluez_mfr_message = (
"6c040101780000009aca0a009500000001016f00250000002f6f72672f626c75657a2f686369302f646576"
"5f44305f43325f34455f30385f41425f3537000000020173001f0000006f72672e667265656465736b746f"
"702e444275732e50726f7065727469657300030173001100000050726f706572746965734368616e676564"
"00000000000000080167000873617b73767d617300000007017300040000003a312e340000000011000000"
"6f72672e626c75657a2e446576696365310000005400000000000000040000005253534900016e00aaff00"
"00100000004d616e756661637475726572446174610005617b71767d002400000075000261790000001800"
"00004204010170d0c24e08ab57d2c24e08ab5601000000000000000000006c040101340000009bca0a0095"
"00000001016f002500"
)
message_bytes = bytes.fromhex(bluez_mfr_message)
stream = io.BytesIO(message_bytes)
unmarshaller = Unmarshaller(stream)
assert unmarshaller.unmarshall()
message = unmarshaller.message
assert message is not None
assert message.body == [
"org.bluez.Device1",
{
"ManufacturerData": Variant(
"a{qv}",
{
117: Variant(
"ay",
bytearray(
b"B\x04\x01\x01p\xd0\xc2N\x08\xabW\xd2\xc2N\x08\xabV\x01\x00\x00\x00\x00\x00\x00"
),
)
},
),
"RSSI": Variant("n", -86),
},
[],
]
assert message.sender == ":1.4"
assert message.path == "/org/bluez/hci0/dev_D0_C2_4E_08_AB_57"
assert message.interface == "org.freedesktop.DBus.Properties"
assert message.member == "PropertiesChanged"
assert message.signature == "sa{sv}as"
assert message.message_type == MessageType.SIGNAL
assert message.flags == MessageFlag.NO_REPLY_EXPECTED
assert message.serial == 707226
assert message.destination is None
unpacked = unpack_variants(message.body)
assert unpacked == [
"org.bluez.Device1",
{
"ManufacturerData": {
117: bytearray(
b"B\x04\x01\x01p\xd0\xc2N\x08\xabW\xd2"
b"\xc2N\x08\xabV\x01\x00\x00"
b"\x00\x00\x00\x00"
)
},
"RSSI": -86,
},
[],
]
def test_unmarshall_bluez_interfaces_added_message():
bluez_interfaces_added_message = (
b'l\4\1\1\240\2\0\0\227\272\23\0u\0\0\0\1\1o\0\1\0\0\0/\0\0\0\0\0\0\0\2\1s\0"\0\0\0'
b"org.freedesktop.DBus.ObjectManager\0\0\0\0\0\0\3\1s\0\17\0\0\0InterfacesAdded\0\10"
b"\1g\0\noa{sa{sv}}\0\7\1s\0\4\0\0\0:1.4\0\0\0\0%\0\0\0/org/bluez/hci1/dev_58_2D_34"
b"_60_26_36\0\0\0p\2\0\0#\0\0\0org.freedesktop.DBus.Introspectable\0\0\0\0\0\0\0\0\0"
b"\21\0\0\0org.bluez.Device1\0\0\0\364\1\0\0\0\0\0\0\7\0\0\0Address\0\1s\0\0\21\0\0"
b"\00058:2D:34:60:26:36\0\0\0\v\0\0\0AddressType\0\1s\0\0\6\0\0\0public\0\0\4\0\0\0"
b"Name\0\1s\0\33\0\0\0Qingping Door/Window Sensor\0\0\0\0\0\5\0\0\0Alias\0\1s\0\0\0"
b"\0\33\0\0\0Qingping Door/Window Sensor\0\6\0\0\0Paired\0\1b\0\0\0\0\0\0\0\0\0\0\0"
b"\7\0\0\0Trusted\0\1b\0\0\0\0\0\0\0\0\0\0\7\0\0\0Blocked\0\1b\0\0\0\0\0\0\0\0\0\0\r"
b"\0\0\0LegacyPairing\0\1b\0\0\0\0\0\0\0\0\0\0\0\0\4\0\0\0RSSI\0\1n\0\316\377\0\0\t"
b"\0\0\0Connected\0\1b\0\0\0\0\0\0\0\0\5\0\0\0UUIDs\0\2as\0\0\0\0\0\0\0\0\0\0\0\7\0"
b"\0\0Adapter\0\1o\0\0\17\0\0\0/org/bluez/hci1\0\0\0\0\0\v\0\0\0ServiceData\0\5a{sv}"
b"\0\0@\0\0\0\0\0\0\0$\0\0\0000000fe95-0000-1000-8000-00805f9b34fb\0\2ay\0\0\0\0\f\0"
b"\0\0000X\326\3\0026&`4-X\10\20\0\0\0ServicesResolved\0\1b\0\0\0\0\0\0\0\0\0\37\0\0"
b"\0org.freedesktop.DBus.Properties\0\0\0\0\0"
)
stream = io.BytesIO(bluez_interfaces_added_message)
unmarshaller = Unmarshaller(stream)
assert unmarshaller.unmarshall()
message = unmarshaller.message
assert message is not None
assert message.body == [
"/org/bluez/hci1/dev_58_2D_34_60_26_36",
{
"org.bluez.Device1": {
"Adapter": Variant("o", "/org/bluez/hci1"),
"Address": Variant("s", "58:2D:34:60:26:36"),
"AddressType": Variant("s", "public"),
"Alias": Variant("s", "Qingping Door/Window Sensor"),
"Blocked": Variant("b", False),
"Connected": Variant("b", False),
"LegacyPairing": Variant("b", False),
"Name": Variant("s", "Qingping Door/Window Sensor"),
"Paired": Variant("b", False),
"RSSI": Variant("n", -50),
"ServiceData": Variant(
"a{sv}",
{
"0000fe95-0000-1000-8000-00805f9b34fb": Variant(
"ay", bytearray(b"0X\xd6\x03\x026&`4-X\x08")
)
},
),
"ServicesResolved": Variant("b", False),
"Trusted": Variant("b", False),
"UUIDs": Variant("as", []),
},
"org.freedesktop.DBus.Introspectable": {},
"org.freedesktop.DBus.Properties": {},
},
]
assert message.sender == ":1.4"
assert message.path == "/"
assert message.interface == "org.freedesktop.DBus.ObjectManager"
assert message.member == "InterfacesAdded"
assert message.signature == "oa{sa{sv}}"
assert message.message_type == MessageType.SIGNAL
assert message.flags == MessageFlag.NO_REPLY_EXPECTED
assert message.serial == 1292951
assert message.destination is None
unpacked = unpack_variants(message.body)
assert unpacked == [
"/org/bluez/hci1/dev_58_2D_34_60_26_36",
{
"org.bluez.Device1": {
"Adapter": "/org/bluez/hci1",
"Address": "58:2D:34:60:26:36",
"AddressType": "public",
"Alias": "Qingping Door/Window Sensor",
"Blocked": False,
"Connected": False,
"LegacyPairing": False,
"Name": "Qingping Door/Window Sensor",
"Paired": False,
"RSSI": -50,
"ServiceData": {
"0000fe95-0000-1000-8000-00805f9b34fb": bytearray(
b"0X\xd6\x03\x026&`4-X\x08"
)
},
"ServicesResolved": False,
"Trusted": False,
"UUIDs": [],
},
"org.freedesktop.DBus.Introspectable": {},
"org.freedesktop.DBus.Properties": {},
},
]
def test_unmarshall_bluez_interfaces_removed_message():
bluez_interfaces_removed_message = (
b'l\4\1\1\222\0\0\0\377@-\0~\0\0\0\1\1o\0\1\0\0\0/\0\0\0\0\0\0\0\2\1s\0"\0\0\0'
b"org.freedesktop.DBus.ObjectManager\0\0\0\0\0\0\3\1s\0\21\0\0\0InterfacesRemoved"
b"\0\0\0\0\0\0\0\10\1g\0\3oas\0\0\0\0\0\0\0\0\7\1s\0\5\0\0\0:1.12\0\0\0%\0\0\0"
b"/org/bluez/hci0/dev_5F_13_47_38_26_55\0\0\0b\0\0\0\37\0\0\0org.freedesktop.DBus"
b".Properties\0#\0\0\0org.freedesktop.DBus.Introspectable\0\21\0\0\0org.bluez.Dev"
b"ice1\0"
)
stream = io.BytesIO(bluez_interfaces_removed_message)
unmarshaller = Unmarshaller(stream)
assert unmarshaller.unmarshall()
message = unmarshaller.message
assert message is not None
assert message.body == [
"/org/bluez/hci0/dev_5F_13_47_38_26_55",
[
"org.freedesktop.DBus.Properties",
"org.freedesktop.DBus.Introspectable",
"org.bluez.Device1",
],
]
assert message.sender == ":1.12"
assert message.path == "/"
assert message.interface == "org.freedesktop.DBus.ObjectManager"
assert message.member == "InterfacesRemoved"
assert message.signature == "oas"
assert message.message_type == MessageType.SIGNAL
assert message.flags == MessageFlag.NO_REPLY_EXPECTED
assert message.serial == 2965759
assert message.destination is None
unpacked = unpack_variants(message.body)
assert unpacked == [
"/org/bluez/hci0/dev_5F_13_47_38_26_55",
[
"org.freedesktop.DBus.Properties",
"org.freedesktop.DBus.Introspectable",
"org.bluez.Device1",
],
]
def test_unmarshall_bluez_properties_changed_with_service_data():
bluez_properties_changed_message = (
b"l\4\1\1\334\0\0\0@\236.\0\226\0\0\0\1\1o\0%\0\0\0/org/bluez/hci0/dev_58_2D_34_60_DA_1F"
b"\0\0\0\2\1s\0\37\0\0\0org.freedesktop.DBus.Properties\0\3\1s\0\21\0\0\0PropertiesChanged"
b"\0\0\0\0\0\0\0\10\1g\0\10sa{sv}as\0\0\0\7\1s\0\5\0\0\0:1.12\0\0\0\21\0\0\0org.bluez.Devi"
b"ce1\0\0\0\270\0\0\0\0\0\0\0\4\0\0\0RSSI\0\1n\0\301\377\0\0\v\0\0\0ServiceData\0\5a{sv}"
b"\0\0\210\0\0\0\0\0\0\0$\0\0\0000000fdcd-0000-1000-8000-00805f9b34fb\0\2ay\0\0\0\0\24\0"
b"\0\0\10\22\37\332`4-X\2\1U\17\1\315\t\4\5\0\0\0$\0\0\0000000fe95-0000-1000-8000-00805f"
b"9b34fb\0\2ay\0\0\0\0\f\0\0\0000X\203\n\2\37\332`4-X\10\0\0\0\0"
)
stream = io.BytesIO(bluez_properties_changed_message)
unmarshaller = Unmarshaller(stream)
assert unmarshaller.unmarshall()
message = unmarshaller.message
assert message is not None
assert message.body == [
"org.bluez.Device1",
{
"RSSI": Variant("n", -63),
"ServiceData": Variant(
"a{sv}",
{
"0000fdcd-0000-1000-8000-00805f9b34fb": Variant(
"ay",
bytearray(
b"\x08\x12\x1f\xda`4-X\x02\x01U\x0f\x01\xcd\t\x04\x05\x00\x00\x00"
),
),
"0000fe95-0000-1000-8000-00805f9b34fb": Variant(
"ay", bytearray(b"0X\x83\n\x02\x1f\xda`4-X\x08")
),
},
),
},
[],
]
assert message.sender == ":1.12"
assert message.path == "/org/bluez/hci0/dev_58_2D_34_60_DA_1F"
assert message.interface == "org.freedesktop.DBus.Properties"
assert message.member == "PropertiesChanged"
assert message.signature == "sa{sv}as"
assert message.message_type == MessageType.SIGNAL
assert message.flags == MessageFlag.NO_REPLY_EXPECTED
assert message.serial == 3055168
assert message.destination is None
unpacked = unpack_variants(message.body)
assert unpacked == [
"org.bluez.Device1",
{
"RSSI": -63,
"ServiceData": {
"0000fdcd-0000-1000-8000-00805f9b34fb": bytearray(
b"\x08\x12\x1f\xda`4-X\x02\x01U\x0f\x01\xcd\t\x04\x05\x00\x00\x00"
),
"0000fe95-0000-1000-8000-00805f9b34fb": bytearray(
b"0X\x83\n\x02\x1f\xda`4-X\x08"
),
},
},
[],
]
def test_unmarshall_multiple_messages():
"""Test we can unmarshall multiple messages in a single packet."""
multiple_message_packet = (
b"l\4\1\0014\0\0\0J\27\230\0\225\0\0\0\1\1o\0%\0\0\0/org/bluez/hci0/dev_F0_B3_EC_15_7F_8E\0\0\0\2\1s\0\37\0\0\0"
b"org.freedesktop.DBus.Properties\0\3\1s\0\21\0\0\0PropertiesChanged\0\0\0\0\0\0\0\10\1g\0\10sa{sv}as\0\0\0\7\1"
b"s\0\4\0\0\0:1.4\0\0\0\0\21\0\0\0org.bluez.Device1\0\0\0\16\0\0\0\0\0\0\0\4\0\0\0RSSI\0\1n\0\264\377\0\0\0\0\0"
b"\0l\4\1\0014\0\0\0K\27\230\0\225\0\0\0\1\1o\0%\0\0\0/org/bluez/hci0/dev_3F_70_98_0F_08_CB\0\0\0\2\1s\0\37\0\0"
b"\0org.freedesktop.DBus.Properties\0\3\1s\0\21\0\0\0PropertiesChanged\0\0\0\0\0\0\0\10\1g\0\10sa{sv}as\0\0\0\7"
b"\1s\0\4\0\0\0:1.4\0\0\0\0\21\0\0\0org.bluez.Device1\0\0\0\16\0\0\0\0\0\0\0\4\0\0\0RSSI\0\1n\0\260\377\0\0\0\0"
b"\0\0l\4\1\0014\0\0\0L\27\230\0\225\0\0\0\1\1o\0%\0\0\0/org/bluez/hci0/dev_D8_35_67_A4_F5_A5\0\0\0\2\1s\0\37\0"
b"\0\0org.freedesktop.DBus.Properties\0\3\1s\0\21\0\0\0PropertiesChanged\0\0\0\0\0\0\0\10\1g\0\10sa{sv}as\0\0\0"
b"\7\1s\0\4\0\0\0:1.4\0\0\0\0\21\0\0\0org.bluez.Device1\0\0\0\16\0\0\0\0\0\0\0\4\0\0\0RSSI\0\1n\0\242\377\0\0\0"
b"\0\0\0"
)
stream = io.BytesIO(multiple_message_packet)
unmarshaller = Unmarshaller(stream)
assert unmarshaller.unmarshall()
message = unmarshaller.message
assert message is not None
unpacked = unpack_variants(message.body)
assert unpacked == ["org.bluez.Device1", {"RSSI": -76}, []]
assert unmarshaller.unmarshall()
message = unmarshaller.message
assert message is not None
unpacked = unpack_variants(message.body)
assert unpacked == ["org.bluez.Device1", {"RSSI": -80}, []]
assert unmarshaller.unmarshall()
message = unmarshaller.message
assert message is not None
unpacked = unpack_variants(message.body)
assert unpacked == ["org.bluez.Device1", {"RSSI": -94}, []]
with pytest.raises(EOFError):
unmarshaller.unmarshall()
def test_ay_buffer():
body = [bytes(10000)]
msg = Message(path="/test", member="test", signature="ay", body=body)
marshalled = msg._marshall(False)
unmarshalled_msg = Unmarshaller(io.BytesIO(marshalled)).unmarshall()
assert unmarshalled_msg.body[0] == body[0]
def tests_fallback_no_cython():
assert FakeCython().compiled is False
def test_unmarshall_large_message():
stream = io.BytesIO(bytes.fromhex(get_managed_objects_msg))
unmarshaller = Unmarshaller(stream)
unmarshaller.unmarshall()
message = unmarshaller.message
unpacked = unpack_variants(message.body)
objects = unpacked[0]
assert objects["/org/bluez/hci0"] == {
"org.bluez.Adapter1": {
"Address": "00:1A:7D:DA:71:04",
"AddressType": "public",
"Alias": "homeassistant",
"Class": 2883584,
"Discoverable": False,
"DiscoverableTimeout": 180,
"Discovering": True,
"Modalias": "usb:v1D6Bp0246d053F",
"Name": "homeassistant",
"Pairable": False,
"PairableTimeout": 0,
"Powered": True,
"Roles": ["central", "peripheral"],
"UUIDs": [
"0000110e-0000-1000-8000-00805f9b34fb",
"0000110a-0000-1000-8000-00805f9b34fb",
"00001200-0000-1000-8000-00805f9b34fb",
"0000110b-0000-1000-8000-00805f9b34fb",
"00001108-0000-1000-8000-00805f9b34fb",
"0000110c-0000-1000-8000-00805f9b34fb",
"00001800-0000-1000-8000-00805f9b34fb",
"00001801-0000-1000-8000-00805f9b34fb",
"0000180a-0000-1000-8000-00805f9b34fb",
"00001112-0000-1000-8000-00805f9b34fb",
],
},
"org.bluez.GattManager1": {},
"org.bluez.LEAdvertisingManager1": {
"ActiveInstances": 0,
"SupportedIncludes": ["tx-power", "appearance", "local-name"],
"SupportedInstances": 5,
},
"org.bluez.Media1": {},
"org.bluez.NetworkServer1": {},
"org.freedesktop.DBus.Introspectable": {},
"org.freedesktop.DBus.Properties": {},
}
assert objects["/org/bluez/hci0/dev_CD_A3_FA_D1_50_56/service000b/char000c"] == {
"org.bluez.GattCharacteristic1": {
"Flags": ["read"],
"Service": "/org/bluez/hci0/dev_CD_A3_FA_D1_50_56/service000b",
"UUID": "e604e95d-a759-4817-87d3-aa005083a0d1",
"Value": bytearray(b""),
},
"org.freedesktop.DBus.Introspectable": {},
"org.freedesktop.DBus.Properties": {},
}
def test_unmarshall_big_end_message():
"""Test we can unmarshall a big endian message."""
msg = (
b"B\x01\x00\x01\x00\x00\x00 \x00\x00\x00\x00\x00\x00\x00\x82"
b"\x01\x01o\x00\x00\x00\x00\x01/\x00\x00\x00\x00\x00\x00\x00"
b'\x02\x01s\x00\x00\x00\x00"org.freedesktop.DBus.ObjectManag'
b"er\x00\x00\x00\x00\x00\x00\x03\x01s\x00\x00\x00\x00\x11GetManagedOb"
b"jects\x00\x00\x00\x00\x00\x00\x00\x06\x01s\x00\x00\x00\x00\torg."
b"bluez\x00\x00\x00\x00\x00\x00\x00\x08\x01g\x00\x04ussv\x00\x00\x00"
b"\x00\x00\x00\x00\x00\x00\x00*\x00\x00\x00\x03zip\x00"
b"\x00\x00\x00\x07Trusted\x00\x01b\x00\x00\x00\x00\x00\x01"
)
stream = io.BytesIO(msg)
unmarshaller = Unmarshaller(stream)
unmarshaller.unmarshall()
message = unmarshaller.message
unpacked = unpack_variants(message.body)
assert unpacked == [42, "zip", "Trusted", True]
class RaucState(str, Enum):
"""Rauc slot states."""
GOOD = "good"
BAD = "bad"
ACTIVE = "active"
def test_marshalling_enum():
"""Test marshalling an enum."""
msg = Message(
path="/test",
member="test",
signature="s",
body=[RaucState.GOOD],
)
marshalled = msg._marshall(False)
unmarshalled_msg = Unmarshaller(io.BytesIO(marshalled)).unmarshall()
assert unpack_variants(unmarshalled_msg.body)[0] == RaucState.GOOD.value
def test_unmarshall_bluez_passive_message():
"""Test we can unmarshall a bluez passive message."""
bluez_passive_message = (
b"l\1\1\1*\0\0\0\205D\267\3\215\0\0\0\1\1o\0\35\0\0\0/org/bleak/61/281472597302272\0\0\0\6\1s\0\7\0\0"
b"\0:1.1450\0\2\1s\0\37\0\0\0org.bluez.AdvertisementMonitor1\0\3\1s\0\v\0\0\0DeviceFound\0\0\0\0\0\10"
b"\1g\0\1o\0\0\7\1s\0\4\0\0\0:1.4\0\0\0\0%\0\0\0/org/bluez/hci0/dev_58_D3_49_E6_02_6E\0l\1\1\1*\0\0\0"
b"\206D\267\3\215\0\0\0\1\1o\0\35\0\0\0/org/bleak/61/281472593362560\0\0\0\6\1s\0\7\0\0\0:1.1450\0\2"
b"\1s\0\37\0\0\0org.bluez.AdvertisementMonitor1\0\3\1s\0\v\0\0\0DeviceFound\0\0\0\0\0\10\1g\0\1o\0\0"
b"\7\1s\0\4\0\0\0:1.4\0\0\0\0%\0\0\0/org/bluez/hci1/dev_58_D3_49_E6_02_6E\0"
)
stream = io.BytesIO(bluez_passive_message)
unmarshaller = Unmarshaller(stream)
unmarshaller.unmarshall()
message = unmarshaller.message
assert "/org/bluez/hci0/dev_58_D3_49_E6_02_6E" in str(message)
unpacked = unpack_variants(message.body)
assert unpacked == ["/org/bluez/hci0/dev_58_D3_49_E6_02_6E"]
def test_unmarshall_mount_message():
"""Test we mount message unmarshall."""
mount_message = (
b"l\1\0\1\30\1\0\0\213\1\0\0\266\0\0\0\1\1o\0\31\0\0\0/org/freedesktop/systemd1"
b"\0\0\0\0\0\0\0\2\1s\0 \0\0\0org.freedesktop.systemd1.Manager\0\0\0\0\0\0\0\0"
b"\3\1s\0\22\0\0\0StartTransientUnit\0\0\0\0\0\0\6\1s\0\30\0\0\0org.freedesktop"
b".systemd1\0\0\0\0\0\0\0\0\10\1g\0\20ssa(sv)a(sa(sv))\0\0\0)\0\0\0mnt-data-sup"
b"ervisor-mounts-test1234.mount\0\0\0\4\0\0\0fail\0\0\0\0\314\0\0\0\7\0\0\0Opti"
b"ons\0\1s\0\0I\0\0\0noserverino,credentials=/mnt/data/supervisor/.mounts_crede"
b"ntials/test1234\0\0\0\4\0\0\0Type\0\1s\0\4\0\0\0cifs\0\0\0\0\v\0\0\0Descripti"
b"on\0\1s\0\0\37\0\0\0Supervisor cifs mount: test1234\0\4\0\0\0What\0\1s\0\v\0\0"
b"\0//\303\274ber/test\0\0\0\0\0\0\0\0\0\0\0\0"
)
stream = io.BytesIO(mount_message)
unmarshaller = Unmarshaller(stream)
unmarshaller.unmarshall()
message = unmarshaller.message
assert unmarshaller.message.signature == "ssa(sv)a(sa(sv))"
unpacked = unpack_variants(message.body)
assert unpacked == [
"mnt-data-supervisor-mounts-test1234.mount",
"fail",
[
[
"Options",
"noserverino,credentials=/mnt/data/supervisor/.mounts_credentials/test1234",
],
["Type", "cifs"],
["Description", "Supervisor cifs mount: test1234"],
["What", "//über/tes"],
],
[],
]
def test_unmarshall_mount_message_2():
"""Test we mount message unmarshall version 2."""
mount_message = (
b"l\1\0\1 \1\0\0+\6\0\0\266\0\0\0\1\1o\0\31\0\0\0/org/freedesktop/systemd1"
b"\0\0\0\0\0\0\0\2\1s\0 \0\0\0org.freedesktop.systemd1.Manager\0\0\0\0\0\0"
b"\0\0\3\1s\0\22\0\0\0StartTransientUnit\0\0\0\0\0\0\6\1s\0\30\0\0\0org.fr"
b"eedesktop.systemd1\0\0\0\0\0\0\0\0\10\1g\0\20ssa(sv)a(sa(sv))\0\0\0(\0\0"
b"\0mnt-data-supervisor-mounts-BadTest.mount\0\0\0\0\4\0\0\0fail\0\0\0\0\324"
b"\0\0\0\7\0\0\0Options\0\1s\0\0H\0\0\0noserverino,credentials=/mnt/data/su"
b"pervisor/.mounts_credentials/BadTest\0\0\0\0\4\0\0\0Type\0\1s\0\4\0\0\0cifs"
b"\0\0\0\0\v\0\0\0Description\0\1s\0\0\36\0\0\0Supervisor cifs mount: BadTest"
b"\0\0\4\0\0\0What\0\1s\0\23\0\0\0//doesntmatter/\303\274ber\0\0\0\0\0\0\0\0\0"
b"\0\0\0"
)
stream = io.BytesIO(mount_message)
unmarshaller = Unmarshaller(stream)
unmarshaller.unmarshall()
message = unmarshaller.message
assert unmarshaller.message.signature == "ssa(sv)a(sa(sv))"
unpacked = unpack_variants(message.body)
assert unpacked == [
"mnt-data-supervisor-mounts-BadTest.mount",
"fail",
[
[
"Options",
"noserverino,credentials=/mnt/data/supervisor/.mounts_credentials/BadTest",
],
["Type", "cifs"],
["Description", "Supervisor cifs mount: BadTest"],
["What", "//doesntmatter/übe"],
],
[],
]
def test_unmarshall_multi_byte_string():
"""Test unmarshall a multi-byte string."""
mount_message = (
b"l\x01\x00\x01\x1d\x00\x00\x00"
b"\x01\x00\x00\x00x\x00\x00\x00"
b"\x01\x01o\x00\x15\x00\x00\x00"
b"/org/fre"
b"edesktop"
b"/DBus\x00\x00\x00"
b"\x02\x01s\x00\x14\x00\x00\x00"
b"org.free"
b"desktop."
b"DBus\x00\x00\x00\x00"
b"\x03\x01s\x00\x05\x00\x00\x00"
b"Hello\x00\x00\x00"
b"\x06\x01s\x00\x14\x00\x00\x00"
b"org.free"
b"desktop."
b"DBus\x00\x00\x00\x00"
b"\x08\x01g\x00\x02as\x00"
b"\x19\x00\x00\x00\x14\x00\x00\x00"
b"//doesnt"
b"matter/\xc3"
b"\xbcber\x00"
)
stream = io.BytesIO(mount_message)
unmarshaller = Unmarshaller(stream)
unmarshaller.unmarshall()
message = unmarshaller.message
assert unmarshaller.message.signature == "as"
unpacked = unpack_variants(message.body)
assert unpacked == [["//doesntmatter/über"]]
def test_marshalling_struct_accepts_tuples():
"""Test marshalling a struct accepts tuples."""
msg = Message(
path="/test",
member="test",
signature="(s)",
body=[(RaucState.GOOD,)],
)
marshalled = msg._marshall(False)
unmarshalled_msg = Unmarshaller(io.BytesIO(marshalled)).unmarshall()
assert unpack_variants(unmarshalled_msg.body)[0] == [RaucState.GOOD.value]
def test_marshalling_struct_accepts_lists():
"""Test marshalling a struct accepts lists."""
msg = Message(
path="/test",
member="test",
signature="(s)",
body=[[RaucState.GOOD]],
)
marshalled = msg._marshall(False)
unmarshalled_msg = Unmarshaller(io.BytesIO(marshalled)).unmarshall()
assert unpack_variants(unmarshalled_msg.body)[0] == [RaucState.GOOD.value]
dbus-fast-2.44.1/tests/test_request_name.py 0000664 0000000 0000000 00000004603 14773556132 0020755 0 ustar 00root root 0000000 0000000 import sys
import pytest
from dbus_fast import (
Message,
MessageType,
NameFlag,
ReleaseNameReply,
RequestNameReply,
aio,
glib,
)
from tests.util import check_gi_repository, skip_reason_no_gi
has_gi = check_gi_repository()
@pytest.mark.asyncio
async def test_name_requests():
test_name = "aio.test.request.name"
bus1 = await aio.MessageBus().connect()
bus2 = await aio.MessageBus().connect()
async def get_name_owner(name):
reply = await bus1.call(
Message(
destination="org.freedesktop.DBus",
path="/org/freedesktop/DBus",
interface="org.freedesktop.DBus",
member="GetNameOwner",
signature="s",
body=[name],
)
)
assert reply.message_type == MessageType.METHOD_RETURN
return reply.body[0]
reply = await bus1.request_name(test_name)
assert reply == RequestNameReply.PRIMARY_OWNER
reply = await bus1.request_name(test_name)
assert reply == RequestNameReply.ALREADY_OWNER
reply = await bus2.request_name(test_name, NameFlag.ALLOW_REPLACEMENT)
assert reply == RequestNameReply.IN_QUEUE
reply = await bus1.release_name(test_name)
assert reply == ReleaseNameReply.RELEASED
reply = await bus1.release_name("name.doesnt.exist")
assert reply == ReleaseNameReply.NON_EXISTENT
reply = await bus1.release_name(test_name)
assert reply == ReleaseNameReply.NOT_OWNER
new_owner = await get_name_owner(test_name)
assert new_owner == bus2.unique_name
reply = await bus1.request_name(test_name, NameFlag.DO_NOT_QUEUE)
assert reply == RequestNameReply.EXISTS
reply = await bus1.request_name(
test_name, NameFlag.DO_NOT_QUEUE | NameFlag.REPLACE_EXISTING
)
assert reply == RequestNameReply.PRIMARY_OWNER
bus1.disconnect()
bus2.disconnect()
@pytest.mark.skipif(
sys.version_info[:3][1] in (10, 11, 12, 13),
reason="segfaults on py3.10,py3.11,py3.12,py3.13",
)
@pytest.mark.skipif(not has_gi, reason=skip_reason_no_gi)
def test_request_name_glib():
test_name = "glib.test.request.name"
bus = glib.MessageBus().connect_sync()
reply = bus.request_name_sync(test_name)
assert reply == RequestNameReply.PRIMARY_OWNER
reply = bus.release_name_sync(test_name)
assert reply == ReleaseNameReply.RELEASED
bus.disconnect()
dbus-fast-2.44.1/tests/test_send_reply.py 0000664 0000000 0000000 00000004577 14773556132 0020443 0 ustar 00root root 0000000 0000000 import os
from unittest.mock import patch
import pytest
from dbus_fast.constants import ErrorType, MessageType
from dbus_fast.errors import DBusError
from dbus_fast.message import Message
from dbus_fast.message_bus import BaseMessageBus
from dbus_fast.send_reply import SendReply
@pytest.fixture(autouse=True)
def mock_address() -> None:
original_address = os.environ.get("DBUS_SESSION_BUS_ADDRESS")
os.environ["DBUS_SESSION_BUS_ADDRESS"] = "unix:path=/dev/null"
yield
if original_address is None:
del os.environ["DBUS_SESSION_BUS_ADDRESS"]
else:
os.environ["DBUS_SESSION_BUS_ADDRESS"] = original_address
def test_send_reply_exception() -> None:
"""Test that SendReply sends an error message when DBusError is raised."""
messages = []
class MockBus(BaseMessageBus):
def send(self, msg: Message) -> None:
messages.append(msg)
def send_message(self, msg: Message) -> None:
messages.append(msg)
def _setup_socket(self) -> None:
pass
with patch("socket.socket.connect"):
mock_message_bus = MockBus()
mock_message = Message(
path="/test/path", interface="test.interface", member="test_member", serial=1
)
send_reply = SendReply(mock_message_bus, mock_message)
with send_reply:
raise DBusError(ErrorType.DISCONNECTED, "Disconnected", None)
assert len(messages) == 1
assert messages[0].message_type == MessageType.ERROR
assert messages[0].error_name == "org.freedesktop.DBus.Error.Disconnected"
assert messages[0].reply_serial == 1
def test_send_reply_happy_path() -> None:
"""Test that SendReply sends a message."""
messages = []
class MockBus(BaseMessageBus):
def send(self, msg: Message) -> None:
messages.append(msg)
def send_message(self, msg: Message) -> None:
messages.append(msg)
def _setup_socket(self) -> None:
pass
with patch("socket.socket.connect"):
mock_message_bus = MockBus()
mock_message = Message(
path="/test/path", interface="test.interface", member="test_member", serial=1
)
send_reply = SendReply(mock_message_bus, mock_message)
with send_reply as reply:
reply(mock_message)
assert len(messages) == 1
assert messages[0].message_type == MessageType.METHOD_CALL
assert messages[0].error_name is None
dbus-fast-2.44.1/tests/test_signature.py 0000664 0000000 0000000 00000016414 14773556132 0020271 0 ustar 00root root 0000000 0000000 import pytest
from dbus_fast import SignatureBodyMismatchError, SignatureTree, Variant
from dbus_fast._private.util import signature_contains_type
def assert_simple_type(signature, type_):
assert type_.token == signature
assert type_.signature == signature
assert len(type_.children) == 0
def test_simple():
tree = SignatureTree("s")
assert len(tree.types) == 1
assert_simple_type("s", tree.types[0])
def test_multiple_simple():
tree = SignatureTree("sss")
assert len(tree.types) == 3
for i in range(3):
assert_simple_type("s", tree.types[i])
def test_children():
tree = SignatureTree("ss")
assert len(tree.types) == 2
parent = tree.types[0]
assert parent.token == "s"
assert parent.signature == "s"
assert len(parent.children) == 0
def test_array():
tree = SignatureTree("as")
assert len(tree.types) == 1
child = tree.types[0]
assert child.signature == "as"
assert child.token == "a"
assert len(child.children) == 1
assert_simple_type("s", child.children[0])
assert child.children[0].token == "s"
assert child._child_0.signature == "s"
assert child._child_1 is None
with pytest.raises(AttributeError):
_ = child._child_1.signature
def test_array_multiple():
tree = SignatureTree("asasass")
assert len(tree.types) == 4
assert_simple_type("s", tree.types[3])
for i in range(3):
array_child = tree.types[i]
assert array_child.token == "a"
assert array_child.signature == "as"
assert len(array_child.children) == 1
assert_simple_type("s", array_child.children[0])
def test_array_nested():
tree = SignatureTree("aas")
assert len(tree.types) == 1
child = tree.types[0]
assert child.token == "a"
assert child.signature == "aas"
assert len(child.children) == 1
nested_child = child.children[0]
assert nested_child.token == "a"
assert nested_child.signature == "as"
assert len(nested_child.children) == 1
assert_simple_type("s", nested_child.children[0])
def test_simple_struct():
tree = SignatureTree("(sss)")
assert len(tree.types) == 1
child = tree.types[0]
assert child.signature == "(sss)"
assert len(child.children) == 3
for i in range(3):
assert_simple_type("s", child.children[i])
assert child._child_0.signature == "s"
assert child._child_1.signature == "s"
def test_nested_struct():
tree = SignatureTree("(s(s(s)))")
assert len(tree.types) == 1
child = tree.types[0]
assert child.signature == "(s(s(s)))"
assert child.token == "("
assert len(child.children) == 2
assert_simple_type("s", child.children[0])
first_nested = child.children[1]
assert first_nested.token == "("
assert first_nested.signature == "(s(s))"
assert len(first_nested.children) == 2
assert_simple_type("s", first_nested.children[0])
second_nested = first_nested.children[1]
assert second_nested.token == "("
assert second_nested.signature == "(s)"
assert len(second_nested.children) == 1
assert_simple_type("s", second_nested.children[0])
def test_struct_multiple():
tree = SignatureTree("(s)(s)(s)")
assert len(tree.types) == 3
for i in range(3):
child = tree.types[0]
assert child.token == "("
assert child.signature == "(s)"
assert len(child.children) == 1
assert_simple_type("s", child.children[0])
def test_array_of_structs():
tree = SignatureTree("a(ss)")
assert len(tree.types) == 1
child = tree.types[0]
assert child.token == "a"
assert child.signature == "a(ss)"
assert len(child.children) == 1
struct_child = child.children[0]
assert struct_child.token == "("
assert struct_child.signature == "(ss)"
assert len(struct_child.children) == 2
for i in range(2):
assert_simple_type("s", struct_child.children[i])
def test_dict_simple():
tree = SignatureTree("a{ss}")
assert len(tree.types) == 1
child = tree.types[0]
assert child.signature == "a{ss}"
assert child.token == "a"
assert len(child.children) == 1
dict_child = child.children[0]
assert dict_child.token == "{"
assert dict_child.signature == "{ss}"
assert len(dict_child.children) == 2
assert_simple_type("s", dict_child.children[0])
assert_simple_type("s", dict_child.children[1])
def test_dict_of_structs():
tree = SignatureTree("a{s(ss)}")
assert len(tree.types) == 1
child = tree.types[0]
assert child.token == "a"
assert child.signature == "a{s(ss)}"
assert len(child.children) == 1
dict_child = child.children[0]
assert dict_child.token == "{"
assert dict_child.signature == "{s(ss)}"
assert len(dict_child.children) == 2
assert_simple_type("s", dict_child.children[0])
struct_child = dict_child.children[1]
assert struct_child.token == "("
assert struct_child.signature == "(ss)"
assert len(struct_child.children) == 2
for i in range(2):
assert_simple_type("s", struct_child.children[i])
def test_contains_type():
tree = SignatureTree("h")
assert signature_contains_type(tree, [0], "h")
assert not signature_contains_type(tree, [0], "u")
tree = SignatureTree("ah")
assert signature_contains_type(tree, [[0]], "h")
assert signature_contains_type(tree, [[0]], "a")
assert not signature_contains_type(tree, [[0]], "u")
tree = SignatureTree("av")
body = [
[
Variant("u", 0),
Variant("i", 0),
Variant("x", 0),
Variant("v", Variant("s", "hi")),
]
]
assert signature_contains_type(tree, body, "u")
assert signature_contains_type(tree, body, "x")
assert signature_contains_type(tree, body, "v")
assert signature_contains_type(tree, body, "s")
assert not signature_contains_type(tree, body, "o")
tree = SignatureTree("a{sv}")
body = {
"foo": Variant("h", 0),
"bar": Variant("i", 0),
"bat": Variant("x", 0),
"baz": Variant("v", Variant("o", "/hi")),
}
for expected in "hixvso":
assert signature_contains_type(tree, [body], expected)
assert not signature_contains_type(tree, [body], "b")
def test_invalid_variants():
tree = SignatureTree("a{sa{sv}}")
s_con = {
"type": "802-11-wireless",
"uuid": "1234",
"id": "SSID",
}
s_wifi = {
"ssid": "SSID",
"mode": "infrastructure",
"hidden": True,
}
s_wsec = {
"key-mgmt": "wpa-psk",
"auth-alg": "open",
"psk": "PASSWORD",
}
s_ip4 = {"method": "auto"}
s_ip6 = {"method": "auto"}
con = {
"connection": s_con,
"802-11-wireless": s_wifi,
"802-11-wireless-security": s_wsec,
"ipv4": s_ip4,
"ipv6": s_ip6,
}
with pytest.raises(SignatureBodyMismatchError):
tree.verify([con])
def test_variant_signature_type():
tree = SignatureTree("as")
var = Variant(tree.types[0], ["foo", "bar"])
assert var.type == tree.types[0]
assert var.value == ["foo", "bar"]
assert var.signature == "as"
with pytest.raises(SignatureBodyMismatchError):
Variant(tree.types[0], "wrong")
def test_struct_accepts_tuples_or_lists():
tree = SignatureTree("(s)")
tree.verify([("ok",)])
tree.verify([["ok"]])
dbus-fast-2.44.1/tests/test_tcp_address.py 0000664 0000000 0000000 00000004572 14773556132 0020565 0 ustar 00root root 0000000 0000000 import asyncio
import os
from contextlib import suppress
import pytest
from dbus_fast import Message
from dbus_fast._private.address import parse_address
from dbus_fast.aio import MessageBus
@pytest.mark.asyncio
async def test_tcp_connection_with_forwarding(event_loop):
closables = []
host = "127.0.0.1"
port = "55556"
addr_info = parse_address(os.environ.get("DBUS_SESSION_BUS_ADDRESS"))
assert addr_info
addr_zero_options = addr_info[0][1]
if "abstract" in addr_zero_options:
path = f"\0{addr_zero_options['abstract']}"
else:
path = addr_zero_options["path"]
tasks: list[asyncio.Task] = []
async def handle_connection(tcp_reader, tcp_writer):
unix_reader, unix_writer = await asyncio.open_unix_connection(path)
closables.append(tcp_writer)
closables.append(unix_writer)
async def handle_read():
while True:
data = await tcp_reader.read(1)
if not data:
break
unix_writer.write(data)
async def handle_write():
while True:
data = await unix_reader.read(1)
if not data:
break
tcp_writer.write(data)
tasks.append(asyncio.create_task(handle_read()))
tasks.append(asyncio.create_task(handle_write()))
server = await asyncio.start_server(handle_connection, host, port)
closables.append(server)
bus = await MessageBus(bus_address=f"tcp:host={host},port={port}").connect()
# basic tests to see if it works
result = await bus.call(
Message(
destination="org.freedesktop.DBus",
path="/org/freedesktop/DBus",
interface="org.freedesktop.DBus.Peer",
member="Ping",
)
)
assert result
intr = await bus.introspect("org.freedesktop.DBus", "/org/freedesktop/DBus")
obj = bus.get_proxy_object("org.freedesktop.DBus", "/org/freedesktop/DBus", intr)
iface = obj.get_interface("org.freedesktop.DBus.Peer")
await iface.call_ping()
assert bus._sock.getpeername()[0] == host
assert bus._sock.getsockname()[0] == host
assert bus._sock.gettimeout() == 0
assert bus._stream.closed is False
for c in closables:
c.close()
for t in tasks:
t.cancel()
with suppress(asyncio.CancelledError):
await t
dbus-fast-2.44.1/tests/test_unpack_variants.py 0000664 0000000 0000000 00000003217 14773556132 0021455 0 ustar 00root root 0000000 0000000 """Test unpack variants."""
import pytest
from dbus_fast.signature import Variant
from dbus_fast.unpack import unpack_variants
@pytest.mark.asyncio
async def test_dictionary():
"""Test variants unpacked from dictionary."""
assert unpack_variants(
{
"string": Variant("s", "test"),
"boolean": Variant("b", True),
"int": Variant("u", 1),
"object": Variant("o", "/test/path"),
"array": Variant("as", ["test", "value"]),
"tuple": Variant("(su)", ["test", 1]),
"bytes": Variant("ay", b"\0x62\0x75\0x66"),
}
) == {
"string": "test",
"boolean": True,
"int": 1,
"object": "/test/path",
"array": ["test", "value"],
"tuple": ["test", 1],
"bytes": b"\0x62\0x75\0x66",
}
@pytest.mark.asyncio
async def test_output_list():
"""Test variants unpacked from multiple outputs."""
assert unpack_variants(
[{"hello": Variant("s", "world")}, {"boolean": Variant("b", True)}, 1]
) == [{"hello": "world"}, {"boolean": True}, 1]
@pytest.mark.asyncio
async def test_nested_variants():
"""Test unpack variants handles nesting."""
assert unpack_variants(
{
"dict": Variant("a{sv}", {"hello": Variant("s", "world")}),
"array": Variant(
"aa{sv}",
[
{"hello": Variant("s", "world")},
{"bytes": Variant("ay", b"\0x62\0x75\0x66")},
],
),
}
) == {
"dict": {"hello": "world"},
"array": [{"hello": "world"}, {"bytes": b"\0x62\0x75\0x66"}],
}
dbus-fast-2.44.1/tests/test_validators.py 0000664 0000000 0000000 00000004424 14773556132 0020436 0 ustar 00root root 0000000 0000000 from dbus_fast import (
is_bus_name_valid,
is_interface_name_valid,
is_member_name_valid,
is_object_path_valid,
)
def test_object_path_validator():
valid_paths = ["/", "/foo", "/foo/bar", "/foo/bar/bat"]
invalid_paths = [
None,
"",
"foo",
"foo/bar",
"/foo/bar/",
"/$/foo/bar",
"/foo//bar",
"/foo$bar/baz",
]
for path in valid_paths:
assert is_object_path_valid(path), f'path should be valid: "{path}"'
for path in invalid_paths:
assert not is_object_path_valid(path), f'path should be invalid: "{path}"'
def test_bus_name_validator():
valid_names = [
"foo.bar",
"foo.bar.bat",
"_foo._bar",
"foo.bar69",
"foo.bar-69",
"org.mpris.MediaPlayer2.google-play-desktop-player",
]
invalid_names = [
None,
"",
"5foo.bar",
"foo.6bar",
".foo.bar",
"bar..baz",
"$foo.bar",
"foo$.ba$r",
]
for name in valid_names:
assert is_bus_name_valid(name), f'bus name should be valid: "{name}"'
for name in invalid_names:
assert not is_bus_name_valid(name), f'bus name should be invalid: "{name}"'
def test_interface_name_validator():
valid_names = ["foo.bar", "foo.bar.bat", "_foo._bar", "foo.bar69"]
invalid_names = [
None,
"",
"5foo.bar",
"foo.6bar",
".foo.bar",
"bar..baz",
"$foo.bar",
"foo$.ba$r",
"org.mpris.MediaPlayer2.google-play-desktop-player",
]
for name in valid_names:
assert is_interface_name_valid(name), (
f'interface name should be valid: "{name}"'
)
for name in invalid_names:
assert not is_interface_name_valid(name), (
f'interface name should be invalid: "{name}"'
)
def test_member_name_validator():
valid_members = ["foo", "FooBar", "Bat_Baz69", "foo-bar"]
invalid_members = [None, "", "foo.bar", "5foo", "foo$bar"]
for member in valid_members:
assert is_member_name_valid(member), f'member name should be valid: "{member}"'
for member in invalid_members:
assert not is_member_name_valid(member), (
f'member name should be invalid: "{member}"'
)
dbus-fast-2.44.1/tests/util.py 0000664 0000000 0000000 00000000532 14773556132 0016200 0 ustar 00root root 0000000 0000000 _has_gi = None
skip_reason_no_gi = "glib tests require python3-gi"
def check_gi_repository():
global _has_gi
if _has_gi is not None:
return _has_gi
try:
from gi.repository import GLib # noqa: F401
_has_gi = True
return _has_gi
except ImportError:
_has_gi = False
return _has_gi