From 08eaac8b612ef02320550bbd1477d54b5b28e56f Mon Sep 17 00:00:00 2001 From: Neucrack <8625829+Neutree@users.noreply.github.com> Date: Wed, 18 Dec 2024 03:39:30 +0000 Subject: [PATCH] Rebuild MaixCDK doc by commit refs/heads/main --- .github/workflows/build_linux.yml | 63 + .github/workflows/build_maixcam.yml | 69 + .../workflows/build_maixcam_pulish_doc.yml | 83 + .github/workflows/sync_gitee.yml | 48 + .github/workflows/trigger_wiki.yml | 45 + maixcdk/404.html | 220 + maixcdk/api/api.json | 36674 ++++++++++++++++ maixcdk/api/config.json | 4 + maixcdk/api/index.html | 458 + maixcdk/api/maix/app.html | 1259 + maixcdk/api/maix/audio.html | 870 + maixcdk/api/maix/camera.html | 1517 + maixcdk/api/maix/comm.html | 962 + maixcdk/api/maix/comm/modbus.html | 1710 + maixcdk/api/maix/display.html | 931 + maixcdk/api/maix/err.html | 532 + maixcdk/api/maix/example.html | 1238 + maixcdk/api/maix/ext_dev.html | 382 + maixcdk/api/maix/ext_dev/axp2101.html | 1374 + maixcdk/api/maix/ext_dev/bm8563.html | 567 + maixcdk/api/maix/ext_dev/fp5510.html | 439 + maixcdk/api/maix/ext_dev/imu.html | 789 + maixcdk/api/maix/ext_dev/mlx90640.html | 1160 + maixcdk/api/maix/ext_dev/pmu.html | 814 + maixcdk/api/maix/ext_dev/qmi8658.html | 415 + maixcdk/api/maix/ext_dev/tmc2209.html | 854 + maixcdk/api/maix/fs.html | 1302 + maixcdk/api/maix/http.html | 571 + maixcdk/api/maix/i18n.html | 697 + maixcdk/api/maix/image.html | 11557 +++++ maixcdk/api/maix/log.html | 539 + maixcdk/api/maix/modbus.html | 354 + maixcdk/api/maix/modbus/Slave.html | 370 + maixcdk/api/maix/network.html | 376 + maixcdk/api/maix/network/wifi.html | 1016 + maixcdk/api/maix/nn.html | 8785 ++++ maixcdk/api/maix/nn/F.html | 366 + maixcdk/api/maix/peripheral.html | 394 + maixcdk/api/maix/peripheral/adc.html | 543 + maixcdk/api/maix/peripheral/gpio.html | 641 + maixcdk/api/maix/peripheral/hid.html | 529 + maixcdk/api/maix/peripheral/i2c.html | 763 + maixcdk/api/maix/peripheral/key.html | 643 + maixcdk/api/maix/peripheral/pinmap.html | 419 + maixcdk/api/maix/peripheral/pwm.html | 575 + maixcdk/api/maix/peripheral/spi.html | 640 + maixcdk/api/maix/peripheral/timer.html | 375 + maixcdk/api/maix/peripheral/uart.html | 1077 + maixcdk/api/maix/peripheral/wdt.html | 461 + maixcdk/api/maix/protocol.html | 1601 + maixcdk/api/maix/rtmp.html | 901 + maixcdk/api/maix/rtsp.html | 952 + maixcdk/api/maix/sys.html | 811 + maixcdk/api/maix/tensor.html | 1146 + maixcdk/api/maix/thread.html | 461 + maixcdk/api/maix/time.html | 1549 + maixcdk/api/maix/touchscreen.html | 647 + maixcdk/api/maix/tracker.html | 863 + maixcdk/api/maix/util.html | 381 + maixcdk/api/maix/uvc.html | 459 + maixcdk/api/maix/video.html | 3915 ++ maixcdk/api/sidebar.yaml | 168 + maixcdk/config.json | 5 + maixcdk/doc/application/ai/yolo11.html | 286 + maixcdk/doc/application/index.html | 286 + maixcdk/doc/application/peripheral/uart.html | 278 + maixcdk/doc/application/ui/lvgl.html | 296 + maixcdk/doc/config.json | 4 + maixcdk/doc/convention/add_api.html | 342 + maixcdk/doc/convention/app.html | 386 + maixcdk/doc/convention/i18n.html | 385 + maixcdk/doc/convention/index.html | 374 + maixcdk/doc/convention/memcheck.html | 330 + maixcdk/doc/convention/nn.html | 336 + maixcdk/doc/convention/protocol.html | 1097 + maixcdk/doc/dev/docker/Dockerfile | 52 + maixcdk/doc/dev/docker/index.html | 354 + maixcdk/doc/dev/docker/requirements.txt | 6 + maixcdk/doc/dev/docker/switch_user.sh | 72 + .../doc/dev/docker/teedoc_requirements.txt | 12 + maixcdk/doc/dev/quick_start.html | 275 + maixcdk/doc/dev/vscode_debug.html | 305 + maixcdk/doc/faq.html | 356 + maixcdk/doc/index.html | 431 + maixcdk/doc/more.html | 285 + maixcdk/doc/sidebar.yaml | 36 + maixcdk/doc/zh/application/ai/yolo11.html | 286 + maixcdk/doc/zh/application/index.html | 286 + .../doc/zh/application/peripheral/uart.html | 278 + maixcdk/doc/zh/application/ui/lvgl.html | 295 + maixcdk/doc/zh/config.json | 4 + maixcdk/doc/zh/convention/add_api.html | 343 + maixcdk/doc/zh/convention/app.html | 385 + maixcdk/doc/zh/convention/i18n.html | 382 + maixcdk/doc/zh/convention/index.html | 387 + maixcdk/doc/zh/convention/memcheck.html | 334 + maixcdk/doc/zh/convention/nn.html | 340 + maixcdk/doc/zh/convention/protocol.html | 1123 + maixcdk/doc/zh/dev/docker/Dockerfile | 52 + maixcdk/doc/zh/dev/docker/index.html | 357 + maixcdk/doc/zh/dev/docker/requirements.txt | 6 + maixcdk/doc/zh/dev/docker/switch_user.sh | 72 + .../doc/zh/dev/docker/teedoc_requirements.txt | 12 + maixcdk/doc/zh/dev/quick_start.html | 275 + maixcdk/doc/zh/dev/vscode_debug.html | 305 + maixcdk/doc/zh/faq.html | 349 + maixcdk/doc/zh/index.html | 432 + maixcdk/doc/zh/more.html | 285 + maixcdk/doc/zh/no_translate.html | 301 + maixcdk/doc/zh/sidebar.yaml | 35 + maixcdk/favicon.ico | Bin 0 -> 3926 bytes maixcdk/index.html | 485 + maixcdk/robots.txt | 2 + maixcdk/sitemap.xml | 531 + maixcdk/static/css/custom.css | 12 + maixcdk/static/css/search/style.css | 330 + maixcdk/static/css/tailwind.css | 63 + maixcdk/static/css/theme_default/dark.css | 169 + maixcdk/static/css/theme_default/light.css | 1349 + .../static/css/theme_default/prism.min.css | 261 + maixcdk/static/css/theme_default/prism.min.js | 46 + .../static/css/theme_default/viewer.min.css | 9 + maixcdk/static/image/github-fill.svg | 1 + maixcdk/static/image/language.svg | 1 + maixcdk/static/image/maix_ecosystem.png | Bin 0 -> 130806 bytes maixcdk/static/image/maixcams.png | Bin 0 -> 281243 bytes maixcdk/static/image/maixhub.jpg | Bin 0 -> 259281 bytes maixcdk/static/image/search/cancel.svg | 1 + maixcdk/static/image/search/close.svg | 1 + maixcdk/static/image/search/search.svg | 1 + maixcdk/static/image/search/up.svg | 1 + maixcdk/static/image/theme_default/anchor.svg | 1 + maixcdk/static/image/theme_default/array.svg | 1 + maixcdk/static/image/theme_default/back.svg | 1 + .../static/image/theme_default/dark_mode.svg | 1 + .../static/image/theme_default/ext_link.svg | 1 + .../static/image/theme_default/indicator.svg | 1 + .../static/image/theme_default/light_mode.svg | 1 + maixcdk/static/image/theme_default/menu.svg | 1 + maixcdk/static/image/theme_default/print.svg | 1 + maixcdk/static/image/theme_default/to-top.svg | 1 + maixcdk/static/images/thumbs_up/up.svg | 1 + maixcdk/static/images/thumbs_up/upped.svg | 1 + maixcdk/static/js/custom.js | 0 maixcdk/static/js/search/search_main.js | 351 + maixcdk/static/js/theme_default/jquery.min.js | 2 + maixcdk/static/js/theme_default/main.js | 474 + maixcdk/static/js/theme_default/pre_main.js | 54 + maixcdk/static/js/theme_default/split.js | 3 + maixcdk/static/js/theme_default/tocbot.min.js | 1 + maixcdk/static/js/theme_default/viewer.min.js | 10 + maixcdk/static/js/thumbs_up/main.js | 215 + maixcdk/static/js/thumbs_up/style.css | 66 + maixcdk/static/search_index/index.json | 1 + maixcdk/static/search_index/index_0.json | 1 + maixcdk/static/search_index/index_1.json | 1 + maixcdk/static/search_index/index_2.json | 1 + maixcdk/static/search_index/index_3.json | 1 + maixcdk/static/search_index/index_4.json | 1 + .../mermaid.min.js | 3 + maixcdk/zh/config.json | 5 + maixcdk/zh/index.html | 485 + maixcdk/zh/no_translate.html | 184 + 163 files changed, 118971 insertions(+) create mode 100755 .github/workflows/build_linux.yml create mode 100755 .github/workflows/build_maixcam.yml create mode 100755 .github/workflows/build_maixcam_pulish_doc.yml create mode 100644 .github/workflows/sync_gitee.yml create mode 100755 .github/workflows/trigger_wiki.yml create mode 100644 maixcdk/404.html create mode 100644 maixcdk/api/api.json create mode 100644 maixcdk/api/config.json create mode 100644 maixcdk/api/index.html create mode 100644 maixcdk/api/maix/app.html create mode 100644 maixcdk/api/maix/audio.html create mode 100644 maixcdk/api/maix/camera.html create mode 100644 maixcdk/api/maix/comm.html create mode 100644 maixcdk/api/maix/comm/modbus.html create mode 100644 maixcdk/api/maix/display.html create mode 100644 maixcdk/api/maix/err.html create mode 100644 maixcdk/api/maix/example.html create mode 100644 maixcdk/api/maix/ext_dev.html create mode 100644 maixcdk/api/maix/ext_dev/axp2101.html create mode 100644 maixcdk/api/maix/ext_dev/bm8563.html create mode 100644 maixcdk/api/maix/ext_dev/fp5510.html create mode 100644 maixcdk/api/maix/ext_dev/imu.html create mode 100644 maixcdk/api/maix/ext_dev/mlx90640.html create mode 100644 maixcdk/api/maix/ext_dev/pmu.html create mode 100644 maixcdk/api/maix/ext_dev/qmi8658.html create mode 100644 maixcdk/api/maix/ext_dev/tmc2209.html create mode 100644 maixcdk/api/maix/fs.html create mode 100644 maixcdk/api/maix/http.html create mode 100644 maixcdk/api/maix/i18n.html create mode 100644 maixcdk/api/maix/image.html create mode 100644 maixcdk/api/maix/log.html create mode 100644 maixcdk/api/maix/modbus.html create mode 100644 maixcdk/api/maix/modbus/Slave.html create mode 100644 maixcdk/api/maix/network.html create mode 100644 maixcdk/api/maix/network/wifi.html create mode 100644 maixcdk/api/maix/nn.html create mode 100644 maixcdk/api/maix/nn/F.html create mode 100644 maixcdk/api/maix/peripheral.html create mode 100644 maixcdk/api/maix/peripheral/adc.html create mode 100644 maixcdk/api/maix/peripheral/gpio.html create mode 100644 maixcdk/api/maix/peripheral/hid.html create mode 100644 maixcdk/api/maix/peripheral/i2c.html create mode 100644 maixcdk/api/maix/peripheral/key.html create mode 100644 maixcdk/api/maix/peripheral/pinmap.html create mode 100644 maixcdk/api/maix/peripheral/pwm.html create mode 100644 maixcdk/api/maix/peripheral/spi.html create mode 100644 maixcdk/api/maix/peripheral/timer.html create mode 100644 maixcdk/api/maix/peripheral/uart.html create mode 100644 maixcdk/api/maix/peripheral/wdt.html create mode 100644 maixcdk/api/maix/protocol.html create mode 100644 maixcdk/api/maix/rtmp.html create mode 100644 maixcdk/api/maix/rtsp.html create mode 100644 maixcdk/api/maix/sys.html create mode 100644 maixcdk/api/maix/tensor.html create mode 100644 maixcdk/api/maix/thread.html create mode 100644 maixcdk/api/maix/time.html create mode 100644 maixcdk/api/maix/touchscreen.html create mode 100644 maixcdk/api/maix/tracker.html create mode 100644 maixcdk/api/maix/util.html create mode 100644 maixcdk/api/maix/uvc.html create mode 100644 maixcdk/api/maix/video.html create mode 100644 maixcdk/api/sidebar.yaml create mode 100644 maixcdk/config.json create mode 100644 maixcdk/doc/application/ai/yolo11.html create mode 100644 maixcdk/doc/application/index.html create mode 100644 maixcdk/doc/application/peripheral/uart.html create mode 100644 maixcdk/doc/application/ui/lvgl.html create mode 100644 maixcdk/doc/config.json create mode 100644 maixcdk/doc/convention/add_api.html create mode 100644 maixcdk/doc/convention/app.html create mode 100644 maixcdk/doc/convention/i18n.html create mode 100644 maixcdk/doc/convention/index.html create mode 100644 maixcdk/doc/convention/memcheck.html create mode 100644 maixcdk/doc/convention/nn.html create mode 100644 maixcdk/doc/convention/protocol.html create mode 100644 maixcdk/doc/dev/docker/Dockerfile create mode 100644 maixcdk/doc/dev/docker/index.html create mode 100644 maixcdk/doc/dev/docker/requirements.txt create mode 100644 maixcdk/doc/dev/docker/switch_user.sh create mode 100644 maixcdk/doc/dev/docker/teedoc_requirements.txt create mode 100644 maixcdk/doc/dev/quick_start.html create mode 100644 maixcdk/doc/dev/vscode_debug.html create mode 100644 maixcdk/doc/faq.html create mode 100644 maixcdk/doc/index.html create mode 100644 maixcdk/doc/more.html create mode 100644 maixcdk/doc/sidebar.yaml create mode 100644 maixcdk/doc/zh/application/ai/yolo11.html create mode 100644 maixcdk/doc/zh/application/index.html create mode 100644 maixcdk/doc/zh/application/peripheral/uart.html create mode 100644 maixcdk/doc/zh/application/ui/lvgl.html create mode 100644 maixcdk/doc/zh/config.json create mode 100644 maixcdk/doc/zh/convention/add_api.html create mode 100644 maixcdk/doc/zh/convention/app.html create mode 100644 maixcdk/doc/zh/convention/i18n.html create mode 100644 maixcdk/doc/zh/convention/index.html create mode 100644 maixcdk/doc/zh/convention/memcheck.html create mode 100644 maixcdk/doc/zh/convention/nn.html create mode 100644 maixcdk/doc/zh/convention/protocol.html create mode 100644 maixcdk/doc/zh/dev/docker/Dockerfile create mode 100644 maixcdk/doc/zh/dev/docker/index.html create mode 100644 maixcdk/doc/zh/dev/docker/requirements.txt create mode 100644 maixcdk/doc/zh/dev/docker/switch_user.sh create mode 100644 maixcdk/doc/zh/dev/docker/teedoc_requirements.txt create mode 100644 maixcdk/doc/zh/dev/quick_start.html create mode 100644 maixcdk/doc/zh/dev/vscode_debug.html create mode 100644 maixcdk/doc/zh/faq.html create mode 100644 maixcdk/doc/zh/index.html create mode 100644 maixcdk/doc/zh/more.html create mode 100644 maixcdk/doc/zh/no_translate.html create mode 100644 maixcdk/doc/zh/sidebar.yaml create mode 100644 maixcdk/favicon.ico create mode 100644 maixcdk/index.html create mode 100644 maixcdk/robots.txt create mode 100644 maixcdk/sitemap.xml create mode 100644 maixcdk/static/css/custom.css create mode 100644 maixcdk/static/css/search/style.css create mode 100644 maixcdk/static/css/tailwind.css create mode 100644 maixcdk/static/css/theme_default/dark.css create mode 100644 maixcdk/static/css/theme_default/light.css create mode 100644 maixcdk/static/css/theme_default/prism.min.css create mode 100644 maixcdk/static/css/theme_default/prism.min.js create mode 100644 maixcdk/static/css/theme_default/viewer.min.css create mode 100644 maixcdk/static/image/github-fill.svg create mode 100644 maixcdk/static/image/language.svg create mode 100644 maixcdk/static/image/maix_ecosystem.png create mode 100644 maixcdk/static/image/maixcams.png create mode 100644 maixcdk/static/image/maixhub.jpg create mode 100644 maixcdk/static/image/search/cancel.svg create mode 100644 maixcdk/static/image/search/close.svg create mode 100644 maixcdk/static/image/search/search.svg create mode 100644 maixcdk/static/image/search/up.svg create mode 100644 maixcdk/static/image/theme_default/anchor.svg create mode 100644 maixcdk/static/image/theme_default/array.svg create mode 100644 maixcdk/static/image/theme_default/back.svg create mode 100644 maixcdk/static/image/theme_default/dark_mode.svg create mode 100644 maixcdk/static/image/theme_default/ext_link.svg create mode 100644 maixcdk/static/image/theme_default/indicator.svg create mode 100644 maixcdk/static/image/theme_default/light_mode.svg create mode 100644 maixcdk/static/image/theme_default/menu.svg create mode 100644 maixcdk/static/image/theme_default/print.svg create mode 100644 maixcdk/static/image/theme_default/to-top.svg create mode 100644 maixcdk/static/images/thumbs_up/up.svg create mode 100644 maixcdk/static/images/thumbs_up/upped.svg create mode 100644 maixcdk/static/js/custom.js create mode 100644 maixcdk/static/js/search/search_main.js create mode 100644 maixcdk/static/js/theme_default/jquery.min.js create mode 100644 maixcdk/static/js/theme_default/main.js create mode 100644 maixcdk/static/js/theme_default/pre_main.js create mode 100644 maixcdk/static/js/theme_default/split.js create mode 100644 maixcdk/static/js/theme_default/tocbot.min.js create mode 100644 maixcdk/static/js/theme_default/viewer.min.js create mode 100644 maixcdk/static/js/thumbs_up/main.js create mode 100644 maixcdk/static/js/thumbs_up/style.css create mode 100644 maixcdk/static/search_index/index.json create mode 100644 maixcdk/static/search_index/index_0.json create mode 100644 maixcdk/static/search_index/index_1.json create mode 100644 maixcdk/static/search_index/index_2.json create mode 100644 maixcdk/static/search_index/index_3.json create mode 100644 maixcdk/static/search_index/index_4.json create mode 100644 maixcdk/teedoc-plugin-markdown-parser/mermaid.min.js create mode 100644 maixcdk/zh/config.json create mode 100644 maixcdk/zh/index.html create mode 100644 maixcdk/zh/no_translate.html diff --git a/.github/workflows/build_linux.yml b/.github/workflows/build_linux.yml new file mode 100755 index 00000000..72110019 --- /dev/null +++ b/.github/workflows/build_linux.yml @@ -0,0 +1,63 @@ +# This is a basic workflow to help you get started with Actions + +name: Build test for Linux + +# Controls when the action will run. +on: + # Triggers the workflow on push or pull request events but only for the main branch + push: + branches: [ main, dev ] + pull_request: + branches: [ main, dev ] + + # Allows you to run this workflow manually from the Actions tab + workflow_dispatch: + +# permissions: write-all + +# A workflow run is made up of one or more jobs that can run sequentially or in parallel +jobs: + # This workflow contains a single job called "build" + build: + # Only run job for specific repository + if: github.repository == 'sipeed/MaixCDK' + # The type of runner that the job will run on + runs-on: ubuntu-latest + strategy: + matrix: + python-version: ["3.11"] # MaixCAM use 3.11 + # Steps represent a sequence of tasks that will be executed as part of the job + steps: + # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 + with: + python-version: ${{ matrix.python-version }} + - name: Build MaixCDK Examples + run: | + echo "-- Check python version must python 3.11 --" + python3 -c 'import sys;print(sys.version);assert sys.version_info >= (3, 11);assert sys.version_info < (3, 12)' + python -c 'import sys;print(sys.version);assert sys.version_info >= (3, 11);assert sys.version_info < (3, 12)' + whereis python + whereis python3 + # export PATH=~/.local/bin/:$PATH + echo "--------------------------------" + echo "-- Install requirements first --" + echo "--------------------------------" + python -m pip install -r requirements.txt + echo "--------------------------------" + echo "-- Build Test for Linux now --" + echo "--------------------------------" + cd test/test_examples + chmod +x test_cases.sh + ./test_cases.sh linux 0 + + - name: Build doc + run: | + pip3 install teedoc + cd docs + echo "== install plugins ==" + teedoc install + echo "== start build ==" + teedoc build + echo "== build complete ==" diff --git a/.github/workflows/build_maixcam.yml b/.github/workflows/build_maixcam.yml new file mode 100755 index 00000000..c1913273 --- /dev/null +++ b/.github/workflows/build_maixcam.yml @@ -0,0 +1,69 @@ +# This is a basic workflow to help you get started with Actions + +name: Build test for MaixCAM + +# Controls when the action will run. +on: + # Triggers the workflow on push or pull request events but only for the main branch + push: + branches: [ main, dev ] + pull_request: + branches: [ main, dev ] + + # Allows you to run this workflow manually from the Actions tab + workflow_dispatch: + +# permissions: write-all + +# A workflow run is made up of one or more jobs that can run sequentially or in parallel +jobs: + # This workflow contains a single job called "build" + build: + # Only run job for specific repository + if: github.repository == 'sipeed/MaixCDK' + # The type of runner that the job will run on + runs-on: ubuntu-latest + strategy: + matrix: + python-version: ["3.11"] # MaixCAM use 3.11 + # Steps represent a sequence of tasks that will be executed as part of the job + steps: + # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 + with: + python-version: ${{ matrix.python-version }} + - name: Build MaixCDK Examples + run: | + echo "-- Check python version must python 3.11 --" + python3 -c 'import sys;print(sys.version);assert sys.version_info >= (3, 11);assert sys.version_info < (3, 12)' + python -c 'import sys;print(sys.version);assert sys.version_info >= (3, 11);assert sys.version_info < (3, 12)' + whereis python + whereis python3 + # export PATH=~/.local/bin/:$PATH + echo "--------------------------------" + echo "-- Install requirements first --" + echo "--------------------------------" + python -m pip install -r requirements.txt + echo "--------------------------------" + echo "-- Build Test for MaixCAM now --" + echo "--------------------------------" + cd test/test_examples + chmod +x test_cases.sh + ./test_cases.sh maixcam 0 + echo "------------------------------------" + echo "-- Build Projects for MaixCAM now --" + echo "------------------------------------" + cd ../../projects + chmod +x build_all.sh + ./build_all.sh + + - name: Build doc + run: | + pip3 install teedoc + cd docs + echo "== install plugins ==" + teedoc install + echo "== start build ==" + teedoc build + echo "== build complete ==" diff --git a/.github/workflows/build_maixcam_pulish_doc.yml b/.github/workflows/build_maixcam_pulish_doc.yml new file mode 100755 index 00000000..62e7210f --- /dev/null +++ b/.github/workflows/build_maixcam_pulish_doc.yml @@ -0,0 +1,83 @@ +# This is a basic workflow to help you get started with Actions + +name: Build and publish docs for MaixCAM + +# Controls when the action will run. +on: + # Triggers the workflow on push or pull request events but only for the main branch + push: + branches: [ main ] + # pull_request: + # branches: [ main ] + + # Allows you to run this workflow manually from the Actions tab + workflow_dispatch: + +permissions: write-all + +# A workflow run is made up of one or more jobs that can run sequentially or in parallel +jobs: + # This workflow contains a single job called "build" + build: + # Only run job for specific repository + if: github.repository == 'sipeed/MaixCDK' + # The type of runner that the job will run on + runs-on: ubuntu-latest + strategy: + matrix: + python-version: ["3.11"] # MaixCAM use 3.11 + # Steps represent a sequence of tasks that will be executed as part of the job + steps: + # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 + with: + python-version: ${{ matrix.python-version }} + - name: Build MaixCDK API doc + run: | + echo "-- Check python version must python 3.11 --" + python3 -c 'import sys;print(sys.version);assert sys.version_info >= (3, 11);assert sys.version_info < (3, 12)' + python -c 'import sys;print(sys.version);assert sys.version_info >= (3, 11);assert sys.version_info < (3, 12)' + whereis python + whereis python3 + # export PATH=~/.local/bin/:$PATH + echo "--------------------------------" + echo "-- Install requirements first --" + echo "--------------------------------" + python -m pip install -r requirements.txt + echo "--------------------------------" + echo "-- Build API DOC for MaixCAM now --" + echo "--------------------------------" + cd examples/nn_yolov5 + maixcdk distclean + maixcdk build -p maixcam + + - name: Push doc to github pages + run: | + pip3 install teedoc + cd docs + echo "== install plugins ==" + teedoc install + echo "== start build ==" + teedoc build + echo "== build complete ==" + remote_addr=`git remote get-url --push origin` + remote_addr=`echo $remote_addr| awk -F'://' '{print $2}'` + user_name=`git log -1 --pretty=format:'%an'` + user_email=`git log -1 --pretty=format:'%ae'` + echo "== checkout gh-pages branch ==" + cd out + cp -r ../../.github . + git config --global init.defaultBranch gh-pages + git init + git config user.name "${user_name}" + git config user.email ${user_email} + remote_addr="https://Neutree:${{ secrets.DISPATCH_PAT }}@${remote_addr}" + echo "-- user ${user_name}" + echo "-- remote addr: ${remote_addr}" + git remote add origin "${remote_addr}" + echo "== add web files ==" + git add -A + git commit -m "Rebuild MaixCDK doc by commit $GITHUB_REF" + git push origin HEAD:gh-pages --force + echo "== push complete ==" diff --git a/.github/workflows/sync_gitee.yml b/.github/workflows/sync_gitee.yml new file mode 100644 index 00000000..13998a99 --- /dev/null +++ b/.github/workflows/sync_gitee.yml @@ -0,0 +1,48 @@ +# This is a basic workflow to help you get started with Actions + +name: sync code to gitee + +# Controls when the action will run. Triggers the workflow on push or pull request +# events but only for the master branch +# on: +# push: +# branches: [ master ] +# pull_request: +# branches: [ master ] +on: + # Triggers the workflow on push or pull request events but only for the main branch + push: + branches: [ main ] + # pull_request: + # branches: [ main ] + + +# A workflow run is made up of one or more jobs that can run sequentially or in parallel +jobs: + # This workflow contains a single job called "build" + sync_gitee: + name: sync repo to gitee + # Only run job for specific repository + if: github.repository == 'sipeed/MaixCDK' + # The type of runner that the job will run on + runs-on: ubuntu-latest + + # Steps represent a sequence of tasks that will be executed as part of the job + steps: + # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it + - name: checkout code from github + uses: actions/checkout@v2 + + # Runs a set of commands using the runners shell + - name: sync shell cmd + run: | + GITEE_GIT_ADDR="git@gitee.com:Sipeed/MaixCDK.git" + git fetch --unshallow + SSHPATH="$HOME/.ssh" + rm -rf "$SSHPATH" + mkdir -p "$SSHPATH" + echo "${{ secrets.GITEE_SYNC_ACCESSS_KEY }}" > "$SSHPATH/id_rsa" + chmod 600 "$SSHPATH/id_rsa" + sudo sh -c "echo StrictHostKeyChecking no >>/etc/ssh/ssh_config" + git remote add upstream $GITEE_GIT_ADDR + git push upstream main:main --force diff --git a/.github/workflows/trigger_wiki.yml b/.github/workflows/trigger_wiki.yml new file mode 100755 index 00000000..a5888170 --- /dev/null +++ b/.github/workflows/trigger_wiki.yml @@ -0,0 +1,45 @@ +# This is a basic workflow to help you get started with Actions + +name: trigger wiki + +# Controls when the action will run. +on: + push: + branches: + - gh-pages + pull_request: + branches: + - gh-pages + + # Allows you to run this workflow manually from the Actions tab + workflow_dispatch: + +permissions: write-all + +# A workflow run is made up of one or more jobs that can run sequentially or in parallel +jobs: + # This workflow contains a single job called "build" + trigger_wiki: + name: trigger sipeed_wiki + # Only run job for specific repository + # if: github.repository == 'sipeed/MaixPy' + # The type of runner that the job will run on + runs-on: ubuntu-latest + # strategy: + # matrix: + # python-version: [3.8] + + # Steps represent a sequence of tasks that will be executed as part of the job + steps: + - name: trigger sipeed wiki request + uses: actions/github-script@v6 + with: + github-token: ${{ secrets.DISPATCH_PAT }} + script: | + const result = await github.rest.repos.createDispatchEvent({ + owner: 'sipeed', + repo: 'sipeed_wiki', + event_type: 'update_maixcdk_doc', + client_payload: {"key": "value"} + }) + console.log(result); diff --git a/maixcdk/404.html b/maixcdk/404.html new file mode 100644 index 00000000..d7658820 --- /dev/null +++ b/maixcdk/404.html @@ -0,0 +1,220 @@ + + + + + + + + + + + + + + + + + + + MaixCDK + + + + + + + + + + + +
+
+
+ + +

404 Page not found

+ + + + + +
+ Return to previous page Home +
+ + + +
+
+ + +
+ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixcdk/api/api.json b/maixcdk/api/api.json new file mode 100644 index 00000000..45ec76f2 --- /dev/null +++ b/maixcdk/api/api.json @@ -0,0 +1,36674 @@ +{ + "type": "top_module", + "members": { + "maix": { + "type": "module", + "doc": { + "breif": "MaixPy C/C++ API from MaixCDK" + }, + "members": { + "image": { + "type": "module", + "doc": { + "brief": "maix.image module, image related definition and functions", + "maixpy": "maix.image", + "py_doc": "maix.image module, image related definition and functions" + }, + "members": { + "QRCodeDetector": { + "type": "class", + "name": "QRCodeDetector", + "doc": { + "brief": "QRCodeDetector class", + "maixpy": "maix.image.QRCodeDetector", + "py_doc": "QRCodeDetector class" + }, + "members": { + "__init__": { + "type": "func", + "name": "QRCodeDetector", + "doc": { + "brief": "QRCodeDetector constructor.\\nUse npu to accelerate the speed of QR code scanning, note that this object will occupy npu resources", + "maixpy": "maix.image.QRCodeDetector.__init__", + "py_doc": "QRCodeDetector constructor.\nUse npu to accelerate the speed of QR code scanning, note that this object will occupy npu resources" + }, + "args": [], + "ret_type": null, + "static": false, + "def": "QRCodeDetector()" + }, + "detect": { + "type": "func", + "name": "detect", + "doc": { + "brief": "Finds all qrcodes in the image.", + "param": { + "img": "The image to find qrcodes.", + "roi": "The region of interest, input in the format of (x, y, w, h), x and y are the coordinates of the upper left corner, w and h are the width and height of roi.\ndefault is None, means whole image.", + "decoder_type": "Select the QR code decoding method. Choosing QRCODE_DECODER_TYPE_QUIRC allows for retrieving QR code version, ECC level, mask, data type, and other details,\nthough it may decode slower at lower resolutions. Opting for QRCODE_DECODER_TYPE_ZBAR enables faster decoding at lower resolutions but may slow down at higher resolutions,\nproviding only the QR code content and position information. default is QRCODE_DECODER_TYPE_ZBAR." + }, + "return": "Returns the qrcodes of the image", + "maixpy": "maix.image.QRCodeDetector.detect", + "py_doc": "Finds all qrcodes in the image.\n\nArgs:\n - img: The image to find qrcodes.\n - roi: The region of interest, input in the format of (x, y, w, h), x and y are the coordinates of the upper left corner, w and h are the width and height of roi.\ndefault is None, means whole image.\n - decoder_type: Select the QR code decoding method. Choosing QRCODE_DECODER_TYPE_QUIRC allows for retrieving QR code version, ECC level, mask, data type, and other details,\nthough it may decode slower at lower resolutions. Opting for QRCODE_DECODER_TYPE_ZBAR enables faster decoding at lower resolutions but may slow down at higher resolutions,\nproviding only the QR code content and position information. default is QRCODE_DECODER_TYPE_ZBAR.\n\n\nReturns: Returns the qrcodes of the image\n" + }, + "args": [ + [ + "image::Image *", + "img", + null + ], + [ + "std::vector", + "roi", + "std::vector()" + ], + [ + "image::QRCodeDecoderType", + "decoder_type", + "image::QRCodeDecoderType::QRCODE_DECODER_TYPE_ZBAR" + ] + ], + "ret_type": "std::vector", + "static": false, + "def": "std::vector detect(image::Image *img, std::vector roi = std::vector(), image::QRCodeDecoderType decoder_type = image::QRCodeDecoderType::QRCODE_DECODER_TYPE_ZBAR)" + } + }, + "def": "class QRCodeDetector" + }, + "Format": { + "type": "enum", + "name": "Format", + "doc": { + "brief": "Image formats", + "attention": "for MaixPy firmware developers, update this enum will also need to update the fmt_size and fmt_names too !!!", + "maixpy": "maix.image.Format", + "py_doc": "Image formats" + }, + "values": [ + [ + "FMT_RGB888", + "0", + "RGBRGB...RGB, R at the lowest address" + ], + [ + "FMT_BGR888", + "", + "BGRBGR...BGR, B at the lowest address" + ], + [ + "FMT_RGBA8888", + "", + "RGBARGBA...RGBA, R at the lowest address" + ], + [ + "FMT_BGRA8888", + "", + "BGRABGRA...BGRA, B at the lowest address" + ], + [ + "FMT_RGB565", + "", + "" + ], + [ + "FMT_BGR565", + "", + "" + ], + [ + "FMT_YUV422SP", + "", + "YYY...UVUVUV...UVUV" + ], + [ + "FMT_YUV422P", + "", + "YYY...UUU...VVV" + ], + [ + "FMT_YVU420SP", + "", + "YYY...VUVUVU...VUVU, NV21" + ], + [ + "FMT_YUV420SP", + "", + "YYY...UVUVUV...UVUV, NV12" + ], + [ + "FMT_YVU420P", + "", + "YYY...VVV...UUU" + ], + [ + "FMT_YUV420P", + "", + "YYY...UUU...VVV" + ], + [ + "FMT_GRAYSCALE", + "", + "" + ], + [ + "FMT_BGGR6", + "", + "6-bit Bayer format with a BGGR pattern." + ], + [ + "FMT_GBRG6", + "", + "6-bit Bayer format with a GBRG pattern." + ], + [ + "FMT_GRBG6", + "", + "6-bit Bayer format with a GRBG pattern." + ], + [ + "FMT_RGGB6", + "", + "6-bit Bayer format with a RGGB pattern." + ], + [ + "FMT_BGGR8", + "", + "8-bit Bayer format with a BGGR pattern." + ], + [ + "FMT_GBRG8", + "", + "8-bit Bayer format with a GBRG pattern." + ], + [ + "FMT_GRBG8", + "", + "8-bit Bayer format with a GRBG pattern." + ], + [ + "FMT_RGGB8", + "", + "8-bit Bayer format with a RGGB pattern." + ], + [ + "FMT_BGGR10", + "", + "10-bit Bayer format with a BGGR pattern." + ], + [ + "FMT_GBRG10", + "", + "10-bit Bayer format with a GBRG pattern." + ], + [ + "FMT_GRBG10", + "", + "10-bit Bayer format with a GRBG pattern." + ], + [ + "FMT_RGGB10", + "", + "10-bit Bayer format with a RGGB pattern." + ], + [ + "FMT_BGGR12", + "", + "12-bit Bayer format with a BGGR pattern." + ], + [ + "FMT_GBRG12", + "", + "12-bit Bayer format with a GBRG pattern." + ], + [ + "FMT_GRBG12", + "", + "12-bit Bayer format with a GRBG pattern." + ], + [ + "FMT_RGGB12", + "", + "12-bit Bayer format with a RGGB pattern." + ], + [ + "FMT_UNCOMPRESSED_MAX", + "", + "" + ], + [ + "FMT_COMPRESSED_MIN", + "", + "" + ], + [ + "FMT_JPEG", + "", + "" + ], + [ + "FMT_PNG", + "", + "" + ], + [ + "FMT_COMPRESSED_MAX", + "", + "" + ], + [ + "FMT_INVALID", + "0xFF", + "format not valid" + ] + ], + "def": "enum Format\n {\n FMT_RGB888 = 0, // RGBRGB...RGB, R at the lowest address\n FMT_BGR888, // BGRBGR...BGR, B at the lowest address\n FMT_RGBA8888, // RGBARGBA...RGBA, R at the lowest address\n FMT_BGRA8888, // BGRABGRA...BGRA, B at the lowest address\n FMT_RGB565,\n FMT_BGR565,\n FMT_YUV422SP, // YYY...UVUVUV...UVUV\n FMT_YUV422P, // YYY...UUU...VVV\n FMT_YVU420SP, // YYY...VUVUVU...VUVU, NV21\n FMT_YUV420SP, // YYY...UVUVUV...UVUV, NV12\n FMT_YVU420P, // YYY...VVV...UUU\n FMT_YUV420P, // YYY...UUU...VVV\n FMT_GRAYSCALE,\n FMT_BGGR6, // 6-bit Bayer format with a BGGR pattern.\n FMT_GBRG6, // 6-bit Bayer format with a GBRG pattern.\n FMT_GRBG6, // 6-bit Bayer format with a GRBG pattern.\n FMT_RGGB6, // 6-bit Bayer format with a RGGB pattern.\n FMT_BGGR8, // 8-bit Bayer format with a BGGR pattern.\n FMT_GBRG8, // 8-bit Bayer format with a GBRG pattern.\n FMT_GRBG8, // 8-bit Bayer format with a GRBG pattern.\n FMT_RGGB8, // 8-bit Bayer format with a RGGB pattern.\n FMT_BGGR10, // 10-bit Bayer format with a BGGR pattern.\n FMT_GBRG10, // 10-bit Bayer format with a GBRG pattern.\n FMT_GRBG10, // 10-bit Bayer format with a GRBG pattern.\n FMT_RGGB10, // 10-bit Bayer format with a RGGB pattern.\n FMT_BGGR12, // 12-bit Bayer format with a BGGR pattern.\n FMT_GBRG12, // 12-bit Bayer format with a GBRG pattern.\n FMT_GRBG12, // 12-bit Bayer format with a GRBG pattern.\n FMT_RGGB12, // 12-bit Bayer format with a RGGB pattern.\n FMT_UNCOMPRESSED_MAX,\n\n // compressed format below, not compressed should define upper\n FMT_COMPRESSED_MIN,\n FMT_JPEG,\n FMT_PNG,\n FMT_COMPRESSED_MAX,\n\n FMT_INVALID = 0xFF // format not valid\n }" + }, + "fmt_size": { + "type": "var", + "name": "", + "doc": { + "brief": "Image format size in bytes", + "attention": "It's a copy of this variable in MaixPy,\nso change it in C++ (e.g. update var in hello function) will not take effect the var inMaixPy.\nSo we add const for this var to avoid this mistake.", + "maixpy": "maix.image.fmt_size", + "py_doc": "Image format size in bytes" + }, + "value": "{\n 3,\n 3,\n 4,\n 4,\n 2,\n 2,\n 2,\n 2,\n 1.5,\n 1.5,\n 1.5,\n 1.5,\n 1, // grayscale\n 0.75, // 6-bit Bayer format\n 0.75, // 6-bit Bayer format\n 0.75, // 6-bit Bayer format\n 0.75, // 6-bit Bayer format\n 1, // 8-bit Bayer format\n 1, // 8-bit Bayer format\n 1, // 8-bit Bayer format\n 1, // 8-bit Bayer format\n 1.25, // 10-bit Bayer format\n 1.25, // 10-bit Bayer format\n 1.25, // 10-bit Bayer format\n 1.25, // 10-bit Bayer format\n 1.5, // 12-bit Bayer format\n 1.5, // 12-bit Bayer format\n 1.5, // 12-bit Bayer format\n 1.5, // 12-bit Bayer format\n 0, // uncompereed_max\n 0, // compressed_min\n 1, // jpeg\n 1, // png\n 0, // compressed_max\n 0 // invalid\n }", + "static": false, + "readonly": true, + "def": "const std::vector fmt_size = {\n 3,\n 3,\n 4,\n 4,\n 2,\n 2,\n 2,\n 2,\n 1.5,\n 1.5,\n 1.5,\n 1.5,\n 1, // grayscale\n 0.75, // 6-bit Bayer format\n 0.75, // 6-bit Bayer format\n 0.75, // 6-bit Bayer format\n 0.75, // 6-bit Bayer format\n 1, // 8-bit Bayer format\n 1, // 8-bit Bayer format\n 1, // 8-bit Bayer format\n 1, // 8-bit Bayer format\n 1.25, // 10-bit Bayer format\n 1.25, // 10-bit Bayer format\n 1.25, // 10-bit Bayer format\n 1.25, // 10-bit Bayer format\n 1.5, // 12-bit Bayer format\n 1.5, // 12-bit Bayer format\n 1.5, // 12-bit Bayer format\n 1.5, // 12-bit Bayer format\n 0, // uncompereed_max\n 0, // compressed_min\n 1, // jpeg\n 1, // png\n 0, // compressed_max\n 0 // invalid\n }" + }, + "fmt_names": { + "type": "var", + "name": "", + "doc": { + "brief": "Image format string", + "maixpy": "maix.image.fmt_names", + "py_doc": "Image format string" + }, + "value": "{\n \"RGB888\",\n \"BGR888\",\n \"RGBA8888\",\n \"BGRA8888\",\n \"RGB565\",\n \"BGR565\",\n \"YUV422SP\",\n \"YUV422P\",\n \"YVU420SP\",\n \"YUV420SP\",\n \"YVU420P\",\n \"YUV420P\",\n \"GRAYSCALE\",\n \"BGGR6\",\n \"GBRG6\",\n \"GRBG6\",\n \"RG6B6\",\n \"BGGR8\",\n \"GBRG8\",\n \"GRBG8\",\n \"RG6B8\",\n \"BGGR10\",\n \"GBRG10\",\n \"GRBG10\",\n \"RG6B10\",\n \"BGGR12\",\n \"GBRG12\",\n \"GRBG12\",\n \"RG6B12\",\n \"UNCOMPRESSED_MAX\",\n \"COMPRESSED_MIN\",\n \"JPEG\",\n \"PNG\",\n \"COMPRESSED_MAX\",\n \"INVALID\"\n }", + "static": false, + "readonly": true, + "def": "const std::vector fmt_names = {\n \"RGB888\",\n \"BGR888\",\n \"RGBA8888\",\n \"BGRA8888\",\n \"RGB565\",\n \"BGR565\",\n \"YUV422SP\",\n \"YUV422P\",\n \"YVU420SP\",\n \"YUV420SP\",\n \"YVU420P\",\n \"YUV420P\",\n \"GRAYSCALE\",\n \"BGGR6\",\n \"GBRG6\",\n \"GRBG6\",\n \"RG6B6\",\n \"BGGR8\",\n \"GBRG8\",\n \"GRBG8\",\n \"RG6B8\",\n \"BGGR10\",\n \"GBRG10\",\n \"GRBG10\",\n \"RG6B10\",\n \"BGGR12\",\n \"GBRG12\",\n \"GRBG12\",\n \"RG6B12\",\n \"UNCOMPRESSED_MAX\",\n \"COMPRESSED_MIN\",\n \"JPEG\",\n \"PNG\",\n \"COMPRESSED_MAX\",\n \"INVALID\"\n }" + }, + "Size": { + "type": "class", + "name": "Size", + "doc": { + "brief": "Image size type", + "maixpy": "maix.image.Size", + "py_doc": "Image size type" + }, + "members": { + "__init__": { + "type": "func", + "name": "Size", + "doc": { + "brief": "Construct a new Size object", + "param": { + "width": "image width", + "height": "image height" + }, + "maixpy": "maix.image.Size.__init__", + "py_doc": "Construct a new Size object\n\nArgs:\n - width: image width\n - height: image height\n" + }, + "args": [ + [ + "int", + "width", + "0" + ], + [ + "int", + "height", + "0" + ] + ], + "ret_type": null, + "static": false, + "def": "Size(int width = 0, int height = 0)" + }, + "width": { + "type": "func", + "name": "width", + "doc": { + "brief": "width of size", + "param": { + "width": "set new width, if not set, only return current width" + }, + "maixpy": "maix.image.Size.width", + "py_doc": "width of size\n\nArgs:\n - width: set new width, if not set, only return current width\n" + }, + "args": [ + [ + "int", + "width", + "-1" + ] + ], + "ret_type": "int", + "static": false, + "def": "int width(int width = -1)" + }, + "height": { + "type": "func", + "name": "height", + "doc": { + "brief": "height of size", + "param": { + "height": "set new height, if not set, only return current height" + }, + "maixpy": "maix.image.Size.height", + "py_doc": "height of size\n\nArgs:\n - height: set new height, if not set, only return current height\n" + }, + "args": [ + [ + "int", + "height", + "-1" + ] + ], + "ret_type": "int", + "static": false, + "def": "int height(int height = -1)" + }, + "[]": { + "type": "func", + "name": "operator[]", + "doc": { + "brief": "Subscript operator", + "param": { + "index": "0 for width, 1 for height" + }, + "return": "int& width or height", + "maixpy": "maix.image.Size.__getitem__", + "maixcdk": "maix.image.Size.[]", + "py_doc": "Subscript operator\n\nArgs:\n - index: 0 for width, 1 for height\n\n\nReturns: int& width or height\n" + }, + "args": [ + [ + "int", + "index", + null + ] + ], + "ret_type": "int&", + "static": false, + "def": "int &operator[](int index)" + }, + "__str__": { + "type": "func", + "name": "__str__", + "doc": { + "brief": "to string", + "maixpy": "maix.image.Size.__str__", + "py_doc": "to string" + }, + "args": [], + "ret_type": "std::string", + "static": false, + "def": "std::string __str__()" + } + }, + "def": "class Size" + }, + "Fit": { + "type": "enum", + "name": "Fit", + "doc": { + "brief": "Object fit method", + "maixpy": "maix.image.Fit", + "py_doc": "Object fit method" + }, + "values": [ + [ + "FIT_NONE", + "-1", + "no object fit, keep original" + ], + [ + "FIT_FILL", + "0", + "width to new width, height to new height, may be stretch" + ], + [ + "FIT_CONTAIN", + "", + "keep aspect ratio, fill blank area with black color" + ], + [ + "FIT_COVER", + "", + "keep aspect ratio, crop image to fit new size" + ], + [ + "FIT_MAX", + "", + "" + ] + ], + "def": "enum Fit\n {\n FIT_NONE = -1, // no object fit, keep original\n FIT_FILL = 0, // width to new width, height to new height, may be stretch\n FIT_CONTAIN, // keep aspect ratio, fill blank area with black color\n FIT_COVER, // keep aspect ratio, crop image to fit new size\n FIT_MAX\n }" + }, + "ResizeMethod": { + "type": "enum", + "name": "ResizeMethod", + "doc": { + "brief": "Resize method", + "maixpy": "maix.image.ResizeMethod", + "py_doc": "Resize method" + }, + "values": [ + [ + "NEAREST", + "0", + "" + ], + [ + "BILINEAR", + "", + "" + ], + [ + "BICUBIC", + "", + "" + ], + [ + "AREA", + "", + "" + ], + [ + "LANCZOS", + "", + "" + ], + [ + "HAMMING", + "", + "" + ], + [ + "RESIZE_METHOD_MAX", + "", + "" + ] + ], + "def": "enum ResizeMethod\n {\n NEAREST = 0,\n BILINEAR,\n BICUBIC,\n AREA,\n LANCZOS,\n HAMMING,\n RESIZE_METHOD_MAX\n }" + }, + "ApriltagFamilies": { + "type": "enum", + "name": "ApriltagFamilies", + "doc": { + "brief": "Family of apriltag", + "maixpy": "maix.image.ApriltagFamilies", + "py_doc": "Family of apriltag" + }, + "values": [ + [ + "TAG16H5", + "1", + "" + ], + [ + "TAG25H7", + "2", + "" + ], + [ + "TAG25H9", + "4", + "" + ], + [ + "TAG36H10", + "8", + "" + ], + [ + "TAG36H11", + "16", + "" + ], + [ + "ARTOOLKIT", + "32", + "" + ] + ], + "def": "enum ApriltagFamilies\n {\n TAG16H5 = 1,\n TAG25H7 = 2,\n TAG25H9 = 4,\n TAG36H10 = 8,\n TAG36H11 = 16,\n ARTOOLKIT = 32\n }" + }, + "TemplateMatch": { + "type": "enum", + "name": "TemplateMatch", + "doc": { + "brief": "Template match method", + "maixpy": "maix.image.TemplateMatch", + "py_doc": "Template match method" + }, + "values": [ + [ + "SEARCH_EX", + "", + "Exhaustive search" + ], + [ + "SEARCH_DS", + "", + "Diamond search" + ] + ], + "def": "enum TemplateMatch\n {\n SEARCH_EX, // Exhaustive search\n SEARCH_DS, // Diamond search\n }" + }, + "CornerDetector": { + "type": "enum", + "name": "CornerDetector", + "doc": { + "brief": "CornerDetector class", + "maixpy": "maix.image.CornerDetector", + "py_doc": "CornerDetector class" + }, + "values": [ + [ + "CORNER_FAST", + "", + "" + ], + [ + "CORNER_AGAST", + "", + "" + ] + ], + "def": "enum CornerDetector\n {\n CORNER_FAST,\n CORNER_AGAST\n }" + }, + "EdgeDetector": { + "type": "enum", + "name": "EdgeDetector", + "doc": { + "brief": "EdgeDetector class", + "maixpy": "maix.image.EdgeDetector", + "py_doc": "EdgeDetector class" + }, + "values": [ + [ + "EDGE_CANNY", + "", + "" + ], + [ + "EDGE_SIMPLE", + "", + "" + ] + ], + "def": "enum EdgeDetector\n {\n EDGE_CANNY,\n EDGE_SIMPLE,\n }" + }, + "FlipDir": { + "type": "enum", + "name": "class", + "doc": { + "brief": "FlipDir", + "maixpy": "maix.image.FlipDir", + "py_doc": "FlipDir" + }, + "values": [ + [ + "X", + "", + "" + ], + [ + "Y", + "", + "" + ], + [ + "XY", + "", + "" + ] + ], + "def": "enum class FlipDir\n {\n X,\n Y,\n XY\n }" + }, + "Line": { + "type": "class", + "name": "Line", + "doc": { + "brief": "Line class", + "maixpy": "maix.image.Line", + "py_doc": "Line class" + }, + "members": { + "__init__": { + "type": "func", + "name": "Line", + "doc": { + "brief": "Line constructor", + "param": { + "x1": "coordinate x1 of the straight line", + "y1": "coordinate y1 of the straight line", + "x2": "coordinate x2 of the straight line", + "y2": "coordinate y2 of the straight line", + "magnitude": "magnitude of the straight line after Hough transformation", + "theta": "angle of the straight line after Hough transformation", + "rho": "p-value of the straight line after Hough transformation" + }, + "maixpy": "maix.image.Line.__init__", + "py_doc": "Line constructor\n\nArgs:\n - x1: coordinate x1 of the straight line\n - y1: coordinate y1 of the straight line\n - x2: coordinate x2 of the straight line\n - y2: coordinate y2 of the straight line\n - magnitude: magnitude of the straight line after Hough transformation\n - theta: angle of the straight line after Hough transformation\n - rho: p-value of the straight line after Hough transformation\n" + }, + "args": [ + [ + "int", + "x1", + null + ], + [ + "int", + "y1", + null + ], + [ + "int", + "x2", + null + ], + [ + "int", + "y2", + null + ], + [ + "int", + "magnitude", + "0" + ], + [ + "int", + "theta", + "0" + ], + [ + "int", + "rho", + "0" + ] + ], + "ret_type": null, + "static": false, + "def": "Line(int x1, int y1, int x2, int y2, int magnitude = 0, int theta = 0, int rho = 0)" + }, + "__getitem__": { + "type": "func", + "name": "__getitem__", + "doc": { + "brief": "Subscript operator", + "param": { + "index": "[0] get x1 of line\n[1] get y1 of line\n[2] get x2 of line\n[3] get y2 of line\n[4] get length of line\n[5] get magnitude of the straight line after Hough transformation\n[6] get angle of the straight line after Hough transformation (0-179 degrees)\n[7] get p-value of the straight line after Hough transformation" + }, + "return": "int&", + "maixpy": "maix.image.Line.__getitem__", + "py_doc": "Subscript operator\n\nArgs:\n - index: [0] get x1 of line\n[1] get y1 of line\n[2] get x2 of line\n[3] get y2 of line\n[4] get length of line\n[5] get magnitude of the straight line after Hough transformation\n[6] get angle of the straight line after Hough transformation (0-179 degrees)\n[7] get p-value of the straight line after Hough transformation\n\n\nReturns: int&\n" + }, + "args": [ + [ + "int", + "index", + null + ] + ], + "ret_type": "int&", + "static": false, + "def": "int &__getitem__(int index)" + }, + "x1": { + "type": "func", + "name": "x1", + "doc": { + "brief": "get x1 of line", + "return": "return x1 of the line, type is int", + "maixpy": "maix.image.Line.x1", + "py_doc": "get x1 of line\n\nReturns: return x1 of the line, type is int\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int x1()" + }, + "y1": { + "type": "func", + "name": "y1", + "doc": { + "brief": "get y1 of line", + "return": "return y1 of the line, type is int", + "maixpy": "maix.image.Line.y1", + "py_doc": "get y1 of line\n\nReturns: return y1 of the line, type is int\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int y1()" + }, + "x2": { + "type": "func", + "name": "x2", + "doc": { + "brief": "get x2 of line", + "return": "return x2 of the line, type is int", + "maixpy": "maix.image.Line.x2", + "py_doc": "get x2 of line\n\nReturns: return x2 of the line, type is int\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int x2()" + }, + "y2": { + "type": "func", + "name": "y2", + "doc": { + "brief": "get y2 of line", + "return": "return y2 of the line, type is int", + "maixpy": "maix.image.Line.y2", + "py_doc": "get y2 of line\n\nReturns: return y2 of the line, type is int\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int y2()" + }, + "length": { + "type": "func", + "name": "length", + "doc": { + "brief": "get length of line", + "return": "return length of the line, type is int", + "maixpy": "maix.image.Line.length", + "py_doc": "get length of line\n\nReturns: return length of the line, type is int\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int length()" + }, + "magnitude": { + "type": "func", + "name": "magnitude", + "doc": { + "brief": "get magnitude of the straight line after Hough transformation", + "return": "return magnitude, type is int", + "maixpy": "maix.image.Line.magnitude", + "py_doc": "get magnitude of the straight line after Hough transformation\n\nReturns: return magnitude, type is int\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int magnitude()" + }, + "theta": { + "type": "func", + "name": "theta", + "doc": { + "brief": "get angle of the straight line after Hough transformation (0-179 degrees)", + "return": "return angle, type is int", + "maixpy": "maix.image.Line.theta", + "py_doc": "get angle of the straight line after Hough transformation (0-179 degrees)\n\nReturns: return angle, type is int\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int theta()" + }, + "rho": { + "type": "func", + "name": "rho", + "doc": { + "brief": "get p-value of the straight line after Hough transformation", + "return": "return p-value, type is int", + "maixpy": "maix.image.Line.rho", + "py_doc": "get p-value of the straight line after Hough transformation\n\nReturns: return p-value, type is int\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int rho()" + } + }, + "def": "class Line" + }, + "Rect": { + "type": "class", + "name": "Rect", + "doc": { + "brief": "Rect class", + "maixpy": "maix.image.Rect", + "py_doc": "Rect class" + }, + "members": { + "__init__": { + "type": "func", + "name": "Rect", + "doc": { + "brief": "Rect constructor", + "param": { + "corners": "corners of rect", + "x": "coordinate x of the straight line", + "y": "coordinate y of the straight line", + "w": "coordinate w of the straight line", + "h": "coordinate h of the straight line", + "magnitude": "magnitude of the straight line after Hough transformation" + }, + "maixpy": "maix.image.Rect.__init__", + "py_doc": "Rect constructor\n\nArgs:\n - corners: corners of rect\n - x: coordinate x of the straight line\n - y: coordinate y of the straight line\n - w: coordinate w of the straight line\n - h: coordinate h of the straight line\n - magnitude: magnitude of the straight line after Hough transformation\n" + }, + "args": [ + [ + "std::vector> &", + "corners", + null + ], + [ + "int", + "x", + null + ], + [ + "int", + "y", + null + ], + [ + "int", + "w", + null + ], + [ + "int", + "h", + null + ], + [ + "int", + "magnitude", + "0" + ] + ], + "ret_type": null, + "static": false, + "def": "Rect(std::vector> &corners, int x, int y, int w, int h, int magnitude = 0)" + }, + "__getitem__": { + "type": "func", + "name": "__getitem__", + "doc": { + "brief": "Subscript operator", + "param": { + "index": "[0] get x of rect\n[1] get y of rect\n[2] get w of rect\n[3] get h of rect\n[4] get magnitude of the straight line after Hough transformation" + }, + "return": "int&", + "maixpy": "maix.image.Rect.__getitem__", + "py_doc": "Subscript operator\n\nArgs:\n - index: [0] get x of rect\n[1] get y of rect\n[2] get w of rect\n[3] get h of rect\n[4] get magnitude of the straight line after Hough transformation\n\n\nReturns: int&\n" + }, + "args": [ + [ + "int", + "index", + null + ] + ], + "ret_type": "int&", + "static": false, + "def": "int &__getitem__(int index)" + }, + "corners": { + "type": "func", + "name": "corners", + "doc": { + "brief": "get corners of rect", + "return": "return the coordinate of the rect.", + "maixpy": "maix.image.Rect.corners", + "py_doc": "get corners of rect\n\nReturns: return the coordinate of the rect.\n" + }, + "args": [], + "ret_type": "std::vector>", + "static": false, + "def": "std::vector> corners()" + }, + "rect": { + "type": "func", + "name": "rect", + "doc": { + "brief": "get rectangle of rect", + "return": "return the rectangle of the rect. format is {x, y, w, h}, type is std::vector", + "maixpy": "maix.image.Rect.rect", + "py_doc": "get rectangle of rect\n\nReturns: return the rectangle of the rect. format is {x, y, w, h}, type is std::vector\n" + }, + "args": [], + "ret_type": "std::vector", + "static": false, + "def": "std::vector rect()" + }, + "x": { + "type": "func", + "name": "x", + "doc": { + "brief": "get x of rect", + "return": "return x of the rect, type is int", + "maixpy": "maix.image.Rect.x", + "py_doc": "get x of rect\n\nReturns: return x of the rect, type is int\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int x()" + }, + "y": { + "type": "func", + "name": "y", + "doc": { + "brief": "get y of rect", + "return": "return y of the rect, type is int", + "maixpy": "maix.image.Rect.y", + "py_doc": "get y of rect\n\nReturns: return y of the rect, type is int\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int y()" + }, + "w": { + "type": "func", + "name": "w", + "doc": { + "brief": "get w of rect", + "return": "return w of the rect, type is int", + "maixpy": "maix.image.Rect.w", + "py_doc": "get w of rect\n\nReturns: return w of the rect, type is int\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int w()" + }, + "h": { + "type": "func", + "name": "h", + "doc": { + "brief": "get h of rect", + "return": "return h of the rect, type is int", + "maixpy": "maix.image.Rect.h", + "py_doc": "get h of rect\n\nReturns: return h of the rect, type is int\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int h()" + }, + "magnitude": { + "type": "func", + "name": "magnitude", + "doc": { + "brief": "get magnitude of the straight line after Hough transformation", + "return": "return magnitude, type is int", + "maixpy": "maix.image.Rect.magnitude", + "py_doc": "get magnitude of the straight line after Hough transformation\n\nReturns: return magnitude, type is int\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int magnitude()" + } + }, + "def": "class Rect" + }, + "Circle": { + "type": "class", + "name": "Circle", + "doc": { + "brief": "circle class", + "maixpy": "maix.image.Circle", + "py_doc": "circle class" + }, + "members": { + "__init__": { + "type": "func", + "name": "Circle", + "doc": { + "brief": "Circle constructor", + "param": { + "x": "coordinate x of the circle", + "y": "coordinate y of the circle", + "r": "coordinate r of the circle", + "magnitude": "coordinate y2 of the straight line" + }, + "maixpy": "maix.image.Circle.__init__", + "py_doc": "Circle constructor\n\nArgs:\n - x: coordinate x of the circle\n - y: coordinate y of the circle\n - r: coordinate r of the circle\n - magnitude: coordinate y2 of the straight line\n" + }, + "args": [ + [ + "int", + "x", + null + ], + [ + "int", + "y", + null + ], + [ + "int", + "r", + null + ], + [ + "int", + "magnitude", + null + ] + ], + "ret_type": null, + "static": false, + "def": "Circle(int x, int y, int r, int magnitude)" + }, + "__getitem__": { + "type": "func", + "name": "__getitem__", + "doc": { + "brief": "Subscript operator", + "param": { + "index": "[0] get x of circle\n[1] get y of circle\n[2] get r of circle\n[3] get magnitude of the circle after Hough transformation" + }, + "return": "int&", + "maixpy": "maix.image.Circle.__getitem__", + "py_doc": "Subscript operator\n\nArgs:\n - index: [0] get x of circle\n[1] get y of circle\n[2] get r of circle\n[3] get magnitude of the circle after Hough transformation\n\n\nReturns: int&\n" + }, + "args": [ + [ + "int", + "index", + null + ] + ], + "ret_type": "int&", + "static": false, + "def": "int &__getitem__(int index)" + }, + "x": { + "type": "func", + "name": "x", + "doc": { + "brief": "get x of circle", + "return": "return x of the circle, type is int", + "maixpy": "maix.image.Circle.x", + "py_doc": "get x of circle\n\nReturns: return x of the circle, type is int\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int x()" + }, + "y": { + "type": "func", + "name": "y", + "doc": { + "brief": "get y of circle", + "return": "return y of the circle, type is int", + "maixpy": "maix.image.Circle.y", + "py_doc": "get y of circle\n\nReturns: return y of the circle, type is int\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int y()" + }, + "r": { + "type": "func", + "name": "r", + "doc": { + "brief": "get r of circle", + "return": "return r of the circle, type is int", + "maixpy": "maix.image.Circle.r", + "py_doc": "get r of circle\n\nReturns: return r of the circle, type is int\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int r()" + }, + "magnitude": { + "type": "func", + "name": "magnitude", + "doc": { + "brief": "get magnitude of the circle after Hough transformation", + "return": "return magnitude, type is int", + "maixpy": "maix.image.Circle.magnitude", + "py_doc": "get magnitude of the circle after Hough transformation\n\nReturns: return magnitude, type is int\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int magnitude()" + } + }, + "def": "class Circle" + }, + "Blob": { + "type": "class", + "name": "Blob", + "doc": { + "brief": "Blob class", + "maixpy": "maix.image.Blob", + "py_doc": "Blob class" + }, + "members": { + "__init__": { + "type": "func", + "name": "Blob", + "doc": { + "brief": "Blob constructor", + "param": { + "rect": "blob rect, type is std::vector", + "corners": "blob corners, type is std::vector>", + "mini_corners": "blob mini_corners, type is std::vector>", + "cx": "blob center x, type is float", + "cy": "blob center y, type is float", + "pixels": "blob pixels, type is int", + "rotation": "blob rotation, type is float", + "code": "blob code, type is int", + "count": "blob count, type is int", + "perimeter": "blob perimeter, type is int", + "roundness": "blob roundness, type is float", + "x_hist_bins": "blob x_hist_bins, type is std::vector", + "y_hist_bins": "blob y_hist_bins, type is std::vector" + }, + "maixpy": "maix.image.Blob.__init__", + "py_doc": "Blob constructor\n\nArgs:\n - rect: blob rect, type is std::vector\n - corners: blob corners, type is std::vector>\n - mini_corners: blob mini_corners, type is std::vector>\n - cx: blob center x, type is float\n - cy: blob center y, type is float\n - pixels: blob pixels, type is int\n - rotation: blob rotation, type is float\n - code: blob code, type is int\n - count: blob count, type is int\n - perimeter: blob perimeter, type is int\n - roundness: blob roundness, type is float\n - x_hist_bins: blob x_hist_bins, type is std::vector\n - y_hist_bins: blob y_hist_bins, type is std::vector\n" + }, + "args": [ + [ + "std::vector &", + "rect", + null + ], + [ + "std::vector> &", + "corners", + null + ], + [ + "std::vector> &", + "mini_corners", + null + ], + [ + "float", + "cx", + null + ], + [ + "float", + "cy", + null + ], + [ + "int", + "pixels", + null + ], + [ + "float", + "rotation", + null + ], + [ + "int", + "code", + null + ], + [ + "int", + "count", + null + ], + [ + "int", + "perimeter", + null + ], + [ + "float", + "roundness", + null + ], + [ + "std::vector &", + "x_hist_bins", + null + ], + [ + "std::vector &", + "y_hist_bins", + null + ] + ], + "ret_type": null, + "static": false, + "def": "Blob(std::vector &rect, std::vector> &corners, std::vector> &mini_corners,float cx, float cy, int pixels, float rotation, int code, int count, int perimeter, float roundness, std::vector &x_hist_bins, std::vector &y_hist_bins)" + }, + "__getitem__": { + "type": "func", + "name": "__getitem__", + "doc": { + "brief": "Subscript operator", + "param": { + "index": "[0] Returns the blob\u2019s bounding box x coordinate\n[1] Returns the blob\u2019s bounding box y coordinate\n[2] Returns the blob\u2019s bounding box w coordinate\n[3] Returns the blob\u2019s bounding box h coordinate\n[4] Returns the number of pixels that are part of this blob\n[5] Returns the centroid x position of the blob\n[6] Returns the centroid y position of the blob" + }, + "return": "int& width or height", + "maixpy": "maix.image.Blob.__getitem__", + "py_doc": "Subscript operator\n\nArgs:\n - index: [0] Returns the blob\u2019s bounding box x coordinate\n[1] Returns the blob\u2019s bounding box y coordinate\n[2] Returns the blob\u2019s bounding box w coordinate\n[3] Returns the blob\u2019s bounding box h coordinate\n[4] Returns the number of pixels that are part of this blob\n[5] Returns the centroid x position of the blob\n[6] Returns the centroid y position of the blob\n\n\nReturns: int& width or height\n" + }, + "args": [ + [ + "int", + "index", + null + ] + ], + "ret_type": "int&", + "static": false, + "def": "int &__getitem__(int index)" + }, + "corners": { + "type": "func", + "name": "corners", + "doc": { + "brief": "get blob corners", + "return": "Returns a list of 4 (x,y) tuples of the 4 corners of the object.\n(x0, y0)___________(x1, y1)\n| |\n| |\n| |\n|___________|\n(x3, y3) (x2, y2)\nnote: the order of corners may change", + "maixpy": "maix.image.Blob.corners", + "py_doc": "get blob corners\n\nReturns: Returns a list of 4 (x,y) tuples of the 4 corners of the object.\n(x0, y0)___________(x1, y1)\n| |\n| |\n| |\n|___________|\n(x3, y3) (x2, y2)\nnote: the order of corners may change\n" + }, + "args": [], + "ret_type": "std::vector>", + "static": false, + "def": "std::vector> corners()" + }, + "mini_corners": { + "type": "func", + "name": "mini_corners", + "doc": { + "brief": "get blob mini corners", + "return": "Returns a list of 4 (x,y) tuples of the 4 corners than bound the min area rectangle of the blob.\n(x0, y0)___________(x1, y1)\n| |\n| |\n| |\n|___________|\n(x3, y3) (x2, y2)\nnote: the order of corners may change", + "maixpy": "maix.image.Blob.mini_corners", + "py_doc": "get blob mini corners\n\nReturns: Returns a list of 4 (x,y) tuples of the 4 corners than bound the min area rectangle of the blob.\n(x0, y0)___________(x1, y1)\n| |\n| |\n| |\n|___________|\n(x3, y3) (x2, y2)\nnote: the order of corners may change\n" + }, + "args": [], + "ret_type": "std::vector>", + "static": false, + "def": "std::vector> mini_corners()" + }, + "rect": { + "type": "func", + "name": "rect", + "doc": { + "brief": "get blob rect", + "return": "Returns the center coordinates and width and height of the rectangle. format is (x, y, w, h)\nw\n(x, y) ___________\n| |\n| | h\n| |\n|___________|", + "maixpy": "maix.image.Blob.rect", + "py_doc": "get blob rect\n\nReturns: Returns the center coordinates and width and height of the rectangle. format is (x, y, w, h)\nw\n(x, y) ___________\n| |\n| | h\n| |\n|___________|\n" + }, + "args": [], + "ret_type": "std::vector", + "static": false, + "def": "std::vector rect()" + }, + "x": { + "type": "func", + "name": "x", + "doc": { + "brief": "get blob x of the upper left coordinate", + "return": "Returns the x coordinate of the upper left corner of the rectangle.", + "maixpy": "maix.image.Blob.x", + "py_doc": "get blob x of the upper left coordinate\n\nReturns: Returns the x coordinate of the upper left corner of the rectangle.\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int x()" + }, + "y": { + "type": "func", + "name": "y", + "doc": { + "brief": "get blob y of the upper left coordinate", + "return": "Returns the y coordinate of the upper left corner of the rectangle.", + "maixpy": "maix.image.Blob.y", + "py_doc": "get blob y of the upper left coordinate\n\nReturns: Returns the y coordinate of the upper left corner of the rectangle.\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int y()" + }, + "w": { + "type": "func", + "name": "w", + "doc": { + "brief": "get blob width", + "return": "Returns the blob\u2019s bounding box w coordinate", + "maixpy": "maix.image.Blob.w", + "py_doc": "get blob width\n\nReturns: Returns the blob\u2019s bounding box w coordinate\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int w()" + }, + "h": { + "type": "func", + "name": "h", + "doc": { + "brief": "get blob height", + "return": "Returns the blob\u2019s bounding box h coordinate", + "maixpy": "maix.image.Blob.h", + "py_doc": "get blob height\n\nReturns: Returns the blob\u2019s bounding box h coordinate\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int h()" + }, + "pixels": { + "type": "func", + "name": "pixels", + "doc": { + "brief": "get blob pixels", + "return": "Returns the number of pixels that are part of this blob.", + "maixpy": "maix.image.Blob.pixels", + "py_doc": "get blob pixels\n\nReturns: Returns the number of pixels that are part of this blob.\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int pixels()" + }, + "cx": { + "type": "func", + "name": "cx", + "doc": { + "brief": "get blob center x", + "return": "Returns the centroid x position of the blob", + "maixpy": "maix.image.Blob.cx", + "py_doc": "get blob center x\n\nReturns: Returns the centroid x position of the blob\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int cx()" + }, + "cy": { + "type": "func", + "name": "cy", + "doc": { + "brief": "get blob center y", + "return": "Returns the centroid y position of the blob", + "maixpy": "maix.image.Blob.cy", + "py_doc": "get blob center y\n\nReturns: Returns the centroid y position of the blob\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int cy()" + }, + "cxf": { + "type": "func", + "name": "cxf", + "doc": { + "brief": "get blob center x", + "return": "Returns the centroid x position of the blob", + "maixpy": "maix.image.Blob.cxf", + "py_doc": "get blob center x\n\nReturns: Returns the centroid x position of the blob\n" + }, + "args": [], + "ret_type": "float", + "static": false, + "def": "float cxf()" + }, + "cyf": { + "type": "func", + "name": "cyf", + "doc": { + "brief": "get blob center y", + "return": "Returns the centroid y position of the blob", + "maixpy": "maix.image.Blob.cyf", + "py_doc": "get blob center y\n\nReturns: Returns the centroid y position of the blob\n" + }, + "args": [], + "ret_type": "float", + "static": false, + "def": "float cyf()" + }, + "rotation": { + "type": "func", + "name": "rotation", + "doc": { + "brief": "get blob rotation", + "return": "Returns the rotation of the blob in radians (float). If the blob is like a pencil or pen this value will be unique for 0-180 degrees.", + "maixpy": "maix.image.Blob.rotation", + "py_doc": "get blob rotation\n\nReturns: Returns the rotation of the blob in radians (float). If the blob is like a pencil or pen this value will be unique for 0-180 degrees.\n" + }, + "args": [], + "ret_type": "float", + "static": false, + "def": "float rotation()" + }, + "rotation_rad": { + "type": "func", + "name": "rotation_rad", + "doc": { + "brief": "get blob rotation_rad", + "return": "Returns the rotation of the blob in radians", + "maixpy": "maix.image.Blob.rotation_rad", + "py_doc": "get blob rotation_rad\n\nReturns: Returns the rotation of the blob in radians\n" + }, + "args": [], + "ret_type": "float", + "static": false, + "def": "float rotation_rad()" + }, + "rotation_deg": { + "type": "func", + "name": "rotation_deg", + "doc": { + "brief": "get blob rotation_deg", + "return": "Returns the rotation of the blob in degrees.", + "maixpy": "maix.image.Blob.rotation_deg", + "py_doc": "get blob rotation_deg\n\nReturns: Returns the rotation of the blob in degrees.\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int rotation_deg()" + }, + "code": { + "type": "func", + "name": "code", + "doc": { + "brief": "get blob code", + "return": "Returns a 32-bit binary number with a bit set in it for each color threshold that\u2019s part of this blob", + "maixpy": "maix.image.Blob.code", + "py_doc": "get blob code\n\nReturns: Returns a 32-bit binary number with a bit set in it for each color threshold that\u2019s part of this blob\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int code()" + }, + "count": { + "type": "func", + "name": "count", + "doc": { + "brief": "get blob count", + "return": "Returns the number of blobs merged into this blob.", + "maixpy": "maix.image.Blob.count", + "py_doc": "get blob count\n\nReturns: Returns the number of blobs merged into this blob.\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int count()" + }, + "perimeter": { + "type": "func", + "name": "perimeter", + "doc": { + "brief": "get blob merge_cnt", + "return": "Returns the number of pixels on this blob\u2019s perimeter.", + "maixpy": "maix.image.Blob.perimeter", + "py_doc": "get blob merge_cnt\n\nReturns: Returns the number of pixels on this blob\u2019s perimeter.\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int perimeter()" + }, + "roundness": { + "type": "func", + "name": "roundness", + "doc": { + "brief": "get blob roundness", + "return": "Returns a value between 0 and 1 representing how round the object is", + "maixpy": "maix.image.Blob.roundness", + "py_doc": "get blob roundness\n\nReturns: Returns a value between 0 and 1 representing how round the object is\n" + }, + "args": [], + "ret_type": "float", + "static": false, + "def": "float roundness()" + }, + "elongation": { + "type": "func", + "name": "elongation", + "doc": { + "brief": "get blob elongation", + "returnReturns": "a value between 0 and 1 representing how long (not round) the object is", + "maixpy": "maix.image.Blob.elongation", + "py_doc": "get blob elongation" + }, + "args": [], + "ret_type": "float", + "static": false, + "def": "float elongation()" + }, + "area": { + "type": "func", + "name": "area", + "doc": { + "brief": "get blob area", + "return": "Returns the area of the bounding box around the blob", + "maixpy": "maix.image.Blob.area", + "py_doc": "get blob area\n\nReturns: Returns the area of the bounding box around the blob\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int area()" + }, + "density": { + "type": "func", + "name": "density", + "doc": { + "brief": "get blob density", + "return": "Returns the density ratio of the blob", + "maixpy": "maix.image.Blob.density", + "py_doc": "get blob density\n\nReturns: Returns the density ratio of the blob\n" + }, + "args": [], + "ret_type": "float", + "static": false, + "def": "float density()" + }, + "extent": { + "type": "func", + "name": "extent", + "doc": { + "brief": "Alias for blob.density()", + "return": "Returns the density ratio of the blob", + "maixpy": "maix.image.Blob.extent", + "py_doc": "Alias for blob.density()\n\nReturns: Returns the density ratio of the blob\n" + }, + "args": [], + "ret_type": "float", + "static": false, + "def": "float extent()" + }, + "compactness": { + "type": "func", + "name": "compactness", + "doc": { + "brief": "get blob compactness", + "return": "Returns the compactness ratio of the blob", + "maixpy": "maix.image.Blob.compactness", + "py_doc": "get blob compactness\n\nReturns: Returns the compactness ratio of the blob\n" + }, + "args": [], + "ret_type": "float", + "static": false, + "def": "float compactness()" + }, + "solidity": { + "type": "func", + "name": "solidity", + "doc": { + "brief": "get blob solidity", + "return": "Returns the solidity ratio of the blob", + "maixpy": "maix.image.Blob.solidity", + "py_doc": "get blob solidity\n\nReturns: Returns the solidity ratio of the blob\n" + }, + "args": [], + "ret_type": "float", + "static": false, + "def": "float solidity()" + }, + "convexity": { + "type": "func", + "name": "convexity", + "doc": { + "brief": "get blob convexity", + "return": "Returns a value between 0 and 1 representing how convex the object is", + "maixpy": "maix.image.Blob.convexity", + "py_doc": "get blob convexity\n\nReturns: Returns a value between 0 and 1 representing how convex the object is\n" + }, + "args": [], + "ret_type": "float", + "static": false, + "def": "float convexity()" + }, + "x_hist_bins": { + "type": "func", + "name": "x_hist_bins", + "doc": { + "brief": "get blob x_hist_bins", + "return": "Returns the x_hist_bins of the blob", + "maixpy": "maix.image.Blob.x_hist_bins", + "py_doc": "get blob x_hist_bins\n\nReturns: Returns the x_hist_bins of the blob\n" + }, + "args": [], + "ret_type": "std::vector", + "static": false, + "def": "std::vector x_hist_bins()" + }, + "y_hist_bins": { + "type": "func", + "name": "y_hist_bins", + "doc": { + "brief": "get blob y_hist_bins", + "return": "Returns the y_hist_bins of the blob", + "maixpy": "maix.image.Blob.y_hist_bins", + "py_doc": "get blob y_hist_bins\n\nReturns: Returns the y_hist_bins of the blob\n" + }, + "args": [], + "ret_type": "std::vector", + "static": false, + "def": "std::vector y_hist_bins()" + }, + "major_axis_line": { + "type": "func", + "name": "major_axis_line", + "doc": { + "brief": "get blob major_axis_line", + "return": "Returns a line tuple (x1, y1, x2, y2) of the minor axis of the blob.", + "maixpy": "maix.image.Blob.major_axis_line", + "py_doc": "get blob major_axis_line\n\nReturns: Returns a line tuple (x1, y1, x2, y2) of the minor axis of the blob.\n" + }, + "args": [], + "ret_type": "std::vector", + "static": false, + "def": "std::vector major_axis_line()" + }, + "minor_axis_line": { + "type": "func", + "name": "minor_axis_line", + "doc": { + "brief": "get blob minor_axis_line", + "return": "Returns a line tuple (x1, y1, x2, y2) of the minor axis of the blob.", + "maixpy": "maix.image.Blob.minor_axis_line", + "py_doc": "get blob minor_axis_line\n\nReturns: Returns a line tuple (x1, y1, x2, y2) of the minor axis of the blob.\n" + }, + "args": [], + "ret_type": "std::vector", + "static": false, + "def": "std::vector minor_axis_line()" + }, + "enclosing_circle": { + "type": "func", + "name": "enclosing_circle", + "doc": { + "brief": "get blob enclosing_circle", + "return": "Returns a circle tuple (x, y, r) of the circle that encloses the min area rectangle of a blob.", + "maixpy": "maix.image.Blob.enclosing_circle", + "py_doc": "get blob enclosing_circle\n\nReturns: Returns a circle tuple (x, y, r) of the circle that encloses the min area rectangle of a blob.\n" + }, + "args": [], + "ret_type": "std::vector", + "static": false, + "def": "std::vector enclosing_circle()" + }, + "enclosed_ellipse": { + "type": "func", + "name": "enclosed_ellipse", + "doc": { + "brief": "get blob enclosed_ellipse", + "return": "Returns an ellipse tuple (x, y, rx, ry, rotation) of the ellipse that fits inside of the min area rectangle of a blob.", + "maixpy": "maix.image.Blob.enclosed_ellipse", + "py_doc": "get blob enclosed_ellipse\n\nReturns: Returns an ellipse tuple (x, y, rx, ry, rotation) of the ellipse that fits inside of the min area rectangle of a blob.\n" + }, + "args": [], + "ret_type": "std::vector", + "static": false, + "def": "std::vector enclosed_ellipse()" + } + }, + "def": "class Blob" + }, + "QRCodeDecoderType": { + "type": "enum", + "name": "class", + "doc": { + "brief": "QRCode decode type class", + "maixpy": "maix.image.QRCodeDecoderType", + "py_doc": "QRCode decode type class" + }, + "values": [ + [ + "QRCODE_DECODER_TYPE_ZBAR", + "", + "" + ], + [ + "QRCODE_DECODER_TYPE_QUIRC", + "", + "" + ] + ], + "def": "enum class QRCodeDecoderType {\n QRCODE_DECODER_TYPE_ZBAR,\n QRCODE_DECODER_TYPE_QUIRC\n }" + }, + "QRCode": { + "type": "class", + "name": "QRCode", + "doc": { + "brief": "QRCode class", + "maixpy": "maix.image.QRCode", + "py_doc": "QRCode class" + }, + "members": { + "__init__": { + "type": "func", + "name": "QRCode", + "doc": { + "brief": "QRCode constructor", + "param": { + "rect": "rect of corners, type is std::vector", + "corners": "corners of QRCode", + "payload": "payload of the QRCode", + "version": "version of the QRCode", + "ecc_level": "ecc_level of the QRCode", + "mask": "mask of the QRCode", + "data_type": "data_type of the QRCode", + "eci": "eci of the QRCode" + }, + "maixpy": "maix.image.QRCode.__init__", + "py_doc": "QRCode constructor\n\nArgs:\n - rect: rect of corners, type is std::vector\n - corners: corners of QRCode\n - payload: payload of the QRCode\n - version: version of the QRCode\n - ecc_level: ecc_level of the QRCode\n - mask: mask of the QRCode\n - data_type: data_type of the QRCode\n - eci: eci of the QRCode\n" + }, + "args": [ + [ + "std::vector &", + "rect", + null + ], + [ + "std::vector> &", + "corners", + null + ], + [ + "std::string &", + "payload", + null + ], + [ + "int", + "version", + null + ], + [ + "int", + "ecc_level", + null + ], + [ + "int", + "mask", + null + ], + [ + "int", + "data_type", + null + ], + [ + "int", + "eci", + null + ] + ], + "ret_type": null, + "static": false, + "def": "QRCode(std::vector &rect, std::vector> &corners, std::string &payload, int version, int ecc_level, int mask, int data_type, int eci)" + }, + "__getitem__": { + "type": "func", + "name": "__getitem__", + "doc": { + "brief": "Subscript operator", + "param": { + "index": "[0] Returns the qrcode\u2019s bounding box x coordinate\n[1] Returns the qrcode\u2019s bounding box y coordinate\n[2] Returns the qrcode\u2019s bounding box w coordinate\n[3] Returns the qrcode\u2019s bounding box h coordinate\n[4] Not support this index, try to use payload() method\n[5] Returns the version of qrcode\n[6] Returns the error correction level of qrcode\n[7] Returns the mask of qrcode\n[8] Returns the datatype of qrcode\n[9] Returns the eci of qrcode" + }, + "return": "int&", + "maixpy": "maix.image.QRCode.__getitem__", + "py_doc": "Subscript operator\n\nArgs:\n - index: [0] Returns the qrcode\u2019s bounding box x coordinate\n[1] Returns the qrcode\u2019s bounding box y coordinate\n[2] Returns the qrcode\u2019s bounding box w coordinate\n[3] Returns the qrcode\u2019s bounding box h coordinate\n[4] Not support this index, try to use payload() method\n[5] Returns the version of qrcode\n[6] Returns the error correction level of qrcode\n[7] Returns the mask of qrcode\n[8] Returns the datatype of qrcode\n[9] Returns the eci of qrcode\n\n\nReturns: int&\n" + }, + "args": [ + [ + "int", + "index", + null + ] + ], + "ret_type": "int&", + "static": false, + "def": "int &__getitem__(int index)" + }, + "corners": { + "type": "func", + "name": "corners", + "doc": { + "brief": "get coordinate of QRCode", + "return": "return the coordinate of the QRCode.", + "maixpy": "maix.image.QRCode.corners", + "py_doc": "get coordinate of QRCode\n\nReturns: return the coordinate of the QRCode.\n" + }, + "args": [], + "ret_type": "std::vector>", + "static": false, + "def": "std::vector> corners()" + }, + "rect": { + "type": "func", + "name": "rect", + "doc": { + "brief": "get rectangle of QRCode", + "return": "return the rectangle of the QRCode. format is {x, y, w, h}, type is std::vector", + "maixpy": "maix.image.QRCode.rect", + "py_doc": "get rectangle of QRCode\n\nReturns: return the rectangle of the QRCode. format is {x, y, w, h}, type is std::vector\n" + }, + "args": [], + "ret_type": "std::vector", + "static": false, + "def": "std::vector rect()" + }, + "x": { + "type": "func", + "name": "x", + "doc": { + "brief": "get x of QRCode", + "return": "return x of the QRCode, type is int", + "maixpy": "maix.image.QRCode.x", + "py_doc": "get x of QRCode\n\nReturns: return x of the QRCode, type is int\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int x()" + }, + "y": { + "type": "func", + "name": "y", + "doc": { + "brief": "get y of QRCode", + "return": "return y of the QRCode, type is int", + "maixpy": "maix.image.QRCode.y", + "py_doc": "get y of QRCode\n\nReturns: return y of the QRCode, type is int\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int y()" + }, + "w": { + "type": "func", + "name": "w", + "doc": { + "brief": "get w of QRCode", + "return": "return w of the QRCode, type is int", + "maixpy": "maix.image.QRCode.w", + "py_doc": "get w of QRCode\n\nReturns: return w of the QRCode, type is int\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int w()" + }, + "h": { + "type": "func", + "name": "h", + "doc": { + "brief": "get h of QRCode", + "return": "return h of the QRCode, type is int", + "maixpy": "maix.image.QRCode.h", + "py_doc": "get h of QRCode\n\nReturns: return h of the QRCode, type is int\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int h()" + }, + "payload": { + "type": "func", + "name": "payload", + "doc": { + "brief": "get QRCode payload", + "return": "return area of the QRCode", + "maixpy": "maix.image.QRCode.payload", + "py_doc": "get QRCode payload\n\nReturns: return area of the QRCode\n" + }, + "args": [], + "ret_type": "std::string", + "static": false, + "def": "std::string payload()" + }, + "version": { + "type": "func", + "name": "version", + "doc": { + "brief": "get QRCode version", + "return": "return version of the QRCode", + "maixpy": "maix.image.QRCode.version", + "py_doc": "get QRCode version\n\nReturns: return version of the QRCode\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int version()" + }, + "ecc_level": { + "type": "func", + "name": "ecc_level", + "doc": { + "brief": "get QRCode error correction level", + "return": "return error correction level of the QRCode", + "maixpy": "maix.image.QRCode.ecc_level", + "py_doc": "get QRCode error correction level\n\nReturns: return error correction level of the QRCode\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int ecc_level()" + }, + "mask": { + "type": "func", + "name": "mask", + "doc": { + "brief": "get QRCode mask", + "return": "return mask of the QRCode", + "maixpy": "maix.image.QRCode.mask", + "py_doc": "get QRCode mask\n\nReturns: return mask of the QRCode\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int mask()" + }, + "data_type": { + "type": "func", + "name": "data_type", + "doc": { + "brief": "get QRCode dataType", + "return": "return mask of the QRCode", + "maixpy": "maix.image.QRCode.data_type", + "py_doc": "get QRCode dataType\n\nReturns: return mask of the QRCode\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int data_type()" + }, + "eci": { + "type": "func", + "name": "eci", + "doc": { + "brief": "get QRCode eci", + "return": "return data of the QRCode", + "maixpy": "maix.image.QRCode.eci", + "py_doc": "get QRCode eci\n\nReturns: return data of the QRCode\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int eci()" + }, + "is_numeric": { + "type": "func", + "name": "is_numeric", + "doc": { + "brief": "check QRCode is numeric", + "return": "return true if the result type of the QRCode is numeric", + "maixpy": "maix.image.QRCode.is_numeric", + "py_doc": "check QRCode is numeric\n\nReturns: return true if the result type of the QRCode is numeric\n" + }, + "args": [], + "ret_type": "bool", + "static": false, + "def": "bool is_numeric()" + }, + "is_alphanumeric": { + "type": "func", + "name": "is_alphanumeric", + "doc": { + "brief": "check QRCode is alphanumeric", + "return": "return true if the result type of the QRCode is alphanumeric", + "maixpy": "maix.image.QRCode.is_alphanumeric", + "py_doc": "check QRCode is alphanumeric\n\nReturns: return true if the result type of the QRCode is alphanumeric\n" + }, + "args": [], + "ret_type": "bool", + "static": false, + "def": "bool is_alphanumeric()" + }, + "is_binary": { + "type": "func", + "name": "is_binary", + "doc": { + "brief": "check QRCode is binary", + "return": "return true if the result type of the QRCode is binary", + "maixpy": "maix.image.QRCode.is_binary", + "py_doc": "check QRCode is binary\n\nReturns: return true if the result type of the QRCode is binary\n" + }, + "args": [], + "ret_type": "bool", + "static": false, + "def": "bool is_binary()" + }, + "is_kanji": { + "type": "func", + "name": "is_kanji", + "doc": { + "brief": "check QRCode is kanji", + "return": "return true if the result type of the QRCode is kanji", + "maixpy": "maix.image.QRCode.is_kanji", + "py_doc": "check QRCode is kanji\n\nReturns: return true if the result type of the QRCode is kanji\n" + }, + "args": [], + "ret_type": "bool", + "static": false, + "def": "bool is_kanji()" + } + }, + "def": "class QRCode" + }, + "AprilTag": { + "type": "class", + "name": "AprilTag", + "doc": { + "brief": "AprilTag class", + "maixpy": "maix.image.AprilTag", + "py_doc": "AprilTag class" + }, + "members": { + "__init__": { + "type": "func", + "name": "AprilTag", + "doc": { + "brief": "AprilTag constructor", + "param": { + "rect": "Inlucdes the top-left corner and the width and height of the rectangle. format is {x, y, w, h}, type is std::vector", + "corners": "Includes the four corners of the rectangle. format is {{x0, y0}, {x1, y1}, {x2, y2}, {x3, y3}}, type is std::vector>", + "id": "The id of the AprilTag", + "famliy": "The family of the AprilTag", + "centroid_x": "The x coordinate of the center of the AprilTag", + "centroid_y": "The y coordinate of the center of the AprilTag", + "rotation": "The rotation of the AprilTag", + "decision_margin": "The decision_margin of the AprilTag", + "hamming": "The hamming of the AprilTag", + "goodness": "The goodness of the AprilTag", + "x_translation": "The x_translation of the AprilTag", + "y_translation": "The y_translation of the AprilTag", + "z_translation": "The z_translation of the AprilTag", + "x_rotation": "The x_rotation of the AprilTag", + "y_rotation": "The y_rotation of the AprilTag", + "z_rotation": "The z_rotation of the AprilTag" + }, + "maixpy": "maix.image.AprilTag.__init__", + "py_doc": "AprilTag constructor\n\nArgs:\n - rect: Inlucdes the top-left corner and the width and height of the rectangle. format is {x, y, w, h}, type is std::vector\n - corners: Includes the four corners of the rectangle. format is {{x0, y0}, {x1, y1}, {x2, y2}, {x3, y3}}, type is std::vector>\n - id: The id of the AprilTag\n - famliy: The family of the AprilTag\n - centroid_x: The x coordinate of the center of the AprilTag\n - centroid_y: The y coordinate of the center of the AprilTag\n - rotation: The rotation of the AprilTag\n - decision_margin: The decision_margin of the AprilTag\n - hamming: The hamming of the AprilTag\n - goodness: The goodness of the AprilTag\n - x_translation: The x_translation of the AprilTag\n - y_translation: The y_translation of the AprilTag\n - z_translation: The z_translation of the AprilTag\n - x_rotation: The x_rotation of the AprilTag\n - y_rotation: The y_rotation of the AprilTag\n - z_rotation: The z_rotation of the AprilTag\n" + }, + "args": [ + [ + "std::vector &", + "rect", + null + ], + [ + "std::vector> &", + "corners", + null + ], + [ + "int", + "id", + null + ], + [ + "int", + "famliy", + null + ], + [ + "float", + "centroid_x", + null + ], + [ + "float", + "centroid_y", + null + ], + [ + "float", + "rotation", + null + ], + [ + "float", + "decision_margin", + null + ], + [ + "int", + "hamming", + null + ], + [ + "float", + "goodness", + null + ], + [ + "float", + "x_translation", + null + ], + [ + "float", + "y_translation", + null + ], + [ + "float", + "z_translation", + null + ], + [ + "float", + "x_rotation", + null + ], + [ + "float", + "y_rotation", + null + ], + [ + "float", + "z_rotation", + null + ] + ], + "ret_type": null, + "static": false, + "def": "AprilTag(std::vector &rect, std::vector> &corners, int id, int famliy, float centroid_x, float centroid_y, float rotation, float decision_margin, int hamming, float goodness, float x_translation, float y_translation, float z_translation, float x_rotation, float y_rotation, float z_rotation)" + }, + "__getitem__": { + "type": "func", + "name": "__getitem__", + "doc": { + "brief": "Subscript operator", + "param": { + "index": "[0] Returns the apriltag\u2019s bounding box x coordinate\n[1] Returns the apriltag\u2019s bounding box y coordinate\n[2] Returns the apriltag\u2019s bounding box w coordinate\n[3] Returns the apriltag\u2019s bounding box h coordinate\n[4] Returns the apriltag\u2019s id\n[5] Returns the apriltag\u2019s family\n[6] Not support\n[7] Not support\n[8] Not support\n[9] Not support\n[10] Returns the apriltag\u2019s hamming\n[11] Not support\n[12] Not support\n[13] Not support\n[14] Not support\n[15] Not support\n[16] Not support\n[17] Not support" + }, + "return": "int&", + "maixpy": "maix.image.AprilTag.__getitem__", + "py_doc": "Subscript operator\n\nArgs:\n - index: [0] Returns the apriltag\u2019s bounding box x coordinate\n[1] Returns the apriltag\u2019s bounding box y coordinate\n[2] Returns the apriltag\u2019s bounding box w coordinate\n[3] Returns the apriltag\u2019s bounding box h coordinate\n[4] Returns the apriltag\u2019s id\n[5] Returns the apriltag\u2019s family\n[6] Not support\n[7] Not support\n[8] Not support\n[9] Not support\n[10] Returns the apriltag\u2019s hamming\n[11] Not support\n[12] Not support\n[13] Not support\n[14] Not support\n[15] Not support\n[16] Not support\n[17] Not support\n\n\nReturns: int&\n" + }, + "args": [ + [ + "int", + "index", + null + ] + ], + "ret_type": "int&", + "static": false, + "def": "int &__getitem__(int index)" + }, + "corners": { + "type": "func", + "name": "corners", + "doc": { + "brief": "get coordinate of AprilTag", + "return": "return the coordinate of the AprilTag.", + "maixpy": "maix.image.AprilTag.corners", + "py_doc": "get coordinate of AprilTag\n\nReturns: return the coordinate of the AprilTag.\n" + }, + "args": [], + "ret_type": "std::vector>", + "static": false, + "def": "std::vector> corners()" + }, + "rect": { + "type": "func", + "name": "rect", + "doc": { + "brief": "get rectangle of AprilTag", + "return": "return the rectangle of the AprilTag. format is {x, y, w, h}, type is std::vector", + "maixpy": "maix.image.AprilTag.rect", + "py_doc": "get rectangle of AprilTag\n\nReturns: return the rectangle of the AprilTag. format is {x, y, w, h}, type is std::vector\n" + }, + "args": [], + "ret_type": "std::vector", + "static": false, + "def": "std::vector rect()" + }, + "x": { + "type": "func", + "name": "x", + "doc": { + "brief": "get x of AprilTag", + "return": "return x of the AprilTag, type is int", + "maixpy": "maix.image.AprilTag.x", + "py_doc": "get x of AprilTag\n\nReturns: return x of the AprilTag, type is int\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int x()" + }, + "y": { + "type": "func", + "name": "y", + "doc": { + "brief": "get y of AprilTag", + "return": "return y of the AprilTag, type is int", + "maixpy": "maix.image.AprilTag.y", + "py_doc": "get y of AprilTag\n\nReturns: return y of the AprilTag, type is int\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int y()" + }, + "w": { + "type": "func", + "name": "w", + "doc": { + "brief": "get w of AprilTag", + "return": "return w of the AprilTag, type is int", + "maixpy": "maix.image.AprilTag.w", + "py_doc": "get w of AprilTag\n\nReturns: return w of the AprilTag, type is int\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int w()" + }, + "h": { + "type": "func", + "name": "h", + "doc": { + "brief": "get h of AprilTag", + "return": "return h of the AprilTag, type is int", + "maixpy": "maix.image.AprilTag.h", + "py_doc": "get h of AprilTag\n\nReturns: return h of the AprilTag, type is int\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int h()" + }, + "id": { + "type": "func", + "name": "id", + "doc": { + "brief": "get id of AprilTag", + "return": "return id of the AprilTag, type is int", + "maixpy": "maix.image.AprilTag.id", + "py_doc": "get id of AprilTag\n\nReturns: return id of the AprilTag, type is int\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int id()" + }, + "family": { + "type": "func", + "name": "family", + "doc": { + "brief": "get family of AprilTag", + "return": "return family of the AprilTag, type is int", + "maixpy": "maix.image.AprilTag.family", + "py_doc": "get family of AprilTag\n\nReturns: return family of the AprilTag, type is int\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int family()" + }, + "cx": { + "type": "func", + "name": "cx", + "doc": { + "brief": "get cx of AprilTag", + "return": "return cx of the AprilTag, type is int", + "maixpy": "maix.image.AprilTag.cx", + "py_doc": "get cx of AprilTag\n\nReturns: return cx of the AprilTag, type is int\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int cx()" + }, + "cxf": { + "type": "func", + "name": "cxf", + "doc": { + "brief": "get cxf of AprilTag", + "return": "return cxf of the AprilTag, type is float", + "maixpy": "maix.image.AprilTag.cxf", + "py_doc": "get cxf of AprilTag\n\nReturns: return cxf of the AprilTag, type is float\n" + }, + "args": [], + "ret_type": "float", + "static": false, + "def": "float cxf()" + }, + "cy": { + "type": "func", + "name": "cy", + "doc": { + "brief": "get cy of AprilTag", + "return": "return cy of the AprilTag, type is int", + "maixpy": "maix.image.AprilTag.cy", + "py_doc": "get cy of AprilTag\n\nReturns: return cy of the AprilTag, type is int\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int cy()" + }, + "cyf": { + "type": "func", + "name": "cyf", + "doc": { + "brief": "get cyf of AprilTag", + "return": "return cyf of the AprilTag, type is float", + "maixpy": "maix.image.AprilTag.cyf", + "py_doc": "get cyf of AprilTag\n\nReturns: return cyf of the AprilTag, type is float\n" + }, + "args": [], + "ret_type": "float", + "static": false, + "def": "float cyf()" + }, + "rotation": { + "type": "func", + "name": "rotation", + "doc": { + "brief": "get rotation of AprilTag", + "return": "return rotation of the AprilTag, type is float", + "maixpy": "maix.image.AprilTag.rotation", + "py_doc": "get rotation of AprilTag\n\nReturns: return rotation of the AprilTag, type is float\n" + }, + "args": [], + "ret_type": "float", + "static": false, + "def": "float rotation()" + }, + "decision_margin": { + "type": "func", + "name": "decision_margin", + "doc": { + "brief": "Get decision_margin of AprilTag", + "return": "Returns the quality of the apriltag match (0.0 - 1.0) where 1.0 is the best.", + "maixpy": "maix.image.AprilTag.decision_margin", + "py_doc": "Get decision_margin of AprilTag\n\nReturns: Returns the quality of the apriltag match (0.0 - 1.0) where 1.0 is the best.\n" + }, + "args": [], + "ret_type": "float", + "static": false, + "def": "float decision_margin()" + }, + "hamming": { + "type": "func", + "name": "hamming", + "doc": { + "brief": "get hamming of AprilTag", + "return": "Returns the number of accepted bit errors for this tag.\nreturn 0, means 0 bit errors will be accepted.\n1 is TAG25H7, means up to 1 bit error may be accepted\n2 is TAG25H9, means up to 3 bit errors may be accepted\n3 is TAG36H10, means up to 3 bit errors may be accepted\n4 is TAG36H11, means up to 4 bit errors may be accepted\n5 is ARTOOLKIT, means 0 bit errors will be accepted", + "maixpy": "maix.image.AprilTag.hamming", + "py_doc": "get hamming of AprilTag\n\nReturns: Returns the number of accepted bit errors for this tag.\nreturn 0, means 0 bit errors will be accepted.\n1 is TAG25H7, means up to 1 bit error may be accepted\n2 is TAG25H9, means up to 3 bit errors may be accepted\n3 is TAG36H10, means up to 3 bit errors may be accepted\n4 is TAG36H11, means up to 4 bit errors may be accepted\n5 is ARTOOLKIT, means 0 bit errors will be accepted\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int hamming()" + }, + "goodness": { + "type": "func", + "name": "goodness", + "doc": { + "brief": "get goodness of AprilTag", + "return": "return goodness of the AprilTag, type is float\nNote: This value is always 0.0 for now.", + "maixpy": "maix.image.AprilTag.goodness", + "py_doc": "get goodness of AprilTag\n\nReturns: return goodness of the AprilTag, type is float\nNote: This value is always 0.0 for now.\n" + }, + "args": [], + "ret_type": "float", + "static": false, + "def": "float goodness()" + }, + "x_translation": { + "type": "func", + "name": "x_translation", + "doc": { + "brief": "get x_translation of AprilTag", + "return": "return x_translation of the AprilTag, type is float", + "maixpy": "maix.image.AprilTag.x_translation", + "py_doc": "get x_translation of AprilTag\n\nReturns: return x_translation of the AprilTag, type is float\n" + }, + "args": [], + "ret_type": "float", + "static": false, + "def": "float x_translation()" + }, + "y_translation": { + "type": "func", + "name": "y_translation", + "doc": { + "brief": "get y_translation of AprilTag", + "return": "return y_translation of the AprilTag, type is float", + "maixpy": "maix.image.AprilTag.y_translation", + "py_doc": "get y_translation of AprilTag\n\nReturns: return y_translation of the AprilTag, type is float\n" + }, + "args": [], + "ret_type": "float", + "static": false, + "def": "float y_translation()" + }, + "z_translation": { + "type": "func", + "name": "z_translation", + "doc": { + "brief": "get z_translation of AprilTag", + "return": "return z_translation of the AprilTag, type is float", + "maixpy": "maix.image.AprilTag.z_translation", + "py_doc": "get z_translation of AprilTag\n\nReturns: return z_translation of the AprilTag, type is float\n" + }, + "args": [], + "ret_type": "float", + "static": false, + "def": "float z_translation()" + }, + "x_rotation": { + "type": "func", + "name": "x_rotation", + "doc": { + "brief": "get x_rotation of AprilTag", + "return": "return x_rotation of the AprilTag, type is float", + "maixpy": "maix.image.AprilTag.x_rotation", + "py_doc": "get x_rotation of AprilTag\n\nReturns: return x_rotation of the AprilTag, type is float\n" + }, + "args": [], + "ret_type": "float", + "static": false, + "def": "float x_rotation()" + }, + "y_rotation": { + "type": "func", + "name": "y_rotation", + "doc": { + "brief": "get y_rotation of AprilTag", + "return": "return y_rotation of the AprilTag, type is float", + "maixpy": "maix.image.AprilTag.y_rotation", + "py_doc": "get y_rotation of AprilTag\n\nReturns: return y_rotation of the AprilTag, type is float\n" + }, + "args": [], + "ret_type": "float", + "static": false, + "def": "float y_rotation()" + }, + "z_rotation": { + "type": "func", + "name": "z_rotation", + "doc": { + "brief": "get z_rotation of AprilTag", + "return": "return z_rotation of the AprilTag, type is float", + "maixpy": "maix.image.AprilTag.z_rotation", + "py_doc": "get z_rotation of AprilTag\n\nReturns: return z_rotation of the AprilTag, type is float\n" + }, + "args": [], + "ret_type": "float", + "static": false, + "def": "float z_rotation()" + } + }, + "def": "class AprilTag" + }, + "DataMatrix": { + "type": "class", + "name": "DataMatrix", + "doc": { + "brief": "DataMatrix class", + "maixpy": "maix.image.DataMatrix", + "py_doc": "DataMatrix class" + }, + "members": { + "__init__": { + "type": "func", + "name": "DataMatrix", + "doc": { + "brief": "DataMatrix constructor", + "param": { + "rect": "Inlucdes the top-left corner and the width and height of the rectangle. format is {x, y, w, h}, type is std::vector", + "corners": "Includes the four corners of the rectangle. format is {{x0, y0}, {x1, y1}, {x2, y2}, {x3, y3}}, type is std::vector>", + "payload": "The payload of the DataMatrix", + "rotation": "The rotation of the DataMatrix", + "rows": "The rows of the DataMatrix", + "columns": "The columns of the DataMatrix", + "capacity": "The capacity of the DataMatrix", + "padding": "The padding of the DataMatrix" + }, + "maixpy": "maix.image.DataMatrix.__init__", + "py_doc": "DataMatrix constructor\n\nArgs:\n - rect: Inlucdes the top-left corner and the width and height of the rectangle. format is {x, y, w, h}, type is std::vector\n - corners: Includes the four corners of the rectangle. format is {{x0, y0}, {x1, y1}, {x2, y2}, {x3, y3}}, type is std::vector>\n - payload: The payload of the DataMatrix\n - rotation: The rotation of the DataMatrix\n - rows: The rows of the DataMatrix\n - columns: The columns of the DataMatrix\n - capacity: The capacity of the DataMatrix\n - padding: The padding of the DataMatrix\n" + }, + "args": [ + [ + "std::vector &", + "rect", + null + ], + [ + "std::vector> &", + "corners", + null + ], + [ + "std::string &", + "payload", + null + ], + [ + "float", + "rotation", + null + ], + [ + "int", + "rows", + null + ], + [ + "int", + "columns", + null + ], + [ + "int", + "capacity", + null + ], + [ + "int", + "padding", + null + ] + ], + "ret_type": null, + "static": false, + "def": "DataMatrix(std::vector &rect, std::vector> &corners, std::string &payload, float rotation, int rows, int columns, int capacity, int padding)" + }, + "__getitem__": { + "type": "func", + "name": "__getitem__", + "doc": { + "brief": "Subscript operator", + "param": { + "index": "[0] get x of DataMatrix\n[1] get y of DataMatrix\n[2] get w of DataMatrix\n[3] get h of DataMatrix\n[4] Not support this index, try to use payload() method\n[5] Not support this index, try to use rotation() method\n[6] get rows of DataMatrix\n[7] get columns of DataMatrix\n[8] get capacity of DataMatrix\n[9] get padding of DataMatrix" + }, + "return": "int&", + "maixpy": "maix.image.DataMatrix.__getitem__", + "py_doc": "Subscript operator\n\nArgs:\n - index: [0] get x of DataMatrix\n[1] get y of DataMatrix\n[2] get w of DataMatrix\n[3] get h of DataMatrix\n[4] Not support this index, try to use payload() method\n[5] Not support this index, try to use rotation() method\n[6] get rows of DataMatrix\n[7] get columns of DataMatrix\n[8] get capacity of DataMatrix\n[9] get padding of DataMatrix\n\n\nReturns: int&\n" + }, + "args": [ + [ + "int", + "index", + null + ] + ], + "ret_type": "int&", + "static": false, + "def": "int &__getitem__(int index)" + }, + "corners": { + "type": "func", + "name": "corners", + "doc": { + "brief": "get coordinate of DataMatrix", + "return": "return the coordinate of the DataMatrix.", + "maixpy": "maix.image.DataMatrix.corners", + "py_doc": "get coordinate of DataMatrix\n\nReturns: return the coordinate of the DataMatrix.\n" + }, + "args": [], + "ret_type": "std::vector>", + "static": false, + "def": "std::vector> corners()" + }, + "rect": { + "type": "func", + "name": "rect", + "doc": { + "brief": "get rectangle of DataMatrix", + "return": "return the rectangle of the DataMatrix. format is {x, y, w, h}, type is std::vector", + "maixpy": "maix.image.DataMatrix.rect", + "py_doc": "get rectangle of DataMatrix\n\nReturns: return the rectangle of the DataMatrix. format is {x, y, w, h}, type is std::vector\n" + }, + "args": [], + "ret_type": "std::vector", + "static": false, + "def": "std::vector rect()" + }, + "x": { + "type": "func", + "name": "x", + "doc": { + "brief": "get x of DataMatrix", + "return": "return x of the DataMatrix, type is int", + "maixpy": "maix.image.DataMatrix.x", + "py_doc": "get x of DataMatrix\n\nReturns: return x of the DataMatrix, type is int\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int x()" + }, + "y": { + "type": "func", + "name": "y", + "doc": { + "brief": "get y of DataMatrix", + "return": "return y of the DataMatrix, type is int", + "maixpy": "maix.image.DataMatrix.y", + "py_doc": "get y of DataMatrix\n\nReturns: return y of the DataMatrix, type is int\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int y()" + }, + "w": { + "type": "func", + "name": "w", + "doc": { + "brief": "get w of DataMatrix", + "return": "return w of the DataMatrix, type is int", + "maixpy": "maix.image.DataMatrix.w", + "py_doc": "get w of DataMatrix\n\nReturns: return w of the DataMatrix, type is int\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int w()" + }, + "h": { + "type": "func", + "name": "h", + "doc": { + "brief": "get h of DataMatrix", + "return": "return h of the DataMatrix, type is int", + "maixpy": "maix.image.DataMatrix.h", + "py_doc": "get h of DataMatrix\n\nReturns: return h of the DataMatrix, type is int\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int h()" + }, + "payload": { + "type": "func", + "name": "payload", + "doc": { + "brief": "get payload of DataMatrix", + "return": "return payload of the DataMatrix, type is std::string", + "maixpy": "maix.image.DataMatrix.payload", + "py_doc": "get payload of DataMatrix\n\nReturns: return payload of the DataMatrix, type is std::string\n" + }, + "args": [], + "ret_type": "std::string", + "static": false, + "def": "std::string payload()" + }, + "rotation": { + "type": "func", + "name": "rotation", + "doc": { + "brief": "get rotation of DataMatrix", + "return": "return rotation of the DataMatrix, type is float", + "maixpy": "maix.image.DataMatrix.rotation", + "py_doc": "get rotation of DataMatrix\n\nReturns: return rotation of the DataMatrix, type is float\n" + }, + "args": [], + "ret_type": "float", + "static": false, + "def": "float rotation()" + }, + "rows": { + "type": "func", + "name": "rows", + "doc": { + "brief": "get rows of DataMatrix", + "return": "return rows of the DataMatrix, type is int", + "maixpy": "maix.image.DataMatrix.rows", + "py_doc": "get rows of DataMatrix\n\nReturns: return rows of the DataMatrix, type is int\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int rows()" + }, + "columns": { + "type": "func", + "name": "columns", + "doc": { + "brief": "get columns of DataMatrix", + "return": "return columns of the DataMatrix, type is int", + "maixpy": "maix.image.DataMatrix.columns", + "py_doc": "get columns of DataMatrix\n\nReturns: return columns of the DataMatrix, type is int\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int columns()" + }, + "capacity": { + "type": "func", + "name": "capacity", + "doc": { + "brief": "get capacity of DataMatrix", + "return": "returns how many characters could fit in this data matrix, type is int", + "maixpy": "maix.image.DataMatrix.capacity", + "py_doc": "get capacity of DataMatrix\n\nReturns: returns how many characters could fit in this data matrix, type is int\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int capacity()" + }, + "padding": { + "type": "func", + "name": "padding", + "doc": { + "brief": "get padding of DataMatrix", + "return": "returns how many unused characters are in this data matrix, type is int", + "maixpy": "maix.image.DataMatrix.padding", + "py_doc": "get padding of DataMatrix\n\nReturns: returns how many unused characters are in this data matrix, type is int\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int padding()" + } + }, + "def": "class DataMatrix" + }, + "BarCode": { + "type": "class", + "name": "BarCode", + "doc": { + "brief": "BarCode class", + "maixpy": "maix.image.BarCode", + "py_doc": "BarCode class" + }, + "members": { + "__init__": { + "type": "func", + "name": "BarCode", + "doc": { + "brief": "BarCode constructor", + "param": { + "rect": "Inlucdes the top-left corner and the width and height of the rectangle. format is {x, y, w, h}, type is std::vector", + "corners": "Includes the four corners of the rectangle. format is {{x0, y0}, {x1, y1}, {x2, y2}, {x3, y3}}, type is std::vector>", + "payload": "The payload of the BarCode", + "type": "The type of the BarCode", + "rotation": "The rotation of the BarCode", + "quality": "The quality of the BarCode" + }, + "maixpy": "maix.image.BarCode.__init__", + "py_doc": "BarCode constructor\n\nArgs:\n - rect: Inlucdes the top-left corner and the width and height of the rectangle. format is {x, y, w, h}, type is std::vector\n - corners: Includes the four corners of the rectangle. format is {{x0, y0}, {x1, y1}, {x2, y2}, {x3, y3}}, type is std::vector>\n - payload: The payload of the BarCode\n - type: The type of the BarCode\n - rotation: The rotation of the BarCode\n - quality: The quality of the BarCode\n" + }, + "args": [ + [ + "std::vector &", + "rect", + null + ], + [ + "std::vector> &", + "corners", + null + ], + [ + "std::string &", + "payload", + null + ], + [ + "int", + "type", + null + ], + [ + "float", + "rotation", + null + ], + [ + "int", + "quality", + null + ] + ], + "ret_type": null, + "static": false, + "def": "BarCode(std::vector &rect, std::vector> &corners, std::string &payload, int type, float rotation, int quality)" + }, + "__getitem__": { + "type": "func", + "name": "__getitem__", + "doc": { + "brief": "Subscript operator", + "param": { + "index": "[0] get x of BarCode\n[1] get y of BarCode\n[2] get w of BarCode\n[3] get h of BarCode\n[4] Not support this index, try to use payload() method\n[5] get type of BarCode\n[6] Not support this index, try to use rotation() method\n[7] get quality of BarCode" + }, + "return": "int&", + "maixpy": "maix.image.BarCode.__getitem__", + "py_doc": "Subscript operator\n\nArgs:\n - index: [0] get x of BarCode\n[1] get y of BarCode\n[2] get w of BarCode\n[3] get h of BarCode\n[4] Not support this index, try to use payload() method\n[5] get type of BarCode\n[6] Not support this index, try to use rotation() method\n[7] get quality of BarCode\n\n\nReturns: int&\n" + }, + "args": [ + [ + "int", + "index", + null + ] + ], + "ret_type": "int&", + "static": false, + "def": "int &__getitem__(int index)" + }, + "corners": { + "type": "func", + "name": "corners", + "doc": { + "brief": "get coordinate of BarCode", + "return": "return the coordinate of the BarCode.", + "maixpy": "maix.image.BarCode.corners", + "py_doc": "get coordinate of BarCode\n\nReturns: return the coordinate of the BarCode.\n" + }, + "args": [], + "ret_type": "std::vector>", + "static": false, + "def": "std::vector> corners()" + }, + "rect": { + "type": "func", + "name": "rect", + "doc": { + "brief": "get rectangle of BarCode", + "return": "return the rectangle of the BarCode. format is {x, y, w, h}, type is std::vector", + "maixpy": "maix.image.BarCode.rect", + "py_doc": "get rectangle of BarCode\n\nReturns: return the rectangle of the BarCode. format is {x, y, w, h}, type is std::vector\n" + }, + "args": [], + "ret_type": "std::vector", + "static": false, + "def": "std::vector rect()" + }, + "x": { + "type": "func", + "name": "x", + "doc": { + "brief": "get x of BarCode", + "return": "return x of the BarCode, type is int", + "maixpy": "maix.image.BarCode.x", + "py_doc": "get x of BarCode\n\nReturns: return x of the BarCode, type is int\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int x()" + }, + "y": { + "type": "func", + "name": "y", + "doc": { + "brief": "get y of BarCode", + "return": "return y of the BarCode, type is int", + "maixpy": "maix.image.BarCode.y", + "py_doc": "get y of BarCode\n\nReturns: return y of the BarCode, type is int\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int y()" + }, + "w": { + "type": "func", + "name": "w", + "doc": { + "brief": "get w of BarCode", + "return": "return w of the BarCode, type is int", + "maixpy": "maix.image.BarCode.w", + "py_doc": "get w of BarCode\n\nReturns: return w of the BarCode, type is int\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int w()" + }, + "h": { + "type": "func", + "name": "h", + "doc": { + "brief": "get h of BarCode", + "return": "return h of the BarCode, type is int", + "maixpy": "maix.image.BarCode.h", + "py_doc": "get h of BarCode\n\nReturns: return h of the BarCode, type is int\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int h()" + }, + "payload": { + "type": "func", + "name": "payload", + "doc": { + "brief": "get payload of BarCode", + "return": "return payload of the BarCode, type is std::string", + "maixpy": "maix.image.BarCode.payload", + "py_doc": "get payload of BarCode\n\nReturns: return payload of the BarCode, type is std::string\n" + }, + "args": [], + "ret_type": "std::string", + "static": false, + "def": "std::string payload()" + }, + "type": { + "type": "func", + "name": "type", + "doc": { + "brief": "get type of BarCode", + "return": "return type of the BarCode, type is int", + "maixpy": "maix.image.BarCode.type", + "py_doc": "get type of BarCode\n\nReturns: return type of the BarCode, type is int\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int type()" + }, + "rotation": { + "type": "func", + "name": "rotation", + "doc": { + "brief": "get rotation of BarCode", + "return": "return rotation of the BarCode, type is float. FIXME: always return 0.0", + "maixpy": "maix.image.BarCode.rotation", + "py_doc": "get rotation of BarCode\n\nReturns: return rotation of the BarCode, type is float. FIXME: always return 0.0\n" + }, + "args": [], + "ret_type": "float", + "static": false, + "def": "float rotation()" + }, + "quality": { + "type": "func", + "name": "quality", + "doc": { + "brief": "get quality of BarCode", + "return": "return quality of the BarCode, type is int", + "maixpy": "maix.image.BarCode.quality", + "py_doc": "get quality of BarCode\n\nReturns: return quality of the BarCode, type is int\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int quality()" + } + }, + "def": "class BarCode" + }, + "Statistics": { + "type": "class", + "name": "Statistics", + "doc": { + "brief": "Statistics class", + "maixpy": "maix.image.Statistics", + "py_doc": "Statistics class" + }, + "members": { + "__init__": { + "type": "func", + "name": "Statistics", + "doc": { + "brief": "Statistics constructor", + "param": { + "format": "The statistics source image format", + "l_statistics": "The statistics of the L channel. format is {mean, median, mode, std_dev, min, max, lq, uq}, type is std::vector", + "a_statistics": "The statistics of the A channel. format is {mean, median, mode, std_dev, min, max, lq, uq}, type is std::vector", + "b_statistics": "The statistics of the B channel. format is {mean, median, mode, std_dev, min, max, lq, uq}, type is std::vector" + }, + "maixpy": "maix.image.Statistics.__init__", + "py_doc": "Statistics constructor\n\nArgs:\n - format: The statistics source image format\n - l_statistics: The statistics of the L channel. format is {mean, median, mode, std_dev, min, max, lq, uq}, type is std::vector\n - a_statistics: The statistics of the A channel. format is {mean, median, mode, std_dev, min, max, lq, uq}, type is std::vector\n - b_statistics: The statistics of the B channel. format is {mean, median, mode, std_dev, min, max, lq, uq}, type is std::vector\n" + }, + "args": [ + [ + "image::Format", + "format", + null + ], + [ + "std::vector &", + "l_statistics", + null + ], + [ + "std::vector &", + "a_statistics", + null + ], + [ + "std::vector &", + "b_statistics", + null + ] + ], + "ret_type": null, + "static": false, + "def": "Statistics(image::Format format, std::vector &l_statistics, std::vector &a_statistics, std::vector &b_statistics)" + }, + "__getitem__": { + "type": "func", + "name": "__getitem__", + "doc": { + "brief": "Subscript operator", + "param": { + "index": "array index" + }, + "return": "int&", + "maixpy": "maix.image.Statistics.__getitem__", + "py_doc": "Subscript operator\n\nArgs:\n - index: array index\n\n\nReturns: int&\n" + }, + "args": [ + [ + "int", + "index", + null + ] + ], + "ret_type": "int&", + "static": false, + "def": "int &__getitem__(int index)" + }, + "format": { + "type": "func", + "name": "format", + "doc": { + "brief": "get format of Statistics source image", + "return": "return format of the Statistics source image, type is image::Format", + "maixpy": "maix.image.Statistics.format", + "py_doc": "get format of Statistics source image\n\nReturns: return format of the Statistics source image, type is image::Format\n" + }, + "args": [], + "ret_type": "image::Format", + "static": false, + "def": "image::Format format()" + }, + "l_mean": { + "type": "func", + "name": "l_mean", + "doc": { + "brief": "get L channel mean", + "return": "return L channel mean, type is int", + "maixpy": "maix.image.Statistics.l_mean", + "py_doc": "get L channel mean\n\nReturns: return L channel mean, type is int\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int l_mean()" + }, + "l_median": { + "type": "func", + "name": "l_median", + "doc": { + "brief": "get L channel median", + "return": "return L channel median, type is int", + "maixpy": "maix.image.Statistics.l_median", + "py_doc": "get L channel median\n\nReturns: return L channel median, type is int\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int l_median()" + }, + "l_mode": { + "type": "func", + "name": "l_mode", + "doc": { + "brief": "get L channel mode", + "return": "return L channel mode, type is int", + "maixpy": "maix.image.Statistics.l_mode", + "py_doc": "get L channel mode\n\nReturns: return L channel mode, type is int\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int l_mode()" + }, + "l_std_dev": { + "type": "func", + "name": "l_std_dev", + "doc": { + "brief": "get L channel std_dev", + "return": "return L channel std_dev, type is int", + "maixpy": "maix.image.Statistics.l_std_dev", + "py_doc": "get L channel std_dev\n\nReturns: return L channel std_dev, type is int\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int l_std_dev()" + }, + "l_min": { + "type": "func", + "name": "l_min", + "doc": { + "brief": "get L channel min", + "return": "return L channel min, type is int", + "maixpy": "maix.image.Statistics.l_min", + "py_doc": "get L channel min\n\nReturns: return L channel min, type is int\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int l_min()" + }, + "l_max": { + "type": "func", + "name": "l_max", + "doc": { + "brief": "get L channel max", + "return": "return L channel max, type is int", + "maixpy": "maix.image.Statistics.l_max", + "py_doc": "get L channel max\n\nReturns: return L channel max, type is int\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int l_max()" + }, + "l_lq": { + "type": "func", + "name": "l_lq", + "doc": { + "brief": "get L channel lq", + "return": "return L channel lq, type is int", + "maixpy": "maix.image.Statistics.l_lq", + "py_doc": "get L channel lq\n\nReturns: return L channel lq, type is int\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int l_lq()" + }, + "l_uq": { + "type": "func", + "name": "l_uq", + "doc": { + "brief": "get L channel uq", + "return": "return L channel uq, type is int", + "maixpy": "maix.image.Statistics.l_uq", + "py_doc": "get L channel uq\n\nReturns: return L channel uq, type is int\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int l_uq()" + }, + "a_mean": { + "type": "func", + "name": "a_mean", + "doc": { + "brief": "get A channel mean", + "return": "return A channel mean, type is int", + "maixpy": "maix.image.Statistics.a_mean", + "py_doc": "get A channel mean\n\nReturns: return A channel mean, type is int\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int a_mean()" + }, + "a_median": { + "type": "func", + "name": "a_median", + "doc": { + "brief": "get A channea median", + "return": "return A channel median, type is int", + "maixpy": "maix.image.Statistics.a_median", + "py_doc": "get A channea median\n\nReturns: return A channel median, type is int\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int a_median()" + }, + "a_mode": { + "type": "func", + "name": "a_mode", + "doc": { + "brief": "get A channel mode", + "return": "return A channel mode, type is int", + "maixpy": "maix.image.Statistics.a_mode", + "py_doc": "get A channel mode\n\nReturns: return A channel mode, type is int\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int a_mode()" + }, + "a_std_dev": { + "type": "func", + "name": "a_std_dev", + "doc": { + "brief": "get A channel std_dev", + "return": "return A channel std_dev, type is int", + "maixpy": "maix.image.Statistics.a_std_dev", + "py_doc": "get A channel std_dev\n\nReturns: return A channel std_dev, type is int\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int a_std_dev()" + }, + "a_min": { + "type": "func", + "name": "a_min", + "doc": { + "brief": "get A channel min", + "return": "return A channel min, type is int", + "maixpy": "maix.image.Statistics.a_min", + "py_doc": "get A channel min\n\nReturns: return A channel min, type is int\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int a_min()" + }, + "a_max": { + "type": "func", + "name": "a_max", + "doc": { + "brief": "get A channel max", + "return": "return A channel max, type is int", + "maixpy": "maix.image.Statistics.a_max", + "py_doc": "get A channel max\n\nReturns: return A channel max, type is int\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int a_max()" + }, + "a_lq": { + "type": "func", + "name": "a_lq", + "doc": { + "brief": "get A channel lq", + "return": "return A channel lq, type is int", + "maixpy": "maix.image.Statistics.a_lq", + "py_doc": "get A channel lq\n\nReturns: return A channel lq, type is int\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int a_lq()" + }, + "a_uq": { + "type": "func", + "name": "a_uq", + "doc": { + "brief": "get A channel uq", + "return": "return A channel uq, type is int", + "maixpy": "maix.image.Statistics.a_uq", + "py_doc": "get A channel uq\n\nReturns: return A channel uq, type is int\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int a_uq()" + }, + "b_mean": { + "type": "func", + "name": "b_mean", + "doc": { + "brief": "get B channel mean", + "return": "return B channel mean, type is int", + "maixpy": "maix.image.Statistics.b_mean", + "py_doc": "get B channel mean\n\nReturns: return B channel mean, type is int\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int b_mean()" + }, + "b_median": { + "type": "func", + "name": "b_median", + "doc": { + "brief": "get B channea median", + "return": "return B channel median, type is int", + "maixpy": "maix.image.Statistics.b_median", + "py_doc": "get B channea median\n\nReturns: return B channel median, type is int\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int b_median()" + }, + "b_mode": { + "type": "func", + "name": "b_mode", + "doc": { + "brief": "get B channel mode", + "return": "return B channel mode, type is int", + "maixpy": "maix.image.Statistics.b_mode", + "py_doc": "get B channel mode\n\nReturns: return B channel mode, type is int\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int b_mode()" + }, + "b_std_dev": { + "type": "func", + "name": "b_std_dev", + "doc": { + "brief": "get B channel std_dev", + "return": "return B channel std_dev, type is int", + "maixpy": "maix.image.Statistics.b_std_dev", + "py_doc": "get B channel std_dev\n\nReturns: return B channel std_dev, type is int\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int b_std_dev()" + }, + "b_min": { + "type": "func", + "name": "b_min", + "doc": { + "brief": "get B channel min", + "return": "return B channel min, type is int", + "maixpy": "maix.image.Statistics.b_min", + "py_doc": "get B channel min\n\nReturns: return B channel min, type is int\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int b_min()" + }, + "b_max": { + "type": "func", + "name": "b_max", + "doc": { + "brief": "get B channel max", + "return": "return B channel max, type is int", + "maixpy": "maix.image.Statistics.b_max", + "py_doc": "get B channel max\n\nReturns: return B channel max, type is int\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int b_max()" + }, + "b_lq": { + "type": "func", + "name": "b_lq", + "doc": { + "brief": "get B channel lq", + "return": "return B channel lq, type is int", + "maixpy": "maix.image.Statistics.b_lq", + "py_doc": "get B channel lq\n\nReturns: return B channel lq, type is int\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int b_lq()" + }, + "b_uq": { + "type": "func", + "name": "b_uq", + "doc": { + "brief": "get B channel uq", + "return": "return B channel uq, type is int", + "maixpy": "maix.image.Statistics.b_uq", + "py_doc": "get B channel uq\n\nReturns: return B channel uq, type is int\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int b_uq()" + } + }, + "def": "class Statistics" + }, + "Displacement": { + "type": "class", + "name": "Displacement", + "doc": { + "brief": "Displacement class", + "maixpy": "maix.image.Displacement", + "py_doc": "Displacement class" + }, + "members": { + "__init__": { + "type": "func", + "name": "Displacement", + "doc": { + "brief": "Displacement constructor", + "param": { + "x_translation": "The x_translation of the Displacement", + "y_translation": "The y_translation of the Displacement", + "rotation": "The rotation of the Displacement", + "scale": "The scale of the Displacement", + "response": "The response of the Displacement" + }, + "maixpy": "maix.image.Displacement.__init__", + "py_doc": "Displacement constructor\n\nArgs:\n - x_translation: The x_translation of the Displacement\n - y_translation: The y_translation of the Displacement\n - rotation: The rotation of the Displacement\n - scale: The scale of the Displacement\n - response: The response of the Displacement\n" + }, + "args": [ + [ + "float", + "x_translation", + null + ], + [ + "float", + "y_translation", + null + ], + [ + "float", + "rotation", + null + ], + [ + "float", + "scale", + null + ], + [ + "float", + "response", + null + ] + ], + "ret_type": null, + "static": false, + "def": "Displacement(float x_translation, float y_translation, float rotation, float scale, float response)" + }, + "__getitem__": { + "type": "func", + "name": "__getitem__", + "doc": { + "brief": "Subscript operator", + "param": { + "index": "array index" + }, + "return": "int&", + "maixpy": "maix.image.Displacement.__getitem__", + "py_doc": "Subscript operator\n\nArgs:\n - index: array index\n\n\nReturns: int&\n" + }, + "args": [ + [ + "int", + "index", + null + ] + ], + "ret_type": "int&", + "static": false, + "def": "int &__getitem__(int index)" + }, + "x_translation": { + "type": "func", + "name": "x_translation", + "doc": { + "brief": "get x_translation of Displacement", + "return": "return x_translation of the Displacement, type is float", + "maixpy": "maix.image.Displacement.x_translation", + "py_doc": "get x_translation of Displacement\n\nReturns: return x_translation of the Displacement, type is float\n" + }, + "args": [], + "ret_type": "float", + "static": false, + "def": "float x_translation()" + }, + "y_translation": { + "type": "func", + "name": "y_translation", + "doc": { + "brief": "get y_translation of Displacement", + "return": "return y_translation of the Displacement, type is float", + "maixpy": "maix.image.Displacement.y_translation", + "py_doc": "get y_translation of Displacement\n\nReturns: return y_translation of the Displacement, type is float\n" + }, + "args": [], + "ret_type": "float", + "static": false, + "def": "float y_translation()" + }, + "rotation": { + "type": "func", + "name": "rotation", + "doc": { + "brief": "get rotation of Displacement", + "return": "return rotation of the Displacement, type is float", + "maixpy": "maix.image.Displacement.rotation", + "py_doc": "get rotation of Displacement\n\nReturns: return rotation of the Displacement, type is float\n" + }, + "args": [], + "ret_type": "float", + "static": false, + "def": "float rotation()" + }, + "scale": { + "type": "func", + "name": "scale", + "doc": { + "brief": "get scale of Displacement", + "return": "return scale of the Displacement, type is float", + "maixpy": "maix.image.Displacement.scale", + "py_doc": "get scale of Displacement\n\nReturns: return scale of the Displacement, type is float\n" + }, + "args": [], + "ret_type": "float", + "static": false, + "def": "float scale()" + }, + "response": { + "type": "func", + "name": "response", + "doc": { + "brief": "get response of Displacement", + "return": "return response of the Displacement, type is float", + "maixpy": "maix.image.Displacement.response", + "py_doc": "get response of Displacement\n\nReturns: return response of the Displacement, type is float\n" + }, + "args": [], + "ret_type": "float", + "static": false, + "def": "float response()" + } + }, + "def": "class Displacement" + }, + "Percentile": { + "type": "class", + "name": "Percentile", + "doc": { + "brief": "Percentile class", + "maixpy": "maix.image.Percentile", + "py_doc": "Percentile class" + }, + "members": { + "__init__": { + "type": "func", + "name": "Percentile", + "doc": { + "brief": "Percentile constructor", + "param": { + "l_value": "for grayscale image, it is grayscale percentile value (between 0 and 255).\nfor rgb888 image, it is l channel percentile value of lab (between 0 and 100).", + "a_value": "for rgb888 image, it is a channel percentile value of lab format(between -128 and 127).", + "b_value": "for rgb888 image, it is b channel percentile value of lab format(between -128 and 127)." + }, + "maixpy": "maix.image.Percentile.__init__", + "py_doc": "Percentile constructor\n\nArgs:\n - l_value: for grayscale image, it is grayscale percentile value (between 0 and 255).\nfor rgb888 image, it is l channel percentile value of lab (between 0 and 100).\n - a_value: for rgb888 image, it is a channel percentile value of lab format(between -128 and 127).\n - b_value: for rgb888 image, it is b channel percentile value of lab format(between -128 and 127).\n" + }, + "args": [ + [ + "int", + "l_value", + null + ], + [ + "int", + "a_value", + "0" + ], + [ + "int", + "b_value", + "0" + ] + ], + "ret_type": null, + "static": false, + "def": "Percentile(int l_value, int a_value = 0, int b_value = 0)" + }, + "__getitem__": { + "type": "func", + "name": "__getitem__", + "doc": { + "brief": "Subscript operator", + "maixpy": "maix.image.Percentile.__getitem__", + "py_doc": "Subscript operator" + }, + "args": [ + [ + "int", + "index", + null + ] + ], + "ret_type": "int&", + "static": false, + "def": "int &__getitem__(int index)" + }, + "value": { + "type": "func", + "name": "value", + "doc": { + "brief": "Return the grayscale percentile value (between 0 and 255).", + "return": "returns grayscale percentile value", + "maixpy": "maix.image.Percentile.value", + "py_doc": "Return the grayscale percentile value (between 0 and 255).\n\nReturns: returns grayscale percentile value\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int value()" + }, + "l_value": { + "type": "func", + "name": "l_value", + "doc": { + "brief": "Return the l channel percentile value of lab format (between 0 and 100).", + "return": "returns l channel percentile value", + "maixpy": "maix.image.Percentile.l_value", + "py_doc": "Return the l channel percentile value of lab format (between 0 and 100).\n\nReturns: returns l channel percentile value\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int l_value()" + }, + "a_value": { + "type": "func", + "name": "a_value", + "doc": { + "brief": "Return the a channel percentile value of lab format (between -128 and 127).", + "return": "returns a channel percentile value", + "maixpy": "maix.image.Percentile.a_value", + "py_doc": "Return the a channel percentile value of lab format (between -128 and 127).\n\nReturns: returns a channel percentile value\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int a_value()" + }, + "b_value": { + "type": "func", + "name": "b_value", + "doc": { + "brief": "Return the b channel percentile value of lab format (between -128 and 127).", + "return": "returns b channel percentile value", + "maixpy": "maix.image.Percentile.b_value", + "py_doc": "Return the b channel percentile value of lab format (between -128 and 127).\n\nReturns: returns b channel percentile value\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int b_value()" + } + }, + "def": "class Percentile" + }, + "Threshold": { + "type": "class", + "name": "Threshold", + "doc": { + "brief": "Threshold class", + "maixpy": "maix.image.Threshold", + "py_doc": "Threshold class" + }, + "members": { + "__init__": { + "type": "func", + "name": "Threshold", + "doc": { + "brief": "Threshold constructor", + "param": { + "l_value": "for grayscale image, it is grayscale threshold value (between 0 and 255).\nfor rgb888 image, it is l channel threshold value of lab (between 0 and 100).", + "a_value": "for rgb888 image, it is a channel threshold value of lab format(between -128 and 127).", + "b_value": "for rgb888 image, it is b channel threshold value of lab format(between -128 and 127)." + }, + "maixpy": "maix.image.Threshold.__init__", + "py_doc": "Threshold constructor\n\nArgs:\n - l_value: for grayscale image, it is grayscale threshold value (between 0 and 255).\nfor rgb888 image, it is l channel threshold value of lab (between 0 and 100).\n - a_value: for rgb888 image, it is a channel threshold value of lab format(between -128 and 127).\n - b_value: for rgb888 image, it is b channel threshold value of lab format(between -128 and 127).\n" + }, + "args": [ + [ + "int", + "l_value", + null + ], + [ + "int", + "a_value", + "0" + ], + [ + "int", + "b_value", + "0" + ] + ], + "ret_type": null, + "static": false, + "def": "Threshold(int l_value, int a_value = 0, int b_value = 0)" + }, + "__getitem__": { + "type": "func", + "name": "__getitem__", + "doc": { + "brief": "Subscript operator", + "maixpy": "maix.image.Threshold.__getitem__", + "py_doc": "Subscript operator" + }, + "args": [ + [ + "int", + "index", + null + ] + ], + "ret_type": "int&", + "static": false, + "def": "int &__getitem__(int index)" + }, + "value": { + "type": "func", + "name": "value", + "doc": { + "brief": "Return the grayscale threshold value (between 0 and 255).", + "return": "returns grayscale threshold value", + "maixpy": "maix.image.Threshold.value", + "py_doc": "Return the grayscale threshold value (between 0 and 255).\n\nReturns: returns grayscale threshold value\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int value()" + }, + "l_value": { + "type": "func", + "name": "l_value", + "doc": { + "brief": "Return the l channel threshold value of lab format (between 0 and 100).", + "return": "returns l channel percentile value", + "maixpy": "maix.image.Threshold.l_value", + "py_doc": "Return the l channel threshold value of lab format (between 0 and 100).\n\nReturns: returns l channel percentile value\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int l_value()" + }, + "a_value": { + "type": "func", + "name": "a_value", + "doc": { + "brief": "Return the a channel threshold value of lab format (between -128 and 127).", + "return": "returns a channel percentile value", + "maixpy": "maix.image.Threshold.a_value", + "py_doc": "Return the a channel threshold value of lab format (between -128 and 127).\n\nReturns: returns a channel percentile value\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int a_value()" + }, + "b_value": { + "type": "func", + "name": "b_value", + "doc": { + "brief": "Return the b channel threshold value of lab format (between -128 and 127).", + "return": "returns b channel percentile value", + "maixpy": "maix.image.Threshold.b_value", + "py_doc": "Return the b channel threshold value of lab format (between -128 and 127).\n\nReturns: returns b channel percentile value\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int b_value()" + } + }, + "def": "class Threshold" + }, + "Histogram": { + "type": "class", + "name": "Histogram", + "doc": { + "brief": "Histogram class", + "maixpy": "maix.image.Histogram", + "py_doc": "Histogram class" + }, + "members": { + "__init__": { + "type": "func", + "name": "Histogram", + "doc": { + "brief": "Histogram constructor", + "param": { + "l_value": "for grayscale image, it is grayscale threshold value list (the range of element values in the list is 0 and 255).\nfor rgb888 image, it is l channel threshold value list of lab (the range of element values in the list is 0 and 100).", + "a_value": "for rgb888 image, it is a channel threshold value list of lab format(the range of element values in the list is -128 and 127).", + "b_value": "for rgb888 image, it is b channel threshold value list of lab format(the range of element values in the list is -128 and 127).", + "format": "format of the source image" + }, + "maixpy": "maix.image.Histogram.__init__", + "py_doc": "Histogram constructor\n\nArgs:\n - l_value: for grayscale image, it is grayscale threshold value list (the range of element values in the list is 0 and 255).\nfor rgb888 image, it is l channel threshold value list of lab (the range of element values in the list is 0 and 100).\n - a_value: for rgb888 image, it is a channel threshold value list of lab format(the range of element values in the list is -128 and 127).\n - b_value: for rgb888 image, it is b channel threshold value list of lab format(the range of element values in the list is -128 and 127).\n - format: format of the source image\n" + }, + "args": [ + [ + "std::vector", + "l_bin", + null + ], + [ + "std::vector", + "a_bin", + null + ], + [ + "std::vector", + "b_bin", + null + ], + [ + "image::Format", + "format", + "image::Format::FMT_RGB888" + ] + ], + "ret_type": null, + "static": false, + "def": "Histogram(std::vector l_bin, std::vector a_bin, std::vector b_bin, image::Format format = image::Format::FMT_RGB888)" + }, + "__getitem__": { + "type": "func", + "name": "__getitem__", + "doc": { + "brief": "Subscript operator", + "maixpy": "maix.image.Histogram.__getitem__", + "py_doc": "Subscript operator" + }, + "args": [ + [ + "int", + "index", + null + ] + ], + "ret_type": "int&", + "static": false, + "def": "int &__getitem__(int index)" + }, + "bins": { + "type": "func", + "name": "bins", + "doc": { + "brief": "Returns a list of floats for the grayscale histogram.", + "maixpy": "maix.image.Histogram.bins", + "py_doc": "Returns a list of floats for the grayscale histogram." + }, + "args": [], + "ret_type": "std::vector", + "static": false, + "def": "std::vector bins()" + }, + "l_bins": { + "type": "func", + "name": "l_bins", + "doc": { + "brief": "Returns a list of floats for the RGB565 histogram LAB L channel.", + "maixpy": "maix.image.Histogram.l_bins", + "py_doc": "Returns a list of floats for the RGB565 histogram LAB L channel." + }, + "args": [], + "ret_type": "std::vector", + "static": false, + "def": "std::vector l_bins()" + }, + "a_bins": { + "type": "func", + "name": "a_bins", + "doc": { + "brief": "Returns a list of floats for the RGB565 histogram LAB A channel.", + "maixpy": "maix.image.Histogram.a_bins", + "py_doc": "Returns a list of floats for the RGB565 histogram LAB A channel." + }, + "args": [], + "ret_type": "std::vector", + "static": false, + "def": "std::vector a_bins()" + }, + "b_bins": { + "type": "func", + "name": "b_bins", + "doc": { + "brief": "Returns a list of floats for the RGB565 histogram LAB B channel.", + "maixpy": "maix.image.Histogram.b_bins", + "py_doc": "Returns a list of floats for the RGB565 histogram LAB B channel." + }, + "args": [], + "ret_type": "std::vector", + "static": false, + "def": "std::vector b_bins()" + }, + "get_percentile": { + "type": "func", + "name": "get_percentile", + "doc": { + "brief": "Computes the CDF of the histogram channels and returns a image::Percentile object", + "param": { + "percentile": "the values of the histogram at the passed in percentile (0.0 - 1.0) (float).\nSo, if you pass in 0.1 this method will tell you (going from left-to-right in the histogram)\nwhat bin when summed into an accumulator caused the accumulator to cross 0.1. This is useful\nto determine min (with 0.1) and max (with 0.9) of a color distribution without outlier effects\nruining your results for adaptive color tracking." + }, + "return": "image::Percentile object", + "maixpy": "maix.image.Histogram.get_percentile", + "py_doc": "Computes the CDF of the histogram channels and returns a image::Percentile object\n\nArgs:\n - percentile: the values of the histogram at the passed in percentile (0.0 - 1.0) (float).\nSo, if you pass in 0.1 this method will tell you (going from left-to-right in the histogram)\nwhat bin when summed into an accumulator caused the accumulator to cross 0.1. This is useful\nto determine min (with 0.1) and max (with 0.9) of a color distribution without outlier effects\nruining your results for adaptive color tracking.\n\n\nReturns: image::Percentile object\n" + }, + "args": [ + [ + "float", + "percentile", + null + ] + ], + "ret_type": "image::Percentile", + "static": false, + "def": "image::Percentile get_percentile(float percentile)" + }, + "get_threshold": { + "type": "func", + "name": "get_threshold", + "doc": { + "brief": "Uses Otsu\u2019s Method to compute the optimal threshold values that split the histogram into two halves for each channel of the histogram and returns a image::Threshold object.", + "return": "image::Threshold object", + "maixpy": "maix.image.Histogram.get_threshold", + "py_doc": "Uses Otsu\u2019s Method to compute the optimal threshold values that split the histogram into two halves for each channel of the histogram and returns a image::Threshold object.\n\nReturns: image::Threshold object\n" + }, + "args": [], + "ret_type": "image::Threshold", + "static": false, + "def": "image::Threshold get_threshold()" + }, + "get_statistics": { + "type": "func", + "name": "get_statistics", + "doc": { + "brief": "Computes the mean, median, mode, standard deviation, min, max, lower quartile, and upper quartile of each color channel in the histogram and returns a image::Statistics object.", + "return": "image::Statistics object", + "maixpy": "maix.image.Histogram.get_statistics", + "py_doc": "Computes the mean, median, mode, standard deviation, min, max, lower quartile, and upper quartile of each color channel in the histogram and returns a image::Statistics object.\n\nReturns: image::Statistics object\n" + }, + "args": [], + "ret_type": "image::Statistics", + "static": false, + "def": "image::Statistics get_statistics()" + } + }, + "def": "class Histogram" + }, + "LBPKeyPoint": { + "type": "class", + "name": "LBPKeyPoint", + "doc": { + "brief": "LBPKeyPoint class", + "maixpy": "maix.image.LBPKeyPoint", + "py_doc": "LBPKeyPoint class" + }, + "members": { + "__init__": { + "type": "func", + "name": "LBPKeyPoint", + "doc": { + "brief": "LBPKeyPoint constructor", + "param": { + "data": "The data of the LBPKeyPoint" + }, + "maixpy": "maix.image.LBPKeyPoint.__init__", + "py_doc": "LBPKeyPoint constructor\n\nArgs:\n - data: The data of the LBPKeyPoint\n" + }, + "args": [ + [ + "std::valarray &", + "data", + null + ] + ], + "ret_type": null, + "static": false, + "def": "LBPKeyPoint(std::valarray &data)" + } + }, + "def": "class LBPKeyPoint" + }, + "KeyPoint": { + "type": "class", + "name": "KeyPoint", + "doc": { + "brief": "KeyPoint class", + "maixpy": "maix.image.KeyPoint", + "py_doc": "KeyPoint class" + }, + "members": { + "__init__": { + "type": "func", + "name": "KeyPoint", + "doc": { + "brief": "KeyPoint constructor", + "param": { + "x": "The x of the KeyPoint", + "y": "The y of the KeyPoint", + "score": "The score of the KeyPoint", + "octave": "The octave of the KeyPoint", + "angle": "The angle of the KeyPoint", + "matched": "The matched of the KeyPoint", + "desc": "The desc of the KeyPoint" + }, + "maixpy": "maix.image.KeyPoint.__init__", + "py_doc": "KeyPoint constructor\n\nArgs:\n - x: The x of the KeyPoint\n - y: The y of the KeyPoint\n - score: The score of the KeyPoint\n - octave: The octave of the KeyPoint\n - angle: The angle of the KeyPoint\n - matched: The matched of the KeyPoint\n - desc: The desc of the KeyPoint\n" + }, + "args": [ + [ + "uint16_t", + "x", + null + ], + [ + "uint16_t", + "y", + null + ], + [ + "uint16_t", + "score", + null + ], + [ + "uint16_t", + "octave", + null + ], + [ + "uint16_t", + "angle", + null + ], + [ + "uint16_t", + "matched", + null + ], + [ + "std::vector &", + "desc", + null + ] + ], + "ret_type": null, + "static": false, + "def": "KeyPoint(uint16_t x, uint16_t y, uint16_t score, uint16_t octave, uint16_t angle, uint16_t matched, std::vector &desc)" + } + }, + "def": "class KeyPoint" + }, + "KPTMatch": { + "type": "class", + "name": "KPTMatch", + "doc": { + "brief": "KPTMatch class", + "maixpy": "maix.image.KPTMatch", + "py_doc": "KPTMatch class" + }, + "members": { + "__init__": { + "type": "func", + "name": "KPTMatch", + "doc": { + "brief": "KPTMatch constructor", + "param": { + "cx": "The cx of the KPTMatch", + "cy": "The cy of the KPTMatch", + "x": "The x of the KPTMatch", + "y": "The y of the KPTMatch", + "w": "The w of the KPTMatch", + "h": "The h of the KPTMatch", + "score": "The score of the KPTMatch", + "theta": "The theta of the KPTMatch", + "match": "The match of the KPTMatch" + }, + "maixpy": "maix.image.KPTMatch.__init__", + "py_doc": "KPTMatch constructor\n\nArgs:\n - cx: The cx of the KPTMatch\n - cy: The cy of the KPTMatch\n - x: The x of the KPTMatch\n - y: The y of the KPTMatch\n - w: The w of the KPTMatch\n - h: The h of the KPTMatch\n - score: The score of the KPTMatch\n - theta: The theta of the KPTMatch\n - match: The match of the KPTMatch\n" + }, + "args": [ + [ + "int", + "cx", + null + ], + [ + "int", + "cy", + null + ], + [ + "int", + "x", + null + ], + [ + "int", + "y", + null + ], + [ + "int", + "w", + null + ], + [ + "int", + "h", + null + ], + [ + "int", + "score", + null + ], + [ + "int", + "theta", + null + ], + [ + "int", + "match", + null + ] + ], + "ret_type": null, + "static": false, + "def": "KPTMatch(int cx, int cy, int x, int y, int w, int h, int score, int theta, int match)" + } + }, + "def": "class KPTMatch" + }, + "ORBKeyPoint": { + "type": "class", + "name": "ORBKeyPoint", + "doc": { + "brief": "ORBKeyPoint class", + "maixpy": "maix.image.ORBKeyPoint", + "py_doc": "ORBKeyPoint class" + }, + "members": { + "__init__": { + "type": "func", + "name": "ORBKeyPoint", + "doc": { + "brief": "ORBKeyPoint constructor", + "param": { + "data": "The data of the ORBKeyPoint", + "threshold": "The threshold of the ORBKeyPoint", + "normalized": "The normalized of the ORBKeyPoint" + }, + "maixpy": "maix.image.ORBKeyPoint.__init__", + "py_doc": "ORBKeyPoint constructor\n\nArgs:\n - data: The data of the ORBKeyPoint\n - threshold: The threshold of the ORBKeyPoint\n - normalized: The normalized of the ORBKeyPoint\n" + }, + "args": [ + [ + "std::vector &", + "data", + null + ], + [ + "int", + "threshold", + null + ], + [ + "bool", + "normalized", + null + ] + ], + "ret_type": null, + "static": false, + "def": "ORBKeyPoint(std::vector &data, int threshold, bool normalized)" + }, + "get_data": { + "type": "func", + "name": "get_data", + "doc": { + "brief": "get data of ORBKeyPoint", + "return": "return data of the ORBKeyPoint, type is std::vector", + "maixpy": "maix.image.ORBKeyPoint.get_data", + "py_doc": "get data of ORBKeyPoint\n\nReturns: return data of the ORBKeyPoint, type is std::vector\n" + }, + "args": [], + "ret_type": "std::vector", + "static": false, + "def": "std::vector get_data()" + } + }, + "def": "class ORBKeyPoint" + }, + "HaarCascade": { + "type": "class", + "name": "HaarCascade", + "doc": { + "brief": "HaarCascade class", + "maixpy": "maix.image.HaarCascade", + "py_doc": "HaarCascade class" + }, + "members": { + "__init__": { + "type": "func", + "name": "HaarCascade", + "doc": { + "brief": "HaarCascade constructor", + "param": { + "data": "The data of the HaarCascade", + "threshold": "The threshold of the HaarCascade", + "normalized": "The normalized of the HaarCascade" + }, + "maixpy": "maix.image.HaarCascade.__init__", + "py_doc": "HaarCascade constructor\n\nArgs:\n - data: The data of the HaarCascade\n - threshold: The threshold of the HaarCascade\n - normalized: The normalized of the HaarCascade\n" + }, + "args": [], + "ret_type": null, + "static": false, + "def": "HaarCascade()", + "overload": [ + { + "type": "func", + "name": "LineGroup", + "doc": { + "brief": "LineGroup constructor", + "param": { + "id": "The id of line", + "type": "The line list type, @see image::LineType", + "lines": "The line list", + "points": "Point sets of line" + }, + "maixpy": "maix.image.HaarCascade.__init__", + "py_doc": "LineGroup constructor\n\nArgs:\n - id: The id of line\n - type: The line list type, @see image::LineType\n - lines: The line list\n - points: Point sets of line\n" + }, + "args": [ + [ + "int", + "id", + null + ], + [ + "image::LineType", + "type", + null + ], + [ + "std::vector", + "lines", + null + ], + [ + "std::vector>>", + "points", + "std::vector>>()" + ] + ], + "ret_type": null, + "static": false, + "def": "LineGroup(int id, image::LineType type, std::vector lines, std::vector>> points = std::vector>>())" + } + ] + } + }, + "def": "class HaarCascade" + }, + "LineType": { + "type": "enum", + "name": "class", + "doc": { + "brief": "Line type class", + "maixpy": "maix.image.LineType", + "py_doc": "Line type class" + }, + "values": [ + [ + "LINE_NORMAL", + "", + "" + ], + [ + "LINE_CROSS", + "", + "" + ], + [ + "LINE_T", + "", + "" + ], + [ + "LINE_L", + "", + "" + ] + ], + "def": "enum class LineType {\n LINE_NORMAL,\n LINE_CROSS,\n LINE_T,\n LINE_L,\n }" + }, + "LineGroup": { + "type": "class", + "name": "LineGroup", + "doc": { + "brief": "LineGroup class", + "maixpy": "maix.image.LineGroup", + "py_doc": "LineGroup class" + }, + "members": { + "id": { + "type": "func", + "name": "id", + "doc": { + "brief": "Get the line id of group, first id is 0.", + "return": "return id", + "maixpy": "maix.image.LineGroup.id", + "py_doc": "Get the line id of group, first id is 0.\n\nReturns: return id\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int id()" + }, + "type": { + "type": "func", + "name": "type", + "doc": { + "brief": "Get the line type of group", + "return": "returns line type. @see LineType", + "maixpy": "maix.image.LineGroup.type", + "py_doc": "Get the line type of group\n\nReturns: returns line type. @see LineType\n" + }, + "args": [], + "ret_type": "image::LineType", + "static": false, + "def": "image::LineType type()" + }, + "lines": { + "type": "func", + "name": "lines", + "doc": { + "brief": "Get a list of line", + "return": "returns a list composed of Line objects", + "maixpy": "maix.image.LineGroup.lines", + "py_doc": "Get a list of line\n\nReturns: returns a list composed of Line objects\n" + }, + "args": [], + "ret_type": "std::vector", + "static": false, + "def": "std::vector lines()" + }, + "points": { + "type": "func", + "name": "points", + "doc": { + "brief": "Get the key points of line", + "return": "returns a list composed of (x,y) coordnates.", + "maixpy": "maix.image.LineGroup.points", + "py_doc": "Get the key points of line\n\nReturns: returns a list composed of (x,y) coordnates.\n" + }, + "args": [], + "ret_type": "std::vector>>", + "static": false, + "def": "std::vector>> points()" + } + }, + "def": "class LineGroup" + }, + "resize_map_pos": { + "type": "func", + "name": "resize_map_pos", + "doc": { + "brief": "map point position or rectangle position from one image size to another image size(resize)", + "param": { + "int": "h_out target image height", + "fit": "resize method, see maix.image.Fit", + "x": "original point x, or rectagle left-top point's x", + "y": "original point y, or rectagle left-top point's y", + "w": "original rectagle width, can be -1 if not use this arg, default -1.", + "h": "original rectagle height, can be -1 if not use this arg, default -1." + }, + "return": "list type, [x, y] if map point, [x, y, w, h] if resize rectangle.", + "maixpy": "maix.image.resize_map_pos", + "py_doc": "map point position or rectangle position from one image size to another image size(resize)\n\nArgs:\n - int: h_out target image height\n - fit: resize method, see maix.image.Fit\n - x: original point x, or rectagle left-top point's x\n - y: original point y, or rectagle left-top point's y\n - w: original rectagle width, can be -1 if not use this arg, default -1.\n - h: original rectagle height, can be -1 if not use this arg, default -1.\n\n\nReturns: list type, [x, y] if map point, [x, y, w, h] if resize rectangle.\n" + }, + "args": [ + [ + "int", + "w_in", + null + ], + [ + "int", + "h_in", + null + ], + [ + "int", + "w_out", + null + ], + [ + "int", + "h_out", + null + ], + [ + "image::Fit", + "fit", + null + ], + [ + "int", + "x", + null + ], + [ + "int", + "y", + null + ], + [ + "int", + "w", + "-1" + ], + [ + "int", + "h", + "-1" + ] + ], + "ret_type": "std::vector", + "static": false, + "def": "std::vector resize_map_pos(int w_in, int h_in, int w_out, int h_out, image::Fit fit, int x, int y, int w = -1, int h = -1)", + "overload": [ + { + "type": "func", + "name": "resize_map_pos", + "doc": { + "brief": "map point position or rectangle position from this image size to another image size(resize)", + "param": { + "int": "h_out target image height", + "fit": "resize method, see maix.image.Fit", + "x": "original point x, or rectagle left-top point's x", + "y": "original point y, or rectagle left-top point's y", + "w": "original rectagle width, can be -1 if not use this arg, default -1.", + "h": "original rectagle height, can be -1 if not use this arg, default -1." + }, + "return": "list type, [x, y] if map point, [x, y, w, h] if resize rectangle.", + "maixpy": "maix.image.resize_map_pos", + "py_doc": "map point position or rectangle position from this image size to another image size(resize)\n\nArgs:\n - int: h_out target image height\n - fit: resize method, see maix.image.Fit\n - x: original point x, or rectagle left-top point's x\n - y: original point y, or rectagle left-top point's y\n - w: original rectagle width, can be -1 if not use this arg, default -1.\n - h: original rectagle height, can be -1 if not use this arg, default -1.\n\n\nReturns: list type, [x, y] if map point, [x, y, w, h] if resize rectangle.\n" + }, + "args": [ + [ + "int", + "w_out", + null + ], + [ + "int", + "h_out", + null + ], + [ + "image::Fit", + "fit", + null + ], + [ + "int", + "x", + null + ], + [ + "int", + "y", + null + ], + [ + "int", + "w", + "-1" + ], + [ + "int", + "h", + "-1" + ] + ], + "ret_type": "std::vector", + "static": false, + "def": "std::vector resize_map_pos(int w_out, int h_out, image::Fit fit, int x, int y, int w = -1, int h = -1)" + } + ] + }, + "resize_map_pos_reverse": { + "type": "func", + "name": "resize_map_pos_reverse", + "doc": { + "brief": "reverse resize_map_pos method, when we call image.resize method resiz image 'a' to image 'b', we want to known the original position on 'a' whith a knew point on 'b'", + "param": { + "int": "h_out image height after resized", + "fit": "resize method, see maix.image.Fit", + "x": "point on resized image x, or rectagle left-top point's x", + "y": "original point y, or rectagle left-top point's y", + "w": "original rectagle width, can be -1 if not use this arg, default -1.", + "h": "original rectagle height, can be -1 if not use this arg, default -1." + }, + "return": "list type, [x, y] if map point, [x, y, w, h] if resize rectangle.", + "maixpy": "maix.image.resize_map_pos_reverse", + "py_doc": "reverse resize_map_pos method, when we call image.resize method resiz image 'a' to image 'b', we want to known the original position on 'a' whith a knew point on 'b'\n\nArgs:\n - int: h_out image height after resized\n - fit: resize method, see maix.image.Fit\n - x: point on resized image x, or rectagle left-top point's x\n - y: original point y, or rectagle left-top point's y\n - w: original rectagle width, can be -1 if not use this arg, default -1.\n - h: original rectagle height, can be -1 if not use this arg, default -1.\n\n\nReturns: list type, [x, y] if map point, [x, y, w, h] if resize rectangle.\n" + }, + "args": [ + [ + "int", + "w_in", + null + ], + [ + "int", + "h_in", + null + ], + [ + "int", + "w_out", + null + ], + [ + "int", + "h_out", + null + ], + [ + "image::Fit", + "fit", + null + ], + [ + "int", + "x", + null + ], + [ + "int", + "y", + null + ], + [ + "int", + "w", + "-1" + ], + [ + "int", + "h", + "-1" + ] + ], + "ret_type": "std::vector", + "static": false, + "def": "std::vector resize_map_pos_reverse(int w_in, int h_in, int w_out, int h_out, image::Fit fit, int x, int y, int w = -1, int h = -1)" + }, + "Image": { + "type": "class", + "name": "Image", + "doc": { + "brief": "Image class", + "maixpy": "maix.image.Image", + "py_doc": "Image class" + }, + "members": { + "Image": { + "type": "func", + "name": "Image", + "doc": { + "brief": "Image constructor", + "param": { + "width": "image width, should > 0", + "height": "image height, should > 0", + "format": "image format @see image::Format" + }, + "maixpy": "maix.image.Image.__init__", + "maixcdk": "maix.image.Image.Image", + "py_doc": "Image constructor\n\nArgs:\n - width: image width, should > 0\n - height: image height, should > 0\n - format: image format @see image::Format\n" + }, + "args": [ + [ + "int", + "width", + null + ], + [ + "int", + "height", + null + ], + [ + "image::Format", + "format", + "image::Format::FMT_RGB888" + ] + ], + "ret_type": null, + "static": false, + "def": "Image(int width, int height, image::Format format = image::Format::FMT_RGB888)", + "overload": [ + { + "type": "func", + "name": "Image", + "doc": { + "brief": "Image constructor", + "param": { + "width": "image width, should > 0", + "height": "image height, should > 0", + "format": "image format @see image::Format", + "data": "image data, if data is nullptr, will malloc memory for image data\nIf the image is in jpeg format, data must be filled in.", + "data_size": "image data size, only for compressed format like jpeg png, data_size must be filled in, or should be -1, default is -1.", + "copy": "if true and data is not nullptr, will copy data to new buffer, else will use data directly. default is true to avoid memory leak." + }, + "maixcdk": "maix.image.Image.Image", + "py_doc": "Image constructor\n\nArgs:\n - width: image width, should > 0\n - height: image height, should > 0\n - format: image format @see image::Format\n - data: image data, if data is nullptr, will malloc memory for image data\nIf the image is in jpeg format, data must be filled in.\n - data_size: image data size, only for compressed format like jpeg png, data_size must be filled in, or should be -1, default is -1.\n - copy: if true and data is not nullptr, will copy data to new buffer, else will use data directly. default is true to avoid memory leak.\n" + }, + "args": [ + [ + "int", + "width", + null + ], + [ + "int", + "height", + null + ], + [ + "image::Format", + "format", + null + ], + [ + "uint8_t *", + "data", + null + ], + [ + "int", + "data_size", + null + ], + [ + "bool", + "copy", + null + ] + ], + "ret_type": null, + "static": false, + "def": "Image(int width, int height, image::Format format, uint8_t *data, int data_size, bool copy)" + } + ] + }, + "update": { + "type": "func", + "name": "update", + "doc": { + "brief": "set image", + "maixcdk": "maix.image.Image.update", + "py_doc": "set image" + }, + "args": [ + [ + "int", + "width", + null + ], + [ + "int", + "height", + null + ], + [ + "image::Format", + "format", + null + ], + [ + "uint8_t *", + "data", + "NULL" + ], + [ + "int", + "data_size", + "0" + ], + [ + "bool", + "copy", + "true" + ] + ], + "ret_type": "err::Err", + "static": false, + "def": "err::Err update(int width, int height, image::Format format, uint8_t *data = NULL, int data_size = 0, bool copy = true)" + }, + "format": { + "type": "func", + "name": "format", + "doc": { + "brief": "Get image's format", + "see": "image.Format", + "maixpy": "maix.image.Image.format", + "py_doc": "Get image's format" + }, + "args": [], + "ret_type": "image::Format", + "static": false, + "def": "image::Format format()" + }, + "size": { + "type": "func", + "name": "size", + "doc": { + "brief": "Get image's size, [width, height]", + "maixpy": "maix.image.Image.size", + "py_doc": "Get image's size, [width, height]" + }, + "args": [], + "ret_type": "image::Size", + "static": false, + "def": "image::Size size()" + }, + "data_size": { + "type": "func", + "name": "data_size", + "doc": { + "brief": "Get image's data size", + "maixpy": "maix.image.Image.data_size", + "py_doc": "Get image's data size" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int data_size()" + }, + "width": { + "type": "func", + "name": "width", + "doc": { + "brief": "Get image's width", + "maixpy": "maix.image.Image.width", + "py_doc": "Get image's width" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int width()" + }, + "height": { + "type": "func", + "name": "height", + "doc": { + "brief": "Get image's height", + "maixpy": "maix.image.Image.height", + "py_doc": "Get image's height" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int height()" + }, + "data": { + "type": "func", + "name": "data", + "doc": { + "brief": "Get image's data pointer.\\nIn MaixPy is capsule object.", + "maixcdk": "maix.image.Image.data", + "py_doc": "Get image's data pointer.\nIn MaixPy is capsule object." + }, + "args": [], + "ret_type": "void*", + "static": false, + "def": "void *data()" + }, + "__str__": { + "type": "func", + "name": "__str__", + "doc": { + "brief": "To string method", + "maixpy": "maix.image.Image.__str__", + "py_doc": "To string method" + }, + "args": [], + "ret_type": "std::string", + "static": false, + "def": "std::string __str__()" + }, + "to_str": { + "type": "func", + "name": "to_str", + "doc": { + "brief": "To string method", + "maixpy": "maix.image.Image.to_str", + "py_doc": "To string method" + }, + "args": [], + "ret_type": "std::string", + "static": false, + "def": "std::string to_str()" + }, + "get_pixel": { + "type": "func", + "name": "get_pixel", + "doc": { + "brief": "Get pixel of image", + "param": { + "x": "pixel's coordinate x. x must less than image's width", + "y": "pixel's coordinate y. y must less than image's height", + "rgbtuple": "switch return value method. rgbtuple decides whether to split the return or not. default is false." + }, + "return": "pixel value,\nAccording to image format and rgbtuple, return different value:\nformat is FMT_RGB888, rgbtuple is true, return [R, G, B]; rgbtuple is false, return [RGB]\nforamt is FMT_BGR888, rgbtuple is true, return [B, G, R]; rgbtuple is false, return [BGR]\nformat is FMT_GRAYSCALE, return [GRAY];", + "maixpy": "maix.image.Image.get_pixel", + "py_doc": "Get pixel of image\n\nArgs:\n - x: pixel's coordinate x. x must less than image's width\n - y: pixel's coordinate y. y must less than image's height\n - rgbtuple: switch return value method. rgbtuple decides whether to split the return or not. default is false.\n\n\nReturns: pixel value,\nAccording to image format and rgbtuple, return different value:\nformat is FMT_RGB888, rgbtuple is true, return [R, G, B]; rgbtuple is false, return [RGB]\nforamt is FMT_BGR888, rgbtuple is true, return [B, G, R]; rgbtuple is false, return [BGR]\nformat is FMT_GRAYSCALE, return [GRAY];\n" + }, + "args": [ + [ + "int", + "x", + null + ], + [ + "int", + "y", + null + ], + [ + "bool", + "rgbtuple", + "false" + ] + ], + "ret_type": "std::vector", + "static": false, + "def": "std::vector get_pixel(int x, int y, bool rgbtuple = false)" + }, + "set_pixel": { + "type": "func", + "name": "set_pixel", + "doc": { + "brief": "Set pixel of image", + "param": { + "x": "pixel's coordinate x. x must less than image's width", + "y": "pixel's coordinate y. y must less than image's height", + "pixel": "pixel value, according to image format and size of pixel, has different operation:\nformat is FMT_RGB888, pixel size must be 1 or 3, if size is 1, will split pixel[0] to [R, G, B]; if size is 3, will use pixel directly\nformat is FMT_BGR888, pixel size must be 1 or 3, if size is 1, will split pixel[0] to [B, G, R]; if size is 3, will use pixel directly\nformat is FMT_GRAYSCALE, pixel size must be 1, will use pixel directly" + }, + "return": "error code, Err::ERR_NONE is ok, other is error", + "maixpy": "maix.image.Image.set_pixel", + "py_doc": "Set pixel of image\n\nArgs:\n - x: pixel's coordinate x. x must less than image's width\n - y: pixel's coordinate y. y must less than image's height\n - pixel: pixel value, according to image format and size of pixel, has different operation:\nformat is FMT_RGB888, pixel size must be 1 or 3, if size is 1, will split pixel[0] to [R, G, B]; if size is 3, will use pixel directly\nformat is FMT_BGR888, pixel size must be 1 or 3, if size is 1, will split pixel[0] to [B, G, R]; if size is 3, will use pixel directly\nformat is FMT_GRAYSCALE, pixel size must be 1, will use pixel directly\n\n\nReturns: error code, Err::ERR_NONE is ok, other is error\n" + }, + "args": [ + [ + "int", + "x", + null + ], + [ + "int", + "y", + null + ], + [ + "std::vector", + "pixel", + null + ] + ], + "ret_type": "err::Err", + "static": false, + "def": "err::Err set_pixel(int x, int y, std::vector pixel)" + }, + "to_tensor": { + "type": "func", + "name": "to_tensor", + "doc": { + "brief": "Convert Image object to tensor::Tensor object", + "param": { + "chw": "if true, the shape of tensor is [C, H, W], else [H, W, C]", + "copy": "if true, will alloc memory for tensor data, else will use the memory of Image object" + }, + "return": "tensor::Tensor object pointer, an allocated tensor object", + "maixpy": "maix.image.Image.to_tensor", + "py_doc": "Convert Image object to tensor::Tensor object\n\nArgs:\n - chw: if true, the shape of tensor is [C, H, W], else [H, W, C]\n - copy: if true, will alloc memory for tensor data, else will use the memory of Image object\n\n\nReturns: tensor::Tensor object pointer, an allocated tensor object\n" + }, + "args": [ + [ + "bool", + "chw", + "false" + ], + [ + "bool", + "copy", + "true" + ] + ], + "ret_type": "tensor::Tensor*", + "static": false, + "def": "tensor::Tensor *to_tensor(bool chw = false, bool copy = true)" + }, + "to_bytes": { + "type": "func", + "name": "to_bytes", + "doc": { + "brief": "Get image's data and convert to array bytes", + "param": { + "copy": "if true, will alloc memory and copy data to new buffer,\nelse will use the memory of Image object, delete bytes object will not affect Image object\uff0c\nbut delete Image object will make bytes object invalid, it may cause program crash !!!!\nSo use this param carefully." + }, + "return": "image's data bytes, need be delete by caller in C++.", + "maixpy": "maix.image.Image.to_bytes", + "py_doc": "Get image's data and convert to array bytes\n\nArgs:\n - copy: if true, will alloc memory and copy data to new buffer,\nelse will use the memory of Image object, delete bytes object will not affect Image object\uff0c\nbut delete Image object will make bytes object invalid, it may cause program crash !!!!\nSo use this param carefully.\n\n\nReturns: image's data bytes, need be delete by caller in C++.\n" + }, + "args": [ + [ + "bool", + "copy", + "true" + ] + ], + "ret_type": "Bytes*", + "static": false, + "def": "Bytes *to_bytes(bool copy = true)" + }, + "to_format": { + "type": "func", + "name": "to_format", + "doc": { + "brief": "Convert image to specific format", + "param": { + "format": "format want to convert to, @see image::Format, only support RGB888, BGR888, RGBA8888, BGRA8888, GRAYSCALE, JPEG." + }, + "return": "new image object. Need be delete by caller in C++.", + "throw": "err.Exception, if two images' format not support, **or already the format**, will raise exception", + "maixpy": "maix.image.Image.to_format", + "py_doc": "Convert image to specific format\n\nArgs:\n - format: format want to convert to, @see image::Format, only support RGB888, BGR888, RGBA8888, BGRA8888, GRAYSCALE, JPEG.\n\n\nReturns: new image object. Need be delete by caller in C++.\n" + }, + "args": [ + [ + "const image::Format &", + "format", + null + ] + ], + "ret_type": "image::Image*", + "static": false, + "def": "image::Image *to_format(const image::Format &format)", + "overload": [ + { + "type": "func", + "name": "to_format", + "doc": { + "brief": "Convert image to specific format", + "param": { + "format": "format want to convert to, @see image::Format, only support RGB888, BGR888, RGBA8888, BGRA8888, GRAYSCALE, JPEG.", + "buff": "user's buffer, if buff is nullptr, will malloc memory for new image data, else will use buff directly" + }, + "return": "new image object. Need be delete by caller in C++.", + "throw": "err.Exception, if two images' format not support, **or already the format**, will raise exception", + "maixcdk": "maix.image.Image.to_format", + "py_doc": "Convert image to specific format\n\nArgs:\n - format: format want to convert to, @see image::Format, only support RGB888, BGR888, RGBA8888, BGRA8888, GRAYSCALE, JPEG.\n - buff: user's buffer, if buff is nullptr, will malloc memory for new image data, else will use buff directly\n\n\nReturns: new image object. Need be delete by caller in C++.\n" + }, + "args": [ + [ + "const image::Format &", + "format", + null + ], + [ + "void *", + "buff", + null + ], + [ + "size_t", + "buff_size", + null + ] + ], + "ret_type": "image::Image*", + "static": false, + "def": "image::Image *to_format(const image::Format &format, void *buff, size_t buff_size)" + } + ] + }, + "to_jpeg": { + "type": "func", + "name": "to_jpeg", + "doc": { + "brief": "Convert image to jpeg", + "param": { + "quality": "the quality of jpg, default is 95. For MaixCAM supported range is (50, 100], if <= 50 will be fixed to 51." + }, + "return": "new image object. Need be delete by caller in C++.", + "throw": "err.Exception, if two images' format not support, **or already the format**, will raise exception", + "maixpy": "maix.image.Image.to_jpeg", + "py_doc": "Convert image to jpeg\n\nArgs:\n - quality: the quality of jpg, default is 95. For MaixCAM supported range is (50, 100], if <= 50 will be fixed to 51.\n\n\nReturns: new image object. Need be delete by caller in C++.\n" + }, + "args": [ + [ + "int", + "quality", + "95" + ] + ], + "ret_type": "image::Image*", + "static": false, + "def": "image::Image *to_jpeg(int quality = 95)" + }, + "draw_image": { + "type": "func", + "name": "draw_image", + "doc": { + "brief": "Draw image on this image", + "param": { + "x": "left top corner of image point's coordinate x", + "y": "left top corner of image point's coordinate y", + "img": "image object to draw, the caller's channel must <= the args' channel,\ne.g. caller is RGB888, args is RGBA8888, will throw exception, but caller is RGBA8888, args is RGB888 or RGBA8888 is ok" + }, + "return": "this image object self", + "maixpy": "maix.image.Image.draw_image", + "py_doc": "Draw image on this image\n\nArgs:\n - x: left top corner of image point's coordinate x\n - y: left top corner of image point's coordinate y\n - img: image object to draw, the caller's channel must <= the args' channel,\ne.g. caller is RGB888, args is RGBA8888, will throw exception, but caller is RGBA8888, args is RGB888 or RGBA8888 is ok\n\n\nReturns: this image object self\n" + }, + "args": [ + [ + "int", + "x", + null + ], + [ + "int", + "y", + null + ], + [ + "image::Image &", + "img", + null + ] + ], + "ret_type": "image::Image*", + "static": false, + "def": "image::Image *draw_image(int x, int y, image::Image &img)" + }, + "draw_rect": { + "type": "func", + "name": "draw_rect", + "doc": { + "brief": "Fill rectangle color to image", + "param": { + "x": "left top corner of rectangle point's coordinate x", + "y": "left top corner of rectangle point's coordinate y", + "w": "rectangle width", + "h": "rectangle height", + "color": "rectangle color", + "thickness": "rectangle thickness(line width), by default(value is 1), -1 means fill rectangle" + }, + "return": "this image object self", + "maixpy": "maix.image.Image.draw_rect", + "py_doc": "Fill rectangle color to image\n\nArgs:\n - x: left top corner of rectangle point's coordinate x\n - y: left top corner of rectangle point's coordinate y\n - w: rectangle width\n - h: rectangle height\n - color: rectangle color\n - thickness: rectangle thickness(line width), by default(value is 1), -1 means fill rectangle\n\n\nReturns: this image object self\n" + }, + "args": [ + [ + "int", + "x", + null + ], + [ + "int", + "y", + null + ], + [ + "int", + "w", + null + ], + [ + "int", + "h", + null + ], + [ + "const image::Color &", + "color", + null + ], + [ + "int", + "thickness", + "1" + ] + ], + "ret_type": "image::Image*", + "static": false, + "def": "image::Image *draw_rect(int x, int y, int w, int h, const image::Color &color, int thickness = 1)" + }, + "draw_line": { + "type": "func", + "name": "draw_line", + "doc": { + "brief": "Draw line on image", + "param": { + "x1": "start point's coordinate x", + "y1": "start point's coordinate y", + "x2": "end point's coordinate x", + "y2": "end point's coordinate y", + "color": "line color @see image::Color", + "thickness": "line thickness(line width), by default(value is 1)" + }, + "return": "this image object self", + "maixpy": "maix.image.Image.draw_line", + "py_doc": "Draw line on image\n\nArgs:\n - x1: start point's coordinate x\n - y1: start point's coordinate y\n - x2: end point's coordinate x\n - y2: end point's coordinate y\n - color: line color @see image::Color\n - thickness: line thickness(line width), by default(value is 1)\n\n\nReturns: this image object self\n" + }, + "args": [ + [ + "int", + "x1", + null + ], + [ + "int", + "y1", + null + ], + [ + "int", + "x2", + null + ], + [ + "int", + "y2", + null + ], + [ + "const image::Color &", + "color", + null + ], + [ + "int", + "thickness", + "1" + ] + ], + "ret_type": "image::Image*", + "static": false, + "def": "image::Image *draw_line(int x1, int y1, int x2, int y2, const image::Color &color, int thickness = 1)" + }, + "draw_circle": { + "type": "func", + "name": "draw_circle", + "doc": { + "brief": "Draw circle on image", + "param": { + "x": "circle center point's coordinate x", + "y": "circle center point's coordinate y", + "radius": "circle radius", + "color": "circle color @see image::Color", + "thickness": "circle thickness(line width), default -1 means fill circle" + }, + "return": "this image object self", + "maixpy": "maix.image.Image.draw_circle", + "py_doc": "Draw circle on image\n\nArgs:\n - x: circle center point's coordinate x\n - y: circle center point's coordinate y\n - radius: circle radius\n - color: circle color @see image::Color\n - thickness: circle thickness(line width), default -1 means fill circle\n\n\nReturns: this image object self\n" + }, + "args": [ + [ + "int", + "x", + null + ], + [ + "int", + "y", + null + ], + [ + "int", + "radius", + null + ], + [ + "const image::Color &", + "color", + null + ], + [ + "int", + "thickness", + "1" + ] + ], + "ret_type": "image::Image*", + "static": false, + "def": "image::Image *draw_circle(int x, int y, int radius, const image::Color &color, int thickness = 1)" + }, + "draw_ellipse": { + "type": "func", + "name": "draw_ellipse", + "doc": { + "brief": "Draw ellipse on image", + "param": { + "x": "ellipse center point's coordinate x", + "y": "ellipse center point's coordinate y", + "a": "ellipse major axis length", + "b": "ellipse minor axis length", + "angle": "ellipse rotation angle", + "start_angle": "ellipse start angle", + "end_angle": "ellipse end angle", + "color": "ellipse color @see image::Color", + "thickness": "ellipse thickness(line width), by default(value is 1), -1 means fill ellipse" + }, + "return": "this image object self", + "maixpy": "maix.image.Image.draw_ellipse", + "py_doc": "Draw ellipse on image\n\nArgs:\n - x: ellipse center point's coordinate x\n - y: ellipse center point's coordinate y\n - a: ellipse major axis length\n - b: ellipse minor axis length\n - angle: ellipse rotation angle\n - start_angle: ellipse start angle\n - end_angle: ellipse end angle\n - color: ellipse color @see image::Color\n - thickness: ellipse thickness(line width), by default(value is 1), -1 means fill ellipse\n\n\nReturns: this image object self\n" + }, + "args": [ + [ + "int", + "x", + null + ], + [ + "int", + "y", + null + ], + [ + "int", + "a", + null + ], + [ + "int", + "b", + null + ], + [ + "float", + "angle", + null + ], + [ + "float", + "start_angle", + null + ], + [ + "float", + "end_angle", + null + ], + [ + "const image::Color &", + "color", + null + ], + [ + "int", + "thickness", + "1" + ] + ], + "ret_type": "image::Image*", + "static": false, + "def": "image::Image *draw_ellipse(int x, int y, int a, int b, float angle, float start_angle, float end_angle, const image::Color &color, int thickness = 1)" + }, + "draw_string": { + "type": "func", + "name": "draw_string", + "doc": { + "brief": "Draw text on image", + "param": { + "x": "text left top point's coordinate x", + "y": "text left top point's coordinate y", + "string": "text content", + "color": "text color @see image::Color, default is white", + "scale": "font scale, by default(value is 1)", + "thickness": "text thickness(line width), if negative, the glyph is filled, by default(value is -1)", + "wrap": "if true, will auto wrap text to next line if text width > image width, by default(value is true)" + }, + "return": "this image object self", + "maixpy": "maix.image.Image.draw_string", + "py_doc": "Draw text on image\n\nArgs:\n - x: text left top point's coordinate x\n - y: text left top point's coordinate y\n - string: text content\n - color: text color @see image::Color, default is white\n - scale: font scale, by default(value is 1)\n - thickness: text thickness(line width), if negative, the glyph is filled, by default(value is -1)\n - wrap: if true, will auto wrap text to next line if text width > image width, by default(value is true)\n\n\nReturns: this image object self\n" + }, + "args": [ + [ + "int", + "x", + null + ], + [ + "int", + "y", + null + ], + [ + "const std::string &", + "textstring", + null + ], + [ + "const image::Color &", + "color", + "image::COLOR_WHITE" + ], + [ + "float", + "scale", + "1" + ], + [ + "int", + "thickness", + "-1" + ], + [ + "bool", + "wrap", + "true" + ], + [ + "int", + "wrap_space", + "4" + ], + [ + "const std::string &", + "font", + "\"\"" + ] + ], + "ret_type": "image::Image*", + "static": false, + "def": "image::Image *draw_string(int x, int y, const std::string &textstring, const image::Color &color = image::COLOR_WHITE, float scale = 1, int thickness = -1,\n bool wrap = true, int wrap_space = 4, const std::string &font = \"\")" + }, + "draw_cross": { + "type": "func", + "name": "draw_cross", + "doc": { + "brief": "Draw cross on image", + "param": { + "x": "cross center point's coordinate x", + "y": "cross center point's coordinate y", + "color": "cross color @see image::Color", + "size": "how long the lines of the cross extend, by default(value is 5). So the line length is `2 * size + thickness`", + "thickness": "cross thickness(line width), by default(value is 1)" + }, + "maixpy": "maix.image.Image.draw_cross", + "py_doc": "Draw cross on image\n\nArgs:\n - x: cross center point's coordinate x\n - y: cross center point's coordinate y\n - color: cross color @see image::Color\n - size: how long the lines of the cross extend, by default(value is 5). So the line length is `2 * size + thickness`\n - thickness: cross thickness(line width), by default(value is 1)\n" + }, + "args": [ + [ + "int", + "x", + null + ], + [ + "int", + "y", + null + ], + [ + "const image::Color &", + "color", + null + ], + [ + "int", + "size", + "5" + ], + [ + "int", + "thickness", + "1" + ] + ], + "ret_type": "image::Image*", + "static": false, + "def": "image::Image *draw_cross(int x, int y, const image::Color &color, int size = 5, int thickness = 1)" + }, + "draw_arrow": { + "type": "func", + "name": "draw_arrow", + "doc": { + "brief": "Draw arrow on image", + "param": { + "x0": "start coordinate of the arrow x0", + "y0": "start coordinate of the arrow y0", + "x1": "end coordinate of the arrow x1", + "y1": "end coordinate of the arrow y1", + "color": "cross color @see image::Color", + "thickness": "cross thickness(line width), by default(value is 1)" + }, + "return": "this image object self", + "maixpy": "maix.image.Image.draw_arrow", + "py_doc": "Draw arrow on image\n\nArgs:\n - x0: start coordinate of the arrow x0\n - y0: start coordinate of the arrow y0\n - x1: end coordinate of the arrow x1\n - y1: end coordinate of the arrow y1\n - color: cross color @see image::Color\n - thickness: cross thickness(line width), by default(value is 1)\n\n\nReturns: this image object self\n" + }, + "args": [ + [ + "int", + "x0", + null + ], + [ + "int", + "y0", + null + ], + [ + "int", + "x1", + null + ], + [ + "int", + "y1", + null + ], + [ + "const image::Color &", + "color", + null + ], + [ + "int", + "thickness", + "1" + ] + ], + "ret_type": "image::Image*", + "static": false, + "def": "image::Image *draw_arrow(int x0, int y0, int x1, int y1, const image::Color &color, int thickness = 1)" + }, + "draw_edges": { + "type": "func", + "name": "draw_edges", + "doc": { + "brief": "Draw edges on image", + "param": { + "corners": "edges, [[x0, y0], [x1, y1], [x2, y2], [x3, y3]]", + "color": "edges color @see image::Color", + "size": "the circle of radius size. TODO: support in the feature", + "thickness": "edges thickness(line width), by default(value is 1)", + "fill": "if true, will fill edges, by default(value is false)" + }, + "return": "this image object self", + "maixpy": "maix.image.Image.draw_edges", + "py_doc": "Draw edges on image\n\nArgs:\n - corners: edges, [[x0, y0], [x1, y1], [x2, y2], [x3, y3]]\n - color: edges color @see image::Color\n - size: the circle of radius size. TODO: support in the feature\n - thickness: edges thickness(line width), by default(value is 1)\n - fill: if true, will fill edges, by default(value is false)\n\n\nReturns: this image object self\n" + }, + "args": [ + [ + "std::vector>", + "corners", + null + ], + [ + "const image::Color &", + "color", + null + ], + [ + "int", + "size", + "0" + ], + [ + "int", + "thickness", + "1" + ], + [ + "bool", + "fill", + "false" + ] + ], + "ret_type": "image::Image*", + "static": false, + "def": "image::Image *draw_edges(std::vector> corners, const image::Color &color, int size = 0, int thickness = 1, bool fill = false)" + }, + "draw_keypoints": { + "type": "func", + "name": "draw_keypoints", + "doc": { + "brief": "Draw keypoints on image", + "param": { + "keypoints": "keypoints, [x1, y1, x2, y2...] or [x, y, rotation_andle_in_degrees, x2, y2, rotation_andle_in_degrees2](TODO: rotation_andle_in_degrees support in the feature)", + "color": "keypoints color @see image::Color", + "size": "size of keypoints(radius)", + "thickness": "keypoints thickness(line width), by default(value is -1 means fill circle)", + "line_thickness": "line thickness, default 0 means not draw lines, > 0 will draw lines connect points." + }, + "return": "this image object self", + "maixpy": "maix.image.Image.draw_keypoints", + "py_doc": "Draw keypoints on image\n\nArgs:\n - keypoints: keypoints, [x1, y1, x2, y2...] or [x, y, rotation_andle_in_degrees, x2, y2, rotation_andle_in_degrees2](TODO: rotation_andle_in_degrees support in the feature)\n - color: keypoints color @see image::Color\n - size: size of keypoints(radius)\n - thickness: keypoints thickness(line width), by default(value is -1 means fill circle)\n - line_thickness: line thickness, default 0 means not draw lines, > 0 will draw lines connect points.\n\n\nReturns: this image object self\n" + }, + "args": [ + [ + "const std::vector &", + "keypoints", + null + ], + [ + "const image::Color &", + "color", + null + ], + [ + "int", + "size", + "4" + ], + [ + "int", + "thickness", + "-1" + ], + [ + "int", + "line_thickness", + "0" + ] + ], + "ret_type": "image::Image*", + "static": false, + "def": "image::Image *draw_keypoints(const std::vector &keypoints, const image::Color &color, int size = 4, int thickness = -1, int line_thickness = 0)" + }, + "resize": { + "type": "func", + "name": "resize", + "doc": { + "brief": "Resize image, will create a new resized image object", + "param": { + "width": "new width, if value is -1, will use height to calculate aspect ratio", + "height": "new height, if value is -1, will use width to calculate aspect ratio", + "object_fit": "fill, contain, cover, by default is fill", + "method": "resize method, by default is NEAREST" + }, + "return": "Always return a new resized image object even size not change, So in C++ you should take care of the return value to avoid memory leak.\nAnd it's better to judge whether the size has changed before calling this function to make the program more efficient.\ne.g.\nif img->width() != width || img->height() != height:\nimg = img->resize(width, height);", + "maixpy": "maix.image.Image.resize", + "py_doc": "Resize image, will create a new resized image object\n\nArgs:\n - width: new width, if value is -1, will use height to calculate aspect ratio\n - height: new height, if value is -1, will use width to calculate aspect ratio\n - object_fit: fill, contain, cover, by default is fill\n - method: resize method, by default is NEAREST\n\n\nReturns: Always return a new resized image object even size not change, So in C++ you should take care of the return value to avoid memory leak.\nAnd it's better to judge whether the size has changed before calling this function to make the program more efficient.\ne.g.\nif img->width() != width || img->height() != height:\nimg = img->resize(width, height);\n" + }, + "args": [ + [ + "int", + "width", + null + ], + [ + "int", + "height", + null + ], + [ + "image::Fit", + "object_fit", + "image::Fit::FIT_FILL" + ], + [ + "image::ResizeMethod", + "method", + "image::ResizeMethod::NEAREST" + ] + ], + "ret_type": "image::Image*", + "static": false, + "def": "image::Image *resize(int width, int height, image::Fit object_fit = image::Fit::FIT_FILL, image::ResizeMethod method = image::ResizeMethod::NEAREST)" + }, + "affine": { + "type": "func", + "name": "affine", + "doc": { + "brief": "Affine transform image, will create a new transformed image object, need 3 points.", + "param": { + "src_points": "three source points, [x1, y1, x2, y2, x3, y3]", + "dst_points": "three destination points, [x1, y1, x2, y2, x3, y3]", + "width": "new width, if value is -1, will use height to calculate aspect ratio", + "height": "new height, if value is -1, will use width to calculate aspect ratio", + "method": "resize method, by default is bilinear" + }, + "return": "new transformed image object", + "maixpy": "maix.image.Image.affine", + "py_doc": "Affine transform image, will create a new transformed image object, need 3 points.\n\nArgs:\n - src_points: three source points, [x1, y1, x2, y2, x3, y3]\n - dst_points: three destination points, [x1, y1, x2, y2, x3, y3]\n - width: new width, if value is -1, will use height to calculate aspect ratio\n - height: new height, if value is -1, will use width to calculate aspect ratio\n - method: resize method, by default is bilinear\n\n\nReturns: new transformed image object\n" + }, + "args": [ + [ + "std::vector", + "src_points", + null + ], + [ + "std::vector", + "dst_points", + null + ], + [ + "int", + "width", + "-1" + ], + [ + "int", + "height", + "-1" + ], + [ + "image::ResizeMethod", + "method", + "image::ResizeMethod::BILINEAR" + ] + ], + "ret_type": "image::Image*", + "static": false, + "def": "image::Image *affine(std::vector src_points, std::vector dst_points, int width = -1, int height = -1, image::ResizeMethod method = image::ResizeMethod::BILINEAR)", + "overload": [ + { + "type": "func", + "name": "perspective", + "doc": { + "brief": "Perspective transform image, will create a new transformed image object, need 4 points.", + "param": { + "src_points": "three source points, [x1, y1, x2, y2, x3, y3, x4, y4]", + "dst_points": "three destination points, [x1, y1, x2, y2, x3, y3, x4, y4]", + "width": "new width, if value is -1, will use height to calculate aspect ratio", + "height": "new height, if value is -1, will use width to calculate aspect ratio", + "method": "resize method, by default is bilinear" + }, + "return": "new transformed image object", + "maixpy": "maix.image.Image.affine", + "py_doc": "Perspective transform image, will create a new transformed image object, need 4 points.\n\nArgs:\n - src_points: three source points, [x1, y1, x2, y2, x3, y3, x4, y4]\n - dst_points: three destination points, [x1, y1, x2, y2, x3, y3, x4, y4]\n - width: new width, if value is -1, will use height to calculate aspect ratio\n - height: new height, if value is -1, will use width to calculate aspect ratio\n - method: resize method, by default is bilinear\n\n\nReturns: new transformed image object\n" + }, + "args": [ + [ + "std::vector", + "src_points", + null + ], + [ + "std::vector", + "dst_points", + null + ], + [ + "int", + "width", + "-1" + ], + [ + "int", + "height", + "-1" + ], + [ + "image::ResizeMethod", + "method", + "image::ResizeMethod::BILINEAR" + ] + ], + "ret_type": "image::Image*", + "static": false, + "def": "image::Image* perspective(std::vector src_points, std::vector dst_points, int width = -1, int height = -1, image::ResizeMethod method = image::ResizeMethod::BILINEAR)" + } + ] + }, + "copy": { + "type": "func", + "name": "copy", + "doc": { + "brief": "Copy image, will create a new copied image object", + "return": "new copied image object", + "maixpy": "maix.image.Image.copy", + "py_doc": "Copy image, will create a new copied image object\n\nReturns: new copied image object\n" + }, + "args": [], + "ret_type": "image::Image*", + "static": false, + "def": "image::Image *copy()" + }, + "crop": { + "type": "func", + "name": "crop", + "doc": { + "brief": "Crop image, will create a new cropped image object", + "param": { + "x": "left top corner of crop rectangle point's coordinate x", + "y": "left top corner of crop rectangle point's coordinate y", + "w": "crop rectangle width", + "h": "crop rectangle height" + }, + "return": "new cropped image object", + "maixpy": "maix.image.Image.crop", + "py_doc": "Crop image, will create a new cropped image object\n\nArgs:\n - x: left top corner of crop rectangle point's coordinate x\n - y: left top corner of crop rectangle point's coordinate y\n - w: crop rectangle width\n - h: crop rectangle height\n\n\nReturns: new cropped image object\n" + }, + "args": [ + [ + "int", + "x", + null + ], + [ + "int", + "y", + null + ], + [ + "int", + "w", + null + ], + [ + "int", + "h", + null + ] + ], + "ret_type": "image::Image*", + "static": false, + "def": "image::Image *crop(int x, int y, int w, int h)" + }, + "rotate": { + "type": "func", + "name": "rotate", + "doc": { + "brief": "Rotate image, will create a new rotated image object", + "param": { + "angle": "anti-clock wise rotate angle, if angle is 90 or 270, and width or height is -1, will swap width and height, or will throw exception", + "width": "new width, if value is -1, will use height to calculate aspect ratio", + "height": "new height, if value is -1, will use width to calculate aspect ratio", + "method": "resize method, by default is bilinear" + }, + "return": "new rotated image object", + "maixpy": "maix.image.Image.rotate", + "py_doc": "Rotate image, will create a new rotated image object\n\nArgs:\n - angle: anti-clock wise rotate angle, if angle is 90 or 270, and width or height is -1, will swap width and height, or will throw exception\n - width: new width, if value is -1, will use height to calculate aspect ratio\n - height: new height, if value is -1, will use width to calculate aspect ratio\n - method: resize method, by default is bilinear\n\n\nReturns: new rotated image object\n" + }, + "args": [ + [ + "float", + "angle", + null + ], + [ + "int", + "width", + "-1" + ], + [ + "int", + "height", + "-1" + ], + [ + "image::ResizeMethod", + "method", + "image::ResizeMethod::BILINEAR" + ] + ], + "ret_type": "image::Image*", + "static": false, + "def": "image::Image *rotate(float angle, int width = -1, int height = -1, image::ResizeMethod method = image::ResizeMethod::BILINEAR)" + }, + "flip": { + "type": "func", + "name": "flip", + "doc": { + "brief": "Vertical flip image, and return a new image.", + "param": { + "dir": "flip dir, see image.FlipDir, e.g. image.FlipDir.X is vertical flip." + }, + "return": "new flipped image.", + "throw": "When arg error, will throw out err.Err exception.", + "maixpy": "maix.image.Image.flip", + "py_doc": "Vertical flip image, and return a new image.\n\nArgs:\n - dir: flip dir, see image.FlipDir, e.g. image.FlipDir.X is vertical flip.\n\n\nReturns: new flipped image.\n" + }, + "args": [ + [ + "const image::FlipDir", + "dir", + null + ] + ], + "ret_type": "image::Image*", + "static": false, + "def": "image::Image *flip(const image::FlipDir dir)" + }, + "mean_pool": { + "type": "func", + "name": "mean_pool", + "doc": { + "brief": "Finds the mean of x_div * y_div squares in the image and returns the modified image composed of the mean of each square.", + "param": { + "x_div": "The width of the squares.", + "y_div": "The height of the squares.", + "copy": "Select whether to return a new image or modify the original image. default is false.\nIf true, returns a new image composed of the mean of each square; If false, returns the modified image composed of the mean of each square." + }, + "return": "Returns the image after the operation is completed.", + "maixpy": "maix.image.Image.mean_pool", + "py_doc": "Finds the mean of x_div * y_div squares in the image and returns the modified image composed of the mean of each square.\n\nArgs:\n - x_div: The width of the squares.\n - y_div: The height of the squares.\n - copy: Select whether to return a new image or modify the original image. default is false.\nIf true, returns a new image composed of the mean of each square; If false, returns the modified image composed of the mean of each square.\n\n\nReturns: Returns the image after the operation is completed.\n" + }, + "args": [ + [ + "int", + "x_div", + null + ], + [ + "int", + "y_div", + null + ], + [ + "bool", + "copy", + "false" + ] + ], + "ret_type": "image::Image*", + "static": false, + "def": "image::Image *mean_pool(int x_div, int y_div, bool copy = false)" + }, + "midpoint_pool": { + "type": "func", + "name": "midpoint_pool", + "doc": { + "brief": "Finds the midpoint of x_div * y_div squares in the image and returns the modified image composed of the mean of each square.", + "param": { + "x_div": "The width of the squares.", + "y_div": "The height of the squares.", + "bias": "The bias of the midpoint. default is 0.5.\nmidpoint value is equal to (max * bias + min * (1 - bias))", + "copy": "Select whether to return a new image or modify the original image. default is false.\nIf true, returns a new image composed of the midpoint of each square; If false, returns the modified image composed of the midpoint of each square." + }, + "return": "Returns the image after the operation is completed.", + "maixpy": "maix.image.Image.midpoint_pool", + "py_doc": "Finds the midpoint of x_div * y_div squares in the image and returns the modified image composed of the mean of each square.\n\nArgs:\n - x_div: The width of the squares.\n - y_div: The height of the squares.\n - bias: The bias of the midpoint. default is 0.5.\nmidpoint value is equal to (max * bias + min * (1 - bias))\n - copy: Select whether to return a new image or modify the original image. default is false.\nIf true, returns a new image composed of the midpoint of each square; If false, returns the modified image composed of the midpoint of each square.\n\n\nReturns: Returns the image after the operation is completed.\n" + }, + "args": [ + [ + "int", + "x_div", + null + ], + [ + "int", + "y_div", + null + ], + [ + "double", + "bias", + "0.5" + ], + [ + "bool", + "copy", + "false" + ] + ], + "ret_type": "image::Image*", + "static": false, + "def": "image::Image *midpoint_pool(int x_div, int y_div, double bias = 0.5, bool copy = false)" + }, + "compress": { + "type": "func", + "name": "compress", + "doc": { + "brief": "JPEG compresses the image in place, the same as to_jpeg functioin, it's recommend to use to_jpeg instead.", + "param": { + "quality": "The quality of the compressed image. default is 95." + }, + "return": "Returns the compressed JPEG image", + "maixpy": "maix.image.Image.compress", + "py_doc": "JPEG compresses the image in place, the same as to_jpeg functioin, it's recommend to use to_jpeg instead.\n\nArgs:\n - quality: The quality of the compressed image. default is 95.\n\n\nReturns: Returns the compressed JPEG image\n" + }, + "args": [ + [ + "int", + "quality", + "95" + ] + ], + "ret_type": "image::Image*", + "static": false, + "def": "image::Image *compress(int quality = 95)" + }, + "clear": { + "type": "func", + "name": "clear", + "doc": { + "brief": "Sets all pixels in the image to zero", + "param": { + "mask": "Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.\nOnly pixels set in the mask are modified. default is None." + }, + "return": "Returns the image after the operation is completed.", + "maixpy": "maix.image.Image.clear", + "py_doc": "Sets all pixels in the image to zero\n\nArgs:\n - mask: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.\nOnly pixels set in the mask are modified. default is None.\n\n\nReturns: Returns the image after the operation is completed.\n" + }, + "args": [ + [ + "image::Image *", + "mask", + "nullptr" + ] + ], + "ret_type": "image::Image*", + "static": false, + "def": "image::Image *clear(image::Image *mask = nullptr)" + }, + "mask_rectange": { + "type": "func", + "name": "mask_rectange", + "doc": { + "brief": "Zeros a rectangular part of the image. If no arguments are supplied this method zeros the center of the image.", + "param": { + "x": "The x coordinate of the top left corner of the rectangle.", + "y": "The y coordinate of the top left corner of the rectangle.", + "w": "The width of the rectangle.", + "h": "The height of the rectangle." + }, + "return": "Returns the image after the operation is completed.", + "maixpy": "maix.image.Image.mask_rectange", + "py_doc": "Zeros a rectangular part of the image. If no arguments are supplied this method zeros the center of the image.\n\nArgs:\n - x: The x coordinate of the top left corner of the rectangle.\n - y: The y coordinate of the top left corner of the rectangle.\n - w: The width of the rectangle.\n - h: The height of the rectangle.\n\n\nReturns: Returns the image after the operation is completed.\n" + }, + "args": [ + [ + "int", + "x", + "-1" + ], + [ + "int", + "y", + "-1" + ], + [ + "int", + "w", + "-1" + ], + [ + "int", + "h", + "-1" + ] + ], + "ret_type": "image::Image*", + "static": false, + "def": "image::Image *mask_rectange(int x = -1, int y = -1, int w = -1, int h = -1)" + }, + "mask_circle": { + "type": "func", + "name": "mask_circle", + "doc": { + "brief": "Zeros a circular part of the image. If no arguments are supplied this method zeros the center of the image.", + "param": { + "x": "The x coordinate of the center of the circle.", + "y": "The y coordinate of the center of the circle.", + "radius": "The radius of the circle." + }, + "return": "Returns the image after the operation is completed.", + "maixpy": "maix.image.Image.mask_circle", + "py_doc": "Zeros a circular part of the image. If no arguments are supplied this method zeros the center of the image.\n\nArgs:\n - x: The x coordinate of the center of the circle.\n - y: The y coordinate of the center of the circle.\n - radius: The radius of the circle.\n\n\nReturns: Returns the image after the operation is completed.\n" + }, + "args": [ + [ + "int", + "x", + "-1" + ], + [ + "int", + "y", + "-1" + ], + [ + "int", + "radius", + "-1" + ] + ], + "ret_type": "image::Image*", + "static": false, + "def": "image::Image *mask_circle(int x = -1, int y = -1, int radius = -1)" + }, + "mask_ellipse": { + "type": "func", + "name": "mask_ellipse", + "doc": { + "brief": "Zeros a ellipse part of the image. If no arguments are supplied this method zeros the center of the image.", + "param": { + "x": "The x coordinate of the center of the ellipse.", + "y": "The y coordinate of the center of the ellipse.", + "radius_x": "The radius of the ellipse in the x direction.", + "radius_y": "The radius of the ellipse in the y direction.", + "rotation_angle_in_degrees": "The rotation angle of the ellipse in degrees." + }, + "return": "Returns the image after the operation is completed.", + "maixpy": "maix.image.Image.mask_ellipse", + "py_doc": "Zeros a ellipse part of the image. If no arguments are supplied this method zeros the center of the image.\n\nArgs:\n - x: The x coordinate of the center of the ellipse.\n - y: The y coordinate of the center of the ellipse.\n - radius_x: The radius of the ellipse in the x direction.\n - radius_y: The radius of the ellipse in the y direction.\n - rotation_angle_in_degrees: The rotation angle of the ellipse in degrees.\n\n\nReturns: Returns the image after the operation is completed.\n" + }, + "args": [ + [ + "int", + "x", + "-1" + ], + [ + "int", + "y", + "-1" + ], + [ + "int", + "radius_x", + "-1" + ], + [ + "int", + "radius_y", + "-1" + ], + [ + "float", + "rotation_angle_in_degrees", + "0" + ] + ], + "ret_type": "image::Image*", + "static": false, + "def": "image::Image *mask_ellipse(int x = -1, int y = -1, int radius_x = -1, int radius_y = -1, float rotation_angle_in_degrees = 0)" + }, + "binary": { + "type": "func", + "name": "binary", + "doc": { + "brief": "Sets all pixels in the image to black or white depending on if the pixel is inside of a threshold in the threshold list thresholds or not.", + "note": "For GRAYSCALE format, Lmin and Lmax range is [0, 255]. For RGB888 format, Lmin and Lmax range is [0, 100].", + "param": { + "thresholds": "You can define multiple thresholds.\nFor GRAYSCALE format, you can use {{Lmin, Lmax}, ...} to define one or more thresholds.\nFor RGB888 format, you can use {{Lmin, Lmax, Amin, Amax, Bmin, Bmax}, ...} to define one or more thresholds.\nWhere the upper case L,A,B represent the L,A,B channels of the LAB image format, and min, max represent the minimum and maximum values of the corresponding channels.", + "invert": "If true, the thresholds will be inverted before the operation. default is false.", + "zero": "If zero is true, the image will be set the pixels within the threshold to 0, other pixels remain unchanged. If zero is false, the image will be set to black or white. default is false.", + "mask": "Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.\nOnly pixels set in the mask are modified. default is None.", + "to_bitmap": "If true, the image will be converted to a bitmap image before thresholding. default is false. TODO: support in the feature", + "copy": "Select whether to return a new image or modify the original image. default is false." + }, + "return": "Returns the image after the operation is completed.", + "maixpy": "maix.image.Image.binary", + "py_doc": "Sets all pixels in the image to black or white depending on if the pixel is inside of a threshold in the threshold list thresholds or not.\n\nArgs:\n - thresholds: You can define multiple thresholds.\nFor GRAYSCALE format, you can use {{Lmin, Lmax}, ...} to define one or more thresholds.\nFor RGB888 format, you can use {{Lmin, Lmax, Amin, Amax, Bmin, Bmax}, ...} to define one or more thresholds.\nWhere the upper case L,A,B represent the L,A,B channels of the LAB image format, and min, max represent the minimum and maximum values of the corresponding channels.\n - invert: If true, the thresholds will be inverted before the operation. default is false.\n - zero: If zero is true, the image will be set the pixels within the threshold to 0, other pixels remain unchanged. If zero is false, the image will be set to black or white. default is false.\n - mask: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.\nOnly pixels set in the mask are modified. default is None.\n - to_bitmap: If true, the image will be converted to a bitmap image before thresholding. default is false. TODO: support in the feature\n - copy: Select whether to return a new image or modify the original image. default is false.\n\n\nReturns: Returns the image after the operation is completed.\n" + }, + "args": [ + [ + "std::vector>", + "thresholds", + "std::vector>()" + ], + [ + "bool", + "invert", + "false" + ], + [ + "bool", + "zero", + "false" + ], + [ + "image::Image *", + "mask", + "nullptr" + ], + [ + "bool", + "to_bitmap", + "false" + ], + [ + "bool", + "copy", + "false" + ] + ], + "ret_type": "image::Image*", + "static": false, + "def": "image::Image *binary(std::vector> thresholds = std::vector>(), bool invert = false, bool zero = false, image::Image *mask = nullptr, bool to_bitmap = false, bool copy = false)" + }, + "invert": { + "type": "func", + "name": "invert", + "doc": { + "brief": "Inverts the image in place.", + "return": "Returns the image after the operation is completed", + "maixpy": "maix.image.Image.invert", + "py_doc": "Inverts the image in place.\n\nReturns: Returns the image after the operation is completed\n" + }, + "args": [], + "ret_type": "image::Image*", + "static": false, + "def": "image::Image *invert()" + }, + "b_and": { + "type": "func", + "name": "b_and", + "doc": { + "brief": "Performs a bitwise and operation between the image and the other image.", + "param": { + "other": "The other image should be an image and should be the same size as the image being operated on. TODO: support path?", + "mask": "Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.\nOnly pixels set in the mask are modified. default is None." + }, + "return": "Returns the image after the operation is completed.", + "maixpy": "maix.image.Image.b_and", + "py_doc": "Performs a bitwise and operation between the image and the other image.\n\nArgs:\n - other: The other image should be an image and should be the same size as the image being operated on. TODO: support path?\n - mask: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.\nOnly pixels set in the mask are modified. default is None.\n\n\nReturns: Returns the image after the operation is completed.\n" + }, + "args": [ + [ + "image::Image *", + "other", + null + ], + [ + "image::Image *", + "mask", + "nullptr" + ] + ], + "ret_type": "image::Image*", + "static": false, + "def": "image::Image *b_and(image::Image *other, image::Image *mask = nullptr)" + }, + "b_nand": { + "type": "func", + "name": "b_nand", + "doc": { + "brief": "Performs a bitwise nand operation between the image and the other image.", + "param": { + "other": "The other image should be an image and should be the same size as the image being operated on. TODO: support path?", + "mask": "Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.\nOnly pixels set in the mask are modified. default is None." + }, + "return": "Returns the image after the operation is completed.", + "maixpy": "maix.image.Image.b_nand", + "py_doc": "Performs a bitwise nand operation between the image and the other image.\n\nArgs:\n - other: The other image should be an image and should be the same size as the image being operated on. TODO: support path?\n - mask: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.\nOnly pixels set in the mask are modified. default is None.\n\n\nReturns: Returns the image after the operation is completed.\n" + }, + "args": [ + [ + "image::Image *", + "other", + null + ], + [ + "image::Image *", + "mask", + "nullptr" + ] + ], + "ret_type": "image::Image*", + "static": false, + "def": "image::Image *b_nand(image::Image *other, image::Image *mask = nullptr)" + }, + "b_or": { + "type": "func", + "name": "b_or", + "doc": { + "brief": "Performs a bitwise or operation between the image and the other image.", + "param": { + "other": "The other image should be an image and should be the same size as the image being operated on. TODO: support path?", + "mask": "Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.\nOnly pixels set in the mask are modified. default is None." + }, + "return": "Returns the image after the operation is completed.", + "maixpy": "maix.image.Image.b_or", + "py_doc": "Performs a bitwise or operation between the image and the other image.\n\nArgs:\n - other: The other image should be an image and should be the same size as the image being operated on. TODO: support path?\n - mask: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.\nOnly pixels set in the mask are modified. default is None.\n\n\nReturns: Returns the image after the operation is completed.\n" + }, + "args": [ + [ + "image::Image *", + "other", + null + ], + [ + "image::Image *", + "mask", + "nullptr" + ] + ], + "ret_type": "image::Image*", + "static": false, + "def": "image::Image *b_or(image::Image *other, image::Image *mask = nullptr)" + }, + "b_nor": { + "type": "func", + "name": "b_nor", + "doc": { + "brief": "Performs a bitwise nor operation between the image and the other image.", + "param": { + "other": "The other image should be an image and should be the same size as the image being operated on. TODO: support path?", + "mask": "Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.\nOnly pixels set in the mask are modified. default is None." + }, + "return": "Returns the image after the operation is completed.", + "maixpy": "maix.image.Image.b_nor", + "py_doc": "Performs a bitwise nor operation between the image and the other image.\n\nArgs:\n - other: The other image should be an image and should be the same size as the image being operated on. TODO: support path?\n - mask: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.\nOnly pixels set in the mask are modified. default is None.\n\n\nReturns: Returns the image after the operation is completed.\n" + }, + "args": [ + [ + "image::Image *", + "other", + null + ], + [ + "image::Image *", + "mask", + "nullptr" + ] + ], + "ret_type": "image::Image*", + "static": false, + "def": "image::Image *b_nor(image::Image *other, image::Image *mask = nullptr)" + }, + "b_xor": { + "type": "func", + "name": "b_xor", + "doc": { + "brief": "Performs a bitwise xor operation between the image and the other image.", + "param": { + "other": "The other image should be an image and should be the same size as the image being operated on. TODO: support path?", + "mask": "Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.\nOnly pixels set in the mask are modified. default is None." + }, + "return": "Returns the image after the operation is completed.", + "maixpy": "maix.image.Image.b_xor", + "py_doc": "Performs a bitwise xor operation between the image and the other image.\n\nArgs:\n - other: The other image should be an image and should be the same size as the image being operated on. TODO: support path?\n - mask: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.\nOnly pixels set in the mask are modified. default is None.\n\n\nReturns: Returns the image after the operation is completed.\n" + }, + "args": [ + [ + "image::Image *", + "other", + null + ], + [ + "image::Image *", + "mask", + "nullptr" + ] + ], + "ret_type": "image::Image*", + "static": false, + "def": "image::Image *b_xor(image::Image *other, image::Image *mask = nullptr)" + }, + "b_xnor": { + "type": "func", + "name": "b_xnor", + "doc": { + "brief": "Performs a bitwise xnor operation between the image and the other image.", + "param": { + "other": "The other image should be an image and should be the same size as the image being operated on. TODO: support path?", + "mask": "Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.\nOnly pixels set in the mask are modified. default is None." + }, + "return": "Returns the image after the operation is completed.", + "maixpy": "maix.image.Image.b_xnor", + "py_doc": "Performs a bitwise xnor operation between the image and the other image.\n\nArgs:\n - other: The other image should be an image and should be the same size as the image being operated on. TODO: support path?\n - mask: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.\nOnly pixels set in the mask are modified. default is None.\n\n\nReturns: Returns the image after the operation is completed.\n" + }, + "args": [ + [ + "image::Image *", + "other", + null + ], + [ + "image::Image *", + "mask", + "nullptr" + ] + ], + "ret_type": "image::Image*", + "static": false, + "def": "image::Image *b_xnor(image::Image *other, image::Image *mask = nullptr)" + }, + "awb": { + "type": "func", + "name": "awb", + "doc": { + "brief": "Performs an auto white balance operation on the image. TODO: support in the feature", + "param": { + "max": "if True uses the white-patch algorithm instead. default is false." + }, + "return": "Returns the image after the operation is completed.", + "maixpy": "maix.image.Image.awb", + "py_doc": "Performs an auto white balance operation on the image. TODO: support in the feature\n\nArgs:\n - max: if True uses the white-patch algorithm instead. default is false.\n\n\nReturns: Returns the image after the operation is completed.\n" + }, + "args": [ + [ + "bool", + "max", + "false" + ] + ], + "ret_type": "image::Image*", + "static": false, + "def": "image::Image *awb(bool max = false)" + }, + "ccm": { + "type": "func", + "name": "ccm", + "doc": { + "brief": "Multiples the passed (3x3) or (4x3) floating-point color-correction-matrix with the image.\\nnote: Grayscale format is not support.", + "param": { + "matrix": "The color correction matrix to use. 3x3 or 4x3 matrix.\nWeights may either be positive or negative, and the sum of each column in the 3x3 matrix should generally be 1.\nexample:\n{\n1, 0, 0,\n0, 1, 0,\n0, 0, 1,\n}\nWhere the last row of the 4x3 matrix is an offset per color channel. If you add an offset you may wish to make the\nweights sum to less than 1 to account for the offset.\nexample:\n{\n1, 0, 0,\n0, 1, 0,\n0, 0, 1,\n0, 0, 0,\n}" + }, + "return": "Returns the image after the operation is completed.", + "maixpy": "maix.image.Image.ccm", + "py_doc": "Multiples the passed (3x3) or (4x3) floating-point color-correction-matrix with the image.\nnote: Grayscale format is not support.\n\nArgs:\n - matrix: The color correction matrix to use. 3x3 or 4x3 matrix.\nWeights may either be positive or negative, and the sum of each column in the 3x3 matrix should generally be 1.\nexample:\n{\n1, 0, 0,\n0, 1, 0,\n0, 0, 1,\n}\nWhere the last row of the 4x3 matrix is an offset per color channel. If you add an offset you may wish to make the\nweights sum to less than 1 to account for the offset.\nexample:\n{\n1, 0, 0,\n0, 1, 0,\n0, 0, 1,\n0, 0, 0,\n}\n\n\nReturns: Returns the image after the operation is completed.\n" + }, + "args": [ + [ + "std::vector &", + "matrix", + null + ] + ], + "ret_type": "image::Image*", + "static": false, + "def": "image::Image *ccm(std::vector &matrix)" + }, + "gamma": { + "type": "func", + "name": "gamma", + "doc": { + "brief": "Quickly changes the image gamma, contrast, and brightness. Create a array whose size is usually 255,\\nand use the parameters gamma, contrast, and brightness to calculate the value of the array, and then map the\\nimage pixel value through the value of the array.\\nThe calculation method for array is: array[array_idx] = (powf((array_idx / 255.0), (1 / gamma)) * contrast + brightness) * scale,\\n`powf` is a function used to calculate floating point power.\\n`array` is the array used for mapping.\\n`array_idx` is the index of the array, the maximum value is determined according to the image format, usually 255.\\n`scale` is a constant, the value is determined by the image format, usually 255.\\nMapping method:\\nAssume that a pixel value in the image is 128, then map the pixel value to the value of array[128]\\nUsers can adjust the value of the array through the gamma, contrast, and brightness parameters.", + "param": { + "gamma": "The contrast gamma greater than 1.0 makes the image darker in a non-linear manner while less than 1.0 makes the image brighter. default is 1.0.", + "contrast": "The contrast value greater than 1.0 makes the image brighter in a linear manner while less than 1.0 makes the image darker. default is 1.0.", + "brightness": "The brightness value greater than 0.0 makes the image brighter in a constant manner while less than 0.0 makes the image darker. default is 0.0." + }, + "return": "Returns the image after the operation is completed.", + "maixpy": "maix.image.Image.gamma", + "py_doc": "Quickly changes the image gamma, contrast, and brightness. Create a array whose size is usually 255,\nand use the parameters gamma, contrast, and brightness to calculate the value of the array, and then map the\nimage pixel value through the value of the array.\nThe calculation method for array is: array[array_idx] = (powf((array_idx / 255.0), (1 / gamma)) * contrast + brightness) * scale,\n`powf` is a function used to calculate floating point power.\n`array` is the array used for mapping.\n`array_idx` is the index of the array, the maximum value is determined according to the image format, usually 255.\n`scale` is a constant, the value is determined by the image format, usually 255.\nMapping method:\nAssume that a pixel value in the image is 128, then map the pixel value to the value of array[128]\nUsers can adjust the value of the array through the gamma, contrast, and brightness parameters.\n\nArgs:\n - gamma: The contrast gamma greater than 1.0 makes the image darker in a non-linear manner while less than 1.0 makes the image brighter. default is 1.0.\n - contrast: The contrast value greater than 1.0 makes the image brighter in a linear manner while less than 1.0 makes the image darker. default is 1.0.\n - brightness: The brightness value greater than 0.0 makes the image brighter in a constant manner while less than 0.0 makes the image darker. default is 0.0.\n\n\nReturns: Returns the image after the operation is completed.\n" + }, + "args": [ + [ + "double", + "gamma", + "1.0" + ], + [ + "double", + "contrast", + "1.0" + ], + [ + "double", + "brightness", + "0.0" + ] + ], + "ret_type": "image::Image*", + "static": false, + "def": "image::Image *gamma(double gamma = 1.0, double contrast = 1.0, double brightness = 0.0)" + }, + "gamma_corr": { + "type": "func", + "name": "gamma_corr", + "doc": { + "brief": "Alias for Image.gamma.", + "param": { + "gamma": "The contrast gamma greater than 1.0 makes the image darker in a non-linear manner while less than 1.0 makes the image brighter. default is 1.0.", + "contrast": "The contrast value greater than 1.0 makes the image brighter in a linear manner while less than 1.0 makes the image darker. default is 1.0.", + "brightness": "The brightness value greater than 0.0 makes the image brighter in a constant manner while less than 0.0 makes the image darker. default is 0.0." + }, + "return": "Returns the image after the operation is completed.", + "maixpy": "maix.image.Image.gamma_corr", + "py_doc": "Alias for Image.gamma.\n\nArgs:\n - gamma: The contrast gamma greater than 1.0 makes the image darker in a non-linear manner while less than 1.0 makes the image brighter. default is 1.0.\n - contrast: The contrast value greater than 1.0 makes the image brighter in a linear manner while less than 1.0 makes the image darker. default is 1.0.\n - brightness: The brightness value greater than 0.0 makes the image brighter in a constant manner while less than 0.0 makes the image darker. default is 0.0.\n\n\nReturns: Returns the image after the operation is completed.\n" + }, + "args": [ + [ + "double", + "gamma", + null + ], + [ + "double", + "contrast", + "1.0" + ], + [ + "double", + "brightness", + "0.0" + ] + ], + "ret_type": "image::Image*", + "static": false, + "def": "image::Image *gamma_corr(double gamma, double contrast = 1.0, double brightness = 0.0)" + }, + "negate": { + "type": "func", + "name": "negate", + "doc": { + "brief": "Flips (numerically inverts) all pixels values in an image", + "return": "Returns the image after the operation is completed.", + "maixpy": "maix.image.Image.negate", + "py_doc": "Flips (numerically inverts) all pixels values in an image\n\nReturns: Returns the image after the operation is completed.\n" + }, + "args": [], + "ret_type": "image::Image*", + "static": false, + "def": "image::Image *negate()" + }, + "replace": { + "type": "func", + "name": "replace", + "doc": { + "brief": "Replaces all pixels in the image with the corresponding pixels in the other image.", + "param": { + "other": "The other image should be an image and should be the same size as the image being operated on.", + "hmirror": "If true, the image will be horizontally mirrored before the operation. default is false.", + "vflip": "If true, the image will be vertically flipped before the operation. default is false.", + "transpose": "If true, the image can be used to rotate 90 degrees or 270 degrees.\nhmirror = false, vflip = false, transpose = false, the image will not be rotated.\nhmirror = false, vflip = true, transpose = true, the image will be rotated 90 degrees.\nhmirror = true, vflip = true, transpose = false, the image will be rotated 180 degrees.\nhmirror = true, vflip = false, transpose = true, the image will be rotated 270 degrees.", + "mask": "Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.\nOnly pixels set in the mask are modified. default is None." + }, + "return": "Returns the image after the operation is completed.", + "maixpy": "maix.image.Image.replace", + "py_doc": "Replaces all pixels in the image with the corresponding pixels in the other image.\n\nArgs:\n - other: The other image should be an image and should be the same size as the image being operated on.\n - hmirror: If true, the image will be horizontally mirrored before the operation. default is false.\n - vflip: If true, the image will be vertically flipped before the operation. default is false.\n - transpose: If true, the image can be used to rotate 90 degrees or 270 degrees.\nhmirror = false, vflip = false, transpose = false, the image will not be rotated.\nhmirror = false, vflip = true, transpose = true, the image will be rotated 90 degrees.\nhmirror = true, vflip = true, transpose = false, the image will be rotated 180 degrees.\nhmirror = true, vflip = false, transpose = true, the image will be rotated 270 degrees.\n - mask: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.\nOnly pixels set in the mask are modified. default is None.\n\n\nReturns: Returns the image after the operation is completed.\n" + }, + "args": [ + [ + "image::Image *", + "other", + "nullptr" + ], + [ + "bool", + "hmirror", + "false" + ], + [ + "bool", + "vflip", + "false" + ], + [ + "bool", + "transpose", + "false" + ], + [ + "image::Image *", + "mask", + "nullptr" + ] + ], + "ret_type": "image::Image*", + "static": false, + "def": "image::Image *replace(image::Image *other = nullptr, bool hmirror = false, bool vflip = false, bool transpose = false, image::Image *mask = nullptr)" + }, + "set": { + "type": "func", + "name": "set", + "doc": { + "brief": "Alias for Image::replace.", + "param": { + "other": "The other image should be an image and should be the same size as the image being operated on.", + "hmirror": "If true, the image will be horizontally mirrored before the operation. default is false.", + "vflip": "If true, the image will be vertically flipped before the operation. default is false.", + "mask": "Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.\nOnly pixels set in the mask are modified. default is None." + }, + "return": "Returns the image after the operation is completed.", + "maixpy": "maix.image.Image.set", + "py_doc": "Alias for Image::replace.\n\nArgs:\n - other: The other image should be an image and should be the same size as the image being operated on.\n - hmirror: If true, the image will be horizontally mirrored before the operation. default is false.\n - vflip: If true, the image will be vertically flipped before the operation. default is false.\n - mask: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.\nOnly pixels set in the mask are modified. default is None.\n\n\nReturns: Returns the image after the operation is completed.\n" + }, + "args": [ + [ + "image::Image *", + "other", + null + ], + [ + "bool", + "hmirror", + "false" + ], + [ + "bool", + "vflip", + "false" + ], + [ + "bool", + "transpose", + "false" + ], + [ + "image::Image *", + "mask", + "nullptr" + ] + ], + "ret_type": "image::Image*", + "static": false, + "def": "image::Image *set(image::Image *other, bool hmirror = false, bool vflip = false, bool transpose = false, image::Image *mask = nullptr)" + }, + "add": { + "type": "func", + "name": "add", + "doc": { + "brief": "Adds the other image to the image.", + "param": { + "other": "The other image should be an image and should be the same size as the image being operated on. TODO: support path?", + "mask": "Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.\nOnly pixels set in the mask are modified. default is None." + }, + "return": "Returns the image after the operation is completed.", + "maixpy": "maix.image.Image.add", + "py_doc": "Adds the other image to the image.\n\nArgs:\n - other: The other image should be an image and should be the same size as the image being operated on. TODO: support path?\n - mask: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.\nOnly pixels set in the mask are modified. default is None.\n\n\nReturns: Returns the image after the operation is completed.\n" + }, + "args": [ + [ + "image::Image *", + "other", + null + ], + [ + "image::Image *", + "mask", + "nullptr" + ] + ], + "ret_type": "image::Image*", + "static": false, + "def": "image::Image *add(image::Image *other, image::Image *mask = nullptr)" + }, + "sub": { + "type": "func", + "name": "sub", + "doc": { + "brief": "Subtracts the other image from the image.", + "param": { + "other": "The other image should be an image and should be the same size as the image being operated on. TODO: support path?", + "reverse": "If true, the image will be reversed before the operation. default is false.", + "mask": "Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.\nOnly pixels set in the mask are modified. default is None." + }, + "return": "Returns the image after the operation is completed.", + "maixpy": "maix.image.Image.sub", + "py_doc": "Subtracts the other image from the image.\n\nArgs:\n - other: The other image should be an image and should be the same size as the image being operated on. TODO: support path?\n - reverse: If true, the image will be reversed before the operation. default is false.\n - mask: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.\nOnly pixels set in the mask are modified. default is None.\n\n\nReturns: Returns the image after the operation is completed.\n" + }, + "args": [ + [ + "image::Image *", + "other", + null + ], + [ + "bool", + "reverse", + "false" + ], + [ + "image::Image *", + "mask", + "nullptr" + ] + ], + "ret_type": "image::Image*", + "static": false, + "def": "image::Image *sub(image::Image *other, bool reverse = false, image::Image *mask = nullptr)" + }, + "mul": { + "type": "func", + "name": "mul", + "doc": { + "brief": "Multiplies the image by the other image.\\nNote: This method is meant for image blending and cannot multiply the pixels in the image by a scalar like 2.", + "param": { + "other": "The other image should be an image and should be the same size as the image being operated on. TODO: support path?", + "invert": "If true, the image will be change the multiplication operation from a*b to 1/((1/a)*(1/b)).\nIn particular, this lightens the image instead of darkening it (e.g. multiply versus burn operations). default is false.", + "mask": "Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.\nOnly pixels set in the mask are modified. default is None." + }, + "return": "Returns the image after the operation is completed.", + "maixpy": "maix.image.Image.mul", + "py_doc": "Multiplies the image by the other image.\nNote: This method is meant for image blending and cannot multiply the pixels in the image by a scalar like 2.\n\nArgs:\n - other: The other image should be an image and should be the same size as the image being operated on. TODO: support path?\n - invert: If true, the image will be change the multiplication operation from a*b to 1/((1/a)*(1/b)).\nIn particular, this lightens the image instead of darkening it (e.g. multiply versus burn operations). default is false.\n - mask: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.\nOnly pixels set in the mask are modified. default is None.\n\n\nReturns: Returns the image after the operation is completed.\n" + }, + "args": [ + [ + "image::Image *", + "other", + null + ], + [ + "bool", + "invert", + "false" + ], + [ + "image::Image *", + "mask", + "nullptr" + ] + ], + "ret_type": "image::Image*", + "static": false, + "def": "image::Image *mul(image::Image *other, bool invert = false, image::Image *mask = nullptr)" + }, + "div": { + "type": "func", + "name": "div", + "doc": { + "brief": "Divides the image by the other image.\\nThis method is meant for image blending and cannot divide the pixels in the image by a scalar like 2.", + "param": { + "other": "The other image should be an image and should be the same size as the image being operated on. TODO: support path?", + "invert": "If true, the image will be change the division direction from a/b to b/a. default is false.", + "mod": "If true, the image will be change the division operation to the modulus operation. default is false.", + "mask": "Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.\nOnly pixels set in the mask are modified. default is None." + }, + "return": "Returns the image after the operation is completed.", + "maixpy": "maix.image.Image.div", + "py_doc": "Divides the image by the other image.\nThis method is meant for image blending and cannot divide the pixels in the image by a scalar like 2.\n\nArgs:\n - other: The other image should be an image and should be the same size as the image being operated on. TODO: support path?\n - invert: If true, the image will be change the division direction from a/b to b/a. default is false.\n - mod: If true, the image will be change the division operation to the modulus operation. default is false.\n - mask: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.\nOnly pixels set in the mask are modified. default is None.\n\n\nReturns: Returns the image after the operation is completed.\n" + }, + "args": [ + [ + "image::Image *", + "other", + null + ], + [ + "bool", + "invert", + "false" + ], + [ + "bool", + "mod", + "false" + ], + [ + "image::Image *", + "mask", + "nullptr" + ] + ], + "ret_type": "image::Image*", + "static": false, + "def": "image::Image *div(image::Image *other, bool invert = false, bool mod = false, image::Image *mask = nullptr)" + }, + "min": { + "type": "func", + "name": "min", + "doc": { + "brief": "Caculate the minimum of each pixel in the image and the other image.", + "param": { + "other": "The other image should be an image and should be the same size as the image being operated on.", + "mask": "Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.\nOnly pixels set in the mask are modified. default is None." + }, + "return": "Returns the image after the operation is completed.", + "maixpy": "maix.image.Image.min", + "py_doc": "Caculate the minimum of each pixel in the image and the other image.\n\nArgs:\n - other: The other image should be an image and should be the same size as the image being operated on.\n - mask: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.\nOnly pixels set in the mask are modified. default is None.\n\n\nReturns: Returns the image after the operation is completed.\n" + }, + "args": [ + [ + "image::Image *", + "other", + null + ], + [ + "image::Image *", + "mask", + "nullptr" + ] + ], + "ret_type": "image::Image*", + "static": false, + "def": "image::Image *min(image::Image *other, image::Image *mask = nullptr)" + }, + "max": { + "type": "func", + "name": "max", + "doc": { + "brief": "Caculate the maximum of each pixel in the image and the other image.", + "param": { + "other": "The other image should be an image and should be the same size as the image being operated on.", + "mask": "Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.\nOnly pixels set in the mask are modified. default is None." + }, + "return": "Returns the image after the operation is completed.", + "maixpy": "maix.image.Image.max", + "py_doc": "Caculate the maximum of each pixel in the image and the other image.\n\nArgs:\n - other: The other image should be an image and should be the same size as the image being operated on.\n - mask: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.\nOnly pixels set in the mask are modified. default is None.\n\n\nReturns: Returns the image after the operation is completed.\n" + }, + "args": [ + [ + "image::Image *", + "other", + null + ], + [ + "image::Image *", + "mask", + "nullptr" + ] + ], + "ret_type": "image::Image*", + "static": false, + "def": "image::Image *max(image::Image *other, image::Image *mask = nullptr)" + }, + "difference": { + "type": "func", + "name": "difference", + "doc": { + "brief": "Caculate the absolute value of the difference between each pixel in the image and the other image.", + "param": { + "other": "The other image should be an image and should be the same size as the image being operated on.", + "mask": "Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.\nOnly pixels set in the mask are modified. default is None." + }, + "return": "Returns the image after the operation is completed.", + "maixpy": "maix.image.Image.difference", + "py_doc": "Caculate the absolute value of the difference between each pixel in the image and the other image.\n\nArgs:\n - other: The other image should be an image and should be the same size as the image being operated on.\n - mask: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.\nOnly pixels set in the mask are modified. default is None.\n\n\nReturns: Returns the image after the operation is completed.\n" + }, + "args": [ + [ + "image::Image *", + "other", + null + ], + [ + "image::Image *", + "mask", + "nullptr" + ] + ], + "ret_type": "image::Image*", + "static": false, + "def": "image::Image *difference(image::Image *other, image::Image *mask = nullptr)" + }, + "blend": { + "type": "func", + "name": "blend", + "doc": { + "brief": "Blends the image with the other image.\\nres = alpha * this_img / 256 + (256 - alpha) * other_img / 256", + "param": { + "other": "The other image should be an image and should be the same size as the image being operated on.", + "alpha": "The alpha value of the blend, the value range is [0, 256],default is 128.", + "mask": "Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.\nOnly pixels set in the mask are modified. default is None." + }, + "return": "Returns the image after the operation is completed.", + "maixpy": "maix.image.Image.blend", + "py_doc": "Blends the image with the other image.\nres = alpha * this_img / 256 + (256 - alpha) * other_img / 256\n\nArgs:\n - other: The other image should be an image and should be the same size as the image being operated on.\n - alpha: The alpha value of the blend, the value range is [0, 256],default is 128.\n - mask: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.\nOnly pixels set in the mask are modified. default is None.\n\n\nReturns: Returns the image after the operation is completed.\n" + }, + "args": [ + [ + "image::Image *", + "other", + null + ], + [ + "int", + "alpha", + "128" + ], + [ + "image::Image *", + "mask", + "nullptr" + ] + ], + "ret_type": "image::Image*", + "static": false, + "def": "image::Image *blend(image::Image *other, int alpha = 128, image::Image *mask = nullptr)" + }, + "histeq": { + "type": "func", + "name": "histeq", + "doc": { + "brief": "Runs the histogram equalization algorithm on the image.", + "param": { + "adaptive": "If true, an adaptive histogram equalization method will be run on the image instead which as generally better results than non-adaptive histogram qualization but a longer run time. default is false.", + "clip_limit": "Provides a way to limit the contrast of the adaptive histogram qualization. Use a small value for this, like 10, to produce good histogram equalized contrast limited images. default is -1.", + "mask": "Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.\nOnly pixels set in the mask are modified. default is None." + }, + "return": "Returns the image after the operation is completed.", + "maixpy": "maix.image.Image.histeq", + "py_doc": "Runs the histogram equalization algorithm on the image.\n\nArgs:\n - adaptive: If true, an adaptive histogram equalization method will be run on the image instead which as generally better results than non-adaptive histogram qualization but a longer run time. default is false.\n - clip_limit: Provides a way to limit the contrast of the adaptive histogram qualization. Use a small value for this, like 10, to produce good histogram equalized contrast limited images. default is -1.\n - mask: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.\nOnly pixels set in the mask are modified. default is None.\n\n\nReturns: Returns the image after the operation is completed.\n" + }, + "args": [ + [ + "bool", + "adaptive", + "false" + ], + [ + "int", + "clip_limit", + "-1" + ], + [ + "image::Image *", + "mask", + "nullptr" + ] + ], + "ret_type": "image::Image*", + "static": false, + "def": "image::Image *histeq(bool adaptive = false, int clip_limit = -1, image::Image *mask = nullptr)" + }, + "mean": { + "type": "func", + "name": "mean", + "doc": { + "brief": "Standard mean blurring filter using a box filter.\\nThe parameters offset and invert are valid when threshold is True.", + "param": { + "size": "Kernel size. The actual kernel size is ((size * 2) + 1) * ((size * 2) + 1). Use 1(3x3 kernel), 2(5x5 kernel).", + "threshold": "If true, which will enable adaptive thresholding of the image which sets pixels to white or black based on a pixel\u2019s brightness in relation to the brightness of the kernel of pixels around them.\ndefault is false.", + "offset": "The larger the offset value, the lower brightness pixels on the original image will be set to white. default is 0.", + "invert": "If true, the image will be inverted before the operation. default is false.", + "mask": "Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.\nOnly pixels set in the mask are modified. default is None." + }, + "return": "Returns the image after the operation is completed.", + "maixpy": "maix.image.Image.mean", + "py_doc": "Standard mean blurring filter using a box filter.\nThe parameters offset and invert are valid when threshold is True.\n\nArgs:\n - size: Kernel size. The actual kernel size is ((size * 2) + 1) * ((size * 2) + 1). Use 1(3x3 kernel), 2(5x5 kernel).\n - threshold: If true, which will enable adaptive thresholding of the image which sets pixels to white or black based on a pixel\u2019s brightness in relation to the brightness of the kernel of pixels around them.\ndefault is false.\n - offset: The larger the offset value, the lower brightness pixels on the original image will be set to white. default is 0.\n - invert: If true, the image will be inverted before the operation. default is false.\n - mask: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.\nOnly pixels set in the mask are modified. default is None.\n\n\nReturns: Returns the image after the operation is completed.\n" + }, + "args": [ + [ + "int", + "size", + null + ], + [ + "bool", + "threshold", + "false" + ], + [ + "int", + "offset", + "0" + ], + [ + "bool", + "invert", + "false" + ], + [ + "image::Image *", + "mask", + "nullptr" + ] + ], + "ret_type": "image::Image*", + "static": false, + "def": "image::Image *mean(int size, bool threshold = false, int offset = 0, bool invert = false, image::Image *mask = nullptr)" + }, + "median": { + "type": "func", + "name": "median", + "doc": { + "brief": "Runs the median filter on the image. The median filter is the best filter for smoothing surfaces while preserving edges but it is very slow.", + "param": { + "size": "Kernel size. The actual kernel size is ((size * 2) + 1) * ((size * 2) + 1). Use 1(3x3 kernel), 2(5x5 kernel).", + "percentile": "This parameter controls the percentile of the value used in the kernel. You can set this to 0 for a min filter, 0.25 for a lower quartile filter, 0.75 for an upper quartile filter, and 1.0 for a max filter. default is 0.5.", + "threshold": "If true, which will enable adaptive thresholding of the image which sets pixels to white or black based on a pixel\u2019s brightness in relation to the brightness of the kernel of pixels around them.\ndefault is false.", + "offset": "The larger the offset value, the lower brightness pixels on the original image will be set to white. default is 0.", + "invert": "If true, the image will be inverted before the operation. default is false.", + "mask": "Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.\nOnly pixels set in the mask are modified. default is None." + }, + "return": "Returns the image after the operation is completed.", + "maixpy": "maix.image.Image.median", + "py_doc": "Runs the median filter on the image. The median filter is the best filter for smoothing surfaces while preserving edges but it is very slow.\n\nArgs:\n - size: Kernel size. The actual kernel size is ((size * 2) + 1) * ((size * 2) + 1). Use 1(3x3 kernel), 2(5x5 kernel).\n - percentile: This parameter controls the percentile of the value used in the kernel. You can set this to 0 for a min filter, 0.25 for a lower quartile filter, 0.75 for an upper quartile filter, and 1.0 for a max filter. default is 0.5.\n - threshold: If true, which will enable adaptive thresholding of the image which sets pixels to white or black based on a pixel\u2019s brightness in relation to the brightness of the kernel of pixels around them.\ndefault is false.\n - offset: The larger the offset value, the lower brightness pixels on the original image will be set to white. default is 0.\n - invert: If true, the image will be inverted before the operation. default is false.\n - mask: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.\nOnly pixels set in the mask are modified. default is None.\n\n\nReturns: Returns the image after the operation is completed.\n" + }, + "args": [ + [ + "int", + "size", + null + ], + [ + "double", + "percentile", + "0.5" + ], + [ + "bool", + "threshold", + "false" + ], + [ + "int", + "offset", + "0" + ], + [ + "bool", + "invert", + "false" + ], + [ + "image::Image *", + "mask", + "nullptr" + ] + ], + "ret_type": "image::Image*", + "static": false, + "def": "image::Image *median(int size, double percentile = 0.5, bool threshold = false, int offset = 0, bool invert = false, image::Image *mask = nullptr)" + }, + "mode": { + "type": "func", + "name": "mode", + "doc": { + "brief": "Runs the mode filter on the image by replacing each pixel with the mode of their neighbors.", + "param": { + "size": "Kernel size. The actual kernel size is ((size * 2) + 1) * ((size * 2) + 1). Use 1(3x3 kernel), 2(5x5 kernel).", + "threshold": "If true, which will enable adaptive thresholding of the image which sets pixels to white or black based on a pixel\u2019s brightness in relation to the brightness of the kernel of pixels around them.\ndefault is false.", + "offset": "The larger the offset value, the lower brightness pixels on the original image will be set to white. default is 0.", + "invert": "If true, the image will be inverted before the operation. default is false.", + "mask": "Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.\nOnly pixels set in the mask are modified. default is None." + }, + "return": "Returns the image after the operation is completed.", + "maixpy": "maix.image.Image.mode", + "py_doc": "Runs the mode filter on the image by replacing each pixel with the mode of their neighbors.\n\nArgs:\n - size: Kernel size. The actual kernel size is ((size * 2) + 1) * ((size * 2) + 1). Use 1(3x3 kernel), 2(5x5 kernel).\n - threshold: If true, which will enable adaptive thresholding of the image which sets pixels to white or black based on a pixel\u2019s brightness in relation to the brightness of the kernel of pixels around them.\ndefault is false.\n - offset: The larger the offset value, the lower brightness pixels on the original image will be set to white. default is 0.\n - invert: If true, the image will be inverted before the operation. default is false.\n - mask: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.\nOnly pixels set in the mask are modified. default is None.\n\n\nReturns: Returns the image after the operation is completed.\n" + }, + "args": [ + [ + "int", + "size", + null + ], + [ + "bool", + "threshold", + "false" + ], + [ + "int", + "offset", + "0" + ], + [ + "bool", + "invert", + "false" + ], + [ + "image::Image *", + "mask", + "nullptr" + ] + ], + "ret_type": "image::Image*", + "static": false, + "def": "image::Image *mode(int size, bool threshold = false, int offset = 0, bool invert = false, image::Image *mask = nullptr)" + }, + "midpoint": { + "type": "func", + "name": "midpoint", + "doc": { + "brief": "Runs the midpoint filter on the image.This filter finds the midpoint (max * bias + min * (1 - bias)) of each pixel neighborhood in the image.", + "param": { + "size": "Kernel size. The actual kernel size is ((size * 2) + 1) * ((size * 2) + 1). Use 1(3x3 kernel), 2(5x5 kernel).", + "bias": "The bias of the midpoint. default is 0.5.", + "threshold": "If true, which will enable adaptive thresholding of the image which sets pixels to white or black based on a pixel\u2019s brightness in relation to the brightness of the kernel of pixels around them.\ndefault is false.", + "offset": "The larger the offset value, the lower brightness pixels on the original image will be set to white. default is 0.", + "invert": "If true, the image will be inverted before the operation. default is false.", + "mask": "Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.\nOnly pixels set in the mask are modified. default is None." + }, + "return": "Returns the image after the operation is completed.", + "maixpy": "maix.image.Image.midpoint", + "py_doc": "Runs the midpoint filter on the image.This filter finds the midpoint (max * bias + min * (1 - bias)) of each pixel neighborhood in the image.\n\nArgs:\n - size: Kernel size. The actual kernel size is ((size * 2) + 1) * ((size * 2) + 1). Use 1(3x3 kernel), 2(5x5 kernel).\n - bias: The bias of the midpoint. default is 0.5.\n - threshold: If true, which will enable adaptive thresholding of the image which sets pixels to white or black based on a pixel\u2019s brightness in relation to the brightness of the kernel of pixels around them.\ndefault is false.\n - offset: The larger the offset value, the lower brightness pixels on the original image will be set to white. default is 0.\n - invert: If true, the image will be inverted before the operation. default is false.\n - mask: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.\nOnly pixels set in the mask are modified. default is None.\n\n\nReturns: Returns the image after the operation is completed.\n" + }, + "args": [ + [ + "int", + "size", + null + ], + [ + "double", + "bias", + "0.5" + ], + [ + "bool", + "threshold", + "false" + ], + [ + "int", + "offset", + "0" + ], + [ + "bool", + "invert", + "false" + ], + [ + "image::Image *", + "mask", + "nullptr" + ] + ], + "ret_type": "image::Image*", + "static": false, + "def": "image::Image *midpoint(int size, double bias = 0.5, bool threshold = false, int offset = 0, bool invert = false, image::Image *mask = nullptr)" + }, + "morph": { + "type": "func", + "name": "morph", + "doc": { + "brief": "Convolves the image by a filter kernel. This allows you to do general purpose convolutions on an image.", + "param": { + "size": "Kernel size. The actual kernel size is ((size * 2) + 1) * ((size * 2) + 1). Use 1(3x3 kernel), 2(5x5 kernel).", + "kernel": "The kernel used for convolution. The kernel should be a list of lists of numbers. The kernel should be the same size as the actual kernel size.", + "mul": "This parameter is used to multiply the convolved pixel results. default is auto.", + "add": "This parameter is the value to be added to each convolution pixel result. default is 0.0.", + "threshold": "If true, which will enable adaptive thresholding of the image which sets pixels to white or black based on a pixel\u2019s brightness in relation to the brightness of the kernel of pixels around them.\ndefault is false.", + "offset": "The larger the offset value, the lower brightness pixels on the original image will be set to white. default is 0.", + "invert": "If true, the image will be inverted before the operation. default is false.", + "mask": "Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.\nOnly pixels set in the mask are modified. default is None." + }, + "return": "Returns the image after the operation is completed.", + "maixpy": "maix.image.Image.morph", + "py_doc": "Convolves the image by a filter kernel. This allows you to do general purpose convolutions on an image.\n\nArgs:\n - size: Kernel size. The actual kernel size is ((size * 2) + 1) * ((size * 2) + 1). Use 1(3x3 kernel), 2(5x5 kernel).\n - kernel: The kernel used for convolution. The kernel should be a list of lists of numbers. The kernel should be the same size as the actual kernel size.\n - mul: This parameter is used to multiply the convolved pixel results. default is auto.\n - add: This parameter is the value to be added to each convolution pixel result. default is 0.0.\n - threshold: If true, which will enable adaptive thresholding of the image which sets pixels to white or black based on a pixel\u2019s brightness in relation to the brightness of the kernel of pixels around them.\ndefault is false.\n - offset: The larger the offset value, the lower brightness pixels on the original image will be set to white. default is 0.\n - invert: If true, the image will be inverted before the operation. default is false.\n - mask: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.\nOnly pixels set in the mask are modified. default is None.\n\n\nReturns: Returns the image after the operation is completed.\n" + }, + "args": [ + [ + "int", + "size", + null + ], + [ + "std::vector", + "kernel", + null + ], + [ + "float", + "mul", + "-1" + ], + [ + "float", + "add", + "0.0" + ], + [ + "bool", + "threshold", + "false" + ], + [ + "int", + "offset", + "0" + ], + [ + "bool", + "invert", + "false" + ], + [ + "image::Image *", + "mask", + "nullptr" + ] + ], + "ret_type": "image::Image*", + "static": false, + "def": "image::Image *morph(int size, std::vector kernel, float mul = -1, float add = 0.0, bool threshold = false, int offset = 0, bool invert = false, image::Image *mask = nullptr)" + }, + "gaussian": { + "type": "func", + "name": "gaussian", + "doc": { + "brief": "Convolves the image by a smoothing guassian kernel.", + "param": { + "size": "Kernel size. The actual kernel size is ((size * 2) + 1) * ((size * 2) + 1). Use 1(3x3 kernel), 2(5x5 kernel).", + "unsharp": "If true, this method will perform an unsharp mask operation instead of gaussian filtering operation, this improves the clarity of image edges. default is false.", + "mul": "This parameter is used to multiply the convolved pixel results. default is auto.", + "add": "This parameter is the value to be added to each convolution pixel result. default is 0.0.", + "threshold": "If true, which will enable adaptive thresholding of the image which sets pixels to white or black based on a pixel\u2019s brightness in relation to the brightness of the kernel of pixels around them.\ndefault is false.", + "offset": "The larger the offset value, the lower brightness pixels on the original image will be set to white. default is 0.", + "invert": "If true, the image will be inverted before the operation. default is false.", + "mask": "Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.\nOnly pixels set in the mask are modified. default is None." + }, + "return": "Returns the image after the operation is completed.", + "maixpy": "maix.image.Image.gaussian", + "py_doc": "Convolves the image by a smoothing guassian kernel.\n\nArgs:\n - size: Kernel size. The actual kernel size is ((size * 2) + 1) * ((size * 2) + 1). Use 1(3x3 kernel), 2(5x5 kernel).\n - unsharp: If true, this method will perform an unsharp mask operation instead of gaussian filtering operation, this improves the clarity of image edges. default is false.\n - mul: This parameter is used to multiply the convolved pixel results. default is auto.\n - add: This parameter is the value to be added to each convolution pixel result. default is 0.0.\n - threshold: If true, which will enable adaptive thresholding of the image which sets pixels to white or black based on a pixel\u2019s brightness in relation to the brightness of the kernel of pixels around them.\ndefault is false.\n - offset: The larger the offset value, the lower brightness pixels on the original image will be set to white. default is 0.\n - invert: If true, the image will be inverted before the operation. default is false.\n - mask: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.\nOnly pixels set in the mask are modified. default is None.\n\n\nReturns: Returns the image after the operation is completed.\n" + }, + "args": [ + [ + "int", + "size", + null + ], + [ + "bool", + "unsharp", + "false" + ], + [ + "float", + "mul", + "-1" + ], + [ + "float", + "add", + "0.0" + ], + [ + "bool", + "threshold", + "false" + ], + [ + "int", + "offset", + "0" + ], + [ + "bool", + "invert", + "false" + ], + [ + "image::Image *", + "mask", + "nullptr" + ] + ], + "ret_type": "image::Image*", + "static": false, + "def": "image::Image *gaussian(int size, bool unsharp = false, float mul = -1, float add = 0.0, bool threshold = false, int offset = 0, bool invert = false, image::Image *mask = nullptr)" + }, + "laplacian": { + "type": "func", + "name": "laplacian", + "doc": { + "brief": "Convolves the image by a edge detecting laplacian kernel.", + "param": { + "size": "Kernel size. The actual kernel size is ((size * 2) + 1) * ((size * 2) + 1). Use 1(3x3 kernel), 2(5x5 kernel).", + "sharpen": "If True, this method will sharpen the image instead of an unthresholded edge detection image. Then increase the kernel size to improve image clarity. default is false.", + "mul": "This parameter is used to multiply the convolved pixel results. default is auto.", + "add": "This parameter is the value to be added to each convolution pixel result. default is 0.0.", + "threshold": "If true, which will enable adaptive thresholding of the image which sets pixels to white or black based on a pixel\u2019s brightness in relation to the brightness of the kernel of pixels around them.\ndefault is false.", + "offset": "The larger the offset value, the lower brightness pixels on the original image will be set to white. default is 0.", + "invert": "If true, the image will be inverted before the operation. default is false.", + "mask": "Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.\nOnly pixels set in the mask are modified. default is None." + }, + "return": "Returns the image after the operation is completed.", + "maixpy": "maix.image.Image.laplacian", + "py_doc": "Convolves the image by a edge detecting laplacian kernel.\n\nArgs:\n - size: Kernel size. The actual kernel size is ((size * 2) + 1) * ((size * 2) + 1). Use 1(3x3 kernel), 2(5x5 kernel).\n - sharpen: If True, this method will sharpen the image instead of an unthresholded edge detection image. Then increase the kernel size to improve image clarity. default is false.\n - mul: This parameter is used to multiply the convolved pixel results. default is auto.\n - add: This parameter is the value to be added to each convolution pixel result. default is 0.0.\n - threshold: If true, which will enable adaptive thresholding of the image which sets pixels to white or black based on a pixel\u2019s brightness in relation to the brightness of the kernel of pixels around them.\ndefault is false.\n - offset: The larger the offset value, the lower brightness pixels on the original image will be set to white. default is 0.\n - invert: If true, the image will be inverted before the operation. default is false.\n - mask: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.\nOnly pixels set in the mask are modified. default is None.\n\n\nReturns: Returns the image after the operation is completed.\n" + }, + "args": [ + [ + "int", + "size", + null + ], + [ + "bool", + "sharpen", + "false" + ], + [ + "float", + "mul", + "-1" + ], + [ + "float", + "add", + "0.0" + ], + [ + "bool", + "threshold", + "false" + ], + [ + "int", + "offset", + "0" + ], + [ + "bool", + "invert", + "false" + ], + [ + "image::Image *", + "mask", + "nullptr" + ] + ], + "ret_type": "image::Image*", + "static": false, + "def": "image::Image *laplacian(int size, bool sharpen = false, float mul = -1, float add = 0.0, bool threshold = false, int offset = 0, bool invert = false, image::Image *mask = nullptr)" + }, + "bilateral": { + "type": "func", + "name": "bilateral", + "doc": { + "brief": "Convolves the image by a bilateral filter.", + "param": { + "size": "Kernel size. The actual kernel size is ((size * 2) + 1) * ((size * 2) + 1). Use 1(3x3 kernel), 2(5x5 kernel).", + "color_sigma": "Controls how closely colors are matched using the bilateral filter. default is 0.1.", + "space_sigma": "Controls how closely pixels space-wise are blurred with each other. default is 1.", + "threshold": "If true, which will enable adaptive thresholding of the image which sets pixels to white or black based on a pixel\u2019s brightness in relation to the brightness of the kernel of pixels around them.\ndefault is false.", + "offset": "The larger the offset value, the lower brightness pixels on the original image will be set to white. default is 0.", + "invert": "If true, the image will be inverted before the operation. default is false.", + "mask": "Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.\nOnly pixels set in the mask are modified. default is None." + }, + "return": "Returns the image after the operation is completed.", + "maixpy": "maix.image.Image.bilateral", + "py_doc": "Convolves the image by a bilateral filter.\n\nArgs:\n - size: Kernel size. The actual kernel size is ((size * 2) + 1) * ((size * 2) + 1). Use 1(3x3 kernel), 2(5x5 kernel).\n - color_sigma: Controls how closely colors are matched using the bilateral filter. default is 0.1.\n - space_sigma: Controls how closely pixels space-wise are blurred with each other. default is 1.\n - threshold: If true, which will enable adaptive thresholding of the image which sets pixels to white or black based on a pixel\u2019s brightness in relation to the brightness of the kernel of pixels around them.\ndefault is false.\n - offset: The larger the offset value, the lower brightness pixels on the original image will be set to white. default is 0.\n - invert: If true, the image will be inverted before the operation. default is false.\n - mask: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.\nOnly pixels set in the mask are modified. default is None.\n\n\nReturns: Returns the image after the operation is completed.\n" + }, + "args": [ + [ + "int", + "size", + null + ], + [ + "double", + "color_sigma", + "0.1" + ], + [ + "double", + "space_sigma", + "1" + ], + [ + "bool", + "threshold", + "false" + ], + [ + "int", + "offset", + "0" + ], + [ + "bool", + "invert", + "false" + ], + [ + "image::Image *", + "mask", + "nullptr" + ] + ], + "ret_type": "image::Image*", + "static": false, + "def": "image::Image *bilateral(int size, double color_sigma = 0.1, double space_sigma = 1, bool threshold = false, int offset = 0, bool invert = false, image::Image *mask = nullptr)" + }, + "linpolar": { + "type": "func", + "name": "linpolar", + "doc": { + "brief": "Re-project\u2019s and image from cartessian coordinates to linear polar coordinates.", + "param": { + "reverse": "If true, the image will be reverse polar transformed. default is false." + }, + "return": "Returns the image after the operation is completed.", + "maixpy": "maix.image.Image.linpolar", + "py_doc": "Re-project\u2019s and image from cartessian coordinates to linear polar coordinates.\n\nArgs:\n - reverse: If true, the image will be reverse polar transformed. default is false.\n\n\nReturns: Returns the image after the operation is completed.\n" + }, + "args": [ + [ + "bool", + "reverse", + "false" + ] + ], + "ret_type": "image::Image*", + "static": false, + "def": "image::Image *linpolar(bool reverse = false)" + }, + "logpolar": { + "type": "func", + "name": "logpolar", + "doc": { + "brief": "Re-project\u2019s and image from cartessian coordinates to log polar coordinates.", + "param": { + "reverse": "If true, the image will be reverse polar transformed. default is false." + }, + "return": "Returns the image after the operation is completed.", + "maixpy": "maix.image.Image.logpolar", + "py_doc": "Re-project\u2019s and image from cartessian coordinates to log polar coordinates.\n\nArgs:\n - reverse: If true, the image will be reverse polar transformed. default is false.\n\n\nReturns: Returns the image after the operation is completed.\n" + }, + "args": [ + [ + "bool", + "reverse", + "false" + ] + ], + "ret_type": "image::Image*", + "static": false, + "def": "image::Image *logpolar(bool reverse = false)" + }, + "lens_corr": { + "type": "func", + "name": "lens_corr", + "doc": { + "brief": "Performs a lens correction operation on the image. TODO: support in the feature", + "param": { + "strength": "The strength of the lens correction. default is 1.8.", + "zoom": "The zoom of the lens correction. default is 1.0.", + "x_corr": "The x correction of the lens correction. default is 0.0.", + "y_corr": "The y correction of the lens correction. default is 0.0." + }, + "return": "Returns the image after the operation is completed.", + "maixpy": "maix.image.Image.lens_corr", + "py_doc": "Performs a lens correction operation on the image. TODO: support in the feature\n\nArgs:\n - strength: The strength of the lens correction. default is 1.8.\n - zoom: The zoom of the lens correction. default is 1.0.\n - x_corr: The x correction of the lens correction. default is 0.0.\n - y_corr: The y correction of the lens correction. default is 0.0.\n\n\nReturns: Returns the image after the operation is completed.\n" + }, + "args": [ + [ + "double", + "strength", + "1.8" + ], + [ + "double", + "zoom", + "1.0" + ], + [ + "double", + "x_corr", + "0.0" + ], + [ + "double", + "y_corr", + "0.0" + ] + ], + "ret_type": "image::Image*", + "static": false, + "def": "image::Image *lens_corr(double strength = 1.8, double zoom = 1.0, double x_corr = 0.0, double y_corr = 0.0)" + }, + "rotation_corr": { + "type": "func", + "name": "rotation_corr", + "doc": { + "brief": "Performs a rotation correction operation on the image. TODO: support in the feature", + "param": { + "x_rotation": "The x rotation of the rotation correction. default is 0.0.", + "y_rotation": "The y rotation of the rotation correction. default is 0.0.", + "z_rotation": "The z rotation of the rotation correction. default is 0.0.", + "x_translation": "The x translation of the rotation correction. default is 0.0.", + "y_translation": "The y translation of the rotation correction. default is 0.0.", + "zoom": "The zoom of the rotation correction. default is 1.0.", + "fov": "The fov of the rotation correction. default is 60.0.", + "corners": "The corners of the rotation correction. default is None." + }, + "return": "Returns the image after the operation is completed.", + "maixpy": "maix.image.Image.rotation_corr", + "py_doc": "Performs a rotation correction operation on the image. TODO: support in the feature\n\nArgs:\n - x_rotation: The x rotation of the rotation correction. default is 0.0.\n - y_rotation: The y rotation of the rotation correction. default is 0.0.\n - z_rotation: The z rotation of the rotation correction. default is 0.0.\n - x_translation: The x translation of the rotation correction. default is 0.0.\n - y_translation: The y translation of the rotation correction. default is 0.0.\n - zoom: The zoom of the rotation correction. default is 1.0.\n - fov: The fov of the rotation correction. default is 60.0.\n - corners: The corners of the rotation correction. default is None.\n\n\nReturns: Returns the image after the operation is completed.\n" + }, + "args": [ + [ + "double", + "x_rotation", + "0.0" + ], + [ + "double", + "y_rotation", + "0.0" + ], + [ + "double", + "z_rotation", + "0.0" + ], + [ + "double", + "x_translation", + "0.0" + ], + [ + "double", + "y_translation", + "0.0" + ], + [ + "double", + "zoom", + "1.0" + ], + [ + "double", + "fov", + "60.0" + ], + [ + "std::vector", + "corners", + "std::vector()" + ] + ], + "ret_type": "image::Image*", + "static": false, + "def": "image::Image *rotation_corr(double x_rotation = 0.0, double y_rotation = 0.0, double z_rotation = 0.0, double x_translation = 0.0, double y_translation = 0.0, double zoom = 1.0, double fov = 60.0, std::vector corners = std::vector())" + }, + "get_histogram": { + "type": "func", + "name": "get_histogram", + "doc": { + "brief": "Computes the normalized histogram on all color channels and returns a image::Histogram object.", + "note": "For GRAYSCALE format, Lmin and Lmax range is [0, 255]. For RGB888 format, Lmin and Lmax range is [0, 100].", + "param": { + "thresholds": "You can define multiple thresholds.\nFor GRAYSCALE format, you can use {{Lmin, Lmax}, ...} to define one or more thresholds.\nFor RGB888 format, you can use {{Lmin, Lmax, Amin, Amax, Bmin, Bmax}, ...} to define one or more thresholds.\nWhere the upper case L,A,B represent the L,A,B channels of the LAB image format, and min, max represent the minimum and maximum values of the corresponding channels.", + "invert": "If true, the thresholds will be inverted before the operation. default is false.", + "roi": "The region of interest, input in the format of (x, y, w, h), x and y are the coordinates of the upper left corner, w and h are the width and height of roi.\ndefault is None, means whole image.", + "bins": "The number of bins to use for the histogram.\nIn GRAYSCALE format, setting range is [2, 256], default is 100.\nIn RGB888 format, setting range is [2, 100], default is 100.", + "l_bins": "The number of bins to use for the l channel of the histogram. Only valid in RGB888 format.\nIf an invalid value is set, bins will be used instead. The setting range is [2, 100], default is 100.", + "a_bins": "The number of bins to use for the a channel of the histogram.\nOnly valid in RGB888 format.The setting range is [2, 256], default is 256.", + "b_bins": "The number of bins to use for the b channel of the histogram.\nOnly valid in RGB888 format. The setting range is [2, 256], default is 256.", + "difference": "difference may be set to an image object to cause this method to operate on the difference image between the current image and the difference image object.\ndefault is None." + }, + "return": "Returns image::Histogram object", + "maixpy": "maix.image.Image.get_histogram", + "py_doc": "Computes the normalized histogram on all color channels and returns a image::Histogram object.\n\nArgs:\n - thresholds: You can define multiple thresholds.\nFor GRAYSCALE format, you can use {{Lmin, Lmax}, ...} to define one or more thresholds.\nFor RGB888 format, you can use {{Lmin, Lmax, Amin, Amax, Bmin, Bmax}, ...} to define one or more thresholds.\nWhere the upper case L,A,B represent the L,A,B channels of the LAB image format, and min, max represent the minimum and maximum values of the corresponding channels.\n - invert: If true, the thresholds will be inverted before the operation. default is false.\n - roi: The region of interest, input in the format of (x, y, w, h), x and y are the coordinates of the upper left corner, w and h are the width and height of roi.\ndefault is None, means whole image.\n - bins: The number of bins to use for the histogram.\nIn GRAYSCALE format, setting range is [2, 256], default is 100.\nIn RGB888 format, setting range is [2, 100], default is 100.\n - l_bins: The number of bins to use for the l channel of the histogram. Only valid in RGB888 format.\nIf an invalid value is set, bins will be used instead. The setting range is [2, 100], default is 100.\n - a_bins: The number of bins to use for the a channel of the histogram.\nOnly valid in RGB888 format.The setting range is [2, 256], default is 256.\n - b_bins: The number of bins to use for the b channel of the histogram.\nOnly valid in RGB888 format. The setting range is [2, 256], default is 256.\n - difference: difference may be set to an image object to cause this method to operate on the difference image between the current image and the difference image object.\ndefault is None.\n\n\nReturns: Returns image::Histogram object\n" + }, + "args": [ + [ + "std::vector>", + "thresholds", + "std::vector>()" + ], + [ + "bool", + "invert", + "false" + ], + [ + "std::vector", + "roi", + "std::vector()" + ], + [ + "int", + "bins", + "-1" + ], + [ + "int", + "l_bins", + "100" + ], + [ + "int", + "a_bins", + "256" + ], + [ + "int", + "b_bins", + "256" + ], + [ + "image::Image *", + "difference", + "nullptr" + ] + ], + "ret_type": "image::Histogram", + "static": false, + "def": "image::Histogram get_histogram(std::vector> thresholds = std::vector>(), bool invert = false, std::vector roi = std::vector(), int bins = -1, int l_bins = 100, int a_bins = 256, int b_bins = 256, image::Image *difference = nullptr)" + }, + "get_statistics": { + "type": "func", + "name": "get_statistics", + "doc": { + "brief": "Gets the statistics of the image. TODO: support in the feature", + "note": "For GRAYSCALE format, Lmin and Lmax range is [0, 255]. For RGB888 format, Lmin and Lmax range is [0, 100].", + "param": { + "thresholds": "You can define multiple thresholds.\nFor GRAYSCALE format, you can use {{Lmin, Lmax}, ...} to define one or more thresholds.\nFor RGB888 format, you can use {{Lmin, Lmax, Amin, Amax, Bmin, Bmax}, ...} to define one or more thresholds.\nWhere the upper case L,A,B represent the L,A,B channels of the LAB image format, and min, max represent the minimum and maximum values of the corresponding channels.", + "invert": "If true, the image will be inverted before the operation. default is false.", + "roi": "The region of interest, input in the format of (x, y, w, h), x and y are the coordinates of the upper left corner, w and h are the width and height of roi.\ndefault is None, means whole image.", + "bins": "The number of bins to use for the statistics. default is -1.", + "l_bins": "The number of bins to use for the l channel of the statistics. default is -1.", + "a_bins": "The number of bins to use for the a channel of the statistics. default is -1.", + "b_bins": "The number of bins to use for the b channel of the statistics. default is -1.", + "difference": "The difference image to use for the statistics. default is None." + }, + "return": "Returns the statistics of the image", + "maixpy": "maix.image.Image.get_statistics", + "py_doc": "Gets the statistics of the image. TODO: support in the feature\n\nArgs:\n - thresholds: You can define multiple thresholds.\nFor GRAYSCALE format, you can use {{Lmin, Lmax}, ...} to define one or more thresholds.\nFor RGB888 format, you can use {{Lmin, Lmax, Amin, Amax, Bmin, Bmax}, ...} to define one or more thresholds.\nWhere the upper case L,A,B represent the L,A,B channels of the LAB image format, and min, max represent the minimum and maximum values of the corresponding channels.\n - invert: If true, the image will be inverted before the operation. default is false.\n - roi: The region of interest, input in the format of (x, y, w, h), x and y are the coordinates of the upper left corner, w and h are the width and height of roi.\ndefault is None, means whole image.\n - bins: The number of bins to use for the statistics. default is -1.\n - l_bins: The number of bins to use for the l channel of the statistics. default is -1.\n - a_bins: The number of bins to use for the a channel of the statistics. default is -1.\n - b_bins: The number of bins to use for the b channel of the statistics. default is -1.\n - difference: The difference image to use for the statistics. default is None.\n\n\nReturns: Returns the statistics of the image\n" + }, + "args": [ + [ + "std::vector>", + "thresholds", + "std::vector>()" + ], + [ + "bool", + "invert", + "false" + ], + [ + "std::vector", + "roi", + "std::vector()" + ], + [ + "int", + "bins", + "-1" + ], + [ + "int", + "l_bins", + "-1" + ], + [ + "int", + "a_bins", + "-1" + ], + [ + "int", + "b_bins", + "-1" + ], + [ + "image::Image *", + "difference", + "nullptr" + ] + ], + "ret_type": "image::Statistics", + "static": false, + "def": "image::Statistics get_statistics(std::vector> thresholds = std::vector>(), bool invert = false, std::vector roi = std::vector(), int bins = -1, int l_bins = -1, int a_bins = -1, int b_bins = -1, image::Image *difference = nullptr)" + }, + "get_regression": { + "type": "func", + "name": "get_regression", + "doc": { + "brief": "Gets the regression of the image.", + "note": "For GRAYSCALE format, Lmin and Lmax range is [0, 255]. For RGB888 format, Lmin and Lmax range is [0, 100].", + "param": { + "thresholds": "You can define multiple thresholds.\nFor GRAYSCALE format, you can use {{Lmin, Lmax}, ...} to define one or more thresholds.\nFor RGB888 format, you can use {{Lmin, Lmax, Amin, Amax, Bmin, Bmax}, ...} to define one or more thresholds.\nWhere the upper case L,A,B represent the L,A,B channels of the LAB image format, and min, max represent the minimum and maximum values of the corresponding channels.", + "invert": "If true, the image will be inverted before the operation. default is false.", + "roi": "The region of interest, input in the format of (x, y, w, h), x and y are the coordinates of the upper left corner, w and h are the width and height of roi.\ndefault is None, means whole image.", + "x_stride": "The x stride to use for the regression. default is 2.", + "y_stride": "The y stride to use for the regression. default is 1.", + "area_threshold": "The area threshold to use for the regression. default is 10.", + "pixels_threshold": "The pixels threshold to use for the regression. default is 10.", + "robust": "If true, the regression will be robust. default is false." + }, + "return": "Returns the regression of the image", + "maixpy": "maix.image.Image.get_regression", + "py_doc": "Gets the regression of the image.\n\nArgs:\n - thresholds: You can define multiple thresholds.\nFor GRAYSCALE format, you can use {{Lmin, Lmax}, ...} to define one or more thresholds.\nFor RGB888 format, you can use {{Lmin, Lmax, Amin, Amax, Bmin, Bmax}, ...} to define one or more thresholds.\nWhere the upper case L,A,B represent the L,A,B channels of the LAB image format, and min, max represent the minimum and maximum values of the corresponding channels.\n - invert: If true, the image will be inverted before the operation. default is false.\n - roi: The region of interest, input in the format of (x, y, w, h), x and y are the coordinates of the upper left corner, w and h are the width and height of roi.\ndefault is None, means whole image.\n - x_stride: The x stride to use for the regression. default is 2.\n - y_stride: The y stride to use for the regression. default is 1.\n - area_threshold: The area threshold to use for the regression. default is 10.\n - pixels_threshold: The pixels threshold to use for the regression. default is 10.\n - robust: If true, the regression will be robust. default is false.\n\n\nReturns: Returns the regression of the image\n" + }, + "args": [ + [ + "std::vector>", + "thresholds", + "std::vector>()" + ], + [ + "bool", + "invert", + "false" + ], + [ + "std::vector", + "roi", + "std::vector()" + ], + [ + "int", + "x_stride", + "2" + ], + [ + "int", + "y_stride", + "1" + ], + [ + "int", + "area_threshold", + "10" + ], + [ + "int", + "pixels_threshold", + "10" + ], + [ + "bool", + "robust", + "false" + ] + ], + "ret_type": "std::vector", + "static": false, + "def": "std::vector get_regression(std::vector> thresholds = std::vector>(), bool invert = false, std::vector roi = std::vector(), int x_stride = 2, int y_stride = 1, int area_threshold = 10, int pixels_threshold = 10, bool robust = false)" + }, + "save": { + "type": "func", + "name": "save", + "doc": { + "brief": "Save image to file", + "param": { + "path": "file path", + "quality": "image quality, by default(value is 95), support jpeg and png format" + }, + "return": "error code, err::ERR_NONE is ok, other is error", + "maixpy": "maix.image.Image.save", + "py_doc": "Save image to file\n\nArgs:\n - path: file path\n - quality: image quality, by default(value is 95), support jpeg and png format\n\n\nReturns: error code, err::ERR_NONE is ok, other is error\n" + }, + "args": [ + [ + "const char *", + "path", + null + ], + [ + "int", + "quality", + "95" + ] + ], + "ret_type": "err::Err", + "static": false, + "def": "err::Err save(const char *path, int quality = 95)" + }, + "flood_fill": { + "type": "func", + "name": "flood_fill", + "doc": { + "brief": "Flood fills a region of the image starting from location x, y.", + "param": { + "x": "The x coordinate of the seed point.", + "y": "The y coordinate of the seed point.", + "seed_threshold": "The seed_threshold value controls how different any pixel in the fill area may be from the original starting pixel. default is 0.05.", + "floating_threshold": "The floating_threshold value controls how different any pixel in the fill area may be from any neighbor pixels. default is 0.05.", + "color": "The color to fill the region with. default is white.", + "invert": "If true, the image will be inverted before the operation. default is false.", + "clear_background": "If true, the background will be cleared before the operation. default is false.", + "mask": "Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.\nOnly pixels set in the mask are modified. default is None. FIXME: the mask image works abnormally" + }, + "return": "Returns the image after the operation is completed.", + "maixpy": "maix.image.Image.flood_fill", + "py_doc": "Flood fills a region of the image starting from location x, y.\n\nArgs:\n - x: The x coordinate of the seed point.\n - y: The y coordinate of the seed point.\n - seed_threshold: The seed_threshold value controls how different any pixel in the fill area may be from the original starting pixel. default is 0.05.\n - floating_threshold: The floating_threshold value controls how different any pixel in the fill area may be from any neighbor pixels. default is 0.05.\n - color: The color to fill the region with. default is white.\n - invert: If true, the image will be inverted before the operation. default is false.\n - clear_background: If true, the background will be cleared before the operation. default is false.\n - mask: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.\nOnly pixels set in the mask are modified. default is None. FIXME: the mask image works abnormally\n\n\nReturns: Returns the image after the operation is completed.\n" + }, + "args": [ + [ + "int", + "x", + null + ], + [ + "int", + "y", + null + ], + [ + "float", + "seed_threshold", + "0.05" + ], + [ + "float", + "floating_threshold", + "0.05" + ], + [ + "image::Color", + "color", + "image::COLOR_WHITE" + ], + [ + "bool", + "invert", + "false" + ], + [ + "bool", + "clear_background", + "false" + ], + [ + "image::Image *", + "mask", + "nullptr" + ] + ], + "ret_type": "image::Image*", + "static": false, + "def": "image::Image *flood_fill(int x, int y, float seed_threshold = 0.05, float floating_threshold = 0.05, image::Color color = image::COLOR_WHITE, bool invert = false, bool clear_background = false, image::Image *mask = nullptr)" + }, + "erode": { + "type": "func", + "name": "erode", + "doc": { + "brief": "Erodes the image in place.", + "param": { + "size": "Kernel size. The actual kernel size is ((size * 2) + 1) * ((size * 2) + 1). Use 1(3x3 kernel), 2(5x5 kernel).", + "threshold": "The number of pixels in the kernel that are not 0. If it is less than or equal to the threshold, set the center pixel to black. default is (kernel_size - 1).", + "mask": "Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.\nOnly pixels set in the mask are modified. default is None." + }, + "return": "Returns the image after the operation is completed.", + "maixpy": "maix.image.Image.erode", + "py_doc": "Erodes the image in place.\n\nArgs:\n - size: Kernel size. The actual kernel size is ((size * 2) + 1) * ((size * 2) + 1). Use 1(3x3 kernel), 2(5x5 kernel).\n - threshold: The number of pixels in the kernel that are not 0. If it is less than or equal to the threshold, set the center pixel to black. default is (kernel_size - 1).\n - mask: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.\nOnly pixels set in the mask are modified. default is None.\n\n\nReturns: Returns the image after the operation is completed.\n" + }, + "args": [ + [ + "int", + "size", + null + ], + [ + "int", + "threshold", + "-1" + ], + [ + "image::Image *", + "mask", + "nullptr" + ] + ], + "ret_type": "image::Image*", + "static": false, + "def": "image::Image *erode(int size, int threshold = -1, image::Image *mask = nullptr)" + }, + "dilate": { + "type": "func", + "name": "dilate", + "doc": { + "brief": "Dilates the image in place.", + "param": { + "size": "Kernel size. The actual kernel size is ((size * 2) + 1) * ((size * 2) + 1). Use 1(3x3 kernel), 2(5x5 kernel).", + "threshold": "The number of pixels in the kernel that are not 0. If it is greater than or equal to the threshold, set the center pixel to white. default is 0.", + "mask": "Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.\nOnly pixels set in the mask are modified. default is None." + }, + "return": "Returns the image after the operation is completed.", + "maixpy": "maix.image.Image.dilate", + "py_doc": "Dilates the image in place.\n\nArgs:\n - size: Kernel size. The actual kernel size is ((size * 2) + 1) * ((size * 2) + 1). Use 1(3x3 kernel), 2(5x5 kernel).\n - threshold: The number of pixels in the kernel that are not 0. If it is greater than or equal to the threshold, set the center pixel to white. default is 0.\n - mask: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.\nOnly pixels set in the mask are modified. default is None.\n\n\nReturns: Returns the image after the operation is completed.\n" + }, + "args": [ + [ + "int", + "size", + null + ], + [ + "int", + "threshold", + "0" + ], + [ + "image::Image *", + "mask", + "nullptr" + ] + ], + "ret_type": "image::Image*", + "static": false, + "def": "image::Image *dilate(int size, int threshold = 0, image::Image *mask = nullptr)" + }, + "open": { + "type": "func", + "name": "open", + "doc": { + "brief": "Performs erosion and dilation on an image in order.", + "param": { + "size": "Kernel size. The actual kernel size is ((size * 2) + 1) * ((size * 2) + 1). Use 1(3x3 kernel), 2(5x5 kernel).", + "threshold": "As the threshold for erosion and dilation, the actual threshold for erosion is (kernel_size - 1 - threshold), the actual threshold for dialation is threshold. default is 0.", + "mask": "Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.\nOnly pixels set in the mask are modified. default is None." + }, + "return": "Returns the image after the operation is completed.", + "maixpy": "maix.image.Image.open", + "py_doc": "Performs erosion and dilation on an image in order.\n\nArgs:\n - size: Kernel size. The actual kernel size is ((size * 2) + 1) * ((size * 2) + 1). Use 1(3x3 kernel), 2(5x5 kernel).\n - threshold: As the threshold for erosion and dilation, the actual threshold for erosion is (kernel_size - 1 - threshold), the actual threshold for dialation is threshold. default is 0.\n - mask: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.\nOnly pixels set in the mask are modified. default is None.\n\n\nReturns: Returns the image after the operation is completed.\n" + }, + "args": [ + [ + "int", + "size", + null + ], + [ + "int", + "threshold", + "0" + ], + [ + "image::Image *", + "mask", + "nullptr" + ] + ], + "ret_type": "image::Image*", + "static": false, + "def": "image::Image *open(int size, int threshold = 0, image::Image *mask = nullptr)" + }, + "close": { + "type": "func", + "name": "close", + "doc": { + "brief": "Performs dilation and erosion on an image in order.", + "param": { + "size": "Kernel size. The actual kernel size is ((size * 2) + 1) * ((size * 2) + 1). Use 1(3x3 kernel), 2(5x5 kernel).", + "threshold": "As the threshold for erosion and dilation, the actual threshold for erosion is (kernel_size - 1 - threshold), the actual threshold for dialation is threshold. default is 0.", + "mask": "Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.\nOnly pixels set in the mask are modified. default is None." + }, + "return": "Returns the image after the operation is completed.", + "maixpy": "maix.image.Image.close", + "py_doc": "Performs dilation and erosion on an image in order.\n\nArgs:\n - size: Kernel size. The actual kernel size is ((size * 2) + 1) * ((size * 2) + 1). Use 1(3x3 kernel), 2(5x5 kernel).\n - threshold: As the threshold for erosion and dilation, the actual threshold for erosion is (kernel_size - 1 - threshold), the actual threshold for dialation is threshold. default is 0.\n - mask: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.\nOnly pixels set in the mask are modified. default is None.\n\n\nReturns: Returns the image after the operation is completed.\n" + }, + "args": [ + [ + "int", + "size", + null + ], + [ + "int", + "threshold", + "0" + ], + [ + "image::Image *", + "mask", + "nullptr" + ] + ], + "ret_type": "image::Image*", + "static": false, + "def": "image::Image *close(int size, int threshold = 0, image::Image *mask = nullptr)" + }, + "top_hat": { + "type": "func", + "name": "top_hat", + "doc": { + "brief": "Returns the image difference of the image and Image.open()\u2019ed image.", + "param": { + "size": "Kernel size. The actual kernel size is ((size * 2) + 1) * ((size * 2) + 1). Use 1(3x3 kernel), 2(5x5 kernel).", + "threshold": "As the threshold for open method. default is 0.", + "mask": "Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.\nOnly pixels set in the mask are modified. default is None." + }, + "return": "Returns the image after the operation is completed.", + "maixpy": "maix.image.Image.top_hat", + "py_doc": "Returns the image difference of the image and Image.open()\u2019ed image.\n\nArgs:\n - size: Kernel size. The actual kernel size is ((size * 2) + 1) * ((size * 2) + 1). Use 1(3x3 kernel), 2(5x5 kernel).\n - threshold: As the threshold for open method. default is 0.\n - mask: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.\nOnly pixels set in the mask are modified. default is None.\n\n\nReturns: Returns the image after the operation is completed.\n" + }, + "args": [ + [ + "int", + "size", + null + ], + [ + "int", + "threshold", + "0" + ], + [ + "image::Image *", + "mask", + "nullptr" + ] + ], + "ret_type": "image::Image*", + "static": false, + "def": "image::Image *top_hat(int size, int threshold = 0, image::Image *mask = nullptr)" + }, + "black_hat": { + "type": "func", + "name": "black_hat", + "doc": { + "brief": "Returns the image difference of the image and Image.close()\u2019ed image.", + "param": { + "size": "Kernel size. The actual kernel size is ((size * 2) + 1) * ((size * 2) + 1). Use 1(3x3 kernel), 2(5x5 kernel).", + "threshold": "As the threshold for close method. default is 0.", + "mask": "Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.\nOnly pixels set in the mask are modified. default is None." + }, + "return": "Returns the image after the operation is completed.", + "maixpy": "maix.image.Image.black_hat", + "py_doc": "Returns the image difference of the image and Image.close()\u2019ed image.\n\nArgs:\n - size: Kernel size. The actual kernel size is ((size * 2) + 1) * ((size * 2) + 1). Use 1(3x3 kernel), 2(5x5 kernel).\n - threshold: As the threshold for close method. default is 0.\n - mask: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.\nOnly pixels set in the mask are modified. default is None.\n\n\nReturns: Returns the image after the operation is completed.\n" + }, + "args": [ + [ + "int", + "size", + null + ], + [ + "int", + "threshold", + "0" + ], + [ + "image::Image *", + "mask", + "nullptr" + ] + ], + "ret_type": "image::Image*", + "static": false, + "def": "image::Image *black_hat(int size, int threshold = 0, image::Image *mask = nullptr)" + }, + "find_blobs": { + "type": "func", + "name": "find_blobs", + "doc": { + "brief": "Finds all blobs in the image and returns a list of image.Blob class which describe each Blob.\\nPlease see the image.Blob object more more information.", + "note": "For GRAYSCALE format, Lmin and Lmax range is [0, 255]. For RGB888 format, Lmin and Lmax range is [0, 100].", + "param": { + "thresholds": "You can define multiple thresholds.\nFor GRAYSCALE format, you can use {{Lmin, Lmax}, ...} to define one or more thresholds.\nFor RGB888 format, you can use {{Lmin, Lmax, Amin, Amax, Bmin, Bmax}, ...} to define one or more thresholds.\nWhere the upper case L,A,B represent the L,A,B channels of the LAB image format, and min, max represent the minimum and maximum values of the corresponding channels.", + "invert": "if true, will invert thresholds before find blobs, default is false", + "roi": "The region of interest, input in the format of (x, y, w, h), x and y are the coordinates of the upper left corner, w and h are the width and height of roi.\ndefault is None, means whole image.", + "x_stride": "x stride is the number of x pixels to skip when doing the hough transform. default is 2", + "y_stride": "y_stride is the number of y pixels to skip when doing the hough transform. default is 1", + "area_threshold": "area threshold, if the blob area is smaller than area_threshold, the blob is not returned, default is 10", + "pixels_threshold": "pixels threshold, if the blob pixels is smaller than area_threshold, the blob is not returned,, default is 10.\nwhen x_stride and y_stride is equal to 1, pixels_threshold is equivalent to area_threshold", + "merge": "if True merges all not filtered out blobs whos bounding rectangles intersect each other. default is false", + "margin": "margin can be used to increase or decrease the size of the bounding rectangles for blobs during the intersection test.\nFor example, with a margin of 1 blobs whos bounding rectangles are 1 pixel away from each other will be merged. default is 0", + "x_hist_bins_max": "if set to non-zero populates a histogram buffer in each blob object with an x_histogram projection of all columns in the object. This value then sets the number of bins for that projection.", + "y_hist_bins_max": "if set to non-zero populates a histogram buffer in each blob object with an y_histogram projection of all rows in the object. This value then sets the number of bins for that projection." + }, + "return": "Return the blob when found blobs, format is (blob1, blob2, ...), you can use blob class methods to do more operations.", + "maixpy": "maix.image.Image.find_blobs", + "py_doc": "Finds all blobs in the image and returns a list of image.Blob class which describe each Blob.\nPlease see the image.Blob object more more information.\n\nArgs:\n - thresholds: You can define multiple thresholds.\nFor GRAYSCALE format, you can use {{Lmin, Lmax}, ...} to define one or more thresholds.\nFor RGB888 format, you can use {{Lmin, Lmax, Amin, Amax, Bmin, Bmax}, ...} to define one or more thresholds.\nWhere the upper case L,A,B represent the L,A,B channels of the LAB image format, and min, max represent the minimum and maximum values of the corresponding channels.\n - invert: if true, will invert thresholds before find blobs, default is false\n - roi: The region of interest, input in the format of (x, y, w, h), x and y are the coordinates of the upper left corner, w and h are the width and height of roi.\ndefault is None, means whole image.\n - x_stride: x stride is the number of x pixels to skip when doing the hough transform. default is 2\n - y_stride: y_stride is the number of y pixels to skip when doing the hough transform. default is 1\n - area_threshold: area threshold, if the blob area is smaller than area_threshold, the blob is not returned, default is 10\n - pixels_threshold: pixels threshold, if the blob pixels is smaller than area_threshold, the blob is not returned,, default is 10.\nwhen x_stride and y_stride is equal to 1, pixels_threshold is equivalent to area_threshold\n - merge: if True merges all not filtered out blobs whos bounding rectangles intersect each other. default is false\n - margin: margin can be used to increase or decrease the size of the bounding rectangles for blobs during the intersection test.\nFor example, with a margin of 1 blobs whos bounding rectangles are 1 pixel away from each other will be merged. default is 0\n - x_hist_bins_max: if set to non-zero populates a histogram buffer in each blob object with an x_histogram projection of all columns in the object. This value then sets the number of bins for that projection.\n - y_hist_bins_max: if set to non-zero populates a histogram buffer in each blob object with an y_histogram projection of all rows in the object. This value then sets the number of bins for that projection.\n\n\nReturns: Return the blob when found blobs, format is (blob1, blob2, ...), you can use blob class methods to do more operations.\n" + }, + "args": [ + [ + "std::vector>", + "thresholds", + "std::vector>()" + ], + [ + "bool", + "invert", + "false" + ], + [ + "std::vector", + "roi", + "std::vector()" + ], + [ + "int", + "x_stride", + "2" + ], + [ + "int", + "y_stride", + "1" + ], + [ + "int", + "area_threshold", + "10" + ], + [ + "int", + "pixels_threshold", + "10" + ], + [ + "bool", + "merge", + "false" + ], + [ + "int", + "margin", + "0" + ], + [ + "int", + "x_hist_bins_max", + "0" + ], + [ + "int", + "y_hist_bins_max", + "0" + ] + ], + "ret_type": "std::vector", + "static": false, + "def": "std::vector find_blobs(std::vector> thresholds = std::vector>(), bool invert = false, std::vector roi = std::vector(), int x_stride = 2, int y_stride = 1, int area_threshold = 10, int pixels_threshold = 10, bool merge = false, int margin = 0, int x_hist_bins_max = 0, int y_hist_bins_max = 0)" + }, + "find_lines": { + "type": "func", + "name": "find_lines", + "doc": { + "brief": "Find lines in image", + "param": { + "roi": "The region of interest, input in the format of (x, y, w, h), x and y are the coordinates of the upper left corner, w and h are the width and height of roi.\ndefault is None, means whole image.", + "x_stride": "x stride is the number of x pixels to skip when doing the hough transform. default is 2", + "y_stride": "y_stride is the number of y pixels to skip when doing the hough transform. default is 1", + "threshold": "threshold threshold controls what lines are detected from the hough transform. Only lines with a magnitude greater than or equal to threshold are returned.\nThe right value of threshold for your application is image dependent. default is 1000.", + "theta_margin": "theta_margin controls the merging of detected lines. default is 25.", + "rho_margin": "rho_margin controls the merging of detected lines. default is 25." + }, + "return": "Return the line when found lines, format is (line1, line2, ...), you can use line class methods to do more operations", + "maixpy": "maix.image.Image.find_lines", + "py_doc": "Find lines in image\n\nArgs:\n - roi: The region of interest, input in the format of (x, y, w, h), x and y are the coordinates of the upper left corner, w and h are the width and height of roi.\ndefault is None, means whole image.\n - x_stride: x stride is the number of x pixels to skip when doing the hough transform. default is 2\n - y_stride: y_stride is the number of y pixels to skip when doing the hough transform. default is 1\n - threshold: threshold threshold controls what lines are detected from the hough transform. Only lines with a magnitude greater than or equal to threshold are returned.\nThe right value of threshold for your application is image dependent. default is 1000.\n - theta_margin: theta_margin controls the merging of detected lines. default is 25.\n - rho_margin: rho_margin controls the merging of detected lines. default is 25.\n\n\nReturns: Return the line when found lines, format is (line1, line2, ...), you can use line class methods to do more operations\n" + }, + "args": [ + [ + "std::vector", + "roi", + "std::vector()" + ], + [ + "int", + "x_stride", + "2" + ], + [ + "int", + "y_stride", + "1" + ], + [ + "double", + "threshold", + "1000" + ], + [ + "double", + "theta_margin", + "25" + ], + [ + "double", + "rho_margin", + "25" + ] + ], + "ret_type": "std::vector", + "static": false, + "def": "std::vector find_lines(std::vector roi = std::vector(), int x_stride = 2, int y_stride = 1, double threshold = 1000, double theta_margin = 25, double rho_margin = 25)" + }, + "find_line_segments": { + "type": "func", + "name": "find_line_segments", + "doc": { + "brief": "Finds all line segments in the image.", + "param": { + "roi": "The region of interest, input in the format of (x, y, w, h), x and y are the coordinates of the upper left corner, w and h are the width and height of roi.\ndefault is None, means whole image.", + "merge_distance": "The maximum distance between two lines to merge them. default is 0.", + "max_theta_difference": "The maximum difference between two lines to merge them. default is 15." + }, + "return": "Return the line when found lines, format is (line1, line2, ...), you can use line class methods to do more operations", + "maixpy": "maix.image.Image.find_line_segments", + "py_doc": "Finds all line segments in the image.\n\nArgs:\n - roi: The region of interest, input in the format of (x, y, w, h), x and y are the coordinates of the upper left corner, w and h are the width and height of roi.\ndefault is None, means whole image.\n - merge_distance: The maximum distance between two lines to merge them. default is 0.\n - max_theta_difference: The maximum difference between two lines to merge them. default is 15.\n\n\nReturns: Return the line when found lines, format is (line1, line2, ...), you can use line class methods to do more operations\n" + }, + "args": [ + [ + "std::vector", + "roi", + "std::vector()" + ], + [ + "int", + "merge_distance", + "0" + ], + [ + "int", + "max_theta_difference", + "15" + ] + ], + "ret_type": "std::vector", + "static": false, + "def": "std::vector find_line_segments(std::vector roi = std::vector(), int merge_distance = 0, int max_theta_difference = 15)" + }, + "search_line_path": { + "type": "func", + "name": "search_line_path", + "doc": { + "brief": "Search the path of line", + "param": { + "thresholds": "You can define multiple thresholds.\nFor GRAYSCALE format, you can use {{Lmin, Lmax}, ...} to define one or more thresholds.\nFor RGB888 format, you can use {{Lmin, Lmax, Amin, Amax, Bmin, Bmax}, ...} to define one or more thresholds.\nWhere the upper case L,A,B represent the L,A,B channels of the LAB image format, and min, max represent the minimum and maximum values of the corresponding channels.", + "detect_pixel_size": "Before finding the path, the screen is divided into several smaller blocks, each with a width and height of detect_pixel_size. The smaller the detect_pixel_size, the finer the division. the unit is pixels.", + "point_merge_size": "Minimum distance between merged point sets. the unit is pixels.", + "connection_max_size": "Minimum size allowed for connecting points to form a line. the unit is pixels.", + "connection_max_distance": "Minimum distance allowed for point to line. the unit is pixels.", + "connection_max_angle": "Minimum angle allowed for connecting points to form a line." + }, + "return": "Return the line when found lines, format is (groupline1, groupline2, ...), you can use LineGroup class methods to do more operations", + "maixpy": "maix.image.Image.search_line_path", + "py_doc": "Search the path of line\n\nArgs:\n - thresholds: You can define multiple thresholds.\nFor GRAYSCALE format, you can use {{Lmin, Lmax}, ...} to define one or more thresholds.\nFor RGB888 format, you can use {{Lmin, Lmax, Amin, Amax, Bmin, Bmax}, ...} to define one or more thresholds.\nWhere the upper case L,A,B represent the L,A,B channels of the LAB image format, and min, max represent the minimum and maximum values of the corresponding channels.\n - detect_pixel_size: Before finding the path, the screen is divided into several smaller blocks, each with a width and height of detect_pixel_size. The smaller the detect_pixel_size, the finer the division. the unit is pixels.\n - point_merge_size: Minimum distance between merged point sets. the unit is pixels.\n - connection_max_size: Minimum size allowed for connecting points to form a line. the unit is pixels.\n - connection_max_distance: Minimum distance allowed for point to line. the unit is pixels.\n - connection_max_angle: Minimum angle allowed for connecting points to form a line.\n\n\nReturns: Return the line when found lines, format is (groupline1, groupline2, ...), you can use LineGroup class methods to do more operations\n" + }, + "args": [ + [ + "std::vector>", + "thresholds", + "std::vector>()" + ], + [ + "int", + "detect_pixel_size", + "30" + ], + [ + "int", + "point_merge_size", + "15" + ], + [ + "int", + "connection_max_size", + "51" + ], + [ + "int", + "connection_max_distance", + "20" + ], + [ + "int", + "connection_max_angle", + "20" + ] + ], + "ret_type": "std::vector", + "static": false, + "def": "std::vector search_line_path(std::vector> thresholds = std::vector>(), int detect_pixel_size = 30, int point_merge_size = 15, int connection_max_size = 51, int connection_max_distance = 20, int connection_max_angle = 20)" + }, + "find_circles": { + "type": "func", + "name": "find_circles", + "doc": { + "brief": "Find circles in image", + "param": { + "roi": "The region of interest, input in the format of (x, y, w, h), x and y are the coordinates of the upper left corner, w and h are the width and height of roi.\ndefault is None, means whole image.", + "x_stride": "x stride is the number of x pixels to skip when doing the hough transform. default is 2", + "y_stride": "y_stride is the number of y pixels to skip when doing the hough transform. default is 1", + "threshold": "threshold controls what circles are detected from the hough transform. Only circles with a magnitude greater than or equal to threshold are returned.\nThe right value of threshold for your application is image dependent.", + "x_margin": "x_margin controls the merging of detected circles. Circles which are x_margin, y_margin, and r_margin pixels apart are merged. default is 10", + "y_margin": "y_margin controls the merging of detected circles. Circles which are x_margin, y_margin, and r_margin pixels apart are merged. default is 10", + "r_margin": "r_margin controls the merging of detected circles. Circles which are x_margin, y_margin, and r_margin pixels apart are merged. default is 10", + "r_min": "r_min controls the minimum circle radius detected. Increase this to speed up the algorithm. default is 2", + "r_max": "r_max controls the maximum circle radius detected. Decrease this to speed up the algorithm. default is min(roi.w / 2, roi.h / 2)", + "r_step": "r_step controls how to step the radius detection by. default is 2." + }, + "return": "Return the circle when found circles, format is (circle1, circle2, ...), you can use circle class methods to do more operations", + "maixpy": "maix.image.Image.find_circles", + "py_doc": "Find circles in image\n\nArgs:\n - roi: The region of interest, input in the format of (x, y, w, h), x and y are the coordinates of the upper left corner, w and h are the width and height of roi.\ndefault is None, means whole image.\n - x_stride: x stride is the number of x pixels to skip when doing the hough transform. default is 2\n - y_stride: y_stride is the number of y pixels to skip when doing the hough transform. default is 1\n - threshold: threshold controls what circles are detected from the hough transform. Only circles with a magnitude greater than or equal to threshold are returned.\nThe right value of threshold for your application is image dependent.\n - x_margin: x_margin controls the merging of detected circles. Circles which are x_margin, y_margin, and r_margin pixels apart are merged. default is 10\n - y_margin: y_margin controls the merging of detected circles. Circles which are x_margin, y_margin, and r_margin pixels apart are merged. default is 10\n - r_margin: r_margin controls the merging of detected circles. Circles which are x_margin, y_margin, and r_margin pixels apart are merged. default is 10\n - r_min: r_min controls the minimum circle radius detected. Increase this to speed up the algorithm. default is 2\n - r_max: r_max controls the maximum circle radius detected. Decrease this to speed up the algorithm. default is min(roi.w / 2, roi.h / 2)\n - r_step: r_step controls how to step the radius detection by. default is 2.\n\n\nReturns: Return the circle when found circles, format is (circle1, circle2, ...), you can use circle class methods to do more operations\n" + }, + "args": [ + [ + "std::vector", + "roi", + "std::vector()" + ], + [ + "int", + "x_stride", + "2" + ], + [ + "int", + "y_stride", + "1" + ], + [ + "int", + "threshold", + "2000" + ], + [ + "int", + "x_margin", + "10" + ], + [ + "int", + "y_margin", + "10" + ], + [ + "int", + "r_margin", + "10" + ], + [ + "int", + "r_min", + "2" + ], + [ + "int", + "r_max", + "-1" + ], + [ + "int", + "r_step", + "2" + ] + ], + "ret_type": "std::vector", + "static": false, + "def": "std::vector find_circles(std::vector roi = std::vector(), int x_stride = 2, int y_stride = 1, int threshold = 2000, int x_margin = 10, int y_margin = 10, int r_margin = 10, int r_min = 2, int r_max = -1, int r_step = 2)" + }, + "find_rects": { + "type": "func", + "name": "find_rects", + "doc": { + "brief": "Finds all rects in the image.", + "param": { + "roi": "The region of interest, input in the format of (x, y, w, h), x and y are the coordinates of the upper left corner, w and h are the width and height of roi.\ndefault is None, means whole image.", + "threshold": "The threshold to use for the rects. default is 10000." + }, + "return": "Returns the rects of the image", + "maixpy": "maix.image.Image.find_rects", + "py_doc": "Finds all rects in the image.\n\nArgs:\n - roi: The region of interest, input in the format of (x, y, w, h), x and y are the coordinates of the upper left corner, w and h are the width and height of roi.\ndefault is None, means whole image.\n - threshold: The threshold to use for the rects. default is 10000.\n\n\nReturns: Returns the rects of the image\n" + }, + "args": [ + [ + "std::vector", + "roi", + "std::vector()" + ], + [ + "int", + "threshold", + "10000" + ] + ], + "ret_type": "std::vector", + "static": false, + "def": "std::vector find_rects(std::vector roi = std::vector(), int threshold = 10000)" + }, + "find_qrcodes": { + "type": "func", + "name": "find_qrcodes", + "doc": { + "brief": "Finds all qrcodes in the image.", + "param": { + "roi": "The region of interest, input in the format of (x, y, w, h), x and y are the coordinates of the upper left corner, w and h are the width and height of roi.\ndefault is None, means whole image.", + "decoder_type": "Select the QR code decoding method. Choosing QRCODE_DECODER_TYPE_QUIRC allows for retrieving QR code version, ECC level, mask, data type, and other details,\nthough it may decode slower at lower resolutions. Opting for QRCODE_DECODER_TYPE_ZBAR enables faster decoding at lower resolutions but may slow down at higher resolutions,\nproviding only the QR code content and position information. default is QRCODE_DECODER_TYPE_ZBAR." + }, + "return": "Returns the qrcodes of the image", + "maixpy": "maix.image.Image.find_qrcodes", + "py_doc": "Finds all qrcodes in the image.\n\nArgs:\n - roi: The region of interest, input in the format of (x, y, w, h), x and y are the coordinates of the upper left corner, w and h are the width and height of roi.\ndefault is None, means whole image.\n - decoder_type: Select the QR code decoding method. Choosing QRCODE_DECODER_TYPE_QUIRC allows for retrieving QR code version, ECC level, mask, data type, and other details,\nthough it may decode slower at lower resolutions. Opting for QRCODE_DECODER_TYPE_ZBAR enables faster decoding at lower resolutions but may slow down at higher resolutions,\nproviding only the QR code content and position information. default is QRCODE_DECODER_TYPE_ZBAR.\n\n\nReturns: Returns the qrcodes of the image\n" + }, + "args": [ + [ + "std::vector", + "roi", + "std::vector()" + ], + [ + "image::QRCodeDecoderType", + "decoder_type", + "image::QRCodeDecoderType::QRCODE_DECODER_TYPE_ZBAR" + ] + ], + "ret_type": "std::vector", + "static": false, + "def": "std::vector find_qrcodes(std::vector roi = std::vector(), image::QRCodeDecoderType decoder_type = image::QRCodeDecoderType::QRCODE_DECODER_TYPE_ZBAR)" + }, + "find_apriltags": { + "type": "func", + "name": "find_apriltags", + "doc": { + "brief": "Finds all apriltags in the image.", + "param": { + "roi": "The region of interest, input in the format of (x, y, w, h), x and y are the coordinates of the upper left corner, w and h are the width and height of roi.\ndefault is None, means whole image.", + "families": "The families to use for the apriltags. default is TAG36H11.", + "fx": "The camera X focal length in pixels, default is -1.", + "fy": "The camera Y focal length in pixels, default is -1.", + "cx": "The camera X center in pixels, default is image.width / 2.", + "cy": "The camera Y center in pixels, default is image.height / 2." + }, + "return": "Returns the apriltags of the image", + "maixpy": "maix.image.Image.find_apriltags", + "py_doc": "Finds all apriltags in the image.\n\nArgs:\n - roi: The region of interest, input in the format of (x, y, w, h), x and y are the coordinates of the upper left corner, w and h are the width and height of roi.\ndefault is None, means whole image.\n - families: The families to use for the apriltags. default is TAG36H11.\n - fx: The camera X focal length in pixels, default is -1.\n - fy: The camera Y focal length in pixels, default is -1.\n - cx: The camera X center in pixels, default is image.width / 2.\n - cy: The camera Y center in pixels, default is image.height / 2.\n\n\nReturns: Returns the apriltags of the image\n" + }, + "args": [ + [ + "std::vector", + "roi", + "std::vector()" + ], + [ + "image::ApriltagFamilies", + "families", + "image::ApriltagFamilies::TAG36H11" + ], + [ + "float", + "fx", + "-1" + ], + [ + "float", + "fy", + "-1" + ], + [ + "int", + "cx", + "-1" + ], + [ + "int", + "cy", + "-1" + ] + ], + "ret_type": "std::vector", + "static": false, + "def": "std::vector find_apriltags(std::vector roi = std::vector(), image::ApriltagFamilies families = image::ApriltagFamilies::TAG36H11, float fx = -1, float fy = -1, int cx = -1, int cy = -1)" + }, + "find_datamatrices": { + "type": "func", + "name": "find_datamatrices", + "doc": { + "brief": "Finds all datamatrices in the image.", + "param": { + "roi": "The region of interest, input in the format of (x, y, w, h), x and y are the coordinates of the upper left corner, w and h are the width and height of roi.\ndefault is None, means whole image.", + "effort": "Controls how much time to spend trying to find data matrix matches. default is 200." + }, + "return": "Returns the datamatrices of the image", + "maixpy": "maix.image.Image.find_datamatrices", + "py_doc": "Finds all datamatrices in the image.\n\nArgs:\n - roi: The region of interest, input in the format of (x, y, w, h), x and y are the coordinates of the upper left corner, w and h are the width and height of roi.\ndefault is None, means whole image.\n - effort: Controls how much time to spend trying to find data matrix matches. default is 200.\n\n\nReturns: Returns the datamatrices of the image\n" + }, + "args": [ + [ + "std::vector", + "roi", + "std::vector()" + ], + [ + "int", + "effort", + "200" + ] + ], + "ret_type": "std::vector", + "static": false, + "def": "std::vector find_datamatrices(std::vector roi = std::vector(), int effort = 200)" + }, + "find_barcodes": { + "type": "func", + "name": "find_barcodes", + "doc": { + "brief": "Finds all barcodes in the image.", + "param": { + "roi": "The region of interest, input in the format of (x, y, w, h), x and y are the coordinates of the upper left corner, w and h are the width and height of roi.\ndefault is None, means whole image." + }, + "return": "Returns the barcodes of the image", + "maixpy": "maix.image.Image.find_barcodes", + "py_doc": "Finds all barcodes in the image.\n\nArgs:\n - roi: The region of interest, input in the format of (x, y, w, h), x and y are the coordinates of the upper left corner, w and h are the width and height of roi.\ndefault is None, means whole image.\n\n\nReturns: Returns the barcodes of the image\n" + }, + "args": [ + [ + "std::vector", + "roi", + "std::vector()" + ] + ], + "ret_type": "std::vector", + "static": false, + "def": "std::vector find_barcodes(std::vector roi = std::vector())" + }, + "find_displacement": { + "type": "func", + "name": "find_displacement", + "doc": { + "brief": "Finds the displacement between the image and the template. TODO: support in the feature\\nnote: this method must be used on power-of-2 image sizes", + "param": { + "template_image": "The template image.", + "roi": "The region of interest, input in the format of (x, y, w, h), x and y are the coordinates of the upper left corner, w and h are the width and height of roi.\ndefault is None, means whole image.", + "template_roi": "The region-of-interest rectangle (x, y, w, h) to work in. If not specified, it is equal to the image rectangle.", + "logpolar": "If true, it will instead find rotation and scale changes between the two images. default is false." + }, + "return": "Returns the displacement of the image", + "maixpy": "maix.image.Image.find_displacement", + "py_doc": "Finds the displacement between the image and the template. TODO: support in the feature\nnote: this method must be used on power-of-2 image sizes\n\nArgs:\n - template_image: The template image.\n - roi: The region of interest, input in the format of (x, y, w, h), x and y are the coordinates of the upper left corner, w and h are the width and height of roi.\ndefault is None, means whole image.\n - template_roi: The region-of-interest rectangle (x, y, w, h) to work in. If not specified, it is equal to the image rectangle.\n - logpolar: If true, it will instead find rotation and scale changes between the two images. default is false.\n\n\nReturns: Returns the displacement of the image\n" + }, + "args": [ + [ + "image::Image &", + "template_image", + null + ], + [ + "std::vector", + "roi", + "std::vector()" + ], + [ + "std::vector", + "template_roi", + "std::vector()" + ], + [ + "bool", + "logpolar", + "false" + ] + ], + "ret_type": "image::Displacement", + "static": false, + "def": "image::Displacement find_displacement(image::Image &template_image, std::vector roi = std::vector(), std::vector template_roi = std::vector(), bool logpolar = false)" + }, + "find_template": { + "type": "func", + "name": "find_template", + "doc": { + "brief": "Finds the template in the image.", + "param": { + "template_image": "The template image.", + "threshold": "Threshold is floating point number (0.0-1.0) where a higher threshold prevents false positives while lowering the detection rate while a lower threshold does the opposite.", + "roi": "The region of interest, input in the format of (x, y, w, h), x and y are the coordinates of the upper left corner, w and h are the width and height of roi.\ndefault is None, means whole image. Only valid in SEARCH_EX mode.", + "step": "The step size to use for the template. default is 2. Only valid in SEARCH_EX mode", + "search": "The search method to use for the template. default is SEARCH_EX." + }, + "return": "Returns a bounding box tuple (x, y, w, h) for the matching location otherwise None.", + "maixpy": "maix.image.Image.find_template", + "py_doc": "Finds the template in the image.\n\nArgs:\n - template_image: The template image.\n - threshold: Threshold is floating point number (0.0-1.0) where a higher threshold prevents false positives while lowering the detection rate while a lower threshold does the opposite.\n - roi: The region of interest, input in the format of (x, y, w, h), x and y are the coordinates of the upper left corner, w and h are the width and height of roi.\ndefault is None, means whole image. Only valid in SEARCH_EX mode.\n - step: The step size to use for the template. default is 2. Only valid in SEARCH_EX mode\n - search: The search method to use for the template. default is SEARCH_EX.\n\n\nReturns: Returns a bounding box tuple (x, y, w, h) for the matching location otherwise None.\n" + }, + "args": [ + [ + "image::Image &", + "template_image", + null + ], + [ + "float", + "threshold", + null + ], + [ + "std::vector", + "roi", + "std::vector()" + ], + [ + "int", + "step", + "2" + ], + [ + "image::TemplateMatch", + "search", + "image::TemplateMatch::SEARCH_EX" + ] + ], + "ret_type": "std::vector", + "static": false, + "def": "std::vector find_template(image::Image &template_image, float threshold, std::vector roi = std::vector(), int step = 2, image::TemplateMatch search = image::TemplateMatch::SEARCH_EX)" + }, + "find_features": { + "type": "func", + "name": "find_features", + "doc": { + "brief": "Finds the features in the image. TODO: support in the feature", + "param": { + "cascade": "The cascade to use for the features. default is CASCADE_FRONTALFACE_ALT.", + "threshold": "The threshold to use for the features. default is 0.5.", + "scale": "The scale to use for the features. default is 1.5.", + "roi": "The region of interest, input in the format of (x, y, w, h), x and y are the coordinates of the upper left corner, w and h are the width and height of roi.\ndefault is None, means whole image." + }, + "return": "Returns the features of the image", + "maixpy": "maix.image.Image.find_features", + "py_doc": "Finds the features in the image. TODO: support in the feature\n\nArgs:\n - cascade: The cascade to use for the features. default is CASCADE_FRONTALFACE_ALT.\n - threshold: The threshold to use for the features. default is 0.5.\n - scale: The scale to use for the features. default is 1.5.\n - roi: The region of interest, input in the format of (x, y, w, h), x and y are the coordinates of the upper left corner, w and h are the width and height of roi.\ndefault is None, means whole image.\n\n\nReturns: Returns the features of the image\n" + }, + "args": [ + [ + "int", + "cascade", + null + ], + [ + "float", + "threshold", + "0.5" + ], + [ + "float", + "scale", + "1.5" + ], + [ + "std::vector", + "roi", + "std::vector()" + ] + ], + "ret_type": "std::vector", + "static": false, + "def": "std::vector find_features(int cascade, float threshold = 0.5, float scale = 1.5, std::vector roi = std::vector())" + }, + "find_lbp": { + "type": "func", + "name": "find_lbp", + "doc": { + "brief": "Finds the lbp in the image. TODO: support in the feature.", + "param": { + "roi": "The region of interest, input in the format of (x, y, w, h), x and y are the coordinates of the upper left corner, w and h are the width and height of roi.\ndefault is None, means whole image." + }, + "return": "Returns the lbp of the image", + "maixpy": "maix.image.Image.find_lbp", + "py_doc": "Finds the lbp in the image. TODO: support in the feature.\n\nArgs:\n - roi: The region of interest, input in the format of (x, y, w, h), x and y are the coordinates of the upper left corner, w and h are the width and height of roi.\ndefault is None, means whole image.\n\n\nReturns: Returns the lbp of the image\n" + }, + "args": [ + [ + "std::vector", + "roi", + "std::vector()" + ] + ], + "ret_type": "image::LBPKeyPoint", + "static": false, + "def": "image::LBPKeyPoint find_lbp(std::vector roi = std::vector())" + }, + "find_keypoints": { + "type": "func", + "name": "find_keypoints", + "doc": { + "brief": "Finds the keypoints in the image. TODO: support in the feature.", + "param": { + "roi": "The region of interest, input in the format of (x, y, w, h), x and y are the coordinates of the upper left corner, w and h are the width and height of roi.\ndefault is None, means whole image.", + "threshold": "The threshold to use for the keypoints. default is 20.", + "normalized": "If true, the image will be normalized before the operation. default is false.", + "scale_factor": "The scale factor to use for the keypoints. default is 1.5.", + "max_keypoints": "The maximum number of keypoints to use for the keypoints. default is 100.", + "corner_detector": "The corner detector to use for the keypoints. default is CORNER_AGAST." + }, + "return": "Returns the keypoints of the image", + "maixpy": "maix.image.Image.find_keypoints", + "py_doc": "Finds the keypoints in the image. TODO: support in the feature.\n\nArgs:\n - roi: The region of interest, input in the format of (x, y, w, h), x and y are the coordinates of the upper left corner, w and h are the width and height of roi.\ndefault is None, means whole image.\n - threshold: The threshold to use for the keypoints. default is 20.\n - normalized: If true, the image will be normalized before the operation. default is false.\n - scale_factor: The scale factor to use for the keypoints. default is 1.5.\n - max_keypoints: The maximum number of keypoints to use for the keypoints. default is 100.\n - corner_detector: The corner detector to use for the keypoints. default is CORNER_AGAST.\n\n\nReturns: Returns the keypoints of the image\n" + }, + "args": [ + [ + "std::vector", + "roi", + "std::vector()" + ], + [ + "int", + "threshold", + "20" + ], + [ + "bool", + "normalized", + "false" + ], + [ + "float", + "scale_factor", + "1.5" + ], + [ + "int", + "max_keypoints", + "100" + ], + [ + "image::CornerDetector", + "corner_detector", + "image::CornerDetector::CORNER_AGAST" + ] + ], + "ret_type": "image::ORBKeyPoint", + "static": false, + "def": "image::ORBKeyPoint find_keypoints(std::vector roi = std::vector(), int threshold = 20, bool normalized = false, float scale_factor = 1.5, int max_keypoints = 100, image::CornerDetector corner_detector = image::CornerDetector::CORNER_AGAST)" + }, + "find_edges": { + "type": "func", + "name": "find_edges", + "doc": { + "brief": "Finds the edges in the image.", + "param": { + "edge_type": "The edge type to use for the edges. default is EDGE_CANNY.", + "roi": "The region of interest, input in the format of (x, y, w, h), x and y are the coordinates of the upper left corner, w and h are the width and height of roi.\ndefault is None, means whole image.", + "threshold": "The threshold to use for the edges. default is 20." + }, + "return": "Returns the edges of the image", + "maixpy": "maix.image.Image.find_edges", + "py_doc": "Finds the edges in the image.\n\nArgs:\n - edge_type: The edge type to use for the edges. default is EDGE_CANNY.\n - roi: The region of interest, input in the format of (x, y, w, h), x and y are the coordinates of the upper left corner, w and h are the width and height of roi.\ndefault is None, means whole image.\n - threshold: The threshold to use for the edges. default is 20.\n\n\nReturns: Returns the edges of the image\n" + }, + "args": [ + [ + "image::EdgeDetector", + "edge_type", + null + ], + [ + "std::vector", + "roi", + "std::vector()" + ], + [ + "std::vector", + "threshold", + "std::vector({100, 200})" + ] + ], + "ret_type": "image::Image*", + "static": false, + "def": "image::Image* find_edges(image::EdgeDetector edge_type, std::vector roi = std::vector(), std::vector threshold = std::vector({100, 200}))" + }, + "find_hog": { + "type": "func", + "name": "find_hog", + "doc": { + "brief": "Finds the hog in the image. TODO: support in the feature", + "param": { + "roi": "The region of interest, input in the format of (x, y, w, h), x and y are the coordinates of the upper left corner, w and h are the width and height of roi.\ndefault is None, means whole image.", + "size": "The size to use for the hog. default is 8." + }, + "return": "Returns the hog of the image", + "maixpy": "maix.image.Image.find_hog", + "py_doc": "Finds the hog in the image. TODO: support in the feature\n\nArgs:\n - roi: The region of interest, input in the format of (x, y, w, h), x and y are the coordinates of the upper left corner, w and h are the width and height of roi.\ndefault is None, means whole image.\n - size: The size to use for the hog. default is 8.\n\n\nReturns: Returns the hog of the image\n" + }, + "args": [ + [ + "std::vector", + "roi", + "std::vector()" + ], + [ + "int", + "size", + "8" + ] + ], + "ret_type": "image::Image*", + "static": false, + "def": "image::Image* find_hog(std::vector roi = std::vector(), int size = 8)" + }, + "match_lbp_descriptor": { + "type": "func", + "name": "match_lbp_descriptor", + "doc": { + "brief": "Matches the lbp descriptor of the image. TODO: support in the feature", + "param": { + "desc1": "The descriptor to use for the match.", + "desc2": "The descriptor to use for the match." + }, + "return": "Returns the match of the image", + "maixpy": "maix.image.Image.match_lbp_descriptor", + "py_doc": "Matches the lbp descriptor of the image. TODO: support in the feature\n\nArgs:\n - desc1: The descriptor to use for the match.\n - desc2: The descriptor to use for the match.\n\n\nReturns: Returns the match of the image\n" + }, + "args": [ + [ + "image::LBPKeyPoint &", + "desc1", + null + ], + [ + "image::LBPKeyPoint &", + "desc2", + null + ] + ], + "ret_type": "int", + "static": false, + "def": "int match_lbp_descriptor(image::LBPKeyPoint &desc1, image::LBPKeyPoint &desc2)" + }, + "match_orb_descriptor": { + "type": "func", + "name": "match_orb_descriptor", + "doc": { + "brief": "Matches the orb descriptor of the image. TODO: support in the feature", + "param": { + "desc1": "The descriptor to use for the match.", + "desc2": "The descriptor to use for the match.", + "threshold": "The threshold to use for the match. default is 95.", + "filter_outliers": "If true, the image will be filter_outliers before the operation. default is false." + }, + "return": "Returns the match of the image", + "maixpy": "maix.image.Image.match_orb_descriptor", + "py_doc": "Matches the orb descriptor of the image. TODO: support in the feature\n\nArgs:\n - desc1: The descriptor to use for the match.\n - desc2: The descriptor to use for the match.\n - threshold: The threshold to use for the match. default is 95.\n - filter_outliers: If true, the image will be filter_outliers before the operation. default is false.\n\n\nReturns: Returns the match of the image\n" + }, + "args": [ + [ + "image::ORBKeyPoint &", + "desc1", + null + ], + [ + "image::ORBKeyPoint &", + "desc2", + null + ], + [ + "int", + "threshold", + "95" + ], + [ + "bool", + "filter_outliers", + "false" + ] + ], + "ret_type": "image::KPTMatch", + "static": false, + "def": "image::KPTMatch match_orb_descriptor(image::ORBKeyPoint &desc1, image::ORBKeyPoint &desc2, int threshold = 95, bool filter_outliers = false)" + } + }, + "def": "class Image" + }, + "load": { + "type": "func", + "name": "load", + "doc": { + "brief": "Load image from file, and convert to Image object", + "param": { + "path": "image file path", + "format": "read as this format, if not match, will convert to this format, by default is RGB888" + }, + "return": "Image object, if load failed, will return None(nullptr in C++), so you should care about it.", + "maixpy": "maix.image.load", + "py_doc": "Load image from file, and convert to Image object\n\nArgs:\n - path: image file path\n - format: read as this format, if not match, will convert to this format, by default is RGB888\n\n\nReturns: Image object, if load failed, will return None(nullptr in C++), so you should care about it.\n" + }, + "args": [ + [ + "const char *", + "path", + null + ], + [ + "image::Format", + "format", + "image::Format::FMT_RGB888" + ] + ], + "ret_type": "image::Image*", + "static": false, + "def": "image::Image *load(const char *path, image::Format format = image::Format::FMT_RGB888)" + }, + "from_bytes": { + "type": "func", + "name": "from_bytes", + "doc": { + "brief": "Create image from bytes", + "param": { + "width": "image width", + "height": "image height", + "format": "image format", + "data": "image data, if data is None, will malloc memory for image data\nIf the image is in jpeg format, data must be filled in.", + "copy": "if true and data is not None, will copy data to new buffer, else will use data directly. default is true to avoid memory leak.\nUse it carefully!!!" + }, + "return": "Image object", + "maixpy": "maix.image.from_bytes", + "py_doc": "Create image from bytes\n\nArgs:\n - width: image width\n - height: image height\n - format: image format\n - data: image data, if data is None, will malloc memory for image data\nIf the image is in jpeg format, data must be filled in.\n - copy: if true and data is not None, will copy data to new buffer, else will use data directly. default is true to avoid memory leak.\nUse it carefully!!!\n\n\nReturns: Image object\n" + }, + "args": [ + [ + "int", + "width", + null + ], + [ + "int", + "height", + null + ], + [ + "image::Format", + "format", + null + ], + [ + "Bytes *", + "data", + null + ], + [ + "bool", + "copy", + "true" + ] + ], + "ret_type": "image::Image*", + "static": false, + "def": "image::Image *from_bytes(int width, int height, image::Format format, Bytes *data, bool copy = true)" + }, + "load_font": { + "type": "func", + "name": "load_font", + "doc": { + "brief": "Load font from file", + "param": { + "name": "font name, used to identify font", + "path": "font file path, support ttf, ttc, otf", + "size": "font size, font height, by default is 16" + }, + "return": "error code, err::ERR_NONE is ok, other is error", + "maixpy": "maix.image.load_font", + "py_doc": "Load font from file\n\nArgs:\n - name: font name, used to identify font\n - path: font file path, support ttf, ttc, otf\n - size: font size, font height, by default is 16\n\n\nReturns: error code, err::ERR_NONE is ok, other is error\n" + }, + "args": [ + [ + "const std::string &", + "name", + null + ], + [ + "const char *", + "path", + null + ], + [ + "int", + "size", + "16" + ] + ], + "ret_type": "err::Err", + "static": false, + "def": "err::Err load_font(const std::string &name, const char *path, int size = 16)" + }, + "set_default_font": { + "type": "func", + "name": "set_default_font", + "doc": { + "brief": "Set default font, if not call this method, default is hershey_plain", + "param": { + "name": "font name, supported names can be get by fonts()" + }, + "return": "error code, err::ERR_NONE is ok, other is error", + "maixpy": "maix.image.set_default_font", + "py_doc": "Set default font, if not call this method, default is hershey_plain\n\nArgs:\n - name: font name, supported names can be get by fonts()\n\n\nReturns: error code, err::ERR_NONE is ok, other is error\n" + }, + "args": [ + [ + "const std::string &", + "name", + null + ] + ], + "ret_type": "err::Err", + "static": false, + "def": "err::Err set_default_font(const std::string &name)" + }, + "fonts": { + "type": "func", + "name": "fonts", + "doc": { + "brief": "Get all loaded fonts", + "return": "all loaded fonts, string list type", + "maixpy": "maix.image.fonts", + "py_doc": "Get all loaded fonts\n\nReturns: all loaded fonts, string list type\n" + }, + "args": [], + "ret_type": "std::vector*", + "static": false, + "def": "std::vector *fonts()" + }, + "string_size": { + "type": "func", + "name": "string_size", + "doc": { + "brief": "Get text rendered width and height", + "param": { + "string": "text content", + "scale": "font scale, by default(value is 1)", + "thickness": "text thickness(line width), by default(value is 1)" + }, + "return": "text rendered width and height, [width, height]", + "maixpy": "maix.image.string_size", + "py_doc": "Get text rendered width and height\n\nArgs:\n - string: text content\n - scale: font scale, by default(value is 1)\n - thickness: text thickness(line width), by default(value is 1)\n\n\nReturns: text rendered width and height, [width, height]\n" + }, + "args": [ + [ + "std::string", + "string", + null + ], + [ + "float", + "scale", + "1" + ], + [ + "int", + "thickness", + "1" + ], + [ + "const std::string &", + "font", + "\"\"" + ] + ], + "ret_type": "image::Size", + "static": false, + "def": "image::Size string_size(std::string string, float scale = 1, int thickness = 1, const std::string &font = \"\")" + }, + "Color": { + "type": "class", + "name": "Color", + "doc": { + "brief": "Color class", + "maixpy": "maix.image.Color", + "py_doc": "Color class" + }, + "members": { + "__init__": { + "type": "func", + "name": "Color", + "doc": { + "brief": "Color constructor", + "param": { + "alpha": "alpha channel, value range: 0 ~ 1" + }, + "maixpy": "maix.image.Color.__init__", + "py_doc": "Color constructor\n\nArgs:\n - alpha: alpha channel, value range: 0 ~ 1\n" + }, + "args": [ + [ + "uint8_t", + "ch1", + null + ], + [ + "uint8_t", + "ch2", + "0" + ], + [ + "uint8_t", + "ch3", + "0" + ], + [ + "float", + "alpha", + "0" + ], + [ + "image::Format", + "format", + "image::FMT_GRAYSCALE" + ] + ], + "ret_type": null, + "static": false, + "def": "Color(uint8_t ch1, uint8_t ch2 = 0, uint8_t ch3 = 0, float alpha = 0, image::Format format = image::FMT_GRAYSCALE)" + }, + "r": { + "type": "var", + "name": "r", + "doc": { + "brief": "Color red channel", + "maixpy": "maix.image.Color.r", + "py_doc": "Color red channel" + }, + "value": null, + "static": false, + "readonly": false, + "def": "uint8_t r" + }, + "g": { + "type": "var", + "name": "g", + "doc": { + "brief": "Color green channel", + "maixpy": "maix.image.Color.g", + "py_doc": "Color green channel" + }, + "value": null, + "static": false, + "readonly": false, + "def": "uint8_t g" + }, + "b": { + "type": "var", + "name": "b", + "doc": { + "brief": "Color blue channel", + "maixpy": "maix.image.Color.b", + "py_doc": "Color blue channel" + }, + "value": null, + "static": false, + "readonly": false, + "def": "uint8_t b" + }, + "alpha": { + "type": "var", + "name": "alpha", + "doc": { + "brief": "Color alpha channel, value from 0.0 to 1.0, float value", + "maixpy": "maix.image.Color.alpha", + "py_doc": "Color alpha channel, value from 0.0 to 1.0, float value" + }, + "value": null, + "static": false, + "readonly": false, + "def": "float alpha" + }, + "gray": { + "type": "var", + "name": "gray", + "doc": { + "brief": "Color gray channel", + "maixpy": "maix.image.Color.gray", + "py_doc": "Color gray channel" + }, + "value": null, + "static": false, + "readonly": false, + "def": "uint8_t gray" + }, + "format": { + "type": "var", + "name": "format", + "doc": { + "brief": "Color format", + "maixpy": "maix.image.Color.format", + "py_doc": "Color format" + }, + "value": null, + "static": false, + "readonly": false, + "def": "image::Format format" + }, + "hex": { + "type": "func", + "name": "hex", + "doc": { + "brief": "Get color's hex value", + "maixpy": "maix.image.Color.hex", + "py_doc": "Get color's hex value" + }, + "args": [], + "ret_type": "uint32_t", + "static": false, + "def": "uint32_t hex()" + }, + "from_rgb": { + "type": "func", + "name": "from_rgb", + "doc": { + "brief": "Create Color object from RGB channels", + "maixpy": "maix.image.Color.from_rgb", + "py_doc": "Create Color object from RGB channels" + }, + "args": [ + [ + "uint8_t", + "r", + null + ], + [ + "uint8_t", + "g", + null + ], + [ + "uint8_t", + "b", + null + ] + ], + "ret_type": "image::Color", + "static": true, + "def": "static image::Color from_rgb(uint8_t r, uint8_t g, uint8_t b)" + }, + "from_bgr": { + "type": "func", + "name": "from_bgr", + "doc": { + "brief": "Create Color object from BGR channels", + "maixpy": "maix.image.Color.from_bgr", + "py_doc": "Create Color object from BGR channels" + }, + "args": [ + [ + "uint8_t", + "b", + null + ], + [ + "uint8_t", + "g", + null + ], + [ + "uint8_t", + "r", + null + ] + ], + "ret_type": "image::Color", + "static": true, + "def": "static image::Color from_bgr(uint8_t b, uint8_t g, uint8_t r)" + }, + "from_gray": { + "type": "func", + "name": "from_gray", + "doc": { + "brief": "Create Color object from gray channel", + "maixpy": "maix.image.Color.from_gray", + "py_doc": "Create Color object from gray channel" + }, + "args": [ + [ + "uint8_t", + "gray", + null + ] + ], + "ret_type": "image::Color", + "static": true, + "def": "static image::Color from_gray(uint8_t gray)" + }, + "from_rgba": { + "type": "func", + "name": "from_rgba", + "doc": { + "brief": "Create Color object from RGBA channels", + "param": { + "alpha": "alpha channel, float value, value range: 0 ~ 1" + }, + "maixpy": "maix.image.Color.from_rgba", + "py_doc": "Create Color object from RGBA channels\n\nArgs:\n - alpha: alpha channel, float value, value range: 0 ~ 1\n" + }, + "args": [ + [ + "uint8_t", + "r", + null + ], + [ + "uint8_t", + "g", + null + ], + [ + "uint8_t", + "b", + null + ], + [ + "float", + "alpha", + null + ] + ], + "ret_type": "image::Color", + "static": true, + "def": "static image::Color from_rgba(uint8_t r, uint8_t g, uint8_t b, float alpha)" + }, + "from_bgra": { + "type": "func", + "name": "from_bgra", + "doc": { + "brief": "Create Color object from BGRA channels", + "param": { + "alpha": "alpha channel, float value, value range: 0 ~ 1" + }, + "maixpy": "maix.image.Color.from_bgra", + "py_doc": "Create Color object from BGRA channels\n\nArgs:\n - alpha: alpha channel, float value, value range: 0 ~ 1\n" + }, + "args": [ + [ + "uint8_t", + "b", + null + ], + [ + "uint8_t", + "g", + null + ], + [ + "uint8_t", + "r", + null + ], + [ + "float", + "alpha", + null + ] + ], + "ret_type": "image::Color", + "static": true, + "def": "static image::Color from_bgra(uint8_t b, uint8_t g, uint8_t r, float alpha)" + }, + "from_hex": { + "type": "func", + "name": "from_hex", + "doc": { + "brief": "Create Color object from hex value", + "param": { + "hex": "hex value, e.g. 0x0000FF00, lower address if first channel", + "format": "color format, @see image::Format" + }, + "maixpy": "maix.image.Color.from_hex", + "py_doc": "Create Color object from hex value\n\nArgs:\n - hex: hex value, e.g. 0x0000FF00, lower address if first channel\n - format: color format, @see image::Format\n" + }, + "args": [ + [ + "uint32_t", + "hex", + null + ], + [ + "image::Format &", + "format", + null + ] + ], + "ret_type": "image::Color", + "static": true, + "def": "static image::Color from_hex(uint32_t hex, image::Format &format)" + }, + "to_format": { + "type": "func", + "name": "to_format", + "doc": { + "brief": "Convert Color format", + "param": { + "format": "format want to convert to, @see image::Format, only support RGB888, BGR888, RGBA8888, BGRA8888, GRAYSCALE." + }, + "maixpy": "maix.image.Color.to_format", + "py_doc": "Convert Color format\n\nArgs:\n - format: format want to convert to, @see image::Format, only support RGB888, BGR888, RGBA8888, BGRA8888, GRAYSCALE.\n" + }, + "args": [ + [ + "const image::Format &", + "format", + null + ] + ], + "ret_type": "void", + "static": false, + "def": "void to_format(const image::Format &format)" + }, + "to_format2": { + "type": "func", + "name": "to_format2", + "doc": { + "brief": "Convert color format and return a new Color object", + "param": { + "format": "format want to convert to, @see image::Format, only support RGB888, BGR888, RGBA8888, BGRA8888, GRAYSCALE." + }, + "return": "new Color object, you need to delete it manually in C++.", + "maixpy": "maix.image.Color.to_format2", + "py_doc": "Convert color format and return a new Color object\n\nArgs:\n - format: format want to convert to, @see image::Format, only support RGB888, BGR888, RGBA8888, BGRA8888, GRAYSCALE.\n\n\nReturns: new Color object, you need to delete it manually in C++.\n" + }, + "args": [ + [ + "const image::Format &", + "format", + null + ] + ], + "ret_type": "image::Color*", + "static": false, + "def": "image::Color *to_format2(const image::Format &format)" + } + }, + "def": "class Color" + }, + "COLOR_WHITE": { + "type": "var", + "name": "", + "doc": { + "brief": "Predefined color white", + "maixpy": "maix.image.COLOR_WHITE", + "py_doc": "Predefined color white" + }, + "value": "image::Color::from_rgb(255, 255, 255)", + "static": false, + "readonly": true, + "def": "const image::Color COLOR_WHITE = image::Color::from_rgb(255, 255, 255)" + }, + "COLOR_BLACK": { + "type": "var", + "name": "", + "doc": { + "brief": "Predefined color black", + "maixpy": "maix.image.COLOR_BLACK", + "py_doc": "Predefined color black" + }, + "value": "image::Color::from_rgb(0, 0, 0)", + "static": false, + "readonly": true, + "def": "const image::Color COLOR_BLACK = image::Color::from_rgb(0, 0, 0)" + }, + "COLOR_RED": { + "type": "var", + "name": "", + "doc": { + "brief": "Predefined color red", + "maixpy": "maix.image.COLOR_RED", + "py_doc": "Predefined color red" + }, + "value": "image::Color::from_rgb(255, 0, 0)", + "static": false, + "readonly": true, + "def": "const image::Color COLOR_RED = image::Color::from_rgb(255, 0, 0)" + }, + "COLOR_GREEN": { + "type": "var", + "name": "", + "doc": { + "brief": "Predefined color green", + "maixpy": "maix.image.COLOR_GREEN", + "py_doc": "Predefined color green" + }, + "value": "image::Color::from_rgb(0, 255, 0)", + "static": false, + "readonly": true, + "def": "const image::Color COLOR_GREEN = image::Color::from_rgb(0, 255, 0)" + }, + "COLOR_BLUE": { + "type": "var", + "name": "", + "doc": { + "brief": "Predefined color blue", + "maixpy": "maix.image.COLOR_BLUE", + "py_doc": "Predefined color blue" + }, + "value": "image::Color::from_rgb(0, 0, 255)", + "static": false, + "readonly": true, + "def": "const image::Color COLOR_BLUE = image::Color::from_rgb(0, 0, 255)" + }, + "COLOR_YELLOW": { + "type": "var", + "name": "", + "doc": { + "brief": "Predefined color yellow", + "maixpy": "maix.image.COLOR_YELLOW", + "py_doc": "Predefined color yellow" + }, + "value": "image::Color::from_rgb(255, 255, 0)", + "static": false, + "readonly": true, + "def": "const image::Color COLOR_YELLOW = image::Color::from_rgb(255, 255, 0)" + }, + "COLOR_PURPLE": { + "type": "var", + "name": "", + "doc": { + "brief": "Predefined color purple", + "maixpy": "maix.image.COLOR_PURPLE", + "py_doc": "Predefined color purple" + }, + "value": "image::Color::from_rgb(143, 0, 255)", + "static": false, + "readonly": true, + "def": "const image::Color COLOR_PURPLE = image::Color::from_rgb(143, 0, 255)" + }, + "COLOR_ORANGE": { + "type": "var", + "name": "", + "doc": { + "brief": "Predefined color orange", + "maixpy": "maix.image.COLOR_ORANGE", + "py_doc": "Predefined color orange" + }, + "value": "image::Color::from_rgb(255, 127, 0)", + "static": false, + "readonly": true, + "def": "const image::Color COLOR_ORANGE = image::Color::from_rgb(255, 127, 0)" + }, + "COLOR_GRAY": { + "type": "var", + "name": "", + "doc": { + "brief": "Predefined color gray", + "maixpy": "maix.image.COLOR_GRAY", + "py_doc": "Predefined color gray" + }, + "value": "image::Color::from_rgb(127, 127, 127)", + "static": false, + "readonly": true, + "def": "const image::Color COLOR_GRAY = image::Color::from_rgb(127, 127, 127)" + } + }, + "auto_add": true + }, + "audio": { + "type": "module", + "doc": { + "brief": "maix.audio module", + "maixpy": "maix.audio", + "py_doc": "maix.audio module" + }, + "members": { + "Format": { + "type": "enum", + "name": "Format", + "doc": { + "brief": "Audio type", + "maixpy": "maix.audio.Format", + "py_doc": "Audio type" + }, + "values": [ + [ + "FMT_NONE", + "0", + "format invalid" + ], + [ + "FMT_S8", + "", + "unsigned 8 bits" + ], + [ + "FMT_S16_LE", + "", + "signed 16 bits, little endian" + ], + [ + "FMT_S32_LE", + "", + "signed 32 bits, little endian" + ], + [ + "FMT_S16_BE", + "", + "signed 16 bits, big endian" + ], + [ + "FMT_S32_BE", + "", + "signed 32 bits, big endian" + ], + [ + "FMT_U8", + "", + "unsigned 8 bits" + ], + [ + "FMT_U16_LE", + "", + "unsigned 16 bits, little endian" + ], + [ + "FMT_U32_LE", + "", + "unsigned 32 bits, little endian" + ], + [ + "FMT_U16_BE", + "", + "unsigned 16 bits, big endian" + ], + [ + "FMT_U32_BE", + "", + "unsigned 32 bits, big endian" + ] + ], + "def": "enum Format\n {\n FMT_NONE = 0, // format invalid\n FMT_S8, // unsigned 8 bits\n FMT_S16_LE, // signed 16 bits, little endian\n FMT_S32_LE, // signed 32 bits, little endian\n FMT_S16_BE, // signed 16 bits, big endian\n FMT_S32_BE, // signed 32 bits, big endian\n FMT_U8, // unsigned 8 bits\n FMT_U16_LE, // unsigned 16 bits, little endian\n FMT_U32_LE, // unsigned 32 bits, little endian\n FMT_U16_BE, // unsigned 16 bits, big endian\n FMT_U32_BE, // unsigned 32 bits, big endian\n }" + }, + "Recorder": { + "type": "class", + "name": "Recorder", + "doc": { + "brief": "Recorder class", + "maixpy": "maix.audio.Recorder", + "py_doc": "Recorder class" + }, + "members": { + "Recorder": { + "type": "func", + "name": "Recorder", + "doc": { + "brief": "Construct a new Recorder object. currectly only pcm and wav formats supported.", + "param": { + "path": "record path. the path determines the location where you save the file, if path is none, the audio module will not save file.", + "sample_rate": "record sample rate, default is 48000(48KHz), means 48000 samples per second.", + "format": "record sample format, default is audio::Format::FMT_S16_LE, means sampling 16 bits at a time and save as signed 16 bits, little endian. see @audio::Format", + "channel": "record sample channel, default is 1, means 1 channel sampling at the same time" + }, + "maixpy": "maix.audio.Recorder.__init__", + "maixcdk": "maix.audio.Recorder.Recorder", + "py_doc": "Construct a new Recorder object. currectly only pcm and wav formats supported.\n\nArgs:\n - path: record path. the path determines the location where you save the file, if path is none, the audio module will not save file.\n - sample_rate: record sample rate, default is 48000(48KHz), means 48000 samples per second.\n - format: record sample format, default is audio::Format::FMT_S16_LE, means sampling 16 bits at a time and save as signed 16 bits, little endian. see @audio::Format\n - channel: record sample channel, default is 1, means 1 channel sampling at the same time\n" + }, + "args": [ + [ + "std::string", + "path", + "std::string()" + ], + [ + "int", + "sample_rate", + "48000" + ], + [ + "audio::Format", + "format", + "audio::Format::FMT_S16_LE" + ], + [ + "int", + "channel", + "1" + ] + ], + "ret_type": null, + "static": false, + "def": "Recorder(std::string path = std::string(), int sample_rate = 48000, audio::Format format = audio::Format::FMT_S16_LE, int channel = 1)" + }, + "volume": { + "type": "func", + "name": "volume", + "doc": { + "brief": "Set/Get record volume", + "param": { + "value": "volume value, If you use this parameter, audio will set the value to volume,\nif you don't, it will return the current volume. range is [0, 100]." + }, + "return": "the current volume", + "maixpy": "maix.audio.Recorder.volume", + "py_doc": "Set/Get record volume\n\nArgs:\n - value: volume value, If you use this parameter, audio will set the value to volume,\nif you don't, it will return the current volume. range is [0, 100].\n\n\nReturns: the current volume\n" + }, + "args": [ + [ + "int", + "value", + "-1" + ] + ], + "ret_type": "int", + "static": false, + "def": "int volume(int value = -1)" + }, + "mute": { + "type": "func", + "name": "mute", + "doc": { + "brief": "Mute", + "param": { + "data": "mute data, If you set this parameter to true, audio will set the value to mute,\nif you don't, it will return the current mute status." + }, + "return": "Returns whether mute is currently enabled.", + "maixpy": "maix.audio.Recorder.mute", + "py_doc": "Mute\n\nArgs:\n - data: mute data, If you set this parameter to true, audio will set the value to mute,\nif you don't, it will return the current mute status.\n\n\nReturns: Returns whether mute is currently enabled.\n" + }, + "args": [ + [ + "int", + "data", + "-1" + ] + ], + "ret_type": "bool", + "static": false, + "def": "bool mute(int data = -1)" + }, + "record": { + "type": "func", + "name": "record", + "doc": { + "brief": "Record, Read all cached data in buffer and return. If there is no audio data in the buffer, may return empty data.", + "param": { + "record_ms": "Block and record audio data lasting `record_ms` milliseconds and save it to a file, the return value does not return audio data. Only valid if the initialisation `path` is set." + }, + "return": "pcm data. datatype @see Bytes. If you pass in record_ms parameter, the return value is an empty Bytes object.", + "maixpy": "maix.audio.Recorder.record", + "py_doc": "Record, Read all cached data in buffer and return. If there is no audio data in the buffer, may return empty data.\n\nArgs:\n - record_ms: Block and record audio data lasting `record_ms` milliseconds and save it to a file, the return value does not return audio data. Only valid if the initialisation `path` is set.\n\n\nReturns: pcm data. datatype @see Bytes. If you pass in record_ms parameter, the return value is an empty Bytes object.\n" + }, + "args": [ + [ + "int", + "record_ms", + "-1" + ] + ], + "ret_type": "maix::Bytes*", + "static": false, + "def": "maix::Bytes *record(int record_ms = -1)" + }, + "record_bytes": { + "type": "func", + "name": "record_bytes", + "doc": { + "brief": "Record, Read all cached data in buffer and return. If there is no audio data in the buffer, may return empty data.", + "note": "This interface is experimental and may be removed in the future.", + "param": { + "record_size": "Record audio data of size record_size." + }, + "return": "pcm data. datatype @see Bytes. If you pass in record_ms parameter, the return value is an empty Bytes object.", + "maixcdk": "maix.audio.Recorder.record_bytes", + "py_doc": "Record, Read all cached data in buffer and return. If there is no audio data in the buffer, may return empty data.\n\nArgs:\n - record_size: Record audio data of size record_size.\n\n\nReturns: pcm data. datatype @see Bytes. If you pass in record_ms parameter, the return value is an empty Bytes object.\n" + }, + "args": [ + [ + "int", + "record_size", + "-1" + ] + ], + "ret_type": "maix::Bytes*", + "static": false, + "def": "maix::Bytes *record_bytes(int record_size = -1)" + }, + "finish": { + "type": "func", + "name": "finish", + "doc": { + "brief": "Finish the record, if you have passed in the path, this api will save the audio data to file.", + "return": "error code, err::ERR_NONE means success, others means failed", + "maixpy": "maix.audio.Recorder.finish", + "py_doc": "Finish the record, if you have passed in the path, this api will save the audio data to file.\n\nReturns: error code, err::ERR_NONE means success, others means failed\n" + }, + "args": [], + "ret_type": "err::Err", + "static": false, + "def": "err::Err finish()" + }, + "sample_rate": { + "type": "func", + "name": "sample_rate", + "doc": { + "brief": "Get sample rate", + "return": "returns sample rate", + "maixpy": "maix.audio.Recorder.sample_rate", + "py_doc": "Get sample rate\n\nReturns: returns sample rate\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int sample_rate()" + }, + "format": { + "type": "func", + "name": "format", + "doc": { + "brief": "Get sample format", + "return": "returns sample format", + "maixpy": "maix.audio.Recorder.format", + "py_doc": "Get sample format\n\nReturns: returns sample format\n" + }, + "args": [], + "ret_type": "audio::Format", + "static": false, + "def": "audio::Format format()" + }, + "channel": { + "type": "func", + "name": "channel", + "doc": { + "brief": "Get sample channel", + "return": "returns sample channel", + "maixpy": "maix.audio.Recorder.channel", + "py_doc": "Get sample channel\n\nReturns: returns sample channel\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int channel()" + } + }, + "def": "class Recorder" + }, + "Player": { + "type": "class", + "name": "Player", + "doc": { + "brief": "Player class", + "maixpy": "maix.audio.Player", + "py_doc": "Player class" + }, + "members": { + "Player": { + "type": "func", + "name": "Player", + "doc": { + "brief": "Construct a new Player object", + "param": { + "path": "player path. the path determines the location where you save the file, if path is none, the audio module will not save file.", + "sample_rate": "player sample rate, default is 48000(48KHz), means 48000 samples per second.", + "format": "player sample format, default is audio::Format::FMT_S16_LE, means sampling 16 bits at a time and save as signed 16 bits, little endian. see @audio::Format", + "channel": "player sample channel, default is 1, means 1 channel sampling at the same time" + }, + "maixpy": "maix.audio.Player.__init__", + "maixcdk": "maix.audio.Player.Player", + "py_doc": "Construct a new Player object\n\nArgs:\n - path: player path. the path determines the location where you save the file, if path is none, the audio module will not save file.\n - sample_rate: player sample rate, default is 48000(48KHz), means 48000 samples per second.\n - format: player sample format, default is audio::Format::FMT_S16_LE, means sampling 16 bits at a time and save as signed 16 bits, little endian. see @audio::Format\n - channel: player sample channel, default is 1, means 1 channel sampling at the same time\n" + }, + "args": [ + [ + "std::string", + "path", + "std::string()" + ], + [ + "int", + "sample_rate", + "48000" + ], + [ + "audio::Format", + "format", + "audio::Format::FMT_S16_LE" + ], + [ + "int", + "channel", + "1" + ] + ], + "ret_type": null, + "static": false, + "def": "Player(std::string path = std::string(), int sample_rate = 48000, audio::Format format = audio::Format::FMT_S16_LE, int channel = 1)" + }, + "volume": { + "type": "func", + "name": "volume", + "doc": { + "brief": "Set/Get player volume", + "param": { + "value": "volume value, If you use this parameter, audio will set the value to volume,\nif you don't, it will return the current volume. range is [0, 100]." + }, + "return": "the current volume", + "maixpy": "maix.audio.Player.volume", + "py_doc": "Set/Get player volume\n\nArgs:\n - value: volume value, If you use this parameter, audio will set the value to volume,\nif you don't, it will return the current volume. range is [0, 100].\n\n\nReturns: the current volume\n" + }, + "args": [ + [ + "int", + "value", + "-1" + ] + ], + "ret_type": "int", + "static": false, + "def": "int volume(int value = -1)" + }, + "play": { + "type": "func", + "name": "play", + "doc": { + "brief": "Play", + "param": { + "data": "audio data, must be raw data" + }, + "return": "error code, err::ERR_NONE means success, others means failed", + "maixpy": "maix.audio.Player.play", + "py_doc": "Play\n\nArgs:\n - data: audio data, must be raw data\n\n\nReturns: error code, err::ERR_NONE means success, others means failed\n" + }, + "args": [ + [ + "maix::Bytes *", + "data", + "maix::audio::Player::NoneBytes" + ] + ], + "ret_type": "err::Err", + "static": false, + "def": "err::Err play(maix::Bytes *data = maix::audio::Player::NoneBytes)" + }, + "sample_rate": { + "type": "func", + "name": "sample_rate", + "doc": { + "brief": "Get sample rate", + "return": "returns sample rate", + "maixpy": "maix.audio.Player.sample_rate", + "py_doc": "Get sample rate\n\nReturns: returns sample rate\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int sample_rate()" + }, + "format": { + "type": "func", + "name": "format", + "doc": { + "brief": "Get sample format", + "return": "returns sample format", + "maixpy": "maix.audio.Player.format", + "py_doc": "Get sample format\n\nReturns: returns sample format\n" + }, + "args": [], + "ret_type": "audio::Format", + "static": false, + "def": "audio::Format format()" + }, + "channel": { + "type": "func", + "name": "channel", + "doc": { + "brief": "Get sample channel", + "return": "returns sample channel", + "maixpy": "maix.audio.Player.channel", + "py_doc": "Get sample channel\n\nReturns: returns sample channel\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int channel()" + } + }, + "def": "class Player" + } + }, + "auto_add": false + }, + "tracker": { + "type": "module", + "doc": { + "brief": "maix.tracker module" + }, + "members": { + "Object": { + "type": "class", + "name": "Object", + "doc": { + "brief": "tracker.Object class", + "maixpy": "maix.tracker.Object", + "py_doc": "tracker.Object class" + }, + "members": { + "Object": { + "type": "func", + "name": "Object", + "doc": { + "brief": "tracker.Object class constructor", + "maixpy": "maix.tracker.Object.__init__", + "maixcdk": "maix.tracker.Object.Object", + "py_doc": "tracker.Object class constructor" + }, + "args": [ + [ + "const int &", + "x", + null + ], + [ + "const int &", + "y", + null + ], + [ + "const int &", + "w", + null + ], + [ + "const int &", + "h", + null + ], + [ + "const int &", + "class_id", + null + ], + [ + "const float &", + "score", + null + ] + ], + "ret_type": null, + "static": false, + "def": "Object(const int &x, const int &y, const int &w, const int &h, const int &class_id, const float &score)" + }, + "x": { + "type": "var", + "name": "x", + "doc": { + "brief": "position x attribute.", + "maixpy": "maix.tracker.Object.x", + "py_doc": "position x attribute." + }, + "value": null, + "static": false, + "readonly": false, + "def": "int x" + }, + "y": { + "type": "var", + "name": "y", + "doc": { + "brief": "position y attribute.", + "maixpy": "maix.tracker.Object.y", + "py_doc": "position y attribute." + }, + "value": null, + "static": false, + "readonly": false, + "def": "int y" + }, + "w": { + "type": "var", + "name": "w", + "doc": { + "brief": "position rectangle width.", + "maixpy": "maix.tracker.Object.w", + "py_doc": "position rectangle width." + }, + "value": null, + "static": false, + "readonly": false, + "def": "int w" + }, + "h": { + "type": "var", + "name": "h", + "doc": { + "brief": "position rectangle height.", + "maixpy": "maix.tracker.Object.h", + "py_doc": "position rectangle height." + }, + "value": null, + "static": false, + "readonly": false, + "def": "int h" + }, + "class_id": { + "type": "var", + "name": "class_id", + "doc": { + "brief": "object class id, int type.", + "maixpy": "maix.tracker.Object.class_id", + "py_doc": "object class id, int type." + }, + "value": null, + "static": false, + "readonly": false, + "def": "int class_id" + }, + "score": { + "type": "var", + "name": "score", + "doc": { + "brief": "object score(prob).", + "maixpy": "maix.tracker.Object.score", + "py_doc": "object score(prob)." + }, + "value": null, + "static": false, + "readonly": false, + "def": "float score" + } + }, + "def": "class Object" + }, + "Track": { + "type": "class", + "name": "Track", + "doc": { + "brief": "tracker.Track class", + "maixpy": "maix.tracker.Track", + "py_doc": "tracker.Track class" + }, + "members": { + "Track": { + "type": "func", + "name": "Track", + "doc": { + "brief": "tracker.Track class constructor", + "maixpy": "maix.tracker.Track.__init__", + "maixcdk": "maix.tracker.Track.Track", + "py_doc": "tracker.Track class constructor" + }, + "args": [ + [ + "const size_t &", + "id", + null + ], + [ + "const float &", + "score", + null + ], + [ + "const bool &", + "lost", + null + ], + [ + "const size_t &", + "start_frame_id", + null + ], + [ + "const size_t &", + "frame_id", + null + ] + ], + "ret_type": null, + "static": false, + "def": "Track(const size_t &id, const float &score, const bool &lost, const size_t &start_frame_id, const size_t &frame_id)", + "overload": [ + { + "type": "func", + "name": "Track", + "doc": { + "brief": "tracker.Track class constructor", + "maixcdk": "maix.tracker.Track.Track", + "py_doc": "tracker.Track class constructor" + }, + "args": [], + "ret_type": null, + "static": false, + "def": "Track()" + } + ] + }, + "id": { + "type": "var", + "name": "id", + "doc": { + "brief": "track id.", + "maixpy": "maix.tracker.Track.id", + "py_doc": "track id." + }, + "value": null, + "static": false, + "readonly": false, + "def": "size_t id" + }, + "score": { + "type": "var", + "name": "score", + "doc": { + "brief": "track score(prob).", + "maixpy": "maix.tracker.Track.score", + "py_doc": "track score(prob)." + }, + "value": null, + "static": false, + "readonly": false, + "def": "float score" + }, + "lost": { + "type": "var", + "name": "lost", + "doc": { + "brief": "whether this track lost.", + "maixpy": "maix.tracker.Track.lost", + "py_doc": "whether this track lost." + }, + "value": null, + "static": false, + "readonly": false, + "def": "bool lost" + }, + "start_frame_id": { + "type": "var", + "name": "start_frame_id", + "doc": { + "brief": "track start frame id.", + "maixpy": "maix.tracker.Track.start_frame_id", + "py_doc": "track start frame id." + }, + "value": null, + "static": false, + "readonly": false, + "def": "size_t start_frame_id" + }, + "frame_id": { + "type": "var", + "name": "frame_id", + "doc": { + "brief": "track current frame id.", + "maixpy": "maix.tracker.Track.frame_id", + "py_doc": "track current frame id." + }, + "value": null, + "static": false, + "readonly": false, + "def": "size_t frame_id" + }, + "history": { + "type": "var", + "name": "history", + "doc": { + "brief": "track position history, the last one is latest position.", + "maixpy": "maix.tracker.Track.history", + "py_doc": "track position history, the last one is latest position." + }, + "value": null, + "static": false, + "readonly": false, + "def": "std::deque history" + } + }, + "def": "class Track" + }, + "ByteTracker": { + "type": "class", + "name": "ByteTracker", + "doc": { + "brief": "tracker.ByteTracker class", + "maixpy": "maix.tracker.ByteTracker", + "py_doc": "tracker.ByteTracker class" + }, + "members": { + "ByteTracker": { + "type": "func", + "name": "ByteTracker", + "doc": { + "brief": "tracker.ByteTracker class constructor", + "param": { + "max_lost_buff_num": "the frames for keep lost tracks.", + "track_thresh": "tracking confidence threshold.", + "high_thresh": "threshold to add to new track.", + "match_thresh": "matching threshold for tracking, e.g. one object in two frame iou < match_thresh we think they are the same obj.", + "max_history": "max tack's position history length." + }, + "maixpy": "maix.tracker.ByteTracker.__init__", + "maixcdk": "maix.tracker.ByteTracker.ByteTracker", + "py_doc": "tracker.ByteTracker class constructor\n\nArgs:\n - max_lost_buff_num: the frames for keep lost tracks.\n - track_thresh: tracking confidence threshold.\n - high_thresh: threshold to add to new track.\n - match_thresh: matching threshold for tracking, e.g. one object in two frame iou < match_thresh we think they are the same obj.\n - max_history: max tack's position history length.\n" + }, + "args": [ + [ + "const int &", + "max_lost_buff_num", + "60" + ], + [ + "const float &", + "track_thresh", + "0.5" + ], + [ + "const float &", + "high_thresh", + "0.6" + ], + [ + "const float &", + "match_thresh", + "0.8" + ], + [ + "const int &", + "max_history", + "20" + ] + ], + "ret_type": null, + "static": false, + "def": "ByteTracker(const int &max_lost_buff_num = 60,\n const float &track_thresh = 0.5,\n const float &high_thresh = 0.6,\n const float &match_thresh = 0.8,\n const int &max_history = 20)" + }, + "update": { + "type": "func", + "name": "update", + "doc": { + "brief": "update tracks according to current detected objects.", + "maixpy": "maix.tracker.ByteTracker.update", + "py_doc": "update tracks according to current detected objects." + }, + "args": [ + [ + "const std::vector &", + "objs", + null + ] + ], + "ret_type": "std::vector", + "static": false, + "def": "std::vector update(const std::vector &objs)" + } + }, + "def": "class ByteTracker" + } + }, + "auto_add": true + }, + "http": { + "type": "module", + "doc": { + "brief": "maix.http module" + }, + "members": { + "JpegStreamer": { + "type": "class", + "name": "JpegStreamer", + "doc": { + "brief": "JpegStreamer class", + "maixpy": "maix.http.JpegStreamer", + "py_doc": "JpegStreamer class" + }, + "members": { + "JpegStreamer": { + "type": "func", + "name": "JpegStreamer", + "doc": { + "brief": "Construct a new jpeg streamer object", + "note": "You can get the picture stream through http://host:port/stream, you can also get it through http://ip:port, and you can add personal style through set_html() at this time", + "param": { + "host": "http host", + "port": "http port, default is 8000", + "client_number": "the max number of client" + }, + "maixpy": "maix.http.JpegStreamer.__init__", + "maixcdk": "maix.http.JpegStreamer.JpegStreamer", + "py_doc": "Construct a new jpeg streamer object\n\nArgs:\n - host: http host\n - port: http port, default is 8000\n - client_number: the max number of client\n" + }, + "args": [ + [ + "std::string", + "host", + "std::string()" + ], + [ + "int", + "port", + "8000" + ], + [ + "int", + "client_number", + "16" + ] + ], + "ret_type": null, + "static": false, + "def": "JpegStreamer(std::string host = std::string(), int port = 8000, int client_number = 16)" + }, + "start": { + "type": "func", + "name": "start", + "doc": { + "brief": "start jpeg streame", + "return": "error code, err::ERR_NONE means success, others means failed", + "maixpy": "maix.http.JpegStreamer.start", + "py_doc": "start jpeg streame\n\nReturns: error code, err::ERR_NONE means success, others means failed\n" + }, + "args": [], + "ret_type": "err::Err", + "static": false, + "def": "err::Err start()", + "overload": [ + { + "type": "func", + "name": "stop", + "doc": { + "brief": "stop http", + "return": "error code, err::ERR_NONE means success, others means failed", + "maixpy": "maix.http.JpegStreamer.start", + "py_doc": "stop http\n\nReturns: error code, err::ERR_NONE means success, others means failed\n" + }, + "args": [], + "ret_type": "err::Err", + "static": false, + "def": "err::Err stop()" + } + ] + }, + "write": { + "type": "func", + "name": "write", + "doc": { + "brief": "Write data to http", + "param": { + "img": "image object" + }, + "return": "error code, err::ERR_NONE means success, others means failed", + "maixpy": "maix.http.JpegStreamer.write", + "py_doc": "Write data to http\n\nArgs:\n - img: image object\n\n\nReturns: error code, err::ERR_NONE means success, others means failed\n" + }, + "args": [ + [ + "image::Image *", + "img", + null + ] + ], + "ret_type": "err::Err", + "static": false, + "def": "err::Err write(image::Image *img)" + }, + "set_html": { + "type": "func", + "name": "set_html", + "doc": { + "brief": "add your style in this api\\ndefault is:\\n\\n\\n

JPG Stream

\\n\\n\\n", + "param": { + "data": "html code" + }, + "return": "error code, err::ERR_NONE means success, others means failed", + "maixpy": "maix.http.JpegStreamer.set_html", + "py_doc": "add your style in this api\ndefault is:\n\n\n

JPG Stream

\n\n\n\n\nArgs:\n - data: html code\n\n\nReturns: error code, err::ERR_NONE means success, others means failed\n" + }, + "args": [ + [ + "std::string", + "data", + null + ] + ], + "ret_type": "err::Err", + "static": false, + "def": "err::Err set_html(std::string data)" + }, + "host": { + "type": "func", + "name": "host", + "doc": { + "brief": "Get host", + "return": "host name", + "maixpy": "maix.http.JpegStreamer.host", + "py_doc": "Get host\n\nReturns: host name\n" + }, + "args": [], + "ret_type": "std::string", + "static": false, + "def": "std::string host()" + }, + "port": { + "type": "func", + "name": "port", + "doc": { + "brief": "Get port", + "return": "port", + "maixpy": "maix.http.JpegStreamer.port", + "py_doc": "Get port\n\nReturns: port\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int port()" + } + }, + "def": "class JpegStreamer" + } + }, + "auto_add": true + }, + "camera": { + "type": "module", + "doc": { + "brief": "maix.camera module, access camera device and get image from it", + "maixpy": "maix.camera", + "py_doc": "maix.camera module, access camera device and get image from it" + }, + "members": { + "list_devices": { + "type": "func", + "name": "list_devices", + "doc": { + "brief": "List all supported camera devices.", + "return": "Returns the path to the camera device.", + "maixpy": "maix.camera.list_devices", + "py_doc": "List all supported camera devices.\n\nReturns: Returns the path to the camera device.\n" + }, + "args": [], + "ret_type": "std::vector", + "static": false, + "def": "std::vector list_devices()" + }, + "set_regs_enable": { + "type": "func", + "name": "set_regs_enable", + "doc": { + "brief": "Enable set camera registers, default is false, if set to true, will not set camera registers, you can manually set registers by write_reg API.", + "param": { + "enable": "enable/disable set camera registers" + }, + "maixpy": "maix.camera.set_regs_enable", + "py_doc": "Enable set camera registers, default is false, if set to true, will not set camera registers, you can manually set registers by write_reg API.\n\nArgs:\n - enable: enable/disable set camera registers\n" + }, + "args": [ + [ + "bool", + "enable", + "true" + ] + ], + "ret_type": "void", + "static": false, + "def": "void set_regs_enable(bool enable = true)" + }, + "get_device_name": { + "type": "func", + "name": "get_device_name", + "doc": { + "brief": "Get device name. Most of the time, the returned name is the name of the sensor.", + "maixpy": "maix.camera.get_device_name", + "py_doc": "Get device name. Most of the time, the returned name is the name of the sensor." + }, + "args": [], + "ret_type": "std::string", + "static": false, + "def": "std::string get_device_name()" + }, + "Camera": { + "type": "class", + "name": "Camera", + "doc": { + "brief": "Camera class", + "maixpy": "maix.camera.Camera", + "py_doc": "Camera class" + }, + "members": { + "Camera": { + "type": "func", + "name": "Camera", + "doc": { + "brief": "Construct a new Camera object.\\nMaximum resolution support 2560x1440.", + "param": { + "width": "camera width, default is -1, means auto, mostly means max width of camera support", + "height": "camera height, default is -1, means auto, mostly means max height of camera support", + "format": "camera output format, default is image.Format.FMT_RGB888", + "device": "camera device path, you can get devices by list_devices method, by default(value is NULL(None in MaixPy)) means the first device", + "fps": "camera fps, default is -1, means auto, mostly means max fps of camera support", + "buff_num": "camera buffer number, default is 3, means 3 buffer, one used by user, one used for cache the next frame,\nmore than one buffer will accelerate image read speed, but will cost more memory.", + "open": "If true, camera will automatically call open() after creation. default is true.", + "raw": "If true, you can use read_raw() to capture the raw image output from the sensor." + }, + "maixpy": "maix.camera.Camera.__init__", + "maixcdk": "maix.camera.Camera.Camera", + "py_doc": "Construct a new Camera object.\nMaximum resolution support 2560x1440.\n\nArgs:\n - width: camera width, default is -1, means auto, mostly means max width of camera support\n - height: camera height, default is -1, means auto, mostly means max height of camera support\n - format: camera output format, default is image.Format.FMT_RGB888\n - device: camera device path, you can get devices by list_devices method, by default(value is NULL(None in MaixPy)) means the first device\n - fps: camera fps, default is -1, means auto, mostly means max fps of camera support\n - buff_num: camera buffer number, default is 3, means 3 buffer, one used by user, one used for cache the next frame,\nmore than one buffer will accelerate image read speed, but will cost more memory.\n - open: If true, camera will automatically call open() after creation. default is true.\n - raw: If true, you can use read_raw() to capture the raw image output from the sensor.\n" + }, + "args": [ + [ + "int", + "width", + "-1" + ], + [ + "int", + "height", + "-1" + ], + [ + "image::Format", + "format", + "image::FMT_RGB888" + ], + [ + "const char *", + "device", + "nullptr" + ], + [ + "double", + "fps", + "-1" + ], + [ + "int", + "buff_num", + "3" + ], + [ + "bool", + "open", + "true" + ], + [ + "bool", + "raw", + "false" + ] + ], + "ret_type": null, + "static": false, + "def": "Camera(int width = -1, int height = -1, image::Format format = image::FMT_RGB888, const char *device = nullptr, double fps = -1, int buff_num = 3, bool open = true, bool raw = false)" + }, + "get_ch_nums": { + "type": "func", + "name": "get_ch_nums", + "doc": { + "brief": "Get the number of channels supported by the camera.", + "return": "Returns the maximum number of channels.", + "maixpy": "maix.camera.Camera.get_ch_nums", + "py_doc": "Get the number of channels supported by the camera.\n\nReturns: Returns the maximum number of channels.\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int get_ch_nums()" + }, + "open": { + "type": "func", + "name": "open", + "doc": { + "brief": "Open camera and run", + "param": { + "width": "camera width, default is -1, means auto, mostly means max width of camera support", + "height": "camera height, default is -1, means auto, mostly means max height of camera support", + "format": "camera output format, default same as the constructor's format argument", + "fps": "camera fps, default is -1, means auto, mostly means max fps of camera support", + "buff_num": "camera buffer number, default is 3, means 3 buffer, one used by user, one used for cache the next frame,\nmore than one buffer will accelerate image read speed, but will cost more memory." + }, + "return": "error code, err::ERR_NONE means success, others means failed", + "maixpy": "maix.camera.Camera.open", + "py_doc": "Open camera and run\n\nArgs:\n - width: camera width, default is -1, means auto, mostly means max width of camera support\n - height: camera height, default is -1, means auto, mostly means max height of camera support\n - format: camera output format, default same as the constructor's format argument\n - fps: camera fps, default is -1, means auto, mostly means max fps of camera support\n - buff_num: camera buffer number, default is 3, means 3 buffer, one used by user, one used for cache the next frame,\nmore than one buffer will accelerate image read speed, but will cost more memory.\n\n\nReturns: error code, err::ERR_NONE means success, others means failed\n" + }, + "args": [ + [ + "int", + "width", + "-1" + ], + [ + "int", + "height", + "-1" + ], + [ + "image::Format", + "format", + "image::FMT_INVALID" + ], + [ + "double", + "fps", + "-1" + ], + [ + "int", + "buff_num", + "-1" + ] + ], + "ret_type": "err::Err", + "static": false, + "def": "err::Err open(int width = -1, int height = -1, image::Format format = image::FMT_INVALID, double fps = -1, int buff_num = -1)" + }, + "read": { + "type": "func", + "name": "read", + "doc": { + "brief": "Get one frame image from camera buffer, must call open method before read.\\nIf open method not called, will call it automatically, if open failed, will throw exception!\\nSo call open method before read is recommended.", + "param": { + "buff": "buffer to store image data, if buff is nullptr, will alloc memory automatically.\nIn MaixPy, default to None, you can create a image.Image object, then pass img.data() to buff.", + "block": "block read, default is true, means block util read image successfully,\nif set to false, will return nullptr if no image in buffer", + "block_ms": "block read timeout" + }, + "return": "image::Image object, if failed, return nullptr, you should delete if manually in C++", + "maixpy": "maix.camera.Camera.read", + "py_doc": "Get one frame image from camera buffer, must call open method before read.\nIf open method not called, will call it automatically, if open failed, will throw exception!\nSo call open method before read is recommended.\n\nArgs:\n - buff: buffer to store image data, if buff is nullptr, will alloc memory automatically.\nIn MaixPy, default to None, you can create a image.Image object, then pass img.data() to buff.\n - block: block read, default is true, means block util read image successfully,\nif set to false, will return nullptr if no image in buffer\n - block_ms: block read timeout\n\n\nReturns: image::Image object, if failed, return nullptr, you should delete if manually in C++\n" + }, + "args": [ + [ + "void *", + "buff", + "nullptr" + ], + [ + "size_t", + "buff_size", + "0" + ], + [ + "bool", + "block", + "true" + ], + [ + "int", + "block_ms", + "-1" + ] + ], + "ret_type": "image::Image*", + "static": false, + "def": "image::Image *read(void *buff = nullptr, size_t buff_size = 0, bool block = true, int block_ms = -1)" + }, + "read_raw": { + "type": "func", + "name": "read_raw", + "doc": { + "brief": "Read the raw image and obtain the width, height, and format of the raw image through the returned Image object.", + "note": "The raw image is in a Bayer format, and its width and height are affected by the driver. Modifying the size and format is generally not allowed.", + "return": "image::Image object, if failed, return nullptr, you should delete if manually in C++", + "maixpy": "maix.camera.Camera.read_raw", + "py_doc": "Read the raw image and obtain the width, height, and format of the raw image through the returned Image object.\n\nReturns: image::Image object, if failed, return nullptr, you should delete if manually in C++\n" + }, + "args": [], + "ret_type": "image::Image*", + "static": false, + "def": "image::Image *read_raw()" + }, + "clear_buff": { + "type": "func", + "name": "clear_buff", + "doc": { + "brief": "Clear buff to ensure the next read image is the latest image", + "maixpy": "maix.camera.Camera.clear_buff", + "py_doc": "Clear buff to ensure the next read image is the latest image" + }, + "args": [], + "ret_type": "void", + "static": false, + "def": "void clear_buff()" + }, + "skip_frames": { + "type": "func", + "name": "skip_frames", + "doc": { + "brief": "Read some frames and drop, this is usually used avoid read not stable image when camera just opened.", + "param": { + "num": "number of frames to read and drop" + }, + "maixpy": "maix.camera.Camera.skip_frames", + "py_doc": "Read some frames and drop, this is usually used avoid read not stable image when camera just opened.\n\nArgs:\n - num: number of frames to read and drop\n" + }, + "args": [ + [ + "int", + "num", + null + ] + ], + "ret_type": "void", + "static": false, + "def": "void skip_frames(int num)" + }, + "close": { + "type": "func", + "name": "close", + "doc": { + "brief": "Close camera", + "maixpy": "maix.camera.Camera.close", + "py_doc": "Close camera" + }, + "args": [], + "ret_type": "void", + "static": false, + "def": "void close()" + }, + "add_channel": { + "type": "func", + "name": "add_channel", + "doc": { + "brief": "Add a new channel and return a new Camera object, you can use close() to close this channel.", + "param": { + "width": "camera width, default is -1, means auto, mostly means max width of camera support", + "height": "camera height, default is -1, means auto, mostly means max height of camera support", + "format": "camera output format, default is RGB888", + "fps": "camera fps, default is -1, means auto, mostly means max fps of camera support", + "buff_num": "camera buffer number, default is 3, means 3 buffer, one used by user, one used for cache the next frame,\nmore than one buffer will accelerate image read speed, but will cost more memory.", + "open": "If true, camera will automatically call open() after creation. default is true." + }, + "return": "new Camera object", + "maixpy": "maix.camera.Camera.add_channel", + "py_doc": "Add a new channel and return a new Camera object, you can use close() to close this channel.\n\nArgs:\n - width: camera width, default is -1, means auto, mostly means max width of camera support\n - height: camera height, default is -1, means auto, mostly means max height of camera support\n - format: camera output format, default is RGB888\n - fps: camera fps, default is -1, means auto, mostly means max fps of camera support\n - buff_num: camera buffer number, default is 3, means 3 buffer, one used by user, one used for cache the next frame,\nmore than one buffer will accelerate image read speed, but will cost more memory.\n - open: If true, camera will automatically call open() after creation. default is true.\n\n\nReturns: new Camera object\n" + }, + "args": [ + [ + "int", + "width", + "-1" + ], + [ + "int", + "height", + "-1" + ], + [ + "image::Format", + "format", + "image::FMT_RGB888" + ], + [ + "double", + "fps", + "-1" + ], + [ + "int", + "buff_num", + "3" + ], + [ + "bool", + "open", + "true" + ] + ], + "ret_type": "camera::Camera*", + "static": false, + "def": "camera::Camera *add_channel(int width = -1, int height = -1, image::Format format = image::FMT_RGB888, double fps = -1, int buff_num = 3, bool open = true)" + }, + "is_opened": { + "type": "func", + "name": "is_opened", + "doc": { + "brief": "Check if camera is opened", + "return": "true if camera is opened, false if not", + "maixpy": "maix.camera.Camera.is_opened", + "py_doc": "Check if camera is opened\n\nReturns: true if camera is opened, false if not\n" + }, + "args": [], + "ret_type": "bool", + "static": false, + "def": "bool is_opened()" + }, + "is_closed": { + "type": "func", + "name": "is_closed", + "doc": { + "brief": "check camera device is closed or not", + "return": "closed or not, bool type", + "maixpy": "maix.camera.Camera.is_closed", + "py_doc": "check camera device is closed or not\n\nReturns: closed or not, bool type\n" + }, + "args": [], + "ret_type": "bool", + "static": false, + "def": "bool is_closed()" + }, + "width": { + "type": "func", + "name": "width", + "doc": { + "brief": "Get camera width", + "return": "camera width", + "maixpy": "maix.camera.Camera.width", + "py_doc": "Get camera width\n\nReturns: camera width\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int width()" + }, + "height": { + "type": "func", + "name": "height", + "doc": { + "brief": "Get camera height", + "return": "camera height", + "maixpy": "maix.camera.Camera.height", + "py_doc": "Get camera height\n\nReturns: camera height\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int height()" + }, + "fps": { + "type": "func", + "name": "fps", + "doc": { + "brief": "Get camera fps", + "return": "camera fps", + "maixpy": "maix.camera.Camera.fps", + "py_doc": "Get camera fps\n\nReturns: camera fps\n" + }, + "args": [], + "ret_type": "double", + "static": false, + "def": "double fps()" + }, + "format": { + "type": "func", + "name": "format", + "doc": { + "brief": "Get camera output format", + "return": "camera output format, image::Format object", + "maixpy": "maix.camera.Camera.format", + "py_doc": "Get camera output format\n\nReturns: camera output format, image::Format object\n" + }, + "args": [], + "ret_type": "image::Format", + "static": false, + "def": "image::Format format()" + }, + "buff_num": { + "type": "func", + "name": "buff_num", + "doc": { + "brief": "Get camera buffer number", + "return": "camera buffer number", + "maixpy": "maix.camera.Camera.buff_num", + "py_doc": "Get camera buffer number\n\nReturns: camera buffer number\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int buff_num()" + }, + "hmirror": { + "type": "func", + "name": "hmirror", + "doc": { + "brief": "Set/Get camera horizontal mirror", + "return": "camera horizontal mirror", + "maixpy": "maix.camera.Camera.hmirror", + "py_doc": "Set/Get camera horizontal mirror\n\nReturns: camera horizontal mirror\n" + }, + "args": [ + [ + "int", + "value", + "-1" + ] + ], + "ret_type": "int", + "static": false, + "def": "int hmirror(int value = -1)" + }, + "vflip": { + "type": "func", + "name": "vflip", + "doc": { + "brief": "Set/Get camera vertical flip", + "return": "camera vertical flip", + "maixpy": "maix.camera.Camera.vflip", + "py_doc": "Set/Get camera vertical flip\n\nReturns: camera vertical flip\n" + }, + "args": [ + [ + "int", + "value", + "-1" + ] + ], + "ret_type": "int", + "static": false, + "def": "int vflip(int value = -1)" + }, + "device": { + "type": "func", + "name": "device", + "doc": { + "brief": "Get camera device path", + "return": "camera device path", + "maixpy": "maix.camera.Camera.device", + "py_doc": "Get camera device path\n\nReturns: camera device path\n" + }, + "args": [], + "ret_type": "std::string", + "static": false, + "def": "std::string device()" + }, + "write_reg": { + "type": "func", + "name": "write_reg", + "doc": { + "brief": "Write camera register", + "param": { + "addr": "register address", + "data": "register data", + "bit_width": "register data bit width, default is 8" + }, + "return": "error code, err::ERR_NONE means success, others means failed", + "maixpy": "maix.camera.Camera.write_reg", + "py_doc": "Write camera register\n\nArgs:\n - addr: register address\n - data: register data\n - bit_width: register data bit width, default is 8\n\n\nReturns: error code, err::ERR_NONE means success, others means failed\n" + }, + "args": [ + [ + "int", + "addr", + null + ], + [ + "int", + "data", + null + ], + [ + "int", + "bit_width", + "8" + ] + ], + "ret_type": "err::Err", + "static": false, + "def": "err::Err write_reg(int addr, int data, int bit_width = 8)" + }, + "read_reg": { + "type": "func", + "name": "read_reg", + "doc": { + "brief": "Read camera register", + "param": { + "addr": "register address", + "bit_width": "register data bit width, default is 8" + }, + "return": "register data, -1 means failed", + "maixpy": "maix.camera.Camera.read_reg", + "py_doc": "Read camera register\n\nArgs:\n - addr: register address\n - bit_width: register data bit width, default is 8\n\n\nReturns: register data, -1 means failed\n" + }, + "args": [ + [ + "int", + "addr", + null + ], + [ + "int", + "bit_width", + "8" + ] + ], + "ret_type": "int", + "static": false, + "def": "int read_reg(int addr, int bit_width = 8)" + }, + "show_colorbar": { + "type": "func", + "name": "show_colorbar", + "doc": { + "brief": "Camera output color bar image for test", + "param": { + "enable": "enable/disable color bar" + }, + "return": "error code, err::ERR_NONE means success, others means failed", + "maixpy": "maix.camera.Camera.show_colorbar", + "py_doc": "Camera output color bar image for test\n\nArgs:\n - enable: enable/disable color bar\n\n\nReturns: error code, err::ERR_NONE means success, others means failed\n" + }, + "args": [ + [ + "bool", + "enable", + null + ] + ], + "ret_type": "err::Err", + "static": false, + "def": "err::Err show_colorbar(bool enable)" + }, + "get_channel": { + "type": "func", + "name": "get_channel", + "doc": { + "brief": "Get channel of camera", + "return": "channel number", + "maixpy": "maix.camera.Camera.get_channel", + "py_doc": "Get channel of camera\n\nReturns: channel number\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int get_channel()" + }, + "set_resolution": { + "type": "func", + "name": "set_resolution", + "doc": { + "brief": "Set camera resolution", + "param": { + "width": "new width", + "height": "new height" + }, + "return": "error code, err::ERR_NONE means success, others means failed", + "maixpy": "maix.camera.Camera.set_resolution", + "py_doc": "Set camera resolution\n\nArgs:\n - width: new width\n - height: new height\n\n\nReturns: error code, err::ERR_NONE means success, others means failed\n" + }, + "args": [ + [ + "int", + "width", + null + ], + [ + "int", + "height", + null + ] + ], + "ret_type": "err::Err", + "static": false, + "def": "err::Err set_resolution(int width, int height)" + }, + "set_fps": { + "type": "func", + "name": "set_fps", + "doc": { + "brief": "Set camera fps", + "param": { + "fps": "new fps" + }, + "return": "error code, err::ERR_NONE means success, others means failed", + "maixpy": "maix.camera.Camera.set_fps", + "py_doc": "Set camera fps\n\nArgs:\n - fps: new fps\n\n\nReturns: error code, err::ERR_NONE means success, others means failed\n" + }, + "args": [ + [ + "double", + "fps", + null + ] + ], + "ret_type": "err::Err", + "static": false, + "def": "err::Err set_fps(double fps)" + }, + "exposure": { + "type": "func", + "name": "exposure", + "doc": { + "brief": "Set/Get camera exposure", + "attention": "This method will affect the isp and thus the image, so please be careful with it.", + "param": { + "value": "exposure time. unit: us\nIf value == -1, return exposure time.\nIf value != 0, set and return exposure time." + }, + "return": "camera exposure time", + "maixpy": "maix.camera.Camera.exposure", + "py_doc": "Set/Get camera exposure\n\nArgs:\n - value: exposure time. unit: us\nIf value == -1, return exposure time.\nIf value != 0, set and return exposure time.\n\n\nReturns: camera exposure time\n" + }, + "args": [ + [ + "int", + "value", + "-1" + ] + ], + "ret_type": "int", + "static": false, + "def": "int exposure(int value = -1)" + }, + "gain": { + "type": "func", + "name": "gain", + "doc": { + "brief": "Set/Get camera gain", + "attention": "This method will affect the isp and thus the image, so please be careful with it.", + "param": { + "value": "camera gain.\nIf value == -1, returns camera gain.\nIf value != 0, set and return camera gain." + }, + "return": "camera gain", + "maixpy": "maix.camera.Camera.gain", + "py_doc": "Set/Get camera gain\n\nArgs:\n - value: camera gain.\nIf value == -1, returns camera gain.\nIf value != 0, set and return camera gain.\n\n\nReturns: camera gain\n" + }, + "args": [ + [ + "int", + "value", + "-1" + ] + ], + "ret_type": "int", + "static": false, + "def": "int gain(int value = -1)" + }, + "luma": { + "type": "func", + "name": "luma", + "doc": { + "brief": "Set/Get camera luma", + "attention": "This method will affect the isp and thus the image, so please be careful with it.", + "param": { + "value": "luma value, range is [0, 100]\nIf value == -1, returns luma value.\nIf value != 0, set and return luma value." + }, + "return": "returns luma value", + "maixpy": "maix.camera.Camera.luma", + "py_doc": "Set/Get camera luma\n\nArgs:\n - value: luma value, range is [0, 100]\nIf value == -1, returns luma value.\nIf value != 0, set and return luma value.\n\n\nReturns: returns luma value\n" + }, + "args": [ + [ + "int", + "value", + "-1" + ] + ], + "ret_type": "int", + "static": false, + "def": "int luma(int value = -1)" + }, + "constrast": { + "type": "func", + "name": "constrast", + "doc": { + "brief": "Set/Get camera constrast", + "attention": "This method will affect the isp and thus the image, so please be careful with it.", + "param": { + "value": "constrast value, range is [0, 100]\nIf value == -1, returns constrast value.\nIf value != 0, set and return constrast value." + }, + "return": "returns constrast value", + "maixpy": "maix.camera.Camera.constrast", + "py_doc": "Set/Get camera constrast\n\nArgs:\n - value: constrast value, range is [0, 100]\nIf value == -1, returns constrast value.\nIf value != 0, set and return constrast value.\n\n\nReturns: returns constrast value\n" + }, + "args": [ + [ + "int", + "value", + "-1" + ] + ], + "ret_type": "int", + "static": false, + "def": "int constrast(int value = -1)" + }, + "saturation": { + "type": "func", + "name": "saturation", + "doc": { + "brief": "Set/Get camera saturation", + "attention": "This method will affect the isp and thus the image, so please be careful with it.", + "param": { + "value": "saturation value, range is [0, 100]\nIf value == -1, returns saturation value.\nIf value != 0, set and return saturation value." + }, + "return": "returns saturation value", + "maixpy": "maix.camera.Camera.saturation", + "py_doc": "Set/Get camera saturation\n\nArgs:\n - value: saturation value, range is [0, 100]\nIf value == -1, returns saturation value.\nIf value != 0, set and return saturation value.\n\n\nReturns: returns saturation value\n" + }, + "args": [ + [ + "int", + "value", + "-1" + ] + ], + "ret_type": "int", + "static": false, + "def": "int saturation(int value = -1)" + }, + "awb_mode": { + "type": "func", + "name": "awb_mode", + "doc": { + "brief": "Set/Get white balance mode (deprecated interface)", + "attention": "This method will affect the isp and thus the image, so please be careful with it.\nThis interface may be deprecated in the future, and there may be incompatibilities in the definition of the parameters of the new interface", + "param": { + "value": "value = 0, means set white balance to auto mode, value = 1, means set white balance to manual mode, default is auto mode." + }, + "return": "returns awb mode", + "maixpy": "maix.camera.Camera.awb_mode", + "py_doc": "Set/Get white balance mode (deprecated interface)\n\nArgs:\n - value: value = 0, means set white balance to auto mode, value = 1, means set white balance to manual mode, default is auto mode.\n\n\nReturns: returns awb mode\n" + }, + "args": [ + [ + "int", + "value", + "-1" + ] + ], + "ret_type": "int", + "static": false, + "def": "int awb_mode(int value = -1)" + }, + "set_awb": { + "type": "func", + "name": "set_awb", + "doc": { + "brief": "Set/Get white balance mode", + "attention": "This method will affect the isp and thus the image, so please be careful with it.", + "param": { + "value": "value = 0, means set white balance to manual mode, value = 1, means set white balance to auto mode, default is auto mode." + }, + "return": "returns awb mode", + "maixpy": "maix.camera.Camera.set_awb", + "py_doc": "Set/Get white balance mode\n\nArgs:\n - value: value = 0, means set white balance to manual mode, value = 1, means set white balance to auto mode, default is auto mode.\n\n\nReturns: returns awb mode\n" + }, + "args": [ + [ + "int", + "mode", + "-1" + ] + ], + "ret_type": "int", + "static": false, + "def": "int set_awb(int mode = -1)" + }, + "exp_mode": { + "type": "func", + "name": "exp_mode", + "doc": { + "brief": "Set/Get exposure mode (deprecated interface)", + "attention": "This method will affect the isp and thus the image, so please be careful with it.\nThis interface may be deprecated in the future, and there may be incompatibilities in the definition of the parameters of the new interface", + "param": { + "value": "value = 0, means set exposure to auto mode, value = 1, means set exposure to manual mode, default is auto mode." + }, + "return": "returns exposure mode", + "maixpy": "maix.camera.Camera.exp_mode", + "py_doc": "Set/Get exposure mode (deprecated interface)\n\nArgs:\n - value: value = 0, means set exposure to auto mode, value = 1, means set exposure to manual mode, default is auto mode.\n\n\nReturns: returns exposure mode\n" + }, + "args": [ + [ + "int", + "value", + "-1" + ] + ], + "ret_type": "int", + "static": false, + "def": "int exp_mode(int value = -1)" + }, + "set_windowing": { + "type": "func", + "name": "set_windowing", + "doc": { + "brief": "Set window size of camera", + "param": { + "roi": "Support two input formats, [x,y,w,h] set the coordinates and size of the window;\n[w,h] set the size of the window, when the window is centred." + }, + "return": "error code", + "maixpy": "maix.camera.Camera.set_windowing", + "py_doc": "Set window size of camera\n\nArgs:\n - roi: Support two input formats, [x,y,w,h] set the coordinates and size of the window;\n[w,h] set the size of the window, when the window is centred.\n\n\nReturns: error code\n" + }, + "args": [ + [ + "std::vector", + "roi", + null + ] + ], + "ret_type": "err::Err", + "static": false, + "def": "err::Err set_windowing(std::vector roi)" + } + }, + "def": "class Camera" + } + }, + "auto_add": false + }, + "rtsp": { + "type": "module", + "doc": { + "brief": "maix.rtsp module" + }, + "members": { + "RtspStreamType": { + "type": "enum", + "name": "RtspStreamType", + "doc": { + "brief": "The stream type of rtsp", + "maixpy": "maix.rtsp.RtspStreamType", + "py_doc": "The stream type of rtsp" + }, + "values": [ + [ + "RTSP_STREAM_NONE", + "0", + "format invalid" + ], + [ + "RTSP_STREAM_H264", + "", + "" + ], + [ + "RTSP_STREAM_H265", + "", + "" + ] + ], + "def": "enum RtspStreamType\n {\n RTSP_STREAM_NONE = 0, // format invalid\n RTSP_STREAM_H264,\n RTSP_STREAM_H265,\n }" + }, + "Region": { + "type": "class", + "name": "Region", + "doc": { + "brief": "Region class", + "maixpy": "maix.rtsp.Region", + "py_doc": "Region class" + }, + "members": { + "Region": { + "type": "func", + "name": "Region", + "doc": { + "brief": "Construct a new Region object", + "param": { + "x": "region coordinate x", + "y": "region coordinate y", + "width": "region width", + "height": "region height", + "format": "region format", + "camera": "bind region to camera" + }, + "maixpy": "maix.rtsp.Region.__init__", + "maixcdk": "maix.rtsp.Region.Region", + "py_doc": "Construct a new Region object\n\nArgs:\n - x: region coordinate x\n - y: region coordinate y\n - width: region width\n - height: region height\n - format: region format\n - camera: bind region to camera\n" + }, + "args": [ + [ + "int", + "x", + null + ], + [ + "int", + "y", + null + ], + [ + "int", + "width", + null + ], + [ + "int", + "height", + null + ], + [ + "image::Format", + "format", + null + ], + [ + "camera::Camera *", + "camera", + null + ] + ], + "ret_type": null, + "static": false, + "def": "Region(int x, int y, int width, int height, image::Format format, camera::Camera *camera)" + }, + "get_canvas": { + "type": "func", + "name": "get_canvas", + "doc": { + "brief": "Return an image object from region", + "return": "image object", + "maixpy": "maix.rtsp.Region.get_canvas", + "py_doc": "Return an image object from region\n\nReturns: image object\n" + }, + "args": [], + "ret_type": "image::Image*", + "static": false, + "def": "image::Image *get_canvas()" + }, + "update_canvas": { + "type": "func", + "name": "update_canvas", + "doc": { + "brief": "Update canvas", + "return": "error code", + "maixpy": "maix.rtsp.Region.update_canvas", + "py_doc": "Update canvas\n\nReturns: error code\n" + }, + "args": [], + "ret_type": "err::Err", + "static": false, + "def": "err::Err update_canvas()" + } + }, + "def": "class Region" + }, + "Rtsp": { + "type": "class", + "name": "Rtsp", + "doc": { + "brief": "Rtsp class", + "maixpy": "maix.rtsp.Rtsp", + "py_doc": "Rtsp class" + }, + "members": { + "Rtsp": { + "type": "func", + "name": "Rtsp", + "doc": { + "brief": "Construct a new Video object", + "param": { + "ip": "rtsp ip", + "port": "rtsp port", + "fps": "rtsp fps", + "stream_type": "rtsp stream type", + "bitrate": "rtsp bitrate" + }, + "maixpy": "maix.rtsp.Rtsp.__init__", + "maixcdk": "maix.rtsp.Rtsp.Rtsp", + "py_doc": "Construct a new Video object\n\nArgs:\n - ip: rtsp ip\n - port: rtsp port\n - fps: rtsp fps\n - stream_type: rtsp stream type\n - bitrate: rtsp bitrate\n" + }, + "args": [ + [ + "std::string", + "ip", + "std::string()" + ], + [ + "int", + "port", + "8554" + ], + [ + "int", + "fps", + "30" + ], + [ + "rtsp::RtspStreamType", + "stream_type", + "rtsp::RtspStreamType::RTSP_STREAM_H264" + ], + [ + "int", + "bitrate", + "3000 * 1000" + ] + ], + "ret_type": null, + "static": false, + "def": "Rtsp(std::string ip = std::string(), int port = 8554, int fps = 30, rtsp::RtspStreamType stream_type = rtsp::RtspStreamType::RTSP_STREAM_H264, int bitrate = 3000 * 1000)" + }, + "start": { + "type": "func", + "name": "start", + "doc": { + "brief": "start rtsp", + "return": "error code, err::ERR_NONE means success, others means failed", + "maixpy": "maix.rtsp.Rtsp.start", + "py_doc": "start rtsp\n\nReturns: error code, err::ERR_NONE means success, others means failed\n" + }, + "args": [], + "ret_type": "err::Err", + "static": false, + "def": "err::Err start()", + "overload": [ + { + "type": "func", + "name": "stop", + "doc": { + "brief": "stop rtsp", + "return": "error code, err::ERR_NONE means success, others means failed", + "maixpy": "maix.rtsp.Rtsp.start", + "py_doc": "stop rtsp\n\nReturns: error code, err::ERR_NONE means success, others means failed\n" + }, + "args": [], + "ret_type": "err::Err", + "static": false, + "def": "err::Err stop()" + } + ] + }, + "bind_camera": { + "type": "func", + "name": "bind_camera", + "doc": { + "brief": "Bind camera", + "param": { + "camera": "camera object" + }, + "return": "error code, err::ERR_NONE means success, others means failed", + "maixpy": "maix.rtsp.Rtsp.bind_camera", + "py_doc": "Bind camera\n\nArgs:\n - camera: camera object\n\n\nReturns: error code, err::ERR_NONE means success, others means failed\n" + }, + "args": [ + [ + "camera::Camera *", + "camera", + null + ] + ], + "ret_type": "err::Err", + "static": false, + "def": "err::Err bind_camera(camera::Camera *camera)" + }, + "bind_audio_recorder": { + "type": "func", + "name": "bind_audio_recorder", + "doc": { + "brief": "Bind audio recorder", + "note": "If the audio_recorder object is bound, the audio_recorder object cannot be used elsewhere.", + "param": { + "recorder": "audio_recorder object" + }, + "return": "error code, err::ERR_NONE means success, others means failed", + "maixpy": "maix.rtsp.Rtsp.bind_audio_recorder", + "py_doc": "Bind audio recorder\n\nArgs:\n - recorder: audio_recorder object\n\n\nReturns: error code, err::ERR_NONE means success, others means failed\n" + }, + "args": [ + [ + "audio::Recorder *", + "recorder", + null + ] + ], + "ret_type": "err::Err", + "static": false, + "def": "err::Err bind_audio_recorder(audio::Recorder *recorder)" + }, + "write": { + "type": "func", + "name": "write", + "doc": { + "brief": "Write data to rtsp(This function will be removed in the future)", + "param": { + "frame": "video frame data" + }, + "return": "error code, err::ERR_NONE means success, others means failed", + "maixpy": "maix.rtsp.Rtsp.write", + "py_doc": "Write data to rtsp(This function will be removed in the future)\n\nArgs:\n - frame: video frame data\n\n\nReturns: error code, err::ERR_NONE means success, others means failed\n" + }, + "args": [ + [ + "video::Frame &", + "frame", + null + ] + ], + "ret_type": "err::Err", + "static": false, + "def": "err::Err write(video::Frame &frame)" + }, + "get_url": { + "type": "func", + "name": "get_url", + "doc": { + "brief": "Get url of rtsp", + "return": "url of rtsp", + "maixpy": "maix.rtsp.Rtsp.get_url", + "py_doc": "Get url of rtsp\n\nReturns: url of rtsp\n" + }, + "args": [], + "ret_type": "std::string", + "static": false, + "def": "std::string get_url()" + }, + "get_urls": { + "type": "func", + "name": "get_urls", + "doc": { + "brief": "Get url list of rtsp", + "return": "url list of rtsp", + "maixpy": "maix.rtsp.Rtsp.get_urls", + "py_doc": "Get url list of rtsp\n\nReturns: url list of rtsp\n" + }, + "args": [], + "ret_type": "std::vector", + "static": false, + "def": "std::vector get_urls()" + }, + "to_camera": { + "type": "func", + "name": "to_camera", + "doc": { + "brief": "Get camera object from rtsp", + "return": "camera object", + "maixpy": "maix.rtsp.Rtsp.to_camera", + "py_doc": "Get camera object from rtsp\n\nReturns: camera object\n" + }, + "args": [], + "ret_type": "camera::Camera*", + "static": false, + "def": "camera::Camera *to_camera()" + }, + "rtsp_is_start": { + "type": "func", + "name": "rtsp_is_start", + "doc": { + "brief": "return rtsp start status", + "return": "true means rtsp is start, false means rtsp is stop.", + "maixcdk": "maix.rtsp.Rtsp.rtsp_is_start", + "py_doc": "return rtsp start status\n\nReturns: true means rtsp is start, false means rtsp is stop.\n" + }, + "args": [], + "ret_type": "bool", + "static": false, + "def": "bool rtsp_is_start()" + }, + "add_region": { + "type": "func", + "name": "add_region", + "doc": { + "brief": "return a region object, you can draw image on the region.(This function will be removed in the future)", + "param": { + "x": "region coordinate x", + "y": "region coordinate y", + "width": "region width", + "height": "region height", + "format": "region format, support Format::FMT_BGRA8888 only" + }, + "return": "the reigon object", + "maixpy": "maix.rtsp.Rtsp.add_region", + "py_doc": "return a region object, you can draw image on the region.(This function will be removed in the future)\n\nArgs:\n - x: region coordinate x\n - y: region coordinate y\n - width: region width\n - height: region height\n - format: region format, support Format::FMT_BGRA8888 only\n\n\nReturns: the reigon object\n" + }, + "args": [ + [ + "int", + "x", + null + ], + [ + "int", + "y", + null + ], + [ + "int", + "width", + null + ], + [ + "int", + "height", + null + ], + [ + "image::Format", + "format", + "image::Format::FMT_BGRA8888" + ] + ], + "ret_type": "rtsp::Region*", + "static": false, + "def": "rtsp::Region *add_region(int x, int y, int width, int height, image::Format format = image::Format::FMT_BGRA8888)" + }, + "update_region": { + "type": "func", + "name": "update_region", + "doc": { + "brief": "update and show region(This function will be removed in the future)", + "return": "error code", + "maixpy": "maix.rtsp.Rtsp.update_region", + "py_doc": "update and show region(This function will be removed in the future)\n\nReturns: error code\n" + }, + "args": [ + [ + "rtsp::Region &", + "region", + null + ] + ], + "ret_type": "err::Err", + "static": false, + "def": "err::Err update_region(rtsp::Region ®ion)" + }, + "del_region": { + "type": "func", + "name": "del_region", + "doc": { + "brief": "del region(This function will be removed in the future)", + "return": "error code", + "maixpy": "maix.rtsp.Rtsp.del_region", + "py_doc": "del region(This function will be removed in the future)\n\nReturns: error code\n" + }, + "args": [ + [ + "rtsp::Region *", + "region", + null + ] + ], + "ret_type": "err::Err", + "static": false, + "def": "err::Err del_region(rtsp::Region *region)" + }, + "draw_rect": { + "type": "func", + "name": "draw_rect", + "doc": { + "brief": "Draw a rectangle on the canvas(This function will be removed in the future)", + "param": { + "id": "region id", + "x": "rectangle coordinate x", + "y": "rectangle coordinate y", + "width": "rectangle width", + "height": "rectangle height", + "color": "rectangle color", + "thickness": "rectangle thickness. If you set it to -1, the rectangle will be filled." + }, + "return": "error code", + "maixpy": "maix.rtsp.Rtsp.draw_rect", + "py_doc": "Draw a rectangle on the canvas(This function will be removed in the future)\n\nArgs:\n - id: region id\n - x: rectangle coordinate x\n - y: rectangle coordinate y\n - width: rectangle width\n - height: rectangle height\n - color: rectangle color\n - thickness: rectangle thickness. If you set it to -1, the rectangle will be filled.\n\n\nReturns: error code\n" + }, + "args": [ + [ + "int", + "id", + null + ], + [ + "int", + "x", + null + ], + [ + "int", + "y", + null + ], + [ + "int", + "width", + null + ], + [ + "int", + "height", + null + ], + [ + "image::Color", + "color", + null + ], + [ + "int", + "thickness", + "1" + ] + ], + "ret_type": "err::Err", + "static": false, + "def": "err::Err draw_rect(int id, int x, int y, int width, int height, image::Color color, int thickness = 1)" + }, + "draw_string": { + "type": "func", + "name": "draw_string", + "doc": { + "brief": "Draw a string on the canvas(This function will be removed in the future)", + "param": { + "id": "region id", + "x": "string coordinate x", + "y": "string coordinate y", + "str": "string", + "color": "string color", + "size": "string size", + "thickness": "string thickness" + }, + "return": "error code", + "maixpy": "maix.rtsp.Rtsp.draw_string", + "py_doc": "Draw a string on the canvas(This function will be removed in the future)\n\nArgs:\n - id: region id\n - x: string coordinate x\n - y: string coordinate y\n - str: string\n - color: string color\n - size: string size\n - thickness: string thickness\n\n\nReturns: error code\n" + }, + "args": [ + [ + "int", + "id", + null + ], + [ + "int", + "x", + null + ], + [ + "int", + "y", + null + ], + [ + "const char *", + "str", + null + ], + [ + "image::Color", + "color", + null + ], + [ + "int", + "size", + "16" + ], + [ + "int", + "thickness", + "1" + ] + ], + "ret_type": "err::Err", + "static": false, + "def": "err::Err draw_string(int id, int x, int y, const char *str, image::Color color, int size = 16, int thickness = 1)" + } + }, + "def": "class Rtsp" + } + }, + "auto_add": true + }, + "rtmp": { + "type": "module", + "doc": { + "brief": "maix.rtmp module", + "maixpy": "maix.rtmp", + "py_doc": "maix.rtmp module" + }, + "members": { + "TagType": { + "type": "enum", + "name": "TagType", + "doc": { + "brief": "Video type", + "maixpy": "maix.rtmp.TagType", + "py_doc": "Video type" + }, + "values": [ + [ + "TAG_NONE", + "", + "" + ], + [ + "TAG_VIDEO", + "", + "" + ], + [ + "TAG_AUDIO", + "", + "" + ], + [ + "TAG_SCRIPT", + "", + "" + ] + ], + "def": "enum TagType\n {\n TAG_NONE,\n TAG_VIDEO,\n TAG_AUDIO,\n TAG_SCRIPT,\n }" + }, + "Rtmp": { + "type": "class", + "name": "Rtmp", + "doc": { + "brief": "Rtmp class", + "maixpy": "maix.rtmp.Rtmp", + "py_doc": "Rtmp class" + }, + "members": { + "Rtmp": { + "type": "func", + "name": "Rtmp", + "doc": { + "brief": "Construct a new Video object", + "note": "Rtmp url : rtmp://host:prot/app/stream\nexample:\nr = Rtmp(\"localhost\", 1935, \"live\", \"stream\")\nmeans rtmp url is rtmp://localhost:1935/live/stream", + "param": { + "host": "rtmp ip", + "port": "rtmp port, default is 1935.", + "app": "rtmp app name", + "stream": "rtmp stream name", + "bitrate": "rtmp bitrate, default is 1000 * 1000" + }, + "maixpy": "maix.rtmp.Rtmp.__init__", + "maixcdk": "maix.rtmp.Rtmp.Rtmp", + "py_doc": "Construct a new Video object\n\nArgs:\n - host: rtmp ip\n - port: rtmp port, default is 1935.\n - app: rtmp app name\n - stream: rtmp stream name\n - bitrate: rtmp bitrate, default is 1000 * 1000\n" + }, + "args": [ + [ + "std::string", + "host", + "\"localhost\"" + ], + [ + "int", + "port", + "1935" + ], + [ + "std::string", + "app", + "std::string()" + ], + [ + "std::string", + "stream", + "std::string()" + ], + [ + "int", + "bitrate", + "1000 * 1000" + ] + ], + "ret_type": null, + "static": false, + "def": "Rtmp(std::string host = \"localhost\", int port = 1935, std::string app = std::string(), std::string stream = std::string(), int bitrate = 1000 * 1000)" + }, + "push_video": { + "type": "func", + "name": "bitrate", + "doc": { + "brief": "Get bitrate", + "return": "bitrate", + "maixpy": "maix.rtmp.Rtmp.push_video", + "py_doc": "Get bitrate\n\nReturns: bitrate\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int bitrate()", + "overload": [ + { + "type": "func", + "name": "push_video", + "doc": { + "brief": "Push rtmp video data", + "return": "return 0 ok, other error", + "maixcdk": "maix.rtmp.Rtmp.push_video", + "py_doc": "Push rtmp video data\n\nReturns: return 0 ok, other error\n" + }, + "args": [ + [ + "void *", + "data", + null + ], + [ + "size_t", + "data_size", + null + ], + [ + "uint32_t", + "timestamp", + null + ] + ], + "ret_type": "int", + "static": false, + "def": "int push_video(void *data, size_t data_size, uint32_t timestamp)" + } + ] + }, + "push_audio": { + "type": "func", + "name": "push_audio", + "doc": { + "brief": "Push rtmp audio data", + "return": "return 0 ok, other error", + "maixcdk": "maix.rtmp.Rtmp.push_audio", + "py_doc": "Push rtmp audio data\n\nReturns: return 0 ok, other error\n" + }, + "args": [ + [ + "void *", + "data", + null + ], + [ + "size_t", + "data_size", + null + ], + [ + "uint32_t", + "timestamp", + null + ] + ], + "ret_type": "int", + "static": false, + "def": "int push_audio(void *data, size_t data_size, uint32_t timestamp)" + }, + "push_script": { + "type": "func", + "name": "push_script", + "doc": { + "brief": "Push rtmp script data", + "return": "return 0 ok, other error", + "maixcdk": "maix.rtmp.Rtmp.push_script", + "py_doc": "Push rtmp script data\n\nReturns: return 0 ok, other error\n" + }, + "args": [ + [ + "void *", + "data", + null + ], + [ + "size_t", + "data_size", + null + ], + [ + "uint32_t", + "timestamp", + null + ] + ], + "ret_type": "int", + "static": false, + "def": "int push_script(void *data, size_t data_size, uint32_t timestamp)" + }, + "bind_camera": { + "type": "func", + "name": "bind_camera", + "doc": { + "brief": "Bind camera", + "note": "If the cam object is bound, the cam object cannot be used elsewhere.", + "param": { + "cam": "camera object" + }, + "return": "error code, err::ERR_NONE means success, others means failed", + "maixpy": "maix.rtmp.Rtmp.bind_camera", + "py_doc": "Bind camera\n\nArgs:\n - cam: camera object\n\n\nReturns: error code, err::ERR_NONE means success, others means failed\n" + }, + "args": [ + [ + "camera::Camera *", + "cam", + null + ] + ], + "ret_type": "err::Err", + "static": false, + "def": "err::Err bind_camera(camera::Camera *cam)" + }, + "bind_audio_recorder": { + "type": "func", + "name": "bind_audio_recorder", + "doc": { + "brief": "Bind audio recorder", + "note": "If the audio_recorder object is bound, the audio_recorder object cannot be used elsewhere.", + "param": { + "recorder": "audio_recorder object" + }, + "return": "error code, err::ERR_NONE means success, others means failed", + "maixpy": "maix.rtmp.Rtmp.bind_audio_recorder", + "py_doc": "Bind audio recorder\n\nArgs:\n - recorder: audio_recorder object\n\n\nReturns: error code, err::ERR_NONE means success, others means failed\n" + }, + "args": [ + [ + "audio::Recorder *", + "recorder", + null + ] + ], + "ret_type": "err::Err", + "static": false, + "def": "err::Err bind_audio_recorder(audio::Recorder *recorder)" + }, + "bind_display": { + "type": "func", + "name": "bind_display", + "doc": { + "brief": "Bind display", + "note": "If the display object is bound, the display object cannot be used elsewhere.", + "param": { + "disaply": "display object" + }, + "return": "error code, err::ERR_NONE means success, others means failed", + "maixpy": "maix.rtmp.Rtmp.bind_display", + "py_doc": "Bind display\n\nArgs:\n - disaply: display object\n\n\nReturns: error code, err::ERR_NONE means success, others means failed\n" + }, + "args": [ + [ + "display::Display *", + "display", + null + ] + ], + "ret_type": "err::Err", + "static": false, + "def": "err::Err bind_display(display::Display *display)" + }, + "get_camera": { + "type": "func", + "name": "get_camera", + "doc": { + "brief": "If you bind a camera, return the camera object.", + "return": "Camera object", + "maixpy": "maix.rtmp.Rtmp.get_camera", + "py_doc": "If you bind a camera, return the camera object.\n\nReturns: Camera object\n" + }, + "args": [], + "ret_type": "camera::Camera*", + "static": false, + "def": "camera::Camera *get_camera()" + }, + "capture": { + "type": "func", + "name": "capture", + "doc": { + "brief": "If you bind a camera, capture the image of the camera", + "note": "The return value may be null, you must check whether the return value is null", + "return": "Image object", + "maixcdk": "maix.rtmp.Rtmp.capture", + "py_doc": "If you bind a camera, capture the image of the camera\n\nReturns: Image object\n" + }, + "args": [], + "ret_type": "image::Image*", + "static": false, + "def": "image::Image *capture()" + }, + "start": { + "type": "func", + "name": "start", + "doc": { + "brief": "Start push stream", + "note": "only support flv file now", + "param": { + "path": "File path, if you passed file path, cyclic push the file, else if you bound camera, push the camera image.(This parameter has been deprecated)" + }, + "return": "error code, err::ERR_NONE means success, others means failed", + "maixpy": "maix.rtmp.Rtmp.start", + "py_doc": "Start push stream\n\nArgs:\n - path: File path, if you passed file path, cyclic push the file, else if you bound camera, push the camera image.(This parameter has been deprecated)\n\n\nReturns: error code, err::ERR_NONE means success, others means failed\n" + }, + "args": [ + [ + "std::string", + "path", + "std::string()" + ] + ], + "ret_type": "err::Err", + "static": false, + "def": "err::Err start(std::string path = std::string())" + }, + "stop": { + "type": "func", + "name": "stop", + "doc": { + "brief": "Stop push stream", + "return": "error code, err::ERR_NONE means success, others means failed", + "maixpy": "maix.rtmp.Rtmp.stop", + "py_doc": "Stop push stream\n\nReturns: error code, err::ERR_NONE means success, others means failed\n" + }, + "args": [], + "ret_type": "err::Err", + "static": false, + "def": "err::Err stop()" + }, + "lock": { + "type": "func", + "name": "lock", + "doc": { + "brief": "Lock", + "param": { + "time": "lock time, unit:ms" + }, + "return": "error code, err::ERR_NONE means success, others means failed", + "maixcdk": "maix.rtmp.Rtmp.lock", + "py_doc": "Lock\n\nArgs:\n - time: lock time, unit:ms\n\n\nReturns: error code, err::ERR_NONE means success, others means failed\n" + }, + "args": [ + [ + "uint32_t", + "time", + null + ] + ], + "ret_type": "err::Err", + "static": false, + "def": "err::Err lock(uint32_t time)" + }, + "unlock": { + "type": "func", + "name": "unlock", + "doc": { + "brief": "Unlock", + "return": "error code, err::ERR_NONE means success, others means failed", + "maixcdk": "maix.rtmp.Rtmp.unlock", + "py_doc": "Unlock\n\nReturns: error code, err::ERR_NONE means success, others means failed\n" + }, + "args": [], + "ret_type": "err::Err", + "static": false, + "def": "err::Err unlock()" + }, + "get_path": { + "type": "func", + "name": "get_path", + "doc": { + "brief": "Get the file path of the push stream", + "return": "file path", + "maixpy": "maix.rtmp.Rtmp.get_path", + "py_doc": "Get the file path of the push stream\n\nReturns: file path\n" + }, + "args": [], + "ret_type": "std::string", + "static": false, + "def": "std::string get_path()", + "overload": [ + { + "type": "func", + "name": "is_started", + "doc": { + "brief": "Check whether push streaming has started", + "return": "If rtmp thread is running, returns true", + "maixpy": "maix.rtmp.Rtmp.get_path", + "py_doc": "Check whether push streaming has started\n\nReturns: If rtmp thread is running, returns true\n" + }, + "args": [], + "ret_type": "bool", + "static": false, + "def": "bool is_started()" + } + ] + } + }, + "def": "class Rtmp" + } + }, + "auto_add": false + }, + "touchscreen": { + "type": "module", + "doc": { + "brief": "maix.touchscreen module" + }, + "members": { + "TouchScreen": { + "type": "class", + "name": "TouchScreen", + "doc": { + "brief": "TouchScreen class", + "maixpy": "maix.touchscreen.TouchScreen", + "py_doc": "TouchScreen class" + }, + "members": { + "TouchScreen": { + "type": "func", + "name": "TouchScreen", + "doc": { + "brief": "Construct a new TouchScreen object", + "param": { + "device": "touchscreen device path, you can get devices by list_devices method, by default(value is NULL(None in MaixPy)) means the first device", + "open": "If true, touchscreen will automatically call open() after creation. default is true." + }, + "maixpy": "maix.touchscreen.TouchScreen.__init__", + "maixcdk": "maix.touchscreen.TouchScreen.TouchScreen", + "py_doc": "Construct a new TouchScreen object\n\nArgs:\n - device: touchscreen device path, you can get devices by list_devices method, by default(value is NULL(None in MaixPy)) means the first device\n - open: If true, touchscreen will automatically call open() after creation. default is true.\n" + }, + "args": [ + [ + "const std::string &", + "device", + "\"\"" + ], + [ + "bool", + "open", + "true" + ] + ], + "ret_type": null, + "static": false, + "def": "TouchScreen(const std::string &device = \"\", bool open = true)" + }, + "open": { + "type": "func", + "name": "open", + "doc": { + "brief": "open touchscreen device", + "return": "error code, err::ERR_NONE means success, others means failed", + "maixpy": "maix.touchscreen.TouchScreen.open", + "py_doc": "open touchscreen device\n\nReturns: error code, err::ERR_NONE means success, others means failed\n" + }, + "args": [], + "ret_type": "err::Err", + "static": false, + "def": "err::Err open()" + }, + "close": { + "type": "func", + "name": "close", + "doc": { + "brief": "close touchscreen device", + "return": "error code, err::ERR_NONE means success, others means failed", + "maixpy": "maix.touchscreen.TouchScreen.close", + "py_doc": "close touchscreen device\n\nReturns: error code, err::ERR_NONE means success, others means failed\n" + }, + "args": [], + "ret_type": "err::Err", + "static": false, + "def": "err::Err close()" + }, + "read": { + "type": "func", + "name": "read", + "doc": { + "brief": "read touchscreen device.", + "attention": "This method will discard same event in buffer, that is:\nif too many move event in buffer when call this method, it will only return the last one,\nand if read pressed or released event, it will return immediately.", + "param": { + "x": "x coordinate", + "y": "y coordinate", + "pressed": "pressed state" + }, + "return": "error code, err::ERR_NONE means success, others means failed, if no event return err::ERR_NOT_READY", + "maixcdk": "maix.touchscreen.TouchScreen.read", + "py_doc": "read touchscreen device.\n\nArgs:\n - x: x coordinate\n - y: y coordinate\n - pressed: pressed state\n\n\nReturns: error code, err::ERR_NONE means success, others means failed, if no event return err::ERR_NOT_READY\n" + }, + "args": [ + [ + "int &", + "x", + null + ], + [ + "int &", + "y", + null + ], + [ + "bool &", + "pressed", + null + ] + ], + "ret_type": "err::Err", + "static": false, + "def": "err::Err read(int &x, int &y, bool &pressed)", + "overload": [ + { + "type": "func", + "name": "read", + "doc": { + "brief": "read touchscreen device", + "attention": "This method will discard same event in buffer, that is:\nif too many move event in buffer when call this method, it will only return the last one,\nand if read pressed or released event, it will return immediately.", + "return": "Returns a list include x, y, pressed state", + "maixpy": "maix.touchscreen.TouchScreen.read", + "py_doc": "read touchscreen device\n\nReturns: Returns a list include x, y, pressed state\n" + }, + "args": [], + "ret_type": "std::vector", + "static": false, + "def": "std::vector read()" + }, + { + "type": "func", + "name": "read0", + "doc": { + "brief": "read touchscreen device", + "attention": "This method will return immediately if have event, so it's better to use available() to check if have more event in buffer,\nor too much event in buffer when your program call this read() interval is too long will make your program slow.", + "param": { + "x": "x coordinate", + "y": "y coordinate", + "pressed": "pressed state" + }, + "return": "error code, err::ERR_NONE means success, others means failed, if no event return err::ERR_NOT_READY", + "maixcdk": "maix.touchscreen.TouchScreen.read", + "py_doc": "read touchscreen device\n\nArgs:\n - x: x coordinate\n - y: y coordinate\n - pressed: pressed state\n\n\nReturns: error code, err::ERR_NONE means success, others means failed, if no event return err::ERR_NOT_READY\n" + }, + "args": [ + [ + "int &", + "x", + null + ], + [ + "int &", + "y", + null + ], + [ + "bool &", + "pressed", + null + ] + ], + "ret_type": "err::Err", + "static": false, + "def": "err::Err read0(int &x, int &y, bool &pressed)" + }, + { + "type": "func", + "name": "read0", + "doc": { + "brief": "read touchscreen device", + "attention": "This method will return immediately if have event, so it's better to use available() to check if have more event in buffer,\nor too much event in buffer when your program call this read() interval is too long will make your program slow.", + "return": "Returns a list include x, y, pressed state", + "maixpy": "maix.touchscreen.TouchScreen.read", + "py_doc": "read touchscreen device\n\nReturns: Returns a list include x, y, pressed state\n" + }, + "args": [], + "ret_type": "std::vector", + "static": false, + "def": "std::vector read0()" + } + ] + }, + "available": { + "type": "func", + "name": "available", + "doc": { + "brief": "If we need to read from touchscreen, for event driven touchscreen means have event or not", + "param": { + "timeout": "-1 means block, 0 means no block, >0 means timeout, default is 0, unit is ms." + }, + "return": "true if need to read(have event), false if not", + "maixpy": "maix.touchscreen.TouchScreen.available", + "py_doc": "If we need to read from touchscreen, for event driven touchscreen means have event or not\n\nArgs:\n - timeout: -1 means block, 0 means no block, >0 means timeout, default is 0, unit is ms.\n\n\nReturns: true if need to read(have event), false if not\n" + }, + "args": [ + [ + "int", + "timeout", + "0" + ] + ], + "ret_type": "bool", + "static": false, + "def": "bool available(int timeout = 0)" + }, + "is_opened": { + "type": "func", + "name": "is_opened", + "doc": { + "brief": "Check if touchscreen is opened", + "return": "true if touchscreen is opened, false if not", + "maixpy": "maix.touchscreen.TouchScreen.is_opened", + "py_doc": "Check if touchscreen is opened\n\nReturns: true if touchscreen is opened, false if not\n" + }, + "args": [], + "ret_type": "bool", + "static": false, + "def": "bool is_opened()" + } + }, + "def": "class TouchScreen" + } + }, + "auto_add": true + }, + "video": { + "type": "module", + "doc": { + "brief": "maix.video module", + "maixpy": "maix.video", + "py_doc": "maix.video module" + }, + "members": { + "VideoType": { + "type": "enum", + "name": "VideoType", + "doc": { + "brief": "Video type", + "maixpy": "maix.video.VideoType", + "py_doc": "Video type" + }, + "values": [ + [ + "VIDEO_NONE", + "0", + "format invalid" + ], + [ + "VIDEO_ENC_H265_CBR", + "", + "Deprecated" + ], + [ + "VIDEO_ENC_MP4_CBR", + "", + "Deprecated" + ], + [ + "VIDEO_DEC_H265_CBR", + "", + "Deprecated" + ], + [ + "VIDEO_DEC_MP4_CBR", + "", + "Deprecated" + ], + [ + "VIDEO_H264_CBR", + "", + "Deprecated" + ], + [ + "VIDEO_H265_CBR", + "", + "Deprecated" + ], + [ + "VIDEO_H264_CBR_MP4", + "", + "Deprecated" + ], + [ + "VIDEO_H265_CBR_MP4", + "", + "Deprecated" + ], + [ + "VIDEO_H264", + "", + "" + ], + [ + "VIDEO_H264_MP4", + "", + "" + ], + [ + "VIDEO_H264_FLV", + "", + "" + ], + [ + "VIDEO_H265", + "", + "" + ], + [ + "VIDEO_H265_MP4", + "", + "" + ] + ], + "def": "enum VideoType\n {\n VIDEO_NONE = 0, // format invalid\n VIDEO_ENC_H265_CBR, // Deprecated\n VIDEO_ENC_MP4_CBR, // Deprecated\n VIDEO_DEC_H265_CBR, // Deprecated\n VIDEO_DEC_MP4_CBR, // Deprecated\n VIDEO_H264_CBR, // Deprecated\n VIDEO_H265_CBR, // Deprecated\n VIDEO_H264_CBR_MP4, // Deprecated\n VIDEO_H265_CBR_MP4, // Deprecated\n\n VIDEO_H264,\n VIDEO_H264_MP4,\n VIDEO_H264_FLV,\n VIDEO_H265,\n VIDEO_H265_MP4,\n }" + }, + "MediaType": { + "type": "enum", + "name": "MediaType", + "doc": { + "brief": "Video type", + "maixpy": "maix.video.MediaType", + "py_doc": "Video type" + }, + "values": [ + [ + "MEDIA_TYPE_UNKNOWN", + "-1", + "Represents an unknown media type, which is usually treated as AVMEDIA_TYPE_DATA." + ], + [ + "MEDIA_TYPE_VIDEO", + "", + "Represents a video stream, such as video content encoded in H.264, MPEG-4, etc." + ], + [ + "MEDIA_TYPE_AUDIO", + "", + "Represents an audio stream, such as audio content encoded in AAC, MP3, etc." + ], + [ + "MEDIA_TYPE_DATA", + "", + "Represents opaque data streams that are usually continuous. This type of stream is not necessarily audio or video and may be used for other data purposes." + ], + [ + "MEDIA_TYPE_SUBTITLE", + "", + "Represents a subtitle stream used for displaying text or subtitle information, such as SRT, ASS, etc." + ], + [ + "MEDIA_TYPE_ATTACHMENT", + "", + "Represents attachment streams that are usually sparse. Attachment streams can include images, fonts, or other files that need to be bundled with the media." + ], + [ + "MEDIA_TYPE_NB", + "", + "Represents the number of media types (count) and indicates the total number of media types defined in this enumeration. It is not a media type itself but is used for counting enumeration items." + ] + ], + "def": "enum MediaType\n {\n MEDIA_TYPE_UNKNOWN = -1, // Represents an unknown media type, which is usually treated as AVMEDIA_TYPE_DATA.\n MEDIA_TYPE_VIDEO, // Represents a video stream, such as video content encoded in H.264, MPEG-4, etc.\n MEDIA_TYPE_AUDIO, // Represents an audio stream, such as audio content encoded in AAC, MP3, etc.\n MEDIA_TYPE_DATA, // Represents opaque data streams that are usually continuous. This type of stream is not necessarily audio or video and may be used for other data purposes.\n MEDIA_TYPE_SUBTITLE, // Represents a subtitle stream used for displaying text or subtitle information, such as SRT, ASS, etc.\n MEDIA_TYPE_ATTACHMENT, // Represents attachment streams that are usually sparse. Attachment streams can include images, fonts, or other files that need to be bundled with the media.\n MEDIA_TYPE_NB // Represents the number of media types (count) and indicates the total number of media types defined in this enumeration. It is not a media type itself but is used for counting enumeration items.\n }" + }, + "timebase_to_us": { + "type": "func", + "name": "timebase_to_us", + "doc": { + "brief": "Convert a value in timebase units to microseconds. value * 1000000 / (timebase[1] / timebase[0])", + "param": { + "timebse": "Time base, used as the unit for calculating playback time. It must be an array containing two parameters,\nin the format [num, den], where the first parameter is the numerator of the time base, and the second parameter is the denominator of the time base.", + "value": "Input value" + }, + "return": "Return the result in microseconds.", + "maixpy": "maix.video.timebase_to_us", + "py_doc": "Convert a value in timebase units to microseconds. value * 1000000 / (timebase[1] / timebase[0])\n\nArgs:\n - timebse: Time base, used as the unit for calculating playback time. It must be an array containing two parameters,\nin the format [num, den], where the first parameter is the numerator of the time base, and the second parameter is the denominator of the time base.\n - value: Input value\n\n\nReturns: Return the result in microseconds.\n" + }, + "args": [ + [ + "std::vector", + "timebase", + null + ], + [ + "uint64_t", + "value", + null + ] + ], + "ret_type": "double", + "static": false, + "def": "double timebase_to_us(std::vector timebase, uint64_t value)" + }, + "timebase_to_ms": { + "type": "func", + "name": "timebase_to_ms", + "doc": { + "brief": "Convert a value in timebase units to milliseconds.", + "param": { + "timebse": "Time base, used as the unit for calculating playback time. It must be an array containing two parameters,\nin the format [num, den], where the first parameter is the numerator of the time base, and the second parameter is the denominator of the time base.", + "value": "Input value" + }, + "return": "Return the result in milliseconds.", + "maixpy": "maix.video.timebase_to_ms", + "py_doc": "Convert a value in timebase units to milliseconds.\n\nArgs:\n - timebse: Time base, used as the unit for calculating playback time. It must be an array containing two parameters,\nin the format [num, den], where the first parameter is the numerator of the time base, and the second parameter is the denominator of the time base.\n - value: Input value\n\n\nReturns: Return the result in milliseconds.\n" + }, + "args": [ + [ + "std::vector", + "timebase", + null + ], + [ + "uint64_t", + "value", + null + ] + ], + "ret_type": "double", + "static": false, + "def": "double timebase_to_ms(std::vector timebase, uint64_t value)" + }, + "Context": { + "type": "class", + "name": "Context", + "doc": { + "brief": "Context class", + "maixpy": "maix.video.Context", + "py_doc": "Context class" + }, + "members": { + "Context": { + "type": "func", + "name": "Context", + "doc": { + "brief": "Construct a new Context object", + "param": { + "media_type": "enable capture, if true, you can use capture() function to get an image object", + "timebase": "Time base, used as the unit for calculating playback time. It must be an array containing two parameters,\nin the format [num, den], where the first parameter is the numerator of the time base, and the second parameter is the denominator of the time base." + }, + "maixpy": "maix.video.Context.__init__", + "maixcdk": "maix.video.Context.Context", + "py_doc": "Construct a new Context object\n\nArgs:\n - media_type: enable capture, if true, you can use capture() function to get an image object\n - timebase: Time base, used as the unit for calculating playback time. It must be an array containing two parameters,\nin the format [num, den], where the first parameter is the numerator of the time base, and the second parameter is the denominator of the time base.\n" + }, + "args": [ + [ + "video::MediaType", + "media_type", + null + ], + [ + "std::vector", + "timebase", + null + ] + ], + "ret_type": null, + "static": false, + "def": "Context(video::MediaType media_type, std::vector timebase)", + "overload": [ + { + "type": "func", + "name": "Context", + "doc": { + "brief": "Construct a new Context object", + "param": { + "media_type": "enable capture, if true, you can use capture() function to get an image object", + "timebase": "Time base, used as the unit for calculating playback time. It must be an array containing two parameters,\nin the format [num, den], where the first parameter is the numerator of the time base, and the second parameter is the denominator of the time base.", + "sample_rate": "sampling rate of audio", + "format": "audio format", + "channels": "number of audio channels" + }, + "maixcdk": "maix.video.Context.Context", + "py_doc": "Construct a new Context object\n\nArgs:\n - media_type: enable capture, if true, you can use capture() function to get an image object\n - timebase: Time base, used as the unit for calculating playback time. It must be an array containing two parameters,\nin the format [num, den], where the first parameter is the numerator of the time base, and the second parameter is the denominator of the time base.\n - sample_rate: sampling rate of audio\n - format: audio format\n - channels: number of audio channels\n" + }, + "args": [ + [ + "video::MediaType", + "media_type", + null + ], + [ + "std::vector", + "timebase", + null + ], + [ + "int", + "sample_rate", + null + ], + [ + "audio::Format", + "format", + null + ], + [ + "int", + "channels", + null + ] + ], + "ret_type": null, + "static": false, + "def": "Context(video::MediaType media_type, std::vector timebase, int sample_rate, audio::Format format, int channels)" + } + ] + }, + "audio_sample_rate": { + "type": "func", + "name": "audio_sample_rate", + "doc": { + "brief": "Get sample rate of audio (only valid in the context of audio)", + "return": "sample rate", + "maixpy": "maix.video.Context.audio_sample_rate", + "py_doc": "Get sample rate of audio (only valid in the context of audio)\n\nReturns: sample rate\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int audio_sample_rate()", + "overload": [ + { + "type": "func", + "name": "audio_sample_rate", + "doc": { + "brief": "Get sample rate of audio (only valid in the context of audio)", + "return": "sample rate", + "maixpy": "maix.video.Context.audio_sample_rate", + "py_doc": "Get sample rate of audio (only valid in the context of audio)\n\nReturns: sample rate\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int audio_sample_rate()" + } + ] + }, + "audio_channels": { + "type": "func", + "name": "audio_channels", + "doc": { + "brief": "Get channels of audio (only valid in the context of audio)", + "return": "channels", + "maixpy": "maix.video.Context.audio_channels", + "py_doc": "Get channels of audio (only valid in the context of audio)\n\nReturns: channels\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int audio_channels()", + "overload": [ + { + "type": "func", + "name": "audio_channels", + "doc": { + "brief": "Get channels of audio (only valid in the context of audio)", + "return": "channels", + "maixpy": "maix.video.Context.audio_channels", + "py_doc": "Get channels of audio (only valid in the context of audio)\n\nReturns: channels\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int audio_channels()" + } + ] + }, + "audio_format": { + "type": "func", + "name": "audio_format", + "doc": { + "brief": "Get format of audio (only valid in the context of audio)", + "return": "audio format. @see audio::Format", + "maixpy": "maix.video.Context.audio_format", + "py_doc": "Get format of audio (only valid in the context of audio)\n\nReturns: audio format. @see audio::Format\n" + }, + "args": [], + "ret_type": "audio::Format", + "static": false, + "def": "audio::Format audio_format()", + "overload": [ + { + "type": "func", + "name": "audio_format", + "doc": { + "brief": "Get format of audio (only valid in the context of audio)", + "return": "audio format. @see audio::Format", + "maixpy": "maix.video.Context.audio_format", + "py_doc": "Get format of audio (only valid in the context of audio)\n\nReturns: audio format. @see audio::Format\n" + }, + "args": [], + "ret_type": "audio::Format", + "static": false, + "def": "audio::Format audio_format()" + } + ] + }, + "set_pcm": { + "type": "func", + "name": "set_pcm", + "doc": { + "brief": "Set pcm data (only valid in the context of audio)", + "param": { + "duration": "Duration of the current pcm. unit: timebase", + "pts": "The start time of this pcm playback. If it is 0, it means this parameter is not supported. unit: timebase" + }, + "return": "err::Err", + "maixpy": "maix.video.Context.set_pcm", + "py_doc": "Set pcm data (only valid in the context of audio)\n\nArgs:\n - duration: Duration of the current pcm. unit: timebase\n - pts: The start time of this pcm playback. If it is 0, it means this parameter is not supported. unit: timebase\n\n\nReturns: err::Err\n" + }, + "args": [ + [ + "maix::Bytes *", + "data", + null + ], + [ + "int", + "duration", + "0" + ], + [ + "uint64_t", + "pts", + "0" + ], + [ + "bool", + "copy", + "true" + ] + ], + "ret_type": "err::Err", + "static": false, + "def": "err::Err set_pcm(maix::Bytes *data, int duration = 0, uint64_t pts = 0, bool copy = true)" + }, + "get_pcm": { + "type": "func", + "name": "get_pcm", + "doc": { + "brief": "Get pcm data (only valid in the context of audio)", + "attention": "Note that if you call this interface, you are responsible for releasing the memory of the data, and this interface cannot be called again.", + "return": "Bytes", + "maixpy": "maix.video.Context.get_pcm", + "py_doc": "Get pcm data (only valid in the context of audio)\n\nReturns: Bytes\n" + }, + "args": [], + "ret_type": "Bytes*", + "static": false, + "def": "Bytes *get_pcm()" + }, + "set_image": { + "type": "func", + "name": "set_image", + "doc": { + "brief": "Set image info", + "param": { + "image": "image data", + "duration": "Duration of the current image. unit: timebase", + "pts": "The start time of this image playback. If it is 0, it means this parameter is not supported. unit: timebase", + "last_pts": "The start time of the previous image playback. It can be used to ensure the playback order. If it is 0, it means this parameter is not supported. unit: timebase" + }, + "maixcdk": "maix.video.Context.set_image", + "py_doc": "Set image info\n\nArgs:\n - image: image data\n - duration: Duration of the current image. unit: timebase\n - pts: The start time of this image playback. If it is 0, it means this parameter is not supported. unit: timebase\n - last_pts: The start time of the previous image playback. It can be used to ensure the playback order. If it is 0, it means this parameter is not supported. unit: timebase\n" + }, + "args": [ + [ + "image::Image *", + "image", + null + ], + [ + "int", + "duration", + "0" + ], + [ + "uint64_t", + "pts", + "0" + ], + [ + "uint64_t", + "last_pts", + "0" + ] + ], + "ret_type": "void", + "static": false, + "def": "void set_image(image::Image *image, int duration = 0, uint64_t pts = 0, uint64_t last_pts = 0)" + }, + "set_raw_data": { + "type": "func", + "name": "set_raw_data", + "doc": { + "brief": "Set private data", + "param": { + "data": "private raw data", + "data_size": "private raw data size", + "duration": "Duration of the current image. unit: timebase", + "pts": "The start time of this image playback. If it is 0, it means this parameter is not supported. unit: timebase", + "last_pts": "The start time of the previous image playback. It can be used to ensure the playback order. If it is 0, it means this parameter is not supported. unit: timebase" + }, + "maixcdk": "maix.video.Context.set_raw_data", + "py_doc": "Set private data\n\nArgs:\n - data: private raw data\n - data_size: private raw data size\n - duration: Duration of the current image. unit: timebase\n - pts: The start time of this image playback. If it is 0, it means this parameter is not supported. unit: timebase\n - last_pts: The start time of the previous image playback. It can be used to ensure the playback order. If it is 0, it means this parameter is not supported. unit: timebase\n" + }, + "args": [ + [ + "void *", + "data", + null + ], + [ + "size_t", + "data_size", + null + ], + [ + "int", + "duration", + "0" + ], + [ + "uint64_t", + "pts", + "0" + ], + [ + "uint64_t", + "last_pts", + "0" + ], + [ + "bool", + "copy", + "false" + ] + ], + "ret_type": "void", + "static": false, + "def": "void set_raw_data(void *data, size_t data_size, int duration = 0, uint64_t pts = 0, uint64_t last_pts = 0, bool copy = false)" + }, + "get_raw_data": { + "type": "func", + "name": "get_raw_data", + "doc": { + "brief": "Get private data", + "maixcdk": "maix.video.Context.get_raw_data", + "py_doc": "Get private data" + }, + "args": [], + "ret_type": "void*", + "static": false, + "def": "void *get_raw_data()" + }, + "image": { + "type": "func", + "name": "image", + "doc": { + "brief": "Retrieve the image data to be played.", + "attention": "Note that if you call this interface, you are responsible for releasing the memory of the image, and this interface cannot be called again.", + "maixpy": "maix.video.Context.image", + "py_doc": "Retrieve the image data to be played." + }, + "args": [], + "ret_type": "image::Image*", + "static": false, + "def": "image::Image *image()" + }, + "media_type": { + "type": "func", + "name": "media_type", + "doc": { + "brief": "Get the media type to determine whether it is video, audio, or another media type.", + "maixpy": "maix.video.Context.media_type", + "py_doc": "Get the media type to determine whether it is video, audio, or another media type." + }, + "args": [], + "ret_type": "video::MediaType", + "static": false, + "def": "video::MediaType media_type()" + }, + "pts": { + "type": "func", + "name": "pts", + "doc": { + "brief": "Get the start time of the current playback., in units of time base.", + "maixpy": "maix.video.Context.pts", + "py_doc": "Get the start time of the current playback., in units of time base." + }, + "args": [], + "ret_type": "uint64_t", + "static": false, + "def": "uint64_t pts()" + }, + "last_pts": { + "type": "func", + "name": "last_pts", + "doc": { + "brief": "Get the start time of the previous playback, in units of time base.", + "maixpy": "maix.video.Context.last_pts", + "py_doc": "Get the start time of the previous playback, in units of time base." + }, + "args": [], + "ret_type": "uint64_t", + "static": false, + "def": "uint64_t last_pts()" + }, + "timebase": { + "type": "func", + "name": "timebase", + "doc": { + "brief": "Get the time base.", + "maixpy": "maix.video.Context.timebase", + "py_doc": "Get the time base." + }, + "args": [], + "ret_type": "std::vector", + "static": false, + "def": "std::vector timebase()" + }, + "duration": { + "type": "func", + "name": "duration", + "doc": { + "brief": "Duration of the current frame. unit: timebase", + "maixpy": "maix.video.Context.duration", + "py_doc": "Duration of the current frame. unit: timebase" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int duration()" + }, + "duration_us": { + "type": "func", + "name": "duration_us", + "doc": { + "brief": "Duration of the current frame. unit: us", + "maixpy": "maix.video.Context.duration_us", + "py_doc": "Duration of the current frame. unit: us" + }, + "args": [], + "ret_type": "uint64_t", + "static": false, + "def": "uint64_t duration_us()" + } + }, + "def": "class Context" + }, + "Frame": { + "type": "class", + "name": "Frame", + "doc": { + "brief": "Frame class", + "maixpy": "maix.video.Frame", + "py_doc": "Frame class" + }, + "members": { + "Frame": { + "type": "func", + "name": "Frame", + "doc": { + "brief": "Frame object", + "param": { + "data": "src data pointer, use pointers directly without copying.\nNote: this object will try to free this memory", + "len": "data len", + "pts": "presentation time stamp. unit: time_base", + "dts": "decoding time stamp. unit: time_base", + "duration": "packet display time. unit: time_base (not used)", + "auto_detele": "if true, will delete data when destruct. When copy is true, this arg will be ignore.", + "copy": "data will be copy to new buffer if true, if false, will use data directly,\ndefault true to ensure memory safety." + }, + "maixcdk": "maix.video.Frame.Frame", + "py_doc": "Frame object\n\nArgs:\n - data: src data pointer, use pointers directly without copying.\nNote: this object will try to free this memory\n - len: data len\n - pts: presentation time stamp. unit: time_base\n - dts: decoding time stamp. unit: time_base\n - duration: packet display time. unit: time_base (not used)\n - auto_detele: if true, will delete data when destruct. When copy is true, this arg will be ignore.\n - copy: data will be copy to new buffer if true, if false, will use data directly,\ndefault true to ensure memory safety.\n" + }, + "args": [ + [ + "uint8_t *", + "data", + null + ], + [ + "int", + "len", + null + ], + [ + "uint64_t", + "pts", + "-1" + ], + [ + "uint64_t", + "dts", + "-1" + ], + [ + "int64_t", + "duration", + "0" + ], + [ + "bool", + "auto_detele", + "false" + ], + [ + "bool", + "copy", + "false" + ] + ], + "ret_type": null, + "static": false, + "def": "Frame(uint8_t *data, int len, uint64_t pts = -1, uint64_t dts = -1, int64_t duration = 0, bool auto_detele = false, bool copy = false)", + "overload": [ + { + "type": "func", + "name": "Frame", + "doc": { + "brief": "Frame number (pair of numerator and denominator).", + "maixcdk": "maix.video.Frame.Frame", + "py_doc": "Frame number (pair of numerator and denominator)." + }, + "args": [], + "ret_type": null, + "static": false, + "def": "Frame()" + } + ] + }, + "get": { + "type": "func", + "name": "get", + "doc": { + "brief": "Get raw data of packet", + "param": { + "data": "data pointer", + "len": "data length pointer" + }, + "return": "raw data", + "maixcdk": "maix.video.Frame.get", + "py_doc": "Get raw data of packet\n\nArgs:\n - data: data pointer\n - len: data length pointer\n\n\nReturns: raw data\n" + }, + "args": [ + [ + "void **", + "data", + null + ], + [ + "int *", + "len", + null + ] + ], + "ret_type": "err::Err", + "static": false, + "def": "err::Err get(void **data, int *len)" + }, + "to_bytes": { + "type": "func", + "name": "to_bytes", + "doc": { + "brief": "Get raw data of packet", + "param": { + "copy": "if true, will alloc memory and copy data to new buffer" + }, + "return": "raw data", + "maixpy": "maix.video.Frame.to_bytes", + "py_doc": "Get raw data of packet\n\nArgs:\n - copy: if true, will alloc memory and copy data to new buffer\n\n\nReturns: raw data\n" + }, + "args": [ + [ + "bool", + "copy", + "false" + ] + ], + "ret_type": "Bytes*", + "static": false, + "def": "Bytes *to_bytes(bool copy = false)" + }, + "size": { + "type": "func", + "name": "size", + "doc": { + "brief": "Get raw data size of packet", + "return": "size of raw data", + "maixpy": "maix.video.Frame.size", + "py_doc": "Get raw data size of packet\n\nReturns: size of raw data\n" + }, + "args": [], + "ret_type": "size_t", + "static": false, + "def": "size_t size()" + }, + "is_valid": { + "type": "func", + "name": "is_valid", + "doc": { + "brief": "Check packet is valid", + "return": "true, packet is valid; false, packet is invalid", + "maixpy": "maix.video.Frame.is_valid", + "py_doc": "Check packet is valid\n\nReturns: true, packet is valid; false, packet is invalid\n" + }, + "args": [], + "ret_type": "bool", + "static": false, + "def": "bool is_valid()" + }, + "set_pts": { + "type": "func", + "name": "set_pts", + "doc": { + "brief": "Set pts", + "param": { + "pts": "presentation time stamp. unit: time_base" + }, + "maixpy": "maix.video.Frame.set_pts", + "py_doc": "Set pts\n\nArgs:\n - pts: presentation time stamp. unit: time_base\n" + }, + "args": [ + [ + "uint64_t", + "pts", + null + ] + ], + "ret_type": "void", + "static": false, + "def": "void set_pts(uint64_t pts)" + }, + "set_dts": { + "type": "func", + "name": "set_dts", + "doc": { + "brief": "Set dts", + "param": { + "dts": "decoding time stamp. unit: time_base" + }, + "maixpy": "maix.video.Frame.set_dts", + "py_doc": "Set dts\n\nArgs:\n - dts: decoding time stamp. unit: time_base\n" + }, + "args": [ + [ + "uint64_t", + "dts", + null + ] + ], + "ret_type": "void", + "static": false, + "def": "void set_dts(uint64_t dts)" + }, + "set_duration": { + "type": "func", + "name": "set_duration", + "doc": { + "brief": "Set duration", + "param": { + "duration": "packet display time. unit: time_base" + }, + "maixpy": "maix.video.Frame.set_duration", + "py_doc": "Set duration\n\nArgs:\n - duration: packet display time. unit: time_base\n" + }, + "args": [ + [ + "uint64_t", + "duration", + null + ] + ], + "ret_type": "void", + "static": false, + "def": "void set_duration(uint64_t duration)" + }, + "get_pts": { + "type": "func", + "name": "get_pts", + "doc": { + "brief": "Set pts", + "param": { + "pts": "presentation time stamp. unit: time_base" + }, + "return": "pts value", + "maixpy": "maix.video.Frame.get_pts", + "py_doc": "Set pts\n\nArgs:\n - pts: presentation time stamp. unit: time_base\n\n\nReturns: pts value\n" + }, + "args": [], + "ret_type": "uint64_t", + "static": false, + "def": "uint64_t get_pts()" + }, + "get_dts": { + "type": "func", + "name": "get_dts", + "doc": { + "brief": "Set dts", + "param": { + "dts": "decoding time stamp. unit: time_base" + }, + "return": "dts value", + "maixpy": "maix.video.Frame.get_dts", + "py_doc": "Set dts\n\nArgs:\n - dts: decoding time stamp. unit: time_base\n\n\nReturns: dts value\n" + }, + "args": [], + "ret_type": "uint64_t", + "static": false, + "def": "uint64_t get_dts()" + }, + "get_duration": { + "type": "func", + "name": "get_duration", + "doc": { + "brief": "Get duration", + "return": "duration value", + "maixpy": "maix.video.Frame.get_duration", + "py_doc": "Get duration\n\nReturns: duration value\n" + }, + "args": [], + "ret_type": "uint64_t", + "static": false, + "def": "uint64_t get_duration()" + }, + "type": { + "type": "func", + "name": "type", + "doc": { + "brief": "Get frame type", + "return": "video type. @see video::VideoType", + "maixpy": "maix.video.Frame.type", + "py_doc": "Get frame type\n\nReturns: video type. @see video::VideoType\n" + }, + "args": [], + "ret_type": "video::VideoType", + "static": false, + "def": "video::VideoType type()" + } + }, + "def": "class Frame" + }, + "Packet": { + "type": "class", + "name": "Packet", + "doc": { + "brief": "Packet class", + "maixpy": "maix.video.Packet", + "py_doc": "Packet class" + }, + "members": { + "Packet": { + "type": "func", + "name": "Packet", + "doc": { + "brief": "Packet number (pair of numerator and denominator).", + "param": { + "data": "src data pointer, use pointers directly without copying.\nNote: this object will try to free this memory", + "len": "data len", + "pts": "presentation time stamp. unit: time_base", + "dts": "decoding time stamp. unit: time_base", + "duration": "packet display time. unit: time_base" + }, + "maixpy": "maix.video.Packet.__init__", + "maixcdk": "maix.video.Packet.Packet", + "py_doc": "Packet number (pair of numerator and denominator).\n\nArgs:\n - data: src data pointer, use pointers directly without copying.\nNote: this object will try to free this memory\n - len: data len\n - pts: presentation time stamp. unit: time_base\n - dts: decoding time stamp. unit: time_base\n - duration: packet display time. unit: time_base\n" + }, + "args": [ + [ + "uint8_t *", + "data", + null + ], + [ + "int", + "len", + null + ], + [ + "uint64_t", + "pts", + "-1" + ], + [ + "uint64_t", + "dts", + "-1" + ], + [ + "int64_t", + "duration", + "0" + ] + ], + "ret_type": null, + "static": false, + "def": "Packet(uint8_t *data, int len, uint64_t pts = -1, uint64_t dts = -1, int64_t duration = 0)", + "overload": [ + { + "type": "func", + "name": "Packet", + "doc": { + "brief": "Packet number (pair of numerator and denominator).", + "maixcdk": "maix.video.Packet.Packet", + "py_doc": "Packet number (pair of numerator and denominator)." + }, + "args": [], + "ret_type": null, + "static": false, + "def": "Packet()" + } + ] + }, + "get": { + "type": "func", + "name": "get", + "doc": { + "brief": "Get raw data of packet", + "return": "raw data", + "maixpy": "maix.video.Packet.get", + "py_doc": "Get raw data of packet\n\nReturns: raw data\n" + }, + "args": [], + "ret_type": "std::vector", + "static": false, + "def": "std::vector get()" + }, + "data": { + "type": "func", + "name": "data", + "doc": { + "brief": "Get raw data of packet", + "return": "raw data", + "maixpy": "maix.video.Packet.data", + "py_doc": "Get raw data of packet\n\nReturns: raw data\n" + }, + "args": [], + "ret_type": "uint8_t*", + "static": false, + "def": "uint8_t *data()" + }, + "data_size": { + "type": "func", + "name": "data_size", + "doc": { + "brief": "Get raw data size of packet", + "return": "size of raw data", + "maixpy": "maix.video.Packet.data_size", + "py_doc": "Get raw data size of packet\n\nReturns: size of raw data\n" + }, + "args": [], + "ret_type": "size_t", + "static": false, + "def": "size_t data_size()" + }, + "is_valid": { + "type": "func", + "name": "is_valid", + "doc": { + "brief": "Check packet is valid", + "return": "true, packet is valid; false, packet is invalid", + "maixpy": "maix.video.Packet.is_valid", + "py_doc": "Check packet is valid\n\nReturns: true, packet is valid; false, packet is invalid\n" + }, + "args": [], + "ret_type": "bool", + "static": false, + "def": "bool is_valid()" + }, + "set_pts": { + "type": "func", + "name": "set_pts", + "doc": { + "brief": "Set pts", + "param": { + "pts": "presentation time stamp. unit: time_base" + }, + "return": "true, packet is valid; false, packet is invalid", + "maixpy": "maix.video.Packet.set_pts", + "py_doc": "Set pts\n\nArgs:\n - pts: presentation time stamp. unit: time_base\n\n\nReturns: true, packet is valid; false, packet is invalid\n" + }, + "args": [ + [ + "uint64_t", + "pts", + null + ] + ], + "ret_type": "void", + "static": false, + "def": "void set_pts(uint64_t pts)" + }, + "set_dts": { + "type": "func", + "name": "set_dts", + "doc": { + "brief": "Set dts", + "param": { + "dts": "decoding time stamp. unit: time_base" + }, + "return": "true, packet is valid; false, packet is invalid", + "maixpy": "maix.video.Packet.set_dts", + "py_doc": "Set dts\n\nArgs:\n - dts: decoding time stamp. unit: time_base\n\n\nReturns: true, packet is valid; false, packet is invalid\n" + }, + "args": [ + [ + "uint64_t", + "dts", + null + ] + ], + "ret_type": "void", + "static": false, + "def": "void set_dts(uint64_t dts)" + }, + "set_duration": { + "type": "func", + "name": "set_duration", + "doc": { + "brief": "Set duration", + "param": { + "duration": "packet display time. unit: time_base" + }, + "return": "true, packet is valid; false, packet is invalid", + "maixpy": "maix.video.Packet.set_duration", + "py_doc": "Set duration\n\nArgs:\n - duration: packet display time. unit: time_base\n\n\nReturns: true, packet is valid; false, packet is invalid\n" + }, + "args": [ + [ + "uint64_t", + "duration", + null + ] + ], + "ret_type": "void", + "static": false, + "def": "void set_duration(uint64_t duration)" + } + }, + "def": "class Packet" + }, + "Encoder": { + "type": "class", + "name": "Encoder", + "doc": { + "brief": "Encode class", + "maixpy": "maix.video.Encoder", + "py_doc": "Encode class" + }, + "members": { + "Encoder": { + "type": "func", + "name": "Encoder", + "doc": { + "brief": "Construct a new Video object", + "param": { + "width": "picture width. this value may be set automatically. default is 2560.", + "height": "picture height. this value may be set automatically. default is 1440.", + "format": "picture format. default is image::Format::FMT_YVU420SP. @see image::Format", + "type": "video encode/decode type. default is ENC_H265_CBR. @see EncodeType", + "framerate": "frame rate. framerate default is 30, means 30 frames per second\nfor video. 1/time_base is not the average frame rate if the frame rate is not constant.", + "gop": "for h264/h265 encoding, the interval between two I-frames, default is 50.", + "bitrate": "for h264/h265 encoding, used to limit the bandwidth used by compressed data, default is 3000kbps", + "time_base": "frame time base. time_base default is 1000, means 1/1000 ms (not used)", + "capture": "enable capture, if true, you can use capture() function to get an image object", + "block": "This parameter determines whether encoding should block until it is complete.\nIf set to true, it will wait until encoding is finished before returning.\nIf set to false, it will return the current encoding result on the next call." + }, + "maixpy": "maix.video.Encoder.__init__", + "maixcdk": "maix.video.Encoder.Encoder", + "py_doc": "Construct a new Video object\n\nArgs:\n - width: picture width. this value may be set automatically. default is 2560.\n - height: picture height. this value may be set automatically. default is 1440.\n - format: picture format. default is image::Format::FMT_YVU420SP. @see image::Format\n - type: video encode/decode type. default is ENC_H265_CBR. @see EncodeType\n - framerate: frame rate. framerate default is 30, means 30 frames per second\nfor video. 1/time_base is not the average frame rate if the frame rate is not constant.\n - gop: for h264/h265 encoding, the interval between two I-frames, default is 50.\n - bitrate: for h264/h265 encoding, used to limit the bandwidth used by compressed data, default is 3000kbps\n - time_base: frame time base. time_base default is 1000, means 1/1000 ms (not used)\n - capture: enable capture, if true, you can use capture() function to get an image object\n - block: This parameter determines whether encoding should block until it is complete.\nIf set to true, it will wait until encoding is finished before returning.\nIf set to false, it will return the current encoding result on the next call.\n" + }, + "args": [ + [ + "std::string", + "path", + "\"\"" + ], + [ + "int", + "width", + "2560" + ], + [ + "int", + "height", + "1440" + ], + [ + "image::Format", + "format", + "image::Format::FMT_YVU420SP" + ], + [ + "video::VideoType", + "type", + "video::VideoType::VIDEO_H264" + ], + [ + "int", + "framerate", + "30" + ], + [ + "int", + "gop", + "50" + ], + [ + "int", + "bitrate", + "3000 * 1000" + ], + [ + "int", + "time_base", + "1000" + ], + [ + "bool", + "capture", + "false" + ], + [ + "bool", + "block", + "true" + ] + ], + "ret_type": null, + "static": false, + "def": "Encoder(std::string path = \"\", int width = 2560, int height = 1440, image::Format format = image::Format::FMT_YVU420SP, video::VideoType type = video::VideoType::VIDEO_H264, int framerate = 30, int gop = 50, int bitrate = 3000 * 1000, int time_base = 1000, bool capture = false, bool block = true)" + }, + "bind_camera": { + "type": "func", + "name": "bind_camera", + "doc": { + "brief": "Bind camera", + "param": { + "camera": "camera object" + }, + "return": "error code, err::ERR_NONE means success, others means failed", + "maixpy": "maix.video.Encoder.bind_camera", + "py_doc": "Bind camera\n\nArgs:\n - camera: camera object\n\n\nReturns: error code, err::ERR_NONE means success, others means failed\n" + }, + "args": [ + [ + "camera::Camera *", + "camera", + null + ] + ], + "ret_type": "err::Err", + "static": false, + "def": "err::Err bind_camera(camera::Camera *camera)" + }, + "encode": { + "type": "func", + "name": "encode", + "doc": { + "brief": "Encode image.", + "param": { + "img": "the image will be encode.\nif the img is NULL, this function will try to get image from camera, you must use bind_camera() function to bind the camera.", + "pcm": "the pcm data will be encode." + }, + "return": "encode result", + "maixpy": "maix.video.Encoder.encode", + "py_doc": "Encode image.\n\nArgs:\n - img: the image will be encode.\nif the img is NULL, this function will try to get image from camera, you must use bind_camera() function to bind the camera.\n - pcm: the pcm data will be encode.\n\n\nReturns: encode result\n" + }, + "args": [ + [ + "image::Image *", + "img", + "maix::video::Encoder::NoneImage" + ], + [ + "Bytes *", + "pcm", + "maix::video::Encoder::NoneBytes" + ] + ], + "ret_type": "video::Frame*", + "static": false, + "def": "video::Frame *encode(image::Image *img = maix::video::Encoder::NoneImage, Bytes *pcm = maix::video::Encoder::NoneBytes)" + }, + "capture": { + "type": "func", + "name": "capture", + "doc": { + "brief": "Capture image", + "attention": "Each time encode is called, the last captured image will be released.", + "return": "error code", + "maixpy": "maix.video.Encoder.capture", + "py_doc": "Capture image\n\nReturns: error code\n" + }, + "args": [], + "ret_type": "image::Image*", + "static": false, + "def": "image::Image *capture()" + }, + "width": { + "type": "func", + "name": "width", + "doc": { + "brief": "Get video width", + "return": "video width", + "maixpy": "maix.video.Encoder.width", + "py_doc": "Get video width\n\nReturns: video width\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int width()" + }, + "height": { + "type": "func", + "name": "height", + "doc": { + "brief": "Get video height", + "return": "video height", + "maixpy": "maix.video.Encoder.height", + "py_doc": "Get video height\n\nReturns: video height\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int height()" + }, + "format": { + "type": "func", + "name": "format", + "doc": { + "brief": "Get video format", + "return": "video format", + "maixpy": "maix.video.Encoder.format", + "py_doc": "Get video format\n\nReturns: video format\n" + }, + "args": [], + "ret_type": "image::Format", + "static": false, + "def": "image::Format format()" + }, + "type": { + "type": "func", + "name": "type", + "doc": { + "brief": "Get video encode type", + "return": "VideoType", + "maixpy": "maix.video.Encoder.type", + "py_doc": "Get video encode type\n\nReturns: VideoType\n" + }, + "args": [], + "ret_type": "video::VideoType", + "static": false, + "def": "video::VideoType type()" + }, + "framerate": { + "type": "func", + "name": "framerate", + "doc": { + "brief": "Get video encode framerate", + "return": "frame rate", + "maixpy": "maix.video.Encoder.framerate", + "py_doc": "Get video encode framerate\n\nReturns: frame rate\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int framerate()" + }, + "gop": { + "type": "func", + "name": "gop", + "doc": { + "brief": "Get video encode gop", + "return": "gop value", + "maixpy": "maix.video.Encoder.gop", + "py_doc": "Get video encode gop\n\nReturns: gop value\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int gop()" + }, + "bitrate": { + "type": "func", + "name": "bitrate", + "doc": { + "brief": "Get video encode bitrate", + "return": "bitrate value", + "maixpy": "maix.video.Encoder.bitrate", + "py_doc": "Get video encode bitrate\n\nReturns: bitrate value\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int bitrate()" + }, + "time_base": { + "type": "func", + "name": "time_base", + "doc": { + "brief": "Get video encode time base", + "return": "time base value", + "maixpy": "maix.video.Encoder.time_base", + "py_doc": "Get video encode time base\n\nReturns: time base value\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int time_base()" + }, + "get_pts": { + "type": "func", + "name": "get_pts", + "doc": { + "brief": "Get current pts, unit: time_base\\nNote: The current default is to assume that there is no B-frame implementation, so pts and bts are always the same", + "param": { + "time_ms": "start time from the first frame. unit: ms" + }, + "return": "time base value", + "maixcdk": "maix.video.Encoder.get_pts", + "py_doc": "Get current pts, unit: time_base\nNote: The current default is to assume that there is no B-frame implementation, so pts and bts are always the same\n\nArgs:\n - time_ms: start time from the first frame. unit: ms\n\n\nReturns: time base value\n" + }, + "args": [ + [ + "uint64_t", + "time_ms", + null + ] + ], + "ret_type": "uint64_t", + "static": false, + "def": "uint64_t get_pts(uint64_t time_ms)" + }, + "get_dts": { + "type": "func", + "name": "get_dts", + "doc": { + "brief": "Get current dts, unit: time_base\\nNote: The current default is to assume that there is no B-frame implementation, so pts and bts are always the same", + "param": { + "time_ms": "start time from the first frame. unit: ms" + }, + "return": "time base value", + "maixcdk": "maix.video.Encoder.get_dts", + "py_doc": "Get current dts, unit: time_base\nNote: The current default is to assume that there is no B-frame implementation, so pts and bts are always the same\n\nArgs:\n - time_ms: start time from the first frame. unit: ms\n\n\nReturns: time base value\n" + }, + "args": [ + [ + "uint64_t", + "time_ms", + null + ] + ], + "ret_type": "uint64_t", + "static": false, + "def": "uint64_t get_dts(uint64_t time_ms)" + } + }, + "def": "class Encoder" + }, + "Decoder": { + "type": "class", + "name": "Decoder", + "doc": { + "brief": "Decoder class", + "maixpy": "maix.video.Decoder", + "py_doc": "Decoder class" + }, + "members": { + "Decoder": { + "type": "func", + "name": "Decoder", + "doc": { + "brief": "Construct a new decoder object", + "param": { + "path": "Path to the file to be decoded. Supports files with .264 and .mp4 extensions. Note that only mp4 files containing h.264 streams are supported.", + "format": "Decoded output format, currently only support YUV420SP" + }, + "maixpy": "maix.video.Decoder.__init__", + "maixcdk": "maix.video.Decoder.Decoder", + "py_doc": "Construct a new decoder object\n\nArgs:\n - path: Path to the file to be decoded. Supports files with .264 and .mp4 extensions. Note that only mp4 files containing h.264 streams are supported.\n - format: Decoded output format, currently only support YUV420SP\n" + }, + "args": [ + [ + "std::string", + "path", + null + ], + [ + "image::Format", + "format", + "image::Format::FMT_YVU420SP" + ] + ], + "ret_type": null, + "static": false, + "def": "Decoder(std::string path, image::Format format = image::Format::FMT_YVU420SP)" + }, + "decode_video": { + "type": "func", + "name": "decode_video", + "doc": { + "brief": "Decode the video stream, returning the image of the next frame each time.", + "param": { + "block": "Whether it blocks or not. If true, it will wait for the decoding to complete and return the current frame.\nIf false, it will return the result of the previous frame's decoding. If the previous frame's decoding result is empty,\nit will return an unknown Context, and you can use the media_type method of the Context to determine if a valid result exists.\ndefault is true." + }, + "return": "Decoded context information.", + "maixpy": "maix.video.Decoder.decode_video", + "py_doc": "Decode the video stream, returning the image of the next frame each time.\n\nArgs:\n - block: Whether it blocks or not. If true, it will wait for the decoding to complete and return the current frame.\nIf false, it will return the result of the previous frame's decoding. If the previous frame's decoding result is empty,\nit will return an unknown Context, and you can use the media_type method of the Context to determine if a valid result exists.\ndefault is true.\n\n\nReturns: Decoded context information.\n" + }, + "args": [ + [ + "bool", + "block", + "true" + ] + ], + "ret_type": "video::Context *", + "static": false, + "def": "video::Context * decode_video(bool block = true)" + }, + "decode_audio": { + "type": "func", + "name": "decode_audio", + "doc": { + "brief": "Decode the video stream, returning the image of the next frame each time.", + "return": "Decoded context information.", + "maixpy": "maix.video.Decoder.decode_audio", + "py_doc": "Decode the video stream, returning the image of the next frame each time.\n\nReturns: Decoded context information.\n" + }, + "args": [], + "ret_type": "video::Context *", + "static": false, + "def": "video::Context * decode_audio()" + }, + "decode": { + "type": "func", + "name": "decode", + "doc": { + "brief": "Decode the video and audio stream", + "param": { + "block": "Whether it blocks or not. If true, it will wait for the decoding to complete and return the current frame.\nIf false, it will return the result of the previous frame's decoding. If the previous frame's decoding result is empty,\nit will return an unknown Context, and you can use the media_type method of the Context to determine if a valid result exists.\ndefault is true." + }, + "return": "Decoded context information.", + "maixpy": "maix.video.Decoder.decode", + "py_doc": "Decode the video and audio stream\n\nArgs:\n - block: Whether it blocks or not. If true, it will wait for the decoding to complete and return the current frame.\nIf false, it will return the result of the previous frame's decoding. If the previous frame's decoding result is empty,\nit will return an unknown Context, and you can use the media_type method of the Context to determine if a valid result exists.\ndefault is true.\n\n\nReturns: Decoded context information.\n" + }, + "args": [ + [ + "bool", + "block", + "true" + ] + ], + "ret_type": "video::Context *", + "static": false, + "def": "video::Context * decode(bool block = true)" + }, + "unpack": { + "type": "func", + "name": "unpack", + "doc": { + "brief": "Unpacking the video and audio stream", + "return": "Unpacking context information.", + "maixcdk": "maix.video.Decoder.unpack", + "py_doc": "Unpacking the video and audio stream\n\nReturns: Unpacking context information.\n" + }, + "args": [], + "ret_type": "video::Context *", + "static": false, + "def": "video::Context * unpack()" + }, + "width": { + "type": "func", + "name": "width", + "doc": { + "brief": "Get the video width", + "return": "video width", + "maixpy": "maix.video.Decoder.width", + "py_doc": "Get the video width\n\nReturns: video width\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int width()" + }, + "height": { + "type": "func", + "name": "height", + "doc": { + "brief": "Get the video height", + "return": "video height", + "maixpy": "maix.video.Decoder.height", + "py_doc": "Get the video height\n\nReturns: video height\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int height()" + }, + "bitrate": { + "type": "func", + "name": "bitrate", + "doc": { + "brief": "Get the video bitrate", + "return": "bitrate value", + "maixpy": "maix.video.Decoder.bitrate", + "py_doc": "Get the video bitrate\n\nReturns: bitrate value\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int bitrate()" + }, + "fps": { + "type": "func", + "name": "fps", + "doc": { + "brief": "Get the video fps", + "return": "fps value", + "maixpy": "maix.video.Decoder.fps", + "py_doc": "Get the video fps\n\nReturns: fps value\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int fps()" + }, + "seek": { + "type": "func", + "name": "seek", + "doc": { + "brief": "Seek to the required playback position", + "param": { + "time": "timestamp value, unit: s" + }, + "return": "return the current position, unit: s", + "maixpy": "maix.video.Decoder.seek", + "py_doc": "Seek to the required playback position\n\nArgs:\n - time: timestamp value, unit: s\n\n\nReturns: return the current position, unit: s\n" + }, + "args": [ + [ + "double", + "time", + "-1" + ] + ], + "ret_type": "double", + "static": false, + "def": "double seek(double time = -1)" + }, + "duration": { + "type": "func", + "name": "duration", + "doc": { + "brief": "Get the maximum duration of the video. If it returns 0, it means it cannot be predicted.", + "return": "duration value, unit: s", + "maixpy": "maix.video.Decoder.duration", + "py_doc": "Get the maximum duration of the video. If it returns 0, it means it cannot be predicted.\n\nReturns: duration value, unit: s\n" + }, + "args": [], + "ret_type": "double", + "static": false, + "def": "double duration()" + }, + "timebase": { + "type": "func", + "name": "timebase", + "doc": { + "brief": "Get the time base.", + "maixpy": "maix.video.Decoder.timebase", + "py_doc": "Get the time base." + }, + "args": [], + "ret_type": "std::vector", + "static": false, + "def": "std::vector timebase()" + }, + "has_audio": { + "type": "func", + "name": "has_audio", + "doc": { + "brief": "If find audio data, return true", + "maixpy": "maix.video.Decoder.has_audio", + "py_doc": "If find audio data, return true" + }, + "args": [], + "ret_type": "bool", + "static": false, + "def": "bool has_audio()" + }, + "has_video": { + "type": "func", + "name": "has_video", + "doc": { + "brief": "If find video data, return true", + "maixpy": "maix.video.Decoder.has_video", + "py_doc": "If find video data, return true" + }, + "args": [], + "ret_type": "bool", + "static": false, + "def": "bool has_video()" + } + }, + "def": "class Decoder" + }, + "Video": { + "type": "class", + "name": "Video", + "doc": { + "brief": "Video class", + "maixpy": "maix.video.Video", + "py_doc": "Video class" + }, + "members": { + "Video": { + "type": "func", + "name": "Video", + "doc": { + "brief": "Construct a new Video object", + "param": { + "path": "video path. the path determines the location where you load or save the file, if path is none, the video module will not save or load file.\nxxx.h265 means video format is H265, xxx.mp4 means video format is MP4", + "width": "picture width. this value may be set automatically. default is 2560.", + "height": "picture height. this value may be set automatically. default is 1440.", + "format": "picture pixel format. this value may be set automatically. default is FMT_YVU420SP.", + "time_base": "frame time base. time_base default is 30, means 1/30 ms", + "framerate": "frame rate. framerate default is 30, means 30 frames per second\nfor video. 1/time_base is not the average frame rate if the frame rate is not constant.", + "capture": "enable capture, if true, you can use capture() function to get an image object", + "open": "If true, video will automatically call open() after creation. default is true." + }, + "maixpy": "maix.video.Video.__init__", + "maixcdk": "maix.video.Video.Video", + "py_doc": "Construct a new Video object\n\nArgs:\n - path: video path. the path determines the location where you load or save the file, if path is none, the video module will not save or load file.\nxxx.h265 means video format is H265, xxx.mp4 means video format is MP4\n - width: picture width. this value may be set automatically. default is 2560.\n - height: picture height. this value may be set automatically. default is 1440.\n - format: picture pixel format. this value may be set automatically. default is FMT_YVU420SP.\n - time_base: frame time base. time_base default is 30, means 1/30 ms\n - framerate: frame rate. framerate default is 30, means 30 frames per second\nfor video. 1/time_base is not the average frame rate if the frame rate is not constant.\n - capture: enable capture, if true, you can use capture() function to get an image object\n - open: If true, video will automatically call open() after creation. default is true.\n" + }, + "args": [ + [ + "std::string", + "path", + "std::string()" + ], + [ + "int", + "width", + "2560" + ], + [ + "int", + "height", + "1440" + ], + [ + "image::Format", + "format", + "image::Format::FMT_YVU420SP" + ], + [ + "int", + "time_base", + "30" + ], + [ + "int", + "framerate", + "30" + ], + [ + "bool", + "capture", + "false" + ], + [ + "bool", + "open", + "true" + ] + ], + "ret_type": null, + "static": false, + "def": "Video(std::string path = std::string(), int width = 2560, int height = 1440, image::Format format = image::Format::FMT_YVU420SP, int time_base = 30, int framerate = 30, bool capture = false, bool open = true)" + }, + "open": { + "type": "func", + "name": "open", + "doc": { + "brief": "Open video and run", + "param": { + "path": "video path. the path determines the location where you load or save the file, if path is none, the video module will not save or load file.\nxxx.h265 means video format is H265, xxx.mp4 means video format is MP4", + "fps": "video fps" + }, + "return": "error code, err::ERR_NONE means success, others means failed", + "maixpy": "maix.video.Video.open", + "py_doc": "Open video and run\n\nArgs:\n - path: video path. the path determines the location where you load or save the file, if path is none, the video module will not save or load file.\nxxx.h265 means video format is H265, xxx.mp4 means video format is MP4\n - fps: video fps\n\n\nReturns: error code, err::ERR_NONE means success, others means failed\n" + }, + "args": [ + [ + "std::string", + "path", + "std::string()" + ], + [ + "double", + "fps", + "30.0" + ] + ], + "ret_type": "err::Err", + "static": false, + "def": "err::Err open(std::string path = std::string(), double fps = 30.0)" + }, + "close": { + "type": "func", + "name": "close", + "doc": { + "brief": "Close video", + "maixpy": "maix.video.Video.close", + "py_doc": "Close video" + }, + "args": [], + "ret_type": "void", + "static": false, + "def": "void close()" + }, + "bind_camera": { + "type": "func", + "name": "bind_camera", + "doc": { + "brief": "Bind camera", + "param": { + "camera": "camera object" + }, + "return": "error code, err::ERR_NONE means success, others means failed", + "maixpy": "maix.video.Video.bind_camera", + "py_doc": "Bind camera\n\nArgs:\n - camera: camera object\n\n\nReturns: error code, err::ERR_NONE means success, others means failed\n" + }, + "args": [ + [ + "camera::Camera *", + "camera", + null + ] + ], + "ret_type": "err::Err", + "static": false, + "def": "err::Err bind_camera(camera::Camera *camera)" + }, + "encode": { + "type": "func", + "name": "encode", + "doc": { + "brief": "Encode image.", + "param": { + "img": "the image will be encode.\nif the img is NULL, this function will try to get image from camera, you must use bind_camera() function to bind the camera." + }, + "return": "encode result", + "maixpy": "maix.video.Video.encode", + "py_doc": "Encode image.\n\nArgs:\n - img: the image will be encode.\nif the img is NULL, this function will try to get image from camera, you must use bind_camera() function to bind the camera.\n\n\nReturns: encode result\n" + }, + "args": [ + [ + "image::Image *", + "img", + "maix::video::Video::NoneImage" + ] + ], + "ret_type": "video::Packet*", + "static": false, + "def": "video::Packet *encode(image::Image *img = maix::video::Video::NoneImage)" + }, + "decode": { + "type": "func", + "name": "decode", + "doc": { + "brief": "Decode frame", + "param": { + "frame": "the frame will be decode" + }, + "return": "decode result", + "maixpy": "maix.video.Video.decode", + "py_doc": "Decode frame\n\nArgs:\n - frame: the frame will be decode\n\n\nReturns: decode result\n" + }, + "args": [ + [ + "video::Frame *", + "frame", + "nullptr" + ] + ], + "ret_type": "image::Image*", + "static": false, + "def": "image::Image *decode(video::Frame *frame = nullptr)" + }, + "finish": { + "type": "func", + "name": "finish", + "doc": { + "brief": "Encode or decode finish", + "return": "error code", + "maixpy": "maix.video.Video.finish", + "py_doc": "Encode or decode finish\n\nReturns: error code\n" + }, + "args": [], + "ret_type": "err::Err", + "static": false, + "def": "err::Err finish()" + }, + "capture": { + "type": "func", + "name": "capture", + "doc": { + "brief": "Capture image", + "attention": "Each time encode is called, the last captured image will be released.", + "return": "error code", + "maixpy": "maix.video.Video.capture", + "py_doc": "Capture image\n\nReturns: error code\n" + }, + "args": [], + "ret_type": "image::Image*", + "static": false, + "def": "image::Image *capture()" + }, + "is_recording": { + "type": "func", + "name": "is_recording", + "doc": { + "brief": "Check if video is recording", + "return": "true if video is recording, false if not", + "maixpy": "maix.video.Video.is_recording", + "py_doc": "Check if video is recording\n\nReturns: true if video is recording, false if not\n" + }, + "args": [], + "ret_type": "bool", + "static": false, + "def": "bool is_recording()" + }, + "is_opened": { + "type": "func", + "name": "is_opened", + "doc": { + "brief": "Check if video is opened", + "return": "true if video is opened, false if not", + "maixpy": "maix.video.Video.is_opened", + "py_doc": "Check if video is opened\n\nReturns: true if video is opened, false if not\n" + }, + "args": [], + "ret_type": "bool", + "static": false, + "def": "bool is_opened()" + }, + "is_closed": { + "type": "func", + "name": "is_closed", + "doc": { + "brief": "check video device is closed or not", + "return": "closed or not, bool type", + "maixpy": "maix.video.Video.is_closed", + "py_doc": "check video device is closed or not\n\nReturns: closed or not, bool type\n" + }, + "args": [], + "ret_type": "bool", + "static": false, + "def": "bool is_closed()" + }, + "width": { + "type": "func", + "name": "width", + "doc": { + "brief": "Get video width", + "return": "video width", + "maixpy": "maix.video.Video.width", + "py_doc": "Get video width\n\nReturns: video width\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int width()" + }, + "height": { + "type": "func", + "name": "height", + "doc": { + "brief": "Get video height", + "return": "video height", + "maixpy": "maix.video.Video.height", + "py_doc": "Get video height\n\nReturns: video height\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int height()" + } + }, + "def": "class Video" + }, + "VideoRecorder": { + "type": "class", + "name": "VideoRecorder", + "doc": { + "brief": "Video Recorder class. This module is not fully supported and may be deprecated in the future.", + "maixpy": "maix.video.VideoRecorder", + "py_doc": "Video Recorder class. This module is not fully supported and may be deprecated in the future." + }, + "members": { + "VideoRecorder": { + "type": "func", + "name": "VideoRecorder", + "doc": { + "brief": "Construct a new VideoRecorder object. This is an object that integrates recording, video capturing, and display functions, which can be used to achieve high-resolution video input when needed.", + "param": { + "open": "If true, video will automatically call open() after creation. default is true." + }, + "maixpy": "maix.video.VideoRecorder.__init__", + "maixcdk": "maix.video.VideoRecorder.VideoRecorder", + "py_doc": "Construct a new VideoRecorder object. This is an object that integrates recording, video capturing, and display functions, which can be used to achieve high-resolution video input when needed.\n\nArgs:\n - open: If true, video will automatically call open() after creation. default is true.\n" + }, + "args": [ + [ + "bool", + "open", + "true" + ] + ], + "ret_type": null, + "static": false, + "def": "VideoRecorder(bool open = true)" + }, + "lock": { + "type": "func", + "name": "lock", + "doc": { + "brief": "lock video", + "param": { + "timeout": "timeout in ms. unit:ms" + }, + "return": "error code", + "maixpy": "maix.video.VideoRecorder.lock", + "py_doc": "lock video\n\nArgs:\n - timeout: timeout in ms. unit:ms\n\n\nReturns: error code\n" + }, + "args": [ + [ + "int64_t", + "timeout", + "-1" + ] + ], + "ret_type": "err::Err", + "static": false, + "def": "err::Err lock(int64_t timeout = -1)" + }, + "unlock": { + "type": "func", + "name": "unlock", + "doc": { + "brief": "unlock video", + "return": "error code", + "maixpy": "maix.video.VideoRecorder.unlock", + "py_doc": "unlock video\n\nReturns: error code\n" + }, + "args": [], + "ret_type": "err::Err", + "static": false, + "def": "err::Err unlock()" + }, + "open": { + "type": "func", + "name": "open", + "doc": { + "brief": "Start a thread to handle the input function.", + "return": "error code", + "maixpy": "maix.video.VideoRecorder.open", + "py_doc": "Start a thread to handle the input function.\n\nReturns: error code\n" + }, + "args": [], + "ret_type": "err::Err", + "static": false, + "def": "err::Err open()" + }, + "close": { + "type": "func", + "name": "close", + "doc": { + "brief": "Stop the thread, and reset the object.", + "return": "error code", + "maixpy": "maix.video.VideoRecorder.close", + "py_doc": "Stop the thread, and reset the object.\n\nReturns: error code\n" + }, + "args": [], + "ret_type": "err::Err", + "static": false, + "def": "err::Err close()" + }, + "is_opened": { + "type": "func", + "name": "is_opened", + "doc": { + "brief": "Check whether the object is opened.", + "maixpy": "maix.video.VideoRecorder.is_opened", + "py_doc": "Check whether the object is opened." + }, + "args": [], + "ret_type": "bool", + "static": false, + "def": "bool is_opened()" + }, + "bind_display": { + "type": "func", + "name": "bind_display", + "doc": { + "brief": "Bind a Display object. if this object is not bound, it will not be displayed.", + "param": { + "display": "display object", + "fit": "fit mode. It is recommended to fill in FIT_COVER or FIT_FILL. For maixcam, using FIT_CONTAIN may affect the\nfunctionality of the second layer created by add_channel() in the Display. default is FIT_COVER." + }, + "return": "error code", + "maixpy": "maix.video.VideoRecorder.bind_display", + "py_doc": "Bind a Display object. if this object is not bound, it will not be displayed.\n\nArgs:\n - display: display object\n - fit: fit mode. It is recommended to fill in FIT_COVER or FIT_FILL. For maixcam, using FIT_CONTAIN may affect the\nfunctionality of the second layer created by add_channel() in the Display. default is FIT_COVER.\n\n\nReturns: error code\n" + }, + "args": [ + [ + "display::Display *", + "display", + null + ], + [ + "image::Fit", + "fit", + "image::FIT_COVER" + ] + ], + "ret_type": "err::Err", + "static": false, + "def": "err::Err bind_display(display::Display *display, image::Fit fit = image::FIT_COVER)" + }, + "bind_camera": { + "type": "func", + "name": "bind_camera", + "doc": { + "brief": "Bind a Camera object. if this object is not bound, images cannot be captured.", + "param": { + "camera": "camera object" + }, + "return": "error code", + "maixpy": "maix.video.VideoRecorder.bind_camera", + "py_doc": "Bind a Camera object. if this object is not bound, images cannot be captured.\n\nArgs:\n - camera: camera object\n\n\nReturns: error code\n" + }, + "args": [ + [ + "camera::Camera *", + "camera", + null + ] + ], + "ret_type": "err::Err", + "static": false, + "def": "err::Err bind_camera(camera::Camera *camera)" + }, + "bind_audio": { + "type": "func", + "name": "bind_audio", + "doc": { + "brief": "Bind a AudioRecorder object. if this object is not bound, audio cannot be captured.", + "param": { + "audio": "audio recorder object" + }, + "return": "error code", + "maixpy": "maix.video.VideoRecorder.bind_audio", + "py_doc": "Bind a AudioRecorder object. if this object is not bound, audio cannot be captured.\n\nArgs:\n - audio: audio recorder object\n\n\nReturns: error code\n" + }, + "args": [ + [ + "audio::Recorder *", + "audio", + null + ] + ], + "ret_type": "err::Err", + "static": false, + "def": "err::Err bind_audio(audio::Recorder *audio)" + }, + "bind_imu": { + "type": "func", + "name": "bind_imu", + "doc": { + "brief": "Bind a IMU object. if this object is not bound, imu data cannot be captured.", + "param": { + "imu": "imu object" + }, + "return": "error code", + "maixpy": "maix.video.VideoRecorder.bind_imu", + "py_doc": "Bind a IMU object. if this object is not bound, imu data cannot be captured.\n\nArgs:\n - imu: imu object\n\n\nReturns: error code\n" + }, + "args": [ + [ + "void *", + "imu", + null + ] + ], + "ret_type": "err::Err", + "static": false, + "def": "err::Err bind_imu(void *imu)" + }, + "reset": { + "type": "func", + "name": "reset", + "doc": { + "brief": "Reset the video recorder.", + "note": "It will not reset the bound object; if you have already bound the display using bind_display(), there is no need to rebind the display after calling reset().", + "return": "error code", + "maixpy": "maix.video.VideoRecorder.reset", + "py_doc": "Reset the video recorder.\n\nReturns: error code\n" + }, + "args": [], + "ret_type": "err::Err", + "static": false, + "def": "err::Err reset()" + }, + "config_path": { + "type": "func", + "name": "config_path", + "doc": { + "brief": "The recorded video will be saved to this path, and this API cannot be called during runtime.", + "param": { + "path": "The path of the video file to be saved" + }, + "return": "error code", + "maixpy": "maix.video.VideoRecorder.config_path", + "py_doc": "The recorded video will be saved to this path, and this API cannot be called during runtime.\n\nArgs:\n - path: The path of the video file to be saved\n\n\nReturns: error code\n" + }, + "args": [ + [ + "std::string", + "path", + null + ] + ], + "ret_type": "err::Err", + "static": false, + "def": "err::Err config_path(std::string path)" + }, + "get_path": { + "type": "func", + "name": "get_path", + "doc": { + "brief": "Get the path of the video file to be saved", + "return": "path", + "maixpy": "maix.video.VideoRecorder.get_path", + "py_doc": "Get the path of the video file to be saved\n\nReturns: path\n" + }, + "args": [], + "ret_type": "std::string", + "static": false, + "def": "std::string get_path()" + }, + "config_snapshot": { + "type": "func", + "name": "config_snapshot", + "doc": { + "brief": "Set the snapshot parameters", + "note": "Enabling snapshot functionality may result in some performance loss.", + "param": { + "enable": "enable or disable snapshot", + "resolution": "image resolution of snapshot", + "format": "image format of snapshot" + }, + "return": "error code", + "maixpy": "maix.video.VideoRecorder.config_snapshot", + "py_doc": "Set the snapshot parameters\n\nArgs:\n - enable: enable or disable snapshot\n - resolution: image resolution of snapshot\n - format: image format of snapshot\n\n\nReturns: error code\n" + }, + "args": [ + [ + "bool", + "enable", + null + ], + [ + "std::vector", + "resolution", + "std::vector()" + ], + [ + "image::Format", + "format", + "image::Format::FMT_YVU420SP" + ] + ], + "ret_type": "err::Err", + "static": false, + "def": "err::Err config_snapshot(bool enable, std::vector resolution = std::vector(), image::Format format = image::Format::FMT_YVU420SP)" + }, + "config_resolution": { + "type": "func", + "name": "config_resolution", + "doc": { + "brief": "Set the resolution of the video, and this API cannot be called during runtime.", + "note": "You must bind the camera first, and this interface will modify the camera's resolution. The width must be divisible by 32.", + "param": { + "resolution": "The resolution of the video" + }, + "return": "error code", + "maixpy": "maix.video.VideoRecorder.config_resolution", + "py_doc": "Set the resolution of the video, and this API cannot be called during runtime.\n\nArgs:\n - resolution: The resolution of the video\n\n\nReturns: error code\n" + }, + "args": [ + [ + "std::vector", + "resolution", + null + ] + ], + "ret_type": "err::Err", + "static": false, + "def": "err::Err config_resolution(std::vector resolution)" + }, + "get_resolution": { + "type": "func", + "name": "get_resolution", + "doc": { + "brief": "Get the resolution of the video", + "return": "the resolution of the video", + "maixpy": "maix.video.VideoRecorder.get_resolution", + "py_doc": "Get the resolution of the video\n\nReturns: the resolution of the video\n" + }, + "args": [], + "ret_type": "std::vector", + "static": false, + "def": "std::vector get_resolution()" + }, + "config_fps": { + "type": "func", + "name": "config_fps", + "doc": { + "brief": "Set the fps of the video, and this API cannot be called during runtime.", + "note": "This interface only affect the fps of the encoded file.", + "return": "error code", + "maixpy": "maix.video.VideoRecorder.config_fps", + "py_doc": "Set the fps of the video, and this API cannot be called during runtime.\n\nReturns: error code\n" + }, + "args": [ + [ + "int", + "fps", + null + ] + ], + "ret_type": "err::Err", + "static": false, + "def": "err::Err config_fps(int fps)" + }, + "get_fps": { + "type": "func", + "name": "get_fps", + "doc": { + "brief": "Get the fps of the video.", + "return": "fps value", + "maixpy": "maix.video.VideoRecorder.get_fps", + "py_doc": "Get the fps of the video.\n\nReturns: fps value\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int get_fps()" + }, + "config_bitrate": { + "type": "func", + "name": "config_bitrate", + "doc": { + "brief": "Set the bitrate of the video, and this API cannot be called during runtime.", + "return": "error code", + "maixpy": "maix.video.VideoRecorder.config_bitrate", + "py_doc": "Set the bitrate of the video, and this API cannot be called during runtime.\n\nReturns: error code\n" + }, + "args": [ + [ + "int", + "bitrate", + null + ] + ], + "ret_type": "err::Err", + "static": false, + "def": "err::Err config_bitrate(int bitrate)" + }, + "get_bitrate": { + "type": "func", + "name": "get_bitrate", + "doc": { + "brief": "Get the bitrate of the video.", + "return": "bitrate value", + "maixpy": "maix.video.VideoRecorder.get_bitrate", + "py_doc": "Get the bitrate of the video.\n\nReturns: bitrate value\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int get_bitrate()" + }, + "mute": { + "type": "func", + "name": "mute", + "doc": { + "brief": "Set/Get the mute of the video", + "param": { + "data": "If the parameter is true, mute; if false, unmute; if no parameter is provided, return the mute status." + }, + "return": "error code", + "maixpy": "maix.video.VideoRecorder.mute", + "py_doc": "Set/Get the mute of the video\n\nArgs:\n - data: If the parameter is true, mute; if false, unmute; if no parameter is provided, return the mute status.\n\n\nReturns: error code\n" + }, + "args": [ + [ + "int", + "data", + "-1" + ] + ], + "ret_type": "int", + "static": false, + "def": "int mute(int data = -1)" + }, + "volume": { + "type": "func", + "name": "volume", + "doc": { + "brief": "Set/Get the volume of the video", + "param": { + "data": "The volume of the video, the range is 0-100. if no parameter is provided, return the volume." + }, + "return": "error code", + "maixpy": "maix.video.VideoRecorder.volume", + "py_doc": "Set/Get the volume of the video\n\nArgs:\n - data: The volume of the video, the range is 0-100. if no parameter is provided, return the volume.\n\n\nReturns: error code\n" + }, + "args": [ + [ + "int", + "data", + "-1" + ] + ], + "ret_type": "int", + "static": false, + "def": "int volume(int data = -1)" + }, + "seek": { + "type": "func", + "name": "seek", + "doc": { + "brief": "Get the current position of the video", + "return": "current position, unit: ms", + "maixpy": "maix.video.VideoRecorder.seek", + "py_doc": "Get the current position of the video\n\nReturns: current position, unit: ms\n" + }, + "args": [], + "ret_type": "int64_t", + "static": false, + "def": "int64_t seek()" + }, + "record_start": { + "type": "func", + "name": "record_start", + "doc": { + "brief": "Start recording", + "note": "You must bind the camera at a minimum during input. Additionally,\nif you bind a display, the input image will be shown,\nif you bind a audio, audio will be recorded,\nif you bind a IMU, IMU data will be logged.", + "return": "error code", + "maixpy": "maix.video.VideoRecorder.record_start", + "py_doc": "Start recording\n\nReturns: error code\n" + }, + "args": [], + "ret_type": "err::Err", + "static": false, + "def": "err::Err record_start()" + }, + "snapshot": { + "type": "func", + "name": "snapshot", + "doc": { + "brief": "Take a snapshot", + "return": "image::Image", + "maixpy": "maix.video.VideoRecorder.snapshot", + "py_doc": "Take a snapshot\n\nReturns: image::Image\n" + }, + "args": [], + "ret_type": "image::Image*", + "static": false, + "def": "image::Image *snapshot()" + }, + "record_finish": { + "type": "func", + "name": "record_finish", + "doc": { + "brief": "Stop recording and save the video", + "return": "error code", + "maixpy": "maix.video.VideoRecorder.record_finish", + "py_doc": "Stop recording and save the video\n\nReturns: error code\n" + }, + "args": [], + "ret_type": "err::Err", + "static": false, + "def": "err::Err record_finish()" + }, + "draw_rect": { + "type": "func", + "name": "draw_rect", + "doc": { + "brief": "Draw a rect on the video", + "param": { + "id": "id of the rect, range is [0, 15]", + "x": "x coordinate", + "y": "y coordinate", + "w": "width", + "h": "height", + "color": "color", + "tickness": "The line width of the rectangular box; if set to -1, it indicates that the rectangular box will be filled.", + "hidden": "Hide or show the rectangular box" + }, + "return": "error code", + "maixpy": "maix.video.VideoRecorder.draw_rect", + "py_doc": "Draw a rect on the video\n\nArgs:\n - id: id of the rect, range is [0, 15]\n - x: x coordinate\n - y: y coordinate\n - w: width\n - h: height\n - color: color\n - tickness: The line width of the rectangular box; if set to -1, it indicates that the rectangular box will be filled.\n - hidden: Hide or show the rectangular box\n\n\nReturns: error code\n" + }, + "args": [ + [ + "int", + "id", + null + ], + [ + "int", + "x", + null + ], + [ + "int", + "y", + null + ], + [ + "int", + "w", + null + ], + [ + "int", + "h", + null + ], + [ + "image::Color", + "color", + "image::COLOR_WHITE" + ], + [ + "int", + "thickness", + "-1" + ], + [ + "bool", + "hidden", + "false" + ] + ], + "ret_type": "err::Err", + "static": false, + "def": "err::Err draw_rect(int id, int x, int y, int w, int h, image::Color color = image::COLOR_WHITE, int thickness = -1, bool hidden = false)" + } + }, + "def": "class VideoRecorder" + } + }, + "auto_add": false + }, + "display": { + "type": "module", + "doc": { + "brief": "maix.display module, control display device and show image on it", + "maixpy": "maix.display", + "py_doc": "maix.display module, control display device and show image on it" + }, + "members": { + "Display": { + "type": "class", + "name": "Display", + "doc": { + "brief": "Display class", + "maixpy": "maix.display.Display", + "py_doc": "Display class" + }, + "members": { + "Display": { + "type": "func", + "name": "Display", + "doc": { + "brief": "Construct a new Display object", + "param": { + "width": "display width, by default(value is -1) means auto detect,\nif width > max device supported width, will auto set to max device supported width", + "height": "display height, by default(value is -1) means auto detect,\nif height > max device supported height, will auto set to max device supported height", + "device": "display device name, you can get devices by list_devices method, by default(value is NULL(None in MaixPy)) means the first device", + "open": "If true, display will automatically call open() after creation. default is true." + }, + "maixpy": "maix.display.Display.__init__", + "maixcdk": "maix.display.Display.Display", + "py_doc": "Construct a new Display object\n\nArgs:\n - width: display width, by default(value is -1) means auto detect,\nif width > max device supported width, will auto set to max device supported width\n - height: display height, by default(value is -1) means auto detect,\nif height > max device supported height, will auto set to max device supported height\n - device: display device name, you can get devices by list_devices method, by default(value is NULL(None in MaixPy)) means the first device\n - open: If true, display will automatically call open() after creation. default is true.\n" + }, + "args": [ + [ + "int", + "width", + "-1" + ], + [ + "int", + "height", + "-1" + ], + [ + "image::Format", + "format", + "image::FMT_RGB888" + ], + [ + "const std::string &", + "device", + "\"\"" + ], + [ + "bool", + "open", + "true" + ] + ], + "ret_type": null, + "static": false, + "def": "Display(int width = -1, int height = -1, image::Format format = image::FMT_RGB888, const std::string &device = \"\", bool open = true)", + "overload": [ + { + "type": "func", + "name": "Display", + "doc": { + "brief": "Construct a new Display object.", + "attention": "DisplayBase * parameter need to be set manually, otherwise the operation of this object will be invalid.", + "param": { + "device": "display device path, you can get devices by list_devices method, by default(value is NULL(None in MaixPy)) means the first device", + "base": "basic operation objects.", + "width": "display width, default is -1, means auto, mostly means max width of display support", + "height": "display height, default is -1, means auto, mostly means max height of display support", + "format": "display output format", + "open": "If true, display will automatically call open() after creation. default is true." + }, + "maixcdk": "maix.display.Display.Display", + "py_doc": "Construct a new Display object.\n\nArgs:\n - device: display device path, you can get devices by list_devices method, by default(value is NULL(None in MaixPy)) means the first device\n - base: basic operation objects.\n - width: display width, default is -1, means auto, mostly means max width of display support\n - height: display height, default is -1, means auto, mostly means max height of display support\n - format: display output format\n - open: If true, display will automatically call open() after creation. default is true.\n" + }, + "args": [ + [ + "const std::string &", + "device", + null + ], + [ + "DisplayBase *", + "base", + null + ], + [ + "int", + "width", + "-1" + ], + [ + "int", + "height", + "-1" + ], + [ + "image::Format", + "format", + "image::FMT_INVALID" + ], + [ + "bool", + "open", + "true" + ] + ], + "ret_type": null, + "static": false, + "def": "Display(const std::string &device, DisplayBase *base, int width = -1, int height = -1, image::Format format = image::FMT_INVALID, bool open = true)" + } + ] + }, + "width": { + "type": "func", + "name": "width", + "doc": { + "brief": "Get display width", + "return": "width", + "maixpy": "maix.display.Display.width", + "py_doc": "Get display width\n\nReturns: width\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int width()" + }, + "height": { + "type": "func", + "name": "height", + "doc": { + "brief": "Get display height", + "param": { + "ch": "channel to get, by default(value is 0) means the first channel" + }, + "return": "height", + "maixpy": "maix.display.Display.height", + "py_doc": "Get display height\n\nArgs:\n - ch: channel to get, by default(value is 0) means the first channel\n\n\nReturns: height\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int height()" + }, + "size": { + "type": "func", + "name": "size", + "doc": { + "brief": "Get display size", + "param": { + "ch": "channel to get, by default(value is 0) means the first channel" + }, + "return": "size A list type in MaixPy, [width, height]", + "maixpy": "maix.display.Display.size", + "py_doc": "Get display size\n\nArgs:\n - ch: channel to get, by default(value is 0) means the first channel\n\n\nReturns: size A list type in MaixPy, [width, height]\n" + }, + "args": [], + "ret_type": "std::vector", + "static": false, + "def": "std::vector size()" + }, + "format": { + "type": "func", + "name": "format", + "doc": { + "brief": "Get display format", + "return": "format", + "maixpy": "maix.display.Display.format", + "py_doc": "Get display format\n\nReturns: format\n" + }, + "args": [], + "ret_type": "image::Format", + "static": false, + "def": "image::Format format()" + }, + "open": { + "type": "func", + "name": "open", + "doc": { + "brief": "open display device, if already opened, will return err.ERR_NONE.", + "param": { + "width": "display width, default is -1, means auto, mostly means max width of display support", + "height": "display height, default is -1, means auto, mostly means max height of display support", + "format": "display output format, default is RGB888" + }, + "return": "error code", + "maixpy": "maix.display.Display.open", + "py_doc": "open display device, if already opened, will return err.ERR_NONE.\n\nArgs:\n - width: display width, default is -1, means auto, mostly means max width of display support\n - height: display height, default is -1, means auto, mostly means max height of display support\n - format: display output format, default is RGB888\n\n\nReturns: error code\n" + }, + "args": [ + [ + "int", + "width", + "-1" + ], + [ + "int", + "height", + "-1" + ], + [ + "image::Format", + "format", + "image::FMT_INVALID" + ] + ], + "ret_type": "err::Err", + "static": false, + "def": "err::Err open(int width = -1, int height = -1, image::Format format = image::FMT_INVALID)" + }, + "close": { + "type": "func", + "name": "close", + "doc": { + "brief": "close display device", + "return": "error code", + "maixpy": "maix.display.Display.close", + "py_doc": "close display device\n\nReturns: error code\n" + }, + "args": [], + "ret_type": "err::Err", + "static": false, + "def": "err::Err close()" + }, + "add_channel": { + "type": "func", + "name": "add_channel", + "doc": { + "brief": "Add a new channel and return a new Display object, you can use close() to close this channel.", + "attention": "If a new disp channel is created, it is recommended to set fit=image::FIT_COVER or fit=image::FIT_FILL when running show for the main channel,\notherwise the display of the new disp channel may be abnormal.", + "param": { + "width": "display width, default is -1, means auto, mostly means max width of display support. Maximum width must not exceed the main channel.", + "height": "display height, default is -1, means auto, mostly means max height of display support. Maximum height must not exceed the main channel.", + "format": "display output format, default is FMT_BGRA8888", + "open": "If true, display will automatically call open() after creation. default is true." + }, + "return": "new Display object", + "maixpy": "maix.display.Display.add_channel", + "py_doc": "Add a new channel and return a new Display object, you can use close() to close this channel.\n\nArgs:\n - width: display width, default is -1, means auto, mostly means max width of display support. Maximum width must not exceed the main channel.\n - height: display height, default is -1, means auto, mostly means max height of display support. Maximum height must not exceed the main channel.\n - format: display output format, default is FMT_BGRA8888\n - open: If true, display will automatically call open() after creation. default is true.\n\n\nReturns: new Display object\n" + }, + "args": [ + [ + "int", + "width", + "-1" + ], + [ + "int", + "height", + "-1" + ], + [ + "image::Format", + "format", + "image::FMT_BGRA8888" + ], + [ + "bool", + "open", + "true" + ] + ], + "ret_type": "display::Display*", + "static": false, + "def": "display::Display *add_channel(int width = -1, int height = -1, image::Format format = image::FMT_BGRA8888, bool open = true)" + }, + "is_opened": { + "type": "func", + "name": "is_opened", + "doc": { + "brief": "check display device is opened or not", + "return": "opened or not, bool type", + "maixpy": "maix.display.Display.is_opened", + "py_doc": "check display device is opened or not\n\nReturns: opened or not, bool type\n" + }, + "args": [], + "ret_type": "bool", + "static": false, + "def": "bool is_opened()" + }, + "is_closed": { + "type": "func", + "name": "is_closed", + "doc": { + "brief": "check display device is closed or not", + "return": "closed or not, bool type", + "maixpy": "maix.display.Display.is_closed", + "py_doc": "check display device is closed or not\n\nReturns: closed or not, bool type\n" + }, + "args": [], + "ret_type": "bool", + "static": false, + "def": "bool is_closed()" + }, + "show": { + "type": "func", + "name": "show", + "doc": { + "brief": "show image on display device, and will also send to MaixVision work station if connected.", + "param": { + "img": "image to show, image.Image object,\nif the size of image smaller than display size, will show in the center of display;\nif the size of image bigger than display size, will auto resize to display size and keep ratio, fill blank with black color.", + "fit": "image in screen fit mode, by default(value is image.FIT_CONTAIN), @see image.Fit for more details\ne.g. image.FIT_CONTAIN means resize image to fit display size and keep ratio, fill blank with black color." + }, + "return": "error code", + "maixpy": "maix.display.Display.show", + "py_doc": "show image on display device, and will also send to MaixVision work station if connected.\n\nArgs:\n - img: image to show, image.Image object,\nif the size of image smaller than display size, will show in the center of display;\nif the size of image bigger than display size, will auto resize to display size and keep ratio, fill blank with black color.\n - fit: image in screen fit mode, by default(value is image.FIT_CONTAIN), @see image.Fit for more details\ne.g. image.FIT_CONTAIN means resize image to fit display size and keep ratio, fill blank with black color.\n\n\nReturns: error code\n" + }, + "args": [ + [ + "image::Image &", + "img", + null + ], + [ + "image::Fit", + "fit", + "image::FIT_CONTAIN" + ] + ], + "ret_type": "err::Err", + "static": false, + "def": "err::Err show(image::Image &img, image::Fit fit = image::FIT_CONTAIN)" + }, + "device": { + "type": "func", + "name": "device", + "doc": { + "brief": "Get display device path", + "return": "display device path", + "maixpy": "maix.display.Display.device", + "py_doc": "Get display device path\n\nReturns: display device path\n" + }, + "args": [], + "ret_type": "std::string", + "static": false, + "def": "std::string device()" + }, + "set_backlight": { + "type": "func", + "name": "set_backlight", + "doc": { + "brief": "Set display backlight", + "param": { + "value": "backlight value, float type, range is [0, 100]" + }, + "maixpy": "maix.display.Display.set_backlight", + "py_doc": "Set display backlight\n\nArgs:\n - value: backlight value, float type, range is [0, 100]\n" + }, + "args": [ + [ + "float", + "value", + null + ] + ], + "ret_type": "void", + "static": false, + "def": "void set_backlight(float value)" + }, + "get_backlight": { + "type": "func", + "name": "get_backlight", + "doc": { + "brief": "Get display backlight", + "return": "value backlight value, float type, range is [0, 100]", + "maixpy": "maix.display.Display.get_backlight", + "py_doc": "Get display backlight\n\nReturns: value backlight value, float type, range is [0, 100]\n" + }, + "args": [], + "ret_type": "float", + "static": false, + "def": "float get_backlight()" + }, + "set_hmirror": { + "type": "func", + "name": "set_hmirror", + "doc": { + "brief": "Set display mirror", + "param": { + "en": "enable/disable mirror" + }, + "maixpy": "maix.display.Display.set_hmirror", + "py_doc": "Set display mirror\n\nArgs:\n - en: enable/disable mirror\n" + }, + "args": [ + [ + "bool", + "en", + null + ] + ], + "ret_type": "err::Err", + "static": false, + "def": "err::Err set_hmirror(bool en)" + }, + "set_vflip": { + "type": "func", + "name": "set_vflip", + "doc": { + "brief": "Set display flip", + "param": { + "en": "enable/disable flip" + }, + "maixpy": "maix.display.Display.set_vflip", + "py_doc": "Set display flip\n\nArgs:\n - en: enable/disable flip\n" + }, + "args": [ + [ + "bool", + "en", + null + ] + ], + "ret_type": "err::Err", + "static": false, + "def": "err::Err set_vflip(bool en)" + } + }, + "def": "class Display" + }, + "send_to_maixvision": { + "type": "func", + "name": "send_to_maixvision", + "doc": { + "brief": "Send image to MaixVision work station if connected.\\nIf you want to debug your program an don't want to initialize display, use this method.", + "param": { + "img": "image to send, image.Image object" + }, + "maixpy": "maix.display.send_to_maixvision", + "py_doc": "Send image to MaixVision work station if connected.\nIf you want to debug your program an don't want to initialize display, use this method.\n\nArgs:\n - img: image to send, image.Image object\n" + }, + "args": [ + [ + "image::Image &", + "img", + null + ] + ], + "ret_type": "void", + "static": false, + "def": "void send_to_maixvision(image::Image &img)" + }, + "set_trans_image_quality": { + "type": "func", + "name": "set_trans_image_quality", + "doc": { + "brief": "Set image transport quality(only for JPEG)", + "param": { + "quality": "default 95, value from 51 ~ 100" + }, + "maixpy": "maix.display.set_trans_image_quality", + "py_doc": "Set image transport quality(only for JPEG)\n\nArgs:\n - quality: default 95, value from 51 ~ 100\n" + }, + "args": [ + [ + "const int", + "value", + null + ] + ], + "ret_type": "void", + "static": false, + "def": "void set_trans_image_quality(const int value)" + } + }, + "auto_add": false + }, + "uvc": { + "type": "module", + "doc": { + "brief": "maix.uvc module" + }, + "members": { + "get_supported_formats": { + "type": "func", + "name": "get_supported_formats", + "doc": { + "brief": "get_supported_formats function", + "maixpy": "maix.uvc.get_supported_formats", + "py_doc": "get_supported_formats function" + }, + "args": [], + "ret_type": "std::vector", + "static": false, + "def": "std::vector get_supported_formats()" + }, + "UvcStreamer": { + "type": "class", + "name": "UvcStreamer", + "doc": { + "brief": "UvcStreamer class", + "maixpy": "maix.uvc.UvcStreamer", + "py_doc": "UvcStreamer class" + }, + "members": { + "UvcStreamer": { + "type": "func", + "name": "UvcStreamer", + "doc": { + "brief": "Construct a new jpeg streamer object", + "note": "You can get the picture stream through http://host:port/stream, you can also get it through http://ip:port, and you can add personal style through set_html() at this time", + "param": { + "host": "http host", + "port": "http port, default is 8000", + "client_number": "the max number of client" + }, + "maixpy": "maix.uvc.UvcStreamer.__init__", + "maixcdk": "maix.uvc.UvcStreamer.UvcStreamer", + "py_doc": "Construct a new jpeg streamer object\n\nArgs:\n - host: http host\n - port: http port, default is 8000\n - client_number: the max number of client\n" + }, + "args": [ + [ + "unsigned ", + "index", + "0" + ] + ], + "ret_type": null, + "static": false, + "def": "UvcStreamer(unsigned index=0)" + }, + "show": { + "type": "func", + "name": "show", + "doc": { + "brief": "Write data to uvc", + "param": { + "img": "image object" + }, + "return": "error code, err::ERR_NONE means success, others means failed", + "maixpy": "maix.uvc.UvcStreamer.show", + "py_doc": "Write data to uvc\n\nArgs:\n - img: image object\n\n\nReturns: error code, err::ERR_NONE means success, others means failed\n" + }, + "args": [ + [ + "image::Image *", + "img", + null + ] + ], + "ret_type": "err::Err", + "static": false, + "def": "err::Err show(image::Image *img)" + }, + "use_mjpg": { + "type": "func", + "name": "use_mjpg", + "doc": { + "brief": "use mjpg on uvc", + "param": { + "b": "using mjpg: 0 for NOT, others to use" + }, + "return": "void", + "maixpy": "maix.uvc.UvcStreamer.use_mjpg", + "py_doc": "use mjpg on uvc\n\nArgs:\n - b: using mjpg: 0 for NOT, others to use\n\n\nReturns: void\n" + }, + "args": [ + [ + "uint32_t", + "b", + "1" + ] + ], + "ret_type": "void", + "static": false, + "def": "void use_mjpg(uint32_t b=1)" + } + }, + "def": "class UvcStreamer" + } + }, + "auto_add": true + }, + "network": { + "type": "module", + "doc": { + "brief": "maix.network module" + }, + "members": { + "have_network": { + "type": "func", + "name": "have_network", + "doc": { + "brief": "Return if device have network(WiFi/Eth etc.)", + "return": "True if have network, else False.", + "maixpy": "maix.network.have_network", + "py_doc": "Return if device have network(WiFi/Eth etc.)\n\nReturns: True if have network, else False.\n" + }, + "args": [], + "ret_type": "bool", + "static": false, + "def": "bool have_network()" + }, + "wifi": { + "type": "module", + "doc": { + "brief": "maix.network.wifi module" + }, + "members": { + "AP_Info": { + "type": "class", + "name": "AP_Info", + "doc": { + "brief": "WiFi AP info", + "maixpy": "maix.network.wifi.AP_Info", + "py_doc": "WiFi AP info" + }, + "members": { + "ssid": { + "type": "var", + "name": "ssid", + "doc": { + "brief": "WiFi AP info SSID", + "maixpy": "maix.network.wifi.AP_Info.ssid", + "py_doc": "WiFi AP info SSID" + }, + "value": null, + "static": false, + "readonly": false, + "def": "std::vector ssid" + }, + "bssid": { + "type": "var", + "name": "bssid", + "doc": { + "brief": "WiFi AP info BSSID", + "maixpy": "maix.network.wifi.AP_Info.bssid", + "py_doc": "WiFi AP info BSSID" + }, + "value": null, + "static": false, + "readonly": false, + "def": "std::string bssid" + }, + "security": { + "type": "var", + "name": "security", + "doc": { + "brief": "WiFi AP info security", + "maixpy": "maix.network.wifi.AP_Info.security", + "py_doc": "WiFi AP info security" + }, + "value": null, + "static": false, + "readonly": false, + "def": "std::string security" + }, + "channel": { + "type": "var", + "name": "channel", + "doc": { + "brief": "WiFi AP info channel", + "maixpy": "maix.network.wifi.AP_Info.channel", + "py_doc": "WiFi AP info channel" + }, + "value": null, + "static": false, + "readonly": false, + "def": "int channel" + }, + "frequency": { + "type": "var", + "name": "frequency", + "doc": { + "brief": "WiFi AP info frequency", + "maixpy": "maix.network.wifi.AP_Info.frequency", + "py_doc": "WiFi AP info frequency" + }, + "value": null, + "static": false, + "readonly": false, + "def": "int frequency" + }, + "rssi": { + "type": "var", + "name": "rssi", + "doc": { + "brief": "WiFi AP info rssi", + "maixpy": "maix.network.wifi.AP_Info.rssi", + "py_doc": "WiFi AP info rssi" + }, + "value": null, + "static": false, + "readonly": false, + "def": "int rssi" + }, + "ssid_str": { + "type": "func", + "name": "ssid_str", + "doc": { + "brief": "WiFi AP info ssid_str", + "maixpy": "maix.network.wifi.AP_Info.ssid_str", + "py_doc": "WiFi AP info ssid_str" + }, + "args": [], + "ret_type": "std::string", + "static": false, + "def": "std::string ssid_str()" + } + }, + "def": "class AP_Info" + }, + "list_devices": { + "type": "func", + "name": "list_devices", + "doc": { + "brief": "List WiFi interfaces", + "return": "WiFi interface list, string type", + "maixpy": "maix.network.wifi.list_devices", + "py_doc": "List WiFi interfaces\n\nReturns: WiFi interface list, string type\n" + }, + "args": [], + "ret_type": "std::vector", + "static": false, + "def": "std::vector list_devices()" + }, + "Wifi": { + "type": "class", + "name": "Wifi", + "doc": { + "brief": "Wifi class", + "maixpy": "maix.network.wifi.Wifi", + "py_doc": "Wifi class" + }, + "members": { + "Wifi": { + "type": "func", + "name": "Wifi", + "doc": { + "brief": "Wifi class", + "param": { + "iface": "wifi interface name, default is wlan0" + }, + "maixpy": "maix.network.wifi.Wifi.__init__", + "maixcdk": "maix.network.wifi.Wifi.Wifi", + "py_doc": "Wifi class\n\nArgs:\n - iface: wifi interface name, default is wlan0\n" + }, + "args": [ + [ + "std::string", + "iface", + "\"wlan0\"" + ] + ], + "ret_type": null, + "static": false, + "def": "Wifi(std::string iface = \"wlan0\")" + }, + "get_ip": { + "type": "func", + "name": "get_ip", + "doc": { + "brief": "Get current WiFi ip", + "return": "ip, string type, if network not connected, will return empty string.", + "maixpy": "maix.network.wifi.Wifi.get_ip", + "py_doc": "Get current WiFi ip\n\nReturns: ip, string type, if network not connected, will return empty string.\n" + }, + "args": [], + "ret_type": "std::string", + "static": false, + "def": "std::string get_ip()" + }, + "get_mac": { + "type": "func", + "name": "get_mac", + "doc": { + "brief": "Get current WiFi MAC address", + "return": "ip, string type.", + "maixpy": "maix.network.wifi.Wifi.get_mac", + "py_doc": "Get current WiFi MAC address\n\nReturns: ip, string type.\n" + }, + "args": [], + "ret_type": "std::string", + "static": false, + "def": "std::string get_mac()" + }, + "get_ssid": { + "type": "func", + "name": "get_ssid", + "doc": { + "brief": "Get current WiFi SSID", + "param": { + "from_cache": "if true, will not read config from file, direct use ssid in cache.\nattention, first time call this method will auto matically read config from file, and if call connect method will set cache." + }, + "return": "SSID, string type.", + "maixpy": "maix.network.wifi.Wifi.get_ssid", + "py_doc": "Get current WiFi SSID\n\nArgs:\n - from_cache: if true, will not read config from file, direct use ssid in cache.\nattention, first time call this method will auto matically read config from file, and if call connect method will set cache.\n\n\nReturns: SSID, string type.\n" + }, + "args": [ + [ + "bool", + "from_cache", + "true" + ] + ], + "ret_type": "std::string", + "static": false, + "def": "std::string get_ssid(bool from_cache = true)" + }, + "get_gateway": { + "type": "func", + "name": "get_gateway", + "doc": { + "brief": "Get current WiFi ip", + "return": "ip, string type, if network not connected, will return empty string.", + "maixpy": "maix.network.wifi.Wifi.get_gateway", + "py_doc": "Get current WiFi ip\n\nReturns: ip, string type, if network not connected, will return empty string.\n" + }, + "args": [], + "ret_type": "std::string", + "static": false, + "def": "std::string get_gateway()" + }, + "start_scan": { + "type": "func", + "name": "start_scan", + "doc": { + "brief": "WiFi start scan AP info around in background.", + "return": "If success, return err.Err.ERR_NONE, else means failed.", + "maixpy": "maix.network.wifi.Wifi.start_scan", + "py_doc": "WiFi start scan AP info around in background.\n\nReturns: If success, return err.Err.ERR_NONE, else means failed.\n" + }, + "args": [], + "ret_type": "err::Err", + "static": false, + "def": "err::Err start_scan()" + }, + "get_scan_result": { + "type": "func", + "name": "get_scan_result", + "doc": { + "brief": "Get WiFi scan AP info.", + "return": "wifi.AP_Info list.", + "maixpy": "maix.network.wifi.Wifi.get_scan_result", + "py_doc": "Get WiFi scan AP info.\n\nReturns: wifi.AP_Info list.\n" + }, + "args": [], + "ret_type": "std::vector", + "static": false, + "def": "std::vector get_scan_result()" + }, + "stop_scan": { + "type": "func", + "name": "stop_scan", + "doc": { + "brief": "Stop WiFi scan AP info.", + "maixpy": "maix.network.wifi.Wifi.stop_scan", + "py_doc": "Stop WiFi scan AP info." + }, + "args": [], + "ret_type": "void", + "static": false, + "def": "void stop_scan()" + }, + "connect": { + "type": "func", + "name": "connect", + "doc": { + "brief": "Connect to WiFi AP.", + "param": { + "ssid": "SSID of AP", + "password": "password of AP, if no password, leave it empty.", + "wait": "wait for got IP or failed or timeout.", + "timeout": "connect timeout internal, unit second." + }, + "return": "If success, return err.Err.ERR_NONE, else means failed.", + "maixpy": "maix.network.wifi.Wifi.connect", + "py_doc": "Connect to WiFi AP.\n\nArgs:\n - ssid: SSID of AP\n - password: password of AP, if no password, leave it empty.\n - wait: wait for got IP or failed or timeout.\n - timeout: connect timeout internal, unit second.\n\n\nReturns: If success, return err.Err.ERR_NONE, else means failed.\n" + }, + "args": [ + [ + "const std::string &", + "ssid", + null + ], + [ + "const std::string &", + "password", + null + ], + [ + "bool", + "wait", + "true" + ], + [ + "int", + "timeout", + "60" + ] + ], + "ret_type": "err::Err", + "static": false, + "def": "err::Err connect(const std::string &ssid, const std::string &password, bool wait = true, int timeout = 60)" + }, + "disconnect": { + "type": "func", + "name": "disconnect", + "doc": { + "brief": "Disconnect from WiFi AP.", + "return": "If success, return err.Err.ERR_NONE, else means failed.", + "maixpy": "maix.network.wifi.Wifi.disconnect", + "py_doc": "Disconnect from WiFi AP.\n\nReturns: If success, return err.Err.ERR_NONE, else means failed.\n" + }, + "args": [], + "ret_type": "err::Err", + "static": false, + "def": "err::Err disconnect()" + }, + "is_connected": { + "type": "func", + "name": "is_connected", + "doc": { + "brief": "See if WiFi is connected to AP.", + "return": "If connected return true, else false.", + "maixpy": "maix.network.wifi.Wifi.is_connected", + "py_doc": "See if WiFi is connected to AP.\n\nReturns: If connected return true, else false.\n" + }, + "args": [], + "ret_type": "bool", + "static": false, + "def": "bool is_connected()" + }, + "start_ap": { + "type": "func", + "name": "start_ap", + "doc": { + "brief": "Start WiFi AP.", + "param": { + "ssid": "SSID of AP.", + "password": "password of AP, if no password, leave it empty.", + "ip": "ip address of hostap, default empty string means auto generated one according to hardware.", + "netmask": "netmask, default 255.255.255.0, now only support 255.255.255.0 .", + "mode": "WiFi mode, default g(IEEE 802.11g (2.4 GHz)), a = IEEE 802.11a (5 GHz), b = IEEE 802.11b (2.4 GHz).", + "channel": "WiFi channel number, 0 means auto select. MaixCAM not support auto, will default channel 1.", + "hidden": "hidden SSID or not." + }, + "return": "If success, return err.Err.ERR_NONE, else means failed.", + "maixpy": "maix.network.wifi.Wifi.start_ap", + "py_doc": "Start WiFi AP.\n\nArgs:\n - ssid: SSID of AP.\n - password: password of AP, if no password, leave it empty.\n - ip: ip address of hostap, default empty string means auto generated one according to hardware.\n - netmask: netmask, default 255.255.255.0, now only support 255.255.255.0 .\n - mode: WiFi mode, default g(IEEE 802.11g (2.4 GHz)), a = IEEE 802.11a (5 GHz), b = IEEE 802.11b (2.4 GHz).\n - channel: WiFi channel number, 0 means auto select. MaixCAM not support auto, will default channel 1.\n - hidden: hidden SSID or not.\n\n\nReturns: If success, return err.Err.ERR_NONE, else means failed.\n" + }, + "args": [ + [ + "const std::string &", + "ssid", + null + ], + [ + "const std::string &", + "password", + null + ], + [ + "std::string", + "mode", + "\"g\"" + ], + [ + "int", + "channel", + "0" + ], + [ + "const std::string &", + "ip", + "\"192.168.66.1\"" + ], + [ + "const std::string &", + "netmask", + "\"255.255.255.0\"" + ], + [ + "bool", + "hidden", + "false" + ] + ], + "ret_type": "err::Err", + "static": false, + "def": "err::Err start_ap(const std::string &ssid, const std::string &password,\n std::string mode = \"g\", int channel = 0,\n const std::string &ip = \"192.168.66.1\", const std::string &netmask = \"255.255.255.0\",\n bool hidden = false)" + }, + "stop_ap": { + "type": "func", + "name": "stop_ap", + "doc": { + "brief": "Stop WiFi AP.", + "return": "If success, return err.Err.ERR_NONE, else means failed.", + "maixpy": "maix.network.wifi.Wifi.stop_ap", + "py_doc": "Stop WiFi AP.\n\nReturns: If success, return err.Err.ERR_NONE, else means failed.\n" + }, + "args": [], + "ret_type": "err::Err", + "static": false, + "def": "err::Err stop_ap()" + }, + "is_ap_mode": { + "type": "func", + "name": "is_ap_mode", + "doc": { + "brief": "Whether WiFi is AP mode", + "return": "True if AP mode now, or False.", + "maixpy": "maix.network.wifi.Wifi.is_ap_mode", + "py_doc": "Whether WiFi is AP mode\n\nReturns: True if AP mode now, or False.\n" + }, + "args": [], + "ret_type": "bool", + "static": false, + "def": "bool is_ap_mode()" + } + }, + "def": "class Wifi" + } + }, + "auto_add": true + } + }, + "auto_add": true + }, + "comm": { + "type": "module", + "doc": { + "brief": "maix.comm module" + }, + "members": { + "modbus": { + "type": "module", + "doc": { + "brief": "maix.comm.modbus module" + }, + "members": { + "Mode": { + "type": "enum", + "name": "class", + "doc": { + "brief": "modbus mode", + "maixpy": "maix.comm.modbus.Mode", + "py_doc": "modbus mode" + }, + "values": [ + [ + "RTU", + "", + "" + ], + [ + "TCP", + "", + "" + ] + ], + "def": "enum class Mode : unsigned char {\n RTU,\n TCP\n }" + }, + "RequestType": { + "type": "enum", + "name": "class", + "doc": { + "brief": "Modbus request types enumeration.\\nThis enumeration defines the various Modbus request types,\\nincluding functions for reading and writing coils, registers,\\nas well as diagnostics and identification.", + "maixpy": "maix.comm.modbus.RequestType", + "py_doc": "Modbus request types enumeration.\nThis enumeration defines the various Modbus request types,\nincluding functions for reading and writing coils, registers,\nas well as diagnostics and identification." + }, + "values": [ + [ + "READ_COILS", + "0x01", + "< Read Coils" + ], + [ + "READ_DISCRETE_INPUTS", + "0x02", + "< Read Discrete Inputs" + ], + [ + "READ_HOLDING_REGISTERS", + "0x03", + "< Read Holding Registers" + ], + [ + "READ_INPUT_REGISTERS", + "0x04", + "< Read Input Registers" + ], + [ + "WRITE_SINGLE_COIL", + "0x05", + "< Write Single Coil" + ], + [ + "WRITE_SINGLE_REGISTER", + "0x06", + "< Write Single Register" + ], + [ + "DIAGNOSTICS", + "0x08", + "< Diagnostics (Serial Line only)" + ], + [ + "GET_COMM_EVENT_COUNTER", + "0x0B", + "< Get Comm Event Counter (Serial Line only)" + ], + [ + "WRITE_MULTIPLE_COILS", + "0x0F", + "< Write Multiple Coils" + ], + [ + "WRITE_MULTIPLE_REGISTERS", + "0x10", + "< Write Multiple Registers" + ], + [ + "REPORT_SERVER_ID", + "0x11", + "< Report Slave ID (Serial Line only)" + ], + [ + "MASK_WRITE_REGISTER", + "0x16", + "< Mask Write Register" + ], + [ + "READ_WRITE_MULTIPLE_REGISTERS", + "0x17", + "< Read/Write Multiple Registers" + ], + [ + "READ_DEVICE_IDENTIFICATION", + "0x2B", + "< Read Device Identification" + ], + [ + "UNKNOWN", + "0xFF", + "< Unknown Request Type" + ] + ], + "def": "enum class RequestType : unsigned char {\n READ_COILS = 0x01, ///< Read Coils\n READ_DISCRETE_INPUTS = 0x02, ///< Read Discrete Inputs\n READ_HOLDING_REGISTERS = 0x03, ///< Read Holding Registers\n READ_INPUT_REGISTERS = 0x04, ///< Read Input Registers\n WRITE_SINGLE_COIL = 0x05, ///< Write Single Coil\n WRITE_SINGLE_REGISTER = 0x06, ///< Write Single Register\n DIAGNOSTICS = 0x08, ///< Diagnostics (Serial Line only)\n GET_COMM_EVENT_COUNTER = 0x0B, ///< Get Comm Event Counter (Serial Line only)\n WRITE_MULTIPLE_COILS = 0x0F, ///< Write Multiple Coils\n WRITE_MULTIPLE_REGISTERS = 0x10, ///< Write Multiple Registers\n REPORT_SERVER_ID = 0x11, ///< Report Slave ID (Serial Line only)\n MASK_WRITE_REGISTER = 0x16, ///< Mask Write Register\n READ_WRITE_MULTIPLE_REGISTERS = 0x17, ///< Read/Write Multiple Registers\n READ_DEVICE_IDENTIFICATION = 0x2B, ///< Read Device Identification\n UNKNOWN = 0xFF ///< Unknown Request Type\n }" + }, + "RegisterInfo": { + "type": "class", + "name": "RegisterInfo", + "doc": { + "brief": "Structure to hold information about a Modbus register.\\nThis structure contains the starting address and size of a Modbus register,\\nallowing for easy management of register information.", + "maixcdk": "maix.comm.modbus.RegisterInfo", + "py_doc": "Structure to hold information about a Modbus register.\nThis structure contains the starting address and size of a Modbus register,\nallowing for easy management of register information." + }, + "members": {}, + "def": "struct RegisterInfo" + }, + "Registers": { + "type": "class", + "name": "Registers", + "doc": { + "brief": "Structure to hold information about multiple Modbus registers.\\nThis structure aggregates information for various types of Modbus registers,\\nincluding coils, discrete inputs, holding registers, and input registers.", + "maixcdk": "maix.comm.modbus.Registers", + "py_doc": "Structure to hold information about multiple Modbus registers.\nThis structure aggregates information for various types of Modbus registers,\nincluding coils, discrete inputs, holding registers, and input registers." + }, + "members": {}, + "def": "struct Registers" + }, + "Slave": { + "type": "class", + "name": "Slave", + "doc": { + "brief": "Class for modbus Slave", + "maixpy": "maix.comm.modbus.Slave", + "py_doc": "Class for modbus Slave" + }, + "members": { + "__init__": { + "type": "func", + "name": "Slave", + "doc": { + "brief": "Modbus Slave constructor.\\nThis constructor initializes a Modbus Slave instance. Depending on the mode (RTU or TCP),\\nit sets up the necessary parameters for communication and defines the register structure.", + "param": { + "mode": "Specifies the communication mode: RTU or TCP.", + "ip_or_device": "The UART device name if using RTU mode.\nIf TCP mode is selected, this parameter is ignored.", + "coils_start": "The starting address of the coils register.", + "coils_size": "The number of coils to manage.", + "discrete_start": "The starting address of the discrete inputs register.", + "discrete_size": "The number of discrete inputs to manage.", + "holding_start": "The starting address of the holding registers.", + "holding_size": "The number of holding registers to manage.", + "input_start": "The starting address of the input registers.", + "input_size": "The number of input registers to manage.", + "rtu_baud": "The baud rate for RTU communication.\nSupported rates include: 110, 300, 600, 1200, 2400, 4800,\n9600, 19200, 38400, 57600, 115200, 230400, 460800,\n500000, 576000, 921600, 1000000, 1152000, 1500000,\n2500000, 3000000, 3500000, 4000000.\nDefault is 115200. Ensure that the selected baud rate\nis supported by the underlying hardware and libmodbus.", + "rtu_slave": "The RTU slave address. Ignored in TCP mode. Default is 1.", + "tcp_port": "The port used for TCP communication. Ignored in RTU mode. Default is 502.", + "debug": "A boolean flag to enable or disable debug mode. Default is false." + }, + "see": "modbus.Mode for valid modes.", + "maixpy": "maix.comm.modbus.Slave.__init__", + "py_doc": "Modbus Slave constructor.\nThis constructor initializes a Modbus Slave instance. Depending on the mode (RTU or TCP),\nit sets up the necessary parameters for communication and defines the register structure.\n\nArgs:\n - mode: Specifies the communication mode: RTU or TCP.\n - ip_or_device: The UART device name if using RTU mode.\nIf TCP mode is selected, this parameter is ignored.\n - coils_start: The starting address of the coils register.\n - coils_size: The number of coils to manage.\n - discrete_start: The starting address of the discrete inputs register.\n - discrete_size: The number of discrete inputs to manage.\n - holding_start: The starting address of the holding registers.\n - holding_size: The number of holding registers to manage.\n - input_start: The starting address of the input registers.\n - input_size: The number of input registers to manage.\n - rtu_baud: The baud rate for RTU communication.\nSupported rates include: 110, 300, 600, 1200, 2400, 4800,\n9600, 19200, 38400, 57600, 115200, 230400, 460800,\n500000, 576000, 921600, 1000000, 1152000, 1500000,\n2500000, 3000000, 3500000, 4000000.\nDefault is 115200. Ensure that the selected baud rate\nis supported by the underlying hardware and libmodbus.\n - rtu_slave: The RTU slave address. Ignored in TCP mode. Default is 1.\n - tcp_port: The port used for TCP communication. Ignored in RTU mode. Default is 502.\n - debug: A boolean flag to enable or disable debug mode. Default is false.\n" + }, + "args": [ + [ + "maix::comm::modbus::Mode", + "mode", + null + ], + [ + "const std::string&", + "ip_or_device", + null + ], + [ + "uint32_t", + "coils_start", + "0" + ], + [ + "uint32_t", + "coils_size", + "0" + ], + [ + "uint32_t", + "discrete_start", + "0" + ], + [ + "uint32_t", + "discrete_size", + "0" + ], + [ + "uint32_t", + "holding_start", + "0" + ], + [ + "uint32_t", + "holding_size", + "0" + ], + [ + "uint32_t", + "input_start", + "0" + ], + [ + "uint32_t", + "input_size", + "0" + ], + [ + "int", + "rtu_baud", + "115200" + ], + [ + "uint8_t", + "rtu_slave", + "1" + ], + [ + "int", + "tcp_port", + "502" + ], + [ + "bool", + "debug", + "false" + ] + ], + "ret_type": null, + "static": false, + "def": "Slave(maix::comm::modbus::Mode mode, const std::string& ip_or_device,\n uint32_t coils_start=0, uint32_t coils_size=0,\n uint32_t discrete_start=0, uint32_t discrete_size=0,\n uint32_t holding_start=0, uint32_t holding_size=0,\n uint32_t input_start=0, uint32_t input_size=0,\n int rtu_baud=115200, uint8_t rtu_slave=1,\n int tcp_port=502, bool debug=false)" + }, + "receive": { + "type": "func", + "name": "receive", + "doc": { + "brief": "Receives a Modbus request\\nThis function is used to receive a Modbus request from the client. The behavior of the function\\ndepends on the parameter `timeout_ms` provided, which dictates how long the function will wait\\nfor a request before returning.", + "note": "This function gets and parses the request, it does not manipulate the registers.", + "param": { + "timeout_ms": "Timeout setting\n-1 Block indefinitely until a request is received\n0 Non-blocking mode; function returns immediately, regardless of whether a request is received\n>0 Blocking mode; function will wait for the specified number of milliseconds for a request" + }, + "return": "maix::err::Err type, @see maix::err::Err", + "maixpy": "maix.comm.modbus.Slave.receive", + "py_doc": "Receives a Modbus request\nThis function is used to receive a Modbus request from the client. The behavior of the function\ndepends on the parameter `timeout_ms` provided, which dictates how long the function will wait\nfor a request before returning.\n\nArgs:\n - timeout_ms: Timeout setting\n-1 Block indefinitely until a request is received\n0 Non-blocking mode; function returns immediately, regardless of whether a request is received\n>0 Blocking mode; function will wait for the specified number of milliseconds for a request\n\n\nReturns: maix::err::Err type, @see maix::err::Err\n" + }, + "args": [ + [ + "const int", + "timeout_ms", + "-1" + ] + ], + "ret_type": "::maix::err::Err", + "static": false, + "def": "::maix::err::Err receive(const int timeout_ms=-1)" + }, + "request_type": { + "type": "func", + "name": "request_type", + "doc": { + "brief": "Gets the type of the Modbus request that was successfully received\\nThis function can be used to retrieve the type of the request received after a successful\\ncall to `receive()`. The return value indicates the type of the Modbus request, allowing\\nthe user to understand and process the received request appropriately.", + "return": "RequestType The type of the Modbus request that has been received.", + "see": "modbus.RequestType", + "maixpy": "maix.comm.modbus.Slave.request_type", + "py_doc": "Gets the type of the Modbus request that was successfully received\nThis function can be used to retrieve the type of the request received after a successful\ncall to `receive()`. The return value indicates the type of the Modbus request, allowing\nthe user to understand and process the received request appropriately.\n\nReturns: RequestType The type of the Modbus request that has been received.\n" + }, + "args": [], + "ret_type": "::maix::comm::modbus::RequestType", + "static": false, + "def": "::maix::comm::modbus::RequestType request_type()" + }, + "reply": { + "type": "func", + "name": "reply", + "doc": { + "brief": "Processes the request and returns the corresponding data.\\nThis function handles the requests received from the client. It retrieves any data that the client\\nneeds to write to the registers and updates the registers accordingly. Additionally, it retrieves\\nthe requested data from the registers and sends it back to the client in the response.\\nThis function is essential for managing read and write operations in a Modbus Slave context.", + "note": "The function will modify the Slave's internal state based on the data received in the\nrequest, and ensure that the appropriate data is returned to the client.", + "return": "maix::err::Err type, @see maix::err::Err", + "maixpy": "maix.comm.modbus.Slave.reply", + "py_doc": "Processes the request and returns the corresponding data.\nThis function handles the requests received from the client. It retrieves any data that the client\nneeds to write to the registers and updates the registers accordingly. Additionally, it retrieves\nthe requested data from the registers and sends it back to the client in the response.\nThis function is essential for managing read and write operations in a Modbus Slave context.\n\nReturns: maix::err::Err type, @see maix::err::Err\n" + }, + "args": [], + "ret_type": "::maix::err::Err", + "static": false, + "def": "::maix::err::Err reply()" + }, + "receive_and_reply": { + "type": "func", + "name": "receive_and_reply", + "doc": { + "brief": "Receives a request from the client and sends a response.\\nThis function combines the operations of receiving a request and sending a corresponding\\nresponse in a single call. It waits for a specified duration (defined by the `timeout_ms`\\nparameter) to receive a request from the client. Upon successful receipt of the request,\\nit processes the request and prepares the necessary data to be sent back to the client.", + "param": { + "timeout_ms": "The timeout duration for waiting to receive a request.\n- A value of -1 makes the function block indefinitely until a request\nis received.\n- A value of 0 makes it non-blocking, returning immediately without\nwaiting for a request.\n- A positive value specifies the maximum time (in milliseconds) to wait\nfor a request before timing out." + }, + "return": "RequestType The type of the Modbus request that has been received.", + "see": "modbus.RequestType", + "maixpy": "maix.comm.modbus.Slave.receive_and_reply", + "py_doc": "Receives a request from the client and sends a response.\nThis function combines the operations of receiving a request and sending a corresponding\nresponse in a single call. It waits for a specified duration (defined by the `timeout_ms`\nparameter) to receive a request from the client. Upon successful receipt of the request,\nit processes the request and prepares the necessary data to be sent back to the client.\n\nArgs:\n - timeout_ms: The timeout duration for waiting to receive a request.\n- A value of -1 makes the function block indefinitely until a request\nis received.\n- A value of 0 makes it non-blocking, returning immediately without\nwaiting for a request.\n- A positive value specifies the maximum time (in milliseconds) to wait\nfor a request before timing out.\n\n\nReturns: RequestType The type of the Modbus request that has been received.\n" + }, + "args": [ + [ + "const int", + "timeout_ms", + "-1" + ] + ], + "ret_type": "::maix::comm::modbus::RequestType", + "static": false, + "def": "::maix::comm::modbus::RequestType receive_and_reply(const int timeout_ms=-1)" + }, + "coils": { + "type": "func", + "name": "coils", + "doc": { + "brief": "Reads from or writes to coils.\\nThis function can be used to either read data from coils or write data to them.\\nIf the `data` parameter is empty, the function performs a read operation.\\nIf `data` is not empty, the function writes the contents of `data` to the coils\\nstarting at the specified index.", + "param": { + "data": "A vector of data to be written. If empty, a read operation is performed.\nIf not empty, the data will overwrite the coils from `index`.", + "index": "The starting index for writing data. This parameter is ignored during read operations." + }, + "return": "std::vector When the read operation is successful, return all data in the coils as a list.\nWhen the write operation is successful, return a non-empty list; when it fails, return an empty list.", + "maixpy": "maix.comm.modbus.Slave.coils", + "py_doc": "Reads from or writes to coils.\nThis function can be used to either read data from coils or write data to them.\nIf the `data` parameter is empty, the function performs a read operation.\nIf `data` is not empty, the function writes the contents of `data` to the coils\nstarting at the specified index.\n\nArgs:\n - data: A vector of data to be written. If empty, a read operation is performed.\nIf not empty, the data will overwrite the coils from `index`.\n - index: The starting index for writing data. This parameter is ignored during read operations.\n\n\nReturns: std::vector When the read operation is successful, return all data in the coils as a list.\nWhen the write operation is successful, return a non-empty list; when it fails, return an empty list.\n" + }, + "args": [ + [ + "const std::vector&", + "data", + "std::vector{}" + ], + [ + "const uint32_t", + "index", + "0" + ] + ], + "ret_type": "std::vector", + "static": false, + "def": "std::vector coils(const std::vector& data = std::vector{}, const uint32_t index = 0)" + }, + "discrete_input": { + "type": "func", + "name": "discrete_input", + "doc": { + "brief": "Reads from or writes to discrete input.\\nThis function can be used to either read data from discrete input or write data to them.\\nIf the `data` parameter is empty, the function performs a read operation.\\nIf `data` is not empty, the function writes the contents of `data` to the discrete input\\nstarting at the specified index.", + "param": { + "data": "A vector of data to be written. If empty, a read operation is performed.\nIf not empty, the data will overwrite the discrete input from `index`.", + "index": "The starting index for writing data. This parameter is ignored during read operations." + }, + "return": "std::vector When the read operation is successful, return all data in the discrete input as a list.\nWhen the write operation is successful, return a non-empty list; when it fails, return an empty list.", + "maixpy": "maix.comm.modbus.Slave.discrete_input", + "py_doc": "Reads from or writes to discrete input.\nThis function can be used to either read data from discrete input or write data to them.\nIf the `data` parameter is empty, the function performs a read operation.\nIf `data` is not empty, the function writes the contents of `data` to the discrete input\nstarting at the specified index.\n\nArgs:\n - data: A vector of data to be written. If empty, a read operation is performed.\nIf not empty, the data will overwrite the discrete input from `index`.\n - index: The starting index for writing data. This parameter is ignored during read operations.\n\n\nReturns: std::vector When the read operation is successful, return all data in the discrete input as a list.\nWhen the write operation is successful, return a non-empty list; when it fails, return an empty list.\n" + }, + "args": [ + [ + "const std::vector&", + "data", + "std::vector{}" + ], + [ + "const uint32_t", + "index", + "0" + ] + ], + "ret_type": "std::vector", + "static": false, + "def": "std::vector discrete_input(const std::vector& data = std::vector{}, const uint32_t index = 0)" + }, + "input_registers": { + "type": "func", + "name": "input_registers", + "doc": { + "brief": "Reads from or writes to input registers.\\nThis function can be used to either read data from input registers or write data to them.\\nIf the `data` parameter is empty, the function performs a read operation.\\nIf `data` is not empty, the function writes the contents of `data` to the input registers\\nstarting at the specified index.", + "param": { + "data": "A vector of data to be written. If empty, a read operation is performed.\nIf not empty, the data will overwrite the input registers from `index`.", + "index": "The starting index for writing data. This parameter is ignored during read operations." + }, + "return": "std::vector When the read operation is successful, return all data in the input registers as a list.\nWhen the write operation is successful, return a non-empty list; when it fails, return an empty list.", + "maixpy": "maix.comm.modbus.Slave.input_registers", + "py_doc": "Reads from or writes to input registers.\nThis function can be used to either read data from input registers or write data to them.\nIf the `data` parameter is empty, the function performs a read operation.\nIf `data` is not empty, the function writes the contents of `data` to the input registers\nstarting at the specified index.\n\nArgs:\n - data: A vector of data to be written. If empty, a read operation is performed.\nIf not empty, the data will overwrite the input registers from `index`.\n - index: The starting index for writing data. This parameter is ignored during read operations.\n\n\nReturns: std::vector When the read operation is successful, return all data in the input registers as a list.\nWhen the write operation is successful, return a non-empty list; when it fails, return an empty list.\n" + }, + "args": [ + [ + "const std::vector&", + "data", + "std::vector{}" + ], + [ + "const uint32_t", + "index", + "0" + ] + ], + "ret_type": "std::vector", + "static": false, + "def": "std::vector input_registers(const std::vector& data = std::vector{}, const uint32_t index = 0)" + }, + "holding_registers": { + "type": "func", + "name": "holding_registers", + "doc": { + "brief": "Reads from or writes to holding registers.\\nThis function can be used to either read data from holding registers or write data to them.\\nIf the `data` parameter is empty, the function performs a read operation.\\nIf `data` is not empty, the function writes the contents of `data` to the holding registers\\nstarting at the specified index.", + "param": { + "data": "A vector of data to be written. If empty, a read operation is performed.\nIf not empty, the data will overwrite the holding registers from `index`.", + "index": "The starting index for writing data. This parameter is ignored during read operations." + }, + "return": "std::vector When the read operation is successful, return all data in the holding registers as a list.\nWhen the write operation is successful, return a non-empty list; when it fails, return an empty list.", + "maixpy": "maix.comm.modbus.Slave.holding_registers", + "py_doc": "Reads from or writes to holding registers.\nThis function can be used to either read data from holding registers or write data to them.\nIf the `data` parameter is empty, the function performs a read operation.\nIf `data` is not empty, the function writes the contents of `data` to the holding registers\nstarting at the specified index.\n\nArgs:\n - data: A vector of data to be written. If empty, a read operation is performed.\nIf not empty, the data will overwrite the holding registers from `index`.\n - index: The starting index for writing data. This parameter is ignored during read operations.\n\n\nReturns: std::vector When the read operation is successful, return all data in the holding registers as a list.\nWhen the write operation is successful, return a non-empty list; when it fails, return an empty list.\n" + }, + "args": [ + [ + "const std::vector&", + "data", + "std::vector{}" + ], + [ + "const uint32_t", + "index", + "0" + ] + ], + "ret_type": "std::vector", + "static": false, + "def": "std::vector holding_registers(const std::vector& data = std::vector{}, const uint32_t index = 0)" + } + }, + "def": "class Slave" + }, + "set_master_debug": { + "type": "func", + "name": "set_master_debug", + "doc": { + "brief": "Set the master debug ON/OFF", + "param": { + "debug": "True(ON) or False(OFF)" + }, + "maixpy": "maix.comm.modbus.set_master_debug", + "py_doc": "Set the master debug ON/OFF\n\nArgs:\n - debug: True(ON) or False(OFF)\n" + }, + "args": [ + [ + "bool", + "debug", + null + ] + ], + "ret_type": "void", + "static": false, + "def": "void set_master_debug(bool debug)" + }, + "MasterRTU": { + "type": "class", + "name": "MasterRTU", + "doc": { + "brief": "Class for modbus MasterRTU", + "maixpy": "maix.comm.modbus.MasterRTU", + "py_doc": "Class for modbus MasterRTU" + }, + "members": { + "__init__": { + "type": "func", + "name": "MasterRTU", + "doc": { + "brief": "Construct a new MasterRTU object", + "param": { + "device": "Default uart device.", + "baudrate": "Default uart baudrate." + }, + "maixpy": "maix.comm.modbus.MasterRTU.__init__", + "py_doc": "Construct a new MasterRTU object\n\nArgs:\n - device: Default uart device.\n - baudrate: Default uart baudrate.\n" + }, + "args": [ + [ + "const std::string&", + "device", + "\"\"" + ], + [ + "const int", + "baudrate", + "115200" + ] + ], + "ret_type": null, + "static": false, + "def": "MasterRTU(const std::string& device=\"\", const int baudrate=115200)" + }, + "read_coils": { + "type": "func", + "name": "read_coils", + "doc": { + "brief": "Reads coils from the Modbus device.\\nThis function reads a specified number of coils starting from a given address.\\nIt includes timeout settings to define how long to wait for a response.", + "param": { + "slave_id": "The RTU slave address.", + "addr": "The starting address for reading coils.", + "size": "The number of coils to read.", + "timeout_ms": "The timeout duration for waiting to receive a request.\n- A value of -1 makes the function block indefinitely until a request\nis received.\n- A value of 0 makes it non-blocking, returning immediately without\nwaiting for a request.\n- A positive value specifies the maximum time (in milliseconds) to wait\nfor a request before timing out.", + "device": "The UART device to use. An empty string (\"\") indicates that the\ndefault device from the constructor will be used.", + "baudrate": "The UART baud rate. A value of -1 signifies that the default baud rate\nfrom the constructor will be applied." + }, + "return": "std::vector/list[int] A vector containing the read coil values.", + "maixpy": "maix.comm.modbus.MasterRTU.read_coils", + "py_doc": "Reads coils from the Modbus device.\nThis function reads a specified number of coils starting from a given address.\nIt includes timeout settings to define how long to wait for a response.\n\nArgs:\n - slave_id: The RTU slave address.\n - addr: The starting address for reading coils.\n - size: The number of coils to read.\n - timeout_ms: The timeout duration for waiting to receive a request.\n- A value of -1 makes the function block indefinitely until a request\nis received.\n- A value of 0 makes it non-blocking, returning immediately without\nwaiting for a request.\n- A positive value specifies the maximum time (in milliseconds) to wait\nfor a request before timing out.\n - device: The UART device to use. An empty string (\"\") indicates that the\ndefault device from the constructor will be used.\n - baudrate: The UART baud rate. A value of -1 signifies that the default baud rate\nfrom the constructor will be applied.\n\n\nReturns: std::vector/list[int] A vector containing the read coil values.\n" + }, + "args": [ + [ + "const uint32_t", + "slave_id", + null + ], + [ + "const uint32_t", + "addr", + null + ], + [ + "const uint32_t", + "size", + null + ], + [ + "const int", + "timeout_ms", + "-1" + ], + [ + "const std::string&", + "device", + "\"\"" + ], + [ + "const int", + "baudrate", + "-1" + ] + ], + "ret_type": "std::vector", + "static": false, + "def": "std::vector read_coils(const uint32_t slave_id, const uint32_t addr,\n const uint32_t size, const int timeout_ms=-1,\n const std::string& device=\"\", const int baudrate=-1)", + "overload": [ + { + "type": "func", + "name": "read_coils", + "doc": { + "brief": "Reads coils from the Modbus device.\\nThis function reads a specified number of coils starting from a given address.\\nIt includes timeout settings to define how long to wait for a response.", + "param": { + "device": "The UART device to use.", + "baudrate": "he UART baud rate.", + "slave_id": "The RTU slave address.", + "addr": "The starting address for reading coils.", + "size": "The number of coils to read.", + "timeout_ms": "The timeout duration for waiting to receive a request.\n- A value of -1 makes the function block indefinitely until a request\nis received.\n- A value of 0 makes it non-blocking, returning immediately without\nwaiting for a request.\n- A positive value specifies the maximum time (in milliseconds) to wait\nfor a request before timing out." + }, + "return": "std::vector/list[int] A vector containing the read coil values.", + "maixcdk": "maix.comm.modbus.MasterRTU.read_coils", + "py_doc": "Reads coils from the Modbus device.\nThis function reads a specified number of coils starting from a given address.\nIt includes timeout settings to define how long to wait for a response.\n\nArgs:\n - device: The UART device to use.\n - baudrate: he UART baud rate.\n - slave_id: The RTU slave address.\n - addr: The starting address for reading coils.\n - size: The number of coils to read.\n - timeout_ms: The timeout duration for waiting to receive a request.\n- A value of -1 makes the function block indefinitely until a request\nis received.\n- A value of 0 makes it non-blocking, returning immediately without\nwaiting for a request.\n- A positive value specifies the maximum time (in milliseconds) to wait\nfor a request before timing out.\n\n\nReturns: std::vector/list[int] A vector containing the read coil values.\n" + }, + "args": [ + [ + "const std::string&", + "device", + null + ], + [ + "const int", + "baudrate", + null + ], + [ + "const uint32_t", + "slave_id", + null + ], + [ + "const uint32_t", + "addr", + null + ], + [ + "const uint32_t", + "size", + null + ], + [ + "const int", + "timeout_ms", + "-1" + ] + ], + "ret_type": "std::vector", + "static": true, + "def": "static std::vector read_coils( const std::string& device, const int baudrate,\n const uint32_t slave_id, const uint32_t addr,\n const uint32_t size, const int timeout_ms=-1)" + } + ] + }, + "write_coils": { + "type": "func", + "name": "write_coils", + "doc": { + "brief": "Writes values to coils on the Modbus device.\\nThis function writes the specified data to the coils starting from a given address.", + "param": { + "slave_id": "The RTU slave address.", + "data": "A vector containing the coil values to write.", + "addr": "The starting address for writing coils.", + "timeout_ms": "The timeout duration for the write operation.\n- A value of -1 makes the function block until the write is complete.\n- A value of 0 makes it non-blocking.\n- A positive value specifies the maximum time (in milliseconds) to wait.", + "device": "The UART device to use. An empty string (\"\") indicates that the\ndefault device from the constructor will be used.", + "baudrate": "The UART baud rate. A value of -1 signifies that the default baud rate\nfrom the constructor will be applied." + }, + "return": "int Returns the number of bytes written on success, or a value less than 0 on failure.", + "maixpy": "maix.comm.modbus.MasterRTU.write_coils", + "py_doc": "Writes values to coils on the Modbus device.\nThis function writes the specified data to the coils starting from a given address.\n\nArgs:\n - slave_id: The RTU slave address.\n - data: A vector containing the coil values to write.\n - addr: The starting address for writing coils.\n - timeout_ms: The timeout duration for the write operation.\n- A value of -1 makes the function block until the write is complete.\n- A value of 0 makes it non-blocking.\n- A positive value specifies the maximum time (in milliseconds) to wait.\n - device: The UART device to use. An empty string (\"\") indicates that the\ndefault device from the constructor will be used.\n - baudrate: The UART baud rate. A value of -1 signifies that the default baud rate\nfrom the constructor will be applied.\n\n\nReturns: int Returns the number of bytes written on success, or a value less than 0 on failure.\n" + }, + "args": [ + [ + "const uint32_t", + "slave_id", + null + ], + [ + "const std::vector&", + "data", + null + ], + [ + "const uint32_t", + "addr", + null + ], + [ + "const int", + "timeout_ms", + "-1" + ], + [ + "const std::string&", + "device", + "\"\"" + ], + [ + "const int", + "baudrate", + "-1" + ] + ], + "ret_type": "int", + "static": false, + "def": "int write_coils(const uint32_t slave_id, const std::vector& data,\n const uint32_t addr, const int timeout_ms=-1,\n const std::string& device=\"\", const int baudrate=-1)", + "overload": [ + { + "type": "func", + "name": "write_coils", + "doc": { + "brief": "Writes values to coils on the Modbus device.\\nThis function writes the specified data to the coils starting from a given address.", + "param": { + "device": "The UART device to use.", + "baudrate": "The UART baud rate.", + "slave_id": "The RTU slave address.", + "data": "A vector containing the coil values to write.", + "addr": "The starting address for writing coils.", + "timeout_ms": "The timeout duration for the write operation.\n- A value of -1 makes the function block until the write is complete.\n- A value of 0 makes it non-blocking.\n- A positive value specifies the maximum time (in milliseconds) to wait." + }, + "return": "int Returns the number of bytes written on success, or a value less than 0 on failure.", + "maixcdk": "maix.comm.modbus.MasterRTU.write_coils", + "py_doc": "Writes values to coils on the Modbus device.\nThis function writes the specified data to the coils starting from a given address.\n\nArgs:\n - device: The UART device to use.\n - baudrate: The UART baud rate.\n - slave_id: The RTU slave address.\n - data: A vector containing the coil values to write.\n - addr: The starting address for writing coils.\n - timeout_ms: The timeout duration for the write operation.\n- A value of -1 makes the function block until the write is complete.\n- A value of 0 makes it non-blocking.\n- A positive value specifies the maximum time (in milliseconds) to wait.\n\n\nReturns: int Returns the number of bytes written on success, or a value less than 0 on failure.\n" + }, + "args": [ + [ + "const std::string&", + "device", + null + ], + [ + "const int", + "baudrate", + null + ], + [ + "const uint32_t", + "slave_id", + null + ], + [ + "const std::vector&", + "data", + null + ], + [ + "const uint32_t", + "addr", + null + ], + [ + "const int", + "timeout_ms", + "-1" + ] + ], + "ret_type": "int", + "static": true, + "def": "static int write_coils(const std::string& device, const int baudrate,\n const uint32_t slave_id, const std::vector& data,\n const uint32_t addr, const int timeout_ms=-1)" + } + ] + }, + "read_discrete_input": { + "type": "func", + "name": "read_discrete_input", + "doc": { + "brief": "Reads discrete inputs from the Modbus device.\\nThis function reads a specified number of discrete inputs starting from a given address.", + "param": { + "slave_id": "The RTU slave address.", + "addr": "The starting address for reading discrete inputs.", + "size": "The number of discrete inputs to read.", + "timeout_ms": "The timeout duration for the write operation.\n- A value of -1 makes the function block until the write is complete.\n- A value of 0 makes it non-blocking.\n- A positive value specifies the maximum time (in milliseconds) to wait.", + "device": "The UART device to use. An empty string (\"\") indicates that the\ndefault device from the constructor will be used.", + "baudrate": "The UART baud rate. A value of -1 signifies that the default baud rate\nfrom the constructor will be applied." + }, + "return": "std::vector/list[int] A vector containing the read discrete input values.", + "maixpy": "maix.comm.modbus.MasterRTU.read_discrete_input", + "py_doc": "Reads discrete inputs from the Modbus device.\nThis function reads a specified number of discrete inputs starting from a given address.\n\nArgs:\n - slave_id: The RTU slave address.\n - addr: The starting address for reading discrete inputs.\n - size: The number of discrete inputs to read.\n - timeout_ms: The timeout duration for the write operation.\n- A value of -1 makes the function block until the write is complete.\n- A value of 0 makes it non-blocking.\n- A positive value specifies the maximum time (in milliseconds) to wait.\n - device: The UART device to use. An empty string (\"\") indicates that the\ndefault device from the constructor will be used.\n - baudrate: The UART baud rate. A value of -1 signifies that the default baud rate\nfrom the constructor will be applied.\n\n\nReturns: std::vector/list[int] A vector containing the read discrete input values.\n" + }, + "args": [ + [ + "const uint32_t", + "slave_id", + null + ], + [ + "const uint32_t", + "addr", + null + ], + [ + "const uint32_t", + "size", + null + ], + [ + "const int", + "timeout_ms", + "-1" + ], + [ + "const std::string&", + "device", + "\"\"" + ], + [ + "const int", + "baudrate", + "-1" + ] + ], + "ret_type": "std::vector", + "static": false, + "def": "std::vector read_discrete_input(const uint32_t slave_id, const uint32_t addr,\n const uint32_t size, const int timeout_ms=-1,\n const std::string& device=\"\", const int baudrate=-1)", + "overload": [ + { + "type": "func", + "name": "read_discrete_input", + "doc": { + "brief": "Reads discrete inputs from the Modbus device.\\nThis function reads a specified number of discrete inputs starting from a given address.", + "param": { + "device": "The UART device to use.", + "baudrate": "The UART baud rate.", + "slave_id": "The RTU slave address.", + "addr": "The starting address for reading discrete inputs.", + "size": "The number of discrete inputs to read.", + "timeout_ms": "The timeout duration for the write operation.\n- A value of -1 makes the function block until the write is complete.\n- A value of 0 makes it non-blocking.\n- A positive value specifies the maximum time (in milliseconds) to wait." + }, + "return": "std::vector/list[int] A vector containing the read discrete input values.", + "maixcdk": "maix.comm.modbus.MasterRTU.read_discrete_input", + "py_doc": "Reads discrete inputs from the Modbus device.\nThis function reads a specified number of discrete inputs starting from a given address.\n\nArgs:\n - device: The UART device to use.\n - baudrate: The UART baud rate.\n - slave_id: The RTU slave address.\n - addr: The starting address for reading discrete inputs.\n - size: The number of discrete inputs to read.\n - timeout_ms: The timeout duration for the write operation.\n- A value of -1 makes the function block until the write is complete.\n- A value of 0 makes it non-blocking.\n- A positive value specifies the maximum time (in milliseconds) to wait.\n\n\nReturns: std::vector/list[int] A vector containing the read discrete input values.\n" + }, + "args": [ + [ + "const std::string&", + "device", + null + ], + [ + "const int", + "baudrate", + null + ], + [ + "const uint32_t", + "slave_id", + null + ], + [ + "const uint32_t", + "addr", + null + ], + [ + "const uint32_t", + "size", + null + ], + [ + "const int", + "timeout_ms", + "-1" + ] + ], + "ret_type": "std::vector", + "static": true, + "def": "static std::vector read_discrete_input(const std::string& device, const int baudrate,\n const uint32_t slave_id, const uint32_t addr,\n const uint32_t size, const int timeout_ms=-1)" + } + ] + }, + "read_input_registers": { + "type": "func", + "name": "read_input_registers", + "doc": { + "brief": "Reads input registers from the Modbus device.\\nThis function reads a specified number of input registers starting from a given address.", + "param": { + "slave_id": "The RTU slave address.", + "addr": "The starting address for reading input registers.", + "size": "The number of input registers to read.", + "timeout_ms": "The timeout duration for the write operation.\n- A value of -1 makes the function block until the write is complete.\n- A value of 0 makes it non-blocking.\n- A positive value specifies the maximum time (in milliseconds) to wait.", + "device": "The UART device to use. An empty string (\"\") indicates that the\ndefault device from the constructor will be used.", + "baudrate": "The UART baud rate. A value of -1 signifies that the default baud rate\nfrom the constructor will be applied." + }, + "return": "std::vector/list[int] A vector containing the read input register values.", + "maixpy": "maix.comm.modbus.MasterRTU.read_input_registers", + "py_doc": "Reads input registers from the Modbus device.\nThis function reads a specified number of input registers starting from a given address.\n\nArgs:\n - slave_id: The RTU slave address.\n - addr: The starting address for reading input registers.\n - size: The number of input registers to read.\n - timeout_ms: The timeout duration for the write operation.\n- A value of -1 makes the function block until the write is complete.\n- A value of 0 makes it non-blocking.\n- A positive value specifies the maximum time (in milliseconds) to wait.\n - device: The UART device to use. An empty string (\"\") indicates that the\ndefault device from the constructor will be used.\n - baudrate: The UART baud rate. A value of -1 signifies that the default baud rate\nfrom the constructor will be applied.\n\n\nReturns: std::vector/list[int] A vector containing the read input register values.\n" + }, + "args": [ + [ + "const uint32_t", + "slave_id", + null + ], + [ + "const uint32_t", + "addr", + null + ], + [ + "const uint32_t", + "size", + null + ], + [ + "const int", + "timeout_ms", + "-1" + ], + [ + "const std::string&", + "device", + "\"\"" + ], + [ + "const int", + "baudrate", + "-1" + ] + ], + "ret_type": "std::vector", + "static": false, + "def": "std::vector read_input_registers(const uint32_t slave_id, const uint32_t addr,\n const uint32_t size, const int timeout_ms=-1,\n const std::string& device=\"\", const int baudrate=-1)", + "overload": [ + { + "type": "func", + "name": "read_input_registers", + "doc": { + "brief": "Reads input registers from the Modbus device.\\nThis function reads a specified number of input registers starting from a given address.", + "param": { + "device": "The UART device to use.", + "baudrate": "The UART baud rate.", + "slave_id": "The RTU slave address.", + "addr": "The starting address for reading input registers.", + "size": "The number of input registers to read.", + "timeout_ms": "The timeout duration for the write operation.\n- A value of -1 makes the function block until the write is complete.\n- A value of 0 makes it non-blocking.\n- A positive value specifies the maximum time (in milliseconds) to wait." + }, + "return": "std::vector/list[int] A vector containing the read input register values.", + "maixcdk": "maix.comm.modbus.MasterRTU.read_input_registers", + "py_doc": "Reads input registers from the Modbus device.\nThis function reads a specified number of input registers starting from a given address.\n\nArgs:\n - device: The UART device to use.\n - baudrate: The UART baud rate.\n - slave_id: The RTU slave address.\n - addr: The starting address for reading input registers.\n - size: The number of input registers to read.\n - timeout_ms: The timeout duration for the write operation.\n- A value of -1 makes the function block until the write is complete.\n- A value of 0 makes it non-blocking.\n- A positive value specifies the maximum time (in milliseconds) to wait.\n\n\nReturns: std::vector/list[int] A vector containing the read input register values.\n" + }, + "args": [ + [ + "const std::string&", + "device", + null + ], + [ + "const int", + "baudrate", + null + ], + [ + "const uint32_t", + "slave_id", + null + ], + [ + "const uint32_t", + "addr", + null + ], + [ + "const uint32_t", + "size", + null + ], + [ + "const int", + "timeout_ms", + "-1" + ] + ], + "ret_type": "std::vector", + "static": true, + "def": "static std::vector read_input_registers(const std::string& device, const int baudrate,\n const uint32_t slave_id, const uint32_t addr,\n const uint32_t size, const int timeout_ms=-1)" + } + ] + }, + "read_holding_registers": { + "type": "func", + "name": "read_holding_registers", + "doc": { + "brief": "Reads holding registers from the Modbus device.\\nThis function reads a specified number of holding registers starting from a given address.", + "param": { + "slave_id": "The RTU slave address.", + "addr": "The starting address for reading holding registers.", + "size": "The number of holding registers to read.", + "timeout_ms": "The timeout duration for the write operation.\n- A value of -1 makes the function block until the write is complete.\n- A value of 0 makes it non-blocking.\n- A positive value specifies the maximum time (in milliseconds) to wait.", + "device": "The UART device to use. An empty string (\"\") indicates that the\ndefault device from the constructor will be used.", + "baudrate": "The UART baud rate. A value of -1 signifies that the default baud rate\nfrom the constructor will be applied." + }, + "return": "std::vector/list[int] A vector containing the read holding register values.", + "maixpy": "maix.comm.modbus.MasterRTU.read_holding_registers", + "py_doc": "Reads holding registers from the Modbus device.\nThis function reads a specified number of holding registers starting from a given address.\n\nArgs:\n - slave_id: The RTU slave address.\n - addr: The starting address for reading holding registers.\n - size: The number of holding registers to read.\n - timeout_ms: The timeout duration for the write operation.\n- A value of -1 makes the function block until the write is complete.\n- A value of 0 makes it non-blocking.\n- A positive value specifies the maximum time (in milliseconds) to wait.\n - device: The UART device to use. An empty string (\"\") indicates that the\ndefault device from the constructor will be used.\n - baudrate: The UART baud rate. A value of -1 signifies that the default baud rate\nfrom the constructor will be applied.\n\n\nReturns: std::vector/list[int] A vector containing the read holding register values.\n" + }, + "args": [ + [ + "const uint32_t", + "slave_id", + null + ], + [ + "const uint32_t", + "addr", + null + ], + [ + "const uint32_t", + "size", + null + ], + [ + "const int", + "timeout_ms", + "-1" + ], + [ + "const std::string&", + "device", + "\"\"" + ], + [ + "const int", + "baudrate", + "-1" + ] + ], + "ret_type": "std::vector", + "static": false, + "def": "std::vector read_holding_registers(const uint32_t slave_id, const uint32_t addr,\n const uint32_t size, const int timeout_ms=-1,\n const std::string& device=\"\", const int baudrate=-1)", + "overload": [ + { + "type": "func", + "name": "read_holding_registers", + "doc": { + "brief": "Reads holding registers from the Modbus device.\\nThis function reads a specified number of holding registers starting from a given address.", + "param": { + "device": "The UART device to use.", + "baudrate": "The UART baud rate.", + "slave_id": "The RTU slave address.", + "addr": "The starting address for reading holding registers.", + "size": "The number of holding registers to read.", + "timeout_ms": "The timeout duration for the write operation.\n- A value of -1 makes the function block until the write is complete.\n- A value of 0 makes it non-blocking.\n- A positive value specifies the maximum time (in milliseconds) to wait." + }, + "return": "std::vector/list[int] A vector containing the read holding register values.", + "maixcdk": "maix.comm.modbus.MasterRTU.read_holding_registers", + "py_doc": "Reads holding registers from the Modbus device.\nThis function reads a specified number of holding registers starting from a given address.\n\nArgs:\n - device: The UART device to use.\n - baudrate: The UART baud rate.\n - slave_id: The RTU slave address.\n - addr: The starting address for reading holding registers.\n - size: The number of holding registers to read.\n - timeout_ms: The timeout duration for the write operation.\n- A value of -1 makes the function block until the write is complete.\n- A value of 0 makes it non-blocking.\n- A positive value specifies the maximum time (in milliseconds) to wait.\n\n\nReturns: std::vector/list[int] A vector containing the read holding register values.\n" + }, + "args": [ + [ + "const std::string&", + "device", + null + ], + [ + "const int", + "baudrate", + null + ], + [ + "const uint32_t", + "slave_id", + null + ], + [ + "const uint32_t", + "addr", + null + ], + [ + "const uint32_t", + "size", + null + ], + [ + "const int", + "timeout_ms", + "-1" + ] + ], + "ret_type": "std::vector", + "static": true, + "def": "static std::vector read_holding_registers(const std::string& device, const int baudrate,\n const uint32_t slave_id, const uint32_t addr,\n const uint32_t size, const int timeout_ms=-1)" + } + ] + }, + "write_holding_registers": { + "type": "func", + "name": "write_holding_registers", + "doc": { + "brief": "Writes values to holding registers on the Modbus device.\\nThis function writes the specified data to the holding registers starting from a given address.", + "param": { + "slave_id": "The RTU slave address.", + "data": "A vector containing the values to write to holding registers.", + "addr": "The starting address for writing holding registers.", + "timeout_ms": "The timeout duration for the write operation.\n- A value of -1 makes the function block until the write is complete.\n- A value of 0 makes it non-blocking.\n- A positive value specifies the maximum time (in milliseconds) to wait.", + "device": "The UART device to use. An empty string (\"\") indicates that the\ndefault device from the constructor will be used.", + "baudrate": "The UART baud rate. A value of -1 signifies that the default baud rate\nfrom the constructor will be applied." + }, + "return": "int Returns the number of bytes written on success, or a value less than 0 on failure.", + "maixpy": "maix.comm.modbus.MasterRTU.write_holding_registers", + "py_doc": "Writes values to holding registers on the Modbus device.\nThis function writes the specified data to the holding registers starting from a given address.\n\nArgs:\n - slave_id: The RTU slave address.\n - data: A vector containing the values to write to holding registers.\n - addr: The starting address for writing holding registers.\n - timeout_ms: The timeout duration for the write operation.\n- A value of -1 makes the function block until the write is complete.\n- A value of 0 makes it non-blocking.\n- A positive value specifies the maximum time (in milliseconds) to wait.\n - device: The UART device to use. An empty string (\"\") indicates that the\ndefault device from the constructor will be used.\n - baudrate: The UART baud rate. A value of -1 signifies that the default baud rate\nfrom the constructor will be applied.\n\n\nReturns: int Returns the number of bytes written on success, or a value less than 0 on failure.\n" + }, + "args": [ + [ + "const uint32_t", + "slave_id", + null + ], + [ + "const std::vector&", + "data", + null + ], + [ + "const uint32_t", + "addr", + null + ], + [ + "const int", + "timeout_ms", + "-1" + ], + [ + "const std::string&", + "device", + "\"\"" + ], + [ + "const int", + "baudrate", + "-1" + ] + ], + "ret_type": "int", + "static": false, + "def": "int write_holding_registers(const uint32_t slave_id, const std::vector& data,\n const uint32_t addr, const int timeout_ms=-1,\n const std::string& device=\"\", const int baudrate=-1)", + "overload": [ + { + "type": "func", + "name": "write_holding_registers", + "doc": { + "brief": "Writes values to holding registers on the Modbus device.\\nThis function writes the specified data to the holding registers starting from a given address.", + "param": { + "device": "The UART device to use.", + "baudrate": "The UART baud rate.", + "slave_id": "The RTU slave address.", + "data": "A vector containing the values to write to holding registers.", + "addr": "The starting address for writing holding registers.", + "timeout_ms": "The timeout duration for the write operation.\n- A value of -1 makes the function block until the write is complete.\n- A value of 0 makes it non-blocking.\n- A positive value specifies the maximum time (in milliseconds) to wait." + }, + "return": "int Returns the number of bytes written on success, or a value less than 0 on failure.", + "maixcdk": "maix.comm.modbus.MasterRTU.write_holding_registers", + "py_doc": "Writes values to holding registers on the Modbus device.\nThis function writes the specified data to the holding registers starting from a given address.\n\nArgs:\n - device: The UART device to use.\n - baudrate: The UART baud rate.\n - slave_id: The RTU slave address.\n - data: A vector containing the values to write to holding registers.\n - addr: The starting address for writing holding registers.\n - timeout_ms: The timeout duration for the write operation.\n- A value of -1 makes the function block until the write is complete.\n- A value of 0 makes it non-blocking.\n- A positive value specifies the maximum time (in milliseconds) to wait.\n\n\nReturns: int Returns the number of bytes written on success, or a value less than 0 on failure.\n" + }, + "args": [ + [ + "const std::string&", + "device", + null + ], + [ + "const int", + "baudrate", + null + ], + [ + "const uint32_t", + "slave_id", + null + ], + [ + "const std::vector&", + "data", + null + ], + [ + "const uint32_t", + "addr", + null + ], + [ + "const int", + "timeout_ms", + "-1" + ] + ], + "ret_type": "int", + "static": true, + "def": "static int write_holding_registers(const std::string& device, const int baudrate,\n const uint32_t slave_id, const std::vector& data,\n const uint32_t addr, const int timeout_ms=-1)" + } + ] + } + }, + "def": "class MasterRTU final" + }, + "MasterTCP": { + "type": "class", + "name": "MasterTCP", + "doc": { + "brief": "Class for modbus Master", + "maixpy": "maix.comm.modbus.MasterTCP", + "py_doc": "Class for modbus Master" + }, + "members": { + "__init__": { + "type": "func", + "name": "MasterTCP", + "doc": { + "brief": "Construct a new MasterTCP object", + "param": { + "port": "Device tcp port." + }, + "maixpy": "maix.comm.modbus.MasterTCP.__init__", + "py_doc": "Construct a new MasterTCP object\n\nArgs:\n - port: Device tcp port.\n" + }, + "args": [ + [ + "const int", + "port", + "502" + ] + ], + "ret_type": null, + "static": false, + "def": "MasterTCP(const int port=502)" + }, + "read_coils": { + "type": "func", + "name": "read_coils", + "doc": { + "brief": "Reads coils from the Modbus device.\\nThis function reads a specified number of coils starting from a given address.\\nIt includes timeout settings to define how long to wait for a response.", + "param": { + "ip": "The TCP IP address.", + "addr": "The starting address for reading coils.", + "size": "The number of coils to read.", + "timeout_ms": "The timeout duration for waiting to receive a request.\n- A value of -1 makes the function block indefinitely until a request\nis received.\n- A value of 0 makes it non-blocking, returning immediately without\nwaiting for a request.\n- A positive value specifies the maximum time (in milliseconds) to wait\nfor a request before timing out.", + "port": "The TCP port. A value of -1 signifies that the default port\nfrom the constructor will be applied." + }, + "return": "std::vector/list[int] A vector containing the read coil values.", + "maixpy": "maix.comm.modbus.MasterTCP.read_coils", + "py_doc": "Reads coils from the Modbus device.\nThis function reads a specified number of coils starting from a given address.\nIt includes timeout settings to define how long to wait for a response.\n\nArgs:\n - ip: The TCP IP address.\n - addr: The starting address for reading coils.\n - size: The number of coils to read.\n - timeout_ms: The timeout duration for waiting to receive a request.\n- A value of -1 makes the function block indefinitely until a request\nis received.\n- A value of 0 makes it non-blocking, returning immediately without\nwaiting for a request.\n- A positive value specifies the maximum time (in milliseconds) to wait\nfor a request before timing out.\n - port: The TCP port. A value of -1 signifies that the default port\nfrom the constructor will be applied.\n\n\nReturns: std::vector/list[int] A vector containing the read coil values.\n" + }, + "args": [ + [ + "const std::string", + "ip", + null + ], + [ + "const uint32_t", + "addr", + null + ], + [ + "const uint32_t", + "size", + null + ], + [ + "const int", + "timeout_ms", + "-1" + ], + [ + "const int", + "port", + "-1" + ] + ], + "ret_type": "std::vector", + "static": false, + "def": "std::vector read_coils(const std::string ip, const uint32_t addr,\n const uint32_t size, const int timeout_ms=-1,\n const int port=-1)", + "overload": [ + { + "type": "func", + "name": "read_coils", + "doc": { + "brief": "Reads coils from the Modbus device.\\nThis function reads a specified number of coils starting from a given address.\\nIt includes timeout settings to define how long to wait for a response.", + "param": { + "ip": "The TCP IP address.", + "port": "The TCP port.", + "addr": "The starting address for reading coils.", + "size": "The number of coils to read.", + "timeout_ms": "The timeout duration for waiting to receive a request.\n- A value of -1 makes the function block indefinitely until a request\nis received.\n- A value of 0 makes it non-blocking, returning immediately without\nwaiting for a request.\n- A positive value specifies the maximum time (in milliseconds) to wait\nfor a request before timing out." + }, + "return": "std::vector/list[int] A vector containing the read coil values.", + "maixcdk": "maix.comm.modbus.MasterTCP.read_coils", + "py_doc": "Reads coils from the Modbus device.\nThis function reads a specified number of coils starting from a given address.\nIt includes timeout settings to define how long to wait for a response.\n\nArgs:\n - ip: The TCP IP address.\n - port: The TCP port.\n - addr: The starting address for reading coils.\n - size: The number of coils to read.\n - timeout_ms: The timeout duration for waiting to receive a request.\n- A value of -1 makes the function block indefinitely until a request\nis received.\n- A value of 0 makes it non-blocking, returning immediately without\nwaiting for a request.\n- A positive value specifies the maximum time (in milliseconds) to wait\nfor a request before timing out.\n\n\nReturns: std::vector/list[int] A vector containing the read coil values.\n" + }, + "args": [ + [ + "const std::string", + "ip", + null + ], + [ + "const int", + "port", + null + ], + [ + "const uint32_t", + "addr", + null + ], + [ + "const uint32_t", + "size", + null + ], + [ + "const int", + "timeout_ms", + "-1" + ] + ], + "ret_type": "std::vector", + "static": true, + "def": "static std::vector read_coils( const std::string ip, const int port,\n const uint32_t addr,\n const uint32_t size, const int timeout_ms=-1)" + } + ] + }, + "write_coils": { + "type": "func", + "name": "write_coils", + "doc": { + "brief": "Writes values to coils on the Modbus device.\\nThis function writes the specified data to the coils starting from a given address.", + "param": { + "ip": "The TCP IP address.", + "data": "A vector containing the coil values to write.", + "addr": "The starting address for writing coils.", + "timeout_ms": "The timeout duration for the write operation.\n- A value of -1 makes the function block until the write is complete.\n- A value of 0 makes it non-blocking.\n- A positive value specifies the maximum time (in milliseconds) to wait.", + "port": "The TCP port. A value of -1 signifies that the default port\nfrom the constructor will be applied." + }, + "return": "int Returns the number of bytes written on success, or a value less than 0 on failure.", + "maixpy": "maix.comm.modbus.MasterTCP.write_coils", + "py_doc": "Writes values to coils on the Modbus device.\nThis function writes the specified data to the coils starting from a given address.\n\nArgs:\n - ip: The TCP IP address.\n - data: A vector containing the coil values to write.\n - addr: The starting address for writing coils.\n - timeout_ms: The timeout duration for the write operation.\n- A value of -1 makes the function block until the write is complete.\n- A value of 0 makes it non-blocking.\n- A positive value specifies the maximum time (in milliseconds) to wait.\n - port: The TCP port. A value of -1 signifies that the default port\nfrom the constructor will be applied.\n\n\nReturns: int Returns the number of bytes written on success, or a value less than 0 on failure.\n" + }, + "args": [ + [ + "const std::string", + "ip", + null + ], + [ + "const std::vector&", + "data", + null + ], + [ + "const uint32_t", + "addr", + null + ], + [ + "const int", + "timeout_ms", + "-1" + ], + [ + "const int", + "port", + "-1" + ] + ], + "ret_type": "int", + "static": false, + "def": "int write_coils(const std::string ip, const std::vector& data,\n const uint32_t addr, const int timeout_ms=-1,\n const int port=-1)", + "overload": [ + { + "type": "func", + "name": "write_coils", + "doc": { + "brief": "Writes values to coils on the Modbus device.\\nThis function writes the specified data to the coils starting from a given address.", + "param": { + "ip": "The TCP IP address.", + "port": "The TCP port.", + "data": "A vector containing the coil values to write.", + "addr": "The starting address for writing coils.", + "timeout_ms": "The timeout duration for the write operation.\n- A value of -1 makes the function block until the write is complete.\n- A value of 0 makes it non-blocking.\n- A positive value specifies the maximum time (in milliseconds) to wait." + }, + "return": "int Returns the number of bytes written on success, or a value less than 0 on failure.", + "maixcdk": "maix.comm.modbus.MasterTCP.write_coils", + "py_doc": "Writes values to coils on the Modbus device.\nThis function writes the specified data to the coils starting from a given address.\n\nArgs:\n - ip: The TCP IP address.\n - port: The TCP port.\n - data: A vector containing the coil values to write.\n - addr: The starting address for writing coils.\n - timeout_ms: The timeout duration for the write operation.\n- A value of -1 makes the function block until the write is complete.\n- A value of 0 makes it non-blocking.\n- A positive value specifies the maximum time (in milliseconds) to wait.\n\n\nReturns: int Returns the number of bytes written on success, or a value less than 0 on failure.\n" + }, + "args": [ + [ + "const std::string", + "ip", + null + ], + [ + "const int", + "port", + null + ], + [ + "const std::vector&", + "data", + null + ], + [ + "const uint32_t", + "addr", + null + ], + [ + "const int", + "timeout_ms", + "-1" + ] + ], + "ret_type": "int", + "static": true, + "def": "static int write_coils(const std::string ip, const int port,\n const std::vector& data,\n const uint32_t addr, const int timeout_ms=-1)" + } + ] + }, + "read_discrete_input": { + "type": "func", + "name": "read_discrete_input", + "doc": { + "brief": "Reads discrete inputs from the Modbus device.\\nThis function reads a specified number of discrete inputs starting from a given address.", + "param": { + "ip": "The TCP IP address.", + "addr": "The starting address for reading discrete inputs.", + "size": "The number of discrete inputs to read.", + "timeout_ms": "The timeout duration for the write operation.\n- A value of -1 makes the function block until the write is complete.\n- A value of 0 makes it non-blocking.\n- A positive value specifies the maximum time (in milliseconds) to wait.", + "port": "The TCP port. A value of -1 signifies that the default port\nfrom the constructor will be applied." + }, + "return": "std::vector/list[int] A vector containing the read discrete input values.", + "maixpy": "maix.comm.modbus.MasterTCP.read_discrete_input", + "py_doc": "Reads discrete inputs from the Modbus device.\nThis function reads a specified number of discrete inputs starting from a given address.\n\nArgs:\n - ip: The TCP IP address.\n - addr: The starting address for reading discrete inputs.\n - size: The number of discrete inputs to read.\n - timeout_ms: The timeout duration for the write operation.\n- A value of -1 makes the function block until the write is complete.\n- A value of 0 makes it non-blocking.\n- A positive value specifies the maximum time (in milliseconds) to wait.\n - port: The TCP port. A value of -1 signifies that the default port\nfrom the constructor will be applied.\n\n\nReturns: std::vector/list[int] A vector containing the read discrete input values.\n" + }, + "args": [ + [ + "const std::string", + "ip", + null + ], + [ + "const uint32_t", + "addr", + null + ], + [ + "const uint32_t", + "size", + null + ], + [ + "const int", + "timeout_ms", + "-1" + ], + [ + "const int", + "port", + "-1" + ] + ], + "ret_type": "std::vector", + "static": false, + "def": "std::vector read_discrete_input(const std::string ip, const uint32_t addr,\n const uint32_t size, const int timeout_ms=-1,\n const int port=-1)", + "overload": [ + { + "type": "func", + "name": "read_discrete_input", + "doc": { + "brief": "Reads discrete inputs from the Modbus device.\\nThis function reads a specified number of discrete inputs starting from a given address.", + "param": { + "ip": "The TCP IP address.", + "port": "The TCP port.", + "addr": "The starting address for reading discrete inputs.", + "size": "The number of discrete inputs to read.", + "timeout_ms": "The timeout duration for the write operation.\n- A value of -1 makes the function block until the write is complete.\n- A value of 0 makes it non-blocking.\n- A positive value specifies the maximum time (in milliseconds) to wait." + }, + "return": "std::vector/list[int] A vector containing the read discrete input values.", + "maixcdk": "maix.comm.modbus.MasterTCP.read_discrete_input", + "py_doc": "Reads discrete inputs from the Modbus device.\nThis function reads a specified number of discrete inputs starting from a given address.\n\nArgs:\n - ip: The TCP IP address.\n - port: The TCP port.\n - addr: The starting address for reading discrete inputs.\n - size: The number of discrete inputs to read.\n - timeout_ms: The timeout duration for the write operation.\n- A value of -1 makes the function block until the write is complete.\n- A value of 0 makes it non-blocking.\n- A positive value specifies the maximum time (in milliseconds) to wait.\n\n\nReturns: std::vector/list[int] A vector containing the read discrete input values.\n" + }, + "args": [ + [ + "const std::string", + "ip", + null + ], + [ + "const int", + "port", + null + ], + [ + "const uint32_t", + "addr", + null + ], + [ + "const uint32_t", + "size", + null + ], + [ + "const int", + "timeout_ms", + "-1" + ] + ], + "ret_type": "std::vector", + "static": true, + "def": "static std::vector read_discrete_input(const std::string ip, const int port,\n const uint32_t addr,\n const uint32_t size, const int timeout_ms=-1)" + } + ] + }, + "read_input_registers": { + "type": "func", + "name": "read_input_registers", + "doc": { + "brief": "Reads input registers from the Modbus device.\\nThis function reads a specified number of input registers starting from a given address.", + "param": { + "ip": "The TCP IP address.", + "addr": "The starting address for reading input registers.", + "size": "The number of input registers to read.", + "timeout_ms": "The timeout duration for the write operation.\n- A value of -1 makes the function block until the write is complete.\n- A value of 0 makes it non-blocking.\n- A positive value specifies the maximum time (in milliseconds) to wait.", + "port": "The TCP port. A value of -1 signifies that the default port\nfrom the constructor will be applied." + }, + "return": "std::vector/list[int] A vector containing the read input register values.", + "maixpy": "maix.comm.modbus.MasterTCP.read_input_registers", + "py_doc": "Reads input registers from the Modbus device.\nThis function reads a specified number of input registers starting from a given address.\n\nArgs:\n - ip: The TCP IP address.\n - addr: The starting address for reading input registers.\n - size: The number of input registers to read.\n - timeout_ms: The timeout duration for the write operation.\n- A value of -1 makes the function block until the write is complete.\n- A value of 0 makes it non-blocking.\n- A positive value specifies the maximum time (in milliseconds) to wait.\n - port: The TCP port. A value of -1 signifies that the default port\nfrom the constructor will be applied.\n\n\nReturns: std::vector/list[int] A vector containing the read input register values.\n" + }, + "args": [ + [ + "const std::string", + "ip", + null + ], + [ + "const uint32_t", + "addr", + null + ], + [ + "const uint32_t", + "size", + null + ], + [ + "const int", + "timeout_ms", + "-1" + ], + [ + "const int", + "port", + "-1" + ] + ], + "ret_type": "std::vector", + "static": false, + "def": "std::vector read_input_registers(const std::string ip, const uint32_t addr,\n const uint32_t size, const int timeout_ms=-1,\n const int port=-1)", + "overload": [ + { + "type": "func", + "name": "read_input_registers", + "doc": { + "brief": "Reads input registers from the Modbus device.\\nThis function reads a specified number of input registers starting from a given address.", + "param": { + "ip": "The TCP IP address.", + "port": "The TCP port.", + "addr": "The starting address for reading input registers.", + "size": "The number of input registers to read.", + "timeout_ms": "The timeout duration for the write operation.\n- A value of -1 makes the function block until the write is complete.\n- A value of 0 makes it non-blocking.\n- A positive value specifies the maximum time (in milliseconds) to wait." + }, + "return": "std::vector/list[int] A vector containing the read input register values.", + "maixcdk": "maix.comm.modbus.MasterTCP.read_input_registers", + "py_doc": "Reads input registers from the Modbus device.\nThis function reads a specified number of input registers starting from a given address.\n\nArgs:\n - ip: The TCP IP address.\n - port: The TCP port.\n - addr: The starting address for reading input registers.\n - size: The number of input registers to read.\n - timeout_ms: The timeout duration for the write operation.\n- A value of -1 makes the function block until the write is complete.\n- A value of 0 makes it non-blocking.\n- A positive value specifies the maximum time (in milliseconds) to wait.\n\n\nReturns: std::vector/list[int] A vector containing the read input register values.\n" + }, + "args": [ + [ + "const std::string", + "ip", + null + ], + [ + "const int", + "port", + null + ], + [ + "const uint32_t", + "addr", + null + ], + [ + "const uint32_t", + "size", + null + ], + [ + "const int", + "timeout_ms", + "-1" + ] + ], + "ret_type": "std::vector", + "static": true, + "def": "static std::vector read_input_registers(const std::string ip, const int port,\n const uint32_t addr,\n const uint32_t size, const int timeout_ms=-1)" + } + ] + }, + "read_holding_registers": { + "type": "func", + "name": "read_holding_registers", + "doc": { + "brief": "Reads holding registers from the Modbus device.\\nThis function reads a specified number of holding registers starting from a given address.", + "param": { + "ip": "The TCP IP address.", + "addr": "The starting address for reading holding registers.", + "size": "The number of holding registers to read.", + "timeout_ms": "The timeout duration for the write operation.\n- A value of -1 makes the function block until the write is complete.\n- A value of 0 makes it non-blocking.\n- A positive value specifies the maximum time (in milliseconds) to wait.", + "port": "The TCP port. A value of -1 signifies that the default port\nfrom the constructor will be applied." + }, + "return": "std::vector/list[int] A vector containing the read holding register values.", + "maixpy": "maix.comm.modbus.MasterTCP.read_holding_registers", + "py_doc": "Reads holding registers from the Modbus device.\nThis function reads a specified number of holding registers starting from a given address.\n\nArgs:\n - ip: The TCP IP address.\n - addr: The starting address for reading holding registers.\n - size: The number of holding registers to read.\n - timeout_ms: The timeout duration for the write operation.\n- A value of -1 makes the function block until the write is complete.\n- A value of 0 makes it non-blocking.\n- A positive value specifies the maximum time (in milliseconds) to wait.\n - port: The TCP port. A value of -1 signifies that the default port\nfrom the constructor will be applied.\n\n\nReturns: std::vector/list[int] A vector containing the read holding register values.\n" + }, + "args": [ + [ + "const std::string", + "ip", + null + ], + [ + "const uint32_t", + "addr", + null + ], + [ + "const uint32_t", + "size", + null + ], + [ + "const int", + "timeout_ms", + "-1" + ], + [ + "const int", + "port", + "-1" + ] + ], + "ret_type": "std::vector", + "static": false, + "def": "std::vector read_holding_registers(const std::string ip, const uint32_t addr,\n const uint32_t size, const int timeout_ms=-1,\n const int port=-1)", + "overload": [ + { + "type": "func", + "name": "read_holding_registers", + "doc": { + "brief": "Reads holding registers from the Modbus device.\\nThis function reads a specified number of holding registers starting from a given address.", + "param": { + "ip": "The TCP IP address.", + "port": "The TCP port.", + "addr": "The starting address for reading holding registers.", + "size": "The number of holding registers to read.", + "timeout_ms": "The timeout duration for the write operation.\n- A value of -1 makes the function block until the write is complete.\n- A value of 0 makes it non-blocking.\n- A positive value specifies the maximum time (in milliseconds) to wait." + }, + "return": "std::vector/list[int] A vector containing the read holding register values.", + "maixcdk": "maix.comm.modbus.MasterTCP.read_holding_registers", + "py_doc": "Reads holding registers from the Modbus device.\nThis function reads a specified number of holding registers starting from a given address.\n\nArgs:\n - ip: The TCP IP address.\n - port: The TCP port.\n - addr: The starting address for reading holding registers.\n - size: The number of holding registers to read.\n - timeout_ms: The timeout duration for the write operation.\n- A value of -1 makes the function block until the write is complete.\n- A value of 0 makes it non-blocking.\n- A positive value specifies the maximum time (in milliseconds) to wait.\n\n\nReturns: std::vector/list[int] A vector containing the read holding register values.\n" + }, + "args": [ + [ + "const std::string", + "ip", + null + ], + [ + "const int", + "port", + null + ], + [ + "const uint32_t", + "addr", + null + ], + [ + "const uint32_t", + "size", + null + ], + [ + "const int", + "timeout_ms", + "-1" + ] + ], + "ret_type": "std::vector", + "static": true, + "def": "static std::vector read_holding_registers(const std::string ip, const int port,\n const uint32_t addr,\n const uint32_t size, const int timeout_ms=-1)" + } + ] + }, + "write_holding_registers": { + "type": "func", + "name": "write_holding_registers", + "doc": { + "brief": "Writes values to holding registers on the Modbus device.\\nThis function writes the specified data to the holding registers starting from a given address.", + "param": { + "ip": "The TCP IP address.", + "data": "A vector containing the values to write to holding registers.", + "addr": "The starting address for writing holding registers.", + "timeout_ms": "The timeout duration for the write operation.\n- A value of -1 makes the function block until the write is complete.\n- A value of 0 makes it non-blocking.\n- A positive value specifies the maximum time (in milliseconds) to wait.", + "port": "The TCP port. A value of -1 signifies that the default port\nfrom the constructor will be applied." + }, + "return": "int Returns the number of bytes written on success, or a value less than 0 on failure.", + "maixpy": "maix.comm.modbus.MasterTCP.write_holding_registers", + "py_doc": "Writes values to holding registers on the Modbus device.\nThis function writes the specified data to the holding registers starting from a given address.\n\nArgs:\n - ip: The TCP IP address.\n - data: A vector containing the values to write to holding registers.\n - addr: The starting address for writing holding registers.\n - timeout_ms: The timeout duration for the write operation.\n- A value of -1 makes the function block until the write is complete.\n- A value of 0 makes it non-blocking.\n- A positive value specifies the maximum time (in milliseconds) to wait.\n - port: The TCP port. A value of -1 signifies that the default port\nfrom the constructor will be applied.\n\n\nReturns: int Returns the number of bytes written on success, or a value less than 0 on failure.\n" + }, + "args": [ + [ + "const std::string", + "ip", + null + ], + [ + "const std::vector&", + "data", + null + ], + [ + "const uint32_t", + "addr", + null + ], + [ + "const int", + "timeout_ms", + "-1" + ], + [ + "const int", + "port", + "-1" + ] + ], + "ret_type": "int", + "static": false, + "def": "int write_holding_registers(const std::string ip, const std::vector& data,\n const uint32_t addr, const int timeout_ms=-1,\n const int port=-1)", + "overload": [ + { + "type": "func", + "name": "write_holding_registers", + "doc": { + "brief": "Writes values to holding registers on the Modbus device.\\nThis function writes the specified data to the holding registers starting from a given address.", + "param": { + "ip": "The TCP IP address.", + "port": "The TCP port.", + "data": "A vector containing the values to write to holding registers.", + "addr": "The starting address for writing holding registers.", + "timeout_ms": "The timeout duration for the write operation.\n- A value of -1 makes the function block until the write is complete.\n- A value of 0 makes it non-blocking.\n- A positive value specifies the maximum time (in milliseconds) to wait." + }, + "return": "int Returns the number of bytes written on success, or a value less than 0 on failure.", + "maixcdk": "maix.comm.modbus.MasterTCP.write_holding_registers", + "py_doc": "Writes values to holding registers on the Modbus device.\nThis function writes the specified data to the holding registers starting from a given address.\n\nArgs:\n - ip: The TCP IP address.\n - port: The TCP port.\n - data: A vector containing the values to write to holding registers.\n - addr: The starting address for writing holding registers.\n - timeout_ms: The timeout duration for the write operation.\n- A value of -1 makes the function block until the write is complete.\n- A value of 0 makes it non-blocking.\n- A positive value specifies the maximum time (in milliseconds) to wait.\n\n\nReturns: int Returns the number of bytes written on success, or a value less than 0 on failure.\n" + }, + "args": [ + [ + "const std::string", + "ip", + null + ], + [ + "const int", + "port", + null + ], + [ + "const std::vector&", + "data", + null + ], + [ + "const uint32_t", + "addr", + null + ], + [ + "const int", + "timeout_ms", + "-1" + ] + ], + "ret_type": "int", + "static": true, + "def": "static int write_holding_registers(const std::string ip, const int port,\n const std::vector& data,\n const uint32_t addr, const int timeout_ms=-1)" + } + ] + } + }, + "def": "class MasterTCP final" + } + }, + "auto_add": true + }, + "add_default_comm_listener": { + "type": "func", + "name": "add_default_comm_listener", + "doc": { + "brief": "Add default CommProtocol listener.\\nWhen the application uses this port, the listening thread will immediately\\nrelease the port resources and exit. If you need to start the default listening thread again,\\nplease release the default port resources and then call this function.", + "maixpy": "maix.comm.add_default_comm_listener", + "py_doc": "Add default CommProtocol listener.\nWhen the application uses this port, the listening thread will immediately\nrelease the port resources and exit. If you need to start the default listening thread again,\nplease release the default port resources and then call this function." + }, + "args": [], + "ret_type": "void", + "static": false, + "def": "void add_default_comm_listener()" + }, + "rm_default_comm_listener": { + "type": "func", + "name": "rm_default_comm_listener", + "doc": { + "brief": "Remove default CommProtocol listener.", + "return": "bool type.", + "maixpy": "maix.comm.rm_default_comm_listener", + "py_doc": "Remove default CommProtocol listener.\n\nReturns: bool type.\n" + }, + "args": [], + "ret_type": "bool", + "static": false, + "def": "bool rm_default_comm_listener()" + }, + "CommProtocol": { + "type": "class", + "name": "CommProtocol", + "doc": { + "brief": "Class for communication protocol", + "maixpy": "maix.comm.CommProtocol", + "py_doc": "Class for communication protocol" + }, + "members": { + "CommProtocol": { + "type": "func", + "name": "CommProtocol", + "doc": { + "brief": "Construct a new CommProtocol object", + "param": { + "buff_size": "buffer size, default to 1024 bytes" + }, + "maixpy": "maix.comm.CommProtocol.__init__", + "maixcdk": "maix.comm.CommProtocol.CommProtocol", + "py_doc": "Construct a new CommProtocol object\n\nArgs:\n - buff_size: buffer size, default to 1024 bytes\n" + }, + "args": [ + [ + "int", + "buff_size", + "1024" + ], + [ + "uint32_t", + "header", + "maix::protocol::HEADER" + ] + ], + "ret_type": null, + "static": false, + "def": "CommProtocol(int buff_size = 1024, uint32_t header=maix::protocol::HEADER)" + }, + "get_msg": { + "type": "func", + "name": "get_msg", + "doc": { + "brief": "Read data to buffer, and try to decode it as maix.protocol.MSG object", + "param": { + "timeout": "unit ms, 0 means return immediatly, -1 means block util have msg, >0 means block until have msg or timeout." + }, + "return": "decoded data, if nullptr, means no valid frame found.\nAttentioin, delete it after use in C++.", + "maixpy": "maix.comm.CommProtocol.get_msg", + "py_doc": "Read data to buffer, and try to decode it as maix.protocol.MSG object\n\nArgs:\n - timeout: unit ms, 0 means return immediatly, -1 means block util have msg, >0 means block until have msg or timeout.\n\n\nReturns: decoded data, if nullptr, means no valid frame found.\nAttentioin, delete it after use in C++.\n" + }, + "args": [ + [ + "int", + "timeout", + "0" + ] + ], + "ret_type": "protocol::MSG*", + "static": false, + "def": "protocol::MSG *get_msg(int timeout = 0)" + }, + "resp_ok": { + "type": "func", + "name": "resp_ok", + "doc": { + "brief": "Send response ok(success) message", + "param": { + "buff": "output buffer", + "buff_len": "output buffer length", + "cmd": "CMD value", + "body": "response body, can be null", + "body_len": "response body length, can be 0" + }, + "return": "send response error code, maix.err.Err type", + "maixcdk": "maix.comm.CommProtocol.resp_ok", + "py_doc": "Send response ok(success) message\n\nArgs:\n - buff: output buffer\n - buff_len: output buffer length\n - cmd: CMD value\n - body: response body, can be null\n - body_len: response body length, can be 0\n\n\nReturns: send response error code, maix.err.Err type\n" + }, + "args": [ + [ + "uint8_t *", + "buff", + null + ], + [ + "int", + "buff_len", + null + ], + [ + "uint8_t", + "cmd", + null + ], + [ + "uint8_t *", + "body", + "nullptr" + ], + [ + "int", + "body_len", + "0" + ] + ], + "ret_type": "err::Err", + "static": false, + "def": "err::Err resp_ok(uint8_t *buff, int buff_len, uint8_t cmd, uint8_t *body = nullptr, int body_len = 0)", + "overload": [ + { + "type": "func", + "name": "resp_ok", + "doc": { + "brief": "Send response ok(success) message", + "param": { + "cmd": "CMD value", + "body": "response body, can be null", + "body_len": "response body length, can be 0" + }, + "return": "encoded data, if nullptr, means error, and the error code is -err.Err.\nAttentioin, delete it after use in C++.", + "maixcdk": "maix.comm.CommProtocol.resp_ok", + "py_doc": "Send response ok(success) message\n\nArgs:\n - cmd: CMD value\n - body: response body, can be null\n - body_len: response body length, can be 0\n\n\nReturns: encoded data, if nullptr, means error, and the error code is -err.Err.\nAttentioin, delete it after use in C++.\n" + }, + "args": [ + [ + "uint8_t", + "cmd", + null + ], + [ + "uint8_t *", + "body", + "nullptr" + ], + [ + "int", + "body_len", + "0" + ] + ], + "ret_type": "err::Err", + "static": false, + "def": "err::Err resp_ok(uint8_t cmd, uint8_t *body = nullptr, int body_len = 0)" + }, + { + "type": "func", + "name": "resp_ok", + "doc": { + "brief": "Send response ok(success) message", + "param": { + "cmd": "CMD value", + "body": "response body, can be null" + }, + "return": "encoded data, if nullptr, means error, and the error code is -err.Err.\nAttentioin, delete it after use in C++.", + "maixpy": "maix.comm.CommProtocol.resp_ok", + "py_doc": "Send response ok(success) message\n\nArgs:\n - cmd: CMD value\n - body: response body, can be null\n\n\nReturns: encoded data, if nullptr, means error, and the error code is -err.Err.\nAttentioin, delete it after use in C++.\n" + }, + "args": [ + [ + "uint8_t", + "cmd", + null + ], + [ + "Bytes *", + "body", + "nullptr" + ] + ], + "ret_type": "err::Err", + "static": false, + "def": "err::Err resp_ok(uint8_t cmd, Bytes *body = nullptr)" + } + ] + }, + "report": { + "type": "func", + "name": "report", + "doc": { + "brief": "Send report message", + "param": { + "buff": "output buffer", + "buff_len": "output buffer length", + "cmd": "CMD value", + "body": "report body, can be null", + "body_len": "report body length, can be 0" + }, + "return": "send report error code, maix.err.Err type", + "maixcdk": "maix.comm.CommProtocol.report", + "py_doc": "Send report message\n\nArgs:\n - buff: output buffer\n - buff_len: output buffer length\n - cmd: CMD value\n - body: report body, can be null\n - body_len: report body length, can be 0\n\n\nReturns: send report error code, maix.err.Err type\n" + }, + "args": [ + [ + "uint8_t *", + "buff", + null + ], + [ + "int", + "buff_len", + null + ], + [ + "uint8_t", + "cmd", + null + ], + [ + "uint8_t *", + "body", + "nullptr" + ], + [ + "int", + "body_len", + "0" + ] + ], + "ret_type": "err::Err", + "static": false, + "def": "err::Err report(uint8_t *buff, int buff_len, uint8_t cmd, uint8_t *body = nullptr, int body_len = 0)", + "overload": [ + { + "type": "func", + "name": "report", + "doc": { + "brief": "Send report message", + "param": { + "cmd": "CMD value", + "body": "report body, can be null", + "body_len": "report body length, can be 0" + }, + "return": "encoded data, if nullptr, means error, and the error code is -err.Err.\nAttentioin, delete it after use in C++.", + "maixcdk": "maix.comm.CommProtocol.report", + "py_doc": "Send report message\n\nArgs:\n - cmd: CMD value\n - body: report body, can be null\n - body_len: report body length, can be 0\n\n\nReturns: encoded data, if nullptr, means error, and the error code is -err.Err.\nAttentioin, delete it after use in C++.\n" + }, + "args": [ + [ + "uint8_t", + "cmd", + null + ], + [ + "uint8_t *", + "body", + "nullptr" + ], + [ + "int", + "body_len", + "0" + ] + ], + "ret_type": "err::Err", + "static": false, + "def": "err::Err report(uint8_t cmd, uint8_t *body = nullptr, int body_len = 0)" + }, + { + "type": "func", + "name": "report", + "doc": { + "brief": "Send report message", + "param": { + "cmd": "CMD value", + "body": "report body, can be null" + }, + "return": "encoded data, if nullptr, means error, and the error code is -err.Err.\nAttentioin, delete it after use in C++.", + "maixpy": "maix.comm.CommProtocol.report", + "py_doc": "Send report message\n\nArgs:\n - cmd: CMD value\n - body: report body, can be null\n\n\nReturns: encoded data, if nullptr, means error, and the error code is -err.Err.\nAttentioin, delete it after use in C++.\n" + }, + "args": [ + [ + "uint8_t", + "cmd", + null + ], + [ + "Bytes *", + "body", + "nullptr" + ] + ], + "ret_type": "err::Err", + "static": false, + "def": "err::Err report(uint8_t cmd, Bytes *body = nullptr)" + } + ] + }, + "resp_err": { + "type": "func", + "name": "resp_err", + "doc": { + "brief": "Encode response error message to buffer", + "param": { + "buff": "output buffer", + "buff_len": "output buffer length", + "cmd": "CMD value", + "code": "error code", + "msg": "error message" + }, + "return": "send response error code, maix.err.Err type", + "maixcdk": "maix.comm.CommProtocol.resp_err", + "py_doc": "Encode response error message to buffer\n\nArgs:\n - buff: output buffer\n - buff_len: output buffer length\n - cmd: CMD value\n - code: error code\n - msg: error message\n\n\nReturns: send response error code, maix.err.Err type\n" + }, + "args": [ + [ + "uint8_t *", + "buff", + null + ], + [ + "int", + "buff_len", + null + ], + [ + "uint8_t", + "cmd", + null + ], + [ + "err::Err", + "code", + null + ], + [ + "const std::string &", + "msg", + null + ] + ], + "ret_type": "err::Err", + "static": false, + "def": "err::Err resp_err(uint8_t *buff, int buff_len, uint8_t cmd, err::Err code, const std::string &msg)", + "overload": [ + { + "type": "func", + "name": "resp_err", + "doc": { + "brief": "Encode response error message to buffer", + "param": { + "cmd": "CMD value", + "code": "error code", + "msg": "error message" + }, + "return": "encoded data, if nullptr, means error, and the error code is -err.Err.\nAttentioin, delete it after use in C++.", + "maixpy": "maix.comm.CommProtocol.resp_err", + "py_doc": "Encode response error message to buffer\n\nArgs:\n - cmd: CMD value\n - code: error code\n - msg: error message\n\n\nReturns: encoded data, if nullptr, means error, and the error code is -err.Err.\nAttentioin, delete it after use in C++.\n" + }, + "args": [ + [ + "uint8_t", + "cmd", + null + ], + [ + "err::Err", + "code", + null + ], + [ + "const std::string &", + "msg", + null + ] + ], + "ret_type": "err::Err", + "static": false, + "def": "err::Err resp_err(uint8_t cmd, err::Err code, const std::string &msg)" + } + ] + } + }, + "def": "class CommProtocol" + }, + "CommBase": { + "type": "class", + "name": "CommBase", + "doc": { + "brief": "Communication base class, all communication methods should implement this interface", + "maixcdk": "maix.comm.CommBase", + "py_doc": "Communication base class, all communication methods should implement this interface" + }, + "members": { + "open": { + "type": "func", + "name": "open", + "doc": { + "brief": "Open device, if already opened, do nothing and return err.ERR_NONE.", + "return": "open device error code, err.Err type.", + "maixcdk": "maix.comm.CommBase.open", + "py_doc": "Open device, if already opened, do nothing and return err.ERR_NONE.\n\nReturns: open device error code, err.Err type.\n" + }, + "args": [], + "ret_type": "virtual err::Err", + "static": false, + "def": "virtual err::Err open()" + }, + "close": { + "type": "func", + "name": "close", + "doc": { + "brief": "Close device, if already closed, do nothing and return err.ERR_NONE.", + "return": "close device error code, err.Err type.", + "maixcdk": "maix.comm.CommBase.close", + "py_doc": "Close device, if already closed, do nothing and return err.ERR_NONE.\n\nReturns: close device error code, err.Err type.\n" + }, + "args": [], + "ret_type": "virtual err::Err", + "static": false, + "def": "virtual err::Err close()" + }, + "is_open": { + "type": "func", + "name": "is_open", + "doc": { + "brief": "Check if opened", + "return": "true if opened, else false.", + "maixcdk": "maix.comm.CommBase.is_open", + "py_doc": "Check if opened\n\nReturns: true if opened, else false.\n" + }, + "args": [], + "ret_type": "virtual bool", + "static": false, + "def": "virtual bool is_open()" + }, + "write": { + "type": "func", + "name": "write", + "doc": { + "brief": "Send data to device", + "param": { + "buff": "data buffer", + "len": "data length need to send, the len must <= buff length." + }, + "return": "sent data length, < 0 means error, value is -err.Err.", + "maixcdk": "maix.comm.CommBase.write", + "py_doc": "Send data to device\n\nArgs:\n - buff: data buffer\n - len: data length need to send, the len must <= buff length.\n\n\nReturns: sent data length, < 0 means error, value is -err.Err.\n" + }, + "args": [ + [ + "const uint8_t *", + "buff", + null + ], + [ + "int", + "len", + null + ] + ], + "ret_type": "virtual int", + "static": false, + "def": "virtual int write(const uint8_t *buff, int len)", + "overload": [ + { + "type": "func", + "name": "write", + "doc": { + "brief": "Send data to uart", + "param": { + "data": "direction [in], data to send, bytes type. If you want to send str type, use str.encode() to convert." + }, + "return": "sent length, int type, if < 0 means error, value is -err.Err.", + "maixcdk": "maix.comm.CommBase.write", + "py_doc": "Send data to uart\n\nArgs:\n - data: direction [in], data to send, bytes type. If you want to send str type, use str.encode() to convert.\n\n\nReturns: sent length, int type, if < 0 means error, value is -err.Err.\n" + }, + "args": [ + [ + "Bytes &", + "data", + null + ] + ], + "ret_type": "virtual int", + "static": false, + "def": "virtual int write(Bytes &data)" + } + ] + }, + "read": { + "type": "func", + "name": "read", + "doc": { + "brief": "Receive data", + "param": { + "buff": "data buffer to store received data", + "buff_len": "data buffer length", + "recv_len": "max data length want to receive, default -1.\n-1 means read data in uart receive buffer.\n>0 means read recv_len data want to receive.\nother values is invalid.", + "timeout": "unit ms, timeout to receive data, default 0.\n0 means read data in uart receive buffer and return immediately,\n-1 means block until read recv_len data,\n>0 means block until read recv_len data or timeout." + }, + "return": "received data length, < 0 means error, value is -err.Err.", + "maixcdk": "maix.comm.CommBase.read", + "py_doc": "Receive data\n\nArgs:\n - buff: data buffer to store received data\n - buff_len: data buffer length\n - recv_len: max data length want to receive, default -1.\n-1 means read data in uart receive buffer.\n>0 means read recv_len data want to receive.\nother values is invalid.\n - timeout: unit ms, timeout to receive data, default 0.\n0 means read data in uart receive buffer and return immediately,\n-1 means block until read recv_len data,\n>0 means block until read recv_len data or timeout.\n\n\nReturns: received data length, < 0 means error, value is -err.Err.\n" + }, + "args": [ + [ + "uint8_t *", + "buff", + null + ], + [ + "int", + "buff_len", + null + ], + [ + "int", + "recv_len", + null + ], + [ + "int", + "timeout", + null + ] + ], + "ret_type": "virtual int", + "static": false, + "def": "virtual int read(uint8_t *buff, int buff_len, int recv_len, int timeout)", + "overload": [ + { + "type": "func", + "name": "read", + "doc": { + "brief": "Recv data from uart", + "param": { + "len": "max data length want to receive, default -1.\n-1 means read data in uart receive buffer.\n>0 means read len data want to receive.\nother values is invalid.", + "timeout": "unit ms, timeout to receive data, default 0.\n0 means read data in uart receive buffer and return immediately,\n-1 means block until read len data,\n>0 means block until read len data or timeout." + }, + "return": "received data, bytes type.", + "maixcdk": "maix.comm.CommBase.read", + "py_doc": "Recv data from uart\n\nArgs:\n - len: max data length want to receive, default -1.\n-1 means read data in uart receive buffer.\n>0 means read len data want to receive.\nother values is invalid.\n - timeout: unit ms, timeout to receive data, default 0.\n0 means read data in uart receive buffer and return immediately,\n-1 means block until read len data,\n>0 means block until read len data or timeout.\n\n\nReturns: received data, bytes type.\n" + }, + "args": [ + [ + "int", + "len", + null + ], + [ + "int", + "timeout", + null + ] + ], + "ret_type": "virtual Bytes*", + "static": false, + "def": "virtual Bytes *read(int len, int timeout)" + } + ] + } + }, + "def": "class CommBase" + } + }, + "auto_add": true + }, + "modbus": { + "type": "module", + "doc": { + "brief": "maix.modbus module" + }, + "members": { + "Slave": { + "type": "module", + "doc": { + "brief": "maix.modbus.Slave module" + }, + "members": { + "__init__": { + "type": "func", + "name": "Slave", + "doc": { + "brief": "Constructor for creating a Modbus Slave instance with specified registers.\\nThis constructor initializes a Modbus Slave using the provided mode and connection\\nparameters. It also allows for defining register information through a\\n`Registers` object, enabling easier management of multiple registers at once.", + "param": { + "mode": "Specifies the communication mode: RTU or TCP.", + "ip_or_device": "The UART device name if using RTU mode.\nIf TCP mode is chosen, this parameter is ignored.", + "registers": "A Registers object that holds starting addresses and sizes\nfor coils, discrete inputs, holding registers, and input registers.\nThis allows the user to set up the Slave's register configuration\nin a structured manner.", + "rtu_baud": "The baud rate for RTU communication.\nSupported rates include: 110, 300, 600, 1200, 2400, 4800,\n9600, 19200, 38400, 57600, 115200, 230400, 460800,\n500000, 576000, 921600, 1000000, 1152000, 1500000,\n2500000, 3000000, 3500000, 4000000.\nDefault is 115200. Ensure that the selected baud rate\nis supported by the underlying hardware and libmodbus.", + "rtu_slave": "The RTU slave address. Ignored in TCP mode. Default is 1.", + "tcp_port": "The port used for TCP communication. Ignored in RTU mode. Default is 502.", + "debug": "A boolean flag to enable or disable debug mode. Default is false." + }, + "see": "modbus.Mode for valid modes.", + "maixcdk": "maix.modbus.Slave.__init__", + "py_doc": "Constructor for creating a Modbus Slave instance with specified registers.\nThis constructor initializes a Modbus Slave using the provided mode and connection\nparameters. It also allows for defining register information through a\n`Registers` object, enabling easier management of multiple registers at once.\n\nArgs:\n - mode: Specifies the communication mode: RTU or TCP.\n - ip_or_device: The UART device name if using RTU mode.\nIf TCP mode is chosen, this parameter is ignored.\n - registers: A Registers object that holds starting addresses and sizes\nfor coils, discrete inputs, holding registers, and input registers.\nThis allows the user to set up the Slave's register configuration\nin a structured manner.\n - rtu_baud: The baud rate for RTU communication.\nSupported rates include: 110, 300, 600, 1200, 2400, 4800,\n9600, 19200, 38400, 57600, 115200, 230400, 460800,\n500000, 576000, 921600, 1000000, 1152000, 1500000,\n2500000, 3000000, 3500000, 4000000.\nDefault is 115200. Ensure that the selected baud rate\nis supported by the underlying hardware and libmodbus.\n - rtu_slave: The RTU slave address. Ignored in TCP mode. Default is 1.\n - tcp_port: The port used for TCP communication. Ignored in RTU mode. Default is 502.\n - debug: A boolean flag to enable or disable debug mode. Default is false.\n" + }, + "args": [ + [ + "maix::comm::modbus::Mode", + "mode", + null + ], + [ + "const std::string&", + "ip_or_device", + null + ], + [ + "const Registers&", + "registers", + "Registers{}" + ], + [ + "int", + "rtu_baud", + "115200" + ], + [ + "uint8_t", + "rtu_slave", + "1" + ], + [ + "int", + "tcp_port", + "502" + ], + [ + "bool", + "debug", + "false" + ] + ], + "ret_type": null, + "static": false, + "def": "Slave(maix::comm::modbus::Mode mode, const std::string& ip_or_device,\n const Registers& registers=Registers{},\n int rtu_baud=115200, uint8_t rtu_slave=1,\n int tcp_port=502, bool debug=false)" + } + }, + "auto_add": true + } + }, + "auto_add": true + }, + "fs": { + "type": "module", + "doc": { + "brief": "maix.fs module" + }, + "members": { + "SEEK": { + "type": "enum", + "name": "SEEK", + "doc": { + "brief": "SEEK enums", + "maixpy": "maix.fs.SEEK", + "py_doc": "SEEK enums" + }, + "values": [ + [ + "SEEK_SET", + "0", + "Seek from beginning of file." + ], + [ + "SEEK_CUR", + "1", + "Seek from current position." + ], + [ + "SEEK_END", + "2", + "Seek from end of file." + ] + ], + "def": "enum SEEK\n {\n SEEK_SET = 0, // Seek from beginning of file.\n SEEK_CUR = 1, // Seek from current position.\n SEEK_END = 2, // Seek from end of file.\n }" + }, + "isabs": { + "type": "func", + "name": "isabs", + "doc": { + "brief": "Check if the path is absolute path", + "param": { + "path": "path to check" + }, + "return": "true if path is absolute path", + "maixpy": "maix.fs.isabs", + "py_doc": "Check if the path is absolute path\n\nArgs:\n - path: path to check\n\n\nReturns: true if path is absolute path\n" + }, + "args": [ + [ + "const std::string &", + "path", + null + ] + ], + "ret_type": "bool", + "static": false, + "def": "bool isabs(const std::string &path)" + }, + "isdir": { + "type": "func", + "name": "isdir", + "doc": { + "brief": "Check if the path is a directory, if not exist, throw exception", + "param": { + "path": "path to check" + }, + "return": "true if path is a directory", + "maixpy": "maix.fs.isdir", + "py_doc": "Check if the path is a directory, if not exist, throw exception\n\nArgs:\n - path: path to check\n\n\nReturns: true if path is a directory\n" + }, + "args": [ + [ + "const std::string &", + "path", + null + ] + ], + "ret_type": "bool", + "static": false, + "def": "bool isdir(const std::string &path)" + }, + "isfile": { + "type": "func", + "name": "isfile", + "doc": { + "brief": "Check if the path is a file, if not exist, throw exception", + "param": { + "path": "path to check" + }, + "return": "true if path is a file", + "maixpy": "maix.fs.isfile", + "py_doc": "Check if the path is a file, if not exist, throw exception\n\nArgs:\n - path: path to check\n\n\nReturns: true if path is a file\n" + }, + "args": [ + [ + "const std::string &", + "path", + null + ] + ], + "ret_type": "bool", + "static": false, + "def": "bool isfile(const std::string &path)" + }, + "islink": { + "type": "func", + "name": "islink", + "doc": { + "brief": "Check if the path is a link, if not exist, throw exception", + "param": { + "path": "path to check" + }, + "return": "true if path is a link", + "maixpy": "maix.fs.islink", + "py_doc": "Check if the path is a link, if not exist, throw exception\n\nArgs:\n - path: path to check\n\n\nReturns: true if path is a link\n" + }, + "args": [ + [ + "const std::string &", + "path", + null + ] + ], + "ret_type": "bool", + "static": false, + "def": "bool islink(const std::string &path)" + }, + "symlink": { + "type": "func", + "name": "symlink", + "doc": { + "brief": "Create soft link", + "param": { + "src": "real file path", + "link": "link file path", + "force": "force link, if already have link file, will delet it first then create." + }, + "maixpy": "maix.fs.symlink", + "py_doc": "Create soft link\n\nArgs:\n - src: real file path\n - link: link file path\n - force: force link, if already have link file, will delet it first then create.\n" + }, + "args": [ + [ + "const std::string &", + "src", + null + ], + [ + "const std::string &", + "link", + null + ], + [ + "bool", + "force", + "false" + ] + ], + "ret_type": "err::Err", + "static": false, + "def": "err::Err symlink(const std::string &src, const std::string &link, bool force = false)" + }, + "exists": { + "type": "func", + "name": "exists", + "doc": { + "brief": "Check if the path exists", + "param": { + "path": "path to check" + }, + "return": "true if path exists", + "maixpy": "maix.fs.exists", + "py_doc": "Check if the path exists\n\nArgs:\n - path: path to check\n\n\nReturns: true if path exists\n" + }, + "args": [ + [ + "const std::string &", + "path", + null + ] + ], + "ret_type": "bool", + "static": false, + "def": "bool exists(const std::string &path)" + }, + "mkdir": { + "type": "func", + "name": "mkdir", + "doc": { + "brief": "Create a directory recursively", + "param": { + "path": "path to create", + "exist_ok": "if true, also return true if directory already exists", + "recursive": "if true, create directory recursively, otherwise, only create one directory, default is true" + }, + "return": "err::ERR_NONE(err.Err.ERR_NONE in MaixPy) if success, other error code if failed", + "maixpy": "maix.fs.mkdir", + "py_doc": "Create a directory recursively\n\nArgs:\n - path: path to create\n - exist_ok: if true, also return true if directory already exists\n - recursive: if true, create directory recursively, otherwise, only create one directory, default is true\n\n\nReturns: err::ERR_NONE(err.Err.ERR_NONE in MaixPy) if success, other error code if failed\n" + }, + "args": [ + [ + "const std::string &", + "path", + null + ], + [ + "bool", + "exist_ok", + "true" + ], + [ + "bool", + "recursive", + "true" + ] + ], + "ret_type": "err::Err", + "static": false, + "def": "err::Err mkdir(const std::string &path, bool exist_ok = true, bool recursive = true)" + }, + "rmdir": { + "type": "func", + "name": "rmdir", + "doc": { + "brief": "Remove a directory", + "param": { + "path": "path to remove", + "recursive": "if true, remove directory recursively, otherwise, only remove empty directory, default is false" + }, + "return": "err::ERR_NONE(err.Err.ERR_NONE in MaixPy) if success, other error code if failed", + "maixpy": "maix.fs.rmdir", + "py_doc": "Remove a directory\n\nArgs:\n - path: path to remove\n - recursive: if true, remove directory recursively, otherwise, only remove empty directory, default is false\n\n\nReturns: err::ERR_NONE(err.Err.ERR_NONE in MaixPy) if success, other error code if failed\n" + }, + "args": [ + [ + "const std::string &", + "path", + null + ], + [ + "bool", + "recursive", + "false" + ] + ], + "ret_type": "err::Err", + "static": false, + "def": "err::Err rmdir(const std::string &path, bool recursive = false)" + }, + "remove": { + "type": "func", + "name": "remove", + "doc": { + "brief": "Remove a file", + "param": { + "path": "path to remove" + }, + "return": "err::ERR_NONE(err.Err.ERR_NONE in MaixPy) if success, other error code if failed", + "maixpy": "maix.fs.remove", + "py_doc": "Remove a file\n\nArgs:\n - path: path to remove\n\n\nReturns: err::ERR_NONE(err.Err.ERR_NONE in MaixPy) if success, other error code if failed\n" + }, + "args": [ + [ + "const std::string &", + "path", + null + ] + ], + "ret_type": "err::Err", + "static": false, + "def": "err::Err remove(const std::string &path)" + }, + "rename": { + "type": "func", + "name": "rename", + "doc": { + "brief": "Rename a file or directory", + "param": { + "src": "source path", + "dst": "destination path, if destination dirs not exist, will auto create" + }, + "return": "err::ERR_NONE(err.Err.ERR_NONE in MaixPy) if success, other error code if failed", + "maixpy": "maix.fs.rename", + "py_doc": "Rename a file or directory\n\nArgs:\n - src: source path\n - dst: destination path, if destination dirs not exist, will auto create\n\n\nReturns: err::ERR_NONE(err.Err.ERR_NONE in MaixPy) if success, other error code if failed\n" + }, + "args": [ + [ + "const std::string &", + "src", + null + ], + [ + "const std::string &", + "dst", + null + ] + ], + "ret_type": "err::Err", + "static": false, + "def": "err::Err rename(const std::string &src, const std::string &dst)" + }, + "sync": { + "type": "func", + "name": "sync", + "doc": { + "brief": "Sync files, ensure they're wrriten to disk from RAM", + "maixpy": "maix.fs.sync", + "py_doc": "Sync files, ensure they're wrriten to disk from RAM" + }, + "args": [], + "ret_type": "void", + "static": false, + "def": "void sync()" + }, + "getsize": { + "type": "func", + "name": "getsize", + "doc": { + "brief": "Get file size", + "param": { + "path": "path to get size" + }, + "return": "file size if success, -err::Err code if failed", + "maixpy": "maix.fs.getsize", + "py_doc": "Get file size\n\nArgs:\n - path: path to get size\n\n\nReturns: file size if success, -err::Err code if failed\n" + }, + "args": [ + [ + "const std::string &", + "path", + null + ] + ], + "ret_type": "int", + "static": false, + "def": "int getsize(const std::string &path)" + }, + "dirname": { + "type": "func", + "name": "dirname", + "doc": { + "brief": "Get directory name of path", + "param": { + "path": "path to get dirname" + }, + "return": "dirname if success, empty string if failed", + "maixpy": "maix.fs.dirname", + "py_doc": "Get directory name of path\n\nArgs:\n - path: path to get dirname\n\n\nReturns: dirname if success, empty string if failed\n" + }, + "args": [ + [ + "const std::string &", + "path", + null + ] + ], + "ret_type": "std::string", + "static": false, + "def": "std::string dirname(const std::string &path)" + }, + "basename": { + "type": "func", + "name": "basename", + "doc": { + "brief": "Get base name of path", + "param": { + "path": "path to get basename" + }, + "return": "basename if success, empty string if failed", + "maixpy": "maix.fs.basename", + "py_doc": "Get base name of path\n\nArgs:\n - path: path to get basename\n\n\nReturns: basename if success, empty string if failed\n" + }, + "args": [ + [ + "const std::string &", + "path", + null + ] + ], + "ret_type": "std::string", + "static": false, + "def": "std::string basename(const std::string &path)" + }, + "abspath": { + "type": "func", + "name": "abspath", + "doc": { + "brief": "Get absolute path", + "param": { + "path": "path to get absolute path" + }, + "return": "absolute path if success, empty string if failed", + "maixpy": "maix.fs.abspath", + "py_doc": "Get absolute path\n\nArgs:\n - path: path to get absolute path\n\n\nReturns: absolute path if success, empty string if failed\n" + }, + "args": [ + [ + "const std::string &", + "path", + null + ] + ], + "ret_type": "std::string", + "static": false, + "def": "std::string abspath(const std::string &path)" + }, + "getcwd": { + "type": "func", + "name": "getcwd", + "doc": { + "brief": "Get current working directory", + "return": "current working directory absolute path", + "maixpy": "maix.fs.getcwd", + "py_doc": "Get current working directory\n\nReturns: current working directory absolute path\n" + }, + "args": [], + "ret_type": "std::string", + "static": false, + "def": "std::string getcwd()" + }, + "realpath": { + "type": "func", + "name": "realpath", + "doc": { + "brief": "Get realpath of path", + "param": { + "path": "path to get realpath" + }, + "return": "realpath if success, empty string if failed", + "maixpy": "maix.fs.realpath", + "py_doc": "Get realpath of path\n\nArgs:\n - path: path to get realpath\n\n\nReturns: realpath if success, empty string if failed\n" + }, + "args": [ + [ + "const std::string &", + "path", + null + ] + ], + "ret_type": "std::string", + "static": false, + "def": "std::string realpath(const std::string &path)" + }, + "splitext": { + "type": "func", + "name": "splitext", + "doc": { + "brief": "Get file extension", + "param": { + "path": "path to get extension" + }, + "return": "prefix_path and extension list if success, empty string if failed", + "maixpy": "maix.fs.splitext", + "py_doc": "Get file extension\n\nArgs:\n - path: path to get extension\n\n\nReturns: prefix_path and extension list if success, empty string if failed\n" + }, + "args": [ + [ + "const std::string &", + "path", + null + ] + ], + "ret_type": "std::vector", + "static": false, + "def": "std::vector splitext(const std::string &path)" + }, + "listdir": { + "type": "func", + "name": "listdir", + "doc": { + "brief": "List files in directory", + "param": { + "path": "path to list", + "recursive": "if true, list recursively, otherwise, only list current directory, default is false", + "full_path": "if true, return full path, otherwise, only return basename, default is false" + }, + "return": "files list if success, nullptr if failed, you should manually delete it in C++.", + "maixpy": "maix.fs.listdir", + "py_doc": "List files in directory\n\nArgs:\n - path: path to list\n - recursive: if true, list recursively, otherwise, only list current directory, default is false\n - full_path: if true, return full path, otherwise, only return basename, default is false\n\n\nReturns: files list if success, nullptr if failed, you should manually delete it in C++.\n" + }, + "args": [ + [ + "const std::string &", + "path", + null + ], + [ + "bool", + "recursive", + "false" + ], + [ + "bool", + "full_path", + "false" + ] + ], + "ret_type": "std::vector*", + "static": false, + "def": "std::vector *listdir(const std::string &path, bool recursive = false, bool full_path = false)" + }, + "File": { + "type": "class", + "name": "File", + "doc": { + "brief": "File read write ops", + "maixpy": "maix.fs.File", + "py_doc": "File read write ops" + }, + "members": { + "File": { + "type": "func", + "name": "File", + "doc": { + "brief": "Construct File object", + "maixpy": "maix.fs.File.__init__", + "maixcdk": "maix.fs.File.File", + "py_doc": "Construct File object" + }, + "args": [], + "ret_type": null, + "static": false, + "def": "File()" + }, + "open": { + "type": "func", + "name": "open", + "doc": { + "brief": "Open a file", + "param": { + "path": "path to open", + "mode": "open mode, support \"r\", \"w\", \"a\", \"r+\", \"w+\", \"a+\", \"rb\", \"wb\", \"ab\", \"rb+\", \"wb+\", \"ab+\"" + }, + "return": "err::ERR_NONE(err.Err.ERR_NONE in MaixPy) if success, other error code if failed", + "maixpy": "maix.fs.File.open", + "py_doc": "Open a file\n\nArgs:\n - path: path to open\n - mode: open mode, support \"r\", \"w\", \"a\", \"r+\", \"w+\", \"a+\", \"rb\", \"wb\", \"ab\", \"rb+\", \"wb+\", \"ab+\"\n\n\nReturns: err::ERR_NONE(err.Err.ERR_NONE in MaixPy) if success, other error code if failed\n" + }, + "args": [ + [ + "const std::string &", + "path", + null + ], + [ + "const std::string &", + "mode", + null + ] + ], + "ret_type": "err::Err", + "static": false, + "def": "err::Err open(const std::string &path, const std::string &mode)" + }, + "close": { + "type": "func", + "name": "close", + "doc": { + "brief": "Close a file", + "maixpy": "maix.fs.File.close", + "py_doc": "Close a file" + }, + "args": [], + "ret_type": "void", + "static": false, + "def": "void close()" + }, + "read": { + "type": "func", + "name": "read", + "doc": { + "brief": "Read data from file", + "param": { + "buf": "buffer to store data", + "size": "buffer size(max read size)" + }, + "return": "read size if success, -err::Err code if failed", + "maixcdk": "maix.fs.File.read", + "py_doc": "Read data from file\n\nArgs:\n - buf: buffer to store data\n - size: buffer size(max read size)\n\n\nReturns: read size if success, -err::Err code if failed\n" + }, + "args": [ + [ + "void *", + "buf", + null + ], + [ + "int", + "size", + null + ] + ], + "ret_type": "int", + "static": false, + "def": "int read(void *buf, int size)", + "overload": [ + { + "type": "func", + "name": "read", + "doc": { + "brief": "Read data from file API2", + "param": { + "size": "max read size" + }, + "return": "bytes data if success(need delete manually in C/C++), nullptr if failed", + "maixpy": "maix.fs.File.read", + "py_doc": "Read data from file API2\n\nArgs:\n - size: max read size\n\n\nReturns: bytes data if success(need delete manually in C/C++), nullptr if failed\n" + }, + "args": [ + [ + "int", + "size", + null + ] + ], + "ret_type": "std::vector*", + "static": false, + "def": "std::vector *read(int size)" + } + ] + }, + "readline": { + "type": "func", + "name": "readline", + "doc": { + "brief": "Read line from file", + "param": { + "line": "buffer to store line" + }, + "return": "read size if success, -err::Err code if failed", + "maixcdk": "maix.fs.File.readline", + "py_doc": "Read line from file\n\nArgs:\n - line: buffer to store line\n\n\nReturns: read size if success, -err::Err code if failed\n" + }, + "args": [ + [ + "std::string &", + "line", + null + ] + ], + "ret_type": "int", + "static": false, + "def": "int readline(std::string &line)", + "overload": [ + { + "type": "func", + "name": "readline", + "doc": { + "brief": "Read line from file", + "return": "line if success, None(nullptr in C++) if failed. You need to delete the returned object manually in C/C++.", + "maixpy": "maix.fs.File.readline", + "py_doc": "Read line from file\n\nReturns: line if success, None(nullptr in C++) if failed. You need to delete the returned object manually in C/C++.\n" + }, + "args": [], + "ret_type": "std::string*", + "static": false, + "def": "std::string *readline()" + } + ] + }, + "eof": { + "type": "func", + "name": "eof", + "doc": { + "brief": "End of file or not", + "return": "0 if not reach end of file, else eof.", + "maixpy": "maix.fs.File.eof", + "py_doc": "End of file or not\n\nReturns: 0 if not reach end of file, else eof.\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int eof()" + }, + "write": { + "type": "func", + "name": "write", + "doc": { + "brief": "Write data to file", + "param": { + "buf": "buffer to write", + "size": "buffer size" + }, + "return": "write size if success, -err::Err code if failed", + "maixcdk": "maix.fs.File.write", + "py_doc": "Write data to file\n\nArgs:\n - buf: buffer to write\n - size: buffer size\n\n\nReturns: write size if success, -err::Err code if failed\n" + }, + "args": [ + [ + "const void *", + "buf", + null + ], + [ + "int", + "size", + null + ] + ], + "ret_type": "int", + "static": false, + "def": "int write(const void *buf, int size)", + "overload": [ + { + "type": "func", + "name": "write", + "doc": { + "brief": "Write data to file API2", + "param": { + "buf": "buffer to write" + }, + "return": "write size if success, -err::Err code if failed", + "maixpy": "maix.fs.File.write", + "py_doc": "Write data to file API2\n\nArgs:\n - buf: buffer to write\n\n\nReturns: write size if success, -err::Err code if failed\n" + }, + "args": [ + [ + "const std::vector &", + "buf", + null + ] + ], + "ret_type": "int", + "static": false, + "def": "int write(const std::vector &buf)" + } + ] + }, + "seek": { + "type": "func", + "name": "seek", + "doc": { + "brief": "Seek file position", + "param": { + "offset": "offset to seek", + "whence": "@see maix.fs.SEEK" + }, + "return": "new position if success, -err::Err code if failed", + "maixpy": "maix.fs.File.seek", + "py_doc": "Seek file position\n\nArgs:\n - offset: offset to seek\n - whence: @see maix.fs.SEEK\n\n\nReturns: new position if success, -err::Err code if failed\n" + }, + "args": [ + [ + "int", + "offset", + null + ], + [ + "int", + "whence", + null + ] + ], + "ret_type": "int", + "static": false, + "def": "int seek(int offset, int whence)" + }, + "tell": { + "type": "func", + "name": "tell", + "doc": { + "brief": "Get file position", + "return": "file position if success, -err::Err code if failed", + "maixpy": "maix.fs.File.tell", + "py_doc": "Get file position\n\nReturns: file position if success, -err::Err code if failed\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int tell()" + }, + "flush": { + "type": "func", + "name": "flush", + "doc": { + "brief": "Flush file", + "return": "err::ERR_NONE(err.Err.ERR_NONE in MaixPy) if success, other error code if failed", + "maixpy": "maix.fs.File.flush", + "py_doc": "Flush file\n\nReturns: err::ERR_NONE(err.Err.ERR_NONE in MaixPy) if success, other error code if failed\n" + }, + "args": [], + "ret_type": "err::Err", + "static": false, + "def": "err::Err flush()" + } + }, + "def": "class File" + }, + "open": { + "type": "func", + "name": "open", + "doc": { + "brief": "Open a file, and return a File object", + "param": { + "path": "path to open", + "mode": "open mode, support \"r\", \"w\", \"a\", \"r+\", \"w+\", \"a+\", \"rb\", \"wb\", \"ab\", \"rb+\", \"wb+\", \"ab+\"" + }, + "return": "File object if success(need to delete object manually in C/C++), nullptr if failed", + "maixpy": "maix.fs.open", + "py_doc": "Open a file, and return a File object\n\nArgs:\n - path: path to open\n - mode: open mode, support \"r\", \"w\", \"a\", \"r+\", \"w+\", \"a+\", \"rb\", \"wb\", \"ab\", \"rb+\", \"wb+\", \"ab+\"\n\n\nReturns: File object if success(need to delete object manually in C/C++), nullptr if failed\n" + }, + "args": [ + [ + "const std::string &", + "path", + null + ], + [ + "const std::string &", + "mode", + null + ] + ], + "ret_type": "fs::File*", + "static": false, + "def": "fs::File *open(const std::string &path, const std::string &mode)" + }, + "tempdir": { + "type": "func", + "name": "tempdir", + "doc": { + "brief": "Get temp files directory", + "return": "temp files directory", + "maixpy": "maix.fs.tempdir", + "py_doc": "Get temp files directory\n\nReturns: temp files directory\n" + }, + "args": [], + "ret_type": "std::string", + "static": false, + "def": "std::string tempdir()" + } + }, + "auto_add": true + }, + "Bytes": { + "type": "class", + "name": "Bytes", + "doc": { + "brief": "Bytes type for Python bytes compatibility.", + "maixcdk": "maix.Bytes", + "py_doc": "Bytes type for Python bytes compatibility." + }, + "members": { + "Bytes": { + "type": "func", + "name": "Bytes", + "doc": { + "brief": "Construct a Bytes object from a uint8_t array.", + "param": { + "data": "uint8_t array", + "len": "length of the array", + "auto_delete": "if true, will delete data when destruct. When copy is true, this arg will be ignore.", + "copy": "data will be copy to new buffer if true, if false, will use data directly,\ndefault true to ensure memory safety." + }, + "maixcdk": "maix.Bytes.Bytes", + "py_doc": "Construct a Bytes object from a uint8_t array.\n\nArgs:\n - data: uint8_t array\n - len: length of the array\n - auto_delete: if true, will delete data when destruct. When copy is true, this arg will be ignore.\n - copy: data will be copy to new buffer if true, if false, will use data directly,\ndefault true to ensure memory safety.\n" + }, + "args": [ + [ + "uint8_t *", + "data", + null + ], + [ + "uint32_t", + "len", + null + ], + [ + "bool", + "auto_delete", + "false" + ], + [ + "bool", + "copy", + "true" + ] + ], + "ret_type": null, + "static": false, + "def": "Bytes(uint8_t *data, uint32_t len, bool auto_delete = false, bool copy = true)", + "overload": [ + { + "type": "func", + "name": "Bytes", + "doc": { + "brief": "Construct a Bytes object from a uint8_t array. but not set anything.", + "maixcdk": "maix.Bytes.Bytes", + "py_doc": "Construct a Bytes object from a uint8_t array. but not set anything." + }, + "args": [], + "ret_type": null, + "static": false, + "def": "Bytes()" + } + ] + }, + "operator=": { + "type": "var", + "name": "!", + "doc": { + "brief": "overload = operator", + "param": { + "other": "another Bytes object" + }, + "return": "Bytes object", + "maixcdk": "maix.Bytes.operator=", + "py_doc": "overload = operator\n\nArgs:\n - other: another Bytes object\n\n\nReturns: Bytes object\n" + }, + "value": "&other)\n {\n if (_is_alloc && data)\n {\n delete[] data", + "static": false, + "readonly": false, + "def": "Bytes &operator=(const Bytes &other)\n {\n if (this != &other)\n {\n if (_is_alloc && data)\n {\n delete[] data" + }, + "at": { + "type": "func", + "name": "at", + "doc": { + "brief": "at method", + "param": { + "index": "index of the data" + }, + "return": "uint8_t data", + "maixcdk": "maix.Bytes.at", + "py_doc": "at method\n\nArgs:\n - index: index of the data\n\n\nReturns: uint8_t data\n" + }, + "args": [ + [ + "int", + "index", + null + ] + ], + "ret_type": "uint8_t", + "static": false, + "def": "uint8_t at(int index)" + }, + "operator[]": { + "type": "func", + "name": "operator[]", + "doc": { + "brief": "overload [] operator", + "param": { + "index": "index of the data" + }, + "return": "uint8_t data", + "maixcdk": "maix.Bytes.operator[]", + "py_doc": "overload [] operator\n\nArgs:\n - index: index of the data\n\n\nReturns: uint8_t data\n" + }, + "args": [ + [ + "int", + "index", + null + ] + ], + "ret_type": "uint8_t", + "static": false, + "def": "uint8_t operator[](int index)" + }, + "size": { + "type": "func", + "name": "size", + "doc": { + "brief": "Get data length, equal to data_len.", + "return": "uint32_t length", + "maixcdk": "maix.Bytes.size", + "py_doc": "Get data length, equal to data_len.\n\nReturns: uint32_t length\n" + }, + "args": [], + "ret_type": "size_t", + "static": false, + "def": "size_t size()" + }, + "begin": { + "type": "func", + "name": "begin", + "doc": { + "brief": "iter data begin", + "maixcdk": "maix.Bytes.begin", + "py_doc": "iter data begin" + }, + "args": [], + "ret_type": "uint8_t*", + "static": false, + "def": "uint8_t *begin()" + }, + "end": { + "type": "func", + "name": "end", + "doc": { + "brief": "iter data end", + "maixcdk": "maix.Bytes.end", + "py_doc": "iter data end" + }, + "args": [], + "ret_type": "uint8_t*", + "static": false, + "def": "uint8_t *end()" + }, + "data": { + "type": "var", + "name": "data", + "doc": { + "brief": "Get raw data pointer. carefully update this value if you need change this value.", + "return": "uint8_t pointer", + "maixcdk": "maix.Bytes.data", + "py_doc": "Get raw data pointer. carefully update this value if you need change this value.\n\nReturns: uint8_t pointer\n" + }, + "value": null, + "static": false, + "readonly": false, + "def": "uint8_t *data" + }, + "buff_len": { + "type": "var", + "name": "buff_len", + "doc": { + "brief": "Length property, carefully update this value if you need change this value.", + "return": "buffer length", + "maixcdk": "maix.Bytes.buff_len", + "py_doc": "Length property, carefully update this value if you need change this value.\n\nReturns: buffer length\n" + }, + "value": null, + "static": false, + "readonly": false, + "def": "size_t buff_len" + }, + "data_len": { + "type": "var", + "name": "data_len", + "doc": { + "brief": "data length, carefully update this value if you need change this value.", + "return": "actual data length, <= buff_len", + "maixcdk": "maix.Bytes.data_len", + "py_doc": "data length, carefully update this value if you need change this value.\n\nReturns: actual data length, <= buff_len\n" + }, + "value": null, + "static": false, + "readonly": false, + "def": "size_t data_len" + } + }, + "def": "class Bytes" + }, + "app": { + "type": "module", + "doc": { + "brief": "maix.app module" + }, + "members": { + "Version": { + "type": "class", + "name": "Version", + "doc": { + "brief": "APP version", + "maixpy": "maix.app.Version", + "py_doc": "APP version" + }, + "members": { + "__str__": { + "type": "func", + "name": "__str__", + "doc": { + "brief": "Convert to string, e.g. 1.0.0", + "maixpy": "maix.app.Version.__str__", + "py_doc": "Convert to string, e.g. 1.0.0" + }, + "args": [], + "ret_type": "std::string", + "static": false, + "def": "std::string __str__()" + }, + "from_str": { + "type": "func", + "name": "from_str", + "doc": { + "brief": "Convert from string, e.g. \\\"1.0.0\\\"", + "maixpy": "maix.app.Version.from_str", + "py_doc": "Convert from string, e.g. \"1.0.0\"" + }, + "args": [ + [ + "const string &", + "version_str", + null + ] + ], + "ret_type": "app::Version", + "static": true, + "def": "static app::Version from_str(const string &version_str)" + } + }, + "def": "class Version" + }, + "APP_Info": { + "type": "class", + "name": "APP_Info", + "doc": { + "brief": "APP info", + "maixpy": "maix.app.APP_Info", + "py_doc": "APP info" + }, + "members": { + "id": { + "type": "var", + "name": "id", + "doc": { + "brief": "APP id", + "maixpy": "maix.app.APP_Info.id", + "py_doc": "APP id" + }, + "value": null, + "static": false, + "readonly": false, + "def": "string id" + }, + "name": { + "type": "var", + "name": "name", + "doc": { + "brief": "APP name", + "maixpy": "maix.app.APP_Info.name", + "py_doc": "APP name" + }, + "value": null, + "static": false, + "readonly": false, + "def": "string name" + }, + "icon": { + "type": "var", + "name": "icon", + "doc": { + "brief": "APP icon", + "maixpy": "maix.app.APP_Info.icon", + "py_doc": "APP icon" + }, + "value": null, + "static": false, + "readonly": false, + "def": "string icon" + }, + "version": { + "type": "var", + "name": "version", + "doc": { + "brief": "APP version", + "maixpy": "maix.app.APP_Info.version", + "py_doc": "APP version" + }, + "value": null, + "static": false, + "readonly": false, + "def": "Version version" + }, + "exec": { + "type": "var", + "name": "exec", + "doc": { + "brief": "APP exec", + "maixpy": "maix.app.APP_Info.exec", + "py_doc": "APP exec" + }, + "value": null, + "static": false, + "readonly": false, + "def": "string exec" + }, + "author": { + "type": "var", + "name": "author", + "doc": { + "brief": "APP author", + "maixpy": "maix.app.APP_Info.author", + "py_doc": "APP author" + }, + "value": null, + "static": false, + "readonly": false, + "def": "string author" + }, + "desc": { + "type": "var", + "name": "desc", + "doc": { + "brief": "APP desc", + "maixpy": "maix.app.APP_Info.desc", + "py_doc": "APP desc" + }, + "value": null, + "static": false, + "readonly": false, + "def": "string desc" + }, + "names": { + "type": "var", + "name": "names", + "doc": { + "brief": "APP names", + "maixpy": "maix.app.APP_Info.names", + "py_doc": "APP names" + }, + "value": null, + "static": false, + "readonly": false, + "def": "map names" + }, + "descs": { + "type": "var", + "name": "descs", + "doc": { + "brief": "APP descs", + "maixpy": "maix.app.APP_Info.descs", + "py_doc": "APP descs" + }, + "value": null, + "static": false, + "readonly": false, + "def": "map descs" + } + }, + "def": "class APP_Info" + }, + "app_id": { + "type": "func", + "name": "app_id", + "doc": { + "brief": "Get current APP ID.", + "return": "APP ID.", + "maixpy": "maix.app.app_id", + "py_doc": "Get current APP ID.\n\nReturns: APP ID.\n" + }, + "args": [], + "ret_type": "string", + "static": false, + "def": "string app_id()" + }, + "set_app_id": { + "type": "func", + "name": "set_app_id", + "doc": { + "brief": "Set current APP ID.", + "param": { + "app_id": "APP ID." + }, + "maixpy": "maix.app.set_app_id", + "py_doc": "Set current APP ID.\n\nArgs:\n - app_id: APP ID.\n" + }, + "args": [ + [ + "const string &", + "app_id", + null + ] + ], + "ret_type": "string", + "static": false, + "def": "string set_app_id(const string &app_id)" + }, + "get_apps_info_path": { + "type": "func", + "name": "get_apps_info_path", + "doc": { + "brief": "Get APP info file path.", + "maixpy": "maix.app.get_apps_info_path", + "py_doc": "Get APP info file path." + }, + "args": [], + "ret_type": "string", + "static": false, + "def": "string get_apps_info_path()" + }, + "get_apps_info": { + "type": "func", + "name": "get_apps_info", + "doc": { + "brief": "Get APP info list.", + "param": { + "ignore_launcher": "if true, ignore launcher APP. default false.", + "ignore_app_store": "if true, ignore app store APP. default false." + }, + "return": "APP info list. APP_Info object list.", + "maixpy": "maix.app.get_apps_info", + "py_doc": "Get APP info list.\n\nArgs:\n - ignore_launcher: if true, ignore launcher APP. default false.\n - ignore_app_store: if true, ignore app store APP. default false.\n\n\nReturns: APP info list. APP_Info object list.\n" + }, + "args": [ + [ + "bool", + "ignore_launcher", + "false" + ], + [ + "bool", + "ignore_app_store", + "false" + ] + ], + "ret_type": "vector&", + "static": false, + "def": "vector &get_apps_info(bool ignore_launcher = false, bool ignore_app_store = false)" + }, + "get_app_info": { + "type": "func", + "name": "get_app_info", + "doc": { + "brief": "Get app info by app id.", + "return": "app.APP_Info type.", + "maixpy": "maix.app.get_app_info", + "py_doc": "Get app info by app id.\n\nReturns: app.APP_Info type.\n" + }, + "args": [ + [ + "const std::string &", + "app_id", + null + ] + ], + "ret_type": "app::APP_Info", + "static": false, + "def": "app::APP_Info get_app_info(const std::string &app_id)" + }, + "get_app_data_path": { + "type": "func", + "name": "get_app_data_path", + "doc": { + "brief": "Get APP info, APP can store private data in this directory.", + "return": "APP data path \"./data\", just return the data folder in current path because APP executed in app install path or project path.\nSo, you must execute your program in you project path to use the project/data folder when you debug your APP.", + "maixpy": "maix.app.get_app_data_path", + "py_doc": "Get APP info, APP can store private data in this directory.\n\nReturns: APP data path \"./data\", just return the data folder in current path because APP executed in app install path or project path.\nSo, you must execute your program in you project path to use the project/data folder when you debug your APP.\n" + }, + "args": [], + "ret_type": "string", + "static": false, + "def": "string get_app_data_path()" + }, + "get_app_path": { + "type": "func", + "name": "get_app_path", + "doc": { + "brief": "Get APP path.", + "param": { + "app_id": "APP ID, if empty, return current APP path, else return the APP path by app_id." + }, + "return": "APP path, just return the current path because APP executed in app install path or project path.\nSo, you must execute your program in you project path to use the project/data folder when you debug your APP.", + "maixpy": "maix.app.get_app_path", + "py_doc": "Get APP path.\n\nArgs:\n - app_id: APP ID, if empty, return current APP path, else return the APP path by app_id.\n\n\nReturns: APP path, just return the current path because APP executed in app install path or project path.\nSo, you must execute your program in you project path to use the project/data folder when you debug your APP.\n" + }, + "args": [ + [ + "const string &", + "app_id", + "\"\"" + ] + ], + "ret_type": "string", + "static": false, + "def": "string get_app_path(const string &app_id = \"\")" + }, + "get_tmp_path": { + "type": "func", + "name": "get_tmp_path", + "doc": { + "brief": "Get global temporary data path, APPs can use this path as temporary data directory.", + "return": "temporary data path.", + "maixpy": "maix.app.get_tmp_path", + "py_doc": "Get global temporary data path, APPs can use this path as temporary data directory.\n\nReturns: temporary data path.\n" + }, + "args": [], + "ret_type": "string", + "static": false, + "def": "string get_tmp_path()" + }, + "get_share_path": { + "type": "func", + "name": "get_share_path", + "doc": { + "brief": "Get data path of share, shared data like picture and video will put in this directory", + "return": "share data path.", + "maixpy": "maix.app.get_share_path", + "py_doc": "Get data path of share, shared data like picture and video will put in this directory\n\nReturns: share data path.\n" + }, + "args": [], + "ret_type": "string", + "static": false, + "def": "string get_share_path()" + }, + "get_picture_path": { + "type": "func", + "name": "get_picture_path", + "doc": { + "brief": "Get picture path of share, shared picture will put in this directory", + "return": "share picture path.", + "maixpy": "maix.app.get_picture_path", + "py_doc": "Get picture path of share, shared picture will put in this directory\n\nReturns: share picture path.\n" + }, + "args": [], + "ret_type": "string", + "static": false, + "def": "string get_picture_path()" + }, + "get_video_path": { + "type": "func", + "name": "get_video_path", + "doc": { + "brief": "Get video path of share, shared video will put in this directory", + "return": "share video path.", + "maixpy": "maix.app.get_video_path", + "py_doc": "Get video path of share, shared video will put in this directory\n\nReturns: share video path.\n" + }, + "args": [], + "ret_type": "string", + "static": false, + "def": "string get_video_path()" + }, + "get_font_path": { + "type": "func", + "name": "get_font_path", + "doc": { + "brief": "Get font path of share, shared font will put in this directory", + "return": "share font path.", + "maixpy": "maix.app.get_font_path", + "py_doc": "Get font path of share, shared font will put in this directory\n\nReturns: share font path.\n" + }, + "args": [], + "ret_type": "string", + "static": false, + "def": "string get_font_path()" + }, + "get_icon_path": { + "type": "func", + "name": "get_icon_path", + "doc": { + "brief": "Get icon path of share, shared icon will put in this directory", + "return": "share icon path.", + "maixpy": "maix.app.get_icon_path", + "py_doc": "Get icon path of share, shared icon will put in this directory\n\nReturns: share icon path.\n" + }, + "args": [], + "ret_type": "string", + "static": false, + "def": "string get_icon_path()" + }, + "get_sys_config_kv": { + "type": "func", + "name": "get_sys_config_kv", + "doc": { + "brief": "Get system config item value.", + "param": { + "item": "name of setting item, e.g. wifi, language. more see settings APP.", + "key": "config key, e.g. for wifi, key can be ssid, for language, key can be locale.", + "value": "default value, if not found, return this value.", + "from_cache": "if true, read from cache, if false, read from file." + }, + "return": "config value, always string type, if not found, return empty string.", + "maixpy": "maix.app.get_sys_config_kv", + "py_doc": "Get system config item value.\n\nArgs:\n - item: name of setting item, e.g. wifi, language. more see settings APP.\n - key: config key, e.g. for wifi, key can be ssid, for language, key can be locale.\n - value: default value, if not found, return this value.\n - from_cache: if true, read from cache, if false, read from file.\n\n\nReturns: config value, always string type, if not found, return empty string.\n" + }, + "args": [ + [ + "const string &", + "item", + null + ], + [ + "const string &", + "key", + null + ], + [ + "const string &", + "value", + "\"\"" + ], + [ + "bool", + "from_cache", + "true" + ] + ], + "ret_type": "string", + "static": false, + "def": "string get_sys_config_kv(const string &item, const string &key, const string &value = \"\", bool from_cache = true)" + }, + "get_app_config_kv": { + "type": "func", + "name": "get_app_config_kv", + "doc": { + "brief": "Get APP config item value.", + "param": { + "item": "name of setting item, e.g. user_info", + "key": "config key, e.g. for user_info, key can be name, age etc.", + "value": "default value, if not found, return this value.", + "from_cache": "if true, read from cache, if false, read from file." + }, + "return": "config value, always string type, if not found, return empty string.", + "maixpy": "maix.app.get_app_config_kv", + "py_doc": "Get APP config item value.\n\nArgs:\n - item: name of setting item, e.g. user_info\n - key: config key, e.g. for user_info, key can be name, age etc.\n - value: default value, if not found, return this value.\n - from_cache: if true, read from cache, if false, read from file.\n\n\nReturns: config value, always string type, if not found, return empty string.\n" + }, + "args": [ + [ + "const string &", + "item", + null + ], + [ + "const string &", + "key", + null + ], + [ + "const string &", + "value", + "\"\"" + ], + [ + "bool", + "from_cache", + "true" + ] + ], + "ret_type": "string", + "static": false, + "def": "string get_app_config_kv(const string &item, const string &key, const string &value = \"\", bool from_cache = true)" + }, + "set_app_config_kv": { + "type": "func", + "name": "set_app_config_kv", + "doc": { + "brief": "Set APP config item value.", + "param": { + "item": "name of setting item, e.g. user_info", + "key": "config key, e.g. for user_info, key can be name, age etc.", + "value": "config value, always string type.", + "write_file": "if true, write to file, if false, just write to cache." + }, + "return": "err::Err", + "maixpy": "maix.app.set_app_config_kv", + "py_doc": "Set APP config item value.\n\nArgs:\n - item: name of setting item, e.g. user_info\n - key: config key, e.g. for user_info, key can be name, age etc.\n - value: config value, always string type.\n - write_file: if true, write to file, if false, just write to cache.\n\n\nReturns: err::Err\n" + }, + "args": [ + [ + "const string &", + "item", + null + ], + [ + "const string &", + "key", + null + ], + [ + "const string &", + "value", + null + ], + [ + "bool", + "write_file", + "true" + ] + ], + "ret_type": "err::Err", + "static": false, + "def": "err::Err set_app_config_kv(const string &item, const string &key, const string &value, bool write_file = true)" + }, + "get_app_config_path": { + "type": "func", + "name": "get_app_config_path", + "doc": { + "brief": "Get APP config path, ini format, so you can use your own ini parser to parse it like `configparser` in Python.\\nAll APP config info is recommended to store in this file.", + "return": "APP config path(ini format).", + "maixpy": "maix.app.get_app_config_path", + "py_doc": "Get APP config path, ini format, so you can use your own ini parser to parse it like `configparser` in Python.\nAll APP config info is recommended to store in this file.\n\nReturns: APP config path(ini format).\n" + }, + "args": [], + "ret_type": "string", + "static": false, + "def": "string get_app_config_path()" + }, + "set_exit_msg": { + "type": "func", + "name": "set_exit_msg", + "doc": { + "brief": "Set APP exit code and exit message.\\nIf code != 0, the launcher will show a dialog to user, and display the msg.", + "param": { + "code": "exit code, 0 means success, other means error, if code is 0, do nothing.", + "msg": "exit message, if code is 0, msg is not used." + }, + "return": "exit code, the same as arg @code.", + "maixpy": "maix.app.set_exit_msg", + "py_doc": "Set APP exit code and exit message.\nIf code != 0, the launcher will show a dialog to user, and display the msg.\n\nArgs:\n - code: exit code, 0 means success, other means error, if code is 0, do nothing.\n - msg: exit message, if code is 0, msg is not used.\n\n\nReturns: exit code, the same as arg @code.\n" + }, + "args": [ + [ + "err::Err", + "code", + null + ], + [ + "const string &", + "msg", + null + ] + ], + "ret_type": "err::Err", + "static": false, + "def": "err::Err set_exit_msg(err::Err code, const string &msg)" + }, + "get_exit_msg": { + "type": "func", + "name": "get_exit_msg", + "doc": { + "brief": "Get APP exit code and exit message.", + "param": { + "cache": "if true, read from cache, if false, read from file. default false." + }, + "return": "exit return app_id, exit code and exit message.", + "maixpy": "maix.app.get_exit_msg", + "py_doc": "Get APP exit code and exit message.\n\nArgs:\n - cache: if true, read from cache, if false, read from file. default false.\n\n\nReturns: exit return app_id, exit code and exit message.\n" + }, + "args": [ + [ + "bool", + "cache", + "false" + ] + ], + "ret_type": "tuple", + "static": false, + "def": "tuple get_exit_msg(bool cache = false)" + }, + "have_exit_msg": { + "type": "func", + "name": "have_exit_msg", + "doc": { + "brief": "Check if have exit msg", + "param": { + "cache": "if true, just check from cache, if false, check from file. default false." + }, + "return": "true if have exit msg, false if not.", + "maixpy": "maix.app.have_exit_msg", + "py_doc": "Check if have exit msg\n\nArgs:\n - cache: if true, just check from cache, if false, check from file. default false.\n\n\nReturns: true if have exit msg, false if not.\n" + }, + "args": [ + [ + "bool", + "cache", + "false" + ] + ], + "ret_type": "bool", + "static": false, + "def": "bool have_exit_msg(bool cache = false)" + }, + "switch_app": { + "type": "func", + "name": "switch_app", + "doc": { + "brief": "Exit this APP and start another APP(by launcher).\\nCall this API will call set_exit_flag(true), you should check app::need_exit() in your code.\\nAnd exit this APP if app::need_exit() return true.", + "param": { + "app_id": "APP ID which will be started. app_id and idx must have one is valid.", + "idx": "APP index. app_id and idx must have one is valid.", + "start_param": "string type, will send to app, app can get this param by `app.get_start_param()`" + }, + "attention": "If app id or idx the same as current app, do nothing.", + "maixpy": "maix.app.switch_app", + "py_doc": "Exit this APP and start another APP(by launcher).\nCall this API will call set_exit_flag(true), you should check app::need_exit() in your code.\nAnd exit this APP if app::need_exit() return true.\n\nArgs:\n - app_id: APP ID which will be started. app_id and idx must have one is valid.\n - idx: APP index. app_id and idx must have one is valid.\n - start_param: string type, will send to app, app can get this param by `app.get_start_param()`\n" + }, + "args": [ + [ + "const string &", + "app_id", + null + ], + [ + "int", + "idx", + "-1" + ], + [ + "const std::string &", + "start_param", + "\"\"" + ] + ], + "ret_type": "void", + "static": false, + "def": "void switch_app(const string &app_id, int idx = -1, const std::string &start_param = \"\")" + }, + "get_start_param": { + "type": "func", + "name": "get_start_param", + "doc": { + "brief": "Get start param set by caller", + "return": "param, string type", + "maixpy": "maix.app.get_start_param", + "py_doc": "Get start param set by caller\n\nReturns: param, string type\n" + }, + "args": [], + "ret_type": "const std::string", + "static": false, + "def": "const std::string get_start_param()" + }, + "need_exit": { + "type": "func", + "name": "need_exit", + "doc": { + "brief": "Shoule this APP exit?", + "return": "true if this APP should exit, false if not.", + "attention": "This API is a function, not a variable.", + "maixpy": "maix.app.need_exit", + "py_doc": "Shoule this APP exit?\n\nReturns: true if this APP should exit, false if not.\n" + }, + "args": [], + "ret_type": "bool", + "static": false, + "def": "bool need_exit()" + }, + "running": { + "type": "func", + "name": "running", + "doc": { + "brief": "App should running? The same as !app::need_exit() (not app::need_exit() in MaixPy).", + "return": "true if this APP should running, false if not.", + "attention": "This API is a function, not a variable.", + "maixpy": "maix.app.running", + "py_doc": "App should running? The same as !app::need_exit() (not app::need_exit() in MaixPy).\n\nReturns: true if this APP should running, false if not.\n" + }, + "args": [], + "ret_type": "bool", + "static": false, + "def": "bool running()" + }, + "set_exit_flag": { + "type": "func", + "name": "set_exit_flag", + "doc": { + "brief": "Set exit flag. You can get exit flag by app.need_exit().", + "param": { + "exit": "true if this APP should exit, false if not." + }, + "maixpy": "maix.app.set_exit_flag", + "py_doc": "Set exit flag. You can get exit flag by app.need_exit().\n\nArgs:\n - exit: true if this APP should exit, false if not.\n" + }, + "args": [ + [ + "bool", + "exit", + null + ] + ], + "ret_type": "void", + "static": false, + "def": "void set_exit_flag(bool exit)" + } + }, + "auto_add": true + }, + "protocol": { + "type": "module", + "doc": { + "brief": "maix.protocol module" + }, + "members": { + "VERSION": { + "type": "var", + "name": "", + "doc": { + "brief": "protocol version", + "maixpy": "maix.protocol.VERSION", + "py_doc": "protocol version" + }, + "value": "1", + "static": false, + "readonly": true, + "def": "const uint8_t VERSION = 1" + }, + "HEADER": { + "type": "var", + "name": "HEADER", + "doc": { + "brief": "protocol header", + "maixpy": "maix.protocol.HEADER", + "py_doc": "protocol header" + }, + "value": null, + "static": false, + "readonly": false, + "def": "extern uint32_t HEADER" + }, + "CMD": { + "type": "enum", + "name": "CMD", + "doc": { + "brief": "protocol cmd, more doc see MaixCDK document's convention doc", + "note": "max app custom CMD value should < CMD_APP_MAX", + "maixpy": "maix.protocol.CMD", + "py_doc": "protocol cmd, more doc see MaixCDK document's convention doc" + }, + "values": [ + [ + "CMD_APP_MAX", + "0xC8", + "200, max app custom CMD value should < CMD_APP_MAX" + ], + [ + "CMD_SET_REPORT", + "0xF8", + "set auto upload data mode" + ], + [ + "CMD_APP_LIST", + "0xF9", + "" + ], + [ + "CMD_START_APP", + "0xFA", + "" + ], + [ + "CMD_EXIT_APP", + "0xFB", + "" + ], + [ + "CMD_CUR_APP_INFO", + "0xFC", + "" + ], + [ + "CMD_APP_INFO", + "0xFD", + "" + ], + [ + "CMD_KEY", + "0xFE", + "" + ], + [ + "CMD_TOUCH", + "0xFF", + "" + ] + ], + "def": "enum CMD\n {\n CMD_APP_MAX = 0xC8, // 200, max app custom CMD value should < CMD_APP_MAX\n\n CMD_SET_REPORT = 0xF8, // set auto upload data mode\n CMD_APP_LIST = 0xF9,\n CMD_START_APP = 0xFA,\n CMD_EXIT_APP = 0xFB,\n CMD_CUR_APP_INFO = 0xFC,\n CMD_APP_INFO = 0xFD,\n CMD_KEY = 0xFE,\n CMD_TOUCH = 0xFF,\n }" + }, + "FLAGS": { + "type": "enum", + "name": "FLAGS", + "doc": { + "brief": "protocol flags, more doc see MaixCDK document's convention doc", + "maixpy": "maix.protocol.FLAGS", + "py_doc": "protocol flags, more doc see MaixCDK document's convention doc" + }, + "values": [ + [ + "FLAG_REQ", + "0x00", + "" + ], + [ + "FLAG_RESP", + "0x80", + "" + ], + [ + "FLAG_IS_RESP_MASK", + "0x80", + "" + ], + [ + "FLAG_RESP_OK", + "0x40", + "" + ], + [ + "FLAG_RESP_ERR", + "0x00", + "" + ], + [ + "FLAG_RESP_OK_MASK", + "0x40", + "" + ], + [ + "FLAG_REPORT", + "0x20", + "" + ], + [ + "FLAG_REPORT_MASK", + "0x20", + "" + ], + [ + "FLAG_VERSION_MASK", + "0x03", + "" + ] + ], + "def": "enum FLAGS\n {\n FLAG_REQ = 0x00,\n FLAG_RESP = 0x80,\n FLAG_IS_RESP_MASK = 0x80,\n\n FLAG_RESP_OK = 0x40,\n FLAG_RESP_ERR = 0x00,\n FLAG_RESP_OK_MASK = 0x40,\n\n FLAG_REPORT = 0x20,\n FLAG_REPORT_MASK = 0x20,\n\n FLAG_VERSION_MASK = 0x03\n }" + }, + "MSG": { + "type": "class", + "name": "MSG", + "doc": { + "brief": "protocol msg", + "maixpy": "maix.protocol.MSG", + "py_doc": "protocol msg" + }, + "members": { + "version": { + "type": "var", + "name": "version", + "doc": { + "brief": "protocol version", + "maixpy": "maix.protocol.MSG.version", + "py_doc": "protocol version" + }, + "value": null, + "static": false, + "readonly": false, + "def": "uint8_t version" + }, + "resp_ok": { + "type": "var", + "name": "resp_ok", + "doc": { + "brief": "Indicate response message type, true means CMD valid and the CMD processed correctly, (only for response msg)", + "maixpy": "maix.protocol.MSG.resp_ok", + "py_doc": "Indicate response message type, true means CMD valid and the CMD processed correctly, (only for response msg)" + }, + "value": null, + "static": false, + "readonly": false, + "def": "uint8_t resp_ok" + }, + "has_been_replied": { + "type": "var", + "name": "has_been_replied{false}", + "doc": { + "brief": "Flag whether CMD has been processed and responded to CMD sender.\\nE.g. CMD CMD_START_APP will be automatically processed in CommProtocol.get_msg function,\\nso the return msg will set this flag to true.", + "maixpy": "maix.protocol.MSG.has_been_replied", + "py_doc": "Flag whether CMD has been processed and responded to CMD sender.\nE.g. CMD CMD_START_APP will be automatically processed in CommProtocol.get_msg function,\nso the return msg will set this flag to true." + }, + "value": null, + "static": false, + "readonly": false, + "def": "bool has_been_replied{false}" + }, + "cmd": { + "type": "var", + "name": "cmd", + "doc": { + "brief": "CMD value", + "maixpy": "maix.protocol.MSG.cmd", + "py_doc": "CMD value" + }, + "value": null, + "static": false, + "readonly": false, + "def": "uint8_t cmd" + }, + "is_resp": { + "type": "var", + "name": "is_resp", + "doc": { + "brief": "message is response or not, contrast with is_req", + "maixpy": "maix.protocol.MSG.is_resp", + "py_doc": "message is response or not, contrast with is_req" + }, + "value": null, + "static": false, + "readonly": false, + "def": "bool is_resp" + }, + "body": { + "type": "var", + "name": "body", + "doc": { + "brief": "Message body, read only, use set_body() to update", + "attention": "DO NOT manually change this value", + "maixcdk": "maix.protocol.MSG.body", + "py_doc": "Message body, read only, use set_body() to update" + }, + "value": null, + "static": false, + "readonly": false, + "def": "uint8_t *body" + }, + "body_len": { + "type": "var", + "name": "body_len", + "doc": { + "brief": "Message body length, read only, use set_body() to update", + "attention": "DO NOT manually change this value", + "maixpy": "maix.protocol.MSG.body_len", + "py_doc": "Message body length, read only, use set_body() to update" + }, + "value": null, + "static": false, + "readonly": false, + "def": "int body_len" + }, + "encode_resp_ok": { + "type": "func", + "name": "encode_resp_ok", + "doc": { + "brief": "Encode response ok(success) message", + "param": { + "buff": "output buffer", + "buff_len": "output buffer length", + "body": "response body, can be null", + "body_len": "response body length, can be 0" + }, + "return": "encoded data length, if < 0, means error, and the error code is -err.Err", + "maixcdk": "maix.protocol.MSG.encode_resp_ok", + "py_doc": "Encode response ok(success) message\n\nArgs:\n - buff: output buffer\n - buff_len: output buffer length\n - body: response body, can be null\n - body_len: response body length, can be 0\n\n\nReturns: encoded data length, if < 0, means error, and the error code is -err.Err\n" + }, + "args": [ + [ + "uint8_t *", + "buff", + null + ], + [ + "int", + "buff_len", + null + ], + [ + "uint8_t *", + "body", + "nullptr" + ], + [ + "int", + "body_len", + "0" + ] + ], + "ret_type": "int", + "static": false, + "def": "int encode_resp_ok(uint8_t *buff, int buff_len, uint8_t *body = nullptr, int body_len = 0)", + "overload": [ + { + "type": "func", + "name": "encode_resp_ok", + "doc": { + "brief": "Encode response ok(success) message", + "param": { + "body": "response body, can be null" + }, + "return": "encoded data, if nullptr, means error, and the error code is -err.Err", + "maixcdk": "maix.protocol.MSG.encode_resp_ok", + "py_doc": "Encode response ok(success) message\n\nArgs:\n - body: response body, can be null\n\n\nReturns: encoded data, if nullptr, means error, and the error code is -err.Err\n" + }, + "args": [ + [ + "uint8_t *", + "body", + "nullptr" + ], + [ + "int", + "body_len", + "0" + ] + ], + "ret_type": "Bytes*", + "static": false, + "def": "Bytes *encode_resp_ok(uint8_t *body = nullptr, int body_len = 0)" + }, + { + "type": "func", + "name": "encode_resp_ok", + "doc": { + "brief": "Encode response ok(success) message", + "param": { + "body": "response body, can be null" + }, + "return": "encoded data, if nullptr, means error, and the error code is -err.Err", + "maixpy": "maix.protocol.MSG.encode_resp_ok", + "py_doc": "Encode response ok(success) message\n\nArgs:\n - body: response body, can be null\n\n\nReturns: encoded data, if nullptr, means error, and the error code is -err.Err\n" + }, + "args": [ + [ + "Bytes *", + "body", + "nullptr" + ] + ], + "ret_type": "Bytes*", + "static": false, + "def": "Bytes *encode_resp_ok(Bytes *body = nullptr)" + } + ] + }, + "encode_report": { + "type": "func", + "name": "encode_report", + "doc": { + "brief": "Encode proactively report message", + "param": { + "buff": "output buffer", + "buff_len": "output buffer length", + "body": "report body, can be null", + "body_len": "report body length, can be 0" + }, + "return": "encoded data length, if < 0, means error, and the error code is -err.Err", + "maixcdk": "maix.protocol.MSG.encode_report", + "py_doc": "Encode proactively report message\n\nArgs:\n - buff: output buffer\n - buff_len: output buffer length\n - body: report body, can be null\n - body_len: report body length, can be 0\n\n\nReturns: encoded data length, if < 0, means error, and the error code is -err.Err\n" + }, + "args": [ + [ + "uint8_t *", + "buff", + null + ], + [ + "int", + "buff_len", + null + ], + [ + "uint8_t *", + "body", + "nullptr" + ], + [ + "int", + "body_len", + "0" + ] + ], + "ret_type": "int", + "static": false, + "def": "int encode_report(uint8_t *buff, int buff_len, uint8_t *body = nullptr, int body_len = 0)", + "overload": [ + { + "type": "func", + "name": "encode_report", + "doc": { + "brief": "Encode proactively report message", + "param": { + "body": "report body, can be null" + }, + "return": "encoded data, if nullptr, means error, and the error code is -err.Err", + "maixcdk": "maix.protocol.MSG.encode_report", + "py_doc": "Encode proactively report message\n\nArgs:\n - body: report body, can be null\n\n\nReturns: encoded data, if nullptr, means error, and the error code is -err.Err\n" + }, + "args": [ + [ + "uint8_t *", + "body", + "nullptr" + ], + [ + "int", + "body_len", + "0" + ] + ], + "ret_type": "Bytes*", + "static": false, + "def": "Bytes *encode_report(uint8_t *body = nullptr, int body_len = 0)" + }, + { + "type": "func", + "name": "encode_report", + "doc": { + "brief": "Encode proactively report message", + "param": { + "body": "report body, can be null" + }, + "return": "encoded data, if nullptr, means error, and the error code is -err.Err", + "maixpy": "maix.protocol.MSG.encode_report", + "py_doc": "Encode proactively report message\n\nArgs:\n - body: report body, can be null\n\n\nReturns: encoded data, if nullptr, means error, and the error code is -err.Err\n" + }, + "args": [ + [ + "Bytes *", + "body", + "nullptr" + ] + ], + "ret_type": "Bytes*", + "static": false, + "def": "Bytes *encode_report(Bytes *body = nullptr)" + } + ] + }, + "encode_resp_err": { + "type": "func", + "name": "encode_resp_err", + "doc": { + "brief": "Encode response error message", + "param": { + "buff": "output buffer", + "buff_len": "output buffer length", + "code": "error code", + "msg": "error message" + }, + "return": "encoded data length, if < 0, means error, and the error code is -err.Err", + "maixcdk": "maix.protocol.MSG.encode_resp_err", + "py_doc": "Encode response error message\n\nArgs:\n - buff: output buffer\n - buff_len: output buffer length\n - code: error code\n - msg: error message\n\n\nReturns: encoded data length, if < 0, means error, and the error code is -err.Err\n" + }, + "args": [ + [ + "uint8_t *", + "buff", + null + ], + [ + "int", + "buff_len", + null + ], + [ + "err::Err", + "code", + null + ], + [ + "const std::string &", + "msg", + null + ] + ], + "ret_type": "int", + "static": false, + "def": "int encode_resp_err(uint8_t *buff, int buff_len, err::Err code, const std::string &msg)", + "overload": [ + { + "type": "func", + "name": "encode_resp_err", + "doc": { + "brief": "Encode response error message", + "param": { + "code": "error code", + "msg": "error message" + }, + "return": "encoded data, if nullptr, means error, and the error code is -err.Err", + "maixpy": "maix.protocol.MSG.encode_resp_err", + "py_doc": "Encode response error message\n\nArgs:\n - code: error code\n - msg: error message\n\n\nReturns: encoded data, if nullptr, means error, and the error code is -err.Err\n" + }, + "args": [ + [ + "err::Err", + "code", + null + ], + [ + "const std::string &", + "msg", + null + ] + ], + "ret_type": "Bytes*", + "static": false, + "def": "Bytes *encode_resp_err(err::Err code, const std::string &msg)" + } + ] + }, + "set_body": { + "type": "func", + "name": "set_body", + "doc": { + "brief": "Update message body", + "param": { + "body_new": "new body data", + "body_len": "new body data length" + }, + "maixcdk": "maix.protocol.MSG.set_body", + "py_doc": "Update message body\n\nArgs:\n - body_new: new body data\n - body_len: new body data length\n" + }, + "args": [ + [ + "uint8_t *", + "body_new", + null + ], + [ + "int", + "body_len", + null + ] + ], + "ret_type": "void", + "static": false, + "def": "void set_body(uint8_t *body_new, int body_len)", + "overload": [ + { + "type": "func", + "name": "set_body", + "doc": { + "brief": "Update message body", + "param": { + "body_new": "new body data" + }, + "maixpy": "maix.protocol.MSG.set_body", + "py_doc": "Update message body\n\nArgs:\n - body_new: new body data\n" + }, + "args": [ + [ + "Bytes *", + "body_new", + null + ] + ], + "ret_type": "void", + "static": false, + "def": "void set_body(Bytes *body_new)" + } + ] + }, + "get_body": { + "type": "func", + "name": "get_body", + "doc": { + "brief": "Get message body", + "return": "message body, bytes type", + "maixpy": "maix.protocol.MSG.get_body", + "py_doc": "Get message body\n\nReturns: message body, bytes type\n" + }, + "args": [], + "ret_type": "Bytes*", + "static": false, + "def": "Bytes *get_body()" + } + }, + "def": "class MSG" + }, + "Protocol": { + "type": "class", + "name": "Protocol", + "doc": { + "brief": "Communicate protocol", + "maixpy": "maix.protocol.Protocol", + "py_doc": "Communicate protocol" + }, + "members": { + "Protocol": { + "type": "func", + "name": "Protocol", + "doc": { + "brief": "Construct a new Protocol object", + "param": { + "buff_size": "Data queue buffer size" + }, + "maixpy": "maix.protocol.Protocol.__init__", + "maixcdk": "maix.protocol.Protocol.Protocol", + "py_doc": "Construct a new Protocol object\n\nArgs:\n - buff_size: Data queue buffer size\n" + }, + "args": [ + [ + "int", + "buff_size", + "1024" + ], + [ + "uint32_t", + "header", + "maix::protocol::HEADER" + ] + ], + "ret_type": null, + "static": false, + "def": "Protocol(int buff_size = 1024, uint32_t header=maix::protocol::HEADER)" + }, + "buff_size": { + "type": "func", + "name": "buff_size", + "doc": { + "brief": "Data queue buffer size", + "maixpy": "maix.protocol.Protocol.buff_size", + "py_doc": "Data queue buffer size" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int buff_size()" + }, + "push_data": { + "type": "func", + "name": "push_data", + "doc": { + "brief": "Add data to data queue", + "param": { + "new_data": "new data", + "len": "new data length" + }, + "return": "error code, maybe err.Err.ERR_BUFF_FULL", + "maixcdk": "maix.protocol.Protocol.push_data", + "py_doc": "Add data to data queue\n\nArgs:\n - new_data: new data\n - len: new data length\n\n\nReturns: error code, maybe err.Err.ERR_BUFF_FULL\n" + }, + "args": [ + [ + "uint8_t *", + "new_data", + null + ], + [ + "int", + "len", + null + ] + ], + "ret_type": "err::Err", + "static": false, + "def": "err::Err push_data(uint8_t *new_data, int len)", + "overload": [ + { + "type": "func", + "name": "push_data", + "doc": { + "brief": "Add data to data queue", + "param": { + "new_data": "new data" + }, + "return": "error code, maybe err.Err.ERR_BUFF_FULL", + "maixpy": "maix.protocol.Protocol.push_data", + "py_doc": "Add data to data queue\n\nArgs:\n - new_data: new data\n\n\nReturns: error code, maybe err.Err.ERR_BUFF_FULL\n" + }, + "args": [ + [ + "const Bytes *", + "new_data", + null + ] + ], + "ret_type": "err::Err", + "static": false, + "def": "err::Err push_data(const Bytes *new_data)" + } + ] + }, + "decode": { + "type": "func", + "name": "decode", + "doc": { + "brief": "Decode data in data queue and return a message", + "param": { + "new_data": "new data add to data queue, if null, only decode.", + "len": "new data length, can be 0." + }, + "return": "decoded message, if nullptr, means no message decoded.", + "maixcdk": "maix.protocol.Protocol.decode", + "py_doc": "Decode data in data queue and return a message\n\nArgs:\n - new_data: new data add to data queue, if null, only decode.\n - len: new data length, can be 0.\n\n\nReturns: decoded message, if nullptr, means no message decoded.\n" + }, + "args": [ + [ + "uint8_t *", + "new_data", + "nullptr" + ], + [ + "size_t", + "len", + "0" + ] + ], + "ret_type": "protocol::MSG*", + "static": false, + "def": "protocol::MSG *decode(uint8_t *new_data = nullptr, size_t len = 0)", + "overload": [ + { + "type": "func", + "name": "decode", + "doc": { + "brief": "Decode data in data queue and return a message", + "param": { + "new_data": "new data add to data queue, if null, only decode." + }, + "return": "decoded message, if nullptr, means no message decoded.", + "maixpy": "maix.protocol.Protocol.decode", + "py_doc": "Decode data in data queue and return a message\n\nArgs:\n - new_data: new data add to data queue, if null, only decode.\n\n\nReturns: decoded message, if nullptr, means no message decoded.\n" + }, + "args": [ + [ + "const Bytes *", + "new_data", + "nullptr" + ] + ], + "ret_type": "protocol::MSG*", + "static": false, + "def": "protocol::MSG *decode(const Bytes *new_data = nullptr)" + } + ] + }, + "encode_resp_ok": { + "type": "func", + "name": "encode_resp_ok", + "doc": { + "brief": "Encode response ok(success) message to buffer", + "param": { + "buff": "output buffer", + "buff_len": "output buffer length", + "cmd": "CMD value", + "body": "response body, can be null", + "body_len": "response body length, can be 0" + }, + "return": "encoded data length, if < 0, means error, and the error code is -err.Err", + "maixcdk": "maix.protocol.Protocol.encode_resp_ok", + "py_doc": "Encode response ok(success) message to buffer\n\nArgs:\n - buff: output buffer\n - buff_len: output buffer length\n - cmd: CMD value\n - body: response body, can be null\n - body_len: response body length, can be 0\n\n\nReturns: encoded data length, if < 0, means error, and the error code is -err.Err\n" + }, + "args": [ + [ + "uint8_t *", + "buff", + null + ], + [ + "int", + "buff_len", + null + ], + [ + "uint8_t", + "cmd", + null + ], + [ + "uint8_t *", + "body", + "nullptr" + ], + [ + "int", + "body_len", + "0" + ] + ], + "ret_type": "int", + "static": false, + "def": "int encode_resp_ok(uint8_t *buff, int buff_len, uint8_t cmd, uint8_t *body = nullptr, int body_len = 0)", + "overload": [ + { + "type": "func", + "name": "encode_resp_ok", + "doc": { + "brief": "Encode response ok(success) message to buffer", + "param": { + "cmd": "CMD value", + "body": "response body, can be null", + "body_len": "response body length, can be 0" + }, + "return": "encoded data, if nullptr, means error, and the error code is -err.Err", + "maixcdk": "maix.protocol.Protocol.encode_resp_ok", + "py_doc": "Encode response ok(success) message to buffer\n\nArgs:\n - cmd: CMD value\n - body: response body, can be null\n - body_len: response body length, can be 0\n\n\nReturns: encoded data, if nullptr, means error, and the error code is -err.Err\n" + }, + "args": [ + [ + "uint8_t", + "cmd", + null + ], + [ + "uint8_t *", + "body", + "nullptr" + ], + [ + "int", + "body_len", + "0" + ] + ], + "ret_type": "Bytes*", + "static": false, + "def": "Bytes *encode_resp_ok(uint8_t cmd, uint8_t *body = nullptr, int body_len = 0)" + }, + { + "type": "func", + "name": "encode_resp_ok", + "doc": { + "brief": "Encode response ok(success) message to buffer", + "param": { + "cmd": "CMD value", + "body": "response body, can be null" + }, + "return": "encoded data, if nullptr, means error, and the error code is -err.Err", + "maixpy": "maix.protocol.Protocol.encode_resp_ok", + "py_doc": "Encode response ok(success) message to buffer\n\nArgs:\n - cmd: CMD value\n - body: response body, can be null\n\n\nReturns: encoded data, if nullptr, means error, and the error code is -err.Err\n" + }, + "args": [ + [ + "uint8_t", + "cmd", + null + ], + [ + "Bytes *", + "body", + "nullptr" + ] + ], + "ret_type": "Bytes*", + "static": false, + "def": "Bytes *encode_resp_ok(uint8_t cmd, Bytes *body = nullptr)" + } + ] + }, + "encode_report": { + "type": "func", + "name": "encode_report", + "doc": { + "brief": "Encode proactively report message to buffer", + "param": { + "buff": "output buffer", + "buff_len": "output buffer length", + "cmd": "CMD value", + "body": "report body, can be null", + "body_len": "report body length, can be 0" + }, + "return": "encoded data length, if < 0, means error, and the error code is -err.Err", + "maixcdk": "maix.protocol.Protocol.encode_report", + "py_doc": "Encode proactively report message to buffer\n\nArgs:\n - buff: output buffer\n - buff_len: output buffer length\n - cmd: CMD value\n - body: report body, can be null\n - body_len: report body length, can be 0\n\n\nReturns: encoded data length, if < 0, means error, and the error code is -err.Err\n" + }, + "args": [ + [ + "uint8_t *", + "buff", + null + ], + [ + "int", + "buff_len", + null + ], + [ + "uint8_t", + "cmd", + null + ], + [ + "uint8_t *", + "body", + "nullptr" + ], + [ + "int", + "body_len", + "0" + ] + ], + "ret_type": "int", + "static": false, + "def": "int encode_report(uint8_t *buff, int buff_len, uint8_t cmd, uint8_t *body = nullptr, int body_len = 0)", + "overload": [ + { + "type": "func", + "name": "encode_report", + "doc": { + "brief": "Encode proactively report message to buffer", + "param": { + "cmd": "CMD value", + "body": "report body, can be null", + "body_len": "report body length, can be 0" + }, + "return": "encoded data, if nullptr, means error, and the error code is -err.Err", + "maixcdk": "maix.protocol.Protocol.encode_report", + "py_doc": "Encode proactively report message to buffer\n\nArgs:\n - cmd: CMD value\n - body: report body, can be null\n - body_len: report body length, can be 0\n\n\nReturns: encoded data, if nullptr, means error, and the error code is -err.Err\n" + }, + "args": [ + [ + "uint8_t", + "cmd", + null + ], + [ + "uint8_t *", + "body", + "nullptr" + ], + [ + "int", + "body_len", + "0" + ] + ], + "ret_type": "Bytes*", + "static": false, + "def": "Bytes *encode_report(uint8_t cmd, uint8_t *body = nullptr, int body_len = 0)" + }, + { + "type": "func", + "name": "encode_report", + "doc": { + "brief": "Encode proactively report message to buffer", + "param": { + "cmd": "CMD value", + "body": "report body, can be null" + }, + "return": "encoded data, if nullptr, means error, and the error code is -err.Err", + "maixpy": "maix.protocol.Protocol.encode_report", + "py_doc": "Encode proactively report message to buffer\n\nArgs:\n - cmd: CMD value\n - body: report body, can be null\n\n\nReturns: encoded data, if nullptr, means error, and the error code is -err.Err\n" + }, + "args": [ + [ + "uint8_t", + "cmd", + null + ], + [ + "Bytes *", + "body", + "nullptr" + ] + ], + "ret_type": "Bytes*", + "static": false, + "def": "Bytes *encode_report(uint8_t cmd, Bytes *body = nullptr)" + } + ] + }, + "encode_resp_err": { + "type": "func", + "name": "encode_resp_err", + "doc": { + "brief": "Encode response error message to buffer", + "param": { + "buff": "output buffer", + "buff_len": "output buffer length", + "cmd": "CMD value", + "code": "error code", + "msg": "error message" + }, + "return": "encoded data length, if < 0, means error, and the error code is -err.Err", + "maixcdk": "maix.protocol.Protocol.encode_resp_err", + "py_doc": "Encode response error message to buffer\n\nArgs:\n - buff: output buffer\n - buff_len: output buffer length\n - cmd: CMD value\n - code: error code\n - msg: error message\n\n\nReturns: encoded data length, if < 0, means error, and the error code is -err.Err\n" + }, + "args": [ + [ + "uint8_t *", + "buff", + null + ], + [ + "int", + "buff_len", + null + ], + [ + "uint8_t", + "cmd", + null + ], + [ + "err::Err", + "code", + null + ], + [ + "const std::string &", + "msg", + null + ] + ], + "ret_type": "int", + "static": false, + "def": "int encode_resp_err(uint8_t *buff, int buff_len, uint8_t cmd, err::Err code, const std::string &msg)", + "overload": [ + { + "type": "func", + "name": "encode_resp_err", + "doc": { + "brief": "Encode response error message to buffer", + "param": { + "cmd": "CMD value", + "code": "error code", + "msg": "error message" + }, + "return": "encoded data, if nullptr, means error, and the error code is -err.Err", + "maixpy": "maix.protocol.Protocol.encode_resp_err", + "py_doc": "Encode response error message to buffer\n\nArgs:\n - cmd: CMD value\n - code: error code\n - msg: error message\n\n\nReturns: encoded data, if nullptr, means error, and the error code is -err.Err\n" + }, + "args": [ + [ + "uint8_t", + "cmd", + null + ], + [ + "err::Err", + "code", + null + ], + [ + "const std::string &", + "msg", + null + ] + ], + "ret_type": "Bytes*", + "static": false, + "def": "Bytes *encode_resp_err(uint8_t cmd, err::Err code, const std::string &msg)" + } + ] + } + }, + "def": "class Protocol" + }, + "crc16_IBM": { + "type": "func", + "name": "crc16_IBM", + "doc": { + "brief": "CRC16-IBM", + "param": { + "data": "data", + "len": "data length" + }, + "return": "CRC16-IBM value, uint16_t type.", + "maixcdk": "maix.protocol.crc16_IBM", + "py_doc": "CRC16-IBM\n\nArgs:\n - data: data\n - len: data length\n\n\nReturns: CRC16-IBM value, uint16_t type.\n" + }, + "args": [ + [ + "unsigned char *", + "data", + null + ], + [ + "size_t", + "len", + null + ] + ], + "ret_type": "uint16_t", + "static": false, + "def": "uint16_t crc16_IBM(unsigned char *data, size_t len)", + "overload": [ + { + "type": "func", + "name": "crc16_IBM", + "doc": { + "brief": "CRC16-IBM", + "param": { + "data": "data, bytes type." + }, + "return": "CRC16-IBM value, uint16_t type.", + "maixpy": "maix.protocol.crc16_IBM", + "py_doc": "CRC16-IBM\n\nArgs:\n - data: data, bytes type.\n\n\nReturns: CRC16-IBM value, uint16_t type.\n" + }, + "args": [ + [ + "const Bytes *", + "data", + null + ] + ], + "ret_type": "uint16_t", + "static": false, + "def": "uint16_t crc16_IBM(const Bytes *data)" + } + ] + }, + "encode": { + "type": "func", + "name": "encode", + "doc": { + "brief": "Encode message to buffer", + "param": { + "out_buff": "output buffer", + "out_buff_len": "output buffer length", + "cmd": "CMD value", + "flags": "FLAGS value, @see maix.protocol.FLAGS", + "body": "message body, can be null", + "body_len": "message body length, can be 0", + "code": "error code, only for error message, that is FLAGS.FLAG_ERR in flags", + "version": "protocol version" + }, + "return": "encoded data length, if < 0, means error, and the error code is -err.Err", + "maixcdk": "maix.protocol.encode", + "py_doc": "Encode message to buffer\n\nArgs:\n - out_buff: output buffer\n - out_buff_len: output buffer length\n - cmd: CMD value\n - flags: FLAGS value, @see maix.protocol.FLAGS\n - body: message body, can be null\n - body_len: message body length, can be 0\n - code: error code, only for error message, that is FLAGS.FLAG_ERR in flags\n - version: protocol version\n\n\nReturns: encoded data length, if < 0, means error, and the error code is -err.Err\n" + }, + "args": [ + [ + "uint8_t *", + "out_buff", + null + ], + [ + "int", + "out_buff_len", + null + ], + [ + "uint8_t", + "cmd", + null + ], + [ + "uint8_t", + "flags", + null + ], + [ + "uint8_t *", + "body", + null + ], + [ + "int", + "body_len", + null + ], + [ + "uint8_t", + "code", + "0xFF" + ], + [ + "const uint8_t", + "version", + "VERSION" + ] + ], + "ret_type": "int", + "static": false, + "def": "int encode(uint8_t *out_buff, int out_buff_len, uint8_t cmd, uint8_t flags, uint8_t *body, int body_len, uint8_t code = 0xFF, const uint8_t version = VERSION)" + } + }, + "auto_add": true + }, + "time": { + "type": "module", + "doc": { + "brief": "maix.time module" + }, + "members": { + "time": { + "type": "func", + "name": "time", + "doc": { + "brief": "Get current time in s", + "return": "current time in s, double type", + "attention": "If board have no RTC battery, when bootup and connect to network,\nsystem will automatically sync time by NTP, will cause time() have big change,\ne.g. before NTP: 10(s), after: 1718590639.5149617(s).\nIf you want to calculate time interval, please use ticks_s().", + "maixpy": "maix.time.time", + "py_doc": "Get current time in s\n\nReturns: current time in s, double type\n" + }, + "args": [], + "ret_type": "double", + "static": false, + "def": "double time()" + }, + "time_ms": { + "type": "func", + "name": "time_ms", + "doc": { + "brief": "Get current time in ms", + "return": "current time in ms, uint64_t type", + "attention": "If board have no RTC battery, when bootup and connect to network,\nsystem will automatically sync time by NTP, will cause time() have big change,\ne.g. before NTP: 10000(ms), after: 1718590639000(ms)\nIf you want to calculate time interval, please use ticks_ms().", + "maixpy": "maix.time.time_ms", + "py_doc": "Get current time in ms\n\nReturns: current time in ms, uint64_t type\n" + }, + "args": [], + "ret_type": "uint64_t", + "static": false, + "def": "uint64_t time_ms()" + }, + "time_s": { + "type": "func", + "name": "time_s", + "doc": { + "brief": "Get current time in s", + "return": "current time in s, uint64_t type", + "attention": "If board have no RTC battery, when bootup and connect to network,\nsystem will automatically sync time by NTP, will cause time() have big change,\ne.g. before NTP: 10(s), after: 1718590639(s)", + "maixpy": "maix.time.time_s", + "py_doc": "Get current time in s\n\nReturns: current time in s, uint64_t type\n" + }, + "args": [], + "ret_type": "uint64_t", + "static": false, + "def": "uint64_t time_s()" + }, + "time_us": { + "type": "func", + "name": "time_us", + "doc": { + "brief": "Get current time in us", + "return": "current time in us, uint64_t type", + "attention": "If board have no RTC battery, when bootup and connect to network,\nsystem will automatically sync time by NTP, will cause time() have big change,\ne.g. before NTP: 10000000(us), after: 1718590639000000(s)\nIf you want to calculate time interval, please use ticks_us().", + "maixpy": "maix.time.time_us", + "py_doc": "Get current time in us\n\nReturns: current time in us, uint64_t type\n" + }, + "args": [], + "ret_type": "uint64_t", + "static": false, + "def": "uint64_t time_us()" + }, + "time_diff": { + "type": "func", + "name": "time_diff", + "doc": { + "brief": "Calculate time difference in s.", + "param": { + "last": "last time", + "now": "current time, can be -1 if use current time" + }, + "return": "time difference", + "attention": "If board have no RTC battery, when bootup and connect to network,\nsystem will automatically sync time by NTP, will cause time() have big change, and lead to big value.\ne.g. before NTP: 1(s), after: 1718590500(s)\nIf you want to calculate time interval, please use ticks_diff().", + "maixpy": "maix.time.time_diff", + "py_doc": "Calculate time difference in s.\n\nArgs:\n - last: last time\n - now: current time, can be -1 if use current time\n\n\nReturns: time difference\n" + }, + "args": [ + [ + "double", + "last", + null + ], + [ + "double", + "now", + "-1" + ] + ], + "ret_type": "double", + "static": false, + "def": "double time_diff(double last, double now = -1)" + }, + "ticks_s": { + "type": "func", + "name": "ticks_s", + "doc": { + "brief": "Get current time in s since bootup", + "return": "current time in s, double type", + "maixpy": "maix.time.ticks_s", + "py_doc": "Get current time in s since bootup\n\nReturns: current time in s, double type\n" + }, + "args": [], + "ret_type": "double", + "static": false, + "def": "double ticks_s()" + }, + "ticks_ms": { + "type": "func", + "name": "ticks_ms", + "doc": { + "brief": "Get current time in ms since bootup", + "return": "current time in ms, uint64_t type", + "maixpy": "maix.time.ticks_ms", + "py_doc": "Get current time in ms since bootup\n\nReturns: current time in ms, uint64_t type\n" + }, + "args": [], + "ret_type": "uint64_t", + "static": false, + "def": "uint64_t ticks_ms()" + }, + "ticks_us": { + "type": "func", + "name": "ticks_us", + "doc": { + "brief": "Get current time in us since bootup", + "return": "current time in us, uint64_t type", + "maixpy": "maix.time.ticks_us", + "py_doc": "Get current time in us since bootup\n\nReturns: current time in us, uint64_t type\n" + }, + "args": [], + "ret_type": "uint64_t", + "static": false, + "def": "uint64_t ticks_us()" + }, + "ticks_diff": { + "type": "func", + "name": "ticks_diff", + "doc": { + "brief": "Calculate time difference in s.", + "param": { + "last": "last time", + "now": "current time, can be -1 if use current time" + }, + "return": "time difference", + "maixpy": "maix.time.ticks_diff", + "py_doc": "Calculate time difference in s.\n\nArgs:\n - last: last time\n - now: current time, can be -1 if use current time\n\n\nReturns: time difference\n" + }, + "args": [ + [ + "double", + "last", + null + ], + [ + "double", + "now", + "-1" + ] + ], + "ret_type": "double", + "static": false, + "def": "double ticks_diff(double last, double now = -1)" + }, + "sleep": { + "type": "func", + "name": "sleep", + "doc": { + "brief": "Sleep seconds", + "param": { + "s": "seconds, double type" + }, + "maixpy": "maix.time.sleep", + "py_doc": "Sleep seconds\n\nArgs:\n - s: seconds, double type\n" + }, + "args": [ + [ + "double", + "s", + null + ] + ], + "ret_type": "void", + "static": false, + "def": "void sleep(double s)" + }, + "sleep_ms": { + "type": "func", + "name": "sleep_ms", + "doc": { + "brief": "Sleep milliseconds", + "param": { + "ms": "milliseconds, uint64_t type" + }, + "maixpy": "maix.time.sleep_ms", + "py_doc": "Sleep milliseconds\n\nArgs:\n - ms: milliseconds, uint64_t type\n" + }, + "args": [ + [ + "uint64_t", + "ms", + null + ] + ], + "ret_type": "void", + "static": false, + "def": "void sleep_ms(uint64_t ms)" + }, + "sleep_us": { + "type": "func", + "name": "sleep_us", + "doc": { + "brief": "Sleep microseconds", + "param": { + "us": "microseconds, uint64_t type" + }, + "maixpy": "maix.time.sleep_us", + "py_doc": "Sleep microseconds\n\nArgs:\n - us: microseconds, uint64_t type\n" + }, + "args": [ + [ + "uint64_t", + "us", + null + ] + ], + "ret_type": "void", + "static": false, + "def": "void sleep_us(uint64_t us)" + }, + "fps": { + "type": "func", + "name": "fps", + "doc": { + "brief": "Calculate FPS since last call this method.\\nAttention, this method is not multi thread safe, only call this method in one threads.\\nIf you want to use in multi threads, please use time.FPS class.\\nFPS is average value of recent n(buff_len) times, and you can call fps_set_buff_len(10) to change buffer length, default is 20.\\nMultiple invoke this function will calculate fps between two invoke, and you can also call fps_start() fisrt to manually assign fps calulate start point.", + "return": "float type, current fps since last call this method", + "maixpy": "maix.time.fps", + "py_doc": "Calculate FPS since last call this method.\nAttention, this method is not multi thread safe, only call this method in one threads.\nIf you want to use in multi threads, please use time.FPS class.\nFPS is average value of recent n(buff_len) times, and you can call fps_set_buff_len(10) to change buffer length, default is 20.\nMultiple invoke this function will calculate fps between two invoke, and you can also call fps_start() fisrt to manually assign fps calulate start point.\n\nReturns: float type, current fps since last call this method\n" + }, + "args": [], + "ret_type": "float", + "static": false, + "def": "float fps()" + }, + "fps_start": { + "type": "func", + "name": "fps_start", + "doc": { + "brief": "Manually set fps calculation start point, then you can call fps() function to calculate fps between fps_start() and fps().", + "maixpy": "maix.time.fps_start", + "py_doc": "Manually set fps calculation start point, then you can call fps() function to calculate fps between fps_start() and fps()." + }, + "args": [], + "ret_type": "void", + "static": false, + "def": "void fps_start()" + }, + "fps_set_buff_len": { + "type": "func", + "name": "fps_set_buff_len", + "doc": { + "brief": "Set fps method buffer length, by default the buffer length is 10.", + "param": { + "len": "Buffer length to store recent fps value." + }, + "maixpy": "maix.time.fps_set_buff_len", + "py_doc": "Set fps method buffer length, by default the buffer length is 10.\n\nArgs:\n - len: Buffer length to store recent fps value.\n" + }, + "args": [ + [ + "int", + "len", + null + ] + ], + "ret_type": "void", + "static": false, + "def": "void fps_set_buff_len(int len)" + }, + "FPS": { + "type": "class", + "name": "FPS", + "doc": { + "brief": "FPS class to use average filter to calculate FPS.", + "maixpy": "maix.time.FPS", + "py_doc": "FPS class to use average filter to calculate FPS." + }, + "members": { + "FPS": { + "type": "func", + "name": "FPS", + "doc": { + "brief": "FPS class constructor", + "param": { + "buff_len": "Average buffer length, default 20, that is, fps() function will return the average fps in recent buff_len times fps." + }, + "maixpy": "maix.time.FPS.__init__", + "maixcdk": "maix.time.FPS.FPS", + "py_doc": "FPS class constructor\n\nArgs:\n - buff_len: Average buffer length, default 20, that is, fps() function will return the average fps in recent buff_len times fps.\n" + }, + "args": [ + [ + "int", + "buff_len", + "20" + ] + ], + "ret_type": null, + "static": false, + "def": "FPS(int buff_len = 20)" + }, + "start": { + "type": "func", + "name": "start", + "doc": { + "brief": "Manually set fps calculation start point, then you can call fps() function to calculate fps between start() and fps().", + "maixpy": "maix.time.FPS.start", + "py_doc": "Manually set fps calculation start point, then you can call fps() function to calculate fps between start() and fps()." + }, + "args": [], + "ret_type": "void", + "static": false, + "def": "void start()" + }, + "fps": { + "type": "func", + "name": "fps", + "doc": { + "brief": "The same as end function.", + "return": "float type, current fps since last call this method", + "maixpy": "maix.time.FPS.fps", + "py_doc": "The same as end function.\n\nReturns: float type, current fps since last call this method\n" + }, + "args": [], + "ret_type": "float", + "static": false, + "def": "float fps()", + "overload": [ + { + "type": "func", + "name": "end", + "doc": { + "brief": "Calculate FPS since last call this method.\\nFPS is average value of recent n(buff_len) times, and you can call fps_set_buff_len(10) to change buffer length, default is 20.\\nMultiple invoke this function will calculate fps between two invoke, and you can also call fps_start() fisrt to manually assign fps calulate start point.", + "return": "float type, current fps since last call this method", + "maixpy": "maix.time.FPS.fps", + "py_doc": "Calculate FPS since last call this method.\nFPS is average value of recent n(buff_len) times, and you can call fps_set_buff_len(10) to change buffer length, default is 20.\nMultiple invoke this function will calculate fps between two invoke, and you can also call fps_start() fisrt to manually assign fps calulate start point.\n\nReturns: float type, current fps since last call this method\n" + }, + "args": [], + "ret_type": "inline float", + "static": false, + "def": "inline float end()" + } + ] + }, + "set_buff_len": { + "type": "func", + "name": "set_buff_len", + "doc": { + "brief": "Set fps method buffer length, by default the buffer length is 10.", + "param": { + "len": "Buffer length to store recent fps value." + }, + "maixpy": "maix.time.FPS.set_buff_len", + "py_doc": "Set fps method buffer length, by default the buffer length is 10.\n\nArgs:\n - len: Buffer length to store recent fps value.\n" + }, + "args": [ + [ + "int", + "len", + null + ] + ], + "ret_type": "void", + "static": false, + "def": "void set_buff_len(int len)" + } + }, + "def": "class FPS" + }, + "DateTime": { + "type": "class", + "name": "DateTime", + "doc": { + "brief": "Date and time class", + "maixpy": "maix.time.DateTime", + "py_doc": "Date and time class" + }, + "members": { + "year": { + "type": "var", + "name": "year", + "doc": { + "brief": "Year", + "maixpy": "maix.time.DateTime.year", + "py_doc": "Year" + }, + "value": null, + "static": false, + "readonly": false, + "def": "int year" + }, + "month": { + "type": "var", + "name": "month", + "doc": { + "brief": "Month, 1~12", + "maixpy": "maix.time.DateTime.month", + "py_doc": "Month, 1~12" + }, + "value": null, + "static": false, + "readonly": false, + "def": "int month" + }, + "day": { + "type": "var", + "name": "day", + "doc": { + "brief": "Day", + "maixpy": "maix.time.DateTime.day", + "py_doc": "Day" + }, + "value": null, + "static": false, + "readonly": false, + "def": "int day" + }, + "hour": { + "type": "var", + "name": "hour", + "doc": { + "brief": "Hour", + "maixpy": "maix.time.DateTime.hour", + "py_doc": "Hour" + }, + "value": null, + "static": false, + "readonly": false, + "def": "int hour" + }, + "minute": { + "type": "var", + "name": "minute", + "doc": { + "brief": "Minute", + "maixpy": "maix.time.DateTime.minute", + "py_doc": "Minute" + }, + "value": null, + "static": false, + "readonly": false, + "def": "int minute" + }, + "second": { + "type": "var", + "name": "second", + "doc": { + "brief": "Second", + "maixpy": "maix.time.DateTime.second", + "py_doc": "Second" + }, + "value": null, + "static": false, + "readonly": false, + "def": "int second" + }, + "microsecond": { + "type": "var", + "name": "microsecond", + "doc": { + "brief": "Microsecond", + "maixpy": "maix.time.DateTime.microsecond", + "py_doc": "Microsecond" + }, + "value": null, + "static": false, + "readonly": false, + "def": "int microsecond" + }, + "yearday": { + "type": "var", + "name": "yearday", + "doc": { + "brief": "Year day", + "maixpy": "maix.time.DateTime.yearday", + "py_doc": "Year day" + }, + "value": null, + "static": false, + "readonly": false, + "def": "int yearday" + }, + "weekday": { + "type": "var", + "name": "weekday", + "doc": { + "brief": "Weekday, 0 is Monday, 6 is Sunday", + "maixpy": "maix.time.DateTime.weekday", + "py_doc": "Weekday, 0 is Monday, 6 is Sunday" + }, + "value": null, + "static": false, + "readonly": false, + "def": "int weekday" + }, + "zone": { + "type": "var", + "name": "zone", + "doc": { + "brief": "Time zone", + "maixpy": "maix.time.DateTime.zone", + "py_doc": "Time zone" + }, + "value": null, + "static": false, + "readonly": false, + "def": "float zone" + }, + "zone_name": { + "type": "var", + "name": "zone_name", + "doc": { + "brief": "Time zone name", + "maixpy": "maix.time.DateTime.zone_name", + "py_doc": "Time zone name" + }, + "value": null, + "static": false, + "readonly": false, + "def": "std::string zone_name" + }, + "DateTime": { + "type": "func", + "name": "DateTime", + "doc": { + "brief": "Constructor", + "param": { + "year": "year", + "month": "month", + "day": "day", + "hour": "hour", + "minute": "minute", + "second": "second", + "microsecond": "microsecond", + "yearday": "year day", + "weekday": "weekday", + "zone": "time zone" + }, + "maixcdk": "maix.time.DateTime.DateTime", + "maixpy": "maix.time.DateTime.__init__", + "py_doc": "Constructor\n\nArgs:\n - year: year\n - month: month\n - day: day\n - hour: hour\n - minute: minute\n - second: second\n - microsecond: microsecond\n - yearday: year day\n - weekday: weekday\n - zone: time zone\n" + }, + "args": [ + [ + "int", + "year", + "0" + ], + [ + "int", + "month", + "0" + ], + [ + "int", + "day", + "0" + ], + [ + "int", + "hour", + "0" + ], + [ + "int", + "minute", + "0" + ], + [ + "int", + "second", + "0" + ], + [ + "int", + "microsecond", + "0" + ], + [ + "int", + "yearday", + "0" + ], + [ + "int", + "weekday", + "0" + ], + [ + "int", + "zone", + "0" + ] + ], + "ret_type": null, + "static": false, + "def": "DateTime(int year = 0, int month = 0, int day = 0, int hour = 0, int minute = 0, int second = 0, int microsecond = 0, int yearday = 0, int weekday = 0, int zone = 0)" + }, + "strftime": { + "type": "func", + "name": "strftime", + "doc": { + "brief": "Convert to string", + "return": "date time string", + "maixpy": "maix.time.DateTime.strftime", + "py_doc": "Convert to string\n\nReturns: date time string\n" + }, + "args": [ + [ + "const std::string &", + "format", + null + ] + ], + "ret_type": "std::string", + "static": false, + "def": "std::string strftime(const std::string &format)" + }, + "timestamp": { + "type": "func", + "name": "timestamp", + "doc": { + "brief": "Convert to float timestamp", + "return": "float timestamp", + "maixpy": "maix.time.DateTime.timestamp", + "py_doc": "Convert to float timestamp\n\nReturns: float timestamp\n" + }, + "args": [], + "ret_type": "double", + "static": false, + "def": "double timestamp()" + } + }, + "def": "class DateTime" + }, + "now": { + "type": "func", + "name": "now", + "doc": { + "brief": "Get current UTC date and time", + "return": "current date and time, DateTime type", + "maixpy": "maix.time.now", + "py_doc": "Get current UTC date and time\n\nReturns: current date and time, DateTime type\n" + }, + "args": [], + "ret_type": "time::DateTime*", + "static": false, + "def": "time::DateTime *now()" + }, + "localtime": { + "type": "func", + "name": "localtime", + "doc": { + "brief": "Get local time", + "return": "local time, DateTime type", + "maixpy": "maix.time.localtime", + "py_doc": "Get local time\n\nReturns: local time, DateTime type\n" + }, + "args": [], + "ret_type": "time::DateTime*", + "static": false, + "def": "time::DateTime *localtime()" + }, + "strptime": { + "type": "func", + "name": "strptime", + "doc": { + "brief": "DateTime from string", + "param": { + "str": "date time string", + "format": "date time format" + }, + "return": "DateTime", + "maixpy": "maix.time.strptime", + "py_doc": "DateTime from string\n\nArgs:\n - str: date time string\n - format: date time format\n\n\nReturns: DateTime\n" + }, + "args": [ + [ + "const std::string &", + "str", + null + ], + [ + "const std::string &", + "format", + null + ] + ], + "ret_type": "time::DateTime*", + "static": false, + "def": "time::DateTime *strptime(const std::string &str, const std::string &format)" + }, + "gmtime": { + "type": "func", + "name": "gmtime", + "doc": { + "brief": "timestamp to DateTime(time zone is UTC (value 0))", + "param": { + "timestamp": "double timestamp" + }, + "return": "DateTime", + "maixpy": "maix.time.gmtime", + "py_doc": "timestamp to DateTime(time zone is UTC (value 0))\n\nArgs:\n - timestamp: double timestamp\n\n\nReturns: DateTime\n" + }, + "args": [ + [ + "double", + "timestamp", + null + ] + ], + "ret_type": "time::DateTime*", + "static": false, + "def": "time::DateTime *gmtime(double timestamp)" + }, + "timezone": { + "type": "func", + "name": "timezone", + "doc": { + "brief": "Set or get timezone", + "param": { + "timezone": "string type, can be empty and default to empty, if empty, only return crrent timezone, a \"region/city\" string, e.g. Asia/Shanghai, Etc/UTC, you can get all by list_timezones function." + }, + "return": "string type, return current timezone setting.", + "attention": "when set new timezone, time setting not take effect in this process for some API, so you need to restart program.", + "maixpy": "maix.time.timezone", + "py_doc": "Set or get timezone\n\nArgs:\n - timezone: string type, can be empty and default to empty, if empty, only return crrent timezone, a \"region/city\" string, e.g. Asia/Shanghai, Etc/UTC, you can get all by list_timezones function.\n\n\nReturns: string type, return current timezone setting.\n" + }, + "args": [ + [ + "const std::string &", + "timezone", + "\"\"" + ] + ], + "ret_type": "std::string", + "static": false, + "def": "std::string timezone(const std::string &timezone = \"\")", + "overload": [ + { + "type": "func", + "name": "timezone2", + "doc": { + "brief": "Set or get timezone", + "param": { + "region": "string type, which region to set, can be empty means only get current, default empty.", + "city": "string type, which city to set, can be empty means only get current, default empty." + }, + "return": "list type, return current timezone setting, first is region, second is city.", + "attention": "when set new timezone, time setting not take effect in this process for some API, so you need to restart program.", + "maixpy": "maix.time.timezone", + "py_doc": "Set or get timezone\n\nArgs:\n - region: string type, which region to set, can be empty means only get current, default empty.\n - city: string type, which city to set, can be empty means only get current, default empty.\n\n\nReturns: list type, return current timezone setting, first is region, second is city.\n" + }, + "args": [ + [ + "const std::string &", + "region", + "\"\"" + ], + [ + "const std::string &", + "city", + "\"\"" + ] + ], + "ret_type": "std::vector", + "static": false, + "def": "std::vector timezone2(const std::string ®ion = \"\", const std::string &city = \"\")" + } + ] + }, + "list_timezones": { + "type": "func", + "name": "list_timezones", + "doc": { + "brief": "List all timezone info", + "return": "A dict with key are regions, and value are region's cities.", + "maixpy": "maix.time.list_timezones", + "py_doc": "List all timezone info\n\nReturns: A dict with key are regions, and value are region's cities.\n" + }, + "args": [], + "ret_type": "std::map>", + "static": false, + "def": "std::map> list_timezones()" + }, + "ntp_timetuple": { + "type": "func", + "name": "ntp_timetuple", + "doc": { + "brief": "Retrieves time from an NTP server\\nThis function fetches the current time from the specified NTP server and port,\\nreturning a tuple containing the time details.", + "param": { + "host": "The hostname or IP address of the NTP server.", + "port": "The port number of the NTP server. Use -1 for the default port 123.", + "retry": "The number of retry attempts. Must be at least 1.", + "timeout_ms": "The timeout duration in milliseconds. Must be non-negative." + }, + "return": "A list of 6 elements: [year, month, day, hour, minute, second]", + "maixpy": "maix.time.ntp_timetuple", + "py_doc": "Retrieves time from an NTP server\nThis function fetches the current time from the specified NTP server and port,\nreturning a tuple containing the time details.\n\nArgs:\n - host: The hostname or IP address of the NTP server.\n - port: The port number of the NTP server. Use -1 for the default port 123.\n - retry: The number of retry attempts. Must be at least 1.\n - timeout_ms: The timeout duration in milliseconds. Must be non-negative.\n\n\nReturns: A list of 6 elements: [year, month, day, hour, minute, second]\n" + }, + "args": [ + [ + "std::string", + "host", + null + ], + [ + "int", + "port", + "-1" + ], + [ + "uint8_t", + "retry", + "3" + ], + [ + "int", + "timeout_ms", + "0" + ] + ], + "ret_type": "std::vector", + "static": false, + "def": "std::vector ntp_timetuple(std::string host, int port=-1, uint8_t retry=3, int timeout_ms=0)" + }, + "ntp_timetuple_with_config": { + "type": "func", + "name": "ntp_timetuple_with_config", + "doc": { + "brief": "Retrieves time from an NTP server using a configuration file\\nThis function reads the configuration from a YAML file to fetch the current time\\nfrom a list of specified NTP servers, returning a tuple containing the time details.", + "param": { + "path": "The path to the YAML configuration file, which should include:\n- Config:\n- retry: Number of retry attempts (must be at least 1)\n- total_timeout_ms: Total timeout duration in milliseconds (must be non-negative)\n- NtpServers:\n- host: Hostname or IP address of the NTP server\n- port: Port number of the NTP server (use 123 for default)\nExample YAML configuration:\nConfig:\n- retry: 3\n- total_timeout_ms: 10000\nNtpServers:\n- host: \"pool.ntp.org\"\nport: 123\n- host: \"time.nist.gov\"\nport: 123\n- host: \"time.windows.com\"\nport: 123" + }, + "return": "A list of 6 elements: [year, month, day, hour, minute, second]", + "maixpy": "maix.time.ntp_timetuple_with_config", + "py_doc": "Retrieves time from an NTP server using a configuration file\nThis function reads the configuration from a YAML file to fetch the current time\nfrom a list of specified NTP servers, returning a tuple containing the time details.\n\nArgs:\n - path: The path to the YAML configuration file, which should include:\n- Config:\n- retry: Number of retry attempts (must be at least 1)\n- total_timeout_ms: Total timeout duration in milliseconds (must be non-negative)\n- NtpServers:\n- host: Hostname or IP address of the NTP server\n- port: Port number of the NTP server (use 123 for default)\nExample YAML configuration:\nConfig:\n- retry: 3\n- total_timeout_ms: 10000\nNtpServers:\n- host: \"pool.ntp.org\"\nport: 123\n- host: \"time.nist.gov\"\nport: 123\n- host: \"time.windows.com\"\nport: 123\n\n\nReturns: A list of 6 elements: [year, month, day, hour, minute, second]\n" + }, + "args": [ + [ + "std::string", + "path", + null + ] + ], + "ret_type": "std::vector", + "static": false, + "def": "std::vector ntp_timetuple_with_config(std::string path)" + }, + "ntp_sync_sys_time": { + "type": "func", + "name": "ntp_sync_sys_time", + "doc": { + "brief": "Retrieves time from an NTP server and synchronizes the system time\\nThis function fetches the current time from the specified NTP server and port,\\nthen synchronizes the system time with the retrieved time.", + "param": { + "host": "The hostname or IP address of the NTP server.", + "port": "The port number of the NTP server. Use 123 for the default port.", + "retry": "The number of retry attempts. Must be at least 1.", + "timeout_ms": "The timeout duration in milliseconds. Must be non-negative." + }, + "return": "A list of 6 elements: [year, month, day, hour, minute, second]", + "maixpy": "maix.time.ntp_sync_sys_time", + "py_doc": "Retrieves time from an NTP server and synchronizes the system time\nThis function fetches the current time from the specified NTP server and port,\nthen synchronizes the system time with the retrieved time.\n\nArgs:\n - host: The hostname or IP address of the NTP server.\n - port: The port number of the NTP server. Use 123 for the default port.\n - retry: The number of retry attempts. Must be at least 1.\n - timeout_ms: The timeout duration in milliseconds. Must be non-negative.\n\n\nReturns: A list of 6 elements: [year, month, day, hour, minute, second]\n" + }, + "args": [ + [ + "std::string", + "host", + null + ], + [ + "int", + "port", + "-1" + ], + [ + "uint8_t", + "retry", + "3" + ], + [ + "int", + "timeout_ms", + "0" + ] + ], + "ret_type": "std::vector", + "static": false, + "def": "std::vector ntp_sync_sys_time(std::string host, int port=-1, uint8_t retry=3, int timeout_ms=0)" + }, + "ntp_sync_sys_time_with_config": { + "type": "func", + "name": "ntp_sync_sys_time_with_config", + "doc": { + "brief": "Retrieves time from an NTP server using a configuration file and synchronizes the system time\\nThis function reads the configuration from a YAML file to fetch the current time\\nfrom a list of specified NTP servers, then synchronizes the system time with the retrieved time.", + "param": { + "path": "The path to the YAML configuration file, which should include:\n- Config:\n- retry: Number of retry attempts (must be at least 1)\n- total_timeout_ms: Total timeout duration in milliseconds (must be non-negative)\n- NtpServers:\n- host: Hostname or IP address of the NTP server\n- port: Port number of the NTP server (use 123 for default)\nExample YAML configuration:\nConfig:\n- retry: 3\n- total_timeout_ms: 10000\nNtpServers:\n- host: \"pool.ntp.org\"\nport: 123\n- host: \"time.nist.gov\"\nport: 123\n- host: \"time.windows.com\"\nport: 123" + }, + "return": "A vector of integers containing the time details: [year, month, day, hour, minute, second]", + "maixpy": "maix.time.ntp_sync_sys_time_with_config", + "py_doc": "Retrieves time from an NTP server using a configuration file and synchronizes the system time\nThis function reads the configuration from a YAML file to fetch the current time\nfrom a list of specified NTP servers, then synchronizes the system time with the retrieved time.\n\nArgs:\n - path: The path to the YAML configuration file, which should include:\n- Config:\n- retry: Number of retry attempts (must be at least 1)\n- total_timeout_ms: Total timeout duration in milliseconds (must be non-negative)\n- NtpServers:\n- host: Hostname or IP address of the NTP server\n- port: Port number of the NTP server (use 123 for default)\nExample YAML configuration:\nConfig:\n- retry: 3\n- total_timeout_ms: 10000\nNtpServers:\n- host: \"pool.ntp.org\"\nport: 123\n- host: \"time.nist.gov\"\nport: 123\n- host: \"time.windows.com\"\nport: 123\n\n\nReturns: A vector of integers containing the time details: [year, month, day, hour, minute, second]\n" + }, + "args": [ + [ + "std::string", + "path", + null + ] + ], + "ret_type": "std::vector", + "static": false, + "def": "std::vector ntp_sync_sys_time_with_config(std::string path)" + } + }, + "auto_add": true + }, + "err": { + "type": "module", + "doc": { + "brief": "maix.err module" + }, + "members": { + "Err": { + "type": "enum", + "name": "Err", + "doc": { + "brief": "Maix Error code", + "maixpy": "maix.err.Err", + "py_doc": "Maix Error code" + }, + "values": [ + [ + "ERR_NONE", + "0", + "No error" + ], + [ + "ERR_ARGS", + "", + "Invalid arguments" + ], + [ + "ERR_NO_MEM", + "", + "No memory" + ], + [ + "ERR_NOT_IMPL", + "", + "Not implemented" + ], + [ + "ERR_NOT_READY", + "", + "Not ready" + ], + [ + "ERR_NOT_INIT", + "", + "Not initialized" + ], + [ + "ERR_NOT_OPEN", + "", + "Not opened" + ], + [ + "ERR_NOT_PERMIT", + "", + "Not permitted" + ], + [ + "ERR_REOPEN", + "", + "Re-open" + ], + [ + "ERR_BUSY", + "", + "Busy" + ], + [ + "ERR_READ", + "", + "Read error" + ], + [ + "ERR_WRITE", + "", + "Write error" + ], + [ + "ERR_TIMEOUT", + "", + "Timeout" + ], + [ + "ERR_RUNTIME", + "", + "Runtime error" + ], + [ + "ERR_IO", + "", + "IO error" + ], + [ + "ERR_NOT_FOUND", + "", + "Not found" + ], + [ + "ERR_ALREAY_EXIST", + "", + "Already exist" + ], + [ + "ERR_BUFF_FULL", + "", + "Buffer full" + ], + [ + "ERR_BUFF_EMPTY", + "", + "Buffer empty" + ], + [ + "ERR_CANCEL", + "", + "Cancel" + ], + [ + "ERR_OVERFLOW", + "", + "Overflow" + ], + [ + "ERR_MAX", + "", + "" + ] + ], + "def": "enum Err\n {\n // !!! fixed error code, DO NOT change number already defined, only append new error code\n ERR_NONE = 0, // No error\n ERR_ARGS , // Invalid arguments\n ERR_NO_MEM , // No memory\n ERR_NOT_IMPL , // Not implemented\n ERR_NOT_READY , // Not ready\n ERR_NOT_INIT , // Not initialized\n ERR_NOT_OPEN , // Not opened\n ERR_NOT_PERMIT , // Not permitted\n ERR_REOPEN , // Re-open\n ERR_BUSY , // Busy\n ERR_READ , // Read error\n ERR_WRITE , // Write error\n ERR_TIMEOUT , // Timeout\n ERR_RUNTIME , // Runtime error\n ERR_IO , // IO error\n ERR_NOT_FOUND , // Not found\n ERR_ALREAY_EXIST , // Already exist\n ERR_BUFF_FULL , // Buffer full\n ERR_BUFF_EMPTY , // Buffer empty\n ERR_CANCEL , // Cancel\n ERR_OVERFLOW , // Overflow\n ERR_MAX,\n }" + }, + "Exception": { + "type": "class", + "name": "Exception", + "doc": { + "brief": "Maix Exception", + "maixpy": "maix.err.Exception", + "py_doc": "Maix Exception" + }, + "members": {}, + "def": "class Exception : public std::exception" + }, + "to_str": { + "type": "func", + "name": "to_str", + "doc": { + "brief": "Error code to string", + "param": { + "e": "direction [in], error code, err::Err type" + }, + "return": "error string", + "maixpy": "maix.err.to_str", + "py_doc": "Error code to string\n\nArgs:\n - e: direction [in], error code, err::Err type\n\n\nReturns: error string\n" + }, + "args": [ + [ + "err::Err", + "e", + null + ] + ], + "ret_type": "std::string", + "static": false, + "def": "std::string to_str(err::Err e)" + }, + "get_error": { + "type": "func", + "name": "get_error", + "doc": { + "brief": "get last error string", + "return": "error string", + "maixpy": "maix.err.get_error", + "py_doc": "get last error string\n\nReturns: error string\n" + }, + "args": [], + "ret_type": "std::string&", + "static": false, + "def": "std::string& get_error()" + }, + "set_error": { + "type": "func", + "name": "set_error", + "doc": { + "brief": "set last error string", + "param": { + "str": "direction [in], error string" + }, + "maixpy": "maix.err.set_error", + "py_doc": "set last error string\n\nArgs:\n - str: direction [in], error string\n" + }, + "args": [ + [ + "const std::string &", + "str", + null + ] + ], + "ret_type": "void", + "static": false, + "def": "void set_error(const std::string &str)" + }, + "check_raise": { + "type": "func", + "name": "check_raise", + "doc": { + "brief": "Check error code, if not ERR_NONE, raise err.Exception", + "param": { + "e": "direction [in], error code, err::Err type", + "msg": "direction [in], error message" + }, + "maixpy": "maix.err.check_raise", + "py_doc": "Check error code, if not ERR_NONE, raise err.Exception\n\nArgs:\n - e: direction [in], error code, err::Err type\n - msg: direction [in], error message\n" + }, + "args": [ + [ + "err::Err", + "e", + null + ], + [ + "const std::string &", + "msg", + "\"\"" + ] + ], + "ret_type": "void", + "static": false, + "def": "void check_raise(err::Err e, const std::string &msg = \"\")" + }, + "check_bool_raise": { + "type": "func", + "name": "check_bool_raise", + "doc": { + "brief": "Check condition, if false, raise err.Exception", + "param": { + "ok": "direction [in], condition, if true, do nothing, if false, raise err.Exception", + "msg": "direction [in], error message" + }, + "maixpy": "maix.err.check_bool_raise", + "py_doc": "Check condition, if false, raise err.Exception\n\nArgs:\n - ok: direction [in], condition, if true, do nothing, if false, raise err.Exception\n - msg: direction [in], error message\n" + }, + "args": [ + [ + "bool", + "ok", + null + ], + [ + "const std::string &", + "msg", + "\"\"" + ] + ], + "ret_type": "void", + "static": false, + "def": "void check_bool_raise(bool ok, const std::string &msg = \"\")" + }, + "check_null_raise": { + "type": "func", + "name": "check_null_raise", + "doc": { + "brief": "Check NULL pointer, if NULL, raise exception", + "param": { + "ptr": "direction [in], pointer", + "msg": "direction [in], error message" + }, + "maixpy": "maix.err.check_null_raise", + "py_doc": "Check NULL pointer, if NULL, raise exception\n\nArgs:\n - ptr: direction [in], pointer\n - msg: direction [in], error message\n" + }, + "args": [ + [ + "void *", + "ptr", + null + ], + [ + "const std::string &", + "msg", + "\"\"" + ] + ], + "ret_type": "void", + "static": false, + "def": "void check_null_raise(void *ptr, const std::string &msg = \"\")" + } + }, + "auto_add": true + }, + "example": { + "type": "module", + "doc": { + "brief": "example module, this will be maix.example module in MaixPy, maix::example namespace in MaixCDK", + "maixpy": "maix.example", + "py_doc": "example module, this will be maix.example module in MaixPy, maix::example namespace in MaixCDK" + }, + "members": { + "Test": { + "type": "class", + "name": "Test", + "doc": { + "brief": "Test class", + "maixpy": "maix.example.Test", + "py_doc": "Test class" + }, + "members": { + "Test": { + "type": "func", + "name": "Test", + "doc": { + "brief": "Test constructor", + "maixpy": "maix.example.Test.__init__", + "maixcdk": "maix.example.Test.Test", + "py_doc": "Test constructor" + }, + "args": [], + "ret_type": null, + "static": false, + "def": "Test()" + } + }, + "def": "class Test" + }, + "Kind": { + "type": "enum", + "name": "Kind", + "doc": { + "brief": "Example enum(not recommend! See Kind2)", + "maixpy": "maix.example.Kind", + "py_doc": "Example enum(not recommend! See Kind2)" + }, + "values": [ + [ + "KIND_NONE", + "0", + "Kind none, value always 0, other enum value will auto increase" + ], + [ + "KIND_DOG", + "", + "Kind dog" + ], + [ + "KIND_CAT", + "", + "Kind cat, value is auto generated according to KING_DOG" + ], + [ + "KIND_BIRD", + "", + "" + ], + [ + "KIND_MAX", + "", + "Max Kind quantity\nYou can get max Kind value by KIND_MAX - 1" + ] + ], + "def": "enum Kind\n {\n KIND_NONE = 0, /** Kind none, value always 0, other enum value will auto increase */\n KIND_DOG, /** Kind dog*/\n KIND_CAT, // Kind cat, value is auto generated according to KING_DOG\n KIND_BIRD,\n KIND_MAX /* Max Kind quantity,\n You can get max Kind value by KIND_MAX - 1\n */\n }" + }, + "Kind2": { + "type": "enum", + "name": "class", + "doc": { + "brief": "Example enum class(recommend!)", + "maixpy": "maix.example.Kind2", + "py_doc": "Example enum class(recommend!)" + }, + "values": [ + [ + "NONE", + "0", + "Kind none, value always 0, other enum value will auto increase" + ], + [ + "DOG", + "", + "Kind dog" + ], + [ + "CAT", + "", + "Kind cat, value is auto generated according to KING_DOG" + ], + [ + "BIRD", + "", + "" + ], + [ + "MAX", + "", + "Max Kind quantity\nYou can get max Kind value by KIND_MAX - 1" + ] + ], + "def": "enum class Kind2\n {\n NONE = 0, /** Kind none, value always 0, other enum value will auto increase */\n DOG, /** Kind dog*/\n CAT, // Kind cat, value is auto generated according to KING_DOG\n BIRD,\n MAX /* Max Kind quantity,\n You can get max Kind value by KIND_MAX - 1\n */\n }" + }, + "var1": { + "type": "var", + "name": "", + "doc": { + "brief": "Example module variable", + "attention": "It's a copy of this variable in MaixPy,\nso change it in C++ (e.g. update var in hello function) will not take effect the var inMaixPy.\nSo we add const for this var to avoid this mistake.", + "maixpy": "maix.example.var1", + "py_doc": "Example module variable" + }, + "value": "\"Sipeed\"", + "static": false, + "readonly": true, + "def": "const std::string var1 = \"Sipeed\"" + }, + "list_var": { + "type": "var", + "name": "", + "doc": { + "brief": "Tensor data type size in bytes", + "attention": [ + "DO NOT use C/C++ array directly for python API, the python wrapper not support it.\nUse std::vector instead.", + "It's a copy of this variable in MaixPy,\nso change it in C++ (e.g. update var in hello function) will not take effect the var inMaixPy.\nSo we add const for this var to avoid this mistake." + ], + "maixpy": "maix.example.list_var", + "py_doc": "Tensor data type size in bytes" + }, + "value": "{\n 0, 1, 2, 3, 4, 5, 6, 7, 8, 9}", + "static": false, + "readonly": true, + "def": "const std::vector list_var = {\n 0, 1, 2, 3, 4, 5, 6, 7, 8, 9}" + }, + "test_var": { + "type": "var", + "name": "", + "doc": { + "brief": "Example module variable test_var", + "attention": "It's a copy of this variable in MaixPy, so if you change it in C++, it will not take effect in MaixPy.\nAnd change it in MaixPy will not take effect in C++ as well !!!\nIf you want to use vars shared between C++ and MaixPy, you can create a class and use its member.", + "maixpy": "maix.example.test_var", + "py_doc": "Example module variable test_var" + }, + "value": "100", + "static": false, + "readonly": false, + "def": "int test_var = 100" + }, + "hello": { + "type": "func", + "name": "hello", + "doc": { + "brief": "say hello to someone", + "param": { + "name": "direction [in], name of someone, string type" + }, + "return": "string type, content is hello + name", + "maixpy": "maix.example.hello", + "py_doc": "say hello to someone\n\nArgs:\n - name: direction [in], name of someone, string type\n\n\nReturns: string type, content is hello + name\n" + }, + "args": [ + [ + "std::string", + "name", + null + ] + ], + "ret_type": "std::string", + "static": false, + "def": "std::string hello(std::string name)" + }, + "hello_maixcdk": { + "type": "func", + "name": "hello_maixcdk", + "doc": { + "brief": "This is an API only for MaixCDK, MaixPy can't use it.\\nOnly item with `maixcdk` or `maixpy` keyword will be exported as MaixCDK API.", + "maixcdk": "maix.example.hello_maixcdk", + "py_doc": "This is an API only for MaixCDK, MaixPy can't use it.\nOnly item with `maixcdk` or `maixpy` keyword will be exported as MaixCDK API." + }, + "args": [ + [ + "std::string", + "name", + null + ] + ], + "ret_type": "std::string", + "static": false, + "def": "std::string hello_maixcdk(std::string name)" + }, + "Example": { + "type": "class", + "name": "Example", + "doc": { + "brief": "Example class\\nthis class will be export to MaixPy as maix.example.Example", + "maixpy": "maix.example.Example", + "py_doc": "Example class\nthis class will be export to MaixPy as maix.example.Example" + }, + "members": { + "Example": { + "type": "func", + "name": "Example", + "doc": { + "brief": "Example constructor\\nthis constructor will be export to MaixPy as maix.example.Example.__init__", + "param": { + "name": "direction [in], name of Example, string type", + "age": "direction [in], age of Example, int type, default is 18, value range is [0, 100]" + }, + "attention": "to make auto generate code work, param Kind should with full namespace name `example::Kind` instead of `Kind`,\nnamespace `maix` can be ignored.", + "maixpy": "maix.example.Example.__init__", + "maixcdk": "maix.example.Example.Example", + "py_doc": "Example constructor\nthis constructor will be export to MaixPy as maix.example.Example.__init__\n\nArgs:\n - name: direction [in], name of Example, string type\n - age: direction [in], age of Example, int type, default is 18, value range is [0, 100]\n" + }, + "args": [ + [ + "std::string &", + "name", + null + ], + [ + "int", + "age", + "18" + ], + [ + "example::Kind", + "pet", + "example::KIND_NONE" + ] + ], + "ret_type": null, + "static": false, + "def": "Example(std::string &name, int age = 18, example::Kind pet = example::KIND_NONE)" + }, + "get_name": { + "type": "func", + "name": "get_name", + "doc": { + "brief": "get name of Example\\nyou can also get name by property `name`.", + "return": "name of Example, string type", + "maixpy": "maix.example.Example.get_name", + "py_doc": "get name of Example\nyou can also get name by property `name`.\n\nReturns: name of Example, string type\n" + }, + "args": [], + "ret_type": "std::string", + "static": false, + "def": "std::string get_name()" + }, + "get_age": { + "type": "func", + "name": "get_age", + "doc": { + "brief": "get age of Example", + "return": "age of Example, int type, value range is [0, 100]", + "maixpy": "maix.example.Example.get_age", + "py_doc": "get age of Example\n\nReturns: age of Example, int type, value range is [0, 100]\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int get_age()" + }, + "set_name": { + "type": "func", + "name": "set_name", + "doc": { + "brief": "set name of Example", + "param": { + "name": "name of Example, string type" + }, + "maixpy": "maix.example.Example.set_name", + "py_doc": "set name of Example\n\nArgs:\n - name: name of Example, string type\n" + }, + "args": [ + [ + "std::string", + "name", + null + ] + ], + "ret_type": "void", + "static": false, + "def": "void set_name(std::string name)" + }, + "set_age": { + "type": "func", + "name": "set_age", + "doc": { + "brief": "set age of Example", + "param": { + "age": "age of Example, int type, value range is [0, 100]" + }, + "maixpy": "maix.example.Example.set_age", + "py_doc": "set age of Example\n\nArgs:\n - age: age of Example, int type, value range is [0, 100]\n" + }, + "args": [ + [ + "int", + "age", + null + ] + ], + "ret_type": "void", + "static": false, + "def": "void set_age(int age)" + }, + "set_pet": { + "type": "func", + "name": "set_pet", + "doc": { + "brief": "Example enum member", + "attention": "", + "maixpy": "maix.example.Example.set_pet", + "py_doc": "Example enum member" + }, + "args": [ + [ + "example::Kind", + "pet", + null + ] + ], + "ret_type": "void", + "static": false, + "def": "void set_pet(example::Kind pet)" + }, + "get_pet": { + "type": "func", + "name": "get_pet", + "doc": { + "brief": "Example enum member", + "maixpy": "maix.example.Example.get_pet", + "py_doc": "Example enum member" + }, + "args": [], + "ret_type": "example::Kind", + "static": false, + "def": "example::Kind get_pet()" + }, + "get_list": { + "type": "func", + "name": "get_list", + "doc": { + "brief": "get list example", + "param": { + "in": "direction [in], input list, items are int type.\nIn MaixPy, you can pass list or tuple to this API" + }, + "return": "list, items are int type, content is [1, 2, 3] + in. Alloc item, del in MaixPy will auto free memory.", + "maixpy": "maix.example.Example.get_list", + "py_doc": "get list example\n\nArgs:\n - in: direction [in], input list, items are int type.\nIn MaixPy, you can pass list or tuple to this API\n\n\nReturns: list, items are int type, content is [1, 2, 3] + in. Alloc item, del in MaixPy will auto free memory.\n" + }, + "args": [ + [ + "std::vector", + "in", + null + ] + ], + "ret_type": "std::vector*", + "static": false, + "def": "std::vector *get_list(std::vector in)" + }, + "get_dict": { + "type": "func", + "name": "get_dict", + "doc": { + "brief": "Example dict API", + "param": { + "in": "direction [in], input dict, key is string type, value is int type.\nIn MaixPy, you can pass `dict` to this API" + }, + "return": "dict, key is string type, value is int type, content is {\"a\": 1} + in\nIn MaixPy, return type is `dict` object", + "maixpy": "maix.example.Example.get_dict", + "py_doc": "Example dict API\n\nArgs:\n - in: direction [in], input dict, key is string type, value is int type.\nIn MaixPy, you can pass `dict` to this API\n\n\nReturns: dict, key is string type, value is int type, content is {\"a\": 1} + in\nIn MaixPy, return type is `dict` object\n" + }, + "args": [ + [ + "std::map &", + "in", + null + ] + ], + "ret_type": "std::map", + "static": false, + "def": "std::map get_dict(std::map &in)" + }, + "hello": { + "type": "func", + "name": "hello", + "doc": { + "brief": "say hello to someone", + "param": { + "name": "name of someone, string type" + }, + "return": "string type, content is Example::hello_str + name", + "maixpy": "maix.example.Example.hello", + "py_doc": "say hello to someone\n\nArgs:\n - name: name of someone, string type\n\n\nReturns: string type, content is Example::hello_str + name\n" + }, + "args": [ + [ + "std::string", + "name", + null + ] + ], + "ret_type": "std::string", + "static": true, + "def": "static std::string hello(std::string name)" + }, + "hello_bytes": { + "type": "func", + "name": "hello_bytes", + "doc": { + "brief": "param is bytes example", + "param": { + "bytes": "bytes type param" + }, + "return": "bytes type, return value is bytes changed value", + "maixpy": "maix.example.Example.hello_bytes", + "py_doc": "param is bytes example\n\nArgs:\n - bytes: bytes type param\n\n\nReturns: bytes type, return value is bytes changed value\n" + }, + "args": [ + [ + "Bytes &", + "bytes", + null + ] + ], + "ret_type": "Bytes*", + "static": true, + "def": "static Bytes *hello_bytes(Bytes &bytes)" + }, + "callback": { + "type": "func", + "name": "callback", + "doc": { + "brief": "Callback example", + "param": { + "cb": "callback function, param is two int type, return is int type" + }, + "return": "int type, return value is cb's return value.", + "maixpy": "maix.example.Example.callback", + "py_doc": "Callback example\n\nArgs:\n - cb: callback function, param is two int type, return is int type\n\n\nReturns: int type, return value is cb's return value.\n" + }, + "args": [ + [ + "std::function", + "cb", + null + ] + ], + "ret_type": "int", + "static": true, + "def": "static int callback(std::function cb)" + }, + "callback2": { + "type": "func", + "name": "callback2", + "doc": { + "brief": "Callback example", + "param": { + "cb": "callback function, param is a int list type and int type, return is int type" + }, + "return": "int type, return value is cb's return value.", + "maixpy": "maix.example.Example.callback2", + "py_doc": "Callback example\n\nArgs:\n - cb: callback function, param is a int list type and int type, return is int type\n\n\nReturns: int type, return value is cb's return value.\n" + }, + "args": [ + [ + "std::function, int)>", + "cb", + null + ] + ], + "ret_type": "int", + "static": true, + "def": "static int callback2(std::function, int)> cb)" + }, + "hello_dict": { + "type": "func", + "name": "hello_dict", + "doc": { + "brief": "Dict param example", + "param": { + "dict": "dict type param, key is string type, value is int type" + }, + "maixpy": "maix.example.Example.hello_dict", + "py_doc": "Dict param example\n\nArgs:\n - dict: dict type param, key is string type, value is int type\n" + }, + "args": [ + [ + "std::map *", + "dict", + null + ] + ], + "ret_type": "std::map*", + "static": true, + "def": "static std::map *hello_dict(std::map *dict)" + }, + "name": { + "type": "var", + "name": "name", + "doc": { + "brief": "name member of Example", + "maixpy": "maix.example.Example.name", + "py_doc": "name member of Example" + }, + "value": null, + "static": false, + "readonly": false, + "def": "std::string name" + }, + "age": { + "type": "var", + "name": "age", + "doc": { + "brief": "age member of Example, value range should be [0, 100]", + "maixpy": "maix.example.Example.age", + "py_doc": "age member of Example, value range should be [0, 100]" + }, + "value": null, + "static": false, + "readonly": false, + "def": "int age" + }, + "hello_str": { + "type": "var", + "name": "hello_str", + "doc": { + "brief": "hello_str member of Example, default value is \\\"hello \\\"", + "maixpy": "maix.example.Example.hello_str", + "py_doc": "hello_str member of Example, default value is \"hello \"" + }, + "value": null, + "static": true, + "readonly": false, + "def": "static std::string hello_str" + }, + "var1": { + "type": "var", + "name": "", + "doc": { + "brief": "Example module readonly variable", + "maixpy": "maix.example.Example.var1", + "py_doc": "Example module readonly variable" + }, + "value": "\"Example.var1\"", + "static": false, + "readonly": true, + "def": "const std::string var1 = \"Example.var1\"" + }, + "var2": { + "type": "var", + "name": "", + "doc": { + "brief": "Example module readonly variable", + "maixpy": "maix.example.Example.var2\n:readonly", + "py_doc": "Example module readonly variable" + }, + "value": "\"Example.var2\"", + "static": false, + "readonly": true, + "def": "std::string var2 = \"Example.var2\"" + }, + "dict_test": { + "type": "func", + "name": "dict_test", + "doc": { + "brief": "dict_test, return dict type, and element is pointer type(alloc in C++).\\nHere when the returned Tensor object will auto delete by Python GC.", + "maixpy": "maix.example.Example.dict_test", + "py_doc": "dict_test, return dict type, and element is pointer type(alloc in C++).\nHere when the returned Tensor object will auto delete by Python GC." + }, + "args": [], + "ret_type": "std::map*", + "static": true, + "def": "static std::map *dict_test()" + } + }, + "def": "class Example" + }, + "change_arg_name": { + "type": "func", + "name": "change_arg_name", + "doc": { + "brief": "Change arg name example", + "param": { + "e": "Example object" + }, + "return": "same as arg", + "maixpy": "maix.example.change_arg_name", + "py_doc": "Change arg name example\n\nArgs:\n - e: Example object\n\n\nReturns: same as arg\n" + }, + "args": [ + [ + "example::Example *", + "e", + null + ] + ], + "ret_type": "example::Example*", + "static": false, + "def": "example::Example *change_arg_name(example::Example *e)" + }, + "change_arg_name2": { + "type": "func", + "name": "change_arg_name2", + "doc": { + "brief": "Change arg name example", + "param": { + "e": "Example object" + }, + "maixpy": "maix.example.change_arg_name2", + "py_doc": "Change arg name example\n\nArgs:\n - e: Example object\n" + }, + "args": [ + [ + "example::Example &", + "e", + null + ] + ], + "ret_type": "void", + "static": false, + "def": "void change_arg_name2(example::Example &e)" + } + }, + "auto_add": false + }, + "util": { + "type": "module", + "doc": { + "brief": "maix.util module" + }, + "members": { + "disable_kernel_debug": { + "type": "func", + "name": "disable_kernel_debug", + "doc": { + "brief": "disable the kernel debug", + "maixcdk": "maix.util.disable_kernel_debug", + "py_doc": "disable the kernel debug" + }, + "args": [], + "ret_type": "void", + "static": false, + "def": "void disable_kernel_debug()" + }, + "enable_kernel_debug": { + "type": "func", + "name": "enable_kernel_debug", + "doc": { + "brief": "disable the kernel debug", + "maixcdk": "maix.util.enable_kernel_debug", + "py_doc": "disable the kernel debug" + }, + "args": [], + "ret_type": "void", + "static": false, + "def": "void enable_kernel_debug()" + }, + "register_exit_function": { + "type": "func", + "name": "register_exit_function", + "doc": { + "brief": "register exit function", + "maixcdk": "maix.util.register_exit_function", + "py_doc": "register exit function" + }, + "args": [ + [ + "void (*", + "process)(void)", + null + ] + ], + "ret_type": "void", + "static": false, + "def": "void register_exit_function(void (*process)(void))" + }, + "do_exit_function": { + "type": "func", + "name": "do_exit_function", + "doc": { + "brief": "exec all of exit function", + "maixpy": "maix.util.do_exit_function", + "py_doc": "exec all of exit function" + }, + "args": [], + "ret_type": "void", + "static": false, + "def": "void do_exit_function()" + }, + "register_atexit": { + "type": "func", + "name": "register_atexit", + "doc": { + "brief": "Registering default processes that need to be executed on exit", + "maixpy": "maix.util.register_atexit", + "py_doc": "Registering default processes that need to be executed on exit" + }, + "args": [], + "ret_type": "void", + "static": false, + "def": "void register_atexit()" + } + }, + "auto_add": true + }, + "thread": { + "type": "module", + "doc": { + "brief": "maix.thread module" + }, + "members": { + "Thread": { + "type": "class", + "name": "Thread", + "doc": { + "brief": "thread class", + "maixpy": "maix.thread.Thread", + "py_doc": "thread class" + }, + "members": { + "Thread": { + "type": "func", + "name": "Thread", + "doc": { + "brief": "create thread", + "param": { + "func": "direction [in], thread function, one `args` parameter, void* type, no return value", + "args": "direction [in], thread function parameter" + }, + "maixpy": "maix.thread.Thread.__init__", + "maixcdk": "maix.thread.Thread.Thread", + "py_doc": "create thread\n\nArgs:\n - func: direction [in], thread function, one `args` parameter, void* type, no return value\n - args: direction [in], thread function parameter\n" + }, + "args": [ + [ + "std::function", + "func", + null + ], + [ + "void *", + "args", + "nullptr" + ] + ], + "ret_type": null, + "static": false, + "def": "Thread(std::function func, void *args = nullptr)" + }, + "join": { + "type": "func", + "name": "join", + "doc": { + "brief": "wait thread exit", + "maixpy": "maix.thread.Thread.join", + "py_doc": "wait thread exit" + }, + "args": [], + "ret_type": "void", + "static": false, + "def": "void join()" + }, + "detach": { + "type": "func", + "name": "detach", + "doc": { + "brief": "detach thread, detach will auto start thread and you can't use join anymore.", + "maixpy": "maix.thread.Thread.detach", + "py_doc": "detach thread, detach will auto start thread and you can't use join anymore." + }, + "args": [], + "ret_type": "void", + "static": false, + "def": "void detach()" + }, + "joinable": { + "type": "func", + "name": "joinable", + "doc": { + "brief": "Check if thread is joinable", + "return": "true if thread is joinable", + "maixpy": "maix.thread.Thread.joinable", + "py_doc": "Check if thread is joinable\n\nReturns: true if thread is joinable\n" + }, + "args": [], + "ret_type": "bool", + "static": false, + "def": "bool joinable()" + } + }, + "def": "class Thread" + } + }, + "auto_add": true + }, + "sys": { + "type": "module", + "doc": { + "brief": "maix.sys module" + }, + "members": { + "os_version": { + "type": "func", + "name": "os_version", + "doc": { + "brief": "Get system version", + "return": "version string, e.g. \"maixcam-2024-08-13-maixpy-v4.4.20\"", + "maixpy": "maix.sys.os_version", + "py_doc": "Get system version\n\nReturns: version string, e.g. \"maixcam-2024-08-13-maixpy-v4.4.20\"\n" + }, + "args": [], + "ret_type": "std::string", + "static": false, + "def": "std::string os_version()" + }, + "maixpy_version": { + "type": "func", + "name": "maixpy_version", + "doc": { + "brief": "Get MaixPy version, if get failed will return empty string.", + "return": "version string, e.g. \"4.4.21\"", + "maixpy": "maix.sys.maixpy_version", + "py_doc": "Get MaixPy version, if get failed will return empty string.\n\nReturns: version string, e.g. \"4.4.21\"\n" + }, + "args": [], + "ret_type": "std::string", + "static": false, + "def": "std::string maixpy_version()" + }, + "runtime_version": { + "type": "func", + "name": "runtime_version", + "doc": { + "brief": "Get runtime version", + "return": "current runtime version", + "maixpy": "maix.sys.runtime_version", + "py_doc": "Get runtime version\n\nReturns: current runtime version\n" + }, + "args": [], + "ret_type": "std::string", + "static": false, + "def": "std::string runtime_version()" + }, + "device_id": { + "type": "func", + "name": "device_configs", + "doc": { + "brief": "Get device configs, we also say board configs. e.g. for MaixCAM it read form /boot/board", + "param": { + "cache": "read id from cache(if exists, or will call device_configs first internally) if true,\nif false, always read fron config file." + }, + "return": "device id, e.g. \"maixcam\" \"maixcam_pro\"", + "throw": "If board config file error will throw out exception(err.Exception)", + "maixpy": "maix.sys.device_id", + "py_doc": "Get device configs, we also say board configs. e.g. for MaixCAM it read form /boot/board\n\nArgs:\n - cache: read id from cache(if exists, or will call device_configs first internally) if true,\nif false, always read fron config file.\n\n\nReturns: device id, e.g. \"maixcam\" \"maixcam_pro\"\n" + }, + "args": [ + [ + "bool", + "cache", + "true" + ] + ], + "ret_type": "std::map", + "static": false, + "def": "std::map device_configs(bool cache = true)", + "overload": [ + { + "type": "func", + "name": "device_id", + "doc": { + "brief": "Get device id", + "param": { + "cache": "read id from cache(if exists, or will call device_configs first internally) if true,\nif false, always read fron config file." + }, + "return": "device id, e.g. \"maixcam\" \"maixcam_pro\"", + "maixpy": "maix.sys.device_id", + "py_doc": "Get device id\n\nArgs:\n - cache: read id from cache(if exists, or will call device_configs first internally) if true,\nif false, always read fron config file.\n\n\nReturns: device id, e.g. \"maixcam\" \"maixcam_pro\"\n" + }, + "args": [ + [ + "bool", + "cache", + "true" + ] + ], + "ret_type": "std::string", + "static": false, + "def": "std::string device_id(bool cache = true)" + } + ] + }, + "device_name": { + "type": "func", + "name": "device_name", + "doc": { + "brief": "Get device name", + "param": { + "cache": "read id from cache(if exists, or will call device_configs first internally) if true,\nif false, always read fron config file." + }, + "return": "device name, e.g. \"MaixCAM\" \"MaixCAM-Pro\"", + "maixpy": "maix.sys.device_name", + "py_doc": "Get device name\n\nArgs:\n - cache: read id from cache(if exists, or will call device_configs first internally) if true,\nif false, always read fron config file.\n\n\nReturns: device name, e.g. \"MaixCAM\" \"MaixCAM-Pro\"\n" + }, + "args": [ + [ + "bool", + "cache", + "true" + ] + ], + "ret_type": "std::string", + "static": false, + "def": "std::string device_name(bool cache = true)" + }, + "host_name": { + "type": "func", + "name": "host_name", + "doc": { + "brief": "Get host name", + "return": "host name, e.g. \"maixcam-2f9f\"", + "maixpy": "maix.sys.host_name", + "py_doc": "Get host name\n\nReturns: host name, e.g. \"maixcam-2f9f\"\n" + }, + "args": [], + "ret_type": "std::string", + "static": false, + "def": "std::string host_name()" + }, + "host_domain": { + "type": "func", + "name": "host_domain", + "doc": { + "brief": "Get host domain", + "return": "host domain, e.g. \"maixcam-2f9f.local\"", + "maixpy": "maix.sys.host_domain", + "py_doc": "Get host domain\n\nReturns: host domain, e.g. \"maixcam-2f9f.local\"\n" + }, + "args": [], + "ret_type": "std::string", + "static": false, + "def": "std::string host_domain()" + }, + "ip_address": { + "type": "func", + "name": "ip_address", + "doc": { + "brief": "Get ip address", + "return": "ip address, dict type, e.g. {\"eth0\": \"192.168.0.195\", \"wlan0\": \"192.168.0.123\", \"usb0\": \"10.47.159.1\"}", + "maixpy": "maix.sys.ip_address", + "py_doc": "Get ip address\n\nReturns: ip address, dict type, e.g. {\"eth0\": \"192.168.0.195\", \"wlan0\": \"192.168.0.123\", \"usb0\": \"10.47.159.1\"}\n" + }, + "args": [], + "ret_type": "std::map", + "static": false, + "def": "std::map ip_address()" + }, + "mac_address": { + "type": "func", + "name": "mac_address", + "doc": { + "brief": "Get mac address", + "return": "mac address, dict type, e.g. {\"eth0\": \"00:0c:29:2f:9f:00\", \"wlan0\": \"00:0c:29:2f:9f:01\", \"usb0\": \"00:0c:29:2f:9f:02\"}", + "maixpy": "maix.sys.mac_address", + "py_doc": "Get mac address\n\nReturns: mac address, dict type, e.g. {\"eth0\": \"00:0c:29:2f:9f:00\", \"wlan0\": \"00:0c:29:2f:9f:01\", \"usb0\": \"00:0c:29:2f:9f:02\"}\n" + }, + "args": [], + "ret_type": "std::map", + "static": false, + "def": "std::map mac_address()" + }, + "device_key": { + "type": "func", + "name": "device_key", + "doc": { + "brief": "Get device key, can be unique id of device", + "return": "device key, 32 bytes hex string, e.g. \"1234567890abcdef1234567890abcdef\"", + "maixpy": "maix.sys.device_key", + "py_doc": "Get device key, can be unique id of device\n\nReturns: device key, 32 bytes hex string, e.g. \"1234567890abcdef1234567890abcdef\"\n" + }, + "args": [], + "ret_type": "std::string", + "static": false, + "def": "std::string device_key()" + }, + "memory_info": { + "type": "func", + "name": "memory_info", + "doc": { + "brief": "Get memory info", + "return": "memory info, dict type, e.g. {\"total\": 1024, \"used\": 512, \"hw_total\": 256*1024*1024}\ntotal: total memory size in Byte.\nused: used memory size in Byte.\nhw_total: total memory size in Byte of hardware, the total <= hw_total\uff0c\nOS kernel may reserve some memory for some hardware like camera, npu, display etc.", + "maixpy": "maix.sys.memory_info", + "py_doc": "Get memory info\n\nReturns: memory info, dict type, e.g. {\"total\": 1024, \"used\": 512, \"hw_total\": 256*1024*1024}\ntotal: total memory size in Byte.\nused: used memory size in Byte.\nhw_total: total memory size in Byte of hardware, the total <= hw_total\uff0c\nOS kernel may reserve some memory for some hardware like camera, npu, display etc.\n" + }, + "args": [], + "ret_type": "std::map", + "static": false, + "def": "std::map memory_info()" + }, + "bytes_to_human": { + "type": "func", + "name": "bytes_to_human", + "doc": { + "brief": "Bytes to human readable string", + "param": { + "bytes:": "bytes size\uff0ce.g. 1234B = 1234/1024 = 1.205 KB", + "precision:": "decimal precision, default 2", + "base:": "base number, default 1024", + "unit:": "unit string, e.g. \"B\"", + "sep:": "separator string, e.g. \" \"" + }, + "return": "human readable string, e.g. \"1.21 KB\"", + "maixpy": "maix.sys.bytes_to_human", + "py_doc": "Bytes to human readable string\n\nArgs:\n - bytes:: bytes size\uff0ce.g. 1234B = 1234/1024 = 1.205 KB\n - precision:: decimal precision, default 2\n - base:: base number, default 1024\n - unit:: unit string, e.g. \"B\"\n - sep:: separator string, e.g. \" \"\n\n\nReturns: human readable string, e.g. \"1.21 KB\"\n" + }, + "args": [ + [ + "unsigned long long", + "bytes", + null + ], + [ + "int", + "precision", + "2" + ], + [ + "int", + "base", + "1024" + ], + [ + "const std::string &", + "unit", + "\"B\"" + ], + [ + "const std::string &", + "sep", + "\" \"" + ] + ], + "ret_type": "std::string", + "static": false, + "def": "std::string bytes_to_human(unsigned long long bytes, int precision = 2, int base = 1024, const std::string &unit = \"B\", const std::string &sep = \" \")" + }, + "cpu_freq": { + "type": "func", + "name": "cpu_freq", + "doc": { + "brief": "Get CPU frequency", + "return": "CPU frequency, dict type, e.g. {\"cpu0\": 1000000000, \"cpu1\": 1000000000}", + "maixpy": "maix.sys.cpu_freq", + "py_doc": "Get CPU frequency\n\nReturns: CPU frequency, dict type, e.g. {\"cpu0\": 1000000000, \"cpu1\": 1000000000}\n" + }, + "args": [], + "ret_type": "std::map", + "static": false, + "def": "std::map cpu_freq()" + }, + "cpu_temp": { + "type": "func", + "name": "cpu_temp", + "doc": { + "brief": "Get CPU temperature", + "return": "CPU temperature, unit dgree, dict type, e.g. {\"cpu\": 50.0, \"cpu0\": 50, \"cpu1\": 50}", + "maixpy": "maix.sys.cpu_temp", + "py_doc": "Get CPU temperature\n\nReturns: CPU temperature, unit dgree, dict type, e.g. {\"cpu\": 50.0, \"cpu0\": 50, \"cpu1\": 50}\n" + }, + "args": [], + "ret_type": "std::map", + "static": false, + "def": "std::map cpu_temp()" + }, + "cpu_usage": { + "type": "func", + "name": "cpu_usage", + "doc": { + "brief": "Get CPU usage", + "return": "CPU usage, dict type, e.g. {\"cpu\": 50.0, \"cpu0\": 50, \"cpu1\": 50}", + "maixpy": "maix.sys.cpu_usage", + "py_doc": "Get CPU usage\n\nReturns: CPU usage, dict type, e.g. {\"cpu\": 50.0, \"cpu0\": 50, \"cpu1\": 50}\n" + }, + "args": [], + "ret_type": "std::map", + "static": false, + "def": "std::map cpu_usage()" + }, + "npu_freq": { + "type": "func", + "name": "npu_freq", + "doc": { + "brief": "Get NPU frequency", + "return": "NPU frequency, dict type, e.g. {\"npu0\": 500000000}", + "maixpy": "maix.sys.npu_freq", + "py_doc": "Get NPU frequency\n\nReturns: NPU frequency, dict type, e.g. {\"npu0\": 500000000}\n" + }, + "args": [], + "ret_type": "std::map", + "static": false, + "def": "std::map npu_freq()" + }, + "disk_usage": { + "type": "func", + "name": "disk_usage", + "doc": { + "brief": "Get disk usage", + "param": { + "path:": "disk path, default \"/\"" + }, + "return": "disk usage, dict type, e.g. {\"total\": 1024, \"used\": 512}", + "maixpy": "maix.sys.disk_usage", + "py_doc": "Get disk usage\n\nArgs:\n - path:: disk path, default \"/\"\n\n\nReturns: disk usage, dict type, e.g. {\"total\": 1024, \"used\": 512}\n" + }, + "args": [ + [ + "const std::string &", + "path", + "\"/\"" + ] + ], + "ret_type": "std::map", + "static": false, + "def": "std::map disk_usage(const std::string &path = \"/\")" + }, + "disk_partitions": { + "type": "func", + "name": "disk_partitions", + "doc": { + "brief": "Get disk partition and mount point info", + "param": { + "only_disk": "only return real disk, tempfs sysfs etc. not return, default true." + }, + "return": "disk partition and mount point info, list type, e.g. [{\"device\": \"/dev/mmcblk0p1\", \"mountpoint\": \"/mnt/sdcard\", \"fstype\": \"vfat\"}]", + "maixpy": "maix.sys.disk_partitions", + "py_doc": "Get disk partition and mount point info\n\nArgs:\n - only_disk: only return real disk, tempfs sysfs etc. not return, default true.\n\n\nReturns: disk partition and mount point info, list type, e.g. [{\"device\": \"/dev/mmcblk0p1\", \"mountpoint\": \"/mnt/sdcard\", \"fstype\": \"vfat\"}]\n" + }, + "args": [ + [ + "bool", + "only_disk", + "true" + ] + ], + "ret_type": "std::vector>", + "static": false, + "def": "std::vector> disk_partitions(bool only_disk = true)" + }, + "register_default_signal_handle": { + "type": "func", + "name": "register_default_signal_handle", + "doc": { + "brief": "register default signal handle", + "maixpy": "maix.sys.register_default_signal_handle", + "py_doc": "register default signal handle" + }, + "args": [], + "ret_type": "void", + "static": false, + "def": "void register_default_signal_handle()" + }, + "poweroff": { + "type": "func", + "name": "poweroff", + "doc": { + "brief": "Power off device", + "maixpy": "maix.sys.poweroff", + "py_doc": "Power off device" + }, + "args": [], + "ret_type": "void", + "static": false, + "def": "void poweroff()" + }, + "reboot": { + "type": "func", + "name": "reboot", + "doc": { + "brief": "Power off device and power on", + "maixpy": "maix.sys.reboot", + "py_doc": "Power off device and power on" + }, + "args": [], + "ret_type": "void", + "static": false, + "def": "void reboot()" + } + }, + "auto_add": true + }, + "log": { + "type": "module", + "doc": { + "brief": "maix.log module" + }, + "members": { + "error": { + "type": "func", + "name": "error", + "doc": { + "brief": "print error log", + "param": { + "fmt": "format string", + "...": "args" + }, + "maixcdk": "maix.log.error", + "py_doc": "print error log\n\nArgs:\n - fmt: format string\n - ...: args\n" + }, + "args": [ + [ + "const char *", + "fmt", + null + ], + [ + "...", + "...", + null + ] + ], + "ret_type": "void", + "static": false, + "def": "void error(const char *fmt, ...)" + }, + "warn": { + "type": "func", + "name": "warn", + "doc": { + "brief": "print warning log", + "param": { + "fmt": "format string", + "...": "args" + }, + "maixcdk": "maix.log.warn", + "py_doc": "print warning log\n\nArgs:\n - fmt: format string\n - ...: args\n" + }, + "args": [ + [ + "const char *", + "fmt", + null + ], + [ + "...", + "...", + null + ] + ], + "ret_type": "void", + "static": false, + "def": "void warn(const char *fmt, ...)" + }, + "info": { + "type": "func", + "name": "info", + "doc": { + "brief": "print info log", + "param": { + "fmt": "format string", + "...": "args" + }, + "maixcdk": "maix.log.info", + "py_doc": "print info log\n\nArgs:\n - fmt: format string\n - ...: args\n" + }, + "args": [ + [ + "const char *", + "fmt", + null + ], + [ + "...", + "...", + null + ] + ], + "ret_type": "void", + "static": false, + "def": "void info(const char *fmt, ...)" + }, + "debug": { + "type": "func", + "name": "debug", + "doc": { + "brief": "print debug log", + "param": { + "fmt": "format string", + "...": "args" + }, + "maixcdk": "maix.log.debug", + "py_doc": "print debug log\n\nArgs:\n - fmt: format string\n - ...: args\n" + }, + "args": [ + [ + "const char *", + "fmt", + null + ], + [ + "...", + "...", + null + ] + ], + "ret_type": "void", + "static": false, + "def": "void debug(const char *fmt, ...)" + }, + "error0": { + "type": "func", + "name": "error0", + "doc": { + "brief": "print error log, but not add '\\n' at end", + "param": { + "fmt": "format string", + "...": "args" + }, + "maixcdk": "maix.log.error0", + "py_doc": "print error log, but not add '\\n' at end\n\nArgs:\n - fmt: format string\n - ...: args\n" + }, + "args": [ + [ + "const char *", + "fmt", + null + ], + [ + "...", + "...", + null + ] + ], + "ret_type": "void", + "static": false, + "def": "void error0(const char *fmt, ...)" + }, + "warn0": { + "type": "func", + "name": "warn0", + "doc": { + "brief": "print warning log, but not add '\\n' at end", + "param": { + "fmt": "format string", + "...": "args" + }, + "maixcdk": "maix.log.warn0", + "py_doc": "print warning log, but not add '\\n' at end\n\nArgs:\n - fmt: format string\n - ...: args\n" + }, + "args": [ + [ + "const char *", + "fmt", + null + ], + [ + "...", + "...", + null + ] + ], + "ret_type": "void", + "static": false, + "def": "void warn0(const char *fmt, ...)" + }, + "info0": { + "type": "func", + "name": "info0", + "doc": { + "brief": "print info log, but not add '\\n' at end", + "param": { + "fmt": "format string", + "...": "args" + }, + "maixcdk": "maix.log.info0", + "py_doc": "print info log, but not add '\\n' at end\n\nArgs:\n - fmt: format string\n - ...: args\n" + }, + "args": [ + [ + "const char *", + "fmt", + null + ], + [ + "...", + "...", + null + ] + ], + "ret_type": "void", + "static": false, + "def": "void info0(const char *fmt, ...)" + }, + "debug0": { + "type": "func", + "name": "debug0", + "doc": { + "brief": "print debug log, but not add '\\n' at end", + "param": { + "fmt": "format string", + "...": "args" + }, + "maixcdk": "maix.log.debug0", + "py_doc": "print debug log, but not add '\\n' at end\n\nArgs:\n - fmt: format string\n - ...: args\n" + }, + "args": [ + [ + "const char *", + "fmt", + null + ], + [ + "...", + "...", + null + ] + ], + "ret_type": "void", + "static": false, + "def": "void debug0(const char *fmt, ...)" + }, + "print": { + "type": "func", + "name": "print", + "doc": { + "brief": "same as printf, but recommend use this function instead of printf\\nthis function will add prefix like \\\"-- [E] \\\" to log", + "param": { + "fmt": "format string", + "...": "args" + }, + "maixcdk": "maix.log.print", + "py_doc": "same as printf, but recommend use this function instead of printf\nthis function will add prefix like \"-- [E] \" to log\n\nArgs:\n - fmt: format string\n - ...: args\n" + }, + "args": [ + [ + "const char *", + "fmt", + null + ], + [ + "...", + "...", + null + ] + ], + "ret_type": "void", + "static": false, + "def": "void print(const char *fmt, ...)" + } + }, + "auto_add": true + }, + "tensor": { + "type": "module", + "doc": { + "brief": "maix.tensor module" + }, + "members": { + "DType": { + "type": "enum", + "name": "DType", + "doc": { + "brief": "Tensor data types", + "maixpy": "maix.tensor.DType", + "py_doc": "Tensor data types" + }, + "values": [ + [ + "UINT8", + "0", + "" + ], + [ + "INT8", + "", + "" + ], + [ + "UINT16", + "", + "" + ], + [ + "INT16", + "", + "" + ], + [ + "UINT32", + "", + "" + ], + [ + "INT32", + "", + "" + ], + [ + "FLOAT16", + "", + "" + ], + [ + "FLOAT32", + "", + "" + ], + [ + "FLOAT64", + "", + "" + ], + [ + "BOOL", + "", + "" + ], + [ + "DTYPE_MAX", + "", + "" + ] + ], + "def": "enum DType\n {\n UINT8 = 0,\n INT8,\n UINT16,\n INT16,\n UINT32,\n INT32,\n FLOAT16,\n FLOAT32,\n FLOAT64,\n BOOL,\n // STRING,\n // OBJECT,\n DTYPE_MAX\n }" + }, + "dtype_size": { + "type": "var", + "name": "", + "doc": { + "brief": "Tensor data type size in bytes", + "attention": "It's a copy of this variable in MaixPy,\nso change it in C++ (e.g. update var in hello function) will not take effect the var inMaixPy.\nSo we add const for this var to avoid this mistake.", + "maixpy": "maix.tensor.dtype_size", + "py_doc": "Tensor data type size in bytes" + }, + "value": "{\n 1, // UINT8\n 1, // INT8\n 2, // UINT16\n 2, // INT16\n 4, // UINT32\n 4, // INT32\n 2, // FLOAT16\n 4, // FLOAT32\n 8, // FLOAT64\n 1, // BOOL\n // 1, // STRING\n // 1, // OBJECT\n 0\n }", + "static": false, + "readonly": true, + "def": "const std::vector dtype_size = {\n 1, // UINT8\n 1, // INT8\n 2, // UINT16\n 2, // INT16\n 4, // UINT32\n 4, // INT32\n 2, // FLOAT16\n 4, // FLOAT32\n 8, // FLOAT64\n 1, // BOOL\n // 1, // STRING\n // 1, // OBJECT\n 0\n }" + }, + "dtype_name": { + "type": "var", + "name": "", + "doc": { + "brief": "Tensor data type name", + "maixpy": "maix.tensor.dtype_name", + "py_doc": "Tensor data type name" + }, + "value": "{\n \"uint8\",\n \"int8\",\n \"uint16\",\n \"int16\",\n \"uint32\",\n \"int32\",\n \"float16\",\n \"float32\",\n \"float64\",\n \"bool\",\n // \"string\",\n // \"object\",\n \"invalid\"\n }", + "static": false, + "readonly": true, + "def": "const std::vector dtype_name = {\n \"uint8\",\n \"int8\",\n \"uint16\",\n \"int16\",\n \"uint32\",\n \"int32\",\n \"float16\",\n \"float32\",\n \"float64\",\n \"bool\",\n // \"string\",\n // \"object\",\n \"invalid\"\n }" + }, + "Tensor": { + "type": "class", + "name": "Tensor", + "doc": { + "brief": "Tensor class", + "maixpy": "maix.tensor.Tensor", + "py_doc": "Tensor class" + }, + "members": { + "__init__": { + "type": "func", + "name": "Tensor", + "doc": { + "brief": "Tensor constructor", + "param": { + "shape": "tensor shape, a int list", + "dtype": "tensor element data type, see DType of this module" + }, + "maixpy": "maix.tensor.Tensor.__init__", + "py_doc": "Tensor constructor\n\nArgs:\n - shape: tensor shape, a int list\n - dtype: tensor element data type, see DType of this module\n" + }, + "args": [ + [ + "std::vector", + "shape", + null + ], + [ + "tensor::DType", + "dtype", + null + ] + ], + "ret_type": null, + "static": false, + "def": "Tensor(std::vector shape, tensor::DType dtype)" + }, + "Tensor": { + "type": "func", + "name": "Tensor", + "doc": { + "brief": "Tensor constructor", + "param": { + "shape": "tensor shape, a int list", + "dtype": "tensor element data type, see DType of this module", + "data": "pointer to data content, can be nullptr, it will automatically alloc memory\nand detroy it when this object is destroyed", + "copy": "defalt true to alloc new memory and copy from data." + }, + "maixcdk": "maix.tensor.Tensor.Tensor", + "py_doc": "Tensor constructor\n\nArgs:\n - shape: tensor shape, a int list\n - dtype: tensor element data type, see DType of this module\n - data: pointer to data content, can be nullptr, it will automatically alloc memory\nand detroy it when this object is destroyed\n - copy: defalt true to alloc new memory and copy from data.\n" + }, + "args": [ + [ + "std::vector", + "shape", + null + ], + [ + "tensor::DType", + "dtype", + null + ], + [ + "void *", + "data", + null + ], + [ + "bool", + "copy", + "true" + ] + ], + "ret_type": null, + "static": false, + "def": "Tensor(std::vector shape, tensor::DType dtype, void *data, bool copy = true)" + }, + "to_str": { + "type": "func", + "name": "to_str", + "doc": { + "brief": "To string", + "maixpy": "maix.tensor.Tensor.to_str", + "py_doc": "To string" + }, + "args": [], + "ret_type": "std::string", + "static": false, + "def": "std::string to_str()" + }, + "__str__": { + "type": "func", + "name": "__str__", + "doc": { + "brief": "To string", + "maixpy": "maix.tensor.Tensor.__str__", + "py_doc": "To string" + }, + "args": [], + "ret_type": "std::string", + "static": false, + "def": "std::string __str__()" + }, + "shape": { + "type": "func", + "name": "shape", + "doc": { + "brief": "get tensor shape", + "return": "tensor shape, a int list", + "maixpy": "maix.tensor.Tensor.shape", + "py_doc": "get tensor shape\n\nReturns: tensor shape, a int list\n" + }, + "args": [], + "ret_type": "std::vector", + "static": false, + "def": "std::vector shape()" + }, + "expand_dims": { + "type": "func", + "name": "expand_dims", + "doc": { + "brief": "expand tensor shape", + "param": { + "axis": "axis to expand" + }, + "maixpy": "maix.tensor.Tensor.expand_dims", + "py_doc": "expand tensor shape\n\nArgs:\n - axis: axis to expand\n" + }, + "args": [ + [ + "int", + "axis", + null + ] + ], + "ret_type": "void", + "static": false, + "def": "void expand_dims(int axis)" + }, + "reshape": { + "type": "func", + "name": "reshape", + "doc": { + "brief": "reshape tensor shape, if size not match, it will throw an err::Exception", + "param": { + "shape": "new shape" + }, + "maixpy": "maix.tensor.Tensor.reshape", + "py_doc": "reshape tensor shape, if size not match, it will throw an err::Exception\n\nArgs:\n - shape: new shape\n" + }, + "args": [ + [ + "std::vector", + "shape", + null + ] + ], + "ret_type": "void", + "static": false, + "def": "void reshape(std::vector shape)" + }, + "flatten": { + "type": "func", + "name": "flatten", + "doc": { + "brief": "Flatten tensor shape to 1D", + "maixpy": "maix.tensor.Tensor.flatten", + "py_doc": "Flatten tensor shape to 1D" + }, + "args": [], + "ret_type": "void", + "static": false, + "def": "void flatten()" + }, + "dtype": { + "type": "func", + "name": "dtype", + "doc": { + "brief": "get tensor data type", + "return": "tensor data type, see DType of this module", + "maixpy": "maix.tensor.Tensor.dtype", + "py_doc": "get tensor data type\n\nReturns: tensor data type, see DType of this module\n" + }, + "args": [], + "ret_type": "tensor::DType", + "static": false, + "def": "tensor::DType dtype()" + }, + "to_float_list": { + "type": "func", + "name": "to_float_list", + "doc": { + "brief": "get tensor data and return a list", + "return": "list type data", + "maixpy": "maix.tensor.Tensor.to_float_list", + "py_doc": "get tensor data and return a list\n\nReturns: list type data\n" + }, + "args": [], + "ret_type": "std::valarray*", + "static": false, + "def": "std::valarray* to_float_list()" + }, + "argmax": { + "type": "func", + "name": "argmax", + "doc": { + "brief": "argmax of tensor", + "param": { + "axis": "By default, the index is into the flattened array, otherwise along the specified axis., wrong axis will throw an err::Exception" + }, + "return": "argmax result, you need to delete it after use in C++.", + "maixpy": "maix.tensor.Tensor.argmax", + "py_doc": "argmax of tensor\n\nArgs:\n - axis: By default, the index is into the flattened array, otherwise along the specified axis., wrong axis will throw an err::Exception\n\n\nReturns: argmax result, you need to delete it after use in C++.\n" + }, + "args": [ + [ + "int", + "axis", + "0xffff" + ] + ], + "ret_type": "tensor::Tensor*", + "static": false, + "def": "tensor::Tensor *argmax(int axis = 0xffff)" + }, + "argmax1": { + "type": "func", + "name": "argmax1", + "doc": { + "brief": "argmax1, flattened data max index", + "return": "argmax result, int type", + "maixpy": "maix.tensor.Tensor.argmax1", + "py_doc": "argmax1, flattened data max index\n\nReturns: argmax result, int type\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int argmax1()" + } + }, + "def": "class Tensor" + }, + "Tensors": { + "type": "class", + "name": "Tensors", + "doc": { + "brief": "Tensors", + "maixpy": "maix.tensor.Tensors", + "py_doc": "Tensors" + }, + "members": { + "Tensors": { + "type": "func", + "name": "Tensors", + "doc": { + "brief": "Constructor of Tensors", + "maixpy": "maix.tensor.Tensors.__init__", + "maixcdk": "maix.tensor.Tensors.Tensors", + "py_doc": "Constructor of Tensors" + }, + "args": [], + "ret_type": null, + "static": false, + "def": "Tensors()" + }, + "add_tensor": { + "type": "func", + "name": "add_tensor", + "doc": { + "brief": "Add tensor", + "maixpy": "maix.tensor.Tensors.add_tensor", + "py_doc": "Add tensor" + }, + "args": [ + [ + "const std::string &", + "key", + null + ], + [ + "tensor::Tensor *", + "tensor", + null + ], + [ + "bool", + "copy", + null + ], + [ + "bool", + "auto_delete", + null + ] + ], + "ret_type": "void", + "static": false, + "def": "void add_tensor(const std::string &key, tensor::Tensor *tensor, bool copy, bool auto_delete)" + }, + "rm_tensor": { + "type": "func", + "name": "rm_tensor", + "doc": { + "brief": "Remove tensor", + "maixpy": "maix.tensor.Tensors.rm_tensor", + "py_doc": "Remove tensor" + }, + "args": [ + [ + "const std::string &", + "key", + null + ] + ], + "ret_type": "void", + "static": false, + "def": "void rm_tensor(const std::string &key)" + }, + "clear": { + "type": "func", + "name": "clear", + "doc": { + "brief": "Clear tensors", + "maixpy": "maix.tensor.Tensors.clear", + "py_doc": "Clear tensors" + }, + "args": [], + "ret_type": "void", + "static": false, + "def": "void clear()" + }, + "begin": { + "type": "func", + "name": "begin", + "doc": { + "brief": "Begin of tensors", + "maixcdk": "maix.tensor.Tensors.begin", + "py_doc": "Begin of tensors" + }, + "args": [], + "ret_type": "std::map::iterator", + "static": false, + "def": "std::map::iterator begin()" + }, + "end": { + "type": "func", + "name": "end", + "doc": { + "brief": "End of tensors", + "maixcdk": "maix.tensor.Tensors.end", + "py_doc": "End of tensors" + }, + "args": [], + "ret_type": "std::map::iterator", + "static": false, + "def": "std::map::iterator end()" + }, + "next": { + "type": "func", + "name": "next", + "doc": { + "brief": "__next__", + "maixcdk": "maix.tensor.Tensors.next", + "py_doc": "__next__" + }, + "args": [ + [ + "std::map::iterator", + "it", + null + ] + ], + "ret_type": "std::map::iterator", + "static": false, + "def": "std::map::iterator next(std::map::iterator it)" + }, + "get_tensor": { + "type": "func", + "name": "get_tensor", + "doc": { + "brief": "Get tensor by key", + "maixpy": "maix.tensor.Tensors.get_tensor", + "maixcdk": "maix.tensor.Tensors.get_tensor", + "py_doc": "Get tensor by key" + }, + "args": [ + [ + "const std::string &", + "key", + null + ] + ], + "ret_type": "tensor::Tensor&", + "static": false, + "def": "tensor::Tensor &get_tensor(const std::string &key)" + }, + "[]": { + "type": "func", + "name": "operator[]", + "doc": { + "brief": "Operator []", + "maixpy": "maix.tensor.Tensors.__getitem__", + "maixcdk": "maix.tensor.Tensors.[]", + "py_doc": "Operator []" + }, + "args": [ + [ + "const std::string &", + "key", + null + ] + ], + "ret_type": "tensor::Tensor&", + "static": false, + "def": "tensor::Tensor &operator[](const std::string &key)" + }, + "size": { + "type": "func", + "name": "size", + "doc": { + "brief": "Size", + "maixpy": "maix.tensor.Tensors.__len__", + "maixcdk": "maix.tensor.Tensors.size", + "py_doc": "Size" + }, + "args": [], + "ret_type": "size_t", + "static": false, + "def": "size_t size()" + }, + "keys": { + "type": "func", + "name": "keys", + "doc": { + "brief": "Get names", + "maixpy": "maix.tensor.Tensors.keys", + "py_doc": "Get names" + }, + "args": [], + "ret_type": "std::vector", + "static": false, + "def": "std::vector keys()" + }, + "tensors": { + "type": "var", + "name": "tensors", + "doc": { + "brief": "Tensors data, dict type", + "maixpy": "maix.tensor.Tensors.tensors", + "py_doc": "Tensors data, dict type" + }, + "value": null, + "static": false, + "readonly": false, + "def": "std::map tensors" + } + }, + "def": "class Tensors" + } + }, + "auto_add": true + }, + "i18n": { + "type": "module", + "doc": { + "brief": "maix.i18n module" + }, + "members": { + "locales": { + "type": "var", + "name": "", + "doc": { + "brief": "i18n locales list", + "maixpy": "maix.i18n.locales", + "py_doc": "i18n locales list" + }, + "value": "{\n \"en\",\n \"zh\",\n \"zh-tw\",\n \"ja\"}", + "static": true, + "readonly": false, + "def": "static std::vector locales = {\n \"en\",\n \"zh\",\n \"zh-tw\",\n \"ja\"}" + }, + "names": { + "type": "var", + "name": "", + "doc": { + "brief": "i18n language names list", + "maixpy": "maix.i18n.names", + "py_doc": "i18n language names list" + }, + "value": "{\n \"English\",\n \"\u7b80\u4f53\u4e2d\u6587\",\n \"\u7e41\u9ad4\u4e2d\u6587\",\n \"\u65e5\u672c\u8a9e\"}", + "static": false, + "readonly": true, + "def": "const static std::vector names = {\n \"English\",\n \"\u7b80\u4f53\u4e2d\u6587\",\n \"\u7e41\u9ad4\u4e2d\u6587\",\n \"\u65e5\u672c\u8a9e\"}" + }, + "get_locale": { + "type": "func", + "name": "get_locale", + "doc": { + "brief": "Get system config of locale.", + "return": "language locale, e.g. en, zh, zh_CN, zh_TW, etc.", + "maixpy": "maix.i18n.get_locale", + "py_doc": "Get system config of locale.\n\nReturns: language locale, e.g. en, zh, zh_CN, zh_TW, etc.\n" + }, + "args": [], + "ret_type": "string", + "static": false, + "def": "string get_locale()" + }, + "get_language_name": { + "type": "func", + "name": "get_language_name", + "doc": { + "brief": "Get system config of language name.", + "return": "language name, e.g. English, \u7b80\u4f53\u4e2d\u6587, \u7e41\u9ad4\u4e2d\u6587, etc.", + "maixpy": "maix.i18n.get_language_name", + "py_doc": "Get system config of language name.\n\nReturns: language name, e.g. English, \u7b80\u4f53\u4e2d\u6587, \u7e41\u9ad4\u4e2d\u6587, etc.\n" + }, + "args": [], + "ret_type": "string", + "static": false, + "def": "string get_language_name()" + }, + "load_trans_yaml": { + "type": "func", + "name": "load_trans_yaml", + "doc": { + "brief": "Load translations from yaml files.", + "param": { + "locales_dir": "translation yaml files directory." + }, + "return": "A dict contains all translations, e.g. {\"zh\":{\"hello\": \"\u4f60\u597d\"}, \"en\":{\"hello\": \"hello\"}}, you should delete it after use in C++.", + "maixpy": "maix.i18n.load_trans_yaml", + "py_doc": "Load translations from yaml files.\n\nArgs:\n - locales_dir: translation yaml files directory.\n\n\nReturns: A dict contains all translations, e.g. {\"zh\":{\"hello\": \"\u4f60\u597d\"}, \"en\":{\"hello\": \"hello\"}}, you should delete it after use in C++.\n" + }, + "args": [ + [ + "const std::string &", + "locales_dir", + null + ] + ], + "ret_type": "const std::map>*", + "static": false, + "def": "const std::map> *load_trans_yaml(const std::string &locales_dir)", + "overload": [ + { + "type": "func", + "name": "load_trans_yaml", + "doc": { + "brief": "Load translations from yaml files.", + "param": { + "locales_dir": "translation yaml files directory.", + "dict": "dict to store key values. A dict contains all translations, e.g. {\"zh\":{\"hello\": \"\u4f60\u597d\"}, \"en\":{\"hello\": \"hello\"}}, you should delete it after use in C++." + }, + "return": "err::ERR", + "maixcdk": "maix.i18n.load_trans_yaml", + "py_doc": "Load translations from yaml files.\n\nArgs:\n - locales_dir: translation yaml files directory.\n - dict: dict to store key values. A dict contains all translations, e.g. {\"zh\":{\"hello\": \"\u4f60\u597d\"}, \"en\":{\"hello\": \"hello\"}}, you should delete it after use in C++.\n\n\nReturns: err::ERR\n" + }, + "args": [ + [ + "const std::string &", + "locales_dir", + null + ], + [ + "std::map> &", + "dict", + null + ] + ], + "ret_type": "err::Err", + "static": false, + "def": "err::Err load_trans_yaml(const std::string &locales_dir, std::map> &dict)" + } + ] + }, + "Trans": { + "type": "class", + "name": "Trans", + "doc": { + "brief": "Translate helper class.", + "maixpy": "maix.i18n.Trans", + "py_doc": "Translate helper class." + }, + "members": { + "Trans": { + "type": "func", + "name": "Trans", + "doc": { + "brief": "Translate helper class constructor.\\nBy default locale is get by `i18n.get_locale()` function which set by system settings.\\nBut you can also manually set by `set_locale` function temporarily.", + "param": { + "locales_dict": "locales dict, e.g. {\"zh\": {\"Confirm\": \"\u786e\u8ba4\", \"OK\": \"\u597d\u7684\"}, \"en\": {\"Confirm\": \"Confirm\", \"OK\": \"OK\"}}" + }, + "maixpy": "maix.i18n.Trans.__init__", + "maixcdk": "maix.i18n.Trans.Trans", + "py_doc": "Translate helper class constructor.\nBy default locale is get by `i18n.get_locale()` function which set by system settings.\nBut you can also manually set by `set_locale` function temporarily.\n\nArgs:\n - locales_dict: locales dict, e.g. {\"zh\": {\"Confirm\": \"\u786e\u8ba4\", \"OK\": \"\u597d\u7684\"}, \"en\": {\"Confirm\": \"Confirm\", \"OK\": \"OK\"}}\n" + }, + "args": [ + [ + "const std::map> &", + "locales_dict", + "std::map>()" + ] + ], + "ret_type": null, + "static": false, + "def": "Trans(const std::map> &locales_dict = std::map>())" + }, + "load": { + "type": "func", + "name": "load", + "doc": { + "brief": "Load translation from yaml files generated by `maixtool i18n` command.", + "param": { + "locales_dir": "the translation files directory." + }, + "return": "err.Err type, no error will return err.Err.ERR_NONE.", + "maixpy": "maix.i18n.Trans.load", + "py_doc": "Load translation from yaml files generated by `maixtool i18n` command.\n\nArgs:\n - locales_dir: the translation files directory.\n\n\nReturns: err.Err type, no error will return err.Err.ERR_NONE.\n" + }, + "args": [ + [ + "const std::string &", + "locales_dir", + null + ] + ], + "ret_type": "err::Err", + "static": false, + "def": "err::Err load(const std::string &locales_dir)" + }, + "update_dict": { + "type": "func", + "name": "update_dict", + "doc": { + "brief": "Update translation dict.", + "param": { + "dict": "the new translation dict." + }, + "return": "err.Err type, no error will return err.Err.ERR_NONE.", + "maixpy": "maix.i18n.Trans.update_dict", + "py_doc": "Update translation dict.\n\nArgs:\n - dict: the new translation dict.\n\n\nReturns: err.Err type, no error will return err.Err.ERR_NONE.\n" + }, + "args": [ + [ + "const std::map> &", + "dict", + null + ] + ], + "ret_type": "err::Err", + "static": false, + "def": "err::Err update_dict(const std::map> &dict)" + }, + "tr": { + "type": "func", + "name": "tr", + "doc": { + "brief": "Translate string by key.", + "param": { + "key": "string key, e.g. \"Confirm\"", + "locale": "locale name, if not assign, use default locale set by system settings or set_locale function." + }, + "return": "translated string, if find translation, return it, or return key, e.g. \"\u786e\u8ba4\", \"Confirm\", etc.", + "maixpy": "maix.i18n.Trans.tr", + "py_doc": "Translate string by key.\n\nArgs:\n - key: string key, e.g. \"Confirm\"\n - locale: locale name, if not assign, use default locale set by system settings or set_locale function.\n\n\nReturns: translated string, if find translation, return it, or return key, e.g. \"\u786e\u8ba4\", \"Confirm\", etc.\n" + }, + "args": [ + [ + "const string &", + "key", + null + ], + [ + "const string", + "locale", + "\"\"" + ] + ], + "ret_type": "string", + "static": false, + "def": "string tr(const string &key, const string locale = \"\")" + }, + "set_locale": { + "type": "func", + "name": "set_locale", + "doc": { + "brief": "Set locale temporarily, will not affect system settings.", + "param": { + "locale": "locale name, e.g. \"zh\", \"en\", etc. @see maix.i18n.locales" + }, + "maixpy": "maix.i18n.Trans.set_locale", + "py_doc": "Set locale temporarily, will not affect system settings.\n\nArgs:\n - locale: locale name, e.g. \"zh\", \"en\", etc. @see maix.i18n.locales\n" + }, + "args": [ + [ + "const string &", + "locale", + null + ] + ], + "ret_type": "void", + "static": false, + "def": "void set_locale(const string &locale)" + }, + "get_locale": { + "type": "func", + "name": "get_locale", + "doc": { + "brief": "Get current locale.", + "return": "locale name, e.g. \"zh\", \"en\", etc. @see maix.i18n.locales", + "maixpy": "maix.i18n.Trans.get_locale", + "py_doc": "Get current locale.\n\nReturns: locale name, e.g. \"zh\", \"en\", etc. @see maix.i18n.locales\n" + }, + "args": [], + "ret_type": "string", + "static": false, + "def": "string get_locale()" + } + }, + "def": "class Trans" + } + }, + "auto_add": true + }, + "peripheral": { + "type": "module", + "doc": { + "brief": "Chip's peripheral driver", + "maixpy": "maix.peripheral", + "py_doc": "Chip's peripheral driver" + }, + "members": { + "key": { + "type": "module", + "doc": { + "brief": "maix.peripheral.key module" + }, + "members": { + "Keys": { + "type": "enum", + "name": "Keys{", + "doc": { + "brief": "Keys enum, id the same as linux input.h(input-event-codes.h)", + "maixpy": "maix.peripheral.key.Keys", + "py_doc": "Keys enum, id the same as linux input.h(input-event-codes.h)" + }, + "values": [ + [ + "KEY_NONE", + "0x000", + "" + ], + [ + "KEY_ESC", + "0x001", + "" + ], + [ + "KEY_POWER", + "0x074", + "" + ], + [ + "KEY_OK", + "0x160", + "" + ], + [ + "KEY_OPTION", + "0x165", + "" + ], + [ + "KEY_NEXT", + "0x197", + "" + ], + [ + "KEY_PREV", + "0x19c", + "" + ] + ], + "def": "enum Keys{\n KEY_NONE = 0x000,\n KEY_ESC = 0x001,\n KEY_POWER = 0x074,\n KEY_OK = 0x160,\n KEY_OPTION = 0x165,\n KEY_NEXT = 0x197,\n KEY_PREV = 0x19c,\n }" + }, + "State": { + "type": "enum", + "name": "State{", + "doc": { + "brief": "Key state enum", + "maixpy": "maix.peripheral.key.State", + "py_doc": "Key state enum" + }, + "values": [ + [ + "KEY_RELEASED", + "0", + "" + ], + [ + "KEY_PRESSED", + "1", + "" + ], + [ + "KEY_LONG_PRESSED", + "2", + "" + ] + ], + "def": "enum State{\n KEY_RELEASED = 0,\n KEY_PRESSED = 1,\n KEY_LONG_PRESSED = 2,\n }" + }, + "Key": { + "type": "class", + "name": "Key", + "doc": { + "brief": "Key input class", + "maixpy": "maix.peripheral.key.Key", + "py_doc": "Key input class" + }, + "members": { + "Key": { + "type": "func", + "name": "Key", + "doc": { + "brief": "Key Device constructor", + "param": { + "callback": "When key triggered and callback is not empty(empty In MaixPy is None, in C++ is nullptr),\ncallback will be called with args key(key.Keys) and value(key.State).\nIf set to null, you can get key value by read() function.\nThis callback called in a standalone thread, so you can block a while in callback, and you should be carefully when operate shared data.", + "open": "auto open device in constructor, if false, you need call open() to open device.", + "device": "Specifies the input device to use. The default initializes all keys,\nfor a specific device, provide the path (e.g., \"/dev/input/device\").", + "long_press_time": "The duration (in milliseconds) from pressing the key to triggering the long press event. Default is 2000ms." + }, + "maixpy": "maix.peripheral.key.Key.__init__", + "maixcdk": "maix.peripheral.key.Key.Key", + "py_doc": "Key Device constructor\n\nArgs:\n - callback: When key triggered and callback is not empty(empty In MaixPy is None, in C++ is nullptr),\ncallback will be called with args key(key.Keys) and value(key.State).\nIf set to null, you can get key value by read() function.\nThis callback called in a standalone thread, so you can block a while in callback, and you should be carefully when operate shared data.\n - open: auto open device in constructor, if false, you need call open() to open device.\n - device: Specifies the input device to use. The default initializes all keys,\nfor a specific device, provide the path (e.g., \"/dev/input/device\").\n - long_press_time: The duration (in milliseconds) from pressing the key to triggering the long press event. Default is 2000ms.\n" + }, + "args": [ + [ + "std::function", + "callback", + "nullptr" + ], + [ + "bool", + "open", + "true" + ], + [ + "const string &", + "device", + "\"\"" + ], + [ + "int", + "long_press_time", + "2000" + ] + ], + "ret_type": null, + "static": false, + "def": "Key(std::function callback = nullptr, bool open = true, const string &device = \"\", int long_press_time = 2000)" + }, + "open": { + "type": "func", + "name": "open", + "doc": { + "brief": "Open(Initialize) key device, if already opened, will close first and then open.", + "return": "err::Err type, err.Err.ERR_NONE means success", + "maixpy": "maix.peripheral.key.Key.open", + "py_doc": "Open(Initialize) key device, if already opened, will close first and then open.\n\nReturns: err::Err type, err.Err.ERR_NONE means success\n" + }, + "args": [], + "ret_type": "err::Err", + "static": false, + "def": "err::Err open()" + }, + "close": { + "type": "func", + "name": "close", + "doc": { + "brief": "Close key device", + "return": "err::Err type, err.Err.ERR_NONE means success", + "maixpy": "maix.peripheral.key.Key.close", + "py_doc": "Close key device\n\nReturns: err::Err type, err.Err.ERR_NONE means success\n" + }, + "args": [], + "ret_type": "err::Err", + "static": false, + "def": "err::Err close()" + }, + "is_opened": { + "type": "func", + "name": "is_opened", + "doc": { + "brief": "Check key device is opened", + "return": "bool type, true means opened, false means closed", + "maixpy": "maix.peripheral.key.Key.is_opened", + "py_doc": "Check key device is opened\n\nReturns: bool type, true means opened, false means closed\n" + }, + "args": [], + "ret_type": "bool", + "static": false, + "def": "bool is_opened()" + }, + "read": { + "type": "func", + "name": "read", + "doc": { + "brief": "Read key input, if callback is set, DO NOT call this function manually.", + "param": { + "key": "maix.key.Keys type, indicate which key is triggered, e.g. maix.key.Keys.KEY_OK mean the OK key is triggered.\nIf read failed, will not change the value of key.", + "value": "maix.key.State type, indicate the key state, e.g. maix.key.State.KEY_PRESSED mean the key is pressed\nIf read failed, will not change the value of value." + }, + "return": "err::Err type, err.Err.ERR_NONE means success, err.Err.ERR_NOT_READY means no key input, other means error.", + "maixcdk": "maix.peripheral.key.Key.read", + "py_doc": "Read key input, if callback is set, DO NOT call this function manually.\n\nArgs:\n - key: maix.key.Keys type, indicate which key is triggered, e.g. maix.key.Keys.KEY_OK mean the OK key is triggered.\nIf read failed, will not change the value of key.\n - value: maix.key.State type, indicate the key state, e.g. maix.key.State.KEY_PRESSED mean the key is pressed\nIf read failed, will not change the value of value.\n\n\nReturns: err::Err type, err.Err.ERR_NONE means success, err.Err.ERR_NOT_READY means no key input, other means error.\n" + }, + "args": [ + [ + "int &", + "key", + null + ], + [ + "int &", + "value", + null + ] + ], + "ret_type": "err::Err", + "static": false, + "def": "err::Err read(int &key, int &value)", + "overload": [ + { + "type": "func", + "name": "read", + "doc": { + "brief": "Read key input, and return key and value, if callback is set, DO NOT call this function manually.", + "return": "list type, first is key(maix.key.Keys), second is value(maix.key.State), if no key input, return [0, 0]", + "throw": "If read failed, will throw maix.err.Exception.", + "maixpy": "maix.peripheral.key.Key.read", + "py_doc": "Read key input, and return key and value, if callback is set, DO NOT call this function manually.\n\nReturns: list type, first is key(maix.key.Keys), second is value(maix.key.State), if no key input, return [0, 0]\n" + }, + "args": [], + "ret_type": "std::pair", + "static": false, + "def": "std::pair read()" + } + ] + }, + "long_press_time": { + "type": "func", + "name": "long_press_time", + "doc": { + "brief": "Sets and retrieves the key's long press time.", + "param": { + "press_time": "The long press time to set for the key.\nSetting it to 0 will disable the long press event." + }, + "return": "int type, the current long press time for the key (in milliseconds).", + "maixpy": "maix.peripheral.key.Key.long_press_time", + "py_doc": "Sets and retrieves the key's long press time.\n\nArgs:\n - press_time: The long press time to set for the key.\nSetting it to 0 will disable the long press event.\n\n\nReturns: int type, the current long press time for the key (in milliseconds).\n" + }, + "args": [ + [ + "int", + "press_time", + "-1" + ] + ], + "ret_type": "int", + "static": false, + "def": "int long_press_time(int press_time = -1)" + } + }, + "def": "class Key" + }, + "add_default_listener": { + "type": "func", + "name": "add_default_listener", + "doc": { + "brief": "Add default listener, if you want to exit app when press ok button, you can just call this function.\\nThis function is auto called in MaixPy' startup code, so you don't need to call it in MaixPy.\\nCreate Key object will auto call rm_default_listener() to cancel the default ok button function.\\nWhen ok button pressed, a SIGINT signal will be raise and call app.set_exit_flag(True).", + "maixpy": "maix.peripheral.key.add_default_listener", + "py_doc": "Add default listener, if you want to exit app when press ok button, you can just call this function.\nThis function is auto called in MaixPy' startup code, so you don't need to call it in MaixPy.\nCreate Key object will auto call rm_default_listener() to cancel the default ok button function.\nWhen ok button pressed, a SIGINT signal will be raise and call app.set_exit_flag(True)." + }, + "args": [], + "ret_type": "void", + "static": false, + "def": "void add_default_listener()" + }, + "rm_default_listener": { + "type": "func", + "name": "rm_default_listener", + "doc": { + "brief": "Remove default listener, if you want to cancel the default ok button function(exit app), you can just call this function.", + "maixpy": "maix.peripheral.key.rm_default_listener", + "py_doc": "Remove default listener, if you want to cancel the default ok button function(exit app), you can just call this function." + }, + "args": [], + "ret_type": "void", + "static": false, + "def": "void rm_default_listener()" + } + }, + "auto_add": true + }, + "i2c": { + "type": "module", + "doc": { + "brief": "maix.peripheral.i2c module" + }, + "members": { + "AddrSize": { + "type": "enum", + "name": "AddrSize", + "doc": { + "brief": "Address size enum", + "maixpy": "maix.peripheral.i2c.AddrSize", + "py_doc": "Address size enum" + }, + "values": [ + [ + "SEVEN_BIT", + "7", + "7-bit address mode" + ], + [ + "TEN_BIT", + "10", + "10-bit address mode" + ] + ], + "def": "enum AddrSize\n {\n SEVEN_BIT = 7, // 7-bit address mode\n TEN_BIT = 10 // 10-bit address mode\n }" + }, + "Mode": { + "type": "enum", + "name": "Mode", + "doc": { + "brief": "I2C mode enum", + "maixpy": "maix.peripheral.i2c.Mode", + "py_doc": "I2C mode enum" + }, + "values": [ + [ + "MASTER", + "0x00", + "master mode" + ], + [ + "SLAVE", + "0x01", + "slave mode" + ] + ], + "def": "enum Mode\n {\n MASTER = 0x00, // master mode\n SLAVE = 0x01 // slave mode\n }" + }, + "list_devices": { + "type": "func", + "name": "list_devices", + "doc": { + "brief": "Get supported i2c bus devices.", + "return": "i2c bus devices list, int type, is the i2c bus id.", + "maixpy": "maix.peripheral.i2c.list_devices", + "py_doc": "Get supported i2c bus devices.\n\nReturns: i2c bus devices list, int type, is the i2c bus id.\n" + }, + "args": [], + "ret_type": "std::vector", + "static": false, + "def": "std::vector list_devices()" + }, + "I2C": { + "type": "class", + "name": "I2C", + "doc": { + "brief": "Peripheral i2c class", + "maixpy": "maix.peripheral.i2c.I2C", + "py_doc": "Peripheral i2c class" + }, + "members": { + "__init__": { + "type": "func", + "name": "I2C", + "doc": { + "brief": "I2C Device constructor\\nthis constructor will be export to MaixPy as _maix.example.Example.__init__", + "param": { + "id": "direction [in], i2c bus id, int type, e.g. 0, 1, 2", + "freq": "direction [in], i2c clock, int type, default is 100000(100kbit/s), will auto set fast mode if freq > 100000.", + "mode": "direction [in], mode of i2c, i2c.Mode.SLAVE or i2c.Mode.MASTER.", + "addr_size": "direction [in], address length of i2c, i2c.AddrSize.SEVEN_BIT or i2c.AddrSize.TEN_BIT." + }, + "throw": "err::Exception if open i2c device failed.", + "maixpy": "maix.peripheral.i2c.I2C.__init__", + "py_doc": "I2C Device constructor\nthis constructor will be export to MaixPy as _maix.example.Example.__init__\n\nArgs:\n - id: direction [in], i2c bus id, int type, e.g. 0, 1, 2\n - freq: direction [in], i2c clock, int type, default is 100000(100kbit/s), will auto set fast mode if freq > 100000.\n - mode: direction [in], mode of i2c, i2c.Mode.SLAVE or i2c.Mode.MASTER.\n - addr_size: direction [in], address length of i2c, i2c.AddrSize.SEVEN_BIT or i2c.AddrSize.TEN_BIT.\n" + }, + "args": [ + [ + "int", + "id", + null + ], + [ + "i2c::Mode", + "mode", + null + ], + [ + "int", + "freq", + "100000" + ], + [ + "i2c::AddrSize", + "addr_size", + "i2c::AddrSize::SEVEN_BIT" + ] + ], + "ret_type": null, + "static": false, + "def": "I2C(int id, i2c::Mode mode, int freq = 100000, i2c::AddrSize addr_size = i2c::AddrSize::SEVEN_BIT)" + }, + "scan": { + "type": "func", + "name": "scan", + "doc": { + "brief": "scan all i2c salve address on the bus", + "param": { + "addr": "If -1, only scan this addr, or scan from 0x08~0x77, default -1." + }, + "return": "the list of i2c slave address, int list type.", + "maixpy": "maix.peripheral.i2c.I2C.scan", + "py_doc": "scan all i2c salve address on the bus\n\nArgs:\n - addr: If -1, only scan this addr, or scan from 0x08~0x77, default -1.\n\n\nReturns: the list of i2c slave address, int list type.\n" + }, + "args": [ + [ + "int", + "addr", + "-1" + ] + ], + "ret_type": "std::vector", + "static": false, + "def": "std::vector scan(int addr = -1)" + }, + "writeto": { + "type": "func", + "name": "writeto", + "doc": { + "brief": "write data to i2c slave", + "param": { + "addr": "direction [in], i2c slave address, int type", + "data": "direction [in], data to write, vector type in C++, int list in MaixPy.\nNote: The range of value should be in [0,255]." + }, + "return": "if success, return the length of written data, error occurred will return -err::Err\u3002", + "maixcdk": "maix.peripheral.i2c.I2C.writeto", + "py_doc": "write data to i2c slave\n\nArgs:\n - addr: direction [in], i2c slave address, int type\n - data: direction [in], data to write, vector type in C++, int list in MaixPy.\nNote: The range of value should be in [0,255].\n\n\nReturns: if success, return the length of written data, error occurred will return -err::Err\u3002\n" + }, + "args": [ + [ + "int", + "addr", + null + ], + [ + "const std::vector", + "data", + null + ] + ], + "ret_type": "int", + "static": false, + "def": "int writeto(int addr, const std::vector data)", + "overload": [ + { + "type": "func", + "name": "writeto", + "doc": { + "brief": "write data to i2c slave", + "param": { + "addr": "direction [in], i2c slave address, int type", + "data": "direction [in], data to write, bytes type.\nNote: The range of value should be in [0,255]." + }, + "return": "if success, return the length of written data, error occurred will return -err::Err.", + "maixpy": "maix.peripheral.i2c.I2C.writeto", + "py_doc": "write data to i2c slave\n\nArgs:\n - addr: direction [in], i2c slave address, int type\n - data: direction [in], data to write, bytes type.\nNote: The range of value should be in [0,255].\n\n\nReturns: if success, return the length of written data, error occurred will return -err::Err.\n" + }, + "args": [ + [ + "int", + "addr", + null + ], + [ + "const Bytes &", + "data", + null + ] + ], + "ret_type": "int", + "static": false, + "def": "int writeto(int addr, const Bytes &data)" + }, + { + "type": "func", + "name": "writeto", + "doc": { + "brief": "write data to i2c slave", + "param": { + "addr": "direction [in], i2c slave address, int type", + "data": "direction [in], data to write, uint8_t type.", + "len": "direction [in], data length to write, int type" + }, + "return": "if success, return the length of written data, error occurred will return -err::Err.", + "maixcdk": "maix.peripheral.i2c.I2C.writeto", + "py_doc": "write data to i2c slave\n\nArgs:\n - addr: direction [in], i2c slave address, int type\n - data: direction [in], data to write, uint8_t type.\n - len: direction [in], data length to write, int type\n\n\nReturns: if success, return the length of written data, error occurred will return -err::Err.\n" + }, + "args": [ + [ + "int", + "addr", + null + ], + [ + "const uint8_t *", + "data", + null + ], + [ + "int", + "len", + null + ] + ], + "ret_type": "int", + "static": false, + "def": "int writeto(int addr, const uint8_t *data, int len)" + } + ] + }, + "readfrom": { + "type": "func", + "name": "readfrom", + "doc": { + "brief": "read data from i2c slave", + "param": { + "addr": "direction [in], i2c slave address, int type", + "len": "direction [in], data length to read, int type" + }, + "return": "the list of data read from i2c slave, bytes type, you should delete it after use in C++.\nIf read failed, return nullptr in C++, None in MaixPy.", + "maixpy": "maix.peripheral.i2c.I2C.readfrom", + "py_doc": "read data from i2c slave\n\nArgs:\n - addr: direction [in], i2c slave address, int type\n - len: direction [in], data length to read, int type\n\n\nReturns: the list of data read from i2c slave, bytes type, you should delete it after use in C++.\nIf read failed, return nullptr in C++, None in MaixPy.\n" + }, + "args": [ + [ + "int", + "addr", + null + ], + [ + "int", + "len", + null + ] + ], + "ret_type": "Bytes*", + "static": false, + "def": "Bytes* readfrom(int addr, int len)" + }, + "writeto_mem": { + "type": "func", + "name": "writeto_mem", + "doc": { + "brief": "write data to i2c slave's memory address", + "param": { + "addr": "direction [in], i2c slave address, int type", + "mem_addr": "direction [in], memory address want to write, int type.", + "data": "direction [in], data to write, vector type.", + "mem_addr_size": "direction [in], memory address size, default is 8.", + "mem_addr_le": "direction [in], memory address little endian, default is false, that is send high byte first." + }, + "return": "data length written if success, error occurred will return -err::Err.", + "maixcdk": "maix.peripheral.i2c.I2C.writeto_mem", + "py_doc": "write data to i2c slave's memory address\n\nArgs:\n - addr: direction [in], i2c slave address, int type\n - mem_addr: direction [in], memory address want to write, int type.\n - data: direction [in], data to write, vector type.\n - mem_addr_size: direction [in], memory address size, default is 8.\n - mem_addr_le: direction [in], memory address little endian, default is false, that is send high byte first.\n\n\nReturns: data length written if success, error occurred will return -err::Err.\n" + }, + "args": [ + [ + "int", + "addr", + null + ], + [ + "int", + "mem_addr", + null + ], + [ + "const std::vector", + "data", + null + ], + [ + "int", + "mem_addr_size", + "8" + ], + [ + "bool", + "mem_addr_le", + "false" + ] + ], + "ret_type": "int", + "static": false, + "def": "int writeto_mem(int addr, int mem_addr, const std::vector data, int mem_addr_size = 8, bool mem_addr_le = false)", + "overload": [ + { + "type": "func", + "name": "writeto_mem", + "doc": { + "brief": "write data to i2c slave's memory address", + "param": { + "addr": "direction [in], i2c slave address, int type", + "mem_addr": "direction [in], memory address want to write, int type.", + "data": "direction [in], data to write, bytes type.", + "mem_addr_size": "direction [in], memory address size, default is 8.", + "mem_addr_le": "direction [in], memory address little endian, default is false, that is send high byte first." + }, + "return": "data length written if success, error occurred will return -err::Err.", + "maixpy": "maix.peripheral.i2c.I2C.writeto_mem", + "py_doc": "write data to i2c slave's memory address\n\nArgs:\n - addr: direction [in], i2c slave address, int type\n - mem_addr: direction [in], memory address want to write, int type.\n - data: direction [in], data to write, bytes type.\n - mem_addr_size: direction [in], memory address size, default is 8.\n - mem_addr_le: direction [in], memory address little endian, default is false, that is send high byte first.\n\n\nReturns: data length written if success, error occurred will return -err::Err.\n" + }, + "args": [ + [ + "int", + "addr", + null + ], + [ + "int", + "mem_addr", + null + ], + [ + "const Bytes &", + "data", + null + ], + [ + "int", + "mem_addr_size", + "8" + ], + [ + "bool", + "mem_addr_le", + "false" + ] + ], + "ret_type": "int", + "static": false, + "def": "int writeto_mem(int addr, int mem_addr, const Bytes &data, int mem_addr_size = 8, bool mem_addr_le = false)" + }, + { + "type": "func", + "name": "writeto_mem", + "doc": { + "brief": "write data to i2c slave's memory address", + "param": { + "addr": "direction [in], i2c slave address, int type", + "mem_addr": "direction [in], memory address want to write, int type.", + "data": "direction [in], data to write, uint8_t type.", + "len": "direction [in], data length to write, int type", + "mem_addr_size": "direction [in], memory address size, default is 8.", + "mem_addr_le": "direction [in], memory address little endian, default is false, that is send high byte first." + }, + "return": "data length written if success, error occurred will return -err::Err.", + "maixcdk": "maix.peripheral.i2c.I2C.writeto_mem", + "py_doc": "write data to i2c slave's memory address\n\nArgs:\n - addr: direction [in], i2c slave address, int type\n - mem_addr: direction [in], memory address want to write, int type.\n - data: direction [in], data to write, uint8_t type.\n - len: direction [in], data length to write, int type\n - mem_addr_size: direction [in], memory address size, default is 8.\n - mem_addr_le: direction [in], memory address little endian, default is false, that is send high byte first.\n\n\nReturns: data length written if success, error occurred will return -err::Err.\n" + }, + "args": [ + [ + "int", + "addr", + null + ], + [ + "int", + "mem_addr", + null + ], + [ + "const uint8_t *", + "data", + null + ], + [ + "int", + "len", + null + ], + [ + "int", + "mem_addr_size", + "8" + ], + [ + "bool", + "mem_addr_le", + "false" + ] + ], + "ret_type": "int", + "static": false, + "def": "int writeto_mem(int addr, int mem_addr, const uint8_t *data, int len, int mem_addr_size = 8, bool mem_addr_le = false)" + } + ] + }, + "readfrom_mem": { + "type": "func", + "name": "readfrom_mem", + "doc": { + "brief": "read data from i2c slave", + "param": { + "addr": "direction [in], i2c slave address, int type", + "mem_addr": "direction [in], memory address want to read, int type.", + "len": "direction [in], data length to read, int type", + "mem_addr_size": "direction [in], memory address size, default is 8.", + "mem_addr_le": "direction [in], memory address little endian, default is false, that is send high byte first." + }, + "return": "the list of data read from i2c slave, bytes type, you should delete it after use in C++.\nIf read failed, return nullptr in C++, None in MaixPy.", + "maixpy": "maix.peripheral.i2c.I2C.readfrom_mem", + "py_doc": "read data from i2c slave\n\nArgs:\n - addr: direction [in], i2c slave address, int type\n - mem_addr: direction [in], memory address want to read, int type.\n - len: direction [in], data length to read, int type\n - mem_addr_size: direction [in], memory address size, default is 8.\n - mem_addr_le: direction [in], memory address little endian, default is false, that is send high byte first.\n\n\nReturns: the list of data read from i2c slave, bytes type, you should delete it after use in C++.\nIf read failed, return nullptr in C++, None in MaixPy.\n" + }, + "args": [ + [ + "int", + "addr", + null + ], + [ + "int", + "mem_addr", + null + ], + [ + "int", + "len", + null + ], + [ + "int", + "mem_addr_size", + "8" + ], + [ + "bool", + "mem_addr_le", + "false" + ] + ], + "ret_type": "Bytes*", + "static": false, + "def": "Bytes* readfrom_mem(int addr, int mem_addr, int len, int mem_addr_size = 8, bool mem_addr_le = false)" + } + }, + "def": "class I2C" + } + }, + "auto_add": true + }, + "spi": { + "type": "module", + "doc": { + "brief": "maix.peripheral.spi module" + }, + "members": { + "Mode": { + "type": "enum", + "name": "Mode", + "doc": { + "brief": "SPI mode enum", + "maixpy": "maix.peripheral.spi.Mode", + "py_doc": "SPI mode enum" + }, + "values": [ + [ + "MASTER", + "0x0", + "spi master mode" + ], + [ + "SLAVE", + "0x1", + "spi slave mode" + ] + ], + "def": "enum Mode\n {\n MASTER = 0x0, // spi master mode\n SLAVE = 0x1, // spi slave mode\n }" + }, + "SPI": { + "type": "class", + "name": "SPI", + "doc": { + "brief": "Peripheral spi class", + "maixpy": "maix.peripheral.spi.SPI", + "py_doc": "Peripheral spi class" + }, + "members": { + "__init__": { + "type": "func", + "name": "SPI", + "doc": { + "brief": "SPI constructor", + "param": { + "id": "direction [in], spi bus id, int type", + "mode": "direction [in], mode of spi, spi.Mode type, spi.Mode.MASTER or spi.Mode.SLAVE.", + "freq": "direction [in], freq of spi, int type", + "polarity": "direction [in], polarity of spi, 0 means idle level of clock is low, 1 means high, int type, default is 0.", + "phase": "direction [in], phase of spi, 0 means data is captured on the first edge of the SPI clock cycle, 1 means second, int type, default is 0.", + "bits": "direction [in], bits of spi, int type, default is 8.", + "cs_enable": "direction [in], cs pin active level, default is 0(low)", + "soft_cs": "direction [in], not use hardware cs, bool type, if set true, you can operate cs pin use gpio manually.", + "cs": "direction [in], soft cs pin number, std::string type, default is \"GPIOA19\", if SPI support multi hardware cs, you can set it to other value." + }, + "maixpy": "maix.peripheral.spi.SPI.__init__", + "py_doc": "SPI constructor\n\nArgs:\n - id: direction [in], spi bus id, int type\n - mode: direction [in], mode of spi, spi.Mode type, spi.Mode.MASTER or spi.Mode.SLAVE.\n - freq: direction [in], freq of spi, int type\n - polarity: direction [in], polarity of spi, 0 means idle level of clock is low, 1 means high, int type, default is 0.\n - phase: direction [in], phase of spi, 0 means data is captured on the first edge of the SPI clock cycle, 1 means second, int type, default is 0.\n - bits: direction [in], bits of spi, int type, default is 8.\n - cs_enable: direction [in], cs pin active level, default is 0(low)\n - soft_cs: direction [in], not use hardware cs, bool type, if set true, you can operate cs pin use gpio manually.\n - cs: direction [in], soft cs pin number, std::string type, default is \"GPIOA19\", if SPI support multi hardware cs, you can set it to other value.\n" + }, + "args": [ + [ + "int", + "id", + null + ], + [ + "spi::Mode", + "mode", + null + ], + [ + "int", + "freq", + null + ], + [ + "int", + "polarity", + "0" + ], + [ + "int", + "phase", + "0" + ], + [ + "int", + "bits", + "8" + ], + [ + "unsigned char", + "cs_enable", + "0" + ], + [ + "bool", + "soft_cs", + "false" + ], + [ + "std::string", + "cs", + "\"GPIOA19\"" + ] + ], + "ret_type": null, + "static": false, + "def": "SPI(int id, spi::Mode mode, int freq, int polarity = 0, int phase = 0,\n int bits = 8, unsigned char cs_enable=0, bool soft_cs = false, std::string cs = \"GPIOA19\")" + }, + "read": { + "type": "func", + "name": "read", + "doc": { + "brief": "read data from spi", + "param": { + "length": "direction [in], read length, int type" + }, + "return": "bytes data, Bytes type in C++, bytes type in MaixPy. You need to delete it manually after use in C++.", + "maixpy": "maix.peripheral.spi.SPI.read", + "py_doc": "read data from spi\n\nArgs:\n - length: direction [in], read length, int type\n\n\nReturns: bytes data, Bytes type in C++, bytes type in MaixPy. You need to delete it manually after use in C++.\n" + }, + "args": [ + [ + "int", + "length", + null + ] + ], + "ret_type": "Bytes*", + "static": false, + "def": "Bytes *read(int length)", + "overload": [ + { + "type": "func", + "name": "read", + "doc": { + "brief": "read data from spi", + "param": { + "length": "direction [in], read length, unsigned int type" + }, + "return": "bytes data, vector type", + "maixcdk": "maix.peripheral.spi.SPI.read", + "py_doc": "read data from spi\n\nArgs:\n - length: direction [in], read length, unsigned int type\n\n\nReturns: bytes data, vector type\n" + }, + "args": [ + [ + "unsigned int", + "length", + null + ] + ], + "ret_type": "std::vector", + "static": false, + "def": "std::vector read(unsigned int length)" + } + ] + }, + "write": { + "type": "func", + "name": "write", + "doc": { + "brief": "write data to spi", + "param": { + "data": "direction [in], data to write, vector type\nthe member range of the list is [0,255]" + }, + "return": "write length, int type, if write failed, return -err::Err code.", + "maixcdk": "maix.peripheral.spi.SPI.write", + "py_doc": "write data to spi\n\nArgs:\n - data: direction [in], data to write, vector type\nthe member range of the list is [0,255]\n\n\nReturns: write length, int type, if write failed, return -err::Err code.\n" + }, + "args": [ + [ + "std::vector", + "data", + null + ] + ], + "ret_type": "int", + "static": false, + "def": "int write(std::vector data)", + "overload": [ + { + "type": "func", + "name": "write", + "doc": { + "brief": "write data to spi", + "param": { + "data": "direction [in], data to write, Bytes type in C++, bytes type in MaixPy" + }, + "return": "write length, int type, if write failed, return -err::Err code.", + "maixpy": "maix.peripheral.spi.SPI.write", + "py_doc": "write data to spi\n\nArgs:\n - data: direction [in], data to write, Bytes type in C++, bytes type in MaixPy\n\n\nReturns: write length, int type, if write failed, return -err::Err code.\n" + }, + "args": [ + [ + "Bytes *", + "data", + null + ] + ], + "ret_type": "int", + "static": false, + "def": "int write(Bytes *data)" + } + ] + }, + "write_read": { + "type": "func", + "name": "write_read", + "doc": { + "brief": "write data to spi and read data from spi at the same time.", + "param": { + "data": "direction [in], data to write, vector type.", + "read_len": "direction [in], read length, int type, should > 0." + }, + "return": "read data, vector type", + "maixcdk": "maix.peripheral.spi.SPI.write_read", + "py_doc": "write data to spi and read data from spi at the same time.\n\nArgs:\n - data: direction [in], data to write, vector type.\n - read_len: direction [in], read length, int type, should > 0.\n\n\nReturns: read data, vector type\n" + }, + "args": [ + [ + "std::vector", + "data", + null + ], + [ + "int", + "read_len", + null + ] + ], + "ret_type": "std::vector", + "static": false, + "def": "std::vector write_read(std::vector data, int read_len)", + "overload": [ + { + "type": "func", + "name": "write_read", + "doc": { + "brief": "write data to spi and read data from spi at the same time.", + "param": { + "data": "direction [in], data to write, Bytes type in C++, bytes type in MaixPy", + "read_len": "direction [in], read length, int type, should > 0." + }, + "return": "read data, Bytes type in C++, bytes type in MaixPy. You need to delete it manually after use in C++.", + "maixpy": "maix.peripheral.spi.SPI.write_read", + "py_doc": "write data to spi and read data from spi at the same time.\n\nArgs:\n - data: direction [in], data to write, Bytes type in C++, bytes type in MaixPy\n - read_len: direction [in], read length, int type, should > 0.\n\n\nReturns: read data, Bytes type in C++, bytes type in MaixPy. You need to delete it manually after use in C++.\n" + }, + "args": [ + [ + "Bytes *", + "data", + null + ], + [ + "int", + "read_len", + null + ] + ], + "ret_type": "Bytes*", + "static": false, + "def": "Bytes *write_read(Bytes *data, int read_len)" + } + ] + }, + "is_busy": { + "type": "func", + "name": "is_busy", + "doc": { + "brief": "get busy status of spi", + "return": "busy status, bool type", + "maixpy": "maix.peripheral.spi.SPI.is_busy", + "py_doc": "get busy status of spi\n\nReturns: busy status, bool type\n" + }, + "args": [], + "ret_type": "bool", + "static": false, + "def": "bool is_busy()" + } + }, + "def": "class SPI" + } + }, + "auto_add": true + }, + "pwm": { + "type": "module", + "doc": { + "brief": "maix.peripheral.pwm module" + }, + "members": { + "PWM": { + "type": "class", + "name": "PWM", + "doc": { + "brief": "Peripheral pwm class", + "maixpy": "maix.peripheral.pwm.PWM", + "py_doc": "Peripheral pwm class" + }, + "members": { + "__init__": { + "type": "func", + "name": "PWM", + "doc": { + "brief": "PWM constructor", + "param": { + "pin": "direction [in], pwm id, int type, like 0, 1, 2 etc.", + "freq": "direction [in], pwm frequency, unit: Hz. int type. default is 1000", + "duty": "direction [in], pwm duty. double type. range is [0, 100], default is 0.", + "enable": "direction [in], enable pwm output right now. bool type. default is true, if false, you need to call enable() to enable pwm output.", + "duty_val": "direction [in], pwm duty value, int type. default -1 means not set and auto calculate by freq and duty.\nThis arg directly set pwm duty value, if set, will ignore duty arg.\nduty_val = duty / 100 * T_ns, T_ns = 1 / freq * 1000000000." + }, + "throw": "If args error or init pwm failed, will throw err::Exception", + "maixpy": "maix.peripheral.pwm.PWM.__init__", + "py_doc": "PWM constructor\n\nArgs:\n - pin: direction [in], pwm id, int type, like 0, 1, 2 etc.\n - freq: direction [in], pwm frequency, unit: Hz. int type. default is 1000\n - duty: direction [in], pwm duty. double type. range is [0, 100], default is 0.\n - enable: direction [in], enable pwm output right now. bool type. default is true, if false, you need to call enable() to enable pwm output.\n - duty_val: direction [in], pwm duty value, int type. default -1 means not set and auto calculate by freq and duty.\nThis arg directly set pwm duty value, if set, will ignore duty arg.\nduty_val = duty / 100 * T_ns, T_ns = 1 / freq * 1000000000.\n" + }, + "args": [ + [ + "int", + "id", + null + ], + [ + "int", + "freq", + "1000" + ], + [ + "double", + "duty", + "0" + ], + [ + "bool", + "enable", + "true" + ], + [ + "int", + "duty_val", + "-1" + ] + ], + "ret_type": null, + "static": false, + "def": "PWM(int id, int freq = 1000, double duty = 0, bool enable = true, int duty_val = -1)" + }, + "duty": { + "type": "func", + "name": "duty", + "doc": { + "brief": "get or set pwm duty", + "param": { + "duty": "direction [in], pwm duty, double type, value in [0, 100], default -1 means only read." + }, + "return": "current duty, float type, if set and set failed will return -err::Err", + "maixpy": "maix.peripheral.pwm.PWM.duty", + "py_doc": "get or set pwm duty\n\nArgs:\n - duty: direction [in], pwm duty, double type, value in [0, 100], default -1 means only read.\n\n\nReturns: current duty, float type, if set and set failed will return -err::Err\n" + }, + "args": [ + [ + "double", + "duty", + "-1" + ] + ], + "ret_type": "double", + "static": false, + "def": "double duty(double duty = -1)" + }, + "duty_val": { + "type": "func", + "name": "duty_val", + "doc": { + "brief": "set pwm duty value", + "param": { + "duty_val": "direction [in], pwm duty value. int type. default is -1\nduty_val > 0 means set duty_val\nduty_val == -1 or not set, return current duty_val" + }, + "return": "int type\nwhen get duty_val, return current duty_val, else return -err::Err code.", + "maixpy": "maix.peripheral.pwm.PWM.duty_val", + "py_doc": "set pwm duty value\n\nArgs:\n - duty_val: direction [in], pwm duty value. int type. default is -1\nduty_val > 0 means set duty_val\nduty_val == -1 or not set, return current duty_val\n\n\nReturns: int type\nwhen get duty_val, return current duty_val, else return -err::Err code.\n" + }, + "args": [ + [ + "int", + "duty_val", + "-1" + ] + ], + "ret_type": "int", + "static": false, + "def": "int duty_val(int duty_val = -1)" + }, + "freq": { + "type": "func", + "name": "freq", + "doc": { + "brief": "get or set pwm frequency", + "param": { + "freq": "direction [in], pwm frequency. int type. default is -1\nfreq >= 0, set freq\nfreq == -1 or not set, return current freq" + }, + "return": "int type, current freq, if set and set failed will return -err::Err", + "maixpy": "maix.peripheral.pwm.PWM.freq", + "py_doc": "get or set pwm frequency\n\nArgs:\n - freq: direction [in], pwm frequency. int type. default is -1\nfreq >= 0, set freq\nfreq == -1 or not set, return current freq\n\n\nReturns: int type, current freq, if set and set failed will return -err::Err\n" + }, + "args": [ + [ + "int", + "freq", + "-1" + ] + ], + "ret_type": "int", + "static": false, + "def": "int freq(int freq = -1)" + }, + "enable": { + "type": "func", + "name": "enable", + "doc": { + "brief": "set pwm enable", + "return": "err::Err type, err.Err.ERR_NONE means success", + "maixpy": "maix.peripheral.pwm.PWM.enable", + "py_doc": "set pwm enable\n\nReturns: err::Err type, err.Err.ERR_NONE means success\n" + }, + "args": [], + "ret_type": "err::Err", + "static": false, + "def": "err::Err enable()" + }, + "disable": { + "type": "func", + "name": "disable", + "doc": { + "brief": "set pwm disable", + "return": "err::Err type, err.Err.ERR_NONE means success", + "maixpy": "maix.peripheral.pwm.PWM.disable", + "py_doc": "set pwm disable\n\nReturns: err::Err type, err.Err.ERR_NONE means success\n" + }, + "args": [], + "ret_type": "err::Err", + "static": false, + "def": "err::Err disable()" + }, + "is_enabled": { + "type": "func", + "name": "is_enabled", + "doc": { + "brief": "get pwm enable status", + "return": "bool type, true means enable, false means disable", + "maixpy": "maix.peripheral.pwm.PWM.is_enabled", + "py_doc": "get pwm enable status\n\nReturns: bool type, true means enable, false means disable\n" + }, + "args": [], + "ret_type": "bool", + "static": false, + "def": "bool is_enabled()" + } + }, + "def": "class PWM" + } + }, + "auto_add": true + }, + "wdt": { + "type": "module", + "doc": { + "brief": "maix.peripheral.wdt module" + }, + "members": { + "WDT": { + "type": "class", + "name": "WDT", + "doc": { + "brief": "Peripheral wdt class", + "maixpy": "maix.peripheral.wdt.WDT", + "py_doc": "Peripheral wdt class" + }, + "members": { + "__init__": { + "type": "func", + "name": "WDT", + "doc": { + "brief": "WDT constructor, after construct, the wdt will auto start.", + "param": { + "id": "direction [in], id of wdt, int type", + "feed_ms": "direction [in], feed interval, int type, unit is ms, you must feed wdt in this interval, or system will restart." + }, + "maixpy": "maix.peripheral.wdt.WDT.__init__", + "py_doc": "WDT constructor, after construct, the wdt will auto start.\n\nArgs:\n - id: direction [in], id of wdt, int type\n - feed_ms: direction [in], feed interval, int type, unit is ms, you must feed wdt in this interval, or system will restart.\n" + }, + "args": [ + [ + "int", + "id", + null + ], + [ + "int", + "feed_ms", + null + ] + ], + "ret_type": null, + "static": false, + "def": "WDT(int id, int feed_ms)" + }, + "feed": { + "type": "func", + "name": "feed", + "doc": { + "brief": "feed wdt", + "return": "error code, if feed success, return err::ERR_NONE", + "maixpy": "maix.peripheral.wdt.WDT.feed", + "py_doc": "feed wdt\n\nReturns: error code, if feed success, return err::ERR_NONE\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int feed()" + }, + "stop": { + "type": "func", + "name": "stop", + "doc": { + "brief": "stop wdt", + "maixpy": "maix.peripheral.wdt.WDT.stop", + "py_doc": "stop wdt" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int stop()" + }, + "restart": { + "type": "func", + "name": "restart", + "doc": { + "brief": "restart wdt, stop and start watchdog timer.", + "maixpy": "maix.peripheral.wdt.WDT.restart", + "py_doc": "restart wdt, stop and start watchdog timer." + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int restart()" + } + }, + "def": "class WDT" + } + }, + "auto_add": true + }, + "adc": { + "type": "module", + "doc": { + "brief": "maix.peripheral.adc module" + }, + "members": { + "RES_BIT_8": { + "type": "var", + "name": "", + "doc": { + "brief": "8-bit resolution, supported by the actual hardware", + "maixpy": "maix.peripheral.adc.RES_BIT_8", + "py_doc": "8-bit resolution, supported by the actual hardware" + }, + "value": "8", + "static": false, + "readonly": true, + "def": "const int RES_BIT_8 = 8" + }, + "RES_BIT_10": { + "type": "var", + "name": "", + "doc": { + "brief": "10-bit resolution, supported by the actual hardware", + "maixpy": "maix.peripheral.adc.RES_BIT_10", + "py_doc": "10-bit resolution, supported by the actual hardware" + }, + "value": "10", + "static": false, + "readonly": true, + "def": "const int RES_BIT_10 = 10" + }, + "RES_BIT_12": { + "type": "var", + "name": "", + "doc": { + "brief": "12-bit resolution, supported by the actual hardware", + "maixpy": "maix.peripheral.adc.RES_BIT_12", + "py_doc": "12-bit resolution, supported by the actual hardware" + }, + "value": "12", + "static": false, + "readonly": true, + "def": "const int RES_BIT_12 = 12" + }, + "RES_BIT_16": { + "type": "var", + "name": "", + "doc": { + "brief": "16-bit resolution, supported by the actual hardware", + "maixpy": "maix.peripheral.adc.RES_BIT_16", + "py_doc": "16-bit resolution, supported by the actual hardware" + }, + "value": "16", + "static": false, + "readonly": true, + "def": "const int RES_BIT_16 = 16" + }, + "ADC": { + "type": "class", + "name": "ADC", + "doc": { + "brief": "Peripheral adc class", + "maixpy": "maix.peripheral.adc.ADC", + "py_doc": "Peripheral adc class" + }, + "members": { + "__init__": { + "type": "func", + "name": "ADC", + "doc": { + "brief": "ADC constructor", + "param": { + "pin": "direction [in], adc pin, int type", + "resolution": "direction [in], adc resolution. default is -1, means use default resolution\noption:\nresolution = adc.RES_BIT_8, means 8-bit resolution\nresolution = adc.RES_BIT_10, means 10-bit resolution\nresolution = adc.RES_BIT_12, means 12-bit resolution\nresolution = adc.RES_BIT_16, means 16-bit resolution\nthe default resolution is determined by actual hardware.", + "vref": "direction [in], adc refer voltage. default is -1, means use default refer voltage.\nthe default vref is determined by actual hardware. range: [0.0, 10.0]" + }, + "maixpy": "maix.peripheral.adc.ADC.__init__", + "py_doc": "ADC constructor\n\nArgs:\n - pin: direction [in], adc pin, int type\n - resolution: direction [in], adc resolution. default is -1, means use default resolution\noption:\nresolution = adc.RES_BIT_8, means 8-bit resolution\nresolution = adc.RES_BIT_10, means 10-bit resolution\nresolution = adc.RES_BIT_12, means 12-bit resolution\nresolution = adc.RES_BIT_16, means 16-bit resolution\nthe default resolution is determined by actual hardware.\n - vref: direction [in], adc refer voltage. default is -1, means use default refer voltage.\nthe default vref is determined by actual hardware. range: [0.0, 10.0]\n" + }, + "args": [ + [ + "int", + "pin", + null + ], + [ + "int", + "resolution", + null + ], + [ + "float", + "vref", + "-1" + ] + ], + "ret_type": null, + "static": false, + "def": "ADC(int pin, int resolution, float vref = -1)" + }, + "read": { + "type": "func", + "name": "read", + "doc": { + "brief": "read adc value", + "return": "adc data, int type\nif resolution is 8-bit, return value range is [0, 255]\nif resolution is 10-bit, return value range is [0, 1023]\nif resolution is 12-bit, return value range is [0, 4095]\nif resolution is 16-bit, return value range is [0, 65535]", + "maixpy": "maix.peripheral.adc.ADC.read", + "py_doc": "read adc value\n\nReturns: adc data, int type\nif resolution is 8-bit, return value range is [0, 255]\nif resolution is 10-bit, return value range is [0, 1023]\nif resolution is 12-bit, return value range is [0, 4095]\nif resolution is 16-bit, return value range is [0, 65535]\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int read()" + }, + "read_vol": { + "type": "func", + "name": "read_vol", + "doc": { + "brief": "read adc voltage", + "return": "adc voltage, float type\u3002the range is [0.0, vref]", + "maixpy": "maix.peripheral.adc.ADC.read_vol", + "py_doc": "read adc voltage\n\nReturns: adc voltage, float type\u3002the range is [0.0, vref]\n" + }, + "args": [], + "ret_type": "float", + "static": false, + "def": "float read_vol()" + } + }, + "def": "class ADC" + } + }, + "auto_add": true + }, + "pinmap": { + "type": "module", + "doc": { + "brief": "maix.peripheral.pinmap module" + }, + "members": { + "get_pins": { + "type": "func", + "name": "get_pins", + "doc": { + "brief": "Get all pins of devices", + "return": "pin name list, string type.", + "maixpy": "maix.peripheral.pinmap.get_pins", + "py_doc": "Get all pins of devices\n\nReturns: pin name list, string type.\n" + }, + "args": [], + "ret_type": "std::vector", + "static": false, + "def": "std::vector get_pins()" + }, + "get_pin_functions": { + "type": "func", + "name": "get_pin_functions", + "doc": { + "brief": "Get all function of a pin", + "param": { + "pin": "pin name, string type." + }, + "return": "function list, function name is string type.", + "throw": "If pin name error will throwout err.Err.ERR_ARGS error.", + "maixpy": "maix.peripheral.pinmap.get_pin_functions", + "py_doc": "Get all function of a pin\n\nArgs:\n - pin: pin name, string type.\n\n\nReturns: function list, function name is string type.\n" + }, + "args": [ + [ + "const std::string &", + "pin", + null + ] + ], + "ret_type": "std::vector", + "static": false, + "def": "std::vector get_pin_functions(const std::string &pin)" + }, + "set_pin_function": { + "type": "func", + "name": "set_pin_function", + "doc": { + "brief": "Set function of a pin", + "param": { + "pin": "pin name, string type.", + "func": "which function should this pin use." + }, + "return": "if set ok, will return err.Err.ERR_NONE, else error occurs.", + "maixpy": "maix.peripheral.pinmap.set_pin_function", + "py_doc": "Set function of a pin\n\nArgs:\n - pin: pin name, string type.\n - func: which function should this pin use.\n\n\nReturns: if set ok, will return err.Err.ERR_NONE, else error occurs.\n" + }, + "args": [ + [ + "const std::string &", + "pin", + null + ], + [ + "const std::string &", + "func", + null + ] + ], + "ret_type": "err::Err", + "static": false, + "def": "err::Err set_pin_function(const std::string &pin, const std::string &func)" + } + }, + "auto_add": true + }, + "uart": { + "type": "module", + "doc": { + "brief": "maix uart peripheral driver", + "maixpy": "maix.peripheral.uart", + "py_doc": "maix uart peripheral driver" + }, + "members": { + "PARITY": { + "type": "enum", + "name": "PARITY", + "doc": { + "brief": "uart parity enum", + "maixpy": "maix.peripheral.uart.PARITY", + "py_doc": "uart parity enum" + }, + "values": [ + [ + "PARITY_NONE", + "0x00", + "no parity" + ], + [ + "PARITY_ODD", + "0x01", + "odd parity" + ], + [ + "PARITY_EVEN", + "0x02", + "even parity" + ], + [ + "PARITY_MAX", + "", + "" + ] + ], + "def": "enum PARITY\n {\n PARITY_NONE = 0x00, // no parity\n PARITY_ODD = 0x01, // odd parity\n PARITY_EVEN = 0x02, // even parity\n PARITY_MAX\n }" + }, + "STOP": { + "type": "enum", + "name": "STOP", + "doc": { + "brief": "uart stop bits", + "maixpy": "maix.peripheral.uart.STOP", + "py_doc": "uart stop bits" + }, + "values": [ + [ + "STOP_1", + "0x01", + "1 stop bit" + ], + [ + "STOP_2", + "0x02", + "2 stop bits" + ], + [ + "STOP_1_5", + "0x03", + "1.5 stop bits" + ], + [ + "STOP_MAX", + "", + "" + ] + ], + "def": "enum STOP\n {\n STOP_1 = 0x01, // 1 stop bit\n STOP_2 = 0x02, // 2 stop bits\n STOP_1_5 = 0x03, // 1.5 stop bits\n STOP_MAX\n }" + }, + "BITS": { + "type": "enum", + "name": "BITS", + "doc": { + "brief": "uart stop bits", + "maixpy": "maix.peripheral.uart.BITS", + "py_doc": "uart stop bits" + }, + "values": [ + [ + "BITS_5", + "5", + "5 data bits" + ], + [ + "BITS_6", + "6", + "6 data bits" + ], + [ + "BITS_7", + "7", + "7 data bits" + ], + [ + "BITS_8", + "8", + "8 data bits" + ], + [ + "BITS_MAX", + "", + "" + ] + ], + "def": "enum BITS\n {\n BITS_5 = 5, // 5 data bits\n BITS_6 = 6, // 6 data bits\n BITS_7 = 7, // 7 data bits\n BITS_8 = 8, // 8 data bits\n BITS_MAX\n }" + }, + "FLOW_CTRL": { + "type": "enum", + "name": "FLOW_CTRL", + "doc": { + "brief": "uart flow control", + "maixpy": "maix.peripheral.uart.FLOW_CTRL", + "py_doc": "uart flow control" + }, + "values": [ + [ + "FLOW_CTRL_NONE", + "0", + "no flow control" + ], + [ + "FLOW_CTRL_HW", + "1", + "hardware flow control" + ], + [ + "FLOW_CTRL_MAX", + "", + "" + ] + ], + "def": "enum FLOW_CTRL\n {\n FLOW_CTRL_NONE = 0, // no flow control\n FLOW_CTRL_HW = 1, // hardware flow control\n FLOW_CTRL_MAX\n }" + }, + "list_devices": { + "type": "func", + "name": "list_devices", + "doc": { + "brief": "Get supported uart ports.", + "return": "uart ports list, string type.", + "maixpy": "maix.peripheral.uart.list_devices", + "py_doc": "Get supported uart ports.\n\nReturns: uart ports list, string type.\n" + }, + "args": [], + "ret_type": "std::vector", + "static": false, + "def": "std::vector list_devices()" + }, + "UART": { + "type": "class", + "name": "UART", + "doc": { + "brief": "maix uart peripheral driver", + "maixpy": "maix.peripheral.uart.UART", + "py_doc": "maix uart peripheral driver" + }, + "members": { + "__init__": { + "type": "func", + "name": "UART", + "doc": { + "brief": "UART constructor. You need to call open() to open the device.", + "param": { + "port": "uart port. string type, can get it by uart.list_devices().\nIf empty, will not open device in constructor, default empty.\nif not empty, will auto open device in constructor, open fail will throw err.Exception.", + "baudrate": "baudrate of uart. int type, default 115200.", + "databits": "databits, values @see uart.DATA_BITS", + "parity": "parity, values @see uart.PARITY", + "stopbits": "stopbits, values @see uart.STOP_BITS", + "flow_control": "flow_control, values @see uart.FLOW_CTRL" + }, + "maixpy": "maix.peripheral.uart.UART.__init__", + "py_doc": "UART constructor. You need to call open() to open the device.\n\nArgs:\n - port: uart port. string type, can get it by uart.list_devices().\nIf empty, will not open device in constructor, default empty.\nif not empty, will auto open device in constructor, open fail will throw err.Exception.\n - baudrate: baudrate of uart. int type, default 115200.\n - databits: databits, values @see uart.DATA_BITS\n - parity: parity, values @see uart.PARITY\n - stopbits: stopbits, values @see uart.STOP_BITS\n - flow_control: flow_control, values @see uart.FLOW_CTRL\n" + }, + "args": [ + [ + "const std::string &", + "port", + "\"\"" + ], + [ + "int", + "baudrate", + "115200" + ], + [ + "uart::BITS", + "databits", + "uart::BITS_8" + ], + [ + "uart::PARITY", + "parity", + "uart::PARITY_NONE" + ], + [ + "uart::STOP", + "stopbits", + "uart::STOP_1" + ], + [ + "uart::FLOW_CTRL", + "flow_ctrl", + "uart::FLOW_CTRL_NONE" + ] + ], + "ret_type": null, + "static": false, + "def": "UART(const std::string &port = \"\", int baudrate = 115200, uart::BITS databits = uart::BITS_8,\n uart::PARITY parity = uart::PARITY_NONE, uart::STOP stopbits = uart::STOP_1,\n uart::FLOW_CTRL flow_ctrl = uart::FLOW_CTRL_NONE)" + }, + "set_port": { + "type": "func", + "name": "set_port", + "doc": { + "brief": "Set port", + "param": { + "port": "uart port. string type, can get it by uart.list_devices()." + }, + "return": "set port error code, err.Err type.", + "maixpy": "maix.peripheral.uart.UART.set_port", + "py_doc": "Set port\n\nArgs:\n - port: uart port. string type, can get it by uart.list_devices().\n\n\nReturns: set port error code, err.Err type.\n" + }, + "args": [ + [ + "const std::string &", + "port", + null + ] + ], + "ret_type": "err::Err", + "static": false, + "def": "err::Err set_port(const std::string &port)" + }, + "get_port": { + "type": "func", + "name": "get_port", + "doc": { + "brief": "Get port", + "return": "uart port, string type.", + "maixpy": "maix.peripheral.uart.UART.get_port", + "py_doc": "Get port\n\nReturns: uart port, string type.\n" + }, + "args": [], + "ret_type": "std::string", + "static": false, + "def": "std::string get_port()" + }, + "set_baudrate": { + "type": "func", + "name": "set_baudrate", + "doc": { + "brief": "Set baud rate", + "param": { + "baudrate": "baudrate of uart. int type, default 115200." + }, + "return": "set baud rate error code, err.Err type.", + "maixpy": "maix.peripheral.uart.UART.set_baudrate", + "py_doc": "Set baud rate\n\nArgs:\n - baudrate: baudrate of uart. int type, default 115200.\n\n\nReturns: set baud rate error code, err.Err type.\n" + }, + "args": [ + [ + "int", + "baudrate", + null + ] + ], + "ret_type": "err::Err", + "static": false, + "def": "err::Err set_baudrate(int baudrate)" + }, + "get_baudrate": { + "type": "func", + "name": "get_baudrate", + "doc": { + "brief": "Get baud rate", + "return": "baud rate, int type.", + "maixpy": "maix.peripheral.uart.UART.get_baudrate", + "py_doc": "Get baud rate\n\nReturns: baud rate, int type.\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int get_baudrate()" + }, + "open": { + "type": "func", + "name": "open", + "doc": { + "brief": "Open uart device, before open, port must be set in constructor or by set_port().\\nIf already opened, do nothing and return err.ERR_NONE.", + "return": "open device error code, err.Err type.", + "maixpy": "maix.peripheral.uart.UART.open", + "py_doc": "Open uart device, before open, port must be set in constructor or by set_port().\nIf already opened, do nothing and return err.ERR_NONE.\n\nReturns: open device error code, err.Err type.\n" + }, + "args": [], + "ret_type": "err::Err", + "static": false, + "def": "err::Err open()" + }, + "is_open": { + "type": "func", + "name": "is_open", + "doc": { + "brief": "Check if device is opened.", + "return": "true if opened, false if not opened.", + "maixpy": "maix.peripheral.uart.UART.is_open", + "py_doc": "Check if device is opened.\n\nReturns: true if opened, false if not opened.\n" + }, + "args": [], + "ret_type": "bool", + "static": false, + "def": "bool is_open()" + }, + "close": { + "type": "func", + "name": "close", + "doc": { + "brief": "Close uart device, if already closed, do nothing and return err.ERR_NONE.", + "return": "close device error code, err.Err type.", + "maixpy": "maix.peripheral.uart.UART.close", + "py_doc": "Close uart device, if already closed, do nothing and return err.ERR_NONE.\n\nReturns: close device error code, err.Err type.\n" + }, + "args": [], + "ret_type": "err::Err", + "static": false, + "def": "err::Err close()" + }, + "set_received_callback": { + "type": "func", + "name": "set_received_callback", + "doc": { + "brief": "Set received callback function", + "param": { + "callback": "function to call when received data" + }, + "maixpy": "maix.peripheral.uart.UART.set_received_callback", + "py_doc": "Set received callback function\n\nArgs:\n - callback: function to call when received data\n" + }, + "args": [ + [ + "std::function", + "callback", + null + ] + ], + "ret_type": "void", + "static": false, + "def": "void set_received_callback(std::function callback)" + }, + "write": { + "type": "func", + "name": "write", + "doc": { + "brief": "Send data to device", + "param": { + "buff": "data buffer", + "len": "data length need to send" + }, + "return": "sent data length, < 0 means error, value is -err.Err.", + "maixcdk": "maix.peripheral.uart.UART.write", + "py_doc": "Send data to device\n\nArgs:\n - buff: data buffer\n - len: data length need to send\n\n\nReturns: sent data length, < 0 means error, value is -err.Err.\n" + }, + "args": [ + [ + "const uint8_t *", + "buff", + null + ], + [ + "int", + "len", + null + ] + ], + "ret_type": "int", + "static": false, + "def": "int write(const uint8_t *buff, int len)", + "overload": [ + { + "type": "func", + "name": "write", + "doc": { + "brief": "Send data to device", + "param": { + "buff": "data buffer", + "len": "data length need to send, if len == -1, means buff is a string, send buff until '\\0'." + }, + "return": "sent data length, < 0 means error, value is -err.Err.", + "maixcdk": "maix.peripheral.uart.UART.write", + "py_doc": "Send data to device\n\nArgs:\n - buff: data buffer\n - len: data length need to send, if len == -1, means buff is a string, send buff until '\\0'.\n\n\nReturns: sent data length, < 0 means error, value is -err.Err.\n" + }, + "args": [ + [ + "const char *", + "buff", + null + ], + [ + "int", + "len", + "-1" + ] + ], + "ret_type": "int", + "static": false, + "def": "int write(const char *buff, int len = -1)" + }, + { + "type": "func", + "name": "write", + "doc": { + "brief": "Send string data", + "param": { + "str": "string data" + }, + "return": "sent data length, < 0 means error, value is -err.Err.", + "maixcdk": "maix.peripheral.uart.UART.write", + "py_doc": "Send string data\n\nArgs:\n - str: string data\n\n\nReturns: sent data length, < 0 means error, value is -err.Err.\n" + }, + "args": [ + [ + "const std::string &", + "str", + null + ] + ], + "ret_type": "int", + "static": false, + "def": "int write(const std::string &str)" + }, + { + "type": "func", + "name": "write", + "doc": { + "brief": "Send data to uart", + "param": { + "data": "direction [in], data to send, bytes type. If you want to send str type, use str.encode() to convert." + }, + "return": "sent length, int type, if < 0 means error, value is -err.Err.", + "maixpy": "maix.peripheral.uart.UART.write", + "py_doc": "Send data to uart\n\nArgs:\n - data: direction [in], data to send, bytes type. If you want to send str type, use str.encode() to convert.\n\n\nReturns: sent length, int type, if < 0 means error, value is -err.Err.\n" + }, + "args": [ + [ + "Bytes &", + "data", + null + ] + ], + "ret_type": "int", + "static": false, + "def": "int write(Bytes &data)" + } + ] + }, + "write_str": { + "type": "func", + "name": "write_str", + "doc": { + "brief": "Send string data", + "param": { + "str": "string data" + }, + "return": "sent data length, < 0 means error, value is -err.Err.", + "maixpy": "maix.peripheral.uart.UART.write_str", + "py_doc": "Send string data\n\nArgs:\n - str: string data\n\n\nReturns: sent data length, < 0 means error, value is -err.Err.\n" + }, + "args": [ + [ + "const std::string &", + "str", + null + ] + ], + "ret_type": "int", + "static": false, + "def": "int write_str(const std::string &str)" + }, + "available": { + "type": "func", + "name": "available", + "doc": { + "brief": "Check if data available or wait data available.", + "param": { + "timeout": "unit ms, timeout to wait data, default 0.\n0 means check data available and return immediately,\n> 0 means wait until data available or timeout.\n- 1 means wait until data available." + }, + "return": "available data number, 0 if timeout or no data, <0 if error, value is -err.Err, can be err::ERR_IO\uff0c err::ERR_CANCEL, err::ERR_NOT_OPEN.", + "throw": "err.Exception if fatal error.", + "maixpy": "maix.peripheral.uart.UART.available", + "py_doc": "Check if data available or wait data available.\n\nArgs:\n - timeout: unit ms, timeout to wait data, default 0.\n0 means check data available and return immediately,\n> 0 means wait until data available or timeout.\n- 1 means wait until data available.\n\n\nReturns: available data number, 0 if timeout or no data, <0 if error, value is -err.Err, can be err::ERR_IO\uff0c err::ERR_CANCEL, err::ERR_NOT_OPEN.\n" + }, + "args": [ + [ + "int", + "timeout", + "0" + ] + ], + "ret_type": "int", + "static": false, + "def": "int available(int timeout = 0)" + }, + "read": { + "type": "func", + "name": "read", + "doc": { + "brief": "Receive data", + "param": { + "buff": "data buffer to store received data", + "buff_len": "data buffer length", + "recv_len": "max data length want to receive, default -1.\n-1 means read data in uart receive buffer.\n>0 means read recv_len data want to receive.\nother values is invalid.", + "timeout": "unit ms, timeout to receive data, default 0.\n0 means read data in uart receive buffer and return immediately,\n-1 means block until read recv_len data,\n>0 means block until read recv_len data or timeout." + }, + "return": "received data length, < 0 means error, value is -err.Err.", + "maixcdk": "maix.peripheral.uart.UART.read", + "py_doc": "Receive data\n\nArgs:\n - buff: data buffer to store received data\n - buff_len: data buffer length\n - recv_len: max data length want to receive, default -1.\n-1 means read data in uart receive buffer.\n>0 means read recv_len data want to receive.\nother values is invalid.\n - timeout: unit ms, timeout to receive data, default 0.\n0 means read data in uart receive buffer and return immediately,\n-1 means block until read recv_len data,\n>0 means block until read recv_len data or timeout.\n\n\nReturns: received data length, < 0 means error, value is -err.Err.\n" + }, + "args": [ + [ + "uint8_t *", + "buff", + null + ], + [ + "int", + "buff_len", + null + ], + [ + "int", + "recv_len", + "-1" + ], + [ + "int", + "timeout", + "0" + ] + ], + "ret_type": "int", + "static": false, + "def": "int read(uint8_t *buff, int buff_len, int recv_len = -1, int timeout = 0)", + "overload": [ + { + "type": "func", + "name": "read", + "doc": { + "brief": "Recv data from uart", + "param": { + "len": "max data length want to receive, default -1.\n-1 means read data in uart receive buffer.\n>0 means read len data want to receive.\nother values is invalid.", + "timeout": "unit ms, timeout to receive data, default 0.\n0 means read data in uart receive buffer and return immediately,\n-1 means block until read len data,\n>0 means block until read len data or timeout." + }, + "return": "received data, bytes type.\nAttention, you need to delete the returned object yourself in C++.", + "throw": "Read failed will raise err.Exception error.", + "maixpy": "maix.peripheral.uart.UART.read", + "py_doc": "Recv data from uart\n\nArgs:\n - len: max data length want to receive, default -1.\n-1 means read data in uart receive buffer.\n>0 means read len data want to receive.\nother values is invalid.\n - timeout: unit ms, timeout to receive data, default 0.\n0 means read data in uart receive buffer and return immediately,\n-1 means block until read len data,\n>0 means block until read len data or timeout.\n\n\nReturns: received data, bytes type.\nAttention, you need to delete the returned object yourself in C++.\n" + }, + "args": [ + [ + "int", + "len", + "-1" + ], + [ + "int", + "timeout", + "0" + ] + ], + "ret_type": "Bytes*", + "static": false, + "def": "Bytes *read(int len = -1, int timeout = 0)" + } + ] + }, + "readline": { + "type": "func", + "name": "readline", + "doc": { + "brief": "Read line from uart, that is read until '\\n' or '\\r\\n'.", + "param": { + "timeout": "unit ms, timeout to receive data, default -1 means block until read '\\n' or '\\r\\n'.\n> 0 means block until read '\\n' or '\\r\\n' or timeout." + }, + "return": "received data, bytes type. If timeout will return the current received data despite not read '\\n' or '\\r\\n'.\ne.g. If we want to read b'123\\n', but when we only read b'12', timeout, then return b'12'.", + "maixpy": "maix.peripheral.uart.UART.readline", + "py_doc": "Read line from uart, that is read until '\\n' or '\\r\\n'.\n\nArgs:\n - timeout: unit ms, timeout to receive data, default -1 means block until read '\\n' or '\\r\\n'.\n> 0 means block until read '\\n' or '\\r\\n' or timeout.\n\n\nReturns: received data, bytes type. If timeout will return the current received data despite not read '\\n' or '\\r\\n'.\ne.g. If we want to read b'123\\n', but when we only read b'12', timeout, then return b'12'.\n" + }, + "args": [ + [ + "int", + "timeout", + "-1" + ] + ], + "ret_type": "Bytes*", + "static": false, + "def": "Bytes *readline(int timeout = -1)" + } + }, + "def": "class UART : public comm::CommBase" + } + }, + "auto_add": false + }, + "gpio": { + "type": "module", + "doc": { + "brief": "maix.peripheral.gpio module" + }, + "members": { + "Mode": { + "type": "enum", + "name": "Mode", + "doc": { + "brief": "GPIO mode", + "maixpy": "maix.peripheral.gpio.Mode", + "py_doc": "GPIO mode" + }, + "values": [ + [ + "IN", + "0x01", + "input mode" + ], + [ + "OUT", + "0x02", + "output mode" + ], + [ + "OUT_OD", + "0x03", + "output open drain mode" + ], + [ + "MODE_MAX", + "", + "" + ] + ], + "def": "enum Mode\n {\n IN = 0x01, // input mode\n OUT = 0x02, // output mode\n OUT_OD = 0x03, // output open drain mode\n MODE_MAX\n }" + }, + "Pull": { + "type": "enum", + "name": "Pull", + "doc": { + "brief": "GPIO pull mode", + "maixpy": "maix.peripheral.gpio.Pull", + "py_doc": "GPIO pull mode" + }, + "values": [ + [ + "PULL_NONE", + "0x00", + "pull none mode" + ], + [ + "PULL_UP", + "0x01", + "pull up mode" + ], + [ + "PULL_DOWN", + "0x02", + "pull down mode" + ], + [ + "PULL_MAX", + "", + "" + ] + ], + "def": "enum Pull\n {\n PULL_NONE = 0x00, // pull none mode\n PULL_UP = 0x01, // pull up mode\n PULL_DOWN = 0x02, // pull down mode\n PULL_MAX\n }" + }, + "GPIO": { + "type": "class", + "name": "GPIO", + "doc": { + "brief": "Peripheral gpio class", + "maixpy": "maix.peripheral.gpio.GPIO", + "py_doc": "Peripheral gpio class" + }, + "members": { + "__init__": { + "type": "func", + "name": "GPIO", + "doc": { + "brief": "GPIO constructor", + "param": { + "pin": "direction [in], gpio pin name, string type the same as board's pin name, e.g. \"B14\" or \"GPIOB14\", or number string like \"10\" if board no gpiochipe name.", + "mode": "direction [in], gpio mode. gpio.Mode type, default is gpio.Mode.IN (input) mode.", + "pull": "direction [in], gpio pull. gpio.Pull type, default is gpio.Pull.PULL_NONE (pull none) mode.\nFor input mode, this will set gpio default status(value), if set to gpio.Pull.PULL_NONE, gpio value will be floating.\nFor output mode, this will set gpio default status(value), if set to gpio.Pull.PULL_UP, gpio value will be 1, else 0." + }, + "throw": "err::Exception if open gpio device failed.", + "maixpy": "maix.peripheral.gpio.GPIO.__init__", + "py_doc": "GPIO constructor\n\nArgs:\n - pin: direction [in], gpio pin name, string type the same as board's pin name, e.g. \"B14\" or \"GPIOB14\", or number string like \"10\" if board no gpiochipe name.\n - mode: direction [in], gpio mode. gpio.Mode type, default is gpio.Mode.IN (input) mode.\n - pull: direction [in], gpio pull. gpio.Pull type, default is gpio.Pull.PULL_NONE (pull none) mode.\nFor input mode, this will set gpio default status(value), if set to gpio.Pull.PULL_NONE, gpio value will be floating.\nFor output mode, this will set gpio default status(value), if set to gpio.Pull.PULL_UP, gpio value will be 1, else 0.\n" + }, + "args": [ + [ + "std::string", + "pin", + null + ], + [ + "gpio::Mode", + "mode", + "gpio::Mode::IN" + ], + [ + "gpio::Pull", + "pull", + "gpio::Pull::PULL_NONE" + ] + ], + "ret_type": null, + "static": false, + "def": "GPIO(std::string pin, gpio::Mode mode = gpio::Mode::IN, gpio::Pull pull = gpio::Pull::PULL_NONE)" + }, + "value": { + "type": "func", + "name": "value", + "doc": { + "brief": "set and get gpio value", + "param": { + "value": "direction [in], gpio value. int type.\n0, means write gpio to low level\n1, means write gpio to high level\n-1, means read gpio value, not set" + }, + "return": "int type, return gpio value, can be 0 or 1", + "maixpy": "maix.peripheral.gpio.GPIO.value", + "py_doc": "set and get gpio value\n\nArgs:\n - value: direction [in], gpio value. int type.\n0, means write gpio to low level\n1, means write gpio to high level\n-1, means read gpio value, not set\n\n\nReturns: int type, return gpio value, can be 0 or 1\n" + }, + "args": [ + [ + "int", + "value", + "-1" + ] + ], + "ret_type": "int", + "static": false, + "def": "int value(int value = -1)" + }, + "high": { + "type": "func", + "name": "high", + "doc": { + "brief": "set gpio high (value to 1)", + "maixpy": "maix.peripheral.gpio.GPIO.high", + "py_doc": "set gpio high (value to 1)" + }, + "args": [], + "ret_type": "void", + "static": false, + "def": "void high()" + }, + "low": { + "type": "func", + "name": "low", + "doc": { + "brief": "set gpio low (value to 0)", + "maixpy": "maix.peripheral.gpio.GPIO.low", + "py_doc": "set gpio low (value to 0)" + }, + "args": [], + "ret_type": "void", + "static": false, + "def": "void low()" + }, + "toggle": { + "type": "func", + "name": "toggle", + "doc": { + "brief": "gpio toggle", + "maixpy": "maix.peripheral.gpio.GPIO.toggle", + "py_doc": "gpio toggle" + }, + "args": [], + "ret_type": "void", + "static": false, + "def": "void toggle()" + }, + "get_mode": { + "type": "func", + "name": "get_mode", + "doc": { + "brief": "gpio get mode", + "maixpy": "maix.peripheral.gpio.GPIO.get_mode", + "py_doc": "gpio get mode" + }, + "args": [], + "ret_type": "gpio::Mode", + "static": false, + "def": "gpio::Mode get_mode()" + }, + "get_pull": { + "type": "func", + "name": "get_pull", + "doc": { + "brief": "get gpio pull", + "return": "gpio::Pull type", + "maixpy": "maix.peripheral.gpio.GPIO.get_pull", + "py_doc": "get gpio pull\n\nReturns: gpio::Pull type\n" + }, + "args": [], + "ret_type": "gpio::Pull", + "static": false, + "def": "gpio::Pull get_pull()" + }, + "reset": { + "type": "func", + "name": "reset", + "doc": { + "brief": "reset gpio", + "param": { + "mode": "direction [in], gpio mode. gpio.Mode type", + "pull": "direction [in], gpio pull. gpio.Pull type\nFor input mode, this will set gpio default status(value), if set to gpio.Pull.PULL_NONE, gpio value will be floating.\nFor output mode, this will set gpio default status(value), if set to gpio.Pull.PULL_UP, gpio value will be 1, else 0." + }, + "return": "err::Err type", + "maixpy": "maix.peripheral.gpio.GPIO.reset", + "py_doc": "reset gpio\n\nArgs:\n - mode: direction [in], gpio mode. gpio.Mode type\n - pull: direction [in], gpio pull. gpio.Pull type\nFor input mode, this will set gpio default status(value), if set to gpio.Pull.PULL_NONE, gpio value will be floating.\nFor output mode, this will set gpio default status(value), if set to gpio.Pull.PULL_UP, gpio value will be 1, else 0.\n\n\nReturns: err::Err type\n" + }, + "args": [ + [ + "gpio::Mode", + "mode", + null + ], + [ + "gpio::Pull", + "pull", + null + ] + ], + "ret_type": "err::Err", + "static": false, + "def": "err::Err reset(gpio::Mode mode, gpio::Pull pull)" + } + }, + "def": "class GPIO" + } + }, + "auto_add": true + }, + "hid": { + "type": "module", + "doc": { + "brief": "maix.peripheral.hid module" + }, + "members": { + "DeviceType": { + "type": "enum", + "name": "DeviceType", + "doc": { + "brief": "Device enum of hid", + "maixpy": "maix.peripheral.hid.DeviceType", + "py_doc": "Device enum of hid" + }, + "values": [ + [ + "DEVICE_MOUSE", + "0", + "" + ], + [ + "DEVICE_KEYBOARD", + "", + "" + ], + [ + "DEVICE_TOUCHPAD", + "", + "" + ] + ], + "def": "enum DeviceType {\n DEVICE_MOUSE = 0,\n DEVICE_KEYBOARD,\n DEVICE_TOUCHPAD\n }" + }, + "Hid": { + "type": "class", + "name": "Hid", + "doc": { + "brief": "Hid class", + "maixpy": "maix.peripheral.hid.Hid", + "py_doc": "Hid class" + }, + "members": { + "__init__": { + "type": "func", + "name": "Hid", + "doc": { + "brief": "Hid Device constructor", + "param": { + "device_type": "Device type, used to select mouse, keyboard, or touchpad.", + "open": "auto open device in constructor, if false, you need call open() to open device" + }, + "maixpy": "maix.peripheral.hid.Hid.__init__", + "py_doc": "Hid Device constructor\n\nArgs:\n - device_type: Device type, used to select mouse, keyboard, or touchpad.\n - open: auto open device in constructor, if false, you need call open() to open device\n" + }, + "args": [ + [ + "hid::DeviceType", + "device_type", + null + ], + [ + "bool", + "open", + "true" + ] + ], + "ret_type": null, + "static": false, + "def": "Hid(hid::DeviceType device_type, bool open = true)" + }, + "open": { + "type": "func", + "name": "open", + "doc": { + "brief": "Open hid device", + "return": "err::Err", + "maixpy": "maix.peripheral.hid.Hid.open", + "py_doc": "Open hid device\n\nReturns: err::Err\n" + }, + "args": [], + "ret_type": "err::Err", + "static": false, + "def": "err::Err open()" + }, + "close": { + "type": "func", + "name": "close", + "doc": { + "brief": "Close hid device", + "return": "err::Err", + "maixpy": "maix.peripheral.hid.Hid.close", + "py_doc": "Close hid device\n\nReturns: err::Err\n" + }, + "args": [], + "ret_type": "err::Err", + "static": false, + "def": "err::Err close()" + }, + "write": { + "type": "func", + "name": "write", + "doc": { + "brief": "Write data to hid device", + "param": { + "data": "data to write\nFor the keyboard, 8 bytes of data need to be written, with the format as follows:\ndata = [0x00, #\n0x00, #\n0x00, # Key value. Refer to the \"Universal Serial Bus HID Usage Tables\" section of the official documentation(https://www.usb.org).\n0x00, #\n0x00, #\n0x00, #\n0x00, #\n0x00] #\nFor the mouse, 4 bytes of data need to be written, with the format as follows:\ndata = [0x00, # Button state\n0x00: no button pressed\n0x01: press left button\n0x02: press right button\n0x04: press middle button\nx, # X-axis relative coordinates. Signed number, positive values for x indicate movement to the right\ny, # Y-axis relative coordinates. Signed number, positive values for y indicate movement downward\n0x00] # Wheel movement. Signed number, positive values indicate downward movement.\nFor the touchpad, 6 bytes of data need to be written, with the format as follows:\ndata = [0x00, # Button state (0: no button pressed, 0x01: press left button, 0x10, press right button.)\nx & 0xFF, (x >> 8) & 0xFF, # X-axis absolute coordinate, 0 means unused.\nNote: You must map the target position to the range [0x1, 0x7FFF]. This means x value = * 0x7FFF / \ny & 0xFF, (y >> 8) & 0xFF, # Y-axis absolute coordinate, 0 means unused.\nNote: You must map the target position to the range [0x1, 0x7FFF]. This means y value = * 0x7FFF / \n0x00, # Wheel movement. Signed number, positive values indicate downward movement." + }, + "return": "err::Err", + "maixpy": "maix.peripheral.hid.Hid.write", + "py_doc": "Write data to hid device\n\nArgs:\n - data: data to write\nFor the keyboard, 8 bytes of data need to be written, with the format as follows:\ndata = [0x00, #\n0x00, #\n0x00, # Key value. Refer to the \"Universal Serial Bus HID Usage Tables\" section of the official documentation(https://www.usb.org).\n0x00, #\n0x00, #\n0x00, #\n0x00, #\n0x00] #\nFor the mouse, 4 bytes of data need to be written, with the format as follows:\ndata = [0x00, # Button state\n0x00: no button pressed\n0x01: press left button\n0x02: press right button\n0x04: press middle button\nx, # X-axis relative coordinates. Signed number, positive values for x indicate movement to the right\ny, # Y-axis relative coordinates. Signed number, positive values for y indicate movement downward\n0x00] # Wheel movement. Signed number, positive values indicate downward movement.\nFor the touchpad, 6 bytes of data need to be written, with the format as follows:\ndata = [0x00, # Button state (0: no button pressed, 0x01: press left button, 0x10, press right button.)\nx & 0xFF, (x >> 8) & 0xFF, # X-axis absolute coordinate, 0 means unused.\nNote: You must map the target position to the range [0x1, 0x7FFF]. This means x value = * 0x7FFF / \ny & 0xFF, (y >> 8) & 0xFF, # Y-axis absolute coordinate, 0 means unused.\nNote: You must map the target position to the range [0x1, 0x7FFF]. This means y value = * 0x7FFF / \n0x00, # Wheel movement. Signed number, positive values indicate downward movement.\n\n\nReturns: err::Err\n" + }, + "args": [ + [ + "std::vector &", + "data", + null + ] + ], + "ret_type": "err::Err", + "static": false, + "def": "err::Err write(std::vector &data)" + }, + "is_opened": { + "type": "func", + "name": "is_opened", + "doc": { + "brief": "Check if hid device is opened", + "return": "bool", + "maixpy": "maix.peripheral.hid.Hid.is_opened", + "py_doc": "Check if hid device is opened\n\nReturns: bool\n" + }, + "args": [], + "ret_type": "bool", + "static": false, + "def": "bool is_opened()" + } + }, + "def": "class Hid" + } + }, + "auto_add": true + }, + "timer": { + "type": "module", + "doc": { + "brief": "maix.peripheral.timer module" + }, + "members": { + "TIMER": { + "type": "class", + "name": "TIMER", + "doc": { + "brief": "Peripheral timer class", + "maixpy": "maix.peripheral.timer.TIMER", + "py_doc": "Peripheral timer class" + }, + "members": { + "__init__": { + "type": "func", + "name": "TIMER", + "doc": { + "brief": "TIMER constructor", + "maixpy": "maix.peripheral.timer.TIMER.__init__", + "py_doc": "TIMER constructor" + }, + "args": [], + "ret_type": null, + "static": false, + "def": "TIMER()" + } + }, + "def": "class TIMER" + } + }, + "auto_add": true + } + }, + "auto_add": false + }, + "ext_dev": { + "type": "module", + "doc": { + "brief": "maix.ext_dev module" + }, + "members": { + "tmc2209": { + "type": "module", + "doc": { + "brief": "maix.ext_dev.tmc2209 module" + }, + "members": { + "slide_scan": { + "type": "func", + "name": "slide_scan", + "doc": { + "brief": "Scan and initialize the slide with the given parameters", + "param": { + "port": "UART port, string type.", + "addr": "TMC2209 UART address, range 0x00~0x03, integer type.", + "baud": "UART baud rate, integer type.", + "step_angle": "Motor step angle, float type.", + "micro_step": "Motor micro step, options: 1/2/4/8/16/32/64/128/256, integer type.", + "round_mm": "Round distance in mm, float type.", + "speed_mm_s": "Speed of the slide in mm/s, float type.", + "dir": "Direction of movement, boolean type. Default is true.", + "use_internal_sense_resistors": "Enable internal sense resistors if true, disable if false, boolean type. Default is true.", + "run_current_per": "Motor run current percentage, range 0~100(%), integer type. Default is 100%.", + "hold_current_per": "Motor hold current percentage, range 0~100(%), integer type. Default is 100%.", + "conf_save_path": "Configuration save path, string type. Default is \"./slide_conf.bin\".", + "force_update": "Force update the configuration if true, boolean type. Default is true." + }, + "maixpy": "maix.ext_dev.tmc2209.slide_scan", + "py_doc": "Scan and initialize the slide with the given parameters\n\nArgs:\n - port: UART port, string type.\n - addr: TMC2209 UART address, range 0x00~0x03, integer type.\n - baud: UART baud rate, integer type.\n - step_angle: Motor step angle, float type.\n - micro_step: Motor micro step, options: 1/2/4/8/16/32/64/128/256, integer type.\n - round_mm: Round distance in mm, float type.\n - speed_mm_s: Speed of the slide in mm/s, float type.\n - dir: Direction of movement, boolean type. Default is true.\n - use_internal_sense_resistors: Enable internal sense resistors if true, disable if false, boolean type. Default is true.\n - run_current_per: Motor run current percentage, range 0~100(%), integer type. Default is 100%.\n - hold_current_per: Motor hold current percentage, range 0~100(%), integer type. Default is 100%.\n - conf_save_path: Configuration save path, string type. Default is \"./slide_conf.bin\".\n - force_update: Force update the configuration if true, boolean type. Default is true.\n" + }, + "args": [ + [ + "const char*", + "port", + null + ], + [ + "uint8_t", + "addr", + null + ], + [ + "long", + "baud", + null + ], + [ + "/* Uart init param */ float", + "step_angle", + null + ], + [ + "uint16_t", + "micro_step", + null + ], + [ + "float", + "round_mm", + null + ], + [ + "/* Motor init param */ float", + "speed_mm_s", + null + ], + [ + "bool", + "dir", + "true" + ], + [ + "bool", + "use_internal_sense_resistors", + "true" + ], + [ + "uint8_t", + "run_current_per", + "100" + ], + [ + "uint8_t", + "hold_current_per", + "100" + ], + [ + "const std::string", + "conf_save_path", + "\"./slide_conf.bin\"" + ], + [ + "bool", + "force_update", + "true /* Driver init param */" + ] + ], + "ret_type": "void", + "static": false, + "def": "void slide_scan(const char* port, uint8_t addr, long baud, /* Uart init param */\n float step_angle, uint16_t micro_step, float round_mm, /* Motor init param */\n float speed_mm_s, bool dir=true, bool use_internal_sense_resistors=true, uint8_t run_current_per=100,\n uint8_t hold_current_per=100, const std::string conf_save_path=\"./slide_conf.bin\",\n bool force_update=true /* Driver init param */)" + }, + "slide_test": { + "type": "func", + "name": "slide_test", + "doc": { + "brief": "Test the slide with the given parameters\\nThis function tests the slide by moving it in the specified direction until a stall condition is detected, as defined in the configuration file.", + "param": { + "port": "UART port, string type.", + "addr": "TMC2209 UART address, range 0x00~0x03, integer type.", + "baud": "UART baud rate, integer type.", + "step_angle": "Motor step angle, float type.", + "micro_step": "Motor micro step, options: 1/2/4/8/16/32/64/128/256, integer type.", + "round_mm": "Round distance in mm, float type.", + "speed_mm_s": "Speed of the slide in mm/s, float type.", + "dir": "Direction of movement, boolean type. Default is true.", + "use_internal_sense_resistors": "Enable internal sense resistors if true, disable if false, boolean type. Default is true.", + "run_current_per": "Motor run current percentage, range 0~100(%), integer type. Default is 100%.", + "hold_current_per": "Motor hold current percentage, range 0~100(%), integer type. Default is 100%.", + "conf_save_path": "Configuration save path, string type. Default is \"./slide_conf.bin\"." + }, + "maixpy": "maix.ext_dev.tmc2209.slide_test", + "py_doc": "Test the slide with the given parameters\nThis function tests the slide by moving it in the specified direction until a stall condition is detected, as defined in the configuration file.\n\nArgs:\n - port: UART port, string type.\n - addr: TMC2209 UART address, range 0x00~0x03, integer type.\n - baud: UART baud rate, integer type.\n - step_angle: Motor step angle, float type.\n - micro_step: Motor micro step, options: 1/2/4/8/16/32/64/128/256, integer type.\n - round_mm: Round distance in mm, float type.\n - speed_mm_s: Speed of the slide in mm/s, float type.\n - dir: Direction of movement, boolean type. Default is true.\n - use_internal_sense_resistors: Enable internal sense resistors if true, disable if false, boolean type. Default is true.\n - run_current_per: Motor run current percentage, range 0~100(%), integer type. Default is 100%.\n - hold_current_per: Motor hold current percentage, range 0~100(%), integer type. Default is 100%.\n - conf_save_path: Configuration save path, string type. Default is \"./slide_conf.bin\".\n" + }, + "args": [ + [ + "const char*", + "port", + null + ], + [ + "uint8_t", + "addr", + null + ], + [ + "long", + "baud", + null + ], + [ + "/* Uart init param */ float", + "step_angle", + null + ], + [ + "uint16_t", + "micro_step", + null + ], + [ + "float", + "round_mm", + null + ], + [ + "/* Motor init param */ float", + "speed_mm_s", + null + ], + [ + "bool", + "dir", + "true" + ], + [ + "bool", + "use_internal_sense_resistors", + "true" + ], + [ + "uint8_t", + "run_current_per", + "100" + ], + [ + "uint8_t", + "hold_current_per", + "100" + ], + [ + "const std::string", + "conf_save_path", + "\"./slide_conf.bin\"/* Driver init param */" + ] + ], + "ret_type": "void", + "static": false, + "def": "void slide_test(const char* port, uint8_t addr, long baud, /* Uart init param */\n float step_angle, uint16_t micro_step, float round_mm, /* Motor init param */\n float speed_mm_s, bool dir=true, bool use_internal_sense_resistors=true, uint8_t run_current_per=100,\n uint8_t hold_current_per=100, const std::string conf_save_path=\"./slide_conf.bin\"/* Driver init param */)" + }, + "Slide": { + "type": "class", + "name": "Slide", + "doc": { + "brief": "Slide Class", + "maixpy": "maix.ext_dev.tmc2209.Slide", + "py_doc": "Slide Class" + }, + "members": { + "__init__": { + "type": "func", + "name": "Slide", + "doc": { + "brief": "Constructor for Slide\\nInitializes the Slide object with the specified parameters.", + "param": { + "port": "UART port, string type.", + "addr": "TMC2209 UART address, range 0x00~0x03, integer type.", + "baud": "UART baud rate, integer type.", + "step_angle": "Motor step angle, float type.", + "micro_step": "Motor micro step, options: 1/2/4/8/16/32/64/128/256, integer type.", + "round_mm": "Round distance in mm, float type.", + "speed_mm_s": "Speed of the slide in mm/s, float type. Default is -1, indicating the use of a default speed factor.", + "use_internal_sense_resistors": "Enable internal sense resistors if TRUE, disable if FALSE, boolean type. Default is TRUE.", + "run_current_per": "Motor run current percentage, range 0~100(%), integer type. Default is 100%.", + "hold_current_per": "Motor hold current percentage, range 0~100(%), integer type. Default is 100%.", + "cfg_file_path": "Configuration file path, string type. Default is an empty string, indicating no configuration file." + }, + "maixpy": "maix.ext_dev.tmc2209.Slide.__init__", + "py_doc": "Constructor for Slide\nInitializes the Slide object with the specified parameters.\n\nArgs:\n - port: UART port, string type.\n - addr: TMC2209 UART address, range 0x00~0x03, integer type.\n - baud: UART baud rate, integer type.\n - step_angle: Motor step angle, float type.\n - micro_step: Motor micro step, options: 1/2/4/8/16/32/64/128/256, integer type.\n - round_mm: Round distance in mm, float type.\n - speed_mm_s: Speed of the slide in mm/s, float type. Default is -1, indicating the use of a default speed factor.\n - use_internal_sense_resistors: Enable internal sense resistors if TRUE, disable if FALSE, boolean type. Default is TRUE.\n - run_current_per: Motor run current percentage, range 0~100(%), integer type. Default is 100%.\n - hold_current_per: Motor hold current percentage, range 0~100(%), integer type. Default is 100%.\n - cfg_file_path: Configuration file path, string type. Default is an empty string, indicating no configuration file.\n" + }, + "args": [ + [ + "const char*", + "port", + null + ], + [ + "uint8_t", + "addr", + null + ], + [ + "long", + "baud", + null + ], + [ + "/* Uart init param */ float", + "step_angle", + null + ], + [ + "uint16_t", + "micro_step", + null + ], + [ + "float", + "round_mm", + null + ], + [ + "/* Motor init param */ float", + "speed_mm_s", + "-1" + ], + [ + "bool", + "use_internal_sense_resistors", + "true" + ], + [ + "uint8_t", + "run_current_per", + "100" + ], + [ + "uint8_t", + "hold_current_per", + "100" + ], + [ + "std::string", + "cfg_file_path", + "\"\" /* Driver init param */" + ] + ], + "ret_type": null, + "static": false, + "def": "Slide(const char* port, uint8_t addr, long baud, /* Uart init param */\n float step_angle, uint16_t micro_step, float round_mm, /* Motor init param */\n float speed_mm_s=-1, bool use_internal_sense_resistors=true, uint8_t run_current_per=100,\n uint8_t hold_current_per=100, std::string cfg_file_path=\"\" /* Driver init param */)" + }, + "load_conf": { + "type": "func", + "name": "load_conf", + "doc": { + "brief": "Load configuration from a file\\nLoads the configuration settings for the slide from the specified file path.", + "param": { + "path": "Path to the configuration file, string type." + }, + "maixpy": "maix.ext_dev.tmc2209.Slide.load_conf", + "py_doc": "Load configuration from a file\nLoads the configuration settings for the slide from the specified file path.\n\nArgs:\n - path: Path to the configuration file, string type.\n" + }, + "args": [ + [ + "std::string", + "path", + null + ] + ], + "ret_type": "void", + "static": false, + "def": "void load_conf(std::string path)" + }, + "move": { + "type": "func", + "name": "move", + "doc": { + "brief": "Move the slide by a specified length\\nMoves the slide by the specified length at the given speed. Optionally checks for stall conditions.", + "param": { + "oft": "Length to move, float type.", + "speed_mm_s": "Speed in mm/s. Default is -1, indicating the use of the default speed set during initialization.", + "check": "Enable movement check if true, boolean type. Default is true." + }, + "maixpy": "maix.ext_dev.tmc2209.Slide.move", + "py_doc": "Move the slide by a specified length\nMoves the slide by the specified length at the given speed. Optionally checks for stall conditions.\n\nArgs:\n - oft: Length to move, float type.\n - speed_mm_s: Speed in mm/s. Default is -1, indicating the use of the default speed set during initialization.\n - check: Enable movement check if true, boolean type. Default is true.\n" + }, + "args": [ + [ + "float", + "oft", + null + ], + [ + "int", + "speed_mm_s", + "-1" + ], + [ + "bool", + "check", + "true" + ] + ], + "ret_type": "void", + "static": false, + "def": "void move(float oft, int speed_mm_s=-1, bool check=true)" + }, + "reset": { + "type": "func", + "name": "reset", + "doc": { + "brief": "Reset the slide position\\nResets the slide position in the specified direction at the given speed.", + "param": { + "dir": "Direction of reset, boolean type. Default is false.", + "speed_mm_s": "Speed in mm/s. Default is -1, indicating the use of the speed set during initialization." + }, + "maixpy": "maix.ext_dev.tmc2209.Slide.reset", + "py_doc": "Reset the slide position\nResets the slide position in the specified direction at the given speed.\n\nArgs:\n - dir: Direction of reset, boolean type. Default is false.\n - speed_mm_s: Speed in mm/s. Default is -1, indicating the use of the speed set during initialization.\n" + }, + "args": [ + [ + "bool", + "dir", + "false" + ], + [ + "int", + "speed_mm_s", + "-1" + ] + ], + "ret_type": "void", + "static": false, + "def": "void reset(bool dir=false, int speed_mm_s=-1)" + }, + "stop_default_per": { + "type": "func", + "name": "stop_default_per", + "doc": { + "brief": "Get or set the stop default percentage\\nRetrieves or sets the stop default percentage. If the parameter is -1, it returns the current setting.", + "param": { + "per": "Stop default percentage, range 0~100(%), integer type. Default is -1, indicating no change." + }, + "return": "int Current stop default percentage if per is -1, otherwise the new set percentage.", + "maixpy": "maix.ext_dev.tmc2209.Slide.stop_default_per", + "py_doc": "Get or set the stop default percentage\nRetrieves or sets the stop default percentage. If the parameter is -1, it returns the current setting.\n\nArgs:\n - per: Stop default percentage, range 0~100(%), integer type. Default is -1, indicating no change.\n\n\nReturns: int Current stop default percentage if per is -1, otherwise the new set percentage.\n" + }, + "args": [ + [ + "int", + "per", + "-1" + ] + ], + "ret_type": "int", + "static": false, + "def": "int stop_default_per(int per=-1)" + }, + "run_current_per": { + "type": "func", + "name": "run_current_per", + "doc": { + "brief": "Get or set the run current percentage\\nRetrieves or sets the run current percentage. If the parameter is -1, it returns the current setting.", + "param": { + "per": "Run current percentage, range 0~100(%), integer type. Default is -1, indicating no change." + }, + "return": "int Current run current percentage if per is -1, otherwise the new set percentage.", + "maixpy": "maix.ext_dev.tmc2209.Slide.run_current_per", + "py_doc": "Get or set the run current percentage\nRetrieves or sets the run current percentage. If the parameter is -1, it returns the current setting.\n\nArgs:\n - per: Run current percentage, range 0~100(%), integer type. Default is -1, indicating no change.\n\n\nReturns: int Current run current percentage if per is -1, otherwise the new set percentage.\n" + }, + "args": [ + [ + "int", + "per", + "-1" + ] + ], + "ret_type": "int", + "static": false, + "def": "int run_current_per(int per=-1)" + }, + "hold_current_per": { + "type": "func", + "name": "hold_current_per", + "doc": { + "brief": "Get or set the hold current percentage\\nRetrieves or sets the hold current percentage. If the parameter is -1, it returns the current setting.", + "param": { + "per": "Hold current percentage, range 0~100(%), integer type. Default is -1, indicating no change." + }, + "return": "int Current hold current percentage if per is -1, otherwise the new set percentage.", + "maixpy": "maix.ext_dev.tmc2209.Slide.hold_current_per", + "py_doc": "Get or set the hold current percentage\nRetrieves or sets the hold current percentage. If the parameter is -1, it returns the current setting.\n\nArgs:\n - per: Hold current percentage, range 0~100(%), integer type. Default is -1, indicating no change.\n\n\nReturns: int Current hold current percentage if per is -1, otherwise the new set percentage.\n" + }, + "args": [ + [ + "int", + "per", + "-1" + ] + ], + "ret_type": "int", + "static": false, + "def": "int hold_current_per(int per=-1)" + }, + "use_internal_sense_resistors": { + "type": "func", + "name": "use_internal_sense_resistors", + "doc": { + "brief": "Enable or disable internal sense resistors\\nEnables or disables the internal sense resistors based on the provided boolean value.", + "param": { + "b": "Boolean value to enable (true) or disable (false) internal sense resistors. Default is true." + }, + "maixpy": "maix.ext_dev.tmc2209.Slide.use_internal_sense_resistors", + "py_doc": "Enable or disable internal sense resistors\nEnables or disables the internal sense resistors based on the provided boolean value.\n\nArgs:\n - b: Boolean value to enable (true) or disable (false) internal sense resistors. Default is true.\n" + }, + "args": [ + [ + "bool", + "b", + "true" + ] + ], + "ret_type": "void", + "static": false, + "def": "void use_internal_sense_resistors(bool b=true)" + } + }, + "def": "class Slide" + }, + "ScrewSlide": { + "type": "class", + "name": "ScrewSlide", + "doc": { + "brief": "ScrewSlide Class", + "maixpy": "maix.ext_dev.tmc2209.ScrewSlide", + "py_doc": "ScrewSlide Class" + }, + "members": { + "__init__": { + "type": "func", + "name": "ScrewSlide", + "doc": { + "brief": "Constructor for ScrewSlide", + "param": { + "port": "UART port, string type.", + "addr": "TMC2209 UART address, range 0x00~0x03, integer type.", + "baud": "UART baud rate, integer type.", + "step_angle": "Motor step angle, float type.", + "micro_step": "Motor micro step, options: 1/2/4/8/16/32/64/128/256, integer type.", + "screw_pitch": "Screw pitch of the slide, integer type.", + "speed_mm_s": "Speed of the slide in mm/s, 10 means 10mm/s, float type.\nDefault is -1, indicating the use of a default speed factor.", + "use_internal_sense_resistors": "Enable internal sense resistors if TRUE,\ndisable if FALSE, boolean type. Default is TRUE.", + "run_current_per": "Motor run current percentage, range 0~100(%), integer type. Default is 100%.", + "hold_current_per": "Motor hold current percentage, range 0~100(%), integer type. Default is 100%." + }, + "maixpy": "maix.ext_dev.tmc2209.ScrewSlide.__init__", + "py_doc": "Constructor for ScrewSlide\n\nArgs:\n - port: UART port, string type.\n - addr: TMC2209 UART address, range 0x00~0x03, integer type.\n - baud: UART baud rate, integer type.\n - step_angle: Motor step angle, float type.\n - micro_step: Motor micro step, options: 1/2/4/8/16/32/64/128/256, integer type.\n - screw_pitch: Screw pitch of the slide, integer type.\n - speed_mm_s: Speed of the slide in mm/s, 10 means 10mm/s, float type.\nDefault is -1, indicating the use of a default speed factor.\n - use_internal_sense_resistors: Enable internal sense resistors if TRUE,\ndisable if FALSE, boolean type. Default is TRUE.\n - run_current_per: Motor run current percentage, range 0~100(%), integer type. Default is 100%.\n - hold_current_per: Motor hold current percentage, range 0~100(%), integer type. Default is 100%.\n" + }, + "args": [ + [ + "const char*", + "port", + null + ], + [ + "uint8_t", + "addr", + null + ], + [ + "long", + "baud", + null + ], + [ + "/* Uart init param */ float", + "step_angle", + null + ], + [ + "uint16_t", + "micro_step", + null + ], + [ + "float", + "screw_pitch", + null + ], + [ + "/* Motor init param */ float", + "speed_mm_s", + "-1" + ], + [ + "bool", + "use_internal_sense_resistors", + "true" + ], + [ + "uint8_t", + "run_current_per", + "100" + ], + [ + "uint8_t", + "hold_current_per", + "100" + ] + ], + "ret_type": null, + "static": false, + "def": "ScrewSlide(const char* port, uint8_t addr, long baud, /* Uart init param */\n float step_angle, uint16_t micro_step, float screw_pitch, /* Motor init param */\n float speed_mm_s=-1, bool use_internal_sense_resistors=true, uint8_t run_current_per=100,\n uint8_t hold_current_per=100)" + }, + "move": { + "type": "func", + "name": "move", + "doc": { + "brief": "Move the slide by a specified length", + "param": { + "oft": "Length to move, 10 means 10mm, float type.\nPositive values move the slide in the positive direction, negative values move it in the opposite direction.", + "speed_mm_s": "Speed in mm/s. Default is -1, indicating the use of the default speed set during initialization.", + "callback": "Callback function to be called during movement.\nThe callback function receives the current progress percentage (0~100%) of the movement.\nIf the callback returns true, the move operation will be terminated immediately. Default is nullptr." + }, + "maixpy": "maix.ext_dev.tmc2209.ScrewSlide.move", + "py_doc": "Move the slide by a specified length\n\nArgs:\n - oft: Length to move, 10 means 10mm, float type.\nPositive values move the slide in the positive direction, negative values move it in the opposite direction.\n - speed_mm_s: Speed in mm/s. Default is -1, indicating the use of the default speed set during initialization.\n - callback: Callback function to be called during movement.\nThe callback function receives the current progress percentage (0~100%) of the movement.\nIf the callback returns true, the move operation will be terminated immediately. Default is nullptr.\n" + }, + "args": [ + [ + "float", + "oft", + null + ], + [ + "int", + "speed_mm_s", + "-1" + ], + [ + "std::function", + "callback", + "nullptr" + ] + ], + "ret_type": "void", + "static": false, + "def": "void move(float oft, int speed_mm_s=-1, std::function callback=nullptr)" + }, + "reset": { + "type": "func", + "name": "reset", + "doc": { + "brief": "Reset the slide position", + "param": { + "callback": "Callback function to be called during the reset loop.\nThe reset operation will only terminate if the callback returns true.", + "dir": "Direction of reset. Default is false.", + "speed_mm_s": "Speed in mm/s. Default is -1, indicating the use of the speed set during initialization." + }, + "maixpy": "maix.ext_dev.tmc2209.ScrewSlide.reset", + "py_doc": "Reset the slide position\n\nArgs:\n - callback: Callback function to be called during the reset loop.\nThe reset operation will only terminate if the callback returns true.\n - dir: Direction of reset. Default is false.\n - speed_mm_s: Speed in mm/s. Default is -1, indicating the use of the speed set during initialization.\n" + }, + "args": [ + [ + "std::function", + "callback", + null + ], + [ + "bool", + "dir", + "false" + ], + [ + "int", + "speed_mm_s", + "-1" + ] + ], + "ret_type": "void", + "static": false, + "def": "void reset(std::function callback, bool dir=false, int speed_mm_s=-1)" + }, + "run_current_per": { + "type": "func", + "name": "run_current_per", + "doc": { + "brief": "Get or set the run current percentage", + "param": { + "per": "Run current percentage, range 0~100(%).\nDefault is -1, indicating no change and returning the current run current percentage." + }, + "return": "int Current run current percentage if per is -1, otherwise the new set percentage.", + "maixpy": "maix.ext_dev.tmc2209.ScrewSlide.run_current_per", + "py_doc": "Get or set the run current percentage\n\nArgs:\n - per: Run current percentage, range 0~100(%).\nDefault is -1, indicating no change and returning the current run current percentage.\n\n\nReturns: int Current run current percentage if per is -1, otherwise the new set percentage.\n" + }, + "args": [ + [ + "int", + "per", + "-1" + ] + ], + "ret_type": "int", + "static": false, + "def": "int run_current_per(int per=-1)" + }, + "hold_current_per": { + "type": "func", + "name": "hold_current_per", + "doc": { + "brief": "Get or set the hold current percentage", + "param": { + "per": "Hold current percentage, range 0~100(%). Default is -1, indicating no change and returning the current hold current percentage." + }, + "return": "int Current hold current percentage if per is -1, otherwise the new set percentage.", + "maixpy": "maix.ext_dev.tmc2209.ScrewSlide.hold_current_per", + "py_doc": "Get or set the hold current percentage\n\nArgs:\n - per: Hold current percentage, range 0~100(%). Default is -1, indicating no change and returning the current hold current percentage.\n\n\nReturns: int Current hold current percentage if per is -1, otherwise the new set percentage.\n" + }, + "args": [ + [ + "int", + "per", + "-1" + ] + ], + "ret_type": "int", + "static": false, + "def": "int hold_current_per(int per=-1)" + }, + "use_internal_sense_resistors": { + "type": "func", + "name": "use_internal_sense_resistors", + "doc": { + "brief": "Enable or disable internal sense resistors", + "param": { + "b": "Boolean value to enable (true) or disable (false) internal sense resistors. Default is true." + }, + "maixpy": "maix.ext_dev.tmc2209.ScrewSlide.use_internal_sense_resistors", + "py_doc": "Enable or disable internal sense resistors\n\nArgs:\n - b: Boolean value to enable (true) or disable (false) internal sense resistors. Default is true.\n" + }, + "args": [ + [ + "bool", + "b", + "true" + ] + ], + "ret_type": "void", + "static": false, + "def": "void use_internal_sense_resistors(bool b=true)" + } + }, + "def": "class ScrewSlide" + } + }, + "auto_add": true + }, + "bm8563": { + "type": "module", + "doc": { + "brief": "maix.ext_dev.bm8563 module" + }, + "members": { + "BM8563": { + "type": "class", + "name": "BM8563", + "doc": { + "brief": "Peripheral BM8563 class", + "maixpy": "maix.ext_dev.bm8563.BM8563", + "py_doc": "Peripheral BM8563 class" + }, + "members": { + "__init__": { + "type": "func", + "name": "BM8563", + "doc": { + "brief": "BM8563 constructor", + "param": { + "i2c_bus": "i2c bus number." + }, + "maixpy": "maix.ext_dev.bm8563.BM8563.__init__", + "py_doc": "BM8563 constructor\n\nArgs:\n - i2c_bus: i2c bus number.\n" + }, + "args": [ + [ + "int", + "i2c_bus", + "-1" + ] + ], + "ret_type": null, + "static": false, + "def": "BM8563(int i2c_bus=-1)" + }, + "datetime": { + "type": "func", + "name": "datetime", + "doc": { + "brief": "Get or set the date and time of the BM8563.", + "param": { + "timetuple": "time tuple, like (year, month, day[, hour[, minute[, second]]])" + }, + "return": "time tuple, like (year, month, day[, hour[, minute[, second]]])", + "maixpy": "maix.ext_dev.bm8563.BM8563.datetime", + "py_doc": "Get or set the date and time of the BM8563.\n\nArgs:\n - timetuple: time tuple, like (year, month, day[, hour[, minute[, second]]])\n\n\nReturns: time tuple, like (year, month, day[, hour[, minute[, second]]])\n" + }, + "args": [ + [ + "std::vector", + "timetuple", + "std::vector()" + ] + ], + "ret_type": "std::vector", + "static": false, + "def": "std::vector datetime(std::vector timetuple=std::vector())" + }, + "init": { + "type": "func", + "name": "init", + "doc": { + "brief": "Initialise the BM8563.", + "param": { + "timetuple": "time tuple, like (year, month, day[, hour[, minute[, second]]])" + }, + "return": "err::Err type, if init success, return err::ERR_NONE", + "maixpy": "maix.ext_dev.bm8563.BM8563.init", + "py_doc": "Initialise the BM8563.\n\nArgs:\n - timetuple: time tuple, like (year, month, day[, hour[, minute[, second]]])\n\n\nReturns: err::Err type, if init success, return err::ERR_NONE\n" + }, + "args": [ + [ + "std::vector", + "timetuple", + null + ] + ], + "ret_type": "err::Err", + "static": false, + "def": "err::Err init(std::vector timetuple)" + }, + "now": { + "type": "func", + "name": "now", + "doc": { + "brief": "Get get the current datetime.", + "return": "time tuple, like (year, month, day[, hour[, minute[, second]]])", + "maixpy": "maix.ext_dev.bm8563.BM8563.now", + "py_doc": "Get get the current datetime.\n\nReturns: time tuple, like (year, month, day[, hour[, minute[, second]]])\n" + }, + "args": [], + "ret_type": "std::vector", + "static": false, + "def": "std::vector now()" + }, + "deinit": { + "type": "func", + "name": "deinit", + "doc": { + "brief": "Deinit the BM8563.", + "return": "err::Err err::Err type, if deinit success, return err::ERR_NONE", + "maixpy": "maix.ext_dev.bm8563.BM8563.deinit", + "py_doc": "Deinit the BM8563.\n\nReturns: err::Err err::Err type, if deinit success, return err::ERR_NONE\n" + }, + "args": [], + "ret_type": "err::Err", + "static": false, + "def": "err::Err deinit()" + }, + "hctosys": { + "type": "func", + "name": "hctosys", + "doc": { + "brief": "Set the system time from the BM8563", + "return": "err::Err type", + "maixpy": "maix.ext_dev.bm8563.BM8563.hctosys", + "py_doc": "Set the system time from the BM8563\n\nReturns: err::Err type\n" + }, + "args": [], + "ret_type": "err::Err", + "static": false, + "def": "err::Err hctosys()" + }, + "systohc": { + "type": "func", + "name": "systohc", + "doc": { + "brief": "Set the BM8563 from the system time", + "return": "err::Err type", + "maixpy": "maix.ext_dev.bm8563.BM8563.systohc", + "py_doc": "Set the BM8563 from the system time\n\nReturns: err::Err type\n" + }, + "args": [], + "ret_type": "err::Err", + "static": false, + "def": "err::Err systohc()" + } + }, + "def": "class BM8563" + } + }, + "auto_add": true + }, + "qmi8658": { + "type": "module", + "doc": { + "brief": "maix.ext_dev.qmi8658 module" + }, + "members": { + "QMI8658": { + "type": "class", + "name": "QMI8658", + "doc": { + "brief": "QMI8656 driver class", + "maixpy": "maix.ext_dev.qmi8658.QMI8658", + "py_doc": "QMI8656 driver class" + }, + "members": { + "__init__": { + "type": "func", + "name": "QMI8658", + "doc": { + "brief": "Construct a new QMI8658 object, will open QMI8658", + "param": { + "i2c_bus": "i2c bus number. Automatically selects the on-board qmi8658 when -1 is passed in.", + "addr": "QMI8658 i2c addr.", + "freq": "QMI8658 freq", + "mode": "QMI8658 Mode: ACC_ONLY/GYRO_ONLY/DUAL", + "acc_scale": "acc scale, see @qmi8658::AccScale", + "acc_odr": "acc output data rate, see @qmi8658::AccOdr", + "gyro_scale": "gyro scale, see @qmi8658::GyroScale", + "gyro_odr": "gyro output data rate, see @qmi8658::GyroOdr", + "block": "block or non-block, defalut is true" + }, + "maixpy": "maix.ext_dev.qmi8658.QMI8658.__init__", + "py_doc": "Construct a new QMI8658 object, will open QMI8658\n\nArgs:\n - i2c_bus: i2c bus number. Automatically selects the on-board qmi8658 when -1 is passed in.\n - addr: QMI8658 i2c addr.\n - freq: QMI8658 freq\n - mode: QMI8658 Mode: ACC_ONLY/GYRO_ONLY/DUAL\n - acc_scale: acc scale, see @qmi8658::AccScale\n - acc_odr: acc output data rate, see @qmi8658::AccOdr\n - gyro_scale: gyro scale, see @qmi8658::GyroScale\n - gyro_odr: gyro output data rate, see @qmi8658::GyroOdr\n - block: block or non-block, defalut is true\n" + }, + "args": [ + [ + "int", + "i2c_bus", + "-1" + ], + [ + "int", + "addr", + "0x6B" + ], + [ + "int", + "freq", + "400000" + ], + [ + "maix::ext_dev::imu::Mode", + "mode", + "maix::ext_dev::imu::Mode::DUAL" + ], + [ + "maix::ext_dev::imu::AccScale", + "acc_scale", + "maix::ext_dev::imu::AccScale::ACC_SCALE_2G" + ], + [ + "maix::ext_dev::imu::AccOdr", + "acc_odr", + "maix::ext_dev::imu::AccOdr::ACC_ODR_8000" + ], + [ + "maix::ext_dev::imu::GyroScale", + "gyro_scale", + "maix::ext_dev::imu::GyroScale::GYRO_SCALE_16DPS" + ], + [ + "maix::ext_dev::imu::GyroOdr", + "gyro_odr", + "maix::ext_dev::imu::GyroOdr::GYRO_ODR_8000" + ], + [ + "bool", + "block", + "true" + ] + ], + "ret_type": null, + "static": false, + "def": "QMI8658(int i2c_bus=-1, int addr=0x6B, int freq=400000,\n maix::ext_dev::imu::Mode mode=maix::ext_dev::imu::Mode::DUAL,\n maix::ext_dev::imu::AccScale acc_scale=maix::ext_dev::imu::AccScale::ACC_SCALE_2G,\n maix::ext_dev::imu::AccOdr acc_odr=maix::ext_dev::imu::AccOdr::ACC_ODR_8000,\n maix::ext_dev::imu::GyroScale gyro_scale=maix::ext_dev::imu::GyroScale::GYRO_SCALE_16DPS,\n maix::ext_dev::imu::GyroOdr gyro_odr=maix::ext_dev::imu::GyroOdr::GYRO_ODR_8000,\n bool block=true)" + }, + "read": { + "type": "func", + "name": "read", + "doc": { + "brief": "Read data from QMI8658.", + "return": "list type. If only one of the outputs is initialized, only [x,y,z] of that output will be returned.\nIf all outputs are initialized, [acc_x, acc_y, acc_z, gyro_x, gyro_y, gyro_z] is returned.", + "maixpy": "maix.ext_dev.qmi8658.QMI8658.read", + "py_doc": "Read data from QMI8658.\n\nReturns: list type. If only one of the outputs is initialized, only [x,y,z] of that output will be returned.\nIf all outputs are initialized, [acc_x, acc_y, acc_z, gyro_x, gyro_y, gyro_z] is returned.\n" + }, + "args": [], + "ret_type": "std::vector", + "static": false, + "def": "std::vector read()" + } + }, + "def": "class QMI8658" + } + }, + "auto_add": true + }, + "mlx90640": { + "type": "module", + "doc": { + "brief": "maix.ext_dev.mlx90640 module" + }, + "members": { + "Cmap": { + "type": "enum", + "name": "class", + "doc": { + "brief": "Cmap", + "maixpy": "maix.ext_dev.mlx90640.Cmap", + "py_doc": "Cmap" + }, + "values": [ + [ + "WHITE_HOT", + "0", + "" + ], + [ + "BLACK_HOT", + "", + "" + ], + [ + "IRONBOW", + "", + "" + ], + [ + "NIGHT", + "", + "" + ], + [ + "RED_HOT", + "", + "" + ], + [ + "WHITE_HOT_SD", + "", + "" + ], + [ + "BLACK_HOT_SD", + "", + "" + ], + [ + "RED_HOT_SD", + "", + "" + ] + ], + "def": "enum class Cmap : uint8_t {\n WHITE_HOT = 0,\n BLACK_HOT,\n IRONBOW,\n NIGHT,\n RED_HOT,\n WHITE_HOT_SD,\n BLACK_HOT_SD,\n RED_HOT_SD\n}" + }, + "FPS": { + "type": "enum", + "name": "class", + "doc": { + "brief": "MLX90640 FPS", + "maixpy": "maix.ext_dev.mlx90640.FPS", + "py_doc": "MLX90640 FPS" + }, + "values": [ + [ + "FPS_1", + "0b001", + "" + ], + [ + "FPS_2", + "0b010", + "" + ], + [ + "FPS_4", + "0b011", + "" + ], + [ + "FPS_8", + "0b100", + "" + ], + [ + "FPS_16", + "0b101", + "" + ], + [ + "FPS_32", + "0b110", + "" + ], + [ + "FPS_64", + "0b111", + "" + ] + ], + "def": "enum class FPS : uint8_t {\n FPS_1 = 0b001,\n FPS_2 = 0b010,\n FPS_4 = 0b011,\n FPS_8 = 0b100,\n FPS_16 = 0b101,\n FPS_32 = 0b110,\n FPS_64 = 0b111,\n}" + }, + "MLX_W": { + "type": "var", + "name": "", + "doc": { + "brief": "MLX90640 Image Width.", + "maixpy": "maix.ext_dev.mlx90640.MLX_W", + "py_doc": "MLX90640 Image Width." + }, + "value": "32", + "static": false, + "readonly": true, + "def": "constexpr uint32_t MLX_W = 32" + }, + "MLX_H": { + "type": "var", + "name": "", + "doc": { + "brief": "MLX90640 Image Height.", + "maixpy": "maix.ext_dev.mlx90640.MLX_H", + "py_doc": "MLX90640 Image Height." + }, + "value": "24", + "static": false, + "readonly": true, + "def": "constexpr uint32_t MLX_H = 24" + }, + "to_kmatrix": { + "type": "func", + "name": "to_kmatrix", + "doc": { + "brief": "CMatrix to KMatrix.", + "param": { + "matrix": "CMatrix type." + }, + "return": "KMatrix", + "maixpy": "maix.ext_dev.mlx90640.to_kmatrix", + "py_doc": "CMatrix to KMatrix.\n\nArgs:\n - matrix: CMatrix type.\n\n\nReturns: KMatrix\n" + }, + "args": [ + [ + "const CMatrix&", + "matrix", + null + ] + ], + "ret_type": "KMatrix", + "static": false, + "def": "KMatrix to_kmatrix(const CMatrix& matrix)" + }, + "to_cmatrix": { + "type": "func", + "name": "to_cmatrix", + "doc": { + "brief": "KMatrix to CMatrix", + "param": { + "matrix": "KMatrix type." + }, + "return": "CMatrix", + "maixpy": "maix.ext_dev.mlx90640.to_cmatrix", + "py_doc": "KMatrix to CMatrix\n\nArgs:\n - matrix: KMatrix type.\n\n\nReturns: CMatrix\n" + }, + "args": [ + [ + "const KMatrix&", + "matrix", + null + ] + ], + "ret_type": "CMatrix", + "static": false, + "def": "CMatrix to_cmatrix(const KMatrix& matrix)" + }, + "MLX90640Celsius": { + "type": "class", + "name": "MLX90640Celsius", + "doc": { + "brief": "MLX90640 (\u2103)", + "maixpy": "maix.ext_dev.mlx90640.MLX90640Celsius", + "py_doc": "MLX90640 (\u2103)" + }, + "members": { + "__init__": { + "type": "func", + "name": "MLX90640Celsius", + "doc": { + "brief": "Construct a new MLX90640Celsius object\\nThis constructor initializes an MLX90640Celsius object with the specified parameters\\nto configure the I2C bus communication, frame rate, color mapping, temperature ranges,\\nand emissivity for the MLX90640 thermal camera.", + "param": { + "i2c_bus_num": "The I2C bus number to which the MLX90640 is connected.", + "fps": "The preferred frame rate for the MLX90640, default is FPS::FPS_32.", + "cmap": "The color mapping to be used for generating the pseudo color image, default is Cmap::WHITE_HOT.", + "temp_min": "The minimum reference temperature (in \u00b0C) for generating the pseudo color image. Default is -1.", + "temp_max": "The maximum reference temperature (in \u00b0C) for generating the pseudo color image. Default is -1.\nIf both max and min are equal, it operates in auto mode:\nthe maximum temperature in the frame is taken as the maximum reference temperature,\nand the minimum temperature in the frame is taken as the minimum reference temperature.", + "emissivity": "The emissivity parameter for the MLX90640, default is 0.95." + }, + "maixpy": "maix.ext_dev.mlx90640.MLX90640Celsius.__init__", + "py_doc": "Construct a new MLX90640Celsius object\nThis constructor initializes an MLX90640Celsius object with the specified parameters\nto configure the I2C bus communication, frame rate, color mapping, temperature ranges,\nand emissivity for the MLX90640 thermal camera.\n\nArgs:\n - i2c_bus_num: The I2C bus number to which the MLX90640 is connected.\n - fps: The preferred frame rate for the MLX90640, default is FPS::FPS_32.\n - cmap: The color mapping to be used for generating the pseudo color image, default is Cmap::WHITE_HOT.\n - temp_min: The minimum reference temperature (in \u00b0C) for generating the pseudo color image. Default is -1.\n - temp_max: The maximum reference temperature (in \u00b0C) for generating the pseudo color image. Default is -1.\nIf both max and min are equal, it operates in auto mode:\nthe maximum temperature in the frame is taken as the maximum reference temperature,\nand the minimum temperature in the frame is taken as the minimum reference temperature.\n - emissivity: The emissivity parameter for the MLX90640, default is 0.95.\n" + }, + "args": [ + [ + "int", + "i2c_bus_num", + null + ], + [ + "::maix::ext_dev::mlx90640::FPS", + "fps", + "::maix::ext_dev::mlx90640::FPS::FPS_32" + ], + [ + "::maix::ext_dev::mlx90640::Cmap", + "cmap", + "::maix::ext_dev::mlx90640::Cmap::WHITE_HOT" + ], + [ + "float", + "temp_min", + "-1" + ], + [ + "float", + "temp_max", + "-1" + ], + [ + "float", + "emissivity", + "0.95" + ] + ], + "ret_type": null, + "static": false, + "def": "MLX90640Celsius(int i2c_bus_num,\n ::maix::ext_dev::mlx90640::FPS fps=::maix::ext_dev::mlx90640::FPS::FPS_32,\n ::maix::ext_dev::mlx90640::Cmap cmap=::maix::ext_dev::mlx90640::Cmap::WHITE_HOT,\n float temp_min=-1, float temp_max=-1, float emissivity=0.95)" + }, + "matrix": { + "type": "func", + "name": "matrix", + "doc": { + "brief": "Retrieves sensor data and returns a temperature matrix of size MLX_H * MLX_W\\nMLX_W: 32\\n---------------\\n|\\nMLX_H |\\n: 24 |\\nThe matrix structure is represented as list[MLX_H][MLX_W],\\nwhere MLX_H is the number of rows (24) and MLX_W is the number of columns (32).", + "return": "CMatrix containing the temperature data, or an empty matrix ([]) if the operation fails.", + "maixpy": "maix.ext_dev.mlx90640.MLX90640Celsius.matrix", + "py_doc": "Retrieves sensor data and returns a temperature matrix of size MLX_H * MLX_W\nMLX_W: 32\n---------------\n|\nMLX_H |\n: 24 |\nThe matrix structure is represented as list[MLX_H][MLX_W],\nwhere MLX_H is the number of rows (24) and MLX_W is the number of columns (32).\n\nReturns: CMatrix containing the temperature data, or an empty matrix ([]) if the operation fails.\n" + }, + "args": [], + "ret_type": "CMatrix", + "static": false, + "def": "CMatrix matrix()" + }, + "image": { + "type": "func", + "name": "image", + "doc": { + "brief": "Obtains sensor data and converts it into a pseudo-color image\\nThis function retrieves the thermal data from the sensor and processes it\\nto generate a pseudo-color representation of the temperature distribution.", + "return": "maix::image::Image* A raw pointer to a maix image object.\nIt is the responsibility of the caller to free this memory\nin C/C++ to prevent memory leaks.", + "maixpy": "maix.ext_dev.mlx90640.MLX90640Celsius.image", + "py_doc": "Obtains sensor data and converts it into a pseudo-color image\nThis function retrieves the thermal data from the sensor and processes it\nto generate a pseudo-color representation of the temperature distribution.\n\nReturns: maix::image::Image* A raw pointer to a maix image object.\nIt is the responsibility of the caller to free this memory\nin C/C++ to prevent memory leaks.\n" + }, + "args": [], + "ret_type": "::maix::image::Image*", + "static": false, + "def": "::maix::image::Image* image()" + }, + "min_temp_point": { + "type": "func", + "name": "min_temp_point", + "doc": { + "brief": "Finds the pixel with the minimum temperature from the most recent reading\\nThis function identifies the pixel with the minimum temperature\\nfrom the latest data obtained from the sensor.", + "return": "Point A tuple of type , representing\n(x, y, temperature) of the pixel with the minimum temperature.\nIf the operation fails, the return values will be x, y < 0.", + "maixpy": "maix.ext_dev.mlx90640.MLX90640Celsius.min_temp_point", + "py_doc": "Finds the pixel with the minimum temperature from the most recent reading\nThis function identifies the pixel with the minimum temperature\nfrom the latest data obtained from the sensor.\n\nReturns: Point A tuple of type , representing\n(x, y, temperature) of the pixel with the minimum temperature.\nIf the operation fails, the return values will be x, y < 0.\n" + }, + "args": [], + "ret_type": "Point", + "static": false, + "def": "Point min_temp_point()" + }, + "max_temp_point": { + "type": "func", + "name": "max_temp_point", + "doc": { + "brief": "Finds the pixel with the maximum temperature from the most recent reading\\nThis function identifies the pixel with the maximum temperature\\nfrom the latest data obtained from the sensor.", + "return": "Point A tuple of type , representing\n(x, y, temperature) of the pixel with the maximum temperature.\nIf the operation fails, the return values will be x, y < 0.", + "maixpy": "maix.ext_dev.mlx90640.MLX90640Celsius.max_temp_point", + "py_doc": "Finds the pixel with the maximum temperature from the most recent reading\nThis function identifies the pixel with the maximum temperature\nfrom the latest data obtained from the sensor.\n\nReturns: Point A tuple of type , representing\n(x, y, temperature) of the pixel with the maximum temperature.\nIf the operation fails, the return values will be x, y < 0.\n" + }, + "args": [], + "ret_type": "Point", + "static": false, + "def": "Point max_temp_point()" + }, + "center_point": { + "type": "func", + "name": "center_point", + "doc": { + "brief": "Finds the center pixel from the most recent reading\\nThis function determines the center pixel of the temperature matrix\\nbased on the most recent data obtained from the sensor.", + "return": "Point A tuple of type , representing\n(x, y, temperature) of the center pixel in the temperature matrix.\nIf the operation fails, the return values will be x, y < 0.", + "maixpy": "maix.ext_dev.mlx90640.MLX90640Celsius.center_point", + "py_doc": "Finds the center pixel from the most recent reading\nThis function determines the center pixel of the temperature matrix\nbased on the most recent data obtained from the sensor.\n\nReturns: Point A tuple of type , representing\n(x, y, temperature) of the center pixel in the temperature matrix.\nIf the operation fails, the return values will be x, y < 0.\n" + }, + "args": [], + "ret_type": "Point", + "static": false, + "def": "Point center_point()" + }, + "image_from": { + "type": "func", + "name": "image_from", + "doc": { + "brief": "Converts a given matrix of temperature data into an image\\nThis function takes a temperature matrix and generates\\na corresponding image representation based on the\\nconfigured color map and other parameters.", + "param": { + "matrix": "The temperature matrix to be converted." + }, + "return": "maix::image::Image* A pointer to the generated image.\nIt is the responsibility of the caller to free this memory\nin C/C++ to prevent memory leaks.", + "maixpy": "maix.ext_dev.mlx90640.MLX90640Celsius.image_from", + "py_doc": "Converts a given matrix of temperature data into an image\nThis function takes a temperature matrix and generates\na corresponding image representation based on the\nconfigured color map and other parameters.\n\nArgs:\n - matrix: The temperature matrix to be converted.\n\n\nReturns: maix::image::Image* A pointer to the generated image.\nIt is the responsibility of the caller to free this memory\nin C/C++ to prevent memory leaks.\n" + }, + "args": [ + [ + "const CMatrix&", + "matrix", + null + ] + ], + "ret_type": "::maix::image::Image*", + "static": false, + "def": "::maix::image::Image* image_from(const CMatrix& matrix)" + }, + "max_temp_point_from": { + "type": "func", + "name": "max_temp_point_from", + "doc": { + "brief": "Finds the pixel with the maximum temperature from the given matrix\\nThis static function identifies the pixel with the maximum temperature\\nfrom the specified temperature matrix.", + "param": { + "matrix": "The temperature matrix to be analyzed." + }, + "return": "Point A tuple of type , representing\n(x, y, temperature) of the pixel with the maximum temperature.\nIf the operation fails, the return values will be x, y < 0.", + "maixpy": "maix.ext_dev.mlx90640.MLX90640Celsius.max_temp_point_from", + "py_doc": "Finds the pixel with the maximum temperature from the given matrix\nThis static function identifies the pixel with the maximum temperature\nfrom the specified temperature matrix.\n\nArgs:\n - matrix: The temperature matrix to be analyzed.\n\n\nReturns: Point A tuple of type , representing\n(x, y, temperature) of the pixel with the maximum temperature.\nIf the operation fails, the return values will be x, y < 0.\n" + }, + "args": [ + [ + "const CMatrix&", + "matrix", + null + ] + ], + "ret_type": "Point", + "static": true, + "def": "static Point max_temp_point_from(const CMatrix& matrix)" + }, + "min_temp_point_from": { + "type": "func", + "name": "min_temp_point_from", + "doc": { + "brief": "Finds the pixel with the minimum temperature from the given matrix\\nThis static function identifies the pixel with the minimum temperature\\nfrom the specified temperature matrix.", + "param": { + "matrix": "The temperature matrix to be analyzed." + }, + "return": "Point A tuple of type , representing\n(x, y, temperature) of the pixel with the minimum temperature.\nIf the operation fails, the return values will be x, y < 0.", + "maixpy": "maix.ext_dev.mlx90640.MLX90640Celsius.min_temp_point_from", + "py_doc": "Finds the pixel with the minimum temperature from the given matrix\nThis static function identifies the pixel with the minimum temperature\nfrom the specified temperature matrix.\n\nArgs:\n - matrix: The temperature matrix to be analyzed.\n\n\nReturns: Point A tuple of type , representing\n(x, y, temperature) of the pixel with the minimum temperature.\nIf the operation fails, the return values will be x, y < 0.\n" + }, + "args": [ + [ + "const CMatrix&", + "matrix", + null + ] + ], + "ret_type": "Point", + "static": true, + "def": "static Point min_temp_point_from(const CMatrix& matrix)" + }, + "center_point_from": { + "type": "func", + "name": "center_point_from", + "doc": { + "brief": "Finds the center pixel from the given matrix\\nThis static function determines the center pixel of the\\nspecified temperature matrix based on its dimensions.", + "param": { + "matrix": "The temperature matrix to be analyzed." + }, + "return": "Point A tuple of type , representing\n(x, y, temperature) of the center pixel in the matrix.\nIf the operation fails, the return values will be x, y < 0.", + "maixpy": "maix.ext_dev.mlx90640.MLX90640Celsius.center_point_from", + "py_doc": "Finds the center pixel from the given matrix\nThis static function determines the center pixel of the\nspecified temperature matrix based on its dimensions.\n\nArgs:\n - matrix: The temperature matrix to be analyzed.\n\n\nReturns: Point A tuple of type , representing\n(x, y, temperature) of the center pixel in the matrix.\nIf the operation fails, the return values will be x, y < 0.\n" + }, + "args": [ + [ + "const CMatrix&", + "matrix", + null + ] + ], + "ret_type": "Point", + "static": true, + "def": "static Point center_point_from(const CMatrix& matrix)" + } + }, + "def": "class MLX90640Celsius final" + }, + "MLX90640Kelvin": { + "type": "class", + "name": "MLX90640Kelvin", + "doc": { + "brief": "MLX90640 (K))", + "maixpy": "maix.ext_dev.mlx90640.MLX90640Kelvin", + "py_doc": "MLX90640 (K))" + }, + "members": { + "__init__": { + "type": "func", + "name": "MLX90640Kelvin", + "doc": { + "brief": "Construct a new MLX90640Kelvin object\\nThis constructor initializes an MLX90640Kelvin object with the specified parameters\\nto configure the I2C bus communication, frame rate, color mapping, temperature ranges,\\nand emissivity for the MLX90640 thermal camera.", + "param": { + "i2c_bus_num": "The I2C bus number to which the MLX90640 is connected.", + "fps": "The preferred frame rate for the MLX90640, default is FPS::FPS_32.", + "cmap": "The color mapping to be used for generating the pseudo color image, default is Cmap::WHITE_HOT.", + "temp_min": "The minimum reference temperature (in K) for generating the pseudo color image. Default is -1.", + "temp_max": "The maximum reference temperature (in K) for generating the pseudo color image. Default is -1.\nIf both max and min are equal, it operates in auto mode:\nthe maximum temperature in the frame is taken as the maximum reference temperature,\nand the minimum temperature in the frame is taken as the minimum reference temperature.", + "emissivity": "The emissivity parameter for the MLX90640, default is 0.95." + }, + "maixpy": "maix.ext_dev.mlx90640.MLX90640Kelvin.__init__", + "py_doc": "Construct a new MLX90640Kelvin object\nThis constructor initializes an MLX90640Kelvin object with the specified parameters\nto configure the I2C bus communication, frame rate, color mapping, temperature ranges,\nand emissivity for the MLX90640 thermal camera.\n\nArgs:\n - i2c_bus_num: The I2C bus number to which the MLX90640 is connected.\n - fps: The preferred frame rate for the MLX90640, default is FPS::FPS_32.\n - cmap: The color mapping to be used for generating the pseudo color image, default is Cmap::WHITE_HOT.\n - temp_min: The minimum reference temperature (in K) for generating the pseudo color image. Default is -1.\n - temp_max: The maximum reference temperature (in K) for generating the pseudo color image. Default is -1.\nIf both max and min are equal, it operates in auto mode:\nthe maximum temperature in the frame is taken as the maximum reference temperature,\nand the minimum temperature in the frame is taken as the minimum reference temperature.\n - emissivity: The emissivity parameter for the MLX90640, default is 0.95.\n" + }, + "args": [ + [ + "int", + "i2c_bus_num", + null + ], + [ + "::maix::ext_dev::mlx90640::FPS", + "fps", + "::maix::ext_dev::mlx90640::FPS::FPS_32" + ], + [ + "::maix::ext_dev::mlx90640::Cmap", + "cmap", + "::maix::ext_dev::mlx90640::Cmap::WHITE_HOT" + ], + [ + "float", + "temp_min", + "-1" + ], + [ + "float", + "temp_max", + "-1" + ], + [ + "float", + "emissivity", + "0.95" + ] + ], + "ret_type": null, + "static": false, + "def": "MLX90640Kelvin( int i2c_bus_num,\n ::maix::ext_dev::mlx90640::FPS fps=::maix::ext_dev::mlx90640::FPS::FPS_32,\n ::maix::ext_dev::mlx90640::Cmap cmap=::maix::ext_dev::mlx90640::Cmap::WHITE_HOT,\n float temp_min=-1, float temp_max=-1, float emissivity=0.95)" + }, + "matrix": { + "type": "func", + "name": "matrix", + "doc": { + "brief": "Retrieves sensor data and returns a temperature matrix of size MLX_H * MLX_W\\nMLX_W: 32\\n---------------\\n|\\nMLX_H |\\n: 24 |\\nThe matrix structure is represented as list[MLX_H][MLX_W],\\nwhere MLX_H is the number of rows (24) and MLX_W is the number of columns (32).", + "return": "KMatrix containing the temperature data, or an empty matrix ([]) if the operation fails.", + "maixpy": "maix.ext_dev.mlx90640.MLX90640Kelvin.matrix", + "py_doc": "Retrieves sensor data and returns a temperature matrix of size MLX_H * MLX_W\nMLX_W: 32\n---------------\n|\nMLX_H |\n: 24 |\nThe matrix structure is represented as list[MLX_H][MLX_W],\nwhere MLX_H is the number of rows (24) and MLX_W is the number of columns (32).\n\nReturns: KMatrix containing the temperature data, or an empty matrix ([]) if the operation fails.\n" + }, + "args": [], + "ret_type": "KMatrix", + "static": false, + "def": "KMatrix matrix()" + }, + "image": { + "type": "func", + "name": "image", + "doc": { + "brief": "Obtains sensor data and converts it into a pseudo-color image\\nThis function retrieves the thermal data from the sensor and processes it\\nto generate a pseudo-color representation of the temperature distribution.", + "return": "maix::image::Image* A raw pointer to a maix image object.\nIt is the responsibility of the caller to free this memory\nin C/C++ to prevent memory leaks.", + "maixpy": "maix.ext_dev.mlx90640.MLX90640Kelvin.image", + "py_doc": "Obtains sensor data and converts it into a pseudo-color image\nThis function retrieves the thermal data from the sensor and processes it\nto generate a pseudo-color representation of the temperature distribution.\n\nReturns: maix::image::Image* A raw pointer to a maix image object.\nIt is the responsibility of the caller to free this memory\nin C/C++ to prevent memory leaks.\n" + }, + "args": [], + "ret_type": "::maix::image::Image*", + "static": false, + "def": "::maix::image::Image* image()" + }, + "max_temp_point": { + "type": "func", + "name": "max_temp_point", + "doc": { + "brief": "Finds the pixel with the minimum temperature from the most recent reading\\nThis function identifies the pixel with the minimum temperature\\nfrom the latest data obtained from the sensor.", + "return": "Point A tuple of type , representing\n(x, y, temperature) of the pixel with the minimum temperature.\nIf the operation fails, the return values will be x, y < 0.", + "maixpy": "maix.ext_dev.mlx90640.MLX90640Kelvin.max_temp_point", + "py_doc": "Finds the pixel with the minimum temperature from the most recent reading\nThis function identifies the pixel with the minimum temperature\nfrom the latest data obtained from the sensor.\n\nReturns: Point A tuple of type , representing\n(x, y, temperature) of the pixel with the minimum temperature.\nIf the operation fails, the return values will be x, y < 0.\n" + }, + "args": [], + "ret_type": "Point", + "static": false, + "def": "Point max_temp_point()" + }, + "min_temp_point": { + "type": "func", + "name": "min_temp_point", + "doc": { + "brief": "Finds the pixel with the maximum temperature from the most recent reading\\nThis function identifies the pixel with the maximum temperature\\nfrom the latest data obtained from the sensor.", + "return": "Point A tuple of type , representing\n(x, y, temperature) of the pixel with the maximum temperature.\nIf the operation fails, the return values will be x, y < 0.", + "maixpy": "maix.ext_dev.mlx90640.MLX90640Kelvin.min_temp_point", + "py_doc": "Finds the pixel with the maximum temperature from the most recent reading\nThis function identifies the pixel with the maximum temperature\nfrom the latest data obtained from the sensor.\n\nReturns: Point A tuple of type , representing\n(x, y, temperature) of the pixel with the maximum temperature.\nIf the operation fails, the return values will be x, y < 0.\n" + }, + "args": [], + "ret_type": "Point", + "static": false, + "def": "Point min_temp_point()" + }, + "center_point": { + "type": "func", + "name": "center_point", + "doc": { + "brief": "Finds the center pixel from the most recent reading\\nThis function determines the center pixel of the temperature matrix\\nbased on the most recent data obtained from the sensor.", + "return": "Point A tuple of type , representing\n(x, y, temperature) of the center pixel in the temperature matrix.\nIf the operation fails, the return values will be x, y < 0.", + "maixpy": "maix.ext_dev.mlx90640.MLX90640Kelvin.center_point", + "py_doc": "Finds the center pixel from the most recent reading\nThis function determines the center pixel of the temperature matrix\nbased on the most recent data obtained from the sensor.\n\nReturns: Point A tuple of type , representing\n(x, y, temperature) of the center pixel in the temperature matrix.\nIf the operation fails, the return values will be x, y < 0.\n" + }, + "args": [], + "ret_type": "Point", + "static": false, + "def": "Point center_point()" + }, + "image_from": { + "type": "func", + "name": "image_from", + "doc": { + "brief": "Converts a given matrix of temperature data into an image\\nThis function takes a temperature matrix and generates\\na corresponding image representation based on the\\nconfigured color map and other parameters.", + "param": { + "matrix": "The temperature matrix to be converted." + }, + "return": "maix::image::Image* A pointer to the generated image.\nIt is the responsibility of the caller to free this memory\nin C/C++ to prevent memory leaks.", + "maixpy": "maix.ext_dev.mlx90640.MLX90640Kelvin.image_from", + "py_doc": "Converts a given matrix of temperature data into an image\nThis function takes a temperature matrix and generates\na corresponding image representation based on the\nconfigured color map and other parameters.\n\nArgs:\n - matrix: The temperature matrix to be converted.\n\n\nReturns: maix::image::Image* A pointer to the generated image.\nIt is the responsibility of the caller to free this memory\nin C/C++ to prevent memory leaks.\n" + }, + "args": [ + [ + "const KMatrix&", + "matrix", + null + ] + ], + "ret_type": "::maix::image::Image*", + "static": false, + "def": "::maix::image::Image* image_from(const KMatrix& matrix)" + }, + "max_temp_point_from": { + "type": "func", + "name": "max_temp_point_from", + "doc": { + "brief": "Finds the pixel with the maximum temperature from the given matrix\\nThis static function identifies the pixel with the maximum temperature\\nfrom the specified temperature matrix.", + "param": { + "matrix": "The temperature matrix to be analyzed." + }, + "return": "Point A tuple of type , representing\n(x, y, temperature) of the pixel with the maximum temperature.\nIf the operation fails, the return values will be x, y < 0.", + "maixpy": "maix.ext_dev.mlx90640.MLX90640Kelvin.max_temp_point_from", + "py_doc": "Finds the pixel with the maximum temperature from the given matrix\nThis static function identifies the pixel with the maximum temperature\nfrom the specified temperature matrix.\n\nArgs:\n - matrix: The temperature matrix to be analyzed.\n\n\nReturns: Point A tuple of type , representing\n(x, y, temperature) of the pixel with the maximum temperature.\nIf the operation fails, the return values will be x, y < 0.\n" + }, + "args": [ + [ + "const KMatrix&", + "matrix", + null + ] + ], + "ret_type": "Point", + "static": true, + "def": "static Point max_temp_point_from(const KMatrix& matrix)" + }, + "min_temp_point_from": { + "type": "func", + "name": "min_temp_point_from", + "doc": { + "brief": "Finds the pixel with the minimum temperature from the given matrix\\nThis static function identifies the pixel with the minimum temperature\\nfrom the specified temperature matrix.", + "param": { + "matrix": "The temperature matrix to be analyzed." + }, + "return": "Point A tuple of type , representing\n(x, y, temperature) of the pixel with the minimum temperature.\nIf the operation fails, the return values will be x, y < 0.", + "maixpy": "maix.ext_dev.mlx90640.MLX90640Kelvin.min_temp_point_from", + "py_doc": "Finds the pixel with the minimum temperature from the given matrix\nThis static function identifies the pixel with the minimum temperature\nfrom the specified temperature matrix.\n\nArgs:\n - matrix: The temperature matrix to be analyzed.\n\n\nReturns: Point A tuple of type , representing\n(x, y, temperature) of the pixel with the minimum temperature.\nIf the operation fails, the return values will be x, y < 0.\n" + }, + "args": [ + [ + "const KMatrix&", + "matrix", + null + ] + ], + "ret_type": "Point", + "static": true, + "def": "static Point min_temp_point_from(const KMatrix& matrix)" + }, + "center_point_from": { + "type": "func", + "name": "center_point_from", + "doc": { + "brief": "Finds the center pixel from the given matrix\\nThis static function determines the center pixel of the\\nspecified temperature matrix based on its dimensions.", + "param": { + "matrix": "The temperature matrix to be analyzed." + }, + "return": "Point A tuple of type , representing\n(x, y, temperature) of the center pixel in the matrix.\nIf the operation fails, the return values will be x, y < 0.", + "maixpy": "maix.ext_dev.mlx90640.MLX90640Kelvin.center_point_from", + "py_doc": "Finds the center pixel from the given matrix\nThis static function determines the center pixel of the\nspecified temperature matrix based on its dimensions.\n\nArgs:\n - matrix: The temperature matrix to be analyzed.\n\n\nReturns: Point A tuple of type , representing\n(x, y, temperature) of the center pixel in the matrix.\nIf the operation fails, the return values will be x, y < 0.\n" + }, + "args": [ + [ + "const KMatrix&", + "matrix", + null + ] + ], + "ret_type": "Point", + "static": true, + "def": "static Point center_point_from(const KMatrix& matrix)" + } + }, + "def": "class MLX90640Kelvin final" + } + }, + "auto_add": true + }, + "fp5510": { + "type": "module", + "doc": { + "brief": "maix.ext_dev.fp5510 module" + }, + "members": { + "FP5510": { + "type": "class", + "name": "FP5510", + "doc": { + "brief": "FP5510 class", + "maixpy": "maix.ext_dev.fp5510.FP5510", + "py_doc": "FP5510 class" + }, + "members": { + "__init__": { + "type": "func", + "name": "FP5510", + "doc": { + "brief": "Construct a new FP5510 object", + "param": { + "id": "iic number, default is 4", + "slave_addr": "slave address of fp5510, default is 0x0c.", + "freq": "iic frequency, default is 400k" + }, + "maixpy": "maix.ext_dev.fp5510.FP5510.__init__", + "py_doc": "Construct a new FP5510 object\n\nArgs:\n - id: iic number, default is 4\n - slave_addr: slave address of fp5510, default is 0x0c.\n - freq: iic frequency, default is 400k\n" + }, + "args": [ + [ + "int", + "id", + "4" + ], + [ + "int", + "slave_addr", + "0x0c" + ], + [ + "int", + "freq", + "400000" + ] + ], + "ret_type": null, + "static": false, + "def": "FP5510(int id = 4, int slave_addr = 0x0c, int freq = 400000)" + }, + "set_pos": { + "type": "func", + "name": "set_pos", + "doc": { + "brief": "Set fp5510 position", + "param": { + "pos": "the position of fp5510, range is [0, 1023]" + }, + "maixpy": "maix.ext_dev.fp5510.FP5510.set_pos", + "py_doc": "Set fp5510 position\n\nArgs:\n - pos: the position of fp5510, range is [0, 1023]\n" + }, + "args": [ + [ + "uint32_t", + "pos", + null + ] + ], + "ret_type": "void", + "static": false, + "def": "void set_pos(uint32_t pos)" + }, + "get_pos": { + "type": "func", + "name": "get_pos", + "doc": { + "brief": "Get fp5510 position", + "return": "returns the position of fp5510, range is [0, 1023]", + "maixpy": "maix.ext_dev.fp5510.FP5510.get_pos", + "py_doc": "Get fp5510 position\n\nReturns: returns the position of fp5510, range is [0, 1023]\n" + }, + "args": [], + "ret_type": "uint32_t", + "static": false, + "def": "uint32_t get_pos()" + } + }, + "def": "class FP5510" + } + }, + "auto_add": true + }, + "imu": { + "type": "module", + "doc": { + "brief": "maix.ext_dev.imu module" + }, + "members": { + "Mode": { + "type": "enum", + "name": "class", + "doc": { + "brief": "imu mode", + "maixpy": "maix.ext_dev.imu.Mode", + "py_doc": "imu mode" + }, + "values": [ + [ + "ACC_ONLY", + "0", + "" + ], + [ + "GYRO_ONLY", + "", + "" + ], + [ + "DUAL", + "", + "" + ] + ], + "def": "enum class Mode {\n ACC_ONLY = 0,\n GYRO_ONLY,\n DUAL\n}" + }, + "AccScale": { + "type": "enum", + "name": "class", + "doc": { + "brief": "imu acc scale", + "maixpy": "maix.ext_dev.imu.AccScale", + "py_doc": "imu acc scale" + }, + "values": [ + [ + "ACC_SCALE_2G", + "0", + "" + ], + [ + "ACC_SCALE_4G", + "", + "" + ], + [ + "ACC_SCALE_8G", + "", + "" + ], + [ + "ACC_SCALE_16G", + "", + "" + ] + ], + "def": "enum class AccScale {\n ACC_SCALE_2G = 0,\n ACC_SCALE_4G,\n ACC_SCALE_8G,\n ACC_SCALE_16G\n}" + }, + "AccOdr": { + "type": "enum", + "name": "class", + "doc": { + "brief": "imu acc output data rate", + "maixpy": "maix.ext_dev.imu.AccOdr", + "py_doc": "imu acc output data rate" + }, + "values": [ + [ + "ACC_ODR_8000", + "", + "Accelerometer ODR set to 8000 Hz." + ], + [ + "ACC_ODR_4000", + "", + "Accelerometer ODR set to 4000 Hz." + ], + [ + "ACC_ODR_2000", + "", + "Accelerometer ODR set to 2000 Hz." + ], + [ + "ACC_ODR_1000", + "", + "Accelerometer ODR set to 1000 Hz." + ], + [ + "ACC_ODR_500", + "", + "Accelerometer ODR set to 500 Hz." + ], + [ + "ACC_ODR_250", + "", + "Accelerometer ODR set to 250 Hz." + ], + [ + "ACC_ODR_125", + "", + "Accelerometer ODR set to 125 Hz." + ], + [ + "ACC_ODR_62_5", + "", + "Accelerometer ODR set to 62.5 Hz." + ], + [ + "ACC_ODR_31_25", + "", + "Accelerometer ODR set to 31.25 Hz." + ], + [ + "ACC_ODR_128", + "12", + "Accelerometer ODR set to 128 Hz." + ], + [ + "ACC_ODR_21", + "", + "Accelerometer ODR set to 21 Hz." + ], + [ + "ACC_ODR_11", + "", + "Accelerometer ODR set to 11 Hz." + ], + [ + "ACC_ODR_3", + "", + "Accelerometer ODR set to 3 Hz." + ] + ], + "def": "enum class AccOdr {\n ACC_ODR_8000, // Accelerometer ODR set to 8000 Hz.\n ACC_ODR_4000, // Accelerometer ODR set to 4000 Hz.\n ACC_ODR_2000, // Accelerometer ODR set to 2000 Hz.\n ACC_ODR_1000, // Accelerometer ODR set to 1000 Hz.\n ACC_ODR_500, // Accelerometer ODR set to 500 Hz.\n ACC_ODR_250, // Accelerometer ODR set to 250 Hz.\n ACC_ODR_125, // Accelerometer ODR set to 125 Hz.\n ACC_ODR_62_5, // Accelerometer ODR set to 62.5 Hz.\n ACC_ODR_31_25, // Accelerometer ODR set to 31.25 Hz.\n ACC_ODR_128 = 12, // Accelerometer ODR set to 128 Hz.\n ACC_ODR_21, // Accelerometer ODR set to 21 Hz.\n ACC_ODR_11, // Accelerometer ODR set to 11 Hz.\n ACC_ODR_3, // Accelerometer ODR set to 3 Hz.\n}" + }, + "GyroScale": { + "type": "enum", + "name": "class", + "doc": { + "brief": "imu gyro scale", + "maixpy": "maix.ext_dev.imu.GyroScale", + "py_doc": "imu gyro scale" + }, + "values": [ + [ + "GYRO_SCALE_16DPS", + "0", + "Gyroscope scale set to \u00b116 degrees per second." + ], + [ + "GYRO_SCALE_32DPS", + "", + "Gyroscope scale set to \u00b132 degrees per second." + ], + [ + "GYRO_SCALE_64DPS", + "", + "Gyroscope scale set to \u00b164 degrees per second." + ], + [ + "GYRO_SCALE_128DPS", + "", + "Gyroscope scale set to \u00b1128 degrees per second." + ], + [ + "GYRO_SCALE_256DPS", + "", + "Gyroscope scale set to \u00b1256 degrees per second." + ], + [ + "GYRO_SCALE_512DPS", + "", + "Gyroscope scale set to \u00b1512 degrees per second." + ], + [ + "GYRO_SCALE_1024DPS", + "", + "Gyroscope scale set to \u00b11024 degrees per second." + ], + [ + "GYRO_SCALE_2048DPS", + "", + "Gyroscope scale set to \u00b12048 degrees per second." + ] + ], + "def": "enum class GyroScale {\n GYRO_SCALE_16DPS = 0, // Gyroscope scale set to \u00b116 degrees per second.\n GYRO_SCALE_32DPS, // Gyroscope scale set to \u00b132 degrees per second.\n GYRO_SCALE_64DPS, // Gyroscope scale set to \u00b164 degrees per second.\n GYRO_SCALE_128DPS, // Gyroscope scale set to \u00b1128 degrees per second.\n GYRO_SCALE_256DPS, // Gyroscope scale set to \u00b1256 degrees per second.\n GYRO_SCALE_512DPS, // Gyroscope scale set to \u00b1512 degrees per second.\n GYRO_SCALE_1024DPS, // Gyroscope scale set to \u00b11024 degrees per second.\n GYRO_SCALE_2048DPS, // Gyroscope scale set to \u00b12048 degrees per second.\n}" + }, + "GyroOdr": { + "type": "enum", + "name": "class", + "doc": { + "brief": "imu gyro output data rate", + "maixpy": "maix.ext_dev.imu.GyroOdr", + "py_doc": "imu gyro output data rate" + }, + "values": [ + [ + "GYRO_ODR_8000", + "", + "Gyroscope ODR set to 8000 Hz." + ], + [ + "GYRO_ODR_4000", + "", + "Gyroscope ODR set to 4000 Hz." + ], + [ + "GYRO_ODR_2000", + "", + "Gyroscope ODR set to 2000 Hz." + ], + [ + "GYRO_ODR_1000", + "", + "Gyroscope ODR set to 1000 Hz." + ], + [ + "GYRO_ODR_500", + "", + "Gyroscope ODR set to 500 Hz." + ], + [ + "GYRO_ODR_250", + "", + "Gyroscope ODR set to 250 Hz." + ], + [ + "GYRO_ODR_125", + "", + "Gyroscope ODR set to 125 Hz." + ], + [ + "GYRO_ODR_62_5", + "", + "Gyroscope ODR set to 62.5 Hz." + ], + [ + "GYRO_ODR_31_25", + "", + "Gyroscope ODR set to 31.25 Hz." + ] + ], + "def": "enum class GyroOdr {\n GYRO_ODR_8000, // Gyroscope ODR set to 8000 Hz.\n GYRO_ODR_4000, // Gyroscope ODR set to 4000 Hz.\n GYRO_ODR_2000, // Gyroscope ODR set to 2000 Hz.\n GYRO_ODR_1000, // Gyroscope ODR set to 1000 Hz.\n GYRO_ODR_500, // Gyroscope ODR set to 500 Hz.\n GYRO_ODR_250, // Gyroscope ODR set to 250 Hz.\n GYRO_ODR_125, // Gyroscope ODR set to 125 Hz.\n GYRO_ODR_62_5, // Gyroscope ODR set to 62.5 Hz.\n GYRO_ODR_31_25, // Gyroscope ODR set to 31.25 Hz.\n}" + }, + "IMU": { + "type": "class", + "name": "IMU", + "doc": { + "brief": "QMI8656 driver class", + "maixpy": "maix.ext_dev.imu.IMU", + "py_doc": "QMI8656 driver class" + }, + "members": { + "__init__": { + "type": "func", + "name": "IMU", + "doc": { + "brief": "Construct a new IMU object, will open IMU", + "param": { + "driver": "driver name, only support \"qmi8656\"", + "i2c_bus": "i2c bus number. Automatically selects the on-board imu when -1 is passed in.", + "addr": "IMU i2c addr.", + "freq": "IMU freq", + "mode": "IMU Mode: ACC_ONLY/GYRO_ONLY/DUAL", + "acc_scale": "acc scale, see @imu::AccScale", + "acc_odr": "acc output data rate, see @imu::AccOdr", + "gyro_scale": "gyro scale, see @imu::GyroScale", + "gyro_odr": "gyro output data rate, see @imu::GyroOdr", + "block": "block or non-block, defalut is true" + }, + "maixpy": "maix.ext_dev.imu.IMU.__init__", + "py_doc": "Construct a new IMU object, will open IMU\n\nArgs:\n - driver: driver name, only support \"qmi8656\"\n - i2c_bus: i2c bus number. Automatically selects the on-board imu when -1 is passed in.\n - addr: IMU i2c addr.\n - freq: IMU freq\n - mode: IMU Mode: ACC_ONLY/GYRO_ONLY/DUAL\n - acc_scale: acc scale, see @imu::AccScale\n - acc_odr: acc output data rate, see @imu::AccOdr\n - gyro_scale: gyro scale, see @imu::GyroScale\n - gyro_odr: gyro output data rate, see @imu::GyroOdr\n - block: block or non-block, defalut is true\n" + }, + "args": [ + [ + "std::string", + "driver", + null + ], + [ + "int", + "i2c_bus", + "-1" + ], + [ + "int", + "addr", + "0x6B" + ], + [ + "int", + "freq", + "400000" + ], + [ + "maix::ext_dev::imu::Mode", + "mode", + "maix::ext_dev::imu::Mode::DUAL" + ], + [ + "maix::ext_dev::imu::AccScale", + "acc_scale", + "maix::ext_dev::imu::AccScale::ACC_SCALE_2G" + ], + [ + "maix::ext_dev::imu::AccOdr", + "acc_odr", + "maix::ext_dev::imu::AccOdr::ACC_ODR_8000" + ], + [ + "maix::ext_dev::imu::GyroScale", + "gyro_scale", + "maix::ext_dev::imu::GyroScale::GYRO_SCALE_16DPS" + ], + [ + "maix::ext_dev::imu::GyroOdr", + "gyro_odr", + "maix::ext_dev::imu::GyroOdr::GYRO_ODR_8000" + ], + [ + "bool", + "block", + "true" + ] + ], + "ret_type": null, + "static": false, + "def": "IMU(std::string driver, int i2c_bus=-1, int addr=0x6B, int freq=400000,\n maix::ext_dev::imu::Mode mode=maix::ext_dev::imu::Mode::DUAL,\n maix::ext_dev::imu::AccScale acc_scale=maix::ext_dev::imu::AccScale::ACC_SCALE_2G,\n maix::ext_dev::imu::AccOdr acc_odr=maix::ext_dev::imu::AccOdr::ACC_ODR_8000,\n maix::ext_dev::imu::GyroScale gyro_scale=maix::ext_dev::imu::GyroScale::GYRO_SCALE_16DPS,\n maix::ext_dev::imu::GyroOdr gyro_odr=maix::ext_dev::imu::GyroOdr::GYRO_ODR_8000,\n bool block=true)" + }, + "read": { + "type": "func", + "name": "read", + "doc": { + "brief": "Read data from IMU.", + "return": "list type. If only one of the outputs is initialized, only [x,y,z] of that output will be returned.\nIf all outputs are initialized, [acc_x, acc_y, acc_z, gyro_x, gyro_y, gyro_z] is returned.", + "maixpy": "maix.ext_dev.imu.IMU.read", + "py_doc": "Read data from IMU.\n\nReturns: list type. If only one of the outputs is initialized, only [x,y,z] of that output will be returned.\nIf all outputs are initialized, [acc_x, acc_y, acc_z, gyro_x, gyro_y, gyro_z] is returned.\n" + }, + "args": [], + "ret_type": "std::vector", + "static": false, + "def": "std::vector read()" + }, + "calculate_calibration": { + "type": "func", + "name": "calculate_calibration", + "doc": { + "brief": "Caculate calibration, save calibration data to /maixapp/shart/imu_calibration", + "param": { + "time_ms": "caculate max time, unit:ms" + }, + "return": "err::Err", + "maixpy": "maix.ext_dev.imu.IMU.calculate_calibration", + "py_doc": "Caculate calibration, save calibration data to /maixapp/shart/imu_calibration\n\nArgs:\n - time_ms: caculate max time, unit:ms\n\n\nReturns: err::Err\n" + }, + "args": [ + [ + "uint64_t", + "time_ms", + "30 * 1000" + ] + ], + "ret_type": "err::Err", + "static": false, + "def": "err::Err calculate_calibration(uint64_t time_ms = 30 * 1000)" + }, + "get_calibration": { + "type": "func", + "name": "get_calibration", + "doc": { + "brief": "Get calibration data", + "return": "return an array, format is [acc_x_bias, acc_y_bias, acc_z_bias, gyro_x_bias, gyro_y_bias, gyro_z_bias]\nIf the calibration file cannot be found, an empty array will be returned.", + "maixpy": "maix.ext_dev.imu.IMU.get_calibration", + "py_doc": "Get calibration data\n\nReturns: return an array, format is [acc_x_bias, acc_y_bias, acc_z_bias, gyro_x_bias, gyro_y_bias, gyro_z_bias]\nIf the calibration file cannot be found, an empty array will be returned.\n" + }, + "args": [], + "ret_type": "std::vector", + "static": false, + "def": "std::vector get_calibration()" + } + }, + "def": "class IMU" + }, + "Gcsv": { + "type": "class", + "name": "Gcsv", + "doc": { + "brief": "Gcsv class", + "maixpy": "maix.ext_dev.imu.Gcsv", + "py_doc": "Gcsv class" + }, + "members": { + "__init__": { + "type": "func", + "name": "Gcsv", + "doc": { + "brief": "Construct a new IMU object", + "maixpy": "maix.ext_dev.imu.Gcsv.__init__", + "py_doc": "Construct a new IMU object" + }, + "args": [], + "ret_type": null, + "static": false, + "def": "Gcsv()" + }, + "open": { + "type": "func", + "name": "open", + "doc": { + "brief": "Open a file", + "param": { + "path": "the path where data will be saved", + "tscale": "time scale, default is 0.001", + "gscale": "gyroscope scale factor, default is 1, unit:g", + "ascale": "accelerometer scale factor, default is 1, unit:radians/second", + "mscale": "magnetometer scale factor, default is 1(unused)", + "version": "version number, default is \"1.3\"", + "id": "identifier for the IMU, default is \"imu\"", + "orientation": "sensor orientation, default is \"YxZ\"" + }, + "return": "error code", + "maixpy": "maix.ext_dev.imu.Gcsv.open", + "py_doc": "Open a file\n\nArgs:\n - path: the path where data will be saved\n - tscale: time scale, default is 0.001\n - gscale: gyroscope scale factor, default is 1, unit:g\n - ascale: accelerometer scale factor, default is 1, unit:radians/second\n - mscale: magnetometer scale factor, default is 1(unused)\n - version: version number, default is \"1.3\"\n - id: identifier for the IMU, default is \"imu\"\n - orientation: sensor orientation, default is \"YxZ\"\n\n\nReturns: error code\n" + }, + "args": [ + [ + "std::string", + "path", + null + ], + [ + "double", + "tscale", + "0.001" + ], + [ + "double", + "gscale", + "1" + ], + [ + "double", + "ascale", + "1" + ], + [ + "double", + "mscale", + "1" + ], + [ + "std::string", + "version", + "\"1.3\"" + ], + [ + "std::string", + "id", + "\"imu\"" + ], + [ + "std::string", + "orientation", + "\"YxZ\"" + ] + ], + "ret_type": "err::Err", + "static": false, + "def": "err::Err open(std::string path, double tscale = 0.001, double gscale = 1, double ascale = 1, double mscale = 1, std::string version = \"1.3\", std::string id = \"imu\", std::string orientation = \"YxZ\")" + }, + "close": { + "type": "func", + "name": "close", + "doc": { + "brief": "Close file", + "return": "error code", + "maixpy": "maix.ext_dev.imu.Gcsv.close", + "py_doc": "Close file\n\nReturns: error code\n" + }, + "args": [], + "ret_type": "err::Err", + "static": false, + "def": "err::Err close()" + }, + "is_opened": { + "type": "func", + "name": "is_opened", + "doc": { + "brief": "Check if the object is already open", + "return": "true, opened; false, not opened", + "maixpy": "maix.ext_dev.imu.Gcsv.is_opened", + "py_doc": "Check if the object is already open\n\nReturns: true, opened; false, not opened\n" + }, + "args": [], + "ret_type": "bool", + "static": false, + "def": "bool is_opened()" + }, + "write": { + "type": "func", + "name": "write", + "doc": { + "brief": "Write imu data to gcsv file", + "param": { + "t": "Timestamp of the current data. The actual value is equal to t * tscale. unit:s", + "gyro": "Gyroscope data must be an array consisting of x, y, and z-axis data. The actual value is equal to gyro * gscale. unit:g", + "acc": "Acceleration data must be an array consisting of x, y, and z-axis data. The actual value is equal to acc * ascale.unit:radians/second", + "mag": "Magnetic data must be an array consisting of x, y, and z-axis data. Currently not supported." + }, + "maixpy": "maix.ext_dev.imu.Gcsv.write", + "py_doc": "Write imu data to gcsv file\n\nArgs:\n - t: Timestamp of the current data. The actual value is equal to t * tscale. unit:s\n - gyro: Gyroscope data must be an array consisting of x, y, and z-axis data. The actual value is equal to gyro * gscale. unit:g\n - acc: Acceleration data must be an array consisting of x, y, and z-axis data. The actual value is equal to acc * ascale.unit:radians/second\n - mag: Magnetic data must be an array consisting of x, y, and z-axis data. Currently not supported.\n" + }, + "args": [ + [ + "double", + "timestamp", + null + ], + [ + "std::vector", + "gyro", + null + ], + [ + "std::vector", + "acc", + null + ], + [ + "std::vector", + "mag", + "std::vector()" + ] + ], + "ret_type": "err::Err", + "static": false, + "def": "err::Err write(double timestamp, std::vector gyro, std::vector acc, std::vector mag = std::vector())" + } + }, + "def": "class Gcsv" + } + }, + "auto_add": true + }, + "pmu": { + "type": "module", + "doc": { + "brief": "maix.ext_dev.pmu module" + }, + "members": { + "ChargerStatus": { + "type": "enum", + "name": "class", + "doc": { + "brief": "charger status", + "maixpy": "maix.ext_dev.pmu.ChargerStatus", + "py_doc": "charger status" + }, + "values": [ + [ + "CHG_TRI_STATE", + "", + "tri_charge" + ], + [ + "CHG_PRE_STATE", + "", + "pre_charge" + ], + [ + "CHG_CC_STATE", + "", + "constant charge" + ], + [ + "CHG_CV_STATE", + "", + "constant voltage" + ], + [ + "CHG_DONE_STATE", + "", + "charge done" + ], + [ + "CHG_STOP_STATE", + "", + "not charge" + ] + ], + "def": "enum class ChargerStatus {\n CHG_TRI_STATE, //tri_charge\n CHG_PRE_STATE, //pre_charge\n CHG_CC_STATE, //constant charge\n CHG_CV_STATE, //constant voltage\n CHG_DONE_STATE, //charge done\n CHG_STOP_STATE, //not charge\n}" + }, + "PowerChannel": { + "type": "enum", + "name": "class", + "doc": { + "brief": "power channel", + "maixpy": "maix.ext_dev.pmu.PowerChannel", + "py_doc": "power channel" + }, + "values": [ + [ + "DCDC1", + "", + "" + ], + [ + "DCDC2", + "", + "" + ], + [ + "DCDC3", + "", + "" + ], + [ + "DCDC4", + "", + "" + ], + [ + "DCDC5", + "", + "" + ], + [ + "ALDO1", + "", + "" + ], + [ + "ALDO2", + "", + "" + ], + [ + "ALDO3", + "", + "" + ], + [ + "ALDO4", + "", + "" + ], + [ + "BLDO1", + "", + "" + ], + [ + "BLDO2", + "", + "" + ], + [ + "DLDO1", + "", + "" + ], + [ + "DLDO2", + "", + "" + ], + [ + "VBACKUP", + "", + "" + ], + [ + "CPULDO", + "", + "" + ] + ], + "def": "enum class PowerChannel {\n DCDC1,\n DCDC2,\n DCDC3,\n DCDC4,\n DCDC5,\n ALDO1,\n ALDO2,\n ALDO3,\n ALDO4,\n BLDO1,\n BLDO2,\n DLDO1,\n DLDO2,\n VBACKUP,\n CPULDO,\n}" + }, + "PMU": { + "type": "class", + "name": "PMU", + "doc": { + "brief": "PMU driver class", + "maixpy": "maix.ext_dev.pmu.PMU", + "py_doc": "PMU driver class" + }, + "members": { + "__init__": { + "type": "func", + "name": "PMU", + "doc": { + "brief": "Construct a new PMU object, will open PMU.", + "param": { + "driver": "driver name, only support \"axp2101\".", + "i2c_bus": "i2c bus number. Automatically selects the on-board pmu when -1 is passed in.", + "addr": "PMU i2c addr." + }, + "maixpy": "maix.ext_dev.pmu.PMU.__init__", + "py_doc": "Construct a new PMU object, will open PMU.\n\nArgs:\n - driver: driver name, only support \"axp2101\".\n - i2c_bus: i2c bus number. Automatically selects the on-board pmu when -1 is passed in.\n - addr: PMU i2c addr.\n" + }, + "args": [ + [ + "std::string", + "driver", + "\"axp2101\"" + ], + [ + "int", + "i2c_bus", + "-1" + ], + [ + "int", + "addr", + "0x34" + ] + ], + "ret_type": null, + "static": false, + "def": "PMU(std::string driver = \"axp2101\", int i2c_bus = -1, int addr = 0x34)" + }, + "poweroff": { + "type": "func", + "name": "poweroff", + "doc": { + "brief": "Poweroff immediately.", + "return": "err::Err type, if init success, return err::ERR_NONE.", + "maixpy": "maix.ext_dev.pmu.PMU.poweroff", + "py_doc": "Poweroff immediately.\n\nReturns: err::Err type, if init success, return err::ERR_NONE.\n" + }, + "args": [], + "ret_type": "err::Err", + "static": false, + "def": "err::Err poweroff()" + }, + "is_bat_connect": { + "type": "func", + "name": "is_bat_connect", + "doc": { + "brief": "Is the battery connected.", + "return": "bool type, if battery is connected, return true.", + "maixpy": "maix.ext_dev.pmu.PMU.is_bat_connect", + "py_doc": "Is the battery connected.\n\nReturns: bool type, if battery is connected, return true.\n" + }, + "args": [], + "ret_type": "bool", + "static": false, + "def": "bool is_bat_connect()" + }, + "is_vbus_in": { + "type": "func", + "name": "is_vbus_in", + "doc": { + "brief": "Is the power adapter connected.", + "return": "bool type, if power adapter is connected, return true.", + "maixpy": "maix.ext_dev.pmu.PMU.is_vbus_in", + "py_doc": "Is the power adapter connected.\n\nReturns: bool type, if power adapter is connected, return true.\n" + }, + "args": [], + "ret_type": "bool", + "static": false, + "def": "bool is_vbus_in()" + }, + "is_charging": { + "type": "func", + "name": "is_charging", + "doc": { + "brief": "Is bat charging.", + "return": "bool type, if bat is charging, return true.", + "maixpy": "maix.ext_dev.pmu.PMU.is_charging", + "py_doc": "Is bat charging.\n\nReturns: bool type, if bat is charging, return true.\n" + }, + "args": [], + "ret_type": "bool", + "static": false, + "def": "bool is_charging()" + }, + "get_bat_percent": { + "type": "func", + "name": "get_bat_percent", + "doc": { + "brief": "Get the battery percentage.", + "return": "int type, return battery percentage.", + "maixpy": "maix.ext_dev.pmu.PMU.get_bat_percent", + "py_doc": "Get the battery percentage.\n\nReturns: int type, return battery percentage.\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int get_bat_percent()" + }, + "get_charger_status": { + "type": "func", + "name": "get_charger_status", + "doc": { + "brief": "Get the battery charging status.", + "return": "int type, return battery charging status.", + "maixpy": "maix.ext_dev.pmu.PMU.get_charger_status", + "py_doc": "Get the battery charging status.\n\nReturns: int type, return battery charging status.\n" + }, + "args": [], + "ret_type": "ext_dev::pmu::ChargerStatus", + "static": false, + "def": "ext_dev::pmu::ChargerStatus get_charger_status()" + }, + "get_vat_vol": { + "type": "func", + "name": "get_bat_vol", + "doc": { + "brief": "Get the battery voltage.", + "return": "uint16_t type, return battery voltage.", + "maixpy": "maix.ext_dev.pmu.PMU.get_vat_vol", + "py_doc": "Get the battery voltage.\n\nReturns: uint16_t type, return battery voltage.\n" + }, + "args": [], + "ret_type": "uint16_t", + "static": false, + "def": "uint16_t get_bat_vol()" + }, + "clean_irq": { + "type": "func", + "name": "clean_irq", + "doc": { + "brief": "Clear interrupt flag.", + "return": "err::Err type, if clean success, return err::ERR_NONE.", + "maixpy": "maix.ext_dev.pmu.PMU.clean_irq", + "py_doc": "Clear interrupt flag.\n\nReturns: err::Err type, if clean success, return err::ERR_NONE.\n" + }, + "args": [], + "ret_type": "err::Err", + "static": false, + "def": "err::Err clean_irq()" + }, + "set_bat_charging_cur": { + "type": "func", + "name": "set_bat_charging_cur", + "doc": { + "brief": "Set the battery charging current.", + "param": { + "current": "The current to be set." + }, + "return": "err::Err type, if set success, return err::ERR_NONE.", + "maixpy": "maix.ext_dev.pmu.PMU.set_bat_charging_cur", + "py_doc": "Set the battery charging current.\n\nArgs:\n - current: The current to be set.\n\n\nReturns: err::Err type, if set success, return err::ERR_NONE.\n" + }, + "args": [ + [ + "int", + "current", + null + ] + ], + "ret_type": "err::Err", + "static": false, + "def": "err::Err set_bat_charging_cur(int current)" + }, + "get_bat_charging_cur": { + "type": "func", + "name": "get_bat_charging_cur", + "doc": { + "brief": "Get the battery charging current.", + "return": "int, return the currently set charging current.", + "maixpy": "maix.ext_dev.pmu.PMU.get_bat_charging_cur", + "py_doc": "Get the battery charging current.\n\nReturns: int, return the currently set charging current.\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int get_bat_charging_cur()" + }, + "set_vol": { + "type": "func", + "name": "set_vol", + "doc": { + "brief": "Set the PMU channel voltage.\\nYou can retrieve the available channel from ext_dev.pmu.PowerChannel.", + "param": { + "voltage": "The voltage to be set." + }, + "return": "int, return the channel voltage.", + "maixpy": "maix.ext_dev.pmu.PMU.set_vol", + "py_doc": "Set the PMU channel voltage.\nYou can retrieve the available channel from ext_dev.pmu.PowerChannel.\n\nArgs:\n - voltage: The voltage to be set.\n\n\nReturns: int, return the channel voltage.\n" + }, + "args": [ + [ + "ext_dev::pmu::PowerChannel", + "channel", + null + ], + [ + "int", + "voltage", + null + ] + ], + "ret_type": "err::Err", + "static": false, + "def": "err::Err set_vol(ext_dev::pmu::PowerChannel channel, int voltage)" + }, + "get_vol": { + "type": "func", + "name": "get_vol", + "doc": { + "brief": "Get the PMU channel voltage.\\nYou can retrieve the available channel from ext_dev.pmu.PowerChannel.", + "return": "err::Err type, if set success, return err::ERR_NONE.", + "maixpy": "maix.ext_dev.pmu.PMU.get_vol", + "py_doc": "Get the PMU channel voltage.\nYou can retrieve the available channel from ext_dev.pmu.PowerChannel.\n\nReturns: err::Err type, if set success, return err::ERR_NONE.\n" + }, + "args": [ + [ + "ext_dev::pmu::PowerChannel", + "channel", + null + ] + ], + "ret_type": "int", + "static": false, + "def": "int get_vol(ext_dev::pmu::PowerChannel channel)" + } + }, + "def": "class PMU" + } + }, + "auto_add": true + }, + "axp2101": { + "type": "module", + "doc": { + "brief": "maix.ext_dev.axp2101 module" + }, + "members": { + "ChargerStatus": { + "type": "enum", + "name": "class", + "doc": { + "brief": "charger status", + "maixpy": "maix.ext_dev.axp2101.ChargerStatus", + "py_doc": "charger status" + }, + "values": [ + [ + "CHG_TRI_STATE", + "", + "tri_charge" + ], + [ + "CHG_PRE_STATE", + "", + "pre_charge" + ], + [ + "CHG_CC_STATE", + "", + "constant charge" + ], + [ + "CHG_CV_STATE", + "", + "constant voltage" + ], + [ + "CHG_DONE_STATE", + "", + "charge done" + ], + [ + "CHG_STOP_STATE", + "", + "not charge" + ] + ], + "def": "enum class ChargerStatus {\n CHG_TRI_STATE, //tri_charge\n CHG_PRE_STATE, //pre_charge\n CHG_CC_STATE, //constant charge\n CHG_CV_STATE, //constant voltage\n CHG_DONE_STATE, //charge done\n CHG_STOP_STATE, //not charge\n }" + }, + "ChargerCurrent": { + "type": "enum", + "name": "class", + "doc": { + "brief": "charger current", + "maixpy": "maix.ext_dev.axp2101.ChargerCurrent", + "py_doc": "charger current" + }, + "values": [ + [ + "CHG_CUR_0MA", + "", + "" + ], + [ + "CHG_CUR_100MA", + "4", + "" + ], + [ + "CHG_CUR_125MA", + "", + "" + ], + [ + "CHG_CUR_150MA", + "", + "" + ], + [ + "CHG_CUR_175MA", + "", + "" + ], + [ + "CHG_CUR_200MA", + "", + "" + ], + [ + "CHG_CUR_300MA", + "", + "" + ], + [ + "CHG_CUR_400MA", + "", + "" + ], + [ + "CHG_CUR_500MA", + "", + "" + ], + [ + "CHG_CUR_600MA", + "", + "" + ], + [ + "CHG_CUR_700MA", + "", + "" + ], + [ + "CHG_CUR_800MA", + "", + "" + ], + [ + "CHG_CUR_900MA", + "", + "" + ], + [ + "CHG_CUR_1000MA", + "", + "" + ] + ], + "def": "enum class ChargerCurrent {\n CHG_CUR_0MA,\n CHG_CUR_100MA = 4,\n CHG_CUR_125MA,\n CHG_CUR_150MA,\n CHG_CUR_175MA,\n CHG_CUR_200MA,\n CHG_CUR_300MA,\n CHG_CUR_400MA,\n CHG_CUR_500MA,\n CHG_CUR_600MA,\n CHG_CUR_700MA,\n CHG_CUR_800MA,\n CHG_CUR_900MA,\n CHG_CUR_1000MA,\n }" + }, + "PowerChannel": { + "type": "enum", + "name": "class", + "doc": { + "brief": "power channel", + "maixpy": "maix.ext_dev.axp2101.PowerChannel", + "py_doc": "power channel" + }, + "values": [ + [ + "DCDC1", + "", + "" + ], + [ + "DCDC2", + "", + "" + ], + [ + "DCDC3", + "", + "" + ], + [ + "DCDC4", + "", + "" + ], + [ + "DCDC5", + "", + "" + ], + [ + "ALDO1", + "", + "" + ], + [ + "ALDO2", + "", + "" + ], + [ + "ALDO3", + "", + "" + ], + [ + "ALDO4", + "", + "" + ], + [ + "BLDO1", + "", + "" + ], + [ + "BLDO2", + "", + "" + ], + [ + "DLDO1", + "", + "" + ], + [ + "DLDO2", + "", + "" + ], + [ + "VBACKUP", + "", + "" + ], + [ + "CPULDO", + "", + "" + ] + ], + "def": "enum class PowerChannel {\n DCDC1,\n DCDC2,\n DCDC3,\n DCDC4,\n DCDC5,\n ALDO1,\n ALDO2,\n ALDO3,\n ALDO4,\n BLDO1,\n BLDO2,\n DLDO1,\n DLDO2,\n VBACKUP,\n CPULDO,\n }" + }, + "PowerOffTime": { + "type": "enum", + "name": "class", + "doc": { + "brief": "power off time", + "maixpy": "maix.ext_dev.axp2101.PowerOffTime", + "py_doc": "power off time" + }, + "values": [ + [ + "POWEROFF_4S", + "", + "" + ], + [ + "POWEROFF_6S", + "", + "" + ], + [ + "POWEROFF_8S", + "", + "" + ], + [ + "POWEROFF_10S", + "", + "" + ], + [ + "POWEROFF_DISABLE", + "65535", + "" + ] + ], + "def": "enum class PowerOffTime {\n POWEROFF_4S,\n POWEROFF_6S,\n POWEROFF_8S,\n POWEROFF_10S,\n POWEROFF_DISABLE = 65535,\n }" + }, + "PowerOnTime": { + "type": "enum", + "name": "class", + "doc": { + "brief": "power on time", + "maixpy": "maix.ext_dev.axp2101.PowerOnTime", + "py_doc": "power on time" + }, + "values": [ + [ + "POWERON_128MS", + "", + "" + ], + [ + "POWERON_512MS", + "", + "" + ], + [ + "POWERON_1S", + "", + "" + ], + [ + "POWERON_2S", + "", + "" + ] + ], + "def": "enum class PowerOnTime {\n POWERON_128MS,\n POWERON_512MS,\n POWERON_1S,\n POWERON_2S,\n }" + }, + "AXP2101": { + "type": "class", + "name": "AXP2101", + "doc": { + "brief": "Peripheral AXP2101 class", + "maixpy": "maix.ext_dev.axp2101.AXP2101", + "py_doc": "Peripheral AXP2101 class" + }, + "members": { + "__init__": { + "type": "func", + "name": "AXP2101", + "doc": { + "brief": "AXP2101 constructor.", + "param": { + "i2c_bus": "i2c bus number.", + "addr": "pmu device addr." + }, + "maixpy": "maix.ext_dev.axp2101.AXP2101.__init__", + "py_doc": "AXP2101 constructor.\n\nArgs:\n - i2c_bus: i2c bus number.\n - addr: pmu device addr.\n" + }, + "args": [ + [ + "int", + "i2c_bus", + "-1" + ], + [ + "uint8_t", + "addr", + "0x34" + ] + ], + "ret_type": null, + "static": false, + "def": "AXP2101(int i2c_bus = -1, uint8_t addr = 0x34)" + }, + "init": { + "type": "func", + "name": "init", + "doc": { + "brief": "Initialise the AXP2101.", + "return": "err::Err type, if init success, return err::ERR_NONE.", + "maixpy": "maix.ext_dev.axp2101.AXP2101.init", + "py_doc": "Initialise the AXP2101.\n\nReturns: err::Err type, if init success, return err::ERR_NONE.\n" + }, + "args": [], + "ret_type": "err::Err", + "static": false, + "def": "err::Err init()" + }, + "poweroff": { + "type": "func", + "name": "poweroff", + "doc": { + "brief": "Poweroff immediately.", + "return": "err::Err type, if init success, return err::ERR_NONE.", + "maixpy": "maix.ext_dev.axp2101.AXP2101.poweroff", + "py_doc": "Poweroff immediately.\n\nReturns: err::Err type, if init success, return err::ERR_NONE.\n" + }, + "args": [], + "ret_type": "err::Err", + "static": false, + "def": "err::Err poweroff()" + }, + "is_bat_connect": { + "type": "func", + "name": "is_bat_connect", + "doc": { + "brief": "Is the battery connected.", + "return": "bool type, if battery is connected, return true.", + "maixpy": "maix.ext_dev.axp2101.AXP2101.is_bat_connect", + "py_doc": "Is the battery connected.\n\nReturns: bool type, if battery is connected, return true.\n" + }, + "args": [], + "ret_type": "bool", + "static": false, + "def": "bool is_bat_connect()" + }, + "is_vbus_in": { + "type": "func", + "name": "is_vbus_in", + "doc": { + "brief": "Is the power adapter connected.", + "return": "bool type, if power adapter is connected, return true.", + "maixpy": "maix.ext_dev.axp2101.AXP2101.is_vbus_in", + "py_doc": "Is the power adapter connected.\n\nReturns: bool type, if power adapter is connected, return true.\n" + }, + "args": [], + "ret_type": "bool", + "static": false, + "def": "bool is_vbus_in()" + }, + "is_charging": { + "type": "func", + "name": "is_charging", + "doc": { + "brief": "Is bat charging.", + "return": "bool type, if bat is charging, return true.", + "maixpy": "maix.ext_dev.axp2101.AXP2101.is_charging", + "py_doc": "Is bat charging.\n\nReturns: bool type, if bat is charging, return true.\n" + }, + "args": [], + "ret_type": "bool", + "static": false, + "def": "bool is_charging()" + }, + "get_bat_percent": { + "type": "func", + "name": "get_bat_percent", + "doc": { + "brief": "Get the battery percentage.", + "return": "int type, return battery percentage.", + "maixpy": "maix.ext_dev.axp2101.AXP2101.get_bat_percent", + "py_doc": "Get the battery percentage.\n\nReturns: int type, return battery percentage.\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int get_bat_percent()" + }, + "get_charger_status": { + "type": "func", + "name": "get_charger_status", + "doc": { + "brief": "Get the battery charging status.", + "return": "int type, return battery charging status.", + "maixpy": "maix.ext_dev.axp2101.AXP2101.get_charger_status", + "py_doc": "Get the battery charging status.\n\nReturns: int type, return battery charging status.\n" + }, + "args": [], + "ret_type": "ext_dev::axp2101::ChargerStatus", + "static": false, + "def": "ext_dev::axp2101::ChargerStatus get_charger_status()", + "overload": [ + { + "type": "func", + "name": "get_bat_vol", + "doc": { + "brief": "Get the battery voltage.", + "return": "uint16_t type, return battery voltage.", + "maixpy": "maix.ext_dev.axp2101.AXP2101.get_charger_status", + "py_doc": "Get the battery voltage.\n\nReturns: uint16_t type, return battery voltage.\n" + }, + "args": [], + "ret_type": "uint16_t", + "static": false, + "def": "uint16_t get_bat_vol()" + } + ] + }, + "clean_irq": { + "type": "func", + "name": "clean_irq", + "doc": { + "brief": "Clear interrupt flag.", + "return": "err::Err type, if clean success, return err::ERR_NONE.", + "maixpy": "maix.ext_dev.axp2101.AXP2101.clean_irq", + "py_doc": "Clear interrupt flag.\n\nReturns: err::Err type, if clean success, return err::ERR_NONE.\n" + }, + "args": [], + "ret_type": "err::Err", + "static": false, + "def": "err::Err clean_irq()" + }, + "set_bat_charging_cur": { + "type": "func", + "name": "set_bat_charging_cur", + "doc": { + "brief": "Set the battery charging current.", + "param": { + "current": "The current to be set.\nThe available values are 0mA, 100mA, 125mA, 150mA, 175mA,\n200mA, 300mA, 400mA, 500mA, 600mA, 700mA, 800mA, 900mA, and 1000mA." + }, + "return": "err::Err type, if set success, return err::ERR_NONE.", + "maixpy": "maix.ext_dev.axp2101.AXP2101.set_bat_charging_cur", + "py_doc": "Set the battery charging current.\n\nArgs:\n - current: The current to be set.\nThe available values are 0mA, 100mA, 125mA, 150mA, 175mA,\n200mA, 300mA, 400mA, 500mA, 600mA, 700mA, 800mA, 900mA, and 1000mA.\n\n\nReturns: err::Err type, if set success, return err::ERR_NONE.\n" + }, + "args": [ + [ + "ext_dev::axp2101::ChargerCurrent", + "current", + null + ] + ], + "ret_type": "err::Err", + "static": false, + "def": "err::Err set_bat_charging_cur(ext_dev::axp2101::ChargerCurrent current)" + }, + "get_bat_charging_cur": { + "type": "func", + "name": "get_bat_charging_cur", + "doc": { + "brief": "Get the battery charging current.", + "return": "ChargerCurrent, return the currently set charging current.", + "maixpy": "maix.ext_dev.axp2101.AXP2101.get_bat_charging_cur", + "py_doc": "Get the battery charging current.\n\nReturns: ChargerCurrent, return the currently set charging current.\n" + }, + "args": [], + "ret_type": "ext_dev::axp2101::ChargerCurrent", + "static": false, + "def": "ext_dev::axp2101::ChargerCurrent get_bat_charging_cur()" + }, + "dcdc1": { + "type": "func", + "name": "dcdc1", + "doc": { + "brief": "Set and get the PMU DCDC1 voltage.", + "param": { + "voltage": "The voltage to be set,\nvoltage range is 1500mV~3400mV(step 20mV)." + }, + "return": "int, return the PMU DCDC1 voltage.", + "maixpy": "maix.ext_dev.axp2101.AXP2101.dcdc1", + "py_doc": "Set and get the PMU DCDC1 voltage.\n\nArgs:\n - voltage: The voltage to be set,\nvoltage range is 1500mV~3400mV(step 20mV).\n\n\nReturns: int, return the PMU DCDC1 voltage.\n" + }, + "args": [ + [ + "int", + "voltage", + "-1" + ] + ], + "ret_type": "int", + "static": false, + "def": "int dcdc1(int voltage = -1)" + }, + "dcdc2": { + "type": "func", + "name": "dcdc2", + "doc": { + "brief": "Set and get the PMU DCDC2 voltage.", + "param": { + "voltage": "The voltage to be set,\nvoltage range is 500mV~1200mV(step 10mV) and 1220mV~1540mV(step 20mV)." + }, + "return": "int, return the PMU DCDC2 voltage.", + "maixpy": "maix.ext_dev.axp2101.AXP2101.dcdc2", + "py_doc": "Set and get the PMU DCDC2 voltage.\n\nArgs:\n - voltage: The voltage to be set,\nvoltage range is 500mV~1200mV(step 10mV) and 1220mV~1540mV(step 20mV).\n\n\nReturns: int, return the PMU DCDC2 voltage.\n" + }, + "args": [ + [ + "int", + "voltage", + "-1" + ] + ], + "ret_type": "int", + "static": false, + "def": "int dcdc2(int voltage = -1)" + }, + "dcdc3": { + "type": "func", + "name": "dcdc3", + "doc": { + "brief": "Set and get the PMU DCDC3 voltage.", + "param": { + "voltage": "The voltage to be set,\nvoltage range is 500mV~1200mV(step 10mV) and 1220mV~1540mV(step 20mV)." + }, + "return": "int, return the PMU DCDC3 voltage.", + "maixpy": "maix.ext_dev.axp2101.AXP2101.dcdc3", + "py_doc": "Set and get the PMU DCDC3 voltage.\n\nArgs:\n - voltage: The voltage to be set,\nvoltage range is 500mV~1200mV(step 10mV) and 1220mV~1540mV(step 20mV).\n\n\nReturns: int, return the PMU DCDC3 voltage.\n" + }, + "args": [ + [ + "int", + "voltage", + "-1" + ] + ], + "ret_type": "int", + "static": false, + "def": "int dcdc3(int voltage = -1)" + }, + "dcdc4": { + "type": "func", + "name": "dcdc4", + "doc": { + "brief": "Set and get the PMU DCDC4 voltage.", + "param": { + "voltage": "The voltage to be set,\nvoltage range is 500mV~1200mV(step 10mV) and 1220mV~1840mV(step 20mV)." + }, + "return": "int, return the PMU DCDC4 voltage.", + "maixpy": "maix.ext_dev.axp2101.AXP2101.dcdc4", + "py_doc": "Set and get the PMU DCDC4 voltage.\n\nArgs:\n - voltage: The voltage to be set,\nvoltage range is 500mV~1200mV(step 10mV) and 1220mV~1840mV(step 20mV).\n\n\nReturns: int, return the PMU DCDC4 voltage.\n" + }, + "args": [ + [ + "int", + "voltage", + "-1" + ] + ], + "ret_type": "int", + "static": false, + "def": "int dcdc4(int voltage = -1)" + }, + "dcdc5": { + "type": "func", + "name": "dcdc5", + "doc": { + "brief": "Set and get the PMU DCDC5 voltage.", + "param": { + "voltage": "The voltage to be set,\nvoltage range is 1400mV~3700mV(step 100mV)." + }, + "return": "int, return the PMU DCDC5 voltage.", + "maixpy": "maix.ext_dev.axp2101.AXP2101.dcdc5", + "py_doc": "Set and get the PMU DCDC5 voltage.\n\nArgs:\n - voltage: The voltage to be set,\nvoltage range is 1400mV~3700mV(step 100mV).\n\n\nReturns: int, return the PMU DCDC5 voltage.\n" + }, + "args": [ + [ + "int", + "voltage", + "-1" + ] + ], + "ret_type": "int", + "static": false, + "def": "int dcdc5(int voltage = -1)" + }, + "aldo1": { + "type": "func", + "name": "aldo1", + "doc": { + "brief": "Set and get the PMU ALDO1 voltage.", + "param": { + "voltage": "The voltage to be set,\nvoltage range is 500mV~3500mV(step 100mV)." + }, + "return": "int, return the PMU ALDO1 voltage.", + "maixpy": "maix.ext_dev.axp2101.AXP2101.aldo1", + "py_doc": "Set and get the PMU ALDO1 voltage.\n\nArgs:\n - voltage: The voltage to be set,\nvoltage range is 500mV~3500mV(step 100mV).\n\n\nReturns: int, return the PMU ALDO1 voltage.\n" + }, + "args": [ + [ + "int", + "voltage", + "-1" + ] + ], + "ret_type": "int", + "static": false, + "def": "int aldo1(int voltage = -1)" + }, + "aldo2": { + "type": "func", + "name": "aldo2", + "doc": { + "brief": "Set and get the PMU ALDO2 voltage.", + "param": { + "voltage": "The voltage to be set,\nvoltage range is 500mV~3500mV(step 100mV)." + }, + "return": "int, return the PMU ALDO2 voltage.", + "maixpy": "maix.ext_dev.axp2101.AXP2101.aldo2", + "py_doc": "Set and get the PMU ALDO2 voltage.\n\nArgs:\n - voltage: The voltage to be set,\nvoltage range is 500mV~3500mV(step 100mV).\n\n\nReturns: int, return the PMU ALDO2 voltage.\n" + }, + "args": [ + [ + "int", + "voltage", + "-1" + ] + ], + "ret_type": "int", + "static": false, + "def": "int aldo2(int voltage = -1)" + }, + "aldo3": { + "type": "func", + "name": "aldo3", + "doc": { + "brief": "Set and get the PMU ALDO3 voltage.", + "param": { + "voltage": "The voltage to be set,\nvoltage range is 500mV~3500mV(step 100mV)." + }, + "return": "int, return the PMU ALDO3 voltage.", + "maixpy": "maix.ext_dev.axp2101.AXP2101.aldo3", + "py_doc": "Set and get the PMU ALDO3 voltage.\n\nArgs:\n - voltage: The voltage to be set,\nvoltage range is 500mV~3500mV(step 100mV).\n\n\nReturns: int, return the PMU ALDO3 voltage.\n" + }, + "args": [ + [ + "int", + "voltage", + "-1" + ] + ], + "ret_type": "int", + "static": false, + "def": "int aldo3(int voltage = -1)" + }, + "aldo4": { + "type": "func", + "name": "aldo4", + "doc": { + "brief": "Set and get the PMU ALDO4 voltage.", + "param": { + "voltage": "The voltage to be set,\nvoltage range is 500mV~3500mV(step 100mV)." + }, + "return": "int, return the PMU ALDO4 voltage.", + "maixpy": "maix.ext_dev.axp2101.AXP2101.aldo4", + "py_doc": "Set and get the PMU ALDO4 voltage.\n\nArgs:\n - voltage: The voltage to be set,\nvoltage range is 500mV~3500mV(step 100mV).\n\n\nReturns: int, return the PMU ALDO4 voltage.\n" + }, + "args": [ + [ + "int", + "voltage", + "-1" + ] + ], + "ret_type": "int", + "static": false, + "def": "int aldo4(int voltage = -1)" + }, + "bldo1": { + "type": "func", + "name": "bldo1", + "doc": { + "brief": "Set and get the PMU BLDO1 voltage.", + "param": { + "voltage": "The voltage to be set,\nvoltage range is 500mV~3500mV(step 100mV)." + }, + "return": "int, return the PMU BLDO1 voltage.", + "maixpy": "maix.ext_dev.axp2101.AXP2101.bldo1", + "py_doc": "Set and get the PMU BLDO1 voltage.\n\nArgs:\n - voltage: The voltage to be set,\nvoltage range is 500mV~3500mV(step 100mV).\n\n\nReturns: int, return the PMU BLDO1 voltage.\n" + }, + "args": [ + [ + "int", + "voltage", + "-1" + ] + ], + "ret_type": "int", + "static": false, + "def": "int bldo1(int voltage = -1)" + }, + "bldo2": { + "type": "func", + "name": "bldo2", + "doc": { + "brief": "Set and get the PMU BLDO2 voltage.", + "param": { + "voltage": "The voltage to be set,\nvoltage range is 500mV~3500mV(step 100mV)." + }, + "return": "int, return the PMU BLDO2 voltage.", + "maixpy": "maix.ext_dev.axp2101.AXP2101.bldo2", + "py_doc": "Set and get the PMU BLDO2 voltage.\n\nArgs:\n - voltage: The voltage to be set,\nvoltage range is 500mV~3500mV(step 100mV).\n\n\nReturns: int, return the PMU BLDO2 voltage.\n" + }, + "args": [ + [ + "int", + "voltage", + "-1" + ] + ], + "ret_type": "int", + "static": false, + "def": "int bldo2(int voltage = -1)" + }, + "set_poweroff_time": { + "type": "func", + "name": "set_poweroff_time", + "doc": { + "brief": "Set power-off time, The device will shut down\\nif the power button is held down longer than this time.", + "param": { + "tm": "The time to be set, you can set it to 4s, 6s, 8s, or 10s." + }, + "return": "err::Err type, if set success, return err::ERR_NONE.", + "maixpy": "maix.ext_dev.axp2101.AXP2101.set_poweroff_time", + "py_doc": "Set power-off time, The device will shut down\nif the power button is held down longer than this time.\n\nArgs:\n - tm: The time to be set, you can set it to 4s, 6s, 8s, or 10s.\n\n\nReturns: err::Err type, if set success, return err::ERR_NONE.\n" + }, + "args": [ + [ + "ext_dev::axp2101::PowerOffTime", + "tm", + null + ] + ], + "ret_type": "err::Err", + "static": false, + "def": "err::Err set_poweroff_time(ext_dev::axp2101::PowerOffTime tm)" + }, + "get_poweroff_time": { + "type": "func", + "name": "get_poweroff_time", + "doc": { + "brief": "Get power-off time.", + "return": "PowerOffTime, return power-off time.", + "maixpy": "maix.ext_dev.axp2101.AXP2101.get_poweroff_time", + "py_doc": "Get power-off time.\n\nReturns: PowerOffTime, return power-off time.\n" + }, + "args": [], + "ret_type": "ext_dev::axp2101::PowerOffTime", + "static": false, + "def": "ext_dev::axp2101::PowerOffTime get_poweroff_time()" + }, + "set_poweron_time": { + "type": "func", + "name": "set_poweron_time", + "doc": { + "brief": "Set power-on time, The device will power on\\nif the power button is held down longer than this time.", + "param": { + "tm": "The time to be set, you can set it to 128ms, 512ms, 1s, or 2s." + }, + "return": "err::Err type, if set success, return err::ERR_NONE.", + "maixpy": "maix.ext_dev.axp2101.AXP2101.set_poweron_time", + "py_doc": "Set power-on time, The device will power on\nif the power button is held down longer than this time.\n\nArgs:\n - tm: The time to be set, you can set it to 128ms, 512ms, 1s, or 2s.\n\n\nReturns: err::Err type, if set success, return err::ERR_NONE.\n" + }, + "args": [ + [ + "ext_dev::axp2101::PowerOnTime", + "tm", + null + ] + ], + "ret_type": "err::Err", + "static": false, + "def": "err::Err set_poweron_time(ext_dev::axp2101::PowerOnTime tm)" + }, + "get_poweron_time": { + "type": "func", + "name": "get_poweron_time", + "doc": { + "brief": "Get power-on time.", + "return": "PowerOnTime, return power-on time.", + "maixpy": "maix.ext_dev.axp2101.AXP2101.get_poweron_time", + "py_doc": "Get power-on time.\n\nReturns: PowerOnTime, return power-on time.\n" + }, + "args": [], + "ret_type": "ext_dev::axp2101::PowerOnTime", + "static": false, + "def": "ext_dev::axp2101::PowerOnTime get_poweron_time()" + } + }, + "def": "class AXP2101" + } + }, + "auto_add": true + } + }, + "auto_add": true + }, + "nn": { + "type": "module", + "doc": { + "brief": "maix.nn module" + }, + "members": { + "NanoTrack": { + "type": "class", + "name": "NanoTrack", + "doc": { + "brief": "NanoTrack class", + "maixpy": "maix.nn.NanoTrack", + "py_doc": "NanoTrack class" + }, + "members": { + "NanoTrack": { + "type": "func", + "name": "NanoTrack", + "doc": { + "brief": "Constructor of NanoTrack class", + "param": { + "model": "model path, default empty, you can load model later by load function." + }, + "throw": "If model arg is not empty and load failed, will throw err::Exception.", + "maixpy": "maix.nn.NanoTrack.__init__", + "maixcdk": "maix.nn.NanoTrack.NanoTrack", + "py_doc": "Constructor of NanoTrack class\n\nArgs:\n - model: model path, default empty, you can load model later by load function.\n" + }, + "args": [ + [ + "const string &", + "model", + "\"\"" + ] + ], + "ret_type": null, + "static": false, + "def": "NanoTrack(const string &model = \"\")" + }, + "load": { + "type": "func", + "name": "load", + "doc": { + "brief": "Load model from file", + "param": { + "model": "Model path want to load" + }, + "return": "err::Err", + "maixpy": "maix.nn.NanoTrack.load", + "py_doc": "Load model from file\n\nArgs:\n - model: Model path want to load\n\n\nReturns: err::Err\n" + }, + "args": [ + [ + "const string &", + "model", + null + ] + ], + "ret_type": "err::Err", + "static": false, + "def": "err::Err load(const string &model)" + }, + "init": { + "type": "func", + "name": "init", + "doc": { + "brief": "Init tracker, give tacker first target image and target position.", + "param": { + "img": "Image want to detect, target should be in this image.", + "x": "the target position left top coordinate x.", + "y": "the target position left top coordinate y.", + "w": "the target width.", + "h": "the target height." + }, + "throw": "If image format not match model input format, will throw err::Exception.", + "maixpy": "maix.nn.NanoTrack.init", + "py_doc": "Init tracker, give tacker first target image and target position.\n\nArgs:\n - img: Image want to detect, target should be in this image.\n - x: the target position left top coordinate x.\n - y: the target position left top coordinate y.\n - w: the target width.\n - h: the target height.\n" + }, + "args": [ + [ + "image::Image &", + "img", + null + ], + [ + "int", + "x", + null + ], + [ + "int", + "y", + null + ], + [ + "int", + "w", + null + ], + [ + "int", + "h", + null + ] + ], + "ret_type": "void", + "static": false, + "def": "void init(image::Image &img, int x, int y, int w, int h)" + }, + "track": { + "type": "func", + "name": "track", + "doc": { + "brief": "Track object acoording to last object position and the init function learned target feature.", + "param": { + "img": "image to detect object and track, can be any resolution, before detect it will crop a area according to last time target's position.", + "threshold": "If score < threshold, will see this new detection is invalid, but remain return this new detecion, default 0.9." + }, + "return": "object, position and score, and detect area in points's first 4 element(x, y, w, h, center_x, center_y, input_size, target_size)", + "maixpy": "maix.nn.NanoTrack.track", + "py_doc": "Track object acoording to last object position and the init function learned target feature.\n\nArgs:\n - img: image to detect object and track, can be any resolution, before detect it will crop a area according to last time target's position.\n - threshold: If score < threshold, will see this new detection is invalid, but remain return this new detecion, default 0.9.\n\n\nReturns: object, position and score, and detect area in points's first 4 element(x, y, w, h, center_x, center_y, input_size, target_size)\n" + }, + "args": [ + [ + "image::Image &", + "img", + null + ], + [ + "float", + "threshold", + "0.9" + ] + ], + "ret_type": "nn::Object", + "static": false, + "def": "nn::Object track(image::Image &img, float threshold = 0.9)" + }, + "input_size": { + "type": "func", + "name": "input_size", + "doc": { + "brief": "Get model input size", + "return": "model input size", + "maixpy": "maix.nn.NanoTrack.input_size", + "py_doc": "Get model input size\n\nReturns: model input size\n" + }, + "args": [], + "ret_type": "image::Size", + "static": false, + "def": "image::Size input_size()" + }, + "input_width": { + "type": "func", + "name": "input_width", + "doc": { + "brief": "Get model input width", + "return": "model input size of width", + "maixpy": "maix.nn.NanoTrack.input_width", + "py_doc": "Get model input width\n\nReturns: model input size of width\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int input_width()" + }, + "input_height": { + "type": "func", + "name": "input_height", + "doc": { + "brief": "Get model input height", + "return": "model input size of height", + "maixpy": "maix.nn.NanoTrack.input_height", + "py_doc": "Get model input height\n\nReturns: model input size of height\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int input_height()" + }, + "input_format": { + "type": "func", + "name": "input_format", + "doc": { + "brief": "Get input image format", + "return": "input image format, image::Format type.", + "maixpy": "maix.nn.NanoTrack.input_format", + "py_doc": "Get input image format\n\nReturns: input image format, image::Format type.\n" + }, + "args": [], + "ret_type": "image::Format", + "static": false, + "def": "image::Format input_format()" + }, + "mean": { + "type": "var", + "name": "mean", + "doc": { + "brief": "Get mean value, list type", + "maixpy": "maix.nn.NanoTrack.mean", + "py_doc": "Get mean value, list type" + }, + "value": null, + "static": false, + "readonly": false, + "def": "std::vector mean" + }, + "scale": { + "type": "var", + "name": "scale", + "doc": { + "brief": "Get scale value, list type", + "maixpy": "maix.nn.NanoTrack.scale", + "py_doc": "Get scale value, list type" + }, + "value": null, + "static": false, + "readonly": false, + "def": "std::vector scale" + } + }, + "def": "class NanoTrack" + }, + "OCR_Box": { + "type": "class", + "name": "OCR_Box", + "doc": { + "brief": "Object for OCR detect box", + "maixpy": "maix.nn.OCR_Box", + "py_doc": "Object for OCR detect box" + }, + "members": { + "OCR_Box": { + "type": "func", + "name": "OCR_Box", + "doc": { + "brief": "OCR_Box constructor", + "maixpy": "maix.nn.OCR_Box.__init__", + "maixcdk": "maix.nn.OCR_Box.OCR_Box", + "py_doc": "OCR_Box constructor" + }, + "args": [ + [ + "int", + "x1", + "0" + ], + [ + "int", + "y1", + "0" + ], + [ + "int", + "x2", + "0" + ], + [ + "int", + "y2", + "0" + ], + [ + "int", + "x3", + "0" + ], + [ + "int", + "y3", + "0" + ], + [ + "int", + "x4", + "0" + ], + [ + "int", + "y4", + "0" + ] + ], + "ret_type": null, + "static": false, + "def": "OCR_Box(int x1 = 0, int y1 = 0, int x2 = 0, int y2 = 0, int x3 = 0, int y3 = 0, int x4 = 0, int y4 = 0)" + }, + "x1": { + "type": "var", + "name": "x1", + "doc": { + "brief": "left top point of box", + "maixpy": "maix.nn.OCR_Box.x1", + "py_doc": "left top point of box" + }, + "value": null, + "static": false, + "readonly": false, + "def": "int x1" + }, + "y1": { + "type": "var", + "name": "y1", + "doc": { + "brief": "left top point of box", + "maixpy": "maix.nn.OCR_Box.y1", + "py_doc": "left top point of box" + }, + "value": null, + "static": false, + "readonly": false, + "def": "int y1" + }, + "x2": { + "type": "var", + "name": "x2", + "doc": { + "brief": "right top point of box", + "maixpy": "maix.nn.OCR_Box.x2", + "py_doc": "right top point of box" + }, + "value": null, + "static": false, + "readonly": false, + "def": "int x2" + }, + "y2": { + "type": "var", + "name": "y2", + "doc": { + "brief": "right top point of box", + "maixpy": "maix.nn.OCR_Box.y2", + "py_doc": "right top point of box" + }, + "value": null, + "static": false, + "readonly": false, + "def": "int y2" + }, + "x3": { + "type": "var", + "name": "x3", + "doc": { + "brief": "right bottom point of box", + "maixpy": "maix.nn.OCR_Box.x3", + "py_doc": "right bottom point of box" + }, + "value": null, + "static": false, + "readonly": false, + "def": "int x3" + }, + "y3": { + "type": "var", + "name": "y3", + "doc": { + "brief": "right bottom point of box", + "maixpy": "maix.nn.OCR_Box.y3", + "py_doc": "right bottom point of box" + }, + "value": null, + "static": false, + "readonly": false, + "def": "int y3" + }, + "x4": { + "type": "var", + "name": "x4", + "doc": { + "brief": "left bottom point of box", + "maixpy": "maix.nn.OCR_Box.x4", + "py_doc": "left bottom point of box" + }, + "value": null, + "static": false, + "readonly": false, + "def": "int x4" + }, + "y4": { + "type": "var", + "name": "y4", + "doc": { + "brief": "left bottom point of box", + "maixpy": "maix.nn.OCR_Box.y4", + "py_doc": "left bottom point of box" + }, + "value": null, + "static": false, + "readonly": false, + "def": "int y4" + }, + "to_list": { + "type": "func", + "name": "to_list", + "doc": { + "brief": "convert box point to a list type.", + "return": "list type, element is int type, value [x1, y1, x2, y2, x3, y3, x4, y4].", + "maixpy": "maix.nn.OCR_Box.to_list", + "py_doc": "convert box point to a list type.\n\nReturns: list type, element is int type, value [x1, y1, x2, y2, x3, y3, x4, y4].\n" + }, + "args": [], + "ret_type": "std::vector", + "static": false, + "def": "std::vector to_list()" + } + }, + "def": "class OCR_Box" + }, + "OCR_Object": { + "type": "class", + "name": "OCR_Object", + "doc": { + "brief": "Object for OCR detect result", + "maixpy": "maix.nn.OCR_Object", + "py_doc": "Object for OCR detect result" + }, + "members": { + "OCR_Object": { + "type": "func", + "name": "OCR_Object", + "doc": { + "brief": "Constructor of Object for OCR detect result", + "param": { + "score": "score" + }, + "maixpy": "maix.nn.OCR_Object.__init__", + "maixcdk": "maix.nn.OCR_Object.OCR_Object", + "py_doc": "Constructor of Object for OCR detect result\n\nArgs:\n - score: score\n" + }, + "args": [ + [ + "const nn::OCR_Box &", + "box", + null + ], + [ + "const std::vector &", + "idx_list", + null + ], + [ + "const std::vector &", + "char_list", + null + ], + [ + "float", + "score", + "0" + ], + [ + "const std::vector &", + "char_pos", + "std::vector()" + ] + ], + "ret_type": null, + "static": false, + "def": "OCR_Object(const nn::OCR_Box &box, const std::vector &idx_list, const std::vector &char_list, float score = 0, const std::vector &char_pos = std::vector())" + }, + "box": { + "type": "var", + "name": "box", + "doc": { + "brief": "OCR_Object box, 4 points box, first point at the left-top, clock-wise.", + "maixpy": "maix.nn.OCR_Object.box", + "py_doc": "OCR_Object box, 4 points box, first point at the left-top, clock-wise." + }, + "value": null, + "static": false, + "readonly": false, + "def": "nn::OCR_Box box" + }, + "score": { + "type": "var", + "name": "score", + "doc": { + "brief": "Object score", + "maixpy": "maix.nn.OCR_Object.score", + "py_doc": "Object score" + }, + "value": null, + "static": false, + "readonly": false, + "def": "float score" + }, + "idx_list": { + "type": "var", + "name": "idx_list", + "doc": { + "brief": "chars' idx list, element is int type.", + "maixpy": "maix.nn.OCR_Object.idx_list", + "py_doc": "chars' idx list, element is int type." + }, + "value": null, + "static": false, + "readonly": false, + "def": "std::vector idx_list" + }, + "char_pos": { + "type": "var", + "name": "char_pos", + "doc": { + "brief": "Chars' position relative to left", + "maixpy": "maix.nn.OCR_Object.char_pos", + "py_doc": "Chars' position relative to left" + }, + "value": null, + "static": false, + "readonly": false, + "def": "std::vector char_pos" + }, + "char_str": { + "type": "func", + "name": "char_str", + "doc": { + "brief": "Get OCR_Object's charactors, return a string type.", + "return": "All charactors in string type.", + "maixpy": "maix.nn.OCR_Object.char_str", + "py_doc": "Get OCR_Object's charactors, return a string type.\n\nReturns: All charactors in string type.\n" + }, + "args": [], + "ret_type": "const std::string&", + "static": false, + "def": "const std::string &char_str()" + }, + "char_list": { + "type": "func", + "name": "char_list", + "doc": { + "brief": "Get OCR_Object's charactors, return a list type.", + "return": "All charactors in list type.", + "maixpy": "maix.nn.OCR_Object.char_list", + "py_doc": "Get OCR_Object's charactors, return a list type.\n\nReturns: All charactors in list type.\n" + }, + "args": [], + "ret_type": "const std::vector&", + "static": false, + "def": "const std::vector &char_list()" + }, + "update_chars": { + "type": "func", + "name": "update_chars", + "doc": { + "brief": "Set OCR_Object's charactors", + "param": { + "char_list": "All charactors in list type." + }, + "maixpy": "maix.nn.OCR_Object.update_chars", + "py_doc": "Set OCR_Object's charactors\n\nArgs:\n - char_list: All charactors in list type.\n" + }, + "args": [ + [ + "const std::vector &", + "char_list", + null + ] + ], + "ret_type": "void", + "static": false, + "def": "void update_chars(const std::vector &char_list)" + }, + "to_str": { + "type": "func", + "name": "to_str", + "doc": { + "brief": "OCR_Object info to string", + "return": "OCR_Object info string", + "maixpy": "maix.nn.OCR_Object.__str__", + "maixcdk": "maix.nn.OCR_Object.to_str", + "py_doc": "OCR_Object info to string\n\nReturns: OCR_Object info string\n" + }, + "args": [], + "ret_type": "std::string", + "static": false, + "def": "std::string to_str()" + } + }, + "def": "class OCR_Object" + }, + "OCR_Objects": { + "type": "class", + "name": "OCR_Objects", + "doc": { + "brief": "OCR_Objects Class for detect result", + "maixpy": "maix.nn.OCR_Objects", + "py_doc": "OCR_Objects Class for detect result" + }, + "members": { + "OCR_Objects": { + "type": "func", + "name": "OCR_Objects", + "doc": { + "brief": "Constructor of OCR_Objects class", + "maixpy": "maix.nn.OCR_Objects.__init__", + "maixcdk": "maix.nn.OCR_Objects.OCR_Objects", + "py_doc": "Constructor of OCR_Objects class" + }, + "args": [], + "ret_type": null, + "static": false, + "def": "OCR_Objects()" + }, + "add": { + "type": "func", + "name": "add", + "doc": { + "brief": "Add object to objects", + "throw": "Throw exception if no memory", + "maixpy": "maix.nn.OCR_Objects.add", + "py_doc": "Add object to objects" + }, + "args": [ + [ + "const nn::OCR_Box &", + "box", + null + ], + [ + "const std::vector &", + "idx_list", + null + ], + [ + "const std::vector &", + "char_list", + null + ], + [ + "float", + "score", + "0" + ], + [ + "const std::vector &", + "char_pos", + "std::vector()" + ] + ], + "ret_type": "nn::OCR_Object&", + "static": false, + "def": "nn::OCR_Object &add(const nn::OCR_Box &box, const std::vector &idx_list, const std::vector &char_list, float score = 0, const std::vector &char_pos = std::vector())" + }, + "remove": { + "type": "func", + "name": "remove", + "doc": { + "brief": "Remove object form objects", + "maixpy": "maix.nn.OCR_Objects.remove", + "py_doc": "Remove object form objects" + }, + "args": [ + [ + "int", + "idx", + null + ] + ], + "ret_type": "err::Err", + "static": false, + "def": "err::Err remove(int idx)" + }, + "at": { + "type": "func", + "name": "at", + "doc": { + "brief": "Get object item", + "maixpy": "maix.nn.OCR_Objects.at", + "py_doc": "Get object item" + }, + "args": [ + [ + "int", + "idx", + null + ] + ], + "ret_type": "nn::OCR_Object&", + "static": false, + "def": "nn::OCR_Object &at(int idx)" + }, + "[]": { + "type": "func", + "name": "operator[]", + "doc": { + "brief": "Get object item", + "maixpy": "maix.nn.OCR_Objects.__getitem__", + "maixcdk": "maix.nn.OCR_Objects.[]", + "py_doc": "Get object item" + }, + "args": [ + [ + "int", + "idx", + null + ] + ], + "ret_type": "nn::OCR_Object&", + "static": false, + "def": "nn::OCR_Object &operator[](int idx)" + }, + "size": { + "type": "func", + "name": "size", + "doc": { + "brief": "Get size", + "maixpy": "maix.nn.OCR_Objects.__len__", + "maixcdk": "maix.nn.OCR_Objects.size", + "py_doc": "Get size" + }, + "args": [], + "ret_type": "size_t", + "static": false, + "def": "size_t size()" + }, + "begin": { + "type": "func", + "name": "begin", + "doc": { + "brief": "Begin", + "maixpy": "maix.nn.OCR_Objects.__iter__", + "maixcdk": "maix.nn.OCR_Objects.begin", + "py_doc": "Begin" + }, + "args": [], + "ret_type": "std::vector::iterator", + "static": false, + "def": "std::vector::iterator begin()" + }, + "end": { + "type": "func", + "name": "end", + "doc": { + "brief": "End", + "maixcdk": "maix.nn.OCR_Objects.end", + "py_doc": "End" + }, + "args": [], + "ret_type": "std::vector::iterator", + "static": false, + "def": "std::vector::iterator end()" + } + }, + "def": "class OCR_Objects" + }, + "SpeechDevice": { + "type": "enum", + "name": "class", + "doc": { + "brief": "speech device", + "maixpy": "maix.nn.SpeechDevice", + "py_doc": "speech device" + }, + "values": [ + [ + "DEVICE_NONE", + "-1", + "" + ], + [ + "DEVICE_PCM", + "", + "" + ], + [ + "DEVICE_MIC", + "", + "" + ], + [ + "DEVICE_WAV", + "", + "" + ] + ], + "def": "enum class SpeechDevice {\n DEVICE_NONE = -1,\n DEVICE_PCM,\n DEVICE_MIC,\n DEVICE_WAV,\n}" + }, + "SpeechDecoder": { + "type": "enum", + "name": "class", + "doc": { + "brief": "speech decoder type", + "maixpy": "maix.nn.SpeechDecoder", + "py_doc": "speech decoder type" + }, + "values": [ + [ + "DECODER_RAW", + "1", + "" + ], + [ + "DECODER_DIG", + "2", + "" + ], + [ + "DECODER_LVCSR", + "4", + "" + ], + [ + "DECODER_KWS", + "8", + "" + ], + [ + "DECODER_ALL", + "65535", + "" + ] + ], + "def": "enum class SpeechDecoder {\n DECODER_RAW = 1,\n DECODER_DIG = 2,\n DECODER_LVCSR = 4,\n DECODER_KWS = 8,\n DECODER_ALL = 65535,\n}" + }, + "Speech": { + "type": "class", + "name": "Speech", + "doc": { + "brief": "Speech", + "maixpy": "maix.nn.Speech", + "py_doc": "Speech" + }, + "members": { + "Speech": { + "type": "func", + "name": "Speech", + "doc": { + "brief": "Construct a new Speech object", + "param": { + "model": "model path, default empty, you can load model later by load function." + }, + "throw": "If model arg is not empty and load failed, will throw err::Exception.", + "maixpy": "maix.nn.Speech.__init__", + "maixcdk": "maix.nn.Speech.Speech", + "py_doc": "Construct a new Speech object\n\nArgs:\n - model: model path, default empty, you can load model later by load function.\n" + }, + "args": [ + [ + "const string &", + "model", + "\"\"" + ] + ], + "ret_type": null, + "static": false, + "def": "Speech(const string &model = \"\")", + "overload": [ + { + "type": "func", + "name": "Speech", + "doc": { + "brief": "Construct a new Speech object", + "param": { + "model": "model path, default empty, you can load model later by load function." + }, + "throw": "If model arg is not empty and load failed, will throw err::Exception.", + "maixpy": "maix.nn.Speech.__init__", + "maixcdk": "maix.nn.Speech.Speech", + "py_doc": "Construct a new Speech object\n\nArgs:\n - model: model path, default empty, you can load model later by load function.\n" + }, + "args": [ + [ + "const string &", + "model", + "\"\"" + ] + ], + "ret_type": null, + "static": false, + "def": "Speech(const string &model = \"\")" + } + ] + }, + "load": { + "type": "func", + "name": "load", + "doc": { + "brief": "Load model from file", + "param": { + "model": "Model path want to load" + }, + "return": "err::Err", + "maixpy": "maix.nn.Speech.load", + "py_doc": "Load model from file\n\nArgs:\n - model: Model path want to load\n\n\nReturns: err::Err\n" + }, + "args": [ + [ + "const string &", + "model", + null + ] + ], + "ret_type": "err::Err", + "static": false, + "def": "err::Err load(const string &model)", + "overload": [ + { + "type": "func", + "name": "load", + "doc": { + "brief": "Load model from file", + "param": { + "model": "Model path want to load" + }, + "return": "err::Err", + "maixpy": "maix.nn.Speech.load", + "py_doc": "Load model from file\n\nArgs:\n - model: Model path want to load\n\n\nReturns: err::Err\n" + }, + "args": [ + [ + "const string &", + "model", + null + ] + ], + "ret_type": "err::Err", + "static": false, + "def": "err::Err load(const string &model)" + } + ] + }, + "init": { + "type": "func", + "name": "init", + "doc": { + "brief": "Init the ASR library and select the type and name of the audio device.", + "param": { + "dev_type": "device type want to detect, can choose between WAV, PCM, or MIC.", + "device_name": "device name want to detect, can choose a WAV file, a PCM file, or a MIC device name." + }, + "throw": [ + "If am model is not loaded, will throw err::ERR_NOT_IMPL.", + "If device is not supported, will throw err::ERR_NOT_IMPL." + ], + "return": "err::Err type, if init success, return err::ERR_NONE", + "maixpy": "maix.nn.Speech.init", + "py_doc": "Init the ASR library and select the type and name of the audio device.\n\nArgs:\n - dev_type: device type want to detect, can choose between WAV, PCM, or MIC.\n - device_name: device name want to detect, can choose a WAV file, a PCM file, or a MIC device name.\n\n\nReturns: err::Err type, if init success, return err::ERR_NONE\n" + }, + "args": [ + [ + "nn::SpeechDevice", + "dev_type", + null + ], + [ + "const string &", + "device_name", + "\"\"" + ] + ], + "ret_type": "err::Err", + "static": false, + "def": "err::Err init(nn::SpeechDevice dev_type, const string &device_name = \"\")", + "overload": [ + { + "type": "func", + "name": "init", + "doc": { + "brief": "Init the ASR library and select the type and name of the audio device.", + "param": { + "dev_type": "device type want to detect, can choose between WAV, PCM, or MIC.", + "device_name": "device name want to detect, can choose a WAV file, a PCM file, or a MIC device name." + }, + "throw": [ + "If am model is not loaded, will throw err::ERR_NOT_IMPL.", + "If device is not supported, will throw err::ERR_NOT_IMPL." + ], + "return": "err::Err type, if init success, return err::ERR_NONE", + "maixpy": "maix.nn.Speech.init", + "py_doc": "Init the ASR library and select the type and name of the audio device.\n\nArgs:\n - dev_type: device type want to detect, can choose between WAV, PCM, or MIC.\n - device_name: device name want to detect, can choose a WAV file, a PCM file, or a MIC device name.\n\n\nReturns: err::Err type, if init success, return err::ERR_NONE\n" + }, + "args": [ + [ + "nn::SpeechDevice", + "dev_type", + null + ], + [ + "const string &", + "device_name", + "\"\"" + ] + ], + "ret_type": "err::Err", + "static": false, + "def": "err::Err init(nn::SpeechDevice dev_type, const string &device_name = \"\")" + } + ] + }, + "devive": { + "type": "func", + "name": "devive", + "doc": { + "brief": "Reset the device, usually used for PCM/WAV recognition,\\nsuch as identifying the next WAV file.", + "param": { + "dev_type": "device type want to detect, can choose between WAV, PCM, or MIC.", + "device_name": "device name want to detect, can choose a WAV file, a PCM file, or a MIC device name." + }, + "throw": "If device is not supported, will throw err::ERR_NOT_IMPL.", + "return": "err::Err type, if init success, return err::ERR_NONE", + "maixpy": "maix.nn.Speech.devive", + "py_doc": "Reset the device, usually used for PCM/WAV recognition,\nsuch as identifying the next WAV file.\n\nArgs:\n - dev_type: device type want to detect, can choose between WAV, PCM, or MIC.\n - device_name: device name want to detect, can choose a WAV file, a PCM file, or a MIC device name.\n\n\nReturns: err::Err type, if init success, return err::ERR_NONE\n" + }, + "args": [ + [ + "nn::SpeechDevice", + "dev_type", + null + ], + [ + "const string &", + "device_name", + null + ] + ], + "ret_type": "err::Err", + "static": false, + "def": "err::Err devive(nn::SpeechDevice dev_type, const string &device_name)", + "overload": [ + { + "type": "func", + "name": "devive", + "doc": { + "brief": "Reset the device, usually used for PCM/WAV recognition,\\nsuch as identifying the next WAV file.", + "param": { + "dev_type": "device type want to detect, can choose between WAV, PCM, or MIC.", + "device_name": "device name want to detect, can choose a WAV file, a PCM file, or a MIC device name." + }, + "throw": "If device is not supported, will throw err::ERR_NOT_IMPL.", + "return": "err::Err type, if init success, return err::ERR_NONE", + "maixpy": "maix.nn.Speech.devive", + "py_doc": "Reset the device, usually used for PCM/WAV recognition,\nsuch as identifying the next WAV file.\n\nArgs:\n - dev_type: device type want to detect, can choose between WAV, PCM, or MIC.\n - device_name: device name want to detect, can choose a WAV file, a PCM file, or a MIC device name.\n\n\nReturns: err::Err type, if init success, return err::ERR_NONE\n" + }, + "args": [ + [ + "nn::SpeechDevice", + "dev_type", + null + ], + [ + "const string &", + "device_name", + null + ] + ], + "ret_type": "err::Err", + "static": false, + "def": "err::Err devive(nn::SpeechDevice dev_type, const string &device_name)" + } + ] + }, + "dec_deinit": { + "type": "func", + "name": "dec_deinit", + "doc": { + "brief": "Deinit the decoder.", + "param": { + "decoder": "decoder type want to deinit\ncan choose between DECODER_RAW, DECODER_DIG, DECODER_LVCSR, DECODER_KWS or DECODER_ALL." + }, + "throw": "If device is not supported, will throw err::ERR_NOT_IMPL.", + "maixpy": "maix.nn.Speech.dec_deinit", + "py_doc": "Deinit the decoder.\n\nArgs:\n - decoder: decoder type want to deinit\ncan choose between DECODER_RAW, DECODER_DIG, DECODER_LVCSR, DECODER_KWS or DECODER_ALL.\n" + }, + "args": [ + [ + "nn::SpeechDecoder", + "decoder", + null + ] + ], + "ret_type": "void", + "static": false, + "def": "void dec_deinit(nn::SpeechDecoder decoder)", + "overload": [ + { + "type": "func", + "name": "dec_deinit", + "doc": { + "brief": "Deinit the decoder.", + "param": { + "decoder": "decoder type want to deinit\ncan choose between DECODER_RAW, DECODER_DIG, DECODER_LVCSR, DECODER_KWS or DECODER_ALL." + }, + "throw": "If device is not supported, will throw err::ERR_NOT_IMPL.", + "maixpy": "maix.nn.Speech.dec_deinit", + "py_doc": "Deinit the decoder.\n\nArgs:\n - decoder: decoder type want to deinit\ncan choose between DECODER_RAW, DECODER_DIG, DECODER_LVCSR, DECODER_KWS or DECODER_ALL.\n" + }, + "args": [ + [ + "nn::SpeechDecoder", + "decoder", + null + ] + ], + "ret_type": "void", + "static": false, + "def": "void dec_deinit(nn::SpeechDecoder decoder)" + } + ] + }, + "raw": { + "type": "func", + "name": "raw", + "doc": { + "brief": "Init raw decoder, it will output the prediction results of the original AM.", + "param": { + "callback": "raw decoder user callback." + }, + "return": "err::Err type, if init success, return err::ERR_NONE", + "maixpy": "maix.nn.Speech.raw", + "py_doc": "Init raw decoder, it will output the prediction results of the original AM.\n\nArgs:\n - callback: raw decoder user callback.\n\n\nReturns: err::Err type, if init success, return err::ERR_NONE\n" + }, + "args": [ + [ + "std::function>, int)>", + "callback", + null + ] + ], + "ret_type": "err::Err", + "static": false, + "def": "err::Err raw(std::function>, int)> callback)", + "overload": [ + { + "type": "func", + "name": "raw", + "doc": { + "brief": "Get raw decoder status", + "return": "bool, raw decoder status", + "maixpy": "maix.nn.Speech.raw", + "py_doc": "Get raw decoder status\n\nReturns: bool, raw decoder status\n" + }, + "args": [], + "ret_type": "bool", + "static": false, + "def": "bool raw()" + }, + { + "type": "func", + "name": "raw", + "doc": { + "brief": "Init raw decoder, it will output the prediction results of the original AM.", + "param": { + "callback": "raw decoder user callback." + }, + "return": "err::Err type, if init success, return err::ERR_NONE", + "maixpy": "maix.nn.Speech.raw", + "py_doc": "Init raw decoder, it will output the prediction results of the original AM.\n\nArgs:\n - callback: raw decoder user callback.\n\n\nReturns: err::Err type, if init success, return err::ERR_NONE\n" + }, + "args": [ + [ + "std::function>, int)>", + "callback", + null + ] + ], + "ret_type": "err::Err", + "static": false, + "def": "err::Err raw(std::function>, int)> callback)" + }, + { + "type": "func", + "name": "raw", + "doc": { + "brief": "Get raw decoder status", + "return": "bool, raw decoder status", + "maixpy": "maix.nn.Speech.raw", + "py_doc": "Get raw decoder status\n\nReturns: bool, raw decoder status\n" + }, + "args": [], + "ret_type": "bool", + "static": false, + "def": "bool raw()" + } + ] + }, + "digit": { + "type": "func", + "name": "digit", + "doc": { + "brief": "Init digit decoder, it will output the Chinese digit recognition results within the last 4 seconds.", + "param": { + "blank": "If it exceeds this value, insert a '_' in the output result to indicate idle mute.", + "callback": "digit decoder user callback." + }, + "return": "err::Err type, if init success, return err::ERR_NONE", + "maixpy": "maix.nn.Speech.digit", + "py_doc": "Init digit decoder, it will output the Chinese digit recognition results within the last 4 seconds.\n\nArgs:\n - blank: If it exceeds this value, insert a '_' in the output result to indicate idle mute.\n - callback: digit decoder user callback.\n\n\nReturns: err::Err type, if init success, return err::ERR_NONE\n" + }, + "args": [ + [ + "int", + "blank", + null + ], + [ + "std::function", + "callback", + null + ] + ], + "ret_type": "err::Err", + "static": false, + "def": "err::Err digit(int blank, std::function callback)", + "overload": [ + { + "type": "func", + "name": "digit", + "doc": { + "brief": "Get digit decoder status", + "return": "bool, digit decoder status", + "maixpy": "maix.nn.Speech.digit", + "py_doc": "Get digit decoder status\n\nReturns: bool, digit decoder status\n" + }, + "args": [], + "ret_type": "bool", + "static": false, + "def": "bool digit()" + }, + { + "type": "func", + "name": "digit", + "doc": { + "brief": "Init digit decoder, it will output the Chinese digit recognition results within the last 4 seconds.", + "param": { + "blank": "If it exceeds this value, insert a '_' in the output result to indicate idle mute.", + "callback": "digit decoder user callback." + }, + "return": "err::Err type, if init success, return err::ERR_NONE", + "maixpy": "maix.nn.Speech.digit", + "py_doc": "Init digit decoder, it will output the Chinese digit recognition results within the last 4 seconds.\n\nArgs:\n - blank: If it exceeds this value, insert a '_' in the output result to indicate idle mute.\n - callback: digit decoder user callback.\n\n\nReturns: err::Err type, if init success, return err::ERR_NONE\n" + }, + "args": [ + [ + "int", + "blank", + null + ], + [ + "std::function", + "callback", + null + ] + ], + "ret_type": "err::Err", + "static": false, + "def": "err::Err digit(int blank, std::function callback)" + }, + { + "type": "func", + "name": "digit", + "doc": { + "brief": "Get digit decoder status", + "return": "bool, digit decoder status", + "maixpy": "maix.nn.Speech.digit", + "py_doc": "Get digit decoder status\n\nReturns: bool, digit decoder status\n" + }, + "args": [], + "ret_type": "bool", + "static": false, + "def": "bool digit()" + } + ] + }, + "kws": { + "type": "func", + "name": "kws", + "doc": { + "brief": "Init kws decoder, it will output a probability list of all registered keywords in the latest frame,\\nusers can set their own thresholds for wake-up.", + "param": { + "kw_tbl": "Keyword list, filled in with spaces separated by pinyin, for example: xiao3 ai4 tong2 xue2", + "kw_gate": "kw_gate, keyword probability gate table, the number should be the same as kw_tbl", + "auto_similar": "Whether to perform automatic homophone processing,\nsetting it to true will automatically calculate the probability by using pinyin with different tones as homophones", + "callback": "digit decoder user callback." + }, + "return": "err::Err type, if init success, return err::ERR_NONE", + "maixpy": "maix.nn.Speech.kws", + "py_doc": "Init kws decoder, it will output a probability list of all registered keywords in the latest frame,\nusers can set their own thresholds for wake-up.\n\nArgs:\n - kw_tbl: Keyword list, filled in with spaces separated by pinyin, for example: xiao3 ai4 tong2 xue2\n - kw_gate: kw_gate, keyword probability gate table, the number should be the same as kw_tbl\n - auto_similar: Whether to perform automatic homophone processing,\nsetting it to true will automatically calculate the probability by using pinyin with different tones as homophones\n - callback: digit decoder user callback.\n\n\nReturns: err::Err type, if init success, return err::ERR_NONE\n" + }, + "args": [ + [ + "std::vector", + "kw_tbl", + null + ], + [ + "std::vector", + "kw_gate", + null + ], + [ + "std::function, int)>", + "callback", + null + ], + [ + "bool", + "auto_similar", + "true" + ] + ], + "ret_type": "err::Err", + "static": false, + "def": "err::Err kws(std::vector kw_tbl, std::vector kw_gate, std::function, int)> callback, bool auto_similar = true)", + "overload": [ + { + "type": "func", + "name": "kws", + "doc": { + "brief": "Get kws decoder status", + "return": "bool, kws decoder status", + "maixpy": "maix.nn.Speech.kws", + "py_doc": "Get kws decoder status\n\nReturns: bool, kws decoder status\n" + }, + "args": [], + "ret_type": "bool", + "static": false, + "def": "bool kws()" + }, + { + "type": "func", + "name": "kws", + "doc": { + "brief": "Init kws decoder, it will output a probability list of all registered keywords in the latest frame,\\nusers can set their own thresholds for wake-up.", + "param": { + "kw_tbl": "Keyword list, filled in with spaces separated by pinyin, for example: xiao3 ai4 tong2 xue2", + "kw_gate": "kw_gate, keyword probability gate table, the number should be the same as kw_tbl", + "auto_similar": "Whether to perform automatic homophone processing,\nsetting it to true will automatically calculate the probability by using pinyin with different tones as homophones", + "callback": "digit decoder user callback." + }, + "return": "err::Err type, if init success, return err::ERR_NONE", + "maixpy": "maix.nn.Speech.kws", + "py_doc": "Init kws decoder, it will output a probability list of all registered keywords in the latest frame,\nusers can set their own thresholds for wake-up.\n\nArgs:\n - kw_tbl: Keyword list, filled in with spaces separated by pinyin, for example: xiao3 ai4 tong2 xue2\n - kw_gate: kw_gate, keyword probability gate table, the number should be the same as kw_tbl\n - auto_similar: Whether to perform automatic homophone processing,\nsetting it to true will automatically calculate the probability by using pinyin with different tones as homophones\n - callback: digit decoder user callback.\n\n\nReturns: err::Err type, if init success, return err::ERR_NONE\n" + }, + "args": [ + [ + "std::vector", + "kw_tbl", + null + ], + [ + "std::vector", + "kw_gate", + null + ], + [ + "std::function, int)>", + "callback", + null + ], + [ + "bool", + "auto_similar", + "true" + ] + ], + "ret_type": "err::Err", + "static": false, + "def": "err::Err kws(std::vector kw_tbl, std::vector kw_gate, std::function, int)> callback, bool auto_similar = true)" + }, + { + "type": "func", + "name": "kws", + "doc": { + "brief": "Get kws decoder status", + "return": "bool, kws decoder status", + "maixpy": "maix.nn.Speech.kws", + "py_doc": "Get kws decoder status\n\nReturns: bool, kws decoder status\n" + }, + "args": [], + "ret_type": "bool", + "static": false, + "def": "bool kws()" + } + ] + }, + "lvcsr": { + "type": "func", + "name": "lvcsr", + "doc": { + "brief": "Init lvcsr decoder, it will output continuous speech recognition results (less than 1024 Chinese characters).", + "param": { + "sfst_name": "Sfst file path.", + "sym_name": "Sym file path (output symbol table).", + "phones_txt": "Path to phones.bin (pinyin table).", + "words_txt": "Path to words.bin (dictionary table).", + "callback": "lvcsr decoder user callback.", + "beam": "The beam size for WFST search is set to 8 by default, and it is recommended to be between 3 and 9.\nThe larger the size, the larger the search space, and the more accurate but slower the search.", + "bg_prob": "The absolute value of the natural logarithm of the default probability value for background pinyin\noutside of BEAM-CNT is set to 10 by default.", + "scale": "acoustics_cost = log(pny_prob)*scale.", + "mmap": "use mmap to load the WFST decoding image,\nIf set to true, the beam should be less than 5." + }, + "return": "err::Err type, if init success, return err::ERR_NONE", + "maixpy": "maix.nn.Speech.lvcsr", + "py_doc": "Init lvcsr decoder, it will output continuous speech recognition results (less than 1024 Chinese characters).\n\nArgs:\n - sfst_name: Sfst file path.\n - sym_name: Sym file path (output symbol table).\n - phones_txt: Path to phones.bin (pinyin table).\n - words_txt: Path to words.bin (dictionary table).\n - callback: lvcsr decoder user callback.\n - beam: The beam size for WFST search is set to 8 by default, and it is recommended to be between 3 and 9.\nThe larger the size, the larger the search space, and the more accurate but slower the search.\n - bg_prob: The absolute value of the natural logarithm of the default probability value for background pinyin\noutside of BEAM-CNT is set to 10 by default.\n - scale: acoustics_cost = log(pny_prob)*scale.\n - mmap: use mmap to load the WFST decoding image,\nIf set to true, the beam should be less than 5.\n\n\nReturns: err::Err type, if init success, return err::ERR_NONE\n" + }, + "args": [ + [ + "const string &", + "sfst_name", + null + ], + [ + "const string &", + "sym_name", + null + ], + [ + "const string &", + "phones_txt", + null + ], + [ + "const string &", + "words_txt", + null + ], + [ + "std::function, int)>", + "callback", + null + ], + [ + "float", + "beam", + "8" + ], + [ + "float", + "bg_prob", + "10" + ], + [ + "float", + "scale", + "0.5" + ], + [ + "bool", + "mmap", + "false" + ] + ], + "ret_type": "err::Err", + "static": false, + "def": "err::Err lvcsr(const string &sfst_name, const string &sym_name,\n const string &phones_txt, const string &words_txt, \n std::function, int)> callback,\n float beam = 8, float bg_prob = 10, float scale = 0.5, bool mmap = false)", + "overload": [ + { + "type": "func", + "name": "lvcsr", + "doc": { + "brief": "Get lvcsr decoder status", + "return": "bool, lvcsr decoder status", + "maixpy": "maix.nn.Speech.lvcsr", + "py_doc": "Get lvcsr decoder status\n\nReturns: bool, lvcsr decoder status\n" + }, + "args": [], + "ret_type": "bool", + "static": false, + "def": "bool lvcsr()" + }, + { + "type": "func", + "name": "lvcsr", + "doc": { + "brief": "Init lvcsr decoder, it will output continuous speech recognition results (less than 1024 Chinese characters).", + "param": { + "sfst_name": "Sfst file path.", + "sym_name": "Sym file path (output symbol table).", + "phones_txt": "Path to phones.bin (pinyin table).", + "words_txt": "Path to words.bin (dictionary table).", + "callback": "lvcsr decoder user callback.", + "beam": "The beam size for WFST search is set to 8 by default, and it is recommended to be between 3 and 9.\nThe larger the size, the larger the search space, and the more accurate but slower the search.", + "bg_prob": "The absolute value of the natural logarithm of the default probability value for background pinyin\noutside of BEAM-CNT is set to 10 by default.", + "scale": "acoustics_cost = log(pny_prob)*scale.", + "mmap": "use mmap to load the WFST decoding image,\nIf set to true, the beam should be less than 5." + }, + "return": "err::Err type, if init success, return err::ERR_NONE", + "maixpy": "maix.nn.Speech.lvcsr", + "py_doc": "Init lvcsr decoder, it will output continuous speech recognition results (less than 1024 Chinese characters).\n\nArgs:\n - sfst_name: Sfst file path.\n - sym_name: Sym file path (output symbol table).\n - phones_txt: Path to phones.bin (pinyin table).\n - words_txt: Path to words.bin (dictionary table).\n - callback: lvcsr decoder user callback.\n - beam: The beam size for WFST search is set to 8 by default, and it is recommended to be between 3 and 9.\nThe larger the size, the larger the search space, and the more accurate but slower the search.\n - bg_prob: The absolute value of the natural logarithm of the default probability value for background pinyin\noutside of BEAM-CNT is set to 10 by default.\n - scale: acoustics_cost = log(pny_prob)*scale.\n - mmap: use mmap to load the WFST decoding image,\nIf set to true, the beam should be less than 5.\n\n\nReturns: err::Err type, if init success, return err::ERR_NONE\n" + }, + "args": [ + [ + "const string &", + "sfst_name", + null + ], + [ + "const string &", + "sym_name", + null + ], + [ + "const string &", + "phones_txt", + null + ], + [ + "const string &", + "words_txt", + null + ], + [ + "std::function, int)>", + "callback", + null + ], + [ + "float", + "beam", + "8" + ], + [ + "float", + "bg_prob", + "10" + ], + [ + "float", + "scale", + "0.5" + ], + [ + "bool", + "mmap", + "false" + ] + ], + "ret_type": "err::Err", + "static": false, + "def": "err::Err lvcsr(const string &sfst_name, const string &sym_name,\n const string &phones_txt, const string &words_txt, \n std::function, int)> callback,\n float beam = 8, float bg_prob = 10, float scale = 0.5, bool mmap = false)" + }, + { + "type": "func", + "name": "lvcsr", + "doc": { + "brief": "Get lvcsr decoder status", + "return": "bool, lvcsr decoder status", + "maixpy": "maix.nn.Speech.lvcsr", + "py_doc": "Get lvcsr decoder status\n\nReturns: bool, lvcsr decoder status\n" + }, + "args": [], + "ret_type": "bool", + "static": false, + "def": "bool lvcsr()" + } + ] + }, + "run": { + "type": "func", + "name": "run", + "doc": { + "brief": "Run speech recognition, user can run 1 frame at a time and do other processing after running,\\nor it can run continuously within a thread and be stopped by an external thread.", + "param": { + "frame": "The number of frames per run." + }, + "return": "int type, return actual number of frames in the run.", + "maixpy": "maix.nn.Speech.run", + "py_doc": "Run speech recognition, user can run 1 frame at a time and do other processing after running,\nor it can run continuously within a thread and be stopped by an external thread.\n\nArgs:\n - frame: The number of frames per run.\n\n\nReturns: int type, return actual number of frames in the run.\n" + }, + "args": [ + [ + "int", + "frame", + null + ] + ], + "ret_type": "int", + "static": false, + "def": "int run(int frame)", + "overload": [ + { + "type": "func", + "name": "run", + "doc": { + "brief": "Run speech recognition, user can run 1 frame at a time and do other processing after running,\\nor it can run continuously within a thread and be stopped by an external thread.", + "param": { + "frame": "The number of frames per run." + }, + "return": "int type, return actual number of frames in the run.", + "maixpy": "maix.nn.Speech.run", + "py_doc": "Run speech recognition, user can run 1 frame at a time and do other processing after running,\nor it can run continuously within a thread and be stopped by an external thread.\n\nArgs:\n - frame: The number of frames per run.\n\n\nReturns: int type, return actual number of frames in the run.\n" + }, + "args": [ + [ + "int", + "frame", + null + ] + ], + "ret_type": "int", + "static": false, + "def": "int run(int frame)" + } + ] + }, + "clear": { + "type": "func", + "name": "clear", + "doc": { + "brief": "Reset internal cache operation", + "maixpy": "maix.nn.Speech.clear", + "py_doc": "Reset internal cache operation" + }, + "args": [], + "ret_type": "void", + "static": false, + "def": "void clear()", + "overload": [ + { + "type": "func", + "name": "clear", + "doc": { + "brief": "Reset internal cache operation", + "maixpy": "maix.nn.Speech.clear", + "py_doc": "Reset internal cache operation" + }, + "args": [], + "ret_type": "void", + "static": false, + "def": "void clear()" + } + ] + }, + "frame_time": { + "type": "func", + "name": "frame_time", + "doc": { + "brief": "Get the time of one frame.", + "return": "int type, return the time of one frame.", + "maixpy": "maix.nn.Speech.frame_time", + "py_doc": "Get the time of one frame.\n\nReturns: int type, return the time of one frame.\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int frame_time()", + "overload": [ + { + "type": "func", + "name": "frame_time", + "doc": { + "brief": "Get the time of one frame.", + "return": "int type, return the time of one frame.", + "maixpy": "maix.nn.Speech.frame_time", + "py_doc": "Get the time of one frame.\n\nReturns: int type, return the time of one frame.\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int frame_time()" + } + ] + }, + "similar": { + "type": "func", + "name": "similar", + "doc": { + "brief": "Manually register mute words, and each pinyin can register up to 10 homophones,\\nplease note that using this interface to register homophones will overwrite,\\nthe homophone table automatically generated in the \\\"automatic homophone processing\\\" feature.", + "param": { + "dev_type": "device type want to detect, can choose between WAV, PCM, or MIC.", + "device_name": "device name want to detect, can choose a WAV file, a PCM file, or a MIC device name." + }, + "return": "err::Err type, if init success, return err::ERR_NONE", + "maixpy": "maix.nn.Speech.similar", + "py_doc": "Manually register mute words, and each pinyin can register up to 10 homophones,\nplease note that using this interface to register homophones will overwrite,\nthe homophone table automatically generated in the \"automatic homophone processing\" feature.\n\nArgs:\n - dev_type: device type want to detect, can choose between WAV, PCM, or MIC.\n - device_name: device name want to detect, can choose a WAV file, a PCM file, or a MIC device name.\n\n\nReturns: err::Err type, if init success, return err::ERR_NONE\n" + }, + "args": [ + [ + "const string &", + "pny", + null + ], + [ + "std::vector", + "similar_pnys", + null + ] + ], + "ret_type": "err::Err", + "static": false, + "def": "err::Err similar(const string &pny, std::vector similar_pnys)", + "overload": [ + { + "type": "func", + "name": "similar", + "doc": { + "brief": "Manually register mute words, and each pinyin can register up to 10 homophones,\\nplease note that using this interface to register homophones will overwrite,\\nthe homophone table automatically generated in the \\\"automatic homophone processing\\\" feature.", + "param": { + "dev_type": "device type want to detect, can choose between WAV, PCM, or MIC.", + "device_name": "device name want to detect, can choose a WAV file, a PCM file, or a MIC device name." + }, + "return": "err::Err type, if init success, return err::ERR_NONE", + "maixpy": "maix.nn.Speech.similar", + "py_doc": "Manually register mute words, and each pinyin can register up to 10 homophones,\nplease note that using this interface to register homophones will overwrite,\nthe homophone table automatically generated in the \"automatic homophone processing\" feature.\n\nArgs:\n - dev_type: device type want to detect, can choose between WAV, PCM, or MIC.\n - device_name: device name want to detect, can choose a WAV file, a PCM file, or a MIC device name.\n\n\nReturns: err::Err type, if init success, return err::ERR_NONE\n" + }, + "args": [ + [ + "const string &", + "pny", + null + ], + [ + "std::vector", + "similar_pnys", + null + ] + ], + "ret_type": "err::Err", + "static": false, + "def": "err::Err similar(const string &pny, std::vector similar_pnys)" + } + ] + }, + "skip_frames": { + "type": "func", + "name": "skip_frames", + "doc": { + "brief": "Run some frames and drop, this can be used to avoid\\nincorrect recognition results when switching decoders.", + "param": { + "num": "number of frames to run and drop" + }, + "maixpy": "maix.nn.Speech.skip_frames", + "py_doc": "Run some frames and drop, this can be used to avoid\nincorrect recognition results when switching decoders.\n\nArgs:\n - num: number of frames to run and drop\n" + }, + "args": [ + [ + "int", + "num", + null + ] + ], + "ret_type": "void", + "static": false, + "def": "void skip_frames(int num)", + "overload": [ + { + "type": "func", + "name": "skip_frames", + "doc": { + "brief": "Run some frames and drop, this can be used to avoid\\nincorrect recognition results when switching decoders.", + "param": { + "num": "number of frames to run and drop" + }, + "maixpy": "maix.nn.Speech.skip_frames", + "py_doc": "Run some frames and drop, this can be used to avoid\nincorrect recognition results when switching decoders.\n\nArgs:\n - num: number of frames to run and drop\n" + }, + "args": [ + [ + "int", + "num", + null + ] + ], + "ret_type": "void", + "static": false, + "def": "void skip_frames(int num)" + } + ] + }, + "mean": { + "type": "var", + "name": "mean", + "doc": { + "brief": "Get mean value, list type", + "maixpy": "maix.nn.Speech.mean", + "py_doc": "Get mean value, list type" + }, + "value": null, + "static": false, + "readonly": false, + "def": "std::vector mean" + }, + "scale": { + "type": "var", + "name": "scale", + "doc": { + "brief": "Get scale value, list type", + "maixpy": "maix.nn.Speech.scale", + "py_doc": "Get scale value, list type" + }, + "value": null, + "static": false, + "readonly": false, + "def": "std::vector scale" + }, + "dev_type": { + "type": "func", + "name": "dev_type", + "doc": { + "brief": "get device type", + "return": "nn::SpeechDevice type, see SpeechDevice of this module", + "maixpy": "maix.nn.Speech.dev_type", + "py_doc": "get device type\n\nReturns: nn::SpeechDevice type, see SpeechDevice of this module\n" + }, + "args": [], + "ret_type": "nn::SpeechDevice", + "static": false, + "def": "nn::SpeechDevice dev_type()", + "overload": [ + { + "type": "func", + "name": "dev_type", + "doc": { + "brief": "get device type", + "return": "nn::SpeechDevice type, see SpeechDevice of this module", + "maixpy": "maix.nn.Speech.dev_type", + "py_doc": "get device type\n\nReturns: nn::SpeechDevice type, see SpeechDevice of this module\n" + }, + "args": [], + "ret_type": "nn::SpeechDevice", + "static": false, + "def": "nn::SpeechDevice dev_type()" + } + ] + } + }, + "def": "class Speech" + }, + "YOLOv8": { + "type": "class", + "name": "YOLOv8", + "doc": { + "brief": "YOLOv8 class", + "maixpy": "maix.nn.YOLOv8", + "py_doc": "YOLOv8 class" + }, + "members": { + "YOLOv8": { + "type": "func", + "name": "YOLOv8", + "doc": { + "brief": "Constructor of YOLOv8 class", + "param": { + "model": "model path, default empty, you can load model later by load function.", + "dual_buff": "direction [in], prepare dual input output buffer to accelarate forward, that is, when NPU is forwarding we not wait and prepare the next input buff.\nIf you want to ensure every time forward output the input's result, set this arg to false please.\nDefault true to ensure speed." + }, + "throw": "If model arg is not empty and load failed, will throw err::Exception.", + "maixpy": "maix.nn.YOLOv8.__init__", + "maixcdk": "maix.nn.YOLOv8.YOLOv8", + "py_doc": "Constructor of YOLOv8 class\n\nArgs:\n - model: model path, default empty, you can load model later by load function.\n - dual_buff: direction [in], prepare dual input output buffer to accelarate forward, that is, when NPU is forwarding we not wait and prepare the next input buff.\nIf you want to ensure every time forward output the input's result, set this arg to false please.\nDefault true to ensure speed.\n" + }, + "args": [ + [ + "const string &", + "model", + "\"\"" + ], + [ + "bool", + "dual_buff", + "true" + ] + ], + "ret_type": null, + "static": false, + "def": "YOLOv8(const string &model = \"\", bool dual_buff = true)" + }, + "load": { + "type": "func", + "name": "load", + "doc": { + "brief": "Load model from file", + "param": { + "model": "Model path want to load" + }, + "return": "err::Err", + "maixpy": "maix.nn.YOLOv8.load", + "py_doc": "Load model from file\n\nArgs:\n - model: Model path want to load\n\n\nReturns: err::Err\n" + }, + "args": [ + [ + "const string &", + "model", + null + ] + ], + "ret_type": "err::Err", + "static": false, + "def": "err::Err load(const string &model)" + }, + "detect": { + "type": "func", + "name": "detect", + "doc": { + "brief": "Detect objects from image", + "param": { + "img": "Image want to detect, if image's size not match model input's, will auto resize with fit method.", + "conf_th": "Confidence threshold, default 0.5.", + "iou_th": "IoU threshold, default 0.45.", + "fit": "Resize method, default image.Fit.FIT_CONTAIN.", + "keypoint_th": "keypoint threshold, default 0.5, only for yolov8-pose model." + }, + "throw": "If image format not match model input format, will throw err::Exception.", + "return": "Object list. In C++, you should delete it after use.\nIf model is yolov8-pose, object's points have value, and if points' value < 0 means that point is invalid(conf < keypoint_th).", + "maixpy": "maix.nn.YOLOv8.detect", + "py_doc": "Detect objects from image\n\nArgs:\n - img: Image want to detect, if image's size not match model input's, will auto resize with fit method.\n - conf_th: Confidence threshold, default 0.5.\n - iou_th: IoU threshold, default 0.45.\n - fit: Resize method, default image.Fit.FIT_CONTAIN.\n - keypoint_th: keypoint threshold, default 0.5, only for yolov8-pose model.\n\n\nReturns: Object list. In C++, you should delete it after use.\nIf model is yolov8-pose, object's points have value, and if points' value < 0 means that point is invalid(conf < keypoint_th).\n" + }, + "args": [ + [ + "image::Image &", + "img", + null + ], + [ + "float", + "conf_th", + "0.5" + ], + [ + "float", + "iou_th", + "0.45" + ], + [ + "maix::image::Fit", + "fit", + "maix::image::FIT_CONTAIN" + ], + [ + "float", + "keypoint_th", + "0.5" + ] + ], + "ret_type": "nn::Objects*", + "static": false, + "def": "nn::Objects *detect(image::Image &img, float conf_th = 0.5, float iou_th = 0.45, maix::image::Fit fit = maix::image::FIT_CONTAIN, float keypoint_th = 0.5)" + }, + "input_size": { + "type": "func", + "name": "input_size", + "doc": { + "brief": "Get model input size", + "return": "model input size", + "maixpy": "maix.nn.YOLOv8.input_size", + "py_doc": "Get model input size\n\nReturns: model input size\n" + }, + "args": [], + "ret_type": "image::Size", + "static": false, + "def": "image::Size input_size()" + }, + "input_width": { + "type": "func", + "name": "input_width", + "doc": { + "brief": "Get model input width", + "return": "model input size of width", + "maixpy": "maix.nn.YOLOv8.input_width", + "py_doc": "Get model input width\n\nReturns: model input size of width\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int input_width()" + }, + "input_height": { + "type": "func", + "name": "input_height", + "doc": { + "brief": "Get model input height", + "return": "model input size of height", + "maixpy": "maix.nn.YOLOv8.input_height", + "py_doc": "Get model input height\n\nReturns: model input size of height\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int input_height()" + }, + "input_format": { + "type": "func", + "name": "input_format", + "doc": { + "brief": "Get input image format", + "return": "input image format, image::Format type.", + "maixpy": "maix.nn.YOLOv8.input_format", + "py_doc": "Get input image format\n\nReturns: input image format, image::Format type.\n" + }, + "args": [], + "ret_type": "image::Format", + "static": false, + "def": "image::Format input_format()" + }, + "draw_pose": { + "type": "func", + "name": "draw_pose", + "doc": { + "brief": "Draw pose keypoints on image", + "param": { + "img": "image object, maix.image.Image type.", + "points": "keypoits, int list type, [x, y, x, y ...]", + "radius": "radius of points.", + "color": "color of points.", + "body": "true, if points' length is 17*2 and body is ture, will draw lines as human body, if set to false won't draw lines, default true." + }, + "maixpy": "maix.nn.YOLOv8.draw_pose", + "py_doc": "Draw pose keypoints on image\n\nArgs:\n - img: image object, maix.image.Image type.\n - points: keypoits, int list type, [x, y, x, y ...]\n - radius: radius of points.\n - color: color of points.\n - body: true, if points' length is 17*2 and body is ture, will draw lines as human body, if set to false won't draw lines, default true.\n" + }, + "args": [ + [ + "image::Image &", + "img", + null + ], + [ + "std::vector", + "points", + null + ], + [ + "int", + "radius", + "4" + ], + [ + "image::Color", + "color", + "image::COLOR_RED" + ], + [ + "bool", + "body", + "true" + ] + ], + "ret_type": "void", + "static": false, + "def": "void draw_pose(image::Image &img, std::vector points, int radius = 4, image::Color color = image::COLOR_RED, bool body = true)" + }, + "draw_seg_mask": { + "type": "func", + "name": "draw_seg_mask", + "doc": { + "brief": "Draw segmentation on image", + "param": { + "img": "image object, maix.image.Image type.", + "seg_mask": "segmentation mask image by detect method, a grayscale image", + "threshold": "only mask's value > threshold will be draw on image, value from 0 to 255." + }, + "maixpy": "maix.nn.YOLOv8.draw_seg_mask", + "py_doc": "Draw segmentation on image\n\nArgs:\n - img: image object, maix.image.Image type.\n - seg_mask: segmentation mask image by detect method, a grayscale image\n - threshold: only mask's value > threshold will be draw on image, value from 0 to 255.\n" + }, + "args": [ + [ + "image::Image &", + "img", + null + ], + [ + "int", + "x", + null + ], + [ + "int", + "y", + null + ], + [ + "image::Image &", + "seg_mask", + null + ], + [ + "int", + "threshold", + "127" + ] + ], + "ret_type": "void", + "static": false, + "def": "void draw_seg_mask(image::Image &img, int x, int y, image::Image &seg_mask, int threshold = 127)" + }, + "labels": { + "type": "var", + "name": "labels", + "doc": { + "brief": "Labels list", + "maixpy": "maix.nn.YOLOv8.labels", + "py_doc": "Labels list" + }, + "value": null, + "static": false, + "readonly": false, + "def": "std::vector labels" + }, + "label_path": { + "type": "var", + "name": "label_path", + "doc": { + "brief": "Label file path", + "maixpy": "maix.nn.YOLOv8.label_path", + "py_doc": "Label file path" + }, + "value": null, + "static": false, + "readonly": false, + "def": "std::string label_path" + }, + "mean": { + "type": "var", + "name": "mean", + "doc": { + "brief": "Get mean value, list type", + "maixpy": "maix.nn.YOLOv8.mean", + "py_doc": "Get mean value, list type" + }, + "value": null, + "static": false, + "readonly": false, + "def": "std::vector mean" + }, + "scale": { + "type": "var", + "name": "scale", + "doc": { + "brief": "Get scale value, list type", + "maixpy": "maix.nn.YOLOv8.scale", + "py_doc": "Get scale value, list type" + }, + "value": null, + "static": false, + "readonly": false, + "def": "std::vector scale" + } + }, + "def": "class YOLOv8" + }, + "Object": { + "type": "class", + "name": "Object", + "doc": { + "brief": "Object for detect result", + "maixpy": "maix.nn.Object", + "py_doc": "Object for detect result" + }, + "members": { + "Object": { + "type": "func", + "name": "Object", + "doc": { + "brief": "Constructor of Object for detect result", + "param": { + "x": "left top x", + "y": "left top y", + "w": "width", + "h": "height", + "class_id": "class id", + "score": "score" + }, + "maixpy": "maix.nn.Object.__init__", + "maixcdk": "maix.nn.Object.Object", + "py_doc": "Constructor of Object for detect result\n\nArgs:\n - x: left top x\n - y: left top y\n - w: width\n - h: height\n - class_id: class id\n - score: score\n" + }, + "args": [ + [ + "int", + "x", + "0" + ], + [ + "int", + "y", + "0" + ], + [ + "int", + "w", + "0" + ], + [ + "int", + "h", + "0" + ], + [ + "int", + "class_id", + "0" + ], + [ + "float", + "score", + "0" + ], + [ + "std::vector", + "points", + "std::vector()" + ] + ], + "ret_type": null, + "static": false, + "def": "Object(int x = 0, int y = 0, int w = 0, int h = 0, int class_id = 0, float score = 0, std::vector points = std::vector())" + }, + "to_str": { + "type": "func", + "name": "to_str", + "doc": { + "brief": "Object info to string", + "return": "Object info string", + "maixpy": "maix.nn.Object.__str__", + "maixcdk": "maix.nn.Object.to_str", + "py_doc": "Object info to string\n\nReturns: Object info string\n" + }, + "args": [], + "ret_type": "std::string", + "static": false, + "def": "std::string to_str()" + }, + "x": { + "type": "var", + "name": "x", + "doc": { + "brief": "Object left top coordinate x", + "maixpy": "maix.nn.Object.x", + "py_doc": "Object left top coordinate x" + }, + "value": null, + "static": false, + "readonly": false, + "def": "int x" + }, + "y": { + "type": "var", + "name": "y", + "doc": { + "brief": "Object left top coordinate y", + "maixpy": "maix.nn.Object.y", + "py_doc": "Object left top coordinate y" + }, + "value": null, + "static": false, + "readonly": false, + "def": "int y" + }, + "w": { + "type": "var", + "name": "w", + "doc": { + "brief": "Object width", + "maixpy": "maix.nn.Object.w", + "py_doc": "Object width" + }, + "value": null, + "static": false, + "readonly": false, + "def": "int w" + }, + "h": { + "type": "var", + "name": "h", + "doc": { + "brief": "Object height", + "maixpy": "maix.nn.Object.h", + "py_doc": "Object height" + }, + "value": null, + "static": false, + "readonly": false, + "def": "int h" + }, + "class_id": { + "type": "var", + "name": "class_id", + "doc": { + "brief": "Object class id", + "maixpy": "maix.nn.Object.class_id", + "py_doc": "Object class id" + }, + "value": null, + "static": false, + "readonly": false, + "def": "int class_id" + }, + "score": { + "type": "var", + "name": "score", + "doc": { + "brief": "Object score", + "maixpy": "maix.nn.Object.score", + "py_doc": "Object score" + }, + "value": null, + "static": false, + "readonly": false, + "def": "float score" + }, + "points": { + "type": "var", + "name": "points", + "doc": { + "brief": "keypoints", + "maixpy": "maix.nn.Object.points", + "py_doc": "keypoints" + }, + "value": null, + "static": false, + "readonly": false, + "def": "std::vector points" + }, + "seg_mask": { + "type": "var", + "name": "seg_mask", + "doc": { + "brief": "segmentation mask, uint8 list type, shape is h * w but flattened to one dimension, value fron 0 to 255.", + "attention": "For efficiency, it's a pointer in C++, use this carefully!", + "maixpy": "maix.nn.Object.seg_mask", + "py_doc": "segmentation mask, uint8 list type, shape is h * w but flattened to one dimension, value fron 0 to 255." + }, + "value": null, + "static": false, + "readonly": false, + "def": "image::Image *seg_mask" + } + }, + "def": "class Object" + }, + "ObjectFloat": { + "type": "class", + "name": "ObjectFloat", + "doc": { + "brief": "Object for detect result", + "maixpy": "maix.nn.ObjectFloat", + "py_doc": "Object for detect result" + }, + "members": { + "ObjectFloat": { + "type": "func", + "name": "ObjectFloat", + "doc": { + "brief": "Constructor of Object for detect result", + "param": { + "x": "left top x", + "y": "left top y", + "w": "width", + "h": "height", + "class_id": "class id", + "score": "score" + }, + "maixpy": "maix.nn.ObjectFloat.__init__", + "maixcdk": "maix.nn.ObjectFloat.ObjectFloat", + "py_doc": "Constructor of Object for detect result\n\nArgs:\n - x: left top x\n - y: left top y\n - w: width\n - h: height\n - class_id: class id\n - score: score\n" + }, + "args": [ + [ + "float", + "x", + "0" + ], + [ + "float", + "y", + "0" + ], + [ + "float", + "w", + "0" + ], + [ + "float", + "h", + "0" + ], + [ + "float", + "class_id", + "0" + ], + [ + "float", + "score", + "0" + ], + [ + "std::vector", + "points", + "std::vector()" + ] + ], + "ret_type": null, + "static": false, + "def": "ObjectFloat(float x = 0, float y = 0, float w = 0, float h = 0, float class_id = 0, float score = 0, std::vector points = std::vector())" + }, + "to_str": { + "type": "func", + "name": "to_str", + "doc": { + "brief": "Object info to string", + "return": "Object info string", + "maixpy": "maix.nn.ObjectFloat.__str__", + "maixcdk": "maix.nn.ObjectFloat.to_str", + "py_doc": "Object info to string\n\nReturns: Object info string\n" + }, + "args": [], + "ret_type": "std::string", + "static": false, + "def": "std::string to_str()" + }, + "x": { + "type": "var", + "name": "x", + "doc": { + "brief": "Object left top coordinate x", + "maixpy": "maix.nn.ObjectFloat.x", + "py_doc": "Object left top coordinate x" + }, + "value": null, + "static": false, + "readonly": false, + "def": "float x" + }, + "y": { + "type": "var", + "name": "y", + "doc": { + "brief": "Object left top coordinate y", + "maixpy": "maix.nn.ObjectFloat.y", + "py_doc": "Object left top coordinate y" + }, + "value": null, + "static": false, + "readonly": false, + "def": "float y" + }, + "w": { + "type": "var", + "name": "w", + "doc": { + "brief": "Object width", + "maixpy": "maix.nn.ObjectFloat.w", + "py_doc": "Object width" + }, + "value": null, + "static": false, + "readonly": false, + "def": "float w" + }, + "h": { + "type": "var", + "name": "h", + "doc": { + "brief": "Object height", + "maixpy": "maix.nn.ObjectFloat.h", + "py_doc": "Object height" + }, + "value": null, + "static": false, + "readonly": false, + "def": "float h" + }, + "class_id": { + "type": "var", + "name": "class_id", + "doc": { + "brief": "Object class id", + "maixpy": "maix.nn.ObjectFloat.class_id", + "py_doc": "Object class id" + }, + "value": null, + "static": false, + "readonly": false, + "def": "float class_id" + }, + "score": { + "type": "var", + "name": "score", + "doc": { + "brief": "Object score", + "maixpy": "maix.nn.ObjectFloat.score", + "py_doc": "Object score" + }, + "value": null, + "static": false, + "readonly": false, + "def": "float score" + }, + "points": { + "type": "var", + "name": "points", + "doc": { + "brief": "keypoints", + "maixpy": "maix.nn.ObjectFloat.points", + "py_doc": "keypoints" + }, + "value": null, + "static": false, + "readonly": false, + "def": "std::vector points" + } + }, + "def": "class ObjectFloat" + }, + "Objects": { + "type": "class", + "name": "Objects", + "doc": { + "brief": "Objects Class for detect result", + "maixpy": "maix.nn.Objects", + "py_doc": "Objects Class for detect result" + }, + "members": { + "Objects": { + "type": "func", + "name": "Objects", + "doc": { + "brief": "Constructor of Objects class", + "maixpy": "maix.nn.Objects.__init__", + "maixcdk": "maix.nn.Objects.Objects", + "py_doc": "Constructor of Objects class" + }, + "args": [], + "ret_type": null, + "static": false, + "def": "Objects()" + }, + "add": { + "type": "func", + "name": "add", + "doc": { + "brief": "Add object to objects", + "throw": "Throw exception if no memory", + "maixpy": "maix.nn.Objects.add", + "py_doc": "Add object to objects" + }, + "args": [ + [ + "int", + "x", + "0" + ], + [ + "int", + "y", + "0" + ], + [ + "int", + "w", + "0" + ], + [ + "int", + "h", + "0" + ], + [ + "int", + "class_id", + "0" + ], + [ + "float", + "score", + "0" + ], + [ + "std::vector", + "points", + "std::vector()" + ] + ], + "ret_type": "nn::Object&", + "static": false, + "def": "nn::Object &add(int x = 0, int y = 0, int w = 0, int h = 0, int class_id = 0, float score = 0, std::vector points = std::vector())" + }, + "remove": { + "type": "func", + "name": "remove", + "doc": { + "brief": "Remove object form objects", + "maixpy": "maix.nn.Objects.remove", + "py_doc": "Remove object form objects" + }, + "args": [ + [ + "int", + "idx", + null + ] + ], + "ret_type": "err::Err", + "static": false, + "def": "err::Err remove(int idx)" + }, + "at": { + "type": "func", + "name": "at", + "doc": { + "brief": "Get object item", + "maixpy": "maix.nn.Objects.at", + "py_doc": "Get object item" + }, + "args": [ + [ + "int", + "idx", + null + ] + ], + "ret_type": "nn::Object&", + "static": false, + "def": "nn::Object &at(int idx)" + }, + "[]": { + "type": "func", + "name": "operator[]", + "doc": { + "brief": "Get object item", + "maixpy": "maix.nn.Objects.__getitem__", + "maixcdk": "maix.nn.Objects.[]", + "py_doc": "Get object item" + }, + "args": [ + [ + "int", + "idx", + null + ] + ], + "ret_type": "nn::Object&", + "static": false, + "def": "nn::Object &operator[](int idx)" + }, + "size": { + "type": "func", + "name": "size", + "doc": { + "brief": "Get size", + "maixpy": "maix.nn.Objects.__len__", + "maixcdk": "maix.nn.Objects.size", + "py_doc": "Get size" + }, + "args": [], + "ret_type": "size_t", + "static": false, + "def": "size_t size()" + }, + "begin": { + "type": "func", + "name": "begin", + "doc": { + "brief": "Begin", + "maixpy": "maix.nn.Objects.__iter__", + "maixcdk": "maix.nn.Objects.begin", + "py_doc": "Begin" + }, + "args": [], + "ret_type": "std::vector::iterator", + "static": false, + "def": "std::vector::iterator begin()" + }, + "end": { + "type": "func", + "name": "end", + "doc": { + "brief": "End", + "maixcdk": "maix.nn.Objects.end", + "py_doc": "End" + }, + "args": [], + "ret_type": "std::vector::iterator", + "static": false, + "def": "std::vector::iterator end()" + } + }, + "def": "class Objects" + }, + "MUD": { + "type": "class", + "name": "MUD", + "doc": { + "brief": "MUD(model universal describe file) class", + "maixpy": "maix.nn.MUD", + "py_doc": "MUD(model universal describe file) class" + }, + "members": { + "MUD": { + "type": "func", + "name": "MUD", + "doc": { + "brief": "MUD constructor", + "param": { + "model_path": "direction [in], model file path, model format can be MUD(model universal describe file) file.\nIf model_path set, will load model from file, load failed will raise err.Exception.\nIf model_path not set, you can load model later by load function." + }, + "maixpy": "maix.nn.MUD.__init__", + "maixcdk": "maix.nn.MUD.MUD", + "py_doc": "MUD constructor\n\nArgs:\n - model_path: direction [in], model file path, model format can be MUD(model universal describe file) file.\nIf model_path set, will load model from file, load failed will raise err.Exception.\nIf model_path not set, you can load model later by load function.\n" + }, + "args": [ + [ + "const char *", + "model_path", + "nullptr" + ] + ], + "ret_type": null, + "static": false, + "def": "MUD(const char *model_path = nullptr)" + }, + "load": { + "type": "func", + "name": "load", + "doc": { + "brief": "Load model from file", + "param": { + "model_path": "direction [in], model file path, model format can be MUD(model universal describe file) file." + }, + "return": "error code, if load success, return err::ERR_NONE", + "maixpy": "maix.nn.MUD.load", + "py_doc": "Load model from file\n\nArgs:\n - model_path: direction [in], model file path, model format can be MUD(model universal describe file) file.\n\n\nReturns: error code, if load success, return err::ERR_NONE\n" + }, + "args": [ + [ + "const std::string &", + "model_path", + null + ] + ], + "ret_type": "err::Err", + "static": false, + "def": "err::Err load(const std::string &model_path)" + }, + "type": { + "type": "var", + "name": "type", + "doc": { + "brief": "Model type, string type", + "maixpy": "maix.nn.MUD.type", + "py_doc": "Model type, string type" + }, + "value": null, + "static": false, + "readonly": false, + "def": "std::string type" + }, + "items": { + "type": "var", + "name": "items", + "doc": { + "brief": "Model config items, different model type has different config items", + "maixpy": "maix.nn.MUD.items", + "py_doc": "Model config items, different model type has different config items" + }, + "value": null, + "static": false, + "readonly": false, + "def": "std::map> items" + } + }, + "def": "class MUD" + }, + "LayerInfo": { + "type": "class", + "name": "LayerInfo", + "doc": { + "brief": "NN model layer info", + "maixpy": "maix.nn.LayerInfo", + "py_doc": "NN model layer info" + }, + "members": { + "LayerInfo": { + "type": "func", + "name": "LayerInfo", + "doc": { + "brief": "LayerInfo constructor", + "param": { + "name": "direction [in], layer name", + "dtype": "direction [in], layer data type", + "shape": "direction [in], layer shape" + }, + "maixpy": "maix.nn.LayerInfo.__init__", + "maixcdk": "maix.nn.LayerInfo.LayerInfo", + "py_doc": "LayerInfo constructor\n\nArgs:\n - name: direction [in], layer name\n - dtype: direction [in], layer data type\n - shape: direction [in], layer shape\n" + }, + "args": [ + [ + "const std::string &", + "name", + "\"\"" + ], + [ + "tensor::DType", + "dtype", + "tensor::DType::FLOAT32" + ], + [ + "std::vector", + "shape", + "std::vector()" + ] + ], + "ret_type": null, + "static": false, + "def": "LayerInfo(const std::string &name = \"\", tensor::DType dtype = tensor::DType::FLOAT32, std::vector shape = std::vector())" + }, + "name": { + "type": "var", + "name": "name", + "doc": { + "brief": "Layer name", + "maixpy": "maix.nn.LayerInfo.name", + "py_doc": "Layer name" + }, + "value": null, + "static": false, + "readonly": false, + "def": "std::string name" + }, + "dtype": { + "type": "var", + "name": "dtype", + "doc": { + "brief": "Layer data type", + "attention": "If model is quantized, this is the real quantized data type like int8 float16,\nin most scene, inputs and outputs we actually use float32 in API like forward.", + "maixpy": "maix.nn.LayerInfo.dtype", + "py_doc": "Layer data type" + }, + "value": null, + "static": false, + "readonly": false, + "def": "tensor::DType dtype" + }, + "shape": { + "type": "var", + "name": "shape", + "doc": { + "brief": "Layer shape", + "maixpy": "maix.nn.LayerInfo.shape", + "py_doc": "Layer shape" + }, + "value": null, + "static": false, + "readonly": false, + "def": "std::vector shape" + }, + "shape_int": { + "type": "func", + "name": "shape_int", + "doc": { + "brief": "Shape as one int type, multiply all dims of shape", + "maixpy": "maix.nn.LayerInfo.shape_int", + "py_doc": "Shape as one int type, multiply all dims of shape" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int shape_int()" + }, + "to_str": { + "type": "func", + "name": "to_str", + "doc": { + "brief": "To string", + "maixpy": "maix.nn.LayerInfo.to_str", + "py_doc": "To string" + }, + "args": [], + "ret_type": "std::string", + "static": false, + "def": "std::string to_str()" + }, + "__str__": { + "type": "func", + "name": "__str__", + "doc": { + "brief": "To string", + "maixpy": "maix.nn.LayerInfo.__str__", + "py_doc": "To string" + }, + "args": [], + "ret_type": "std::string", + "static": false, + "def": "std::string __str__()" + } + }, + "def": "class LayerInfo" + }, + "NN": { + "type": "class", + "name": "NN", + "doc": { + "brief": "Neural network class", + "maixpy": "maix.nn.NN", + "py_doc": "Neural network class" + }, + "members": { + "__init__": { + "type": "func", + "name": "NN", + "doc": { + "brief": "Neural network constructor", + "param": { + "model": "direction [in], model file path, model format can be MUD(model universal describe file) file.\nIf model_path set, will load model from file, load failed will raise err.Exception.\nIf model_path not set, you can load model later by load function.", + "dual_buff": "direction [in], prepare dual input output buffer to accelarate forward, that is, when NPU is forwarding we not wait and prepare the next input buff.\nIf you want to ensure every time forward output the input's result, set this arg to false please.\nDefault true to ensure speed." + }, + "maixpy": "maix.nn.NN.__init__", + "py_doc": "Neural network constructor\n\nArgs:\n - model: direction [in], model file path, model format can be MUD(model universal describe file) file.\nIf model_path set, will load model from file, load failed will raise err.Exception.\nIf model_path not set, you can load model later by load function.\n - dual_buff: direction [in], prepare dual input output buffer to accelarate forward, that is, when NPU is forwarding we not wait and prepare the next input buff.\nIf you want to ensure every time forward output the input's result, set this arg to false please.\nDefault true to ensure speed.\n" + }, + "args": [ + [ + "const std::string &", + "model", + "\"\"" + ], + [ + "bool", + "dual_buff", + "true" + ] + ], + "ret_type": null, + "static": false, + "def": "NN(const std::string &model = \"\", bool dual_buff = true)" + }, + "load": { + "type": "func", + "name": "load", + "doc": { + "brief": "Load model from file", + "param": { + "model": "direction [in], model file path, model format can be MUD(model universal describe file) file." + }, + "return": "error code, if load success, return err::ERR_NONE", + "maixpy": "maix.nn.NN.load", + "py_doc": "Load model from file\n\nArgs:\n - model: direction [in], model file path, model format can be MUD(model universal describe file) file.\n\n\nReturns: error code, if load success, return err::ERR_NONE\n" + }, + "args": [ + [ + "const std::string &", + "model", + null + ] + ], + "ret_type": "err::Err", + "static": false, + "def": "err::Err load(const std::string &model)" + }, + "loaded": { + "type": "func", + "name": "loaded", + "doc": { + "brief": "Is model loaded", + "return": "true if model loaded, else false", + "maixpy": "maix.nn.NN.loaded", + "py_doc": "Is model loaded\n\nReturns: true if model loaded, else false\n" + }, + "args": [], + "ret_type": "bool", + "static": false, + "def": "bool loaded()" + }, + "set_dual_buff": { + "type": "func", + "name": "set_dual_buff", + "doc": { + "brief": "Enable dual buff or disable dual buff", + "param": { + "enable": "true to enable, false to disable" + }, + "maixpy": "maix.nn.NN.set_dual_buff", + "py_doc": "Enable dual buff or disable dual buff\n\nArgs:\n - enable: true to enable, false to disable\n" + }, + "args": [ + [ + "bool", + "enable", + null + ] + ], + "ret_type": "void", + "static": false, + "def": "void set_dual_buff(bool enable)" + }, + "inputs_info": { + "type": "func", + "name": "inputs_info", + "doc": { + "brief": "Get model input layer info", + "return": "input layer info", + "maixpy": "maix.nn.NN.inputs_info", + "py_doc": "Get model input layer info\n\nReturns: input layer info\n" + }, + "args": [], + "ret_type": "std::vector", + "static": false, + "def": "std::vector inputs_info()" + }, + "outputs_info": { + "type": "func", + "name": "outputs_info", + "doc": { + "brief": "Get model output layer info", + "return": "output layer info", + "maixpy": "maix.nn.NN.outputs_info", + "py_doc": "Get model output layer info\n\nReturns: output layer info\n" + }, + "args": [], + "ret_type": "std::vector", + "static": false, + "def": "std::vector outputs_info()" + }, + "extra_info": { + "type": "func", + "name": "extra_info", + "doc": { + "brief": "Get model extra info define in MUD file", + "return": "extra info, dict type, key-value object, attention: key and value are all string type.", + "maixpy": "maix.nn.NN.extra_info", + "py_doc": "Get model extra info define in MUD file\n\nReturns: extra info, dict type, key-value object, attention: key and value are all string type.\n" + }, + "args": [], + "ret_type": "std::map", + "static": false, + "def": "std::map extra_info()" + }, + "forward": { + "type": "func", + "name": "forward", + "doc": { + "brief": "forward run model, get output of model,\\nthis is specially for MaixPy, not efficient, but easy to use in MaixPy", + "param": { + "input": "direction [in], input tensor", + "copy_result": "If set true, will copy result to a new variable; else will use a internal memory, you can only use it until to the next forward.\nDefault true to avoid problems, you can set it to false manually to make speed faster.", + "dual_buff_wait": "bool type, only for dual_buff mode, if true, will inference this image and wait for result, default false." + }, + "return": "output tensor. In C++, you should manually delete tensors in return value and return value.\nIf dual_buff mode, it can be NULL(None in MaixPy) means not ready.", + "throw": "if error ocurrs like no memory or arg error, will raise err.Exception.", + "maixpy": "maix.nn.NN.forward", + "py_doc": "forward run model, get output of model,\nthis is specially for MaixPy, not efficient, but easy to use in MaixPy\n\nArgs:\n - input: direction [in], input tensor\n - copy_result: If set true, will copy result to a new variable; else will use a internal memory, you can only use it until to the next forward.\nDefault true to avoid problems, you can set it to false manually to make speed faster.\n - dual_buff_wait: bool type, only for dual_buff mode, if true, will inference this image and wait for result, default false.\n\n\nReturns: output tensor. In C++, you should manually delete tensors in return value and return value.\nIf dual_buff mode, it can be NULL(None in MaixPy) means not ready.\n" + }, + "args": [ + [ + "tensor::Tensors &", + "inputs", + null + ], + [ + "bool", + "copy_result", + "true" + ], + [ + "bool", + "dual_buff_wait", + "false" + ] + ], + "ret_type": "tensor::Tensors*", + "static": false, + "def": "tensor::Tensors *forward(tensor::Tensors &inputs, bool copy_result = true, bool dual_buff_wait = false)" + }, + "forward_image": { + "type": "func", + "name": "forward_image", + "doc": { + "brief": "forward model, param is image", + "param": { + "img": "input image", + "mean": "mean value, a list type, e.g. [0.485, 0.456, 0.406], default is empty list means not normalize.", + "scale": "scale value, a list type, e.g. [1/0.229, 1/0.224, 1/0.225], default is empty list means not normalize.", + "fit": "fit mode, if the image size of input not equal to model's input, it will auto resize use this fit method,\ndefault is image.Fit.FIT_FILL for easy coordinate calculation, but for more accurate result, use image.Fit.FIT_CONTAIN is better.", + "copy_result": "If set true, will copy result to a new variable; else will use a internal memory, you can only use it until to the next forward.\nDefault true to avoid problems, you can set it to false manually to make speed faster.", + "dual_buff_wait": "bool type, only for dual_buff mode, if true, will inference this image and wait for result, default false." + }, + "return": "output tensor. In C++, you should manually delete tensors in return value and return value.\nIf dual_buff mode, it can be NULL(None in MaixPy) means not ready.", + "throw": "If error occurs, like arg error or alloc memory failed, will raise err.Exception.", + "maixpy": "maix.nn.NN.forward_image", + "py_doc": "forward model, param is image\n\nArgs:\n - img: input image\n - mean: mean value, a list type, e.g. [0.485, 0.456, 0.406], default is empty list means not normalize.\n - scale: scale value, a list type, e.g. [1/0.229, 1/0.224, 1/0.225], default is empty list means not normalize.\n - fit: fit mode, if the image size of input not equal to model's input, it will auto resize use this fit method,\ndefault is image.Fit.FIT_FILL for easy coordinate calculation, but for more accurate result, use image.Fit.FIT_CONTAIN is better.\n - copy_result: If set true, will copy result to a new variable; else will use a internal memory, you can only use it until to the next forward.\nDefault true to avoid problems, you can set it to false manually to make speed faster.\n - dual_buff_wait: bool type, only for dual_buff mode, if true, will inference this image and wait for result, default false.\n\n\nReturns: output tensor. In C++, you should manually delete tensors in return value and return value.\nIf dual_buff mode, it can be NULL(None in MaixPy) means not ready.\n" + }, + "args": [ + [ + "image::Image &", + "img", + null + ], + [ + "std::vector", + "mean", + "std::vector()" + ], + [ + "std::vector", + "scale", + "std::vector()" + ], + [ + "image::Fit", + "fit", + "image::Fit::FIT_FILL" + ], + [ + "bool", + "copy_result", + "true" + ], + [ + "bool", + "dual_buff_wait", + "false" + ] + ], + "ret_type": "tensor::Tensors*", + "static": false, + "def": "tensor::Tensors *forward_image(image::Image &img, std::vector mean = std::vector(), std::vector scale = std::vector(), image::Fit fit = image::Fit::FIT_FILL, bool copy_result = true, bool dual_buff_wait = false)" + } + }, + "def": "class NN" + }, + "FaceObject": { + "type": "class", + "name": "FaceObject", + "doc": { + "brief": "Face object", + "maixpy": "maix.nn.FaceObject", + "py_doc": "Face object" + }, + "members": { + "FaceObject": { + "type": "func", + "name": "FaceObject", + "doc": { + "brief": "Constructor", + "maixpy": "maix.nn.FaceObject.__init__", + "maixcdk": "maix.nn.FaceObject.FaceObject", + "py_doc": "Constructor" + }, + "args": [ + [ + "int", + "x", + "0" + ], + [ + "int", + "y", + "0" + ], + [ + "int", + "w", + "0" + ], + [ + "int", + "h", + "0" + ], + [ + "int", + "class_id", + "0" + ], + [ + "float", + "score", + "0" + ], + [ + "std::vector", + "points", + "std::vector()" + ], + [ + "std::vector", + "feature", + "std::vector()" + ], + [ + "image::Image", + "face", + "image::Image()" + ] + ], + "ret_type": null, + "static": false, + "def": "FaceObject(int x = 0, int y = 0, int w = 0, int h = 0, int class_id = 0, float score = 0, std::vector points = std::vector(), std::vector feature = std::vector(), image::Image face = image::Image())" + }, + "to_str": { + "type": "func", + "name": "to_str", + "doc": { + "brief": "FaceObject info to string", + "return": "FaceObject info string", + "maixpy": "maix.nn.FaceObject.__str__", + "maixcdk": "maix.nn.FaceObject.to_str", + "py_doc": "FaceObject info to string\n\nReturns: FaceObject info string\n" + }, + "args": [], + "ret_type": "std::string", + "static": false, + "def": "std::string to_str()" + }, + "x": { + "type": "var", + "name": "x", + "doc": { + "brief": "FaceObject left top coordinate x", + "maixpy": "maix.nn.FaceObject.x", + "py_doc": "FaceObject left top coordinate x" + }, + "value": null, + "static": false, + "readonly": false, + "def": "int x" + }, + "y": { + "type": "var", + "name": "y", + "doc": { + "brief": "FaceObject left top coordinate y", + "maixpy": "maix.nn.FaceObject.y", + "py_doc": "FaceObject left top coordinate y" + }, + "value": null, + "static": false, + "readonly": false, + "def": "int y" + }, + "w": { + "type": "var", + "name": "w", + "doc": { + "brief": "FaceObject width", + "maixpy": "maix.nn.FaceObject.w", + "py_doc": "FaceObject width" + }, + "value": null, + "static": false, + "readonly": false, + "def": "int w" + }, + "h": { + "type": "var", + "name": "h", + "doc": { + "brief": "FaceObject height", + "maixpy": "maix.nn.FaceObject.h", + "py_doc": "FaceObject height" + }, + "value": null, + "static": false, + "readonly": false, + "def": "int h" + }, + "class_id": { + "type": "var", + "name": "class_id", + "doc": { + "brief": "FaceObject class id", + "maixpy": "maix.nn.FaceObject.class_id", + "py_doc": "FaceObject class id" + }, + "value": null, + "static": false, + "readonly": false, + "def": "int class_id" + }, + "score": { + "type": "var", + "name": "score", + "doc": { + "brief": "FaceObject score", + "maixpy": "maix.nn.FaceObject.score", + "py_doc": "FaceObject score" + }, + "value": null, + "static": false, + "readonly": false, + "def": "float score" + }, + "points": { + "type": "var", + "name": "points", + "doc": { + "brief": "keypoints", + "maixpy": "maix.nn.FaceObject.points", + "py_doc": "keypoints" + }, + "value": null, + "static": false, + "readonly": false, + "def": "std::vector points" + }, + "feature": { + "type": "var", + "name": "feature", + "doc": { + "brief": "feature, float list type", + "maixpy": "maix.nn.FaceObject.feature", + "py_doc": "feature, float list type" + }, + "value": null, + "static": false, + "readonly": false, + "def": "std::vector feature" + }, + "face": { + "type": "var", + "name": "face", + "doc": { + "brief": "face image", + "maixpy": "maix.nn.FaceObject.face", + "py_doc": "face image" + }, + "value": null, + "static": false, + "readonly": false, + "def": "image::Image face" + } + }, + "def": "class FaceObject" + }, + "FaceObjects": { + "type": "class", + "name": "FaceObjects", + "doc": { + "brief": "Objects Class for detect result", + "maixpy": "maix.nn.FaceObjects", + "py_doc": "Objects Class for detect result" + }, + "members": { + "FaceObjects": { + "type": "func", + "name": "FaceObjects", + "doc": { + "brief": "Constructor of FaceObjects class", + "maixpy": "maix.nn.FaceObjects.__init__", + "maixcdk": "maix.nn.FaceObjects.FaceObjects", + "py_doc": "Constructor of FaceObjects class" + }, + "args": [], + "ret_type": null, + "static": false, + "def": "FaceObjects()" + }, + "add": { + "type": "func", + "name": "add", + "doc": { + "brief": "Add object to FaceObjects", + "throw": "Throw exception if no memory", + "maixpy": "maix.nn.FaceObjects.add", + "py_doc": "Add object to FaceObjects" + }, + "args": [ + [ + "int", + "x", + "0" + ], + [ + "int", + "y", + "0" + ], + [ + "int", + "w", + "0" + ], + [ + "int", + "h", + "0" + ], + [ + "int", + "class_id", + "0" + ], + [ + "float", + "score", + "0" + ], + [ + "std::vector", + "points", + "std::vector()" + ], + [ + "std::vector", + "feature", + "std::vector()" + ], + [ + "image::Image", + "face", + "image::Image()" + ] + ], + "ret_type": "nn::FaceObject&", + "static": false, + "def": "nn::FaceObject &add(int x = 0, int y = 0, int w = 0, int h = 0, int class_id = 0, float score = 0, std::vector points = std::vector(), std::vector feature = std::vector(), image::Image face = image::Image())" + }, + "remove": { + "type": "func", + "name": "remove", + "doc": { + "brief": "Remove object form FaceObjects", + "maixpy": "maix.nn.FaceObjects.remove", + "py_doc": "Remove object form FaceObjects" + }, + "args": [ + [ + "int", + "idx", + null + ] + ], + "ret_type": "err::Err", + "static": false, + "def": "err::Err remove(int idx)" + }, + "at": { + "type": "func", + "name": "at", + "doc": { + "brief": "Get object item", + "maixpy": "maix.nn.FaceObjects.at", + "py_doc": "Get object item" + }, + "args": [ + [ + "int", + "idx", + null + ] + ], + "ret_type": "nn::FaceObject&", + "static": false, + "def": "nn::FaceObject &at(int idx)" + }, + "[]": { + "type": "func", + "name": "operator[]", + "doc": { + "brief": "Get object item", + "maixpy": "maix.nn.FaceObjects.__getitem__", + "maixcdk": "maix.nn.FaceObjects.[]", + "py_doc": "Get object item" + }, + "args": [ + [ + "int", + "idx", + null + ] + ], + "ret_type": "nn::FaceObject&", + "static": false, + "def": "nn::FaceObject &operator[](int idx)" + }, + "size": { + "type": "func", + "name": "size", + "doc": { + "brief": "Get size", + "maixpy": "maix.nn.FaceObjects.__len__", + "maixcdk": "maix.nn.FaceObjects.size", + "py_doc": "Get size" + }, + "args": [], + "ret_type": "size_t", + "static": false, + "def": "size_t size()" + }, + "begin": { + "type": "func", + "name": "begin", + "doc": { + "brief": "Begin", + "maixpy": "maix.nn.FaceObjects.__iter__", + "maixcdk": "maix.nn.FaceObjects.begin", + "py_doc": "Begin" + }, + "args": [], + "ret_type": "std::vector::iterator", + "static": false, + "def": "std::vector::iterator begin()" + }, + "end": { + "type": "func", + "name": "end", + "doc": { + "brief": "End", + "maixcdk": "maix.nn.FaceObjects.end", + "py_doc": "End" + }, + "args": [], + "ret_type": "std::vector::iterator", + "static": false, + "def": "std::vector::iterator end()" + } + }, + "def": "class FaceObjects" + }, + "FaceRecognizer": { + "type": "class", + "name": "FaceRecognizer", + "doc": { + "brief": "FaceRecognizer class", + "maixpy": "maix.nn.FaceRecognizer", + "py_doc": "FaceRecognizer class" + }, + "members": { + "FaceRecognizer": { + "type": "func", + "name": "FaceRecognizer", + "doc": { + "brief": "Constructor of FaceRecognizer class", + "param": { + "detect_model": "face detect model path, default empty, you can load model later by load function.", + "feature_model": "feature extract model", + "dual_buff": "direction [in], prepare dual input output buffer to accelarate forward, that is, when NPU is forwarding we not wait and prepare the next input buff.\nIf you want to ensure every time forward output the input's result, set this arg to false please.\nDefault true to ensure speed." + }, + "throw": "If model arg is not empty and load failed, will throw err::Exception.", + "maixpy": "maix.nn.FaceRecognizer.__init__", + "maixcdk": "maix.nn.FaceRecognizer.FaceRecognizer", + "py_doc": "Constructor of FaceRecognizer class\n\nArgs:\n - detect_model: face detect model path, default empty, you can load model later by load function.\n - feature_model: feature extract model\n - dual_buff: direction [in], prepare dual input output buffer to accelarate forward, that is, when NPU is forwarding we not wait and prepare the next input buff.\nIf you want to ensure every time forward output the input's result, set this arg to false please.\nDefault true to ensure speed.\n" + }, + "args": [ + [ + "const string &", + "detect_model", + "\"\"" + ], + [ + "const string &", + "feature_model", + "\"\"" + ], + [ + "bool", + "dual_buff", + "true" + ] + ], + "ret_type": null, + "static": false, + "def": "FaceRecognizer(const string &detect_model = \"\", const string &feature_model = \"\", bool dual_buff = true)" + }, + "load": { + "type": "func", + "name": "load", + "doc": { + "brief": "Load model from file", + "param": { + "detect_model": "face detect model path, default empty, you can load model later by load function.", + "feature_model": "feature extract model" + }, + "return": "err::Err", + "maixpy": "maix.nn.FaceRecognizer.load", + "py_doc": "Load model from file\n\nArgs:\n - detect_model: face detect model path, default empty, you can load model later by load function.\n - feature_model: feature extract model\n\n\nReturns: err::Err\n" + }, + "args": [ + [ + "const string &", + "detect_model", + null + ], + [ + "const string &", + "feature_model", + null + ] + ], + "ret_type": "err::Err", + "static": false, + "def": "err::Err load(const string &detect_model, const string &feature_model)" + }, + "recognize": { + "type": "func", + "name": "recognize", + "doc": { + "brief": "Detect objects from image", + "param": { + "img": "Image want to detect, if image's size not match model input's, will auto resize with fit method.", + "conf_th": "Detect confidence threshold, default 0.5.", + "iou_th": "Detect IoU threshold, default 0.45.", + "compare_th": "Compare two face score threshold, default 0.8, if two faces' score < this value, will see this face fas unknown.", + "get_feature": "return feature or not, if true will copy features to result, if false will not copy feature to result to save time and memory.", + "get_face": "return face image or not, if true result object's face attribute will valid, or face sttribute is empty. Get face image will alloc memory and copy image, so will lead to slower speed.", + "fit": "Resize method, default image.Fit.FIT_CONTAIN." + }, + "throw": "If image format not match model input format, will throw err::Exception.", + "return": "FaceObjects object. In C++, you should delete it after use.", + "maixpy": "maix.nn.FaceRecognizer.recognize", + "py_doc": "Detect objects from image\n\nArgs:\n - img: Image want to detect, if image's size not match model input's, will auto resize with fit method.\n - conf_th: Detect confidence threshold, default 0.5.\n - iou_th: Detect IoU threshold, default 0.45.\n - compare_th: Compare two face score threshold, default 0.8, if two faces' score < this value, will see this face fas unknown.\n - get_feature: return feature or not, if true will copy features to result, if false will not copy feature to result to save time and memory.\n - get_face: return face image or not, if true result object's face attribute will valid, or face sttribute is empty. Get face image will alloc memory and copy image, so will lead to slower speed.\n - fit: Resize method, default image.Fit.FIT_CONTAIN.\n\n\nReturns: FaceObjects object. In C++, you should delete it after use.\n" + }, + "args": [ + [ + "image::Image &", + "img", + null + ], + [ + "float", + "conf_th", + "0.5" + ], + [ + "float", + "iou_th", + "0.45" + ], + [ + "float", + "compare_th", + "0.8" + ], + [ + "bool", + "get_feature", + "false" + ], + [ + "bool", + "get_face", + "false" + ], + [ + "maix::image::Fit", + "fit", + "maix::image::FIT_CONTAIN" + ] + ], + "ret_type": "nn::FaceObjects*", + "static": false, + "def": "nn::FaceObjects *recognize(image::Image &img, float conf_th = 0.5, float iou_th = 0.45, float compare_th = 0.8, bool get_feature = false, bool get_face = false, maix::image::Fit fit = maix::image::FIT_CONTAIN)" + }, + "add_face": { + "type": "func", + "name": "add_face", + "doc": { + "brief": "Add face to lib", + "param": { + "face": "face object, find by recognize", + "label": "face label(name)" + }, + "maixpy": "maix.nn.FaceRecognizer.add_face", + "py_doc": "Add face to lib\n\nArgs:\n - face: face object, find by recognize\n - label: face label(name)\n" + }, + "args": [ + [ + "nn::FaceObject *", + "face", + null + ], + [ + "const std::string &", + "label", + null + ] + ], + "ret_type": "err::Err", + "static": false, + "def": "err::Err add_face(nn::FaceObject *face, const std::string &label)" + }, + "remove_face": { + "type": "func", + "name": "remove_face", + "doc": { + "brief": "remove face from lib", + "param": { + "idx": "index of face in lib, default -1 means use label, value [0,face_num), idx and label must have one, idx have high priotiry.", + "label": "which face to remove, default to empty string mean use idx, idx and label must have one, idx have high priotiry." + }, + "maixpy": "maix.nn.FaceRecognizer.remove_face", + "py_doc": "remove face from lib\n\nArgs:\n - idx: index of face in lib, default -1 means use label, value [0,face_num), idx and label must have one, idx have high priotiry.\n - label: which face to remove, default to empty string mean use idx, idx and label must have one, idx have high priotiry.\n" + }, + "args": [ + [ + "int", + "idx", + "-1" + ], + [ + "const std::string &", + "label", + "\"\"" + ] + ], + "ret_type": "err::Err", + "static": false, + "def": "err::Err remove_face(int idx = -1, const std::string &label = \"\")" + }, + "save_faces": { + "type": "func", + "name": "save_faces", + "doc": { + "brief": "Save faces info to a file", + "param": { + "path": "where to save, string type." + }, + "return": "err.Err type", + "maixpy": "maix.nn.FaceRecognizer.save_faces", + "py_doc": "Save faces info to a file\n\nArgs:\n - path: where to save, string type.\n\n\nReturns: err.Err type\n" + }, + "args": [ + [ + "const std::string &", + "path", + null + ] + ], + "ret_type": "err::Err", + "static": false, + "def": "err::Err save_faces(const std::string &path)" + }, + "load_faces": { + "type": "func", + "name": "load_faces", + "doc": { + "brief": "Load faces info from a file", + "param": { + "path": "from where to load, string type." + }, + "return": "err::Err type", + "maixpy": "maix.nn.FaceRecognizer.load_faces", + "py_doc": "Load faces info from a file\n\nArgs:\n - path: from where to load, string type.\n\n\nReturns: err::Err type\n" + }, + "args": [ + [ + "const std::string &", + "path", + null + ] + ], + "ret_type": "err::Err", + "static": false, + "def": "err::Err load_faces(const std::string &path)" + }, + "input_size": { + "type": "func", + "name": "input_size", + "doc": { + "brief": "Get model input size", + "return": "model input size", + "maixpy": "maix.nn.FaceRecognizer.input_size", + "py_doc": "Get model input size\n\nReturns: model input size\n" + }, + "args": [], + "ret_type": "image::Size", + "static": false, + "def": "image::Size input_size()" + }, + "input_width": { + "type": "func", + "name": "input_width", + "doc": { + "brief": "Get model input width", + "return": "model input size of width", + "maixpy": "maix.nn.FaceRecognizer.input_width", + "py_doc": "Get model input width\n\nReturns: model input size of width\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int input_width()" + }, + "input_height": { + "type": "func", + "name": "input_height", + "doc": { + "brief": "Get model input height", + "return": "model input size of height", + "maixpy": "maix.nn.FaceRecognizer.input_height", + "py_doc": "Get model input height\n\nReturns: model input size of height\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int input_height()" + }, + "input_format": { + "type": "func", + "name": "input_format", + "doc": { + "brief": "Get input image format", + "return": "input image format, image::Format type.", + "maixpy": "maix.nn.FaceRecognizer.input_format", + "py_doc": "Get input image format\n\nReturns: input image format, image::Format type.\n" + }, + "args": [], + "ret_type": "image::Format", + "static": false, + "def": "image::Format input_format()" + }, + "mean_detector": { + "type": "var", + "name": "mean_detector", + "doc": { + "brief": "Get mean value, list type", + "maixpy": "maix.nn.FaceRecognizer.mean_detector", + "py_doc": "Get mean value, list type" + }, + "value": null, + "static": false, + "readonly": false, + "def": "std::vector mean_detector" + }, + "scale_detector": { + "type": "var", + "name": "scale_detector", + "doc": { + "brief": "Get scale value, list type", + "maixpy": "maix.nn.FaceRecognizer.scale_detector", + "py_doc": "Get scale value, list type" + }, + "value": null, + "static": false, + "readonly": false, + "def": "std::vector scale_detector" + }, + "mean_feature": { + "type": "var", + "name": "mean_feature", + "doc": { + "brief": "Get mean value, list type", + "maixpy": "maix.nn.FaceRecognizer.mean_feature", + "py_doc": "Get mean value, list type" + }, + "value": null, + "static": false, + "readonly": false, + "def": "std::vector mean_feature" + }, + "scale_feature": { + "type": "var", + "name": "scale_feature", + "doc": { + "brief": "Get scale value, list type", + "maixpy": "maix.nn.FaceRecognizer.scale_feature", + "py_doc": "Get scale value, list type" + }, + "value": null, + "static": false, + "readonly": false, + "def": "std::vector scale_feature" + }, + "labels": { + "type": "var", + "name": "labels", + "doc": { + "brief": "labels, list type, first is \\\"unknown\\\"", + "maixpy": "maix.nn.FaceRecognizer.labels", + "py_doc": "labels, list type, first is \"unknown\"" + }, + "value": null, + "static": false, + "readonly": false, + "def": "std::vector labels" + }, + "features": { + "type": "var", + "name": "features", + "doc": { + "brief": "features", + "maixpy": "maix.nn.FaceRecognizer.features", + "py_doc": "features" + }, + "value": null, + "static": false, + "readonly": false, + "def": "std::vector> features" + } + }, + "def": "class FaceRecognizer" + }, + "SelfLearnClassifier": { + "type": "class", + "name": "SelfLearnClassifier", + "doc": { + "brief": "SelfLearnClassifier", + "maixpy": "maix.nn.SelfLearnClassifier", + "py_doc": "SelfLearnClassifier" + }, + "members": { + "SelfLearnClassifier": { + "type": "func", + "name": "SelfLearnClassifier", + "doc": { + "brief": "Construct a new SelfLearnClassifier object", + "param": { + "model": "MUD model path, if empty, will not load model, you can call load_model() later.\nif not empty, will load model and will raise err::Exception if load failed.", + "dual_buff": "direction [in], prepare dual input output buffer to accelarate forward, that is, when NPU is forwarding we not wait and prepare the next input buff.\nIf you want to ensure every time forward output the input's result, set this arg to false please.\nDefault true to ensure speed." + }, + "maixpy": "maix.nn.SelfLearnClassifier.__init__", + "maixcdk": "maix.nn.SelfLearnClassifier.SelfLearnClassifier", + "py_doc": "Construct a new SelfLearnClassifier object\n\nArgs:\n - model: MUD model path, if empty, will not load model, you can call load_model() later.\nif not empty, will load model and will raise err::Exception if load failed.\n - dual_buff: direction [in], prepare dual input output buffer to accelarate forward, that is, when NPU is forwarding we not wait and prepare the next input buff.\nIf you want to ensure every time forward output the input's result, set this arg to false please.\nDefault true to ensure speed.\n" + }, + "args": [ + [ + "const std::string &", + "model", + "\"\"" + ], + [ + "bool", + "dual_buff", + "true" + ] + ], + "ret_type": null, + "static": false, + "def": "SelfLearnClassifier(const std::string &model = \"\", bool dual_buff = true)" + }, + "load_model": { + "type": "func", + "name": "load_model", + "doc": { + "brief": "Load model from file, model format is .mud,\\nMUD file should contain [extra] section, have key-values:\\n- model_type: classifier_no_top\\n- input_type: rgb or bgr\\n- mean: 123.675, 116.28, 103.53\\n- scale: 0.017124753831663668, 0.01750700280112045, 0.017429193899782137", + "param": { + "model": "MUD model path" + }, + "return": "error code, if load failed, return error code", + "maixpy": "maix.nn.SelfLearnClassifier.load_model", + "py_doc": "Load model from file, model format is .mud,\nMUD file should contain [extra] section, have key-values:\n- model_type: classifier_no_top\n- input_type: rgb or bgr\n- mean: 123.675, 116.28, 103.53\n- scale: 0.017124753831663668, 0.01750700280112045, 0.017429193899782137\n\nArgs:\n - model: MUD model path\n\n\nReturns: error code, if load failed, return error code\n" + }, + "args": [ + [ + "const string &", + "model", + null + ] + ], + "ret_type": "err::Err", + "static": false, + "def": "err::Err load_model(const string &model)" + }, + "classify": { + "type": "func", + "name": "classify", + "doc": { + "brief": "Classify image", + "param": { + "img": "image, format should match model input_type\uff0c or will raise err.Exception", + "fit": "image resize fit mode, default Fit.FIT_COVER, see image.Fit." + }, + "throw": "If error occurred, will raise err::Exception, you can find reason in log, mostly caused by args error or hardware error.", + "return": "result, a list of (idx, distance), smaller distance means more similar. In C++, you need to delete it after use.", + "maixpy": "maix.nn.SelfLearnClassifier.classify", + "py_doc": "Classify image\n\nArgs:\n - img: image, format should match model input_type\uff0c or will raise err.Exception\n - fit: image resize fit mode, default Fit.FIT_COVER, see image.Fit.\n\n\nReturns: result, a list of (idx, distance), smaller distance means more similar. In C++, you need to delete it after use.\n" + }, + "args": [ + [ + "image::Image &", + "img", + null + ], + [ + "image::Fit", + "fit", + "image::FIT_COVER" + ] + ], + "ret_type": "std::vector>*", + "static": false, + "def": "std::vector> *classify(image::Image &img, image::Fit fit = image::FIT_COVER)" + }, + "add_class": { + "type": "func", + "name": "add_class", + "doc": { + "brief": "Add a class to recognize", + "param": { + "img": "Add a image as a new class", + "fit": "image resize fit mode, default Fit.FIT_COVER, see image.Fit." + }, + "maixpy": "maix.nn.SelfLearnClassifier.add_class", + "py_doc": "Add a class to recognize\n\nArgs:\n - img: Add a image as a new class\n - fit: image resize fit mode, default Fit.FIT_COVER, see image.Fit.\n" + }, + "args": [ + [ + "image::Image &", + "img", + null + ], + [ + "image::Fit", + "fit", + "image::FIT_COVER" + ] + ], + "ret_type": "void", + "static": false, + "def": "void add_class(image::Image &img, image::Fit fit = image::FIT_COVER)" + }, + "class_num": { + "type": "func", + "name": "class_num", + "doc": { + "brief": "Get class number", + "maixpy": "maix.nn.SelfLearnClassifier.class_num", + "py_doc": "Get class number" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int class_num()" + }, + "rm_class": { + "type": "func", + "name": "rm_class", + "doc": { + "brief": "Remove a class", + "param": { + "idx": "index, value from 0 to class_num();" + }, + "maixpy": "maix.nn.SelfLearnClassifier.rm_class", + "py_doc": "Remove a class\n\nArgs:\n - idx: index, value from 0 to class_num();\n" + }, + "args": [ + [ + "int", + "idx", + null + ] + ], + "ret_type": "err::Err", + "static": false, + "def": "err::Err rm_class(int idx)" + }, + "add_sample": { + "type": "func", + "name": "add_sample", + "doc": { + "brief": "Add sample, you should call learn method after add some samples to learn classes.\\nSample image can be any of classes we already added.", + "param": { + "img": "Add a image as a new sample." + }, + "maixpy": "maix.nn.SelfLearnClassifier.add_sample", + "py_doc": "Add sample, you should call learn method after add some samples to learn classes.\nSample image can be any of classes we already added.\n\nArgs:\n - img: Add a image as a new sample.\n" + }, + "args": [ + [ + "image::Image &", + "img", + null + ], + [ + "image::Fit", + "fit", + "image::FIT_COVER" + ] + ], + "ret_type": "void", + "static": false, + "def": "void add_sample(image::Image &img, image::Fit fit = image::FIT_COVER)" + }, + "rm_sample": { + "type": "func", + "name": "rm_sample", + "doc": { + "brief": "Remove a sample", + "param": { + "idx": "index, value from 0 to sample_num();" + }, + "maixpy": "maix.nn.SelfLearnClassifier.rm_sample", + "py_doc": "Remove a sample\n\nArgs:\n - idx: index, value from 0 to sample_num();\n" + }, + "args": [ + [ + "int", + "idx", + null + ] + ], + "ret_type": "err::Err", + "static": false, + "def": "err::Err rm_sample(int idx)" + }, + "sample_num": { + "type": "func", + "name": "sample_num", + "doc": { + "brief": "Get sample number", + "maixpy": "maix.nn.SelfLearnClassifier.sample_num", + "py_doc": "Get sample number" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int sample_num()" + }, + "learn": { + "type": "func", + "name": "learn", + "doc": { + "brief": "Start auto learn class features from classes image and samples.\\nYou should call this method after you add some samples.", + "return": "learn epoch(times), 0 means learn nothing.", + "maixpy": "maix.nn.SelfLearnClassifier.learn", + "py_doc": "Start auto learn class features from classes image and samples.\nYou should call this method after you add some samples.\n\nReturns: learn epoch(times), 0 means learn nothing.\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int learn()" + }, + "clear": { + "type": "func", + "name": "clear", + "doc": { + "brief": "Clear all class and samples", + "maixpy": "maix.nn.SelfLearnClassifier.clear", + "py_doc": "Clear all class and samples" + }, + "args": [], + "ret_type": "void", + "static": false, + "def": "void clear()" + }, + "input_size": { + "type": "func", + "name": "input_size", + "doc": { + "brief": "Get model input size, only for image input", + "return": "model input size", + "maixpy": "maix.nn.SelfLearnClassifier.input_size", + "py_doc": "Get model input size, only for image input\n\nReturns: model input size\n" + }, + "args": [], + "ret_type": "image::Size", + "static": false, + "def": "image::Size input_size()" + }, + "input_width": { + "type": "func", + "name": "input_width", + "doc": { + "brief": "Get model input width, only for image input", + "return": "model input size of width", + "maixpy": "maix.nn.SelfLearnClassifier.input_width", + "py_doc": "Get model input width, only for image input\n\nReturns: model input size of width\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int input_width()" + }, + "input_height": { + "type": "func", + "name": "input_height", + "doc": { + "brief": "Get model input height, only for image input", + "return": "model input size of height", + "maixpy": "maix.nn.SelfLearnClassifier.input_height", + "py_doc": "Get model input height, only for image input\n\nReturns: model input size of height\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int input_height()" + }, + "input_format": { + "type": "func", + "name": "input_format", + "doc": { + "brief": "Get input image format, only for image input", + "return": "input image format, image::Format type.", + "maixpy": "maix.nn.SelfLearnClassifier.input_format", + "py_doc": "Get input image format, only for image input\n\nReturns: input image format, image::Format type.\n" + }, + "args": [], + "ret_type": "image::Format", + "static": false, + "def": "image::Format input_format()" + }, + "input_shape": { + "type": "func", + "name": "input_shape", + "doc": { + "brief": "Get input shape, if have multiple input, only return first input shape", + "return": "input shape, list type", + "maixpy": "maix.nn.SelfLearnClassifier.input_shape", + "py_doc": "Get input shape, if have multiple input, only return first input shape\n\nReturns: input shape, list type\n" + }, + "args": [], + "ret_type": "std::vector", + "static": false, + "def": "std::vector input_shape()" + }, + "save": { + "type": "func", + "name": "save", + "doc": { + "brief": "Save features and labels to a binary file", + "param": { + "path": "file path to save, e.g. /root/my_classes.bin", + "labels": "class labels, can be None, or length must equal to class num, or will return err::Err" + }, + "return": "maix.err.Err if labels exists but length not equal to class num, or save file failed, or class num is 0.", + "maixpy": "maix.nn.SelfLearnClassifier.save", + "py_doc": "Save features and labels to a binary file\n\nArgs:\n - path: file path to save, e.g. /root/my_classes.bin\n - labels: class labels, can be None, or length must equal to class num, or will return err::Err\n\n\nReturns: maix.err.Err if labels exists but length not equal to class num, or save file failed, or class num is 0.\n" + }, + "args": [ + [ + "const std::string &", + "path", + null + ], + [ + "const std::vector &", + "labels", + "std::vector()" + ] + ], + "ret_type": "err::Err", + "static": false, + "def": "err::Err save(const std::string &path, const std::vector &labels = std::vector())" + }, + "load": { + "type": "func", + "name": "load", + "doc": { + "brief": "Load features info from binary file", + "param": { + "path": "feature info binary file path, e.g. /root/my_classes.bin" + }, + "maixpy": "maix.nn.SelfLearnClassifier.load", + "py_doc": "Load features info from binary file\n\nArgs:\n - path: feature info binary file path, e.g. /root/my_classes.bin\n" + }, + "args": [ + [ + "const std::string &", + "path", + null + ] + ], + "ret_type": "std::vector", + "static": false, + "def": "std::vector load(const std::string &path)" + }, + "labels": { + "type": "var", + "name": "labels", + "doc": { + "brief": "Labels list", + "maixpy": "maix.nn.SelfLearnClassifier.labels", + "py_doc": "Labels list" + }, + "value": null, + "static": false, + "readonly": false, + "def": "std::vector labels" + }, + "label_path": { + "type": "var", + "name": "label_path", + "doc": { + "brief": "Label file path", + "maixpy": "maix.nn.SelfLearnClassifier.label_path", + "py_doc": "Label file path" + }, + "value": null, + "static": false, + "readonly": false, + "def": "std::string label_path" + }, + "mean": { + "type": "var", + "name": "mean", + "doc": { + "brief": "Get mean value, list type", + "maixpy": "maix.nn.SelfLearnClassifier.mean", + "py_doc": "Get mean value, list type" + }, + "value": null, + "static": false, + "readonly": false, + "def": "std::vector mean" + }, + "scale": { + "type": "var", + "name": "scale", + "doc": { + "brief": "Get scale value, list type", + "maixpy": "maix.nn.SelfLearnClassifier.scale", + "py_doc": "Get scale value, list type" + }, + "value": null, + "static": false, + "readonly": false, + "def": "std::vector scale" + } + }, + "def": "class SelfLearnClassifier" + }, + "YOLOv5": { + "type": "class", + "name": "YOLOv5", + "doc": { + "brief": "YOLOv5 class", + "maixpy": "maix.nn.YOLOv5", + "py_doc": "YOLOv5 class" + }, + "members": { + "YOLOv5": { + "type": "func", + "name": "YOLOv5", + "doc": { + "brief": "Constructor of YOLOv5 class", + "param": { + "model": "model path, default empty, you can load model later by load function.", + "dual_buff": "direction [in], prepare dual input output buffer to accelarate forward, that is, when NPU is forwarding we not wait and prepare the next input buff.\nIf you want to ensure every time forward output the input's result, set this arg to false please.\nDefault true to ensure speed." + }, + "throw": "If model arg is not empty and load failed, will throw err::Exception.", + "maixpy": "maix.nn.YOLOv5.__init__", + "maixcdk": "maix.nn.YOLOv5.YOLOv5", + "py_doc": "Constructor of YOLOv5 class\n\nArgs:\n - model: model path, default empty, you can load model later by load function.\n - dual_buff: direction [in], prepare dual input output buffer to accelarate forward, that is, when NPU is forwarding we not wait and prepare the next input buff.\nIf you want to ensure every time forward output the input's result, set this arg to false please.\nDefault true to ensure speed.\n" + }, + "args": [ + [ + "const string &", + "model", + "\"\"" + ], + [ + "bool", + "dual_buff", + "true" + ] + ], + "ret_type": null, + "static": false, + "def": "YOLOv5(const string &model = \"\", bool dual_buff = true)" + }, + "load": { + "type": "func", + "name": "load", + "doc": { + "brief": "Load model from file", + "param": { + "model": "Model path want to load" + }, + "return": "err::Err", + "maixpy": "maix.nn.YOLOv5.load", + "py_doc": "Load model from file\n\nArgs:\n - model: Model path want to load\n\n\nReturns: err::Err\n" + }, + "args": [ + [ + "const string &", + "model", + null + ] + ], + "ret_type": "err::Err", + "static": false, + "def": "err::Err load(const string &model)" + }, + "detect": { + "type": "func", + "name": "detect", + "doc": { + "brief": "Detect objects from image", + "param": { + "img": "Image want to detect, if image's size not match model input's, will auto resize with fit method.", + "conf_th": "Confidence threshold, default 0.5.", + "iou_th": "IoU threshold, default 0.45.", + "fit": "Resize method, default image.Fit.FIT_CONTAIN." + }, + "throw": "If image format not match model input format, will throw err::Exception.", + "return": "Object list. In C++, you should delete it after use.", + "maixpy": "maix.nn.YOLOv5.detect", + "py_doc": "Detect objects from image\n\nArgs:\n - img: Image want to detect, if image's size not match model input's, will auto resize with fit method.\n - conf_th: Confidence threshold, default 0.5.\n - iou_th: IoU threshold, default 0.45.\n - fit: Resize method, default image.Fit.FIT_CONTAIN.\n\n\nReturns: Object list. In C++, you should delete it after use.\n" + }, + "args": [ + [ + "image::Image &", + "img", + null + ], + [ + "float", + "conf_th", + "0.5" + ], + [ + "float", + "iou_th", + "0.45" + ], + [ + "maix::image::Fit", + "fit", + "maix::image::FIT_CONTAIN" + ] + ], + "ret_type": "std::vector*", + "static": false, + "def": "std::vector *detect(image::Image &img, float conf_th = 0.5, float iou_th = 0.45, maix::image::Fit fit = maix::image::FIT_CONTAIN)" + }, + "input_size": { + "type": "func", + "name": "input_size", + "doc": { + "brief": "Get model input size", + "return": "model input size", + "maixpy": "maix.nn.YOLOv5.input_size", + "py_doc": "Get model input size\n\nReturns: model input size\n" + }, + "args": [], + "ret_type": "image::Size", + "static": false, + "def": "image::Size input_size()" + }, + "input_width": { + "type": "func", + "name": "input_width", + "doc": { + "brief": "Get model input width", + "return": "model input size of width", + "maixpy": "maix.nn.YOLOv5.input_width", + "py_doc": "Get model input width\n\nReturns: model input size of width\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int input_width()" + }, + "input_height": { + "type": "func", + "name": "input_height", + "doc": { + "brief": "Get model input height", + "return": "model input size of height", + "maixpy": "maix.nn.YOLOv5.input_height", + "py_doc": "Get model input height\n\nReturns: model input size of height\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int input_height()" + }, + "input_format": { + "type": "func", + "name": "input_format", + "doc": { + "brief": "Get input image format", + "return": "input image format, image::Format type.", + "maixpy": "maix.nn.YOLOv5.input_format", + "py_doc": "Get input image format\n\nReturns: input image format, image::Format type.\n" + }, + "args": [], + "ret_type": "image::Format", + "static": false, + "def": "image::Format input_format()" + }, + "labels": { + "type": "var", + "name": "labels", + "doc": { + "brief": "Labels list", + "maixpy": "maix.nn.YOLOv5.labels", + "py_doc": "Labels list" + }, + "value": null, + "static": false, + "readonly": false, + "def": "std::vector labels" + }, + "label_path": { + "type": "var", + "name": "label_path", + "doc": { + "brief": "Label file path", + "maixpy": "maix.nn.YOLOv5.label_path", + "py_doc": "Label file path" + }, + "value": null, + "static": false, + "readonly": false, + "def": "std::string label_path" + }, + "mean": { + "type": "var", + "name": "mean", + "doc": { + "brief": "Get mean value, list type", + "maixpy": "maix.nn.YOLOv5.mean", + "py_doc": "Get mean value, list type" + }, + "value": null, + "static": false, + "readonly": false, + "def": "std::vector mean" + }, + "scale": { + "type": "var", + "name": "scale", + "doc": { + "brief": "Get scale value, list type", + "maixpy": "maix.nn.YOLOv5.scale", + "py_doc": "Get scale value, list type" + }, + "value": null, + "static": false, + "readonly": false, + "def": "std::vector scale" + }, + "anchors": { + "type": "var", + "name": "anchors", + "doc": { + "brief": "Get anchors", + "maixpy": "maix.nn.YOLOv5.anchors", + "py_doc": "Get anchors" + }, + "value": null, + "static": false, + "readonly": false, + "def": "std::vector anchors" + } + }, + "def": "class YOLOv5" + }, + "YOLO11": { + "type": "class", + "name": "YOLO11", + "doc": { + "brief": "YOLO11 class", + "maixpy": "maix.nn.YOLO11", + "py_doc": "YOLO11 class" + }, + "members": { + "YOLO11": { + "type": "func", + "name": "YOLO11", + "doc": { + "brief": "Constructor of YOLO11 class", + "param": { + "model": "model path, default empty, you can load model later by load function.", + "dual_buff": "direction [in], prepare dual input output buffer to accelarate forward, that is, when NPU is forwarding we not wait and prepare the next input buff.\nIf you want to ensure every time forward output the input's result, set this arg to false please.\nDefault true to ensure speed." + }, + "throw": "If model arg is not empty and load failed, will throw err::Exception.", + "maixpy": "maix.nn.YOLO11.__init__", + "maixcdk": "maix.nn.YOLO11.YOLO11", + "py_doc": "Constructor of YOLO11 class\n\nArgs:\n - model: model path, default empty, you can load model later by load function.\n - dual_buff: direction [in], prepare dual input output buffer to accelarate forward, that is, when NPU is forwarding we not wait and prepare the next input buff.\nIf you want to ensure every time forward output the input's result, set this arg to false please.\nDefault true to ensure speed.\n" + }, + "args": [ + [ + "const string &", + "model", + "\"\"" + ], + [ + "bool", + "dual_buff", + "true" + ] + ], + "ret_type": null, + "static": false, + "def": "YOLO11(const string &model = \"\", bool dual_buff = true)" + }, + "load": { + "type": "func", + "name": "load", + "doc": { + "brief": "Load model from file", + "param": { + "model": "Model path want to load" + }, + "return": "err::Err", + "maixpy": "maix.nn.YOLO11.load", + "py_doc": "Load model from file\n\nArgs:\n - model: Model path want to load\n\n\nReturns: err::Err\n" + }, + "args": [ + [ + "const string &", + "model", + null + ] + ], + "ret_type": "err::Err", + "static": false, + "def": "err::Err load(const string &model)" + }, + "detect": { + "type": "func", + "name": "detect", + "doc": { + "brief": "Detect objects from image", + "param": { + "img": "Image want to detect, if image's size not match model input's, will auto resize with fit method.", + "conf_th": "Confidence threshold, default 0.5.", + "iou_th": "IoU threshold, default 0.45.", + "fit": "Resize method, default image.Fit.FIT_CONTAIN.", + "keypoint_th": "keypoint threshold, default 0.5, only for yolo11-pose model." + }, + "throw": "If image format not match model input format, will throw err::Exception.", + "return": "Object list. In C++, you should delete it after use.\nIf model is yolo11-pose, object's points have value, and if points' value < 0 means that point is invalid(conf < keypoint_th).", + "maixpy": "maix.nn.YOLO11.detect", + "py_doc": "Detect objects from image\n\nArgs:\n - img: Image want to detect, if image's size not match model input's, will auto resize with fit method.\n - conf_th: Confidence threshold, default 0.5.\n - iou_th: IoU threshold, default 0.45.\n - fit: Resize method, default image.Fit.FIT_CONTAIN.\n - keypoint_th: keypoint threshold, default 0.5, only for yolo11-pose model.\n\n\nReturns: Object list. In C++, you should delete it after use.\nIf model is yolo11-pose, object's points have value, and if points' value < 0 means that point is invalid(conf < keypoint_th).\n" + }, + "args": [ + [ + "image::Image &", + "img", + null + ], + [ + "float", + "conf_th", + "0.5" + ], + [ + "float", + "iou_th", + "0.45" + ], + [ + "maix::image::Fit", + "fit", + "maix::image::FIT_CONTAIN" + ], + [ + "float", + "keypoint_th", + "0.5" + ] + ], + "ret_type": "nn::Objects*", + "static": false, + "def": "nn::Objects *detect(image::Image &img, float conf_th = 0.5, float iou_th = 0.45, maix::image::Fit fit = maix::image::FIT_CONTAIN, float keypoint_th = 0.5)" + }, + "input_size": { + "type": "func", + "name": "input_size", + "doc": { + "brief": "Get model input size", + "return": "model input size", + "maixpy": "maix.nn.YOLO11.input_size", + "py_doc": "Get model input size\n\nReturns: model input size\n" + }, + "args": [], + "ret_type": "image::Size", + "static": false, + "def": "image::Size input_size()" + }, + "input_width": { + "type": "func", + "name": "input_width", + "doc": { + "brief": "Get model input width", + "return": "model input size of width", + "maixpy": "maix.nn.YOLO11.input_width", + "py_doc": "Get model input width\n\nReturns: model input size of width\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int input_width()" + }, + "input_height": { + "type": "func", + "name": "input_height", + "doc": { + "brief": "Get model input height", + "return": "model input size of height", + "maixpy": "maix.nn.YOLO11.input_height", + "py_doc": "Get model input height\n\nReturns: model input size of height\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int input_height()" + }, + "input_format": { + "type": "func", + "name": "input_format", + "doc": { + "brief": "Get input image format", + "return": "input image format, image::Format type.", + "maixpy": "maix.nn.YOLO11.input_format", + "py_doc": "Get input image format\n\nReturns: input image format, image::Format type.\n" + }, + "args": [], + "ret_type": "image::Format", + "static": false, + "def": "image::Format input_format()" + }, + "draw_pose": { + "type": "func", + "name": "draw_pose", + "doc": { + "brief": "Draw pose keypoints on image", + "param": { + "img": "image object, maix.image.Image type.", + "points": "keypoits, int list type, [x, y, x, y ...]", + "radius": "radius of points.", + "color": "color of points.", + "body": "true, if points' length is 17*2 and body is ture, will draw lines as human body, if set to false won't draw lines, default true." + }, + "maixpy": "maix.nn.YOLO11.draw_pose", + "py_doc": "Draw pose keypoints on image\n\nArgs:\n - img: image object, maix.image.Image type.\n - points: keypoits, int list type, [x, y, x, y ...]\n - radius: radius of points.\n - color: color of points.\n - body: true, if points' length is 17*2 and body is ture, will draw lines as human body, if set to false won't draw lines, default true.\n" + }, + "args": [ + [ + "image::Image &", + "img", + null + ], + [ + "std::vector", + "points", + null + ], + [ + "int", + "radius", + "4" + ], + [ + "image::Color", + "color", + "image::COLOR_RED" + ], + [ + "bool", + "body", + "true" + ] + ], + "ret_type": "void", + "static": false, + "def": "void draw_pose(image::Image &img, std::vector points, int radius = 4, image::Color color = image::COLOR_RED, bool body = true)" + }, + "draw_seg_mask": { + "type": "func", + "name": "draw_seg_mask", + "doc": { + "brief": "Draw segmentation on image", + "param": { + "img": "image object, maix.image.Image type.", + "seg_mask": "segmentation mask image by detect method, a grayscale image", + "threshold": "only mask's value > threshold will be draw on image, value from 0 to 255." + }, + "maixpy": "maix.nn.YOLO11.draw_seg_mask", + "py_doc": "Draw segmentation on image\n\nArgs:\n - img: image object, maix.image.Image type.\n - seg_mask: segmentation mask image by detect method, a grayscale image\n - threshold: only mask's value > threshold will be draw on image, value from 0 to 255.\n" + }, + "args": [ + [ + "image::Image &", + "img", + null + ], + [ + "int", + "x", + null + ], + [ + "int", + "y", + null + ], + [ + "image::Image &", + "seg_mask", + null + ], + [ + "int", + "threshold", + "127" + ] + ], + "ret_type": "void", + "static": false, + "def": "void draw_seg_mask(image::Image &img, int x, int y, image::Image &seg_mask, int threshold = 127)" + }, + "labels": { + "type": "var", + "name": "labels", + "doc": { + "brief": "Labels list", + "maixpy": "maix.nn.YOLO11.labels", + "py_doc": "Labels list" + }, + "value": null, + "static": false, + "readonly": false, + "def": "std::vector labels" + }, + "label_path": { + "type": "var", + "name": "label_path", + "doc": { + "brief": "Label file path", + "maixpy": "maix.nn.YOLO11.label_path", + "py_doc": "Label file path" + }, + "value": null, + "static": false, + "readonly": false, + "def": "std::string label_path" + }, + "mean": { + "type": "var", + "name": "mean", + "doc": { + "brief": "Get mean value, list type", + "maixpy": "maix.nn.YOLO11.mean", + "py_doc": "Get mean value, list type" + }, + "value": null, + "static": false, + "readonly": false, + "def": "std::vector mean" + }, + "scale": { + "type": "var", + "name": "scale", + "doc": { + "brief": "Get scale value, list type", + "maixpy": "maix.nn.YOLO11.scale", + "py_doc": "Get scale value, list type" + }, + "value": null, + "static": false, + "readonly": false, + "def": "std::vector scale" + } + }, + "def": "class YOLO11" + }, + "Classifier": { + "type": "class", + "name": "Classifier", + "doc": { + "brief": "Classifier", + "maixpy": "maix.nn.Classifier", + "py_doc": "Classifier" + }, + "members": { + "Classifier": { + "type": "func", + "name": "Classifier", + "doc": { + "brief": "Construct a new Classifier object", + "param": { + "model": "MUD model path, if empty, will not load model, you can call load() later.\nif not empty, will load model and will raise err::Exception if load failed.", + "dual_buff": "direction [in], prepare dual input output buffer to accelarate forward, that is, when NPU is forwarding we not wait and prepare the next input buff.\nIf you want to ensure every time forward output the input's result, set this arg to false please.\nDefault true to ensure speed." + }, + "maixpy": "maix.nn.Classifier.__init__", + "maixcdk": "maix.nn.Classifier.Classifier", + "py_doc": "Construct a new Classifier object\n\nArgs:\n - model: MUD model path, if empty, will not load model, you can call load() later.\nif not empty, will load model and will raise err::Exception if load failed.\n - dual_buff: direction [in], prepare dual input output buffer to accelarate forward, that is, when NPU is forwarding we not wait and prepare the next input buff.\nIf you want to ensure every time forward output the input's result, set this arg to false please.\nDefault true to ensure speed.\n" + }, + "args": [ + [ + "const string &", + "model", + "\"\"" + ], + [ + "bool", + "dual_buff", + "true" + ] + ], + "ret_type": null, + "static": false, + "def": "Classifier(const string &model = \"\", bool dual_buff = true)" + }, + "load": { + "type": "func", + "name": "load", + "doc": { + "brief": "Load model from file, model format is .mud,\\nMUD file should contain [extra] section, have key-values:\\n- model_type: classifier\\n- input_type: rgb or bgr\\n- mean: 123.675, 116.28, 103.53\\n- scale: 0.017124753831663668, 0.01750700280112045, 0.017429193899782137\\n- labels: imagenet_classes.txt", + "param": { + "model": "MUD model path" + }, + "return": "error code, if load failed, return error code", + "maixpy": "maix.nn.Classifier.load", + "py_doc": "Load model from file, model format is .mud,\nMUD file should contain [extra] section, have key-values:\n- model_type: classifier\n- input_type: rgb or bgr\n- mean: 123.675, 116.28, 103.53\n- scale: 0.017124753831663668, 0.01750700280112045, 0.017429193899782137\n- labels: imagenet_classes.txt\n\nArgs:\n - model: MUD model path\n\n\nReturns: error code, if load failed, return error code\n" + }, + "args": [ + [ + "const string &", + "model", + null + ] + ], + "ret_type": "err::Err", + "static": false, + "def": "err::Err load(const string &model)" + }, + "classify": { + "type": "func", + "name": "classify", + "doc": { + "brief": "Forward image to model, get result. Only for image input, use classify_raw for tensor input.", + "param": { + "img": "image, format should match model input_type\uff0c or will raise err.Exception", + "softmax": "if true, will do softmax to result, or will return raw value", + "fit": "image resize fit mode, default Fit.FIT_COVER, see image.Fit." + }, + "throw": "If error occurred, will raise err::Exception, you can find reason in log, mostly caused by args error or hardware error.", + "return": "result, a list of (label, score). If in dual_buff mode, value can be one element list and score is zero when not ready. In C++, you need to delete it after use.", + "maixpy": "maix.nn.Classifier.classify", + "py_doc": "Forward image to model, get result. Only for image input, use classify_raw for tensor input.\n\nArgs:\n - img: image, format should match model input_type\uff0c or will raise err.Exception\n - softmax: if true, will do softmax to result, or will return raw value\n - fit: image resize fit mode, default Fit.FIT_COVER, see image.Fit.\n\n\nReturns: result, a list of (label, score). If in dual_buff mode, value can be one element list and score is zero when not ready. In C++, you need to delete it after use.\n" + }, + "args": [ + [ + "image::Image &", + "img", + null + ], + [ + "bool", + "softmax", + "true" + ], + [ + "image::Fit", + "fit", + "image::FIT_COVER" + ] + ], + "ret_type": "std::vector>*", + "static": false, + "def": "std::vector> *classify(image::Image &img, bool softmax = true, image::Fit fit = image::FIT_COVER)" + }, + "classify_raw": { + "type": "func", + "name": "classify_raw", + "doc": { + "brief": "Forward tensor data to model, get result", + "param": { + "data": "tensor data, format should match model input_type\uff0c or will raise err.Excetion", + "softmax": "if true, will do softmax to result, or will return raw value" + }, + "throw": "If error occurred, will raise err::Exception, you can find reason in log, mostly caused by args error or hardware error.", + "return": "result, a list of (label, score). In C++, you need to delete it after use.", + "maixpy": "maix.nn.Classifier.classify_raw", + "py_doc": "Forward tensor data to model, get result\n\nArgs:\n - data: tensor data, format should match model input_type\uff0c or will raise err.Excetion\n - softmax: if true, will do softmax to result, or will return raw value\n\n\nReturns: result, a list of (label, score). In C++, you need to delete it after use.\n" + }, + "args": [ + [ + "tensor::Tensor &", + "data", + null + ], + [ + "bool", + "softmax", + "true" + ] + ], + "ret_type": "std::vector>*", + "static": false, + "def": "std::vector> *classify_raw(tensor::Tensor &data, bool softmax = true)" + }, + "input_size": { + "type": "func", + "name": "input_size", + "doc": { + "brief": "Get model input size, only for image input", + "return": "model input size", + "maixpy": "maix.nn.Classifier.input_size", + "py_doc": "Get model input size, only for image input\n\nReturns: model input size\n" + }, + "args": [], + "ret_type": "image::Size", + "static": false, + "def": "image::Size input_size()" + }, + "input_width": { + "type": "func", + "name": "input_width", + "doc": { + "brief": "Get model input width, only for image input", + "return": "model input size of width", + "maixpy": "maix.nn.Classifier.input_width", + "py_doc": "Get model input width, only for image input\n\nReturns: model input size of width\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int input_width()" + }, + "input_height": { + "type": "func", + "name": "input_height", + "doc": { + "brief": "Get model input height, only for image input", + "return": "model input size of height", + "maixpy": "maix.nn.Classifier.input_height", + "py_doc": "Get model input height, only for image input\n\nReturns: model input size of height\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int input_height()" + }, + "input_format": { + "type": "func", + "name": "input_format", + "doc": { + "brief": "Get input image format, only for image input", + "return": "input image format, image::Format type.", + "maixpy": "maix.nn.Classifier.input_format", + "py_doc": "Get input image format, only for image input\n\nReturns: input image format, image::Format type.\n" + }, + "args": [], + "ret_type": "image::Format", + "static": false, + "def": "image::Format input_format()" + }, + "input_shape": { + "type": "func", + "name": "input_shape", + "doc": { + "brief": "Get input shape, if have multiple input, only return first input shape", + "return": "input shape, list type", + "maixpy": "maix.nn.Classifier.input_shape", + "py_doc": "Get input shape, if have multiple input, only return first input shape\n\nReturns: input shape, list type\n" + }, + "args": [], + "ret_type": "std::vector", + "static": false, + "def": "std::vector input_shape()" + }, + "labels": { + "type": "var", + "name": "labels", + "doc": { + "brief": "Labels list", + "maixpy": "maix.nn.Classifier.labels", + "py_doc": "Labels list" + }, + "value": null, + "static": false, + "readonly": false, + "def": "std::vector labels" + }, + "label_path": { + "type": "var", + "name": "label_path", + "doc": { + "brief": "Label file path", + "maixpy": "maix.nn.Classifier.label_path", + "py_doc": "Label file path" + }, + "value": null, + "static": false, + "readonly": false, + "def": "std::string label_path" + }, + "mean": { + "type": "var", + "name": "mean", + "doc": { + "brief": "Get mean value, list type", + "maixpy": "maix.nn.Classifier.mean", + "py_doc": "Get mean value, list type" + }, + "value": null, + "static": false, + "readonly": false, + "def": "std::vector mean" + }, + "scale": { + "type": "var", + "name": "scale", + "doc": { + "brief": "Get scale value, list type", + "maixpy": "maix.nn.Classifier.scale", + "py_doc": "Get scale value, list type" + }, + "value": null, + "static": false, + "readonly": false, + "def": "std::vector scale" + } + }, + "def": "class Classifier" + }, + "Retinaface": { + "type": "class", + "name": "Retinaface", + "doc": { + "brief": "Retinaface class", + "maixpy": "maix.nn.Retinaface", + "py_doc": "Retinaface class" + }, + "members": { + "Retinaface": { + "type": "func", + "name": "Retinaface", + "doc": { + "brief": "Constructor of Retinaface class", + "param": { + "model": "model path, default empty, you can load model later by load function.", + "dual_buff": "direction [in], prepare dual input output buffer to accelarate forward, that is, when NPU is forwarding we not wait and prepare the next input buff.\nIf you want to ensure every time forward output the input's result, set this arg to false please.\nDefault true to ensure speed." + }, + "throw": "If model arg is not empty and load failed, will throw err::Exception.", + "maixpy": "maix.nn.Retinaface.__init__", + "maixcdk": "maix.nn.Retinaface.Retinaface", + "py_doc": "Constructor of Retinaface class\n\nArgs:\n - model: model path, default empty, you can load model later by load function.\n - dual_buff: direction [in], prepare dual input output buffer to accelarate forward, that is, when NPU is forwarding we not wait and prepare the next input buff.\nIf you want to ensure every time forward output the input's result, set this arg to false please.\nDefault true to ensure speed.\n" + }, + "args": [ + [ + "const string &", + "model", + "\"\"" + ], + [ + "bool", + "dual_buff", + "true" + ] + ], + "ret_type": null, + "static": false, + "def": "Retinaface(const string &model = \"\", bool dual_buff = true)" + }, + "load": { + "type": "func", + "name": "load", + "doc": { + "brief": "Load model from file", + "param": { + "model": "Model path want to load" + }, + "return": "err::Err", + "maixpy": "maix.nn.Retinaface.load", + "py_doc": "Load model from file\n\nArgs:\n - model: Model path want to load\n\n\nReturns: err::Err\n" + }, + "args": [ + [ + "const string &", + "model", + null + ] + ], + "ret_type": "err::Err", + "static": false, + "def": "err::Err load(const string &model)" + }, + "detect": { + "type": "func", + "name": "detect", + "doc": { + "brief": "Detect objects from image", + "param": { + "img": "Image want to detect, if image's size not match model input's, will auto resize with fit method.", + "conf_th": "Confidence threshold, default 0.4.", + "iou_th": "IoU threshold, default 0.45.", + "fit": "Resize method, default image.Fit.FIT_CONTAIN." + }, + "throw": "If image format not match model input format, will throw err::Exception.", + "return": "Object list. In C++, you should delete it after use.", + "maixpy": "maix.nn.Retinaface.detect", + "py_doc": "Detect objects from image\n\nArgs:\n - img: Image want to detect, if image's size not match model input's, will auto resize with fit method.\n - conf_th: Confidence threshold, default 0.4.\n - iou_th: IoU threshold, default 0.45.\n - fit: Resize method, default image.Fit.FIT_CONTAIN.\n\n\nReturns: Object list. In C++, you should delete it after use.\n" + }, + "args": [ + [ + "image::Image &", + "img", + null + ], + [ + "float", + "conf_th", + "0.4" + ], + [ + "float", + "iou_th", + "0.45" + ], + [ + "maix::image::Fit", + "fit", + "maix::image::FIT_CONTAIN" + ] + ], + "ret_type": "std::vector*", + "static": false, + "def": "std::vector *detect(image::Image &img, float conf_th = 0.4, float iou_th = 0.45, maix::image::Fit fit = maix::image::FIT_CONTAIN)" + }, + "input_size": { + "type": "func", + "name": "input_size", + "doc": { + "brief": "Get model input size", + "return": "model input size", + "maixpy": "maix.nn.Retinaface.input_size", + "py_doc": "Get model input size\n\nReturns: model input size\n" + }, + "args": [], + "ret_type": "image::Size", + "static": false, + "def": "image::Size input_size()" + }, + "input_width": { + "type": "func", + "name": "input_width", + "doc": { + "brief": "Get model input width", + "return": "model input size of width", + "maixpy": "maix.nn.Retinaface.input_width", + "py_doc": "Get model input width\n\nReturns: model input size of width\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int input_width()" + }, + "input_height": { + "type": "func", + "name": "input_height", + "doc": { + "brief": "Get model input height", + "return": "model input size of height", + "maixpy": "maix.nn.Retinaface.input_height", + "py_doc": "Get model input height\n\nReturns: model input size of height\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int input_height()" + }, + "input_format": { + "type": "func", + "name": "input_format", + "doc": { + "brief": "Get input image format", + "return": "input image format, image::Format type.", + "maixpy": "maix.nn.Retinaface.input_format", + "py_doc": "Get input image format\n\nReturns: input image format, image::Format type.\n" + }, + "args": [], + "ret_type": "image::Format", + "static": false, + "def": "image::Format input_format()" + }, + "mean": { + "type": "var", + "name": "mean", + "doc": { + "brief": "Get mean value, list type", + "maixpy": "maix.nn.Retinaface.mean", + "py_doc": "Get mean value, list type" + }, + "value": null, + "static": false, + "readonly": false, + "def": "std::vector mean" + }, + "scale": { + "type": "var", + "name": "scale", + "doc": { + "brief": "Get scale value, list type", + "maixpy": "maix.nn.Retinaface.scale", + "py_doc": "Get scale value, list type" + }, + "value": null, + "static": false, + "readonly": false, + "def": "std::vector scale" + } + }, + "def": "class Retinaface" + }, + "F": { + "type": "module", + "doc": { + "brief": "maix.nn.F module" + }, + "members": { + "softmax": { + "type": "func", + "name": "softmax", + "doc": { + "brief": "Softmax, only support 1D tensor, multi-dimension tensor will be treated as 1D tensor", + "param": { + "tensor": "input tensor", + "replace": "change input tensor data directly, if not, will create a new tensor" + }, + "throw": "If arg error, will raise err.Exception error", + "return": "output tensor, if arg replace is true, return the arg tensor's address.\nIf not replace, return a new object, so In C++, you should delete it manually in this case!", + "maixpy": "maix.nn.F.softmax", + "py_doc": "Softmax, only support 1D tensor, multi-dimension tensor will be treated as 1D tensor\n\nArgs:\n - tensor: input tensor\n - replace: change input tensor data directly, if not, will create a new tensor\n\n\nReturns: output tensor, if arg replace is true, return the arg tensor's address.\nIf not replace, return a new object, so In C++, you should delete it manually in this case!\n" + }, + "args": [ + [ + "tensor::Tensor *", + "tensor", + null + ], + [ + "bool", + "replace", + null + ] + ], + "ret_type": "tensor::Tensor*", + "static": false, + "def": "tensor::Tensor *softmax(tensor::Tensor *tensor, bool replace)" + } + }, + "auto_add": true + }, + "FaceDetector": { + "type": "class", + "name": "FaceDetector", + "doc": { + "brief": "FaceDetector class", + "maixpy": "maix.nn.FaceDetector", + "py_doc": "FaceDetector class" + }, + "members": { + "FaceDetector": { + "type": "func", + "name": "FaceDetector", + "doc": { + "brief": "Constructor of FaceDetector class", + "param": { + "model": "model path, default empty, you can load model later by load function.", + "dual_buff": "direction [in], prepare dual input output buffer to accelarate forward, that is, when NPU is forwarding we not wait and prepare the next input buff.\nIf you want to ensure every time forward output the input's result, set this arg to false please.\nDefault true to ensure speed." + }, + "throw": "If model arg is not empty and load failed, will throw err::Exception.", + "maixpy": "maix.nn.FaceDetector.__init__", + "maixcdk": "maix.nn.FaceDetector.FaceDetector", + "py_doc": "Constructor of FaceDetector class\n\nArgs:\n - model: model path, default empty, you can load model later by load function.\n - dual_buff: direction [in], prepare dual input output buffer to accelarate forward, that is, when NPU is forwarding we not wait and prepare the next input buff.\nIf you want to ensure every time forward output the input's result, set this arg to false please.\nDefault true to ensure speed.\n" + }, + "args": [ + [ + "const string &", + "model", + "\"\"" + ], + [ + "bool", + "dual_buff", + "true" + ] + ], + "ret_type": null, + "static": false, + "def": "FaceDetector(const string &model = \"\", bool dual_buff = true)" + }, + "load": { + "type": "func", + "name": "load", + "doc": { + "brief": "Load model from file", + "param": { + "model": "Model path want to load" + }, + "return": "err::Err", + "maixpy": "maix.nn.FaceDetector.load", + "py_doc": "Load model from file\n\nArgs:\n - model: Model path want to load\n\n\nReturns: err::Err\n" + }, + "args": [ + [ + "const string &", + "model", + null + ] + ], + "ret_type": "err::Err", + "static": false, + "def": "err::Err load(const string &model)" + }, + "detect": { + "type": "func", + "name": "detect", + "doc": { + "brief": "Detect objects from image", + "param": { + "img": "Image want to detect, if image's size not match model input's, will auto resize with fit method.", + "conf_th": "Confidence threshold, default 0.5.", + "iou_th": "IoU threshold, default 0.45.", + "fit": "Resize method, default image.Fit.FIT_CONTAIN." + }, + "throw": "If image format not match model input format, will throw err::Exception.", + "return": "Object list. In C++, you should delete it after use.", + "maixpy": "maix.nn.FaceDetector.detect", + "py_doc": "Detect objects from image\n\nArgs:\n - img: Image want to detect, if image's size not match model input's, will auto resize with fit method.\n - conf_th: Confidence threshold, default 0.5.\n - iou_th: IoU threshold, default 0.45.\n - fit: Resize method, default image.Fit.FIT_CONTAIN.\n\n\nReturns: Object list. In C++, you should delete it after use.\n" + }, + "args": [ + [ + "image::Image &", + "img", + null + ], + [ + "float", + "conf_th", + "0.5" + ], + [ + "float", + "iou_th", + "0.45" + ], + [ + "maix::image::Fit", + "fit", + "maix::image::FIT_CONTAIN" + ] + ], + "ret_type": "std::vector*", + "static": false, + "def": "std::vector *detect(image::Image &img, float conf_th = 0.5, float iou_th = 0.45, maix::image::Fit fit = maix::image::FIT_CONTAIN)" + }, + "input_size": { + "type": "func", + "name": "input_size", + "doc": { + "brief": "Get model input size", + "return": "model input size", + "maixpy": "maix.nn.FaceDetector.input_size", + "py_doc": "Get model input size\n\nReturns: model input size\n" + }, + "args": [], + "ret_type": "image::Size", + "static": false, + "def": "image::Size input_size()" + }, + "input_width": { + "type": "func", + "name": "input_width", + "doc": { + "brief": "Get model input width", + "return": "model input size of width", + "maixpy": "maix.nn.FaceDetector.input_width", + "py_doc": "Get model input width\n\nReturns: model input size of width\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int input_width()" + }, + "input_height": { + "type": "func", + "name": "input_height", + "doc": { + "brief": "Get model input height", + "return": "model input size of height", + "maixpy": "maix.nn.FaceDetector.input_height", + "py_doc": "Get model input height\n\nReturns: model input size of height\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int input_height()" + }, + "input_format": { + "type": "func", + "name": "input_format", + "doc": { + "brief": "Get input image format", + "return": "input image format, image::Format type.", + "maixpy": "maix.nn.FaceDetector.input_format", + "py_doc": "Get input image format\n\nReturns: input image format, image::Format type.\n" + }, + "args": [], + "ret_type": "image::Format", + "static": false, + "def": "image::Format input_format()" + }, + "mean": { + "type": "var", + "name": "mean", + "doc": { + "brief": "Get mean value, list type", + "maixpy": "maix.nn.FaceDetector.mean", + "py_doc": "Get mean value, list type" + }, + "value": null, + "static": false, + "readonly": false, + "def": "std::vector mean" + }, + "scale": { + "type": "var", + "name": "scale", + "doc": { + "brief": "Get scale value, list type", + "maixpy": "maix.nn.FaceDetector.scale", + "py_doc": "Get scale value, list type" + }, + "value": null, + "static": false, + "readonly": false, + "def": "std::vector scale" + } + }, + "def": "class FaceDetector" + }, + "PP_OCR": { + "type": "class", + "name": "PP_OCR", + "doc": { + "brief": "PP_OCR class", + "maixpy": "maix.nn.PP_OCR", + "py_doc": "PP_OCR class" + }, + "members": { + "PP_OCR": { + "type": "func", + "name": "PP_OCR", + "doc": { + "brief": "Constructor of PP_OCR class", + "param": { + "model": "model path, default empty, you can load model later by load function." + }, + "throw": "If model arg is not empty and load failed, will throw err::Exception.", + "maixpy": "maix.nn.PP_OCR.__init__", + "maixcdk": "maix.nn.PP_OCR.PP_OCR", + "py_doc": "Constructor of PP_OCR class\n\nArgs:\n - model: model path, default empty, you can load model later by load function.\n" + }, + "args": [ + [ + "const string &", + "model", + "\"\"" + ] + ], + "ret_type": null, + "static": false, + "def": "PP_OCR(const string &model = \"\")" + }, + "load": { + "type": "func", + "name": "load", + "doc": { + "brief": "Load model from file", + "param": { + "model": "Model path want to load" + }, + "return": "err::Err", + "maixpy": "maix.nn.PP_OCR.load", + "py_doc": "Load model from file\n\nArgs:\n - model: Model path want to load\n\n\nReturns: err::Err\n" + }, + "args": [ + [ + "const string &", + "model", + null + ] + ], + "ret_type": "err::Err", + "static": false, + "def": "err::Err load(const string &model)" + }, + "detect": { + "type": "func", + "name": "detect", + "doc": { + "brief": "Detect objects from image", + "param": { + "img": "Image want to detect, if image's size not match model input's, will auto resize with fit method.", + "thresh": "Confidence threshold where pixels have charactor, default 0.3.", + "box_thresh": "Box threshold, the box prob higher than this value will be valid, default 0.6.", + "fit": "Resize method, default image.Fit.FIT_CONTAIN.", + "char_box": "Calculate every charactor's box, default false, if true then you can get charactor's box by nn.OCR_Object's char_boxes attribute." + }, + "throw": "If image format not match model input format or no memory, will throw err::Exception.", + "return": "nn.OCR_Objects type. In C++, you should delete it after use.", + "maixpy": "maix.nn.PP_OCR.detect", + "py_doc": "Detect objects from image\n\nArgs:\n - img: Image want to detect, if image's size not match model input's, will auto resize with fit method.\n - thresh: Confidence threshold where pixels have charactor, default 0.3.\n - box_thresh: Box threshold, the box prob higher than this value will be valid, default 0.6.\n - fit: Resize method, default image.Fit.FIT_CONTAIN.\n - char_box: Calculate every charactor's box, default false, if true then you can get charactor's box by nn.OCR_Object's char_boxes attribute.\n\n\nReturns: nn.OCR_Objects type. In C++, you should delete it after use.\n" + }, + "args": [ + [ + "image::Image &", + "img", + null + ], + [ + "float", + "thresh", + "0.3" + ], + [ + "float", + "box_thresh", + "0.6" + ], + [ + "maix::image::Fit", + "fit", + "maix::image::FIT_CONTAIN" + ], + [ + "bool", + "char_box", + "false" + ] + ], + "ret_type": "nn::OCR_Objects*", + "static": false, + "def": "nn::OCR_Objects *detect(image::Image &img, float thresh = 0.3, float box_thresh = 0.6, maix::image::Fit fit = maix::image::FIT_CONTAIN, bool char_box = false)" + }, + "recognize": { + "type": "func", + "name": "recognize", + "doc": { + "brief": "Only recognize, not detect", + "param": { + "img": "image to recognize chractors, can be a stanrd cropped charactors image,\nif crop image not standard, you can use box_points to assgin where the charactors' 4 corner is.", + "box_points": "list type, length must be 8 or 0, default empty means not transfer image to standard image.\n4 points postiion, format: [x1, y1, x2, y2, x3, y3, x4, y4], point 1 at the left-top, point 2 right-top...", + "char_box": "Calculate every charactor's box, default false, if true then you can get charactor's box by nn.OCR_Object's char_boxes attribute." + }, + "maixpy": "maix.nn.PP_OCR.recognize", + "py_doc": "Only recognize, not detect\n\nArgs:\n - img: image to recognize chractors, can be a stanrd cropped charactors image,\nif crop image not standard, you can use box_points to assgin where the charactors' 4 corner is.\n - box_points: list type, length must be 8 or 0, default empty means not transfer image to standard image.\n4 points postiion, format: [x1, y1, x2, y2, x3, y3, x4, y4], point 1 at the left-top, point 2 right-top...\n - char_box: Calculate every charactor's box, default false, if true then you can get charactor's box by nn.OCR_Object's char_boxes attribute.\n" + }, + "args": [ + [ + "image::Image &", + "img", + null + ], + [ + "const std::vector &", + "box_points", + "std::vector()" + ] + ], + "ret_type": "nn::OCR_Object*", + "static": false, + "def": "nn::OCR_Object *recognize(image::Image &img, const std::vector &box_points = std::vector())" + }, + "draw_seg_mask": { + "type": "func", + "name": "draw_seg_mask", + "doc": { + "brief": "Draw segmentation on image", + "param": { + "img": "image object, maix.image.Image type.", + "seg_mask": "segmentation mask image by detect method, a grayscale image", + "threshold": "only mask's value > threshold will be draw on image, value from 0 to 255." + }, + "maixpy": "maix.nn.PP_OCR.draw_seg_mask", + "py_doc": "Draw segmentation on image\n\nArgs:\n - img: image object, maix.image.Image type.\n - seg_mask: segmentation mask image by detect method, a grayscale image\n - threshold: only mask's value > threshold will be draw on image, value from 0 to 255.\n" + }, + "args": [ + [ + "image::Image &", + "img", + null + ], + [ + "int", + "x", + null + ], + [ + "int", + "y", + null + ], + [ + "image::Image &", + "seg_mask", + null + ], + [ + "int", + "threshold", + "127" + ] + ], + "ret_type": "void", + "static": false, + "def": "void draw_seg_mask(image::Image &img, int x, int y, image::Image &seg_mask, int threshold = 127)" + }, + "input_size": { + "type": "func", + "name": "input_size", + "doc": { + "brief": "Get model input size", + "return": "model input size", + "maixpy": "maix.nn.PP_OCR.input_size", + "py_doc": "Get model input size\n\nReturns: model input size\n" + }, + "args": [], + "ret_type": "image::Size", + "static": false, + "def": "image::Size input_size()" + }, + "input_width": { + "type": "func", + "name": "input_width", + "doc": { + "brief": "Get model input width", + "return": "model input size of width", + "maixpy": "maix.nn.PP_OCR.input_width", + "py_doc": "Get model input width\n\nReturns: model input size of width\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int input_width()" + }, + "input_height": { + "type": "func", + "name": "input_height", + "doc": { + "brief": "Get model input height", + "return": "model input size of height", + "maixpy": "maix.nn.PP_OCR.input_height", + "py_doc": "Get model input height\n\nReturns: model input size of height\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int input_height()" + }, + "input_format": { + "type": "func", + "name": "input_format", + "doc": { + "brief": "Get input image format", + "return": "input image format, image::Format type.", + "maixpy": "maix.nn.PP_OCR.input_format", + "py_doc": "Get input image format\n\nReturns: input image format, image::Format type.\n" + }, + "args": [], + "ret_type": "image::Format", + "static": false, + "def": "image::Format input_format()" + }, + "mean": { + "type": "var", + "name": "mean", + "doc": { + "brief": "Get mean value, list type", + "maixpy": "maix.nn.PP_OCR.mean", + "py_doc": "Get mean value, list type" + }, + "value": null, + "static": false, + "readonly": false, + "def": "std::vector mean" + }, + "scale": { + "type": "var", + "name": "scale", + "doc": { + "brief": "Get scale value, list type", + "maixpy": "maix.nn.PP_OCR.scale", + "py_doc": "Get scale value, list type" + }, + "value": null, + "static": false, + "readonly": false, + "def": "std::vector scale" + }, + "rec_mean": { + "type": "var", + "name": "rec_mean", + "doc": { + "brief": "Get mean value, list type", + "maixpy": "maix.nn.PP_OCR.rec_mean", + "py_doc": "Get mean value, list type" + }, + "value": null, + "static": false, + "readonly": false, + "def": "std::vector rec_mean" + }, + "rec_scale": { + "type": "var", + "name": "rec_scale", + "doc": { + "brief": "Get scale value, list type", + "maixpy": "maix.nn.PP_OCR.rec_scale", + "py_doc": "Get scale value, list type" + }, + "value": null, + "static": false, + "readonly": false, + "def": "std::vector rec_scale" + }, + "labels": { + "type": "var", + "name": "labels", + "doc": { + "brief": "labels (charactors)", + "maixpy": "maix.nn.PP_OCR.labels", + "py_doc": "labels (charactors)" + }, + "value": null, + "static": false, + "readonly": false, + "def": "std::vector labels" + }, + "det": { + "type": "var", + "name": "det", + "doc": { + "brief": "model have detect model", + "maixpy": "maix.nn.PP_OCR.det", + "py_doc": "model have detect model" + }, + "value": null, + "static": false, + "readonly": false, + "def": "bool det" + }, + "rec": { + "type": "var", + "name": "rec", + "doc": { + "brief": "model have recognize model", + "maixpy": "maix.nn.PP_OCR.rec", + "py_doc": "model have recognize model" + }, + "value": null, + "static": false, + "readonly": false, + "def": "bool rec" + } + }, + "def": "class PP_OCR" + } + }, + "auto_add": true + } + } + } + } +} \ No newline at end of file diff --git a/maixcdk/api/config.json b/maixcdk/api/config.json new file mode 100644 index 00000000..cc9f7f37 --- /dev/null +++ b/maixcdk/api/config.json @@ -0,0 +1,4 @@ +{ + "import": "config", + "name": "MaixCDK API Doc" +} diff --git a/maixcdk/api/index.html b/maixcdk/api/index.html new file mode 100644 index 00000000..df3d5adb --- /dev/null +++ b/maixcdk/api/index.html @@ -0,0 +1,458 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MaixCDK API -- Maix AI machine vision platform C/C++ API - MaixCDK + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

MaixCDK API -- Maix AI machine vision platform C/C++ API

+ +
+
+
    + +
+
+
+
+ + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +
+

For MaixCDK developer: This API documentation is generated from the source code, DO NOT edit this file manually!

+
+

MaixCDK API documentation, modules:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
modulebrief
maix::imagemaix.image module, image related definition and functions
maix::audiomaix.audio module
maix::trackermaix.tracker module
maix::httpmaix.http module
maix::cameramaix.camera module, access camera device and get image from it
maix::rtspmaix.rtsp module
maix::rtmpmaix.rtmp module
maix::touchscreenmaix.touchscreen module
maix::videomaix.video module
maix::displaymaix.display module, control display device and show image on it
maix::uvcmaix.uvc module
maix::networkmaix.network module
maix::commmaix.comm module
maix::modbusmaix.modbus module
maix::fsmaix.fs module
maix::BytesBytes type for Python bytes compatibility.
maix::appmaix.app module
maix::protocolmaix.protocol module
maix::timemaix.time module
maix::errmaix.err module
maix::exampleexample module, this will be maix.example module in MaixPy, maix::example namespace in MaixCDK
maix::utilmaix.util module
maix::threadmaix.thread module
maix::sysmaix.sys module
maix::logmaix.log module
maix::tensormaix.tensor module
maix::i18nmaix.i18n module
maix::peripheralChip's peripheral driver
maix::ext_devmaix.ext_dev module
maix::nnmaix.nn module
+ + +
+
+
+ + +
+
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixcdk/api/maix/app.html b/maixcdk/api/maix/app.html new file mode 100644 index 00000000..83666ab1 --- /dev/null +++ b/maixcdk/api/maix/app.html @@ -0,0 +1,1259 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + maix::app - MaixCDK + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

maix::app

+ +
+
+
    + +
+
+
+
+ + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

maix.app module

+
+

This is maix::app module of MaixCDK.
+All of these elements are in namespace maix::app.

+

For MaixCDK developer: DO NOT edit this doc file manually, this doc is auto generated!

+
+

Module

+

No module

+

Enum

+

Variable

+

Function

+

app_id

+

Get current APP ID.

+ + + + + + + + + + + + + +
itemdescription
returnAPP ID.
+
+

C++ defination code:

+ +
string app_id()
+
+
+

set_app_id

+

Set current APP ID.

+ + + + + + + + + + + + + +
itemdescription
paramapp_id: APP ID.
+
+

C++ defination code:

+ +
string set_app_id(const string &app_id)
+
+
+

get_apps_info_path

+

Get APP info file path.

+
+

C++ defination code:

+ +
string get_apps_info_path()
+
+
+

get_apps_info

+

Get APP info list.

+ + + + + + + + + + + + + + + + + +
itemdescription
paramignore_launcher: if true, ignore launcher APP. default false.
ignore_app_store: if true, ignore app store APP. default false.
returnAPP info list. APP_Info object list.
+
+

C++ defination code:

+ +
vector<app::APP_Info> &get_apps_info(bool ignore_launcher = false, bool ignore_app_store = false)
+
+
+

get_app_info

+

Get app info by app id.

+ + + + + + + + + + + + + +
itemdescription
returnapp.APP_Info type.
+
+

C++ defination code:

+ +
app::APP_Info get_app_info(const std::string &app_id)
+
+
+

get_app_data_path

+

Get APP info, APP can store private data in this directory.

+ + + + + + + + + + + + + +
itemdescription
returnAPP data path "./data", just return the data folder in current path because APP executed in app install path or project path.
So, you must execute your program in you project path to use the project/data folder when you debug your APP.
+
+

C++ defination code:

+ +
string get_app_data_path()
+
+
+

get_app_path

+

Get APP path.

+ + + + + + + + + + + + + + + + + +
itemdescription
paramapp_id: APP ID, if empty, return current APP path, else return the APP path by app_id.
returnAPP path, just return the current path because APP executed in app install path or project path.
So, you must execute your program in you project path to use the project/data folder when you debug your APP.
+
+

C++ defination code:

+ +
string get_app_path(const string &app_id = "")
+
+
+

get_tmp_path

+

Get global temporary data path, APPs can use this path as temporary data directory.

+ + + + + + + + + + + + + +
itemdescription
returntemporary data path.
+
+

C++ defination code:

+ +
string get_tmp_path()
+
+
+

get_share_path

+

Get data path of share, shared data like picture and video will put in this directory

+ + + + + + + + + + + + + +
itemdescription
returnshare data path.
+
+

C++ defination code:

+ +
string get_share_path()
+
+
+

get_picture_path

+

Get picture path of share, shared picture will put in this directory

+ + + + + + + + + + + + + +
itemdescription
returnshare picture path.
+
+

C++ defination code:

+ +
string get_picture_path()
+
+
+

get_video_path

+

Get video path of share, shared video will put in this directory

+ + + + + + + + + + + + + +
itemdescription
returnshare video path.
+
+

C++ defination code:

+ +
string get_video_path()
+
+
+

get_font_path

+

Get font path of share, shared font will put in this directory

+ + + + + + + + + + + + + +
itemdescription
returnshare font path.
+
+

C++ defination code:

+ +
string get_font_path()
+
+
+

get_icon_path

+

Get icon path of share, shared icon will put in this directory

+ + + + + + + + + + + + + +
itemdescription
returnshare icon path.
+
+

C++ defination code:

+ +
string get_icon_path()
+
+
+

get_sys_config_kv

+

Get system config item value.

+ + + + + + + + + + + + + + + + + +
itemdescription
paramitem: name of setting item, e.g. wifi, language. more see settings APP.
key: config key, e.g. for wifi, key can be ssid, for language, key can be locale.
value: default value, if not found, return this value.
from_cache: if true, read from cache, if false, read from file.
returnconfig value, always string type, if not found, return empty string.
+
+

C++ defination code:

+ +
string get_sys_config_kv(const string &item, const string &key, const string &value = "", bool from_cache = true)
+
+
+

get_app_config_kv

+

Get APP config item value.

+ + + + + + + + + + + + + + + + + +
itemdescription
paramitem: name of setting item, e.g. user_info
key: config key, e.g. for user_info, key can be name, age etc.
value: default value, if not found, return this value.
from_cache: if true, read from cache, if false, read from file.
returnconfig value, always string type, if not found, return empty string.
+
+

C++ defination code:

+ +
string get_app_config_kv(const string &item, const string &key, const string &value = "", bool from_cache = true)
+
+
+

set_app_config_kv

+

Set APP config item value.

+ + + + + + + + + + + + + + + + + +
itemdescription
paramitem: name of setting item, e.g. user_info
key: config key, e.g. for user_info, key can be name, age etc.
value: config value, always string type.
write_file: if true, write to file, if false, just write to cache.
returnerr::Err
+
+

C++ defination code:

+ +
err::Err set_app_config_kv(const string &item, const string &key, const string &value, bool write_file = true)
+
+
+

get_app_config_path

+

Get APP config path, ini format, so you can use your own ini parser to parse it like configparser in Python.\nAll APP config info is recommended to store in this file.

+ + + + + + + + + + + + + +
itemdescription
returnAPP config path(ini format).
+
+

C++ defination code:

+ +
string get_app_config_path()
+
+
+

set_exit_msg

+

Set APP exit code and exit message.\nIf code != 0, the launcher will show a dialog to user, and display the msg.

+ + + + + + + + + + + + + + + + + +
itemdescription
paramcode: exit code, 0 means success, other means error, if code is 0, do nothing.
msg: exit message, if code is 0, msg is not used.
returnexit code, the same as arg @code.
+
+

C++ defination code:

+ +
err::Err set_exit_msg(err::Err code, const string &msg)
+
+
+

get_exit_msg

+

Get APP exit code and exit message.

+ + + + + + + + + + + + + + + + + +
itemdescription
paramcache: if true, read from cache, if false, read from file. default false.
returnexit return app_id, exit code and exit message.
+
+

C++ defination code:

+ +
tuple<string, err::Err, string> get_exit_msg(bool cache = false)
+
+
+

have_exit_msg

+

Check if have exit msg

+ + + + + + + + + + + + + + + + + +
itemdescription
paramcache: if true, just check from cache, if false, check from file. default false.
returntrue if have exit msg, false if not.
+
+

C++ defination code:

+ +
bool have_exit_msg(bool cache = false)
+
+
+

switch_app

+

Exit this APP and start another APP(by launcher).\nCall this API will call set_exit_flag(true), you should check app::need_exit() in your code.\nAnd exit this APP if app::need_exit() return true.

+ + + + + + + + + + + + + + + + + +
itemdescription
paramapp_id: APP ID which will be started. app_id and idx must have one is valid.
idx: APP index. app_id and idx must have one is valid.
start_param: string type, will send to app, app can get this param by app.get_start_param()
attentionIf app id or idx the same as current app, do nothing.
+
+

C++ defination code:

+ +
void switch_app(const string &app_id, int idx = -1, const std::string &start_param = "")
+
+
+

get_start_param

+

Get start param set by caller

+ + + + + + + + + + + + + +
itemdescription
returnparam, string type
+
+

C++ defination code:

+ +
const std::string get_start_param()
+
+
+

need_exit

+

Shoule this APP exit?

+ + + + + + + + + + + + + + + + + +
itemdescription
returntrue if this APP should exit, false if not.
attentionThis API is a function, not a variable.
+
+

C++ defination code:

+ +
bool need_exit()
+
+
+

running

+

App should running? The same as !app::need_exit() (not app::need_exit() in MaixPy).

+ + + + + + + + + + + + + + + + + +
itemdescription
returntrue if this APP should running, false if not.
attentionThis API is a function, not a variable.
+
+

C++ defination code:

+ +
bool running()
+
+
+

set_exit_flag

+

Set exit flag. You can get exit flag by app.need_exit().

+ + + + + + + + + + + + + +
itemdescription
paramexit: true if this APP should exit, false if not.
+
+

C++ defination code:

+ +
void set_exit_flag(bool exit)
+
+
+

Class

+

Version

+

APP version

+
+

C++ defination code:

+ +
class Version
+
+
+

__str__

+

Convert to string, e.g. 1.0.0

+ + + + + + + + + + + + + + + + + +
itemdescription
typefunc
staticFalse
+
+

C++ defination code:

+ +
std::string __str__()
+
+
+

from_str

+

Convert from string, e.g. "1.0.0"

+ + + + + + + + + + + + + + + + + +
itemdescription
typefunc
staticTrue
+
+

C++ defination code:

+ +
static app::Version from_str(const string &version_str)
+
+
+

APP_Info

+

APP info

+
+

C++ defination code:

+ +
class APP_Info
+
+
+

id

+

APP id

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typevar
staticFalse
readonlyFalse
+
+

C++ defination code:

+ +
string id
+
+
+

name

+

APP name

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typevar
staticFalse
readonlyFalse
+
+

C++ defination code:

+ +
string name
+
+
+

icon

+

APP icon

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typevar
staticFalse
readonlyFalse
+
+

C++ defination code:

+ +
string icon
+
+
+

version

+

APP version

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typevar
staticFalse
readonlyFalse
+
+

C++ defination code:

+ +
Version version
+
+
+

exec

+

APP exec

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typevar
staticFalse
readonlyFalse
+
+

C++ defination code:

+ +
string exec
+
+
+

author

+

APP author

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typevar
staticFalse
readonlyFalse
+
+

C++ defination code:

+ +
string author
+
+
+

desc

+

APP desc

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typevar
staticFalse
readonlyFalse
+
+

C++ defination code:

+ +
string desc
+
+
+

names

+

APP names

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typevar
staticFalse
readonlyFalse
+
+

C++ defination code:

+ +
map<string, string> names
+
+
+

descs

+

APP descs

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typevar
staticFalse
readonlyFalse
+
+

C++ defination code:

+ +
map<string, string> descs
+
+
+ + +
+
+
+ + +
+
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixcdk/api/maix/audio.html b/maixcdk/api/maix/audio.html new file mode 100644 index 00000000..235f8a31 --- /dev/null +++ b/maixcdk/api/maix/audio.html @@ -0,0 +1,870 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + maix::audio - MaixCDK + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

maix::audio

+ +
+
+
    + +
+
+
+
+ + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

maix.audio module

+
+

This is maix::audio module of MaixCDK.
+All of these elements are in namespace maix::audio.

+

For MaixCDK developer: DO NOT edit this doc file manually, this doc is auto generated!

+
+

Module

+

No module

+

Enum

+

Format

+

Audio type

+ + + + + + + + + + + + + +
itemdescribe
valuesFMT_NONE: format invalid
FMT_S8: unsigned 8 bits
FMT_S16_LE: signed 16 bits, little endian
FMT_S32_LE: signed 32 bits, little endian
FMT_S16_BE: signed 16 bits, big endian
FMT_S32_BE: signed 32 bits, big endian
FMT_U8: unsigned 8 bits
FMT_U16_LE: unsigned 16 bits, little endian
FMT_U32_LE: unsigned 32 bits, little endian
FMT_U16_BE: unsigned 16 bits, big endian
FMT_U32_BE: unsigned 32 bits, big endian
+
+

C++ defination code:

+ +
enum Format
+    {
+        FMT_NONE = 0,       // format invalid
+        FMT_S8,             // unsigned 8 bits
+        FMT_S16_LE,         // signed 16 bits, little endian
+        FMT_S32_LE,         // signed 32 bits, little endian
+        FMT_S16_BE,         // signed 16 bits, big endian
+        FMT_S32_BE,         // signed 32 bits, big endian
+        FMT_U8,             // unsigned 8 bits
+        FMT_U16_LE,         // unsigned 16 bits, little endian
+        FMT_U32_LE,         // unsigned 32 bits, little endian
+        FMT_U16_BE,         // unsigned 16 bits, big endian
+        FMT_U32_BE,         // unsigned 32 bits, big endian
+    }
+
+
+

Variable

+

Function

+

Class

+

Recorder

+

Recorder class

+
+

C++ defination code:

+ +
class Recorder
+
+
+

Recorder

+

Construct a new Recorder object. currectly only pcm and wav formats supported.

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
parampath: record path. the path determines the location where you save the file, if path is none, the audio module will not save file.
sample_rate: record sample rate, default is 48000(48KHz), means 48000 samples per second.
format: record sample format, default is audio::Format::FMT_S16_LE, means sampling 16 bits at a time and save as signed 16 bits, little endian. see @audio::Format
channel: record sample channel, default is 1, means 1 channel sampling at the same time
staticFalse
+
+

C++ defination code:

+ +
Recorder(std::string path = std::string(), int sample_rate = 48000, audio::Format format = audio::Format::FMT_S16_LE, int channel = 1)
+
+
+

volume

+

Set/Get record volume

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramvalue: volume value, If you use this parameter, audio will set the value to volume,
if you don't, it will return the current volume. range is [0, 100].
returnthe current volume
staticFalse
+
+

C++ defination code:

+ +
int volume(int value = -1)
+
+
+

mute

+

Mute

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramdata: mute data, If you set this parameter to true, audio will set the value to mute,
if you don't, it will return the current mute status.
returnReturns whether mute is currently enabled.
staticFalse
+
+

C++ defination code:

+ +
bool mute(int data = -1)
+
+
+

record

+

Record, Read all cached data in buffer and return. If there is no audio data in the buffer, may return empty data.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramrecord_ms: Block and record audio data lasting record_ms milliseconds and save it to a file, the return value does not return audio data. Only valid if the initialisation path is set.
returnpcm data. datatype @see Bytes. If you pass in record_ms parameter, the return value is an empty Bytes object.
staticFalse
+
+

C++ defination code:

+ +
maix::Bytes *record(int record_ms = -1)
+
+
+

record_bytes

+

Record, Read all cached data in buffer and return. If there is no audio data in the buffer, may return empty data.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
noteThis interface is experimental and may be removed in the future.
paramrecord_size: Record audio data of size record_size.
returnpcm data. datatype @see Bytes. If you pass in record_ms parameter, the return value is an empty Bytes object.
staticFalse
+
+

C++ defination code:

+ +
maix::Bytes *record_bytes(int record_size = -1)
+
+
+

finish

+

Finish the record, if you have passed in the path, this api will save the audio data to file.

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnerror code, err::ERR_NONE means success, others means failed
staticFalse
+
+

C++ defination code:

+ +
err::Err finish()
+
+
+

sample_rate

+

Get sample rate

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnreturns sample rate
staticFalse
+
+

C++ defination code:

+ +
int sample_rate()
+
+
+

format

+

Get sample format

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnreturns sample format
staticFalse
+
+

C++ defination code:

+ +
audio::Format format()
+
+
+

channel

+

Get sample channel

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnreturns sample channel
staticFalse
+
+

C++ defination code:

+ +
int channel()
+
+
+

Player

+

Player class

+
+

C++ defination code:

+ +
class Player
+
+
+

Player

+

Construct a new Player object

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
parampath: player path. the path determines the location where you save the file, if path is none, the audio module will not save file.
sample_rate: player sample rate, default is 48000(48KHz), means 48000 samples per second.
format: player sample format, default is audio::Format::FMT_S16_LE, means sampling 16 bits at a time and save as signed 16 bits, little endian. see @audio::Format
channel: player sample channel, default is 1, means 1 channel sampling at the same time
staticFalse
+
+

C++ defination code:

+ +
Player(std::string path = std::string(), int sample_rate = 48000, audio::Format format = audio::Format::FMT_S16_LE, int channel = 1)
+
+
+

volume

+

Set/Get player volume

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramvalue: volume value, If you use this parameter, audio will set the value to volume,
if you don't, it will return the current volume. range is [0, 100].
returnthe current volume
staticFalse
+
+

C++ defination code:

+ +
int volume(int value = -1)
+
+
+

play

+

Play

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramdata: audio data, must be raw data
returnerror code, err::ERR_NONE means success, others means failed
staticFalse
+
+

C++ defination code:

+ +
err::Err play(maix::Bytes *data = maix::audio::Player::NoneBytes)
+
+
+

sample_rate

+

Get sample rate

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnreturns sample rate
staticFalse
+
+

C++ defination code:

+ +
int sample_rate()
+
+
+

format

+

Get sample format

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnreturns sample format
staticFalse
+
+

C++ defination code:

+ +
audio::Format format()
+
+
+

channel

+

Get sample channel

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnreturns sample channel
staticFalse
+
+

C++ defination code:

+ +
int channel()
+
+
+ + +
+
+
+ + +
+
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixcdk/api/maix/camera.html b/maixcdk/api/maix/camera.html new file mode 100644 index 00000000..da6ad554 --- /dev/null +++ b/maixcdk/api/maix/camera.html @@ -0,0 +1,1517 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + maix::camera - MaixCDK + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

maix::camera

+ +
+
+
    + +
+
+
+
+ + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

maix.camera module, access camera device and get image from it

+
+

This is maix::camera module of MaixCDK.
+All of these elements are in namespace maix::camera.

+

For MaixCDK developer: DO NOT edit this doc file manually, this doc is auto generated!

+
+

Module

+

No module

+

Enum

+

Variable

+

Function

+

list_devices

+

List all supported camera devices.

+ + + + + + + + + + + + + +
itemdescription
returnReturns the path to the camera device.
+
+

C++ defination code:

+ +
std::vector<std::string> list_devices()
+
+
+

set_regs_enable

+

Enable set camera registers, default is false, if set to true, will not set camera registers, you can manually set registers by write_reg API.

+ + + + + + + + + + + + + +
itemdescription
paramenable: enable/disable set camera registers
+
+

C++ defination code:

+ +
void set_regs_enable(bool enable = true)
+
+
+

get_device_name

+

Get device name. Most of the time, the returned name is the name of the sensor.

+
+

C++ defination code:

+ +
std::string get_device_name()
+
+
+

Class

+

Camera

+

Camera class

+
+

C++ defination code:

+ +
class Camera
+
+
+

Camera

+

Construct a new Camera object.\nMaximum resolution support 2560x1440.

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramwidth: camera width, default is -1, means auto, mostly means max width of camera support
height: camera height, default is -1, means auto, mostly means max height of camera support
format: camera output format, default is image.Format.FMT_RGB888
device: camera device path, you can get devices by list_devices method, by default(value is NULL(None in MaixPy)) means the first device
fps: camera fps, default is -1, means auto, mostly means max fps of camera support
buff_num: camera buffer number, default is 3, means 3 buffer, one used by user, one used for cache the next frame,
more than one buffer will accelerate image read speed, but will cost more memory.
open: If true, camera will automatically call open() after creation. default is true.
raw: If true, you can use read_raw() to capture the raw image output from the sensor.
staticFalse
+
+

C++ defination code:

+ +
Camera(int width = -1, int height = -1, image::Format format = image::FMT_RGB888, const char *device = nullptr, double fps = -1, int buff_num = 3, bool open = true, bool raw = false)
+
+
+

get_ch_nums

+

Get the number of channels supported by the camera.

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnReturns the maximum number of channels.
staticFalse
+
+

C++ defination code:

+ +
int get_ch_nums()
+
+
+

open

+

Open camera and run

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramwidth: camera width, default is -1, means auto, mostly means max width of camera support
height: camera height, default is -1, means auto, mostly means max height of camera support
format: camera output format, default same as the constructor's format argument
fps: camera fps, default is -1, means auto, mostly means max fps of camera support
buff_num: camera buffer number, default is 3, means 3 buffer, one used by user, one used for cache the next frame,
more than one buffer will accelerate image read speed, but will cost more memory.
returnerror code, err::ERR_NONE means success, others means failed
staticFalse
+
+

C++ defination code:

+ +
err::Err open(int width = -1, int height = -1, image::Format format = image::FMT_INVALID, double fps = -1, int buff_num = -1)
+
+
+

read

+

Get one frame image from camera buffer, must call open method before read.\nIf open method not called, will call it automatically, if open failed, will throw exception!\nSo call open method before read is recommended.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
parambuff: buffer to store image data, if buff is nullptr, will alloc memory automatically.
In MaixPy, default to None, you can create a image.Image object, then pass img.data() to buff.
block: block read, default is true, means block util read image successfully,
if set to false, will return nullptr if no image in buffer
block_ms: block read timeout
returnimage::Image object, if failed, return nullptr, you should delete if manually in C++
staticFalse
+
+

C++ defination code:

+ +
image::Image *read(void *buff = nullptr, size_t buff_size = 0, bool block = true, int block_ms = -1)
+
+
+

read_raw

+

Read the raw image and obtain the width, height, and format of the raw image through the returned Image object.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
noteThe raw image is in a Bayer format, and its width and height are affected by the driver. Modifying the size and format is generally not allowed.
returnimage::Image object, if failed, return nullptr, you should delete if manually in C++
staticFalse
+
+

C++ defination code:

+ +
image::Image *read_raw()
+
+
+

clear_buff

+

Clear buff to ensure the next read image is the latest image

+ + + + + + + + + + + + + + + + + +
itemdescription
typefunc
staticFalse
+
+

C++ defination code:

+ +
void clear_buff()
+
+
+

skip_frames

+

Read some frames and drop, this is usually used avoid read not stable image when camera just opened.

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramnum: number of frames to read and drop
staticFalse
+
+

C++ defination code:

+ +
void skip_frames(int num)
+
+
+

close

+

Close camera

+ + + + + + + + + + + + + + + + + +
itemdescription
typefunc
staticFalse
+
+

C++ defination code:

+ +
void close()
+
+
+

add_channel

+

Add a new channel and return a new Camera object, you can use close() to close this channel.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramwidth: camera width, default is -1, means auto, mostly means max width of camera support
height: camera height, default is -1, means auto, mostly means max height of camera support
format: camera output format, default is RGB888
fps: camera fps, default is -1, means auto, mostly means max fps of camera support
buff_num: camera buffer number, default is 3, means 3 buffer, one used by user, one used for cache the next frame,
more than one buffer will accelerate image read speed, but will cost more memory.
open: If true, camera will automatically call open() after creation. default is true.
returnnew Camera object
staticFalse
+
+

C++ defination code:

+ +
camera::Camera *add_channel(int width = -1, int height = -1, image::Format format = image::FMT_RGB888, double fps = -1, int buff_num = 3, bool open = true)
+
+
+

is_opened

+

Check if camera is opened

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returntrue if camera is opened, false if not
staticFalse
+
+

C++ defination code:

+ +
bool is_opened()
+
+
+

is_closed

+

check camera device is closed or not

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnclosed or not, bool type
staticFalse
+
+

C++ defination code:

+ +
bool is_closed()
+
+
+

width

+

Get camera width

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returncamera width
staticFalse
+
+

C++ defination code:

+ +
int width()
+
+
+

height

+

Get camera height

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returncamera height
staticFalse
+
+

C++ defination code:

+ +
int height()
+
+
+

fps

+

Get camera fps

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returncamera fps
staticFalse
+
+

C++ defination code:

+ +
double fps()
+
+
+

format

+

Get camera output format

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returncamera output format, image::Format object
staticFalse
+
+

C++ defination code:

+ +
image::Format format()
+
+
+

buff_num

+

Get camera buffer number

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returncamera buffer number
staticFalse
+
+

C++ defination code:

+ +
int buff_num()
+
+
+

hmirror

+

Set/Get camera horizontal mirror

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returncamera horizontal mirror
staticFalse
+
+

C++ defination code:

+ +
int hmirror(int value = -1)
+
+
+

vflip

+

Set/Get camera vertical flip

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returncamera vertical flip
staticFalse
+
+

C++ defination code:

+ +
int vflip(int value = -1)
+
+
+

device

+

Get camera device path

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returncamera device path
staticFalse
+
+

C++ defination code:

+ +
std::string device()
+
+
+

write_reg

+

Write camera register

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramaddr: register address
data: register data
bit_width: register data bit width, default is 8
returnerror code, err::ERR_NONE means success, others means failed
staticFalse
+
+

C++ defination code:

+ +
err::Err write_reg(int addr, int data, int bit_width = 8)
+
+
+

read_reg

+

Read camera register

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramaddr: register address
bit_width: register data bit width, default is 8
returnregister data, -1 means failed
staticFalse
+
+

C++ defination code:

+ +
int read_reg(int addr, int bit_width = 8)
+
+
+

show_colorbar

+

Camera output color bar image for test

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramenable: enable/disable color bar
returnerror code, err::ERR_NONE means success, others means failed
staticFalse
+
+

C++ defination code:

+ +
err::Err show_colorbar(bool enable)
+
+
+

get_channel

+

Get channel of camera

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnchannel number
staticFalse
+
+

C++ defination code:

+ +
int get_channel()
+
+
+

set_resolution

+

Set camera resolution

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramwidth: new width
height: new height
returnerror code, err::ERR_NONE means success, others means failed
staticFalse
+
+

C++ defination code:

+ +
err::Err set_resolution(int width, int height)
+
+
+

set_fps

+

Set camera fps

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramfps: new fps
returnerror code, err::ERR_NONE means success, others means failed
staticFalse
+
+

C++ defination code:

+ +
err::Err set_fps(double fps)
+
+
+

exposure

+

Set/Get camera exposure

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
attentionThis method will affect the isp and thus the image, so please be careful with it.
paramvalue: exposure time. unit: us
If value == -1, return exposure time.
If value != 0, set and return exposure time.
returncamera exposure time
staticFalse
+
+

C++ defination code:

+ +
int exposure(int value = -1)
+
+
+

gain

+

Set/Get camera gain

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
attentionThis method will affect the isp and thus the image, so please be careful with it.
paramvalue: camera gain.
If value == -1, returns camera gain.
If value != 0, set and return camera gain.
returncamera gain
staticFalse
+
+

C++ defination code:

+ +
int gain(int value = -1)
+
+
+

luma

+

Set/Get camera luma

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
attentionThis method will affect the isp and thus the image, so please be careful with it.
paramvalue: luma value, range is [0, 100]
If value == -1, returns luma value.
If value != 0, set and return luma value.
returnreturns luma value
staticFalse
+
+

C++ defination code:

+ +
int luma(int value = -1)
+
+
+

constrast

+

Set/Get camera constrast

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
attentionThis method will affect the isp and thus the image, so please be careful with it.
paramvalue: constrast value, range is [0, 100]
If value == -1, returns constrast value.
If value != 0, set and return constrast value.
returnreturns constrast value
staticFalse
+
+

C++ defination code:

+ +
int constrast(int value = -1)
+
+
+

saturation

+

Set/Get camera saturation

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
attentionThis method will affect the isp and thus the image, so please be careful with it.
paramvalue: saturation value, range is [0, 100]
If value == -1, returns saturation value.
If value != 0, set and return saturation value.
returnreturns saturation value
staticFalse
+
+

C++ defination code:

+ +
int saturation(int value = -1)
+
+
+

awb_mode

+

Set/Get white balance mode (deprecated interface)

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
attentionThis method will affect the isp and thus the image, so please be careful with it.
This interface may be deprecated in the future, and there may be incompatibilities in the definition of the parameters of the new interface
paramvalue: value = 0, means set white balance to auto mode, value = 1, means set white balance to manual mode, default is auto mode.
returnreturns awb mode
staticFalse
+
+

C++ defination code:

+ +
int awb_mode(int value = -1)
+
+
+

set_awb

+

Set/Get white balance mode

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
attentionThis method will affect the isp and thus the image, so please be careful with it.
paramvalue: value = 0, means set white balance to manual mode, value = 1, means set white balance to auto mode, default is auto mode.
returnreturns awb mode
staticFalse
+
+

C++ defination code:

+ +
int set_awb(int mode = -1)
+
+
+

exp_mode

+

Set/Get exposure mode (deprecated interface)

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
attentionThis method will affect the isp and thus the image, so please be careful with it.
This interface may be deprecated in the future, and there may be incompatibilities in the definition of the parameters of the new interface
paramvalue: value = 0, means set exposure to auto mode, value = 1, means set exposure to manual mode, default is auto mode.
returnreturns exposure mode
staticFalse
+
+

C++ defination code:

+ +
int exp_mode(int value = -1)
+
+
+

set_windowing

+

Set window size of camera

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramroi: Support two input formats, [x,y,w,h] set the coordinates and size of the window;
[w,h] set the size of the window, when the window is centred.
returnerror code
staticFalse
+
+

C++ defination code:

+ +
err::Err set_windowing(std::vector<int> roi)
+
+
+ + +
+
+
+ + +
+
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixcdk/api/maix/comm.html b/maixcdk/api/maix/comm.html new file mode 100644 index 00000000..5d0626c5 --- /dev/null +++ b/maixcdk/api/maix/comm.html @@ -0,0 +1,962 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + maix::comm - MaixCDK + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

maix::comm

+ +
+
+
    + +
+
+
+
+ + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

maix.comm module

+
+

This is maix::comm module of MaixCDK.
+All of these elements are in namespace maix::comm.

+

For MaixCDK developer: DO NOT edit this doc file manually, this doc is auto generated!

+
+

Module

+ + + + + + + + + + + + + +
modulebrief
modbusmaix.comm.modbus module
+

Enum

+

Variable

+

Function

+

add_default_comm_listener

+

Add default CommProtocol listener.\nWhen the application uses this port, the listening thread will immediately\nrelease the port resources and exit. If you need to start the default listening thread again,\nplease release the default port resources and then call this function.

+
+

C++ defination code:

+ +
void add_default_comm_listener()
+
+
+

rm_default_comm_listener

+

Remove default CommProtocol listener.

+ + + + + + + + + + + + + +
itemdescription
returnbool type.
+
+

C++ defination code:

+ +
bool rm_default_comm_listener()
+
+
+

Class

+

CommProtocol

+

Class for communication protocol

+
+

C++ defination code:

+ +
class CommProtocol
+
+
+

CommProtocol

+

Construct a new CommProtocol object

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
parambuff_size: buffer size, default to 1024 bytes
staticFalse
+
+

C++ defination code:

+ +
CommProtocol(int buff_size = 1024, uint32_t header=maix::protocol::HEADER)
+
+
+

get_msg

+

Read data to buffer, and try to decode it as maix.protocol.MSG object

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramtimeout: unit ms, 0 means return immediatly, -1 means block util have msg, >0 means block until have msg or timeout.
returndecoded data, if nullptr, means no valid frame found.
Attentioin, delete it after use in C++.
staticFalse
+
+

C++ defination code:

+ +
protocol::MSG *get_msg(int timeout = 0)
+
+
+

resp_ok

+

Send response ok(success) message

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
parambuff: output buffer
buff_len: output buffer length
cmd: CMD value
body: response body, can be null
body_len: response body length, can be 0
returnsend response error code, maix.err.Err type
staticFalse
+
+

C++ defination code:

+ +
err::Err resp_ok(uint8_t *buff, int buff_len, uint8_t cmd, uint8_t *body = nullptr, int body_len = 0)
+
+
+

resp_ok (overload 1)

+

Send response ok(success) message

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramcmd: CMD value
body: response body, can be null
body_len: response body length, can be 0
returnencoded data, if nullptr, means error, and the error code is -err.Err.
Attentioin, delete it after use in C++.
staticFalse
+
+

C++ defination code:

+ +
err::Err resp_ok(uint8_t cmd, uint8_t *body = nullptr, int body_len = 0)
+
+
+

resp_ok (overload 2)

+

Send response ok(success) message

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramcmd: CMD value
body: response body, can be null
returnencoded data, if nullptr, means error, and the error code is -err.Err.
Attentioin, delete it after use in C++.
staticFalse
+
+

C++ defination code:

+ +
err::Err resp_ok(uint8_t cmd, Bytes *body = nullptr)
+
+
+

report

+

Send report message

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
parambuff: output buffer
buff_len: output buffer length
cmd: CMD value
body: report body, can be null
body_len: report body length, can be 0
returnsend report error code, maix.err.Err type
staticFalse
+
+

C++ defination code:

+ +
err::Err report(uint8_t *buff, int buff_len, uint8_t cmd, uint8_t *body = nullptr, int body_len = 0)
+
+
+

report (overload 1)

+

Send report message

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramcmd: CMD value
body: report body, can be null
body_len: report body length, can be 0
returnencoded data, if nullptr, means error, and the error code is -err.Err.
Attentioin, delete it after use in C++.
staticFalse
+
+

C++ defination code:

+ +
err::Err report(uint8_t cmd, uint8_t *body = nullptr, int body_len = 0)
+
+
+

report (overload 2)

+

Send report message

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramcmd: CMD value
body: report body, can be null
returnencoded data, if nullptr, means error, and the error code is -err.Err.
Attentioin, delete it after use in C++.
staticFalse
+
+

C++ defination code:

+ +
err::Err report(uint8_t cmd, Bytes *body = nullptr)
+
+
+

resp_err

+

Encode response error message to buffer

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
parambuff: output buffer
buff_len: output buffer length
cmd: CMD value
code: error code
msg: error message
returnsend response error code, maix.err.Err type
staticFalse
+
+

C++ defination code:

+ +
err::Err resp_err(uint8_t *buff, int buff_len, uint8_t cmd, err::Err code, const std::string &msg)
+
+
+

resp_err (overload 1)

+

Encode response error message to buffer

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramcmd: CMD value
code: error code
msg: error message
returnencoded data, if nullptr, means error, and the error code is -err.Err.
Attentioin, delete it after use in C++.
staticFalse
+
+

C++ defination code:

+ +
err::Err resp_err(uint8_t cmd, err::Err code, const std::string &msg)
+
+
+

CommBase

+

Communication base class, all communication methods should implement this interface

+
+

C++ defination code:

+ +
class CommBase
+
+
+

open

+

Open device, if already opened, do nothing and return err.ERR_NONE.

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnopen device error code, err.Err type.
staticFalse
+
+

C++ defination code:

+ +
virtual err::Err open()
+
+
+

close

+

Close device, if already closed, do nothing and return err.ERR_NONE.

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnclose device error code, err.Err type.
staticFalse
+
+

C++ defination code:

+ +
virtual err::Err close()
+
+
+

is_open

+

Check if opened

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returntrue if opened, else false.
staticFalse
+
+

C++ defination code:

+ +
virtual bool is_open()
+
+
+

write

+

Send data to device

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
parambuff: data buffer
len: data length need to send, the len must <= buff length.
returnsent data length, < 0 means error, value is -err.Err.
staticFalse
+
+

C++ defination code:

+ +
virtual int write(const uint8_t *buff, int len)
+
+
+

write (overload 1)

+

Send data to uart

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramdata: direction [in], data to send, bytes type. If you want to send str type, use str.encode() to convert.
returnsent length, int type, if < 0 means error, value is -err.Err.
staticFalse
+
+

C++ defination code:

+ +
virtual int write(Bytes &data)
+
+
+

read

+

Receive data

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
parambuff: data buffer to store received data
buff_len: data buffer length
recv_len: max data length want to receive, default -1.
-1 means read data in uart receive buffer.
>0 means read recv_len data want to receive.
other values is invalid.
timeout: unit ms, timeout to receive data, default 0.
0 means read data in uart receive buffer and return immediately,
-1 means block until read recv_len data,
>0 means block until read recv_len data or timeout.
returnreceived data length, < 0 means error, value is -err.Err.
staticFalse
+
+

C++ defination code:

+ +
virtual int read(uint8_t *buff, int buff_len, int recv_len, int timeout)
+
+
+

read (overload 1)

+

Recv data from uart

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramlen: max data length want to receive, default -1.
-1 means read data in uart receive buffer.
>0 means read len data want to receive.
other values is invalid.
timeout: unit ms, timeout to receive data, default 0.
0 means read data in uart receive buffer and return immediately,
-1 means block until read len data,
>0 means block until read len data or timeout.
returnreceived data, bytes type.
staticFalse
+
+

C++ defination code:

+ +
virtual Bytes *read(int len, int timeout)
+
+
+ + +
+
+
+ + +
+
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixcdk/api/maix/comm/modbus.html b/maixcdk/api/maix/comm/modbus.html new file mode 100644 index 00000000..bd4bc594 --- /dev/null +++ b/maixcdk/api/maix/comm/modbus.html @@ -0,0 +1,1710 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + maix::comm::modbus - MaixCDK + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

maix::comm::modbus

+ +
+
+
    + +
+
+
+
+ + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

maix.comm.modbus module

+
+

This is maix::comm::modbus module of MaixCDK.
+All of these elements are in namespace maix::comm::modbus.

+

For MaixCDK developer: DO NOT edit this doc file manually, this doc is auto generated!

+
+

Module

+

No module

+

Enum

+

Mode

+

modbus mode

+ + + + + + + + + + + + + +
itemdescribe
valuesRTU:
TCP:
+
+

C++ defination code:

+ +
enum class Mode : unsigned char {
+        RTU,
+        TCP
+    }
+
+
+

RequestType

+

Modbus request types enumeration.\nThis enumeration defines the various Modbus request types,\nincluding functions for reading and writing coils, registers,\nas well as diagnostics and identification.

+ + + + + + + + + + + + + +
itemdescribe
valuesREAD_COILS: < Read Coils
READ_DISCRETE_INPUTS: < Read Discrete Inputs
READ_HOLDING_REGISTERS: < Read Holding Registers
READ_INPUT_REGISTERS: < Read Input Registers
WRITE_SINGLE_COIL: < Write Single Coil
WRITE_SINGLE_REGISTER: < Write Single Register
DIAGNOSTICS: < Diagnostics (Serial Line only)
GET_COMM_EVENT_COUNTER: < Get Comm Event Counter (Serial Line only)
WRITE_MULTIPLE_COILS: < Write Multiple Coils
WRITE_MULTIPLE_REGISTERS: < Write Multiple Registers
REPORT_SERVER_ID: < Report Slave ID (Serial Line only)
MASK_WRITE_REGISTER: < Mask Write Register
READ_WRITE_MULTIPLE_REGISTERS: < Read/Write Multiple Registers
READ_DEVICE_IDENTIFICATION: < Read Device Identification
UNKNOWN: < Unknown Request Type
+
+

C++ defination code:

+ +
enum class RequestType : unsigned char {
+        READ_COILS                      = 0x01,     ///< Read Coils
+        READ_DISCRETE_INPUTS            = 0x02,     ///< Read Discrete Inputs
+        READ_HOLDING_REGISTERS          = 0x03,     ///< Read Holding Registers
+        READ_INPUT_REGISTERS            = 0x04,     ///< Read Input Registers
+        WRITE_SINGLE_COIL               = 0x05,     ///< Write Single Coil
+        WRITE_SINGLE_REGISTER           = 0x06,     ///< Write Single Register
+        DIAGNOSTICS                     = 0x08,     ///< Diagnostics (Serial Line only)
+        GET_COMM_EVENT_COUNTER          = 0x0B,     ///< Get Comm Event Counter (Serial Line only)
+        WRITE_MULTIPLE_COILS            = 0x0F,     ///< Write Multiple Coils
+        WRITE_MULTIPLE_REGISTERS        = 0x10,     ///< Write Multiple Registers
+        REPORT_SERVER_ID                = 0x11,     ///< Report Slave ID (Serial Line only)
+        MASK_WRITE_REGISTER             = 0x16,     ///< Mask Write Register
+        READ_WRITE_MULTIPLE_REGISTERS   = 0x17,     ///< Read/Write Multiple Registers
+        READ_DEVICE_IDENTIFICATION      = 0x2B,     ///< Read Device Identification
+        UNKNOWN                         = 0xFF      ///< Unknown Request Type
+    }
+
+
+

Variable

+

Function

+

set_master_debug

+

Set the master debug ON/OFF

+ + + + + + + + + + + + + +
itemdescription
paramdebug: True(ON) or False(OFF)
+
+

C++ defination code:

+ +
void set_master_debug(bool debug)
+
+
+

Class

+

RegisterInfo

+

Structure to hold information about a Modbus register.\nThis structure contains the starting address and size of a Modbus register,\nallowing for easy management of register information.

+
+

C++ defination code:

+ +
struct RegisterInfo
+
+
+

Registers

+

Structure to hold information about multiple Modbus registers.\nThis structure aggregates information for various types of Modbus registers,\nincluding coils, discrete inputs, holding registers, and input registers.

+
+

C++ defination code:

+ +
struct Registers
+
+
+

Slave

+

Class for modbus Slave

+
+

C++ defination code:

+ +
class Slave
+
+
+

__init__

+

Modbus Slave constructor.\nThis constructor initializes a Modbus Slave instance. Depending on the mode (RTU or TCP),\nit sets up the necessary parameters for communication and defines the register structure.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
parammode: Specifies the communication mode: RTU or TCP.
ip_or_device: The UART device name if using RTU mode.
If TCP mode is selected, this parameter is ignored.
coils_start: The starting address of the coils register.
coils_size: The number of coils to manage.
discrete_start: The starting address of the discrete inputs register.
discrete_size: The number of discrete inputs to manage.
holding_start: The starting address of the holding registers.
holding_size: The number of holding registers to manage.
input_start: The starting address of the input registers.
input_size: The number of input registers to manage.
rtu_baud: The baud rate for RTU communication.
Supported rates include: 110, 300, 600, 1200, 2400, 4800,
9600, 19200, 38400, 57600, 115200, 230400, 460800,
500000, 576000, 921600, 1000000, 1152000, 1500000,
2500000, 3000000, 3500000, 4000000.
Default is 115200. Ensure that the selected baud rate
is supported by the underlying hardware and libmodbus.
rtu_slave: The RTU slave address. Ignored in TCP mode. Default is 1.
tcp_port: The port used for TCP communication. Ignored in RTU mode. Default is 502.
debug: A boolean flag to enable or disable debug mode. Default is false.
seemodbus.Mode for valid modes.
staticFalse
+
+

C++ defination code:

+ +
Slave(maix::comm::modbus::Mode mode, const std::string& ip_or_device,
+            uint32_t coils_start=0, uint32_t coils_size=0,
+            uint32_t discrete_start=0, uint32_t discrete_size=0,
+            uint32_t holding_start=0, uint32_t holding_size=0,
+            uint32_t input_start=0, uint32_t input_size=0,
+            int rtu_baud=115200, uint8_t rtu_slave=1,
+            int tcp_port=502, bool debug=false)
+
+
+

receive

+

Receives a Modbus request\nThis function is used to receive a Modbus request from the client. The behavior of the function\ndepends on the parameter timeout_ms provided, which dictates how long the function will wait\nfor a request before returning.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
noteThis function gets and parses the request, it does not manipulate the registers.
paramtimeout_ms: Timeout setting
-1 Block indefinitely until a request is received
0 Non-blocking mode; function returns immediately, regardless of whether a request is received
>0 Blocking mode; function will wait for the specified number of milliseconds for a request
returnmaix::err::Err type, @see maix::err::Err
staticFalse
+
+

C++ defination code:

+ +
::maix::err::Err receive(const int timeout_ms=-1)
+
+
+

request_type

+

Gets the type of the Modbus request that was successfully received\nThis function can be used to retrieve the type of the request received after a successful\ncall to receive(). The return value indicates the type of the Modbus request, allowing\nthe user to understand and process the received request appropriately.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnRequestType The type of the Modbus request that has been received.
seemodbus.RequestType
staticFalse
+
+

C++ defination code:

+ +
::maix::comm::modbus::RequestType request_type()
+
+
+

reply

+

Processes the request and returns the corresponding data.\nThis function handles the requests received from the client. It retrieves any data that the client\nneeds to write to the registers and updates the registers accordingly. Additionally, it retrieves\nthe requested data from the registers and sends it back to the client in the response.\nThis function is essential for managing read and write operations in a Modbus Slave context.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
noteThe function will modify the Slave's internal state based on the data received in the
request, and ensure that the appropriate data is returned to the client.
returnmaix::err::Err type, @see maix::err::Err
staticFalse
+
+

C++ defination code:

+ +
::maix::err::Err reply()
+
+
+

receive_and_reply

+

Receives a request from the client and sends a response.\nThis function combines the operations of receiving a request and sending a corresponding\nresponse in a single call. It waits for a specified duration (defined by the timeout_ms\nparameter) to receive a request from the client. Upon successful receipt of the request,\nit processes the request and prepares the necessary data to be sent back to the client.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramtimeout_ms: The timeout duration for waiting to receive a request.
- A value of -1 makes the function block indefinitely until a request
is received.
- A value of 0 makes it non-blocking, returning immediately without
waiting for a request.
- A positive value specifies the maximum time (in milliseconds) to wait
for a request before timing out.
returnRequestType The type of the Modbus request that has been received.
seemodbus.RequestType
staticFalse
+
+

C++ defination code:

+ +
::maix::comm::modbus::RequestType receive_and_reply(const int timeout_ms=-1)
+
+
+

coils

+

Reads from or writes to coils.\nThis function can be used to either read data from coils or write data to them.\nIf the data parameter is empty, the function performs a read operation.\nIf data is not empty, the function writes the contents of data to the coils\nstarting at the specified index.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramdata: A vector of data to be written. If empty, a read operation is performed.
If not empty, the data will overwrite the coils from index.
index: The starting index for writing data. This parameter is ignored during read operations.
returnstd::vector<uint16_t> When the read operation is successful, return all data in the coils as a list.
When the write operation is successful, return a non-empty list; when it fails, return an empty list.
staticFalse
+
+

C++ defination code:

+ +
std::vector<uint8_t> coils(const std::vector<uint8_t>& data = std::vector<uint8_t>{}, const uint32_t index = 0)
+
+
+

discrete_input

+

Reads from or writes to discrete input.\nThis function can be used to either read data from discrete input or write data to them.\nIf the data parameter is empty, the function performs a read operation.\nIf data is not empty, the function writes the contents of data to the discrete input\nstarting at the specified index.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramdata: A vector of data to be written. If empty, a read operation is performed.
If not empty, the data will overwrite the discrete input from index.
index: The starting index for writing data. This parameter is ignored during read operations.
returnstd::vector<uint16_t> When the read operation is successful, return all data in the discrete input as a list.
When the write operation is successful, return a non-empty list; when it fails, return an empty list.
staticFalse
+
+

C++ defination code:

+ +
std::vector<uint8_t> discrete_input(const std::vector<uint8_t>& data = std::vector<uint8_t>{}, const uint32_t index = 0)
+
+
+

input_registers

+

Reads from or writes to input registers.\nThis function can be used to either read data from input registers or write data to them.\nIf the data parameter is empty, the function performs a read operation.\nIf data is not empty, the function writes the contents of data to the input registers\nstarting at the specified index.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramdata: A vector of data to be written. If empty, a read operation is performed.
If not empty, the data will overwrite the input registers from index.
index: The starting index for writing data. This parameter is ignored during read operations.
returnstd::vector<uint16_t> When the read operation is successful, return all data in the input registers as a list.
When the write operation is successful, return a non-empty list; when it fails, return an empty list.
staticFalse
+
+

C++ defination code:

+ +
std::vector<uint16_t> input_registers(const std::vector<uint16_t>& data = std::vector<uint16_t>{}, const uint32_t index = 0)
+
+
+

holding_registers

+

Reads from or writes to holding registers.\nThis function can be used to either read data from holding registers or write data to them.\nIf the data parameter is empty, the function performs a read operation.\nIf data is not empty, the function writes the contents of data to the holding registers\nstarting at the specified index.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramdata: A vector of data to be written. If empty, a read operation is performed.
If not empty, the data will overwrite the holding registers from index.
index: The starting index for writing data. This parameter is ignored during read operations.
returnstd::vector<uint16_t> When the read operation is successful, return all data in the holding registers as a list.
When the write operation is successful, return a non-empty list; when it fails, return an empty list.
staticFalse
+
+

C++ defination code:

+ +
std::vector<uint16_t> holding_registers(const std::vector<uint16_t>& data = std::vector<uint16_t>{}, const uint32_t index = 0)
+
+
+

MasterRTU

+

Class for modbus MasterRTU

+
+

C++ defination code:

+ +
class MasterRTU final
+
+
+

__init__

+

Construct a new MasterRTU object

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramdevice: Default uart device.
baudrate: Default uart baudrate.
staticFalse
+
+

C++ defination code:

+ +
MasterRTU(const std::string& device="", const int baudrate=115200)
+
+
+

read_coils

+

Reads coils from the Modbus device.\nThis function reads a specified number of coils starting from a given address.\nIt includes timeout settings to define how long to wait for a response.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramslave_id: The RTU slave address.
addr: The starting address for reading coils.
size: The number of coils to read.
timeout_ms: The timeout duration for waiting to receive a request.
- A value of -1 makes the function block indefinitely until a request
is received.
- A value of 0 makes it non-blocking, returning immediately without
waiting for a request.
- A positive value specifies the maximum time (in milliseconds) to wait
for a request before timing out.
device: The UART device to use. An empty string ("") indicates that the
default device from the constructor will be used.
baudrate: The UART baud rate. A value of -1 signifies that the default baud rate
from the constructor will be applied.
returnstd::vector<uint8_t>/list[int] A vector containing the read coil values.
staticFalse
+
+

C++ defination code:

+ +
std::vector<uint8_t> read_coils(const uint32_t slave_id, const uint32_t addr,
+                                        const uint32_t size, const int timeout_ms=-1,
+                                        const std::string& device="", const int baudrate=-1)
+
+
+

read_coils (overload 1)

+

Reads coils from the Modbus device.\nThis function reads a specified number of coils starting from a given address.\nIt includes timeout settings to define how long to wait for a response.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramdevice: The UART device to use.
baudrate: he UART baud rate.
slave_id: The RTU slave address.
addr: The starting address for reading coils.
size: The number of coils to read.
timeout_ms: The timeout duration for waiting to receive a request.
- A value of -1 makes the function block indefinitely until a request
is received.
- A value of 0 makes it non-blocking, returning immediately without
waiting for a request.
- A positive value specifies the maximum time (in milliseconds) to wait
for a request before timing out.
returnstd::vector<uint8_t>/list[int] A vector containing the read coil values.
staticTrue
+
+

C++ defination code:

+ +
static std::vector<uint8_t> read_coils( const std::string& device, const int baudrate,
+                                                const uint32_t slave_id, const uint32_t addr,
+                                                const uint32_t size, const int timeout_ms=-1)
+
+
+

write_coils

+

Writes values to coils on the Modbus device.\nThis function writes the specified data to the coils starting from a given address.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramslave_id: The RTU slave address.
data: A vector containing the coil values to write.
addr: The starting address for writing coils.
timeout_ms: The timeout duration for the write operation.
- A value of -1 makes the function block until the write is complete.
- A value of 0 makes it non-blocking.
- A positive value specifies the maximum time (in milliseconds) to wait.
device: The UART device to use. An empty string ("") indicates that the
default device from the constructor will be used.
baudrate: The UART baud rate. A value of -1 signifies that the default baud rate
from the constructor will be applied.
returnint Returns the number of bytes written on success, or a value less than 0 on failure.
staticFalse
+
+

C++ defination code:

+ +
int write_coils(const uint32_t slave_id, const std::vector<uint8_t>& data,
+                        const uint32_t addr, const int timeout_ms=-1,
+                        const std::string& device="", const int baudrate=-1)
+
+
+

write_coils (overload 1)

+

Writes values to coils on the Modbus device.\nThis function writes the specified data to the coils starting from a given address.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramdevice: The UART device to use.
baudrate: The UART baud rate.
slave_id: The RTU slave address.
data: A vector containing the coil values to write.
addr: The starting address for writing coils.
timeout_ms: The timeout duration for the write operation.
- A value of -1 makes the function block until the write is complete.
- A value of 0 makes it non-blocking.
- A positive value specifies the maximum time (in milliseconds) to wait.
returnint Returns the number of bytes written on success, or a value less than 0 on failure.
staticTrue
+
+

C++ defination code:

+ +
static int write_coils(const std::string& device, const int baudrate,
+                                const uint32_t slave_id, const std::vector<uint8_t>& data,
+                                const uint32_t addr, const int timeout_ms=-1)
+
+
+

read_discrete_input

+

Reads discrete inputs from the Modbus device.\nThis function reads a specified number of discrete inputs starting from a given address.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramslave_id: The RTU slave address.
addr: The starting address for reading discrete inputs.
size: The number of discrete inputs to read.
timeout_ms: The timeout duration for the write operation.
- A value of -1 makes the function block until the write is complete.
- A value of 0 makes it non-blocking.
- A positive value specifies the maximum time (in milliseconds) to wait.
device: The UART device to use. An empty string ("") indicates that the
default device from the constructor will be used.
baudrate: The UART baud rate. A value of -1 signifies that the default baud rate
from the constructor will be applied.
returnstd::vector<uint8_t>/list[int] A vector containing the read discrete input values.
staticFalse
+
+

C++ defination code:

+ +
std::vector<uint8_t> read_discrete_input(const uint32_t slave_id, const uint32_t addr,
+                                                const uint32_t size, const int timeout_ms=-1,
+                                                const std::string& device="", const int baudrate=-1)
+
+
+

read_discrete_input (overload 1)

+

Reads discrete inputs from the Modbus device.\nThis function reads a specified number of discrete inputs starting from a given address.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramdevice: The UART device to use.
baudrate: The UART baud rate.
slave_id: The RTU slave address.
addr: The starting address for reading discrete inputs.
size: The number of discrete inputs to read.
timeout_ms: The timeout duration for the write operation.
- A value of -1 makes the function block until the write is complete.
- A value of 0 makes it non-blocking.
- A positive value specifies the maximum time (in milliseconds) to wait.
returnstd::vector<uint8_t>/list[int] A vector containing the read discrete input values.
staticTrue
+
+

C++ defination code:

+ +
static std::vector<uint8_t> read_discrete_input(const std::string& device, const int baudrate,
+                                                        const uint32_t slave_id, const uint32_t addr,
+                                                        const uint32_t size, const int timeout_ms=-1)
+
+
+

read_input_registers

+

Reads input registers from the Modbus device.\nThis function reads a specified number of input registers starting from a given address.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramslave_id: The RTU slave address.
addr: The starting address for reading input registers.
size: The number of input registers to read.
timeout_ms: The timeout duration for the write operation.
- A value of -1 makes the function block until the write is complete.
- A value of 0 makes it non-blocking.
- A positive value specifies the maximum time (in milliseconds) to wait.
device: The UART device to use. An empty string ("") indicates that the
default device from the constructor will be used.
baudrate: The UART baud rate. A value of -1 signifies that the default baud rate
from the constructor will be applied.
returnstd::vector<uint16_t>/list[int] A vector containing the read input register values.
staticFalse
+
+

C++ defination code:

+ +
std::vector<uint16_t> read_input_registers(const uint32_t slave_id, const uint32_t addr,
+                                                const uint32_t size, const int timeout_ms=-1,
+                                                const std::string& device="", const int baudrate=-1)
+
+
+

read_input_registers (overload 1)

+

Reads input registers from the Modbus device.\nThis function reads a specified number of input registers starting from a given address.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramdevice: The UART device to use.
baudrate: The UART baud rate.
slave_id: The RTU slave address.
addr: The starting address for reading input registers.
size: The number of input registers to read.
timeout_ms: The timeout duration for the write operation.
- A value of -1 makes the function block until the write is complete.
- A value of 0 makes it non-blocking.
- A positive value specifies the maximum time (in milliseconds) to wait.
returnstd::vector<uint16_t>/list[int] A vector containing the read input register values.
staticTrue
+
+

C++ defination code:

+ +
static std::vector<uint16_t> read_input_registers(const std::string& device, const int baudrate,
+                                                        const uint32_t slave_id, const uint32_t addr,
+                                                        const uint32_t size, const int timeout_ms=-1)
+
+
+

read_holding_registers

+

Reads holding registers from the Modbus device.\nThis function reads a specified number of holding registers starting from a given address.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramslave_id: The RTU slave address.
addr: The starting address for reading holding registers.
size: The number of holding registers to read.
timeout_ms: The timeout duration for the write operation.
- A value of -1 makes the function block until the write is complete.
- A value of 0 makes it non-blocking.
- A positive value specifies the maximum time (in milliseconds) to wait.
device: The UART device to use. An empty string ("") indicates that the
default device from the constructor will be used.
baudrate: The UART baud rate. A value of -1 signifies that the default baud rate
from the constructor will be applied.
returnstd::vector<uint16_t>/list[int] A vector containing the read holding register values.
staticFalse
+
+

C++ defination code:

+ +
std::vector<uint16_t> read_holding_registers(const uint32_t slave_id, const uint32_t addr,
+                                                    const uint32_t size, const int timeout_ms=-1,
+                                                    const std::string& device="", const int baudrate=-1)
+
+
+

read_holding_registers (overload 1)

+

Reads holding registers from the Modbus device.\nThis function reads a specified number of holding registers starting from a given address.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramdevice: The UART device to use.
baudrate: The UART baud rate.
slave_id: The RTU slave address.
addr: The starting address for reading holding registers.
size: The number of holding registers to read.
timeout_ms: The timeout duration for the write operation.
- A value of -1 makes the function block until the write is complete.
- A value of 0 makes it non-blocking.
- A positive value specifies the maximum time (in milliseconds) to wait.
returnstd::vector<uint16_t>/list[int] A vector containing the read holding register values.
staticTrue
+
+

C++ defination code:

+ +
static std::vector<uint16_t> read_holding_registers(const std::string& device, const int baudrate,
+                                                            const uint32_t slave_id, const uint32_t addr,
+                                                            const uint32_t size, const int timeout_ms=-1)
+
+
+

write_holding_registers

+

Writes values to holding registers on the Modbus device.\nThis function writes the specified data to the holding registers starting from a given address.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramslave_id: The RTU slave address.
data: A vector containing the values to write to holding registers.
addr: The starting address for writing holding registers.
timeout_ms: The timeout duration for the write operation.
- A value of -1 makes the function block until the write is complete.
- A value of 0 makes it non-blocking.
- A positive value specifies the maximum time (in milliseconds) to wait.
device: The UART device to use. An empty string ("") indicates that the
default device from the constructor will be used.
baudrate: The UART baud rate. A value of -1 signifies that the default baud rate
from the constructor will be applied.
returnint Returns the number of bytes written on success, or a value less than 0 on failure.
staticFalse
+
+

C++ defination code:

+ +
int write_holding_registers(const uint32_t slave_id, const std::vector<uint16_t>& data,
+                                    const uint32_t addr, const int timeout_ms=-1,
+                                    const std::string& device="", const int baudrate=-1)
+
+
+

write_holding_registers (overload 1)

+

Writes values to holding registers on the Modbus device.\nThis function writes the specified data to the holding registers starting from a given address.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramdevice: The UART device to use.
baudrate: The UART baud rate.
slave_id: The RTU slave address.
data: A vector containing the values to write to holding registers.
addr: The starting address for writing holding registers.
timeout_ms: The timeout duration for the write operation.
- A value of -1 makes the function block until the write is complete.
- A value of 0 makes it non-blocking.
- A positive value specifies the maximum time (in milliseconds) to wait.
returnint Returns the number of bytes written on success, or a value less than 0 on failure.
staticTrue
+
+

C++ defination code:

+ +
static int write_holding_registers(const std::string& device, const int baudrate,
+                                           const uint32_t slave_id, const std::vector<uint16_t>& data,
+                                           const uint32_t addr, const int timeout_ms=-1)
+
+
+

MasterTCP

+

Class for modbus Master

+
+

C++ defination code:

+ +
class MasterTCP final
+
+
+

__init__

+

Construct a new MasterTCP object

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramport: Device tcp port.
staticFalse
+
+

C++ defination code:

+ +
MasterTCP(const int port=502)
+
+
+

read_coils

+

Reads coils from the Modbus device.\nThis function reads a specified number of coils starting from a given address.\nIt includes timeout settings to define how long to wait for a response.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramip: The TCP IP address.
addr: The starting address for reading coils.
size: The number of coils to read.
timeout_ms: The timeout duration for waiting to receive a request.
- A value of -1 makes the function block indefinitely until a request
is received.
- A value of 0 makes it non-blocking, returning immediately without
waiting for a request.
- A positive value specifies the maximum time (in milliseconds) to wait
for a request before timing out.
port: The TCP port. A value of -1 signifies that the default port
from the constructor will be applied.
returnstd::vector<uint8_t>/list[int] A vector containing the read coil values.
staticFalse
+
+

C++ defination code:

+ +
std::vector<uint8_t> read_coils(const std::string ip, const uint32_t addr,
+                                        const uint32_t size, const int timeout_ms=-1,
+                                        const int port=-1)
+
+
+

read_coils (overload 1)

+

Reads coils from the Modbus device.\nThis function reads a specified number of coils starting from a given address.\nIt includes timeout settings to define how long to wait for a response.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramip: The TCP IP address.
port: The TCP port.
addr: The starting address for reading coils.
size: The number of coils to read.
timeout_ms: The timeout duration for waiting to receive a request.
- A value of -1 makes the function block indefinitely until a request
is received.
- A value of 0 makes it non-blocking, returning immediately without
waiting for a request.
- A positive value specifies the maximum time (in milliseconds) to wait
for a request before timing out.
returnstd::vector<uint8_t>/list[int] A vector containing the read coil values.
staticTrue
+
+

C++ defination code:

+ +
static std::vector<uint8_t> read_coils( const std::string ip, const int port,
+                                                const uint32_t addr,
+                                                const uint32_t size, const int timeout_ms=-1)
+
+
+

write_coils

+

Writes values to coils on the Modbus device.\nThis function writes the specified data to the coils starting from a given address.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramip: The TCP IP address.
data: A vector containing the coil values to write.
addr: The starting address for writing coils.
timeout_ms: The timeout duration for the write operation.
- A value of -1 makes the function block until the write is complete.
- A value of 0 makes it non-blocking.
- A positive value specifies the maximum time (in milliseconds) to wait.
port: The TCP port. A value of -1 signifies that the default port
from the constructor will be applied.
returnint Returns the number of bytes written on success, or a value less than 0 on failure.
staticFalse
+
+

C++ defination code:

+ +
int write_coils(const std::string ip, const std::vector<uint8_t>& data,
+                        const uint32_t addr, const int timeout_ms=-1,
+                        const int port=-1)
+
+
+

write_coils (overload 1)

+

Writes values to coils on the Modbus device.\nThis function writes the specified data to the coils starting from a given address.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramip: The TCP IP address.
port: The TCP port.
data: A vector containing the coil values to write.
addr: The starting address for writing coils.
timeout_ms: The timeout duration for the write operation.
- A value of -1 makes the function block until the write is complete.
- A value of 0 makes it non-blocking.
- A positive value specifies the maximum time (in milliseconds) to wait.
returnint Returns the number of bytes written on success, or a value less than 0 on failure.
staticTrue
+
+

C++ defination code:

+ +
static int write_coils(const std::string ip, const int port,
+                                const std::vector<uint8_t>& data,
+                                const uint32_t addr, const int timeout_ms=-1)
+
+
+

read_discrete_input

+

Reads discrete inputs from the Modbus device.\nThis function reads a specified number of discrete inputs starting from a given address.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramip: The TCP IP address.
addr: The starting address for reading discrete inputs.
size: The number of discrete inputs to read.
timeout_ms: The timeout duration for the write operation.
- A value of -1 makes the function block until the write is complete.
- A value of 0 makes it non-blocking.
- A positive value specifies the maximum time (in milliseconds) to wait.
port: The TCP port. A value of -1 signifies that the default port
from the constructor will be applied.
returnstd::vector<uint8_t>/list[int] A vector containing the read discrete input values.
staticFalse
+
+

C++ defination code:

+ +
std::vector<uint8_t> read_discrete_input(const std::string ip, const uint32_t addr,
+                                        const uint32_t size, const int timeout_ms=-1,
+                                        const int port=-1)
+
+
+

read_discrete_input (overload 1)

+

Reads discrete inputs from the Modbus device.\nThis function reads a specified number of discrete inputs starting from a given address.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramip: The TCP IP address.
port: The TCP port.
addr: The starting address for reading discrete inputs.
size: The number of discrete inputs to read.
timeout_ms: The timeout duration for the write operation.
- A value of -1 makes the function block until the write is complete.
- A value of 0 makes it non-blocking.
- A positive value specifies the maximum time (in milliseconds) to wait.
returnstd::vector<uint8_t>/list[int] A vector containing the read discrete input values.
staticTrue
+
+

C++ defination code:

+ +
static std::vector<uint8_t> read_discrete_input(const std::string ip, const int port,
+                                                        const uint32_t addr,
+                                                        const uint32_t size, const int timeout_ms=-1)
+
+
+

read_input_registers

+

Reads input registers from the Modbus device.\nThis function reads a specified number of input registers starting from a given address.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramip: The TCP IP address.
addr: The starting address for reading input registers.
size: The number of input registers to read.
timeout_ms: The timeout duration for the write operation.
- A value of -1 makes the function block until the write is complete.
- A value of 0 makes it non-blocking.
- A positive value specifies the maximum time (in milliseconds) to wait.
port: The TCP port. A value of -1 signifies that the default port
from the constructor will be applied.
returnstd::vector<uint16_t>/list[int] A vector containing the read input register values.
staticFalse
+
+

C++ defination code:

+ +
std::vector<uint16_t> read_input_registers(const std::string ip, const uint32_t addr,
+                                        const uint32_t size, const int timeout_ms=-1,
+                                        const int port=-1)
+
+
+

read_input_registers (overload 1)

+

Reads input registers from the Modbus device.\nThis function reads a specified number of input registers starting from a given address.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramip: The TCP IP address.
port: The TCP port.
addr: The starting address for reading input registers.
size: The number of input registers to read.
timeout_ms: The timeout duration for the write operation.
- A value of -1 makes the function block until the write is complete.
- A value of 0 makes it non-blocking.
- A positive value specifies the maximum time (in milliseconds) to wait.
returnstd::vector<uint16_t>/list[int] A vector containing the read input register values.
staticTrue
+
+

C++ defination code:

+ +
static std::vector<uint16_t> read_input_registers(const std::string ip, const int port,
+                                                        const uint32_t addr,
+                                                        const uint32_t size, const int timeout_ms=-1)
+
+
+

read_holding_registers

+

Reads holding registers from the Modbus device.\nThis function reads a specified number of holding registers starting from a given address.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramip: The TCP IP address.
addr: The starting address for reading holding registers.
size: The number of holding registers to read.
timeout_ms: The timeout duration for the write operation.
- A value of -1 makes the function block until the write is complete.
- A value of 0 makes it non-blocking.
- A positive value specifies the maximum time (in milliseconds) to wait.
port: The TCP port. A value of -1 signifies that the default port
from the constructor will be applied.
returnstd::vector<uint16_t>/list[int] A vector containing the read holding register values.
staticFalse
+
+

C++ defination code:

+ +
std::vector<uint16_t> read_holding_registers(const std::string ip, const uint32_t addr,
+                                        const uint32_t size, const int timeout_ms=-1,
+                                        const int port=-1)
+
+
+

read_holding_registers (overload 1)

+

Reads holding registers from the Modbus device.\nThis function reads a specified number of holding registers starting from a given address.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramip: The TCP IP address.
port: The TCP port.
addr: The starting address for reading holding registers.
size: The number of holding registers to read.
timeout_ms: The timeout duration for the write operation.
- A value of -1 makes the function block until the write is complete.
- A value of 0 makes it non-blocking.
- A positive value specifies the maximum time (in milliseconds) to wait.
returnstd::vector<uint16_t>/list[int] A vector containing the read holding register values.
staticTrue
+
+

C++ defination code:

+ +
static std::vector<uint16_t> read_holding_registers(const std::string ip, const int port,
+                                                            const uint32_t addr,
+                                                            const uint32_t size, const int timeout_ms=-1)
+
+
+

write_holding_registers

+

Writes values to holding registers on the Modbus device.\nThis function writes the specified data to the holding registers starting from a given address.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramip: The TCP IP address.
data: A vector containing the values to write to holding registers.
addr: The starting address for writing holding registers.
timeout_ms: The timeout duration for the write operation.
- A value of -1 makes the function block until the write is complete.
- A value of 0 makes it non-blocking.
- A positive value specifies the maximum time (in milliseconds) to wait.
port: The TCP port. A value of -1 signifies that the default port
from the constructor will be applied.
returnint Returns the number of bytes written on success, or a value less than 0 on failure.
staticFalse
+
+

C++ defination code:

+ +
int write_holding_registers(const std::string ip, const std::vector<uint16_t>& data,
+                                    const uint32_t addr, const int timeout_ms=-1,
+                                    const int port=-1)
+
+
+

write_holding_registers (overload 1)

+

Writes values to holding registers on the Modbus device.\nThis function writes the specified data to the holding registers starting from a given address.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramip: The TCP IP address.
port: The TCP port.
data: A vector containing the values to write to holding registers.
addr: The starting address for writing holding registers.
timeout_ms: The timeout duration for the write operation.
- A value of -1 makes the function block until the write is complete.
- A value of 0 makes it non-blocking.
- A positive value specifies the maximum time (in milliseconds) to wait.
returnint Returns the number of bytes written on success, or a value less than 0 on failure.
staticTrue
+
+

C++ defination code:

+ +
static int write_holding_registers(const std::string ip, const int port,
+                                           const std::vector<uint16_t>& data,
+                                           const uint32_t addr, const int timeout_ms=-1)
+
+
+ + +
+
+
+ + +
+
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixcdk/api/maix/display.html b/maixcdk/api/maix/display.html new file mode 100644 index 00000000..b4e90b16 --- /dev/null +++ b/maixcdk/api/maix/display.html @@ -0,0 +1,931 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + maix::display - MaixCDK + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

maix::display

+ +
+
+
    + +
+
+
+
+ + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

maix.display module, control display device and show image on it

+
+

This is maix::display module of MaixCDK.
+All of these elements are in namespace maix::display.

+

For MaixCDK developer: DO NOT edit this doc file manually, this doc is auto generated!

+
+

Module

+

No module

+

Enum

+

Variable

+

Function

+

send_to_maixvision

+

Send image to MaixVision work station if connected.\nIf you want to debug your program an don't want to initialize display, use this method.

+ + + + + + + + + + + + + +
itemdescription
paramimg: image to send, image.Image object
+
+

C++ defination code:

+ +
void send_to_maixvision(image::Image &img)
+
+
+

set_trans_image_quality

+

Set image transport quality(only for JPEG)

+ + + + + + + + + + + + + +
itemdescription
paramquality: default 95, value from 51 ~ 100
+
+

C++ defination code:

+ +
void set_trans_image_quality(const int value)
+
+
+

Class

+

Display

+

Display class

+
+

C++ defination code:

+ +
class Display
+
+
+

Display

+

Construct a new Display object

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramwidth: display width, by default(value is -1) means auto detect,
if width > max device supported width, will auto set to max device supported width
height: display height, by default(value is -1) means auto detect,
if height > max device supported height, will auto set to max device supported height
device: display device name, you can get devices by list_devices method, by default(value is NULL(None in MaixPy)) means the first device
open: If true, display will automatically call open() after creation. default is true.
staticFalse
+
+

C++ defination code:

+ +
Display(int width = -1, int height = -1, image::Format format = image::FMT_RGB888, const std::string &device = "", bool open = true)
+
+
+

Display (overload 1)

+

Construct a new Display object.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
attentionDisplayBase * parameter need to be set manually, otherwise the operation of this object will be invalid.
paramdevice: display device path, you can get devices by list_devices method, by default(value is NULL(None in MaixPy)) means the first device
base: basic operation objects.
width: display width, default is -1, means auto, mostly means max width of display support
height: display height, default is -1, means auto, mostly means max height of display support
format: display output format
open: If true, display will automatically call open() after creation. default is true.
staticFalse
+
+

C++ defination code:

+ +
Display(const std::string &device, DisplayBase *base, int width = -1, int height = -1, image::Format format = image::FMT_INVALID, bool open = true)
+
+
+

width

+

Get display width

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnwidth
staticFalse
+
+

C++ defination code:

+ +
int width()
+
+
+

height

+

Get display height

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramch: channel to get, by default(value is 0) means the first channel
returnheight
staticFalse
+
+

C++ defination code:

+ +
int height()
+
+
+

size

+

Get display size

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramch: channel to get, by default(value is 0) means the first channel
returnsize A list type in MaixPy, [width, height]
staticFalse
+
+

C++ defination code:

+ +
std::vector<int> size()
+
+
+

format

+

Get display format

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnformat
staticFalse
+
+

C++ defination code:

+ +
image::Format format()
+
+
+

open

+

open display device, if already opened, will return err.ERR_NONE.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramwidth: display width, default is -1, means auto, mostly means max width of display support
height: display height, default is -1, means auto, mostly means max height of display support
format: display output format, default is RGB888
returnerror code
staticFalse
+
+

C++ defination code:

+ +
err::Err open(int width = -1, int height = -1, image::Format format = image::FMT_INVALID)
+
+
+

close

+

close display device

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnerror code
staticFalse
+
+

C++ defination code:

+ +
err::Err close()
+
+
+

add_channel

+

Add a new channel and return a new Display object, you can use close() to close this channel.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
attentionIf a new disp channel is created, it is recommended to set fit=image::FIT_COVER or fit=image::FIT_FILL when running show for the main channel,
otherwise the display of the new disp channel may be abnormal.
paramwidth: display width, default is -1, means auto, mostly means max width of display support. Maximum width must not exceed the main channel.
height: display height, default is -1, means auto, mostly means max height of display support. Maximum height must not exceed the main channel.
format: display output format, default is FMT_BGRA8888
open: If true, display will automatically call open() after creation. default is true.
returnnew Display object
staticFalse
+
+

C++ defination code:

+ +
display::Display *add_channel(int width = -1, int height = -1, image::Format format = image::FMT_BGRA8888, bool open = true)
+
+
+

is_opened

+

check display device is opened or not

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnopened or not, bool type
staticFalse
+
+

C++ defination code:

+ +
bool is_opened()
+
+
+

is_closed

+

check display device is closed or not

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnclosed or not, bool type
staticFalse
+
+

C++ defination code:

+ +
bool is_closed()
+
+
+

show

+

show image on display device, and will also send to MaixVision work station if connected.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramimg: image to show, image.Image object,
if the size of image smaller than display size, will show in the center of display;
if the size of image bigger than display size, will auto resize to display size and keep ratio, fill blank with black color.
fit: image in screen fit mode, by default(value is image.FIT_CONTAIN), @see image.Fit for more details
e.g. image.FIT_CONTAIN means resize image to fit display size and keep ratio, fill blank with black color.
returnerror code
staticFalse
+
+

C++ defination code:

+ +
err::Err show(image::Image &img, image::Fit fit = image::FIT_CONTAIN)
+
+
+

device

+

Get display device path

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returndisplay device path
staticFalse
+
+

C++ defination code:

+ +
std::string device()
+
+
+

set_backlight

+

Set display backlight

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramvalue: backlight value, float type, range is [0, 100]
staticFalse
+
+

C++ defination code:

+ +
void set_backlight(float value)
+
+
+

get_backlight

+

Get display backlight

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnvalue backlight value, float type, range is [0, 100]
staticFalse
+
+

C++ defination code:

+ +
float get_backlight()
+
+
+

set_hmirror

+

Set display mirror

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramen: enable/disable mirror
staticFalse
+
+

C++ defination code:

+ +
err::Err set_hmirror(bool en)
+
+
+

set_vflip

+

Set display flip

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramen: enable/disable flip
staticFalse
+
+

C++ defination code:

+ +
err::Err set_vflip(bool en)
+
+
+ + +
+
+
+ + +
+
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixcdk/api/maix/err.html b/maixcdk/api/maix/err.html new file mode 100644 index 00000000..18206db9 --- /dev/null +++ b/maixcdk/api/maix/err.html @@ -0,0 +1,532 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + maix::err - MaixCDK + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

maix::err

+ +
+
+
    + +
+
+
+
+ + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

maix.err module

+
+

This is maix::err module of MaixCDK.
+All of these elements are in namespace maix::err.

+

For MaixCDK developer: DO NOT edit this doc file manually, this doc is auto generated!

+
+

Module

+

No module

+

Enum

+

Err

+

Maix Error code

+ + + + + + + + + + + + + +
itemdescribe
valuesERR_NONE: No error
ERR_ARGS: Invalid arguments
ERR_NO_MEM: No memory
ERR_NOT_IMPL: Not implemented
ERR_NOT_READY: Not ready
ERR_NOT_INIT: Not initialized
ERR_NOT_OPEN: Not opened
ERR_NOT_PERMIT: Not permitted
ERR_REOPEN: Re-open
ERR_BUSY: Busy
ERR_READ: Read error
ERR_WRITE: Write error
ERR_TIMEOUT: Timeout
ERR_RUNTIME: Runtime error
ERR_IO: IO error
ERR_NOT_FOUND: Not found
ERR_ALREAY_EXIST: Already exist
ERR_BUFF_FULL: Buffer full
ERR_BUFF_EMPTY: Buffer empty
ERR_CANCEL: Cancel
ERR_OVERFLOW: Overflow
ERR_MAX:
+
+

C++ defination code:

+ +
enum Err
+    {
+        // !!! fixed error code, DO NOT change number already defined, only append new error code
+        ERR_NONE        = 0,   // No error
+        ERR_ARGS           ,   // Invalid arguments
+        ERR_NO_MEM         ,   // No memory
+        ERR_NOT_IMPL       ,   // Not implemented
+        ERR_NOT_READY      ,   // Not ready
+        ERR_NOT_INIT       ,   // Not initialized
+        ERR_NOT_OPEN       ,   // Not opened
+        ERR_NOT_PERMIT     ,   // Not permitted
+        ERR_REOPEN         ,   // Re-open
+        ERR_BUSY           ,   // Busy
+        ERR_READ           ,   // Read error
+        ERR_WRITE          ,   // Write error
+        ERR_TIMEOUT        ,   // Timeout
+        ERR_RUNTIME        ,   // Runtime error
+        ERR_IO             ,   // IO error
+        ERR_NOT_FOUND      ,   // Not found
+        ERR_ALREAY_EXIST   ,   // Already exist
+        ERR_BUFF_FULL      ,   // Buffer full
+        ERR_BUFF_EMPTY     ,   // Buffer empty
+        ERR_CANCEL         ,   // Cancel
+        ERR_OVERFLOW       ,   // Overflow
+        ERR_MAX,
+    }
+
+
+

Variable

+

Function

+

to_str

+

Error code to string

+ + + + + + + + + + + + + + + + + +
itemdescription
parame: direction [in], error code, err::Err type
returnerror string
+
+

C++ defination code:

+ +
std::string to_str(err::Err e)
+
+
+

get_error

+

get last error string

+ + + + + + + + + + + + + +
itemdescription
returnerror string
+
+

C++ defination code:

+ +
std::string& get_error()
+
+
+

set_error

+

set last error string

+ + + + + + + + + + + + + +
itemdescription
paramstr: direction [in], error string
+
+

C++ defination code:

+ +
void set_error(const std::string &str)
+
+
+

check_raise

+

Check error code, if not ERR_NONE, raise err.Exception

+ + + + + + + + + + + + + +
itemdescription
parame: direction [in], error code, err::Err type
msg: direction [in], error message
+
+

C++ defination code:

+ +
void check_raise(err::Err e, const std::string &msg = "")
+
+
+

check_bool_raise

+

Check condition, if false, raise err.Exception

+ + + + + + + + + + + + + +
itemdescription
paramok: direction [in], condition, if true, do nothing, if false, raise err.Exception
msg: direction [in], error message
+
+

C++ defination code:

+ +
void check_bool_raise(bool ok, const std::string &msg = "")
+
+
+

check_null_raise

+

Check NULL pointer, if NULL, raise exception

+ + + + + + + + + + + + + +
itemdescription
paramptr: direction [in], pointer
msg: direction [in], error message
+
+

C++ defination code:

+ +
void check_null_raise(void *ptr, const std::string &msg = "")
+
+
+

Class

+

Exception

+

Maix Exception

+
+

C++ defination code:

+ +
class Exception : public std::exception
+
+
+ + +
+
+
+ + +
+
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixcdk/api/maix/example.html b/maixcdk/api/maix/example.html new file mode 100644 index 00000000..b97f435e --- /dev/null +++ b/maixcdk/api/maix/example.html @@ -0,0 +1,1238 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + maix::example - MaixCDK + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

maix::example

+ +
+
+
    + +
+
+
+
+ + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

example module, this will be maix.example module in MaixPy, maix::example namespace in MaixCDK

+
+

This is maix::example module of MaixCDK.
+All of these elements are in namespace maix::example.

+

For MaixCDK developer: DO NOT edit this doc file manually, this doc is auto generated!

+
+

Module

+

No module

+

Enum

+

Kind

+

Example enum(not recommend! See Kind2)

+ + + + + + + + + + + + + +
itemdescribe
valuesKIND_NONE: Kind none, value always 0, other enum value will auto increase
KIND_DOG: Kind dog
KIND_CAT: Kind cat, value is auto generated according to KING_DOG
KIND_BIRD:
KIND_MAX: Max Kind quantity
You can get max Kind value by KIND_MAX - 1
+
+

C++ defination code:

+ +
enum Kind
+        {
+            KIND_NONE = 0, /** Kind none, value always 0, other enum value will auto increase */
+            KIND_DOG,      /** Kind dog*/
+            KIND_CAT,      // Kind cat, value is auto generated according to KING_DOG
+            KIND_BIRD,
+            KIND_MAX /* Max Kind quantity,
+                        You can get max Kind value by KIND_MAX - 1
+                     */
+        }
+
+
+

Kind2

+

Example enum class(recommend!)

+ + + + + + + + + + + + + +
itemdescribe
valuesNONE: Kind none, value always 0, other enum value will auto increase
DOG: Kind dog
CAT: Kind cat, value is auto generated according to KING_DOG
BIRD:
MAX: Max Kind quantity
You can get max Kind value by KIND_MAX - 1
+
+

C++ defination code:

+ +
enum class Kind2
+        {
+            NONE = 0, /** Kind none, value always 0, other enum value will auto increase */
+            DOG,      /** Kind dog*/
+            CAT,      // Kind cat, value is auto generated according to KING_DOG
+            BIRD,
+            MAX       /* Max Kind quantity,
+                         You can get max Kind value by KIND_MAX - 1
+                      */
+        }
+
+
+

Variable

+

var1

+

Example module variable

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
attentionIt's a copy of this variable in MaixPy,
so change it in C++ (e.g. update var in hello function) will not take effect the var inMaixPy.
So we add const for this var to avoid this mistake.
value"Sipeed"
readonlyTrue
+
+

C++ defination code:

+ +
const std::string var1 = "Sipeed"
+
+
+

list_var

+

Tensor data type size in bytes

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
attention1. DO NOT use C/C++ array directly for python API, the python wrapper not support it.
Use std::vector instead.
2. It's a copy of this variable in MaixPy,
so change it in C++ (e.g. update var in hello function) will not take effect the var inMaixPy.
So we add const for this var to avoid this mistake.
value{
0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
readonlyTrue
+
+

C++ defination code:

+ +
const std::vector<int> list_var = {
+            0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
+
+
+

test_var

+

Example module variable test_var

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
attentionIt's a copy of this variable in MaixPy, so if you change it in C++, it will not take effect in MaixPy.
And change it in MaixPy will not take effect in C++ as well !!!
If you want to use vars shared between C++ and MaixPy, you can create a class and use its member.
value100
readonlyFalse
+
+

C++ defination code:

+ +
int test_var = 100
+
+
+

Function

+

hello

+

say hello to someone

+ + + + + + + + + + + + + + + + + +
itemdescription
paramname: direction [in], name of someone, string type
returnstring type, content is hello + name
+
+

C++ defination code:

+ +
std::string hello(std::string name)
+
+
+

hello_maixcdk

+

This is an API only for MaixCDK, MaixPy can't use it.\nOnly item with maixcdk or maixpy keyword will be exported as MaixCDK API.

+
+

C++ defination code:

+ +
std::string hello_maixcdk(std::string name)
+
+
+

change_arg_name

+

Change arg name example

+ + + + + + + + + + + + + + + + + +
itemdescription
parame: Example object
returnsame as arg
+
+

C++ defination code:

+ +
example::Example *change_arg_name(example::Example *e)
+
+
+

change_arg_name2

+

Change arg name example

+ + + + + + + + + + + + + +
itemdescription
parame: Example object
+
+

C++ defination code:

+ +
void change_arg_name2(example::Example &e)
+
+
+

Class

+

Test

+

Test class

+
+

C++ defination code:

+ +
class Test
+
+
+

Test

+

Test constructor

+ + + + + + + + + + + + + + + + + +
itemdescription
typefunc
staticFalse
+
+

C++ defination code:

+ +
Test()
+
+
+

Example

+

Example class\nthis class will be export to MaixPy as maix.example.Example

+
+

C++ defination code:

+ +
class Example
+
+
+

Example

+

Example constructor\nthis constructor will be export to MaixPy as maix.example.Example.init

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramname: direction [in], name of Example, string type
age: direction [in], age of Example, int type, default is 18, value range is [0, 100]
attentionto make auto generate code work, param Kind should with full namespace name example::Kind instead of Kind,
namespace maix can be ignored.
staticFalse
+
+

C++ defination code:

+ +
Example(std::string &name, int age = 18, example::Kind pet = example::KIND_NONE)
+
+
+

get_name

+

get name of Example\nyou can also get name by property name.

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnname of Example, string type
staticFalse
+
+

C++ defination code:

+ +
std::string get_name()
+
+
+

get_age

+

get age of Example

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnage of Example, int type, value range is [0, 100]
staticFalse
+
+

C++ defination code:

+ +
int get_age()
+
+
+

set_name

+

set name of Example

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramname: name of Example, string type
staticFalse
+
+

C++ defination code:

+ +
void set_name(std::string name)
+
+
+

set_age

+

set age of Example

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramage: age of Example, int type, value range is [0, 100]
staticFalse
+
+

C++ defination code:

+ +
void set_age(int age)
+
+
+

set_pet

+

Example enum member

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
attention
staticFalse
+
+

C++ defination code:

+ +
void set_pet(example::Kind pet)
+
+
+

get_pet

+

Example enum member

+ + + + + + + + + + + + + + + + + +
itemdescription
typefunc
staticFalse
+
+

C++ defination code:

+ +
example::Kind get_pet()
+
+
+

get_list

+

get list example

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramin: direction [in], input list, items are int type.
In MaixPy, you can pass list or tuple to this API
returnlist, items are int type, content is [1, 2, 3] + in. Alloc item, del in MaixPy will auto free memory.
staticFalse
+
+

C++ defination code:

+ +
std::vector<int> *get_list(std::vector<int> in)
+
+
+

get_dict

+

Example dict API

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramin: direction [in], input dict, key is string type, value is int type.
In MaixPy, you can pass dict to this API
returndict, key is string type, value is int type, content is {"a": 1} + in
In MaixPy, return type is dict object
staticFalse
+
+

C++ defination code:

+ +
std::map<std::string, int> get_dict(std::map<std::string, int> &in)
+
+
+

hello

+

say hello to someone

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramname: name of someone, string type
returnstring type, content is Example::hello_str + name
staticTrue
+
+

C++ defination code:

+ +
static std::string hello(std::string name)
+
+
+

hello_bytes

+

param is bytes example

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
parambytes: bytes type param
returnbytes type, return value is bytes changed value
staticTrue
+
+

C++ defination code:

+ +
static Bytes *hello_bytes(Bytes &bytes)
+
+
+

callback

+

Callback example

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramcb: callback function, param is two int type, return is int type
returnint type, return value is cb's return value.
staticTrue
+
+

C++ defination code:

+ +
static int callback(std::function<int(int, int)> cb)
+
+
+

callback2

+

Callback example

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramcb: callback function, param is a int list type and int type, return is int type
returnint type, return value is cb's return value.
staticTrue
+
+

C++ defination code:

+ +
static int callback2(std::function<int(std::vector<int>, int)> cb)
+
+
+

hello_dict

+

Dict param example

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramdict: dict type param, key is string type, value is int type
staticTrue
+
+

C++ defination code:

+ +
static std::map<std::string, int> *hello_dict(std::map<std::string, int> *dict)
+
+
+

name

+

name member of Example

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typevar
staticFalse
readonlyFalse
+
+

C++ defination code:

+ +
std::string name
+
+
+

age

+

age member of Example, value range should be [0, 100]

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typevar
staticFalse
readonlyFalse
+
+

C++ defination code:

+ +
int age
+
+
+

hello_str

+

hello_str member of Example, default value is "hello "

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typevar
staticTrue
readonlyFalse
+
+

C++ defination code:

+ +
static std::string hello_str
+
+
+

var1

+

Example module readonly variable

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typevar
staticFalse
readonlyTrue
+
+

C++ defination code:

+ +
const std::string var1 = "Example.var1"
+
+
+

var2

+

Example module readonly variable

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typevar
staticFalse
readonlyTrue
+
+

C++ defination code:

+ +
std::string var2 = "Example.var2"
+
+
+

dict_test

+

dict_test, return dict type, and element is pointer type(alloc in C++).\nHere when the returned Tensor object will auto delete by Python GC.

+ + + + + + + + + + + + + + + + + +
itemdescription
typefunc
staticTrue
+
+

C++ defination code:

+ +
static std::map<std::string, example::Test *> *dict_test()
+
+
+ + +
+
+
+ + +
+
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixcdk/api/maix/ext_dev.html b/maixcdk/api/maix/ext_dev.html new file mode 100644 index 00000000..f5c43b64 --- /dev/null +++ b/maixcdk/api/maix/ext_dev.html @@ -0,0 +1,382 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + maix::ext_dev - MaixCDK + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

maix::ext_dev

+ +
+
+
    + +
+
+
+
+ + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

maix.ext_dev module

+
+

This is maix::ext_dev module of MaixCDK.
+All of these elements are in namespace maix::ext_dev.

+

For MaixCDK developer: DO NOT edit this doc file manually, this doc is auto generated!

+
+

Module

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
modulebrief
tmc2209maix.ext_dev.tmc2209 module
bm8563maix.ext_dev.bm8563 module
qmi8658maix.ext_dev.qmi8658 module
mlx90640maix.ext_dev.mlx90640 module
fp5510maix.ext_dev.fp5510 module
imumaix.ext_dev.imu module
pmumaix.ext_dev.pmu module
axp2101maix.ext_dev.axp2101 module
+

Enum

+

Variable

+

Function

+

Class

+ + +
+
+
+ + +
+
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixcdk/api/maix/ext_dev/axp2101.html b/maixcdk/api/maix/ext_dev/axp2101.html new file mode 100644 index 00000000..422c036c --- /dev/null +++ b/maixcdk/api/maix/ext_dev/axp2101.html @@ -0,0 +1,1374 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + maix::ext_dev::axp2101 - MaixCDK + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

maix::ext_dev::axp2101

+ +
+
+
    + +
+
+
+
+ + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

maix.ext_dev.axp2101 module

+
+

This is maix::ext_dev::axp2101 module of MaixCDK.
+All of these elements are in namespace maix::ext_dev::axp2101.

+

For MaixCDK developer: DO NOT edit this doc file manually, this doc is auto generated!

+
+

Module

+

No module

+

Enum

+

ChargerStatus

+

charger status

+ + + + + + + + + + + + + +
itemdescribe
valuesCHG_TRI_STATE: tri_charge
CHG_PRE_STATE: pre_charge
CHG_CC_STATE: constant charge
CHG_CV_STATE: constant voltage
CHG_DONE_STATE: charge done
CHG_STOP_STATE: not charge
+
+

C++ defination code:

+ +
enum class ChargerStatus {
+        CHG_TRI_STATE,   //tri_charge
+        CHG_PRE_STATE,   //pre_charge
+        CHG_CC_STATE,    //constant charge
+        CHG_CV_STATE,    //constant voltage
+        CHG_DONE_STATE,  //charge done
+        CHG_STOP_STATE,  //not charge
+    }
+
+
+

ChargerCurrent

+

charger current

+ + + + + + + + + + + + + +
itemdescribe
valuesCHG_CUR_0MA:
CHG_CUR_100MA:
CHG_CUR_125MA:
CHG_CUR_150MA:
CHG_CUR_175MA:
CHG_CUR_200MA:
CHG_CUR_300MA:
CHG_CUR_400MA:
CHG_CUR_500MA:
CHG_CUR_600MA:
CHG_CUR_700MA:
CHG_CUR_800MA:
CHG_CUR_900MA:
CHG_CUR_1000MA:
+
+

C++ defination code:

+ +
enum class ChargerCurrent {
+        CHG_CUR_0MA,
+        CHG_CUR_100MA = 4,
+        CHG_CUR_125MA,
+        CHG_CUR_150MA,
+        CHG_CUR_175MA,
+        CHG_CUR_200MA,
+        CHG_CUR_300MA,
+        CHG_CUR_400MA,
+        CHG_CUR_500MA,
+        CHG_CUR_600MA,
+        CHG_CUR_700MA,
+        CHG_CUR_800MA,
+        CHG_CUR_900MA,
+        CHG_CUR_1000MA,
+    }
+
+
+

PowerChannel

+

power channel

+ + + + + + + + + + + + + +
itemdescribe
valuesDCDC1:
DCDC2:
DCDC3:
DCDC4:
DCDC5:
ALDO1:
ALDO2:
ALDO3:
ALDO4:
BLDO1:
BLDO2:
DLDO1:
DLDO2:
VBACKUP:
CPULDO:
+
+

C++ defination code:

+ +
enum class PowerChannel {
+        DCDC1,
+        DCDC2,
+        DCDC3,
+        DCDC4,
+        DCDC5,
+        ALDO1,
+        ALDO2,
+        ALDO3,
+        ALDO4,
+        BLDO1,
+        BLDO2,
+        DLDO1,
+        DLDO2,
+        VBACKUP,
+        CPULDO,
+    }
+
+
+

PowerOffTime

+

power off time

+ + + + + + + + + + + + + +
itemdescribe
valuesPOWEROFF_4S:
POWEROFF_6S:
POWEROFF_8S:
POWEROFF_10S:
POWEROFF_DISABLE:
+
+

C++ defination code:

+ +
enum class PowerOffTime {
+        POWEROFF_4S,
+        POWEROFF_6S,
+        POWEROFF_8S,
+        POWEROFF_10S,
+        POWEROFF_DISABLE = 65535,
+    }
+
+
+

PowerOnTime

+

power on time

+ + + + + + + + + + + + + +
itemdescribe
valuesPOWERON_128MS:
POWERON_512MS:
POWERON_1S:
POWERON_2S:
+
+

C++ defination code:

+ +
enum class PowerOnTime {
+        POWERON_128MS,
+        POWERON_512MS,
+        POWERON_1S,
+        POWERON_2S,
+    }
+
+
+

Variable

+

Function

+

Class

+

AXP2101

+

Peripheral AXP2101 class

+
+

C++ defination code:

+ +
class AXP2101
+
+
+

__init__

+

AXP2101 constructor.

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
parami2c_bus: i2c bus number.
addr: pmu device addr.
staticFalse
+
+

C++ defination code:

+ +
AXP2101(int i2c_bus = -1, uint8_t addr = 0x34)
+
+
+

init

+

Initialise the AXP2101.

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnerr::Err type, if init success, return err::ERR_NONE.
staticFalse
+
+

C++ defination code:

+ +
err::Err init()
+
+
+

poweroff

+

Poweroff immediately.

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnerr::Err type, if init success, return err::ERR_NONE.
staticFalse
+
+

C++ defination code:

+ +
err::Err poweroff()
+
+
+

is_bat_connect

+

Is the battery connected.

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnbool type, if battery is connected, return true.
staticFalse
+
+

C++ defination code:

+ +
bool is_bat_connect()
+
+
+

is_vbus_in

+

Is the power adapter connected.

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnbool type, if power adapter is connected, return true.
staticFalse
+
+

C++ defination code:

+ +
bool is_vbus_in()
+
+
+

is_charging

+

Is bat charging.

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnbool type, if bat is charging, return true.
staticFalse
+
+

C++ defination code:

+ +
bool is_charging()
+
+
+

get_bat_percent

+

Get the battery percentage.

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnint type, return battery percentage.
staticFalse
+
+

C++ defination code:

+ +
int get_bat_percent()
+
+
+

get_charger_status

+

Get the battery charging status.

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnint type, return battery charging status.
staticFalse
+
+

C++ defination code:

+ +
ext_dev::axp2101::ChargerStatus get_charger_status()
+
+
+

get_charger_status (overload 1)

+

Get the battery voltage.

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnuint16_t type, return battery voltage.
staticFalse
+
+

C++ defination code:

+ +
uint16_t get_bat_vol()
+
+
+

clean_irq

+

Clear interrupt flag.

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnerr::Err type, if clean success, return err::ERR_NONE.
staticFalse
+
+

C++ defination code:

+ +
err::Err clean_irq()
+
+
+

set_bat_charging_cur

+

Set the battery charging current.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramcurrent: The current to be set.
The available values are 0mA, 100mA, 125mA, 150mA, 175mA,
200mA, 300mA, 400mA, 500mA, 600mA, 700mA, 800mA, 900mA, and 1000mA.
returnerr::Err type, if set success, return err::ERR_NONE.
staticFalse
+
+

C++ defination code:

+ +
err::Err set_bat_charging_cur(ext_dev::axp2101::ChargerCurrent current)
+
+
+

get_bat_charging_cur

+

Get the battery charging current.

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnChargerCurrent, return the currently set charging current.
staticFalse
+
+

C++ defination code:

+ +
ext_dev::axp2101::ChargerCurrent get_bat_charging_cur()
+
+
+

dcdc1

+

Set and get the PMU DCDC1 voltage.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramvoltage: The voltage to be set,
voltage range is 1500mV~3400mV(step 20mV).
returnint, return the PMU DCDC1 voltage.
staticFalse
+
+

C++ defination code:

+ +
int dcdc1(int voltage = -1)
+
+
+

dcdc2

+

Set and get the PMU DCDC2 voltage.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramvoltage: The voltage to be set,
voltage range is 500mV~1200mV(step 10mV) and 1220mV~1540mV(step 20mV).
returnint, return the PMU DCDC2 voltage.
staticFalse
+
+

C++ defination code:

+ +
int dcdc2(int voltage = -1)
+
+
+

dcdc3

+

Set and get the PMU DCDC3 voltage.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramvoltage: The voltage to be set,
voltage range is 500mV~1200mV(step 10mV) and 1220mV~1540mV(step 20mV).
returnint, return the PMU DCDC3 voltage.
staticFalse
+
+

C++ defination code:

+ +
int dcdc3(int voltage = -1)
+
+
+

dcdc4

+

Set and get the PMU DCDC4 voltage.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramvoltage: The voltage to be set,
voltage range is 500mV~1200mV(step 10mV) and 1220mV~1840mV(step 20mV).
returnint, return the PMU DCDC4 voltage.
staticFalse
+
+

C++ defination code:

+ +
int dcdc4(int voltage = -1)
+
+
+

dcdc5

+

Set and get the PMU DCDC5 voltage.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramvoltage: The voltage to be set,
voltage range is 1400mV~3700mV(step 100mV).
returnint, return the PMU DCDC5 voltage.
staticFalse
+
+

C++ defination code:

+ +
int dcdc5(int voltage = -1)
+
+
+

aldo1

+

Set and get the PMU ALDO1 voltage.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramvoltage: The voltage to be set,
voltage range is 500mV~3500mV(step 100mV).
returnint, return the PMU ALDO1 voltage.
staticFalse
+
+

C++ defination code:

+ +
int aldo1(int voltage = -1)
+
+
+

aldo2

+

Set and get the PMU ALDO2 voltage.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramvoltage: The voltage to be set,
voltage range is 500mV~3500mV(step 100mV).
returnint, return the PMU ALDO2 voltage.
staticFalse
+
+

C++ defination code:

+ +
int aldo2(int voltage = -1)
+
+
+

aldo3

+

Set and get the PMU ALDO3 voltage.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramvoltage: The voltage to be set,
voltage range is 500mV~3500mV(step 100mV).
returnint, return the PMU ALDO3 voltage.
staticFalse
+
+

C++ defination code:

+ +
int aldo3(int voltage = -1)
+
+
+

aldo4

+

Set and get the PMU ALDO4 voltage.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramvoltage: The voltage to be set,
voltage range is 500mV~3500mV(step 100mV).
returnint, return the PMU ALDO4 voltage.
staticFalse
+
+

C++ defination code:

+ +
int aldo4(int voltage = -1)
+
+
+

bldo1

+

Set and get the PMU BLDO1 voltage.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramvoltage: The voltage to be set,
voltage range is 500mV~3500mV(step 100mV).
returnint, return the PMU BLDO1 voltage.
staticFalse
+
+

C++ defination code:

+ +
int bldo1(int voltage = -1)
+
+
+

bldo2

+

Set and get the PMU BLDO2 voltage.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramvoltage: The voltage to be set,
voltage range is 500mV~3500mV(step 100mV).
returnint, return the PMU BLDO2 voltage.
staticFalse
+
+

C++ defination code:

+ +
int bldo2(int voltage = -1)
+
+
+

set_poweroff_time

+

Set power-off time, The device will shut down\nif the power button is held down longer than this time.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramtm: The time to be set, you can set it to 4s, 6s, 8s, or 10s.
returnerr::Err type, if set success, return err::ERR_NONE.
staticFalse
+
+

C++ defination code:

+ +
err::Err set_poweroff_time(ext_dev::axp2101::PowerOffTime tm)
+
+
+

get_poweroff_time

+

Get power-off time.

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnPowerOffTime, return power-off time.
staticFalse
+
+

C++ defination code:

+ +
ext_dev::axp2101::PowerOffTime get_poweroff_time()
+
+
+

set_poweron_time

+

Set power-on time, The device will power on\nif the power button is held down longer than this time.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramtm: The time to be set, you can set it to 128ms, 512ms, 1s, or 2s.
returnerr::Err type, if set success, return err::ERR_NONE.
staticFalse
+
+

C++ defination code:

+ +
err::Err set_poweron_time(ext_dev::axp2101::PowerOnTime tm)
+
+
+

get_poweron_time

+

Get power-on time.

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnPowerOnTime, return power-on time.
staticFalse
+
+

C++ defination code:

+ +
ext_dev::axp2101::PowerOnTime get_poweron_time()
+
+
+ + +
+
+
+ + +
+
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixcdk/api/maix/ext_dev/bm8563.html b/maixcdk/api/maix/ext_dev/bm8563.html new file mode 100644 index 00000000..09f6168e --- /dev/null +++ b/maixcdk/api/maix/ext_dev/bm8563.html @@ -0,0 +1,567 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + maix::ext_dev::bm8563 - MaixCDK + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

maix::ext_dev::bm8563

+ +
+
+
    + +
+
+
+
+ + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

maix.ext_dev.bm8563 module

+
+

This is maix::ext_dev::bm8563 module of MaixCDK.
+All of these elements are in namespace maix::ext_dev::bm8563.

+

For MaixCDK developer: DO NOT edit this doc file manually, this doc is auto generated!

+
+

Module

+

No module

+

Enum

+

Variable

+

Function

+

Class

+

BM8563

+

Peripheral BM8563 class

+
+

C++ defination code:

+ +
class BM8563
+
+
+

__init__

+

BM8563 constructor

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
parami2c_bus: i2c bus number.
staticFalse
+
+

C++ defination code:

+ +
BM8563(int i2c_bus=-1)
+
+
+

datetime

+

Get or set the date and time of the BM8563.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramtimetuple: time tuple, like (year, month, day[, hour[, minute[, second]]])
returntime tuple, like (year, month, day[, hour[, minute[, second]]])
staticFalse
+
+

C++ defination code:

+ +
std::vector<int> datetime(std::vector<int> timetuple=std::vector<int>())
+
+
+

init

+

Initialise the BM8563.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramtimetuple: time tuple, like (year, month, day[, hour[, minute[, second]]])
returnerr::Err type, if init success, return err::ERR_NONE
staticFalse
+
+

C++ defination code:

+ +
err::Err init(std::vector<int> timetuple)
+
+
+

now

+

Get get the current datetime.

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returntime tuple, like (year, month, day[, hour[, minute[, second]]])
staticFalse
+
+

C++ defination code:

+ +
std::vector<int> now()
+
+
+

deinit

+

Deinit the BM8563.

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnerr::Err err::Err type, if deinit success, return err::ERR_NONE
staticFalse
+
+

C++ defination code:

+ +
err::Err deinit()
+
+
+

hctosys

+

Set the system time from the BM8563

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnerr::Err type
staticFalse
+
+

C++ defination code:

+ +
err::Err hctosys()
+
+
+

systohc

+

Set the BM8563 from the system time

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnerr::Err type
staticFalse
+
+

C++ defination code:

+ +
err::Err systohc()
+
+
+ + +
+
+
+ + +
+
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixcdk/api/maix/ext_dev/fp5510.html b/maixcdk/api/maix/ext_dev/fp5510.html new file mode 100644 index 00000000..7ef91022 --- /dev/null +++ b/maixcdk/api/maix/ext_dev/fp5510.html @@ -0,0 +1,439 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + maix::ext_dev::fp5510 - MaixCDK + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

maix::ext_dev::fp5510

+ +
+
+
    + +
+
+
+
+ + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

maix.ext_dev.fp5510 module

+
+

This is maix::ext_dev::fp5510 module of MaixCDK.
+All of these elements are in namespace maix::ext_dev::fp5510.

+

For MaixCDK developer: DO NOT edit this doc file manually, this doc is auto generated!

+
+

Module

+

No module

+

Enum

+

Variable

+

Function

+

Class

+

FP5510

+

FP5510 class

+
+

C++ defination code:

+ +
class FP5510
+
+
+

__init__

+

Construct a new FP5510 object

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramid: iic number, default is 4
slave_addr: slave address of fp5510, default is 0x0c.
freq: iic frequency, default is 400k
staticFalse
+
+

C++ defination code:

+ +
FP5510(int id = 4, int slave_addr = 0x0c, int freq = 400000)
+
+
+

set_pos

+

Set fp5510 position

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
parampos: the position of fp5510, range is [0, 1023]
staticFalse
+
+

C++ defination code:

+ +
void set_pos(uint32_t pos)
+
+
+

get_pos

+

Get fp5510 position

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnreturns the position of fp5510, range is [0, 1023]
staticFalse
+
+

C++ defination code:

+ +
uint32_t get_pos()
+
+
+ + +
+
+
+ + +
+
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixcdk/api/maix/ext_dev/imu.html b/maixcdk/api/maix/ext_dev/imu.html new file mode 100644 index 00000000..c56a7aa6 --- /dev/null +++ b/maixcdk/api/maix/ext_dev/imu.html @@ -0,0 +1,789 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + maix::ext_dev::imu - MaixCDK + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

maix::ext_dev::imu

+ +
+
+
    + +
+
+
+
+ + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

maix.ext_dev.imu module

+
+

This is maix::ext_dev::imu module of MaixCDK.
+All of these elements are in namespace maix::ext_dev::imu.

+

For MaixCDK developer: DO NOT edit this doc file manually, this doc is auto generated!

+
+

Module

+

No module

+

Enum

+

Mode

+

imu mode

+ + + + + + + + + + + + + +
itemdescribe
valuesACC_ONLY:
GYRO_ONLY:
DUAL:
+
+

C++ defination code:

+ +
enum class Mode {
+    ACC_ONLY = 0,
+    GYRO_ONLY,
+    DUAL
+}
+
+
+

AccScale

+

imu acc scale

+ + + + + + + + + + + + + +
itemdescribe
valuesACC_SCALE_2G:
ACC_SCALE_4G:
ACC_SCALE_8G:
ACC_SCALE_16G:
+
+

C++ defination code:

+ +
enum class AccScale {
+    ACC_SCALE_2G = 0,
+    ACC_SCALE_4G,
+    ACC_SCALE_8G,
+    ACC_SCALE_16G
+}
+
+
+

AccOdr

+

imu acc output data rate

+ + + + + + + + + + + + + +
itemdescribe
valuesACC_ODR_8000: Accelerometer ODR set to 8000 Hz.
ACC_ODR_4000: Accelerometer ODR set to 4000 Hz.
ACC_ODR_2000: Accelerometer ODR set to 2000 Hz.
ACC_ODR_1000: Accelerometer ODR set to 1000 Hz.
ACC_ODR_500: Accelerometer ODR set to 500 Hz.
ACC_ODR_250: Accelerometer ODR set to 250 Hz.
ACC_ODR_125: Accelerometer ODR set to 125 Hz.
ACC_ODR_62_5: Accelerometer ODR set to 62.5 Hz.
ACC_ODR_31_25: Accelerometer ODR set to 31.25 Hz.
ACC_ODR_128: Accelerometer ODR set to 128 Hz.
ACC_ODR_21: Accelerometer ODR set to 21 Hz.
ACC_ODR_11: Accelerometer ODR set to 11 Hz.
ACC_ODR_3: Accelerometer ODR set to 3 Hz.
+
+

C++ defination code:

+ +
enum class AccOdr {
+    ACC_ODR_8000,      // Accelerometer ODR set to 8000 Hz.
+    ACC_ODR_4000,      // Accelerometer ODR set to 4000 Hz.
+    ACC_ODR_2000,      // Accelerometer ODR set to 2000 Hz.
+    ACC_ODR_1000,      // Accelerometer ODR set to 1000 Hz.
+    ACC_ODR_500,       // Accelerometer ODR set to 500 Hz.
+    ACC_ODR_250,       // Accelerometer ODR set to 250 Hz.
+    ACC_ODR_125,       // Accelerometer ODR set to 125 Hz.
+    ACC_ODR_62_5,      // Accelerometer ODR set to 62.5 Hz.
+    ACC_ODR_31_25,     // Accelerometer ODR set to 31.25 Hz.
+    ACC_ODR_128 = 12,  // Accelerometer ODR set to 128 Hz.
+    ACC_ODR_21,        // Accelerometer ODR set to 21 Hz.
+    ACC_ODR_11,        // Accelerometer ODR set to 11 Hz.
+    ACC_ODR_3,         // Accelerometer ODR set to 3 Hz.
+}
+
+
+

GyroScale

+

imu gyro scale

+ + + + + + + + + + + + + +
itemdescribe
valuesGYRO_SCALE_16DPS: Gyroscope scale set to ±16 degrees per second.
GYRO_SCALE_32DPS: Gyroscope scale set to ±32 degrees per second.
GYRO_SCALE_64DPS: Gyroscope scale set to ±64 degrees per second.
GYRO_SCALE_128DPS: Gyroscope scale set to ±128 degrees per second.
GYRO_SCALE_256DPS: Gyroscope scale set to ±256 degrees per second.
GYRO_SCALE_512DPS: Gyroscope scale set to ±512 degrees per second.
GYRO_SCALE_1024DPS: Gyroscope scale set to ±1024 degrees per second.
GYRO_SCALE_2048DPS: Gyroscope scale set to ±2048 degrees per second.
+
+

C++ defination code:

+ +
enum class GyroScale {
+    GYRO_SCALE_16DPS = 0,       // Gyroscope scale set to ±16 degrees per second.
+    GYRO_SCALE_32DPS,            // Gyroscope scale set to ±32 degrees per second.
+    GYRO_SCALE_64DPS,            // Gyroscope scale set to ±64 degrees per second.
+    GYRO_SCALE_128DPS,           // Gyroscope scale set to ±128 degrees per second.
+    GYRO_SCALE_256DPS,           // Gyroscope scale set to ±256 degrees per second.
+    GYRO_SCALE_512DPS,           // Gyroscope scale set to ±512 degrees per second.
+    GYRO_SCALE_1024DPS,          // Gyroscope scale set to ±1024 degrees per second.
+    GYRO_SCALE_2048DPS,          // Gyroscope scale set to ±2048 degrees per second.
+}
+
+
+

GyroOdr

+

imu gyro output data rate

+ + + + + + + + + + + + + +
itemdescribe
valuesGYRO_ODR_8000: Gyroscope ODR set to 8000 Hz.
GYRO_ODR_4000: Gyroscope ODR set to 4000 Hz.
GYRO_ODR_2000: Gyroscope ODR set to 2000 Hz.
GYRO_ODR_1000: Gyroscope ODR set to 1000 Hz.
GYRO_ODR_500: Gyroscope ODR set to 500 Hz.
GYRO_ODR_250: Gyroscope ODR set to 250 Hz.
GYRO_ODR_125: Gyroscope ODR set to 125 Hz.
GYRO_ODR_62_5: Gyroscope ODR set to 62.5 Hz.
GYRO_ODR_31_25: Gyroscope ODR set to 31.25 Hz.
+
+

C++ defination code:

+ +
enum class GyroOdr {
+    GYRO_ODR_8000,     // Gyroscope ODR set to 8000 Hz.
+    GYRO_ODR_4000,     // Gyroscope ODR set to 4000 Hz.
+    GYRO_ODR_2000,     // Gyroscope ODR set to 2000 Hz.
+    GYRO_ODR_1000,     // Gyroscope ODR set to 1000 Hz.
+    GYRO_ODR_500,      // Gyroscope ODR set to 500 Hz.
+    GYRO_ODR_250,      // Gyroscope ODR set to 250 Hz.
+    GYRO_ODR_125,      // Gyroscope ODR set to 125 Hz.
+    GYRO_ODR_62_5,     // Gyroscope ODR set to 62.5 Hz.
+    GYRO_ODR_31_25,    // Gyroscope ODR set to 31.25 Hz.
+}
+
+
+

Variable

+

Function

+

Class

+

IMU

+

QMI8656 driver class

+
+

C++ defination code:

+ +
class IMU
+
+
+

__init__

+

Construct a new IMU object, will open IMU

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramdriver: driver name, only support "qmi8656"
i2c_bus: i2c bus number. Automatically selects the on-board imu when -1 is passed in.
addr: IMU i2c addr.
freq: IMU freq
mode: IMU Mode: ACC_ONLY/GYRO_ONLY/DUAL
acc_scale: acc scale, see @imu::AccScale
acc_odr: acc output data rate, see @imu::AccOdr
gyro_scale: gyro scale, see @imu::GyroScale
gyro_odr: gyro output data rate, see @imu::GyroOdr
block: block or non-block, defalut is true
staticFalse
+
+

C++ defination code:

+ +
IMU(std::string driver, int i2c_bus=-1, int addr=0x6B, int freq=400000,
+            maix::ext_dev::imu::Mode mode=maix::ext_dev::imu::Mode::DUAL,
+            maix::ext_dev::imu::AccScale acc_scale=maix::ext_dev::imu::AccScale::ACC_SCALE_2G,
+            maix::ext_dev::imu::AccOdr acc_odr=maix::ext_dev::imu::AccOdr::ACC_ODR_8000,
+            maix::ext_dev::imu::GyroScale gyro_scale=maix::ext_dev::imu::GyroScale::GYRO_SCALE_16DPS,
+            maix::ext_dev::imu::GyroOdr gyro_odr=maix::ext_dev::imu::GyroOdr::GYRO_ODR_8000,
+            bool block=true)
+
+
+

read

+

Read data from IMU.

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnlist type. If only one of the outputs is initialized, only [x,y,z] of that output will be returned.
If all outputs are initialized, [acc_x, acc_y, acc_z, gyro_x, gyro_y, gyro_z] is returned.
staticFalse
+
+

C++ defination code:

+ +
std::vector<float> read()
+
+
+

calculate_calibration

+

Caculate calibration, save calibration data to /maixapp/shart/imu_calibration

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramtime_ms: caculate max time, unit:ms
returnerr::Err
staticFalse
+
+

C++ defination code:

+ +
err::Err calculate_calibration(uint64_t time_ms = 30 * 1000)
+
+
+

get_calibration

+

Get calibration data

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnreturn an array, format is [acc_x_bias, acc_y_bias, acc_z_bias, gyro_x_bias, gyro_y_bias, gyro_z_bias]
If the calibration file cannot be found, an empty array will be returned.
staticFalse
+
+

C++ defination code:

+ +
std::vector<double> get_calibration()
+
+
+

Gcsv

+

Gcsv class

+
+

C++ defination code:

+ +
class Gcsv
+
+
+

__init__

+

Construct a new IMU object

+ + + + + + + + + + + + + + + + + +
itemdescription
typefunc
staticFalse
+
+

C++ defination code:

+ +
Gcsv()
+
+
+

open

+

Open a file

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
parampath: the path where data will be saved
tscale: time scale, default is 0.001
gscale: gyroscope scale factor, default is 1, unit:g
ascale: accelerometer scale factor, default is 1, unit:radians/second
mscale: magnetometer scale factor, default is 1(unused)
version: version number, default is "1.3"
id: identifier for the IMU, default is "imu"
orientation: sensor orientation, default is "YxZ"
returnerror code
staticFalse
+
+

C++ defination code:

+ +
err::Err open(std::string path, double tscale = 0.001, double gscale = 1, double ascale = 1, double mscale = 1, std::string version = "1.3", std::string id = "imu", std::string orientation = "YxZ")
+
+
+

close

+

Close file

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnerror code
staticFalse
+
+

C++ defination code:

+ +
err::Err close()
+
+
+

is_opened

+

Check if the object is already open

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returntrue, opened; false, not opened
staticFalse
+
+

C++ defination code:

+ +
bool is_opened()
+
+
+

write

+

Write imu data to gcsv file

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramt: Timestamp of the current data. The actual value is equal to t * tscale. unit:s
gyro: Gyroscope data must be an array consisting of x, y, and z-axis data. The actual value is equal to gyro * gscale. unit:g
acc: Acceleration data must be an array consisting of x, y, and z-axis data. The actual value is equal to acc * ascale.unit:radians/second
mag: Magnetic data must be an array consisting of x, y, and z-axis data. Currently not supported.
staticFalse
+
+

C++ defination code:

+ +
err::Err write(double timestamp, std::vector<double> gyro, std::vector<double> acc, std::vector<double> mag = std::vector<double>())
+
+
+ + +
+
+
+ + +
+
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixcdk/api/maix/ext_dev/mlx90640.html b/maixcdk/api/maix/ext_dev/mlx90640.html new file mode 100644 index 00000000..5d5d99f5 --- /dev/null +++ b/maixcdk/api/maix/ext_dev/mlx90640.html @@ -0,0 +1,1160 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + maix::ext_dev::mlx90640 - MaixCDK + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

maix::ext_dev::mlx90640

+ +
+
+
    + +
+
+
+
+ + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

maix.ext_dev.mlx90640 module

+
+

This is maix::ext_dev::mlx90640 module of MaixCDK.
+All of these elements are in namespace maix::ext_dev::mlx90640.

+

For MaixCDK developer: DO NOT edit this doc file manually, this doc is auto generated!

+
+

Module

+

No module

+

Enum

+

Cmap

+

Cmap

+ + + + + + + + + + + + + +
itemdescribe
valuesWHITE_HOT:
BLACK_HOT:
IRONBOW:
NIGHT:
RED_HOT:
WHITE_HOT_SD:
BLACK_HOT_SD:
RED_HOT_SD:
+
+

C++ defination code:

+ +
enum class Cmap : uint8_t {
+    WHITE_HOT = 0,
+    BLACK_HOT,
+    IRONBOW,
+    NIGHT,
+    RED_HOT,
+    WHITE_HOT_SD,
+    BLACK_HOT_SD,
+    RED_HOT_SD
+}
+
+
+

FPS

+

MLX90640 FPS

+ + + + + + + + + + + + + +
itemdescribe
valuesFPS_1:
FPS_2:
FPS_4:
FPS_8:
FPS_16:
FPS_32:
FPS_64:
+
+

C++ defination code:

+ +
enum class FPS : uint8_t {
+    FPS_1   = 0b001,
+    FPS_2   = 0b010,
+    FPS_4   = 0b011,
+    FPS_8   = 0b100,
+    FPS_16  = 0b101,
+    FPS_32  = 0b110,
+    FPS_64  = 0b111,
+}
+
+
+

Variable

+

MLX_W

+

MLX90640 Image Width.

+ + + + + + + + + + + + + + + + + +
itemdescription
value32
readonlyTrue
+
+

C++ defination code:

+ +
constexpr uint32_t MLX_W = 32
+
+
+

MLX_H

+

MLX90640 Image Height.

+ + + + + + + + + + + + + + + + + +
itemdescription
value24
readonlyTrue
+
+

C++ defination code:

+ +
constexpr uint32_t MLX_H = 24
+
+
+

Function

+

to_kmatrix

+

CMatrix to KMatrix.

+ + + + + + + + + + + + + + + + + +
itemdescription
parammatrix: CMatrix type.
returnKMatrix
+
+

C++ defination code:

+ +
KMatrix to_kmatrix(const CMatrix& matrix)
+
+
+

to_cmatrix

+

KMatrix to CMatrix

+ + + + + + + + + + + + + + + + + +
itemdescription
parammatrix: KMatrix type.
returnCMatrix
+
+

C++ defination code:

+ +
CMatrix to_cmatrix(const KMatrix& matrix)
+
+
+

Class

+

MLX90640Celsius

+

MLX90640 (℃)

+
+

C++ defination code:

+ +
class MLX90640Celsius final
+
+
+

__init__

+

Construct a new MLX90640Celsius object\nThis constructor initializes an MLX90640Celsius object with the specified parameters\nto configure the I2C bus communication, frame rate, color mapping, temperature ranges,\nand emissivity for the MLX90640 thermal camera.

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
parami2c_bus_num: The I2C bus number to which the MLX90640 is connected.
fps: The preferred frame rate for the MLX90640, default is FPS::FPS_32.
cmap: The color mapping to be used for generating the pseudo color image, default is Cmap::WHITE_HOT.
temp_min: The minimum reference temperature (in °C) for generating the pseudo color image. Default is -1.
temp_max: The maximum reference temperature (in °C) for generating the pseudo color image. Default is -1.
If both max and min are equal, it operates in auto mode:
the maximum temperature in the frame is taken as the maximum reference temperature,
and the minimum temperature in the frame is taken as the minimum reference temperature.
emissivity: The emissivity parameter for the MLX90640, default is 0.95.
staticFalse
+
+

C++ defination code:

+ +
MLX90640Celsius(int i2c_bus_num,
+                    ::maix::ext_dev::mlx90640::FPS fps=::maix::ext_dev::mlx90640::FPS::FPS_32,
+                    ::maix::ext_dev::mlx90640::Cmap cmap=::maix::ext_dev::mlx90640::Cmap::WHITE_HOT,
+                    float temp_min=-1, float temp_max=-1, float emissivity=0.95)
+
+
+

matrix

+

Retrieves sensor data and returns a temperature matrix of size MLX_H * MLX_W\nMLX_W: 32\n---------------\n|\nMLX_H |\n: 24 |\nThe matrix structure is represented as list[MLX_H][MLX_W],\nwhere MLX_H is the number of rows (24) and MLX_W is the number of columns (32).

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnCMatrix containing the temperature data, or an empty matrix ([]) if the operation fails.
staticFalse
+
+

C++ defination code:

+ +
CMatrix matrix()
+
+
+

image

+

Obtains sensor data and converts it into a pseudo-color image\nThis function retrieves the thermal data from the sensor and processes it\nto generate a pseudo-color representation of the temperature distribution.

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnmaix::image::Image* A raw pointer to a maix image object.
It is the responsibility of the caller to free this memory
in C/C++ to prevent memory leaks.
staticFalse
+
+

C++ defination code:

+ +
::maix::image::Image* image()
+
+
+

min_temp_point

+

Finds the pixel with the minimum temperature from the most recent reading\nThis function identifies the pixel with the minimum temperature\nfrom the latest data obtained from the sensor.

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnPoint A tuple of type <int, int, float>, representing
(x, y, temperature) of the pixel with the minimum temperature.
If the operation fails, the return values will be x, y < 0.
staticFalse
+
+

C++ defination code:

+ +
Point min_temp_point()
+
+
+

max_temp_point

+

Finds the pixel with the maximum temperature from the most recent reading\nThis function identifies the pixel with the maximum temperature\nfrom the latest data obtained from the sensor.

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnPoint A tuple of type <int, int, float>, representing
(x, y, temperature) of the pixel with the maximum temperature.
If the operation fails, the return values will be x, y < 0.
staticFalse
+
+

C++ defination code:

+ +
Point max_temp_point()
+
+
+

center_point

+

Finds the center pixel from the most recent reading\nThis function determines the center pixel of the temperature matrix\nbased on the most recent data obtained from the sensor.

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnPoint A tuple of type <int, int, float>, representing
(x, y, temperature) of the center pixel in the temperature matrix.
If the operation fails, the return values will be x, y < 0.
staticFalse
+
+

C++ defination code:

+ +
Point center_point()
+
+
+

image_from

+

Converts a given matrix of temperature data into an image\nThis function takes a temperature matrix and generates\na corresponding image representation based on the\nconfigured color map and other parameters.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
parammatrix: The temperature matrix to be converted.
returnmaix::image::Image* A pointer to the generated image.
It is the responsibility of the caller to free this memory
in C/C++ to prevent memory leaks.
staticFalse
+
+

C++ defination code:

+ +
::maix::image::Image* image_from(const CMatrix& matrix)
+
+
+

max_temp_point_from

+

Finds the pixel with the maximum temperature from the given matrix\nThis static function identifies the pixel with the maximum temperature\nfrom the specified temperature matrix.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
parammatrix: The temperature matrix to be analyzed.
returnPoint A tuple of type <int, int, float>, representing
(x, y, temperature) of the pixel with the maximum temperature.
If the operation fails, the return values will be x, y < 0.
staticTrue
+
+

C++ defination code:

+ +
static Point max_temp_point_from(const CMatrix& matrix)
+
+
+

min_temp_point_from

+

Finds the pixel with the minimum temperature from the given matrix\nThis static function identifies the pixel with the minimum temperature\nfrom the specified temperature matrix.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
parammatrix: The temperature matrix to be analyzed.
returnPoint A tuple of type <int, int, float>, representing
(x, y, temperature) of the pixel with the minimum temperature.
If the operation fails, the return values will be x, y < 0.
staticTrue
+
+

C++ defination code:

+ +
static Point min_temp_point_from(const CMatrix& matrix)
+
+
+

center_point_from

+

Finds the center pixel from the given matrix\nThis static function determines the center pixel of the\nspecified temperature matrix based on its dimensions.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
parammatrix: The temperature matrix to be analyzed.
returnPoint A tuple of type <int, int, float>, representing
(x, y, temperature) of the center pixel in the matrix.
If the operation fails, the return values will be x, y < 0.
staticTrue
+
+

C++ defination code:

+ +
static Point center_point_from(const CMatrix& matrix)
+
+
+

MLX90640Kelvin

+

MLX90640 (K))

+
+

C++ defination code:

+ +
class MLX90640Kelvin final
+
+
+

__init__

+

Construct a new MLX90640Kelvin object\nThis constructor initializes an MLX90640Kelvin object with the specified parameters\nto configure the I2C bus communication, frame rate, color mapping, temperature ranges,\nand emissivity for the MLX90640 thermal camera.

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
parami2c_bus_num: The I2C bus number to which the MLX90640 is connected.
fps: The preferred frame rate for the MLX90640, default is FPS::FPS_32.
cmap: The color mapping to be used for generating the pseudo color image, default is Cmap::WHITE_HOT.
temp_min: The minimum reference temperature (in K) for generating the pseudo color image. Default is -1.
temp_max: The maximum reference temperature (in K) for generating the pseudo color image. Default is -1.
If both max and min are equal, it operates in auto mode:
the maximum temperature in the frame is taken as the maximum reference temperature,
and the minimum temperature in the frame is taken as the minimum reference temperature.
emissivity: The emissivity parameter for the MLX90640, default is 0.95.
staticFalse
+
+

C++ defination code:

+ +
MLX90640Kelvin( int i2c_bus_num,
+                    ::maix::ext_dev::mlx90640::FPS fps=::maix::ext_dev::mlx90640::FPS::FPS_32,
+                    ::maix::ext_dev::mlx90640::Cmap cmap=::maix::ext_dev::mlx90640::Cmap::WHITE_HOT,
+                    float temp_min=-1, float temp_max=-1,  float emissivity=0.95)
+
+
+

matrix

+

Retrieves sensor data and returns a temperature matrix of size MLX_H * MLX_W\nMLX_W: 32\n---------------\n|\nMLX_H |\n: 24 |\nThe matrix structure is represented as list[MLX_H][MLX_W],\nwhere MLX_H is the number of rows (24) and MLX_W is the number of columns (32).

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnKMatrix containing the temperature data, or an empty matrix ([]) if the operation fails.
staticFalse
+
+

C++ defination code:

+ +
KMatrix matrix()
+
+
+

image

+

Obtains sensor data and converts it into a pseudo-color image\nThis function retrieves the thermal data from the sensor and processes it\nto generate a pseudo-color representation of the temperature distribution.

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnmaix::image::Image* A raw pointer to a maix image object.
It is the responsibility of the caller to free this memory
in C/C++ to prevent memory leaks.
staticFalse
+
+

C++ defination code:

+ +
::maix::image::Image* image()
+
+
+

max_temp_point

+

Finds the pixel with the minimum temperature from the most recent reading\nThis function identifies the pixel with the minimum temperature\nfrom the latest data obtained from the sensor.

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnPoint A tuple of type <int, int, float>, representing
(x, y, temperature) of the pixel with the minimum temperature.
If the operation fails, the return values will be x, y < 0.
staticFalse
+
+

C++ defination code:

+ +
Point max_temp_point()
+
+
+

min_temp_point

+

Finds the pixel with the maximum temperature from the most recent reading\nThis function identifies the pixel with the maximum temperature\nfrom the latest data obtained from the sensor.

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnPoint A tuple of type <int, int, float>, representing
(x, y, temperature) of the pixel with the maximum temperature.
If the operation fails, the return values will be x, y < 0.
staticFalse
+
+

C++ defination code:

+ +
Point min_temp_point()
+
+
+

center_point

+

Finds the center pixel from the most recent reading\nThis function determines the center pixel of the temperature matrix\nbased on the most recent data obtained from the sensor.

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnPoint A tuple of type <int, int, float>, representing
(x, y, temperature) of the center pixel in the temperature matrix.
If the operation fails, the return values will be x, y < 0.
staticFalse
+
+

C++ defination code:

+ +
Point center_point()
+
+
+

image_from

+

Converts a given matrix of temperature data into an image\nThis function takes a temperature matrix and generates\na corresponding image representation based on the\nconfigured color map and other parameters.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
parammatrix: The temperature matrix to be converted.
returnmaix::image::Image* A pointer to the generated image.
It is the responsibility of the caller to free this memory
in C/C++ to prevent memory leaks.
staticFalse
+
+

C++ defination code:

+ +
::maix::image::Image* image_from(const KMatrix& matrix)
+
+
+

max_temp_point_from

+

Finds the pixel with the maximum temperature from the given matrix\nThis static function identifies the pixel with the maximum temperature\nfrom the specified temperature matrix.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
parammatrix: The temperature matrix to be analyzed.
returnPoint A tuple of type <int, int, float>, representing
(x, y, temperature) of the pixel with the maximum temperature.
If the operation fails, the return values will be x, y < 0.
staticTrue
+
+

C++ defination code:

+ +
static Point max_temp_point_from(const KMatrix& matrix)
+
+
+

min_temp_point_from

+

Finds the pixel with the minimum temperature from the given matrix\nThis static function identifies the pixel with the minimum temperature\nfrom the specified temperature matrix.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
parammatrix: The temperature matrix to be analyzed.
returnPoint A tuple of type <int, int, float>, representing
(x, y, temperature) of the pixel with the minimum temperature.
If the operation fails, the return values will be x, y < 0.
staticTrue
+
+

C++ defination code:

+ +
static Point min_temp_point_from(const KMatrix& matrix)
+
+
+

center_point_from

+

Finds the center pixel from the given matrix\nThis static function determines the center pixel of the\nspecified temperature matrix based on its dimensions.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
parammatrix: The temperature matrix to be analyzed.
returnPoint A tuple of type <int, int, float>, representing
(x, y, temperature) of the center pixel in the matrix.
If the operation fails, the return values will be x, y < 0.
staticTrue
+
+

C++ defination code:

+ +
static Point center_point_from(const KMatrix& matrix)
+
+
+ + +
+
+
+ + +
+
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixcdk/api/maix/ext_dev/pmu.html b/maixcdk/api/maix/ext_dev/pmu.html new file mode 100644 index 00000000..3c143867 --- /dev/null +++ b/maixcdk/api/maix/ext_dev/pmu.html @@ -0,0 +1,814 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + maix::ext_dev::pmu - MaixCDK + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

maix::ext_dev::pmu

+ +
+
+
    + +
+
+
+
+ + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

maix.ext_dev.pmu module

+
+

This is maix::ext_dev::pmu module of MaixCDK.
+All of these elements are in namespace maix::ext_dev::pmu.

+

For MaixCDK developer: DO NOT edit this doc file manually, this doc is auto generated!

+
+

Module

+

No module

+

Enum

+

ChargerStatus

+

charger status

+ + + + + + + + + + + + + +
itemdescribe
valuesCHG_TRI_STATE: tri_charge
CHG_PRE_STATE: pre_charge
CHG_CC_STATE: constant charge
CHG_CV_STATE: constant voltage
CHG_DONE_STATE: charge done
CHG_STOP_STATE: not charge
+
+

C++ defination code:

+ +
enum class ChargerStatus {
+    CHG_TRI_STATE,   //tri_charge
+    CHG_PRE_STATE,   //pre_charge
+    CHG_CC_STATE,    //constant charge
+    CHG_CV_STATE,    //constant voltage
+    CHG_DONE_STATE,  //charge done
+    CHG_STOP_STATE,  //not charge
+}
+
+
+

PowerChannel

+

power channel

+ + + + + + + + + + + + + +
itemdescribe
valuesDCDC1:
DCDC2:
DCDC3:
DCDC4:
DCDC5:
ALDO1:
ALDO2:
ALDO3:
ALDO4:
BLDO1:
BLDO2:
DLDO1:
DLDO2:
VBACKUP:
CPULDO:
+
+

C++ defination code:

+ +
enum class PowerChannel {
+        DCDC1,
+        DCDC2,
+        DCDC3,
+        DCDC4,
+        DCDC5,
+        ALDO1,
+        ALDO2,
+        ALDO3,
+        ALDO4,
+        BLDO1,
+        BLDO2,
+        DLDO1,
+        DLDO2,
+        VBACKUP,
+        CPULDO,
+}
+
+
+

Variable

+

Function

+

Class

+

PMU

+

PMU driver class

+
+

C++ defination code:

+ +
class PMU
+
+
+

__init__

+

Construct a new PMU object, will open PMU.

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramdriver: driver name, only support "axp2101".
i2c_bus: i2c bus number. Automatically selects the on-board pmu when -1 is passed in.
addr: PMU i2c addr.
staticFalse
+
+

C++ defination code:

+ +
PMU(std::string driver = "axp2101", int i2c_bus = -1, int addr = 0x34)
+
+
+

poweroff

+

Poweroff immediately.

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnerr::Err type, if init success, return err::ERR_NONE.
staticFalse
+
+

C++ defination code:

+ +
err::Err poweroff()
+
+
+

is_bat_connect

+

Is the battery connected.

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnbool type, if battery is connected, return true.
staticFalse
+
+

C++ defination code:

+ +
bool is_bat_connect()
+
+
+

is_vbus_in

+

Is the power adapter connected.

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnbool type, if power adapter is connected, return true.
staticFalse
+
+

C++ defination code:

+ +
bool is_vbus_in()
+
+
+

is_charging

+

Is bat charging.

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnbool type, if bat is charging, return true.
staticFalse
+
+

C++ defination code:

+ +
bool is_charging()
+
+
+

get_bat_percent

+

Get the battery percentage.

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnint type, return battery percentage.
staticFalse
+
+

C++ defination code:

+ +
int get_bat_percent()
+
+
+

get_charger_status

+

Get the battery charging status.

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnint type, return battery charging status.
staticFalse
+
+

C++ defination code:

+ +
ext_dev::pmu::ChargerStatus get_charger_status()
+
+
+

get_vat_vol

+

Get the battery voltage.

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnuint16_t type, return battery voltage.
staticFalse
+
+

C++ defination code:

+ +
uint16_t get_bat_vol()
+
+
+

clean_irq

+

Clear interrupt flag.

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnerr::Err type, if clean success, return err::ERR_NONE.
staticFalse
+
+

C++ defination code:

+ +
err::Err clean_irq()
+
+
+

set_bat_charging_cur

+

Set the battery charging current.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramcurrent: The current to be set.
returnerr::Err type, if set success, return err::ERR_NONE.
staticFalse
+
+

C++ defination code:

+ +
err::Err set_bat_charging_cur(int current)
+
+
+

get_bat_charging_cur

+

Get the battery charging current.

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnint, return the currently set charging current.
staticFalse
+
+

C++ defination code:

+ +
int get_bat_charging_cur()
+
+
+

set_vol

+

Set the PMU channel voltage.\nYou can retrieve the available channel from ext_dev.pmu.PowerChannel.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramvoltage: The voltage to be set.
returnint, return the channel voltage.
staticFalse
+
+

C++ defination code:

+ +
err::Err set_vol(ext_dev::pmu::PowerChannel channel, int voltage)
+
+
+

get_vol

+

Get the PMU channel voltage.\nYou can retrieve the available channel from ext_dev.pmu.PowerChannel.

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnerr::Err type, if set success, return err::ERR_NONE.
staticFalse
+
+

C++ defination code:

+ +
int get_vol(ext_dev::pmu::PowerChannel channel)
+
+
+ + +
+
+
+ + +
+
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixcdk/api/maix/ext_dev/qmi8658.html b/maixcdk/api/maix/ext_dev/qmi8658.html new file mode 100644 index 00000000..5e768fe3 --- /dev/null +++ b/maixcdk/api/maix/ext_dev/qmi8658.html @@ -0,0 +1,415 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + maix::ext_dev::qmi8658 - MaixCDK + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

maix::ext_dev::qmi8658

+ +
+
+
    + +
+
+
+
+ + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

maix.ext_dev.qmi8658 module

+
+

This is maix::ext_dev::qmi8658 module of MaixCDK.
+All of these elements are in namespace maix::ext_dev::qmi8658.

+

For MaixCDK developer: DO NOT edit this doc file manually, this doc is auto generated!

+
+

Module

+

No module

+

Enum

+

Variable

+

Function

+

Class

+

QMI8658

+

QMI8656 driver class

+
+

C++ defination code:

+ +
class QMI8658
+
+
+

__init__

+

Construct a new QMI8658 object, will open QMI8658

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
parami2c_bus: i2c bus number. Automatically selects the on-board qmi8658 when -1 is passed in.
addr: QMI8658 i2c addr.
freq: QMI8658 freq
mode: QMI8658 Mode: ACC_ONLY/GYRO_ONLY/DUAL
acc_scale: acc scale, see @qmi8658::AccScale
acc_odr: acc output data rate, see @qmi8658::AccOdr
gyro_scale: gyro scale, see @qmi8658::GyroScale
gyro_odr: gyro output data rate, see @qmi8658::GyroOdr
block: block or non-block, defalut is true
staticFalse
+
+

C++ defination code:

+ +
QMI8658(int i2c_bus=-1, int addr=0x6B, int freq=400000,
+            maix::ext_dev::imu::Mode mode=maix::ext_dev::imu::Mode::DUAL,
+            maix::ext_dev::imu::AccScale acc_scale=maix::ext_dev::imu::AccScale::ACC_SCALE_2G,
+            maix::ext_dev::imu::AccOdr acc_odr=maix::ext_dev::imu::AccOdr::ACC_ODR_8000,
+            maix::ext_dev::imu::GyroScale gyro_scale=maix::ext_dev::imu::GyroScale::GYRO_SCALE_16DPS,
+            maix::ext_dev::imu::GyroOdr gyro_odr=maix::ext_dev::imu::GyroOdr::GYRO_ODR_8000,
+            bool block=true)
+
+
+

read

+

Read data from QMI8658.

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnlist type. If only one of the outputs is initialized, only [x,y,z] of that output will be returned.
If all outputs are initialized, [acc_x, acc_y, acc_z, gyro_x, gyro_y, gyro_z] is returned.
staticFalse
+
+

C++ defination code:

+ +
std::vector<float> read()
+
+
+ + +
+
+
+ + +
+
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixcdk/api/maix/ext_dev/tmc2209.html b/maixcdk/api/maix/ext_dev/tmc2209.html new file mode 100644 index 00000000..f55994b4 --- /dev/null +++ b/maixcdk/api/maix/ext_dev/tmc2209.html @@ -0,0 +1,854 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + maix::ext_dev::tmc2209 - MaixCDK + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

maix::ext_dev::tmc2209

+ +
+
+
    + +
+
+
+
+ + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

maix.ext_dev.tmc2209 module

+
+

This is maix::ext_dev::tmc2209 module of MaixCDK.
+All of these elements are in namespace maix::ext_dev::tmc2209.

+

For MaixCDK developer: DO NOT edit this doc file manually, this doc is auto generated!

+
+

Module

+

No module

+

Enum

+

Variable

+

Function

+

slide_scan

+

Scan and initialize the slide with the given parameters

+ + + + + + + + + + + + + +
itemdescription
paramport: UART port, string type.
addr: TMC2209 UART address, range 0x00~0x03, integer type.
baud: UART baud rate, integer type.
step_angle: Motor step angle, float type.
micro_step: Motor micro step, options: 1/2/4/8/16/32/64/128/256, integer type.
round_mm: Round distance in mm, float type.
speed_mm_s: Speed of the slide in mm/s, float type.
dir: Direction of movement, boolean type. Default is true.
use_internal_sense_resistors: Enable internal sense resistors if true, disable if false, boolean type. Default is true.
run_current_per: Motor run current percentage, range 0~100(%), integer type. Default is 100%.
hold_current_per: Motor hold current percentage, range 0~100(%), integer type. Default is 100%.
conf_save_path: Configuration save path, string type. Default is "./slide_conf.bin".
force_update: Force update the configuration if true, boolean type. Default is true.
+
+

C++ defination code:

+ +
void slide_scan(const char* port, uint8_t addr, long baud, /* Uart init param */
+                float step_angle, uint16_t micro_step, float round_mm, /* Motor init param */
+                float speed_mm_s, bool dir=true, bool use_internal_sense_resistors=true, uint8_t run_current_per=100,
+                uint8_t hold_current_per=100, const std::string conf_save_path="./slide_conf.bin",
+                bool force_update=true  /* Driver init param */)
+
+
+

slide_test

+

Test the slide with the given parameters\nThis function tests the slide by moving it in the specified direction until a stall condition is detected, as defined in the configuration file.

+ + + + + + + + + + + + + +
itemdescription
paramport: UART port, string type.
addr: TMC2209 UART address, range 0x00~0x03, integer type.
baud: UART baud rate, integer type.
step_angle: Motor step angle, float type.
micro_step: Motor micro step, options: 1/2/4/8/16/32/64/128/256, integer type.
round_mm: Round distance in mm, float type.
speed_mm_s: Speed of the slide in mm/s, float type.
dir: Direction of movement, boolean type. Default is true.
use_internal_sense_resistors: Enable internal sense resistors if true, disable if false, boolean type. Default is true.
run_current_per: Motor run current percentage, range 0~100(%), integer type. Default is 100%.
hold_current_per: Motor hold current percentage, range 0~100(%), integer type. Default is 100%.
conf_save_path: Configuration save path, string type. Default is "./slide_conf.bin".
+
+

C++ defination code:

+ +
void slide_test(const char* port, uint8_t addr, long baud, /* Uart init param */
+                float step_angle, uint16_t micro_step, float round_mm, /* Motor init param */
+                float speed_mm_s, bool dir=true, bool use_internal_sense_resistors=true, uint8_t run_current_per=100,
+                uint8_t hold_current_per=100, const std::string conf_save_path="./slide_conf.bin"/* Driver init param */)
+
+
+

Class

+

Slide

+

Slide Class

+
+

C++ defination code:

+ +
class Slide
+
+
+

__init__

+

Constructor for Slide\nInitializes the Slide object with the specified parameters.

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramport: UART port, string type.
addr: TMC2209 UART address, range 0x00~0x03, integer type.
baud: UART baud rate, integer type.
step_angle: Motor step angle, float type.
micro_step: Motor micro step, options: 1/2/4/8/16/32/64/128/256, integer type.
round_mm: Round distance in mm, float type.
speed_mm_s: Speed of the slide in mm/s, float type. Default is -1, indicating the use of a default speed factor.
use_internal_sense_resistors: Enable internal sense resistors if TRUE, disable if FALSE, boolean type. Default is TRUE.
run_current_per: Motor run current percentage, range 0~100(%), integer type. Default is 100%.
hold_current_per: Motor hold current percentage, range 0~100(%), integer type. Default is 100%.
cfg_file_path: Configuration file path, string type. Default is an empty string, indicating no configuration file.
staticFalse
+
+

C++ defination code:

+ +
Slide(const char* port, uint8_t addr, long baud, /* Uart init param */
+            float step_angle, uint16_t micro_step, float round_mm,   /* Motor init param */
+            float speed_mm_s=-1, bool use_internal_sense_resistors=true, uint8_t run_current_per=100,
+            uint8_t hold_current_per=100, std::string cfg_file_path="" /* Driver init param */)
+
+
+

load_conf

+

Load configuration from a file\nLoads the configuration settings for the slide from the specified file path.

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
parampath: Path to the configuration file, string type.
staticFalse
+
+

C++ defination code:

+ +
void load_conf(std::string path)
+
+
+

move

+

Move the slide by a specified length\nMoves the slide by the specified length at the given speed. Optionally checks for stall conditions.

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramoft: Length to move, float type.
speed_mm_s: Speed in mm/s. Default is -1, indicating the use of the default speed set during initialization.
check: Enable movement check if true, boolean type. Default is true.
staticFalse
+
+

C++ defination code:

+ +
void move(float oft, int speed_mm_s=-1, bool check=true)
+
+
+

reset

+

Reset the slide position\nResets the slide position in the specified direction at the given speed.

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramdir: Direction of reset, boolean type. Default is false.
speed_mm_s: Speed in mm/s. Default is -1, indicating the use of the speed set during initialization.
staticFalse
+
+

C++ defination code:

+ +
void reset(bool dir=false, int speed_mm_s=-1)
+
+
+

stop_default_per

+

Get or set the stop default percentage\nRetrieves or sets the stop default percentage. If the parameter is -1, it returns the current setting.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramper: Stop default percentage, range 0~100(%), integer type. Default is -1, indicating no change.
returnint Current stop default percentage if per is -1, otherwise the new set percentage.
staticFalse
+
+

C++ defination code:

+ +
int stop_default_per(int per=-1)
+
+
+

run_current_per

+

Get or set the run current percentage\nRetrieves or sets the run current percentage. If the parameter is -1, it returns the current setting.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramper: Run current percentage, range 0~100(%), integer type. Default is -1, indicating no change.
returnint Current run current percentage if per is -1, otherwise the new set percentage.
staticFalse
+
+

C++ defination code:

+ +
int run_current_per(int per=-1)
+
+
+

hold_current_per

+

Get or set the hold current percentage\nRetrieves or sets the hold current percentage. If the parameter is -1, it returns the current setting.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramper: Hold current percentage, range 0~100(%), integer type. Default is -1, indicating no change.
returnint Current hold current percentage if per is -1, otherwise the new set percentage.
staticFalse
+
+

C++ defination code:

+ +
int hold_current_per(int per=-1)
+
+
+

use_internal_sense_resistors

+

Enable or disable internal sense resistors\nEnables or disables the internal sense resistors based on the provided boolean value.

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramb: Boolean value to enable (true) or disable (false) internal sense resistors. Default is true.
staticFalse
+
+

C++ defination code:

+ +
void use_internal_sense_resistors(bool b=true)
+
+
+

ScrewSlide

+

ScrewSlide Class

+
+

C++ defination code:

+ +
class ScrewSlide
+
+
+

__init__

+

Constructor for ScrewSlide

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramport: UART port, string type.
addr: TMC2209 UART address, range 0x00~0x03, integer type.
baud: UART baud rate, integer type.
step_angle: Motor step angle, float type.
micro_step: Motor micro step, options: 1/2/4/8/16/32/64/128/256, integer type.
screw_pitch: Screw pitch of the slide, integer type.
speed_mm_s: Speed of the slide in mm/s, 10 means 10mm/s, float type.
Default is -1, indicating the use of a default speed factor.
use_internal_sense_resistors: Enable internal sense resistors if TRUE,
disable if FALSE, boolean type. Default is TRUE.
run_current_per: Motor run current percentage, range 0~100(%), integer type. Default is 100%.
hold_current_per: Motor hold current percentage, range 0~100(%), integer type. Default is 100%.
staticFalse
+
+

C++ defination code:

+ +
ScrewSlide(const char* port, uint8_t addr, long baud, /* Uart init param */
+                float step_angle, uint16_t micro_step, float screw_pitch,   /* Motor init param */
+                float speed_mm_s=-1, bool use_internal_sense_resistors=true, uint8_t run_current_per=100,
+                uint8_t hold_current_per=100)
+
+
+

move

+

Move the slide by a specified length

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramoft: Length to move, 10 means 10mm, float type.
Positive values move the slide in the positive direction, negative values move it in the opposite direction.
speed_mm_s: Speed in mm/s. Default is -1, indicating the use of the default speed set during initialization.
callback: Callback function to be called during movement.
The callback function receives the current progress percentage (0~100%) of the movement.
If the callback returns true, the move operation will be terminated immediately. Default is nullptr.
staticFalse
+
+

C++ defination code:

+ +
void move(float oft, int speed_mm_s=-1, std::function<bool(float)> callback=nullptr)
+
+
+

reset

+

Reset the slide position

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramcallback: Callback function to be called during the reset loop.
The reset operation will only terminate if the callback returns true.
dir: Direction of reset. Default is false.
speed_mm_s: Speed in mm/s. Default is -1, indicating the use of the speed set during initialization.
staticFalse
+
+

C++ defination code:

+ +
void reset(std::function<bool(void)> callback, bool dir=false, int speed_mm_s=-1)
+
+
+

run_current_per

+

Get or set the run current percentage

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramper: Run current percentage, range 0~100(%).
Default is -1, indicating no change and returning the current run current percentage.
returnint Current run current percentage if per is -1, otherwise the new set percentage.
staticFalse
+
+

C++ defination code:

+ +
int run_current_per(int per=-1)
+
+
+

hold_current_per

+

Get or set the hold current percentage

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramper: Hold current percentage, range 0~100(%). Default is -1, indicating no change and returning the current hold current percentage.
returnint Current hold current percentage if per is -1, otherwise the new set percentage.
staticFalse
+
+

C++ defination code:

+ +
int hold_current_per(int per=-1)
+
+
+

use_internal_sense_resistors

+

Enable or disable internal sense resistors

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramb: Boolean value to enable (true) or disable (false) internal sense resistors. Default is true.
staticFalse
+
+

C++ defination code:

+ +
void use_internal_sense_resistors(bool b=true)
+
+
+ + +
+
+
+ + +
+
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixcdk/api/maix/fs.html b/maixcdk/api/maix/fs.html new file mode 100644 index 00000000..637a5d7d --- /dev/null +++ b/maixcdk/api/maix/fs.html @@ -0,0 +1,1302 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + maix::fs - MaixCDK + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

maix::fs

+ +
+
+
    + +
+
+
+
+ + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

maix.fs module

+
+

This is maix::fs module of MaixCDK.
+All of these elements are in namespace maix::fs.

+

For MaixCDK developer: DO NOT edit this doc file manually, this doc is auto generated!

+
+

Module

+

No module

+

Enum

+

SEEK

+

SEEK enums

+ + + + + + + + + + + + + +
itemdescribe
valuesSEEK_SET: Seek from beginning of file.
SEEK_CUR: Seek from current position.
SEEK_END: Seek from end of file.
+
+

C++ defination code:

+ +
enum SEEK
+    {
+        SEEK_SET = 0,  // Seek from beginning of file.
+        SEEK_CUR = 1,  // Seek from current position.
+        SEEK_END = 2,  // Seek from end of file.
+    }
+
+
+

Variable

+

Function

+

isabs

+

Check if the path is absolute path

+ + + + + + + + + + + + + + + + + +
itemdescription
parampath: path to check
returntrue if path is absolute path
+
+

C++ defination code:

+ +
bool isabs(const std::string &path)
+
+
+

isdir

+

Check if the path is a directory, if not exist, throw exception

+ + + + + + + + + + + + + + + + + +
itemdescription
parampath: path to check
returntrue if path is a directory
+
+

C++ defination code:

+ +
bool isdir(const std::string &path)
+
+
+

isfile

+

Check if the path is a file, if not exist, throw exception

+ + + + + + + + + + + + + + + + + +
itemdescription
parampath: path to check
returntrue if path is a file
+
+

C++ defination code:

+ +
bool isfile(const std::string &path)
+
+
+ +

Check if the path is a link, if not exist, throw exception

+ + + + + + + + + + + + + + + + + +
itemdescription
parampath: path to check
returntrue if path is a link
+
+

C++ defination code:

+ +
bool islink(const std::string &path)
+
+
+ +

Create soft link

+ + + + + + + + + + + + + +
itemdescription
paramsrc: real file path
link: link file path
force: force link, if already have link file, will delet it first then create.
+
+

C++ defination code:

+ +
err::Err symlink(const std::string &src, const std::string &link, bool force = false)
+
+
+

exists

+

Check if the path exists

+ + + + + + + + + + + + + + + + + +
itemdescription
parampath: path to check
returntrue if path exists
+
+

C++ defination code:

+ +
bool exists(const std::string &path)
+
+
+

mkdir

+

Create a directory recursively

+ + + + + + + + + + + + + + + + + +
itemdescription
parampath: path to create
exist_ok: if true, also return true if directory already exists
recursive: if true, create directory recursively, otherwise, only create one directory, default is true
returnerr::ERR_NONE(err.Err.ERR_NONE in MaixPy) if success, other error code if failed
+
+

C++ defination code:

+ +
err::Err mkdir(const std::string &path, bool exist_ok = true, bool recursive = true)
+
+
+

rmdir

+

Remove a directory

+ + + + + + + + + + + + + + + + + +
itemdescription
parampath: path to remove
recursive: if true, remove directory recursively, otherwise, only remove empty directory, default is false
returnerr::ERR_NONE(err.Err.ERR_NONE in MaixPy) if success, other error code if failed
+
+

C++ defination code:

+ +
err::Err rmdir(const std::string &path, bool recursive = false)
+
+
+

remove

+

Remove a file

+ + + + + + + + + + + + + + + + + +
itemdescription
parampath: path to remove
returnerr::ERR_NONE(err.Err.ERR_NONE in MaixPy) if success, other error code if failed
+
+

C++ defination code:

+ +
err::Err remove(const std::string &path)
+
+
+

rename

+

Rename a file or directory

+ + + + + + + + + + + + + + + + + +
itemdescription
paramsrc: source path
dst: destination path, if destination dirs not exist, will auto create
returnerr::ERR_NONE(err.Err.ERR_NONE in MaixPy) if success, other error code if failed
+
+

C++ defination code:

+ +
err::Err rename(const std::string &src, const std::string &dst)
+
+
+

sync

+

Sync files, ensure they're wrriten to disk from RAM

+
+

C++ defination code:

+ +
void sync()
+
+
+

getsize

+

Get file size

+ + + + + + + + + + + + + + + + + +
itemdescription
parampath: path to get size
returnfile size if success, -err::Err code if failed
+
+

C++ defination code:

+ +
int getsize(const std::string &path)
+
+
+

dirname

+

Get directory name of path

+ + + + + + + + + + + + + + + + + +
itemdescription
parampath: path to get dirname
returndirname if success, empty string if failed
+
+

C++ defination code:

+ +
std::string dirname(const std::string &path)
+
+
+

basename

+

Get base name of path

+ + + + + + + + + + + + + + + + + +
itemdescription
parampath: path to get basename
returnbasename if success, empty string if failed
+
+

C++ defination code:

+ +
std::string basename(const std::string &path)
+
+
+

abspath

+

Get absolute path

+ + + + + + + + + + + + + + + + + +
itemdescription
parampath: path to get absolute path
returnabsolute path if success, empty string if failed
+
+

C++ defination code:

+ +
std::string abspath(const std::string &path)
+
+
+

getcwd

+

Get current working directory

+ + + + + + + + + + + + + +
itemdescription
returncurrent working directory absolute path
+
+

C++ defination code:

+ +
std::string getcwd()
+
+
+

realpath

+

Get realpath of path

+ + + + + + + + + + + + + + + + + +
itemdescription
parampath: path to get realpath
returnrealpath if success, empty string if failed
+
+

C++ defination code:

+ +
std::string realpath(const std::string &path)
+
+
+

splitext

+

Get file extension

+ + + + + + + + + + + + + + + + + +
itemdescription
parampath: path to get extension
returnprefix_path and extension list if success, empty string if failed
+
+

C++ defination code:

+ +
std::vector<std::string> splitext(const std::string &path)
+
+
+

listdir

+

List files in directory

+ + + + + + + + + + + + + + + + + +
itemdescription
parampath: path to list
recursive: if true, list recursively, otherwise, only list current directory, default is false
full_path: if true, return full path, otherwise, only return basename, default is false
returnfiles list if success, nullptr if failed, you should manually delete it in C++.
+
+

C++ defination code:

+ +
std::vector<std::string> *listdir(const std::string &path, bool recursive = false, bool full_path = false)
+
+
+

open

+

Open a file, and return a File object

+ + + + + + + + + + + + + + + + + +
itemdescription
parampath: path to open
mode: open mode, support "r", "w", "a", "r+", "w+", "a+", "rb", "wb", "ab", "rb+", "wb+", "ab+"
returnFile object if success(need to delete object manually in C/C++), nullptr if failed
+
+

C++ defination code:

+ +
fs::File *open(const std::string &path, const std::string &mode)
+
+
+

tempdir

+

Get temp files directory

+ + + + + + + + + + + + + +
itemdescription
returntemp files directory
+
+

C++ defination code:

+ +
std::string tempdir()
+
+
+

Class

+

File

+

File read write ops

+
+

C++ defination code:

+ +
class File
+
+
+

File

+

Construct File object

+ + + + + + + + + + + + + + + + + +
itemdescription
typefunc
staticFalse
+
+

C++ defination code:

+ +
File()
+
+
+

open

+

Open a file

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
parampath: path to open
mode: open mode, support "r", "w", "a", "r+", "w+", "a+", "rb", "wb", "ab", "rb+", "wb+", "ab+"
returnerr::ERR_NONE(err.Err.ERR_NONE in MaixPy) if success, other error code if failed
staticFalse
+
+

C++ defination code:

+ +
err::Err open(const std::string &path, const std::string &mode)
+
+
+

close

+

Close a file

+ + + + + + + + + + + + + + + + + +
itemdescription
typefunc
staticFalse
+
+

C++ defination code:

+ +
void close()
+
+
+

read

+

Read data from file

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
parambuf: buffer to store data
size: buffer size(max read size)
returnread size if success, -err::Err code if failed
staticFalse
+
+

C++ defination code:

+ +
int read(void *buf, int size)
+
+
+

read (overload 1)

+

Read data from file API2

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramsize: max read size
returnbytes data if success(need delete manually in C/C++), nullptr if failed
staticFalse
+
+

C++ defination code:

+ +
std::vector<uint8_t> *read(int size)
+
+
+

readline

+

Read line from file

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramline: buffer to store line
returnread size if success, -err::Err code if failed
staticFalse
+
+

C++ defination code:

+ +
int readline(std::string &line)
+
+
+

readline (overload 1)

+

Read line from file

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnline if success, None(nullptr in C++) if failed. You need to delete the returned object manually in C/C++.
staticFalse
+
+

C++ defination code:

+ +
std::string *readline()
+
+
+

eof

+

End of file or not

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
return0 if not reach end of file, else eof.
staticFalse
+
+

C++ defination code:

+ +
int eof()
+
+
+

write

+

Write data to file

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
parambuf: buffer to write
size: buffer size
returnwrite size if success, -err::Err code if failed
staticFalse
+
+

C++ defination code:

+ +
int write(const void *buf, int size)
+
+
+

write (overload 1)

+

Write data to file API2

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
parambuf: buffer to write
returnwrite size if success, -err::Err code if failed
staticFalse
+
+

C++ defination code:

+ +
int write(const std::vector<uint8_t> &buf)
+
+
+

seek

+

Seek file position

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramoffset: offset to seek
whence: @see maix.fs.SEEK
returnnew position if success, -err::Err code if failed
staticFalse
+
+

C++ defination code:

+ +
int seek(int offset, int whence)
+
+
+

tell

+

Get file position

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnfile position if success, -err::Err code if failed
staticFalse
+
+

C++ defination code:

+ +
int tell()
+
+
+

flush

+

Flush file

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnerr::ERR_NONE(err.Err.ERR_NONE in MaixPy) if success, other error code if failed
staticFalse
+
+

C++ defination code:

+ +
err::Err flush()
+
+
+ + +
+
+
+ + +
+
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixcdk/api/maix/http.html b/maixcdk/api/maix/http.html new file mode 100644 index 00000000..1575b3de --- /dev/null +++ b/maixcdk/api/maix/http.html @@ -0,0 +1,571 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + maix::http - MaixCDK + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

maix::http

+ +
+
+
    + +
+
+
+
+ + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

maix.http module

+
+

This is maix::http module of MaixCDK.
+All of these elements are in namespace maix::http.

+

For MaixCDK developer: DO NOT edit this doc file manually, this doc is auto generated!

+
+

Module

+

No module

+

Enum

+

Variable

+

Function

+

Class

+

JpegStreamer

+

JpegStreamer class

+
+

C++ defination code:

+ +
class JpegStreamer
+
+
+

JpegStreamer

+

Construct a new jpeg streamer object

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
noteYou can get the picture stream through http://host:port/stream, you can also get it through http://ip:port, and you can add personal style through set_html() at this time
paramhost: http host
port: http port, default is 8000
client_number: the max number of client
staticFalse
+
+

C++ defination code:

+ +
JpegStreamer(std::string host = std::string(), int port = 8000, int client_number = 16)
+
+
+

start

+

start jpeg streame

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnerror code, err::ERR_NONE means success, others means failed
staticFalse
+
+

C++ defination code:

+ +
err::Err start()
+
+
+

start (overload 1)

+

stop http

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnerror code, err::ERR_NONE means success, others means failed
staticFalse
+
+

C++ defination code:

+ +
err::Err stop()
+
+
+

write

+

Write data to http

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramimg: image object
returnerror code, err::ERR_NONE means success, others means failed
staticFalse
+
+

C++ defination code:

+ +
err::Err write(image::Image *img)
+
+
+

set_html

+

add your style in this api\ndefault is:\n\n\n

JPG Stream

\n\n\n

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramdata: html code
returnerror code, err::ERR_NONE means success, others means failed
staticFalse
+
+

C++ defination code:

+ +
err::Err set_html(std::string data)
+
+
+

host

+

Get host

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnhost name
staticFalse
+
+

C++ defination code:

+ +
std::string host()
+
+
+

port

+

Get port

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnport
staticFalse
+
+

C++ defination code:

+ +
int port()
+
+
+ + +
+
+
+ + +
+
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixcdk/api/maix/i18n.html b/maixcdk/api/maix/i18n.html new file mode 100644 index 00000000..a5f0458a --- /dev/null +++ b/maixcdk/api/maix/i18n.html @@ -0,0 +1,697 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + maix::i18n - MaixCDK + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

maix::i18n

+ +
+
+
    + +
+
+
+
+ + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

maix.i18n module

+
+

This is maix::i18n module of MaixCDK.
+All of these elements are in namespace maix::i18n.

+

For MaixCDK developer: DO NOT edit this doc file manually, this doc is auto generated!

+
+

Module

+

No module

+

Enum

+

Variable

+

locales

+

i18n locales list

+ + + + + + + + + + + + + + + + + +
itemdescription
value{
"en",
"zh",
"zh-tw",
"ja"}
readonlyFalse
+
+

C++ defination code:

+ +
static std::vector<std::string> locales = {
+        "en",
+        "zh",
+        "zh-tw",
+        "ja"}
+
+
+

names

+

i18n language names list

+ + + + + + + + + + + + + + + + + +
itemdescription
value{
"English",
"简体中文",
"繁體中文",
"日本語"}
readonlyTrue
+
+

C++ defination code:

+ +
const static std::vector<std::string> names = {
+        "English",
+        "简体中文",
+        "繁體中文",
+        "日本語"}
+
+
+

Function

+

get_locale

+

Get system config of locale.

+ + + + + + + + + + + + + +
itemdescription
returnlanguage locale, e.g. en, zh, zh_CN, zh_TW, etc.
+
+

C++ defination code:

+ +
string get_locale()
+
+
+

get_language_name

+

Get system config of language name.

+ + + + + + + + + + + + + +
itemdescription
returnlanguage name, e.g. English, 简体中文, 繁體中文, etc.
+
+

C++ defination code:

+ +
string get_language_name()
+
+
+

load_trans_yaml

+

Load translations from yaml files.

+ + + + + + + + + + + + + + + + + +
itemdescription
paramlocales_dir: translation yaml files directory.
returnA dict contains all translations, e.g. {"zh":{"hello": "你好"}, "en":{"hello": "hello"}}, you should delete it after use in C++.
+
+

C++ defination code:

+ +
const std::map<string, std::map<string, string>> *load_trans_yaml(const std::string &locales_dir)
+
+
+

load_trans_yaml (overload 1)

+

Load translations from yaml files.

+ + + + + + + + + + + + + + + + + +
itemdescription
paramlocales_dir: translation yaml files directory.
dict: dict to store key values. A dict contains all translations, e.g. {"zh":{"hello": "你好"}, "en":{"hello": "hello"}}, you should delete it after use in C++.
returnerr::ERR
+
+

C++ defination code:

+ +
err::Err load_trans_yaml(const std::string &locales_dir, std::map<string, std::map<string, string>> &dict)
+
+
+

Class

+

Trans

+

Translate helper class.

+
+

C++ defination code:

+ +
class Trans
+
+
+

Trans

+

Translate helper class constructor.\nBy default locale is get by i18n.get_locale() function which set by system settings.\nBut you can also manually set by set_locale function temporarily.

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramlocales_dict: locales dict, e.g. {"zh": {"Confirm": "确认", "OK": "好的"}, "en": {"Confirm": "Confirm", "OK": "OK"}}
staticFalse
+
+

C++ defination code:

+ +
Trans(const std::map<string, const std::map<string, string>> &locales_dict = std::map<string, const std::map<string, string>>())
+
+
+

load

+

Load translation from yaml files generated by maixtool i18n command.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramlocales_dir: the translation files directory.
returnerr.Err type, no error will return err.Err.ERR_NONE.
staticFalse
+
+

C++ defination code:

+ +
err::Err load(const std::string &locales_dir)
+
+
+

update_dict

+

Update translation dict.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramdict: the new translation dict.
returnerr.Err type, no error will return err.Err.ERR_NONE.
staticFalse
+
+

C++ defination code:

+ +
err::Err update_dict(const std::map<std::string, const std::map<std::string, std::string>> &dict)
+
+
+

tr

+

Translate string by key.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramkey: string key, e.g. "Confirm"
locale: locale name, if not assign, use default locale set by system settings or set_locale function.
returntranslated string, if find translation, return it, or return key, e.g. "确认", "Confirm", etc.
staticFalse
+
+

C++ defination code:

+ +
string tr(const string &key, const string locale = "")
+
+
+

set_locale

+

Set locale temporarily, will not affect system settings.

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramlocale: locale name, e.g. "zh", "en", etc. @see maix.i18n.locales
staticFalse
+
+

C++ defination code:

+ +
void set_locale(const string &locale)
+
+
+

get_locale

+

Get current locale.

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnlocale name, e.g. "zh", "en", etc. @see maix.i18n.locales
staticFalse
+
+

C++ defination code:

+ +
string get_locale()
+
+
+ + +
+
+ +
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixcdk/api/maix/image.html b/maixcdk/api/maix/image.html new file mode 100644 index 00000000..aef9ea37 --- /dev/null +++ b/maixcdk/api/maix/image.html @@ -0,0 +1,11557 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + maix::image - MaixCDK + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

maix::image

+ +
+
+
    + +
+
+
+
+ + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

maix.image module, image related definition and functions

+
+

This is maix::image module of MaixCDK.
+All of these elements are in namespace maix::image.

+

For MaixCDK developer: DO NOT edit this doc file manually, this doc is auto generated!

+
+

Module

+

No module

+

Enum

+

Format

+

Image formats

+ + + + + + + + + + + + + + + + + +
itemdescribe
attentionfor MaixPy firmware developers, update this enum will also need to update the fmt_size and fmt_names too !!!
valuesFMT_RGB888: RGBRGB...RGB, R at the lowest address
FMT_BGR888: BGRBGR...BGR, B at the lowest address
FMT_RGBA8888: RGBARGBA...RGBA, R at the lowest address
FMT_BGRA8888: BGRABGRA...BGRA, B at the lowest address
FMT_RGB565:
FMT_BGR565:
FMT_YUV422SP: YYY...UVUVUV...UVUV
FMT_YUV422P: YYY...UUU...VVV
FMT_YVU420SP: YYY...VUVUVU...VUVU, NV21
FMT_YUV420SP: YYY...UVUVUV...UVUV, NV12
FMT_YVU420P: YYY...VVV...UUU
FMT_YUV420P: YYY...UUU...VVV
FMT_GRAYSCALE:
FMT_BGGR6: 6-bit Bayer format with a BGGR pattern.
FMT_GBRG6: 6-bit Bayer format with a GBRG pattern.
FMT_GRBG6: 6-bit Bayer format with a GRBG pattern.
FMT_RGGB6: 6-bit Bayer format with a RGGB pattern.
FMT_BGGR8: 8-bit Bayer format with a BGGR pattern.
FMT_GBRG8: 8-bit Bayer format with a GBRG pattern.
FMT_GRBG8: 8-bit Bayer format with a GRBG pattern.
FMT_RGGB8: 8-bit Bayer format with a RGGB pattern.
FMT_BGGR10: 10-bit Bayer format with a BGGR pattern.
FMT_GBRG10: 10-bit Bayer format with a GBRG pattern.
FMT_GRBG10: 10-bit Bayer format with a GRBG pattern.
FMT_RGGB10: 10-bit Bayer format with a RGGB pattern.
FMT_BGGR12: 12-bit Bayer format with a BGGR pattern.
FMT_GBRG12: 12-bit Bayer format with a GBRG pattern.
FMT_GRBG12: 12-bit Bayer format with a GRBG pattern.
FMT_RGGB12: 12-bit Bayer format with a RGGB pattern.
FMT_UNCOMPRESSED_MAX:
FMT_COMPRESSED_MIN:
FMT_JPEG:
FMT_PNG:
FMT_COMPRESSED_MAX:
FMT_INVALID: format not valid
+
+

C++ defination code:

+ +
enum Format
+    {
+        FMT_RGB888 = 0, // RGBRGB...RGB, R at the lowest address
+        FMT_BGR888,     // BGRBGR...BGR, B at the lowest address
+        FMT_RGBA8888,   // RGBARGBA...RGBA, R at the lowest address
+        FMT_BGRA8888,   // BGRABGRA...BGRA, B at the lowest address
+        FMT_RGB565,
+        FMT_BGR565,
+        FMT_YUV422SP, // YYY...UVUVUV...UVUV
+        FMT_YUV422P,  // YYY...UUU...VVV
+        FMT_YVU420SP, // YYY...VUVUVU...VUVU, NV21
+        FMT_YUV420SP, // YYY...UVUVUV...UVUV, NV12
+        FMT_YVU420P,  // YYY...VVV...UUU
+        FMT_YUV420P,  // YYY...UUU...VVV
+        FMT_GRAYSCALE,
+        FMT_BGGR6,      // 6-bit Bayer format with a BGGR pattern.
+        FMT_GBRG6,      // 6-bit Bayer format with a GBRG pattern.
+        FMT_GRBG6,      // 6-bit Bayer format with a GRBG pattern.
+        FMT_RGGB6,      // 6-bit Bayer format with a RGGB pattern.
+        FMT_BGGR8,      // 8-bit Bayer format with a BGGR pattern.
+        FMT_GBRG8,      // 8-bit Bayer format with a GBRG pattern.
+        FMT_GRBG8,      // 8-bit Bayer format with a GRBG pattern.
+        FMT_RGGB8,      // 8-bit Bayer format with a RGGB pattern.
+        FMT_BGGR10,     // 10-bit Bayer format with a BGGR pattern.
+        FMT_GBRG10,     // 10-bit Bayer format with a GBRG pattern.
+        FMT_GRBG10,     // 10-bit Bayer format with a GRBG pattern.
+        FMT_RGGB10,     // 10-bit Bayer format with a RGGB pattern.
+        FMT_BGGR12,     // 12-bit Bayer format with a BGGR pattern.
+        FMT_GBRG12,     // 12-bit Bayer format with a GBRG pattern.
+        FMT_GRBG12,     // 12-bit Bayer format with a GRBG pattern.
+        FMT_RGGB12,     // 12-bit Bayer format with a RGGB pattern.
+        FMT_UNCOMPRESSED_MAX,
+
+        // compressed format below, not compressed should define upper
+        FMT_COMPRESSED_MIN,
+        FMT_JPEG,
+        FMT_PNG,
+        FMT_COMPRESSED_MAX,
+
+        FMT_INVALID = 0xFF  // format not valid
+    }
+
+
+

Fit

+

Object fit method

+ + + + + + + + + + + + + +
itemdescribe
valuesFIT_NONE: no object fit, keep original
FIT_FILL: width to new width, height to new height, may be stretch
FIT_CONTAIN: keep aspect ratio, fill blank area with black color
FIT_COVER: keep aspect ratio, crop image to fit new size
FIT_MAX:
+
+

C++ defination code:

+ +
enum Fit
+    {
+        FIT_NONE = -1, // no object fit, keep original
+        FIT_FILL = 0,  // width to new width, height to new height, may be stretch
+        FIT_CONTAIN,   // keep aspect ratio, fill blank area with black color
+        FIT_COVER,     // keep aspect ratio, crop image to fit new size
+        FIT_MAX
+    }
+
+
+

ResizeMethod

+

Resize method

+ + + + + + + + + + + + + +
itemdescribe
valuesNEAREST:
BILINEAR:
BICUBIC:
AREA:
LANCZOS:
HAMMING:
RESIZE_METHOD_MAX:
+
+

C++ defination code:

+ +
enum ResizeMethod
+    {
+        NEAREST = 0,
+        BILINEAR,
+        BICUBIC,
+        AREA,
+        LANCZOS,
+        HAMMING,
+        RESIZE_METHOD_MAX
+    }
+
+
+

ApriltagFamilies

+

Family of apriltag

+ + + + + + + + + + + + + +
itemdescribe
valuesTAG16H5:
TAG25H7:
TAG25H9:
TAG36H10:
TAG36H11:
ARTOOLKIT:
+
+

C++ defination code:

+ +
enum ApriltagFamilies
+    {
+        TAG16H5   = 1,
+        TAG25H7   = 2,
+        TAG25H9   = 4,
+        TAG36H10  = 8,
+        TAG36H11  = 16,
+        ARTOOLKIT = 32
+    }
+
+
+

TemplateMatch

+

Template match method

+ + + + + + + + + + + + + +
itemdescribe
valuesSEARCH_EX: Exhaustive search
SEARCH_DS: Diamond search
+
+

C++ defination code:

+ +
enum TemplateMatch
+    {
+        SEARCH_EX,  // Exhaustive search
+        SEARCH_DS,  // Diamond search
+    }
+
+
+

CornerDetector

+

CornerDetector class

+ + + + + + + + + + + + + +
itemdescribe
valuesCORNER_FAST:
CORNER_AGAST:
+
+

C++ defination code:

+ +
enum CornerDetector
+    {
+        CORNER_FAST,
+        CORNER_AGAST
+    }
+
+
+

EdgeDetector

+

EdgeDetector class

+ + + + + + + + + + + + + +
itemdescribe
valuesEDGE_CANNY:
EDGE_SIMPLE:
+
+

C++ defination code:

+ +
enum EdgeDetector
+    {
+        EDGE_CANNY,
+        EDGE_SIMPLE,
+    }
+
+
+

FlipDir

+

FlipDir

+ + + + + + + + + + + + + +
itemdescribe
valuesX:
Y:
XY:
+
+

C++ defination code:

+ +
enum class FlipDir
+    {
+        X,
+        Y,
+        XY
+    }
+
+
+

QRCodeDecoderType

+

QRCode decode type class

+ + + + + + + + + + + + + +
itemdescribe
valuesQRCODE_DECODER_TYPE_ZBAR:
QRCODE_DECODER_TYPE_QUIRC:
+
+

C++ defination code:

+ +
enum class QRCodeDecoderType {
+        QRCODE_DECODER_TYPE_ZBAR,
+        QRCODE_DECODER_TYPE_QUIRC
+    }
+
+
+

LineType

+

Line type class

+ + + + + + + + + + + + + +
itemdescribe
valuesLINE_NORMAL:
LINE_CROSS:
LINE_T:
LINE_L:
+
+

C++ defination code:

+ +
enum class LineType {
+        LINE_NORMAL,
+        LINE_CROSS,
+        LINE_T,
+        LINE_L,
+    }
+
+
+

Variable

+

fmt_size

+

Image format size in bytes

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
attentionIt's a copy of this variable in MaixPy,
so change it in C++ (e.g. update var in hello function) will not take effect the var inMaixPy.
So we add const for this var to avoid this mistake.
value{
3,
3,
4,
4,
2,
2,
2,
2,
1.5,
1.5,
1.5,
1.5,
1, // grayscale
0.75, // 6-bit Bayer format
0.75, // 6-bit Bayer format
0.75, // 6-bit Bayer format
0.75, // 6-bit Bayer format
1, // 8-bit Bayer format
1, // 8-bit Bayer format
1, // 8-bit Bayer format
1, // 8-bit Bayer format
1.25, // 10-bit Bayer format
1.25, // 10-bit Bayer format
1.25, // 10-bit Bayer format
1.25, // 10-bit Bayer format
1.5, // 12-bit Bayer format
1.5, // 12-bit Bayer format
1.5, // 12-bit Bayer format
1.5, // 12-bit Bayer format
0, // uncompereed_max
0, // compressed_min
1, // jpeg
1, // png
0, // compressed_max
0 // invalid
}
readonlyTrue
+
+

C++ defination code:

+ +
const std::vector<float> fmt_size = {
+        3,
+        3,
+        4,
+        4,
+        2,
+        2,
+        2,
+        2,
+        1.5,
+        1.5,
+        1.5,
+        1.5,
+        1, // grayscale
+        0.75,   // 6-bit Bayer format
+        0.75,   // 6-bit Bayer format
+        0.75,   // 6-bit Bayer format
+        0.75,   // 6-bit Bayer format
+        1,      // 8-bit Bayer format
+        1,      // 8-bit Bayer format
+        1,      // 8-bit Bayer format
+        1,      // 8-bit Bayer format
+        1.25,   // 10-bit Bayer format
+        1.25,   // 10-bit Bayer format
+        1.25,   // 10-bit Bayer format
+        1.25,   // 10-bit Bayer format
+        1.5,    // 12-bit Bayer format
+        1.5,    // 12-bit Bayer format
+        1.5,    // 12-bit Bayer format
+        1.5,    // 12-bit Bayer format
+        0, // uncompereed_max
+        0, // compressed_min
+        1, // jpeg
+        1, // png
+        0, // compressed_max
+        0  // invalid
+        }
+
+
+

fmt_names

+

Image format string

+ + + + + + + + + + + + + + + + + +
itemdescription
value{
"RGB888",
"BGR888",
"RGBA8888",
"BGRA8888",
"RGB565",
"BGR565",
"YUV422SP",
"YUV422P",
"YVU420SP",
"YUV420SP",
"YVU420P",
"YUV420P",
"GRAYSCALE",
"BGGR6",
"GBRG6",
"GRBG6",
"RG6B6",
"BGGR8",
"GBRG8",
"GRBG8",
"RG6B8",
"BGGR10",
"GBRG10",
"GRBG10",
"RG6B10",
"BGGR12",
"GBRG12",
"GRBG12",
"RG6B12",
"UNCOMPRESSED_MAX",
"COMPRESSED_MIN",
"JPEG",
"PNG",
"COMPRESSED_MAX",
"INVALID"
}
readonlyTrue
+
+

C++ defination code:

+ +
const std::vector<std::string> fmt_names = {
+        "RGB888",
+        "BGR888",
+        "RGBA8888",
+        "BGRA8888",
+        "RGB565",
+        "BGR565",
+        "YUV422SP",
+        "YUV422P",
+        "YVU420SP",
+        "YUV420SP",
+        "YVU420P",
+        "YUV420P",
+        "GRAYSCALE",
+        "BGGR6",
+        "GBRG6",
+        "GRBG6",
+        "RG6B6",
+        "BGGR8",
+        "GBRG8",
+        "GRBG8",
+        "RG6B8",
+        "BGGR10",
+        "GBRG10",
+        "GRBG10",
+        "RG6B10",
+        "BGGR12",
+        "GBRG12",
+        "GRBG12",
+        "RG6B12",
+        "UNCOMPRESSED_MAX",
+        "COMPRESSED_MIN",
+        "JPEG",
+        "PNG",
+        "COMPRESSED_MAX",
+        "INVALID"
+        }
+
+
+

COLOR_WHITE

+

Predefined color white

+ + + + + + + + + + + + + + + + + +
itemdescription
valueimage::Color::from_rgb(255, 255, 255)
readonlyTrue
+
+

C++ defination code:

+ +
const image::Color COLOR_WHITE = image::Color::from_rgb(255, 255, 255)
+
+
+

COLOR_BLACK

+

Predefined color black

+ + + + + + + + + + + + + + + + + +
itemdescription
valueimage::Color::from_rgb(0, 0, 0)
readonlyTrue
+
+

C++ defination code:

+ +
const image::Color COLOR_BLACK = image::Color::from_rgb(0, 0, 0)
+
+
+

COLOR_RED

+

Predefined color red

+ + + + + + + + + + + + + + + + + +
itemdescription
valueimage::Color::from_rgb(255, 0, 0)
readonlyTrue
+
+

C++ defination code:

+ +
const image::Color COLOR_RED = image::Color::from_rgb(255, 0, 0)
+
+
+

COLOR_GREEN

+

Predefined color green

+ + + + + + + + + + + + + + + + + +
itemdescription
valueimage::Color::from_rgb(0, 255, 0)
readonlyTrue
+
+

C++ defination code:

+ +
const image::Color COLOR_GREEN = image::Color::from_rgb(0, 255, 0)
+
+
+

COLOR_BLUE

+

Predefined color blue

+ + + + + + + + + + + + + + + + + +
itemdescription
valueimage::Color::from_rgb(0, 0, 255)
readonlyTrue
+
+

C++ defination code:

+ +
const image::Color COLOR_BLUE = image::Color::from_rgb(0, 0, 255)
+
+
+

COLOR_YELLOW

+

Predefined color yellow

+ + + + + + + + + + + + + + + + + +
itemdescription
valueimage::Color::from_rgb(255, 255, 0)
readonlyTrue
+
+

C++ defination code:

+ +
const image::Color COLOR_YELLOW = image::Color::from_rgb(255, 255, 0)
+
+
+

COLOR_PURPLE

+

Predefined color purple

+ + + + + + + + + + + + + + + + + +
itemdescription
valueimage::Color::from_rgb(143, 0, 255)
readonlyTrue
+
+

C++ defination code:

+ +
const image::Color COLOR_PURPLE = image::Color::from_rgb(143, 0, 255)
+
+
+

COLOR_ORANGE

+

Predefined color orange

+ + + + + + + + + + + + + + + + + +
itemdescription
valueimage::Color::from_rgb(255, 127, 0)
readonlyTrue
+
+

C++ defination code:

+ +
const image::Color COLOR_ORANGE = image::Color::from_rgb(255, 127, 0)
+
+
+

COLOR_GRAY

+

Predefined color gray

+ + + + + + + + + + + + + + + + + +
itemdescription
valueimage::Color::from_rgb(127, 127, 127)
readonlyTrue
+
+

C++ defination code:

+ +
const image::Color COLOR_GRAY = image::Color::from_rgb(127, 127, 127)
+
+
+

Function

+

resize_map_pos

+

map point position or rectangle position from one image size to another image size(resize)

+ + + + + + + + + + + + + + + + + +
itemdescription
paramint: h_out target image height
fit: resize method, see maix.image.Fit
x: original point x, or rectagle left-top point's x
y: original point y, or rectagle left-top point's y
w: original rectagle width, can be -1 if not use this arg, default -1.
h: original rectagle height, can be -1 if not use this arg, default -1.
returnlist type, [x, y] if map point, [x, y, w, h] if resize rectangle.
+
+

C++ defination code:

+ +
std::vector<int> resize_map_pos(int w_in, int h_in, int w_out, int h_out, image::Fit fit, int x, int y, int w = -1, int h = -1)
+
+
+

resize_map_pos (overload 1)

+

map point position or rectangle position from this image size to another image size(resize)

+ + + + + + + + + + + + + + + + + +
itemdescription
paramint: h_out target image height
fit: resize method, see maix.image.Fit
x: original point x, or rectagle left-top point's x
y: original point y, or rectagle left-top point's y
w: original rectagle width, can be -1 if not use this arg, default -1.
h: original rectagle height, can be -1 if not use this arg, default -1.
returnlist type, [x, y] if map point, [x, y, w, h] if resize rectangle.
+
+

C++ defination code:

+ +
std::vector<int> resize_map_pos(int w_out, int h_out, image::Fit fit, int x, int y, int w = -1, int h = -1)
+
+
+

resize_map_pos_reverse

+

reverse resize_map_pos method, when we call image.resize method resiz image 'a' to image 'b', we want to known the original position on 'a' whith a knew point on 'b'

+ + + + + + + + + + + + + + + + + +
itemdescription
paramint: h_out image height after resized
fit: resize method, see maix.image.Fit
x: point on resized image x, or rectagle left-top point's x
y: original point y, or rectagle left-top point's y
w: original rectagle width, can be -1 if not use this arg, default -1.
h: original rectagle height, can be -1 if not use this arg, default -1.
returnlist type, [x, y] if map point, [x, y, w, h] if resize rectangle.
+
+

C++ defination code:

+ +
std::vector<int> resize_map_pos_reverse(int w_in, int h_in, int w_out, int h_out, image::Fit fit, int x, int y, int w = -1, int h = -1)
+
+
+

load

+

Load image from file, and convert to Image object

+ + + + + + + + + + + + + + + + + +
itemdescription
parampath: image file path
format: read as this format, if not match, will convert to this format, by default is RGB888
returnImage object, if load failed, will return None(nullptr in C++), so you should care about it.
+
+

C++ defination code:

+ +
image::Image *load(const char *path, image::Format format = image::Format::FMT_RGB888)
+
+
+

from_bytes

+

Create image from bytes

+ + + + + + + + + + + + + + + + + +
itemdescription
paramwidth: image width
height: image height
format: image format
data: image data, if data is None, will malloc memory for image data
If the image is in jpeg format, data must be filled in.
copy: if true and data is not None, will copy data to new buffer, else will use data directly. default is true to avoid memory leak.
Use it carefully!!!
returnImage object
+
+

C++ defination code:

+ +
image::Image *from_bytes(int width, int height, image::Format format, Bytes *data, bool copy = true)
+
+
+

load_font

+

Load font from file

+ + + + + + + + + + + + + + + + + +
itemdescription
paramname: font name, used to identify font
path: font file path, support ttf, ttc, otf
size: font size, font height, by default is 16
returnerror code, err::ERR_NONE is ok, other is error
+
+

C++ defination code:

+ +
err::Err load_font(const std::string &name, const char *path, int size = 16)
+
+
+

set_default_font

+

Set default font, if not call this method, default is hershey_plain

+ + + + + + + + + + + + + + + + + +
itemdescription
paramname: font name, supported names can be get by fonts()
returnerror code, err::ERR_NONE is ok, other is error
+
+

C++ defination code:

+ +
err::Err set_default_font(const std::string &name)
+
+
+

fonts

+

Get all loaded fonts

+ + + + + + + + + + + + + +
itemdescription
returnall loaded fonts, string list type
+
+

C++ defination code:

+ +
std::vector<std::string> *fonts()
+
+
+

string_size

+

Get text rendered width and height

+ + + + + + + + + + + + + + + + + +
itemdescription
paramstring: text content
scale: font scale, by default(value is 1)
thickness: text thickness(line width), by default(value is 1)
returntext rendered width and height, [width, height]
+
+

C++ defination code:

+ +
image::Size string_size(std::string string, float scale = 1, int thickness = 1, const std::string &font = "")
+
+
+

Class

+

QRCodeDetector

+

QRCodeDetector class

+
+

C++ defination code:

+ +
class QRCodeDetector
+
+
+

__init__

+

QRCodeDetector constructor.\nUse npu to accelerate the speed of QR code scanning, note that this object will occupy npu resources

+ + + + + + + + + + + + + + + + + +
itemdescription
typefunc
staticFalse
+
+

C++ defination code:

+ +
QRCodeDetector()
+
+
+

detect

+

Finds all qrcodes in the image.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramimg: The image to find qrcodes.
roi: The region of interest, input in the format of (x, y, w, h), x and y are the coordinates of the upper left corner, w and h are the width and height of roi.
default is None, means whole image.
decoder_type: Select the QR code decoding method. Choosing QRCODE_DECODER_TYPE_QUIRC allows for retrieving QR code version, ECC level, mask, data type, and other details,
though it may decode slower at lower resolutions. Opting for QRCODE_DECODER_TYPE_ZBAR enables faster decoding at lower resolutions but may slow down at higher resolutions,
providing only the QR code content and position information. default is QRCODE_DECODER_TYPE_ZBAR.
returnReturns the qrcodes of the image
staticFalse
+
+

C++ defination code:

+ +
std::vector<image::QRCode> detect(image::Image *img, std::vector<int> roi = std::vector<int>(), image::QRCodeDecoderType decoder_type = image::QRCodeDecoderType::QRCODE_DECODER_TYPE_ZBAR)
+
+
+

Size

+

Image size type

+
+

C++ defination code:

+ +
class Size
+
+
+

__init__

+

Construct a new Size object

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramwidth: image width
height: image height
staticFalse
+
+

C++ defination code:

+ +
Size(int width = 0, int height = 0)
+
+
+

width

+

width of size

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramwidth: set new width, if not set, only return current width
staticFalse
+
+

C++ defination code:

+ +
int width(int width = -1)
+
+
+

height

+

height of size

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramheight: set new height, if not set, only return current height
staticFalse
+
+

C++ defination code:

+ +
int height(int height = -1)
+
+
+

[]

+

Subscript operator

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramindex: 0 for width, 1 for height
returnint& width or height
staticFalse
+
+

C++ defination code:

+ +
int &operator[](int index)
+
+
+

__str__

+

to string

+ + + + + + + + + + + + + + + + + +
itemdescription
typefunc
staticFalse
+
+

C++ defination code:

+ +
std::string __str__()
+
+
+

Line

+

Line class

+
+

C++ defination code:

+ +
class Line
+
+
+

__init__

+

Line constructor

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramx1: coordinate x1 of the straight line
y1: coordinate y1 of the straight line
x2: coordinate x2 of the straight line
y2: coordinate y2 of the straight line
magnitude: magnitude of the straight line after Hough transformation
theta: angle of the straight line after Hough transformation
rho: p-value of the straight line after Hough transformation
staticFalse
+
+

C++ defination code:

+ +
Line(int x1, int y1, int x2, int y2, int magnitude = 0, int theta = 0, int rho = 0)
+
+
+

__getitem__

+

Subscript operator

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramindex: [0] get x1 of line
[1] get y1 of line
[2] get x2 of line
[3] get y2 of line
[4] get length of line
[5] get magnitude of the straight line after Hough transformation
[6] get angle of the straight line after Hough transformation (0-179 degrees)
[7] get p-value of the straight line after Hough transformation
returnint&
staticFalse
+
+

C++ defination code:

+ +
int &__getitem__(int index)
+
+
+

x1

+

get x1 of line

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnreturn x1 of the line, type is int
staticFalse
+
+

C++ defination code:

+ +
int x1()
+
+
+

y1

+

get y1 of line

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnreturn y1 of the line, type is int
staticFalse
+
+

C++ defination code:

+ +
int y1()
+
+
+

x2

+

get x2 of line

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnreturn x2 of the line, type is int
staticFalse
+
+

C++ defination code:

+ +
int x2()
+
+
+

y2

+

get y2 of line

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnreturn y2 of the line, type is int
staticFalse
+
+

C++ defination code:

+ +
int y2()
+
+
+

length

+

get length of line

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnreturn length of the line, type is int
staticFalse
+
+

C++ defination code:

+ +
int length()
+
+
+

magnitude

+

get magnitude of the straight line after Hough transformation

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnreturn magnitude, type is int
staticFalse
+
+

C++ defination code:

+ +
int magnitude()
+
+
+

theta

+

get angle of the straight line after Hough transformation (0-179 degrees)

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnreturn angle, type is int
staticFalse
+
+

C++ defination code:

+ +
int theta()
+
+
+

rho

+

get p-value of the straight line after Hough transformation

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnreturn p-value, type is int
staticFalse
+
+

C++ defination code:

+ +
int rho()
+
+
+

Rect

+

Rect class

+
+

C++ defination code:

+ +
class Rect
+
+
+

__init__

+

Rect constructor

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramcorners: corners of rect
x: coordinate x of the straight line
y: coordinate y of the straight line
w: coordinate w of the straight line
h: coordinate h of the straight line
magnitude: magnitude of the straight line after Hough transformation
staticFalse
+
+

C++ defination code:

+ +
Rect(std::vector<std::vector<int>> &corners, int x, int y, int w, int h, int magnitude = 0)
+
+
+

__getitem__

+

Subscript operator

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramindex: [0] get x of rect
[1] get y of rect
[2] get w of rect
[3] get h of rect
[4] get magnitude of the straight line after Hough transformation
returnint&
staticFalse
+
+

C++ defination code:

+ +
int &__getitem__(int index)
+
+
+

corners

+

get corners of rect

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnreturn the coordinate of the rect.
staticFalse
+
+

C++ defination code:

+ +
std::vector<std::vector<int>> corners()
+
+
+

rect

+

get rectangle of rect

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnreturn the rectangle of the rect. format is {x, y, w, h}, type is std::vector
staticFalse
+
+

C++ defination code:

+ +
std::vector<int> rect()
+
+
+

x

+

get x of rect

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnreturn x of the rect, type is int
staticFalse
+
+

C++ defination code:

+ +
int x()
+
+
+

y

+

get y of rect

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnreturn y of the rect, type is int
staticFalse
+
+

C++ defination code:

+ +
int y()
+
+
+

w

+

get w of rect

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnreturn w of the rect, type is int
staticFalse
+
+

C++ defination code:

+ +
int w()
+
+
+

h

+

get h of rect

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnreturn h of the rect, type is int
staticFalse
+
+

C++ defination code:

+ +
int h()
+
+
+

magnitude

+

get magnitude of the straight line after Hough transformation

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnreturn magnitude, type is int
staticFalse
+
+

C++ defination code:

+ +
int magnitude()
+
+
+

Circle

+

circle class

+
+

C++ defination code:

+ +
class Circle
+
+
+

__init__

+

Circle constructor

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramx: coordinate x of the circle
y: coordinate y of the circle
r: coordinate r of the circle
magnitude: coordinate y2 of the straight line
staticFalse
+
+

C++ defination code:

+ +
Circle(int x, int y, int r, int magnitude)
+
+
+

__getitem__

+

Subscript operator

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramindex: [0] get x of circle
[1] get y of circle
[2] get r of circle
[3] get magnitude of the circle after Hough transformation
returnint&
staticFalse
+
+

C++ defination code:

+ +
int &__getitem__(int index)
+
+
+

x

+

get x of circle

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnreturn x of the circle, type is int
staticFalse
+
+

C++ defination code:

+ +
int x()
+
+
+

y

+

get y of circle

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnreturn y of the circle, type is int
staticFalse
+
+

C++ defination code:

+ +
int y()
+
+
+

r

+

get r of circle

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnreturn r of the circle, type is int
staticFalse
+
+

C++ defination code:

+ +
int r()
+
+
+

magnitude

+

get magnitude of the circle after Hough transformation

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnreturn magnitude, type is int
staticFalse
+
+

C++ defination code:

+ +
int magnitude()
+
+
+

Blob

+

Blob class

+
+

C++ defination code:

+ +
class Blob
+
+
+

__init__

+

Blob constructor

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramrect: blob rect, type is std::vector
corners: blob corners, type is std::vector<std::vector>
mini_corners: blob mini_corners, type is std::vector<std::vector>
cx: blob center x, type is float
cy: blob center y, type is float
pixels: blob pixels, type is int
rotation: blob rotation, type is float
code: blob code, type is int
count: blob count, type is int
perimeter: blob perimeter, type is int
roundness: blob roundness, type is float
x_hist_bins: blob x_hist_bins, type is std::vector
y_hist_bins: blob y_hist_bins, type is std::vector
staticFalse
+
+

C++ defination code:

+ +
Blob(std::vector<int> &rect, std::vector<std::vector<int>> &corners, std::vector<std::vector<int>> &mini_corners,float cx, float cy, int pixels, float rotation, int code, int count, int perimeter, float roundness, std::vector<int> &x_hist_bins, std::vector<int> &y_hist_bins)
+
+
+

__getitem__

+

Subscript operator

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramindex: [0] Returns the blob’s bounding box x coordinate
[1] Returns the blob’s bounding box y coordinate
[2] Returns the blob’s bounding box w coordinate
[3] Returns the blob’s bounding box h coordinate
[4] Returns the number of pixels that are part of this blob
[5] Returns the centroid x position of the blob
[6] Returns the centroid y position of the blob
returnint& width or height
staticFalse
+
+

C++ defination code:

+ +
int &__getitem__(int index)
+
+
+

corners

+

get blob corners

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnReturns a list of 4 (x,y) tuples of the 4 corners of the object.
(x0, y0)___________(x1, y1)



___________
(x3, y3) (x2, y2)
note: the order of corners may change
staticFalse
+
+

C++ defination code:

+ +
std::vector<std::vector<int>> corners()
+
+
+

mini_corners

+

get blob mini corners

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnReturns a list of 4 (x,y) tuples of the 4 corners than bound the min area rectangle of the blob.
(x0, y0)___________(x1, y1)



___________
(x3, y3) (x2, y2)
note: the order of corners may change
staticFalse
+
+

C++ defination code:

+ +
std::vector<std::vector<int>> mini_corners()
+
+
+

rect

+

get blob rect

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnReturns the center coordinates and width and height of the rectangle. format is (x, y, w, h)
w
(x, y) ___________

h

___________
staticFalse
+
+

C++ defination code:

+ +
std::vector<int> rect()
+
+
+

x

+

get blob x of the upper left coordinate

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnReturns the x coordinate of the upper left corner of the rectangle.
staticFalse
+
+

C++ defination code:

+ +
int x()
+
+
+

y

+

get blob y of the upper left coordinate

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnReturns the y coordinate of the upper left corner of the rectangle.
staticFalse
+
+

C++ defination code:

+ +
int y()
+
+
+

w

+

get blob width

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnReturns the blob’s bounding box w coordinate
staticFalse
+
+

C++ defination code:

+ +
int w()
+
+
+

h

+

get blob height

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnReturns the blob’s bounding box h coordinate
staticFalse
+
+

C++ defination code:

+ +
int h()
+
+
+

pixels

+

get blob pixels

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnReturns the number of pixels that are part of this blob.
staticFalse
+
+

C++ defination code:

+ +
int pixels()
+
+
+

cx

+

get blob center x

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnReturns the centroid x position of the blob
staticFalse
+
+

C++ defination code:

+ +
int cx()
+
+
+

cy

+

get blob center y

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnReturns the centroid y position of the blob
staticFalse
+
+

C++ defination code:

+ +
int cy()
+
+
+

cxf

+

get blob center x

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnReturns the centroid x position of the blob
staticFalse
+
+

C++ defination code:

+ +
float cxf()
+
+
+

cyf

+

get blob center y

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnReturns the centroid y position of the blob
staticFalse
+
+

C++ defination code:

+ +
float cyf()
+
+
+

rotation

+

get blob rotation

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnReturns the rotation of the blob in radians (float). If the blob is like a pencil or pen this value will be unique for 0-180 degrees.
staticFalse
+
+

C++ defination code:

+ +
float rotation()
+
+
+

rotation_rad

+

get blob rotation_rad

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnReturns the rotation of the blob in radians
staticFalse
+
+

C++ defination code:

+ +
float rotation_rad()
+
+
+

rotation_deg

+

get blob rotation_deg

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnReturns the rotation of the blob in degrees.
staticFalse
+
+

C++ defination code:

+ +
int rotation_deg()
+
+
+

code

+

get blob code

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnReturns a 32-bit binary number with a bit set in it for each color threshold that’s part of this blob
staticFalse
+
+

C++ defination code:

+ +
int code()
+
+
+

count

+

get blob count

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnReturns the number of blobs merged into this blob.
staticFalse
+
+

C++ defination code:

+ +
int count()
+
+
+

perimeter

+

get blob merge_cnt

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnReturns the number of pixels on this blob’s perimeter.
staticFalse
+
+

C++ defination code:

+ +
int perimeter()
+
+
+

roundness

+

get blob roundness

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnReturns a value between 0 and 1 representing how round the object is
staticFalse
+
+

C++ defination code:

+ +
float roundness()
+
+
+

elongation

+

get blob elongation

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnReturnsa value between 0 and 1 representing how long (not round) the object is
staticFalse
+
+

C++ defination code:

+ +
float elongation()
+
+
+

area

+

get blob area

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnReturns the area of the bounding box around the blob
staticFalse
+
+

C++ defination code:

+ +
int area()
+
+
+

density

+

get blob density

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnReturns the density ratio of the blob
staticFalse
+
+

C++ defination code:

+ +
float density()
+
+
+

extent

+

Alias for blob.density()

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnReturns the density ratio of the blob
staticFalse
+
+

C++ defination code:

+ +
float extent()
+
+
+

compactness

+

get blob compactness

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnReturns the compactness ratio of the blob
staticFalse
+
+

C++ defination code:

+ +
float compactness()
+
+
+

solidity

+

get blob solidity

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnReturns the solidity ratio of the blob
staticFalse
+
+

C++ defination code:

+ +
float solidity()
+
+
+

convexity

+

get blob convexity

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnReturns a value between 0 and 1 representing how convex the object is
staticFalse
+
+

C++ defination code:

+ +
float convexity()
+
+
+

x_hist_bins

+

get blob x_hist_bins

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnReturns the x_hist_bins of the blob
staticFalse
+
+

C++ defination code:

+ +
std::vector<int> x_hist_bins()
+
+
+

y_hist_bins

+

get blob y_hist_bins

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnReturns the y_hist_bins of the blob
staticFalse
+
+

C++ defination code:

+ +
std::vector<int> y_hist_bins()
+
+
+

major_axis_line

+

get blob major_axis_line

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnReturns a line tuple (x1, y1, x2, y2) of the minor axis of the blob.
staticFalse
+
+

C++ defination code:

+ +
std::vector<int> major_axis_line()
+
+
+

minor_axis_line

+

get blob minor_axis_line

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnReturns a line tuple (x1, y1, x2, y2) of the minor axis of the blob.
staticFalse
+
+

C++ defination code:

+ +
std::vector<int> minor_axis_line()
+
+
+

enclosing_circle

+

get blob enclosing_circle

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnReturns a circle tuple (x, y, r) of the circle that encloses the min area rectangle of a blob.
staticFalse
+
+

C++ defination code:

+ +
std::vector<int> enclosing_circle()
+
+
+

enclosed_ellipse

+

get blob enclosed_ellipse

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnReturns an ellipse tuple (x, y, rx, ry, rotation) of the ellipse that fits inside of the min area rectangle of a blob.
staticFalse
+
+

C++ defination code:

+ +
std::vector<int> enclosed_ellipse()
+
+
+

QRCode

+

QRCode class

+
+

C++ defination code:

+ +
class QRCode
+
+
+

__init__

+

QRCode constructor

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramrect: rect of corners, type is std::vector
corners: corners of QRCode
payload: payload of the QRCode
version: version of the QRCode
ecc_level: ecc_level of the QRCode
mask: mask of the QRCode
data_type: data_type of the QRCode
eci: eci of the QRCode
staticFalse
+
+

C++ defination code:

+ +
QRCode(std::vector<int> &rect, std::vector<std::vector<int>> &corners, std::string &payload, int version, int ecc_level, int mask, int data_type, int eci)
+
+
+

__getitem__

+

Subscript operator

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramindex: [0] Returns the qrcode’s bounding box x coordinate
[1] Returns the qrcode’s bounding box y coordinate
[2] Returns the qrcode’s bounding box w coordinate
[3] Returns the qrcode’s bounding box h coordinate
[4] Not support this index, try to use payload() method
[5] Returns the version of qrcode
[6] Returns the error correction level of qrcode
[7] Returns the mask of qrcode
[8] Returns the datatype of qrcode
[9] Returns the eci of qrcode
returnint&
staticFalse
+
+

C++ defination code:

+ +
int &__getitem__(int index)
+
+
+

corners

+

get coordinate of QRCode

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnreturn the coordinate of the QRCode.
staticFalse
+
+

C++ defination code:

+ +
std::vector<std::vector<int>> corners()
+
+
+

rect

+

get rectangle of QRCode

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnreturn the rectangle of the QRCode. format is {x, y, w, h}, type is std::vector
staticFalse
+
+

C++ defination code:

+ +
std::vector<int> rect()
+
+
+

x

+

get x of QRCode

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnreturn x of the QRCode, type is int
staticFalse
+
+

C++ defination code:

+ +
int x()
+
+
+

y

+

get y of QRCode

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnreturn y of the QRCode, type is int
staticFalse
+
+

C++ defination code:

+ +
int y()
+
+
+

w

+

get w of QRCode

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnreturn w of the QRCode, type is int
staticFalse
+
+

C++ defination code:

+ +
int w()
+
+
+

h

+

get h of QRCode

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnreturn h of the QRCode, type is int
staticFalse
+
+

C++ defination code:

+ +
int h()
+
+
+

payload

+

get QRCode payload

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnreturn area of the QRCode
staticFalse
+
+

C++ defination code:

+ +
std::string payload()
+
+
+

version

+

get QRCode version

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnreturn version of the QRCode
staticFalse
+
+

C++ defination code:

+ +
int version()
+
+
+

ecc_level

+

get QRCode error correction level

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnreturn error correction level of the QRCode
staticFalse
+
+

C++ defination code:

+ +
int ecc_level()
+
+
+

mask

+

get QRCode mask

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnreturn mask of the QRCode
staticFalse
+
+

C++ defination code:

+ +
int mask()
+
+
+

data_type

+

get QRCode dataType

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnreturn mask of the QRCode
staticFalse
+
+

C++ defination code:

+ +
int data_type()
+
+
+

eci

+

get QRCode eci

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnreturn data of the QRCode
staticFalse
+
+

C++ defination code:

+ +
int eci()
+
+
+

is_numeric

+

check QRCode is numeric

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnreturn true if the result type of the QRCode is numeric
staticFalse
+
+

C++ defination code:

+ +
bool is_numeric()
+
+
+

is_alphanumeric

+

check QRCode is alphanumeric

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnreturn true if the result type of the QRCode is alphanumeric
staticFalse
+
+

C++ defination code:

+ +
bool is_alphanumeric()
+
+
+

is_binary

+

check QRCode is binary

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnreturn true if the result type of the QRCode is binary
staticFalse
+
+

C++ defination code:

+ +
bool is_binary()
+
+
+

is_kanji

+

check QRCode is kanji

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnreturn true if the result type of the QRCode is kanji
staticFalse
+
+

C++ defination code:

+ +
bool is_kanji()
+
+
+

AprilTag

+

AprilTag class

+
+

C++ defination code:

+ +
class AprilTag
+
+
+

__init__

+

AprilTag constructor

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramrect: Inlucdes the top-left corner and the width and height of the rectangle. format is {x, y, w, h}, type is std::vector
corners: Includes the four corners of the rectangle. format is {{x0, y0}, {x1, y1}, {x2, y2}, {x3, y3}}, type is std::vector<std::vector>
id: The id of the AprilTag
famliy: The family of the AprilTag
centroid_x: The x coordinate of the center of the AprilTag
centroid_y: The y coordinate of the center of the AprilTag
rotation: The rotation of the AprilTag
decision_margin: The decision_margin of the AprilTag
hamming: The hamming of the AprilTag
goodness: The goodness of the AprilTag
x_translation: The x_translation of the AprilTag
y_translation: The y_translation of the AprilTag
z_translation: The z_translation of the AprilTag
x_rotation: The x_rotation of the AprilTag
y_rotation: The y_rotation of the AprilTag
z_rotation: The z_rotation of the AprilTag
staticFalse
+
+

C++ defination code:

+ +
AprilTag(std::vector<int> &rect, std::vector<std::vector<int>> &corners, int id, int famliy, float centroid_x, float centroid_y, float rotation, float decision_margin, int hamming, float goodness, float x_translation, float y_translation, float z_translation, float x_rotation, float y_rotation, float z_rotation)
+
+
+

__getitem__

+

Subscript operator

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramindex: [0] Returns the apriltag’s bounding box x coordinate
[1] Returns the apriltag’s bounding box y coordinate
[2] Returns the apriltag’s bounding box w coordinate
[3] Returns the apriltag’s bounding box h coordinate
[4] Returns the apriltag’s id
[5] Returns the apriltag’s family
[6] Not support
[7] Not support
[8] Not support
[9] Not support
[10] Returns the apriltag’s hamming
[11] Not support
[12] Not support
[13] Not support
[14] Not support
[15] Not support
[16] Not support
[17] Not support
returnint&
staticFalse
+
+

C++ defination code:

+ +
int &__getitem__(int index)
+
+
+

corners

+

get coordinate of AprilTag

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnreturn the coordinate of the AprilTag.
staticFalse
+
+

C++ defination code:

+ +
std::vector<std::vector<int>> corners()
+
+
+

rect

+

get rectangle of AprilTag

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnreturn the rectangle of the AprilTag. format is {x, y, w, h}, type is std::vector
staticFalse
+
+

C++ defination code:

+ +
std::vector<int> rect()
+
+
+

x

+

get x of AprilTag

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnreturn x of the AprilTag, type is int
staticFalse
+
+

C++ defination code:

+ +
int x()
+
+
+

y

+

get y of AprilTag

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnreturn y of the AprilTag, type is int
staticFalse
+
+

C++ defination code:

+ +
int y()
+
+
+

w

+

get w of AprilTag

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnreturn w of the AprilTag, type is int
staticFalse
+
+

C++ defination code:

+ +
int w()
+
+
+

h

+

get h of AprilTag

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnreturn h of the AprilTag, type is int
staticFalse
+
+

C++ defination code:

+ +
int h()
+
+
+

id

+

get id of AprilTag

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnreturn id of the AprilTag, type is int
staticFalse
+
+

C++ defination code:

+ +
int id()
+
+
+

family

+

get family of AprilTag

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnreturn family of the AprilTag, type is int
staticFalse
+
+

C++ defination code:

+ +
int family()
+
+
+

cx

+

get cx of AprilTag

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnreturn cx of the AprilTag, type is int
staticFalse
+
+

C++ defination code:

+ +
int cx()
+
+
+

cxf

+

get cxf of AprilTag

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnreturn cxf of the AprilTag, type is float
staticFalse
+
+

C++ defination code:

+ +
float cxf()
+
+
+

cy

+

get cy of AprilTag

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnreturn cy of the AprilTag, type is int
staticFalse
+
+

C++ defination code:

+ +
int cy()
+
+
+

cyf

+

get cyf of AprilTag

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnreturn cyf of the AprilTag, type is float
staticFalse
+
+

C++ defination code:

+ +
float cyf()
+
+
+

rotation

+

get rotation of AprilTag

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnreturn rotation of the AprilTag, type is float
staticFalse
+
+

C++ defination code:

+ +
float rotation()
+
+
+

decision_margin

+

Get decision_margin of AprilTag

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnReturns the quality of the apriltag match (0.0 - 1.0) where 1.0 is the best.
staticFalse
+
+

C++ defination code:

+ +
float decision_margin()
+
+
+

hamming

+

get hamming of AprilTag

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnReturns the number of accepted bit errors for this tag.
return 0, means 0 bit errors will be accepted.
1 is TAG25H7, means up to 1 bit error may be accepted
2 is TAG25H9, means up to 3 bit errors may be accepted
3 is TAG36H10, means up to 3 bit errors may be accepted
4 is TAG36H11, means up to 4 bit errors may be accepted
5 is ARTOOLKIT, means 0 bit errors will be accepted
staticFalse
+
+

C++ defination code:

+ +
int hamming()
+
+
+

goodness

+

get goodness of AprilTag

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnreturn goodness of the AprilTag, type is float
Note: This value is always 0.0 for now.
staticFalse
+
+

C++ defination code:

+ +
float goodness()
+
+
+

x_translation

+

get x_translation of AprilTag

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnreturn x_translation of the AprilTag, type is float
staticFalse
+
+

C++ defination code:

+ +
float x_translation()
+
+
+

y_translation

+

get y_translation of AprilTag

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnreturn y_translation of the AprilTag, type is float
staticFalse
+
+

C++ defination code:

+ +
float y_translation()
+
+
+

z_translation

+

get z_translation of AprilTag

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnreturn z_translation of the AprilTag, type is float
staticFalse
+
+

C++ defination code:

+ +
float z_translation()
+
+
+

x_rotation

+

get x_rotation of AprilTag

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnreturn x_rotation of the AprilTag, type is float
staticFalse
+
+

C++ defination code:

+ +
float x_rotation()
+
+
+

y_rotation

+

get y_rotation of AprilTag

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnreturn y_rotation of the AprilTag, type is float
staticFalse
+
+

C++ defination code:

+ +
float y_rotation()
+
+
+

z_rotation

+

get z_rotation of AprilTag

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnreturn z_rotation of the AprilTag, type is float
staticFalse
+
+

C++ defination code:

+ +
float z_rotation()
+
+
+

DataMatrix

+

DataMatrix class

+
+

C++ defination code:

+ +
class DataMatrix
+
+
+

__init__

+

DataMatrix constructor

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramrect: Inlucdes the top-left corner and the width and height of the rectangle. format is {x, y, w, h}, type is std::vector
corners: Includes the four corners of the rectangle. format is {{x0, y0}, {x1, y1}, {x2, y2}, {x3, y3}}, type is std::vector<std::vector>
payload: The payload of the DataMatrix
rotation: The rotation of the DataMatrix
rows: The rows of the DataMatrix
columns: The columns of the DataMatrix
capacity: The capacity of the DataMatrix
padding: The padding of the DataMatrix
staticFalse
+
+

C++ defination code:

+ +
DataMatrix(std::vector<int> &rect, std::vector<std::vector<int>> &corners, std::string &payload, float rotation, int rows, int columns, int capacity, int padding)
+
+
+

__getitem__

+

Subscript operator

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramindex: [0] get x of DataMatrix
[1] get y of DataMatrix
[2] get w of DataMatrix
[3] get h of DataMatrix
[4] Not support this index, try to use payload() method
[5] Not support this index, try to use rotation() method
[6] get rows of DataMatrix
[7] get columns of DataMatrix
[8] get capacity of DataMatrix
[9] get padding of DataMatrix
returnint&
staticFalse
+
+

C++ defination code:

+ +
int &__getitem__(int index)
+
+
+

corners

+

get coordinate of DataMatrix

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnreturn the coordinate of the DataMatrix.
staticFalse
+
+

C++ defination code:

+ +
std::vector<std::vector<int>> corners()
+
+
+

rect

+

get rectangle of DataMatrix

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnreturn the rectangle of the DataMatrix. format is {x, y, w, h}, type is std::vector
staticFalse
+
+

C++ defination code:

+ +
std::vector<int> rect()
+
+
+

x

+

get x of DataMatrix

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnreturn x of the DataMatrix, type is int
staticFalse
+
+

C++ defination code:

+ +
int x()
+
+
+

y

+

get y of DataMatrix

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnreturn y of the DataMatrix, type is int
staticFalse
+
+

C++ defination code:

+ +
int y()
+
+
+

w

+

get w of DataMatrix

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnreturn w of the DataMatrix, type is int
staticFalse
+
+

C++ defination code:

+ +
int w()
+
+
+

h

+

get h of DataMatrix

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnreturn h of the DataMatrix, type is int
staticFalse
+
+

C++ defination code:

+ +
int h()
+
+
+

payload

+

get payload of DataMatrix

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnreturn payload of the DataMatrix, type is std::string
staticFalse
+
+

C++ defination code:

+ +
std::string payload()
+
+
+

rotation

+

get rotation of DataMatrix

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnreturn rotation of the DataMatrix, type is float
staticFalse
+
+

C++ defination code:

+ +
float rotation()
+
+
+

rows

+

get rows of DataMatrix

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnreturn rows of the DataMatrix, type is int
staticFalse
+
+

C++ defination code:

+ +
int rows()
+
+
+

columns

+

get columns of DataMatrix

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnreturn columns of the DataMatrix, type is int
staticFalse
+
+

C++ defination code:

+ +
int columns()
+
+
+

capacity

+

get capacity of DataMatrix

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnreturns how many characters could fit in this data matrix, type is int
staticFalse
+
+

C++ defination code:

+ +
int capacity()
+
+
+

padding

+

get padding of DataMatrix

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnreturns how many unused characters are in this data matrix, type is int
staticFalse
+
+

C++ defination code:

+ +
int padding()
+
+
+

BarCode

+

BarCode class

+
+

C++ defination code:

+ +
class BarCode
+
+
+

__init__

+

BarCode constructor

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramrect: Inlucdes the top-left corner and the width and height of the rectangle. format is {x, y, w, h}, type is std::vector
corners: Includes the four corners of the rectangle. format is {{x0, y0}, {x1, y1}, {x2, y2}, {x3, y3}}, type is std::vector<std::vector>
payload: The payload of the BarCode
type: The type of the BarCode
rotation: The rotation of the BarCode
quality: The quality of the BarCode
staticFalse
+
+

C++ defination code:

+ +
BarCode(std::vector<int> &rect, std::vector<std::vector<int>> &corners, std::string &payload, int type, float rotation, int quality)
+
+
+

__getitem__

+

Subscript operator

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramindex: [0] get x of BarCode
[1] get y of BarCode
[2] get w of BarCode
[3] get h of BarCode
[4] Not support this index, try to use payload() method
[5] get type of BarCode
[6] Not support this index, try to use rotation() method
[7] get quality of BarCode
returnint&
staticFalse
+
+

C++ defination code:

+ +
int &__getitem__(int index)
+
+
+

corners

+

get coordinate of BarCode

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnreturn the coordinate of the BarCode.
staticFalse
+
+

C++ defination code:

+ +
std::vector<std::vector<int>> corners()
+
+
+

rect

+

get rectangle of BarCode

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnreturn the rectangle of the BarCode. format is {x, y, w, h}, type is std::vector
staticFalse
+
+

C++ defination code:

+ +
std::vector<int> rect()
+
+
+

x

+

get x of BarCode

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnreturn x of the BarCode, type is int
staticFalse
+
+

C++ defination code:

+ +
int x()
+
+
+

y

+

get y of BarCode

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnreturn y of the BarCode, type is int
staticFalse
+
+

C++ defination code:

+ +
int y()
+
+
+

w

+

get w of BarCode

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnreturn w of the BarCode, type is int
staticFalse
+
+

C++ defination code:

+ +
int w()
+
+
+

h

+

get h of BarCode

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnreturn h of the BarCode, type is int
staticFalse
+
+

C++ defination code:

+ +
int h()
+
+
+

payload

+

get payload of BarCode

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnreturn payload of the BarCode, type is std::string
staticFalse
+
+

C++ defination code:

+ +
std::string payload()
+
+
+

type

+

get type of BarCode

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnreturn type of the BarCode, type is int
staticFalse
+
+

C++ defination code:

+ +
int type()
+
+
+

rotation

+

get rotation of BarCode

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnreturn rotation of the BarCode, type is float. FIXME: always return 0.0
staticFalse
+
+

C++ defination code:

+ +
float rotation()
+
+
+

quality

+

get quality of BarCode

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnreturn quality of the BarCode, type is int
staticFalse
+
+

C++ defination code:

+ +
int quality()
+
+
+

Statistics

+

Statistics class

+
+

C++ defination code:

+ +
class Statistics
+
+
+

__init__

+

Statistics constructor

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramformat: The statistics source image format
l_statistics: The statistics of the L channel. format is {mean, median, mode, std_dev, min, max, lq, uq}, type is std::vector
a_statistics: The statistics of the A channel. format is {mean, median, mode, std_dev, min, max, lq, uq}, type is std::vector
b_statistics: The statistics of the B channel. format is {mean, median, mode, std_dev, min, max, lq, uq}, type is std::vector
staticFalse
+
+

C++ defination code:

+ +
Statistics(image::Format format, std::vector<int> &l_statistics, std::vector<int> &a_statistics, std::vector<int> &b_statistics)
+
+
+

__getitem__

+

Subscript operator

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramindex: array index
returnint&
staticFalse
+
+

C++ defination code:

+ +
int &__getitem__(int index)
+
+
+

format

+

get format of Statistics source image

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnreturn format of the Statistics source image, type is image::Format
staticFalse
+
+

C++ defination code:

+ +
image::Format format()
+
+
+

l_mean

+

get L channel mean

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnreturn L channel mean, type is int
staticFalse
+
+

C++ defination code:

+ +
int l_mean()
+
+
+

l_median

+

get L channel median

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnreturn L channel median, type is int
staticFalse
+
+

C++ defination code:

+ +
int l_median()
+
+
+

l_mode

+

get L channel mode

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnreturn L channel mode, type is int
staticFalse
+
+

C++ defination code:

+ +
int l_mode()
+
+
+

l_std_dev

+

get L channel std_dev

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnreturn L channel std_dev, type is int
staticFalse
+
+

C++ defination code:

+ +
int l_std_dev()
+
+
+

l_min

+

get L channel min

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnreturn L channel min, type is int
staticFalse
+
+

C++ defination code:

+ +
int l_min()
+
+
+

l_max

+

get L channel max

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnreturn L channel max, type is int
staticFalse
+
+

C++ defination code:

+ +
int l_max()
+
+
+

l_lq

+

get L channel lq

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnreturn L channel lq, type is int
staticFalse
+
+

C++ defination code:

+ +
int l_lq()
+
+
+

l_uq

+

get L channel uq

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnreturn L channel uq, type is int
staticFalse
+
+

C++ defination code:

+ +
int l_uq()
+
+
+

a_mean

+

get A channel mean

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnreturn A channel mean, type is int
staticFalse
+
+

C++ defination code:

+ +
int a_mean()
+
+
+

a_median

+

get A channea median

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnreturn A channel median, type is int
staticFalse
+
+

C++ defination code:

+ +
int a_median()
+
+
+

a_mode

+

get A channel mode

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnreturn A channel mode, type is int
staticFalse
+
+

C++ defination code:

+ +
int a_mode()
+
+
+

a_std_dev

+

get A channel std_dev

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnreturn A channel std_dev, type is int
staticFalse
+
+

C++ defination code:

+ +
int a_std_dev()
+
+
+

a_min

+

get A channel min

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnreturn A channel min, type is int
staticFalse
+
+

C++ defination code:

+ +
int a_min()
+
+
+

a_max

+

get A channel max

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnreturn A channel max, type is int
staticFalse
+
+

C++ defination code:

+ +
int a_max()
+
+
+

a_lq

+

get A channel lq

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnreturn A channel lq, type is int
staticFalse
+
+

C++ defination code:

+ +
int a_lq()
+
+
+

a_uq

+

get A channel uq

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnreturn A channel uq, type is int
staticFalse
+
+

C++ defination code:

+ +
int a_uq()
+
+
+

b_mean

+

get B channel mean

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnreturn B channel mean, type is int
staticFalse
+
+

C++ defination code:

+ +
int b_mean()
+
+
+

b_median

+

get B channea median

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnreturn B channel median, type is int
staticFalse
+
+

C++ defination code:

+ +
int b_median()
+
+
+

b_mode

+

get B channel mode

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnreturn B channel mode, type is int
staticFalse
+
+

C++ defination code:

+ +
int b_mode()
+
+
+

b_std_dev

+

get B channel std_dev

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnreturn B channel std_dev, type is int
staticFalse
+
+

C++ defination code:

+ +
int b_std_dev()
+
+
+

b_min

+

get B channel min

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnreturn B channel min, type is int
staticFalse
+
+

C++ defination code:

+ +
int b_min()
+
+
+

b_max

+

get B channel max

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnreturn B channel max, type is int
staticFalse
+
+

C++ defination code:

+ +
int b_max()
+
+
+

b_lq

+

get B channel lq

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnreturn B channel lq, type is int
staticFalse
+
+

C++ defination code:

+ +
int b_lq()
+
+
+

b_uq

+

get B channel uq

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnreturn B channel uq, type is int
staticFalse
+
+

C++ defination code:

+ +
int b_uq()
+
+
+

Displacement

+

Displacement class

+
+

C++ defination code:

+ +
class Displacement
+
+
+

__init__

+

Displacement constructor

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramx_translation: The x_translation of the Displacement
y_translation: The y_translation of the Displacement
rotation: The rotation of the Displacement
scale: The scale of the Displacement
response: The response of the Displacement
staticFalse
+
+

C++ defination code:

+ +
Displacement(float x_translation, float y_translation, float rotation, float scale, float response)
+
+
+

__getitem__

+

Subscript operator

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramindex: array index
returnint&
staticFalse
+
+

C++ defination code:

+ +
int &__getitem__(int index)
+
+
+

x_translation

+

get x_translation of Displacement

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnreturn x_translation of the Displacement, type is float
staticFalse
+
+

C++ defination code:

+ +
float x_translation()
+
+
+

y_translation

+

get y_translation of Displacement

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnreturn y_translation of the Displacement, type is float
staticFalse
+
+

C++ defination code:

+ +
float y_translation()
+
+
+

rotation

+

get rotation of Displacement

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnreturn rotation of the Displacement, type is float
staticFalse
+
+

C++ defination code:

+ +
float rotation()
+
+
+

scale

+

get scale of Displacement

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnreturn scale of the Displacement, type is float
staticFalse
+
+

C++ defination code:

+ +
float scale()
+
+
+

response

+

get response of Displacement

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnreturn response of the Displacement, type is float
staticFalse
+
+

C++ defination code:

+ +
float response()
+
+
+

Percentile

+

Percentile class

+
+

C++ defination code:

+ +
class Percentile
+
+
+

__init__

+

Percentile constructor

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paraml_value: for grayscale image, it is grayscale percentile value (between 0 and 255).
for rgb888 image, it is l channel percentile value of lab (between 0 and 100).
a_value: for rgb888 image, it is a channel percentile value of lab format(between -128 and 127).
b_value: for rgb888 image, it is b channel percentile value of lab format(between -128 and 127).
staticFalse
+
+

C++ defination code:

+ +
Percentile(int l_value, int a_value = 0, int b_value = 0)
+
+
+

__getitem__

+

Subscript operator

+ + + + + + + + + + + + + + + + + +
itemdescription
typefunc
staticFalse
+
+

C++ defination code:

+ +
int &__getitem__(int index)
+
+
+

value

+

Return the grayscale percentile value (between 0 and 255).

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnreturns grayscale percentile value
staticFalse
+
+

C++ defination code:

+ +
int value()
+
+
+

l_value

+

Return the l channel percentile value of lab format (between 0 and 100).

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnreturns l channel percentile value
staticFalse
+
+

C++ defination code:

+ +
int l_value()
+
+
+

a_value

+

Return the a channel percentile value of lab format (between -128 and 127).

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnreturns a channel percentile value
staticFalse
+
+

C++ defination code:

+ +
int a_value()
+
+
+

b_value

+

Return the b channel percentile value of lab format (between -128 and 127).

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnreturns b channel percentile value
staticFalse
+
+

C++ defination code:

+ +
int b_value()
+
+
+

Threshold

+

Threshold class

+
+

C++ defination code:

+ +
class Threshold
+
+
+

__init__

+

Threshold constructor

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paraml_value: for grayscale image, it is grayscale threshold value (between 0 and 255).
for rgb888 image, it is l channel threshold value of lab (between 0 and 100).
a_value: for rgb888 image, it is a channel threshold value of lab format(between -128 and 127).
b_value: for rgb888 image, it is b channel threshold value of lab format(between -128 and 127).
staticFalse
+
+

C++ defination code:

+ +
Threshold(int l_value, int a_value = 0, int b_value = 0)
+
+
+

__getitem__

+

Subscript operator

+ + + + + + + + + + + + + + + + + +
itemdescription
typefunc
staticFalse
+
+

C++ defination code:

+ +
int &__getitem__(int index)
+
+
+

value

+

Return the grayscale threshold value (between 0 and 255).

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnreturns grayscale threshold value
staticFalse
+
+

C++ defination code:

+ +
int value()
+
+
+

l_value

+

Return the l channel threshold value of lab format (between 0 and 100).

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnreturns l channel percentile value
staticFalse
+
+

C++ defination code:

+ +
int l_value()
+
+
+

a_value

+

Return the a channel threshold value of lab format (between -128 and 127).

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnreturns a channel percentile value
staticFalse
+
+

C++ defination code:

+ +
int a_value()
+
+
+

b_value

+

Return the b channel threshold value of lab format (between -128 and 127).

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnreturns b channel percentile value
staticFalse
+
+

C++ defination code:

+ +
int b_value()
+
+
+

Histogram

+

Histogram class

+
+

C++ defination code:

+ +
class Histogram
+
+
+

__init__

+

Histogram constructor

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paraml_value: for grayscale image, it is grayscale threshold value list (the range of element values in the list is 0 and 255).
for rgb888 image, it is l channel threshold value list of lab (the range of element values in the list is 0 and 100).
a_value: for rgb888 image, it is a channel threshold value list of lab format(the range of element values in the list is -128 and 127).
b_value: for rgb888 image, it is b channel threshold value list of lab format(the range of element values in the list is -128 and 127).
format: format of the source image
staticFalse
+
+

C++ defination code:

+ +
Histogram(std::vector<float> l_bin, std::vector<float> a_bin, std::vector<float> b_bin, image::Format format = image::Format::FMT_RGB888)
+
+
+

__getitem__

+

Subscript operator

+ + + + + + + + + + + + + + + + + +
itemdescription
typefunc
staticFalse
+
+

C++ defination code:

+ +
int &__getitem__(int index)
+
+
+

bins

+

Returns a list of floats for the grayscale histogram.

+ + + + + + + + + + + + + + + + + +
itemdescription
typefunc
staticFalse
+
+

C++ defination code:

+ +
std::vector<float> bins()
+
+
+

l_bins

+

Returns a list of floats for the RGB565 histogram LAB L channel.

+ + + + + + + + + + + + + + + + + +
itemdescription
typefunc
staticFalse
+
+

C++ defination code:

+ +
std::vector<float> l_bins()
+
+
+

a_bins

+

Returns a list of floats for the RGB565 histogram LAB A channel.

+ + + + + + + + + + + + + + + + + +
itemdescription
typefunc
staticFalse
+
+

C++ defination code:

+ +
std::vector<float> a_bins()
+
+
+

b_bins

+

Returns a list of floats for the RGB565 histogram LAB B channel.

+ + + + + + + + + + + + + + + + + +
itemdescription
typefunc
staticFalse
+
+

C++ defination code:

+ +
std::vector<float> b_bins()
+
+
+

get_percentile

+

Computes the CDF of the histogram channels and returns a image::Percentile object

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
parampercentile: the values of the histogram at the passed in percentile (0.0 - 1.0) (float).
So, if you pass in 0.1 this method will tell you (going from left-to-right in the histogram)
what bin when summed into an accumulator caused the accumulator to cross 0.1. This is useful
to determine min (with 0.1) and max (with 0.9) of a color distribution without outlier effects
ruining your results for adaptive color tracking.
returnimage::Percentile object
staticFalse
+
+

C++ defination code:

+ +
image::Percentile get_percentile(float percentile)
+
+
+

get_threshold

+

Uses Otsu’s Method to compute the optimal threshold values that split the histogram into two halves for each channel of the histogram and returns a image::Threshold object.

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnimage::Threshold object
staticFalse
+
+

C++ defination code:

+ +
image::Threshold get_threshold()
+
+
+

get_statistics

+

Computes the mean, median, mode, standard deviation, min, max, lower quartile, and upper quartile of each color channel in the histogram and returns a image::Statistics object.

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnimage::Statistics object
staticFalse
+
+

C++ defination code:

+ +
image::Statistics get_statistics()
+
+
+

LBPKeyPoint

+

LBPKeyPoint class

+
+

C++ defination code:

+ +
class LBPKeyPoint
+
+
+

__init__

+

LBPKeyPoint constructor

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramdata: The data of the LBPKeyPoint
staticFalse
+
+

C++ defination code:

+ +
LBPKeyPoint(std::valarray<uint8_t> &data)
+
+
+

KeyPoint

+

KeyPoint class

+
+

C++ defination code:

+ +
class KeyPoint
+
+
+

__init__

+

KeyPoint constructor

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramx: The x of the KeyPoint
y: The y of the KeyPoint
score: The score of the KeyPoint
octave: The octave of the KeyPoint
angle: The angle of the KeyPoint
matched: The matched of the KeyPoint
desc: The desc of the KeyPoint
staticFalse
+
+

C++ defination code:

+ +
KeyPoint(uint16_t x, uint16_t y, uint16_t score, uint16_t octave, uint16_t angle, uint16_t matched, std::vector<uint8_t> &desc)
+
+
+

KPTMatch

+

KPTMatch class

+
+

C++ defination code:

+ +
class KPTMatch
+
+
+

__init__

+

KPTMatch constructor

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramcx: The cx of the KPTMatch
cy: The cy of the KPTMatch
x: The x of the KPTMatch
y: The y of the KPTMatch
w: The w of the KPTMatch
h: The h of the KPTMatch
score: The score of the KPTMatch
theta: The theta of the KPTMatch
match: The match of the KPTMatch
staticFalse
+
+

C++ defination code:

+ +
KPTMatch(int cx, int cy, int x, int y, int w, int h, int score, int theta, int match)
+
+
+

ORBKeyPoint

+

ORBKeyPoint class

+
+

C++ defination code:

+ +
class ORBKeyPoint
+
+
+

__init__

+

ORBKeyPoint constructor

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramdata: The data of the ORBKeyPoint
threshold: The threshold of the ORBKeyPoint
normalized: The normalized of the ORBKeyPoint
staticFalse
+
+

C++ defination code:

+ +
ORBKeyPoint(std::vector<image::KeyPoint> &data, int threshold, bool normalized)
+
+
+

get_data

+

get data of ORBKeyPoint

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnreturn data of the ORBKeyPoint, type is std::vector
staticFalse
+
+

C++ defination code:

+ +
std::vector<image::KeyPoint> get_data()
+
+
+

HaarCascade

+

HaarCascade class

+
+

C++ defination code:

+ +
class HaarCascade
+
+
+

__init__

+

HaarCascade constructor

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramdata: The data of the HaarCascade
threshold: The threshold of the HaarCascade
normalized: The normalized of the HaarCascade
staticFalse
+
+

C++ defination code:

+ +
HaarCascade()
+
+
+

__init__ (overload 1)

+

LineGroup constructor

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramid: The id of line
type: The line list type, @see image::LineType
lines: The line list
points: Point sets of line
staticFalse
+
+

C++ defination code:

+ +
LineGroup(int id, image::LineType type, std::vector<image::Line> lines, std::vector<std::vector<std::vector<int>>> points = std::vector<std::vector<std::vector<int>>>())
+
+
+

LineGroup

+

LineGroup class

+
+

C++ defination code:

+ +
class LineGroup
+
+
+

id

+

Get the line id of group, first id is 0.

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnreturn id
staticFalse
+
+

C++ defination code:

+ +
int id()
+
+
+

type

+

Get the line type of group

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnreturns line type. @see LineType
staticFalse
+
+

C++ defination code:

+ +
image::LineType type()
+
+
+

lines

+

Get a list of line

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnreturns a list composed of Line objects
staticFalse
+
+

C++ defination code:

+ +
std::vector<image::Line> lines()
+
+
+

points

+

Get the key points of line

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnreturns a list composed of (x,y) coordnates.
staticFalse
+
+

C++ defination code:

+ +
std::vector<std::vector<std::vector<int>>> points()
+
+
+

Image

+

Image class

+
+

C++ defination code:

+ +
class Image
+
+
+

Image

+

Image constructor

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramwidth: image width, should > 0
height: image height, should > 0
format: image format @see image::Format
staticFalse
+
+

C++ defination code:

+ +
Image(int width, int height, image::Format format = image::Format::FMT_RGB888)
+
+
+

Image (overload 1)

+

Image constructor

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramwidth: image width, should > 0
height: image height, should > 0
format: image format @see image::Format
data: image data, if data is nullptr, will malloc memory for image data
If the image is in jpeg format, data must be filled in.
data_size: image data size, only for compressed format like jpeg png, data_size must be filled in, or should be -1, default is -1.
copy: if true and data is not nullptr, will copy data to new buffer, else will use data directly. default is true to avoid memory leak.
staticFalse
+
+

C++ defination code:

+ +
Image(int width, int height, image::Format format, uint8_t *data, int data_size, bool copy)
+
+
+

update

+

set image

+ + + + + + + + + + + + + + + + + +
itemdescription
typefunc
staticFalse
+
+

C++ defination code:

+ +
err::Err update(int width, int height, image::Format format, uint8_t *data = NULL, int data_size = 0, bool copy = true)
+
+
+

format

+

Get image's format

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
seeimage.Format
staticFalse
+
+

C++ defination code:

+ +
image::Format format()
+
+
+

size

+

Get image's size, [width, height]

+ + + + + + + + + + + + + + + + + +
itemdescription
typefunc
staticFalse
+
+

C++ defination code:

+ +
image::Size size()
+
+
+

data_size

+

Get image's data size

+ + + + + + + + + + + + + + + + + +
itemdescription
typefunc
staticFalse
+
+

C++ defination code:

+ +
int data_size()
+
+
+

width

+

Get image's width

+ + + + + + + + + + + + + + + + + +
itemdescription
typefunc
staticFalse
+
+

C++ defination code:

+ +
int width()
+
+
+

height

+

Get image's height

+ + + + + + + + + + + + + + + + + +
itemdescription
typefunc
staticFalse
+
+

C++ defination code:

+ +
int height()
+
+
+

data

+

Get image's data pointer.\nIn MaixPy is capsule object.

+ + + + + + + + + + + + + + + + + +
itemdescription
typefunc
staticFalse
+
+

C++ defination code:

+ +
void *data()
+
+
+

__str__

+

To string method

+ + + + + + + + + + + + + + + + + +
itemdescription
typefunc
staticFalse
+
+

C++ defination code:

+ +
std::string __str__()
+
+
+

to_str

+

To string method

+ + + + + + + + + + + + + + + + + +
itemdescription
typefunc
staticFalse
+
+

C++ defination code:

+ +
std::string to_str()
+
+
+

get_pixel

+

Get pixel of image

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramx: pixel's coordinate x. x must less than image's width
y: pixel's coordinate y. y must less than image's height
rgbtuple: switch return value method. rgbtuple decides whether to split the return or not. default is false.
returnpixel value,
According to image format and rgbtuple, return different value:
format is FMT_RGB888, rgbtuple is true, return [R, G, B]; rgbtuple is false, return [RGB]
foramt is FMT_BGR888, rgbtuple is true, return [B, G, R]; rgbtuple is false, return [BGR]
format is FMT_GRAYSCALE, return [GRAY];
staticFalse
+
+

C++ defination code:

+ +
std::vector<int> get_pixel(int x, int y, bool rgbtuple = false)
+
+
+

set_pixel

+

Set pixel of image

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramx: pixel's coordinate x. x must less than image's width
y: pixel's coordinate y. y must less than image's height
pixel: pixel value, according to image format and size of pixel, has different operation:
format is FMT_RGB888, pixel size must be 1 or 3, if size is 1, will split pixel[0] to [R, G, B]; if size is 3, will use pixel directly
format is FMT_BGR888, pixel size must be 1 or 3, if size is 1, will split pixel[0] to [B, G, R]; if size is 3, will use pixel directly
format is FMT_GRAYSCALE, pixel size must be 1, will use pixel directly
returnerror code, Err::ERR_NONE is ok, other is error
staticFalse
+
+

C++ defination code:

+ +
err::Err set_pixel(int x, int y, std::vector<int> pixel)
+
+
+

to_tensor

+

Convert Image object to tensor::Tensor object

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramchw: if true, the shape of tensor is [C, H, W], else [H, W, C]
copy: if true, will alloc memory for tensor data, else will use the memory of Image object
returntensor::Tensor object pointer, an allocated tensor object
staticFalse
+
+

C++ defination code:

+ +
tensor::Tensor *to_tensor(bool chw = false, bool copy = true)
+
+
+

to_bytes

+

Get image's data and convert to array bytes

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramcopy: if true, will alloc memory and copy data to new buffer,
else will use the memory of Image object, delete bytes object will not affect Image object,
but delete Image object will make bytes object invalid, it may cause program crash !!!!
So use this param carefully.
returnimage's data bytes, need be delete by caller in C++.
staticFalse
+
+

C++ defination code:

+ +
Bytes *to_bytes(bool copy = true)
+
+
+

to_format

+

Convert image to specific format

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramformat: format want to convert to, @see image::Format, only support RGB888, BGR888, RGBA8888, BGRA8888, GRAYSCALE, JPEG.
returnnew image object. Need be delete by caller in C++.
throwerr.Exception, if two images' format not support, or already the format, will raise exception
staticFalse
+
+

C++ defination code:

+ +
image::Image *to_format(const image::Format &format)
+
+
+

to_format (overload 1)

+

Convert image to specific format

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramformat: format want to convert to, @see image::Format, only support RGB888, BGR888, RGBA8888, BGRA8888, GRAYSCALE, JPEG.
buff: user's buffer, if buff is nullptr, will malloc memory for new image data, else will use buff directly
returnnew image object. Need be delete by caller in C++.
throwerr.Exception, if two images' format not support, or already the format, will raise exception
staticFalse
+
+

C++ defination code:

+ +
image::Image *to_format(const image::Format &format, void *buff, size_t buff_size)
+
+
+

to_jpeg

+

Convert image to jpeg

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramquality: the quality of jpg, default is 95. For MaixCAM supported range is (50, 100], if <= 50 will be fixed to 51.
returnnew image object. Need be delete by caller in C++.
throwerr.Exception, if two images' format not support, or already the format, will raise exception
staticFalse
+
+

C++ defination code:

+ +
image::Image *to_jpeg(int quality = 95)
+
+
+

draw_image

+

Draw image on this image

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramx: left top corner of image point's coordinate x
y: left top corner of image point's coordinate y
img: image object to draw, the caller's channel must <= the args' channel,
e.g. caller is RGB888, args is RGBA8888, will throw exception, but caller is RGBA8888, args is RGB888 or RGBA8888 is ok
returnthis image object self
staticFalse
+
+

C++ defination code:

+ +
image::Image *draw_image(int x, int y, image::Image &img)
+
+
+

draw_rect

+

Fill rectangle color to image

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramx: left top corner of rectangle point's coordinate x
y: left top corner of rectangle point's coordinate y
w: rectangle width
h: rectangle height
color: rectangle color
thickness: rectangle thickness(line width), by default(value is 1), -1 means fill rectangle
returnthis image object self
staticFalse
+
+

C++ defination code:

+ +
image::Image *draw_rect(int x, int y, int w, int h, const image::Color &color, int thickness = 1)
+
+
+

draw_line

+

Draw line on image

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramx1: start point's coordinate x
y1: start point's coordinate y
x2: end point's coordinate x
y2: end point's coordinate y
color: line color @see image::Color
thickness: line thickness(line width), by default(value is 1)
returnthis image object self
staticFalse
+
+

C++ defination code:

+ +
image::Image *draw_line(int x1, int y1, int x2, int y2, const image::Color &color, int thickness = 1)
+
+
+

draw_circle

+

Draw circle on image

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramx: circle center point's coordinate x
y: circle center point's coordinate y
radius: circle radius
color: circle color @see image::Color
thickness: circle thickness(line width), default -1 means fill circle
returnthis image object self
staticFalse
+
+

C++ defination code:

+ +
image::Image *draw_circle(int x, int y, int radius, const image::Color &color, int thickness = 1)
+
+
+

draw_ellipse

+

Draw ellipse on image

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramx: ellipse center point's coordinate x
y: ellipse center point's coordinate y
a: ellipse major axis length
b: ellipse minor axis length
angle: ellipse rotation angle
start_angle: ellipse start angle
end_angle: ellipse end angle
color: ellipse color @see image::Color
thickness: ellipse thickness(line width), by default(value is 1), -1 means fill ellipse
returnthis image object self
staticFalse
+
+

C++ defination code:

+ +
image::Image *draw_ellipse(int x, int y, int a, int b, float angle, float start_angle, float end_angle, const image::Color &color, int thickness = 1)
+
+
+

draw_string

+

Draw text on image

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramx: text left top point's coordinate x
y: text left top point's coordinate y
string: text content
color: text color @see image::Color, default is white
scale: font scale, by default(value is 1)
thickness: text thickness(line width), if negative, the glyph is filled, by default(value is -1)
wrap: if true, will auto wrap text to next line if text width > image width, by default(value is true)
returnthis image object self
staticFalse
+
+

C++ defination code:

+ +
image::Image *draw_string(int x, int y, const std::string &textstring, const image::Color &color = image::COLOR_WHITE, float scale = 1, int thickness = -1,
+                                bool wrap = true, int wrap_space = 4, const std::string &font = "")
+
+
+

draw_cross

+

Draw cross on image

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramx: cross center point's coordinate x
y: cross center point's coordinate y
color: cross color @see image::Color
size: how long the lines of the cross extend, by default(value is 5). So the line length is 2 * size + thickness
thickness: cross thickness(line width), by default(value is 1)
staticFalse
+
+

C++ defination code:

+ +
image::Image *draw_cross(int x, int y, const image::Color &color, int size = 5, int thickness = 1)
+
+
+

draw_arrow

+

Draw arrow on image

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramx0: start coordinate of the arrow x0
y0: start coordinate of the arrow y0
x1: end coordinate of the arrow x1
y1: end coordinate of the arrow y1
color: cross color @see image::Color
thickness: cross thickness(line width), by default(value is 1)
returnthis image object self
staticFalse
+
+

C++ defination code:

+ +
image::Image *draw_arrow(int x0, int y0, int x1, int y1, const image::Color &color, int thickness = 1)
+
+
+

draw_edges

+

Draw edges on image

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramcorners: edges, [[x0, y0], [x1, y1], [x2, y2], [x3, y3]]
color: edges color @see image::Color
size: the circle of radius size. TODO: support in the feature
thickness: edges thickness(line width), by default(value is 1)
fill: if true, will fill edges, by default(value is false)
returnthis image object self
staticFalse
+
+

C++ defination code:

+ +
image::Image *draw_edges(std::vector<std::vector<int>> corners, const image::Color &color, int size = 0, int thickness = 1, bool fill = false)
+
+
+

draw_keypoints

+

Draw keypoints on image

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramkeypoints: keypoints, [x1, y1, x2, y2...] or [x, y, rotation_andle_in_degrees, x2, y2, rotation_andle_in_degrees2](TODO: rotation_andle_in_degrees support in the feature)
color: keypoints color @see image::Color
size: size of keypoints(radius)
thickness: keypoints thickness(line width), by default(value is -1 means fill circle)
line_thickness: line thickness, default 0 means not draw lines, > 0 will draw lines connect points.
returnthis image object self
staticFalse
+
+

C++ defination code:

+ +
image::Image *draw_keypoints(const std::vector<int> &keypoints, const image::Color &color, int size = 4, int thickness = -1, int line_thickness = 0)
+
+
+

resize

+

Resize image, will create a new resized image object

+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramwidth: new width, if value is -1, will use height to calculate aspect ratio
height: new height, if value is -1, will use width to calculate aspect ratio
object_fit: fill, contain, cover, by default is fill
method: resize method, by default is NEAREST
returnAlways return a new resized image object even size not change, So in C++ you should take care of the return value to avoid memory leak.
And it's better to judge whether the size has changed before calling this function to make the program more efficient.
e.g.
if img->width() != width
img->height() != height:
img = img->resize(width, height);
staticFalse
+
+

C++ defination code:

+ +
image::Image *resize(int width, int height, image::Fit object_fit = image::Fit::FIT_FILL, image::ResizeMethod method = image::ResizeMethod::NEAREST)
+
+
+

affine

+

Affine transform image, will create a new transformed image object, need 3 points.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramsrc_points: three source points, [x1, y1, x2, y2, x3, y3]
dst_points: three destination points, [x1, y1, x2, y2, x3, y3]
width: new width, if value is -1, will use height to calculate aspect ratio
height: new height, if value is -1, will use width to calculate aspect ratio
method: resize method, by default is bilinear
returnnew transformed image object
staticFalse
+
+

C++ defination code:

+ +
image::Image *affine(std::vector<int> src_points, std::vector<int> dst_points, int width = -1, int height = -1, image::ResizeMethod method = image::ResizeMethod::BILINEAR)
+
+
+

affine (overload 1)

+

Perspective transform image, will create a new transformed image object, need 4 points.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramsrc_points: three source points, [x1, y1, x2, y2, x3, y3, x4, y4]
dst_points: three destination points, [x1, y1, x2, y2, x3, y3, x4, y4]
width: new width, if value is -1, will use height to calculate aspect ratio
height: new height, if value is -1, will use width to calculate aspect ratio
method: resize method, by default is bilinear
returnnew transformed image object
staticFalse
+
+

C++ defination code:

+ +
image::Image* perspective(std::vector<int> src_points, std::vector<int> dst_points, int width = -1, int height = -1, image::ResizeMethod method = image::ResizeMethod::BILINEAR)
+
+
+

copy

+

Copy image, will create a new copied image object

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnnew copied image object
staticFalse
+
+

C++ defination code:

+ +
image::Image *copy()
+
+
+

crop

+

Crop image, will create a new cropped image object

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramx: left top corner of crop rectangle point's coordinate x
y: left top corner of crop rectangle point's coordinate y
w: crop rectangle width
h: crop rectangle height
returnnew cropped image object
staticFalse
+
+

C++ defination code:

+ +
image::Image *crop(int x, int y, int w, int h)
+
+
+

rotate

+

Rotate image, will create a new rotated image object

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramangle: anti-clock wise rotate angle, if angle is 90 or 270, and width or height is -1, will swap width and height, or will throw exception
width: new width, if value is -1, will use height to calculate aspect ratio
height: new height, if value is -1, will use width to calculate aspect ratio
method: resize method, by default is bilinear
returnnew rotated image object
staticFalse
+
+

C++ defination code:

+ +
image::Image *rotate(float angle, int width = -1, int height = -1, image::ResizeMethod method = image::ResizeMethod::BILINEAR)
+
+
+

flip

+

Vertical flip image, and return a new image.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramdir: flip dir, see image.FlipDir, e.g. image.FlipDir.X is vertical flip.
returnnew flipped image.
throwWhen arg error, will throw out err.Err exception.
staticFalse
+
+

C++ defination code:

+ +
image::Image *flip(const image::FlipDir dir)
+
+
+

mean_pool

+

Finds the mean of x_div * y_div squares in the image and returns the modified image composed of the mean of each square.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramx_div: The width of the squares.
y_div: The height of the squares.
copy: Select whether to return a new image or modify the original image. default is false.
If true, returns a new image composed of the mean of each square; If false, returns the modified image composed of the mean of each square.
returnReturns the image after the operation is completed.
staticFalse
+
+

C++ defination code:

+ +
image::Image *mean_pool(int x_div, int y_div, bool copy = false)
+
+
+

midpoint_pool

+

Finds the midpoint of x_div * y_div squares in the image and returns the modified image composed of the mean of each square.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramx_div: The width of the squares.
y_div: The height of the squares.
bias: The bias of the midpoint. default is 0.5.
midpoint value is equal to (max * bias + min * (1 - bias))
copy: Select whether to return a new image or modify the original image. default is false.
If true, returns a new image composed of the midpoint of each square; If false, returns the modified image composed of the midpoint of each square.
returnReturns the image after the operation is completed.
staticFalse
+
+

C++ defination code:

+ +
image::Image *midpoint_pool(int x_div, int y_div, double bias = 0.5, bool copy = false)
+
+
+

compress

+

JPEG compresses the image in place, the same as to_jpeg functioin, it's recommend to use to_jpeg instead.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramquality: The quality of the compressed image. default is 95.
returnReturns the compressed JPEG image
staticFalse
+
+

C++ defination code:

+ +
image::Image *compress(int quality = 95)
+
+
+

clear

+

Sets all pixels in the image to zero

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
parammask: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.
Only pixels set in the mask are modified. default is None.
returnReturns the image after the operation is completed.
staticFalse
+
+

C++ defination code:

+ +
image::Image *clear(image::Image *mask = nullptr)
+
+
+

mask_rectange

+

Zeros a rectangular part of the image. If no arguments are supplied this method zeros the center of the image.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramx: The x coordinate of the top left corner of the rectangle.
y: The y coordinate of the top left corner of the rectangle.
w: The width of the rectangle.
h: The height of the rectangle.
returnReturns the image after the operation is completed.
staticFalse
+
+

C++ defination code:

+ +
image::Image *mask_rectange(int x = -1, int y = -1, int w = -1, int h = -1)
+
+
+

mask_circle

+

Zeros a circular part of the image. If no arguments are supplied this method zeros the center of the image.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramx: The x coordinate of the center of the circle.
y: The y coordinate of the center of the circle.
radius: The radius of the circle.
returnReturns the image after the operation is completed.
staticFalse
+
+

C++ defination code:

+ +
image::Image *mask_circle(int x = -1, int y = -1, int radius = -1)
+
+
+

mask_ellipse

+

Zeros a ellipse part of the image. If no arguments are supplied this method zeros the center of the image.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramx: The x coordinate of the center of the ellipse.
y: The y coordinate of the center of the ellipse.
radius_x: The radius of the ellipse in the x direction.
radius_y: The radius of the ellipse in the y direction.
rotation_angle_in_degrees: The rotation angle of the ellipse in degrees.
returnReturns the image after the operation is completed.
staticFalse
+
+

C++ defination code:

+ +
image::Image *mask_ellipse(int x = -1, int y = -1, int radius_x = -1, int radius_y = -1, float rotation_angle_in_degrees = 0)
+
+
+

binary

+

Sets all pixels in the image to black or white depending on if the pixel is inside of a threshold in the threshold list thresholds or not.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
noteFor GRAYSCALE format, Lmin and Lmax range is [0, 255]. For RGB888 format, Lmin and Lmax range is [0, 100].
paramthresholds: You can define multiple thresholds.
For GRAYSCALE format, you can use {{Lmin, Lmax}, ...} to define one or more thresholds.
For RGB888 format, you can use {{Lmin, Lmax, Amin, Amax, Bmin, Bmax}, ...} to define one or more thresholds.
Where the upper case L,A,B represent the L,A,B channels of the LAB image format, and min, max represent the minimum and maximum values of the corresponding channels.
invert: If true, the thresholds will be inverted before the operation. default is false.
zero: If zero is true, the image will be set the pixels within the threshold to 0, other pixels remain unchanged. If zero is false, the image will be set to black or white. default is false.
mask: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.
Only pixels set in the mask are modified. default is None.
to_bitmap: If true, the image will be converted to a bitmap image before thresholding. default is false. TODO: support in the feature
copy: Select whether to return a new image or modify the original image. default is false.
returnReturns the image after the operation is completed.
staticFalse
+
+

C++ defination code:

+ +
image::Image *binary(std::vector<std::vector<int>> thresholds = std::vector<std::vector<int>>(), bool invert = false, bool zero = false, image::Image *mask = nullptr, bool to_bitmap = false, bool copy = false)
+
+
+

invert

+

Inverts the image in place.

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnReturns the image after the operation is completed
staticFalse
+
+

C++ defination code:

+ +
image::Image *invert()
+
+
+

b_and

+

Performs a bitwise and operation between the image and the other image.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramother: The other image should be an image and should be the same size as the image being operated on. TODO: support path?
mask: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.
Only pixels set in the mask are modified. default is None.
returnReturns the image after the operation is completed.
staticFalse
+
+

C++ defination code:

+ +
image::Image *b_and(image::Image *other, image::Image *mask = nullptr)
+
+
+

b_nand

+

Performs a bitwise nand operation between the image and the other image.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramother: The other image should be an image and should be the same size as the image being operated on. TODO: support path?
mask: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.
Only pixels set in the mask are modified. default is None.
returnReturns the image after the operation is completed.
staticFalse
+
+

C++ defination code:

+ +
image::Image *b_nand(image::Image *other, image::Image *mask = nullptr)
+
+
+

b_or

+

Performs a bitwise or operation between the image and the other image.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramother: The other image should be an image and should be the same size as the image being operated on. TODO: support path?
mask: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.
Only pixels set in the mask are modified. default is None.
returnReturns the image after the operation is completed.
staticFalse
+
+

C++ defination code:

+ +
image::Image *b_or(image::Image *other, image::Image *mask = nullptr)
+
+
+

b_nor

+

Performs a bitwise nor operation between the image and the other image.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramother: The other image should be an image and should be the same size as the image being operated on. TODO: support path?
mask: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.
Only pixels set in the mask are modified. default is None.
returnReturns the image after the operation is completed.
staticFalse
+
+

C++ defination code:

+ +
image::Image *b_nor(image::Image *other, image::Image *mask = nullptr)
+
+
+

b_xor

+

Performs a bitwise xor operation between the image and the other image.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramother: The other image should be an image and should be the same size as the image being operated on. TODO: support path?
mask: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.
Only pixels set in the mask are modified. default is None.
returnReturns the image after the operation is completed.
staticFalse
+
+

C++ defination code:

+ +
image::Image *b_xor(image::Image *other, image::Image *mask = nullptr)
+
+
+

b_xnor

+

Performs a bitwise xnor operation between the image and the other image.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramother: The other image should be an image and should be the same size as the image being operated on. TODO: support path?
mask: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.
Only pixels set in the mask are modified. default is None.
returnReturns the image after the operation is completed.
staticFalse
+
+

C++ defination code:

+ +
image::Image *b_xnor(image::Image *other, image::Image *mask = nullptr)
+
+
+

awb

+

Performs an auto white balance operation on the image. TODO: support in the feature

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
parammax: if True uses the white-patch algorithm instead. default is false.
returnReturns the image after the operation is completed.
staticFalse
+
+

C++ defination code:

+ +
image::Image *awb(bool max = false)
+
+
+

ccm

+

Multiples the passed (3x3) or (4x3) floating-point color-correction-matrix with the image.\nnote: Grayscale format is not support.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
parammatrix: The color correction matrix to use. 3x3 or 4x3 matrix.
Weights may either be positive or negative, and the sum of each column in the 3x3 matrix should generally be 1.
example:
{
1, 0, 0,
0, 1, 0,
0, 0, 1,
}
Where the last row of the 4x3 matrix is an offset per color channel. If you add an offset you may wish to make the
weights sum to less than 1 to account for the offset.
example:
{
1, 0, 0,
0, 1, 0,
0, 0, 1,
0, 0, 0,
}
returnReturns the image after the operation is completed.
staticFalse
+
+

C++ defination code:

+ +
image::Image *ccm(std::vector<float> &matrix)
+
+
+

gamma

+

Quickly changes the image gamma, contrast, and brightness. Create a array whose size is usually 255,\nand use the parameters gamma, contrast, and brightness to calculate the value of the array, and then map the\nimage pixel value through the value of the array.\nThe calculation method for array is: array[array_idx] = (powf((array_idx / 255.0), (1 / gamma)) * contrast + brightness) * scale,\npowf is a function used to calculate floating point power.\narray is the array used for mapping.\narray_idx is the index of the array, the maximum value is determined according to the image format, usually 255.\nscale is a constant, the value is determined by the image format, usually 255.\nMapping method:\nAssume that a pixel value in the image is 128, then map the pixel value to the value of array[128]\nUsers can adjust the value of the array through the gamma, contrast, and brightness parameters.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramgamma: The contrast gamma greater than 1.0 makes the image darker in a non-linear manner while less than 1.0 makes the image brighter. default is 1.0.
contrast: The contrast value greater than 1.0 makes the image brighter in a linear manner while less than 1.0 makes the image darker. default is 1.0.
brightness: The brightness value greater than 0.0 makes the image brighter in a constant manner while less than 0.0 makes the image darker. default is 0.0.
returnReturns the image after the operation is completed.
staticFalse
+
+

C++ defination code:

+ +
image::Image *gamma(double gamma = 1.0, double contrast = 1.0, double brightness = 0.0)
+
+
+

gamma_corr

+

Alias for Image.gamma.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramgamma: The contrast gamma greater than 1.0 makes the image darker in a non-linear manner while less than 1.0 makes the image brighter. default is 1.0.
contrast: The contrast value greater than 1.0 makes the image brighter in a linear manner while less than 1.0 makes the image darker. default is 1.0.
brightness: The brightness value greater than 0.0 makes the image brighter in a constant manner while less than 0.0 makes the image darker. default is 0.0.
returnReturns the image after the operation is completed.
staticFalse
+
+

C++ defination code:

+ +
image::Image *gamma_corr(double gamma, double contrast = 1.0, double brightness = 0.0)
+
+
+

negate

+

Flips (numerically inverts) all pixels values in an image

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnReturns the image after the operation is completed.
staticFalse
+
+

C++ defination code:

+ +
image::Image *negate()
+
+
+

replace

+

Replaces all pixels in the image with the corresponding pixels in the other image.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramother: The other image should be an image and should be the same size as the image being operated on.
hmirror: If true, the image will be horizontally mirrored before the operation. default is false.
vflip: If true, the image will be vertically flipped before the operation. default is false.
transpose: If true, the image can be used to rotate 90 degrees or 270 degrees.
hmirror = false, vflip = false, transpose = false, the image will not be rotated.
hmirror = false, vflip = true, transpose = true, the image will be rotated 90 degrees.
hmirror = true, vflip = true, transpose = false, the image will be rotated 180 degrees.
hmirror = true, vflip = false, transpose = true, the image will be rotated 270 degrees.
mask: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.
Only pixels set in the mask are modified. default is None.
returnReturns the image after the operation is completed.
staticFalse
+
+

C++ defination code:

+ +
image::Image *replace(image::Image *other = nullptr, bool hmirror = false, bool vflip = false, bool transpose = false, image::Image *mask = nullptr)
+
+
+

set

+

Alias for Image::replace.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramother: The other image should be an image and should be the same size as the image being operated on.
hmirror: If true, the image will be horizontally mirrored before the operation. default is false.
vflip: If true, the image will be vertically flipped before the operation. default is false.
mask: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.
Only pixels set in the mask are modified. default is None.
returnReturns the image after the operation is completed.
staticFalse
+
+

C++ defination code:

+ +
image::Image *set(image::Image *other, bool hmirror = false, bool vflip = false, bool transpose = false, image::Image *mask = nullptr)
+
+
+

add

+

Adds the other image to the image.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramother: The other image should be an image and should be the same size as the image being operated on. TODO: support path?
mask: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.
Only pixels set in the mask are modified. default is None.
returnReturns the image after the operation is completed.
staticFalse
+
+

C++ defination code:

+ +
image::Image *add(image::Image *other, image::Image *mask = nullptr)
+
+
+

sub

+

Subtracts the other image from the image.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramother: The other image should be an image and should be the same size as the image being operated on. TODO: support path?
reverse: If true, the image will be reversed before the operation. default is false.
mask: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.
Only pixels set in the mask are modified. default is None.
returnReturns the image after the operation is completed.
staticFalse
+
+

C++ defination code:

+ +
image::Image *sub(image::Image *other, bool reverse = false, image::Image *mask = nullptr)
+
+
+

mul

+

Multiplies the image by the other image.\nNote: This method is meant for image blending and cannot multiply the pixels in the image by a scalar like 2.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramother: The other image should be an image and should be the same size as the image being operated on. TODO: support path?
invert: If true, the image will be change the multiplication operation from ab to 1/((1/a)(1/b)).
In particular, this lightens the image instead of darkening it (e.g. multiply versus burn operations). default is false.
mask: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.
Only pixels set in the mask are modified. default is None.
returnReturns the image after the operation is completed.
staticFalse
+
+

C++ defination code:

+ +
image::Image *mul(image::Image *other, bool invert = false, image::Image *mask = nullptr)
+
+
+

div

+

Divides the image by the other image.\nThis method is meant for image blending and cannot divide the pixels in the image by a scalar like 2.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramother: The other image should be an image and should be the same size as the image being operated on. TODO: support path?
invert: If true, the image will be change the division direction from a/b to b/a. default is false.
mod: If true, the image will be change the division operation to the modulus operation. default is false.
mask: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.
Only pixels set in the mask are modified. default is None.
returnReturns the image after the operation is completed.
staticFalse
+
+

C++ defination code:

+ +
image::Image *div(image::Image *other, bool invert = false, bool mod = false, image::Image *mask = nullptr)
+
+
+

min

+

Caculate the minimum of each pixel in the image and the other image.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramother: The other image should be an image and should be the same size as the image being operated on.
mask: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.
Only pixels set in the mask are modified. default is None.
returnReturns the image after the operation is completed.
staticFalse
+
+

C++ defination code:

+ +
image::Image *min(image::Image *other, image::Image *mask = nullptr)
+
+
+

max

+

Caculate the maximum of each pixel in the image and the other image.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramother: The other image should be an image and should be the same size as the image being operated on.
mask: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.
Only pixels set in the mask are modified. default is None.
returnReturns the image after the operation is completed.
staticFalse
+
+

C++ defination code:

+ +
image::Image *max(image::Image *other, image::Image *mask = nullptr)
+
+
+

difference

+

Caculate the absolute value of the difference between each pixel in the image and the other image.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramother: The other image should be an image and should be the same size as the image being operated on.
mask: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.
Only pixels set in the mask are modified. default is None.
returnReturns the image after the operation is completed.
staticFalse
+
+

C++ defination code:

+ +
image::Image *difference(image::Image *other, image::Image *mask = nullptr)
+
+
+

blend

+

Blends the image with the other image.\nres = alpha * this_img / 256 + (256 - alpha) * other_img / 256

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramother: The other image should be an image and should be the same size as the image being operated on.
alpha: The alpha value of the blend, the value range is [0, 256],default is 128.
mask: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.
Only pixels set in the mask are modified. default is None.
returnReturns the image after the operation is completed.
staticFalse
+
+

C++ defination code:

+ +
image::Image *blend(image::Image *other, int alpha = 128, image::Image *mask = nullptr)
+
+
+

histeq

+

Runs the histogram equalization algorithm on the image.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramadaptive: If true, an adaptive histogram equalization method will be run on the image instead which as generally better results than non-adaptive histogram qualization but a longer run time. default is false.
clip_limit: Provides a way to limit the contrast of the adaptive histogram qualization. Use a small value for this, like 10, to produce good histogram equalized contrast limited images. default is -1.
mask: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.
Only pixels set in the mask are modified. default is None.
returnReturns the image after the operation is completed.
staticFalse
+
+

C++ defination code:

+ +
image::Image *histeq(bool adaptive = false, int clip_limit = -1, image::Image *mask = nullptr)
+
+
+

mean

+

Standard mean blurring filter using a box filter.\nThe parameters offset and invert are valid when threshold is True.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramsize: Kernel size. The actual kernel size is ((size * 2) + 1) * ((size * 2) + 1). Use 1(3x3 kernel), 2(5x5 kernel).
threshold: If true, which will enable adaptive thresholding of the image which sets pixels to white or black based on a pixel’s brightness in relation to the brightness of the kernel of pixels around them.
default is false.
offset: The larger the offset value, the lower brightness pixels on the original image will be set to white. default is 0.
invert: If true, the image will be inverted before the operation. default is false.
mask: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.
Only pixels set in the mask are modified. default is None.
returnReturns the image after the operation is completed.
staticFalse
+
+

C++ defination code:

+ +
image::Image *mean(int size, bool threshold = false, int offset = 0, bool invert = false, image::Image *mask = nullptr)
+
+
+

median

+

Runs the median filter on the image. The median filter is the best filter for smoothing surfaces while preserving edges but it is very slow.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramsize: Kernel size. The actual kernel size is ((size * 2) + 1) * ((size * 2) + 1). Use 1(3x3 kernel), 2(5x5 kernel).
percentile: This parameter controls the percentile of the value used in the kernel. You can set this to 0 for a min filter, 0.25 for a lower quartile filter, 0.75 for an upper quartile filter, and 1.0 for a max filter. default is 0.5.
threshold: If true, which will enable adaptive thresholding of the image which sets pixels to white or black based on a pixel’s brightness in relation to the brightness of the kernel of pixels around them.
default is false.
offset: The larger the offset value, the lower brightness pixels on the original image will be set to white. default is 0.
invert: If true, the image will be inverted before the operation. default is false.
mask: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.
Only pixels set in the mask are modified. default is None.
returnReturns the image after the operation is completed.
staticFalse
+
+

C++ defination code:

+ +
image::Image *median(int size, double percentile = 0.5, bool threshold = false, int offset = 0, bool invert = false, image::Image *mask = nullptr)
+
+
+

mode

+

Runs the mode filter on the image by replacing each pixel with the mode of their neighbors.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramsize: Kernel size. The actual kernel size is ((size * 2) + 1) * ((size * 2) + 1). Use 1(3x3 kernel), 2(5x5 kernel).
threshold: If true, which will enable adaptive thresholding of the image which sets pixels to white or black based on a pixel’s brightness in relation to the brightness of the kernel of pixels around them.
default is false.
offset: The larger the offset value, the lower brightness pixels on the original image will be set to white. default is 0.
invert: If true, the image will be inverted before the operation. default is false.
mask: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.
Only pixels set in the mask are modified. default is None.
returnReturns the image after the operation is completed.
staticFalse
+
+

C++ defination code:

+ +
image::Image *mode(int size, bool threshold = false, int offset = 0, bool invert = false, image::Image *mask = nullptr)
+
+
+

midpoint

+

Runs the midpoint filter on the image.This filter finds the midpoint (max * bias + min * (1 - bias)) of each pixel neighborhood in the image.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramsize: Kernel size. The actual kernel size is ((size * 2) + 1) * ((size * 2) + 1). Use 1(3x3 kernel), 2(5x5 kernel).
bias: The bias of the midpoint. default is 0.5.
threshold: If true, which will enable adaptive thresholding of the image which sets pixels to white or black based on a pixel’s brightness in relation to the brightness of the kernel of pixels around them.
default is false.
offset: The larger the offset value, the lower brightness pixels on the original image will be set to white. default is 0.
invert: If true, the image will be inverted before the operation. default is false.
mask: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.
Only pixels set in the mask are modified. default is None.
returnReturns the image after the operation is completed.
staticFalse
+
+

C++ defination code:

+ +
image::Image *midpoint(int size, double bias = 0.5, bool threshold = false, int offset = 0, bool invert = false, image::Image *mask = nullptr)
+
+
+

morph

+

Convolves the image by a filter kernel. This allows you to do general purpose convolutions on an image.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramsize: Kernel size. The actual kernel size is ((size * 2) + 1) * ((size * 2) + 1). Use 1(3x3 kernel), 2(5x5 kernel).
kernel: The kernel used for convolution. The kernel should be a list of lists of numbers. The kernel should be the same size as the actual kernel size.
mul: This parameter is used to multiply the convolved pixel results. default is auto.
add: This parameter is the value to be added to each convolution pixel result. default is 0.0.
threshold: If true, which will enable adaptive thresholding of the image which sets pixels to white or black based on a pixel’s brightness in relation to the brightness of the kernel of pixels around them.
default is false.
offset: The larger the offset value, the lower brightness pixels on the original image will be set to white. default is 0.
invert: If true, the image will be inverted before the operation. default is false.
mask: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.
Only pixels set in the mask are modified. default is None.
returnReturns the image after the operation is completed.
staticFalse
+
+

C++ defination code:

+ +
image::Image *morph(int size, std::vector<int> kernel, float mul = -1, float add = 0.0, bool threshold = false, int offset = 0, bool invert = false, image::Image *mask = nullptr)
+
+
+

gaussian

+

Convolves the image by a smoothing guassian kernel.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramsize: Kernel size. The actual kernel size is ((size * 2) + 1) * ((size * 2) + 1). Use 1(3x3 kernel), 2(5x5 kernel).
unsharp: If true, this method will perform an unsharp mask operation instead of gaussian filtering operation, this improves the clarity of image edges. default is false.
mul: This parameter is used to multiply the convolved pixel results. default is auto.
add: This parameter is the value to be added to each convolution pixel result. default is 0.0.
threshold: If true, which will enable adaptive thresholding of the image which sets pixels to white or black based on a pixel’s brightness in relation to the brightness of the kernel of pixels around them.
default is false.
offset: The larger the offset value, the lower brightness pixels on the original image will be set to white. default is 0.
invert: If true, the image will be inverted before the operation. default is false.
mask: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.
Only pixels set in the mask are modified. default is None.
returnReturns the image after the operation is completed.
staticFalse
+
+

C++ defination code:

+ +
image::Image *gaussian(int size, bool unsharp = false, float mul = -1, float add = 0.0, bool threshold = false, int offset = 0, bool invert = false, image::Image *mask = nullptr)
+
+
+

laplacian

+

Convolves the image by a edge detecting laplacian kernel.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramsize: Kernel size. The actual kernel size is ((size * 2) + 1) * ((size * 2) + 1). Use 1(3x3 kernel), 2(5x5 kernel).
sharpen: If True, this method will sharpen the image instead of an unthresholded edge detection image. Then increase the kernel size to improve image clarity. default is false.
mul: This parameter is used to multiply the convolved pixel results. default is auto.
add: This parameter is the value to be added to each convolution pixel result. default is 0.0.
threshold: If true, which will enable adaptive thresholding of the image which sets pixels to white or black based on a pixel’s brightness in relation to the brightness of the kernel of pixels around them.
default is false.
offset: The larger the offset value, the lower brightness pixels on the original image will be set to white. default is 0.
invert: If true, the image will be inverted before the operation. default is false.
mask: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.
Only pixels set in the mask are modified. default is None.
returnReturns the image after the operation is completed.
staticFalse
+
+

C++ defination code:

+ +
image::Image *laplacian(int size, bool sharpen = false, float mul = -1, float add = 0.0, bool threshold = false, int offset = 0, bool invert = false, image::Image *mask = nullptr)
+
+
+

bilateral

+

Convolves the image by a bilateral filter.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramsize: Kernel size. The actual kernel size is ((size * 2) + 1) * ((size * 2) + 1). Use 1(3x3 kernel), 2(5x5 kernel).
color_sigma: Controls how closely colors are matched using the bilateral filter. default is 0.1.
space_sigma: Controls how closely pixels space-wise are blurred with each other. default is 1.
threshold: If true, which will enable adaptive thresholding of the image which sets pixels to white or black based on a pixel’s brightness in relation to the brightness of the kernel of pixels around them.
default is false.
offset: The larger the offset value, the lower brightness pixels on the original image will be set to white. default is 0.
invert: If true, the image will be inverted before the operation. default is false.
mask: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.
Only pixels set in the mask are modified. default is None.
returnReturns the image after the operation is completed.
staticFalse
+
+

C++ defination code:

+ +
image::Image *bilateral(int size, double color_sigma = 0.1, double space_sigma = 1, bool threshold = false, int offset = 0, bool invert = false, image::Image *mask = nullptr)
+
+
+

linpolar

+

Re-project’s and image from cartessian coordinates to linear polar coordinates.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramreverse: If true, the image will be reverse polar transformed. default is false.
returnReturns the image after the operation is completed.
staticFalse
+
+

C++ defination code:

+ +
image::Image *linpolar(bool reverse = false)
+
+
+

logpolar

+

Re-project’s and image from cartessian coordinates to log polar coordinates.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramreverse: If true, the image will be reverse polar transformed. default is false.
returnReturns the image after the operation is completed.
staticFalse
+
+

C++ defination code:

+ +
image::Image *logpolar(bool reverse = false)
+
+
+

lens_corr

+

Performs a lens correction operation on the image. TODO: support in the feature

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramstrength: The strength of the lens correction. default is 1.8.
zoom: The zoom of the lens correction. default is 1.0.
x_corr: The x correction of the lens correction. default is 0.0.
y_corr: The y correction of the lens correction. default is 0.0.
returnReturns the image after the operation is completed.
staticFalse
+
+

C++ defination code:

+ +
image::Image *lens_corr(double strength = 1.8, double zoom = 1.0, double x_corr = 0.0, double y_corr = 0.0)
+
+
+

rotation_corr

+

Performs a rotation correction operation on the image. TODO: support in the feature

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramx_rotation: The x rotation of the rotation correction. default is 0.0.
y_rotation: The y rotation of the rotation correction. default is 0.0.
z_rotation: The z rotation of the rotation correction. default is 0.0.
x_translation: The x translation of the rotation correction. default is 0.0.
y_translation: The y translation of the rotation correction. default is 0.0.
zoom: The zoom of the rotation correction. default is 1.0.
fov: The fov of the rotation correction. default is 60.0.
corners: The corners of the rotation correction. default is None.
returnReturns the image after the operation is completed.
staticFalse
+
+

C++ defination code:

+ +
image::Image *rotation_corr(double x_rotation = 0.0, double y_rotation = 0.0, double z_rotation = 0.0, double x_translation = 0.0, double y_translation = 0.0, double zoom = 1.0, double fov = 60.0, std::vector<float> corners = std::vector<float>())
+
+
+

get_histogram

+

Computes the normalized histogram on all color channels and returns a image::Histogram object.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
noteFor GRAYSCALE format, Lmin and Lmax range is [0, 255]. For RGB888 format, Lmin and Lmax range is [0, 100].
paramthresholds: You can define multiple thresholds.
For GRAYSCALE format, you can use {{Lmin, Lmax}, ...} to define one or more thresholds.
For RGB888 format, you can use {{Lmin, Lmax, Amin, Amax, Bmin, Bmax}, ...} to define one or more thresholds.
Where the upper case L,A,B represent the L,A,B channels of the LAB image format, and min, max represent the minimum and maximum values of the corresponding channels.
invert: If true, the thresholds will be inverted before the operation. default is false.
roi: The region of interest, input in the format of (x, y, w, h), x and y are the coordinates of the upper left corner, w and h are the width and height of roi.
default is None, means whole image.
bins: The number of bins to use for the histogram.
In GRAYSCALE format, setting range is [2, 256], default is 100.
In RGB888 format, setting range is [2, 100], default is 100.
l_bins: The number of bins to use for the l channel of the histogram. Only valid in RGB888 format.
If an invalid value is set, bins will be used instead. The setting range is [2, 100], default is 100.
a_bins: The number of bins to use for the a channel of the histogram.
Only valid in RGB888 format.The setting range is [2, 256], default is 256.
b_bins: The number of bins to use for the b channel of the histogram.
Only valid in RGB888 format. The setting range is [2, 256], default is 256.
difference: difference may be set to an image object to cause this method to operate on the difference image between the current image and the difference image object.
default is None.
returnReturns image::Histogram object
staticFalse
+
+

C++ defination code:

+ +
image::Histogram get_histogram(std::vector<std::vector<int>> thresholds = std::vector<std::vector<int>>(), bool invert = false, std::vector<int> roi = std::vector<int>(), int bins = -1, int l_bins = 100, int a_bins = 256, int b_bins = 256, image::Image *difference = nullptr)
+
+
+

get_statistics

+

Gets the statistics of the image. TODO: support in the feature

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
noteFor GRAYSCALE format, Lmin and Lmax range is [0, 255]. For RGB888 format, Lmin and Lmax range is [0, 100].
paramthresholds: You can define multiple thresholds.
For GRAYSCALE format, you can use {{Lmin, Lmax}, ...} to define one or more thresholds.
For RGB888 format, you can use {{Lmin, Lmax, Amin, Amax, Bmin, Bmax}, ...} to define one or more thresholds.
Where the upper case L,A,B represent the L,A,B channels of the LAB image format, and min, max represent the minimum and maximum values of the corresponding channels.
invert: If true, the image will be inverted before the operation. default is false.
roi: The region of interest, input in the format of (x, y, w, h), x and y are the coordinates of the upper left corner, w and h are the width and height of roi.
default is None, means whole image.
bins: The number of bins to use for the statistics. default is -1.
l_bins: The number of bins to use for the l channel of the statistics. default is -1.
a_bins: The number of bins to use for the a channel of the statistics. default is -1.
b_bins: The number of bins to use for the b channel of the statistics. default is -1.
difference: The difference image to use for the statistics. default is None.
returnReturns the statistics of the image
staticFalse
+
+

C++ defination code:

+ +
image::Statistics get_statistics(std::vector<std::vector<int>> thresholds = std::vector<std::vector<int>>(), bool invert = false, std::vector<int> roi = std::vector<int>(), int bins = -1, int l_bins = -1, int a_bins = -1, int b_bins = -1, image::Image *difference = nullptr)
+
+
+

get_regression

+

Gets the regression of the image.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
noteFor GRAYSCALE format, Lmin and Lmax range is [0, 255]. For RGB888 format, Lmin and Lmax range is [0, 100].
paramthresholds: You can define multiple thresholds.
For GRAYSCALE format, you can use {{Lmin, Lmax}, ...} to define one or more thresholds.
For RGB888 format, you can use {{Lmin, Lmax, Amin, Amax, Bmin, Bmax}, ...} to define one or more thresholds.
Where the upper case L,A,B represent the L,A,B channels of the LAB image format, and min, max represent the minimum and maximum values of the corresponding channels.
invert: If true, the image will be inverted before the operation. default is false.
roi: The region of interest, input in the format of (x, y, w, h), x and y are the coordinates of the upper left corner, w and h are the width and height of roi.
default is None, means whole image.
x_stride: The x stride to use for the regression. default is 2.
y_stride: The y stride to use for the regression. default is 1.
area_threshold: The area threshold to use for the regression. default is 10.
pixels_threshold: The pixels threshold to use for the regression. default is 10.
robust: If true, the regression will be robust. default is false.
returnReturns the regression of the image
staticFalse
+
+

C++ defination code:

+ +
std::vector<image::Line> get_regression(std::vector<std::vector<int>> thresholds = std::vector<std::vector<int>>(), bool invert = false, std::vector<int> roi = std::vector<int>(), int x_stride = 2, int y_stride = 1, int area_threshold = 10, int pixels_threshold = 10, bool robust = false)
+
+
+

save

+

Save image to file

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
parampath: file path
quality: image quality, by default(value is 95), support jpeg and png format
returnerror code, err::ERR_NONE is ok, other is error
staticFalse
+
+

C++ defination code:

+ +
err::Err save(const char *path, int quality = 95)
+
+
+

flood_fill

+

Flood fills a region of the image starting from location x, y.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramx: The x coordinate of the seed point.
y: The y coordinate of the seed point.
seed_threshold: The seed_threshold value controls how different any pixel in the fill area may be from the original starting pixel. default is 0.05.
floating_threshold: The floating_threshold value controls how different any pixel in the fill area may be from any neighbor pixels. default is 0.05.
color: The color to fill the region with. default is white.
invert: If true, the image will be inverted before the operation. default is false.
clear_background: If true, the background will be cleared before the operation. default is false.
mask: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.
Only pixels set in the mask are modified. default is None. FIXME: the mask image works abnormally
returnReturns the image after the operation is completed.
staticFalse
+
+

C++ defination code:

+ +
image::Image *flood_fill(int x, int y, float seed_threshold = 0.05, float floating_threshold = 0.05, image::Color color = image::COLOR_WHITE, bool invert = false, bool clear_background = false, image::Image *mask = nullptr)
+
+
+

erode

+

Erodes the image in place.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramsize: Kernel size. The actual kernel size is ((size * 2) + 1) * ((size * 2) + 1). Use 1(3x3 kernel), 2(5x5 kernel).
threshold: The number of pixels in the kernel that are not 0. If it is less than or equal to the threshold, set the center pixel to black. default is (kernel_size - 1).
mask: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.
Only pixels set in the mask are modified. default is None.
returnReturns the image after the operation is completed.
staticFalse
+
+

C++ defination code:

+ +
image::Image *erode(int size, int threshold = -1, image::Image *mask = nullptr)
+
+
+

dilate

+

Dilates the image in place.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramsize: Kernel size. The actual kernel size is ((size * 2) + 1) * ((size * 2) + 1). Use 1(3x3 kernel), 2(5x5 kernel).
threshold: The number of pixels in the kernel that are not 0. If it is greater than or equal to the threshold, set the center pixel to white. default is 0.
mask: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.
Only pixels set in the mask are modified. default is None.
returnReturns the image after the operation is completed.
staticFalse
+
+

C++ defination code:

+ +
image::Image *dilate(int size, int threshold = 0, image::Image *mask = nullptr)
+
+
+

open

+

Performs erosion and dilation on an image in order.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramsize: Kernel size. The actual kernel size is ((size * 2) + 1) * ((size * 2) + 1). Use 1(3x3 kernel), 2(5x5 kernel).
threshold: As the threshold for erosion and dilation, the actual threshold for erosion is (kernel_size - 1 - threshold), the actual threshold for dialation is threshold. default is 0.
mask: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.
Only pixels set in the mask are modified. default is None.
returnReturns the image after the operation is completed.
staticFalse
+
+

C++ defination code:

+ +
image::Image *open(int size, int threshold = 0, image::Image *mask = nullptr)
+
+
+

close

+

Performs dilation and erosion on an image in order.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramsize: Kernel size. The actual kernel size is ((size * 2) + 1) * ((size * 2) + 1). Use 1(3x3 kernel), 2(5x5 kernel).
threshold: As the threshold for erosion and dilation, the actual threshold for erosion is (kernel_size - 1 - threshold), the actual threshold for dialation is threshold. default is 0.
mask: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.
Only pixels set in the mask are modified. default is None.
returnReturns the image after the operation is completed.
staticFalse
+
+

C++ defination code:

+ +
image::Image *close(int size, int threshold = 0, image::Image *mask = nullptr)
+
+
+

top_hat

+

Returns the image difference of the image and Image.open()’ed image.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramsize: Kernel size. The actual kernel size is ((size * 2) + 1) * ((size * 2) + 1). Use 1(3x3 kernel), 2(5x5 kernel).
threshold: As the threshold for open method. default is 0.
mask: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.
Only pixels set in the mask are modified. default is None.
returnReturns the image after the operation is completed.
staticFalse
+
+

C++ defination code:

+ +
image::Image *top_hat(int size, int threshold = 0, image::Image *mask = nullptr)
+
+
+

black_hat

+

Returns the image difference of the image and Image.close()’ed image.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramsize: Kernel size. The actual kernel size is ((size * 2) + 1) * ((size * 2) + 1). Use 1(3x3 kernel), 2(5x5 kernel).
threshold: As the threshold for close method. default is 0.
mask: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.
Only pixels set in the mask are modified. default is None.
returnReturns the image after the operation is completed.
staticFalse
+
+

C++ defination code:

+ +
image::Image *black_hat(int size, int threshold = 0, image::Image *mask = nullptr)
+
+
+

find_blobs

+

Finds all blobs in the image and returns a list of image.Blob class which describe each Blob.\nPlease see the image.Blob object more more information.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
noteFor GRAYSCALE format, Lmin and Lmax range is [0, 255]. For RGB888 format, Lmin and Lmax range is [0, 100].
paramthresholds: You can define multiple thresholds.
For GRAYSCALE format, you can use {{Lmin, Lmax}, ...} to define one or more thresholds.
For RGB888 format, you can use {{Lmin, Lmax, Amin, Amax, Bmin, Bmax}, ...} to define one or more thresholds.
Where the upper case L,A,B represent the L,A,B channels of the LAB image format, and min, max represent the minimum and maximum values of the corresponding channels.
invert: if true, will invert thresholds before find blobs, default is false
roi: The region of interest, input in the format of (x, y, w, h), x and y are the coordinates of the upper left corner, w and h are the width and height of roi.
default is None, means whole image.
x_stride: x stride is the number of x pixels to skip when doing the hough transform. default is 2
y_stride: y_stride is the number of y pixels to skip when doing the hough transform. default is 1
area_threshold: area threshold, if the blob area is smaller than area_threshold, the blob is not returned, default is 10
pixels_threshold: pixels threshold, if the blob pixels is smaller than area_threshold, the blob is not returned,, default is 10.
when x_stride and y_stride is equal to 1, pixels_threshold is equivalent to area_threshold
merge: if True merges all not filtered out blobs whos bounding rectangles intersect each other. default is false
margin: margin can be used to increase or decrease the size of the bounding rectangles for blobs during the intersection test.
For example, with a margin of 1 blobs whos bounding rectangles are 1 pixel away from each other will be merged. default is 0
x_hist_bins_max: if set to non-zero populates a histogram buffer in each blob object with an x_histogram projection of all columns in the object. This value then sets the number of bins for that projection.
y_hist_bins_max: if set to non-zero populates a histogram buffer in each blob object with an y_histogram projection of all rows in the object. This value then sets the number of bins for that projection.
returnReturn the blob when found blobs, format is (blob1, blob2, ...), you can use blob class methods to do more operations.
staticFalse
+
+

C++ defination code:

+ +
std::vector<image::Blob> find_blobs(std::vector<std::vector<int>> thresholds = std::vector<std::vector<int>>(), bool invert = false, std::vector<int> roi = std::vector<int>(), int x_stride = 2, int y_stride = 1, int area_threshold = 10, int pixels_threshold = 10, bool merge = false, int margin = 0, int x_hist_bins_max = 0, int y_hist_bins_max = 0)
+
+
+

find_lines

+

Find lines in image

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramroi: The region of interest, input in the format of (x, y, w, h), x and y are the coordinates of the upper left corner, w and h are the width and height of roi.
default is None, means whole image.
x_stride: x stride is the number of x pixels to skip when doing the hough transform. default is 2
y_stride: y_stride is the number of y pixels to skip when doing the hough transform. default is 1
threshold: threshold threshold controls what lines are detected from the hough transform. Only lines with a magnitude greater than or equal to threshold are returned.
The right value of threshold for your application is image dependent. default is 1000.
theta_margin: theta_margin controls the merging of detected lines. default is 25.
rho_margin: rho_margin controls the merging of detected lines. default is 25.
returnReturn the line when found lines, format is (line1, line2, ...), you can use line class methods to do more operations
staticFalse
+
+

C++ defination code:

+ +
std::vector<image::Line> find_lines(std::vector<int> roi = std::vector<int>(), int x_stride = 2, int y_stride = 1, double threshold = 1000, double theta_margin = 25, double rho_margin = 25)
+
+
+

find_line_segments

+

Finds all line segments in the image.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramroi: The region of interest, input in the format of (x, y, w, h), x and y are the coordinates of the upper left corner, w and h are the width and height of roi.
default is None, means whole image.
merge_distance: The maximum distance between two lines to merge them. default is 0.
max_theta_difference: The maximum difference between two lines to merge them. default is 15.
returnReturn the line when found lines, format is (line1, line2, ...), you can use line class methods to do more operations
staticFalse
+
+

C++ defination code:

+ +
std::vector<image::Line> find_line_segments(std::vector<int> roi = std::vector<int>(), int merge_distance = 0, int max_theta_difference = 15)
+
+
+

search_line_path

+

Search the path of line

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramthresholds: You can define multiple thresholds.
For GRAYSCALE format, you can use {{Lmin, Lmax}, ...} to define one or more thresholds.
For RGB888 format, you can use {{Lmin, Lmax, Amin, Amax, Bmin, Bmax}, ...} to define one or more thresholds.
Where the upper case L,A,B represent the L,A,B channels of the LAB image format, and min, max represent the minimum and maximum values of the corresponding channels.
detect_pixel_size: Before finding the path, the screen is divided into several smaller blocks, each with a width and height of detect_pixel_size. The smaller the detect_pixel_size, the finer the division. the unit is pixels.
point_merge_size: Minimum distance between merged point sets. the unit is pixels.
connection_max_size: Minimum size allowed for connecting points to form a line. the unit is pixels.
connection_max_distance: Minimum distance allowed for point to line. the unit is pixels.
connection_max_angle: Minimum angle allowed for connecting points to form a line.
returnReturn the line when found lines, format is (groupline1, groupline2, ...), you can use LineGroup class methods to do more operations
staticFalse
+
+

C++ defination code:

+ +
std::vector<image::LineGroup> search_line_path(std::vector<std::vector<int>> thresholds = std::vector<std::vector<int>>(), int detect_pixel_size = 30, int point_merge_size = 15, int connection_max_size = 51, int connection_max_distance = 20, int connection_max_angle = 20)
+
+
+

find_circles

+

Find circles in image

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramroi: The region of interest, input in the format of (x, y, w, h), x and y are the coordinates of the upper left corner, w and h are the width and height of roi.
default is None, means whole image.
x_stride: x stride is the number of x pixels to skip when doing the hough transform. default is 2
y_stride: y_stride is the number of y pixels to skip when doing the hough transform. default is 1
threshold: threshold controls what circles are detected from the hough transform. Only circles with a magnitude greater than or equal to threshold are returned.
The right value of threshold for your application is image dependent.
x_margin: x_margin controls the merging of detected circles. Circles which are x_margin, y_margin, and r_margin pixels apart are merged. default is 10
y_margin: y_margin controls the merging of detected circles. Circles which are x_margin, y_margin, and r_margin pixels apart are merged. default is 10
r_margin: r_margin controls the merging of detected circles. Circles which are x_margin, y_margin, and r_margin pixels apart are merged. default is 10
r_min: r_min controls the minimum circle radius detected. Increase this to speed up the algorithm. default is 2
r_max: r_max controls the maximum circle radius detected. Decrease this to speed up the algorithm. default is min(roi.w / 2, roi.h / 2)
r_step: r_step controls how to step the radius detection by. default is 2.
returnReturn the circle when found circles, format is (circle1, circle2, ...), you can use circle class methods to do more operations
staticFalse
+
+

C++ defination code:

+ +
std::vector<image::Circle> find_circles(std::vector<int> roi = std::vector<int>(), int x_stride = 2, int y_stride = 1, int threshold = 2000, int x_margin = 10, int y_margin = 10, int r_margin = 10, int r_min = 2, int r_max = -1, int r_step = 2)
+
+
+

find_rects

+

Finds all rects in the image.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramroi: The region of interest, input in the format of (x, y, w, h), x and y are the coordinates of the upper left corner, w and h are the width and height of roi.
default is None, means whole image.
threshold: The threshold to use for the rects. default is 10000.
returnReturns the rects of the image
staticFalse
+
+

C++ defination code:

+ +
std::vector<image::Rect> find_rects(std::vector<int> roi = std::vector<int>(), int threshold = 10000)
+
+
+

find_qrcodes

+

Finds all qrcodes in the image.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramroi: The region of interest, input in the format of (x, y, w, h), x and y are the coordinates of the upper left corner, w and h are the width and height of roi.
default is None, means whole image.
decoder_type: Select the QR code decoding method. Choosing QRCODE_DECODER_TYPE_QUIRC allows for retrieving QR code version, ECC level, mask, data type, and other details,
though it may decode slower at lower resolutions. Opting for QRCODE_DECODER_TYPE_ZBAR enables faster decoding at lower resolutions but may slow down at higher resolutions,
providing only the QR code content and position information. default is QRCODE_DECODER_TYPE_ZBAR.
returnReturns the qrcodes of the image
staticFalse
+
+

C++ defination code:

+ +
std::vector<image::QRCode> find_qrcodes(std::vector<int> roi = std::vector<int>(), image::QRCodeDecoderType decoder_type = image::QRCodeDecoderType::QRCODE_DECODER_TYPE_ZBAR)
+
+
+

find_apriltags

+

Finds all apriltags in the image.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramroi: The region of interest, input in the format of (x, y, w, h), x and y are the coordinates of the upper left corner, w and h are the width and height of roi.
default is None, means whole image.
families: The families to use for the apriltags. default is TAG36H11.
fx: The camera X focal length in pixels, default is -1.
fy: The camera Y focal length in pixels, default is -1.
cx: The camera X center in pixels, default is image.width / 2.
cy: The camera Y center in pixels, default is image.height / 2.
returnReturns the apriltags of the image
staticFalse
+
+

C++ defination code:

+ +
std::vector<image::AprilTag> find_apriltags(std::vector<int> roi = std::vector<int>(), image::ApriltagFamilies families = image::ApriltagFamilies::TAG36H11, float fx = -1, float fy = -1, int cx = -1, int cy = -1)
+
+
+

find_datamatrices

+

Finds all datamatrices in the image.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramroi: The region of interest, input in the format of (x, y, w, h), x and y are the coordinates of the upper left corner, w and h are the width and height of roi.
default is None, means whole image.
effort: Controls how much time to spend trying to find data matrix matches. default is 200.
returnReturns the datamatrices of the image
staticFalse
+
+

C++ defination code:

+ +
std::vector<image::DataMatrix> find_datamatrices(std::vector<int> roi = std::vector<int>(), int effort = 200)
+
+
+

find_barcodes

+

Finds all barcodes in the image.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramroi: The region of interest, input in the format of (x, y, w, h), x and y are the coordinates of the upper left corner, w and h are the width and height of roi.
default is None, means whole image.
returnReturns the barcodes of the image
staticFalse
+
+

C++ defination code:

+ +
std::vector<image::BarCode> find_barcodes(std::vector<int> roi = std::vector<int>())
+
+
+

find_displacement

+

Finds the displacement between the image and the template. TODO: support in the feature\nnote: this method must be used on power-of-2 image sizes

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramtemplate_image: The template image.
roi: The region of interest, input in the format of (x, y, w, h), x and y are the coordinates of the upper left corner, w and h are the width and height of roi.
default is None, means whole image.
template_roi: The region-of-interest rectangle (x, y, w, h) to work in. If not specified, it is equal to the image rectangle.
logpolar: If true, it will instead find rotation and scale changes between the two images. default is false.
returnReturns the displacement of the image
staticFalse
+
+

C++ defination code:

+ +
image::Displacement find_displacement(image::Image &template_image, std::vector<int> roi = std::vector<int>(), std::vector<int> template_roi = std::vector<int>(), bool logpolar = false)
+
+
+

find_template

+

Finds the template in the image.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramtemplate_image: The template image.
threshold: Threshold is floating point number (0.0-1.0) where a higher threshold prevents false positives while lowering the detection rate while a lower threshold does the opposite.
roi: The region of interest, input in the format of (x, y, w, h), x and y are the coordinates of the upper left corner, w and h are the width and height of roi.
default is None, means whole image. Only valid in SEARCH_EX mode.
step: The step size to use for the template. default is 2. Only valid in SEARCH_EX mode
search: The search method to use for the template. default is SEARCH_EX.
returnReturns a bounding box tuple (x, y, w, h) for the matching location otherwise None.
staticFalse
+
+

C++ defination code:

+ +
std::vector<int> find_template(image::Image &template_image, float threshold, std::vector<int> roi = std::vector<int>(), int step = 2, image::TemplateMatch search = image::TemplateMatch::SEARCH_EX)
+
+
+

find_features

+

Finds the features in the image. TODO: support in the feature

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramcascade: The cascade to use for the features. default is CASCADE_FRONTALFACE_ALT.
threshold: The threshold to use for the features. default is 0.5.
scale: The scale to use for the features. default is 1.5.
roi: The region of interest, input in the format of (x, y, w, h), x and y are the coordinates of the upper left corner, w and h are the width and height of roi.
default is None, means whole image.
returnReturns the features of the image
staticFalse
+
+

C++ defination code:

+ +
std::vector<int> find_features(int cascade, float threshold = 0.5, float scale = 1.5, std::vector<int> roi = std::vector<int>())
+
+
+

find_lbp

+

Finds the lbp in the image. TODO: support in the feature.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramroi: The region of interest, input in the format of (x, y, w, h), x and y are the coordinates of the upper left corner, w and h are the width and height of roi.
default is None, means whole image.
returnReturns the lbp of the image
staticFalse
+
+

C++ defination code:

+ +
image::LBPKeyPoint find_lbp(std::vector<int> roi = std::vector<int>())
+
+
+

find_keypoints

+

Finds the keypoints in the image. TODO: support in the feature.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramroi: The region of interest, input in the format of (x, y, w, h), x and y are the coordinates of the upper left corner, w and h are the width and height of roi.
default is None, means whole image.
threshold: The threshold to use for the keypoints. default is 20.
normalized: If true, the image will be normalized before the operation. default is false.
scale_factor: The scale factor to use for the keypoints. default is 1.5.
max_keypoints: The maximum number of keypoints to use for the keypoints. default is 100.
corner_detector: The corner detector to use for the keypoints. default is CORNER_AGAST.
returnReturns the keypoints of the image
staticFalse
+
+

C++ defination code:

+ +
image::ORBKeyPoint find_keypoints(std::vector<int> roi = std::vector<int>(), int threshold = 20, bool normalized = false, float scale_factor = 1.5, int max_keypoints = 100, image::CornerDetector corner_detector = image::CornerDetector::CORNER_AGAST)
+
+
+

find_edges

+

Finds the edges in the image.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramedge_type: The edge type to use for the edges. default is EDGE_CANNY.
roi: The region of interest, input in the format of (x, y, w, h), x and y are the coordinates of the upper left corner, w and h are the width and height of roi.
default is None, means whole image.
threshold: The threshold to use for the edges. default is 20.
returnReturns the edges of the image
staticFalse
+
+

C++ defination code:

+ +
image::Image* find_edges(image::EdgeDetector edge_type, std::vector<int> roi = std::vector<int>(), std::vector<int> threshold = std::vector<int>({100, 200}))
+
+
+

find_hog

+

Finds the hog in the image. TODO: support in the feature

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramroi: The region of interest, input in the format of (x, y, w, h), x and y are the coordinates of the upper left corner, w and h are the width and height of roi.
default is None, means whole image.
size: The size to use for the hog. default is 8.
returnReturns the hog of the image
staticFalse
+
+

C++ defination code:

+ +
image::Image* find_hog(std::vector<int> roi = std::vector<int>(), int size = 8)
+
+
+

match_lbp_descriptor

+

Matches the lbp descriptor of the image. TODO: support in the feature

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramdesc1: The descriptor to use for the match.
desc2: The descriptor to use for the match.
returnReturns the match of the image
staticFalse
+
+

C++ defination code:

+ +
int match_lbp_descriptor(image::LBPKeyPoint &desc1, image::LBPKeyPoint &desc2)
+
+
+

match_orb_descriptor

+

Matches the orb descriptor of the image. TODO: support in the feature

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramdesc1: The descriptor to use for the match.
desc2: The descriptor to use for the match.
threshold: The threshold to use for the match. default is 95.
filter_outliers: If true, the image will be filter_outliers before the operation. default is false.
returnReturns the match of the image
staticFalse
+
+

C++ defination code:

+ +
image::KPTMatch match_orb_descriptor(image::ORBKeyPoint &desc1, image::ORBKeyPoint &desc2, int threshold = 95, bool filter_outliers = false)
+
+
+

Color

+

Color class

+
+

C++ defination code:

+ +
class Color
+
+
+

__init__

+

Color constructor

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramalpha: alpha channel, value range: 0 ~ 1
staticFalse
+
+

C++ defination code:

+ +
Color(uint8_t ch1, uint8_t ch2 = 0, uint8_t ch3 = 0, float alpha = 0, image::Format format = image::FMT_GRAYSCALE)
+
+
+

r

+

Color red channel

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typevar
staticFalse
readonlyFalse
+
+

C++ defination code:

+ +
uint8_t r
+
+
+

g

+

Color green channel

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typevar
staticFalse
readonlyFalse
+
+

C++ defination code:

+ +
uint8_t g
+
+
+

b

+

Color blue channel

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typevar
staticFalse
readonlyFalse
+
+

C++ defination code:

+ +
uint8_t b
+
+
+

alpha

+

Color alpha channel, value from 0.0 to 1.0, float value

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typevar
staticFalse
readonlyFalse
+
+

C++ defination code:

+ +
float alpha
+
+
+

gray

+

Color gray channel

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typevar
staticFalse
readonlyFalse
+
+

C++ defination code:

+ +
uint8_t gray
+
+
+

format

+

Color format

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typevar
staticFalse
readonlyFalse
+
+

C++ defination code:

+ +
image::Format format
+
+
+

hex

+

Get color's hex value

+ + + + + + + + + + + + + + + + + +
itemdescription
typefunc
staticFalse
+
+

C++ defination code:

+ +
uint32_t hex()
+
+
+

from_rgb

+

Create Color object from RGB channels

+ + + + + + + + + + + + + + + + + +
itemdescription
typefunc
staticTrue
+
+

C++ defination code:

+ +
static image::Color from_rgb(uint8_t r, uint8_t g, uint8_t b)
+
+
+

from_bgr

+

Create Color object from BGR channels

+ + + + + + + + + + + + + + + + + +
itemdescription
typefunc
staticTrue
+
+

C++ defination code:

+ +
static image::Color from_bgr(uint8_t b, uint8_t g, uint8_t r)
+
+
+

from_gray

+

Create Color object from gray channel

+ + + + + + + + + + + + + + + + + +
itemdescription
typefunc
staticTrue
+
+

C++ defination code:

+ +
static image::Color from_gray(uint8_t gray)
+
+
+

from_rgba

+

Create Color object from RGBA channels

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramalpha: alpha channel, float value, value range: 0 ~ 1
staticTrue
+
+

C++ defination code:

+ +
static image::Color from_rgba(uint8_t r, uint8_t g, uint8_t b, float alpha)
+
+
+

from_bgra

+

Create Color object from BGRA channels

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramalpha: alpha channel, float value, value range: 0 ~ 1
staticTrue
+
+

C++ defination code:

+ +
static image::Color from_bgra(uint8_t b, uint8_t g, uint8_t r, float alpha)
+
+
+

from_hex

+

Create Color object from hex value

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramhex: hex value, e.g. 0x0000FF00, lower address if first channel
format: color format, @see image::Format
staticTrue
+
+

C++ defination code:

+ +
static image::Color from_hex(uint32_t hex, image::Format &format)
+
+
+

to_format

+

Convert Color format

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramformat: format want to convert to, @see image::Format, only support RGB888, BGR888, RGBA8888, BGRA8888, GRAYSCALE.
staticFalse
+
+

C++ defination code:

+ +
void to_format(const image::Format &format)
+
+
+

to_format2

+

Convert color format and return a new Color object

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramformat: format want to convert to, @see image::Format, only support RGB888, BGR888, RGBA8888, BGRA8888, GRAYSCALE.
returnnew Color object, you need to delete it manually in C++.
staticFalse
+
+

C++ defination code:

+ +
image::Color *to_format2(const image::Format &format)
+
+
+ + +
+
+
+ + +
+
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixcdk/api/maix/log.html b/maixcdk/api/maix/log.html new file mode 100644 index 00000000..6fe8aeb5 --- /dev/null +++ b/maixcdk/api/maix/log.html @@ -0,0 +1,539 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + maix::log - MaixCDK + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

maix::log

+ +
+
+
    + +
+
+
+
+ + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

maix.log module

+
+

This is maix::log module of MaixCDK.
+All of these elements are in namespace maix::log.

+

For MaixCDK developer: DO NOT edit this doc file manually, this doc is auto generated!

+
+

Module

+

No module

+

Enum

+

Variable

+

Function

+

error

+

print error log

+ + + + + + + + + + + + + +
itemdescription
paramfmt: format string
...: args
+
+

C++ defination code:

+ +
void error(const char *fmt, ...)
+
+
+

warn

+

print warning log

+ + + + + + + + + + + + + +
itemdescription
paramfmt: format string
...: args
+
+

C++ defination code:

+ +
void warn(const char *fmt, ...)
+
+
+

info

+

print info log

+ + + + + + + + + + + + + +
itemdescription
paramfmt: format string
...: args
+
+

C++ defination code:

+ +
void info(const char *fmt, ...)
+
+
+

debug

+

print debug log

+ + + + + + + + + + + + + +
itemdescription
paramfmt: format string
...: args
+
+

C++ defination code:

+ +
void debug(const char *fmt, ...)
+
+
+

error0

+

print error log, but not add '\n' at end

+ + + + + + + + + + + + + +
itemdescription
paramfmt: format string
...: args
+
+

C++ defination code:

+ +
void error0(const char *fmt, ...)
+
+
+

warn0

+

print warning log, but not add '\n' at end

+ + + + + + + + + + + + + +
itemdescription
paramfmt: format string
...: args
+
+

C++ defination code:

+ +
void warn0(const char *fmt, ...)
+
+
+

info0

+

print info log, but not add '\n' at end

+ + + + + + + + + + + + + +
itemdescription
paramfmt: format string
...: args
+
+

C++ defination code:

+ +
void info0(const char *fmt, ...)
+
+
+

debug0

+

print debug log, but not add '\n' at end

+ + + + + + + + + + + + + +
itemdescription
paramfmt: format string
...: args
+
+

C++ defination code:

+ +
void debug0(const char *fmt, ...)
+
+
+

print

+

same as printf, but recommend use this function instead of printf\nthis function will add prefix like "-- [E] " to log

+ + + + + + + + + + + + + +
itemdescription
paramfmt: format string
...: args
+
+

C++ defination code:

+ +
void print(const char *fmt, ...)
+
+
+

Class

+ + +
+
+
+ + +
+
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixcdk/api/maix/modbus.html b/maixcdk/api/maix/modbus.html new file mode 100644 index 00000000..487b831c --- /dev/null +++ b/maixcdk/api/maix/modbus.html @@ -0,0 +1,354 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + maix::modbus - MaixCDK + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

maix::modbus

+ +
+
+
    + +
+
+
+
+ + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

maix.modbus module

+
+

This is maix::modbus module of MaixCDK.
+All of these elements are in namespace maix::modbus.

+

For MaixCDK developer: DO NOT edit this doc file manually, this doc is auto generated!

+
+

Module

+ + + + + + + + + + + + + +
modulebrief
Slavemaix.modbus.Slave module
+

Enum

+

Variable

+

Function

+

Class

+ + +
+
+
+ + +
+
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixcdk/api/maix/modbus/Slave.html b/maixcdk/api/maix/modbus/Slave.html new file mode 100644 index 00000000..42ae90cd --- /dev/null +++ b/maixcdk/api/maix/modbus/Slave.html @@ -0,0 +1,370 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + maix::modbus::Slave - MaixCDK + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

maix::modbus::Slave

+ +
+
+
    + +
+
+
+
+ + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

maix.modbus.Slave module

+
+

This is maix::modbus::Slave module of MaixCDK.
+All of these elements are in namespace maix::modbus::Slave.

+

For MaixCDK developer: DO NOT edit this doc file manually, this doc is auto generated!

+
+

Module

+

No module

+

Enum

+

Variable

+

Function

+

__init__

+

Constructor for creating a Modbus Slave instance with specified registers.\nThis constructor initializes a Modbus Slave using the provided mode and connection\nparameters. It also allows for defining register information through a\nRegisters object, enabling easier management of multiple registers at once.

+ + + + + + + + + + + + + + + + + +
itemdescription
parammode: Specifies the communication mode: RTU or TCP.
ip_or_device: The UART device name if using RTU mode.
If TCP mode is chosen, this parameter is ignored.
registers: A Registers object that holds starting addresses and sizes
for coils, discrete inputs, holding registers, and input registers.
This allows the user to set up the Slave's register configuration
in a structured manner.
rtu_baud: The baud rate for RTU communication.
Supported rates include: 110, 300, 600, 1200, 2400, 4800,
9600, 19200, 38400, 57600, 115200, 230400, 460800,
500000, 576000, 921600, 1000000, 1152000, 1500000,
2500000, 3000000, 3500000, 4000000.
Default is 115200. Ensure that the selected baud rate
is supported by the underlying hardware and libmodbus.
rtu_slave: The RTU slave address. Ignored in TCP mode. Default is 1.
tcp_port: The port used for TCP communication. Ignored in RTU mode. Default is 502.
debug: A boolean flag to enable or disable debug mode. Default is false.
seemodbus.Mode for valid modes.
+
+

C++ defination code:

+ +
Slave(maix::comm::modbus::Mode mode, const std::string& ip_or_device,
+            const Registers& registers=Registers{},
+            int rtu_baud=115200, uint8_t rtu_slave=1,
+            int tcp_port=502, bool debug=false)
+
+
+

Class

+ + +
+
+
+ + +
+
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixcdk/api/maix/network.html b/maixcdk/api/maix/network.html new file mode 100644 index 00000000..2454dff2 --- /dev/null +++ b/maixcdk/api/maix/network.html @@ -0,0 +1,376 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + maix::network - MaixCDK + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

maix::network

+ +
+
+
    + +
+
+
+
+ + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

maix.network module

+
+

This is maix::network module of MaixCDK.
+All of these elements are in namespace maix::network.

+

For MaixCDK developer: DO NOT edit this doc file manually, this doc is auto generated!

+
+

Module

+ + + + + + + + + + + + + +
modulebrief
wifimaix.network.wifi module
+

Enum

+

Variable

+

Function

+

have_network

+

Return if device have network(WiFi/Eth etc.)

+ + + + + + + + + + + + + +
itemdescription
returnTrue if have network, else False.
+
+

C++ defination code:

+ +
bool have_network()
+
+
+

Class

+ + +
+
+
+ + +
+
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixcdk/api/maix/network/wifi.html b/maixcdk/api/maix/network/wifi.html new file mode 100644 index 00000000..448a3e0c --- /dev/null +++ b/maixcdk/api/maix/network/wifi.html @@ -0,0 +1,1016 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + maix::network::wifi - MaixCDK + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

maix::network::wifi

+ +
+
+
    + +
+
+
+
+ + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

maix.network.wifi module

+
+

This is maix::network::wifi module of MaixCDK.
+All of these elements are in namespace maix::network::wifi.

+

For MaixCDK developer: DO NOT edit this doc file manually, this doc is auto generated!

+
+

Module

+

No module

+

Enum

+

Variable

+

Function

+

list_devices

+

List WiFi interfaces

+ + + + + + + + + + + + + +
itemdescription
returnWiFi interface list, string type
+
+

C++ defination code:

+ +
std::vector<std::string> list_devices()
+
+
+

Class

+

AP_Info

+

WiFi AP info

+
+

C++ defination code:

+ +
class AP_Info
+
+
+

ssid

+

WiFi AP info SSID

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typevar
staticFalse
readonlyFalse
+
+

C++ defination code:

+ +
std::vector<uint8_t> ssid
+
+
+

bssid

+

WiFi AP info BSSID

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typevar
staticFalse
readonlyFalse
+
+

C++ defination code:

+ +
std::string bssid
+
+
+

security

+

WiFi AP info security

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typevar
staticFalse
readonlyFalse
+
+

C++ defination code:

+ +
std::string security
+
+
+

channel

+

WiFi AP info channel

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typevar
staticFalse
readonlyFalse
+
+

C++ defination code:

+ +
int channel
+
+
+

frequency

+

WiFi AP info frequency

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typevar
staticFalse
readonlyFalse
+
+

C++ defination code:

+ +
int frequency
+
+
+

rssi

+

WiFi AP info rssi

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typevar
staticFalse
readonlyFalse
+
+

C++ defination code:

+ +
int rssi
+
+
+

ssid_str

+

WiFi AP info ssid_str

+ + + + + + + + + + + + + + + + + +
itemdescription
typefunc
staticFalse
+
+

C++ defination code:

+ +
std::string ssid_str()
+
+
+

Wifi

+

Wifi class

+
+

C++ defination code:

+ +
class Wifi
+
+
+

Wifi

+

Wifi class

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramiface: wifi interface name, default is wlan0
staticFalse
+
+

C++ defination code:

+ +
Wifi(std::string iface = "wlan0")
+
+
+

get_ip

+

Get current WiFi ip

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnip, string type, if network not connected, will return empty string.
staticFalse
+
+

C++ defination code:

+ +
std::string get_ip()
+
+
+

get_mac

+

Get current WiFi MAC address

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnip, string type.
staticFalse
+
+

C++ defination code:

+ +
std::string get_mac()
+
+
+

get_ssid

+

Get current WiFi SSID

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramfrom_cache: if true, will not read config from file, direct use ssid in cache.
attention, first time call this method will auto matically read config from file, and if call connect method will set cache.
returnSSID, string type.
staticFalse
+
+

C++ defination code:

+ +
std::string get_ssid(bool from_cache = true)
+
+
+

get_gateway

+

Get current WiFi ip

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnip, string type, if network not connected, will return empty string.
staticFalse
+
+

C++ defination code:

+ +
std::string get_gateway()
+
+
+

start_scan

+

WiFi start scan AP info around in background.

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnIf success, return err.Err.ERR_NONE, else means failed.
staticFalse
+
+

C++ defination code:

+ +
err::Err start_scan()
+
+
+

get_scan_result

+

Get WiFi scan AP info.

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnwifi.AP_Info list.
staticFalse
+
+

C++ defination code:

+ +
std::vector<network::wifi::AP_Info> get_scan_result()
+
+
+

stop_scan

+

Stop WiFi scan AP info.

+ + + + + + + + + + + + + + + + + +
itemdescription
typefunc
staticFalse
+
+

C++ defination code:

+ +
void stop_scan()
+
+
+

connect

+

Connect to WiFi AP.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramssid: SSID of AP
password: password of AP, if no password, leave it empty.
wait: wait for got IP or failed or timeout.
timeout: connect timeout internal, unit second.
returnIf success, return err.Err.ERR_NONE, else means failed.
staticFalse
+
+

C++ defination code:

+ +
err::Err connect(const std::string &ssid, const std::string &password, bool wait = true, int timeout = 60)
+
+
+

disconnect

+

Disconnect from WiFi AP.

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnIf success, return err.Err.ERR_NONE, else means failed.
staticFalse
+
+

C++ defination code:

+ +
err::Err disconnect()
+
+
+

is_connected

+

See if WiFi is connected to AP.

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnIf connected return true, else false.
staticFalse
+
+

C++ defination code:

+ +
bool is_connected()
+
+
+

start_ap

+

Start WiFi AP.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramssid: SSID of AP.
password: password of AP, if no password, leave it empty.
ip: ip address of hostap, default empty string means auto generated one according to hardware.
netmask: netmask, default 255.255.255.0, now only support 255.255.255.0 .
mode: WiFi mode, default g(IEEE 802.11g (2.4 GHz)), a = IEEE 802.11a (5 GHz), b = IEEE 802.11b (2.4 GHz).
channel: WiFi channel number, 0 means auto select. MaixCAM not support auto, will default channel 1.
hidden: hidden SSID or not.
returnIf success, return err.Err.ERR_NONE, else means failed.
staticFalse
+
+

C++ defination code:

+ +
err::Err start_ap(const std::string &ssid, const std::string &password,
+                          std::string mode = "g", int channel = 0,
+                          const std::string &ip = "192.168.66.1", const std::string &netmask = "255.255.255.0",
+                          bool hidden = false)
+
+
+

stop_ap

+

Stop WiFi AP.

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnIf success, return err.Err.ERR_NONE, else means failed.
staticFalse
+
+

C++ defination code:

+ +
err::Err stop_ap()
+
+
+

is_ap_mode

+

Whether WiFi is AP mode

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnTrue if AP mode now, or False.
staticFalse
+
+

C++ defination code:

+ +
bool is_ap_mode()
+
+
+ + +
+
+
+ + +
+
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixcdk/api/maix/nn.html b/maixcdk/api/maix/nn.html new file mode 100644 index 00000000..16575bc8 --- /dev/null +++ b/maixcdk/api/maix/nn.html @@ -0,0 +1,8785 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + maix::nn - MaixCDK + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

maix::nn

+ +
+
+
    + +
+
+
+
+ + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

maix.nn module

+
+

This is maix::nn module of MaixCDK.
+All of these elements are in namespace maix::nn.

+

For MaixCDK developer: DO NOT edit this doc file manually, this doc is auto generated!

+
+

Module

+ + + + + + + + + + + + + +
modulebrief
Fmaix.nn.F module
+

Enum

+

SpeechDevice

+

speech device

+ + + + + + + + + + + + + +
itemdescribe
valuesDEVICE_NONE:
DEVICE_PCM:
DEVICE_MIC:
DEVICE_WAV:
+
+

C++ defination code:

+ +
enum class SpeechDevice {
+    DEVICE_NONE = -1,
+    DEVICE_PCM,
+    DEVICE_MIC,
+    DEVICE_WAV,
+}
+
+
+

SpeechDecoder

+

speech decoder type

+ + + + + + + + + + + + + +
itemdescribe
valuesDECODER_RAW:
DECODER_DIG:
DECODER_LVCSR:
DECODER_KWS:
DECODER_ALL:
+
+

C++ defination code:

+ +
enum class SpeechDecoder {
+    DECODER_RAW = 1,
+    DECODER_DIG = 2,
+    DECODER_LVCSR = 4,
+    DECODER_KWS = 8,
+    DECODER_ALL = 65535,
+}
+
+
+

Variable

+

Function

+

Class

+

NanoTrack

+

NanoTrack class

+
+

C++ defination code:

+ +
class NanoTrack
+
+
+

NanoTrack

+

Constructor of NanoTrack class

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
parammodel: model path, default empty, you can load model later by load function.
throwIf model arg is not empty and load failed, will throw err::Exception.
staticFalse
+
+

C++ defination code:

+ +
NanoTrack(const string &model = "")
+
+
+

load

+

Load model from file

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
parammodel: Model path want to load
returnerr::Err
staticFalse
+
+

C++ defination code:

+ +
err::Err load(const string &model)
+
+
+

init

+

Init tracker, give tacker first target image and target position.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramimg: Image want to detect, target should be in this image.
x: the target position left top coordinate x.
y: the target position left top coordinate y.
w: the target width.
h: the target height.
throwIf image format not match model input format, will throw err::Exception.
staticFalse
+
+

C++ defination code:

+ +
void init(image::Image &img, int x, int y, int w, int h)
+
+
+

track

+

Track object acoording to last object position and the init function learned target feature.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramimg: image to detect object and track, can be any resolution, before detect it will crop a area according to last time target's position.
threshold: If score < threshold, will see this new detection is invalid, but remain return this new detecion, default 0.9.
returnobject, position and score, and detect area in points's first 4 element(x, y, w, h, center_x, center_y, input_size, target_size)
staticFalse
+
+

C++ defination code:

+ +
nn::Object track(image::Image &img, float threshold = 0.9)
+
+
+

input_size

+

Get model input size

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnmodel input size
staticFalse
+
+

C++ defination code:

+ +
image::Size input_size()
+
+
+

input_width

+

Get model input width

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnmodel input size of width
staticFalse
+
+

C++ defination code:

+ +
int input_width()
+
+
+

input_height

+

Get model input height

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnmodel input size of height
staticFalse
+
+

C++ defination code:

+ +
int input_height()
+
+
+

input_format

+

Get input image format

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returninput image format, image::Format type.
staticFalse
+
+

C++ defination code:

+ +
image::Format input_format()
+
+
+

mean

+

Get mean value, list type

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typevar
staticFalse
readonlyFalse
+
+

C++ defination code:

+ +
std::vector<float> mean
+
+
+

scale

+

Get scale value, list type

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typevar
staticFalse
readonlyFalse
+
+

C++ defination code:

+ +
std::vector<float> scale
+
+
+

OCR_Box

+

Object for OCR detect box

+
+

C++ defination code:

+ +
class OCR_Box
+
+
+

OCR_Box

+

OCR_Box constructor

+ + + + + + + + + + + + + + + + + +
itemdescription
typefunc
staticFalse
+
+

C++ defination code:

+ +
OCR_Box(int x1 = 0, int y1 = 0, int x2 = 0, int y2 = 0, int x3 = 0, int y3 = 0, int x4 = 0, int y4 = 0)
+
+
+

x1

+

left top point of box

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typevar
staticFalse
readonlyFalse
+
+

C++ defination code:

+ +
int x1
+
+
+

y1

+

left top point of box

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typevar
staticFalse
readonlyFalse
+
+

C++ defination code:

+ +
int y1
+
+
+

x2

+

right top point of box

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typevar
staticFalse
readonlyFalse
+
+

C++ defination code:

+ +
int x2
+
+
+

y2

+

right top point of box

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typevar
staticFalse
readonlyFalse
+
+

C++ defination code:

+ +
int y2
+
+
+

x3

+

right bottom point of box

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typevar
staticFalse
readonlyFalse
+
+

C++ defination code:

+ +
int x3
+
+
+

y3

+

right bottom point of box

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typevar
staticFalse
readonlyFalse
+
+

C++ defination code:

+ +
int y3
+
+
+

x4

+

left bottom point of box

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typevar
staticFalse
readonlyFalse
+
+

C++ defination code:

+ +
int x4
+
+
+

y4

+

left bottom point of box

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typevar
staticFalse
readonlyFalse
+
+

C++ defination code:

+ +
int y4
+
+
+

to_list

+

convert box point to a list type.

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnlist type, element is int type, value [x1, y1, x2, y2, x3, y3, x4, y4].
staticFalse
+
+

C++ defination code:

+ +
std::vector<int> to_list()
+
+
+

OCR_Object

+

Object for OCR detect result

+
+

C++ defination code:

+ +
class OCR_Object
+
+
+

OCR_Object

+

Constructor of Object for OCR detect result

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramscore: score
staticFalse
+
+

C++ defination code:

+ +
OCR_Object(const nn::OCR_Box &box, const std::vector<int> &idx_list, const std::vector<std::string> &char_list, float score = 0, const std::vector<int> &char_pos = std::vector<int>())
+
+
+

box

+

OCR_Object box, 4 points box, first point at the left-top, clock-wise.

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typevar
staticFalse
readonlyFalse
+
+

C++ defination code:

+ +
nn::OCR_Box box
+
+
+

score

+

Object score

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typevar
staticFalse
readonlyFalse
+
+

C++ defination code:

+ +
float score
+
+
+

idx_list

+

chars' idx list, element is int type.

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typevar
staticFalse
readonlyFalse
+
+

C++ defination code:

+ +
std::vector<int> idx_list
+
+
+

char_pos

+

Chars' position relative to left

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typevar
staticFalse
readonlyFalse
+
+

C++ defination code:

+ +
std::vector<int> char_pos
+
+
+

char_str

+

Get OCR_Object's charactors, return a string type.

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnAll charactors in string type.
staticFalse
+
+

C++ defination code:

+ +
const std::string &char_str()
+
+
+

char_list

+

Get OCR_Object's charactors, return a list type.

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnAll charactors in list type.
staticFalse
+
+

C++ defination code:

+ +
const std::vector<std::string> &char_list()
+
+
+

update_chars

+

Set OCR_Object's charactors

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramchar_list: All charactors in list type.
staticFalse
+
+

C++ defination code:

+ +
void update_chars(const std::vector<std::string> &char_list)
+
+
+

to_str

+

OCR_Object info to string

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnOCR_Object info string
staticFalse
+
+

C++ defination code:

+ +
std::string to_str()
+
+
+

OCR_Objects

+

OCR_Objects Class for detect result

+
+

C++ defination code:

+ +
class OCR_Objects
+
+
+

OCR_Objects

+

Constructor of OCR_Objects class

+ + + + + + + + + + + + + + + + + +
itemdescription
typefunc
staticFalse
+
+

C++ defination code:

+ +
OCR_Objects()
+
+
+

add

+

Add object to objects

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
throwThrow exception if no memory
staticFalse
+
+

C++ defination code:

+ +
nn::OCR_Object &add(const nn::OCR_Box &box, const std::vector<int> &idx_list, const std::vector<std::string> &char_list, float score = 0, const std::vector<int> &char_pos = std::vector<int>())
+
+
+

remove

+

Remove object form objects

+ + + + + + + + + + + + + + + + + +
itemdescription
typefunc
staticFalse
+
+

C++ defination code:

+ +
err::Err remove(int idx)
+
+
+

at

+

Get object item

+ + + + + + + + + + + + + + + + + +
itemdescription
typefunc
staticFalse
+
+

C++ defination code:

+ +
nn::OCR_Object &at(int idx)
+
+
+

[]

+

Get object item

+ + + + + + + + + + + + + + + + + +
itemdescription
typefunc
staticFalse
+
+

C++ defination code:

+ +
nn::OCR_Object &operator[](int idx)
+
+
+

size

+

Get size

+ + + + + + + + + + + + + + + + + +
itemdescription
typefunc
staticFalse
+
+

C++ defination code:

+ +
size_t size()
+
+
+

begin

+

Begin

+ + + + + + + + + + + + + + + + + +
itemdescription
typefunc
staticFalse
+
+

C++ defination code:

+ +
std::vector<OCR_Object*>::iterator begin()
+
+
+

end

+

End

+ + + + + + + + + + + + + + + + + +
itemdescription
typefunc
staticFalse
+
+

C++ defination code:

+ +
std::vector<OCR_Object*>::iterator end()
+
+
+

Speech

+

Speech

+
+

C++ defination code:

+ +
class Speech
+
+
+

Speech

+

Construct a new Speech object

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
parammodel: model path, default empty, you can load model later by load function.
throwIf model arg is not empty and load failed, will throw err::Exception.
staticFalse
+
+

C++ defination code:

+ +
Speech(const string &model = "")
+
+
+

Speech (overload 1)

+

Construct a new Speech object

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
parammodel: model path, default empty, you can load model later by load function.
throwIf model arg is not empty and load failed, will throw err::Exception.
staticFalse
+
+

C++ defination code:

+ +
Speech(const string &model = "")
+
+
+

load

+

Load model from file

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
parammodel: Model path want to load
returnerr::Err
staticFalse
+
+

C++ defination code:

+ +
err::Err load(const string &model)
+
+
+

load (overload 1)

+

Load model from file

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
parammodel: Model path want to load
returnerr::Err
staticFalse
+
+

C++ defination code:

+ +
err::Err load(const string &model)
+
+
+

init

+

Init the ASR library and select the type and name of the audio device.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramdev_type: device type want to detect, can choose between WAV, PCM, or MIC.
device_name: device name want to detect, can choose a WAV file, a PCM file, or a MIC device name.
throw1. If am model is not loaded, will throw err::ERR_NOT_IMPL.
2. If device is not supported, will throw err::ERR_NOT_IMPL.
returnerr::Err type, if init success, return err::ERR_NONE
staticFalse
+
+

C++ defination code:

+ +
err::Err init(nn::SpeechDevice dev_type, const string &device_name = "")
+
+
+

init (overload 1)

+

Init the ASR library and select the type and name of the audio device.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramdev_type: device type want to detect, can choose between WAV, PCM, or MIC.
device_name: device name want to detect, can choose a WAV file, a PCM file, or a MIC device name.
throw1. If am model is not loaded, will throw err::ERR_NOT_IMPL.
2. If device is not supported, will throw err::ERR_NOT_IMPL.
returnerr::Err type, if init success, return err::ERR_NONE
staticFalse
+
+

C++ defination code:

+ +
err::Err init(nn::SpeechDevice dev_type, const string &device_name = "")
+
+
+

devive

+

Reset the device, usually used for PCM/WAV recognition,\nsuch as identifying the next WAV file.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramdev_type: device type want to detect, can choose between WAV, PCM, or MIC.
device_name: device name want to detect, can choose a WAV file, a PCM file, or a MIC device name.
throwIf device is not supported, will throw err::ERR_NOT_IMPL.
returnerr::Err type, if init success, return err::ERR_NONE
staticFalse
+
+

C++ defination code:

+ +
err::Err devive(nn::SpeechDevice dev_type, const string &device_name)
+
+
+

devive (overload 1)

+

Reset the device, usually used for PCM/WAV recognition,\nsuch as identifying the next WAV file.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramdev_type: device type want to detect, can choose between WAV, PCM, or MIC.
device_name: device name want to detect, can choose a WAV file, a PCM file, or a MIC device name.
throwIf device is not supported, will throw err::ERR_NOT_IMPL.
returnerr::Err type, if init success, return err::ERR_NONE
staticFalse
+
+

C++ defination code:

+ +
err::Err devive(nn::SpeechDevice dev_type, const string &device_name)
+
+
+

dec_deinit

+

Deinit the decoder.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramdecoder: decoder type want to deinit
can choose between DECODER_RAW, DECODER_DIG, DECODER_LVCSR, DECODER_KWS or DECODER_ALL.
throwIf device is not supported, will throw err::ERR_NOT_IMPL.
staticFalse
+
+

C++ defination code:

+ +
void dec_deinit(nn::SpeechDecoder decoder)
+
+
+

dec_deinit (overload 1)

+

Deinit the decoder.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramdecoder: decoder type want to deinit
can choose between DECODER_RAW, DECODER_DIG, DECODER_LVCSR, DECODER_KWS or DECODER_ALL.
throwIf device is not supported, will throw err::ERR_NOT_IMPL.
staticFalse
+
+

C++ defination code:

+ +
void dec_deinit(nn::SpeechDecoder decoder)
+
+
+

raw

+

Init raw decoder, it will output the prediction results of the original AM.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramcallback: raw decoder user callback.
returnerr::Err type, if init success, return err::ERR_NONE
staticFalse
+
+

C++ defination code:

+ +
err::Err raw(std::function<void(std::vector<std::pair<int, float>>, int)> callback)
+
+
+

raw (overload 1)

+

Get raw decoder status

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnbool, raw decoder status
staticFalse
+
+

C++ defination code:

+ +
bool raw()
+
+
+

raw (overload 2)

+

Init raw decoder, it will output the prediction results of the original AM.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramcallback: raw decoder user callback.
returnerr::Err type, if init success, return err::ERR_NONE
staticFalse
+
+

C++ defination code:

+ +
err::Err raw(std::function<void(std::vector<std::pair<int, float>>, int)> callback)
+
+
+

raw (overload 3)

+

Get raw decoder status

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnbool, raw decoder status
staticFalse
+
+

C++ defination code:

+ +
bool raw()
+
+
+

digit

+

Init digit decoder, it will output the Chinese digit recognition results within the last 4 seconds.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramblank: If it exceeds this value, insert a '_' in the output result to indicate idle mute.
callback: digit decoder user callback.
returnerr::Err type, if init success, return err::ERR_NONE
staticFalse
+
+

C++ defination code:

+ +
err::Err digit(int blank, std::function<void(char*, int)> callback)
+
+
+

digit (overload 1)

+

Get digit decoder status

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnbool, digit decoder status
staticFalse
+
+

C++ defination code:

+ +
bool digit()
+
+
+

digit (overload 2)

+

Init digit decoder, it will output the Chinese digit recognition results within the last 4 seconds.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramblank: If it exceeds this value, insert a '_' in the output result to indicate idle mute.
callback: digit decoder user callback.
returnerr::Err type, if init success, return err::ERR_NONE
staticFalse
+
+

C++ defination code:

+ +
err::Err digit(int blank, std::function<void(char*, int)> callback)
+
+
+

digit (overload 3)

+

Get digit decoder status

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnbool, digit decoder status
staticFalse
+
+

C++ defination code:

+ +
bool digit()
+
+
+

kws

+

Init kws decoder, it will output a probability list of all registered keywords in the latest frame,\nusers can set their own thresholds for wake-up.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramkw_tbl: Keyword list, filled in with spaces separated by pinyin, for example: xiao3 ai4 tong2 xue2
kw_gate: kw_gate, keyword probability gate table, the number should be the same as kw_tbl
auto_similar: Whether to perform automatic homophone processing,
setting it to true will automatically calculate the probability by using pinyin with different tones as homophones
callback: digit decoder user callback.
returnerr::Err type, if init success, return err::ERR_NONE
staticFalse
+
+

C++ defination code:

+ +
err::Err kws(std::vector<string> kw_tbl, std::vector<float> kw_gate, std::function<void(std::vector<float>, int)> callback, bool auto_similar = true)
+
+
+

kws (overload 1)

+

Get kws decoder status

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnbool, kws decoder status
staticFalse
+
+

C++ defination code:

+ +
bool kws()
+
+
+

kws (overload 2)

+

Init kws decoder, it will output a probability list of all registered keywords in the latest frame,\nusers can set their own thresholds for wake-up.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramkw_tbl: Keyword list, filled in with spaces separated by pinyin, for example: xiao3 ai4 tong2 xue2
kw_gate: kw_gate, keyword probability gate table, the number should be the same as kw_tbl
auto_similar: Whether to perform automatic homophone processing,
setting it to true will automatically calculate the probability by using pinyin with different tones as homophones
callback: digit decoder user callback.
returnerr::Err type, if init success, return err::ERR_NONE
staticFalse
+
+

C++ defination code:

+ +
err::Err kws(std::vector<string> kw_tbl, std::vector<float> kw_gate, std::function<void(std::vector<float>, int)> callback, bool auto_similar = true)
+
+
+

kws (overload 3)

+

Get kws decoder status

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnbool, kws decoder status
staticFalse
+
+

C++ defination code:

+ +
bool kws()
+
+
+

lvcsr

+

Init lvcsr decoder, it will output continuous speech recognition results (less than 1024 Chinese characters).

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramsfst_name: Sfst file path.
sym_name: Sym file path (output symbol table).
phones_txt: Path to phones.bin (pinyin table).
words_txt: Path to words.bin (dictionary table).
callback: lvcsr decoder user callback.
beam: The beam size for WFST search is set to 8 by default, and it is recommended to be between 3 and 9.
The larger the size, the larger the search space, and the more accurate but slower the search.
bg_prob: The absolute value of the natural logarithm of the default probability value for background pinyin
outside of BEAM-CNT is set to 10 by default.
scale: acoustics_cost = log(pny_prob)scale.
mmap*: use mmap to load the WFST decoding image,
If set to true, the beam should be less than 5.
returnerr::Err type, if init success, return err::ERR_NONE
staticFalse
+
+

C++ defination code:

+ +
err::Err lvcsr(const string &sfst_name, const string &sym_name,
+                       const string &phones_txt, const string &words_txt, 
+                       std::function<void(std::pair<char*, char*>, int)> callback,
+                       float beam = 8, float bg_prob = 10, float scale = 0.5, bool mmap = false)
+
+
+

lvcsr (overload 1)

+

Get lvcsr decoder status

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnbool, lvcsr decoder status
staticFalse
+
+

C++ defination code:

+ +
bool lvcsr()
+
+
+

lvcsr (overload 2)

+

Init lvcsr decoder, it will output continuous speech recognition results (less than 1024 Chinese characters).

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramsfst_name: Sfst file path.
sym_name: Sym file path (output symbol table).
phones_txt: Path to phones.bin (pinyin table).
words_txt: Path to words.bin (dictionary table).
callback: lvcsr decoder user callback.
beam: The beam size for WFST search is set to 8 by default, and it is recommended to be between 3 and 9.
The larger the size, the larger the search space, and the more accurate but slower the search.
bg_prob: The absolute value of the natural logarithm of the default probability value for background pinyin
outside of BEAM-CNT is set to 10 by default.
scale: acoustics_cost = log(pny_prob)scale.
mmap*: use mmap to load the WFST decoding image,
If set to true, the beam should be less than 5.
returnerr::Err type, if init success, return err::ERR_NONE
staticFalse
+
+

C++ defination code:

+ +
err::Err lvcsr(const string &sfst_name, const string &sym_name,
+                       const string &phones_txt, const string &words_txt, 
+                       std::function<void(std::pair<char*, char*>, int)> callback,
+                       float beam = 8, float bg_prob = 10, float scale = 0.5, bool mmap = false)
+
+
+

lvcsr (overload 3)

+

Get lvcsr decoder status

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnbool, lvcsr decoder status
staticFalse
+
+

C++ defination code:

+ +
bool lvcsr()
+
+
+

run

+

Run speech recognition, user can run 1 frame at a time and do other processing after running,\nor it can run continuously within a thread and be stopped by an external thread.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramframe: The number of frames per run.
returnint type, return actual number of frames in the run.
staticFalse
+
+

C++ defination code:

+ +
int run(int frame)
+
+
+

run (overload 1)

+

Run speech recognition, user can run 1 frame at a time and do other processing after running,\nor it can run continuously within a thread and be stopped by an external thread.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramframe: The number of frames per run.
returnint type, return actual number of frames in the run.
staticFalse
+
+

C++ defination code:

+ +
int run(int frame)
+
+
+

clear

+

Reset internal cache operation

+ + + + + + + + + + + + + + + + + +
itemdescription
typefunc
staticFalse
+
+

C++ defination code:

+ +
void clear()
+
+
+

clear (overload 1)

+

Reset internal cache operation

+ + + + + + + + + + + + + + + + + +
itemdescription
typefunc
staticFalse
+
+

C++ defination code:

+ +
void clear()
+
+
+

frame_time

+

Get the time of one frame.

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnint type, return the time of one frame.
staticFalse
+
+

C++ defination code:

+ +
int frame_time()
+
+
+

frame_time (overload 1)

+

Get the time of one frame.

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnint type, return the time of one frame.
staticFalse
+
+

C++ defination code:

+ +
int frame_time()
+
+
+

similar

+

Manually register mute words, and each pinyin can register up to 10 homophones,\nplease note that using this interface to register homophones will overwrite,\nthe homophone table automatically generated in the "automatic homophone processing" feature.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramdev_type: device type want to detect, can choose between WAV, PCM, or MIC.
device_name: device name want to detect, can choose a WAV file, a PCM file, or a MIC device name.
returnerr::Err type, if init success, return err::ERR_NONE
staticFalse
+
+

C++ defination code:

+ +
err::Err similar(const string &pny, std::vector<std::string> similar_pnys)
+
+
+

similar (overload 1)

+

Manually register mute words, and each pinyin can register up to 10 homophones,\nplease note that using this interface to register homophones will overwrite,\nthe homophone table automatically generated in the "automatic homophone processing" feature.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramdev_type: device type want to detect, can choose between WAV, PCM, or MIC.
device_name: device name want to detect, can choose a WAV file, a PCM file, or a MIC device name.
returnerr::Err type, if init success, return err::ERR_NONE
staticFalse
+
+

C++ defination code:

+ +
err::Err similar(const string &pny, std::vector<std::string> similar_pnys)
+
+
+

skip_frames

+

Run some frames and drop, this can be used to avoid\nincorrect recognition results when switching decoders.

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramnum: number of frames to run and drop
staticFalse
+
+

C++ defination code:

+ +
void skip_frames(int num)
+
+
+

skip_frames (overload 1)

+

Run some frames and drop, this can be used to avoid\nincorrect recognition results when switching decoders.

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramnum: number of frames to run and drop
staticFalse
+
+

C++ defination code:

+ +
void skip_frames(int num)
+
+
+

mean

+

Get mean value, list type

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typevar
staticFalse
readonlyFalse
+
+

C++ defination code:

+ +
std::vector<float> mean
+
+
+

scale

+

Get scale value, list type

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typevar
staticFalse
readonlyFalse
+
+

C++ defination code:

+ +
std::vector<float> scale
+
+
+

dev_type

+

get device type

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnnn::SpeechDevice type, see SpeechDevice of this module
staticFalse
+
+

C++ defination code:

+ +
nn::SpeechDevice dev_type()
+
+
+

dev_type (overload 1)

+

get device type

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnnn::SpeechDevice type, see SpeechDevice of this module
staticFalse
+
+

C++ defination code:

+ +
nn::SpeechDevice dev_type()
+
+
+

YOLOv8

+

YOLOv8 class

+
+

C++ defination code:

+ +
class YOLOv8
+
+
+

YOLOv8

+

Constructor of YOLOv8 class

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
parammodel: model path, default empty, you can load model later by load function.
dual_buff: direction [in], prepare dual input output buffer to accelarate forward, that is, when NPU is forwarding we not wait and prepare the next input buff.
If you want to ensure every time forward output the input's result, set this arg to false please.
Default true to ensure speed.
throwIf model arg is not empty and load failed, will throw err::Exception.
staticFalse
+
+

C++ defination code:

+ +
YOLOv8(const string &model = "", bool dual_buff = true)
+
+
+

load

+

Load model from file

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
parammodel: Model path want to load
returnerr::Err
staticFalse
+
+

C++ defination code:

+ +
err::Err load(const string &model)
+
+
+

detect

+

Detect objects from image

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramimg: Image want to detect, if image's size not match model input's, will auto resize with fit method.
conf_th: Confidence threshold, default 0.5.
iou_th: IoU threshold, default 0.45.
fit: Resize method, default image.Fit.FIT_CONTAIN.
keypoint_th: keypoint threshold, default 0.5, only for yolov8-pose model.
throwIf image format not match model input format, will throw err::Exception.
returnObject list. In C++, you should delete it after use.
If model is yolov8-pose, object's points have value, and if points' value < 0 means that point is invalid(conf < keypoint_th).
staticFalse
+
+

C++ defination code:

+ +
nn::Objects *detect(image::Image &img, float conf_th = 0.5, float iou_th = 0.45, maix::image::Fit fit = maix::image::FIT_CONTAIN, float keypoint_th = 0.5)
+
+
+

input_size

+

Get model input size

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnmodel input size
staticFalse
+
+

C++ defination code:

+ +
image::Size input_size()
+
+
+

input_width

+

Get model input width

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnmodel input size of width
staticFalse
+
+

C++ defination code:

+ +
int input_width()
+
+
+

input_height

+

Get model input height

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnmodel input size of height
staticFalse
+
+

C++ defination code:

+ +
int input_height()
+
+
+

input_format

+

Get input image format

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returninput image format, image::Format type.
staticFalse
+
+

C++ defination code:

+ +
image::Format input_format()
+
+
+

draw_pose

+

Draw pose keypoints on image

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramimg: image object, maix.image.Image type.
points: keypoits, int list type, [x, y, x, y ...]
radius: radius of points.
color: color of points.
body: true, if points' length is 17*2 and body is ture, will draw lines as human body, if set to false won't draw lines, default true.
staticFalse
+
+

C++ defination code:

+ +
void draw_pose(image::Image &img, std::vector<int> points, int radius = 4, image::Color color = image::COLOR_RED, bool body = true)
+
+
+

draw_seg_mask

+

Draw segmentation on image

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramimg: image object, maix.image.Image type.
seg_mask: segmentation mask image by detect method, a grayscale image
threshold: only mask's value > threshold will be draw on image, value from 0 to 255.
staticFalse
+
+

C++ defination code:

+ +
void draw_seg_mask(image::Image &img, int x, int y, image::Image &seg_mask, int threshold = 127)
+
+
+

labels

+

Labels list

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typevar
staticFalse
readonlyFalse
+
+

C++ defination code:

+ +
std::vector<string> labels
+
+
+

label_path

+

Label file path

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typevar
staticFalse
readonlyFalse
+
+

C++ defination code:

+ +
std::string label_path
+
+
+

mean

+

Get mean value, list type

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typevar
staticFalse
readonlyFalse
+
+

C++ defination code:

+ +
std::vector<float> mean
+
+
+

scale

+

Get scale value, list type

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typevar
staticFalse
readonlyFalse
+
+

C++ defination code:

+ +
std::vector<float> scale
+
+
+

Object

+

Object for detect result

+
+

C++ defination code:

+ +
class Object
+
+
+

Object

+

Constructor of Object for detect result

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramx: left top x
y: left top y
w: width
h: height
class_id: class id
score: score
staticFalse
+
+

C++ defination code:

+ +
Object(int x = 0, int y = 0, int w = 0, int h = 0, int class_id = 0, float score = 0, std::vector<int> points = std::vector<int>())
+
+
+

to_str

+

Object info to string

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnObject info string
staticFalse
+
+

C++ defination code:

+ +
std::string to_str()
+
+
+

x

+

Object left top coordinate x

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typevar
staticFalse
readonlyFalse
+
+

C++ defination code:

+ +
int x
+
+
+

y

+

Object left top coordinate y

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typevar
staticFalse
readonlyFalse
+
+

C++ defination code:

+ +
int y
+
+
+

w

+

Object width

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typevar
staticFalse
readonlyFalse
+
+

C++ defination code:

+ +
int w
+
+
+

h

+

Object height

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typevar
staticFalse
readonlyFalse
+
+

C++ defination code:

+ +
int h
+
+
+

class_id

+

Object class id

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typevar
staticFalse
readonlyFalse
+
+

C++ defination code:

+ +
int class_id
+
+
+

score

+

Object score

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typevar
staticFalse
readonlyFalse
+
+

C++ defination code:

+ +
float score
+
+
+

points

+

keypoints

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typevar
staticFalse
readonlyFalse
+
+

C++ defination code:

+ +
std::vector<int> points
+
+
+

seg_mask

+

segmentation mask, uint8 list type, shape is h * w but flattened to one dimension, value fron 0 to 255.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typevar
attentionFor efficiency, it's a pointer in C++, use this carefully!
staticFalse
readonlyFalse
+
+

C++ defination code:

+ +
image::Image *seg_mask
+
+
+

ObjectFloat

+

Object for detect result

+
+

C++ defination code:

+ +
class ObjectFloat
+
+
+

ObjectFloat

+

Constructor of Object for detect result

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramx: left top x
y: left top y
w: width
h: height
class_id: class id
score: score
staticFalse
+
+

C++ defination code:

+ +
ObjectFloat(float x = 0, float y = 0, float w = 0, float h = 0, float class_id = 0, float score = 0, std::vector<float> points = std::vector<float>())
+
+
+

to_str

+

Object info to string

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnObject info string
staticFalse
+
+

C++ defination code:

+ +
std::string to_str()
+
+
+

x

+

Object left top coordinate x

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typevar
staticFalse
readonlyFalse
+
+

C++ defination code:

+ +
float x
+
+
+

y

+

Object left top coordinate y

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typevar
staticFalse
readonlyFalse
+
+

C++ defination code:

+ +
float y
+
+
+

w

+

Object width

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typevar
staticFalse
readonlyFalse
+
+

C++ defination code:

+ +
float w
+
+
+

h

+

Object height

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typevar
staticFalse
readonlyFalse
+
+

C++ defination code:

+ +
float h
+
+
+

class_id

+

Object class id

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typevar
staticFalse
readonlyFalse
+
+

C++ defination code:

+ +
float class_id
+
+
+

score

+

Object score

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typevar
staticFalse
readonlyFalse
+
+

C++ defination code:

+ +
float score
+
+
+

points

+

keypoints

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typevar
staticFalse
readonlyFalse
+
+

C++ defination code:

+ +
std::vector<float> points
+
+
+

Objects

+

Objects Class for detect result

+
+

C++ defination code:

+ +
class Objects
+
+
+

Objects

+

Constructor of Objects class

+ + + + + + + + + + + + + + + + + +
itemdescription
typefunc
staticFalse
+
+

C++ defination code:

+ +
Objects()
+
+
+

add

+

Add object to objects

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
throwThrow exception if no memory
staticFalse
+
+

C++ defination code:

+ +
nn::Object &add(int x = 0, int y = 0, int w = 0, int h = 0, int class_id = 0, float score = 0, std::vector<int> points = std::vector<int>())
+
+
+

remove

+

Remove object form objects

+ + + + + + + + + + + + + + + + + +
itemdescription
typefunc
staticFalse
+
+

C++ defination code:

+ +
err::Err remove(int idx)
+
+
+

at

+

Get object item

+ + + + + + + + + + + + + + + + + +
itemdescription
typefunc
staticFalse
+
+

C++ defination code:

+ +
nn::Object &at(int idx)
+
+
+

[]

+

Get object item

+ + + + + + + + + + + + + + + + + +
itemdescription
typefunc
staticFalse
+
+

C++ defination code:

+ +
nn::Object &operator[](int idx)
+
+
+

size

+

Get size

+ + + + + + + + + + + + + + + + + +
itemdescription
typefunc
staticFalse
+
+

C++ defination code:

+ +
size_t size()
+
+
+

begin

+

Begin

+ + + + + + + + + + + + + + + + + +
itemdescription
typefunc
staticFalse
+
+

C++ defination code:

+ +
std::vector<Object*>::iterator begin()
+
+
+

end

+

End

+ + + + + + + + + + + + + + + + + +
itemdescription
typefunc
staticFalse
+
+

C++ defination code:

+ +
std::vector<Object*>::iterator end()
+
+
+

MUD

+

MUD(model universal describe file) class

+
+

C++ defination code:

+ +
class MUD
+
+
+

MUD

+

MUD constructor

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
parammodel_path: direction [in], model file path, model format can be MUD(model universal describe file) file.
If model_path set, will load model from file, load failed will raise err.Exception.
If model_path not set, you can load model later by load function.
staticFalse
+
+

C++ defination code:

+ +
MUD(const char *model_path = nullptr)
+
+
+

load

+

Load model from file

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
parammodel_path: direction [in], model file path, model format can be MUD(model universal describe file) file.
returnerror code, if load success, return err::ERR_NONE
staticFalse
+
+

C++ defination code:

+ +
err::Err load(const std::string &model_path)
+
+
+

type

+

Model type, string type

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typevar
staticFalse
readonlyFalse
+
+

C++ defination code:

+ +
std::string type
+
+
+

items

+

Model config items, different model type has different config items

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typevar
staticFalse
readonlyFalse
+
+

C++ defination code:

+ +
std::map<std::string, std::map<std::string, std::string>> items
+
+
+

LayerInfo

+

NN model layer info

+
+

C++ defination code:

+ +
class LayerInfo
+
+
+

LayerInfo

+

LayerInfo constructor

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramname: direction [in], layer name
dtype: direction [in], layer data type
shape: direction [in], layer shape
staticFalse
+
+

C++ defination code:

+ +
LayerInfo(const std::string &name =  "", tensor::DType dtype = tensor::DType::FLOAT32, std::vector<int> shape = std::vector<int>())
+
+
+

name

+

Layer name

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typevar
staticFalse
readonlyFalse
+
+

C++ defination code:

+ +
std::string   name
+
+
+

dtype

+

Layer data type

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typevar
attentionIf model is quantized, this is the real quantized data type like int8 float16,
in most scene, inputs and outputs we actually use float32 in API like forward.
staticFalse
readonlyFalse
+
+

C++ defination code:

+ +
tensor::DType dtype
+
+
+

shape

+

Layer shape

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typevar
staticFalse
readonlyFalse
+
+

C++ defination code:

+ +
std::vector<int> shape
+
+
+

shape_int

+

Shape as one int type, multiply all dims of shape

+ + + + + + + + + + + + + + + + + +
itemdescription
typefunc
staticFalse
+
+

C++ defination code:

+ +
int shape_int()
+
+
+

to_str

+

To string

+ + + + + + + + + + + + + + + + + +
itemdescription
typefunc
staticFalse
+
+

C++ defination code:

+ +
std::string to_str()
+
+
+

__str__

+

To string

+ + + + + + + + + + + + + + + + + +
itemdescription
typefunc
staticFalse
+
+

C++ defination code:

+ +
std::string __str__()
+
+
+

NN

+

Neural network class

+
+

C++ defination code:

+ +
class NN
+
+
+

__init__

+

Neural network constructor

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
parammodel: direction [in], model file path, model format can be MUD(model universal describe file) file.
If model_path set, will load model from file, load failed will raise err.Exception.
If model_path not set, you can load model later by load function.
dual_buff: direction [in], prepare dual input output buffer to accelarate forward, that is, when NPU is forwarding we not wait and prepare the next input buff.
If you want to ensure every time forward output the input's result, set this arg to false please.
Default true to ensure speed.
staticFalse
+
+

C++ defination code:

+ +
NN(const std::string &model = "", bool dual_buff = true)
+
+
+

load

+

Load model from file

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
parammodel: direction [in], model file path, model format can be MUD(model universal describe file) file.
returnerror code, if load success, return err::ERR_NONE
staticFalse
+
+

C++ defination code:

+ +
err::Err load(const std::string &model)
+
+
+

loaded

+

Is model loaded

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returntrue if model loaded, else false
staticFalse
+
+

C++ defination code:

+ +
bool loaded()
+
+
+

set_dual_buff

+

Enable dual buff or disable dual buff

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramenable: true to enable, false to disable
staticFalse
+
+

C++ defination code:

+ +
void set_dual_buff(bool enable)
+
+
+

inputs_info

+

Get model input layer info

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returninput layer info
staticFalse
+
+

C++ defination code:

+ +
std::vector<nn::LayerInfo> inputs_info()
+
+
+

outputs_info

+

Get model output layer info

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnoutput layer info
staticFalse
+
+

C++ defination code:

+ +
std::vector<nn::LayerInfo> outputs_info()
+
+
+

extra_info

+

Get model extra info define in MUD file

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnextra info, dict type, key-value object, attention: key and value are all string type.
staticFalse
+
+

C++ defination code:

+ +
std::map<std::string, std::string> extra_info()
+
+
+

forward

+

forward run model, get output of model,\nthis is specially for MaixPy, not efficient, but easy to use in MaixPy

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paraminput: direction [in], input tensor
copy_result: If set true, will copy result to a new variable; else will use a internal memory, you can only use it until to the next forward.
Default true to avoid problems, you can set it to false manually to make speed faster.
dual_buff_wait: bool type, only for dual_buff mode, if true, will inference this image and wait for result, default false.
returnoutput tensor. In C++, you should manually delete tensors in return value and return value.
If dual_buff mode, it can be NULL(None in MaixPy) means not ready.
throwif error ocurrs like no memory or arg error, will raise err.Exception.
staticFalse
+
+

C++ defination code:

+ +
tensor::Tensors *forward(tensor::Tensors &inputs, bool copy_result = true, bool dual_buff_wait = false)
+
+
+

forward_image

+

forward model, param is image

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramimg: input image
mean: mean value, a list type, e.g. [0.485, 0.456, 0.406], default is empty list means not normalize.
scale: scale value, a list type, e.g. [1/0.229, 1/0.224, 1/0.225], default is empty list means not normalize.
fit: fit mode, if the image size of input not equal to model's input, it will auto resize use this fit method,
default is image.Fit.FIT_FILL for easy coordinate calculation, but for more accurate result, use image.Fit.FIT_CONTAIN is better.
copy_result: If set true, will copy result to a new variable; else will use a internal memory, you can only use it until to the next forward.
Default true to avoid problems, you can set it to false manually to make speed faster.
dual_buff_wait: bool type, only for dual_buff mode, if true, will inference this image and wait for result, default false.
returnoutput tensor. In C++, you should manually delete tensors in return value and return value.
If dual_buff mode, it can be NULL(None in MaixPy) means not ready.
throwIf error occurs, like arg error or alloc memory failed, will raise err.Exception.
staticFalse
+
+

C++ defination code:

+ +
tensor::Tensors *forward_image(image::Image &img, std::vector<float> mean = std::vector<float>(), std::vector<float> scale = std::vector<float>(), image::Fit fit = image::Fit::FIT_FILL, bool copy_result = true, bool dual_buff_wait = false)
+
+
+

FaceObject

+

Face object

+
+

C++ defination code:

+ +
class FaceObject
+
+
+

FaceObject

+

Constructor

+ + + + + + + + + + + + + + + + + +
itemdescription
typefunc
staticFalse
+
+

C++ defination code:

+ +
FaceObject(int x = 0, int y = 0, int w = 0, int h = 0, int class_id = 0, float score = 0, std::vector<int> points = std::vector<int>(), std::vector<float> feature = std::vector<float>(), image::Image face = image::Image())
+
+
+

to_str

+

FaceObject info to string

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnFaceObject info string
staticFalse
+
+

C++ defination code:

+ +
std::string to_str()
+
+
+

x

+

FaceObject left top coordinate x

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typevar
staticFalse
readonlyFalse
+
+

C++ defination code:

+ +
int x
+
+
+

y

+

FaceObject left top coordinate y

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typevar
staticFalse
readonlyFalse
+
+

C++ defination code:

+ +
int y
+
+
+

w

+

FaceObject width

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typevar
staticFalse
readonlyFalse
+
+

C++ defination code:

+ +
int w
+
+
+

h

+

FaceObject height

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typevar
staticFalse
readonlyFalse
+
+

C++ defination code:

+ +
int h
+
+
+

class_id

+

FaceObject class id

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typevar
staticFalse
readonlyFalse
+
+

C++ defination code:

+ +
int class_id
+
+
+

score

+

FaceObject score

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typevar
staticFalse
readonlyFalse
+
+

C++ defination code:

+ +
float score
+
+
+

points

+

keypoints

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typevar
staticFalse
readonlyFalse
+
+

C++ defination code:

+ +
std::vector<int> points
+
+
+

feature

+

feature, float list type

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typevar
staticFalse
readonlyFalse
+
+

C++ defination code:

+ +
std::vector<float> feature
+
+
+

face

+

face image

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typevar
staticFalse
readonlyFalse
+
+

C++ defination code:

+ +
image::Image face
+
+
+

FaceObjects

+

Objects Class for detect result

+
+

C++ defination code:

+ +
class FaceObjects
+
+
+

FaceObjects

+

Constructor of FaceObjects class

+ + + + + + + + + + + + + + + + + +
itemdescription
typefunc
staticFalse
+
+

C++ defination code:

+ +
FaceObjects()
+
+
+

add

+

Add object to FaceObjects

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
throwThrow exception if no memory
staticFalse
+
+

C++ defination code:

+ +
nn::FaceObject &add(int x = 0, int y = 0, int w = 0, int h = 0, int class_id = 0, float score = 0, std::vector<int> points = std::vector<int>(), std::vector<float> feature = std::vector<float>(), image::Image face = image::Image())
+
+
+

remove

+

Remove object form FaceObjects

+ + + + + + + + + + + + + + + + + +
itemdescription
typefunc
staticFalse
+
+

C++ defination code:

+ +
err::Err remove(int idx)
+
+
+

at

+

Get object item

+ + + + + + + + + + + + + + + + + +
itemdescription
typefunc
staticFalse
+
+

C++ defination code:

+ +
nn::FaceObject &at(int idx)
+
+
+

[]

+

Get object item

+ + + + + + + + + + + + + + + + + +
itemdescription
typefunc
staticFalse
+
+

C++ defination code:

+ +
nn::FaceObject &operator[](int idx)
+
+
+

size

+

Get size

+ + + + + + + + + + + + + + + + + +
itemdescription
typefunc
staticFalse
+
+

C++ defination code:

+ +
size_t size()
+
+
+

begin

+

Begin

+ + + + + + + + + + + + + + + + + +
itemdescription
typefunc
staticFalse
+
+

C++ defination code:

+ +
std::vector<FaceObject*>::iterator begin()
+
+
+

end

+

End

+ + + + + + + + + + + + + + + + + +
itemdescription
typefunc
staticFalse
+
+

C++ defination code:

+ +
std::vector<FaceObject*>::iterator end()
+
+
+

FaceRecognizer

+

FaceRecognizer class

+
+

C++ defination code:

+ +
class FaceRecognizer
+
+
+

FaceRecognizer

+

Constructor of FaceRecognizer class

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramdetect_model: face detect model path, default empty, you can load model later by load function.
feature_model: feature extract model
dual_buff: direction [in], prepare dual input output buffer to accelarate forward, that is, when NPU is forwarding we not wait and prepare the next input buff.
If you want to ensure every time forward output the input's result, set this arg to false please.
Default true to ensure speed.
throwIf model arg is not empty and load failed, will throw err::Exception.
staticFalse
+
+

C++ defination code:

+ +
FaceRecognizer(const string &detect_model = "", const string &feature_model = "", bool dual_buff = true)
+
+
+

load

+

Load model from file

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramdetect_model: face detect model path, default empty, you can load model later by load function.
feature_model: feature extract model
returnerr::Err
staticFalse
+
+

C++ defination code:

+ +
err::Err load(const string &detect_model, const string &feature_model)
+
+
+

recognize

+

Detect objects from image

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramimg: Image want to detect, if image's size not match model input's, will auto resize with fit method.
conf_th: Detect confidence threshold, default 0.5.
iou_th: Detect IoU threshold, default 0.45.
compare_th: Compare two face score threshold, default 0.8, if two faces' score < this value, will see this face fas unknown.
get_feature: return feature or not, if true will copy features to result, if false will not copy feature to result to save time and memory.
get_face: return face image or not, if true result object's face attribute will valid, or face sttribute is empty. Get face image will alloc memory and copy image, so will lead to slower speed.
fit: Resize method, default image.Fit.FIT_CONTAIN.
throwIf image format not match model input format, will throw err::Exception.
returnFaceObjects object. In C++, you should delete it after use.
staticFalse
+
+

C++ defination code:

+ +
nn::FaceObjects *recognize(image::Image &img, float conf_th = 0.5, float iou_th = 0.45, float compare_th = 0.8, bool get_feature = false, bool get_face = false, maix::image::Fit fit = maix::image::FIT_CONTAIN)
+
+
+

add_face

+

Add face to lib

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramface: face object, find by recognize
label: face label(name)
staticFalse
+
+

C++ defination code:

+ +
err::Err add_face(nn::FaceObject *face, const std::string &label)
+
+
+

remove_face

+

remove face from lib

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramidx: index of face in lib, default -1 means use label, value [0,face_num), idx and label must have one, idx have high priotiry.
label: which face to remove, default to empty string mean use idx, idx and label must have one, idx have high priotiry.
staticFalse
+
+

C++ defination code:

+ +
err::Err remove_face(int idx = -1, const std::string &label = "")
+
+
+

save_faces

+

Save faces info to a file

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
parampath: where to save, string type.
returnerr.Err type
staticFalse
+
+

C++ defination code:

+ +
err::Err save_faces(const std::string &path)
+
+
+

load_faces

+

Load faces info from a file

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
parampath: from where to load, string type.
returnerr::Err type
staticFalse
+
+

C++ defination code:

+ +
err::Err load_faces(const std::string &path)
+
+
+

input_size

+

Get model input size

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnmodel input size
staticFalse
+
+

C++ defination code:

+ +
image::Size input_size()
+
+
+

input_width

+

Get model input width

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnmodel input size of width
staticFalse
+
+

C++ defination code:

+ +
int input_width()
+
+
+

input_height

+

Get model input height

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnmodel input size of height
staticFalse
+
+

C++ defination code:

+ +
int input_height()
+
+
+

input_format

+

Get input image format

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returninput image format, image::Format type.
staticFalse
+
+

C++ defination code:

+ +
image::Format input_format()
+
+
+

mean_detector

+

Get mean value, list type

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typevar
staticFalse
readonlyFalse
+
+

C++ defination code:

+ +
std::vector<float> mean_detector
+
+
+

scale_detector

+

Get scale value, list type

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typevar
staticFalse
readonlyFalse
+
+

C++ defination code:

+ +
std::vector<float> scale_detector
+
+
+

mean_feature

+

Get mean value, list type

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typevar
staticFalse
readonlyFalse
+
+

C++ defination code:

+ +
std::vector<float> mean_feature
+
+
+

scale_feature

+

Get scale value, list type

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typevar
staticFalse
readonlyFalse
+
+

C++ defination code:

+ +
std::vector<float> scale_feature
+
+
+

labels

+

labels, list type, first is "unknown"

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typevar
staticFalse
readonlyFalse
+
+

C++ defination code:

+ +
std::vector<std::string> labels
+
+
+

features

+

features

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typevar
staticFalse
readonlyFalse
+
+

C++ defination code:

+ +
std::vector<std::vector<float>> features
+
+
+

SelfLearnClassifier

+

SelfLearnClassifier

+
+

C++ defination code:

+ +
class SelfLearnClassifier
+
+
+

SelfLearnClassifier

+

Construct a new SelfLearnClassifier object

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
parammodel: MUD model path, if empty, will not load model, you can call load_model() later.
if not empty, will load model and will raise err::Exception if load failed.
dual_buff: direction [in], prepare dual input output buffer to accelarate forward, that is, when NPU is forwarding we not wait and prepare the next input buff.
If you want to ensure every time forward output the input's result, set this arg to false please.
Default true to ensure speed.
staticFalse
+
+

C++ defination code:

+ +
SelfLearnClassifier(const std::string &model = "", bool dual_buff = true)
+
+
+

load_model

+

Load model from file, model format is .mud,\nMUD file should contain [extra] section, have key-values:\n- model_type: classifier_no_top\n- input_type: rgb or bgr\n- mean: 123.675, 116.28, 103.53\n- scale: 0.017124753831663668, 0.01750700280112045, 0.017429193899782137

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
parammodel: MUD model path
returnerror code, if load failed, return error code
staticFalse
+
+

C++ defination code:

+ +
err::Err load_model(const string &model)
+
+
+

classify

+

Classify image

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramimg: image, format should match model input_type, or will raise err.Exception
fit: image resize fit mode, default Fit.FIT_COVER, see image.Fit.
throwIf error occurred, will raise err::Exception, you can find reason in log, mostly caused by args error or hardware error.
returnresult, a list of (idx, distance), smaller distance means more similar. In C++, you need to delete it after use.
staticFalse
+
+

C++ defination code:

+ +
std::vector<std::pair<int, float>> *classify(image::Image &img, image::Fit fit = image::FIT_COVER)
+
+
+

add_class

+

Add a class to recognize

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramimg: Add a image as a new class
fit: image resize fit mode, default Fit.FIT_COVER, see image.Fit.
staticFalse
+
+

C++ defination code:

+ +
void add_class(image::Image &img, image::Fit fit = image::FIT_COVER)
+
+
+

class_num

+

Get class number

+ + + + + + + + + + + + + + + + + +
itemdescription
typefunc
staticFalse
+
+

C++ defination code:

+ +
int class_num()
+
+
+

rm_class

+

Remove a class

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramidx: index, value from 0 to class_num();
staticFalse
+
+

C++ defination code:

+ +
err::Err rm_class(int idx)
+
+
+

add_sample

+

Add sample, you should call learn method after add some samples to learn classes.\nSample image can be any of classes we already added.

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramimg: Add a image as a new sample.
staticFalse
+
+

C++ defination code:

+ +
void add_sample(image::Image &img, image::Fit fit = image::FIT_COVER)
+
+
+

rm_sample

+

Remove a sample

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramidx: index, value from 0 to sample_num();
staticFalse
+
+

C++ defination code:

+ +
err::Err rm_sample(int idx)
+
+
+

sample_num

+

Get sample number

+ + + + + + + + + + + + + + + + + +
itemdescription
typefunc
staticFalse
+
+

C++ defination code:

+ +
int sample_num()
+
+
+

learn

+

Start auto learn class features from classes image and samples.\nYou should call this method after you add some samples.

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnlearn epoch(times), 0 means learn nothing.
staticFalse
+
+

C++ defination code:

+ +
int learn()
+
+
+

clear

+

Clear all class and samples

+ + + + + + + + + + + + + + + + + +
itemdescription
typefunc
staticFalse
+
+

C++ defination code:

+ +
void clear()
+
+
+

input_size

+

Get model input size, only for image input

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnmodel input size
staticFalse
+
+

C++ defination code:

+ +
image::Size input_size()
+
+
+

input_width

+

Get model input width, only for image input

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnmodel input size of width
staticFalse
+
+

C++ defination code:

+ +
int input_width()
+
+
+

input_height

+

Get model input height, only for image input

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnmodel input size of height
staticFalse
+
+

C++ defination code:

+ +
int input_height()
+
+
+

input_format

+

Get input image format, only for image input

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returninput image format, image::Format type.
staticFalse
+
+

C++ defination code:

+ +
image::Format input_format()
+
+
+

input_shape

+

Get input shape, if have multiple input, only return first input shape

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returninput shape, list type
staticFalse
+
+

C++ defination code:

+ +
std::vector<int> input_shape()
+
+
+

save

+

Save features and labels to a binary file

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
parampath: file path to save, e.g. /root/my_classes.bin
labels: class labels, can be None, or length must equal to class num, or will return err::Err
returnmaix.err.Err if labels exists but length not equal to class num, or save file failed, or class num is 0.
staticFalse
+
+

C++ defination code:

+ +
err::Err save(const std::string &path, const std::vector<std::string> &labels = std::vector<std::string>())
+
+
+

load

+

Load features info from binary file

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
parampath: feature info binary file path, e.g. /root/my_classes.bin
staticFalse
+
+

C++ defination code:

+ +
std::vector<std::string> load(const std::string &path)
+
+
+

labels

+

Labels list

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typevar
staticFalse
readonlyFalse
+
+

C++ defination code:

+ +
std::vector<string> labels
+
+
+

label_path

+

Label file path

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typevar
staticFalse
readonlyFalse
+
+

C++ defination code:

+ +
std::string label_path
+
+
+

mean

+

Get mean value, list type

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typevar
staticFalse
readonlyFalse
+
+

C++ defination code:

+ +
std::vector<float> mean
+
+
+

scale

+

Get scale value, list type

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typevar
staticFalse
readonlyFalse
+
+

C++ defination code:

+ +
std::vector<float> scale
+
+
+

YOLOv5

+

YOLOv5 class

+
+

C++ defination code:

+ +
class YOLOv5
+
+
+

YOLOv5

+

Constructor of YOLOv5 class

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
parammodel: model path, default empty, you can load model later by load function.
dual_buff: direction [in], prepare dual input output buffer to accelarate forward, that is, when NPU is forwarding we not wait and prepare the next input buff.
If you want to ensure every time forward output the input's result, set this arg to false please.
Default true to ensure speed.
throwIf model arg is not empty and load failed, will throw err::Exception.
staticFalse
+
+

C++ defination code:

+ +
YOLOv5(const string &model = "", bool dual_buff = true)
+
+
+

load

+

Load model from file

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
parammodel: Model path want to load
returnerr::Err
staticFalse
+
+

C++ defination code:

+ +
err::Err load(const string &model)
+
+
+

detect

+

Detect objects from image

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramimg: Image want to detect, if image's size not match model input's, will auto resize with fit method.
conf_th: Confidence threshold, default 0.5.
iou_th: IoU threshold, default 0.45.
fit: Resize method, default image.Fit.FIT_CONTAIN.
throwIf image format not match model input format, will throw err::Exception.
returnObject list. In C++, you should delete it after use.
staticFalse
+
+

C++ defination code:

+ +
std::vector<nn::Object> *detect(image::Image &img, float conf_th = 0.5, float iou_th = 0.45, maix::image::Fit fit = maix::image::FIT_CONTAIN)
+
+
+

input_size

+

Get model input size

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnmodel input size
staticFalse
+
+

C++ defination code:

+ +
image::Size input_size()
+
+
+

input_width

+

Get model input width

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnmodel input size of width
staticFalse
+
+

C++ defination code:

+ +
int input_width()
+
+
+

input_height

+

Get model input height

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnmodel input size of height
staticFalse
+
+

C++ defination code:

+ +
int input_height()
+
+
+

input_format

+

Get input image format

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returninput image format, image::Format type.
staticFalse
+
+

C++ defination code:

+ +
image::Format input_format()
+
+
+

labels

+

Labels list

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typevar
staticFalse
readonlyFalse
+
+

C++ defination code:

+ +
std::vector<string> labels
+
+
+

label_path

+

Label file path

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typevar
staticFalse
readonlyFalse
+
+

C++ defination code:

+ +
std::string label_path
+
+
+

mean

+

Get mean value, list type

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typevar
staticFalse
readonlyFalse
+
+

C++ defination code:

+ +
std::vector<float> mean
+
+
+

scale

+

Get scale value, list type

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typevar
staticFalse
readonlyFalse
+
+

C++ defination code:

+ +
std::vector<float> scale
+
+
+

anchors

+

Get anchors

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typevar
staticFalse
readonlyFalse
+
+

C++ defination code:

+ +
std::vector<float> anchors
+
+
+

YOLO11

+

YOLO11 class

+
+

C++ defination code:

+ +
class YOLO11
+
+
+

YOLO11

+

Constructor of YOLO11 class

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
parammodel: model path, default empty, you can load model later by load function.
dual_buff: direction [in], prepare dual input output buffer to accelarate forward, that is, when NPU is forwarding we not wait and prepare the next input buff.
If you want to ensure every time forward output the input's result, set this arg to false please.
Default true to ensure speed.
throwIf model arg is not empty and load failed, will throw err::Exception.
staticFalse
+
+

C++ defination code:

+ +
YOLO11(const string &model = "", bool dual_buff = true)
+
+
+

load

+

Load model from file

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
parammodel: Model path want to load
returnerr::Err
staticFalse
+
+

C++ defination code:

+ +
err::Err load(const string &model)
+
+
+

detect

+

Detect objects from image

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramimg: Image want to detect, if image's size not match model input's, will auto resize with fit method.
conf_th: Confidence threshold, default 0.5.
iou_th: IoU threshold, default 0.45.
fit: Resize method, default image.Fit.FIT_CONTAIN.
keypoint_th: keypoint threshold, default 0.5, only for yolo11-pose model.
throwIf image format not match model input format, will throw err::Exception.
returnObject list. In C++, you should delete it after use.
If model is yolo11-pose, object's points have value, and if points' value < 0 means that point is invalid(conf < keypoint_th).
staticFalse
+
+

C++ defination code:

+ +
nn::Objects *detect(image::Image &img, float conf_th = 0.5, float iou_th = 0.45, maix::image::Fit fit = maix::image::FIT_CONTAIN, float keypoint_th = 0.5)
+
+
+

input_size

+

Get model input size

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnmodel input size
staticFalse
+
+

C++ defination code:

+ +
image::Size input_size()
+
+
+

input_width

+

Get model input width

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnmodel input size of width
staticFalse
+
+

C++ defination code:

+ +
int input_width()
+
+
+

input_height

+

Get model input height

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnmodel input size of height
staticFalse
+
+

C++ defination code:

+ +
int input_height()
+
+
+

input_format

+

Get input image format

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returninput image format, image::Format type.
staticFalse
+
+

C++ defination code:

+ +
image::Format input_format()
+
+
+

draw_pose

+

Draw pose keypoints on image

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramimg: image object, maix.image.Image type.
points: keypoits, int list type, [x, y, x, y ...]
radius: radius of points.
color: color of points.
body: true, if points' length is 17*2 and body is ture, will draw lines as human body, if set to false won't draw lines, default true.
staticFalse
+
+

C++ defination code:

+ +
void draw_pose(image::Image &img, std::vector<int> points, int radius = 4, image::Color color = image::COLOR_RED, bool body = true)
+
+
+

draw_seg_mask

+

Draw segmentation on image

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramimg: image object, maix.image.Image type.
seg_mask: segmentation mask image by detect method, a grayscale image
threshold: only mask's value > threshold will be draw on image, value from 0 to 255.
staticFalse
+
+

C++ defination code:

+ +
void draw_seg_mask(image::Image &img, int x, int y, image::Image &seg_mask, int threshold = 127)
+
+
+

labels

+

Labels list

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typevar
staticFalse
readonlyFalse
+
+

C++ defination code:

+ +
std::vector<string> labels
+
+
+

label_path

+

Label file path

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typevar
staticFalse
readonlyFalse
+
+

C++ defination code:

+ +
std::string label_path
+
+
+

mean

+

Get mean value, list type

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typevar
staticFalse
readonlyFalse
+
+

C++ defination code:

+ +
std::vector<float> mean
+
+
+

scale

+

Get scale value, list type

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typevar
staticFalse
readonlyFalse
+
+

C++ defination code:

+ +
std::vector<float> scale
+
+
+

Classifier

+

Classifier

+
+

C++ defination code:

+ +
class Classifier
+
+
+

Classifier

+

Construct a new Classifier object

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
parammodel: MUD model path, if empty, will not load model, you can call load() later.
if not empty, will load model and will raise err::Exception if load failed.
dual_buff: direction [in], prepare dual input output buffer to accelarate forward, that is, when NPU is forwarding we not wait and prepare the next input buff.
If you want to ensure every time forward output the input's result, set this arg to false please.
Default true to ensure speed.
staticFalse
+
+

C++ defination code:

+ +
Classifier(const string &model = "", bool dual_buff = true)
+
+
+

load

+

Load model from file, model format is .mud,\nMUD file should contain [extra] section, have key-values:\n- model_type: classifier\n- input_type: rgb or bgr\n- mean: 123.675, 116.28, 103.53\n- scale: 0.017124753831663668, 0.01750700280112045, 0.017429193899782137\n- labels: imagenet_classes.txt

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
parammodel: MUD model path
returnerror code, if load failed, return error code
staticFalse
+
+

C++ defination code:

+ +
err::Err load(const string &model)
+
+
+

classify

+

Forward image to model, get result. Only for image input, use classify_raw for tensor input.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramimg: image, format should match model input_type, or will raise err.Exception
softmax: if true, will do softmax to result, or will return raw value
fit: image resize fit mode, default Fit.FIT_COVER, see image.Fit.
throwIf error occurred, will raise err::Exception, you can find reason in log, mostly caused by args error or hardware error.
returnresult, a list of (label, score). If in dual_buff mode, value can be one element list and score is zero when not ready. In C++, you need to delete it after use.
staticFalse
+
+

C++ defination code:

+ +
std::vector<std::pair<int, float>> *classify(image::Image &img, bool softmax = true, image::Fit fit = image::FIT_COVER)
+
+
+

classify_raw

+

Forward tensor data to model, get result

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramdata: tensor data, format should match model input_type, or will raise err.Excetion
softmax: if true, will do softmax to result, or will return raw value
throwIf error occurred, will raise err::Exception, you can find reason in log, mostly caused by args error or hardware error.
returnresult, a list of (label, score). In C++, you need to delete it after use.
staticFalse
+
+

C++ defination code:

+ +
std::vector<std::pair<int, float>> *classify_raw(tensor::Tensor &data, bool softmax = true)
+
+
+

input_size

+

Get model input size, only for image input

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnmodel input size
staticFalse
+
+

C++ defination code:

+ +
image::Size input_size()
+
+
+

input_width

+

Get model input width, only for image input

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnmodel input size of width
staticFalse
+
+

C++ defination code:

+ +
int input_width()
+
+
+

input_height

+

Get model input height, only for image input

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnmodel input size of height
staticFalse
+
+

C++ defination code:

+ +
int input_height()
+
+
+

input_format

+

Get input image format, only for image input

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returninput image format, image::Format type.
staticFalse
+
+

C++ defination code:

+ +
image::Format input_format()
+
+
+

input_shape

+

Get input shape, if have multiple input, only return first input shape

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returninput shape, list type
staticFalse
+
+

C++ defination code:

+ +
std::vector<int> input_shape()
+
+
+

labels

+

Labels list

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typevar
staticFalse
readonlyFalse
+
+

C++ defination code:

+ +
std::vector<string> labels
+
+
+

label_path

+

Label file path

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typevar
staticFalse
readonlyFalse
+
+

C++ defination code:

+ +
std::string label_path
+
+
+

mean

+

Get mean value, list type

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typevar
staticFalse
readonlyFalse
+
+

C++ defination code:

+ +
std::vector<float> mean
+
+
+

scale

+

Get scale value, list type

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typevar
staticFalse
readonlyFalse
+
+

C++ defination code:

+ +
std::vector<float> scale
+
+
+

Retinaface

+

Retinaface class

+
+

C++ defination code:

+ +
class Retinaface
+
+
+

Retinaface

+

Constructor of Retinaface class

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
parammodel: model path, default empty, you can load model later by load function.
dual_buff: direction [in], prepare dual input output buffer to accelarate forward, that is, when NPU is forwarding we not wait and prepare the next input buff.
If you want to ensure every time forward output the input's result, set this arg to false please.
Default true to ensure speed.
throwIf model arg is not empty and load failed, will throw err::Exception.
staticFalse
+
+

C++ defination code:

+ +
Retinaface(const string &model = "", bool dual_buff = true)
+
+
+

load

+

Load model from file

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
parammodel: Model path want to load
returnerr::Err
staticFalse
+
+

C++ defination code:

+ +
err::Err load(const string &model)
+
+
+

detect

+

Detect objects from image

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramimg: Image want to detect, if image's size not match model input's, will auto resize with fit method.
conf_th: Confidence threshold, default 0.4.
iou_th: IoU threshold, default 0.45.
fit: Resize method, default image.Fit.FIT_CONTAIN.
throwIf image format not match model input format, will throw err::Exception.
returnObject list. In C++, you should delete it after use.
staticFalse
+
+

C++ defination code:

+ +
std::vector<nn::Object> *detect(image::Image &img, float conf_th = 0.4, float iou_th = 0.45, maix::image::Fit fit = maix::image::FIT_CONTAIN)
+
+
+

input_size

+

Get model input size

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnmodel input size
staticFalse
+
+

C++ defination code:

+ +
image::Size input_size()
+
+
+

input_width

+

Get model input width

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnmodel input size of width
staticFalse
+
+

C++ defination code:

+ +
int input_width()
+
+
+

input_height

+

Get model input height

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnmodel input size of height
staticFalse
+
+

C++ defination code:

+ +
int input_height()
+
+
+

input_format

+

Get input image format

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returninput image format, image::Format type.
staticFalse
+
+

C++ defination code:

+ +
image::Format input_format()
+
+
+

mean

+

Get mean value, list type

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typevar
staticFalse
readonlyFalse
+
+

C++ defination code:

+ +
std::vector<float> mean
+
+
+

scale

+

Get scale value, list type

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typevar
staticFalse
readonlyFalse
+
+

C++ defination code:

+ +
std::vector<float> scale
+
+
+

FaceDetector

+

FaceDetector class

+
+

C++ defination code:

+ +
class FaceDetector
+
+
+

FaceDetector

+

Constructor of FaceDetector class

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
parammodel: model path, default empty, you can load model later by load function.
dual_buff: direction [in], prepare dual input output buffer to accelarate forward, that is, when NPU is forwarding we not wait and prepare the next input buff.
If you want to ensure every time forward output the input's result, set this arg to false please.
Default true to ensure speed.
throwIf model arg is not empty and load failed, will throw err::Exception.
staticFalse
+
+

C++ defination code:

+ +
FaceDetector(const string &model = "", bool dual_buff = true)
+
+
+

load

+

Load model from file

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
parammodel: Model path want to load
returnerr::Err
staticFalse
+
+

C++ defination code:

+ +
err::Err load(const string &model)
+
+
+

detect

+

Detect objects from image

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramimg: Image want to detect, if image's size not match model input's, will auto resize with fit method.
conf_th: Confidence threshold, default 0.5.
iou_th: IoU threshold, default 0.45.
fit: Resize method, default image.Fit.FIT_CONTAIN.
throwIf image format not match model input format, will throw err::Exception.
returnObject list. In C++, you should delete it after use.
staticFalse
+
+

C++ defination code:

+ +
std::vector<nn::Object> *detect(image::Image &img, float conf_th = 0.5, float iou_th = 0.45, maix::image::Fit fit = maix::image::FIT_CONTAIN)
+
+
+

input_size

+

Get model input size

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnmodel input size
staticFalse
+
+

C++ defination code:

+ +
image::Size input_size()
+
+
+

input_width

+

Get model input width

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnmodel input size of width
staticFalse
+
+

C++ defination code:

+ +
int input_width()
+
+
+

input_height

+

Get model input height

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnmodel input size of height
staticFalse
+
+

C++ defination code:

+ +
int input_height()
+
+
+

input_format

+

Get input image format

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returninput image format, image::Format type.
staticFalse
+
+

C++ defination code:

+ +
image::Format input_format()
+
+
+

mean

+

Get mean value, list type

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typevar
staticFalse
readonlyFalse
+
+

C++ defination code:

+ +
std::vector<float> mean
+
+
+

scale

+

Get scale value, list type

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typevar
staticFalse
readonlyFalse
+
+

C++ defination code:

+ +
std::vector<float> scale
+
+
+

PP_OCR

+

PP_OCR class

+
+

C++ defination code:

+ +
class PP_OCR
+
+
+

PP_OCR

+

Constructor of PP_OCR class

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
parammodel: model path, default empty, you can load model later by load function.
throwIf model arg is not empty and load failed, will throw err::Exception.
staticFalse
+
+

C++ defination code:

+ +
PP_OCR(const string &model = "")
+
+
+

load

+

Load model from file

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
parammodel: Model path want to load
returnerr::Err
staticFalse
+
+

C++ defination code:

+ +
err::Err load(const string &model)
+
+
+

detect

+

Detect objects from image

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramimg: Image want to detect, if image's size not match model input's, will auto resize with fit method.
thresh: Confidence threshold where pixels have charactor, default 0.3.
box_thresh: Box threshold, the box prob higher than this value will be valid, default 0.6.
fit: Resize method, default image.Fit.FIT_CONTAIN.
char_box: Calculate every charactor's box, default false, if true then you can get charactor's box by nn.OCR_Object's char_boxes attribute.
throwIf image format not match model input format or no memory, will throw err::Exception.
returnnn.OCR_Objects type. In C++, you should delete it after use.
staticFalse
+
+

C++ defination code:

+ +
nn::OCR_Objects *detect(image::Image &img, float thresh = 0.3, float box_thresh = 0.6, maix::image::Fit fit = maix::image::FIT_CONTAIN, bool char_box = false)
+
+
+

recognize

+

Only recognize, not detect

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramimg: image to recognize chractors, can be a stanrd cropped charactors image,
if crop image not standard, you can use box_points to assgin where the charactors' 4 corner is.
box_points: list type, length must be 8 or 0, default empty means not transfer image to standard image.
4 points postiion, format: [x1, y1, x2, y2, x3, y3, x4, y4], point 1 at the left-top, point 2 right-top...
char_box: Calculate every charactor's box, default false, if true then you can get charactor's box by nn.OCR_Object's char_boxes attribute.
staticFalse
+
+

C++ defination code:

+ +
nn::OCR_Object *recognize(image::Image &img, const std::vector<int> &box_points = std::vector<int>())
+
+
+

draw_seg_mask

+

Draw segmentation on image

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramimg: image object, maix.image.Image type.
seg_mask: segmentation mask image by detect method, a grayscale image
threshold: only mask's value > threshold will be draw on image, value from 0 to 255.
staticFalse
+
+

C++ defination code:

+ +
void draw_seg_mask(image::Image &img, int x, int y, image::Image &seg_mask, int threshold = 127)
+
+
+

input_size

+

Get model input size

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnmodel input size
staticFalse
+
+

C++ defination code:

+ +
image::Size input_size()
+
+
+

input_width

+

Get model input width

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnmodel input size of width
staticFalse
+
+

C++ defination code:

+ +
int input_width()
+
+
+

input_height

+

Get model input height

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnmodel input size of height
staticFalse
+
+

C++ defination code:

+ +
int input_height()
+
+
+

input_format

+

Get input image format

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returninput image format, image::Format type.
staticFalse
+
+

C++ defination code:

+ +
image::Format input_format()
+
+
+

mean

+

Get mean value, list type

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typevar
staticFalse
readonlyFalse
+
+

C++ defination code:

+ +
std::vector<float> mean
+
+
+

scale

+

Get scale value, list type

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typevar
staticFalse
readonlyFalse
+
+

C++ defination code:

+ +
std::vector<float> scale
+
+
+

rec_mean

+

Get mean value, list type

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typevar
staticFalse
readonlyFalse
+
+

C++ defination code:

+ +
std::vector<float> rec_mean
+
+
+

rec_scale

+

Get scale value, list type

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typevar
staticFalse
readonlyFalse
+
+

C++ defination code:

+ +
std::vector<float> rec_scale
+
+
+

labels

+

labels (charactors)

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typevar
staticFalse
readonlyFalse
+
+

C++ defination code:

+ +
std::vector<std::string> labels
+
+
+

det

+

model have detect model

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typevar
staticFalse
readonlyFalse
+
+

C++ defination code:

+ +
bool det
+
+
+

rec

+

model have recognize model

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typevar
staticFalse
readonlyFalse
+
+

C++ defination code:

+ +
bool rec
+
+
+ + +
+
+
+ + +
+
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixcdk/api/maix/nn/F.html b/maixcdk/api/maix/nn/F.html new file mode 100644 index 00000000..522cde56 --- /dev/null +++ b/maixcdk/api/maix/nn/F.html @@ -0,0 +1,366 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + maix::nn::F - MaixCDK + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

maix::nn::F

+ +
+
+
    + +
+
+
+
+ + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

maix.nn.F module

+
+

This is maix::nn::F module of MaixCDK.
+All of these elements are in namespace maix::nn::F.

+

For MaixCDK developer: DO NOT edit this doc file manually, this doc is auto generated!

+
+

Module

+

No module

+

Enum

+

Variable

+

Function

+

softmax

+

Softmax, only support 1D tensor, multi-dimension tensor will be treated as 1D tensor

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
paramtensor: input tensor
replace: change input tensor data directly, if not, will create a new tensor
throwIf arg error, will raise err.Exception error
returnoutput tensor, if arg replace is true, return the arg tensor's address.
If not replace, return a new object, so In C++, you should delete it manually in this case!
+
+

C++ defination code:

+ +
tensor::Tensor *softmax(tensor::Tensor *tensor, bool replace)
+
+
+

Class

+ + +
+
+
+ + +
+
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixcdk/api/maix/peripheral.html b/maixcdk/api/maix/peripheral.html new file mode 100644 index 00000000..f8846478 --- /dev/null +++ b/maixcdk/api/maix/peripheral.html @@ -0,0 +1,394 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + maix::peripheral - MaixCDK + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

maix::peripheral

+ +
+
+
    + +
+
+
+
+ + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

Chip's peripheral driver

+
+

This is maix::peripheral module of MaixCDK.
+All of these elements are in namespace maix::peripheral.

+

For MaixCDK developer: DO NOT edit this doc file manually, this doc is auto generated!

+
+

Module

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
modulebrief
keymaix.peripheral.key module
i2cmaix.peripheral.i2c module
spimaix.peripheral.spi module
pwmmaix.peripheral.pwm module
wdtmaix.peripheral.wdt module
adcmaix.peripheral.adc module
pinmapmaix.peripheral.pinmap module
uartmaix uart peripheral driver
gpiomaix.peripheral.gpio module
hidmaix.peripheral.hid module
timermaix.peripheral.timer module
+

Enum

+

Variable

+

Function

+

Class

+ + +
+
+
+ + +
+
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixcdk/api/maix/peripheral/adc.html b/maixcdk/api/maix/peripheral/adc.html new file mode 100644 index 00000000..f61ffc0e --- /dev/null +++ b/maixcdk/api/maix/peripheral/adc.html @@ -0,0 +1,543 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + maix::peripheral::adc - MaixCDK + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

maix::peripheral::adc

+ +
+
+
    + +
+
+
+
+ + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

maix.peripheral.adc module

+
+

This is maix::peripheral::adc module of MaixCDK.
+All of these elements are in namespace maix::peripheral::adc.

+

For MaixCDK developer: DO NOT edit this doc file manually, this doc is auto generated!

+
+

Module

+

No module

+

Enum

+

Variable

+

RES_BIT_8

+

8-bit resolution, supported by the actual hardware

+ + + + + + + + + + + + + + + + + +
itemdescription
value8
readonlyTrue
+
+

C++ defination code:

+ +
const int RES_BIT_8 = 8
+
+
+

RES_BIT_10

+

10-bit resolution, supported by the actual hardware

+ + + + + + + + + + + + + + + + + +
itemdescription
value10
readonlyTrue
+
+

C++ defination code:

+ +
const int RES_BIT_10 = 10
+
+
+

RES_BIT_12

+

12-bit resolution, supported by the actual hardware

+ + + + + + + + + + + + + + + + + +
itemdescription
value12
readonlyTrue
+
+

C++ defination code:

+ +
const int RES_BIT_12 = 12
+
+
+

RES_BIT_16

+

16-bit resolution, supported by the actual hardware

+ + + + + + + + + + + + + + + + + +
itemdescription
value16
readonlyTrue
+
+

C++ defination code:

+ +
const int RES_BIT_16 = 16
+
+
+

Function

+

Class

+

ADC

+

Peripheral adc class

+
+

C++ defination code:

+ +
class ADC
+
+
+

__init__

+

ADC constructor

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
parampin: direction [in], adc pin, int type
resolution: direction [in], adc resolution. default is -1, means use default resolution
option:
resolution = adc.RES_BIT_8, means 8-bit resolution
resolution = adc.RES_BIT_10, means 10-bit resolution
resolution = adc.RES_BIT_12, means 12-bit resolution
resolution = adc.RES_BIT_16, means 16-bit resolution
the default resolution is determined by actual hardware.
vref: direction [in], adc refer voltage. default is -1, means use default refer voltage.
the default vref is determined by actual hardware. range: [0.0, 10.0]
staticFalse
+
+

C++ defination code:

+ +
ADC(int pin, int resolution, float vref = -1)
+
+
+

read

+

read adc value

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnadc data, int type
if resolution is 8-bit, return value range is [0, 255]
if resolution is 10-bit, return value range is [0, 1023]
if resolution is 12-bit, return value range is [0, 4095]
if resolution is 16-bit, return value range is [0, 65535]
staticFalse
+
+

C++ defination code:

+ +
int read()
+
+
+

read_vol

+

read adc voltage

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnadc voltage, float type。the range is [0.0, vref]
staticFalse
+
+

C++ defination code:

+ +
float read_vol()
+
+
+ + +
+
+
+ + +
+
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixcdk/api/maix/peripheral/gpio.html b/maixcdk/api/maix/peripheral/gpio.html new file mode 100644 index 00000000..aace00be --- /dev/null +++ b/maixcdk/api/maix/peripheral/gpio.html @@ -0,0 +1,641 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + maix::peripheral::gpio - MaixCDK + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

maix::peripheral::gpio

+ +
+
+
    + +
+
+
+
+ + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

maix.peripheral.gpio module

+
+

This is maix::peripheral::gpio module of MaixCDK.
+All of these elements are in namespace maix::peripheral::gpio.

+

For MaixCDK developer: DO NOT edit this doc file manually, this doc is auto generated!

+
+

Module

+

No module

+

Enum

+

Mode

+

GPIO mode

+ + + + + + + + + + + + + +
itemdescribe
valuesIN: input mode
OUT: output mode
OUT_OD: output open drain mode
MODE_MAX:
+
+

C++ defination code:

+ +
enum Mode
+    {
+        IN     = 0x01,     // input mode
+        OUT    = 0x02,     // output mode
+        OUT_OD = 0x03,     // output open drain mode
+        MODE_MAX
+    }
+
+
+

Pull

+

GPIO pull mode

+ + + + + + + + + + + + + +
itemdescribe
valuesPULL_NONE: pull none mode
PULL_UP: pull up mode
PULL_DOWN: pull down mode
PULL_MAX:
+
+

C++ defination code:

+ +
enum Pull
+    {
+        PULL_NONE = 0x00,  // pull none mode
+        PULL_UP   = 0x01,  // pull up mode
+        PULL_DOWN = 0x02,  // pull down mode
+        PULL_MAX
+    }
+
+
+

Variable

+

Function

+

Class

+

GPIO

+

Peripheral gpio class

+
+

C++ defination code:

+ +
class GPIO
+
+
+

__init__

+

GPIO constructor

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
parampin: direction [in], gpio pin name, string type the same as board's pin name, e.g. "B14" or "GPIOB14", or number string like "10" if board no gpiochipe name.
mode: direction [in], gpio mode. gpio.Mode type, default is gpio.Mode.IN (input) mode.
pull: direction [in], gpio pull. gpio.Pull type, default is gpio.Pull.PULL_NONE (pull none) mode.
For input mode, this will set gpio default status(value), if set to gpio.Pull.PULL_NONE, gpio value will be floating.
For output mode, this will set gpio default status(value), if set to gpio.Pull.PULL_UP, gpio value will be 1, else 0.
throwerr::Exception if open gpio device failed.
staticFalse
+
+

C++ defination code:

+ +
GPIO(std::string pin, gpio::Mode mode = gpio::Mode::IN, gpio::Pull pull = gpio::Pull::PULL_NONE)
+
+
+

value

+

set and get gpio value

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramvalue: direction [in], gpio value. int type.
0, means write gpio to low level
1, means write gpio to high level
-1, means read gpio value, not set
returnint type, return gpio value, can be 0 or 1
staticFalse
+
+

C++ defination code:

+ +
int value(int value = -1)
+
+
+

high

+

set gpio high (value to 1)

+ + + + + + + + + + + + + + + + + +
itemdescription
typefunc
staticFalse
+
+

C++ defination code:

+ +
void high()
+
+
+

low

+

set gpio low (value to 0)

+ + + + + + + + + + + + + + + + + +
itemdescription
typefunc
staticFalse
+
+

C++ defination code:

+ +
void low()
+
+
+

toggle

+

gpio toggle

+ + + + + + + + + + + + + + + + + +
itemdescription
typefunc
staticFalse
+
+

C++ defination code:

+ +
void toggle()
+
+
+

get_mode

+

gpio get mode

+ + + + + + + + + + + + + + + + + +
itemdescription
typefunc
staticFalse
+
+

C++ defination code:

+ +
gpio::Mode get_mode()
+
+
+

get_pull

+

get gpio pull

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returngpio::Pull type
staticFalse
+
+

C++ defination code:

+ +
gpio::Pull get_pull()
+
+
+

reset

+

reset gpio

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
parammode: direction [in], gpio mode. gpio.Mode type
pull: direction [in], gpio pull. gpio.Pull type
For input mode, this will set gpio default status(value), if set to gpio.Pull.PULL_NONE, gpio value will be floating.
For output mode, this will set gpio default status(value), if set to gpio.Pull.PULL_UP, gpio value will be 1, else 0.
returnerr::Err type
staticFalse
+
+

C++ defination code:

+ +
err::Err reset(gpio::Mode mode, gpio::Pull pull)
+
+
+ + +
+
+
+ + +
+
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixcdk/api/maix/peripheral/hid.html b/maixcdk/api/maix/peripheral/hid.html new file mode 100644 index 00000000..d8515a73 --- /dev/null +++ b/maixcdk/api/maix/peripheral/hid.html @@ -0,0 +1,529 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + maix::peripheral::hid - MaixCDK + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

maix::peripheral::hid

+ +
+
+
    + +
+
+
+
+ + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

maix.peripheral.hid module

+
+

This is maix::peripheral::hid module of MaixCDK.
+All of these elements are in namespace maix::peripheral::hid.

+

For MaixCDK developer: DO NOT edit this doc file manually, this doc is auto generated!

+
+

Module

+

No module

+

Enum

+

DeviceType

+

Device enum of hid

+ + + + + + + + + + + + + +
itemdescribe
valuesDEVICE_MOUSE:
DEVICE_KEYBOARD:
DEVICE_TOUCHPAD:
+
+

C++ defination code:

+ +
enum DeviceType {
+        DEVICE_MOUSE = 0,
+        DEVICE_KEYBOARD,
+        DEVICE_TOUCHPAD
+    }
+
+
+

Variable

+

Function

+

Class

+

Hid

+

Hid class

+
+

C++ defination code:

+ +
class Hid
+
+
+

__init__

+

Hid Device constructor

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramdevice_type: Device type, used to select mouse, keyboard, or touchpad.
open: auto open device in constructor, if false, you need call open() to open device
staticFalse
+
+

C++ defination code:

+ +
Hid(hid::DeviceType device_type, bool open = true)
+
+
+

open

+

Open hid device

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnerr::Err
staticFalse
+
+

C++ defination code:

+ +
err::Err open()
+
+
+

close

+

Close hid device

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnerr::Err
staticFalse
+
+

C++ defination code:

+ +
err::Err close()
+
+
+

write

+

Write data to hid device

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramdata: data to write
For the keyboard, 8 bytes of data need to be written, with the format as follows:
data = [0x00, #
0x00, #
0x00, # Key value. Refer to the "Universal Serial Bus HID Usage Tables" section of the official documentation(https://www.usb.org).
0x00, #
0x00, #
0x00, #
0x00, #
0x00] #
For the mouse, 4 bytes of data need to be written, with the format as follows:
data = [0x00, # Button state
0x00: no button pressed
0x01: press left button
0x02: press right button
0x04: press middle button
x, # X-axis relative coordinates. Signed number, positive values for x indicate movement to the right
y, # Y-axis relative coordinates. Signed number, positive values for y indicate movement downward
0x00] # Wheel movement. Signed number, positive values indicate downward movement.
For the touchpad, 6 bytes of data need to be written, with the format as follows:
data = [0x00, # Button state (0: no button pressed, 0x01: press left button, 0x10, press right button.)
x & 0xFF, (x >> 8) & 0xFF, # X-axis absolute coordinate, 0 means unused.
Note: You must map the target position to the range [0x1, 0x7FFF]. This means x value = <position_to_move> * 0x7FFF / <actual_screen_width>
y & 0xFF, (y >> 8) & 0xFF, # Y-axis absolute coordinate, 0 means unused.
Note: You must map the target position to the range [0x1, 0x7FFF]. This means y value = <position_to_move> * 0x7FFF / <actual_screen_height>
0x00, # Wheel movement. Signed number, positive values indicate downward movement.
returnerr::Err
staticFalse
+
+

C++ defination code:

+ +
err::Err write(std::vector<int> &data)
+
+
+

is_opened

+

Check if hid device is opened

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnbool
staticFalse
+
+

C++ defination code:

+ +
bool is_opened()
+
+
+ + +
+
+
+ + +
+
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixcdk/api/maix/peripheral/i2c.html b/maixcdk/api/maix/peripheral/i2c.html new file mode 100644 index 00000000..4f74fbc8 --- /dev/null +++ b/maixcdk/api/maix/peripheral/i2c.html @@ -0,0 +1,763 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + maix::peripheral::i2c - MaixCDK + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

maix::peripheral::i2c

+ +
+
+
    + +
+
+
+
+ + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

maix.peripheral.i2c module

+
+

This is maix::peripheral::i2c module of MaixCDK.
+All of these elements are in namespace maix::peripheral::i2c.

+

For MaixCDK developer: DO NOT edit this doc file manually, this doc is auto generated!

+
+

Module

+

No module

+

Enum

+

AddrSize

+

Address size enum

+ + + + + + + + + + + + + +
itemdescribe
valuesSEVEN_BIT: 7-bit address mode
TEN_BIT: 10-bit address mode
+
+

C++ defination code:

+ +
enum AddrSize
+    {
+        SEVEN_BIT = 7,   // 7-bit address mode
+        TEN_BIT   = 10   // 10-bit address mode
+    }
+
+
+

Mode

+

I2C mode enum

+ + + + + + + + + + + + + +
itemdescribe
valuesMASTER: master mode
SLAVE: slave mode
+
+

C++ defination code:

+ +
enum Mode
+    {
+        MASTER = 0x00, // master mode
+        SLAVE = 0x01   // slave mode
+    }
+
+
+

Variable

+

Function

+

list_devices

+

Get supported i2c bus devices.

+ + + + + + + + + + + + + +
itemdescription
returni2c bus devices list, int type, is the i2c bus id.
+
+

C++ defination code:

+ +
std::vector<int> list_devices()
+
+
+

Class

+

I2C

+

Peripheral i2c class

+
+

C++ defination code:

+ +
class I2C
+
+
+

__init__

+

I2C Device constructor\nthis constructor will be export to MaixPy as _maix.example.Example.init

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramid: direction [in], i2c bus id, int type, e.g. 0, 1, 2
freq: direction [in], i2c clock, int type, default is 100000(100kbit/s), will auto set fast mode if freq > 100000.
mode: direction [in], mode of i2c, i2c.Mode.SLAVE or i2c.Mode.MASTER.
addr_size: direction [in], address length of i2c, i2c.AddrSize.SEVEN_BIT or i2c.AddrSize.TEN_BIT.
throwerr::Exception if open i2c device failed.
staticFalse
+
+

C++ defination code:

+ +
I2C(int id, i2c::Mode mode, int freq = 100000, i2c::AddrSize addr_size = i2c::AddrSize::SEVEN_BIT)
+
+
+

scan

+

scan all i2c salve address on the bus

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramaddr: If -1, only scan this addr, or scan from 0x08~0x77, default -1.
returnthe list of i2c slave address, int list type.
staticFalse
+
+

C++ defination code:

+ +
std::vector<int> scan(int addr = -1)
+
+
+

writeto

+

write data to i2c slave

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramaddr: direction [in], i2c slave address, int type
data: direction [in], data to write, vector type in C++, int list in MaixPy.
Note: The range of value should be in [0,255].
returnif success, return the length of written data, error occurred will return -err::Err。
staticFalse
+
+

C++ defination code:

+ +
int writeto(int addr, const std::vector<unsigned char> data)
+
+
+

writeto (overload 1)

+

write data to i2c slave

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramaddr: direction [in], i2c slave address, int type
data: direction [in], data to write, bytes type.
Note: The range of value should be in [0,255].
returnif success, return the length of written data, error occurred will return -err::Err.
staticFalse
+
+

C++ defination code:

+ +
int writeto(int addr, const Bytes &data)
+
+
+

writeto (overload 2)

+

write data to i2c slave

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramaddr: direction [in], i2c slave address, int type
data: direction [in], data to write, uint8_t type.
len: direction [in], data length to write, int type
returnif success, return the length of written data, error occurred will return -err::Err.
staticFalse
+
+

C++ defination code:

+ +
int writeto(int addr, const uint8_t *data, int len)
+
+
+

readfrom

+

read data from i2c slave

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramaddr: direction [in], i2c slave address, int type
len: direction [in], data length to read, int type
returnthe list of data read from i2c slave, bytes type, you should delete it after use in C++.
If read failed, return nullptr in C++, None in MaixPy.
staticFalse
+
+

C++ defination code:

+ +
Bytes* readfrom(int addr, int len)
+
+
+

writeto_mem

+

write data to i2c slave's memory address

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramaddr: direction [in], i2c slave address, int type
mem_addr: direction [in], memory address want to write, int type.
data: direction [in], data to write, vector type.
mem_addr_size: direction [in], memory address size, default is 8.
mem_addr_le: direction [in], memory address little endian, default is false, that is send high byte first.
returndata length written if success, error occurred will return -err::Err.
staticFalse
+
+

C++ defination code:

+ +
int writeto_mem(int addr, int mem_addr, const std::vector<unsigned char> data, int mem_addr_size = 8, bool mem_addr_le = false)
+
+
+

writeto_mem (overload 1)

+

write data to i2c slave's memory address

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramaddr: direction [in], i2c slave address, int type
mem_addr: direction [in], memory address want to write, int type.
data: direction [in], data to write, bytes type.
mem_addr_size: direction [in], memory address size, default is 8.
mem_addr_le: direction [in], memory address little endian, default is false, that is send high byte first.
returndata length written if success, error occurred will return -err::Err.
staticFalse
+
+

C++ defination code:

+ +
int writeto_mem(int addr, int mem_addr, const Bytes &data, int mem_addr_size = 8, bool mem_addr_le = false)
+
+
+

writeto_mem (overload 2)

+

write data to i2c slave's memory address

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramaddr: direction [in], i2c slave address, int type
mem_addr: direction [in], memory address want to write, int type.
data: direction [in], data to write, uint8_t type.
len: direction [in], data length to write, int type
mem_addr_size: direction [in], memory address size, default is 8.
mem_addr_le: direction [in], memory address little endian, default is false, that is send high byte first.
returndata length written if success, error occurred will return -err::Err.
staticFalse
+
+

C++ defination code:

+ +
int writeto_mem(int addr, int mem_addr, const uint8_t *data, int len, int mem_addr_size = 8, bool mem_addr_le = false)
+
+
+

readfrom_mem

+

read data from i2c slave

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramaddr: direction [in], i2c slave address, int type
mem_addr: direction [in], memory address want to read, int type.
len: direction [in], data length to read, int type
mem_addr_size: direction [in], memory address size, default is 8.
mem_addr_le: direction [in], memory address little endian, default is false, that is send high byte first.
returnthe list of data read from i2c slave, bytes type, you should delete it after use in C++.
If read failed, return nullptr in C++, None in MaixPy.
staticFalse
+
+

C++ defination code:

+ +
Bytes* readfrom_mem(int addr, int mem_addr, int len, int mem_addr_size = 8, bool mem_addr_le = false)
+
+
+ + +
+
+
+ + +
+
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixcdk/api/maix/peripheral/key.html b/maixcdk/api/maix/peripheral/key.html new file mode 100644 index 00000000..af32a9f9 --- /dev/null +++ b/maixcdk/api/maix/peripheral/key.html @@ -0,0 +1,643 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + maix::peripheral::key - MaixCDK + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

maix::peripheral::key

+ +
+
+
    + +
+
+
+
+ + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

maix.peripheral.key module

+
+

This is maix::peripheral::key module of MaixCDK.
+All of these elements are in namespace maix::peripheral::key.

+

For MaixCDK developer: DO NOT edit this doc file manually, this doc is auto generated!

+
+

Module

+

No module

+

Enum

+

Keys

+

Keys enum, id the same as linux input.h(input-event-codes.h)

+ + + + + + + + + + + + + +
itemdescribe
valuesKEY_NONE:
KEY_ESC:
KEY_POWER:
KEY_OK:
KEY_OPTION:
KEY_NEXT:
KEY_PREV:
+
+

C++ defination code:

+ +
enum Keys{
+        KEY_NONE   = 0x000,
+        KEY_ESC    = 0x001,
+        KEY_POWER  = 0x074,
+        KEY_OK     = 0x160,
+        KEY_OPTION = 0x165,
+        KEY_NEXT   = 0x197,
+        KEY_PREV   = 0x19c,
+    }
+
+
+

State

+

Key state enum

+ + + + + + + + + + + + + +
itemdescribe
valuesKEY_RELEASED:
KEY_PRESSED:
KEY_LONG_PRESSED:
+
+

C++ defination code:

+ +
enum State{
+        KEY_RELEASED     = 0,
+        KEY_PRESSED      = 1,
+        KEY_LONG_PRESSED = 2,
+    }
+
+
+

Variable

+

Function

+

add_default_listener

+

Add default listener, if you want to exit app when press ok button, you can just call this function.\nThis function is auto called in MaixPy' startup code, so you don't need to call it in MaixPy.\nCreate Key object will auto call rm_default_listener() to cancel the default ok button function.\nWhen ok button pressed, a SIGINT signal will be raise and call app.set_exit_flag(True).

+
+

C++ defination code:

+ +
void add_default_listener()
+
+
+

rm_default_listener

+

Remove default listener, if you want to cancel the default ok button function(exit app), you can just call this function.

+
+

C++ defination code:

+ +
void rm_default_listener()
+
+
+

Class

+

Key

+

Key input class

+
+

C++ defination code:

+ +
class Key
+
+
+

Key

+

Key Device constructor

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramcallback: When key triggered and callback is not empty(empty In MaixPy is None, in C++ is nullptr),
callback will be called with args key(key.Keys) and value(key.State).
If set to null, you can get key value by read() function.
This callback called in a standalone thread, so you can block a while in callback, and you should be carefully when operate shared data.
open: auto open device in constructor, if false, you need call open() to open device.
device: Specifies the input device to use. The default initializes all keys,
for a specific device, provide the path (e.g., "/dev/input/device").
long_press_time: The duration (in milliseconds) from pressing the key to triggering the long press event. Default is 2000ms.
staticFalse
+
+

C++ defination code:

+ +
Key(std::function<void(int, int)> callback = nullptr, bool open = true, const string &device = "", int long_press_time = 2000)
+
+
+

open

+

Open(Initialize) key device, if already opened, will close first and then open.

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnerr::Err type, err.Err.ERR_NONE means success
staticFalse
+
+

C++ defination code:

+ +
err::Err open()
+
+
+

close

+

Close key device

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnerr::Err type, err.Err.ERR_NONE means success
staticFalse
+
+

C++ defination code:

+ +
err::Err close()
+
+
+

is_opened

+

Check key device is opened

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnbool type, true means opened, false means closed
staticFalse
+
+

C++ defination code:

+ +
bool is_opened()
+
+
+

read

+

Read key input, if callback is set, DO NOT call this function manually.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramkey: maix.key.Keys type, indicate which key is triggered, e.g. maix.key.Keys.KEY_OK mean the OK key is triggered.
If read failed, will not change the value of key.
value: maix.key.State type, indicate the key state, e.g. maix.key.State.KEY_PRESSED mean the key is pressed
If read failed, will not change the value of value.
returnerr::Err type, err.Err.ERR_NONE means success, err.Err.ERR_NOT_READY means no key input, other means error.
staticFalse
+
+

C++ defination code:

+ +
err::Err read(int &key, int &value)
+
+
+

read (overload 1)

+

Read key input, and return key and value, if callback is set, DO NOT call this function manually.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnlist type, first is key(maix.key.Keys), second is value(maix.key.State), if no key input, return [0, 0]
throwIf read failed, will throw maix.err.Exception.
staticFalse
+
+

C++ defination code:

+ +
std::pair<int, int> read()
+
+
+

long_press_time

+

Sets and retrieves the key's long press time.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
parampress_time: The long press time to set for the key.
Setting it to 0 will disable the long press event.
returnint type, the current long press time for the key (in milliseconds).
staticFalse
+
+

C++ defination code:

+ +
int long_press_time(int press_time = -1)
+
+
+ + +
+
+
+ + +
+
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixcdk/api/maix/peripheral/pinmap.html b/maixcdk/api/maix/peripheral/pinmap.html new file mode 100644 index 00000000..d659a5ca --- /dev/null +++ b/maixcdk/api/maix/peripheral/pinmap.html @@ -0,0 +1,419 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + maix::peripheral::pinmap - MaixCDK + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

maix::peripheral::pinmap

+ +
+
+
    + +
+
+
+
+ + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

maix.peripheral.pinmap module

+
+

This is maix::peripheral::pinmap module of MaixCDK.
+All of these elements are in namespace maix::peripheral::pinmap.

+

For MaixCDK developer: DO NOT edit this doc file manually, this doc is auto generated!

+
+

Module

+

No module

+

Enum

+

Variable

+

Function

+

get_pins

+

Get all pins of devices

+ + + + + + + + + + + + + +
itemdescription
returnpin name list, string type.
+
+

C++ defination code:

+ +
std::vector<std::string> get_pins()
+
+
+

get_pin_functions

+

Get all function of a pin

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
parampin: pin name, string type.
returnfunction list, function name is string type.
throwIf pin name error will throwout err.Err.ERR_ARGS error.
+
+

C++ defination code:

+ +
std::vector<std::string> get_pin_functions(const std::string &pin)
+
+
+

set_pin_function

+

Set function of a pin

+ + + + + + + + + + + + + + + + + +
itemdescription
parampin: pin name, string type.
func: which function should this pin use.
returnif set ok, will return err.Err.ERR_NONE, else error occurs.
+
+

C++ defination code:

+ +
err::Err set_pin_function(const std::string &pin, const std::string &func)
+
+
+

Class

+ + +
+
+
+ + +
+
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixcdk/api/maix/peripheral/pwm.html b/maixcdk/api/maix/peripheral/pwm.html new file mode 100644 index 00000000..488db7d1 --- /dev/null +++ b/maixcdk/api/maix/peripheral/pwm.html @@ -0,0 +1,575 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + maix::peripheral::pwm - MaixCDK + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

maix::peripheral::pwm

+ +
+
+
    + +
+
+
+
+ + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

maix.peripheral.pwm module

+
+

This is maix::peripheral::pwm module of MaixCDK.
+All of these elements are in namespace maix::peripheral::pwm.

+

For MaixCDK developer: DO NOT edit this doc file manually, this doc is auto generated!

+
+

Module

+

No module

+

Enum

+

Variable

+

Function

+

Class

+

PWM

+

Peripheral pwm class

+
+

C++ defination code:

+ +
class PWM
+
+
+

__init__

+

PWM constructor

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
parampin: direction [in], pwm id, int type, like 0, 1, 2 etc.
freq: direction [in], pwm frequency, unit: Hz. int type. default is 1000
duty: direction [in], pwm duty. double type. range is [0, 100], default is 0.
enable: direction [in], enable pwm output right now. bool type. default is true, if false, you need to call enable() to enable pwm output.
duty_val: direction [in], pwm duty value, int type. default -1 means not set and auto calculate by freq and duty.
This arg directly set pwm duty value, if set, will ignore duty arg.
duty_val = duty / 100 * T_ns, T_ns = 1 / freq * 1000000000.
throwIf args error or init pwm failed, will throw err::Exception
staticFalse
+
+

C++ defination code:

+ +
PWM(int id, int freq = 1000, double duty = 0, bool enable = true, int duty_val = -1)
+
+
+

duty

+

get or set pwm duty

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramduty: direction [in], pwm duty, double type, value in [0, 100], default -1 means only read.
returncurrent duty, float type, if set and set failed will return -err::Err
staticFalse
+
+

C++ defination code:

+ +
double duty(double duty = -1)
+
+
+

duty_val

+

set pwm duty value

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramduty_val: direction [in], pwm duty value. int type. default is -1
duty_val > 0 means set duty_val
duty_val == -1 or not set, return current duty_val
returnint type
when get duty_val, return current duty_val, else return -err::Err code.
staticFalse
+
+

C++ defination code:

+ +
int duty_val(int duty_val = -1)
+
+
+

freq

+

get or set pwm frequency

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramfreq: direction [in], pwm frequency. int type. default is -1
freq >= 0, set freq
freq == -1 or not set, return current freq
returnint type, current freq, if set and set failed will return -err::Err
staticFalse
+
+

C++ defination code:

+ +
int freq(int freq = -1)
+
+
+

enable

+

set pwm enable

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnerr::Err type, err.Err.ERR_NONE means success
staticFalse
+
+

C++ defination code:

+ +
err::Err enable()
+
+
+

disable

+

set pwm disable

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnerr::Err type, err.Err.ERR_NONE means success
staticFalse
+
+

C++ defination code:

+ +
err::Err disable()
+
+
+

is_enabled

+

get pwm enable status

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnbool type, true means enable, false means disable
staticFalse
+
+

C++ defination code:

+ +
bool is_enabled()
+
+
+ + +
+
+
+ + +
+
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixcdk/api/maix/peripheral/spi.html b/maixcdk/api/maix/peripheral/spi.html new file mode 100644 index 00000000..88c9e4b6 --- /dev/null +++ b/maixcdk/api/maix/peripheral/spi.html @@ -0,0 +1,640 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + maix::peripheral::spi - MaixCDK + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

maix::peripheral::spi

+ +
+
+
    + +
+
+
+
+ + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

maix.peripheral.spi module

+
+

This is maix::peripheral::spi module of MaixCDK.
+All of these elements are in namespace maix::peripheral::spi.

+

For MaixCDK developer: DO NOT edit this doc file manually, this doc is auto generated!

+
+

Module

+

No module

+

Enum

+

Mode

+

SPI mode enum

+ + + + + + + + + + + + + +
itemdescribe
valuesMASTER: spi master mode
SLAVE: spi slave mode
+
+

C++ defination code:

+ +
enum Mode
+    {
+        MASTER = 0x0, // spi master mode
+        SLAVE = 0x1,  // spi slave mode
+    }
+
+
+

Variable

+

Function

+

Class

+

SPI

+

Peripheral spi class

+
+

C++ defination code:

+ +
class SPI
+
+
+

__init__

+

SPI constructor

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramid: direction [in], spi bus id, int type
mode: direction [in], mode of spi, spi.Mode type, spi.Mode.MASTER or spi.Mode.SLAVE.
freq: direction [in], freq of spi, int type
polarity: direction [in], polarity of spi, 0 means idle level of clock is low, 1 means high, int type, default is 0.
phase: direction [in], phase of spi, 0 means data is captured on the first edge of the SPI clock cycle, 1 means second, int type, default is 0.
bits: direction [in], bits of spi, int type, default is 8.
cs_enable: direction [in], cs pin active level, default is 0(low)
soft_cs: direction [in], not use hardware cs, bool type, if set true, you can operate cs pin use gpio manually.
cs: direction [in], soft cs pin number, std::string type, default is "GPIOA19", if SPI support multi hardware cs, you can set it to other value.
staticFalse
+
+

C++ defination code:

+ +
SPI(int id, spi::Mode mode, int freq, int polarity = 0, int phase = 0,
+            int bits = 8, unsigned char cs_enable=0, bool soft_cs = false, std::string cs = "GPIOA19")
+
+
+

read

+

read data from spi

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramlength: direction [in], read length, int type
returnbytes data, Bytes type in C++, bytes type in MaixPy. You need to delete it manually after use in C++.
staticFalse
+
+

C++ defination code:

+ +
Bytes *read(int length)
+
+
+

read (overload 1)

+

read data from spi

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramlength: direction [in], read length, unsigned int type
returnbytes data, vector type
staticFalse
+
+

C++ defination code:

+ +
std::vector<unsigned char> read(unsigned int length)
+
+
+

write

+

write data to spi

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramdata: direction [in], data to write, vector type
the member range of the list is [0,255]
returnwrite length, int type, if write failed, return -err::Err code.
staticFalse
+
+

C++ defination code:

+ +
int write(std::vector<unsigned char> data)
+
+
+

write (overload 1)

+

write data to spi

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramdata: direction [in], data to write, Bytes type in C++, bytes type in MaixPy
returnwrite length, int type, if write failed, return -err::Err code.
staticFalse
+
+

C++ defination code:

+ +
int write(Bytes *data)
+
+
+

write_read

+

write data to spi and read data from spi at the same time.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramdata: direction [in], data to write, vector type.
read_len: direction [in], read length, int type, should > 0.
returnread data, vector type
staticFalse
+
+

C++ defination code:

+ +
std::vector<unsigned char> write_read(std::vector<unsigned char> data, int read_len)
+
+
+

write_read (overload 1)

+

write data to spi and read data from spi at the same time.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramdata: direction [in], data to write, Bytes type in C++, bytes type in MaixPy
read_len: direction [in], read length, int type, should > 0.
returnread data, Bytes type in C++, bytes type in MaixPy. You need to delete it manually after use in C++.
staticFalse
+
+

C++ defination code:

+ +
Bytes *write_read(Bytes *data, int read_len)
+
+
+

is_busy

+

get busy status of spi

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnbusy status, bool type
staticFalse
+
+

C++ defination code:

+ +
bool is_busy()
+
+
+ + +
+
+
+ + +
+
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixcdk/api/maix/peripheral/timer.html b/maixcdk/api/maix/peripheral/timer.html new file mode 100644 index 00000000..66a21fd2 --- /dev/null +++ b/maixcdk/api/maix/peripheral/timer.html @@ -0,0 +1,375 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + maix::peripheral::timer - MaixCDK + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

maix::peripheral::timer

+ +
+
+
    + +
+
+
+
+ + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

maix.peripheral.timer module

+
+

This is maix::peripheral::timer module of MaixCDK.
+All of these elements are in namespace maix::peripheral::timer.

+

For MaixCDK developer: DO NOT edit this doc file manually, this doc is auto generated!

+
+

Module

+

No module

+

Enum

+

Variable

+

Function

+

Class

+

TIMER

+

Peripheral timer class

+
+

C++ defination code:

+ +
class TIMER
+
+
+

__init__

+

TIMER constructor

+ + + + + + + + + + + + + + + + + +
itemdescription
typefunc
staticFalse
+
+

C++ defination code:

+ +
TIMER()
+
+
+ + +
+
+
+ + +
+
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixcdk/api/maix/peripheral/uart.html b/maixcdk/api/maix/peripheral/uart.html new file mode 100644 index 00000000..16be61f6 --- /dev/null +++ b/maixcdk/api/maix/peripheral/uart.html @@ -0,0 +1,1077 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + maix::peripheral::uart - MaixCDK + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

maix::peripheral::uart

+ +
+
+
    + +
+
+
+
+ + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

maix uart peripheral driver

+
+

This is maix::peripheral::uart module of MaixCDK.
+All of these elements are in namespace maix::peripheral::uart.

+

For MaixCDK developer: DO NOT edit this doc file manually, this doc is auto generated!

+
+

Module

+

No module

+

Enum

+

PARITY

+

uart parity enum

+ + + + + + + + + + + + + +
itemdescribe
valuesPARITY_NONE: no parity
PARITY_ODD: odd parity
PARITY_EVEN: even parity
PARITY_MAX:
+
+

C++ defination code:

+ +
enum PARITY
+    {
+        PARITY_NONE = 0x00,  // no parity
+        PARITY_ODD  = 0x01,  // odd parity
+        PARITY_EVEN = 0x02,  // even parity
+        PARITY_MAX
+    }
+
+
+

STOP

+

uart stop bits

+ + + + + + + + + + + + + +
itemdescribe
valuesSTOP_1: 1 stop bit
STOP_2: 2 stop bits
STOP_1_5: 1.5 stop bits
STOP_MAX:
+
+

C++ defination code:

+ +
enum STOP
+    {
+        STOP_1   = 0x01,  // 1 stop bit
+        STOP_2   = 0x02,  // 2 stop bits
+        STOP_1_5 = 0x03,  // 1.5 stop bits
+        STOP_MAX
+    }
+
+
+

BITS

+

uart stop bits

+ + + + + + + + + + + + + +
itemdescribe
valuesBITS_5: 5 data bits
BITS_6: 6 data bits
BITS_7: 7 data bits
BITS_8: 8 data bits
BITS_MAX:
+
+

C++ defination code:

+ +
enum BITS
+    {
+        BITS_5 = 5,  // 5 data bits
+        BITS_6 = 6,  // 6 data bits
+        BITS_7 = 7,  // 7 data bits
+        BITS_8 = 8,  // 8 data bits
+        BITS_MAX
+    }
+
+
+

FLOW_CTRL

+

uart flow control

+ + + + + + + + + + + + + +
itemdescribe
valuesFLOW_CTRL_NONE: no flow control
FLOW_CTRL_HW: hardware flow control
FLOW_CTRL_MAX:
+
+

C++ defination code:

+ +
enum FLOW_CTRL
+    {
+        FLOW_CTRL_NONE = 0,  // no flow control
+        FLOW_CTRL_HW   = 1,  // hardware flow control
+        FLOW_CTRL_MAX
+    }
+
+
+

Variable

+

Function

+

list_devices

+

Get supported uart ports.

+ + + + + + + + + + + + + +
itemdescription
returnuart ports list, string type.
+
+

C++ defination code:

+ +
std::vector<std::string> list_devices()
+
+
+

Class

+

UART

+

maix uart peripheral driver

+
+

C++ defination code:

+ +
class UART : public comm::CommBase
+
+
+

__init__

+

UART constructor. You need to call open() to open the device.

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramport: uart port. string type, can get it by uart.list_devices().
If empty, will not open device in constructor, default empty.
if not empty, will auto open device in constructor, open fail will throw err.Exception.
baudrate: baudrate of uart. int type, default 115200.
databits: databits, values @see uart.DATA_BITS
parity: parity, values @see uart.PARITY
stopbits: stopbits, values @see uart.STOP_BITS
flow_control: flow_control, values @see uart.FLOW_CTRL
staticFalse
+
+

C++ defination code:

+ +
UART(const std::string &port = "", int baudrate = 115200, uart::BITS databits = uart::BITS_8,
+            uart::PARITY parity = uart::PARITY_NONE, uart::STOP stopbits = uart::STOP_1,
+            uart::FLOW_CTRL flow_ctrl = uart::FLOW_CTRL_NONE)
+
+
+

set_port

+

Set port

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramport: uart port. string type, can get it by uart.list_devices().
returnset port error code, err.Err type.
staticFalse
+
+

C++ defination code:

+ +
err::Err set_port(const std::string &port)
+
+
+

get_port

+

Get port

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnuart port, string type.
staticFalse
+
+

C++ defination code:

+ +
std::string get_port()
+
+
+

set_baudrate

+

Set baud rate

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
parambaudrate: baudrate of uart. int type, default 115200.
returnset baud rate error code, err.Err type.
staticFalse
+
+

C++ defination code:

+ +
err::Err set_baudrate(int baudrate)
+
+
+

get_baudrate

+

Get baud rate

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnbaud rate, int type.
staticFalse
+
+

C++ defination code:

+ +
int get_baudrate()
+
+
+

open

+

Open uart device, before open, port must be set in constructor or by set_port().\nIf already opened, do nothing and return err.ERR_NONE.

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnopen device error code, err.Err type.
staticFalse
+
+

C++ defination code:

+ +
err::Err open()
+
+
+

is_open

+

Check if device is opened.

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returntrue if opened, false if not opened.
staticFalse
+
+

C++ defination code:

+ +
bool is_open()
+
+
+

close

+

Close uart device, if already closed, do nothing and return err.ERR_NONE.

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnclose device error code, err.Err type.
staticFalse
+
+

C++ defination code:

+ +
err::Err close()
+
+
+

set_received_callback

+

Set received callback function

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramcallback: function to call when received data
staticFalse
+
+

C++ defination code:

+ +
void set_received_callback(std::function<void(uart::UART&, Bytes&)> callback)
+
+
+

write

+

Send data to device

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
parambuff: data buffer
len: data length need to send
returnsent data length, < 0 means error, value is -err.Err.
staticFalse
+
+

C++ defination code:

+ +
int write(const uint8_t *buff, int len)
+
+
+

write (overload 1)

+

Send data to device

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
parambuff: data buffer
len: data length need to send, if len == -1, means buff is a string, send buff until '\0'.
returnsent data length, < 0 means error, value is -err.Err.
staticFalse
+
+

C++ defination code:

+ +
int write(const char *buff, int len = -1)
+
+
+

write (overload 2)

+

Send string data

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramstr: string data
returnsent data length, < 0 means error, value is -err.Err.
staticFalse
+
+

C++ defination code:

+ +
int write(const std::string &str)
+
+
+

write (overload 3)

+

Send data to uart

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramdata: direction [in], data to send, bytes type. If you want to send str type, use str.encode() to convert.
returnsent length, int type, if < 0 means error, value is -err.Err.
staticFalse
+
+

C++ defination code:

+ +
int write(Bytes &data)
+
+
+

write_str

+

Send string data

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramstr: string data
returnsent data length, < 0 means error, value is -err.Err.
staticFalse
+
+

C++ defination code:

+ +
int write_str(const std::string &str)
+
+
+

available

+

Check if data available or wait data available.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramtimeout: unit ms, timeout to wait data, default 0.
0 means check data available and return immediately,
> 0 means wait until data available or timeout.
- 1 means wait until data available.
returnavailable data number, 0 if timeout or no data, <0 if error, value is -err.Err, can be err::ERR_IO, err::ERR_CANCEL, err::ERR_NOT_OPEN.
throwerr.Exception if fatal error.
staticFalse
+
+

C++ defination code:

+ +
int available(int timeout = 0)
+
+
+

read

+

Receive data

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
parambuff: data buffer to store received data
buff_len: data buffer length
recv_len: max data length want to receive, default -1.
-1 means read data in uart receive buffer.
>0 means read recv_len data want to receive.
other values is invalid.
timeout: unit ms, timeout to receive data, default 0.
0 means read data in uart receive buffer and return immediately,
-1 means block until read recv_len data,
>0 means block until read recv_len data or timeout.
returnreceived data length, < 0 means error, value is -err.Err.
staticFalse
+
+

C++ defination code:

+ +
int read(uint8_t *buff, int buff_len, int recv_len = -1, int timeout = 0)
+
+
+

read (overload 1)

+

Recv data from uart

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramlen: max data length want to receive, default -1.
-1 means read data in uart receive buffer.
>0 means read len data want to receive.
other values is invalid.
timeout: unit ms, timeout to receive data, default 0.
0 means read data in uart receive buffer and return immediately,
-1 means block until read len data,
>0 means block until read len data or timeout.
returnreceived data, bytes type.
Attention, you need to delete the returned object yourself in C++.
throwRead failed will raise err.Exception error.
staticFalse
+
+

C++ defination code:

+ +
Bytes *read(int len = -1, int timeout = 0)
+
+
+

readline

+

Read line from uart, that is read until '\n' or '\r\n'.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramtimeout: unit ms, timeout to receive data, default -1 means block until read '\n' or '\r\n'.
> 0 means block until read '\n' or '\r\n' or timeout.
returnreceived data, bytes type. If timeout will return the current received data despite not read '\n' or '\r\n'.
e.g. If we want to read b'123\n', but when we only read b'12', timeout, then return b'12'.
staticFalse
+
+

C++ defination code:

+ +
Bytes *readline(int timeout = -1)
+
+
+ + +
+
+
+ + +
+
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixcdk/api/maix/peripheral/wdt.html b/maixcdk/api/maix/peripheral/wdt.html new file mode 100644 index 00000000..b4652687 --- /dev/null +++ b/maixcdk/api/maix/peripheral/wdt.html @@ -0,0 +1,461 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + maix::peripheral::wdt - MaixCDK + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

maix::peripheral::wdt

+ +
+
+
    + +
+
+
+
+ + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

maix.peripheral.wdt module

+
+

This is maix::peripheral::wdt module of MaixCDK.
+All of these elements are in namespace maix::peripheral::wdt.

+

For MaixCDK developer: DO NOT edit this doc file manually, this doc is auto generated!

+
+

Module

+

No module

+

Enum

+

Variable

+

Function

+

Class

+

WDT

+

Peripheral wdt class

+
+

C++ defination code:

+ +
class WDT
+
+
+

__init__

+

WDT constructor, after construct, the wdt will auto start.

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramid: direction [in], id of wdt, int type
feed_ms: direction [in], feed interval, int type, unit is ms, you must feed wdt in this interval, or system will restart.
staticFalse
+
+

C++ defination code:

+ +
WDT(int id, int feed_ms)
+
+
+

feed

+

feed wdt

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnerror code, if feed success, return err::ERR_NONE
staticFalse
+
+

C++ defination code:

+ +
int feed()
+
+
+

stop

+

stop wdt

+ + + + + + + + + + + + + + + + + +
itemdescription
typefunc
staticFalse
+
+

C++ defination code:

+ +
int stop()
+
+
+

restart

+

restart wdt, stop and start watchdog timer.

+ + + + + + + + + + + + + + + + + +
itemdescription
typefunc
staticFalse
+
+

C++ defination code:

+ +
int restart()
+
+
+ + +
+
+
+ + +
+
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixcdk/api/maix/protocol.html b/maixcdk/api/maix/protocol.html new file mode 100644 index 00000000..dda6a393 --- /dev/null +++ b/maixcdk/api/maix/protocol.html @@ -0,0 +1,1601 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + maix::protocol - MaixCDK + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

maix::protocol

+ +
+
+
    + +
+
+
+
+ + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

maix.protocol module

+
+

This is maix::protocol module of MaixCDK.
+All of these elements are in namespace maix::protocol.

+

For MaixCDK developer: DO NOT edit this doc file manually, this doc is auto generated!

+
+

Module

+

No module

+

Enum

+

CMD

+

protocol cmd, more doc see MaixCDK document's convention doc

+ + + + + + + + + + + + + + + + + +
itemdescribe
notemax app custom CMD value should < CMD_APP_MAX
valuesCMD_APP_MAX: 200, max app custom CMD value should < CMD_APP_MAX
CMD_SET_REPORT: set auto upload data mode
CMD_APP_LIST:
CMD_START_APP:
CMD_EXIT_APP:
CMD_CUR_APP_INFO:
CMD_APP_INFO:
CMD_KEY:
CMD_TOUCH:
+
+

C++ defination code:

+ +
enum CMD
+        {
+            CMD_APP_MAX = 0xC8,     //  200, max app custom CMD value should < CMD_APP_MAX
+
+            CMD_SET_REPORT   = 0xF8, // set auto upload data mode
+            CMD_APP_LIST     = 0xF9,
+            CMD_START_APP    = 0xFA,
+            CMD_EXIT_APP     = 0xFB,
+            CMD_CUR_APP_INFO = 0xFC,
+            CMD_APP_INFO     = 0xFD,
+            CMD_KEY          = 0xFE,
+            CMD_TOUCH        = 0xFF,
+        }
+
+
+

FLAGS

+

protocol flags, more doc see MaixCDK document's convention doc

+ + + + + + + + + + + + + +
itemdescribe
valuesFLAG_REQ:
FLAG_RESP:
FLAG_IS_RESP_MASK:
FLAG_RESP_OK:
FLAG_RESP_ERR:
FLAG_RESP_OK_MASK:
FLAG_REPORT:
FLAG_REPORT_MASK:
FLAG_VERSION_MASK:
+
+

C++ defination code:

+ +
enum FLAGS
+        {
+            FLAG_REQ = 0x00,
+            FLAG_RESP = 0x80,
+            FLAG_IS_RESP_MASK = 0x80,
+
+            FLAG_RESP_OK = 0x40,
+            FLAG_RESP_ERR = 0x00,
+            FLAG_RESP_OK_MASK = 0x40,
+
+            FLAG_REPORT = 0x20,
+            FLAG_REPORT_MASK = 0x20,
+
+            FLAG_VERSION_MASK = 0x03
+        }
+
+
+

Variable

+

VERSION

+

protocol version

+ + + + + + + + + + + + + + + + + +
itemdescription
value1
readonlyTrue
+
+

C++ defination code:

+ +
const uint8_t VERSION = 1
+
+
+ +

protocol header

+ + + + + + + + + + + + + +
itemdescription
readonlyFalse
+
+

C++ defination code:

+ +
extern uint32_t HEADER
+
+
+

Function

+

crc16_IBM

+

CRC16-IBM

+ + + + + + + + + + + + + + + + + +
itemdescription
paramdata: data
len: data length
returnCRC16-IBM value, uint16_t type.
+
+

C++ defination code:

+ +
uint16_t crc16_IBM(unsigned char *data, size_t len)
+
+
+

crc16_IBM (overload 1)

+

CRC16-IBM

+ + + + + + + + + + + + + + + + + +
itemdescription
paramdata: data, bytes type.
returnCRC16-IBM value, uint16_t type.
+
+

C++ defination code:

+ +
uint16_t crc16_IBM(const Bytes *data)
+
+
+

encode

+

Encode message to buffer

+ + + + + + + + + + + + + + + + + +
itemdescription
paramout_buff: output buffer
out_buff_len: output buffer length
cmd: CMD value
flags: FLAGS value, @see maix.protocol.FLAGS
body: message body, can be null
body_len: message body length, can be 0
code: error code, only for error message, that is FLAGS.FLAG_ERR in flags
version: protocol version
returnencoded data length, if < 0, means error, and the error code is -err.Err
+
+

C++ defination code:

+ +
int encode(uint8_t *out_buff, int out_buff_len, uint8_t cmd, uint8_t flags, uint8_t *body, int body_len, uint8_t code = 0xFF, const uint8_t version = VERSION)
+
+
+

Class

+

MSG

+

protocol msg

+
+

C++ defination code:

+ +
class MSG
+
+
+

version

+

protocol version

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typevar
staticFalse
readonlyFalse
+
+

C++ defination code:

+ +
uint8_t version
+
+
+

resp_ok

+

Indicate response message type, true means CMD valid and the CMD processed correctly, (only for response msg)

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typevar
staticFalse
readonlyFalse
+
+

C++ defination code:

+ +
uint8_t resp_ok
+
+
+

has_been_replied

+

Flag whether CMD has been processed and responded to CMD sender.\nE.g. CMD CMD_START_APP will be automatically processed in CommProtocol.get_msg function,\nso the return msg will set this flag to true.

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typevar
staticFalse
readonlyFalse
+
+

C++ defination code:

+ +
bool has_been_replied{false}
+
+
+

cmd

+

CMD value

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typevar
staticFalse
readonlyFalse
+
+

C++ defination code:

+ +
uint8_t cmd
+
+
+

is_resp

+

message is response or not, contrast with is_req

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typevar
staticFalse
readonlyFalse
+
+

C++ defination code:

+ +
bool is_resp
+
+
+

body

+

Message body, read only, use set_body() to update

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typevar
attentionDO NOT manually change this value
staticFalse
readonlyFalse
+
+

C++ defination code:

+ +
uint8_t *body
+
+
+

body_len

+

Message body length, read only, use set_body() to update

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typevar
attentionDO NOT manually change this value
staticFalse
readonlyFalse
+
+

C++ defination code:

+ +
int body_len
+
+
+

encode_resp_ok

+

Encode response ok(success) message

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
parambuff: output buffer
buff_len: output buffer length
body: response body, can be null
body_len: response body length, can be 0
returnencoded data length, if < 0, means error, and the error code is -err.Err
staticFalse
+
+

C++ defination code:

+ +
int encode_resp_ok(uint8_t *buff, int buff_len, uint8_t *body = nullptr, int body_len = 0)
+
+
+

encode_resp_ok (overload 1)

+

Encode response ok(success) message

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
parambody: response body, can be null
returnencoded data, if nullptr, means error, and the error code is -err.Err
staticFalse
+
+

C++ defination code:

+ +
Bytes *encode_resp_ok(uint8_t *body = nullptr, int body_len = 0)
+
+
+

encode_resp_ok (overload 2)

+

Encode response ok(success) message

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
parambody: response body, can be null
returnencoded data, if nullptr, means error, and the error code is -err.Err
staticFalse
+
+

C++ defination code:

+ +
Bytes *encode_resp_ok(Bytes *body = nullptr)
+
+
+

encode_report

+

Encode proactively report message

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
parambuff: output buffer
buff_len: output buffer length
body: report body, can be null
body_len: report body length, can be 0
returnencoded data length, if < 0, means error, and the error code is -err.Err
staticFalse
+
+

C++ defination code:

+ +
int encode_report(uint8_t *buff, int buff_len, uint8_t *body = nullptr, int body_len = 0)
+
+
+

encode_report (overload 1)

+

Encode proactively report message

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
parambody: report body, can be null
returnencoded data, if nullptr, means error, and the error code is -err.Err
staticFalse
+
+

C++ defination code:

+ +
Bytes *encode_report(uint8_t *body = nullptr, int body_len = 0)
+
+
+

encode_report (overload 2)

+

Encode proactively report message

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
parambody: report body, can be null
returnencoded data, if nullptr, means error, and the error code is -err.Err
staticFalse
+
+

C++ defination code:

+ +
Bytes *encode_report(Bytes *body = nullptr)
+
+
+

encode_resp_err

+

Encode response error message

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
parambuff: output buffer
buff_len: output buffer length
code: error code
msg: error message
returnencoded data length, if < 0, means error, and the error code is -err.Err
staticFalse
+
+

C++ defination code:

+ +
int encode_resp_err(uint8_t *buff, int buff_len, err::Err code, const std::string &msg)
+
+
+

encode_resp_err (overload 1)

+

Encode response error message

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramcode: error code
msg: error message
returnencoded data, if nullptr, means error, and the error code is -err.Err
staticFalse
+
+

C++ defination code:

+ +
Bytes *encode_resp_err(err::Err code, const std::string &msg)
+
+
+

set_body

+

Update message body

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
parambody_new: new body data
body_len: new body data length
staticFalse
+
+

C++ defination code:

+ +
void set_body(uint8_t *body_new, int body_len)
+
+
+

set_body (overload 1)

+

Update message body

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
parambody_new: new body data
staticFalse
+
+

C++ defination code:

+ +
void set_body(Bytes *body_new)
+
+
+

get_body

+

Get message body

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnmessage body, bytes type
staticFalse
+
+

C++ defination code:

+ +
Bytes *get_body()
+
+
+

Protocol

+

Communicate protocol

+
+

C++ defination code:

+ +
class Protocol
+
+
+

Protocol

+

Construct a new Protocol object

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
parambuff_size: Data queue buffer size
staticFalse
+
+

C++ defination code:

+ +
Protocol(int buff_size = 1024, uint32_t header=maix::protocol::HEADER)
+
+
+

buff_size

+

Data queue buffer size

+ + + + + + + + + + + + + + + + + +
itemdescription
typefunc
staticFalse
+
+

C++ defination code:

+ +
int buff_size()
+
+
+

push_data

+

Add data to data queue

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramnew_data: new data
len: new data length
returnerror code, maybe err.Err.ERR_BUFF_FULL
staticFalse
+
+

C++ defination code:

+ +
err::Err push_data(uint8_t *new_data, int len)
+
+
+

push_data (overload 1)

+

Add data to data queue

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramnew_data: new data
returnerror code, maybe err.Err.ERR_BUFF_FULL
staticFalse
+
+

C++ defination code:

+ +
err::Err push_data(const Bytes *new_data)
+
+
+

decode

+

Decode data in data queue and return a message

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramnew_data: new data add to data queue, if null, only decode.
len: new data length, can be 0.
returndecoded message, if nullptr, means no message decoded.
staticFalse
+
+

C++ defination code:

+ +
protocol::MSG *decode(uint8_t *new_data = nullptr, size_t len = 0)
+
+
+

decode (overload 1)

+

Decode data in data queue and return a message

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramnew_data: new data add to data queue, if null, only decode.
returndecoded message, if nullptr, means no message decoded.
staticFalse
+
+

C++ defination code:

+ +
protocol::MSG *decode(const Bytes *new_data = nullptr)
+
+
+

encode_resp_ok

+

Encode response ok(success) message to buffer

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
parambuff: output buffer
buff_len: output buffer length
cmd: CMD value
body: response body, can be null
body_len: response body length, can be 0
returnencoded data length, if < 0, means error, and the error code is -err.Err
staticFalse
+
+

C++ defination code:

+ +
int encode_resp_ok(uint8_t *buff, int buff_len, uint8_t cmd, uint8_t *body = nullptr, int body_len = 0)
+
+
+

encode_resp_ok (overload 1)

+

Encode response ok(success) message to buffer

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramcmd: CMD value
body: response body, can be null
body_len: response body length, can be 0
returnencoded data, if nullptr, means error, and the error code is -err.Err
staticFalse
+
+

C++ defination code:

+ +
Bytes *encode_resp_ok(uint8_t cmd, uint8_t *body = nullptr, int body_len = 0)
+
+
+

encode_resp_ok (overload 2)

+

Encode response ok(success) message to buffer

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramcmd: CMD value
body: response body, can be null
returnencoded data, if nullptr, means error, and the error code is -err.Err
staticFalse
+
+

C++ defination code:

+ +
Bytes *encode_resp_ok(uint8_t cmd, Bytes *body = nullptr)
+
+
+

encode_report

+

Encode proactively report message to buffer

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
parambuff: output buffer
buff_len: output buffer length
cmd: CMD value
body: report body, can be null
body_len: report body length, can be 0
returnencoded data length, if < 0, means error, and the error code is -err.Err
staticFalse
+
+

C++ defination code:

+ +
int encode_report(uint8_t *buff, int buff_len, uint8_t cmd, uint8_t *body = nullptr, int body_len = 0)
+
+
+

encode_report (overload 1)

+

Encode proactively report message to buffer

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramcmd: CMD value
body: report body, can be null
body_len: report body length, can be 0
returnencoded data, if nullptr, means error, and the error code is -err.Err
staticFalse
+
+

C++ defination code:

+ +
Bytes *encode_report(uint8_t cmd, uint8_t *body = nullptr, int body_len = 0)
+
+
+

encode_report (overload 2)

+

Encode proactively report message to buffer

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramcmd: CMD value
body: report body, can be null
returnencoded data, if nullptr, means error, and the error code is -err.Err
staticFalse
+
+

C++ defination code:

+ +
Bytes *encode_report(uint8_t cmd, Bytes *body = nullptr)
+
+
+

encode_resp_err

+

Encode response error message to buffer

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
parambuff: output buffer
buff_len: output buffer length
cmd: CMD value
code: error code
msg: error message
returnencoded data length, if < 0, means error, and the error code is -err.Err
staticFalse
+
+

C++ defination code:

+ +
int encode_resp_err(uint8_t *buff, int buff_len, uint8_t cmd, err::Err code, const std::string &msg)
+
+
+

encode_resp_err (overload 1)

+

Encode response error message to buffer

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramcmd: CMD value
code: error code
msg: error message
returnencoded data, if nullptr, means error, and the error code is -err.Err
staticFalse
+
+

C++ defination code:

+ +
Bytes *encode_resp_err(uint8_t cmd, err::Err code, const std::string &msg)
+
+
+ + +
+
+
+ + +
+
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixcdk/api/maix/rtmp.html b/maixcdk/api/maix/rtmp.html new file mode 100644 index 00000000..bae16db5 --- /dev/null +++ b/maixcdk/api/maix/rtmp.html @@ -0,0 +1,901 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + maix::rtmp - MaixCDK + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

maix::rtmp

+ +
+
+
    + +
+
+
+
+ + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

maix.rtmp module

+
+

This is maix::rtmp module of MaixCDK.
+All of these elements are in namespace maix::rtmp.

+

For MaixCDK developer: DO NOT edit this doc file manually, this doc is auto generated!

+
+

Module

+

No module

+

Enum

+

TagType

+

Video type

+ + + + + + + + + + + + + +
itemdescribe
valuesTAG_NONE:
TAG_VIDEO:
TAG_AUDIO:
TAG_SCRIPT:
+
+

C++ defination code:

+ +
enum TagType
+    {
+        TAG_NONE,
+        TAG_VIDEO,
+        TAG_AUDIO,
+        TAG_SCRIPT,
+    }
+
+
+

Variable

+

Function

+

Class

+

Rtmp

+

Rtmp class

+
+

C++ defination code:

+ +
class Rtmp
+
+
+

Rtmp

+

Construct a new Video object

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
noteRtmp url : rtmp://host:prot/app/stream
example:
r = Rtmp("localhost", 1935, "live", "stream")
means rtmp url is rtmp://localhost:1935/live/stream
paramhost: rtmp ip
port: rtmp port, default is 1935.
app: rtmp app name
stream: rtmp stream name
bitrate: rtmp bitrate, default is 1000 * 1000
staticFalse
+
+

C++ defination code:

+ +
Rtmp(std::string host = "localhost", int port = 1935, std::string app = std::string(), std::string stream = std::string(), int bitrate = 1000 * 1000)
+
+
+

push_video

+

Get bitrate

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnbitrate
staticFalse
+
+

C++ defination code:

+ +
int bitrate()
+
+
+

push_video (overload 1)

+

Push rtmp video data

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnreturn 0 ok, other error
staticFalse
+
+

C++ defination code:

+ +
int push_video(void *data, size_t data_size, uint32_t timestamp)
+
+
+

push_audio

+

Push rtmp audio data

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnreturn 0 ok, other error
staticFalse
+
+

C++ defination code:

+ +
int push_audio(void *data, size_t data_size, uint32_t timestamp)
+
+
+

push_script

+

Push rtmp script data

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnreturn 0 ok, other error
staticFalse
+
+

C++ defination code:

+ +
int push_script(void *data, size_t data_size, uint32_t timestamp)
+
+
+

bind_camera

+

Bind camera

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
noteIf the cam object is bound, the cam object cannot be used elsewhere.
paramcam: camera object
returnerror code, err::ERR_NONE means success, others means failed
staticFalse
+
+

C++ defination code:

+ +
err::Err bind_camera(camera::Camera *cam)
+
+
+

bind_audio_recorder

+

Bind audio recorder

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
noteIf the audio_recorder object is bound, the audio_recorder object cannot be used elsewhere.
paramrecorder: audio_recorder object
returnerror code, err::ERR_NONE means success, others means failed
staticFalse
+
+

C++ defination code:

+ +
err::Err bind_audio_recorder(audio::Recorder *recorder)
+
+
+

bind_display

+

Bind display

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
noteIf the display object is bound, the display object cannot be used elsewhere.
paramdisaply: display object
returnerror code, err::ERR_NONE means success, others means failed
staticFalse
+
+

C++ defination code:

+ +
err::Err bind_display(display::Display *display)
+
+
+

get_camera

+

If you bind a camera, return the camera object.

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnCamera object
staticFalse
+
+

C++ defination code:

+ +
camera::Camera *get_camera()
+
+
+

capture

+

If you bind a camera, capture the image of the camera

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
noteThe return value may be null, you must check whether the return value is null
returnImage object
staticFalse
+
+

C++ defination code:

+ +
image::Image *capture()
+
+
+

start

+

Start push stream

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
noteonly support flv file now
parampath: File path, if you passed file path, cyclic push the file, else if you bound camera, push the camera image.(This parameter has been deprecated)
returnerror code, err::ERR_NONE means success, others means failed
staticFalse
+
+

C++ defination code:

+ +
err::Err start(std::string path = std::string())
+
+
+

stop

+

Stop push stream

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnerror code, err::ERR_NONE means success, others means failed
staticFalse
+
+

C++ defination code:

+ +
err::Err stop()
+
+
+

lock

+

Lock

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramtime: lock time, unit:ms
returnerror code, err::ERR_NONE means success, others means failed
staticFalse
+
+

C++ defination code:

+ +
err::Err lock(uint32_t time)
+
+
+

unlock

+

Unlock

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnerror code, err::ERR_NONE means success, others means failed
staticFalse
+
+

C++ defination code:

+ +
err::Err unlock()
+
+
+

get_path

+

Get the file path of the push stream

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnfile path
staticFalse
+
+

C++ defination code:

+ +
std::string get_path()
+
+
+

get_path (overload 1)

+

Check whether push streaming has started

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnIf rtmp thread is running, returns true
staticFalse
+
+

C++ defination code:

+ +
bool is_started()
+
+
+ + +
+
+
+ + +
+
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixcdk/api/maix/rtsp.html b/maixcdk/api/maix/rtsp.html new file mode 100644 index 00000000..c8efc034 --- /dev/null +++ b/maixcdk/api/maix/rtsp.html @@ -0,0 +1,952 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + maix::rtsp - MaixCDK + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

maix::rtsp

+ +
+
+
    + +
+
+
+
+ + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

maix.rtsp module

+
+

This is maix::rtsp module of MaixCDK.
+All of these elements are in namespace maix::rtsp.

+

For MaixCDK developer: DO NOT edit this doc file manually, this doc is auto generated!

+
+

Module

+

No module

+

Enum

+

RtspStreamType

+

The stream type of rtsp

+ + + + + + + + + + + + + +
itemdescribe
valuesRTSP_STREAM_NONE: format invalid
RTSP_STREAM_H264:
RTSP_STREAM_H265:
+
+

C++ defination code:

+ +
enum RtspStreamType
+    {
+        RTSP_STREAM_NONE = 0,  // format invalid
+        RTSP_STREAM_H264,
+        RTSP_STREAM_H265,
+    }
+
+
+

Variable

+

Function

+

Class

+

Region

+

Region class

+
+

C++ defination code:

+ +
class Region
+
+
+

Region

+

Construct a new Region object

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramx: region coordinate x
y: region coordinate y
width: region width
height: region height
format: region format
camera: bind region to camera
staticFalse
+
+

C++ defination code:

+ +
Region(int x, int y, int width, int height, image::Format format, camera::Camera *camera)
+
+
+

get_canvas

+

Return an image object from region

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnimage object
staticFalse
+
+

C++ defination code:

+ +
image::Image *get_canvas()
+
+
+

update_canvas

+

Update canvas

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnerror code
staticFalse
+
+

C++ defination code:

+ +
err::Err update_canvas()
+
+
+

Rtsp

+

Rtsp class

+
+

C++ defination code:

+ +
class Rtsp
+
+
+

Rtsp

+

Construct a new Video object

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramip: rtsp ip
port: rtsp port
fps: rtsp fps
stream_type: rtsp stream type
bitrate: rtsp bitrate
staticFalse
+
+

C++ defination code:

+ +
Rtsp(std::string ip = std::string(), int port = 8554, int fps = 30, rtsp::RtspStreamType stream_type = rtsp::RtspStreamType::RTSP_STREAM_H264, int bitrate = 3000 * 1000)
+
+
+

start

+

start rtsp

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnerror code, err::ERR_NONE means success, others means failed
staticFalse
+
+

C++ defination code:

+ +
err::Err start()
+
+
+

start (overload 1)

+

stop rtsp

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnerror code, err::ERR_NONE means success, others means failed
staticFalse
+
+

C++ defination code:

+ +
err::Err stop()
+
+
+

bind_camera

+

Bind camera

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramcamera: camera object
returnerror code, err::ERR_NONE means success, others means failed
staticFalse
+
+

C++ defination code:

+ +
err::Err bind_camera(camera::Camera *camera)
+
+
+

bind_audio_recorder

+

Bind audio recorder

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
noteIf the audio_recorder object is bound, the audio_recorder object cannot be used elsewhere.
paramrecorder: audio_recorder object
returnerror code, err::ERR_NONE means success, others means failed
staticFalse
+
+

C++ defination code:

+ +
err::Err bind_audio_recorder(audio::Recorder *recorder)
+
+
+

write

+

Write data to rtsp(This function will be removed in the future)

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramframe: video frame data
returnerror code, err::ERR_NONE means success, others means failed
staticFalse
+
+

C++ defination code:

+ +
err::Err write(video::Frame &frame)
+
+
+

get_url

+

Get url of rtsp

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnurl of rtsp
staticFalse
+
+

C++ defination code:

+ +
std::string get_url()
+
+
+

get_urls

+

Get url list of rtsp

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnurl list of rtsp
staticFalse
+
+

C++ defination code:

+ +
std::vector<std::string> get_urls()
+
+
+

to_camera

+

Get camera object from rtsp

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returncamera object
staticFalse
+
+

C++ defination code:

+ +
camera::Camera *to_camera()
+
+
+

rtsp_is_start

+

return rtsp start status

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returntrue means rtsp is start, false means rtsp is stop.
staticFalse
+
+

C++ defination code:

+ +
bool rtsp_is_start()
+
+
+

add_region

+

return a region object, you can draw image on the region.(This function will be removed in the future)

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramx: region coordinate x
y: region coordinate y
width: region width
height: region height
format: region format, support Format::FMT_BGRA8888 only
returnthe reigon object
staticFalse
+
+

C++ defination code:

+ +
rtsp::Region *add_region(int x, int y, int width, int height, image::Format format = image::Format::FMT_BGRA8888)
+
+
+

update_region

+

update and show region(This function will be removed in the future)

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnerror code
staticFalse
+
+

C++ defination code:

+ +
err::Err update_region(rtsp::Region &region)
+
+
+

del_region

+

del region(This function will be removed in the future)

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnerror code
staticFalse
+
+

C++ defination code:

+ +
err::Err del_region(rtsp::Region *region)
+
+
+

draw_rect

+

Draw a rectangle on the canvas(This function will be removed in the future)

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramid: region id
x: rectangle coordinate x
y: rectangle coordinate y
width: rectangle width
height: rectangle height
color: rectangle color
thickness: rectangle thickness. If you set it to -1, the rectangle will be filled.
returnerror code
staticFalse
+
+

C++ defination code:

+ +
err::Err draw_rect(int id, int x, int y, int width, int height, image::Color color, int thickness = 1)
+
+
+

draw_string

+

Draw a string on the canvas(This function will be removed in the future)

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramid: region id
x: string coordinate x
y: string coordinate y
str: string
color: string color
size: string size
thickness: string thickness
returnerror code
staticFalse
+
+

C++ defination code:

+ +
err::Err draw_string(int id, int x, int y, const char *str, image::Color color, int size = 16, int thickness = 1)
+
+
+ + +
+
+
+ + +
+
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixcdk/api/maix/sys.html b/maixcdk/api/maix/sys.html new file mode 100644 index 00000000..5ec9d408 --- /dev/null +++ b/maixcdk/api/maix/sys.html @@ -0,0 +1,811 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + maix::sys - MaixCDK + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

maix::sys

+ +
+
+
    + +
+
+
+
+ + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

maix.sys module

+
+

This is maix::sys module of MaixCDK.
+All of these elements are in namespace maix::sys.

+

For MaixCDK developer: DO NOT edit this doc file manually, this doc is auto generated!

+
+

Module

+

No module

+

Enum

+

Variable

+

Function

+

os_version

+

Get system version

+ + + + + + + + + + + + + +
itemdescription
returnversion string, e.g. "maixcam-2024-08-13-maixpy-v4.4.20"
+
+

C++ defination code:

+ +
std::string os_version()
+
+
+

maixpy_version

+

Get MaixPy version, if get failed will return empty string.

+ + + + + + + + + + + + + +
itemdescription
returnversion string, e.g. "4.4.21"
+
+

C++ defination code:

+ +
std::string maixpy_version()
+
+
+

runtime_version

+

Get runtime version

+ + + + + + + + + + + + + +
itemdescription
returncurrent runtime version
+
+

C++ defination code:

+ +
std::string runtime_version()
+
+
+

device_id

+

Get device configs, we also say board configs. e.g. for MaixCAM it read form /boot/board

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
paramcache: read id from cache(if exists, or will call device_configs first internally) if true,
if false, always read fron config file.
returndevice id, e.g. "maixcam" "maixcam_pro"
throwIf board config file error will throw out exception(err.Exception)
+
+

C++ defination code:

+ +
std::map<std::string, std::string> device_configs(bool cache = true)
+
+
+

device_id (overload 1)

+

Get device id

+ + + + + + + + + + + + + + + + + +
itemdescription
paramcache: read id from cache(if exists, or will call device_configs first internally) if true,
if false, always read fron config file.
returndevice id, e.g. "maixcam" "maixcam_pro"
+
+

C++ defination code:

+ +
std::string device_id(bool cache = true)
+
+
+

device_name

+

Get device name

+ + + + + + + + + + + + + + + + + +
itemdescription
paramcache: read id from cache(if exists, or will call device_configs first internally) if true,
if false, always read fron config file.
returndevice name, e.g. "MaixCAM" "MaixCAM-Pro"
+
+

C++ defination code:

+ +
std::string device_name(bool cache = true)
+
+
+

host_name

+

Get host name

+ + + + + + + + + + + + + +
itemdescription
returnhost name, e.g. "maixcam-2f9f"
+
+

C++ defination code:

+ +
std::string host_name()
+
+
+

host_domain

+

Get host domain

+ + + + + + + + + + + + + +
itemdescription
returnhost domain, e.g. "maixcam-2f9f.local"
+
+

C++ defination code:

+ +
std::string host_domain()
+
+
+

ip_address

+

Get ip address

+ + + + + + + + + + + + + +
itemdescription
returnip address, dict type, e.g. {"eth0": "192.168.0.195", "wlan0": "192.168.0.123", "usb0": "10.47.159.1"}
+
+

C++ defination code:

+ +
std::map<std::string, std::string> ip_address()
+
+
+

mac_address

+

Get mac address

+ + + + + + + + + + + + + +
itemdescription
returnmac address, dict type, e.g. {"eth0": "00:0c:29:2f:9f:00", "wlan0": "00:0c:29:2f:9f:01", "usb0": "00:0c:29:2f:9f:02"}
+
+

C++ defination code:

+ +
std::map<std::string, std::string> mac_address()
+
+
+

device_key

+

Get device key, can be unique id of device

+ + + + + + + + + + + + + +
itemdescription
returndevice key, 32 bytes hex string, e.g. "1234567890abcdef1234567890abcdef"
+
+

C++ defination code:

+ +
std::string device_key()
+
+
+

memory_info

+

Get memory info

+ + + + + + + + + + + + + +
itemdescription
returnmemory info, dict type, e.g. {"total": 1024, "used": 512, "hw_total": 25610241024}
total: total memory size in Byte.
used: used memory size in Byte.
hw_total: total memory size in Byte of hardware, the total <= hw_total,
OS kernel may reserve some memory for some hardware like camera, npu, display etc.
+
+

C++ defination code:

+ +
std::map<std::string, int> memory_info()
+
+
+

bytes_to_human

+

Bytes to human readable string

+ + + + + + + + + + + + + + + + + +
itemdescription
parambytes:: bytes size,e.g. 1234B = 1234/1024 = 1.205 KB
precision:: decimal precision, default 2
base:: base number, default 1024
unit:: unit string, e.g. "B"
sep:: separator string, e.g. " "
returnhuman readable string, e.g. "1.21 KB"
+
+

C++ defination code:

+ +
std::string bytes_to_human(unsigned long long bytes, int precision = 2, int base = 1024, const std::string &unit = "B", const std::string &sep = " ")
+
+
+

cpu_freq

+

Get CPU frequency

+ + + + + + + + + + + + + +
itemdescription
returnCPU frequency, dict type, e.g. {"cpu0": 1000000000, "cpu1": 1000000000}
+
+

C++ defination code:

+ +
std::map<std::string, unsigned long> cpu_freq()
+
+
+

cpu_temp

+

Get CPU temperature

+ + + + + + + + + + + + + +
itemdescription
returnCPU temperature, unit dgree, dict type, e.g. {"cpu": 50.0, "cpu0": 50, "cpu1": 50}
+
+

C++ defination code:

+ +
std::map<std::string, float> cpu_temp()
+
+
+

cpu_usage

+

Get CPU usage

+ + + + + + + + + + + + + +
itemdescription
returnCPU usage, dict type, e.g. {"cpu": 50.0, "cpu0": 50, "cpu1": 50}
+
+

C++ defination code:

+ +
std::map<std::string, float> cpu_usage()
+
+
+

npu_freq

+

Get NPU frequency

+ + + + + + + + + + + + + +
itemdescription
returnNPU frequency, dict type, e.g. {"npu0": 500000000}
+
+

C++ defination code:

+ +
std::map<std::string, unsigned long> npu_freq()
+
+
+

disk_usage

+

Get disk usage

+ + + + + + + + + + + + + + + + + +
itemdescription
parampath:: disk path, default "/"
returndisk usage, dict type, e.g. {"total": 1024, "used": 512}
+
+

C++ defination code:

+ +
std::map<std::string, unsigned long long> disk_usage(const std::string &path = "/")
+
+
+

disk_partitions

+

Get disk partition and mount point info

+ + + + + + + + + + + + + + + + + +
itemdescription
paramonly_disk: only return real disk, tempfs sysfs etc. not return, default true.
returndisk partition and mount point info, list type, e.g. [{"device": "/dev/mmcblk0p1", "mountpoint": "/mnt/sdcard", "fstype": "vfat"}]
+
+

C++ defination code:

+ +
std::vector<std::map<std::string, std::string>> disk_partitions(bool only_disk = true)
+
+
+

register_default_signal_handle

+

register default signal handle

+
+

C++ defination code:

+ +
void register_default_signal_handle()
+
+
+

poweroff

+

Power off device

+
+

C++ defination code:

+ +
void poweroff()
+
+
+

reboot

+

Power off device and power on

+
+

C++ defination code:

+ +
void reboot()
+
+
+

Class

+ + +
+
+
+ + +
+
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixcdk/api/maix/tensor.html b/maixcdk/api/maix/tensor.html new file mode 100644 index 00000000..56444209 --- /dev/null +++ b/maixcdk/api/maix/tensor.html @@ -0,0 +1,1146 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + maix::tensor - MaixCDK + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

maix::tensor

+ +
+
+
    + +
+
+
+
+ + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

maix.tensor module

+
+

This is maix::tensor module of MaixCDK.
+All of these elements are in namespace maix::tensor.

+

For MaixCDK developer: DO NOT edit this doc file manually, this doc is auto generated!

+
+

Module

+

No module

+

Enum

+

DType

+

Tensor data types

+ + + + + + + + + + + + + +
itemdescribe
valuesUINT8:
INT8:
UINT16:
INT16:
UINT32:
INT32:
FLOAT16:
FLOAT32:
FLOAT64:
BOOL:
DTYPE_MAX:
+
+

C++ defination code:

+ +
enum DType
+        {
+            UINT8 = 0,
+            INT8,
+            UINT16,
+            INT16,
+            UINT32,
+            INT32,
+            FLOAT16,
+            FLOAT32,
+            FLOAT64,
+            BOOL,
+            // STRING,
+            // OBJECT,
+            DTYPE_MAX
+        }
+
+
+

Variable

+

dtype_size

+

Tensor data type size in bytes

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
attentionIt's a copy of this variable in MaixPy,
so change it in C++ (e.g. update var in hello function) will not take effect the var inMaixPy.
So we add const for this var to avoid this mistake.
value{
1, // UINT8
1, // INT8
2, // UINT16
2, // INT16
4, // UINT32
4, // INT32
2, // FLOAT16
4, // FLOAT32
8, // FLOAT64
1, // BOOL
// 1, // STRING
// 1, // OBJECT
0
}
readonlyTrue
+
+

C++ defination code:

+ +
const std::vector<int> dtype_size = {
+            1, // UINT8
+            1, // INT8
+            2, // UINT16
+            2, // INT16
+            4, // UINT32
+            4, // INT32
+            2, // FLOAT16
+            4, // FLOAT32
+            8, // FLOAT64
+            1, // BOOL
+            // 1, // STRING
+            // 1, // OBJECT
+            0
+        }
+
+
+

dtype_name

+

Tensor data type name

+ + + + + + + + + + + + + + + + + +
itemdescription
value{
"uint8",
"int8",
"uint16",
"int16",
"uint32",
"int32",
"float16",
"float32",
"float64",
"bool",
// "string",
// "object",
"invalid"
}
readonlyTrue
+
+

C++ defination code:

+ +
const std::vector<std::string> dtype_name = {
+            "uint8",
+            "int8",
+            "uint16",
+            "int16",
+            "uint32",
+            "int32",
+            "float16",
+            "float32",
+            "float64",
+            "bool",
+            // "string",
+            // "object",
+            "invalid"
+        }
+
+
+

Function

+

Class

+

Tensor

+

Tensor class

+
+

C++ defination code:

+ +
class Tensor
+
+
+

__init__

+

Tensor constructor

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramshape: tensor shape, a int list
dtype: tensor element data type, see DType of this module
staticFalse
+
+

C++ defination code:

+ +
Tensor(std::vector<int> shape, tensor::DType dtype)
+
+
+

Tensor

+

Tensor constructor

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramshape: tensor shape, a int list
dtype: tensor element data type, see DType of this module
data: pointer to data content, can be nullptr, it will automatically alloc memory
and detroy it when this object is destroyed
copy: defalt true to alloc new memory and copy from data.
staticFalse
+
+

C++ defination code:

+ +
Tensor(std::vector<int> shape, tensor::DType dtype, void *data, bool copy = true)
+
+
+

to_str

+

To string

+ + + + + + + + + + + + + + + + + +
itemdescription
typefunc
staticFalse
+
+

C++ defination code:

+ +
std::string to_str()
+
+
+

__str__

+

To string

+ + + + + + + + + + + + + + + + + +
itemdescription
typefunc
staticFalse
+
+

C++ defination code:

+ +
std::string __str__()
+
+
+

shape

+

get tensor shape

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returntensor shape, a int list
staticFalse
+
+

C++ defination code:

+ +
std::vector<int> shape()
+
+
+

expand_dims

+

expand tensor shape

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramaxis: axis to expand
staticFalse
+
+

C++ defination code:

+ +
void expand_dims(int axis)
+
+
+

reshape

+

reshape tensor shape, if size not match, it will throw an err::Exception

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramshape: new shape
staticFalse
+
+

C++ defination code:

+ +
void reshape(std::vector<int> shape)
+
+
+

flatten

+

Flatten tensor shape to 1D

+ + + + + + + + + + + + + + + + + +
itemdescription
typefunc
staticFalse
+
+

C++ defination code:

+ +
void flatten()
+
+
+

dtype

+

get tensor data type

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returntensor data type, see DType of this module
staticFalse
+
+

C++ defination code:

+ +
tensor::DType  dtype()
+
+
+

to_float_list

+

get tensor data and return a list

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnlist type data
staticFalse
+
+

C++ defination code:

+ +
std::valarray<float>* to_float_list()
+
+
+

argmax

+

argmax of tensor

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramaxis: By default, the index is into the flattened array, otherwise along the specified axis., wrong axis will throw an err::Exception
returnargmax result, you need to delete it after use in C++.
staticFalse
+
+

C++ defination code:

+ +
tensor::Tensor *argmax(int axis = 0xffff)
+
+
+

argmax1

+

argmax1, flattened data max index

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnargmax result, int type
staticFalse
+
+

C++ defination code:

+ +
int argmax1()
+
+
+

Tensors

+

Tensors

+
+

C++ defination code:

+ +
class Tensors
+
+
+

Tensors

+

Constructor of Tensors

+ + + + + + + + + + + + + + + + + +
itemdescription
typefunc
staticFalse
+
+

C++ defination code:

+ +
Tensors()
+
+
+

add_tensor

+

Add tensor

+ + + + + + + + + + + + + + + + + +
itemdescription
typefunc
staticFalse
+
+

C++ defination code:

+ +
void add_tensor(const std::string &key, tensor::Tensor *tensor, bool copy, bool auto_delete)
+
+
+

rm_tensor

+

Remove tensor

+ + + + + + + + + + + + + + + + + +
itemdescription
typefunc
staticFalse
+
+

C++ defination code:

+ +
void rm_tensor(const std::string &key)
+
+
+

clear

+

Clear tensors

+ + + + + + + + + + + + + + + + + +
itemdescription
typefunc
staticFalse
+
+

C++ defination code:

+ +
void clear()
+
+
+

begin

+

Begin of tensors

+ + + + + + + + + + + + + + + + + +
itemdescription
typefunc
staticFalse
+
+

C++ defination code:

+ +
std::map<std::string, tensor::Tensor*>::iterator begin()
+
+
+

end

+

End of tensors

+ + + + + + + + + + + + + + + + + +
itemdescription
typefunc
staticFalse
+
+

C++ defination code:

+ +
std::map<std::string, tensor::Tensor*>::iterator end()
+
+
+

next

+

next

+ + + + + + + + + + + + + + + + + +
itemdescription
typefunc
staticFalse
+
+

C++ defination code:

+ +
std::map<std::string, tensor::Tensor*>::iterator next(std::map<std::string, tensor::Tensor*>::iterator it)
+
+
+

get_tensor

+

Get tensor by key

+ + + + + + + + + + + + + + + + + +
itemdescription
typefunc
staticFalse
+
+

C++ defination code:

+ +
tensor::Tensor &get_tensor(const std::string &key)
+
+
+

[]

+

Operator []

+ + + + + + + + + + + + + + + + + +
itemdescription
typefunc
staticFalse
+
+

C++ defination code:

+ +
tensor::Tensor &operator[](const std::string &key)
+
+
+

size

+

Size

+ + + + + + + + + + + + + + + + + +
itemdescription
typefunc
staticFalse
+
+

C++ defination code:

+ +
size_t size()
+
+
+

keys

+

Get names

+ + + + + + + + + + + + + + + + + +
itemdescription
typefunc
staticFalse
+
+

C++ defination code:

+ +
std::vector<std::string> keys()
+
+
+

tensors

+

Tensors data, dict type

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typevar
staticFalse
readonlyFalse
+
+

C++ defination code:

+ +
std::map<std::string, tensor::Tensor*> tensors
+
+
+ + +
+
+
+ + +
+
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixcdk/api/maix/thread.html b/maixcdk/api/maix/thread.html new file mode 100644 index 00000000..dc9355f2 --- /dev/null +++ b/maixcdk/api/maix/thread.html @@ -0,0 +1,461 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + maix::thread - MaixCDK + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

maix::thread

+ +
+
+
    + +
+
+
+
+ + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

maix.thread module

+
+

This is maix::thread module of MaixCDK.
+All of these elements are in namespace maix::thread.

+

For MaixCDK developer: DO NOT edit this doc file manually, this doc is auto generated!

+
+

Module

+

No module

+

Enum

+

Variable

+

Function

+

Class

+

Thread

+

thread class

+
+

C++ defination code:

+ +
class Thread
+
+
+

Thread

+

create thread

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramfunc: direction [in], thread function, one args parameter, void* type, no return value
args: direction [in], thread function parameter
staticFalse
+
+

C++ defination code:

+ +
Thread(std::function<void(void *)> func, void *args = nullptr)
+
+
+

join

+

wait thread exit

+ + + + + + + + + + + + + + + + + +
itemdescription
typefunc
staticFalse
+
+

C++ defination code:

+ +
void join()
+
+
+

detach

+

detach thread, detach will auto start thread and you can't use join anymore.

+ + + + + + + + + + + + + + + + + +
itemdescription
typefunc
staticFalse
+
+

C++ defination code:

+ +
void detach()
+
+
+

joinable

+

Check if thread is joinable

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returntrue if thread is joinable
staticFalse
+
+

C++ defination code:

+ +
bool joinable()
+
+
+ + +
+
+
+ + +
+
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixcdk/api/maix/time.html b/maixcdk/api/maix/time.html new file mode 100644 index 00000000..4272c87f --- /dev/null +++ b/maixcdk/api/maix/time.html @@ -0,0 +1,1549 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + maix::time - MaixCDK + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

maix::time

+ +
+
+
    + +
+
+
+
+ + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

maix.time module

+
+

This is maix::time module of MaixCDK.
+All of these elements are in namespace maix::time.

+

For MaixCDK developer: DO NOT edit this doc file manually, this doc is auto generated!

+
+

Module

+

No module

+

Enum

+

Variable

+

Function

+

time

+

Get current time in s

+ + + + + + + + + + + + + + + + + +
itemdescription
returncurrent time in s, double type
attentionIf board have no RTC battery, when bootup and connect to network,
system will automatically sync time by NTP, will cause time() have big change,
e.g. before NTP: 10(s), after: 1718590639.5149617(s).
If you want to calculate time interval, please use ticks_s().
+
+

C++ defination code:

+ +
double time()
+
+
+

time_ms

+

Get current time in ms

+ + + + + + + + + + + + + + + + + +
itemdescription
returncurrent time in ms, uint64_t type
attentionIf board have no RTC battery, when bootup and connect to network,
system will automatically sync time by NTP, will cause time() have big change,
e.g. before NTP: 10000(ms), after: 1718590639000(ms)
If you want to calculate time interval, please use ticks_ms().
+
+

C++ defination code:

+ +
uint64_t time_ms()
+
+
+

time_s

+

Get current time in s

+ + + + + + + + + + + + + + + + + +
itemdescription
returncurrent time in s, uint64_t type
attentionIf board have no RTC battery, when bootup and connect to network,
system will automatically sync time by NTP, will cause time() have big change,
e.g. before NTP: 10(s), after: 1718590639(s)
+
+

C++ defination code:

+ +
uint64_t time_s()
+
+
+

time_us

+

Get current time in us

+ + + + + + + + + + + + + + + + + +
itemdescription
returncurrent time in us, uint64_t type
attentionIf board have no RTC battery, when bootup and connect to network,
system will automatically sync time by NTP, will cause time() have big change,
e.g. before NTP: 10000000(us), after: 1718590639000000(s)
If you want to calculate time interval, please use ticks_us().
+
+

C++ defination code:

+ +
uint64_t time_us()
+
+
+

time_diff

+

Calculate time difference in s.

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
paramlast: last time
now: current time, can be -1 if use current time
returntime difference
attentionIf board have no RTC battery, when bootup and connect to network,
system will automatically sync time by NTP, will cause time() have big change, and lead to big value.
e.g. before NTP: 1(s), after: 1718590500(s)
If you want to calculate time interval, please use ticks_diff().
+
+

C++ defination code:

+ +
double time_diff(double last, double now = -1)
+
+
+

ticks_s

+

Get current time in s since bootup

+ + + + + + + + + + + + + +
itemdescription
returncurrent time in s, double type
+
+

C++ defination code:

+ +
double ticks_s()
+
+
+

ticks_ms

+

Get current time in ms since bootup

+ + + + + + + + + + + + + +
itemdescription
returncurrent time in ms, uint64_t type
+
+

C++ defination code:

+ +
uint64_t ticks_ms()
+
+
+

ticks_us

+

Get current time in us since bootup

+ + + + + + + + + + + + + +
itemdescription
returncurrent time in us, uint64_t type
+
+

C++ defination code:

+ +
uint64_t ticks_us()
+
+
+

ticks_diff

+

Calculate time difference in s.

+ + + + + + + + + + + + + + + + + +
itemdescription
paramlast: last time
now: current time, can be -1 if use current time
returntime difference
+
+

C++ defination code:

+ +
double ticks_diff(double last, double now = -1)
+
+
+

sleep

+

Sleep seconds

+ + + + + + + + + + + + + +
itemdescription
params: seconds, double type
+
+

C++ defination code:

+ +
void sleep(double s)
+
+
+

sleep_ms

+

Sleep milliseconds

+ + + + + + + + + + + + + +
itemdescription
paramms: milliseconds, uint64_t type
+
+

C++ defination code:

+ +
void sleep_ms(uint64_t ms)
+
+
+

sleep_us

+

Sleep microseconds

+ + + + + + + + + + + + + +
itemdescription
paramus: microseconds, uint64_t type
+
+

C++ defination code:

+ +
void sleep_us(uint64_t us)
+
+
+

fps

+

Calculate FPS since last call this method.\nAttention, this method is not multi thread safe, only call this method in one threads.\nIf you want to use in multi threads, please use time.FPS class.\nFPS is average value of recent n(buff_len) times, and you can call fps_set_buff_len(10) to change buffer length, default is 20.\nMultiple invoke this function will calculate fps between two invoke, and you can also call fps_start() fisrt to manually assign fps calulate start point.

+ + + + + + + + + + + + + +
itemdescription
returnfloat type, current fps since last call this method
+
+

C++ defination code:

+ +
float fps()
+
+
+

fps_start

+

Manually set fps calculation start point, then you can call fps() function to calculate fps between fps_start() and fps().

+
+

C++ defination code:

+ +
void fps_start()
+
+
+

fps_set_buff_len

+

Set fps method buffer length, by default the buffer length is 10.

+ + + + + + + + + + + + + +
itemdescription
paramlen: Buffer length to store recent fps value.
+
+

C++ defination code:

+ +
void fps_set_buff_len(int len)
+
+
+

now

+

Get current UTC date and time

+ + + + + + + + + + + + + +
itemdescription
returncurrent date and time, DateTime type
+
+

C++ defination code:

+ +
time::DateTime *now()
+
+
+

localtime

+

Get local time

+ + + + + + + + + + + + + +
itemdescription
returnlocal time, DateTime type
+
+

C++ defination code:

+ +
time::DateTime *localtime()
+
+
+

strptime

+

DateTime from string

+ + + + + + + + + + + + + + + + + +
itemdescription
paramstr: date time string
format: date time format
returnDateTime
+
+

C++ defination code:

+ +
time::DateTime *strptime(const std::string &str, const std::string &format)
+
+
+

gmtime

+

timestamp to DateTime(time zone is UTC (value 0))

+ + + + + + + + + + + + + + + + + +
itemdescription
paramtimestamp: double timestamp
returnDateTime
+
+

C++ defination code:

+ +
time::DateTime *gmtime(double timestamp)
+
+
+

timezone

+

Set or get timezone

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
paramtimezone: string type, can be empty and default to empty, if empty, only return crrent timezone, a "region/city" string, e.g. Asia/Shanghai, Etc/UTC, you can get all by list_timezones function.
returnstring type, return current timezone setting.
attentionwhen set new timezone, time setting not take effect in this process for some API, so you need to restart program.
+
+

C++ defination code:

+ +
std::string timezone(const std::string &timezone = "")
+
+
+

timezone (overload 1)

+

Set or get timezone

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
paramregion: string type, which region to set, can be empty means only get current, default empty.
city: string type, which city to set, can be empty means only get current, default empty.
returnlist type, return current timezone setting, first is region, second is city.
attentionwhen set new timezone, time setting not take effect in this process for some API, so you need to restart program.
+
+

C++ defination code:

+ +
std::vector<std::string> timezone2(const std::string &region = "", const std::string &city = "")
+
+
+

list_timezones

+

List all timezone info

+ + + + + + + + + + + + + +
itemdescription
returnA dict with key are regions, and value are region's cities.
+
+

C++ defination code:

+ +
std::map<std::string, std::vector<std::string>> list_timezones()
+
+
+

ntp_timetuple

+

Retrieves time from an NTP server\nThis function fetches the current time from the specified NTP server and port,\nreturning a tuple containing the time details.

+ + + + + + + + + + + + + + + + + +
itemdescription
paramhost: The hostname or IP address of the NTP server.
port: The port number of the NTP server. Use -1 for the default port 123.
retry: The number of retry attempts. Must be at least 1.
timeout_ms: The timeout duration in milliseconds. Must be non-negative.
returnA list of 6 elements: [year, month, day, hour, minute, second]
+
+

C++ defination code:

+ +
std::vector<int> ntp_timetuple(std::string host, int port=-1, uint8_t retry=3, int timeout_ms=0)
+
+
+

ntp_timetuple_with_config

+

Retrieves time from an NTP server using a configuration file\nThis function reads the configuration from a YAML file to fetch the current time\nfrom a list of specified NTP servers, returning a tuple containing the time details.

+ + + + + + + + + + + + + + + + + +
itemdescription
parampath: The path to the YAML configuration file, which should include:
- Config:
- retry: Number of retry attempts (must be at least 1)
- total_timeout_ms: Total timeout duration in milliseconds (must be non-negative)
- NtpServers:
- host: Hostname or IP address of the NTP server
- port: Port number of the NTP server (use 123 for default)
Example YAML configuration:
Config:
- retry: 3
- total_timeout_ms: 10000
NtpServers:
- host: "pool.ntp.org"
port: 123
- host: "time.nist.gov"
port: 123
- host: "time.windows.com"
port: 123
returnA list of 6 elements: [year, month, day, hour, minute, second]
+
+

C++ defination code:

+ +
std::vector<int> ntp_timetuple_with_config(std::string path)
+
+
+

ntp_sync_sys_time

+

Retrieves time from an NTP server and synchronizes the system time\nThis function fetches the current time from the specified NTP server and port,\nthen synchronizes the system time with the retrieved time.

+ + + + + + + + + + + + + + + + + +
itemdescription
paramhost: The hostname or IP address of the NTP server.
port: The port number of the NTP server. Use 123 for the default port.
retry: The number of retry attempts. Must be at least 1.
timeout_ms: The timeout duration in milliseconds. Must be non-negative.
returnA list of 6 elements: [year, month, day, hour, minute, second]
+
+

C++ defination code:

+ +
std::vector<int> ntp_sync_sys_time(std::string host, int port=-1, uint8_t retry=3, int timeout_ms=0)
+
+
+

ntp_sync_sys_time_with_config

+

Retrieves time from an NTP server using a configuration file and synchronizes the system time\nThis function reads the configuration from a YAML file to fetch the current time\nfrom a list of specified NTP servers, then synchronizes the system time with the retrieved time.

+ + + + + + + + + + + + + + + + + +
itemdescription
parampath: The path to the YAML configuration file, which should include:
- Config:
- retry: Number of retry attempts (must be at least 1)
- total_timeout_ms: Total timeout duration in milliseconds (must be non-negative)
- NtpServers:
- host: Hostname or IP address of the NTP server
- port: Port number of the NTP server (use 123 for default)
Example YAML configuration:
Config:
- retry: 3
- total_timeout_ms: 10000
NtpServers:
- host: "pool.ntp.org"
port: 123
- host: "time.nist.gov"
port: 123
- host: "time.windows.com"
port: 123
returnA vector of integers containing the time details: [year, month, day, hour, minute, second]
+
+

C++ defination code:

+ +
std::vector<int> ntp_sync_sys_time_with_config(std::string path)
+
+
+

Class

+

FPS

+

FPS class to use average filter to calculate FPS.

+
+

C++ defination code:

+ +
class FPS
+
+
+

FPS

+

FPS class constructor

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
parambuff_len: Average buffer length, default 20, that is, fps() function will return the average fps in recent buff_len times fps.
staticFalse
+
+

C++ defination code:

+ +
FPS(int buff_len = 20)
+
+
+

start

+

Manually set fps calculation start point, then you can call fps() function to calculate fps between start() and fps().

+ + + + + + + + + + + + + + + + + +
itemdescription
typefunc
staticFalse
+
+

C++ defination code:

+ +
void start()
+
+
+

fps

+

The same as end function.

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnfloat type, current fps since last call this method
staticFalse
+
+

C++ defination code:

+ +
float fps()
+
+
+

fps (overload 1)

+

Calculate FPS since last call this method.\nFPS is average value of recent n(buff_len) times, and you can call fps_set_buff_len(10) to change buffer length, default is 20.\nMultiple invoke this function will calculate fps between two invoke, and you can also call fps_start() fisrt to manually assign fps calulate start point.

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnfloat type, current fps since last call this method
staticFalse
+
+

C++ defination code:

+ +
inline float end()
+
+
+

set_buff_len

+

Set fps method buffer length, by default the buffer length is 10.

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramlen: Buffer length to store recent fps value.
staticFalse
+
+

C++ defination code:

+ +
void set_buff_len(int len)
+
+
+

DateTime

+

Date and time class

+
+

C++ defination code:

+ +
class DateTime
+
+
+

year

+

Year

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typevar
staticFalse
readonlyFalse
+
+

C++ defination code:

+ +
int year
+
+
+

month

+

Month, 1~12

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typevar
staticFalse
readonlyFalse
+
+

C++ defination code:

+ +
int month
+
+
+

day

+

Day

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typevar
staticFalse
readonlyFalse
+
+

C++ defination code:

+ +
int day
+
+
+

hour

+

Hour

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typevar
staticFalse
readonlyFalse
+
+

C++ defination code:

+ +
int hour
+
+
+

minute

+

Minute

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typevar
staticFalse
readonlyFalse
+
+

C++ defination code:

+ +
int minute
+
+
+

second

+

Second

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typevar
staticFalse
readonlyFalse
+
+

C++ defination code:

+ +
int second
+
+
+

microsecond

+

Microsecond

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typevar
staticFalse
readonlyFalse
+
+

C++ defination code:

+ +
int microsecond
+
+
+

yearday

+

Year day

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typevar
staticFalse
readonlyFalse
+
+

C++ defination code:

+ +
int yearday
+
+
+

weekday

+

Weekday, 0 is Monday, 6 is Sunday

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typevar
staticFalse
readonlyFalse
+
+

C++ defination code:

+ +
int weekday
+
+
+

zone

+

Time zone

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typevar
staticFalse
readonlyFalse
+
+

C++ defination code:

+ +
float zone
+
+
+

zone_name

+

Time zone name

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typevar
staticFalse
readonlyFalse
+
+

C++ defination code:

+ +
std::string zone_name
+
+
+

DateTime

+

Constructor

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramyear: year
month: month
day: day
hour: hour
minute: minute
second: second
microsecond: microsecond
yearday: year day
weekday: weekday
zone: time zone
staticFalse
+
+

C++ defination code:

+ +
DateTime(int year = 0, int month = 0, int day = 0, int hour = 0, int minute = 0, int second = 0, int microsecond = 0, int yearday = 0, int weekday = 0, int zone = 0)
+
+
+

strftime

+

Convert to string

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returndate time string
staticFalse
+
+

C++ defination code:

+ +
std::string strftime(const std::string &format)
+
+
+

timestamp

+

Convert to float timestamp

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnfloat timestamp
staticFalse
+
+

C++ defination code:

+ +
double timestamp()
+
+
+ + +
+
+
+ + +
+
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixcdk/api/maix/touchscreen.html b/maixcdk/api/maix/touchscreen.html new file mode 100644 index 00000000..7d37c279 --- /dev/null +++ b/maixcdk/api/maix/touchscreen.html @@ -0,0 +1,647 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + maix::touchscreen - MaixCDK + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

maix::touchscreen

+ +
+
+
    + +
+
+
+
+ + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

maix.touchscreen module

+
+

This is maix::touchscreen module of MaixCDK.
+All of these elements are in namespace maix::touchscreen.

+

For MaixCDK developer: DO NOT edit this doc file manually, this doc is auto generated!

+
+

Module

+

No module

+

Enum

+

Variable

+

Function

+

Class

+

TouchScreen

+

TouchScreen class

+
+

C++ defination code:

+ +
class TouchScreen
+
+
+

TouchScreen

+

Construct a new TouchScreen object

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramdevice: touchscreen device path, you can get devices by list_devices method, by default(value is NULL(None in MaixPy)) means the first device
open: If true, touchscreen will automatically call open() after creation. default is true.
staticFalse
+
+

C++ defination code:

+ +
TouchScreen(const std::string &device = "", bool open = true)
+
+
+

open

+

open touchscreen device

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnerror code, err::ERR_NONE means success, others means failed
staticFalse
+
+

C++ defination code:

+ +
err::Err open()
+
+
+

close

+

close touchscreen device

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnerror code, err::ERR_NONE means success, others means failed
staticFalse
+
+

C++ defination code:

+ +
err::Err close()
+
+
+

read

+

read touchscreen device.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
attentionThis method will discard same event in buffer, that is:
if too many move event in buffer when call this method, it will only return the last one,
and if read pressed or released event, it will return immediately.
paramx: x coordinate
y: y coordinate
pressed: pressed state
returnerror code, err::ERR_NONE means success, others means failed, if no event return err::ERR_NOT_READY
staticFalse
+
+

C++ defination code:

+ +
err::Err read(int &x, int &y, bool &pressed)
+
+
+

read (overload 1)

+

read touchscreen device

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
attentionThis method will discard same event in buffer, that is:
if too many move event in buffer when call this method, it will only return the last one,
and if read pressed or released event, it will return immediately.
returnReturns a list include x, y, pressed state
staticFalse
+
+

C++ defination code:

+ +
std::vector<int> read()
+
+
+

read (overload 2)

+

read touchscreen device

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
attentionThis method will return immediately if have event, so it's better to use available() to check if have more event in buffer,
or too much event in buffer when your program call this read() interval is too long will make your program slow.
paramx: x coordinate
y: y coordinate
pressed: pressed state
returnerror code, err::ERR_NONE means success, others means failed, if no event return err::ERR_NOT_READY
staticFalse
+
+

C++ defination code:

+ +
err::Err read0(int &x, int &y, bool &pressed)
+
+
+

read (overload 3)

+

read touchscreen device

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
attentionThis method will return immediately if have event, so it's better to use available() to check if have more event in buffer,
or too much event in buffer when your program call this read() interval is too long will make your program slow.
returnReturns a list include x, y, pressed state
staticFalse
+
+

C++ defination code:

+ +
std::vector<int> read0()
+
+
+

available

+

If we need to read from touchscreen, for event driven touchscreen means have event or not

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramtimeout: -1 means block, 0 means no block, >0 means timeout, default is 0, unit is ms.
returntrue if need to read(have event), false if not
staticFalse
+
+

C++ defination code:

+ +
bool available(int timeout = 0)
+
+
+

is_opened

+

Check if touchscreen is opened

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returntrue if touchscreen is opened, false if not
staticFalse
+
+

C++ defination code:

+ +
bool is_opened()
+
+
+ + +
+
+
+ + +
+
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixcdk/api/maix/tracker.html b/maixcdk/api/maix/tracker.html new file mode 100644 index 00000000..e575ab02 --- /dev/null +++ b/maixcdk/api/maix/tracker.html @@ -0,0 +1,863 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + maix::tracker - MaixCDK + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

maix::tracker

+ +
+
+
    + +
+
+
+
+ + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

maix.tracker module

+
+

This is maix::tracker module of MaixCDK.
+All of these elements are in namespace maix::tracker.

+

For MaixCDK developer: DO NOT edit this doc file manually, this doc is auto generated!

+
+

Module

+

No module

+

Enum

+

Variable

+

Function

+

Class

+

Object

+

tracker.Object class

+
+

C++ defination code:

+ +
class Object
+
+
+

Object

+

tracker.Object class constructor

+ + + + + + + + + + + + + + + + + +
itemdescription
typefunc
staticFalse
+
+

C++ defination code:

+ +
Object(const int &x, const int &y, const int &w, const int &h, const int &class_id, const float &score)
+
+
+

x

+

position x attribute.

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typevar
staticFalse
readonlyFalse
+
+

C++ defination code:

+ +
int x
+
+
+

y

+

position y attribute.

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typevar
staticFalse
readonlyFalse
+
+

C++ defination code:

+ +
int y
+
+
+

w

+

position rectangle width.

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typevar
staticFalse
readonlyFalse
+
+

C++ defination code:

+ +
int w
+
+
+

h

+

position rectangle height.

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typevar
staticFalse
readonlyFalse
+
+

C++ defination code:

+ +
int h
+
+
+

class_id

+

object class id, int type.

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typevar
staticFalse
readonlyFalse
+
+

C++ defination code:

+ +
int class_id
+
+
+

score

+

object score(prob).

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typevar
staticFalse
readonlyFalse
+
+

C++ defination code:

+ +
float score
+
+
+

Track

+

tracker.Track class

+
+

C++ defination code:

+ +
class Track
+
+
+

Track

+

tracker.Track class constructor

+ + + + + + + + + + + + + + + + + +
itemdescription
typefunc
staticFalse
+
+

C++ defination code:

+ +
Track(const size_t &id, const float &score, const bool &lost, const size_t &start_frame_id, const size_t &frame_id)
+
+
+

Track (overload 1)

+

tracker.Track class constructor

+ + + + + + + + + + + + + + + + + +
itemdescription
typefunc
staticFalse
+
+

C++ defination code:

+ +
Track()
+
+
+

id

+

track id.

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typevar
staticFalse
readonlyFalse
+
+

C++ defination code:

+ +
size_t id
+
+
+

score

+

track score(prob).

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typevar
staticFalse
readonlyFalse
+
+

C++ defination code:

+ +
float score
+
+
+

lost

+

whether this track lost.

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typevar
staticFalse
readonlyFalse
+
+

C++ defination code:

+ +
bool lost
+
+
+

start_frame_id

+

track start frame id.

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typevar
staticFalse
readonlyFalse
+
+

C++ defination code:

+ +
size_t start_frame_id
+
+
+

frame_id

+

track current frame id.

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typevar
staticFalse
readonlyFalse
+
+

C++ defination code:

+ +
size_t frame_id
+
+
+

history

+

track position history, the last one is latest position.

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typevar
staticFalse
readonlyFalse
+
+

C++ defination code:

+ +
std::deque<tracker::Object> history
+
+
+

ByteTracker

+

tracker.ByteTracker class

+
+

C++ defination code:

+ +
class ByteTracker
+
+
+

ByteTracker

+

tracker.ByteTracker class constructor

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
parammax_lost_buff_num: the frames for keep lost tracks.
track_thresh: tracking confidence threshold.
high_thresh: threshold to add to new track.
match_thresh: matching threshold for tracking, e.g. one object in two frame iou < match_thresh we think they are the same obj.
max_history: max tack's position history length.
staticFalse
+
+

C++ defination code:

+ +
ByteTracker(const int &max_lost_buff_num = 60,
+                    const float &track_thresh = 0.5,
+                    const float &high_thresh = 0.6,
+                    const float &match_thresh = 0.8,
+                    const int &max_history = 20)
+
+
+

update

+

update tracks according to current detected objects.

+ + + + + + + + + + + + + + + + + +
itemdescription
typefunc
staticFalse
+
+

C++ defination code:

+ +
std::vector<tracker::Track> update(const std::vector<tracker::Object> &objs)
+
+
+ + +
+
+
+ + +
+
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixcdk/api/maix/util.html b/maixcdk/api/maix/util.html new file mode 100644 index 00000000..b58aa175 --- /dev/null +++ b/maixcdk/api/maix/util.html @@ -0,0 +1,381 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + maix::util - MaixCDK + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

maix::util

+ +
+
+
    + +
+
+
+
+ + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

maix.util module

+
+

This is maix::util module of MaixCDK.
+All of these elements are in namespace maix::util.

+

For MaixCDK developer: DO NOT edit this doc file manually, this doc is auto generated!

+
+

Module

+

No module

+

Enum

+

Variable

+

Function

+

disable_kernel_debug

+

disable the kernel debug

+
+

C++ defination code:

+ +
void disable_kernel_debug()
+
+
+

enable_kernel_debug

+

disable the kernel debug

+
+

C++ defination code:

+ +
void enable_kernel_debug()
+
+
+

register_exit_function

+

register exit function

+
+

C++ defination code:

+ +
void register_exit_function(void (*process)(void))
+
+
+

do_exit_function

+

exec all of exit function

+
+

C++ defination code:

+ +
void do_exit_function()
+
+
+

register_atexit

+

Registering default processes that need to be executed on exit

+
+

C++ defination code:

+ +
void register_atexit()
+
+
+

Class

+ + +
+
+
+ + +
+
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixcdk/api/maix/uvc.html b/maixcdk/api/maix/uvc.html new file mode 100644 index 00000000..461a8bb3 --- /dev/null +++ b/maixcdk/api/maix/uvc.html @@ -0,0 +1,459 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + maix::uvc - MaixCDK + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

maix::uvc

+ +
+
+
    + +
+
+
+
+ + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

maix.uvc module

+
+

This is maix::uvc module of MaixCDK.
+All of these elements are in namespace maix::uvc.

+

For MaixCDK developer: DO NOT edit this doc file manually, this doc is auto generated!

+
+

Module

+

No module

+

Enum

+

Variable

+

Function

+

get_supported_formats

+

get_supported_formats function

+
+

C++ defination code:

+ +
std::vector<std::string> get_supported_formats()
+
+
+

Class

+

UvcStreamer

+

UvcStreamer class

+
+

C++ defination code:

+ +
class UvcStreamer
+
+
+

UvcStreamer

+

Construct a new jpeg streamer object

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
noteYou can get the picture stream through http://host:port/stream, you can also get it through http://ip:port, and you can add personal style through set_html() at this time
paramhost: http host
port: http port, default is 8000
client_number: the max number of client
staticFalse
+
+

C++ defination code:

+ +
UvcStreamer(unsigned  index=0)
+
+
+

show

+

Write data to uvc

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramimg: image object
returnerror code, err::ERR_NONE means success, others means failed
staticFalse
+
+

C++ defination code:

+ +
err::Err show(image::Image *img)
+
+
+

use_mjpg

+

use mjpg on uvc

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramb: using mjpg: 0 for NOT, others to use
returnvoid
staticFalse
+
+

C++ defination code:

+ +
void use_mjpg(uint32_t b=1)
+
+
+ + +
+
+
+ + +
+
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixcdk/api/maix/video.html b/maixcdk/api/maix/video.html new file mode 100644 index 00000000..6909f0ec --- /dev/null +++ b/maixcdk/api/maix/video.html @@ -0,0 +1,3915 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + maix::video - MaixCDK + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

maix::video

+ +
+
+
    + +
+
+
+
+ + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

maix.video module

+
+

This is maix::video module of MaixCDK.
+All of these elements are in namespace maix::video.

+

For MaixCDK developer: DO NOT edit this doc file manually, this doc is auto generated!

+
+

Module

+

No module

+

Enum

+

VideoType

+

Video type

+ + + + + + + + + + + + + +
itemdescribe
valuesVIDEO_NONE: format invalid
VIDEO_ENC_H265_CBR: Deprecated
VIDEO_ENC_MP4_CBR: Deprecated
VIDEO_DEC_H265_CBR: Deprecated
VIDEO_DEC_MP4_CBR: Deprecated
VIDEO_H264_CBR: Deprecated
VIDEO_H265_CBR: Deprecated
VIDEO_H264_CBR_MP4: Deprecated
VIDEO_H265_CBR_MP4: Deprecated
VIDEO_H264:
VIDEO_H264_MP4:
VIDEO_H264_FLV:
VIDEO_H265:
VIDEO_H265_MP4:
+
+

C++ defination code:

+ +
enum VideoType
+    {
+        VIDEO_NONE = 0,  // format invalid
+        VIDEO_ENC_H265_CBR,     // Deprecated
+        VIDEO_ENC_MP4_CBR,      // Deprecated
+        VIDEO_DEC_H265_CBR,     // Deprecated
+        VIDEO_DEC_MP4_CBR,      // Deprecated
+        VIDEO_H264_CBR,         // Deprecated
+        VIDEO_H265_CBR,         // Deprecated
+        VIDEO_H264_CBR_MP4,     // Deprecated
+        VIDEO_H265_CBR_MP4,     // Deprecated
+
+        VIDEO_H264,
+        VIDEO_H264_MP4,
+        VIDEO_H264_FLV,
+        VIDEO_H265,
+        VIDEO_H265_MP4,
+    }
+
+
+

MediaType

+

Video type

+ + + + + + + + + + + + + +
itemdescribe
valuesMEDIA_TYPE_UNKNOWN: Represents an unknown media type, which is usually treated as AVMEDIA_TYPE_DATA.
MEDIA_TYPE_VIDEO: Represents a video stream, such as video content encoded in H.264, MPEG-4, etc.
MEDIA_TYPE_AUDIO: Represents an audio stream, such as audio content encoded in AAC, MP3, etc.
MEDIA_TYPE_DATA: Represents opaque data streams that are usually continuous. This type of stream is not necessarily audio or video and may be used for other data purposes.
MEDIA_TYPE_SUBTITLE: Represents a subtitle stream used for displaying text or subtitle information, such as SRT, ASS, etc.
MEDIA_TYPE_ATTACHMENT: Represents attachment streams that are usually sparse. Attachment streams can include images, fonts, or other files that need to be bundled with the media.
MEDIA_TYPE_NB: Represents the number of media types (count) and indicates the total number of media types defined in this enumeration. It is not a media type itself but is used for counting enumeration items.
+
+

C++ defination code:

+ +
enum MediaType
+    {
+        MEDIA_TYPE_UNKNOWN = -1,    // Represents an unknown media type, which is usually treated as AVMEDIA_TYPE_DATA.
+        MEDIA_TYPE_VIDEO,           // Represents a video stream, such as video content encoded in H.264, MPEG-4, etc.
+        MEDIA_TYPE_AUDIO,           // Represents an audio stream, such as audio content encoded in AAC, MP3, etc.
+        MEDIA_TYPE_DATA,            // Represents opaque data streams that are usually continuous. This type of stream is not necessarily audio or video and may be used for other data purposes.
+        MEDIA_TYPE_SUBTITLE,        // Represents a subtitle stream used for displaying text or subtitle information, such as SRT, ASS, etc.
+        MEDIA_TYPE_ATTACHMENT,      // Represents attachment streams that are usually sparse. Attachment streams can include images, fonts, or other files that need to be bundled with the media.
+        MEDIA_TYPE_NB               // Represents the number of media types (count) and indicates the total number of media types defined in this enumeration. It is not a media type itself but is used for counting enumeration items.
+    }
+
+
+

Variable

+

Function

+

timebase_to_us

+

Convert a value in timebase units to microseconds. value * 1000000 / (timebase[1] / timebase[0])

+ + + + + + + + + + + + + + + + + +
itemdescription
paramtimebse: Time base, used as the unit for calculating playback time. It must be an array containing two parameters,
in the format [num, den], where the first parameter is the numerator of the time base, and the second parameter is the denominator of the time base.
value: Input value
returnReturn the result in microseconds.
+
+

C++ defination code:

+ +
double timebase_to_us(std::vector<int> timebase, uint64_t value)
+
+
+

timebase_to_ms

+

Convert a value in timebase units to milliseconds.

+ + + + + + + + + + + + + + + + + +
itemdescription
paramtimebse: Time base, used as the unit for calculating playback time. It must be an array containing two parameters,
in the format [num, den], where the first parameter is the numerator of the time base, and the second parameter is the denominator of the time base.
value: Input value
returnReturn the result in milliseconds.
+
+

C++ defination code:

+ +
double timebase_to_ms(std::vector<int> timebase, uint64_t value)
+
+
+

Class

+

Context

+

Context class

+
+

C++ defination code:

+ +
class Context
+
+
+

Context

+

Construct a new Context object

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
parammedia_type: enable capture, if true, you can use capture() function to get an image object
timebase: Time base, used as the unit for calculating playback time. It must be an array containing two parameters,
in the format [num, den], where the first parameter is the numerator of the time base, and the second parameter is the denominator of the time base.
staticFalse
+
+

C++ defination code:

+ +
Context(video::MediaType media_type, std::vector<int> timebase)
+
+
+

Context (overload 1)

+

Construct a new Context object

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
parammedia_type: enable capture, if true, you can use capture() function to get an image object
timebase: Time base, used as the unit for calculating playback time. It must be an array containing two parameters,
in the format [num, den], where the first parameter is the numerator of the time base, and the second parameter is the denominator of the time base.
sample_rate: sampling rate of audio
format: audio format
channels: number of audio channels
staticFalse
+
+

C++ defination code:

+ +
Context(video::MediaType media_type, std::vector<int> timebase, int sample_rate, audio::Format format, int channels)
+
+
+

audio_sample_rate

+

Get sample rate of audio (only valid in the context of audio)

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnsample rate
staticFalse
+
+

C++ defination code:

+ +
int audio_sample_rate()
+
+
+

audio_sample_rate (overload 1)

+

Get sample rate of audio (only valid in the context of audio)

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnsample rate
staticFalse
+
+

C++ defination code:

+ +
int audio_sample_rate()
+
+
+

audio_channels

+

Get channels of audio (only valid in the context of audio)

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnchannels
staticFalse
+
+

C++ defination code:

+ +
int audio_channels()
+
+
+

audio_channels (overload 1)

+

Get channels of audio (only valid in the context of audio)

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnchannels
staticFalse
+
+

C++ defination code:

+ +
int audio_channels()
+
+
+

audio_format

+

Get format of audio (only valid in the context of audio)

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnaudio format. @see audio::Format
staticFalse
+
+

C++ defination code:

+ +
audio::Format audio_format()
+
+
+

audio_format (overload 1)

+

Get format of audio (only valid in the context of audio)

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnaudio format. @see audio::Format
staticFalse
+
+

C++ defination code:

+ +
audio::Format audio_format()
+
+
+

set_pcm

+

Set pcm data (only valid in the context of audio)

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramduration: Duration of the current pcm. unit: timebase
pts: The start time of this pcm playback. If it is 0, it means this parameter is not supported. unit: timebase
returnerr::Err
staticFalse
+
+

C++ defination code:

+ +
err::Err set_pcm(maix::Bytes *data, int duration = 0, uint64_t pts = 0, bool copy = true)
+
+
+

get_pcm

+

Get pcm data (only valid in the context of audio)

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
attentionNote that if you call this interface, you are responsible for releasing the memory of the data, and this interface cannot be called again.
returnBytes
staticFalse
+
+

C++ defination code:

+ +
Bytes *get_pcm()
+
+
+

set_image

+

Set image info

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramimage: image data
duration: Duration of the current image. unit: timebase
pts: The start time of this image playback. If it is 0, it means this parameter is not supported. unit: timebase
last_pts: The start time of the previous image playback. It can be used to ensure the playback order. If it is 0, it means this parameter is not supported. unit: timebase
staticFalse
+
+

C++ defination code:

+ +
void set_image(image::Image *image, int duration = 0, uint64_t pts = 0, uint64_t last_pts = 0)
+
+
+

set_raw_data

+

Set private data

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramdata: private raw data
data_size: private raw data size
duration: Duration of the current image. unit: timebase
pts: The start time of this image playback. If it is 0, it means this parameter is not supported. unit: timebase
last_pts: The start time of the previous image playback. It can be used to ensure the playback order. If it is 0, it means this parameter is not supported. unit: timebase
staticFalse
+
+

C++ defination code:

+ +
void set_raw_data(void *data, size_t data_size, int duration = 0, uint64_t pts = 0, uint64_t last_pts = 0, bool copy = false)
+
+
+

get_raw_data

+

Get private data

+ + + + + + + + + + + + + + + + + +
itemdescription
typefunc
staticFalse
+
+

C++ defination code:

+ +
void *get_raw_data()
+
+
+

image

+

Retrieve the image data to be played.

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
attentionNote that if you call this interface, you are responsible for releasing the memory of the image, and this interface cannot be called again.
staticFalse
+
+

C++ defination code:

+ +
image::Image *image()
+
+
+

media_type

+

Get the media type to determine whether it is video, audio, or another media type.

+ + + + + + + + + + + + + + + + + +
itemdescription
typefunc
staticFalse
+
+

C++ defination code:

+ +
video::MediaType media_type()
+
+
+

pts

+

Get the start time of the current playback., in units of time base.

+ + + + + + + + + + + + + + + + + +
itemdescription
typefunc
staticFalse
+
+

C++ defination code:

+ +
uint64_t pts()
+
+
+

last_pts

+

Get the start time of the previous playback, in units of time base.

+ + + + + + + + + + + + + + + + + +
itemdescription
typefunc
staticFalse
+
+

C++ defination code:

+ +
uint64_t last_pts()
+
+
+

timebase

+

Get the time base.

+ + + + + + + + + + + + + + + + + +
itemdescription
typefunc
staticFalse
+
+

C++ defination code:

+ +
std::vector<int> timebase()
+
+
+

duration

+

Duration of the current frame. unit: timebase

+ + + + + + + + + + + + + + + + + +
itemdescription
typefunc
staticFalse
+
+

C++ defination code:

+ +
int duration()
+
+
+

duration_us

+

Duration of the current frame. unit: us

+ + + + + + + + + + + + + + + + + +
itemdescription
typefunc
staticFalse
+
+

C++ defination code:

+ +
uint64_t duration_us()
+
+
+

Frame

+

Frame class

+
+

C++ defination code:

+ +
class Frame
+
+
+

Frame

+

Frame object

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramdata: src data pointer, use pointers directly without copying.
Note: this object will try to free this memory
len: data len
pts: presentation time stamp. unit: time_base
dts: decoding time stamp. unit: time_base
duration: packet display time. unit: time_base (not used)
auto_detele: if true, will delete data when destruct. When copy is true, this arg will be ignore.
copy: data will be copy to new buffer if true, if false, will use data directly,
default true to ensure memory safety.
staticFalse
+
+

C++ defination code:

+ +
Frame(uint8_t *data, int len, uint64_t pts = -1, uint64_t dts = -1, int64_t duration = 0, bool auto_detele = false, bool copy = false)
+
+
+

Frame (overload 1)

+

Frame number (pair of numerator and denominator).

+ + + + + + + + + + + + + + + + + +
itemdescription
typefunc
staticFalse
+
+

C++ defination code:

+ +
Frame()
+
+
+

get

+

Get raw data of packet

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramdata: data pointer
len: data length pointer
returnraw data
staticFalse
+
+

C++ defination code:

+ +
err::Err get(void **data, int *len)
+
+
+

to_bytes

+

Get raw data of packet

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramcopy: if true, will alloc memory and copy data to new buffer
returnraw data
staticFalse
+
+

C++ defination code:

+ +
Bytes *to_bytes(bool copy = false)
+
+
+

size

+

Get raw data size of packet

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnsize of raw data
staticFalse
+
+

C++ defination code:

+ +
size_t size()
+
+
+

is_valid

+

Check packet is valid

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returntrue, packet is valid; false, packet is invalid
staticFalse
+
+

C++ defination code:

+ +
bool is_valid()
+
+
+

set_pts

+

Set pts

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
parampts: presentation time stamp. unit: time_base
staticFalse
+
+

C++ defination code:

+ +
void set_pts(uint64_t pts)
+
+
+

set_dts

+

Set dts

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramdts: decoding time stamp. unit: time_base
staticFalse
+
+

C++ defination code:

+ +
void set_dts(uint64_t dts)
+
+
+

set_duration

+

Set duration

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramduration: packet display time. unit: time_base
staticFalse
+
+

C++ defination code:

+ +
void set_duration(uint64_t duration)
+
+
+

get_pts

+

Set pts

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
parampts: presentation time stamp. unit: time_base
returnpts value
staticFalse
+
+

C++ defination code:

+ +
uint64_t get_pts()
+
+
+

get_dts

+

Set dts

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramdts: decoding time stamp. unit: time_base
returndts value
staticFalse
+
+

C++ defination code:

+ +
uint64_t get_dts()
+
+
+

get_duration

+

Get duration

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnduration value
staticFalse
+
+

C++ defination code:

+ +
uint64_t get_duration()
+
+
+

type

+

Get frame type

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnvideo type. @see video::VideoType
staticFalse
+
+

C++ defination code:

+ +
video::VideoType type()
+
+
+

Packet

+

Packet class

+
+

C++ defination code:

+ +
class Packet
+
+
+

Packet

+

Packet number (pair of numerator and denominator).

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramdata: src data pointer, use pointers directly without copying.
Note: this object will try to free this memory
len: data len
pts: presentation time stamp. unit: time_base
dts: decoding time stamp. unit: time_base
duration: packet display time. unit: time_base
staticFalse
+
+

C++ defination code:

+ +
Packet(uint8_t *data, int len, uint64_t pts = -1, uint64_t dts = -1, int64_t duration = 0)
+
+
+

Packet (overload 1)

+

Packet number (pair of numerator and denominator).

+ + + + + + + + + + + + + + + + + +
itemdescription
typefunc
staticFalse
+
+

C++ defination code:

+ +
Packet()
+
+
+

get

+

Get raw data of packet

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnraw data
staticFalse
+
+

C++ defination code:

+ +
std::vector<uint8_t> get()
+
+
+

data

+

Get raw data of packet

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnraw data
staticFalse
+
+

C++ defination code:

+ +
uint8_t *data()
+
+
+

data_size

+

Get raw data size of packet

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnsize of raw data
staticFalse
+
+

C++ defination code:

+ +
size_t data_size()
+
+
+

is_valid

+

Check packet is valid

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returntrue, packet is valid; false, packet is invalid
staticFalse
+
+

C++ defination code:

+ +
bool is_valid()
+
+
+

set_pts

+

Set pts

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
parampts: presentation time stamp. unit: time_base
returntrue, packet is valid; false, packet is invalid
staticFalse
+
+

C++ defination code:

+ +
void set_pts(uint64_t pts)
+
+
+

set_dts

+

Set dts

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramdts: decoding time stamp. unit: time_base
returntrue, packet is valid; false, packet is invalid
staticFalse
+
+

C++ defination code:

+ +
void set_dts(uint64_t dts)
+
+
+

set_duration

+

Set duration

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramduration: packet display time. unit: time_base
returntrue, packet is valid; false, packet is invalid
staticFalse
+
+

C++ defination code:

+ +
void set_duration(uint64_t duration)
+
+
+

Encoder

+

Encode class

+
+

C++ defination code:

+ +
class Encoder
+
+
+

Encoder

+

Construct a new Video object

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramwidth: picture width. this value may be set automatically. default is 2560.
height: picture height. this value may be set automatically. default is 1440.
format: picture format. default is image::Format::FMT_YVU420SP. @see image::Format
type: video encode/decode type. default is ENC_H265_CBR. @see EncodeType
framerate: frame rate. framerate default is 30, means 30 frames per second
for video. 1/time_base is not the average frame rate if the frame rate is not constant.
gop: for h264/h265 encoding, the interval between two I-frames, default is 50.
bitrate: for h264/h265 encoding, used to limit the bandwidth used by compressed data, default is 3000kbps
time_base: frame time base. time_base default is 1000, means 1/1000 ms (not used)
capture: enable capture, if true, you can use capture() function to get an image object
block: This parameter determines whether encoding should block until it is complete.
If set to true, it will wait until encoding is finished before returning.
If set to false, it will return the current encoding result on the next call.
staticFalse
+
+

C++ defination code:

+ +
Encoder(std::string path = "", int width = 2560, int height = 1440, image::Format format = image::Format::FMT_YVU420SP, video::VideoType type = video::VideoType::VIDEO_H264, int framerate = 30, int gop = 50, int bitrate = 3000 * 1000, int time_base = 1000, bool capture = false, bool block = true)
+
+
+

bind_camera

+

Bind camera

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramcamera: camera object
returnerror code, err::ERR_NONE means success, others means failed
staticFalse
+
+

C++ defination code:

+ +
err::Err bind_camera(camera::Camera *camera)
+
+
+

encode

+

Encode image.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramimg: the image will be encode.
if the img is NULL, this function will try to get image from camera, you must use bind_camera() function to bind the camera.
pcm: the pcm data will be encode.
returnencode result
staticFalse
+
+

C++ defination code:

+ +
video::Frame *encode(image::Image *img = maix::video::Encoder::NoneImage, Bytes *pcm = maix::video::Encoder::NoneBytes)
+
+
+

capture

+

Capture image

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
attentionEach time encode is called, the last captured image will be released.
returnerror code
staticFalse
+
+

C++ defination code:

+ +
image::Image *capture()
+
+
+

width

+

Get video width

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnvideo width
staticFalse
+
+

C++ defination code:

+ +
int width()
+
+
+

height

+

Get video height

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnvideo height
staticFalse
+
+

C++ defination code:

+ +
int height()
+
+
+

format

+

Get video format

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnvideo format
staticFalse
+
+

C++ defination code:

+ +
image::Format format()
+
+
+

type

+

Get video encode type

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnVideoType
staticFalse
+
+

C++ defination code:

+ +
video::VideoType type()
+
+
+

framerate

+

Get video encode framerate

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnframe rate
staticFalse
+
+

C++ defination code:

+ +
int framerate()
+
+
+

gop

+

Get video encode gop

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returngop value
staticFalse
+
+

C++ defination code:

+ +
int gop()
+
+
+

bitrate

+

Get video encode bitrate

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnbitrate value
staticFalse
+
+

C++ defination code:

+ +
int bitrate()
+
+
+

time_base

+

Get video encode time base

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returntime base value
staticFalse
+
+

C++ defination code:

+ +
int time_base()
+
+
+

get_pts

+

Get current pts, unit: time_base\nNote: The current default is to assume that there is no B-frame implementation, so pts and bts are always the same

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramtime_ms: start time from the first frame. unit: ms
returntime base value
staticFalse
+
+

C++ defination code:

+ +
uint64_t get_pts(uint64_t time_ms)
+
+
+

get_dts

+

Get current dts, unit: time_base\nNote: The current default is to assume that there is no B-frame implementation, so pts and bts are always the same

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramtime_ms: start time from the first frame. unit: ms
returntime base value
staticFalse
+
+

C++ defination code:

+ +
uint64_t get_dts(uint64_t time_ms)
+
+
+

Decoder

+

Decoder class

+
+

C++ defination code:

+ +
class Decoder
+
+
+

Decoder

+

Construct a new decoder object

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
parampath: Path to the file to be decoded. Supports files with .264 and .mp4 extensions. Note that only mp4 files containing h.264 streams are supported.
format: Decoded output format, currently only support YUV420SP
staticFalse
+
+

C++ defination code:

+ +
Decoder(std::string path, image::Format format = image::Format::FMT_YVU420SP)
+
+
+

decode_video

+

Decode the video stream, returning the image of the next frame each time.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramblock: Whether it blocks or not. If true, it will wait for the decoding to complete and return the current frame.
If false, it will return the result of the previous frame's decoding. If the previous frame's decoding result is empty,
it will return an unknown Context, and you can use the media_type method of the Context to determine if a valid result exists.
default is true.
returnDecoded context information.
staticFalse
+
+

C++ defination code:

+ +
video::Context * decode_video(bool block = true)
+
+
+

decode_audio

+

Decode the video stream, returning the image of the next frame each time.

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnDecoded context information.
staticFalse
+
+

C++ defination code:

+ +
video::Context * decode_audio()
+
+
+

decode

+

Decode the video and audio stream

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramblock: Whether it blocks or not. If true, it will wait for the decoding to complete and return the current frame.
If false, it will return the result of the previous frame's decoding. If the previous frame's decoding result is empty,
it will return an unknown Context, and you can use the media_type method of the Context to determine if a valid result exists.
default is true.
returnDecoded context information.
staticFalse
+
+

C++ defination code:

+ +
video::Context * decode(bool block = true)
+
+
+

unpack

+

Unpacking the video and audio stream

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnUnpacking context information.
staticFalse
+
+

C++ defination code:

+ +
video::Context * unpack()
+
+
+

width

+

Get the video width

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnvideo width
staticFalse
+
+

C++ defination code:

+ +
int width()
+
+
+

height

+

Get the video height

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnvideo height
staticFalse
+
+

C++ defination code:

+ +
int height()
+
+
+

bitrate

+

Get the video bitrate

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnbitrate value
staticFalse
+
+

C++ defination code:

+ +
int bitrate()
+
+
+

fps

+

Get the video fps

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnfps value
staticFalse
+
+

C++ defination code:

+ +
int fps()
+
+
+

seek

+

Seek to the required playback position

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramtime: timestamp value, unit: s
returnreturn the current position, unit: s
staticFalse
+
+

C++ defination code:

+ +
double seek(double time = -1)
+
+
+

duration

+

Get the maximum duration of the video. If it returns 0, it means it cannot be predicted.

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnduration value, unit: s
staticFalse
+
+

C++ defination code:

+ +
double duration()
+
+
+

timebase

+

Get the time base.

+ + + + + + + + + + + + + + + + + +
itemdescription
typefunc
staticFalse
+
+

C++ defination code:

+ +
std::vector<int> timebase()
+
+
+

has_audio

+

If find audio data, return true

+ + + + + + + + + + + + + + + + + +
itemdescription
typefunc
staticFalse
+
+

C++ defination code:

+ +
bool has_audio()
+
+
+

has_video

+

If find video data, return true

+ + + + + + + + + + + + + + + + + +
itemdescription
typefunc
staticFalse
+
+

C++ defination code:

+ +
bool has_video()
+
+
+

Video

+

Video class

+
+

C++ defination code:

+ +
class Video
+
+
+

Video

+

Construct a new Video object

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
parampath: video path. the path determines the location where you load or save the file, if path is none, the video module will not save or load file.
xxx.h265 means video format is H265, xxx.mp4 means video format is MP4
width: picture width. this value may be set automatically. default is 2560.
height: picture height. this value may be set automatically. default is 1440.
format: picture pixel format. this value may be set automatically. default is FMT_YVU420SP.
time_base: frame time base. time_base default is 30, means 1/30 ms
framerate: frame rate. framerate default is 30, means 30 frames per second
for video. 1/time_base is not the average frame rate if the frame rate is not constant.
capture: enable capture, if true, you can use capture() function to get an image object
open: If true, video will automatically call open() after creation. default is true.
staticFalse
+
+

C++ defination code:

+ +
Video(std::string path = std::string(), int width = 2560, int height = 1440, image::Format format = image::Format::FMT_YVU420SP, int time_base = 30, int framerate = 30, bool capture = false, bool open = true)
+
+
+

open

+

Open video and run

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
parampath: video path. the path determines the location where you load or save the file, if path is none, the video module will not save or load file.
xxx.h265 means video format is H265, xxx.mp4 means video format is MP4
fps: video fps
returnerror code, err::ERR_NONE means success, others means failed
staticFalse
+
+

C++ defination code:

+ +
err::Err open(std::string path = std::string(), double fps = 30.0)
+
+
+

close

+

Close video

+ + + + + + + + + + + + + + + + + +
itemdescription
typefunc
staticFalse
+
+

C++ defination code:

+ +
void close()
+
+
+

bind_camera

+

Bind camera

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramcamera: camera object
returnerror code, err::ERR_NONE means success, others means failed
staticFalse
+
+

C++ defination code:

+ +
err::Err bind_camera(camera::Camera *camera)
+
+
+

encode

+

Encode image.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramimg: the image will be encode.
if the img is NULL, this function will try to get image from camera, you must use bind_camera() function to bind the camera.
returnencode result
staticFalse
+
+

C++ defination code:

+ +
video::Packet *encode(image::Image *img = maix::video::Video::NoneImage)
+
+
+

decode

+

Decode frame

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramframe: the frame will be decode
returndecode result
staticFalse
+
+

C++ defination code:

+ +
image::Image *decode(video::Frame *frame = nullptr)
+
+
+

finish

+

Encode or decode finish

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnerror code
staticFalse
+
+

C++ defination code:

+ +
err::Err finish()
+
+
+

capture

+

Capture image

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
attentionEach time encode is called, the last captured image will be released.
returnerror code
staticFalse
+
+

C++ defination code:

+ +
image::Image *capture()
+
+
+

is_recording

+

Check if video is recording

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returntrue if video is recording, false if not
staticFalse
+
+

C++ defination code:

+ +
bool is_recording()
+
+
+

is_opened

+

Check if video is opened

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returntrue if video is opened, false if not
staticFalse
+
+

C++ defination code:

+ +
bool is_opened()
+
+
+

is_closed

+

check video device is closed or not

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnclosed or not, bool type
staticFalse
+
+

C++ defination code:

+ +
bool is_closed()
+
+
+

width

+

Get video width

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnvideo width
staticFalse
+
+

C++ defination code:

+ +
int width()
+
+
+

height

+

Get video height

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnvideo height
staticFalse
+
+

C++ defination code:

+ +
int height()
+
+
+

VideoRecorder

+

Video Recorder class. This module is not fully supported and may be deprecated in the future.

+
+

C++ defination code:

+ +
class VideoRecorder
+
+
+

VideoRecorder

+

Construct a new VideoRecorder object. This is an object that integrates recording, video capturing, and display functions, which can be used to achieve high-resolution video input when needed.

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramopen: If true, video will automatically call open() after creation. default is true.
staticFalse
+
+

C++ defination code:

+ +
VideoRecorder(bool open = true)
+
+
+

lock

+

lock video

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramtimeout: timeout in ms. unit:ms
returnerror code
staticFalse
+
+

C++ defination code:

+ +
err::Err lock(int64_t timeout = -1)
+
+
+

unlock

+

unlock video

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnerror code
staticFalse
+
+

C++ defination code:

+ +
err::Err unlock()
+
+
+

open

+

Start a thread to handle the input function.

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnerror code
staticFalse
+
+

C++ defination code:

+ +
err::Err open()
+
+
+

close

+

Stop the thread, and reset the object.

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnerror code
staticFalse
+
+

C++ defination code:

+ +
err::Err close()
+
+
+

is_opened

+

Check whether the object is opened.

+ + + + + + + + + + + + + + + + + +
itemdescription
typefunc
staticFalse
+
+

C++ defination code:

+ +
bool is_opened()
+
+
+

bind_display

+

Bind a Display object. if this object is not bound, it will not be displayed.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramdisplay: display object
fit: fit mode. It is recommended to fill in FIT_COVER or FIT_FILL. For maixcam, using FIT_CONTAIN may affect the
functionality of the second layer created by add_channel() in the Display. default is FIT_COVER.
returnerror code
staticFalse
+
+

C++ defination code:

+ +
err::Err bind_display(display::Display *display, image::Fit fit = image::FIT_COVER)
+
+
+

bind_camera

+

Bind a Camera object. if this object is not bound, images cannot be captured.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramcamera: camera object
returnerror code
staticFalse
+
+

C++ defination code:

+ +
err::Err bind_camera(camera::Camera *camera)
+
+
+

bind_audio

+

Bind a AudioRecorder object. if this object is not bound, audio cannot be captured.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramaudio: audio recorder object
returnerror code
staticFalse
+
+

C++ defination code:

+ +
err::Err bind_audio(audio::Recorder *audio)
+
+
+

bind_imu

+

Bind a IMU object. if this object is not bound, imu data cannot be captured.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramimu: imu object
returnerror code
staticFalse
+
+

C++ defination code:

+ +
err::Err bind_imu(void *imu)
+
+
+

reset

+

Reset the video recorder.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
noteIt will not reset the bound object; if you have already bound the display using bind_display(), there is no need to rebind the display after calling reset().
returnerror code
staticFalse
+
+

C++ defination code:

+ +
err::Err reset()
+
+
+

config_path

+

The recorded video will be saved to this path, and this API cannot be called during runtime.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
parampath: The path of the video file to be saved
returnerror code
staticFalse
+
+

C++ defination code:

+ +
err::Err config_path(std::string path)
+
+
+

get_path

+

Get the path of the video file to be saved

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnpath
staticFalse
+
+

C++ defination code:

+ +
std::string get_path()
+
+
+

config_snapshot

+

Set the snapshot parameters

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
noteEnabling snapshot functionality may result in some performance loss.
paramenable: enable or disable snapshot
resolution: image resolution of snapshot
format: image format of snapshot
returnerror code
staticFalse
+
+

C++ defination code:

+ +
err::Err config_snapshot(bool enable, std::vector<int> resolution = std::vector<int>(), image::Format format = image::Format::FMT_YVU420SP)
+
+
+

config_resolution

+

Set the resolution of the video, and this API cannot be called during runtime.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
noteYou must bind the camera first, and this interface will modify the camera's resolution. The width must be divisible by 32.
paramresolution: The resolution of the video
returnerror code
staticFalse
+
+

C++ defination code:

+ +
err::Err config_resolution(std::vector<int> resolution)
+
+
+

get_resolution

+

Get the resolution of the video

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnthe resolution of the video
staticFalse
+
+

C++ defination code:

+ +
std::vector<int> get_resolution()
+
+
+

config_fps

+

Set the fps of the video, and this API cannot be called during runtime.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
noteThis interface only affect the fps of the encoded file.
returnerror code
staticFalse
+
+

C++ defination code:

+ +
err::Err config_fps(int fps)
+
+
+

get_fps

+

Get the fps of the video.

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnfps value
staticFalse
+
+

C++ defination code:

+ +
int get_fps()
+
+
+

config_bitrate

+

Set the bitrate of the video, and this API cannot be called during runtime.

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnerror code
staticFalse
+
+

C++ defination code:

+ +
err::Err config_bitrate(int bitrate)
+
+
+

get_bitrate

+

Get the bitrate of the video.

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnbitrate value
staticFalse
+
+

C++ defination code:

+ +
int get_bitrate()
+
+
+

mute

+

Set/Get the mute of the video

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramdata: If the parameter is true, mute; if false, unmute; if no parameter is provided, return the mute status.
returnerror code
staticFalse
+
+

C++ defination code:

+ +
int mute(int data = -1)
+
+
+

volume

+

Set/Get the volume of the video

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramdata: The volume of the video, the range is 0-100. if no parameter is provided, return the volume.
returnerror code
staticFalse
+
+

C++ defination code:

+ +
int volume(int data = -1)
+
+
+

seek

+

Get the current position of the video

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returncurrent position, unit: ms
staticFalse
+
+

C++ defination code:

+ +
int64_t seek()
+
+
+

record_start

+

Start recording

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
noteYou must bind the camera at a minimum during input. Additionally,
if you bind a display, the input image will be shown,
if you bind a audio, audio will be recorded,
if you bind a IMU, IMU data will be logged.
returnerror code
staticFalse
+
+

C++ defination code:

+ +
err::Err record_start()
+
+
+

snapshot

+

Take a snapshot

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnimage::Image
staticFalse
+
+

C++ defination code:

+ +
image::Image *snapshot()
+
+
+

record_finish

+

Stop recording and save the video

+ + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
returnerror code
staticFalse
+
+

C++ defination code:

+ +
err::Err record_finish()
+
+
+

draw_rect

+

Draw a rect on the video

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdescription
typefunc
paramid: id of the rect, range is [0, 15]
x: x coordinate
y: y coordinate
w: width
h: height
color: color
tickness: The line width of the rectangular box; if set to -1, it indicates that the rectangular box will be filled.
hidden: Hide or show the rectangular box
returnerror code
staticFalse
+
+

C++ defination code:

+ +
err::Err draw_rect(int id, int x, int y, int w, int h, image::Color color = image::COLOR_WHITE, int thickness = -1, bool hidden = false)
+
+
+ + +
+
+ +
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixcdk/api/sidebar.yaml b/maixcdk/api/sidebar.yaml new file mode 100644 index 00000000..00302b01 --- /dev/null +++ b/maixcdk/api/sidebar.yaml @@ -0,0 +1,168 @@ +items: +- file: README.md + label: Brief +- collapsed: false + items: + - collapsed: false + file: maix/image.md + label: image + - collapsed: false + file: maix/audio.md + label: audio + - collapsed: false + file: maix/tracker.md + label: tracker + - collapsed: false + file: maix/http.md + label: http + - collapsed: false + file: maix/camera.md + label: camera + - collapsed: false + file: maix/rtsp.md + label: rtsp + - collapsed: false + file: maix/rtmp.md + label: rtmp + - collapsed: false + file: maix/touchscreen.md + label: touchscreen + - collapsed: false + file: maix/video.md + label: video + - collapsed: false + file: maix/display.md + label: display + - collapsed: false + file: maix/uvc.md + label: uvc + - collapsed: false + file: maix/network.md + items: + - collapsed: false + file: maix/network/wifi.md + label: wifi + label: network + - collapsed: false + file: maix/comm.md + items: + - collapsed: false + file: maix/comm/modbus.md + label: modbus + label: comm + - collapsed: false + file: maix/modbus.md + items: + - collapsed: false + file: maix/modbus/Slave.md + label: Slave + label: modbus + - collapsed: false + file: maix/fs.md + label: fs + - collapsed: false + file: maix/app.md + label: app + - collapsed: false + file: maix/protocol.md + label: protocol + - collapsed: false + file: maix/time.md + label: time + - collapsed: false + file: maix/err.md + label: err + - collapsed: false + file: maix/example.md + label: example + - collapsed: false + file: maix/util.md + label: util + - collapsed: false + file: maix/thread.md + label: thread + - collapsed: false + file: maix/sys.md + label: sys + - collapsed: false + file: maix/log.md + label: log + - collapsed: false + file: maix/tensor.md + label: tensor + - collapsed: false + file: maix/i18n.md + label: i18n + - collapsed: false + file: maix/peripheral.md + items: + - collapsed: false + file: maix/peripheral/key.md + label: key + - collapsed: false + file: maix/peripheral/i2c.md + label: i2c + - collapsed: false + file: maix/peripheral/spi.md + label: spi + - collapsed: false + file: maix/peripheral/pwm.md + label: pwm + - collapsed: false + file: maix/peripheral/wdt.md + label: wdt + - collapsed: false + file: maix/peripheral/adc.md + label: adc + - collapsed: false + file: maix/peripheral/pinmap.md + label: pinmap + - collapsed: false + file: maix/peripheral/uart.md + label: uart + - collapsed: false + file: maix/peripheral/gpio.md + label: gpio + - collapsed: false + file: maix/peripheral/hid.md + label: hid + - collapsed: false + file: maix/peripheral/timer.md + label: timer + label: peripheral + - collapsed: false + file: maix/ext_dev.md + items: + - collapsed: false + file: maix/ext_dev/tmc2209.md + label: tmc2209 + - collapsed: false + file: maix/ext_dev/bm8563.md + label: bm8563 + - collapsed: false + file: maix/ext_dev/qmi8658.md + label: qmi8658 + - collapsed: false + file: maix/ext_dev/mlx90640.md + label: mlx90640 + - collapsed: false + file: maix/ext_dev/fp5510.md + label: fp5510 + - collapsed: false + file: maix/ext_dev/imu.md + label: imu + - collapsed: false + file: maix/ext_dev/pmu.md + label: pmu + - collapsed: false + file: maix/ext_dev/axp2101.md + label: axp2101 + label: ext_dev + - collapsed: false + file: maix/nn.md + items: + - collapsed: false + file: maix/nn/F.md + label: F + label: nn + label: maix diff --git a/maixcdk/config.json b/maixcdk/config.json new file mode 100644 index 00000000..a3836181 --- /dev/null +++ b/maixcdk/config.json @@ -0,0 +1,5 @@ +{ + "import": "config", + "class": "md_page", + "name": "Pages" +} diff --git a/maixcdk/doc/application/ai/yolo11.html b/maixcdk/doc/application/ai/yolo11.html new file mode 100644 index 00000000..81b32ff2 --- /dev/null +++ b/maixcdk/doc/application/ai/yolo11.html @@ -0,0 +1,286 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MaixCDK YOLO11 develop notes - MaixCDK + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

MaixCDK YOLO11 develop notes

+ +
+
+
    + +
+
+
+
+ + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

Souce code in MaixCDK/components/nn/include/maix_nn_yolo11.hpp

+

Model port from ultralytics/ultralytics, train and convert model refer to MaixPy doc customize yolo11.

+ + +
+
+ +
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixcdk/doc/application/index.html b/maixcdk/doc/application/index.html new file mode 100644 index 00000000..76721713 --- /dev/null +++ b/maixcdk/doc/application/index.html @@ -0,0 +1,286 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MaixCDK Application notes - MaixCDK + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

MaixCDK Application notes

+ +
+
+
    + +
+
+
+
+ + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

These notes is MaixCDK developer notes, taken down by developer when create some functions.

+

If you want to known more features and functions and documentation, please visit MaixPy documentation

+ + +
+
+ +
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixcdk/doc/application/peripheral/uart.html b/maixcdk/doc/application/peripheral/uart.html new file mode 100644 index 00000000..8f453592 --- /dev/null +++ b/maixcdk/doc/application/peripheral/uart.html @@ -0,0 +1,278 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MaixCDK + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

+ +
+
+
    + +
+
+
+
+ + + + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ + + +
+
+
+ + +
+
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixcdk/doc/application/ui/lvgl.html b/maixcdk/doc/application/ui/lvgl.html new file mode 100644 index 00000000..c4ca55b1 --- /dev/null +++ b/maixcdk/doc/application/ui/lvgl.html @@ -0,0 +1,296 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Use LVGL in MaixCDK - MaixCDK + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

Use LVGL in MaixCDK

+ +
+
+
    + +
+
+
+
+ + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

run gui_lvgl demo

+
    +
  • Go to examples/gui_lvgl in MaixCDK.
  • +
  • Execute maixcdk build to build the project for PC.
  • +
  • Execute maixcdk run to run the project on PC.
  • +
+

You can also execute maixcdk menuconfig to change platform to build for other platform.

+

Custom your own UI

+
    +
  • Download squareline and install first.
  • +
  • Create a new UI project in squareline.
  • +
  • Edit your UI.
  • +
  • Export UI files, then you will get a ui folder.
  • +
  • Copy all ui files to examples/gui_lvgl/ui folder.
  • +
  • Run maixcdk build to build.
  • +
+

Or you can mannually write code and not use squareline.

+ + +
+
+
+ + +
+
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixcdk/doc/config.json b/maixcdk/doc/config.json new file mode 100644 index 00000000..fa750fa6 --- /dev/null +++ b/maixcdk/doc/config.json @@ -0,0 +1,4 @@ +{ + "import": "config", + "name": "MaixCDK" +} diff --git a/maixcdk/doc/convention/add_api.html b/maixcdk/doc/convention/add_api.html new file mode 100644 index 00000000..0649aaf5 --- /dev/null +++ b/maixcdk/doc/convention/add_api.html @@ -0,0 +1,342 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Add API for MaixCDK / MaixPy - MaixCDK + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

Add API for MaixCDK / MaixPy

+ +
+
+
    + +
+
+
+
+ + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

Code Guidelines

+

Please refer to Code Guidelines first.

+

How to Add an API

+

At the end of the Quick Start, we briefly mentioned adding a new API to MaixPy using annotations. It looks straightforward – you only need to add a comment to the API function, for example:

+ +
namespace maix::example
+{
+    /**
+     * @brief Say hello to someone
+     * @param[in] name The name of the person, of string type
+     * @return A string containing "hello" + name
+     * @maixpy maix.example.hello
+     */
+    std::string hello(std::string name);
+}
+
+

Then you can call this in MaixPy:

+ +
from maix import example
+
+result = example.hello("Bob")
+print(result)
+
+

To ensure that the APIs we add are usable for users, we need to follow these guidelines:

+
    +
  • Design the API names and parameters to be reasonable, general, and highly cross-platform.
  • +
  • Ensure the API is annotated (documentation will be automatically generated during compilation).
  • +
  • The API should come with usage documentation, a tutorial, and example code.
  • +
+

Here is a more detailed process and guidelines:

+
    +
  1. Confirm the functionality and add a usage document and example code in the MaixPy Documentation Source. This acts as a design document, helping to avoid frequent API changes due to incomplete considerations during coding. It also serves as documentation. (This is very important!)
  2. +
  3. You can add an application document under docs/doc/application to record development details. Use lowercase filenames with underscores, e.g., peripheral/uart.md or ai/yolov2.md.
  4. +
  5. Mention the sources or open-source projects referenced for API design in the development document to facilitate the review process and improve the chances of passing the review quickly.
  6. +
  7. Refer to [components/basic/include/maix_api_example.hpp] and add the API to an appropriate component. If it's a new component, consider discussing its rationality first in issues.
  8. +
+
+

Note: The API is identified through comments, which helps automatically generate documentation and MaixPy source code. Pay close attention to the annotation guidelines and refer to maix_api_example.hpp for specifics.
+Additionally, because MaixCDK does not include definitions related to Python.h or Pybind11.h, language-native types are automatically converted by pybind11. For instance, void hello(std::string a, std::vector<int> b) is equivalent to def hello(a: str, b: list) in MaixPy.
+Common conversions include std::vector to list, std::map to dict, std::valarray (accepts list and bytes as input, returns list), and maix::Bytes (both input and return values are bytes). std::function maps to a function in MaixPy. For more details, refer to the pybind11 documentation.

+
+
    +
  1. Add a C++ example to the examples directory and ensure it compiles and runs successfully.
  2. +
  3. The documentation will be automatically generated during compilation. Check the generated files under docs/doc/api for any errors and correct them in the code if needed.
  4. +
  5. Test the updated MaixPy project with the new MaixCDK to ensure it compiles successfully and the generated documentation is correct. Fix any errors if they occur.
  6. +
  7. Submit your code to your own GitHub repository and wait for the action to automatically build and test it. Correct any errors promptly.
  8. +
  9. Once all online tests pass, submit a PR (Pull Request) and request to merge it into the dev branch on GitHub.
  10. +
+

Manually Adding a MaixPy API

+

The above method can automatically generate a MaixPy API, but in certain scenarios, manual addition might be necessary. For example, when the parameter is a specific type, such as numpy.array:

+
    +
  • Add the header file and code under components/maix/include in the MaixPy project. You can use the same namespace as in MaixCDK. For instance, the function maix.image.cv2image converts a numpy array to an image.Image object. Refer to the definitions in the convert_image.hpp file.
  • +
+

More references:

+ + + +
+
+ +
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixcdk/doc/convention/app.html b/maixcdk/doc/convention/app.html new file mode 100644 index 00000000..657c1ec6 --- /dev/null +++ b/maixcdk/doc/convention/app.html @@ -0,0 +1,386 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MaixCDK APP framework guide - MaixCDK + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

MaixCDK APP framework guide

+ +
+
+
    + +
+
+
+
+ + + + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

Introduction

+

User use steps:

+
    +
  • When device boot up, will automatically start launcher.
  • +
  • Use select one APP to start.
  • +
  • Run selected APP.
  • +
  • User interact with APP.
  • +
  • User exit APP.
  • +
  • launcher will start again and wait for user to select APP.
  • +
+

User install new APP:

+
    +
  • Ensure device is connected to internet(can connect WiFi in app_settings APP).
  • +
  • Open maixhub.com/app to find APP, click download button, and a QR code and a install code will be shown.
  • +
  • Open app_store APP in device to open camera to scan QR code, or input install code to install the APP.
  • +
  • Return to launcher, the new APP will be shown in the list.
  • +
+

Pack APP

+

If use MaixCDK:

+
    +
  • Create a app.yaml in your project folder, see below for format.
  • +
  • Execute maixcdk release -P maixcam to pack APP for maixcam platform.
  • +
  • Then you will find a app_store_v1.0.0.zip in dist folder, this is the APP package.
  • +
  • You can upload this package to maixhub.com/app to share with others.
  • +
  • Or you can execute maixcdk deploy -P maixcam to serve a local server and a QR code will be shown.
  • +
  • Or you can upload this app file to device and execute app_store install app_path.zip to install by command.
  • +
+

If use MaixPy, you can use MaixVision Workstation to release APP, or use maixtool to release manually:

+
    +
  • Create a app.yaml in your project folder, see below for format.
  • +
  • Create a main.py in your project folder, this is the entry of your APP.
  • +
  • Execute maixtool release in this folder, dist/app_id_vx.x.x.zip will be generated.
  • +
  • You can upload this package to maixhub.com/app to share with others.
  • +
  • Or you can execute maixtool deploy to serve a local server and a QR code will be shown.
  • +
+

app.yaml format:

+ +
id: my_app                         # unique id, use lowercase and `_` to separate words
+name: My APP
+name[zh]: 我的应用                  # Chinese name
+version: 1.0.0                     # version number, major.minor.patch
+icon: assets/my_app.png            # can be png or lottie json file, or empty
+author: Sipeed Ltd
+desc: My APP description
+desc[zh]: 我的应用描述
+
+#### Include files method 1:
+#         By default will include all files in project dir except exclude files
+exclude:       # not support regular expression, .git and __pycache__ is always exclude
+  - .vscode
+  - compile
+  - build
+  - dist
+# extra_include:
+#   src: dst
+#   build/filename123: filename123
+
+#### Include files method 2:
+#         White list mode, only include files in files dict.
+#         If no this key or value is empty, will use method 1.
+# files:
+#   - assets
+#   - hello.py
+#   - main.py
+
+
+#### Include files method 2.1:
+#         White list mode, only include files in files dict.
+#         If no this key or value is empty, will use method 1.
+# files:
+#   assets: assets
+
+
+

exclude is blacklist mode, files is whitelist mode, you can use one of them.

+

Files convention

+
    +
  • All app data is stored in /maixapp.
  • +
  • Apps are stored in /maixapp/apps.
  • +
  • There is a /maixapp/apps/app.info INI file for simple description of installed apps. Install and uninstall APP will update this file.
  • +
+
+

developer or use can manually copy APP directories here and execute python gen_app_info.py will generate app.info file.

+
+
    +
  • APP store in /maixapp/apps/app_id folder, every app must contain app_id executable file, or main.sh shell script, or main.py python script.
  • +
  • When boot up APP, the launcher will find file in app_id folder: main.sh -> main.py -> app_id. The main.sh will be executed by sh, main.py will be executed by python3, app_id will be directly executed.
  • +
  • All shared data is stored in /maixapp/share.
  • +
  • All pictures are stored in /maixapp/share/picture.
  • +
  • All video files are stored in /maixapp/share/video.
  • +
  • Temporary data can be stored in /maixapp/tmp. Note that this directory is located on the file system (SD card), which differs from the system's /tmp directory. The /tmp directory on the system is a virtual file system in memory, offering faster read/write speeds but with limited memory size. Large files and log files that need to be stored long-term (which may grow over time) are recommended to be placed in the /maixapp/tmp directory.
  • +
  • Font files are stored in /maixapp/share/font.
  • +
  • Icon files are stored in /maixapp/share/icon.
  • +
  • APP's data files created at runtime can be stored in /maixapp/apps/app_id/data.
  • +
  • All this path can be get by API maix.app.get_xxx_path, more detail see API doc or maix_app.hpp file.
  • +
+

Switch from APP to anothor APP

+

Use void maix::app::switch_app(const string &app_id, int idx = -1, const std::string &start_param = "") function to switch APP.

+

This will exit current APP and start another APP, and parse start_param string to the second APP, the second APP can get this param by maix::app::get_start_param().

+ + +
+
+ +
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixcdk/doc/convention/i18n.html b/maixcdk/doc/convention/i18n.html new file mode 100644 index 00000000..0d47536f --- /dev/null +++ b/maixcdk/doc/convention/i18n.html @@ -0,0 +1,385 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MaixCDK i18n(Internationalization), multi language support - MaixCDK + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

MaixCDK i18n(Internationalization), multi language support

+ +
+
+
    + +
+
+
+
+ + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

You can use any i18n library you like, gettext for example, they are supported in Python and C++.

+

And we provide a simple i18n library, for simple use case.

+

For MaixPy

+

See MaixPy i18n documentation.

+

For MaixCDK:

+

The same as MaixPy's, there's two ways:

+

Simple translation dict

+

Ensure your source file if UTF-8 encoded first.

+ +
#include "maix_i18n.hpp"
+
+const std::map<string, string> locale_zh_dict = {
+    {"out", "输出"},
+    {"hello", "你好"}
+};
+
+const std::map<string, string> locale_ja_dict = {
+    // {"out", "出力"},
+    {"hello", "こんにちは"}
+};
+
+const std::map<string, const std::map<string, string>> locales_dict = {
+    {"zh", locale_zh_dict},
+    {"ja", locale_ja_dict}
+};
+
+
+i18n::Trans trans(locales_dict);
+
+int main()
+{
+    log::info("system locale: %s\n", i18n::get_locale().c_str());
+    log::info("%s: %s\n", trans.tr("out").c_str(), trans.tr("hello").c_str());
+
+    trans.set_locale("zh");
+    printf("%s: %s\n", trans.tr("out").c_str(), trans.tr("hello").c_str());
+
+    trans.set_locale("en");
+    printf("%s: %s\n", trans.tr("out").c_str(), trans.tr("hello").c_str());
+
+    trans.set_locale("ja");
+    printf("%s: %s\n", trans.tr("out").c_str(), trans.tr("hello").c_str());
+    return 0;
+}
+
+
+

Seperated translation files

+

The upper demo is more simple for little translation strings, but if you have many strings need to translate, this way is recommended, use this way:

+
    +
  • We don't need to change source code when we want to change translation, translation strings in seperate yaml files.
  • +
  • It's easier to find translation strings, support auto scan strings which need to be translated and auto generate yaml files.
  • +
+ +
err::Err e = trans.load("locales"); // load from locales directory
+err::check_raise(e, "load translation yamls failed");
+
+log::info("system locale: %s\n", i18n::get_locale().c_str());
+log::info("%s: %s, %s\n", i18n::get_locale().c_str(), trans.tr("out").c_str(), trans.tr("hello").c_str());
+
+trans.set_locale("zh");
+log::info("zh: %s, %s\n", trans.tr("out").c_str(), trans.tr("hello").c_str());
+
+trans.set_locale("en");
+log::info("en: %s, %s\n", trans.tr("out").c_str(), trans.tr("hello").c_str());
+
+trans.set_locale("ja");
+log::info("ja: %s, %s\n", trans.tr("out").c_str(), trans.tr("hello").c_str());
+
+

Full demo see examples/i18n for example.

+

Then we exexute maixtool i18n -d . r, this will scan all the strings translate by tr() or _() function and generate locales directory and translation files.
+Manually translate the yaml files in locales, then run program on device, put locales directory besides program.

+

Show in LVGL APP

+

See how to show custom font at https://neucrack.com/p/514 .

+

Then use this piece of code:

+ +

+LV_FONT_DECLARE(zh_fonts);
+
+static const std::map<string, void*> fonts = {
+    {"zh", (void*)&zh_fonts}
+};
+
+const lv_font_t *get_font_by_locale(const string &locale)
+{
+    const std::map<string, void*>::const_iterator iter = fonts.find(locale);
+    if (iter == fonts.end())
+    {
+        return &zh_fonts;
+    }
+    return (lv_font_t *)iter->second;
+}
+
+

Finally you can use i18n font by

+ +
std::string locale = i18n::get_locale();
+
+lv_obj_set_style_text_font(lv_scr_act() , get_font_by_locale(locale), LV_PART_MAIN);
+
+lv_obj_t *label = lv_label_create(lv_scr_act());
+lv_label_set_text(label, trans.tr("hello").c_str());
+
+ + +
+
+ +
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixcdk/doc/convention/index.html b/maixcdk/doc/convention/index.html new file mode 100644 index 00000000..778752e1 --- /dev/null +++ b/maixcdk/doc/convention/index.html @@ -0,0 +1,374 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MaixCDK Development Guidelines and Guidance - MaixCDK + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

MaixCDK Development Guidelines and Guidance

+ +
+
+
    + +
+
+
+
+ + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

General Guidelines

+
    +
  • Simplicity and Ease of Use: Assume minimal prior experience from users. Minimize required actions and provide simple APIs with comprehensive documentation.
  • +
+
+

For example, instead of asking users to choose and download a toolchain, it is better to automatically select and download the toolchain based on the chosen platform, reducing the entry barrier.

+
+
    +
  • Universality: APIs should be designed to be platform-agnostic and provide consistent abstraction. If this cannot be achieved, reconsider whether the feature should be included.

    +
  • +
  • Consistency: Maintain consistent API styles and coding standards.

    +
  • +
  • Extensibility: While ensuring core functionality, provide extension interfaces to allow users to add features easily.

    +
  • +
  • Depth: Keep APIs simple but document the underlying principles. Open-source as much code as possible to facilitate deeper exploration by users.

    +
  • +
+

Source Code and Binary Files

+
    +
  • Avoid Using Git Submodules: This facilitates faster downloads for users in China. Even if the main repository is mirrored, submodules still need to be fetched from GitHub, which can be slow for Chinese users.

    +
  • +
  • Do Not Store Large Files or Binaries in the Source Code Repository: Storing these will significantly increase the Git repository size. Git is optimized for text files; handle binary files as described below.

    +
  • +
  • Automatically Download Third-Party Libraries and Binaries Before Compilation: Define necessary files for download in component.py. During compilation, they will be downloaded to dl/pkgs and extracted to dl/extracted, allowing direct inclusion in CMakeLists.txt, e.g., list(APPEND ADD_INCLUDE "${DL_EXTRACTED_PATH}/sunxi_mpp/sunxi-mpp-1.0.0/include").

    +
  • +
+
+

The list of files to be downloaded is stored in dl/pkgs_info.json during each build. Users with slow internet connections can manually download these files from official sources or third-party services and place them in dl/pkgs.

+
+
    +
  • Do Not Modify Third-Party Libraries: Avoid modifying the source code of third-party libraries to facilitate upgrades. If modifications are necessary, consider applying patches automatically after extraction.
  • +
+

Overview of MaixCDK Architecture

+

For general application developers, key concepts include:

+
    +
  • MaixCDK consists of two main parts: MaixCDK (library storage) and project (application code). Official examples and apps are located in MaixCDK/examples and MaixCDK/projects, respectively. You can also create your own projects in MaixCDK/projects.
  • +
+

Alternatively, you can separate the two and set an environment variable MAIXCDK_PATH pointing to the MaixCDK directory, e.g., export MAIXCDK_PATH=/home/xxx/MaixCDK. This allows projects to reside in other locations, such as /home/xxx/projects.

+
    +
  • Components: Each functional module can be encapsulated as a component, making it easy to include in different applications.

    +
      +
    • For example, the main component in examples/hello_world and various components in components. You can also add custom components, like hello_world/component1.
    • +
    • Use the environment variable MAIXCDK_EXTRA_COMPONENTS_PATH to specify additional component paths.
    • +
    • Each component includes a CMakeLists.txt file describing its contents, e.g., list(APPEND ADD_INCLUDE "include") for header files, list(APPEND ADD_SRCS "src/hello.c") for source files, and list(APPEND ADD_REQUIREMENTS basic) for dependencies.
    • +
    +
  • +
  • Kconfig: Provides terminal-based configuration options. Each component can include a Kconfig file for setting options, accessible via maixcdk menuconfig. The configuration is saved in build/config, generating global_config.cmake and global_config.h for use in CMakeLists.txt and C/C++ files.

    +
  • +
  • Third-Party Library Integration: There are two recommended methods:

    +
      +
    • Method 1: Specify third-party libraries in the component’s CMakeLists.txt for automatic download during compilation. This is preferred for libraries integrated into MaixCDK.
    • +
    • Method 2: Package and publish the library as a Python package on pypi.org with the naming convention maixcdk-xxx. Users can then install it using pip install maixcdk-xxx.
    • +
    +
  • +
  • Documentation: Located in the docs directory. API documentation is auto-generated from code; do not edit it manually. The application documentation serves as a user guide.

    +
  • +
+

Coding Style

+

To ensure consistency across MaixCDK and MaixPy APIs, follow these coding style guidelines:

+
    +
  • Function Names: Use lowercase with underscores, e.g., get_name.
  • +
  • Variable Names: Use lowercase with underscores, e.g., file_path.
  • +
  • Class Names: Use CamelCase, with common abbreviations in uppercase, e.g., Person, YOLOv2, UART.
  • +
  • Macros: Use uppercase with underscores, e.g., MAIXPY_VERSION.
  • +
  • Class Member Variables: Use lowercase with underscores without m_ prefix, e.g., name.
  • +
  • Private Class Member Variables: Prefix with _, e.g., _name.
  • +
  • Using Class Member Variables: Explicitly use this-> for clarity, e.g., this->name.
  • +
  • Namespace: Use the maix namespace for all official APIs, with sub-namespaces for different features, e.g., maix::thread, maix::peripheral.
  • +
  • Source File Naming: Use lowercase with underscores, e.g., maix_peripheral_uart.cpp. Use .hpp for C++ header files.
  • +
  • Comments: Follow Doxygen style for API documentation, as shown in components/basic/include/maix_api_example.hpp.
  • +
+

API Documentation Guidelines

+

Include the following keywords in your API comments:

+
    +
  • brief: A brief description of the functionality.
  • +
  • param: Detailed parameter descriptions, including value requirements and direction (e.g., param[in] a).
  • +
  • return: Detailed return value descriptions.
  • +
  • retval: Use this for specific return value explanations, e.g., @retval 0 success.
  • +
  • attention: Special considerations for using the API.
  • +
  • maixpy: Indicates a MaixPy API, including the package and variable name, e.g., maix.example.
  • +
  • maixcdk: Indicates a MaixCDK API.
  • +
+

Follow the guidelines strictly, especially when defining types and default values, to ensure accurate MaixPy API and documentation generation.

+

API Standardization Suggestions

+
    +
  • Prefer MaixCDK APIs over direct third-party APIs for better cross-platform compatibility, e.g., use maix_fs.hpp for file operations.
  • +
  • Use logging APIs from maix_log.hpp for consistent logging and to manage log levels.
  • +
  • Use error handling from maix_err.hpp for consistent error codes and exception handling.
  • +
  • For common APIs across modules, define a base class and inherit it in specific implementations, enhancing code reuse and consistency across platforms.
  • +
+ + +
+
+
+ + +
+
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixcdk/doc/convention/memcheck.html b/maixcdk/doc/convention/memcheck.html new file mode 100644 index 00000000..526aa3ac --- /dev/null +++ b/maixcdk/doc/convention/memcheck.html @@ -0,0 +1,330 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Memory Check Method - MaixCDK + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

Memory Check Method

+ +
+
+
    + +
+
+
+
+ + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

Introduction

+

Use the Valgrind tool to check for memory leaks, out-of-bounds memory access, and other memory-related issues.

+

Installation

+ +
sudo apt install valgrind
+
+

Using Valgrind

+ +
cd examples/hello_world
+maixcdk build
+
+# Output a brief log
+valgrind ./build/hello_world
+
+# Output a detailed log
+# --tool=memcheck: Specifies the tool as memcheck. Memcheck is the default tool, so this option can be omitted.
+# --leak-check=full: Displays detailed information for each memory leak.
+# --log-file=valgrind.log: Outputs the memory leak check result to the specified file. Here, valgrind.log is a custom filename.
+valgrind --tool=memcheck --leak-check=full --log-file=valgrind.log ./build/hello_world
+
+

Analyzing Valgrind Output

+

Checking Memory Leak Summary

+

In case of memory leaks, you may see logs similar to the following:

+ +
LEAK SUMMARY:
+   definitely lost: 48 bytes in 3 blocks.   # Memory definitely leaked (e.g., memory allocated by a pointer not freed)
+   indirectly lost: 32 bytes in 2 blocks.   # Indirectly leaked memory (e.g., a double pointer's memory not freed, causing indirect leakage)
+     possibly lost: 96 bytes in 6 blocks.
+   still reachable: 64 bytes in 4 blocks.
+        suppressed: 0 bytes in 0 blocks.
+
+

Checking Detailed Memory Errors

+

There are various types of memory errors that Valgrind can detect. Here is an example log. For more details, refer to the official documentation.

+ +
8 bytes in 1 blocks are definitely lost in loss record 1 of 14  # Identifies where memory is leaked
+   at 0x........: malloc (vg_replace_malloc.c:...)
+   by 0x........: mk (leak-tree.c:11)
+   by 0x........: main (leak-tree.c:39)
+
+88 (8 direct, 80 indirect) bytes in 1 blocks are definitely lost in loss record 13 of 14
+   at 0x........: malloc (vg_replace_malloc.c:...)
+   by 0x........: mk (leak-tree.c:11)
+   by 0x........: main (leak-tree.c:25)
+
+

Troubleshooting Unresolved Issues

+

If you encounter issues that cannot be resolved, refer to the official documentation.

+ + +
+
+ +
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixcdk/doc/convention/nn.html b/maixcdk/doc/convention/nn.html new file mode 100644 index 00000000..d04f3b10 --- /dev/null +++ b/maixcdk/doc/convention/nn.html @@ -0,0 +1,336 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + NN convention - MaixCDK + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

NN convention

+ +
+
+
    + +
+
+
+
+ + + + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

NN model file

+

Every AI model described by a .mud file, which is a INI format file.

+

MUD(Model Universal Description) file is a simple format to describe a model.

+
+

The reason we create this file is that every hardware platform has its own model format, it's difficult to load them directly, and we have to write many different code to load them, now we use MUD file and wrote model info in it to make load model easier.

+
+

MUD file definition:

+ +
[basic]
+type = cvimodel
+model = model_path_relative_to_mud_file
+
+[extra]
+model_type = classifier
+input_type = bgr
+mean = 103.94, 116.78, 123.68
+scale = 0.017, 0.017, 0.017
+labels = labels.txt
+
+

basic section is required, extra section is optional.
+basic section describes model type and model path.

+
    +
  • type is model type, now we support cvimodel for MaixCam.
  • +
  • model is model path relative to MUD file.
  • +
+

extra section describes model extra info, the application can get it by model.extra_info() method.

+
    +
  • model_type is model function type, like classifier and yolov2, it's optional for application.
  • +
  • input_type is model input type, like bgr and gray, it's optional for application.
  • +
  • mean is model input mean value, it's optional for application.
  • +
  • scale is model input scale value, it's optional for application.
  • +
  • labels is model labels file path, it's optional for application.
  • +
+

Current MaixCDK support:

+
    +
  • classifier
  • +
  • classifier_no_top
  • +
  • yolo11
  • +
  • yolov8
  • +
  • yolov5
  • +
  • pp_ocr
  • +
  • retinaface
  • +
  • nanotrack
  • +
  • retinaface
  • +
  • face_detector
  • +
  • speech
  • +
  • and more ... please refer to components/nn/include souce code and search model_type keyword and see load method.
  • +
+ + +
+
+ +
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixcdk/doc/convention/protocol.html b/maixcdk/doc/convention/protocol.html new file mode 100644 index 00000000..21f93edd --- /dev/null +++ b/maixcdk/doc/convention/protocol.html @@ -0,0 +1,1097 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Maix Communicate Protocol - MaixCDK + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

Maix Communicate Protocol

+ +
+
+
    + +
+
+
+
+ + + + +
+
+ + + +
+
+
+
+ + +
+
+ + +
+ + Update history +
+ + + + + + + + + + + + + + + + + + + +
DateVersionAuthorUpdate content
2023-11-281.0.0neucrack + + Designed and implemented the protocol documentation and code API + +
+
+
+ +
+
+ +
+

This article is translated from Chinese by ChatGPT, may have error, Pull Request is welcome!

+
+

Introduction to Maix Serial Protocol

+

Devices running MaixCDK or MaixPy can be controlled not only directly via the device's touch screen and buttons but also as modules using UART (serial port) or I2C.

+
+

Since I2C operates in a master-slave mode, the protocol adopts a request-response format: Request + Response.
+For UART protocol, some functions support active reporting. Please refer to the specific protocol details.

+
+

The communication protocol is explained in detail below.

+

How to Use Maix Device

+

Upon startup, go to the Settings application, and select the communication interface under Communication settings:

+
    +
  • Serial Port: Uses the serial port for communication. The specific serial port depends on the board, with a default baud rate of 115200.
  • +
  • TCP: Starts a TCP service on the Maix device, allowing the master device to connect via TCP. The default port is 5555.
  • +
+

Once the master device is connected to the Maix device, it can communicate following the protocol, where the master device acts as the primary device, and the Maix device as the slave.

+

Development on Maix Device Side:

+

You can easily implement command responses using the provided maix.comm.CommProtocol class. Refer to the examples comm_protocol (C++) or comm_protocol.py (MaixPy) for details.

+

Development on Master Device Side:

+

The master device can implement the protocol based on the chip and programming language. Template code is provided in the appendix.

+
+

Data Frame

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
header (4B LE)data len (4B LE)(flags+cmd+body+crc)flags (1B)cmd (1B)body (nB)CRC16_IBM (2B LE) (all previous)
Decimal Example3148663466901hello17451
Hex Example0xBBACCAAA0x000000090x000x01hello0x442B
Byte Stream (Hex)AA CA AC BB09 00 00 00000168 65 6C 6C 6F2B 44
+
+

Note: Multi-byte data uses little-endian (LE) encoding. For example, data_len is 0x00000006, with 06 in the lowest byte, so it is sent first as 0x06, followed by 0x00 0x00 0x00.
+Strings are sent in order, e.g., hello is sent as h, then e, l, l, o.
+In this example, the final data sent is: AA CA AC BB 09 00 00 00 00 01 68 65 6C 6C 6F 2B 44.

+
+
    +
  • header: 4-byte header marking the start of a frame, fixed as 0xAA 0xCA 0xAC 0xBB, sent starting with 0xAA.
  • +
  • data len: 4-byte data length, including the length of flags, cmd, body, and CRC.
  • +
  • flags: 1-byte flag where each bit indicates:
      +
    • MSB is_resp: Indicates if it is a response. 0 for request, 1 for response or active report (requires the third highest bit set to 1).
    • +
    • Second highest bit resp_ok:
        +
      • For requests: Reserved.
      • +
      • For responses: 1 for success, 0 for failure.
      • +
      +
    • +
    • Third highest bit is_report:
        +
      • For requests: Reserved.
      • +
      • For responses: 1 for active report, 0 for response message.
      • +
      +
    • +
    • Bits 4-6: Reserved for future use.
    • +
    • Lowest 2 bits version: Protocol version, updated only for incompatible changes. Compatible changes do not require a version update. The current version is 0.
    • +
    +
  • +
  • cmd: 1-byte command type, with several predefined commands listed in Command Definitions. Custom commands range from 0 to maix.protocol.CMD.CMD_APP_MAX.
  • +
  • body: Variable length, < (2^32 - 1). Different commands have different body content, detailed below for each command.
  • +
  • crc16: 2-byte CRC check value using the CRC IBM method, verifying data integrity during transmission. See C Code Implementation or Python CRC16.
  • +
+

For encoding and decoding, see Appendix: Code.

+
+

Request and Response

+

Sending Request

+

Data direction: MCU or other master device -> Maix device

+

Set the highest bit of flags (is_resp) to 0. The body content is determined by cmd.

+

Receiving Response

+

Data direction: Maix device -> MCU or other master device

+

Set the highest bit of flags (is_resp) to 1.

+
    +
  • For a successful response: Set resp_ok to 1, and the body content is determined by cmd. An empty body is the simplest successful response.
  • +
  • For a failed response:
      +
    • Set resp_ok to 0.
    • +
    • The first byte of body is the error code. Refer to MaixCDK maix.err.Err for error codes.
    • +
    • The following bytes in body contain the error message in UTF-8 encoding, preferably in plain English for better compatibility.
    • +
    +
  • +
+

Each request should have a corresponding response, either successful (RESP_OK) or failed (RESP_ERR). If RESP_OK has no specified body, it is empty.

+

Active Data Reporting

+

Data direction: Maix device -> MCU or other master device

+

The master device must first enable active reporting using the CMD_SET_REPORT command (only supported for specific commands).

+
+

For example, if the APP supports the CMD_GET_TEMP command to get temperature data, the master can use the CMD_SET_REPORT command to enable periodic temperature reporting. If the APP does not support active reporting for CMD_GET_TEMP, it will respond with CMD_ERROR.

+
+

Set the highest bit of flags (is_resp) to 1 and the third bit is_report to 1. The body content depends on the cmd.

+
+

Examples

+

Example:

+

The MCU connects to the Maix device via the serial port using the default baud rate of 115200.

+

The MCU requests the list of applications from the Maix device. The steps are as follows:

+
    +
  1. According to the protocol specification, the MCU sends a request with cmd set to 0xF9 (CMD_APP_LIST), and an empty body. Actual byte stream:
    +AA CA AC BB 04 00 00 00 01 F9 C9 77.

    +
  2. +
  3. The Maix device responds with cmd set to 0xF9 and flags set to 0xC1 (with |0x80 for response and |0x40 for success). The body contains the application list. If there are two applications, the actual byte stream is:
    +AA CA AC BB 0A 00 00 00 C1 F9 02 66 61 63 65 00 66 61 63 65 00 F6 06.

    +
  4. +
+
+

Command Definitions

+

The cmd values in the protocol frame are defined as follows:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Command NameValueDescription
CMD_APP_MAX0xC8Maximum value for custom commands (exclusive)
CMD_SET_REPORT0xF8Set active reporting
CMD_APP_LIST0xF9Query application list
CMD_START_APP0xFAStart an application
CMD_EXIT_APP0xFBExit the current application
CMD_CUR_APP_INFO0xFCQuery current application info
CMD_APP_INFO0xFDQuery specific application info
CMD_KEY0xFESimulate key press message
CMD_TOUCH0xFFSimulate touch message
+

Note that CMD_APP_MAX defines the range for custom commands, from 0 up to (but not including) CMD_APP_MAX.

+

Each cmd has specific request and response data and a unique body. Detailed explanations for each command are provided below:

+
+

CMD_SET_REPORT

+

Enables or disables active reporting for specific commands.

+

Active reporting includes:

+
    +
  1. Event-based reporting, such as reporting detected faces.
  2. +
  3. Periodic reporting, such as reporting temperature every 5 seconds.
  4. +
+

If both periodic and event-based reporting are enabled, the timer restarts after an event report.

+

Request

+

body:

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
cmd (1B)on_off (1B)event (1B)timer (4B)
DescriptionCommand for active reportingEnable (1) or disable (0)Event reporting (1 for enable, 0 for disable)Timer for periodic reporting in ms (set to 0 if not needed)
Example0x020x0115000
+

Response

+

If the command supports active reporting, respond with RESP_OK; otherwise, respond with RESP_ERR.

+

body: None

+
+

CMD_APP_LIST

+

Queries the list of available applications.

+

Request

+

body: None

+

Response

+

body:

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
number (1B)app1...app n info
DescriptionNumber of applicationsid1 (null-terminated string)...idn
Example0x02'face\0'...'appn\0'
+
+

CMD_CUR_APP_INFO

+

Gets the current application information.

+

Request

+

body: None

+

Response

+

body:

+ + + + + + + + + + + + + + + + + + + + +
idx (1B)app info (id + name + brief)
DescriptionApplication indexApplication info (id, name in UTF-8, brief description in UTF-8)
Example0x00'face\0face\0face detect\0'
+
+

CMD_APP_INFO

+

Queries specific application information.

+

Request

+

body:

+ + + + + + + + + + + + + + + + + + + + +
idx (1B)app_id (nB)
DescriptionApplication indexApplication ID
Example0x02'face'
+

Either idx or app_id can be specified:

+
    +
  • idx: Application index (starts from 0). Setting to 0xFF means it is not specified.
  • +
  • app_id: Application ID. If idx is specified, app_id can be omitted.
  • +
+

Response

+

body:

+ + + + + + + + + + + + + + + +
idx (1B)app info (id + name + brief)
Example0x00'face\0face\0face detect\0'
+
+

CMD_START_APP

+

Requests to start a specified application. This command will exit the current application and start the specified one.

+
    +
  • If the APP receives this command, it must call the API maix.app.switch_app to switch the application.
  • +
+
+

There is a risk if the APP does not correctly implement the response to this command, prompting the developer to implement it.

+
+
    +
  • If the Launcher receives this command, it will start the specified application.
  • +
+

Request

+

body:

+ + + + + + + + + + + + + + + + + + + + + + + +
idx (1B)app_id (nB)app_func (nB)
DescriptionApplication index (starts from 0, set to 0xFF if unspecified)Application ID (optional if idx is specified)Function to execute if the application has multiple functions
Example0x02'scan''qrcode'
+

Response

+

body: None

+
+

CMD_EXIT_APP

+

Requests to exit the current application.

+

Request

+

body: None

+

Response

+

body: None

+
+

CMD_KEY

+

Sends a simulated key press request.

+

Request

+

body:

+ + + + + + + + + + + + + +
key (4B)value (1B)
Key value (little-endian)0x01 (pressed), 0x00 (released), 0x02 (long press)
+

Response

+

body: None

+
+

CMD_TOUCH

+

Sends a simulated touch request.

+

Request

+

body:

+ + + + + + + + + + + + + + + +
xyevent (1B)
x-coordinatey-coordinateEvent type
+

Event types:

+
    +
  • 0x00: Press
  • +
  • 0x01: Release
  • +
  • 0x02: Move
  • +
+

Response

+

body: None

+

Application (APPS) Protocol Specification

+

Camera

+

Commands:

+ + + + + + + + + + + + + + + + + +
CommandValueDescriptionResponse
CMD_SNAP0x01Take a photo
+

Classifier

+

TODO:

+

body Description:
+The request consists of a single byte representing the command, as shown in the table below:

+ + + + + + + + + + + + + + + + + +
CommandValueDescriptionResponse
CMD_RECOGNIZE0x01Recognize objectCMD_APP_CMD
+

Response:

+
    +
  • Response for command CMD_RECOGNIZE: The response cmd is CMD_APP_CMD, and the body is structured as follows:
  • +
+ + + + + + + + + + + + + + + + + +
CMD_RECOGNIZEid (2B uint16 LE)prob (4B float LE)name
CMD_RECOGNIZE valueRecognized id (index), little-endianProbability, float, little-endianName, UTF-8 encoded
+

Face Detection

+

TODO:

+

body Description:
+The request consists of a single byte representing the command, as shown in the table below:

+ + + + + + + + + + + + + + + + + +
CommandValueDescriptionResponse
CMD_POS0x01Detect faceCMD_APP_CMD
+

Response:

+
    +
  • Response for command CMD_POS: The response cmd is CMD_APP_CMD, and the body is structured as follows:
  • +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
CMD_POSface num (2B LE)prob (4B float LE)x (2B LE)y (2B LE)w (2B LE)h (2B LE)...
CMD_POS valueNumber of detected facesProbability, float, little-endianTop-left x-coordinate of the face boxTop-left y-coordinate of the face boxWidth of the face boxHeight of the face boxRemaining faces...
+

Face Recognition

+

TODO:

+

body Description:
+The request consists of a single byte representing the command, as shown in the table below:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
CommandValueDescriptionResponse
CMD_FACES0x01Recognize facesCMD_APP_CMD
CMD_USERS0x02Query all usersCMD_APP_CMD
CMD_RECORD0x03Record a faceCMD_APP_CMD
CMD_REMOVE0x04Remove a faceCMD_APP_CMD
+

Request:

+

CMD_APP_CMD plus an additional byte for app_cmd. Some commands have extra parameters, as follows:

+
    +
  • Request for command CMD_RECORD:
  • +
+ + + + + + + + + + + + + +
CMD_RECORDuser name
CMD_RECORD valueName of the user being recorded
+
    +
  • Request for command CMD_REMOVE:
  • +
+ + + + + + + + + + + + + + + +
CMD_REMOVEuser idx (2B int16)user name
CMD_REMOVE valueUser index, 2 bytes, little-endianName of the user to be removed
+

Either index or username can be provided.

+

Response:

+
    +
  • Response for command CMD_FACES: The response cmd is CMD_APP_CMD, and the body is structured as follows:
  • +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
CMD_FACESface num (2B LE)id (2B)name_len (1B)nameprob (4B float LE)x (2B LE)y (2B LE)w (2B LE)h (2B LE)...
CMD_FACES valueNumber of detected facesFace ID (index)Length of the nameName, UTF-8 encodedProbability, float, little-endianTop-left x-coordinate of the face boxTop-left y-coordinate of the face boxWidth of the face boxHeight of the face boxRemaining faces...
+
    +
  • Response for command CMD_USERS: The response cmd is CMD_APP_CMD, and the body is structured as follows:
  • +
+ + + + + + + + + + + + + + + + + + + +
CMD_USERSuser num (2B LE)name_len (1B)name...
CMD_USERS valueNumber of usersLength of the usernameName, UTF-8 encodedRemaining usernames...
+
    +
  • Response for command CMD_RECORD: CMD_OK or CMD_ERROR

    +
  • +
  • Response for command CMD_REMOVE: CMD_OK or CMD_ERROR

    +
  • +
+

Appendix: Code

+

C CRC16 IBM

+ +
unsigned short crc16_IBM(unsigned char *ptr, int len)
+{
+    unsigned int i;
+    unsigned short crc = 0x0000;
+
+    while(len--)
+    {
+        crc ^= *ptr++;
+        for (i = 0; i < 8; ++i)
+        {
+            if (crc & 1)
+                crc = (crc >> 1) ^ 0xA001;
+            else
+                crc = (crc >> 1);
+        }
+    }
+
+    return crc;
+}
+
+

Alternatively, using a lookup table:

+ +
const unsigned int crc16_table[256] = {
+    0x0000, 0xc0c1, 0xc181, 0x0140, 0xc301, 0x03c0, 0x0280, 0xc241,
+    0xc601, 0x06c0, 0x0780, 0xc741, 0x0500, 0xc5c1, 0xc481, 0x0440,
+    0xcc01, 0x0cc0, 0x0d80, 0xcd41, 0x0f00, 0xcfc1, 0xce81, 0x0e40,
+    0x0a00, 0xcac1, 0xcb81, 0x0b40, 0xc901, 0x09c0, 0x0880, 0xc841,
+    0xd801, 0x18c0, 0x1980, 0xd941, 0x1b00, 0xdbc1, 0xda81, 0x1a40,
+    0x1e00, 0xdec1, 0xdf81, 0x1f40, 0xdd01, 0x1dc0, 0x1c80, 0xdc41,
+    0x1400, 0xd4c1, 0xd581, 0x1540, 0xd701, 0x17c0, 0x1680, 0xd641,
+    0xd201, 0x12c0, 0x1380, 0xd341, 0x1100, 0xd1c1, 0xd081, 0x1040,
+    0xf001, 0x30c0, 0x3180, 0xf141, 0x3300, 0xf3c1, 0xf281, 0x3240,
+    0x3600, 0xf6c1, 0xf781, 0x3740, 0xf501, 0x35c0, 0x3480, 0xf441,
+    0x3c00, 0xfcc1, 0xfd81, 0x3d40, 0xff01, 0x3fc0, 0x3e80, 0xfe41,
+    0xfa01, 0x3ac0, 0x3b80, 0xfb41, 0x3900, 0xf9c1, 0xf881, 0x3840,
+    0x2800, 0xe8c1, 0xe981, 0x2940, 0xeb01, 0x2bc0, 0x2a80, 0xea41,
+    0xee01, 0x2ec0, 0x2f80, 0xef41, 0x2d00, 0xedc1, 0xec81, 0x2c40,
+    0xe401, 0x24c0, 0x2580, 0xe541, 0x2700, 0xe7c1, 0xe681, 0x2640,
+    0x2200, 0xe2c1, 0xe381, 0x2340, 0xe101, 0x21c0, 0x2080, 0xe041,
+    0xa001, 0x60c0, 0x6180, 0xa141, 0x6300, 0xa3c1, 0xa281, 0x6240,
+    0x6600, 0xa6c1, 0xa781, 0x6740, 0xa501, 0x65c0, 0x6480, 0xa441,
+    0x6c00, 0xacc1, 0xad81, 0x6d40, 0xaf01, 0x6fc0, 0x6e80, 0xae41,
+    0xaa01, 0x6ac0, 0x6b80, 0xab41, 0x6900, 0xa9c1, 0xa881, 0x6840,
+    0x7800, 0xb8c1, 0xb981, 0x7940, 0xbb01, 0x7bc0, 0x7a80, 0xba41,
+    0xbe01, 0x7ec0, 0x7f80, 0xbf41, 0x7d00, 0xbdc1, 0xbc81, 0x7c40,
+    0xb401, 0x74c0, 0x7580, 0xb541, 0x7700, 0xb7c1, 0xb681, 0x7640,
+    0x7200, 0xb2c1, 0xb381, 0x7340, 0xb101, 0x71c0, 0x7080, 0xb041,
+    0x5000, 0x90c1, 0x9181, 0x5140, 0x9301, 0x53c0, 0x5280, 0x9241,
+    0x9601, 0x56c0, 0x5780, 0x9741, 0x5500, 0x95c1, 0x9481, 0x5440,
+    0x9c01, 0x5cc0, 0x5d80, 0x9d41, 0x5f00, 0x9fc1, 0x9e81, 0x5e40,
+    0x5a00, 0x9ac1, 0x9b81, 0x5b40, 0x9901, 0x59c0, 0x5880, 0x9841,
+    0x8801, 0x48c0, 0x4980, 0x8941, 0x4b00, 0x8bc1, 0x8a81, 0x4a40,
+    0x4e00, 0x8ec1, 0x8f81, 0x4f40, 0x8d01, 0x4dc0, 0x4c80, 0x8c41,
+    0x4400, 0x84c1, 0x8581, 0x4540, 0x8701, 0x47c0, 0x4680, 0x8641,
+    0x8201, 0x42c0, 0x4380, 0x8341, 0x4100, 0x81c1, 0x8081, 0x4040,
+};
+
+
+unsigned short crc16_IBM(const unsigned char *ptr,int len)
+{
+    unsigned short crc = 0x0000;
+
+    while(len--)
+    {
+        crc = (crc >> 8) ^ crc16_table[(crc ^ *ptr++) & 0xff];
+    }
+
+    return (crc);
+}
+
+
+ + +
+
+ +
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixcdk/doc/dev/docker/Dockerfile b/maixcdk/doc/dev/docker/Dockerfile new file mode 100644 index 00000000..caddb4e3 --- /dev/null +++ b/maixcdk/doc/dev/docker/Dockerfile @@ -0,0 +1,52 @@ +FROM ubuntu:20.04 + +ENV DEBIAN_FRONTEND noninteractive + +EXPOSE 8888 +EXPOSE 2333 + +RUN dpkg --add-architecture i386 \ + && apt-get -o APT::Retries=3 update -y + +RUN apt-get update \ + && apt-get install -y software-properties-common \ + && add-apt-repository -y ppa:deadsnakes/ppa\ + && apt-get update \ + && apt-get install build-essential vim \ + git libncurses5-dev zlib1g-dev gawk \ + libssl-dev unzip lib32z1 lib32z1-dev lib32stdc++6 libstdc++6 \ + ca-certificates file g++-multilib libc6:i386 locales \ + python3 python3-pip rsync shellcheck \ + libopencv-dev libopencv-contrib-dev \ + libsdl2-dev \ + python3.11 python3.11-venv python3.11-dev \ + unzip wget sudo -y \ + && rm /usr/bin/python3 \ + && ln -s /usr/bin/python3.11 /usr/bin/python3 \ + && python3 -m ensurepip --upgrade \ + && apt-get purge -yq \ + && apt-get autoremove -yq --purge \ + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* \ + && rm -rf /tmp/* + +COPY requirements.txt /tmp/requirements.txt +COPY teedoc_requirements.txt /tmp/teedoc_requirements.txt + +# RUN python3 -m pip install --upgrade pip +# RUN python3 -m pip install cmake teedoc +# RUN python3 -m pip install -r /tmp/requirements.txt +# RUN python3 -m pip install -r /tmp/teedoc_requirements.txt + +RUN python3 -m pip install --upgrade pip -i https://pypi.tuna.tsinghua.edu.cn/simple +RUN python3 -m pip install cmake teedoc -i https://pypi.tuna.tsinghua.edu.cn/simple +RUN python3 -m pip install -r /tmp/requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple +RUN python3 -m pip install -r /tmp/teedoc_requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple + +RUN ln -s /usr/bin/python3 /usr/bin/python + +COPY switch_user.sh /usr/local/bin/switch_user.sh +RUN chmod +x /usr/local/bin/switch_user.sh +ENTRYPOINT ["/usr/local/bin/switch_user.sh"] + + diff --git a/maixcdk/doc/dev/docker/index.html b/maixcdk/doc/dev/docker/index.html new file mode 100644 index 00000000..c30075f8 --- /dev/null +++ b/maixcdk/doc/dev/docker/index.html @@ -0,0 +1,354 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MaixCDK docker building environment - MaixCDK + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

MaixCDK docker building environment

+ +
+
+
    + +
+
+
+
+ + + + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

About Docker and install Docker

+

Docker is a tool, here we use it to create a clean Ubuntu environment to build MaixCDK.
+Use docker you don't need to install dependencies manually, just create a docker container and then all ready.

+

Docker install doc see Docker official doc

+

After installation, you can use docker --version to check if it is installed successfully.

+

Pull from docker hub (recommended), or build by yourself

+ +
docker pull sipeed/maixcdk-builder
+
+
+

Or you can build from Dockerfile by yourself.

+ +
docker build --network=host -t maixcdk-builder .
+
+

You can also add proxy by add args:--network=host --build-arg http_proxy=http://127.0.0.1:8123 --build-arg https_proxy=http://127.0.0.1:8123

+
+

Create and run container

+

The upper step we got a docker system image, now we create a container to run this image.

+ +
docker run -it --network=host --hostname maixcdk-env --name maixcdk-env --env USER=$USER --env UID=`id -u` --env GID=`id -g` --env MAIXCDK_PATH=/home/${USER}/MaixCDK -v /home/${USER}/MaixCDK:/home/${USER}/MaixCDK sipeed/maixcdk-builder
+
+
+

! DO NOT add /bin/bash to the end of the command.
+--network=host means use the same network as host PC.
+--hostname means set hostname of container to maixcdk-env.
+--name means set container name to maixcdk-env, then you can use docker command to control it.
+Then assign USER(your user name of host PC), user id, group id to use the same as host PC's user info in container to avoid permission problem.
+You can use -v host_dir:container_dir to map your data to container, e.g. -v /home/${USER}/MaixCDK:/home/${USER}/MaixCDK -v /home/${USER}/projects:/home/${USER}/projects.
+It's recommended to map your directories to the container's same directory, this is useful to see logs.
+--env MAIXCDK_PATH=/home/${USER}/MaixCDK arg to set MAIXCDK_PATH environment variable, so you can compile your project anywhere in container.
+sipeed/maixcdk-builder is the image name, if you build by yourself, use maixcdk-builder instead.

+
+

Then you can use shell command in container.
+The user's password is maixcdk by default, if you want to change it, use docker exec -it maixcdk-env passwd to change it.

+

Build MaixCDK projects or examples

+

When step into container, you can use shell command to build according to the MaixCDK document.

+ +
cd /MaixCDK/examples/hello_world
+maixcdk build
+maixcdk run
+
+cd ~/projects/my_project
+maixcdk build
+maixcdk run
+
+

Stop container

+ +
docker stop maixcdk-env
+
+

RUN container

+ +
docker start maixcdk-env
+docker attach maixcdk-env
+
+

Execute command through host shell

+ +
docker exec -it --user $USER maixcdk-env "cd /MaixCDK/examples/hello_world && maixcdk build && maixcdk run"
+
+ +
docker exec -it --user $USER maixcdk-env  /bin/bash
+
+

Remove container

+ +
docker stop maixcdk-env
+docker rm maixcdk-env
+
+ + +
+
+ +
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixcdk/doc/dev/docker/requirements.txt b/maixcdk/doc/dev/docker/requirements.txt new file mode 100644 index 00000000..01ba693d --- /dev/null +++ b/maixcdk/doc/dev/docker/requirements.txt @@ -0,0 +1,6 @@ +PyYAML +progress +requests +maixtool +pybind11-stubgen + diff --git a/maixcdk/doc/dev/docker/switch_user.sh b/maixcdk/doc/dev/docker/switch_user.sh new file mode 100644 index 00000000..f3776c04 --- /dev/null +++ b/maixcdk/doc/dev/docker/switch_user.sh @@ -0,0 +1,72 @@ +#!/bin/bash + +set -e + +UID=${UID:-""} +GID=${GID:-""} +USER=${USER:-""} + +if [ -z "$USER" ]; then + echo "USER env is required by --env USER=\$USER" + exit 1 +fi + +if [ -z "$UID" ]; then + echo "UID env is required by --env UID=\`id -u\`" + exit 1 +fi + +if [ -z "$GID" ]; then + echo "GID env is required by --env GID=\`id -g\`" + exit 1 +fi + +# if group $USER not exists, add group +if ! grep -q "^$USER:" /etc/group; then + addgroup --gid "$GID" "$USER" +fi + +# if user $UID not exists, add user +if ! grep -q "^$USER:" /etc/passwd; then + adduser --gecos "" --uid "$UID" --gid "$GID" --no-create-home --disabled-password "$USER" + mkdir -p /home/"$USER" + cp -r /etc/skel/. /home/"$USER" + # default password is maixcdk + echo "$USER:maixcdk" | chpasswd + usermod -aG sudo "$USER" +fi +chown "$UID":"$GID" /home/"$USER" + +# add /maixapp directory and chown to $USER +mkdir -p /maixapp +chown "$UID":"$GID" /maixapp + +echo "###########################################################" +echo "##" +echo "## ███ ███ █████ ██ ██ ██ ██████ ██████ ██ ██" +echo "## ████ ████ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██" +echo "## ██ ████ ██ ███████ ██ ███ ██ ██ ██ █████" +echo "## ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██" +echo "## ██ ██ ██ ██ ██ ██ ██ ██████ ██████ ██ ██" +echo "##" +echo "## ${USER}! Welcome to MaixCDK Docker Container!" +echo "###########################################################" +echo "##" + +# if $MAIXCDK_PATH exists and is a directory and is not empty +if [ -n "$MAIXCDK_PATH" ] && [ -d "$MAIXCDK_PATH" ] ; then + echo "## MAIXCDK_PATH is set to '$MAIXCDK_PATH'" +else + echo "## MAIXCDK_PATH is not set or ${MAIXCDK_PATH} not exists" + echo "## Please set MAIXCDK_PATH to MaixCDK path in container" + echo "## e.g. add args \`--env MAIXCDK_PATH=/path/to/MaixCDK -v /path/to/MaixCDK:/path/to/MaixCDK\` to docker run command" +fi +echo "## The default password of user ${USER} is 'maixcdk'" +echo "###########################################################" +echo "" + +cd /home/"$USER" + +su "$USER" + + diff --git a/maixcdk/doc/dev/docker/teedoc_requirements.txt b/maixcdk/doc/dev/docker/teedoc_requirements.txt new file mode 100644 index 00000000..a7202be0 --- /dev/null +++ b/maixcdk/doc/dev/docker/teedoc_requirements.txt @@ -0,0 +1,12 @@ +teedoc-plugin-ad-hint +teedoc-plugin-assets +teedoc-plugin-baidu-tongji +teedoc-plugin-blog +teedoc-plugin-comments-gitalk +teedoc-plugin-google-analytics +teedoc-plugin-google-translate +teedoc-plugin-jupyter-notebook-parser +teedoc-plugin-markdown-parser +teedoc-plugin-search +teedoc-plugin-theme-default +teedoc-plugin-thumbs-up diff --git a/maixcdk/doc/dev/quick_start.html b/maixcdk/doc/dev/quick_start.html new file mode 100644 index 00000000..5c05f055 --- /dev/null +++ b/maixcdk/doc/dev/quick_start.html @@ -0,0 +1,275 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MaixCDK quick start - MaixCDK + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

MaixCDK quick start

+ +
+
+
    + +
+
+
+
+ + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

see quick start

+ + +
+
+
+ + +
+
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixcdk/doc/dev/vscode_debug.html b/maixcdk/doc/dev/vscode_debug.html new file mode 100644 index 00000000..21b99467 --- /dev/null +++ b/maixcdk/doc/dev/vscode_debug.html @@ -0,0 +1,305 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 使用 VSCode 在线调试 - MaixCDK + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

使用 VSCode 在线调试

+ +
+
+
    + +
+
+
+
+ + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

调试

+

这里主要提供 vscode + gdb 的调试方法,看不太懂可以先跳过,可以先使用代码加printf打印的方式调试。

+

(1). 对于在本机(PC)运行,VSCode + GDB 在线调试

+

这里以 PC 为 Linux 系统为例:

+
    +
  • 添加 MaixCDK(第一次试用推荐这样) 或者 工程目录到 VSCode 工作区
  • +
  • 拷贝 tools/vscode/vscode_local_debug/.vscode 目录到上一步的工作目录下
  • +
  • 根据.vscode是在 MaixCDK 还是在工程目录下,修改.vscode/launch.json中的cwd字段
  • +
  • 按键盘 F5 即可开始调试
  • +
+
+

windows 也类似,修改.vscode里面的相关命令和路径即可

+
+

(2). 对于在嵌入式设备(/远程设备,带 Linux 系统)调试

+

使用 VSCode + gdbserver 在嵌入式设备(/远程设备,带 Linux 系统)调试

+

这里以 PC 为 Linux 系统为例:

+
    +
  • 先保证远程设备有gdbserver这个程序,以及 PC 有gdb-multiarch这个程序
  • +
  • tools/vscode/vscode_remote_debug/.vscode 目录拷贝到工程目录下
  • +
  • 编辑 launch.jsonbuild_run_gdbserver.sh 文件,修改里面的路径和命令,以及用户名等。
  • +
+
+

建议先将 PC 的 ssh key 加入到远程设备的 ~/.ssh/authorized_keys 文件中,这样就不需要输入密码了。

+
+
    +
  • 每次调试需要执行 build_run_gdbserver.sh 脚本,然后在 VSCode 中按 F5 即可开始调试
  • +
+
+

脚本会编译工程,然后拷贝可执行文件到远程设备,并且启动 gdbserver
+按 F5 启动调试时, VSCode 使用 GDB 连接到远程设备的gdbserver以调试。

+
+ + +
+
+
+ + +
+
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixcdk/doc/faq.html b/maixcdk/doc/faq.html new file mode 100644 index 00000000..34d356c5 --- /dev/null +++ b/maixcdk/doc/faq.html @@ -0,0 +1,356 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MaixCDK FAQ - MaixCDK + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

MaixCDK FAQ

+ +
+
+
    + +
+
+
+
+ + + + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

You can also find FAQ from:

+ +

Common Compilation Errors and General Solutions

+
    +
  • Errors such as extraction failures: Try deleting the corresponding files in the dl/pkgs and dl/extracted directories, then recompile and download again.

    +
  • +
  • Compilation errors:

    +
      +
    • Run maixcdk build --verbose to see where the error occurs. Carefully check the error log and investigate the issue step by step.
    • +
    • Run maixcdk distclean to clean temporary files, then try recompiling.
    • +
    • Visit the GitHub commit history to check whether the automated tests for each commit passed (a green checkmark ✅ means it passed, a red cross ❌ means it failed). You can switch your local code to a commit that passed the tests ✅ and recompile. Use the command git checkout <commit-hash>, for example: git checkout 3aba2fe3fa9de9f638bb9cb34eca0c2e0f5f3813. If switching fails, you may need to search for Git usage instructions or start over, but make sure to back up any changes you made to your code.
    • +
    +
  • +
+

Downloading ippicv_2021.8_lnx_intel64_20230330_general.tgz takes a long time or fail

+

Manually download according to the log's url, and put it into:
+MaixCDK -> components -> opencv -> opencv4 -> .cache -> ippicv
+The file name is 43219bdc7e3805adcbe3a1e2f1f3ef3b-ippicv_2021.8_lnx_intel64_20230330_general.tgz,
+File name and url can also be found in MaixCDK/components/3rd_party/opencv/opencv4/3rdparty/ippicv/ippicv.cmake

+

So the same as ade cache file .cache/ade/4f93a0844dfc463c617d83b09011819a-v0.1.2b.zip

+

Exception: parse_api_from_header **.hpp error: 'members'

+

API comment not complete.
+e.g.

+ +
/**
+ * Class for communication protocol
+ */
+class CommProtocol
+{
+    /**
+     * Read data to buffer, and try to decode it as maix.protocol.MSG object
+     * @return decoded data, if nullptr, means no valid frame found.
+     *         Attentioin, delete it after use in C++.
+     * @maixpy maix.comm.CommProtocol.get_msg
+     */
+    protocol::MSG *get_msg();
+}
+
+

Here class CommProtocol not add @maixpy maix.comm.CommProtocol but its method get_msg add it.
+So we add @maixpy maix.comm.CommProtocol to class CommProtocol comment will fix this error.

+

Build OpenSSL Error when using WSL( Windows Subsystem Layer)

+

When I add openssl to my project
+a0cee88e7a7a747c2d34eadb31a925bd
+build fail occured:

+

3b42197634ee4cd6a7b0462636e8dd34

+

Use "maixcdk build --verbose" to check . I found that windows path polluted wsl path . and there are "(" and space in path ,which make configure of openssl fail .

+

Fix : fix the path :

+

edit wsl.conf in wsl

+ +
sudo nano /etc/wsl.conf
+
+

create the file if no exist. add the content below :

+ +

+[interop]
+appendWindowsPath = false
+
+

restart wsl

+ +
wsl --shutdown Ubuntu
+
+

9a86a628630209725d362f07b51ecb9a

+

path is fixed ,openssl configure succ

+

d6e43b3bf8e5c68d9966636464b08a43

+ + +
+
+ +
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixcdk/doc/index.html b/maixcdk/doc/index.html new file mode 100644 index 00000000..c1bd358e --- /dev/null +++ b/maixcdk/doc/index.html @@ -0,0 +1,431 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Quick Start with MaixCDK - MaixCDK + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

Quick Start with MaixCDK

+ +
+
+
    + +
+
+
+
+ + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

Introduction to MaixCDK

+

MaixCDK provides C++ APIs for commonly used AI functions related to image processing, vision, audio, and peripherals, enabling quick prototyping and stable product development.

+

MaixCDK is not only a C++ SDK but also auto-generates Python API bindings, so development can be done in Python through MaixPy.

+

Basic Linux knowledge and a fundamental understanding of cross-compilation are required to use MaixCDK.

+

Basic Knowledge

+

To use MaixCDK, it is assumed that you are already familiar with the following knowledge. If not, please learn them first or consider using MaixPy:

+
    +
  • Proficient in using Linux for development, familiar with the terminal and common commands.
  • +
  • Proficient in either C or C++ programming language. C++ proficiency is not required, but you must understand the basic syntax and object-oriented concepts.
  • +
  • Able to actively read and analyze source code to troubleshoot issues.
  • +
  • Chinese developers should be familiar with using network proxies.
  • +
  • Understand cross-compilation.
  • +
+

How to Find Resources and Troubleshoot

+
    +
  1. Read MaixCDK source code.
  2. +
  3. Since MaixCDK shares the same functionality/API as MaixPy, detailed tutorials are not provided separately. Refer to the MaixPy documentation; the principles and code are nearly identical, requiring only minor modifications.
  4. +
  5. It’s recommended to get hands-on experience with MaixPy before using MaixCDK for a smoother learning curve.
  6. +
  7. Carefully review the official documentation, including MaixCDK, MaixPy, and hardware documentation.
  8. +
  9. If issues arise, start by checking MaixCDK FAQ, MaixPy FAQ, MaixCAM Hardware FAQ, and the source code issues.
  10. +
  11. Check out the MaixHub Share Plaza for community insights.
  12. +
  13. Read error logs carefully and patiently, following logs from top to bottom, as errors might appear in the middle—don’t skip ahead hastily!
  14. +
+

Quick Start

+

Setting Up the System and Environment

+

Two options are available:

+

Local Machine:

+

Only supported on Linux, with Ubuntu >= 20.04 recommended.
+Note that the MaixCAM toolchain only supports x86_64 CPUs and is not compatible with ARM-based computers, such as ARM MacOS.

+ +
sudo apt update
+sudo apt install git cmake build-essential python3 python3-pip autoconf automake libtool
+cmake --version # cmake version should be >= 3.13
+
+
+

To compile for a Linux PC (instead of cross-compiling for a dev board), if you’re using Ubuntu, ensure the system version is >=20.04, or some dependencies may be too outdated to compile. Install dependencies following the commands in the Dockerfile.
+If compilation errors occur, consider using Docker to compile.

+
+

Docker:

+

The Docker environment includes ubuntu20.04 and dependencies, making it ready for compilation. For users familiar with Docker or those facing issues with local setup, refer to the Docker Usage Guide.

+

Obtaining the Source Code

+ +
git clone https://github.com/Sipeed/MaixCDK
+
+
+
    +
  • Stable Release versions can be downloaded from the release page.
  • +
  • Alternatively, check MaixPy release assets for maixcdk_version_xxxxx.txt, where xxxxx indicates the MaixPy version in use. Use git checkout xxxx to switch to the corresponding version.
  • +
+
+
+

For users in China experiencing slow clone speeds, use git clone https://gitee.com/Sipeed/MaixCDK.

+
+

Installing Dependencies

+ +
cd MaixCDK
+pip install -U pip                     # Update pip to the latest version
+pip install -U -r requirements.txt     # Install dependencies
+
+
+

Users in China can add the parameter -i https://pypi.tuna.tsinghua.edu.cn/simple to use the Tsinghua mirror.
+Dependencies are already installed in the Docker environment, but you can update them to the latest version within the Docker container.

+
+

Run maixtool and maixcdk commands in the terminal to view help information.

+
+

If the commands are not found, try restarting the terminal or use find / -name "maixtool" to locate maixtool, then set it in the system path using export PATH=directory_containing_maixtool:$PATH.

+
+

Compilation

+ +
cd examples/hello_world
+maixcdk menuconfig
+
+

Follow the prompts to select the device platform. A menu appears to configure parameters. For first-time use, the default parameters are fine (or skip menuconfig and go straight to build), then press ESC, and Y to save and exit.

+ +
maixcdk build
+
+

The first time you run this step, the device will download the compilation toolchain. If the download is slow, you can manually download it to the specified directory as prompted, and then proceed with the compilation.

+
+

The resources are mostly downloaded from GitHub, and download speeds in China may be slow or even fail (the list of files to download is in dl/pkgs_info.json). There are several common solutions:

+
    +
  1. Set a proxy in the terminal (recommended), for example: export http_proxy=http://127.0.0.1:8123 https_proxy=http://127.0.0.1:8123. Here, http://127.0.0.1:8123 is the address of your HTTP proxy.
  2. +
  3. Manually download to the dl/pkgs folder: During the download, the download URL and local path will be printed. You can manually download the files and place them in the corresponding directory. When you run the build command again, it will use the locally prepared files (Note: the file’s sha256 checksum must match, i.e., it must be the same file).
  4. +
  5. Users in China can go to the QQ Group on the homepage, find the MaixCDK folder, and download the files to the MaixCDK/dl directory.
  6. +
+
+
+

For common errors and solutions, refer to the FAQ.

+
+

After the compilation, you will find the binary program files in the build directory, and the dependent .so files in build/dl_lib.

+

After modifying the code, you can run maixcdk build again to compile.

+

If you haven’t added or removed source files, you can run maixcdk build2 or maixcdk build --no-gen for faster compilation (it will only compile the modified files).

+
+

This is because the build command starts the entire build process from scratch, scanning files and recompiling. In contrast, the build2 command will not scan for file additions or deletions and will only compile the edited files.
+Note: The build2 command will not detect file additions or deletions, so if you add or remove files, you must run the build command again.

+
+

Run maixcdk distclean to clear all temporary build files and start fresh (this increases build time and is typically used to troubleshoot issues).

+

Uploading to the Device

+

Copy the executable and dl_lib folder to the device for execution.

+

Use scp to copy files, for example:

+ +
scp -r dist/ root@10.127.117.1:/root/
+
+

The default password is root.

+

Running the Program

+

Run the program via SSH. Ensure no other programs are running (including the startup application launcher).
+Steps:

+
    +
  • Connect MaixVision to the device to close the Launcher, or use SSH to kill the launcher_daemon.
  • +
  • SSH into the device, e.g., ssh root@192.168.0.123, password root.
  • +
  • Navigate to the executable directory and run it, e.g., cd /root/dist/camera_display_release && ./camera_display.
  • +
+

Packaging for Release

+

In the project directory, use maixcdk -p maixcam release to create a program package for maixcam in the dist folder. This package can be uploaded to the MaixHub App Store.

+

Usage:

+
    +
  • Method 1: Unzip and copy to the device, run chmod +x program_name && ./program_name.
  • +
  • Method 2: Use the App Store application on the device to install from MaixHub.
  • +
  • Method 3: For developers, if the device is connected to the same LAN as the PC, use maixcdk deploy to generate a QR code, which the device can scan to install.
  • +
  • Method 4: Copy the package to the device and install it by running /maixapp/apps/app_store/app_store install xxx.zip.
  • +
+

Application releases should follow the App Development Guidelines.

+

Creating a New Project

+

To create a project:

+ +
maixcdk new
+
+

Development convention

+

To get started with MaixCDK, please begin by reading the MaixCDK Development Guidelines.

+

Adding an API to MaixPy

+

Since MaixPy’s core is largely MaixCDK, adding APIs to MaixPy is straightforward. Just annotate the function with @maixpy maix.xxx.xxxx.

+

For example, to implement the following API:

+ +
from maix import example
+
+result = example.hello("Bob")
+print(result)
+
+

Simply add a declaration in maix_api_example.hpp:

+ +
namespace maix::example
+{
+    /**
+     * @brief say hello to someone
+     * @param[in] name name of someone, string type
+     * @return string type, content is hello + name
+     * @maixpy maix.example.hello
+     */
+    std::string hello(std::string name);
+}
+
+

Then compile the MaixPy project to get an installation package, which can be installed on the device to use the new API—simple, right?

+

For more detailed documentation, refer to Add API.

+ + +
+
+
+ + +
+
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixcdk/doc/more.html b/maixcdk/doc/more.html new file mode 100644 index 00000000..1b334d5a --- /dev/null +++ b/maixcdk/doc/more.html @@ -0,0 +1,285 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 更多 MaixCDK 文档 - MaixCDK + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

更多 MaixCDK 文档

+ +
+
+
    + +
+
+
+
+ + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

MaixCDK 由于是 MaixPy 的大多数 API 底层实现,所以 MaixPy 的文档也适用于 MaixCDK,比如 功能介绍和教程,系统定制等等。

+ + +
+
+ +
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixcdk/doc/sidebar.yaml b/maixcdk/doc/sidebar.yaml new file mode 100644 index 00000000..2be33c51 --- /dev/null +++ b/maixcdk/doc/sidebar.yaml @@ -0,0 +1,36 @@ +items: + - label: Quick start + file: README.md + - label: FAQ + file: faq.md + - label: Convention + collapsed: false + items: + - label: Code Convention + file: convention/README.md + - label: Add New API + file: convention/add_api.md + - label: APP framework + file: convention/app.md + - label: I18N(translation) + file: convention/i18n.md + - label: Communicate protocol + file: convention/protocol.md + - label: NN AI model + file: convention/nn.md + - label: Memory leak check + file: convention/memcheck.md + - label: Docker Evironment + file: dev/docker/README.md + - label: More documentaion + file: more.md + - label: Application Notes + collapsed: false + items: + - label: About These Notes + file: application/README.md + - label: YOLO11 dev note + file: application/ai/yolo11.md + - label: LVGL + file: application/ui/lvgl.md + diff --git a/maixcdk/doc/zh/application/ai/yolo11.html b/maixcdk/doc/zh/application/ai/yolo11.html new file mode 100644 index 00000000..5694db0c --- /dev/null +++ b/maixcdk/doc/zh/application/ai/yolo11.html @@ -0,0 +1,286 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MaixCDK YOLO11 develop notes - MaixCDK + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

MaixCDK YOLO11 develop notes

+ +
+
+
    + +
+
+
+
+ + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

源代码在: MaixCDK/components/nn/include/maix_nn_yolo11.hpp

+

模型来自 ultralytics/ultralytics, 训练和转换模型参考 MaixPy doc customize yolo11

+ + +
+
+ +
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixcdk/doc/zh/application/index.html b/maixcdk/doc/zh/application/index.html new file mode 100644 index 00000000..ca0c060d --- /dev/null +++ b/maixcdk/doc/zh/application/index.html @@ -0,0 +1,286 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MaixCDK 应用笔记 - MaixCDK + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

MaixCDK 应用笔记

+ +
+
+
    + +
+
+
+
+ + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

这些笔记是 MaixCDK 开发者在创建某些功能时记录的开发笔记。

+

如果你想了解更多功能和详细文档,请访问 MaixPy 文档

+ + +
+
+ +
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixcdk/doc/zh/application/peripheral/uart.html b/maixcdk/doc/zh/application/peripheral/uart.html new file mode 100644 index 00000000..0134921d --- /dev/null +++ b/maixcdk/doc/zh/application/peripheral/uart.html @@ -0,0 +1,278 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MaixCDK + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

+ +
+
+
    + +
+
+
+
+ + + + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ + + +
+
+
+ + +
+
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixcdk/doc/zh/application/ui/lvgl.html b/maixcdk/doc/zh/application/ui/lvgl.html new file mode 100644 index 00000000..7f552b8e --- /dev/null +++ b/maixcdk/doc/zh/application/ui/lvgl.html @@ -0,0 +1,295 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 在 MaixCDK 中使用 LVGL - MaixCDK + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

在 MaixCDK 中使用 LVGL

+ +
+
+
    + +
+
+
+
+ + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

运行 gui_lvgl 示例

+
    +
  • 进入 MaixCDK 的 examples/gui_lvgl 目录。
  • +
  • 执行 maixcdk build 来在 PC 上构建项目。
  • +
  • 执行 maixcdk run 来在 PC 上运行项目。
  • +
+

你还可以执行 maixcdk menuconfig 来切换平台,构建适用于其他平台的项目。

+

自定义 UI

+
    +
  • 首先下载并安装 Squareline
  • +
  • 在 Squareline 中创建一个新的 UI 项目。
  • +
  • 编辑你的 UI。
  • +
  • 导出 UI 文件,此时会得到一个 ui 文件夹。
  • +
  • 将所有 UI 文件复制到 examples/gui_lvgl/ui 文件夹。
  • +
  • 运行 maixcdk build 进行构建。
  • +
+ + +
+
+
+ + +
+
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixcdk/doc/zh/config.json b/maixcdk/doc/zh/config.json new file mode 100644 index 00000000..f6dbd997 --- /dev/null +++ b/maixcdk/doc/zh/config.json @@ -0,0 +1,4 @@ +{ + "import": "config_zh", + "name": "MaixCDK 中文文档" +} diff --git a/maixcdk/doc/zh/convention/add_api.html b/maixcdk/doc/zh/convention/add_api.html new file mode 100644 index 00000000..498ec8ed --- /dev/null +++ b/maixcdk/doc/zh/convention/add_api.html @@ -0,0 +1,343 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Add API for MaixCDK / MaixPy - MaixCDK + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

Add API for MaixCDK / MaixPy

+ +
+
+
    + +
+
+
+
+ + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

代码规范

+

请先看代码规范

+

如何添加 API

+

快速开始 中末尾我们提到过通过注释的方式给 MaixPy 添加一个新的 API,看起来非常简单,只需要给 API 函数添加一个注释即可,比如

+ +
namespace maix::example
+{
+    /**
+     * @brief say hello to someone
+     * @param[in] name name of someone, string type
+     * @return string type, content is hello + name
+     * @maixpy maix.example.hello
+     */
+    std::string hello(std::string name);
+}
+
+

然后就可以在 MaixPy 中调用了:

+ +
from maix import example
+
+result = example.hello("Bob")
+print(result)
+
+

为了尽量保证我们添加的 API 对用户可用,我们需要保证以下几个特性:

+
    +
  • API 名字和参数设计合理,通用性、跨平台性强。
  • +
  • API 有注释(编译时会自动生成 API 文档)。
  • +
  • API 不只是 API,有使用介绍文档教程和例程代码。
  • +
+

这里更详细地阐述和规范流程:

+
    +
  • 确认功能,先在MaixPy 文档源码中添加一份使用文档和例程。相当于设计文档,这样做可以避免直接写代码考虑不全后期不停修改 API,同时也有了文档。(这很重要!!!)
  • +
  • 可以在docs/doc/application 目录下找到合适的地方添加一份应用文档,用来记录开发时的一些细节。文件名全小写,单词使用下划线隔开比如peripheral/uart.md 或者ai/yolov2.md
  • +
  • 最好是在开发文档里面注明 API 设计参考了哪些资料或者开源项目,方便大家审阅 API 的通用性和合理性,会更快通过审阅。
  • +
  • 参考[components/basic/include/maix_api_example.hpp],在合适的 component中添加 API,如果是新的组件,尽量先在issues中讨论合理性。
  • +
+
+

注意这里使用了注释来标识 API,方便自动生成文档和MaixPy源码,所以要十分小心,具体请看上面的注释规范说明以及maix_api_example.hpp文件。
+另外为了让在MaixCDK中写的 API能顺利生成 MaixPyAPI,而且因为MaixCDK中不包含 Python.hPybind11.h等跟 Python相关的定义,
+语言自带的类型都是最终由pybind11自动转换的,比如void hello(std::string a, std::vector<int> b) 最终等价 MaixPy 中的def hello(a: str, b: list)
+常见的比如 std::vector对应liststd::map对应dict, std::valarray(作为参数可以接受listbytes, 返回值会变成 list) 和 maix::Bytes(作为参数和返回值都是bytes)对应 bytesstd::function 对应 MaixPy 中的函数等,具体更多可以参考pybind11 文档

+
+
    +
  • examples目录添加一个 C++ 例程,保证它能编译运行。
  • +
  • 编译会自动生成文档,检查 docs/doc/api下生成的文档是否有误,有误则检测修改代码。
  • +
  • 编译测试MaixPy工程基于更新后的 MaixCDK 能否通过,以及查看生成的MaixPy文档是否有误,有误则检测修改代码。
  • +
  • git提交代码到github自己的仓库,等待action自动构建和测试,检查是否有错误,如果有错误,及时修改。
  • +
  • 所有在线测试无误后,提交 PR(Pull Request), 在 githubgithub 分别请求合并到dev分支。
  • +
+

手动添加 MaixPy API

+

上面的方法可以自动生成 MaixPy API,但是在某些场景下可能需要手动添加,比如 参数是特定的类型,以 numpy.array为参数举例:

+
    +
  • MaixPy 项目中的components/maix/include下添加头文件和代码,可以使用和 MaixCDK相同的namespace,比如maix.image.cv2image函数是将numpy数组转化为image.Image对象,具体看convert_image.hpp文件中的定义。
  • +
+

更多参考:

+ + + +
+
+ +
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixcdk/doc/zh/convention/app.html b/maixcdk/doc/zh/convention/app.html new file mode 100644 index 00000000..818e8bf3 --- /dev/null +++ b/maixcdk/doc/zh/convention/app.html @@ -0,0 +1,385 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MaixCDK 应用框架指南 - MaixCDK + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

MaixCDK 应用框架指南

+ +
+
+
    + +
+
+
+
+ + + + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

简介

+

用户使用步骤:

+
    +
  • 设备启动时会自动启动 launcher
  • +
  • 用户选择一个 APP 启动。
  • +
  • 运行选中的 APP。
  • +
  • 用户与 APP 交互。
  • +
  • 用户退出 APP。
  • +
  • launcher 会再次启动并等待用户选择 APP。
  • +
+

用户安装新的 APP:

+
    +
  • 确保设备已连接到互联网(可以在 app_settings APP 中连接 WiFi)。
  • +
  • 打开 maixhub.com/app 查找 APP,点击“下载”按钮,会显示一个二维码和安装码。
  • +
  • 在设备上打开 app_store APP,使用摄像头扫描二维码,或输入安装码来安装 APP。
  • +
  • 返回 launcher,新安装的 APP 会显示在列表中。
  • +
+

打包 APP

+

如果使用 MaixCDK

+
    +
  • 在项目文件夹中创建一个 app.yaml,格式见下文。
  • +
  • 执行 maixcdk release -P maixcam 来为 maixcam 平台打包 APP。
  • +
  • dist 文件夹中会找到一个 app_store_v1.0.0.zip,这是打包好的 APP 文件。
  • +
  • 你可以将这个包上传到 maixhub.com/app 与他人分享。
  • +
  • 或者执行 maixcdk deploy -P maixcam 来启动本地服务器,并显示一个二维码。
  • +
  • 你也可以将这个文件上传到设备,并执行 app_store install app_path.zip 来通过命令安装。
  • +
+

如果使用 MaixPy,你可以使用 MaixVision Workstation 打包 APP,或手动使用 maixtool

+
    +
  • 在项目文件夹中创建一个 app.yaml 文件,格式见下文。
  • +
  • 创建一个 main.py 文件,这是 APP 的入口。
  • +
  • 在此文件夹中执行 maixtool release,将生成 dist/app_id_vx.x.x.zip
  • +
  • 你可以将这个包上传到 maixhub.com/app 与他人分享。
  • +
  • 或者执行 maixtool deploy 来启动本地服务器,并显示一个二维码。
  • +
+

app.yaml 格式:

+ +
id: my_app                         # 唯一 ID,使用小写字母并用下划线分隔单词
+name: My APP
+name[zh]: 我的应用                  # 中文名称
+version: 1.0.0                     # 版本号,格式为 major.minor.patch
+icon: assets/my_app.png            # 图标文件,可以是 png 或 lottie json 文件,或为空
+author: Sipeed Ltd
+desc: My APP description
+desc[zh]: 我的应用描述
+
+#### 包含文件方法 1:
+# 默认情况下,会包含项目目录中的所有文件,除了排除文件
+exclude:       # 不支持正则表达式,.git 和 __pycache__ 总是会被排除
+  - .vscode
+  - compile
+  - build
+  - dist
+# extra_include:
+#   src: dst
+#   build/filename123: filename123
+
+#### 包含文件方法 2:
+# 白名单模式,只包含 files 字典中的文件。
+# 如果没有此键或值为空,将使用方法 1。
+# files:
+#   - assets
+#   - hello.py
+#   - main.py
+
+#### 包含文件方法 2.1:
+# 白名单模式,只包含 files 字典中的文件。
+# 如果没有此键或值为空,将使用方法 1。
+# files:
+#   assets: assets
+
+
+

exclude 为黑名单模式,files 为白名单模式,你可以选择其中一种方式。

+

文件约定

+
    +
  • 所有应用数据存储在 /maixapp
  • +
  • 应用存储在 /maixapp/apps
  • +
  • /maixapp/apps/app.info 为描述已安装应用的 INI 文件。安装和卸载应用会更新此文件。
  • +
+
+

开发者或用户也可以手动复制应用目录到此,并执行 python gen_app_info.py 生成 app.info 文件。

+
+
    +
  • 应用存放在 /maixapp/apps/app_id 文件夹中,每个应用必须包含 app_id 可执行文件,或 main.sh 脚本,或 main.py 脚本。
  • +
  • 启动应用时,launcher 会在 app_id 文件夹中寻找:main.sh -> main.py -> app_id 文件。main.sh 使用 sh 执行,main.py 使用 python3 执行,app_id 直接执行。
  • +
  • 共享数据存储在 /maixapp/share
  • +
  • 图片文件存储在 /maixapp/share/picture
  • +
  • 视频文件存储在 /maixapp/share/video
  • +
  • 临时数据可以存储在 /maixapp/tmp,注意,和 Linux 本身的/tmp 目录不同的是这个目录是在文件系统(SD卡)上的,系统/tmp是在内存上虚拟的文件系统,/tmp读写速度更快但是内存大小受限,大文件以及需要长期记录的日志文件(随着时间推移可能变得比较大)建议放在/maixapp/tmp目录下。
  • +
  • 字体文件存储在 /maixapp/share/font
  • +
  • 图标文件存储在 /maixapp/share/icon
  • +
  • 应用运行时创建的数据文件可以存储在 /maixapp/apps/app_id/data
  • +
  • 所有路径都可以通过 API maix.app.get_xxx_path 获取,更多详情请参考 API 文档或 maix_app.hpp 文件。
  • +
+

切换应用

+

使用 void maix::app::switch_app(const string &app_id, int idx = -1, const std::string &start_param = "") 函数来切换应用。

+

这将退出当前应用并启动另一个应用,并将 start_param 字符串传递给目标应用,目标应用可以通过 maix::app::get_start_param() 获取此参数。

+ + +
+
+ +
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixcdk/doc/zh/convention/i18n.html b/maixcdk/doc/zh/convention/i18n.html new file mode 100644 index 00000000..fea0ce75 --- /dev/null +++ b/maixcdk/doc/zh/convention/i18n.html @@ -0,0 +1,382 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MaixCDK 国际化(i18n)与多语言支持 - MaixCDK + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

MaixCDK 国际化(i18n)与多语言支持

+ +
+
+
    + +
+
+
+
+ + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

你可以使用任何喜欢的国际化库,例如 gettext,它支持 Python 和 C++。

+

此外,我们还提供了一个简单的 i18n 库,适用于简单的使用场景。

+

针对 MaixPy

+

请参阅 MaixPy 国际化文档

+

针对 MaixCDK

+

与 MaixPy 相同,有两种方法可以使用:

+

简单的翻译字典

+

首先确保你的源文件编码为 UTF-8

+ +
#include "maix_i18n.hpp"
+
+const std::map<string, string> locale_zh_dict = {
+    {"out", "输出"},
+    {"hello", "你好"}
+};
+
+const std::map<string, string> locale_ja_dict = {
+    // {"out", "出力"},
+    {"hello", "こんにちは"}
+};
+
+const std::map<string, const std::map<string, string>> locales_dict = {
+    {"zh", locale_zh_dict},
+    {"ja", locale_ja_dict}
+};
+
+i18n::Trans trans(locales_dict);
+
+int main()
+{
+    log::info("系统语言: %s\n", i18n::get_locale().c_str());
+    log::info("%s: %s\n", trans.tr("out").c_str(), trans.tr("hello").c_str());
+
+    trans.set_locale("zh");
+    printf("%s: %s\n", trans.tr("out").c_str(), trans.tr("hello").c_str());
+
+    trans.set_locale("en");
+    printf("%s: %s\n", trans.tr("out").c_str(), trans.tr("hello").c_str());
+
+    trans.set_locale("ja");
+    printf("%s: %s\n", trans.tr("out").c_str(), trans.tr("hello").c_str());
+
+    return 0;
+}
+
+

分离的翻译文件

+

上面的示例适用于少量翻译字符串。如果需要翻译大量字符串,推荐使用此方法:

+
    +
  • 不需要修改源代码即可更换翻译内容,翻译字符串保存在独立的 yaml 文件中。
  • +
  • 更容易定位翻译字符串,支持自动扫描需要翻译的字符串,并自动生成 yaml 文件。
  • +
+ +
err::Err e = trans.load("locales"); // 从 locales 目录加载翻译文件
+err::check_raise(e, "加载翻译 yaml 文件失败");
+
+log::info("系统语言: %s\n", i18n::get_locale().c_str());
+log::info("%s: %s, %s\n", i18n::get_locale().c_str(), trans.tr("out").c_str(), trans.tr("hello").c_str());
+
+trans.set_locale("zh");
+log::info("zh: %s, %s\n", trans.tr("out").c_str(), trans.tr("hello").c_str());
+
+trans.set_locale("en");
+log::info("en: %s, %s\n", trans.tr("out").c_str(), trans.tr("hello").c_str());
+
+trans.set_locale("ja");
+log::info("ja: %s, %s\n", trans.tr("out").c_str(), trans.tr("hello").c_str());
+
+

完整示例请参见 examples/i18n

+

然后执行 maixtool i18n -d . r,这将扫描所有使用 tr()_() 的翻译字符串,生成 locales 目录和翻译文件。手动翻译 locales 中的 yaml 文件后,将其放置在程序旁边并运行。

+

在 LVGL 应用中显示国际化字体

+

查看如何显示自定义字体:https://neucrack.com/p/514

+

使用以下代码:

+ +
LV_FONT_DECLARE(zh_fonts);
+
+static const std::map<string, void*> fonts = {
+    {"zh", (void*)&zh_fonts}
+};
+
+const lv_font_t *get_font_by_locale(const string &locale)
+{
+    const std::map<string, void*>::const_iterator iter = fonts.find(locale);
+    if (iter == fonts.end())
+    {
+        return &zh_fonts;
+    }
+    return (lv_font_t *)iter->second;
+}
+
+

最后,使用国际化字体:

+ +
std::string locale = i18n::get_locale();
+
+lv_obj_set_style_text_font(lv_scr_act(), get_font_by_locale(locale), LV_PART_MAIN);
+
+lv_obj_t *label = lv_label_create(lv_scr_act());
+lv_label_set_text(label, trans.tr("hello").c_str());
+
+ + +
+
+ +
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixcdk/doc/zh/convention/index.html b/maixcdk/doc/zh/convention/index.html new file mode 100644 index 00000000..cc1d4c53 --- /dev/null +++ b/maixcdk/doc/zh/convention/index.html @@ -0,0 +1,387 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MaixCDK 开发准则和指导 - MaixCDK + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

MaixCDK 开发准则和指导

+ +
+
+
    + +
+
+
+
+ + + + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

总体准则

+
    +
  • 简单简洁易用。 不假设用户已经有特定的开发经验,尽量少操作,API 尽量简单,有详细指导文档。
  • +
+
+

比如 相比 让用户自己选择并下载工具链,根据用户选择的平台自动选择并下载工具链更好,入门门槛更低。

+
+
    +
  • 通用性。API 在设计时应该保证能在不同平台通用和统一抽象,如果做不到,那么这个功能可能得再三斟酌是否应该增加。
  • +
  • 统一性。API 风格统一,代码风格统一。
  • +
  • 扩展性。 保证核心功能的同时,尽量提供扩展接口,方便用户扩展。
  • +
  • 深度性。API 足够简单,文档写明原理,源码尽量开源,方便用户深入研究。
  • +
+

源码和二进制文件

+
    +
  • 不用 git 子模块:方便中国用户下载,因为如果子模块在 github,就算对仓库做了镜像,子模块始终还是要去 github 拉取,中国用户会非常缓慢。
  • +
  • 不要往源码仓库放大文件和二进制文件:这会大大增加仓库 git 的大小, git 只擅长管理文本文件,二进制文件采用下一条的方式管理。
  • +
  • 对于第三方库和二进制文件,在编译前自动下载到本地:使用component.py定义在编译开始前需要自动下载到dl/pkgs并自动解压到dl/extracted目录下的文件,这样就能直接在CMakeLists.txt中引用源码了,比如list(APPEND ADD_INCLUDE "${DL_EXTRACTED_PATH}/sunxi_mpp/sunxi-mpp-1.0.0/include")
  • +
+
+

每次编译时会将所有需要下载的文件列表写入到dl/pkgs_info.json,用户有网速问题的可以到官方 QQ 群或者第三方提供的网盘手动下载放到dl/pkgs目录即可,这样可以解决网络环境导致的下载速度慢问题。

+
+
    +
  • 不修改第三方库源码:不修改第三方源码,方便升级第三方库。(如果以后发现有这样的需求可以考虑在解压后增加自动打 patch 的功能)
  • +
+

MaixCDK 架构简介

+

对于普通应用开发者, 必要知识:

+
    +
  • 主要由MaixCDKproject两大部分组成,前者是存放的地方,后者是应用代码存放的地方。
  • +
+

官方的例程和APP都直接放在MaixCDK/examplesMaixCDK/projects目录下,你也可以直接在MaixCDK/projects创建你的应用项目。

+

另外也可以两者分开放,在系统环境变量中加一个变量MAIXCDK_PATH,值为MaixCDK目录比如/home/xxx/MaixCDK,比如编辑~/.bashrc添加export MAIXCDK_PATH=/home/xxx/MaixCDK
+这样项目就可以放其它位置了比如/home/xxx/projects

+
    +
  • 组件:每个功能模块可以封装成一个组件,方便不同应用选择性地使用。

    +
      +
    • 可以看到examples/hello_world中有个main组件,components中有很多组件,还可以自己添加组件,比如hello_world/component1或者hello_world/compoents/component2
    • +
    • 也可以设置环境变量MAIXCDK_EXTRA_COMPONENTS_PATH来指定其它额外的组件库。
    • +
    • 每个组件包含一个CMakeLists.txt来描述组件内容,比如list(APPEND ADD_INCLUDE "include")来指定包含的头文件路径,list(APPEND ADD_SRCS "src/hello.c")来包含源文件,list(APPEND ADD_REQUIREMENTS basic)来依赖其它组件等。
    • +
    • 另外,默认也会到 python site-packages 目录寻找,也就是说,如果你了解 python 库打包,你的组件包可以直接发布到 pypi.org, 这样用户通过pip install maixcdk-xxx 就可以快速安装你的组件包了! 可以参考examples/maixcdk-example组件。
    • +
    +
  • +
  • Kconfig: 带终端界面的可配置项。每个组件下面都可以有一个Kconfig文件,里面可以设置一些配置项,在执行maixcdk menuconfig时就可以看到选项了,保存后会在build/config目录下生成global_config.cmake,global_config.h文件,可以直接在组件的CMakeLists.txtc/cpp文件中使用。Kconfig的语法可以参考其它组件,活话则自行搜索、参考这里等。

    +
  • +
  • 依赖的第三方库: 两种方式,开发者可以自行选择,推荐集成到MaixCDK中的使用方式一,个人开发者发布的组件可以使用方式二。

    +
      +
    • 方式一:依赖的第三方库在编译时会自动被下载到dl文件夹,都在组件CMakeLists.txt中指定需要下载的文件,编译时会将所有需要下载的文件列表写入到dl/pkgs_info.json,这样的好处是遇到网络问题可以手动下载放到对应位置。
    • +
    • 方式二:使用 python package 的方式将源码和资源文件都打包发布到 pypi.org,取名为maixcdk-xxx方便大家搜索到,这样用户通过pip install maixcdk-xxx 就可以快速安装你的组件包了,而且用户也可以在安装时通过-i参数来设置镜像源。可以参考examples/maixcdk-example组件。
    • +
    +
  • +
  • 文档:在docs目录下包含了应用文档和 API 文档, API 文档是从代码自动生成的,不要手动修改,应用文档是具体功能的入门指导文档。

    +
  • +
+

代码风格

+

为了保持 MaixCDK 和 MaixPy API 的统一性,以及方便用户和开发者阅读,简单规范了以下代码风格:

+
    +
  • 函数名:全小写,单词之间用下划线隔开,比如get_name
  • +
  • 变量名:全小写,单词之间用下划线隔开,比如file_path
  • +
  • 类名:大驼峰,某些简单的缩写词可以全大写,比如 Person, YOLOv2, UART, PWM
  • +
  • :全大写,单词之间用下划线隔开,比如MAIXPY_VERSION
  • +
  • 类成员变量:不用加m_前缀,全小写+下划线,比如name,这样方便Python里的API足够简洁。
  • +
  • 类私有成员变量:前面加_,比如_name
  • +
  • 使用类成员变量:因为成员变量没有类似m_开头的明显标识,所以显示地使用this->,比如this->name,而不是name来提高可阅读性。
  • +
  • namespace:所有MaixCDK官方的API都在maix命名空间下,maix下再有一个namespace用来区分不同的功能,可以是一个头文件一个namespace,也可以是一个目录一个namespace,比如比如maix::threadmaix::peripheralmaix::nnmaix::peripheral::uart等。
  • +
+

在生成MaixPy API 时,也会自动生成相应的模块,比如maix.threadmaix.peripheralmaix.nnmaix.peripheral.uart等。

+
    +
  • 源文件命名:全小写,单词之间用下划线隔开,比如maix_peripheral_uart.cppC++ 头文件使用.hpp后缀。
  • +
  • 注释API的注释使用doxygen风格,参考components/basic/include/maix_api_example.hpp中的使用方法。
  • +
  • API 注释文档:一般需要写以下关键字
      +
    • brief: 一句话描述功能
    • +
    • param: 参数说明,一定要详细说明参数的取值要求(比如取值范围),注意点,不能是简单的参数名称复读,那文档就没什么意义了,还不如不写。也可以加数据方向,比如param[in] a表示a是输入参数,param[out] b表示b是输出参数,param[in,out] c表示c是输入输出参数。
    • +
    • return:返回值说明,一定要详细说明返回值的取值情况(比如取值范围),注意点,同样不能是简单的返回值名称复读。
    • +
    • retval:出了使用return统一说明返回值,也可以用过过个这个关键字来阐述不同返回值的意义,比如@retval 0 success
    • +
    • attention: API 使用的注意点。
    • +
    • maixpy:标识这是一个 MaixPy API,内容为在MaixPy中的包名+变量名,比如maix.examplemaix.example.hellomaix.example.Example.name等。注意加了这个关键词不仅会生成MaixPy API和文档,如果没有同时指定maixcdk关键字,还会用这个名称生成MaixCDKAPI文档
    • +
    • maixcdk: 标识这是一个 MaixCDK API,如果同时存在maixpy关键字则优先使用这个作为MaixCDKAPI名称。比如* @maixcdk maix.example.hello_maixcdk
    • +
    +
  • +
+

另外,对于本 SDK 中特殊的地方,比如为了能正确准确地生成 MaixPy API和文档,需要遵循:

+
    +
  • API 中的类型和默认值需要完整的定义,不省略maix明明空间可以省略,具体地:
      +
    • 命名空间写全, 比如image::Image,而不是Image
    • +
    • 枚举类型写全,比如image::Format::FMT_RGB888,而不是Format::FMT_RGB888或者image::FMT_RGB888或者FMT_RGB888
    • +
    +
  • +
+

API 规范化建议

+
    +
  • 如果 MaixCDK 有的 API, 尽量使用,而不是直接使用第三方 API,方便不同平台移植,比如文件操作用maix_fs.hpp中的 API,而不是直接使用 C++ 的fstream
  • +
  • 打印日志使用maix_log.hpp中的log::info log::debug等 API, 这样在release版本中debug日志会被自动去掉,而且可以通过maixcdk menuconfig来设置日志级别。也方便不同平台移植。
  • +
  • 错误代码使用maix_err.hpp中的err::Err,统一管理所有错误代码,方便用户查找错误原因。
  • +
  • 抛出异常使用maix_err.hpp中的err::Exception,统一管理所有异常,方便用户查找错误原因, 并且需要在 API 注释中说明可能抛出的异常和类型
  • +
  • 对于多个模块有共性的 API,尽量有一个共同特性的基类,其它类继承并实现,比如maix_peripheral_uart.hpp中的UART继承maix_comm.hpp中的通信基类CommBase,这样方便 C++ 开发,也方便编写MaixPy的 API。
  • +
+
+

比如 Display 类,可以直接暴露给 MaixPy 作为 API,由于不同平台实现可能不同,定义一个DisplayBase基类,不同平台实现自己的Display类比如SDL_Display,然后在Display类里面统一调用DisplayBase的 API,这样就可以保证MaixPy的 API 通用性,用户只需要知道Display类,不需要知道下面用了什么具体的实现方法,提高移植性的同时用户使用也更加简单。

+
+ + +
+
+ +
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixcdk/doc/zh/convention/memcheck.html b/maixcdk/doc/zh/convention/memcheck.html new file mode 100644 index 00000000..a881d0d0 --- /dev/null +++ b/maixcdk/doc/zh/convention/memcheck.html @@ -0,0 +1,334 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 内存检查方法 - MaixCDK + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

内存检查方法

+ +
+
+
    + +
+
+
+
+ + + + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

简介

+

使用valgrind工具检查内存泄露、内存越界等问题

+

安装

+ +
sudo apt install valgrind
+
+

使用valgrind

+ +
cd examples/hello_world
+maixcdk build
+
+# 输出简要日志
+valgrind ./build/hello_world
+
+# 输出更详细日志
+# --tool=memcheck:指定工具为memcheck, memcheck是默认工具,该参数可以省略
+# --leak-check=full:详细的显示每个单独的内存泄露信息
+# --log-file=valgrind.log:将内存泄露检查结果输出到指定文件, valgrind.log为自定义的文件名
+valgrind --tool=memcheck --leak-check=full --log-file=valgrind.log ./build/hello_world
+
+

观察valgrind输出日志的方法

+

观察内存泄露摘要信息

+

内存泄露时可以看到类似如下日志

+ +
LEAK SUMMARY:
+   definitely lost: 48 bytes in 3 blocks.   # 一定泄露的内存,例如一级指针指向的内存没有free
+   indirectly lost: 32 bytes in 2 blocks.   # 间接泄露的内存,例如二级指针指向的内存没有free,间接导致二级指针指向的一级指针指向的内存没有free
+     possibly lost: 96 bytes in 6 blocks.
+   still reachable: 64 bytes in 4 blocks.
+        suppressed: 0 bytes in 0 blocks.
+
+

观察内存异常详细信息

+

内存操作有多种异常,可以看到类似如下日志,详情见官方文档查看具体含义。

+ +
8 bytes in 1 blocks are definitely lost in loss record 1 of 14  # 找到内存泄露的位置
+   at 0x........: malloc (vg_replace_malloc.c:...)
+   by 0x........: mk (leak-tree.c:11)
+   by 0x........: main (leak-tree.c:39)
+
+88 (8 direct, 80 indirect) bytes in 1 blocks are definitely lost in loss record 13 of 14
+   at 0x........: malloc (vg_replace_malloc.c:...)
+   by 0x........: mk (leak-tree.c:11)
+   by 0x........: main (leak-tree.c:25)
+
+

遇到无法解决的问题

+

官方文档

+ + +
+
+ +
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixcdk/doc/zh/convention/nn.html b/maixcdk/doc/zh/convention/nn.html new file mode 100644 index 00000000..faf28118 --- /dev/null +++ b/maixcdk/doc/zh/convention/nn.html @@ -0,0 +1,340 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + NN 规范 - MaixCDK + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

NN 规范

+ +
+
+
    + +
+
+
+
+ + + + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

======

+

神经网络模型文件

+

每个 AI 模型都使用 .mud 文件进行描述,这是一种 INI 格式的文件。

+

MUD(Model Universal Description,模型通用描述)文件是一种简单的模型描述格式。

+
+

创建这个文件的原因在于,各种硬件平台的模型格式不同,无法直接加载,我们需要编写多种不同的代码来加载模型。而现在使用 MUD 文件,只需在其中写入模型信息,即可简化模型加载过程。

+
+

MUD 文件定义如下:

+ +
[basic]
+type = cvimodel
+model = model_path_relative_to_mud_file
+
+[extra]
+model_type = classifier
+input_type = bgr
+mean = 103.94, 116.78, 123.68
+scale = 0.017, 0.017, 0.017
+labels = labels.txt
+
+

basic 部分是必需的,extra 部分是可选的。

+
    +
  • basic 部分描述了模型的类型和模型路径。

    +
      +
    • type 表示模型类型,目前支持 MaixCamcvimodel 类型。
    • +
    • model 表示模型的相对路径,相对于 MUD 文件所在位置。
    • +
    +
  • +
  • extra 部分描述了模型的额外信息,应用程序可以通过 model.extra_info() 方法获取。

    +
      +
    • model_type 表示模型的功能类型,如 classifier(分类器)和 yolov2(目标检测),此项为可选。
    • +
    • input_type 表示模型的输入类型,如 bgrgray(灰度图),此项为可选。
    • +
    • mean 表示模型输入的均值,此项为可选。
    • +
    • scale 表示模型输入的缩放比例,此项为可选。
    • +
    • labels 表示模型标签文件的路径,此项为可选。
    • +
    +
  • +
+

当前 MaixCDK 支持的模型类型:

+
    +
  • classifier
  • +
  • classifier_no_top
  • +
  • yolo11
  • +
  • yolov8
  • +
  • yolov5
  • +
  • pp_ocr
  • +
  • retinaface
  • +
  • nanotrack
  • +
  • face_detector
  • +
  • speech
  • +
  • 以及更多类型,详情请参考 components/nn/include 源代码,并搜索 model_type 关键字查看 load 方法。
  • +
+ + +
+
+ +
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixcdk/doc/zh/convention/protocol.html b/maixcdk/doc/zh/convention/protocol.html new file mode 100644 index 00000000..a1d2efe9 --- /dev/null +++ b/maixcdk/doc/zh/convention/protocol.html @@ -0,0 +1,1123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Maix communicate Protocol - MaixCDK + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

Maix communicate Protocol

+ +
+
+
    + +
+
+
+
+ + + + +
+
+ + + +
+
+
+
+ + +
+
+ + +
+ + 更新历史 +
+ + + + + + + + + + + + + + + + + + + +
日期版本作者更新内容
2023-11-281.0.0neucrack + + 设计并编写协议文档和代码 API 实现 + +
+
+
+ +
+
+ +

Maix 串口协议简介

+

运行 MaixCDK 或者 MaixPy 的设备, 除了可以直接使用设备上的触摸屏和按键操作外, 还可以作为模块,可以使用 UART(串口) 或者 I2C 进行通信控制。

+
+

因为 I2C 为主从模式,所以协议都采用问答模式,一问一答,即Request+Response
+对于 UART 协议, 部分功能支持配置主动上报,具体请看协议

+
+

后文会详细阐述通信协议内容。

+

Maix 设备端如何使用

+

开机进入 设置 应用,在 通信 设置里面选择通信接口,有:

+
    +
  • 串口:选择后会使用串口进行通信,串口根据板子决定,波特率默认为115200
  • +
  • TCP:选择后 Maix 设备会启动一个 TCP 服务,主控端可以通过 TCP 连接 Maix 设备,端口默认为5555
  • +
+

然后主控连接上 Maix 设备后,就可以通过协议进行通信了, 主控作为主设备, Maix 设备作为从设备。

+

Maix 设备端开发

+

用提供的maix.comm.CommProtocol类可以很方便实现命令响应,具体参考例程 comm_protocol(C++)或者 comm_protocol.py(MaixPy)。

+

主控端开发

+

主控端根据芯片和开发语言可自行实现协议,在文末附录中有提供模板代码。

+

数据帧

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
header(4B LE)data len(4B LE)(flags+cmd+body+crc)flags(1B)cmd(1B)body(nB)CRC16_IBM(2B LE)(前面所有)
十进制示例3148663466901hello17451
十六进制示例0xBBACCAAA0x000000090x000x01hello0x442B
字节流(十六进制)AA CA AC BB09 00 00 00000168 65 6c 6c 6F2B 44
+
+

注意这里超过一个字节的数据均采用小端(LE)编码,比如这里 data_len0x0000000606在最低位,发送时需要先发送0x06再发送0x00 0x00 0x00
+字符串就按照顺序发即可,比如hello,先发h再发e l l o
+这里的例子,最终发送数据: AA CA AC BB 09 00 00 00 00 01 68 65 6c 6c 6F 2B 44

+
+
    +
  • header: 头,4 字节,用来标识一帧的开始,固定为 4 字节 0xAA 0xCA 0xAC 0xBB, 先发0xAA
  • +
  • data len: 数据长度, 4 字节, 包含了 flags cmd + body + CRC 的长度。
  • +
  • flags: 一个字节,各个位分别表示:
      +
    • 最高位 is_resp: 是否是响应,0代表发送请求,1代表 响应 或者 主动上报(第三高位需要置1)。
    • +
    • 第二高位 resp_ok:
        +
      • 对于请求,保留位。
      • +
      • 对于响应,1表示成功,0表示失败。
      • +
      +
    • +
    • 第三高位 is_report
        +
      • 对于请求,保留位。
      • +
      • 对于响应,1表示主动上报,0表示为响应消息。
      • +
      +
    • +
    • 第 4~6 高位: 保留以后使用。
    • +
    • 低 2位 version: 协议版本,以后修改不兼容的协议才会更改这个版本号,如果修改协议后与当前版本协议兼容则这个版本号不需要升级。目前的版本为 0
    • +
    +
  • +
  • cmd: 基本命令类型,1 字节,已经预先定义了几个命令,看后文命令定义,这些预定义命令的值从 255 逐渐递减,APP 自定义的命令可以从 0 ~ maix.protocol.CMD.CMD_APP_MAX
  • +
  • body: 内容,变长, 长度只要 < (2^32 - 1) 即可,不同的命令对应不同的body,在后面会对每个命令进行详细说明
  • +
  • crc16: CRC 校验值,2 字节, 用以校验帧数据在传输过程中是否出错,使用 CRC IBM 方法计算,可以参见C 代码实现,或者 Python CRC16。和data_len同样两个字节小端存放,传输时先传输低位再传输高位。
  • +
+

编解码的代码见附录:代码

+

请求和响应

+

发送方主动请求

+

数据方向为: 单片机或其它主控设备 -> Maix 设备

+

flags最高位is_resp设置为0body 内容由cmd决定;

+

接收方响应

+

数据方向为: Maix 设备 -> 单片机或其它主控设备

+

flags最高位is_resp设置为1

+
    +
  • 对于成功响应:resp_ok 设置为 1, body 内容由cmd决定, 其中最简单的成功响应即 body 为空。
  • +
  • 对是失败响应:
      +
    • resp_ok设置为 0
    • +
    • body 第一个字节为错误码, 具体的错误码见MaixCDK maix.err.Err
    • +
    • body 后面的字节为错误字符串信息,UTF-8 编码,一般情况下建议用纯英文,提高兼容性。
    • +
    +
  • +
+

每个请求均应有对应的响应,即执行成功或者失败,后面均用RESP_OKRESP_ERR来代替执行成功和失败两种响应。
+RESP_OKbody 字节不说明就是没有,有会单独进行说明。

+

主动上报数据

+

数据方向为: Maix 设备 -> 单片机或其它主控设备

+

需要主控先通过CMD_SET_REPORT命令设置需要主动上报的数据(需要对应的命令支持)

+
+

比如 APP 支持 CMD_GET_TEMP 命令获取温度,主控可以通过 CMD_SET_REPORT 命令设置主动定时上报温度,然后 APP 收到这个命令后,就会定时上报温度,如果 APP 不支持设置CMD_GET_TEMP命令的主动上报,则会响应CMD_ERROR

+
+

flags最高位is_resp设置为1,第三位is_report 设置为 1body 内容由cmd决定。

+

实例

+

举例:

+

单片机与 Maix 设备通过串口连接,默认使用115200波特率。

+

单片机向 Maix 设备请求获取 应用列表,步骤:

+
    +
  1. 根据下方的协议说明,单片机通过串口发送cmd0xF9的请求,即CMD_APP_LISTbody为空。实际字节流:
  2. +
+

AA CA AC BB 04 00 00 00 01 F9 C9 77

+
    +
  1. Maix 设备收到请求后,返回cmd0xF9, flags0x01 | 0x80 | 0x40 => 0xC1的响应(响应flags最高为1所以有|0x80, 成功响应第二高位为1所以有|0x40),body内容为应用列表,具体内容见下方协议说明。假如有两个 APP,实际字节流:
  2. +
+

AA CA AC BB 0A 00 00 00 C1 F9 02 66 61 63 65 00 66 61 63 65 00 F6 06

+

命令定义

+

协议帧中的cmd取值如下:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
命令名含义
CMD_APP_MAX0xC8应用可自定义命令最大值(不含)
CMD_SET_REPORT0xF8设置主动上报
CMD_APP_LIST0xF9应用列表查询
CMD_START_APP0xFA启动应用
CMD_EXIT_APP0xFB退出应用
CMD_CUR_APP_INFO0xFC当前应用信息查询
CMD_APP_INFO0xFD应用信息查询
CMD_KEY0xFE按键模拟消息
CMD_TOUCH0xFF触摸模拟消息
+

注意这里有个 CMD_APP_MAX, 任何 APP 自定义的命令都应该在0 ~ CMD_APP_MAX之间,包含0,不包含CMD_APP_MAX

+

不同的cmd对应不同的请求和响应数据, 以及不同的body,详细协议(主要阐述cmdbody)如下:

+

CMD_SET_REPORT

+

开启或关闭命令主动上报。
+主动上报包括:

+
    +
  1. 有事件时主动上报,比如检测到人脸时主动上报人脸信息。
  2. +
  3. 定时上报,比如每隔 5s 上报一次温度。
  4. +
+

如果定时上报和事件上报同时开启,则事件上报后,定时器重新计时。

+

请求

+

body

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
cmd(1B)on_off(1B)event(1B)timer(4B)
解释需要开启主动上报的命令开关(1 开, 0 关)事件上报(1 开, 0 关)定时上报,单位 ms,不需要定时则设置为 0
例子0x020x015000
+

响应

+

如果相应的命令支持主动上报,则响应RESP_OK,否则响应RESP_ERR,均由应用自行决定。

+

body: 无

+

CMD_APP_LIST

+

获取应用列表

+

请求

+

body 为空

+

响应

+

body:

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
number(1B)app1...app n info
解释应用数量id1 + '\0'结尾的字符串...idn
例子0x02'face\0'...'appn\0'
+

CMD_CUR_APP_INFO

+

获取当前应用信息

+

请求

+

body 为空

+

响应

+

body:

+ + + + + + + + + + + + + + + + + + + + +
idx(1B)app info(id + name + brief)
解释应用序号应用信息(id, 名字(UTF-8 编码),简介(UTF-8 编码))
例子0x00'face\0face\0face detect\0'
+

CMD_APP_INFO

+

获取指定应用信息

+

请求

+

body

+ + + + + + + + + + + + + + + + + + + + +
idx(1B)app_id(nB)
解释应用序号应用 ID
例子0x02'face'
+

idxapp_id 二选一即可

+
    +
  • idx: 应用序号(从0开始),设置为 0xFF 表示不设置
  • +
  • app_id: 应用 ID,如果 idx 设置了,可以不用设置
  • +
+

响应

+

body:

+ + + + + + + + + + + + + + + + + + + + +
idx(1B)app info(id + name + brief)
解释应用序号应用信息(id, 名字(UTF-8 编码),简介(UTF-8 编码))
例子0x00'face\0face\0face detect\0'
+

CMD_START_APP

+

请求启动指定应用,执行此命令会退出当前应用,然后启动指定应用。

+
    +
  • 如果是 APP 收到这个命令,则它需要调用 API maix.app.switch_app 切换 APP。
  • +
+
+

这里存在一个风险,就是如果 APP 没有正确实现响应这个命令,则可以敦促开发者实现这个命令。

+
+
    +
  • 如果时 Launcher 收到这个命令后会启动对应的应用。
  • +
+

请求

+

body

+ + + + + + + + + + + + + + + + + + + + + + + +
idx(1B)app_id(nB)app_func(nB)
解释应用序号(从0开始),设置为 0xFF 表示不设置应用 ID,如果 idx 设置了,可以不用设置该应用存在多个功能时用于指定应用启动时执行的功能
例子0x02'scan''qrcode'
+

idxapp_idapp_func 三个参数如何使用:

+
    +
  • 不带参数启动应用: 单独设置 idx 或者 app_id

    +
  • +
  • 带参数启动应用:

    +
    +

    idx + app_func,设置 idx 后,解释器会将后续的第一个字符串视为 app_func,如果有多个字符串将会返回错误。

    +
    +
    +

    app_id + app_func,不设置 idx,解释器会在后续字符串中查找 app_idapp_func,不符合条件将会返回错误。

    +
    +
  • +
+

响应

+

body: 无

+

CMD_EXIT_APP

+

请求退出当前应用

+

请求

+

body

+

响应

+

body: 无

+

CMD_KEY

+

发送模拟按键请求

+

请求

+

body

+ + + + + + + + + + + + + +
key(4B)value(1B)
键值(小端)取值:0x01(/0x00/0x02)
+
    +
  • key: 键值,4 字节,发送时需要按小端编码,比如0x00000001 发送时的字节流为0x01 0x00 0x00 0x00,支持的取值为:
      +
    • 38: "up"
    • +
    • 40: "down"
    • +
    • 37: "left"
    • +
    • 39: "right"
    • +
    • 108: "enter"
    • +
    • 27: "esc"
    • +
    • 0x01010101: "ok"
    • +
    • 0x02020202: "ret"
    • +
    • 0x03030303: "pre"
    • +
    • 0x04040404: "next"
    • +
    +
  • +
  • value: 按键值, 1 字节
      +
    • 0x01: 按下
    • +
    • 0x00: 释放
    • +
    • 0x02: 长按
    • +
    +
  • +
+

响应

+

body: 无

+

CMD_TOUCH

+

发送模拟触摸请求

+

请求

+

body

+ + + + + + + + + + + + + + + +
xyevent(1B)
x 坐标y 坐标事件
+

event 取值:

+
    +
  • 0x00: 按下
  • +
  • 0x01: 抬起
  • +
  • 0x02: 移动
  • +
+

响应

+

body:无

+

应用(APPS)协议说明

+

相机

+

命令:

+ + + + + + + + + + + + + + + + + +
命令取值含义响应
CMD_SNAP0x01拍照
+

分类器

+

TODO:

+

body说明:
+请求只有一个字节, 代表了命令, 具体如下表:

+ + + + + + + + + + + + + + + + + +
命令取值含义响应
CMD_RECOGNIZE0x01识别物体CMD_APP_CMD
+

响应:

+
    +
  • 命令 CMD_RECOGNIZE 的响应: 响应 cmdCMD_APP_CMD, body:
  • +
+ + + + + + + + + + + + + + + + + +
CMD_RECOGNIZEid(2B uint16 LE)prob(4B float LE)name
CMD_RECOGNIZE 值识别到的 id(下标),小端概率, 浮点型, 小端名字, UTF-8 编码
+

人脸检测

+

TODO:

+

body说明:
+请求只有一个字节, 代表了命令, 具体如下表:

+ + + + + + + + + + + + + + + + + +
命令取值含义响应
CMD_POS0x01检测人脸CMD_APP_CMD
+

响应:

+
    +
  • 命令 CMD_POS 的响应: 响应 cmdCMD_APP_CMD, body:
  • +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
CMD_POSface num(2B LE)prob(4B float LE)x(2B LE)y(2B LE)w(2B LE)h(2B LE)...
CMD_POS 值检测到的人脸数量概率, 浮点型, 小端人脸框左上角横坐标人脸框左上角纵坐标人脸框宽人脸框高剩下的人脸...
+

人脸识别

+

TODO:

+

body说明:
+请求只有一个字节, 代表了命令, 具体如下表:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
命令取值含义响应
CMD_FACES0x01识别人脸CMD_APP_CMD
CMD_USERS0x02查询所有用户CMD_APP_CMD
CMD_RECORD0x03录入人脸CMD_APP_CMD
CMD_REMOVE0x04删除人脸CMD_APP_CMD
+

请求

+

CMD_APP_CMD加一个字节的app_cmd,个别命令有额外的参数,如下:

+
    +
  • 命令 CMD_RECORD 的请求
  • +
+ + + + + + + + + + + + + +
CMD_RECORDuser name
CMD_RECORD 值录制的用户名
+
    +
  • 命令 CMD_REMOVE 的请求
  • +
+ + + + + + + + + + + + + + + +
CMD_REMOVEuser idx(2B int16)user name
CMD_REMOVE 值用户下标, 两字节,小端要删除的用户名
+

下标和用户名二选一

+

响应:

+
    +
  • 命令 CMD_FACES 的响应: 响应 cmdCMD_APP_CMD, body:
  • +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
CMD_FACESface num(2B LE)id(2B)name_len(1B)nameprob(4B float LE)x(2B LE)y(2B LE)w(2B LE)h(2B LE)...
CMD_FACES 值检测到的人脸数量人脸 ID(下标)名字长度名字, UTF-8 编码概率, 浮点型, 小端人脸框左上角横坐标人脸框左上角纵坐标人脸框宽人脸框高剩下的人脸...
+
    +
  • 命令 CMD_USERS 的响应: 响应 cmdCMD_APP_CMD, body:
  • +
+ + + + + + + + + + + + + + + + + + + +
CMD_USERSuser num(2B LE)name_len(1B)name...
CMD_USERS 值用户数量用户名长度名字, UTF-8 编码剩下的用户名...
+
    +
  • 命令 CMD_RECORD 的响应: CMD_OK 或者 CMD_ERROR

    +
  • +
  • 命令 CMD_REMOVE 的响应: CMD_OK 或者 CMD_ERROR

    +
  • +
+

附录:代码

+

C CRC16 IBM

+ +
unsigned short crc16_IBM(unsigned char *ptr, int len)
+{
+    unsigned int i;
+    unsigned short crc = 0x0000;
+
+    while(len--)
+    {
+        crc ^= *ptr++;
+        for (i = 0; i < 8; ++i)
+        {
+            if (crc & 1)
+                crc = (crc >> 1) ^ 0xA001;
+            else
+                crc = (crc >> 1);
+        }
+    }
+
+    return crc;
+}
+
+

或者查表法:

+ +

+const unsigned int crc16_table[256] = {
+    0x0000, 0xc0c1, 0xc181, 0x0140, 0xc301, 0x03c0, 0x0280, 0xc241,
+    0xc601, 0x06c0, 0x0780, 0xc741, 0x0500, 0xc5c1, 0xc481, 0x0440,
+    0xcc01, 0x0cc0, 0x0d80, 0xcd41, 0x0f00, 0xcfc1, 0xce81, 0x0e40,
+    0x0a00, 0xcac1, 0xcb81, 0x0b40, 0xc901, 0x09c0, 0x0880, 0xc841,
+    0xd801, 0x18c0, 0x1980, 0xd941, 0x1b00, 0xdbc1, 0xda81, 0x1a40,
+    0x1e00, 0xdec1, 0xdf81, 0x1f40, 0xdd01, 0x1dc0, 0x1c80, 0xdc41,
+    0x1400, 0xd4c1, 0xd581, 0x1540, 0xd701, 0x17c0, 0x1680, 0xd641,
+    0xd201, 0x12c0, 0x1380, 0xd341, 0x1100, 0xd1c1, 0xd081, 0x1040,
+    0xf001, 0x30c0, 0x3180, 0xf141, 0x3300, 0xf3c1, 0xf281, 0x3240,
+    0x3600, 0xf6c1, 0xf781, 0x3740, 0xf501, 0x35c0, 0x3480, 0xf441,
+    0x3c00, 0xfcc1, 0xfd81, 0x3d40, 0xff01, 0x3fc0, 0x3e80, 0xfe41,
+    0xfa01, 0x3ac0, 0x3b80, 0xfb41, 0x3900, 0xf9c1, 0xf881, 0x3840,
+    0x2800, 0xe8c1, 0xe981, 0x2940, 0xeb01, 0x2bc0, 0x2a80, 0xea41,
+    0xee01, 0x2ec0, 0x2f80, 0xef41, 0x2d00, 0xedc1, 0xec81, 0x2c40,
+    0xe401, 0x24c0, 0x2580, 0xe541, 0x2700, 0xe7c1, 0xe681, 0x2640,
+    0x2200, 0xe2c1, 0xe381, 0x2340, 0xe101, 0x21c0, 0x2080, 0xe041,
+    0xa001, 0x60c0, 0x6180, 0xa141, 0x6300, 0xa3c1, 0xa281, 0x6240,
+    0x6600, 0xa6c1, 0xa781, 0x6740, 0xa501, 0x65c0, 0x6480, 0xa441,
+    0x6c00, 0xacc1, 0xad81, 0x6d40, 0xaf01, 0x6fc0, 0x6e80, 0xae41,
+    0xaa01, 0x6ac0, 0x6b80, 0xab41, 0x6900, 0xa9c1, 0xa881, 0x6840,
+    0x7800, 0xb8c1, 0xb981, 0x7940, 0xbb01, 0x7bc0, 0x7a80, 0xba41,
+    0xbe01, 0x7ec0, 0x7f80, 0xbf41, 0x7d00, 0xbdc1, 0xbc81, 0x7c40,
+    0xb401, 0x74c0, 0x7580, 0xb541, 0x7700, 0xb7c1, 0xb681, 0x7640,
+    0x7200, 0xb2c1, 0xb381, 0x7340, 0xb101, 0x71c0, 0x7080, 0xb041,
+    0x5000, 0x90c1, 0x9181, 0x5140, 0x9301, 0x53c0, 0x5280, 0x9241,
+    0x9601, 0x56c0, 0x5780, 0x9741, 0x5500, 0x95c1, 0x9481, 0x5440,
+    0x9c01, 0x5cc0, 0x5d80, 0x9d41, 0x5f00, 0x9fc1, 0x9e81, 0x5e40,
+    0x5a00, 0x9ac1, 0x9b81, 0x5b40, 0x9901, 0x59c0, 0x5880, 0x9841,
+    0x8801, 0x48c0, 0x4980, 0x8941, 0x4b00, 0x8bc1, 0x8a81, 0x4a40,
+    0x4e00, 0x8ec1, 0x8f81, 0x4f40, 0x8d01, 0x4dc0, 0x4c80, 0x8c41,
+    0x4400, 0x84c1, 0x8581, 0x4540, 0x8701, 0x47c0, 0x4680, 0x8641,
+    0x8201, 0x42c0, 0x4380, 0x8341, 0x4100, 0x81c1, 0x8081, 0x4040,
+};
+
+
+unsigned short crc16_IBM(const unsigned char *ptr,int len)
+{
+    unsigned short crc = 0x0000;
+
+    while(len--)
+    {
+        crc = (crc >> 8) ^ crc16_table[(crc ^ *ptr++) & 0xff];
+    }
+
+    return (crc);
+}
+
+
+ + +
+
+ +
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixcdk/doc/zh/dev/docker/Dockerfile b/maixcdk/doc/zh/dev/docker/Dockerfile new file mode 100644 index 00000000..caddb4e3 --- /dev/null +++ b/maixcdk/doc/zh/dev/docker/Dockerfile @@ -0,0 +1,52 @@ +FROM ubuntu:20.04 + +ENV DEBIAN_FRONTEND noninteractive + +EXPOSE 8888 +EXPOSE 2333 + +RUN dpkg --add-architecture i386 \ + && apt-get -o APT::Retries=3 update -y + +RUN apt-get update \ + && apt-get install -y software-properties-common \ + && add-apt-repository -y ppa:deadsnakes/ppa\ + && apt-get update \ + && apt-get install build-essential vim \ + git libncurses5-dev zlib1g-dev gawk \ + libssl-dev unzip lib32z1 lib32z1-dev lib32stdc++6 libstdc++6 \ + ca-certificates file g++-multilib libc6:i386 locales \ + python3 python3-pip rsync shellcheck \ + libopencv-dev libopencv-contrib-dev \ + libsdl2-dev \ + python3.11 python3.11-venv python3.11-dev \ + unzip wget sudo -y \ + && rm /usr/bin/python3 \ + && ln -s /usr/bin/python3.11 /usr/bin/python3 \ + && python3 -m ensurepip --upgrade \ + && apt-get purge -yq \ + && apt-get autoremove -yq --purge \ + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* \ + && rm -rf /tmp/* + +COPY requirements.txt /tmp/requirements.txt +COPY teedoc_requirements.txt /tmp/teedoc_requirements.txt + +# RUN python3 -m pip install --upgrade pip +# RUN python3 -m pip install cmake teedoc +# RUN python3 -m pip install -r /tmp/requirements.txt +# RUN python3 -m pip install -r /tmp/teedoc_requirements.txt + +RUN python3 -m pip install --upgrade pip -i https://pypi.tuna.tsinghua.edu.cn/simple +RUN python3 -m pip install cmake teedoc -i https://pypi.tuna.tsinghua.edu.cn/simple +RUN python3 -m pip install -r /tmp/requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple +RUN python3 -m pip install -r /tmp/teedoc_requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple + +RUN ln -s /usr/bin/python3 /usr/bin/python + +COPY switch_user.sh /usr/local/bin/switch_user.sh +RUN chmod +x /usr/local/bin/switch_user.sh +ENTRYPOINT ["/usr/local/bin/switch_user.sh"] + + diff --git a/maixcdk/doc/zh/dev/docker/index.html b/maixcdk/doc/zh/dev/docker/index.html new file mode 100644 index 00000000..befbf655 --- /dev/null +++ b/maixcdk/doc/zh/dev/docker/index.html @@ -0,0 +1,357 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MaixCDK Docker 构建环境 - MaixCDK + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

MaixCDK Docker 构建环境

+ +
+
+
    + +
+
+
+
+ + + + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

关于 Docker 和安装 Docker

+

Docker 是一种工具,我们在这里使用它来创建一个干净的 Ubuntu 环境用于构建 MaixCDK。
+使用 Docker,你无需手动安装依赖项,只需创建一个 Docker 容器,一切环境就准备好了。

+

安装 Docker 的文档请参考 Docker 官方文档

+

安装完成后,你可以使用 docker --version 检查是否安装成功。

+

从 Docker Hub 拉取(推荐),或自行构建

+ +
docker pull sipeed/maixcdk-builder
+
+
+

或者你也可以通过 Dockerfile 自行构建:

+ +
docker build --network=host -t maixcdk-builder .
+
+

你也可以通过添加参数使用代理:
+--network=host --build-arg http_proxy=http://127.0.0.1:8123 --build-arg https_proxy=http://127.0.0.1:8123

+
+

创建并运行容器

+

在上一步中我们得到了一个 Docker 系统镜像,现在我们创建一个容器来运行这个镜像。

+ +
docker run -it --network=host --hostname maixcdk-env --name maixcdk-env --env USER=$USER --env UID=`id -u` --env GID=`id -g` --env MAIXCDK_PATH=/home/${USER}/MaixCDK -v /home/${USER}/MaixCDK:/home/${USER}/MaixCDK sipeed/maixcdk-builder
+
+
+

! 不要在命令末尾添加 /bin/bash
+--network=host 表示使用与主机相同的网络。
+--hostname 设置容器的主机名为 maixcdk-env
+--name 设置容器名称为 maixcdk-env,方便使用 docker 命令进行控制。
+USER(主机的用户名)、用户 ID 和组 ID 将与主机的用户信息一致,避免权限问题。
+你可以使用 -v host_dir:container_dir 将你的数据映射到容器中,例如:-v /home/${USER}/MaixCDK:/home/${USER}/MaixCDK -v /home/${USER}/projects:/home/${USER}/projects
+建议将主机目录映射到容器的相同目录,这样查看日志会更方便。
+使用 --env MAIXCDK_PATH=/home/${USER}/MaixCDK 参数设置 MAIXCDK_PATH 环境变量,这样你可以在容器内任何位置编译项目。
+sipeed/maixcdk-builder 是镜像名称,如果你自行构建,请使用 maixcdk-builder

+
+

接下来你可以在容器中使用 shell 命令。默认用户密码为 maixcdk,如果需要修改密码,可以使用以下命令:

+ +
docker exec -it maixcdk-env passwd
+
+

构建 MaixCDK 项目或示例

+

进入容器后,可以根据 MaixCDK 文档使用 shell 命令进行构建。

+ +
cd /MaixCDK/examples/hello_world
+maixcdk build
+maixcdk run
+
+cd ~/projects/my_project
+maixcdk build
+maixcdk run
+
+

停止容器

+ +
docker stop maixcdk-env
+
+

启动容器

+ +
docker start maixcdk-env
+docker attach maixcdk-env
+
+

从主机 shell 执行命令

+ +
docker exec -it --user $USER maixcdk-env "cd /MaixCDK/examples/hello_world && maixcdk build && maixcdk run"
+
+ +
docker exec -it --user $USER maixcdk-env /bin/bash
+
+

删除容器

+ +
docker stop maixcdk-env
+docker rm maixcdk-env
+
+ + +
+
+ +
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixcdk/doc/zh/dev/docker/requirements.txt b/maixcdk/doc/zh/dev/docker/requirements.txt new file mode 100644 index 00000000..01ba693d --- /dev/null +++ b/maixcdk/doc/zh/dev/docker/requirements.txt @@ -0,0 +1,6 @@ +PyYAML +progress +requests +maixtool +pybind11-stubgen + diff --git a/maixcdk/doc/zh/dev/docker/switch_user.sh b/maixcdk/doc/zh/dev/docker/switch_user.sh new file mode 100644 index 00000000..f3776c04 --- /dev/null +++ b/maixcdk/doc/zh/dev/docker/switch_user.sh @@ -0,0 +1,72 @@ +#!/bin/bash + +set -e + +UID=${UID:-""} +GID=${GID:-""} +USER=${USER:-""} + +if [ -z "$USER" ]; then + echo "USER env is required by --env USER=\$USER" + exit 1 +fi + +if [ -z "$UID" ]; then + echo "UID env is required by --env UID=\`id -u\`" + exit 1 +fi + +if [ -z "$GID" ]; then + echo "GID env is required by --env GID=\`id -g\`" + exit 1 +fi + +# if group $USER not exists, add group +if ! grep -q "^$USER:" /etc/group; then + addgroup --gid "$GID" "$USER" +fi + +# if user $UID not exists, add user +if ! grep -q "^$USER:" /etc/passwd; then + adduser --gecos "" --uid "$UID" --gid "$GID" --no-create-home --disabled-password "$USER" + mkdir -p /home/"$USER" + cp -r /etc/skel/. /home/"$USER" + # default password is maixcdk + echo "$USER:maixcdk" | chpasswd + usermod -aG sudo "$USER" +fi +chown "$UID":"$GID" /home/"$USER" + +# add /maixapp directory and chown to $USER +mkdir -p /maixapp +chown "$UID":"$GID" /maixapp + +echo "###########################################################" +echo "##" +echo "## ███ ███ █████ ██ ██ ██ ██████ ██████ ██ ██" +echo "## ████ ████ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██" +echo "## ██ ████ ██ ███████ ██ ███ ██ ██ ██ █████" +echo "## ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██" +echo "## ██ ██ ██ ██ ██ ██ ██ ██████ ██████ ██ ██" +echo "##" +echo "## ${USER}! Welcome to MaixCDK Docker Container!" +echo "###########################################################" +echo "##" + +# if $MAIXCDK_PATH exists and is a directory and is not empty +if [ -n "$MAIXCDK_PATH" ] && [ -d "$MAIXCDK_PATH" ] ; then + echo "## MAIXCDK_PATH is set to '$MAIXCDK_PATH'" +else + echo "## MAIXCDK_PATH is not set or ${MAIXCDK_PATH} not exists" + echo "## Please set MAIXCDK_PATH to MaixCDK path in container" + echo "## e.g. add args \`--env MAIXCDK_PATH=/path/to/MaixCDK -v /path/to/MaixCDK:/path/to/MaixCDK\` to docker run command" +fi +echo "## The default password of user ${USER} is 'maixcdk'" +echo "###########################################################" +echo "" + +cd /home/"$USER" + +su "$USER" + + diff --git a/maixcdk/doc/zh/dev/docker/teedoc_requirements.txt b/maixcdk/doc/zh/dev/docker/teedoc_requirements.txt new file mode 100644 index 00000000..a7202be0 --- /dev/null +++ b/maixcdk/doc/zh/dev/docker/teedoc_requirements.txt @@ -0,0 +1,12 @@ +teedoc-plugin-ad-hint +teedoc-plugin-assets +teedoc-plugin-baidu-tongji +teedoc-plugin-blog +teedoc-plugin-comments-gitalk +teedoc-plugin-google-analytics +teedoc-plugin-google-translate +teedoc-plugin-jupyter-notebook-parser +teedoc-plugin-markdown-parser +teedoc-plugin-search +teedoc-plugin-theme-default +teedoc-plugin-thumbs-up diff --git a/maixcdk/doc/zh/dev/quick_start.html b/maixcdk/doc/zh/dev/quick_start.html new file mode 100644 index 00000000..16cbed3d --- /dev/null +++ b/maixcdk/doc/zh/dev/quick_start.html @@ -0,0 +1,275 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MaixCDK quick start - MaixCDK + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

MaixCDK quick start

+ +
+
+
    + +
+
+
+
+ + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

see quick start

+ + +
+
+
+ + +
+
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixcdk/doc/zh/dev/vscode_debug.html b/maixcdk/doc/zh/dev/vscode_debug.html new file mode 100644 index 00000000..7a1aff34 --- /dev/null +++ b/maixcdk/doc/zh/dev/vscode_debug.html @@ -0,0 +1,305 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 使用 VSCode 在线调试 - MaixCDK + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

使用 VSCode 在线调试

+ +
+
+
    + +
+
+
+
+ + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

调试

+

这里主要提供 vscode + gdb 的调试方法,看不太懂可以先跳过,可以先使用代码加printf打印的方式调试。

+

(1). 对于在本机(PC)运行,VSCode + GDB 在线调试

+

这里以 PC 为 Linux 系统为例:

+
    +
  • 添加 MaixCDK(第一次试用推荐这样) 或者 工程目录到 VSCode 工作区
  • +
  • 拷贝 tools/vscode/vscode_local_debug/.vscode 目录到上一步的工作目录下
  • +
  • 根据.vscode是在 MaixCDK 还是在工程目录下,修改.vscode/launch.json中的cwd字段
  • +
  • 按键盘 F5 即可开始调试
  • +
+
+

windows 也类似,修改.vscode里面的相关命令和路径即可

+
+

(2). 对于在嵌入式设备(/远程设备,带 Linux 系统)调试

+

使用 VSCode + gdbserver 在嵌入式设备(/远程设备,带 Linux 系统)调试

+

这里以 PC 为 Linux 系统为例:

+
    +
  • 先保证远程设备有gdbserver这个程序,以及 PC 有gdb-multiarch这个程序
  • +
  • tools/vscode/vscode_remote_debug/.vscode 目录拷贝到工程目录下
  • +
  • 编辑 launch.jsonbuild_run_gdbserver.sh 文件,修改里面的路径和命令,以及用户名等。
  • +
+
+

建议先将 PC 的 ssh key 加入到远程设备的 ~/.ssh/authorized_keys 文件中,这样就不需要输入密码了。

+
+
    +
  • 每次调试需要执行 build_run_gdbserver.sh 脚本,然后在 VSCode 中按 F5 即可开始调试
  • +
+
+

脚本会编译工程,然后拷贝可执行文件到远程设备,并且启动 gdbserver
+按 F5 启动调试时, VSCode 使用 GDB 连接到远程设备的gdbserver以调试。

+
+ + +
+
+
+ + +
+
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixcdk/doc/zh/faq.html b/maixcdk/doc/zh/faq.html new file mode 100644 index 00000000..df73a593 --- /dev/null +++ b/maixcdk/doc/zh/faq.html @@ -0,0 +1,349 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MaixCDK FAQ - MaixCDK + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

MaixCDK FAQ

+ +
+
+
    + +
+
+
+
+ + + + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

You can also find FAQ from:

+ +

常见编译错误的通用解决方法

+
    +
  • 提示解压失败等错误: 可以尝试删除掉dl/pkgsdl/extracted目录下的对应文件让重新编译下载即可。
  • +
  • 编译报错
      +
    • 执行maixcdk build --verbose 查看哪里报错,仔细看报错日志一步一步探寻问题。
    • +
    • 执行 maixcdk distclean 清理临时文件后重新编译。
    • +
    • github 提交记录处看到每个提交的自动测试是否通过(绿色的勾勾✅就是通过,红色叉叉❌就是失败),可以将本地代码切换到测试通过的提交✅再编译(本地执行git checkout 提交号比如git checkout 3aba2fe3fa9de9f638bb9cb34eca0c2e0f5f3813, 如果切换失败请自行搜索 git 用法或者直接从头来过,注意备份自己修改的代码)。
    • +
    +
  • +
+

Downloading ippicv_2021.8_lnx_intel64_20230330_general.tgz takes a long time or fail

+

Manually download according to the log's url, and put it into:
+MaixCDK -> components -> opencv -> opencv4 -> .cache -> ippicv
+The file name is 43219bdc7e3805adcbe3a1e2f1f3ef3b-ippicv_2021.8_lnx_intel64_20230330_general.tgz,
+File name and url can also be found in MaixCDK/components/3rd_party/opencv/opencv4/3rdparty/ippicv/ippicv.cmake

+

So the same as ade cache file .cache/ade/4f93a0844dfc463c617d83b09011819a-v0.1.2b.zip

+

Exception: parse_api_from_header **.hpp error: 'members'

+

API comment not complete.
+e.g.

+ +
/**
+ * Class for communication protocol
+ */
+class CommProtocol
+{
+    /**
+     * Read data to buffer, and try to decode it as maix.protocol.MSG object
+     * @return decoded data, if nullptr, means no valid frame found.
+     *         Attentioin, delete it after use in C++.
+     * @maixpy maix.comm.CommProtocol.get_msg
+     */
+    protocol::MSG *get_msg();
+}
+
+

Here class CommProtocol not add @maixpy maix.comm.CommProtocol but its method get_msg add it.
+So we add @maixpy maix.comm.CommProtocol to class CommProtocol comment will fix this error.

+

使用WSL编译OpenSSL时出错的修复方法

+

当我在工程中使用openssl时:
+a0cee88e7a7a747c2d34eadb31a925bd

+

编译报错:

+

3b42197634ee4cd6a7b0462636e8dd34

+

用verbose查看命令发现, Path里是包含“(”的,这是windows的Path将WSL的path污染了。

+

参照网上的方法,在WSL中:

+ +
sudo nano /etc/wsl.conf
+
+

如果没有则新建,内容如下:

+ +
[interop]
+appendWindowsPath = false
+
+

重启WSL后, Path干净了。

+

9a86a628630209725d362f07b51ecb9a

+

编译openssl也成功了。

+

d6e43b3bf8e5c68d9966636464b08a43

+ + +
+
+ +
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixcdk/doc/zh/index.html b/maixcdk/doc/zh/index.html new file mode 100644 index 00000000..8f7c2323 --- /dev/null +++ b/maixcdk/doc/zh/index.html @@ -0,0 +1,432 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MaixCDK 快速开始 - MaixCDK + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

MaixCDK 快速开始

+ +
+
+
    + +
+
+
+
+ + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

MaixCDK 基本介绍

+

MaixCDK 使用 C++ 封装了常用的 AI 图像、视觉、语音,外设相关的 API,使用 MaixCDK 可以快速验证产品原型和开发稳定的产品。

+

MaixCDK 不光是一套 C++ SDK,同时会自动生成 Python API 绑定,即可以使用 Python 进行开发,也就是MaixPy

+

使用 MaixCDK 需要基本的 Linux 使用经验和懂交叉编译的基本概念。

+

基础知识

+

要使用 MaixCDK,均假设你已经会以下知识,不会请先自行学习或者请转角使用MaixPy

+
    +
  • 熟练使用 Linux 进行开发,熟悉终端以及常见命令使用。
  • +
  • 熟练掌握 C/C++ 其中一种语言,其中 C++ 可以不熟练但是必须了解基础语法和面向对象概念。
  • +
  • 会主动看源码分析问题。
  • +
  • 中国开发者须了解使用网络代理。
  • +
  • 了解交叉编译。
  • +
+

如何找资料和解决问题

+
    +
  1. 多看 MaixCDK 源码
  2. +
  3. 由于功能 / APIMaixPy 相同,MaixCDK 不再单独提供详细的教程,请参考MaixPy 文档,原理和代码基本一致,稍微转换一下就能使用。
  4. +
  5. 建议不要直接从 MaixCDK 上手,先体验完基本的 MaixPy 使用再使用 MaixCDK 会轻松很多。
  6. +
  7. 多看仔细看官方文档,包括 MaixCDK、MaixPy、硬件文档。
  8. +
  9. 遇到问题先从 MaixCDK FAQ, MaixPy FAQ, MaixCAM 硬件 FAQ 以及源码 issues 等地方找答案。
  10. +
  11. MaixHub 分享广场 看社区成员的经验。
  12. +
  13. 仔细 耐心 看 错误LOG, 从上到下看日志,出错日志有时可能在中间,不要跳过着急!!
  14. +
+

快速开始

+

准备系统和环境

+

两种方式:

+

本机:

+

仅支持 Linux 系统,推荐使用 Ubuntu >= 20.04
+注意 MaixCAM 工具链只支持 x86_64 CPU,不支持 ARM 电脑,特别是如果你是 ARM MacOS 则无法编译过。

+ +
sudo apt update
+sudo apt install git cmake build-essential python3 python3-pip autoconf automake libtool
+cmake --version # cmake 版本应该 >= 3.13
+
+
+

如果你希望编译出来到 Linux PC 上跑,而不是交叉编译到开发板,如果是 Ubuntu,请使用系统版本>=20.04,否则有些依赖包可能会版本太旧无法编译通过,并且按照Dockerfile里面的安装依赖的命令来安装依赖。
+如果编译仍然报错,请使用 Docker 环境进行编译

+
+

Docker:

+

Docker 环境准备好了 ubuntu20.04 系统和依赖,可以直接获取开始编译,Docker 熟悉 或者 搭建本地开发环境遇到问题可以参考。
+详细请看 Docker 环境使用方法

+

获取源码

+ +
git clone https://github.com/Sipeed/MaixCDK
+
+
+
    +
  • 稳定的 Release 版本可以到 release 页面 下载。
  • +
  • 另外也可以看 MaixPy release assets 下的 maixcdk_version_xxxxx.txt, 这个xxxxx 就是 MaixPy 对应 release 使用的版本,可以使用git checkout xxxx来切换到对应的版本。
  • +
+
+
+

中国国内用户可能克隆速度比较慢,可以使用git clone https://gitee.com/Sipeed/MaixCDK

+
+

安装依赖

+ +
cd MaixCDK
+pip install -U pip                     # 更新 pip 到最新版本
+pip install -U -r requirements.txt     # 安装依赖
+
+
+

中国国内可以加-i https://pypi.tuna.tsinghua.edu.cn/simple参数来使用清华源。
+Docker环境里面已经装好了,不过也可以在Docker容器里面执行命令更新到最新版本。

+
+

此时在终端执行maixtoolmaixcdk命令可以看到帮助信息。

+
+

如果报错找不到命令,可以尝试重启终端,或者通过find / -name "maixtool"来找到maixtool命令的位置,然后通过export PATH=maixtool所在目录;$PATH来设置系统环境变量,重启终端就可以执行maixtool命令了。

+
+

编译

+ +
cd examples/hello_world
+maixcdk menuconfig
+
+

根据提示选择设备平台,会出来一个界面可以配置一些参数,初次使用用默认的参数即可(用默认的参数也可以不执行 menuconfig, 直接执行 build 命令),然后按ESC按键,再按Y保存退出。

+ +
maixcdk build
+
+

第一次执行这一步会根据设备下载编译工具链,下载如果太慢,可以根据提示手动下载到提示的目录,然后再执行编译。

+
+

下载的资源基本都是 github 上的,中国国内下载速度可能会比较慢甚至失败(要下载的文件列表在dl/pkgs_info.json),有几种常见解决方法:

+
    +
  1. 终端设置代理(推荐), 比如:export http_proxy=http://127.0.0.1:8123 https_proxy=http://127.0.0.1:8123,这里http://127.0.0.1:8123就是你的http代理的地址。
  2. +
  3. 手动下载到dl/pkgs下:下载时,会打印下载连接和下载到本地的路径,手动下载文件方到对应路径,再次执行编译就会直接使用本地准备好的(注意文件 sha256 校验值必须相同即同一个文件)。
  4. +
  5. 中国国内用户可以到 首页 QQ 群 群文件MaixCDK文件夹下载放到MaixCDK/dl目录下。
  6. +
+
+
+

常见错误和解决方法看FAQ

+
+

编译完后在build目录下可以看到二进制程序文件,以及build/dl_lib下有依赖的so文件。

+

修改了代码后,再次执行maixcdk build即可编译。

+

如果你没有增删源码文件可以执行maixcdk build2 或者 maixcdk build --no-gen 编译会更快(只编译修改了的文件)。

+
+

因为build命令会从头开始构建,扫描文件再编译,build2命令则不会扫描文件增删,直接编译编辑过的文件。
+注意build2命令不会检测到文件增加或者删除,如果增删了文件必须再执行一遍build命令

+
+

也可以执行maixcdk distclean 清除所有编译产生的临时文件以从一个干净的环境开始编译(但是这样构建时间会很长,一般编译出现奇怪的问题可以先尝试这样解决)。

+

上传程序到设备

+

拷贝 可执行文件 和 dl_lib文件夹 到设备运行。

+

可以通过 scp命令来拷贝,比如:

+ +
scp -r dist/ root@10.127.117.1:/root/
+
+

默认密码是root

+

运行

+

通过 ssh 终端运行程序。注意要保证没有程序正在运行(包括开机的应用选择界面(Launcher))。
+具体方法:

+
    +
  • MaixVision 连接设备,这会让 Launcher 退出。也可以在 ssh 终端手动kill launcher_daemon程序。(重要!!
  • +
  • ssh 连接设备,比如 ssh root@192.168.0.123, 密码是 root
  • +
  • 然后到可知性文件目录下执行文件, 比如 cd /root/dist/camera_display_release && ./camera_display
  • +
+

打包发布

+

在工程目录下,使用 maixcdk -p maixcam release 可以为 maixcam 打包一个程序包并且存放在dist目录,可以上传发布到MaixHub 应用商店

+

安装包使用方法:

+
    +
  • 方法一: ssh 终端,直接解压拷贝到设备,执行chmod +x 程序名 && ./程序名即可运行。
  • +
  • 方法二: 在设备运行应用商店应用,在 MaixHub 应用商店 扫码安装。
  • +
  • 方法三: 对于开发者,保证设备已经连到了和电脑所在局域网,在工程目录执行maixcdk deploy 会出现一个二维码, 在设备运行应用商店应用扫码安装。
  • +
  • 方法四: 拷贝安装包到设备,在设备执行/maixapp/apps/app_store/app_store install xxx.zip 即可安装应用。
  • +
+

这里简单提及一下,发布的应用需要遵循APP 开发准则

+

新建工程

+

使用命令创建工程:

+ +
maixcdk new
+
+

为 MaixPy 添加 API

+

因为 MaixPy 底层大多数就是 MaixCDK,而为 MaixPy 添加 API 也非常简单,给函数加一个注释@maixpy maix.xxx.xxxx 就可以了。

+

比如要实现以下 API:

+ +
from maix import example
+
+result = example.hello("Bob")
+print(result)
+
+

只需要在maix_api_example.hpp 中添加声明:

+ +
namespace maix::example
+{
+    /**
+     * @brief say hello to someone
+     * @param[in] name name of someone, string type
+     * @return string type, content is hello + name
+     * @maixpy maix.example.hello
+     */
+    std::string hello(std::string name);
+}
+
+

然后编译MaixPy项目得到 MaixPy 安装包,安装到设备即可使用新的 API 了,简单吧!

+

更详细的文档请看 添加 API

+

开发准则

+

要开始使用 MaixCDK,请从阅读MaixCDK 开发准则 开始。

+ + +
+
+
+ + +
+
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixcdk/doc/zh/more.html b/maixcdk/doc/zh/more.html new file mode 100644 index 00000000..54e5064f --- /dev/null +++ b/maixcdk/doc/zh/more.html @@ -0,0 +1,285 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 更多 MaixCDK 文档 - MaixCDK + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

更多 MaixCDK 文档

+ +
+
+
    + +
+
+
+
+ + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

MaixCDK 由于是 MaixPy 的大多数 API 底层实现,所以 MaixPy 的文档也适用于 MaixCDK,比如 功能介绍和教程,系统定制等等。

+ + +
+
+ +
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixcdk/doc/zh/no_translate.html b/maixcdk/doc/zh/no_translate.html new file mode 100644 index 00000000..d562e124 --- /dev/null +++ b/maixcdk/doc/zh/no_translate.html @@ -0,0 +1,301 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + no_translate_title - MaixCDK + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

no_translate_title

+ +
+
+
    + +
+
+
+
+ + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +
+
no_translate_hint
+
+ visit_hint + +
+
+ +
+ + +
+
+
+ + +
+
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixcdk/doc/zh/sidebar.yaml b/maixcdk/doc/zh/sidebar.yaml new file mode 100644 index 00000000..ed9976cb --- /dev/null +++ b/maixcdk/doc/zh/sidebar.yaml @@ -0,0 +1,35 @@ +items: + - label: 快速开始 + file: README.md + - label: FAQ 常见问题 + file: faq.md + - label: 规范 + collapsed: false + items: + - label: 编码规范 + file: convention/README.md + - label: 添加新 API + file: convention/add_api.md + - label: APP 框架 + file: convention/app.md + - label: I18N(国际化/多语言) + file: convention/i18n.md + - label: Maix 通信协议 + file: convention/protocol.md + - label: NN AI 模型 + file: convention/nn.md + - label: 内存泄漏检测 + file: convention/memcheck.md + - label: Docker 环境 + file: dev/docker/README.md + - label: 更多文档 + file: more.md + - label: 应用笔记 + collapsed: false + items: + - label: 关于本笔记 + file: application/README.md + - label: YOLO11 开发笔记 + file: application/ai/yolo11.md + - label: LVGL + file: application/ui/lvgl.md diff --git a/maixcdk/favicon.ico b/maixcdk/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..3d8e88b1db08b40e0706694fb9d5dec6ef81cdba GIT binary patch literal 3926 zcmeH~`EyfM6vuB;5G||x00Zb$Y15`@Y1*dQ*XF&KK){{=@pFD>y0HXWUDoZ)3o&&^#w2V0xJ<(gAg(yACM`uMIcf47>>F}36#!+ zz~g9ho+YmJlnRu()H<1OJRXCY$wHZPbxma|$Z&9c^J zDsMB>dAqsP&e@t-&e6)`98K()vo@abtWS*k?(fJ1miF=C#r)8Fi#c;7pk0J4(KDOTpx;f)?)-gbj*&m~`wkPPEeFyOErt{Y4Xx{n? z#5xFkd5C>DBsNX}%UN79eu7DLb6^)Rx$aU>s=b6s#yRLekBP=vV4W%P3mT_sN?WJx zEh3iqc!>Enm2Z22&e{jzyqHABYhw?3A7X~Ri>?b8ANHZ-p@6;l0Y`Y$ECmsf_kYYLu{tW2% zS)|Z74Scg2A82?iDLGw(N7;qj`0tPsFIyMWZ@bqqhde7fMuPf2jznFf7|Vyc>#;$trr_=;p|*x0uOo1loe_D{Yed0#8Y>vCf?dJYx=XvtZGAM{nmN4!?3?ap%|%9Odp9oI zUQbAlJxS3uloCCCFvpV?u&O>Gbbr50uG}I;R_!>My6>sU?!T0)JvqE0G3IGv^7bK$ zx4cCPW-%-`ysyA9T zWXJQs_c-uv?h^e>x7hCQ5ioPFKx_og4TDG6<w86FX_pwN?i77qFbvw>w1lyLxBbLFzt831cN_mJ1+Hli5Z}uG0%O`6_zf`a z5?uF}p{?~_g9iLd3+vz5Hy;Q2Oa6CMrTO0+Xl2PGv}D1fdB3c*{&%!uJ`SovOG@$l Qm*?YM`)yw-?#=oB07Z16H2?qr literal 0 HcmV?d00001 diff --git a/maixcdk/index.html b/maixcdk/index.html new file mode 100644 index 00000000..d3306537 --- /dev/null +++ b/maixcdk/index.html @@ -0,0 +1,485 @@ + + + + + + + + + + + + + + + + + + MaixCDK - MaixCDK + + + + + + + + + + +
+
+
+ +
+ +
+ + +
+
+
+ MaixPy Banner +
+

MaixCDK

+

Fast implementation of AI vision and auditory applications

+
+ +
+

GitHub Repo starsApache 2.0GitHub downloads Build MaixCAMTrigger wiki

+
+
+

English | 中文

+
+
+
+

If you like MaixCDK or MaixPy, please give a star ⭐️ to the MaixPy and MaixCDK open source project to encourage us to develop more features.

+
+
+

Simple API Design, AI Image Recognition within 20 Lines of Code

+
+
+ +
#include "maix_nn.hpp"
+#include "maix_camera.hpp"
+#include "maix_display.hpp"
+
+int main()
+{
+    nn::Classifier classifier("/root/models/mobilenetv2.mud");
+    image::Size input_size = classifier.input_size();
+    camera::Camera cam = camera::Camera(input_size.width(), input_size.height(), classifier.input_format());
+    display::Display disp = display::Display();
+
+    char msg[64];
+    while(!app::need_exit())
+    {
+        image::Image *img = cam.read();
+        auto *result = classifier.classify(*img);
+        int max_idx = result->at(0).first;
+        float max_score = result->at(0).second;
+        snprintf(msg, sizeof(msg), "%5.2f: %s", max_score, classifier.labels[max_idx].c_str());
+        img->draw_string(10, 10, msg, image::COLOR_RED);
+        disp.show(*img);
+        delete result;
+        delete img;
+    }
+    return 0;
+}
+
+
+ +
+

Same simple Python API binding

+
+
+ +
from maix import camera, display, image, nn
+
+classifier = nn.Classifier(model="/root/models/mobilenetv2.mud")
+cam = camera.Camera(classifier.input_width(), classifier.input_height(), classifier.input_format())
+disp = display.Display()
+
+while 1:
+    img = cam.read()
+    res = classifier.classify(img)
+    max_idx, max_prob = res[0]
+    msg = f"{max_prob:5.2f}: {classifier.labels[max_idx]}"
+    img.draw_string(10, 10, msg, image.COLOR_RED)
+    disp.show(img)
+
+
+ +
+ +
+

Variety of built-in functions

+

The functionality of MaixCDK is kept in sync with MaixPy, and the MaixPy documentation is also applicable to MaixCDK.

+ +
+ + +
+

Add Python binding in one second

+

Just add comments, then you can use this API in MaixPy!

+
+
+

Python demo code:

+ +
from maix import uart
+
+
+devices = uart.list_devices()
+print(devices)
+
+
+
+
+
+
+
+

MaixCDK implemention in maix_uart.hpp:

+ +
namespace maix::uart {
+    /**
+     * List all UART devices can be directly used.
+     * @return All device path, list type, element is string type
+     * @maixpy maix.uart.list_devices
+     */
+    std::vector<std::string> list_devices();
+}
+
+
+
+
+
+ + +
+

Online AI Training Platform MaixHub

+

No need for AI expertise or expensive training equipment, train models with one click, deploy to MaixCAM with one click.

+
+ +
+ +

Maix Ecosystem

+ +

Community

+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
CommunityAddress
MaixCDK DocumentationMaixCDK Documentation
MaixPy DocumentationMaixPy Documentation
App Storemaixhub.com/app
Project Sharingmaixhub.com/share
BilibiliSearch for MaixCAM or MaixPy on Bilibili
Discussionmaixhub.com/discussion
MaixCDK issuesgithub.com/sipeed/MaixPy/issues
Telegramt.me/maixpy
QQ Group862340358
+
+
+
+ + + +
+
+ + +
+ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixcdk/robots.txt b/maixcdk/robots.txt new file mode 100644 index 00000000..fbd77f3f --- /dev/null +++ b/maixcdk/robots.txt @@ -0,0 +1,2 @@ +User-agent: * +Sitemap: https://wiki.sipeed.com/sitemap.xml diff --git a/maixcdk/sitemap.xml b/maixcdk/sitemap.xml new file mode 100644 index 00000000..72194fc3 --- /dev/null +++ b/maixcdk/sitemap.xml @@ -0,0 +1,531 @@ + + + + https://wiki.sipeed.com/maixcdk/doc/convention/add_api.html + 2024-12-18 + weekly + 1.0 + + + https://wiki.sipeed.com/maixcdk/doc/dev/vscode_debug.html + 2024-12-18 + weekly + 1.0 + + + https://wiki.sipeed.com/maixcdk/doc/dev/docker/index.html + 2024-12-18 + weekly + 1.0 + + + https://wiki.sipeed.com/maixcdk/doc/index.html + 2024-12-18 + weekly + 1.0 + + + https://wiki.sipeed.com/maixcdk/doc/faq.html + 2024-12-18 + weekly + 1.0 + + + https://wiki.sipeed.com/maixcdk/doc/more.html + 2024-12-18 + weekly + 1.0 + + + https://wiki.sipeed.com/maixcdk/doc/dev/quick_start.html + 2024-12-18 + weekly + 1.0 + + + https://wiki.sipeed.com/maixcdk/doc/application/ai/yolo11.html + 2024-12-18 + weekly + 1.0 + + + https://wiki.sipeed.com/maixcdk/doc/application/index.html + 2024-12-18 + weekly + 1.0 + + + https://wiki.sipeed.com/maixcdk/doc/application/ui/lvgl.html + 2024-12-18 + weekly + 1.0 + + + https://wiki.sipeed.com/maixcdk/doc/application/peripheral/uart.html + 2024-12-18 + weekly + 1.0 + + + https://wiki.sipeed.com/maixcdk/doc/convention/i18n.html + 2024-12-18 + weekly + 1.0 + + + https://wiki.sipeed.com/maixcdk/doc/convention/protocol.html + 2023-11-28 + weekly + 1.0 + + + https://wiki.sipeed.com/maixcdk/doc/convention/app.html + 2024-12-18 + weekly + 1.0 + + + https://wiki.sipeed.com/maixcdk/doc/convention/memcheck.html + 2024-12-18 + weekly + 1.0 + + + https://wiki.sipeed.com/maixcdk/doc/convention/index.html + 2024-12-18 + weekly + 1.0 + + + https://wiki.sipeed.com/maixcdk/doc/convention/nn.html + 2024-12-18 + weekly + 1.0 + + + https://wiki.sipeed.com/maixcdk/api/maix/ext_dev/fp5510.html + 2024-12-18 + weekly + 1.0 + + + https://wiki.sipeed.com/maixcdk/api/maix/ext_dev/mlx90640.html + 2024-12-18 + weekly + 1.0 + + + https://wiki.sipeed.com/maixcdk/api/maix/ext_dev/axp2101.html + 2024-12-18 + weekly + 1.0 + + + https://wiki.sipeed.com/maixcdk/api/maix/ext_dev/qmi8658.html + 2024-12-18 + weekly + 1.0 + + + https://wiki.sipeed.com/maixcdk/api/maix/ext_dev/tmc2209.html + 2024-12-18 + weekly + 1.0 + + + https://wiki.sipeed.com/maixcdk/api/maix/ext_dev/pmu.html + 2024-12-18 + weekly + 1.0 + + + https://wiki.sipeed.com/maixcdk/api/maix/ext_dev/imu.html + 2024-12-18 + weekly + 1.0 + + + https://wiki.sipeed.com/maixcdk/api/maix/log.html + 2024-12-18 + weekly + 1.0 + + + https://wiki.sipeed.com/maixcdk/api/maix/nn/F.html + 2024-12-18 + weekly + 1.0 + + + https://wiki.sipeed.com/maixcdk/api/maix/camera.html + 2024-12-18 + weekly + 1.0 + + + https://wiki.sipeed.com/maixcdk/api/index.html + 2024-12-18 + weekly + 1.0 + + + https://wiki.sipeed.com/maixcdk/api/maix/peripheral.html + 2024-12-18 + weekly + 1.0 + + + https://wiki.sipeed.com/maixcdk/api/maix/tracker.html + 2024-12-18 + weekly + 1.0 + + + https://wiki.sipeed.com/maixcdk/api/maix/util.html + 2024-12-18 + weekly + 1.0 + + + https://wiki.sipeed.com/maixcdk/api/maix/tensor.html + 2024-12-18 + weekly + 1.0 + + + https://wiki.sipeed.com/maixcdk/api/maix/touchscreen.html + 2024-12-18 + weekly + 1.0 + + + https://wiki.sipeed.com/maixcdk/api/maix/example.html + 2024-12-18 + weekly + 1.0 + + + https://wiki.sipeed.com/maixcdk/api/maix/time.html + 2024-12-18 + weekly + 1.0 + + + https://wiki.sipeed.com/maixcdk/api/maix/sys.html + 2024-12-18 + weekly + 1.0 + + + https://wiki.sipeed.com/maixcdk/api/maix/network/wifi.html + 2024-12-18 + weekly + 1.0 + + + https://wiki.sipeed.com/maixcdk/api/maix/modbus.html + 2024-12-18 + weekly + 1.0 + + + https://wiki.sipeed.com/maixcdk/api/maix/comm/modbus.html + 2024-12-18 + weekly + 1.0 + + + https://wiki.sipeed.com/maixcdk/api/maix/modbus/Slave.html + 2024-12-18 + weekly + 1.0 + + + https://wiki.sipeed.com/maixcdk/api/maix/rtmp.html + 2024-12-18 + weekly + 1.0 + + + https://wiki.sipeed.com/maixcdk/api/maix/video.html + 2024-12-18 + weekly + 1.0 + + + https://wiki.sipeed.com/maixcdk/api/maix/nn.html + 2024-12-18 + weekly + 1.0 + + + https://wiki.sipeed.com/maixcdk/api/maix/http.html + 2024-12-18 + weekly + 1.0 + + + https://wiki.sipeed.com/maixcdk/api/maix/peripheral/pwm.html + 2024-12-18 + weekly + 1.0 + + + https://wiki.sipeed.com/maixcdk/api/maix/peripheral/wdt.html + 2024-12-18 + weekly + 1.0 + + + https://wiki.sipeed.com/maixcdk/api/maix/peripheral/uart.html + 2024-12-18 + weekly + 1.0 + + + https://wiki.sipeed.com/maixcdk/api/maix/peripheral/adc.html + 2024-12-18 + weekly + 1.0 + + + https://wiki.sipeed.com/maixcdk/api/maix/peripheral/hid.html + 2024-12-18 + weekly + 1.0 + + + https://wiki.sipeed.com/maixcdk/api/maix/peripheral/gpio.html + 2024-12-18 + weekly + 1.0 + + + https://wiki.sipeed.com/maixcdk/api/maix/peripheral/spi.html + 2024-12-18 + weekly + 1.0 + + + https://wiki.sipeed.com/maixcdk/api/maix/peripheral/timer.html + 2024-12-18 + weekly + 1.0 + + + https://wiki.sipeed.com/maixcdk/api/maix/peripheral/i2c.html + 2024-12-18 + weekly + 1.0 + + + https://wiki.sipeed.com/maixcdk/api/maix/peripheral/key.html + 2024-12-18 + weekly + 1.0 + + + https://wiki.sipeed.com/maixcdk/api/maix/peripheral/pinmap.html + 2024-12-18 + weekly + 1.0 + + + https://wiki.sipeed.com/maixcdk/api/maix/ext_dev/bm8563.html + 2024-12-18 + weekly + 1.0 + + + https://wiki.sipeed.com/maixcdk/api/maix/audio.html + 2024-12-18 + weekly + 1.0 + + + https://wiki.sipeed.com/maixcdk/api/maix/err.html + 2024-12-18 + weekly + 1.0 + + + https://wiki.sipeed.com/maixcdk/api/maix/fs.html + 2024-12-18 + weekly + 1.0 + + + https://wiki.sipeed.com/maixcdk/api/maix/network.html + 2024-12-18 + weekly + 1.0 + + + https://wiki.sipeed.com/maixcdk/api/maix/thread.html + 2024-12-18 + weekly + 1.0 + + + https://wiki.sipeed.com/maixcdk/api/maix/i18n.html + 2024-12-18 + weekly + 1.0 + + + https://wiki.sipeed.com/maixcdk/api/maix/image.html + 2024-12-18 + weekly + 1.0 + + + https://wiki.sipeed.com/maixcdk/api/maix/display.html + 2024-12-18 + weekly + 1.0 + + + https://wiki.sipeed.com/maixcdk/api/maix/protocol.html + 2024-12-18 + weekly + 1.0 + + + https://wiki.sipeed.com/maixcdk/api/maix/uvc.html + 2024-12-18 + weekly + 1.0 + + + https://wiki.sipeed.com/maixcdk/api/maix/app.html + 2024-12-18 + weekly + 1.0 + + + https://wiki.sipeed.com/maixcdk/api/maix/ext_dev.html + 2024-12-18 + weekly + 1.0 + + + https://wiki.sipeed.com/maixcdk/api/maix/comm.html + 2024-12-18 + weekly + 1.0 + + + https://wiki.sipeed.com/maixcdk/api/maix/rtsp.html + 2024-12-18 + weekly + 1.0 + + + https://wiki.sipeed.com/maixcdk/doc/zh/convention/add_api.html + 2024-12-18 + weekly + 1.0 + + + https://wiki.sipeed.com/maixcdk/doc/zh/dev/vscode_debug.html + 2024-12-18 + weekly + 1.0 + + + https://wiki.sipeed.com/maixcdk/doc/zh/dev/docker/index.html + 2024-12-18 + weekly + 1.0 + + + https://wiki.sipeed.com/maixcdk/doc/zh/index.html + 2024-12-18 + weekly + 1.0 + + + https://wiki.sipeed.com/maixcdk/doc/zh/faq.html + 2024-12-18 + weekly + 1.0 + + + https://wiki.sipeed.com/maixcdk/doc/zh/more.html + 2024-12-18 + weekly + 1.0 + + + https://wiki.sipeed.com/maixcdk/doc/zh/dev/quick_start.html + 2024-12-18 + weekly + 1.0 + + + https://wiki.sipeed.com/maixcdk/doc/zh/application/ai/yolo11.html + 2024-12-18 + weekly + 1.0 + + + https://wiki.sipeed.com/maixcdk/doc/zh/application/index.html + 2024-12-18 + weekly + 1.0 + + + https://wiki.sipeed.com/maixcdk/doc/zh/application/ui/lvgl.html + 2024-12-18 + weekly + 1.0 + + + https://wiki.sipeed.com/maixcdk/doc/zh/application/peripheral/uart.html + 2024-12-18 + weekly + 1.0 + + + https://wiki.sipeed.com/maixcdk/doc/zh/convention/i18n.html + 2024-12-18 + weekly + 1.0 + + + https://wiki.sipeed.com/maixcdk/doc/zh/convention/protocol.html + 2023-11-28 + weekly + 1.0 + + + https://wiki.sipeed.com/maixcdk/doc/zh/convention/app.html + 2024-12-18 + weekly + 1.0 + + + https://wiki.sipeed.com/maixcdk/doc/zh/convention/memcheck.html + 2024-12-18 + weekly + 1.0 + + + https://wiki.sipeed.com/maixcdk/doc/zh/convention/index.html + 2024-12-18 + weekly + 1.0 + + + https://wiki.sipeed.com/maixcdk/doc/zh/convention/nn.html + 2024-12-18 + weekly + 1.0 + + + https://wiki.sipeed.com/maixcdk/doc/zh/no_translate.html + 2024-12-18 + weekly + 1.0 + + diff --git a/maixcdk/static/css/custom.css b/maixcdk/static/css/custom.css new file mode 100644 index 00000000..9b2f1169 --- /dev/null +++ b/maixcdk/static/css/custom.css @@ -0,0 +1,12 @@ + + +#home_page h1 { + color: #1f8dbf; +} +.dark #home_page h1{ + color: white; +} + +@media screen and (max-width: 900px) { +} + diff --git a/maixcdk/static/css/search/style.css b/maixcdk/static/css/search/style.css new file mode 100644 index 00000000..d482cd10 --- /dev/null +++ b/maixcdk/static/css/search/style.css @@ -0,0 +1,330 @@ +/** + teedoc search plugin css + @author neucrack + @copyright (c) neucrack CZD666666@gmail.com with MIT License + @changes 2021.2.1 add basic attrributes + */ +.blur { + -webkit-filter: blur(9px); + filter: blur(9px); +} +.pointer { + cursor: pointer; +} +.dark #search { + background-color: #2d2d2d; +} +#search { + border-radius: 2em; + background-color: #f1f1f1; + display: flex; + flex-direction: row; + justify-content: center; + align-items: center; + transition: 0.4s; +} + +#search .icon { + transition: transform 0.4s linear; + background: url("/maixcdk/static/image/search/search.svg"); + background-size: contain; + background-repeat: no-repeat; + background-position: center; + align-self: center; + min-height: 1.8rem; + min-width: 1.8rem; + transition: 0.2s; +} +#search .placeholder { + padding: 0 1em; + color: #a5a5a5; +} +#search_hints { + display: none; +} + +#search_wrapper { + display: none; + position: fixed; + top: 0; + bottom: 0; + left: 0; + right: 0; + background-color: rgba(0, 0, 0, 0.73); + z-index: 100; +} +.dark #search_wrapper { + background-color: transparent; +} +#search_wrapper input:focus{ + outline: none; + border: 1px solid #58b195; +} +#search_wrapper .close { + background: url("/maixcdk/static/image/search/close.svg"); + background-size: contain; + background-repeat: no-repeat; + background-position: center; + border-radius: 0.5em; + min-height: 2.5rem; + min-width: 2.5rem; + z-index: 100; + position: fixed; + top: 3em; + right: 3em; + cursor: pointer; +} +#search_title { + margin: 1em; +} +#search_wrapper #search_title > div { + display: flex; + flex-direction: row; + justify-content: center; +} +#search_wrapper input { + height: 60px; + width: 60%; + border: none; + border-radius: 0.5em; + margin: 0; + text-align: center; + color: #222222; + font-size: 1.2em; + display: inline-block; + box-shadow: 0 0 12px 0 #e8e8e8; +} +.dark #search_wrapper input { + box-shadow: 0 0 12px 0 #000000; + background-color: black; + color: white; +} +#search_wrapper > div { + display: flex; + height: 100%; +} +#search_wrapper #search_content { + display: flex; + flex-direction: column; + width: 75%; + height: 100%; + background-color: white; + margin: auto; + padding: 0; + border-radius: 0.5em; +} +.dark #search_wrapper #search_content { + background-color: #3c3c3c; +} +#search_result { + height: 100%; + display: flex; + flex-direction: row; + overflow: auto; +} +#search_result h1 { + font-size: 1.2em; +} +#search_result_name { + overflow-y: auto; + min-width: max-content; +} +#search_result_content { + overflow-y: auto; + flex-grow: 1; +} +#search_result ul { + padding-left: 0; + list-style: none; +} +#search_result li { + box-shadow: 0 0 10px #e0e0e0; + list-style: none; + padding: 1em; + margin: 1em; + border-radius: 0.5em; + transition: 0.4s; + background-color: white; +} +.dark #search_result li { + background-color: #2d2d2d; + box-shadow: 0 0 2px #000000; +} +#search_result #search_result_name li { + margin: 0.5em 1em 0.5em 0; + background: #4caf7d; + color: white; + border-radius: 0; +} +.dark #search_result #search_result_name li { + background: #1b4c33; +} +#search_result #search_result_name li:hover { + margin-right: 0; +} +#search_result li:hover { + box-shadow: 0px 5px 14px #868686; +} +.dark #search_result li:hover{ + box-shadow: 0px 5px 14px #1d1d1d; +} + +#search_result code { + background-color: #4caf7d; + color: white; + border-radius: 0.2em; + padding: 0.1em; +} +#search_result .loading_hint { + color: red; +} +#search_curr_result { + margin-top: 0; + padding-bottom: 3em; + border: 1px solid #4caf7d; + border-radius: 5px; +} +#search_others_result { + padding-bottom: 3em; + border: 1px solid #bdbdbd; + border-radius: 5px; +} +.dark #search_curr_result { + border: 1px solid #1b4c33; +} +.dark #search_others_result { + border: 1px solid #696969; +} +#search_curr_result:first-child, +#search_others_result:first-child { + border-radius: 5px; +} +#search_result .hint { + height: 2em; + color: white; + font-size: 1.5em; + display: flex; + justify-content: center; + flex-direction: column; + text-align: center; + border-top: none; + box-shadow: 0 6px 7px rgba(76, 175, 125, 0.38); + background: #4caf7d; +} +.dark #search_result .hint { + background: #1b4c33; +} +#search_curr_result > .hint { + background-color: #4caf7d; +} +#search_curr_result .searching { + background-color: #ff9800; +} +.search_highlight { + background-color: #FFEB3B; + border-radius: 0.2em; + padding: 0.1em; + +} +.dark .search_highlight{ + color: #1b1b1b; +} +.selected_highlight { + background-color: #ff9823; +} + +#search_ctrl_btn { + position: fixed; + top: 2em; + right: 1em; + display: flex; + flex-direction: row; + z-index: 999; + user-select: none; +} +#search_ctrl_btn > div { + border-radius: 0.2em; + min-width: 5em; + min-height: 2.5em; + background-color: #fae94e; + margin: 0.2em; + display: flex; + flex-direction: row; + align-items: center; + justify-content: center; + padding: 0.2em; + cursor: pointer; + box-shadow: 0 0 12px 0 rgb(0, 0, 0, 0.06); + transition: 0.4s; + color: #8b7000; +} +#search_ctrl_btn > div:hover { + box-shadow: 0 0 12px 0 rgb(0, 0, 0, 0.2); +} +#search_ctrl_btn > .previous .icon { + background-image: url("/static/image/search/up.svg"); + -ms-transform: rotate(270deg); + -moz-transform: rotate(270deg); + -webkit-transform: rotate(270deg); + transform: rotate(270deg); + background-size: 2em; + background-repeat: no-repeat; + background-position: center; + min-height: 1.5em; + min-width: 1.5em; + height: 1.5em; + width: 1.5em; +} +#search_ctrl_btn > .next .icon { + background-image: url("/static/image/search/up.svg"); + -ms-transform: rotate(90deg); + -moz-transform: rotate(90deg); + -webkit-transform: rotate(90deg); + transform: rotate(90deg); + background-size: 2em; + background-repeat: no-repeat; + background-position: center; + min-height: 1.5em; + min-width: 1.5em; + height: 1.5em; + width: 1.5em; +} + +#remove_search > .icon { + background-image: url("/static/image/search/cancel.svg"); + background-size: 2em; + background-repeat: no-repeat; + background-position: center; + min-height: 1.5em; + min-width: 1.5em; + height: 1.5em; + width: 1.5em; +} + + +@media screen and (max-width: 900px) { + #search_wrapper #search_content { + width: 100%; + height: 100%; + border-radius: 0; + } + #search_wrapper input { + font-size: 0.8em; + } + #search_wrapper .close { + top: 1.5em; + right: 1em; + } + #search_result li { + margin: 0; + } + #search_result #search_result_name li { + font-size: 0.8em; + } + #search_curr_result > .hint { + font-size: 1.2em; + } + #search_result .hint { + font-size: 1.2em; + } +} diff --git a/maixcdk/static/css/tailwind.css b/maixcdk/static/css/tailwind.css new file mode 100644 index 00000000..d705193e --- /dev/null +++ b/maixcdk/static/css/tailwind.css @@ -0,0 +1,63 @@ +(()=>{var Sb=Object.create;var li=Object.defineProperty;var Cb=Object.getOwnPropertyDescriptor;var Ab=Object.getOwnPropertyNames;var _b=Object.getPrototypeOf,Eb=Object.prototype.hasOwnProperty;var uu=i=>li(i,"__esModule",{value:!0});var fu=i=>{if(typeof require!="undefined")return require(i);throw new Error('Dynamic require of "'+i+'" is not supported')};var C=(i,e)=>()=>(i&&(e=i(i=0)),e);var v=(i,e)=>()=>(e||i((e={exports:{}}).exports,e),e.exports),Ae=(i,e)=>{uu(i);for(var t in e)li(i,t,{get:e[t],enumerable:!0})},Ob=(i,e,t)=>{if(e&&typeof e=="object"||typeof e=="function")for(let r of Ab(e))!Eb.call(i,r)&&r!=="default"&&li(i,r,{get:()=>e[r],enumerable:!(t=Cb(e,r))||t.enumerable});return i},K=i=>Ob(uu(li(i!=null?Sb(_b(i)):{},"default",i&&i.__esModule&&"default"in i?{get:()=>i.default,enumerable:!0}:{value:i,enumerable:!0})),i);var m,l=C(()=>{m={platform:"",env:{},versions:{node:"14.17.6"}}});var Tb,te,ze=C(()=>{l();Tb=0,te={readFileSync:i=>self[i]||"",statSync:()=>({mtimeMs:Tb++}),promises:{readFile:i=>Promise.resolve(self[i]||"")}}});var Xn=v((X5,pu)=>{l();"use strict";var cu=class{constructor(e={}){if(!(e.maxSize&&e.maxSize>0))throw new TypeError("`maxSize` must be a number greater than 0");if(typeof e.maxAge=="number"&&e.maxAge===0)throw new TypeError("`maxAge` must be a number greater than 0");this.maxSize=e.maxSize,this.maxAge=e.maxAge||1/0,this.onEviction=e.onEviction,this.cache=new Map,this.oldCache=new Map,this._size=0}_emitEvictions(e){if(typeof this.onEviction=="function")for(let[t,r]of e)this.onEviction(t,r.value)}_deleteIfExpired(e,t){return typeof t.expiry=="number"&&t.expiry<=Date.now()?(typeof this.onEviction=="function"&&this.onEviction(e,t.value),this.delete(e)):!1}_getOrDeleteIfExpired(e,t){if(this._deleteIfExpired(e,t)===!1)return t.value}_getItemValue(e,t){return t.expiry?this._getOrDeleteIfExpired(e,t):t.value}_peek(e,t){let r=t.get(e);return this._getItemValue(e,r)}_set(e,t){this.cache.set(e,t),this._size++,this._size>=this.maxSize&&(this._size=0,this._emitEvictions(this.oldCache),this.oldCache=this.cache,this.cache=new Map)}_moveToRecent(e,t){this.oldCache.delete(e),this._set(e,t)}*_entriesAscending(){for(let e of this.oldCache){let[t,r]=e;this.cache.has(t)||this._deleteIfExpired(t,r)===!1&&(yield e)}for(let e of this.cache){let[t,r]=e;this._deleteIfExpired(t,r)===!1&&(yield e)}}get(e){if(this.cache.has(e)){let t=this.cache.get(e);return this._getItemValue(e,t)}if(this.oldCache.has(e)){let t=this.oldCache.get(e);if(this._deleteIfExpired(e,t)===!1)return this._moveToRecent(e,t),t.value}}set(e,t,{maxAge:r=this.maxAge===1/0?void 0:Date.now()+this.maxAge}={}){this.cache.has(e)?this.cache.set(e,{value:t,maxAge:r}):this._set(e,{value:t,expiry:r})}has(e){return this.cache.has(e)?!this._deleteIfExpired(e,this.cache.get(e)):this.oldCache.has(e)?!this._deleteIfExpired(e,this.oldCache.get(e)):!1}peek(e){if(this.cache.has(e))return this._peek(e,this.cache);if(this.oldCache.has(e))return this._peek(e,this.oldCache)}delete(e){let t=this.cache.delete(e);return t&&this._size--,this.oldCache.delete(e)||t}clear(){this.cache.clear(),this.oldCache.clear(),this._size=0}resize(e){if(!(e&&e>0))throw new TypeError("`maxSize` must be a number greater than 0");let t=[...this._entriesAscending()],r=t.length-e;r<0?(this.cache=new Map(t),this.oldCache=new Map,this._size=t.length):(r>0&&this._emitEvictions(t.slice(0,r)),this.oldCache=new Map(t.slice(r)),this.cache=new Map,this._size=0),this.maxSize=e}*keys(){for(let[e]of this)yield e}*values(){for(let[,e]of this)yield e}*[Symbol.iterator](){for(let e of this.cache){let[t,r]=e;this._deleteIfExpired(t,r)===!1&&(yield[t,r.value])}for(let e of this.oldCache){let[t,r]=e;this.cache.has(t)||this._deleteIfExpired(t,r)===!1&&(yield[t,r.value])}}*entriesDescending(){let e=[...this.cache];for(let t=e.length-1;t>=0;--t){let r=e[t],[n,a]=r;this._deleteIfExpired(n,a)===!1&&(yield[n,a.value])}e=[...this.oldCache];for(let t=e.length-1;t>=0;--t){let r=e[t],[n,a]=r;this.cache.has(n)||this._deleteIfExpired(n,a)===!1&&(yield[n,a.value])}}*entriesAscending(){for(let[e,t]of this._entriesAscending())yield[e,t.value]}get size(){if(!this._size)return this.oldCache.size;let e=0;for(let t of this.oldCache.keys())this.cache.has(t)||e++;return Math.min(this._size+e,this.maxSize)}};pu.exports=cu});var du,hu=C(()=>{l();du=i=>i&&i._hash});function ui(i){return du(i,{ignoreUnknown:!0})}var mu=C(()=>{l();hu()});function Xe(i){if(i=`${i}`,i==="0")return"0";if(/^[+-]?(\d+|\d*\.\d+)(e[+-]?\d+)?(%|\w+)?$/.test(i))return i.replace(/^[+-]?/,t=>t==="-"?"":"-");let e=["var","calc","min","max","clamp"];for(let t of e)if(i.includes(`${t}(`))return`calc(${i} * -1)`}var fi=C(()=>{l()});var gu,yu=C(()=>{l();gu=["preflight","container","accessibility","pointerEvents","visibility","position","inset","isolation","zIndex","order","gridColumn","gridColumnStart","gridColumnEnd","gridRow","gridRowStart","gridRowEnd","float","clear","margin","boxSizing","lineClamp","display","aspectRatio","height","maxHeight","minHeight","width","minWidth","maxWidth","flex","flexShrink","flexGrow","flexBasis","tableLayout","captionSide","borderCollapse","borderSpacing","transformOrigin","translate","rotate","skew","scale","transform","animation","cursor","touchAction","userSelect","resize","scrollSnapType","scrollSnapAlign","scrollSnapStop","scrollMargin","scrollPadding","listStylePosition","listStyleType","listStyleImage","appearance","columns","breakBefore","breakInside","breakAfter","gridAutoColumns","gridAutoFlow","gridAutoRows","gridTemplateColumns","gridTemplateRows","flexDirection","flexWrap","placeContent","placeItems","alignContent","alignItems","justifyContent","justifyItems","gap","space","divideWidth","divideStyle","divideColor","divideOpacity","placeSelf","alignSelf","justifySelf","overflow","overscrollBehavior","scrollBehavior","textOverflow","hyphens","whitespace","wordBreak","borderRadius","borderWidth","borderStyle","borderColor","borderOpacity","backgroundColor","backgroundOpacity","backgroundImage","gradientColorStops","boxDecorationBreak","backgroundSize","backgroundAttachment","backgroundClip","backgroundPosition","backgroundRepeat","backgroundOrigin","fill","stroke","strokeWidth","objectFit","objectPosition","padding","textAlign","textIndent","verticalAlign","fontFamily","fontSize","fontWeight","textTransform","fontStyle","fontVariantNumeric","lineHeight","letterSpacing","textColor","textOpacity","textDecoration","textDecorationColor","textDecorationStyle","textDecorationThickness","textUnderlineOffset","fontSmoothing","placeholderColor","placeholderOpacity","caretColor","accentColor","opacity","backgroundBlendMode","mixBlendMode","boxShadow","boxShadowColor","outlineStyle","outlineWidth","outlineOffset","outlineColor","ringWidth","ringColor","ringOpacity","ringOffsetWidth","ringOffsetColor","blur","brightness","contrast","dropShadow","grayscale","hueRotate","invert","saturate","sepia","filter","backdropBlur","backdropBrightness","backdropContrast","backdropGrayscale","backdropHueRotate","backdropInvert","backdropOpacity","backdropSaturate","backdropSepia","backdropFilter","transitionProperty","transitionDelay","transitionDuration","transitionTimingFunction","willChange","content"]});function wu(i,e){return i===void 0?e:Array.isArray(i)?i:[...new Set(e.filter(r=>i!==!1&&i[r]!==!1).concat(Object.keys(i).filter(r=>i[r]!==!1)))]}var bu=C(()=>{l()});var vu={};Ae(vu,{default:()=>_e});var _e,ci=C(()=>{l();_e=new Proxy({},{get:()=>String})});function Kn(i,e,t){typeof m!="undefined"&&m.env.JEST_WORKER_ID||t&&xu.has(t)||(t&&xu.add(t),console.warn(""),e.forEach(r=>console.warn(i,"-",r)))}function Zn(i){return _e.dim(i)}var xu,F,Ee=C(()=>{l();ci();xu=new Set;F={info(i,e){Kn(_e.bold(_e.cyan("info")),...Array.isArray(i)?[i]:[e,i])},warn(i,e){["content-problems"].includes(i)||Kn(_e.bold(_e.yellow("warn")),...Array.isArray(i)?[i]:[e,i])},risk(i,e){Kn(_e.bold(_e.magenta("risk")),...Array.isArray(i)?[i]:[e,i])}}});var ku={};Ae(ku,{default:()=>es});function nr({version:i,from:e,to:t}){F.warn(`${e}-color-renamed`,[`As of Tailwind CSS ${i}, \`${e}\` has been renamed to \`${t}\`.`,"Update your configuration file to silence this warning."])}var es,ts=C(()=>{l();Ee();es={inherit:"inherit",current:"currentColor",transparent:"transparent",black:"#000",white:"#fff",slate:{50:"#f8fafc",100:"#f1f5f9",200:"#e2e8f0",300:"#cbd5e1",400:"#94a3b8",500:"#64748b",600:"#475569",700:"#334155",800:"#1e293b",900:"#0f172a",950:"#020617"},gray:{50:"#f9fafb",100:"#f3f4f6",200:"#e5e7eb",300:"#d1d5db",400:"#9ca3af",500:"#6b7280",600:"#4b5563",700:"#374151",800:"#1f2937",900:"#111827",950:"#030712"},zinc:{50:"#fafafa",100:"#f4f4f5",200:"#e4e4e7",300:"#d4d4d8",400:"#a1a1aa",500:"#71717a",600:"#52525b",700:"#3f3f46",800:"#27272a",900:"#18181b",950:"#09090b"},neutral:{50:"#fafafa",100:"#f5f5f5",200:"#e5e5e5",300:"#d4d4d4",400:"#a3a3a3",500:"#737373",600:"#525252",700:"#404040",800:"#262626",900:"#171717",950:"#0a0a0a"},stone:{50:"#fafaf9",100:"#f5f5f4",200:"#e7e5e4",300:"#d6d3d1",400:"#a8a29e",500:"#78716c",600:"#57534e",700:"#44403c",800:"#292524",900:"#1c1917",950:"#0c0a09"},red:{50:"#fef2f2",100:"#fee2e2",200:"#fecaca",300:"#fca5a5",400:"#f87171",500:"#ef4444",600:"#dc2626",700:"#b91c1c",800:"#991b1b",900:"#7f1d1d",950:"#450a0a"},orange:{50:"#fff7ed",100:"#ffedd5",200:"#fed7aa",300:"#fdba74",400:"#fb923c",500:"#f97316",600:"#ea580c",700:"#c2410c",800:"#9a3412",900:"#7c2d12",950:"#431407"},amber:{50:"#fffbeb",100:"#fef3c7",200:"#fde68a",300:"#fcd34d",400:"#fbbf24",500:"#f59e0b",600:"#d97706",700:"#b45309",800:"#92400e",900:"#78350f",950:"#451a03"},yellow:{50:"#fefce8",100:"#fef9c3",200:"#fef08a",300:"#fde047",400:"#facc15",500:"#eab308",600:"#ca8a04",700:"#a16207",800:"#854d0e",900:"#713f12",950:"#422006"},lime:{50:"#f7fee7",100:"#ecfccb",200:"#d9f99d",300:"#bef264",400:"#a3e635",500:"#84cc16",600:"#65a30d",700:"#4d7c0f",800:"#3f6212",900:"#365314",950:"#1a2e05"},green:{50:"#f0fdf4",100:"#dcfce7",200:"#bbf7d0",300:"#86efac",400:"#4ade80",500:"#22c55e",600:"#16a34a",700:"#15803d",800:"#166534",900:"#14532d",950:"#052e16"},emerald:{50:"#ecfdf5",100:"#d1fae5",200:"#a7f3d0",300:"#6ee7b7",400:"#34d399",500:"#10b981",600:"#059669",700:"#047857",800:"#065f46",900:"#064e3b",950:"#022c22"},teal:{50:"#f0fdfa",100:"#ccfbf1",200:"#99f6e4",300:"#5eead4",400:"#2dd4bf",500:"#14b8a6",600:"#0d9488",700:"#0f766e",800:"#115e59",900:"#134e4a",950:"#042f2e"},cyan:{50:"#ecfeff",100:"#cffafe",200:"#a5f3fc",300:"#67e8f9",400:"#22d3ee",500:"#06b6d4",600:"#0891b2",700:"#0e7490",800:"#155e75",900:"#164e63",950:"#083344"},sky:{50:"#f0f9ff",100:"#e0f2fe",200:"#bae6fd",300:"#7dd3fc",400:"#38bdf8",500:"#0ea5e9",600:"#0284c7",700:"#0369a1",800:"#075985",900:"#0c4a6e",950:"#082f49"},blue:{50:"#eff6ff",100:"#dbeafe",200:"#bfdbfe",300:"#93c5fd",400:"#60a5fa",500:"#3b82f6",600:"#2563eb",700:"#1d4ed8",800:"#1e40af",900:"#1e3a8a",950:"#172554"},indigo:{50:"#eef2ff",100:"#e0e7ff",200:"#c7d2fe",300:"#a5b4fc",400:"#818cf8",500:"#6366f1",600:"#4f46e5",700:"#4338ca",800:"#3730a3",900:"#312e81",950:"#1e1b4b"},violet:{50:"#f5f3ff",100:"#ede9fe",200:"#ddd6fe",300:"#c4b5fd",400:"#a78bfa",500:"#8b5cf6",600:"#7c3aed",700:"#6d28d9",800:"#5b21b6",900:"#4c1d95",950:"#2e1065"},purple:{50:"#faf5ff",100:"#f3e8ff",200:"#e9d5ff",300:"#d8b4fe",400:"#c084fc",500:"#a855f7",600:"#9333ea",700:"#7e22ce",800:"#6b21a8",900:"#581c87",950:"#3b0764"},fuchsia:{50:"#fdf4ff",100:"#fae8ff",200:"#f5d0fe",300:"#f0abfc",400:"#e879f9",500:"#d946ef",600:"#c026d3",700:"#a21caf",800:"#86198f",900:"#701a75",950:"#4a044e"},pink:{50:"#fdf2f8",100:"#fce7f3",200:"#fbcfe8",300:"#f9a8d4",400:"#f472b6",500:"#ec4899",600:"#db2777",700:"#be185d",800:"#9d174d",900:"#831843",950:"#500724"},rose:{50:"#fff1f2",100:"#ffe4e6",200:"#fecdd3",300:"#fda4af",400:"#fb7185",500:"#f43f5e",600:"#e11d48",700:"#be123c",800:"#9f1239",900:"#881337",950:"#4c0519"},get lightBlue(){return nr({version:"v2.2",from:"lightBlue",to:"sky"}),this.sky},get warmGray(){return nr({version:"v3.0",from:"warmGray",to:"stone"}),this.stone},get trueGray(){return nr({version:"v3.0",from:"trueGray",to:"neutral"}),this.neutral},get coolGray(){return nr({version:"v3.0",from:"coolGray",to:"gray"}),this.gray},get blueGray(){return nr({version:"v3.0",from:"blueGray",to:"slate"}),this.slate}}});function rs(i,...e){for(let t of e){for(let r in t)i?.hasOwnProperty?.(r)||(i[r]=t[r]);for(let r of Object.getOwnPropertySymbols(t))i?.hasOwnProperty?.(r)||(i[r]=t[r])}return i}var Su=C(()=>{l()});function Ke(i){if(Array.isArray(i))return i;let e=i.split("[").length-1,t=i.split("]").length-1;if(e!==t)throw new Error(`Path is invalid. Has unbalanced brackets: ${i}`);return i.split(/\.(?![^\[]*\])|[\[\]]/g).filter(Boolean)}var pi=C(()=>{l()});function J(i,e){return di.future.includes(e)?i.future==="all"||(i?.future?.[e]??Cu[e]??!1):di.experimental.includes(e)?i.experimental==="all"||(i?.experimental?.[e]??Cu[e]??!1):!1}function Au(i){return i.experimental==="all"?di.experimental:Object.keys(i?.experimental??{}).filter(e=>di.experimental.includes(e)&&i.experimental[e])}function _u(i){if(m.env.JEST_WORKER_ID===void 0&&Au(i).length>0){let e=Au(i).map(t=>_e.yellow(t)).join(", ");F.warn("experimental-flags-enabled",[`You have enabled experimental features: ${e}`,"Experimental features in Tailwind CSS are not covered by semver, may introduce breaking changes, and can change at any time."])}}var Cu,di,De=C(()=>{l();ci();Ee();Cu={optimizeUniversalDefaults:!1,generalizedModifiers:!0,get disableColorOpacityUtilitiesByDefault(){return!1},get relativeContentPathsByDefault(){return!1}},di={future:["hoverOnlyWhenSupported","respectDefaultRingColorOpacity","disableColorOpacityUtilitiesByDefault","relativeContentPathsByDefault"],experimental:["optimizeUniversalDefaults","generalizedModifiers"]}});function Eu(i){(()=>{if(i.purge||!i.content||!Array.isArray(i.content)&&!(typeof i.content=="object"&&i.content!==null))return!1;if(Array.isArray(i.content))return i.content.every(t=>typeof t=="string"?!0:!(typeof t?.raw!="string"||t?.extension&&typeof t?.extension!="string"));if(typeof i.content=="object"&&i.content!==null){if(Object.keys(i.content).some(t=>!["files","relative","extract","transform"].includes(t)))return!1;if(Array.isArray(i.content.files)){if(!i.content.files.every(t=>typeof t=="string"?!0:!(typeof t?.raw!="string"||t?.extension&&typeof t?.extension!="string")))return!1;if(typeof i.content.extract=="object"){for(let t of Object.values(i.content.extract))if(typeof t!="function")return!1}else if(!(i.content.extract===void 0||typeof i.content.extract=="function"))return!1;if(typeof i.content.transform=="object"){for(let t of Object.values(i.content.transform))if(typeof t!="function")return!1}else if(!(i.content.transform===void 0||typeof i.content.transform=="function"))return!1;if(typeof i.content.relative!="boolean"&&typeof i.content.relative!="undefined")return!1}return!0}return!1})()||F.warn("purge-deprecation",["The `purge`/`content` options have changed in Tailwind CSS v3.0.","Update your configuration file to eliminate this warning.","https://tailwindcss.com/docs/upgrade-guide#configure-content-sources"]),i.safelist=(()=>{let{content:t,purge:r,safelist:n}=i;return Array.isArray(n)?n:Array.isArray(t?.safelist)?t.safelist:Array.isArray(r?.safelist)?r.safelist:Array.isArray(r?.options?.safelist)?r.options.safelist:[]})(),i.blocklist=(()=>{let{blocklist:t}=i;if(Array.isArray(t)){if(t.every(r=>typeof r=="string"))return t;F.warn("blocklist-invalid",["The `blocklist` option must be an array of strings.","https://tailwindcss.com/docs/content-configuration#discarding-classes"])}return[]})(),typeof i.prefix=="function"?(F.warn("prefix-function",["As of Tailwind CSS v3.0, `prefix` cannot be a function.","Update `prefix` in your configuration to be a string to eliminate this warning.","https://tailwindcss.com/docs/upgrade-guide#prefix-cannot-be-a-function"]),i.prefix=""):i.prefix=i.prefix??"",i.content={relative:(()=>{let{content:t}=i;return t?.relative?t.relative:J(i,"relativeContentPathsByDefault")})(),files:(()=>{let{content:t,purge:r}=i;return Array.isArray(r)?r:Array.isArray(r?.content)?r.content:Array.isArray(t)?t:Array.isArray(t?.content)?t.content:Array.isArray(t?.files)?t.files:[]})(),extract:(()=>{let t=(()=>i.purge?.extract?i.purge.extract:i.content?.extract?i.content.extract:i.purge?.extract?.DEFAULT?i.purge.extract.DEFAULT:i.content?.extract?.DEFAULT?i.content.extract.DEFAULT:i.purge?.options?.extractors?i.purge.options.extractors:i.content?.options?.extractors?i.content.options.extractors:{})(),r={},n=(()=>{if(i.purge?.options?.defaultExtractor)return i.purge.options.defaultExtractor;if(i.content?.options?.defaultExtractor)return i.content.options.defaultExtractor})();if(n!==void 0&&(r.DEFAULT=n),typeof t=="function")r.DEFAULT=t;else if(Array.isArray(t))for(let{extensions:a,extractor:s}of t??[])for(let o of a)r[o]=s;else typeof t=="object"&&t!==null&&Object.assign(r,t);return r})(),transform:(()=>{let t=(()=>i.purge?.transform?i.purge.transform:i.content?.transform?i.content.transform:i.purge?.transform?.DEFAULT?i.purge.transform.DEFAULT:i.content?.transform?.DEFAULT?i.content.transform.DEFAULT:{})(),r={};return typeof t=="function"&&(r.DEFAULT=t),typeof t=="object"&&t!==null&&Object.assign(r,t),r})()};for(let t of i.content.files)if(typeof t=="string"&&/{([^,]*?)}/g.test(t)){F.warn("invalid-glob-braces",[`The glob pattern ${Zn(t)} in your Tailwind CSS configuration is invalid.`,`Update it to ${Zn(t.replace(/{([^,]*?)}/g,"$1"))} to silence this warning.`]);break}return i}var Ou=C(()=>{l();De();Ee()});function ie(i){if(Object.prototype.toString.call(i)!=="[object Object]")return!1;let e=Object.getPrototypeOf(i);return e===null||e===Object.prototype}var xt=C(()=>{l()});function Ze(i){return Array.isArray(i)?i.map(e=>Ze(e)):typeof i=="object"&&i!==null?Object.fromEntries(Object.entries(i).map(([e,t])=>[e,Ze(t)])):i}var hi=C(()=>{l()});function ht(i){return i.replace(/\\,/g,"\\2c ")}var mi=C(()=>{l()});var is,Tu=C(()=>{l();is={aliceblue:[240,248,255],antiquewhite:[250,235,215],aqua:[0,255,255],aquamarine:[127,255,212],azure:[240,255,255],beige:[245,245,220],bisque:[255,228,196],black:[0,0,0],blanchedalmond:[255,235,205],blue:[0,0,255],blueviolet:[138,43,226],brown:[165,42,42],burlywood:[222,184,135],cadetblue:[95,158,160],chartreuse:[127,255,0],chocolate:[210,105,30],coral:[255,127,80],cornflowerblue:[100,149,237],cornsilk:[255,248,220],crimson:[220,20,60],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgoldenrod:[184,134,11],darkgray:[169,169,169],darkgreen:[0,100,0],darkgrey:[169,169,169],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkseagreen:[143,188,143],darkslateblue:[72,61,139],darkslategray:[47,79,79],darkslategrey:[47,79,79],darkturquoise:[0,206,209],darkviolet:[148,0,211],deeppink:[255,20,147],deepskyblue:[0,191,255],dimgray:[105,105,105],dimgrey:[105,105,105],dodgerblue:[30,144,255],firebrick:[178,34,34],floralwhite:[255,250,240],forestgreen:[34,139,34],fuchsia:[255,0,255],gainsboro:[220,220,220],ghostwhite:[248,248,255],gold:[255,215,0],goldenrod:[218,165,32],gray:[128,128,128],green:[0,128,0],greenyellow:[173,255,47],grey:[128,128,128],honeydew:[240,255,240],hotpink:[255,105,180],indianred:[205,92,92],indigo:[75,0,130],ivory:[255,255,240],khaki:[240,230,140],lavender:[230,230,250],lavenderblush:[255,240,245],lawngreen:[124,252,0],lemonchiffon:[255,250,205],lightblue:[173,216,230],lightcoral:[240,128,128],lightcyan:[224,255,255],lightgoldenrodyellow:[250,250,210],lightgray:[211,211,211],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightsalmon:[255,160,122],lightseagreen:[32,178,170],lightskyblue:[135,206,250],lightslategray:[119,136,153],lightslategrey:[119,136,153],lightsteelblue:[176,196,222],lightyellow:[255,255,224],lime:[0,255,0],limegreen:[50,205,50],linen:[250,240,230],magenta:[255,0,255],maroon:[128,0,0],mediumaquamarine:[102,205,170],mediumblue:[0,0,205],mediumorchid:[186,85,211],mediumpurple:[147,112,219],mediumseagreen:[60,179,113],mediumslateblue:[123,104,238],mediumspringgreen:[0,250,154],mediumturquoise:[72,209,204],mediumvioletred:[199,21,133],midnightblue:[25,25,112],mintcream:[245,255,250],mistyrose:[255,228,225],moccasin:[255,228,181],navajowhite:[255,222,173],navy:[0,0,128],oldlace:[253,245,230],olive:[128,128,0],olivedrab:[107,142,35],orange:[255,165,0],orangered:[255,69,0],orchid:[218,112,214],palegoldenrod:[238,232,170],palegreen:[152,251,152],paleturquoise:[175,238,238],palevioletred:[219,112,147],papayawhip:[255,239,213],peachpuff:[255,218,185],peru:[205,133,63],pink:[255,192,203],plum:[221,160,221],powderblue:[176,224,230],purple:[128,0,128],rebeccapurple:[102,51,153],red:[255,0,0],rosybrown:[188,143,143],royalblue:[65,105,225],saddlebrown:[139,69,19],salmon:[250,128,114],sandybrown:[244,164,96],seagreen:[46,139,87],seashell:[255,245,238],sienna:[160,82,45],silver:[192,192,192],skyblue:[135,206,235],slateblue:[106,90,205],slategray:[112,128,144],slategrey:[112,128,144],snow:[255,250,250],springgreen:[0,255,127],steelblue:[70,130,180],tan:[210,180,140],teal:[0,128,128],thistle:[216,191,216],tomato:[255,99,71],turquoise:[64,224,208],violet:[238,130,238],wheat:[245,222,179],white:[255,255,255],whitesmoke:[245,245,245],yellow:[255,255,0],yellowgreen:[154,205,50]}});function sr(i,{loose:e=!1}={}){if(typeof i!="string")return null;if(i=i.trim(),i==="transparent")return{mode:"rgb",color:["0","0","0"],alpha:"0"};if(i in is)return{mode:"rgb",color:is[i].map(a=>a.toString())};let t=i.replace(Db,(a,s,o,u,c)=>["#",s,s,o,o,u,u,c?c+c:""].join("")).match(Pb);if(t!==null)return{mode:"rgb",color:[parseInt(t[1],16),parseInt(t[2],16),parseInt(t[3],16)].map(a=>a.toString()),alpha:t[4]?(parseInt(t[4],16)/255).toString():void 0};let r=i.match(Ib)??i.match(qb);if(r===null)return null;let n=[r[2],r[3],r[4]].filter(Boolean).map(a=>a.toString());return n.length===2&&n[0].startsWith("var(")?{mode:r[1],color:[n[0]],alpha:n[1]}:!e&&n.length!==3||n.length<3&&!n.some(a=>/^var\(.*?\)$/.test(a))?null:{mode:r[1],color:n,alpha:r[5]?.toString?.()}}function ns({mode:i,color:e,alpha:t}){let r=t!==void 0;return i==="rgba"||i==="hsla"?`${i}(${e.join(", ")}${r?`, ${t}`:""})`:`${i}(${e.join(" ")}${r?` / ${t}`:""})`}var Pb,Db,et,gi,Pu,tt,Ib,qb,ss=C(()=>{l();Tu();Pb=/^#([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})?$/i,Db=/^#([a-f\d])([a-f\d])([a-f\d])([a-f\d])?$/i,et=/(?:\d+|\d*\.\d+)%?/,gi=/(?:\s*,\s*|\s+)/,Pu=/\s*[,/]\s*/,tt=/var\(--(?:[^ )]*?)\)/,Ib=new RegExp(`^(rgba?)\\(\\s*(${et.source}|${tt.source})(?:${gi.source}(${et.source}|${tt.source}))?(?:${gi.source}(${et.source}|${tt.source}))?(?:${Pu.source}(${et.source}|${tt.source}))?\\s*\\)$`),qb=new RegExp(`^(hsla?)\\(\\s*((?:${et.source})(?:deg|rad|grad|turn)?|${tt.source})(?:${gi.source}(${et.source}|${tt.source}))?(?:${gi.source}(${et.source}|${tt.source}))?(?:${Pu.source}(${et.source}|${tt.source}))?\\s*\\)$`)});function Ie(i,e,t){if(typeof i=="function")return i({opacityValue:e});let r=sr(i,{loose:!0});return r===null?t:ns({...r,alpha:e})}function se({color:i,property:e,variable:t}){let r=[].concat(e);if(typeof i=="function")return{[t]:"1",...Object.fromEntries(r.map(a=>[a,i({opacityVariable:t,opacityValue:`var(${t})`})]))};let n=sr(i);return n===null?Object.fromEntries(r.map(a=>[a,i])):n.alpha!==void 0?Object.fromEntries(r.map(a=>[a,i])):{[t]:"1",...Object.fromEntries(r.map(a=>[a,ns({...n,alpha:`var(${t})`})]))}}var ar=C(()=>{l();ss()});function le(i,e){let t=[],r=[],n=0,a=!1;for(let s=0;s{l()});function yi(i){return le(i,",").map(t=>{let r=t.trim(),n={raw:r},a=r.split(Mb),s=new Set;for(let o of a)Du.lastIndex=0,!s.has("KEYWORD")&&Rb.has(o)?(n.keyword=o,s.add("KEYWORD")):Du.test(o)?s.has("X")?s.has("Y")?s.has("BLUR")?s.has("SPREAD")||(n.spread=o,s.add("SPREAD")):(n.blur=o,s.add("BLUR")):(n.y=o,s.add("Y")):(n.x=o,s.add("X")):n.color?(n.unknown||(n.unknown=[]),n.unknown.push(o)):n.color=o;return n.valid=n.x!==void 0&&n.y!==void 0,n})}function Iu(i){return i.map(e=>e.valid?[e.keyword,e.x,e.y,e.blur,e.spread,e.color].filter(Boolean).join(" "):e.raw).join(", ")}var Rb,Mb,Du,as=C(()=>{l();or();Rb=new Set(["inset","inherit","initial","revert","unset"]),Mb=/\ +(?![^(]*\))/g,Du=/^-?(\d+|\.\d+)(.*?)$/g});function os(i){return Bb.some(e=>new RegExp(`^${e}\\(.*\\)`).test(i))}function U(i,e=!0){return i.startsWith("--")?`var(${i})`:i.includes("url(")?i.split(/(url\(.*?\))/g).filter(Boolean).map(t=>/^url\(.*?\)$/.test(t)?t:U(t,!1)).join(""):(i=i.replace(/([^\\])_+/g,(t,r)=>r+" ".repeat(t.length-1)).replace(/^_/g," ").replace(/\\_/g,"_"),e&&(i=i.trim()),i=Nb(i),i)}function Nb(i){return i.replace(/(calc|min|max|clamp)\(.+\)/g,e=>{let t=[];return e.replace(/var\((--.+?)[,)]/g,(r,n)=>(t.push(n),r.replace(n,qu))).replace(/(-?\d*\.?\d(?!\b-\d.+[,)](?![^+\-/*])\D)(?:%|[a-z]+)?|\))([+\-/*])/g,"$1 $2 ").replace(Fb,()=>t.shift())})}function ls(i){return i.startsWith("url(")}function us(i){return!isNaN(Number(i))||os(i)}function lr(i){return i.endsWith("%")&&us(i.slice(0,-1))||os(i)}function ur(i){return i==="0"||new RegExp(`^[+-]?[0-9]*.?[0-9]+(?:[eE][+-]?[0-9]+)?${$b}$`).test(i)||os(i)}function Ru(i){return jb.has(i)}function Mu(i){let e=yi(U(i));for(let t of e)if(!t.valid)return!1;return!0}function Bu(i){let e=0;return le(i,"_").every(r=>(r=U(r),r.startsWith("var(")?!0:sr(r,{loose:!0})!==null?(e++,!0):!1))?e>0:!1}function Fu(i){let e=0;return le(i,",").every(r=>(r=U(r),r.startsWith("var(")?!0:ls(r)||Vb(r)||["element(","image(","cross-fade(","image-set("].some(n=>r.startsWith(n))?(e++,!0):!1))?e>0:!1}function Vb(i){i=U(i);for(let e of zb)if(i.startsWith(`${e}(`))return!0;return!1}function Nu(i){let e=0;return le(i,"_").every(r=>(r=U(r),r.startsWith("var(")?!0:Ub.has(r)||ur(r)||lr(r)?(e++,!0):!1))?e>0:!1}function Lu(i){let e=0;return le(i,",").every(r=>(r=U(r),r.startsWith("var(")?!0:r.includes(" ")&&!/(['"])([^"']+)\1/g.test(r)||/^\d/g.test(r)?!1:(e++,!0)))?e>0:!1}function $u(i){return Wb.has(i)}function ju(i){return Gb.has(i)}function zu(i){return Hb.has(i)}var Bb,qu,Fb,Lb,$b,jb,zb,Ub,Wb,Gb,Hb,fr=C(()=>{l();ss();as();or();Bb=["min","max","clamp","calc"];qu="--tw-placeholder",Fb=new RegExp(qu,"g");Lb=["cm","mm","Q","in","pc","pt","px","em","ex","ch","rem","lh","rlh","vw","vh","vmin","vmax","vb","vi","svw","svh","lvw","lvh","dvw","dvh","cqw","cqh","cqi","cqb","cqmin","cqmax"],$b=`(?:${Lb.join("|")})`;jb=new Set(["thin","medium","thick"]);zb=new Set(["conic-gradient","linear-gradient","radial-gradient","repeating-conic-gradient","repeating-linear-gradient","repeating-radial-gradient"]);Ub=new Set(["center","top","right","bottom","left"]);Wb=new Set(["serif","sans-serif","monospace","cursive","fantasy","system-ui","ui-serif","ui-sans-serif","ui-monospace","ui-rounded","math","emoji","fangsong"]);Gb=new Set(["xx-small","x-small","small","medium","large","x-large","x-large","xxx-large"]);Hb=new Set(["larger","smaller"])});function Vu(i){let e=["cover","contain"];return le(i,",").every(t=>{let r=le(t,"_").filter(Boolean);return r.length===1&&e.includes(r[0])?!0:r.length!==1&&r.length!==2?!1:r.every(n=>ur(n)||lr(n)||n==="auto")})}var Uu=C(()=>{l();fr();or()});function Wu(i,e){i.walkClasses(t=>{t.value=e(t.value),t.raws&&t.raws.value&&(t.raws.value=ht(t.raws.value))})}function Gu(i,e){if(!rt(i))return;let t=i.slice(1,-1);if(!!e(t))return U(t)}function Yb(i,e={},t){let r=e[i];if(r!==void 0)return Xe(r);if(rt(i)){let n=Gu(i,t);return n===void 0?void 0:Xe(n)}}function wi(i,e={},{validate:t=()=>!0}={}){let r=e.values?.[i];return r!==void 0?r:e.supportsNegativeValues&&i.startsWith("-")?Yb(i.slice(1),e.values,t):Gu(i,t)}function rt(i){return i.startsWith("[")&&i.endsWith("]")}function Hu(i){let e=i.lastIndexOf("/");return e===-1||e===i.length-1?[i,void 0]:rt(i)&&!i.includes("]/[")?[i,void 0]:[i.slice(0,e),i.slice(e+1)]}function kt(i){if(typeof i=="string"&&i.includes("")){let e=i;return({opacityValue:t=1})=>e.replace("",t)}return i}function Yu(i){return U(i.slice(1,-1))}function Qb(i,e={},{tailwindConfig:t={}}={}){if(e.values?.[i]!==void 0)return kt(e.values?.[i]);let[r,n]=Hu(i);if(n!==void 0){let a=e.values?.[r]??(rt(r)?r.slice(1,-1):void 0);return a===void 0?void 0:(a=kt(a),rt(n)?Ie(a,Yu(n)):t.theme?.opacity?.[n]===void 0?void 0:Ie(a,t.theme.opacity[n]))}return wi(i,e,{validate:Bu})}function Jb(i,e={}){return e.values?.[i]}function he(i){return(e,t)=>wi(e,t,{validate:i})}function Xb(i,e){let t=i.indexOf(e);return t===-1?[void 0,i]:[i.slice(0,t),i.slice(t+1)]}function cs(i,e,t,r){if(t.values&&e in t.values)for(let{type:a}of i??[]){let s=fs[a](e,t,{tailwindConfig:r});if(s!==void 0)return[s,a,null]}if(rt(e)){let a=e.slice(1,-1),[s,o]=Xb(a,":");if(!/^[\w-_]+$/g.test(s))o=a;else if(s!==void 0&&!Qu.includes(s))return[];if(o.length>0&&Qu.includes(s))return[wi(`[${o}]`,t),s,null]}let n=ps(i,e,t,r);for(let a of n)return a;return[]}function*ps(i,e,t,r){let n=J(r,"generalizedModifiers"),[a,s]=Hu(e);if(n&&t.modifiers!=null&&(t.modifiers==="any"||typeof t.modifiers=="object"&&(s&&rt(s)||s in t.modifiers))||(a=e,s=void 0),s!==void 0&&a===""&&(a="DEFAULT"),s!==void 0&&typeof t.modifiers=="object"){let u=t.modifiers?.[s]??null;u!==null?s=u:rt(s)&&(s=Yu(s))}for(let{type:u}of i??[]){let c=fs[u](a,t,{tailwindConfig:r});c!==void 0&&(yield[c,u,s??null])}}var fs,Qu,cr=C(()=>{l();mi();ar();fr();fi();Uu();De();fs={any:wi,color:Qb,url:he(ls),image:he(Fu),length:he(ur),percentage:he(lr),position:he(Nu),lookup:Jb,"generic-name":he($u),"family-name":he(Lu),number:he(us),"line-width":he(Ru),"absolute-size":he(ju),"relative-size":he(zu),shadow:he(Mu),size:he(Vu)},Qu=Object.keys(fs)});function N(i){return typeof i=="function"?i({}):i}var ds=C(()=>{l()});function St(i){return typeof i=="function"}function pr(i,...e){let t=e.pop();for(let r of e)for(let n in r){let a=t(i[n],r[n]);a===void 0?ie(i[n])&&ie(r[n])?i[n]=pr({},i[n],r[n],t):i[n]=r[n]:i[n]=a}return i}function Kb(i,...e){return St(i)?i(...e):i}function Zb(i){return i.reduce((e,{extend:t})=>pr(e,t,(r,n)=>r===void 0?[n]:Array.isArray(r)?[n,...r]:[n,r]),{})}function e0(i){return{...i.reduce((e,t)=>rs(e,t),{}),extend:Zb(i)}}function Ju(i,e){if(Array.isArray(i)&&ie(i[0]))return i.concat(e);if(Array.isArray(e)&&ie(e[0])&&ie(i))return[i,...e];if(Array.isArray(e))return e}function t0({extend:i,...e}){return pr(e,i,(t,r)=>!St(t)&&!r.some(St)?pr({},t,...r,Ju):(n,a)=>pr({},...[t,...r].map(s=>Kb(s,n,a)),Ju))}function*r0(i){let e=Ke(i);if(e.length===0||(yield e,Array.isArray(i)))return;let t=/^(.*?)\s*\/\s*([^/]+)$/,r=i.match(t);if(r!==null){let[,n,a]=r,s=Ke(n);s.alpha=a,yield s}}function i0(i){let e=(t,r)=>{for(let n of r0(t)){let a=0,s=i;for(;s!=null&&a(t[r]=St(i[r])?i[r](e,hs):i[r],t),{})}function Xu(i){let e=[];return i.forEach(t=>{e=[...e,t];let r=t?.plugins??[];r.length!==0&&r.forEach(n=>{n.__isOptionsFunction&&(n=n()),e=[...e,...Xu([n?.config??{}])]})}),e}function n0(i){return[...i].reduceRight((t,r)=>St(r)?r({corePlugins:t}):wu(r,t),gu)}function s0(i){return[...i].reduceRight((t,r)=>[...t,...r],[])}function ms(i){let e=[...Xu(i),{prefix:"",important:!1,separator:":"}];return Eu(rs({theme:i0(t0(e0(e.map(t=>t?.theme??{})))),corePlugins:n0(e.map(t=>t.corePlugins)),plugins:s0(i.map(t=>t?.plugins??[]))},...e))}var hs,Ku=C(()=>{l();fi();yu();bu();ts();Su();pi();Ou();xt();hi();cr();ar();ds();hs={colors:es,negative(i){return Object.keys(i).filter(e=>i[e]!=="0").reduce((e,t)=>{let r=Xe(i[t]);return r!==void 0&&(e[`-${t}`]=r),e},{})},breakpoints(i){return Object.keys(i).filter(e=>typeof i[e]=="string").reduce((e,t)=>({...e,[`screen-${t}`]:i[t]}),{})}}});var bi=v((eT,Zu)=>{l();Zu.exports={content:[],presets:[],darkMode:"media",theme:{accentColor:({theme:i})=>({...i("colors"),auto:"auto"}),animation:{none:"none",spin:"spin 1s linear infinite",ping:"ping 1s cubic-bezier(0, 0, 0.2, 1) infinite",pulse:"pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite",bounce:"bounce 1s infinite"},aria:{busy:'busy="true"',checked:'checked="true"',disabled:'disabled="true"',expanded:'expanded="true"',hidden:'hidden="true"',pressed:'pressed="true"',readonly:'readonly="true"',required:'required="true"',selected:'selected="true"'},aspectRatio:{auto:"auto",square:"1 / 1",video:"16 / 9"},backdropBlur:({theme:i})=>i("blur"),backdropBrightness:({theme:i})=>i("brightness"),backdropContrast:({theme:i})=>i("contrast"),backdropGrayscale:({theme:i})=>i("grayscale"),backdropHueRotate:({theme:i})=>i("hueRotate"),backdropInvert:({theme:i})=>i("invert"),backdropOpacity:({theme:i})=>i("opacity"),backdropSaturate:({theme:i})=>i("saturate"),backdropSepia:({theme:i})=>i("sepia"),backgroundColor:({theme:i})=>i("colors"),backgroundImage:{none:"none","gradient-to-t":"linear-gradient(to top, var(--tw-gradient-stops))","gradient-to-tr":"linear-gradient(to top right, var(--tw-gradient-stops))","gradient-to-r":"linear-gradient(to right, var(--tw-gradient-stops))","gradient-to-br":"linear-gradient(to bottom right, var(--tw-gradient-stops))","gradient-to-b":"linear-gradient(to bottom, var(--tw-gradient-stops))","gradient-to-bl":"linear-gradient(to bottom left, var(--tw-gradient-stops))","gradient-to-l":"linear-gradient(to left, var(--tw-gradient-stops))","gradient-to-tl":"linear-gradient(to top left, var(--tw-gradient-stops))"},backgroundOpacity:({theme:i})=>i("opacity"),backgroundPosition:{bottom:"bottom",center:"center",left:"left","left-bottom":"left bottom","left-top":"left top",right:"right","right-bottom":"right bottom","right-top":"right top",top:"top"},backgroundSize:{auto:"auto",cover:"cover",contain:"contain"},blur:{0:"0",none:"0",sm:"4px",DEFAULT:"8px",md:"12px",lg:"16px",xl:"24px","2xl":"40px","3xl":"64px"},borderColor:({theme:i})=>({...i("colors"),DEFAULT:i("colors.gray.200","currentColor")}),borderOpacity:({theme:i})=>i("opacity"),borderRadius:{none:"0px",sm:"0.125rem",DEFAULT:"0.25rem",md:"0.375rem",lg:"0.5rem",xl:"0.75rem","2xl":"1rem","3xl":"1.5rem",full:"9999px"},borderSpacing:({theme:i})=>({...i("spacing")}),borderWidth:{DEFAULT:"1px",0:"0px",2:"2px",4:"4px",8:"8px"},boxShadow:{sm:"0 1px 2px 0 rgb(0 0 0 / 0.05)",DEFAULT:"0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1)",md:"0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1)",lg:"0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1)",xl:"0 20px 25px -5px rgb(0 0 0 / 0.1), 0 8px 10px -6px rgb(0 0 0 / 0.1)","2xl":"0 25px 50px -12px rgb(0 0 0 / 0.25)",inner:"inset 0 2px 4px 0 rgb(0 0 0 / 0.05)",none:"none"},boxShadowColor:({theme:i})=>i("colors"),brightness:{0:"0",50:".5",75:".75",90:".9",95:".95",100:"1",105:"1.05",110:"1.1",125:"1.25",150:"1.5",200:"2"},caretColor:({theme:i})=>i("colors"),colors:({colors:i})=>({inherit:i.inherit,current:i.current,transparent:i.transparent,black:i.black,white:i.white,slate:i.slate,gray:i.gray,zinc:i.zinc,neutral:i.neutral,stone:i.stone,red:i.red,orange:i.orange,amber:i.amber,yellow:i.yellow,lime:i.lime,green:i.green,emerald:i.emerald,teal:i.teal,cyan:i.cyan,sky:i.sky,blue:i.blue,indigo:i.indigo,violet:i.violet,purple:i.purple,fuchsia:i.fuchsia,pink:i.pink,rose:i.rose}),columns:{auto:"auto",1:"1",2:"2",3:"3",4:"4",5:"5",6:"6",7:"7",8:"8",9:"9",10:"10",11:"11",12:"12","3xs":"16rem","2xs":"18rem",xs:"20rem",sm:"24rem",md:"28rem",lg:"32rem",xl:"36rem","2xl":"42rem","3xl":"48rem","4xl":"56rem","5xl":"64rem","6xl":"72rem","7xl":"80rem"},container:{},content:{none:"none"},contrast:{0:"0",50:".5",75:".75",100:"1",125:"1.25",150:"1.5",200:"2"},cursor:{auto:"auto",default:"default",pointer:"pointer",wait:"wait",text:"text",move:"move",help:"help","not-allowed":"not-allowed",none:"none","context-menu":"context-menu",progress:"progress",cell:"cell",crosshair:"crosshair","vertical-text":"vertical-text",alias:"alias",copy:"copy","no-drop":"no-drop",grab:"grab",grabbing:"grabbing","all-scroll":"all-scroll","col-resize":"col-resize","row-resize":"row-resize","n-resize":"n-resize","e-resize":"e-resize","s-resize":"s-resize","w-resize":"w-resize","ne-resize":"ne-resize","nw-resize":"nw-resize","se-resize":"se-resize","sw-resize":"sw-resize","ew-resize":"ew-resize","ns-resize":"ns-resize","nesw-resize":"nesw-resize","nwse-resize":"nwse-resize","zoom-in":"zoom-in","zoom-out":"zoom-out"},divideColor:({theme:i})=>i("borderColor"),divideOpacity:({theme:i})=>i("borderOpacity"),divideWidth:({theme:i})=>i("borderWidth"),dropShadow:{sm:"0 1px 1px rgb(0 0 0 / 0.05)",DEFAULT:["0 1px 2px rgb(0 0 0 / 0.1)","0 1px 1px rgb(0 0 0 / 0.06)"],md:["0 4px 3px rgb(0 0 0 / 0.07)","0 2px 2px rgb(0 0 0 / 0.06)"],lg:["0 10px 8px rgb(0 0 0 / 0.04)","0 4px 3px rgb(0 0 0 / 0.1)"],xl:["0 20px 13px rgb(0 0 0 / 0.03)","0 8px 5px rgb(0 0 0 / 0.08)"],"2xl":"0 25px 25px rgb(0 0 0 / 0.15)",none:"0 0 #0000"},fill:({theme:i})=>({none:"none",...i("colors")}),flex:{1:"1 1 0%",auto:"1 1 auto",initial:"0 1 auto",none:"none"},flexBasis:({theme:i})=>({auto:"auto",...i("spacing"),"1/2":"50%","1/3":"33.333333%","2/3":"66.666667%","1/4":"25%","2/4":"50%","3/4":"75%","1/5":"20%","2/5":"40%","3/5":"60%","4/5":"80%","1/6":"16.666667%","2/6":"33.333333%","3/6":"50%","4/6":"66.666667%","5/6":"83.333333%","1/12":"8.333333%","2/12":"16.666667%","3/12":"25%","4/12":"33.333333%","5/12":"41.666667%","6/12":"50%","7/12":"58.333333%","8/12":"66.666667%","9/12":"75%","10/12":"83.333333%","11/12":"91.666667%",full:"100%"}),flexGrow:{0:"0",DEFAULT:"1"},flexShrink:{0:"0",DEFAULT:"1"},fontFamily:{sans:["ui-sans-serif","system-ui","-apple-system","BlinkMacSystemFont",'"Segoe UI"',"Roboto",'"Helvetica Neue"',"Arial",'"Noto Sans"',"sans-serif",'"Apple Color Emoji"','"Segoe UI Emoji"','"Segoe UI Symbol"','"Noto Color Emoji"'],serif:["ui-serif","Georgia","Cambria",'"Times New Roman"',"Times","serif"],mono:["ui-monospace","SFMono-Regular","Menlo","Monaco","Consolas",'"Liberation Mono"','"Courier New"',"monospace"]},fontSize:{xs:["0.75rem",{lineHeight:"1rem"}],sm:["0.875rem",{lineHeight:"1.25rem"}],base:["1rem",{lineHeight:"1.5rem"}],lg:["1.125rem",{lineHeight:"1.75rem"}],xl:["1.25rem",{lineHeight:"1.75rem"}],"2xl":["1.5rem",{lineHeight:"2rem"}],"3xl":["1.875rem",{lineHeight:"2.25rem"}],"4xl":["2.25rem",{lineHeight:"2.5rem"}],"5xl":["3rem",{lineHeight:"1"}],"6xl":["3.75rem",{lineHeight:"1"}],"7xl":["4.5rem",{lineHeight:"1"}],"8xl":["6rem",{lineHeight:"1"}],"9xl":["8rem",{lineHeight:"1"}]},fontWeight:{thin:"100",extralight:"200",light:"300",normal:"400",medium:"500",semibold:"600",bold:"700",extrabold:"800",black:"900"},gap:({theme:i})=>i("spacing"),gradientColorStops:({theme:i})=>i("colors"),gradientColorStopPositions:{"0%":"0%","5%":"5%","10%":"10%","15%":"15%","20%":"20%","25%":"25%","30%":"30%","35%":"35%","40%":"40%","45%":"45%","50%":"50%","55%":"55%","60%":"60%","65%":"65%","70%":"70%","75%":"75%","80%":"80%","85%":"85%","90%":"90%","95%":"95%","100%":"100%"},grayscale:{0:"0",DEFAULT:"100%"},gridAutoColumns:{auto:"auto",min:"min-content",max:"max-content",fr:"minmax(0, 1fr)"},gridAutoRows:{auto:"auto",min:"min-content",max:"max-content",fr:"minmax(0, 1fr)"},gridColumn:{auto:"auto","span-1":"span 1 / span 1","span-2":"span 2 / span 2","span-3":"span 3 / span 3","span-4":"span 4 / span 4","span-5":"span 5 / span 5","span-6":"span 6 / span 6","span-7":"span 7 / span 7","span-8":"span 8 / span 8","span-9":"span 9 / span 9","span-10":"span 10 / span 10","span-11":"span 11 / span 11","span-12":"span 12 / span 12","span-full":"1 / -1"},gridColumnEnd:{auto:"auto",1:"1",2:"2",3:"3",4:"4",5:"5",6:"6",7:"7",8:"8",9:"9",10:"10",11:"11",12:"12",13:"13"},gridColumnStart:{auto:"auto",1:"1",2:"2",3:"3",4:"4",5:"5",6:"6",7:"7",8:"8",9:"9",10:"10",11:"11",12:"12",13:"13"},gridRow:{auto:"auto","span-1":"span 1 / span 1","span-2":"span 2 / span 2","span-3":"span 3 / span 3","span-4":"span 4 / span 4","span-5":"span 5 / span 5","span-6":"span 6 / span 6","span-full":"1 / -1"},gridRowEnd:{auto:"auto",1:"1",2:"2",3:"3",4:"4",5:"5",6:"6",7:"7"},gridRowStart:{auto:"auto",1:"1",2:"2",3:"3",4:"4",5:"5",6:"6",7:"7"},gridTemplateColumns:{none:"none",1:"repeat(1, minmax(0, 1fr))",2:"repeat(2, minmax(0, 1fr))",3:"repeat(3, minmax(0, 1fr))",4:"repeat(4, minmax(0, 1fr))",5:"repeat(5, minmax(0, 1fr))",6:"repeat(6, minmax(0, 1fr))",7:"repeat(7, minmax(0, 1fr))",8:"repeat(8, minmax(0, 1fr))",9:"repeat(9, minmax(0, 1fr))",10:"repeat(10, minmax(0, 1fr))",11:"repeat(11, minmax(0, 1fr))",12:"repeat(12, minmax(0, 1fr))"},gridTemplateRows:{none:"none",1:"repeat(1, minmax(0, 1fr))",2:"repeat(2, minmax(0, 1fr))",3:"repeat(3, minmax(0, 1fr))",4:"repeat(4, minmax(0, 1fr))",5:"repeat(5, minmax(0, 1fr))",6:"repeat(6, minmax(0, 1fr))"},height:({theme:i})=>({auto:"auto",...i("spacing"),"1/2":"50%","1/3":"33.333333%","2/3":"66.666667%","1/4":"25%","2/4":"50%","3/4":"75%","1/5":"20%","2/5":"40%","3/5":"60%","4/5":"80%","1/6":"16.666667%","2/6":"33.333333%","3/6":"50%","4/6":"66.666667%","5/6":"83.333333%",full:"100%",screen:"100vh",min:"min-content",max:"max-content",fit:"fit-content"}),hueRotate:{0:"0deg",15:"15deg",30:"30deg",60:"60deg",90:"90deg",180:"180deg"},inset:({theme:i})=>({auto:"auto",...i("spacing"),"1/2":"50%","1/3":"33.333333%","2/3":"66.666667%","1/4":"25%","2/4":"50%","3/4":"75%",full:"100%"}),invert:{0:"0",DEFAULT:"100%"},keyframes:{spin:{to:{transform:"rotate(360deg)"}},ping:{"75%, 100%":{transform:"scale(2)",opacity:"0"}},pulse:{"50%":{opacity:".5"}},bounce:{"0%, 100%":{transform:"translateY(-25%)",animationTimingFunction:"cubic-bezier(0.8,0,1,1)"},"50%":{transform:"none",animationTimingFunction:"cubic-bezier(0,0,0.2,1)"}}},letterSpacing:{tighter:"-0.05em",tight:"-0.025em",normal:"0em",wide:"0.025em",wider:"0.05em",widest:"0.1em"},lineHeight:{none:"1",tight:"1.25",snug:"1.375",normal:"1.5",relaxed:"1.625",loose:"2",3:".75rem",4:"1rem",5:"1.25rem",6:"1.5rem",7:"1.75rem",8:"2rem",9:"2.25rem",10:"2.5rem"},listStyleType:{none:"none",disc:"disc",decimal:"decimal"},listStyleImage:{none:"none"},margin:({theme:i})=>({auto:"auto",...i("spacing")}),lineClamp:{1:"1",2:"2",3:"3",4:"4",5:"5",6:"6"},maxHeight:({theme:i})=>({...i("spacing"),none:"none",full:"100%",screen:"100vh",min:"min-content",max:"max-content",fit:"fit-content"}),maxWidth:({theme:i,breakpoints:e})=>({none:"none",0:"0rem",xs:"20rem",sm:"24rem",md:"28rem",lg:"32rem",xl:"36rem","2xl":"42rem","3xl":"48rem","4xl":"56rem","5xl":"64rem","6xl":"72rem","7xl":"80rem",full:"100%",min:"min-content",max:"max-content",fit:"fit-content",prose:"65ch",...e(i("screens"))}),minHeight:{0:"0px",full:"100%",screen:"100vh",min:"min-content",max:"max-content",fit:"fit-content"},minWidth:{0:"0px",full:"100%",min:"min-content",max:"max-content",fit:"fit-content"},objectPosition:{bottom:"bottom",center:"center",left:"left","left-bottom":"left bottom","left-top":"left top",right:"right","right-bottom":"right bottom","right-top":"right top",top:"top"},opacity:{0:"0",5:"0.05",10:"0.1",20:"0.2",25:"0.25",30:"0.3",40:"0.4",50:"0.5",60:"0.6",70:"0.7",75:"0.75",80:"0.8",90:"0.9",95:"0.95",100:"1"},order:{first:"-9999",last:"9999",none:"0",1:"1",2:"2",3:"3",4:"4",5:"5",6:"6",7:"7",8:"8",9:"9",10:"10",11:"11",12:"12"},outlineColor:({theme:i})=>i("colors"),outlineOffset:{0:"0px",1:"1px",2:"2px",4:"4px",8:"8px"},outlineWidth:{0:"0px",1:"1px",2:"2px",4:"4px",8:"8px"},padding:({theme:i})=>i("spacing"),placeholderColor:({theme:i})=>i("colors"),placeholderOpacity:({theme:i})=>i("opacity"),ringColor:({theme:i})=>({DEFAULT:i("colors.blue.500","#3b82f6"),...i("colors")}),ringOffsetColor:({theme:i})=>i("colors"),ringOffsetWidth:{0:"0px",1:"1px",2:"2px",4:"4px",8:"8px"},ringOpacity:({theme:i})=>({DEFAULT:"0.5",...i("opacity")}),ringWidth:{DEFAULT:"3px",0:"0px",1:"1px",2:"2px",4:"4px",8:"8px"},rotate:{0:"0deg",1:"1deg",2:"2deg",3:"3deg",6:"6deg",12:"12deg",45:"45deg",90:"90deg",180:"180deg"},saturate:{0:"0",50:".5",100:"1",150:"1.5",200:"2"},scale:{0:"0",50:".5",75:".75",90:".9",95:".95",100:"1",105:"1.05",110:"1.1",125:"1.25",150:"1.5"},screens:{sm:"640px",md:"768px",lg:"1024px",xl:"1280px","2xl":"1536px"},scrollMargin:({theme:i})=>({...i("spacing")}),scrollPadding:({theme:i})=>i("spacing"),sepia:{0:"0",DEFAULT:"100%"},skew:{0:"0deg",1:"1deg",2:"2deg",3:"3deg",6:"6deg",12:"12deg"},space:({theme:i})=>({...i("spacing")}),spacing:{px:"1px",0:"0px",.5:"0.125rem",1:"0.25rem",1.5:"0.375rem",2:"0.5rem",2.5:"0.625rem",3:"0.75rem",3.5:"0.875rem",4:"1rem",5:"1.25rem",6:"1.5rem",7:"1.75rem",8:"2rem",9:"2.25rem",10:"2.5rem",11:"2.75rem",12:"3rem",14:"3.5rem",16:"4rem",20:"5rem",24:"6rem",28:"7rem",32:"8rem",36:"9rem",40:"10rem",44:"11rem",48:"12rem",52:"13rem",56:"14rem",60:"15rem",64:"16rem",72:"18rem",80:"20rem",96:"24rem"},stroke:({theme:i})=>({none:"none",...i("colors")}),strokeWidth:{0:"0",1:"1",2:"2"},supports:{},data:{},textColor:({theme:i})=>i("colors"),textDecorationColor:({theme:i})=>i("colors"),textDecorationThickness:{auto:"auto","from-font":"from-font",0:"0px",1:"1px",2:"2px",4:"4px",8:"8px"},textIndent:({theme:i})=>({...i("spacing")}),textOpacity:({theme:i})=>i("opacity"),textUnderlineOffset:{auto:"auto",0:"0px",1:"1px",2:"2px",4:"4px",8:"8px"},transformOrigin:{center:"center",top:"top","top-right":"top right",right:"right","bottom-right":"bottom right",bottom:"bottom","bottom-left":"bottom left",left:"left","top-left":"top left"},transitionDelay:{0:"0s",75:"75ms",100:"100ms",150:"150ms",200:"200ms",300:"300ms",500:"500ms",700:"700ms",1e3:"1000ms"},transitionDuration:{DEFAULT:"150ms",0:"0s",75:"75ms",100:"100ms",150:"150ms",200:"200ms",300:"300ms",500:"500ms",700:"700ms",1e3:"1000ms"},transitionProperty:{none:"none",all:"all",DEFAULT:"color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter",colors:"color, background-color, border-color, text-decoration-color, fill, stroke",opacity:"opacity",shadow:"box-shadow",transform:"transform"},transitionTimingFunction:{DEFAULT:"cubic-bezier(0.4, 0, 0.2, 1)",linear:"linear",in:"cubic-bezier(0.4, 0, 1, 1)",out:"cubic-bezier(0, 0, 0.2, 1)","in-out":"cubic-bezier(0.4, 0, 0.2, 1)"},translate:({theme:i})=>({...i("spacing"),"1/2":"50%","1/3":"33.333333%","2/3":"66.666667%","1/4":"25%","2/4":"50%","3/4":"75%",full:"100%"}),width:({theme:i})=>({auto:"auto",...i("spacing"),"1/2":"50%","1/3":"33.333333%","2/3":"66.666667%","1/4":"25%","2/4":"50%","3/4":"75%","1/5":"20%","2/5":"40%","3/5":"60%","4/5":"80%","1/6":"16.666667%","2/6":"33.333333%","3/6":"50%","4/6":"66.666667%","5/6":"83.333333%","1/12":"8.333333%","2/12":"16.666667%","3/12":"25%","4/12":"33.333333%","5/12":"41.666667%","6/12":"50%","7/12":"58.333333%","8/12":"66.666667%","9/12":"75%","10/12":"83.333333%","11/12":"91.666667%",full:"100%",screen:"100vw",min:"min-content",max:"max-content",fit:"fit-content"}),willChange:{auto:"auto",scroll:"scroll-position",contents:"contents",transform:"transform"},zIndex:{auto:"auto",0:"0",10:"10",20:"20",30:"30",40:"40",50:"50"}},plugins:[]}});function vi(i){let e=(i?.presets??[ef.default]).slice().reverse().flatMap(n=>vi(n instanceof Function?n():n)),t={respectDefaultRingColorOpacity:{theme:{ringColor:({theme:n})=>({DEFAULT:"#3b82f67f",...n("colors")})}},disableColorOpacityUtilitiesByDefault:{corePlugins:{backgroundOpacity:!1,borderOpacity:!1,divideOpacity:!1,placeholderOpacity:!1,ringOpacity:!1,textOpacity:!1}}},r=Object.keys(t).filter(n=>J(i,n)).map(n=>t[n]);return[i,...r,...e]}var ef,tf=C(()=>{l();ef=K(bi());De()});var rf={};Ae(rf,{default:()=>dr});function dr(...i){let[,...e]=vi(i[0]);return ms([...i,...e])}var gs=C(()=>{l();Ku();tf()});var nf={};Ae(nf,{default:()=>Z});var Z,mt=C(()=>{l();Z={resolve:i=>i,extname:i=>"."+i.split(".").pop()}});function xi(i){return typeof i=="object"&&i!==null}function o0(i){return Object.keys(i).length===0}function sf(i){return typeof i=="string"||i instanceof String}function ys(i){return xi(i)&&i.config===void 0&&!o0(i)?null:xi(i)&&i.config!==void 0&&sf(i.config)?Z.resolve(i.config):xi(i)&&i.config!==void 0&&xi(i.config)?null:sf(i)?Z.resolve(i):l0()}function l0(){for(let i of a0)try{let e=Z.resolve(i);return te.accessSync(e),e}catch(e){}return null}var a0,af=C(()=>{l();ze();mt();a0=["./tailwind.config.js","./tailwind.config.cjs","./tailwind.config.mjs","./tailwind.config.ts"]});var of={};Ae(of,{default:()=>ws});var ws,bs=C(()=>{l();ws={parse:i=>({href:i})}});var vs=v(()=>{l()});var ki=v((fT,ff)=>{l();"use strict";var lf=(ci(),vu),uf=vs(),Ct=class extends Error{constructor(e,t,r,n,a,s){super(e);this.name="CssSyntaxError",this.reason=e,a&&(this.file=a),n&&(this.source=n),s&&(this.plugin=s),typeof t!="undefined"&&typeof r!="undefined"&&(typeof t=="number"?(this.line=t,this.column=r):(this.line=t.line,this.column=t.column,this.endLine=r.line,this.endColumn=r.column)),this.setMessage(),Error.captureStackTrace&&Error.captureStackTrace(this,Ct)}setMessage(){this.message=this.plugin?this.plugin+": ":"",this.message+=this.file?this.file:"",typeof this.line!="undefined"&&(this.message+=":"+this.line+":"+this.column),this.message+=": "+this.reason}showSourceCode(e){if(!this.source)return"";let t=this.source;e==null&&(e=lf.isColorSupported),uf&&e&&(t=uf(t));let r=t.split(/\r?\n/),n=Math.max(this.line-3,0),a=Math.min(this.line+2,r.length),s=String(a).length,o,u;if(e){let{bold:c,red:f,gray:p}=lf.createColors(!0);o=d=>c(f(d)),u=d=>p(d)}else o=u=c=>c;return r.slice(n,a).map((c,f)=>{let p=n+1+f,d=" "+(" "+p).slice(-s)+" | ";if(p===this.line){let h=u(d.replace(/\d/g," "))+c.slice(0,this.column-1).replace(/[^\t]/g," ");return o(">")+u(d)+c+` + `+h+o("^")}return" "+u(d)+c}).join(` +`)}toString(){let e=this.showSourceCode();return e&&(e=` + +`+e+` +`),this.name+": "+this.message+e}};ff.exports=Ct;Ct.default=Ct});var Si=v((cT,xs)=>{l();"use strict";xs.exports.isClean=Symbol("isClean");xs.exports.my=Symbol("my")});var ks=v((pT,pf)=>{l();"use strict";var cf={colon:": ",indent:" ",beforeDecl:` +`,beforeRule:` +`,beforeOpen:" ",beforeClose:` +`,beforeComment:` +`,after:` +`,emptyBody:"",commentLeft:" ",commentRight:" ",semicolon:!1};function u0(i){return i[0].toUpperCase()+i.slice(1)}var Ci=class{constructor(e){this.builder=e}stringify(e,t){if(!this[e.type])throw new Error("Unknown AST node type "+e.type+". Maybe you need to change PostCSS stringifier.");this[e.type](e,t)}document(e){this.body(e)}root(e){this.body(e),e.raws.after&&this.builder(e.raws.after)}comment(e){let t=this.raw(e,"left","commentLeft"),r=this.raw(e,"right","commentRight");this.builder("/*"+t+e.text+r+"*/",e)}decl(e,t){let r=this.raw(e,"between","colon"),n=e.prop+r+this.rawValue(e,"value");e.important&&(n+=e.raws.important||" !important"),t&&(n+=";"),this.builder(n,e)}rule(e){this.block(e,this.rawValue(e,"selector")),e.raws.ownSemicolon&&this.builder(e.raws.ownSemicolon,e,"end")}atrule(e,t){let r="@"+e.name,n=e.params?this.rawValue(e,"params"):"";if(typeof e.raws.afterName!="undefined"?r+=e.raws.afterName:n&&(r+=" "),e.nodes)this.block(e,r+n);else{let a=(e.raws.between||"")+(t?";":"");this.builder(r+n+a,e)}}body(e){let t=e.nodes.length-1;for(;t>0&&e.nodes[t].type==="comment";)t-=1;let r=this.raw(e,"semicolon");for(let n=0;n{if(n=u.raws[t],typeof n!="undefined")return!1})}return typeof n=="undefined"&&(n=cf[r]),s.rawCache[r]=n,n}rawSemicolon(e){let t;return e.walk(r=>{if(r.nodes&&r.nodes.length&&r.last.type==="decl"&&(t=r.raws.semicolon,typeof t!="undefined"))return!1}),t}rawEmptyBody(e){let t;return e.walk(r=>{if(r.nodes&&r.nodes.length===0&&(t=r.raws.after,typeof t!="undefined"))return!1}),t}rawIndent(e){if(e.raws.indent)return e.raws.indent;let t;return e.walk(r=>{let n=r.parent;if(n&&n!==e&&n.parent&&n.parent===e&&typeof r.raws.before!="undefined"){let a=r.raws.before.split(` +`);return t=a[a.length-1],t=t.replace(/\S/g,""),!1}}),t}rawBeforeComment(e,t){let r;return e.walkComments(n=>{if(typeof n.raws.before!="undefined")return r=n.raws.before,r.includes(` +`)&&(r=r.replace(/[^\n]+$/,"")),!1}),typeof r=="undefined"?r=this.raw(t,null,"beforeDecl"):r&&(r=r.replace(/\S/g,"")),r}rawBeforeDecl(e,t){let r;return e.walkDecls(n=>{if(typeof n.raws.before!="undefined")return r=n.raws.before,r.includes(` +`)&&(r=r.replace(/[^\n]+$/,"")),!1}),typeof r=="undefined"?r=this.raw(t,null,"beforeRule"):r&&(r=r.replace(/\S/g,"")),r}rawBeforeRule(e){let t;return e.walk(r=>{if(r.nodes&&(r.parent!==e||e.first!==r)&&typeof r.raws.before!="undefined")return t=r.raws.before,t.includes(` +`)&&(t=t.replace(/[^\n]+$/,"")),!1}),t&&(t=t.replace(/\S/g,"")),t}rawBeforeClose(e){let t;return e.walk(r=>{if(r.nodes&&r.nodes.length>0&&typeof r.raws.after!="undefined")return t=r.raws.after,t.includes(` +`)&&(t=t.replace(/[^\n]+$/,"")),!1}),t&&(t=t.replace(/\S/g,"")),t}rawBeforeOpen(e){let t;return e.walk(r=>{if(r.type!=="decl"&&(t=r.raws.between,typeof t!="undefined"))return!1}),t}rawColon(e){let t;return e.walkDecls(r=>{if(typeof r.raws.between!="undefined")return t=r.raws.between.replace(/[^\s:]/g,""),!1}),t}beforeAfter(e,t){let r;e.type==="decl"?r=this.raw(e,null,"beforeDecl"):e.type==="comment"?r=this.raw(e,null,"beforeComment"):t==="before"?r=this.raw(e,null,"beforeRule"):r=this.raw(e,null,"beforeClose");let n=e.parent,a=0;for(;n&&n.type!=="root";)a+=1,n=n.parent;if(r.includes(` +`)){let s=this.raw(e,null,"indent");if(s.length)for(let o=0;o{l();"use strict";var f0=ks();function Ss(i,e){new f0(e).stringify(i)}df.exports=Ss;Ss.default=Ss});var mr=v((hT,hf)=>{l();"use strict";var{isClean:Ai,my:c0}=Si(),p0=ki(),d0=ks(),h0=hr();function Cs(i,e){let t=new i.constructor;for(let r in i){if(!Object.prototype.hasOwnProperty.call(i,r)||r==="proxyCache")continue;let n=i[r],a=typeof n;r==="parent"&&a==="object"?e&&(t[r]=e):r==="source"?t[r]=n:Array.isArray(n)?t[r]=n.map(s=>Cs(s,t)):(a==="object"&&n!==null&&(n=Cs(n)),t[r]=n)}return t}var _i=class{constructor(e={}){this.raws={},this[Ai]=!1,this[c0]=!0;for(let t in e)if(t==="nodes"){this.nodes=[];for(let r of e[t])typeof r.clone=="function"?this.append(r.clone()):this.append(r)}else this[t]=e[t]}error(e,t={}){if(this.source){let{start:r,end:n}=this.rangeBy(t);return this.source.input.error(e,{line:r.line,column:r.column},{line:n.line,column:n.column},t)}return new p0(e)}warn(e,t,r){let n={node:this};for(let a in r)n[a]=r[a];return e.warn(t,n)}remove(){return this.parent&&this.parent.removeChild(this),this.parent=void 0,this}toString(e=h0){e.stringify&&(e=e.stringify);let t="";return e(this,r=>{t+=r}),t}assign(e={}){for(let t in e)this[t]=e[t];return this}clone(e={}){let t=Cs(this);for(let r in e)t[r]=e[r];return t}cloneBefore(e={}){let t=this.clone(e);return this.parent.insertBefore(this,t),t}cloneAfter(e={}){let t=this.clone(e);return this.parent.insertAfter(this,t),t}replaceWith(...e){if(this.parent){let t=this,r=!1;for(let n of e)n===this?r=!0:r?(this.parent.insertAfter(t,n),t=n):this.parent.insertBefore(t,n);r||this.remove()}return this}next(){if(!this.parent)return;let e=this.parent.index(this);return this.parent.nodes[e+1]}prev(){if(!this.parent)return;let e=this.parent.index(this);return this.parent.nodes[e-1]}before(e){return this.parent.insertBefore(this,e),this}after(e){return this.parent.insertAfter(this,e),this}root(){let e=this;for(;e.parent&&e.parent.type!=="document";)e=e.parent;return e}raw(e,t){return new d0().raw(this,e,t)}cleanRaws(e){delete this.raws.before,delete this.raws.after,e||delete this.raws.between}toJSON(e,t){let r={},n=t==null;t=t||new Map;let a=0;for(let s in this){if(!Object.prototype.hasOwnProperty.call(this,s)||s==="parent"||s==="proxyCache")continue;let o=this[s];if(Array.isArray(o))r[s]=o.map(u=>typeof u=="object"&&u.toJSON?u.toJSON(null,t):u);else if(typeof o=="object"&&o.toJSON)r[s]=o.toJSON(null,t);else if(s==="source"){let u=t.get(o.input);u==null&&(u=a,t.set(o.input,a),a++),r[s]={inputId:u,start:o.start,end:o.end}}else r[s]=o}return n&&(r.inputs=[...t.keys()].map(s=>s.toJSON())),r}positionInside(e){let t=this.toString(),r=this.source.start.column,n=this.source.start.line;for(let a=0;ae.root().toProxy():e[t]}}}toProxy(){return this.proxyCache||(this.proxyCache=new Proxy(this,this.getProxyProcessor())),this.proxyCache}addToError(e){if(e.postcssNode=this,e.stack&&this.source&&/\n\s{4}at /.test(e.stack)){let t=this.source;e.stack=e.stack.replace(/\n\s{4}at /,`$&${t.input.from}:${t.start.line}:${t.start.column}$&`)}return e}markDirty(){if(this[Ai]){this[Ai]=!1;let e=this;for(;e=e.parent;)e[Ai]=!1}}get proxyOf(){return this}};hf.exports=_i;_i.default=_i});var gr=v((mT,mf)=>{l();"use strict";var m0=mr(),Ei=class extends m0{constructor(e){e&&typeof e.value!="undefined"&&typeof e.value!="string"&&(e={...e,value:String(e.value)});super(e);this.type="decl"}get variable(){return this.prop.startsWith("--")||this.prop[0]==="$"}};mf.exports=Ei;Ei.default=Ei});var As=v((gT,gf)=>{l();gf.exports=function(i,e){return{generate:()=>{let t="";return i(e,r=>{t+=r}),[t]}}}});var yr=v((yT,yf)=>{l();"use strict";var g0=mr(),Oi=class extends g0{constructor(e){super(e);this.type="comment"}};yf.exports=Oi;Oi.default=Oi});var it=v((wT,_f)=>{l();"use strict";var{isClean:wf,my:bf}=Si(),vf=gr(),xf=yr(),y0=mr(),kf,_s,Es,Sf;function Cf(i){return i.map(e=>(e.nodes&&(e.nodes=Cf(e.nodes)),delete e.source,e))}function Af(i){if(i[wf]=!1,i.proxyOf.nodes)for(let e of i.proxyOf.nodes)Af(e)}var ye=class extends y0{push(e){return e.parent=this,this.proxyOf.nodes.push(e),this}each(e){if(!this.proxyOf.nodes)return;let t=this.getIterator(),r,n;for(;this.indexes[t]{let n;try{n=e(t,r)}catch(a){throw t.addToError(a)}return n!==!1&&t.walk&&(n=t.walk(e)),n})}walkDecls(e,t){return t?e instanceof RegExp?this.walk((r,n)=>{if(r.type==="decl"&&e.test(r.prop))return t(r,n)}):this.walk((r,n)=>{if(r.type==="decl"&&r.prop===e)return t(r,n)}):(t=e,this.walk((r,n)=>{if(r.type==="decl")return t(r,n)}))}walkRules(e,t){return t?e instanceof RegExp?this.walk((r,n)=>{if(r.type==="rule"&&e.test(r.selector))return t(r,n)}):this.walk((r,n)=>{if(r.type==="rule"&&r.selector===e)return t(r,n)}):(t=e,this.walk((r,n)=>{if(r.type==="rule")return t(r,n)}))}walkAtRules(e,t){return t?e instanceof RegExp?this.walk((r,n)=>{if(r.type==="atrule"&&e.test(r.name))return t(r,n)}):this.walk((r,n)=>{if(r.type==="atrule"&&r.name===e)return t(r,n)}):(t=e,this.walk((r,n)=>{if(r.type==="atrule")return t(r,n)}))}walkComments(e){return this.walk((t,r)=>{if(t.type==="comment")return e(t,r)})}append(...e){for(let t of e){let r=this.normalize(t,this.last);for(let n of r)this.proxyOf.nodes.push(n)}return this.markDirty(),this}prepend(...e){e=e.reverse();for(let t of e){let r=this.normalize(t,this.first,"prepend").reverse();for(let n of r)this.proxyOf.nodes.unshift(n);for(let n in this.indexes)this.indexes[n]=this.indexes[n]+r.length}return this.markDirty(),this}cleanRaws(e){if(super.cleanRaws(e),this.nodes)for(let t of this.nodes)t.cleanRaws(e)}insertBefore(e,t){let r=this.index(e),n=r===0?"prepend":!1,a=this.normalize(t,this.proxyOf.nodes[r],n).reverse();r=this.index(e);for(let o of a)this.proxyOf.nodes.splice(r,0,o);let s;for(let o in this.indexes)s=this.indexes[o],r<=s&&(this.indexes[o]=s+a.length);return this.markDirty(),this}insertAfter(e,t){let r=this.index(e),n=this.normalize(t,this.proxyOf.nodes[r]).reverse();r=this.index(e);for(let s of n)this.proxyOf.nodes.splice(r+1,0,s);let a;for(let s in this.indexes)a=this.indexes[s],r=e&&(this.indexes[r]=t-1);return this.markDirty(),this}removeAll(){for(let e of this.proxyOf.nodes)e.parent=void 0;return this.proxyOf.nodes=[],this.markDirty(),this}replaceValues(e,t,r){return r||(r=t,t={}),this.walkDecls(n=>{t.props&&!t.props.includes(n.prop)||t.fast&&!n.value.includes(t.fast)||(n.value=n.value.replace(e,r))}),this.markDirty(),this}every(e){return this.nodes.every(e)}some(e){return this.nodes.some(e)}index(e){return typeof e=="number"?e:(e.proxyOf&&(e=e.proxyOf),this.proxyOf.nodes.indexOf(e))}get first(){if(!!this.proxyOf.nodes)return this.proxyOf.nodes[0]}get last(){if(!!this.proxyOf.nodes)return this.proxyOf.nodes[this.proxyOf.nodes.length-1]}normalize(e,t){if(typeof e=="string")e=Cf(kf(e).nodes);else if(Array.isArray(e)){e=e.slice(0);for(let n of e)n.parent&&n.parent.removeChild(n,"ignore")}else if(e.type==="root"&&this.type!=="document"){e=e.nodes.slice(0);for(let n of e)n.parent&&n.parent.removeChild(n,"ignore")}else if(e.type)e=[e];else if(e.prop){if(typeof e.value=="undefined")throw new Error("Value field is missed in node creation");typeof e.value!="string"&&(e.value=String(e.value)),e=[new vf(e)]}else if(e.selector)e=[new _s(e)];else if(e.name)e=[new Es(e)];else if(e.text)e=[new xf(e)];else throw new Error("Unknown node type in node creation");return e.map(n=>(n[bf]||ye.rebuild(n),n=n.proxyOf,n.parent&&n.parent.removeChild(n),n[wf]&&Af(n),typeof n.raws.before=="undefined"&&t&&typeof t.raws.before!="undefined"&&(n.raws.before=t.raws.before.replace(/\S/g,"")),n.parent=this.proxyOf,n))}getProxyProcessor(){return{set(e,t,r){return e[t]===r||(e[t]=r,(t==="name"||t==="params"||t==="selector")&&e.markDirty()),!0},get(e,t){return t==="proxyOf"?e:e[t]?t==="each"||typeof t=="string"&&t.startsWith("walk")?(...r)=>e[t](...r.map(n=>typeof n=="function"?(a,s)=>n(a.toProxy(),s):n)):t==="every"||t==="some"?r=>e[t]((n,...a)=>r(n.toProxy(),...a)):t==="root"?()=>e.root().toProxy():t==="nodes"?e.nodes.map(r=>r.toProxy()):t==="first"||t==="last"?e[t].toProxy():e[t]:e[t]}}}getIterator(){this.lastEach||(this.lastEach=0),this.indexes||(this.indexes={}),this.lastEach+=1;let e=this.lastEach;return this.indexes[e]=0,e}};ye.registerParse=i=>{kf=i};ye.registerRule=i=>{_s=i};ye.registerAtRule=i=>{Es=i};ye.registerRoot=i=>{Sf=i};_f.exports=ye;ye.default=ye;ye.rebuild=i=>{i.type==="atrule"?Object.setPrototypeOf(i,Es.prototype):i.type==="rule"?Object.setPrototypeOf(i,_s.prototype):i.type==="decl"?Object.setPrototypeOf(i,vf.prototype):i.type==="comment"?Object.setPrototypeOf(i,xf.prototype):i.type==="root"&&Object.setPrototypeOf(i,Sf.prototype),i[bf]=!0,i.nodes&&i.nodes.forEach(e=>{ye.rebuild(e)})}});var Ti=v((bT,Tf)=>{l();"use strict";var w0=it(),Ef,Of,At=class extends w0{constructor(e){super({type:"document",...e});this.nodes||(this.nodes=[])}toResult(e={}){return new Ef(new Of,this,e).stringify()}};At.registerLazyResult=i=>{Ef=i};At.registerProcessor=i=>{Of=i};Tf.exports=At;At.default=At});var Os=v((vT,Df)=>{l();"use strict";var Pf={};Df.exports=function(e){Pf[e]||(Pf[e]=!0,typeof console!="undefined"&&console.warn&&console.warn(e))}});var Ts=v((xT,If)=>{l();"use strict";var Pi=class{constructor(e,t={}){if(this.type="warning",this.text=e,t.node&&t.node.source){let r=t.node.rangeBy(t);this.line=r.start.line,this.column=r.start.column,this.endLine=r.end.line,this.endColumn=r.end.column}for(let r in t)this[r]=t[r]}toString(){return this.node?this.node.error(this.text,{plugin:this.plugin,index:this.index,word:this.word}).message:this.plugin?this.plugin+": "+this.text:this.text}};If.exports=Pi;Pi.default=Pi});var Ii=v((kT,qf)=>{l();"use strict";var b0=Ts(),Di=class{constructor(e,t,r){this.processor=e,this.messages=[],this.root=t,this.opts=r,this.css=void 0,this.map=void 0}toString(){return this.css}warn(e,t={}){t.plugin||this.lastPlugin&&this.lastPlugin.postcssPlugin&&(t.plugin=this.lastPlugin.postcssPlugin);let r=new b0(e,t);return this.messages.push(r),r}warnings(){return this.messages.filter(e=>e.type==="warning")}get content(){return this.css}};qf.exports=Di;Di.default=Di});var Nf=v((ST,Ff)=>{l();"use strict";var Ps="'".charCodeAt(0),Rf='"'.charCodeAt(0),qi="\\".charCodeAt(0),Mf="/".charCodeAt(0),Ri=` +`.charCodeAt(0),wr=" ".charCodeAt(0),Mi="\f".charCodeAt(0),Bi=" ".charCodeAt(0),Fi="\r".charCodeAt(0),v0="[".charCodeAt(0),x0="]".charCodeAt(0),k0="(".charCodeAt(0),S0=")".charCodeAt(0),C0="{".charCodeAt(0),A0="}".charCodeAt(0),_0=";".charCodeAt(0),E0="*".charCodeAt(0),O0=":".charCodeAt(0),T0="@".charCodeAt(0),Ni=/[\t\n\f\r "#'()/;[\\\]{}]/g,Li=/[\t\n\f\r !"#'():;@[\\\]{}]|\/(?=\*)/g,P0=/.[\n"'(/\\]/,Bf=/[\da-f]/i;Ff.exports=function(e,t={}){let r=e.css.valueOf(),n=t.ignoreErrors,a,s,o,u,c,f,p,d,h,y,x=r.length,w=0,b=[],k=[];function S(){return w}function _(q){throw e.error("Unclosed "+q,w)}function E(){return k.length===0&&w>=x}function I(q){if(k.length)return k.pop();if(w>=x)return;let X=q?q.ignoreUnclosed:!1;switch(a=r.charCodeAt(w),a){case Ri:case wr:case Bi:case Fi:case Mi:{s=w;do s+=1,a=r.charCodeAt(s);while(a===wr||a===Ri||a===Bi||a===Fi||a===Mi);y=["space",r.slice(w,s)],w=s-1;break}case v0:case x0:case C0:case A0:case O0:case _0:case S0:{let ae=String.fromCharCode(a);y=[ae,ae,w];break}case k0:{if(d=b.length?b.pop()[1]:"",h=r.charCodeAt(w+1),d==="url"&&h!==Ps&&h!==Rf&&h!==wr&&h!==Ri&&h!==Bi&&h!==Mi&&h!==Fi){s=w;do{if(f=!1,s=r.indexOf(")",s+1),s===-1)if(n||X){s=w;break}else _("bracket");for(p=s;r.charCodeAt(p-1)===qi;)p-=1,f=!f}while(f);y=["brackets",r.slice(w,s+1),w,s],w=s}else s=r.indexOf(")",w+1),u=r.slice(w,s+1),s===-1||P0.test(u)?y=["(","(",w]:(y=["brackets",u,w,s],w=s);break}case Ps:case Rf:{o=a===Ps?"'":'"',s=w;do{if(f=!1,s=r.indexOf(o,s+1),s===-1)if(n||X){s=w+1;break}else _("string");for(p=s;r.charCodeAt(p-1)===qi;)p-=1,f=!f}while(f);y=["string",r.slice(w,s+1),w,s],w=s;break}case T0:{Ni.lastIndex=w+1,Ni.test(r),Ni.lastIndex===0?s=r.length-1:s=Ni.lastIndex-2,y=["at-word",r.slice(w,s+1),w,s],w=s;break}case qi:{for(s=w,c=!0;r.charCodeAt(s+1)===qi;)s+=1,c=!c;if(a=r.charCodeAt(s+1),c&&a!==Mf&&a!==wr&&a!==Ri&&a!==Bi&&a!==Fi&&a!==Mi&&(s+=1,Bf.test(r.charAt(s)))){for(;Bf.test(r.charAt(s+1));)s+=1;r.charCodeAt(s+1)===wr&&(s+=1)}y=["word",r.slice(w,s+1),w,s],w=s;break}default:{a===Mf&&r.charCodeAt(w+1)===E0?(s=r.indexOf("*/",w+2)+1,s===0&&(n||X?s=r.length:_("comment")),y=["comment",r.slice(w,s+1),w,s],w=s):(Li.lastIndex=w+1,Li.test(r),Li.lastIndex===0?s=r.length-1:s=Li.lastIndex-2,y=["word",r.slice(w,s+1),w,s],b.push(y),w=s);break}}return w++,y}function B(q){k.push(q)}return{back:B,nextToken:I,endOfFile:E,position:S}}});var $i=v((CT,$f)=>{l();"use strict";var Lf=it(),br=class extends Lf{constructor(e){super(e);this.type="atrule"}append(...e){return this.proxyOf.nodes||(this.nodes=[]),super.append(...e)}prepend(...e){return this.proxyOf.nodes||(this.nodes=[]),super.prepend(...e)}};$f.exports=br;br.default=br;Lf.registerAtRule(br)});var _t=v((AT,Uf)=>{l();"use strict";var jf=it(),zf,Vf,gt=class extends jf{constructor(e){super(e);this.type="root",this.nodes||(this.nodes=[])}removeChild(e,t){let r=this.index(e);return!t&&r===0&&this.nodes.length>1&&(this.nodes[1].raws.before=this.nodes[r].raws.before),super.removeChild(e)}normalize(e,t,r){let n=super.normalize(e);if(t){if(r==="prepend")this.nodes.length>1?t.raws.before=this.nodes[1].raws.before:delete t.raws.before;else if(this.first!==t)for(let a of n)a.raws.before=t.raws.before}return n}toResult(e={}){return new zf(new Vf,this,e).stringify()}};gt.registerLazyResult=i=>{zf=i};gt.registerProcessor=i=>{Vf=i};Uf.exports=gt;gt.default=gt;jf.registerRoot(gt)});var Ds=v((_T,Wf)=>{l();"use strict";var vr={split(i,e,t){let r=[],n="",a=!1,s=0,o=!1,u="",c=!1;for(let f of i)c?c=!1:f==="\\"?c=!0:o?f===u&&(o=!1):f==='"'||f==="'"?(o=!0,u=f):f==="("?s+=1:f===")"?s>0&&(s-=1):s===0&&e.includes(f)&&(a=!0),a?(n!==""&&r.push(n.trim()),n="",a=!1):n+=f;return(t||n!=="")&&r.push(n.trim()),r},space(i){let e=[" ",` +`," "];return vr.split(i,e)},comma(i){return vr.split(i,[","],!0)}};Wf.exports=vr;vr.default=vr});var ji=v((ET,Hf)=>{l();"use strict";var Gf=it(),D0=Ds(),xr=class extends Gf{constructor(e){super(e);this.type="rule",this.nodes||(this.nodes=[])}get selectors(){return D0.comma(this.selector)}set selectors(e){let t=this.selector?this.selector.match(/,\s*/):null,r=t?t[0]:","+this.raw("between","beforeOpen");this.selector=e.join(r)}};Hf.exports=xr;xr.default=xr;Gf.registerRule(xr)});var Kf=v((OT,Xf)=>{l();"use strict";var I0=gr(),q0=Nf(),R0=yr(),M0=$i(),B0=_t(),Yf=ji(),Qf={empty:!0,space:!0};function F0(i){for(let e=i.length-1;e>=0;e--){let t=i[e],r=t[3]||t[2];if(r)return r}}var Jf=class{constructor(e){this.input=e,this.root=new B0,this.current=this.root,this.spaces="",this.semicolon=!1,this.customProperty=!1,this.createTokenizer(),this.root.source={input:e,start:{offset:0,line:1,column:1}}}createTokenizer(){this.tokenizer=q0(this.input)}parse(){let e;for(;!this.tokenizer.endOfFile();)switch(e=this.tokenizer.nextToken(),e[0]){case"space":this.spaces+=e[1];break;case";":this.freeSemicolon(e);break;case"}":this.end(e);break;case"comment":this.comment(e);break;case"at-word":this.atrule(e);break;case"{":this.emptyRule(e);break;default:this.other(e);break}this.endFile()}comment(e){let t=new R0;this.init(t,e[2]),t.source.end=this.getPosition(e[3]||e[2]);let r=e[1].slice(2,-2);if(/^\s*$/.test(r))t.text="",t.raws.left=r,t.raws.right="";else{let n=r.match(/^(\s*)([^]*\S)(\s*)$/);t.text=n[2],t.raws.left=n[1],t.raws.right=n[3]}}emptyRule(e){let t=new Yf;this.init(t,e[2]),t.selector="",t.raws.between="",this.current=t}other(e){let t=!1,r=null,n=!1,a=null,s=[],o=e[1].startsWith("--"),u=[],c=e;for(;c;){if(r=c[0],u.push(c),r==="("||r==="[")a||(a=c),s.push(r==="("?")":"]");else if(o&&n&&r==="{")a||(a=c),s.push("}");else if(s.length===0)if(r===";")if(n){this.decl(u,o);return}else break;else if(r==="{"){this.rule(u);return}else if(r==="}"){this.tokenizer.back(u.pop()),t=!0;break}else r===":"&&(n=!0);else r===s[s.length-1]&&(s.pop(),s.length===0&&(a=null));c=this.tokenizer.nextToken()}if(this.tokenizer.endOfFile()&&(t=!0),s.length>0&&this.unclosedBracket(a),t&&n){if(!o)for(;u.length&&(c=u[u.length-1][0],!(c!=="space"&&c!=="comment"));)this.tokenizer.back(u.pop());this.decl(u,o)}else this.unknownWord(u)}rule(e){e.pop();let t=new Yf;this.init(t,e[0][2]),t.raws.between=this.spacesAndCommentsFromEnd(e),this.raw(t,"selector",e),this.current=t}decl(e,t){let r=new I0;this.init(r,e[0][2]);let n=e[e.length-1];for(n[0]===";"&&(this.semicolon=!0,e.pop()),r.source.end=this.getPosition(n[3]||n[2]||F0(e));e[0][0]!=="word";)e.length===1&&this.unknownWord(e),r.raws.before+=e.shift()[1];for(r.source.start=this.getPosition(e[0][2]),r.prop="";e.length;){let c=e[0][0];if(c===":"||c==="space"||c==="comment")break;r.prop+=e.shift()[1]}r.raws.between="";let a;for(;e.length;)if(a=e.shift(),a[0]===":"){r.raws.between+=a[1];break}else a[0]==="word"&&/\w/.test(a[1])&&this.unknownWord([a]),r.raws.between+=a[1];(r.prop[0]==="_"||r.prop[0]==="*")&&(r.raws.before+=r.prop[0],r.prop=r.prop.slice(1));let s=[],o;for(;e.length&&(o=e[0][0],!(o!=="space"&&o!=="comment"));)s.push(e.shift());this.precheckMissedSemicolon(e);for(let c=e.length-1;c>=0;c--){if(a=e[c],a[1].toLowerCase()==="!important"){r.important=!0;let f=this.stringFrom(e,c);f=this.spacesFromEnd(e)+f,f!==" !important"&&(r.raws.important=f);break}else if(a[1].toLowerCase()==="important"){let f=e.slice(0),p="";for(let d=c;d>0;d--){let h=f[d][0];if(p.trim().indexOf("!")===0&&h!=="space")break;p=f.pop()[1]+p}p.trim().indexOf("!")===0&&(r.important=!0,r.raws.important=p,e=f)}if(a[0]!=="space"&&a[0]!=="comment")break}e.some(c=>c[0]!=="space"&&c[0]!=="comment")&&(r.raws.between+=s.map(c=>c[1]).join(""),s=[]),this.raw(r,"value",s.concat(e),t),r.value.includes(":")&&!t&&this.checkMissedSemicolon(e)}atrule(e){let t=new M0;t.name=e[1].slice(1),t.name===""&&this.unnamedAtrule(t,e),this.init(t,e[2]);let r,n,a,s=!1,o=!1,u=[],c=[];for(;!this.tokenizer.endOfFile();){if(e=this.tokenizer.nextToken(),r=e[0],r==="("||r==="["?c.push(r==="("?")":"]"):r==="{"&&c.length>0?c.push("}"):r===c[c.length-1]&&c.pop(),c.length===0)if(r===";"){t.source.end=this.getPosition(e[2]),this.semicolon=!0;break}else if(r==="{"){o=!0;break}else if(r==="}"){if(u.length>0){for(a=u.length-1,n=u[a];n&&n[0]==="space";)n=u[--a];n&&(t.source.end=this.getPosition(n[3]||n[2]))}this.end(e);break}else u.push(e);else u.push(e);if(this.tokenizer.endOfFile()){s=!0;break}}t.raws.between=this.spacesAndCommentsFromEnd(u),u.length?(t.raws.afterName=this.spacesAndCommentsFromStart(u),this.raw(t,"params",u),s&&(e=u[u.length-1],t.source.end=this.getPosition(e[3]||e[2]),this.spaces=t.raws.between,t.raws.between="")):(t.raws.afterName="",t.params=""),o&&(t.nodes=[],this.current=t)}end(e){this.current.nodes&&this.current.nodes.length&&(this.current.raws.semicolon=this.semicolon),this.semicolon=!1,this.current.raws.after=(this.current.raws.after||"")+this.spaces,this.spaces="",this.current.parent?(this.current.source.end=this.getPosition(e[2]),this.current=this.current.parent):this.unexpectedClose(e)}endFile(){this.current.parent&&this.unclosedBlock(),this.current.nodes&&this.current.nodes.length&&(this.current.raws.semicolon=this.semicolon),this.current.raws.after=(this.current.raws.after||"")+this.spaces}freeSemicolon(e){if(this.spaces+=e[1],this.current.nodes){let t=this.current.nodes[this.current.nodes.length-1];t&&t.type==="rule"&&!t.raws.ownSemicolon&&(t.raws.ownSemicolon=this.spaces,this.spaces="")}}getPosition(e){let t=this.input.fromOffset(e);return{offset:e,line:t.line,column:t.col}}init(e,t){this.current.push(e),e.source={start:this.getPosition(t),input:this.input},e.raws.before=this.spaces,this.spaces="",e.type!=="comment"&&(this.semicolon=!1)}raw(e,t,r,n){let a,s,o=r.length,u="",c=!0,f,p;for(let d=0;dh+y[1],"");e.raws[t]={value:u,raw:d}}e[t]=u}spacesAndCommentsFromEnd(e){let t,r="";for(;e.length&&(t=e[e.length-1][0],!(t!=="space"&&t!=="comment"));)r=e.pop()[1]+r;return r}spacesAndCommentsFromStart(e){let t,r="";for(;e.length&&(t=e[0][0],!(t!=="space"&&t!=="comment"));)r+=e.shift()[1];return r}spacesFromEnd(e){let t,r="";for(;e.length&&(t=e[e.length-1][0],t==="space");)r=e.pop()[1]+r;return r}stringFrom(e,t){let r="";for(let n=t;n=0&&(n=e[a],!(n[0]!=="space"&&(r+=1,r===2)));a--);throw this.input.error("Missed semicolon",n[0]==="word"?n[3]+1:n[2])}};Xf.exports=Jf});var Zf=v(()=>{l()});var tc=v((DT,ec)=>{l();var N0="useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict",L0=(i,e=21)=>(t=e)=>{let r="",n=t;for(;n--;)r+=i[Math.random()*i.length|0];return r},$0=(i=21)=>{let e="",t=i;for(;t--;)e+=N0[Math.random()*64|0];return e};ec.exports={nanoid:$0,customAlphabet:L0}});var Is=v((IT,rc)=>{l();rc.exports={}});var Vi=v((qT,ac)=>{l();"use strict";var{SourceMapConsumer:j0,SourceMapGenerator:z0}=Zf(),{fileURLToPath:ic,pathToFileURL:zi}=(bs(),of),{resolve:qs,isAbsolute:Rs}=(mt(),nf),{nanoid:V0}=tc(),Ms=vs(),nc=ki(),U0=Is(),Bs=Symbol("fromOffsetCache"),W0=Boolean(j0&&z0),sc=Boolean(qs&&Rs),kr=class{constructor(e,t={}){if(e===null||typeof e=="undefined"||typeof e=="object"&&!e.toString)throw new Error(`PostCSS received ${e} instead of CSS string`);if(this.css=e.toString(),this.css[0]==="\uFEFF"||this.css[0]==="\uFFFE"?(this.hasBOM=!0,this.css=this.css.slice(1)):this.hasBOM=!1,t.from&&(!sc||/^\w+:\/\//.test(t.from)||Rs(t.from)?this.file=t.from:this.file=qs(t.from)),sc&&W0){let r=new U0(this.css,t);if(r.text){this.map=r;let n=r.consumer().file;!this.file&&n&&(this.file=this.mapResolve(n))}}this.file||(this.id=""),this.map&&(this.map.file=this.from)}fromOffset(e){let t,r;if(this[Bs])r=this[Bs];else{let a=this.css.split(` +`);r=new Array(a.length);let s=0;for(let o=0,u=a.length;o=t)n=r.length-1;else{let a=r.length-2,s;for(;n>1),e=r[s+1])n=s+1;else{n=s;break}}return{line:n+1,col:e-r[n]+1}}error(e,t,r,n={}){let a,s,o;if(t&&typeof t=="object"){let c=t,f=r;if(typeof c.offset=="number"){let p=this.fromOffset(c.offset);t=p.line,r=p.col}else t=c.line,r=c.column;if(typeof f.offset=="number"){let p=this.fromOffset(f.offset);s=p.line,o=p.col}else s=f.line,o=f.column}else if(!r){let c=this.fromOffset(t);t=c.line,r=c.col}let u=this.origin(t,r,s,o);return u?a=new nc(e,u.endLine===void 0?u.line:{line:u.line,column:u.column},u.endLine===void 0?u.column:{line:u.endLine,column:u.endColumn},u.source,u.file,n.plugin):a=new nc(e,s===void 0?t:{line:t,column:r},s===void 0?r:{line:s,column:o},this.css,this.file,n.plugin),a.input={line:t,column:r,endLine:s,endColumn:o,source:this.css},this.file&&(zi&&(a.input.url=zi(this.file).toString()),a.input.file=this.file),a}origin(e,t,r,n){if(!this.map)return!1;let a=this.map.consumer(),s=a.originalPositionFor({line:e,column:t});if(!s.source)return!1;let o;typeof r=="number"&&(o=a.originalPositionFor({line:r,column:n}));let u;Rs(s.source)?u=zi(s.source):u=new URL(s.source,this.map.consumer().sourceRoot||zi(this.map.mapFile));let c={url:u.toString(),line:s.line,column:s.column,endLine:o&&o.line,endColumn:o&&o.column};if(u.protocol==="file:")if(ic)c.file=ic(u);else throw new Error("file: protocol is not available in this PostCSS build");let f=a.sourceContentFor(s.source);return f&&(c.source=f),c}mapResolve(e){return/^\w+:\/\//.test(e)?e:qs(this.map.consumer().sourceRoot||this.map.root||".",e)}get from(){return this.file||this.id}toJSON(){let e={};for(let t of["hasBOM","css","file","id"])this[t]!=null&&(e[t]=this[t]);return this.map&&(e.map={...this.map},e.map.consumerCache&&(e.map.consumerCache=void 0)),e}};ac.exports=kr;kr.default=kr;Ms&&Ms.registerInput&&Ms.registerInput(kr)});var Wi=v((RT,oc)=>{l();"use strict";var G0=it(),H0=Kf(),Y0=Vi();function Ui(i,e){let t=new Y0(i,e),r=new H0(t);try{r.parse()}catch(n){throw n}return r.root}oc.exports=Ui;Ui.default=Ui;G0.registerParse(Ui)});var Ls=v((BT,cc)=>{l();"use strict";var{isClean:qe,my:Q0}=Si(),J0=As(),X0=hr(),K0=it(),Z0=Ti(),MT=Os(),lc=Ii(),ev=Wi(),tv=_t(),rv={document:"Document",root:"Root",atrule:"AtRule",rule:"Rule",decl:"Declaration",comment:"Comment"},iv={postcssPlugin:!0,prepare:!0,Once:!0,Document:!0,Root:!0,Declaration:!0,Rule:!0,AtRule:!0,Comment:!0,DeclarationExit:!0,RuleExit:!0,AtRuleExit:!0,CommentExit:!0,RootExit:!0,DocumentExit:!0,OnceExit:!0},nv={postcssPlugin:!0,prepare:!0,Once:!0},Et=0;function Sr(i){return typeof i=="object"&&typeof i.then=="function"}function uc(i){let e=!1,t=rv[i.type];return i.type==="decl"?e=i.prop.toLowerCase():i.type==="atrule"&&(e=i.name.toLowerCase()),e&&i.append?[t,t+"-"+e,Et,t+"Exit",t+"Exit-"+e]:e?[t,t+"-"+e,t+"Exit",t+"Exit-"+e]:i.append?[t,Et,t+"Exit"]:[t,t+"Exit"]}function fc(i){let e;return i.type==="document"?e=["Document",Et,"DocumentExit"]:i.type==="root"?e=["Root",Et,"RootExit"]:e=uc(i),{node:i,events:e,eventIndex:0,visitors:[],visitorIndex:0,iterator:0}}function Fs(i){return i[qe]=!1,i.nodes&&i.nodes.forEach(e=>Fs(e)),i}var Ns={},Ve=class{constructor(e,t,r){this.stringified=!1,this.processed=!1;let n;if(typeof t=="object"&&t!==null&&(t.type==="root"||t.type==="document"))n=Fs(t);else if(t instanceof Ve||t instanceof lc)n=Fs(t.root),t.map&&(typeof r.map=="undefined"&&(r.map={}),r.map.inline||(r.map.inline=!1),r.map.prev=t.map);else{let a=ev;r.syntax&&(a=r.syntax.parse),r.parser&&(a=r.parser),a.parse&&(a=a.parse);try{n=a(t,r)}catch(s){this.processed=!0,this.error=s}n&&!n[Q0]&&K0.rebuild(n)}this.result=new lc(e,n,r),this.helpers={...Ns,result:this.result,postcss:Ns},this.plugins=this.processor.plugins.map(a=>typeof a=="object"&&a.prepare?{...a,...a.prepare(this.result)}:a)}get[Symbol.toStringTag](){return"LazyResult"}get processor(){return this.result.processor}get opts(){return this.result.opts}get css(){return this.stringify().css}get content(){return this.stringify().content}get map(){return this.stringify().map}get root(){return this.sync().root}get messages(){return this.sync().messages}warnings(){return this.sync().warnings()}toString(){return this.css}then(e,t){return this.async().then(e,t)}catch(e){return this.async().catch(e)}finally(e){return this.async().then(e,e)}async(){return this.error?Promise.reject(this.error):this.processed?Promise.resolve(this.result):(this.processing||(this.processing=this.runAsync()),this.processing)}sync(){if(this.error)throw this.error;if(this.processed)return this.result;if(this.processed=!0,this.processing)throw this.getAsyncError();for(let e of this.plugins){let t=this.runOnRoot(e);if(Sr(t))throw this.getAsyncError()}if(this.prepareVisitors(),this.hasListener){let e=this.result.root;for(;!e[qe];)e[qe]=!0,this.walkSync(e);if(this.listeners.OnceExit)if(e.type==="document")for(let t of e.nodes)this.visitSync(this.listeners.OnceExit,t);else this.visitSync(this.listeners.OnceExit,e)}return this.result}stringify(){if(this.error)throw this.error;if(this.stringified)return this.result;this.stringified=!0,this.sync();let e=this.result.opts,t=X0;e.syntax&&(t=e.syntax.stringify),e.stringifier&&(t=e.stringifier),t.stringify&&(t=t.stringify);let n=new J0(t,this.result.root,this.result.opts).generate();return this.result.css=n[0],this.result.map=n[1],this.result}walkSync(e){e[qe]=!0;let t=uc(e);for(let r of t)if(r===Et)e.nodes&&e.each(n=>{n[qe]||this.walkSync(n)});else{let n=this.listeners[r];if(n&&this.visitSync(n,e.toProxy()))return}}visitSync(e,t){for(let[r,n]of e){this.result.lastPlugin=r;let a;try{a=n(t,this.helpers)}catch(s){throw this.handleError(s,t.proxyOf)}if(t.type!=="root"&&t.type!=="document"&&!t.parent)return!0;if(Sr(a))throw this.getAsyncError()}}runOnRoot(e){this.result.lastPlugin=e;try{if(typeof e=="object"&&e.Once){if(this.result.root.type==="document"){let t=this.result.root.nodes.map(r=>e.Once(r,this.helpers));return Sr(t[0])?Promise.all(t):t}return e.Once(this.result.root,this.helpers)}else if(typeof e=="function")return e(this.result.root,this.result)}catch(t){throw this.handleError(t)}}getAsyncError(){throw new Error("Use process(css).then(cb) to work with async plugins")}handleError(e,t){let r=this.result.lastPlugin;try{t&&t.addToError(e),this.error=e,e.name==="CssSyntaxError"&&!e.plugin?(e.plugin=r.postcssPlugin,e.setMessage()):r.postcssVersion}catch(n){console&&console.error&&console.error(n)}return e}async runAsync(){this.plugin=0;for(let e=0;e0;){let r=this.visitTick(t);if(Sr(r))try{await r}catch(n){let a=t[t.length-1].node;throw this.handleError(n,a)}}}if(this.listeners.OnceExit)for(let[t,r]of this.listeners.OnceExit){this.result.lastPlugin=t;try{if(e.type==="document"){let n=e.nodes.map(a=>r(a,this.helpers));await Promise.all(n)}else await r(e,this.helpers)}catch(n){throw this.handleError(n)}}}return this.processed=!0,this.stringify()}prepareVisitors(){this.listeners={};let e=(t,r,n)=>{this.listeners[r]||(this.listeners[r]=[]),this.listeners[r].push([t,n])};for(let t of this.plugins)if(typeof t=="object")for(let r in t){if(!iv[r]&&/^[A-Z]/.test(r))throw new Error(`Unknown event ${r} in ${t.postcssPlugin}. Try to update PostCSS (${this.processor.version} now).`);if(!nv[r])if(typeof t[r]=="object")for(let n in t[r])n==="*"?e(t,r,t[r][n]):e(t,r+"-"+n.toLowerCase(),t[r][n]);else typeof t[r]=="function"&&e(t,r,t[r])}this.hasListener=Object.keys(this.listeners).length>0}visitTick(e){let t=e[e.length-1],{node:r,visitors:n}=t;if(r.type!=="root"&&r.type!=="document"&&!r.parent){e.pop();return}if(n.length>0&&t.visitorIndex{Ns=i};cc.exports=Ve;Ve.default=Ve;tv.registerLazyResult(Ve);Z0.registerLazyResult(Ve)});var dc=v((NT,pc)=>{l();"use strict";var sv=As(),av=hr(),FT=Os(),ov=Wi(),lv=Ii(),Gi=class{constructor(e,t,r){t=t.toString(),this.stringified=!1,this._processor=e,this._css=t,this._opts=r,this._map=void 0;let n,a=av;this.result=new lv(this._processor,n,this._opts),this.result.css=t;let s=this;Object.defineProperty(this.result,"root",{get(){return s.root}});let o=new sv(a,n,this._opts,t);if(o.isMap()){let[u,c]=o.generate();u&&(this.result.css=u),c&&(this.result.map=c)}}get[Symbol.toStringTag](){return"NoWorkResult"}get processor(){return this.result.processor}get opts(){return this.result.opts}get css(){return this.result.css}get content(){return this.result.css}get map(){return this.result.map}get root(){if(this._root)return this._root;let e,t=ov;try{e=t(this._css,this._opts)}catch(r){this.error=r}if(this.error)throw this.error;return this._root=e,e}get messages(){return[]}warnings(){return[]}toString(){return this._css}then(e,t){return this.async().then(e,t)}catch(e){return this.async().catch(e)}finally(e){return this.async().then(e,e)}async(){return this.error?Promise.reject(this.error):Promise.resolve(this.result)}sync(){if(this.error)throw this.error;return this.result}};pc.exports=Gi;Gi.default=Gi});var mc=v((LT,hc)=>{l();"use strict";var uv=dc(),fv=Ls(),cv=Ti(),pv=_t(),Ot=class{constructor(e=[]){this.version="8.4.24",this.plugins=this.normalize(e)}use(e){return this.plugins=this.plugins.concat(this.normalize([e])),this}process(e,t={}){return this.plugins.length===0&&typeof t.parser=="undefined"&&typeof t.stringifier=="undefined"&&typeof t.syntax=="undefined"?new uv(this,e,t):new fv(this,e,t)}normalize(e){let t=[];for(let r of e)if(r.postcss===!0?r=r():r.postcss&&(r=r.postcss),typeof r=="object"&&Array.isArray(r.plugins))t=t.concat(r.plugins);else if(typeof r=="object"&&r.postcssPlugin)t.push(r);else if(typeof r=="function")t.push(r);else if(!(typeof r=="object"&&(r.parse||r.stringify)))throw new Error(r+" is not a PostCSS plugin");return t}};hc.exports=Ot;Ot.default=Ot;pv.registerProcessor(Ot);cv.registerProcessor(Ot)});var yc=v(($T,gc)=>{l();"use strict";var dv=gr(),hv=Is(),mv=yr(),gv=$i(),yv=Vi(),wv=_t(),bv=ji();function Cr(i,e){if(Array.isArray(i))return i.map(n=>Cr(n));let{inputs:t,...r}=i;if(t){e=[];for(let n of t){let a={...n,__proto__:yv.prototype};a.map&&(a.map={...a.map,__proto__:hv.prototype}),e.push(a)}}if(r.nodes&&(r.nodes=i.nodes.map(n=>Cr(n,e))),r.source){let{inputId:n,...a}=r.source;r.source=a,n!=null&&(r.source.input=e[n])}if(r.type==="root")return new wv(r);if(r.type==="decl")return new dv(r);if(r.type==="rule")return new bv(r);if(r.type==="comment")return new mv(r);if(r.type==="atrule")return new gv(r);throw new Error("Unknown node type: "+i.type)}gc.exports=Cr;Cr.default=Cr});var me=v((jT,Cc)=>{l();"use strict";var vv=ki(),wc=gr(),xv=Ls(),kv=it(),$s=mc(),Sv=hr(),Cv=yc(),bc=Ti(),Av=Ts(),vc=yr(),xc=$i(),_v=Ii(),Ev=Vi(),Ov=Wi(),Tv=Ds(),kc=ji(),Sc=_t(),Pv=mr();function j(...i){return i.length===1&&Array.isArray(i[0])&&(i=i[0]),new $s(i)}j.plugin=function(e,t){let r=!1;function n(...s){console&&console.warn&&!r&&(r=!0,console.warn(e+`: postcss.plugin was deprecated. Migration guide: +https://evilmartians.com/chronicles/postcss-8-plugin-migration`),m.env.LANG&&m.env.LANG.startsWith("cn")&&console.warn(e+`: \u91CC\u9762 postcss.plugin \u88AB\u5F03\u7528. \u8FC1\u79FB\u6307\u5357: +https://www.w3ctech.com/topic/2226`));let o=t(...s);return o.postcssPlugin=e,o.postcssVersion=new $s().version,o}let a;return Object.defineProperty(n,"postcss",{get(){return a||(a=n()),a}}),n.process=function(s,o,u){return j([n(u)]).process(s,o)},n};j.stringify=Sv;j.parse=Ov;j.fromJSON=Cv;j.list=Tv;j.comment=i=>new vc(i);j.atRule=i=>new xc(i);j.decl=i=>new wc(i);j.rule=i=>new kc(i);j.root=i=>new Sc(i);j.document=i=>new bc(i);j.CssSyntaxError=vv;j.Declaration=wc;j.Container=kv;j.Processor=$s;j.Document=bc;j.Comment=vc;j.Warning=Av;j.AtRule=xc;j.Result=_v;j.Input=Ev;j.Rule=kc;j.Root=Sc;j.Node=Pv;xv.registerPostcss(j);Cc.exports=j;j.default=j});var W,z,zT,VT,UT,WT,GT,HT,YT,QT,JT,XT,KT,ZT,eP,tP,rP,iP,nP,sP,aP,oP,lP,uP,fP,cP,nt=C(()=>{l();W=K(me()),z=W.default,zT=W.default.stringify,VT=W.default.fromJSON,UT=W.default.plugin,WT=W.default.parse,GT=W.default.list,HT=W.default.document,YT=W.default.comment,QT=W.default.atRule,JT=W.default.rule,XT=W.default.decl,KT=W.default.root,ZT=W.default.CssSyntaxError,eP=W.default.Declaration,tP=W.default.Container,rP=W.default.Processor,iP=W.default.Document,nP=W.default.Comment,sP=W.default.Warning,aP=W.default.AtRule,oP=W.default.Result,lP=W.default.Input,uP=W.default.Rule,fP=W.default.Root,cP=W.default.Node});var js=v((dP,Ac)=>{l();Ac.exports=function(i,e,t,r,n){for(e=e.split?e.split("."):e,r=0;r{l();"use strict";Hi.__esModule=!0;Hi.default=qv;function Dv(i){for(var e=i.toLowerCase(),t="",r=!1,n=0;n<6&&e[n]!==void 0;n++){var a=e.charCodeAt(n),s=a>=97&&a<=102||a>=48&&a<=57;if(r=a===32,!s)break;t+=e[n]}if(t.length!==0){var o=parseInt(t,16),u=o>=55296&&o<=57343;return u||o===0||o>1114111?["\uFFFD",t.length+(r?1:0)]:[String.fromCodePoint(o),t.length+(r?1:0)]}}var Iv=/\\/;function qv(i){var e=Iv.test(i);if(!e)return i;for(var t="",r=0;r{l();"use strict";Qi.__esModule=!0;Qi.default=Rv;function Rv(i){for(var e=arguments.length,t=new Array(e>1?e-1:0),r=1;r0;){var n=t.shift();if(!i[n])return;i=i[n]}return i}Ec.exports=Qi.default});var Pc=v((Ji,Tc)=>{l();"use strict";Ji.__esModule=!0;Ji.default=Mv;function Mv(i){for(var e=arguments.length,t=new Array(e>1?e-1:0),r=1;r0;){var n=t.shift();i[n]||(i[n]={}),i=i[n]}}Tc.exports=Ji.default});var Ic=v((Xi,Dc)=>{l();"use strict";Xi.__esModule=!0;Xi.default=Bv;function Bv(i){for(var e="",t=i.indexOf("/*"),r=0;t>=0;){e=e+i.slice(r,t);var n=i.indexOf("*/",t+2);if(n<0)return e;r=n+2,t=i.indexOf("/*",r)}return e=e+i.slice(r),e}Dc.exports=Xi.default});var Ar=v(Re=>{l();"use strict";Re.__esModule=!0;Re.unesc=Re.stripComments=Re.getProp=Re.ensureObject=void 0;var Fv=Ki(Yi());Re.unesc=Fv.default;var Nv=Ki(Oc());Re.getProp=Nv.default;var Lv=Ki(Pc());Re.ensureObject=Lv.default;var $v=Ki(Ic());Re.stripComments=$v.default;function Ki(i){return i&&i.__esModule?i:{default:i}}});var Ue=v((_r,Mc)=>{l();"use strict";_r.__esModule=!0;_r.default=void 0;var qc=Ar();function Rc(i,e){for(var t=0;tr||this.source.end.linen||this.source.end.line===r&&this.source.end.column{l();"use strict";G.__esModule=!0;G.UNIVERSAL=G.TAG=G.STRING=G.SELECTOR=G.ROOT=G.PSEUDO=G.NESTING=G.ID=G.COMMENT=G.COMBINATOR=G.CLASS=G.ATTRIBUTE=void 0;var Uv="tag";G.TAG=Uv;var Wv="string";G.STRING=Wv;var Gv="selector";G.SELECTOR=Gv;var Hv="root";G.ROOT=Hv;var Yv="pseudo";G.PSEUDO=Yv;var Qv="nesting";G.NESTING=Qv;var Jv="id";G.ID=Jv;var Xv="comment";G.COMMENT=Xv;var Kv="combinator";G.COMBINATOR=Kv;var Zv="class";G.CLASS=Zv;var ex="attribute";G.ATTRIBUTE=ex;var tx="universal";G.UNIVERSAL=tx});var Zi=v((Er,Lc)=>{l();"use strict";Er.__esModule=!0;Er.default=void 0;var rx=nx(Ue()),We=ix(ne());function Bc(i){if(typeof WeakMap!="function")return null;var e=new WeakMap,t=new WeakMap;return(Bc=function(n){return n?t:e})(i)}function ix(i,e){if(!e&&i&&i.__esModule)return i;if(i===null||typeof i!="object"&&typeof i!="function")return{default:i};var t=Bc(e);if(t&&t.has(i))return t.get(i);var r={},n=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var a in i)if(a!=="default"&&Object.prototype.hasOwnProperty.call(i,a)){var s=n?Object.getOwnPropertyDescriptor(i,a):null;s&&(s.get||s.set)?Object.defineProperty(r,a,s):r[a]=i[a]}return r.default=i,t&&t.set(i,r),r}function nx(i){return i&&i.__esModule?i:{default:i}}function sx(i,e){var t=typeof Symbol!="undefined"&&i[Symbol.iterator]||i["@@iterator"];if(t)return(t=t.call(i)).next.bind(t);if(Array.isArray(i)||(t=ax(i))||e&&i&&typeof i.length=="number"){t&&(i=t);var r=0;return function(){return r>=i.length?{done:!0}:{done:!1,value:i[r++]}}}throw new TypeError(`Invalid attempt to iterate non-iterable instance. +In order to be iterable, non-array objects must have a [Symbol.iterator]() method.`)}function ax(i,e){if(!!i){if(typeof i=="string")return Fc(i,e);var t=Object.prototype.toString.call(i).slice(8,-1);if(t==="Object"&&i.constructor&&(t=i.constructor.name),t==="Map"||t==="Set")return Array.from(i);if(t==="Arguments"||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t))return Fc(i,e)}}function Fc(i,e){(e==null||e>i.length)&&(e=i.length);for(var t=0,r=new Array(e);t=n&&(this.indexes[s]=a-1);return this},t.removeAll=function(){for(var n=sx(this.nodes),a;!(a=n()).done;){var s=a.value;s.parent=void 0}return this.nodes=[],this},t.empty=function(){return this.removeAll()},t.insertAfter=function(n,a){a.parent=this;var s=this.index(n);this.nodes.splice(s+1,0,a),a.parent=this;var o;for(var u in this.indexes)o=this.indexes[u],s<=o&&(this.indexes[u]=o+1);return this},t.insertBefore=function(n,a){a.parent=this;var s=this.index(n);this.nodes.splice(s,0,a),a.parent=this;var o;for(var u in this.indexes)o=this.indexes[u],o<=s&&(this.indexes[u]=o+1);return this},t._findChildAtPosition=function(n,a){var s=void 0;return this.each(function(o){if(o.atPosition){var u=o.atPosition(n,a);if(u)return s=u,!1}else if(o.isAtPosition(n,a))return s=o,!1}),s},t.atPosition=function(n,a){if(this.isAtPosition(n,a))return this._findChildAtPosition(n,a)||this},t._inferEndPosition=function(){this.last&&this.last.source&&this.last.source.end&&(this.source=this.source||{},this.source.end=this.source.end||{},Object.assign(this.source.end,this.last.source.end))},t.each=function(n){this.lastEach||(this.lastEach=0),this.indexes||(this.indexes={}),this.lastEach++;var a=this.lastEach;if(this.indexes[a]=0,!!this.length){for(var s,o;this.indexes[a]{l();"use strict";Or.__esModule=!0;Or.default=void 0;var fx=px(Zi()),cx=ne();function px(i){return i&&i.__esModule?i:{default:i}}function $c(i,e){for(var t=0;t{l();"use strict";Tr.__esModule=!0;Tr.default=void 0;var gx=wx(Zi()),yx=ne();function wx(i){return i&&i.__esModule?i:{default:i}}function bx(i,e){i.prototype=Object.create(e.prototype),i.prototype.constructor=i,Ws(i,e)}function Ws(i,e){return Ws=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(r,n){return r.__proto__=n,r},Ws(i,e)}var vx=function(i){bx(e,i);function e(t){var r;return r=i.call(this,t)||this,r.type=yx.SELECTOR,r}return e}(gx.default);Tr.default=vx;zc.exports=Tr.default});var en=v((gP,Vc)=>{l();"use strict";var xx={},kx=xx.hasOwnProperty,Sx=function(e,t){if(!e)return t;var r={};for(var n in t)r[n]=kx.call(e,n)?e[n]:t[n];return r},Cx=/[ -,\.\/:-@\[-\^`\{-~]/,Ax=/[ -,\.\/:-@\[\]\^`\{-~]/,_x=/(^|\\+)?(\\[A-F0-9]{1,6})\x20(?![a-fA-F0-9\x20])/g,Hs=function i(e,t){t=Sx(t,i.options),t.quotes!="single"&&t.quotes!="double"&&(t.quotes="single");for(var r=t.quotes=="double"?'"':"'",n=t.isIdentifier,a=e.charAt(0),s="",o=0,u=e.length;o126){if(f>=55296&&f<=56319&&o{l();"use strict";Pr.__esModule=!0;Pr.default=void 0;var Ex=Uc(en()),Ox=Ar(),Tx=Uc(Ue()),Px=ne();function Uc(i){return i&&i.__esModule?i:{default:i}}function Wc(i,e){for(var t=0;t{l();"use strict";Dr.__esModule=!0;Dr.default=void 0;var Rx=Bx(Ue()),Mx=ne();function Bx(i){return i&&i.__esModule?i:{default:i}}function Fx(i,e){i.prototype=Object.create(e.prototype),i.prototype.constructor=i,Js(i,e)}function Js(i,e){return Js=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(r,n){return r.__proto__=n,r},Js(i,e)}var Nx=function(i){Fx(e,i);function e(t){var r;return r=i.call(this,t)||this,r.type=Mx.COMMENT,r}return e}(Rx.default);Dr.default=Nx;Hc.exports=Dr.default});var Zs=v((Ir,Yc)=>{l();"use strict";Ir.__esModule=!0;Ir.default=void 0;var Lx=jx(Ue()),$x=ne();function jx(i){return i&&i.__esModule?i:{default:i}}function zx(i,e){i.prototype=Object.create(e.prototype),i.prototype.constructor=i,Ks(i,e)}function Ks(i,e){return Ks=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(r,n){return r.__proto__=n,r},Ks(i,e)}var Vx=function(i){zx(e,i);function e(r){var n;return n=i.call(this,r)||this,n.type=$x.ID,n}var t=e.prototype;return t.valueToString=function(){return"#"+i.prototype.valueToString.call(this)},e}(Lx.default);Ir.default=Vx;Yc.exports=Ir.default});var tn=v((qr,Xc)=>{l();"use strict";qr.__esModule=!0;qr.default=void 0;var Ux=Qc(en()),Wx=Ar(),Gx=Qc(Ue());function Qc(i){return i&&i.__esModule?i:{default:i}}function Jc(i,e){for(var t=0;t{l();"use strict";Rr.__esModule=!0;Rr.default=void 0;var Jx=Kx(tn()),Xx=ne();function Kx(i){return i&&i.__esModule?i:{default:i}}function Zx(i,e){i.prototype=Object.create(e.prototype),i.prototype.constructor=i,ta(i,e)}function ta(i,e){return ta=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(r,n){return r.__proto__=n,r},ta(i,e)}var e1=function(i){Zx(e,i);function e(t){var r;return r=i.call(this,t)||this,r.type=Xx.TAG,r}return e}(Jx.default);Rr.default=e1;Kc.exports=Rr.default});var na=v((Mr,Zc)=>{l();"use strict";Mr.__esModule=!0;Mr.default=void 0;var t1=i1(Ue()),r1=ne();function i1(i){return i&&i.__esModule?i:{default:i}}function n1(i,e){i.prototype=Object.create(e.prototype),i.prototype.constructor=i,ia(i,e)}function ia(i,e){return ia=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(r,n){return r.__proto__=n,r},ia(i,e)}var s1=function(i){n1(e,i);function e(t){var r;return r=i.call(this,t)||this,r.type=r1.STRING,r}return e}(t1.default);Mr.default=s1;Zc.exports=Mr.default});var aa=v((Br,ep)=>{l();"use strict";Br.__esModule=!0;Br.default=void 0;var a1=l1(Zi()),o1=ne();function l1(i){return i&&i.__esModule?i:{default:i}}function u1(i,e){i.prototype=Object.create(e.prototype),i.prototype.constructor=i,sa(i,e)}function sa(i,e){return sa=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(r,n){return r.__proto__=n,r},sa(i,e)}var f1=function(i){u1(e,i);function e(r){var n;return n=i.call(this,r)||this,n.type=o1.PSEUDO,n}var t=e.prototype;return t.toString=function(){var n=this.length?"("+this.map(String).join(",")+")":"";return[this.rawSpaceBefore,this.stringifyProperty("value"),n,this.rawSpaceAfter].join("")},e}(a1.default);Br.default=f1;ep.exports=Br.default});var tp={};Ae(tp,{deprecate:()=>c1});function c1(i){return i}var rp=C(()=>{l()});var np=v((yP,ip)=>{l();ip.exports=(rp(),tp).deprecate});var pa=v(Lr=>{l();"use strict";Lr.__esModule=!0;Lr.default=void 0;Lr.unescapeValue=fa;var Fr=la(en()),p1=la(Yi()),d1=la(tn()),h1=ne(),oa;function la(i){return i&&i.__esModule?i:{default:i}}function sp(i,e){for(var t=0;t0&&!n.quoted&&o.before.length===0&&!(n.spaces.value&&n.spaces.value.after)&&(o.before=" "),ap(s,o)}))),a.push("]"),a.push(this.rawSpaceAfter),a.join("")},m1(e,[{key:"quoted",get:function(){var n=this.quoteMark;return n==="'"||n==='"'},set:function(n){b1()}},{key:"quoteMark",get:function(){return this._quoteMark},set:function(n){if(!this._constructed){this._quoteMark=n;return}this._quoteMark!==n&&(this._quoteMark=n,this._syncRawValue())}},{key:"qualifiedAttribute",get:function(){return this.qualifiedName(this.raws.attribute||this.attribute)}},{key:"insensitiveFlag",get:function(){return this.insensitive?"i":""}},{key:"value",get:function(){return this._value},set:function(n){if(this._constructed){var a=fa(n),s=a.deprecatedUsage,o=a.unescaped,u=a.quoteMark;if(s&&w1(),o===this._value&&u===this._quoteMark)return;this._value=o,this._quoteMark=u,this._syncRawValue()}else this._value=n}},{key:"insensitive",get:function(){return this._insensitive},set:function(n){n||(this._insensitive=!1,this.raws&&(this.raws.insensitiveFlag==="I"||this.raws.insensitiveFlag==="i")&&(this.raws.insensitiveFlag=void 0)),this._insensitive=n}},{key:"attribute",get:function(){return this._attribute},set:function(n){this._handleEscapes("attribute",n),this._attribute=n}}]),e}(d1.default);Lr.default=rn;rn.NO_QUOTE=null;rn.SINGLE_QUOTE="'";rn.DOUBLE_QUOTE='"';var ca=(oa={"'":{quotes:"single",wrap:!0},'"':{quotes:"double",wrap:!0}},oa[null]={isIdentifier:!0},oa);function ap(i,e){return""+e.before+i+e.after}});var ha=v(($r,op)=>{l();"use strict";$r.__esModule=!0;$r.default=void 0;var k1=C1(tn()),S1=ne();function C1(i){return i&&i.__esModule?i:{default:i}}function A1(i,e){i.prototype=Object.create(e.prototype),i.prototype.constructor=i,da(i,e)}function da(i,e){return da=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(r,n){return r.__proto__=n,r},da(i,e)}var _1=function(i){A1(e,i);function e(t){var r;return r=i.call(this,t)||this,r.type=S1.UNIVERSAL,r.value="*",r}return e}(k1.default);$r.default=_1;op.exports=$r.default});var ga=v((jr,lp)=>{l();"use strict";jr.__esModule=!0;jr.default=void 0;var E1=T1(Ue()),O1=ne();function T1(i){return i&&i.__esModule?i:{default:i}}function P1(i,e){i.prototype=Object.create(e.prototype),i.prototype.constructor=i,ma(i,e)}function ma(i,e){return ma=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(r,n){return r.__proto__=n,r},ma(i,e)}var D1=function(i){P1(e,i);function e(t){var r;return r=i.call(this,t)||this,r.type=O1.COMBINATOR,r}return e}(E1.default);jr.default=D1;lp.exports=jr.default});var wa=v((zr,up)=>{l();"use strict";zr.__esModule=!0;zr.default=void 0;var I1=R1(Ue()),q1=ne();function R1(i){return i&&i.__esModule?i:{default:i}}function M1(i,e){i.prototype=Object.create(e.prototype),i.prototype.constructor=i,ya(i,e)}function ya(i,e){return ya=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(r,n){return r.__proto__=n,r},ya(i,e)}var B1=function(i){M1(e,i);function e(t){var r;return r=i.call(this,t)||this,r.type=q1.NESTING,r.value="&",r}return e}(I1.default);zr.default=B1;up.exports=zr.default});var cp=v((nn,fp)=>{l();"use strict";nn.__esModule=!0;nn.default=F1;function F1(i){return i.sort(function(e,t){return e-t})}fp.exports=nn.default});var ba=v(D=>{l();"use strict";D.__esModule=!0;D.word=D.tilde=D.tab=D.str=D.space=D.slash=D.singleQuote=D.semicolon=D.plus=D.pipe=D.openSquare=D.openParenthesis=D.newline=D.greaterThan=D.feed=D.equals=D.doubleQuote=D.dollar=D.cr=D.comment=D.comma=D.combinator=D.colon=D.closeSquare=D.closeParenthesis=D.caret=D.bang=D.backslash=D.at=D.asterisk=D.ampersand=void 0;var N1=38;D.ampersand=N1;var L1=42;D.asterisk=L1;var $1=64;D.at=$1;var j1=44;D.comma=j1;var z1=58;D.colon=z1;var V1=59;D.semicolon=V1;var U1=40;D.openParenthesis=U1;var W1=41;D.closeParenthesis=W1;var G1=91;D.openSquare=G1;var H1=93;D.closeSquare=H1;var Y1=36;D.dollar=Y1;var Q1=126;D.tilde=Q1;var J1=94;D.caret=J1;var X1=43;D.plus=X1;var K1=61;D.equals=K1;var Z1=124;D.pipe=Z1;var ek=62;D.greaterThan=ek;var tk=32;D.space=tk;var pp=39;D.singleQuote=pp;var rk=34;D.doubleQuote=rk;var ik=47;D.slash=ik;var nk=33;D.bang=nk;var sk=92;D.backslash=sk;var ak=13;D.cr=ak;var ok=12;D.feed=ok;var lk=10;D.newline=lk;var uk=9;D.tab=uk;var fk=pp;D.str=fk;var ck=-1;D.comment=ck;var pk=-2;D.word=pk;var dk=-3;D.combinator=dk});var mp=v(Vr=>{l();"use strict";Vr.__esModule=!0;Vr.FIELDS=void 0;Vr.default=vk;var O=hk(ba()),Tt,V;function dp(i){if(typeof WeakMap!="function")return null;var e=new WeakMap,t=new WeakMap;return(dp=function(n){return n?t:e})(i)}function hk(i,e){if(!e&&i&&i.__esModule)return i;if(i===null||typeof i!="object"&&typeof i!="function")return{default:i};var t=dp(e);if(t&&t.has(i))return t.get(i);var r={},n=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var a in i)if(a!=="default"&&Object.prototype.hasOwnProperty.call(i,a)){var s=n?Object.getOwnPropertyDescriptor(i,a):null;s&&(s.get||s.set)?Object.defineProperty(r,a,s):r[a]=i[a]}return r.default=i,t&&t.set(i,r),r}var mk=(Tt={},Tt[O.tab]=!0,Tt[O.newline]=!0,Tt[O.cr]=!0,Tt[O.feed]=!0,Tt),gk=(V={},V[O.space]=!0,V[O.tab]=!0,V[O.newline]=!0,V[O.cr]=!0,V[O.feed]=!0,V[O.ampersand]=!0,V[O.asterisk]=!0,V[O.bang]=!0,V[O.comma]=!0,V[O.colon]=!0,V[O.semicolon]=!0,V[O.openParenthesis]=!0,V[O.closeParenthesis]=!0,V[O.openSquare]=!0,V[O.closeSquare]=!0,V[O.singleQuote]=!0,V[O.doubleQuote]=!0,V[O.plus]=!0,V[O.pipe]=!0,V[O.tilde]=!0,V[O.greaterThan]=!0,V[O.equals]=!0,V[O.dollar]=!0,V[O.caret]=!0,V[O.slash]=!0,V),va={},hp="0123456789abcdefABCDEF";for(sn=0;sn0?(k=s+x,S=b-w[x].length):(k=s,S=a),E=O.comment,s=k,d=k,p=b-S):c===O.slash?(b=o,E=c,d=s,p=o-a,u=b+1):(b=yk(t,o),E=O.word,d=s,p=b-a),u=b+1;break}e.push([E,s,o-a,d,p,o,u]),S&&(a=S,S=null),o=u}return e}});var Sp=v((Ur,kp)=>{l();"use strict";Ur.__esModule=!0;Ur.default=void 0;var xk=we(Us()),xa=we(Gs()),kk=we(Qs()),gp=we(Xs()),Sk=we(Zs()),Ck=we(ra()),ka=we(na()),Ak=we(aa()),yp=an(pa()),_k=we(ha()),Sa=we(ga()),Ek=we(wa()),Ok=we(cp()),A=an(mp()),T=an(ba()),Tk=an(ne()),Y=Ar(),yt,Ca;function wp(i){if(typeof WeakMap!="function")return null;var e=new WeakMap,t=new WeakMap;return(wp=function(n){return n?t:e})(i)}function an(i,e){if(!e&&i&&i.__esModule)return i;if(i===null||typeof i!="object"&&typeof i!="function")return{default:i};var t=wp(e);if(t&&t.has(i))return t.get(i);var r={},n=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var a in i)if(a!=="default"&&Object.prototype.hasOwnProperty.call(i,a)){var s=n?Object.getOwnPropertyDescriptor(i,a):null;s&&(s.get||s.set)?Object.defineProperty(r,a,s):r[a]=i[a]}return r.default=i,t&&t.set(i,r),r}function we(i){return i&&i.__esModule?i:{default:i}}function bp(i,e){for(var t=0;t0){var s=this.current.last;if(s){var o=this.convertWhitespaceNodesToSpace(a),u=o.space,c=o.rawSpace;c!==void 0&&(s.rawSpaceAfter+=c),s.spaces.after+=u}else a.forEach(function(E){return r.newNode(E)})}return}var f=this.currToken,p=void 0;n>this.position&&(p=this.parseWhitespaceEquivalentTokens(n));var d;if(this.isNamedCombinator()?d=this.namedCombinator():this.currToken[A.FIELDS.TYPE]===T.combinator?(d=new Sa.default({value:this.content(),source:Pt(this.currToken),sourceIndex:this.currToken[A.FIELDS.START_POS]}),this.position++):Aa[this.currToken[A.FIELDS.TYPE]]||p||this.unexpected(),d){if(p){var h=this.convertWhitespaceNodesToSpace(p),y=h.space,x=h.rawSpace;d.spaces.before=y,d.rawSpaceBefore=x}}else{var w=this.convertWhitespaceNodesToSpace(p,!0),b=w.space,k=w.rawSpace;k||(k=b);var S={},_={spaces:{}};b.endsWith(" ")&&k.endsWith(" ")?(S.before=b.slice(0,b.length-1),_.spaces.before=k.slice(0,k.length-1)):b.startsWith(" ")&&k.startsWith(" ")?(S.after=b.slice(1),_.spaces.after=k.slice(1)):_.value=k,d=new Sa.default({value:" ",source:_a(f,this.tokens[this.position-1]),sourceIndex:f[A.FIELDS.START_POS],spaces:S,raws:_})}return this.currToken&&this.currToken[A.FIELDS.TYPE]===T.space&&(d.spaces.after=this.optionalSpace(this.content()),this.position++),this.newNode(d)},e.comma=function(){if(this.position===this.tokens.length-1){this.root.trailingComma=!0,this.position++;return}this.current._inferEndPosition();var r=new xa.default({source:{start:vp(this.tokens[this.position+1])}});this.current.parent.append(r),this.current=r,this.position++},e.comment=function(){var r=this.currToken;this.newNode(new gp.default({value:this.content(),source:Pt(r),sourceIndex:r[A.FIELDS.START_POS]})),this.position++},e.error=function(r,n){throw this.root.error(r,n)},e.missingBackslash=function(){return this.error("Expected a backslash preceding the semicolon.",{index:this.currToken[A.FIELDS.START_POS]})},e.missingParenthesis=function(){return this.expected("opening parenthesis",this.currToken[A.FIELDS.START_POS])},e.missingSquareBracket=function(){return this.expected("opening square bracket",this.currToken[A.FIELDS.START_POS])},e.unexpected=function(){return this.error("Unexpected '"+this.content()+"'. Escaping special characters with \\ may help.",this.currToken[A.FIELDS.START_POS])},e.unexpectedPipe=function(){return this.error("Unexpected '|'.",this.currToken[A.FIELDS.START_POS])},e.namespace=function(){var r=this.prevToken&&this.content(this.prevToken)||!0;if(this.nextToken[A.FIELDS.TYPE]===T.word)return this.position++,this.word(r);if(this.nextToken[A.FIELDS.TYPE]===T.asterisk)return this.position++,this.universal(r);this.unexpectedPipe()},e.nesting=function(){if(this.nextToken){var r=this.content(this.nextToken);if(r==="|"){this.position++;return}}var n=this.currToken;this.newNode(new Ek.default({value:this.content(),source:Pt(n),sourceIndex:n[A.FIELDS.START_POS]})),this.position++},e.parentheses=function(){var r=this.current.last,n=1;if(this.position++,r&&r.type===Tk.PSEUDO){var a=new xa.default({source:{start:vp(this.tokens[this.position-1])}}),s=this.current;for(r.append(a),this.current=a;this.position1&&r.nextToken&&r.nextToken[A.FIELDS.TYPE]===T.openParenthesis&&r.error("Misplaced parenthesis.",{index:r.nextToken[A.FIELDS.START_POS]})});else return this.expected(["pseudo-class","pseudo-element"],this.currToken[A.FIELDS.START_POS])},e.space=function(){var r=this.content();this.position===0||this.prevToken[A.FIELDS.TYPE]===T.comma||this.prevToken[A.FIELDS.TYPE]===T.openParenthesis||this.current.nodes.every(function(n){return n.type==="comment"})?(this.spaces=this.optionalSpace(r),this.position++):this.position===this.tokens.length-1||this.nextToken[A.FIELDS.TYPE]===T.comma||this.nextToken[A.FIELDS.TYPE]===T.closeParenthesis?(this.current.last.spaces.after=this.optionalSpace(r),this.position++):this.combinator()},e.string=function(){var r=this.currToken;this.newNode(new ka.default({value:this.content(),source:Pt(r),sourceIndex:r[A.FIELDS.START_POS]})),this.position++},e.universal=function(r){var n=this.nextToken;if(n&&this.content(n)==="|")return this.position++,this.namespace();var a=this.currToken;this.newNode(new _k.default({value:this.content(),source:Pt(a),sourceIndex:a[A.FIELDS.START_POS]}),r),this.position++},e.splitWord=function(r,n){for(var a=this,s=this.nextToken,o=this.content();s&&~[T.dollar,T.caret,T.equals,T.word].indexOf(s[A.FIELDS.TYPE]);){this.position++;var u=this.content();if(o+=u,u.lastIndexOf("\\")===u.length-1){var c=this.nextToken;c&&c[A.FIELDS.TYPE]===T.space&&(o+=this.requiredSpace(this.content(c)),this.position++)}s=this.nextToken}var f=Ea(o,".").filter(function(y){var x=o[y-1]==="\\",w=/^\d+\.\d+%$/.test(o);return!x&&!w}),p=Ea(o,"#").filter(function(y){return o[y-1]!=="\\"}),d=Ea(o,"#{");d.length&&(p=p.filter(function(y){return!~d.indexOf(y)}));var h=(0,Ok.default)(Ik([0].concat(f,p)));h.forEach(function(y,x){var w=h[x+1]||o.length,b=o.slice(y,w);if(x===0&&n)return n.call(a,b,h.length);var k,S=a.currToken,_=S[A.FIELDS.START_POS]+h[x],E=wt(S[1],S[2]+y,S[3],S[2]+(w-1));if(~f.indexOf(y)){var I={value:b.slice(1),source:E,sourceIndex:_};k=new kk.default(Dt(I,"value"))}else if(~p.indexOf(y)){var B={value:b.slice(1),source:E,sourceIndex:_};k=new Sk.default(Dt(B,"value"))}else{var q={value:b,source:E,sourceIndex:_};Dt(q,"value"),k=new Ck.default(q)}a.newNode(k,r),r=null}),this.position++},e.word=function(r){var n=this.nextToken;return n&&this.content(n)==="|"?(this.position++,this.namespace()):this.splitWord(r)},e.loop=function(){for(;this.position{l();"use strict";Wr.__esModule=!0;Wr.default=void 0;var Rk=Mk(Sp());function Mk(i){return i&&i.__esModule?i:{default:i}}var Bk=function(){function i(t,r){this.func=t||function(){},this.funcRes=null,this.options=r}var e=i.prototype;return e._shouldUpdateSelector=function(r,n){n===void 0&&(n={});var a=Object.assign({},this.options,n);return a.updateSelector===!1?!1:typeof r!="string"},e._isLossy=function(r){r===void 0&&(r={});var n=Object.assign({},this.options,r);return n.lossless===!1},e._root=function(r,n){n===void 0&&(n={});var a=new Rk.default(r,this._parseOptions(n));return a.root},e._parseOptions=function(r){return{lossy:this._isLossy(r)}},e._run=function(r,n){var a=this;return n===void 0&&(n={}),new Promise(function(s,o){try{var u=a._root(r,n);Promise.resolve(a.func(u)).then(function(c){var f=void 0;return a._shouldUpdateSelector(r,n)&&(f=u.toString(),r.selector=f),{transform:c,root:u,string:f}}).then(s,o)}catch(c){o(c);return}})},e._runSync=function(r,n){n===void 0&&(n={});var a=this._root(r,n),s=this.func(a);if(s&&typeof s.then=="function")throw new Error("Selector processor returned a promise to a synchronous call.");var o=void 0;return n.updateSelector&&typeof r!="string"&&(o=a.toString(),r.selector=o),{transform:s,root:a,string:o}},e.ast=function(r,n){return this._run(r,n).then(function(a){return a.root})},e.astSync=function(r,n){return this._runSync(r,n).root},e.transform=function(r,n){return this._run(r,n).then(function(a){return a.transform})},e.transformSync=function(r,n){return this._runSync(r,n).transform},e.process=function(r,n){return this._run(r,n).then(function(a){return a.string||a.root.toString()})},e.processSync=function(r,n){var a=this._runSync(r,n);return a.string||a.root.toString()},i}();Wr.default=Bk;Cp.exports=Wr.default});var _p=v(H=>{l();"use strict";H.__esModule=!0;H.universal=H.tag=H.string=H.selector=H.root=H.pseudo=H.nesting=H.id=H.comment=H.combinator=H.className=H.attribute=void 0;var Fk=be(pa()),Nk=be(Qs()),Lk=be(ga()),$k=be(Xs()),jk=be(Zs()),zk=be(wa()),Vk=be(aa()),Uk=be(Us()),Wk=be(Gs()),Gk=be(na()),Hk=be(ra()),Yk=be(ha());function be(i){return i&&i.__esModule?i:{default:i}}var Qk=function(e){return new Fk.default(e)};H.attribute=Qk;var Jk=function(e){return new Nk.default(e)};H.className=Jk;var Xk=function(e){return new Lk.default(e)};H.combinator=Xk;var Kk=function(e){return new $k.default(e)};H.comment=Kk;var Zk=function(e){return new jk.default(e)};H.id=Zk;var eS=function(e){return new zk.default(e)};H.nesting=eS;var tS=function(e){return new Vk.default(e)};H.pseudo=tS;var rS=function(e){return new Uk.default(e)};H.root=rS;var iS=function(e){return new Wk.default(e)};H.selector=iS;var nS=function(e){return new Gk.default(e)};H.string=nS;var sS=function(e){return new Hk.default(e)};H.tag=sS;var aS=function(e){return new Yk.default(e)};H.universal=aS});var Pp=v(L=>{l();"use strict";L.__esModule=!0;L.isComment=L.isCombinator=L.isClassName=L.isAttribute=void 0;L.isContainer=wS;L.isIdentifier=void 0;L.isNamespace=bS;L.isNesting=void 0;L.isNode=Oa;L.isPseudo=void 0;L.isPseudoClass=yS;L.isPseudoElement=Tp;L.isUniversal=L.isTag=L.isString=L.isSelector=L.isRoot=void 0;var Q=ne(),fe,oS=(fe={},fe[Q.ATTRIBUTE]=!0,fe[Q.CLASS]=!0,fe[Q.COMBINATOR]=!0,fe[Q.COMMENT]=!0,fe[Q.ID]=!0,fe[Q.NESTING]=!0,fe[Q.PSEUDO]=!0,fe[Q.ROOT]=!0,fe[Q.SELECTOR]=!0,fe[Q.STRING]=!0,fe[Q.TAG]=!0,fe[Q.UNIVERSAL]=!0,fe);function Oa(i){return typeof i=="object"&&oS[i.type]}function ve(i,e){return Oa(e)&&e.type===i}var Ep=ve.bind(null,Q.ATTRIBUTE);L.isAttribute=Ep;var lS=ve.bind(null,Q.CLASS);L.isClassName=lS;var uS=ve.bind(null,Q.COMBINATOR);L.isCombinator=uS;var fS=ve.bind(null,Q.COMMENT);L.isComment=fS;var cS=ve.bind(null,Q.ID);L.isIdentifier=cS;var pS=ve.bind(null,Q.NESTING);L.isNesting=pS;var Ta=ve.bind(null,Q.PSEUDO);L.isPseudo=Ta;var dS=ve.bind(null,Q.ROOT);L.isRoot=dS;var hS=ve.bind(null,Q.SELECTOR);L.isSelector=hS;var mS=ve.bind(null,Q.STRING);L.isString=mS;var Op=ve.bind(null,Q.TAG);L.isTag=Op;var gS=ve.bind(null,Q.UNIVERSAL);L.isUniversal=gS;function Tp(i){return Ta(i)&&i.value&&(i.value.startsWith("::")||i.value.toLowerCase()===":before"||i.value.toLowerCase()===":after"||i.value.toLowerCase()===":first-letter"||i.value.toLowerCase()===":first-line")}function yS(i){return Ta(i)&&!Tp(i)}function wS(i){return!!(Oa(i)&&i.walk)}function bS(i){return Ep(i)||Op(i)}});var Dp=v(Oe=>{l();"use strict";Oe.__esModule=!0;var Pa=ne();Object.keys(Pa).forEach(function(i){i==="default"||i==="__esModule"||i in Oe&&Oe[i]===Pa[i]||(Oe[i]=Pa[i])});var Da=_p();Object.keys(Da).forEach(function(i){i==="default"||i==="__esModule"||i in Oe&&Oe[i]===Da[i]||(Oe[i]=Da[i])});var Ia=Pp();Object.keys(Ia).forEach(function(i){i==="default"||i==="__esModule"||i in Oe&&Oe[i]===Ia[i]||(Oe[i]=Ia[i])})});var Me=v((Gr,qp)=>{l();"use strict";Gr.__esModule=!0;Gr.default=void 0;var vS=SS(Ap()),xS=kS(Dp());function Ip(i){if(typeof WeakMap!="function")return null;var e=new WeakMap,t=new WeakMap;return(Ip=function(n){return n?t:e})(i)}function kS(i,e){if(!e&&i&&i.__esModule)return i;if(i===null||typeof i!="object"&&typeof i!="function")return{default:i};var t=Ip(e);if(t&&t.has(i))return t.get(i);var r={},n=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var a in i)if(a!=="default"&&Object.prototype.hasOwnProperty.call(i,a)){var s=n?Object.getOwnPropertyDescriptor(i,a):null;s&&(s.get||s.set)?Object.defineProperty(r,a,s):r[a]=i[a]}return r.default=i,t&&t.set(i,r),r}function SS(i){return i&&i.__esModule?i:{default:i}}var qa=function(e){return new vS.default(e)};Object.assign(qa,xS);delete qa.__esModule;var CS=qa;Gr.default=CS;qp.exports=Gr.default});function Ge(i){return["fontSize","outline"].includes(i)?e=>(typeof e=="function"&&(e=e({})),Array.isArray(e)&&(e=e[0]),e):i==="fontFamily"?e=>{typeof e=="function"&&(e=e({}));let t=Array.isArray(e)&&ie(e[1])?e[0]:e;return Array.isArray(t)?t.join(", "):t}:["boxShadow","transitionProperty","transitionDuration","transitionDelay","transitionTimingFunction","backgroundImage","backgroundSize","backgroundColor","cursor","animation"].includes(i)?e=>(typeof e=="function"&&(e=e({})),Array.isArray(e)&&(e=e.join(", ")),e):["gridTemplateColumns","gridTemplateRows","objectPosition"].includes(i)?e=>(typeof e=="function"&&(e=e({})),typeof e=="string"&&(e=z.list.comma(e).join(" ")),e):(e,t={})=>(typeof e=="function"&&(e=e(t)),e)}var Hr=C(()=>{l();nt();xt()});var $p=v((EP,Na)=>{l();var{Rule:Rp,AtRule:AS}=me(),Mp=Me();function Ra(i,e){let t;try{Mp(r=>{t=r}).processSync(i)}catch(r){throw i.includes(":")?e?e.error("Missed semicolon"):r:e?e.error(r.message):r}return t.at(0)}function Bp(i,e){let t=!1;return i.each(r=>{if(r.type==="nesting"){let n=e.clone({});r.value!=="&"?r.replaceWith(Ra(r.value.replace("&",n.toString()))):r.replaceWith(n),t=!0}else"nodes"in r&&r.nodes&&Bp(r,e)&&(t=!0)}),t}function Fp(i,e){let t=[];return i.selectors.forEach(r=>{let n=Ra(r,i);e.selectors.forEach(a=>{if(!a)return;let s=Ra(a,e);Bp(s,n)||(s.prepend(Mp.combinator({value:" "})),s.prepend(n.clone({}))),t.push(s.toString())})}),t}function on(i,e){let t=i.prev();for(e.after(i);t&&t.type==="comment";){let r=t.prev();e.after(t),t=r}return i}function _S(i){return function e(t,r,n,a=n){let s=[];if(r.each(o=>{o.type==="rule"&&n?a&&(o.selectors=Fp(t,o)):o.type==="atrule"&&o.nodes?i[o.name]?e(t,o,a):r[Ba]!==!1&&s.push(o):s.push(o)}),n&&s.length){let o=t.clone({nodes:[]});for(let u of s)o.append(u);r.prepend(o)}}}function Ma(i,e,t){let r=new Rp({selector:i,nodes:[]});return r.append(e),t.after(r),r}function Np(i,e){let t={};for(let r of i)t[r]=!0;if(e)for(let r of e)t[r.replace(/^@/,"")]=!0;return t}function ES(i){i=i.trim();let e=i.match(/^\((.*)\)$/);if(!e)return{type:"basic",selector:i};let t=e[1].match(/^(with(?:out)?):(.+)$/);if(t){let r=t[1]==="with",n=Object.fromEntries(t[2].trim().split(/\s+/).map(s=>[s,!0]));if(r&&n.all)return{type:"noop"};let a=s=>!!n[s];return n.all?a=()=>!0:r&&(a=s=>s==="all"?!1:!n[s]),{type:"withrules",escapes:a}}return{type:"unknown"}}function OS(i){let e=[],t=i.parent;for(;t&&t instanceof AS;)e.push(t),t=t.parent;return e}function TS(i){let e=i[Lp];if(!e)i.after(i.nodes);else{let t=i.nodes,r,n=-1,a,s,o,u=OS(i);if(u.forEach((c,f)=>{if(e(c.name))r=c,n=f,s=o;else{let p=o;o=c.clone({nodes:[]}),p&&o.append(p),a=a||o}}),r?s?(a.append(t),r.after(s)):r.after(t):i.after(t),i.next()&&r){let c;u.slice(0,n+1).forEach((f,p,d)=>{let h=c;c=f.clone({nodes:[]}),h&&c.append(h);let y=[],w=(d[p-1]||i).next();for(;w;)y.push(w),w=w.next();c.append(y)}),c&&(s||t[t.length-1]).after(c)}}i.remove()}var Ba=Symbol("rootRuleMergeSel"),Lp=Symbol("rootRuleEscapes");function PS(i){let{params:e}=i,{type:t,selector:r,escapes:n}=ES(e);if(t==="unknown")throw i.error(`Unknown @${i.name} parameter ${JSON.stringify(e)}`);if(t==="basic"&&r){let a=new Rp({selector:r,nodes:i.nodes});i.removeAll(),i.append(a)}i[Lp]=n,i[Ba]=n?!n("all"):t==="noop"}var Fa=Symbol("hasRootRule");Na.exports=(i={})=>{let e=Np(["media","supports","layer","container"],i.bubble),t=_S(e),r=Np(["document","font-face","keyframes","-webkit-keyframes","-moz-keyframes"],i.unwrap),n=(i.rootRuleName||"at-root").replace(/^@/,""),a=i.preserveEmpty;return{postcssPlugin:"postcss-nested",Once(s){s.walkAtRules(n,o=>{PS(o),s[Fa]=!0})},Rule(s){let o=!1,u=s,c=!1,f=[];s.each(p=>{p.type==="rule"?(f.length&&(u=Ma(s.selector,f,u),f=[]),c=!0,o=!0,p.selectors=Fp(s,p),u=on(p,u)):p.type==="atrule"?(f.length&&(u=Ma(s.selector,f,u),f=[]),p.name===n?(o=!0,t(s,p,!0,p[Ba]),u=on(p,u)):e[p.name]?(c=!0,o=!0,t(s,p,!0),u=on(p,u)):r[p.name]?(c=!0,o=!0,t(s,p,!1),u=on(p,u)):c&&f.push(p)):p.type==="decl"&&c&&f.push(p)}),f.length&&(u=Ma(s.selector,f,u)),o&&a!==!0&&(s.raws.semicolon=!0,s.nodes.length===0&&s.remove())},RootExit(s){s[Fa]&&(s.walkAtRules(n,TS),s[Fa]=!1)}}};Na.exports.postcss=!0});var Up=v((OP,Vp)=>{l();"use strict";var jp=/-(\w|$)/g,zp=(i,e)=>e.toUpperCase(),DS=i=>(i=i.toLowerCase(),i==="float"?"cssFloat":i.startsWith("-ms-")?i.substr(1).replace(jp,zp):i.replace(jp,zp));Vp.exports=DS});var ja=v((TP,Wp)=>{l();var IS=Up(),qS={boxFlex:!0,boxFlexGroup:!0,columnCount:!0,flex:!0,flexGrow:!0,flexPositive:!0,flexShrink:!0,flexNegative:!0,fontWeight:!0,lineClamp:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,tabSize:!0,widows:!0,zIndex:!0,zoom:!0,fillOpacity:!0,strokeDashoffset:!0,strokeOpacity:!0,strokeWidth:!0};function La(i){return typeof i.nodes=="undefined"?!0:$a(i)}function $a(i){let e,t={};return i.each(r=>{if(r.type==="atrule")e="@"+r.name,r.params&&(e+=" "+r.params),typeof t[e]=="undefined"?t[e]=La(r):Array.isArray(t[e])?t[e].push(La(r)):t[e]=[t[e],La(r)];else if(r.type==="rule"){let n=$a(r);if(t[r.selector])for(let a in n)t[r.selector][a]=n[a];else t[r.selector]=n}else if(r.type==="decl"){r.prop[0]==="-"&&r.prop[1]==="-"||r.parent&&r.parent.selector===":export"?e=r.prop:e=IS(r.prop);let n=r.value;!isNaN(r.value)&&qS[e]&&(n=parseFloat(r.value)),r.important&&(n+=" !important"),typeof t[e]=="undefined"?t[e]=n:Array.isArray(t[e])?t[e].push(n):t[e]=[t[e],n]}}),t}Wp.exports=$a});var ln=v((PP,Qp)=>{l();var Yr=me(),Gp=/\s*!important\s*$/i,RS={"box-flex":!0,"box-flex-group":!0,"column-count":!0,flex:!0,"flex-grow":!0,"flex-positive":!0,"flex-shrink":!0,"flex-negative":!0,"font-weight":!0,"line-clamp":!0,"line-height":!0,opacity:!0,order:!0,orphans:!0,"tab-size":!0,widows:!0,"z-index":!0,zoom:!0,"fill-opacity":!0,"stroke-dashoffset":!0,"stroke-opacity":!0,"stroke-width":!0};function MS(i){return i.replace(/([A-Z])/g,"-$1").replace(/^ms-/,"-ms-").toLowerCase()}function Hp(i,e,t){t===!1||t===null||(e.startsWith("--")||(e=MS(e)),typeof t=="number"&&(t===0||RS[e]?t=t.toString():t+="px"),e==="css-float"&&(e="float"),Gp.test(t)?(t=t.replace(Gp,""),i.push(Yr.decl({prop:e,value:t,important:!0}))):i.push(Yr.decl({prop:e,value:t})))}function Yp(i,e,t){let r=Yr.atRule({name:e[1],params:e[3]||""});typeof t=="object"&&(r.nodes=[],za(t,r)),i.push(r)}function za(i,e){let t,r,n;for(t in i)if(r=i[t],!(r===null||typeof r=="undefined"))if(t[0]==="@"){let a=t.match(/@(\S+)(\s+([\W\w]*)\s*)?/);if(Array.isArray(r))for(let s of r)Yp(e,a,s);else Yp(e,a,r)}else if(Array.isArray(r))for(let a of r)Hp(e,t,a);else typeof r=="object"?(n=Yr.rule({selector:t}),za(r,n),e.push(n)):Hp(e,t,r)}Qp.exports=function(i){let e=Yr.root();return za(i,e),e}});var Va=v((DP,Jp)=>{l();var BS=ja();Jp.exports=function(e){return console&&console.warn&&e.warnings().forEach(t=>{let r=t.plugin||"PostCSS";console.warn(r+": "+t.text)}),BS(e.root)}});var Kp=v((IP,Xp)=>{l();var FS=me(),NS=Va(),LS=ln();Xp.exports=function(e){let t=FS(e);return async r=>{let n=await t.process(r,{parser:LS,from:void 0});return NS(n)}}});var ed=v((qP,Zp)=>{l();var $S=me(),jS=Va(),zS=ln();Zp.exports=function(i){let e=$S(i);return t=>{let r=e.process(t,{parser:zS,from:void 0});return jS(r)}}});var rd=v((RP,td)=>{l();var VS=ja(),US=ln(),WS=Kp(),GS=ed();td.exports={objectify:VS,parse:US,async:WS,sync:GS}});var It,id,MP,BP,FP,NP,nd=C(()=>{l();It=K(rd()),id=It.default,MP=It.default.objectify,BP=It.default.parse,FP=It.default.async,NP=It.default.sync});function qt(i){return Array.isArray(i)?i.flatMap(e=>z([(0,sd.default)({bubble:["screen"]})]).process(e,{parser:id}).root.nodes):qt([i])}var sd,Ua=C(()=>{l();nt();sd=K($p());nd()});function Rt(i,e,t=!1){if(i==="")return e;let r=typeof e=="string"?(0,ad.default)().astSync(e):e;return r.walkClasses(n=>{let a=n.value,s=t&&a.startsWith("-");n.value=s?`-${i}${a.slice(1)}`:`${i}${a}`}),typeof e=="string"?r.toString():r}var ad,un=C(()=>{l();ad=K(Me())});function ce(i){let e=od.default.className();return e.value=i,ht(e?.raws?.value??e.value)}var od,Mt=C(()=>{l();od=K(Me());mi()});function Wa(i){return ht(`.${ce(i)}`)}function fn(i,e){return Wa(Qr(i,e))}function Qr(i,e){return e==="DEFAULT"?i:e==="-"||e==="-DEFAULT"?`-${i}`:e.startsWith("-")?`-${i}${e}`:e.startsWith("/")?`${i}${e}`:`${i}-${e}`}var Ga=C(()=>{l();Mt();mi()});function P(i,e=[[i,[i]]],{filterDefault:t=!1,...r}={}){let n=Ge(i);return function({matchUtilities:a,theme:s}){for(let o of e){let u=Array.isArray(o[0])?o:[o];a(u.reduce((c,[f,p])=>Object.assign(c,{[f]:d=>p.reduce((h,y)=>Array.isArray(y)?Object.assign(h,{[y[0]]:y[1]}):Object.assign(h,{[y]:n(d)}),{})}),{}),{...r,values:t?Object.fromEntries(Object.entries(s(i)??{}).filter(([c])=>c!=="DEFAULT")):s(i)})}}}var ld=C(()=>{l();Hr()});function st(i){return i=Array.isArray(i)?i:[i],i.map(e=>{let t=e.values.map(r=>r.raw!==void 0?r.raw:[r.min&&`(min-width: ${r.min})`,r.max&&`(max-width: ${r.max})`].filter(Boolean).join(" and "));return e.not?`not all and ${t}`:t}).join(", ")}var cn=C(()=>{l()});function Ha(i){return i.split(ZS).map(t=>{let r=t.trim(),n={value:r},a=r.split(eC),s=new Set;for(let o of a)!s.has("DIRECTIONS")&&HS.has(o)?(n.direction=o,s.add("DIRECTIONS")):!s.has("PLAY_STATES")&&YS.has(o)?(n.playState=o,s.add("PLAY_STATES")):!s.has("FILL_MODES")&&QS.has(o)?(n.fillMode=o,s.add("FILL_MODES")):!s.has("ITERATION_COUNTS")&&(JS.has(o)||tC.test(o))?(n.iterationCount=o,s.add("ITERATION_COUNTS")):!s.has("TIMING_FUNCTION")&&XS.has(o)||!s.has("TIMING_FUNCTION")&&KS.some(u=>o.startsWith(`${u}(`))?(n.timingFunction=o,s.add("TIMING_FUNCTION")):!s.has("DURATION")&&ud.test(o)?(n.duration=o,s.add("DURATION")):!s.has("DELAY")&&ud.test(o)?(n.delay=o,s.add("DELAY")):s.has("NAME")?(n.unknown||(n.unknown=[]),n.unknown.push(o)):(n.name=o,s.add("NAME"));return n})}var HS,YS,QS,JS,XS,KS,ZS,eC,ud,tC,fd=C(()=>{l();HS=new Set(["normal","reverse","alternate","alternate-reverse"]),YS=new Set(["running","paused"]),QS=new Set(["none","forwards","backwards","both"]),JS=new Set(["infinite"]),XS=new Set(["linear","ease","ease-in","ease-out","ease-in-out","step-start","step-end"]),KS=["cubic-bezier","steps"],ZS=/\,(?![^(]*\))/g,eC=/\ +(?![^(]*\))/g,ud=/^(-?[\d.]+m?s)$/,tC=/^(\d+)$/});var cd,re,pd=C(()=>{l();cd=i=>Object.assign({},...Object.entries(i??{}).flatMap(([e,t])=>typeof t=="object"?Object.entries(cd(t)).map(([r,n])=>({[e+(r==="DEFAULT"?"":`-${r}`)]:n})):[{[`${e}`]:t}])),re=cd});var rC,Qa,iC,nC,sC,aC,oC,lC,uC,fC,cC,pC,dC,hC,mC,gC,yC,wC,Ja,Ya=C(()=>{rC="tailwindcss",Qa="3.3.3",iC="A utility-first CSS framework for rapidly building custom user interfaces.",nC="MIT",sC="lib/index.js",aC="types/index.d.ts",oC="https://github.com/tailwindlabs/tailwindcss.git",lC="https://github.com/tailwindlabs/tailwindcss/issues",uC="https://tailwindcss.com",fC={tailwind:"lib/cli.js",tailwindcss:"lib/cli.js"},cC={engine:"stable"},pC={prebuild:"npm run generate && rimraf lib",build:`swc src --out-dir lib --copy-files --config jsc.transform.optimizer.globals.vars.__OXIDE__='"false"'`,postbuild:"esbuild lib/cli-peer-dependencies.js --bundle --platform=node --outfile=peers/index.js --define:process.env.CSS_TRANSFORMER_WASM=false","rebuild-fixtures":"npm run build && node -r @swc/register scripts/rebuildFixtures.js",style:"eslint .",pretest:"npm run generate",test:"jest","test:integrations":"npm run test --prefix ./integrations","install:integrations":"node scripts/install-integrations.js","generate:plugin-list":"node -r @swc/register scripts/create-plugin-list.js","generate:types":"node -r @swc/register scripts/generate-types.js",generate:"npm run generate:plugin-list && npm run generate:types","release-channel":"node ./scripts/release-channel.js","release-notes":"node ./scripts/release-notes.js",prepublishOnly:"npm install --force && npm run build"},dC=["src/*","cli/*","lib/*","peers/*","scripts/*.js","stubs/*","nesting/*","types/**/*","*.d.ts","*.css","*.js"],hC={"@swc/cli":"^0.1.62","@swc/core":"^1.3.55","@swc/jest":"^0.2.26","@swc/register":"^0.1.10",autoprefixer:"^10.4.14",browserslist:"^4.21.5",concurrently:"^8.0.1",cssnano:"^6.0.0",esbuild:"^0.17.18",eslint:"^8.39.0","eslint-config-prettier":"^8.8.0","eslint-plugin-prettier":"^4.2.1",jest:"^29.5.0","jest-diff":"^29.5.0",lightningcss:"1.18.0",prettier:"^2.8.8",rimraf:"^5.0.0","source-map-js":"^1.0.2",turbo:"^1.9.3"},mC={"@alloc/quick-lru":"^5.2.0",arg:"^5.0.2",chokidar:"^3.5.3",didyoumean:"^1.2.2",dlv:"^1.1.3","fast-glob":"^3.2.12","glob-parent":"^6.0.2","is-glob":"^4.0.3",jiti:"^1.18.2",lilconfig:"^2.1.0",micromatch:"^4.0.5","normalize-path":"^3.0.0","object-hash":"^3.0.0",picocolors:"^1.0.0",postcss:"^8.4.23","postcss-import":"^15.1.0","postcss-js":"^4.0.1","postcss-load-config":"^4.0.1","postcss-nested":"^6.0.1","postcss-selector-parser":"^6.0.11",resolve:"^1.22.2",sucrase:"^3.32.0"},gC=["> 1%","not edge <= 18","not ie 11","not op_mini all"],yC={testTimeout:3e4,setupFilesAfterEnv:["/jest/customMatchers.js"],testPathIgnorePatterns:["/node_modules/","/integrations/","/standalone-cli/","\\.test\\.skip\\.js$"],transformIgnorePatterns:["node_modules/(?!lightningcss)"],transform:{"\\.js$":"@swc/jest","\\.ts$":"@swc/jest"}},wC={node:">=14.0.0"},Ja={name:rC,version:Qa,description:iC,license:nC,main:sC,types:aC,repository:oC,bugs:lC,homepage:uC,bin:fC,tailwindcss:cC,scripts:pC,files:dC,devDependencies:hC,dependencies:mC,browserslist:gC,jest:yC,engines:wC}});function at(i,e=!0){return Array.isArray(i)?i.map(t=>{if(e&&Array.isArray(t))throw new Error("The tuple syntax is not supported for `screens`.");if(typeof t=="string")return{name:t.toString(),not:!1,values:[{min:t,max:void 0}]};let[r,n]=t;return r=r.toString(),typeof n=="string"?{name:r,not:!1,values:[{min:n,max:void 0}]}:Array.isArray(n)?{name:r,not:!1,values:n.map(a=>hd(a))}:{name:r,not:!1,values:[hd(n)]}}):at(Object.entries(i??{}),!1)}function pn(i){return i.values.length!==1?{result:!1,reason:"multiple-values"}:i.values[0].raw!==void 0?{result:!1,reason:"raw-values"}:i.values[0].min!==void 0&&i.values[0].max!==void 0?{result:!1,reason:"min-and-max"}:{result:!0,reason:null}}function dd(i,e,t){let r=dn(e,i),n=dn(t,i),a=pn(r),s=pn(n);if(a.reason==="multiple-values"||s.reason==="multiple-values")throw new Error("Attempted to sort a screen with multiple values. This should never happen. Please open a bug report.");if(a.reason==="raw-values"||s.reason==="raw-values")throw new Error("Attempted to sort a screen with raw values. This should never happen. Please open a bug report.");if(a.reason==="min-and-max"||s.reason==="min-and-max")throw new Error("Attempted to sort a screen with both min and max values. This should never happen. Please open a bug report.");let{min:o,max:u}=r.values[0],{min:c,max:f}=n.values[0];e.not&&([o,u]=[u,o]),t.not&&([c,f]=[f,c]),o=o===void 0?o:parseFloat(o),u=u===void 0?u:parseFloat(u),c=c===void 0?c:parseFloat(c),f=f===void 0?f:parseFloat(f);let[p,d]=i==="min"?[o,c]:[f,u];return p-d}function dn(i,e){return typeof i=="object"?i:{name:"arbitrary-screen",values:[{[e]:i}]}}function hd({"min-width":i,min:e=i,max:t,raw:r}={}){return{min:e,max:t,raw:r}}var hn=C(()=>{l()});function mn(i,e){i.walkDecls(t=>{if(e.includes(t.prop)){t.remove();return}for(let r of e)t.value.includes(`/ var(${r})`)&&(t.value=t.value.replace(`/ var(${r})`,""))})}var md=C(()=>{l()});var pe,Te,Be,Fe,gd,yd=C(()=>{l();ze();mt();nt();ld();cn();Mt();fd();pd();ar();ds();xt();Hr();Ya();Ee();hn();as();md();De();fr();Xr();pe={pseudoElementVariants:({addVariant:i})=>{i("first-letter","&::first-letter"),i("first-line","&::first-line"),i("marker",[({container:e})=>(mn(e,["--tw-text-opacity"]),"& *::marker"),({container:e})=>(mn(e,["--tw-text-opacity"]),"&::marker")]),i("selection",["& *::selection","&::selection"]),i("file","&::file-selector-button"),i("placeholder","&::placeholder"),i("backdrop","&::backdrop"),i("before",({container:e})=>(e.walkRules(t=>{let r=!1;t.walkDecls("content",()=>{r=!0}),r||t.prepend(z.decl({prop:"content",value:"var(--tw-content)"}))}),"&::before")),i("after",({container:e})=>(e.walkRules(t=>{let r=!1;t.walkDecls("content",()=>{r=!0}),r||t.prepend(z.decl({prop:"content",value:"var(--tw-content)"}))}),"&::after"))},pseudoClassVariants:({addVariant:i,matchVariant:e,config:t,prefix:r})=>{let n=[["first","&:first-child"],["last","&:last-child"],["only","&:only-child"],["odd","&:nth-child(odd)"],["even","&:nth-child(even)"],"first-of-type","last-of-type","only-of-type",["visited",({container:s})=>(mn(s,["--tw-text-opacity","--tw-border-opacity","--tw-bg-opacity"]),"&:visited")],"target",["open","&[open]"],"default","checked","indeterminate","placeholder-shown","autofill","optional","required","valid","invalid","in-range","out-of-range","read-only","empty","focus-within",["hover",J(t(),"hoverOnlyWhenSupported")?"@media (hover: hover) and (pointer: fine) { &:hover }":"&:hover"],"focus","focus-visible","active","enabled","disabled"].map(s=>Array.isArray(s)?s:[s,`&:${s}`]);for(let[s,o]of n)i(s,u=>typeof o=="function"?o(u):o);let a={group:(s,{modifier:o})=>o?[`:merge(${r(".group")}\\/${ce(o)})`," &"]:[`:merge(${r(".group")})`," &"],peer:(s,{modifier:o})=>o?[`:merge(${r(".peer")}\\/${ce(o)})`," ~ &"]:[`:merge(${r(".peer")})`," ~ &"]};for(let[s,o]of Object.entries(a))e(s,(u="",c)=>{let f=U(typeof u=="function"?u(c):u);f.includes("&")||(f="&"+f);let[p,d]=o("",c),h=null,y=null,x=0;for(let w=0;w{i("ltr",':is([dir="ltr"] &)'),i("rtl",':is([dir="rtl"] &)')},reducedMotionVariants:({addVariant:i})=>{i("motion-safe","@media (prefers-reduced-motion: no-preference)"),i("motion-reduce","@media (prefers-reduced-motion: reduce)")},darkVariants:({config:i,addVariant:e})=>{let[t,r=".dark"]=[].concat(i("darkMode","media"));t===!1&&(t="media",F.warn("darkmode-false",["The `darkMode` option in your Tailwind CSS configuration is set to `false`, which now behaves the same as `media`.","Change `darkMode` to `media` or remove it entirely.","https://tailwindcss.com/docs/upgrade-guide#remove-dark-mode-configuration"])),t==="class"?e("dark",`:is(${r} &)`):t==="media"&&e("dark","@media (prefers-color-scheme: dark)")},printVariant:({addVariant:i})=>{i("print","@media print")},screenVariants:({theme:i,addVariant:e,matchVariant:t})=>{let r=i("screens")??{},n=Object.values(r).every(b=>typeof b=="string"),a=at(i("screens")),s=new Set([]);function o(b){return b.match(/(\D+)$/)?.[1]??"(none)"}function u(b){b!==void 0&&s.add(o(b))}function c(b){return u(b),s.size===1}for(let b of a)for(let k of b.values)u(k.min),u(k.max);let f=s.size<=1;function p(b){return Object.fromEntries(a.filter(k=>pn(k).result).map(k=>{let{min:S,max:_}=k.values[0];if(b==="min"&&S!==void 0)return k;if(b==="min"&&_!==void 0)return{...k,not:!k.not};if(b==="max"&&_!==void 0)return k;if(b==="max"&&S!==void 0)return{...k,not:!k.not}}).map(k=>[k.name,k]))}function d(b){return(k,S)=>dd(b,k.value,S.value)}let h=d("max"),y=d("min");function x(b){return k=>{if(n)if(f){if(typeof k=="string"&&!c(k))return F.warn("minmax-have-mixed-units",["The `min-*` and `max-*` variants are not supported with a `screens` configuration containing mixed units."]),[]}else return F.warn("mixed-screen-units",["The `min-*` and `max-*` variants are not supported with a `screens` configuration containing mixed units."]),[];else return F.warn("complex-screen-config",["The `min-*` and `max-*` variants are not supported with a `screens` configuration containing objects."]),[];return[`@media ${st(dn(k,b))}`]}}t("max",x("max"),{sort:h,values:n?p("max"):{}});let w="min-screens";for(let b of a)e(b.name,`@media ${st(b)}`,{id:w,sort:n&&f?y:void 0,value:b});t("min",x("min"),{id:w,sort:y})},supportsVariants:({matchVariant:i,theme:e})=>{i("supports",(t="")=>{let r=U(t),n=/^\w*\s*\(/.test(r);return r=n?r.replace(/\b(and|or|not)\b/g," $1 "):r,n?`@supports ${r}`:(r.includes(":")||(r=`${r}: var(--tw)`),r.startsWith("(")&&r.endsWith(")")||(r=`(${r})`),`@supports ${r}`)},{values:e("supports")??{}})},ariaVariants:({matchVariant:i,theme:e})=>{i("aria",t=>`&[aria-${U(t)}]`,{values:e("aria")??{}}),i("group-aria",(t,{modifier:r})=>r?`:merge(.group\\/${r})[aria-${U(t)}] &`:`:merge(.group)[aria-${U(t)}] &`,{values:e("aria")??{}}),i("peer-aria",(t,{modifier:r})=>r?`:merge(.peer\\/${r})[aria-${U(t)}] ~ &`:`:merge(.peer)[aria-${U(t)}] ~ &`,{values:e("aria")??{}})},dataVariants:({matchVariant:i,theme:e})=>{i("data",t=>`&[data-${U(t)}]`,{values:e("data")??{}}),i("group-data",(t,{modifier:r})=>r?`:merge(.group\\/${r})[data-${U(t)}] &`:`:merge(.group)[data-${U(t)}] &`,{values:e("data")??{}}),i("peer-data",(t,{modifier:r})=>r?`:merge(.peer\\/${r})[data-${U(t)}] ~ &`:`:merge(.peer)[data-${U(t)}] ~ &`,{values:e("data")??{}})},orientationVariants:({addVariant:i})=>{i("portrait","@media (orientation: portrait)"),i("landscape","@media (orientation: landscape)")},prefersContrastVariants:({addVariant:i})=>{i("contrast-more","@media (prefers-contrast: more)"),i("contrast-less","@media (prefers-contrast: less)")}},Te=["translate(var(--tw-translate-x), var(--tw-translate-y))","rotate(var(--tw-rotate))","skewX(var(--tw-skew-x))","skewY(var(--tw-skew-y))","scaleX(var(--tw-scale-x))","scaleY(var(--tw-scale-y))"].join(" "),Be=["var(--tw-blur)","var(--tw-brightness)","var(--tw-contrast)","var(--tw-grayscale)","var(--tw-hue-rotate)","var(--tw-invert)","var(--tw-saturate)","var(--tw-sepia)","var(--tw-drop-shadow)"].join(" "),Fe=["var(--tw-backdrop-blur)","var(--tw-backdrop-brightness)","var(--tw-backdrop-contrast)","var(--tw-backdrop-grayscale)","var(--tw-backdrop-hue-rotate)","var(--tw-backdrop-invert)","var(--tw-backdrop-opacity)","var(--tw-backdrop-saturate)","var(--tw-backdrop-sepia)"].join(" "),gd={preflight:({addBase:i})=>{let e=z.parse(`*,::after,::before{box-sizing:border-box;border-width:0;border-style:solid;border-color:theme('borderColor.DEFAULT', currentColor)}::after,::before{--tw-content:''}html{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;tab-size:4;font-family:theme('fontFamily.sans', ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji");font-feature-settings:theme('fontFamily.sans[1].fontFeatureSettings', normal);font-variation-settings:theme('fontFamily.sans[1].fontVariationSettings', normal)}body{margin:0;line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,pre,samp{font-family:theme('fontFamily.mono', ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace);font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-family:inherit;font-feature-settings:inherit;font-variation-settings:inherit;font-size:100%;font-weight:inherit;line-height:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dd,dl,figure,h1,h2,h3,h4,h5,h6,hr,p,pre{margin:0}fieldset{margin:0;padding:0}legend{padding:0}menu,ol,ul{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::placeholder,textarea::placeholder{opacity:1;color:theme('colors.gray.4', #9ca3af)}[role=button],button{cursor:pointer}:disabled{cursor:default}audio,canvas,embed,iframe,img,object,svg,video{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}[hidden]{display:none}`);i([z.comment({text:`! tailwindcss v${Qa} | MIT License | https://tailwindcss.com`}),...e.nodes])},container:(()=>{function i(t=[]){return t.flatMap(r=>r.values.map(n=>n.min)).filter(r=>r!==void 0)}function e(t,r,n){if(typeof n=="undefined")return[];if(!(typeof n=="object"&&n!==null))return[{screen:"DEFAULT",minWidth:0,padding:n}];let a=[];n.DEFAULT&&a.push({screen:"DEFAULT",minWidth:0,padding:n.DEFAULT});for(let s of t)for(let o of r)for(let{min:u}of o.values)u===s&&a.push({minWidth:s,padding:n[o.name]});return a}return function({addComponents:t,theme:r}){let n=at(r("container.screens",r("screens"))),a=i(n),s=e(a,n,r("container.padding")),o=c=>{let f=s.find(p=>p.minWidth===c);return f?{paddingRight:f.padding,paddingLeft:f.padding}:{}},u=Array.from(new Set(a.slice().sort((c,f)=>parseInt(c)-parseInt(f)))).map(c=>({[`@media (min-width: ${c})`]:{".container":{"max-width":c,...o(c)}}}));t([{".container":Object.assign({width:"100%"},r("container.center",!1)?{marginRight:"auto",marginLeft:"auto"}:{},o(0))},...u])}})(),accessibility:({addUtilities:i})=>{i({".sr-only":{position:"absolute",width:"1px",height:"1px",padding:"0",margin:"-1px",overflow:"hidden",clip:"rect(0, 0, 0, 0)",whiteSpace:"nowrap",borderWidth:"0"},".not-sr-only":{position:"static",width:"auto",height:"auto",padding:"0",margin:"0",overflow:"visible",clip:"auto",whiteSpace:"normal"}})},pointerEvents:({addUtilities:i})=>{i({".pointer-events-none":{"pointer-events":"none"},".pointer-events-auto":{"pointer-events":"auto"}})},visibility:({addUtilities:i})=>{i({".visible":{visibility:"visible"},".invisible":{visibility:"hidden"},".collapse":{visibility:"collapse"}})},position:({addUtilities:i})=>{i({".static":{position:"static"},".fixed":{position:"fixed"},".absolute":{position:"absolute"},".relative":{position:"relative"},".sticky":{position:"sticky"}})},inset:P("inset",[["inset",["inset"]],[["inset-x",["left","right"]],["inset-y",["top","bottom"]]],[["start",["inset-inline-start"]],["end",["inset-inline-end"]],["top",["top"]],["right",["right"]],["bottom",["bottom"]],["left",["left"]]]],{supportsNegativeValues:!0}),isolation:({addUtilities:i})=>{i({".isolate":{isolation:"isolate"},".isolation-auto":{isolation:"auto"}})},zIndex:P("zIndex",[["z",["zIndex"]]],{supportsNegativeValues:!0}),order:P("order",void 0,{supportsNegativeValues:!0}),gridColumn:P("gridColumn",[["col",["gridColumn"]]]),gridColumnStart:P("gridColumnStart",[["col-start",["gridColumnStart"]]]),gridColumnEnd:P("gridColumnEnd",[["col-end",["gridColumnEnd"]]]),gridRow:P("gridRow",[["row",["gridRow"]]]),gridRowStart:P("gridRowStart",[["row-start",["gridRowStart"]]]),gridRowEnd:P("gridRowEnd",[["row-end",["gridRowEnd"]]]),float:({addUtilities:i})=>{i({".float-right":{float:"right"},".float-left":{float:"left"},".float-none":{float:"none"}})},clear:({addUtilities:i})=>{i({".clear-left":{clear:"left"},".clear-right":{clear:"right"},".clear-both":{clear:"both"},".clear-none":{clear:"none"}})},margin:P("margin",[["m",["margin"]],[["mx",["margin-left","margin-right"]],["my",["margin-top","margin-bottom"]]],[["ms",["margin-inline-start"]],["me",["margin-inline-end"]],["mt",["margin-top"]],["mr",["margin-right"]],["mb",["margin-bottom"]],["ml",["margin-left"]]]],{supportsNegativeValues:!0}),boxSizing:({addUtilities:i})=>{i({".box-border":{"box-sizing":"border-box"},".box-content":{"box-sizing":"content-box"}})},lineClamp:({matchUtilities:i,addUtilities:e,theme:t})=>{i({"line-clamp":r=>({overflow:"hidden",display:"-webkit-box","-webkit-box-orient":"vertical","-webkit-line-clamp":`${r}`})},{values:t("lineClamp")}),e({".line-clamp-none":{overflow:"visible",display:"block","-webkit-box-orient":"horizontal","-webkit-line-clamp":"none"}})},display:({addUtilities:i})=>{i({".block":{display:"block"},".inline-block":{display:"inline-block"},".inline":{display:"inline"},".flex":{display:"flex"},".inline-flex":{display:"inline-flex"},".table":{display:"table"},".inline-table":{display:"inline-table"},".table-caption":{display:"table-caption"},".table-cell":{display:"table-cell"},".table-column":{display:"table-column"},".table-column-group":{display:"table-column-group"},".table-footer-group":{display:"table-footer-group"},".table-header-group":{display:"table-header-group"},".table-row-group":{display:"table-row-group"},".table-row":{display:"table-row"},".flow-root":{display:"flow-root"},".grid":{display:"grid"},".inline-grid":{display:"inline-grid"},".contents":{display:"contents"},".list-item":{display:"list-item"},".hidden":{display:"none"}})},aspectRatio:P("aspectRatio",[["aspect",["aspect-ratio"]]]),height:P("height",[["h",["height"]]]),maxHeight:P("maxHeight",[["max-h",["maxHeight"]]]),minHeight:P("minHeight",[["min-h",["minHeight"]]]),width:P("width",[["w",["width"]]]),minWidth:P("minWidth",[["min-w",["minWidth"]]]),maxWidth:P("maxWidth",[["max-w",["maxWidth"]]]),flex:P("flex"),flexShrink:P("flexShrink",[["flex-shrink",["flex-shrink"]],["shrink",["flex-shrink"]]]),flexGrow:P("flexGrow",[["flex-grow",["flex-grow"]],["grow",["flex-grow"]]]),flexBasis:P("flexBasis",[["basis",["flex-basis"]]]),tableLayout:({addUtilities:i})=>{i({".table-auto":{"table-layout":"auto"},".table-fixed":{"table-layout":"fixed"}})},captionSide:({addUtilities:i})=>{i({".caption-top":{"caption-side":"top"},".caption-bottom":{"caption-side":"bottom"}})},borderCollapse:({addUtilities:i})=>{i({".border-collapse":{"border-collapse":"collapse"},".border-separate":{"border-collapse":"separate"}})},borderSpacing:({addDefaults:i,matchUtilities:e,theme:t})=>{i("border-spacing",{"--tw-border-spacing-x":0,"--tw-border-spacing-y":0}),e({"border-spacing":r=>({"--tw-border-spacing-x":r,"--tw-border-spacing-y":r,"@defaults border-spacing":{},"border-spacing":"var(--tw-border-spacing-x) var(--tw-border-spacing-y)"}),"border-spacing-x":r=>({"--tw-border-spacing-x":r,"@defaults border-spacing":{},"border-spacing":"var(--tw-border-spacing-x) var(--tw-border-spacing-y)"}),"border-spacing-y":r=>({"--tw-border-spacing-y":r,"@defaults border-spacing":{},"border-spacing":"var(--tw-border-spacing-x) var(--tw-border-spacing-y)"})},{values:t("borderSpacing")})},transformOrigin:P("transformOrigin",[["origin",["transformOrigin"]]]),translate:P("translate",[[["translate-x",[["@defaults transform",{}],"--tw-translate-x",["transform",Te]]],["translate-y",[["@defaults transform",{}],"--tw-translate-y",["transform",Te]]]]],{supportsNegativeValues:!0}),rotate:P("rotate",[["rotate",[["@defaults transform",{}],"--tw-rotate",["transform",Te]]]],{supportsNegativeValues:!0}),skew:P("skew",[[["skew-x",[["@defaults transform",{}],"--tw-skew-x",["transform",Te]]],["skew-y",[["@defaults transform",{}],"--tw-skew-y",["transform",Te]]]]],{supportsNegativeValues:!0}),scale:P("scale",[["scale",[["@defaults transform",{}],"--tw-scale-x","--tw-scale-y",["transform",Te]]],[["scale-x",[["@defaults transform",{}],"--tw-scale-x",["transform",Te]]],["scale-y",[["@defaults transform",{}],"--tw-scale-y",["transform",Te]]]]],{supportsNegativeValues:!0}),transform:({addDefaults:i,addUtilities:e})=>{i("transform",{"--tw-translate-x":"0","--tw-translate-y":"0","--tw-rotate":"0","--tw-skew-x":"0","--tw-skew-y":"0","--tw-scale-x":"1","--tw-scale-y":"1"}),e({".transform":{"@defaults transform":{},transform:Te},".transform-cpu":{transform:Te},".transform-gpu":{transform:Te.replace("translate(var(--tw-translate-x), var(--tw-translate-y))","translate3d(var(--tw-translate-x), var(--tw-translate-y), 0)")},".transform-none":{transform:"none"}})},animation:({matchUtilities:i,theme:e,config:t})=>{let r=a=>ce(t("prefix")+a),n=Object.fromEntries(Object.entries(e("keyframes")??{}).map(([a,s])=>[a,{[`@keyframes ${r(a)}`]:s}]));i({animate:a=>{let s=Ha(a);return[...s.flatMap(o=>n[o.name]),{animation:s.map(({name:o,value:u})=>o===void 0||n[o]===void 0?u:u.replace(o,r(o))).join(", ")}]}},{values:e("animation")})},cursor:P("cursor"),touchAction:({addDefaults:i,addUtilities:e})=>{i("touch-action",{"--tw-pan-x":" ","--tw-pan-y":" ","--tw-pinch-zoom":" "});let t="var(--tw-pan-x) var(--tw-pan-y) var(--tw-pinch-zoom)";e({".touch-auto":{"touch-action":"auto"},".touch-none":{"touch-action":"none"},".touch-pan-x":{"@defaults touch-action":{},"--tw-pan-x":"pan-x","touch-action":t},".touch-pan-left":{"@defaults touch-action":{},"--tw-pan-x":"pan-left","touch-action":t},".touch-pan-right":{"@defaults touch-action":{},"--tw-pan-x":"pan-right","touch-action":t},".touch-pan-y":{"@defaults touch-action":{},"--tw-pan-y":"pan-y","touch-action":t},".touch-pan-up":{"@defaults touch-action":{},"--tw-pan-y":"pan-up","touch-action":t},".touch-pan-down":{"@defaults touch-action":{},"--tw-pan-y":"pan-down","touch-action":t},".touch-pinch-zoom":{"@defaults touch-action":{},"--tw-pinch-zoom":"pinch-zoom","touch-action":t},".touch-manipulation":{"touch-action":"manipulation"}})},userSelect:({addUtilities:i})=>{i({".select-none":{"user-select":"none"},".select-text":{"user-select":"text"},".select-all":{"user-select":"all"},".select-auto":{"user-select":"auto"}})},resize:({addUtilities:i})=>{i({".resize-none":{resize:"none"},".resize-y":{resize:"vertical"},".resize-x":{resize:"horizontal"},".resize":{resize:"both"}})},scrollSnapType:({addDefaults:i,addUtilities:e})=>{i("scroll-snap-type",{"--tw-scroll-snap-strictness":"proximity"}),e({".snap-none":{"scroll-snap-type":"none"},".snap-x":{"@defaults scroll-snap-type":{},"scroll-snap-type":"x var(--tw-scroll-snap-strictness)"},".snap-y":{"@defaults scroll-snap-type":{},"scroll-snap-type":"y var(--tw-scroll-snap-strictness)"},".snap-both":{"@defaults scroll-snap-type":{},"scroll-snap-type":"both var(--tw-scroll-snap-strictness)"},".snap-mandatory":{"--tw-scroll-snap-strictness":"mandatory"},".snap-proximity":{"--tw-scroll-snap-strictness":"proximity"}})},scrollSnapAlign:({addUtilities:i})=>{i({".snap-start":{"scroll-snap-align":"start"},".snap-end":{"scroll-snap-align":"end"},".snap-center":{"scroll-snap-align":"center"},".snap-align-none":{"scroll-snap-align":"none"}})},scrollSnapStop:({addUtilities:i})=>{i({".snap-normal":{"scroll-snap-stop":"normal"},".snap-always":{"scroll-snap-stop":"always"}})},scrollMargin:P("scrollMargin",[["scroll-m",["scroll-margin"]],[["scroll-mx",["scroll-margin-left","scroll-margin-right"]],["scroll-my",["scroll-margin-top","scroll-margin-bottom"]]],[["scroll-ms",["scroll-margin-inline-start"]],["scroll-me",["scroll-margin-inline-end"]],["scroll-mt",["scroll-margin-top"]],["scroll-mr",["scroll-margin-right"]],["scroll-mb",["scroll-margin-bottom"]],["scroll-ml",["scroll-margin-left"]]]],{supportsNegativeValues:!0}),scrollPadding:P("scrollPadding",[["scroll-p",["scroll-padding"]],[["scroll-px",["scroll-padding-left","scroll-padding-right"]],["scroll-py",["scroll-padding-top","scroll-padding-bottom"]]],[["scroll-ps",["scroll-padding-inline-start"]],["scroll-pe",["scroll-padding-inline-end"]],["scroll-pt",["scroll-padding-top"]],["scroll-pr",["scroll-padding-right"]],["scroll-pb",["scroll-padding-bottom"]],["scroll-pl",["scroll-padding-left"]]]]),listStylePosition:({addUtilities:i})=>{i({".list-inside":{"list-style-position":"inside"},".list-outside":{"list-style-position":"outside"}})},listStyleType:P("listStyleType",[["list",["listStyleType"]]]),listStyleImage:P("listStyleImage",[["list-image",["listStyleImage"]]]),appearance:({addUtilities:i})=>{i({".appearance-none":{appearance:"none"}})},columns:P("columns",[["columns",["columns"]]]),breakBefore:({addUtilities:i})=>{i({".break-before-auto":{"break-before":"auto"},".break-before-avoid":{"break-before":"avoid"},".break-before-all":{"break-before":"all"},".break-before-avoid-page":{"break-before":"avoid-page"},".break-before-page":{"break-before":"page"},".break-before-left":{"break-before":"left"},".break-before-right":{"break-before":"right"},".break-before-column":{"break-before":"column"}})},breakInside:({addUtilities:i})=>{i({".break-inside-auto":{"break-inside":"auto"},".break-inside-avoid":{"break-inside":"avoid"},".break-inside-avoid-page":{"break-inside":"avoid-page"},".break-inside-avoid-column":{"break-inside":"avoid-column"}})},breakAfter:({addUtilities:i})=>{i({".break-after-auto":{"break-after":"auto"},".break-after-avoid":{"break-after":"avoid"},".break-after-all":{"break-after":"all"},".break-after-avoid-page":{"break-after":"avoid-page"},".break-after-page":{"break-after":"page"},".break-after-left":{"break-after":"left"},".break-after-right":{"break-after":"right"},".break-after-column":{"break-after":"column"}})},gridAutoColumns:P("gridAutoColumns",[["auto-cols",["gridAutoColumns"]]]),gridAutoFlow:({addUtilities:i})=>{i({".grid-flow-row":{gridAutoFlow:"row"},".grid-flow-col":{gridAutoFlow:"column"},".grid-flow-dense":{gridAutoFlow:"dense"},".grid-flow-row-dense":{gridAutoFlow:"row dense"},".grid-flow-col-dense":{gridAutoFlow:"column dense"}})},gridAutoRows:P("gridAutoRows",[["auto-rows",["gridAutoRows"]]]),gridTemplateColumns:P("gridTemplateColumns",[["grid-cols",["gridTemplateColumns"]]]),gridTemplateRows:P("gridTemplateRows",[["grid-rows",["gridTemplateRows"]]]),flexDirection:({addUtilities:i})=>{i({".flex-row":{"flex-direction":"row"},".flex-row-reverse":{"flex-direction":"row-reverse"},".flex-col":{"flex-direction":"column"},".flex-col-reverse":{"flex-direction":"column-reverse"}})},flexWrap:({addUtilities:i})=>{i({".flex-wrap":{"flex-wrap":"wrap"},".flex-wrap-reverse":{"flex-wrap":"wrap-reverse"},".flex-nowrap":{"flex-wrap":"nowrap"}})},placeContent:({addUtilities:i})=>{i({".place-content-center":{"place-content":"center"},".place-content-start":{"place-content":"start"},".place-content-end":{"place-content":"end"},".place-content-between":{"place-content":"space-between"},".place-content-around":{"place-content":"space-around"},".place-content-evenly":{"place-content":"space-evenly"},".place-content-baseline":{"place-content":"baseline"},".place-content-stretch":{"place-content":"stretch"}})},placeItems:({addUtilities:i})=>{i({".place-items-start":{"place-items":"start"},".place-items-end":{"place-items":"end"},".place-items-center":{"place-items":"center"},".place-items-baseline":{"place-items":"baseline"},".place-items-stretch":{"place-items":"stretch"}})},alignContent:({addUtilities:i})=>{i({".content-normal":{"align-content":"normal"},".content-center":{"align-content":"center"},".content-start":{"align-content":"flex-start"},".content-end":{"align-content":"flex-end"},".content-between":{"align-content":"space-between"},".content-around":{"align-content":"space-around"},".content-evenly":{"align-content":"space-evenly"},".content-baseline":{"align-content":"baseline"},".content-stretch":{"align-content":"stretch"}})},alignItems:({addUtilities:i})=>{i({".items-start":{"align-items":"flex-start"},".items-end":{"align-items":"flex-end"},".items-center":{"align-items":"center"},".items-baseline":{"align-items":"baseline"},".items-stretch":{"align-items":"stretch"}})},justifyContent:({addUtilities:i})=>{i({".justify-normal":{"justify-content":"normal"},".justify-start":{"justify-content":"flex-start"},".justify-end":{"justify-content":"flex-end"},".justify-center":{"justify-content":"center"},".justify-between":{"justify-content":"space-between"},".justify-around":{"justify-content":"space-around"},".justify-evenly":{"justify-content":"space-evenly"},".justify-stretch":{"justify-content":"stretch"}})},justifyItems:({addUtilities:i})=>{i({".justify-items-start":{"justify-items":"start"},".justify-items-end":{"justify-items":"end"},".justify-items-center":{"justify-items":"center"},".justify-items-stretch":{"justify-items":"stretch"}})},gap:P("gap",[["gap",["gap"]],[["gap-x",["columnGap"]],["gap-y",["rowGap"]]]]),space:({matchUtilities:i,addUtilities:e,theme:t})=>{i({"space-x":r=>(r=r==="0"?"0px":r,{"& > :not([hidden]) ~ :not([hidden])":{"--tw-space-x-reverse":"0","margin-right":`calc(${r} * var(--tw-space-x-reverse))`,"margin-left":`calc(${r} * calc(1 - var(--tw-space-x-reverse)))`}}),"space-y":r=>(r=r==="0"?"0px":r,{"& > :not([hidden]) ~ :not([hidden])":{"--tw-space-y-reverse":"0","margin-top":`calc(${r} * calc(1 - var(--tw-space-y-reverse)))`,"margin-bottom":`calc(${r} * var(--tw-space-y-reverse))`}})},{values:t("space"),supportsNegativeValues:!0}),e({".space-y-reverse > :not([hidden]) ~ :not([hidden])":{"--tw-space-y-reverse":"1"},".space-x-reverse > :not([hidden]) ~ :not([hidden])":{"--tw-space-x-reverse":"1"}})},divideWidth:({matchUtilities:i,addUtilities:e,theme:t})=>{i({"divide-x":r=>(r=r==="0"?"0px":r,{"& > :not([hidden]) ~ :not([hidden])":{"@defaults border-width":{},"--tw-divide-x-reverse":"0","border-right-width":`calc(${r} * var(--tw-divide-x-reverse))`,"border-left-width":`calc(${r} * calc(1 - var(--tw-divide-x-reverse)))`}}),"divide-y":r=>(r=r==="0"?"0px":r,{"& > :not([hidden]) ~ :not([hidden])":{"@defaults border-width":{},"--tw-divide-y-reverse":"0","border-top-width":`calc(${r} * calc(1 - var(--tw-divide-y-reverse)))`,"border-bottom-width":`calc(${r} * var(--tw-divide-y-reverse))`}})},{values:t("divideWidth"),type:["line-width","length","any"]}),e({".divide-y-reverse > :not([hidden]) ~ :not([hidden])":{"@defaults border-width":{},"--tw-divide-y-reverse":"1"},".divide-x-reverse > :not([hidden]) ~ :not([hidden])":{"@defaults border-width":{},"--tw-divide-x-reverse":"1"}})},divideStyle:({addUtilities:i})=>{i({".divide-solid > :not([hidden]) ~ :not([hidden])":{"border-style":"solid"},".divide-dashed > :not([hidden]) ~ :not([hidden])":{"border-style":"dashed"},".divide-dotted > :not([hidden]) ~ :not([hidden])":{"border-style":"dotted"},".divide-double > :not([hidden]) ~ :not([hidden])":{"border-style":"double"},".divide-none > :not([hidden]) ~ :not([hidden])":{"border-style":"none"}})},divideColor:({matchUtilities:i,theme:e,corePlugins:t})=>{i({divide:r=>t("divideOpacity")?{["& > :not([hidden]) ~ :not([hidden])"]:se({color:r,property:"border-color",variable:"--tw-divide-opacity"})}:{["& > :not([hidden]) ~ :not([hidden])"]:{"border-color":N(r)}}},{values:(({DEFAULT:r,...n})=>n)(re(e("divideColor"))),type:["color","any"]})},divideOpacity:({matchUtilities:i,theme:e})=>{i({"divide-opacity":t=>({["& > :not([hidden]) ~ :not([hidden])"]:{"--tw-divide-opacity":t}})},{values:e("divideOpacity")})},placeSelf:({addUtilities:i})=>{i({".place-self-auto":{"place-self":"auto"},".place-self-start":{"place-self":"start"},".place-self-end":{"place-self":"end"},".place-self-center":{"place-self":"center"},".place-self-stretch":{"place-self":"stretch"}})},alignSelf:({addUtilities:i})=>{i({".self-auto":{"align-self":"auto"},".self-start":{"align-self":"flex-start"},".self-end":{"align-self":"flex-end"},".self-center":{"align-self":"center"},".self-stretch":{"align-self":"stretch"},".self-baseline":{"align-self":"baseline"}})},justifySelf:({addUtilities:i})=>{i({".justify-self-auto":{"justify-self":"auto"},".justify-self-start":{"justify-self":"start"},".justify-self-end":{"justify-self":"end"},".justify-self-center":{"justify-self":"center"},".justify-self-stretch":{"justify-self":"stretch"}})},overflow:({addUtilities:i})=>{i({".overflow-auto":{overflow:"auto"},".overflow-hidden":{overflow:"hidden"},".overflow-clip":{overflow:"clip"},".overflow-visible":{overflow:"visible"},".overflow-scroll":{overflow:"scroll"},".overflow-x-auto":{"overflow-x":"auto"},".overflow-y-auto":{"overflow-y":"auto"},".overflow-x-hidden":{"overflow-x":"hidden"},".overflow-y-hidden":{"overflow-y":"hidden"},".overflow-x-clip":{"overflow-x":"clip"},".overflow-y-clip":{"overflow-y":"clip"},".overflow-x-visible":{"overflow-x":"visible"},".overflow-y-visible":{"overflow-y":"visible"},".overflow-x-scroll":{"overflow-x":"scroll"},".overflow-y-scroll":{"overflow-y":"scroll"}})},overscrollBehavior:({addUtilities:i})=>{i({".overscroll-auto":{"overscroll-behavior":"auto"},".overscroll-contain":{"overscroll-behavior":"contain"},".overscroll-none":{"overscroll-behavior":"none"},".overscroll-y-auto":{"overscroll-behavior-y":"auto"},".overscroll-y-contain":{"overscroll-behavior-y":"contain"},".overscroll-y-none":{"overscroll-behavior-y":"none"},".overscroll-x-auto":{"overscroll-behavior-x":"auto"},".overscroll-x-contain":{"overscroll-behavior-x":"contain"},".overscroll-x-none":{"overscroll-behavior-x":"none"}})},scrollBehavior:({addUtilities:i})=>{i({".scroll-auto":{"scroll-behavior":"auto"},".scroll-smooth":{"scroll-behavior":"smooth"}})},textOverflow:({addUtilities:i})=>{i({".truncate":{overflow:"hidden","text-overflow":"ellipsis","white-space":"nowrap"},".overflow-ellipsis":{"text-overflow":"ellipsis"},".text-ellipsis":{"text-overflow":"ellipsis"},".text-clip":{"text-overflow":"clip"}})},hyphens:({addUtilities:i})=>{i({".hyphens-none":{hyphens:"none"},".hyphens-manual":{hyphens:"manual"},".hyphens-auto":{hyphens:"auto"}})},whitespace:({addUtilities:i})=>{i({".whitespace-normal":{"white-space":"normal"},".whitespace-nowrap":{"white-space":"nowrap"},".whitespace-pre":{"white-space":"pre"},".whitespace-pre-line":{"white-space":"pre-line"},".whitespace-pre-wrap":{"white-space":"pre-wrap"},".whitespace-break-spaces":{"white-space":"break-spaces"}})},wordBreak:({addUtilities:i})=>{i({".break-normal":{"overflow-wrap":"normal","word-break":"normal"},".break-words":{"overflow-wrap":"break-word"},".break-all":{"word-break":"break-all"},".break-keep":{"word-break":"keep-all"}})},borderRadius:P("borderRadius",[["rounded",["border-radius"]],[["rounded-s",["border-start-start-radius","border-end-start-radius"]],["rounded-e",["border-start-end-radius","border-end-end-radius"]],["rounded-t",["border-top-left-radius","border-top-right-radius"]],["rounded-r",["border-top-right-radius","border-bottom-right-radius"]],["rounded-b",["border-bottom-right-radius","border-bottom-left-radius"]],["rounded-l",["border-top-left-radius","border-bottom-left-radius"]]],[["rounded-ss",["border-start-start-radius"]],["rounded-se",["border-start-end-radius"]],["rounded-ee",["border-end-end-radius"]],["rounded-es",["border-end-start-radius"]],["rounded-tl",["border-top-left-radius"]],["rounded-tr",["border-top-right-radius"]],["rounded-br",["border-bottom-right-radius"]],["rounded-bl",["border-bottom-left-radius"]]]]),borderWidth:P("borderWidth",[["border",[["@defaults border-width",{}],"border-width"]],[["border-x",[["@defaults border-width",{}],"border-left-width","border-right-width"]],["border-y",[["@defaults border-width",{}],"border-top-width","border-bottom-width"]]],[["border-s",[["@defaults border-width",{}],"border-inline-start-width"]],["border-e",[["@defaults border-width",{}],"border-inline-end-width"]],["border-t",[["@defaults border-width",{}],"border-top-width"]],["border-r",[["@defaults border-width",{}],"border-right-width"]],["border-b",[["@defaults border-width",{}],"border-bottom-width"]],["border-l",[["@defaults border-width",{}],"border-left-width"]]]],{type:["line-width","length"]}),borderStyle:({addUtilities:i})=>{i({".border-solid":{"border-style":"solid"},".border-dashed":{"border-style":"dashed"},".border-dotted":{"border-style":"dotted"},".border-double":{"border-style":"double"},".border-hidden":{"border-style":"hidden"},".border-none":{"border-style":"none"}})},borderColor:({matchUtilities:i,theme:e,corePlugins:t})=>{i({border:r=>t("borderOpacity")?se({color:r,property:"border-color",variable:"--tw-border-opacity"}):{"border-color":N(r)}},{values:(({DEFAULT:r,...n})=>n)(re(e("borderColor"))),type:["color","any"]}),i({"border-x":r=>t("borderOpacity")?se({color:r,property:["border-left-color","border-right-color"],variable:"--tw-border-opacity"}):{"border-left-color":N(r),"border-right-color":N(r)},"border-y":r=>t("borderOpacity")?se({color:r,property:["border-top-color","border-bottom-color"],variable:"--tw-border-opacity"}):{"border-top-color":N(r),"border-bottom-color":N(r)}},{values:(({DEFAULT:r,...n})=>n)(re(e("borderColor"))),type:["color","any"]}),i({"border-s":r=>t("borderOpacity")?se({color:r,property:"border-inline-start-color",variable:"--tw-border-opacity"}):{"border-inline-start-color":N(r)},"border-e":r=>t("borderOpacity")?se({color:r,property:"border-inline-end-color",variable:"--tw-border-opacity"}):{"border-inline-end-color":N(r)},"border-t":r=>t("borderOpacity")?se({color:r,property:"border-top-color",variable:"--tw-border-opacity"}):{"border-top-color":N(r)},"border-r":r=>t("borderOpacity")?se({color:r,property:"border-right-color",variable:"--tw-border-opacity"}):{"border-right-color":N(r)},"border-b":r=>t("borderOpacity")?se({color:r,property:"border-bottom-color",variable:"--tw-border-opacity"}):{"border-bottom-color":N(r)},"border-l":r=>t("borderOpacity")?se({color:r,property:"border-left-color",variable:"--tw-border-opacity"}):{"border-left-color":N(r)}},{values:(({DEFAULT:r,...n})=>n)(re(e("borderColor"))),type:["color","any"]})},borderOpacity:P("borderOpacity",[["border-opacity",["--tw-border-opacity"]]]),backgroundColor:({matchUtilities:i,theme:e,corePlugins:t})=>{i({bg:r=>t("backgroundOpacity")?se({color:r,property:"background-color",variable:"--tw-bg-opacity"}):{"background-color":N(r)}},{values:re(e("backgroundColor")),type:["color","any"]})},backgroundOpacity:P("backgroundOpacity",[["bg-opacity",["--tw-bg-opacity"]]]),backgroundImage:P("backgroundImage",[["bg",["background-image"]]],{type:["lookup","image","url"]}),gradientColorStops:(()=>{function i(e){return Ie(e,0,"rgb(255 255 255 / 0)")}return function({matchUtilities:e,theme:t,addDefaults:r}){r("gradient-color-stops",{"--tw-gradient-from-position":" ","--tw-gradient-via-position":" ","--tw-gradient-to-position":" "});let n={values:re(t("gradientColorStops")),type:["color","any"]},a={values:t("gradientColorStopPositions"),type:["length","percentage"]};e({from:s=>{let o=i(s);return{"@defaults gradient-color-stops":{},"--tw-gradient-from":`${N(s)} var(--tw-gradient-from-position)`,"--tw-gradient-to":`${o} var(--tw-gradient-to-position)`,"--tw-gradient-stops":"var(--tw-gradient-from), var(--tw-gradient-to)"}}},n),e({from:s=>({"--tw-gradient-from-position":s})},a),e({via:s=>{let o=i(s);return{"@defaults gradient-color-stops":{},"--tw-gradient-to":`${o} var(--tw-gradient-to-position)`,"--tw-gradient-stops":`var(--tw-gradient-from), ${N(s)} var(--tw-gradient-via-position), var(--tw-gradient-to)`}}},n),e({via:s=>({"--tw-gradient-via-position":s})},a),e({to:s=>({"@defaults gradient-color-stops":{},"--tw-gradient-to":`${N(s)} var(--tw-gradient-to-position)`})},n),e({to:s=>({"--tw-gradient-to-position":s})},a)}})(),boxDecorationBreak:({addUtilities:i})=>{i({".decoration-slice":{"box-decoration-break":"slice"},".decoration-clone":{"box-decoration-break":"clone"},".box-decoration-slice":{"box-decoration-break":"slice"},".box-decoration-clone":{"box-decoration-break":"clone"}})},backgroundSize:P("backgroundSize",[["bg",["background-size"]]],{type:["lookup","length","percentage","size"]}),backgroundAttachment:({addUtilities:i})=>{i({".bg-fixed":{"background-attachment":"fixed"},".bg-local":{"background-attachment":"local"},".bg-scroll":{"background-attachment":"scroll"}})},backgroundClip:({addUtilities:i})=>{i({".bg-clip-border":{"background-clip":"border-box"},".bg-clip-padding":{"background-clip":"padding-box"},".bg-clip-content":{"background-clip":"content-box"},".bg-clip-text":{"background-clip":"text"}})},backgroundPosition:P("backgroundPosition",[["bg",["background-position"]]],{type:["lookup",["position",{preferOnConflict:!0}]]}),backgroundRepeat:({addUtilities:i})=>{i({".bg-repeat":{"background-repeat":"repeat"},".bg-no-repeat":{"background-repeat":"no-repeat"},".bg-repeat-x":{"background-repeat":"repeat-x"},".bg-repeat-y":{"background-repeat":"repeat-y"},".bg-repeat-round":{"background-repeat":"round"},".bg-repeat-space":{"background-repeat":"space"}})},backgroundOrigin:({addUtilities:i})=>{i({".bg-origin-border":{"background-origin":"border-box"},".bg-origin-padding":{"background-origin":"padding-box"},".bg-origin-content":{"background-origin":"content-box"}})},fill:({matchUtilities:i,theme:e})=>{i({fill:t=>({fill:N(t)})},{values:re(e("fill")),type:["color","any"]})},stroke:({matchUtilities:i,theme:e})=>{i({stroke:t=>({stroke:N(t)})},{values:re(e("stroke")),type:["color","url","any"]})},strokeWidth:P("strokeWidth",[["stroke",["stroke-width"]]],{type:["length","number","percentage"]}),objectFit:({addUtilities:i})=>{i({".object-contain":{"object-fit":"contain"},".object-cover":{"object-fit":"cover"},".object-fill":{"object-fit":"fill"},".object-none":{"object-fit":"none"},".object-scale-down":{"object-fit":"scale-down"}})},objectPosition:P("objectPosition",[["object",["object-position"]]]),padding:P("padding",[["p",["padding"]],[["px",["padding-left","padding-right"]],["py",["padding-top","padding-bottom"]]],[["ps",["padding-inline-start"]],["pe",["padding-inline-end"]],["pt",["padding-top"]],["pr",["padding-right"]],["pb",["padding-bottom"]],["pl",["padding-left"]]]]),textAlign:({addUtilities:i})=>{i({".text-left":{"text-align":"left"},".text-center":{"text-align":"center"},".text-right":{"text-align":"right"},".text-justify":{"text-align":"justify"},".text-start":{"text-align":"start"},".text-end":{"text-align":"end"}})},textIndent:P("textIndent",[["indent",["text-indent"]]],{supportsNegativeValues:!0}),verticalAlign:({addUtilities:i,matchUtilities:e})=>{i({".align-baseline":{"vertical-align":"baseline"},".align-top":{"vertical-align":"top"},".align-middle":{"vertical-align":"middle"},".align-bottom":{"vertical-align":"bottom"},".align-text-top":{"vertical-align":"text-top"},".align-text-bottom":{"vertical-align":"text-bottom"},".align-sub":{"vertical-align":"sub"},".align-super":{"vertical-align":"super"}}),e({align:t=>({"vertical-align":t})})},fontFamily:({matchUtilities:i,theme:e})=>{i({font:t=>{let[r,n={}]=Array.isArray(t)&&ie(t[1])?t:[t],{fontFeatureSettings:a,fontVariationSettings:s}=n;return{"font-family":Array.isArray(r)?r.join(", "):r,...a===void 0?{}:{"font-feature-settings":a},...s===void 0?{}:{"font-variation-settings":s}}}},{values:e("fontFamily"),type:["lookup","generic-name","family-name"]})},fontSize:({matchUtilities:i,theme:e})=>{i({text:(t,{modifier:r})=>{let[n,a]=Array.isArray(t)?t:[t];if(r)return{"font-size":n,"line-height":r};let{lineHeight:s,letterSpacing:o,fontWeight:u}=ie(a)?a:{lineHeight:a};return{"font-size":n,...s===void 0?{}:{"line-height":s},...o===void 0?{}:{"letter-spacing":o},...u===void 0?{}:{"font-weight":u}}}},{values:e("fontSize"),modifiers:e("lineHeight"),type:["absolute-size","relative-size","length","percentage"]})},fontWeight:P("fontWeight",[["font",["fontWeight"]]],{type:["lookup","number","any"]}),textTransform:({addUtilities:i})=>{i({".uppercase":{"text-transform":"uppercase"},".lowercase":{"text-transform":"lowercase"},".capitalize":{"text-transform":"capitalize"},".normal-case":{"text-transform":"none"}})},fontStyle:({addUtilities:i})=>{i({".italic":{"font-style":"italic"},".not-italic":{"font-style":"normal"}})},fontVariantNumeric:({addDefaults:i,addUtilities:e})=>{let t="var(--tw-ordinal) var(--tw-slashed-zero) var(--tw-numeric-figure) var(--tw-numeric-spacing) var(--tw-numeric-fraction)";i("font-variant-numeric",{"--tw-ordinal":" ","--tw-slashed-zero":" ","--tw-numeric-figure":" ","--tw-numeric-spacing":" ","--tw-numeric-fraction":" "}),e({".normal-nums":{"font-variant-numeric":"normal"},".ordinal":{"@defaults font-variant-numeric":{},"--tw-ordinal":"ordinal","font-variant-numeric":t},".slashed-zero":{"@defaults font-variant-numeric":{},"--tw-slashed-zero":"slashed-zero","font-variant-numeric":t},".lining-nums":{"@defaults font-variant-numeric":{},"--tw-numeric-figure":"lining-nums","font-variant-numeric":t},".oldstyle-nums":{"@defaults font-variant-numeric":{},"--tw-numeric-figure":"oldstyle-nums","font-variant-numeric":t},".proportional-nums":{"@defaults font-variant-numeric":{},"--tw-numeric-spacing":"proportional-nums","font-variant-numeric":t},".tabular-nums":{"@defaults font-variant-numeric":{},"--tw-numeric-spacing":"tabular-nums","font-variant-numeric":t},".diagonal-fractions":{"@defaults font-variant-numeric":{},"--tw-numeric-fraction":"diagonal-fractions","font-variant-numeric":t},".stacked-fractions":{"@defaults font-variant-numeric":{},"--tw-numeric-fraction":"stacked-fractions","font-variant-numeric":t}})},lineHeight:P("lineHeight",[["leading",["lineHeight"]]]),letterSpacing:P("letterSpacing",[["tracking",["letterSpacing"]]],{supportsNegativeValues:!0}),textColor:({matchUtilities:i,theme:e,corePlugins:t})=>{i({text:r=>t("textOpacity")?se({color:r,property:"color",variable:"--tw-text-opacity"}):{color:N(r)}},{values:re(e("textColor")),type:["color","any"]})},textOpacity:P("textOpacity",[["text-opacity",["--tw-text-opacity"]]]),textDecoration:({addUtilities:i})=>{i({".underline":{"text-decoration-line":"underline"},".overline":{"text-decoration-line":"overline"},".line-through":{"text-decoration-line":"line-through"},".no-underline":{"text-decoration-line":"none"}})},textDecorationColor:({matchUtilities:i,theme:e})=>{i({decoration:t=>({"text-decoration-color":N(t)})},{values:re(e("textDecorationColor")),type:["color","any"]})},textDecorationStyle:({addUtilities:i})=>{i({".decoration-solid":{"text-decoration-style":"solid"},".decoration-double":{"text-decoration-style":"double"},".decoration-dotted":{"text-decoration-style":"dotted"},".decoration-dashed":{"text-decoration-style":"dashed"},".decoration-wavy":{"text-decoration-style":"wavy"}})},textDecorationThickness:P("textDecorationThickness",[["decoration",["text-decoration-thickness"]]],{type:["length","percentage"]}),textUnderlineOffset:P("textUnderlineOffset",[["underline-offset",["text-underline-offset"]]],{type:["length","percentage","any"]}),fontSmoothing:({addUtilities:i})=>{i({".antialiased":{"-webkit-font-smoothing":"antialiased","-moz-osx-font-smoothing":"grayscale"},".subpixel-antialiased":{"-webkit-font-smoothing":"auto","-moz-osx-font-smoothing":"auto"}})},placeholderColor:({matchUtilities:i,theme:e,corePlugins:t})=>{i({placeholder:r=>t("placeholderOpacity")?{"&::placeholder":se({color:r,property:"color",variable:"--tw-placeholder-opacity"})}:{"&::placeholder":{color:N(r)}}},{values:re(e("placeholderColor")),type:["color","any"]})},placeholderOpacity:({matchUtilities:i,theme:e})=>{i({"placeholder-opacity":t=>({["&::placeholder"]:{"--tw-placeholder-opacity":t}})},{values:e("placeholderOpacity")})},caretColor:({matchUtilities:i,theme:e})=>{i({caret:t=>({"caret-color":N(t)})},{values:re(e("caretColor")),type:["color","any"]})},accentColor:({matchUtilities:i,theme:e})=>{i({accent:t=>({"accent-color":N(t)})},{values:re(e("accentColor")),type:["color","any"]})},opacity:P("opacity",[["opacity",["opacity"]]]),backgroundBlendMode:({addUtilities:i})=>{i({".bg-blend-normal":{"background-blend-mode":"normal"},".bg-blend-multiply":{"background-blend-mode":"multiply"},".bg-blend-screen":{"background-blend-mode":"screen"},".bg-blend-overlay":{"background-blend-mode":"overlay"},".bg-blend-darken":{"background-blend-mode":"darken"},".bg-blend-lighten":{"background-blend-mode":"lighten"},".bg-blend-color-dodge":{"background-blend-mode":"color-dodge"},".bg-blend-color-burn":{"background-blend-mode":"color-burn"},".bg-blend-hard-light":{"background-blend-mode":"hard-light"},".bg-blend-soft-light":{"background-blend-mode":"soft-light"},".bg-blend-difference":{"background-blend-mode":"difference"},".bg-blend-exclusion":{"background-blend-mode":"exclusion"},".bg-blend-hue":{"background-blend-mode":"hue"},".bg-blend-saturation":{"background-blend-mode":"saturation"},".bg-blend-color":{"background-blend-mode":"color"},".bg-blend-luminosity":{"background-blend-mode":"luminosity"}})},mixBlendMode:({addUtilities:i})=>{i({".mix-blend-normal":{"mix-blend-mode":"normal"},".mix-blend-multiply":{"mix-blend-mode":"multiply"},".mix-blend-screen":{"mix-blend-mode":"screen"},".mix-blend-overlay":{"mix-blend-mode":"overlay"},".mix-blend-darken":{"mix-blend-mode":"darken"},".mix-blend-lighten":{"mix-blend-mode":"lighten"},".mix-blend-color-dodge":{"mix-blend-mode":"color-dodge"},".mix-blend-color-burn":{"mix-blend-mode":"color-burn"},".mix-blend-hard-light":{"mix-blend-mode":"hard-light"},".mix-blend-soft-light":{"mix-blend-mode":"soft-light"},".mix-blend-difference":{"mix-blend-mode":"difference"},".mix-blend-exclusion":{"mix-blend-mode":"exclusion"},".mix-blend-hue":{"mix-blend-mode":"hue"},".mix-blend-saturation":{"mix-blend-mode":"saturation"},".mix-blend-color":{"mix-blend-mode":"color"},".mix-blend-luminosity":{"mix-blend-mode":"luminosity"},".mix-blend-plus-lighter":{"mix-blend-mode":"plus-lighter"}})},boxShadow:(()=>{let i=Ge("boxShadow"),e=["var(--tw-ring-offset-shadow, 0 0 #0000)","var(--tw-ring-shadow, 0 0 #0000)","var(--tw-shadow)"].join(", ");return function({matchUtilities:t,addDefaults:r,theme:n}){r(" box-shadow",{"--tw-ring-offset-shadow":"0 0 #0000","--tw-ring-shadow":"0 0 #0000","--tw-shadow":"0 0 #0000","--tw-shadow-colored":"0 0 #0000"}),t({shadow:a=>{a=i(a);let s=yi(a);for(let o of s)!o.valid||(o.color="var(--tw-shadow-color)");return{"@defaults box-shadow":{},"--tw-shadow":a==="none"?"0 0 #0000":a,"--tw-shadow-colored":a==="none"?"0 0 #0000":Iu(s),"box-shadow":e}}},{values:n("boxShadow"),type:["shadow"]})}})(),boxShadowColor:({matchUtilities:i,theme:e})=>{i({shadow:t=>({"--tw-shadow-color":N(t),"--tw-shadow":"var(--tw-shadow-colored)"})},{values:re(e("boxShadowColor")),type:["color","any"]})},outlineStyle:({addUtilities:i})=>{i({".outline-none":{outline:"2px solid transparent","outline-offset":"2px"},".outline":{"outline-style":"solid"},".outline-dashed":{"outline-style":"dashed"},".outline-dotted":{"outline-style":"dotted"},".outline-double":{"outline-style":"double"}})},outlineWidth:P("outlineWidth",[["outline",["outline-width"]]],{type:["length","number","percentage"]}),outlineOffset:P("outlineOffset",[["outline-offset",["outline-offset"]]],{type:["length","number","percentage","any"],supportsNegativeValues:!0}),outlineColor:({matchUtilities:i,theme:e})=>{i({outline:t=>({"outline-color":N(t)})},{values:re(e("outlineColor")),type:["color","any"]})},ringWidth:({matchUtilities:i,addDefaults:e,addUtilities:t,theme:r,config:n})=>{let a=(()=>{if(J(n(),"respectDefaultRingColorOpacity"))return r("ringColor.DEFAULT");let s=r("ringOpacity.DEFAULT","0.5");return r("ringColor")?.DEFAULT?Ie(r("ringColor")?.DEFAULT,s,`rgb(147 197 253 / ${s})`):`rgb(147 197 253 / ${s})`})();e("ring-width",{"--tw-ring-inset":" ","--tw-ring-offset-width":r("ringOffsetWidth.DEFAULT","0px"),"--tw-ring-offset-color":r("ringOffsetColor.DEFAULT","#fff"),"--tw-ring-color":a,"--tw-ring-offset-shadow":"0 0 #0000","--tw-ring-shadow":"0 0 #0000","--tw-shadow":"0 0 #0000","--tw-shadow-colored":"0 0 #0000"}),i({ring:s=>({"@defaults ring-width":{},"--tw-ring-offset-shadow":"var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color)","--tw-ring-shadow":`var(--tw-ring-inset) 0 0 0 calc(${s} + var(--tw-ring-offset-width)) var(--tw-ring-color)`,"box-shadow":["var(--tw-ring-offset-shadow)","var(--tw-ring-shadow)","var(--tw-shadow, 0 0 #0000)"].join(", ")})},{values:r("ringWidth"),type:"length"}),t({".ring-inset":{"@defaults ring-width":{},"--tw-ring-inset":"inset"}})},ringColor:({matchUtilities:i,theme:e,corePlugins:t})=>{i({ring:r=>t("ringOpacity")?se({color:r,property:"--tw-ring-color",variable:"--tw-ring-opacity"}):{"--tw-ring-color":N(r)}},{values:Object.fromEntries(Object.entries(re(e("ringColor"))).filter(([r])=>r!=="DEFAULT")),type:["color","any"]})},ringOpacity:i=>{let{config:e}=i;return P("ringOpacity",[["ring-opacity",["--tw-ring-opacity"]]],{filterDefault:!J(e(),"respectDefaultRingColorOpacity")})(i)},ringOffsetWidth:P("ringOffsetWidth",[["ring-offset",["--tw-ring-offset-width"]]],{type:"length"}),ringOffsetColor:({matchUtilities:i,theme:e})=>{i({"ring-offset":t=>({"--tw-ring-offset-color":N(t)})},{values:re(e("ringOffsetColor")),type:["color","any"]})},blur:({matchUtilities:i,theme:e})=>{i({blur:t=>({"--tw-blur":`blur(${t})`,"@defaults filter":{},filter:Be})},{values:e("blur")})},brightness:({matchUtilities:i,theme:e})=>{i({brightness:t=>({"--tw-brightness":`brightness(${t})`,"@defaults filter":{},filter:Be})},{values:e("brightness")})},contrast:({matchUtilities:i,theme:e})=>{i({contrast:t=>({"--tw-contrast":`contrast(${t})`,"@defaults filter":{},filter:Be})},{values:e("contrast")})},dropShadow:({matchUtilities:i,theme:e})=>{i({"drop-shadow":t=>({"--tw-drop-shadow":Array.isArray(t)?t.map(r=>`drop-shadow(${r})`).join(" "):`drop-shadow(${t})`,"@defaults filter":{},filter:Be})},{values:e("dropShadow")})},grayscale:({matchUtilities:i,theme:e})=>{i({grayscale:t=>({"--tw-grayscale":`grayscale(${t})`,"@defaults filter":{},filter:Be})},{values:e("grayscale")})},hueRotate:({matchUtilities:i,theme:e})=>{i({"hue-rotate":t=>({"--tw-hue-rotate":`hue-rotate(${t})`,"@defaults filter":{},filter:Be})},{values:e("hueRotate"),supportsNegativeValues:!0})},invert:({matchUtilities:i,theme:e})=>{i({invert:t=>({"--tw-invert":`invert(${t})`,"@defaults filter":{},filter:Be})},{values:e("invert")})},saturate:({matchUtilities:i,theme:e})=>{i({saturate:t=>({"--tw-saturate":`saturate(${t})`,"@defaults filter":{},filter:Be})},{values:e("saturate")})},sepia:({matchUtilities:i,theme:e})=>{i({sepia:t=>({"--tw-sepia":`sepia(${t})`,"@defaults filter":{},filter:Be})},{values:e("sepia")})},filter:({addDefaults:i,addUtilities:e})=>{i("filter",{"--tw-blur":" ","--tw-brightness":" ","--tw-contrast":" ","--tw-grayscale":" ","--tw-hue-rotate":" ","--tw-invert":" ","--tw-saturate":" ","--tw-sepia":" ","--tw-drop-shadow":" "}),e({".filter":{"@defaults filter":{},filter:Be},".filter-none":{filter:"none"}})},backdropBlur:({matchUtilities:i,theme:e})=>{i({"backdrop-blur":t=>({"--tw-backdrop-blur":`blur(${t})`,"@defaults backdrop-filter":{},"backdrop-filter":Fe})},{values:e("backdropBlur")})},backdropBrightness:({matchUtilities:i,theme:e})=>{i({"backdrop-brightness":t=>({"--tw-backdrop-brightness":`brightness(${t})`,"@defaults backdrop-filter":{},"backdrop-filter":Fe})},{values:e("backdropBrightness")})},backdropContrast:({matchUtilities:i,theme:e})=>{i({"backdrop-contrast":t=>({"--tw-backdrop-contrast":`contrast(${t})`,"@defaults backdrop-filter":{},"backdrop-filter":Fe})},{values:e("backdropContrast")})},backdropGrayscale:({matchUtilities:i,theme:e})=>{i({"backdrop-grayscale":t=>({"--tw-backdrop-grayscale":`grayscale(${t})`,"@defaults backdrop-filter":{},"backdrop-filter":Fe})},{values:e("backdropGrayscale")})},backdropHueRotate:({matchUtilities:i,theme:e})=>{i({"backdrop-hue-rotate":t=>({"--tw-backdrop-hue-rotate":`hue-rotate(${t})`,"@defaults backdrop-filter":{},"backdrop-filter":Fe})},{values:e("backdropHueRotate"),supportsNegativeValues:!0})},backdropInvert:({matchUtilities:i,theme:e})=>{i({"backdrop-invert":t=>({"--tw-backdrop-invert":`invert(${t})`,"@defaults backdrop-filter":{},"backdrop-filter":Fe})},{values:e("backdropInvert")})},backdropOpacity:({matchUtilities:i,theme:e})=>{i({"backdrop-opacity":t=>({"--tw-backdrop-opacity":`opacity(${t})`,"@defaults backdrop-filter":{},"backdrop-filter":Fe})},{values:e("backdropOpacity")})},backdropSaturate:({matchUtilities:i,theme:e})=>{i({"backdrop-saturate":t=>({"--tw-backdrop-saturate":`saturate(${t})`,"@defaults backdrop-filter":{},"backdrop-filter":Fe})},{values:e("backdropSaturate")})},backdropSepia:({matchUtilities:i,theme:e})=>{i({"backdrop-sepia":t=>({"--tw-backdrop-sepia":`sepia(${t})`,"@defaults backdrop-filter":{},"backdrop-filter":Fe})},{values:e("backdropSepia")})},backdropFilter:({addDefaults:i,addUtilities:e})=>{i("backdrop-filter",{"--tw-backdrop-blur":" ","--tw-backdrop-brightness":" ","--tw-backdrop-contrast":" ","--tw-backdrop-grayscale":" ","--tw-backdrop-hue-rotate":" ","--tw-backdrop-invert":" ","--tw-backdrop-opacity":" ","--tw-backdrop-saturate":" ","--tw-backdrop-sepia":" "}),e({".backdrop-filter":{"@defaults backdrop-filter":{},"backdrop-filter":Fe},".backdrop-filter-none":{"backdrop-filter":"none"}})},transitionProperty:({matchUtilities:i,theme:e})=>{let t=e("transitionTimingFunction.DEFAULT"),r=e("transitionDuration.DEFAULT");i({transition:n=>({"transition-property":n,...n==="none"?{}:{"transition-timing-function":t,"transition-duration":r}})},{values:e("transitionProperty")})},transitionDelay:P("transitionDelay",[["delay",["transitionDelay"]]]),transitionDuration:P("transitionDuration",[["duration",["transitionDuration"]]],{filterDefault:!0}),transitionTimingFunction:P("transitionTimingFunction",[["ease",["transitionTimingFunction"]]],{filterDefault:!0}),willChange:P("willChange",[["will-change",["will-change"]]]),content:P("content",[["content",["--tw-content",["content","var(--tw-content)"]]]])}});function bC(i){if(i===void 0)return!1;if(i==="true"||i==="1")return!0;if(i==="false"||i==="0")return!1;if(i==="*")return!0;let e=i.split(",").map(t=>t.split(":")[0]);return e.includes("-tailwindcss")?!1:!!e.includes("tailwindcss")}var Pe,wd,bd,gn,Xa,He,Kr,ot=C(()=>{l();Ya();Pe=typeof m!="undefined"?{NODE_ENV:"production",DEBUG:bC(m.env.DEBUG),ENGINE:Ja.tailwindcss.engine}:{NODE_ENV:"production",DEBUG:!1,ENGINE:Ja.tailwindcss.engine},wd=new Map,bd=new Map,gn=new Map,Xa=new Map,He=new String("*"),Kr=Symbol("__NONE__")});function Bt(i){let e=[],t=!1;for(let r=0;r0)}var vd,xd,vC,Ka=C(()=>{l();vd=new Map([["{","}"],["[","]"],["(",")"]]),xd=new Map(Array.from(vd.entries()).map(([i,e])=>[e,i])),vC=new Set(['"',"'","`"])});function Ft(i){let[e]=kd(i);return e.forEach(([t,r])=>t.removeChild(r)),i.nodes.push(...e.map(([,t])=>t)),i}function kd(i){let e=[],t=null;for(let r of i.nodes)if(r.type==="combinator")e=e.filter(([,n])=>eo(n).includes("jumpable")),t=null;else if(r.type==="pseudo"){xC(r)?(t=r,e.push([i,r,null])):t&&kC(r,t)?e.push([i,r,t]):t=null;for(let n of r.nodes??[]){let[a,s]=kd(n);t=s||t,e.push(...a)}}return[e,t]}function Sd(i){return i.value.startsWith("::")||Za[i.value]!==void 0}function xC(i){return Sd(i)&&eo(i).includes("terminal")}function kC(i,e){return i.type!=="pseudo"||Sd(i)?!1:eo(e).includes("actionable")}function eo(i){return Za[i.value]??Za.__default__}var Za,yn=C(()=>{l();Za={"::after":["terminal","jumpable"],"::backdrop":["terminal","jumpable"],"::before":["terminal","jumpable"],"::cue":["terminal"],"::cue-region":["terminal"],"::first-letter":["terminal","jumpable"],"::first-line":["terminal","jumpable"],"::grammar-error":["terminal"],"::marker":["terminal","jumpable"],"::part":["terminal","actionable"],"::placeholder":["terminal","jumpable"],"::selection":["terminal","jumpable"],"::slotted":["terminal"],"::spelling-error":["terminal"],"::target-text":["terminal"],"::file-selector-button":["terminal","actionable"],"::deep":["actionable"],"::v-deep":["actionable"],"::ng-deep":["actionable"],":after":["terminal","jumpable"],":before":["terminal","jumpable"],":first-letter":["terminal","jumpable"],":first-line":["terminal","jumpable"],__default__:["terminal","actionable"]}});function Nt(i,{context:e,candidate:t}){let r=e?.tailwindConfig.prefix??"",n=i.map(s=>{let o=(0,Ne.default)().astSync(s.format);return{...s,ast:s.respectPrefix?Rt(r,o):o}}),a=Ne.default.root({nodes:[Ne.default.selector({nodes:[Ne.default.className({value:ce(t)})]})]});for(let{ast:s}of n)[a,s]=CC(a,s),s.walkNesting(o=>o.replaceWith(...a.nodes[0].nodes)),a=s;return a}function Ad(i){let e=[];for(;i.prev()&&i.prev().type!=="combinator";)i=i.prev();for(;i&&i.type!=="combinator";)e.push(i),i=i.next();return e}function SC(i){return i.sort((e,t)=>e.type==="tag"&&t.type==="class"?-1:e.type==="class"&&t.type==="tag"?1:e.type==="class"&&t.type==="pseudo"&&t.value.startsWith("::")?-1:e.type==="pseudo"&&e.value.startsWith("::")&&t.type==="class"?1:i.index(e)-i.index(t)),i}function ro(i,e){let t=!1;i.walk(r=>{if(r.type==="class"&&r.value===e)return t=!0,!1}),t||i.remove()}function wn(i,e,{context:t,candidate:r,base:n}){let a=t?.tailwindConfig?.separator??":";n=n??r.split(new RegExp(`\\${a}(?![^[]*\\])`)).pop();let s=(0,Ne.default)().astSync(i);s.walkClasses(f=>{f.raws&&f.value.includes(n)&&(f.raws.value=ce((0,Cd.default)(f.raws.value)))}),s.each(f=>ro(f,n));let o=Array.isArray(e)?Nt(e,{context:t,candidate:r}):e;if(o===null)return s.toString();let u=Ne.default.comment({value:"/*__simple__*/"}),c=Ne.default.comment({value:"/*__simple__*/"});return s.walkClasses(f=>{if(f.value!==n)return;let p=f.parent,d=o.nodes[0].nodes;if(p.nodes.length===1){f.replaceWith(...d);return}let h=Ad(f);p.insertBefore(h[0],u),p.insertAfter(h[h.length-1],c);for(let x of d)p.insertBefore(h[0],x.clone());f.remove(),h=Ad(u);let y=p.index(u);p.nodes.splice(y,h.length,...SC(Ne.default.selector({nodes:h})).nodes),u.remove(),c.remove()}),s.walkPseudos(f=>{f.value===to&&f.replaceWith(f.nodes)}),s.each(f=>Ft(f)),s.toString()}function CC(i,e){let t=[];return i.walkPseudos(r=>{r.value===to&&t.push({pseudo:r,value:r.nodes[0].toString()})}),e.walkPseudos(r=>{if(r.value!==to)return;let n=r.nodes[0].toString(),a=t.find(c=>c.value===n);if(!a)return;let s=[],o=r.next();for(;o&&o.type!=="combinator";)s.push(o),o=o.next();let u=o;a.pseudo.parent.insertAfter(a.pseudo,Ne.default.selector({nodes:s.map(c=>c.clone())})),r.remove(),s.forEach(c=>c.remove()),u&&u.type==="combinator"&&u.remove()}),[i,e]}var Ne,Cd,to,io=C(()=>{l();Ne=K(Me()),Cd=K(Yi());Mt();un();yn();to=":merge"});function bn(i,e){let t=(0,no.default)().astSync(i);return t.each(r=>{r.nodes[0].type==="pseudo"&&r.nodes[0].value===":is"&&r.nodes.every(a=>a.type!=="combinator")||(r.nodes=[no.default.pseudo({value:":is",nodes:[r.clone()]})]),Ft(r)}),`${e} ${t.toString()}`}var no,so=C(()=>{l();no=K(Me());yn()});function ao(i){return AC.transformSync(i)}function*_C(i){let e=1/0;for(;e>=0;){let t,r=!1;if(e===1/0&&i.endsWith("]")){let s=i.indexOf("[");i[s-1]==="-"?t=s-1:i[s-1]==="/"?(t=s-1,r=!0):t=-1}else e===1/0&&i.includes("/")?(t=i.lastIndexOf("/"),r=!0):t=i.lastIndexOf("-",e);if(t<0)break;let n=i.slice(0,t),a=i.slice(r?t:t+1);e=t-1,!(n===""||a==="/")&&(yield[n,a])}}function EC(i,e){if(i.length===0||e.tailwindConfig.prefix==="")return i;for(let t of i){let[r]=t;if(r.options.respectPrefix){let n=z.root({nodes:[t[1].clone()]}),a=t[1].raws.tailwind.classCandidate;n.walkRules(s=>{let o=a.startsWith("-");s.selector=Rt(e.tailwindConfig.prefix,s.selector,o)}),t[1]=n.nodes[0]}}return i}function OC(i,e){if(i.length===0)return i;let t=[];for(let[r,n]of i){let a=z.root({nodes:[n.clone()]});a.walkRules(s=>{let o=(0,vn.default)().astSync(s.selector);o.each(u=>ro(u,e)),Wu(o,u=>u===e?`!${u}`:u),s.selector=o.toString(),s.walkDecls(u=>u.important=!0)}),t.push([{...r,important:!0},a.nodes[0]])}return t}function TC(i,e,t){if(e.length===0)return e;let r={modifier:null,value:Kr};{let[n,...a]=le(i,"/");if(a.length>1&&(n=n+"/"+a.slice(0,-1).join("/"),a=a.slice(-1)),a.length&&!t.variantMap.has(i)&&(i=n,r.modifier=a[0],!J(t.tailwindConfig,"generalizedModifiers")))return[]}if(i.endsWith("]")&&!i.startsWith("[")){let n=/(.)(-?)\[(.*)\]/g.exec(i);if(n){let[,a,s,o]=n;if(a==="@"&&s==="-")return[];if(a!=="@"&&s==="")return[];i=i.replace(`${s}[${o}]`,""),r.value=o}}if(lo(i)&&!t.variantMap.has(i)){let n=t.offsets.recordVariant(i),a=U(i.slice(1,-1)),s=le(a,",");if(s.length>1)return[];if(!s.every(An))return[];let o=s.map((u,c)=>[t.offsets.applyParallelOffset(n,c),Zr(u.trim())]);t.variantMap.set(i,o)}if(t.variantMap.has(i)){let n=lo(i),a=t.variantOptions.get(i)?.[Jr]??{},s=t.variantMap.get(i).slice(),o=[],u=(()=>!(n||a.respectPrefix===!1))();for(let[c,f]of e){if(c.layer==="user")continue;let p=z.root({nodes:[f.clone()]});for(let[d,h,y]of s){let b=function(){x.raws.neededBackup||(x.raws.neededBackup=!0,x.walkRules(E=>E.raws.originalSelector=E.selector))},k=function(E){return b(),x.each(I=>{I.type==="rule"&&(I.selectors=I.selectors.map(B=>E({get className(){return ao(B)},selector:B})))}),x},x=(y??p).clone(),w=[],S=h({get container(){return b(),x},separator:t.tailwindConfig.separator,modifySelectors:k,wrap(E){let I=x.nodes;x.removeAll(),E.append(I),x.append(E)},format(E){w.push({format:E,respectPrefix:u})},args:r});if(Array.isArray(S)){for(let[E,I]of S.entries())s.push([t.offsets.applyParallelOffset(d,E),I,x.clone()]);continue}if(typeof S=="string"&&w.push({format:S,respectPrefix:u}),S===null)continue;x.raws.neededBackup&&(delete x.raws.neededBackup,x.walkRules(E=>{let I=E.raws.originalSelector;if(!I||(delete E.raws.originalSelector,I===E.selector))return;let B=E.selector,q=(0,vn.default)(X=>{X.walkClasses(ae=>{ae.value=`${i}${t.tailwindConfig.separator}${ae.value}`})}).processSync(I);w.push({format:B.replace(q,"&"),respectPrefix:u}),E.selector=I})),x.nodes[0].raws.tailwind={...x.nodes[0].raws.tailwind,parentLayer:c.layer};let _=[{...c,sort:t.offsets.applyVariantOffset(c.sort,d,Object.assign(r,t.variantOptions.get(i))),collectedFormats:(c.collectedFormats??[]).concat(w)},x.nodes[0]];o.push(_)}}return o}return[]}function oo(i,e,t={}){return!ie(i)&&!Array.isArray(i)?[[i],t]:Array.isArray(i)?oo(i[0],e,i[1]):(e.has(i)||e.set(i,qt(i)),[e.get(i),t])}function DC(i){return PC.test(i)}function IC(i){if(!i.includes("://"))return!1;try{let e=new URL(i);return e.scheme!==""&&e.host!==""}catch(e){return!1}}function _d(i){let e=!0;return i.walkDecls(t=>{if(!Ed(t.prop,t.value))return e=!1,!1}),e}function Ed(i,e){if(IC(`${i}:${e}`))return!1;try{return z.parse(`a{${i}:${e}}`).toResult(),!0}catch(t){return!1}}function qC(i,e){let[,t,r]=i.match(/^\[([a-zA-Z0-9-_]+):(\S+)\]$/)??[];if(r===void 0||!DC(t)||!Bt(r))return null;let n=U(r);return Ed(t,n)?[[{sort:e.offsets.arbitraryProperty(),layer:"utilities"},()=>({[Wa(i)]:{[t]:n}})]]:null}function*RC(i,e){e.candidateRuleMap.has(i)&&(yield[e.candidateRuleMap.get(i),"DEFAULT"]),yield*function*(o){o!==null&&(yield[o,"DEFAULT"])}(qC(i,e));let t=i,r=!1,n=e.tailwindConfig.prefix,a=n.length,s=t.startsWith(n)||t.startsWith(`-${n}`);t[a]==="-"&&s&&(r=!0,t=n+t.slice(a+1)),r&&e.candidateRuleMap.has(t)&&(yield[e.candidateRuleMap.get(t),"-DEFAULT"]);for(let[o,u]of _C(t))e.candidateRuleMap.has(o)&&(yield[e.candidateRuleMap.get(o),r?`-${u}`:u])}function MC(i,e){return i===He?[He]:le(i,e)}function*BC(i,e){for(let t of i)t[1].raws.tailwind={...t[1].raws.tailwind,classCandidate:e,preserveSource:t[0].options?.preserveSource??!1},yield t}function*xn(i,e,t=i){let r=e.tailwindConfig.separator,[n,...a]=MC(i,r).reverse(),s=!1;if(n.startsWith("!")&&(s=!0,n=n.slice(1)),J(e.tailwindConfig,"variantGrouping")&&n.startsWith("(")&&n.endsWith(")")){let o=a.slice().reverse().join(r);for(let u of le(n.slice(1,-1),","))yield*xn(o+r+u,e,t)}for(let o of RC(n,e)){let u=[],c=new Map,[f,p]=o,d=f.length===1;for(let[h,y]of f){let x=[];if(typeof y=="function")for(let w of[].concat(y(p,{isOnlyPlugin:d}))){let[b,k]=oo(w,e.postCssNodeCache);for(let S of b)x.push([{...h,options:{...h.options,...k}},S])}else if(p==="DEFAULT"||p==="-DEFAULT"){let w=y,[b,k]=oo(w,e.postCssNodeCache);for(let S of b)x.push([{...h,options:{...h.options,...k}},S])}if(x.length>0){let w=Array.from(ps(h.options?.types??[],p,h.options??{},e.tailwindConfig)).map(([b,k])=>k);w.length>0&&c.set(x,w),u.push(x)}}if(lo(p)){if(u.length>1){let x=function(b){return b.length===1?b[0]:b.find(k=>{let S=c.get(k);return k.some(([{options:_},E])=>_d(E)?_.types.some(({type:I,preferOnConflict:B})=>S.includes(I)&&B):!1)})},[h,y]=u.reduce((b,k)=>(k.some(([{options:_}])=>_.types.some(({type:E})=>E==="any"))?b[0].push(k):b[1].push(k),b),[[],[]]),w=x(y)??x(h);if(w)u=[w];else{let b=u.map(S=>new Set([...c.get(S)??[]]));for(let S of b)for(let _ of S){let E=!1;for(let I of b)S!==I&&I.has(_)&&(I.delete(_),E=!0);E&&S.delete(_)}let k=[];for(let[S,_]of b.entries())for(let E of _){let I=u[S].map(([,B])=>B).flat().map(B=>B.toString().split(` +`).slice(1,-1).map(q=>q.trim()).map(q=>` ${q}`).join(` +`)).join(` + +`);k.push(` Use \`${i.replace("[",`[${E}:`)}\` for \`${I.trim()}\``);break}F.warn([`The class \`${i}\` is ambiguous and matches multiple utilities.`,...k,`If this is content and not a class, replace it with \`${i.replace("[","[").replace("]","]")}\` to silence this warning.`]);continue}}u=u.map(h=>h.filter(y=>_d(y[1])))}u=u.flat(),u=Array.from(BC(u,n)),u=EC(u,e),s&&(u=OC(u,n));for(let h of a)u=TC(h,u,e);for(let h of u)h[1].raws.tailwind={...h[1].raws.tailwind,candidate:i},h=FC(h,{context:e,candidate:i,original:t}),h!==null&&(yield h)}}function FC(i,{context:e,candidate:t,original:r}){if(!i[0].collectedFormats)return i;let n=!0,a;try{a=Nt(i[0].collectedFormats,{context:e,candidate:t})}catch{return null}let s=z.root({nodes:[i[1].clone()]});return s.walkRules(o=>{if(!kn(o))try{o.selector=wn(o.selector,a,{candidate:r,context:e})}catch{return n=!1,!1}}),n?(i[1]=s.nodes[0],i):null}function kn(i){return i.parent&&i.parent.type==="atrule"&&i.parent.name==="keyframes"}function NC(i){if(i===!0)return e=>{kn(e)||e.walkDecls(t=>{t.parent.type==="rule"&&!kn(t.parent)&&(t.important=!0)})};if(typeof i=="string")return e=>{kn(e)||(e.selectors=e.selectors.map(t=>bn(t,i)))}}function Sn(i,e){let t=[],r=NC(e.tailwindConfig.important);for(let n of i){if(e.notClassCache.has(n))continue;if(e.candidateRuleCache.has(n)){t=t.concat(Array.from(e.candidateRuleCache.get(n)));continue}let a=Array.from(xn(n,e));if(a.length===0){e.notClassCache.add(n);continue}e.classCache.set(n,a);let s=e.candidateRuleCache.get(n)??new Set;e.candidateRuleCache.set(n,s);for(let o of a){let[{sort:u,options:c},f]=o;if(c.respectImportant&&r){let d=z.root({nodes:[f.clone()]});d.walkRules(r),f=d.nodes[0]}let p=[u,f];s.add(p),e.ruleCache.add(p),t.push(p)}}return t}function lo(i){return i.startsWith("[")&&i.endsWith("]")}var vn,AC,PC,Cn=C(()=>{l();nt();vn=K(Me());Ua();xt();un();cr();Ee();ot();io();Ga();fr();Xr();Ka();or();De();so();AC=(0,vn.default)(i=>i.first.filter(({type:e})=>e==="class").pop().value);PC=/^[a-z_-]/});var Od,Td=C(()=>{l();Od={}});function LC(i){try{return Od.createHash("md5").update(i,"utf-8").digest("binary")}catch(e){return""}}function Pd(i,e){let t=e.toString();if(!t.includes("@tailwind"))return!1;let r=Xa.get(i),n=LC(t),a=r!==n;return Xa.set(i,n),a}var Dd=C(()=>{l();Td();ot()});function _n(i){return(i>0n)-(i<0n)}var Id=C(()=>{l()});function qd(i,e){let t=0n,r=0n;for(let[n,a]of e)i&n&&(t=t|n,r=r|a);return i&~t|r}var Rd=C(()=>{l()});function Md(i){let e=null;for(let t of i)e=e??t,e=e>t?e:t;return e}function $C(i,e){let t=i.length,r=e.length,n=t{l();Id();Rd();uo=class{constructor(){this.offsets={defaults:0n,base:0n,components:0n,utilities:0n,variants:0n,user:0n},this.layerPositions={defaults:0n,base:1n,components:2n,utilities:3n,user:4n,variants:5n},this.reservedVariantBits=0n,this.variantOffsets=new Map}create(e){return{layer:e,parentLayer:e,arbitrary:0n,variants:0n,parallelIndex:0n,index:this.offsets[e]++,options:[]}}arbitraryProperty(){return{...this.create("utilities"),arbitrary:1n}}forVariant(e,t=0){let r=this.variantOffsets.get(e);if(r===void 0)throw new Error(`Cannot find offset for unknown variant ${e}`);return{...this.create("variants"),variants:r<n.startsWith("[")).sort(([n],[a])=>$C(n,a)),t=e.map(([,n])=>n).sort((n,a)=>_n(n-a));return e.map(([,n],a)=>[n,t[a]]).filter(([n,a])=>n!==a)}remapArbitraryVariantOffsets(e){let t=this.recalculateVariantOffsets();return t.length===0?e:e.map(r=>{let[n,a]=r;return n={...n,variants:qd(n.variants,t)},[n,a]})}sort(e){return e=this.remapArbitraryVariantOffsets(e),e.sort(([t],[r])=>_n(this.compare(t,r)))}}});function ho(i,e){let t=i.tailwindConfig.prefix;return typeof t=="function"?t(e):t+e}function Nd({type:i="any",...e}){let t=[].concat(i);return{...e,types:t.map(r=>Array.isArray(r)?{type:r[0],...r[1]}:{type:r,preferOnConflict:!1})}}function jC(i){let e=[],t="",r=0;for(let n=0;n0&&e.push(t.trim()),e=e.filter(n=>n!==""),e}function zC(i,e,{before:t=[]}={}){if(t=[].concat(t),t.length<=0){i.push(e);return}let r=i.length-1;for(let n of t){let a=i.indexOf(n);a!==-1&&(r=Math.min(r,a))}i.splice(r,0,e)}function Ld(i){return Array.isArray(i)?i.flatMap(e=>!Array.isArray(e)&&!ie(e)?e:qt(e)):Ld([i])}function $d(i,e){return(0,fo.default)(r=>{let n=[];return e&&e(r),r.walkClasses(a=>{n.push(a.value)}),n}).transformSync(i)}function VC(i,e={containsNonOnDemandable:!1},t=0){let r=[];if(i.type==="rule"){let n=function(a){a.walkPseudos(s=>{s.value===":not"&&s.remove()})};for(let a of i.selectors){let s=$d(a,n);s.length===0&&(e.containsNonOnDemandable=!0);for(let o of s)r.push(o)}}else i.type==="atrule"&&i.walkRules(n=>{for(let a of n.selectors.flatMap(s=>$d(s)))r.push(a)});return t===0?[e.containsNonOnDemandable||r.length===0,r]:r}function En(i){return Ld(i).flatMap(e=>{let t=new Map,[r,n]=VC(e);return r&&n.unshift(He),n.map(a=>(t.has(e)||t.set(e,e),[a,t.get(e)]))})}function An(i){return i.startsWith("@")||i.includes("&")}function Zr(i){i=i.replace(/\n+/g,"").replace(/\s{1,}/g," ").trim();let e=jC(i).map(t=>{if(!t.startsWith("@"))return({format:a})=>a(t);let[,r,n]=/@(\S*)( .+|[({].*)?/g.exec(t);return({wrap:a})=>a(z.atRule({name:r,params:n?.trim()??""}))}).reverse();return t=>{for(let r of e)r(t)}}function UC(i,e,{variantList:t,variantMap:r,offsets:n,classList:a}){function s(d,h){return d?(0,Fd.default)(i,d,h):i}function o(d){return Rt(i.prefix,d)}function u(d,h){return d===He?He:h.respectPrefix?e.tailwindConfig.prefix+d:d}function c(d,h,y={}){let x=Ke(d),w=s(["theme",...x],h);return Ge(x[0])(w,y)}let f=0,p={postcss:z,prefix:o,e:ce,config:s,theme:c,corePlugins:d=>Array.isArray(i.corePlugins)?i.corePlugins.includes(d):s(["corePlugins",d],!0),variants:()=>[],addBase(d){for(let[h,y]of En(d)){let x=u(h,{}),w=n.create("base");e.candidateRuleMap.has(x)||e.candidateRuleMap.set(x,[]),e.candidateRuleMap.get(x).push([{sort:w,layer:"base"},y])}},addDefaults(d,h){let y={[`@defaults ${d}`]:h};for(let[x,w]of En(y)){let b=u(x,{});e.candidateRuleMap.has(b)||e.candidateRuleMap.set(b,[]),e.candidateRuleMap.get(b).push([{sort:n.create("defaults"),layer:"defaults"},w])}},addComponents(d,h){h=Object.assign({},{preserveSource:!1,respectPrefix:!0,respectImportant:!1},Array.isArray(h)?{}:h);for(let[x,w]of En(d)){let b=u(x,h);a.add(b),e.candidateRuleMap.has(b)||e.candidateRuleMap.set(b,[]),e.candidateRuleMap.get(b).push([{sort:n.create("components"),layer:"components",options:h},w])}},addUtilities(d,h){h=Object.assign({},{preserveSource:!1,respectPrefix:!0,respectImportant:!0},Array.isArray(h)?{}:h);for(let[x,w]of En(d)){let b=u(x,h);a.add(b),e.candidateRuleMap.has(b)||e.candidateRuleMap.set(b,[]),e.candidateRuleMap.get(b).push([{sort:n.create("utilities"),layer:"utilities",options:h},w])}},matchUtilities:function(d,h){h=Nd({...{respectPrefix:!0,respectImportant:!0,modifiers:!1},...h});let x=n.create("utilities");for(let w in d){let S=function(E,{isOnlyPlugin:I}){let[B,q,X]=cs(h.types,E,h,i);if(B===void 0)return[];if(!h.types.some(({type:$})=>$===q))if(I)F.warn([`Unnecessary typehint \`${q}\` in \`${w}-${E}\`.`,`You can safely update it to \`${w}-${E.replace(q+":","")}\`.`]);else return[];if(!Bt(B))return[];let ae={get modifier(){return h.modifiers||F.warn(`modifier-used-without-options-for-${w}`,["Your plugin must set `modifiers: true` in its options to support modifiers."]),X}},ge=J(i,"generalizedModifiers");return[].concat(ge?k(B,ae):k(B)).filter(Boolean).map($=>({[fn(w,E)]:$}))},b=u(w,h),k=d[w];a.add([b,h]);let _=[{sort:x,layer:"utilities",options:h},S];e.candidateRuleMap.has(b)||e.candidateRuleMap.set(b,[]),e.candidateRuleMap.get(b).push(_)}},matchComponents:function(d,h){h=Nd({...{respectPrefix:!0,respectImportant:!1,modifiers:!1},...h});let x=n.create("components");for(let w in d){let S=function(E,{isOnlyPlugin:I}){let[B,q,X]=cs(h.types,E,h,i);if(B===void 0)return[];if(!h.types.some(({type:$})=>$===q))if(I)F.warn([`Unnecessary typehint \`${q}\` in \`${w}-${E}\`.`,`You can safely update it to \`${w}-${E.replace(q+":","")}\`.`]);else return[];if(!Bt(B))return[];let ae={get modifier(){return h.modifiers||F.warn(`modifier-used-without-options-for-${w}`,["Your plugin must set `modifiers: true` in its options to support modifiers."]),X}},ge=J(i,"generalizedModifiers");return[].concat(ge?k(B,ae):k(B)).filter(Boolean).map($=>({[fn(w,E)]:$}))},b=u(w,h),k=d[w];a.add([b,h]);let _=[{sort:x,layer:"components",options:h},S];e.candidateRuleMap.has(b)||e.candidateRuleMap.set(b,[]),e.candidateRuleMap.get(b).push(_)}},addVariant(d,h,y={}){h=[].concat(h).map(x=>{if(typeof x!="string")return(w={})=>{let{args:b,modifySelectors:k,container:S,separator:_,wrap:E,format:I}=w,B=x(Object.assign({modifySelectors:k,container:S,separator:_},y.type===co.MatchVariant&&{args:b,wrap:E,format:I}));if(typeof B=="string"&&!An(B))throw new Error(`Your custom variant \`${d}\` has an invalid format string. Make sure it's an at-rule or contains a \`&\` placeholder.`);return Array.isArray(B)?B.filter(q=>typeof q=="string").map(q=>Zr(q)):B&&typeof B=="string"&&Zr(B)(w)};if(!An(x))throw new Error(`Your custom variant \`${d}\` has an invalid format string. Make sure it's an at-rule or contains a \`&\` placeholder.`);return Zr(x)}),zC(t,d,y),r.set(d,h),e.variantOptions.set(d,y)},matchVariant(d,h,y){let x=y?.id??++f,w=d==="@",b=J(i,"generalizedModifiers");for(let[S,_]of Object.entries(y?.values??{}))S!=="DEFAULT"&&p.addVariant(w?`${d}${S}`:`${d}-${S}`,({args:E,container:I})=>h(_,b?{modifier:E?.modifier,container:I}:{container:I}),{...y,value:_,id:x,type:co.MatchVariant,variantInfo:po.Base});let k="DEFAULT"in(y?.values??{});p.addVariant(d,({args:S,container:_})=>S?.value===Kr&&!k?null:h(S?.value===Kr?y.values.DEFAULT:S?.value??(typeof S=="string"?S:""),b?{modifier:S?.modifier,container:_}:{container:_}),{...y,id:x,type:co.MatchVariant,variantInfo:po.Dynamic})}};return p}function On(i){return mo.has(i)||mo.set(i,new Map),mo.get(i)}function jd(i,e){let t=!1,r=new Map;for(let n of i){if(!n)continue;let a=ws.parse(n),s=a.hash?a.href.replace(a.hash,""):a.href;s=a.search?s.replace(a.search,""):s;let o=te.statSync(decodeURIComponent(s),{throwIfNoEntry:!1})?.mtimeMs;!o||((!e.has(n)||o>e.get(n))&&(t=!0),r.set(n,o))}return[t,r]}function zd(i){i.walkAtRules(e=>{["responsive","variants"].includes(e.name)&&(zd(e),e.before(e.nodes),e.remove())})}function WC(i){let e=[];return i.each(t=>{t.type==="atrule"&&["responsive","variants"].includes(t.name)&&(t.name="layer",t.params="utilities")}),i.walkAtRules("layer",t=>{if(zd(t),t.params==="base"){for(let r of t.nodes)e.push(function({addBase:n}){n(r,{respectPrefix:!1})});t.remove()}else if(t.params==="components"){for(let r of t.nodes)e.push(function({addComponents:n}){n(r,{respectPrefix:!1,preserveSource:!0})});t.remove()}else if(t.params==="utilities"){for(let r of t.nodes)e.push(function({addUtilities:n}){n(r,{respectPrefix:!1,preserveSource:!0})});t.remove()}}),e}function GC(i,e){let t=Object.entries({...pe,...gd}).map(([o,u])=>i.tailwindConfig.corePlugins.includes(o)?u:null).filter(Boolean),r=i.tailwindConfig.plugins.map(o=>(o.__isOptionsFunction&&(o=o()),typeof o=="function"?o:o.handler)),n=WC(e),a=[pe.pseudoElementVariants,pe.pseudoClassVariants,pe.ariaVariants,pe.dataVariants],s=[pe.supportsVariants,pe.directionVariants,pe.reducedMotionVariants,pe.prefersContrastVariants,pe.darkVariants,pe.printVariant,pe.screenVariants,pe.orientationVariants];return[...t,...a,...r,...s,...n]}function HC(i,e){let t=[],r=new Map;e.variantMap=r;let n=new uo;e.offsets=n;let a=new Set,s=UC(e.tailwindConfig,e,{variantList:t,variantMap:r,offsets:n,classList:a});for(let f of i)if(Array.isArray(f))for(let p of f)p(s);else f?.(s);n.recordVariants(t,f=>r.get(f).length);for(let[f,p]of r.entries())e.variantMap.set(f,p.map((d,h)=>[n.forVariant(f,h),d]));let o=(e.tailwindConfig.safelist??[]).filter(Boolean);if(o.length>0){let f=[];for(let p of o){if(typeof p=="string"){e.changedContent.push({content:p,extension:"html"});continue}if(p instanceof RegExp){F.warn("root-regex",["Regular expressions in `safelist` work differently in Tailwind CSS v3.0.","Update your `safelist` configuration to eliminate this warning.","https://tailwindcss.com/docs/content-configuration#safelisting-classes"]);continue}f.push(p)}if(f.length>0){let p=new Map,d=e.tailwindConfig.prefix.length,h=f.some(y=>y.pattern.source.includes("!"));for(let y of a){let x=Array.isArray(y)?(()=>{let[w,b]=y,S=Object.keys(b?.values??{}).map(_=>Qr(w,_));return b?.supportsNegativeValues&&(S=[...S,...S.map(_=>"-"+_)],S=[...S,...S.map(_=>_.slice(0,d)+"-"+_.slice(d))]),b.types.some(({type:_})=>_==="color")&&(S=[...S,...S.flatMap(_=>Object.keys(e.tailwindConfig.theme.opacity).map(E=>`${_}/${E}`))]),h&&b?.respectImportant&&(S=[...S,...S.map(_=>"!"+_)]),S})():[y];for(let w of x)for(let{pattern:b,variants:k=[]}of f)if(b.lastIndex=0,p.has(b)||p.set(b,0),!!b.test(w)){p.set(b,p.get(b)+1),e.changedContent.push({content:w,extension:"html"});for(let S of k)e.changedContent.push({content:S+e.tailwindConfig.separator+w,extension:"html"})}}for(let[y,x]of p.entries())x===0&&F.warn([`The safelist pattern \`${y}\` doesn't match any Tailwind CSS classes.`,"Fix this pattern or remove it from your `safelist` configuration.","https://tailwindcss.com/docs/content-configuration#safelisting-classes"])}}let u=[].concat(e.tailwindConfig.darkMode??"media")[1]??"dark",c=[ho(e,u),ho(e,"group"),ho(e,"peer")];e.getClassOrder=function(p){let d=[...p].sort((w,b)=>w===b?0:w[w,null])),y=Sn(new Set(d),e);y=e.offsets.sort(y);let x=BigInt(c.length);for(let[,w]of y){let b=w.raws.tailwind.candidate;h.set(b,h.get(b)??x++)}return p.map(w=>{let b=h.get(w)??null,k=c.indexOf(w);return b===null&&k!==-1&&(b=BigInt(k)),[w,b]})},e.getClassList=function(p={}){let d=[];for(let h of a)if(Array.isArray(h)){let[y,x]=h,w=[],b=Object.keys(x?.modifiers??{});x?.types?.some(({type:_})=>_==="color")&&b.push(...Object.keys(e.tailwindConfig.theme.opacity??{}));let k={modifiers:b},S=p.includeMetadata&&b.length>0;for(let[_,E]of Object.entries(x?.values??{})){if(E==null)continue;let I=Qr(y,_);if(d.push(S?[I,k]:I),x?.supportsNegativeValues&&Xe(E)){let B=Qr(y,`-${_}`);w.push(S?[B,k]:B)}}d.push(...w)}else d.push(h);return d},e.getVariants=function(){let p=[];for(let[d,h]of e.variantOptions.entries())h.variantInfo!==po.Base&&p.push({name:d,isArbitrary:h.type===Symbol.for("MATCH_VARIANT"),values:Object.keys(h.values??{}),hasDash:d!=="@",selectors({modifier:y,value:x}={}){let w="__TAILWIND_PLACEHOLDER__",b=z.rule({selector:`.${w}`}),k=z.root({nodes:[b.clone()]}),S=k.toString(),_=(e.variantMap.get(d)??[]).flatMap(([$,oe])=>oe),E=[];for(let $ of _){let oe=[],ai={args:{modifier:y,value:h.values?.[x]??x},separator:e.tailwindConfig.separator,modifySelectors(Ce){return k.each(Jn=>{Jn.type==="rule"&&(Jn.selectors=Jn.selectors.map(lu=>Ce({get className(){return ao(lu)},selector:lu})))}),k},format(Ce){oe.push(Ce)},wrap(Ce){oe.push(`@${Ce.name} ${Ce.params} { & }`)},container:k},oi=$(ai);if(oe.length>0&&E.push(oe),Array.isArray(oi))for(let Ce of oi)oe=[],Ce(ai),E.push(oe)}let I=[],B=k.toString();S!==B&&(k.walkRules($=>{let oe=$.selector,ai=(0,fo.default)(oi=>{oi.walkClasses(Ce=>{Ce.value=`${d}${e.tailwindConfig.separator}${Ce.value}`})}).processSync(oe);I.push(oe.replace(ai,"&").replace(w,"&"))}),k.walkAtRules($=>{I.push(`@${$.name} (${$.params}) { & }`)}));let q=!(x in(h.values??{})),X=h[Jr]??{},ae=(()=>!(q||X.respectPrefix===!1))();E=E.map($=>$.map(oe=>({format:oe,respectPrefix:ae}))),I=I.map($=>({format:$,respectPrefix:ae}));let ge={candidate:w,context:e},je=E.map($=>wn(`.${w}`,Nt($,ge),ge).replace(`.${w}`,"&").replace("{ & }","").trim());return I.length>0&&je.push(Nt(I,ge).toString().replace(`.${w}`,"&")),je}});return p}}function Vd(i,e){!i.classCache.has(e)||(i.notClassCache.add(e),i.classCache.delete(e),i.applyClassCache.delete(e),i.candidateRuleMap.delete(e),i.candidateRuleCache.delete(e),i.stylesheetCache=null)}function YC(i,e){let t=e.raws.tailwind.candidate;if(!!t){for(let r of i.ruleCache)r[1].raws.tailwind.candidate===t&&i.ruleCache.delete(r);Vd(i,t)}}function go(i,e=[],t=z.root()){let r={disposables:[],ruleCache:new Set,candidateRuleCache:new Map,classCache:new Map,applyClassCache:new Map,notClassCache:new Set(i.blocklist??[]),postCssNodeCache:new Map,candidateRuleMap:new Map,tailwindConfig:i,changedContent:e,variantMap:new Map,stylesheetCache:null,variantOptions:new Map,markInvalidUtilityCandidate:a=>Vd(r,a),markInvalidUtilityNode:a=>YC(r,a)},n=GC(r,t);return HC(n,r),r}function Ud(i,e,t,r,n,a){let s=e.opts.from,o=r!==null;Pe.DEBUG&&console.log("Source path:",s);let u;if(o&&Lt.has(s))u=Lt.get(s);else if(ei.has(n)){let d=ei.get(n);lt.get(d).add(s),Lt.set(s,d),u=d}let c=Pd(s,i);if(u){let[d,h]=jd([...a],On(u));if(!d&&!c)return[u,!1,h]}if(Lt.has(s)){let d=Lt.get(s);if(lt.has(d)&&(lt.get(d).delete(s),lt.get(d).size===0)){lt.delete(d);for(let[h,y]of ei)y===d&&ei.delete(h);for(let h of d.disposables.splice(0))h(d)}}Pe.DEBUG&&console.log("Setting up new context...");let f=go(t,[],i);Object.assign(f,{userConfigPath:r});let[,p]=jd([...a],On(f));return ei.set(n,f),Lt.set(s,f),lt.has(f)||lt.set(f,new Set),lt.get(f).add(s),[f,!0,p]}var Fd,fo,Jr,co,po,mo,Lt,ei,lt,Xr=C(()=>{l();ze();bs();nt();Fd=K(js()),fo=K(Me());Hr();Ua();un();xt();Mt();Ga();cr();yd();ot();ot();pi();Ee();fi();Ka();Cn();Dd();Bd();De();io();Jr=Symbol(),co={AddVariant:Symbol.for("ADD_VARIANT"),MatchVariant:Symbol.for("MATCH_VARIANT")},po={Base:1<<0,Dynamic:1<<1};mo=new WeakMap;Lt=wd,ei=bd,lt=gn});function yo(i){return i.ignore?[]:i.glob?m.env.ROLLUP_WATCH==="true"?[{type:"dependency",file:i.base}]:[{type:"dir-dependency",dir:i.base,glob:i.glob}]:[{type:"dependency",file:i.base}]}var Wd=C(()=>{l()});function Gd(i,e){return{handler:i,config:e}}var Hd,Yd=C(()=>{l();Gd.withOptions=function(i,e=()=>({})){let t=function(r){return{__options:r,handler:i(r),config:e(r)}};return t.__isOptionsFunction=!0,t.__pluginFunction=i,t.__configFunction=e,t};Hd=Gd});var wo={};Ae(wo,{default:()=>QC});var QC,bo=C(()=>{l();Yd();QC=Hd});var Jd=v((ID,Qd)=>{l();var JC=(bo(),wo).default,XC={overflow:"hidden",display:"-webkit-box","-webkit-box-orient":"vertical"},KC=JC(function({matchUtilities:i,addUtilities:e,theme:t,variants:r}){let n=t("lineClamp");i({"line-clamp":a=>({...XC,"-webkit-line-clamp":`${a}`})},{values:n}),e([{".line-clamp-none":{"-webkit-line-clamp":"unset"}}],r("lineClamp"))},{theme:{lineClamp:{1:"1",2:"2",3:"3",4:"4",5:"5",6:"6"}},variants:{lineClamp:["responsive"]}});Qd.exports=KC});function vo(i){i.content.files.length===0&&F.warn("content-problems",["The `content` option in your Tailwind CSS configuration is missing or empty.","Configure your content sources or your generated CSS will be missing styles.","https://tailwindcss.com/docs/content-configuration"]);try{let e=Jd();i.plugins.includes(e)&&(F.warn("line-clamp-in-core",["As of Tailwind CSS v3.3, the `@tailwindcss/line-clamp` plugin is now included by default.","Remove it from the `plugins` array in your configuration to eliminate this warning."]),i.plugins=i.plugins.filter(t=>t!==e))}catch{}return i}var Xd=C(()=>{l();Ee()});var Kd,Zd=C(()=>{l();Kd=()=>!1});var Tn,eh=C(()=>{l();Tn={sync:i=>[].concat(i),generateTasks:i=>[{dynamic:!1,base:".",negative:[],positive:[].concat(i),patterns:[].concat(i)}],escapePath:i=>i}});var xo,th=C(()=>{l();xo=i=>i});var rh,ih=C(()=>{l();rh=()=>""});function nh(i){let e=i,t=rh(i);return t!=="."&&(e=i.substr(t.length),e.charAt(0)==="/"&&(e=e.substr(1))),e.substr(0,2)==="./"&&(e=e.substr(2)),e.charAt(0)==="/"&&(e=e.substr(1)),{base:t,glob:e}}var sh=C(()=>{l();ih()});function ah(i,e){let t=e.content.files;t=t.filter(o=>typeof o=="string"),t=t.map(xo);let r=Tn.generateTasks(t),n=[],a=[];for(let o of r)n.push(...o.positive.map(u=>oh(u,!1))),a.push(...o.negative.map(u=>oh(u,!0)));let s=[...n,...a];return s=e2(i,s),s=s.flatMap(t2),s=s.map(ZC),s}function oh(i,e){let t={original:i,base:i,ignore:e,pattern:i,glob:null};return Kd(i)&&Object.assign(t,nh(i)),t}function ZC(i){let e=xo(i.base);return e=Tn.escapePath(e),i.pattern=i.glob?`${e}/${i.glob}`:e,i.pattern=i.ignore?`!${i.pattern}`:i.pattern,i}function e2(i,e){let t=[];return i.userConfigPath&&i.tailwindConfig.content.relative&&(t=[Z.dirname(i.userConfigPath)]),e.map(r=>(r.base=Z.resolve(...t,r.base),r))}function t2(i){let e=[i];try{let t=te.realpathSync(i.base);t!==i.base&&e.push({...i,base:t})}catch{}return e}function lh(i,e,t){let r=i.tailwindConfig.content.files.filter(s=>typeof s.raw=="string").map(({raw:s,extension:o="html"})=>({content:s,extension:o})),[n,a]=r2(e,t);for(let s of n){let o=Z.extname(s).slice(1);r.push({file:s,extension:o})}return[r,a]}function r2(i,e){let t=i.map(s=>s.pattern),r=new Map,n=new Set;Pe.DEBUG&&console.time("Finding changed files");let a=Tn.sync(t,{absolute:!0});for(let s of a){let o=e.get(s)||-1/0,u=te.statSync(s).mtimeMs;u>o&&(n.add(s),r.set(s,u))}return Pe.DEBUG&&console.timeEnd("Finding changed files"),[n,r]}var uh=C(()=>{l();ze();mt();Zd();eh();th();sh();ot()});function fh(){}var ch=C(()=>{l()});function a2(i,e){for(let t of e){let r=`${i}${t}`;if(te.existsSync(r)&&te.statSync(r).isFile())return r}for(let t of e){let r=`${i}/index${t}`;if(te.existsSync(r))return r}return null}function*ph(i,e,t,r=Z.extname(i)){let n=a2(Z.resolve(e,i),i2.includes(r)?n2:s2);if(n===null||t.has(n))return;t.add(n),yield n,e=Z.dirname(n),r=Z.extname(n);let a=te.readFileSync(n,"utf-8");for(let s of[...a.matchAll(/import[\s\S]*?['"](.{3,}?)['"]/gi),...a.matchAll(/import[\s\S]*from[\s\S]*?['"](.{3,}?)['"]/gi),...a.matchAll(/require\(['"`](.+)['"`]\)/gi)])!s[1].startsWith(".")||(yield*ph(s[1],e,t,r))}function ko(i){return i===null?new Set:new Set(ph(i,Z.dirname(i),new Set))}var i2,n2,s2,dh=C(()=>{l();ze();mt();i2=[".js",".cjs",".mjs"],n2=["",".js",".cjs",".mjs",".ts",".cts",".mts",".jsx",".tsx"],s2=["",".ts",".cts",".mts",".tsx",".js",".cjs",".mjs",".jsx"]});function o2(i,e){if(So.has(i))return So.get(i);let t=ah(i,e);return So.set(i,t).get(i)}function l2(i){let e=ys(i);if(e!==null){let[r,n,a,s]=mh.get(e)||[],o=ko(e),u=!1,c=new Map;for(let d of o){let h=te.statSync(d).mtimeMs;c.set(d,h),(!s||!s.has(d)||h>s.get(d))&&(u=!0)}if(!u)return[r,e,n,a];for(let d of o)delete fu.cache[d];let f=vo(dr(fh(e))),p=ui(f);return mh.set(e,[f,p,o,c]),[f,e,p,o]}let t=dr(i?.config??i??{});return t=vo(t),[t,null,ui(t),[]]}function Co(i){return({tailwindDirectives:e,registerDependency:t})=>(r,n)=>{let[a,s,o,u]=l2(i),c=new Set(u);if(e.size>0){c.add(n.opts.from);for(let y of n.messages)y.type==="dependency"&&c.add(y.file)}let[f,,p]=Ud(r,n,a,s,o,c),d=On(f),h=o2(f,a);if(e.size>0){for(let w of h)for(let b of yo(w))t(b);let[y,x]=lh(f,h,d);for(let w of y)f.changedContent.push(w);for(let[w,b]of x.entries())p.set(w,b)}for(let y of u)t({type:"dependency",file:y});for(let[y,x]of p.entries())d.set(y,x);return f}}var hh,mh,So,gh=C(()=>{l();ze();hh=K(Xn());mu();gs();af();Xr();Wd();Xd();uh();ch();dh();mh=new hh.default({maxSize:100}),So=new WeakMap});function Ao(i){let e=new Set,t=new Set,r=new Set;if(i.walkAtRules(n=>{n.name==="apply"&&r.add(n),n.name==="import"&&(n.params==='"tailwindcss/base"'||n.params==="'tailwindcss/base'"?(n.name="tailwind",n.params="base"):n.params==='"tailwindcss/components"'||n.params==="'tailwindcss/components'"?(n.name="tailwind",n.params="components"):n.params==='"tailwindcss/utilities"'||n.params==="'tailwindcss/utilities'"?(n.name="tailwind",n.params="utilities"):(n.params==='"tailwindcss/screens"'||n.params==="'tailwindcss/screens'"||n.params==='"tailwindcss/variants"'||n.params==="'tailwindcss/variants'")&&(n.name="tailwind",n.params="variants")),n.name==="tailwind"&&(n.params==="screens"&&(n.params="variants"),e.add(n.params)),["layer","responsive","variants"].includes(n.name)&&(["responsive","variants"].includes(n.name)&&F.warn(`${n.name}-at-rule-deprecated`,[`The \`@${n.name}\` directive has been deprecated in Tailwind CSS v3.0.`,"Use `@layer utilities` or `@layer components` instead.","https://tailwindcss.com/docs/upgrade-guide#replace-variants-with-layer"]),t.add(n))}),!e.has("base")||!e.has("components")||!e.has("utilities")){for(let n of t)if(n.name==="layer"&&["base","components","utilities"].includes(n.params)){if(!e.has(n.params))throw n.error(`\`@layer ${n.params}\` is used but no matching \`@tailwind ${n.params}\` directive is present.`)}else if(n.name==="responsive"){if(!e.has("utilities"))throw n.error("`@responsive` is used but `@tailwind utilities` is missing.")}else if(n.name==="variants"&&!e.has("utilities"))throw n.error("`@variants` is used but `@tailwind utilities` is missing.")}return{tailwindDirectives:e,applyDirectives:r}}var yh=C(()=>{l();Ee()});function bt(i,e=void 0,t=void 0){return i.map(r=>{let n=r.clone(),a=r.raws.tailwind?.preserveSource!==!0||!n.source;return e!==void 0&&a&&(n.source=e,"walk"in n&&n.walk(s=>{s.source=e})),t!==void 0&&(n.raws.tailwind={...n.raws.tailwind,...t}),n})}var wh=C(()=>{l()});function Pn(i){return i=Array.isArray(i)?i:[i],i=i.map(e=>e instanceof RegExp?e.source:e),i.join("")}function xe(i){return new RegExp(Pn(i),"g")}function $t(i){return`(?:${i.map(Pn).join("|")})`}function _o(i){return`(?:${Pn(i)})?`}function vh(i){return`(?:${Pn(i)})*`}function xh(i){return i&&u2.test(i)?i.replace(bh,"\\$&"):i||""}var bh,u2,kh=C(()=>{l();bh=/[\\^$.*+?()[\]{}|]/g,u2=RegExp(bh.source)});function Sh(i){let e=Array.from(f2(i));return t=>{let r=[];for(let n of e)r=[...r,...t.match(n)??[]];return r.filter(n=>n!==void 0).map(d2)}}function*f2(i){let e=i.tailwindConfig.separator,t=J(i.tailwindConfig,"variantGrouping"),r=i.tailwindConfig.prefix!==""?_o(xe([/-?/,xh(i.tailwindConfig.prefix)])):"",n=$t([/\[[^\s:'"`]+:[^\s\[\]]+\]/,/\[[^\s:'"`]+:[^\s]+?\[[^\s]+\][^\s]+?\]/,xe([/-?(?:\w+)/,_o($t([xe([/-(?:\w+-)*\[[^\s:]+\]/,/(?![{([]])/,/(?:\/[^\s'"`\\><$]*)?/]),xe([/-(?:\w+-)*\[[^\s]+\]/,/(?![{([]])/,/(?:\/[^\s'"`\\$]*)?/]),/[-\/][^\s'"`\\$={><]*/]))])]),a=[$t([xe([/@\[[^\s"'`]+\](\/[^\s"'`]+)?/,e]),xe([/([^\s"'`\[\\]+-)?\[[^\s"'`]+\]/,e]),xe([/[^\s"'`\[\\]+/,e])]),$t([xe([/([^\s"'`\[\\]+-)?\[[^\s`]+\]/,e]),xe([/[^\s`\[\\]+/,e])])];for(let s of a)yield xe(["((?=((",s,")+))\\2)?",/!?/,r,t?$t([xe([/\(/,n,vh([/,/,n]),/\)/]),n]):n]);yield/[^<>"'`\s.(){}[\]#=%$]*[^<>"'`\s.(){}[\]#=%:$]/g}function d2(i){if(!i.includes("-["))return i;let e=0,t=[],r=i.matchAll(c2);r=Array.from(r).flatMap(n=>{let[,...a]=n;return a.map((s,o)=>Object.assign([],n,{index:n.index+o,0:s}))});for(let n of r){let a=n[0],s=t[t.length-1];if(a===s?t.pop():(a==="'"||a==='"'||a==="`")&&t.push(a),!s){if(a==="["){e++;continue}else if(a==="]"){e--;continue}if(e<0)return i.substring(0,n.index-1);if(e===0&&!p2.test(a))return i.substring(0,n.index)}}return i}var c2,p2,Ch=C(()=>{l();De();kh();c2=/([\[\]'"`])([^\[\]'"`])?/g,p2=/[^"'`\s<>\]]+/});function h2(i,e){let t=i.tailwindConfig.content.extract;return t[e]||t.DEFAULT||_h[e]||_h.DEFAULT(i)}function m2(i,e){let t=i.content.transform;return t[e]||t.DEFAULT||Eh[e]||Eh.DEFAULT}function g2(i,e,t,r){ti.has(e)||ti.set(e,new Ah.default({maxSize:25e3}));for(let n of i.split(` +`))if(n=n.trim(),!r.has(n))if(r.add(n),ti.get(e).has(n))for(let a of ti.get(e).get(n))t.add(a);else{let a=e(n).filter(o=>o!=="!*"),s=new Set(a);for(let o of s)t.add(o);ti.get(e).set(n,s)}}function y2(i,e){let t=e.offsets.sort(i),r={base:new Set,defaults:new Set,components:new Set,utilities:new Set,variants:new Set};for(let[n,a]of t)r[n.layer].add(a);return r}function Eo(i){return async e=>{let t={base:null,components:null,utilities:null,variants:null};if(e.walkAtRules(y=>{y.name==="tailwind"&&Object.keys(t).includes(y.params)&&(t[y.params]=y)}),Object.values(t).every(y=>y===null))return e;let r=new Set([...i.candidates??[],He]),n=new Set;Ye.DEBUG&&console.time("Reading changed files"),await Promise.all(i.changedContent.map(async({file:y,content:x,extension:w})=>{let b=m2(i.tailwindConfig,w),k=h2(i,w);x=y?await te.promises.readFile(y,"utf8"):x,g2(b(x),k,r,n)})),Ye.DEBUG&&console.timeEnd("Reading changed files");let a=i.classCache.size;Ye.DEBUG&&console.time("Generate rules"),Ye.DEBUG&&console.time("Sorting candidates");let s=new Set([...r].sort((y,x)=>y===x?0:y{let x=y.raws.tailwind?.parentLayer;return x==="components"?t.components!==null:x==="utilities"?t.utilities!==null:!0});t.variants?(t.variants.before(bt(d,t.variants.source,{layer:"variants"})),t.variants.remove()):d.length>0&&e.append(bt(d,e.source,{layer:"variants"}));let h=d.some(y=>y.raws.tailwind?.parentLayer==="utilities");t.utilities&&f.size===0&&!h&&F.warn("content-problems",["No utility classes were detected in your source files. If this is unexpected, double-check the `content` option in your Tailwind CSS configuration.","https://tailwindcss.com/docs/content-configuration"]),Ye.DEBUG&&(console.log("Potential classes: ",r.size),console.log("Active contexts: ",gn.size)),i.changedContent=[],e.walkAtRules("layer",y=>{Object.keys(t).includes(y.params)&&y.remove()})}}var Ah,Ye,_h,Eh,ti,Oh=C(()=>{l();ze();Ah=K(Xn());ot();Cn();Ee();wh();Ch();Ye=Pe,_h={DEFAULT:Sh},Eh={DEFAULT:i=>i,svelte:i=>i.replace(/(?:^|\s)class:/g," ")};ti=new WeakMap});function In(i){let e=new Map;z.root({nodes:[i.clone()]}).walkRules(a=>{(0,Dn.default)(s=>{s.walkClasses(o=>{let u=o.parent.toString(),c=e.get(u);c||e.set(u,c=new Set),c.add(o.value)})}).processSync(a.selector)});let r=Array.from(e.values(),a=>Array.from(a)),n=r.flat();return Object.assign(n,{groups:r})}function Oo(i){return w2.astSync(i)}function Th(i,e){let t=new Set;for(let r of i)t.add(r.split(e).pop());return Array.from(t)}function Ph(i,e){let t=i.tailwindConfig.prefix;return typeof t=="function"?t(e):t+e}function*Dh(i){for(yield i;i.parent;)yield i.parent,i=i.parent}function b2(i,e={}){let t=i.nodes;i.nodes=[];let r=i.clone(e);return i.nodes=t,r}function v2(i){for(let e of Dh(i))if(i!==e){if(e.type==="root")break;i=b2(e,{nodes:[i]})}return i}function x2(i,e){let t=new Map;return i.walkRules(r=>{for(let s of Dh(r))if(s.raws.tailwind?.layer!==void 0)return;let n=v2(r),a=e.offsets.create("user");for(let s of In(r)){let o=t.get(s)||[];t.set(s,o),o.push([{layer:"user",sort:a,important:!1},n])}}),t}function k2(i,e){for(let t of i){if(e.notClassCache.has(t)||e.applyClassCache.has(t))continue;if(e.classCache.has(t)){e.applyClassCache.set(t,e.classCache.get(t).map(([n,a])=>[n,a.clone()]));continue}let r=Array.from(xn(t,e));if(r.length===0){e.notClassCache.add(t);continue}e.applyClassCache.set(t,r)}return e.applyClassCache}function S2(i){let e=null;return{get:t=>(e=e||i(),e.get(t)),has:t=>(e=e||i(),e.has(t))}}function C2(i){return{get:e=>i.flatMap(t=>t.get(e)||[]),has:e=>i.some(t=>t.has(e))}}function Ih(i){let e=i.split(/[\s\t\n]+/g);return e[e.length-1]==="!important"?[e.slice(0,-1),!0]:[e,!1]}function qh(i,e,t){let r=new Set,n=[];if(i.walkAtRules("apply",u=>{let[c]=Ih(u.params);for(let f of c)r.add(f);n.push(u)}),n.length===0)return;let a=C2([t,k2(r,e)]);function s(u,c,f){let p=Oo(u),d=Oo(c),y=Oo(`.${ce(f)}`).nodes[0].nodes[0];return p.each(x=>{let w=new Set;d.each(b=>{let k=!1;b=b.clone(),b.walkClasses(S=>{S.value===y.value&&(k||(S.replaceWith(...x.nodes.map(_=>_.clone())),w.add(b),k=!0))})});for(let b of w){let k=[[]];for(let S of b.nodes)S.type==="combinator"?(k.push(S),k.push([])):k[k.length-1].push(S);b.nodes=[];for(let S of k)Array.isArray(S)&&S.sort((_,E)=>_.type==="tag"&&E.type==="class"?-1:_.type==="class"&&E.type==="tag"?1:_.type==="class"&&E.type==="pseudo"&&E.value.startsWith("::")?-1:_.type==="pseudo"&&_.value.startsWith("::")&&E.type==="class"?1:0),b.nodes=b.nodes.concat(S)}x.replaceWith(...w)}),p.toString()}let o=new Map;for(let u of n){let[c]=o.get(u.parent)||[[],u.source];o.set(u.parent,[c,u.source]);let[f,p]=Ih(u.params);if(u.parent.type==="atrule"){if(u.parent.name==="screen"){let d=u.parent.params;throw u.error(`@apply is not supported within nested at-rules like @screen. We suggest you write this as @apply ${f.map(h=>`${d}:${h}`).join(" ")} instead.`)}throw u.error(`@apply is not supported within nested at-rules like @${u.parent.name}. You can fix this by un-nesting @${u.parent.name}.`)}for(let d of f){if([Ph(e,"group"),Ph(e,"peer")].includes(d))throw u.error(`@apply should not be used with the '${d}' utility`);if(!a.has(d))throw u.error(`The \`${d}\` class does not exist. If \`${d}\` is a custom class, make sure it is defined within a \`@layer\` directive.`);let h=a.get(d);c.push([d,p,h])}}for(let[u,[c,f]]of o){let p=[];for(let[h,y,x]of c){let w=[h,...Th([h],e.tailwindConfig.separator)];for(let[b,k]of x){let S=In(u),_=In(k);if(_=_.groups.filter(q=>q.some(X=>w.includes(X))).flat(),_=_.concat(Th(_,e.tailwindConfig.separator)),S.some(q=>_.includes(q)))throw k.error(`You cannot \`@apply\` the \`${h}\` utility here because it creates a circular dependency.`);let I=z.root({nodes:[k.clone()]});I.walk(q=>{q.source=f}),(k.type!=="atrule"||k.type==="atrule"&&k.name!=="keyframes")&&I.walkRules(q=>{if(!In(q).some($=>$===h)){q.remove();return}let X=typeof e.tailwindConfig.important=="string"?e.tailwindConfig.important:null,ge=u.raws.tailwind!==void 0&&X&&u.selector.indexOf(X)===0?u.selector.slice(X.length):u.selector;q.selector=s(ge,q.selector,h),X&&ge!==u.selector&&(q.selector=bn(q.selector,X)),q.walkDecls($=>{$.important=b.important||y});let je=(0,Dn.default)().astSync(q.selector);je.each($=>Ft($)),q.selector=je.toString()}),!!I.nodes[0]&&p.push([b.sort,I.nodes[0]])}}let d=e.offsets.sort(p).map(h=>h[1]);u.after(d)}for(let u of n)u.parent.nodes.length>1?u.remove():u.parent.remove();qh(i,e,t)}function To(i){return e=>{let t=S2(()=>x2(e,i));qh(e,i,t)}}var Dn,w2,Rh=C(()=>{l();nt();Dn=K(Me());Cn();Mt();so();yn();w2=(0,Dn.default)()});var Mh=v((PI,qn)=>{l();(function(){"use strict";function i(r,n,a){if(!r)return null;i.caseSensitive||(r=r.toLowerCase());var s=i.threshold===null?null:i.threshold*r.length,o=i.thresholdAbsolute,u;s!==null&&o!==null?u=Math.min(s,o):s!==null?u=s:o!==null?u=o:u=null;var c,f,p,d,h,y=n.length;for(h=0;ha)return a+1;var u=[],c,f,p,d,h;for(c=0;c<=o;c++)u[c]=[c];for(f=0;f<=s;f++)u[0][f]=f;for(c=1;c<=o;c++){for(p=e,d=1,c>a&&(d=c-a),h=o+1,h>a+c&&(h=a+c),f=1;f<=s;f++)fh?u[c][f]=a+1:n.charAt(c-1)===r.charAt(f-1)?u[c][f]=u[c-1][f-1]:u[c][f]=Math.min(u[c-1][f-1]+1,Math.min(u[c][f-1]+1,u[c-1][f]+1)),u[c][f]a)return a+1}return u[o][s]}})()});var Fh=v((DI,Bh)=>{l();var Po="(".charCodeAt(0),Do=")".charCodeAt(0),Rn="'".charCodeAt(0),Io='"'.charCodeAt(0),qo="\\".charCodeAt(0),jt="/".charCodeAt(0),Ro=",".charCodeAt(0),Mo=":".charCodeAt(0),Mn="*".charCodeAt(0),A2="u".charCodeAt(0),_2="U".charCodeAt(0),E2="+".charCodeAt(0),O2=/^[a-f0-9?-]+$/i;Bh.exports=function(i){for(var e=[],t=i,r,n,a,s,o,u,c,f,p=0,d=t.charCodeAt(p),h=t.length,y=[{nodes:e}],x=0,w,b="",k="",S="";p{l();Nh.exports=function i(e,t,r){var n,a,s,o;for(n=0,a=e.length;n{l();function $h(i,e){var t=i.type,r=i.value,n,a;return e&&(a=e(i))!==void 0?a:t==="word"||t==="space"?r:t==="string"?(n=i.quote||"",n+r+(i.unclosed?"":n)):t==="comment"?"/*"+r+(i.unclosed?"":"*/"):t==="div"?(i.before||"")+r+(i.after||""):Array.isArray(i.nodes)?(n=jh(i.nodes,e),t!=="function"?n:r+"("+(i.before||"")+n+(i.after||"")+(i.unclosed?"":")")):r}function jh(i,e){var t,r;if(Array.isArray(i)){for(t="",r=i.length-1;~r;r-=1)t=$h(i[r],e)+t;return t}return $h(i,e)}zh.exports=jh});var Wh=v((RI,Uh)=>{l();var Bn="-".charCodeAt(0),Fn="+".charCodeAt(0),Bo=".".charCodeAt(0),T2="e".charCodeAt(0),P2="E".charCodeAt(0);function D2(i){var e=i.charCodeAt(0),t;if(e===Fn||e===Bn){if(t=i.charCodeAt(1),t>=48&&t<=57)return!0;var r=i.charCodeAt(2);return t===Bo&&r>=48&&r<=57}return e===Bo?(t=i.charCodeAt(1),t>=48&&t<=57):e>=48&&e<=57}Uh.exports=function(i){var e=0,t=i.length,r,n,a;if(t===0||!D2(i))return!1;for(r=i.charCodeAt(e),(r===Fn||r===Bn)&&e++;e57));)e+=1;if(r=i.charCodeAt(e),n=i.charCodeAt(e+1),r===Bo&&n>=48&&n<=57)for(e+=2;e57));)e+=1;if(r=i.charCodeAt(e),n=i.charCodeAt(e+1),a=i.charCodeAt(e+2),(r===T2||r===P2)&&(n>=48&&n<=57||(n===Fn||n===Bn)&&a>=48&&a<=57))for(e+=n===Fn||n===Bn?3:2;e57));)e+=1;return{number:i.slice(0,e),unit:i.slice(e)}}});var Qh=v((MI,Yh)=>{l();var I2=Fh(),Gh=Lh(),Hh=Vh();function ut(i){return this instanceof ut?(this.nodes=I2(i),this):new ut(i)}ut.prototype.toString=function(){return Array.isArray(this.nodes)?Hh(this.nodes):""};ut.prototype.walk=function(i,e){return Gh(this.nodes,i,e),this};ut.unit=Wh();ut.walk=Gh;ut.stringify=Hh;Yh.exports=ut});function No(i){return typeof i=="object"&&i!==null}function q2(i,e){let t=Ke(e);do if(t.pop(),(0,ri.default)(i,t)!==void 0)break;while(t.length);return t.length?t:void 0}function zt(i){return typeof i=="string"?i:i.reduce((e,t,r)=>t.includes(".")?`${e}[${t}]`:r===0?t:`${e}.${t}`,"")}function Xh(i){return i.map(e=>`'${e}'`).join(", ")}function Kh(i){return Xh(Object.keys(i))}function Lo(i,e,t,r={}){let n=Array.isArray(e)?zt(e):e.replace(/^['"]+|['"]+$/g,""),a=Array.isArray(e)?e:Ke(n),s=(0,ri.default)(i.theme,a,t);if(s===void 0){let u=`'${n}' does not exist in your theme config.`,c=a.slice(0,-1),f=(0,ri.default)(i.theme,c);if(No(f)){let p=Object.keys(f).filter(h=>Lo(i,[...c,h]).isValid),d=(0,Jh.default)(a[a.length-1],p);d?u+=` Did you mean '${zt([...c,d])}'?`:p.length>0&&(u+=` '${zt(c)}' has the following valid keys: ${Xh(p)}`)}else{let p=q2(i.theme,n);if(p){let d=(0,ri.default)(i.theme,p);No(d)?u+=` '${zt(p)}' has the following keys: ${Kh(d)}`:u+=` '${zt(p)}' is not an object.`}else u+=` Your theme has the following top-level keys: ${Kh(i.theme)}`}return{isValid:!1,error:u}}if(!(typeof s=="string"||typeof s=="number"||typeof s=="function"||s instanceof String||s instanceof Number||Array.isArray(s))){let u=`'${n}' was found but does not resolve to a string.`;if(No(s)){let c=Object.keys(s).filter(f=>Lo(i,[...a,f]).isValid);c.length&&(u+=` Did you mean something like '${zt([...a,c[0]])}'?`)}return{isValid:!1,error:u}}let[o]=a;return{isValid:!0,value:Ge(o)(s,r)}}function R2(i,e,t){e=e.map(n=>Zh(i,n,t));let r=[""];for(let n of e)n.type==="div"&&n.value===","?r.push(""):r[r.length-1]+=Fo.default.stringify(n);return r}function Zh(i,e,t){if(e.type==="function"&&t[e.value]!==void 0){let r=R2(i,e.nodes,t);e.type="word",e.value=t[e.value](i,...r)}return e}function M2(i,e,t){return Object.keys(t).some(n=>e.includes(`${n}(`))?(0,Fo.default)(e).walk(n=>{Zh(i,n,t)}).toString():e}function*F2(i){i=i.replace(/^['"]+|['"]+$/g,"");let e=i.match(/^([^\s]+)(?![^\[]*\])(?:\s*\/\s*([^\/\s]+))$/),t;yield[i,void 0],e&&(i=e[1],t=e[2],yield[i,t])}function N2(i,e,t){let r=Array.from(F2(e)).map(([n,a])=>Object.assign(Lo(i,n,t,{opacityValue:a}),{resolvedPath:n,alpha:a}));return r.find(n=>n.isValid)??r[0]}function em(i){let e=i.tailwindConfig,t={theme:(r,n,...a)=>{let{isValid:s,value:o,error:u,alpha:c}=N2(e,n,a.length?a:void 0);if(!s){let d=r.parent,h=d?.raws.tailwind?.candidate;if(d&&h!==void 0){i.markInvalidUtilityNode(d),d.remove(),F.warn("invalid-theme-key-in-class",[`The utility \`${h}\` contains an invalid theme value and was not generated.`]);return}throw r.error(u)}let f=kt(o),p=f!==void 0&&typeof f=="function";return(c!==void 0||p)&&(c===void 0&&(c=1),o=Ie(f,c,f)),o},screen:(r,n)=>{n=n.replace(/^['"]+/g,"").replace(/['"]+$/g,"");let s=at(e.theme.screens).find(({name:o})=>o===n);if(!s)throw r.error(`The '${n}' screen does not exist in your theme.`);return st(s)}};return r=>{r.walk(n=>{let a=B2[n.type];a!==void 0&&(n[a]=M2(n,n[a],t))})}}var ri,Jh,Fo,B2,tm=C(()=>{l();ri=K(js()),Jh=K(Mh());Hr();Fo=K(Qh());hn();cn();pi();ar();cr();Ee();B2={atrule:"params",decl:"value"}});function rm({tailwindConfig:{theme:i}}){return function(e){e.walkAtRules("screen",t=>{let r=t.params,a=at(i.screens).find(({name:s})=>s===r);if(!a)throw t.error(`No \`${r}\` screen found.`);t.name="media",t.params=st(a)})}}var im=C(()=>{l();hn();cn()});function L2(i){let e=i.filter(o=>o.type!=="pseudo"||o.nodes.length>0?!0:o.value.startsWith("::")||[":before",":after",":first-line",":first-letter"].includes(o.value)).reverse(),t=new Set(["tag","class","id","attribute"]),r=e.findIndex(o=>t.has(o.type));if(r===-1)return e.reverse().join("").trim();let n=e[r],a=nm[n.type]?nm[n.type](n):n;e=e.slice(0,r);let s=e.findIndex(o=>o.type==="combinator"&&o.value===">");return s!==-1&&(e.splice(0,s),e.unshift(Nn.default.universal())),[a,...e.reverse()].join("").trim()}function j2(i){return $o.has(i)||$o.set(i,$2.transformSync(i)),$o.get(i)}function jo({tailwindConfig:i}){return e=>{let t=new Map,r=new Set;if(e.walkAtRules("defaults",n=>{if(n.nodes&&n.nodes.length>0){r.add(n);return}let a=n.params;t.has(a)||t.set(a,new Set),t.get(a).add(n.parent),n.remove()}),J(i,"optimizeUniversalDefaults"))for(let n of r){let a=new Map,s=t.get(n.params)??[];for(let o of s)for(let u of j2(o.selector)){let c=u.includes(":-")||u.includes("::-")?u:"__DEFAULT__",f=a.get(c)??new Set;a.set(c,f),f.add(u)}if(J(i,"optimizeUniversalDefaults")){if(a.size===0){n.remove();continue}for(let[,o]of a){let u=z.rule({source:n.source});u.selectors=[...o],u.append(n.nodes.map(c=>c.clone())),n.before(u)}}n.remove()}else if(r.size){let n=z.rule({selectors:["*","::before","::after"]});for(let s of r)n.append(s.nodes),n.parent||s.before(n),n.source||(n.source=s.source),s.remove();let a=n.clone({selectors:["::backdrop"]});n.after(a)}}}var Nn,nm,$2,$o,sm=C(()=>{l();nt();Nn=K(Me());De();nm={id(i){return Nn.default.attribute({attribute:"id",operator:"=",value:i.value,quoteMark:'"'})}};$2=(0,Nn.default)(i=>i.map(e=>{let t=e.split(r=>r.type==="combinator"&&r.value===" ").pop();return L2(t)})),$o=new Map});function zo(){function i(e){let t=null;e.each(r=>{if(!z2.has(r.type)){t=null;return}if(t===null){t=r;return}let n=am[r.type];r.type==="atrule"&&r.name==="font-face"?t=r:n.every(a=>(r[a]??"").replace(/\s+/g," ")===(t[a]??"").replace(/\s+/g," "))?(r.nodes&&t.append(r.nodes),r.remove()):t=r}),e.each(r=>{r.type==="atrule"&&i(r)})}return e=>{i(e)}}var am,z2,om=C(()=>{l();am={atrule:["name","params"],rule:["selector"]},z2=new Set(Object.keys(am))});function Vo(){return i=>{i.walkRules(e=>{let t=new Map,r=new Set([]),n=new Map;e.walkDecls(a=>{if(a.parent===e){if(t.has(a.prop)){if(t.get(a.prop).value===a.value){r.add(t.get(a.prop)),t.set(a.prop,a);return}n.has(a.prop)||n.set(a.prop,new Set),n.get(a.prop).add(t.get(a.prop)),n.get(a.prop).add(a)}t.set(a.prop,a)}});for(let a of r)a.remove();for(let a of n.values()){let s=new Map;for(let o of a){let u=U2(o.value);u!==null&&(s.has(u)||s.set(u,new Set),s.get(u).add(o))}for(let o of s.values()){let u=Array.from(o).slice(0,-1);for(let c of u)c.remove()}}})}}function U2(i){let e=/^-?\d*.?\d+([\w%]+)?$/g.exec(i);return e?e[1]??V2:null}var V2,lm=C(()=>{l();V2=Symbol("unitless-number")});function W2(i){if(!i.walkAtRules)return;let e=new Set;if(i.walkAtRules("apply",t=>{e.add(t.parent)}),e.size!==0)for(let t of e){let r=[],n=[];for(let a of t.nodes)a.type==="atrule"&&a.name==="apply"?(n.length>0&&(r.push(n),n=[]),r.push([a])):n.push(a);if(n.length>0&&r.push(n),r.length!==1){for(let a of[...r].reverse()){let s=t.clone({nodes:[]});s.append(a),t.after(s)}t.remove()}}}function Ln(){return i=>{W2(i)}}var um=C(()=>{l()});function G2(i){return i.type==="root"}function H2(i){return i.type==="atrule"&&i.name==="layer"}function fm(i){return(e,t)=>{let r=!1;e.walkAtRules("tailwind",n=>{if(r)return!1;if(n.parent&&!(G2(n.parent)||H2(n.parent)))return r=!0,n.warn(t,["Nested @tailwind rules were detected, but are not supported.","Consider using a prefix to scope Tailwind's classes: https://tailwindcss.com/docs/configuration#prefix","Alternatively, use the important selector strategy: https://tailwindcss.com/docs/configuration#selector-strategy"].join(` +`)),!1}),e.walkRules(n=>{if(r)return!1;n.walkRules(a=>(r=!0,a.warn(t,["Nested CSS was detected, but CSS nesting has not been configured correctly.","Please enable a CSS nesting plugin *before* Tailwind in your configuration.","See how here: https://tailwindcss.com/docs/using-with-preprocessors#nesting"].join(` +`)),!1))})}}var cm=C(()=>{l()});function $n(i){return async function(e,t){let{tailwindDirectives:r,applyDirectives:n}=Ao(e);fm()(e,t),Ln()(e,t);let a=i({tailwindDirectives:r,applyDirectives:n,registerDependency(s){t.messages.push({plugin:"tailwindcss",parent:t.opts.from,...s})},createContext(s,o){return go(s,o,e)}})(e,t);if(a.tailwindConfig.separator==="-")throw new Error("The '-' character cannot be used as a custom separator in JIT mode due to parsing ambiguity. Please use another character like '_' instead.");_u(a.tailwindConfig),await Eo(a)(e,t),Ln()(e,t),To(a)(e,t),em(a)(e,t),rm(a)(e,t),jo(a)(e,t),zo(a)(e,t),Vo(a)(e,t)}}var pm=C(()=>{l();yh();Oh();Rh();tm();im();sm();om();lm();um();cm();Xr();De()});function dm(i,e){let t=null,r=null;return i.walkAtRules("config",n=>{if(r=n.source?.input.file??e.opts.from??null,r===null)throw n.error("The `@config` directive cannot be used without setting `from` in your PostCSS config.");if(t)throw n.error("Only one `@config` directive is allowed per file.");let a=n.params.match(/(['"])(.*?)\1/);if(!a)throw n.error("A path is required when using the `@config` directive.");let s=a[2];if(Z.isAbsolute(s))throw n.error("The `@config` directive cannot be used with an absolute path.");if(t=Z.resolve(Z.dirname(r),s),!te.existsSync(t))throw n.error(`The config file at "${s}" does not exist. Make sure the path is correct and the file exists.`);n.remove()}),t||null}var hm=C(()=>{l();ze();mt()});var mm=v((v4,Uo)=>{l();gh();pm();ot();hm();Uo.exports=function(e){return{postcssPlugin:"tailwindcss",plugins:[Pe.DEBUG&&function(t){return console.log(` +`),console.time("JIT TOTAL"),t},async function(t,r){e=dm(t,r)??e;let n=Co(e);if(t.type==="document"){let a=t.nodes.filter(s=>s.type==="root");for(let s of a)s.type==="root"&&await $n(n)(s,r);return}await $n(n)(t,r)},!1,Pe.DEBUG&&function(t){return console.timeEnd("JIT TOTAL"),console.log(` +`),t}].filter(Boolean)}};Uo.exports.postcss=!0});var ym=v((x4,gm)=>{l();gm.exports=mm()});var Wo=v((k4,wm)=>{l();wm.exports=()=>["and_chr 114","and_uc 15.5","chrome 114","chrome 113","chrome 109","edge 114","firefox 114","ios_saf 16.5","ios_saf 16.4","ios_saf 16.3","ios_saf 16.1","opera 99","safari 16.5","samsung 21"]});var jn={};Ae(jn,{agents:()=>Y2,feature:()=>Q2});function Q2(){return{status:"cr",title:"CSS Feature Queries",stats:{ie:{"6":"n","7":"n","8":"n","9":"n","10":"n","11":"n","5.5":"n"},edge:{"12":"y","13":"y","14":"y","15":"y","16":"y","17":"y","18":"y","79":"y","80":"y","81":"y","83":"y","84":"y","85":"y","86":"y","87":"y","88":"y","89":"y","90":"y","91":"y","92":"y","93":"y","94":"y","95":"y","96":"y","97":"y","98":"y","99":"y","100":"y","101":"y","102":"y","103":"y","104":"y","105":"y","106":"y","107":"y","108":"y","109":"y","110":"y","111":"y","112":"y","113":"y","114":"y"},firefox:{"2":"n","3":"n","4":"n","5":"n","6":"n","7":"n","8":"n","9":"n","10":"n","11":"n","12":"n","13":"n","14":"n","15":"n","16":"n","17":"n","18":"n","19":"n","20":"n","21":"n","22":"y","23":"y","24":"y","25":"y","26":"y","27":"y","28":"y","29":"y","30":"y","31":"y","32":"y","33":"y","34":"y","35":"y","36":"y","37":"y","38":"y","39":"y","40":"y","41":"y","42":"y","43":"y","44":"y","45":"y","46":"y","47":"y","48":"y","49":"y","50":"y","51":"y","52":"y","53":"y","54":"y","55":"y","56":"y","57":"y","58":"y","59":"y","60":"y","61":"y","62":"y","63":"y","64":"y","65":"y","66":"y","67":"y","68":"y","69":"y","70":"y","71":"y","72":"y","73":"y","74":"y","75":"y","76":"y","77":"y","78":"y","79":"y","80":"y","81":"y","82":"y","83":"y","84":"y","85":"y","86":"y","87":"y","88":"y","89":"y","90":"y","91":"y","92":"y","93":"y","94":"y","95":"y","96":"y","97":"y","98":"y","99":"y","100":"y","101":"y","102":"y","103":"y","104":"y","105":"y","106":"y","107":"y","108":"y","109":"y","110":"y","111":"y","112":"y","113":"y","114":"y","115":"y","116":"y","117":"y","3.5":"n","3.6":"n"},chrome:{"4":"n","5":"n","6":"n","7":"n","8":"n","9":"n","10":"n","11":"n","12":"n","13":"n","14":"n","15":"n","16":"n","17":"n","18":"n","19":"n","20":"n","21":"n","22":"n","23":"n","24":"n","25":"n","26":"n","27":"n","28":"y","29":"y","30":"y","31":"y","32":"y","33":"y","34":"y","35":"y","36":"y","37":"y","38":"y","39":"y","40":"y","41":"y","42":"y","43":"y","44":"y","45":"y","46":"y","47":"y","48":"y","49":"y","50":"y","51":"y","52":"y","53":"y","54":"y","55":"y","56":"y","57":"y","58":"y","59":"y","60":"y","61":"y","62":"y","63":"y","64":"y","65":"y","66":"y","67":"y","68":"y","69":"y","70":"y","71":"y","72":"y","73":"y","74":"y","75":"y","76":"y","77":"y","78":"y","79":"y","80":"y","81":"y","83":"y","84":"y","85":"y","86":"y","87":"y","88":"y","89":"y","90":"y","91":"y","92":"y","93":"y","94":"y","95":"y","96":"y","97":"y","98":"y","99":"y","100":"y","101":"y","102":"y","103":"y","104":"y","105":"y","106":"y","107":"y","108":"y","109":"y","110":"y","111":"y","112":"y","113":"y","114":"y","115":"y","116":"y","117":"y"},safari:{"4":"n","5":"n","6":"n","7":"n","8":"n","9":"y","10":"y","11":"y","12":"y","13":"y","14":"y","15":"y","17":"y","9.1":"y","10.1":"y","11.1":"y","12.1":"y","13.1":"y","14.1":"y","15.1":"y","15.2-15.3":"y","15.4":"y","15.5":"y","15.6":"y","16.0":"y","16.1":"y","16.2":"y","16.3":"y","16.4":"y","16.5":"y","16.6":"y",TP:"y","3.1":"n","3.2":"n","5.1":"n","6.1":"n","7.1":"n"},opera:{"9":"n","11":"n","12":"n","15":"y","16":"y","17":"y","18":"y","19":"y","20":"y","21":"y","22":"y","23":"y","24":"y","25":"y","26":"y","27":"y","28":"y","29":"y","30":"y","31":"y","32":"y","33":"y","34":"y","35":"y","36":"y","37":"y","38":"y","39":"y","40":"y","41":"y","42":"y","43":"y","44":"y","45":"y","46":"y","47":"y","48":"y","49":"y","50":"y","51":"y","52":"y","53":"y","54":"y","55":"y","56":"y","57":"y","58":"y","60":"y","62":"y","63":"y","64":"y","65":"y","66":"y","67":"y","68":"y","69":"y","70":"y","71":"y","72":"y","73":"y","74":"y","75":"y","76":"y","77":"y","78":"y","79":"y","80":"y","81":"y","82":"y","83":"y","84":"y","85":"y","86":"y","87":"y","88":"y","89":"y","90":"y","91":"y","92":"y","93":"y","94":"y","95":"y","96":"y","97":"y","98":"y","99":"y","100":"y","12.1":"y","9.5-9.6":"n","10.0-10.1":"n","10.5":"n","10.6":"n","11.1":"n","11.5":"n","11.6":"n"},ios_saf:{"8":"n","17":"y","9.0-9.2":"y","9.3":"y","10.0-10.2":"y","10.3":"y","11.0-11.2":"y","11.3-11.4":"y","12.0-12.1":"y","12.2-12.5":"y","13.0-13.1":"y","13.2":"y","13.3":"y","13.4-13.7":"y","14.0-14.4":"y","14.5-14.8":"y","15.0-15.1":"y","15.2-15.3":"y","15.4":"y","15.5":"y","15.6":"y","16.0":"y","16.1":"y","16.2":"y","16.3":"y","16.4":"y","16.5":"y","16.6":"y","3.2":"n","4.0-4.1":"n","4.2-4.3":"n","5.0-5.1":"n","6.0-6.1":"n","7.0-7.1":"n","8.1-8.4":"n"},op_mini:{all:"y"},android:{"3":"n","4":"n","114":"y","4.4":"y","4.4.3-4.4.4":"y","2.1":"n","2.2":"n","2.3":"n","4.1":"n","4.2-4.3":"n"},bb:{"7":"n","10":"n"},op_mob:{"10":"n","11":"n","12":"n","73":"y","11.1":"n","11.5":"n","12.1":"n"},and_chr:{"114":"y"},and_ff:{"115":"y"},ie_mob:{"10":"n","11":"n"},and_uc:{"15.5":"y"},samsung:{"4":"y","20":"y","21":"y","5.0-5.4":"y","6.2-6.4":"y","7.2-7.4":"y","8.2":"y","9.2":"y","10.1":"y","11.1-11.2":"y","12.0":"y","13.0":"y","14.0":"y","15.0":"y","16.0":"y","17.0":"y","18.0":"y","19.0":"y"},and_qq:{"13.1":"y"},baidu:{"13.18":"y"},kaios:{"2.5":"y","3.0-3.1":"y"}}}}var Y2,zn=C(()=>{l();Y2={ie:{prefix:"ms"},edge:{prefix:"webkit",prefix_exceptions:{"12":"ms","13":"ms","14":"ms","15":"ms","16":"ms","17":"ms","18":"ms"}},firefox:{prefix:"moz"},chrome:{prefix:"webkit"},safari:{prefix:"webkit"},opera:{prefix:"webkit",prefix_exceptions:{"9":"o","11":"o","12":"o","9.5-9.6":"o","10.0-10.1":"o","10.5":"o","10.6":"o","11.1":"o","11.5":"o","11.6":"o","12.1":"o"}},ios_saf:{prefix:"webkit"},op_mini:{prefix:"o"},android:{prefix:"webkit"},bb:{prefix:"webkit"},op_mob:{prefix:"o",prefix_exceptions:{"73":"webkit"}},and_chr:{prefix:"webkit"},and_ff:{prefix:"moz"},ie_mob:{prefix:"ms"},and_uc:{prefix:"webkit",prefix_exceptions:{"15.5":"webkit"}},samsung:{prefix:"webkit"},and_qq:{prefix:"webkit"},baidu:{prefix:"webkit"},kaios:{prefix:"moz"}}});var bm=v(()=>{l()});var ue=v((A4,ft)=>{l();var{list:Go}=me();ft.exports.error=function(i){let e=new Error(i);throw e.autoprefixer=!0,e};ft.exports.uniq=function(i){return[...new Set(i)]};ft.exports.removeNote=function(i){return i.includes(" ")?i.split(" ")[0]:i};ft.exports.escapeRegexp=function(i){return i.replace(/[$()*+-.?[\\\]^{|}]/g,"\\$&")};ft.exports.regexp=function(i,e=!0){return e&&(i=this.escapeRegexp(i)),new RegExp(`(^|[\\s,(])(${i}($|[\\s(,]))`,"gi")};ft.exports.editList=function(i,e){let t=Go.comma(i),r=e(t,[]);if(t===r)return i;let n=i.match(/,\s*/);return n=n?n[0]:", ",r.join(n)};ft.exports.splitSelector=function(i){return Go.comma(i).map(e=>Go.space(e).map(t=>t.split(/(?=\.|#)/g)))}});var ct=v((_4,km)=>{l();var J2=Wo(),vm=(zn(),jn).agents,X2=ue(),xm=class{static prefixes(){if(this.prefixesCache)return this.prefixesCache;this.prefixesCache=[];for(let e in vm)this.prefixesCache.push(`-${vm[e].prefix}-`);return this.prefixesCache=X2.uniq(this.prefixesCache).sort((e,t)=>t.length-e.length),this.prefixesCache}static withPrefix(e){return this.prefixesRegexp||(this.prefixesRegexp=new RegExp(this.prefixes().join("|"))),this.prefixesRegexp.test(e)}constructor(e,t,r,n){this.data=e,this.options=r||{},this.browserslistOpts=n||{},this.selected=this.parse(t)}parse(e){let t={};for(let r in this.browserslistOpts)t[r]=this.browserslistOpts[r];return t.path=this.options.from,J2(e,t)}prefix(e){let[t,r]=e.split(" "),n=this.data[t],a=n.prefix_exceptions&&n.prefix_exceptions[r];return a||(a=n.prefix),`-${a}-`}isSelected(e){return this.selected.includes(e)}};km.exports=xm});var ii=v((E4,Sm)=>{l();Sm.exports={prefix(i){let e=i.match(/^(-\w+-)/);return e?e[0]:""},unprefixed(i){return i.replace(/^-\w+-/,"")}}});var Vt=v((O4,Am)=>{l();var K2=ct(),Cm=ii(),Z2=ue();function Ho(i,e){let t=new i.constructor;for(let r of Object.keys(i||{})){let n=i[r];r==="parent"&&typeof n=="object"?e&&(t[r]=e):r==="source"||r===null?t[r]=n:Array.isArray(n)?t[r]=n.map(a=>Ho(a,t)):r!=="_autoprefixerPrefix"&&r!=="_autoprefixerValues"&&r!=="proxyCache"&&(typeof n=="object"&&n!==null&&(n=Ho(n,t)),t[r]=n)}return t}var Vn=class{static hack(e){return this.hacks||(this.hacks={}),e.names.map(t=>(this.hacks[t]=e,this.hacks[t]))}static load(e,t,r){let n=this.hacks&&this.hacks[e];return n?new n(e,t,r):new this(e,t,r)}static clone(e,t){let r=Ho(e);for(let n in t)r[n]=t[n];return r}constructor(e,t,r){this.prefixes=t,this.name=e,this.all=r}parentPrefix(e){let t;return typeof e._autoprefixerPrefix!="undefined"?t=e._autoprefixerPrefix:e.type==="decl"&&e.prop[0]==="-"?t=Cm.prefix(e.prop):e.type==="root"?t=!1:e.type==="rule"&&e.selector.includes(":-")&&/:(-\w+-)/.test(e.selector)?t=e.selector.match(/:(-\w+-)/)[1]:e.type==="atrule"&&e.name[0]==="-"?t=Cm.prefix(e.name):t=this.parentPrefix(e.parent),K2.prefixes().includes(t)||(t=!1),e._autoprefixerPrefix=t,e._autoprefixerPrefix}process(e,t){if(!this.check(e))return;let r=this.parentPrefix(e),n=this.prefixes.filter(s=>!r||r===Z2.removeNote(s)),a=[];for(let s of n)this.add(e,s,a.concat([s]),t)&&a.push(s);return a}clone(e,t){return Vn.clone(e,t)}};Am.exports=Vn});var R=v((T4,Om)=>{l();var eA=Vt(),tA=ct(),_m=ue(),Em=class extends eA{check(){return!0}prefixed(e,t){return t+e}normalize(e){return e}otherPrefixes(e,t){for(let r of tA.prefixes())if(r!==t&&e.includes(r))return!0;return!1}set(e,t){return e.prop=this.prefixed(e.prop,t),e}needCascade(e){return e._autoprefixerCascade||(e._autoprefixerCascade=this.all.options.cascade!==!1&&e.raw("before").includes(` +`)),e._autoprefixerCascade}maxPrefixed(e,t){if(t._autoprefixerMax)return t._autoprefixerMax;let r=0;for(let n of e)n=_m.removeNote(n),n.length>r&&(r=n.length);return t._autoprefixerMax=r,t._autoprefixerMax}calcBefore(e,t,r=""){let a=this.maxPrefixed(e,t)-_m.removeNote(r).length,s=t.raw("before");return a>0&&(s+=Array(a).fill(" ").join("")),s}restoreBefore(e){let t=e.raw("before").split(` +`),r=t[t.length-1];this.all.group(e).up(n=>{let a=n.raw("before").split(` +`),s=a[a.length-1];s.lengths.prop===n.prop&&s.value===n.value)))return this.needCascade(e)&&(n.raws.before=this.calcBefore(r,e,t)),e.parent.insertBefore(e,n)}isAlready(e,t){let r=this.all.group(e).up(n=>n.prop===t);return r||(r=this.all.group(e).down(n=>n.prop===t)),r}add(e,t,r,n){let a=this.prefixed(e.prop,t);if(!(this.isAlready(e,a)||this.otherPrefixes(e.value,t)))return this.insert(e,t,r,n)}process(e,t){if(!this.needCascade(e)){super.process(e,t);return}let r=super.process(e,t);!r||!r.length||(this.restoreBefore(e),e.raws.before=this.calcBefore(r,e))}old(e,t){return[this.prefixed(e,t)]}};Om.exports=Em});var Pm=v((P4,Tm)=>{l();Tm.exports=function i(e){return{mul:t=>new i(e*t),div:t=>new i(e/t),simplify:()=>new i(e),toString:()=>e.toString()}}});var qm=v((D4,Im)=>{l();var rA=Pm(),iA=Vt(),Yo=ue(),nA=/(min|max)-resolution\s*:\s*\d*\.?\d+(dppx|dpcm|dpi|x)/gi,sA=/(min|max)-resolution(\s*:\s*)(\d*\.?\d+)(dppx|dpcm|dpi|x)/i,Dm=class extends iA{prefixName(e,t){return e==="-moz-"?t+"--moz-device-pixel-ratio":e+t+"-device-pixel-ratio"}prefixQuery(e,t,r,n,a){return n=new rA(n),a==="dpi"?n=n.div(96):a==="dpcm"&&(n=n.mul(2.54).div(96)),n=n.simplify(),e==="-o-"&&(n=n.n+"/"+n.d),this.prefixName(e,t)+r+n}clean(e){if(!this.bad){this.bad=[];for(let t of this.prefixes)this.bad.push(this.prefixName(t,"min")),this.bad.push(this.prefixName(t,"max"))}e.params=Yo.editList(e.params,t=>t.filter(r=>this.bad.every(n=>!r.includes(n))))}process(e){let t=this.parentPrefix(e),r=t?[t]:this.prefixes;e.params=Yo.editList(e.params,(n,a)=>{for(let s of n){if(!s.includes("min-resolution")&&!s.includes("max-resolution")){a.push(s);continue}for(let o of r){let u=s.replace(nA,c=>{let f=c.match(sA);return this.prefixQuery(o,f[1],f[2],f[3],f[4])});a.push(u)}a.push(s)}return Yo.uniq(a)})}};Im.exports=Dm});var Mm=v((I4,Rm)=>{l();var Qo="(".charCodeAt(0),Jo=")".charCodeAt(0),Un="'".charCodeAt(0),Xo='"'.charCodeAt(0),Ko="\\".charCodeAt(0),Ut="/".charCodeAt(0),Zo=",".charCodeAt(0),el=":".charCodeAt(0),Wn="*".charCodeAt(0),aA="u".charCodeAt(0),oA="U".charCodeAt(0),lA="+".charCodeAt(0),uA=/^[a-f0-9?-]+$/i;Rm.exports=function(i){for(var e=[],t=i,r,n,a,s,o,u,c,f,p=0,d=t.charCodeAt(p),h=t.length,y=[{nodes:e}],x=0,w,b="",k="",S="";p{l();Bm.exports=function i(e,t,r){var n,a,s,o;for(n=0,a=e.length;n{l();function Nm(i,e){var t=i.type,r=i.value,n,a;return e&&(a=e(i))!==void 0?a:t==="word"||t==="space"?r:t==="string"?(n=i.quote||"",n+r+(i.unclosed?"":n)):t==="comment"?"/*"+r+(i.unclosed?"":"*/"):t==="div"?(i.before||"")+r+(i.after||""):Array.isArray(i.nodes)?(n=Lm(i.nodes,e),t!=="function"?n:r+"("+(i.before||"")+n+(i.after||"")+(i.unclosed?"":")")):r}function Lm(i,e){var t,r;if(Array.isArray(i)){for(t="",r=i.length-1;~r;r-=1)t=Nm(i[r],e)+t;return t}return Nm(i,e)}$m.exports=Lm});var Vm=v((M4,zm)=>{l();var Gn="-".charCodeAt(0),Hn="+".charCodeAt(0),tl=".".charCodeAt(0),fA="e".charCodeAt(0),cA="E".charCodeAt(0);function pA(i){var e=i.charCodeAt(0),t;if(e===Hn||e===Gn){if(t=i.charCodeAt(1),t>=48&&t<=57)return!0;var r=i.charCodeAt(2);return t===tl&&r>=48&&r<=57}return e===tl?(t=i.charCodeAt(1),t>=48&&t<=57):e>=48&&e<=57}zm.exports=function(i){var e=0,t=i.length,r,n,a;if(t===0||!pA(i))return!1;for(r=i.charCodeAt(e),(r===Hn||r===Gn)&&e++;e57));)e+=1;if(r=i.charCodeAt(e),n=i.charCodeAt(e+1),r===tl&&n>=48&&n<=57)for(e+=2;e57));)e+=1;if(r=i.charCodeAt(e),n=i.charCodeAt(e+1),a=i.charCodeAt(e+2),(r===fA||r===cA)&&(n>=48&&n<=57||(n===Hn||n===Gn)&&a>=48&&a<=57))for(e+=n===Hn||n===Gn?3:2;e57));)e+=1;return{number:i.slice(0,e),unit:i.slice(e)}}});var Yn=v((B4,Gm)=>{l();var dA=Mm(),Um=Fm(),Wm=jm();function pt(i){return this instanceof pt?(this.nodes=dA(i),this):new pt(i)}pt.prototype.toString=function(){return Array.isArray(this.nodes)?Wm(this.nodes):""};pt.prototype.walk=function(i,e){return Um(this.nodes,i,e),this};pt.unit=Vm();pt.walk=Um;pt.stringify=Wm;Gm.exports=pt});var Xm=v((F4,Jm)=>{l();var{list:hA}=me(),Hm=Yn(),mA=ct(),Ym=ii(),Qm=class{constructor(e){this.props=["transition","transition-property"],this.prefixes=e}add(e,t){let r,n,a=this.prefixes.add[e.prop],s=this.ruleVendorPrefixes(e),o=s||a&&a.prefixes||[],u=this.parse(e.value),c=u.map(h=>this.findProp(h)),f=[];if(c.some(h=>h[0]==="-"))return;for(let h of u){if(n=this.findProp(h),n[0]==="-")continue;let y=this.prefixes.add[n];if(!(!y||!y.prefixes))for(r of y.prefixes){if(s&&!s.some(w=>r.includes(w)))continue;let x=this.prefixes.prefixed(n,r);x!=="-ms-transform"&&!c.includes(x)&&(this.disabled(n,r)||f.push(this.clone(n,x,h)))}}u=u.concat(f);let p=this.stringify(u),d=this.stringify(this.cleanFromUnprefixed(u,"-webkit-"));if(o.includes("-webkit-")&&this.cloneBefore(e,`-webkit-${e.prop}`,d),this.cloneBefore(e,e.prop,d),o.includes("-o-")){let h=this.stringify(this.cleanFromUnprefixed(u,"-o-"));this.cloneBefore(e,`-o-${e.prop}`,h)}for(r of o)if(r!=="-webkit-"&&r!=="-o-"){let h=this.stringify(this.cleanOtherPrefixes(u,r));this.cloneBefore(e,r+e.prop,h)}p!==e.value&&!this.already(e,e.prop,p)&&(this.checkForWarning(t,e),e.cloneBefore(),e.value=p)}findProp(e){let t=e[0].value;if(/^\d/.test(t)){for(let[r,n]of e.entries())if(r!==0&&n.type==="word")return n.value}return t}already(e,t,r){return e.parent.some(n=>n.prop===t&&n.value===r)}cloneBefore(e,t,r){this.already(e,t,r)||e.cloneBefore({prop:t,value:r})}checkForWarning(e,t){if(t.prop!=="transition-property")return;let r=!1,n=!1;t.parent.each(a=>{if(a.type!=="decl"||a.prop.indexOf("transition-")!==0)return;let s=hA.comma(a.value);if(a.prop==="transition-property"){s.forEach(o=>{let u=this.prefixes.add[o];u&&u.prefixes&&u.prefixes.length>0&&(r=!0)});return}return n=n||s.length>1,!1}),r&&n&&t.warn(e,"Replace transition-property to transition, because Autoprefixer could not support any cases of transition-property and other transition-*")}remove(e){let t=this.parse(e.value);t=t.filter(s=>{let o=this.prefixes.remove[this.findProp(s)];return!o||!o.remove});let r=this.stringify(t);if(e.value===r)return;if(t.length===0){e.remove();return}let n=e.parent.some(s=>s.prop===e.prop&&s.value===r),a=e.parent.some(s=>s!==e&&s.prop===e.prop&&s.value.length>r.length);if(n||a){e.remove();return}e.value=r}parse(e){let t=Hm(e),r=[],n=[];for(let a of t.nodes)n.push(a),a.type==="div"&&a.value===","&&(r.push(n),n=[]);return r.push(n),r.filter(a=>a.length>0)}stringify(e){if(e.length===0)return"";let t=[];for(let r of e)r[r.length-1].type!=="div"&&r.push(this.div(e)),t=t.concat(r);return t[0].type==="div"&&(t=t.slice(1)),t[t.length-1].type==="div"&&(t=t.slice(0,-2+1||void 0)),Hm.stringify({nodes:t})}clone(e,t,r){let n=[],a=!1;for(let s of r)!a&&s.type==="word"&&s.value===e?(n.push({type:"word",value:t}),a=!0):n.push(s);return n}div(e){for(let t of e)for(let r of t)if(r.type==="div"&&r.value===",")return r;return{type:"div",value:",",after:" "}}cleanOtherPrefixes(e,t){return e.filter(r=>{let n=Ym.prefix(this.findProp(r));return n===""||n===t})}cleanFromUnprefixed(e,t){let r=e.map(a=>this.findProp(a)).filter(a=>a.slice(0,t.length)===t).map(a=>this.prefixes.unprefixed(a)),n=[];for(let a of e){let s=this.findProp(a),o=Ym.prefix(s);!r.includes(s)&&(o===t||o==="")&&n.push(a)}return n}disabled(e,t){let r=["order","justify-content","align-self","align-content"];if(e.includes("flex")||r.includes(e)){if(this.prefixes.options.flexbox===!1)return!0;if(this.prefixes.options.flexbox==="no-2009")return t.includes("2009")}}ruleVendorPrefixes(e){let{parent:t}=e;if(t.type!=="rule")return!1;if(!t.selector.includes(":-"))return!1;let r=mA.prefixes().filter(n=>t.selector.includes(":"+n));return r.length>0?r:!1}};Jm.exports=Qm});var Wt=v((N4,Zm)=>{l();var gA=ue(),Km=class{constructor(e,t,r,n){this.unprefixed=e,this.prefixed=t,this.string=r||t,this.regexp=n||gA.regexp(t)}check(e){return e.includes(this.string)?!!e.match(this.regexp):!1}};Zm.exports=Km});var ke=v((L4,tg)=>{l();var yA=Vt(),wA=Wt(),bA=ii(),vA=ue(),eg=class extends yA{static save(e,t){let r=t.prop,n=[];for(let a in t._autoprefixerValues){let s=t._autoprefixerValues[a];if(s===t.value)continue;let o,u=bA.prefix(r);if(u==="-pie-")continue;if(u===a){o=t.value=s,n.push(o);continue}let c=e.prefixed(r,a),f=t.parent;if(!f.every(y=>y.prop!==c)){n.push(o);continue}let p=s.replace(/\s+/," ");if(f.some(y=>y.prop===t.prop&&y.value.replace(/\s+/," ")===p)){n.push(o);continue}let h=this.clone(t,{value:s});o=t.parent.insertBefore(t,h),n.push(o)}return n}check(e){let t=e.value;return t.includes(this.name)?!!t.match(this.regexp()):!1}regexp(){return this.regexpCache||(this.regexpCache=vA.regexp(this.name))}replace(e,t){return e.replace(this.regexp(),`$1${t}$2`)}value(e){return e.raws.value&&e.raws.value.value===e.value?e.raws.value.raw:e.value}add(e,t){e._autoprefixerValues||(e._autoprefixerValues={});let r=e._autoprefixerValues[t]||this.value(e),n;do if(n=r,r=this.replace(r,t),r===!1)return;while(r!==n);e._autoprefixerValues[t]=r}old(e){return new wA(this.name,e+this.name)}};tg.exports=eg});var dt=v(($4,rg)=>{l();rg.exports={}});var il=v((j4,sg)=>{l();var ig=Yn(),xA=ke(),kA=dt().insertAreas,SA=/(^|[^-])linear-gradient\(\s*(top|left|right|bottom)/i,CA=/(^|[^-])radial-gradient\(\s*\d+(\w*|%)\s+\d+(\w*|%)\s*,/i,AA=/(!\s*)?autoprefixer:\s*ignore\s+next/i,_A=/(!\s*)?autoprefixer\s*grid:\s*(on|off|(no-)?autoplace)/i,EA=["width","height","min-width","max-width","min-height","max-height","inline-size","min-inline-size","max-inline-size","block-size","min-block-size","max-block-size"];function rl(i){return i.parent.some(e=>e.prop==="grid-template"||e.prop==="grid-template-areas")}function OA(i){let e=i.parent.some(r=>r.prop==="grid-template-rows"),t=i.parent.some(r=>r.prop==="grid-template-columns");return e&&t}var ng=class{constructor(e){this.prefixes=e}add(e,t){let r=this.prefixes.add["@resolution"],n=this.prefixes.add["@keyframes"],a=this.prefixes.add["@viewport"],s=this.prefixes.add["@supports"];e.walkAtRules(f=>{if(f.name==="keyframes"){if(!this.disabled(f,t))return n&&n.process(f)}else if(f.name==="viewport"){if(!this.disabled(f,t))return a&&a.process(f)}else if(f.name==="supports"){if(this.prefixes.options.supports!==!1&&!this.disabled(f,t))return s.process(f)}else if(f.name==="media"&&f.params.includes("-resolution")&&!this.disabled(f,t))return r&&r.process(f)}),e.walkRules(f=>{if(!this.disabled(f,t))return this.prefixes.add.selectors.map(p=>p.process(f,t))});function o(f){return f.parent.nodes.some(p=>{if(p.type!=="decl")return!1;let d=p.prop==="display"&&/(inline-)?grid/.test(p.value),h=p.prop.startsWith("grid-template"),y=/^grid-([A-z]+-)?gap/.test(p.prop);return d||h||y})}function u(f){return f.parent.some(p=>p.prop==="display"&&/(inline-)?flex/.test(p.value))}let c=this.gridStatus(e,t)&&this.prefixes.add["grid-area"]&&this.prefixes.add["grid-area"].prefixes;return e.walkDecls(f=>{if(this.disabledDecl(f,t))return;let p=f.parent,d=f.prop,h=f.value;if(d==="grid-row-span"){t.warn("grid-row-span is not part of final Grid Layout. Use grid-row.",{node:f});return}else if(d==="grid-column-span"){t.warn("grid-column-span is not part of final Grid Layout. Use grid-column.",{node:f});return}else if(d==="display"&&h==="box"){t.warn("You should write display: flex by final spec instead of display: box",{node:f});return}else if(d==="text-emphasis-position")(h==="under"||h==="over")&&t.warn("You should use 2 values for text-emphasis-position For example, `under left` instead of just `under`.",{node:f});else if(/^(align|justify|place)-(items|content)$/.test(d)&&u(f))(h==="start"||h==="end")&&t.warn(`${h} value has mixed support, consider using flex-${h} instead`,{node:f});else if(d==="text-decoration-skip"&&h==="ink")t.warn("Replace text-decoration-skip: ink to text-decoration-skip-ink: auto, because spec had been changed",{node:f});else{if(c&&this.gridStatus(f,t))if(f.value==="subgrid"&&t.warn("IE does not support subgrid",{node:f}),/^(align|justify|place)-items$/.test(d)&&o(f)){let x=d.replace("-items","-self");t.warn(`IE does not support ${d} on grid containers. Try using ${x} on child elements instead: ${f.parent.selector} > * { ${x}: ${f.value} }`,{node:f})}else if(/^(align|justify|place)-content$/.test(d)&&o(f))t.warn(`IE does not support ${f.prop} on grid containers`,{node:f});else if(d==="display"&&f.value==="contents"){t.warn("Please do not use display: contents; if you have grid setting enabled",{node:f});return}else if(f.prop==="grid-gap"){let x=this.gridStatus(f,t);x==="autoplace"&&!OA(f)&&!rl(f)?t.warn("grid-gap only works if grid-template(-areas) is being used or both rows and columns have been declared and cells have not been manually placed inside the explicit grid",{node:f}):(x===!0||x==="no-autoplace")&&!rl(f)&&t.warn("grid-gap only works if grid-template(-areas) is being used",{node:f})}else if(d==="grid-auto-columns"){t.warn("grid-auto-columns is not supported by IE",{node:f});return}else if(d==="grid-auto-rows"){t.warn("grid-auto-rows is not supported by IE",{node:f});return}else if(d==="grid-auto-flow"){let x=p.some(b=>b.prop==="grid-template-rows"),w=p.some(b=>b.prop==="grid-template-columns");rl(f)?t.warn("grid-auto-flow is not supported by IE",{node:f}):h.includes("dense")?t.warn("grid-auto-flow: dense is not supported by IE",{node:f}):!x&&!w&&t.warn("grid-auto-flow works only if grid-template-rows and grid-template-columns are present in the same rule",{node:f});return}else if(h.includes("auto-fit")){t.warn("auto-fit value is not supported by IE",{node:f,word:"auto-fit"});return}else if(h.includes("auto-fill")){t.warn("auto-fill value is not supported by IE",{node:f,word:"auto-fill"});return}else d.startsWith("grid-template")&&h.includes("[")&&t.warn("Autoprefixer currently does not support line names. Try using grid-template-areas instead.",{node:f,word:"["});if(h.includes("radial-gradient"))if(CA.test(f.value))t.warn("Gradient has outdated direction syntax. New syntax is like `closest-side at 0 0` instead of `0 0, closest-side`.",{node:f});else{let x=ig(h);for(let w of x.nodes)if(w.type==="function"&&w.value==="radial-gradient")for(let b of w.nodes)b.type==="word"&&(b.value==="cover"?t.warn("Gradient has outdated direction syntax. Replace `cover` to `farthest-corner`.",{node:f}):b.value==="contain"&&t.warn("Gradient has outdated direction syntax. Replace `contain` to `closest-side`.",{node:f}))}h.includes("linear-gradient")&&SA.test(h)&&t.warn("Gradient has outdated direction syntax. New syntax is like `to left` instead of `right`.",{node:f})}EA.includes(f.prop)&&(f.value.includes("-fill-available")||(f.value.includes("fill-available")?t.warn("Replace fill-available to stretch, because spec had been changed",{node:f}):f.value.includes("fill")&&ig(h).nodes.some(w=>w.type==="word"&&w.value==="fill")&&t.warn("Replace fill to stretch, because spec had been changed",{node:f})));let y;if(f.prop==="transition"||f.prop==="transition-property")return this.prefixes.transition.add(f,t);if(f.prop==="align-self"){if(this.displayType(f)!=="grid"&&this.prefixes.options.flexbox!==!1&&(y=this.prefixes.add["align-self"],y&&y.prefixes&&y.process(f)),this.gridStatus(f,t)!==!1&&(y=this.prefixes.add["grid-row-align"],y&&y.prefixes))return y.process(f,t)}else if(f.prop==="justify-self"){if(this.gridStatus(f,t)!==!1&&(y=this.prefixes.add["grid-column-align"],y&&y.prefixes))return y.process(f,t)}else if(f.prop==="place-self"){if(y=this.prefixes.add["place-self"],y&&y.prefixes&&this.gridStatus(f,t)!==!1)return y.process(f,t)}else if(y=this.prefixes.add[f.prop],y&&y.prefixes)return y.process(f,t)}),this.gridStatus(e,t)&&kA(e,this.disabled),e.walkDecls(f=>{if(this.disabledValue(f,t))return;let p=this.prefixes.unprefixed(f.prop),d=this.prefixes.values("add",p);if(Array.isArray(d))for(let h of d)h.process&&h.process(f,t);xA.save(this.prefixes,f)})}remove(e,t){let r=this.prefixes.remove["@resolution"];e.walkAtRules((n,a)=>{this.prefixes.remove[`@${n.name}`]?this.disabled(n,t)||n.parent.removeChild(a):n.name==="media"&&n.params.includes("-resolution")&&r&&r.clean(n)});for(let n of this.prefixes.remove.selectors)e.walkRules((a,s)=>{n.check(a)&&(this.disabled(a,t)||a.parent.removeChild(s))});return e.walkDecls((n,a)=>{if(this.disabled(n,t))return;let s=n.parent,o=this.prefixes.unprefixed(n.prop);if((n.prop==="transition"||n.prop==="transition-property")&&this.prefixes.transition.remove(n),this.prefixes.remove[n.prop]&&this.prefixes.remove[n.prop].remove){let u=this.prefixes.group(n).down(c=>this.prefixes.normalize(c.prop)===o);if(o==="flex-flow"&&(u=!0),n.prop==="-webkit-box-orient"){let c={"flex-direction":!0,"flex-flow":!0};if(!n.parent.some(f=>c[f.prop]))return}if(u&&!this.withHackValue(n)){n.raw("before").includes(` +`)&&this.reduceSpaces(n),s.removeChild(a);return}}for(let u of this.prefixes.values("remove",o)){if(!u.check||!u.check(n.value))continue;if(o=u.unprefixed,this.prefixes.group(n).down(f=>f.value.includes(o))){s.removeChild(a);return}}})}withHackValue(e){return e.prop==="-webkit-background-clip"&&e.value==="text"}disabledValue(e,t){return this.gridStatus(e,t)===!1&&e.type==="decl"&&e.prop==="display"&&e.value.includes("grid")||this.prefixes.options.flexbox===!1&&e.type==="decl"&&e.prop==="display"&&e.value.includes("flex")||e.type==="decl"&&e.prop==="content"?!0:this.disabled(e,t)}disabledDecl(e,t){if(this.gridStatus(e,t)===!1&&e.type==="decl"&&(e.prop.includes("grid")||e.prop==="justify-items"))return!0;if(this.prefixes.options.flexbox===!1&&e.type==="decl"){let r=["order","justify-content","align-items","align-content"];if(e.prop.includes("flex")||r.includes(e.prop))return!0}return this.disabled(e,t)}disabled(e,t){if(!e)return!1;if(e._autoprefixerDisabled!==void 0)return e._autoprefixerDisabled;if(e.parent){let n=e.prev();if(n&&n.type==="comment"&&AA.test(n.text))return e._autoprefixerDisabled=!0,e._autoprefixerSelfDisabled=!0,!0}let r=null;if(e.nodes){let n;e.each(a=>{a.type==="comment"&&/(!\s*)?autoprefixer:\s*(off|on)/i.test(a.text)&&(typeof n!="undefined"?t.warn("Second Autoprefixer control comment was ignored. Autoprefixer applies control comment to whole block, not to next rules.",{node:a}):n=/on/i.test(a.text))}),n!==void 0&&(r=!n)}if(!e.nodes||r===null)if(e.parent){let n=this.disabled(e.parent,t);e.parent._autoprefixerSelfDisabled===!0?r=!1:r=n}else r=!1;return e._autoprefixerDisabled=r,r}reduceSpaces(e){let t=!1;if(this.prefixes.group(e).up(()=>(t=!0,!0)),t)return;let r=e.raw("before").split(` +`),n=r[r.length-1].length,a=!1;this.prefixes.group(e).down(s=>{r=s.raw("before").split(` +`);let o=r.length-1;r[o].length>n&&(a===!1&&(a=r[o].length-n),r[o]=r[o].slice(0,-a),s.raws.before=r.join(` +`))})}displayType(e){for(let t of e.parent.nodes)if(t.prop==="display"){if(t.value.includes("flex"))return"flex";if(t.value.includes("grid"))return"grid"}return!1}gridStatus(e,t){if(!e)return!1;if(e._autoprefixerGridStatus!==void 0)return e._autoprefixerGridStatus;let r=null;if(e.nodes){let n;e.each(a=>{if(a.type==="comment"&&_A.test(a.text)){let s=/:\s*autoplace/i.test(a.text),o=/no-autoplace/i.test(a.text);typeof n!="undefined"?t.warn("Second Autoprefixer grid control comment was ignored. Autoprefixer applies control comments to the whole block, not to the next rules.",{node:a}):s?n="autoplace":o?n=!0:n=/on/i.test(a.text)}}),n!==void 0&&(r=n)}if(e.type==="atrule"&&e.name==="supports"){let n=e.params;n.includes("grid")&&n.includes("auto")&&(r=!1)}if(!e.nodes||r===null)if(e.parent){let n=this.gridStatus(e.parent,t);e.parent._autoprefixerSelfDisabled===!0?r=!1:r=n}else typeof this.prefixes.options.grid!="undefined"?r=this.prefixes.options.grid:typeof m.env.AUTOPREFIXER_GRID!="undefined"?m.env.AUTOPREFIXER_GRID==="autoplace"?r="autoplace":r=!0:r=!1;return e._autoprefixerGridStatus=r,r}};sg.exports=ng});var og=v((z4,ag)=>{l();ag.exports={A:{A:{"2":"K E F G A B JC"},B:{"1":"C L M H N D O P Q R S T U V W X Y Z a b c d e f g h i j n o p q r s t u v w x y z I"},C:{"1":"2 3 4 5 6 7 8 9 AB BB CB DB EB FB GB HB IB JB KB LB MB NB OB PB QB RB SB TB UB VB WB XB YB ZB aB bB cB 0B dB 1B eB fB gB hB iB jB kB lB mB nB oB m pB qB rB sB tB P Q R 2B S T U V W X Y Z a b c d e f g h i j n o p q r s t u v w x y z I uB 3B 4B","2":"0 1 KC zB J K E F G A B C L M H N D O k l LC MC"},D:{"1":"8 9 AB BB CB DB EB FB GB HB IB JB KB LB MB NB OB PB QB RB SB TB UB VB WB XB YB ZB aB bB cB 0B dB 1B eB fB gB hB iB jB kB lB mB nB oB m pB qB rB sB tB P Q R S T U V W X Y Z a b c d e f g h i j n o p q r s t u v w x y z I uB 3B 4B","2":"0 1 2 3 4 5 6 7 J K E F G A B C L M H N D O k l"},E:{"1":"G A B C L M H D RC 6B vB wB 7B SC TC 8B 9B xB AC yB BC CC DC EC FC GC UC","2":"0 J K E F NC 5B OC PC QC"},F:{"1":"1 2 3 4 5 6 7 8 9 H N D O k l AB BB CB DB EB FB GB HB IB JB KB LB MB NB OB PB QB RB SB TB UB VB WB XB YB ZB aB bB cB dB eB fB gB hB iB jB kB lB mB nB oB m pB qB rB sB tB P Q R 2B S T U V W X Y Z a b c d e f g h i j wB","2":"G B C VC WC XC YC vB HC ZC"},G:{"1":"D fC gC hC iC jC kC lC mC nC oC pC qC rC sC tC 8B 9B xB AC yB BC CC DC EC FC GC","2":"F 5B aC IC bC cC dC eC"},H:{"1":"uC"},I:{"1":"I zC 0C","2":"zB J vC wC xC yC IC"},J:{"2":"E A"},K:{"1":"m","2":"A B C vB HC wB"},L:{"1":"I"},M:{"1":"uB"},N:{"2":"A B"},O:{"1":"xB"},P:{"1":"J k l 1C 2C 3C 4C 5C 6B 6C 7C 8C 9C AD yB BD CD DD"},Q:{"1":"7B"},R:{"1":"ED"},S:{"1":"FD GD"}},B:4,C:"CSS Feature Queries"}});var cg=v((V4,fg)=>{l();function lg(i){return i[i.length-1]}var ug={parse(i){let e=[""],t=[e];for(let r of i){if(r==="("){e=[""],lg(t).push(e),t.push(e);continue}if(r===")"){t.pop(),e=lg(t),e.push("");continue}e[e.length-1]+=r}return t[0]},stringify(i){let e="";for(let t of i){if(typeof t=="object"){e+=`(${ug.stringify(t)})`;continue}e+=t}return e}};fg.exports=ug});var gg=v((U4,mg)=>{l();var TA=og(),{feature:PA}=(zn(),jn),{parse:DA}=me(),IA=ct(),nl=cg(),qA=ke(),RA=ue(),pg=PA(TA),dg=[];for(let i in pg.stats){let e=pg.stats[i];for(let t in e){let r=e[t];/y/.test(r)&&dg.push(i+" "+t)}}var hg=class{constructor(e,t){this.Prefixes=e,this.all=t}prefixer(){if(this.prefixerCache)return this.prefixerCache;let e=this.all.browsers.selected.filter(r=>dg.includes(r)),t=new IA(this.all.browsers.data,e,this.all.options);return this.prefixerCache=new this.Prefixes(this.all.data,t,this.all.options),this.prefixerCache}parse(e){let t=e.split(":"),r=t[0],n=t[1];return n||(n=""),[r.trim(),n.trim()]}virtual(e){let[t,r]=this.parse(e),n=DA("a{}").first;return n.append({prop:t,value:r,raws:{before:""}}),n}prefixed(e){let t=this.virtual(e);if(this.disabled(t.first))return t.nodes;let r={warn:()=>null},n=this.prefixer().add[t.first.prop];n&&n.process&&n.process(t.first,r);for(let a of t.nodes){for(let s of this.prefixer().values("add",t.first.prop))s.process(a);qA.save(this.all,a)}return t.nodes}isNot(e){return typeof e=="string"&&/not\s*/i.test(e)}isOr(e){return typeof e=="string"&&/\s*or\s*/i.test(e)}isProp(e){return typeof e=="object"&&e.length===1&&typeof e[0]=="string"}isHack(e,t){return!new RegExp(`(\\(|\\s)${RA.escapeRegexp(t)}:`).test(e)}toRemove(e,t){let[r,n]=this.parse(e),a=this.all.unprefixed(r),s=this.all.cleaner();if(s.remove[r]&&s.remove[r].remove&&!this.isHack(t,a))return!0;for(let o of s.values("remove",a))if(o.check(n))return!0;return!1}remove(e,t){let r=0;for(;rtypeof t!="object"?t:t.length===1&&typeof t[0]=="object"?this.cleanBrackets(t[0]):this.cleanBrackets(t))}convert(e){let t=[""];for(let r of e)t.push([`${r.prop}: ${r.value}`]),t.push(" or ");return t[t.length-1]="",t}normalize(e){if(typeof e!="object")return e;if(e=e.filter(t=>t!==""),typeof e[0]=="string"){let t=e[0].trim();if(t.includes(":")||t==="selector"||t==="not selector")return[nl.stringify(e)]}return e.map(t=>this.normalize(t))}add(e,t){return e.map(r=>{if(this.isProp(r)){let n=this.prefixed(r[0]);return n.length>1?this.convert(n):r}return typeof r=="object"?this.add(r,t):r})}process(e){let t=nl.parse(e.params);t=this.normalize(t),t=this.remove(t,e.params),t=this.add(t,e.params),t=this.cleanBrackets(t),e.params=nl.stringify(t)}disabled(e){if(!this.all.options.grid&&(e.prop==="display"&&e.value.includes("grid")||e.prop.includes("grid")||e.prop==="justify-items"))return!0;if(this.all.options.flexbox===!1){if(e.prop==="display"&&e.value.includes("flex"))return!0;let t=["order","justify-content","align-items","align-content"];if(e.prop.includes("flex")||t.includes(e.prop))return!0}return!1}};mg.exports=hg});var bg=v((W4,wg)=>{l();var yg=class{constructor(e,t){this.prefix=t,this.prefixed=e.prefixed(this.prefix),this.regexp=e.regexp(this.prefix),this.prefixeds=e.possible().map(r=>[e.prefixed(r),e.regexp(r)]),this.unprefixed=e.name,this.nameRegexp=e.regexp()}isHack(e){let t=e.parent.index(e)+1,r=e.parent.nodes;for(;t{l();var{list:MA}=me(),BA=bg(),FA=Vt(),NA=ct(),LA=ue(),vg=class extends FA{constructor(e,t,r){super(e,t,r);this.regexpCache=new Map}check(e){return e.selector.includes(this.name)?!!e.selector.match(this.regexp()):!1}prefixed(e){return this.name.replace(/^(\W*)/,`$1${e}`)}regexp(e){if(!this.regexpCache.has(e)){let t=e?this.prefixed(e):this.name;this.regexpCache.set(e,new RegExp(`(^|[^:"'=])${LA.escapeRegexp(t)}`,"gi"))}return this.regexpCache.get(e)}possible(){return NA.prefixes()}prefixeds(e){if(e._autoprefixerPrefixeds){if(e._autoprefixerPrefixeds[this.name])return e._autoprefixerPrefixeds}else e._autoprefixerPrefixeds={};let t={};if(e.selector.includes(",")){let n=MA.comma(e.selector).filter(a=>a.includes(this.name));for(let a of this.possible())t[a]=n.map(s=>this.replace(s,a)).join(", ")}else for(let r of this.possible())t[r]=this.replace(e.selector,r);return e._autoprefixerPrefixeds[this.name]=t,e._autoprefixerPrefixeds}already(e,t,r){let n=e.parent.index(e)-1;for(;n>=0;){let a=e.parent.nodes[n];if(a.type!=="rule")return!1;let s=!1;for(let o in t[this.name]){let u=t[this.name][o];if(a.selector===u){if(r===o)return!0;s=!0;break}}if(!s)return!1;n-=1}return!1}replace(e,t){return e.replace(this.regexp(),`$1${this.prefixed(t)}`)}add(e,t){let r=this.prefixeds(e);if(this.already(e,r,t))return;let n=this.clone(e,{selector:r[this.name][t]});e.parent.insertBefore(e,n)}old(e){return new BA(this,e)}};xg.exports=vg});var Cg=v((H4,Sg)=>{l();var $A=Vt(),kg=class extends $A{add(e,t){let r=t+e.name;if(e.parent.some(s=>s.name===r&&s.params===e.params))return;let a=this.clone(e,{name:r});return e.parent.insertBefore(e,a)}process(e){let t=this.parentPrefix(e);for(let r of this.prefixes)(!t||t===r)&&this.add(e,r)}};Sg.exports=kg});var _g=v((Y4,Ag)=>{l();var jA=Gt(),sl=class extends jA{prefixed(e){return e==="-webkit-"?":-webkit-full-screen":e==="-moz-"?":-moz-full-screen":`:${e}fullscreen`}};sl.names=[":fullscreen"];Ag.exports=sl});var Og=v((Q4,Eg)=>{l();var zA=Gt(),al=class extends zA{possible(){return super.possible().concat(["-moz- old","-ms- old"])}prefixed(e){return e==="-webkit-"?"::-webkit-input-placeholder":e==="-ms-"?"::-ms-input-placeholder":e==="-ms- old"?":-ms-input-placeholder":e==="-moz- old"?":-moz-placeholder":`::${e}placeholder`}};al.names=["::placeholder"];Eg.exports=al});var Pg=v((J4,Tg)=>{l();var VA=Gt(),ol=class extends VA{prefixed(e){return e==="-ms-"?":-ms-input-placeholder":`:${e}placeholder-shown`}};ol.names=[":placeholder-shown"];Tg.exports=ol});var Ig=v((X4,Dg)=>{l();var UA=Gt(),WA=ue(),ll=class extends UA{constructor(e,t,r){super(e,t,r);this.prefixes&&(this.prefixes=WA.uniq(this.prefixes.map(n=>"-webkit-")))}prefixed(e){return e==="-webkit-"?"::-webkit-file-upload-button":`::${e}file-selector-button`}};ll.names=["::file-selector-button"];Dg.exports=ll});var de=v((K4,qg)=>{l();qg.exports=function(i){let e;return i==="-webkit- 2009"||i==="-moz-"?e=2009:i==="-ms-"?e=2012:i==="-webkit-"&&(e="final"),i==="-webkit- 2009"&&(i="-webkit-"),[e,i]}});var Fg=v((Z4,Bg)=>{l();var Rg=me().list,Mg=de(),GA=R(),Ht=class extends GA{prefixed(e,t){let r;return[r,t]=Mg(t),r===2009?t+"box-flex":super.prefixed(e,t)}normalize(){return"flex"}set(e,t){let r=Mg(t)[0];if(r===2009)return e.value=Rg.space(e.value)[0],e.value=Ht.oldValues[e.value]||e.value,super.set(e,t);if(r===2012){let n=Rg.space(e.value);n.length===3&&n[2]==="0"&&(e.value=n.slice(0,2).concat("0px").join(" "))}return super.set(e,t)}};Ht.names=["flex","box-flex"];Ht.oldValues={auto:"1",none:"0"};Bg.exports=Ht});var $g=v((eq,Lg)=>{l();var Ng=de(),HA=R(),ul=class extends HA{prefixed(e,t){let r;return[r,t]=Ng(t),r===2009?t+"box-ordinal-group":r===2012?t+"flex-order":super.prefixed(e,t)}normalize(){return"order"}set(e,t){return Ng(t)[0]===2009&&/\d/.test(e.value)?(e.value=(parseInt(e.value)+1).toString(),super.set(e,t)):super.set(e,t)}};ul.names=["order","flex-order","box-ordinal-group"];Lg.exports=ul});var zg=v((tq,jg)=>{l();var YA=R(),fl=class extends YA{check(e){let t=e.value;return!t.toLowerCase().includes("alpha(")&&!t.includes("DXImageTransform.Microsoft")&&!t.includes("data:image/svg+xml")}};fl.names=["filter"];jg.exports=fl});var Ug=v((rq,Vg)=>{l();var QA=R(),cl=class extends QA{insert(e,t,r,n){if(t!=="-ms-")return super.insert(e,t,r);let a=this.clone(e),s=e.prop.replace(/end$/,"start"),o=t+e.prop.replace(/end$/,"span");if(!e.parent.some(u=>u.prop===o)){if(a.prop=o,e.value.includes("span"))a.value=e.value.replace(/span\s/i,"");else{let u;if(e.parent.walkDecls(s,c=>{u=c}),u){let c=Number(e.value)-Number(u.value)+"";a.value=c}else e.warn(n,`Can not prefix ${e.prop} (${s} is not found)`)}e.cloneBefore(a)}}};cl.names=["grid-row-end","grid-column-end"];Vg.exports=cl});var Gg=v((iq,Wg)=>{l();var JA=R(),pl=class extends JA{check(e){return!e.value.split(/\s+/).some(t=>{let r=t.toLowerCase();return r==="reverse"||r==="alternate-reverse"})}};pl.names=["animation","animation-direction"];Wg.exports=pl});var Yg=v((nq,Hg)=>{l();var XA=de(),KA=R(),dl=class extends KA{insert(e,t,r){let n;if([n,t]=XA(t),n!==2009)return super.insert(e,t,r);let a=e.value.split(/\s+/).filter(p=>p!=="wrap"&&p!=="nowrap"&&"wrap-reverse");if(a.length===0||e.parent.some(p=>p.prop===t+"box-orient"||p.prop===t+"box-direction"))return;let o=a[0],u=o.includes("row")?"horizontal":"vertical",c=o.includes("reverse")?"reverse":"normal",f=this.clone(e);return f.prop=t+"box-orient",f.value=u,this.needCascade(e)&&(f.raws.before=this.calcBefore(r,e,t)),e.parent.insertBefore(e,f),f=this.clone(e),f.prop=t+"box-direction",f.value=c,this.needCascade(e)&&(f.raws.before=this.calcBefore(r,e,t)),e.parent.insertBefore(e,f)}};dl.names=["flex-flow","box-direction","box-orient"];Hg.exports=dl});var Jg=v((sq,Qg)=>{l();var ZA=de(),e_=R(),hl=class extends e_{normalize(){return"flex"}prefixed(e,t){let r;return[r,t]=ZA(t),r===2009?t+"box-flex":r===2012?t+"flex-positive":super.prefixed(e,t)}};hl.names=["flex-grow","flex-positive"];Qg.exports=hl});var Kg=v((aq,Xg)=>{l();var t_=de(),r_=R(),ml=class extends r_{set(e,t){if(t_(t)[0]!==2009)return super.set(e,t)}};ml.names=["flex-wrap"];Xg.exports=ml});var ey=v((oq,Zg)=>{l();var i_=R(),Yt=dt(),gl=class extends i_{insert(e,t,r,n){if(t!=="-ms-")return super.insert(e,t,r);let a=Yt.parse(e),[s,o]=Yt.translate(a,0,2),[u,c]=Yt.translate(a,1,3);[["grid-row",s],["grid-row-span",o],["grid-column",u],["grid-column-span",c]].forEach(([f,p])=>{Yt.insertDecl(e,f,p)}),Yt.warnTemplateSelectorNotFound(e,n),Yt.warnIfGridRowColumnExists(e,n)}};gl.names=["grid-area"];Zg.exports=gl});var ry=v((lq,ty)=>{l();var n_=R(),ni=dt(),yl=class extends n_{insert(e,t,r){if(t!=="-ms-")return super.insert(e,t,r);if(e.parent.some(s=>s.prop==="-ms-grid-row-align"))return;let[[n,a]]=ni.parse(e);a?(ni.insertDecl(e,"grid-row-align",n),ni.insertDecl(e,"grid-column-align",a)):(ni.insertDecl(e,"grid-row-align",n),ni.insertDecl(e,"grid-column-align",n))}};yl.names=["place-self"];ty.exports=yl});var ny=v((uq,iy)=>{l();var s_=R(),wl=class extends s_{check(e){let t=e.value;return!t.includes("/")||t.includes("span")}normalize(e){return e.replace("-start","")}prefixed(e,t){let r=super.prefixed(e,t);return t==="-ms-"&&(r=r.replace("-start","")),r}};wl.names=["grid-row-start","grid-column-start"];iy.exports=wl});var oy=v((fq,ay)=>{l();var sy=de(),a_=R(),Qt=class extends a_{check(e){return e.parent&&!e.parent.some(t=>t.prop&&t.prop.startsWith("grid-"))}prefixed(e,t){let r;return[r,t]=sy(t),r===2012?t+"flex-item-align":super.prefixed(e,t)}normalize(){return"align-self"}set(e,t){let r=sy(t)[0];if(r===2012)return e.value=Qt.oldValues[e.value]||e.value,super.set(e,t);if(r==="final")return super.set(e,t)}};Qt.names=["align-self","flex-item-align"];Qt.oldValues={"flex-end":"end","flex-start":"start"};ay.exports=Qt});var uy=v((cq,ly)=>{l();var o_=R(),l_=ue(),bl=class extends o_{constructor(e,t,r){super(e,t,r);this.prefixes&&(this.prefixes=l_.uniq(this.prefixes.map(n=>n==="-ms-"?"-webkit-":n)))}};bl.names=["appearance"];ly.exports=bl});var py=v((pq,cy)=>{l();var fy=de(),u_=R(),vl=class extends u_{normalize(){return"flex-basis"}prefixed(e,t){let r;return[r,t]=fy(t),r===2012?t+"flex-preferred-size":super.prefixed(e,t)}set(e,t){let r;if([r,t]=fy(t),r===2012||r==="final")return super.set(e,t)}};vl.names=["flex-basis","flex-preferred-size"];cy.exports=vl});var hy=v((dq,dy)=>{l();var f_=R(),xl=class extends f_{normalize(){return this.name.replace("box-image","border")}prefixed(e,t){let r=super.prefixed(e,t);return t==="-webkit-"&&(r=r.replace("border","box-image")),r}};xl.names=["mask-border","mask-border-source","mask-border-slice","mask-border-width","mask-border-outset","mask-border-repeat","mask-box-image","mask-box-image-source","mask-box-image-slice","mask-box-image-width","mask-box-image-outset","mask-box-image-repeat"];dy.exports=xl});var gy=v((hq,my)=>{l();var c_=R(),Le=class extends c_{insert(e,t,r){let n=e.prop==="mask-composite",a;n?a=e.value.split(","):a=e.value.match(Le.regexp)||[],a=a.map(c=>c.trim()).filter(c=>c);let s=a.length,o;if(s&&(o=this.clone(e),o.value=a.map(c=>Le.oldValues[c]||c).join(", "),a.includes("intersect")&&(o.value+=", xor"),o.prop=t+"mask-composite"),n)return s?(this.needCascade(e)&&(o.raws.before=this.calcBefore(r,e,t)),e.parent.insertBefore(e,o)):void 0;let u=this.clone(e);return u.prop=t+u.prop,s&&(u.value=u.value.replace(Le.regexp,"")),this.needCascade(e)&&(u.raws.before=this.calcBefore(r,e,t)),e.parent.insertBefore(e,u),s?(this.needCascade(e)&&(o.raws.before=this.calcBefore(r,e,t)),e.parent.insertBefore(e,o)):e}};Le.names=["mask","mask-composite"];Le.oldValues={add:"source-over",subtract:"source-out",intersect:"source-in",exclude:"xor"};Le.regexp=new RegExp(`\\s+(${Object.keys(Le.oldValues).join("|")})\\b(?!\\))\\s*(?=[,])`,"ig");my.exports=Le});var by=v((mq,wy)=>{l();var yy=de(),p_=R(),Jt=class extends p_{prefixed(e,t){let r;return[r,t]=yy(t),r===2009?t+"box-align":r===2012?t+"flex-align":super.prefixed(e,t)}normalize(){return"align-items"}set(e,t){let r=yy(t)[0];return(r===2009||r===2012)&&(e.value=Jt.oldValues[e.value]||e.value),super.set(e,t)}};Jt.names=["align-items","flex-align","box-align"];Jt.oldValues={"flex-end":"end","flex-start":"start"};wy.exports=Jt});var xy=v((gq,vy)=>{l();var d_=R(),kl=class extends d_{set(e,t){return t==="-ms-"&&e.value==="contain"&&(e.value="element"),super.set(e,t)}insert(e,t,r){if(!(e.value==="all"&&t==="-ms-"))return super.insert(e,t,r)}};kl.names=["user-select"];vy.exports=kl});var Cy=v((yq,Sy)=>{l();var ky=de(),h_=R(),Sl=class extends h_{normalize(){return"flex-shrink"}prefixed(e,t){let r;return[r,t]=ky(t),r===2012?t+"flex-negative":super.prefixed(e,t)}set(e,t){let r;if([r,t]=ky(t),r===2012||r==="final")return super.set(e,t)}};Sl.names=["flex-shrink","flex-negative"];Sy.exports=Sl});var _y=v((wq,Ay)=>{l();var m_=R(),Cl=class extends m_{prefixed(e,t){return`${t}column-${e}`}normalize(e){return e.includes("inside")?"break-inside":e.includes("before")?"break-before":"break-after"}set(e,t){return(e.prop==="break-inside"&&e.value==="avoid-column"||e.value==="avoid-page")&&(e.value="avoid"),super.set(e,t)}insert(e,t,r){if(e.prop!=="break-inside")return super.insert(e,t,r);if(!(/region/i.test(e.value)||/page/i.test(e.value)))return super.insert(e,t,r)}};Cl.names=["break-inside","page-break-inside","column-break-inside","break-before","page-break-before","column-break-before","break-after","page-break-after","column-break-after"];Ay.exports=Cl});var Oy=v((bq,Ey)=>{l();var g_=R(),Al=class extends g_{prefixed(e,t){return t+"print-color-adjust"}normalize(){return"color-adjust"}};Al.names=["color-adjust","print-color-adjust"];Ey.exports=Al});var Py=v((vq,Ty)=>{l();var y_=R(),Xt=class extends y_{insert(e,t,r){if(t==="-ms-"){let n=this.set(this.clone(e),t);this.needCascade(e)&&(n.raws.before=this.calcBefore(r,e,t));let a="ltr";return e.parent.nodes.forEach(s=>{s.prop==="direction"&&(s.value==="rtl"||s.value==="ltr")&&(a=s.value)}),n.value=Xt.msValues[a][e.value]||e.value,e.parent.insertBefore(e,n)}return super.insert(e,t,r)}};Xt.names=["writing-mode"];Xt.msValues={ltr:{"horizontal-tb":"lr-tb","vertical-rl":"tb-rl","vertical-lr":"tb-lr"},rtl:{"horizontal-tb":"rl-tb","vertical-rl":"bt-rl","vertical-lr":"bt-lr"}};Ty.exports=Xt});var Iy=v((xq,Dy)=>{l();var w_=R(),_l=class extends w_{set(e,t){return e.value=e.value.replace(/\s+fill(\s)/,"$1"),super.set(e,t)}};_l.names=["border-image"];Dy.exports=_l});var My=v((kq,Ry)=>{l();var qy=de(),b_=R(),Kt=class extends b_{prefixed(e,t){let r;return[r,t]=qy(t),r===2012?t+"flex-line-pack":super.prefixed(e,t)}normalize(){return"align-content"}set(e,t){let r=qy(t)[0];if(r===2012)return e.value=Kt.oldValues[e.value]||e.value,super.set(e,t);if(r==="final")return super.set(e,t)}};Kt.names=["align-content","flex-line-pack"];Kt.oldValues={"flex-end":"end","flex-start":"start","space-between":"justify","space-around":"distribute"};Ry.exports=Kt});var Fy=v((Sq,By)=>{l();var v_=R(),Se=class extends v_{prefixed(e,t){return t==="-moz-"?t+(Se.toMozilla[e]||e):super.prefixed(e,t)}normalize(e){return Se.toNormal[e]||e}};Se.names=["border-radius"];Se.toMozilla={};Se.toNormal={};for(let i of["top","bottom"])for(let e of["left","right"]){let t=`border-${i}-${e}-radius`,r=`border-radius-${i}${e}`;Se.names.push(t),Se.names.push(r),Se.toMozilla[t]=r,Se.toNormal[r]=t}By.exports=Se});var Ly=v((Cq,Ny)=>{l();var x_=R(),El=class extends x_{prefixed(e,t){return e.includes("-start")?t+e.replace("-block-start","-before"):t+e.replace("-block-end","-after")}normalize(e){return e.includes("-before")?e.replace("-before","-block-start"):e.replace("-after","-block-end")}};El.names=["border-block-start","border-block-end","margin-block-start","margin-block-end","padding-block-start","padding-block-end","border-before","border-after","margin-before","margin-after","padding-before","padding-after"];Ny.exports=El});var jy=v((Aq,$y)=>{l();var k_=R(),{parseTemplate:S_,warnMissedAreas:C_,getGridGap:A_,warnGridGap:__,inheritGridGap:E_}=dt(),Ol=class extends k_{insert(e,t,r,n){if(t!=="-ms-")return super.insert(e,t,r);if(e.parent.some(h=>h.prop==="-ms-grid-rows"))return;let a=A_(e),s=E_(e,a),{rows:o,columns:u,areas:c}=S_({decl:e,gap:s||a}),f=Object.keys(c).length>0,p=Boolean(o),d=Boolean(u);return __({gap:a,hasColumns:d,decl:e,result:n}),C_(c,e,n),(p&&d||f)&&e.cloneBefore({prop:"-ms-grid-rows",value:o,raws:{}}),d&&e.cloneBefore({prop:"-ms-grid-columns",value:u,raws:{}}),e}};Ol.names=["grid-template"];$y.exports=Ol});var Vy=v((_q,zy)=>{l();var O_=R(),Tl=class extends O_{prefixed(e,t){return t+e.replace("-inline","")}normalize(e){return e.replace(/(margin|padding|border)-(start|end)/,"$1-inline-$2")}};Tl.names=["border-inline-start","border-inline-end","margin-inline-start","margin-inline-end","padding-inline-start","padding-inline-end","border-start","border-end","margin-start","margin-end","padding-start","padding-end"];zy.exports=Tl});var Wy=v((Eq,Uy)=>{l();var T_=R(),Pl=class extends T_{check(e){return!e.value.includes("flex-")&&e.value!=="baseline"}prefixed(e,t){return t+"grid-row-align"}normalize(){return"align-self"}};Pl.names=["grid-row-align"];Uy.exports=Pl});var Hy=v((Oq,Gy)=>{l();var P_=R(),Zt=class extends P_{keyframeParents(e){let{parent:t}=e;for(;t;){if(t.type==="atrule"&&t.name==="keyframes")return!0;({parent:t}=t)}return!1}contain3d(e){if(e.prop==="transform-origin")return!1;for(let t of Zt.functions3d)if(e.value.includes(`${t}(`))return!0;return!1}set(e,t){return e=super.set(e,t),t==="-ms-"&&(e.value=e.value.replace(/rotatez/gi,"rotate")),e}insert(e,t,r){if(t==="-ms-"){if(!this.contain3d(e)&&!this.keyframeParents(e))return super.insert(e,t,r)}else if(t==="-o-"){if(!this.contain3d(e))return super.insert(e,t,r)}else return super.insert(e,t,r)}};Zt.names=["transform","transform-origin"];Zt.functions3d=["matrix3d","translate3d","translateZ","scale3d","scaleZ","rotate3d","rotateX","rotateY","perspective"];Gy.exports=Zt});var Jy=v((Tq,Qy)=>{l();var Yy=de(),D_=R(),Dl=class extends D_{normalize(){return"flex-direction"}insert(e,t,r){let n;if([n,t]=Yy(t),n!==2009)return super.insert(e,t,r);if(e.parent.some(f=>f.prop===t+"box-orient"||f.prop===t+"box-direction"))return;let s=e.value,o,u;s==="inherit"||s==="initial"||s==="unset"?(o=s,u=s):(o=s.includes("row")?"horizontal":"vertical",u=s.includes("reverse")?"reverse":"normal");let c=this.clone(e);return c.prop=t+"box-orient",c.value=o,this.needCascade(e)&&(c.raws.before=this.calcBefore(r,e,t)),e.parent.insertBefore(e,c),c=this.clone(e),c.prop=t+"box-direction",c.value=u,this.needCascade(e)&&(c.raws.before=this.calcBefore(r,e,t)),e.parent.insertBefore(e,c)}old(e,t){let r;return[r,t]=Yy(t),r===2009?[t+"box-orient",t+"box-direction"]:super.old(e,t)}};Dl.names=["flex-direction","box-direction","box-orient"];Qy.exports=Dl});var Ky=v((Pq,Xy)=>{l();var I_=R(),Il=class extends I_{check(e){return e.value==="pixelated"}prefixed(e,t){return t==="-ms-"?"-ms-interpolation-mode":super.prefixed(e,t)}set(e,t){return t!=="-ms-"?super.set(e,t):(e.prop="-ms-interpolation-mode",e.value="nearest-neighbor",e)}normalize(){return"image-rendering"}process(e,t){return super.process(e,t)}};Il.names=["image-rendering","interpolation-mode"];Xy.exports=Il});var ew=v((Dq,Zy)=>{l();var q_=R(),R_=ue(),ql=class extends q_{constructor(e,t,r){super(e,t,r);this.prefixes&&(this.prefixes=R_.uniq(this.prefixes.map(n=>n==="-ms-"?"-webkit-":n)))}};ql.names=["backdrop-filter"];Zy.exports=ql});var rw=v((Iq,tw)=>{l();var M_=R(),B_=ue(),Rl=class extends M_{constructor(e,t,r){super(e,t,r);this.prefixes&&(this.prefixes=B_.uniq(this.prefixes.map(n=>n==="-ms-"?"-webkit-":n)))}check(e){return e.value.toLowerCase()==="text"}};Rl.names=["background-clip"];tw.exports=Rl});var nw=v((qq,iw)=>{l();var F_=R(),N_=["none","underline","overline","line-through","blink","inherit","initial","unset"],Ml=class extends F_{check(e){return e.value.split(/\s+/).some(t=>!N_.includes(t))}};Ml.names=["text-decoration"];iw.exports=Ml});var ow=v((Rq,aw)=>{l();var sw=de(),L_=R(),er=class extends L_{prefixed(e,t){let r;return[r,t]=sw(t),r===2009?t+"box-pack":r===2012?t+"flex-pack":super.prefixed(e,t)}normalize(){return"justify-content"}set(e,t){let r=sw(t)[0];if(r===2009||r===2012){let n=er.oldValues[e.value]||e.value;if(e.value=n,r!==2009||n!=="distribute")return super.set(e,t)}else if(r==="final")return super.set(e,t)}};er.names=["justify-content","flex-pack","box-pack"];er.oldValues={"flex-end":"end","flex-start":"start","space-between":"justify","space-around":"distribute"};aw.exports=er});var uw=v((Mq,lw)=>{l();var $_=R(),Bl=class extends $_{set(e,t){let r=e.value.toLowerCase();return t==="-webkit-"&&!r.includes(" ")&&r!=="contain"&&r!=="cover"&&(e.value=e.value+" "+e.value),super.set(e,t)}};Bl.names=["background-size"];lw.exports=Bl});var cw=v((Bq,fw)=>{l();var j_=R(),Fl=dt(),Nl=class extends j_{insert(e,t,r){if(t!=="-ms-")return super.insert(e,t,r);let n=Fl.parse(e),[a,s]=Fl.translate(n,0,1);n[0]&&n[0].includes("span")&&(s=n[0].join("").replace(/\D/g,"")),[[e.prop,a],[`${e.prop}-span`,s]].forEach(([u,c])=>{Fl.insertDecl(e,u,c)})}};Nl.names=["grid-row","grid-column"];fw.exports=Nl});var hw=v((Fq,dw)=>{l();var z_=R(),{prefixTrackProp:pw,prefixTrackValue:V_,autoplaceGridItems:U_,getGridGap:W_,inheritGridGap:G_}=dt(),H_=il(),Ll=class extends z_{prefixed(e,t){return t==="-ms-"?pw({prop:e,prefix:t}):super.prefixed(e,t)}normalize(e){return e.replace(/^grid-(rows|columns)/,"grid-template-$1")}insert(e,t,r,n){if(t!=="-ms-")return super.insert(e,t,r);let{parent:a,prop:s,value:o}=e,u=s.includes("rows"),c=s.includes("columns"),f=a.some(k=>k.prop==="grid-template"||k.prop==="grid-template-areas");if(f&&u)return!1;let p=new H_({options:{}}),d=p.gridStatus(a,n),h=W_(e);h=G_(e,h)||h;let y=u?h.row:h.column;(d==="no-autoplace"||d===!0)&&!f&&(y=null);let x=V_({value:o,gap:y});e.cloneBefore({prop:pw({prop:s,prefix:t}),value:x});let w=a.nodes.find(k=>k.prop==="grid-auto-flow"),b="row";if(w&&!p.disabled(w,n)&&(b=w.value.trim()),d==="autoplace"){let k=a.nodes.find(_=>_.prop==="grid-template-rows");if(!k&&f)return;if(!k&&!f){e.warn(n,"Autoplacement does not work without grid-template-rows property");return}!a.nodes.find(_=>_.prop==="grid-template-columns")&&!f&&e.warn(n,"Autoplacement does not work without grid-template-columns property"),c&&!f&&U_(e,n,h,b)}}};Ll.names=["grid-template-rows","grid-template-columns","grid-rows","grid-columns"];dw.exports=Ll});var gw=v((Nq,mw)=>{l();var Y_=R(),$l=class extends Y_{check(e){return!e.value.includes("flex-")&&e.value!=="baseline"}prefixed(e,t){return t+"grid-column-align"}normalize(){return"justify-self"}};$l.names=["grid-column-align"];mw.exports=$l});var ww=v((Lq,yw)=>{l();var Q_=R(),jl=class extends Q_{prefixed(e,t){return t+"scroll-chaining"}normalize(){return"overscroll-behavior"}set(e,t){return e.value==="auto"?e.value="chained":(e.value==="none"||e.value==="contain")&&(e.value="none"),super.set(e,t)}};jl.names=["overscroll-behavior","scroll-chaining"];yw.exports=jl});var xw=v(($q,vw)=>{l();var J_=R(),{parseGridAreas:X_,warnMissedAreas:K_,prefixTrackProp:Z_,prefixTrackValue:bw,getGridGap:eE,warnGridGap:tE,inheritGridGap:rE}=dt();function iE(i){return i.trim().slice(1,-1).split(/["']\s*["']?/g)}var zl=class extends J_{insert(e,t,r,n){if(t!=="-ms-")return super.insert(e,t,r);let a=!1,s=!1,o=e.parent,u=eE(e);u=rE(e,u)||u,o.walkDecls(/-ms-grid-rows/,p=>p.remove()),o.walkDecls(/grid-template-(rows|columns)/,p=>{if(p.prop==="grid-template-rows"){s=!0;let{prop:d,value:h}=p;p.cloneBefore({prop:Z_({prop:d,prefix:t}),value:bw({value:h,gap:u.row})})}else a=!0});let c=iE(e.value);a&&!s&&u.row&&c.length>1&&e.cloneBefore({prop:"-ms-grid-rows",value:bw({value:`repeat(${c.length}, auto)`,gap:u.row}),raws:{}}),tE({gap:u,hasColumns:a,decl:e,result:n});let f=X_({rows:c,gap:u});return K_(f,e,n),e}};zl.names=["grid-template-areas"];vw.exports=zl});var Sw=v((jq,kw)=>{l();var nE=R(),Vl=class extends nE{set(e,t){return t==="-webkit-"&&(e.value=e.value.replace(/\s*(right|left)\s*/i,"")),super.set(e,t)}};Vl.names=["text-emphasis-position"];kw.exports=Vl});var Aw=v((zq,Cw)=>{l();var sE=R(),Ul=class extends sE{set(e,t){return e.prop==="text-decoration-skip-ink"&&e.value==="auto"?(e.prop=t+"text-decoration-skip",e.value="ink",e):super.set(e,t)}};Ul.names=["text-decoration-skip-ink","text-decoration-skip"];Cw.exports=Ul});var Dw=v((Vq,Pw)=>{l();"use strict";Pw.exports={wrap:_w,limit:Ew,validate:Ow,test:Wl,curry:aE,name:Tw};function _w(i,e,t){var r=e-i;return((t-i)%r+r)%r+i}function Ew(i,e,t){return Math.max(i,Math.min(e,t))}function Ow(i,e,t,r,n){if(!Wl(i,e,t,r,n))throw new Error(t+" is outside of range ["+i+","+e+")");return t}function Wl(i,e,t,r,n){return!(te||n&&t===e||r&&t===i)}function Tw(i,e,t,r){return(t?"(":"[")+i+","+e+(r?")":"]")}function aE(i,e,t,r){var n=Tw.bind(null,i,e,t,r);return{wrap:_w.bind(null,i,e),limit:Ew.bind(null,i,e),validate:function(a){return Ow(i,e,a,t,r)},test:function(a){return Wl(i,e,a,t,r)},toString:n,name:n}}});var Rw=v((Uq,qw)=>{l();var Gl=Yn(),oE=Dw(),lE=Wt(),uE=ke(),fE=ue(),Iw=/top|left|right|bottom/gi,Qe=class extends uE{replace(e,t){let r=Gl(e);for(let n of r.nodes)if(n.type==="function"&&n.value===this.name)if(n.nodes=this.newDirection(n.nodes),n.nodes=this.normalize(n.nodes),t==="-webkit- old"){if(!this.oldWebkit(n))return!1}else n.nodes=this.convertDirection(n.nodes),n.value=t+n.value;return r.toString()}replaceFirst(e,...t){return t.map(n=>n===" "?{type:"space",value:n}:{type:"word",value:n}).concat(e.slice(1))}normalizeUnit(e,t){return`${parseFloat(e)/t*360}deg`}normalize(e){if(!e[0])return e;if(/-?\d+(.\d+)?grad/.test(e[0].value))e[0].value=this.normalizeUnit(e[0].value,400);else if(/-?\d+(.\d+)?rad/.test(e[0].value))e[0].value=this.normalizeUnit(e[0].value,2*Math.PI);else if(/-?\d+(.\d+)?turn/.test(e[0].value))e[0].value=this.normalizeUnit(e[0].value,1);else if(e[0].value.includes("deg")){let t=parseFloat(e[0].value);t=oE.wrap(0,360,t),e[0].value=`${t}deg`}return e[0].value==="0deg"?e=this.replaceFirst(e,"to"," ","top"):e[0].value==="90deg"?e=this.replaceFirst(e,"to"," ","right"):e[0].value==="180deg"?e=this.replaceFirst(e,"to"," ","bottom"):e[0].value==="270deg"&&(e=this.replaceFirst(e,"to"," ","left")),e}newDirection(e){if(e[0].value==="to"||(Iw.lastIndex=0,!Iw.test(e[0].value)))return e;e.unshift({type:"word",value:"to"},{type:"space",value:" "});for(let t=2;t0&&(e[0].value==="to"?this.fixDirection(e):e[0].value.includes("deg")?this.fixAngle(e):this.isRadial(e)&&this.fixRadial(e)),e}fixDirection(e){e.splice(0,2);for(let t of e){if(t.type==="div")break;t.type==="word"&&(t.value=this.revertDirection(t.value))}}fixAngle(e){let t=e[0].value;t=parseFloat(t),t=Math.abs(450-t)%360,t=this.roundFloat(t,3),e[0].value=`${t}deg`}fixRadial(e){let t=[],r=[],n,a,s,o,u;for(o=0;o{l();var cE=Wt(),pE=ke();function Mw(i){return new RegExp(`(^|[\\s,(])(${i}($|[\\s),]))`,"gi")}var Hl=class extends pE{regexp(){return this.regexpCache||(this.regexpCache=Mw(this.name)),this.regexpCache}isStretch(){return this.name==="stretch"||this.name==="fill"||this.name==="fill-available"}replace(e,t){return t==="-moz-"&&this.isStretch()?e.replace(this.regexp(),"$1-moz-available$3"):t==="-webkit-"&&this.isStretch()?e.replace(this.regexp(),"$1-webkit-fill-available$3"):super.replace(e,t)}old(e){let t=e+this.name;return this.isStretch()&&(e==="-moz-"?t="-moz-available":e==="-webkit-"&&(t="-webkit-fill-available")),new cE(this.name,t,t,Mw(t))}add(e,t){if(!(e.prop.includes("grid")&&t!=="-webkit-"))return super.add(e,t)}};Hl.names=["max-content","min-content","fit-content","fill","fill-available","stretch"];Bw.exports=Hl});var $w=v((Gq,Lw)=>{l();var Nw=Wt(),dE=ke(),Yl=class extends dE{replace(e,t){return t==="-webkit-"?e.replace(this.regexp(),"$1-webkit-optimize-contrast"):t==="-moz-"?e.replace(this.regexp(),"$1-moz-crisp-edges"):super.replace(e,t)}old(e){return e==="-webkit-"?new Nw(this.name,"-webkit-optimize-contrast"):e==="-moz-"?new Nw(this.name,"-moz-crisp-edges"):super.old(e)}};Yl.names=["pixelated"];Lw.exports=Yl});var zw=v((Hq,jw)=>{l();var hE=ke(),Ql=class extends hE{replace(e,t){let r=super.replace(e,t);return t==="-webkit-"&&(r=r.replace(/("[^"]+"|'[^']+')(\s+\d+\w)/gi,"url($1)$2")),r}};Ql.names=["image-set"];jw.exports=Ql});var Uw=v((Yq,Vw)=>{l();var mE=me().list,gE=ke(),Jl=class extends gE{replace(e,t){return mE.space(e).map(r=>{if(r.slice(0,+this.name.length+1)!==this.name+"(")return r;let n=r.lastIndexOf(")"),a=r.slice(n+1),s=r.slice(this.name.length+1,n);if(t==="-webkit-"){let o=s.match(/\d*.?\d+%?/);o?(s=s.slice(o[0].length).trim(),s+=`, ${o[0]}`):s+=", 0.5"}return t+this.name+"("+s+")"+a}).join(" ")}};Jl.names=["cross-fade"];Vw.exports=Jl});var Gw=v((Qq,Ww)=>{l();var yE=de(),wE=Wt(),bE=ke(),Xl=class extends bE{constructor(e,t){super(e,t);e==="display-flex"&&(this.name="flex")}check(e){return e.prop==="display"&&e.value===this.name}prefixed(e){let t,r;return[t,e]=yE(e),t===2009?this.name==="flex"?r="box":r="inline-box":t===2012?this.name==="flex"?r="flexbox":r="inline-flexbox":t==="final"&&(r=this.name),e+r}replace(e,t){return this.prefixed(t)}old(e){let t=this.prefixed(e);if(!!t)return new wE(this.name,t)}};Xl.names=["display-flex","inline-flex"];Ww.exports=Xl});var Yw=v((Jq,Hw)=>{l();var vE=ke(),Kl=class extends vE{constructor(e,t){super(e,t);e==="display-grid"&&(this.name="grid")}check(e){return e.prop==="display"&&e.value===this.name}};Kl.names=["display-grid","inline-grid"];Hw.exports=Kl});var Jw=v((Xq,Qw)=>{l();var xE=ke(),Zl=class extends xE{constructor(e,t){super(e,t);e==="filter-function"&&(this.name="filter")}};Zl.names=["filter","filter-function"];Qw.exports=Zl});var eb=v((Kq,Zw)=>{l();var Xw=ii(),M=R(),Kw=qm(),kE=Xm(),SE=il(),CE=gg(),eu=ct(),tr=Gt(),AE=Cg(),$e=ke(),rr=ue(),_E=_g(),EE=Og(),OE=Pg(),TE=Ig(),PE=Fg(),DE=$g(),IE=zg(),qE=Ug(),RE=Gg(),ME=Yg(),BE=Jg(),FE=Kg(),NE=ey(),LE=ry(),$E=ny(),jE=oy(),zE=uy(),VE=py(),UE=hy(),WE=gy(),GE=by(),HE=xy(),YE=Cy(),QE=_y(),JE=Oy(),XE=Py(),KE=Iy(),ZE=My(),e5=Fy(),t5=Ly(),r5=jy(),i5=Vy(),n5=Wy(),s5=Hy(),a5=Jy(),o5=Ky(),l5=ew(),u5=rw(),f5=nw(),c5=ow(),p5=uw(),d5=cw(),h5=hw(),m5=gw(),g5=ww(),y5=xw(),w5=Sw(),b5=Aw(),v5=Rw(),x5=Fw(),k5=$w(),S5=zw(),C5=Uw(),A5=Gw(),_5=Yw(),E5=Jw();tr.hack(_E);tr.hack(EE);tr.hack(OE);tr.hack(TE);M.hack(PE);M.hack(DE);M.hack(IE);M.hack(qE);M.hack(RE);M.hack(ME);M.hack(BE);M.hack(FE);M.hack(NE);M.hack(LE);M.hack($E);M.hack(jE);M.hack(zE);M.hack(VE);M.hack(UE);M.hack(WE);M.hack(GE);M.hack(HE);M.hack(YE);M.hack(QE);M.hack(JE);M.hack(XE);M.hack(KE);M.hack(ZE);M.hack(e5);M.hack(t5);M.hack(r5);M.hack(i5);M.hack(n5);M.hack(s5);M.hack(a5);M.hack(o5);M.hack(l5);M.hack(u5);M.hack(f5);M.hack(c5);M.hack(p5);M.hack(d5);M.hack(h5);M.hack(m5);M.hack(g5);M.hack(y5);M.hack(w5);M.hack(b5);$e.hack(v5);$e.hack(x5);$e.hack(k5);$e.hack(S5);$e.hack(C5);$e.hack(A5);$e.hack(_5);$e.hack(E5);var tu=new Map,si=class{constructor(e,t,r={}){this.data=e,this.browsers=t,this.options=r,[this.add,this.remove]=this.preprocess(this.select(this.data)),this.transition=new kE(this),this.processor=new SE(this)}cleaner(){if(this.cleanerCache)return this.cleanerCache;if(this.browsers.selected.length){let e=new eu(this.browsers.data,[]);this.cleanerCache=new si(this.data,e,this.options)}else return this;return this.cleanerCache}select(e){let t={add:{},remove:{}};for(let r in e){let n=e[r],a=n.browsers.map(u=>{let c=u.split(" ");return{browser:`${c[0]} ${c[1]}`,note:c[2]}}),s=a.filter(u=>u.note).map(u=>`${this.browsers.prefix(u.browser)} ${u.note}`);s=rr.uniq(s),a=a.filter(u=>this.browsers.isSelected(u.browser)).map(u=>{let c=this.browsers.prefix(u.browser);return u.note?`${c} ${u.note}`:c}),a=this.sort(rr.uniq(a)),this.options.flexbox==="no-2009"&&(a=a.filter(u=>!u.includes("2009")));let o=n.browsers.map(u=>this.browsers.prefix(u));n.mistakes&&(o=o.concat(n.mistakes)),o=o.concat(s),o=rr.uniq(o),a.length?(t.add[r]=a,a.length!a.includes(u)))):t.remove[r]=o}return t}sort(e){return e.sort((t,r)=>{let n=rr.removeNote(t).length,a=rr.removeNote(r).length;return n===a?r.length-t.length:a-n})}preprocess(e){let t={selectors:[],"@supports":new CE(si,this)};for(let n in e.add){let a=e.add[n];if(n==="@keyframes"||n==="@viewport")t[n]=new AE(n,a,this);else if(n==="@resolution")t[n]=new Kw(n,a,this);else if(this.data[n].selector)t.selectors.push(tr.load(n,a,this));else{let s=this.data[n].props;if(s){let o=$e.load(n,a,this);for(let u of s)t[u]||(t[u]={values:[]}),t[u].values.push(o)}else{let o=t[n]&&t[n].values||[];t[n]=M.load(n,a,this),t[n].values=o}}}let r={selectors:[]};for(let n in e.remove){let a=e.remove[n];if(this.data[n].selector){let s=tr.load(n,a);for(let o of a)r.selectors.push(s.old(o))}else if(n==="@keyframes"||n==="@viewport")for(let s of a){let o=`@${s}${n.slice(1)}`;r[o]={remove:!0}}else if(n==="@resolution")r[n]=new Kw(n,a,this);else{let s=this.data[n].props;if(s){let o=$e.load(n,[],this);for(let u of a){let c=o.old(u);if(c)for(let f of s)r[f]||(r[f]={}),r[f].values||(r[f].values=[]),r[f].values.push(c)}}else for(let o of a){let u=this.decl(n).old(n,o);if(n==="align-self"){let c=t[n]&&t[n].prefixes;if(c){if(o==="-webkit- 2009"&&c.includes("-webkit-"))continue;if(o==="-webkit-"&&c.includes("-webkit- 2009"))continue}}for(let c of u)r[c]||(r[c]={}),r[c].remove=!0}}}return[t,r]}decl(e){return tu.has(e)||tu.set(e,M.load(e)),tu.get(e)}unprefixed(e){let t=this.normalize(Xw.unprefixed(e));return t==="flex-direction"&&(t="flex-flow"),t}normalize(e){return this.decl(e).normalize(e)}prefixed(e,t){return e=Xw.unprefixed(e),this.decl(e).prefixed(e,t)}values(e,t){let r=this[e],n=r["*"]&&r["*"].values,a=r[t]&&r[t].values;return n&&a?rr.uniq(n.concat(a)):n||a||[]}group(e){let t=e.parent,r=t.index(e),{length:n}=t.nodes,a=this.unprefixed(e.prop),s=(o,u)=>{for(r+=o;r>=0&&r{l();tb.exports={"backdrop-filter":{feature:"css-backdrop-filter",browsers:["ios_saf 16.1","ios_saf 16.3","ios_saf 16.4","ios_saf 16.5","safari 16.5"]},element:{props:["background","background-image","border-image","mask","list-style","list-style-image","content","mask-image"],feature:"css-element-function",browsers:["firefox 114"]},"user-select":{mistakes:["-khtml-"],feature:"user-select-none",browsers:["ios_saf 16.1","ios_saf 16.3","ios_saf 16.4","ios_saf 16.5","safari 16.5"]},"background-clip":{feature:"background-clip-text",browsers:["and_chr 114","and_uc 15.5","chrome 109","chrome 113","chrome 114","edge 114","opera 99","samsung 21"]},hyphens:{feature:"css-hyphens",browsers:["ios_saf 16.1","ios_saf 16.3","ios_saf 16.4","ios_saf 16.5","safari 16.5"]},fill:{props:["width","min-width","max-width","height","min-height","max-height","inline-size","min-inline-size","max-inline-size","block-size","min-block-size","max-block-size","grid","grid-template","grid-template-rows","grid-template-columns","grid-auto-columns","grid-auto-rows"],feature:"intrinsic-width",browsers:["and_chr 114","and_uc 15.5","chrome 109","chrome 113","chrome 114","edge 114","opera 99","samsung 21"]},"fill-available":{props:["width","min-width","max-width","height","min-height","max-height","inline-size","min-inline-size","max-inline-size","block-size","min-block-size","max-block-size","grid","grid-template","grid-template-rows","grid-template-columns","grid-auto-columns","grid-auto-rows"],feature:"intrinsic-width",browsers:["and_chr 114","and_uc 15.5","chrome 109","chrome 113","chrome 114","edge 114","opera 99","samsung 21"]},stretch:{props:["width","min-width","max-width","height","min-height","max-height","inline-size","min-inline-size","max-inline-size","block-size","min-block-size","max-block-size","grid","grid-template","grid-template-rows","grid-template-columns","grid-auto-columns","grid-auto-rows"],feature:"intrinsic-width",browsers:["firefox 114"]},"fit-content":{props:["width","min-width","max-width","height","min-height","max-height","inline-size","min-inline-size","max-inline-size","block-size","min-block-size","max-block-size","grid","grid-template","grid-template-rows","grid-template-columns","grid-auto-columns","grid-auto-rows"],feature:"intrinsic-width",browsers:["firefox 114"]},"text-decoration-style":{feature:"text-decoration",browsers:["ios_saf 16.1","ios_saf 16.3","ios_saf 16.4","ios_saf 16.5"]},"text-decoration-color":{feature:"text-decoration",browsers:["ios_saf 16.1","ios_saf 16.3","ios_saf 16.4","ios_saf 16.5"]},"text-decoration-line":{feature:"text-decoration",browsers:["ios_saf 16.1","ios_saf 16.3","ios_saf 16.4","ios_saf 16.5"]},"text-decoration":{feature:"text-decoration",browsers:["ios_saf 16.1","ios_saf 16.3","ios_saf 16.4","ios_saf 16.5"]},"text-decoration-skip":{feature:"text-decoration",browsers:["ios_saf 16.1","ios_saf 16.3","ios_saf 16.4","ios_saf 16.5"]},"text-decoration-skip-ink":{feature:"text-decoration",browsers:["ios_saf 16.1","ios_saf 16.3","ios_saf 16.4","ios_saf 16.5"]},"text-size-adjust":{feature:"text-size-adjust",browsers:["ios_saf 16.1","ios_saf 16.3","ios_saf 16.4","ios_saf 16.5"]},"mask-clip":{feature:"css-masks",browsers:["and_chr 114","and_uc 15.5","chrome 109","chrome 113","chrome 114","edge 114","opera 99","samsung 21"]},"mask-composite":{feature:"css-masks",browsers:["and_chr 114","and_uc 15.5","chrome 109","chrome 113","chrome 114","edge 114","opera 99","samsung 21"]},"mask-image":{feature:"css-masks",browsers:["and_chr 114","and_uc 15.5","chrome 109","chrome 113","chrome 114","edge 114","opera 99","samsung 21"]},"mask-origin":{feature:"css-masks",browsers:["and_chr 114","and_uc 15.5","chrome 109","chrome 113","chrome 114","edge 114","opera 99","samsung 21"]},"mask-repeat":{feature:"css-masks",browsers:["and_chr 114","and_uc 15.5","chrome 109","chrome 113","chrome 114","edge 114","opera 99","samsung 21"]},"mask-border-repeat":{feature:"css-masks",browsers:["and_chr 114","and_uc 15.5","chrome 109","chrome 113","chrome 114","edge 114","opera 99","samsung 21"]},"mask-border-source":{feature:"css-masks",browsers:["and_chr 114","and_uc 15.5","chrome 109","chrome 113","chrome 114","edge 114","opera 99","samsung 21"]},mask:{feature:"css-masks",browsers:["and_chr 114","and_uc 15.5","chrome 109","chrome 113","chrome 114","edge 114","opera 99","samsung 21"]},"mask-position":{feature:"css-masks",browsers:["and_chr 114","and_uc 15.5","chrome 109","chrome 113","chrome 114","edge 114","opera 99","samsung 21"]},"mask-size":{feature:"css-masks",browsers:["and_chr 114","and_uc 15.5","chrome 109","chrome 113","chrome 114","edge 114","opera 99","samsung 21"]},"mask-border":{feature:"css-masks",browsers:["and_chr 114","and_uc 15.5","chrome 109","chrome 113","chrome 114","edge 114","opera 99","samsung 21"]},"mask-border-outset":{feature:"css-masks",browsers:["and_chr 114","and_uc 15.5","chrome 109","chrome 113","chrome 114","edge 114","opera 99","samsung 21"]},"mask-border-width":{feature:"css-masks",browsers:["and_chr 114","and_uc 15.5","chrome 109","chrome 113","chrome 114","edge 114","opera 99","samsung 21"]},"mask-border-slice":{feature:"css-masks",browsers:["and_chr 114","and_uc 15.5","chrome 109","chrome 113","chrome 114","edge 114","opera 99","samsung 21"]},"clip-path":{feature:"css-clip-path",browsers:["samsung 21"]},"box-decoration-break":{feature:"css-boxdecorationbreak",browsers:["and_chr 114","and_uc 15.5","chrome 109","chrome 113","chrome 114","edge 114","ios_saf 16.1","ios_saf 16.3","ios_saf 16.4","ios_saf 16.5","opera 99","safari 16.5","samsung 21"]},appearance:{feature:"css-appearance",browsers:["samsung 21"]},"image-set":{props:["background","background-image","border-image","cursor","mask","mask-image","list-style","list-style-image","content"],feature:"css-image-set",browsers:["and_uc 15.5","chrome 109","samsung 21"]},"cross-fade":{props:["background","background-image","border-image","mask","list-style","list-style-image","content","mask-image"],feature:"css-cross-fade",browsers:["and_chr 114","and_uc 15.5","chrome 109","chrome 113","chrome 114","edge 114","opera 99","samsung 21"]},isolate:{props:["unicode-bidi"],feature:"css-unicode-bidi",browsers:["ios_saf 16.1","ios_saf 16.3","ios_saf 16.4","ios_saf 16.5","safari 16.5"]},"color-adjust":{feature:"css-color-adjust",browsers:["chrome 109","chrome 113","chrome 114","edge 114","opera 99"]}}});var nb=v((e6,ib)=>{l();ib.exports={}});var lb=v((t6,ob)=>{l();var O5=Wo(),{agents:T5}=(zn(),jn),ru=bm(),P5=ct(),D5=eb(),I5=rb(),q5=nb(),sb={browsers:T5,prefixes:I5},ab=` + Replace Autoprefixer \`browsers\` option to Browserslist config. + Use \`browserslist\` key in \`package.json\` or \`.browserslistrc\` file. + + Using \`browsers\` option can cause errors. Browserslist config can + be used for Babel, Autoprefixer, postcss-normalize and other tools. + + If you really need to use option, rename it to \`overrideBrowserslist\`. + + Learn more at: + https://github.com/browserslist/browserslist#readme + https://twitter.com/browserslist + +`;function R5(i){return Object.prototype.toString.apply(i)==="[object Object]"}var iu=new Map;function M5(i,e){e.browsers.selected.length!==0&&(e.add.selectors.length>0||Object.keys(e.add).length>2||i.warn(`Autoprefixer target browsers do not need any prefixes.You do not need Autoprefixer anymore. +Check your Browserslist config to be sure that your targets are set up correctly. + + Learn more at: + https://github.com/postcss/autoprefixer#readme + https://github.com/browserslist/browserslist#readme + +`))}ob.exports=ir;function ir(...i){let e;if(i.length===1&&R5(i[0])?(e=i[0],i=void 0):i.length===0||i.length===1&&!i[0]?i=void 0:i.length<=2&&(Array.isArray(i[0])||!i[0])?(e=i[1],i=i[0]):typeof i[i.length-1]=="object"&&(e=i.pop()),e||(e={}),e.browser)throw new Error("Change `browser` option to `overrideBrowserslist` in Autoprefixer");if(e.browserslist)throw new Error("Change `browserslist` option to `overrideBrowserslist` in Autoprefixer");e.overrideBrowserslist?i=e.overrideBrowserslist:e.browsers&&(typeof console!="undefined"&&console.warn&&(ru.red?console.warn(ru.red(ab.replace(/`[^`]+`/g,n=>ru.yellow(n.slice(1,-1))))):console.warn(ab)),i=e.browsers);let t={ignoreUnknownVersions:e.ignoreUnknownVersions,stats:e.stats,env:e.env};function r(n){let a=sb,s=new P5(a.browsers,i,n,t),o=s.selected.join(", ")+JSON.stringify(e);return iu.has(o)||iu.set(o,new D5(a.prefixes,s,e)),iu.get(o)}return{postcssPlugin:"autoprefixer",prepare(n){let a=r({from:n.opts.from,env:e.env});return{OnceExit(s){M5(n,a),e.remove!==!1&&a.processor.remove(s,n),e.add!==!1&&a.processor.add(s,n)}}},info(n){return n=n||{},n.from=n.from||m.cwd(),q5(r(n))},options:e,browsers:i}}ir.postcss=!0;ir.data=sb;ir.defaults=O5.defaults;ir.info=()=>ir().info()});var ub={};Ae(ub,{default:()=>B5});var B5,fb=C(()=>{l();B5=[]});var pb={};Ae(pb,{default:()=>F5});var cb,F5,db=C(()=>{l();hi();cb=K(bi()),F5=Ze(cb.default.theme)});var mb={};Ae(mb,{default:()=>N5});var hb,N5,gb=C(()=>{l();hi();hb=K(bi()),N5=Ze(hb.default)});l();"use strict";var L5=Je(ym()),$5=Je(me()),j5=Je(lb()),z5=Je((fb(),ub)),V5=Je((db(),pb)),U5=Je((gb(),mb)),W5=Je((ts(),ku)),G5=Je((bo(),wo)),H5=Je((gs(),rf));function Je(i){return i&&i.__esModule?i:{default:i}}console.warn("cdn.tailwindcss.com should not be used in production. To use Tailwind CSS in production, install it as a PostCSS plugin or use the Tailwind CLI: https://tailwindcss.com/docs/installation");var Qn="tailwind",nu="text/tailwindcss",yb="/template.html",vt,wb=!0,bb=0,su=new Set,au,vb="",xb=(i=!1)=>({get(e,t){return(!i||t==="config")&&typeof e[t]=="object"&&e[t]!==null?new Proxy(e[t],xb()):e[t]},set(e,t,r){return e[t]=r,(!i||t==="config")&&ou(!0),!0}});window[Qn]=new Proxy({config:{},defaultTheme:V5.default,defaultConfig:U5.default,colors:W5.default,plugin:G5.default,resolveConfig:H5.default},xb(!0));function kb(i){au.observe(i,{attributes:!0,attributeFilter:["type"],characterData:!0,subtree:!0,childList:!0})}new MutationObserver(async i=>{let e=!1;if(!au){au=new MutationObserver(async()=>await ou(!0));for(let t of document.querySelectorAll(`style[type="${nu}"]`))kb(t)}for(let t of i)for(let r of t.addedNodes)r.nodeType===1&&r.tagName==="STYLE"&&r.getAttribute("type")===nu&&(kb(r),e=!0);await ou(e)}).observe(document.documentElement,{attributes:!0,attributeFilter:["class"],childList:!0,subtree:!0});async function ou(i=!1){i&&(bb++,su.clear());let e="";for(let r of document.querySelectorAll(`style[type="${nu}"]`))e+=r.textContent;let t=new Set;for(let r of document.querySelectorAll("[class]"))for(let n of r.classList)su.has(n)||t.add(n);if(document.body&&(wb||t.size>0||e!==vb||!vt||!vt.isConnected)){for(let n of t)su.add(n);wb=!1,vb=e,self[yb]=Array.from(t).join(" ");let{css:r}=await(0,$5.default)([(0,L5.default)({...window[Qn].config,_hash:bb,content:[yb],plugins:[...z5.default,...Array.isArray(window[Qn].config.plugins)?window[Qn].config.plugins:[]]}),(0,j5.default)({remove:!1})]).process(`@tailwind base;@tailwind components;@tailwind utilities;${e}`);(!vt||!vt.isConnected)&&(vt=document.createElement("style"),document.head.append(vt)),vt.textContent=r}}})(); +/*! https://mths.be/cssesc v3.0.0 by @mathias */ \ No newline at end of file diff --git a/maixcdk/static/css/theme_default/dark.css b/maixcdk/static/css/theme_default/dark.css new file mode 100644 index 00000000..daf5799e --- /dev/null +++ b/maixcdk/static/css/theme_default/dark.css @@ -0,0 +1,169 @@ +/** + teedoc light theme css + @author neucrack + @copyright (c) neucrack CZD666666@gmail.com with MIT License + @changes 2021.1.27 add basic attrributes + */ + + /* + use .dark class to cover light theme style + */ + +/* global template */ +.dark body { + color: #d1d1d1; + background-color: #1b1b1b; +} +.dark a { + color: #8a8a8a; +} +.dark a:visited { + color: #8a8a8a; +} +.dark code { + background-color: #2a2a2a; +} +.dark pre[class*="language-"].line-numbers > code { + background: none; + padding: 0; +} +.dark #navbar .sub_items ul { + box-shadow: 0 0 9px 0px #000000; + background-color: #232323; +} +.dark #sidebar .active > a, +.dark #navbar .active > a { + background-color: #2d2d2d; + color: #1f8dbf; +} +.dark #sidebar .active > a, +.dark #navbar .active > a, +.dark #navbar .active_parent > a { + background-color: #2d2d2d; +} +.dark #sidebar li > a:hover, +.dark #sidebar li.active_parent > a:hover, +.dark #navbar li > a:hover, +.dark #navbar .sub_items > a:hover { + background-color: #2d2d2d; +} +.dark #sidebar ul .active_parent > a { + background-color: #232323; +} +.dark .gutter.gutter-horizontal { + background-color: #484848; +} +.dark *::-webkit-scrollbar-track { + background: #484848; +} +.dark *::-webkit-scrollbar-thumb { + background-color: #6b6b6b; +} +.dark #article #toc { + background-color: #1b1b1b; +} +.dark #to_top { + background-color: #2d2d2d; + box-shadow: 8px 8px 20px #000000; +} +.dark #to_top:hover { + box-shadow: 8px 8px 28px #000000; +} +.dark #to_top:active { + box-shadow: 0px 0px 20px #000000; +} +.dark blockquote { + background-color: #2d2d2d; +} +.dark blockquote.spoiler { + border-left: 5px solid #FF9800; + background-color: #6e5200; + color: white; +} +.dark td { + background-color: #373737; + border: 2px solid #555555; +} +.dark th { + font-weight: 700; + background-color: #0f5943; + color: white; + border: 2px solid #006f4f; +} +.dark sup a { + background-color: #2d2d2d; +} +.dark a:hover { + background-color: #424242; +} +.dark #doc_footer { + background-color: #2d2d2d; + border-top: 1px solid #2d2d2d; +} +.dark #page_footer { + background-color: #2d2d2d; + border-top: 1px solid #2d2d2d; +} +.dark #footer a:hover { + background-color: #404040; +} +.dark #previous_next { + border-top: 1px solid #525252; +} +.dark #previous_next a { + background-color: #2d2d2d; +} + +/* google translate */ +.dark #navbar #google_translate_element .goog-te-gadget-simple { + background-color: #1b1b1b; +} +.dark #navbar #google_translate_element .goog-te-gadget-simple .goog-te-menu-value { + color: #8a8a8a; +} + +/* tabset */ +.dark .tabset { + border: 0.2em solid #4c4c4c; +} +.dark .tabset-text-container { + background-color: #212121; +} +.dark .tabset-tab-active { + background-color: #212121; +} + +/* details */ +.dark details { + border: 0.2em solid #4c4c4c; +} +.dark details > .details-content { + background-color: #212121; +} + +/* markdown */ +.dark #mermaid-1662893106119 .messageText { + fill: #6f6f6f; + stroke: #6f6f6f; +} +#mermaid-1662893106119 .loopText, #mermaid-1662893106119 .loopText>tspan { + fill: #a99b1a; + stroke: none; +} + +@media screen and (max-width: 900px) { + .dark #menu_wrapper.m_menu_fixed { + background-color: rgb(27, 27, 27, 0.9); + box-shadow: 0px 1px 10px 0px rgb(0, 0, 0, 0.32); + } + .dark #sidebar_wrapper { + background-color: #1b1b1b; + } + .dark #navbar { + display: block; + border-bottom: 1px solid #383838; + z-index: 89; + } +} + + diff --git a/maixcdk/static/css/theme_default/light.css b/maixcdk/static/css/theme_default/light.css new file mode 100644 index 00000000..d0f0bbf3 --- /dev/null +++ b/maixcdk/static/css/theme_default/light.css @@ -0,0 +1,1349 @@ +/** + teedoc light theme css + @author neucrack + @copyright (c) neucrack CZD666666@gmail.com with MIT License + @changes 2021.1.26 add basic attrributes + */ + +/* global template */ +body { + color: #606975; + background-color: white; + transition: 0.4s; + margin: 0; + display: flex; + flex-direction: column; + justify-content: space-between; + min-height: 100vh; + letter-spacing: 0.03em; + font-family: "Microsoft YaHei",Helvetica,"Meiryo UI","Malgun Gothic","Segoe UI","Trebuchet MS",Monaco,monospace,Tahoma,STXihei,"华文细黑",STHeiti,"Helvetica Neue","Droid Sans","wenquanyi micro hei",FreeSans,Arimo,Arial,SimSun,"宋体",Heiti,"黑体",sans-serif; +} +a { + color: #606975; + text-decoration: none; +} +a:visited { + color: #606975; +} +a:hover { + background-color: #d8d8d8; + border-radius: 5px; + transition: 0.4s; +} +h1 { + text-align: center; + font-size: 2.2em; +} +h2 { + font-size: 2em; +} +h3 { + font-size: 1.5em; +} +h4 { + font-size: 1.17em; +} +h5 { + font-size: 1em; +} +h6 { + font-size: 0.83em; +} + +p { + /* text-align: justify; */ + line-height: 2em; +} +blockquote { + border-left: 4px solid #1f8dbf; + margin: 0 0 1em 2px; + padding: 1px; + padding-left: 1em; + background-color: #f1f1f1; + border-radius: 0 5px 5px 0; + transition: 0.4s; +} +blockquote.spoiler { + border-left: 5px solid #FF9800; + background-color: #ffd65b; +} +*::-webkit-scrollbar { + width : 0.8rem; + height: 0.8rem; + min-width: 0.8rem; + min-height: 0.6rem; +} +#sidebar ul::-webkit-scrollbar { + width : 0.45rem; + height: 0.8rem; + min-width: 0.45rem; + min-height: 0.6rem; +} +*::-webkit-scrollbar-thumb { + border-radius : 0.6rem; + background-color: #b8b8b8; +} +*::-webkit-scrollbar-track { + background : #ededed; + border-radius: 10px; +} +sup a { + font-size: 1.1em; + background-color: #f1f1f1; + padding: 4px; + border-left: 1px solid #1f8dbf; + border-right: 1px solid #1f8dbf; +} +dl > dt { + font-weight: bold; +} +table { + border-collapse: collapse; + border-spacing: 0; + display: block; + width: 100%; + overflow: auto; + word-break: keep-all; + border-color: transparent; +} +tr { + background-color: #f1f1f1; + border-top: 1px solid #ccc; +} +td, th { + padding: 6px 13px; + transition: 0.4s; +} +th { + font-weight: 700; + color: white; + filter: brightness(110%); + border: 2px solid #1f8dbf; + background-color: #1f8dbf; +} +td { + background-color: #fbfbfb; + border: 2px solid #f1f1f1; +} +code { + background-color: #f1f1f1; + border-radius: 0.2em; + transition: 0.4s; + font-family: Menlo, Consolas, "DejaVu Sans Mono", Bitstream Vera Sans Mono, Courier New, monospace, Monaco, 'Andale Mono', 'Ubuntu Mono', "Microsoft YaHei"; + font-size: 85%; + padding: 0.2em 0.4em; + color: #1f8dbf; +} +pre[class*="language-"].line-numbers > code { + background: none; + padding: 0; +} +.btn, +#page_content .btn, +#content_body .btn { + color: white; + border-radius: 5px; + transition: 0.2s; + padding: 1em; + cursor: pointer; + transition: 0.2s; + background: #1f8dbf; + box-shadow: 1px 1px 2px 0px #1f8dbf; +} +.btn:hover, +#page_content .btn:hover, +#content_body .btn:hover { + background: #1f8dbf; + box-shadow: 1px 1px 8px 0px #1f8dbf; +} +.btn:visited, +#page_content .btn:visited, +#content_body .btn:visited { + color: white; +} + +/* wrapper */ +.type_doc #wrapper { + margin-top: 1.5em; +} +#wrapper { + display: flex; + flex-grow: 1; +} +#page_wrapper { + display: flex; + flex-grow: 1; + flex-direction: column; + justify-content: space-between; + text-align: center; +} + +/* page */ +#page_content { + width: 100%; + flex-grow: 1; + display: flex; + flex-direction: row; +} +#page_content > div { + flex-grow: 1; + align-self: center; +} +#page_content a { + color: #c33a3a; +} + +/* navbar */ +#navbar { + display: flex; + justify-content: start; + z-index: 100; +} +#navbar * { + display: flex; + align-items: center; +} +#navbar_menu_btn { + display: none; +} +#navbar #navbar_items { + display: flex; + flex-grow: 1; + justify-content: space-between; + padding-right: 1em; + word-break: keep-all; +} +#navbar h2 { + color: #1f8dbf; +} +#navbar a{ + margin: 5px; + padding: 10px 15px; + cursor: pointer; +} +#navbar a.site_title{ + padding: 0; +} +#navbar a.site_title:hover{ + background-color: transparent; +} +#navbar .site_logo { + max-height: 60px; +} +#navbar ul { + list-style: none; + padding-inline-start: 10px; +} +#navbar .sub_items { + position: relative; + display: block; +} +#navbar .sub_items > a { + margin: 5px; + padding: 10px 15px; +} +#navbar .sub_items > a:hover + ul { + visibility: visible; +} +#navbar .sub_items ul { + display: block; + position: absolute; + left: 0; + box-shadow: 0 0 9px 0px #dadada; + border-radius: 5px; + padding: 0; + width: max-content; + min-width: 100%; + background-color: white; + visibility: hidden; + margin-top: -5px; + z-index: 101; + transition: 0.2s; +} +#navbar .sub_items ul:hover { + visibility: visible; +} +#navbar .sub_items ul li { + display: block; +} + +#navbar .sub_items ul ul { + left: 100%; + top: 0; +} + + +/* sidebar */ +#sidebar_wrapper { + width: 300px; +} +/* sidebar splitter */ +.gutter_icon { + background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAeCAYAAADkftS9AAAAIklEQVQoU2M4c+bMfxAGAgYYmwGrIIiDjrELjpo5aiZeMwF+yNnOs5KSvgAAAABJRU5ErkJggg==); + width: 3px; + height: 2em; + background-repeat: no-repeat; + position: fixed; + top: 50%; +} +.gutter { + background-color: #eee; + background-repeat: no-repeat; + background-position: 50%; + transition: 0.2s; + border-radius: 5px; + display: block; +} + +.gutter.gutter-horizontal { + /* background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAeCAYAAADkftS9AAAAIklEQVQoU2M4c+bMfxAGAgYYmwGrIIiDjrELjpo5aiZeMwF+yNnOs5KSvgAAAABJRU5ErkJggg=='); */ + cursor: col-resize; +} + +#sidebar { + /* width: 300px; + min-width: 200px; + position: sticky; + top: 0; + overflow-x: hidden; */ + /* min-width: 200px; */ + /* position: sticky; */ + /* top: 0; */ + /* overflow-x: hidden; */ + display: flex; + flex-direction: column; + height: 100vh; + position: -webkit-sticky; + position: sticky; + top: 0; + padding-top: var(--ifm-navbar-height); + /* width: var(--doc-sidebar-width); */ + transition: opacity 50ms; + padding-top: 0; + z-index: 1; +} +#sidebar ul { + padding-inline-start: 20px; + display: none; +} +#sidebar > ul { + padding-inline-start: 0; + padding: .5rem; + display: block; + padding-bottom: 3em; + margin: 0; + overflow-y: auto; + overflow-x: hidden; +} +#sidebar ul .show{ + /* display: block; */ /* js instead, just reserve this item*/ +} +#sidebar ul .active_parent { + display: block; +} +#sidebar ul .active_parent > ul{ + display: block; +} +#sidebar ul.collapsed, #sidebar ul .active_parent > ul.collapsed{ + /* display: none; */ /* js instead, just reserve this item*/ +} +#sidebar ul .active_parent > a{ + background-color: #f1f1f1; + border-radius: 5px; + transition: 0.4s; +} +#sidebar li { + list-style: none; + margin: 2px 0; + position: relative; +} +#sidebar li > a { + display: flex; + justify-content: space-between; + padding: 0; + font-size: 0.9em; +} +#sidebar a:hover { + cursor: pointer; +} +#sidebar .active > a, #navbar .active > a, #navbar .active_parent > a{ + background-color: #f1f1f1; + border-radius: 5px; + color: #1f8dbf; + transition: 0.4s; +} +#navbar .sub_items .active > a { + transition: 0s; +} +#sidebar .active > a { + transition: 0.4s; +} +#sidebar li > a > .label { + padding: 10px; + display: inline-block; + white-space: nowrap; + width: 100%; + overflow: hidden; + text-overflow: ellipsis; +} + +#sidebar li > a:hover, +#sidebar li.active_parent > a:hover, +#navbar li > a:hover, +#navbar .sub_items > a:hover{ + background-color: #d8d8d8; + border-radius: 5px; + transition: 0.4s; +} +#sidebar .sub_indicator { + transition: transform 0.4s linear; + background: url("/maixcdk/static/image/theme_default/indicator.svg"); + background-size: contain; + background-repeat: no-repeat; + background-position: center; + align-self: center; + height: 1.25rem; + width: 1.25rem; + -ms-transform: rotate(-45deg); + -moz-transform: rotate(-45deg); + -webkit-transform: rotate(-45deg); + transform: rotate(-45deg); + transition: 0.2s; +} + +#sidebar .sub_indicator:hover, +#sidebar li.no_link > a:hover > .sub_indicator, +#sidebar li.no_link > a.sub_indicator:hover, +#sidebar li.no_link > a.sub_indicator{ + height: 1.6em; + width: 1.6em; +} +#sidebar .sub_indicator_collapsed { + -ms-transform: rotate(0deg); + -moz-transform: rotate(0deg); + -webkit-transform: rotate(0deg); + transform: rotate(0deg); +} +#sidebar li.sidebar_category { + font-size: 0.9em; + color: #9e9e9e; + margin: 1em 0 0.1em 0; +} +#sidebar .tip { + position: fixed; + color: white; + left: 300px; + top: 18%; + box-shadow: 0px 0px 8px 0px rgba(0, 0, 0, 0.19); + border-radius: 0.2em; + padding: 1em; + display: flex; + flex-direction: column; + width: max-content; + transition: 0.4s; + visibility: hidden; + opacity: 0; + background: #1f8dbf; +} +#sidebar li > a:hover+.tip, #sidebar .tip:hover { + visibility: visible; + opacity: 1; +} +.blog_info > span { + margin: 0.4em; +} +.blog_tags { + text-align: center; + margin-top: 1em; +} +.blog_tags > span { + border-radius: 0.2em; + padding: 0.2em; + margin: 0.4em; + filter: brightness(120%); + border: 1px solid #1f8dbf; +} +#blog_list > ul { + padding-left: 0; +} +#blog_list > ul > li { + list-style: none; + box-shadow: 0px 0px 7px #00000033; + margin: 2em 1em; + padding: 2em; + border-radius: 0.4em; +} +#blog_list > ul > li a, #blog_list > ul > li a:visited { + padding: 0; + color: #1f8dbf; +} +html[lang^=zh] #article_content #blog_list h2:before { + content: ""; +} +#blog_list .blog_tags { + text-align: left; +} +#blog_list .blog_info { + color: #ababab; +} +#blog_list .blog_brief { + color: #828282; +} +.blog_cover { + text-align: center; + margin-top: 1em; +} +.blog_cover > img { + width: 100%; +} +#menu_wrapper { + width: 2%; +} +#menu { + background: url("/maixcdk/static/image/theme_default/menu.svg"); + background-size: contain; + background-repeat: no-repeat; + background-position: center; + border-radius: 5px; + min-height: 2rem; + min-width: 2rem; + transition: 0.2s; + cursor: pointer; + position: sticky; + top: 1em; + z-index: 99; + margin-left: 0.2em; +} + +/* article */ +#article { + display: flex; + width: 98%; + margin: auto; + justify-content: space-evenly; +} +#toc_wrapper { + width: 25%; +} +#article #toc { + background-color: white; + position: sticky; + transition: 0.4s; + top: 15%; + max-height: calc(100vh - 15vh); + overflow-y: auto; +} +#article #toc a{ + padding: 0.2em 0.0em; + display: block; + font-size: 0.9em; +} +#article #toc ul, #article #toc ol { + list-style: none; + padding-left: 1.5em; +} +#article #toc > div > ul, #article #toc > div > ol { + padding-left: 1em; +} + +/* add numbers for toc */ +#toc {counter-reset: toc_l1;} +#toc #toc_content {counter-reset: toc_l2;} +#toc a.node-name--H1 { + counter-reset: toc_l2; +} +#toc a.node-name--H2 { + counter-reset: toc_l3; +} +#toc a.node-name--H1:before { + counter-increment: toc_l1; +} +#toc a.node-name--H2:before { + counter-increment: toc_l2; + content: counter(toc_l2, decimal) ".\00a0"; +} +html[lang^=zh] #toc a.node-name--H2:before { + counter-increment: toc_l2; + content: counter(toc_l2, simp-chinese-informal) "、"; +} +#toc a.node-name--H3:before { + counter-increment: toc_l3; + content: counter(toc_l2, decimal) "." counter(toc_l3, decimal) ".\00a0"; +} +.heading_no_counter #toc a.node-name--H2:before { + content: ""; +} +.heading_no_counter #toc a.node-name--H3:before { + content: ""; +} +html[lang^=zh].heading_no_counter #toc a.node-name--H2:before { + content: ""; +} +/* add numbers for titles toc*/ + + +/* article content */ +#content_wrapper { + flex-grow: 1; + justify-content: space-between; + flex-direction: column; + display: flex; + width: 65%; +} +#content_body { + max-width: 50em; + width: 90%; + display: flex; + flex-direction: column; + justify-content: space-between; + line-height: 2em; + margin: auto; +} +#content_body h1 { + line-height: initial; +} +#content_body a, #content_body a:visited { + color: #c33a3a; + padding: 0.2em; +} +#content_body a:hover { + background-color: #fde1e1; + padding: 0.2em; + border-radius: 0.2em; +} +#content_body img { + max-width: 100%; + object-fit: contain; + cursor: zoom-in; +} + +/* add numbers for titles */ +#article_content { + /* counter-reset: h2section h3section h4section; */ + min-height: 50vh; + word-break: break-word; +} +#article_content h1 { + /* counter-reset: h2section h3section h4section; */ + line-height: 1.3em; +} +#article_content h2 { + /* counter-reset: h3section h4section; */ + line-height: 1.3em; +} +/* #article_content h3 { + counter-reset: h4section; +} +#article_content h2:before +{ + counter-increment: h2section; + content: counter(h2section, upper-roman) "、"; +} +#article_content h3:before +{ + counter-increment: h3section; + content: counter(h2section, decimal) "." counter(h3section, decimal) "、"; +} +#article_content h4:before +{ + counter-increment: h4section; + content: counter(h2section, decimal) "." counter(h3section, decimal) "." counter(h4section, decimal) "、"; +} +html[lang^=zh] #article_content h2:before { + content: counter(h2section, simp-chinese-informal) "、"; +} +html[lang^=zh] #article_content h3:before { + content: counter(h2section, decimal) "." counter(h3section, decimal) "、"; +} +html[lang^=zh] #article_content h4:before { + content: counter(h2section, decimal) "." counter(h3section, decimal) "." counter(h4section, decimal) "、"; +} +.heading_no_counter #article_content h2:before { + content: ""; +} +.heading_no_counter #article_content h3:before { + content: ""; +} +.heading_no_counter #article_content h4:before { + content: ""; +} +html[lang^=zh].heading_no_counter #article_content h2:before { + content: ""; +} +html[lang^=zh].heading_no_counter #article_content h3:before { + content: ""; +} +html[lang^=zh].heading_no_counter #article_content h4:before { + content: ""; +} */ +/* add numbers for titles end*/ + +#article_head { + margin-bottom: 2em; +} +#article_tags ul { + list-style: none; + display: flex; + align-items: baseline; + justify-content: flex-end; + padding: 0 +} +#article_tags ul li{ + margin: 5px; + padding: 8px; + border-radius: 5px; + color: #ffffffcc; + font-size: 0.9em; + background-color: #1f8dbf; +} +#article_info { + display: flex; + flex-direction: row; + justify-content: space-between; +} +#article_info > div { + align-self: center; + display: flex; + flex-direction: row; + align-items: center; +} +#article_info > div > div { + margin: 2px; +} +#article_info #print_page { + height: 1em; + width: 1em; + cursor: pointer; + background-repeat: no-repeat; + background-size: contain; + background-image: url("/maixcdk/static/image/theme_default/print.svg"); +} +#article_info>div>span { + padding: 0.2em; + color: #1f8dbf; +} +#source_link { + display: flex; + flex-direction: row; + justify-content: flex-end; +} + +/* cover prism.css */ + +:not(pre) > code[class*="language-"], pre[class*="language-"] { + background: #2d2d2d; + border-radius: 5px; +} +div.code-toolbar > .toolbar a, div.code-toolbar > .toolbar button, div.code-toolbar > .toolbar span { + color: #fff; + font-size: .8em; + padding: 1em; + background: #f5f2f0; + background: rgba(224, 224, 224, 0.2); + box-shadow: 0 2px 0 0 rgba(0,0,0,0.2); + border-radius: .5em; + cursor: pointer; +} +div.code-toolbar > .toolbar a:hover, div.code-toolbar > .toolbar a:focus, div.code-toolbar > .toolbar button:hover, div.code-toolbar > .toolbar button:focus, div.code-toolbar > .toolbar span:hover, div.code-toolbar > .toolbar span:focus { + color: #a9ffe0; + text-decoration: none; +} + +/* back to top button */ +/* #to_top_wrapper { +} */ +#to_top { + background: url("/maixcdk/static/image/theme_default/to-top.svg"); + background-size: 2em; + background-repeat: no-repeat; + background-position: center; + align-self: flex-end; + position: sticky; + bottom: 6em; + right: 3em; + margin: 1em; + height: 3rem; + width: 3rem; + cursor: pointer; + transition: 0.4s; + z-index: 97; + border-radius: 100%; + padding: 2px; + background-color: #f1f1f1; + box-shadow: 8px 8px 20px rgba(0,0,0,0.13); +} +#to_top:hover { + background-size: 2.5em; + box-shadow: 8px 8px 20px rgba(0,0,0,0.24); +} +#to_top:active { + box-shadow: 0px 0px 20px rgba(0,0,0,0.05); +} + + +/* footer article */ +#previous_next { + min-height: 3em; + margin-top: 2em; + display: flex; + border-top: 1px solid #f1f1f1; + padding: 1em; + transition: 0.4s; + display: flex; + justify-content: space-between; +} +#previous_next > div { + margin: 1em; +} +#previous_next a{ + padding: 1em; + border-radius: 5px; + display: flex; + align-items: center; + background-color: #f1f1f1; + justify-content: flex-start; +} +#previous_next a:hover { + background-color: #dedede; +} +#previous_next #previous a > .label{ + flex-grow: 1; + text-align: center; + padding-right: 2.5em; +} +#previous_next #previous a > .icon{ + transition: transform 0.4s linear; + background: url("/maixcdk/static/image/theme_default/to-top.svg"); + background-size: 2em; + background-repeat: no-repeat; + background-position: center; + min-height: 2.5rem; + min-width: 2.5rem; + -ms-transform: rotate(-90deg); + -moz-transform: rotate(-90deg); + -webkit-transform: rotate(-90deg); + transform: rotate(-90deg); + padding-right: 2em; + padding: 0; +} +#previous_next #next a { + justify-content: flex-end; +} +#previous_next #next a > .label{ + flex-grow: 1; + text-align: center; + padding-left: 2.5em; +} +#previous_next #next a > .icon{ + transition: transform 0.4s linear; + background: url("/maixcdk/static/image/theme_default/to-top.svg"); + background-size: 2em; + background-repeat: no-repeat; + background-position: center; + min-height: 2.5rem; + min-width: 2.5rem; + -ms-transform: rotate(90deg); + -moz-transform: rotate(90deg); + -webkit-transform: rotate(90deg); + transform: rotate(90deg); + padding-left: 2em; + padding: 0; +} +.footnotes { + margin-top: 5em; +} +#doc_footer { + min-height: 2em; + display: flex; + background-color: #2d2d2d; + border-top: 1px solid #2d2d2d; + padding: 1em; + transition: 0.4s; +} +#page_footer { + min-height: 2em; + /* margin-top: 5em; */ + display: flex; + padding: 1em; + transition: 0.4s; + background-color: #292929; +} +#footer { + display: flex; + flex-direction: column; + align-items: center; + width: 100%; + line-height: 1em; +} +#footer ul { + list-style: none; + padding: 0; + margin: 0; +} +#footer a, #footer a:visited{ + color: #848fa0; + display: flex; + padding: 0.2em; + font-size: 0.9em; +} +#footer a:hover { + background-color: #e6e6e6; + border-radius: 0.1em; + padding: 0.2em; +} +#footer_top { + width: 100%; +} +#footer_top > ul { + display: flex; + justify-content: space-around; + flex-direction: row; +} +#footer_top > ul > li > a { + color: #cecece; + font-weight: 700; + margin: 1em 0 0.5em 0; +} +#footer_top > ul > li > a:hover { + background-color: transparent; +} +#footer_bottom { + margin-top: 2em; +} +#footer_bottom a { + justify-content: center; +} + +/* TOC */ +.anchor { + opacity: 0; + transition: 0.4s; +} +h2:hover > .anchor, h3:hover > .anchor, h4:hover > .anchor, h5:hover > .anchor { + opacity: 1; +} +.anchor:hover { + opacity: 1; +} +.anchor-link { + display: none; +} +#toc_content>.toc-list { + overflow: hidden; + position: relative +} + +#toc_content>.toc-list li { + list-style: none +} + +.toc-list { + margin: 0; + padding-left: 10px +} +#toc_content > .toc-list > .toc-list-item { + border-left: 2px solid #f1f1f1; + padding: 0.1em 0.1em; + line-height: 1.2em; +} + +a.toc-link { + color: currentColor; + height: 100% +} + +.is-collapsible { + /* max-height: 1000px; */ + overflow: hidden; + transition: all 300ms ease-in-out +} + +.is-collapsed { + max-height: 0 +} + +.is-position-fixed { + position: fixed !important; + top: 0 +} + +.is-active-link { + font-weight: 700 +} + +.toc-link::before { + content: ' '; + display: inline-block; + height: inherit; + left: 0; + margin-top: -1px; + padding-left: 6px; + margin-left: -2px; +} + +.is-active-link::before { + border-left: 2px solid #1f8dbf; +} + +/* class template */ +.md_page #page_content > div { + width: 90%; + max-width: 50em; + margin: auto; + line-height: 2em; +} + +/* jupyter notebook parser */ +.jp-InputArea { + display: flex; + flex-direction: row; +} +.jp-InputPrompt { + word-break: keep-all; + margin-right: 0.2em; + font-size: 0.8em; +} +.jp-CodeMirrorEditor { + flex-grow: 1; + overflow: auto; +} +.jp-OutputArea-child { + display: flex; + flex-direction: row; +} +.jp-OutputPrompt { + word-break: keep-all; + margin-right: 0.2em; + font-size: 0.8em; + min-width: 2.7em; +} +.jp-OutputArea-output { + flex-grow: 1; + overflow: auto; + background: #2d2d2d; +} + +/* google translate */ +#navbar #google_translate_element { + padding: 0; +} +#navbar #google_translate_element .goog-te-gadget-simple { + border-radius: 5px; + transition: 0.4s; +} +#navbar #google_translate_element .goog-te-gadget-simple .goog-te-menu-value { + transition: 0.4s; +} + +/* tabset */ +.tabset { + display: flex; + flex-direction: column; + align-items: normal; + border: 0.2em solid #ebedf0; + border-radius: 0.5em; + margin: 0.5em 0; +} +.tabset-title { + font-size: medium; + font-weight: 500; + padding: 0.5em 1em; +} +.tabset-content { + display: flex; + flex-direction: column; + align-items: normal; +} +.tabset-tab { + display: flex; + flex-direction: row; + padding: 0 1em; +} +.tabset-tab-label { + cursor: pointer; + font-size: large; + font-weight: 700; + padding: 0.5em 1em; + border-top-left-radius: 0.2em; + border-top-right-radius: 0.2em; +} +.tabset-tab-label:hover { + background-color: #0000000d; +} +.tabset-tab-active { + background-color: #0000000d; + border-bottom: 0.2em solid #1f8dbf; + color: #1f8dbf; +} +.tabset-text-container { + padding: 1em; + background-color: #0000000d; +} +.tabset-text-container > div { + display: none; +} +.tabset-text-container > div.tabset-text-active { + display: block; +} + +/* details */ +details { + display: flex; + flex-direction: column; + align-items: normal; + border: 0.2em solid #ebedf0; + border-radius: 0.5em; + margin: 0.5em 0; + transition: 0.4s; +} +details > summary { + font-size: medium; + font-weight: 500; + padding: 0.5em 1em; + cursor: pointer; +} +details > summary { + list-style-type:none; + position: relative; + padding-left: 2em; +} +details > summary:before { + display:inline-block; + content: url("/maixcdk/static/image/theme_default/array.svg"); + transform:rotate(90deg); + transition: 0.4s; + left: 0.5em; + position: absolute; + top: 0.45rem; +} +details[open] > summary:before { + transform:rotate(180deg); + top: 0.35rem; +} +details[open] summary ~ * { + animation: sweep .4s ease-in-out; + } +@keyframes sweep { +0% {opacity: 0; margin-left: -10px} +100% {opacity: 1; margin-left: 0px} +} +details > .details-content, details > div { + padding: 1em; + background-color: #0000000d; +} + +#update_history { + overflow-x: auto; +} +#update_history details > div { + padding: 0; +} +#update_history details { + width: fit-content; +} + +/* mobile phone */ +@media screen and (max-width: 900px) { + #navbar { + display: block; + border-bottom: 1px solid #f1f1f1; + z-index: 89; + } + #navbar * { + display: block; + } + #navbar a.site_title { + display: flex; + } + #navbar_menu { + display: flex; + justify-content: space-between; + } + #navbar ul { + padding-left: 0; + } + #navbar_menu_btn { + background: url("/maixcdk/static/image/theme_default/menu.svg"); + background-size: contain; + background-repeat: no-repeat; + background-position: center; + border-radius: 5px; + cursor: pointer; + width: 1em; + height: 1em; + display: block; + } + #navbar #navbar_items { + display: none; + padding-right: 0; + } + #navbar .sub_items ul { + left: 0; + right: auto; + } + #navbar .sub_items ul ul { + left: 0; + top: 3em; + } + #sidebar_wrapper { + position: fixed; + top: 0; + left: 0; + bottom: 0; + background-color: white; + box-shadow: 0 0 20px 0px #bbbbbb; + width: 100%; + z-index: 98; + display: none; + } + #sidebar { + position: relative; + width: 100%; + } + .gutter { + display: none; + } + #sidebar > ul { + padding-top: 4em; + } + #menu_wrapper { + z-index: 99; + } + #menu_wrapper.m_menu_fixed { + position: fixed; + left: 0; + top: 0; + width: 100%; + height: 4em; + background-color: rgb(255, 255, 255, 0.9); + box-shadow: 0px 1px 10px 0px rgb(0, 0, 0, 0.06); + } + #menu_wrapper.m_menu_fixed > #menu { + position: fixed; + left: 0.2em; + top: 1em; + } + #menu.close { + background: url("/maixcdk/static/image/theme_default/back.svg"); + background-size: contain; + background-repeat: no-repeat; + background-position: center; + border-radius: 5px; + min-height: 2em; + min-width: 2em; + } + #content_body { + width: 90%; + } + #toc_wrapper { + display: none; + position: fixed; + width: 100vh; + height: 100vh; + top: 0; + left: 0; + background-color: rgb(0, 0, 0, 0.5); + z-index: 999; + transition: 0.4s; + } + #toc_wrapper.show { + display: block; + } + #article #toc{ + position: fixed; + top: 4em; + right: 0; + z-index: 200; + width: 90%; + padding: 1em 0 1em 0; + border-radius: 0.3em 0 0 0.3em; + } + #previous_next { + flex-direction: column; + } + + .m_hide { + display: none; + } + #footer_top > ul { + flex-direction: column; + } + #article_tools { + width: 100%; + display: flex; + flex-direction: column; + align-items: flex-end; + position: -webkit-sticky; + position: sticky; + top: 1em; + z-index: 97; + } + #toc_btn { + background: url("/maixcdk/static/image/theme_default/anchor.svg"); + background-size: contain; + background-repeat: no-repeat; + background-position: center; + border-radius: 5px; + min-height: 2em; + min-width: 2em; + -ms-transform: rotate(12deg); + -moz-transform: rotate(12deg); + -webkit-transform: rotate(12deg); + transform: rotate(12deg); + } +} + + +/* special */ + +#themes{ + padding: 2px 5px; + cursor: pointer; +} +#navbar .light, #navbar .dark:hover { + background: url("/maixcdk/static/image/theme_default/light_mode.svg"); + background-size: contain; + background-repeat: no-repeat; + background-position: center; + min-height: 1rem; + min-width: 1rem; +} +#navbar .dark, #navbar .light:hover { + background: url("/maixcdk/static/image/theme_default/dark_mode.svg"); + background-size: contain; + background-repeat: no-repeat; + background-position: center; + min-height: 1rem; + min-width: 1rem; +} + + +@media print { + code[class*="language-"], pre[class*="language-"] { + white-space: pre-wrap; + } + pre[class*="language-"].line-numbers { + border: 1px solid #2d2d2d; + } + #navbar, + #sidebar_wrapper, .gutter, #menu_wrapper, + #toc, #to_top, #doc_footer, + #previous_next, + #source_link, #print_page, + #comments-container { + display: none; + } + #article { + width: 100%; + } + #content_body { + max-width: 100%; + width: 100%; + } + /* .line-numbers-rows { + display: none; + } */ + .gutter { + display: none; + } +} diff --git a/maixcdk/static/css/theme_default/prism.min.css b/maixcdk/static/css/theme_default/prism.min.css new file mode 100644 index 00000000..c087ba96 --- /dev/null +++ b/maixcdk/static/css/theme_default/prism.min.css @@ -0,0 +1,261 @@ +/* PrismJS 1.23.0 +https://prismjs.com/download.html#themes=prism-tomorrow&languages=markup+css+clike+javascript+bash+c+cpp+cmake+coffeescript+docker+go+ini+java+json+json5+kotlin+latex+less+lua+makefile+markdown+markup-templating+objectivec+php+powershell+python+jsx+tsx+ruby+rust+sass+scss+shell-session+sql+swift+textile+typescript+yaml&plugins=line-numbers+highlight-keywords+toolbar+copy-to-clipboard+match-braces */ +/** + * prism.js tomorrow night eighties for JavaScript, CoffeeScript, CSS and HTML + * Based on https://github.com/chriskempson/tomorrow-theme + * @author Rose Pritchard + */ + +code[class*="language-"], +pre[class*="language-"] { + color: #ccc; + background: none; + font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace; + font-size: 1em; + text-align: left; + white-space: pre; + word-spacing: normal; + word-break: normal; + word-wrap: normal; + line-height: 1.5; + + -moz-tab-size: 4; + -o-tab-size: 4; + tab-size: 4; + + -webkit-hyphens: none; + -moz-hyphens: none; + -ms-hyphens: none; + hyphens: none; + +} + +/* Code blocks */ +pre[class*="language-"] { + padding: 1em; + margin: .5em 0; + overflow: auto; +} + +:not(pre) > code[class*="language-"], +pre[class*="language-"] { + background: #2d2d2d; +} + +/* Inline code */ +:not(pre) > code[class*="language-"] { + padding: .1em; + border-radius: .3em; + white-space: normal; +} + +.token.comment, +.token.block-comment, +.token.prolog, +.token.doctype, +.token.cdata { + color: #999; +} + +.token.punctuation { + color: #ccc; +} + +.token.tag, +.token.attr-name, +.token.namespace, +.token.deleted { + color: #e2777a; +} + +.token.function-name { + color: #6196cc; +} + +.token.boolean, +.token.number, +.token.function { + color: #f08d49; +} + +.token.property, +.token.class-name, +.token.constant, +.token.symbol { + color: #f8c555; +} + +.token.selector, +.token.important, +.token.atrule, +.token.keyword, +.token.builtin { + color: #cc99cd; +} + +.token.string, +.token.char, +.token.attr-value, +.token.regex, +.token.variable { + color: #7ec699; +} + +.token.operator, +.token.entity, +.token.url { + color: #67cdcc; +} + +.token.important, +.token.bold { + font-weight: bold; +} +.token.italic { + font-style: italic; +} + +.token.entity { + cursor: help; +} + +.token.inserted { + color: green; +} + +pre[class*="language-"].line-numbers { + position: relative; + padding-left: 3.8em; + counter-reset: linenumber; +} + +pre[class*="language-"].line-numbers > code { + position: relative; + white-space: inherit; +} + +.line-numbers .line-numbers-rows { + position: absolute; + pointer-events: none; + top: 0; + font-size: 100%; + left: -3.8em; + width: 3em; /* works for line-numbers below 1000 lines */ + letter-spacing: -1px; + border-right: 1px solid #999; + + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + +} + + .line-numbers-rows > span { + display: block; + counter-increment: linenumber; + } + + .line-numbers-rows > span:before { + content: counter(linenumber); + color: #999; + display: block; + padding-right: 0.8em; + text-align: right; + } + +div.code-toolbar { + position: relative; +} + +div.code-toolbar > .toolbar { + position: absolute; + top: .3em; + right: .2em; + transition: opacity 0.3s ease-in-out; + opacity: 0; +} + +div.code-toolbar:hover > .toolbar { + opacity: 1; +} + +/* Separate line b/c rules are thrown out if selector is invalid. + IE11 and old Edge versions don't support :focus-within. */ +div.code-toolbar:focus-within > .toolbar { + opacity: 1; +} + +div.code-toolbar > .toolbar .toolbar-item { + display: inline-block; +} + +div.code-toolbar > .toolbar a { + cursor: pointer; +} + +div.code-toolbar > .toolbar button { + background: none; + border: 0; + color: inherit; + font: inherit; + line-height: normal; + overflow: visible; + padding: 0; + -webkit-user-select: none; /* for button */ + -moz-user-select: none; + -ms-user-select: none; +} + +div.code-toolbar > .toolbar a, +div.code-toolbar > .toolbar button, +div.code-toolbar > .toolbar span { + color: #bbb; + font-size: .8em; + padding: 0 .5em; + background: #f5f2f0; + background: rgba(224, 224, 224, 0.2); + box-shadow: 0 2px 0 0 rgba(0,0,0,0.2); + border-radius: .5em; +} + +div.code-toolbar > .toolbar a:hover, +div.code-toolbar > .toolbar a:focus, +div.code-toolbar > .toolbar button:hover, +div.code-toolbar > .toolbar button:focus, +div.code-toolbar > .toolbar span:hover, +div.code-toolbar > .toolbar span:focus { + color: inherit; + text-decoration: none; +} + +.token.punctuation.brace-hover, +.token.punctuation.brace-selected { + outline: solid 1px; +} + +.rainbow-braces .token.punctuation.brace-level-1, +.rainbow-braces .token.punctuation.brace-level-5, +.rainbow-braces .token.punctuation.brace-level-9 { + color: #E50; + opacity: 1; +} +.rainbow-braces .token.punctuation.brace-level-2, +.rainbow-braces .token.punctuation.brace-level-6, +.rainbow-braces .token.punctuation.brace-level-10 { + color: #0B3; + opacity: 1; +} +.rainbow-braces .token.punctuation.brace-level-3, +.rainbow-braces .token.punctuation.brace-level-7, +.rainbow-braces .token.punctuation.brace-level-11 { + color: #26F; + opacity: 1; +} +.rainbow-braces .token.punctuation.brace-level-4, +.rainbow-braces .token.punctuation.brace-level-8, +.rainbow-braces .token.punctuation.brace-level-12 { + color: #E0E; + opacity: 1; +} + diff --git a/maixcdk/static/css/theme_default/prism.min.js b/maixcdk/static/css/theme_default/prism.min.js new file mode 100644 index 00000000..debc9322 --- /dev/null +++ b/maixcdk/static/css/theme_default/prism.min.js @@ -0,0 +1,46 @@ +/* PrismJS 1.23.0 +https://prismjs.com/download.html#themes=prism-tomorrow&languages=markup+css+clike+javascript+bash+c+cpp+cmake+coffeescript+docker+go+ini+java+json+json5+kotlin+latex+less+lua+makefile+markdown+markup-templating+objectivec+php+powershell+python+jsx+tsx+ruby+rust+sass+scss+shell-session+sql+swift+textile+typescript+yaml&plugins=line-numbers+highlight-keywords+toolbar+copy-to-clipboard+match-braces */ +var _self="undefined"!=typeof window?window:"undefined"!=typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope?self:{},Prism=function(u){var c=/\blang(?:uage)?-([\w-]+)\b/i,n=0,M={manual:u.Prism&&u.Prism.manual,disableWorkerMessageHandler:u.Prism&&u.Prism.disableWorkerMessageHandler,util:{encode:function e(n){return n instanceof W?new W(n.type,e(n.content),n.alias):Array.isArray(n)?n.map(e):n.replace(/&/g,"&").replace(/=l.reach);y+=m.value.length,m=m.next){var k=m.value;if(r.length>n.length)return;if(!(k instanceof W)){var b,x=1;if(h){if(!(b=z(p,y,n,f)))break;var w=b.index,A=b.index+b[0].length,P=y;for(P+=m.value.length;P<=w;)m=m.next,P+=m.value.length;if(P-=m.value.length,y=P,m.value instanceof W)continue;for(var S=m;S!==r.tail&&(Pl.reach&&(l.reach=N);var j=m.prev;O&&(j=I(r,j,O),y+=O.length),q(r,j,x);var C=new W(o,g?M.tokenize(E,g):E,d,E);if(m=I(r,j,C),L&&I(r,m,L),1l.reach&&(l.reach=_.reach)}}}}}}(e,a,n,a.head,0),function(e){var n=[],r=e.head.next;for(;r!==e.tail;)n.push(r.value),r=r.next;return n}(a)},hooks:{all:{},add:function(e,n){var r=M.hooks.all;r[e]=r[e]||[],r[e].push(n)},run:function(e,n){var r=M.hooks.all[e];if(r&&r.length)for(var t,a=0;t=r[a++];)t(n)}},Token:W};function W(e,n,r,t){this.type=e,this.content=n,this.alias=r,this.length=0|(t||"").length}function z(e,n,r,t){e.lastIndex=n;var a=e.exec(r);if(a&&t&&a[1]){var i=a[1].length;a.index+=i,a[0]=a[0].slice(i)}return a}function i(){var e={value:null,prev:null,next:null},n={value:null,prev:e,next:null};e.next=n,this.head=e,this.tail=n,this.length=0}function I(e,n,r){var t=n.next,a={value:r,prev:n,next:t};return n.next=a,t.prev=a,e.length++,a}function q(e,n,r){for(var t=n.next,a=0;a"+a.content+""},!u.document)return u.addEventListener&&(M.disableWorkerMessageHandler||u.addEventListener("message",function(e){var n=JSON.parse(e.data),r=n.language,t=n.code,a=n.immediateClose;u.postMessage(M.highlight(t,M.languages[r],r)),a&&u.close()},!1)),M;var e=M.util.currentScript();function r(){M.manual||M.highlightAll()}if(e&&(M.filename=e.src,e.hasAttribute("data-manual")&&(M.manual=!0)),!M.manual){var t=document.readyState;"loading"===t||"interactive"===t&&e&&e.defer?document.addEventListener("DOMContentLoaded",r):window.requestAnimationFrame?window.requestAnimationFrame(r):window.setTimeout(r,16)}return M}(_self);"undefined"!=typeof module&&module.exports&&(module.exports=Prism),"undefined"!=typeof global&&(global.Prism=Prism); +Prism.languages.markup={comment://,prolog:/<\?[\s\S]+?\?>/,doctype:{pattern:/"'[\]]|"[^"]*"|'[^']*')+(?:\[(?:[^<"'\]]|"[^"]*"|'[^']*'|<(?!!--)|)*\]\s*)?>/i,greedy:!0,inside:{"internal-subset":{pattern:/(\[)[\s\S]+(?=\]>$)/,lookbehind:!0,greedy:!0,inside:null},string:{pattern:/"[^"]*"|'[^']*'/,greedy:!0},punctuation:/^$|[[\]]/,"doctype-tag":/^DOCTYPE/,name:/[^\s<>'"]+/}},cdata://i,tag:{pattern:/<\/?(?!\d)[^\s>\/=$<%]+(?:\s(?:\s*[^\s>\/=]+(?:\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))|(?=[\s/>])))+)?\s*\/?>/,greedy:!0,inside:{tag:{pattern:/^<\/?[^\s>\/]+/,inside:{punctuation:/^<\/?/,namespace:/^[^\s>\/:]+:/}},"attr-value":{pattern:/=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+)/,inside:{punctuation:[{pattern:/^=/,alias:"attr-equals"},/"|'/]}},punctuation:/\/?>/,"attr-name":{pattern:/[^\s>\/]+/,inside:{namespace:/^[^\s>\/:]+:/}}}},entity:[{pattern:/&[\da-z]{1,8};/i,alias:"named-entity"},/&#x?[\da-f]{1,8};/i]},Prism.languages.markup.tag.inside["attr-value"].inside.entity=Prism.languages.markup.entity,Prism.languages.markup.doctype.inside["internal-subset"].inside=Prism.languages.markup,Prism.hooks.add("wrap",function(a){"entity"===a.type&&(a.attributes.title=a.content.replace(/&/,"&"))}),Object.defineProperty(Prism.languages.markup.tag,"addInlined",{value:function(a,e){var s={};s["language-"+e]={pattern:/(^$)/i,lookbehind:!0,inside:Prism.languages[e]},s.cdata=/^$/i;var n={"included-cdata":{pattern://i,inside:s}};n["language-"+e]={pattern:/[\s\S]+/,inside:Prism.languages[e]};var t={};t[a]={pattern:RegExp("(<__[^>]*>)(?:))*\\]\\]>|(?!)".replace(/__/g,function(){return a}),"i"),lookbehind:!0,greedy:!0,inside:n},Prism.languages.insertBefore("markup","cdata",t)}}),Prism.languages.html=Prism.languages.markup,Prism.languages.mathml=Prism.languages.markup,Prism.languages.svg=Prism.languages.markup,Prism.languages.xml=Prism.languages.extend("markup",{}),Prism.languages.ssml=Prism.languages.xml,Prism.languages.atom=Prism.languages.xml,Prism.languages.rss=Prism.languages.xml; +!function(s){var e=/("|')(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/;s.languages.css={comment:/\/\*[\s\S]*?\*\//,atrule:{pattern:/@[\w-](?:[^;{\s]|\s+(?![\s{]))*(?:;|(?=\s*\{))/,inside:{rule:/^@[\w-]+/,"selector-function-argument":{pattern:/(\bselector\s*\(\s*(?![\s)]))(?:[^()\s]|\s+(?![\s)])|\((?:[^()]|\([^()]*\))*\))+(?=\s*\))/,lookbehind:!0,alias:"selector"},keyword:{pattern:/(^|[^\w-])(?:and|not|only|or)(?![\w-])/,lookbehind:!0}}},url:{pattern:RegExp("\\burl\\((?:"+e.source+"|(?:[^\\\\\r\n()\"']|\\\\[^])*)\\)","i"),greedy:!0,inside:{function:/^url/i,punctuation:/^\(|\)$/,string:{pattern:RegExp("^"+e.source+"$"),alias:"url"}}},selector:RegExp("[^{}\\s](?:[^{};\"'\\s]|\\s+(?![\\s{])|"+e.source+")*(?=\\s*\\{)"),string:{pattern:e,greedy:!0},property:/(?!\s)[-_a-z\xA0-\uFFFF](?:(?!\s)[-\w\xA0-\uFFFF])*(?=\s*:)/i,important:/!important\b/i,function:/[-a-z0-9]+(?=\()/i,punctuation:/[(){};:,]/},s.languages.css.atrule.inside.rest=s.languages.css;var t=s.languages.markup;t&&(t.tag.addInlined("style","css"),s.languages.insertBefore("inside","attr-value",{"style-attr":{pattern:/(^|["'\s])style\s*=\s*(?:"[^"]*"|'[^']*')/i,lookbehind:!0,inside:{"attr-value":{pattern:/=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+)/,inside:{style:{pattern:/(["'])[\s\S]+(?=["']$)/,lookbehind:!0,alias:"language-css",inside:s.languages.css},punctuation:[{pattern:/^=/,alias:"attr-equals"},/"|'/]}},"attr-name":/^style/i}}},t.tag))}(Prism); +Prism.languages.clike={comment:[{pattern:/(^|[^\\])\/\*[\s\S]*?(?:\*\/|$)/,lookbehind:!0,greedy:!0},{pattern:/(^|[^\\:])\/\/.*/,lookbehind:!0,greedy:!0}],string:{pattern:/(["'])(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,greedy:!0},"class-name":{pattern:/(\b(?:class|interface|extends|implements|trait|instanceof|new)\s+|\bcatch\s+\()[\w.\\]+/i,lookbehind:!0,inside:{punctuation:/[.\\]/}},keyword:/\b(?:if|else|while|do|for|return|in|instanceof|function|new|try|throw|catch|finally|null|break|continue)\b/,boolean:/\b(?:true|false)\b/,function:/\w+(?=\()/,number:/\b0x[\da-f]+\b|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:e[+-]?\d+)?/i,operator:/[<>]=?|[!=]=?=?|--?|\+\+?|&&?|\|\|?|[?*/~^%]/,punctuation:/[{}[\];(),.:]/}; +Prism.languages.javascript=Prism.languages.extend("clike",{"class-name":[Prism.languages.clike["class-name"],{pattern:/(^|[^$\w\xA0-\uFFFF])(?!\s)[_$A-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\.(?:prototype|constructor))/,lookbehind:!0}],keyword:[{pattern:/((?:^|})\s*)catch\b/,lookbehind:!0},{pattern:/(^|[^.]|\.\.\.\s*)\b(?:as|async(?=\s*(?:function\b|\(|[$\w\xA0-\uFFFF]|$))|await|break|case|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally(?=\s*(?:\{|$))|for|from(?=\s*(?:['"]|$))|function|(?:get|set)(?=\s*(?:[\[$\w\xA0-\uFFFF]|$))|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)\b/,lookbehind:!0}],function:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*(?:\.\s*(?:apply|bind|call)\s*)?\()/,number:/\b(?:(?:0[xX](?:[\dA-Fa-f](?:_[\dA-Fa-f])?)+|0[bB](?:[01](?:_[01])?)+|0[oO](?:[0-7](?:_[0-7])?)+)n?|(?:\d(?:_\d)?)+n|NaN|Infinity)\b|(?:\b(?:\d(?:_\d)?)+\.?(?:\d(?:_\d)?)*|\B\.(?:\d(?:_\d)?)+)(?:[Ee][+-]?(?:\d(?:_\d)?)+)?/,operator:/--|\+\+|\*\*=?|=>|&&=?|\|\|=?|[!=]==|<<=?|>>>?=?|[-+*/%&|^!=<>]=?|\.{3}|\?\?=?|\?\.?|[~:]/}),Prism.languages.javascript["class-name"][0].pattern=/(\b(?:class|interface|extends|implements|instanceof|new)\s+)[\w.\\]+/,Prism.languages.insertBefore("javascript","keyword",{regex:{pattern:/((?:^|[^$\w\xA0-\uFFFF."'\])\s]|\b(?:return|yield))\s*)\/(?:\[(?:[^\]\\\r\n]|\\.)*]|\\.|[^/\\\[\r\n])+\/[gimyus]{0,6}(?=(?:\s|\/\*(?:[^*]|\*(?!\/))*\*\/)*(?:$|[\r\n,.;:})\]]|\/\/))/,lookbehind:!0,greedy:!0,inside:{"regex-source":{pattern:/^(\/)[\s\S]+(?=\/[a-z]*$)/,lookbehind:!0,alias:"language-regex",inside:Prism.languages.regex},"regex-flags":/[a-z]+$/,"regex-delimiter":/^\/|\/$/}},"function-variable":{pattern:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*[=:]\s*(?:async\s*)?(?:\bfunction\b|(?:\((?:[^()]|\([^()]*\))*\)|(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)\s*=>))/,alias:"function"},parameter:[{pattern:/(function(?:\s+(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)?\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\))/,lookbehind:!0,inside:Prism.languages.javascript},{pattern:/(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*=>)/i,inside:Prism.languages.javascript},{pattern:/(\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*=>)/,lookbehind:!0,inside:Prism.languages.javascript},{pattern:/((?:\b|\s|^)(?!(?:as|async|await|break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally|for|from|function|get|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|set|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)(?![$\w\xA0-\uFFFF]))(?:(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*\s*)\(\s*|\]\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*\{)/,lookbehind:!0,inside:Prism.languages.javascript}],constant:/\b[A-Z](?:[A-Z_]|\dx?)*\b/}),Prism.languages.insertBefore("javascript","string",{"template-string":{pattern:/`(?:\\[\s\S]|\${(?:[^{}]|{(?:[^{}]|{[^}]*})*})+}|(?!\${)[^\\`])*`/,greedy:!0,inside:{"template-punctuation":{pattern:/^`|`$/,alias:"string"},interpolation:{pattern:/((?:^|[^\\])(?:\\{2})*)\${(?:[^{}]|{(?:[^{}]|{[^}]*})*})+}/,lookbehind:!0,inside:{"interpolation-punctuation":{pattern:/^\${|}$/,alias:"punctuation"},rest:Prism.languages.javascript}},string:/[\s\S]+/}}}),Prism.languages.markup&&Prism.languages.markup.tag.addInlined("script","javascript"),Prism.languages.js=Prism.languages.javascript; +!function(e){var t="\\b(?:BASH|BASHOPTS|BASH_ALIASES|BASH_ARGC|BASH_ARGV|BASH_CMDS|BASH_COMPLETION_COMPAT_DIR|BASH_LINENO|BASH_REMATCH|BASH_SOURCE|BASH_VERSINFO|BASH_VERSION|COLORTERM|COLUMNS|COMP_WORDBREAKS|DBUS_SESSION_BUS_ADDRESS|DEFAULTS_PATH|DESKTOP_SESSION|DIRSTACK|DISPLAY|EUID|GDMSESSION|GDM_LANG|GNOME_KEYRING_CONTROL|GNOME_KEYRING_PID|GPG_AGENT_INFO|GROUPS|HISTCONTROL|HISTFILE|HISTFILESIZE|HISTSIZE|HOME|HOSTNAME|HOSTTYPE|IFS|INSTANCE|JOB|LANG|LANGUAGE|LC_ADDRESS|LC_ALL|LC_IDENTIFICATION|LC_MEASUREMENT|LC_MONETARY|LC_NAME|LC_NUMERIC|LC_PAPER|LC_TELEPHONE|LC_TIME|LESSCLOSE|LESSOPEN|LINES|LOGNAME|LS_COLORS|MACHTYPE|MAILCHECK|MANDATORY_PATH|NO_AT_BRIDGE|OLDPWD|OPTERR|OPTIND|ORBIT_SOCKETDIR|OSTYPE|PAPERSIZE|PATH|PIPESTATUS|PPID|PS1|PS2|PS3|PS4|PWD|RANDOM|REPLY|SECONDS|SELINUX_INIT|SESSION|SESSIONTYPE|SESSION_MANAGER|SHELL|SHELLOPTS|SHLVL|SSH_AUTH_SOCK|TERM|UID|UPSTART_EVENTS|UPSTART_INSTANCE|UPSTART_JOB|UPSTART_SESSION|USER|WINDOWID|XAUTHORITY|XDG_CONFIG_DIRS|XDG_CURRENT_DESKTOP|XDG_DATA_DIRS|XDG_GREETER_DATA_DIR|XDG_MENU_PREFIX|XDG_RUNTIME_DIR|XDG_SEAT|XDG_SEAT_PATH|XDG_SESSION_DESKTOP|XDG_SESSION_ID|XDG_SESSION_PATH|XDG_SESSION_TYPE|XDG_VTNR|XMODIFIERS)\\b",n={pattern:/(^(["']?)\w+\2)[ \t]+\S.*/,lookbehind:!0,alias:"punctuation",inside:null},a={bash:n,environment:{pattern:RegExp("\\$"+t),alias:"constant"},variable:[{pattern:/\$?\(\([\s\S]+?\)\)/,greedy:!0,inside:{variable:[{pattern:/(^\$\(\([\s\S]+)\)\)/,lookbehind:!0},/^\$\(\(/],number:/\b0x[\dA-Fa-f]+\b|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:[Ee]-?\d+)?/,operator:/--?|-=|\+\+?|\+=|!=?|~|\*\*?|\*=|\/=?|%=?|<<=?|>>=?|<=?|>=?|==?|&&?|&=|\^=?|\|\|?|\|=|\?|:/,punctuation:/\(\(?|\)\)?|,|;/}},{pattern:/\$\((?:\([^)]+\)|[^()])+\)|`[^`]+`/,greedy:!0,inside:{variable:/^\$\(|^`|\)$|`$/}},{pattern:/\$\{[^}]+\}/,greedy:!0,inside:{operator:/:[-=?+]?|[!\/]|##?|%%?|\^\^?|,,?/,punctuation:/[\[\]]/,environment:{pattern:RegExp("(\\{)"+t),lookbehind:!0,alias:"constant"}}},/\$(?:\w+|[#?*!@$])/],entity:/\\(?:[abceEfnrtv\\"]|O?[0-7]{1,3}|x[0-9a-fA-F]{1,2}|u[0-9a-fA-F]{4}|U[0-9a-fA-F]{8})/};e.languages.bash={shebang:{pattern:/^#!\s*\/.*/,alias:"important"},comment:{pattern:/(^|[^"{\\$])#.*/,lookbehind:!0},"function-name":[{pattern:/(\bfunction\s+)\w+(?=(?:\s*\(?:\s*\))?\s*\{)/,lookbehind:!0,alias:"function"},{pattern:/\b\w+(?=\s*\(\s*\)\s*\{)/,alias:"function"}],"for-or-select":{pattern:/(\b(?:for|select)\s+)\w+(?=\s+in\s)/,alias:"variable",lookbehind:!0},"assign-left":{pattern:/(^|[\s;|&]|[<>]\()\w+(?=\+?=)/,inside:{environment:{pattern:RegExp("(^|[\\s;|&]|[<>]\\()"+t),lookbehind:!0,alias:"constant"}},alias:"variable",lookbehind:!0},string:[{pattern:/((?:^|[^<])<<-?\s*)(\w+?)\s[\s\S]*?(?:\r?\n|\r)\2/,lookbehind:!0,greedy:!0,inside:a},{pattern:/((?:^|[^<])<<-?\s*)(["'])(\w+)\2\s[\s\S]*?(?:\r?\n|\r)\3/,lookbehind:!0,greedy:!0,inside:{bash:n}},{pattern:/(^|[^\\](?:\\\\)*)(["'])(?:\\[\s\S]|\$\([^)]+\)|\$(?!\()|`[^`]+`|(?!\2)[^\\`$])*\2/,lookbehind:!0,greedy:!0,inside:a}],environment:{pattern:RegExp("\\$?"+t),alias:"constant"},variable:a.variable,function:{pattern:/(^|[\s;|&]|[<>]\()(?:add|apropos|apt|aptitude|apt-cache|apt-get|aspell|automysqlbackup|awk|basename|bash|bc|bconsole|bg|bzip2|cal|cat|cfdisk|chgrp|chkconfig|chmod|chown|chroot|cksum|clear|cmp|column|comm|composer|cp|cron|crontab|csplit|curl|cut|date|dc|dd|ddrescue|debootstrap|df|diff|diff3|dig|dir|dircolors|dirname|dirs|dmesg|du|egrep|eject|env|ethtool|expand|expect|expr|fdformat|fdisk|fg|fgrep|file|find|fmt|fold|format|free|fsck|ftp|fuser|gawk|git|gparted|grep|groupadd|groupdel|groupmod|groups|grub-mkconfig|gzip|halt|head|hg|history|host|hostname|htop|iconv|id|ifconfig|ifdown|ifup|import|install|ip|jobs|join|kill|killall|less|link|ln|locate|logname|logrotate|look|lpc|lpr|lprint|lprintd|lprintq|lprm|ls|lsof|lynx|make|man|mc|mdadm|mkconfig|mkdir|mke2fs|mkfifo|mkfs|mkisofs|mknod|mkswap|mmv|more|most|mount|mtools|mtr|mutt|mv|nano|nc|netstat|nice|nl|nohup|notify-send|npm|nslookup|op|open|parted|passwd|paste|pathchk|ping|pkill|pnpm|popd|pr|printcap|printenv|ps|pushd|pv|quota|quotacheck|quotactl|ram|rar|rcp|reboot|remsync|rename|renice|rev|rm|rmdir|rpm|rsync|scp|screen|sdiff|sed|sendmail|seq|service|sftp|sh|shellcheck|shuf|shutdown|sleep|slocate|sort|split|ssh|stat|strace|su|sudo|sum|suspend|swapon|sync|tac|tail|tar|tee|time|timeout|top|touch|tr|traceroute|tsort|tty|umount|uname|unexpand|uniq|units|unrar|unshar|unzip|update-grub|uptime|useradd|userdel|usermod|users|uudecode|uuencode|v|vdir|vi|vim|virsh|vmstat|wait|watch|wc|wget|whereis|which|who|whoami|write|xargs|xdg-open|yarn|yes|zenity|zip|zsh|zypper)(?=$|[)\s;|&])/,lookbehind:!0},keyword:{pattern:/(^|[\s;|&]|[<>]\()(?:if|then|else|elif|fi|for|while|in|case|esac|function|select|do|done|until)(?=$|[)\s;|&])/,lookbehind:!0},builtin:{pattern:/(^|[\s;|&]|[<>]\()(?:\.|:|break|cd|continue|eval|exec|exit|export|getopts|hash|pwd|readonly|return|shift|test|times|trap|umask|unset|alias|bind|builtin|caller|command|declare|echo|enable|help|let|local|logout|mapfile|printf|read|readarray|source|type|typeset|ulimit|unalias|set|shopt)(?=$|[)\s;|&])/,lookbehind:!0,alias:"class-name"},boolean:{pattern:/(^|[\s;|&]|[<>]\()(?:true|false)(?=$|[)\s;|&])/,lookbehind:!0},"file-descriptor":{pattern:/\B&\d\b/,alias:"important"},operator:{pattern:/\d?<>|>\||\+=|==?|!=?|=~|<<[<-]?|[&\d]?>>|\d?[<>]&?|&[>&]?|\|[&|]?|<=?|>=?/,inside:{"file-descriptor":{pattern:/^\d/,alias:"important"}}},punctuation:/\$?\(\(?|\)\)?|\.\.|[{}[\];\\]/,number:{pattern:/(^|\s)(?:[1-9]\d*|0)(?:[.,]\d+)?\b/,lookbehind:!0}},n.inside=e.languages.bash;for(var s=["comment","function-name","for-or-select","assign-left","string","environment","function","keyword","builtin","boolean","file-descriptor","operator","punctuation","number"],i=a.variable[1].inside,o=0;o>=?|<<=?|->|([-+&|:])\1|[?:~]|[-+*/%&|^!=<>]=?/}),Prism.languages.insertBefore("c","string",{macro:{pattern:/(^\s*)#\s*[a-z](?:[^\r\n\\/]|\/(?!\*)|\/\*(?:[^*]|\*(?!\/))*\*\/|\\(?:\r\n|[\s\S]))*/im,lookbehind:!0,greedy:!0,alias:"property",inside:{string:[{pattern:/^(#\s*include\s*)<[^>]+>/,lookbehind:!0},Prism.languages.c.string],comment:Prism.languages.c.comment,"macro-name":[{pattern:/(^#\s*define\s+)\w+\b(?!\()/i,lookbehind:!0},{pattern:/(^#\s*define\s+)\w+\b(?=\()/i,lookbehind:!0,alias:"function"}],directive:{pattern:/^(#\s*)[a-z]+/,lookbehind:!0,alias:"keyword"},"directive-hash":/^#/,punctuation:/##|\\(?=[\r\n])/,expression:{pattern:/\S[\s\S]*/,inside:Prism.languages.c}}},constant:/\b(?:__FILE__|__LINE__|__DATE__|__TIME__|__TIMESTAMP__|__func__|EOF|NULL|SEEK_CUR|SEEK_END|SEEK_SET|stdin|stdout|stderr)\b/}),delete Prism.languages.c.boolean; +!function(e){var t=/\b(?:alignas|alignof|asm|auto|bool|break|case|catch|char|char8_t|char16_t|char32_t|class|compl|concept|const|consteval|constexpr|constinit|const_cast|continue|co_await|co_return|co_yield|decltype|default|delete|do|double|dynamic_cast|else|enum|explicit|export|extern|final|float|for|friend|goto|if|import|inline|int|int8_t|int16_t|int32_t|int64_t|uint8_t|uint16_t|uint32_t|uint64_t|long|module|mutable|namespace|new|noexcept|nullptr|operator|override|private|protected|public|register|reinterpret_cast|requires|return|short|signed|sizeof|static|static_assert|static_cast|struct|switch|template|this|thread_local|throw|try|typedef|typeid|typename|union|unsigned|using|virtual|void|volatile|wchar_t|while)\b/,n="\\b(?!)\\w+(?:\\s*\\.\\s*\\w+)*\\b".replace(//g,function(){return t.source});e.languages.cpp=e.languages.extend("c",{"class-name":[{pattern:RegExp("(\\b(?:class|concept|enum|struct|typename)\\s+)(?!)\\w+".replace(//g,function(){return t.source})),lookbehind:!0},/\b[A-Z]\w*(?=\s*::\s*\w+\s*\()/,/\b[A-Z_]\w*(?=\s*::\s*~\w+\s*\()/i,/\w+(?=\s*<(?:[^<>]|<(?:[^<>]|<[^<>]*>)*>)*>\s*::\s*\w+\s*\()/],keyword:t,number:{pattern:/(?:\b0b[01']+|\b0x(?:[\da-f']+(?:\.[\da-f']*)?|\.[\da-f']+)(?:p[+-]?[\d']+)?|(?:\b[\d']+(?:\.[\d']*)?|\B\.[\d']+)(?:e[+-]?[\d']+)?)[ful]{0,4}/i,greedy:!0},operator:/>>=?|<<=?|->|([-+&|:])\1|[?:~]|<=>|[-+*/%&|^!=<>]=?|\b(?:and|and_eq|bitand|bitor|not|not_eq|or|or_eq|xor|xor_eq)\b/,boolean:/\b(?:true|false)\b/}),e.languages.insertBefore("cpp","string",{module:{pattern:RegExp('(\\b(?:module|import)\\s+)(?:"(?:\\\\(?:\r\n|[^])|[^"\\\\\r\n])*"|<[^<>\r\n]*>|'+"(?:\\s*:\\s*)?|:\\s*".replace(//g,function(){return n})+")"),lookbehind:!0,greedy:!0,inside:{string:/^[<"][\s\S]+/,operator:/:/,punctuation:/\./}},"raw-string":{pattern:/R"([^()\\ ]{0,16})\([\s\S]*?\)\1"/,alias:"string",greedy:!0}}),e.languages.insertBefore("cpp","class-name",{"base-clause":{pattern:/(\b(?:class|struct)\s+\w+\s*:\s*)[^;{}"'\s]+(?:\s+[^;{}"'\s]+)*(?=\s*[;{])/,lookbehind:!0,greedy:!0,inside:e.languages.extend("cpp",{})}}),e.languages.insertBefore("inside","operator",{"class-name":/\b[a-z_]\w*\b(?!\s*::)/i},e.languages.cpp["base-clause"])}(Prism); +Prism.languages.cmake={comment:/#.*/,string:{pattern:/"(?:[^\\"]|\\.)*"/,greedy:!0,inside:{interpolation:{pattern:/\${(?:[^{}$]|\${[^{}$]*})*}/,inside:{punctuation:/\${|}/,variable:/\w+/}}}},variable:/\b(?:CMAKE_\w+|\w+_(?:VERSION(?:_MAJOR|_MINOR|_PATCH|_TWEAK)?|(?:BINARY|SOURCE)_DIR|DESCRIPTION|HOMEPAGE_URL|ROOT)|(?:CTEST_CUSTOM_(?:MAXIMUM_(?:(?:FAIL|PASS)ED_TEST_OUTPUT_SIZE|NUMBER_OF_(?:ERROR|WARNING)S)|ERROR_(?:P(?:OST|RE)_CONTEXT|EXCEPTION|MATCH)|P(?:OST|RE)_MEMCHECK|WARNING_(?:EXCEPTION|MATCH)|(?:MEMCHECK|TESTS)_IGNORE|P(?:OST|RE)_TEST|COVERAGE_EXCLUDE)|ANDROID|APPLE|BORLAND|BUILD_SHARED_LIBS|CACHE|CPACK_(?:ABSOLUTE_DESTINATION_FILES|COMPONENT_INCLUDE_TOPLEVEL_DIRECTORY|ERROR_ON_ABSOLUTE_INSTALL_DESTINATION|INCLUDE_TOPLEVEL_DIRECTORY|INSTALL_DEFAULT_DIRECTORY_PERMISSIONS|INSTALL_SCRIPT|PACKAGING_INSTALL_PREFIX|SET_DESTDIR|WARN_ON_ABSOLUTE_INSTALL_DESTINATION)|CTEST_(?:BINARY_DIRECTORY|BUILD_COMMAND|BUILD_NAME|BZR_COMMAND|BZR_UPDATE_OPTIONS|CHANGE_ID|CHECKOUT_COMMAND|CONFIGURATION_TYPE|CONFIGURE_COMMAND|COVERAGE_COMMAND|COVERAGE_EXTRA_FLAGS|CURL_OPTIONS|CUSTOM_(?:COVERAGE_EXCLUDE|ERROR_EXCEPTION|ERROR_MATCH|ERROR_POST_CONTEXT|ERROR_PRE_CONTEXT|MAXIMUM_FAILED_TEST_OUTPUT_SIZE|MAXIMUM_NUMBER_OF_(?:ERRORS|WARNINGS)|MAXIMUM_PASSED_TEST_OUTPUT_SIZE|MEMCHECK_IGNORE|POST_MEMCHECK|POST_TEST|PRE_MEMCHECK|PRE_TEST|TESTS_IGNORE|WARNING_EXCEPTION|WARNING_MATCH)|CVS_CHECKOUT|CVS_COMMAND|CVS_UPDATE_OPTIONS|DROP_LOCATION|DROP_METHOD|DROP_SITE|DROP_SITE_CDASH|DROP_SITE_PASSWORD|DROP_SITE_USER|EXTRA_COVERAGE_GLOB|GIT_COMMAND|GIT_INIT_SUBMODULES|GIT_UPDATE_CUSTOM|GIT_UPDATE_OPTIONS|HG_COMMAND|HG_UPDATE_OPTIONS|LABELS_FOR_SUBPROJECTS|MEMORYCHECK_(?:COMMAND|COMMAND_OPTIONS|SANITIZER_OPTIONS|SUPPRESSIONS_FILE|TYPE)|NIGHTLY_START_TIME|P4_CLIENT|P4_COMMAND|P4_OPTIONS|P4_UPDATE_OPTIONS|RUN_CURRENT_SCRIPT|SCP_COMMAND|SITE|SOURCE_DIRECTORY|SUBMIT_URL|SVN_COMMAND|SVN_OPTIONS|SVN_UPDATE_OPTIONS|TEST_LOAD|TEST_TIMEOUT|TRIGGER_SITE|UPDATE_COMMAND|UPDATE_OPTIONS|UPDATE_VERSION_ONLY|USE_LAUNCHERS)|CYGWIN|ENV|EXECUTABLE_OUTPUT_PATH|GHS-MULTI|IOS|LIBRARY_OUTPUT_PATH|MINGW|MSVC(?:10|11|12|14|60|70|71|80|90|_IDE|_TOOLSET_VERSION|_VERSION)?|MSYS|PROJECT_(?:BINARY_DIR|DESCRIPTION|HOMEPAGE_URL|NAME|SOURCE_DIR|VERSION|VERSION_(?:MAJOR|MINOR|PATCH|TWEAK))|UNIX|WIN32|WINCE|WINDOWS_PHONE|WINDOWS_STORE|XCODE|XCODE_VERSION))\b/,property:/\b(?:cxx_\w+|(?:ARCHIVE_OUTPUT_(?:DIRECTORY|NAME)|COMPILE_DEFINITIONS|COMPILE_PDB_NAME|COMPILE_PDB_OUTPUT_DIRECTORY|EXCLUDE_FROM_DEFAULT_BUILD|IMPORTED_(?:IMPLIB|LIBNAME|LINK_DEPENDENT_LIBRARIES|LINK_INTERFACE_LANGUAGES|LINK_INTERFACE_LIBRARIES|LINK_INTERFACE_MULTIPLICITY|LOCATION|NO_SONAME|OBJECTS|SONAME)|INTERPROCEDURAL_OPTIMIZATION|LIBRARY_OUTPUT_DIRECTORY|LIBRARY_OUTPUT_NAME|LINK_FLAGS|LINK_INTERFACE_LIBRARIES|LINK_INTERFACE_MULTIPLICITY|LOCATION|MAP_IMPORTED_CONFIG|OSX_ARCHITECTURES|OUTPUT_NAME|PDB_NAME|PDB_OUTPUT_DIRECTORY|RUNTIME_OUTPUT_DIRECTORY|RUNTIME_OUTPUT_NAME|STATIC_LIBRARY_FLAGS|VS_CSHARP|VS_DOTNET_REFERENCEPROP|VS_DOTNET_REFERENCE|VS_GLOBAL_SECTION_POST|VS_GLOBAL_SECTION_PRE|VS_GLOBAL|XCODE_ATTRIBUTE)_\w+|\w+_(?:CLANG_TIDY|COMPILER_LAUNCHER|CPPCHECK|CPPLINT|INCLUDE_WHAT_YOU_USE|OUTPUT_NAME|POSTFIX|VISIBILITY_PRESET)|ABSTRACT|ADDITIONAL_MAKE_CLEAN_FILES|ADVANCED|ALIASED_TARGET|ALLOW_DUPLICATE_CUSTOM_TARGETS|ANDROID_(?:ANT_ADDITIONAL_OPTIONS|API|API_MIN|ARCH|ASSETS_DIRECTORIES|GUI|JAR_DEPENDENCIES|NATIVE_LIB_DEPENDENCIES|NATIVE_LIB_DIRECTORIES|PROCESS_MAX|PROGUARD|PROGUARD_CONFIG_PATH|SECURE_PROPS_PATH|SKIP_ANT_STEP|STL_TYPE)|ARCHIVE_OUTPUT_DIRECTORY|ARCHIVE_OUTPUT_NAME|ATTACHED_FILES|ATTACHED_FILES_ON_FAIL|AUTOGEN_(?:BUILD_DIR|ORIGIN_DEPENDS|PARALLEL|SOURCE_GROUP|TARGETS_FOLDER|TARGET_DEPENDS)|AUTOMOC|AUTOMOC_(?:COMPILER_PREDEFINES|DEPEND_FILTERS|EXECUTABLE|MACRO_NAMES|MOC_OPTIONS|SOURCE_GROUP|TARGETS_FOLDER)|AUTORCC|AUTORCC_EXECUTABLE|AUTORCC_OPTIONS|AUTORCC_SOURCE_GROUP|AUTOUIC|AUTOUIC_EXECUTABLE|AUTOUIC_OPTIONS|AUTOUIC_SEARCH_PATHS|BINARY_DIR|BUILDSYSTEM_TARGETS|BUILD_RPATH|BUILD_RPATH_USE_ORIGIN|BUILD_WITH_INSTALL_NAME_DIR|BUILD_WITH_INSTALL_RPATH|BUNDLE|BUNDLE_EXTENSION|CACHE_VARIABLES|CLEAN_NO_CUSTOM|COMMON_LANGUAGE_RUNTIME|COMPATIBLE_INTERFACE_(?:BOOL|NUMBER_MAX|NUMBER_MIN|STRING)|COMPILE_(?:DEFINITIONS|FEATURES|FLAGS|OPTIONS|PDB_NAME|PDB_OUTPUT_DIRECTORY)|COST|CPACK_DESKTOP_SHORTCUTS|CPACK_NEVER_OVERWRITE|CPACK_PERMANENT|CPACK_STARTUP_SHORTCUTS|CPACK_START_MENU_SHORTCUTS|CPACK_WIX_ACL|CROSSCOMPILING_EMULATOR|CUDA_EXTENSIONS|CUDA_PTX_COMPILATION|CUDA_RESOLVE_DEVICE_SYMBOLS|CUDA_SEPARABLE_COMPILATION|CUDA_STANDARD|CUDA_STANDARD_REQUIRED|CXX_EXTENSIONS|CXX_STANDARD|CXX_STANDARD_REQUIRED|C_EXTENSIONS|C_STANDARD|C_STANDARD_REQUIRED|DEBUG_CONFIGURATIONS|DEBUG_POSTFIX|DEFINE_SYMBOL|DEFINITIONS|DEPENDS|DEPLOYMENT_ADDITIONAL_FILES|DEPLOYMENT_REMOTE_DIRECTORY|DISABLED|DISABLED_FEATURES|ECLIPSE_EXTRA_CPROJECT_CONTENTS|ECLIPSE_EXTRA_NATURES|ENABLED_FEATURES|ENABLED_LANGUAGES|ENABLE_EXPORTS|ENVIRONMENT|EXCLUDE_FROM_ALL|EXCLUDE_FROM_DEFAULT_BUILD|EXPORT_NAME|EXPORT_PROPERTIES|EXTERNAL_OBJECT|EchoString|FAIL_REGULAR_EXPRESSION|FIND_LIBRARY_USE_LIB32_PATHS|FIND_LIBRARY_USE_LIB64_PATHS|FIND_LIBRARY_USE_LIBX32_PATHS|FIND_LIBRARY_USE_OPENBSD_VERSIONING|FIXTURES_CLEANUP|FIXTURES_REQUIRED|FIXTURES_SETUP|FOLDER|FRAMEWORK|Fortran_FORMAT|Fortran_MODULE_DIRECTORY|GENERATED|GENERATOR_FILE_NAME|GENERATOR_IS_MULTI_CONFIG|GHS_INTEGRITY_APP|GHS_NO_SOURCE_GROUP_FILE|GLOBAL_DEPENDS_DEBUG_MODE|GLOBAL_DEPENDS_NO_CYCLES|GNUtoMS|HAS_CXX|HEADER_FILE_ONLY|HELPSTRING|IMPLICIT_DEPENDS_INCLUDE_TRANSFORM|IMPORTED|IMPORTED_(?:COMMON_LANGUAGE_RUNTIME|CONFIGURATIONS|GLOBAL|IMPLIB|LIBNAME|LINK_DEPENDENT_LIBRARIES|LINK_INTERFACE_(?:LANGUAGES|LIBRARIES|MULTIPLICITY)|LOCATION|NO_SONAME|OBJECTS|SONAME)|IMPORT_PREFIX|IMPORT_SUFFIX|INCLUDE_DIRECTORIES|INCLUDE_REGULAR_EXPRESSION|INSTALL_NAME_DIR|INSTALL_RPATH|INSTALL_RPATH_USE_LINK_PATH|INTERFACE_(?:AUTOUIC_OPTIONS|COMPILE_DEFINITIONS|COMPILE_FEATURES|COMPILE_OPTIONS|INCLUDE_DIRECTORIES|LINK_DEPENDS|LINK_DIRECTORIES|LINK_LIBRARIES|LINK_OPTIONS|POSITION_INDEPENDENT_CODE|SOURCES|SYSTEM_INCLUDE_DIRECTORIES)|INTERPROCEDURAL_OPTIMIZATION|IN_TRY_COMPILE|IOS_INSTALL_COMBINED|JOB_POOLS|JOB_POOL_COMPILE|JOB_POOL_LINK|KEEP_EXTENSION|LABELS|LANGUAGE|LIBRARY_OUTPUT_DIRECTORY|LIBRARY_OUTPUT_NAME|LINKER_LANGUAGE|LINK_(?:DEPENDS|DEPENDS_NO_SHARED|DIRECTORIES|FLAGS|INTERFACE_LIBRARIES|INTERFACE_MULTIPLICITY|LIBRARIES|OPTIONS|SEARCH_END_STATIC|SEARCH_START_STATIC|WHAT_YOU_USE)|LISTFILE_STACK|LOCATION|MACOSX_BUNDLE|MACOSX_BUNDLE_INFO_PLIST|MACOSX_FRAMEWORK_INFO_PLIST|MACOSX_PACKAGE_LOCATION|MACOSX_RPATH|MACROS|MANUALLY_ADDED_DEPENDENCIES|MEASUREMENT|MODIFIED|NAME|NO_SONAME|NO_SYSTEM_FROM_IMPORTED|OBJECT_DEPENDS|OBJECT_OUTPUTS|OSX_ARCHITECTURES|OUTPUT_NAME|PACKAGES_FOUND|PACKAGES_NOT_FOUND|PARENT_DIRECTORY|PASS_REGULAR_EXPRESSION|PDB_NAME|PDB_OUTPUT_DIRECTORY|POSITION_INDEPENDENT_CODE|POST_INSTALL_SCRIPT|PREDEFINED_TARGETS_FOLDER|PREFIX|PRE_INSTALL_SCRIPT|PRIVATE_HEADER|PROCESSORS|PROCESSOR_AFFINITY|PROJECT_LABEL|PUBLIC_HEADER|REPORT_UNDEFINED_PROPERTIES|REQUIRED_FILES|RESOURCE|RESOURCE_LOCK|RULE_LAUNCH_COMPILE|RULE_LAUNCH_CUSTOM|RULE_LAUNCH_LINK|RULE_MESSAGES|RUNTIME_OUTPUT_DIRECTORY|RUNTIME_OUTPUT_NAME|RUN_SERIAL|SKIP_AUTOGEN|SKIP_AUTOMOC|SKIP_AUTORCC|SKIP_AUTOUIC|SKIP_BUILD_RPATH|SKIP_RETURN_CODE|SOURCES|SOURCE_DIR|SOVERSION|STATIC_LIBRARY_FLAGS|STATIC_LIBRARY_OPTIONS|STRINGS|SUBDIRECTORIES|SUFFIX|SYMBOLIC|TARGET_ARCHIVES_MAY_BE_SHARED_LIBS|TARGET_MESSAGES|TARGET_SUPPORTS_SHARED_LIBS|TESTS|TEST_INCLUDE_FILE|TEST_INCLUDE_FILES|TIMEOUT|TIMEOUT_AFTER_MATCH|TYPE|USE_FOLDERS|VALUE|VARIABLES|VERSION|VISIBILITY_INLINES_HIDDEN|VS_(?:CONFIGURATION_TYPE|COPY_TO_OUT_DIR|DEBUGGER_(?:COMMAND|COMMAND_ARGUMENTS|ENVIRONMENT|WORKING_DIRECTORY)|DEPLOYMENT_CONTENT|DEPLOYMENT_LOCATION|DOTNET_REFERENCES|DOTNET_REFERENCES_COPY_LOCAL|GLOBAL_KEYWORD|GLOBAL_PROJECT_TYPES|GLOBAL_ROOTNAMESPACE|INCLUDE_IN_VSIX|IOT_STARTUP_TASK|KEYWORD|RESOURCE_GENERATOR|SCC_AUXPATH|SCC_LOCALPATH|SCC_PROJECTNAME|SCC_PROVIDER|SDK_REFERENCES|SHADER_(?:DISABLE_OPTIMIZATIONS|ENABLE_DEBUG|ENTRYPOINT|FLAGS|MODEL|OBJECT_FILE_NAME|OUTPUT_HEADER_FILE|TYPE|VARIABLE_NAME)|STARTUP_PROJECT|TOOL_OVERRIDE|USER_PROPS|WINRT_COMPONENT|WINRT_EXTENSIONS|WINRT_REFERENCES|XAML_TYPE)|WILL_FAIL|WIN32_EXECUTABLE|WINDOWS_EXPORT_ALL_SYMBOLS|WORKING_DIRECTORY|WRAP_EXCLUDE|XCODE_(?:EMIT_EFFECTIVE_PLATFORM_NAME|EXPLICIT_FILE_TYPE|FILE_ATTRIBUTES|LAST_KNOWN_FILE_TYPE|PRODUCT_TYPE|SCHEME_(?:ADDRESS_SANITIZER|ADDRESS_SANITIZER_USE_AFTER_RETURN|ARGUMENTS|DISABLE_MAIN_THREAD_CHECKER|DYNAMIC_LIBRARY_LOADS|DYNAMIC_LINKER_API_USAGE|ENVIRONMENT|EXECUTABLE|GUARD_MALLOC|MAIN_THREAD_CHECKER_STOP|MALLOC_GUARD_EDGES|MALLOC_SCRIBBLE|MALLOC_STACK|THREAD_SANITIZER(?:_STOP)?|UNDEFINED_BEHAVIOUR_SANITIZER(?:_STOP)?|ZOMBIE_OBJECTS))|XCTEST)\b/,keyword:/\b(?:add_compile_definitions|add_compile_options|add_custom_command|add_custom_target|add_definitions|add_dependencies|add_executable|add_library|add_link_options|add_subdirectory|add_test|aux_source_directory|break|build_command|build_name|cmake_host_system_information|cmake_minimum_required|cmake_parse_arguments|cmake_policy|configure_file|continue|create_test_sourcelist|ctest_build|ctest_configure|ctest_coverage|ctest_empty_binary_directory|ctest_memcheck|ctest_read_custom_files|ctest_run_script|ctest_sleep|ctest_start|ctest_submit|ctest_test|ctest_update|ctest_upload|define_property|else|elseif|enable_language|enable_testing|endforeach|endfunction|endif|endmacro|endwhile|exec_program|execute_process|export|export_library_dependencies|file|find_file|find_library|find_package|find_path|find_program|fltk_wrap_ui|foreach|function|get_cmake_property|get_directory_property|get_filename_component|get_property|get_source_file_property|get_target_property|get_test_property|if|include|include_directories|include_external_msproject|include_guard|include_regular_expression|install|install_files|install_programs|install_targets|link_directories|link_libraries|list|load_cache|load_command|macro|make_directory|mark_as_advanced|math|message|option|output_required_files|project|qt_wrap_cpp|qt_wrap_ui|remove|remove_definitions|return|separate_arguments|set|set_directory_properties|set_property|set_source_files_properties|set_target_properties|set_tests_properties|site_name|source_group|string|subdir_depends|subdirs|target_compile_definitions|target_compile_features|target_compile_options|target_include_directories|target_link_directories|target_link_libraries|target_link_options|target_sources|try_compile|try_run|unset|use_mangled_mesa|utility_source|variable_requires|variable_watch|while|write_file)(?=\s*\()\b/,boolean:/\b(?:ON|OFF|TRUE|FALSE)\b/,namespace:/\b(?:PROPERTIES|SHARED|PRIVATE|STATIC|PUBLIC|INTERFACE|TARGET_OBJECTS)\b/,operator:/\b(?:NOT|AND|OR|MATCHES|LESS|GREATER|EQUAL|STRLESS|STRGREATER|STREQUAL|VERSION_LESS|VERSION_EQUAL|VERSION_GREATER|DEFINED)\b/,inserted:{pattern:/\b\w+::\w+\b/,alias:"class-name"},number:/\b\d+(?:\.\d+)*\b/,function:/\b[a-z_]\w*(?=\s*\()\b/i,punctuation:/[()>}]|\$[<{]/}; +!function(e){var t=/#(?!\{).+/,n={pattern:/#\{[^}]+\}/,alias:"variable"};e.languages.coffeescript=e.languages.extend("javascript",{comment:t,string:[{pattern:/'(?:\\[\s\S]|[^\\'])*'/,greedy:!0},{pattern:/"(?:\\[\s\S]|[^\\"])*"/,greedy:!0,inside:{interpolation:n}}],keyword:/\b(?:and|break|by|catch|class|continue|debugger|delete|do|each|else|extend|extends|false|finally|for|if|in|instanceof|is|isnt|let|loop|namespace|new|no|not|null|of|off|on|or|own|return|super|switch|then|this|throw|true|try|typeof|undefined|unless|until|when|while|window|with|yes|yield)\b/,"class-member":{pattern:/@(?!\d)\w+/,alias:"variable"}}),e.languages.insertBefore("coffeescript","comment",{"multiline-comment":{pattern:/###[\s\S]+?###/,alias:"comment"},"block-regex":{pattern:/\/{3}[\s\S]*?\/{3}/,alias:"regex",inside:{comment:t,interpolation:n}}}),e.languages.insertBefore("coffeescript","string",{"inline-javascript":{pattern:/`(?:\\[\s\S]|[^\\`])*`/,inside:{delimiter:{pattern:/^`|`$/,alias:"punctuation"},script:{pattern:/[\s\S]+/,alias:"language-javascript",inside:e.languages.javascript}}},"multiline-string":[{pattern:/'''[\s\S]*?'''/,greedy:!0,alias:"string"},{pattern:/"""[\s\S]*?"""/,greedy:!0,alias:"string",inside:{interpolation:n}}]}),e.languages.insertBefore("coffeescript","keyword",{property:/(?!\d)\w+(?=\s*:(?!:))/}),delete e.languages.coffeescript["template-string"],e.languages.coffee=e.languages.coffeescript}(Prism); +!function(e){var r="(?:[ \t]+(?![ \t])(?:)?|)".replace(//g,function(){return"\\\\[\r\n](?:\\s|\\\\[\r\n]|#.*(?!.))*(?![\\s#]|\\\\[\r\n])"}),n="\"(?:[^\"\\\\\r\n]|\\\\(?:\r\n|[^]))*\"|'(?:[^'\\\\\r\n]|\\\\(?:\r\n|[^]))*'",t="--[\\w-]+=(?:|(?![\"'])(?:[^\\s\\\\]|\\\\.)+)".replace(//g,function(){return n}),o={pattern:RegExp(n),greedy:!0},i={pattern:/(^[ \t]*)#.*/m,lookbehind:!0,greedy:!0};function a(e,n){return e=e.replace(//g,function(){return t}).replace(//g,function(){return r}),RegExp(e,n)}e.languages.docker={instruction:{pattern:/(^[ \t]*)(?:ADD|ARG|CMD|COPY|ENTRYPOINT|ENV|EXPOSE|FROM|HEALTHCHECK|LABEL|MAINTAINER|ONBUILD|RUN|SHELL|STOPSIGNAL|USER|VOLUME|WORKDIR)(?=\s)(?:\\.|[^\r\n\\])*(?:\\$(?:\s|#.*$)*(?![\s#])(?:\\.|[^\r\n\\])*)*/im,lookbehind:!0,greedy:!0,inside:{options:{pattern:a("(^(?:ONBUILD)?\\w+)(?:)*","i"),lookbehind:!0,greedy:!0,inside:{property:{pattern:/(^|\s)--[\w-]+/,lookbehind:!0},string:[o,{pattern:/(=)(?!["'])(?:[^\s\\]|\\.)+/,lookbehind:!0}],operator:/\\$/m,punctuation:/=/}},keyword:[{pattern:a("(^(?:ONBUILD)?HEALTHCHECK(?:)*)(?:CMD|NONE)\\b","i"),lookbehind:!0,greedy:!0},{pattern:a("(^(?:ONBUILD)?FROM(?:)*(?!--)[^ \t\\\\]+)AS","i"),lookbehind:!0,greedy:!0},{pattern:a("(^ONBUILD)\\w+","i"),lookbehind:!0,greedy:!0},{pattern:/^\w+/,greedy:!0}],comment:i,string:o,variable:/\$(?:\w+|\{[^{}"'\\]*\})/,operator:/\\$/m}},comment:i},e.languages.dockerfile=e.languages.docker}(Prism); +Prism.languages.go=Prism.languages.extend("clike",{string:{pattern:/(["'`])(?:\\[\s\S]|(?!\1)[^\\])*\1/,greedy:!0},keyword:/\b(?:break|case|chan|const|continue|default|defer|else|fallthrough|for|func|go(?:to)?|if|import|interface|map|package|range|return|select|struct|switch|type|var)\b/,boolean:/\b(?:_|iota|nil|true|false)\b/,number:/(?:\b0x[a-f\d]+|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:e[-+]?\d+)?)i?/i,operator:/[*\/%^!=]=?|\+[=+]?|-[=-]?|\|[=|]?|&(?:=|&|\^=?)?|>(?:>=?|=)?|<(?:<=?|=|-)?|:=|\.\.\./,builtin:/\b(?:bool|byte|complex(?:64|128)|error|float(?:32|64)|rune|string|u?int(?:8|16|32|64)?|uintptr|append|cap|close|complex|copy|delete|imag|len|make|new|panic|print(?:ln)?|real|recover)\b/}),delete Prism.languages.go["class-name"]; +Prism.languages.ini={comment:/^[ \t]*[;#].*$/m,selector:/^[ \t]*\[.*?\]/m,constant:/^[ \t]*[^\s=]+?(?=[ \t]*=)/m,"attr-value":{pattern:/=.*/,inside:{punctuation:/^[=]/}}}; +!function(e){var t=/\b(?:abstract|assert|boolean|break|byte|case|catch|char|class|const|continue|default|do|double|else|enum|exports|extends|final|finally|float|for|goto|if|implements|import|instanceof|int|interface|long|module|native|new|non-sealed|null|open|opens|package|permits|private|protected|provides|public|record|requires|return|sealed|short|static|strictfp|super|switch|synchronized|this|throw|throws|to|transient|transitive|try|uses|var|void|volatile|while|with|yield)\b/,n="(^|[^\\w.])(?:[a-z]\\w*\\s*\\.\\s*)*(?:[A-Z]\\w*\\s*\\.\\s*)*",a={pattern:RegExp(n+"[A-Z](?:[\\d_A-Z]*[a-z]\\w*)?\\b"),lookbehind:!0,inside:{namespace:{pattern:/^[a-z]\w*(?:\s*\.\s*[a-z]\w*)*(?:\s*\.)?/,inside:{punctuation:/\./}},punctuation:/\./}};e.languages.java=e.languages.extend("clike",{"class-name":[a,{pattern:RegExp(n+"[A-Z]\\w*(?=\\s+\\w+\\s*[;,=())])"),lookbehind:!0,inside:a.inside}],keyword:t,function:[e.languages.clike.function,{pattern:/(\:\:\s*)[a-z_]\w*/,lookbehind:!0}],number:/\b0b[01][01_]*L?\b|\b0x(?:\.[\da-f_p+-]+|[\da-f_]+(?:\.[\da-f_p+-]+)?)\b|(?:\b\d[\d_]*(?:\.[\d_]*)?|\B\.\d[\d_]*)(?:e[+-]?\d[\d_]*)?[dfl]?/i,operator:{pattern:/(^|[^.])(?:<<=?|>>>?=?|->|--|\+\+|&&|\|\||::|[?:~]|[-+*/%&|^!=<>]=?)/m,lookbehind:!0}}),e.languages.insertBefore("java","string",{"triple-quoted-string":{pattern:/"""[ \t]*[\r\n](?:(?:"|"")?(?:\\.|[^"\\]))*"""/,greedy:!0,alias:"string"}}),e.languages.insertBefore("java","class-name",{annotation:{pattern:/(^|[^.])@\w+(?:\s*\.\s*\w+)*/,lookbehind:!0,alias:"punctuation"},generics:{pattern:/<(?:[\w\s,.&?]|<(?:[\w\s,.&?]|<(?:[\w\s,.&?]|<[\w\s,.&?]*>)*>)*>)*>/,inside:{"class-name":a,keyword:t,punctuation:/[<>(),.:]/,operator:/[?&|]/}},namespace:{pattern:RegExp("(\\b(?:exports|import(?:\\s+static)?|module|open|opens|package|provides|requires|to|transitive|uses|with)\\s+)(?!)[a-z]\\w*(?:\\.[a-z]\\w*)*\\.?".replace(//g,function(){return t.source})),lookbehind:!0,inside:{punctuation:/\./}}})}(Prism); +Prism.languages.json={property:{pattern:/(^|[^\\])"(?:\\.|[^\\"\r\n])*"(?=\s*:)/,lookbehind:!0,greedy:!0},string:{pattern:/(^|[^\\])"(?:\\.|[^\\"\r\n])*"(?!\s*:)/,lookbehind:!0,greedy:!0},comment:{pattern:/\/\/.*|\/\*[\s\S]*?(?:\*\/|$)/,greedy:!0},number:/-?\b\d+(?:\.\d+)?(?:e[+-]?\d+)?\b/i,punctuation:/[{}[\],]/,operator:/:/,boolean:/\b(?:true|false)\b/,null:{pattern:/\bnull\b/,alias:"keyword"}},Prism.languages.webmanifest=Prism.languages.json; +!function(n){var e=/("|')(?:\\(?:\r\n?|\n|.)|(?!\1)[^\\\r\n])*\1/;n.languages.json5=n.languages.extend("json",{property:[{pattern:RegExp(e.source+"(?=\\s*:)"),greedy:!0},{pattern:/(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*:)/,alias:"unquoted"}],string:{pattern:e,greedy:!0},number:/[+-]?\b(?:NaN|Infinity|0x[a-fA-F\d]+)\b|[+-]?(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:[eE][+-]?\d+\b)?/})}(Prism); +!function(e){e.languages.kotlin=e.languages.extend("clike",{keyword:{pattern:/(^|[^.])\b(?:abstract|actual|annotation|as|break|by|catch|class|companion|const|constructor|continue|crossinline|data|do|dynamic|else|enum|expect|external|final|finally|for|fun|get|if|import|in|infix|init|inline|inner|interface|internal|is|lateinit|noinline|null|object|open|operator|out|override|package|private|protected|public|reified|return|sealed|set|super|suspend|tailrec|this|throw|to|try|typealias|val|var|vararg|when|where|while)\b/,lookbehind:!0},function:[{pattern:/(?:`[^\r\n`]+`|\w+)(?=\s*\()/,greedy:!0},{pattern:/(\.)(?:`[^\r\n`]+`|\w+)(?=\s*\{)/,lookbehind:!0,greedy:!0}],number:/\b(?:0[xX][\da-fA-F]+(?:_[\da-fA-F]+)*|0[bB][01]+(?:_[01]+)*|\d+(?:_\d+)*(?:\.\d+(?:_\d+)*)?(?:[eE][+-]?\d+(?:_\d+)*)?[fFL]?)\b/,operator:/\+[+=]?|-[-=>]?|==?=?|!(?:!|==?)?|[\/*%<>]=?|[?:]:?|\.\.|&&|\|\||\b(?:and|inv|or|shl|shr|ushr|xor)\b/}),delete e.languages.kotlin["class-name"],e.languages.insertBefore("kotlin","string",{"raw-string":{pattern:/("""|''')[\s\S]*?\1/,alias:"string"}}),e.languages.insertBefore("kotlin","keyword",{annotation:{pattern:/\B@(?:\w+:)?(?:[A-Z]\w*|\[[^\]]+\])/,alias:"builtin"}}),e.languages.insertBefore("kotlin","function",{label:{pattern:/\w+@|@\w+/,alias:"symbol"}});var n=[{pattern:/\$\{[^}]+\}/,inside:{delimiter:{pattern:/^\$\{|\}$/,alias:"variable"},rest:e.languages.kotlin}},{pattern:/\$\w+/,alias:"variable"}];e.languages.kotlin.string.inside=e.languages.kotlin["raw-string"].inside={interpolation:n},e.languages.kt=e.languages.kotlin,e.languages.kts=e.languages.kotlin}(Prism); +!function(a){var e=/\\(?:[^a-z()[\]]|[a-z*]+)/i,n={"equation-command":{pattern:e,alias:"regex"}};a.languages.latex={comment:/%.*/m,cdata:{pattern:/(\\begin\{((?:verbatim|lstlisting)\*?)\})[\s\S]*?(?=\\end\{\2\})/,lookbehind:!0},equation:[{pattern:/\$\$(?:\\[\s\S]|[^\\$])+\$\$|\$(?:\\[\s\S]|[^\\$])+\$|\\\([\s\S]*?\\\)|\\\[[\s\S]*?\\\]/,inside:n,alias:"string"},{pattern:/(\\begin\{((?:equation|math|eqnarray|align|multline|gather)\*?)\})[\s\S]*?(?=\\end\{\2\})/,lookbehind:!0,inside:n,alias:"string"}],keyword:{pattern:/(\\(?:begin|end|ref|cite|label|usepackage|documentclass)(?:\[[^\]]+\])?\{)[^}]+(?=\})/,lookbehind:!0},url:{pattern:/(\\url\{)[^}]+(?=\})/,lookbehind:!0},headline:{pattern:/(\\(?:part|chapter|section|subsection|frametitle|subsubsection|paragraph|subparagraph|subsubparagraph|subsubsubparagraph)\*?(?:\[[^\]]+\])?\{)[^}]+(?=\}(?:\[[^\]]+\])?)/,lookbehind:!0,alias:"class-name"},function:{pattern:e,alias:"selector"},punctuation:/[[\]{}&]/},a.languages.tex=a.languages.latex,a.languages.context=a.languages.latex}(Prism); +Prism.languages.less=Prism.languages.extend("css",{comment:[/\/\*[\s\S]*?\*\//,{pattern:/(^|[^\\])\/\/.*/,lookbehind:!0}],atrule:{pattern:/@[\w-](?:\((?:[^(){}]|\([^(){}]*\))*\)|[^(){};\s]|\s+(?!\s))*?(?=\s*\{)/,inside:{punctuation:/[:()]/}},selector:{pattern:/(?:@\{[\w-]+\}|[^{};\s@])(?:@\{[\w-]+\}|\((?:[^(){}]|\([^(){}]*\))*\)|[^(){};@\s]|\s+(?!\s))*?(?=\s*\{)/,inside:{variable:/@+[\w-]+/}},property:/(?:@\{[\w-]+\}|[\w-])+(?:\+_?)?(?=\s*:)/i,operator:/[+\-*\/]/}),Prism.languages.insertBefore("less","property",{variable:[{pattern:/@[\w-]+\s*:/,inside:{punctuation:/:/}},/@@?[\w-]+/],"mixin-usage":{pattern:/([{;]\s*)[.#](?!\d)[\w-].*?(?=[(;])/,lookbehind:!0,alias:"function"}}); +Prism.languages.lua={comment:/^#!.+|--(?:\[(=*)\[[\s\S]*?\]\1\]|.*)/m,string:{pattern:/(["'])(?:(?!\1)[^\\\r\n]|\\z(?:\r\n|\s)|\\(?:\r\n|[^z]))*\1|\[(=*)\[[\s\S]*?\]\2\]/,greedy:!0},number:/\b0x[a-f\d]+(?:\.[a-f\d]*)?(?:p[+-]?\d+)?\b|\b\d+(?:\.\B|(?:\.\d*)?(?:e[+-]?\d+)?\b)|\B\.\d+(?:e[+-]?\d+)?\b/i,keyword:/\b(?:and|break|do|else|elseif|end|false|for|function|goto|if|in|local|nil|not|or|repeat|return|then|true|until|while)\b/,function:/(?!\d)\w+(?=\s*(?:[({]))/,operator:[/[-+*%^&|#]|\/\/?|<[<=]?|>[>=]?|[=~]=?/,{pattern:/(^|[^.])\.\.(?!\.)/,lookbehind:!0}],punctuation:/[\[\](){},;]|\.+|:+/}; +Prism.languages.makefile={comment:{pattern:/(^|[^\\])#(?:\\(?:\r\n|[\s\S])|[^\\\r\n])*/,lookbehind:!0},string:{pattern:/(["'])(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,greedy:!0},builtin:/\.[A-Z][^:#=\s]+(?=\s*:(?!=))/,symbol:{pattern:/^(?:[^:=\s]|[ \t]+(?![\s:]))+(?=\s*:(?!=))/m,inside:{variable:/\$+(?:(?!\$)[^(){}:#=\s]+|(?=[({]))/}},variable:/\$+(?:(?!\$)[^(){}:#=\s]+|\([@*%<^+?][DF]\)|(?=[({]))/,keyword:[/-include\b|\b(?:define|else|endef|endif|export|ifn?def|ifn?eq|include|override|private|sinclude|undefine|unexport|vpath)\b/,{pattern:/(\()(?:addsuffix|abspath|and|basename|call|dir|error|eval|file|filter(?:-out)?|findstring|firstword|flavor|foreach|guile|if|info|join|lastword|load|notdir|or|origin|patsubst|realpath|shell|sort|strip|subst|suffix|value|warning|wildcard|word(?:s|list)?)(?=[ \t])/,lookbehind:!0}],operator:/(?:::|[?:+!])?=|[|@]/,punctuation:/[:;(){}]/}; +!function(u){function n(n){return n=n.replace(//g,function(){return"(?:\\\\.|[^\\\\\n\r]|(?:\n|\r\n?)(?!\n|\r\n?))"}),RegExp("((?:^|[^\\\\])(?:\\\\{2})*)(?:"+n+")")}var e="(?:\\\\.|``(?:[^`\r\n]|`(?!`))+``|`[^`\r\n]+`|[^\\\\|\r\n`])+",t="\\|?__(?:\\|__)+\\|?(?:(?:\n|\r\n?)|(?![^]))".replace(/__/g,function(){return e}),a="\\|?[ \t]*:?-{3,}:?[ \t]*(?:\\|[ \t]*:?-{3,}:?[ \t]*)+\\|?(?:\n|\r\n?)";u.languages.markdown=u.languages.extend("markup",{}),u.languages.insertBefore("markdown","prolog",{"front-matter-block":{pattern:/(^(?:\s*[\r\n])?)---(?!.)[\s\S]*?[\r\n]---(?!.)/,lookbehind:!0,greedy:!0,inside:{punctuation:/^---|---$/,"font-matter":{pattern:/\S+(?:\s+\S+)*/,alias:["yaml","language-yaml"],inside:u.languages.yaml}}},blockquote:{pattern:/^>(?:[\t ]*>)*/m,alias:"punctuation"},table:{pattern:RegExp("^"+t+a+"(?:"+t+")*","m"),inside:{"table-data-rows":{pattern:RegExp("^("+t+a+")(?:"+t+")*$"),lookbehind:!0,inside:{"table-data":{pattern:RegExp(e),inside:u.languages.markdown},punctuation:/\|/}},"table-line":{pattern:RegExp("^("+t+")"+a+"$"),lookbehind:!0,inside:{punctuation:/\||:?-{3,}:?/}},"table-header-row":{pattern:RegExp("^"+t+"$"),inside:{"table-header":{pattern:RegExp(e),alias:"important",inside:u.languages.markdown},punctuation:/\|/}}}},code:[{pattern:/((?:^|\n)[ \t]*\n|(?:^|\r\n?)[ \t]*\r\n?)(?: {4}|\t).+(?:(?:\n|\r\n?)(?: {4}|\t).+)*/,lookbehind:!0,alias:"keyword"},{pattern:/``.+?``|`[^`\r\n]+`/,alias:"keyword"},{pattern:/^```[\s\S]*?^```$/m,greedy:!0,inside:{"code-block":{pattern:/^(```.*(?:\n|\r\n?))[\s\S]+?(?=(?:\n|\r\n?)^```$)/m,lookbehind:!0},"code-language":{pattern:/^(```).+/,lookbehind:!0},punctuation:/```/}}],title:[{pattern:/\S.*(?:\n|\r\n?)(?:==+|--+)(?=[ \t]*$)/m,alias:"important",inside:{punctuation:/==+$|--+$/}},{pattern:/(^\s*)#.+/m,lookbehind:!0,alias:"important",inside:{punctuation:/^#+|#+$/}}],hr:{pattern:/(^\s*)([*-])(?:[\t ]*\2){2,}(?=\s*$)/m,lookbehind:!0,alias:"punctuation"},list:{pattern:/(^\s*)(?:[*+-]|\d+\.)(?=[\t ].)/m,lookbehind:!0,alias:"punctuation"},"url-reference":{pattern:/!?\[[^\]]+\]:[\t ]+(?:\S+|<(?:\\.|[^>\\])+>)(?:[\t ]+(?:"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'|\((?:\\.|[^)\\])*\)))?/,inside:{variable:{pattern:/^(!?\[)[^\]]+/,lookbehind:!0},string:/(?:"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'|\((?:\\.|[^)\\])*\))$/,punctuation:/^[\[\]!:]|[<>]/},alias:"url"},bold:{pattern:n("\\b__(?:(?!_)|_(?:(?!_))+_)+__\\b|\\*\\*(?:(?!\\*)|\\*(?:(?!\\*))+\\*)+\\*\\*"),lookbehind:!0,greedy:!0,inside:{content:{pattern:/(^..)[\s\S]+(?=..$)/,lookbehind:!0,inside:{}},punctuation:/\*\*|__/}},italic:{pattern:n("\\b_(?:(?!_)|__(?:(?!_))+__)+_\\b|\\*(?:(?!\\*)|\\*\\*(?:(?!\\*))+\\*\\*)+\\*"),lookbehind:!0,greedy:!0,inside:{content:{pattern:/(^.)[\s\S]+(?=.$)/,lookbehind:!0,inside:{}},punctuation:/[*_]/}},strike:{pattern:n("(~~?)(?:(?!~))+?\\2"),lookbehind:!0,greedy:!0,inside:{content:{pattern:/(^~~?)[\s\S]+(?=\1$)/,lookbehind:!0,inside:{}},punctuation:/~~?/}},url:{pattern:n('!?\\[(?:(?!\\]))+\\](?:\\([^\\s)]+(?:[\t ]+"(?:\\\\.|[^"\\\\])*")?\\)|[ \t]?\\[(?:(?!\\]))+\\])'),lookbehind:!0,greedy:!0,inside:{operator:/^!/,content:{pattern:/(^\[)[^\]]+(?=\])/,lookbehind:!0,inside:{}},variable:{pattern:/(^\][ \t]?\[)[^\]]+(?=\]$)/,lookbehind:!0},url:{pattern:/(^\]\()[^\s)]+/,lookbehind:!0},string:{pattern:/(^[ \t]+)"(?:\\.|[^"\\])*"(?=\)$)/,lookbehind:!0}}}}),["url","bold","italic","strike"].forEach(function(e){["url","bold","italic","strike"].forEach(function(n){e!==n&&(u.languages.markdown[e].inside.content.inside[n]=u.languages.markdown[n])})}),u.hooks.add("after-tokenize",function(n){"markdown"!==n.language&&"md"!==n.language||!function n(e){if(e&&"string"!=typeof e)for(var t=0,a=e.length;t=d.length);t++){var a=n[t];if("string"==typeof a||a.content&&"string"==typeof a.content){var r=d[m],o=p.tokenStack[r],c="string"==typeof a?a:a.content,i=v(k,r),u=c.indexOf(i);if(-1]?|\+\+?|!=?|<>?=?|==?|&&?|\|\|?|[~^%?*\/@]/}),delete Prism.languages.objectivec["class-name"],Prism.languages.objc=Prism.languages.objectivec; +!function(a){var e=/\/\*[\s\S]*?\*\/|\/\/.*|#(?!\[).*/,t=[{pattern:/\b(?:false|true)\b/i,alias:"boolean"},{pattern:/(::\s*)\b[a-z_]\w*\b(?!\s*\()/i,greedy:!0,lookbehind:!0},{pattern:/(\b(?:case|const)\s+)\b[a-z_]\w*(?=\s*[;=])/i,greedy:!0,lookbehind:!0},/\b(?:null)\b/i,/\b[A-Z_][A-Z0-9_]*\b(?!\s*\()/],i=/\b0b[01]+(?:_[01]+)*\b|\b0o[0-7]+(?:_[0-7]+)*\b|\b0x[\da-f]+(?:_[\da-f]+)*\b|(?:\b\d+(?:_\d+)*\.?(?:\d+(?:_\d+)*)?|\B\.\d+)(?:e[+-]?\d+)?/i,n=/|\?\?=?|\.{3}|\??->|[!=]=?=?|::|\*\*=?|--|\+\+|&&|\|\||<<|>>|[?~]|[/^|%*&<>.+-]=?/,s=/[{}\[\](),:;]/;a.languages.php={delimiter:{pattern:/\?>$|^<\?(?:php(?=\s)|=)?/i,alias:"important"},comment:e,variable:/\$+(?:\w+\b|(?={))/i,package:{pattern:/(namespace\s+|use\s+(?:function\s+)?)(?:\\?\b[a-z_]\w*)+\b(?!\\)/i,lookbehind:!0,inside:{punctuation:/\\/}},"class-name-definition":{pattern:/(\b(?:class|enum|interface|trait)\s+)\b[a-z_]\w*(?!\\)\b/i,lookbehind:!0,alias:"class-name"},keyword:[{pattern:/(\(\s*)\b(?:bool|boolean|int|integer|float|string|object|array)\b(?=\s*\))/i,alias:"type-casting",greedy:!0,lookbehind:!0},{pattern:/([(,?]\s*)\b(?:bool|int|float|string|object|array(?!\s*\()|mixed|self|static|callable|iterable|(?:null|false)(?=\s*\|))\b(?=\s*\$)/i,alias:"type-hint",greedy:!0,lookbehind:!0},{pattern:/([(,?]\s*[a-z0-9_|]\|\s*)(?:null|false)\b(?=\s*\$)/i,alias:"type-hint",greedy:!0,lookbehind:!0},{pattern:/(\)\s*:\s*(?:\?\s*)?)\b(?:bool|int|float|string|object|void|array(?!\s*\()|mixed|self|static|callable|iterable|(?:null|false)(?=\s*\|))\b/i,alias:"return-type",greedy:!0,lookbehind:!0},{pattern:/(\)\s*:\s*(?:\?\s*)?[a-z0-9_|]\|\s*)(?:null|false)\b/i,alias:"return-type",greedy:!0,lookbehind:!0},{pattern:/\b(?:bool|int|float|string|object|void|array(?!\s*\()|mixed|iterable|(?:null|false)(?=\s*\|))\b/i,alias:"type-declaration",greedy:!0},{pattern:/(\|\s*)(?:null|false)\b/i,alias:"type-declaration",greedy:!0,lookbehind:!0},{pattern:/\b(?:parent|self|static)(?=\s*::)/i,alias:"static-context",greedy:!0},/\b(?:__halt_compiler|abstract|and|array|as|break|callable|case|catch|class|clone|const|continue|declare|default|die|do|echo|else|elseif|empty|enddeclare|endfor|endforeach|endif|endswitch|endwhile|enum|eval|exit|extends|final|finally|for|foreach|function|global|goto|if|implements|include|include_once|instanceof|insteadof|interface|isset|list|namespace|match|new|or|parent|print|private|protected|public|require|require_once|return|self|static|switch|throw|trait|try|unset|use|var|while|xor|yield)\b/i],"argument-name":{pattern:/([(,]\s+)\b[a-z_]\w*(?=\s*:(?!:))/i,lookbehind:!0},"class-name":[{pattern:/(\b(?:extends|implements|instanceof|new(?!\s+self|\s+static))\s+|\bcatch\s*\()\b[a-z_]\w*(?!\\)\b/i,greedy:!0,lookbehind:!0},{pattern:/(\|\s*)\b[a-z_]\w*(?!\\)\b/i,greedy:!0,lookbehind:!0},{pattern:/\b[a-z_]\w*(?!\\)\b(?=\s*\|)/i,greedy:!0},{pattern:/(\|\s*)(?:\\?\b[a-z_]\w*)+\b/i,alias:"class-name-fully-qualified",greedy:!0,lookbehind:!0,inside:{punctuation:/\\/}},{pattern:/(?:\\?\b[a-z_]\w*)+\b(?=\s*\|)/i,alias:"class-name-fully-qualified",greedy:!0,inside:{punctuation:/\\/}},{pattern:/(\b(?:extends|implements|instanceof|new(?!\s+self\b|\s+static\b))\s+|\bcatch\s*\()(?:\\?\b[a-z_]\w*)+\b(?!\\)/i,alias:"class-name-fully-qualified",greedy:!0,lookbehind:!0,inside:{punctuation:/\\/}},{pattern:/\b[a-z_]\w*(?=\s*\$)/i,alias:"type-declaration",greedy:!0},{pattern:/(?:\\?\b[a-z_]\w*)+(?=\s*\$)/i,alias:["class-name-fully-qualified","type-declaration"],greedy:!0,inside:{punctuation:/\\/}},{pattern:/\b[a-z_]\w*(?=\s*::)/i,alias:"static-context",greedy:!0},{pattern:/(?:\\?\b[a-z_]\w*)+(?=\s*::)/i,alias:["class-name-fully-qualified","static-context"],greedy:!0,inside:{punctuation:/\\/}},{pattern:/([(,?]\s*)[a-z_]\w*(?=\s*\$)/i,alias:"type-hint",greedy:!0,lookbehind:!0},{pattern:/([(,?]\s*)(?:\\?\b[a-z_]\w*)+(?=\s*\$)/i,alias:["class-name-fully-qualified","type-hint"],greedy:!0,lookbehind:!0,inside:{punctuation:/\\/}},{pattern:/(\)\s*:\s*(?:\?\s*)?)\b[a-z_]\w*(?!\\)\b/i,alias:"return-type",greedy:!0,lookbehind:!0},{pattern:/(\)\s*:\s*(?:\?\s*)?)(?:\\?\b[a-z_]\w*)+\b(?!\\)/i,alias:["class-name-fully-qualified","return-type"],greedy:!0,lookbehind:!0,inside:{punctuation:/\\/}}],constant:t,function:/\w+\s*(?=\()/,property:{pattern:/(->)[\w]+/,lookbehind:!0},number:i,operator:n,punctuation:s};var l={pattern:/{\$(?:{(?:{[^{}]+}|[^{}]+)}|[^{}])+}|(^|[^\\{])\$+(?:\w+(?:\[[^\r\n\[\]]+\]|->\w+)*)/,lookbehind:!0,inside:a.languages.php},r=[{pattern:/<<<'([^']+)'[\r\n](?:.*[\r\n])*?\1;/,alias:"nowdoc-string",greedy:!0,inside:{delimiter:{pattern:/^<<<'[^']+'|[a-z_]\w*;$/i,alias:"symbol",inside:{punctuation:/^<<<'?|[';]$/}}}},{pattern:/<<<(?:"([^"]+)"[\r\n](?:.*[\r\n])*?\1;|([a-z_]\w*)[\r\n](?:.*[\r\n])*?\2;)/i,alias:"heredoc-string",greedy:!0,inside:{delimiter:{pattern:/^<<<(?:"[^"]+"|[a-z_]\w*)|[a-z_]\w*;$/i,alias:"symbol",inside:{punctuation:/^<<<"?|[";]$/}},interpolation:l}},{pattern:/`(?:\\[\s\S]|[^\\`])*`/,alias:"backtick-quoted-string",greedy:!0},{pattern:/'(?:\\[\s\S]|[^\\'])*'/,alias:"single-quoted-string",greedy:!0},{pattern:/"(?:\\[\s\S]|[^\\"])*"/,alias:"double-quoted-string",greedy:!0,inside:{interpolation:l}}];a.languages.insertBefore("php","variable",{string:r}),a.languages.insertBefore("php","variable",{attribute:{pattern:/#\[(?:[^"'\/#]|\/(?![*/])|\/\/.*$|#(?!\[).*$|\/\*(?:[^*]|\*(?!\/))*\*\/|"(?:\\[\s\S]|[^\\"])*"|'(?:\\[\s\S]|[^\\'])*')+\](?=\s*[a-z$#])/im,greedy:!0,inside:{"attribute-content":{pattern:/^(#\[)[\s\S]+(?=]$)/,lookbehind:!0,inside:{comment:e,string:r,"attribute-class-name":[{pattern:/([^:]|^)\b[a-z_]\w*(?!\\)\b/i,alias:"class-name",greedy:!0,lookbehind:!0},{pattern:/([^:]|^)(?:\\?\b[a-z_]\w*)+/i,alias:["class-name","class-name-fully-qualified"],greedy:!0,lookbehind:!0,inside:{punctuation:/\\/}}],constant:t,number:i,operator:n,punctuation:s}},delimiter:{pattern:/^#\[|]$/,alias:"punctuation"}}}}),a.hooks.add("before-tokenize",function(e){if(/<\?/.test(e.code)){a.languages["markup-templating"].buildPlaceholders(e,"php",/<\?(?:[^"'/#]|\/(?![*/])|("|')(?:\\[\s\S]|(?!\1)[^\\])*\1|(?:\/\/|#(?!\[))(?:[^?\n\r]|\?(?!>))*(?=$|\?>|[\r\n])|#\[|\/\*(?:[^*]|\*(?!\/))*(?:\*\/|$))*?(?:\?>|$)/gi)}}),a.hooks.add("after-tokenize",function(e){a.languages["markup-templating"].tokenizePlaceholders(e,"php")})}(Prism); +!function(e){var i=Prism.languages.powershell={comment:[{pattern:/(^|[^`])<#[\s\S]*?#>/,lookbehind:!0},{pattern:/(^|[^`])#.*/,lookbehind:!0}],string:[{pattern:/"(?:`[\s\S]|[^`"])*"/,greedy:!0,inside:{function:{pattern:/(^|[^`])\$\((?:\$\([^\r\n()]*\)|(?!\$\()[^\r\n)])*\)/,lookbehind:!0,inside:{}}}},{pattern:/'(?:[^']|'')*'/,greedy:!0}],namespace:/\[[a-z](?:\[(?:\[[^\]]*]|[^\[\]])*]|[^\[\]])*]/i,boolean:/\$(?:true|false)\b/i,variable:/\$\w+\b/,function:[/\b(?:Add|Approve|Assert|Backup|Block|Checkpoint|Clear|Close|Compare|Complete|Compress|Confirm|Connect|Convert|ConvertFrom|ConvertTo|Copy|Debug|Deny|Disable|Disconnect|Dismount|Edit|Enable|Enter|Exit|Expand|Export|Find|ForEach|Format|Get|Grant|Group|Hide|Import|Initialize|Install|Invoke|Join|Limit|Lock|Measure|Merge|Move|New|Open|Optimize|Out|Ping|Pop|Protect|Publish|Push|Read|Receive|Redo|Register|Remove|Rename|Repair|Request|Reset|Resize|Resolve|Restart|Restore|Resume|Revoke|Save|Search|Select|Send|Set|Show|Skip|Sort|Split|Start|Step|Stop|Submit|Suspend|Switch|Sync|Tee|Test|Trace|Unblock|Undo|Uninstall|Unlock|Unprotect|Unpublish|Unregister|Update|Use|Wait|Watch|Where|Write)-[a-z]+\b/i,/\b(?:ac|cat|chdir|clc|cli|clp|clv|compare|copy|cp|cpi|cpp|cvpa|dbp|del|diff|dir|ebp|echo|epal|epcsv|epsn|erase|fc|fl|ft|fw|gal|gbp|gc|gci|gcs|gdr|gi|gl|gm|gp|gps|group|gsv|gu|gv|gwmi|iex|ii|ipal|ipcsv|ipsn|irm|iwmi|iwr|kill|lp|ls|measure|mi|mount|move|mp|mv|nal|ndr|ni|nv|ogv|popd|ps|pushd|pwd|rbp|rd|rdr|ren|ri|rm|rmdir|rni|rnp|rp|rv|rvpa|rwmi|sal|saps|sasv|sbp|sc|select|set|shcm|si|sl|sleep|sls|sort|sp|spps|spsv|start|sv|swmi|tee|trcm|type|write)\b/i],keyword:/\b(?:Begin|Break|Catch|Class|Continue|Data|Define|Do|DynamicParam|Else|ElseIf|End|Exit|Filter|Finally|For|ForEach|From|Function|If|InlineScript|Parallel|Param|Process|Return|Sequence|Switch|Throw|Trap|Try|Until|Using|Var|While|Workflow)\b/i,operator:{pattern:/(\W?)(?:!|-(?:eq|ne|gt|ge|lt|le|sh[lr]|not|b?(?:and|x?or)|(?:Not)?(?:Like|Match|Contains|In)|Replace|Join|is(?:Not)?|as)\b|-[-=]?|\+[+=]?|[*\/%]=?)/i,lookbehind:!0},punctuation:/[|{}[\];(),.]/},r=i.string[0].inside;r.boolean=i.boolean,r.variable=i.variable,r.function.inside=i}(); +Prism.languages.python={comment:{pattern:/(^|[^\\])#.*/,lookbehind:!0},"string-interpolation":{pattern:/(?:f|rf|fr)(?:("""|''')[\s\S]*?\1|("|')(?:\\.|(?!\2)[^\\\r\n])*\2)/i,greedy:!0,inside:{interpolation:{pattern:/((?:^|[^{])(?:{{)*){(?!{)(?:[^{}]|{(?!{)(?:[^{}]|{(?!{)(?:[^{}])+})+})+}/,lookbehind:!0,inside:{"format-spec":{pattern:/(:)[^:(){}]+(?=}$)/,lookbehind:!0},"conversion-option":{pattern:/![sra](?=[:}]$)/,alias:"punctuation"},rest:null}},string:/[\s\S]+/}},"triple-quoted-string":{pattern:/(?:[rub]|rb|br)?("""|''')[\s\S]*?\1/i,greedy:!0,alias:"string"},string:{pattern:/(?:[rub]|rb|br)?("|')(?:\\.|(?!\1)[^\\\r\n])*\1/i,greedy:!0},function:{pattern:/((?:^|\s)def[ \t]+)[a-zA-Z_]\w*(?=\s*\()/g,lookbehind:!0},"class-name":{pattern:/(\bclass\s+)\w+/i,lookbehind:!0},decorator:{pattern:/(^\s*)@\w+(?:\.\w+)*/im,lookbehind:!0,alias:["annotation","punctuation"],inside:{punctuation:/\./}},keyword:/\b(?:and|as|assert|async|await|break|class|continue|def|del|elif|else|except|exec|finally|for|from|global|if|import|in|is|lambda|nonlocal|not|or|pass|print|raise|return|try|while|with|yield)\b/,builtin:/\b(?:__import__|abs|all|any|apply|ascii|basestring|bin|bool|buffer|bytearray|bytes|callable|chr|classmethod|cmp|coerce|compile|complex|delattr|dict|dir|divmod|enumerate|eval|execfile|file|filter|float|format|frozenset|getattr|globals|hasattr|hash|help|hex|id|input|int|intern|isinstance|issubclass|iter|len|list|locals|long|map|max|memoryview|min|next|object|oct|open|ord|pow|property|range|raw_input|reduce|reload|repr|reversed|round|set|setattr|slice|sorted|staticmethod|str|sum|super|tuple|type|unichr|unicode|vars|xrange|zip)\b/,boolean:/\b(?:True|False|None)\b/,number:/(?:\b(?=\d)|\B(?=\.))(?:0[bo])?(?:(?:\d|0x[\da-f])[\da-f]*(?:\.\d*)?|\.\d+)(?:e[+-]?\d+)?j?\b/i,operator:/[-+%=]=?|!=|\*\*?=?|\/\/?=?|<[<=>]?|>[=>]?|[&|^~]/,punctuation:/[{}[\];(),.:]/},Prism.languages.python["string-interpolation"].inside.interpolation.inside.rest=Prism.languages.python,Prism.languages.py=Prism.languages.python; +!function(o){var t=o.util.clone(o.languages.javascript),e="(?:\\{*\\.{3}(?:[^{}]|)*\\})";function n(t,n){return t=t.replace(//g,function(){return"(?:\\s|//.*(?!.)|/\\*(?:[^*]|\\*(?!/))\\*/)"}).replace(//g,function(){return"(?:\\{(?:\\{(?:\\{[^{}]*\\}|[^{}])*\\}|[^{}])*\\})"}).replace(//g,function(){return e}),RegExp(t,n)}e=n(e).source,o.languages.jsx=o.languages.extend("markup",t),o.languages.jsx.tag.pattern=n("+(?:[\\w.:$-]+(?:=(?:\"(?:\\\\[^]|[^\\\\\"])*\"|'(?:\\\\[^]|[^\\\\'])*'|[^\\s{'\"/>=]+|))?|))**/?)?>"),o.languages.jsx.tag.inside.tag.pattern=/^<\/?[^\s>\/]*/i,o.languages.jsx.tag.inside["attr-value"].pattern=/=(?!\{)(?:"(?:\\[^]|[^\\"])*"|'(?:\\[^]|[^\\'])*'|[^\s'">]+)/i,o.languages.jsx.tag.inside.tag.inside["class-name"]=/^[A-Z]\w*(?:\.[A-Z]\w*)*$/,o.languages.jsx.tag.inside.comment=t.comment,o.languages.insertBefore("inside","attr-name",{spread:{pattern:n(""),inside:o.languages.jsx}},o.languages.jsx.tag),o.languages.insertBefore("inside","attr-value",{script:{pattern:n("="),inside:{"script-punctuation":{pattern:/^=(?={)/,alias:"punctuation"},rest:o.languages.jsx},alias:"language-javascript"}},o.languages.jsx.tag);var i=function(t){return t?"string"==typeof t?t:"string"==typeof t.content?t.content:t.content.map(i).join(""):""},r=function(t){for(var n=[],e=0;e"===a.content[a.content.length-1].content||n.push({tagName:i(a.content[0].content[1]),openedBraces:0}):0]|<(?:[^<>]|<[^<>]*>)*>)*>)?/,lookbehind:!0,greedy:!0,inside:null},keyword:/\b(?:abstract|as|asserts|async|await|break|case|catch|class|const|constructor|continue|debugger|declare|default|delete|do|else|enum|export|extends|finally|for|from|function|get|if|implements|import|in|instanceof|interface|is|keyof|let|module|namespace|new|null|of|package|private|protected|public|readonly|return|require|set|static|super|switch|this|throw|try|type|typeof|undefined|var|void|while|with|yield)\b/,builtin:/\b(?:string|Function|any|number|boolean|Array|symbol|console|Promise|unknown|never)\b/}),delete e.languages.typescript.parameter;var n=e.languages.extend("typescript",{});delete n["class-name"],e.languages.typescript["class-name"].inside=n,e.languages.insertBefore("typescript","function",{"generic-function":{pattern:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*\s*<(?:[^<>]|<(?:[^<>]|<[^<>]*>)*>)*>(?=\s*\()/,greedy:!0,inside:{function:/^#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*/,generic:{pattern:/<[\s\S]+/,alias:"class-name",inside:n}}}}),e.languages.ts=e.languages.typescript}(Prism); +!function(a){var e=a.util.clone(a.languages.typescript);a.languages.tsx=a.languages.extend("jsx",e);var t=a.languages.tsx.tag;t.pattern=RegExp("(^|[^\\w$]|(?=\\\\]|\\\\[^])*>[gim]{0,3}"].join("|")+")"),greedy:!0,inside:{interpolation:n}},{pattern:/(^|[^/])\/(?!\/)(?:\[[^\r\n\]]+\]|\\.|[^[/\\\r\n])+\/[gim]{0,3}(?=\s*(?:$|[\r\n,.;})]))/,lookbehind:!0,greedy:!0}],variable:/[@$]+[a-zA-Z_]\w*(?:[?!]|\b)/,symbol:{pattern:/(^|[^:]):[a-zA-Z_]\w*(?:[?!]|\b)/,lookbehind:!0},"method-definition":{pattern:/(\bdef\s+)[\w.]+/,lookbehind:!0,inside:{function:/\w+$/,rest:e.languages.ruby}}}),e.languages.insertBefore("ruby","number",{builtin:/\b(?:Array|Bignum|Binding|Class|Continuation|Dir|Exception|FalseClass|File|Stat|Fixnum|Float|Hash|Integer|IO|MatchData|Method|Module|NilClass|Numeric|Object|Proc|Range|Regexp|String|Struct|TMS|Symbol|ThreadGroup|Thread|Time|TrueClass)\b/,constant:/\b[A-Z]\w*(?:[?!]|\b)/}),e.languages.ruby.string=[{pattern:RegExp("%[qQiIwWxs]?(?:"+["([^a-zA-Z0-9\\s{(\\[<])(?:(?!\\1)[^\\\\]|\\\\[^])*\\1","\\((?:[^()\\\\]|\\\\[^])*\\)","\\{(?:[^#{}\\\\]|#(?:\\{[^}]+\\})?|\\\\[^])*\\}","\\[(?:[^\\[\\]\\\\]|\\\\[^])*\\]","<(?:[^<>\\\\]|\\\\[^])*>"].join("|")+")"),greedy:!0,inside:{interpolation:n}},{pattern:/("|')(?:#\{[^}]+\}|#(?!\{)|\\(?:\r\n|[\s\S])|(?!\1)[^\\#\r\n])*\1/,greedy:!0,inside:{interpolation:n}}],e.languages.rb=e.languages.ruby}(Prism); +!function(e){for(var a="/\\*(?:[^*/]|\\*(?!/)|/(?!\\*)|)*\\*/",t=0;t<2;t++)a=a.replace(//g,function(){return a});a=a.replace(//g,function(){return"[^\\s\\S]"}),e.languages.rust={comment:[{pattern:RegExp("(^|[^\\\\])"+a),lookbehind:!0,greedy:!0},{pattern:/(^|[^\\:])\/\/.*/,lookbehind:!0,greedy:!0}],string:{pattern:/b?"(?:\\[\s\S]|[^\\"])*"|b?r(#*)"(?:[^"]|"(?!\1))*"\1/,greedy:!0},char:{pattern:/b?'(?:\\(?:x[0-7][\da-fA-F]|u\{(?:[\da-fA-F]_*){1,6}\}|.)|[^\\\r\n\t'])'/,greedy:!0,alias:"string"},attribute:{pattern:/#!?\[(?:[^\[\]"]|"(?:\\[\s\S]|[^\\"])*")*\]/,greedy:!0,alias:"attr-name",inside:{string:null}},"closure-params":{pattern:/([=(,:]\s*|\bmove\s*)\|[^|]*\||\|[^|]*\|(?=\s*(?:\{|->))/,lookbehind:!0,greedy:!0,inside:{"closure-punctuation":{pattern:/^\||\|$/,alias:"punctuation"},rest:null}},"lifetime-annotation":{pattern:/'\w+/,alias:"symbol"},"fragment-specifier":{pattern:/(\$\w+:)[a-z]+/,lookbehind:!0,alias:"punctuation"},variable:/\$\w+/,"function-definition":{pattern:/(\bfn\s+)\w+/,lookbehind:!0,alias:"function"},"type-definition":{pattern:/(\b(?:enum|struct|union)\s+)\w+/,lookbehind:!0,alias:"class-name"},"module-declaration":[{pattern:/(\b(?:crate|mod)\s+)[a-z][a-z_\d]*/,lookbehind:!0,alias:"namespace"},{pattern:/(\b(?:crate|self|super)\s*)::\s*[a-z][a-z_\d]*\b(?:\s*::(?:\s*[a-z][a-z_\d]*\s*::)*)?/,lookbehind:!0,alias:"namespace",inside:{punctuation:/::/}}],keyword:[/\b(?:abstract|as|async|await|become|box|break|const|continue|crate|do|dyn|else|enum|extern|final|fn|for|if|impl|in|let|loop|macro|match|mod|move|mut|override|priv|pub|ref|return|self|Self|static|struct|super|trait|try|type|typeof|union|unsafe|unsized|use|virtual|where|while|yield)\b/,/\b(?:[ui](?:8|16|32|64|128|size)|f(?:32|64)|bool|char|str)\b/],function:/\b[a-z_]\w*(?=\s*(?:::\s*<|\())/,macro:{pattern:/\w+!/,alias:"property"},constant:/\b[A-Z_][A-Z_\d]+\b/,"class-name":/\b[A-Z]\w*\b/,namespace:{pattern:/(?:\b[a-z][a-z_\d]*\s*::\s*)*\b[a-z][a-z_\d]*\s*::(?!\s*<)/,inside:{punctuation:/::/}},number:/\b(?:0x[\dA-Fa-f](?:_?[\dA-Fa-f])*|0o[0-7](?:_?[0-7])*|0b[01](?:_?[01])*|(?:(?:\d(?:_?\d)*)?\.)?\d(?:_?\d)*(?:[Ee][+-]?\d+)?)(?:_?(?:[iu](?:8|16|32|64|size)?|f32|f64))?\b/,boolean:/\b(?:false|true)\b/,punctuation:/->|\.\.=|\.{1,3}|::|[{}[\];(),:]/,operator:/[-+*\/%!^]=?|=[=>]?|&[&=]?|\|[|=]?|<>?=?|[@?]/},e.languages.rust["closure-params"].inside.rest=e.languages.rust,e.languages.rust.attribute.inside.string=e.languages.rust.string}(Prism); +!function(e){e.languages.sass=e.languages.extend("css",{comment:{pattern:/^([ \t]*)\/[\/*].*(?:(?:\r?\n|\r)\1[ \t].+)*/m,lookbehind:!0}}),e.languages.insertBefore("sass","atrule",{"atrule-line":{pattern:/^(?:[ \t]*)[@+=].+/m,inside:{atrule:/(?:@[\w-]+|[+=])/m}}}),delete e.languages.sass.atrule;var t=/\$[-\w]+|#\{\$[-\w]+\}/,a=[/[+*\/%]|[=!]=|<=?|>=?|\b(?:and|or|not)\b/,{pattern:/(\s+)-(?=\s)/,lookbehind:!0}];e.languages.insertBefore("sass","property",{"variable-line":{pattern:/^[ \t]*\$.+/m,inside:{punctuation:/:/,variable:t,operator:a}},"property-line":{pattern:/^[ \t]*(?:[^:\s]+ *:.*|:[^:\s].*)/m,inside:{property:[/[^:\s]+(?=\s*:)/,{pattern:/(:)[^:\s]+/,lookbehind:!0}],punctuation:/:/,variable:t,operator:a,important:e.languages.sass.important}}}),delete e.languages.sass.property,delete e.languages.sass.important,e.languages.insertBefore("sass","punctuation",{selector:{pattern:/([ \t]*)\S(?:,[^,\r\n]+|[^,\r\n]*)(?:,[^,\r\n]+)*(?:,(?:\r?\n|\r)\1[ \t]+\S(?:,[^,\r\n]+|[^,\r\n]*)(?:,[^,\r\n]+)*)*/,lookbehind:!0}})}(Prism); +Prism.languages.scss=Prism.languages.extend("css",{comment:{pattern:/(^|[^\\])(?:\/\*[\s\S]*?\*\/|\/\/.*)/,lookbehind:!0},atrule:{pattern:/@[\w-](?:\([^()]+\)|[^()\s]|\s+(?!\s))*?(?=\s+[{;])/,inside:{rule:/@[\w-]+/}},url:/(?:[-a-z]+-)?url(?=\()/i,selector:{pattern:/(?=\S)[^@;{}()]?(?:[^@;{}()\s]|\s+(?!\s)|#\{\$[-\w]+\})+(?=\s*\{(?:\}|\s|[^}][^:{}]*[:{][^}]+))/m,inside:{parent:{pattern:/&/,alias:"important"},placeholder:/%[-\w]+/,variable:/\$[-\w]+|#\{\$[-\w]+\}/}},property:{pattern:/(?:[-\w]|\$[-\w]|#\{\$[-\w]+\})+(?=\s*:)/,inside:{variable:/\$[-\w]+|#\{\$[-\w]+\}/}}}),Prism.languages.insertBefore("scss","atrule",{keyword:[/@(?:if|else(?: if)?|forward|for|each|while|import|use|extend|debug|warn|mixin|include|function|return|content)\b/i,{pattern:/( +)(?:from|through)(?= )/,lookbehind:!0}]}),Prism.languages.insertBefore("scss","important",{variable:/\$[-\w]+|#\{\$[-\w]+\}/}),Prism.languages.insertBefore("scss","function",{"module-modifier":{pattern:/\b(?:as|with|show|hide)\b/i,alias:"keyword"},placeholder:{pattern:/%[-\w]+/,alias:"selector"},statement:{pattern:/\B!(?:default|optional)\b/i,alias:"keyword"},boolean:/\b(?:true|false)\b/,null:{pattern:/\bnull\b/,alias:"keyword"},operator:{pattern:/(\s)(?:[-+*\/%]|[=!]=|<=?|>=?|and|or|not)(?=\s)/,lookbehind:!0}}),Prism.languages.scss.atrule.inside.rest=Prism.languages.scss; +!function(s){var n=["([\"'])(?:\\\\[^]|\\$\\([^)]+\\)|\\$(?!\\()|`[^`]+`|(?!\\1)[^\\\\`$])*\\1","<<-?\\s*([\"']?)(\\w+)\\2\\s[^]*?[\r\n]\\3"].join("|");s.languages["shell-session"]={command:{pattern:RegExp('^(?:[^\\s@:$#*!/\\\\]+@[^\\s@:$#*!/\\\\]+(?::[^\0-\\x1F$#*?"<>:;|]+)?|[^\0-\\x1F$#*?"<>:;|]+)?[$#](?:[^\\\\\r\n\'"<]|\\\\.|<>)+'.replace(/<>/g,function(){return n}),"m"),greedy:!0,inside:{info:{pattern:/^[^#$]+/,alias:"punctuation",inside:{user:/^[^\s@:$#*!/\\]+@[^\s@:$#*!/\\]+/,punctuation:/:/,path:/[\s\S]+/}},bash:{pattern:/(^[$#]\s*)\S[\s\S]*/,lookbehind:!0,alias:"language-bash",inside:s.languages.bash},"shell-symbol":{pattern:/^[$#]/,alias:"important"}}},output:/.(?:.*(?:[\r\n]|.$))*/},s.languages["sh-session"]=s.languages.shellsession=s.languages["shell-session"]}(Prism); +Prism.languages.sql={comment:{pattern:/(^|[^\\])(?:\/\*[\s\S]*?\*\/|(?:--|\/\/|#).*)/,lookbehind:!0},variable:[{pattern:/@(["'`])(?:\\[\s\S]|(?!\1)[^\\])+\1/,greedy:!0},/@[\w.$]+/],string:{pattern:/(^|[^@\\])("|')(?:\\[\s\S]|(?!\2)[^\\]|\2\2)*\2/,greedy:!0,lookbehind:!0},function:/\b(?:AVG|COUNT|FIRST|FORMAT|LAST|LCASE|LEN|MAX|MID|MIN|MOD|NOW|ROUND|SUM|UCASE)(?=\s*\()/i,keyword:/\b(?:ACTION|ADD|AFTER|ALGORITHM|ALL|ALTER|ANALYZE|ANY|APPLY|AS|ASC|AUTHORIZATION|AUTO_INCREMENT|BACKUP|BDB|BEGIN|BERKELEYDB|BIGINT|BINARY|BIT|BLOB|BOOL|BOOLEAN|BREAK|BROWSE|BTREE|BULK|BY|CALL|CASCADED?|CASE|CHAIN|CHAR(?:ACTER|SET)?|CHECK(?:POINT)?|CLOSE|CLUSTERED|COALESCE|COLLATE|COLUMNS?|COMMENT|COMMIT(?:TED)?|COMPUTE|CONNECT|CONSISTENT|CONSTRAINT|CONTAINS(?:TABLE)?|CONTINUE|CONVERT|CREATE|CROSS|CURRENT(?:_DATE|_TIME|_TIMESTAMP|_USER)?|CURSOR|CYCLE|DATA(?:BASES?)?|DATE(?:TIME)?|DAY|DBCC|DEALLOCATE|DEC|DECIMAL|DECLARE|DEFAULT|DEFINER|DELAYED|DELETE|DELIMITERS?|DENY|DESC|DESCRIBE|DETERMINISTIC|DISABLE|DISCARD|DISK|DISTINCT|DISTINCTROW|DISTRIBUTED|DO|DOUBLE|DROP|DUMMY|DUMP(?:FILE)?|DUPLICATE|ELSE(?:IF)?|ENABLE|ENCLOSED|END|ENGINE|ENUM|ERRLVL|ERRORS|ESCAPED?|EXCEPT|EXEC(?:UTE)?|EXISTS|EXIT|EXPLAIN|EXTENDED|FETCH|FIELDS|FILE|FILLFACTOR|FIRST|FIXED|FLOAT|FOLLOWING|FOR(?: EACH ROW)?|FORCE|FOREIGN|FREETEXT(?:TABLE)?|FROM|FULL|FUNCTION|GEOMETRY(?:COLLECTION)?|GLOBAL|GOTO|GRANT|GROUP|HANDLER|HASH|HAVING|HOLDLOCK|HOUR|IDENTITY(?:_INSERT|COL)?|IF|IGNORE|IMPORT|INDEX|INFILE|INNER|INNODB|INOUT|INSERT|INT|INTEGER|INTERSECT|INTERVAL|INTO|INVOKER|ISOLATION|ITERATE|JOIN|KEYS?|KILL|LANGUAGE|LAST|LEAVE|LEFT|LEVEL|LIMIT|LINENO|LINES|LINESTRING|LOAD|LOCAL|LOCK|LONG(?:BLOB|TEXT)|LOOP|MATCH(?:ED)?|MEDIUM(?:BLOB|INT|TEXT)|MERGE|MIDDLEINT|MINUTE|MODE|MODIFIES|MODIFY|MONTH|MULTI(?:LINESTRING|POINT|POLYGON)|NATIONAL|NATURAL|NCHAR|NEXT|NO|NONCLUSTERED|NULLIF|NUMERIC|OFF?|OFFSETS?|ON|OPEN(?:DATASOURCE|QUERY|ROWSET)?|OPTIMIZE|OPTION(?:ALLY)?|ORDER|OUT(?:ER|FILE)?|OVER|PARTIAL|PARTITION|PERCENT|PIVOT|PLAN|POINT|POLYGON|PRECEDING|PRECISION|PREPARE|PREV|PRIMARY|PRINT|PRIVILEGES|PROC(?:EDURE)?|PUBLIC|PURGE|QUICK|RAISERROR|READS?|REAL|RECONFIGURE|REFERENCES|RELEASE|RENAME|REPEAT(?:ABLE)?|REPLACE|REPLICATION|REQUIRE|RESIGNAL|RESTORE|RESTRICT|RETURN(?:S|ING)?|REVOKE|RIGHT|ROLLBACK|ROUTINE|ROW(?:COUNT|GUIDCOL|S)?|RTREE|RULE|SAVE(?:POINT)?|SCHEMA|SECOND|SELECT|SERIAL(?:IZABLE)?|SESSION(?:_USER)?|SET(?:USER)?|SHARE|SHOW|SHUTDOWN|SIMPLE|SMALLINT|SNAPSHOT|SOME|SONAME|SQL|START(?:ING)?|STATISTICS|STATUS|STRIPED|SYSTEM_USER|TABLES?|TABLESPACE|TEMP(?:ORARY|TABLE)?|TERMINATED|TEXT(?:SIZE)?|THEN|TIME(?:STAMP)?|TINY(?:BLOB|INT|TEXT)|TOP?|TRAN(?:SACTIONS?)?|TRIGGER|TRUNCATE|TSEQUAL|TYPES?|UNBOUNDED|UNCOMMITTED|UNDEFINED|UNION|UNIQUE|UNLOCK|UNPIVOT|UNSIGNED|UPDATE(?:TEXT)?|USAGE|USE|USER|USING|VALUES?|VAR(?:BINARY|CHAR|CHARACTER|YING)|VIEW|WAITFOR|WARNINGS|WHEN|WHERE|WHILE|WITH(?: ROLLUP|IN)?|WORK|WRITE(?:TEXT)?|YEAR)\b/i,boolean:/\b(?:TRUE|FALSE|NULL)\b/i,number:/\b0x[\da-f]+\b|\b\d+(?:\.\d*)?|\B\.\d+\b/i,operator:/[-+*\/=%^~]|&&?|\|\|?|!=?|<(?:=>?|<|>)?|>[>=]?|\b(?:AND|BETWEEN|DIV|IN|ILIKE|IS|LIKE|NOT|OR|REGEXP|RLIKE|SOUNDS LIKE|XOR)\b/i,punctuation:/[;[\]()`,.]/}; +Prism.languages.swift=Prism.languages.extend("clike",{string:{pattern:/("|')(?:\\(?:\((?:[^()]|\([^)]+\))+\)|\r\n|[^(])|(?!\1)[^\\\r\n])*\1/,greedy:!0,inside:{interpolation:{pattern:/\\\((?:[^()]|\([^)]+\))+\)/,inside:{delimiter:{pattern:/^\\\(|\)$/,alias:"variable"}}}}},keyword:/\b(?:as|associativity|break|case|catch|class|continue|convenience|default|defer|deinit|didSet|do|dynamic(?:Type)?|else|enum|extension|fallthrough|final|for|func|get|guard|if|import|in|infix|init|inout|internal|is|lazy|left|let|mutating|new|none|nonmutating|operator|optional|override|postfix|precedence|prefix|private|protocol|public|repeat|required|rethrows|return|right|safe|self|Self|set|some|static|struct|subscript|super|switch|throws?|try|Type|typealias|unowned|unsafe|var|weak|where|while|willSet|__(?:COLUMN__|FILE__|FUNCTION__|LINE__))\b/,number:/\b(?:[\d_]+(?:\.[\de_]+)?|0x[a-f0-9_]+(?:\.[a-f0-9p_]+)?|0b[01_]+|0o[0-7_]+)\b/i,constant:/\b(?:nil|[A-Z_]{2,}|k[A-Z][A-Za-z_]+)\b/,atrule:/@\b(?:IB(?:Outlet|Designable|Action|Inspectable)|class_protocol|exported|noreturn|NS(?:Copying|Managed)|objc|UIApplicationMain|auto_closure)\b/,builtin:/\b(?:[A-Z]\S+|abs|advance|alignof(?:Value)?|assert|contains|count(?:Elements)?|debugPrint(?:ln)?|distance|drop(?:First|Last)|dump|enumerate|equal|filter|find|first|getVaList|indices|isEmpty|join|last|lexicographicalCompare|map|max(?:Element)?|min(?:Element)?|numericCast|overlaps|partition|print(?:ln)?|reduce|reflect|reverse|sizeof(?:Value)?|sort(?:ed)?|split|startsWith|stride(?:of(?:Value)?)?|suffix|swap|toDebugString|toString|transcode|underestimateCount|unsafeBitCast|with(?:ExtendedLifetime|Unsafe(?:MutablePointers?|Pointers?)|VaList))\b/}),Prism.languages.swift.string.inside.interpolation.inside.rest=Prism.languages.swift; +!function(n){function e(n,e){return RegExp(n.replace(//g,function(){return"(?:\\([^|()\n]+\\)|\\[[^\\]\n]+\\]|\\{[^}\n]+\\})"}).replace(//g,function(){return"(?:\\)|\\((?![^|()\n]+\\)))"}),e||"")}var i={css:{pattern:/\{[^}]+\}/,inside:{rest:n.languages.css}},"class-id":{pattern:/(\()[^)]+(?=\))/,lookbehind:!0,alias:"attr-value"},lang:{pattern:/(\[)[^\]]+(?=\])/,lookbehind:!0,alias:"attr-value"},punctuation:/[\\\/]\d+|\S/},t=n.languages.textile=n.languages.extend("markup",{phrase:{pattern:/(^|\r|\n)\S[\s\S]*?(?=$|\r?\n\r?\n|\r\r)/,lookbehind:!0,inside:{"block-tag":{pattern:e("^[a-z]\\w*(?:||[<>=])*\\."),inside:{modifier:{pattern:e("(^[a-z]\\w*)(?:||[<>=])+(?=\\.)"),lookbehind:!0,inside:i},tag:/^[a-z]\w*/,punctuation:/\.$/}},list:{pattern:e("^[*#]+*\\s+\\S.*","m"),inside:{modifier:{pattern:e("(^[*#]+)+"),lookbehind:!0,inside:i},punctuation:/^[*#]+/}},table:{pattern:e("^(?:(?:||[<>=^~])+\\.\\s*)?(?:\\|(?:(?:||[<>=^~_]|[\\\\/]\\d+)+\\.|(?!(?:||[<>=^~_]|[\\\\/]\\d+)+\\.))[^|]*)+\\|","m"),inside:{modifier:{pattern:e("(^|\\|(?:\r?\n|\r)?)(?:||[<>=^~_]|[\\\\/]\\d+)+(?=\\.)"),lookbehind:!0,inside:i},punctuation:/\||^\./}},inline:{pattern:e("(^|[^a-zA-Z\\d])(\\*\\*|__|\\?\\?|[*_%@+\\-^~])*.+?\\2(?![a-zA-Z\\d])"),lookbehind:!0,inside:{bold:{pattern:e("(^(\\*\\*?)*).+?(?=\\2)"),lookbehind:!0},italic:{pattern:e("(^(__?)*).+?(?=\\2)"),lookbehind:!0},cite:{pattern:e("(^\\?\\?*).+?(?=\\?\\?)"),lookbehind:!0,alias:"string"},code:{pattern:e("(^@*).+?(?=@)"),lookbehind:!0,alias:"keyword"},inserted:{pattern:e("(^\\+*).+?(?=\\+)"),lookbehind:!0},deleted:{pattern:e("(^-*).+?(?=-)"),lookbehind:!0},span:{pattern:e("(^%*).+?(?=%)"),lookbehind:!0},modifier:{pattern:e("(^\\*\\*|__|\\?\\?|[*_%@+\\-^~])+"),lookbehind:!0,inside:i},punctuation:/[*_%?@+\-^~]+/}},"link-ref":{pattern:/^\[[^\]]+\]\S+$/m,inside:{string:{pattern:/(\[)[^\]]+(?=\])/,lookbehind:!0},url:{pattern:/(\])\S+$/,lookbehind:!0},punctuation:/[\[\]]/}},link:{pattern:e('"*[^"]+":.+?(?=[^\\w/]?(?:\\s|$))'),inside:{text:{pattern:e('(^"*)[^"]+(?=")'),lookbehind:!0},modifier:{pattern:e('(^")+'),lookbehind:!0,inside:i},url:{pattern:/(:).+/,lookbehind:!0},punctuation:/[":]/}},image:{pattern:e("!(?:||[<>=])*(?![<>=])[^!\\s()]+(?:\\([^)]+\\))?!(?::.+?(?=[^\\w/]?(?:\\s|$)))?"),inside:{source:{pattern:e("(^!(?:||[<>=])*)(?![<>=])[^!\\s()]+(?:\\([^)]+\\))?(?=!)"),lookbehind:!0,alias:"url"},modifier:{pattern:e("(^!)(?:||[<>=])+"),lookbehind:!0,inside:i},url:{pattern:/(:).+/,lookbehind:!0},punctuation:/[!:]/}},footnote:{pattern:/\b\[\d+\]/,alias:"comment",inside:{punctuation:/\[|\]/}},acronym:{pattern:/\b[A-Z\d]+\([^)]+\)/,inside:{comment:{pattern:/(\()[^)]+(?=\))/,lookbehind:!0},punctuation:/[()]/}},mark:{pattern:/\b\((?:TM|R|C)\)/,alias:"comment",inside:{punctuation:/[()]/}}}}}),a=t.phrase.inside,o={inline:a.inline,link:a.link,image:a.image,footnote:a.footnote,acronym:a.acronym,mark:a.mark};t.tag.pattern=/<\/?(?!\d)[a-z0-9]+(?:\s+[^\s>\/=]+(?:=(?:("|')(?:\\[\s\S]|(?!\1)[^\\])*\1|[^\s'">=]+))?)*\s*\/?>/i;var r=a.inline.inside;r.bold.inside=o,r.italic.inside=o,r.inserted.inside=o,r.deleted.inside=o,r.span.inside=o;var d=a.table.inside;d.inline=o.inline,d.link=o.link,d.image=o.image,d.footnote=o.footnote,d.acronym=o.acronym,d.mark=o.mark}(Prism); +!function(e){var n=/[*&][^\s[\]{},]+/,r=/!(?:<[\w\-%#;/?:@&=+$,.!~*'()[\]]+>|(?:[a-zA-Z\d-]*!)?[\w\-%#;/?:@&=+$.~*'()]+)?/,t="(?:"+r.source+"(?:[ \t]+"+n.source+")?|"+n.source+"(?:[ \t]+"+r.source+")?)",a="(?:[^\\s\\x00-\\x08\\x0e-\\x1f!\"#%&'*,\\-:>?@[\\]`{|}\\x7f-\\x84\\x86-\\x9f\\ud800-\\udfff\\ufffe\\uffff]|[?:-])(?:[ \t]*(?:(?![#:])|:))*".replace(//g,function(){return"[^\\s\\x00-\\x08\\x0e-\\x1f,[\\]{}\\x7f-\\x84\\x86-\\x9f\\ud800-\\udfff\\ufffe\\uffff]"}),d="\"(?:[^\"\\\\\r\n]|\\\\.)*\"|'(?:[^'\\\\\r\n]|\\\\.)*'";function o(e,n){n=(n||"").replace(/m/g,"")+"m";var r="([:\\-,[{]\\s*(?:\\s<>[ \t]+)?)(?:<>)(?=[ \t]*(?:$|,|]|}|(?:[\r\n]\\s*)?#))".replace(/<>/g,function(){return t}).replace(/<>/g,function(){return e});return RegExp(r,n)}e.languages.yaml={scalar:{pattern:RegExp("([\\-:]\\s*(?:\\s<>[ \t]+)?[|>])[ \t]*(?:((?:\r?\n|\r)[ \t]+)\\S[^\r\n]*(?:\\2[^\r\n]+)*)".replace(/<>/g,function(){return t})),lookbehind:!0,alias:"string"},comment:/#.*/,key:{pattern:RegExp("((?:^|[:\\-,[{\r\n?])[ \t]*(?:<>[ \t]+)?)<>(?=\\s*:\\s)".replace(/<>/g,function(){return t}).replace(/<>/g,function(){return"(?:"+a+"|"+d+")"})),lookbehind:!0,greedy:!0,alias:"atrule"},directive:{pattern:/(^[ \t]*)%.+/m,lookbehind:!0,alias:"important"},datetime:{pattern:o("\\d{4}-\\d\\d?-\\d\\d?(?:[tT]|[ \t]+)\\d\\d?:\\d{2}:\\d{2}(?:\\.\\d*)?(?:[ \t]*(?:Z|[-+]\\d\\d?(?::\\d{2})?))?|\\d{4}-\\d{2}-\\d{2}|\\d\\d?:\\d{2}(?::\\d{2}(?:\\.\\d*)?)?"),lookbehind:!0,alias:"number"},boolean:{pattern:o("true|false","i"),lookbehind:!0,alias:"important"},null:{pattern:o("null|~","i"),lookbehind:!0,alias:"important"},string:{pattern:o(d),lookbehind:!0,greedy:!0},number:{pattern:o("[+-]?(?:0x[\\da-f]+|0o[0-7]+|(?:\\d+(?:\\.\\d*)?|\\.?\\d+)(?:e[+-]?\\d+)?|\\.inf|\\.nan)","i"),lookbehind:!0},tag:r,important:n,punctuation:/---|[:[\]{}\-,|>?]|\.\.\./},e.languages.yml=e.languages.yaml}(Prism); +!function(){if("undefined"!=typeof self&&self.Prism&&self.document){var o="line-numbers",a=/\n(?!$)/g,e=Prism.plugins.lineNumbers={getLine:function(e,n){if("PRE"===e.tagName&&e.classList.contains(o)){var t=e.querySelector(".line-numbers-rows");if(t){var i=parseInt(e.getAttribute("data-start"),10)||1,r=i+(t.children.length-1);n");(i=document.createElement("span")).setAttribute("aria-hidden","true"),i.className="line-numbers-rows",i.innerHTML=l,t.hasAttribute("data-start")&&(t.style.counterReset="linenumber "+(parseInt(t.getAttribute("data-start"),10)-1)),e.element.appendChild(i),u([t]),Prism.hooks.run("line-numbers",e)}}}),Prism.hooks.add("line-numbers",function(e){e.plugins=e.plugins||{},e.plugins.lineNumbers=!0})}function u(e){if(0!=(e=e.filter(function(e){var n=t(e)["white-space"];return"pre-wrap"===n||"pre-line"===n})).length){var n=e.map(function(e){var n=e.querySelector("code"),t=e.querySelector(".line-numbers-rows");if(n&&t){var i=e.querySelector(".line-numbers-sizer"),r=n.textContent.split(a);i||((i=document.createElement("span")).className="line-numbers-sizer",n.appendChild(i)),i.innerHTML="0",i.style.display="block";var s=i.getBoundingClientRect().height;return i.innerHTML="",{element:e,lines:r,lineHeights:[],oneLinerHeight:s,sizer:i}}}).filter(Boolean);n.forEach(function(e){var i=e.sizer,n=e.lines,r=e.lineHeights,s=e.oneLinerHeight;r[n.length-1]=void 0,n.forEach(function(e,n){if(e&&1img{height:auto;margin:15px auto;max-width:90%!important;width:auto}.viewer-footer{bottom:0;left:0;overflow:hidden;position:absolute;right:0;text-align:center}.viewer-navbar{background-color:rgba(0,0,0,.5);overflow:hidden}.viewer-list{-webkit-box-sizing:content-box;box-sizing:content-box;height:50px;margin:0;overflow:hidden;padding:1px 0}.viewer-list>li{color:transparent;cursor:pointer;float:left;font-size:0;height:50px;line-height:0;opacity:.5;overflow:hidden;-webkit-transition:opacity .15s;transition:opacity .15s;width:30px}.viewer-list>li:focus,.viewer-list>li:hover{opacity:.75}.viewer-list>li:focus{outline:0}.viewer-list>li+li{margin-left:1px}.viewer-list>.viewer-loading{position:relative}.viewer-list>.viewer-loading:after{border-width:2px;height:20px;margin-left:-10px;margin-top:-10px;width:20px}.viewer-list>.viewer-active,.viewer-list>.viewer-active:focus,.viewer-list>.viewer-active:hover{opacity:1}.viewer-player{background-color:#000;bottom:0;cursor:none;display:none;right:0;z-index:1}.viewer-player,.viewer-player>img{left:0;position:absolute;top:0}.viewer-toolbar>ul{display:inline-block;margin:0 auto 5px;overflow:hidden;padding:6px 3px}.viewer-toolbar>ul>li{background-color:rgba(0,0,0,.5);border-radius:50%;cursor:pointer;float:left;height:24px;overflow:hidden;-webkit-transition:background-color .15s;transition:background-color .15s;width:24px}.viewer-toolbar>ul>li:focus,.viewer-toolbar>ul>li:hover{background-color:rgba(0,0,0,.8)}.viewer-toolbar>ul>li:focus{-webkit-box-shadow:0 0 3px #fff;box-shadow:0 0 3px #fff;outline:0;position:relative;z-index:1}.viewer-toolbar>ul>li:before{margin:2px}.viewer-toolbar>ul>li+li{margin-left:1px}.viewer-toolbar>ul>.viewer-small{height:18px;margin-bottom:3px;margin-top:3px;width:18px}.viewer-toolbar>ul>.viewer-small:before{margin:-1px}.viewer-toolbar>ul>.viewer-large{height:30px;margin-bottom:-3px;margin-top:-3px;width:30px}.viewer-toolbar>ul>.viewer-large:before{margin:5px}.viewer-tooltip{background-color:rgba(0,0,0,.8);border-radius:10px;color:#fff;display:none;font-size:12px;height:20px;left:50%;line-height:20px;margin-left:-25px;margin-top:-10px;position:absolute;text-align:center;top:50%;width:50px}.viewer-title{color:#ccc;display:inline-block;font-size:12px;line-height:1;margin:0 5% 5px;max-width:90%;opacity:.8;overflow:hidden;text-overflow:ellipsis;-webkit-transition:opacity .15s;transition:opacity .15s;white-space:nowrap}.viewer-title:hover{opacity:1}.viewer-button{background-color:rgba(0,0,0,.5);border-radius:50%;cursor:pointer;height:80px;overflow:hidden;position:absolute;right:-40px;top:-40px;-webkit-transition:background-color .15s;transition:background-color .15s;width:80px}.viewer-button:focus,.viewer-button:hover{background-color:rgba(0,0,0,.8)}.viewer-button:focus{-webkit-box-shadow:0 0 3px #fff;box-shadow:0 0 3px #fff;outline:0}.viewer-button:before{bottom:15px;left:15px;position:absolute}.viewer-fixed{position:fixed}.viewer-open{overflow:hidden}.viewer-show{display:block}.viewer-hide{display:none}.viewer-backdrop{background-color:rgba(0,0,0,.5)}.viewer-invisible{visibility:hidden}.viewer-move{cursor:move;cursor:-webkit-grab;cursor:grab}.viewer-fade{opacity:0}.viewer-in{opacity:1}.viewer-transition{-webkit-transition:all .3s;transition:all .3s}@-webkit-keyframes viewer-spinner{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(1turn);transform:rotate(1turn)}}@keyframes viewer-spinner{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(1turn);transform:rotate(1turn)}}.viewer-loading:after{-webkit-animation:viewer-spinner 1s linear infinite;animation:viewer-spinner 1s linear infinite;border:4px solid hsla(0,0%,100%,.1);border-left-color:hsla(0,0%,100%,.5);border-radius:50%;content:"";display:inline-block;height:40px;left:50%;margin-left:-20px;margin-top:-20px;position:absolute;top:50%;width:40px;z-index:1}@media (max-width:767px){.viewer-hide-xs-down{display:none}}@media (max-width:991px){.viewer-hide-sm-down{display:none}}@media (max-width:1199px){.viewer-hide-md-down{display:none}} \ No newline at end of file diff --git a/maixcdk/static/image/github-fill.svg b/maixcdk/static/image/github-fill.svg new file mode 100644 index 00000000..d3fd1f6d --- /dev/null +++ b/maixcdk/static/image/github-fill.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/maixcdk/static/image/language.svg b/maixcdk/static/image/language.svg new file mode 100644 index 00000000..b1903d01 --- /dev/null +++ b/maixcdk/static/image/language.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/maixcdk/static/image/maix_ecosystem.png b/maixcdk/static/image/maix_ecosystem.png new file mode 100644 index 0000000000000000000000000000000000000000..dff03994a540f239b3c770ac77c1a15a46ff03e0 GIT binary patch literal 130806 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 F{{wtr^56gf literal 0 HcmV?d00001 diff --git a/maixcdk/static/image/maixcams.png b/maixcdk/static/image/maixcams.png new file mode 100644 index 0000000000000000000000000000000000000000..c87bb6f35e56a53b21e694572f942133cf67e33c GIT binary patch literal 281243 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
    1FsZ~b1#>$ zP%(yDf+_2s8rLXtEsFb@p-9J*+#9qG%qS|W6y$luU9%;G1c=EQqG=7mw6HXiadrY) z$y;^!zXr)7bZ$@DkAU@Dv{s$d8OmYRN8!R%TW)@S6$=dIOYGXVwji8LHkEQHutuqC z9@HCRLB?|3NbzrE^5hm0kNh09JMgyhT9I0Kh5(L3Av?#fuY_zS8Ql2XS->*GUI5?7 zdL^u`IVg`ERsSLC2lG5J^b4|*bW%US63%N9+etrnL?F*M$qb?GZ;W<7EXj*sFj0Y5 z;=4}e11tSfHE1qMK~enXFdBZE-VqA(JCCkab-rJW-wgVV#oGd!936FSHAZ@u z8QNZt;j`Wq&$sHBPW4bnwf(Nfd%!xuV^&4*9OBiL3~=_>%Qp||1Tt|HZPA?%szs|L zWxqz{`!1OxU~Lf<-2v=nd7gT&F78dfH6YNmFv>b+UGj|8qpLWqz4Rn5w&Z#`zw}9~ z*Zx0o=GA?-D+66geg9F3RM%bx%ux}=_HnG_Oe0@MwyPEeS4QbQuxEEkN-8F~ylnWf z^hUZUuyrmn{m+mK9+n+AN#gf;ks#Uf-#=EA2QbB?Buf(Ac~c;H1`tnf(W3?!M9h#< z$Xb_(iN30I1eJ1O{6O+<`o$HcLxF<&>x9x6vpzK zb8v;Q(|;M(Vpt+RB=~K!w6qLiWi)aBt#Y(7bIDKWl0?2<-*KIpmH*auUhDBa)ah== zDewRr>l8TpyRT7yC(#FF1|HPC^!QGF?9b}$NW>AaxMO}jl{1cK{VaP~r?QjYkZYS$ z!p&Mi=C>IgIJD3CJ9`<{fq(pMZSZ}A{Hc|{2WsW*C)SbFQFSdxfzn4jz_{~(xsu9pfGRDy+@i9hgjFQGp)Nr$j{;NZqV6>u; z-K}CA%uJM~o>X3{iixb_xLvt?WqddDZp9T!k^Rux0A3N=|E$T6O)l0u(Yj8475_r3)Vzw2kvLHm z`+6Ln<+wSR<+NM<8{6%6)oa#v0OS4G)(p}YBd&SXNON*Fq_}ntpvfp4cbQKd*)%(4e7ko~CuU?{o&gXAHV*_M7RCOR5yf>wQ zhv%Nv89{Ub0ChgKj8z|jO_3Hb+vUZ{-HK~q(xoqU|BBHY$d5_++OFcP^STYH$_#tC zp}UfdxRtP1XtRb;k`!M$@-^II#ug59mtyHc=RZw`h3<({GpK^{>L_n~2?iA2(X42h z@kE&c>!<_IcHlec^7v0JO6ddg4)0M7_^|x* zxA+%06LHpo^Wb4w-L&z(6Xydh)l;&B6k7EBJd@g7+@HOc+YXvBo^L?muTSrc;e~)g zS~_;w$03ja{XnOqcGH`?PW#Fl9NF`tEq z0r9}@=zfV5UqeH)^n%{~wHkT+*2J%0E17qEx^rjPw4*2&mvV8GHhGcNsp(zmUq*m7 zAN$9*`F>RsISrrg%~bUwmR~q{De=HquRg`W&?F3o_35K3-dltwt*$$&k+T;6)#U{R z=}w0vEF2(70ifHcbu&W|Dv2OxgDyJXLADdRB~ zY-|qB1MB`dtTpXXVeq%1yp>h#4In{fwW~zw8QUhguiP|GGCz`{+J8+Yawd%y_RcXV zp|+pIpmX{$a{6qdgLZpZbY6GnI?;}RUW?|lsYmfeFA8!`P(;KxbWO{%(A648v)c9kvzauibGXO%?M=p~}+Jv&%g=(#06s))U3#;Nq z$-tECUAp0eZJE~-Uu?~OvdRF8@Z-hF4_?{V6Z{v2reKd89oG9!aV%m&|M_`(Wu`sm zi=?NA8!mBf$m1hwJs)F~8Bz#&0e-O?xu^xz7@3%A_K(Yj?znPW8N4BL#qqCPA5ab* zUc+(9{me5OavhBqO5%|aYsgX&3N%5yABWd(B!#p|KRQggV9d+R)0W6|d49~rF8`=P zfhJ{)KpuqC`|vm&rC_dUaq2c6cC~oO4=Rz1ElkJ`P;VL8l!&mR@xIIA zr*4v1er&^kj!luOUY$x|*C8@L78mPVBGuNz$xX$1MNQqv^g*Au9m)Nb&7ceG&s=hw z-?FSKiR!goZG&6A2o+E}%I7k=C=*p946bU%Y3>LJXgJ8f?7!J4qP*21HY+0&o3P@K z%-n);^fXnrsYB1Ft925Bt~$N6x4o#1Nkx0r6~CqyQJ(#fwLqZ_njWaCrX{^Phuh~- zq|W_ngvWAN`g7mV=mSJ-O@%~L#!!c5Mv(x?(@712M7`Uu(@JCqAtMIoZihnjfCx36v?7;1Y;TI2=YTEm(ipnY~DVz1$=2$#6QpVfZ%cu2+ z_Z;4Xvu&s0WOoHGS9B<-RChgr+t>jwUSQ~Cca9d5l+yMIeF4bpboqhZNLSay(J_v- zx;411P3Q);4q&ejM&j_1Pp8K(XBc7&K| zcHgDph*MJ46$M$MxsgKN`KKH>JayamR`qE@HR#!)pv!4E0!qQ zo(M^Iu2sKia>!R~YWRPrvz(K+gB zJ3^Kz4jgh}iGS4>|9T(Vlxs;L=?rn0R;?<3 zLUc;tK|iF+O47<=j*{nMuHsV??3#Y%foICsDU3=@D0=3)Jc;#5{EHH|xVY;4#i|Ch zL-FFEt_bA=GvQH{+(2_4@{_o>-|j_A#}V@LtQ|+|#-YSrb4v&OB8TE(vPJ}p$`{D> zBBD00|6-!hG2JTq=SCae*vandV&OgP;eV z%NP$?ew!8AF0qQu3;GEqj#QzVJw7TylcA(R)8ZQWzw+&{_~uN$```%@#DS92Fkv*PTs~PitsQKKT|X_il@y4 z{M+@u(HT?#Me=aSC@;4WUagxlKSRSTqXX`;0)+2MF_mn7NlI#|`%oLtZZuN9IjH=D z6s=?^QtZmC3y0Mtd`K*07R^~F4t#pZ_6kY)mi&`>v)cFcVRQYlYQ0q?D%tDhiY#F1 zB)e7ws^3PKKHrUgH@o!XACf*kMC6P7061SF@P;>U50UEb1lhs0+T&wQ%iz)=ZZYFW zNC6KP!&`X1+-MS!|73LQX*d+LeQu>jAe0_>$hzXcOwqBszpjeM>b~<%+{2;!B>EB* zC**#BX4S@J=wbAWG;^;H#)K!_6kvxJT2zX9oJYMeZR<^oDYMmCE0LHcDe5t`}@2#8L z5X?}|eH*OyIYp>c;28;s0d^EW<`rwmDrAiB&f8seu zm84!+9LhW>#5@-4v-5g=UeUI=FX*Q@t*zjIoyIFC*110q;&vKlF$HYOdC`vJKR298 z55@I$-g+mKzI##{rH&vf8u@DGMo;ju5T4om?o@^M4^sK>1Uw+9r{vIGI3_l}z@0av z{t6jUOItf5GqbQ-sj^%?EYHEn$vbCW&jq&GhpfuRVRUn!=XYr=4v+lgz5MBA?#0*L zYTYE%TfM=yT(g7v{V|-oItorrRna?%iJhQS#8XQZ(q8vt0!&tT zleZlp!k3y`d~}=?4>up{+UrNPpP%jg;1@Nfl^e%ylw)`Q-dr|ZX6yW5;&i<^Aual= zn31Lb)!!^ci_py$su{I(HdmHA36ORD7h9r)5rkjEK0tqT`j&w#*2RIBgGI83_-QST z=ks?uoFo$?bwV+{#H~shWTERh4K6vZZs%a5K*^R_i+0Q(t45)mF`yDTC}Obpg*L6&9)?F-0L{kOmZ7yft2@g zA~aj7Xd`z!1U6}PUG3w0gGfs6Q*JQH*7+KP4&t14K(AzU_vjU)2xp>qsxV(kQ1Cz* z)aOC0lEmxZaFzr?sniY@-^`!;$)R=?JAEq;9V#l^*6i^Oc7|_ zF{xH2H1hx)w~oHCnaMM;TZ6o=flg0m6lg?8U%z10F?nA|E&KkCuS(Ipw|1P{L$R3F z$pTN@$*4X5!yiFc&HTCtyT$M=Lv?LJ1`Hlo=8k(w5*b79=-@nvNR1M+G7gREuU~Cf z^)(&P#mNB6w;fLVp{u&8o@`Y zs3-W;*m@hbAv@$7hAHh1ZHppJaMwQ# z86W?n$|qiap@F#_0$yHTAW5D_TmYiu6;pRgysDbcHu1fPxLovH$KDR-N9lnh}fla)yQ{!7C-mKb5kSN#3tRsGaI;+u#2d%K#a zph^E{bnUL&C#sbK^cN~BzN<@TNBjN`!lL03hX~bV1ZUTw2KXzQjuyX)1`(eJxvopC zw4`EgBx*-%TDCvxJ%6W(6^^9Ya(B`R@u+J$S` zWoKlt0JA$%4kgZ{S?l7T;FN7a{3Vidr6b$9~iv-j4Ou||0# zkywM8D<12(aS#sYQz5Ifj(vlkxhr4{=uofY(uXN{nVttH*EWEA%<%2%PWmC~E?Jrc zq+O@t$9VB#9k0gn5^7^E{{B67Saxc;-qmSuzsHuVWA5OQT9y+iKC8h?4E%0bMiGLx zNA`33NUX9|3mM?G<_*SN!>q7@1|&PyE&9?NMXcjx`HEFbE@l$KchMDNl@9iwmx1ev zhnBYB$jp!O44Wx5c76-B=}}Wgrc#Bie=>|!44mjbPn6NhW7#@7UqNhs8WUi>HW+R{ zWi>&Mb(0Ngq)K7Pjix&phv9yYv{9NpmH^3~3=&w%qM*_aJ2*M_ea)FB7|Qmm?mW~? zMKLS|t%NQ#%FmvZ27za#hwMw@?MGi>-&|}!GgbWleX-W@V&JRDjpx4G{Nmzehs*9o z-%IDQ>UPLO!~9ZT2F&?X^YVw%dqh+dKp!9cGk@kJ8o^fZwZ8SiU^B^w0)IMOsTgK! ziLGy4)HCkit?B9MgXkrZr16G7sGGg#Ux%;pV*BdYbp}@YLptBpmFP?3m0uU<>Zb}f zO|I=%cHZ1S2dtaeZ1O4jC~O{FpoD#PH2UgciEu>wFheh;l*k>E?UFOkB3Gus;+*J2 zUFmM=30m@R65YCyu88BD1%E{~~3&kt++CrGPpm2}6{D z3vC?cgk=ssQyh=iJ>N+w>rUDj9rLGxQ2Hpm8T!I?XnvIxlrLF8Xe5#KC|DhWDEpqM zX`dch^|q$?g9VbWFf_pqQSleBn+Zua3Nwi_AU0qBO~GT6-Hpa^Es3U;mbLQyx8}Lq zN_(MU`!|ww8d*9TO?9)@C);GKTim#L@mKrRXSYo?tACIs?vSs1a7~ECg&J>EL*$-_ zr5D)_Uzs|5UqTfQ^K2N}ulXIv8nC_ks{bjab$L5co^k_l0(l#dek1 z4_LHWpmTcvK?i~l5n%zhzb926Va{_}L_c!GqEfaLBe5TiFmA~MO`{{6WYBbO3)$5A zNuyzKU*+AIp-+<>zsinC=N8NF=HeNAz9o9ZrRyG*)my_d ziz%_mSB>hFWCD)#>0{IOjn*xO1!c1~8t+pRl?rCvQ92f=W^et=uv_A6Gf)R6oxe|7 z!p|nvF=TsWxF&?B?0KHx)O{<5!|&9~oASC~%;m0C`p+Lm@418>I>9+jai7`x69Oa} zjmOt`$9n<_KIikO(+p#9)+fC6S*47?rjmX&%gcM^+i5bMMUwr3-+q8$*7Ignwd`WJ zDE|4l`ynGw*UbVaoHE#dl8FTUt=0s zI$TT1YhWN$^Psu>;xCa-WLAY=oZO!8)~rDi>4pwGvOaWjpf{8qHj<(^uXhu-_K^{# z7U8$AiklGEn^+=hkO>rs<{8yY-u+{4GoZ{VrB_rc07(-QTHoSjUSsJCsBrNJD-rME zNVocqz4bP$`h)GK1Sfwoia?B~uyO&XUQRAT&^dpHDs#4dn@+^tBhtD%%JI5PU54%G z$CJ|=vjKdks=C9Eyezud`yFXTag5=8f>8~6Ao7^P!pA2npitMyrXbebvJXj4UhYR$ zUeR>r??O#*DBoXACD}n%u$G<2(yI7sz(;a>y@c(Er{FsbXz}fX|MOU20J;W#a(;hpHcw24k7*GzS?+!gYw=w7 z?H_DW2E2uaS5GYD3+wLJlYTcaiI-`om6klW+vB~$=oXi=DcsChadmTULFt6C-3Tlg z6iw`nNl*WdIpHOZj-jp#MK3)~oS9OI`aHP#KoeUE_Ua?{^-k{o%VxL z;j0*F;i+(J=3S`D%2$=>Vd2#?pX6Hpsd17XKdzYhzHKbw+c;8op1&|XCS#?;t$$Gr zz0~9k3b5Bcpv9`24#yj-sixZUxl?dLK?JhJIe5t69S5=VvpDY5WqNMcuE z{*6>LI(yu&vs(b)1w~-ER#vi2$K$^*L4$L}pAl54lC5KN_0GWT5GKvWN?Ban5TtNg ze^ibWj~7GAh4XH~-s>({6yR(pu`87ByQ93V6*o^DSyW(gq20Q-#OXZQiCx>;IDV6} zyx3_+RB??|rkY!-W^7T6lY~y7JjObAgqaQhF*Ir$p;t6v+ZlT$eUsgiuHH62JrvI) zAt6tbzW>;{?|L4VKK1jjj$V~n6C)AYUb?Njh+!>Dm>*>_X)&MuB52^BPMBny<7snM z*1tM45&XaJw~Mv`7fqRsh{k1zf?8He#)w)aF5j}4pRwBe-9HNLovNNS=Jr%@$Z^LhyDOlO^Ji8Q?S+(;Slb`c*wl-(U1#02Q6e4XXNk5q8S#{~?8Pe=zbv`1G5 zr!V?;Q^F*KG?)+%!+-pXp;^^<cV%@}ba7_44{UG$Xh(4sEhv}s+ozWjp>iJT-bFuly`;Q$cOTddOzA#U)gs<7Ux}VkrC8UtD?@5mUy zv%14B2n1KW5g(|QCLdR5nd0+`b%tG*t6HYwXL$dBXJy|9NW{knK5lnhS2^vj`NDRm z<*9Zr#yIyI@}7=0upoiwnCX{$#$aAwPSN;?(?I4~Z;4L%q<;6`DoQ2X+E)QcUjl%J zACMd@qlCOF4^{q=WEcK75OyVgK|&94;LsU7&yiLM$<@`z~=X zgZQe<-Ikpjw=4@TM-_`0lR=4DTfg?%b!cpqY2*c0V<(G2839nBc+vqbB3wT2gL9Kqj22bUyle z&za=ynmI+wpHdbj_3Cc8-O6K$eukJo!pGjx3v%>^p@Zh-gSidlIHT;+L0Jo%*muE} zWg%yNp0K5XlF6I#IVU?s0 zD5znh|p$s9MwS^{%k&aLux8eW{~ZdV>uGOIX#PcHU_ zm)mG*Y3bI( zxjm*v^i8mqUD&izMxs&%TrYmR!6Qa75p9cJDl6sOHq20@nM*uP9!;g_Z(+iuh)l;3 zG2D-`oIp;$*=coL=ywZ#33XWE!Xb~CP_MZMK*fB*W7u(xQnE;quKreo5EBHNr(g0Y z6Wit9_(*J4r-lE9QmH)~HieBdGlUYBB;Msta^0(!a>cV@7e4JcNL(0@-bghK^R#Kn zywX=`uR^M5dV5sC3gE|6_I%%cIxD?t6K48I7aY9Wt%9yZsiPl~a>vNx9{Qg+6zAlb zG7WwdeP+X9!X2v^yYiv%+f`$ZOF+MbFwsZZcJi^T5+Jt+H@-Td$?Oc=!ioyp;%WrjECUdV-;2#2OuH8# zBaWfrJJ2@1Mloqz9tcvmE&n4+M6qVMVBzGedhA5ccUdlVk`g@%v!OV{kDr|6bUriV zoVxLp%PGm)W*7HZ%cRgNl$?oWWc(I--;rEk9pf<>Ar)KHG7Dz7hCNGrSLL*-ULADHY+b2tDzSmP>mC^Z%Cab^xM4n0V{^hiPi>~ z60n^Ygay8Q;mcxwpUPC^c8WjbZ`)+1Fp0q+ro;3Ae(+rzsR+1VKVMt-=ajgaNmt`Y z9e#&6TJ(19alYkZgFlta$j{q8gLZpn(jTd0Xmrki_5y6bD5V9A~fbNdrUlsLK1t=G`l*bi6`02^Ex z{APCjX1q6>38N~_n+g#bkb>J1MR9M}bDquhvrnQ@=1)<|1lv zp%}gOjuRW#(0H1K=@IrykFh-GRduCcYWnfrGe4^JOB6SnE-IWi&%*3QMV6(Cy+QJ~ zF19xWf6w3RH#^crnzeUUyX8{#BaX+i z`4J>AdP;SPv`k_cRdR-U@9vnh1f8~ofKQPhhkOOutmC|m0F-YTb@W!q=MmHeOQz?3 zGK$#;$5_gR?2e-BpRSCK89&nsIIL_Gw&TgvEc6k}aL&v@F)!fcR4?P#bJ}Uvb6Ue; zuif0n_?FoPoYwk<_K$msWgCplEId#vG+d>=?X#kR;}Z)brh`G;3KHfnO^Ovn4d6>c zPuQ9Y9#ghBI2eGjUE$|xT0v19@~YB|&xGKC;1vNJ@g9NW;^6lI~V>tVBO5SVsWfh?G7vdcfhz)BxA zROPUdP7BKVArktL#0&*dmL^?(qy3j6p)nECpDAv!II}`#MkRh5yr8iBGZ26E92uguJ*ylzCN zxHkNW}pL81ot7)DX(FEsgm=62g4(5Y>d8wQ-Rs!=``25~0o|BW}^*g#S)~|Z3 zHiGv6Po}G@w5KS($Lr;pJ@#I`8jU= z`KCpKnV=PjJo8?ESd%YN-=u(fBj2tEzG!@(UMNz#LASWg4j}CtqF4Oq521AIc!pUw`!Y|Syp_za|L~Ld>|SEA zg0i&4EM|>}>5#ResDy640{UM+gf_?@c)I|5HqHa&D(L9Sj)=DGW@g*o0X=3BarKRJ zTQmE|78Y%QXDVg>Cd~##JE6*z+W%O9H1t0^I|RAv#WuokhI3Sh9D3D>7Sbk(=3kxS zZ~dLms!t>t-gRxGNoXPI)Q{qwpgk5&;Fy0AFY0MfWpZ2~nTurlcFp^9>Qnw%jaM8~ zw8Le{l&sJ@v^yE++`e1C^fI<=L|*B9QS8dyxshbxFd&o=08^d*F@x1)5NSX&qHFX- zyNnV`*+8QmUqBVUE1Wi0{mRF1f92Tyd26nGb~5nvG7!k9!4|z|dSPT=$` zjyP?-R5(A_9?ENKZGBuahSzla97%MXUYG^?PFN*b&2+5Y{)>zjTlZ~9`Gr8DY)X-C z_>}@=EJ%a|$=F)1y7sJU$i?`@{PRc7WCDxMI z(W|J3YTEw;^?`kFYQ11@-xLh3Jc@Q2k+Ja86@j(1evf~gtgUU_!5H2G%_5u_Kd@jNYEJaoRR3&|D@NK!B8 z834q=bNz2RjrwgnBd`2JF|7IYfj+~Mai|B-K$?t|VjeHGB`cLH{9a{D=dAad6w*}s zf>wf{r(Z0X09KIaPgAv%P@^bYI8mz*JnML6!VdS#^=VMV8~UgbwKNV+ZhUL7m?@|42A zl^RZS--`&=(TDeY*>2P@7f31O0UHHT<2tun@CTQe{=@c?6jjn4f-{JkRx4VUi3(xL z(VT3SZY`r*@T36v$tc~ZOr_#)@d6Bw33Yb%KZLX4U+2CkV_E6J?ZZwldFm*0MbkU1 zQ{T|phO&ceA7++Xn<&6ZAs-O@Wgezp zR^Sz$4|bn_tu38ot3s2<6h~WD+`_|qs3C(COYojIe4J;iYCK8AV5Kz0v1+QEbyCrw zBb8q@m%3pzmpkom>e8uT=ix<$_RGrTnkTRZD7Eq;0JYBt_(~*P>gbA^T)kxeWOKf&`oyS@yI{V!4c}cjk`nDKIr*kY@HUrAhCzO^I zSJvyLS*l_(GwYV4yWCF&nl3CVpJu1+o4uj>FX+C2onuClrKOi+4NEvCte3J!s?MH&&* z?|kqwKk`xUn`1`SVjd)>A?uM9*Lu2ZJ|XvYv26fEmLa zavh@6Y|tfHpi`*n+8x}Z_R_~i?zv`>X7UU9TyDO$wRL#fEWT(qbUINj{gSnxgyXi7 z)%%~v)l&gdKz?E>Wv6NcC~_o>X6c|{xm7($gXvR_*Y)~y$V(0+jC18t@%o?$d;O|O zBtF(kYLr~U^FMzp`0-zCv8&;0Z1JnJW~-SM@xa^ph+<74WHtl8ls~n5FE9aFo$#yP zAd+m}L){83VfI|! z_1(}1vP46!iYS+gcX|^HIQnnJM1doY35dzzp}F#NpMIvugS;l&>{q*D>G|0>*y>xo z(W*2M)@6uQ%D$L&2`P>FzV^9a$NSWg^gLW4^w*z7u_JXl5_6oR+V!ArC`13p5V~kW zuw{c>%`#1-&kj2H-bS)2bq4nPTfJq)h`UG9>T-+oTJGvc)fn72l*BK0$QYlD~x08QabAxd7PT3^mLg?)u(p0Y6aVI>p)XNphbu9fllrsAj2$Yy- z=8~+-Ubif+IG?U%f;=fU6Q|Xhofb#2jc%klKrhma6<-GBh787|71a>fXp1@`zEi*A zeg#IO!6Xd(V9Hz7fQP`4ogO}D8bhtZm!p+s=@2$}!LzEhI`NT3A(>KG73GU0O?sbp zl4pf#kuF^<9s)oUA$^lX*M2oKh_fTze6lolH7+N7O}eTTYp^lv$dBSL*!?D$pydXv zzR8NspgE8Ei3d@@s^6@V(vh-$;9X9sU@!$ywY0Nz{-_DdbH)Y^>GY1GDF?ft^T24qiP23N_& zI`T^3v)RHP1T-$ymvYHRq13}Pwe)&s_1>-01si-Ux{a9vkb*VT7o^Jfk<$=jE=7vv zKQk6?dKbq^TCFhX2td=X~8eJ*S>()6>Rfvlw#r28hF9q7`|kPy{CU-DYxuy*yUIgz3=Ni zY7yO%Il(VB-F^&fVzVwgVIzpnfTvO-*t0OKs%B~0r7yFF`J%x8NN)UwkegHm?+^y^ z7xyWbocZS&h{L`)?|l}X%EoRlb_HaIF*co8|3}kRhtvJP{V}Fv7$&FNbhkO0iJ3Oe zbWJzYQ%84A&(zd(=hV^Nb#xsZ?fHD4>-zoaAJ>KBec$&hkCaG3Z8%*`vpsXwPrl!p z5&u0=AHTi&X8Pmw9wm@BAkk(N^(i70Ikf@zNpx0g3e2%?a` zhk?j@l+W<^qRUK5v1TP6{gSM;LpxH2CiP^odP_@i`P<5Y2M_gs^P+XL`S9efNR8=r zky(UNQIJ4Cqhj~|LKEdZg8B{*Ai5+EG98;YPAt10{I|!el|$G2+NteGKjhrI;Wgy-p(zMN%o?J^NLY zCc#WJ937+n#dT=j>TO(|fvQ-#2yZ1I7p1xr(!q0B^%$^6YI(~?` zzYzGo6I)Dg%ZLEz!&WED879Upq13Xn4HsPL-WpK%&@6M$k-bY&3FA`xjjl^-dC7IK#6wh1mS<-}M zxY`pW!J1srSkkky%-qb=rQ{iJ8UUb>8k? zKGUCze`e*LrFRRhqLD$^Xrp~-Rt*KcR4T9WZTN*N=KL{EZ7RZg${A04kY>u zcwC){gd_n*;~e;VGgzg#-C}cSx@zXzDz%TCvH3~zq@JGskO2tA<~bdjQC6Y*xr0*` zOa!JU?e1(AbiCBSD;JNZz;hw}5&nB)1@dmmKeE*Mnu&hnw_ z6ZPhN1laH%FF?I)sTWaRd;2;_O;oOAts@)$-xBp7{%yC~nocR|epW2l7Loh3pSv65 z=u20kmhG(sJr;(xBmvD6vDH##E9(sJ{W0()&bVGQ_@4{(GY#D2!P?{AulbXodc&%w z4zF`Ga{U^XP=0Dt`RF&bV9{6!WIkMw2c!qU^QqmbICBhPUi=?O7Y-Q?#p7m~3Z4tV zykh;c9*=h|&({b5A-_)a6JK30fAA4J>39wVJoHO#;5G-mOmT`jHAOd>S`E4b#C)B3 zS;1cAp#T;Q1+yVyeq28hbIy-M23uMLIkJy7QHytEG@HtO&!B>sShh)9nDESUbH8JKZ365)Mu#H} zvQZFMczudek=bx^WuMDVY{7?9- z$t-cF`rE>*=}T#_#Wc4>d}LVb{$7Gri*&zuS%-3sY-xvA{-|x9EShrj$7)y6)i^-Hnkmw&e4XIe=qUG zhe{W`1RS$W2O#!Vwt8tMg;Ne%Bca=}crnFG5sIzi^P6~iM}4~d-Ee;??kX*{6~{AY zWNvq=5~^7AJ9*Mf3iGWI72-D}A7ix+{DNb&xQNsHRX!_=@!bne5z>j>=SQVwloNze z4b|FFl<|nS#rsx&Pl{9%q#3JQCZ1E&R7!w)@nxp?ocP5}xxgQ`V>{4ku*oeM_uZN) zydUBYK^{IRfoAz4W0TG=D{ywq{@MHM6)&AOIci%vEaylTy4~lfXY{g6lZ%-&!D8mn|4RrmMr{x35rzoBQd0l7{n66RjC_~i6Goc;JJIm1s5b1ih%SL zvwE3};&dP0eeu60;w2Xde(h>tU;g*9*$?PD?;IQysx68AcG1gCcGVp9Z7S^7oLtH4 zMY1H4Kj1lc#xgB!rs5y@oL6_OGZ8r7clW?(LVp6N*|1y`0@?f(B48x1We5;-Di*#> zMg6qgj9p~1k~QhF0pF_?cNOpoi3?gs>LtKM=uFazgu(GI7or&P6Q)U%@OY}}6?bvo zp)xu_U&J$P>(O6vA-r$vouK&#mpug6$^yXCSi|3A;esQlsqrKQ?b%8f-YwMGaP73AY3Mr5o&aIWAWbV4h zdc^p%S2xQ`=2cQT*Oxc1viDycpUwB{`$Atr?OR{zd)SV|K_riUTS~d7W#>Hl|I|X% zMw{>-`9{%H_~BpeicIT~ILyZkcjgM9GlYF1LmCAozC=SzIQ;FzWTku4Uq*P6$DW1D zr<$0z>)W_Tx+S&U$>%^xDe1$CjnqbJXz9LcoiTp=A-VcI{x-ltV%ZN$5|!J0N7z6i zQ5Oljy-~u!M5aYY{#wsEw8NvUto*@=9dWv5Qa)o7fB>SG=j8(~-bkK{?kF|!ONiXn z`G`o~2d$j9)0I??!Deh@`1JxoIbC<8V=ZowV+cH_&4%)dITdRmV4JUD)tzJ%grm|u zxk=Gx{C?Po7`<#fqMt10G`u$=(F!0%o7~CuN4--BDXX2P7?Vmq&dOQqg}8L%%3z}A z7VXFdaSargvJexe?jv|8>t9c2@Yl_3Uw8pw)QXjZpHIDi^vJ6@?bnW(`a6Z*p9K7% zi={51W{8f~-n(w$v%zsLdhJRPk0%D;K#M=rC}_J$XiNM_Z3RqQU#pbK-}?`2$xM=!y$)kOtDzZW)0pW1MP-+@EdKcHLn9Hns<|jvElFzfbHx6Xs6lQK|Ob%#`i6UbuE4y4a zbLOj-usr5Oy=F@;+rB`J3?8;i1pK0*o|O*1rkP-+8}#x#x&+vO%l9zRT%eMK!MIr$Ty+tHQVgT>{r zVcTE{805->%5cjKf(3}}B4J+i=og8Z3Ton@miF%Xe$3hub?!D(!cr$^>lij<%#Cf7 zugPB7RzOgNl49Wmk+YZOpA@%|XnqP&?=+dbkW)0zcKLUHV(LyeXQsH6o=NT{QE`!c zihCXgy-v}n7olQ4V+%do)1V7eszUkS96J+E<=?jkAWk>qNI*y^db03nVnw*spE!EI zLh2Wo_5|f_bsluf!XWFA*~oWiiiz!0w``$U5KY;?$ey-$CKVBM!JV>-QTS@a8q87+ zB<9ZShSHr%Qh0MuT!VnacLJslc0d-$S+UNdd@Fnd(YJ%OUx_C zAKIrECO!KuE=Y}yLAAYuAJ$L$-%;5=FyPfgzS_yru-vUGxN=$d0`?+XC*0)T@pO~! zvtQa&t;^aqe*j!C*SkLeuZ#`LsvKl+;h=a3`H)4znh_8z<+neAuk zQ1Oeihol+e9mVMSLZ{vc!h!$fptOhd~d(WV) zA+k!g#GV%g5njjch+-Lx;@P9~@}l)st{g7L2%6jQb4^PX6_ zY{qPA2nzm&rgEFpK)m$08C9(drLRH!S_dE+2F>s~VVZBz9yV&Jyn;2&2^+kD8#2XAFxU zl7{6399NXgzxMY1z@Y`I?pT1ACqoxF=x7*9EMP(xH%R3n}?|TyF*+_!4m0K^K7*MX%U8Y zs6&G)#Z`EDszXUk9KJVh=Z*^v0Oy0y`}Vb%gq*jzGh)cB$r8y@%@699)f%#O6`G9> zuBe6oribcm3P~(c2UZ1@h9&92?^53AYqG3{ z4$W`S*Gdf8*S&ba_Jwa>4wCakm?g`;k)No4W7D5sFrWUoBQqJeZ}DnKoF#id``e*Z z#~RZ}nnVt4lXi-}3+`8^h7la+Kg|$%Kd)Wuc8GfrBNC2#0(SBz-uD4O=!8qfdKXzJ zi84TUWOmkWW61$I2e*bf>FGG-(>7uk>%k*qR0UJ}&2FE~7q%CJT$`WyVwNAvab`U% ze(KmV<<@XAs)R%1(<)*hN5GooXwJmFAJL(3 zBNzpK_i!Q8P~YDo3_P*AfF8i;X&`yKiZJ%-Sy<^`pg{?+;;14gzC`muJxtRfJxelk zzeWKf%TArw{P46YAmSKC#-VEbY-|G)b>Vf_Oj#U1F~s_)A2+D!k~bea9wl^a%K)@X zGQ64$x)Sy-o5nCBt=5F+EVJV_Q-P%kC_x4M=Mvqr0E%2EIuL-F^$gq>cRY#&z=T#S zbp0p1cJE{Sr>16veD#ca!RLvJEQUCcnpWHW6#L$m_TF)n*%>FZ%5AC-9}*SNJ2|>~ z+H_@sNB|1LhbzRGp4AgVeDenX+KWX+g-%@D8Mk;+0c8=*o?Tp>K8bzTl3TMet1kxyjJ#%##UJ9)1%JfLz|UOB^}RIboZ z*HoH6r2W1elae6uVL_4p#Gs#xETCkv1b{CFn!O&xc8$0pAg+YOm`h*iIPpN`8SG-Cq9 zoWQyw5jUV^EHNn2$%W0I7r6R}CnagKzPV`1`lhy#AyW-hT70{)-lsedh6+nwp-9H{ zI{Ef{TO4x@ET;E1jnSpK)xU0WfY>Va#rcIpfPqF6qOk8SI-NoSj6${>-6;GpZ9KlA zFfMGC?U#VsRKEfccoS}c=>W#<-wr0dzRTGlw=Wb78x#K!5l#}8q*TzWp_2FUi?45F z{Djj`@@x0g<+16JSK6RqrpzeaK<*&=33d(+&8mvYQ^dYUi;DI@(_S~0*Ljrj;EiXp z?-&z*n0|p;+sZrQu#~h9IwrEFn>(bAB%)M3(38+q^?_D9+o84raVp6)e8+^e z1lj`yf+{7!o7cO$OnTP(B7TaJ0+(A3RJ#*ToSnt=BYh;F zJe8tPV1Dj4l!7ZQkKepUm|h)nthNfDfG&#QH`;6tN9L`MV0Ycjm;BD3k- zzv7^`j{L|OY-k~h&3$PVhhmJb)7;3IJ$dY*r=RAM>y$A5UvCXc@E407kn!0vtk!S9 zy|`E~u@Iv#-f5^{>(bkgD!@*1AeK5`1Mr+2vSL~if9EDsX8|NB!OQc~dFJbSW)-9J z>X1+L429_t)?uv6zCA`!Z;+!vm{C%Axq>3~y`?lUIE+rVQuwSgYx_|9l*@P9>%7BH z+1v^{PS3%yPfsRKGr2J6iBNk$FE(`ce_DWnO-(vo{ol`(_16`%2mC|FBHtXMyWnCe zDX`mhw5m-&sc33ucC=LT;~}cE=|f4_&Q5{V)SW;!oGHjv)_NM&)A4ND-!H#V?Z@P? z=Jwuyy;VAd;Bt}WpU2CrXP4p`=+DNW}{TNGnCclP( z%S*m0-yOCNwt)k8{VWlu`J#zmr+#Z5fT^COZI7W9Cg_jD=Q$+*brFsvYmZ)g+)Qc7 zC`K(7{z~wNQR>AXs;nh9!FbKhQT1!L?Bk!35nE9Wk3A`w?VfNFgrqmo>_9S0XiW+i zHb&5Q8@EmDnAvsdSRhTJ(4YWhv0?)DR&0_cUxq4> z3}NFPCR3euTvC&~G-$e`V6nrLDBMPFJ3G=k%Q`FjFAN_twD+RP2+>I}X76QWxb(eS zqLKgA&o$f^HE!%dfz>PTqE`GsxXZ#!*CBw&NFF1WHhOm3+3T;vNrt$H zS7V#CR+%kRdnNas_XC^da>n{?VAQ#i)}|06KTA8zWsVZBwwdQSW!U&EYuMpo(oOQ} zBDKxg{p|GVfRNhnY9_#EC!`keR z0TCv5uqKt~4Y!RlJfz+1X&Y0KV2cf}V5&Uvm98q_Z7~b9aSQtQ&ziI81{pJy2aZ)n zA?_WbU(hu@jUxKj(ZZ>^e+41lJ2LWWXorIBD#X75O@>>TzpKfI@t2^D>%HFr0JKoS z#qAiCO%-Mkfhx+jguaqrd|g8*MgMNVoR^*E=C~DAiVX8st-<-LV&f~VD+VfN2WIsp45QvCP40uzrpIjrsuvTgh^#B8oAz#j1yYu* z0vF4r7XRjhMmWGE{NeJ+@XrvUQ<99m1YT*8+Yo+0XLNDvo02NF7o=RCtYB)?pwC?R zjS_|Cjg1+v%|7X9lUB5vqnVfKto2|~Z=!P=?FNfn{y*&V5Z*hK=x;f+(xeH!kETbt z2?Wq!wT9r_;c79-SVb*Oa2Ht;EPv7cWWH~9bm^n!&k!^T6^Ob975P>kTKm7Pa6BGK zk4T|NbmRc5qun&lFtchI2@@&B!1x4u#Tr}n+6q}>>-0B96`?{AXG!$@8HV`HA5gv$ zSHJ51o;)@Pr5&H$+*pNLjngu`3G39-wLW)|(9hhcRX3Z>;T9Q9Q{xhB`GaV`Z?C@G zki6@OTD>lFl=OB-oIeU3g-6$SY!c{?WQ1^mJKt`#TB<>FHa#S7e0*>JioPZH;SqsB z6l-dnv1JDs)_u{`Z32tL4yF!mP=aKHrIb7<+uW51o=v{HoZC~?UI$E7*7`O)p65(Y zoFZ~BnCnl!8hY+CWCd*8s;H^{si_+|ZtzQ9NG$2FXS%U8eq?<*Ip{$B$)mp;8*qx( zaR}oDNJrq-?5%pfs|q0Lh~g|!r!bpJSvg5h7Q1EXl0nze`P_JxA9V{TFR5<=e=4vj ze-Y7A&Y{WJcqadTRn8w$ZC&rOxiU6F*p@RjNVoCt(JR4l1NgbVSl z$|g#uOuX8mH#aE#>;wZ&0@eI0#;IB*YFxtH{|5Jjl(K2C#{`Tlbmf#(MIQDmcSeR1 zhV|ww8yoN{ZNE@?fSzupQrjiA{KoeMEJ&RgiwXiTS;j%N#fE=f_3d|e)qvZCTQA9w z^c6r`hn`17L`&~R5(Eo13qdF!y(r!KDi5#mpzjZ-oAZAd-nW#;{haEx*RTCW{N1@} z=*h2)LinM`(&Re$*vFyqw%>#^rRV(^6q2`T z@1LriRMT(8EyB|s+kRPOm2KSO)N?s?{o1>$NmRn`Z1A5tDcF~Xi+fO# z_^aNaP-F|+(bu)^&V4dzPV{sWE2oDW?n0tE1CE3GHcoZx3h9fQ$s6J_{ zjiEB_3JoNL@;KdGUzYxI*eM8nEUVxV6&*gwHc+V8IYcZgbHaGJx&Q6WhaC2%uxby< zF_!%H-6F?xzB!X7@hU=#YU)F;wz(Jc$Q%l57v$Obf15yot1`*uV1TBP-+6u}$m!nZ$5_ zm=JM8$R3>B9!wJnr~>&H3AYP!3A%L2u_WFhw_>JwKRyzd%P2|{Tt(c8YZho24=ONp z7G}6WTS7?MZsb222LeI%r`CKKb}P;4p?zMOU@O5Cy)2WTdS$}>s-*d?(M@#8iIr(d zhG|UH#5@tIn|DSpSM-ae5l;a?ukuh$Sv&mk$gevl*~RS>TK%-NO=)}x0rLySx8Ogo z47xfM{K357{*ifgF!-oJ*V95QVE`%QZIJYrS6p=X@93py6%?2QKc?tsyLh~BOV{yyW&Zs&1VW@C{SIoQ30dngi)7O2C+vI<6y3$(L{kH}30B#R#NRc3#-IxJ`Nqpg zI3h;r={0l+;z(n*yk|dZe{HG%ixZiIgWux;zzoNiMr}+2UZmqgud*|Z$W#ipf)C*-k;asB>bO|fX zZ#fL0^6|xEvMa;X+grWLj;B{AO|ZaJdL>o#h}l0v0Y7@Dr?TKC*s3rrV^&1%x|o$- zZWswa_p{y$qpVhUHvppz!xS1S4QZh!9W^Zng@(|NJF^Uf0Iz-gS2cCg5)H=?ES zF~yMzakJWP{B+UrB*+)`J%rrx#=sW}JFR>^BrHDVB#r_KVADNw2Ht!&>{{_y16DYu z?fL?t?X$d<=n8%LypObs#(OwP_K7y2z5-r57 zTa}5St<7(c?_OXE<{oroN04L0$(niKK3-XIp01evLsca2@9F}`pz}*~kro~{_Fp8M zV#?3@T2(XlU*k@JiZKn0S^HQJ%`f>m?c?SdYJLR_WI*zxe6I23$!P>+p^TlDr{O?Ja73(}9o!Aagw zJ6M&a>vuI(-&y)W!(};}!IET~U^u-ZGf|`h&D*z>1yupxb=b@hm2E3a9w(k8j9$aR zcw!HhXb8$-rU;I+Q0~(A8P>M-Mc;lTt*0NO#c)CXg#IBw9uZx;S|W-J?R9BeyPYJF zta@TFxqrTmeQKm`{8%X0ocyGl>K}iAEH@zBpyifmG)^C3QQAC$X!m#znn_R3DXQVJ z9c>kp%>IRu@FCF!)iTS8bt{n&MOvopO@X$GL~22cZZEu|r#%U`;%DE(5%S@z3T;ui zt2iUmXD!w@`zHt8PV|+D;OD1c3Q_l@zED&wi*L3R#s~?6vi%5+p`l)TT zxUrIXLSkD|W>w&Zb+br1zF3uN|6l#Wmbv|ddvR^X^+1qu)+a*3oA%Tb41vT&w-wh@ zF3+5m_r;bejaw~P96Hw8(Shd{DYcKpWcO`(mmc$Q+w zXbqPnFn^hIatjRExg|TKDkgfbd;zGSq#^1ZBz`i_kagppssa?;6e=8K@v?wVgqsM{ zT;CKcIjA`SS?MV#D$Fb=Qm42s{ zL{=}Am{RoeiQ3uXOTFTxi}n3&ReskwOfA6&stz#23yrS0aQ@GD|sT!J!I$i2+2i923(gR=Cv61u_rZ_b>ePs#y|t(Ue{ zTQEjBWaN;kb5fU!#XA^8uytqjVJfw~*C61k!fvr9e#zm{!e{=~xFp}m3gY>Pppoxe z8B$s@`VeNbNQb~R?*T_As2}3nUT5C5OZU6&&b-IgEy~kQ4_{g$N3Rv~F2ZG(xu}7_ z;NW22BQW*We;Sm43#Nc>;PsO>F`>qjxLL;#eXq~T=E_8N626kWl_Gq#iK=898 z8Uh#>B~PC(QcoW`r#JM-Vnmc!UcGwtZ^s$9XX<7F^9t5)Em_pWj9>NAri;H{>zO7H zo2UCvkQ%&*w|T*VuJ?}{>inHI^$MHa!_BRro)%knk==m>J?J}t-X!#H!<(+RY8ktn z7B4O@Mm8sS$lQxzgO>@%VfL`zhsGl}$S{wiWsK+;96qRZ*E$=yvty1+Dbnd|o=y*0 zs+%%w@66!0-9J2Z6zy)vB(-nwIuxP~oq(6z4!EVO-WRh?&JB{iP}0+{S2EiKKxQ#9 zbsoM1OH)&%iZ7n7L~HQ$>>Mzn^092!g4oZ8b;={TU2qMdwNk>NyQQ0+l}mCf)AgNL zpB(vE;oU_fx9x<8xQQ9ds#r;<+IXGAc-{CK{&x!_GP9uV)QZ zXhzY>ob>IQapN61U0#Cg}-Qvhi7_t``{Bwb)K=~q}^XD{tO|I z277W`caiRq*_SWh1G{MM?!4pGaKYHTF16^`_4?V)pGjgY5`)8Wowo-~0ap76hR24( z#}*`Kv9LGj8p*sEuO-bUgSAIZQLIw|A31ruYhZAubprcHF@Yz;;0_K1wsEQQN9nWBTIm7rVXW)n>yXPE8fE@A0Pczv0eT za5*ToW!{D#&DVx&%~kA-$FsN}FDjQNS=!l=vY-YB%TkEB4jw>a{Bj{%fBtCaz2O7$ z7AlN^YdzsZ^@^x3NdX6WH>oO7gOK?n=->*|1#1drv^NKcLbKG>|6Zac9IF!<+N8%i zgQ*+^=gU-05c;d_KSzg68}uh|7OBPkWc@5p_Jh;NW;gAW7T~K=l}d!$_X}zk7h96i z{M0>=L07~_oeeZv!bs;9z{$7wW~R(Mk4ZkKAc?ic?tcG~=x63IsU+a_sa~ZE)%1A} z6`;26b!w_nvR&$BhziwP;8kRh7k_+d==sm~8)fWM7tL&?p6ut(?kIzk)V&&W~MT@(@?w%yhhe8^k+TZFunKLFQKZuqgQzL z8dxC78ZeS<&1`+yuR!H_CeaQ*7F~MLrptOBV&&FYoUN}{midvCu(9FP zem!GQ-eu+eA9Le#`bg8^bi1>Cfs66Fs$=_V*&lXHA$r%X3cI)!6I^j6GyzhY0mIow z%`oSd->DDv(qH=mowDpRm+fY%K4&~85i)6X={6nnnQeWbQwRFT{fcx(pHSXA1qn7N zAY{@-Hn0VW7SHrbAFq5CrM_S0O!hpP>;A$jX!x9J;#FE%n@EHp^!2@mWJ2$Ncdd0} zFi$UIG;FlRn+sEUJFHxcDmph{Mzf~6RKuQ!tga%7%~_f{jftF8?q%uerj_VdjL*#UtdGCzlfj7AN7^X=8e$-e zUV<~f zI04caa_D{hO71S`>nmH<(bNY0&%udgll5!EE`kY{ewI;-Zbk$}3JHxklQ`?Ji<>6K zxpp{*w(X~OAH)>JVn=vR4$><$wDjCuRPZ-HlV9{+IkPLkaxg>%)H%w>5AIaVX%NX} z`J6Omxi5N` z)L1z>jnl(y6juixE3`%0#q+-bOSxP(8Qe}YIc};tdU8Nd<^#C_=8IcYv?st5`rJ2m z+%n&AioUhgbLr~lM8ScT&Jh&`V_#sak9>(CI{2IS!b3)K z#3U)d*!8rOpl)Y|lBkv#YR38cDHD?`Q&FjibYb@pi;7Ub6r_R#6jWxy1P@B*KAs3A zU48wZ`g*kJ;N~Gzr6RH6WJZV`0VDTS5$4oD@gDgeBZRDujAq6rTZfGno4|0c=jy`U z<|_?N3T@fo&IJ%n&Xb|5_w7W9%_dH!xSe=1$c289Ib_@_n>(%0jfzAUb{*)X6waoN zcg*zpgie9!e8D2l%SYF!0bC@bTNSM{p0CYJ7fPc|`?)5#mBy@=mGGCK0uNbN)5KvW6G=ZS~r`Id+^Qm~k7QpYFXL&Ii2C1|*BCr;#!8 zUoZz^sO4XdZ9RN8>a=fI2~)=2zJ=o%4_rMzdS>5vRW*N~Yr8We)BeNpFp}UII)+c^ zeBxF0GwwaU`~cMO^gD4f5Voytje)@pE1XC6GP%* z1JC9DxBo7!@e(q%Udn_n5`4=G$*mL)f$+vk0{UZ4jx3pQ^hJBSs zRe7gAl>|Gr$f%#H*y)>otx(Wgn(+!Bs7JlH_L<`D;6?Ah{+}{UB$5z#RA5Z%m7$iWJP0zM?VW;6{1(hRqO0nq*P1)xU5aqQ*c{l&>VwL|8i#uJN(X>*jn;BvOs+x_i?s^TwV}h zMPUIY%c8fh)qFCxn>m3+;_~WR+;OsM%Frb_$AFx_#Ev%@H`QCj3Xx52aDQ53bTeY8 zMxGdG4FZ8aPN$Kw!8^tA&K8HqEDJjZSH){lD)0r1YMR^C0kFC>LrP-%h^3hojOC#$+g0``=Y}hA;8#Cqu*#u;o zpj)qrO7o>~f&I~Pb-FogGHSDuS1~U8h637LL$#7q(!0VgH_D5gU?BAj9hoAX2|}39 zW$J48i;*;Wqq%kOmC!4IQO8Y++D|XQ(e+xJ?F}&roh!luNZ>&CNDI?MnMrdL zv$?6Q#TjFaty*JH{PDW_PokD7dRYb-S4CBs7CfG#j4R8==Lx5odk*Y5R`*rsNZL9w@D%9)eB_UY0;Z_wGWE_SY@9OM7hB|dF zUXkk>XO-xb1z*0_Hw{7UsQmL2zsP#pc4Ty<0A1Me5X9MhW@w{2Iyi5GkE=Cc@oO$M zUWSXGzh??6fh9t7+Ef?xT`2k+1s)WRzrSjA^q65N0elSTBayZ9%M+WvNzF4R@I>&V z^UWG9I2p1%(_H=IdSx!96zn=_9T8+vp6B>xby;I`2>E51AU?|smE*!Mmk1t#^lm41 zd^vq7@&N(!&K~@Rj9x}X1I!c|2|-@e+JyEeq~em|Gx5~;bBybwm7Wty=r=%YxA`;K zo2by3rrSG%NZE)8vv1mbd1APj9G#8cc8GD?V}aMvvOOD{{jeGqS12 z%x&7|1*qGG$)%;ogzqk3lqjrl#p#PEG?*s-Um{cGwm28F(!1Lc7Th@W9ESui()NqhuQjb{|hAdT2!t+^EJdoLevEI<7qRdnWPkpuQUq z2U36jGhP1w*7$fDAn6Fe?kuUpt;hC`q8sZJKLfrb1$J>KDXHD)+X`e7VKPXZ|BH3m zO^IRWVBZpIPfissg}!l}mz=s5JjnX_4DZLzUW8+B*CJoX77S+cGa=m#Z_n2sE-V4A zi_%r^dZmJe-oo^4({Wl%+0H*UGxXA=e+!xyo1F%%gOxNhe3lfK%T;viCMa=>{&s3A z2Dz>XxRl~(YW*oow)O~0ntW##)Y&|!u2yMo?G(79gv!;}zk7>Ws+eTv?VZurCnvgd z%&Ntna`tGLDRa{3Kz45-vWcn7tz8TD`NsZh7DU%~-v8~#o01PjL>i=%m>Gb6<@XG$ zBE?qYNhBMa0IaR0C43|PwJ%gHcL`PnCd=heNVe|(wEWU2)$V^?cPC=)#2oy&!8#XcoL18zmxb?h%=nfwxZiGM@DQJ+{S zm3ABq8pDt@MOcPKGeH=@SeH?%Y`wsY*KhzQ(^qcU`7F4mn^b!Nawy4Lw)WFG7q5;l zz2~pp*#uuHYw&~WRBJOvS!48rK?R^R9?2vAuT49w8qC;61v-bh!z5g+`7>4;N33yd zM7p&Wlm<|L)CdB0olJJh3{z9<2pI`^q7R*M`mC<^C zg}aEzOZe!9GKB`-)QvlIb`qC$S$zjb7CilF_7T#Lk*6I3V&6XuTl1|Qo)AuxEXLP= zEx@qjA1)hJaFlcX*3fqD??=pydB*g^+g`;FrMhMg4iQW_i~YYRG-g#)YW$CF+Aq}` zfEb*Xj2-XJ%}t&dPCSS>jNZC1Yw3 zEifvO4Zwum6LR2iE7P=0lP^8R7@SS(DntJ9UGe;OWE2*@Gbn_FThXyNulrud=qK6~ zbglZKHC_EZ{RU6%P@y@cDeN3>vU*wh$Lqi;|BM1n{mwoX7yHJas)B$Ivyfk;jv*B# z9i$b>E--#VVm}J#?nE?o72`h_3W-DnY`<`7lc_98-3L!$L!$LOE|U~%G(Q$P)OO=(Tn4!=Ei7I%LQ+9Im5j?Hg(8XI%!h@En2!iPNVlpIsd zE!7xBmg66nPuug+Zkv}^E>sXOj=D>zm=at5U~^xlz>4G}cJv>dH`wapZI2y(4~YQ* zOFqv%_ZDh8OwW1PQ8jkwiC8AA|HP{tJgwOQ~@ok0LWFYtXU#{N%zvpnUt7}lK z-_2C(eRfBW&(q`S#WZ*+-YX*IRes{!D%0~uqNflFsl;t*EF2baO(F?*0)lkt>HUp0 z^?<=kvn`DfKb{k)SwPH z-OLY2^w&ZqhTZ0j6w5C5E7i9YiEeyTqPlbl7rfl8yr7jEBfv8mRAkRqexxRx)hZ@s<^GgcL zcdL^EqnP7dn02F zRG}2_zPKQW@m|sVNO;)GF1!k&nF=uY&2_9xHL3VpC-T=!zHt?=px|&G^u0OA z*E*1cGMpJxOEr^Li2%6Ab$PN}cIgLjPhks|IXg*iB^tJGiBn|hiL;bVjV^2JgenMw z-gUYe0R|2>9-R`^om9=U>xM^>%B{jat7xTZLwuC?Wj8;S$JTxuRP4%cF}pm@4IsI+ ztStPqG7z*PxTeftfGsU=+nB$FLKonLe2g(AaA&HV)4Y0)gWz8gt~3#E2mudnvm0AX z%I5eq`~5Zb=3ce+E=fvSrqR1-+5{mQ^p_A7)rn6-@Lj=H$m;4UUzGlrI+cT=i$YxrIW#}p9o9m5@tDAjBx%`rFh}`S_Tma{eS_(Z&2)il zqL0oA*U0)6jD2SD1zNSseseE@ds(B5ukrrGhx9EaeJ&fk z@BJDmKs~)AXJNGdv~_Zbdzs?#rFgkP3s7W$TMHBz7QFuBZ5H$r_`?2PP0c6(Gu7A~ zL(+en8<#>TKf@q-qtcNPz~Leo0$=g*h8F||A8yuvQS7T!KS^VNs=vEtR4 z$3D2cZgvq}ff7&K&Ci3>#t8prA2bcJO`#Rr7?7>(XAh4h6b{}NB3!FCbQBSXO+t`4 zHJ6Y2rb$v|=mneF`SIs_d?IckGmAs1h4>##6%3CU=LDnmvluEl7k9OlETOZZvu_Uv zt!5@iCK~9BI*ygu&fROSwp0jNdeeA(V$M!mh3O> z-BSAhnAMcvPu6#u=+=rWCyZOsM*tNiiKKNkyLyU~-Ec9(IeBxOFFM8K`UbVq_#;q` z7_p19f~kPVxw%}A8kyTU_D0Xv6DLq&vm zV@NcH#IRU`4_NQXvancwAgh+$B0riK#X+QZDP6zJd+u8JpFN(QcS$}5Xnu2;n^S@; zLi3?j@6xf1Z&^=TU^J^2e+Bbivc(WcbX<;|CIY3&=o1P61IA%{Vo8DJ0>5cI_7;L4 z7?j5F3ny-kIj)_H{d}1()B+igl?^h8u z{*T@e3gQ3Qlkn0nPyIDS`e&H zlVhEWQI`vx71tt-MG7DqXY6x=zj}@tuAV*1Gj1p*HWGgGJF9a3MGGZ9(K`}PKI;v5!U^i|h zP;Ss1shFRp%Wymgq57?2Z9WTcPB@3*9w_}LhmL7jIFndfI4c2b0d0)wJJhjBClQ0KloOVaBI|zc zh#Ie9Co-DpndGe_jx8X-lhb@Etln;|Df8a{fnCc5sn3v_wR$vNWy(6*)X6%~Vv0CT zMi<;6lb5D>x`h1#KJ+<+9s>ztl$+k7wwr$(CZB4Gp zc1^A)W75ew+2(tH-?e`KKr7r`=f1AJ_h-WuycGQe!zYK67+{K`h9Zje|LDGF4_>W| zEU=I0k$?i*r|EuJN5D^`;b*4oI|sic8yVzU)W8hr9p)49Pg0+%laz>{h`#ObPy%#K z3+H>9UZ+=rv#mbh3G#fc>-*murFheiS&+sdk^RfhXWe)a2_%<`Rg1z@^VjLT)M#ji z&TU^LLcl8-zInmm|MHZwm~O4>_~Etw`B&tB167zrp*OKylM2X=3elv|IALqjH#9U@ zD{JPt6&a(M0mz+d?JmsX9~1B{p8kZ#?NkKiXpmwa4n!k=ol8gR`mTL%!tjv=y7QKM zKkjuM`)RfKxu?GhdL`@mAhYl`{k=QmYht~foSb6jZyHM~Ua;jl$DmlQ-UIk1gKh*} z;z7n82*M?}HZl`UJdO+BS}5YaP4Lm-Q#1Xislr!3AL)wgfagTBp%WSxD_f_PM#lBb z2aS%#FvHxigV6aJQAtNnj2|_Zu4J53_q$=io;q(a*3OKP;fIWBj#*B`6vPlZ6^e|fdDH@a! z+}kJ|e?bifcWU6Fx0Z*}*c0ciI~fA>e3$!w8n^%IwkFpnyAMDo1~)OYVG{xOoUl>c zKDV^(cWxOs|LS~)y&GKdg{sEY`tCtcq37P^w<%O}005h9S^t)o4X@_mmcxE+$nWtZ zQk3nA>iWIQVeh8R;69jTSn#PIdDn{&AVa}}+8n^CD)Ku(8fH_*7PRS=os?L7{OC=jB z<~qGV#YeW^FX?D$W{Y?WM3mcPk|jjbb3OVIE#F7(Wge807csGA=zBAp6o-g9{lXYs z^3vA&jWWudQbjpDjAdY&Ool3ik?mb$Uqn1#MM){(YU_Pyw%q4`kd-sw(rVjY_@kL{ zGFzRm{4&$eT^w(h$<(?mn3UZKBc)^tLpFQM4y}1UHJTg$c-9sg=zk}LhL?dLEjB?w zh*zv)haJFls-8z`E!@U=d3AR6I9P4-K-Q-H{)}I{r+7tHY*J;L-@$D8BWb29x7Q1v zbgwG2z`%H`*AJhs9eAv@1}e-Ps>MxIgHe;!EhSZj(dbbnek4CJJwrtB%SGq}Y#Se< zQ*gHH-cz*S)IfIdj7s*AX{ipWg-9XDYbA;-pK*j5BPl+S~SZdlYgJ9+%8jVa%GaDM_*s^DbZ+#WvYENgQ(Xx#KX$gEsw_gZV zB9MNTm;r)5@c$`(XtG#%Ym4Vvql-q@NlB_S6J327dkZ> zQ5pb4M@%5J`M8i8otfA5=<*EOnyftKoChrf6gJ@ThYBHy7gqga#bJtm5Xl5<$*#R< zg9sEB2w|hNYBvXC3at>wqv6JVoAM6%twi}UI6fvK)}RV$M1Ka3_QC2gR7eYc3`4LY(^E=x>DSI37;HIdhm_x&M}E{!IW5CQ zHQwaXC9Hih0{rA8;-L1bG)b9NhF}ye+{g<{c^y4(>|rXi*#9b>tu*XonFrNHM0Jk%hC)@WkYN9-Di2`8+*0 z>&7iX5L>F7X9-?W%`;b6UUUE2BzAh5&*(Lk(bnG#MTCtaABSyX4+Q~4rD=l>wL_@vfC{uYBgG$-&3(B z!^E|uQzztcw|v|}0jQ&2k$pY3Yke;L-YAjzL8WQz3h0&o@{&;n!K*tvsCYAJWOf_e zCD+2#nTt4%$C)J-9Kl(v_Tb@yA5x8o1MGQ9kfS-ntILfW~pC1 z<}F=>QZHW5`3^0&%DY|yr<}EB&T9F~dN0;&*}MT)u)L4csFd8koEaQe>kr)4Y^Rem zGiCgkQ$GHe^sXL{S9c3tDy&puxnu};k2zZ%54eS~XijK3)-5zeRA>jv&r1_qA4>^u z=UZ=66Ye#D7rpN@l&PB;?Bz#cCoM&yAt^Fo-&|@O&+qfl*sgl8{lVXi>xMr=DT7>J zkOX0eor7Jz3M&a@C3}B)C=faLP2i!#Pqga6P(2a)>6tZ40~@)att(0tg%X@ZdAw4k zI=9(|HiF`$&lxwLZ!3}(ys*tR;A;r!hP+^**UFlX*wz2jtzAoLaCBiYUqV`td z0BPX}t$bO|;39-dGP=kllSe2sxRL0iuyp4QjUc`7R#imgM_b;DHRW`u{Yd<$ALjds z(sMdeLC>(Tp;DH3>*ONP7I13sf01Mmo!i7&H@JkI% z9a73x9Wrb*(^6* zEG`_KL;F!&6iF4WtcA?+O+}Nw2l|4c7DG{|NV_iO^hC(Jb|XclBSMdewinO6 zt@R)r>}6NapqIcEHSf2$iEK;&k$rO0X!jE*?9?kY+Dryw3C^D(qJVMjHH4#Ge|mm) z;p`fKVRv+avR|NUekdf#+M89Q=1b=Ee4Fb{@T!er$|jDlW+U&pOk~Gx;D^ty-cmX*E(YEoI+UU{gDt*l+kAcP^LYYo^_qaj|2sHv zo1A1ohTNLdcA#Jnoj8H6X-P|#3Q~qM=y|SM_uTs&c=Yq#3XuByJTRb?U8BXfwKMG4 z8-_uaRHhZM)9h}F=>b2i8%0Uz75wq>QE&^jz>H_BR8U~#wB>%%Bthk#u;Y=|z~C~P zWys9OHn7+*$k%d?<60DOEcAkW*%_g}vOVSCNsGeD$2P4%=pRW*7|{5hNfq4zXh^dg zI>uAsDo0a~d)ta}<{by81_x^%pA4Y<)sODw+JDyT&J)X)t+;P;f<)26YCAhuremUMBb)iq65#*mg(fr{vKl+EeOys^;Et2$>dt zm79ylEx)3ds=Zp!W^)C$2TNbD5&&@*e4r3|~0& zrop#fz&~AQSJyZgzLmSs4O9}x#z3DFXu*Aj^QCR89LztlbUyo3MOL_JyRvoM*>1%a za_kt3QfZEFVhK&JyFC1Ot6DX2PBAugqQu8&I`{%XK@r~Zt|Msf&-@ddPEWoxYmPGn zc=6OpVIkjiFr7-ZD zgO*`@yuaBl21)nuZ^S(NPJ0k!ohX2ONf4r?You8UQ1qYT{gA*m3b0bSq5Za?tOv`3-^ot7A*UNBiR&byLcu9 zoFm4@?#1n74TE2~f$FFL$JcjTBw%W6mN-XYOSDkY+{h_O1m>Zsp2=YfTg80nWSspD z@vb3Y%m1*vocX7@??x8a4F*k%A6v26Zbim=|*ZDMfqPj zd~>|tc)yu2WY7pirkBYI|1w9-!pcC zp(pd4*8>%rzSHMrrSky6|7Ky7>mU_Qw+%ps`KDYqkZ?Gx0TqL6_tJ4{dnU57@k(_2 zP9;FTkPKF&i0W|S6KsBR|4mtQp(V>C!m3$&iF|`cu#0REM_+Nb$2@Wz-L$S*V&h@m1L?jI#&V#~_S5_eW)_bV=8NvpeQ=%tOG)9!e%Z29}{NT@-_j zI<@>R!#d4iQPCoRpmxc*M9ho@4e z4NH>A>z*mxfG3zyp2--5!8Kp1t@YQ5pws&$Y9PHd9}hmUbP*$(9Jt8~VJlauMGmC1 zHxCKfgmFl%xjN2{h|5dc+Lj6xrUCuzs^9Zb8mGRXuUc~y6=yaE>H;=vQ;JH>KizR) zbkEw5Qz<@;-Oi;HVpw!QJeu^02VhCrscvO08?5SeI6LbuGvn{qpYN2E=e7C_DYvWt zksald{xu30!uix#;Jmd?!uFlL`vbFC<)2?*5P#Qc9U_HGo_e~EB48VQr9n|WNj4ZdD zzM^{#ISuU^hb4TxOLV;a2^buBL(9*3G2w>9pDU}GXl7_u`j;M*9_}+6&#e%*vvx>5 zW7WONqB>v6k7Zmcb>FS7@lq^$e2ILQzWJo=mrtp;Zt%C^avSOTDg@c@&c)#EB^}@e zVnA2xwB-Yr&8C0NNX-O9HW;H7T;}#1MT&Gu69@BAinHzx8d>?B3me@VEmJJd%59Hq zV4c!3=T+BLc|?Q~!HM1(22)ZT@M`t=4awglF229@V~0(E@9d<>vr`>~!X@P`q@a{KP1ET}|O{evdKi z92b=2V#P+-kFJ*d%i9AY1XNHb@#jV5 zg09H@3D-MG#^E0>V~(%MT!JPB3Ny9T2AtS0Py7Snd&-Ybog`byE4mdN+`{=E1;pQ* z)fP|X!e6|x32=5dH2Oj$h1OLaRvK0h^I-h`q0af9)ldlmvufjdm(HNpAm2&3tCqS~Mh7Y+lSF#c3=%!}`3 zg+pGeFTK3LH(LDb%eR*m*B2bw*o1`*kW9~6RtHWxrg>CRAhBgpOKC5yo!(>$ zS%XgslWdg8lBB%1tD74ML4mi4{W}h6KFqOWLbZL5+Z|T@#hg z%vJfPM)gAcIFt&3K1`w3Gwbf*L1hf9lGB>)L@k-iS^+^cf;s+I$#9nVDHJIIKE7*F zlnR!?4p-%9Wpkg_cP3i8pz1_ntJvn}OJSbM!x;`TrYQbL>15bA6his6^(io4$zBrK zRB9s?s0sae1+{ojv*u+-gcSji@Pl<*gt96#V|d>ed$LBl%0;&G8_NuVo$a)jd6Cbp zhW%l{d)*AsQj`xaaCE%rB#ePySj<^?>K%>o@*)u$W`xX*!SIo}st-w;2-xGy|2iG8 z`8LI)w&;Et+I1n4r$yq9_{_LIIM3-H`swkBPHEtc)V{3ixLI|4Ow*)VS0wDF9E0Th zp+@7~^iZoM25FdqA$3Ok;+ECUH(qmz4{3g&?~-L3;yi1jo&SgL zTFHHRUcLpktZVhxTh?V23{m8s)Phr~zz@iH5tzr1leRvOOP`$kK=WdI2TX0Cwgg3a z-kKw-*by4vdZWy0$wm!G2N_T$&Va32AYK1}ShaMuz-CFxj5Qy1J-8rXhTe7NLFWXy zk~oIei;+Q&x}6Q_;gy)Q`2H-_v$ji17=V_L)FH+TQf>{%re;?~)A25A<-}ZWGUSm$ zyXoLtTk%9s8G*K{sh-o}n96v#ymIzhS3S*v*mdtyuXGR1@tlSNoVT=OQJT#2O)qn> zH7Tk#bqUJ@rqkDU*?nh6nWfCu%B^ub_{(;jgw1nY@irUXVZQ+{JRhHMhwjLuueiAS z+%oTE6DZ%@%4$6O#^{)3)l^ejYTW7Q62ZYJmcPZ&>eAVYYbZ zS(nP=50|Oe!Iiqct6}M(Kz8T$d%1@yJ(V}z!Xww}wVa%O_wmzQ4HL(f>e<|1Y}vzK z>5EYAh&c%3mM;BiDo#A|yZM&{^JrNa4xXNvF~+bk((=8clq?!;r;J!h;Jpn64nAR7 zUAe5lrPD~d9FT6%!(Z`0(fH1{EFm31jF5$WYVkS7m1dn+SsanY%^_CxPnx%hiH~gz z=y;Aoy}C6we-ZPJYa9^{`m7D3Bot z8HOQt2(9fS92~HCA&N+n!d=m{Rw*12tE=Pud0n)5E}vX#{QNP0VQZKYR=o-N*Yfg? zYiqgPPTqSjIp0Dx#CeaWG#ocQf3#>s?0?+Dl+dEnrJ1OX(s?K7g@L_1^CdV^c5_+v zheeR=DM2#h(p#GIra;yS8I;DoG$Ic2&m(;uUN7r&5s}p zlO^9QBIqBH(nqLL$TS_3v_zRT(Z#f4WzHpGR_k`e%FSH%x9HMQ!@ebMba`B-+id=_ z8fK3D*!H2*YK}~cKxp#cXaYV~cb*|2rPiEQ+O5#xVX&OX{;1LEwC1Xgn7Lk30eeom zcaM10YRNxq6fqK`5)`T26nR+z6B7lx=I?XL3)bwYuz!A_caV{rHj2^7%z~C@=0@{H zQJ`&C>-*1yaQWbszlxZOw=s9^d6{q_(k+I%TIEbniG)0-x?bC*TlCtD0i|@ZeQ2dnuLr2_W|+}G&6P)v=6?R~Ej$F#L?iW#ypqGkpjXtk zuC&mV@?S3vxJV35>Im)1VZb_S@CivKICCGlHhteL;155YecsHt7Jq-o^DR95+Fe%Z zc~;{1S+LDes{GVqYR2HYZ25Ys?-?d^0nX&9Mqq&HO`-pJ!Y|kRq!Qm{5{T16|IY&8 z{InBs3&bcx4kj{OCg|H7xBMOnt{x}NZ|St0$GUxP0)uarvlM)9RNm?YyUdNeVJEhoZkn7z>*iV4iH2A&RJ+~%zcS@Sb$or0Bi_X6rxYu|e^ZXbOVLq2{c zND%dyJU`mMUKisno!9G3l|@~Ck2U9IR%HEbgX_Yd1oIpI6q!(yPMR_Y7cGZIVW642 z&N@*l{H*x<#WHTwA!us3!ownFn{1HZ;#VPI)+B<&?A*E^ysx+}8J3%5AU*_e$gTZt_x@}0%nvbCBb3bW zUvFOEqLkQeHYaD~y*^5`FUA_L@mc!w#IPd4qVB)hhVu!7|CVpCV9bccU;-Z|fSU?A zPCUf8VQl&w6sx`=2T}BO8tjKeoHw5N#KReO-cI!+X#(7FxK@>vjuI!Xr!g_YR!6{Q z>62nSH}Elf(ee5L`si90Z1dl9xNGaZUY_YY?mT52H)9#htLWDpBr7!?1R}RJJfOC7 zVoT0A1z`;1aWXJ@v_=mZ0%=?qD&xn>cgfQ&nrbk1T+H)}E-H*P&&9|lNKUGC@RrlyP&$XfDU ztGg{&xl;g=ad@6wrb7Lc4v%moIT`vZ|GLXoh-VGOrSGd7uq}Lh@o~b(3mdQCOwmL) zIedk{m7_=*c=V+xr>NvSv8<8m!dcUgnSF#4{(3_+AjVAb&(Ge`5+BzerrhGSr0j?d|x4}of^@yDx`J%!)Jn5}!W6)ldr7(HP> zPYbqUPs_Lu+xIlPEtyG+eZ1VyRb=BYP0Tw*YqZ&=ke&Gc%%f^c zwuJgKiDKAm@{7@I(Ye=Rm6~;0^4wo!E+qai$S`5lQmA|H zIPDtSK#sEhtg}nuOp3Dk@l)!(B?ht}Fsf)!mIO?s4QJvYO*Qw1-1mcDv^|Br;sm3bJnlwRcbvu^nETHDvz5U zpXnh#rW}596-<5otWb3=ykHq)$!B#zq+NDu-fher!rFo-I9jBaJc%VJySG?; zwRBF*&K~A-^!?1OEAx+Sx#J=CSzQ~!YF7@?mOoa}DWCtv?~mmr%#WuvL^Z09*B{+JT_4v9 zeAJ_#x#X)_;9tHMaB~TLBJy0c169ohUglK`H`$>|vkOjbShee%=SF=(wfgBSEK*wsgWY|JK_P}-TTyA?BK1(F5oyK!IR>PhbY zTDS8oZx*khia%14-0yZ#pa2bti*9W5#U6aktLS`+uAn-xymQm&)}Bw3;lKd3cG-`0 z96{|K27-MWZtE3z@*sa}Q!iMzje~DZo3z|7S4ApScY(=qc+GATo8x@udf5W1s1*-6 zv!q6RnlWt*M-3WjwcYd_#zPSXELnH9rF3tz<*U}mocc~#mXmxUB{wsl9^DBP78YAH zbl3N3A|hbQQ)npa};G%pTo(*%ne87?d|P^&uRWA^DuFb%hUxY*N{{G8bP>jz)0k) zY$`{S7sX&>;q4Kv_TnkU)^qFvojkYf)jmZ5y$^fZcYOCwkzR$y^XouKozS3PT#9wp z)<)qP^0AKY??gD-Ka{!d>8u4eLM!A|bo-(nn1RNTUFzz#-u$Imrj7^=6~9BAZ}R@o z^UQ3_O+>Kr{LfI+T<<@CQ6}Bgbhg=)Al)&2?!iA`+aX+~Rrt@EwcRjKBiEI$vKcVt z`2jwDKfv1tM8}ww*)9?q1OrR->r$Kv1{95?g1|m>`h1agr495MRF>${QVtG+=dCd3 zfr`+Q$HrYq`bSDtiwKq(kmPLov*LxB)M;M3$M?E-Ys**bop~$qVOXIhx*2(0?oOLt z;9Zz(p9`N%$^y^i@_f%+6?yLb6a@k3nS=^e8#ZgXZ&(b5Gh^}(XPZJ8;cO>z&Cv+; z>~^i8oQqcS(j+L_MZ3GdXyNzp?J4?{Y;DV2Lx1i1L@l(7!pZ6Vvt&D6{6qfo4Kro> zFmt^vgUM3G>BbZ$BZ+Whd>YZFe`?P9-`J0sp=!6Y_9iRK%V5c@$p`OZquBcrXzZ_o zH9u33Y5zL8{1V-M4HqYr7?zSro-!S`xaEo$Y0@g!twDJTDr6W5lf#ezQ?be8!yQLJ z7-Cb=e7_dn!*|Gp7@_+|6-(F2?}Q2|7AiWzHpE54HrvHyFtjIc6%7tBSkqcI9hwp;f0bD-E3DP+M*Oc9UbT@SGS9VknZzDA&VZbr>a<@P zG$6?J;IYm$w6N8TDj!&Ktw{$;%?tQ_KZ)^&$}HV4<3P(zv~ zmvVCaoFxto`wa_Wvd6S}OOS}~kN_T&ZabaPH-E7Rk*J+YNN3r zwiVu9s_}Xze?s!Xp?9p#sIjGhcjvm|kT35UeD<%8mz{eiU6(IyMC*e4UYok8#q2fe zAX)wQ4d8&1JasUJ6%G6;Y4Qs7>qw2Gy; zhhNNdBUB(tIil&z`EpIN7ZtDghgC^Y7)2cWrLa^<$kO#JUDPH@9nv=CJV&-TMQp<< zSL3$j#)+I=VmM(#J!z<;IqCw16gD;sl1ABbH4TEOAYgQxf%*hZkK1)}2W`6mdx)GH z>}p3W)g)}g4?dwe{4Qdg!iDYcR81vw?P&iw)pBeQGkEOn$b~ z8)scC&NI!Ep^P@7LJ7syYT^%WFv_L=-Liy>`Xo@-bH;*6uPs@%QKU`&PmagAu znuL$5k8fM`G-cdy8UGpoxWJB8&_&R`9p$Fe(+}-u&!T42!WYkF%3P%(*dH7gv)bZE zi!;hzraDlqM*t?4G5YeJKWCL~SCBSA`fx^QG+tCXDVx@yG9r2MWTIX~Dps?)J8)|t zC1AtK*9`@f9Rw**k97MLtQoU8t)k|#+!nq19y#)OIZ(Bwb(P2BzB_dn}oXWN_M zBI>6wDS+8sASu=!FH)ntd$bp>s1BWk_tW}?&e_}wtgb>$FJ7Vc8$T5pi(Z4TN8|P_ za_UKSY*sjDB0f|WR1S_tu=(tXv!g!A7g2?8mlXI9ns1V%91CCw{P+*zSmmao>*Ck> zY8ZQKhPYwM^S(jS3(@jIylvyBKi1S4CdZU)<4xwE7FYWhoi#e_qn+MY!s4acT`tT~ zLMJF%jcUV<7jRS&$AXH$>&W9Zb4z)IYV*tXxG}N}MsVu#i%$oCN_oR{Wz!JI(qJvyjLT4(r&m%%c2w{Ksr9*?Cz# zDZByjjyyHFPlcYMg73fRw0?WFfbdYRHQSe}%{)VI@b;OEi3}0(-9|D%L8<)LHES@0VmtFe2ETaiYw4ll)EmO zcuCouHHexGS1|WhBSjhQTkopRAW9Gi8YP4DpMUjnPD?eySh|Q+IPTmH~<&&JEZC<*;c$fu=cVAEe zu1_Mr(e2CpEvx($Mz#^pAXE(-Wb7UrXvQm%TgR z?B7z5yN@03R@C^u$C26p|X-+I}Y?AjL_WCku=00R8)heuFlR6zl2U3fEyKA1{a)CJGRSh{Qx{~fX>D~~=&`fhcyAhZ~4;qUS2!n3U& z2`Js@U%fWWYJ*XZmE~Vw4`id!uVu$5L{=QImyU91Q?at5*nQl>D z!|o_d)OJnPjyE$JZBT%#aA?s6UNKcMlDHAa9lWzkYTW-~IR-~^n0 zP!P3yiQ|Wp7WLIbX9`rMp8u-!OA~lMxOScqPo|u0g|Q6bb>601Gypc`^PKNzR9l|+ z4L9hMcT3~7jKTpU{cT_%$RE#+V^5Z01~sD2@G{aWoa`o8G6FWPFtYf%hhx|n*^bfJ zy;Z)eB@gs*E-&D_M^q>**7R>EDLHj7k)|EP=f)B`-7YJNDsjrReXm!-%XSJ~^*>f- zo53R_WNuS(;2PH8zxU1ka!tN?jx0r9<&1i_ok0lYx2tH^u?me`NMIqkNT_y$9|$v@ z&Z^0Hm^L%-yqx8huICw3?j3eYol(mJR>!*6D}!PYlDDq?43Pm`J8PRCso4p&PEWE5 zG5!=OhM}pOqcy>7j2`lV7N^-fEs1RT7px8%e1znylWJ&7$p3&i zX~C^g&)F=c9Z#1~nxf&KKq46$w&9$zfm2~S3e{&Y{!*QCz6i5}>&=ZMjq_E3@k%yi zg2O3{N)Bb14Mbu212x>7KF4?nlE4k^mn~?xfgt!V6bWcvj0QMO4{Oj9_JyrEu6 zm?TOTu7tFtJ~928jTsRkw$@;F?)FsP@I2S3Jf1RP+~47&8ePq2ovSsH3`I0l2p!a5 z)i#lP{fD)EA5p{QX-C3%f{j*#VA{a%8S^3bEFMvvT|uztBEsNlz98W4{j%q}3WhfK z^F^evH*zU}O9Af>yY%o4yWOr4k>|F)z%9^6o10x&UhcWw-(ih~9}<6jsor{GGx(U#2q=B@+zx`_2@v>r+Ut0|=;8+6I@|xZoj-w{ zRIJjG2&}_BVX$+H*-cE)*RL)-Zm$)56M@do)c7dn6iB1dasF4iQMKRz*S00&zCxoL zwK>GaE{a_#T@$R#>`_Hb7rKr3HyWd}@E4!H_!d{-1Sx~>vGMAl;R`mf|NQUi$<^W{ zTQ>RjIk-@4H2Y|$&}hDrt@jdLoFwQH9SXt-+m+4po9i@$xQS$$l9Fig91~(70~1kY zq-5A@&8huh6Sv`q@FIH6A=Osr1XTYKt(z?3a-OlIWKbfiQH5d>^-b~-KF_dWuEd{~ zW7EpaO~NgR@n&A`(fuZOa2z`CqKsAJEIP`&Fwfn7Cpojt_bMx}+F;w3K;xg|OXRu^TV&;LDPQIDJ27*-O zGFb7w6?r~xme?3wff;rU1M)TfoOF$tmI{HUQfhsd&1YfBXa0%wOWu!673t57%bK?L z4-op3N zD$#Rh>o_arXHvOtL-kn%wo!!sXmt8~5QgLWPBPI(rB<7g5(77aPLr;FZ_X_Yp+(ZB z#J76&+9J0*R5lPjOCA3YuSJ?SWr7Af-mE5rFffd!3F#f(WRq9@*tgOZRt~8SWpE@Z z^03XbHY-%*|9Jr{**awNMUZu-{|u@(x=pwp!yxRB;kmf^OraP3z*8PJoe?<@pblp*KV)U)9dv;6O}xD!L5)gDfT)=)-V=Wr z_D%Anb`g%`i28wPc1yuv=1WtP85^XGwDK{=dAdaL+;%8>ywUZ1Y4uk7SD8>**|dr! zTzsE9lDmhypY%D-rP56YNfYK;T^Bg&b^fWqmzLYmqxb<7nMdmEf=%>4wGKL z+wD+Q#cch?kA_wI6H(ll z=_rt+%!e^lO~@2JZrd;;CdA)V<{NjjayaDljJ3m@szgR+(x2R8FTpFHWXw)6>>qhH zj8MV*&m_i8N+y_O^yro5QbBe&3aB%;Ny-4(M}P8k%M&qz&>N~l7`2AQHI5hbMI8H(|u??-MX3bx$LO(uAhId;~k-tE)YI_q%9R~Yl+t?pr|2FlW+2# zBK5sV2^f*BlvPl;{);u#DpIUnsEpI^4$Y|M51G02veMT6?cOi3l z&)X82{5t6Z#@}J}S)e@jvBkRiZ(_B>H&E3fD9oZa`YlNU)o+g@_i|I}&v@ZPS~U*ZquZd+LuW&D4D1AWyy&3}%ka z!v(>Cg1{Atz;hI`a^>RWUnc(%SQ%H}YP5pnX(q=_w7i9+n9no!Jghtpa8@b$pYCmF zwquuoCE;SyA}ZB@yRex6_eY_?4+Gz~1;K#RS>6k8$NRDTYb02?Um6%an-&}QF^D-o>E7LbqlsuCnrs` zhJ4O=9I9RCmcck)0x;tJ=wCXf8ve$wjT%B;APN2Z0Do3vC}pIh(#v_Xabl>ptIcfK zT<10$UK#hhiE{V3hXCAEU$Ia^%au~DN51Gn7T+RvbHomQoItODI>K}p!CqHgu_RU1 z^|Q8evV3V$gO!?aDb|1~EM;6M(4|0;A@Sv(byyZ)s|23@S(nL@cHx@Fwyq;;o#Bx z?6K)B#gRhLN*8sywunnu>YSy=+lmg|TewaWS5MZO^c|Zh!ab+IUtr)DDpi;X@7Y>Q z$`nXKv%{HNCWC?apcB>z0n=`@=-=DfDF!+~>CA=s9FOs^;{S9^;b{qXeiwx@c zZfIcxkQAft#Kkz;c0!#N(DnjirAW(!;`$8Or3OYH9 zeR#v1)KbmXz;>{}3rsYi8m0!DO@w=zpL^p@aU@jx19#N6dPhf+uOVMG(>roV%@Eo{ z6QK$dh^$$tVU}C07IngvwtXaJfcQe`JVFBhGZ2>|)tm>!7v=2y|KZV|gXWZMid|Yu z#5ht&@}>=WgG*&1EL(uX;`vG%h>eH<1k@E~yWw%%*0vc;G@1?aJq&r{!_(aJypEJn zsaXT10O(NB%-1i#9h9? zC&>nqeCu#gCMw>;Txp;#jaQ*aF8Vd(({Skp`&;o$sQ9{h=zF$e)wUPvTCybQ{Oo+b z@eub>Bf+%HGw|C?`jiml%oEnFCx^WV+nLV}SNgEkfJJw@&59pCd1 z`lnO<+VedTIy$-2UL4WeXN!8lthP>`d2Bo>qR5`r9v9LK080;eX~@aUrct89K)TAZ zqyv>IRWa$T#+_4;o@Ov{FV9woJMll!s)KLi7WW{&X{HZ3+r{(Uz}9;2wH!YG<2Go* z3%h6erz0S85ureei<0k&KkU(+wPEl{ankzg_$ZgW)evF%``7K^=Xflq49|hFR%Jm4 z2eIen>y|{*YJ5)w66BqME8q1{ima@H<8WymDA&g~*jHMq73dCH_7r4`;jT z4ld*5^pVYrni2Z`%sPcsMVq5Pjq9XK>69T6N1AhnTGSW_vH7BC65r_BK>s1_9$W|Lr>O@ngXO)Z@N! z*>h^}Mm%=lvbsQT6)0M%YvFpSUq(5~>!gH>(-cOEl1vQiR3hf!ki;a7D+%#B^3ZVD z&|ZWt+R8_y z!}Vw1^Lb37w;V7GUUiR-6~LI7x6Pk5^_ybFV+V~wA4tV4Eb7-TJvymcA<7tZ#9rkt z&k`2&=dIdgE9Y>aoo`03bfEXxk)EWw%<;PK%E#^@J~WJA^06wF{eaWH=Rwd#y zMZo*Z0&K_F$x>$j^AOk+_{C>sp-ri$xK~NlXcuo*ph7E6zNH_*(#dR>5!jAWq{t`9 zTfi2fOgO^|CqTzwl7^Nk+2Kxgrk-tdMcm`HI$x~Tm8^gUWh-Ns?dKo(fRRk<ql~=P&s|XZbX>Gg z4J&v*CH5$dJ2P->woN}3GPBu;6P4DCTjKpQ< z?F9i$RldRH|7N0RM0g!dO*L6wpuBQSr64}#@C)MU(-5USU@;)->EUM_++QzMs$tPt zbus)45a;R1ys5W+1Ik_PdhOww4AwC5f#0@Wc=sd^#8Oy%NZ&_sjV+Y3ZO=&FQokVSe!g7&{K@+>Y^vH|y>a4TnZCK+oyZ#5h zZgU^m7r&cp%GFLkcnAN5G|hoG;R5Yf*bD=2XkPd3r=3&s4BY{bzE?f<8tvhlw$1;h zIJYK?69oQSSy_P)3|N+9Z9Y@f<#hSm-+>Z*ea*c2G3{{;^kwF*DwF5u%Iq!LPsAVc zGGG65-LYa0uoif1dD24L3W#cUXK?>Dw6@Oul{*iCK@8!|Z5`uu4U)~=Pzp*Ex2A}b zUVmNi)t1cy3}cq`D0UF+aP6POQsdHeG9@b5 zQJu9#Erlv{vz8o(N24xBRMn-`i+hJfxI1l;+9e?eVNTp5@*I6jySDZO#91y4I^xRW zTv;dIw!J{toM@{vC2`P< zD*Z$+5~ZPxMSSUB7j-U-`x1Xd$`H^cF!&boq(oS%3ot?pGQJP)i^=Q~PeuHI2>%eA z7W|jzv9!kGxJ|TgikQptJ`wrOx>6SX(-1b@ z{<`@w|=Sn!-r!J4Iby@I{4xpZ}W4x>ycjx#T!3Oeq)~GOiSQ< zww>D-44+p18^*j{C4D*9B{M{AA)|u|?3-KYuvGEH$wAmgT8X^@Fhq;wDT=k8mlXfn z?~T|puxWA~8KQ7ew@Ymq&Yp$muCVrACxw zqiltK(X=IgWC!lA5&3k+Vd@lTbd~Q6xQAz?`Q6=U!tfcnnO~ws>slE==$mjP^c?#s zse3F!LPMSR0wcC&nF@qltgNh)ca>Sd_KP3VWN&^yc@}+6Sh8lFFx3~5JIj?7R)1V$ z84N56x2N2M8~Lx4g8Z2yd{at zVl;tlF!#!~#TG{Vil?=hg=#-{T7F6Ig!SrLOFN?+98)FZYC6rT{v9ylj)22)0*hu| zNrOi_xAi3j*5af>N8jn;e+rDI*{jWPun=C*Hdzj=@V_U{_WJjTjLKwwzJ$L4P1E@d zX-|qW@Stk(S`dCDE6ej>75(}NIGk-=nV*M-YV5cZ81$g+4z1=dT|T6q$A){?C%i*L zWgEY?p!6kwCX>HL$i$2b=E|BaHQEr8zFp+i+1$hbcM3+4>lW!7HFY43OegZdaSc!P>MyeV)@u$GndFvR^98m0kFriC|1hk?Ey zrYpLMFX*xA#7~%KFkHFu#Q%05CN#ObJ01nf`O*C}uj{^S zCayftxTrtY-2H0Tb=O!8OctOX;(0yp!I`aoeOyO-%xXzb2xNVbG4C1sRvW9tB%{KN zplkFFD(dT2yV2p(t>|E3hbYJ`gXi77_nRN>PpfdzeOg_Sn=a|E)}eNlVQR<)yvn)Mt)Rz=8Ogz0QpY0oNj(hC_rL-Z#&@A_9G8fY5EVPhv4> z=-6_+y?piBb>Y&+T(Xdryi58DKB%Otb*FdLDiBk+A$>Q2r zutKsGp5Byv?=})~Q|;JRu~6DaEgNcz%`D3y$Ks<(+cJRge!d?+ht4y|uFq`>1pXX-p|vtSq#D$^Xf2VQll`PWn8Wx4w0 z0Zhyi%3{v6-f{}|>B>a{Y-cUD4CGwW0ULIvhepwY@Y&Ps4$2D}4ZBT-1Mh+$#)|$)& z{N^pm9aWfex#g_PBUKgKq6OQz*aSB7Pk;Uv78gnx9u`smhZ$h3Zx_6|8`k z5NO#3psI_UCWYf9`+>a%e02aMc>fMzcRxoBjd=Gh0~4I~TV6@QabQd8J0lPco2#*d zt6uAC(tCP-`X+^4#~a9!UzR?sz)$4=G7YG6@y^7$i{#VoOR;N50&oR=bzhXRKcmzn zi_0b{@HgndoGesY0Lk6tF`N$fEbT_X9S9tL1nyC>{tlO&JEf{EbXmRyKTleKyO)9m z?S#B?c`}B|%x_L0upsWFR)`SD;v-Y3Z}B|2ruKJM&BEM@6Ouf}uJ+e##SVN5hcDRh z*_-A$lS`S2wbLh7&xE{W?IZ4irreN;LV-jgJuBWpcqmJFjV|GElhZ18t1k(pNv1>< zFe9wa5vLi~N-H^#E{mcyonVHPKAymlfZAj1Ai<)WEp)3-93@u_g8>peM}H!uqc*+| zIHRdX;kzgF)%XLld1?bZ1y(?+^DOJE^q>{tr>d_w#fu@VN%bnvX4K!3vbCxq=4DQ6(tapl3OCC*4Sn` z_YtZ<6^^c-JQFX-E!TdmyqAJg{S?R zB)}R$d+=HUCbS2xk)%&%l}|YOE3B_aF65pw)vw$JtT)H)t=O z5VX}mC$tw32j36-zg(P8zV`YHTvV2i(&t)mjC^?gP&{Kr1mVK4Q8taFw<2eZpemUz z8#1ibuGsN1w=Tj4+GW0K2`oh!Yz*(ykW#4U77QaLD1S4}2v9($>th*x%O1N%6*HMD zEezMF7b#Mv$r;V0lSor-3rEURyz_b)s9{9Pk=KB|K3pA;SQ2oQV;}SP`c?+dWgUh*M2;ZJo^PnFtSgPJzrIT9!E)=byn1f znr~obtXM2>b<@bQ^uoxJ;f{EWISWyJ{qFT+ ztiYCa5kKC9Mv!x>e9>}GEe;lCdqg0vnAq6yfxhEb#>UIg#&h??f3DZ9^Jd+Lp$h-) zl}XYYJQq`Ty4;Q0tXe_J7JHQu!ub5Y5lelON;?ReW}7L-k!z@Az05D<04;=%^b{8; zQ_{Ss@JNeIw7|JBv4_9b9!Csmp0-Vvv2X@dHkBjfCbQu;R19V80csde{{sc%oLc(}Bdxhp*Xb5G{*2&$&-=YMZD04>ZJzSB&Ho!Dgyv9)UEEzBAxQ!si#>OY(Z$JWZcO(ikR)T@Bc`e%i z-OYeA!sd6dVbIxzBcDkO?PBO@(xonw6L^{B{I40xx-#^t%`^pUtkbvs0wwm3YCja5N_^?{?c+zF?0qJMqlCx;^a z;AUY+u`1J9suDJx^*sHpc8GSTWT$?KM#Z!>wjEDpD-H|Qs7%Mov z=b9{qJV^8bMPS2ZtFE6mO-?h`Wc*|soO`&;AL+@8r<%$^Mz*j-10r(@Vtee=Nj2&C zNI_acX*)(9DH_-lM_Aj2#cAT^753#HAMOw>^Js|FPsWJ>0p;}yPc&R&9^8YrDBcx6 z3q%Jk{F9&&Y{yV(hpPn>f6Sege@?v;X(kY^TkVf@oMUMG*%k{z5<*FPf3Ed|vi@FN zbT+HfDb&8yP=3~|`KeJcy036zJS!v8s;lt2e%sytxD`gK?_Y!H&D;ApZq{QbTP})e zk^H6Mmo$b|NS17^$uq9dRYF`XsQ;Qlnym$GlbkV2qrUg_)SiJ~zn&RJ4T;=xfuir? zox+1bPm$utl3d?=9iF*k^{VcFXMi(rGLKbOWb0;@PRFiezT(J60v77T-7CB%xs*rs zTB1~t#$;H>^>?#R%-E2r{hjyK5Gqi{mUjTzc+y|RUu0etIOM}+)*m-`+cR)J$nm(E zZ~!Htfi8kp{qEN|vL=F}pb{iM4E#8O-0x?D=at2WtF-R%Sta3#GT~RNCOgPNc`KS} zz4g&lK{0#l2UK8BD=F!Dow9hb$Gj$r9}Fup_jz>!rBi(PYsuGsSLoK=sDQ`MQ5dvljQ0IuLan+J>y^dTcJAIDa#A{CR-cnaH=XODI#-fR9j7CavrS*% zQ*V$Rp%v~OTbFq_(~j$$c(gX%0*xlulh;%Db_+^+5vO5l=bJA?ibo>n|0WQ5bWAJ@ z5_pYE_VP>eCvmr8j>)Pqb5q#Bx<9Xy=~_S!g)zeZOx!Ae^CBsgp;%@T8a#a`r7Znd z!GokPBKzBr)~cwi?O30iu8RF%4qJvSp!F&_u%fyv@+|=L(qmD|QA8LM8r~OgJG7wE zP-90o$$P%-p?i@jhdT2$0Mg}mvLxZq^3>RB>%Ck@6(m2&vBce$Mtc?h9$Z6Q$Wr=O zlK4>^U((YqFCc&)@cTSv6A&#!)~hBh=QSh z{CwU4cq&QmXO7? zrKGTh$Nq=0<;Bz)x6X?o1<@i8#8f(-Vo zNeTK*SXGsMNhNW#Q~@@JgXvb53QGZNjGBLh2u~~&>Wzw}}VbLclxj9D8#(~SuA+(5&wh#e>l%Yf} z(VwKj#cV?@LqAnQ?0Ado>EZ+3+hsPNoy^M%@@T3yQ(4#uD^X}07$WSJf#{D(8S?kJ zT0F@=dRQ_Nzfsb;eQF{1XMQ!O>J*BUzwu-H zHMU`{e`9)GY@^Fj_{VH~9zfp;mVkFAD!ed0HSo{(Df?MOfVRy=fFXz5M)>B`KowfZ z952q-*R&S9A%#tFjtX&)PmNI<*!ScT*~AD9fEi6yK!4glXMNpB)UbVTo!MfZlXWli zr#VEL_69*hV`$oupn%gU*)0vmAx%VYThT#lX(lqOf>hK1|{lOo?hRN|n})z+vmV@1)&je3l8P)!>MMgv(?;NFK)8ci@&kQnJBWXGjX}F^mcdW20m@5@O^9b%jd}}GfSLl_Nh2VRbjZjmeZxi+^-w1 zj0NwA%MIwEFKs7PMa|7=aek*J*ijO)C72tJlOCu{Z+KoEM+y$xKqJ~NP^CeYqj=p< z`W6q!;upI~N+gbs_FA~W0wi&A*8ta1h?TWB<%fPha37W^{_Y7H7fpSC6rQJ`Zp;Mn z?M83Jcl6*dc2{a^x5pENo~!|BzLp2k53XxwmX*oY67)Pio=1TR2KNL!@Kg8vsQlaE z7K;K+1>O1%n}ew9fIQ>fX@BJmv#opL$|r%IK0>ff=LB?}%v)zf*<{Js7ITi_u4Fg; z8AQaW`$p@13h!Wz%N;HKfsVX3r4Z-o!6-bn7Q^f6-N|>Y?a{WGh80GjJ-oSjV+zqE zpP?kVa9A=rv_ZrXhEhc1FTL>77TR-Z|)(d-P%3Ar~?IHt1bvJ9}ey zK(>>+l4Y?=sArC(h^;*KVDbbD7mF;lh-FOD?)WfS<}3TQNu@Wo1W(h%#S}|bR;hk< zK?8M;;!X>lsjnT;7_|x_*d{^70+~fFJ9$TD(sznUrqycZh(i>9Qs7!1RoECuWRqQo z?nJUvr2Z%XzV&M2NBGfYjPd;M*|&4`ADw%uaOYjEJ8p}*9yax79|c4D9>1nCmZ&(? z`$4$W4&BT&2qOaQw8-p$zi9{Vzh6OSI4qgJf$yhXAVMO7lyrB8z2%ZTJtH2{n(lLr2bE`%jc&jAYvT45TGA&%`)nxWEtA&-r@SvYF zwh_)=xB*{sfSBl9`QjLnn_9x1ZDzuB4l=4a0s$pY%2~(I@1(P{!M1%jj$8?;e|0pk`RXUYJ2keWTCbK#&aO(OOQ`R2`3L|y!-##{>unZE zfTiCa2LvYNis8{WSC8L=U7#V|m2a?im?Y#|{6y)9Dcd_(kYy<+d~mVJN-}&0?0Y!^ zaL8J_)KZ5RA<#3~piKfej!MgD$`_9tAh|}Q10HP+w%N&1XQgzwSIA7d;?O{mV%PMX z98=#7{ojqhVXR_9>>x|2Frl&;=0<-TBSh^ua{Fq&%#>p{ooxHqtxUMnILnvAOUS3i z!gyddhjZBUIS~OxPBLb-#WAsj$)DyXaXQUsexvtMq{ym{?0?5dmSvZZjoaeR8X{kB z8Zkw|2k+GZ7Z{atBKyCC07TbD6PIprsHwyX)s^$kcIN`Y z7eOUSwpCt1e)Dg9krGdedwtA#b8SfJG;-_p9prlg_{hSbXR1!@QU@jU$Dc1cBlV`1 zAKN|746U7!Aa%eT+IQJG@H`ALQOxH`2W*!t4+UtOOnM8S*O%C4%fFHzzJK5X?n^e+otZi9lHqFv z1{XY!yGdGIzPz$@p{4H|_+nHeiPs^2#G9GH?(*cC2dX%Jed~&- zsA`KOv~LOM4@0|d?|yFgy^J#0EzME{fohTyFE3Gc5vlr;kY7rY0S?L4?;o9+CsnUD zqBz^FFe=)iOVPcp+AxJFd`>uD>krtkTrUNFYP-Ig4_2?mJ??;~N8tJKz?DvQJEoV(SgM(?hp3i3+Z|l7F?J*GhBmFbl!ev{P@?@Yf=2NlNX1eUr z1&c5|@YM_0o`K@A$ijj4Xmso=U=S|l5xn@!sGaOgM=*>RuYqV)GIE1$xd@Twk3yyt zEr9R;`As7D?+jr@ItE_qrL1iKh2)$y4iIr|F5@o0ixhD{R$(0Lt7EJmO&q1BSLFDS zU_R_Nq4>+}S7?d;7Bm)XwMcPOS>X1#ic(HxHANeyr+x3XkiW3@nIV#DH&hv+pXITQ z?8Yt30sk2E$Rdros(Lhs2=x&lOGr)eTr}YYVF#PmX@Oq3tBkfUl#d(vL=mqZ-xrW> z!nJh^-4zXkS(7F(L&#H0$`)0ukDSZoh>Iw~@rjA|{#I0pm&cp8%d~dLqr*Pvi|INo zKN{QmzEpRR@wwhscb;%7<^+5Na9zGdPgi(C{!kmxUMAGVwq|jq$?XGJah#3ai-?Y# zLtTqZx@1P0PP&90R^;c2cX4rXv(k?|5pkw0GfzigM$~`uj`~GwJbZV{z%b6v$u7of z0C+v71JqQ|VTBrHbIgk*i}WeeCa^vU9VMF!C5U?HP-1rfVd-ZN9&pp!Kd_)}iYtjE0HJ!!2;-!T9!K3(hB%%>2j4aw;3W2u*hUnh6 zSGaT?-7m!?i0vDVwq(ZvQ*|$7_&YoTt;& zMa@?ZR7HP+ux|XIRO!ba786IIm~oHv?fMnQe0@DWsj$<^$S_8o1y-fq8#S#nWwT+VW5H0Ft#Z*1T->`?{p z#`O--Oq2-YNjFB#^yMevFSN#L}R{rX*`SAnMIXKJ5sGuEx* z$~F77YjL2}T3|j_IuT zWv$;(uS4JNua`{Xa{7uG%6*@cTTDiGv*A$!NgrQubI=;FMk&L=ziMA{?K=NYzLCiZ)k7Bcpg0Fk(my`25Y98L~#jB`b3-o%ytj>Ha%B zWzqf!FUytauAgt)9H>J{U>HorG4_H4fe_c8h9g;l)Oj$SHIv?wZ$DcVL+CF_sbhE@LsHdwpjU z{~oYr%eDrdcok0njx_KCh&C-ouV~zVHbA$eZ;Qf@Ll(j=Yvq#Dcs%;Ir3TN`qS?*X zrjEX*rqSigY;s7~GW1Pmyb){UY>#MN=d+d#(!98xf?gD`CySLvo-J{%D-=oYz%WM4 zer-mw!5zRjy>4KIB@V;bJaIKcF|UnMfL$>ZN{fBnQWbXstO0C`&9Jyh2aYytBa7B- zS-W}qXU4HZbaCkzI;PkIv=VKZhMh|!DwR##?K8)~?a6}Axq)h-R@f%ePZp({5j0k$ ze9|0V*oc9rhwruqu-$C}jtWTrIdFKndZRA7$Ur`#5~UkX92)_LcSY;TWP3R?Gdp{C z50=l})r0D@=P*Qnto}KUoRKzl=8q2hGcrOomG}f2;k+i7>LyZ8`~@IWP?VR|YmihF3g^Zwm+j=`NaW zUx@6Rm%&q1esdxkE_SzBtkqz$;*32w((YTbHxl;-&;XURe%cva;yoK9ML0HoOT{hQHi#p8UrYJD4_P6MP12oTQU*tk*=&Zv{S>BH2pADRtA`sC}E1^1`Sf{v;ut z0L52z{J|(CFRR>2on}^!rp%pT8XnLtdb@khphTL%=;kK<-5F#It?OQo1hlDtrf$%l z3&1$1t+_G;+{ZZr-~qHMcQ*iCUB6Fl?y!Q|L4AE(k7Zv9dmi6isDEdU3N!z^G((}f zX3fv#Qm^_lXz)Vi;dcOh@jmCy{&8kYcL85(Y6?WxbmE~*mS8s!zy#bwXRpG)<}+wy ze|R*`JzsT018P5Z8|?TsE@HnN{WI(|RS`ozH%1S(R#hrU4D^#YY@~i;s!%fY| z=FZPPfPZyNfKNMDhGDf+e9F9yZp)bwC4O*sQVI$0Kq z|HS*~JxfQVR?L@(Hr?4$Vsx4HAo8tTbFREk`PbLpXa=3~k%x-PF98)!} zT45jvoT7<*FF1}sxpKxes1lH?lAu!itv3E6-4UHxgxbKiZpJMkw~7Oo)qG~=GyPwzWpD_}wp&*9m<_PUThC2*pzc zG2-E_sjVTOvo)}A_+V3usj#1Q7$-lmbt$bCAMb6*}pv1%~PO@-!OS`qo zGo={~PoCY}->T5>{!%|djzgZ>ShTTjEPR;LNnlL??`di4ns1LN?;qe^yi%v^vE>q~ zRLp1O=9OtxL1WldkI138k2-d>}XO0MU7;lb5ahJ63hRL0&qj{Mjp z-4awETQ8Ub(l7l3(h@v$S-MPNi|$sRR6`%F=*60$JJ#7=o(^KSU(6 zF1b3|!hN;dDP}jV<3$Xicr=c1r558d_>wf5pjgIfW5+MK23vK$oh%#NrPQf0C}WY- zQM?uQF7T6}YnqN%*2EmxAJ5cFp;9EvCUc0 zu2=w7R+pi#zvlS-6Lh0`YbI8my`~fmcMw;0b#hh|m*qwYej>?rR$)jxcRWhV>Rz{dTd6ELKlt8TaI~|gi$}%^?xr%Yjq@_|2QlinyTV*Q z9MI-LMKJLVVG>8n#X4Tp@mvn<(Bda$L=8Ig=^ymYz430nb4p66fY$t$*E>k-<9^oT zRG83!;QgwL^(B-r765>P4m?0%x=jDI-N^g<3zI%C4J-2Tq^Yp6HN_g&-WNYF!$O&sNzfXAqV1sAyI)kU@3kEpTVjf zw|2*||Gx2~`Et=8XR9mx7Lj-B{SX3oDC~LRbL6n*{jBClLop{- zs0ghAp(29so%G@YdSL(|Dd3#O&DiN8yWu8O-OVk-Bj`%Jkg4GdtKyGnnCNi7f7`*1 zVOUEy|BgA3KQJFELSwW%UImSNh&_6xWSFf@f2OTV4}o0I!I+9_be`U9c%>#}2_JoJ$ zf7Iyk@0<|_tl#ZD9vM8bWs=lDpf30t*WkNyFZkyR;WzXUnB0@ZiQyo7?n($M9<_7?wGY75j`BTV~Ml+v;BJ5;Lv%L)M zKc!C19MMJs{x0$QJyu>l5$Pz=f^S^as$+H;qS}F?4#KMS?8x_bHGadWu@eeA%Zapg zT6wYwvKBRv$hiRqdy@#7nMj{F@YPL%%p~8A{6aNkd|<06+iM6nTP^k)EEv?fOcnYR ziTxDHrhrc&DZSh58n+L)zg5>c zZ0OVPnfa|lVn2=Psq1-D+6G}Z=;Cc$llRSWgaSW(RYIcMtWdv9hA6?tgQqf96Y|AN zfSe(DDxy{;UloEOqnX9wMczb(t|^|Ngf8J(HN5>oG!d#XdvkXi&x~DrhCS0Hua_b3 zjKBx7Wgm#XF(=>C#Fl%#xkZ~6W*O<3LVxrP5Us_dF-rpD)TpAi+Q#}8NEgh>70ihV z<&|k3lBY~!(uJHfq8~+9y+)CxjA1<3&oCtf*I_gpXhmRWhW+At-&u81yiZ1=ps2ILoW#d+`cd26gLX|RW@jUHx zZdGPEC8=;;Cg-GCowx=ab&kH>6+G|(hreZg&{d6w5iY&|Zy;4%r3xO((dolmg!9I3w zyRu8r3yMe%Jzca#O72JbdpWJddzg*gf1DK;*$qewz8FZKXZMNFw@JQ>Fe9UFjq;?nyO55Sra{&&i?uL-%me+eEw5QcgIu^lrGnc*gkWO z8l!01*}mX}x3BoAU-l3DtYrCt-T_#~Ldj80I(YI9G3d}QYatFg0q$RU2>Eol(Ry%q zDtNyJJ-qK~_DDgUIbt9{o-GmU^>lbObSN=1U5LKbX>r{0)D;<-T|5 zn6mKOtvy?<1eEH1lB^HIV{3+(IBPI2YOnK#Tv3;%&>DN^%i z=I)R;HyzD&CqjEm0)d&-UZQR&z+f05?848xiu^W=# zWqRBT4Y6H6+>f&KAiuw95Yom_!+U=8@$p%1JaN7I=a*eF_z@_;>Fn%8MnNq^2X;O{ zNU8fa50vBge5YKoP{WvI%az7*zib=3+^WSO<-r4Knt1rFuIn}rKtj>M9_1P*Km%KC z1IzIEoRc#B{@}`O7W8h2+1F~LTxV8ku-N~3uiDS0v%2|U-eyP=zBV0zEJG|US*rM2 zKgA+|uY%rfpoJIyl;>0ETrbvlVCUplYSk?{Ys$#TFv%|yKi{NHN*Z=z&{IzzE$*$W zC6>Vt+*<zI9_D5syFCC}1*2RX?E4i0zK#bL0$Mg%8 zS}3B<2W$8BPHXhIV{X4w*a#P5oc^_1U<6~t2{naT#T3JpPt~#lkq&SE{AEE8Exo1=}Yz&ab@m;duEQd`${z&4sj!C zDKNETV*};6#JIAGv?{i}?M`=JxaC{(UF;(L)`yfTdvj6?ZT2;~Nk#DSqZFlqwrwl> zfX7zeRgElHE(r$%(pFp4u|&Ofs}Da>DF5`agV`oI?r~8`5xreS43?tToq&sSB~X zx&RC3==BV&mGy007nf8*;rwqJ&Xk#&`5D*VAk;$H_ZTTGY;H&aTIc2gwAf9T;~ry+ zDYeWJ5eB+cP`8Z_#qnfG`7g0-5;l8S-;|u=PB=i8q`ohjxB+DV-EL^;_5`1Vm?mf9 z5)5_4di2HMUmQznKi|3fs^1?V_WZcN*fnrj1g?9%sRxW&KJMf7LN8mw4}~fniq%D)JodJ>3IBwv7U^Fe^PnF+UdB8=<9i~cyNppF zVqd$2eXom1rh&=k4$LFwITtFNWMLZ^t|g9-)aeGnd91!NhK7F9toLRtS9|(My4|xy z^RVmY-`nng(ENCX=TM@2Su>0N2o7@6Y_;$KEQIM98C#`U_7rJjmjGcTDb9D7l7W%& zKjp7CLH208_-l2?|EqltpzEyhi3uklVqEWWuK#ulemkXtIS}i&IXoiv1UNV^FGPSE zFdDg42cb*e+)b3H6Wl0 zC{0j-&4tn^WB-Q_zrM^vf*dh3e1mR=34Kwedn|!Cw4YzK*zn)A1hADCuJ~AHM0D*O z9{)*i1gc0mGTT6OSrb5W+u;cznZZcC)A)9Dz^5#4xf^@pf-CutIA$20$%?{BPgdt< zr_pEfs~7&N)&lZE8-2B6M8lFJ@MQx11?OvWR<~SCk8$0-mu2_lCvHS^@DUe%Q*-ie zTm_j0=%MP1@7m^Vzn80zn%3W7`?wai8>Q~BgtnA*Jd2;07cf@T8~ykLdo>-Yc&n&K zfFHl^){mq2YwBh2e_ntCEeeA&c7>CF-<7EK0>5nGBvG%T%!$~rh=Iy%U_LjmmjS#NYt}Bnb5||b@N&I3k(P^BEEzR-dFUz=$+T0g zP#>`X{DYrm1v_#qGlKRS;pp>CdzJu5Bl(IwVVN9A;C*qe_+D%#>hGk}Dq)!d|C zBnp?y$h7FHkn-6!gnoNuT4qw%2X6**oH12Ki;qAnzBUy(^xkpm?YEjUa`9va&J1prD3M+!KwsS@xxkFp~ z(+^!r*wQhbfjlf3y98-9u|BofM}~2*YB>W|2nirwy}gO39H|Xong4rZ`^=WPG%5nl zeN5|lWd;3AUAzRU724;;5d!RZGtD#-tk&PD73)}S+Zg6oYJ$-5&%G`6n}JqtTSoru z5EY(OqtTdV19+KV#&XGQ@5aOqhG=ov1` ze`D2zKD`!vPJ&-smTA;3TK-dOG>a?wqq0PW(FL5-%;tBB{-fgwMIJnP`S33c;DGDi z2|ba$zWO1fqOx&yrCPU+Uz!YK-MKkAJ*KVScX{BQ17)xL|ILE8Cf43ew_9<(Hx9`v z-2st_uP*qKIq2GBrEB&Vm(WM2uFDCC0l~hmHmpcb-wTH5bWfeZ7oO()dHBoKydvqq zk<(6F%=eU8_31n;6KUNqI9;A&2M=lO|2BKWy1}YS=UbOF?$?!&t|7eco4A+xjTc_% znG!U--ToCOWsh1>vCvjx4rJsA8pQeWAAR7eqWh_0)$1Tf;G*ZlJ6*56l#YGQY5;4U z%?AStq)ZxhTytA=8YcF*_|J)`T{-ll>k20ry<-c-VUv>dQMwRY(CQ#4K03Opq|76J zlL|gqM_=E3tqsNZXrJ&iF-g8kCCxIECWUgx(EX}s4Fu*u&)9v?C2>WeLH^*4@T<%r ztQut-qZSw?@B~!zU?W-*P9d@ROuA9$H1GfF1#{3n_3pI@x+g~Z^cUK87Bp}DK}{UE zt0zRd#wg%@tw7evls$^Inc&d@s14iO?~U@giOba@jcdb13w|={a@{X3uUBYxF9g!7 z;mwH0f|owxxiCNp7WD5BOV3{@S}8XQSu}@KP#9n-lKQ{e6)BQ>!KIS;gzr1&TyH#~ zX6ptRUeQ{?^wl}`|3tUy*mHgSi<4?b^A=5uY}KsenLF0ANtTdcXN-T5u9Yg9nd_1g zJcdA*=Mk9_TxY3ZQ=`;ZGb}t-g+eNWS*@6e+%9nJ^dNKao=RT3Eyq_e``wTU z)K_KEU9?2Ucd1Fiz=5<1Vs7q@D-3^leztQn>v7Sx*d4jneqTrtt|nc-y#26S?4>K? zzwxf>0F$QZ?)LV3d2*waVDv-W`I7=$X@>?G#t0p z&RA-`pP@q!Ok5e+y7|lYS%lf2T9vW48+B+YfHHioPIJyI?kbuzC!ULOP_Cc5@Vxfg zT(nt3u^_6e_*jM*&Q=qIBh$@Sn8nNJcmFZc$i6f1Vj8U_J}Bbkog=uj;-1n3jQUG`NfWBhMwsktsgaF5%e2Id&vCRwo za(RGo1n?#D*X)6fZ;QUFLu}#5$T9!*jH$gf$!ub5#-+*AL1X8z3k1j?>n=*jN+_L^ z9oeF8T!;64d!CvY8Xg$1vT93YB~`?i$We$wAXET8Yj9q=ba?DrPAmpQZ|0H}2p}a zCl-!OlHKtM-~`GrM){%rkUQV|e?E$Id2gKiFO;OOSl>x0m|ml1A7T_H>TId8zXV>hm>T^ZaluAQ(yV>6t{P^EWI85k<{OutQnr;Va znzrTg0!EL=xBG4|Ue`rP(&XLSxo@`1B(Lv95a}0WvH$MKB)%6S)HF0+(B};>;3_PK zNGnpe#~6B^mcSf{0;M~Al$1LFr}`G4@ zn8&i7Z|i<~B$M+9xj|63PM|>U>sD31@yUD1ii7G_CK*Woe2Z}a9rY19JT0W*?WbCD z90NhV%}ugpdEBu&OHRTSi`BF0f7&dvN5%J3u0J8EgFQWDgT@GuRMT0M(;;k&k4Vu~ zbShb>2oQxx00)it3e$Rd#$gdR({@m;)!C{b`S9zPgel!h`2_OIvB6CHt$e0%8=6$B z=blV%=d-=L{w+0^p6_R*S=Hb(dfs93J}H@qNLR!fbjbxAH_Yge2JX^)@V5$hLA)ysnDGVl1l6v!2L z#jgDncq3R=XD$9f`v>PdgR0UL3tu?Qy7F)4{0_rjjnUSw8juHNM z+SH{sJHj*fDD(PWp#0vX!dpxG4>dxAPLr*2U;Y_->!4S;geNI(oe@hQ}0`pRsn zS~3xoGgZ@}v7-muhpF|MMl-ptI!lH+RP#Oz>^MZN)G?!Rf(rgo#?( zSa5;G%Z_${k=A4+VhI>wIh_oSwH?=7C{Ra9?66h6tZ{f^n;EX&XSMQQ+f4N5m&N zlW6pfCC=H6)`QS;AD;?&rpq^tj7-7DXlJyRAToE~5NYR{dLQ#(g`p}RGdkXVws7o^ zY5uOKU)tQAMj3WjYd!xCPuG*AV&RXGr{y<@yKR)Q5L^QAo?rx%(26jnv8QOpE0#Gz z7-Qv$iZrUG+;yZeR7PY_6~w^xy?PS^xE2AV2$mYVDc_pStd z?gak6S)k3>Hjfsw@hGxz7o#dKY;CyC*4cVxQy^KFSy5~M-}*5<26Gk;;0UDPCQ<8-Qx9% zMRmbNYwk{KxPzhz#!AAs$8}AY`OE*rQ%w6Dwj&8~+^R}ypQL^MG8#|LvQ_^;>*UiY zcQoxt)ir&gjd!lrPmNHO@Hia z+*##OFE8teO&6;~WNet9HgCf<#mzGk@cNt~0E$Oq0)4DBkLps%RVU<5{Cj(~2C+AK zP0dM;{0LC+E|&gDCHnn@+*vhd@#ii*Ke&}u^$Euc=J{8v9D`Z^MLtx{6eRKGH!WLV zl`FlXG_PKv$d(kgcIE2!poc^bK2nO;1>7179;ALcus=EA88@(sk9GfwDY>F(XaT$Y zr^o$EYGphs4;?~kPu(pi1!A)ON%%vpShVnSy>S1%AJA{f z=zP!bzt;PW4`(fg#W`p0XWx5Yo6LM~JX_Co=q=FZx0F+Mc%5OzL)>Gp*;o7?;b$Ht z0GvpD&28*F$;{BpryP9*@Ol>%+1L{>bMo^N$0 z6zVcq;a8YRTJ_%C-_WJ$OMdcX*0u9kFBkt{3RFE_sf~cK3Pc2Tv-{tj_cD(v!7_L| zbG|3;EmWJ1jw&W7AOqd!{dWJV!c-Y5KX5Qop4@ zhW@E34rENSB9*dft9q+OeVclY36iXWIV+Vi?y<4SP_R@K+qt%$o|&2F5B-ue6IZ*? z(jjUA*r*U)Nij+<)}Z3i$9m7N35eo{hMDEX4!tN;oK1hfS8&bhqe=2)QfE%6vT7;} z1X|d#Of!&SehlOIVBDi#5ve6n0_T7OiV%@~FLM;bU!D@p!h(bp@rU4YK`Mr(gByHW(2C{^AxJ&H#3^CSeIgHEevXolgLPW{eW!fm5;f%Xy=LW;2DqD^UI zqk^kMeTsNv+RdZp!zEic!wV?f!3uX+_FCB#uJ( zrw12-CMv&>!kJ$m$O4X~0lVAzCDWQrg>q4eM_~UB5~k3(Aif1=^>tnL_n69jjWQ0W zJ1kMcU{z*TO(}qH^c>M#R{4@F*tl|Yq6XY)B#F~5XPQy3sKcjPq*Mi1oOU=LvjQH} z{yjkhrfzK?w;e>oX1XI`FkFcl!?xf0X#d>5Eu+2qwV_fHV$)Iu|BavsrBFu{9rVWW zjsm?=tIK=ce7g?GS6&D7x=q0|FHA?jBi;Y4ZM%?#x`5?{ugxT|wvCKL6}oMnxJV7S zPbC3=4O9wvmUnPlo;XMzuB5rJ&AAM15_%3mgOAGQsj z^%T?m^WQx9t#vMU+;))rZ$)69E*`ghI?;G1e2y9%=)OGbti^?JQZxmzQXQSM;2_#k zs|ZmAy2}`o0i$thPL6@y^3>`W%2Ip*Dc|-HL*JyfDs4nwz&k%nebJM@rdQl&^x5{o zEZwm`G$Jnt)=E6)B}e~xlL}l@G`nHLIG^oao;zvGHLDqws$JJrVuhW))qVV`6w?q*gmx6}CO*M0=s@-;>;Mj%6)Z@}?>5=WXs4M*1 zJR$kt2{l@{ZV%XLO#3R8-W9(u(=>+G0FV(i{S0ZDLA~61yZIWH(7MQ;KR@O2 z0`ek2=Rl=A0Q&eA)J^8R$W>SxDXRJEePQp4Ukr zeD3u81B3=4vH+ikr=+~?K_p`wn!3bMOH})QMF5y+LU&}DAOlm^iV4op@l$DXV^7bl z^dW{h$5jcaYPW~q!=o&h4fhZHk!ZQLt!zh=J?qb4n7O5zzC)GenOf2a>`s-FOir8BNYl&4MW5TYiAO$1F5#&Lb^F#9J!jo!v;16nIQEdJ9@ZM z!gXdA2p;O#ALJn8-s`}>r^8rSVwMP3SGTx#Lgn71k+Ul2d9H7AlSn0F?uAmS5+t0h z!@pO%Nxo(mE&T+nlGUL_Gip?+6CvMr9yQ=cx7zKB#A+4=1lymNF4vpu^fVhS2vhXF z#g@}s^gxMdjFJ>S-pe73fBxM#&>3G!$r(e8>f!i8&ahclwO5ZS5NA?~8OlLiGrlWf zC_I)&jWH`h!z@JiTS2x|)RP(cI~Ob+RD=U0kw6AnqBxiqUy=ylx3Vbf#L#|Dw%wi3 z3CpKFzQEEdLu=9U!X}bTWs5wULf4nCtnl&^bC>LT2SAqc+t`K%#!A>b+(~0>LNwfh zVssV%qaCyhdw&DEuL1z05}gfq>NW9v{Lr?tM#|$^huUYPP_iuM)Ko*>g|+F&?6ZF^ zkELZ_3Bb7-kKF5LD#MYy^DW&X*kKoZr?ABdgTXPw2S%vs0pL#|b!XDj11sh+vgYvd zuD7kAzxuTkAvOK1dgnP<5;6t%wfJ6z{B`)}kQ2!ZQ04gpa0L1R8@w-oa?O3b+MX%s zbCacWC%jW_G4^r%^O?ZS>B`92^Xi!s06GBJJ>vk&D(WoP*S)pUF)e80i+7%PLY%W# zdPj%o%SHGRfCQh`PGdFI_FiB<`P5&IrJvw-0l#>B7&`IugPP84dsAVBcm0Q?7Egyx zzTb#@vbL>BsuH4i^`OhO=TfDY>xmQ8mv?XfP6*vzy*kaWV0P55Se3fB(k?k+B$P@WMdPr| zcB0EHg&kY+=USw7kK|#ZkJ5q_w0G7-j#2eSB9X7jpcg~h`k_afUZca05<) zX(@PzBJom%itQ>TjU|}$$p9vko5gT>*D~AZ*DM3R~GFt>{bcOm9x&1QF z6wTn^MD(Z1fUF-CiZaQD+K&yYH913O7xI!hM+f}H6eu88*6Hcx=q+%Q1M#x^C@cZd z;Eyx3|IRAXB+kgGTC_T;zX9=xHUqB?qTLIO$hn19LHPL9$7@)6y696`vBN0^1qC67uRUE$4Wo2)-5z} z#F9+tx<$8YNXR1y?E)+%V!mtAXz%Gr<&fFv=1CSyl^~YWX3l&|_Nf|W&=3JrsReXR z$A zFjjE&XH%&vX1?1_n@8-h*+ME7iu$deb`1%k5?PWIp~fRnF5y20iJmiCt(h-`bS1k6aK3NV8MR5n^P|K_xk?Luu=;M0-yK`Ns+^S> zz<(u^jOq{Dy4$#f7>#$k%ytTYeG!n@juP&CgYn=bjfDvGs>k}AwWliiZsG#-I1~g; z%gPd{zYB;mH8Ki}3wYWB#zp{rX(9A58F%@giP-S<+AsiObMWvGPDElLiT99Yhb&f@ zuPg4*cJVIDXZ%x2stsy4t^K5mLgXpm51ERMiNTy`Tw@>PX=?QdvA7d$i_?`I%Ycfu zc9%+3RB&9uw=T@Hl^UlfZsCdbCjzv**Xj9=yVJ^m=ZZLP8+)CThHoWbs-L*8{4V?9 z0U^whvdCgiKNW5eXG>b9f zjZKXDXjWu$vo18e!(aI@c57tG$t+JsM=x$C$Eq#-{ae8&OsS&L;w73UX)H-m_?Zwk zAWbAuf|`jIp2pC~vPH>7&c00Dq6I_?U8|Hxz<4FS#Cfc(UB0|;2E{Txz#MHzD zjR9UPxme@9t4*1gP?=_>#o*1!HjHns+)!FcDUt$B0_zUY)F$m_BwJ4|nH>G=L97!b zB!t?Z{k!=Hz9_Ba7!<%B1s zlq+K_$`tUz%{cfaDoQF-b?V3SLk7LvHwmTbN}8SuYSZ=Y*af}5s}GCje?7(%U5}SF z|2eA*E@keik%6lHhpJj0aQaDR^nhJ%Fv$N)$R7d*-5wk zBarGtyNACQql6H}75o5dIo|O#*ssX*oP0fAaQc;OzH~x2tCPJL#t}-UB>Y*jew6}+ zssQwcGG2zt_nDtMTRnFoRR*d`!hglAbnKU8F%4B_{%bY&8R0_lUkjWXc6meeQ8NfC zQ$iBlr6-&;^}!wTCcVdr#t%W9nPsdHJ}lu^q9|q3fX~JCm|nGscr2ZzTbH(PErII# zJ=v^O32@+xb8IX5aX~9`$ho zr}%?3bHvDAyuFlT?jp3`1JGNbPRY`!x}PHb);Qn}hwXkP{JU`&@XETF4?VDqOIrUEkE&5gX6|aoUFsS|{_mAE z$L|T-zQ%$!Ibi-aOPW0=QD``@Lw zxsOMijSKP?T%Uc&5TA`xI&mvv>3%27&V7YSoe)&C%&8f9VT zpPzcK119q)~>(FzB{Ow1xXt%9q>~;xW$fZwjf8=K5 z)IYt+V@g6TK$^Hdy%jjS&b_~)_div8A3*u$A%^$mIjnK@WyNuHJOx#JY_2covbtKu z!gB9iAe91rvCZqE`E;J@BEGUqOID=zuh#8c4WeJ zrA@(>zl1n4O$N1ulUEE&l&`)@AZ_??T@p}g(FwO@EJl#!dBCjI<(7$-TjKL(sf1^w z8Lt?!u4OaiT#9(~6`hv(wB9{}$X5p^2XAX&HJUCD{j8Q=4j7efG7P51a2;r<$*bps zkSRv>$Zg4tZS&`R?RBvZt0Y7fOI#vJe(OftpK$uu5|M`bbaR-bOVl`Bzgh7ajXxyP z+~N{CHTQHn2<$qgVUw~(r}WEZj1|AM(V~7Q;q$kDle4E<_5}i+M#n(MMhsd!{=779 z)YF%Oub+~VS(gD%cHYvx8@nXBI-{(wnR4Sn+hgmk$!d{Z>3`?6!!sg$nMDKlb zlTOyXb1ps~T`xP-%X7GQIoEez{ezd2GuN?Cm4yyJJ>l%-)J8Y=)8Z5CRxt;eL;vj5 zEGVKS^)=Y39^hHi$DH)RnOB#9D;N^<#1b9jyWRAkMC3~9lLvTug;>l}Qu-Q5p1Mj( z8dKfN!sgxMQ@Rp(Vr;VWyW!BF@X@eZzytwgW{>8sLTWAwessb96tQ?m(S`=Hp#eu# zpa{%Y_-_cJ?&H<+7~M$p2$zj{%7{69CuE;HJ)6m8f1e~qBT-|Sm;LvY=aac=S@D|> zNI(d7rrMN*-!pKrndrgW=Uh<#10D2GCY2UEMTh1#--H(hL~waB`ytR6F@_lf*%$;j z6n!iXHUZ!%n@JfFkwLukX0AY(k(bfCee*YA_r@`JBPr_J)^wrFUk-}Txg*o_^JQPq zWeGe`d#m1sI6!HK%;ms}AJ=aAhYpIxNvIP2$)-DozL8Vfy*G=2XF}H#6YjbdEMTKT z@fBF3Klg*5=*NU-L*1dO_>kyc@=?*XWg$6gjcn}W5gIp3cU-|=P!h9Xoig^+Pk}mG zic``!!ENs}3dxcPTzKu6 z9+BG-kLo8n;jRXLn>V7Nst@d2dvsyRY=?R0!GXh<%m7Q!*vK<0$)3H%n`LVYFmN68 zHURj+tyYg$&f7H)%)vO)vp>5kDAu$@EF;l7ur*jfo9z{F9(&m{)cY#*`FB#wyBTkD zo@wJE1mH29En-zhK9Y;I3#Z?w;4@)v8ZY zmxDpDjSXX=$Hj@u^IlBYW9RE5AU$#d@4_m;R(9I7h4C>)ttUSB3jF#6yFZT*9$kB0 zS*y05rd$25a~wdquz|sU28C|e53e8Odb2QN=pRoKy|^+Je1+Fx^8vAdrEGfFm5RDTF%2W~!@HVjzLLbz3XM0gH=U>btV+^4P0X4Lv8RAVrQ`GIsYb^%<3?6DH;zvX#!9nN2 z3Q1=NSj;H`GBw;Jq}kQGzw~`{ZhLinG>86XyA~EzPreu($yokWYqcrAep!PA&c$w_ z;o{?011DX=bPU6JH`H*rw-bYIdbL9+-+J;dJm?`9I;4Z5whCa9gklD@#A)>4paa>I zV9@{(yf6^-Trk%`c)MCW0uX+Sn7x}W(B5JeW$pG+lNP%hiozzv?N&7lFaG+CPT)c2 z2pHrYOwRk-X$+rP3i>3K47zsr+Hp?4M8^6@Mp;oK*<<+cM9a%NY=k-9S>io$48{oz zgvy+UQcSTkWT;1zGZW4XkQW!(Vw^cil+EU?6M!^-HO0pF#dgke96&F;ho{49!>g*$ zn-xmPEW7#%IV%PUADn)?m|;GGRs`3QFZ|X5vyDWof(S(LBBz{(hU zz^gdIp+}Wv(3`Inl7o545_Qpp73qDd1!itQSnJ*$g8>qoo-{iO(hOahRrxg=nzaKL z*!{^VMTyMfC}qgZ+k1pK$8Si<@A(-2IxfI(w^C@eZSyd7W!L*9o?_;4~u ztH-H%`(&3J=~6Ziur}LZgU`QsCrS59QcrX0KpIi>j}cp*G9F%(9 zA)QdnMXWHV$-A(iwb3`kosy~vx(hC(Pa#4?J&Hk6Nm_3jMl6Sm-GZ~|+5yKND94Gp zW^CS*g&4$X)P~^&J2#7Tu1%=@sr7Is?3d_80eWc#*39%Mz zr;C@ZIZ4vc8o=yc6soeDG@>Px)+D;cx;l}0&+qNCDH>V@%6`PFW>6wCKxLCD_H~IK zzV*8&*Z4bZmGENnvonGy2XVbFuU)?*4kcbDwzb)t>0{kI#wN^{|1kS)B8|q4c1qlc zZMO6Wz3m8_P^~%GATXtQ$0ms=SI4M=T?&6%Hg6K>i)~%WZ?67xPoO7dZW25+L^PcI zvE#^Tvk&**OS97DSfyWBVstd!q7H~tZ^{&bKz@Hw%JgK4x8uT%7-%QcJbghm8*dD} zquGzXl!up}i?L?FqJi`bzHUz3|B-f(La{y(w#3hRmv8l(h2uM~UC7|8e`-roFpccN z?PkfI!XvT(_pD7a0y4%|*ck7Bz!RtKKiCEU$LSasS$=sS{ zIm46^`sVzCwm=0SDhLjVv`VS^Vyy=ztKU$xjGJt`0dLJ94ZAZI^lOqhNk56_F-08j z(x_(f*B-Loaz~>}?lUuRJu-LWTLsk0XTe{+x);11aTUV29!GD{3-J`m@>~~>z6#`u zmC7a{fy>s!8O{azhvNseysy|&^`5D21RnW*=L(2gv*oQbCgDhB1Y{hm{WwIF=96OF z2lK$s1TJ>xDcPIAOY?=Qq#-zSm3+~P@rbpp5^`nong~8rVRE>%x6)H1TL2!Gh7NtPv=cXHB0Ub}To0QLbw))`eDa}?hn1g^Re3JkKbDh&PZ z(g_S6i*{0}}1yrqZ!B)eXUW{DqOW19?k< zH6X=E69lvbn)+_7o?W>n=1(jxFJ3<1wvt2}$0YoMUnoRuz6#DS36n4(H(aYhWJ_kN zBY{!SHRZ`ZC`KJ;0(K#=rlE+cH`sll7i=WbI4vp*`-oBaEs;Lfd8mKF!pjR4O7qSI z2J9Gc2T;XO(K;qZuh4++s_!0xx_vDFbQJSxOmV&<8YiEIg5mD%CL26r&X)404+}MH(g|qZq%cn4WeeC> zHcrp{iAAH%?m-jvknv)84hYp07adAOk#&y|7TZ4NNycGdxyJO;?`G=)r*}d?neLU3 zeveVw<0QIx#qZG-j*+=s`#E@A#1hD5F$V5m3uZQ*68RZAP_iukLZqHXj>29%nSW{M z)?FV&_9H!wweQj&gCDyFUyZwK@e;r!Q%hQ=ekXW9K2OmlM6^?yZ6ElbtC$7v^caf} zqVL~+27Vn$Fr-UR2dSwdbSV*1jD~z?qqgG?O^R96Ql1(|TKOM3 z_}>`pfBBhApI>|C;qef%&eHv5RoeOB6_bgVvNIrXn-I^H%PwNiffA~)OU_Fei*qt& zbz{<=mbDHcM*p#wgxB2xLyb<0jpR z#;>x9Ocs%cQUDCkigEw$X4{^PI@oUvlg3eD& zf6RMLU28pv>o~u6?Bs_`*}*1OLI)CUv?=D_xXr^rslzfOvUeSe>Mbh`u?5Q8>#8U{ zY!WEltL=N6AV}*pP#X@*nD2<%6S`GBOf*Ll%@qxhAq?+x8eMu|R8xC<2>nQ(`Wd}+ z-3ul^K05WZ9Jj7cAd^j%*i9gMgT)c5cANL>GZvI@YK65>ooVuJ^EJA)Dpjmp=5itR zTq1ZckUpGCQ|asesUrtpYh>z6bb#b95{)>LVh~Q0Bxb%Ejy;AGe;HF19GZ@8QQ`MJ z4C=iz_ZAdNt%bTs8VC#_$+&MiUe7Pm4ZQa80uaj~P zoIMn8*5-X3Dl5e9XM(Mtr3&7&Q9&ENhBIO;8bC?)@AeG$Y5&w~oLi_wLP>T5B*Ep+mW~Wy$CmoO+PB9y zS4uw5CoHee-Asn=D{uS7Hrldvc_ZCfH}573#WMeFtQ=i?SU#vLmB?q`oz+LIGYG^}}+Wf+)U9Ne*Yz$h$QhKA;TezV&Q zeW*EmAL+Q|rsl$TIJxKNESYFJbZPdlwY0S@!26uv#Sk2l<)EsjgoyG=|lgrJ8^X}-Ss*BS(3_>s#U0* zr-raRG9>v4i&rZHs5GFI2(tAJD2J1Ua&%MVEuSUQpe9G6`mR}m(LJ9os7J>qw!p>K za1^oVp9M+60jfGlW*}LAz6xuzQ11p7X_yQxL^ZoVfRm3~($p`EOYyhBk{Azrf`%oN ztj1ajZVgA7KIhSwPT?ZqeHG@EpGm`DS#6P@mr1V2xzA#7Ype-<>?$NgY@d=9(8-T{ z6yMu^g3^#+XzB6|4PTHSJm`$`#sVc)(B$-)W~_s+&xF^C8@>~l&gkATSI z2fp8_W-%+?6Tno*^>X$FzIdW(6TlJ+9|f&@7efhY+cMWX`-FrUEy<<6xE0ruP{Kmu zh&)_$+B5DSoG?2Gsl{twR_BZMV1VrW#cv36 zT*ouK_=SEY*5QilH>6YqCYVGr}2IY7Mq<@D?&_VXDK*>r5b zW(L2mwf*n#Ssmy19k|;6c|IW9@BwOQ;^uZe8UkCwbIEMjwY=o?3Nw}=lzeIgE}L)P z)tQ@H;sXvl39s&FJzn8opA_b6OYtwR&&Z6N>f>-j@pv6+`I^7!Ja8z^czq zzO_`dwnR40MeVgMW5cXercBJvxNAD^W^X@Cs6`MAP>fVDdX0_jkew1j>>1FR(u<`& z7!ejuQm)MOLXtS*_)JISpg3V-qIl7?zH24QpmhRYf%)ER{Te*89neX0><`%}9s6KV zl(ol_2^N>v(>b-baXy{Fd5`U?*O*-8>(pZT!RsghkiLWI8UR*TyUbro2F|A)E3OgP z^s%J$vG14DX@)@R@?rq0#}Ny$_~P%ij9c&#i0+7!*)9XB!33C8VJ@8LNP->LV?KXr z@IBKg6Ow{KC<|JK&{+pH#s~SNcYTnIWy{cHF;jbjSm*Z?lON|*xO5a!6hBQ_aS>uD zI17lWF(%7QA+E71m*O>V@@YEXUC{4e`_M60C{se~9Ohb79#pL*cqNCf^AE9hF)X97T}&>!d#a5}aHY%~y4SDSPb;-!>< z>bD_ON+A{MBj6nAPRF8k$j4>H3;FZxrJ!7GUe$Q2WLr!mNchy`jsLATX{c-3PX%Sr zT`@Q<{{+I~Ze@6V+71QHiDaV*LlsPYqQ1*I zZ+hu|{IwhYTmZgHNJ?53hgy`Fm^tf{%EXs1+9s9eRkWth+bNbrVb_QB^)6Oh@zM(q z4b1Niw(|suqtYbqCc8grN`KFWlfHbkTZ>136psbgwSKp&W7No)HEpg5Ao;HXVafxF zm3TDOV-m*dn2cBy+>tyJ&r-F|Jv!~4jUBn7qe zjj9+P|6Yh39@Zmd)D)^cEz)7~a~;(U62e*o*V*K#>cqQxoOh^5dmU#kz)7yQrY3kU z1F&YjTq(UKMUeZav7z%hZ~s{g>5ubl-y%I*4BxJy)4)uW6Eel=C8;9O zxV(k=vQFK0m<;IA^^wX0FASu(XqNC&gKb+pIc{~?k?ctNxpVN>Ar$(#WJo0eU(?)M zZUqqb7UzphwF@)AiWt%=SDVj!r+NX59S%7uZ=N$f)~X-30=$+9Qt&kevx}FUNUE!< zM4Ii=a%du5u+pK?OwdsED4NK6EU_zZeWd3gb9X7#fzh6J`$xrMx)Pbh&~jams)mk% z(JL+j{U`a;ms1bEYR@D~{U_#|v$fuTcFC~Yv)$RsmY|1i_*j{J`?`e=KTb>%zu-Y~ zuWw_ig1LuRpB|*+*7dHLWY~ia1%fD$3=1}K!Aia#N{bl`UZg%EcgVS|Ny^(VMg5Xj zTXsV2g+_qF^Mr%+t7RoY z`{wMLjazHwzZPo;i;>;8Wc;q*XQ7e_R^L>oyxr?j-NXw>IMJgDuqNC^9Vg0ZSX^?uxM z+6FrQtw5g@jFFL&pN{|^aG{?9qGen69gz(5Kz8Dg>0Bz4uUw!Es%@wq7zZf2HP$(z zSW`#WsJ%a$7x{`0xf|><3WQNmdP3bxdL;mbr`2m+qg1_k{_K1|zn3f1K1H(?We0nQ zbafy_6@(wJ3Yd1MuNfGVsXDf5CawOSazWw&V=v<@W0*-KNOAufp(PumvVB7;B}K{U z_)q*3h2byt$U;glxXP5KjtG1yx+6d!5@e|fsW+5Hv|Hl7PZ9Z%$tE3Vsc z?5U~72_*}ghEQVZ{5^Ub+8YR{4bAGjA1u=gx>w2ny36ckuAXv<*(Tz%+Eohh5aGv^ zRz*|KX{2ZwejfVzm(y?G>r;^D)ONtrRs73W4benQ6yy-0?mX#woyL5dVkC?qt#YV& zrTK2yM3N%m=Qu_C#z(C%qO>C4?8X#b$If~btFJ}I#R@x1-|De=NR)K*vgVzaC>Owq z6)xc1^7{j8WH4ug79`IxvOPrHU`r}HvYmK3;BDVi%fIl09}+(=KYUxpJg^@|j(3O;(Z%5kBjRLGl$_?vX| zb&Sr?Oj^SPXb9l(u_|JJn`>TI=#j;~(wpxi|_QjcQxgtkn70cP3 zP@*Qu;O~lxiw(?IP5+0ON@M$adw9DriG>{4qzI4h(1~n$Zd+u`Jm)Lc+&}n3U*Z|< zqnU%pqEb@9XH#~h4OhS1@!m&-B!4SMc9zzKqzYlMlpj7RH zXVebN8?(Fn$V_*N-*F{=``sE8yabLIz`W^ltFu=R(I9^d*HHyVszOuVe!LBeBX8nh zePJW~dr-&lK@Lxj_OVU-W}rrm=*=)jak{H|$pbRuTv4*oZnB;B&IDm=Y_i7Op<7Rv zjPW!Lts*X(f4oh-ShZ_WsH#kS6#Ir6a_tl7}V~=%)OcAaD z1q+hJ#dPTzzko>yJp%iP_{g(k1PH|rZVdv@m2N+4T1GwSJ4$dqkq#79tcj)+Rb6d3 zUzu?+#~OjKI%cYL4je1jI^8dN{x8}ifnp!AG&utQybV5fYXbx+Sq6whKj*FLmtB1X zlbjXEAK55mO}KC-JXD4QORuF;6-$&#)(Z8mfWAe%=(jvP8hl>P>HUdizwPVNveWam zm??`w{_?MVP2N&HM?(*XYj;Rh%}1o-#?LYS=8AXykYt<;ty3VP>}E4DwNI8U9WC8S z>{F3pBm6;w9VXWOM#%ojSvE~n3uw)zS(G?cr&dk8(NF)06UNZH@h00W$MXFF;m_f= zVO2_Y)KflI2bVYD#`2Bx{T_mcxNezGS*Z1#?z+^;Ax9suhB+p53X@KpmFm5I^FZ|& z`@jC(+up=(8GB#YGkiGKm)L7R=08II|6YJALW;%?`%~0-dxKFB3yjhQbYqZ%};NwxrK4yxO?>%*} z3uow&o5{E*`)X49e#h{|+~E086PA7E8}WG7nVU$jbon22R#5(l&=BezqmbDk zZ0*R$shL3YyW;mn&YCZ#qtDSqP0bXC=vNe20KM(~I@kR};yKqt#PFgLX3$90z+JAi z+0p{a=h^Ryv{bLg!SNsYM|!>$oZqpb8@RtTf6kp^-7NVavSw8gt>pKRh}?0R{MevN z|Ivw%9X-MXOrn!sdcj06Vm>8s$5KxmSQcVL5#FnuIb$r&ZkC+`;5;MkGJu)BX*O*P7S=(?mB7CNzPnWbd~CGW{~<| zGfegoda{wM%ErehZg-|h(od5%b1e%f`P(%vgZQC}C`fSa2DuK6(g`+EP%7(;3|XF< zb(G8DvVx0T%Ls|`B%IhSGxPvOc3SI#&nGGSb*)*oj^s>bOnTmvP(7!9+M%tuf4D-g z{gnYPI};ry_v?k2(Q&?ax8tW|!btP)D*SdBC})UoPgcjbukhl?1-l;((Sm0>R`E*T z3}S!FVRV8+o<@bRs-`XYtQi~|Z3vJjQb5>y{)o^8C<&fV|B2GGx^;>o{dIabt62j$NnB z#)?0rXpuaSA#F98vX$lA;#~ie6oU5sL)KNddCeRimGx+PO_HD&B^?(9{})AWes(44 z{Pm0EO5gO`m$?97vtFQ6_C(FL_o;kr zO~a~yGjXNs$EUhC``HGXPveiPgX8VBcKGh4#)~Phv?VW+?qSQH zO4H;1oWl{5ScjOkgzE7H6F`6N!cAS%r*+)*-^J2kX1#!RK2=f|IU#~+-MU1Cq#OsPt!G`nj!w=^T2uWhmBj0dr77%gIevEQ6g6c=nqvJ zXwsjjOr4U@UNYUr**?JV*1anDm~NO>q6Gq2AFTP)C(ku%Sue1%fWwSd3?Xl2{#YFH zmle$1mFocXie;huR7}H%p43%?PbvNmXR+lqlkfPPjuDOjHm-NI?UG7UhEYX{+gd9Z zG0-^4bdp!qESY(^g}66{C~o}09b9O&MScf^k?=XEfzU7By(N*}07n574rfw<38)tH z$D3spv*)Rj+OHP1Fg;{SJk$hGGEnFT+^G^KhvG|pYW}Nlcy8eO` zaJ6ft<(hljL;<>Wz+dX`I0ZDKw%rx_pMl&UG4U8iM6T9u-zDP+ldXh`ShFg%WUcKW zMggc`)`9r^8wJGl7nGyb-NDq`IoP6hM5<6UONx1vm5onDnnAK~k_MeR$LAiZcYB#S zd4&AC+QIz8QidyDH5OAlKYOmO+~N5Ua{SP)y607NyBIj30N_QNKa z5(BA72Y1<<{qtF$D5Xo5gNSa1Wh5v`m4?C9hcrpmi!&sC3hL#VJ7A^*&dEd&38jFD zh5ne^vJh$5%Rp;S9E@e#uP-ms=aBu->$&X0di@6>XVEvw8CYYgyP|zf>S4u8`fOe9e z6l={!#eth94hiulJy0E!NHq<&Fvz7!0*t%QoQ!ahh2L$4LnZmavb*TxAbW$Q@THq4Q+L2gROD1jb&@2}iBiHj0FwY%dR~&0PCW~|gdx5aA z-h5$owQQrurF3e2CN$iizJVu&^BNq0qH?EB)yTth*GDhZeY(=xeAe;!a^PPT*c_() z3-<$(=vQ~6OUx#;u!OgJo8LoR%DIn-iJu~FpO9CtV;id)CdZEiq10Hhr7fcg5;gU# z^`yilocCMQbJgvjHG3!S&?(;EiDEN>pp z+RprZH|K)V`(faYZK6ybc1}Ud z3DTvRRjtYrwXF4mGJ}D+6*9Z67njE&#rY8SL`HF4-rpJ^l+=E=aMMXr~PfEA`>=+XOG=tMDdagk4N zp8feO)>JHqV=ZsD?y#2q7p>CC7}Jj$@w~Yiy2GXlTgKVVG%m=u&9sL;nrw$mri!*C zgT~%&X$+^kbEk)PI8{b89(n5mp6=060snlFl9jyWlTC2!xu2R7lw_XGe9AL%iwk>$ zt%w}4Nwvm2zfaDvDlUQih}G}8QL&d2;U!Pe-fG`+?(?~%>uihwb*cAkqY*zE}&enKMsck-1$d^O<@Qj=PD$#f8I zh>2Eja?E?Ako?l89+0?BIUTF#i@ERFBjy$Xnne_o2p>i)2jq3i$!>wNh^Cp!3{3Ka zCbE>#EXn=QN3xJC{v)7mp9{Q0i9z=9hv7%{Q}wH+J2Z~ut@SfC0e*E7`l}^Upw#IA zGdxMoyd@jo3ZzkXg}hq=s0-6)9tW;1=)K=`>cjUQuO1MVvN4>pu$E>Vp?D!i-_96+ zB~w8QjIDZ&C7M<9ji8stNm!EX6YZNEpM2&d>z4dFUe|kpdZ6d$&9^UZfaAjur ztxYnA7$_wLU*S)tOnOc_B}sUSC@--K<%pmAul1(D<_CA! zI%C{ZeZc~JbiH#+4|z(J9YY8s$5m1cxPSJ%$SO>OPxR)YdKFkw;+vpxC5|5N+(K}% zPP)k6l)F9Cg49t-)up|4fYJo(LPKz0&2pig*q>={SEM{n zx>cR`e{@gfW4l26EM+r&;UBekLX`{scyHA#gmd-ia>*w`ja@jbKR3LWK#M5}B@MPN zf|u4|3a#SyR4O**%8TI+`Q4*vl_+R(qBsnH_1i#8X1XRedF0)r2w=}yJQg_nYZ}+K zcTnX|W++gvZ~M&m7ux2}MtUzYKd0$A;o~1&D6ItS94782JV@f)U9vSE!8wlM^ujnU z6%%Y=fa(W+|1bnhAqh5=oCFa+d;61I^eoL^A69Ro9d~v!Uw>de4QAdYdvs*- zKG*Vc@CuIs&M5`l7oVGlpfdH}RaNH5v0FRC^_*_Bke-Vz`n&Qqf7Y|RFy7j>B`!ur z2JG0y!rvV{sg2?(GcRVKPyRB9S$Fvea4_WVriEkV?q)Jat}(bLE%(oW=oDi7_4$79 zv}5nUxifd_ji0@#zVG@o`MRUy<2D~4do5>=jM(DD$k=&mVIi74-kbm?(qM`rb!O*P zuSYAM3~EEKj0NyZC^*($>+e1VE!6C&fwXO#mUX~MUn3p`53CM^hm4{@(iV zn!jVO)^n4_Izg2&nGhWwpJ#0U{s6+x``J;6W!I>nTlV;UpxYB;YUlQ>-hGdpbVRCtL1@lh3&~)zVHLLYN*qSbh4TGTpbLG}alYdsYfGG~PLx0G z%mNXe_YJNpVeyaZxzn~sbSM~4nKwNUMvyh7E*)d!_??syy0*G%Xn@cZ##EYOX=KE3 zSXi2PjzdwW*^worn+Kw;rstN+@#`b`XJwPQAjjvu{GXwT5$#Z&xS~`1y6u{^<8wxu ze&r<^Nt}sJG+oaWg`8T4e<2d zyYiEgO2z*`@$D2zNE2y(=|a>UllRo~JY}9YXpdp~v{KAFrWDn`h3PWSi}4M1WB5mc z+k7O&KA_I_F(&|4xq69zU%B>D2|eQPQE^~Q?mc@+#mruT_3u4UIU7Iw00*)6-1&1L`IpYL`3{(`mZ)a%@M-j7G;lLy4s%eNhG zzjO*xXA=}bW?b9|cC5^`AC@JSk=yrXA%rGoh??cQFvGSWr>6hSBGgB0Rre4}OaM;Pw!o=4FL*l^Xq;Il2S>tA+CqtBVUj6|ro6=zX={==iP~jg;p@IuxH<3!jP6^O$gpXfuW5hLJ_GK%dBt|byj{tXuoQ(YAx^e9{j=F=mh zEMZdVW27;tc$gX|--%kb_l)?RuizK_tDJ~k#$CSP8LW;3+2k6CeT*H!ztzz*<$)hL zUax{R&I*0IX%Gu;b&~F4slrq!D3;c}bo_+FFuGt{87qL-d)Jw8u3&3{Z$n5C7NNeI z=V@{cABq_{*8#Ve0TCg(wAuT7D*tWcml%ne${ zJItEb`}%G7(;P(b>X2$Emn#aYAPk-MNFd6Fi>Pq*2wjFE{^akHHD#)aPCde$Gyc!n z6ux-(tWs0KVMV)%pAf5Wmf>bH2>|WuS|Uk3+OvJ&-zZ|c=lM2)eiPf_t?rVb3U;`? zJ=djwdek?mab=a?7S~#ed?~`rtp+D4OP(Q2TidC$nJnq8mq}I}?7F+PB98dHmm-!IAv;-!xkzPjKmTol4(m% zGel9iWYSe+2ZxK@e|}S8xjo;3T_4a3SBtf7M1xZpab#>wGb<|Lr&sP$e*AN zas)A`w5=|69=!0by+Gc|U%?^| zFt0IAf$h$QspreBGWj15L;@Ba@?RbuoX?tn7fNU;hN}c>UppVv#9I{9-6xWi6a^e(M16d`+x_@-T8)c ztGYP3jxK~ema;OH(bwz3)U{5zXxS1UIkFJHgv*5(*akWm7aD+8PT_uxQpB1DZ+)j` zUq;oy;s(?Y2iHc zMMYcVuxxl=BmfnT1qe!R0B%k_H)pSZ#6p=wKpb1z+X!RPtNOyP|F3*|EnMICqfCPE zKBztu(VSwQ9%XV8wA3&`Mw{8TMg-p3q5$_2>|Et+%~C*rxeZJP?K@|nu|Q?ic_&1l z8yuX6J3aW5%ZPZo=5?$b9;wy1h)0U*Lu4nj-qDUa)FMlFHW`b~U8|188TwY_+m-o& z^@IZ)mXCLtNp`1rX7B;gZ+izZ`Bux%MZ_cv@(_oK6S`9m?k$55qI+Z#_6Y zXwxs=a9>%kS0Plri~(e@M0@3&sFPvnpgf)3Gp9g-i`NNbGmFMtG(DjEw7v0h zZsQlS5QIN>#}~@05sqKGwFxSu99mOBZJT|HkXx&-RLULrlhp4Lh>r|$e)DN}3~XD! zFYD-kC0K2KyKnD)?Riv(uTG(AIOA{H;-p0E>xfwOFa*ZZsjfICnQQdOK!eGKC^w@? zotEoLEVF2f_0YxIbg?$ldA|WLo+RN5_H=BTU5P)1KtbN$V1Sbmmi8BQBcHP|pSNok znXwcsx&$mb30o|w$#u7ytG1}CxDda(lqGa71`^ulbFV{BavglhV+ur~@ojU8Q8g*g%U;$2dQ-U6L+*0SUN46DB0_ zyTJelLRz1?0}cURO(NO#Nu`~UizZTl zzAR?bxH3h`7&)>WH+D2_hEhB@;{#T5vZC??!FwCZuN3uy;)Xk74avr~CS~Gm!aA|; z1b2fbhvi=I02cBm{~0cdXv$t^(Q5UrIxEBe-8rs+KUP<}m_#Qh{WiUljp6{S>ziSr zwY6Z2HNf1TxuVDU^+Q{M8*f5D&S9In5h`v_ zW8KjUxLytN_ibhu5m1QS-h_ce2w{2s+5;4SE__LC*`hK6ASG@WO!n^IadGn+O-W;l zcO;A8sYH{6F!z6d*%@%G=^sd6#YD>>C7L%3I5Ap`dHdw-L{;8hPQLv(t%^e0TDm%?3 z6e|n{z!VwFdBw#ho5@@Qf*;ddw4fJR*^na^KC$UdX$Z|QBNmf%9D_}QkKm@3=T1LZ z!0fqJ2-A-T`JJrRZ_lpveIw$~1CEQ(q3gB!;_|5b6&s){ zoGf=a(D8PiH@>Xr=380#oY6gfzJ7(yZaM|pLA$=sZorHM$26X|%o7xsR}>$%vBz3zT;P|(RLjr7t?j&$2EKv?fkR8{Y9PvG4)cMCr_68>XU{ZhhYr_< zCkt2+WX7=i(ceX;x0+C!*xNAx9#WOrbMz-NkRZyYFe`^xp z5nY*}JyS-Sx&~U@QXNJx7@Qa6=0DlxHjt`)YWm!vASNp~wJ6>OPmD1r4tef`({-Zs zJYDN`%exM4?z|abecq=^5TczFI>@Q7pj9EDePu;6e%!WuU-Ei2UTXA@vAq-5o1mTk z?Q}+K*+P{Xlaxix9YRs95gr0yQ`Cj@2{#E@AkK%35H9fpng&}gr_OhX2jDC9u_3CBQXo@p zQ&Yx;gT^O+yAAOW#?ji@oyaC`wh3zhuiV^mKSK_G9kfREIZG*SdDx+xiKUVnC z^d&8az1MLb!yM`GFh6$qO6F}7OBrgIdDH1dpL?n9@7?u*k+ph{R(8*l1$l`_8kth5q3N*7$%!5_jvIdKs z#xhz6rKkNOQgjILaR*NgL?>Je+Ojj|DGN1^z5t(~v}w}A|Ag~CBQMixcE7r+Iv2>a z?eLE>21=U*XRdWaE>^mmUnB{4o}~~=DjyB;Z$s^J2_ZM-)NyReS3)9af)jHpo{s~V zOR~SrT{#qHmP{DtOXWEg45s$yKf~nTrzU*h#!V?(P)}O^R7?_^hz7@{u7hhd`r^w# zAvfrEw%nt=g2-2ateT!N>1oo6yNc-4w7RBb(Y`7rpSAKt>L9TxNjty`QCYq*l^Ics z?yy6xa;ciGNL*gkd+NZDCXY%^F+o2I+}(m9^RKKHa zBJZ#XLIIH{#x6qXLMQ5@w}|=OXYuvwUcQEJ9b-Nh-M*|5`QEX=YQG^oMIb8@o+!ON z%{IICq10MFFXVQd4-!4T;GKVcoI`ZGcJn*Go8k}<8CvYVyUmY0821q35ix7N&B@nw zW+~a7tI+7!V|LmK;eF-FRZigIzD+R&RSTW)Pi<(}@D$^S3}@w|It`Xzv-b$CFgf5x zkxKo1OE_50g!q|fqkQ_ac}0}~abB)xeHfp;eG{>OdYa%3e7J3Xo4|W>`jzvJF-y!#)|BbFp>=lOOq$tr1|-OM4&*>bxtO6cda2yOTSChh%1Ka_hpeJI=T3p3T?uTymK5G=Q}2HxiF>qVP53CogIL zYBL#54rQg|5T0RW=fzBIXY7g;tJT?bk*4uO?NZ;3epDr55#qJ6&JlV#HMlOov8=(%_wU;%;!;k^4SU4M1UWLUG8B-Bp zJj2C=H__7u!YG8yBr44ar#wv+a;)I?OYd0bY z4Z)4pVLIEkc-3aP!9KaarrPUsbVOR?+|9G0{2p|PY1q>)_FkciL*Zx?mI5eO&*~uFip`{C zLw4Zjq70&&>VqKg)`z6o+eL>GR|8dS>p8HlX;V;a(s054>r%Et6 zUr~7|uWccIGVjPUL7YSvb?xAHd@N^ZIP8x&_WH2c=0AMw4_n*YepTA>ap(9XoV=Qy zxm6NIL9(Z4@erTeeil4w&J)~i*a=O!LAr^CICn4Pm)RA=&7mo1>JP?ga~(G?x5R)i zh_JcfjXcumFv?}c=z$pAMEQPrzlp8BK6r}E>3J~~6*LFt>eGvpB0ZPSCa;9?#@%VI z^MCq16d30bk2J%hMg(`Tl5gC-0D|m1CIM`wdvv9pDXklp5AOJJacfC#QklIf+yIRr5ol#d)4`uipXDCZiDCb9+_tSs{Fs2Th z&**54kADkGWLc!1@YL*BApB8)TE@;n{q@|%tSAKgI$2u5kk{`$aAak|ZB~znp}YUP zBoj^afLy#`eb97bfpwcB5v#wy9_sR-v~+kxsSw`vM!RF`LKCW=h$ygov_vG3WOwJ@ z?)a-_p0Thr{n?0WV^P!#?s9b;h4`$u2-ALio9_fBC`TY{3Wq5Mh9GGXoH zPoiZW6%{!98ktvxs2`Hl`m^%}u`?Fda5auc^w?1d>$|Z-6Cr}dxCmtkMMnYn;`osa zs(CzsV-~|)HJeXbK`xX-1fpKrT2*KcHHB7)uNH+`)H>a;@7t)C3w~@!HsZSqMPU`b zdmuw?KP*}dIE8SJXPYA6b1Rff2ts!BA#b<5W|C2qxlR+ooq`oY-Gn0&GDJcd^zbh7>fS# z>)}}?Aeyr&=TA@&jNt3;?0fap`)U2u{+RI_2Ozj(5qW={Lb2MM2TfMv8w$Ba(Wv7; zpHB+`-{wOy!v7BZ&g=8Pn%1GCOks~kFZ5drp(}@Lxi=R_7PL z44+Y(6C5cfS<4n_rcURou(#c#lf=ZE%nxd0@Cn9>u*>Ut_g|@TP&=-Ms_%S)3aUNH z<{$~xNsEgWOlgc=A-|k9kyTJ2N-MeaCo8GqCs(l>Hm@sIXE+1axk8*YZaIh}?%}5F zQ*F1uE^`^tME=317KUizsxxw+Wb(sLUi(SAQN`{_XJ%yd+^$9D7?%91PbTO3*c}Ck zE=tr5?$VmkRjg-R5}IfeGE&jgawXv{W-`C%*$19~#`M%TS&z!*^}o*M?FO&BL6PaR zwCo0rh)>%&*$F#LjvINNl9~IthuYIBHR{E0I%3QV@PAIVFstw`o`D~s=Iq}__!RC+ zd@3^D1=x8|_A;iYl|hNy&hHeJ^Ni{Yrk=!*d-!8fkeFa%A-Diaz>)HecxnJQdcTRF ze;YT=Fxzzj(ICoVAaMpevhtHy%ul^9Lq!G^+fPvQ^7GycW;~hhS?7}k#TpEwdx)G? zcO1I(KgQzf_8OAa(gwP^BzEcOtQ|))d5f; ze0;*~o;L|DZf@t7E4#!Q%Rq<;VKzrB@*X}}{@1NSpJ8h~LhBueDND}XL0WWC{#^6B zD&;DjXc#!S&w_I*jhdwe6$m&3d<%v8y&rOHqZZ-;(qnMqGt%$WFb91d#_$v^Y-39b zcnZdaupcdXGL7n=C}e4qm(*Ng6k{&ym{V|mX>{3m_T9_lw29^Tb1hs2WoXyG{EYdD!oqlTEDy(#1q5ZqWoO`9r~?OXOTNkp&@M{3(7LQ`b7Pk zVc8Xtl<1~iu&6Y_A?C4>Pf4DXzSgNy~0?Q#lYa%=)w zzp{1zMJqQ>@86XKJr|=B=z&ec3vWEg+f#G7CX>O{9aGDN)xGjOH72S5A@9SC#Wh3O z?ELIV_v=tP!`@i!v&VgX{xe7kCGJ1eK7diY^b+Qo{jvAoJ=BqT*2UVB1Ay3>TnAhv za|^v~+;*SuPu*JI6c*o`xrLSakEm-}_X%sd-@dVQJ($*X{F8s%5qaDBlAGgoJ5H4+ zn;AJ@G%mesu z1`Uc`AeysCk+Rv9GMFtz81C3ACyM##=QlHL=C;R#*R017#=j!}sRUwtFO=8blG_7X z1E-vSrO4~ZZ^1!Tm}6S#_SS(gLMif2GL_rvew%^mpXX)E8y0}R1fQTavtzM-#2-?o zR}Dnc@X5%mOig142Q8KPA0=@oPb@}ybwL@t*{&spV-_-Vh!RYe#W!gmntk&LpIu&CR*sUhTsp{wWp|9~zgQJdWw9i6=RM5TQEljNRbli?@ zKze);GNc{ZbooBPE%ZBr9s-k_oH{2PL7ua+R*~E15!Oc_s$ODDJd%8w0!I9|Ej;kO zAI^m+S!Np7PLwQdRtc}fBfTsPnFc{>@MeRf|sui^KDT^H0dDjJv>$`69}W0Z;V z+o2R+hIrqmB3FKaaOC(j;LJ8HU!1UJye?9{b6&V0~uDIN73;cx%CRsBZN zyz%cBGoDdfiLdl?)c_KntG7E>onXpIu_*>YP4RE!15w840Zed95ScRW7%?HfIft>R zJkk`}Z&1v~>x0WafpbY~B?Wz=u7j)-QTY^yWW`chEA@UXgp_EkP~kYGxQ6B_a?924 z;7wTu1ca01Db?(nrq=Wk{$at(xR2(P#y{07GDht2F=J?kOEt!ij|y8`!~PVQ5Dyi! z{{rNuNP291T)lZh?G>6#yMu#8)_u}h`dQ#p{71h;@ETv3U*7fPa_^eYHIVE>i$Fu0 zUY#B2XstgyKksj%PK{Q1?-AP{&z<-;a7~asJUcU^*<2IKFNr8dn{4V$EyI{->diOQ z`?2$Ze{ka!CKj2j_nsIN0Sj*bIiS;y^nn!IqGaZVrCefPyp-13UH){l#?#1y&+`9va;_^z7c*-rv#*U{;t^v0y;TEqw4i?M^h&KYX`?~`A556cz%8qb-FkMb$T@{rVMf85SciO zuNdxQ=`nn3x(ilRY@ z&699%b)(;=^L2rcx0jgONBOg&MI+y+a0SsZJuU)x&hZaG^)7$vhec zy|d%5bA=u-HPV_Qy>L!8G2)}th!HWlpuF+a)co&Y@$GZ7A3*l_7TW-ew(*YcA8~h8 zM)pQd1=GrlYq*(ZS7Rw{MF)A(`LZ+7(m5|D1O z?0!E^m8jUwIN$@w;+($CX18oTy-!GX1?#>cS9j9du6ujf zH9tlPfxrnNk!S9arquCechWjv3M?wKrJbo{#XT`XpCZE%HScZ5tUahT`NY9^zSNK+ z^MeKn0}R+NDeCkX+v#<~8_XcSXTQ*VtD8lAlX5iuu&+TDat)r-{N#DcR8{z?t|c2^ zwB?nUa;O3eIewDwFyC9-*%g(Pgt5(;6A`))!%cBEc#0HWQgK}$Oqri|DCY${Ng1tl z$tX~SEo9kC6vYpjiZd|%<5+-js)axkZip%on$dTIy<^$nmws<~r?Kb<58|cmnMRno zH^`g(;$z2w0d(N{rjP=;m3@bnqQv9_;VoCN)oiQxe^yV}nJb_HQ$b3YCz!l0R)>!PC1mQ$w`ygY+ZWsa85^;4J% z)L@VqSgu5adOJ$C%h41UFw`vDQ&CKdGuVX{Wu`EWiCb%IJ{35fGc!gr$2#JP9WItt zawB$@fczE_suD69lx11_2>dZVpCzX~4(2D8%rQ!TJ zWBr8;m?N+yt_V|THpA4qT!Ad{T7vgC8k&_-Ih6`lR(SDdn<>`Ugv<;;!AX-pMfJBI zL}Wu?+nR)EQz08qB%O^aG3%Afn5qsn)+A>!Q!2+hkqru?##NETr8@qavm)7(G^j<+ zJaE|~CRnDE3pSR$%CFt0B^^ zyNOztsV3ie`tc|h5)x4}FDihyFPKc_BpEgze@nFR`)SD|HkM>Rul>SzV2G=M`zjl_ z>U>-Cd6_+UPgG-V=? zMhulDfY(Djq!=JYJyzx5w;dHKd^@LPYJJGoet*8V`3K5C<=+d^>T>6^l(N9>4ZW4B zvLURv@)%<5_HbyFz-+;?Un!x!9JdDsQl&Y+W#VDppQU2j*%|4=f@Jq|0&`V14WH#8 z-_xNhxO}>ec{zhG6}ybZt29~)IqL)8Q=ETqvv)-CVUZlv@2dz$GRvPn-r+Hve*2`5 zl86AsD9V6jimSszsKk*;IlB~0_TU{5X(44~gwo_7L7lHDKhOH64vsu{21-D|MQ*TG zm(1q#Ls!B{3&@Bk;bV;NQllMjf=H7goDn+C0SfT?W5f*E*jpE?SK$AUbXQxX2v8@y z)cpDsm}U|E_=tq-yr64^ekf`!-ut^yp9p$-4*jbFkw6}H(2sA{<)_?DwfyHP8k3Nx zLCohNkC)wN2m$}zT8!h2o}c;Fnvp(Ic2H1XN{mk(N?al(Rh5i0MM|Ook`h?8uzFYcCP_3~HZ7M7X$cE}wo30{OfK0W5+2&G4X;xMQtnKZCtZfNGO<*4? z9r)%G1qN37IjjB<#C_?1_^y;Bwit`LKXG0Hu1M^oqCyY0&?Rp6$^+$bOw0; zQBf|Vd%;lY3F&Wd#QsolFQ)aGpJrCx286-so;6xqJpUYwRu{4&i8#%h>GXx!? zSmC75RK_Z_JH<&1ZT$N1VW!UtzK7O!lo&CKW?yU#euzfwUVoff=8DQtI*29Mr5(LF zgP28YSR{^^m-D0YkCrs=uwz!l+HCr;q>=EFx>qQ|{H-he3{KR|&S2(T&l^t=g9mJr zmf}^&%fHej99I#Ntytob?W#R4!|Leq=rZw%crtfqIj7z=Y@X-BrSv>=C2OkinVB7K z?k2Y!E?RP`^#doLA@`)f=$JIe7H6?Sng~}nA_qv>IJ)yifB1467q8Bf2Gr2J1VoL+ zdEgo*kqiUk)nckUeMr@DS(37DN?Enyhf>_m%!KobBX;0C_~d*N@=O1? zi|hm3u(r%b46~T>#0T@670HxZQfUl(>!=dgG>3)Xq7S9sc!<^h&>|nO)6_lei>~4GDhp->;3y+NQUp?&oY3bUQ`o3*b3K zjtpM}LS7e}P&IEo+&S*sw0Yi7?4IXK9{rGJpj@nXSk(cWGeDlsnZIuyqZud}zY7b$ zK6W3B&rVwIj{~zql*Ox{U&7xlkh;FjE>>tI)QtPz9?!Sb06?s*ns%Tp(swH9?92t& zlByuw){~lcqttsDcrmXj!K9;cHP%Tx(H11ujvuU$ODR(@-+U#Wu3O1f?qXJXt#eYi z-lA{ZwnZ+Ji{!u0tW#0~g`{}1*lOY(iYrEeIeGgMyu_*G$RW0^FJOz9gU%Y)*gdjQ ztk;oTW25_7hlE%CM#5unK~njOUUK;113Ct5TB(8`ctGZQ>+c_7#IRr>b*IUQv(=Wj z>`Wh%IE_IilK-iJ-AKA%=L+^pw)7khN(}w)#)g=J0#k+i%3ny>1Pq$sNR#h{6^Ai; zX1FxF)j9D-z<`B;-?Xl~MncOAF~sJC(2#_0<`yw9oXLA-HbYD!*JO zB#+plLOe*`V$gmlt0dW^nkQwsk5cBCewYJ_c?BQmJoSTY-mUqb^USJD=}6+-&TRerk>vA&kRn zWhwbkIu;?QrAd`@Q&IJCahHONAK&##-OGhM&z7gaV|a;jWdP{}5_F<@DN&#ESfEl) z(HgLFxNa#jcQYrT=^@?9ugQoq{Uhek!IsgJ;pV)mcnJI+hNkw&@m z|0|aI=Rn{S7$!NKF#_ETDpu{^cJZ4kC&wJ&BaFj|kx}=qANg&@F3t=uf#dNM!mp@F z1uqU$)lh|Bvy&CBG|{r_2jD`J0tm?{HsO6|rC zN*ary5rlf)UVFAAxDs_QD@h%$OF}S@7TK?u!!Gnn1`gvNxujjb>N7coNrA#YaNPJA z3~LrB<7IX(Az5r$hYAJ9t(OI;u@{DV=vi{#ezNDlp@@}V`8x~6;fZc$*M1D8wUHc) zga@IIMo;dPyL@kDAzmyp04hJ8$>G0jR1y(KWcZeT90_Ef)Ry>{j+GJbv1 z{_t?#?6@~x->ld<-?SUywKf^fJp{hB^4e-8UG&=|{1pDwve|q6u#6Tc)~Z)p-AH2W z`@vj;z3?2Qeuh0rF-{J^8_SrUx7 zLdOH2dxBv6a{}KUUxvDkRY1U=qb5tbkcQ2suymxdtisY(OJAtd8&`wJ^$+&a(_Vm! zP^a>uj56fb$!_<=|D0hi3@Y)H9#$yfl#58K`_&q2$3{)&;tlLNn%`B0ihnd5Sy%V- zzJ9>BKx4?)QT4P1Jv$Nj;)6Ev6Va403li9%!_#BSf#}rOxHt;fm3w~-SYV(N#PlUP zjQ*OdN@_hJkEpfGVO34r@Yr<(XUZ`!Q8l8WsR2D< zU_=GgZM0M)k}l~~#90+c51~p>h{6@Hii>=Oya|U#L{P0qeBF_w!wf}je%(|KxIRpN z+0Jt?ua~o&$cj@R?J4*>YaSreC1Qe(zm%X!&!lX*V5+><@zKszz{`IN3pP(>;M#h$ zNiC25$8WJ;w3rG!?2j|bD{aphVu=|a-Sjp1YNjr`_Qs$8T8%VW;;-C&%z<;Ho3^Al z{V>J!J++5QE>L$?TkVw0Z5YR|2XTF8ov=m;FY=6<@*YeaEaos%JAPL2iP>bfsM3>6t$;OjK;^w_`-q9tI^PR#m z$lcd2O}{pZ=3%tKmx&uXdhj&4lNGGZLdfLC2pdX*t0M^K~O(t*l4nUtLWxgQV>2 zejN?zmSRwrgsHQqa0F}puTdJtH25*UVbu}|#OBv>CZnq&LoA;>rID4{9cWX}H^{-_5ZOx}+c`wxU1 z0{;Qu=O}YDnb*IDJeYljTEm4S^Al{6xJ#0JMdZaJUtY|P)(?10&pK3bZfxJ6lSdDR z7SVaCpz){D_H4p>GT*yQE93gTWf_qtFf9t%j9!`8+*WNP$v1p!z_(6uce;M>tMa#T zfjU`tI|@{zLD8Q(+VRe+1ov^Th`|nz9J6%uJW~Xz`*`~#eJ?Y{W~W;A=?(Awq_*WP z|2i_41B}5JB5s015J5bcJcdh`hC6SI%67( z?jM?TgI?A^e-U6H6z~?){@G%OwrRtk4hAN~0Fb+|J3oBDGxDaG5^T+luR-1L-Sb6& zNe~Elq1w2fy#GN&wm-)ELX=vB9PPUq1lRI!l<9xIc)+&&07xKw(^!os|6`YTFz$NN z(B!VW$ypI4d~;z5B~Ksw&;9_^wA}^8#mD#xHBh}uXEgm|U959Yk%tXOB#c-3bmu9@ z_VOUpg|MT=xOh{ZGL_kcLq8ie)~i0fmj<$z*MR zZmat|z>H|?2f?a2i53q4umX`MZG_cfqHOHKgAWhh>t3hNr0RMggO(ob6$A;Fdze7R z=e2tV?0=^AAUs3jV0T6(ZEfB-B_*BN59V4R>G61is6v48Yqt7$?%?G-B_whH7%8~n zo}RqNN)Eu*CIG}{C|k-)ML_HjX?7Z|@PUg8PtHocp}855=oRTy{?v>GUtul=9zpor z582Gj`hX^{_rG7Ns$6>1($a>RjQl-597Z6MET1gPJIx=6Ro3-htLwMXK7xajAkvt> z^#(1j`#>c?FY?Ni1U?`qkr`6|s%zaIXW&SKqWwZMQ7^zC7zp_9 z_N^fF#_taazgRx=df!V~t#@??UK$CI?i}BDh1?SHCMsH@Q?eO=V*lpbrqgB(b+S-ncJ!~LfvfRnvH5gi z81-zX-lMto-vT^_6%T(ZdxmxvDxM?*xBM77tns|{KJZXgVNoZ{&@DbbJ|(h*<;1Dw z8T*jw(9X>*nd$w8PzsYp$`A7y-Tld21&+jGRnTv<1D3&SteoF(Iy}V9;kG5Co15@M zRR)7$czJ(n@v!N>%qOaMqV&SWiAN{_84egSwG1PXc@(VS?8C03{!?;?nO%eHq-1*e1zhWVx zKTJms(aV@)XW~lF-qDw)u&JA89x42cb7h*N(1TON$>Y9^fyI``50C)mk*C^x)=D5}mld#rTv)=9v@f8*o78xb5 z%A3Rjh;~a=%bX*Yb;N|kKdW0|zITN@1FQEg(*Z<&e*TuXr<2Ex`>r86;VXm`_3-8EExdm8W9$2`DcNl16oIH~g}oeR<2PC^O0bobCQerxHSl7jrsw9ydj}NU`E#WiXzZE(c`?GQv)k3^4mYCn#Sb}=`Uea7 zKH(pV3`?M`5ACJr_W2y-Ofdik&cCuEFfe`eHbp5Gh&B`q+N0x{^HOWkU@v1b*uiJd zz4i?y8DFONo5%O`x1bP^QAcbB$uF<10SvQ4Do$t^i0r7@i1dmTGsXOpI3zy(Z-wQ* zkk_TCPj$?l*!SI{r6lM)y>;kXpK8yr!!_vGpZnulU=k7`PqqCoa&_wrq2=H2rWps~ z6A=Y|p$K*@nt1op&1vnDp#3d?{V23Gz%r%o-Eee&Lh73dLS1)`?~@69 z7oMC6NrdPQe0gUW-me2 z*C(L{wktjthZh&e>iiWe)vu@=!e2sYf)S&8<31q@?`^Z_C@t+u{?UP1sey-^laFKc z?u~y1sP|z?#MdSch|0y3j)VA&K z--jE(dOP@&p5AJqZ+XrFh%0&XZ-V*O-1Z11M=NZFy=z~H=C4$$vQOPbqRplV?we-I zay*VJ!6$IU_1~Ds(wO&_xa}h8)RBq#L+ie1s>kj%|vrCDtGuwY@CeL|-zlRenh48;Pibgu`FdMk*sn}W;+&e} z=r;`U1*)wQY>f-5LefU7fHaPsk;pouRcuOR1CL55ij$LUbXvD{`^`dAwP%gX_7zQo zN}JHl4dmM9l$X2( z>74k(P==h$H-f{8Id!jf7NKkiuf*6&2;r${q?OoBb!{gmNm#oqOR~sb4~M7^y=;{9 z9g;;1fv62sQLD*$`$fR^)q~n&t_l9vRd)N-Qay(6$VMjO_woauHOHVFZx3+}I4J%? zf%F@bs=XXb8e22Z+C4AVo&2AhksixMyrxUio!?>Z-A+^-i<}@(3)Q+~bpvCU;t>fi zdqYd!FHwT8YqNfbA!Pfd*^axXZc~MJ(s+1=?igr-Hy`|;pNx!?-BCmyuX2G;1cxcD z+Wfq#^<}$Dz~?k-sO71XtXPlvDs2qXPlYC;@t&6L^hn#e&iVM_@!k{M8uQs^NAAUa z_3Y*0uKJ}b+KmD>|9K726ebXGS~?HlX#WOm%B21`YRZCFl3kZ!tUsm>65iZ3W%=6= zevI%Cj7_TvBe)iQPGdHnZ0>$V$s#1G&=f5CT90hpcat%|^tN#sDgQitZPab59h0SC zv$BF+P1G%AzgT;!kz$l4bCqFh(ybDxyvvp(h-m#86T7 zsBCCz0tdW)la`jgxx6$`6TGMN@Y69XT)PPPaP6GwKoSsrvnOmi#A2T@UEd&`E zd3tTF|IeSkj#2>UV8$az9=_A~Kbp?@JFfQa;%$@0jcqly zZCj1e*tTuEv6H50JhAOeY^Sm9|emZ2|3 zjVuNPED>4 z+RSDR3qfKHJH%?gDV?};@Mr)n>wpZ4Mo$c7&JID5$URJ~}SZi-ns=Ll+ z4{SO9+h5o2*I8P&{Y1`+-l!PpVxnBebo~vnSp)yGJ4C^i!_DvRJg(5^Y`x+ z8kIYLohK>GXhE338x?+tItf{8aL}2JgKdV@84()s6kwK$K&E|1SrOV#K@^q^ni8eP zD|iDO-Mg(na{bP~-V>dg8`&hq4pp04cx3k^lB_xK7Ljp>Njfj3U7ct*hN?(#qYp`ys)8CC6Y+2c?_!2H5x&nS1z+qr=!KW=s~bf&N5-Lii4>ti zD>tP??WYSpkd$BhElK~$5Vk$a+=!D*DZ8LxHKc%gwy&Eqd4h>!CO)B&8qUCT$f-XB zEMw}BL$l|Uk<6JBw5u*vrh-B*DB7?y%d{DF%kCw@;OvJ` zDbiG6i<5*Ruq@QjTg<7>rjNhN1rH|GQd23-H8X1+Vv_WrAm>qc6$p*N^iz{-Lr1mc*K%ryoB(-+qie z(X99SI^vS{XZPnS2e1rsamh~CUm0Lk6dcW6U;Tz8?2(^pSr@|I5TX2iiMis5K%?{E zQK$30K~ld6?KW!a*0KQW#Bxxz&mEmgw$@@>_mqb$#l$9l2Kbh*xy?|#V`U=xJ9o-B0GaY+ln38q>}*k38%1b^+idoB$NG>YnFC}j33R`Ys_ z)E;69X-MR4@BNvhLEdq4r0@O>nP>i3gLdzlz50Rw$XZ1=891vKJMUX|{a=&Yx|FDY zxNv06%V>`EF7YRAy#o`fG>i%&yiLrstEklHeO_tmgR=?0iR6cr${C0qr8j_vOCM zX8>;FX|l;_MBLnYZDm)e?eQEEiQfZy(f26N;m?oOHr`NEoxvAEZ0;sx%s_jN$GDR^ zzdo+=CK=m!+27uf5&FH!uyK5$BH@RNn<-yOBg_=2_x)Nr5Ig zTutx6kF7%RTR^*Mz4J@*KYsX4X%zL$jNg;w%--KexccFPQ=syUCtF+Cng*oHSc;99 z*pyA}1;%dPf@+fr=EH=UCd{eGz@_N8=a?p&ri4(vkYE>XAEiIm`t3 zCE)_+j^rSSm%8kU0Jp@>QCXgmgTp7VyEHlK^PH+835*Y!{MR!th7u=fEE#b<*HPeo z;Krk!C2p;wTH`sEwLsKlmxEN}@a{8#H*|75EU)lBus!YgahuHPaHPXPwmKt>Y+KV% z^)wD4`bQnJk)Y4nS3**9*lb7BZG1_Kl-uExS~g3)*?o=O8GuiQ9N2-ZG9brDUrIAE zF$vLPHJ@JRU0q8{?Tx-J3r(^h?`4_Q1-rs3Srk(rgG!a?>bowG^>Qld^qJzt;rGcv zKQ}wy{tY@yyyGu>MHn>?4i0hqcqFKF3IRHovmPQ6;??WTs#cu|q4U8cN%G{@OC}Hx z)6s$d_Dw5|K4UB!u#O%b6*e?P`o2KR*=VSd2U_NoB{}*GQ6lI@?Xi4YMvul~_-VgM z{3K%d=Y+6_F{^Glfk5QbB~iCL}Tf zwmrd!MA7b+X-@_Al58Mwq&|MY$O5fEnvXF0aP^BaS#WrM%5TwSgvw1eV`Pd&JOUM0 z{FEGzJ=k7a{9M)VIg>LhE0GJC>5W~(Q6;j}>9h#(F||NJtnMN^fMDfEkr?@GR&Pp& zwC6NJuH3#>Q~`k+i5_?%XZzQx)6tNxZ?1UHFQUZ8hmlD>mnV`xs1rxuJ0u#-g89eX z2^mKKg(G{WvYyM1u}vpthMsq!wt!2vBVbZEcIciFY(hwTEyndGb!Aus5E4N zyh6=;$X&ME3Wb-qIcaDyQ--;NLqMQtIE-)jva=WW(LYvAkOxMi%B;^EyFIV6sN9zN zo9LCtPR8PKM|D|SA9QX;m|EPVI7$a$7GMs?r27?rLA2hZj_g6MYKep8W-2wQm;l zUUdYV?!t+o>|0*p&eyD@Hq-Uos3D-A9jsMsV9CNImzYG>*+znHtTx=*(+ z5^zcj4$S4@!*vQd&-%t$YaNXF$Bcwz&?RwpQQ_kHTDb(oecX_#D<%dWwCuliw z*#)?N4$uE|72lM{I)O~n!!5|hnIO~b-|a&sR94YDZ<&qGz9AHw)dGLy374QIoB#gH zB7WQWfvaEpKHP2Xm80X!SyL&IhX)vGP?FN9(KZ^m+qSl~Ns}i*b~5^aXN8erx`%Oh z9aYNFYdu6l45$+2`5Pq#h?>uv))7jXEv5RhJqKMlvRjP{=C1 zYI1+;U#vNP*Hs9bGq3vvX1ilM15#yQH6kLCeJ)ihw_zV{oK^>-Wl0S^Z(%5&Wvw){ z6q-e#E#+lB!m%QsmZWwvd?GRDjV7oZA5uDFn4RTi96q^zjMmga{8v7%YYAWeWZKKQDmH9*gi+ zQE|UICc# zt@9ny7o8qN?>0=?T%TPJJoq}DQqs$>JoZ+ash)K{C+> z=1cW+-M8?^oY@Sco=X*|7oDXzdu6Tz*k?IF^NsE!KcwM>VSzFI0FU znTiZMGsfcNi}8UFF10U}kio^3cd|rtT(8M&f8qQqeCX;O)R28g8ErPsrW&7l z8ccfqpo{R+_4@PgGM}bC7hs}rNzZM} z4&)v%`qOWIh*T0SY%Oq3vCE3y!UCHTVDFCz=6!xK-+UN0$r?8EBGn(Tr&Y<85o++c z&4gfKAVz0vV0Q*eGix0-eC%FE9-g*d1T7RWv&i1|M|~=bY@w_*s(X-p2)zzT`XH2H z{XAaIeBQ(S_gM2jp!dO9@j9-hf3l}eTL~5ocO&trxlFZjvz|sZI)ic|I?fkX;&51( zT8t^(H%wJ*1TQxP$u8N9i?|!tJvq(oxs#{Y01K=?1*QGUcuBhMsOCFUS)QYMhX>!y zDeKdbVpH7{Xcn*y{Q9_dZa!~40oHLo&$D@E59jOSd4hSO;fTy!T#tX+_ZJozGIh+i zUN)2&U!y}w;W5V#_Ot8@o0_7Hrn^%^O_LP4>rdcnE*je9?QPcq71m90n2cE>87lF=;?Ut%Y zsydsqr_LI>f#==Ddix83`wKy07wnm}H4$fL+NuMmttnxr78I{G^O=N^pCbwL6>%iV zam*aKeGlva3y;)HE8FR~{B=Jud?Yq*=LwP0h6|-~Th`#62l^#ids)lzbTsvOPM$K- zWz=Xs%JcTtg_(^{s(eStqV-8c+9e+c_gV0?!!x`1hwsIQz=4)k_4#p!x7U5_vboT` zIQnOlH6af1{@=_JH?k=n_B#_3it-4Yk<)8g&HdkZzE}Wdl}bQocvwz`Vc7BmK(x)x zJ+G?j$UV#6BswTRCY;*5+d!zs@-&?^Xg@rv`csy>=hK;Ii;s~xF}&vKtXc0veUj%B z#NUSK@NWq+zS=)?cehB_35Zmx3}QWvd`7Cg-BveIK!&PioFZN1&nno%Qo%yW`Z&w0 ziGwzo>QwnAGBc{2al<6>P($wjIfjsB<3UFNmfGUqFW!lAVOWj zzlkLR$CANTb@nMqZ}t9iD>$CX{ahE5Q9A(0o?xM7*Mbx!g;f!d9_p+HL=<8ak6teP zb>(6-%2Q|on{*C%U;9XyB9(um8Rw(i@Qdx(LYmm4@Xy!ZK-OuLIAp6gn$c`zN1Sv9 z1t?O7DzIb2owJr_(K*2zOx6Cl4h{_>pb?0Zqr$3+mdGDBEJ$Dygl%a~t*!8zIwxLn%Y)kerC#1|UH7blb_zE=kU<;xQ zoOZwpB&UT=RgTi2HHWFNbp%YK?Z(9B|H!9YnnOm6~H%;j6cc8`F9oZ4?SYZv!DC1tuF zg9xO&JU48a@~_0?$xcT{3=SS9*+7j@0a?85kQKfm6mogW*wwV7(-U1|z}Fjd)f+Z% zH=ClP#mkNeliq>EDF!Rj_>D zf`9V-(EF9iLr@^R#AEUhw4B2H0v#gfX0P&RjGA~NJ>-2iD)^pZO{jdHAwBHK^-|H}=1AbOd0m*Ck!4)OpK^%Ca$KZ93 zpndPyx@8x9E+i94^z3tA{gEco(X)JzH_?a0FV`!7xdr~n01~x|JDy!nTZf7tw~8&t ze=3@R&*MTr4lt=w8pp?5E{=14fCRodTWS;3i-P`b(wUOq*f{ z8+|$eN8(lh;q?o{ye{`*pVUkG6r&Y^)iQ4-k)( zXcNKiPA0cp0RBN}g~|P1mu8;SIqX20%H?v773}Ep5BtJvk=OJ5>7ac64+0VrtJf(p zn6EzftnL2h@p)p&O+DLxdO%EU=kf3}aLmcg;+c=^4E)uvg$W(%NkmaCT+S3|P+0KF z(b@1M1B3|yM!V(FK+z%?8$LnuybH6ZYjM7}TVr66(WrW&L)nQuyVdTxPG!oMqM|8f znaDu*^9s)&x_U}DVK~VVpMvw1HK&E9*Gl@EUL2)5kj;@M^w{B&x3!9{DVCmR-w?9Z zYD5+xF8&Tu5tA9f6U*}IuFF& z(+?D+V9uZ_qoYa`Bs9(uhkTbGbvjX>fs0O7$#)?SNm*(PHPtFsu`HxATF)@Avs=e~ zC5}+t5p6dk#=WD^pIwx(wDTKkqjLGWb67k5jp(UEu;X3U;C1Jyt@r3_H~od@W=AfT zNn0D-0q`T%JA;J>;|O|^W*}1|Ej@p=Kz$qjJ#R&xgqf3Lxev~fq}XE-@QW$mAy33~ z!D<~gbE0A_7Em6{`kORna)?LxZ@88@+a@z5t3bCJ4N3rxpv+K5%%V6BN1p(C#&Q>F z5!lQsS1y!up8T?6iUjS{FvT8K#-S%hwV60`LqS8~aD(z*{M`hB9SLQIjLL&g?q*Hu z{8;+0a|d>Q?0WhvT@G2tKOwd{CaluH+e|WEKEdI8WQegot(kp;%F>LHlT(x!i}V)z z5z(QUO?%AZ?cve64TKkH(9xzCbm^P7qZaBy(^F?EOSSm(;k=q2&b4k zz=G{g#uAsVX=0_z&%IJj4BZQOsAW`>#YW52a>?O*d#CagB!_AS)4tc(4&6E^%4hZj zg3Opu;8qXaIu*XN6~3SdJJv_0#0HzW9qIiBeOug59GS)*1Y3 zl018;P=vWy$WQ|F62WAW@wL`N9ED8z_72Fj=OT=$QTT-1G94RC+{~G<_dIL#N80K-oBXcvmmMVrh1WN?B)nLbKFu8b=(6pFCY zKpnl0Vve>0L)qt>6;|*L#KjZ+r~g(Qe%D~Zz?2ZFre$Haaf8~3u8-c$n>M0%y)}`j zKFN58?d5}dvjJQIhcVl~dM&t&w=JhpW0xoIBl+LchT!QRcR$`?-=D!BsEig)M|_ju}1MWbS&9`%R0~80usa3%&5e-2aIPTO@PqbleAli7dezD$%Ba5ZXu$Y*}=6BQV zDAp*{_{%eA;@`A+b{V6!vbX1iGwq6=;!w+n4AVxHZqYpC^t0~`-49%m%}veB%+|xT zdJXSv{c44PcX$7fmR0}fSpz>d1Y{^5>4Jv+sck^`W)DdzoPW!bqHtUfLHuF>3UZyv zV5<*%Q64Rtz6CIY9)Xlb(!YTbO+*HM(Gh0%7{8Kz!YsMOJiA9{(&xt9p_1(l>dq|nJeL6=KG5_cF8~uPF>#!4r$mRqdL zHd=klU?4CQw_2Z)1)sP+JPrgebJ{wGmX??os`O-g$fb_O20}TdG3|qu>;xX2GDK=$Rjkgw{^pMYCC|NsPQwZhe71JRIKkBx%tN6Pqb% zDuYL14Vp<}CbO8f$^2$fw2i~jRvj%0E#ZitB}ZX-+^M}a5hO+$X(}BTuQ;tY%sRC= zFblRTsGybXmH#>LfUHW8E(G*5s0&Mle|3gBJUTHRs_HvkZ}@6rO=V3pvd^d;6-5d# zt!&0Pi20)snAA}s)uM=Ds4*xV(WF_He+j3jwTQw=BZn{>3#`-5DliT~UWfV#6_Z-c zU&}6qeCYKiGl{BTpoR%dNUTHp4gPI0)hZp+%ly-9!XjS3oUfVPeZ$vB+aw~BDou59 zc>Fz?@t5Im+o4paDrKbsD@e2yGn{HK8fkQKN{E|<`p>(|>aC#?7SK%6Bq(VZvJI=X z$NRpr(^ZBL^XFi81VP*K7G%scY8_5tmo$Ph7(AuQ9+yb#Wa7;)AQn4(WY#c4 zsvZw_{rRw;!*{s^vF7q7pY6ThGOooIp7(yZ;gSE9gJr$xQORGk0%1C{?8eTR|g+&vyXvbS5Dorz6bu-yz3_( zFPoH$wKrRamRnTJah-0Abb}uIu8$_q4{yQl7rPgFyN)N!4X3*-;G8g>U7+-Mc-iPP zc#j9ydYxG<{MGGiu`<1I88SyLpY90wmuE9s7>d z3*QTGvrE4}8P1R${Gt*IgrQ|F$Yde;nshVM(>*!vemSnz>MYz^%)wfg_j~)Ej4K89 zwh4a?MqR-|bI&Cyk7LFpihneCEd?rd25?xRP*^)o_K75G325M6!{567XET4u;+DDR zRI3EMcLxjVK6LnZKD;!@5GRk2r`e)~6$mi9Wfw_G{#G9?RAES-G^;5VCr#{j)kA?K zk--@`I&G;>Of&k!CGJ=ka^NXK9ctVrrcCZKJ{j>?fFDM}&)@OSiJQaTFHnx7Z*}t? zv%~I8+i?&l8XN!6$mSF|)hKai&JpmL4;aVu3s>&5GBJs1D27%0K3!k|)MrnD zO!^w-uEkuAM!F$1Gil#LvgBC2C-Luz)`l8w+klGMdixKQ&WE=Pr|qu?%v?++LL#q9 zmfx!zeF`e!6$bM3U;<57|G@{7&r&xET+*kUB#rOY4zu#0)Ed6+@?DJ^qQfoTk8laR z<-o3QW}wKt@F=AzX&dn(cJOxq!|Q>!BXq~p2M?j3bxAEfz<0STrEeP;jBUHy@FgqM z{96b*+Q$&;1d?Os&??%bSrfGm)1-CF_>>CS5w!7i-(Xf7SF&_g-5l1%){L{Zj;%LL z_|i!cw{Q6V%xC^qx3(x5*cpKL+{LI)Z}8e>9Nw18S7)tGm(Ty%>cE{SVc}jd zsZq-^fG@M$gvIQnKOGp{ zW|uR_wkZ^4&J`$TI^Q6ah>KwnaEs}-4*CSPPjX16(*%V8ZF80C zEH-tfNuVMs(ijmQCjz-t3fT65NfCEG3*_361*sOD{F<|A>ydn8RAGR{W1abaN5xl; zdRjcQn4W+HD&9&9HChf!s; z(i&XcF#0Q8R79Kx!s{kLyZP-QYXM6u@ZrKM``Lx}7kK!^7*T(i3pAN+Un(F!z%Hn) z<5a%tuNM$iYM_RU1R|G0(Wo8qP%XFQtQzPGphAdD!3nuVLU8N}Jpgnr8J1;q6_`>A z$|GtQR{L#I9{3IbmIMf4gTsjs!2W(}lQ-a`HRTVx+u53QgSMUj!+twUA42Sp!!z*5 zM!lloq7VD#jlf3>Si$Gk*uNP;le$#V=*API%wWQz6$bUq=gKsV-1#rl6}UUTsvoBElEi&0!NlaDUeSYV+~%!Z%3NJ5Gsq z5gP|@yHUpuVyhFnbE3ii#n$J7Q$u~tWmX<2LEN~ja(CQI)o?ngY;u}lU&O|nrmbm( zdqekvp2!CP-74i`8t$AAYi|UTx=mq5wMJnbD!-JPJ$_TK_Bb#??@>0HIwYCDno?fM zhRL7(F;b{fH6Gl|g`H!k;FTRPM40e;Ybn2;E3sCmE6>}o?3DTZY#cAB+YGc4`JP|) zOoL8ZHPcF5(Ur^RYv{x(wb4Xi)GM|6*0${siMRt7qRi^0kspDMYejn`Wpt(=f0XFb z$~CMWI~9x30UZU&_n*5|8Jf*zEyR$cvi9uk>{u-4djIi{3N8RbvD#=`bUr^2wHNJi z7Mjjty+CIM#+}NL6Nw=Z99@c(ZnWF%YdOdUW~<2t`!;Nhlwa&~LwnU-+2Q_AR7f92 z{4F-Q7_{m?r7cH!QkUsMK8vlCDnBf>J&4onk;12EQ`^9!h$nVlM^*I45ww90UcP`5 z8e`Eh(-K6i3s^HiT*gPJVc}t(etl+2N!>_?r-%E&U2mT|pDG!XWr}g|vB_axxdfDl zdiFqjQDzxGsY`kq>F6lOdSy4GQ*nM8ZF(Kz?`*xJoVR^&TNNm3ko3JSbE`9)8I3qd z{MA~kn9bqec@!fs&?-ii-bDe?<$&D-gs3nI*t7?I5yPevxzfmrg>+`r=E;+&zX&o- z^rsb9H!aRpkBHL)GVoU%$F%fe%-655 z{;xU!FXRu2zW>pai1rSp-YubH|~ICS+pNUZ;c=9wZ@^bTLVy9AMw1`sa;;LDaQUTvUonOuDtEc*lO1$dl~n%}KgX0ygju<`JQ z8oycRNSC3AFmbbsQy9;&Lj9B}Wa_OY062;SPjr&;vGo@3$V(hLP3ML^uZF!;EP88+ zfmTO0Y1&1=>8w)To0%%xBU9%&rXICBq+9?i!}`N2b3it&AO#o}jCna`>LLq~E71Wi zC#0~LrB#$1Pv|a>CZ;W{3-$m)Yl1`!rFI+g=iVp`zArkNG>v8*3s8r%5K3>f-00M? zUqqyU$=hbNr}m6%ZsL>1Se=7jIu%?-W@h&1$x0l&Tp)xlTVNjGLLrGQAyw{xk0qN3Nb1r^ccB)g-wxnNu{0qU1-8$=>vo$%t>EWWeXiG1tNxsnmD zJ>{z+7BfbnZRvLzi2wfGV)iKxWMrpK3Zlp~WZ;BYe!Lh-yWQZi4CdxfQF6p;wVCA< z(Il2{UcX%|*for{Ao^f}o0iGC`SH?zXKP=kblBY}=dixUU4J<2USqU}+6tFrv)Y=9 zW#EzKBZ&o%#aP_s9w5~d87ZBs`@!V6sw0bItEowHbT}?BJDvEn$EwKBdvDcs;d^=? ze*taxDT$Tyh(%q0sZriuk*GyCQ_}wlyU{k!D}gXLT&^+LtjK9JxMAD{111m>Fq&g| zBcAOL*mvc^gWDpEY=g{m{d2`gN1D3sw(7I^*K`7&{lj{xbc!ndN0!aJR!>JKlzI&klXc^oc8=(@5FHjijy^8(A{lh^%lSpU^#uyg_1A?e9ob&jl>#_rI{x?+tCId>C0S;Dx_Z|e z=jQ?2m;T586t0Wx`n$e(e(CycoD$w%I_KVKv%cNSZL;T3dB!NrzFjVkrp@;kzK2&Y zzxVFlXGy_#*ksk+opDx!V06bG;Zu4Wy?pxWGFT*_bqd?w2{KZSbL71U!Yk>2UI2Ev zTd|Vn_-{_M+=M0VK6L#7CvMZWO0-umrOYd zGBtD*>hESOtSBfVQU#>notEhg(WA_Ysy>!;E6x6mLz$9hHfy|_o^=Jt1b-lTO3 zz%+a$ZocSU4KVr~-L7xlJ~y23y8AV_^wD4BBukMm(hC}+B&Ol>_+W#rjdbizFX9{s z(xt?Ulcj^G$Pq*{?=E1UE~SGi zK;&_z`z4qzLuPWaF!6iJCFFpY=l73_rMNMG@FQi;nvIPI0ow?IRSU?Hnwp;<=zoL- z)}8eg6%(59#fHj7OdHmqpaK)`S(1OCbe^1%X$v*jFaA(c_O=pp)k|{`&2|!?lZoPA zhz}{uQV)FbPM%Q`d?`%hp0qU#-EOEZcZi86hgOs}I%&b6Q!W@OTvu_vb~PGOzyjDD zdEa8#d-#{5Z57UjtSZ~uR{{sZd;&Bw71AnCSrds}oaMEa#;HqU>>V7ptd0X=Oi+JN znVIKCS|hN$OBKQ<`a8{ExAEU`7=3yzi`)tF%C;AM)MC3CJZY0^Sc9DoyIA%;L$R?9 z9#tWg5bea25)p9OF`3NvgzV(5_I~k}E@73!kc}b4Gkrsg2i|N0$3IRqTa3QN(Muoj zc(A)E{KZPZ||}jAX=m|==1`{YEeaZ#(2Ry`}U_}yx*^3 zxz0n5j}=|dw3ECSd<<=;ERFV?3IciNK0ev?lRVL2pMBP{{r1eya`1Y-x3`l~t7!_h z-9io8UrCw|a_t@WTN`2&Q^sqiQGYh&GR}@ajU2A>h0j%gA9nSY;(hD$_=!89r6JSw z@Y!}?Cg!A5Z++pMOJmkw5#|ecRfA4J-|OCbK`uw -jlTfP5_VCQAGZ~SI{!wl&L zUq1=Q&TwK8Q1yoT!og-oT43GKI()#3!25@N*(Oen2iQs#s@or`lv4qxZ07+9BvAU? z94m{X zL&)A9D;Of!1=EZB<2BmD@Wy$~rLRHPX<9r*))=P1qoJiVA~$K zlt~-)ICpeaAa}EJPN=ndy=fl>MU-jwpF)bHLZ0$v7Z5q3!orB#Z6T?6(QL_vWp zC?A^*D*^920hcnv*9;3lwyf?lFz_3|le0`#;X(LABkfDcWF%jZ3h@FZr%YXVc%HewohI%}tlt+9F`x8`1gp(vVIzzYtkAGsT&* z3UW>xMGU3EDwqku;f#FU7kIE9NNnK^EQ2zKBF|P~C5DEP?h|!D0ZeMm^E3*5yB6qE zo15{NLFFT;B2=>E&yU460k%cum*p-FNv)Y-GwNZg75x#AeEv<2F>m|s5$$)|D z!KQex=4^l-_}kfzU4bl?xP}Jhs(buYBKwSY$?mOvWn!baKvt1C+ECWK9F%eKi6i^JGHF=(tP@mPWa^cRR@WX@AjD<0LkfDWz1VOGWoRe0 z+rlJ>ms(wE@4PSwpu)Z)L4Xp*b6K+hD|3-L>yVgbFH^q%&tGO85)Inl)4{tdk#1b( z#q5DZ*fn@XD6F^*yH?ejGXxMGt8V2f3dAA&#>TzXk$v-LxZ@mjvCzmP#UxbL4J-}X zp%O)bDy{U^oL%M|fB8G=N8InXxEQoEe7=ps$l9Y%`k}H;L6ZxxPv4@X>})V(R?WS-*eUfsA=uj)F2+Hl&NXA7p#(DTKZ{!lQY-x}^g>3l3-Q#=Q5_Q37^}K(QY`KnVQlkIZPoHY{yz#in+8m$Y+?1?uF?_<<5fC}@M|ov1@{DCN8-ygeGaUoIe{-U0eQu`cSh;IhSU0_IgR!8U8+Ha=VrWtR&iCvVB*tT^~e6~ zBLC&qtUp2UUk=*crAC-OB_KMjO~OMgT?Sl62`pkGVlH&cW~fO*kaG{1xw#qs?6Krt zpq0Z=CjJA8s?pc=zS4~?{70-t@9^!&uC<{y9#X6^oQ20H!rL9h+vusCR`z=uE+S8o zu4;dEx+mfqcRz2b2f2p-Y&9L(kB9s%Y zAQT8>e+lQOa$Flv|LJB)vc`BCl%@X;sApb2F+e2@q4%q$u59wSn{qCVBe3BnrjMRR z6HkgvGuLjMt+ib(oxY7AEkYHse)jUlCdd+#lIKa~p)Oxz>iDUnR5f>aJU+V!MCb9E zW|lJsYW0f0e-lCnbR5`}(xdruH9R^!u5fPW{n~?Wl>75FIqXcrJ2?T_O6|cLQL6^H zaw4 zCNv_GV#k!h?k4y!l#Vvg)L&yIg3am!57>7h4Go3-qjRQ6s(YPneYK_h(X_DU-g*vhA4~~yROnJaBTc&aRkjyUE3_0_&qY0)?iW@ogP9C*Ar1Kk*Va6=$`B((PO9Dy_fT(NqciFV9R)safFL$ls3qd9{Lzky5 zbo!u>jSV}SMGCd3SiIbWr-M8QL&JewU)Cii%TZ}gl!-h+k419<*CDbG<#W%xk2Uj- z`1SWI^MDg!aYJ*x$K5O>Q^sR zZQ|keJ|w{A5WQCQNdf?@$FWcbA1i_m19%L3{gJ3?H8uFcbbnYOluL1J9j~dm$iVVl zF?@@M>bWkj-KbsaB$wC4_vv|;xU($Ad;&?O2eC1E*j=aNuC$U0dGpmq0q56*nkX>91nd6`pOL-GdHtzi8cv> zyiCgpg;u>6!BZ7mU+|k64O$@=JB3V%w1Qk53W-*y4>u6*7l#??{d(iEQ*Q17w8VHW z^4b@Y<(b>~pboh$x4nD>0OBJHf=F8c^*|0}9hcYFz$^pY{ax;IHI z0wpG#F;5F7w^3l><_^TD z{oOu9cd)uVq>5QAp`M|o$>mIw3_~m^AFbB^aI@46Q^6VIkSvXSuJRgNZGQc;ShwAB zcZy4`0*4|=agqWNk|mWaQwq${JgJi~fygrAA;JM!a;T7jZZ?3=NK37F1+6;`XnG(3 z;wPagm`^^?PdfRL2Mjua?nDrJo$gVJTY?; z#bQ#mVwV!_z6U;#1UV`uuUk7+kXi6@Jr*eg}~l9T-GKAzWNcmK%+UMBmn# zkx3OI;vLW!WGv}qnV7ZAEYy)yw1M9ue!2c7a&DZujUq=5#ZtUd{X4L`RrroP1Nc&m z(Ro;kwIBX?KqO3*ax=Sq0Sv7K>F=F(VPWCR?hYYEl8Dn593y*9kow6~5e_PrfPzVt zE=!RwsXh1S2i&^eW3FO{dY^oAb5%5E-NdN4a)l~y+|@6w@$Y||p(cb+0&FBdmx$mt zIAuxOUs(HnP2Mnb31mWm1r)BEOJ6}ki6shVf+?C$=#9xn7L%l2FX2)LP9FMbB;&-3 z!?U}KC~4(Y(@>W@RcQ4G6u)Pa)L;4WFhsGx)^fJ~$irxY010=NcV|GER&HXPZ8(>J zJ}+M-{C>lwk1P2;$5Xy9H&AOgSU3$AYMtfIK1+D(A+!nSVa@ss;)wY3_Cg;Gtvvvd z&oMviMjNrD%2+HR72GfOnuDG7891lP%Sp|%Yh%tCjLYGBBU~s3wk~bL%)y2p9uXV4 zb~8ul%Kyy(XeW!+<}Lt4&TS%qLA^?=cBQ1N>!m;Ft8?e&6a>=QN4!hde&yrrLZa!C&$I zMf83fjxH;n>vJqEaQ)IXMke^N_rYlG=arM`dblOb(Q(P$wJR z0v8kb<|=Y>@(j5;haQnQ0=$wVPc}UHR_|5--$x9;58jp6=twNks$Z)2W{mY(AC?py zNi?Rs1r#cVM!QwXV)7@EG+G090lZw_Y!?<;{|_6h22%bUJ%AvZSzGJt5opg4KxHy? z-?4Kz%naON22>UKzrhR+#?5LS5@(Io`G0(7ZNZWWSV)Wt`A%P28U-kBdiHEr{EFnd zi%iTSNm3M#{geWeuPx34!`q@jZ>*l$NhhKRwcpc{m%jT^Npn@`ZmaEx5p6+(-Zty5 zAqHe;BD*%G9ZQj;6I)hp^S?W+lgMjjz%7_KnZ@?cgeKIs4YbR(*RK?>6`Tu0awiaAJ)j1X_5so{rf}I~l{2|U<#6C4ij(F@l@qjUJZ3u&ga0sshP8^ z(Gcp_y)dCRt1zKMBBw4^)g65y-Q~*ccDYH1=aqX}!dhJNxX*1h)9FZr@J93Ahilh^7(&fQ} z=)H>Ni|*Cp$Osk9H)MUktLbuAi*)`Af@9~9=k)S?m3tFsuSlkk$6Pi|Vz+olLz=t# zYsLTmCtImKZ{&u~i^XauyK-Nj_nxDGano^KHp}Kg+kkDsFwMpGJXRMjN(1`Uy0XRFNIC_TAWP$%(5dW{W2l~ zo^TlD`i!uLgTB6E*Kle7R7GM<+gpD9A8!Xdc(k|Nxgho$YbZIHYr2y?$ zp*T|DBtP-^&ACuXI;E{Qbv9u>ZE|a9R#+JCILv-`0>_?^>s1e4OSnjc3=7=8?_HX? ziHHDDlV-;fLszseNPIx~tzxYIvn9N+=A-d?tM|p_r3RZ?6+l`i>jUC)@vE=%kDI#+Tc#y#f0sBi&brDB8Yo`bM-Cc9}w5^nEmP=FcW}}bs&vgTr;`yint;fO2Fo15Y3Z?%y%;MO1!1InhYY-r>$pfkW+q2YAjX9eH z{+HtH%u2TB$TCWMT$sR90d`>CnHbSv=gDj`LHTkd|HYPn;UhR5-D0X1{#dcE-M2b zYex<)?mXd+ft#$qF9q8yhuoJj(m3_AtMQ1hj^^cSH0VenjS0w! zF#nSRNcJX(XwfRRb*5U?vzZ1_VUz!TE+R%C$qfDpB5(d;;;&hvMNRZ!(Oiu!>kh;T zpf{bMJ2q{*X!a8XlrgEPC5~Et`DxKS?oRMUgd^34eAby+Ej2^XGty_+@}OJD-`}8W zneob>RaGEe+BR(GRxi!$XGa8Z!!9W)***9}!W{T;k)EddK6(4*RHGBe0_%#)_lm1u zg^|;4PN7Ywc)o0Mc{1X7x?E=fc+yMSS#oXRrhV5%RCJ4prC^Rt2K+f^w59|(9m<|- zHv97s)@;JPqnhug|98QM*rd!6bQ!hP&lV-^`n zDm$6{mM?2|I0{+<=aA2O1`3%ptqAKROBjy$W|0WxfTRcDsV$yFO#mY)FDRINaH_Bw zt+xwBDwZ~l0A7Z+s=U@q@;&05MmX0vv3`}u*W6e%P_tOJJ-OhkT>C*Y#%`|XqPu3H zdG;0K?|XO#_S#HJeMt`)ZH|hwVO-Ph!Aus*n|xl@cIdpX9#ozr{f0KKWggnun5*og z_CZv~&F|i05)+Gj;K`&<-=~80Co7qMOax*!ye>Cf`i5S)JGp^rZNAqu33~O*;wH|)A5gsEgkTtW#(Q-Woq1vJJ_6rn5V4prnM8m-|TmLHd+qf6< z{9R>c(v|i6o$~98zke^{H9WtA6E1!nFnjsqa~lbDXuS+9!Ex{oDA>yx zz(K~!%9ZCyq{&g!K%^)(V(S|&^#+ARG#)?QXNY)WAGaOq+@Yb)xA_Xv($bbGjE{d_ zi+|pi-(xYm-S%vknv6jI-7YQPbo}JIcSvH^Gr&tsE;dxqbDqJLc6%EVzsJhap?NS@ z6{A!fJQEFtVgq2_-t{h8mDB+R=CDn@xiot{Y~J-*69Ryc%WT(2y_(rmUwgE_XId>p zUzAWVZWo;=al>_g9sjKkfMm6~^thac3$~_-bX?j4)6U*Wbw}gPv>jrK?4GeTw%RwA zT=a}a?!97>*o9ve!ld3{RBCJh=j@mArGAMcZqWdnIi9$t7c-soqGF&GOsn`aL_@>n_%_r$mRE>q}9EZY?NCk`7&8UPTES zJTjy}YiGa!x1pp&i4QhBlcVr3g0?caz_0wbcZU+!GUu|_mZRffz@U`#esZ56=wb&E zxZ^8mu34@h9)V_k6J3SRIHqK}h#hC~iW&3cYpGWmg-o62(o5RG;hSrrS$+hXVooU! zttQ>Txy##C1FW^uj>e+3%hg?vTyBy4t>uG29%G`41~5|Gn!9kjUTelKo=Dm2N-J4W z-N(UU_^nU+w)v&TJCjwy|pn!pL2--7&u`E;z$CUI?8ZPt2=Xj2aAO-&&4M zipU@ejXP1r^0>}kcQq=pS@?e%G=>lDXlnq?t_(Q?>kJS(Yt#uua^yLhiUKTBYnXhn z2(kYh-*$~XdH(&lRbofn)BEnCgd^@d{b0RW6Dw*kHwgAF);{|6{0AvKyzs*{r26Dh6-VGW+%0G>YGb67=Iq1czTESRu)kZr zLRnl8AzDpU7zK+Xt_VR!~ToAQi(@vKdJ={K;1xefTyHt) z!Sks5ZxkYc6WEanOl42Tq~8KAk$^WLbXKe^()#Gw{+FM(C zYQrjz+iVmU2zYp4w{-A%no7LIz#Mz&aM!J>8*tnr@gM{0VMrg|5P~Ws$*8ER*3N)RoCER&Q$LV|91abR~ z(&%AIwVha+(V>Bn=s;nN0LzhfjeW=?HmpiHI!a>t>$>#37D6`Hkp~!T)A}d_lNc!i zv*(+HA=dMy^Yfpv$;E@6Q05_mG3l7&vx~!a#lPqNvdLpZe*$O%H3@%GCFY~Mfn_p@ z_sky03q4B*WF}KZJ$UMBY6~hT#j*_P{PQY0LnFh*MbW=9t}x_T%`GfSgwA6pWq7~i z3D5?s$N^F<{ta>dBv-S=9Dyz*AoDenk?8dj;EQN>E@G9FgI4)Wvs4R5XR5`B8AL_!R%-|) zByql_;F+45D)i-7w7{s6sWo1k5a0@sSg)nyw^0@qbx9{KK zFF9Pv=Keikqvq8QCO~sNN)T3_E!p zD1}%+T%YOh*-h>$sw@=83n2~a0iJ%5Wk@~1`~|@>kl=r|st?JfT2PdQ(D%4_dF93P z%*Q`U_+C*k!1~wFI69pt2b5GT%e(EGf{v99m)hc0Ny9%^eIbsJw-owm%V;u17cKQB zj0UVf_K}HDW8m&EM8!Dd_rnV~;jjRoyrgT|>JNQdOz?7~m|sQNa`+kmh8 zilkq*&@iz%il^qoh|F+>=)k7hX7kR4T4_twz0eCL_v`WH$GSL$rMriqU3I(PP;(<(h1mi#7xB+u?0?kh(hMSE5nF##%U7+)4v_&au!@eNtO z{e`u)%78!Ni??YTK`7tlvp8Qkh+!|>)D!>(_4rV9H9)5iG zlIZcvRrmXc|1jd%?isLnJNg5S(k~%`GN5tz?hQ4Fm{@qdf1_iF6-Z{D#s_A{kqYu~ zas3)Jyy9tpx~!Z8++g_XqQ48{#eI@;8@hqj@Ngy#zbT2%1R(i!+}z}yQwD63$Es@| zeA9YEHfwlmzE3hs(@Ipm!W=AsG4FDkeBzgz4pVmzv@TduXQ=By9(l_$`HRb}oWq#raU*`z)#y zXCeIL;_9j@;1QLfv_z(Ymp{Ef2HYmcfKNr9PN%qFm;54xt24D-h{q)*v;6ajm?cbT zXUV=q$CgJ#gpp;d8ZIc6L1eTf?daIx70@@rM>}BRwdL|3Eb)9j{(-Umx-9|(BKuZa zN@;zGfR}lSPzuUfZFhOI)D%vUx`)Cn5evxn04<{E!5OK(?6Y59^ECB7fB&Cn z>pntAF+3dgZiMY!G_Zt@tcZzN-E?++InG)VyDB3{^za4dPA#rQ|gcFLc&*OF=MN78_Cp9qd6Y5dqy z2gYKiziox1iSY2qt@#2`{aBsyV*@UssnMWE`3zXa*y3#0nYpyv8p7TbH1UpSo`N$y}aN{H2AtX^mZ0S zVDSTKa_3g<2B-PBKFPX{wBtV|`G$~n719?p;A@8pg`Y?`))D=3weij}tTKp8l8Jl8 zyLK_%jba{+)jB-SS?2_3NXUocmtG{KolGisR#H^4$m<1omM>i`j^h_Vp;ZUMLcp4D zb!o8rvJ29Gi%`as`n?k3GGY!<7&8%QWA119aFL0n4u%*+vhdh ziV~~q$-F=2Oli&50yYveWlq5_n=w)|->f$8P&Pe8v+A|@VC@)rQ3qZ(cse~@#WX(W z-v8ODUJB?td{}7-JT~%En00S@I2#n+|55X2%f-#ZgGW?!Xa=tDeexTPn37V$-StuT z$I+3)QR60diYCORpZ=js;^7sL121f8f!Wjzkb5pUyZrJ-WCWk%k7l!)ha^1j#y=(O zi{BWQlvKP+Xc3s25U^)6uE9F2j}|}}W=uRK7t`!fIk#6n^tq}|R%Z~n!BAcRs&>fL z9pcy5iKt9iX8V`H&!op<|96SxT)Mo?MFY(8<%JRQ=Lmq$;0=NUPC#QDn_#&@lO&;c zk_^(t;NPxdT9va*>4P#ROb=AXdlOqoCXt&NHo(1Jr&yD@P}6#~xo-b+tJ!NwowK7= zuL!2?^FK3s3PY4;YRcR4BsU?4vSN*ajO5FY1qs9J-U9q$QMCW+h$#ZktUZo}KNuP1 zy@v5?l z?FFqoRI5S|=qf2{sR&v2y{dnEWG5gG3R93TSzb-si`=kK{?4e7Y=R;#1Qp`p833|D zGIcummo|i>m+;z8AIKQL%*Ob}>Bs@~E#=yOlXP2ykC(2=Yo33B(6A{8fj_mrin=O{ z-7+Wa_*P)ipj4ls&s#D6E=X*ZcQCvGh;I^M$g^absE{%8!Km@^@!dQ<$CsDc|6RUE z587{1*aKuIaiFmR2;vqJ3!FTD9U0+(Fz+4h73;BRz;z-ExY~|OVeI?9d;$-zokzTP zs=d$mtWv+#;SJDzaj2(34(E!N`64CY0HIIgB)%JO=C?G!J{f}UbQ6;bW@?o_l)D$q z0&$4IaNV{?!FEE~Q%ZNwbfA;DP&3AAhIPsYOLR0C367~mngSh@E5MTlg`0_-cSq%y zVe&w&p{g75xMr{Rxoh@}kYmu85k{&WWf4@H6Q7kN(^Cjyyx%L+`!u)w**?=|{nRN$ z6KyI=Jq}(+lf0L+kFAEip>{5cQRG|D6K9ebp;85xzQ1Y(NX-VZ=xs`p7@mUTU z$1U0#Jzb&m5za3xF0L48ln%GEElH&$p2+EO_E$?? zE0aBh3#fzz6DGf}s&=g?cxS)edKE{IQMz(A)2R6#0gqSF z1~1c}`j09ti~}LIs*0H0qnGc2>J4yf=m;Vp4WXx4UIT0Y-SZcN9K#;g90M-^R+dPH9{Is7I;@(fqr2> z=i!ruQNODi&xeWKw91yFa7uLj7LRdJUdtc=u}S9~tn?+zri*ermUm=rGVkev+3Be!Au#YWMHy8Y21|&PLU>(BjcHCd<6hk~n?61_$y-u{O*~aR1*ax_I$B zJ{Aox%?(uXD7DDWu{$1=`WOf+YnUqD(ucK{k8Ea9_~x0VGY68p^=z`ts+N{$`lBnr zsNo*{;TO+1!WJ1|v0?S1kDl)y?QN{(<8q6LM7+$$@B539v$5pba57Y*USoHP7xc4K zpGBSk6f2MjWRPS5IqEeJJ%{KsO&a?#QO}otGRiz0Ia1*0DoZBIre7Z`q^5cM1OgmN zSo?xpf+7)`13*?7@1|V=Z$FM747_2nJGXSsbSZ~N{LszX6nr*ttpcR>ktUQ&%9=d| zT0To6<7~E}pi%y*d&OUbcz65qlEiEJBd2Ag}Z~*6$HX>UnI{n zwAE>H&sK@#cYX-%lr4WPw{^7_2IM^xVIet;1d)^g?RlJH;T8jbNRUL2;w1mD-v8Cu zi@1k(Mr)xq%dT8upqpfAS>gcB}Q z`;YMFOUOJGaP4)}{S?L5R*_n70G}PN>IC&)`~`)LP~`eL5G^)17HTt%#o}#SSnT~{ zs}~#S#NDl}^tC{!aKOwx>O04bDK9O$|NbTLZ(BZ$YK0$G_aDiDNa7Oc)BtJ$wGv*5 zrA5C55@c3ZDS`<~EFvDZ->9N8?DXuvYQ7n6GBRHu_fh1)=LzL|>YG%XOwIf$M2cOI zRHn|86tI2CPAlZz=WC(x#Qm6PG6;-^gpX zn=_Y>lB1&3S=(UY@w zR=ULX!sXfyKqGjm<4WUx>v{d-?4aTKck&LE*%p{%yW*tqAi2hGC+NO$ z`=9Mx?K)rdEmGd&+3IVKVc@|_oBEf&&Y6=|VFqCNji&gHtNQ!LFG~i{$S4)E^2}#}nBemk(f)gHl*-MQ_=O*Fcb8q)b^fIZ}w^qUg{wAJg#&ICIFWdhl~ zze72z62u?~-=C8c7Q>|`()GC@^xnHBZaHn+Pbm|?SuQ!5*Q)pw5&MdN3wuU=J%g(p%Hmk4ocKd{*K4ieF^m;GHmXky8Wae{mlnPQNRcPWts7mDO^# zOJ|G z2}RKe3Z~lJfJ0RFVkemp2GAWvx2a#Q29VJ%clvodd!#PGb{Qp$mT36c^Ytg2$JCYDgmG8(h~ z`+);y>f@3`mHgWsrAZ}?3!0gcQBv9hOlEuY|BFAJFilR@Op)+2Sd`pe33mKWb@T>) zzO;(2jp+H`&3cOwTmlSP7;A2Hw0)qTr0UGm*&RDff46eIvB$g5 zEryAE-UY-d#7mAl$Wzr>H$p|8=S!LIkutG0eyFS%YpxyBj48+iOIog*(=x#lMqdCz zz|maN_*B#t5l0;j7?G*tJQa#d)LI@tMBa+^Hec=o@38IQGYE8W|BpQHc8GJ!f46xb z(J^aWA5!Bc{xH9G%ORxz48uUO+1|J0GIqh*X=I}*>{fWg@2 z3g{vFCwIq-c!h?25)V{f0wKY?b--OjCb;Uy3(UN46j63GeHh8IF{nZ0Vk7e6XU`}1 zv(FTp$)9{56QS(*xaSlurEy7%=KUBbhll6u#i`aCr5_I8JqTck%vJ-L4E!1_0d zIF~8+vT-@XvUHqx8!az91J=7fMK+5P%N%mfgQk3)ib`t%n2g3$^cqoaYE$WNCyLHQ zv)~UYO7w$ia=3us=Z8T@QrTxBEnZ#=9~-EUnoKdcc-~I)A5%1ZaisT}mj>N0jqPw} zXi{+4v!K58US|Liw=6oh*UAM2?7TD@i^i2+J>Df(!e4?UgFIt?WaO(a6MnVvqfH0-$8#3RBrz z+s^?QwDKimB!E${H@_<)BRkvP6CX7wo;FT#Lm?#^WglgVTSJc#hEb+tbJK)`;9~gm z_oXC(?A4FyESt98LCyf->t$ccs>23CB~mi9!Xz1{;y7+Op-%2P8-s3VWTdKq|M*Cm zuNN zeObVGUB6kTkwf%s_wDe9=Wk59Y#4lE{E8r1H+Og9S$F1l%D@cdb6BXR=;IVV*?X@K zbWwPjcBs^LsVhnJG3C?$fYCHBuL!%LXAfaPL#eV=Vd!t1aNIgDEqpo3`>x+|jOCqe z1d;2}{G#|}mTt$oZK>L+*8cPMUCZc_$APMDM4yg*UEtz*UuDz?VZ-ccBo>FeGtJqSyY?FANmbf{3Jfmzn%uC zs^F{%1#6c7s{J&XFpT;io59eKPDTzhuNc346QmSeQS-d^ zGS}}x14<_RXWX<;_~$cKrC(3a5B-*0e|fnKGO_3#g-~Q>e{hlyW1Ar>oSoJ-yS~rB zhXdTxU3I7;C|7*x#DMaxV7R1VE|6Mz7z#_zF*pPI; zj^$D=&Ic}qxA;q(6aEj6S;*52+*SY0aOfI|XP)iWFPAD=wkXMy+JL8By*J&=m7@K) zFja|E!%o68iHT$wHBL^UhIrgAT!w{O$EUqe^zfwq>EBeyDz*c@{fu5w+rO*Pw6HwO zrkvVl^`e7jl-~jlqfZVvLJX$VQ{A8 z>Ba++nGqP5X6{JeQp$XB_`B6=aJkrNtc2f=D6c3Q;n8%8zl50W=@%*o zQ}<4b?0o^~2W#)B$aAYcFps<6OSkVRdm8jT!9i`W&|6ODOhjhU6bzq*K_~`xWb3m@&nc`8?4guo!^Ng+GISJ5-;qqU%9&oI? z0YVpl{+kg3o^Q2*bMxRI<|AUyp&_oOd}!EY8+WAQ-SSU)q#4;iCI*&qj{GW{aFCkT zqWj{f%ZC9@L#F=W)K1_P%8HoKzO z9;y_nslOkyuX*gdOPfs7!h5C^)I^#OO8pH-k0h>IH45^YEbb@8oX?a9|NBMn=?cRp z;{rOSbW33X(jnou;cau7U_nqHvT2u)t!lK=@%$oQ^p0TD)Vx3eSDw2xr#=xF11_-V zo{TN5-M<7|Q;QL)FZ>FFY6dYymrvWEGskV-&}c;Zv{Bb8g=!86X+~SLK{dHW4ChS5 z!lcILGq-YPA(D=PYJdW)3I7zf@6+2JIO(!ME0)f>>V{HS*w?f27~x#Z=yF@Yr2GA$ zCofRN@3O)OfYeRQkB99yZOkS5$3lmr`uCdur27m-r*>^bF;bwA!)itr7)nY@y0u0h zA~mbJmzK!3Y% z6bNl>arz1aR1>wX%G$_+?kQV$+;Ch(%E4kso{jgw4`M?a)aHBW<3DrV)^*R-=k^<| zhJdrF&jB`%Mh1b;nTwQ7XIZwE$~{ZAXc4GFUb{ktg|ucoFTs;(sH|9E=3uH29WD`G zd37VA`QJ3Tk<4(g^3g@z-!yjm&DYwX;&mgAd6f@1fbSxn)gC`21#h%Q(`WVCSuEXL znTXmTk1@}i0#H1Pu716xviBJS=f~!Q9Y1o6as%QoNETF#E*jCk;-JH3gpK+yF5&V1 zEx@BuvbjXX-z+2}AvQled6ULzpj4Hyb282yeM@EthFMkC)w@)I?GyS@Ra8dCW*1dC z_IZ8$k`NiL01ntdauOP+TJ73Lk-~GZ(h$R#=MxKPUHx-a zg*WZ;#S7i8bm?u|x_=0L=YWQj%|5vkQKG)OX&2PNEL*r%Wp!=N4v1{DIuMb<2PuXQ``f#nTwnFrh ztd?#%Gd8t$$A#EWLZM4QQEa+?QVd_gZ?u6*0lh%4FeRT@E>uGbKJyJX9FWU9_43_9 z_r2%_u!mFY*TWZv^vl5Fe)1*P>TV)IpBm;YOeO0tOH27bd@;;DDtghJI(LLFJo;S( z4)sVzEwiar3yJtC=~QIbkb+nic&|oE*I={8b#7Px=sT~oD`Fkr0)Im8BShc)YWnHL z#2l8Ta&^?t*SF4Pk$7POMe9CDarOD%_v&X-@rq3V?QyuKKKt~#)PC-yO1IU{_b~m@ z$MbwxP}RtD`SR^6UFwq^S$gcCysE1fq57*-yYQNZoI%%7@zJV6dG%<cCLH?!FI=i@ADd(#Gk9f#Y`A%^K6h47!5x0>}0!QOFXQ*fSF?!T~@6g-Vr%obt-G(Wxth3(Cm@AAXB)cv1~WSjmn@VYk%aV~ zixzO*t%bX@s^2Q8pSY;ayxO07MOVauF8|YI%Vk9PnvA>Eg1-r3$W$x?1nxo7957mZ zvp*KDhl-p3+$+#UUxRTOqJNeHK1Mo4nF1Q|rz#2a!R=uhA~Ua^9-=Cj%NNCdy=rrl z-}7dsUQcHIC}A$J7E=L*tEiCoyjJ?Uyd-{gBOU5$uAStxOm+mUb0?P^E9roC zgx!qRvoUb>QcAJhangKSr0U_xG&)=be6ar-u!LZ0q;i=cb3DW6 z=GmW*!S=0t)iF&^uN*h0JAB?t>flyvBZVVF!fO)uXM|OkJE@Yu+fXXCAF^gH%@a@Un({%K<)H+@Ty`5mIP%mJ?xzr7w{W4?O6E-|WxTn6 zek3%UJ4NdG0xecXEuYHjR!j=6B* z%6peYr*QDrm_zoQ?yPO~YTW>D($)XwBb&E7zpQv}MJJLkuCJ>sS50#LT+nuM+cFy- z??jkAu;!0Eix)8~G+%crPX5W^+Z}XIgvK13qjx3zwBFiNVvY`@kxa0!=~c6VxlE|w zoAMQX=L%J09b;=Tt_*v3Av`hDuekU5MXorMz{A*hk+q0?iDcg$S_m@1BrnEpZuVhH zRcg$Q*L>4gHPqzfzh6OwXG-R`+UMF<@7OV;P^L{f^l2c}LORTdc0x5JOJN_kYtCWi~t5hKDo!SN0&ty?q70hi`=ft<4~ z^f73ZxKgbcrYt3db@7ryA6eWJINjD-I21wLbF;&Fei!O`^?oRqK96)a<5gEFQfRM2 z2GulO9!49-J;)57?`F@_8d}4EBVHR&O>7?<7w0^0o_=Z>cx74Yknue5i6b2tSs0Jz ziaq?Me0XU)^TVVo94q_3WXqwj*sP_~sgm-yJ$zDh%h>g?eCgJEvEyz02EW*-DB%qu z!xtkxextWY4EmgnHSGklr5rCE%}`&BSx&>4|{n51YcQKPI^5f;=D3v7QAv2K%0K z|Ms)D*JtSsOJ;46dYsl|@>4eE0C=}6z5PygpoTv@{N4EMtb8%J7d zeGoF7%K8J`6iu)E?tF+>J(uH4p;AMDn^YgyyHMz_(DN^~+4P*qP?Rw287gE{ur&zJ$$?#0d#^2Nm01XB!{%tGW zAk!k&ri&!y?y0{*MveP}O!SF7gUO?!eUI16w(Z`dAqAzSc>sMJB+F(fYGpCVTL7%c z&=Ch<9=VR-^iOS?XPLMxoB1xs%3ibyq$CV00mD8s%k=j|C|wjjAZy2JM&UqBYc#a0l4-8c9<_;x$Lq|tEBHXVj^CXs_rBW1{`js8@lY(G(1hi zAEuvgDzq$b$}e5@XImd79yl>A^E?)^rh7DrL_7|P!0@&A9(r2}7#~De88M|Hqxr-F z)>HeKl}5_>4e<~#%2o@9rVk)aLPqNzwBKCB20>yrU zUE)5tt&Mc>#ydBiXYaM#S4M-gdC}$N95zEf83tJKycG|>@GuZbI^6SyYcxc^K-t{v zD^J<+ItpvE>o|b`vDh#ObbJ&4@Asp^#!dQsfEA8I=zU`UAKKcA&l-p>IJ51MIDuS5P@IcfZorP zOIzKl!)$gsH7NP$QzX-m^;-&fu8lmp$eIH2%h~f2gFGh8a_zwzXpyCHBqU#<_w9-3 zyqc$xm5e7DsnF~f-5;W2=J8sAHSlI-^HYqkh-9Bq`xh{kAThdyVBf(kz%6-QW7m)O zUZi<}N~S2bgu?rr!NsOU7|^YdZ$RRvW64ru&Q0jf*AcFqc80v@#E@S>a?qm z*^F;@1i$Kp6bCrn zN0nW1$wp4u7~{eIt_&EdKikbyFV~aRX82P7u+vWFQCXNVP}HS~^*`<<*^R2BQFOZl zAB@Vs>8sw}`}O&~$329JK(E>B7Li{Z(vVkWeLh_2Kg`dz5`c}1x882+_dVq|Fnr_wDT*&+xqsfC9}I55tm$o1Zq2O3R)jWgl&)Vb4QZl#u9QN|k~ zheulQalMH{160>VN`?%!cJ;f+0AensdVEvyGh;vG-8|iSYRf3;Apy0fZ-L)xfQj

    DpfmQooq8%Ts#IOP%nV3v|_vifILq}g26JgBUMW8A{58xRzjpafz(P7i?yrg{i zx|<@0F!bFvNN>BVK9*?N^xl~&_qTa$oh{~EocS@cKT9smGf*-a4#c4<>5bTuhRsi3 zy#*RHG%H=#^!pLVmO|nJeXi=qRJ669-rc?g%p!i`i#llLHN>J4Ky(WSnSvyQRSZ^1 z{qyw~q@tAF+ROD;R{_`g%67cfQ7Rl6jbJ4yQiknDkU84{ry8ylmLirxC(>3e0hjw`K!@uuHJ+)P)>Cx658^WqzHOnm-~{N z6%G85*_=C@pfO1&Tv)2WO{xfPskZ&FfWeFKHXc z1%)e3;wDC0^GR=8?3B%r?w!8OWjuMrMC@!fPLy*-spLvOEpCHCH|x8SF_FwM>%cj5u^;7%Oq{ZqX6Ocz&KnK||EM7K+~f9w3L9zRxpZsW(iV{f{Q9yB6;^ljT_|15eVjQlKXUA(x{ zDxlC8JT-Gl5J9~^^J9ZH@CMh{j>%oqP(7(T<-O1Dq5g&IBV>Df8@SE^p$wSFacgpa zzalVw14P*VysbHKb!dFRMd5!I6p@Z|5jLatYz)rU1TIW#J~h9PeDjg?O0zZuU5@~78c<1>dd#N$;_4|s*HWY%m7366`si3sZ=c<7mS#iQgw^xq> z>uq{pmV2?xc*UboO(7)~J6>1w^0`Bh>->`%81fi|KR~CIDWv@67q1e*Vog`Z|m)R{4x!bL%wjn z?fz@I?*11Cj~P?~#aU2c*k5V9mrB=k!ZonrU?>WLgG>V25N z!hm@lFbvgVo<&AaEYo}Fc)q1oE2o`nI$le(the)>Uv%s^bSzN!KT9sX8&QWFMY{Ku zKKlUiDe>!Q-qE=PL9YX^D{t)r^lEXXy^C$fOkp(1`j2K77N~^N!iN`=f6QDI zs85k*t6>w?jNp4o<1Opn0Y&olk{O;-gZ;3oq3;6W>#2hotg~~zYgEwM>Dcz;hTjoY zArhTT1(0&hikV2-L8Y`epPO5nL7-i8geK7a(zXIrIdiU6^#POo({g@ky5LDc``QnG zg23$EuCfCqU>pKufiZ+e<=Wj#Vk10c3X{1a4acNmi?UgmN~|iEpuQZsBCp-q@^L`? z86*>~KT5TEpY8cu7O=ciXT4@ke~ZsZt%$dd@)`4|=jzLW)c5z-hnr6TTUk~)ecZ0! zhFp;qZPrS)1~6-oZ9G?Up5n>?T{BMY#Bz{ zwM?I(q(4pR-D{nieYE=7<&fpttF{K4`}b3#M10Yq$S{V=DrTu~>Dk0;g=(5MYS@Cn zMQg(5CMh5!{8!~dr1gF)VmM85;W4sS;CrzIFz+2ZSQLXM{>yXx7(aKVx7(o|6Y>&* zq`Id5B{Kog>vp&2#R$erBBk4sZaiDkjPAVc%ZonZ*2@7e0V(N0I9<**;7$_8_sOUrtH>8D$UPuJPSU&zHTK4czIG?S@0XH=WVgzWv|;WIKDccJzA7v;yEmQ z7PX7Q&^UN>Qof0|*N&s(&vJDOl7_xyz|!YnqG8I!_B*p#AAGela1c?(?B2lrMs3eB z-Yc1R-@52dRiGVsayiv$vgQM5%St4w%NM_a(3te&Uj)EL2`ND2r%v6R#+VtFQU915*|k9!zo$%VLtSj@k#5BlFDbFi1c z2h~?=^Ate4fjiP#{q^4iTvt~Y+>bTpI^TC61Vj%YV8)ko%E8VTeb`nW#eEBJ1K8P1 zO2+}~69G{!Me3v){a1Vf5;|F2oV`R1CPnL8LaLG2I;Z<UGPy1dh5PQa082Bk9jVR(+=8V?EBi^?~8vY zU5in5!yMadqY7T9E$K#1kAHM;{ZuH;6E4WoDRUO0%JB#bl7m zqH@8A zD21Yy;0XrFdOyPK6xIG-o^IKvuz#G;J9C$pE{{$tb)B;-b+!!cm_701y@oYovPeZT z4qVgSUXQ0$w6GWY^7NS?la~IXrPHDkIMzj3nON-SYDO z)bqR;+n0a4aq~TG>3%F`^SN3u!fypOtqZqHTbF3tl%_f>-K-RGb3-l$35`B1pvv*BgkWi=PwvmV+4h*05AQR#ZWc7$ z+beRe*O$Bvp;13D_tK>52OJ!juX|ljj{NcdGa;fkLM%~Gr=86+jX$uwj6c=04YLkB z%=>RUGeFIZpG_qec}~au8h*aLjFD!chbutb3) zw%F-VfC$VWJ$7WdiBAL!MVSU;g$adxu$NX_PNYmHbTv`jo7A>cC}t#{M!H{lHgClD+xL3LZF--ky-)x zbGkPLz9LI2+rcwFCkni{^o*j3g`i!ntdtwpz7x$-qmij|2nRUABG;Gn$`a);%NwEl z-(t;<@V95;yEAktl+OQW0ahXnI@|)|e;;rTH<=}rgfX_L<uRQ~2xQiwL5o~lX{uxDLe>(H=~N6l{YXrfFQH7}(%9G&}1 z;>mC+C`YYsX=___@cRRtPu|!*c9;ml-XMPE@Du$!c$7;~QX))(%6TW)KENzf7q+~y zPoqvpqFg`d@WTwJZ?ngB=5%p20T(a`)~Wqq0#}~%blQC5 zI=Z7-|E}7N&ED2lXMJ@wLTzQJx7XOgytkPut{;&d??4&Ht0usmGWu#(wvo4Jc2ItJ9|WPr327)C)DU9kIO zwJ`xd4=LUfx5};xpbukk`esIvINB(S;$#L*FxC1|VFvfuv%F5^Z1r16?F<@fcZP2N z8;E3N5{hQ^UBl`iRJNI_L&}v)c2^BL)%?|F{$8X6@9a1xMc_U7#|k~)ZS%$og&@9P zi-JHm6a%&O{^N+^~19+0Af+Pf?cIER20anz90vH~4LBq~T_%h+^K~u2O3%TTNXy-mnoyjXP~1r!RX3AJ)o?2hEnJMwaGa+vyzmUZ zto2J8lTs}U(K`9VjkGdtFb1pdq#7rXqjt`^*Az07Qv#Z*XVN5YE;itmYcO2_CBvl?m0mh zHi4GApsz;;5jZvePMX|qs4aiug5M$-_+Fu1pH=T6a>Ad^x8I(P3|`}%N`8~7pcIS! zMIAEvi{rNSs>yzR?iCH=JbgV{&kPTh+WBf{BRBN#7Xok6;SU+=-3boGiq`6S+ek*d zk0oY|$g*oKcG_~#``^Qhk_I8_5}-)W)ENNnu>{PFm}2y6bqw*&Wu98Rbt2Pb`J0;2WK<=Ft<+4Mfz>I`Ip3mm7BB4C*?5q#$y7MLy=_>&s4T(7;Id##;F&5+k4K zxsH!_%w?_xV2K6~5%4p^vQsmLfNofLRsB%|+WtI-bp#r@79 z6|M>qU`+YrU-bC-g;fMGI71gaw*Gbmm$2vb_A5Lv#Uw)nxPrpH8a#pJ6SzPWrBNvc zOE-gvy|RIdOMFiyiXvUc_4fRT8SRIc>#L#E)AsdqCz8D4Emn3UDjgr274C5br6XO^sLkA;nxSXzIRuBb+z z;OZj?HP(TeZ~wZXgA^<9;zpkf!wb@B4z#33SZi)v$ugsgm&q^BN4Bf73me`GlQ0RB z+N}jD(CAR+!N&N+@s^+%Q>tV+3erf+c@7REeEp6NrVzPen63M~UZXXhf;xHyab7IJ z=_O!yUX3`7fjJ8GEzOtJEbn@Dpd^+D8h3u!o*S*mTm_lJxiE|Y zKPuGf5JfKR(t<=%%gF%)RR-(Byk=D!>tmy6R*I#9CoJbK_o}%|L{(^oZM$Ew^_qky z!Rf{PO_ISlQ$JN|eomt5G92c1iN6L%z`-!Bjw)*UFJ@XPIv0)zbEjZMbd-IAj0F47 zAKERZ2@Gp3ckVy196c_%8D34Xa0;xEK_BP#RMp-+5#>TVFyLY@>YJk=Vq_6qzJjT` zc1`|ETct7qqah2xAQ!XZIE3RupZafPP{Y=|%VWIR4j@r?>c?3J06ImLF?nWXB^(&d zyr%g%4dd&swPQsCqNYhcEMqS(;=?RY^zPfq4&!tlLE)LD&xyStKeBAW+lZv=43EwV zf|@=z{*(7NqJMGkv5=-hvQODk#r@P+{&H||H4F{O@J(@*sc+#880D6DRW9bf zfY8u(9uISdG|VIF+Z^>>h72jN9h0ndi}GX`%DxJU#@H3AF^IyUbhBw;6!xut7-59r@H?wW8J8cGCPYHjNlSQJ4n>LFZH|s^q zW_zAdChOlB5C;@n(8I$c@#%ykU(G>TNPyNwkbg}NvxN$B8f{VWoln^x$tXRBrx|(U z#J~_Zus|bKIw6~qPIdP0(0@>9lH~9NUk9C9pM1NB=!jeJg&NG58d4kyu_kwr*1+^VLA9ZV=lgN#52Cg{Bu zwB2Y%q#7uc8Nyy}->1oPFk$27WyJjl3wcc9B_~ugdL3qo@Yhy;(Z!{*0EHa)UgLi8 za*SMUvp^*2F)5E2*>fJRYB74>^hpZ|EJ^ubsoR0Eb-(l6y_==(El#z274*+L_l7!< zA>SEyzU?qqdXgm?ib_od)4#~1PGVn;em95+{6xPq z>uvDut$u2Fn^?lrexKBuMys~@CMU{{gNS}3>Mr>pswu6M&mQ@+-bVGGK2VS1JpETp zFlC1Ikis3z42$y9e9R2LljqaI)tC7n>+MMSan_1D&0jyco}Gzz>&zrNY=sWtD~tz_ z$v8+|211GE^~qAk!|_5gh=^v^7lL${VdlSYM?wL844IP@$=`ZMFQEjd15JW}<-AU( zJ9I%EWIZBQ1o+>HmEA%TAO;_-RvzW=Zw!1<)Vu7!$9eMaFi_-+HZAnbrLYFQM|(na zQu|euP07#|WxbsJD-%q^p(|y&g3;fsZ?@~5B;6Mjm)^MYG*D{F%`C7X<(xAH+VVew zE<~{?a%2j+yP@NCP|Dl+9i{+*v8tgVh7yP)3Zs(NLZgtssgl<}uy32V*{pw?ILisn zAA^S4c0@|tTWEDncXlD}H%+pb&dsRR{Z-uUpdwC+6**zFpCfD*mu9z`BSjL7IMg=? zc>=j4cSbiG%q7@OKbZAwhltqR*9mu=2KZ>`V{~6A2{ghsm9<(kXT=pD)K}KSO`$nR zVTwHyI*|IzCc%-DC*_1yR-_YG&^mflu!?h127|dpg101(Lu39jFC>K4ev!qTm!*}q zuwg0yd$8Dwg#Nva()RVOAfVG^tiDs)A&$b#*moQ(_&$hS+ec5H7t9KL_KM-$zObk)AUbm)BkJ$t+&7R{_6%6Wziv9#U{C8gIyuuoev9g6>x^jKL zJ(;Nc`ymPE#Defnf$8m_C}yogJGr4wPq*jm6Pj`xo_&f{8c?sN7Ex>e?ju(Wpu^}K zE1=f{-q`YX4Z=Zu+L4iMMCh(Z7JJcrm0rNI#YA6hM5w>v{u*j|dt6FM7+G$~6%(Ns zWDJ3mG9n*p6~$4}<@v!87Lk--aYYp0l5Jd_PGP7a)$u(}zid~iGh@Ktzbo#>8we0rVl+iX6ggE)IP0(ONNxH#tE+38 z$!KvhwA;(*PtO>YVxN=&i#}bIez{f^KbjcIh6bh@-nb+#3Jo@8Z})45rmvwe%b8W_ zN_I5W;TQME0#2>$>~y|pi{Ca@LU(7wIKVrI)YkUr#am788-j5A{TJNp&ktg~;6^7t zM;Hr2Oe+IghdJ4C$Hk5sxI_M>RaAY6EP9E&!qFlWYxuH@XL7ZSV(bG=ap(ynq)sR? z>(swg;)U)H7Crq3EP8ze6ej6_A`+=cV*6C84TbGsJmn?;V)Q*bBz`z|w}O-X6Ia-t_Rn5LUSCik?4C@q36L*sHVyf)1u8CxjGuM<^Utic z8kL|Ga^J}rH<{{ibV>fU|J!%Ow8sa(LEv!rVbct<|Bwt8Bon6!?W5#jeK{Skb3Ud# z+jPQI7JOuOz1TpU-yS`@E^9S|AV`~wE5cF`o!+jKwn#z{ zThzuvfbfI}fP2F8^No|%QRIp_yjp&8Hk8Yyn>USxI3ffRT?&2l*|tFrup+BY~jiuUH28~DMU2Ky&42TFGkmo2s zspYFUb5|Msn)!*|#K5MZ!m0nWvT|hohZDxlM5dFQy6FHfThB{EczX6(PY(h@D4SNq zUqsAel|YfAF0y}Zf)T+#bLhXr`ctph-g%s@wP1ux?Cxi*XrppD#`NBUXL`uGFQ&Xi ze5J{%MNE8{bW?Y+LS+jLiW^_BKFCwva^4TUZ z@MSl-azUh*(|&#e=3Z|zPE5W{MQ(i{$U9DrX^H6jg0L5g8ok$vdag->#pKw3=GC?l z@DJs3wPQRnpu>|(PE9T?#h)Ar%q0lS1(KNX>X}igs0JFH4wV3*Wj}@&eepthX--tT zMill{(A*{@!slfk(ULJ!oH1RBnUIPCzCZ~#+!A+ICP-l()RUCa%**ZrC*b<60PVD8 z*M9T41)tHe6;fz?4AFU!9sz(g5Q4 z>!3btBr#4*Bv_RTc;kj)RT{*J^^;OLm;mFH>QmF%0?9^OSqwm-5Zs{!Vds*v#B? znfh!GIqaQa5N!BjbK0@h?s*hZxy9Ry-_u#wjs92=I$MVY_k}?1*vomou`hh!S_sWH z%y@egY1a`kd&2AuT70WXa!%$&CWe15RBaz7PdO zxS_?4%j7BWK-F{^VvIWar>o=1D7Z*NCRl@f--9WEpchZ3KawD|3HsM<@dsAsk^apM z&zaRte+6@xW;5f*e`d9IsEO(X^fbnLA0mcOXopL;HN7;(Xj*eZFSb0{%%}fKIGLi( z9YZ$XrpB*cIHwCc@(JiB43Q2P{zSs#;`<8_dm}z$DlhJpm*$Rypb@F2MoWKY^nr>0ph`|MgBzdQ?IcC=({t3+rp*XK?bd3EQL_l3Ff$&*Fl$j1e^u|#X-!T7 zFEz$4Wx^?qR>%G^hpxL zV#lp5aV_ZOP~Y&$kAr)7YaSEn%kz-7ae0E1Q0O-16~Z&t+UHRIW%$&e{EUgy6q!$8 zo_o0|l+!7P=3n{=`yr$j=q|YJg7QBssH?-G%W=m3uL&{B^?+zcD`M1wGfbjT1!eT3 zGpnGO+mGQ!(x1a3P)0h$x5u>Hl^ss=1(IEcZ`;o`Z@aNR&b~j)KR)MHO>gBeIEAD8a=uz4AHyYTtrr=yTvx4tB^@5A=NbEd@{@-a-)G*3 zZeN8j4aHSNzf7T~2u#y5GQ=(tXdeFFcLzH&27g~!R4qsFcei9D)a_Rs_*bYSBEbfG zHXlIsM3r+kPfq%T8(5(2cP$KY%+1MC&do(hmV3;9bn0Mz9?N!{ur;Zn^Ya;JY1vNE z`_@<0vRMJOJ@WqO_q@;M`$(5_`soYfAsegqnCg6OBPrIZ*O`N%FrdG~f;+j@TEVM9g!ao9Zu*pQ_q)eKaAl>u z<5a&@&0l55DP$G;5A}@}0BQ7;ehax>;Iw*-*l)cGQQpmc&(*WK%UV%U;hz^w4L;Q} zTE#+}!XuaP11^Kz=RHLtvO2EBVn`B{?6@d=%dWUFdw%$R+X#-|f`;I&;r&n|$uLzM z4e-|`xUfa#otTt9JyIwCQUEY&X%U2h(Ib30JZ)J9S%%<1#OH0?U!yo-N|qL*qS&NX!ufjs%Q8-7UO2{!^PCe z^flb+aLNQ);cUGdFAFC?q`#geEd)9Lt7XDbApXqKQfzZGLZh3jNXTamwUCl;A}qR! z$}_R;S)m_~E2ea?xX7u+__Ia$7lQ^~Vd-&E{gN=n`oW*^r%NJXg)eu0u!80Tn5dcO z{SKe#KcHN$Q)+DIv*Jk$l8TCZ6E@=vOl7atodx04Sq(@P&09_63bRG&?p+FEm{KLu zCo?((LWMqK>{tkU;{)J_B#)t(x+%%QRC=`7r%?FFl-?`Qa<|wo3>67K6m17!$eqE7 z>gjqhQo^#P`dxmzhzN5w3~j!VJUK{(cu0+XV(d5iZpmIR7!st?gun<1J=NT9!%K=V zYwbpy2OH_q$_)wPJHB?S%e>DQhFPUvR-lJji7Ri=Cs5VCrY8CsUdbHfU0-0NZTV7qJ|Ng7jkKVJo)k zDbg|P1O-jr6hkbxFd>X5Djg|X;eSl{T%g+*&nl>xDE_O$idZxx-bzhToue|uPgh+j z|H^0)O()P~PAO!2A`3xw(7D=UF-oa!M#ORTHK)#MjTh~W1{W(p#81_)IfW<7WA#_- zb^&)VrFhtH%-9zZgVKoMc5XmQf;dHAxR~lm{r77TquS4a|AHdAjd;|Jy^Esx9?Whc>Newy}Cu1F>DLM)X+}F7H+-R6wiHnZV~24z7{_7Acb(=nq}a8 z(Z8pJQqgwfRT8+xefiUuJF~`WP&nl=K;XXZPu6$uMG3#!V9$mS5&|W8V~8OX0c^{j z9@%`#gW_5rc3Vtd573H|ib_IC;#R9|G#F?Q5btL8lm(S;Z|z$DjoH-R?b#f!_PkUr8{OFGoF{OYW+abFmU#2m4*;WWFv5M;t$nZoi#rt6x}aR|@1n3fK~%HeAo z<2NWN=9dlc)?^e0k>oMSsMy%~g+Fk^!&1qI$+9T2!6wlE6|K()1kB+u&Ie&)+k39j z;6_TyR)}zZD$djYR5MnL5_F^ai8su>DC+AN4-uh&Ps?4qvH`o($<)uKPcl8HhuS?C zu;JBrzvsKidx5h$Zt|;GsIA!ck2o>W2anayi#f4TQF(=3@Zl0L&89XpMOE$A=*w9R z;D3>!Fcb98@gg&rlg_e|p6#SXFu&0KMMzznq7|sxx zi-&h_G~Sr_uW%HQtYsjGp!p~#=P(bm2LQAKseUK~2!r?#RTk{%W#?~gYA7jIepuTn z245RK<3{ksX@C`ZvO`(KM}X|If(%-i;(SOS2nnzE-dm>FTMIORB>XXe5_$@sm@Ys> z)-uouEui?ur6_uCGR2)M-TGySF~Jr1Q84o`HHsN9Vqw`Gf@<13g8-S*4W$vq*cEFR}Gv? zK{mnAFB@v1Gj#vY0?-uu*_{$rtBiKDZaEF3dA)=XT_v;mBA2(fuOiPcEC+K=L6D#C z?M8BhLf>mha`zy$c0?GT9?1WTngZIp+@TC^8;4oRk2|x{WRkQ_wi;2Bli4y$EuAOZ zSz%yq?%@9_Hgi0?V?J+W(|;JFpr->@*N93ZmMdbk8UF2z*@8Xf+GzdxT2mo}Y)Xv4 zOa3Y{QWhcN89hpV17qBDV0D{bindb{TcE@GR%Y>SshD&7g$*vx_h~-2`qk?;IrTE7 zIh1(c*Dw)o+4om7=5qp$qR9=aJO6?2`nN6QPSX-T9_`jr_PmFIH3&1;vy{b9H@ITR#q{ykV$3-bm~f-} zv^ySV%gwO!Tt@h=$r)mrq3et^^(TT%0Z_Nm(aRn77`nQ;K=R&e3)U1gp2{LFuO}w- zye`F|s0Z8uQ83l$hw+2dz7htdG}AJFZq%5}nGfy?y^BBWhzl_N`W2?<$BSc&XN1oqHw42z+!rPzgFMWzj-;_@84CIqcMci5 z7Q&B;KZn2-Ti%{%0$fLR&R-etKIT+L#?(m$3Tm2D6Ug%f-a-d+LCEtsto>)FeMhp# zW!>A^Snr_jfBOO!Q`_mc8DF%!?q4&1Txr^)dR^s*$IKoHW``7GA&vI${RkKvKV~ zqJ=;;cz!T?PN{lEAkLNrhAWUN3tqtinu*ip$2oZqlQW6BE4R~`&4q~HDd>$Z z&6Fn+Gru?dcl6QqT>th;xT3)H4nDvEz+hey!rCtlY-lV-GYl!r-po-y4oR7sC=n#^ z_-~~h1@)d}v9u8q7^!c)Tna_l$hZ+SB<~-}RtI&ZTcC|VqL_Z#B%9*fh8sIVOYli> zOUD#X7no6U`F+;Z*#5sJ30X)zYJw85w=*dJ>hOrD$wLWFqJu#=@$Ou3tHk?qSo>;{ zBl+?oNa1pT%>AJWMhT@w3h^+XSu8<}%bF@V3|MN~9QY@JTS-pH1{m70=hYpwxH;xl z{=fwwNlfy7nO}Di)U)$Y2Y^~NqLE-Ok0A83j4mTF@|n%+ohwJRI7Xys^x~4$$_i6~ zO36IgVoY~dh(#K24dTZy&RANx-V|~)7@_EA0db$0nNTRasnr<<_gt16o@wB^p-}hD z2c6%*7R2!~AeJhYM5jZSo@LIO=ihDycg-KoT`ROLyx;Do;Q_EMTpHR1CGUU~O$5Sg zy!ruVD>Ml^=M+d1A_8S*BW%7`OyJ?($4bL`MjEVeS|fY}x#0EFze2wEh{929K7Y5I zZ~iiAF)l{oXx*8-`=2lOT#V+vEPr~MjotlkgQ@KMq~7`ddI13R02$1x1lfTDpi2+Lc%qbtr-u6^;Kyp>Di9fkN2C;cFwNNREZ2B&%QEt7@xJ+e2J~&tyOMNvL9!2 z9J#6}YP|iMN(1`P+><$g?Hm>obg={rA(zTLsK~12-r7@y1b%@=zvbVxTAlllfnnP~ z?n>R87}V43X^y?HM(0(D@6%KP{Pkb?;mn+j3G^0bc_IR-9XUaGhN6RZ%MnjbZ~-Ur8L8I?5!GK0fY8y!iP@FWn2I8u)Xi{<89 zn%fj!!=Oi}!=OZ%0`f~oqb=9Yoiq8XrkV}^k4xu$7N4A$AQmbr8q6Q!#uXA^VCNCs zBnF-PE9RUrk!7EDRi(=HCAOb0y$pyQswV@vnv%Mh??iG{cEZVN@OiJ!oRqgawz@Fx zH}1uqT_^faI05zDAbpXBPTj7%$G_u4Fn4kxIg(KtsQMx>EdCc7T>nVJv`}QWr|aAm zQ%vEWHgjLRzYi2B`8(7!+Kez*q~~R_W^rZ)$>;G1*vzXJeT6Unj=t1+PXatAI_}S4 zd6@y!Y~a=aiDI$7c)T&<3j;@MF^IJIEgy@Y3mlaaBPk=H|5N`*z-pI064d~XghT|V zlpF&%FgO7oVV-LsiAO5R2~Jc5;V^6nXE1DLz5%K<$3rgqjv>hJ0u?aPF>ZYX;#e;g zm2Vj_!hc)e6xn``v*j5+RFebqso(x62|)@3{GxkmA=bBHKgHghQi`2;SFq+d6I&}Ozk%_6Je(G3p0HUSQKL{atuNfE&`A+yA5Ic{K-Vv#W-@H z_Up^W_rWdLMmgYF1Xy~!I1D%)W^}9oX96Bhg_3)FDlWhAeH0`?G9%E$3^O23T5g6P zcNY7V2vs=-pA=x0M))0tOb!LV1Z}>yx11mAx4I)uQ(J6O_wO8e=&e+WWI?XC_@@SS zN~A~)1L``s)^{ss^-*kw>ojby47l1*388*`SsKGh{nBx;8|gNE zrdGo*b8p{zRU)0NRtYu1Um-F#8&VQXen}B5k{>tHKNJ~PA;0&FE*FT9kNin1!VMcv zFpA38XYBm8c{;x3#?tM*lwJD<1*xeX4pI84-$opYK{}k%<;$;^t68bFb5dC|{GScU z>!y%w2mmtbT+em?lc2ZmMli*oRgnY@m)x1cOhJ=pPMX~PTzTlj=nlPW*81Z_!(wj& zMc~m>!B`kGe1yVQnod^5S+g1FbAk25Hqb~8>mPpQ7zM&8&|n;>x2>&BFYbR$4gN`G z@=~@U6a#YzgV*v;pEa|?VW?g*IX(M?4L2`!1BIKr8NmpP&uywxob36iDbsHJ@#|%P5iu&PIEg4fe6Ve&DlUTIov3x+hSGUJl57VX8yhMZ277HG z0@u@Y(QXwf`-?00-S82|GJ7&5{$uBfldNF691l>3>wRAxNtVZ0xQ_P|$Jg)bNs|Zt zzo0{{B*0vd0-vYR>GJY!tklliN&H-5|3le9Q%6kPqOXnby%gUmRZp@OgUf#z{}gm& z*UJ7KInJgRC_x#nn8`z>O&{QI`fXajo{9$_%Q29NA)G6DUZR`2&UE@)a{Bl9aqY`> zr!`r*Q3=YSb-B;h>f{Ds|1d~=J#(h*xRxlU2z|ISKiU+2!7Py3b#iPXr-qjlL&A+T zOP(~BmHP!S)5N-+mj3v}gzYmiEk4HqPHd~XujrG0*Xg$&pYOf)s<&Uso{lI6z?<1h zrC@eV08KmiPPy(7Scg`psqM4}cQO^qm%r@^cv`RYVKjpMldAudd! z4-I{-t``mMfxzN&9mT6Bz_I|n`p_SL;9yb@iotPrY>y%U%3kmy8ZsvwRi(#E6(42v z>m?ZCy&^~5=3hsJ==jwZH~PFvh9(g+r}y`{K>WDb%|b61baCTpXA)*kY-55Y!MF)B zm9qdA7e7`JUw&aeH07yDo?5_;1lI;XvA|jhJgL;oz7rpu*kRyx#`0(ABC3UxIV%|& z?o-*YRTsa|zjuCcdovn8q~gj5bB^z`LZ8Gbir+fZe%EPppYzuUy!@24a3ESoiGFW% z-MWWOlKUY+i6ukusdVngU2z2B5{noEjA)34gCfonDV%PN9S00MPDs8gcrPS|%5)}4 z1{ti>^vl=oh-8l0#Yx=SpgT_Y5FMTYX7a9V!!TrNh>$pgN0^cXR!8xsn9)12;_qL5 zIuH7dn}aMsw`&cK0N}woqa87QpP>%NxnCCBDq9q`Pa95`T^t9@I#C)1oUZ5VZ~`XA zQ(0}b#6;1PcKAdj13TiO&YU^yMF}oPM`vTVtY02pAFmHK0r~!6^yHb+i1~)k^WoUi zmcyPYR2PYe+=X>UxCuTjXdvLi(=UNOc}%C-7QWSZy9L0G-38ya#=YLQ;Ev@Olg4Yj z<9zlJg~RNTLqeq1-L~Aor5!lw3ZlFO1h7|N&Re|g zPJVXZ;zs?QBZf!kO+FI%2~j_*j8ThvAc{9K_y7q~lc80swIz~R9RBCrj%xaIIHW># zO}wh(FnKANX&*I}<+D!4O8%P|bo=3tqN12^+2KSKsP5-%va{E#Sh7`@wL^Q~g=yt( zGo$53LWM=&pYOypRT_? z9aHs)j?=}T>0)v9mex2zddX%!l&e~Qth8p2X)MDxE8k;w#$49n420AwB!4J#V zb6<3{Bs%_Z1cC-s)|$Ub8~O@&o&Iyn(<#rhc=K|0X&Q);VCUfnikuyb-oYs>*^!^m zWrDzpjoz4!hMjppP7rfdUT@(6JAtM~9bV=Xkhsjtxab z44VKHx_?DwWuZyFpIUhlL-t@VS|EPfZdPACGr*hhrbq{^7mUk0`#E#ZDq z2-K8m^%t24CpTF`lEBQUv8v=nE?4vo>*Jt$YM7ZTD%8=mZ9h`OMgmF-($)-aO-&^* z;(1#3;Etc^lgH_k#x7q(cthLDW5pT3I+w7}!ZTOqQJOu787?%%B}+^c&>Vev zE*FbJtBwFYi%jE!n`>s7$e$fsZM}u15sSKLLnOV8O0pr&7^O9@EeI1z`FZ?aH9xq6 z^+WUwu9BjBuSVJI*TuahU-z_QB^7=x#o%a+Vu!a(*1-rIC4VwFo%;z+FiU@i{5zo> zbSMUiA5L_BR})DUi9v>{iEdev(Ajz&UNfGgx>G|MukYW@L?!+!VNcK0pF)Q}HG|U) zj+d)}eWM;gvwriymg|BQ`BTQFt5bqJ)rN4ag5*V3n&rv}yvXa!##2mF;?avSm5a86 zrQ&NAZ>yPV2HkqD&~)BmH++~=hJPGZ4W}rcI<(r?9<+##&`19mi6PNx`%dF?6>0dN zqho}7Nk6dTZ#(M!malM8Qq2imcG%3!OvKYLBgEIG{Q6O!w9XQ=_5S8oYpIIC(U$cs zX{onulbf$g-|dS4%F`s?Hj(qzdxn>dasx(sLsk<-YB(?r#cmDUp^60}iB}qF(f##kdD%e1sW)lLJ$rA~37&ywA#zvW>BJ79T zMCHPc!f;x;VaFn0BtU9tX>Ccpg|poFgR|>)w`G3obwhYQbIKPLFmS$0QX(a3Bygyk z0{u1ANee3jSvdLDMdES-F&y-M5O%v|DQ;;=6XQRqn&KMybn9{qbMfG(IyFFd6?qlz z2tp(6+ZjNN|D|MfoIrDwvl#8)H&A;Hx%(>+rr!-3uRpebKlqOTX>aFB_|>Re|CMht zeJ!SHt%V|$jR{Zc8T>7;$Jfv2`H%hV`g+v;7jJH@Y#;s)Y-yp+{QinWE!*d*UGUe3 zjba{VgN5vb_!+$zr0)1Wy>UuQg`QJq8R+vy`W7^t9|)n3w-KjN!5mx_jAp6CBl+#^ z{Itoy9XHsW5}Kh&HeL-o%MpeuL5^XHkNsPjTAfU3jc)MfrlhmRM|B2nJMDOAX>jCtBRd1nGqalk&h4UsBwC!?=qmz6R3zRXvj{NNL>S?x z_$np`bYFCJ;+mS8^2*Dx^jd5~`}nA#NcrOlW>A`xWrj3L6gBgd z(He1xl?XjDLw{OxoU0N_T!eK`E+!1hliNbu;e3)iC6660;%6Hjg+M5hx?wSCZ>9PV z*;<@Z72V%-98ehIE96Zc>+y7!J3!*%(hf)4tib)nXtUo8|MWtfBi>I1B}Y%pNglOe z79zMb@_X`>osTajWEg0-?%AFJG|X?n0d^jvS(;02?pi2}C-c5OvwCXJ4^{}+WxFiyR*aHs15>);;+G%M+0kjOMHyiKNS2N5WkcIb8Bns z5L|50ZBvu)xK+p0CO;(-aXy2h4raE516~o)jh^M%cK*yy`HTb(5R# z31$>i%cE}W#K?!XAumh9VEAR zhXx{|Zy#IaNK+UN_63G&bnBM{BHrb=3hl%$m-+}d5R@nzx82D*+@ zx2H}q!KkTa$)!IB=ck3m(-r(dQ=%w?eA;mmp7-bd_CDA0)TZn|b-Hmgd4z)x4Rva| zU6+<>Ew4!^z}C8HF~(wo#l{sqGX^wPlu_NA*q!HbHF>MT$EVcXuhpiWey^#ogWAwYUa{ zBEc=VySqCCcL>hE-+zqnBnLUj$id!g-7@FA7zZi-^pauZPZ1RNvPwkfus%>siS2Mg z=;Wuw3<-UxI<%wna6i+$rz5>y9OaOk&~eP-n<1Xp>=2$8D()0ZcxIy51jDWm&q^!U z&-gq~Z(Ap>g;0^PQD!VSKR(CNd_iZpEulRc`ywepom#>Dap#kw3V^tcsZP$#B_rN= zp#hr^UGSQ(gu4wJ&K>QkJUuPl&hVRu>z~h}_nQ`1OQ)uTOuW1>Hemme(O<2JAk}6D zj|H9DhchPm{los6>BhD-$>u;mnJKYMB<9unUGdKQv3x+RSe!ac3K;B$y71dyJqH+H zAm0WMC}TiXnF7=!X|hQVO!^4Q=f_hAFl$enBog-_UF}8PB?RmhAPogA$d#N%R-b2RU*QA?9N;;c{jwb zCBntS6>!Dx+gtYCLF_VL3p1V8)$WDV!GjLUxTw6}ts`@I${oMEX4h97#vS@!SBU1` zYRw8cCeNCl8oE1#GuUlrsX2kziq)Y`AGDmq>t zi}x;{5V2Wm%z~Bu1^a$iF3_r#d2JzQL+g|kObiS@O(17Z6*_FLvd$~OLml^7~ z)4R?@;EhsoNAJL1W}o1Zi4oQ(D9&^!`Vk+dskRiD=y?2+~CGJO$`JD zMDY2O8;H4oUo||Q6vg;(+IZS#!eOEf^=}ca&O_@8fqQ)23Q$VhZZ@pgY-cmQk*PkN z_#C`@e6-B;Ua!1z)qAWFXm{0qFT8s*BcBKbHH5!feD?(#Ne)nzSCeZbyF%ZA=QY#E ziU94yUt>J)`gCW4pWmKf=f)nxV?q0nNG#17xA0r9?1GuDYwx);CtQ5I2GeY3Y<=7? zhi`C3?sV>;nWMU;Mq6QEznnuvOsqt}&5(da&-J<^{JOK?`Zj*vF4thQ&Ncy>SYY<{ ze$Mwz``^bU#8vldeP#iyQ*Uz_pG3&#lp21?%8;(4O}6k+5%X^$uls(~D1J28&Q8A7 zk^=)S0BHIzwDdo@=CCTd=Z^AINUEg%FPb&0tr%a3uy52En)y;k1IfcYniRd(SxDt0cdg!%@CnqNI@YBD$-RFJ?{W5x=0$?)(-$bi=I z^GcGm5wkF8H-rrk3wP$G(V8U07z#OxrW-l6bvtDJwZsX>GvOU!;}NHgq5X|E*QF&S z>p3@7p!dwS_4nKTAxav2&U=c9F5Kb2o5mkwsc9LJ)41;a4Fwa=c^@FoY*yBv4Xod- z5~++vligq`;^rZ{yDzYI@CzLLcd_dHfgkY>TpgzVes8;Dc#qAV(D0L*PF4nQAm{hv zUijV5kK-+92n}kY}PkiLjpBG@i-??ecI8OPDo> zFa0meV%YKXbtkMumF`~T!00wWW~P%|^;f&Ym|EelVP+NQ5Dsf1tI=^Aev|9|@CPh2 z;+(h8W995;ivQlOdq@t;wOmzpTsQ9aq40`tn<{O1a`NMgU*&naNN@@3^xl>iPLtGh zhL%jTjbqoF!V%AW!+w{|*BIR5LmrpQN))*F0T-Tk8W##0rraJB&xrpn#@C_-( zl+r+Hq+?3u_4hspvi<_U{p=fg;eu&s@pX!*@lHXu2;V^WXNe9XJ>=Vv6Guxl(-kxC z4V*$R>AmYa;&ciWTHBg%Nhn&0bJsfWMTalKdV zrlE>3=&tGph&IL+FOi33H-Hc1Hw!BHJU;z)WcSX+Up%k9k;;yfJwp8KP5zDM%wwMm zxHDfnZhLKUOU998)XP>!mqnMC|LlC3eBVLjrf2&KLzpEMLc8I5 zOH?VVxNPM4?%ez&d;D>k>SEI+&6)2785(u{Jl_CJw2rkdU9NPF4x|(nBcH=48?|s~ zgtzSuoG_^+3+9{|A8rq)Y`B2QzDbp>-YHqwnX!YjZf)g~0o$|L1o zZ9c^(35Oebmf_gIOaFy$GkzV@FW_9z3bWWIAt>Q%zA;-F*6?SKkfT>e|oM zFXgFo*UWi^1J(xv<6JNtltjUR8=V)Mc2HhZ z&~^UrGPU;8AVcm|p^oim*aBrr>r-eai`^Ar-vPdkBCer7#c3P`5s*@{;+olAzo0GC zrt6#jy}1hpS32ioa;zLozMG~oV71l_7()2jiYxe$XrKKZ5UyU>Q}cg_`0sS88&Au)~@>;rm+23ygIoB&jc2|3jakwP@KSO!>!#*ydX_ zMdrwA;TZQEF7UW2=)G5cekn+ZMk93Vh3FG-TF=MI7tf`*uFJWSFdim=T7~xT1R=p-cvq{ zN~Oo1?XU3CyD?jjNH18++bFW$4S@jc#Bs^>PshtVcjc}q5KfwvnVu-&J>UNLyRxbn zRHIWjL^-0Q4kzoQ>T%EW_uDF=G~WX=#bJrl2RB+RAkA$QX#84vIeJTBc!OYjas5!vOM))3OPJN!WzBj;RW^fSBi#no*t%hcdNCgps$VP6c>D9ox8J%6jG7_ zq;@$gnwns2&pUw-q-i~ZoHhB~+^2Ix2Zzj;r#n_5k5rekq1jmq0Ik{=6@_B>Dd`=8 ziHV7My;i(&+S=2-p+U7pPjj$^k=>;~yS(tZv4ZZv?DGgduBlu7{2OMle5z8uOKYBDb!t=2ERZ0nGVc#>C{oy^|DHpIXrb037<}m;wqUni6 zFlVgl&FVB$1*nlQ;aeb>*9zQn`jWnc_jhV7_;8B0p7tNf-6yl$yILO^&?Q;In0y+Mrx7h2W_L5NfrxI~K7kka!fpmr?% zfVw~k6TI*aCUNUk{7IOUN%G&Ybxog+Kq5w|H{~OuwvRK&{Emoluk>6;WV*C=r;goi zOp9qxP4A9xoae1Cu?%k2^_%z0e_2|Ds8HsoR z3Db_%Wbma-J!{$9U#de1WJXa`T7 zexZD?l)hsmr2hCVD+G=L{6_d|&1D+deIxq?eUF8%v%3~9bHPHCL9?cG!OWemY|RD; zf!Jlwe&GO!A|VO&Pkl5o4xb9v6A^N%&7hGF1vK>)dV>l6PZPb_SiXoNon0@UcmyPr zDBYl%g34t{w2*(~rfcduUNTiQpX`X8qIt63Lg&r-4=JF;E$%yK55J*lI_vBYecm_U zNVXEP?|D*m?xehpoMe4=es>fBWZOQ}*6qEHOYlF!>;~6~vpoRUt_GwiH|V{Dc0j8I zQS+}?y)JrEhA7Wl#lFOx{f~a)%X1mT*m|z;`s+%78bDQNW#z8fU|+?3cOPyXrtghp z<3^c&Qlh0_gEVc6>dF?iocXeTLsX5L>!UUPU@4YKA4obb#~n4?Q0e>qPS~qO%p3W1 zu$$7LJa@+C7rh$N%dhf3II#@LG${Xln+Fb;PSp38-q|`ZUE2-Vt8mKL0I2uqH$4#M zojqyOXjS1nrBJ0BzDcW~d5Wz*0vr}?`^(2hD^e>>FEK5LP8ibmy@eak4PU;u*3DPEQ!&pQZRd6qGMH(Ucc$6_r8k0bg;HlL!Jaw4xAK-e<_@<0FbJ zIxAu$AXpIcvJK5T5f!e=YN@8?9lqcFjDljoNns8&KiCNbc`P}qjO;udVI(0Gr`TZC zNcm!Mknt?`m#I;uD9%;)i8hXOMq;-MeH+N0>Vm+97fVQ;89w%`;kzEe>V6KtncpJYc(dU!DwcS&DH3lDs@M}X~rA96siQ} zioM1kh6j3hl!+Mn-TL;2Zg9~DWPdVyu74fiLDc^a!ok}zv5840uO-}3cUBZ26JE0> zt>qBOz|{Mwc!I%KH`iCBj;4TRa~kPKQ9aR-)l6V=~3zq*bGN17F>WHCvYcC-(Q0M^ds1sCAz5 z^R`j6=>$R|WC%HNMKY|2OD_xF@Uxhci}ojGwJMjn2}EdC!(KAU!b1Y=IkBVlM%Bk*g@HP&HgnmRMagGt z(4gXee@|9!B7VuVU0hUegETU^oX+S}fzc6EL>n!UFe2oG$LzZ#4j3!2q_evR=TeBd z?1l@d15bGmo4vc6AH;sWRtk53XpY#~Pu#7zfmuI`jD5HTBnl@em>IbZR%RzeEP{p+ z6rA9-#h*}=)dM!MgiaAG2y%2xkHXy)7f?}A8#k~rDyr0H-`@{Fp07rVUvJ<@9zDSG zzA*nDM5bTTc?k;Z{jY(BR|+Y$nNfvnvRP0d z=l+tD?(%Iyl#rov#)7y$DO!ILb;B+*8Q-`6gkOiE^Bk?6lP~+Z+hdYOut%I1biQTv zqV-a`Z~BKqUShOP!l};^8MR{TUC){&&mgX-V3Qfm9rDO{3Vj!sWRo)SE$kppiFgV! zB=1WBy>8MfjS7HD-~b>L4O!>a8P`6Wco*3W^!Howr!~;yd~mo#Zm721NacI$)@!qy zipS#ixvSj&ytQxHzJ6KZx@Hlzq*S6BL#)x1>O!5*$}X4gLO7}TMfOm@QO7Iu3JRpX zGT@#W_6^S&nQ!|g(5ehNlV6GJOb1Um*A_3#v7_{Zu{<{L>))!QEMo+sE?A^H1dXV5)=!Wq5nBJWi=( z`^`=fVoxhncTmDHN^l>l_ILwZNS8@J*J-Ww7R#Pen5|N|(mmI=qcQ`0-la>e!I-En zqsV^~lJb1fUJE^`h^|xN-gitogV8g}QFB`Vetb-#!jtfa(wAd+!5as!rW=H;_LXCq z&p?iT8%To>sK!yqxpb7Tx^O7 z4gZrADnsKqVO`D?BhwWSnG2NUDbhf(HKJWBM$7G(YAFXYzha=LIMi7({Ka7mALznr zUv!*zc9vpHD-}N@g<*2^d75Kjm&tJ*ll?%ccUa1v(0ZzlNdPf2yM@;=t{b^4;J12p zTTx?uj(`jX6T zE4$#Bb>mv^*&1rPAs0ysaijAHbcg48QO|c@dF)|sFHM8wVNkDu339Wxpl-?B@H1PP z9y&qHFz$QXvg>MWr2r- z%OCBJ`+mTUMPatMjB0cJ0j=q{R-Go1(95C1MU9>(x}o8W8wiTO2ZDpPC5BV`JyJ(} z@d2^(w^1NJu{UCsv!1NgBGUiBlt|phurG;%BD%G!ai~I7+S;K2?@u2S)83M)flVgi z(xle@abHeSkf&oyps9J2YaPO%sfepu9to^=0__V<6JrgP`f%IxU&{ z4n-3AKix8!a12Z53A}1c0sW|k;p<*y5NCf_eLvl$M~FyY{{kiIQFqnQuAdsuH_K@T zaj_{IPAfeyRg!e}NMf+TzQB+0J+Q6!SMCjmO7A_}=kzFr7zdbltbX0zc1mli674R? z^DK8>Z%1q66{m*d+r(#$DD)5U9ahK63V42RebapoCdHCA3#>yWmcsD3lchU?4a3yWG-ma(3S`R*d zVwalC*Kuvy_mLO9|2$jT6Y6-aSi>$JCVY~oroOqgM+%J8WRfE3plEgZ&`seE2bLNEB4ibM3GRrQh|NN z>JJ$0Ax15*-R^xnUGGh6U342z8<$=@k0R!~}XWGz3q5^J6Vm_|$&97~%kZYA0>1BBd zE24~&=rf4}>@g%)9mf!RNBPtK?b&zBQrE1!%gsE(P^3=FR@a=Fn?%X6G zKhmmueOc{@64kQN@liHbA-R?{iNsjwL)!u8y8zNZfBwZfl=Kb;1QWJ6AMa#vlU%=A zYjMA_9SE5Oqky;TwzxVdL5x2 z2IyD`sey#vH>}UQA#Yuqn;jdYO-KB`6P7;LM1-L9AMesli}ZCN(*yB^Wx4!ct}&D6 z)6>%UvL9!Q-S+5pd$+!Q^&>z}u!%@;SWpz#FIY~f6lQ%O^r)>>Xz=sAg0+3rFdLue zb-Vb_UWF{GTel|ol&fNtkbrp`MJSMkjwM3Gk3+_E1w4P55u+>2Z0U=g^k(Irt7G>C zt&fa88C?6{g!gzF_j~Tw1L_4q+qd@64*o^G%ZmGP*scEnY~_}{@%YZ2Y#*p_ID+k9`t(!H9N;=N<0{4<)t z&MpxKp3|htxcpLGt1Ut4G*P{~>6+Hx^JpCU`RCDsShw8^%)2FpAKwvsm~lfvPlQVj ztBL?_!HooWr2q4A$!|F97?c&{ao-jcR8;%n80+UL&$l3t(#t@$0R;M)v0RfOS{Su3-A|I9B7;hhfw4qS_*$K6(*gto@orGTb{`{+mZt5-+7h zy$Mfi;5^rp-FqKe5TYKA_p84-Od7({1 zp3fQ16DD{idYtsOd6R{+248iXx-`N3Y6Yyb?2WpK`7%vTTkn z!3w$>x-n_GB=hzHXpqS^;L5 z>lY-wk8t()WonFuRUO%g#6GF2E#mQbd=M%b0+hzj#eJ0Xh-i#N27jKu@UY2PHjAq2 z_;KIink;zV^UD`M1k#s`b6j%UiXUSiZUv53s1JS%6kV-7Cv~?lqb6E5|A8rHguM*r zs_!Bz>ZcCN!=Q=0!i021zayo|$Q3Z1PBxF^Omp$DYhK^7(-6M>GUTs~)Hc0XqVp6@?apnqR5%o@;s>c{Hx8s*RQVQfCiG1;*EdRf(5cY_#zgg~!GSrWr z(G&G(u;8b#dpR+$TnH=~z!DiQBgS3y6X(`q=o{9dNs>jMZ_^O;)oTc1)&;8FuUXGO zcW*lQ0lVcBU`~R)?sYM_SQf>qSDpM0dSb&mk9JS?0vDJ{dwS=hJkxq9XZzpgh~6{# zH)I?k#!A`=Wds}skzPY9t2f^f`;R>s*)OXb4tIB_9TzTRCjDEY`6q&QsY|U=5nb#F z_oV?O6FIMNk4puDJvc&7sDz->Z*FFwG|0uAboAf8GPFz36;HjuL|SI%wqc5QlwQmI z2jKRcSFRwNhC5J492c}#>!PN!d*ei5e%%<49=>~RvFkqCFQCp!1faa6VXJ1pFH`$> z&2~0Be*BU~4JXVTenyXxW;o^n>_WX;_$g;~otFO5U+1vca~p zO+}mfVij0z5QT17hgCgqek-6w>T^tsTAky3W+h+l>~k(oTs?)Ks3vyCVk!jq!vcTA zSX?~Eu|$;@C%zo12@h~Hy)i+BY^jr!%sO69&sl|p#wG_@nD3LWn}EF%&)NOg0wwTY z3Se@6sonmFs#k}MBY~T-0w^wX>-Paa>EGH3p-8pXZLF*Gh4yh^i1C$s&4JqXWo@Ij zalK&#?lAEix+l0 ziOrM$*h|>XHzRxC-uM1x&t&Iw9Eo#qoKBMmW;|##N#u!8c3#e|*?SaKEw-$@>vHJ+ zDOS9R;T3u0THHRKMza5Ar#Y?5lwCi>*Hq&NE&@PeOx4u;n9!ik19Xj5BskF0A$+0+ zM9O)lFqR}V-+vNppee{}=x&RR$Q51z=4A7$s&r(il*Ig`mmT*|wA$Zs*-7=fxRn4l zZsBL7b{zYy%I8m&UUOwjO$wBr~=Ib`IK z8_rkbRa~Z1rdNl5jOVb&a473iR(G&Fro=XDNDp)9H|@uFFgz&uSUdJbqvBGqE7r?P zSd7fbeLu#MjQ-pM6*qqhXpSubs-<~-x|#Lmr^19{Oncl(y)sr7p6{6AW`@6ff=KRF z=zm-MHm%vme20)h5arKdo>0iEk({tk+mAg_$==Dgk93%ZLTB$7qf^VH7osJqkyF-(=9gjb*Q z7(kW(R4f^EnPqP4gW?uo(>g*lqcau)0stzadt>-bPN%d|iZ- z^r^7b%AW#cMPpq(2?snq!9prha#@CrOoggXeJfyK2QcvZZ0Pld$c;0r)XzReQK3{) zZFXqk^;Uui)wGO>in;Vh_3>M1f83Lmm*2S%WnEb-g1ai z9n)_&Cm39f)!|he0au0le+hO+<}0*G>jFE=L3u(@>n&D1={^{W0kE&#Cs2R9=9(Mz# zNInnq?q(^Pv#0@paWTAixEYq#_45W%*z}7W3I_#@ny2PZn`f3hUia(!Th&w0BD}PD zI<#kZ6T|lXW9V!(!2+RGXB z*bYI{>3l}D#Eg_uRCS+8KTi)!ft`nQ3mo{f`oL_6;v}3dl>%M{?f|M+)X-(?Vp~HXX~gU zXw{=Yyf?Ka;1kWj^P@lc1c%|yj#-vs%(q8Nf>nRyZyDV}#-(Py-#?*=sZ7@s1kI7YIG{gxN6rc6*kmbc1N+rE z1mxf0WagYryVI`rS9hlXQ&vc@$bLTFnD!fT%Cs8MJ+m;eEo2wwpSg6dtKcwkmW`Y) zWA8VGcN;F6s0>F%rXQ87DNOR5fb-IF4JLWGkh~wH78)~Rdx~swDRgy&Z1X@0-YO#M4%U!pW+04ZI1`-fPwE5MlUGxc~|W}B`j4$9hlVQUR$vD zP*8r@rG6W3zngnAe34;#y~WY<=@ZU?3%#?SZaAISWMpSoc8ZVr9Ppn)38;)O;53cV zWdadi5wu8NnzPt+H%^0Iy_PWB_oiMxR6QR7b)WvQ?+C8>ai%1j&qK95I;P(o9ZsV- z-z*0fQw;A!J=yvedtKqGGkgtlZAW1~NLV@d^6N2VpSGf4(5y?X^nM|@>tpr`*LLf2 z?=8f@Wy~s&YZKBRpzf!EeICJ^;0*+nxq}48Ki6Nt)teS+a18*`=c1SKwB-`KT3>fp~Dusn?Ms^mG`z zahFl)tIWos!tZ*TUT@}gcj6PoFwyy`9p{FNei-(tf0|8@eQ3K+W>vch=cbi{(9y;- zgTOL6QitATA&OJoFnlLf(nWauGxz%F?2Ss-JpW_ZRo0maAY zM+SEgUygYeoJR#GFfIqG~I^u521aL1ZtY?zhOyne& zcYk5*UG+d*SET=Q?fA0;W_{C35%lf}C)TcKQU8t*lxK(q#1om$6fvH7Yznyu+HuDh zTWz!_06OOx8_ud_7M3Qz*sANHCZzcsGaU=+rIYTOlf<)MGZG--om?F zrxu}0T**XAKA(5QDqkeIz)kw#yb@h9H&PAROH819QWBc1N}szX->F_c_pidMb}-~F zF$Xyq7rRC~fr3_ofI9{aA#oUsI+D5IFT^E&Q+~RuFTUk(sKCTzKc=VTK)0*seZL>( zhAYXy-V+^4KdbaVn^~HGF6DRiO1HU}_S_K%2;->hGJvV^|Cui^& ztIomkgwHYhn^tR4MW*g2$)1X1A3`-ed}5=O2JnKd;A<1C*ZzL8WTkQMntq_Rg{kdk zjr$$)_XZe?YwqGlQE12CV)@_tbz5~={6MuQyay!T_1ZtzwN+SH`?**q3rxJq!~~wJ z-7ki|MlGTuAy~iw2t{D<-2QX+f|fScxEMY_g+k|Pv)fOU zfy?a`FS=kUF!RIV4a$2c7B;g^^!bxQV7cJVW>-(^3sJ|w|4MjVl59ImAb&YQ(|17Snqesp|I3Qg#iSC|*` zxrr3&`AEU4BfJ$j5*P+q_8GuLQq^M$rEmM3+}c{fjeI!6FkLnV>zK41Y4{p!xX9Qh z=4?;!*GBs%_r%IHrwQBH$JH;W=oBc10i<nXlq@y7lu2p@n3tO>m$bP;V_^0Ci zbdVqGu;whhy?aW%BpQkeSfp?_?)&#@j7L=WX!R123LVl|Pyj8Mva&Lp5Lf^1E=87n z2G)ogaNj$KeUysNaXeLbHr&HveslK1DWuYDF-)f@p)e<3HiNu0tn|XjTlCjFj%GZ> zdU4PPIq!$uoZU zWW6oh)@LU>6$FA`;k+KA%95wbit^`rpX;dflXOQBQ|Z+vUd6Eg+VT7=9YvDD+vI`X zB0IdrQMhJvJ-pBg63sVUb=vtYaNdf{^Cr%0y6}Q}y$IJ>b=``bbyI~gGfgXbBsrL@ zB832#o~1ExqZK&hP=!z(XBi0P4Rz7F*dYIb$&){-1d&xK1(wsa1L)p+Z0^bI>@!9U zQ>5H@FZFDZIE+R{MnMiGvc(C27|P^G4rmJwDLz8x$0@}>EnIiQf40n=)pb`d{8<}B zA@?&rh~gBphJ{S#s|kTzJcqcuJOt|z9jF7ARDp@J{}i760lI{Kmz7rC&?l*8#!-03 z-sYm9NO8yWCD{7`lZb?M#P%Pw!B@dbxJrz#V)j3IBXBEzm-JJ5>7m&R(PJNfZ=iYp zAG$f_Ju$^Ci&1d@A zc`qd=nSppHg;D2*pZsbf=J|k*m~$Q!1Xu2QLe zG7G%sm%bu;>?m6{PjQ_M~ERj0GRweK1$_agN?1UDY;R_?df&W&EGUw|As zp_lN9i&x?Hs7ylf5 zV+PyNac#TNqI{-oJzmh--b+pE-wn?NPq%>;U$wE>Vp!WjFteLtSpvh7?`E8v$f$MW zdRJrntsGF?tbd!cNP>GJk<^ORb0SWP?;ZqiiV@1OAWnl1@hN`jdMDDi%7qB4#+$UE6(+dzawNsqiJMu`L;q*e$H( z%;RUGnt_+W@;(G`Xz0Ig_mBXO)PIJ!2j?ldUFa6|BBgWb;N-HK-=*;Wl4Ua{f9(7- zYj(t*7V}}l(cEh$wX*CyJcELOWG`Tg>=81Ll;?tg`L%UUupnM*d#^gM&q{MmXx6y3n|q)H*DoKZmA4=gASsg}V-I*lfO z@$v9&bT0x@GVQzVsSA9smpVYgU!j)muU~H;xnIYL%t37qW>uU(Ss5|5W1@r6We;I+)!dLxaPDYSc`9=JdT zEl7O$khzb?ODxN26bjBas{ZLZUKxy$FdV*la+xY~`DHVuqvKG+Mne)06!%R<4Ae6% z*6uZM;$d%&;~?MXWG1cg2u@4L)^eFSl&D4ky7?-I@`b5@FlDHmg_U>6saRy4I!Ffb z&l1bfEQf9>`o~GkkenuneIa}qvit(|2uLu*{bJr=n19>x#kRwv-} zklyzNSfp)PgpnY|wMQ#O_G5j$E6&-(7%fxX*6p(+y1jGxc74liH6WJkes%tLCOyj&zHT9~TM-odL294fo zE$%9t9)rfBw}8hhX!|h9>nmcK&A7po`tq~qs5_=O@Efo0Sn%&;Qoxi^22kh?W-@EY z%M;9TsPKGW;q@Main^Gkf17rr#7O|>cA;O?`)$M+kVmcEbQz{os4x z`tlsP+8a4z}#^g!oAqo`p_tToJpeV2)C0!)B?SH5z}X2ZaR3lW3=@FzDiK7s&RNw`sg*G zX;@$?wuSl60BmgH5^{Nn=VTHlll$`8p*@te@$#;){nM$7M6x**H5Db2mqopgB^W3J zVo!Z~O7M*AAvT##+kIM9*p<+&s(!MEpW9!tssNv@zCKy;6|Jr=$8-?qCOC{*4t5z2+& zx(bQ3^mP(M{6YjY)b(H>a>t{|+U zUpRZ_F|0QF+AS`eBPo?Ra~AebjNF%#qOh+|?+E5?NQrSf!*W{vl9qSe!%YhCMa!p7 z39;a97{RKSeCZxWZvPtmvWdOo#QGR?c>vAsUB-#G8!GqfJ)OMp4o82H!x>~p0y~yL ze`hL#1~4i4p8MEzT&os22k5GI>k0g{QO0lop-`+soc)JXIShwP`s@4t0Jea0+H&p` zTTA=t>q#}0VRUbAZ!>FiF4Ht?%DQD*=^V|9Du)M*(mjj>_F7rlXm%l1xpWh!tU*C~ zGX~9KQlGy|6;-M@6Hr5IU9mREs)OI;b;)m;Sp-=15Dd%fi^`s;YK*)fZ3>Pk%N%&_(q8Mh2&!tk%A$jGl zAF;5ni4>=+CbKP>v8_lQ79d!&c`4ASk#F;KvQG|W($UXgKAimbsgOb1%OU?#AeJYh zWDY^2+QQuwAl;o4;o{zhUXSyg4n7}UjA(^^i3PLw`)p{on0&eTr~9ezW)^^jD^m8fubhRPKtkj-K3X!mxu?tXt`y~IeckUcb~<{N5EU#2jWZ;^HN=CgJF z@B;G+dr?NTBdXusXxm6;)VjY26^@!uk7Q~-Fn?Q<{NK@}hS6tS=X3OA8;VM@KUe7^ zn0?4@p4N=kJKJ1#dkdO~ zzcozPHnM6`N@j$z{k^^S^s)RdGaD0?7#)PSGCS#OAD~|o5-d)a>tRmu^T9YmZx5(C zc3ptC01)PHtl!MEj2`$@n12ptpc61v$N|ndruT*x}Gg5 z9Y>xh*tABMEUgMPm@*qmO7K?sRtowYtKvr&nPrV^iz6cmAdW|K&X0?;+)+HuNt1}y zm)^on6ov0SBQtGA(6@IP`(BEug0<;@?0A~s&plxbGJTr3M1ntRml_KHN&7ngLO={P zaxjScCi$h>cSG0Yn4JxPPIL{1ovga!t1@UL=O+GuE>oQ*3XF&-0m4I*Lz41gR!PQW zPWsr_USuY(S0ZeILyK47!UuYS-_*8(bhgfXB%Mer4a7b61KFLMlT~mF!Ss#u5Q2Pk z@s_!w1alv^+xk_Pm9bs-PpZFkxf{Ck9Ocj+ou)HMv>m?*H|x`*OLy6{^MFRsYpsPt)i4*~)p#)MV z^TQb_1x@n@&6hu6B@G{mioc`aS{V|sG!6eww!$j2d^$Uk_de!@#k!i*Bb-sksdIZ> z2-Pr{bJn(;n~l3qoV)w<86*;>IwVwFNA<;Uo2K7hcD{l)S*avc zP~mLI~APd)zYpTD7z z?q@{na>j=a9`u1K)JL*0ghlGZcCRFDxD&`4wOi`R3w;OM@;N6|-f)-Dwp$m)%yk^WvYDY@#-84k%-#bq1X zPEv9qAHZl#Bt=oA`++Z&m!_ZY<`V=RfEV$zPA^b$*&b)6)WKH{Lx24 zgx)72`ARy;N3I%P)^aA>@wK#tBCBR-e;Nfv705th-TUx@ON*%X(_smvP0;*PFlKPM zOrZ+t>7tbK0EfLY7ww3|PdMTEAjNKXj^1eT7VE!@miCU2(~J7Sa&Ui;UQ_(vzc2 zN@b*6zS2YAqx7EYgC2P{2z2M>mR2ZusuY)! z2Dx2EGEZf2+mc7Xttm6b$rlDqSO4PEs3(HDf#dyZWAqc|mCSw!=ju!8Pg*pJjo3y~ z!%oOh5(1stgz|wJ>1J?HzsR(7nd38hnR;Ve!@Q*?XF~}77Y&x3GLu|KU+*q_a)>mq zf^k*nY~Cl&$vR6$@&U3KYb$g1x|~=NHEK7bnuw$k$JNKLK<4|kM)elFO~vO;DNc*rPgYtJxeeYRx4c23W}g*8gx90zlA6zP*f2k#7n;+h3Qmb5hk%?BveTy=%sK?LG z-_B4vqNxD#Wdg>fAAQ@nOoYUZc*7-deKNdA(%_F6tb z*HFYHD6wi7c>@zht$A$chAnS(^_Av6Zx#e=8k<7^%Xo{Ojs4se3HzV(^R=Dc9qfwmsi~lLgee8i9zTiADUX3*M zhzm?AQHDe-cNI)7PZyo|D+_lASmKOny>2rCW@-|_IAZaFRg@Pv8Fa~{jM8@rk_|6@ zDcV;i7BjEDFP<^q+AsGk-Oo3?g8nYUqrHD~$JYl?m?Za|h;C0S8{@14ggr@Wx@kY< zcc=U@b;cmZybAn0YSMt5mQ43~Tc+vgtFJ=Y(vQAR<`f#xZrQrcngrUZ4>xQ7*w-E| zF{M2hf}~y7GyWesqa}Dp_&%2(r?nP1<7w06TBLQ^^KC&;nK$^()3x~@$|5hcW@2o9Q-bfkg z_l*nYu+Z`{?^U@Egyx^CEbGfaHr^UDzv=O`L1aGvKCt=pj~Lzbbot*J&!)2Ke?wvz zRV<>MtuoAieWpX6FUZS1`RK<{=`=I^niXp>WO&aWpWjB3y677G>_vE3$ z@-j%KRe(P%J)^=c`Lc(TC0@ZwzSYJgy(umfwCq+X9lKwwE|@v=4Qd<34{qK6iK5Vo z?nLadh@Ls<)`rE2bd(!B4}Z=WJZy?}=V{9HF6s`38Kkro+IwO*&> z7+ddu*A4{vwU$leC6-gJ9d!(Vk;fR7%384S4QAhb-j1hdD>zC3cp?|?jI>X|yH3*3Xxd$);e2HSeFZ~?_i8wiW5aY2NmS{3!LpZi@zMzwk=4(~wy-#B5 z(De2>gUdaL_|WbiMUI--fsRC_yzXQDQDfX{p~XZbDpq$O(C^W6y{auO<9EWy-T|3` zG-IMN?PonsSOu3xCdJK?rZ*>Xy*-v0g!!uj=2vBq2Jycl_f6U+>oFu+6U-VLSlK`C z3k6ayN0hxRH{O&j=aDhKx|bvzes1ob<}N>$u9hvWEQ8R&TFj15$hHU!Y$V;hevBQq zNJMQ1e`y^w#cfbO;jqbXXd`of0ab`Ay37)cvxD;a2QU$uOg;}5ADmW`0|f~uUOc{C z%8PFM45?*Tn(`&Y!qAfAdjRZ9+&|PO3=aPiorGZW&*Mo>=nrK4(?nc^)sOxC-nQ8I zDRKEk9h9EIl7)-X8NCL*@0!FWpJ?reDU%h=2=LS@toihTC+y)hZ_XZ0uzwFiue73V z(?Nx1^uLKEWgB;cZJHE@L33hnpJ5=T0q99@Iy(Gtk-h55xbK}qd|xTEBtN8&e>JZ+ zcmCv!cLhWMYl%IU36bx)Yqk1JqzMN4D6EsWYnh4!8(y}J7|}k2D&*;GH^87R#|`JxUu#ZTr3kB!;jXBz){sUTfTsyi&LH`@`is}X21OHAE4xl<$VQb+&gi9V}P=xEc80?_{}7DU6Pe3Lk6R64E{gLDrGATYdiT1>iqXOUptTfIvKV z%8kavo?&!A$Wgjhl0X&?f|mWSFj15SY|(EC1#6eW=(l{;)ea!t?qJuUi^}qyN300Hhd@5_N!d%*+%rHHuiiH zXq37!(>A;wGF*E+i6Lvf`2$rLaUWl&&I%nk8gR*VR`68Ji*W8&Hkmz|6(2( z>gVHOqDKqfawlGHYu%9?eZQJdlue7RePf?u*L*supdg8Us-Tcg8XY zvNR>#V)La-ivM!50H$2aKf@rmgd(Ms_@P~XPtUa69%ws}K6V`-oD6-Hi^i}A?qH?}44+#r@AERKt z-!$NooaG=EFPMnf$c>CJi}^g{H|&mTw=}?w^Z=IYUIakx>~0d5m_qU=u!j%-|e+OX`g`0>=iZImQM zk?lwt&LYZ!EgX=xEs62ZzLED5bSG@BU6CqWeGPVX3(%s!dlnHn&&0a>bPgYEJx5IG!qYS z;%pSL`7x*~8Ugk{m!ryN=P{l+$6ho(%uv;U=`5SHD>PP`#37O6bpzY6JgKmje|1cE zS0!SKZO2&eov@2&Eg+aGqbDA64O^SxE+Z9diR%nMuf~xKM#td)f&Wfp@g8gBa3lUY zqH@@x3aE^|)1g6AQm*8^oNct#@^$j3yX$2>2eqw>__*gh)e8mOCp!e}iOr&s2o_R) zJnFu5W6e#h_8QyStkX7799F3HTk-?GlhxG_c`4-dv^Z)%-@ucpiewShtn2z-T7Q#YUi32 z5|wh64t**ZH|Hb>Eu2ckzqgZRDoSu$e!nyH7bKr<{+q5LZQI9wI`sbT3)#nN?_=Ym zrPCIvr=zYHpM=Z`9u>9xSS+w(35PU^sMN0@U=^5!Sd?H&e$52> zsY>TW0EdL0jbaGtMG^6sY~sNou0Nz~1rq^D856DY{ zkmkwXb3;2WN#2i+>I|3&$@HBGeLWvVr^Xdniw#^?=yYVf>wUBa>%t2t*HEjb z1?tcv6b%*kqts>z7bot-OSLUb2z7rCllwf08$;j2gByCvemNoWz{#58TKgeBREGC^ zV%_&|Fc@&szb|?E%NHyFg%?LHgp4bTl|xh?$+Cejyax*)VCi$ zLb9df;or~~3BJ%oxcoVM$aJ-iQzIVB7)mdeV9lgWRLDR79O+%JT%dL&PsZJ}6*q1k zH`Q(1lx8y>QDCk&ofl3aLpfAu_YUGZXl@u8BJ9^8c(!;gHQO-XmJw5&9 z2sqGBy-(<8Vfs*lpeld``nJaR{_rvPGRrFWW!&SX`ZmkwuSgp#e{^KOcsPNuuxv6RsiB>n`4hfYf1s!Xf;FKFKBs*nzDuYgA(gU-G^gq{7z*BLt|L(SSt5(jYNe|bX@#^Zv zREXD!m_w9zI9u$Mq3ZanE?$iHJ26yof@qL3JCCl_>5B;*%{;8M-o*|M;+$~61;>}Y zvAg8(*FoiM*(z6QoP|?VG)S_3bG}jd?(7|i7&ED&e*Y2*u}33E&8+y&`7sn#^`xMB zqW2_%F;U}DP0y*n*yR&FYu?5^H>E<{#b?M3N02H=o*LDZ0XtN(0&6N?%a)UiOR8KA zQfo)NL=i~^e5gbXm}lo&M5a=)ujEvE6M;2usC@L=a*|Z7&MzJM1n4gIcW-SM);51y zxzbZt!=Ex%-qw2bl^+Vu%3v%M5~b)Z_$^gRqN$KZVpn1uSq^ogh+TDRL`^B$F22HU zj_=6*+&k(yFRO6LtDFl4gnT<+b!k&91F2h3b&#x`% z;&F()5T~Q)qauSkLzr(~xQ#A-5qt3NJF+Kz-rSaSy-Ii2(tSM~IV_Q6iOBw8wf2WJ z_~QkG+p(@45r;=;`ncHRUzYX*G>6yhzxV%L>+@xz?otEp@$FkS5QL#yn^A0{g6qrd zp9l;TX*0zb*PqTddb2!UWPES9a^;`+o{%UkI2rIsT%T=!-SNSXk4@nzLbSd*LRJ+2fWKk;4cM}chcnxFLzIexrqA# z!4cz|{L7aoDBI&?1YPbgbsOzM1HPP`9I%+r7|#Qf@oS1Tx5)E97bAN0GSo1167v0R zFFM^+xZoVaABGuiIWZcr?EN5Wh!zu%kB$TrXauj=!bDyQhy%pVH+$%`Usw=G_ZtH^TkSS2Tn^Y%_hNb1D^8n>&*`so9z9EO&rL_Gim1$T3s@XPWOtV`p@XV|0>SWelA(;~Pp*rAJs&)?jsG>LU)mJQh?DK;D%rh4bKT}_5- z4pU^S)O%kujtd@LRWs|>ohhj>UT;4s=2ox0X*XghyfgVZCUk+CK+prCmCF0v#|{E` zA9^9acYvj3GQWTN8<(5{TUEqnxZ_WDiZf!@)au}r>t^C4{3t|#Ylky`_FQejU`>*G+93BDG1zQj}R zgxpm^QqtWDE0IiSz{xid6~{IxfgN7*8@uI7(f&gNT{9Jj?SyDl&EAi1li!nm3k*In z{Ai=X&)C|o+Iu-BmR=+2EUVfzaBJMds$@!X2Sj`cO@~%FHe#J$ z7#L)DdIcDyqVy^P2Mu9B445hRc6ZMBrZ|dKSo`)WDO#_R;;9Kc_W=UkZ+_YlYB|`| zzrOfLbRC&&`-y~T5@_N>fLH97LnRlSzCQUjV~Eo_&KNBeFA!>y-#9hJ-FRHsU_$V; zIi7hxy7!WvqZmjNh3_=C;!$2ZM93BMgFcdfPXM|RIl_w7>KduYz-FfuZopW%bj+*J zo+(*?%_S6n=4i=>l}_wB0J(Jm2pBBt2k-6tJX1+YKFy_rQj)gb0Bht1^+-EjChaO6 zn#Tvkh)o^aqR;e|njl=8#p5Rbn+2+_$%P1S-L-Yn(f_YcKr0yzRPuE|v1jmSLjGm%z-YJ_&b?ZTAuQx1|?Ctiw0^P*p-Wp8cL% z4!EOISS?;xJC?m5-=o3k6yFm&|GvkKe9z3~#ET)4OCMd96qUqjqu!+4c5IS?4!|nq zIOvt@SIE^lT0sa6w5jeNq;kDG6bK{<-t#krfq0<+`tWaWtepuYM{d5u7IBe?noflx zb>)ZaNU3;Y6r#ehp0pNzX_NkR!#bT02J9QD=`+WOm)-C2@gXdKuR9JqET_eUnXIO5 zopB>)xSJk};2;^e72uQRlT#lT4_c6L+7OK-_0`fw;;OCV{PvvPN6ns?YTVzxMG9m{ zY-y{=q|6-wYOI}L42zwrxH5$2V4cg(uZu(TRG7SthxneAQ_|G`toqJ@W+jb?DY-;{5*nT$Ojj8 z1$clt1DAO&s{;P30 z(V!B&@u$|d9?_8lKhuLnGN-5M_)jbJ!FSYTcicbXq(&9uwEviE)M$D@w5$EdRd{d* z>Nwko-_R|&{QDw-cGd_OTo?5NE?{$Zey*8XPKCsDGMIN+?gM2{xm_S**G$CHtac^=vowh#;5MRsg_y}2>u-kPhb?AY)we<)%jzNf*( zrWiKSY~{|Mqw2Y1b{bOuJB}6WnU>q}B?i2xo+grfe#_s2mA9vBW1AsL`$wmANP@0I zU_3Rt6|;EIWC+qzO6Q>l8Qzjd%z?90;QaX=jvlfEZ6Z!>BsZamhzQMa5vk%%-Gtr| zIchCS)ZrEP^0S!H7jF<=)VaS#~~Pt%S?Tl6!-F8jZ6bxffMxCTgWZLxN_+A})YBTkXs;GwnciPmHDkK#>UVQ`p zXBq<4tXV0}&F5_UIA`^3G=AHIZ|+T!Ckyv)m=GC>HT3!hUS=wET$$Ts-OtWC=>+&; z`5hiYrVT2yimrP%$)b2lFI58dggRKEL6|8;de*JxFm9Bt^C$c{Wh&GH7|IDD zfg48C&|h`=i0^tJkaFGgIo*8Q9{Wt0g65Qm#D3aIH=9!&zPv_)JIrpm<)Ax)&i>&n zGMTBf!|6Ek;b}Oh`t`|+*C%#(8yLkYfNCyD(Z>bVgpn3c z|L`P)&^RP1S4x(Ctf9|{r4Se8MN5rzK?7Y8xkJV_fxQQY=;%JuZEf*;hc~7!h?g#J z{p(5?31b#ZW-Ih=n(jY}Voc-;WZv)B5d0&XE-)*gM1^zlb^h0ryX^glAK-g*9CUBT zG2iA>M-7~Qj$RdV+ZxGS>BC*MTnAR7V1jnEZ2Jv8X8u4t+3|9Cadr;GGBRP&ldp$m$8xw zwYs~;*?d8ff^t}5{zBR$U6x}cy00pH;GE%fe!T?}1+|`y-{lxzI8o;#6#yC{d_D_W zGAD+#Flc8MD`3KdKwy`<35nnzibb(9QK<=I=JcsP;hXY66CDQ!hlF6_25>@AVVpcj zSTcEdaKdYI$L>nOCWQ_y8^-j>D0ZU$c?KQ6D;T+MCuGm(yIbJQl8sRy`in7Bp!%jY2I^QJK`MH~08MU`32~QD`K2L(6&&j#Q=#TY>cYYsHm(14!r2y@1 zjyFEEJ9e>DD@F1Ix5Apl-v3PiwdK$d-po+AmOcgiymkI>(|>7XoQK4H%*FC1@r~cxV-oY@e6vp%a5rGPy_Wa3aa!pC0cVzau_uLdgYoeQ{puJ^N1QwYG99z& z!=IdQCQ?9!?`z?t=$$`B<>bIMF{ly#6o=isYexd`L+$QFQsS(+1tlf;XrSmAjq14% zQUO}_GaY-bW0D~!clqIc&(x@r@CvdG6fD6Y`ZMbw{+rJneF~zOwOSGJnI>N|;)ZtV zcTtjtbsvUh6pM)67yA`Zbur`zQsrU) zz7X&4)_(5F>6RKAVxo6-tHtjRb6QGe(Z9*d$ywD0R;If{_cOxAUGL<@c)&9lfjQJ@ z6axPgZSs?f1w~{E)TqE8(+vW1SI=EuZX8}hLA+5g6Fkus3jzd_b(j5hdw_ozsqH|a zP>@FP;oHMX?AK()klXe>k!@!IKut?eOIrs}6eN=2fIa5z!y|qo+n4Zy5=SFD?2?B)C&1Ca~_);eGP+DC1@N3!H1oo*p^#5?F=*rH_nQxaRZ< zMDbb~Mz-j^xqlaq6`E(yyLdqr@ap8Ym+cXuZQ%XED)(6!on*24wDSnxw09uJyk3{3 z2vZ?di|jlY6QS6~dO`;f!WzOiKL>1}%sIZk6Y`v~eF3o<*G5{pWNb`+u>8gX$UXg= zG*RgpS%ouKuDqEa3B&Wn<(#OUTPcBoof=unM7Ifem9is)E4)~cdU-L#d`s?PPhZoL znfM%`E3uIiw~d)9W*NodTRL-xT+uP$xFO40<*3?Ptc)0haxJo`J+J%~d)w+2NyQ;x zvI@3I@5@f(r|7K;)YSuAqF)e4FnYSu zeyiZmRq5VTSmpYVinW}JonZU z{U>*a^ueTkcW_omM1vQnR&gx7b-eL!oj@|$nP#R-xrmeU^`l$a&j*CK*q zh|^9c*TImr)uQ9-5{nBIbn*Jt5nw+KT|X{Om`BlMu;f0tW?I(ERG5N#3ymC133!VX z(ryLB2#INht!$pf;^Yb1*@nBz{U-K2RM?on~R%kfmLg@+}1#Ds261Bgk&4DGKN` znzHxSDUOKT0#iB5Ar$kZSkNI}2l@k|_LW10UdQH|QpnRSc&)}gXG+w#YpK=#*X`;? ze1!II{!X!Vu8Cvx!<+@w>QP7eFYsZ-{+9tYq>Y~qwP=0VNaq8dq z5O&V?Ty|kS(l82SvYP$T9|3z%c6RpeBjZ=^*$Um>t1Ircr(M28gx<-CETtglQ}PgX zHm9d6e}4-2-d?FJ&rJs3od>qB842lnIItQVt&q1XXnIg(V{AFieL3k}m#o?3lP6u` zPcH6MX_KlEa*tomo^j8_tn{k(gcF%ayt)-m%v`mw?;`*PHuk~5g#7C?k(6hcG&#N1}!+3{h+FDteFMX4&wA5 zJxVn{R4OXwq1pVH5X@u&goYhpkBe>Gej~(eSeFD)0-&WcC9MZx&F2%n`V7}sIPmeF z3ra@$0j{tvmtK#~pd`Fd6LwJ!%AZJ;A> z!Zv+0S51ZFr&%G0K%J4Ur`))dlT}43+q_lre=orFb=hxuE3_~4<})Gq9p+oD&<;n) zlaLKCHs2QH%nP{=a#x0|J&fPB>>#dDp#tjK0J}Mzt#A)FT0;uSVr~A^oRna8!3gyOqPU!XE6NlsswTfY0h#0rpDLYHse562!60$< z+;o#afeA-d^}2;pxoQ%&}`kDSxP@JZixk!SyZh5`t<`) zfRVR~Jpbod!Sqvn9iEyNL~Xc2R^P9I5G!h~_a_Zr1MaGhcy9{oX+(si1hJIjhvJ@I zV$o|>)Pl&_Pti3)wkkd}VUUxZ$#ep#Xs6W-Wnsa8F2B6PQ&sN)m6$rf4MKUa=B7fA0l{wICJ15j z`FVDb!exyCH`p{08W1}3FAs?<0KY8*p=V}Cfd3_oCaajv3!d9Df)j08BP9mGCDz!= z7E14eDR(Rf|FHI}N4&hi`6ZJsH^dyZ=%l1i%yWoS$nu=pC9BqNe(A8v@_l-D$>h=bBE-Wj zeDjB2OZ#0_T2b4G?(n^<+fVm4Wn89V5fNVi?sZmHE~?;QeCkk0DaP_+n)`f78J%P~ zMqRG{mio@nV38vI!r1S626$Yc{Q%}pk}ThgArMgYnSA;gSz@gl`=TFt61H4}Dap>m z(|_@i>3$q-t*~0XQ0-RG2%j^rfk^IVcw0e^cKx-QzHtGAhH-YG`+~Ja={@O!fWIgj+fc>1TJF&HdDSXs+=Pbd+<~_@{AoY`{OW=$M#DSK4Nm1rDX^ljCYT zqL+C;MG9&Y6ZP>qF(-bXn=jmEx1IzQyj@sM10xr125UNuITUekVZzGT8YB z!lUD=4j$wz{bFWH6W&N(z*y>z3Um%O`Qi}aRa%vbhE~%s`CM|plUQ-6^C%u}$`j#N z!K1P$;L!uQLqJ*gLI(-tsiR0v`L9$fEJ0ZdG zVYm_TMsyKqALVpXVr)JUP&3mOZRsBK!V%Mjd>16?r4W(BU}d*RD9_I0xGC1|9uL3tdoPQTU-kCk~(YQ9g!(#STIl?dyKL+KUr= z`t^1789u&;8(xtqpFM*F4Ji+hzWI_ZkN=p>DA48JVG!}!-7VVC*=Kcyjm`zMRsA{K z!Z7mMX`|zQc%Pj_RETMv-FLgtlnAOz&IbZP!$WjiUZftY_b8m{qiRkbbBZQHtSQ;~ zGim9)%}-?Ta3mN}K*w%6;77a|X1WKARML#en?UiZxwrR2>5ogrQ%U5a)spNBw&1US z^eh}FDLY@T11vYbl5ueX_Y}nw7wq5#<<4JRX^Jn)%BI*|6kEQ$B?hA$ftf_fH@4kR zNOyRfgSYPRzo12}9@(oO^?vn|x6q*X;`{9$s>)n4-KXpBJ}I4LmRDCBW5l3F$e^S$ zu0v0joY%ZcvRpUCR(&tO6E%z6w9qEcB4VH(sT#N?d(PI6Zv(-X7^5cNvUy2R_X{BV8Q&mi57!YV_8aYvYqy*xkaG&z6aT)~V? zGK+&+)Y?THWst)IeuAM@Kg9WZD-2+;(U}5Xq^Z&;zi~81HA?`q6jIXBkgg7CdH;a`HMk%7$(FQz0_ zQ6D>Xx?PF^Yb;qP0cEkrFGQ&Jbf)N7N-QR})MCU3W4aMxtq&_}>_^+qy2$s!PKD`J z41j_jM_UHU0LF86w2TS`F`+?>VlfQj?`Rblxr_=Eb~YRV!_tPv?fw(IE21K5lGnAJ3iZo++ zlC{!q-{44Or)|HyY*spKOlqUYDld;~RAQ ztUVg7zP{YL+?|Gxbv}HvZ#(AIsxklwC;PA$o)F9=9|Zc8M{p!*fT?N1-}fl@ z!`H^UX+msN_3`>sNiI$K3}72Zsid+KqEW9Z_pAQ9*X0>=cXDeF z%ON`l7^xD=0k6H@u7!;5rwd~OR=H(X-(c-W!yXsc)qWuXkIknj?}Co1U)zn^+*yik zP%0%*^5|$GGL;-bN$5=n)+4p-@cBl$e`}Se%A!R*_c2dj#K>?P(|7IWc(piw_BGIH z)$$ew?ll6KC|PppJe`RmbzNX(Kp+F)<=E!zhp{A)S%NXua1Z#w*P!pAmgO`6uUpN) zbHn8mq3GSLG7)cp_X`OpV4i$5#Bf-Tc31!Af@d@oG`(8?ae2?usCEkBxhLbm9kflLC|oETe+zu}XTFh2SPSNG6v9O0XK1RO-ujM_d| z@*ToH$pUrSg9$Uc1rp7a=(>ti_(FQlL*<%g!Jfb&KXTLzgzbO0F^k*`OO}3B_|7Qv ztseNZ;0|+XQYl4HQO)~8!ytok+MU91?v^st6#cK}o=9D~{p=Kx@Rcd5Bii()rtcY% zBYJ;;(Rd`04Is*I{CVXnZ~;01`B}n{N2fS%YVSmbcY#9XD*2h;CO>8P&%RNN4}y~Y zAMWNPO%(&T=5d{My&t{lZ}Cc#d3@6wmT=r`k@2Tfw+dQyS*>S$7pITul9st6W#P?)g zhJem<|8m;}eO$d21zc3x3J=K3N3iDcsSxv>{1+i3em~@F9Srl=aQr zit0HL_g>d{)~Re|NM1nHsSnh+{@a2ue?aJ*aR0MMsjBZL<7v6^^8?GA@$F8gI)jy4 zhnjJd?OaaFs&%AZWzlKt9_hh-AW%X5zTcD-=8oC(rm_#i;emDSeont{)K&j!K`BSB zO!F%=$7J$bV*_pijZ*3vU?0S}U42wKcX;)ua-#NpMO+;jxGs;EM6!|puE#5}o(LEa z)7TCy%fWcRlJL}s>s&XmkwdUU%kC!D{L=Dzw?ZoU36_A?pDR*L#PIvs%n zU?LdHbZb{Be3v0mKmV7Q|BjxIUiGuF!%I3q4Sx1Z##y$@$rf_QmZ5N>yCh^#bJ}#Q zdN1Eg9%&XF4lG0Dd%Kle;Z6Gf_V)f;@Oc9TSdpeYihuKh9^>ejL9|0jm_KDJRmvy( zxLJO(%UjRehc;yPyOW5!UG0)Q=c=GW#n1jLD5Y<$dRTmQ8E@4X`y%2|&eLEyl)6Kx&<1{=b$iNqM`Vedqgj-YOkyg(8&l38Z zBp3|Ys;8S&QiA8FKZqOob9HU0@IKP@7kzS_e4Y-owyweN&t-gNb5eShNM;`ge$LVg zfRYuu9xf=#8}S-wBHcK_IZ@c_UaSY86uU*K4}qtF>XZ@nT!iI`gHVgu_#GnyZG|Lf z`4YIue&Xk6KVU^YF*hg2o7kg<4T&e=YTfQqWDxA6AgFaXsxkJzj7*fbiKbKedkBo}}%MPq4Bgh+h50=yUKI zS?XjBZkg4q_bxh+qW+D}CV%ryZGJ#6YVT3_=&-zX3+%upB&381kG~h9t3<0W4#BF_ z+6oh81uC>I|5I}>b6SeiX{^t%0f4rhY`jHg{B2IrOZVEz^(>%sSv`tA};~yF)B|>+FcjT#xECQ zY{+5dd%G!9g3*(N_74MNH#ZI|td_-e$E!+gANx&XTaLQBT(;H%zGR8=*znow(fOay z%tbk@-WZ-&E}hma*clbVY-+u)*=56gcU=NhEAeXGMtC!ayz{F|cb=+(&k<|yuT=)T%0Cvkjc%&P9Hh%w?(LP%9&!`8`QH?=?XGpXbAjJ=9<3wl z>X~GcXH$YHdul>Xi<}H%4MgSQ(9eYNX;PadsjIf|DjN8!f{yOEiDIOyNCwQgbk!G_ z{V~_u{7WtzCjOxH$gOV*ag@tC^S2^Y{t0vSIah1IVou3xkK@l)GUjNQG=bRTuWZ$L z%2FlE5I9Pw?53mc^iYT4V{mbJL{BJIfHshO_WsQ$NJy8#~y#Jot14MOmhtl z(fU+vM6>sPTV2$z!^U!VH$5Z0zjobQbj!+;o-ZSfKY~UH^&#bPC~@`;yn+gwg6v%+ zc0yq;@0lUz!jGiAc$K0v14QUs8VQBKJp}{EUqUGY$UK-se=~k_ou4%)lbG=8`kIS> zTD2^VF8Su%pvy%(PWmIwZpjbc2oOosktaEG3EhBz>zxy+kY})B5pt;tyql?Dvw9IW zx;o>-!{b$s5}V)tl+vyL-JX%}it+0;iDl^=?mlU`7V$N2YF!&>=8SU4?nWa zo=Z95iaKnCHqM;b9m5H}eP{S|T2NgwH_pb2^aIT-Q}p7`+|z>#;Du~HZFOC<&x?uo z>*)B?t~qD?kQ%V_F5u;@NlbCGMKmjGw! zG~kuuWlr0EgQx3;sLy1yH&&Ff^X7UJuG_H_+>}wX=(1X+sPLYao7hwm(L9D)VbT)1rd;vV&xpUq5drVEa|@K z$*e}e!Oz}DlWNyI`>i}qfkqCQd7x?O`|laTwa#Z!1F_yY;BG#;nw^?rIQLOqV8E%v zencAIQ253sEO6P|w z_?d4k3vWKiw5sn7=Jgu*&wSZNp)o)VMU1-Ij-sbH__PnfP)8~nw73M)@d+eT4Ak=J zgCv!I^|CdM8fg>9KGWaiwf~UJO9kUOBI)Gc~SV4_^24-k!71YlTS{+C^X0sZ#_=u!}il6Nk))c9HqP`C4T)_AB2+&-MaBkG!Y9 z;qRf^q?e+{RM2EHy?llM*rAg*>#IJeJG1%@I~utUxQOV)E&SW<+~TTh6No)|z{&|6^uX75(=2O<^jRG9quue`fGJAnF!0(AkLJWd1NIaIQt2*(FQpD02a7Qa@vn0B?iJlM|H zIguP_60Y4!GoBqw#V$k1x?b6I4D2F+?&K|gph}AfK9GQrP%%F``fY`X*9CQqHwi@9 z+hx%td^TmS^M+>|MF2|%Yw?>BU4F@=b!|(Fb(h;?bNp1D59C{``|;vw=Vf+)Z~wbk zVQS)o8nZ|DB|j_I$$qYPh$lkR#*CIF5W2m-m;eu|+ch7$VJ9KKeRNp}JrvTX9Q~2x zR)1u@8?)9uJVsW&vF;$gXG&v`Lzr{$E**#a@C&gRWTUr)otF}9y2(!q2#iVO-~ws? zQsRs;!DHDVa`_EJQFWT+C3zz1pEWCz$RS7fI6kucjvc6a@=f->y!yPB z1jK_buHWLNVw-f1JLA-C!b>Y1-v!Ezf^F+iF;LJ~=LVq2+v43rk4w|Vl+ya-hV1d{ zcirDdt1~2Jc^bZ{;YQAMytDhK56L^%^`83Dgk~&JWJH(h^ua9(5g*Uj z*woHE?fzco_ccN%&gZJev~0ut%Hv2J!GW(Sl@Wqr7@eo_W9CkVsYS!sjo;90-{%}9 zjKJe6des5(_k?+ica*l1v^{E(u7X234&2|ES*LX>rXw2vB1?#-n*6FxRcDZ4O;yaF zfdeYur!r_*dZsA$n9?POhC27AD&_=Sc2UE?q+3^I3=;@D^vrOXzT;niC3>M(9o3lh z4(#TLr26@dG>wt@oz&l~E@p=qKGCxa@N_{5FL}(y-oOQaB$t8o>wnf|)F{^u-vVfi zM(E3aYz_fSONl`;Zcf1^>WUSOplGs^g}aRpiiJt-PdjXTcjsHn9&3L1MQfd!|4KX@ zam%mYdsJ3ym3#VUsQO=2x4!%-PtVl{iKfb9{{Y*aA%713ptIO-YGu8&N9BJtq2 zg--rma#?^aT2-!X@prOC_Z;z68h1=*ryFKPRrNi;VxK;-o#Ngb zm{_<6JZ+H$oB=Q}6k}5TF2PjAd!Jl>9+OzI+?rdlvzjwQ&zb6{y5|AqHB2zmLW9ja zrJdjHH;YHW1R|c6L%mp>RDNAc~D%fpiNsyp8~V$n2tG<7lm!!m4GQVid5< zVN5o4bo@*nVm+PNV;aH{n%a3qb9Hq!PY(`Gf=eWjiO?ztIcg#1cWf@5`Bq^pMlYv@ zHe2QM0yTPE0QlTb5wU(*v3^$tD||A*TPf)5pzEc409a?X9egPdt!BNsa=sf>!`roT zGK@%wXn$T-jz~gZq~?eTF@39KYMR0iMj@tgH0T9q>o0WJV#EqNhvPt0FlB(PGxS_T zbTGKPzg9*tL91YVvj=WWHi&+zu-=BfxK}qZ+OCLNk!HrgRze_>U!|^HqYC=8&0Tf6 zj`+4wEBTu;2M?cItCm$QuM(AgT%`8KZ*JKiVbrGt6)4v4b^~6SvS}sNvQ+glY2Hi(6E$@;#v}q_`dV+-xQ#%Gx&v-79K;Fw@Rq>E zNHk8IGPwI%IHM9zH9FSiY?3NVlq0Yf58@$dJ7`jWcxZiUsK`fdVIjQu{Px%2q#dXdggiy|ay#Q4rrvj$m6hIhx`P&6~t zYQ26w`v(LGOoOaDp3FjFb1oUeM$QMyE9+M|vD@{(K>#$(DCyLA@OFxiKclp$rKavi zwm^b6bB`lIrlz$@3lTlVVi-$MZ-h+Z`yp-g<`XDkfrQg(A;ee zAhL6{E15=j9m{YP|NGK4@1?W!Y*_;dc(7!vi#&-h+%4g+G;N>AO*MY}^YBXqnTVof zJjd_2V!h?*qH)!4et+4iUEB0x<;$6b#N{j3;nDRJxGDuAl2LVuudq<`a)8=({}Spr zXXtg6#kYA2D}+vmEWjLVg#veCe6~)WQChDL38fNXMG%TJAW$pYyJM@BgR964HY0J=?>*GpKT5QjzEN9Sm1Chx~x6EqUsw~mC z(aOc2zjZ0+qa7#hC!_-F{hiOlofA%Me}y^BMLr3sZg#NK4V^`(DAbx1mdvO*zfi@> zkxDi${Z>k3GyI>=xcJSL?6Z_A3`ER{hU1Wbt_%B^IOHb$bqXXS~65c$&(EZgGqcy zRRoYMRuKd23K+7b(a}P!4p0WlmHxgHQeIy*J9iz8!Lea?MNg~odaFcHUmf5r_P_tv z0*rmSr(EDhmT12awkCpXxD?5zq1y(3JsT3ue(>}4F^|H-gX2Kthp$|hv${3D&v=C8 zTt&u8!nynPXbO|l9(i8qswm(o&6EpxPeet5*Utf;O!c(!EHkEv> z_obN3oH8$xl#33V44kRm>R8+R@3-)h1zCR1B$wy`auoy)n!zYf@w92Bqeb#3gn_1?$X^|0mFdaJQZd^b>QuG&Q`KJ-g)QaPgv#-H;!Ea)soX*F!qrnBhBK2-7Ejfu|)s)KGB z=5Q_tZr2?_^_d{KcxQe?OB+i^Y5CDGm9>g_J1Y8@+oE6qUv|wS(HQy}%T5TSlIyQB z&N%Re6_LAt%R{ZE%BGXEb=Zu&CVq9+oqREtr@S>T?p4{^+NT#t6W3h^pR3F|9P8z1 zL4FF4NG?&0(PrINdwdXZ?mS=iUds%=@n7qEJY4Z$$Zfax^E+=jS@Zvi15ae%L0@q{ zk;(D3m=cbAe{$E;m^}0)10bNEKZ!JNi>xDjb&q91Kwn~EVeunA@K96q^pA{=5CsV2 z=jY$|_?V-ufeW4Lwo!qCMfilMSyItE5VWCn6<$oC6JAgEv4U|*WN|13bUP0(>@5<~d2Rl0Rzt7i)qqg+=1C!mlBLWR1&!AUX-5|e6CfFf`@ zWbhUJw(HA}+p{Fmq4tCO8RY5rTHvOa=L|38+bI6`$*vJK982GusP!ZA%zXYW8`Zk= zEsbC7?iFJCaoC6RyKF>Gi}IY|be=i0$#1(;Nj6TM;0V_)rP&WxsjvFw!L`nQ*vUIqXtny zT)TBP)#vhuZ=Xx8D5ShIa%aat&i*Uyl5}DHjB}eSdU7ObA)|E{>K@aMF+4Q`Vnz*Uc?G zzQzY1Q{s02?VC3ZtK)_sB0X3f4^p#k0aev}-1tcHFhPVT8_87*E?}H>pe@25wT=cg zE0ftCpo-7+{=<-E(?OOpqif@nIZLp88M(Q$GnS= zXivXdUOsM8>@DxOGCuJczglHomL-x97j#(%`|~W0q-Tw~To6gT+^jraRpD3$q+C`T zfIUJ#bAVXbNGg);1}4ln3(Mr**O&~bS1}S?aYYSopRZiywl?29+)UXCoQdUGsBuCL zLfnWYJiifjZoCP2_>-G5tR0%t6eNjr+f*5T(2U0Xd5STP7J8^P9cyOomZjAXzUZ$f z6LR|oYFA`PmT9Iar3yI zU0IN+o)HsW|GwytO|+vO4FYX3UxfJJ%4HgiT-gI_2Iu@{o8ae0iA+e+!T(-oX`J_w zqweD*nDKPy06OK1&qCczZfjL?LALJBL@*`j^ylzUbk^XFnzWj8WLKAYHy2&@^=Tlb zqeV;uvHj#+K_QwvL%-kC>oPqf(B{!xIXQKMo^8@~`h4)mjn`jiqz@0sGT=J70qC zg?Dy{T*$DQtx87azk*T}hqVv34Ov}nSQ{v>$uj*A{mrQtB?BKNZk~l)_Ym4cd6p|d zSow{;!VtU0?0KiP>V`7O|7OX-DH)mBxUU0WU*8Vm0UD4&uLU5zZP}?ly0UN$NR50R zYdsPA%7rrSeROmDB#zX@*?FHnup_@v9mGCY2V`l z+b-f!Qi>+7NCYi1p_k4dgqqXE@Y|5<&tIGdm|9NRCaZp-Cx>t31uu?IFE7hXVHdtC zkE{QsW#?t*_hb0x2-bPMuR9nyeRDCN_qg&H9ek|IZ`}Mc)b~A}oN&3(aZhKgb$1hv zh8iEAPPCJLp7)qNe!Bbp#-iwxUTs^0nML+x@Bt1re&qqo4w^2VFPX201W;Ps+0yK7 zR)G&-gq%&&9_xz&e>!9Oa3TmXLAvX>_G}11VqTsZ6p;L_rQ6$r$?QsX}iXY}KL7Xp+4;wc1=p<4#C`HM@A) zgl=6Kq5KDjHLE4}J^eCbVoxD2RmlRs8C1YF>8k4cX_A-(?Ej#b zS7TyfxemtV#v8eA6HtIXov2e4SgQbzy#|67)<}lXWghCsaRe<(v zQdkZo%WwJ*pfZa9*!o81s}zo<12?jCJFAe=LB=s|LVrKn>_J{Zo;iJ5jzfE_9{%WP zf@gTRM7MLtb*i$;C?jf&M&hj(TEcMZu@$&M6}s5$;TtBEw{_i6?jk_m?U<%`dwy1W z`|5iuhYST%ELQ(EXw;;Ja~M`w?DObc+&wdA*gzdPV6sx5}lFxUE;WnG6jPC zagw1&=mM*cRTicDiwgd1Bf7n}nXcVT7UoWK-z2m3fRR$xXqw7O5<#<(>Oc24|FgRy znK$t!PdBPz=XT(M5ullu=bMx*+tvR-+&$jgn}oSpsF$)m231VnKN37ZG>=VYIa+Sd zdfTxnpP$wsQ}S5k;(cEvp7i5Hum2ZEE7`=VTBi}A>X6oJa4H(EP1|#8l4VyYRZGqg z9;owkD+0Jw!*~BogENZm^zZNen6I$7T0c|IaUWTKDx3X70w76mA>muCqkR9;mgl=EH4nZkH@M)LHpfz2igK*T5fUz+Wff-J)Uk1!92!*pXL zb9#o=3e-ol7?33gR~XL#CNeaxISKCT?r0j!0TQn@sNdk9GoRZIUK{)C8! z!BnJBR10iF!bk`X|L_3FPOn262xE=8p(;o7TWjPfUxn4 ztt*5nO5xs-F4(2VP{{2T?JnTCU~n~cOG7`$%J2SiItX*Rluf3rKS9IzbjVl3$L>Nt z_))&?*|W2I=F*4}Yf7Ix)G$s4PhkxEv&guY81?#ajd%8Cdfq65grRw3E|d5LWkM0- z@KSI!sZ{&;t^?#JF|p_;;48(d?)+8}Xg()`~k?ia%*OVSXWN9}02gPe#Bq<8qxy4P;` zRAPUFeq+sr@~OS;X6khp`}POyViVfe$Fl^277C|&%Q$nZ@u%;c=F2Ohe*3Fks71<+ zicKMlX4A0r$u&DAuiJA4>IY-{P{*(*;Vo(jkJSZb{(~ASRm@4UxEK@B8;64Ut%c)o zn94O2{+eq=1-ORh1+DSB+4kMUtJV70@dh4S{W8j$5d0_?h^`+w$XdDf>u&A!k4fAv zOp18Q7%CKaqMrS!XYyiq=caG%CnkJCR%y{`>-8n$n9H~tK?$h_=XWn&r>YK)A>|5x zXE3j17!_@p{@%2r@MRXNuvajo)ISsJbU;c<~kUl#g3V~4Uqxd zo_n9!2nG<*TJ|c+<%@z1X^DT$cXs;UYETrG3Amg`f_WuZhxX#)0^s>Z z*C`P(ZC4A546Zy*&#STJ4)F-q5EiXqaN1)pv$5&i_A-ihl?Ck;0bD~NOmSPeVEZ4~ z-e2_pJIa{df!N|y*T-w%SI45Kxl?=7B~HP+ArIbn9ph7v@4d;J;OOwv%9nH1R{MD; z*YO*Q4NbtUG^YT0%K2hmC#47gQhR4+>T+{3s@-dA3&iEs@`q`kbZ|)u2^|D16Yk)yj^a-oL}j7gQM>#5O8kVZ}Tf4BV z@af@ZwI*=B(%Y!Rf4OH>f2NNYH(9f`uz%r1&wlRPVN<>LKugLDi`7snk2!wQI0A^E z5ENK(c`ZB#Y>{Dt!qUP3qExEr@v_!!pxFHqyGoWB@h#aMj2RuR)OHg894hd9Y@Y$i z>Y;hhm#R=RrjC#+WxvT;W^4?}t8n2&WaTN<>5>fg`9ckIbR#7mZuM!_xYIAZVRnTv*6iDLq! z?{=(ODPV* zS@l8A7c1^0aSY0wh61Ra^>AzaMs21G_7TU#j7u6Ngy?LgqSs(zRvnSy znCQ7tz`2t(HQNyFCtL42@5+>wN6f-Lfl%r32e70hg6qa;5e>9p3HiPb>EHVKSDS-s zdVdeqWXHx8)fp3EdH(1w4MEN^@3JfUm0JI`MRQ06|FD2J9P#IZ-22vsh3&}rf}Q{_ zn=>$UFkNYK>M52e`x1FJm3?g|Nv8K0m0N7elZLEo zKeXD-asdEzi`n1mz-~8HS`Wj>f3?0qZvcZCD9S>6UmO~j_3Zn=;gnl5XVcK{Nf{Y> zSrxM+utFmvI83C$=|E>3=;RpxmwvLw(+nQY(zWKvNQ>NF;(CMJchxF6 zy)ZyMGFSD%%F7RB-Sd?q{)hcp5(7AEb{>JQN#ZA3eYPX7?_pv3J3H3EhlDC_Yoe0R zhTs0Hb9w=0;7ax z3*naJkOO_zGO}d?!_JvoZm^JtfS7(>PGsh9+v7ap?)JydzP{4(Rhxdb>OdcRT>@r_ZE(?53Ng5^XU+~^j z_45Ns7SOm@(!3glPUHLeMJ{n?I%H`V76O|Be0enFI1Q%M-e0pM?uTH?eYXRNNo1=vHVqS`{%(+wO>xgPZnB=vt8Hv;$JDAw9A9845-8S zhV{SCSt!3($sPrsCm2lfQ@`e$_kTaN-2|S{M-@Qjp9&H#Ew@R@Oq3Y1gZ&cRB}O-X z*DGurxs>=;@YUA3w{7K~Y~BQ)2;rR(ysiZ|)ifW5 z+@02&RmPi>c87q6O0g5a<12})B;}4v<51eF)*WBKjDo$8-SHedMq^zb2eyYXrRFf% zfj@&H^Yf*=4p+vmkJ7n#cvv`=8}qaaX@4U3lS~TT;f-3?D4JxLZftyyj||C|g1H~~ z_4Avamxwf;)TcW%_d2alr8am^_NkGORP1D9+!^^CxmV=}oAJdOydKv?+s4UO)oI|X zTc#G~{|eP8{TikLlYIH}zdbD!iPY|^z;b>g*I9yc{aOn9H={bN+qBZV`uEMPVtUy<3qc|I)O=+tvBaJ1NL-X;PD8VTyXK+|OD=QR8ptMNoO!$NL3 z%>kl8Yj;6VO;h#2MP(qCv;V^~FexP(<>GLaCBno8yrxqUQ)g%GU%L{yjo_^tsqW

    F#vkh5UZiuEatTqj2O9}=WN*P=63bKlPhk+j)EYUt7kq78=r&q$Ka~FQHc|iSm1Fw*tZ^V zNE_d=s9!ySa{+xB- z6%&L1`-h3A$$OdNmjTJl*U$$he;dByLs!Bua1yW*eOK{rR*ro9O0kF+s%Z;&OM!*B z8#Nsv*BlkHO`$E{GI3$4uARaj{SO-mpqXuon_q-~u)y28YiA<*aeschM~HF7-+dsn ziASnPIw-le*_`CBMx3_)ejCK|A!P0=?yr*cgG zM1gj=&en-W8@xP%lBUj_!dNh2;2EDZY8?rD6qcCi6OfQ3-XH~xcX=93N&N_@M1|kr zDzI#m9L&X4J2_y^yGzkMZ77=FF2+Jt>RxsQ`&~sv$Ke-&n@q)vHU(s|MQa-mH$i#f z6ag95Ww9^@q1%Mt;FKb~ExY^#jmc%hsq6-av~mCAdP)<%mYsNx<@)BiTz2EfroZgY zz6Vdz5zN&R;YSHwR<$mBIJd9VQ|L%$4m`b%mlRo2cL3};b@pfuZDGgHkL1(@nGO)S zb~l~Xa~XPs_;=ca)5nc(x?{1EK-+ZopDm!V^GF5Qp1k@pDpjO~mPwo%aUs_SnOE(o zdCsiuzN*dLk7RpV8LrK7eWo<7VU*C#QJU*>JMk+(nHKh2TgXa$z4`%&QO0N?xGbR- zT?ZqskNz74_yMG^>*sI^d=0@--HuJ|m#3&NVh^5o0jf?W65W-#_MtR{m4)vIxQXAw~_&|v6zfWoofe8916C$LZllZV!PhgUt7 z5_O)P70UO)lHo0K-~M}W#yp7#sPrxcxUF{>w>=V6nfc7Jc#!>lppZNGXZD#P8xNic zKr+iJGPCpk4kY&Eh>P{DJicdCRpa8W@4dVfot{o^+axlT<d#1jU?SFYM7y|SsJ1vQa}K2g2=Gsf+7N0!nOnlR1Z~J zxnr@2c1c&h;e|Ue`Nj~aP3VbcXvGBnl1=K_N_wCWQ09DVG+yIA;&vt8wLud8nYm!X z0vrk29!%o|ca%pMM<-zASML_*ds+~BS1Oy)(bUYaXvf6u9x?L>3y*A=aoz<)K{Q@% z3$t~I#@RpqY`o@`xQJq3=68;L1xS^Ol_vgsQMg%8otDZzc@HfABj35 zvOAxxQeKntzniw{nk-~=731W7?MBdXu<3_Rjcg#Vmtm@c~H zu^X`Pr6!G}vo`3#XJTpcWL(3amA?>9{k2Hb5im8j1ZNwKOt#{+{(jtTHv)NKV1OrT zngl}4T_63KgEVSQ3U|fno^W7G9NqpvVIs?+3(VrPJcP}b8&m)Yuh+RhAZCSv3J@-T zNX*|1fmp$KjaKFLg|XC5fMJ6bIwb^+T7G)^zTP`H!kT%waPe2FAP9^+3Fn0QkF+kumSKkMG?$!UU_JO#!!wk8>7b4tew=!!LdvtPgjy z7bO(6?&I3e;6;BoruOsuWSuGj2NFY1P49jWSL%t1pAs_F7fFu&>O(6pr#;d_=dN%S zRD0bjI0-vIXLKPW+GffI6)~myIn++p9eFL+E#*%bZ23h7%n--IfF#vY?So=1riI3* zF2m7ble+aw>-&Y^K8zsGn@XiEFkDUHD_@y>Yjzb-i{HXK$Vm^ zAfB_cyK>Qg^J(Hh13oMYiC8><_KB4CRsWKurX|}pD9pMr(V;U`GQzU<-@~gt4-&X1 zU;&ET*Gj|H!<%-hvzcdQV!Ob@=55p~rnm!mH3x1gB(;szbstsP=ncNkRl9yV?_P~M zbN#NXRepeXxJo?$rISm(oM`2cMZDK?6sZp*jHR7MuFtsoUbf4bhBj3i_sM7iE1NAf z9cV28dv6Lpke|zs_nF0#8UNg;Bc2HPpSx_$9!>2<^uHQrjzw6Q1?+1zL!wR;otuIO ze}yy}D^#=?df^9m?f<6rye%dC(wX9BCmm_ms*PR$R}NY`jqzw2TX20K;J9?AdC<=< zzAubanp9DOKy8}p@(c*|I1B7_+a}NrxNM#`YHa+>6kt0}51u_90WSF~+Md_kr*f|v zb99CJEb98NUZeM!h|bGf*fx?p{%u_w>dXDV=X96)cx{c{FVQ>GJ8J z^8uwQGk6ul^sz>bO!V^BdCl$O$XUPB{B@tjBxvyqIb4bgn$pdH(TD?pk;@_q7a9z4 zLBi+v2UYcQ0`^ziR3vA3 zvBHo-6EH9Fg*-RuMw#T^MxGo0#$fb4{D)!?O#mG2H(w$%hh9x(nnO>Lu<+r6RG`FMrJ-PoXsi+L{Rz-=|XAKuJ6qzW1SE)`pjxuWxrBS0^3|NcmO=RXQk#?b2N>rIM`& z<4Xt37*ONX@Wlm+oz;LhY!I{UtoxXX&b@o3H0qP1`^UBNknm=68E7x;v-F@s` zYMFb+F=X%fZI-%fgM*O8R*VWyKk>+U)^?z;3d#vd%qz~e*66oC-VmZHrr}k+UNHMc zh9k(5PbOdZ(YM(B*D>g3&3)|I)md9N-tvzgczEt^e>w}Y|9d~HrNlXJJrIJpVa-bg z`6czH48Jxrf4+qAPIuzIi^DoGhJow}9VfltDzu;v84JPH1PP z#XCK202AT9O45a(HlV4Mp@jGDsd{I>rZzeXz?<%JFcc zpG-RUO*fU_1Fp&hrfga)&LcF;pN)IB&2|>SY}zI(Nl1k zwo8JB8KNzd(PON9T_KBm#-UOWR4g&zc7SGCG~T*xlgAuq&{0w2W?l6%GIxYpoN2g) zk@ZV6&xk(o#P_(T$*UT0EYbhc!uJ-XvuR)h`ImF7VpkXr(ud<7X{XF$Ug~}zC1oJ; z+hyv%2@K`yU7BzJq9{p~Rk2`B)Q3Me=xg#To#d>TTR{f5~ zJuKM`O{BxW>#vXI&biIN>yX8l3DtY@m#5%+PT#>BEfo2Fw<8@T$MULv*5T+_043%PZn`fZ4{I_<2+%1*h);!WTi!JzkZ%dbX98Ls+Tajy)C%RdfG7Brg_ zlJmVKxV+J2#>W8Ci0J=+o{DxobiE?SD# z4F8(^sEA=7LCFk7==6$2k!%Z%jQY=8v$mKZf ztjzRoKlpZB;_4pJd9Ka*d|J`CT1*jeDpi{DUIRoON~QQwVRUi}RaT09u)lxMp0U4J z-1lFvd49^5BD9s_vA-^l*>rN9MYDFDe(T2{I9eYU2e`tA+`gqI**GeAh&ZZ@H;DJ^ z6?lEuX$`5u525^arKhI{Yz^b4oEn>VHwGmq-*>`q4jY0FijXw+|wP z814!L@Bg9yi)!{zT{VEF*w`y7r|?ms8;mj>d1Z5%cHg)G^(|CEz@?wWLj(omYI}=q zY!ok)0Et|4N+|+po;JgAX{3G9nu~wd+htIskFcZLspO3op^O$8;*Ks44ksUyVP=r+ z73z(YR9tD8$L6m_**G|TE~}vZL?T7>&n*Q+kEHgQ8PNYjBtd!8C2D}ge6jXRR%t0Y z@cx8q>~$(wI%X4>7uo(L*--gIbbSml_S{_gE7*ESOexM$^cck4*LEcLq1Zx|G}r4& z>;AJwO>@WC%-GwY2k)S4I>j+NHiINOOw3r#((B+Y3)4Hycohw{E3v)J6@%f@fSF1GMm5X+2@kM^FV z4x>Mv-})?1?@-828s-Xm=cpLHc@l|`r||!Dn7ImmCGPzs(RmK0eE0{C&l61RyiAJL zuCFQ>PW?JN>wC7>d56l)n~BHiHyJJduz&JUs(X@?qq5S9a1rb=x*<%^r$cc-R_VeAeFh8S%pr?^$iYC5st$rI=V6o#=EX`-iglS1!9!*Z-bKw zVZ|G#`9cOtjeqMYsnF&Id>xB_pnf3#U{$+jX72mJRBs5VIOqlygl5DP$0b!u;r$7{ zxZBc@NOHV7n&IwlByiz(Wo1=v9v%g8Qw8H0*{nBg)e5%Uat?aK!7>pC<=ogunYoir zvchERqN)%RANsUT*xapc56xbAT>{!G`?50N-Ye7-NnpE}MWMXPkNh^ite zS?>2+)`pfTkzkLlDINmwn_MXmdx)OnGH4(ZkQ%;|* z;b2=2mtJinGA#J~DEW;TKj}_SnQq#A=K)^cEvr+@nGzb18pfG>Q;QT$H+b&$hLD~O z@D~EPW+~}~4KO)C7X=N6ai^PHV;(mj@K?SZmV8*}9_x4_nzFM`o7ah4Vke1Z&|vE3 zil@A1qHk&CR|~UY`m6E)ZvsevT6YN6(Gd6LJqjwySs=DV0)DqB z1l7Rapd!L+#@gp+{3rR)=C2(fi5}XXuLWy1>H}{^MpQMASn=-7m(tCq%YCUW`Cpih zUp{VahU>4DyB+QKa(py6zLSUs^a z`}tD74fP(wb1%V~ws8nDj=zFh_;>&q8XQG3vC^tx;7V(j_;g{Ij?C(IlBy;4D}lli zZ2jbak4`sSk5D@)DUde&-gBt0b5`{3+A5s&TUz&bdN9}wXmx)`OKt5li;*RLGMrml z&s-Hcz8=M5oFHEp%)47bT|e6he0eOpxVWm;T5R^&Sovan_g&(&Mcx320SNQ;E^q}3 zxH*N-zuu{p$El4g(_0?X`;~R-(4VVuQgnLB^{i8ob(3g6KQn#BJZ<}5sx}N4MGfSo ze7N!a;AB32$aZH0k+W<*D_%Yeh^L$Uq^>MJQYgx~yzn6f-v&Gpi9-EWloHIIR@Xwo zm=zoAN%u`UKLYVUH3k1FX>nH5aI-%_7x<*vd*ms)j-xND6uU)qgLC_4(`%K#7ORq#Qk)i#@=eYs83ksZm!dJMI2tfmhg|;Wg2@G_M&-|n zpBf*`?5>gQ>=|*9>L%%GdjFiF-ATflJd$>ngv~e9D|Gg%bZqLEn3xmhrff>?c4k4D z`CTmL9CUHX9|=o|0Vr$?ju4Oz9VQ(Y8L8giFZWAlh-o`Nb}(nj@r$Ox>pN;>U41YX z@J+RCO+~nf@(FtSo#oE$zt|nk^(jyzYupoq^-Lfoi@(5OW@au4-p|Lax4ZHZUOKWZ z8WgT%uKT^TpVS}L@n828YF=Jp=cVRcXqKp+C8c-dNIcX^&=B44HESrQDAbP0!b`<2 zQ1^t(v$dL>@s@rZy}95GZP?XWq@>Jic;ff(pKo<*D{+H}OOsw;2B6z{X&!nghC)$VhH$>td!<^o&nnVXWSMi!iCL4LWU_ zRN_tkUiZ|En`Ch%6pU)4o%6&Onh`S@x|X>z8h&(&-RI}PKou{#NbmRQfwRAez?uu* z>({S|-Mu{WQlgmbTsIebh%b8I31}#wpu+b^NrW)e?W(yt|7?%9eZvmiHE_$9FPl|e zU8=pPPRZqhQ2LVHQc+?2m9LbANR6q(-(Y?3Q=u4)>m_URDW<^-gHHXigtxUn zc&)+(E`W#FeD-J|nWh~J!d88C)axpWBOLYj*wSwHB&eWPSfd zAbQwJgSkWze!nDZRKyZHewtm;KyMs5Cic52fzL%+Y}2~z$*h=@PW6+*1?ua)Hs441 zy0Gma86$xFc%)eC zSU+$w(1O%22}7y`{cc~8#J;<~M^#Khv(N7^*}8;Hr<}j}At%S2#-ddw`+NKSwsf4) zuYv6V0Os>u<_Qz~8px5$COtsI+ydhPhRBag+$W`%0f zjgafH3)1SD3hth21~8YX4XMBWQa9NtF2dV)M`RL;*q#n>&ZVM9vxO1Y!4#-pDYomQ zW`AZU+B;$87W^0?$t}_NXR@cH>2hlLwlcjfsecD0wjU+-UT!JNNmJk^O!Gq2B36`)XdcHyBH$Ur9DrmbWzL=SD#b$iO`SGgrN#w-L!Y#?KJ!npO%j3N!o9+jS zTu|8z`70{A?=m90lw@7IjGb=c-hOef5hj1M=iAad>_Yt7<3`-ZrlZRn4%DUw=^MW( zCoCT#g|G5BHX6Q0G{`5EWCi-iWYrh5_EItqQ0nRnT$IPkCRe2zAH$yA#zpT`+eqFpGbkHq_9i6ZqAYGyYt*jjA; zfsE|uqTR(pq5Q%xfeF`TMqUk5g3e;%ftI-Ur|4Qv?|v6S0}aS?5Jx{6QlKy$(I;0Z+l3~^jL)r zA1NCrCtjc9d6+0XF85!0@E*H^lLJ5s?6Bs)5r{(El~-}pa0Qd$V8$Q*T$1=Ur{=Y7 zRMS@1dk6^(*jT#Z72@l@zenjv$}BB8gwRSsiRfF+$@FCnm)X}Fc{z-77JqjbXLuVd z`=ib@VwdH8sGZZ4K+WcFAaxWM6yv+cbK(=pkpyZB7Tg;ds4f8}9C`jHrPCPWcYpZi z-Qb-o3i%mu>m9{8y>dmvrc@1L#{nYzo^N)e&! z1$DXpA7~eEfQ)t;+gZ{XJH9_j!vsLy-8welsQ#{a<30B?8F||EmLTC1F3?!(1me*m z_i3bBz+wq|uW z7bWaw%|Aiyd6qE)F!Iqw)>=gTAx_r$RnfbIY|r)-NG}JM*EiCmh1vF%(C)IPiXtH1 z9P>|4U(hb10yeH~k7lVzbv+?HU1S{B-f>xLeX>R(9je!@kg2R@N7=M&7?4s=DbFLwv;sgW5*W2;EP66O_mx$UiAuv-cK zxdc1_6Zyw5lm~BO7#?*^@26J^(Dx2AcIA~7IP`COWMozXE-D`P4cFy3MyO{Ovn5l9 zlw#S&rBjxMhR}IyTkl?8Hfdwxv0)u1GN4TBT#QuN(xT4SmiIbPqK~bq4%PkF_@i&; zve-=5#6$KB)7;kz=fkSwdB6G_DT#==+N~bEPNR#H5N~&XymGn{{{Mqc*SP*Lpyn@i z>VLE1U;TL2dCSEZPu_naCRs!}>oA|v57S3ZOFY9(8JTpD&tQAdL64N>&+Eb7 z_=|c1wyGFg^25dPq3p&O^o%mx@5KHInk*X+YQ< z3NwBoE$!iAV>qa}yI(H0uTQ%!@&hHMn(=N0efqFE3&9kzK;aoQTvBsSP31UXy=2;C zaef_sc*p?^3T;=iahRB=cLk}d7ii^{Z%7=)+kx{e)#yhScY>DqY-E45{%yB$vAMiZ zyhx+GqP)7H161%X6_gtM+)Z>h+W0~U{BMBXny~R%&1u#Mt?PX1J#Xuc%Tc{ga@8+M1{8l>J|IU;Pzj*lvxAh=78$bhm_bE6pG^beDu6 z9Ro6el=Ogrgp{;MNem<19V6WxGjw--kMB9}`5!*kVl94~#XWai*WUZu`z?1?I~vNOcJFX-FV}VOy*iV(Ih~Q}*yDX`Vzn;s6lec%s9>^{U+ErbC%xQ1z&jFdrPji^t2tVvn$c zQ|MD_y&@y0rhfk(nl6+5j$2Qr=d*Ek&)V4Y=jrva;36d|`Awch$I=X{7vaT$kblJl z6vbO%by6%7ejg%lyRej6k=ki53onm#s|_m0OrsPuJ&a5~+{p6bho82|P9oU` zRrz_YyMo9pajJAQDPj$C>Z5kbxPP8A0Dg@YdtAWJJ6{(!8k64>m` zqg$t{t%n(&KFk_k*3?ZRwG-ZAQclwy%hNS_kT&FpTNEe5Q1XWL3z!eNvx9eyoR+Ok zwDq^hysUkk7w6riSU+z0;X}lqc`VE?AxsfZ-Dw`l`r+Z@gV{-b>yFwBvy&XZQ;X&o ztpJQxgu8w+4#f!SJE$8t+|L=_LC;TydP>QG>rXB3p1SQW9WK{}&iqx{WvF6yk8vsU zlpQk)7x!k0a2Id za-Q#}0X6r3Z-~){xr3BpSXfd=ZDbP3eowgbOc$Ay2{FG{uPg`uz6g9MVCZ09%y|KR zE%FzM?%}nvl1=1fPAvRcTJF9{g0$Sfd!$qpkxQyPr`DVtF|6EX&82uV+B84dEMG7`j7<^>~AzUd-9-#ga@gN$Kx1N0glGk{&(REaR3 zP)tNrf>5W-SNkG-dg8QG)tm_y&HL}8#2$;ImtI#XmV&L{pvO~ zBca$SA7~m=fz@v`!af}Gpi;Do&bCrx34QP4l44mA!b7sXUEFXvcrUzoe_OtMvRPZD zuYBKSU}*T>-kyy1Zs`dS7xv}bxL{(UQZ_+bzfJcvcs_%?_nk%|Lv3!4yq-Q}%HACr zJty|{OSO$7>H#5TpK&Ub6{!{2l8UG2GoC};6Ul5Uc zZR~rfV%n9jCy`}b7A{1}t5o!NW&}3FmahTQbQUl$GLmKGlfjAidY3!Bax%vdE9I3w z%Bp@iLwiMk_2lY>Ol3_ah!7qJD%g-!YP$Ny6UVvsq4QN-5Hwp3E*7#M##GV8300m`%vS6oiQ zhqOXMlcGLHn1i}e3VsP!8(3oQ<%lk>2m4ruvreHRRO(N@N?oOaB8$khta+^c{BGIxl*wcOPN#M0FPompsT6k|8Ur5lOuHM8CrWc$ zqy~~P%b))-deEkIGtyyH>u|5pj}zC#qYhTn0YzS4z&m{OP6`7zH?6?Q=K(cSlRKH2 zc6H;MKwAS;&Q$6u(Sp*htv*jS%&uo>ZETQtdkV-IrVJfo9EZ0Y5va?LAIDOSQmkAp zGDABb13iX;zP`1EMaE^P4ot!;#2s0ma%B_KWfL>A#i4AUs@4?8s)mP8{VBz=CMm_;4hY9@xTiSV zneLrydkq4G5EqG%nTHN?%ZF=g7*%5T!F~#ve04(p{OlaDT@o{IbG$vj1<}<+WYnDP z#?EseIqq9yjP&_Ht*E-oGg2ua-`vCg;a}~`-dApS3q{Q}x>?eqd~KH~6S+7}Ya{s3 zyB}{@DIAz5^d+Rtt@FD8oe^r- zj{ygPYh^rL!rh8wD)bq!A8IcJRT9aWDW${ji-~#V?48fI@F00bh=2O_B`DB^N$B!Q+nD3rZ z!YP7-+l`O!ifd0Qaeq3F9ZH5KW`JsUa4uiX&%Nlqik?3FXw%?uGvTnKz_KLom9~5N zDYkc($O|$1F50nX6cEyj2XB`cL*<^nrN;yKcWXPB&)>#9Ns~$6U{{k==Lm@@6HEk+OX|>7;$nYc z8vc*=BxSu*aEsD`IMVv2MG@l?3X|cBCHSyyLk!pKYya+%z!vJ)wNqB~48Z`b8sm!e zqb&8omC6b-hri12q_R{vH{U8XHYsPvts?Gboi*5q!*kF^y1)SjI65s3Jzy^D-0d(F zRr&jO;$V8=3%4SXeWj>UUH@6n-}~6k*O+aF=W->dkq0{lA@i@3`ZE#2hK~Kun)H?+ zhHIlyEi-7}csBpuh3Q^Z1lIo+{_S7ClHXSO-L9K89!2*5xftQJQ+Q!s!7~5j=~pz_}cT4AX0u%yUr_Q|&rY0uY;7!!8;>GUuWaEyNzSo(o zqkXlBv+tHMjSNL5ZO0Nq6po~18<)$I&4J)-Q1QH_r_YOAK`=*&p!Z1kIdMKT z@U98So?-yTIlabmz}&zs^`)`C5D*a+l3%gmDs^$+jwm<&^Wr2 zUNVsP+e|j6_TFjF;|UUB)RO9mw65RWmN1X@ zJKZx`b;|2GbPRU+AH1qbXU-k1Pr#~tjce8r*nBsoXa^VK?PAEMQzPWUDS7LIQz8c% zJm_H?zZ({)c_*7LhnCCDv#_*$0<7>cBI}Br%xQnUCOX19V=leRN2LQs*bEt)~s#U`-kh4vi zHN-POsco19#zn(mZl~ju2Q_Bbo?pVkG(Z{DfpnN@X=%Vq@3Q-30eOkqwf*4pQk^3& zk*=!N{k@)QI1T;$Wqn}D)vLNT-}=khq~Ger+YFSRgt4*4+Z%a~gM~&XFXIbrxv7tT zstxcL7Aok?akxXpmpT6P%w8n9E{lpYE}r`zSE}&5Uc8lDR4f|Fl22paq{p3_RHq1#o=E-4HLRRJQ?@7jxBsE$!E3fJ8`6S=kZ zP_s(4Ry(h}S&n?;;P!J1=gJdN8R@n7C?4~V9(3~|h8k_{=Z_*g3CG>O6-Bt(6hdAL zRwO{1!V@Fu4xYC0IyURkw1M*C^yw?3o)5e0CMO59{loKzEk4q0F?Kvx^r?Flb3KcH;m6=-e3|;uLI+)NFPp0v>|6i$0Wyb27esk`Y ze{zfTz58Z-HGm>ut*bvI%Bu`&s3#Z-t zpF+ito`>afjzISQknF@#IL;Kku>Mp}Xvt}23}TAcD%`l>alRz+KVrQn0)}y!l;c@< zJ+bLiveF8j&Ep)(8^5UV)W!`C4pvjLxqsX@?i@^F+3$cGMDcx+ge8#eEmj?CA}XmCVSh*=Ko#dA!Tblcyo#V| zxX-rrU*VB%tx&|bjA2p6>mrAm(dWq(5zsS%U*d#P)faeG85R>M@@bASO+1zPEZ}H* z`ki)ZYB-n5XGasX&M<+!6(d$$%xNyTc)LP&Sh?@d3|WBi6sirqSc|ly&P`O5qSfF= zeHfdS0J2rnP4xlpQlo5bs=_K|(?oo8f14FgCh?(_ydhumrql4Twoo}YZ<~2FOQZl` zjj{HH(%Ib8^RoCJa7y*d6yE~YF}Yn)?d~(d&13LJ9>MHsVgBsi-eakJ%dd;x*UpDu z@dHADL{Ivx`!7w9`gt2Cr_AK$Ba)j9=Y|a2A?dKtQ0qKGwy!!!y9!3GnB^p}A( z-~27AYEG*g{Z#&pj`lU_1d^FNIUlO(&0IU-H=IG*1q)Bmfa2HcZ6PsPF2%k7+o@44 zVnF5syak4@&T0I1dScDa5dr;@kcAKwswGctOGY{GL@Su#F}P)_hu1Hdv7`(bOc3T% zjuyl!w!*@?(##A~o5907dC~neN~IqtI>8)zA}&i*6ltCtWJ%Mt4oU9#>FqG;b|5X5 zPe4G9{7t+aj9Pl|5x&&GA(0|`^3l5;a@!xxS#)@DGJ(IbalzPeIN3_VRWf8D;Q$jJ$K+auE!PFVcc_51@ZD_XW@ zI6%J!@VIvg2s5@2Xtq_@)48M{d)No1_OH6 zJN4`H;7uN0s0&v_{6A3)0PwaSGPzC$E7}Xsd;4CNOWj!r*>mb!DOW4UM0}jsV}HXQ z%X{+jC3T+mOACLCrx_h+rdD){FY!S&f*L3z1SJ>VA@tW86h)>Xj#J&eXb(WX%$z>M}SK^~>7g@#Q2ZfYAtD9Fr= z^qevOeQr(fpzvbbpzvJJTpy0>oB~el@bVop8c!!+t)2GrXPP3ggtH>hwKYltW5&Fm z;Z)>ak0!2NR0XLtHaVJh=_;Tuv$*^Y!|bw8@2^-kxQGDr?WYCk!xA`Pr=+W^`{H5d z;ehQCU|*xsu#>+CEHqZB7v(p2H6tcNJ^GLJ9!pKfX=<0_gx9?jpHVH^s~+>k=4U_k z1s}xQOb?vN^urtk?wy)SBQTU>GG=HdRquY2VkG%bgYutNjj$H=w?eOUQfR?%yLnF3 z^A>fVd8ws%7z7ow{lLXA>w?4nG?;+?SydH3`F2G^wL%UfQ&M&|2NBUKag=qAh|S*E zha|nEe`j>WWu@aOchkYcGVe3@DM3-?+H}?vNy6M#ig>wPK)x^*(>NR{;&+4TPrl?+ zM1asObWiPTCyyaE$SnWuJyNLaaP*C`sl^1cFu0je7!i-jITB+J2aAnNn$2AUuf4|# z3_w3b61rjO-Wdc(6u+6-#Vf2C21ya-)xAy$czDk%>*|K2{qJZm(cRLm!T2=qt$jj8 zlzSday>|DVocRlzQKElIL$i^JY)Id~zuRAZ%;Wt)yell#NFNgul=o~ahjVB>$%UYC zdc(+ZYqP=oOjO80b4dHKadwWXqt`+@mD_4@HVeeUJQ4}>Co4x`M}%oZ_jZ%Lr)mZgBMY(^8v zmHo%n*bDON$Lm*_7Hbxlg1Ntq>=uGns8PdDTTeGI7M!#O0pYzwUmb zQ#`=Kb<`t^f83HC_Gf?LTEuM)dr%kmL5M}q+8SoEnHM`?q`#CC#q<7mbH~bvSd0x3 z{bpu6rjaOWGpnW;=7_QktT3?7*d5x=`1EHy{R56ILN)sw>a<$}yI8QzC2Fiu-8L$L zdphp$+dyE{9>tyiy*h2bUekzPlHp6A^iVdPgqFLYsD+2^#(uMqbUuty6PUmW(e}<{ z%F>fK_dzN;^k037X>IlQQd2dTZyV|3D30ov)08RG|1m$aHjVs5BhG4zeS?utH$e8& zc_Jc*MN^yw+ntLi<2`amDg-R&8UhbWU{%*BP2?keKjGx;``YgjiOa!XdO$d*@LcMG zU>h#@kS9#&sUa)56}G#DZ#TMy)_+SY;C6dY382ISViak`&)UJg=b)lrIf~e`uoSqF z=6gCe;v+zf8uXVHMmRCyAg39U7|)CSQ@4LjMn3o3?lf*eGz&?hp{)5|{zkg3}*sVnd?A3oSWfAsYKVEb9iJrh_|I4D#i{U_+Gi4dG z*7{^`RTSyVT{SvNp8HgW7MIwa{_cQRhGIg<0qKmJV0oUFFfx?1blPY@Y81! zJT2ybQ#l*838@vciRVzT%J$_8#FS+H@oE@8t@N{vRV6-__uZ`$#ajJiysCzQtw7TZ z*j>G`H{JB135BNUG(79??@ujPoIHAU4OI!TdZnxX8;f0n3(LV;j~Vj1zcUps<=}fW z`5-e)=Pvt=X-9_aHO-S!kyf1`BQjOQ-%=E za6|Xzk?bQ`pu7h_8H*(%`By@QFMw-N=^N^xBB8{&Yk-GaYf-;jKPH|qMuC+=x-ib5 zKEHxg-KWI)qs!zj#BJLV;kL7;yyEq61Ua*zDkcmvH0dKbQtTUFc>zhJe%{?2mYQ0` zLn{Sc>1_KB!KKd%Bgh%GQDgaC3RmiwF!uIpidYF3Q9E@pq<+FKj#3{c*(y5QRTU!B zf6FrT>c@lB2)9wjEP2FZDUxBEw2%7~&C_M2lm-WvFV8=v>jngQL3q1LHko|xGE<+j z4pA?DRr>E9iWc1HyM1zYw;pABg~KuaHbhYWjgOSru$?1V(dyBlZij3b%=O^znvLX0 zJJR}!<56NH^HuRbP80i4z9k7gF$feb1l%5Y&(8R(e3MWTD9cR0_4SU50?pWz)cL3h zvH8z9f&0Gt2}5bPjM(iGrwR$;PW8b?&dnLJ_>yu~RSVM~%aYC+%%~2V<8%eZ1pgnT z^TVEi9@77-)aB=ivvuY8n+PGXMv(|r9#X?uPlIGIojiqnYNTtRhMUp$CsZ!u0l)0& zt6Hud-9T|q<^7OUi(#V*XQA6jq0I|5M33WcO}FFZTn4H4EMvcFEZ!n`z2?{~DcYjM z(Z19SZfmn*3ZPs6EjnH;#XqVlJiffyHoGuEq70C}d=b4}WTg)*c)Q}rg9YQzAzoCj z?J#DCsQ)98P?n3CltKk zBuq|2b=6l^G_3>i0Cvh```)~GT0La{N}kKPa)LYGN~pjpWrAcnL+DWZXJOe6sIS_d zdlWx!FyzlX7@d&`$*$9J9zAY23CYd}Em)QgVb)+-@SDM4*~VUNH8tX_JUc{2=J~IV zYltS2q#!J3{BLQ~M;70)|OG7^kWVXJyQp z6cK|sW;8o)RtU3huaPb{Qx+ktz+9ejHsGaeZV7NsAK(-pLc0sTIs$sM!{n?R6(GJ7 z-*w(I%i7&B#{Dd#9X&-32(M(Y+yVa4scD_Xsp-;&#`ok!NW6Du*f`6e zERy47LMC30eBK5%v^hRpQNi>4nR?yLKNT6RrI*c?Vd-fU-Uds_TkKg!GxeB-k1Sn} zD--V6MkmgmXHXqE<=5HbDN@D^*ZHRL8OYBWMvs#_@aj6dJCPYMH*1N8?I6q0`%2K! zj4a`4zY!2rtlnt^beR-ue3hdcJ;5_C*|=&0IiX(M6e0Uh>ja&3IiAPg4LJGA_~ibo zTzW9u*9j16MI_{DffYgcjslrr%%+uw+p2~=MN@Tpvvu`tFIN(%s985;?Oz_471erikYNuLR{XpvwWO^!os1 zW8K=5#okZxdLztG>TC9CW~5$n%l21jX6j+4K9Dnmns5qmL3s^p%^(XV z_{e`-rV-tob;p}f@j6-!5-Csl}R8E z9*#@Fq~~fPTj6{PK4?RkcJ-ScN`_oYOi(1A*deSULjk9ZmsWVXtlmxPakxdL&gNWr z_;>^%Qb7L*%-~i}Fo{`M<#tJ)&m%J+bAyfN3&Da|i}(ngY`FrcD&AE{M$(c<#8?Gp)yL{YFtdn+>fwOrM!)tA0;Yt`zM9_#~Hy2In3(TnU(GP-866dwZ4eN3!vjuq$TmclShF5Exd3Wa@ zFQOJ&2ghdb2^DP_v9F0x4N@i)+V&(RB@^{P6Cmc?IK!SxVk-4@N?<7w#t34uGoLS` zLohI~`;_J0YJ+jAE6Ah?(2TK1Q$VDz>-Bs| zS;@*{noLwMyoe4c96WI!qQKo0o#{n@(Rf9~eN!0BMzQFwl^BWDy*x zD)}4Z2y(BVC7r)-YUJv!lnJt<3AE$HhK}-n2h03QS z`A?Z40{_(s-B&}L`E*UK$-A>WX8^IS2l)%fP_T{NF{b*;X+L9x6|9Oo?8*h)tiChke`N@B;dqrOkp1u#pS~#U+iN_$s`K+wAYBj{ zXz^Kmx8)upScOWf)!(+v3(MI}4C15_Y>Py9L=bIB`^bbn zzm>f{ryY~Vr%f`}_$5f3zSgD`Q9!$EoE`<1!W=|5l?9kO?{6$DEI60nET6~zHo~}@ zd`>0d(U^Yy7H`=CHAd2qww40TtDfg}H!M^6a#C@zTShMYu`PF1eXLtBPn>a+zfpK_ zy5o7!=jRwL#Fb8~WkYv&!g`Lgb-Vqu!ji0H30!Gh$$h#?@eRj1Kh>0rbhU=X3Jv&e z?OWT71R#4KJt5~mhllgC-Ptzqfn@P!#?=d_<-Y&!QMu^;?UQtO&J1_j zSUxq%r)vrF!4WV0Zi=qnXWzP=53yQ#S(FGD)nziVqoBH#)_%tudse77Z=PV7M_%31 zPTW9uzuPvQUIpqk7R9aGOMR*Vo4%F86h)Ch6QMfsdtAli_P-nqlc56Z;G@{p={w{E~6+eGRsteNpHv;wZ8q;G-8U&!fVcI(mg*-u^dzI=A0GPMREA96u?gUP3e zW~)y~C|DR(Qpu%gn;S+zoL-#C$BGJmZ+-3jXG>62GxOzP>E$G;Oie z@RX_k;nMC_DA~Eh)b#Mhu;*yuqVAv&tuzwKm2SpSqE0%-GydL*E3bYy03-U#nU|F) zKfH3?_j+S+eMl4=&Gi6d$^Ni^vCOn)16h3UeS`igrNz!)v}Gyr+D8wEzNp6loV^4+ z)kUXA=4cP)%N%g@gX0sy@orAZ7BD|^&s|{+R6;tUm0&cWPE6dt@$k|!wh9-cAn4UB zL@d=0VcQj5?j=BhD~nC$VNCmUdmNtGyZ<9L^eAfohq|te^r45OUjFVQ(OFr)M)%1o zPK*cC7%txo4l}w*_ZAW7WWXM~lMC0JPEY3-Md=WaH=dB&zvlc_TB7DMprCM6Bdxu` z@mIVM9n4fz&9!eV*fjX~@`tgrfLhno)KdDb{pvCDbs8S#U)Bf}- zh@j05gEp&IQL#o9ed5o|Nbg^1>t18gOS6*!85Q$-NcZCrMj80r@9OxlRO{YUR06u^ zOCM6VUh>hv+TdHI_+*(U#Nf5o(5{=ek0^>cYrT?P1;p1kKrEBE4wfolz?4n|&lx!j zWGWRk)dvpsl~$&`EL^|XS1eALQ#ux| zx09Rg3~anI81mvmLGN#xeCiGSJ_Bd>57wN|Iji)P{d36=wfZ(T_HdQSM#|J)hrZhH zW=;k61K*XW4Ry3ch4(B9sjQ9`y65AsQ}JiwEG0(K=#Qml=XlFhEjkvHD!#^`&0O}b zFfC9Pi0|xTNpRZY@_qjPs_ezo{uFwWUIcEqUXgy>h?tvGM0ow@qm#IrkFBVa9BbE) z4qqp$RHZiHR~r8ssPz-eRFJK6ACEcyH87fr-$Y`ysy!`sujf{py%{6|D=;(^|HGAhwr}{JrW2aI$eyf8W`ex6j>T>#=$J8T*1PdFD@!4UF z8Zys6KVT!aj!ZqtuVh258G9wy;A3ZMm9^p_f4al2CMFL4eyCa* zBr}`pLknO`TIvTl4_)5D6js~myR7*_rWdYR{kBtib<+HN<|Vz#slQB+;}wvan(u=X~33)-l=&4u*@nfY2= z`j7i8snolNZ)W>_&5A@(QY*6hD;a6DmJP!LPS^{O6ay15{boa6z%${rC&+ZsW8(w= zcIy6Q(h?dVC#Vd4whockeE|IV|LxB^>-)z8A!_3;wB3LI{S(UaYI0>V=0X1tm(&_S literal 0 HcmV?d00001 diff --git a/maixcdk/static/image/maixhub.jpg b/maixcdk/static/image/maixhub.jpg new file mode 100644 index 0000000000000000000000000000000000000000..eddf004ab89ae5dbf20367ee2bf772c9b9d872f6 GIT binary patch literal 259281 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

    W-C6AvI_4K&31y0R&5ccJ8k_3ludL<>|YDEB5YQ z;7EW6MD-~{bE6G#gd7HhH%kS*E;RQ5vNi39J!N~iTgA(7LlVE(*j=SJ`9_}2)ApKw z{Y4Ocusd_G0tS*A#Tnz$63lPg1UANoiferbWGUNX!{#onUHUO#POMzK)vq58t;;K5 zr-F_1^H%g3ml(MMb>=GsG6C*7^OvqZlW#f4UgKKq=6?xZ*TY5i&9(I9X4aY&c!j{m z>&lZ|9dHXV-H+`*K;1*R!e#LA9VtE6&ddt59mJwX3A0YC5O%`1Z1=;yVE|WC``YbV zFSB?*&-nYr$FaTD(9o<51ugb4_f9!uUFUBxCTV`k>=~8z0a4Ll$`dp8hm?mc^6Ruf z4S6F$y>?LIad!aiTcHY9u*3J!u#jn<=ZTI*nMX`u5sxOOr-*oT2&(gQE2$J8B(EYqthO%V%JJ;tTukKte*WiTX|+|Q!R`3`eo$zL ze0bryJ&%)Wwnj48a(~jS$5lVtO-4vuVan#A=N;n%Nr(dpF&nmaBqzKz&`ERP<&_wl z`Zz1ext+b04stPTmu^V}t~DI{Ec^ReWQU8W(^Gy4f=H*Pk@ha?1#Qj}grtSi|16z} z0@ppw5%30;~n+Yx04A2Kf??d z*w>I=Mgb?uo~NsDi-+)aTRrd|_yl}WF|){g5;tKy@Y%J;Ln`UCZO;>hnNU9c6%HUg z(s-t3>h!Bq%6C-ukzxP<8`sXQ?ZQ0H2T{^zgPqPMi7!l4wYBzjTUj2ezr!RlS_zbk zx@M)N$+S7Zg%X1Z8n3)|wlF_xvZFi?RGpmXr7mXMRgOrP%PM1ksazdrr_6t|6(6kj zZ6svzIhuiu+qRF}8f4u~zuSz0|C2}`Fn>uE>x^g1duuP*{#eY-2f}-wE5%ROIj>Pq&0{Ro+QU}3Vo$i@ z)#`GTnS77UPPK5IxEnapepNNd7BN+26-q;~YrF_wSJk;me5j&9QI1A1I3RKKp=s_s z9NQuOex2;gJK0W0k{-Nmg1d5;S`9|r{3u6qzNLx|C`KPM9Oy|z#o+D{zI`N03B;+F z`~Zf8?p9%|x*fFdnRvD0bpsQ!eXh%9IF&JGm%v*5yk+oISi+K-C;pSAcAvg-ww)kX z%GK0CI%)$O>I}7<*K%O$9~Ixv>d%iu)ggT)gKVGa41yFSOTcL#R%hON3d0WGhmjxL z79F+&D+2}u5eQzy1r4X)%nW_DE&TW`*)UG*lq~t%SL;k~`a>?p!Q@Y=YlK4q zMoJRJ3{_*2v8XmPA)QucqH$pA%^{{vCTL~S`Hs@KsR`N`5_xi&)SJ+%zeM8N6d?xb ziN*5dSQ#>%7oXYD&|&Md#hJ+;mwZ|q9HYT;zJIOqrVVGl$yiX9OQTj=NP$iN#8?ST zOtsqHI&Eet$_(nKU7h`)uZh#?L_&aUv;?E+oLpL}MsjZhp`aI?ls~ChrLXTX&xy+d zAP&bZrIejH2R5rM|D4_;SYFrAdnHB?Vq}{VGZ;zUCI!Xa0Qct7Q!*}T6(s4Hdg*PZ z?DpXVFjVK*Q_?v;iktkREo`;@DI}_PLLK38?Vmn>|=&+ZvF@fl@979N!j|^U5sk^)q2SR z`IY_;nq3NJC$1ke{m+K*aq^=Ia#_~;y|Z_z*bCkvJ3)klXKMtq#oS0FU1FzxP)?l6 z{XqT(I(3SCl78~W+)4Z?7@QdAYJT+QDcZ>h)~n$Y7l%(!&i&i#9VgQM3Z9;SztaB} zbMAj|1^PsWX#e)s#bH`hy>&NioF#?{<}I(lpm!y-YI^k{ZUNbBp~bJmyocyjUT4qB zEabJCK3K@Ifu1PvXMKNybn4R53H)jB*CE2gzapV9Z&gWy;%Gx%l{GvB8N8FBUR%$o zHno}ZM%kFohp6;R{R$7A3$9WwO|g1y4GUy$HTOH<{^exWr|tAf3V84IWc2s&uT~H9 z6$kOODnuG8k)s}OepM8*jz4mP&hWkNt)Q;v+%$iklw`Fh*BBg}PGx~Y>R}@ zzWiF=Nz8A{cJon!EK|`<_G|n_!8|_1BT{oR2?(D)PdGsY$B64~7u#w#A8bQCsg%r4 zi!hlg^~Z4^PVoE&{B_WP_CX~nja2(DAJGVMv&Wu{%Z6=jAz5=9hNk9xKjrYht!;jt zqc<(G8MIyVO}1pYGd044X`Jg>=G@?$gD1n^wSv=0#^1xg6Z&_Ye-uwtvi(0O#`*Ai z@fmLYEp1sB`QDVOR9eRF-lcUWdf~C*B$0~2#F?&jm$PZ3L=Hw>;quq;qx5lvxWY(o zeoJh&U#(T~pidg@H1u)N6H>Bk)vk_AgAk9#8hJ5*l|9Q@ZFJ3f-J(B8*&8}jt4zVd zY`3&0eMPudc{s;srIXkj-N0c)L(r1gfHTgRJ*UoAvAL@)NHta5lK#uexd*F0rmK=N zPvBzzQO%w@?1yvyHXLkWf+QcN-SGu`iLA8Hv-Hd|O}oZ4tM5qi#&cFK+II;BWsv4s zE9qDpZ?(zdNQk{MZQaqwEpp+V#!GwR*{dA&SDuP`W5(bryM1Udn-;T#^%CQ9&Yn`} zKq-8~9s~K_Zl|X-H==9_F-cF7_F1m(;T^Zxgn2Y?LGOO|z_*jj%hSt7i^j~A;~dTt zjvXZur9+&yBj2P(DAgDgxFc&_Gx^}P|9igy&hdBQ_{R8|_}kwMI##+l zxWC2cWr(oRje6w7feO^b)Rvizek%$}EF@}I+!)%a?5G`YnYsb#oVnj?ixOYyFv&t` zWOeOh8b&+l_hqV-Ez0JKwN*|(nf>7U)I0M0uC?lLdqzabWK3I+>F5_GpT>7PNjX_M zs}2IgVsbjfsYLp+X$c!deGy+uIRzz3eUfhKby=9N)9w^dlxTXzYFjC))Ilm5WE<3% z6sl6W!+0uP;gbDbUo**>mW0d71&OpQv&bj2rP+K;KWq#VNxt!kpsX}{6g$P&-YHF7 zAq*qan~Y8e5?%fQW?D;xg8Dvnx5s3ETF!`~|i=bq0&-vMe+H569 z*+`_&ztj}A$g##FM1xzxwkn}5yKi#PaH&# zSYVNE+Q7~(LHJNw66eXRZQsRZWBDPEQA(Sf8#v#cJ_ztk_VfmMg=oSqkD%9g~ zd4C7y4Po1gEW1Tx~wjQg$~uCM7@X_a`e6O6$k2&FYqT`0DJ4)9|M}j~P$e z+H*YL9O-~R`#|+$S0RaLhPlO-_e-XmdsmQ_8HW4U0z;WOHa6KhY^eIm3WOVZ?^@n= zFrIn*W^!Ah_X%^U3rDr6QP5eI#W$^!3T9Mg3-4=x9Z4UCeLo)G3VU3H^n^rfh?3w7_ZHcc; zD2GvO_Z0L7MQROrv?y0+$e9E=E$vkrEb13_=c1K5YBW~&TRxGqux2U3&NSQZpNvx0 zCKcM?;%GFA3#>}xuI%hJF(ub1C!XF8a4_sG;uv~uw_CTRUls`yqvZEkcCF67_oIyn6xAl9B(W+99n9=aXS zj!j#K=^VDXIZFQ1F=G@4e{5ICJB4b-P6uR?GsH?_GbtC)g zl2sbR#`dkQ3oAU6%By?Vnx>baP5%CFt=CZ6Qc9?djUT0kM=>fd_SEOC#y&ONBc~)` zA()ovAM4ZZEQ&BT``Gzp+1PB}LYX(c&8EnHR+>kUTeLD3pOTVU-={aD9xo@9=`Hi38y=_AaHCUU~^DGer?l(zrF3 zJOcVRZI{FQ6*_4P3KXi8RTg#RXJ#E9trKyl)otJOUgS8-DQVulHh>v5zUi!7nrhK_ zD+;&wbF}oD(6?et_GuRG2s&Y7{?MhhGLc2?nV$KNxqJQk(_5u!MN_jdBS$aqTYZ%) zBpJD4#3V@xGd2mVF%1O+n9@?~>g^@5(+leQJzaC$M%rVM@sW5D+M>eu!+A`{U)6WM z%E}V?T)pGt)7G11r20C)4p?^Y}Bt+W;SQCV`jo3P;G6ej=^ zOG#Lzsmc>Sfo@PDd}qEc_rv}WNx}(%l*fxd(@h!7Whx1;Y7un;e_vROy{_IO<8d$B z&3#ils0B4MN;&iIm@;d2p37VA!sto{mnvix?IbUDj zwvp0+Gnc5>D`~D#XHC9Zbhdz|ZQk9Ib`W%(R#>i-zpdPOYwZ`pa<0-?(Fs7N(}p(s z*t{J-7$2wiSP!a>4wcLsr3((8Xh{l%ttDodv+Ok?$E`a3B;eoaMhu)Q$=#2|u0!$3 z4Zt%4p;QdV#4&ZD3p5LJTSb0!kySfjZpV(v{%AQhety{9lZBF~J=nU$6OAc-5($S- z-?}+LJ@r+9(>Ck4^nLbYMS!8v@8Xg{&>i=F0A4<|f3fC-Ks}HT)`QUQO21wZq(PT{=p~ zC+fAE7 z{${oLp?~u`AW)gs^|621mU(M?h$f?psSt;dtC3`rxkz)dRJ%=TaeCG!pQ}2_|J|~~ zbAQUT#_zzjN|xQlMY>4lIZ51VKLg2r8>aI{A3Qc)%fq0z6zzBvc~eI*N2Nn@w}W;tYE771=UvWoA3oA`XXy^P!xITo9Ig+J3vqrH)8d1@hHd$#mO(NXp z;QO&|($;Q>VRcgoCfTKeTiXCr(KZ+#-HllLrY$_ScUE%7+ORrm&W2ZiysT*5I=44s zK{Kr*ET=NDI%*<8XL;L~A+g8-8k)H?E+M*`5pU zYM(Ka=;D8~^vz2p@8id^iB+P0(t$oM{as>ZGmf@I7nzS`!m)XlE%DuRTD^VA;XALF zd4&vZ(yD}fqSVtTJ6g^9208n6*DMVOiIlruM^DMlpgol><&HJx^N)wcqQzkhCg_C=*w z2j2wa0HVyXj!lIjX~Bm(y+Y z?Y&Ghuhf*yAS@*+$+U=VejsX!$GE0o@cEN?8~a7o78q~McYt-q@Y`a~sEYoYO_kDl zF?SLsR)bbm%!h;6EumZCbbNAE*Ej_@TW-<5}zeOUm4h~ zk65wmt)_|D>ECZfVu{x`rhB0Q9?TXI5{q+=B1;)fuXmd#dD`-gw;Y45G7L>vcDKX( z!scf-c4g(=_OOb^oxsL|9}i-la}RkBkDLhL>7W3Uv?!Nwm;|2NbYhNWuOdiQ$Ko|q zF(HFnH)M1wm7dBl;E>a%RNMqVpFCPy|plOf3U4=l|)!#xwI={w6=6! zcY(0@{SZapIE*B%m$Bjn9qG5e1DQ(mU*9v^DY3?m-xfDdkra{7nJm1{E40dWA1)}| zcN&IBGw(;>h{FILCAUs6_2;iE%3mLhf@p<=p>Xt>fLr(I_MP*JCTy7_ZZ16bn}wEF z@|DW#`F42+2QTv2{UdeX*$A5Cgi;R1`x|91T**xU@5ro?kT&J=PQ?dtF5^e9 zTdwm$SAx4&+H81Xaa#+6qa_p3m%ZxRrH%I)IR@uLyr-ACh z&_gBdT_5h#ro~R3d4b-x(#E=4Sbu>mc7h?>j>OQlrB_!RWvv!%42L4hG?TJiZgKOb z)UL6NDPqcB;OAYuZ&E6oJ7LRREHk(v4oi#u*kN8Ylngsthmx8$VMN+trafs_8Ra;% z!Vwsi8sQ(-VCa#k-n~cNu{8yk?r&Q8>%#_^Tm5bBXP=G^bWf>IP&L3aI1E4hfGz(b zmq#DPJ?vz|r)<57TxP8Er0eawb2j*W_Rg+IZy`7-qQQ4k62EwUrxEM{0x=MJpQ znoX3;%04x9cn&qEnAt&~VZzQvYcOUM7qn(aEB%Vp{geO`m9;U7mQ@cYs+I zJwdYdeg}-%b5Y*ZdVknDM=#LfzKl(<_ok1i zqF!M$Os`Q(5q1{iK7iODE|`R?)`|V*!@j$7#J}%rV#w-E1b0zdo=d3sRPC=_?_pgI zuFhMT?Mt&jZ^P^yep7yhzaNG1_$&Oi58s^bpI&V&=93jXO#zi>So6=;}fV=l} z6ec@?7(BC)DP;UoaCMc-P9}>z{;KLwa${XLO=kAv$_yp81O>+4$mvjjR{HI8Q308P z+3w>jfbi=*;qu|g_Gy`facQyX;ryP-p-GQN%R+BV?83{U@_C+Hmy>3Hyz@LUxlLcX zeQ_qA1E*tZai^3&ch%mhtEGnhTd9K*hFQag-Na(};IbKL#inf=)zupuT~V_V_e41s}5S@_llJdc9_4#S(0*jQL< zQDJQx!Vl8vK;OPf_?<<`3TW56)A&2;iCoRpYg6ou(nmYAsYFblWY^7r>%PNt^}k z$@!+-fq)IeWph}g6PP|tw)OC?`j50i= z0svTQ7CW71Sgu1mzx+Ci(eJ7wbt#7w%broK3`|Xe^yssg=L5O~r7H5}<;1L3{gR~v zLOd2#@VzXsKb(G3pSdI|d?7Wr+4vzKvj z$(Z;c_pe-KWM+AM?K;JsCzPyr`31mltfGQnU`0Sa^Bw4mCy}!g+rXyJyNXbN&XwXW zb(N08rLTK*o*`zCptF0WvD)w^MZ$ML%A(;Nd4qV8t?QmyNnl@d&uvTcuQvHbSU9v8 zjjS8>{f{oWcF&U#v{AMa=Uyp)5F=2|BXcqW7(-S!lgtZC78;OUQM;N&6WRE= zx?4g*ueQ#@^~5ES@4(kh4y0?*Z$(WYiwU@Owv0@Y?6|!H!81Y5e$IPxt~n`*ScNSn zgq~ZsSD1|QT?Sr%oGAAxEFTOvQm7SGS-$f1b3-vB*1f3ditTESYkqI#ds(kmr+-os z_zsAE2V$LH-z)bc^|@J(BBI+XDZVNqWkAlfYk!Anv|5JPB%s|^E7yTS3OSL!gKaE? zDVdVl>Kn3xe6o?KS(t$`Kc2h#tIm2xjr{oUfLYIXU{R9-5~8-|hBYcDR47RCUK42# z#t4oH)PZ%BOEFfMU7pO&N^hfFzsf^Jc$#T7<9P^7im8O}kSAacdlH3eaz1-q`HlLM zx7xWFHpAA+&8TyE4#w*+ZMrMg7JWo)N>RO)c-rTgUHqpr-m85MEl=+btR&LXxRaz- z;1J@A4bhEt?};RR7V~Av&H24LBjJZ(Bd>=Ijt{49r0ds17)qS=$572%9&=8Ii4uIe z`=rE_=quY^RcQ*&>}o@-3-`p6N_%xTaa?jTnH&Y>fcDI>nVD=^noplCdD1RCp8S+x zL?G)D&E}e+@S^$~QXk7BtcPKQ?+h=wfxk=%RZOC|-+V72l}W&OgWF~6W-ES^E$lfC zW$0Qy4NZ$I7O$k(qULuXtqi|_V))f_tWdAK89F?_xXj*OhlkVT^lqY zzE%AAX#ZEg_87Sn*tvP>ntUUpX6Mbn1Ij8gJ&|qUkx_xA2dI}M5A)nqi-=iU6n&GW z&INR-ZONhSSHGQRyVuEbgt!McD~PaLUG6ID(Q3FNi%(ny=MMx%U!M5 zZM9H0U9{qU=dE}R^rj(EM8KNrVKsc0Zisn{diHGN~{ zMz>T~?u%TX>9X&D5WV;HLOW{QRI1qw7*xwn!qnEXp~MGk%1l08eU$z!)mwG^TNTmo zlS{KwKeD-tzYFu88RkV9q^-_c~?9!(aPET+z5qsrtu~>2Z$5}Z^ly+nxTJIHJ7_}3-4`|M6>oQyZ}Pv z1?|h6lA15x*5_yqA+`103_?sgU#BEPQn74gbd|?F**4+gYxU<;CRcPWstTo4`tTGI z^wyx4M;Nn=UL0OmcJaO$s%Obw(LhN;^6@s=z392Uzo?3scpF&)@%;Lbu9__I55@K* z%vyReCk$3oTezC(-7<_GMIrHVNy67AwIeu7bIYKK!Z=zZxz zm*m=W5xg4yt7qu?WIJ-TvnQz%R2^?WN8#ED=Mm_DU7342`lS6+ICHV&jaXW5;SVbJ zB=42HUwYqrGYvWAfrxHE&*;rpP=SZca!~Y$6(%-4Zp52&Ymd{5Xg}Zm)Q};d6h)2T ziQ&F;VUFg~W=qc-Mg>*Z+|T5emi5NHZ9@4ks#qNdh_$#)F!_m1tEVGOVJRa^iG0uIem21WM=38N5IG0 z!Rrm{;bW_F=?Mapz2!}rBex6Ua^(dq9d2&lwS`d%yzx5EMgARVnt;zi2L%u*(8i!> z6?k#P^RK{BJze9=uV48|>82UTVBD3GFU?P&9#L5nxbCTO)z|qhKI;F?ulPHH`3KVP z=B&P0bu%Fh?Rui)I*Z@%zGjC1iM($1Ti<|mmn$TMQeGArox;kWe70kicv}r_yL z1ye~~JIa>`@*S?pVpiyZAK_Ev#Y%d?Wg}0wr0$5D)6C9KV(QE_j%HJbxAGb?c|*PF zex=1Ol!}Eu$)H)cNm8;NK6HbZg9WG;ibo8_3STzcJt(wyqZP`7O<&I;%p79jx4e}o zk`p*x$6j&%Va;5DF14|vl>S>fffsLPu-%M0Y2I`3BhVIU;=ju@Ruwc7%w~JF+jk#z zBWP&np8Pg}=WJs<;jC`{B_)2}>)B854X1`S3MCQ85qD6CFj3Q{7`j&y7)WpV9;p=% z1*oLsV{)hj&Ay5iGc;nVxZ=;id~?)qrc>l=gV&~c02YPD+|;aJ-Ocu%n?AO(4}$LA zeCQmRXgx$JpW`cI1Oy!M)Fe;IV5EXovP- zsSyFzY%vmC3~vhAFm-om+Hc!&BfTixmuKD4(_U z%Avl}2L1nxVaCH;YmL<9Kz6?Uj4!g?DNu_3;ab*(n|E51| zTp^f%#+%+Q$<=U}!fF+_iCPh4rhBimaE9IfBbZ{|DM$);tCg&eE`*2 zgh67&6heCf2PcyCs|j_i8HUWW*G_Ng!wuah_5$qfWUJcv;yamo8WRzQNkXB9 z-whSHnqXY5U~{=RLd5@n4n(gbe9d~p=zf1p0l%s9_%9`%^sanob!`f|MaJmsEwBB5 z{-2x@+i&Jgr4b<^I0lMKQ?d^HQgC|kcJ)qg+Eu9rYvDWp`B7}V^XzcAZ7bQJB~)HT zi8Nf@Wd^nRcR*>|KtEyl#s=DRF2)_W>Fw zb%lUhM>V0Ptv9bLo1S+LTQvoYw_9O)Q(})t`Ra>A+1ZB!G_tH^g3K7b7ld#~nl3$J z8Jed#RA$r3`tmNl99fI+?LRe}l2Q#wWB7|rCGmU*HoxUB8d>5K$UNzk5Ly*^Jb)F< zQgUG$X>j>B()?b=|3lcgjMS(Xi=X9%jP9pu7Sy}%xR(1vZ|2Vl>LCYJ!p=SPp8C{k zz!b+;ZxsB$*n8`!xVCLiI5~s_4^GeocXv;4m%=?b1r&tBH3T2fURtr#iXtZdC z1hQ>Kqe9pdMFB~!b!?;P3r!+AB`Nj>>Bb9)+^BVA@R` zU~48uV{oG|uC9zyI~P_epqGlGB1VN_9Cew%s*%&lKlyaxg&iCtWrOoGX{ltKYll}r zx6s4Ci-@0??AA>&+_{q?y<24Gsu_j&+oZh(R&4`7;0I)tU$FRS;k@GB)H2sqyQ0#wae5t?XfU3U=0-AncB5|WYXc26N1O^1^{;WMcMFGIWwYubPu zC+D`U6QI6nLj!oNPgAdh%@wEqvaLE?NXl($)?YyTxTV3$;-RR}J!!o%-5gUjxj*5w z$hycV#ku$(n?pv{*@>-?LVc;fRQ};Ilzim0D%m2PZH`o`vDS>J0eAxBpIo0}(e_MO z9)U?3g@@<-akmEFqLx*z0b$tP#L4&TG5W?S;az$LpNx@w)`#ts~1%Ary}KUVmA zCmq*roaKe!)pNMzqV&8umFFtbJZz~K|76;A4b;|G)9Xa*ylmw4QC>o`A)$5bi|ZfY z^~Pez>59h{T@$5unnQ6W(-ui3z@_Mz`mk9M05A_o^}CSqkR^uTHWSsBR0gwKZf+-b z+GqE>*|5iq4$GE}zD8%9g(o8%m|7DnEzkg_+MJ_6^5{QiRE<}?B<(y;y+y1#J<#zr zAgQY{syq*X1kHI+F=>tx1n72aiymhB!P&V-Q`4!T(3TT@{dC|DG!$fReRExUy-&S+ zwfT3|ipy!Ooz-{Qv?oCrbaDo=5i{i5>W*KuF=V?U5m%PhBQ9vJ~R!& zOQ*ncYO&C&zgz>JG`5|uBS{1;z~qt8KVqb*sIFsj6bTH{?B>9hfPSvqP=2E?Rck5A zOUEc+jX#aTpQ6j?MG7^`-4J2?KQB31?{qXJq+CC8X{$DX**PF3MBzL{S*?80akCBa zdW*IGYAqAH--<2(P`p`vA^rJyN^$(4q%@H6Fp@JNu6k-juVC)CvPj^+tE=|!nHTr? zu$rWdUm;=`ZE2=ZP`E|9w56p$-%-2~su9L^`Dz13{du={di*4g44itDvvROie6h|= z$sl3FrWZ6mM3zerJV~gN;akNzNiTJ8TenD6wGJr{I0O>|UseabLhX!{N76aVH9Ge8zeCj;IG2*Gk@#*9zBB-i!YpfYJ)5{dd^(O+F;j$`EH3)Ei1BilME; zXsy>_wpC+{Gx@KwnmMn|z)*$1qp(i?Xo&b0*&JI2Vkc1ukwh{M8w|NM>E|j~=8k-S zo^%_f8;@jCh-ak>28EMjHLhc;S=Z>fe(?6ZLp`o>wjQXPIw(!#!o%2{e*s%M1-IrF zSenNJ1II+56OD|bS2~0bV1{26ayJVDK$1L5qE`N255s+u|lb(SJtkD@& zry~Z(WEEo&IV!xH6z7`z(vNHehY=pJFXdUO^v#AL$O5qJl|}>s7;!SvXMWnKS>vQ> z|0&G`4GjFIj~=7^8RON^bcR6xqMKMrZROYpv3^}McifJmMIzHt2Evw<>LDhSPP{T5DrT3ULt(f_}Ca8T-r_a{u1B@kinQ{)uDJKOT zX;$UzX3Ns$63r%cw$2zx?DekWF^wpPhX6T@LEV=#mut=`MnTZH{Sqd0#TLV+s{?K* z?$v-yCC{!o&QHSsJ$tNKWRs8xlE9tcFgIGyaaTb-GEnmh<3Q>9qPpHm;EcS6 zL>3(VK`S*^@KPZ6dJFC0S-#w$n5JBtXqmQahiWHC2n&x^QkRTpFC`o?FuFDK6^xC^ zyKLwLZ7Tie#ZjKG_2l|8Uhl5<#T*K7Z}tRCly1HDK8W}!jE6O*SF7$C6QN>g(x6<; zh(MZISZQY@xft!L-=fb6@AyiRo8FvSq2g+!IwUlkfD*zx2Mv)}l2idyFRKvHJMJjZ z&fIsx?5W#jPmJW!DzG`EW#Uq@p67^bO;2+69OJ>aI5kQmchHikm$dE$_sgVM`CmBZ zPgukLe!#!xC%F0Qtq##@<@~|u#bvrUm3#WO2LKRx=gYMhszjwxJDdc* z)Acqw2LZL2eKfw|2pxn{)lxU14!0zXS2Malo~&Fok=FJc15CqFCQwH*=y=AA5GpVj zeB3Miy?ihPR(bvPKP;s3>~A))S!xzKESFYztapird|lhf`CfOytC=xbAq^O#KeDAW z94N2J^QD_ow#BuZHR=$&?Y*_1y!;OGI_~=?W|EnZk`K95aGzSuHo|5w z7BTl=IjjXggt*SX?E9dMEJjjLqS9>2{N?CIeS&8vReyzS>zd6;LcJVIz#ury6q7(6 z1-s+O`g&-qS58lWn~E44E{;+Pn72?B*2`&*KXos`a!Qji?*{;8;tcz4~xuFd9Bg;Uv#Qs7mgKG_1V0H&f;dq(hTtxPoQAUVV&&X!v?#}$-TChf-iaVOT;M_oxB`< zgWhCZPg4%dPuE|JEep#XARf$0+%P)aQZOV}wqwn?Tyd)R1B5=SBeM6ij*?_-2(GT_ zd|1iU5~N~B*>6}?ry|Nv-GhVz}Y1-H;HTyJX*b-!3N0_+YY&j=h(b z(%C^27VTE)zAAfQ$MBMWPoC+4SpPhzS5^eEjh}u7aK!wB z_|bT5>UwN1xq6)^ao=@%!txWg6cQ5T1Ym`%CLNEOR5ff=WK1`ttTs5uccNzb&HY!X z7~?wUDrITHq&c!9bSSmcis;Hs4U6j9Ti%753dEPH=EYp>b{jD6Mgux^avyw?w@KI- zOkdzpGItJtz1_>j~QSmc}G6CciIWUTXX4Q^!5FQrxJy{cK4=DZ^PfEpjBCj=GE5&B~;s zr0KQ9V75@_H+B!;_L%jgmktx3uD{HY@Ku??$#L$s$}>4++JBn1)ha7`HAW)lA)Vp} zM(R-8aX2!F5uly*=4TL-0OR+VlcxAstqr}Kj60U*i8i1Zh>})j6v&&b+bF7m?eqI{ z$bbGo(y|>ABLB2U*^LBER2^2Oao|F;lb7#?r4ub z@~NA>>lBS+-+4%Dd4fr7A7~kiCg_NGR-6u+N)1h++MlEr6fL6!N`{khMko2`S>OWP zCx&2iwDF#IKIQwN!+~qu23Lo=QO@$>skqT3MX=rT4`&3i`+wRN<_pv;{YQk+dBh$y zx$?3&Hpy4Gwka+>Widp$F)esPU*cbTwcbR<_)$nDt|f2)`|Eg}yQQSOGp@ES8FTWiWRn zS&wAL%dQfe!M5;qD{b?6rVsk0a$lGRg?1R)vB2?+8Es zDOTWIehFh=&#;igD7HmW$b#RVQ6-KthGAS(`@5-#JBy4@3;G+qeUZ}7RW?zh5*$in z*;@^rNB+YqX`%fcm)#Pa4R`MNYdx)7hL~x>?H*jkFK;yH`t^R^=@)vkv7+7YgTGkT zge$K*JEi`PMArTM1%f4o<=6l9Msr@9{;8y--Rjy4@D~9F-y&jH2nnHmjpQ2mNmo{Z z1IwL;yvsKlOWo06_sz5SX%+_fztm@l;;NDuGKJgP~eEOB+ z`KOUzoB#Bc$oSsvNg|@evG+e;^OqTZOIedezot?HF+3~5YHo>Sk`_0$;>PJUB(T0W z`?WabcW4kMH6x7#Ib@nEdAH={WSiAm8$xg7vjuL{_7DHky+FQq_dEXbUtNoNW<2(k zWnY-7vq@8^B||ZOX=!7s6kH_4ug6b3Bvs-G$l$+go^{bi$%;sfv0pVh2>n(aY@zRW zy>*$jdy?`X?Dy-muFNe0(q z)-ITLjn^&%XJC@HzYbzqEn05S43gzeb!MB7g}|}_WRs>9x~0tmlwwKnMZyW@<;j1w zH?tsda)fpVg{*V}U0L3$A@(5psaIYMk+~7`pzU#~zc*3fVs7Mr+alJ1z5nf?pQnk) z9dG&TF8;iif7icR>5c|bku5l6K=V)5QjGq=;hkB4Q}E{WmnzZ?^~VJYuGyZ@Bhz}h z26*w@wnaHJ&W21Q+N!qYoL`_Kcj&c!^a+H_s`n1EMNpJ&ri4e3gDXnsk0Rlk`L9| z7J@3WP^Dqx#vuyS$IFjPZ}HxKMEwOs|A8jwE+kBzWk(p` z!{P%%g+YTx+mQre1r2pI=f#DWk=09PYnv=>8%@$mK`sWQzgYcjeldM4z;2Ek^1eqW zK^rdr%o;2iqy1(JB|7$=mYeS+$6M=cVH$7s3RIa_w9L_D8Ffm?nI5JYLEn!cI)qho z(`FWBXFWz$7E_^^oV|UXm53FLow2RK7RUTPd`Ri+rWswG<&*Szh|(1Er;2lNeG?s<4#!El#CeA8x2}Yib@_?wmZYxFUM^?u& z_gURKvj#0GTCuU%zddnK;VuOO#C)xLs>A0VV5IIK2XSHqa~O{>l$F)q_xrJqPReb^bD7=szQYo>cXPQ99(( z$v%J0i*|qg35tiHu9!63KIdkzm1Xu^gS3A_u4Es~CQ3vMngEJZ6m2@w4lGI73DIJA z2THK6v3^zzGj5TD!HnY&wC~@Jthq*==#Dj=+$WzJRI@2K{lxlm1pWh?Cqrg;1A6c{KUpT%#NSNr}v+Ozhf6Y8YIW6vWrd*^;vy0-8w-`RPck9+kTQD@LZD) z(dV0)jaiax=L#0L3pNxsG$udC{Oo=q4UU=nlU)A_+quiLZw_qN-=DRvuyebh3_d<( zcmC8rxPk@#j?(n_l$*Ztj64f=As3X!rKjxFpZb@7o(iRD^Bs!|O4$lKyUVk|B{*i` z_^r(oTCMvQZst$@0}fbh-+zs#9T`}v2QsFA>W7Do|2gtk4^RK`ALC)C9CG-1HQ4!C zh*2tpf8IIl?FH3ZKue@Da$s=zj%L6c{$r?yM)qH zZAlGQm3bo}v-Q*YnovEm%9Kmi{kaof8r|D+?JFhXJI@?x%9s>>JsRd`(=@J_Xjdm{ zmd~_#&>!9PguV>BEPPjIPYEU6r;aj!AL#JgZaz@el!?e6#!mS0+C9m z>-H->(WHSSO#843ohgI~CSh zvbHzL33kuemSi~MRgUNHgMK9vxuQvp3tdD& zq~Db>GDj6DMa*X(b<#vh*)c`Z#2|Jgjhqn)?}GkwdSaSb6&4e|jUDLKm$d-to{{9op!c0KS5G7{DkFldNhM`Rb-T5#ecCs8z4Hej54Rx=Pejzw*Id0E0JtpAsj=`e72gO^giu``fy%~1j2NZ_jz zGd{~+Dpi{7uALju=$#N@g1;zR;AG=gFvVVxZhQ2C%VRGWz_9BxlUk^CjX5U=7ZNim za8BddNjo!Kw2rlL;nEeC=yysp{`c{aYUN-9!un8S@9ze`MmrEO3ItCn-#uYBg z#I&Y#7mQ`ySpD=Nd6o$Z1R`=YPc$COxYB^hLz2VaOckszwb-DkC~LzPcPSD+ei@Xjn1{hFrIFFFe0oSk<+;5TY6Jwu3kJ6x(strU;c`T z3C*OXNhHa;bED*39p|gk>?;i9Bt*m{Vo)^O|0cFOBN*3Y=mh^aDEfbfu>X(k!*&1Z ziTZiR#SdJZ;}5Ps`C0LvwK#ph|JQ7mCNF9KOTNVard)!5lbyj)%{hLh>Eb8Qi-RYp zTef9}nzVn#FgC>p)gHRSpO)_&d0)Ln_9cO?3qy%YuiLLmladQiyxvi2i!15~;rX0! zPQHd~5KoR?LwtK@GE+2cM|ZQmSX3eJ?bY|o?==4_K`gzzr7y3@TgT@BXc6@HnKu6l<-wo)=~LPbb=2G z|DtuWBhez!_<-DQy92QUKzy(%w&iSe-2C@)_qfU#KUru;7p@Sw|EY4{W6|GeI5OC% z{DE+sup*o@RtP&*$}(~mV3i873yi_ZEqngLEAa~*L6gr=FPg2!1ugt<%E(L8e2X<=N((#&M6UoN7dMu5U;G%c_c6x=eIEqU%)s;rbaEjru z@Jd&V)-cKo{PTQl#s)>zOXR z*A>~<&2{=bOQY`_BTHnC2wrD0xi#*z?~;3I<$~+zLJb2bpGqZ8$VYvI*NaYDBH;@M~~ahu0ZG0>_lxO2Plj9ypDz7WB{a6XLuEqiL%e2 z=wBgF(Dnrnk#+rBZoDB5OS;ZE&BFUl)#mbVqZ-J_vaq~{4-~jCed!o8Q90CocwygnIEu z+70_9lHAm(L-E@?ixLD(e5nU}l|H@#LKmF&--i*) zwvRp3dFtI}V?@G56H};Uep%FjDBs@v78~T)ePA}t+N6EFX#k~SyL0qw(*tQfKFvff zkeqDIQ2$!mf|}6R%`_;K^Tb`ubb=gRT~h(-u3aD+dVO1yOzMor zNa?Lp5|@{wo{X!kj45gMv5j9%i`##NfI?ozFiB~HxW^x`u0%_l(|2$?v5b3pnj1q; zV>jbDS(+a$W3Q-_OJ1>UH7Q=0%y`MOPG8dK)#Q{ACtpY$hpQ_@T~j|g1GVCj3U$s{ zJh`-{%Bd2^Yt$ZRO>+m&f7!z8z@QgZpxi3kly!m#{2}qW4I{xWgdQO+5)IptG=VAq zq~hiCQlON>9bXg+32LN#fFD<7(&T+V-fk(>v$A(AUdW`)-S~Ro2-t=;{$W2$~Fw*v+SnUy$Z!pA{$5touD&}ok$`Dzk zOH7st){F~m^jSzbmg{nN0Lz)y=hX0CO`Jh=R2kkGqxZFu;6(D$d;?6lu;sNDN{~A$ zml(@a@;g%rdhW+TJK7v-Ky^BzrsSO&F2PvY)5T<^34#9C2-}rO0-Y)Tf^}RDS5?AuT_BH>W_UXR^t)9Pws}mG|a5q<06}p`5=~ zW>|2#+|yLyj#KqK?+=VP?Bv6iLt#0QbB30;`!ZmZfJZ_tGJ)i+JaOHCWys)fRB)4b zK70UjIA^6VFh--s=tWuM-B&ZVonig(r3{xNl$K({LD&kH!p;7fdw503>S9i-Ua0UV zZXC?L#E1h(WJBYt0NSnUaXwqSXx%;c96#K&fXrbu$_*1S+?Cmk*=j)4!=QD}Kttqm zq`k|5>+$4BF5ik*fNPvtl`Ep%JQU2%O0TaiTv%!qSi9E^BvHV%F~dAU=% z%1cZyv{yZLimxs(I>T2Rpa3WMUBUGzu<)i_*6tP5Ujo-&Ek$TeP0df0hVA;MDR)j`WyNj5o?|o=Y{yxX|GF5P_BgtznF8wJC_MBY^0fbvAta^J$i)p3Zc5 zX`NX9Xu(DuL++qk-OMw{;Ar`sgU0Ei(G_nJg;Gh~>VjJ~*ATuFi7!Z3_NllAiC|Td z8qZdzksM!=B13rMXXdNTSQ!V zuhyy<{gy&`edPg$0xZ0dtM0~&28gi(uGPJWogC31nL;?N$qEgh?Y6@9TJ<){7$SJ< z$to~zeBEz7K?d@{+11;?U2<}lV@&2bu33*%;GHQ~UY#xD)vuz7h%Zq~?lwS~@AGus zev{QB7XyB2eW$*{*igL~)u@3}VYB*D^t57_$-t2+o9nC&tuYQc!QFHQo1LC(;`Vq> z)QhT@GWa`FN{ToM#}3zM-Wi3g5t&{>hl3zv!1gdqeg*w_5)Jd8OMHIJ^>8>S^$XEygiyQeQAm$D@N`;9pP?cEXW0N z@aB!yi#znS)b~o_$I?wS#sM?zWm;&vK>>LOS~0aCv6M9*@J5VJI!3{c0buXYey_wVd44*V(Z$#$7elXfZs|nY{ ziC1CoSErY7-HrbZDJ-awDrwH+-E6(h_9LcUy6F*+f0k~+EUTPDUBT;9x*-oUMJ|m3 zf43~YV$Z=KbALghQ5rhWApW(wq@#)RU!Ajsvy-=$$jd}Stz~%^Et_N)xp}}zb0*Fw zqx|)iDKfvEn6YTz%qo`9Gw;e-_q|3!yYE4pjPMd-Cz% zh&Yf0ceZ+x!z^|`qRpiI(%MgLVHrJ4m74!9h$eDkn&PSl8qC^rN)QlFpV_z%%cc3k z=C=^7gKHIOmDy&{DOe(ECXyO9zjf*1Jd%G1rT&92i>{t+5Cb1%K=}^FRcj!sl{1jl&NJ6g zR$F6M5r?RDgFVcA?AQ6uK*kw?SXmupY|3!+wm>q%lcU5)_OA3nw21~^uQ$N+iuA?I zDpEAw{Y08I(*77SdK=2En?r|(k`C-dbVl{_zJ%5Cj&Alc-s#yu(#tma=slj71#-4k zzqM?Lgu72CMS2;KzCu5)P<*wgBASX&E_tWsaxuS;qz^kTKoY*>&DBDu43u`AjM1l< zuYZpUsdSPj+WaOHVs?*O>(O|dMy$ZUpe4W9G)y?Hb54Wn;bur49bPN~C4qS7`tUtCtfXZ0O9P0vw%()~(> zEc#GhbnOQwcRgV%PlikLAI!bT+tIEvbXz+Q$(jvaAJI0ie09fg=AhcfDo*k8jvPh;Y6iYp z>DCw7!URCcb@?|!bF>IqPIYPwE!b~f@XLJ}^`cjQ&i@_~^)X0o>tz)Jg+Wl&w>$G3 z=|_&Smt9H9--l)E!e%W}9sTEH1|aexVa=mf==n2`^~&UUBAN{H_#(qZq7X}F;AQ!e z0=*wFIh^i&jav8~V|Ivmkkv_}i)XRQVB~hflhchqNIXB`%ss>QIV8b{cS?tU>Iqfn zVwvJ9>ZH5SU1F75PB+{Xa7LvM4O@}b??*FqEC14$VyLOu1P(Y=?@bXh1^KmS6^bq=_2EbqRk=C-5FB?hG&VAPUmI) zw=A5o@Pit~c?LD(09XM`8(K;$srHdf1_0Ly2?fIQKJ%ZXrTfy#|Z zVR@VO$PXnhx^z63$ix*;$-vS9Ni<+>G_tn5R)9HaDmmL9*QN)(mI{2cb12=Uono^= zQRn3(g+XIT5NT3g8t}Hc)t0HBg6uO0I3X-Bc*4-6QW7d~RKM`0Lg=Yv^ejLg)3tDK zt~mYnPW$gVskxG?`drkXJtMA{>7Nyn`8)fTcb|y#yktGLYsZIpxh1{?VK21E&(^;rQ#RS-e8Tp zZ-<39a+if2pyKom9#>uAS`1_oJKinu~sh3X2DLMpbKAtg^$6L+3%QPdmRfu|h zR233^nvJ__6$WZAy>5#C_^b;!tiLF-NNtFPT6fFxhT|6IwFp;->8-Yc~J?x=I4aEmf zs37T1$9dZGF&S|yfWgVu-7S!O<7DeBH;7*H-$|aIN+!+b&Bwag30l9D4ta*Oj38&g zX6XX$^#?4OBrr{7;jG+*xEous;v@fa&D?5-^JPrkrG4B-*ozh> z#?VO1&rH;4wJpm!$MaZGS~h8khY938;_;|PtwP^_Ji5}m$HJi&a2Z=NERQYL@Q-7p z-vjf95ezMk+vK6~*9u}^=Fg5P9VVZ5@_dNSRhlWy*AtB??(kIJ6q=(fAhxcVS*$&r z&eNIoKMzgKzB42E@nq*Qfv#+#>#J{_wW#n7YHBtMfEK-J4E;PX8893$+*N!W>$fA# z8r6bez47Bo(`*JMH_<<4OPJ#dYBERQ__EqLwwJBK&)Q}4!<2-RzL;N~&NX=0av4x!c{xFV1(c3x%n*Y+mCm8FLWmvI}vMX=#|!$JJz+kS<9#rkoQ%)P|@#A994e z(=Q59)sj{qY`^TUsOn~&VGzZ-)}=VD?$dE|xHpz-XWhPA>TmHjYO!VX%}%rtB^!LP zK!+@iILw6Ca4w;A6(g+0D}uP0470o}Pq5V|(wRd9pC{AlDHeh?B}Zc>dZcQTYj zMztvCwnS72Rw2jpN1{7B_NwI-%G-cw+mhU5&l3=Ahu$YtM=@xDnr#qY`#%Lc(^3W|~ z<%-U!C!}=io89#U7St>!vm4o}qK~IY4~zqIYC9aE6`959NrEy%#DnV(Yp)I?eT9RH zTEL|MZH&VM#%TxF!puAmgyG6dQ^u6K@HK48B5{qPgAdEv7V zqSO(rX##2&1c*vL4-;vWV;gCRT75&s>uo}Q>8r!XqmS)$5803%5DsW7wE~A)(0ylt zUf#mHU$F;;t)HcYv;nCux4gVvI@*1Q=-BnXiHw!^wZ7Ze=J|@53Y9SuokGJGi6j;CWaQyY#M&8Da{4ES zU!Kj>utAwC4`uXeCWFGsCz3 zgcl^&bhcSg+>z3da+=%ghdue}(D()vziDigZ#HPyCK}iM;|Zbm$NfI=3wx+jGyhl` zFCOQQCz*YQF;0`3@dqYUYT0bC=VpsWRfaQ51pPjDmkM9IGd&^(PDs7qlE5;q&ckg} zO^9W-bn$?81J)x2sAPOtmOx#a`lW~IHxk$iGF>g46CCjbir)*N%6V8H`dHg)Bo8`% zJh@9v&31QSDl(D~SbrPe->HJ}ag@&3hxu z-*k3dnddTyG}#FqcD%hQZO@Yr;@mGPnMfCIzF+T>YeE$-56 zON`;gruXoaK(}#DA-QASt~PlTx3_gj*;$SBLHo_n(CCjR@BC5mWFB!8WWl+vG2VqH z<8WqVS2R%xawMW9g(hS8%890G0}GCIO#IZG;bu97wlHIB5*AFKo*N%OSKLmURkv<; zj34`c>axmZ%~&ZV8s1{v;mFQfGr1p4i9x8g-*E4EO3-Ff!OLd+EI%&I7-kMt4MSbQ z%aOKHZs$5Om=GKBP`|_swGfD=2q0$ZwPRv?6?6$yd4Etee9wurUa`E&s>A(81_YAy zy@i0fOhg0^uw+gBWbdJt92>%mhFqDl-Ay~PJ@yaVzviG+SYowdbe{Vxsd87s_#BaO zyJ0kJvUwfGYW%F@3IfoMi8>H)C3Q#?s!s~)kP1-6l+J5?lz~Y{>Grsby+(` zN{-)*N?d%Msl%TUD`E5XuwbpXfHM<4{m5jLjy9odHI^0^hZxlZ60NF?v&OVX)-fUd zn3V4&PI|O%7mQ`L*2LfX<129cQ4pk^OwGDEcvK#)NsvnjC~4uqA4nNj1qG6jrKm~l z3jy1^1V;U(bd8V_Ih8j!zXpquRzr16u&4Mtv{1|Am;miG4W?DXHVb*Hd}%+P5KW?A zx}--OWV%)jrGMVj&uXidr`=ibd!=)PHj|&jFW4vx=Z<%Z!fM^_7azC#F~!!y)}xEV zQPO!^BN|Tc^ z9v?j?d)%<^z>#WMY9L(9M}eyr&5pbzh@p=-ib=rafH?Pl#EDl~B2(9=fa2SO_t#yM z&qZF=HNTOL#-WS4_YP~7v`Y9hR{5tT^f&zcms#osyg#330+5!*Mzt|$eOPwIm<=?U z=oI8dfz(+zo<~K+?){h4Ye+N3iT!_X<37Hi|5InUQ%)(_FLUQ=Ha#B;-A)OqLtLiq zu7oTl9E9s8A_R2Enk&2v?U4tmb`JUW38%T+;z!u3vOMN|aqRsp^n9;NN5rIsm`Pum zid=cYvPy+s1HZ>BdGoc)tbUXjbAHi%(&N&f06;tiE)7qb-u`s+y4rG6(tkDTQl?oV z1_77V)NQlf(%#x|=P;ul4OYyGY4!EbwJyNaV62a+zM1SkI?Keaq$}V$3yX>-VKe5k zivl;Pv$(HY`jEbW`B^A>gJPw<-budCs(NVB6TZBv{N`e9uB1ri%JSNV`BBPSZL%Dj&oDf8qB&9P;nr;w^tCjOIM z`DCjULX+#`BYlp3CmPp?L?C=SOYZ!12-{?ud}d*nmPCVQiHJWZ675%EnuW1L>8_!{ zriYzm-bvd$raq^8D316yjX-|)RP|erEXTbOg{7o7Adf725VLk4C7eNw4TsjEd2?E) zm5ad@g3Jra=;ywY9e8v83HhzX#yT%0Kl;ZcUcB6((^u@G)aCF2M@0u>Qn9_)iZ0sPySe?$fVIq2^FbTDZ@?FJq`zCR3+Z3 z*&V;me(Isxh$45Hbe$RKuv6k5hj;PD4$`WHi>Ba9`W*ce4X@`xjZ~@ax8mc$EI^fpx)o>V+`zNBC5(t5|s}R>uQUFH&f0N zc87W9eIN3z9MgAcq9m6pN)0B5vOXrb_yaB<+OzNT^&<-q^1n{Gsq`>6DDB7%t#)~- zDsnBq$l<}fLZiz|?w{cI6;eK*|H{{-s&qa4wEgWaT_vO4u!e2|!-VJOkWFF|`Or#> zGKGPnIAw`=2d;pmm!=-c^Prsii6XeCaS9uab>7=NyDFGQ^w8?Hu$S(~?$M?Y=0K%4 zuULZV-QuFqLu-~a0yRTJzF1%nK*Cn6>ejZqSolrI2!C(2i<4<)d zsdVQ1=V22(JQX@(XX&s9a!K8ozS>QsSWnfX;z7-$EvwmMoa;tikOK-eA_@)4kf!^Q zkJNDTCO&1Va?uEgW(W^^dPR^q4^jMh;=mo2M;5rv9&wTXW$he@IL9}QaE*ZU5^_1^ z`{N0}gL>sCXX{$lwlRA&_f`Pr^bGC%d^8%%EYirk*53K~AisUJ%y$(z_ zG-45!nLMIImS1w=%sqm?y;b8~t;w?ms*=!)+2GLd6_=-2=cA#yqY*TJ~*g||gU zP~$Us15+MB?-BXsU{N;aryt{$JEs!%Nuj)>OWW^OlE|GL5nG4LKfj4mkYr|exKZ~08j5+{ib+BjsqGC?~iZ2-NbTSJd^>qj_T~O_c~kXs0z=WNK4T) zZ{E^-FCInu_^BbQw2?2HW{WYBbvU)W^Gowzjm*G?Eg4)O;uIw4uwbB zswlWKsKQiTadaoX{+vKp*Q9cRp(Ndsi%5JH*iPeQ^vGH58*g$9$ts zm&qho$jBbkQ0SVkraZ2eu?PcnQe@R!#DV{9DDdvCj{)*5rFVYS%}Q4PwW>DiDrdF4 zLtgbfl=^rOO4q4NBm*peCtfpYw4bWJN6!}xAEzlEIDglNvaGGJye$u3QlqNlDPm<^ z$$e0Ea!9a6^N#FJ79(@?t&)<*9oyGCDgH%1?D{Fz z5j<1Ioy#k}Td=xXIP#xdALpKYT{s@{?aD_&vQYuYs~mV9qu_u~yO@d0a@Ip88tsze z!`K0*U6%ShgVGgB3&1)88zL;xRMS`5L47P$I5CEn^fYY~>dL_y%*`{nh2L5h$72&OG1eEzU7rmIxU$Cr9C2?e~@z%(kmN%dwKiR zlmI|`?IS|!X^V*e*3-*B>?ar8`*q(cbKo#px92$7pBL&^C?XeT$Pln_H|<_?w$*c! z-m+x5NrH3BhB+*h<`L76*aWRLC%aMr=44z(fpo}FsNSUBvY7H`3QH9|`qpF_R zE1o%xv#_ITe*2ks?})EI)J7ShJ}{DiREr|`f_i{0qwNfFN6B~wS1*yzu-G_xS(s@< zSOVKt>PQWZK7&wBDYG5Y&DG#LQWSv7ZB893888njbFp|Tl4wj|@RqnIv#V>{Ldlcd zRq3YtM*mXtlQ|)dY$_nrb=z(_IWA%)EbYd7Ec6;G%n|-&rHxC+Rm*(#@H<1r!PPyk z)|I;#GQ*u<3w)es+Ol`Q(6DW*X}WpMO8Icb{K@|t`2WM{$uQJZa4(Ya1qnc6@`XGaywM;8&tVylMP?N$%$%mQg$sIbVf3oMl3< zU7(_0kK@S~!w9p5LhtUO?Acq>aY0xQjvy;6h0NVccq(}Z&d{XNR(#R11zp5~AE&>* z&NjHLKv-z=S_cB@b2xg}|2}B@|3CQut>U59qNR&JWrV|^>@zfB^WU&VUSoTzF28mM zcsAG_oLv_+3QH{ZI92v2-7|U3xSfg#V7e6esyjc;0}1>7aG|IJuglt${U=MK9>|Z8 z6f!H1Ht7@>SsSlH>|t9lN3%*ekeOqtPp@}aiA^$|xVwv-s)A})#tZk4wT-LNEe;Km zlmdMeId?Pn5z{_*CyS&|hX33tqa$F|Xhw3<5zX%U1Rt=(GE#iuK+yq0qXjdQarrvp zE?NKXWt_~HZ61pzI*P4`P0jis;9PTyK36m9G$%GyFm!VjgIOy4ZH;l%_LZZp`+L|5 zUP7iE!znh&q!I8Yb9Qq_$XP5DE}9ms2~r<5-FqmtZi!U^T^Q2fH`#X)XKC;UN@Hd% zA2w^_P|6kX=lx$aH3(QbzxO14umNEfYCN@gMuDssFHxaz1WEOCWDs(_R5Nnomex6r zud!!8*{U@85*{|w-506RP0I9t80 zN{(a}D|{+l)xe8K@q}}MYtelDh)xR_!Lt-^031_EVQr%t?Sc4;U+kPho&g&$WH}8MG^vAm^q0KchtO&OtuXK#q}?D3{! zu~pWURRKa6GVIuA0ucpDjGTf5`jk1%iQ+vuo)<`fW0`Pb;2!ys8)$B7bg3+$=oP7} z{Y3Rrq{6;K@;&XTrKgMaIi;*pjn||5jRU+yj`y_E%o&8OqM{CVYC#q) zUqd@u!ox|cv`9xbW(VA}=AE{+YXxvf-m655K$SV}uNKb3&IT0KSgK7ccSitG<$I~W zFE^5VXhX(0Bn78IdXZQ(!;$LWSq7k9We`7iY1?QXm)CGSxujmzg4l`jv(F8o%hz zBokHAZXSzzV|@G4#*X2Dk`0iG*{l`cC_~A+VSV@;u#Ro1I%Nw1{HPtl?+>$Q9E}UJ zn$JU>L)7(K*?$S;Vt&JNG2_6^5y82psn^$K(r17VipeI+A?>5No6{~jOIBnq^(>m$ z8I99wc)0s~vXUK@kbFEYAIQYSuCxapiJ?9Ks;#Sxb0^e;b3m(rUMf zok?N^Ebv+oNAz=g3E0TYL7kbo!#ze$LW3ZC>61wI;Tt+Q3x1z3cnO~9OOIweSBk~3 zjA%q^!dN*2%_|+hdM!>1#+Ks_cUiWs6POB&>&&tx*zxfcUJ|ExZM~hz&njV*6Zl%T zB`$_fZSKyg6iPDvev!KmpUB8EDZ&T;4MSFR=G;iFZ}{T)?Fi&W{%7m4klBU1kWaz| z<1|9?KJbXTO4!|F&PH-uxq+;6)F?c z>6U7_TP;!jiBVt^A6#d!X+C=18!3^#@yS$!Yupf#_TAC@2+NC>#1#;~!0@%3^~@u+yr4)2EV0I5YLznc5kTAn=#{CbQ4h zvf(~d>n|{K-jl*C-?}kPru|5GxO!|&IT>PHMo6OM9PXt&xD$>`*+7g{yOYY)zaCnoSaTn zaHP+KAK;lvO9ff(#D8LQQDrd4*M0g5PyeHsF>5$)|OZQ6lHa#F(TVbvyM;~SYe_ugoQ-$)!0vIQG6JpV5KbM z`HF>@c~>F8?o=x>Dc5N8&;w{+=FS`NGDao`lUmi^C8*D?iQUaop-+P^?#_gniCdJ@ zRSCI_now?16TEOOiEutuCfRwLvVWf^5ByV$o%Ih`IiI&0Y&H3}`BD28eXO8hN{~B{ z!L$+^`KQtQiDV}6aYx>6!5(acaabHL>@;?ayx9n!xiO15yWHOs)q@-eoqDFUQ0pU}f`M$e_B7079DlE~~2z0dWBShE{BANP@QCG;&a zFUY39h3g+MrB7Gwyw~vi%8^(1f52E2GBYAJbv9|nJeO48f~?{8x3yt3qUog;Isa7G z6Dw`3Hw^lU*;`GZJ|cEi{l6NW)UVHcp(`TxTlbu-JTo(oY=+w>hJq{BjUpp_+@u<> z`X4ZXhDoB2 zPmGCX-nSWUJ2@#EAnOx#A|d9`^|Vh&ThZzLSoo~=OA?`N)5|S;6qnq^*Prldv4hdC z9RkO!x0*xUMvwcrNu&)ZMNopkx~7JJRyDwxqytbpfFAPCh%fcHC5gGzr_CEJ= zp|&sToclrOIfHwk=!1{43QMBV&ZlG;L2TMoLUUwb@L-`@Ya=~0b$Qh4$zz}}t-SF2 zdqwR}^K4Yo!V-lk-13xJHcuS0cw%0T*&5Vr>R-)g@8jBQ8}}zu-5{tmN{CBz<=k9V z@cuBsNp8b{QbAZVRn4OxBDn}Nov#)5B9BMIwT*Q3c2GT}KGg5!rNx=tO19wrwy7z- zQB}pD3B-d9C)8{_ogon72CF?r{{F_yh&q<>mM}J+4Te5P*HBx>x@x>+o)b$tm^FTB z%g$=d!30g|wJTk^#dM+gaOQljg62YFvdatfOW9cCG(4RA$^*jF3u)f59Vb9>au1)0 zSTOd8l6NIF7-W9f1T!ZYk7l?YW&ODRzg`Oltw!Z6^8g#-;6=D^$~{Qk&`t zsdpbkO#7TDF3LzGye(+6G5WGOl5sD2L@XGyqXh*=Re4>v62%>#*@x-z?;Vk><6BZo zs~;+iG_}Z6f3TU?d3!ig?c9B?sH>1C*J*c!9MT!6*Ta6VzJFV3dg%rpsq22Sl*AoGm;-EeQ8pvITv1efk zV%Lb;XsWhOhboEZDbK+C^*ZRhq*2+Pu*qv#)(|aII3HDlI3D4%Ovlh1%{3{^$POEe zfI%$aZ5u^KZQ*AGo4WN@8q7M_A~RUe`(?JCaWPh>i_T}7A`ZmH5MLvc_4-RuI;3Qx zh4jh~t+Feeo2qX6NyGj+TIcsqemnUkxw6(lT#*S5r2U;UXmBRw<8UmZLM2GQCBW)(rB?r(dBNm0X!4)RM3H6s+ zf2zGT1lkkghT_bcV*lMh7xBi;TUHyc)g~NOw#zjTB>=ctiAy|n5%oLq1);^!I=XKA zRPYukIK=2_|4o+s*QvXFjokv#de50h@BvqP9gcrDq|ivSlF0B190sjaE3L3>q5UN)6t0`0dEw}n>PnO2(B z->vNI-)DV>dwl9^QYh={`@RkZdhlTVb{aXpk_P+tR+2tB23u}$ACJWk7rAkcEa*d#Jb+`hx z|Azh_T>478bSV5dVX_~e&iZl)n$^gAVguDWUftJnV2jYW4HqA?eA*rfSgYS&-+fF9 zkXYw5E0PNiv^sWTo|Ml7&BO;|t!7@H@i@qVPqudH=tx_};MCQt^ZlGgc47Yf(X*|& zx{Sd<_F2(;StYH6W&K0n&NTV3>eLN0IbS9HdZ5Xa2k@%L8_xw8XDwE~wf_8BFcJ!N z?W5Hjju$KNNMFLFDF5tztgQg(PP<7-F8NH;teTmrH|4P}SvkvdXB`JMpz>8q$H%J; z*)5<16+5!5{>I5xEeU?Q{(at{YHG3}yUCYnj}DZl1wX>>!{kHj|3d~=@ayhft4o+< zOnTtPot7SYLjDaZfD`nb4fS;NPZBXHx1HeoM}QMtEB=Yh9z^zgY~CgG0}Y9bIos zS^yg?3Wl)LK1oRkKeXDZT{W~C!r8+7hVc(rc2Dqf9{UsUxdZlKHiONojvS89NToY4 zJGjWGX{$x_HB389JQM<&3Qvxp4d-tkwL{%?}Lq_E>lmE8z> zXr)cAP2dv23N3lrc0lRw+mA@ZL><#Tk8A<+>;ftnysQ^_{|lLxITI+lu_i!wWIaSu zVW9pu0;Cg?qs{Uf%zSylHC>xl^pV9zuFajvY$ivgvlZ>@4E`_rA2O)jS8pibujDfN z>9n#{OB zxCTnY3Q502hoN#3b(Rasi-AJ|E=}3|>47rqMWdKWEEYd#L0lfSJ#xiY!v^J#E~4d% zybOJXHSJuMP#+ctuz9|)0p9`#QIWV0R!bd`N($RvC2F{FisR^vLJ+?oi&4(DQKmd0 zhS##vrz68`IRy>Y#8#uonU}ati`HJwwX_BbP0BaBe7R5H-mTELBTOvATwv4pzO1)lgq!(N z$taB@#2+ngv>5K(!X7!BI6v7?%g|PCV*@61@N;DU-xsj&v+uK}KrexBL z>}xzPWi^Jv!oUEc6)r?QXzZ%iGMx~q*R$$_r9gSB;9WIdqe+TwC>4^+BPv2G&i=e9MILY?BCJ` zzc+yA{Ro9#)upC7w~!%t;O~^@`ioS}&VlG-?oTTslek%7qX%zd=lVe`?CMm^P?WO>KMapmG7ki*c5kr8V*MO{4<(^6Tihb{lc8b=6S7F8hiV8F2r#O(ula z<_>)_{qn|f>IbF@uDrl2`ghk?^jMgs`E+Rqq{&=eM%+(KOTdZ9B1ow<+h^0tjWbaCkzn6V3=hO9ajs_9`4#qA%3fs#+cy7Vf<2bY2nOawUxVdxI!pXl zE(l>TD}^1rVx zW8|M!1afd2{Y}4IFi$f#EiQX*mEO70AgGa^ZDj{9I3c<4tFjbc@8fk}%d4f(^Z5{1 z$q%=^vzW8ksU8$W~ zq)HGMTXdLP*--agc{)^pnH?S+Ea!Y9I%+#=|HMn?6iDM)0vU03l;OdZCpj}$*nHVZ z@%Y_0W!}>zKjLa_5%*pNwmTNXfqD5uHfz{h1GN`DU7&eOg=4X@L;F~uV#a}IhUZd= zz^46yjJNGcEG#99wUR?K(5uEB!m6GEYYua~d}^MiY&_H{H4+ZL<+5Dx@vE_V-2|D~ z4&I5@D0j6!V_ZjtxKGDEG)FR?oqRkM;+3PRPT_75Pke+Ni&LRPhZA7}6I@i}P`+9% zPT&B+IU(%Tb}OBHsVVE-@FFF?eC=A*`+N=!v)-$eno~J*cKZGqS)_e7&2cL_0i~Bf`saFtng6zgIEe&;w50oK^QCFR+XNQ!mI=;xS;D; ziiS%VE(u~TDOiyo8O~N0!F0vbce*Ljm*W#inz$&HYpEv;^nJaPaYHpJ;n(GSR9C5V zhf-2q9pQ-yb3HAL1-Gml^JG6%V)lqeTC%)SNOR#{#KfS(2pZ|p1PR?(+! zm&6)@hp!bINS;{boWrKKA+gZ^qV>$r+-YSH z)@i2`mM6qGWh&7xmp>H!Jj=E`fPk)&^Oc>1WvanXyx2@Q(u$k`lB(o0x~Lxa#mPGI z4iWCc$4N< zS!G_^j<<}>qKJk-lbi{|x;1?YR!J<-nT9*gW`KnrYU%J?wE;)Ff6;=(iL0(GB8Hv) z`dXMf)BRMuhnf9)ykwdq>*BPng`8)0RToP+_MO^@yHoGuv{mLT6=RZQHH4i#zX07C z5W~6}s0JVR`(cwCTf!AXmy~wTd4ZBt+%+|8PGs4c6eHidjSgcUXC*53=}E2wX zxP`g4`}ZdFw^1@Pd_>8nz`7qHi4Flq#ra}4LjQu&ptPYNoP?=#<&8h|KwbtJQzjNxLTXCCmLLJ85;otfW+>~=pU-4`tG&oWpb5)E$~s-{ zL~YgX_aU)B=yz$HxvnO~-p4%~Ag~$PjV1ssC-Ap;LY&UoBaOY(wEzX;+6iOKAC^vE znQuTzK5Vzxrb3ruN#3#2*wQHWIO+hTF1)VO`5z*vw&ta=RshwZEvqHJ{Eo?|xF*^2 z@c>SvI7Z+^jl?WkD>}u%=#x|I~8z^#PN~n^E$izW}9)~MjXBSdP4ks_{Zke z0d&C^Rex+zTSptbid(f#RVk6rfn!E?3v%v?)nJR|Tdg%fK0C;4c)J6GRPHrg(ymEf zhTIB5CpYKgWc%FE(eF4y*oZ=4_sIAMcT*>L>6dz=wKti*xyfudDLc0mx;;U}4AUaC zu|>_0BpgQLM2bAEOv@7X%q1;XXBx?QLK!>Tu^HjVpgN^~obNwx`B#`=na$u6etH}B ze|hDoMi07++2paB#s8!3Arg3F2OkVSv?29#i;6Qv9rkUvkdFlhuOP!HLLnM8VL0=F zo@sY-8a~Blpb$b29x6P2O32$pH53sg?3i9QB@3Hy5*0D=_g?+$&TL6Zv{+7I%8Azc zxaX$!eXc}MIw@#99H03N0dkzaKKYoP)d!pT>2n6E_Eh?_zi2`dCvDeK%Pd1x7Rl@X%r*Y^_LE|E+ne zJ=J1Qk2HD9QlMFysawTYA=aGxjnS)6^hZzwT~_RyI{cvUTVbdFzE(cPFO6QE;Kb}L zD5>}M2;a6&9_}A7q!AO_cEZtJl^LFJtCSlLxgd$fL$N*!zsBTk2($$FJ-h`s_eb|? z??dut_QsZ8XPS(Nd#oIspB{_2=?zTbczPRWuGIHz=*ocS-$}}ODeCINu3ZPooVpbf zA^R|@%w#!`Ini)?t*f&BXuE7s!Lc_WIH=j8=6I3A$V3L}j3;J2bbMOD(LC3gDDvEp>0r!UZ$_S+4sWMWAhavblzn}@JyU|2 zV1tnVm0uS_CEDj~G})M8NL@FW(|TEDxmcu)!>rY+_E-x|n%+t_;p$ooi+uX+yq^$C zFA6y4##F=h=l35ou=jC|hm5&`Vahh#3T-LX|hcVdP#15>+2p zPR5|?R7tF%bD^TFoSqBwDlr`i4_c--CgMj3XBJ}_S%xJmP7Cji%#G`{8KP-ofzgCA z*>~=na6m?w_ABQHF#u%29QKr()JAw|BZ0ZBHD42q3S3k(4~E$+z?%OQOhNff%gQfX zz&Nv_MKSZLP?P{Q{s?dN$nWApkFGTFe}6)mjEAxh;`E9cfzG%SWg%7jS1+kGXFIFD zMq3+tT?sgN3d#)v&y?j19wyY)RddnYT+V^jH(=D9cr5HRBX+LfQ|X>r(-esrhT?#j ziXXOfrcH=*MOYFO${7sLAK1!KXZb$6en&+7d`k{?EnZO**hx-}ug-P!bU|^jS!m7Y z8q2@~QnudHkv>#oam03@3L=Ba>Ls)bigc4xmhZBf1!Al$0R0Ckx~L*=aPS7~@;Wka z`u#~>1}6n(l}X9PU^67%fc8eF}+yC*5Pd?4sbqbZWd9PSJZ&764nt z*#5Dx;oF=wo_$EMjib%h;0jzEDsFvp=%7wXm`5+{h(0{j zgn%>Mm?FjM>myond^o7E*wJOjC<=Pc@-;sZ{V7akQYr7-WIXn>TC}Lq+Nuc;URS(Z>h#eo{C-AWU?F)s zOsI)Qj)78ae|aYTLup>PmEHR+$Y2qL0~4-gVU(w@a3NWj_UtpV^PF~gk?(DhpOg*6 z?m7K;tHlF*2IxeQnAJ<*4ov|7qx^b1a${bKar((xc)3$LlYR;aTo^s6odoMdwBXGr zbXkWzlRSG`kkF}&Y>?(fpNjdoe|jpkkX1}L0MG(8k0&jr)hfaf^YSg6fBhC6Fytdd z`$f(f8eA~ol0~M<8yieY%p>%50(h*9%K$M=%RbnV30PcF=DjOLq$s?jj;W`Ym6(8i zmN@XB_{qE>B8=P~4Zf!v&k^TLr?F5VzXy}F@X3bVbq@QijpmqMF4uq&T{+Sb?}m$0 znFD*(Y~@a?`<4tH-Xzc5OzK1%*^!um_AMC|S?NR-#YD@{Di(3=IceQiT|)U6rdGNm zn6EvBSei*Jv3r-{Dg&~OJlBK{XCe3~N4Ibb3l)_rZv zsS6&S$>n622L|6oh%1mE+@H4F#A}erUz4sJc&i%1&8@(vzU&6Rq`b+P8ObdjV=ow! z1!d<5iov0g=+(MI0*yB>`C_-Hxe>|7iPexEKF>8Vd3AXgB0KVmsm&%L7c1nCQC4N# z%vR#7nozrK{j{)h5X-&`$l!isdGDZ(Y+GCuV(q};(6sv{_xTT)lM$!Y#aUbLo-0~J z**)sjj+>{ zmtL>MNqHq6x>1M)S-tZb-1?w$^KY6qzhh?OgP>n{K4B0DR-icnAdxX>cy^qG{YpL<2EeME z8v0`zKUA4r`&3>CX%U8cYewOHyf8&P@HfHkoaHzprmMgBwrh%s72(Gj5lTkXIlV=# zABUA=OKR|F{;-YPx_z=>4SVj+RTTg=vuv-i&EV+kZD2#!%RRN(vL8b}**@E?OY(t; zK6yQQQPSPYVa^F;4ZHTWI!2{q$=9aRs3!fcTydt!N*ZfXE5u7NbN`jLa~yuZbNr$Wr6QY zb>2_Yxz^pkH-0l0kU_0KImk*fOfR%&O)~ zgFADJS(riS!G*jnUQ4CE?8mCY;fuk3jexh$+Oxx2MXN%x!tgH3)ws7FCQEUM9F=`I zu7&>_wf5H|sapO%BNTwWQ77S>nL1C3Jk6gB8X7z|N?NdrLx>XpaEH9P_#=BOKZu;r zQwS-#wa-I{zOmNHVI4!vvTS4t&1V&7=7?$M&!vzTCOg68jopVx+Bssy>To-H z=4Hp}xN{^2W|q!Ioo~IB_8~YbkVRBv99g#pT-~7|outtr*(-8N+UDSDv0z->!22vu1EH!7lW4VFbf|ojI-hOTwPLv=LUKIN-Lu#Z@{`pIV_Yw~Q zY?Rg8Qymh$%$5bAF0uYWeEGCr_6C}-8YtPZ0(ATRP&txY{>3iU_`ye{(;^WE=SV5R zbZLZgkNzT3uu%{(yzko|eZXaB6^0Pz^_XMjl&y}{k8N9o`5DAk(2u2O*1`^788T@u_jRMq zgjnuO1qOr);~e((ke7Tle6L2cjEw`92}A@>i#ivz!}pi|PM+XaO%)0gh>x-l4;XkK zYOCdCt8NMD&Msi%VEa-Xcef7$mP@GW!t@OGWZej{xh=yV=*Oq9p!`-X|&9VGMoB0Rq4u2L4A#BYCf~ak( zs5wgI#d4mT9)#_n(-B@qY3kroN=9n;aP-Y{b<=O`DvJbH=;(_DQ+v86sbLG zXiZ25^|{4g`&oj7ZX&~MSr`oy8KcJ}m&UwdmO_WI4L*e=^fc6-m>psQk%2X!2`lF2;P0}6kSg#5-lb!O3CK)Q95ir$u3YMf9{VdLg(RXB zwlxGQO^QI_J=~4sQrIt-f`jWW#AMKhWI{VqOCoeKqcq*2J-HJdi`p0^2Gw%pjb^nj z2W5Y%7g8V63}6?3QTJQLXrk`M`Z?zjT9d)cTOAb>L*QIt(7p_N1bBsbW%@%UTkQ_D z0A`ZjDVm%JwEgJOgGW?vM#;vTEORuV03I)g3(WNR8s_+kFjBo}eME5xY ze}FU>83U%D(hw{&u5I~n^g!pNkB@y~XO zq-cAK@M*ZOcP;(_d%^G6W4d?|YV~K)qD7ESL=039GZYWwx-9H1%tiPI?C>+?n`Mxh z;63jwc6sya<^))02Mkx@PI5KIIjd@TWKTND?w(SN7;NaCVMSTH8$2?MOEvbJ>t^kV zQ=c+Eo&tViyu`ulF+7vF)E!i#r0tOWdef720Yd|E2U*zg6^0&KCvg#V*-L*&Un}lPc>;)s zWwI!mYw%J+rA|upE=G>rm%-?qzP5zewHEl9Dpi#oyW*yHQw+zhJwY7>f+PET?SD*> zyxCSp5)rUTF~N{>Y}25wleW~zO$IXV$!u@T^rWVh7KO{Vofb#M_zX@*%@aNFweBF_sHzVs{M3VYm6!V7QYeBNz`mY92UU zr_{K+N3`*()^gz)-#OhBa7fxLI}B45HNXZ+&M=;5qR*p{{eXyrFTWbsCFXj|{s_Kr z%xuVHzx&lpOVsfvv+T4lJcRhL5sr`#{eO5)*Ec#>*fpQplCe0kC(GWp0v6I6FGv7I zE3#gE-^-XDq($LtZmUoV4q^9tTn<>3k`?CERw=%Vy0;yf-3VF>y>dO5Wb7 zDk>3?woJ&|hDQl{Z8Ft!dy6?GB7KgG z@4EdTuyJ?23?&o2(Z7l&;;{PG$iRMGk*!GFurC2)LjHPR!sbBsLz!qOmTBGCjG|Wr zgn_k^YQpBxW?gx4aXCLxi?0Yzq?7=rv*SCjx_ucf6>Ft)uuncFyYQl#r?SjWb(v@Q z)_i=X_0UU@(N26Pw8TMLjc84}QG3VzBV8rT)J~6`e_DD=d}U5Wd)&{f6dzgeOx_t| z=L!`L^vOcq734hu%Wcmx>_Z~;{iU#2-yTe>+sdoOYmVMC0X*eo;V@m&;|5rLgx!}m?bg;&MvJ;V4|0`WZg3}i_<@*@E1FBnPAS%# zTChEuwUc^^U2M2Vdg4GTWsQ4?N!kxWpcSa?w(@T^RE*PIxrLU*`)Jz2A3;NJ^2*~r08FVSqh?V zX*TJ&LUyF09I3UC1d+(-M{+FNUFbR9WK2Nv*cg)(%ac$=CBBF&+>fM9{zE#l<&m)O z^So-aw&_Oe@yAZ!@Ep~|-8M4*$TGue;#GPQELhLU26z5vXIuUMfK`GFS8HG0Ne5bV zPh``;MJ8jonwl%?=V*@Y#2%b>Tz9hHLffOs}|K{^%Lxn&}dKT-W7=cB8k-r`i2E*Eik%{j=JD8Xr9^-Y*gY;Cnp zEQ9EWZt2!B(2=Gk-GL$I9GNwNV(Xo}WJgKQ8%D8{$j>M%k$a89&H?&}Hr2q;;_`DK znFL~g?Kk1a?^3iA4d8qSYU@hGMNjRhf$8GRPK5==ioYhAEv&T*+Ld*AW7x`byD0XM zJ(G8`z?&8_bQANs1=YAR{)R+;+{;;3R|z|{@lYJFnlLRSP21*4M$>_qLZ zjLTQtwT6EKlaXA{tx{Jtv=Zc$R(PO>d0iR(o$3%m911ESAV2@*;lv^@8o{el((`9S zy;1ft>p%mF0}ux3#{iyIFV`|qQ&r|hLpz;F!I-TS=QY)g31WGs^VhU`P~Ao6!1ju` zQNz4E!M<~>jlE1}KYhsQk=Zn-veAJqIri2p7F^no%?*;lsg6D3|MY1pI34cv-?Z?( zdO@<4^*>-t4;B8a_r#t#-hmzhZz7#>?+=uDt+Iw$-#0_PPLf+oVOXw zYW%E)!_Z1JsT<_z{2#Sul4wNS#*JAm)n8R9G3%9WGT&nWzdPjW$B3lK`X1uia3~*= zUV3xaZ(U!5eST|fnuqWgKUxG!3j_~Tq}SYEwU6{Z`Q3B1TOdoI_^3oVlb&S%HVGe8 z2uzqHUwe#mzE+(_Z9h$r(Dl0tuq&3(j=ESXK^g+yP=GuuEY$DM*DV$7X9Mc4w3hb) z2Q@N&vmjw-Xt@X)9fkE?0x?9ePM=VRzwNqqNIvg5wdL8^Ppn<_paJ9lG6&&Ab(t8$ zYiTLJnxZq9z?)l-R6L6@Y_*0f`|~hJ)|h?JqBIosh+jI@^?@caW~e2ua{_rM_;73N z!$2wSO>nn8c{U)w0h6(@K&5bI*?e$BZYX^Z6N{0ic`^7vvFkZicTS~v!y0;W!0-_S zivj@Y?c=*z%0;4l_XwY6)f~D-EKf5s14SU?+UTnjcnAqM`{<3?pUFF<EKhtU0G)x=Ujq=bui~4D=8x!4k}ZFsg)Y`>&)`47UPwn6@{hJtdy_eqf&8WZU84Y ztZ2P+(ee5wq|ZliCp(i#i|cDi_Cdl2vmovyT>=KKW7}95{P8%5)jEu?6T4c8y`5=@ z$ttLjG~BmBQP__aGcXjCWqORq_)wwwfjVc1&atxaT+l+Wa?q0r=aPj(mi{|h8gyny z#`1mlu!L{~Hm0Sq_^rNiJ|Q`|U*3nlGdCR-7=6Wt59+IS5rU@P`?Pa4W(~a~w z`>&3{^$5GuzB9??Aaw~t?D1FZ1L2sSIPpADbn)?s{tp?CNEHTetoP9Wp)kvfffQp2 z09OhMQz^fX{5JGRZ?kNW=PI&PI&w@;6>*hJ2`(~mNFG`%Sg=r%qbZ-Ub4;&JL=77- zA<%@b1j*$Fxc$n;2+Ia9(p$7{b_AX8%INa(;~2~6$#Gk6wlo7)7$Dt>fcR9!#)nRQ zs=z3+Jqfl_+ISVEpFWsyIh8Q(v(xUt!YDrl=_1OgRb&nX|h?!8aU4!VyG$5Oy6+8E5 zbgAVJ%;5DqW8nE#U^rDt0Ve_%JUK`2L+B@IKLP1`&4s}}0ck(+`1TN2Xz6jmeo=do zpdl}KLT1vBVr}gXHAiS~d4kGeh&_pS+W#CC%ps+RM*3M`3#Rdll?~Tc(W;~2OhczU zz|R};s@))8q5lD6zR=o)eL(&+S}i$t;0J09hktprtj*@bg3AnHu8oo41lXD%KoOua z`XA%A)c^4Ge;u~HP;yWMa>sgRn~ucS8)?PF3gCTXQ_^+E&l}BIVI|OZ6Nw?zNHZ(V zwEiurp{WXjA|Cu6i^>z^kzmoiJ$RAx?jMSf&Fvow=v&{ZXQik9d9(2qXzP5JboZ@H zhjuk#2Wi7VCMq#~MHGErj6MI;{7*GunCUiD}N+Czn0fpph@R zJxi*7XHq$K^rxQnVjq3+wjbv=4bs4(DbV7rrpSlt0vI#uQVefmXJ+31QA}z?~eBC8qP!wAT`9Cu$A; z+uff^v+KN3h4JSJyJ_?ia^P%T?Y~;43j5#}qnj~;$hiZ_?S3NyQ;`soI%fZEyC8SO z%?Dw1bxR09Is1X+nd5uw?Hc2Rf*PU5YO|xxFgv< z+k`e0uqyL)GY+irck7u10eW@0>c&@dXx_!e!oRmTxl+aRMdgrnQ3%c0_f!FG#b(&A zS97GyI`(RlFXT((Q$iz$*&Xf1fSeFCZRAHh?O)j6hs;%QFohP;5CqUX^4=Dt3{ zYg%}D7FVUOVc+!2vvQ6#A|?D$#jhd!DczU6$*u%Cl(mDW&(0QdzEFO1?nu^cLjxZZ z*||uSN50Nfag)0DP8ZIUh=VATq$L}!Of()XBRHCNSPw2kI9iOqqoG_U3-22Q(Jt0r zd|hOx|H;A3U?}2Id_R?O!5pDnWU%E=5YD2@{6LhI;DLBN<}KY94%vdCf_7yA%DWtO zjyRVE2~&-+S0#(um=S(sT9% z8f&<;65s-Oru~!M3BWOql%})$2YFlT1aw=wSYyAGBWadlfU1P0EMAqVy|j)~`EMRk z%c&~=;%(K++7KaHL~+@9tjOA+_Hygp_ZOl30EPL8VF7LVUyxCjiCJBy=+`K(QdT7k zv1sY@p2a%LEuwjF81#e~>le{(2)m;9kt(?-I$6jNg??Td`;t+{spwJGU`M%6pe&cZbg!4A@t@}n_|>Vr%LYjP>6LmnwB?e?NYFto8L+VDlt3KO^=pZ z#V$8pXuqVMf`*pdt+u#tTV(@TQ^r#du$>`_oU8AbPB~Y9@*q251yMMx=5J0>ESyNX z;_E0{KD4ke7NMPHWQAv2W&00wB-ozRbF%H%uX08IZ|uEwa2!jsCn~a-(PCz1<`Lrv z#{yf-%wWl)5wk|j%(9rlLW`NnmMpf=Vmxoo`M!JKjosL|`_D$ac(EPbT{Tse+0`{w zQPq{1zl2E_B)A^ij8$|llZ~L-*;PwsuJsUTN$6F3Ye8ik;Efyb(x9O4bXmhG63RIp zE1!=zvrd^_LL5LDu9evv>vTM&2#h{*6I`oMnGd(?I3Gp2WeAeo;I5m}tB~A({j%@Y zgg_6u_XGB1cM?#IEeIo-nXpH2K5k@e63o?})zR*9LHu^l}JoeBpoB%(Av&?&i=6|(PE<8%W~ksdNCx3|1J zP0nZdTEZqbjK{5yTcenC0}cv~Qy;G^s}Kng%`)IFcgxf!Tr^UNNuvAlgf!-Al$Nh| zusjlD=ca8sk){3qJ)NYX>J>BoLD!Dvx`D95UoePNTJ;#!q4u4CmG>`cUs!%oCeQ2} zng99lQXLzpBAM!%FlPOyj{A}AO?O0+K7YLZ`(D$d{{K+4N}LsQyH??3M#`fMUDb}0U*=-1!JUI%Tfv5KBXH>wXtkp z-_1OY_zULyc2I_8niu*f9bXeNuZqv#Z{mlMQ4codFm1^rN0T6?DFw%HCURh(auub~*RI5h{g3WCuZE!Bk;d^k6<=d1>KPLr__BhZcz; z#=>ZkKlMTbmwq!NSF;*`$2?N5u(l@S1NKsfXtG`QY`8MTvI6zFhNanIOp34m--QHI z-J%CZLd(tES#>c0$}=N{Lb48hUWS?tEnmD0mR!h%)r~7lpjr;~Q(R+pNW|x=?DkQ! zgKq zv!-~`28c!H5x+!ukU#(9?Z?~OJ_(;9pAQXQscBcKwlC0BXxm^(^?6cbSG;R*#$aBv zQ5#eWMb{^by7)>57>c$Z#brr+nvFcxXef9bDiTFrPp3L91bE>Z;4A1?7wYE=F$^d1 zc3>)HfB=U?k|=S=$*p?DJoe^lF**_087gc;^~tt2L}kenDLG{0$kUDxOFb=}OvaQ|MR8w{Ocxay&z3c3j`i@chm?Kpz)q&aS^u{*FWvt2X8EC3ey-v= zT~ub?&6Tt2^q1mGDnN-u3Af!Yi@M87gDU}}ko{_VbV?5Ysga!0G|3$YP01mKKM{_W zdw5SwWTo)n$6+GZO0Erq!MPsX#8G)UmsMXPjEJQFDZm$zrOCt^2A>?vNL?*=wC!Gr zM{BufxjG_`@=?SOk#Zl-+;0rwS-My0{_7si6|ujs=-4ap0-PVU(%6$nY@|BVnA_ zR4YazYOfcqUmqa~CDI4p#8#VagU!Ep4@Hiu)m&4xkH_RzoN68~`qWje7%p8zWbHs0 zv%Uo%42Uj7y5}aIp*BxW>tHNwf0q=bWd(2JYPYDbZ#zj{TSptDsCMD>{V6UDp)=NQ zu4wCf_-;lhu|@ge$In_EVrTh9HqUe{fnsi)P9!^rAVPDEL*h57P12$O(ff)UA6IJr z3p{#YP2HS}c)wE^qeS8_Z9MM9db2!B*D%^CDv8?f*){N#; z&NP@ilK9y4*^WziqAESi?Ggte#qA>&tyW_TMTpos*QPNNk zjq<=7F*X52+~0ifLE}@YG|;na~+rSV{IUO#ByABkVQzq?BMLRpHBNm_R>Rw~d8yYv%@Y>R^@q6NXke zr(kMKB^plG7SnSI1y{|vqLJJ+zfT>_V^+65&gZF*tdYG|UkQdj@#;tKa%NT!yAn+< z?Y74p*j@eKg8v_Eo?<6H8#9+F3qXxzN*iI~sJc64!Xn_G5lycYNJyIxsW@f#y~TcS zbQ#gDP`sn)ubRWbQpzdj=~F&eJVHPV*gL|NLX5)l+sqP*qiCvg-nSm9#Hl~oZrA5H zSKSw9(pIe|+|9U-k}26ygz>#HY*D~)iQV*mQ@1avuSTz*_~#rQ&JrkEtBNkFsA7TM zLMi;G9|9>mVZ)LDiTG|4OdPOG{e*6U!2lYu}0mV5kwxTFG5Ka?P zxe0n=OY%s_R){Y}S2Zl|n-(unH`!0OS|kxUc3sh9+szEfjAIrhHZ$k(-kH}$m819%niU^4 z7W&E6yQo+PQ4;YNT=W48H-|_E89W0kV>3_cz109Y&9c(;WeHL<6fwqc--P6XwiAoQ zZ<0dn6?3oEiuz5n4IfE&VRZMoXHpl7o+hYeJ`=dAoSMq4#4&|CFGPzsF_!ha)v9)Yf)q5zG zShcnAu1+Xv1`jsK97+~=mH8{exhJg`y3fc}2$`&_EwCJpQ=MqmeNjBs3>pX^UoBi$ zg2L@OB*P%zS%_~%y-flJZqwqVo=%vu$M1t|~>t32LS$}5Mj{%||Mx1$H9@u!L z&k^mho#>5HBy#Nl60tc7eLNjKPLx<4DjNt7E`l< zblcfuISmDW(C=f)*-5ABr&N=TQ<0Qf2&pzd6%}8)xkxGh$vOlyKymfR(buT^SYeHk zQ6PVJ=2m4rH6dM|SJ-ml1&pBz4vz`fK(m0eCfrPC{%9-es5GUFJU1T=W;rj_$WQ1Dc^aJ8%15Qhiv)a$1Lp~y3hOxOIc zad6~Ry3q^;-y#$UOi=>A&c1eu=onI5%vsMD@{)K;^3keByVl|1zbHDzF@3h}s#SJ8 z_#%hpjrACNqUo(1M>0My@`V`~&?F+0U}1fe|4GR;12y&+k0j@Sy}=;yu1|`2$BL}8 zmV*_5-;7H|F6yjecQgB&hR-TPj76!N0P}~xx9qmf7Dy(DZGp5Bj6zRY;sWBN84jZr zU6rUwV_)chK$!02oE3GxI=!X*-kg12Fd+8che{|v-Fq{=N3&2H7DeI?&0o?IZ+cR{ zc5+zeEPN}yoSDg9xQb(OXJ@?kPm(z0}SNFqAF<1btgA3mB`z#G_0p z%oHL}ODquw)#$MjL=TOtzK^e1uxt3|XWp~fzar7Y|4rlt6~}%jgM()T&jeu27hj(V z!?hf}LyxnxZJh2ell!EzxVU%_SCRSLw7u$BvrocXOq_2B2$gIWou$oSl(7#THhmyd zRu%GwJh>Scpu)A}+yiM;7(!8z?Z=zAv)4B6~QMl>i71B0^DXvmY5ixpf` z`UJ)udN`TTQ@c_#>!hTHkNfJ~fXN|v;HNbQ$@(%HPaP4wFe-r7Jp}3(u?`2d7t`xP zmE~+4%!1?jp@vOtKRhCbkb=(Yq`A0!Xmq2^*udr^53CUOkHk4~wW2rSaXIX~XTvWstLP zat`8dmM3*%r+t`(&505HAdM#jZ7{B8ArD&UPK-WEY&*cH_u+tlC3q2EnU~TfT`nq- zx}iXqT-szK(es_AFDg5EgC*ax4s4-sJ9AEG1=A%dS;)?knKPXt>>`0Vw9E~;w0yAu zYc;tZEh2GGaRmn&62FTOapfXmo^7HLCZgR>7hZh?a8|CYt!El~Oz7YglzC=~R(}f# zAI}S2El40oajqbHJq{K2K_A9pUqW5(8`C2ZY;aaPKKde)W3A&F5khEIJ000lzsW%v z@B_x}_n-LU!vpnzSW7XL$cnY;CFplNsqlI$2TifHsNV39j>DlH^rJp5=gg1@2iTNb zZMMrI;NIe3Bqu-ZRU7kvm_+Aw>}SouATLGfdByy0&h9VX-!`*$sMCG(;nx`b{qWq9 z0Z=VKhlQMv_M!{WVO9+tW_})3yte3Rd$wg{fT*#*){%uolpLO1~sQJTytkHjeT+E2|@I=x&@Z@6m zoTAvn<~E$T7it%g3J7<@>opf@t$Ve!)%SDDg7k6D(*o+Kqz=iY0Tw=PUzH#?@9^hs zLb{6d=cusexckqr9KZW6W;oPJf=$;zf~qZQ66uKV-E%BCPNNBE@a^CK)KK2htXgiX zDAS@ILTDolX*Uv!cr!B;6g2szL5gZ)(;bPJ@0B4XoD>*qsJ9oTNu#)*-hyN+$f8%It zcz%)ZSe$=vVfSTBAc$=DNwzv0A_y#;c4aj~*yK~cs4A`>3>hJla@JynC5ZQUZ0sVI z-AMQ)IiEp^ivyFwJ7@71jNe$w)@(&mJ_UikDp_~F2t?@00A7J9UC7XK3zj?SZD|Nb z6^ftY%_vcvMfRxfd#57jDPz9#&HhtU_fx0!R?!!f(_11ME9;YQnTeXFCfS_Y2uqO* z7wWZ_ReSCsC4d0{54jlCYy6m|t*cE5)R1J0Ausyh8qe(6!&-^~c3bsBz zjq-ja?NkUtr1FNJCyol{!br-zf;n!OBXC^NOfbP;Mb0p7*jR*`^ftI7{!1Px}7dy~@%i>4>lb z3nmp%#mG?VCn=3_@o1vNm|QZEl|ru(AU(^_j+#H#k1eW_;pwR(1;hn}9E z_Pn{mbLYmthR|e{^dgBAxZj)ib5`J|7OHn5|B~__ zQB4NB|19+%Y0xM9_tBSkb=9&^k(wK}i57df-H|BpGXpl2y6)My%R-U zJ}DZB%+3QF(@cofK(@xv-7S;HD9~6(C~E)Ihyr6tD$j7XNGAS1(n`w+wisf}U35zk zfs0eG%1qi8nfiRVIs6w)vPmcDjtPaO!$Dzx09kwIE_!5(Kuk!=F=Ab;9qVNh*-N<( zX?cvpGBfkOc7w*u9G>Xn9Pd5ovc4vnMvv0fUS&$NP!>B|$Ny9wIgXuqik)AhV7cQQ z!*Soq6Is&)(fs?#vFj!FVZvqNAv}mwA0w7gZ>)}zk|m-O{UNLqyR1K5Qa^h^g(jfb z!nutG^8Oc2SGn>}Y-R`!DXr^_Qe_l0VY4O<%{$vdunG{zX@OQSu-gbmF*#_)o z!?6ZamlAfgfpxa%45X8^v~stz4U8;i>t50oiU-5%f zuuUMucJAbb<_3zRTf79drgqX9w<23|7QEv94NJ2h9+jhyn&9aMX5hlD(JUEpoM8>0 z=d5Y>q!kv(CHZByvlunq_zSuH+li4m9v=snmx+Q0c~qfmnCfhHC*AeNVtaqefjv}4 z$)m+Kk-#Eav@z&eN3o_jxB?XfvRKAM3_vjr{4X~u8|04V2N$L`z@_nkc7BOSU=_a6C;jz)!%kT zJor6jCC2iR_9WG4Feqw0${yynRdEam0^@CeYUnBGOPX&gf$`SaF9gb>4T6**{d2=5 zf>Xa=1kZiDhINbEQW>gdX<}5=>%b~p2t1_hxGRr@{KO58BSq4mIlQaE3ZFlMQQ@hL zAISXZopeN(4}hj~Haj)E;{iH0r$G#VD*4*xF%!Pg%J(Zz%$5y2)EIHVKBS|D=CrGl z?MHzBS+Ihj0B@#+*6;pazmib6fNXsGO?Pta(XfQrXnAV>ee$OLvo;1sPF8ifRh^Dk zx3Sc1{vACVuNGvf*{o`EtD5>>L_@Phm#p@6vs3k)bU$?H{znvKsT-~fz5SC8Vg`dO zwNXt~p&?5@^v+d=KaimtlJW1fe4H7W~8D*ucuh=LZJW)6+tA%sa zjSJ2{XNx6JvQfdE4gvsN)yUBh2i}_^EmN7p4*4w}hcLXn!>nn^ppo!TG)uvOazS2p z-$eOM$g}D(r$9(nHE2zGu#eSnr%OSBb{v2VYDgZ6|O%fQ3)py-#@Jk}^tzCXWWZG1aA< zPA_m=zPglfgcnTp4)m$qtQ~7M>bc}E7^M8447a+9{Ag|9w6Ecc%3hUUF^5za=U$1E z(+fFASE{Ni{(|Xe9IhZ!>>vs{>9nk}oeMQEa%Jcib_vh6jN@Ob+ot1FEs(}T#&$#& zB8`SFj%{BpV=TSYAMLXwR$dREuq`%dA)iu?)2GHst9djQ%8Aue6p=W;T%Kt zq4U?krZa(S@!TvVlrTr4*o#H#wAW)8Kf(wo$2i#!Xh46c%nMmcRY^5eajl$4O%j6T%5@bHU<|fdX!tB2Xa%lAsnYgHy%r}wk)BRI z#NV{El+70F^{NWqEdt z#WbHEhsww4YK#q1zg4bh`>-grm(?T-H1iXEJhhu>Ku{f;`u#I42#1$Z!5w6|_k55tr38Bj{JRMOWPtg(xx3nE>i(8v!`ag9RT%*2cfvyk+Ug zNc0&ZFFcJ%%Br?n8c?Rq)&?4C6T8l~mY1l4dYCiKprjFT)~Wa!irOqNd3(puKPcrP zWD%lP`fX!v&WaulOToh@0k2aFapT=e6){4(i09N^h(w4__^nBf^#hx_!??u8>o@x~ zs;CUxK858Un5nb|2F`PB{b~b@`Q`U&DU^~Cy7qK_Pa!Z7iP~~oh1qX z)Rle_x#bmEeZ`=JPJr5G>2zH*?kWc4skTEo>mg3kVYj|0-&zfHKN{;8NW-(Frs%3; z4<0WDHb{)VN=+b8&ZaTo>EUfpOPZX+bl9POM$BU7SyhnR;!4Gb>u1 zblTC|&<%Whd@iTfTezKhPli8P9-&K7vipRASLxA+4jgH5zoA~<^^tSI@M*UO1K2zS zuF6W&wSJh8{a47LA0`jA`kZCI9#5KZuAMvGQMv&~UaexUvwu_T6g)%Pah7ehz7%a8 zlyXz4E@l1KW?8L19x9sqIB#Mbmi6VAM<(e4BTa{Ci|yA7kPH`sOBmSuagFdP1CKl*kP7ST4f!%Yesa`9cYS{PyFXsWeN!5sS1u=|> z=LHe2ky}|-(a^c>Nn@S8{wrLxH73=lXf#K2GF_IDtjN>h8r{4dsinnjF{A8o6JxYT zEF&y6ztKvr!v~Kzs0!9PBIj}n#*mOkP6uFWtiF_aV{f8GfY>Gtth<0f$s=6{v*Ej1 zFVhSam7mJEwfzOd5f?0jzdE8CAt}y6kH|(y)DHFaa8?}zC>^Q9xOK?S)};v&441q~J3V{uXIYKloNUeiN2EGm`>NOteHg3F=Jw9MSUH%Ty_b7)5J zt+|Loszo)ZIu&EYZJUF?q?+dDDAie>*FD9|3{%TL2YnF-w4OuvMNRI6fCJu;fk&ax zDa>oAh?oh7dX9M^)`F$V!FalC0R6MoS}7_$aa}%&oux$3vaW}T=9V40z^J%L3Z^*w zm4QPOR6%dFfpk%&tt1O4^#c_=yUgMtOx|&2*-)z@0X7`I_}$YAbx(*uR1NwDO)g9( z8_L%Yx~Ro&RI`F{nvU`^v&H(ZuvN4);eX;=Fr$o9m-+B=O&3bBvbq{0FCl50;WCcgOwX@|=xpzVTs zeCM0*nlkV3Q|`-3rJE7XSK zF098sXy}{jq^T2gsD;cUQLzX%{XV;?<}>6EGwm2v2n(csMCpFC5g&!6^5cihvb(nD zO;vF{)3~1Ho4L!zgd6f>F7Di=9OWB?!I#c$U9j~m42j)&Qmw(!$23hvVl^_}Ti1Q` z*l_cg-N$I(Jg+QdOegDv1p99k(AtyzO5YAd$`_od6!|VR@u~(;;zLX`bh*r5tO$`W zYlg`wT_}`Eu`-TvTGCQ&!|y|~7E+UR-{5+%)XFAk){hXvp;zPp%lm{e7{U836rB(5 z5Dr;n#y&D98LcQaAof(jlxvZGNFucgZ4r&&(yQC>Ag{bJF#15$QGVoAq?ppUH*1kU z&Ac4;2Q)9UlQ7$Ee?zT;n`x_7#=nPJ3Kx}>DR-OIi38m}HNwK|Z**MbL$*8lJhdf}}S1|&&7jz~FyYQ9iWtkr-b!>)Y zzKZTgNfn!@9zMS7{tKq?Tq;IH!H%fYSHlEIcSlI(cD)$$n}{O*MsXnI$JSyYHgaD4 znD5*LTVwr1OD~HFYQ%I@*{Y*ZNmNS~@|hZs{pVluy4!9uy5nZ@KF@s}C-)g9M2Wv+ z!#j#jmYP?VWpYlB&d(bF9-}nR@?B4meY^0JCfA9>W6{q9ll>_+ZC|Z_?uAD|#y!M5 z+;Wjn8K@>+w^8OcA8Nx7mQtX$M_LIm@?cz)k)m^57U;meVIK`u4SLgdm@ksWw6Vi- z;>o)_Xhzq5E6VqCD|u#Qf>d|}Oby7|)U2U3lxxv`x1WehHX;m0a|cs3I;Cm*g|Gd& zsT2m-w#e8B;2$gjs@e?_&$9}ltCL-mn9(N|HQ4NY5>k70n<0?BlX^+J5k65yT;_JH z%16sW?#-Q2!aopNAxBvC>h1Y_Ay);Ns4)zdBxc@|LS4=#hFj+E$^CJ{3HG7Zeh~;l zB-;*Z;cFT){_^O0vq3Pcndl~~ZsoG={QU6&!@!Q`IYXgq!xENJ-wrPGS?v#ZPHq_4 zCB;#q)jj+X2)_!Y9mb1SXDZJmLSL&Tsu)`-&n|$zhp#SCyS>Ovfjc zo*)0UIF%~-%8(|?oP?ohB8gtX)B07gQtT*zh5K0^jC%MuRILhf#lP!9oLxvlJCj-h zqZiItD?6Sa>p0u?$QHB;Zis6i%`v;43y>=+!&~U^4uoC=YK4PEv%AWVEFAkwuoo-@-%IZDWzyz%XZh}F77P>={3;B{e(ap7 zhMOjdfsy5EFw->V=Nafiw>R?6TRySQ82H*tv(crb0_X}&vl_k1`4DZTZAqtHY_cJK z07h9CdkE(`Dgpxx?1|3ndZ89m12u1syc}SwlMISepJ+`T<#Jxtb zd?DO~av33vsHfv2xmysL-hm9_Wf`iSv(MDnH&QOntgrGn))B54@#(Ie2*gFWxxf)c zja);*OO>u###Ig#NVJHdxW}Up@=%x>1%~q!I5{Zhl<{jZ0h!L~&Q3HWDAkAGzg8lx)jk*(Yq*6wGqM!>tDWEkB35+BQtndfO^xQ4Y>8a$E~<`bWYF6%oUgz{)RUP1A%RpZ~Q&5By; zH}4vMI)Lu;>?+t(tLUh44R9i`Q6l4iGfxtPZvU}N1-|AiQK^#z5Y+La24f*1$BBMZ zWdu?Kn!^M|5CKfsFpv}*?C%0Y-eNBtM%Yr}pWct|s>KkW(Klz8#`H@tM*%#3eB3%Q zKGPimP#_HucpZSlhzm_&A7tuyWjK&y?*z zOfz}(QaA{(tY!Yn?i99vzFXgPIE4vDv&o!B6Gv0S7RnstrK|&GwvK9j-Hj%-)xpHm zby7q5n9SKRZg$KAbPAZNUv&l3Hea zAgwS3(sXusNf5iP>L_zjJyP+fY&RNucF8qZK6X#t=)kgTPM7i09~EP;JV@EyU{;GD z4wzWmke+dE*e!};nWS7J8p(MKyx~(0zq@ft)ijxI3X}Pj_VnSNvy=GjtUS)nB-uK4H zaEzau-zk*>JQSp8COAkJM_p-j`|B_ijYtyP#XS3e)nSpF(AFS$2E|ug7V*$+^(d6` zpo^5ajCBXT!MWziSjqw=~WBdk3ZOMF!5#h?V^XK zc}47cPC0Wg_jLwl`#)pz?t9#+bo)i-Y(3~Ze-5lCDV!E6ZF^&0)+3h)tSm5GTGf%} z;$~j^q|y?U?O*Dd`;7m{@F9T5u9Y^N`OAb^B#ir7Vw}6y!3=9(nf*%-&tEXh-Zxu& zkgJKRjoS1aJJ4S+USB@MDjL2Ny!wg;n7=doP});Up{*g?S3{-dmGs=V^y7;`^+#D8 z3NMectj)fPBS;Hr=OQ;qxcBq!HNVJYZF)P5z-s`YIxCuPn+CF0GQd}^V5iF70l|A5&RTH%>>D1Km(SvB66$IrK-ST50!6~D;?R_GTo zsVw@YiQDD(kGKG|uN$um`oU+Uwy*lM(wrTe1jc@`>G$nfPb$Wx7gq_!qDG~*%~m`C z2_D)>$4^xM`DjdIoK0YF6rq?%$#GEC3Q6sY@{R;M1o$>sq{pGnfYqv<2t#a*X4DwzI z=8y(j#g)U8p!$5VL(B`cqULYc!l$6JQd*i4Ykd-%Y!#@HL5D${NSi<_F9_S_wEh+~?LWRG z=YrHfc$O>bRUbF)B9XOd*bVg;XjI$PD+V4@K5I1ajenK3zEMxZtQgmrH`OBue*Ni} zdfXk|G%W7EUenNCd-itXeZ#BCtJe7SazbzM*|Z%!ZV@%=EvYiBijRfJC@{=ODEn|wq35Qlq2PrQnVqg!uapYznDjQ^#vij*+g=|YpKt;~9&;(R z(|e!*k7RUhD6}zlru_TDkEm^QH;}c(mJjCY^}z&c<^Vu;%KC{RFW^*qIR~ePgR4aN7{%=W0F} z3Y83e8*ew_q;_flprcp=wjcjT2P8DrrCoRw8}KSzSy{ECC-=>uz7T54lJvt|WlM+S z9UhYrB7zu5&%Zo(lEn!kcvb}`-*9nB4J4uJX z%6BxV)+;WsWO%f`6gggy!vHa`p^s7_ZPY&mg zH{8H&cwq1ur?<#u<()yo|AJvZ{OIh%)AE;qh9$iyAA4{AY13vT`@~bgo2+B%vy2N59VEb z1yt^lyITgQ09<;eZ>`2GU_h~E*{F8w2GD{;SFDw5cw3j!jTGhU4qGOYR_vUD`|3t6 z`hEF1SA>oTtCgQFZZK}BG8jA2krwzPMmc&ET${Wz=fU!hB)gNHGgMDnK2)(tiwkGp z<5Xu%-(d-)-ZL!2RVdP8ThSaYA1>?RRppCe!!WVnEfa$~epo%slPMo^O8xmQ(rK6^ zMM$-GiS)cj1Af>=Djm%QmMxcxn&f>V7$`i3>MWy1ltZ<{NjfPOpo8R8w6<0_?Cv^ zUxgA$>4h>q%lZGjThU-)ht)+nKZuXtdLY|7QpinxZ?%tz#oW@6+%878cra*x&`;0O zU1~5vfP3%pCLM9cc0KNVuURUv$Irj3S(m1@z5S?BDVd5sA#^9O`1_+mcK53?gSva^ z<>T)bSluOSj|g3-A3(h9KGd^|gk^!T*j`fnZv>wovmCN&I4D03L@`YEWb)rx0MQ5c z<87xA`ZN;C(U$_8g%yBmjZ(Y37iUsQoOLahp#+^5>d!JNS5+@f*uQQ|h_SgV;+@HmX3{T?P0iV4ibGIi_7|?8Px8PG=Qwp524Go4BBXASYkc}!DgtRYB z_wW%E@sp4{O`?8pBd&g*+6IgM)M{sZ=6+Ew^{qjxnq;2-y3iJglL9%VaIGqG*Nm$< zc5^RTANPa^WGYsIEGlYS4%KHyg*~FY9CT~55GymT1D7t-_Agg)crz7Jg@57d#vTMn zx{|PCP!QM&cV{zanso{+e zh?=FugqXG)@{MCq@7GrP%DUJ<6i5JUQc$ss*9j1;2!+$|4{P8+9BG~c_Qd!J7Jb~# z+YQah`BUVsoQX-Twx;b+l~GE!K@%W&1mptd`4KRW(0)YZACW0l;5%6_a)L@G*xl87 zNOf^8ZLaFS5y!_>F0Q)T#sw_neDys5ISWM;sz2z&ndDn=zbKV(5iux6wFnZaKd7}+ zi;UP2lol%iC&M7fUaG%zL+zEgr5>LABM#s!BB@3T7;OMJen}rZ{FjYU<+Zh%(W}W4 z->o>4B8*cdNUATDUqX@AyqrRErJ_Oy;KvN(1TzxD-4gC@5=mV?H78@6$`Z@?qcL6O zv$C|?8Ri_iTF^}V1=Cs9+%TKvT=S*m;%$alA>NOGCmlCa(L*7%1A7;_|BNSVtJolK z@HzK{ahv#7CtaCduZoT4ei`Z?k`M(PArsGt`~KRk4EVD#Dcs&yfg}`p*acRbI!&tW zJ@D;pu`|FtrU>voEvgXeM z>oW}^lag-3Mv0kH@Gw+UzZ9P93*nSMDZA9ik>3Z<`86{oKg*o<`gM)-rUds<=Jg5q zIkhA(?EDaqrmu4y;~2K!`h&^CkI_c8mWZh-vdH0&b)llU9?^ui@T#yp$b;qDHFI|? z*Gkq)=gn}P%^F4C-hC{)F8F&pn>k^}+5GdE%!B3OndozBsug$IUA92k3pwr6%D3s@ zwPPa%#WRh)$b|RZUQ7i@iQ-SxQN-QBW(l1+B=M_0k1frOTJl&9r*QME9*aZgzpf)aN7cetXun zqKRg@6Pr2oD6jC73y<9BP5U={XX>~-w{Al~k25Ba6*wMgYW#U&%5EL_c_RK35R}5_ zh=8voSeY%dxNluc=)1swIU&7lRqa-OFabGx$F~S+@MhaW^gAeTQCCaPK8UB{_VYQ2 z%FMh!=zG^u;{{b-&LyAnlIv*L1?D~0C#o|$8di`ie||5-DDWaHpQ^Tb4TD;^oMVFd zod7ldp&f?13W0}d>N-w~>`6>e-U@2KeZNf`KtPK@Q&GfQ(&qhEA{p8vdck%idNX6b z_|Jdp3~~l$th$hq(3>UPJJsI9EEBUxHaN@QXw%HQ-4ldGq>9((f=%RkvQ{MAbj_*~ z8i$!O`5%}8V_*CE>uP!Xq{-R>L}zu1WWi7?aYiZYmM2`OhgouP4!=?tAzF!#6h7>K~1zFXodiVwRBKv}9uYdR$ zho2cgR=&C-8})dyw{DzF*t5N$+CV>P^TZ(J`z$^vE^-4=BG|PzNE>n%_~(Y zpDU7OcTl=zpDf(5(KI?V>u_}tU1F#uWc~PD;=Lswey>OEViTxjL_(RYBZR$^H3j^D z+x}ThxrJ4}rqO$ceubr6Fmk41onjbGepHZ8A}qtTWJsNH!uBFZ=0wk$x1l=E=s9?4XRJa@I1g z;FI5MticXQ8BimJ=k3RrA>B$YXSxxGe7XO{uGkQC{1US5vB+zWnU+wJRk%hw?;qY^ zCcp*n(^qzW-cf*I&_;}*g;eL4@+f!6!I1(5h5IDQxQIrE2|%wROF5JH(uhmoA)qwU zKlfnMxGxs%)-|;Omz#Y3d6tK2Pi96Oz60tytF^I8S38NXqg6>YI}sQ6FPO=VQDW~> ziOM@iz!>3ngPP(-(GYuH{Nw4(SXF(gsWO&(owiHgO>o)}{7ll9Ia$2Kqw9GqaIL4| zR93eq<5F7Tq8N5gXUeI2Gs+z^jN*`3fPxIo$Wn7|i6^Kg+cH*7NcmHEQ~pAI>KlmI zaXtHzti|8|(2j7(%=F+m-!!d~0W`R9=&a@4M5!U7Y_U;x=AP5Zb~2wUym2ho7m%}c zVEiP(#;fX4l>+(l-OM)e_lmVyqneW~d2e8{Zt2$^v$XIyy}NhZ&iRzUcsnl)yp_Yr z#i?9ez$(n}gG~cGHD?i_?%ZaluDQtg4t*qgNMrDi5pv3ey z?k`X@pbywkG#~`HcL-?ch$!&z2=K75aPTk)IDex7(MSW6uz5^f-{Diya`DNy1vkv` zN@;4DB^MSIH}>z)$(p!_%oFgtc!Z`j4P0vPUg?-yAkqU$(CVk~MnNANIUBEE z8qrL}&_FZ4Y~@txq1xqQP{*NOL5SfHT}IM(xh0xC^G{a(&F z-&5|d-S_Sv_uV({9T{Vd>{YYZ&YJBr_na@&YatyOzCaHa3o>N!D{C7oW?>=^{4(T~ zM?-KbBwxj*CH}*fRQdQKt=!2lUED+179d@(Q{Tjv-`BN8XuW*ZrHpjnJ9;~uq`OP% z50YtTZ2P#r5DQDFucwTUDu_lgsbvkhtSvP5ma4*K>GR5Tgv2~oVUo{Y zcCHb*9cBk(EPBy+laHee0OKf(sS1=m(=Yufiq;Tr>y51!XdmTWNZ8%DVvEt+5#Oxy ztTeK87N)pwvc>$HlPHfquJtp=gvujDD=)|p{)^(P%nO}$u4Ad(NhW@~U8Sm=7z}*9 zE%e1ppKEu;Bg{0E5&UURqici@Je>CU4bfVc3JrB0WajpCYG=+wEer@>wv7gybWbw2 z;!|D5Fs9oKDW|vUbW8RZ6s$kL6}oo&ml`h1N>f;`#X+j>DdHwsbLK|3snqM~N+^QhzBz~2H=5VE*aucuWr zi^GR`7ufzFxpx`(MYNcKVO80TP{}O0y}f}GW)HCEMr(YS^DGJX8yzckfi`CSL2{=m zIOEq`yKSGNQfu>>o?h6fUc*;W;qRIZ0)YaNyB?S9rozivb=dA}`qFwCEZnObt)j*cXE zhjtn}AlHS2CN->;mlt7vH8Js=?unrErNbXVpNyBVtQ-+%4)iC4)9E-4$5- zuEwfJjE&|z)b!|V*;-x6c ztFN0Lh#LXHB`d(agCZrrDs#`fx2=6DN?Q&}aH8qiYO&VoyNR^+gSE`HTCM>si#4Ec?*LPqBO#}7i^8E88dX;N7)=!zq)w(>0ocmA>o|1lT+eTL*$(?b0c5coN*U1nYmY1tiyN1SUcz7-a?j? z&-}i#V4N}%e!g>)877Q1>xOu0zSCo6jJI|3i`inUVfOV+c!DC?YpSl<*pr!vd8~tR zfh$|s8hMsT#!Mc}R4mrx4(s>A(bk@iADU0U90zH_KbeBdzfJBbjQW467vg!Zk+Q!X ze+%95F22}%9*|m=b`{!aZb7JzOyl%DpueW7aM)r6>w!z#t%AA7zQ+29(GLFgzEV-WA6$@Kz&N|~ASx;X=i z(yMKmmdR(u3*}Vj<8=9Jd=aX|Dj8L>VRJo0Lr4y)f`|EvCMBxBG{0L7=r8PoV)Jfr z-@S}{<+EJzH2?e-Zv*Qj(+eNg+uLE)?I5d$%6x|iBRov+N{^>XZv?rHq-<&6$G>vW zcMYUC{fTa^=3fGI@uZR;o6v5-WpwA)-a^~U&30co#PHOA9IN{pF~&p8M8mW_MU5f( zgI^+P#(O43O-VB6AYeEo%*r9WCbAFR2#)pwHasPyqa=+APxFnGdTeN&q|4$Z;Yfb;zwfkjlx$8nnq3d#Yo_HR1^(#3? zFSfAxO6Lf_j|G>9-;8Jc+<;gKa#c1mASsrc67U%iDM*J}sU=P7p=sj9(Py;ef^xl~ zP7gKrg)uQoVcZb{RlfcLJ@lQ-;Ul^Q=wXNt88faBIkCsIqn~4!ts&h z2CoP;!rDkfi_*Lu#{vUx)@3(8#aPO(<QrAJRxxKX5PKn;?m;J_YzkBsoS<0!ee34AH6rSZy*5x=Q?( zjbGeX$_7j98hOg3Eigla)29$SeVQ|+kv^o|&R@+E;nemmC-)l0%Ye@;JJuX;s{5&Z zS7NiNEeSHs6ZyO#Nmtqj*clg4TifdU!fcA2qYF5+s3bWI~(LhAaN%DwlI5V&2 zw~5AgJ9Q9sKaC#>!Z1{AOgI%Z@|vPkk*!HOrFV6)PVh636Xs0CRl6}Itc;=z#iKo# zxXNxlBGmk?`xXQxCY@DN9?#@RqpDTx=C`8ixEVITSUAa{|}NZ*8rkKcI1P ztp4KYE@l|onWBFUB_93}x@VxbGrCHi3IJ$tzQ28n%S*R(nRNZ8vm17m#j9h=Xzsbg zO9VfY2!0*6K-SoEg^Xo-ATaW;r!AE;KE(p*`UtjnVH7iNUPP{A?KaI=e7(H3t+SPP zrjc=cq8anM;^1v=#shn5wG!%rS>t}DVwd}xVwA)6$6fv7Qol6L3MaFzis$L9-jsjp zET+dYlW(l^A|50uh8!~W%L>Si?}hPbd|F5<(}T;MJJcBLK$Bw~SL2f8xWDpq3rYd7 zgFg?-za@M)9akw@a3x`;lj;8MpCSi&RhfAhy=ftthV9E2rh0~s0OcghrUJ+ANbQN7 zHW`$R`VNZGooI;U<(a50;J76P#y~R!>rEK4ZV- zU;7%}DbE%8al4_IknX@pKo`yVoeR8&73F)>3apNJ_ky~;crxIzUM#qx43!&EXN(r!)E=k&`QZkatZlPiXvXO+=){aZO>xu&ff%gbz|VW^5h5(z|D&8g3ed0H?jb40A0!-JN=?C_8A? z|0-`%rY-I9bVDn$Szj!Z=(~?&er4p%V3U&VWpqX~A^pc9kr&lGAe@;0v$4 zD#?eqsjhe3DOH9`BL+6EVjy04TW*b3SZcuir-N#Tz-P01rxLwACTiN4v!qL+Gn9Rl z1hXs!u>4e)g*r`3?2e-eXo^QK9y(4WK0keT5caknf?i)YPdwI)u;;h~8_(3U{w1&( zyL#mh5*fX+0kaBG4<{PwJHKubK`0$64Od!bB1zG~QHJ|9}qNa$}G)atJ(jz>~eOvNDfzuy{TzG zo|BgGh-6O-YF*oJ&W>vw*zixFBA6U8S|9=90r}KujAwA^*DR8&N)Vb z;7lwK>(aB$y%Y?8f4q4_U)J^V8JEh3+Yum@^6RP!Z*Etm;%q!N#rQcqVM2e9%n>or zAxw9ko+wQVj;9yHhlovA%Uh!#NUxF;uam>Y#7xU6H%;t|rzM?}TkX_fS2dSy^si3o zH*6nI#Z2Rn+V0bX1I_cPVkyZXU9`(7x-E^YuTk7A*4+HkoF~1npADjJXd0*dFD@39 zHgB3oa{avbB3W|-Q{fS@4fOFhDS6pTO6kC0AXy>z371a{xwn=m$*@Xh_;iaAiwKhK z(C$Y9EI}VA$Zfx1gWb(stYTh{lUQj0Bw_tBTU3)!4N?8g1&OZPpP#-HZ)FhQyK`{& zzNF&J*^R2qyv>)MnLkQ@JOAewx({JJPmAH;z4fssM57|)it&Nr7p|Ez!SD2LfyqCw zHYj}fO+L@H{s#%^{!6dt!KZ!AN*#d?nzL|@?`1c><*r-?!9Q=4Ia^uhh=Qxgb>`nH zqgUsqZiZloIWXF-98&J#6lo#Gln~P{@~Jq#?gH9{NDT}|wV3>E4nwhzuK`qy;Z>eS zkWt-SPuSR1{m8{|K5R6JvF`{7TLH0P!zBhK&OnFEUNC+9ZA@crM#Qtn%k)YQgbwq%?Ey^KxAq3#Bpzv()Wn(F|4z{%$y^x{o)UZUW;n4T0 zqvyFjpNWm+u*_q+3Mz=&gEC%6G-Frzy97owsdly6<`S!3Tdm3JF#vqgqP48Tob! zGJy-<=wRH^mn7d*{}&Itrw#z78W|`0(cZ4H|5b@22bw43b4dDXm(Blc}pee3-!agoeo!k!54T?bkj zV&^>E!)X43l>6uN{q>+UGj=qv9t>ckO7S3`u>pS@1kB6pv zu^^0rupFQ2A0#-*6iq6()!Zg!&j2V>OsSQcSna(ul*NQW!IpaKP_yMEiK)7MfM*P8 z-iM!sTI+l+p_%H9hbI3J^#@YQ7*cEvGCouaFmu7=L?b>7;k=lOS-*A*lSXa-L6RCQ z0)!2uFqfX)J&}~02N|Qr)hFvV(L0fhLo3Ksc|4V_ zj?_v#V1OgQy2eG@1j%n$46EIZ_P?uCfRRS~fTwH?x@rV$&|Q$S5M-}GjfRB$3Lt3o zs4%-a%XRx#aN=*J({D0g^pZM$)U(0USVn+W@ZW}pg#~}=SfP`d;~$sE z7n;Wic}fQB($qa}xEuXwsrVm4box)FUa&*+anBW1(2*9;6f~T$C$`}dkIh25vrdF5 zg(@1>RO1ET1+N&xPu|ade~&eiL{td6GQWzGekfi=U8QdzC|rO1G;x0g&8h6De%>VKD=2u?RD5^lW1awY$FpZJlE@Mtn3 zzBl(H2?#~mlM~A3n3*>JQczOQLiywh;#EmFC5zYJnbijH%49LWRtxWDPo;cW z9UuIS%ArHQEE$7yqkjGN{DsI-i+boxMV5h5HbU0CoX&awTfl1fJ5zpSqojZF*KnaK z8Zs4qz$u&~&9Wl%!|t!be_BmsZ#;Qcfl$nwMTcchc3a6rHBp|vcb5DXu(HTzVX{YU zJ4;u2r;rp`7e^^O1DYlx&weI~9EkIVImu``{GU-oUb>Y3Y38BR;C`?!Oh&^5$zN53 z#M3-^H*MH(@BUu#JlE}$@%@+A&v#DyVt@HuIQ0B(33{{o2Z^oX%-83Yd2au==l|Bb z1oBEVZUklM>Qfu#&D~x2hv54U1LLC2DlzQP824oU<|b8{tL}>c{h)3CtNWEsckjH8 z8**~Edn040_dmGsj@k(pgSQyWY+Yj^3az}tIXPq-+UPdKlDmT_Z$sAd#z1!@MX_~j znmc)i&o{TNl+)^IBgOnL#47xoKpV8WO=k|do_1COM}1=MPjjloW;_?`2cS%}5exT- z$syl`{#46-WhEK{(U>MHG~N+>bHe$@em8EFjWGe-F<&9bLvIcV+|@8Ma-PzPldETu zV;Hih!;zUX!Z#}(@yf0!pJfZD+x20-dS%;wbjGDa8s3buS9uU*ttr? z#2c6X?kBvzqE2O18tR`GGte%q85ZtD<^i9Li5CQIrVvej7hgEkT;}o(+a4X$>m~J1 z6888$3Up#O8XMEt>pUk@&At~aOfXt4d#ui{pKv@^&3o%r`g^UW=R=BBbn>Ogc13#< zn>Dmlz3f&_c|ns|43XIrdopfe(W!M8+@Iu^N_A!ew0H<*8nW{Rc!~4R!jmS!uAql0 zGSDzlUe+aU?t2ta#^D{3(OA#(#1^?3AxV9p$2svXdt~y+&As{1N)@3X&(?nW*qm zU;MHmByBYBN8?gIADME;L0GuNT&U?2N?!7}Vxl-geFZnaGi<=~I&eHGR@-7h-55Z{ z9{i7gkt@b3<$A`|?*h-V9n)VL6 zgHXktWs(%WS5YN#lsqp;KfS#5t7yu~WC{rndTDj7@VeZ2_(Y|$nyBHu=m;(;{Ff}C zDUm1I3K2kauQSmm-&H-Lw`QX3OZWJP2x7!d&yD*_8jS*Twy$??sAj0qLpmAjM~(Sn zR)uX_o9`HLWx!uspc0*F>mlKH#7&-Dr;JPCC8I|$r?FnlX@$p;4yg{fM(+lvvHPwY z^R*-jiLtP|Ha_OjEtMAJ=hxs1P?uVYnP?n-qrvy6Tg?wUf9-*CKV6kN<2<6Ikx~E3 zicJ^`GzMf1$2v;`Hx7}LEHcV92{MH)aJm^HI&uGw=)7SOWAz(VsSJA&klbe6wd&)} z1@*eFeihpRRSgoA0@>f5GU8)(tME{%&^goJ+f}Y@UjV|!Xr5^D@?X~qF~zpZ+z@}j zgbok3)r;3@hLYx9#6;HU>Nuh9@Ma#*qDeG2S=|-#Rb**kIJ_s7EBUIf>+Oaz4i#B8 zKgUT-Lsopo3LSL*ww@^KMdA%Yy8`>;C?suByv%rvbi6&TTp+iJLSk)KU^F5^@jY$Y zOwdM&NLu16FAUVwa~Z@ZaZY4G`Usjr@Xmg}7(RD}Tn1@Rd=vvP-OYCQ_Opu_2{PNC2|{(C5@$Oj4CkbX(p!Vh%M8%lP#^@ z@HYAb?^Cp`?_HW759YPwSd(|cBwBD4KnwHaGT8Y_I!)bxr3dfZ(pwbE!<7n_nyL1b zXb#OP)&8G6J=LcPr8-aeEP(M>mJxC*=oPWx%V3lkc$s(6l5FPza@Lpc$d>#|$z@LL zok&q4a}6oj;180Y4y?|LV>?i}0P5R|InSa@qSIcB&IhnwGuqxRUem6vU*69Vh^;?) zRMGgT$X47mKjV_D+DVP8=B1j9dX+26TlP()PY~f9Gn6hm(1;>XPa`99W>*5dfsc?F zzTr{j@u%H;IWqCtxM0H#y7^Q;wU@9#@DIV@<|6-oUJQ3wrKy`Xv~04NS&TD7#ikX2 zc7$VT=D5aMpePm%WpJBAf+Y22;#-LoPndNkIxxg|F59EnMz^UntmH1HO!V>RE9TR@ zll^85ohg2unI^)Xgh`;A8S~FUGi+J`aD)mY^#Ww+pFiK-3NNZ;wmKYWj!Fgig21jK z{FUcq=AK8gH8P2$TZQPmbz9PJlAEtxy%`;|JWpq zds5B@Q@sn1$dH`2Fw(+6H#du56;+KWD*fym`X)=9Y4HUAzoa>iQb7N7I?F`2VYaoTpN*pU@Aet z#G)1{y9du&QhBLWe)_3n8NWf{@2f*C4@(=pF5&az47Kaa7~fL8;Rk&t0p2*C2gdoB z_n3IBylwMi5OAwv3`PYT?FZgqQwxB9fHilRlTjHRha&sbhKn}1wcE2&X7$Cdv@J*^ zOxxv*drfqXu=n_q={$ zpy!r=Sz8?=q5humaUbTx+h)_*0<$!msn?%a^d98AITy>;+x|S&s_5%gDXWD(J>1^W zR?{AHE0LSoL+NKQQEocjKo1MN;+8m8mYUNL8x-5dwI&C$ zFxE1>GgUOO3C`2I12M;q35=GZBlLgz z(y7afg;$tQnqgPm=MEwvjj$7T4BEZkbY|^s7LTVJ>?36ZP;B(bRBbofXfMDyPIXdUMeBewkC&NFG>XS=E?wv9H5!PEouT?# zscUabz*8g1TA_n1l$aXSF1p%`?dEv7wD zgU&83o3g9?lUbD}!{m2M+iuwCmp9g6unX8TcxQxpc-y55dUUyi}?0SSV)gNdp zxc}*eSY#`zkAG?vNTg&2w>pU*VVb@bQ5I_+p{dE5MvwI5n0FW8EUKIuWd`i%6{o2& zux(w*Ui51xNmLz`t#B|xw}y?g5nA!^8RUwSJmV(_Kg_7W3_yB=>aH`tSxb%x(YDlq z%UMtVqvA;79ofQnFnC>j3d854xBN#A5vFFqgWp?U{8Mm#C05Wbjy5$3m{1JKE4ukw7=`P{Mg?gqo04>c_j+mIWhmNar#YJE_I5`Y@wYw(MVx&J!}vFJ=kY~#sVtKwF{z)xb9;bFqn=)#^?ET{b%8ill6bBQ4t$c3BbgWbQ0Ew zO#2*>+PPCsh%)t9PVoym>3^xOi%QNQ9-?rz*f1IApF!YxKlvnuwOsKbQbhD6Mh+P#OSAkL8)W9cyI9~U_P)xw5xF6*-e<+_t~jzX_w#W zmwU_bFV+Qy=-2^9R~Iul%QWp<{-mV1#9Y*4qJWzTaq-PTCguEnb$+R4XVZnBUy3|_ zm3Z*4TNL2rS0b!kRp-Sbli249-aQrYmDo}5|CSt%oCcvqn|25juSPbQoSa-x6QNA= zbPG(jqsN0a!)<$Ym8sm8?&VVIS)yPdH4sfIP*|3zCw~_TXTF|KJR>AT`G3k`KPc3+ zQ^A(fTdh@9teIAv*c6hcF|fP&^H5B5ac_h<@7sZK607`)19KJ@qSQ!zG>6lnXrTs` zO+8JQtFhJb`7~E9to1H*4(yVNp5wNCaKopLIxg1QyeCqi?udzARLb;Btj?U9uC%C= zdAG_|DsLtdu?O+8Zh+useFH~H#@)qJSy}6YE7*0NORW9t$Ydi@&Us3m2^)ls3M_Np z+6T45CGP9gBixeR7oU8eQiM4}Lwk%hYTno`ayqdihFV8j;8XEtpyFrpcOp&ZM*KDi zL|OFI)cGO<*3uGXDE(1|g*CIo+Rb^2>sASrKn$bB%pz-`@q;oGT~xX;@bE^k>`C_5 zo#54Q)~{lDh8qU={~+Por`Nw5xr}Q`BqCZIY~=qu%bepIlfufxV>Ct}waBr{6`46C zG`I8yk9>u{J=CNcQx4Db_UO|iV9rp<8t?I7utTK}BRyK|?13h)n)9jwTj9J4HP$fO+ zX0opF$A-D{do*)%{K5^XoSt_@ddnL^sPP`agyFZVQGQ0!`O@Cvvz(C`#>T!xLa2v9 zk+K?Nzdd?M?qT*EgFy z{x02hv$bf-$*h=gbU&7|_qB>@8oty(n4+X8YlJ~!Z4V2Thma}-1E-L zH$BB1jOflcMJlkgP{!ft0^{9i`+;PXae2U6dwQxCY`DS1{ktjwk1!+PpS`5Gv}S;^ zEwON6ph-WKg{6Ms!#0dBsj4WNl!t68HigkRVJ(lqn#1`XUA=@Ymv#VB0!=5TOkyBi zBCf{FDJbfuNz_)V9aJ*fL401n0H6A}5ur25>#-eHj|9LfDMZ4}gJwG!8H`cRMm5O^ zPoi`&MH7Oz?g6trxt)y)uDZ#Kr3sDKwb{4?U81)3qTTzahw<{mV1q+q$+J82q@3r& zER*+U5dB)u;ck%1{{40`pOcn@oa1%Q`{YtZ#8B!eSmln<&A7*jNm~O09B(fZ8^(?$ zwLITEB>7X8ZwZL=Td3__U1GWV_2sU^Z#XjL^qmW=uIzIsL0+7Lpf7G*S`aJ33QyS% z#aGXz_@(p|q>$#2#Peg%;nk8J6%%a0UXlD2JrfInHda&ZJ(o(<%8i6;8UKeA3p0Pg zfsMIJ{I56VuSRbX3db#wU=tiT9nd~0>>`~p-z)Vs{?c27?caPs4nOexK5Nf=+0fTS z)nw-hs1$5fWv;`!ZsM{H+cfwJ;~lz<{9|YES+4V_B`CgX*y)9ERX@lM)?m!UR6VAc{(TP}ukb z*y1t`=PK~(u%FM3H2pcl=LLx6~kB&2%}fg)D2DD*`14~11Y82WUo)2 z+^DaEnPVVwt4@~jmKd_@uum+USwTGvpYtCnyKf?E9+Q;bh^ET~}}q3o=czBnBoCzTi@GG*ATs_0+}{NM+{N z?Fh8{Fh`6Pf@!CS;VIeP-KvOrB&E<;jGNxAhFCYvc$wTsAtvs8qCn;9* z!H#y=WzVDIvC7}r^_i5-Z9JwDdX}+!79;m-=k7(s+oN2XKP|NH=x=?=-SJ^qQEs=l10RDN1_7$lGLdfuP~$k0f|RCs8D%q{ zZysxO{KZ_>C038r;_+g51umU%(@8m832x`wgGiMxOs>u;m2(K+?x9*x%^ZbTY6nDK z>LP}FR(UCSaj47D&&szGH$2E%r`a}ClQ3Wi!TQ-D0j^xmT~z6whG9ik7%JLhI{9hTeE05X2BLqTCuHv11Y zxuIStJjR$cwKxX3X@HubQSRL!ieMNGt3BW496!WdMpmb}0DQ}*Sldfq|u?iY8L zaq9%~rZ=Zup(4oYnc#Zt21SZP)7EZyv6hFGn{-JT?M!EgYO1ef%4$sYAZS8^|Ay*; zq^19cc|7fd*}D#GQyBPm+Ywqh1inWr1X$3XXQUkBys@o!mBd&&p3e$tccFzLM1hK4@riv}0> z&@NgcX?INg;*s5JNntm_q1b&_ztm?-DwBuIz8A!YXS6|Ex6sTgvLs1W2sGmDS(}4J zd#$n610k)#RJEFfD=D6^C{hmlL0w^3y13`W5j>}9U*Y|qjv*$$W`eez*5ByMiDDCc zyBuZb0nW&XxMaq6Erw-DNPu;U7%3+IMXC#$Hpax(=M(p5<`$u&M8MTYNk{}`eFcdf zli_KUh3Y5>U`8p>d{{0b(y+_(#DvZ^O?Sn<|;sl*5kfe939(gtvx@iY(QE>QLXzL@vX;vw` zWW3IeT=5h^zL?9Mm#W_f;FMA@pzW=9622ztU|VxRy1bKlqx)aU3|x%_r&1Be%#a{JKRZ@^KTS# z-j}<@ypqEmcWH}KWnF!zY2w=D6`@G@5`(tA-O!ubG4G7ksgfysXttf<^U16Wcriw( z2`^Ov*GqGps%{LVrOP8}uW|s|ZxywQNASx(Vkv#7$0(LhPCMD>!zZ(9Ytd05|CHms zY7C&BU(FuE68*!>mp>_D662v0?e9}9?}RjOIv5SfjZb8cJdS+w*vgLZqEtg7Y6_wiyjf5W&7Q{oqwOWQ)jWw>5C-7E5g zVJxxn`VxII`(^UKGUdzGx30L1{5CFZd8-G&i&LLeEXwb2*3RvW+xmKb43bzUb?3g4 z3oiv=>jun|rrrd%OEB5Sn9>BcK9^HivDQHV6mwDAd~ zATQDjY;jl|>lMn%&2QFdQ&oS`bvb7CT{iC`Q!itJo%ky$Xs=>{2bY6D@?R?;nj8*`#+O~Q zevBRL|NKhFyyzN_r!r=P5DDi$Z~Tog{>6E8(XYi2)&>l?$c@h#iPo~cseSebNw3Fx zhOoy%<&NUR#+J!x`=dz%KgYPF4oOMjFW2$8ild7pGNTR zp19`F&~UxL!mi6YNhdo_pHoeynB#oa47VLiuT;MR=-#!sont9pEA-mts3yeU)-~QT z9N;q1sQ09APwQ)6i=tA3!s2h~m}8**+5zJ` z$@{}xE5b*nKga%exgaw`)zzFg6AUG7IU*Au3wx};0$Me9Pj?hoHB|=$;$)j?RL|qb!O4V=`uHQ&t4!|#rt!CxGnukY6*<<;oJEfvIv&$h19bVX zBkQ_`7!my%GoQu7o2tfA=DsWxyd<>oWSZ;lzrlM*%?TyBjzDH7TLd^|SgJeU9=ntm zxER4O`h5zC&0cu?$c&mwAK4>qaODtpw84Cji{&^)Yzax1uje9wPA1(Qi(4d%0DyU`wcK4!~Vk~?E=%Y~+-X}<2>Ny))e#5ZmXTj{*EYVV-fQZ(%^6VgO{Z~!tUJ5gPN}e8!l=)6=fXNK}k{rxnx=zD*kL>BkN5T8o4Y0pH z<{z9LHy&_a40oSD-<6vCjvT}_JB5|p$|l_ytM!>*zLt%o9fJ7QW!0TPwKU!oqDTST z8{TG_3m%+3$+VG7?c%7#>9>XO586K)-wH zyg7pw-K2gbl=+1@JpQ_3x@$JNv8sqX;I4AnLEED3*+bG&OD8CJU@OLOQT%?UDjaGh zZ{=$`wBLEnY{$ioRjAn9kDYs?=~aP=GX|_0IX(15Bmk;>6zTP6o7G z;H6eo=Zy+F)y)YP3FV&$aU48yW)&p~*E()pA22kxe|bReox9u+U34F9nV9xsTR zj09O=N3p4Nxtc&Y(2fFc+C|f6BTCHV7lM6V(5H}?*S}634Xan-CfV@YF8el8lR57- z3a0_TJ*FZxHTj@zBzw&y4jM^D`Zz_J@eHMp{n&oi{+^#vqab#-uYD zesg|49C@mChk22_xwcPzVBeQ( zaVG4%emldr!2mw6d4!R$eG%ej#PlIB!4WM-+@Fc^V`klH1{aS3wM6IhXzv@Qm03_JNgdtJ-Ahgao*XbwQVQ!m(#{~ht zk%3M#b~~Q?|X*^ zQF!VemUVxG)WkSfM)^eY$mzYEI+`odLWFS1r#W?tV}K_*71Zv?mNM1)=E8i69bwqh zSM=Nxj}ksuRLH;Qm)=`@nQEMN5JjgmAhVDkRL@;;;}Jvn0=o7?s9lmps-ID$wR%}7 zp^MU-h2!fy{Uo&|7);tQFpO?eZ#6T#W9BASFY<_jv`jVg{8>ibU`tmFGMN9h`(`%p z2Y7>tNH6;*Jee!(A#*(^2H-sL<6XSH^Zsw4!+5SbSJlb&xT_(T^5~b_159~O4c889 zB8}1+o~Fh`ai=AY$}?QLo&SZZbp*Dj=rP~*>aDfdlvRuIH-M(5Gkzco&Li0uwtn+T zK4Oj{V!(9@*&EGYoq58hx?sLNfO+C>)Hi8&O@y6G#!LRa_E+^u@t+B z*%n_|NcDR)yzt~ZoDDNqxe2cx;+}XXw||;O0mS@H5XmS@B|? z=`JOn;HV!u(Qj9x)%|fh{9aL-Q|l9JiR%QTr*Xd%{yUxhs+C&)gWLK@Q&s)WNrcla z?mGTDdVZc49e)QFHXgru-;H%tD0aS0vdIjt{GOhblk6!`-jphX6;`o;Cv{F-B$ICV zY3Le6gMk9;1c61@g{j??T*9{-P&{`lbDqw87nLtQ{+1PEh;1;aGs{|A7ubOhX22}a zQ$4X@oLeB0c!E1$cg{XT-0%v+PNllk`z@;36od^9P!!a&5Rq28(Z^KEKo3RM>p0;K zcoRRg!vUmE?Uwlf#7uGcFGQ7|vtN-`!PEZuJ0DkGP}94Z%=n}hobTJ+Bb zpRFvnEy!Cfz}$*^D;Zj|Om0Ilp1_%>Oqq34YrzMizN8N>VGA;{n;JV;c71wZb(^YN z`NlKLX&q{hIfzPK?X1j1@@s1948F=dX(D~HIOLtkzFxmchD=^Z39d}p#z1y6x$!= zeh1X+yBa5OMUC^f2c&w(lgehIu1x(*%4A_u_M=^j>Z#)6Ne3}Vl*|J#EcHC0MQt(v z1?)<>h3d?PRtiLxV_rx;d@eM$cwa!?xjIL|y|p-qx8WEt{+~0-FLTO`Dm$h`ZzZkfh zTSt(mi}U8@-uYGk%{BRt9O$d0>r*O~Vf2v`G<3Zs+ZGL~(e>oEP^-Bh) z+gtUh&bpW&80|Ea`I4rio-%^x?i zFrn2m#vU~oI|~Qef#IexV`ot@^c{t(#T~7%sn1X7Np}>F%+1@cO&{vyEl8eae|h*f zwxaOe|Ekxnw9v)m+xSO8W%)13%)Do$Ga$yLih#PGh>*h%j~3+5vNpUPnBrK?G257S zpF?nX!`kg(feqFvg01t&o2RWIfxTnXi_K;F?lS-NLL4)1jxQ#spN9qRum8;a&LJE9 zUJ+&$ zEK3+%=ASfb5y8nUOFBIH2Y+?xnYbe0OAjBg>&k2XfSp>XH=UQbq$O zrEfVzSGCYIs)sE7&b2(~N&WJiwNPY(h$N8NoP=a$F zyQ3Cusu?dx6YwBzNKs%a7Bz=P-4b3adop-Wrn`GHXHnRsqB^Z}IBg;9mAl1)p8j*K zp?eomsL}eS7F_FkSX{Uq4>HVe%wA$X55MSPilCS0%>61S$uB&EfbiBY!EY+FUgU`H zba#OSKrZF7)(n)M?y`kp-da?f3D<@>c)|g^1XgR4au)N9@;lq1HR(lgpptg_doxm) zHI>*70#^X@ENvrQbR$`1ec!*s-obXLi(VFg!7o&Kqw&rq=*60Boql%5Ebbly?1E|5Q>x#njq2z5eU7BfJj#nP(;zm zIlpt>dB3UO{4>|gl`G}hdGhS6y_3DxUiVt}f?$onr2S_f^+$ZHXvrTmoUUP`G2D@W z$^w(;=QtVoA zX_s;&@~35lt2kRpwdUomZ$Di$jNbiXjq_?zDB%y-PTMCrP43=fT@|B!<(aK}p$KKt z&7mxf2UrPDq`(}VdgBdQLdwZpC8mTX*o>`Z`Omk1|LuR#r87r;(lUnADXCWQ1bln5 zD`~`7jjVtz-gX)u5}7Ru>d9R6V<~CE6d*OTCTBTD^0M_;SKk7fDP z$<}Q9J1i~~2W}#gs3`!lxU=jwVeg0&xZnq*>M~sJXtLXZV8F{SNd{4-t#F{2%qd5@BOV zMe!#VrW)%#(+{cCE6^;vKA`Aj`*`w2#%w6t$mq4FG)4v1rc`_7_n!t=zW-FG!D=9j z7`>uddB%sZzdy_G9Tg9SNL9m9$g*=M#K@@Ym%=a2FjT25ZY3fwE6U)U9ibNtf?jjF zzosSa4?40(&sBLNW#&o~*111& z7tQ)tvk7&Ri7}vqbo)}n^Q)izhO|1h^j(Hc7C%!_RVn$N&EGikfAELOVs6&L?fxe) z!`Se*`(W^bw?iTo8$WL=)}iIuW3#`ko|VYJ%-XpxLeo~gD2<(BU7NH-knt5yjH>$* zfZ&80PjHRP&7pk?_vTHUHykR+WeEoY;Vk0f5X0DqF`Q@}IYWA`+K~4(cn6dd5T*hQ z5$|_^)wCeqcsR^{34ghD<`~y}Zyn;!YxY)vy*YH+4xHF(_{2HY!5hJeHYMfZ>s30W z33O0=*#1-4(boezl^5s_-DsO+H&ly$UC<;wk9m9g^J?%rUcZM*kk`Rl2hS_+%v~^) zhXDyofqGGtI){>)jS`0o6(MSk1-V%%%fj8>ox3W|;2x`T$KmknX#?a!uh?N>uwD_OP1 zv))HsR_2xkcrF*sl^!+zuz@7sW?w|VM;epJpaX)494U?P%gQu9a9VS`nrbR*Y`g=6D?e=%fNB#*teSLCS3ha^#P(bvD2bLp4miYB*Z zrIiNO7(c+u9YSwa){2T>aVnOVGc_HGh@`f*X;cyk_`1GC$r)M*sw7jNFW&$3@v+bB zJHP+(F;WuHg{j&H7#9i;^q+hw0rAM}v6uVZSn2q}@GvzdBX!7b<96yKoiPXYi>Vhe zv(}zAmfUFwt=?gN_lGL$toLQ`OZtzsDy{FYUMN3-fJF82R}s&?_HizlPyLEzRQ6oD zW^N7hJY_cl?Hi0A?lrFw`-SSvgtQL~7MLhC0wEQwj^f z;g4Ht8$)@jU_KU8^^P4t#F+;3!_{K%WrVCYYb>hNXOC>sC^beTNBpm0C|8+-lR}aF z+r8^dFNA5PLf!bo2@7S^Ve-%a8+=1K%+;aH^DE` z?|*y#pgJ~=vK!d-BastpQD3hj+N8ZtyN*kD4XaU$|fw%O+P6kM69!<+B!PN zofzU;Sdj>FmKh7RBg*DiLlsB-ZHNb?Omf0*fq=x`Kv`G9`7Ja_LeOiVpW7}>+j>pi z2@39&4`G8K2-O-5Y9I3ZR{3-nR8W(6`-L#PfN_2NpFG>oV>-{h^|N zj#`DGDQ%R`EZ9M=)cIJVRuM=%pQmu_fqcYq?@SG{olWty9S;Mc-O z@wLuBU*oMUCTISZz6kq|q!Sk8nPRRXO1tOv=txg7SHsWYYU3^bzS~j z@+1mZEvqs8fuL*w`0ww+FX&$?x4_@bi;i|Q#)B5_lPSacz5jt;RXcH#spY@R&iMDp z-!D=nw_6wbCA0UeQRMbyd#pDQW@mn7MOeJ~FEQC72^R4_kriDD-BriD2Nx6nGqVR2 zA+Ngi1z!BSd!eeor~R*CE>k~XQaJyY=)nDdMCICNcC7Z!ac>7Lgv|Wi*)OrqvM5u^ zWVB!XXD(i8mqj5cKaTnk@jepkEUP(E+#K;gbk(Ky*R0-8;5i!tz@>I zD)1x|DcM{Uq~~6UR+INoi#q3Ui&Z!B4S3>lX9h6*{L++M_^`U#Vr$~1-fXp=`zGPfR|FL@0xGnvc zk)r#x0@pYbOS@NaD_U=*=Q3eIWp>lNXzQug@96k|Q*k7yZ7 zwd`Nm<5Ze(9y8h>$!z7Mv?vh7M%GW(TifR_F)M3?0g{Ct>%r%&#<;vl4CC6PB}<~q zSi4H|#uq?N=&dO597=QCHtoF$7!2Gk2Y=~SPpP|hz=)R7?3Uf1E(djr@u5McZJt%Z z=|n+Q9cT81{HVh{MOF~YOWqp zV%i{V*m-{js9UKZ6S4iJBIOY|>F2w1xcAGg%d_pRKi_b>FeCMVPa{!|Av3_plD>?o z6veUXcg99~cJ-BTeUtr2G@tW+jmoS;{Ca`YRDWHijCy1IvW@eJo`9tamBfQVqs2-T zoYPlfX!d@TYE_B=mRmh#MF88o{bc2_F$+2(a6Rbe&iZG`>v&W|6mUWkw8Xp;iCPN$ z;U7gSw!j|9cg(Bs;#+Q@y-dE(mwz&UH6Q>Y@*5a!2X*5qRM_+Vbk8b=hm`kL?h42I z_xk8#U%D!wR~^P9KH=J0ibGe}IY^Hq>$UPU*#N2v`ubY4duwbd*PbvF2_@HH5iyV8 zQKfnMnZv>MKSdPYM1dB~z8P|-In z!B@~U+W^)xK)5H6>Jiy%l~$y2+!O-X`|%Yu_yYeTC0a{U*3mh}lS^GTm8D8=`Ep8O zszxcW8G_R+xl}Tewtjmiyp-3l_B%2E>D`}le_Ju3{8yQWxioa@PW!!PYCXZy_*=qiKnSJ_`{ZQ~WuJZj@Nr&e3*q(zu~!f|}iuJ_OP> zCgXOqRfmfKVhYW9){d;V-RQJ`I5r@pq}Q8xL@1i`-KbReK?nltPMzC@%^(3)uMrB}_InlqV+! zQG-KSPrl@J&ASaw4dmWPQ6K2|WZT@eFc~(?aSv3TBhlDo4x-no!oC62fQoD766~X0 zO1vXps|y}P|J)&e-74hw8W8X#poxW6CKx(w1Ml>OWN@!XeYvY5>JODj%&4>Xu&5+` z)%H9Pw$cxowt@3~E>|8kHL=z-15~#n3oe^23R+cU0iXW+~(iYK=W#oDC zaCNb1J~pyYi--rby|fsTs|vmg3@_QGp|+wBXRA)yzH85`778bi}5yK%BK0`0rEt9BQ8I`8eb|qX&&21ida75~a+zMIshxJ#xf;n8Qi_jurib7a*# z@`B)opq1w;)cG~;1Xv@k;8m=bRIXS|(EAx;rkMS2%f`6N>D||Z%wy5awX z>sqs!tD>`B*v3V~tMejR%uTl7giGZqIu(|^3XJzeI8rB>i^kjI37G~S$XWW&qV$$K zBX-Y9IoL+B!<0cdH1t5e#CuVxl!Roi9MK?TG64efJ}1ybskUaYY1T)>iO#9hdeoNA z2I>p$1%qBT`(aE?u>!9xNh*x7sCFRCtL~vy$5i98BH8g-sgPNQEEXb_(v3Bdam)9{ z%qM^dL4yqe%VFN^#l);ZrH2B=Xif~(4dHYaHMHFWy#S~jt$a$EnN8HkPM=+RG!@96 zT?YiXJW|`6<_RhdX^4!HGz^ly`eT`G^0ldR4zNO#7c!y`Db1T!>FGemt4`}x+v4_n z>jYspTF-B>uw~|A)B-S^iSLFUbZQa_D}IQVu?aVF&acP$R{b0w&RUFzW#MF03GCZ7 zpyv9m_7}%X1*faj&O5QAynFZwMo7k{5)DCTzDb4>HA^Q&XwVj7>);A`EB595wOAh5 zJ~6rwvp8XGc-w%<3X%n1{id%n@x9s3q{z2~Wfi4sNnm%)D*6%pIc6p1Z})tJ@e{^b zJ^vyEkphNCkGpswO2Aezuev!By;61}s^sJl=hMH0!xo&{g3H4-2{r(W${)P&5P5b- zcmdiFpqG)6S$&H}5CSK**7?qa%W=xW^ukPv^*}c(VOczQtG*1j3p(NHsXaWUkehl@ z)Y3ArC6xe2QYe6wFGBae>1$xGPJIkVmVj;Q6g<3C1r~I7KuQ3s{8f^rl6F>aF~%JY zSv8?ItErNuA1Aeu%SpA(Jd^b4aN;X0?czIlwjfq3J-{OY(t0oCme8fOv^=(V8_02W z-ps}aMo%HJ=$~>9R_~e2xW1XbGHxa|8HDE*X8d}5??2SSF6WcaJuLm4X#U_ySnvC9 zWV`^(;UmqH>gkaHy2bb7)J~_a5!63J|28g8z>miNZ=w4Cj>G@|-nOa1MYg!TWIAI9E?zfJsxKs(>`p3p5&-{qRJhITw&ecDG{7?PCJ^NxM%brp-GBj|};|jA& z*=N(L4u36w;?~3ioV{k@gHmf*t20p@*J63#n_l0*{H%H3{TyBl0s|d^WIA?}Qe|z% z9*znpt-|j~31x8{TDC4Lj4RvHA*=l4ReP3e+wVZA%jKJ-H5=2-QWZ=T%keke^9>*T zG-S8QkbyL2ig?|43zTn|I!ynf^ml~f`-!uN^LG>=`rc@*8%JF10RwH5U!O|i@3MV? zEMj&0-aiQs&A~X5p2lBEB6SSO!l=N{>CZJvW&~b0u5^UejSa^kox1Ec`GKHiIm_@2 z@Z}eKbv{dJT>DK5nLrdf zR+pD3Fme?A#-pX#!aHbm`U*l0ttshano1Kz?juAvIG!g`YFi+@#4@!Wo&U#Txn2)r z5qag}$?ZUeBW>iH1x7q`;>#EvRc{8!sFxT%WD_#)8@cBMcY;KjUW*+c`DTG-z!h_( zaZX2qn-Pn8#5`wrO$&0RyuzaZ&zTZ_r*^qQaWnZVN>Y?$RrmV^f$8=b#OsQgVL*IZ zx_27BeL@+Y>PE_tq#;k!DJn@IuC6DV3Dja$V42C8+fT2T-#N+x)x&h4EW_SMl;R>| z+^80_;1g<>QmMO_>vBQRjN#OE?~*&W-%uz!JendI;?UXoK0g}}K<95Eq8z@5+O^US zt;^Y5c{45ge*T*NBE|fB9|(((v0<)wrVHJJ|E#`}?jQM(r_-9QGF`C`10}glCC>l{ z)Q0dk#&_Vm5uN9I8M-|{ihUh6UT`4p9-)QfidJp-ukRSOOV+-&-Im`Rc zZnBG6Fx?DGto0&67zF3`^50C6rk;AH87-DInd(E;2@Ow&8R(}r-RSjgF8xlHec$NZ zLC%=uPbYq6SCVNK3-)S!mxTBh&Z(!UvdGC?OImi;wRe9COM03aZfvf-5Sxu9$ev^G*h#{dIQ;t!Cqz zf)y3pv$t%`0&mr1Hn+loAJeho7bE^d8$r=yd%ym7<%ZpHuiPx(7o|T@C{rXShK;Jny)~jaD-IursNAsz^SnEaGe*R%H*vNVNBkF6} z>A<~T8-|a|@qehs>`3%MjW%}vFDj?@A{VIDtvBe=k>B(@mk6$>CG>KRkxcMr_&{jx z;Qc%bl#~_Mlh@mL=-1RNY+HD9?)lNn+ZX;&&AE^O#&@J+PKLwS=jZc6E6i^ujkK?x zZHN7OdzrL~#t7RQy|j#UXL@e5-naYd9Hl_fnY+?&-(v9=sf9bk3H zNdh)<#@oX-)1u|qAF4j7?W(BBu~lZdmUrF-$4|GJ8N7!^mx8B);Rz2!!H@gl=Y?|| zN2{clnS%v0GxMD)(dyA(V2N@C(toHr$D9brMcLl%FkGNtBQ?A)a5(B(j#}WoMjo0P zEu^EiVx-o5)zPy=ob7dUv)@@Kl5o{3$gm)Fe~F2x+Rc)pIarMQ$0doSF3G8cJ z$9}2%ir~Qk6F9OJJW7=!_jQ+5z#BaoKt0Ss%*HSqp1;;g7JbSAv}IGS0o`$03Nm&x zl!3hl2sBUg8oNF2r_8vug6|pVdVm$AVV*0>kpULgo{}-^ZN#Iz!Ekk=UGvr|df6U_ z4Pz+12KLY`(#1^ygcMUp;^Oii?@WJZU)AFKE&Vf?|As>vM=_>g{kYp|wMb<*Y~CG% zv@eWO@5R^$eqcngN6F2eCw~cT@zz?u!1SOY+7UaFUUpMB$rzy~MTydP+=2SevHmJI z6&@UNSQs}etP9^ziG3@;$zfU5;RDEKepcM$q@5gGZpS5KWt1Anl^Y;!Jsz3%sPLe; zAk)VjE$5vf;XeD--1@b+A?)4nOjpgMtv=d2b*SgOsqVu!pYB>-?RjybtoPqV^kQ>U zm6st4w=GBcM`lsk{U2w1U&ATn=leGE+pohrVFi$f>U}laK3OwoBzi~Y56aVT!F8&n z{4ut&9d@4}ljMXoX@Txhg$FFc$|E`Us&nR0@RnSymFR)qPn2)z##QWol-eMP#^(xAF!7w^sVp< z^F5Ds`W(LB8D+=TL-<%V>8r*h01%d$(37Q@=zMXkh9;A!4N&^@+A=Q!$Wj|{5<8M0 zZIn`5cyO(k+QL*6HPV?*ty@i}G*ine?RLHI57j-%x5~nn{cz-5pzE{oH^Mo;@plzs zD~_~8dSao)1uedmLU5;TJjzuuWN_ftI8@A;Kgjw{2Il#O;F`VU=5U0<(>Q=QQ+N3_ zgyK3S;JBOx9Ort7vYDn7s>^TAqy|CX)FMP|UrcW>`iKLSnG<8!lgww=WXav$*t*1keMf>XxfAB}RWB~!5?pm2QEqy=E zqadKKq;E%BCFp6@WP&sgpI)I&yi{hT8bADlayjVz*SpTPqJ2%3b3foUW;5>VN|ZvA z;~?E}sK>JkYQVT=Cw*V!a;1#IshUwDvRSqIo!pB|Y5Va|R%Ih3h2X-=TogdGVnh2& zC{8B4XzD5+NZOHd-X)i%HGYfrGDFgBNYkVR1&?#A++L9Q!Se1QCJKMYqML#OFMC>T z%|wA6`Wvd>mYhy3yvig!{iGVdho9DEPIu=hxtVIe7j*J+M^-ZK57o5vr#ikVvoJzd z9r3Ej?ea^9;(rydbyxBVXRumMU{* z1s7}soEGg$8sK>wtY)RL)nSufAiAS!8|5_D{Yd>GJ(USvEI3LvH>?F-0-w@x$A9u) z_3GBuePs$(@vdjN)kfPQ>?E(>%8>14=$JLk3({2q0t>v6=5v2n6ATu2pXMF=drISS@r*nPMsemf#n#%d#IW~n2xavUI zu=n=Xmw)YciNrL#r(_RA<{D@v5-RZx{9<9E+EI3)C5&r_?OQa$L)WXTM&S=tE-$Q> zM{`~ec=lkFg(g42%uIRx(5s}#H-JNFr0AIwYONw|s;Y0e9sUcfOV(?-`P zGp?{-^ura?|ArCZ#k5VMsHOQv%>A`$xR5hysvVHp_)MzIUlD)1f{$4%#7fvTR=_Ln z$L*nZaxCGVd}YlaDq2ge1sg`+RkY()Q3id;o~i^%Z;-$D zZHJVAcaTfxGc3OM%k|r^OnaP}I!y~EXQl|16kC=S>;LO6;K?bIh2$k%M*dA`g=_r7 zRM``#O)0~*GA{i%SO}CUkhnN2+2m)NpP?4(Sboc}MC5}=N{uM!;?d&Ia4mt~(x>s! za(}1@mdo(F38s>Iu@e`ryfGNwR)4U4#YqL&-M`DH-@W50~*Rq#aBkcl^139oI`q>-x zOmdA9^DHYXSneZ(aY_k3yE@s0bpE#z`fs>aR)(v8fj$&CFf;QW_w`^~0}V}kC!dvl zi9Yw50oy+fHl}vLOWw4Jqbm!OSgXw!3)pm&WW3FhcSIk2PZbZ(s5!p`m5~t{9aYV8 z#Hx50)hI_-@Te^sp&RSGv=}*}RbK;5yPfQ(yuR$9AnoHScHT^yfi(hiAb^ zghW+yXsU@y{uP(9TK^7t{Q~7|!_n4qLYQrlPMHW8|@ZV0mNt{hpNUa=Uu&dxVcAH_=&C3<}Lls+@bN>TL*yKq1 zFlh){y=MQcv_YZgit`1yB*Sa@C!7k;>C9Ez?E<1xT*Nz@Y_{i_*kk2_&J6Y11P{fm zQ6iUA_ZfckreilT$9p)7iyA|F1$~Qz0F!`1cW?5Hmbkp~w`Y1Wo(LaYzPdq8+x@Dj zM)J9!Tl78`dsywF|8*C5+`aDm5-xIOVGZqcY+m32B&+;ls1ehhC7Qw;1Hyx+BA?dR z88$HJ0jRI@F|a*0$%J&t)aU5f?8&Y=&=#l8^1hgTW7!C9zty66Z0z>r57p8iDr;-` zN!4fVt%e3>k~F0H$jKArlzNLl`tH(Dv$!oERDr*$rBsVI2GIMkF`V72*uy*Oiarhp zvvDGA01SOfM(AO%xsU_f&jXbUVnpUsq*49bcfS{sOS^_R5=L_U`FVtI%=i%`=5LCd zP#Av)tWIr5PY(Mzj9VrFs731zF|ioy2PHRy#G51>Cd_VK-f+%0ZD$T`GdJ!`B~i@#Y0a4znsuaFrN<+i1C4T$5y?KS{^m1G7H=4vu)dsAVa zY94i9h6iQ5dlbHkUNm;R^tt+8T-KtyNorO`V8n|;ZBUbgFIJJBq(dVu-&XNe z)8g5+)C)DNWo2p=2B>71%}65z=CZpFY_SWCOdv*a9;cNq3EeT5&p9sQMYqke&qj>4 zuG?xYo1q`3j<&3OCJncbo`SdH>!7UdedOF$A=B|%I0TcJg?lPS#K@o0US z-kL+3O!J*K8~QxmuYh!pI$+fKDj)IWI;N$vY_rSuHn*)IBOEwA@SU$Q;}&}!0E;*V ziA1DOtf`4XFJpuLhhAA(W+j|>d79-alWcomZPPE=a?uY84ci~&TQl0pD{;hZ3v|IVZVs9UBm$Bm=ij>cw^!uOt`2R+*(?1ZLsRwJ|*1;rfP zW%%{dYlj4#cl{Of)S%{X?`ScW^BdF-e&!l;8obTa{2|WHRADj@o^+^S)$9fP#IO?? zb3~y~P(qyxWLwOWB~o+y+tTo&q2ZG_LriPYQQZ@|w##7NwqHzs3Z%p9E+G< zP5zsnlj3Jtc=zV9--A!Qbf|gACVfD3DuhL`T-#L`e=ywz48N!2+&$~5Ir(1HIBzH2 zpEet8QfrB6McvABAb$4fSaftNXB zA5ynK>R?90>vSMQ=bk}V)Ux)E5?5mM&ozYrr#^$PF3*ILa;q`Oen|tQ!y$5Zc0Nlg z9=)P(LBm?E&v~~o@hW@bIgek+HN*X8-!u-j)tjxqQ<1v`&TMOP8=p_bjY_OUy+8S` z6#GI^g)pt1Ms39s)diQdB5&gB`TQ}skyF4GWAlp(I{RPD*ohbU3&g4RIE1$N7}Jv=piKa zwH|}%Hh=uuajI!|4S+h}`>F}@6_=9h*c@E0zn(a{OV7xRw$bx%gS~q`z;FLu^Ny-# zq5x8JuS!Q0-1MTF)rD6Uc7ya{Lm_9}vzPU@X=>KX6}Z;caerB!#(=y@Ps%K20RSVW zl|gKahU`ty4%^Nx-Zg=SQN;!DNk5DKbH#GV~MFlU@5$_bS2`S54ImazZnyM?~k|#DCz@V-l zj@bh58;F`_m zvrulE`C;$gUyC&t2BY$6i(jP|U54%f|0HhU9>@mvK9iTZZXoe1$2N0W0443BskcPaJltgx+1T&mpXa3Z zi7gAo08u%G`z5TQ+p~NK&boc^?kuW6u>Xt$18#ozT(%RewRf6AxN@<*$h5I3I#pjG z2WwVq+Wibq_eevf&Hngvc>KDTqL5Q%g-!xgF?yOb`5Lq!ufBQhjCZH}e$Ch@`&yF= z*f`#t!Vn>S<F)`n#4)CBCl$TMlxs!zy|SW81m2A6Yv~qT_dkg zL#&`GnL;W1c&BVKq@5F|3mwP>Y|^VgTTNaSuGAS6Z`#na_3(~+1p}Qn(`z5REaYIY z2dSnft(BQLqTfu;QZpPCp1o=YYh&Z%1Y@fI%V{K-_K_&I0od0nnI+?#IFn+mL1poL z&c7z+FQm%8zNb^}d<#$~_DS9Nwu9K$^3u4=r=a@13C0}^G5Ug_XU+XHwpJ;$OlAS|E(75XJrrKXb ztlo!4>9ef(Rf~5LBFBl$K6p4=-gA9qYi6sXdScw=2cjs$rfe=z!;Ose`t|4bq1=47 zaRbx(%2-j}N6&@6Ojl|?WQIyjEx_bbN|C#ZHkRkpvHQ3e+zjB_UiWK7pN;Xs#5hDN z*aEl0B`T)vyrdRp>RD8O@J6YcbH!cli+ zf}s)pI;s^W2>Y0k$oIo|C~1)Rp*ITPxc0F~v)eBqN=_*8#=}j<)$aFLcb&;gs`rg$ z*9M9ZQ**W^vOO7W<-p~YEcsfwcjxDNn~9^M{rt?TpDDzVq6Lx!+-qFBL#eepDEH0Y zU?iUoVgamgg7C44RbxLoJ5K{&cDAjy0Fk+prgkQ6pP55RJR$aFGTTto=aZJJUzq8( z^xvjMPyL_ZUTAF3Di3hE{%8lC%S?L%9 zZG{azAyZv(b*~2XOP=|diRbU0GA)`8v`D#Jd`V~WOjml{Z1!v%-Zdm)=jy)wd#jnV zX7cCrv+<+2Q0;Q(?^$1uZ25CJ&z`%Xy_dP>9|N7wC_BPk$_9;JbUs8apf9lNu>%;r z*B^HH(r9c~-w&`?ly4l%&xoDh(9wP1xK8HYxhoT8V`KcIe>-QF`w54NsQn4IRVN_#^$Gtl4hB@Do@#3gruj@;T zF~}2@(P4lXQVD4I{e{MBtQh!p#jgC9J(6TJi;y&_1x*6IW*sah2!z7Z?(P70dmB4s zNey3hb}+Ezu9JOAwLFN_(a*3ODQThE0Yn5$smFUp<(pQ~+P%hKqlQ+C11B;Qw+FQQ z$MRfDVgMFsVn4g={)&v1Ue;>c^yVtfO19SqwQf1|R&?sEUX~IQ1r3GCry5o08vEgM zs9G-zt2MGrg~nj0q#wtAS9v_Mn0L86?CXBLEtPE|_<0v*9ev|n$S#9|h{6K-g;>8@ zwT=q3S)hJ?f`uk^MPsU`UUCF9&Xj6St8Qj0>sL_w0@*BCUQWvA)J<9b>HClRe0+EF zAJ|mPYzG7wj+H&u6M#?ZRH?Z({Gn3qjk_T>a6~{Tl6cCxD&NRAi=2r`&a9V|zc8We z^#T)nq;Fc1O2cwO&{8#@!XJTwFeXU`;uiw~ zs27Y*CZYxV(I*)rY-xz3>jw7IRP{1ZBl7-zOt0{BW_Plz$D}fG8DllyQCY!##Af`5 z%oOT@jNO=b^=4R<%pjx$WNl**zH6i;c z*z*MFx^ptiujZreWrbtC{8$?l>{2cRgv&@AE)Vf~jpR#!ZjmXW&SCPR8PTk@;}~si z?pI^3R-qpU1j+Q#F2+gm*yV5XJA#LRbpoQj0Tq{5-C}hJE=v064{%drZ<&8hhkRyJIae-v|SZE3v;FDzB zgAR>v3ma5RcG9E+RqwF_-ih(MEUlfMxQz^{0Y(=MOd2VlXf_XHBm4@}_BnHSY~iSnRH&*p0n~9%ZYK&fnJd4H zZ=o@Vf(madAUWl00hXcAGTCFV_{Q9#(*ws>4nk6nS7S3StLa2@N5B*%1Ni(6Dne$x zvEH24;S6>}ef~R9Raw|(cto5t5|pFo6#N?4$X*WJ66;_XoM@LMml&QW(;o$0uIy^g zfT;WH+KbD&zr;&<6M$dSbs8|W^qXvfNG39pVq>R4?5_r#`H=avNk1sWGoZJ%SYisT z>OOE+K`I?!QpI?3baYzQXwmicTso+s9;$ebHmTsG*9IiQ%;)v$WzhOyH)>jZakLtY zP!C<_@J&+Q>s9@J2AH&I>0MX;_KQN~Lky3p_Tq8fr&B^B2VSjOUtqtWvUUe8hor_%U} z`?z_}8f#haxT{lY?p?|M1>XN(F5>DtQy<&CVAMU_E!;axQt#X2%a4%bqA~&fFZ9BR z@whquJ+|Cp`TLBJ^bLxc4r;#bny1{*sXo}+c4!V)Ts0k4%_)_1?$`j(!qS@fDLud347Z#6G*o;}-j$NESOZ}1f zhw3WF1A%!_%d@{O7jyfX+v71>K8qo{@2KDR4=jcrQ!bkf+>80~*Wt~-4EZ_!TctLE`i?6+270R~~fv>mgAKc1NQ;I&SSmaZGrq1elYjJQ~yFObu zJ5SVT8D8&F z(p%_@WBkiWdwC)AmWO&1GR-ANfUKKPF6h|^CRjluq?W-GaHbT58C~p({f%mdHKDaZ z7N?=8X6DW@<^sp=nOx_ac2f8PX2m%|#;vfvopycnZ`1+$b58Qd$Xbr{DA^Ij#ZiDA z20Ed!Q}&~T+7pVv5HS_k3t1i|s)Iv!O4J{sK#iELTi;#sfBWTe4I&1ki@`CbGo@W;7tOKdkJiAz4w5!VHB~Kjn+z3RDhs8^_q@B-IR@DB zK)QF{8g^`4?mcb;SHsfbTjv9(($rRLn^vm}E4E_IV5TrD`7xjed)P=v0SsyasE0}_ z3Z#WV_u@>cQG-fhtpvrNPeeVSCKfk;IrVUz8V+;q#>`BOM0?vu)zZE%pJ^zE9lZvK zs=Lin<7LCn1trFRcIDu1td(5&?v`Y|P*>|M$qDA_>3E2Jj0Q&uTBTuK3^YkO<5jo{ zr@Pj#WeUTg60GY^5an4kj>b6;Ex`4W-snZC!a|k}10XLO0Q2s-p>ol{f_R#;qnA=# z%VA}t%|_bT;%=n2p1TqeI(~r~ZO)A^0-*9T!VHu@v`>*{eN^TnwacKp_K<7!5fpmu z@p$g0=ak|@n<+%CG4537`nWiROhzR_OH}d|oGw4cz^-}!f^0gy=>#&sXJzZ@MuqUp zwQ}cO8sWn?fr^z=-(P);j|AJ6GmB_;8p%`?o{G)PeAF_1nqdpU60)f;$*3xddtxMRj1W-+T?E?xxfCj6V%_?*`W_cpM^t%J1`sgO{z!bA2-X z`BMSg$Y>I4x~!n$d#ZWbCz8OwcDW?#P3&aCH0oKO2gBtk7OB5dH2PC!`M<~ z_(gS%n`f(Qh%$Dvo6xRv%!HB+>`lbf2OnukHSF&5Nb^Zi_Yf6{4B(VE?x9jS_V{Xc z;)qTY{AgzlWL|>XO38P6k-UAOMX=fDEkBBqucZ)0hkiQ6yIyN@^GS=4s46j%?UIBm zRx7agsTu6GHD+IOpw z14%b;Pk-F2QnxwRBolyo)XxL^8Iswct9oiE`o1a;+WJ1oA_GQN><-X#cVE%xIMwDe z#jIN-xY{O_Fpn&vC%(T?b#dwKX(g7r&jRI}tD;1FTIuiJ*cY>+raP|E@U9hUQ*C)5 zR+26jXFS@CjeNJW;ne9NN`0ZA6dkL0;*0)JVdBM2#1vdJ4tM|PJl-{pD$S2#aZPb& z{4i40n8}Ehm1?oQc;$+wT>->O5F$^CE@Np8-YlBDwoh#ZEsYR0!Q9-Xa64x_f2k#X zXa$bp4cS=ncAqkYlTN^v;vMm?JW$M@y zAeS#}TmPX7mvqvlgMj4ly+ZNCTY!fFabIQ{!FBPh;K?+*pLvf?*Q}h-3pEe>dQ5r= z%yY+m-@lx#o|oIW_Y{Jyv%XCJT#<7tc<6XQt28E59UWIu$LdffG-uf6##Jnp^1aBd z;n~__LS+_ogX(3RFs5{0wu-^x$!u0(G5MvrMn%?s05IPuZ9k+Jeu*{o}=%}S%FVDVKeIB2_ zlQi&$D(-h)+wJQi53N;xzUYs-c9QLm5IBKvRogze71i* zz(=qLhcQ&YI3U=5b6J*-I7Y3n`?Bn7_{7I39S0K|3qVo?JsSUWQQxFKwE4CubF24_ z07HoN|H9r|hQ+aU3&M@NyGxM9t#Lwd=|&sZgNMf5LV`8!?!n#N6Fg{ecMTeXBuEJP zIOn|gz4y5@bLXA;etq9e_3o!uRqb6>&)$3KUbR+@blbAI+p#C}%SI#n1Lv}Z@aY9z zBA`Mt`)+K`vnLx~Ur}Pqf-;l?>@h^;xtQE+S6TM1o|nczmv~{>)*jXFU{jv!Ib|@q z+ie0|A1>meM!YwNgTm%y`x(>V6C+T)RD8?>30mO*z-j;b4b#zpyfmiTS&i>2xBnao zwg}W+wG62F2gN0C;!fuVmEoN}k_*{x@sd3Ufs zsms%qU1Vta)V?x@A&eOG(DuT{Hx2|R%Wwo6_Fgy{YsG7`9a|Zn8V0cq7JksfW^`f2 zOiA#=bbJ(L4)}9qm|t}^+!7(lt>%<^#T3>ym-da6zb4umxP>!(!67I{*W56sm)T0! zm@N)+b1miVr$Or3lou;l8Wt1R`Cfo4S z$m)%GMT#0ERoHkDsBknp#$r-f>&XID%$M~m=*MipqGP?cBtHwf2R*!K__!NTT5Eu} znWrsD-1TN!*ol}9E);N|cNWW_WEfXc#>f!^W417NwllG9wHl72zilkKZqKBrH8hG{T=-1maK)`)q zRgCBaCla=s7)exc5-{BeylYazyIZQ;9N5j(`-@;D(k#2n+)iE3U*uagOS_2Yq!>&! zo9}-5ixr1LQV)^kWjOKGSZ--@nBaH0JtucS7j8t_bSt+$4zpmXup9U{z+HXISUL9U znJ^8<5EV+dutlyMr`#5#cM89<8@^0gQuoG)2w8C^X9JQ2c*HtL9C;9mJi5hG$ zR|=^ph;Yikti6JRszRKYa-2%s`gx)0Z@JhvFsQQkQ=bm=KC~OOW3p#_@^^hPL-=(p z?T|20CaF>y%TjJsQW`TqREYU~iF^G3yT7Ofev!PM2m1sOQ7*gEv&TZfvjd~5aZmiO z0S6o$%!bVZf%*qp$w2yPuWe zsN<=0v#RCmDW~Sp)bl!-k3ctbD`OUF3QH4eLEg?1;6+rodzc`#;M0g6%h;{M&ar2SE)kJ#oyz4K@qw5#sCQXLIB`9O_6WW9|F|`pTtf1YuYRR@(wi z%^LQG`a{U8Xw`4j=V4IC9;Ml+Vvl~R^HH}{rd*ax5Dk7RyO%Mu|Evl5a1alFfsd4- zshS|&Hy{3u{%;(PuElJ2hsE0c&pKK8w+J4u4KJ_O^y5b6@waWIGwU8%juhhV3vr(| zI5=_hFjY8c14Ks^s_l@ zpJ^l*UKPUGRB0%aX5@+Hw4>wnZ!Mrka><3W6;8okvmxY3>E_g;%3QV9Jj&9s@dU-NLU8C0pv;2hR6B{qdYVh?hSOc! zV3TU0d0ET@xUN916Y5e*f&~hFy5IWnrXscRApY zR?nGrioxAqUOEQ9eO!#xD=A)cAtvB1Y)oOE22kW!xPDUfgPc@|*YO$wP-f=~Xw~jg zrPy%mcjPOs!iU2zI(L(jbh1*hjDn<-Twi!HMA|fHTm`LZN{{k5Co>Yi^V`+>Sw-i{ z%L1=+B8rrEK`WMd0m24o0V+ zN#Wc(aa85#ksm>R+vA;rRobUUrV;1L%3eRIw^AB$)>V{+Vya1w1w$6gecS3C`#!IG z(cOO_&Q$vpc=^jc>&py==aR?g_If>2q|5MIQ_DX|ba{Ew)8#XZh#)B)DUCl44Gc_4 z#Lai2tu|}3n;MNm_zgH9P~X8PEUg8VLlxz~A@wAR-`pSpe-a$gFTJ5=hjceH9$YZf zN+Eow9hBA5K9yAcK0BnkM9Vj$|3FLSKhg3`&G-Gt>z_M66Iq-7cq?=x^Ttc5(snl$ z^x?;GnMnMgEZT18%EMmj$IW=n=+^XgIxo`4=CKT4vM*6;tFmXhwZ|zX9w&Q*vn9RL zh6uQM2o|kn~m_K881qCg$Q-K28TIW))0RFVA)7? zKG{8BEmus>2xo$}7k>@25r;X55Jr#5*xG{+8O<_lmmM7o3>|Q6!Ro>@+w7ri7(EO_ zMWDj=jC6J9c5xcJt}7c{jse8Z!Acg|48@~y)50-~#RZmJ0#-hulZ3s-Sc5H0P*g>& z!FSoAGEBmb*SbdMNxKR1Y#P2{EL-Q{v-{meYK%)b95Sv{Zh?LhG+H9pNV}~B>Lo0c zGOtUC=PZI+P>Bx#E!qZlMQqLBhBZ5K&BNIs^2;8WQPLe>;z}x1 zS1bB6v48Q-Rc3kqqOz_}h2J*89e9cEj}6pDL0_tvN7Q-pwb9wcP50+ zFXqce&QwU-&Lr$b>DHd9h;7D#A+UX?kI|^>Bcc3L%EJF;+v^ub} zP?5cK@nUWip=_yzwo)Q)mP0Blgvx9_(Iw)Gz;G7QtKiwHb&OhMN;A|W_F4AgREs(A zT6bZC&}K?mD=~=+g&Eoo?xOiZc%o%X>Bq5g5u?62Uv?m}U1{@P+Fb(#m;C@(j%lI# zrlfhhqa|8fjDgbT)Ha_%o+Z0JFeMtw3wZPMV==c0&at-eHh|i~r1>_}S|r>SbrvRl z{VpRf9ZFpG6SgF+$|pZBZa!4nFHf-LB?IG509PiwFSq^#g!9*z;mNqN!eLtF=wch9 zPmEMPrzUlJLV1r@!s*|gwnSaoel5heXDB3;+Z{fqj2Rm!Xe=X1&~<&anAgoPcQr?O zYpm_t#s9d&aS_eR?l5%~DjFwD?N|7^+;7M3UH44z+gB+l;iSzd?g;b`3?+rTS!H=S zz?({fl6`m4&KckW$8A9-rpdkv-HU zP1WzgpvZB5GD?ik;YLW*gGgUw$bsY{#w=gs$}!lL9ejn~Y3NyCyyCfvUQ8*|&0z0N z`nW!KyM%H4=~yBzT(mgC1)mtlmJbAHV#VegSQ&#~c>iix-q^VQ#q9Ru)op`FZYS@% zARO~Q=J3`dp*lrm?roNoq7|>n(IKCZ%9RyR#6{$PzPEb&PW#>UH@?ke9oUBG4I>LD zl)0SbU5b`cQr;h}puySWP|61e=vU!QibaQW4BaVthSs#*_5NR$2`hw=`jeHHyyq|H zWQX!DB~fQ_5%HCGF?as$X09df`OCliNexA|FZ zh4Tvw8*qjarm!R+erQUR(}0M~dvn|rcV|@?j_I=43+*|~cXM942JFfW+0cRmEzH48 z#@gml7iLz!(SjQ&$%>$tknsPFf_K+QhsvZv=icGb9H=fR`hBnv5?V#HMGaL&*tf_04ft{5IAHMS?8s}+P-nU| zeD^JUY79T+B;_j`DxeVU8#?r}_*DMj6!fjDcNzJi@U=NHV5b$&u)xJr3%jU{DI#Es zZ+YtS)q*zb=Y#Ryf5>+r;e6>Rp-#+25b17>hID@qZ%T*tkmo${{uDW^XE3jTZ+YwT z)tnxW<;OQf(VrvM<{1jokHhJ<;X;c|-QVKlWg||*umtS>dOQr^&iC?x~+58;GWI*w`4hUD<3MiG|ig}y?cBdgZ9@VJ|9 znM2_Oy)Or&_98RC9wn|;`B>j59}w~EUHEK9IRiL)8++r1oQ1BL$m{#R zj+>2px&Bws$n0d*;G%D#AX-Q=MBngikQqde+imV;*64ysz1Qv%PHj@~VpK!NZ9_>R zZkt6m?{e5E_d7 zN)EQFL$BX%w6gMX)PR#gd6D(-^B{sH2HFx!QpoUgp1(Gb`1IGOH98u3;(cR(%jrV7 zlP?xF0@V|+y@VgtZx+Uvdsm$`JSsCB$iEPsdNN}g+C`m5s(de1erN#ZJL-utvjVxf zrHfvHF%n?MZT?&C_QVlWqdMs$@ts(0Kw2o(3YAth6<v_%9#HbbwQ)c+W32jpry!X`gZ+dZx zmAi_(1|cY^z>UE9Qn50heoAf?QBD5rn%UOMlg0e3WFp{%1v8Jt$N4hORb)iPE53L@$qPQ#Ymwr zuH3!z*H{cbyqitcXQw0X=>&LnonuHWjzZXRvZMcvTT%ioVEb)0w z9j2^0$^)FnRfQBLM0Z|b+AP`##c#j>A=g-I376V}ol+klBy!)rF~U&|;#HAupi~o1 z$Z=ixN2@rU&>xP)LM1|1Qp{{6ZZU7DBx>8{&SJ!=B;J?JorPy4CuhRG5GNP=_Ew{5 zi>$Ss;(NYOTq9zpBc5ens}u4A1V5zxjB_>?ODEJ$jWV<7rQv#nws&yi`!R5L(ikSE z>IBBJ$3}h<5o0@?#T}`5r=5Gi3-6NHjAUtL1sXC>m!-7Wl{7#t8?M|D;~ALBo!B*X zBr_HULkxZJQ=*=zlX{Y2Eu!3M9^CpI))*p}v3fPVm~5yLu*4-z$|h*pqtd()`w8E} z$I@4NbX5;#A>a~#IgXd2T=Cd=sP`^T5-}l3M(Hw>m-1lwIYgPZ z9F|7fQQEvjY9vF@Bw}4V>+1(vGlITUpw!xkeXELsSR9lCArmLxZ{n0lCv;Y>756qb zHIa5psH#ACKl@?UbvCH=Rn^nFtfyIlszl4{?x7K7**N#lF+b@`+H?Z*FF1b4#J!2^ zCu(G2p#~@Q5i4tap?>+E{1$C{W|W&sHd;ex-huU)73j4@i;_?Uq}DqnGltr}Nwu5T1 z65P}#?*=HfkBF>u?{V>VUL9b?li&PvGI(fYVOecHyQe5k!0mpF$G<$*-j`PVj9<$Cw4 zeojR)x(Q|a()F1a4AriRdX9cjaQspOWz4avR!cPyane2xzof%0xTfPH(;R!Bp>|Ux zK4FoOVjyuJY>chok9^&~oLh#*JDVLA#<;9g+y3C1V8f7F`KkY>t>kHH>RE-Qt4CQ_ z48g=6-9Uv?n!&K)?B{H3z-vaubG2W>`BblMDGCSY3jY!*(&PX<-S zVt8nB6LkTnrC);HOz6v=jsKFEhxQA(#OAzsjlS~#C*Uvg$~-;C;dP7R06L)#AP0wA zY0$XcFb{RYqmXi2osYv)+O*082~);7w+yp%o6*o`B(L9AM|xC%m4F&7EtRz^N?Jkt z$AJv5N*zw;o(PyCDMI8!+0U65%EmObAq5@1&Fx9o6_61f9QgpfFkc^(&JT9pj^Ue` z4$OmMMmWOFXEZM3pO5qn^Rzfz=36%~=-|&e$LEuy_%&)R>$X=E4Ku)q#uzviT`iF% zD`zC(TW-!9DXk;uNCqrHvZcW+i_HQer5=$T2Y}+!*R~2iuhGGoa!Jq!+&Ilit!jZ@ z89J+WjO-brGQ(OaG_l<8kxM$9i}4C6r(@~hShW^ZRstgCADK9}P6W^-81_7q$^;FxilShK(nbz3p12@}zvtu)Gsjy3JIl~%QFRAQO#;=0R_6a|?pv6evwt$jEI9PkJqV#LI*4<_? z+@-D+lL(5LQthW|&a>yIp*a)#GIzNYOHET1^A}>npQdV3Zj*%~n_5kK&YI49Cvzn* z>eL$2Gj2{#vHl(eaN;8X5Ri}%P|*+&5CDH}2m}BIK50$!Z}_f3i3NT1yiyG_JC_<} zF27d+&w()j2(K7^1J-hhStQw~Y#HmxbVI82@p8Nrhp^Rc_*M~cfPw61dsywP4rcc$ zKZMT+!uUVYtQNJQn`&IzB2j8G2AqID!7w)Ti&Cs|hL}rZOdTP-vbT2+!xuqAfW;6b z*RuPkN`^Fo%a6FWLMaf=O1vFW^Jy`+$S8-To9+)bcIkpb> z9SeOkgCH{H5OLg6dB{h3XJ*+_E}MdDRH?6O?|}J+yiykeAk#ifMgb%0W4UOKBnC-{ z@7#Myt)O}bGVK^bZv2s3dB{$VEy8FXIJSzV|83-5-2oP0`~9xn5!d9;a~7Y^?Iryf zp;Wj(-;)GPgrj8m)8=6r{3z-W`4XsSosVnvl&%dy1#_-9}7P z)kXr=fLCrC&i&VN)SUisa{^ymIp_@&Inp)rmh=zGcG0EXQ>qVG_JQ}9&YoSbqNvQ= zI8YuW?1wz4w+AzX?8&_~7+LZ|%(6nex?x*IG@8=sRw`KK&b~88f6Ve;-6vP=Y#Di~ z3++#+*p&LdBx19rdb?}GW2DJNt2&+eUE&0_a(X%~YsqUX3;uX7O#ChKl2S0y;$+X# zrU*N@bI{YdhD#4-v5pYaT!g^K=?ERY1PjEC31c)8%oNruZ+Nsa?;cPuJC~McgvWyd zkPG;TlhT$8glNSHTF4b~7^s*7vxz*5P^KBaGPvig?FKn8H={0FQ|m+l6)l}TjK~-3 zVO?w=Msg=f5d9FCGpM-4{AIjFKQH>b?&+Psg=%p(a8i<(Rm#)sg_Bp=2T$JLr7Nwb zqI)b?xJ_!<@OG=6c=>yyg82P4Ja<$|rU)B`4@x2m?a9{KonQlh+8HgN`0X6*%xT7#xQcc3sk@6A|0{9~q z1nPJ&9s+6VSt^-6w8M0%-!2P78XU{Eh5Xe06r`q+k#37xJ<%e-2O|o;)${!_7@v!z zx<>Xzy!$T?OwiDV7KQyWRensYLlzTHi6junzMeGT9Qs&D>FpdS37HOAIeG}Ojg{1c`lKT+y!w-qQxuF^|w+<;&y68}K2-Vu~jz6Crmj{7FfF<#Bh7 z^@qD&i4A}KjM$F3%@J7pzqoU)Nju*a2mqhZMg7-h+1|RtCuVK&f9om#%dho+R0E&_ z-sb(D(p#G~$JT!oMlYOa_WSbR4*z-nzX4VVEt@daAD{lc>3>t@AD0{wzj^d*y_$Y& zV>%`M8z7zh@hSfA6J9rTHx%MOIivc`AW8=MP;j4PRM;RTu4?#*ZJ0oq6C#yPCkZCf)uU@JSyZd9_pE(uCr!)ZDG` z-OJfq|L2E&Uz_$XOmqiOx4=0neey&oc*zXi);*O~{^1mKujMpZA(8#(I1zv`5!jcUgkNzB;CD3U*ZkHpuNxeQkEg-Ug5N)D0c-x=C!m$j?Rg@%*#1 z%kSdTUU-k_@XQ`3flzDeENwOdYzhX3mP*+}WFEid9nCoo2N^KS_jNvjc~DGcIKvNc zI>9jW;!z%ELOs0#5errJoUc9GA+lLRjT(Vg&{V%-o8RHVFpW}_qRRNTI<*5}eG3Wh{ehzZcY~Ybb zHWgE&C8`1&!2}1KlkpUl+Cj=`s}xM%(0Iy-^|dG*FfBti*ZAm7H5<*Nj!X*G8Q-H$d`dkUf6y1L zp*nW-h%T)IGbk?sSvnT7T%;8qE32|tjKw^z;l!VrGAhP>BZz~5OlJ8ca$|bK6`haUZHo@5r_?j) zyZoBo_2mI~eiKdPT{zP)Lj%)blg_eMMY{(`oG5Qejsm=mBCg@GSxjk_`Hu*_I zMIbwqg(cs5X4{IgC>3XxDC@_g+x)ZBpD-!&_H?&ccQ8Lm65t@+w+i{;sCDmXvotdD z3@5rse@4ZCs=PEmVHDAmaRlO~I+1%&{u_WO(UlR)0|J@Sn2WxtQ{k*8Jf0I9k%Q^B zVjMD=G{<8Cm>bAQPJ9>AZkA;~6tWk8kbecNmVR1~99H*yE!Yaj+Wz37L7|dyEn0yp zrQ)4Rr3NT#KlWNU;H(D6%?4heg z1hBz;H>5~Sg>T_#qGfmdbB3>GdlmP41Jpy7o1V)OHu{MvRz6{a54Fq_=cm*`n;|wn zTvw0b64-L!ixRBB1e_6>k9#9df|C{m`Z@%D&71$Ub!K((94KSri)+;3^=bB0J}CQ4&d*q{rnuY8zuv{d1K2`Y zy}oMwc+k1e<5RNXYKAH_gz3t4xy4A;CI5JUq654~xeH3@FAuGj?WG8ojIZ-nBh1|4 zt32I9rxrTF4vlRd+B;H?^8-o=_zbS^B~!L>mDZAo)!#~e#~712$h(_*!KYOJn5MF5-SFhGeNVBv!N>%7H#R zIlK7{kw5A*(ScToY;929_uawwC*hZm^RMC$3myXm@%HY^1L!7Y@1E@FK3!`(y~_H( z7ytJ9!(YFgn-c2L@K=iX@~s;BX>>Nv^^yWjyCTseMx056G<3{<$4LH zyZ-`tUSC36a+Y4nbzliuxUU&$sN#;uV{+g0C%@ZVNc$oIA^Md3Af>6$1hHS~?#efBesR zs1s$fB<`Pt46k-Gq<+32m25VoH86*h)Sm=wru4d)RL#yfw4o#^w!ov@9NB1?d#kgi z(=5#qN{GmauD)FC7^sMf0ilNS^Q}8<3SgD8oyQ`wcJFLFXIyz^$H3IC^d(r%lG$4_gYRV`P{A8T(UJO`m9=ohO(u=)DkZbW`AcPvwiBOrlKY7ibz{*vw0J=h=R%> z>zP*8Ehgtu1PDXLhJnbH$86s)$=Qo1A#!C-T5_GNQbphEbchKn)dv;C9%ZmhJ;td$ z4ZXur%GTIWu*7y+L-HwRC!%6z4kvLi2f7iryF-?P_^uX%yiOESA>nTc-bHspR6WaD z5U^sW?y!FeHgmu7-X?xvAF?oPVle<__Lxn{(~(za9u@4-L@R3==+E(%*KOW0Vkqs| zZj|+oAivO<17bmlmM7Rbyx9gWo&Mq_3n(uQ_dQ${aX1mu^X4z4m&wN&ZldnA)P4OX zY&D})R%Vgdt$9Ckk*t4cBlWl85)_CSHlw%fW)1ruf?czvNd)VBdlUxbI;awx>@I&n zDmPfRnh}ViP{B*}phrgu!2R78xr9L(p8+ms0gm%@(2>hSxchULvwcH^_&#TwtPGiGD5n z;mZiVGU$T_Y4U@#S&n97sU!SNm-&1Of#F2IuH#lD`ucW4h`+hO4fsDHXa-yjY9~KC zg#}kw6&|k5i5Sq3!pFN(2F8{Pl{&LQ%xA~h9ED%2xFm{*5ya!zMw&0bXr{=LZ?XfO zy;V{V%6Twt#udHh>GJ@IObc%kMz{~Y5t)!#o87hjg;2KmO{CnBCApoo>~s+$&BtJ@ zot0<-ui%}H%eVt7V)}$YpRndJt6HLLbo3T!qB9cwkg2SB<;+u%qoYg%K3w+v_CvTI z-UD{-ub2T+yK(eUWb69y#XuiSj3Y+h*$_gE?pbC2BC{w>8hRtF(8=>2u*O=VDZ*Q} zVUt9qHeW~8*d}uV(mrSGnIj ziatNsbI3^Ve|>XOU9h|e(6*9F5hK}FbrJw#4Ndi>@?K>m5!XTcvnb;kjMm_+mIEVk(MoOGH!Xf~i5s}nrBd&{=z zvEFaMqty1|tI1);>Ow0S>7gGi=@mvHd`v0IeL4G898eQMTGub%{uCghUifKU1|kOs zW4hDP1JL-S(S|xrFY=BgyZmtbg5{0(eE z8=fuvKp86eJF6uWE=K9DN}lEGJ6vA1#`4o&Ct|+=esLc+i|TIw&pbN*4aoYh{{MR4 zq?C}whx{elowntlQE#tDxwh`VjvRQNa$nv*`?vqUDKBjc_IEd1NM{^3{|I3X_(l8I z9D6uFdUeF_{p*FkHaiJss7!%I`F{s^&i0`B_hjM5hSIhyJbmwfX*qY?^nUNj*PO>j z?Khw(RL|O<9V8Q>iOC=b48<=b{!btZf->A_wm1x#Po0C9U3`YL%u0kDO=M}cKu*Nh zBQ1-`G7}Q;G2|gpF z^Vb`l3buYSgRcJk48gAvw08ZPlC)`98=87TpzvoiYxRowQ>@}5XAu|QV73Zv#X_h) zL1>Ipv?t7Fdk?@X)4Mb-=mHIWjGLD=gkg&nv*oHh(E+UNACU@#-L`5S)w)f^@5=fT2GciM+ z^8a7`2^pGXia$kGZ)9!fEMqYYU)F*4(`}GqIoD8s6ei6!7U&7(3n$m?#`aYPEiwoA zWVbz7^~nt_jO(0BC2|gA8qEZb5F~C*UzI2l#$@N_{%RrFSkrv+`fFz2<(5yBwev3Y zBSdqfM2AV(TB(SNwCi&Z(6k~jC7BnPp-uv)w?oHtQaC4uVD>LOpbrKJif-u|snwc+ zNC?-$`M&}Aqg$6!o2~>hXd;%p2IG?P^te5mun!Sh_^@C$O7wH8L0g+`1W zMYc9po5iRQ!5f~OAJR!HMQd}`*gf-N8Kd_krw>_?3v=)`g2U7dwz&wozL_S(eLS=V z7Q#&|-Vncr0;Rwm`Yn@VzyK&R+I9w-W02j%+Rmk_`qj`AUU=H0nkpwqlBT^iT1 zdw5^6enHY0I;9%{u`H%HaokP*o|++Y5Q`ai*n)>EO{VIlDS;xNH>!b#1YwspudW=- zq+Auw%m(21(Z$!FiQwI9pe2bl#nd=U<10veQ@J-2)#WO?HtvaCa`U5nzlWMWSOZ_# z%nqU(lZSLZKnndrQA(YGB2kIbSfKlHRc&3`o?d4bHZuNhfY8#aC%AuMY+_ynh{7tD zPcX!-nF^uhkQijj!nrB`q>DbT5o1kkU-Jh>=2uf{s_835PZDO<6($O8-h&3h69qf= zod~jubljmdq7NnmEes=VEC`8RKtAE9-V{W1o@osamt|R(HWl*h`GO-wHbktHL7Zew zq#aSKMB?{&Z`FzAf+8{1JyLk}sJKTOw(zrA=Coe8TQOu#BpCAq71)eMZyLL2ezlno zR_aR>2AoLM=T^j^q(>rPe^m=*iL#Z&5a!63w!x^Pu*508r}{VI`}f%Muf6wg`cc5G za~Lx(e7*bN&q^J*;`KP6iI8?^IU7D!J;uZUDBSpt^zBN(jsuy@r>(?eo+i*}8vOiO zwhh>?=Sh{ z>?F{*25LixqS_5u#?9=YpnTVfWV0RpvmBQhc@@eD3b%ELQ%YDo{_U&mx{oCM6uw3` zfiQim0bN27BK!_`Rvc;f_JDvH21B-&Q0HrtiFuQ^O_Hi8G?7U@d@b@sT|Qc;WUv+N z;U|b{*+@`rCWe`e1$QZx?t6M0HyjfICI!|VbDu$Naf?Pr0Fu3RrL&3xIzK@Jx>aJ47STK;JXR_uUARgyoPNz6!r+Uw7`xgY zGHes(qVVmoA}p8Oqby0lJc^VEgyi*oBVvY9*YJm){p-Ngsq}W?diXK^zaxC2YG%8JQ3>Fk=kmo0-W+hnWu1+ubqF2{)5+u=bBqPTVVkfGk`o3TdRH=G6_Z zMndNfJpto0_-+QE@HLJK0OvXVI^K>tGVvDmBA=JiG^=fQ*Cc-zuXH1)+nFEhvm(oF zKrzl;80a?Jq^-<@PZB2d?|5_88E6sAe?;zK)E^DnQ+OGqMZOf3IHsY?nK1xD7!wh< zlJjPXs8C2r8?>9m7c%SD!Ep0wl9gFr?`scw`@)cq;z(vAU3cu}`1_ijCD@Wb^bbMX z{-d;dW+i23B&BVkt%4T*Piz`zNH}b1fD?-SkP9hA!5dY#jGLjnYTl{szEDx4y}x%J7FTOS&6$A!hNL)e;^sdsvSe*Q`>@J#h8&P5`UF z;$5p}W)zuHrDYFam(`?lPzjRcRn%YgQm>czERv8D5r;)q` z7bgTG&c_Aw6S&5S14x~YgnrJtHWtj_#&4HjOny*e4$h!r3rsVN4wpeLHDAio{|)F& z>0Ldru>EPch#1DTV)Q~5j85MmJEuZ4u??&HC5lsHvM*)V7nSUm_w412k^FHR5``Vq zh!XDiYa!8s6lVwsi91kJjl{yaCC82wx{tNFBkX7AL{AY(o;rC+^z}C&RJIh{%7}AyQ)2|UxJN1wQEQP5!LbVXd|q!x{K{E!%;7#F=x1Y$9O)#RP?Xe$ zqj0MX^yA@f7KMLkYsLs{IKC48OU)gkE^gzH>Ut>Q6oXed!a zOp{momW|pma#JUyy|Wy~?ZI1s1Yn^2fSI&dbU24)`a-#=zVS#&Ok0EKE!UDlbLxeP z|K#7IF_A$R2D&O`S)G^_0`bZF?(!lE-bDDN+^_~u2;%uqo7mB*kEEJ5mPzL_(6Saj zGw+1xSvdO&7K~~&zqt>?USWW;MsHf~8cRif4I@Vb9dsJsu(uzQfT|(&z$MfMae!xk z)ka{`^e^k48Ra!X^DzB`k_bd&C4N-{ew|R0BOoWwYX`^QX=<90ytunQ6oOEbj}A-X zka|(9afw|wpaE33691MxS@_2J#7pD)XOYk^M9X{MMv$v*M6J)#7^dIMNk3;Q(blnD zkFIZpSCk_%NVqx37m2j>|C}V*gCN9W_OGcfv8yX zmer`?6T@S`>|L_L? z`L;(=RNGrk#+z^5eZNnBSrX3sm%-Uj)y6B|)G*Txgcbz}OfT%H$|E9apEw0rZvMbY zok4%2G^_-fJ^N_aP(4F4_!#?7dLA%sb#bSl!pmZP?B`ops)b(GHoj-`>!zDAYjT-X zb9b~WOz>Kx%OjwU7RmHZP>?c1(oMPiaL?fEHsEqHj)OSZd zsK4Gv-o6Vv6?s>Vl&+M}k57;UQ^xN5H1bc8>FL>eFd%`H$p6`gCl}`vQs4{cw3O{M z2C6u(Z>3FMQeT**zM$YTz9rouw;|T`M!QSt>yz7X!T_6{(PSCCUJ&YYU+K~qh!pkw zs^@i1$q6v7Mai}9vB_W|R8bJn;;;gy3~fAt$@ykc;c7$N{Mp_!(Sd~Pd>HX0ud|~z z`IrVp%LT?0$+LBe<<)Tai|@4c`if=4R;K=Bp9P(t=_&z1ecb32Lai0VN6V@un`{3r z?)~-d*oQ@_bTe1IIi$U>&4-^ri_SrujD@|CvXK%`#Pa9VL1{uAUvA$0-3)g# z!%NH830y1=!wtWLCWMrrh+8c89OgG@SYRT3*VU~krZv&WL)Q)16$y!dA0ds2EAV7O%^TOF5HKx-Jgn$w%QatWhldLH^`q&TAkiwYPVT(E`-z zc7&-fE25FQ;ikdI%7MH=%&n?NBWm;ciOz8NA9jo87^H=USWc6?PXyhcBP|wZCM8{Y zyLi*G(*Ye<2qQ>9`nROnMkTE>s<-Tbl=2T+n|6RG7NOlkLv$7Y@i5eh7RdmT;qQUe z)U#XFei1@w|K4pxEi(sl40=95R9b+y+FW(4;6DVrR^@pMD>*k4kBVZ$q|UymIrL}8 z1$o3?@T~F~FP*m8?QB5>({rFpWs!u>qmz8o%Fc7A zDbfl@9{plmY}%53`50$xhK#_jd-nMQ z2YF;jZOtn$3jGCWUBHMes+iPt;ooWQ=&f z*6s%gr|Z~N$FB1;C$9LjaPtdi(d8Eqi%7%rWtNBgvh z{0-5ON;$$rFh938o}Gc7YWyDpjI-L7(KY<1utVwFnJXKaPRY&T1S7;3T7=^jQQGv? zEu4aHq%#tQv!=)=t+bd?>xWL}eWV2`JmkT1gk-x^-D5qei9f;yoa|15VhUm)*SGoi zbY9iFsn)AsdM^FQh84_OzaAhaj6R9-$qt`a z6&6Q>vC!r#=lJOl95v@OS+TFW52M-k)xUjV=&m~{0rUG=1|6$HxD9WdyVPzfN?1>P zcefUcy1pb&-q*TPi=TaHV-4s>aLH9F;*vzVz&4pTtJr!u@7B{amqG@M;IbD`IJsn2 zV|&-?rM@ye`SaLEUNF0U7JgajcU`7L@VVl2tVyYy)bCyp34ZGm8Ws`Vm_>#xHLD0+ z{6S)jI5@b`04-aP$Yxrz5+B#u%8^~CpxKj-3X|)VMsvLVa?oHVi;gF&Tcgt=Ai7x= zsgAnr}DNFk3mT_(Vjj_T^7kfyo}}_oZ>%{$OwN*odOl^hTAt!iUt0R zb-kOZvwAIId)=p7k5qqvXoH|A>rS^H@k-u4p`4^Bs8iai;ro~N+&F-B5R zXAKslXu`WiyD2`hEoSBkt}7ENU)(!ne3JP#VX6$JTwHQjv^X#3;!ZTnK3@KyKxWKQq%~*L^Ah2w3&;u$SuhRrAC=T!-NSF5~|TWa&dbZ=$&-&M=pc*;pJ|ddQ%RP zEbf^)6+0Qd)s9uy<@b=`gb^QhdbywwuVlQ+wD0V4LkQ;8Ym}6j3zM12uiyzHs#tpK z&jA~W4N~hEX%x?jnLpy5TNDjmfZyVNS`8|Y8G>z;kcnA?__m;5y58B{I{cim+ITjH zU1<&u^H9bnd}X`k3?MP%>yQ2k9T9KAd#4IA>d}B`1^cCm)aZOQ{eFA%16W7)=*g!| z#C`k{HvOhdE!}9yF)tnpUR^J;jl7KGxDyNzs?ENvQ0bBoil9059w^4uEp`8}VCFAu z=3KfyHTCyGVN@DwYD}QI=tF2UDW`se#n6A;nO(9tC%8OPP5X--M{H(eq`Xrv@F(m< zligjcb9aYkP@qe^b-clHdQR4;w|7(bahQv7z+-*C(8o(uvg{eLDWqzKOB$Y7kXlEG zf2M$tLiK5W&Ro4m#9btuf4EppKDuioDyql&DST0~L)*OQG+I3kWP#ioeJ*U0D$d~A z3SggP%r`jQpT{NI=qIIQbN;sQD0B$IPG@d=Q4@rD9&PI5AOV^F-dNIfVoW=A^ng;BGmItGL<%5c^puvbOKcoKV!BqEu7yf7t3n%{`|>D!`8>~2a@ zo_iLQHy`zlFn6>~xRmA=b6ZQ6zy4RNWf8d+Wa|6dM%EC!W)YlPh@gSn{JD$eH<=>} z4%4gMvGL=}=e1wL64az466_MVGX%{>w8en@bBja0qdB>O%xx-&A_2mI3=9lvALMgm z%{aSJ@468-7bYKi4p(3{wow43SNB6sTizvV1Yx}^EAPF3kpm10$Pa{J5Cx=ZHM`^*&Pn{U(SKH%ktkk_IotmJYf|0R(SZ!unBPB7E(MYD2Aodb+Wi}>5P+KzTzvn7R5OOw71vb`iztt%6=odN z_kl{$rhGF4izGrysnB4itw7-bT{RdBe5!giN#r99xsBqaE+ky#BoGTJ*4fkcwded< z3Yz+J{CdG=EP3pZ13xnB5L8JpTFZ9B^=`%VAnUEXV%0eM9#k6(tAFtSVehSj;_A9L z(Z=0fgS)$h;L=#*8r&_oOXH2ZL(oQoYjB6)!Cis|2reNZ3Avp&-}lY$*1a?LPR(Ca zHPuz8&pzFCy7xM3@BOT`p0zeNEE5ku?SRNIzo|CGT8>IzFB=^q9nMRcrOK(q%Yi@F z7*A*3sb{EqTw#SpfLZGBq_#cI(U3^1MmQhUhy!RRR5oYe)5SI?fx&#P%VtLfOO=U#$5qfIvtiQtzio^ z*=Y;-ey!sL0@am^zyu4ga5sxK6t+p^aB{TFl~FUyQnGmEL@p1lx1Xzo@l!0H3LqAN zvjZN0Nz@ne6)UGMDe1wJoq3LqU$)S;>?#( zX@~9pZ3#gEKf?j^ybpKxxTNEOVM0Q+WsYFFvkTb`f$((Fw6j?dRwI03Z4ea z6W$lKxk#UzE^Kc@lqMN$y0^PWWttLQdW;1fwy~QnMU`3FD^0df#fYtA+oN8j4zkm- zW?7dfi{QZp!}Ef&c1Xc+f>9@s5KOn&_fdVJi6@fS?vh2^bMFYVmoIKRKz;rCo%Z7U zEw{n!SGOvxsQw364`i^(5>c;4Z^-joC@qCtF4xSOFX`Qohws`H+4 z5aFO-?)$@3to0I*0uf4J$jJZG2M%1+4yTm*04YJ17OIAfIa-0XVDO4y8bo!J;5Yu( zss(!VL{Yo<8-R)YH-<~pu_svFJr%40lL#D6XxDdVS$ctYSyz*T4}spM5l4Skk8DDj zcue?UNf-+Of>52b9;r&N-I_!i?<;$C3;vgl|1zCWo;%3t8~U?le@??OOXxtuG5hzp zzpelAiE0M+Q7Et3u%-ee+lN-m4CVe*+AW%2Op+We6O!e)%&56zlD) z_DiyiIn+@@mL^*uI291>DBzx>H@4!K)6+8KRGZQf8Z&p~6OD zFFlgaTV;;uyO~@$@Z@7X=WmosN4VKtsY`R>oj}La?4N-)B$K56ptZKfUU>&Mc5-fw zGWq$XCO8s*JDB(3dLr_9c<~fY3cm|PsUM?+RO&06U zfYmEeVn2~GlGw6gj4_EcWvkJZTVPEhvYd<#vutDy{UFnsCKFWpbD}&-2l_G3a}VS2s$tPRq`}3)kAQl zVD$;NTb7Y3m&ih%$MgEf&K*)hY~_!{cse6@O`1W36xvzt4}#I?kJxg#qo#XV^7d_w z_a|?u-dZDu4>79@y$n(8y$ak>$$Z3_|FQG<=lsuM(A+SX{=YSMuDy2~e=-02Q`iUl z&4NuT_-@*dteCCtj3X^4D}9oC4eW?U+Ydzq#ly7mSiax$|A~vYmPJmY<>G^6Sf%3; zcRjLC-69WbTcOnHYdn^S@0r%$*Qo~j^l{vNNJMP8O+B>gY*U(^9AQEub-W|!geQBS zwf$g?436jNW_`^j4;L$SRqf>eMPdAjFG{|ss261@P1d7Saijf7+*4TmKG>PD=^*F+ zN07>RkYmz$r*Md|`qU~u4j|X)V(7IO3Fkn7H!7O$G4zHtz3*P#UBw*F1#7s+5t|f|ar}#Rf8wu+ zA1na60T%x8ARl~w(L)D&~>5qPKZ9h zbF|moV~M_LK2p!tI1)>t>FA_-Nt z%M2!^(MU;}Vl^H5%DIWT0ewHsZv8KAdd}x3b1`&^1DIg^`Y5{CG57xDDV|qgzd2k$ z;|tC7{u2O~m~4lqW-dYTnh`hq5SzM0jD>ts8~jyl8eB43yOCw&M+&4;@9!%`%%~n1 zm)ToX&4dhe36ALhCUS8{P_;V?>bc^1~qhog&ys<&nad$xL| zZSm83N@R-MG0|am(qE+FFP_wU6TSld!Nc? z5jSVEm1vXOrotVoY-ll=9l0s(z(?ySfh12`@s^;iDv@KI5W)*rCj%>mB5ce7T4aOw zK~qmW0V`cL6(CR36&yzufMITGGScq8L(3dGt0egEi6$$CHn_@hO96}6XzXEboP0GH zVd54A&ru{h_!ET}{Nm(`&6^ntuBs*eUU3mLQd+3Ct|wa2l!Iw&cz6aGpJmhKjwhgQ za;5h}d_eIcol{^s+68{PC_8yMK!%5FqV2V_NWcEDV%)@g4Wx{zZJ_Z9{xYfjOUA6)7D@aQ@UJ`oAz!f`-r?*L<=VxZ&8*&li z2ujtkYH^g3Q*_#Blk#-tsse@PxojB<9ktWn?`;zY=p-a+HZFVc?#Txf%W!=X(Mdx6 z1TkiWhOj+WXzR)KrnD)m)6k;$WE)WzGRBIg%t!hy=&S(m{-1k{S+@?YyO1j!lrg#9!~rIck9Bd z7ts%CIIPd)bNJr^6KjBc*U`_f*t9=V^xNCAkQC3sylcOTm2fdj07sxYj#0+2c~vIz zyxM_!eeRI#g2|B5aMd8$jbtzVd#9~*vuV(7nC#c|*Nk~(u&4}=)N1NzD1zCD{teO3 z%uqbD3H@8$S4UVI&#wLP4aX;D!?hbGj`yaQt9L{{M>W2|4lu|xt^cR>pA(Py(m&Yi z589&p2ZRMNhxdc4Uy=8R|GApxWwKPSM)A{#W)N zRB_KAtoobGyrEYJg0`8k!=q8CRg>A;g;uOAlS~!3U=$OWv2|P;7FfdYz5CxxuJ5WN z>xhZ!-PZkS=>Z3-i&4n2FECr{5Zg%K{^-vXQWyK71CX}*X@;cgi=9!Q+4nhSp@$0c za<-p}$LSY6@?;at^mjis zkq>`%t=k*1h}Kc^-4+_pIDdRu7ih#9pV68(+Prh8XMI!$PmuOzf8mrC37j}1ypn@O z2BA2rr^~cPqnGCV7?{`8g?UD1cV8*<%6s=$6qBMv2V;E*V&H!xA|eDi0@yu;S|OclK*% zki98eD(i$1{YHcZO}$EKKK9}N=^c2_qMSRc?zrjYZ-CL)Rvq*Lx3MoT$Y4LJHA@^f zem6!urFQmZNhyn<+8+AZIWgS0Xd_;t^jAVl1C(ndniL+^4$J)&_VK<{Sm&=im;R9_ zq473`PrGNyf8>dxeY7$qGcP@1zn7hHw&M_U`NnBu{`KLvH?NEgP)9n4vsU6>3k{mn zd#XKDAh7Zx1htK5)rK+HGj?8i8pEodO)oF0v(6`P|LGR8-B*-X3*atQ&#I%Mjo8>! zK6|9x#J5mZ(#bY#p&9S(f+Y;N;o@2Kz_kWHMjxT?LL`@}MnNl*S->d^W zIx?-rN3noif>m=uc+c7^J&~DA<#R>ruLF7%62{gI`>HOrHc7~D(jUHyKNIzE+EkI|Mh*hlg&zxM);gHZ*#__e%q;nNES81+Ys%RTerHHMvaU^?H_(cy zigA-ss^*1v8!ZSDdhVz~bGG=RrP)k|v^46cbq?Ev`t_(Sek5&*N6HM+nV-yt37wMS zV_(5w)-Pn3JsEYz)o9)IK&qHLKh&uO?>&KbG%AaJ5g!T3r;vOhr`SS##ZV*`#D)t; zgKwUUCQb7ZUkg=9kN-fXhwvIV7!3{ZngB_2FW#r)bEpX!j$ISFs(FCoA_!@7s^aU7G?bLjAO=I&@JL%3(&0bEYjA+%e3yflBaddb z1ureZJdLrHG_PL$!{&k2aW&Q=#ZQSev6*np zo6+;BU$XrQ>atc&IQvko?SD!98$gnkbSwHBp#4|t`l;=`e5uGcs1r}WCk&%>hE)Fh z{tQ2mv=;R6gz`rpDGgkJakSto%QBi;EIU@&o{9*n8H9O^!h$)&EFx7}G8uAFS6+m$ ziLRyTP2Q>xPk-$VSQ5l{+Mwd7lC(6bxMu;~xkk1wW;jEzJ*q!lCH=y6TZjBRBMz_X zwS>_OaQ*X6+{ZRnRdKDO9kmZp<|E-&&;0*2&p}e@gorX3?rV+uhf@PZTDQY~pJhvI zI4~uFZy~aDkaP6&Q}{wLZm<|vhf`qYi<)xf%Ti<(pcP(4EAB+pyp1x_HT)HGNGp7} zgRvZeli7dn?hj6^39Co$Aphj_|MyKKqGc|qz`wjwIR^@g zHfCoT1~Qr?2tp$|^R&726~ojGey+Ha+9SPjZ+nxN1qgg+{5m0r=*s7&b|s5iolurZ z>VvHt$VUot`bvLbE&a{05qwJ z$eZ3);xxy)mY>#3Fz}tBh1yyc!D;$X$xM5PRL2!R5-;v(_%TpU&eRbL5DzDo9!cB{ z8b>}pmts?+;hPrMeDjWwtZ7I4dqHFL5^gMJd&RR_!s2B5gjD3UY5Ob-iEPm|ELidU zrue%MtRU=tg0}m@fS0+$t9KqmlIMs&7HW*Z2CHn4T5LZhe$4)0$qe4UXh&jDHe2Y} z(2{@^QY3VbCnNi~{24GI+y-x*+B>r3EyIq0=%Nfb8&Fkj`1T&|OQ|QEWh>nX;%t1H zT9ssCn$2d;TB2(v+ZTAHY`#w9BiSm_{zC-k3+)-orkE&8TdyjYV?9lV{Ou!AHiiv; z4t|tGyDuKTzl=rW@b{dYv<^S(r3t22IN%ik6uXo_zqW=L)jr3})hP-yw$RONULB|= zF%If_+9>+)GTz-(DqBw*n|w=HcrQeJadsYUmCUNma7~yqNs8?HO@|p|+dM&OB~VKj zXc8cgNavx9>tmEJP_8b_SnIzC_0JL&WjPVy+aL*=BlLB>6W)m4!fjVQW}zHw4a<;K zzm2Y76Wke+ytd0j%W^}9^HGjVX_Cv#laL8VoVUP0a5)XbZI!{kzlM5xB^kHlc`vZ5 z9Yco1ulmox7b&&|-lca#!*B-a*L7MgCk9RBWL2YRW8o>WyF>9~6ijlqXf`EV0^cU( z2C=So)lIewm|uwT_orar13x*mh>Z#bl;KTmX-fNbn|&5gBVFD2>QcLNfwIoBq8q4f zEk#UiUH~hY1dH?E1*1%4qM~=YV2};Y0BQY5I8g#|3Y{bf;qa24{H-l29u*TbWo+z5 zhqu~Nax!Q;sci_wGbbGB&L&?uDjdAPK_HGdf>uo!a+s_nfE~s)yP3-3m_p=Iz7))d zVKSk-xpA#E8gjYKx~ZVoVE>}XrVn5jtYCzPZY>onp{NIteGCg=!5%W54%=YJiOsFp z_rvTM!8ido%d5*1Rvp&zr=`*)Wu?VJW{{P+f?Z)t&J(PfMri(tB#_QS8tnU3UV08X z(B!7ThL!`1-yRp^F?dzD!(ZEq`1#axMB?^nqbGrEW=H`X$T$rXyRZ_Re>?pPPT_1` z@P8sE@;?(l`QPZfT3A1ozKOx~z~u48-4t3N9}L#bUuJjz24MY1T2^FnXaC#2oLjs9 z^eJww%4ud3hDSni6uGM-P1MPAHYcahp6Afu zjh3u(E-{=DoHNnduVoGvKGYN{PAw&J6F{;Npge(?V=BuV2)3U(a2nnc-OtKdacE*^I7jSuz%*CQZv5+qXxuXGyjrh>U0oovz*@>0U#zF6i zn8wgtUTWo8tJSjD#EIVOZj?YQ-FM|P4p$_2FfoN)WM^sb(xNS{@DmmYMz(WESFB7lNh4}hgz#%!xtTD+5<3jR z96$X@Y=))f=1S30Ia-@x;bUMkm{j8wHzP7(Gi3+RhqzAeaH?{=q~#kXd29cI6%hh2 z7fT%1Mq3SuLE0h#sy-CNS6pm^sJ`^baeZHE*I9jo1}i9`RYcUmndiI^UxkQ&yKbtW z8(K<70yJHlGwpj8pKTHNnSd%JHChta{H(<=#Rl{(ei>P^T9SHK>8xzdnWGkngl$0z z!i6(`H3{?7eD8~B5;5SD&foT}apI6>%TFvk6ROHW!*$$w+^7T3c|*7ulsR;0w9cpH zHW9Vx5Z{g&A;fF9zQb&=Fmk&uSCv+^RKrSdI~h_k|3D_8@am}fU*q8CuJk(lcjvm9 z>VwF^xR51`ckGKcHod2Oo8%Zxw<9=&?|?>l;HHI}L^e44*O8kA<}+eut&r`c0OAkZ zVOJ#Z#tUf#&Glzc9r7fP2&1!63{%8Xa;@1ez4U3~4u@_KXibf|j z>I&S6qqlT_j{ZkcsM6p^?{n)T_tANX43UqsCuqux(pI#(zbeRqaEzGKyS%0wU?`Chy$){0r`o}mB(>I6bHRMNCsHS)j8}T^CeI>G3i<31=lv7RH3_qz=KgSVe*<_T zNNlJtPRh>~q(2_$gO#VU;JMwV3`k6l_3(LoS7>M>jB(%eGRE)0Gpm2S&zk&7U%%{uv=nMb#zm=Lf3LUPZGj&D9_Or}6(SgZ@9s#QBZ;s;UG^ zKa|^3D9!Tqg!NREkcX0eORt^31n_Q*rsm^EP%f}Wq0ivHkpsop#nZ3O=4Bxgi}Y%H zr{FZon^rSJ#uK?mbJFLBDl)>5ne1DrCbP+2lyIdMvP9+>Tvlf+)bML&GntXv1$Q4%7Wv9tAgs^h(;SVAx{d93oG0MVfO zzIc(loAnOygOFAimGRQ-yyV4l*R}1AXjFKH3G%JKR+c6Wrb#Z7XRU7)E|cn^kxl>G z?gdRt6RkWiozoFk3WtEZv}Z>Hz0xM0_>hTPI-nxfIR472pvy^a^#rw;K9>`_(2;$R zz1ye(q*(D~(7Vk(K!s|(=zW>)+HFF4Zq2?&oVoXIkRa7pvf0{L=nTt3LwPOz}6iko{>%?2ibA48wmM&9V1<3KtdcY?MIDGRp+VlWj+~pPB?PNTr&j=rF_| znZEVcBh!pG+R@3jLZ!&3nJG8E_Rf-qfEu$b8S<6_mCDtX5dxO|a1GmiSCcH?9{P?Lxl#lo=V7pC+11H-p; z9)4$j8ThVAA?`B_xUP6{X$Z~O8%7WTc!GeAS{vl@MW!fU0!M=~ej*0i9CNLJ+ZxH5 zS`(0|EoLr|D?;kmokC`SzChE``69{3nMy!BQL!>3b|!$NH{E~`%Aq^hWoKhQn!$LJ z$F(k-49*iN=x+D5je*~(Z{GaM;7AUiOS%_jM$-3NKP*PtEeYDT8*CpxAL*XTQ}MpM#AXMGFg= zg=Gt0Kkuv3s>oV&Y_g6IHtVU6Xa8qtgo4?;7%6!xp4 zihRB%`r7Z&q*dBWwQGyM_#2>UxaGDM}ee(*4UvlqCkd< zQ!QJ_>cjxaZ52P~4QLjU0l=eK-sv^yny-~PE7uk*ZjQ3TlN%)nbY0J2S<~|4+MPDt zh-+P08k6XBs+}C#VUZ$3Xg}jAGSC%9S<#L;lT<$-vrTTv?+`BOl6`P+{wUB{ybq3l zeH`8JbwL|L>d84seU%xmRJzhS`^IR>x+Sou>uCvphRlKne=GvKz2;V}oX&NRUqfqI zry2h=iN85>gckB{y7!g(#$y* zt(kVondqcO*H-N_z~$IPQXgais}a1S1jiLdm&%{mJAodsv(bz;mc~Yh2J_wRCKJ$k z@@R)t8ZE;$DA8S*@t|xx7aeJukq=CFPs_8ZVg9KL4uV4?C6uNSG_dXHatig?F+xrs zYVj;exK#B(3M6g(SbIkAdb7_>zgLnVAprGwlpC@WX>6VO_j$D@h{h3j!g1m0$a2zR zL&T)HDH#>E*B?nAE7Xkh$Q^ z3woH%&4}UA{gx+1PLKt2YlSx`1g4neMyTQE%U66FLQXoZU?n?qovEu)**Pr5wZWet zXjrt`_bGTC1CbBT#k^2-j*yX4>m(f6DbbP2j&!fE%dH7xM4YCe*EZ_UEk`iBARMTx zKja%g7N|_1M?_`i6?(tOdn4}pMN+Lm*00|iqiLen45P#@EryeHt#yE&hP1lmkT5Z` z#33$(A(z8K<}L9O+Hj0}{6xhA)K`{OF@)bGq=q?kMt(@4f~n+vVWx*zOw_CB>=#KB zklr&-Z#)eSfF z2osC@fcg02S&I|3&i*v2(tG-!bj-UM_n;Nh-l(;sam<(6{x|16GD+EZS9=O>ZjOdE zOgR3@YAlY@{VS&d)NOT{v^+h1NN3dWOlx&mcUCx)fz_2XnM1z;l|!)^VBfNfkRz>+P(YV$!^tZKR85^ z`J2D^^BdJ&O^D36hy%z!C7#q_Ih>~JI@-Iqt%JB^mB_U$^594hKx}r-I=mnO<}?m8 zj0?vl1CV0DXEU%LXv0^8C`VqFMv*F`k?l7QrO^4~j4F?u@G@0h31NRID7q!E<21b8ptz|Yn$w#hVSTKrCF(68KmCKsKy-Yya9KO&m-qq z9(-bAL&10Hy^=+-G}p9W{!GMf`;-1Hc+`S|%@}=^x5A;Oktb~;Ec*?5YcYbrub8cp z(mOMcTI|%=@*5^0q@{Lv$UWFX*n(T1n@x*E45Z(smkN=t$9@f4UnI*?Q zQ^U|_UbQSxZG_dgZ+BIO0C~z0na}bNebq;+Sp=^1RrhBlF%~WEx|g)E94>H?fg9rN zT$uJfox9k6M}@2R#l^vY0mvx{Z~bbj)QlYF!N5MwxzfGd57L+h=6aHVO^55z|&p zZB%6SAFWOJr?=8!l3sfNu7!_R3IoSWa32E4&qKd2r%BFWBy8}cT(fS)Zpb%<%A@E) z_4CQShfq3(JL)V4pqr!58ys;m`xCfB4-AT0mJsJ5%VHL$nZj%^!M31SV`DhdoGGw5 z;615u9HhHzdL|RApF_lQYm}E_?!64?R)8YO^n-$zWmsW2s`_JI$~==8op7O`aVUUnXT|?%S%l z6paQ^33}8Xd&$otBGU}6OOd4(C62Gv3l>dL)n0lHl__WuQd?J`qaao}5p6SPS)39U z7nsQ{xV|-t1$I#)@vJvsiTDS9{1>kM(sU!)|AOGB1k4r_+mhmuqShtD1JjW~XBEE2 z+Y`h%2D%RI;XVn%GlNfLf%8QMVyT-?bo()(A*#oO}p`3}%m@^D#d{V(;5gZmSkL5&tEe znWTW1jyG2EO*|u(>{`k~0IocevX^O192Ra*^Km&>Jg!>lq_~xS$LTFL_hDx_8__2v z0Q})p0b%JpTEs#P|0{J?)_%POilh;UEqpnF2?hocSS7N6>Vj4)KP?5@ukWO|6AR)D zg0t!8Hd+9teC2wTFg0j&3((ZjK`Li0H!dz<#UcQ6jIb%QrxO!`I4an25!~MS>v~rS zR{ModNC11o5AdQ=03I0r$z(~=WD*#$nuH@;;9YyGI2O!hu->|u3$<{`nJ-We8tarO z?MQXe=&~gpb=BTk)y^~3VI$n#jj_RorcS~^$JN}P8M$*(3r!|c6EoHanXa=fgv044 z4P@1ZZEFS1;u=?rmZzx_ji$FA*RP~bH}c%YO&V)9W!;bXhJ60_ip-+4uJ2}koW~u< z!$}aRPA#BQaLu*x1VZlyTiRj(-+ND#IZzBDYYWwGvXC1>cpKaW$>~AoNJsBwk@-AXK{TP7VRPr5G%SA)i>{C*Cdx*Luv&(x?Gt^8BBVgy+7cMEC0wtDM3rMu* zm?O)z@HwCPPO1zFPc;5nS|USPW1Z=zOuu5~ips-ecw9#Jh!>&x$*~(cd&A^5^NDA+ zL0LmM8<`zJ=&*9gCsq1H3SI_M`^KO=xeyBi;o6K_&1nC-*{57*Y4-nQ55VH1)(e)Bbo92>+BP?{i4Q6Jw;V55>r$zv}f zA5RR%q@d%fd26^Z$*uwP8zdY+;;e>Wpn4V4CJ_Bm`%YV&7lnycwzSDOb1@+9j@DxB z%PvrF#mLbFk7+qH1)d07PWbIvb{|q1U{tw}8{0ua%8*=TBSWO>Ek~K~nMp;|X8e{s z9Mz_p^)aU$Cn}1M12?Iwd~4ZCUM!GYKO>PVd(awr245X+S%}mHQ8UV(~`JNG6 zdQJi^p;68$4^%tGlJ9WSI33;RKFJ2@U9Wm08^f91zkV0_R#>Wyn4pBQdQ}21!BHfI z5iZp-Lt#2RJ#a_yC{W>?$j}94^9j$YANYh=WZ?nb*_Z{P7 z#vnyv|BR*HdiJgN^)sHbymA2!C9Bgr-CPG;mDthzTlG;IqmLfVB*aPxGOXun=_>E2 zz3UXejL;eyYox!0gl@X#oa_?qDuh8Gko*)6bu3 zrAl-hwy@-j;hh2wL|Qsvv?r2`VYjYuIaZm-QhPO%aO0v@B(Xz#uv-+Ob-^2@jq}~E zJFJgv+6}*g+puWvCA)7+LJ!K<(t@!TIfSpvJKzdhI?;&Uz)=y>+KIO3Y0h#LSF}J( zgf6SOr@)T3Tl=3;sk3MKc@Hzh3?+7|LxnwaTD`lQ-g@rY^17?903Y zN&F$-@0HWmThXfXbPH;k=7o=V z+M$5s>J+-!R7Hq@CKE)-RyR}6^=E>V=z3)!?&Z1vn2LTcJ45J|4s*R>g!vy;YEeAr z70KiHh{^@NM}K(<=(ZB{--^XIbkT~EWeUduDm5m-?X}6I0C;kmT+Avyj9hSd07$?H z(=X5u!Dt?OmqrS_4E6-*6P@dFgh1cggzV9G^HZ2KBQAO|H8zjbM4Vi_?j7%!|2Q)Lo9_}9bX1H>27-69pOh~H1ZklR^|NhD&Hz-aHwr1SvnF=R1;Q##NMDdZG` z**N>erugG+W8V>Dc{$w%MSNn_t5o{65>!+9@3 zYVt)>8k!wVE}=dNA7nyl&dX7bq*HJAcdI*fuoA1&B@HHaFoSX!Y7Yg5Difs!?^jc8GgTExbUX4aM8iTLDn)#6F-&iXz$zzytv?hT9dO zBWxlNgc`%y|e`rYpEhgIQS;pX%sco3l zpHjm|O8Dc~+mM!pCZ}l1$%?5h7{u#k*u?m&UK5K?XL^Nc#nWR=hnD;`6f8(5kP*>l zwIuAxvZRv6u`LWIDycc)f?gXxwsJ8O;IhXE5(uB6jicmP-WxO%iXhDyS;_m=P8_>( zTT>yW>mQ=_5kWVNY?wG{Jur?>3d$e7%B>1c`4oM)jfwbS>=O+Z z8euHQ{sZ-TA}iB1U387bu}DH9iJtOHXJICTg<5DYHVxal)kjV zCv+2ruJKW6QCSJ|Q%p0X&X`dtoIyuB>A=w`{%XtkJpiJVouh-M!8onC^~!m9&YXQj z%L{^5&dSKF@$e%DtGI%A-pG7-(|!T-A3Vy+Hgbut5}E}HadKc|>g6%+6 zFkll&?M>~Bg@6e^B`Zxi>&QkYN=}m2f}|kL89py3j~`y)jPdiKoS(EM{5V8e&4C`5 z(O1PF^j{AD|L$C20W9Vxi0yRVuaLXdBLVY}4$3Edqrf+yQ>#vY-5C6MXbCqvBfb{n zYcaaLD^UIs;lJ%G*|U=UMuCJkT`jj9GdUAz%a8l+v5ZH&1JNcy4O1q7EFC z*UoLSJ$c-_kt~pW*7A00C+vMF8NKKOgwK$e8OuDCchPmjygDleo%d|RYy!~#yXA6a*@w&ccX(sv*V~6Pq_=_N(UR|t3G}9oGt-2Iig2VMYq8H zh)dLRC@5RXsESGJ`qY#nl0JC*#L+PV^Y+#x`(EYjLwWGEyCU8DFQIkI?CmC%Xy5OT$qnw-m5W|!CZkQ14yqV z1j0gLC4zAzOn`5EP)(p0Re7&vcOkU4nhL;jry2q950=(hiG>Pt&)+#?N|^;AN2xrB$ph? zeS`DNy{g-7!`tv^N=V{AIgUPZ73C}gX0cuAZ7}ApIx2^U@v8Q+Cc(#2I0^S|&RfR< zWiT@BjyMYze(p{dX9#%ZXG%(+0CLsH5_Akr24_p!Cfc}m#|+dqTeQ{JoV=FO+IiZG zC_cP!isd!rh}(f*0>RrLo!NF(+`mOlT_c#QhU++sr*e@U&rjY{iCIGWp)+X25-!XO zx;Vn5ehPdWCbg|@)t&bM9O(b4)RW2JWF6zlPwjP-g+XtEwoc2#TihHRH@$X@VDs|? z(jlK6Y>#ZuT+}ah|2Bg}`c#|TsP?D2E8W&SX{4R?+Yi}q$Ro+^bXDn^(uBkxY6A7& zO`%b=MZ7nQUy6;(dm-2D^|cNFa@2T4U%5J|wMj6$(gq{1O~gSszauNAz99#k=!J=> z`=;)wP>y0--!L?YHA*I`HNLayydnGz&~=8#gZj51+^d~#%>PkudNP`UFwsfHL89w&uz z;75Gl2m6Ou@vZV13e7H!kE?=-0?jQ>f;?Oa-cKaxuvs6phWpV3` zmzJ`sI=43bW)Oa| z+LGMPr_t`ywNDVKZis@neQ_cFychgtBD)bMpT8`Lr1lGfc2XoO%st@>i5yX@(2Yva zsh(b%28EP^sj?gMFjNE5_69dTr=9mU(m7~{gu&Sfs)#JleZ0J~>icR5N?TYkj;4(2zVIQZ#Jhl(sY+fmd&Zg6l4SCiXbZ8&>T-4_ zh^n^HWe@5y&$!XUDXg6{jZ=No85F)F{llCgn^RnwSsU79F`fW>7=p9X( zxvFCwKwjE(4+_Q1y=@d9&WiQmFx={kTJ$i@w^hM&aZ4ila=Xoj0A^i+A39Q^S-KA; z1LJDk{Aw)7r%i1v=xBJk$$Dj8ypoo|d1C|ykBr3O0?A?=1p+h|Vk@WwJFg4pp;$TY zovDQTjI!3sfvvYt2UU!X7^%ilP)G8Cn$qZivbF}Je2OB*QrD4V?~;S&`oZQdD5o`= zn~<(a2Q0&96Kf`Y6DL~#8xVA}h#_**X467HHy1?UAeP1n|GD0LGd4{}H5 z~tn`KE(Lx%23gxB!L#VgfhOUKBEzsQVVm+GYnc=L(DSOX(sYy4eX9ldS7>LPA}k- zA=!AA`t~GVl{@R$p=F0r^Fs-($R@SS?c#-}muu47#@H(HoFewUj}(zetIkb0ov-5; z2Kj6c9RpTGMnr)ExhXs2n9kQo>e9MWFB;40B&fOHa4~V0Y)d7X=E`nAG2LIlii7jd z{Xrd$IM`D8I+3W&=#G2nDM64SCwZsb0jsN-;fxOwU&Kh6LZm)ABGyv=>sEHh=FnpWVVHEhPSWl~BP{K>%zX(8Nj&&Z^TBL83 ze0jtZ-E^pV{0f%U_8DO3uJ;SHNi2eFCnnHCWCJ2=VT|sOaJc2h<;S)0!ib)`zOg63 z?Tc%{i1lY|{qU|rI-SqC`c=V5Ntmn&8K4W{#*DUB5zdt z`EnouS50~kE~qL^c`WrxrnpKKjZ-$66NHN@^$7{K&m>*MyNWvDVdTA2sNl)@g7*;B z>ROLh3%s9=W(t7`JxToCe%IKqw87pp>tz?abxfQ4BX{aNEsTQ#@#8?o zq^B6+(F9d{dTU;1uGzLwr(dZ>=uEZPGQ}P;{farRXFc;zcOBucX3sxVtvH=OjxkPyi3Lu zQ}9!~rtUxsOG!1=`yqQW@(oKf2hYrvcH)(I?dAOP$o2{_YzngS=UHFVl~C4sJ?{D>v18a?dyXsX*vqOSh-*jacaZ4szdOb=|aN7R-rAh~B zDXS(%S?(<~12-S5B_{t59O^kO^Ieanv81_@^QOgXMn{XK1T_g_%J4;YsS2;GD96Bk z$!N}h<4jwA37FQG;rszYqNQZ$t{XIjH>gc!K*}N3tXSN`%NXP`A}C7yZXe9I(0aOK zT24x92&Wpo*87E}e?*1s9}`gwIkrC)vfF>9DBRhJhRk95>vPltLVT(|H=kvVTIp{S9n&T!f1 zTBRAgjH1>RIAWcn(*c_APLVD^M-4r$mt>_z=H^pi|F%hxF_E+ z2TzeWLrmo9GmR)^a*ZJBD`zGq{HC1g*tu6?ku^U2IXOJ*T_*PHEy#p{^hOOB10UIc zvItU~@4fJ}E&lavLWoGr4q^OS)v5LYgVKtzFFwGhH8l4`oWO~LN+}+SyY9rGRVD|< zFt_OmD2guGwmB_T?Sb90 z?pEv$G+Ja?4l}IcV!w0|NUIaaPNWj@A-udGmEe+5L-DrzhHU_^kh0c1onDsB{h-Th*H7b0Umevv{puE^Iol-{XBI`wii@Xcl zPw=zs*LJ$$(U9Z!3k~Ma7K2KHOaAn!7c!70#_Y(Qr4-co{JO#_)+i+C74Z+P4rwKd z@_Pr_GI|zQSr-ex59T1eQGTPsI-Splmpdp8>4Xw!8I)HfkON0Faz!8N2Lp82&>-;G zRN24B?Ry=44&B85Ug6xr*H!j1xHV~5 z?p9S*SpI8Gf{P)OTCSMD2$VD=`n+7K&tgx@YxO+i9iVYwA0!*wyd6H>_hku(?@ogXMaFLhmmMdh#Dw;K>HV;ptq ziOuGWro6N9#>#Mov_@N4BIdXp&LYO?OQf?ZrviC9Z<=X$n z-do32vHXAhhYmqnx)0sm-JPN!A|=ud0@Bjm(wzcIm!!0GD{4L>Q?Qpi0wu=0}@M@6hFZq3Pxw*Vzrw zP;$>y4(}l|CSk#@-Ou)3b%;F~Yd&RQL+|sJEkQ_$rNQDy#vZT3_DlX6Jhr1|8e`^r z)2qp_F?!#4OWIUP4^H+zO%5ieBQkBOxV!DxK_M(IY_UQl-7WE&j4~6lV6%_fH^w~q z-oEf)%QAWv{C;CYNWVxVHYCt%o=yXt`Vb41<+HyCqv*U&uhCN(8&8l%b%1T}2y?(A zn=db|BG_qnMAe|&O)_AHa>w#szcsNZ?IaiJP5%;%agc{6%*nM|T+`jGtP}2FBBKVFAg9!TDYx9p5c@!aHm0Tsw4qhZ50(^u&951IHADcOAOX zCinWuW^0g{w)#fEE9$XJ${fpBdW8Lc`nE~N-iXgUnlTdU+(vD`~- zCYlgQ_E{hj991b>*ZT7nW1aYxK|!^ObeTjZuF3E~q(QVX&2SJ@W{s^ScHh;#2W?uWns#RLNRO(k%# z2hg`Xj=- zp4~6RF`X5`Oy;tA)c`V#I$l$ z&|Zl=9xv8(5sZCIEjpYYG<#BS!dGQ4*kXY30gic#}3bSThK-6p^c2GUlFVeB4CKg8bJl4OrGb;`atDBeW)2n*~)i55-uavEW=2mOi}&nAr);7)m0T4? z!HuhZ(;gfP7)s{08N?1+6sFjmNHiP@q*3cABRhk84U2h*A)qffjE3DDX<8;SnAU`A z@+wx=KHcJhr117dZ*-s8!$3<9Ryes@Q3aOD7tsssZj6E}5OC;O_;ZcXDCE1<%C@_a ztk{sK#iOA3((WuRoL|{vQV#F??2)3n_uOHwRM`B6wU)oA(vovv$3ryND%bFABGrR%0CIld~1JmK_B!^28E(&Gg+xinTwFe%jcv zJ-bYQ<6;JCO)CHn3m>~GZEpXRdO0tddq=?0>cV~+mkAE^H&wiek8rEimW)>Yc3b{o z4gz0fNP$2jB&s3NKkGG9AaYAF%4%D0^1S;#xAo%GIf`A}XLkPk1VY_nZ#|#rN$j z3)H@!85$T@HF$U}+PY>Zb0i7BL5}GS1^FOYQt$xR*~}GLuWDPUl*Q9?2}5-eHuuw- z)(9*_$+FaU#5gB%v9{nmLqQbX)`dz!^D}Y>udqDs5i+QF1kHHB?&-Ir^&PZND8Q#B z)VoU<(HxM&F!c&}T+l29#AeZKDPlZG8XmSVW=L;(6yH%&;$GIHM*Rd_PZj;J(9M)j zxG#x?*UY_~9LB5D?E8vxQP|%Tld-nk!g+`X^YktaZ1(FJE!(435AXshlbcqW@=^cI zmd?wTO(p1}w~-)i_gi2!EW(ah;f>v~UbhOVxJzf_|B#8WTSIDo5ZNXb88!hmNmS~C zs^}fQvOSZkX6V`IePyY35BaQ@m`h|<;cTTVDZB(jBlj@2kxf4u<=yc(Lixk?{1ka* zGKuc{BnSx#0t5+y0)arNQ8M8FP5?!}&CV6059HKwEKKFkOINpPXV+-nGEry3?*4NI9e0zg#eBk z`=5#?dDjg>H(ne5uk;^ul=Sxhw59*nUK;w3mXv2LFaiGlPXf}}6Xqv>LIwU5|6LXT z!Y1Oq;rX-cf6(H(f5d+){@uT@x%Z!u=}7g8ep@flQmL}2Uz6L;O34}iw(MJi`cV4c z<^p9E7_Z5}-IooF>l$(CG-`8TwP($6+i!D%>3^=Zf zd1eNsL7C^a2I|A4ga-@1BLAbGMM|#8t0rFCm*fb6S`%TfoutshcX#pU9{q|O{vGtc ze;;4<#0t%29dX^@lyeb43x6B_`T5NjRlgXQlP^%jf6Kh6E*L2IPvJ`QH7c%){yE{_ zjtl_)H$5S3^xoW{>b==@Py9qqi)ee&d3p5>Dkvs{tyunS}Qw!FSuK#V#pEdukYU!^a z2ngVp`&-vlUpwc2U-d3-RLb8BYoMm{jl)%=f7IMPbshgrg!=Cqb)ARXKJOPDTToRIYJox2hB3z)$X6jqS>X( zp=acVznN_=vnJnh83LxU^1#QLW*Kla@OQlsrSwo5`iJK893V5U`^@AY!aJ}LU?U0* zd_6%2BJfu|h2FuRT$U(6YkN0QrYEuF1fP|DTez&dF!m z&cmgjugO5-ugRRofp4x${UY)X{2VAN3Jm}OheW}X{0;fW>SIZsGXZhkz}{@RxyQ*c zP~>;v9i=0Xb?yy-86gafdSQ8``8}|BrCFa^bPnT+tpDEJ<2&g1k6iEWpK5x?;u?iz0)!4gAV?y6YLiT!vS-b| z;)=y96g{*26*-{_Aoo~Q|3pT8Z|MnY1ne)uJ20M17ry%E>$)P}#Rjt*4?~Iha+lS! zMEpbst{?s5`!KE>?0iL&m_Z=GQGe$Z(yQ%Y2|!*4 z$nHr$lT$g*$Phn~8)fL9D?(EOhgN_o72<3lp2@fxC1>$VuTXXfWF&k5CWvx?3~Un3 z-SI7|vd;{FAPo+!IwL~{o-YC^@34APRl$*GGYB9X`25o#sqg+l?*6Q+)N?^5F9yiQ zKqD?W=px|2bMo2haS`6ZHYl8}Gr$<}6b7MRZ(Xi53j=0XnuSj6x`7@%(@b`z+3^P% zpmAJ~5w6MLETF6+`1H&hB&gERmo;9I&la!91M2|xf=mhgw_N@Mx%h&7zEYi)dIzpO zBSU+_U+mQUd2RfOOmU6{$Q5zjBxf}Mq1y0LiOjj50S599%_V?5F%opSi+MM%`lf;@K5CROY-8iW`GP0FfI!M-k>a#c8F2} zWM9-ydTDt@7V5tCGuRFO73}(%SzI@m;euS7eNBE>^S$kx=JB-1!fcd2)yd8wiKE&Qj%er-*0Sj&P3Z^bAZU5W`Im| zopM3G>O%HnMDxio0r%8C)erX%ToOR;xaOQigh3#f?dz0xw_=4` zNRW))n;x}u9$8dRTI_$QtPJX*FM9_Qr}?l#AF#Y~^dHDF>I&5gs@EJKA{_^4zP5>a zC*VR_OYMyz=4@m1p=o2ps6j8<5WBBCofxB4ap3XivrX|8`NKQ#*?!rDW*KlLS@sXk zSvskY=vnS%xbOzB_~0T1%H<;Kve)U#fW<5FYi?XVsWY>3N zMUPx8GMp`5k;j~@>tfH+|0Nl){3!@ob^pA09={?lURnM}17ll{Cei&bAzD|h)$g*vm5zN;qzli(~$iVo$44D8~cz1@#4lIPhYNdhUoHXy!^$TEijf5`2f}n-LuOW|5GxVN@V>Xss{A@)z4j@ZccmER>sOZmRDqEf(-(D`O_^amsg#0TpeT+)HvAXl4b|E!h!_s` zHSOL`)ph)wT#W_Ad&^@1e{gz(-}dIi&C~lvk}v5D3F`8GfuNNbw}CZ|mr}i~z_Z+j(vr^KkgrkK3jZ28Cu8RJCOq4@fwGyT zM={&N|GeDwiw#4NcoY2jKG82$m48j1X=JFwMa}ZEBY{QY(gL%-#i~PXMD2{fH}}8Q z?Cr!Sh%vIE(d=nnGDJtPS8=)wTy`-~S7LbK&0ln33@t7=%Fv7z@PeENDbNO!a}h2{ zWkAZgBQ8Dz<-#m)Z#ZC$)(~VQ+VIOBX=j=)y;#EZ2EL60mcJmY?ec)5NX~PmqX52V zC)$}MbGfVxI5Fis{hXf)_N!7v5n_NsBnBtGruPJa(24ORhoUS_en+0c(F8}inVr#O zVz#=^&44&->d(9V=ebu|XO@2nztH>_o4=O2@X24(e@^)YIc5paeBoy)8*>@359VN= z##9s;V=CYog!6j;Or~Osp#QV%Uy#+{3a3+onzY{3;^R_X#OMQXW(`GoE*`P&I(WRxmfi*>c_f; zQSA0wbYWv1X^}e{=Y)H@f8JH;jxhlU7k(BgIPL~N#l<|+!^6!g15WDAK8v4|J&CPQ z>9zE72(nB3>F@6%ps`hnA!*1HrFUPDFRmK+c}G_b7s$F8&+_|wGT>+PMQ1c?bb##D z^n>h&@5Fqs0B3cm&%_2rhk%$%&07SDR%(BN@OR{ykD7n>^BMW)aN!M!-a)Eq>_&cX z9!}6b%n)3nGV$Sk;6!Fv0+5HP3aFHTr2rhgVtA$)3!Yc=s+x0jIMQoosAujmZM@u~ zOiHc<9JBMnPb3w^On)c3OQz)z9Hs3J4BsfRIuaRhNc-^_8Fodq_VT;#MHeQCgl?+r zQfH`l)zlnt5FoiWuu5gCil()n3H#Ns>w>RCIL`ude;3X*Cql$Th&&;3HRLuftDOWR zeVwwEA0!ejxJ&aJa`$h5DAmBhZQqoNv+B;taSjiy4ZedwQ^2ZO85g(cvm-UHp!Zr* zll$Tu`Cr$Su1D#b;3z29KP!H$r2+hAAHw_^9ljiHi~UjZ)Fs>#Ee7A!J2hWb6h2HM z5FR-A0aX82a(BiZpglO}1i;`rQ0&IZfS=BsJN;brkF0B(pCi8@gVBFB_+|V*CI4EC zfj%(vT{^n&&y&Jmzu>(6tL84pf-{}K#QBpefHFhJt{A0FFq3AkaXh zEFvm;HeQj;8Kpy;s3gKI%5z(~)}Fv+j_?qGnGouC&{Q1bC>e5xdtf?CD)DW|2o)o= z(b_$0)S74fjnVf^1DmX#i$WCY1CJ2$_#~V!7{oO1TGglXzIt|J<3t6|e3NT`L8%nZ zIXm!~*g+*~R~_4`xB+RjcIQil)fTRRWx0AmyX?CmVb0s>@|j4w8l)%d{ZSIt8>>q~ zTIhcF?c0W+S=$?}GuooQD9CMlYTled6h2_(5nOxL!JX^NiO}_%5>XGa;(e;i7^lfEUPzlk6P@hn<2eUq0HZE&1ATH0tu zkAIwji;nq?SG~eFpOdKg6Hs=vNR-wwU!2-?>qggqmSk}+ zl5NLSOaW96ccaRfHgwj7)jh4Qxn$VcM0**omVzKlg3qmg2c1x3`Z#EG8)^vbq5Z~> z;iXl4MzYBPcU*Q@vf{&6lL6=-;OfZJ)|E@zvouFTn{|?9(SXY(n`cWCBja4T{k&BW z4IZh*P0=96%YJ(C1eJ$n9)UQ9U3i%;!%~4*B7(xHQ*61CW9CB+Id$`6e7mQZ2GHrD z3hpN3(fNh&k6p0XT)eVc7OGN3eR=BellosOT22$!Y0goMr84Kz4L%~Sq~Qx6P7iG= zJ;<5GqVTR2FE8&gosqT=+&+q9)LrQv7RL|SN?tuW%`P3a6L?^f50}3Y^+2em9U-c~ zSQ>>CImS-XKnt5KKI)*ieT{Wn|E(?t8C6M?-}9DRQV^`T<4ALb8O+6j5bJXM25h=j z9G2=#RPwznl-qqK9FdZow~mSk*Ugi1`)^kGiokM`6J%OopbiC%hwD>Jwh_J`f_C&B zU*W^i(LQ)l1_Fx zCWk@B?ZuYV-bV9eGOm5~g80$3(owgQ+_1ccR0sBtI4DR*n3AMJU%h7&yBBRIk^RM) z>YyWF0y?kA+Hu%(Hdtt4kcy0d3sV-V7);jUup_4i_xAHTlabxvx;_ux=~tPpm0#9sx_tz z*n_%tBr2=CI}zb4u{nK+#M=}r`Jb0DEOSa^4jphAK?`*5$;8<;Mg~k$$-bgL4yxhv zNOOo-6|`Aj6KkG(K`s16N!>%_O<50#EsVv7qY}lmb;!7JhiT)7ieK>Y38=wnye9oz z4oB&c6hoO`z8v@Ael8*KdT_fSaQH-zs_f+R%@o)K&5uq?sy@>nNY(m`Wm=dtD35hB zlFi&-p2EUu&<}j2RC?^{UDv|WpOc&x zcH(o-U|&5^1<4uZOU)e@QG`x*fBJQa=Ur0#9>7gA6iK6H)kfK~!iB>{-5m?arclgz zorjrp)9&(T+A$#BM+ELDyUeRh`i6g#;K2vU*s#X2n}uFXc(1spqY0EhwP@TbJk0wP znb~O19@vS;N-?uG?Io#$Ri?M5*~oUMRYhP;=0Td!uopeenw-t6cLFP~W!CVlU28|+ zMA%-}D)m=n9=w>1>8gZNel}c;S5*u)7I#ox(M_Wipb3sdp~=ATNn09tUQ#lU;UCn@ zhp8ZPcaV+vc_f#G#VxDY_h!p+AD+eqxKKLivq-r^?>wtSVazk~6Kw&_Apv*QDGP|G zYh$*JcTvNjesn4TCuH`uBMvk6ZF|iqw?F4PuMVLC@kXd<-P7IjK<9auRk?@T0%TC* z(HIhn~V#v^pBD6@Z>RIKep zy3+c_s{4h0yhP@j)u;*sv$*U0gA5rs)D@+yVb8d2jDeGNNw;zS{^q?x`~;Tv)AEio zt*5z!>jTB8!cFOd2?cL^NC-$qg88>{P#uWch>BgT3dD*q+%;U}OgZgm2xRtO^1BTA zGu^)7{3rsY=um^4chmD}c0~+9zylrEgJM)TbJt9NQ1s;PSlzfunwlbpiY#fp9g#T` zUc(xH96{z26^t91&Ma$ppeiA52|W|~IMXq)llT}GgKIbw7M`w)C`~*hK4Mwcbq!>^ zt1;EXHlT%W2^HhI)Zwdw?dc+Sbd3FZHj2M9kNp>1Z9r$Q7z3{!;XdCfVANqr1s?X zvh+W^q*w8*Tsp04s)W4rZRSNq0fazi#(mrZR8vIl&4bK^n&VXa4G9Ro2*Q$`15z%V91?#@xg)K%K0o3c20Z_P=GTQ6+>TX~Reo{U9I!~1W8p@Vk~JHjSX zJeFjG{+qAxMdA`&1)OcEJz-dVww5%_RQtHYn!^@;P(J6>s;z5BtnYw_79*%XbjT!LR<;mK$t+YwB#$XO;gBa-SiKsTOC+F8QQ$`uw3taTs!45lg3O z>7Ix51|hjoj`^-KJ1G35e4!=NBw)!s~UL!%tfQgtKlu*Ef7R&pVSYRX$^ zG72Tzmg9%z9lTrmxa&#n+e}|d`1izRigULrwU|GM@wE}WPi*N3X;r@oSzw7XEZ+^o zLyopHS(H=cO#UtX^I1X!Rs16hoK$w|vuw)=I)KWSDMWYS9UBLE}yp^a(ErfD{kB(v89=y!D4e=(X zFXp7e3BNBI`W^Gz2X?W~Ri|`NquLZ{;*+as=W&(C84aVu;y%iIVxzv=@E9!up8v9{ zW3i@2Ur)1J8w{&xV=_0Dj(JN++Z6n+s3(7Z14#{+9rwnK*U6lyySyzX^qmb(IcNW_jps$hD3KnBQ32P3~-Oa0qVIbiDf+J+dcF<(h+j?(^K3dWOs$}ySqDy4U1WQ`H$r`5DJB!9bxAt{q7J_5FaXNYInRu9X+!P3g&Qr+x{+54$i`~kVFIc@^1j%nrM zbY=L^vDGu#dSwT%m#p7TpkP(-CBF2pPEsXD-eOpFdgr-fCHXCFU2)UdM8ypEK8pqI zFoz+2AvZ1;}V!V_SeG%DRPx&3S_t%OyyQ^5`Rp>GcXW>80wl>Xti z6{yKgYpBBxy3If{ml**23IxQBWuV{vpyc_YtOo`kJBBgz}2Zxq?zt5gmQTB_29E9I;X58vS0TEN~~++l56V! z*8`E}v}^H45lj@|XjGap!`4q9WKY^s zFm3&In_X|P5!k(Ak5@^!Wnb;Os+`0`!+1luLEpju(MpSVAT#isjZ@iXSlUtiXd$ss za4P)c*5$_;4BTJSI4TuLn_}0OPQ=^%;rg+H<_S;Ymbr483apq->~L5Mijs)dVJuyS*~RrsXR+aF=JC^0X943j z5BdcI6?;&K@>4siOA02Ss-hFV9KC6CqH6h(pGe@uO2&ZhG)d`zP@i4E-ag5;k0hZZ zx-ek_quU`pQCx{f=<$N2GEeZf!OKjAg6^?}my^*V#0I5do%wfpSI@$JEqD@VvtHO@{Yvdtx~#>Rbd#~&AH(qA6R~YP=tc_ z^lFe+Ed|HhtS_QVcf8+C`8G5mp9&n2E2F`sa(WSF=LB#oK94RT91fx^K$n;@dBui* zd#k7?*8+cC)lAP^^l|04&D>@PLNqsj=gOO;W*Z`WEJA!S;?vnk1a^4Ns!^eEU5_D&zJAp3yf3DGIho(BeOIY{YW5#Mo!T+U*c;`p+j5sEu?U z%N;-2hlVvYuufojGTF&PR^{WDGsvG(8rk2 z-SpQ2R53~(U^09t(-r6Juz+$T&H1#te@4{D%OKBeAx9$koA+2zo0};I&q>hCCRf=^ zV~jd8+G4aCbgjW{-BpNGJ_Xi&f)6Scn7j}WF4n^;Tu*Jr@Yc-v{fg};Z$_26`ag1#X?#g?sqh);1B{lgLYSQ>RYaxO-_ z^W<3QdxjmJbOVfaI~1;0d>KIC2b4_t^PQyW;ly%HvH{QY2R=(W!+Ac>&mNOXVOoZ+^UraZmv|P z0Y@k;L`Z|12B#Fqu{6m=(YKRe;cP~EKgPOwupsmm1V_j)KCy(&gsZI$c+8-;pa(z8$Z#Nxz zlQvz%Mo2w3s#?dthDk*=ZQKBCIi5F`aX&Z$?nf**!XKC11U1sh;v*IbWof>jg@efx zQN7sdae+NHd5vK$OEO=#szRNEw7nqfGFZ>e&&3l1feP_OX-NFR=1k1{Q0%(tP>uWB7w=TQ0Vp6nXcN>SN9Q1V-cs z-TcmxI`tiW@Qw_y4ja9)Y$qcls0{d4r4H3az^}W5uWY;<|daUvc-}# zPUmOL`^kz29p-VG+dqH>pQ7|hMiUbxmq7Tx^?_l;Fm2Hjrg zn04t$W8pR}P>U|Is1Cy2G(h)E2QdprYkhP7(GJ)JBtrtnnGk7tk; zn-O|0CeT?)k=iOx35RNvUN)L|#KHKY&%<+^W&_f@L)UU#*x`xBjf%lT< z9C3vQ7V8@JyzE_RSf%wwylybfgKymu6N|mPaJUWFIr)?-5yBQGeLCINrSYJp+0vtx zfVFE=$Y%C%VdAs!?0u7yrx2wZP4Dad^FD6CnMQIQh1WjOo~-CRl$y+NOz2Qw+N-?l zsa(U%KuwX2FlSI0#MC@1*FQ=QY01TvU;BW7mWxnzn-G{L77tz z3SCh)G~VGrnZ42J)G%5fjQxaScU9)TaUB=B2HGU=sv{mP90-DtZ#g-9b2@v#VM9wq zywaRfkD_3HRnJ?ySvL>33joi}z^I!g&8<<7WTivG){lbv3ieE`^4^ z*hf?o$g5OH3y-y8>JiU+ffEw~zOTa#bL3<-pCJfi!w<>V=MgUTb@xB{5P`==@b}$3 zA+AqZm48PJH$c?%aBKRpTewb|ZQ!sEq`UE({+Kz&laDjZLwyj;?lSx7r0M+qaP%kl zHNmKwj;VOVUlR!&9Man%GWKp;GQB;y{hCnA8jo01uo(j>)%>){-rF#`J8fp|a?QZH z{cIagYFjDm;5BUZX8qRMUSnGNOj4c)CYmN@hoHC>z?KL`!nD?#BH;Y0EWg^*$H*l{51V0*8giQnafR}a6Am_66j6)IJT zmHy%GrV>acDny9Ptz5iQh1S%RdZ=Y2XAMRz@{6f!M%RI$f&}-h`sn%V)bQf}kI&)x zUmUf|Tg@SY`Z^(zKtcIIZU}$)?rk;n>Zj()HX(uN*l}t-68cye&zrtN#;8Y& zvZ*1*zZy{pAi)yWsvwoYU8W|CYUyC~O-KP5h%px<)WCB`_3yC?FUoG=+b@_&Na}cz z?cZuc4`g9QbB*Bf!@wED8P}KO7Yci~>%Qb|f@U`7yfB{34>Re*>A#V5;>1cM6x+J@ zQt!dhc7aMb^ro&_+9I)K#W4;+V_p;@s&Hc?IVx%=8SK=%b#Y+~g06ep22ERvX@M{O zPMP7MZ1lTiW-M0aAn*7L(a@;rLAM4xoG312_eqWo&+;xGBm3fqr0`A@=K$v`+FrOz z6$Jw%>e~;I52F}-F{@ebHPwmIXM}ZT9g~6>o~I9xP~bNo5=Xez4Pn}b zIS@u+2(nkaOu*-0pj(FQycEq}ilN%(&eUoCO~~OmZ=_WmndbJh*Fp?ZViT|V(fo`J z(>et|n2BKaGSa2(FrK%QZm_XGa^nzX);VPaqTw`r3M_;px^U>;59BAeOzWKwwI{*EYAOr0cW*M@qKKFMTpSpY!K; zIxX_^e|#6f|6Jtv@oWZVi+}ZYvRdF;EtdF%If6aR+CRB7pgL_IhaAY)!7G89jGJ2i zctXhq8o0Y=qlLj6GjdoBXQY`Z{_Rn^mqq0SHnnP~A8WHB$&ZHp)B;zC=w_8*3ET;H zo=)uO!9A$qmn)3>4gv%kyNCx?ujgAjhCgt*!ScLe ztP+BF>qL!uPL#*#r6*q>4Hn95eD7ddpRZ0uU&IlcHa{Pyp9lEJVRIC$mE*m#aHrIw z5C%nPjCF5q2NQ8F*vM3qDURhe?G#O3S|v_B&s>n$qtsoqaMKS&qtM<(bINUB`-$5w z_WuSKkNsQxvGx|ef{L(eQJ4loU%2^(BjZM9gr=O;aZI*?D61k(FIKBDdpn;dmmBSH zO?7!7mf~qs|7||Ox{$YA6aKR1HLpyBT^$NO^H!{%jAxkSd>zj)i>`EG60$JuZ8=qG zv2kM(SM|NW-gh^pJT*xfcotnDMws1jdYOV*>tqd+sa}*$Y<*rVIjbF=0&xeT2QhASr=;^F%QZL0TnuDcgKS|mgIuFE4O2{e zRR-0HO=Mp@I$aKZsQt)&m(qgG^>%6lSFR@KY9&q*&+TshSNcU>ZjycU;%P$m-K@Ox z@$<6p!kH3pSG6lSaa0RgP>0bQym?iA^K{Jn1IOM+MIr%r{g8UznFX;&4Fw#X0-X8M zdn$s{_K>K%3A;fF@n7=6#A}n(5%ViWBn0)JB)L2ue8BAw|B_Sk>9nb?C-3O=Io1qL z!7W%8cYD-_*a_Qb-%@UF_`67=_`A_tNq(96$};jwjakZP6z`_(#^Iy)*pBqKI;!wS ziHY^A^UBvn*Vd$$3M%eEXj53nw%kFU&KMHu#=u73VsX>os@&41a+xg*0+MTTtZ%od z)ZM|W8S5yhe8FKOyKsl7W~>v46^3iOEKHm&&tU6??xiS2kn zVM7|H(kTM08pGZ*0h0(v|@alW(OtfS|b4U*Z}(>z235pNKv(yECAf zN3}bgWWJzA=g5AqPZLL`i`C$j?7TDveen<;1Kv{Z6Q2+had1cRM|ss!iGTzn3;4kb zhoWA_Q0h?pr4$xrR8$%0EV@uRN$T-@1aV84B0?Bg*cF60$uI0$%!ZjzAw|X%A;!}V z={>8XT^~YkZQt%bT|n}%FrN6rzPPll8h;R`sKmkc{sD#e3L{C4IAswPq7Sse`jz%X8@h zNhmdwO7Y@C*(62`i;Tr_jF( zDXkY{$XQ`1Dk|dLuGvYf$7AT!vSf*lFzj@UxyvP-@bIi~tw|kyWGHoQ=)L~8(Og!Vfr^30 zm0}}q6JvTVCs7T&u*__5WG3P{^ZbtAXWK&>`6r!JREY_H>K27@bX&+}4l7>$nkeWV zI(x}8HK}vtcq#}ih0Y_GMJoD0vqjk%2+i2e>K0kTB)NKj6hc$-M>Wu*r{?~Q{P1px3 zW5ZQak1AofwBc=paWbIO9uemr3oMLJt=;`*z4d_T4P}}7?BP)5@;F`<1aUjbyP|3J(FI&P0iNsVrs{1U(12*O!^eUcAXo|6J1Y6aAr(cN4+SkP;MjNqY<8=Pm`{* z%M}r%_D$)BVh#D;E7hxe8JlJkmGt3QYiwiXOVVm4U&9GVIin2*VIzI3sVVsqG~KJCGf9k=qNA z^Xg7tr;H1z+n$yICkA(=j*pI?%$3mhH@%q1K(b|Ap@Ettu*)VOT@w%Cn*G+M3Z~j0 zox9b)8-nppKq;5$&SQ46^!du9bx|+ivcM4Fl7NL7BtjANhT?~%4bV_B!SlTgUKP1D zpmKeVAVp6MvntOPD#AX;LUpfzGGn|w!;OfRM|V&C(`aeSHJ#VwsR&Ia$RO}qcoy8_ zGC^%p+>I9O!wU?7{ zoyU5IdYpwfzpm>ZWY~D$jA(iuQG>m3Yc=)p+Z@r{JV}H6Z#Ma8y#nM1lHI`vRC2J6xWTDDCkm~4{I47j%FgYFLDOM#CGSX|@s z_D#=*$dozPJ*lT=kw;tZ{8BR7r0wdMr~*BdM&*z9Ih^A}{BePQ`*dd? z?JyF}V6ROLuua5!kw)$`>~m|30J?OV%*tmx+pm2o-SxEK*#aA3!+i!7*{baH02AR) zC5~~vQ6q2N@Zvi{BwrHGFqk~Yxzm-XQf2W@>=ozfK(9w)-z|wYCv4}@62;b=WtB)Q z16U6$aas5!@GYgZN_FuA8si^F`Py{r)%v2#!HLC&&=OL@($duBB`U(Oe_c2;x3^5E2Orn?Px!83})lwLI-O3fLIH}AXPTH%1X zbe?w6`(;ZcdXLJi+S7M*-a{@_uN>v^Nz*h!M~&L8>cC>FQnKcq@o5f8$vpwSOCFDG z&%SGiB7BhTUMw66*VEFsUjTh$@gwz~zb}q+G(Y7=cL8-ro~!Cx51)gzHMQu0RHt!> z{FJr=$IQI$0EWp(5NFdT?hP3oG9FYcW4ydj;0YD#iW=Ooe2;=(2O7Zjcn3R7j%4A7|Iu5p3`%^Q{#%#fsV-er#$>UxA& zUnC@^It#urjO-9ECr3yo?U0mVFuvP zGX3uS&9z%)F-do&NR>w^RqY$Rp0MbW^HflNPIzjBFb4JbAtE$=`5?wPA8$-WJ@z1q zb|{sXC<4o29xz=E$`_b$uJ0zsjC-rwCB~6|9g>vwp6kw=;3!46cY58*`Y*)B0$U|;+ z3R0o)n#$jweY7XOZWu9E@0y5K)i4)sTZPoNI}@8U=Gm%OWV&c35uZp1aWZk2icY?s zdT*Zm$$min>{uSNZS=6(o~SqrX{feZvQgk&_h=hc52Wv)d8*9}dez8y{3({#>Z$x4 z(yIoUG3L$V$EJq(-ims46=>9L`q1}wg;V3UqW;Ja%eIi-=9stvg<5w>kXS>cC6rd__g zVG2tw_JPZSRcvuESUA!6A(d-c7nWFyLawCs*@) z0KEOUpoAh>#o$R*!L2E=nxglTx9)^l$a{l@c*Of~L-03{xrr(DNhs8uk&L(OXZjMY|9wkypA3Mwh z%~JU$iJiu8$2b+o;+fANWkfEdL1c(T4~k~MAQx%GJU7mWBx!b6w71dD<2+t-G|`T> zJqTXls$+T&oLwk!l!xgw@t~J7If~#em?{fiGbzzl__lck-jS|YvHtO$TtyAKk27`t zDJ>Ya#|FpACCK6%BFv&*gOw1BbAznvFt1U)*x4*yHcVRXbA4O(nM^cM4xuLLo4CV| zVOR{DM|tGjw|5%w9TY1RVor+7+fEv9M&91G)KAOcr8&yu1q~Hv31*G?XmG zr8J6!(*WU@QTuAOeJE17mn-(d3H9C`S%0EUX=%w9aB$>Yd60UjhN{XKgXSJMXJd6M z{E-&qd-)F`4YleWy=*ZINk$xDF%$Z--r%R`&*e)oOd)C$ZY-gCdVQ0um`y;9fH!I; zI*IZ3LW8(bOSAH%SCu}A1s-*L7=)Qb6Z8#@0 zZd2dtD$(&m1L^61G8VEg6^?blfyAOyUa>1)ACH!4P=!~=Cu@m){J~f)%_ECf10g3i z#wRg>G#v(k4s#3xv*Kn9C3VKb>_KA&#{@K5eo>xp3|~>Z$PQu2rao#AJWD= zFp;gMK~(Hk=A?mJ4NAyjN1GQChAC)^om5jPEX_Be+Aj3W}9kXCOF~=fq*GpyjzM+BQx#IjQBePb_G zUPl*OD@JI~$cL!Hd_A7*Xsy1f1+Y%V^*n%ob(O~G{k}@wbPU?N9#g9!)OT&Hqx*e6fL3iSKH5yL;4$95rID+FC&j0zKVn0oF{Eg(rq6r#PD+! zG4Uj+K1qet_>u%omR)$}UHZT(tHd(TqSolqu+uqwqd@zzy$5aN3ck+}#YBH^`j$y5~rE{Sb7WwX$A?8UGBY~qw(Aaw$FQm6}=eQ_XYUDIfwv%Ez z+JkEp)k2xETS6_lnAAciYI>7*VdDAH>mr>a-!1Lg%k%;w@mf_R;V~dIR5!4iaRB2} zxu;Q)+TE&4UEdXJtz;jaDCVeOPuulL0@{#SA+C8u`wL8LojfMKtwm7n(R#{iY56EC zUC8lH_*;pmjY_koJOL^Igk3(Qa*gSL?mpm166v=C7@X8k6`rTWTaYy-Tp~edOAr zTmiayi+qc*#awD4z2g$Vlx9ZPla<)YtvLTm!dpIkpdfjDL z86z-EY=7a>;D%e_<_yLR$oWy$kDumGqkU=48FHVvU?2>G5F4Nss?Q>|@%HEs;Y1Y^ zc+;^#;EEin+l1C-$akuKNP? zUW5^usADleuuDCEg zLr!UiFYuJtd%0+r9@PwfvLCWPBCD{dm%?LZUM6aPLX2Do6?$syAk?qrJPg(u!)Ct;y4AQAe?ogJ$b0whaH!@wEhzx0Z0G zhs1t}TqowBoQc-0ZXU(W7+>VrJAxbGkf->~>9A_nU_ibmdfup%X2?UyfZdfD2>0F` zjM!mmW#X--l&qq;FGQ%Wo(+~4q1T4zZMW*9lF^|BI9z^KhE9CNb11=eFJWb@(nxKP zf_VOv&cY_W_4-qSNtLu2tRp%i${2?*l96O4GiYm*Vf|2ULM_!wzLX8mvN;2pGt4)) zK7ZRb3aYSQlH|`sq9>XuUE3?DIgCNIL@b_E9e`C&Ks(GIWpASwmx#-oCy-#H`nexn zB$>U@R_kwu>619odZOz=j}oh0#U4@Ijx7#wME3=ZRDe+Uu0$8oGqfA(zMs6lcoH49 z4TzOA5pHn$Is z07Mc2&ed|W|MA)$OagBQ&S{I&kjTgRSqtoK-s`)M-HqZ%-3kpbT}o2RuWG2E{iY-l zTOnwT%9j&JQ?3-F9%W?iQ>MlciTcCf*q!GyF=w8l^_D?Tql93UfwgKPTrSTtrAcv9 z>F`TcV}Sm%nS+KCPU<+xuUdFYNOPvp3R(iPaRJ0q-U#hXmZ2@f!c7KEQHpWiTLyuX zcA-ohIRaUiVbDPb?)?i^@nx3FFI|>uaDQq3qRBA}Af|iE<=eEsI6xOyX1-H?Sy>|s zg|TkIf**}LL`0-Ufm@vzrd-`npe$Ui25nO9Qxfk95UDyVb`!@;{Ny&xyR&41NQh2m z57eAwUdoNl#3-K}>2@%v@J-jVn3fYriT(NQvHD~2JH92jxAxwWF|<3CKdPlUk2BaL z;^MiBG(&R@?W>NSNpR8lTFoDMkr?aoqZMhEYv5B9-o=z`RApTiJxgEZqnPAs`RSgO zP1n++@v#IqsvFi3ZCIb0COp!{`ejAi`}14^AsL5p-d+rDh*gvelymG`3G!bx_7oj8 zGv*O=ZbS`rLm!L$5%*#-0EI~Ve;AP|GbIspSO1oRED+iH4?Z50*D{otV`&lZ;eA(( z#z1BmxRE13q#ua{={8u}N0G`XWd(7|rAnZoxl=F!2j3~Kl;bQ=zEFZZU3shXIwQGP zLhtp25{=ZyfrHD*A9|Ox!81{OVxFGeGv&`WWoTYTe{Y1WGncflONl6t-Xt!a&b7?T zJ!skOt!z`mD(on875hC=O5{qz-n`C(J=e zh7J^(sU~#s!9Xmr5N3QncG$GQRftT&D2fBY;d_$oo!Ij+XcY zS&J&Sg^Xn4SJi`^J2MGCJb+1XpL~*c>7Lj8;v+Rwa7|S)T-e}3>R@9^SvDRvS`Tj@ zG)Lp7UiFv8mfB*ZGNgc#TUR~tASg_(Ah>Yu8Y5hOzCP`Pcb$1WP3rm;5R6-ee4c*5 zP80^sMiyD(exIijJIshh_2hHM0KEV5fOSYs(v_}o!YDeDCGGjc^;16^y1p9N@B2e{ z4h2$^zUa5*XEc8K{ln++MAnHAtw;E{cea9Sogj`gf*!CMvaj2|!_KN9Z{zTo=|lko z;oF4}m@7yA6c5J${#X8oe65)4%Ak(rp$1-dx#M(= zG_w;Nu+iV&%83AFoQZ)j7)t_LpAb;rOfv?`%Xj}pvk@PVr*2v)PKU3a^5Y$o`lO=4 zGoL$LDstScGPx=F zS24ZjocipHgEK784U=mpmIlajE%@>?6z=t58OF_|W)Ma>w9lX0@#~u7iytGd(@ZI- z<-)mMn2!oS-Kkhmh3OkSvh9?@jQ<8Rhmj{UebdA5U8;4oLJ848t58{zK{v}N zMOh7QIL8pm$y5e=$zrS}oL@3)lbW!!7UsH6Hwm&jDtr33rhOoL;wT%zSRBc`O%CN> z%^RWL%n<05!K5yPbFtZugpx5+;D<0sg*62}W3Okp^(Z zGVa%TGfO;MXD_@jrDf(;MLi5_NNS7lCBln`(o;&xYPT?XQl(>nj3m1-L3y1Auq`e# zw?fs18`ze1A%PeuNDveTlr^tZ=^?+}mJF^jOhhy~hC}$Z3i{E&+{2t%ZoKfGR$Mv& z4}t1jX9>HIS?PoQ-@bBj@hSi~@fZn_7kL_oPIV{T`pNrGU*RbX>*B?c*7N8oSV~Rh@s{k6)XlbT_VUE({{w zzjKu<(a6(gY$S48fWRHAlRtZUMEszWq}JE38>z4+rA=Op;*{T-LLTQIN#6mxvD1%0 z$Lg`z(*}DnN?Rf zZ$*Pd9PjfL;xQpZ;8>0ljt>7$TX~R`t@&;9;9wAn1>SD|dDG|rM?!7?m+3p38^Tm^ zq}8XJm?H-^eiJgWQbu_`@`UjHyK*GYU!Vi82N!w9wRQthuu1$9OJ@$%A#jHU0}p%_uPveZ^^<>)Y^ zzEe@?H(;a2vT;`4C`90uT%n{Eh_`&Gis@&Qwq0O%T)3+xW(Y$@Jn&%K9iT3AgQn=@MCRjEVX7CYDaBs z$cmv+a^{NrCL4LA%|v6ao)rh*rc_ZLrNHeM(-UVH!MDPz@+Z+fW?)9i_x68JbTyO8WIS~tl8S6l<&O$dA;dTGipO|dKP_r>6ZlU8DDB*sj83=*)EXqMk!HWx|-MiRgaeDV6v5To%2ah z*d-W&LM@x5W1yo*+3WM|)>0yEn(2C#31YN=>SB?V`A+a~(FhPY!nC03F_1Ky!RvtD+8pTF* zY-_MBX`={iu8hc4Mg1S5q&JSnPL!uWP^@(WhA}}$jr8ms-LP`C_RXW_LIlJXA`6Ll z+?6lU|962W$KTIa@BAke7N0(!)LS4~=vCj1tAM3jD5W$~VbWU>gm03&i_Mw!RxI^i zGQd}ZQtVOWkLutw48~hHR+=&e`-gyeEJO?{Vo4TTywsjt1+EEpPq(AC2ZkMVl^=Yr zmkWqHwvWZRzJ-dCyUHLcaEd#a^774||L<2pbzYP*$_LS^uJ?Zh1?vke=@5@&kKr%B zq-FH)(9d<7r}wL-5Z5xu{^^sTndzIg_lq2W*{_UK2i26M~WMQ0^#pa_>OVY zHr8-wZ}qpCr!-RxQ5^N#QuLB0moWR$+oSV)=2v-Skb&v8i0wOwQ?8jX73G64n-nY; zua>2fG3_o|Bft8)uA^VHqo2!5?K=MCqNdu8RA}B1a1TOR*7`^$iVlS2JG>eGSO{+9 z6LnK9dQ3P~wDjw0@NHQ7DW5hj4ySZd9j=q%{;;x*OLz2@WiprIksx!+9^8@2occ-m1)U3xi5u4_wFLS#Dy z|Crj1pf~s`aNN#ic{BDgO)nhemdin0!bXJ<)#8AP#=!Ny{DNBp_gClXlsG}7^WRcS z%$TgjKHhqxD!3zV6zaqThml;{FV-4$p$Od0N&($*8siZ{#;sMTI2ncLy+(Ee&1Ln7 zdYF;>t;H>qId0%-T)r`5NgCg;n1-$^Nj#|u+wU3ri+FD)($3U1Q<=;$Yr~ju+OHPs z`>*fpSJa}G-Yb7eI;mb5Z_Kr0lVT}$o;$O? zNn7z9qcf7V+IWfq0(?nck5+F9tArLMDz$a8wRC2vQsZ%nEq!78< z8#-j>Df2&9Xu@R&>G|O$d?X6Uw1`auaNj_*9nAjd{K;Uq#hz>FBsyyoXYM()*q%uq zSuLEe;oggYMSjiIQPy29lz<0yBsQB>n$_ej{Z6k9xsH_BE+OruOPH@D+7QtuK{xpeef}9@QToJ&Xeu9MjpTg9$^(t(Pe&G?u z2NR)Pgm~5sckIBA>Wq*OY|WnKJ|%U@cGbOu51e~yXXE=cTk%MMTcbowePlEw?9hlg z6XfLBgLal(D#l5?5M@{C(hQBn++DeINQkkVpZJM{U)XgJjJ{!8a5sf!rWh^@FSL=F zw3_SFrXqQ|Tsa1UhIiEVn}Dxol03K9%t00t=Z4uIH7*+!VUqAM!Q-GLqNKS8eJhfx z02dAg4&vkc41?3~8qv5bh1|C_e6w9_E zgofkWW0h{tD^9DCER7JtRP&*(qam(xHsbxoBc%d!cVJ<0q1KK@WdtRc2Qn&8U zwUIbhV%4e@sOeQu71@(BzLJPyKBz0to3Lb*$u=;LZ-sqP(WE8xqqJ24KCPEKl)dva zi6;@l(d0<*ekuYh++1y91WZwj_~%T=5+Z^fsn<<)*T+hY=&5JuN0Kidk;!xoxL+0F zcME}q>j$5-EcDssA=cUvZlh#@$WSNd@FO9hoWyZ-2}xd8@|cLFN1fc~3jJPmTYG6RCoGJ#Pch_lm}cVJk)rV*Muk}n$)V|?dNgmTz{kUE zoR@8r=iZvnS!7H&cwZ25v|uV18unU;8T9Al(tX_OhKFypb;BP}UwBY(D2;|n@!1dv z7kScksHkkG6Oet3V)5q1Y|%f|t6RWtJQS2Vad+Bs<-!Ywo8&Iq;hM7aF{n1qWUN~# zPcko;Aef4ZX`A9s{+4$mnw?Gl*RGW9>WaBgl~*~ANrshl()A~&A=ugS`L$6doDpz} z;3f7z+`!K&6Xs{VGjfBN+9vd@dh418=+O=k?_a&fW{XVd6}6s z%u`XI4B@p6Eu|xGK2~xfldvIccaGaSLE=(im2#Xvtn=687eZ9PYaYIt zGn5+(L&tN2-K;;BRE_?zo#fY>QX$Q{fDBkCGTbuNqlBC_cVxEV$vPO)S=~WOWe3 zMu$vGRM4Rnj!Vrnlo4ssW|$SDOf9=H#3FO$?=VMA@Ud=OKE*o8|3$kgzmx-M0VpJ$ zTW~^wKV7Ml`S?Z^CFQp@BH8vU8-bT}>y@%n(gh4`9>Y_5pC9LLd>L@D=R?QmHDzJ< zdc=Z;0SE0A4zaMiIY?FWA6oGoFbu%*l(w?hq`aTQf7~X-NuO!L0|)bk3e#GM6{X=5 z=};UJc;M_z6y@|~)@8>VViucNO4fP=KONn^X<>9odimaibPqk$9E_!b(d*^KRYx~m zd4XvqL2i}rMjWSK@FWR#$oQPpg-}yAazbOraen@aAxX}=9jS0GEUd#S|Hzg;_A~H3 z58d%svIL!ZMVjJ-TfCf4N`ZW5idEg%e-=L?Vqd8@ns-e;zIn#O3v6b~*H?J7y zl28;Rj55>$ZD<~QShz3Do0wBV8H8Q^2fRz7ePG_@`gM(r$$j}0bf!!^g)rziiZHT; z;A%~b_OC?rWs`i>AJ4Rue&c=fva-xXUFtDA*RCL_(B0%(egwwe&iA4K?0#QALeJMH*a+Qs3<^p@?3i>X>T!IngHOQpH_ zsR6Rozx^fS)3Ap?-S21P!3a3B#~=5FXeB-wnmeJ2WVqQO8Ap30E{Yrs$!3BH!S2P5 zZ~lM>UuM;^-!)>M>@8+mC-|4?4}y&oe<&N+Ds?ua$Av>(C~Wq7oFYQMRb=Umk~)s~ zTYB`pw+>8fUyV8~py_yQM)dEvN*XjKB+Nr4RGAusrlpAmu_R1Cl{$rAo|TIE$F~!w zMvWw%&%uH!-_Da%_st6Wx>_|)WIq@>JnqG1EEv>ahRT#zqj+(py|&Le9cSP|9aittmVRKfzW5K{3&jY)%jpVdTeFf_LaQ7lEZM*Z_PH%;e0vuPHys|_6m?R1sTcA zTs|(|6Q^?uuq^9N4#DI#2pgC0k*s@BLvIVo)?X~l12Rf<=YeP1&MkQATeA_q+TW7! z3K-PZs;QA@XcQo;#+K38h}gWU@hA|=7hJ0>FZZR8g(RlQznMf6Qu_T%XVY*Z*Y-jO z;M}63Wa;)hPC2)z?Q4_-jd^Y|dpq2#iV$nAwV$F+k7WsX!s~Il`?_wp)eV+(b=9B}*`9VpjOrEb<@VdMlG2WlUTpzK#BlkN$bhlKKhpJ10;QFw6 zF9Z6d6RUE;E9Jb^4nc{m?5jV!=Z7Uq=^V_$C=Zv=)4E6*CQ@0dhh8!md>IiAb4u%I z2`d_@aCZr0L9$K(OTIgyKs0?K4~*K#cYni*Eac2*yqyNh={?hI#_}**w-OJ!TZ6p> zKHIc%R_q#Ym^%{Al!Tk>A1P^tB@y_}z9i;YZP>N=W%4`FO!?zB&~%)Zy!cd8xvHfe zpC}<{tI4P>$|pD?{0OhvIctf)6nLmK+YSkRAgQPBcgw!>*L%1CIVo2~Vtps@-c7O> zlHVH^u~(lJh2-GsT#Ox9W?)76^Ux={6UZXVdT-V5KqWIPKr?7-6_R7DIdJY*9A~m- z%*l1u&`Kf6u$Vb0M$KDpDQGw}O09DC{EM<(lx|&fQ>%30tsS#XtDjCAI8}%1%h9;~*UmAhTUQ z6vv7%9Yc!cyCmX`w-6%gemQkU^U@7`SEc*K{|#$`7*$7rk-oQE$XQjv>Ilbo?LK@` zxYIZ1q$_3NC@^fV4Fz zsOZ&maLr6wC6Oe75=PH5w(X#`_ILipuD5I_M7-0JyPh=^7uX@E{+N&hAAviRkS=8* zm1#NXU!unRqxR)79T7#yprqT74yYd#!}dtwl|PqUmnF}}uu{^Byxsn*OrTeIZgKqY za>CtHwWIe_m7{1;Am(MnpuvKX{u5#fygky~K5w}-mUeiFt}SXW*AxVwS}BV*2;>Au zEumyRory3CP>etfr?wfm9ZbW;0v~|$oecj05E?2l46d=;j(3SCR^_3lnn(&3{o5gGdmv z7A2!ucdLECG!g<)&-9WD2qBjtcO}%8mn(1I)BH++9adIT>AseeFgU;gaqSHuf*%c` z7Z|=UNq~Py(|i2wu<8DTK63*7VLoQxVFi1ZUvK!o^sDFkz!1I4F@7hhvZ6$4tx9*o zIaBqVYT)JWC2#Q;OIso7$AVKl!3@uMuQUc~9)(G{`n~j4mb~tgmzQIT)S3kr6yjjJ z^5DXGzNLv6^&bOv&J2g)up|+K>i^N>RdYta&0@;Ub&q<7%S3z)ocEbJ)sdhFQ(VE) z2XK&J%ZM01mLr3DK5u`f$@NixWidYoUNu+erJo<#kvn|fIFg1r=r4scg7wtA^CpRB z`--$$B7Pz@^gc;Iq7L~Muo;sW#r7NIJKa(pW{sDQ>2r`x(0$${z7R?w*g#x%Vduz+G}7}l8Xr%{nBz(s%btBlxz)O{(2-2<~9FfTtx94 zbTs6?+UIW!3oW0=^tbvd8$fxJa*`=WWnS_3n|*;7adxaUpUg8tI-JvpNw9X4g{|4e$;y%}8c=U@1G{BtT37ZLe=>vM zL{1c>Js+Q}Tt|?9ZbybGBk-7Ssp8CDF_Pt%_g3itj4l z+?T@ZrWNzZfBGaP!Dg<{?|m=lR$&pl;daFbo1?wd1XGFK(uNu4(moYMuj{7$=;V9y zaDwFg{&VuzZK+J*>n=Jl#LK0zuN529BTaB6Qv)ny=|5y=QWd8kF}HRknD?m8l7&p~ zOcBUi{vA%DDU{2t<*58P2P>%Poyo0MDOE*hvcEDI#BOzFfCYC-rIAI8Y9^3uh@rI@Q$>>pHyz=Nrj;J}S@Ew5WjI+)-RJ^LP%+PrZ4UypY%wS^kVkAEEq>IRQ_Re8K_jS#zX z+q@I8JQn!xTM;cn42gD4Zx~aCrldWPmq6dcZv#wI;w`zCY1T{Scxa*h46?DS!L82U zK{?RdueU^Q3g0b$&EqyrH=^=xCjX*198X$A@rC8FeFvUA!oY~MJ1Tf=O@ip&%$%J> zLf@dQAZr*PHl1NENog@$JOWkceG?d7*`|yM@mtajo(uZ&_|zXQ@>>6R=lxQ{WCc=d`PP}X^{F|++i^3Vz^$jDb6*4;}1vf=xKGXJZ073qVa7N9yB=7CV9<7aVWzk50%+XT169em4iSH?^ zWTt&JGddd~y%>h8z4mz1k*z7dYsXjmiU3eNqJ8$U3LnIlC&B3C)#_GSb%)J|n;;=0 zz2c0L(wCcrhZ-kxo&eY+-U43I7)0%q-92HfE_%lP_B?GV@KVoodkIIK<0x9ry_EP5 zz6~hBnrPg8reB~p06o6oQG0U#3Ro@+ZvM0bDI+{6wZGpr6R_z zKeyQ@zMhNxBRk#W!&`b>cb7k=k30w!S7Ihr@_bK4&f`L16!{!s&gHPk+ML@P(uZz2 zxka5%gN*GHtjo<&XmueW1P9_K3#5NuCYiO2L~;ytd4vzpN&)1W=4d+)g*kNpZfDnV#EcSG~z7i@*3 zv$dXM`5_*T89Tqk0QH{{R&g!Ac3#v78c#lC2W&M=@D3E5N*bWjDD{?~Dfd(2{~CIt zs0BN|Y7XVcR={*wh$VWTyW3&!QyY5d6U8)5rPAv@3TtrzkOCS%3`?kD)G3b^ttiUp zSLeg+(l@wj(xrMh$KJtY^-m!2mJ7qeBG|*p&sbhtnS5F&$|`-3>}ItdNq`j0#lZ^a zz5lBEtoQHN4IK_FX+2QU^ck4q^)2S-=H_V`cMMqFdtJW&2hbWMc43zMr1$^yOQQ|h z*0wFjDcI#7fHI6Kj-3S6GvuwLy^v9P=i7wUwr_1a-9QaxVM3~5Gvp?Fn81kTp29XZ z#qy?Z!e0w)Dsf%uAcH72WcD;c2tfrt_2Y%Wq*ylZCE3V&exGQOA)>I%HfpvEXa6q7 zuSQ&h$}w6Y{hFRQ#ZlsO{<-ShRy#f7;u3IQTuqPXzcfExSsZGLYqNU`(gk&3RC4+} z!K7y|FBo%pnRy?+RGUN&d{hnWth{ks5 zDV8_#ttiV3Pd@WMFmjYY(9Hm;! zMSY6@88RfNTB_ZV{mSUk>FO>d|`L@=`btp)b&a7Td;mF^;3#os24 z#vBtXWZ-_mX3*i@IPWt|izBmqJ~>K|C+XX7jaFJRTb&l8s!wwUOm2PO7eAh9E~r~g1jZq~ykzA45=nhj!ExR8K~Y%0P+d>8SdY0N zrzw}m0&W;x;B9~-?^?EFR;R1cK>;ql&8M~Bph-VJSR|fMMa6>rFfIr#yyW6ji@FvdF52S9P-jTxvk3Y*OvZMBTb39G1qCS=CnFH_nGZ?DDK6szksi>7Ga~Xvs@W#2V>|C`{xb+ zO?;di^xL8q|L0oP$3W1TmbNrde2ru*e6>d$CUGhz(i-$#JE>@+KqfgSrf@?&M1ew$ zC$^1>Ea$d%PAWO`&a%-sc?Lph0~s~C<@=;P?@`dVJzcew5n*6wXLjwv%M^k6*mdYr z5OnK@Sf+LFLdF0@q*)4_uqenI-E3$%(J$K#dX2=vs2TV4n)Uvi3Ra8%+PKJr!g*1t z51Rpu!d~9UTh}sQ7~wGkmc;GV#!l3!vl$zed#J`2&vj|s<*Hs7%s|dUL6(uqv=s1x z4ukb=Kg2|ttV5ailgo(+A9Xrn^=4lUe8#9C-y>wxzjK(*+bzr3;wTq$+7eVwXy|4A zo}~nWA(VL(Po{TU5zV_Zw_X+~iyL~AJxIAMLbz5YTC$IHc_wZ1VQ$Wja5g9g^y8m3 zQ(zLtI|{>l6J}w&xzzm(j*eJ=-CLnyH&oV!+aM>hDzRw#laP{Vp!}Vo zH@}*1k&TV}YFjpicq6Q~UeVTtdyDO=;5t_idUYW`$!edMax={;(#Ky@ND@cI-0nEOqB;m1f{? zgIxG;<7AYrPVyrEVHCU97HWaM)*h>t1;sx!f#&HuMm}-k*f-atS&hP+7{=;>$x8X- z&2R{*ez*_4IWg2RbT+;0L_;UIr;=7u7_$}s02DdA{4t#6p-Y7=(rHd&*{G)~E% zFdlT2FkK@ptNyFxwxN}AD4qY}Fcp3>4i8Qq793(l_=2cKh{EPTm2U zGD#wS(!2V8wdk<~)XrQfucLsTh>B)fSkeV7B4wWtyTk zX2KXz#bTRw(+Jo`<~ScNG-AO6-O3^nSG-7L8Uof|>&EIj+L~_HoxfR{ykoHw$MckO zr}ks!-%Y@s9+*<3iF$3ZJ_iBEX1vB`)k{;UT@H^bFR8@)6>EK_v5q4T(Wsy60V82b zp_EzkRMXP>1sa$?(VD+vLL^Be*>E%nvS_=izl7$X;nPSU{q}tqz0F*$+*qv^qRy!}&%lYI##ymC`&AX{C# z#R;nO7l;i`LBkn%H!Rbd@BC|Tfb0@&3cwv_=7^v;%{{ZOVr*|AKOE(f3Iqp4D1dfq zc`#(5iz^avN@_^-;6x2X*Flt;7R8A{22i@yDxXXh7hu{r^j%lt7@GW2IE7jJw@ahi z)!ti%pVgCzl{-Gu$RS&F!kPrQV8uxfk}kJ41}lc8_Zxs4rbBsoR76u3Pbb@ukf_MG z+oK+fYdEy;{$iba9kn0}AHQL63kuV(gRDNW=ACiZK5j=37u_{jME2L;knfqlMwp3# z_J98NKOAP}2t?U>6gm~0GLT`v$MH*~_p9O(6Gb_I`;vDw`a>*%`~SrOkD&a4&41x7 ze2b<6eq`I<>|O~rEJg6=983K(%|@H`>2+{N-){Krua=ASy3>_apJ}|jP)Zum(Jj__*n`RV6b~{{~#ir+@O~qisdd~h95T0L7i^LZaXn(?JA?h zL>-_WVPQp{Pu7U8QA_?gsj*a}!<4C5uFR+oAxZoz-Wp`Sq;#0g| zH4Nzg%XS`!TQ>`o$J9ZbN9P)qu%qPed&Er^ zuI!&CuzPt8II;e5yc9YeDD+LJDqP5n43N*k$x|8lc4^Bh9u2-9U;V%siusDM@xlae zNZw?&dKF6z_k1B5$Ot&@eOKnQ5&tbMknsE;fOj357vV?M7jAh>v8z^^V`56Z`T|J{ z2k06> zN10?e^}wja`GksA`6G0{XHF(&A%)L1 z?vL@QihA^7>#`n?g;>s6F|wI5hBtA8QiAst^9Kv+WJ`*fpFD3h>%PJurgOWnvZFdB z5x0H8!@#s)BFhr6VZ5DI1`^V1ZMsU++7KyJ{bBF@$b69D8)v?qC&b;dffphT%Pv=8 z!26BPI%{~W@U#5S0+oo75_w^>I*<@?&#ct}3@Ui1Yt;$|Lg$%?O4CAKkJF1PDL*%o3C32=ZLjOtkf|ARnkgd%AQMtNIL@-Fi=5F z7`M(d#3ZAOo%6S~3EUg6n?7Zw`f|A6oK9I~D*5e{HkGHP*+hb)%d5jH!q+Wi2&6p; z&gMkz0bu-?G_Kr|Bvwf(46urvS>;vUU#6GYqZHD;PhMxr;XaGL8%{ehrRyco#Yz>Y zI(sC_9?^NzHW5?E*pP6jh)FHacbrWr2kkZ|3a78?B}9-*1?rqJW29x|z~3tKw4dge zIxk((WMsNTJQqiph+_!!zdxTyGQc~XUaOZvX&My~)IR|=0!rQ7#U>Qw9K^+G5Fy!T zO8gF(u^rz&IXz5s^Ijib%kNAv*F=~`VnhtAzO5+{5G_@)C~{`Q0YlxEqgPDSwal}S zYGI^JqB`O|6vY<$+ZtJrP28HFL-xX zpG@n}U)VK^?op*(3+ow^K=ZF~$@dz4%&Z#`+#p+^w0qc^ zd#_y-`24p{TL@(Z(xhWvRJqYOtNtj1JiHu8{I^P@zj>9sg<9cR=35X*7Ud`VMORQ* zG*CsA=0Cq1PDt55?-7Kc;-GGgk%T$dgb$NHvg;8(uNL9Fgp593?B1ZWgMKFaBmMY% z@^HMgl+U>LQbNu9*mhlb1LvKALFTkLO|$e68Q;o#ll&`tZc}Yt{dcwqWP?e#+v50z z!tCcdEKV~Rtpwp-?d{{C#nV{GVh2P)T8d~@u;fCw(>smKyPGKLt4|l=GkV zGo%7meQ^16q6wcl&>Ym)6&n2+JD56DB>6dPzvv3xvvfUuD+E~YsVDOvgDU%emwb8N z1b<$ssf)Sn2z8~4x%7WK;@|%t@BG)x|9!%VXB?L|Ehfs0IJRpE+)#m(cY#8i>(KzF zW1j)4flSjw*^^>$0O_Ld3wh1yTM(rOaz<5qX*co^@-2vZuD-yKCS#Dnf_@zs^L@~H zB8bfA;`iduz7@6V*&ciYihFNjvbaXz>5B5*T_siSZJgWtCFTz(@c~8)`F)V5B8L?2 z0+D|JgGAsG*A)u6dCX--6+M=prT9&O*t9@Q?m+PsM9?l!#pB0B(XA~8`CDeY zWue3g4GyIX>T~&l?A}7(@#{4&{Z8z2(T`e`?KsJ_*U!c;s_~>^ffK4Yh28l}IAGX0+6k0K^vj}bH8|b7 znWY9YP#G$7ZBb`%T2Q2#MF%qKUB586N&!Pu#p9mUz2eMh29)f}Q!~K4Q4nu4FQicQ z9bYE(rC1zHH}O}!awPKtxN~)X_2pNh-TYGvHKgFWGL~NdQtsU6+P}rY&3}t|bkLx*BJpnP0Z=z-jj-VZ&Z9HyAi!I6}A5$yBX?d-}}mOxMei6TzU!;!2733o_ZIQ2FT60*_G ziM&Pc`Q1ilnpylO8+DV}fyEoTVY;K|vUd}Zw?4{%@I%zuhtKPgykDQ%B&Xb8lBa_$ zU#1IM9){sN7&jG?iW<*~zHBPxobs( zW||B|$KhI(&t;%1eDytZ(2t@6l#H<&nrDOpxhNTKXEG+fj^Qpw5Uhn3g)K2j$`Sky z-h9irtskHHzWxJnoxw7R!*iu*od50ky#GPX?(frw&L>n91l2oC&&9*3jl4NdX?LqX z)a9BmXf6Tzil}`O)4!}trbDLE5&Zw%;8dyqXEgSIu|nD!R4$?0N3bVUbIXhOn$(uK z0Bmzswg*@|gQDd}R8hlPCUYxXxJ!Nf|Ha;0$41gU>%n7YW@cvgnwgoInb}^$nwgoI znQ_g`FlP3e+1_2#nl|(PZj@Xl%J)a~-K!`{>u6Nnty5D?bxv1TJx>?p5-DYKc0CkZ zDeNG&q$gG>4-y-oUxJZ&D>x$PP)9O8Jmp@B*0F1`IK=66skwKIofAD52x~b#n4trg z1B49$f{$i%IayIW{RJR=f5L=cZe9Be=m^8H>6|y78|VwPZit*SZSAw$D_~~;RM1 z0G4C*(IJ$i*qNYxoz?Oo<3)30i77{nwNr2*7wu(y=g$A)$khl)klb_C)DT!ZbH^_xszAH;GyJ zyd;{*&&3d)fKPYjVARubU4uAzi4jUl^VG|aOy!N4<9q*NkfKkBp{rkgG=cMf0X!65 z%A2qoyAA<6#2%&d;1DJs4K~Jk%ZG!eto1;hSI+Y3K{7UGihAAOo9CaM|6T{Ni=gtz ziMydtP_GVUpXm~R?G0=nNtMv?LZr|jnF=C(pq5=rVO^YlKWmAZ8rUQ)YU;n z3vOCh1vOb^2;Mk}Gw|XK&%XdAjrF}EO-e7yEJeuIH?vb)&Ix-|<+8&UbJpL-b7u5i z%!>0BM9~Q^(hi=Y7NQo`r`&q|Fy}?{WtM{7DSA?8B+e2jW)RNf9~?% zx2TnJ@~_;<3k#&?j2%OuU~zZAPX-x^`r-3<*BZh3Aq=v5_UTz4_oE|Z7VpU2pclWu9gQj`seZhkk(?eVsSOQ1O=yBv0Oz)Y@z zIN?zLk-ji5q%@?zTRA`2QqmFInf2Qb&ufibL*`O0mjdNfLzKcEM^uJZou_bA8oY=X>98zv_(()NB>MO z;sd3X@;9tf5EK?Irv-88!S3!l-7F5B8E^A^(YYG1)3p4vE9_txs@F?Kr@~^g=JlJi z7&iYPYfF)VX{Di9jjHfY4%>jRZZ~V`NX~y!Cm7C_pwXxu&^m|}KBLP?|3kIJgaZ0` zX`9P~H5pyLwYgr{i?G!EYcpqhm{*<>XRVhsTPB~a%<$7dI}te_+i5ZtZk1V}H_S9> zUaR~fSt@Tyhb{-A>`ug?2)sK66TvB7|I7>c{I;Z9pnUZp<{`a*&j0<}_Dawkj}`*- z#C~AG@-vaJYSNu%kvv3>9d&H9)hc5W4&x^4X?RaDI{Lh9zW&O2h16tx2}|YL!?|`8 zA;RpbR%#lxlO8#RPwtAB4>N7{ceHxr?fMqU@K~c81lA@aiR>0W({jZ|L-`!3+0#-{ zow-zjHa2x{nqcQhVD=%8;O_?bc7cxNjvi<2iY}A&tl#ZSXxv)xBiKMgBpXKPA1-dn z*t>fxN}1t#q^4`FnF^L!S@SEfXmF-*K4Ul9&=ux2H2zX;MJ#aH^1QAw-8i79R^O=I zis08oKAlQ{v{S0OL3r%^%d#O)(die{?K+Log{kNADcvm+wuFZbcAn7HIa0-sg+9F` z99zmO{gb6)+(#0-86SL+%*i)ZwF%WCjp7jrsPX$TQc{;SH@-A_C?-lsMOs-hJ8Za@ zkc|&?lU@v&D)-liPdLHL_*eJ4+n7k<9urHON2C3_!WVkFZS_lkc)^MBT?3+BTHHZY z0+<^b8zkFi^VQu~qCFu$OtallTuZ#%A}5ddc8u!aaGp%cpWHmw2w;*)yf| zZ_w^#W)!^Z_2X0%L?OpN=JI;l;jDWO*W36b5o7CsxEUC<{g`WPbEINZVJ5xX z$aeTaBk{hxi@;on>=`t)xVf`-j^Xp@0`Kwgl5)2U&ETjt&-{m4(kwQMxgE#DN^bTW zHsap}^gvb}$x{t4ukCui9bR#KoHI@fLkB7AB@$1HWOFg1ePcPwAiZDGwPOlQo=@-k zGg$o4@>6hi1UGts`0Yvwy`_S5m+Ra}%1?y$&VY+3?0w~JFEJkB%o4|b(5*AVy|G#P z^i+hJ8_~Ei^lZG#NNOf!-rXvh*C#EYQgGfut6Y|>wEgdFKvRUe-l|q{@F10%Qole4@2T{J?__f z*sl#VIfwu2pDKBQb&NUJfA_PpC9qB~=TaMf+Erj5ecCN|+JNP*{l#E)PGpM8Eqx9o z7_81~bNwSe{%ft=U0d*g6j=Lxj$9OH@F^# zFb0nO%m2zM&J+gv#-mMKj)is@L&=GqEF|`EqO#w}UFh+f&t<@4E!wTngChSk{iwsv{+AoM5S*RyO%POa zeWTzzDAla@?Ly0ZFW}i`MG?t^HfT*xa_T#g!JnC;wHw(7&_r?osGf`ycz-&F}tY-klam z?^g5~-VVsV=iJBI-=N+@%iRNd0|FpZ%D-{G0q_3JKIiIvL%aQd$+aIn|D3Wq(EowV zcLJTts`=3ws`F8`8R2`FLp#ffi@AQ(qu+t{?_d867ZtPz`cpnN;LJgN^&R*y;$}S>lm!Yds;FH_yy=COM!=;Ehnhm=7p9o zg%AHZpc)+dvOoBtECg0))_2_2@sR=;*3u;qZ6N96$2tFCYb7BULMQW$aumE$UMP7F$_8;Ys1i4q|sF03QxlHarVz z$jl-G$Yl~{_KQZpSOicUG&~i}gmgN>sBZ_xeoNEkPlHIf5}gv9A}0%`@N+FZNeK_c z#H_;+2Blv;`qXTvmU@qQKiiGkVltIhOKJR7y?YA1Cxs!|pIRFmgfP+Fjh$Lo!c-8| zwA3YepM7oHa#wDe7}cHsIwxh@4XrywxRkS`;-H|Dkm+eHHyA}=qtGcnrbDb66g#R1 zD}M)}0zhp^(Flbm3l#@3`=u#FPK%fA@$@lO;oTwa7TO_(QI6D=DW2-A=HOF{D0RwT zePhDZ#kH=5^ZagET_>%G9D%%Ia=?mPd_Y6FSOvJ2gbcQSJ)3XK1E0e71MvgA=bP>) z*h2E5^!C?R_g{PV2H(l?AaiH-^NBc%1bO_@d#8LmuI7Mjigjk$DvF;=AS?8FbykV? z5={8^@!L3Ur(z5}O0~Ve59eV>T`}8g_oH5Tmo_?IIfhM)9A?LlsobsDTUJ|Q)Ef$k)r7DTd_{H+622Rw7awEeB44-%V+ zr(kW5cv-uLTKnb9u4#(!-u^>lx|y-(!gt0E#m_s}St@>VfnosDVdnu{VD~Ud78=PF z_!reG5+R>HchP2A`5Tugc1W+_A9o#lO4ggomRmD&5V9RM$Q5AXdGMyJ>W z=Y9V*2M|t$=K$x|q>6~H3=~MC+p<<gy zeyqkm%*$|6&l|(O$yseGk8*6^PeK;4Zi!kKth;yczW(UemTZK`5yp4oBP_c6R*_a= zi@K%&EjBQ}{?6NXSB&?Bz^4RKDRPL!Pcyraee@yJT0qT;M91H(h-p{| zt;$)3w}Q82Uw&4ai~iTg&-ua=3=@j)p1)S&aL~pM1FF(ks=EEVH`*P<*RAgs^hDJL zng*Ir!#jBvUtgDaT6mlGe19`yQd!>KPn`kZRf7Hbug0IA*UG~Co<@{phox8Eyo-AE znU`7WW72t|Jdf70-D`Y3-uHsq?udx~Ou9~LMKYWVebTkanma1iJF&@#xMtE9>b^5z z%0f)qI=-qQGE8^7WYCkYRTu}5RmUrl@9VTiK2Bw5r#i6N~0j2+}5fWut#t%w%$ofUB z=%6|ki@DK5YJw#4`(gdLd4QBU<}ku48~P-gA^s5HicEGlJ60u@-GNjrlV5g>PrL{) z>?zA?8F!=?Z9$6Cgez}c}1 zIcxlB2Zk=y-cawnFxocWUa`=}cm^WzBro|7TuT1}raYl)(UYLgkFE}rDlqU9Dvi5k zz}O|`bLKtCPt&G{(AJKRep5eyaqD_muQse0#DmQ?YY$Jc_7H+7=-6LgKXS&{v8f$- z6M9u9C*^IIR)IN8r6EpUM$=JE`ojXq}==OTWvD<0`YwY8Js4Jx!`?XL!JOG<{CmPrVCK9t9K zU4fzT*&e2VfdjCUX7jo}>lMpll)uL1ZVR+g8mPv@3U|D>rK6c3G1Uc}M!A`!HejDi zD>2C^P>C_2hR1t<)=)x=%$-SXEIZi^{y^*e@z`MV1TIJq5IofObXjs`Vbx=Tr26xw z7Mg-ODsj{MCsWTURxtbb{Mrk=`OE4wsl}==i-OE7Nsz%6-v`~|pF(hq_GoM01gK6V zR95ycQfx7B)Qpndsdc03GcJ7cyYEriY0acjo+}6Ijt`g#x(5@TUN)@(Ys9F z)|~TvokdTL(;lbVs+{(KlZ}A?ZIM}9#!D%yBRB9si{VXZjI#v&;&4U+DVtPs<*}{Y z{(LqaXR>Tug^tk7rwtR1hZ23%1T1%mN8zE^4pO&e)G*}vjEf?aVWe0{6~i`H3=#u2 z6+Lj^OmpWRV4g z=IIoc10%|vFUdZqUa|?VDmvLG&VA^F0hLkx=j6VCK5*{$uZWp7Y0V;F(%)ma^#eC~ z%jkmZF8Ja7mB=Bo^S0$ZOM{Sy3$*+f;esjjoUqffDuxWoc5}?Z4s+GyG=JHdVMju) zR@=(qt2ebX?zNJjarP`8i>jQ!gVGtpOTNYkyF^tosFJE)i8y%HSuYwFPs0VSfhsI63<1g%3!<#E<$+ajN>ghH zjYvZK6Ht0OXPE>^2#-pBrL6z_GG%=V->z<^y{fnbTg-Ql^P<}f@>H%@m!0>&e2s@VR z@I205cl!Sa&AUG&zB(f<7QB4p>LxS7o~`RHJ{V{?yY5aK0ZyjO7Ju#5}%Q z7Y2jmEJG9Xs{T^mq=kv=UQH&lQ(3Q9ZK+7kl!HniOU5Zq$>~qp#8c&tk&_EEhfDk# z`8r^y1?NlRQv|IPSYC3d9$gA5#q7ub2KSLl(~g8r%U5Vn?PeMERt-R#Lo87NMS4rb z)F9#IVLO|OlD-+W9V>UM2DfsWHx0gN6-${EK_UfAe?u7-=S&gfTZ$8$7DHis{)F;Y z*~q5+=~bV%bHu9H0_a}%)qbR zkHt$Pkz5NmrB+WjkoNgziNf0fq@h6K-@No$#K$ zEktcf>*tr+l=v8MIG*Cb{k?K#lb(;qsz0>-6no*FOqBs16-*MvcDW&A@QbOUkzmz} zoY-QYj{4zd^>U9z^1=YM@%d9qE;>QEEOE{djf9AHL9~rZJF`c876VR?LI|`dq4sEo4WpKm2Ra>1 z1rXePyBE(JgC{~?RW-j^v*$D2i@gd8|96+AT1!QZ-iRD=xe+%S4erZV4P6`@xbHKV zVuA@O&T|yqQ@HWnUY`(byzTrP#7{OCIx_kP=wHmf#Oq^5V^v(o<=jQN!}(_6B)jub zOt~Ct6lp|(&3fBHMZ&n5I~k(FJAT<_Qe0+rwz2e8yf>`>v{W`N81yNW^suoyLda$3 zpk50m%c2XLb91IcMNaN(jw&)$M7oB`{S;L*jnvIwj?)itj%mhCB0RV3s(E1X)iFU8 z=_SQmBOo*^%vL4WpEiW08E=E7Mwo-!o8u7e4HcteJOxBMGnG)H>fB2XF6wg=rsc-Z zN?F$j?I2t(7H!H%>r=CQ)eEBxvn;8N)Z(EMKI-~{Q1JjrUi!8|g?NFYs>$eCHhXBo zhPf%q>$_9o9)BxH$6m@C=*cF};in>xnZB#hy_nK)uCW(#Fv;@$nciMaG3u$)j^G8u zLaW0J4pElVlQ=b;Dt+dsP$c8KTMEvXPkGfre#0d`MZjuPAMA z2n-2%=VX{FBkDd^vyRB`PX}PI`eIS88J$QNw7hDrtUO^6rcm77GiK%a7W#@9(=P0_ z5@CO&NfcYWa;BmSOM)YktO}y?SDkL^6wE2uu>J8J{4y|vAVQ)itJ_X^`9%MdGjvK3 z$9uQh{iogJX`@}ZBCT%GH=*2%>Ye>v-PBK-`|7KUyT5=LqwuGq7E)4jbAvY7fS%T* zRWx6V*d$I&8A7AdB3~f6q(rguNgoZ&y}N2ysN9^+>dhE#YoGw?8FktRox!|3Mk4PO z2Olx0fcv@J^`#Gv199o5dW=UfMiq5tuYr!|salj@;jtYmgw*dH>X!Hfj=@iwU?sl# zl@qL${pRQ}g0%)M##U}w?pz`)RtI^K&uS~_bW9V>-lUBE@gqJu#h?9^oo z?XU?bV5qF;)o1xswJU>r!-b%+Fs^*UI*0O=p}=WX1aI+-smi3{lFt@DfG#Rp%Mm^B zq-+66dK}r4s{+deVOUL|ZRbvuO{`w#3S9+6QoFN6?u6Mg$72HzACvb{GcW4LJjx3S zuBe6|yI0UH2lG+#Eoy(sL0m3tp28e#Tl+1cqV^q&D@(g4D-A-AmP^bBzO7DPUK}eR zC0yy^-XC$u&d}D8A#IWEUA^=O{&jk%7?F@RR$3W%Y68QRt|2w5Qd1S z4-3MMblte5qM~3tX$tUE#5yA8CFo3_1HR$>q@#;JM^GI&NiCRHwel=VgirfMcOn#BNEAo*M^3w&5Qv@_kk zR+m6mpI2ttYfGGwhUo|kKhO&EO#`c<=s~pX$fsqHKw5Jy(1@d@43owcLc^jFmeZzL zzmuhNkA7YMgNa5QPM#<>Fk3}U=}6P6@)uwS6>atxkojW3$nY?SalDz>h)H~_&{r#d z#8C!BcW_j#tZ4{?o&Q?>wBci~s~9e;S3*0DYf)ity44Uw00s0^vL$9mytK#sK@0w~ z+JT8_DXzFApoZcFHtggr!ZnSrtp-|{v>to%j`r!Px&vJ4fNkw8#}c?Mla;-auSCZ- z_a;((PVA^6J9qrp-u z2i@{25HM{ld9vE0M{QB-<5tlP=aGxJ6y<3c%CfjCt_KH$_{#eFIVr-vP}D#2`5rVi zEI=!}m(IS0x}wnBj>G1SM2Dai_j;clk|KBJ@g;5~(|g^<Dq^`@O4vSMyJwUl}OM)Uwor8iKI zdWwfd1rKmdM<13J$s>CqOQ{ulL{j_-L7Po><=woA5mJPt&{(t-)FkRCtC#IYl_v*L zmJeJ@uaCaK@ne%~L3nO(OW{UKvFvjJ^P(2bnqfE@z9DyURzQz}R!PE@(jwWg{Ryr- z*n%|R!fYa6${LHt-v2Y2mX^h~vyGhT5e>tO0t-z+x8?d$zv2vCCl*zh2l7I9!b4h$(;OD2Mau#2%;-GV|Ofq zz*6brsEp(aRwVafBNy;$@P}73vJIq&A`>nfU&_I+Woj++Fq8S{@D3K4WJp2!9$sq) zGn5@Mr;S6={*5(Od^I!-E+CytR@}+#iB1zFK?!A)mJ2+eZmv?DdN}H=uY|%OOv_;d zCF86WndOcJKI}=!SW=@hDdXY7MsJ$TOr1V-T?c;$zB{X`T@YGLOlER54{Vub6Gn(F z&{}U4zO?N963JBqi!v7|3<7LRuCyMHZ#!P3baH9MPP zkZhr7LpVXre%MUvU$Xpy1Y|Ff)AaK$6_?h59c{&IHoTN3KuR3V>GUw00`W%yeKY{1 zO=Fpa8Tk^LmzD7bwMGYZw+2vB-BgjWMYv1PT&G}}_{LCU*RQ)AlFPamrb#V`nbr(Z z?%5*^%(F*orHf1)W0hu0k$TvR!^H zQL*ETn7_u|@+yvV#@PD&34K$Qj+@xPC;6261fqnep8i3H3nkNogqQkES~j+zU*9*u z6V(Taw3zx8wo^wf3R&iW`mZA znQsc=r~;eU5j)VddY(ent*wjssGQrqm3z(ua$efDEC&EK1X9NO9Yk`V|P-0oL zo5an6HC)^H&Ypi`4|eUTXADPr<)c#;M=rz2x+_1bx0GuXN~q;#k`&zEm1`s|+yG%= z`D?zHPbKvf5OF9J9ZyXwHdaSXMLO`XY-d9KQ_l3dH#2PZN(`YHZB2yF0AsI3pFTTF z*Uhw7Zm3yeo&}46(_qen;3k8B&BwO6i8Ze!!WlXabm2V}!L_ijA(~55yV3I%jka1H! zFRK}~VVDJ=`qH1N8GD)mUGgy)+J?{!osyz}Fm`}`YG@;2AbQKv)w=uyM>|qF&u(z3 z#&9pT7IJ>6TeA<_F1Nt{XW(N(jh2wW(vdR$^tYS>tV;q~k<()ph-){RdDQYqUJYI% zh`oMt^3Y8h%`QkXc0brtR+|ZP6a%-_T=u)i9Qwv+K{N|S!EX%Pb~4sPG34aRlYzvE z{|~Q_8h^I>qFd>tx2zH29dVkiv`m01Ql+em{*jR*8ke9T=#gLeKlp>W#i$J1@62}S zY`!55eWDy9xK-4ie*w$5`jEqCLB?{nL6(5osw+q71%Rif()RCS8kwkc1Bbtm9FSvV z-r|j`Tmq|b-$UB;DSAt{w?a1Hwn^!J2rP3iu~dA>AIavbp-{dy@ijnmRRmWV!F!8# zk~9^`%W`YO$qdp|EdF@>RV5s41*sOE9gkSb}^ zZW!_&iXpj>)z`?SctDb;FtrAJPohJPUJqZU*Q_J}7UVBL#R6(dSoO7BmqUx(@ zRTxBDqX%8kc(hleP@e*Y;5lSwXLEz(c+;{DPQ$msIBaF0;(>-7_OaxX%h6y8dl+nv z&mWFLq_QvAqMf(YJgro)R5q(wS?#$i zRUt@QJk%jsp5}2yqvpeg7Vi%v&*oQ!D|lQ>`Oqi zN-1Tw8o^ECT*I~*X6g%877FM^K6U0$QRjh2HH991ovzK6K1x69MfD@j9KMBDtrdn^KnMju&2wACLd`{E|F!?JMz{{H8vC1 z1zj|_r%iF9{U;&Z(d1S)mlh?OzC}I&h_y#XbHF{!@);zKR#qtGZG4sEltU=`PsO!F zH7m>h6}6OL7+OSWw>U?d%-aS?6tfi0X16&7Y(Ui3ce1J8=+z@u{A>?)D0>UyaD0gPq96#w!lsRE>#o<^*-@ojmyOcDZ} zDja{9#%v`bsZg7<5{3KrtKh`;0jN+Vs)X8BLBVL1^bZNvkJ6cdRnBp6+?>U7kGh$F|E^SRI)hS1lV4v*o|hp?AehWutQ}PkE$Q?ZM#ICmDn?K z?L?l;l#VWrU*X22M#zCuR2`uBp_VI;5jE*}_~K~Yd|_R-+D6Wax-6DrIA_b`UjSaJ z%52y!cdTQdavU2+LRy*=r4nRr6iZBJaS$eR=PTJ-kvA;_1X7%4IjiOjj#5DLjHW7>aVRB0I*MKb(CytMNI_Yojsw<)QF})9%mZS*`!pFGa2I@r-NnjK* zfanQ90U>%vIy4k*yoJaya*0b6i`3;)i}0e%kR+MroQxx6U(aQ)&5{GlH1?axnHvSJQ)ZY);aAg2JEWh{q&cga|l!W(>*DK0!)P#RBFsOESHF z-qlbMxA7*wlxijv&o_oMucW2PUh;6?;0rYB2=Fm`QXnpWD^#bvRw>KHbc9}sa|#;L zafoK7ZuP7z4uMB%_J1$`sZ&FzULCMdZhCP`PwOZU*cQaxc0M-$gX_X*A03r)ttP3v z^+u^e>xtF^u6(a^D~#G%QudGiPtU~wO*}aDbpe$O(-D<$B*eY^8eoI42#$CEs_$XF z5b^37$66D(uFR9KYV(W1%dDDG>+P~^>yOWii34#F8YsxhN12El@XN(Rqy0fcdBGsf z`>!2s2d>$}ShBqZFke>$~}(OMV_=6x+@^WH?M zW-Cj6GbPVr+6$7)ZYAlOn&%pC&h>n(1&9Dx9l@%%VX$10K08_F&ZRP8{Pi;pz1Rk~ z%`8s!Gr9SO7q!4BUvNEFAvbz9qUf)636P37dvhU1As!(B5E;a%pi*`%84CE88MBSu z4eH#gHpQstR9Y+jy>W274_*ryhxs%b;|rwQK6>`!H|V#GcqW2x=Uq`&G&n|5BPJF2 zVJVPTQMs|HUO?}dLo}{D42x3SDTX<&7+ef&;H<9I+%?q@os2%L&PEofVlg6Qf{vv< zW1Tjj{ydp(V^cob^gCd@g^Dih(%NRmew;I&l1doG`ZC*blA=oJXEb+wdW9M3u+62Z1^ zF7!lre)V$SlRJ@Xju>;uqet;)&qn343RB1sSj@=sj)n)i5jDSF6ahlVJD*+xpOkDv zgK?j)cIS9R4VDYdUNS0P#nRs1w8Bp=Qp}b&%`hsHM(eAef(t!G^wg5iW(^gdDFTZt z?DKNT%?H($aQj=IiLOueSm(s6-ddfan=MP(1aBnRAzz5^ZtFu z56%0GzSu+`28XZSyhG*&$5}a1b%}a-k~0o=+>uXpYmXf|Rd|!u=x&-QUo{sHc z)B-(f9Bqpp41FkW+jf&i@q(oSRY9HuPvDoLXwlZP8RrZZIcJ~~Y*^xHvf3ifz+Ryf z2r^1VA}bdJNHc98$yr}B-Ef(-Uv`)2mEvgaKRVCZb|bJ_^_>L%Vcq;OjG?bUNzo4& z>oj^j&J=5_Pg?UR@`Qp(&saK}WzFtc-h=De{<={dW?HDFv!%Z!>^bM_`xS0VZm?>w zZ|0POcdZEnHX=NUmvnX!JQ<_!x*$~vImj^xH+CooxAmhi0J2F3G$y|e2~3ME7M-H| z7_ZOstC3=Z9V7^=A@Wn~SUgr+{W`Py?T+-5x6C5_&&iiJwGUc~xV}rN>)ad*jai&s zEsu;X7P=I=usBpNBJC}3u4;)Uik`+kj`_rr>Rs%SnV-F1pD<}qQ^$qLgSy}bDo^u( z*?}14B*BT{IYFU;u1b83-w#5vRF%-1M0I@qVw^B_`zxu+_;(d8yFem0vD#fA1)(z5*>jV4_VF7F?@r5KFneR6c1>`x5_d&FTe>13^l8dTxA<*@Uq zPkYnniMEnr zWLN7`iq@$lyEssNr%~&zMpg}yVa^I)Il7KWa7;qBQlYK8f&tjqkAc|(oVSCINsP8z zKXOq+su5$6F{D}$x5|}-UCVTi5I_Ea>3UNk#O!6UvvjlK*-PZ`h?m!>xHEl4J6XRf zQK1YVsw&$LT2nZz6v`@Mv{k%PJJ~-wyd>Fp#u>}6;bnYf>GD$%$@M~f7I~?jIw6XF zCX$0oM9&{I4&-Qu4QZwmMDIgXqTXVS4=KKSym^DBsuXEJZx+j4cA}L?J)L5)iQ!ys zCs~5%J1kjqXo*^89^SNtP#1XczJVFyyiN^CAvsAv>f1rKD5D( zdWQ&WUt&S8AvQU`;UIJIro}e9P@P3>SPjv{lGke%Vdejlv1o1_1^Z90H_A z*jnB)p?Tyxy?KXR&lPB?rI01ve?cZ> z+_!DJZDu8yD-koXHf`=r9{-wFjyk=0uDm94D%Bu`d=HZiMwKjLgO+8DQC4O*6=f9) z7biDOL8zyt(#p<3BrfU6{jiZ?PH%AZoHuFHURY#P*02}gvD+YZh_ z3(Y9oY!8XcmiVVS=ZEKd@%U-a95eb5IU?#*zNB+*YepP6AYsvOoAdIt609g!S6iCl zbJ-PkBTiZw9lI7Sx6$K?aZ{TO0e08SP>1wcces7l*Ql>fm!54kZurSeBceeR-TLy5H0AGBdw%xC2e_25} zT+(srV!Y<{HYwAeHgF~Gc~dg zA)G-U4jbqlNb4jymhHNl6Od6pVd-7+W8zTum0Hk96}KIP?Iq+P36j(#3&wvs#uoFz zh|T!)wIsw$h$)koI=_0_p;OA}&mJ5r%-U4Lce9iwu&mGYQH*ws+VK^?0O?oz@?1wp znD#VU_O?!S$hVW>GEQwVII3}SDLfqFii>$@tjTQ&zm*NX1fku}It;wLTbl77cj9i@ zWTYFq$P3h-8N$VIeedQxNBf$UljISP{6-hOPe)|i^03||j z?c+J}jZa`-UXDpxLK4M#0omAO0VAlFBpUtoA}y5L%6HptL2mP2zInDC$>P+f0pyiM zU>hMBNU7(30|pFMscqWyaVas5vz{f-)W3kIvqdEj2|`W!)sujttZ7u_nximFfD~zTqqPT@ zT2Hz+$JTFu74n)Mz*P{yTsX8cN$XEx~-YR9#{ujBI+Y$5g6H;$+q191SE3D=} z`QeFvq@fcq3!CDkPg zj|(M^cEJ-WW8M%A6lQExN#F_biZU9@f(*fwmi-Gju!5b2gLF~XG_qj(Dh8`Svvnm$ z(H48NsXtcKq@;~9c}uA3!hh){G=b76601Vhwsh?t(7}PAy79UAb`Wy_XyKOmP2Jh& zWcI>3<*R`#|Aoe*t{(B%yj-$7U(kpzotNRY{+@Yg7+LloBWRxjnIrmD3V@Rul`(6wxOZvwm_srkRfLqKyzhMxUy3cF)(WbLXPzAf zn9T%=Xl>q8`Gf{f+RLIx^FfowNrf5uASTAM_X^ozHsE46@2m>o7$Y3p@fAo?ynK#oSLr9Gw znB|$MWhrq$F3I&o;^D#Xmh0P8Dg`cUND+ysq0<&mANo6iHOsr1s+1y>oh!; z9IFh#(1?=8gW(u|!i;BI5gth>(_me zi{uIFL*tQ1)7RUMN*5FNU)ZopCuLYDOa5ja1FByhD))Dwuh(Lz)?F=XHP2m(W|kz`L2 z3hDInr5+L;|48blDigWtW!lMiLEVJAgp`mdu2$nqs&qEJw!azDZq36il;hSBrMJCE zT>K%$2_O!+_Tcb-^t0SjQPH$Vru++#$(6g))sgu_=%fm5x|)sps&0AWGgyTG@*FQ` zQ(f+AtU!7vs@bYY8dy9RCIOMO37OXg&E}6)RIJ%BA01cOy$d|Q*%R*JEs--3AfvrQ z(b>e0b}Z%t>y>Q=14C+)hfOKXLunbL4~l|K)h>LHD0hXhYe!h`oh!!p8i!Gl$M@rW z(rdg%nQ0LDdK=9tM!hxSh~7_EdB+FD)6P(DTD$c%ql-Be^bU|)V8x3NHi7>svH0DH}Wg#25A`x6GDT+R-%ef_}D#3mH~d+Jp}Ce>nrlB($1hh8LmnqUm2 zeF<}nfKLXIY7m5Za%tH8)krN?x=(j8nwB67%vK=CB%kCz0l#+J^z^Wj!lg-r=jx=;y1H8`mjN0im>;Tb`r~?K;gL6c+~MWf(j~f z^h&po;hs>RrTVZw&q@Y%9<<*IV*Uc$myBRgJd_tam zR0>cp)HqxH@;?erxo)FbqUG0y{~-qaM;z4u)A^rw1O1r{c;|3w11MD*l4q4JoI zzjf%(r*8}+e*vP${E6>>0TK5vyoDk6FAGSAe!@^c{sM~LBZIHGBkJK009()Ir;39v z742%z296F#{s4YRgx%gEfXp0yXROGP-!dgqCYA%|*Q-$3VENhTfdag?&N56XPJyls zfE!`SME7`Eh?yj04}U76|9FoIzQji1%W)@q5`)HyK#4S z5ALpwJ3)gx3GVKVy9R<2+=IIlGz52df&_;kK{CD1-Z|&qb7$_HJ2O9K%|Ng2s@1FN z`}(V@r{4E@rHsTbHWM#Ik{RLF_oj{)jQvIrVeHe+gT`o9mzAZPzw02i3pNvKb8nhV zK@sdB;7r$UoetV~I}C&|%yAr1>rX@~Q%>@AKr^!Yo6Hrq4svH&^%CPQEu^qQ=W~h! zte`=GyPaQKgi0xCiWPVlj{KWqJ3AgM8D^9)3(me0K`%XwX+8nuel?Z)~wFANGQMRwL5|R$+%MW*0o%eD# zHBR{g+ZL1K9n<9l#lEv|am;lXO&o+K(T@U#fo6cO z*$mhYmA63oWyGZ3PX1#S8Prnndd;?|+!U(v zT7hrEj+_lcN|(uI1aC%mUsJi_k#3Wv5imMQYpo(#pJK}$h<$v8wgn0zcHliL0@P`a8#hP~u@p0^517WDj z=|cM3+1;1)<1}8UDW-|BL4CqjaWnuO!aeq~o-7pgT^Um%u2mEfx;qK8cZ)+y(Z_MS zj2upI14@u}-2*Q-ELW2!H-u88WZYDsBBM=2QO!s|}z278Itnl^06zwD2;ze2c;vN=#7~i@@(0t21BGa_`Ra>D9 z1++&g1h2$C#a+(}K&3kMybvWGxD7z=UlqX%s!HCE-+nM*S^1nyK{po?OjOnU^jaw_ z`+fP|IERxQCZNDwsBQdBZEiJ2Uq2RKvX)?9$i^1Y%00BxR&%>{E&enC#tf{o^ zLt$tqCoI~*JNpYiGb-KjEd#zxu~3N*MOoS~6gY>`4?QtZb*ou9x?{jGu&Hhycz)i? z6hXZmffzwDKUa6DnAI1KG?`0=YYjSoc-3IV#q+-PYXtUPg|VTTOy}@ z#}EB4UHILL52sP-STd)QGF7*2JuiHw?4@*nW(+cP;6djs{bhJ09AD`13Du^S}_ zek#qTBtXeGRsAqpIr>>QnGM`Tpq(;~A!*l^(oTT|oP=cQ-~`S@@Q@Xi2>4V1ym3&^ zA6+Y8Z_tWR!>Rj%KVivq{%4yJ%)l?SUgWin7iGd+DA)vx#;5fxZgo`!0{DIQF zi={_J`AJIZDAsy-3GTRjLSy8VMqzfowsMI0ZCp_1Abd-HXlB70rCA~p8ZYa$9Xmy- zTxF5#{8#ZQk~BlfA~u`dZh9$i696i-%!8H^6ee9Arh1S{+>b%`nrJH%(wXOc@RwhJ z%y~nD#Y%7|DJcWT_ND{FQeKZ85|!`2-TB%Q(p|!?v@>&PFnIRUK%@>;xXKHg#^>xv7veE<<(kIjU9V`qW@E(I~NsXcn zLjg^lO)UJMgQP}y0Eo1jp1%O8ybqwZ16J>^xh@CU|L+uR!$tcOLZa^3&|@z)UNu}8 zk@W%cSc9-v@rD)fQjA<^^P&&*E$keqw!QW0M`0stD}X75KTiO7_4HoMD5jnS^L7eI zq@;8halC{p@7oVAv4 zyE|+;r3_AsVGIk&Fikk(4_D*=K^nRRFfSR>m=G~A+u}gYg%?qUFiw>1(A5aFCn~TP z6NWbDrfW}&ZoPtjYK9?ynhH-4Qp-;ggkS*N8BiYV4V2Z<2Q1{2693iqCMpB@m z&gq#+noI=*K9G-ikqzEh(ZlN4PtOuAKjuys&?;iN#x%GAkW8Xxb_;T&82bn{l@k!- z+Gw!w98SwzW_j2^kPOvwWt0=7yGtmB4|!X$Tn=_-q_PQ*=LF@Lz^Rm+&7@xdoH8nE z($5V-R)iGgG}QXDFjTXw;|LxmG|p{yjKIdeIPM)WPa9J0=Dp?EN1XPu#`l}Ua^u%sK>o^PDAVPP30vS)Xh@Cgf6J49fr!n-@7Ev7CpOkgVE z;)R?;qz;$&xmA!iIeO-2ri9<}pb6qc0j;W?#L~!G6$O#3yJbnd(yl>soY4|M`FM)Y zEyg8(wH{{**m}?KlrnUv$_6qwvz2mABI>heikc6S*RX>mPloJ5x5};(dG>PF?mjy# z0jeEy41Fo{?wGzqg0_{z6wI=)1u9DnR4G!lx#X&#Z>+6)Qu0BnM+zMPGhOcvmp8q* zY+Thw{SC1>n6PlK(D{)PxdAD8qrxBW9=I;M((_YUO#IrGJD@_qI#q}7I&-(fgw>ju zOD(c=U){hWOAD|W_;A#@0q|lvB`LuMjB_{$IHX;WUn9-SI*jnnb6NGs>JUl!Lx*gOnM+OR5gA{V73=Y&5ERfi_f7Nt^QS)%_9X-& z2G$lxaTmkyXYKkFF{tXG*%)}+1APo5}JQ0ckEn>1WR zL}$0}60b_7uNdT_y5=!ZaJ8*+cfE%6oZxWHip$sn3FuVoGkg;Xwt-z~PUA+SO-pAlQK4^%nUg}H;+7F(#_+NZgPl@G(|!r?Z<1dW75Uf~I3 zAMaj03Iq_ITx`Ji4L~-MM$B9+(#uV3B+?U@%JFv2QW!&$>h&L!)F+Qfp`P<R4@ujFQFJhEifjeFTm`M&S7<)1k zcThVNnA{1kZyBv6`9?3`wWdR+5UdM63eys#I;48Uyz=xuLyA*qlIYNU-_tgkCz4Ct z`!^-^HfDz2t}{YwIdR^1t;!dUV?}|q0llx+2_C-R%Mp7Sg8Akkdm5nmL4X7#e3Vu0 zGxaAQD|?$n0ZAOH5h%oQ`e`zUx-BBcH~4+NwQdd=x76r8>Lkr*?KW^>nwFzjqJftW z=#bcboEt)2uJ(!VLRDuC?Gxw7GK6$>nWqV6mM*{lO_$P@c|TL!dO1RG?LfryUEx3H zUOiQg4~OBjKly`cCLa|n_a!;LD;6OdanzE`7OtZbvV}BoNt3=j54+lkRPc}(9BqYT z5}wDn73!DJ{0o3;7|eOJVOhoT9mS`gtakYS?m`Gz-f$VmF^bRM3;*MLh7t^u;y
    Tit$8u|-#WkKkK<1e#itmSn2y~}ob-F~N;QwG7oP(D z5bY=L|7n>11`&N#y@ChcIo~`pHZ1>@j|h7RA2IcN`TbnJ%_{vCvaGQ} z2K)jX#9_fVK=7w;Y9Qy;-lUOO#__?mh{20x<;Srft`E7@fn4*G-+bDhCbj>?uUuPU zi&r!?I-Mpa;ewi=IuFr$dnGX8sxPG;ccFKakd;^p7ObH?A-%$mYiBf%LmT*W>Q4b; zRC$TN0QG}pDG0%8tZPL-hn4hFk{6<8r?U=P0+DKUs zuX?N#f>Z@??+;ojs1=8zoNrRkV1&nNYz}LJ8{Cfa(?s?dp!J|((V%Rcm!;L0N!s*e zl}|p`98kt4y=z4oATk_2OL$OY6VSG_ks~X@j#Ya_D9L7~i}p$T<0a&0nsK$}vwHjM z?*Fh%o6j|V^Z#Q}XUFQ~{W1h`w_1H=%5?fXO5I@!aaNHRH7e1<3(_TchBOXpbWUB! zoGVJPM!yeGR}XH`iY5p?)bwNUVXH|C)0ecfqLHe_Q7LoF9JhFtG_Flyd^IsT zc!z?M2P~jVg3BFWSH$g>&uag`Bo$n4b%euM z8ODCx5S#%algkDSyD!X40OCWa$}%tc1s)r9JSeO-m;(1eP*w{wm5d<6o`gSp`q%*p zGSc)SkVdQiD;adri)I*LAK~#`e3dob0!W-1B;Ml7&^pTVmMD`;F*Ohjgu$r`qe{E!%gW z#gRAxnNI+LG4_%ervZ{* zlY=o>un6s(Bgo%zBzUPUuh z$iqZCkWzEc`8<=1uNytrBsTZOiN=ITLn{nMlg~R1*&Y0j|j^ zsDKMf1sh3RGx_6CZ+Gs%2xT#cwDShbKaY@BaDwFGz?`RWg@(D#cR}P8Mj1uo(L`zr zRCVYMN=xgBGP~mSoS(A@P7b$QgM;}BZW@Hv65I%Vu3v=tf-amP1pQ_1pL`&Mz=tfH zXQDP#HzKKTqDumfdoxJ&JlHlxrc4h8szMS}IXQ?pFMQ={c3qM;;}gdRU@8>mloJND z78^=0L%KEm^k-ZI+~iP0Y+CftSp@eJE;qlSn64t9yFDd4ADj}W4YZeSyWtOm$>+G! z=tuwtto)`{({PO`y7YE1F8mW9M;I~Q6q8}V<0GaZOVf-!+QJLUt0pM$$pSV?CRjk> z^Gmyayu%wFT6cJ1Jd+&nt%vD_ODp7-X771Qi{jR4U!!IPO6?-6I2%a^28>JMcvI`X zD%2TDCzcNgz|o93ln^lMvtcMAYzwPVyf~8jEOdsOX@7@fHvF45Gw8fNx33?Faii?$ z!3Tb$VX{f}-1qsI2-o=Li*{!0W;2X??+v)PgffG|Ht<^t*Q2 z?;Xhx<&1M{D*{ID$@dT{CgR|`RyJ^%|+U}x_W}Vk)7Cp(CYi(0*8A1B~s7^C^zLoDwGofpo{M}(>yfYTzchq1ILC0BP~@6-G(O zJ+S9U9)q<%;L`E?F{TuN43`)8q`q(G(xqM@{~lT zdoBbwlmJcZYm=Tj?&*flX|weLGekC*F76!p#{g=~-D*^vO!}H;S#W~p&;^umX_bc? zDFV@vva)sP!u6JLEMG zv4<@atNv7ru~XkjQ|H%Ue6C3il0?q z0(&&hsI-vs>2Y$Cu)uKho*0hgh$Oy>00$55^AccD2caU-Ka-r_#+<{xWjQ)Nj3Z$-Bk%6(8xI@(xZod-6v zx(vhlbUMXfw9MPl()&`oY3Y#$SVjeDQ63T-;YyQt!< zYLTuNR8V%|xAcie!lwF(j;94CYsdQPzya+V5l*T|5)|{ww&n#JB2(WlQKD!{%bm?+ zWk;R2`dTcmRzsEjM0{`T(27)g%*yyMQ0dv~PCe9SP3Zvk;3BRAh@%n&fJApv#pR{n zSy2|j;8OtKz=)jmg5OH1e98W5B{5KKh5+DO*^h3#8~5$6FnSUI;Ct2H0E2%F+=O$F zW2;Eq?t5~Qg^uK4WCRF*JiqH!?C@{q?>YEqjiN46hc{W;E&cL`Lp-~I)G03P%E|yK zLje>6k=3y$j~t?%QZFJSK-$Nam4}7_Dc{NnTf>2k0_3)ePOVkll9o@5givMgg7>4> z5u;$ely&i2jj@@8h!gj>QoK+~o~Flh><^-DI($$QreVDTH~CbH!UVp+uVDjQbIUrs zod&Hz^wYCDjS^Qn7VOD!U_g)x$J>tM$S`f2wrdQi)|y=tNqxV{w$_@+RX z*AJzwG0fyC$5+1q+kdF_anDdF+t_NMz$~itMu)V>!`ZHUjUf;#@8J1ZFQ&^ilHs2!F{T=MrAw;oU}9r#F19kh!Y&hAcy=6 z5Ma%XWyc0xotDoYxq&P^CP^QbLc*gJH|4pa`xn6OGxF;DM_-fJLHSi}Txv+_)!)XN zz#_r0Qryp#P+%6`EzIwpZO*V{HE?$kWv`usJSiv=QC*`}-~cO?eGyRU!8*~NtJHC( z^7cZbc+TGA5t7Q7yfE%QdFe`ciIs5q%J0?B(QHdwimCQ6S+q4UGbNDTIdIJHPdhWb zq8wzP>%ixMH*k$%W}EP>`M2it3j>k*w;$;>saF9Dbh=kXAkq{=vvgNmM_C&-_g=g@H^%gWF*J=2NIP!sT$=8*sAFj@@^TNu%Sp<*{ikDk8`mTZs_b#6_IT3~j)g z2ZB98@n2!XLp`|-V%Roq$e=DkAWQ!DR?PI{dI^NKJg0w*2%+L(61)w=yrwk?f~0I? z_!ex}O;}D=I-1&E`nWWJx90Cq^wWXK(|QGbYyUm+Ys`0MWzr;U6+$n8ekBAPnvY^; zvm8KbXvA>eLJq>huDUfV_LCw~SJPGy(Pvw_xi)SGjsW7#;D8Hshk$vZwXKrj*e z6WD){F*rGT3?>-HD?*Yk65xpzEhtGd5bE$D5~)HfY-OVMM1~K23{m(EE)M-Cr@LQ( zSTd%0!%AaUb_zl@?0QSi6^uHj^k4w$Z7YlalRXu{D-8_AhJ^dThM|ToYVJ7$6^cU2h%QjoV$eM_x$oE7<}8)Zs0`ndZ&J`UD?y9CqoXxq-Ft*SS!=JiA6=c5G8a8bv#@g(QzjZkWy zaOPz)BmoJHT&q$i&?Fm5R{;|1PK6*`cv;^8$2cG;9Jm~=X+*&t=2S6S8Lh2G{MbBK%=L1MmOz(rh z4e!mn|6vUuh0l?jHOstK#6^tlZjxE7=N{&0OUV@>N`<=d7r-%FVu(dK#IE)pw~@dL zw0HjM$E489H6&?e=XKAy@cHAvSc4yPDA8|eKZvPm_+msid`N<1QrPASs+Hi5f9M`-?bw^PB5lkL;g`l);i*=FqXr246H z6X^Q1)0F-!eIFq;-)g{I3L&=xrPUR3eBrDY+!XB8l4}3tmLGV~9S+1B{qe{&8R->G zQ1Q|#s-dbGzn49hd$2PtI(46faI$NxT&bG1W_W&{VZ<5}NS^eP*FF89#+`F+NO854 zEbQD#j?%D#{}cO{a@eqyxYkli04dBqY41<=$i7xX`jkSo_Mu!C3BuWA$}hz&&BOS; z0opq)yt)znqNct30wBbY1#-Bou;G{}u2KrvgcVi5&|8 zbB7cqlLEN5bwAWAC(Ky_o@gKlrj>5;l(w(7pYjL9xxszi%<}c`>)fBRg&Yp?pP&rM zx4gRRbcawbfyHwX&ls}!+`=?tZt4s2bcP8|zXZDJKI@Wu2+Z80k3PNmF)(gGkdk@h z8e@Nm38U&a2_c^Tw8H#l8YTaUKH^1w&|cGMyx<;jEq^vOf;yc_stK9(t`QI5e`t97 zQi^II_+$(t7>_5~csB4;&G5P3KWU`v85COVC~^vrlYo8>-M}dHm=DuGf_s9W_T=vc zwSA$?Z;aDBl?)!dUP=%Fg2VTY@uEN<{JY)jU?7q3s~0YafcG%{!N1|9p)4@d*z@*+ zE2dOs_S4w}*-{ewXsD2?H8?6Ziju)u=x1e`;R=v0r<2@2SdSY!T82XL0(*Mfh!@iy;uVdCz)*_E(>>i>yM4kZpH zESdja3LunCPOyXsAFeq?xadwbTEM1mzNg_yYZ+4dPd z2H`S8m$s&3pp-=|b7j~g=%kK`1K=JF@VZ}klK{es@vf>m4`X~1guy$M?-C7T)hPKV ztKD@D@ZMyK$P&c$!y+J&frYx7`MaU7dXT%kYFirG;kGe~J%h%ja}sHoKtL_p;R;Cs z@w^Veqqtp8v95)xmJ3GNAA_oT^~a#z{#F2<2!lR0S92b=52~b9iB{Cu=B?A5-=+c> zJT##YK7i0T=CoIiU=QM5yy8tl{F}u!6Sc`7S>=me^Ge=-%~t5n3u;18 zDTe;^IUn|i=TxoU2E&j(xeGu?{1a*H`;GfQ&09{gKEpPLXqC%}b{Cs!KOUT~e*ui% zt^{^rP@_6j9Fyj(e4XA^6FzqP1&9yQL|f$1w}br!2!Sv~tDY5743$Jj!JV+-#_#zj zT6ZGx*af79yg~s>>hjd%(`I04jWWNC3(B0T)3kcJ%|>z zzaocIWt_@?T-vaP)lHGhwUs*l9U2(INXJ#H&~c#2t(|fiuwSsN4bnZPM&Di+dhrHp zX$sb8{~nsV0bICs40q#~T70&4%oH)($}QXHhcxS#)++tiUDtj$w+sTX?U(Dr(+D>z z^U19zXEIUKV%znB9xZiVKeIIoCfnT58=@*?GZTskHw!ZY`MylLpWq_{~;{>+4YGVcU#{uB=wA|Jrjp)cJqtd z&fRd2z-8$LN^-*$L1~Mx+~I4|SY6;m3{H#Ux@?=tn_f>xI&U8XMPrE{n214H zvJ@>m5-JvvS9P*3&@7C=Uc4>UApJQUdJtfao&V0g4ge!Llka<#jS#bgGZ1|4)F;dF z-2xQ`CUesRbgs(}nu`Ax6HPrrs>nG`cO?nim?w_WIl$=qCzy)){`0jw@5EF ze$Bz=^ zVlHhNajuWz4cuyh4DWZ>HeExQOcst`4MO}cAlY~WGB!pwHyfwea|uhv$&lA42;$JU zq;h%;9anoF)B?_j-<2Qt4} zlht;4-rfgmn;DV%Gou%pMg6dXcFpEY_oz)AQ!Oozii!>`!|qdj`q64xwr*ricy)}a z-LO%9b@xigbM7wY1septpRe8ARlDx(o46ziq@9vI_9efZdT;EXC!c>b{bBP3Hrn>} zDv3?ZQL5@xuG_)P=DS9#9p9hwj{`mOLs@09xG0Zi*5Osgg`2rWzW`iwAHSh-$@y%{ zF7=ipXyRQbZ8q4|MBr7l;wW^gRN_5U*l(p|`@xlC z$+}Jqvc7l4E)gDfIAXflUXwk@|JAgxY_$TejXL|66!dm%-rw%y!G}8EXsz-N4oR04dQ`o1ukWFeOtNp z(C0Zy57m&$KlG=n@E{PQ-mCp_2FZCH$fUbPPz|^reM>|uE z*74!A`^$&G(*1Ua?(X~~j-BIZF(Uui^@K|SY8bVXVQ;MSt|{c*wq>3m$dig*=(o_~rasdct} z?7>$w3#%6#ch9dK*ReBcCeI|HatOiKVRSo>cg`x9V@MXu83X*<80G1*iyrYwx}4*b zEtpa@CNwZ884PxoL=DgEq^n*u%j-Ykb(uy>LWQ!RVZ|WI z$%O5%LiCFt`WOHy5k~wThTh0-N+mhgI}{vOvS!c}NdD8EnP{;1fht~c&8*9`T09Mv z1XhO@|2ql3JWe?U-j%Gsbc=wy-;(U`#XM5w*GpviYO=`EISq)T*B@@IVq;hgVu_-k z{Ab5HUOU`V-Uv5A+%TMSI^i7y>u&Bp%aoEpRet!Y(9XuywEyUK4?BTxi9M+j!PR!j z22n|l&VH0v?-_TTlFi}nN_F}Ahl6mHpvif^tN7-iEn8}kqc%7&-N#2BHt4o{D%v*M zdsaMxMqsC#M6_&cNx34L6-U}%+o0#|b;cCk=KqXWfbwS0Lf2Hml#+!Z2DGX|%PGAv zE!>H;QqBQ{=elup)?V+2z^%{7H^YBbe3NvV=5lvQ*S^MrJ5$^^TSYm%3h(BjKC4x| zh8?~2{;kAoSYCFgJmwow9^3ByPdja_P#CH@Z%V0Uu#hCdPzE5DJbsQQW0G`U=DGr+ z-Dj$OLamYgyFMH6u>=u`Q=2T3N|XKbx3uES(J2^FmO_uh5ISi_fN(C9+k1v3z_iq| z2(IT}io`$mK0AHG;5j0mfd2A#?7{F9dJ#)PvApikcBs{IJVI;Btur&oYYDYCFQ&?{ zwYow)ofQ-21(@T9!&S6VQk1wN5rW-G+h9p?U(+c5a4VcQAiUEdLk>_QlUG{&C;%KW)$nx+yI_IfKH1namQBeFR6*TDDJ0$*CpThw3j%`}S zp*$j#**8Q72_`#wuq(Z=XkaZ9R^dZfP9UdMaPhc1Ma%ao7wB0QmRNchy+Fo0ktT%& zZ}eC55hDSxPB4s^a8Vm{Jm!0f=xr){_X!Y5dBH9@$XnTl z=))*sUx%`;(q5xM2tt-txcBA{2zz6i)fzo3E^7)VI=Is0eo8tUox#Ih3%b_1+Xl1R z=TyGkSQI}031MRzAQVg0b-AGs*kL*>M45bZ{%!hiZ?Jp zM<}eGctWwa8M#8VHq2TMCOI|=;QwGyt79hQ| z18{Y%V+B#!hkadPWKV^MamI8W0)e!8Nn0k++~>M=@-)$4@SyL1p6LSQIAE94GC$F< zurnha=Zk!I{8P((;SS%w;=1Y$UL0QcPP2}N)$wR+Cc_-`_5YefZM4;ce7+j@4vyd^ z!A{mz-69{jr4kX0Ij=?{lTlQ#Hc)8*;ge;wWy)Kf@|T)J&KYBDs%G%5(?kcH;8`SM;z)Sj@A{6rOm7wD2NO%JRF23`!IR97u02JG zo*Y8XieVQM#kzg3k{Um{=-&g=q1~_TBs*q2e@PCBB`XVuGowaS;uK=SM0Fk_wul^}n? zR0pAr3Yua5ST8Jkqtqa0KcL36gb0MDQ_v?Is`>>`g7>(xOe-E}x?xkpNGEJ`L3Y)o z`6idZgyTuUIg>{Mbbv*`?Gl#=1)xeo$6DTy$G0Z<$EOT?k^3b6a0fIwV-3W$VM*}&ZG=Z>LlA)wv1T5g=qf|-ZtTx0Z~QN59N&iteaRXy+(Tx=ehe5V8kY8G^UH6OsRi7T{dUyMaVHum zF2WIxs%Ryhr$h=pEJSu8?|tROPQXBu!cO}6`m|zc@wKTDXZcEMC>&U+HTEApZ(eh`M%`X6&EX6bN+0)m?uf&qFl3ypDXOJgXLN0wjct+xgUgIiM zbZBp-L8qCcsXaK}{DC{i=V#iuYD1trl#m<#^Jw5#WCM0t&A6E7^OhG7G2-N`CebiY0CU zwmWWzZCW2jWD*Szpvkax#hwnu6k88k_MK390sw|SKnD($x2AXUHHO$TxuP^o?!pzTu+(>EZ)n?l z8S7|S675I(_Y~g?Bl_o*M@t{y28ZQ~)6PF#UGLB4eH+3C*sS9*Wh&u+;p6`3IfwsRI%#CpJ2 z3!4cC9^@@z!5Rr_(@h$_w(;`{(n&+`vQ<_MDllWJ1ODOU>B&tKBS?@<*{UfgR$1#lyY` zW<5-c5{@uh+QSdly;2R>ICPOznKxf93XngGyrK7D5<~yP52tIp`)I*bA6&BuoJIq8 zG~qbf@IHQQ3CcDU^vH4atQR(2(2760o%q{p(8jN-qjXj1zy3nazv}pCp}zG>_Z5WC z-o5MoYr*{v-+ghXL3l{m7RBQ!J;V8k$9}+f27+=mDuw^5bw<{JQCPG8rlt)R#CS8P z8U4xveX;*<0DG|GxfYF;~4(2AnKL`_9u?_?JL`5zp( zulk;cg$E&NxU6Z|fTgTy($ZhG|FmG@O#ZYM-%kzjL*Ebhhg|cUi#`z7&pVO5yeP(Z zh`MwTzXrI!$hLA%6a(zF^W)WZwcoA^x%~vruIn7Om~r3XJd0987~^Id1J`Z}9oNDV z`Y?9nbS?Bu$O$WX_z1u*5F<0RpoLZ7qe^Ba6ke9q==58k+dRSVr#ZgIxNot!PZoMc z|2_e02G6d#hquL;E;<(cv1)kPOUmO5^hZ=M%}u)Hw>4ud_q;megZ|tozP9;rm-(T+xTF9X91F*K#)On z5@z9wAmEY|P#>aHGxXg37Da4B+*0G$t=25|EsLktVW7lkE?&%(51~heS zt$ekL^9ij{f}81)Vh8WQ8$?+YZ)|@3*mIY(A^^os1gBu_+b>l1CQb;QH?%4#nDw3K zZKWR2-Ox)2q=}4sQQB@Ir^z2dMG%WD&+_c3E-@X!^2p-`F9zwSx}bG3A+;dG#z~q}l*iz~2 zWYgHp*IqjFK{Os~_6^w**xB%)f`^DQ-WD~bN__QU86m0H>*aF*RBsOy%BFY8P-=A| z=f8JYie5_0?O_M{E|~K}_p6WaqfSJ&1wUOOO3{ObX`kKG%`bq0;O)*)k`)30uoVh=6WFgkDvj0-7FJvL$#8GkKn2H6}45P zehg~8=?44BtkMw$c9fD4*Q{leiU(oSl8SVA`(7_@wnSwy)Q-_d^3Z>4`8uU4We%e` zl2$ke6Yo`QG7wfls`%8F{8grg5(?sX(VB!L68HYp9j5td>_I#GUP$7+ZB^tv^;Qh= z!8ieejDN=6Jh|K*3k7GJ<}87P0K3~ye?FSWw?W5tf@p;ebju?*{LSz?#SxD~%gM3DqM&_ROXssy zGGw=RR3OqCB-(cpwwkzI8Qi4_!TdD1uzVI?87fy)TsW_ebYGWiQIAW*QZR*c6x3!V z^v#V_q||{|$s!EE&rsJ{Yl-XP?GA&4Y^$(SzXC0b6h2LM!td>y08J?~gGBJ@I6@{zYu?tm8rveHOa(>31O~aJR;By&9;WJHTIj%4yXp+h$;3pJ7eb_KEyUJ z3&x+-lpv#2M6m|BZMYjgv4+l{4Z{Y77R2$=T~*DQMj?0MruJEpbnY0kmYrkqNN0{z z@n#=5Zm+!yA^nb4&j29luSTJv2=hW-Ty17zfc_4Kq7uTcX_549c7%o628$OVQMtV8 z6Zx$w|MswSLM=&I{Ql@;#<+-dxr1`2-`&guekNi=mUx3kx+{M?|tvz$HWA~ns|Ulb41OF0}0Z+p|E4lL6X zUFc+ys8%#`ZNrgUmEbi2E$>=~$F(UZGV$0D%<_Y+k=vZOmnZD{aX-A(Y_{5AX*WPp zEd~o|ctK*#+9@P3mNIwgctB1}ED{9r8@x#XLSZefQ6T4-UMEOoL)rIHkCwPMn3nZU2*&jSvt<1;qq+1HJ1w*n8+8Q}d zUtL)~!2z$)Ujh25E~uj9#c{Z|R@^IdQz&4)iR}h7ka79M&4!r<1~h-*s~?1cV^#RT zbXjz>u88AN4Jo6l88=qcd~$FWNjZ>&k<8~!P-A=RxwftM(z8t)HnVM75O}`f2{%N# zn^EVz=-|^~_vb(<(8n$>uPR)(I7Qb>@nQXjZZo(9+o@k>U7+*{jObMspz-57?%A5h zTEzh(qm4&I`*@+L*%<|D`jN()o*&)I8wCD!c zp4K71R;Dd2P#RQXyi=i1-BK)BMZlR<|zpq!N!i3Qb zVAN~9845_S@y{ld5H%kd_b?VlRjEN9oMd>puyGgtxQH)q`93=$_h~<)XMB;L>-uGx zvWW;6E?8q^b>U#CCUsKu<$AKGvo!1JfZRAi8)kR>?jRYG`~tMr;(A@*^ZL8w;~rEt~w$-6z_8Y~_Ul6$-lYBmsnHI}zuCt9+yi4%A>KU^DU zUoW1+Z+EV@re!`Ik^x z`kUC^9cK1NNz&KXG@hi--w2{rO?>0K?|=Xp061_^ih_sfR0INAtZEhFLg*7tw_(6v z001e(r@Uw`B<}9WSlUU}oiV1(>?e9wNDO8EX0_3s<4^#^OK#GI)4Dt#V2EUB=56ui z9leAXdqiYsFZ+;sEEeku$dm}GntoILa>m>!sJbA#CT(<|st-Eve5qy^z!FZ^ZG7nDJ_&SXk>|>s~b&O>OmNa@T zwRqZo9Zj*?os%_j8P9;!(<)Qw`Qa<7#AUJf#?My%`q5oE&I7(YJ@X<0?k|GzB!tSnb1qm){e6r@8KFwXU*BbGGU9t z#V$dzO%H(sDAIJL(~ddUzR%9a#tnP7LYkw_2?3d1-RCy^xOpU~Igg^@^wg)y8KsUr zS>6^uz)mAZtG(CO0Nb0}~ZgUaQ&4cMhEgV*UfB0UKS)@vbb`(SjPc4lbBCxW~7vopVnA zjlI8&YP0>;0Pz@3QrumGOL1uf2`5PHMZ=e4q z;QHSuFaU!3(UU%FIUa{s-=>gnY&=#E^S>%buAB|YY{8Ob?4J5`*THxjd&8(bawhqN zW*q;^9FkCcDb3J)d1k$#M{nxl7$3gOP&^_n*I|@?X&wvqi z0j0o+t9!{M;pb)z9v6L+03!q+(1@oU*PUFAQ=1n_neUxEHOgrN--TF7-Z~TFTLl11gZ@p&pgj z%PCKrSp*LKP2vMqt7mT2^|}@}tf-B^4TQDOlekKqSRTkBKaP_B4-AITa#JkS2lj z%sPflo`YJfafN;q5PVQiXRrpYpd2YJd;R{zA*{_A;FC-}pm~-pk77L>)+o zo|b;Ih1qW{U0(IAK21{!GT|IbZc;U`izehTivyEyEqh&!4V{83DJ|4)K+u0@p#LGLa>Wyd9DCL$J1%neRuMg%lYh#=eKJ?0 zg_;T=j6h0330^{?-P)CG+s?4zE#zY&=p~UaR)V#B@J)pRs${p&2k}Up#RpjX8Fg4k z(9`0|aWCg#1X1(wWiM+E+f=Nkz&kFPKfZBrf_$AR$E9B&VPfuG<4th^-xFeq6k1?ue(hAU1k5an|{;rV8HHW3f8c-Gf&}p!V@2od`bbG z9=VfB_EJ#!fbV1Zo^35vLl4Fng}o34D>7qx%>Cn2DFp%4Uh@~GvGDJ$IJic^nR~>@ z7ZZ^3p19NzNv2)ll-++N?*0;l)5>jPJ?U_nCpS4rZ|%v2!_@5DJGz&88!d{9VzRZh zjbJDB@?CG3L$$DW)u&dh;9aD?HVu46-eiR!OJ-j`r(~Q9G2qV>@S;S$ZC|jicL8YNeuUq-T1?>LPua;IR3>yfSo^mGy6aPuxI&{ zIU1)Po%wTNglr$aJ1D=CCBul^zFxi7#faR#^!UH|QQPT<&q06W6fy9H5ei~k?7406 zIs>h&8Wc!+ji#jCyumf2RcZ8ShSg2ltu;Z>R7>c(>nwjpr97dyRoNH+$+YCSlrVkY zbzxgeFh1<#BlFbduzlqrq6!!JY;FnSRB?PMF{!J8XMHhH!H_TXqFNvNKbIU(0gZ|r zL_gERgJrlq#+$NS{4KPaIepm`_^50Dom1m+rBNH8w{(^+DSpIB=*h9iCcIos+LQDYu)fof!gmxTYf5;dOA9>k zD>&J30n60_<)I*6l=1-*rEFnD=2S=k- z<;+&me3w>{x5NPulhRteo8IW@h0lY|&5v_RrbF!y%5vVsVshPIRDTwOP`w_XPrWBS z-L6Fnl@wns$?b*Tw`7(y@ATwTm70^a$eq_8=mH6qace`Jm&|n7iOjG&j2=IyWNfQ( zCZ4`0Av%fneo}nf&xzS)@I#blaZcY52fkc4p3Qe%Urk7GIzoq?Q=FgV>16WPzVa-t z`^Z_ z{R4=XWag85@UrpJumVI%Zu*Wg)cd-ZR$Agh%87(Wv?!Oxf48k7$-GzgdBZFbZq&)6 zKU~O5OT%r&U6}C{{dk+e3W9Nrr9k3T`14o4c3d$J1~ox#cPez@s@A$PH$5v+kt`&} zk;+kdwzBUc;>Qm+d<*uznaW@bElRInZasG6A1_gpG;J#d<(tD<1H>v$u#B$3`UrF^rw#%@J*igNAlNrNv(OAkLp~Q+KH>!&mKvC(sg|L(@uGMfl=3e$z9YR z&V?dVz?RscL&rDnTDDpLI+~Hj2k+s9>s=dDg{3^`dL`U_iLaPs`Q_9f zMK8At8~M(()hj}1M35_AqgOgg3_6i^&EsI?+W%} z6{7N+4bcl);e75a#OsBnCe84Q%rja)9n?4PDI6QN;F$+N+n%qxoOmlNZf=P;?ZilwbFW{#36urKVv%yv+WzI>l_@$l+5Erv>3Op4JR+q;bqU4+TCo}VCxC0-Yzt_(z@P`W{f)UdoH`3*)g&JmEaaAQ9?yOpuqNSAuSl9`O4+w!KNe?~?McQ%W8)A9pZnZp?TNX0S_0BS;v+dE>jBZr5GOW;6 z%Um~ePvQFhCYY1q`N<5I*N+g!7!>|)Z49hmW67~bNw1xB&! zKLQ%Rx!Qus4Y0AtXoF-I?G4@u^Jw7&A(xaQZ7ywBz|n_tzMvu>vqT5;Lv#U);(3z` zjTW?I%XsU@*Pd*E#V1>L9)I5mpaPT*;tEDcfOavWX9mMH0m9;Dv`$c6W9{xiS;u!j zNefDvJlOn67^31CzGrhpK?1+GPcO~2!2&(ExaARi@VbaBw8hK& z{ll;8e-EDjw02!Sp@tPGMuz% zfK^=|Tl^LTiGujc*jQl|6!MjmNFFb^rr1f7Z7L4#g3f{D`UU@OfaiQ3_}3t~sYkDSv+txhL*|)V8U7 zsnN>76&+DWpLWVS3Q{fd1JT+93mTC8EV}@?->rMp+ye!{i#Rxr*~`JdAUb)v6IHU%4P|D-?Gig@a zZx2242>r!wioWjSHVT8c1_lKs)tEBN%#c32!ZaxU=d72Fe`l*k!cDCp^=hmqL5?HZ z0sRD*K9ZxoEPAbcqN`A#Ywd^ z=XNw)LuRjlE~g`vW+g{kYKt0weEH>%%i4RQH@sx{LfD1isUlMjh9fN4K&&cGK3Q8a zeCWoj7h2;rhdt(=Wu*h<6J?>eubUt^+of5Nek5SO#q&%ZYxFi7ew$mmmsv6e8fsX5 z`RT9m{$`19z55}gZ6OevtKY=b?^~mShls|Ba!(q zcIXS2Y5~IW^||UjX;tu40UZLa#dhw@VXn-&Xi4eI`0QK$|6b?cFxq*T7$d5UO3vZ` zVGYfHZiitAvwr;daa6I~OzGS=gL~eV$b|6tSG8h~6@Q!jq)7j2EIj>VjWWfWJq(9C zb!%9~Sbu1;rw@RChOieHbzv)cMM$0kU0mYZ^r5n;sJ6*7&x-$2_856R;5w^+#<`k6 zLGe`Gvd6rQ*@RwR=KYGQoR>}_Rn}lXWj&j8h)s9{b`GzKy4DYiZ~!K^*i)R8)F_b{ zeb1Jt>OM47hF7FJKd0~gUcHklJa&dVgaH42px{Y{ZgVuaUN{?sb-M9_LZ0ne!}1It z_VahjQ9FB@P~zj%qj{re)J8uu9z5KtFj&K*rH_CM4H#< zi#z`=Km@7be+emJir*D zYCpLXrV1rR+--XC2J@i}JTa5&%uD55D^%wUoQ`(Y1o=A^5~}OXkO95HAbhHDRO-lCznfT2OpT4>7ie|xY)x? zf)D@VD$s+LGsWVFe1d}y=b8pasV3=#FsbSp2=2t%SjdHKNV+C<;5RfJFYw|!sB+Kd zBHYsls+CMl9FY4__v+m<0sv-i^0NR4Z$ncAOpY@2Al@Aso0(oMMpg;Yx4&-6g6r)X z+19+U6r48N&|#N=8aM}P<)-Hi=8CL7$QbfqbYgV@FRvZcWyrB;I5IB}^gli{-g|1L9 zkT?Lrai>J|Oxu{RgUbfbuQjrCBIN_Or5UGEDqj1CC)^?00^Y*X0ij{=OY+ijI%Vw6 zt*XEA#73aVgfNPWD)Yl(a| z4`WuALIz*k2T2Q}TeS%mh)ILhd>9GaGMiXm37_9A!LxNCGOq_#uCE5F93Yvwkym~ z(=Ge@6+sFm&IFuBY3HK8BgDwaLdPQI&8JjaMpL*~Thy=itpiG%km>;b{zgR*5YL(5 zY3%#n=vwo(wG)r=oN0brsk@i_d=vM3ZKV_Lzhn%wdSs2ul@(G2PBJ>y(b2BWzE2Zr zqEHMPGNJ~8mRktXc*!Y9H>zs_tzcW2aBw}ZHcGWYl8ghPbiEx+ure*LzUKf3+|yRp zga})`%91lP=!=Vo$B|Jem)^^4_#B4Qkl=#>a<0D6i6r$G^A;G!b+Rt-SeYGo_cK?F zSoMIt{Gac2J_^F1f!~EN+G;1PE&E6)U-)KQ*7gHJc^BhXtC*SMii{_xfGtCjF+O2S zDPvs?h74lr1{sTRC<#F8!*%WRNp4^1cQuqxG zpTfh>QCI7mA2JNeuGPkOhb00&dj^lXo}Ldbn9Mqip^65?rEMEUh3yRGv|!1tD(Uq^ z`$-}pqMuEFiZiA@Z+fqBiBkY0sFkL|EqG&$U^&7*vG#34`6Cyd@VQA(n=SnHnCea4 z;%w+$d1>rX%vB@u8U4;^K)I7xn~(O${HO*w$JLuZ73Fhn-+e1Z!84#vFga@3$a4(J zry)nZx%Co<^<#!Ssf{>RJo)NE#HrR^MhK_^%gWp0 zLcn_ZNOcIYenzvq?E*5pQPoF$w3l(F#nK99b;RVQ@`+h`4Gx~jIV*Xz1^!Ea_S(?8)f0C-mlxj;=SbI0fdPe5-lS4ZyL*XOt~ z)fjQ#yjMh7^(8#Y$h^yhdUN)U(xA$6%GF^A?& zO6JD_BK@fr!Li6mkx%o4-Ka-zt@c3TZyqvsJ7oF~682W?bV7Fgj26A^(f|t_POnyX za3{>ZZGZFEctqp%IWrU=-zT~_sX=D}$jvfWXpEZtrv9^AM!^q@l=Zc_-+je0ThsnG z>Qv%H+SRy)r3d*)YEfD{1wlSq!n)c#9Qh%S{7N))V<23l?j}dT#Xdzy0Nlvhn!^Nt zGDx09Qq~3Pb6S7bM{ys(V?XB7Au^;&Wh5HlbQbS>Z)993YPs`Jw-z3&MHhk3&O#8* z$re}jD=iy^%XL3R7E+C6!E&XMq>O7O#f1RHPgel+LUJvC%nO^&mmCM(MO-{Q_@h8w zf5D?G>c^eHjeXMZf9liIA-WYt>%8SYoe)@b_?(PoyZ1_R7)jqv)> z`6)7N3ah2H$GNVTY-JuqQ(>sOcuF+mw@p5s2uaAJ8U_G%km3 zNf;%+B`e|D2SMbRGr&L;{Pwv4N6b8QSjgsdfT91KTJsxzp#lyCxr?|}uWZ(A49{Cb zj*q5P`3Fwf@mWay1Fv`|&gXwx0Pl)SV3lZ?MdA#>v6mG7EZ4*5&J2V|$XuxLOjKiG zo7=!i^YL1;W{o_S==#&Cn6Fy8@2pI_H2YYRih_GRbD+*``v> zaik)JDSL0jz1kOTdA48VdhIs(TeiU_7sRVy@Mnl6WJL#YD(NO#01gL$z zY%|w^!jqrtEJ1F;x8|-X!xNj!tn(sjI3e@~`M%~sC)*d?D2mv;M;2|*W%D8xH>%@( zQALZgDK=}<(W)~Q4OdS}k>1TXBgE$?<}nkIv>tC`KPS)nUlK9e#S!}3+at$*Dv5X% zZ33?zg2BE=ll+op(iL7G5(GJw6bNqn9T&y%ZXSi_q?By=QhCxaVI%QTULW9i6zTmc zcGy`Ir5Qw|kLkailWzFBfPcsRnQG;OS=&RG-^5<_|2cxaKThh|<*0Lkhxp+F@VaDT zt~cWkM-$QWQ+2=0KO88AR?~t_y^?N%W`!EQmwyz+Myel*z84uX|24YHLON`a=Q@Fh z8Kg3oK~bTs3_$=qN3<(G;l_jJj$hQfqfJzNdkqGKK9|@V6Sc;*zS2*f9kT4HxFjWt z;u%faS9nmgbMygUrNB&1ZMhZLj2S?Mu&W3uyY2(;jZzZZF{Xdp@daTK)FG>Q02fpp z(j7BRlrTTdc)q!-mAK)j_3+n1Uj*^;+^`^^TOxwM$|nXx6sDG$8hh##1kVvpB+&{X zPE%}M3h3`_-mFnsB+?((R>GWkD(7AwFTKQRKWQ2Z9RmCQ1j$iV{L{R7t8YKwRL9%0m--`G_&fsoL-1PJJ^U!bA3ERpH3t(y13*sod5c=M#M>{iW6=A z0hm$K|4J6rv3A$LB%sfq0odB{iMRBkmCd4Ugw&IJsP#oYcuc4H(-lUd>KAef<8L{I zSK?B{7O@?~w=vDp;5aSMpJE?E1O@GUV0&XDH>bk^(2(TL9j~=PlCVu?0->6SI}_Du zronvQM+^1E?&D;2gQ-=0CksDYS%_zV(vyp<Kjc09=voxw8BW5)qFc+dwUK=h zaQ+usPuTh5`1Lm?^!PV|J+yiVkYX)24?`st916@lSSqtwm+Jup)p1yOLIzV1v-@oG z&Ie9zknaug%w*_-U8xA1cCH zSj_{y>3!bzSbvfJrxniubCpwHw$B95hB%4l+0^x&V8&tktq-)lNkodN%1FdUbsC`R z`|74-z?IG|=JW-CC45AwGMM-S6N17E2ZoKWOj_b% z4~4$Z>>kHn#ZB;i_M7`5a|)cpc&0T7-!bqN{M=18uA{`&83CJiOmSlJ!$N^V zqLdyIL^eU^OiQ5sZP`$W5qARkr9AW_G+g1K2v`5?bse2$#VBljFHCMN+KmTOx+Vt)HSKVrYk(p}Ujl#mi8SO>TTMGIy~yC*Jv{ zp6ZM=`hgPmF{5ZTy5Sw6;Yn=FgyOq2RgJ)1J@+ zYFadG07V+YB~+hhbh_{c8_`>@N9JVure0zalkv0mFhf`=_;ouqe<+Y=JCGSfWf`_} zVv+GAlY_PeBJ5>6Ww&!YDyY*|V1Qkqex*%RssgBj=8LhDT}kV4YF}Fp8y9xWEL8=_ zGt{bBRPKX!!MX4L^{BaL`6>PRqxaxg&$#nOz{s4N=4{^~Ji*vVt6(#dUU4C=fPTR% z8uZMm@Y5|t3G}t7QIKvRhYC;p`!jST!AH-Qq{C@yx!jCMr?fZJM*&Y z;YS`S3#Jp4FG@jnw6~{=2pxWeo|8Std~uWh%Q+hGAPJCy*R8DRM&z9B+v@&ZQ4{-7 z@hh5~LGzaZ!-N(9l8e?tkLB&Q++Da>7JM4Y7 zx;c~`?;CYGqatNFS-be`wOs_k8+OepNuN(*xZ}D+%lZikpJaG{6#52iI2LQAc#R|x zN;(PgILo9+htw_$?p`w?Hv*xQQZAj)x3vcNuKrwv6dC` z_UfwnJ5IpiWi}t7KBGY*C0qV>u2A8k6XthP_2TP>3^G!WqIE@)&QZ>vJc&5cv@`%q zHVaKd1(KzLd-z{?D(Jo52}^(2pr;Qu!@<2z+T^nq%vZpaCuaw-jm+Y)@8)6Mao zQ*7Ra><-9j5A5DtrHZJwS>JO4bz+*B~=UHSlej7rxD*9h<9KN;(FU12g?$5V&BY!dCj)WTOP*hL*Q*Wf?xRd2Tzz-Oh&F%5loBj>`5`kcwhStK=cdM+#m1uV@SjBzkE)K8vHQ}wZXzc^!>^+k; zN%<+_XG#2zFW=^E`Rzc5V;*R#u=3ZXsGmODWw2q=ac>$i?EVVzdcoQK7dOAX|7q;8 zn<86|r*J5h9DW>KDSyewDx9L~bP`V>8H*dXlt)iRXmQ!VJQ$;2pH4GWcaim-)1ZwB zB?#^5v6w!U1j-@x6@H*sR5%SUWeZkmVTE|#UQAepZB+_lG(c8XF%fCNBM?WUU^CDY z7vU3syQrf&2&k~58q0_{jl*pVi{akL46HE0Zc8Z18uFdgQQ37(nWlAi3GGiJwfIOA zLWbAqL_{zAvh5jnJUt-UopvcUk1&}WT-yYY&uV4V{Y(cVM z_6K#dEQl?)D!cD}zI?%aVUNgI2Skrchfg_%poUDdWD)^TJTObkC|B6E^VD9v!)G>6 zuIyqp=$=kdv0*z&0*Fn%H7iWJ%;|0RXky6LBMEIF2=K;;x?-Td!&AY&q`t@j zNO{7X2);R|1U{{ZP;jaPUI`~u>r@ZqE}pZkjXH}eO|l2nokh&H%*!$zYR-M^1c$P} zy;zj6Z4jOrb^cyl-R;hp$A|KK`|;LH@-t9DojV|S5`ck3io&W#8)Z7aPe@@DGTzr* zy*`%N|2}sA(fxk_8KB9h=bzDvyvjky71^X=Z!2kGt9P&o=YIfGhL4e^R}(u_8D{y? zST;sIh~ciW>5@jQu_5LMS%6FtMzhy(BII~On4O`DEv8)p%IJ4 z1?w_|_Vw_RanokL2e$(68(7m#w>n2(biUBYUmj!IF4=RC&~}#0K_J|GSx`!v9)PJ8 z@6cD?UXgR*lo@X;xEE=s;s@EX$-zl!8fz=TCjh-Zpq4m9K}X_U3~^2UndsW(v;W01 zVWc10UAp}FLgO`tU--W(nz5}Q7gg5aJ4k<>Jn(vEz^_5r)$$EsUsH}E1Z4ru_`s>)??14$L+JtxpwQd zbf7FZXNv3^j`*N*2cR65F6D?TQ&al?DXb|{RQjqo!z)p1H6BrbQ zkfLJ3&La`KZ#$f$HmE0piVPk3VUh^(OAApB~Rj zeHwV9FzdDwfli3Qbca0{|AXSb@?N$NETKyUXk`PY1@eRt?Gl!RQzt@lrv5p;n|wK& zxNtYpdS{IM_*K+ks5M*cyF_!QXv%VCg?6vth6>xMC1M`qL4V2mL5I+gC_%f!C{}1ydD^F981`Sy=MM@)!!tpyv2P7{$W@rtz00wOxId*ed zB#NGV9X(zVHK=+kJcuyYN@8BuWU<({kSn218!jeSQI|>PWiwxHlKeFkJ|E-%6i68c z{a#g_!3R>EBeX1WnYBaHN@rhrA+Gh^i!_5-!jxMCa_QlrgUy+J{fe4K7Cf*pIMPpo ziM(!VWVx zsV313&T?cKkixVqvyF#C9#@&c`H=lpxv$?CW~fL7N99M;v$L`v3A7wd<^N@Vk1rXX zY1?61Rrr@t>d^kV^>8aPAl{%dr_#ri zCq0^9JxAk)TaJ!&U9ZXBT+(izx)*gx?!5Uq@fR8}S0iE(t)-6`|GkQo+cxB~bb4RInU&)o zV1@q!Xz#XVP_qck71UiruRvd$TrC`P<{)TX6CoQL>{sV}_P_TcSZEuFsC)%~1=b>hH07`NPjXYU!TpYdF-9b0R%pTDJx%24+5e+FEd<5WgpC_nbc~11)D>(7EGa z`R=nMd2-WHzs{LYe=9F8Ify2f&mx~ff9|DY%vZIQ3lUuY+3>@ByF?E(GkAU4yJ(gp zoCl@KpDjgl4!FD^%=s}7dNdYL?^LH_oq$4(9ZqPi0>r9 zjbu>jaJ`}QCXgG8KuiCPm>h}WI!+lL(K)had^RR-Z&W}))p;y)gflcODg)|xMmv0w z9)qh;9JDxWtC*L>g)5?}ReH-i>b=b`ycee(O|P2dL(#{%ZdDgv{6#5#2d~Mgh~Ape zxQt|^s2(c@bRE>O@HGhz02Kve>49mH!N^mli7bg1-DPA=Db@I%o(#;s?tSSU8VSUh z1j?OS>!85FNa(r54J_s;%*iZ#AC&qCXNKd!Qb5&GxjcOS;Kv_aEBaZZv;l*Jp{c{o zy>A%m@-6==UKcz8Y>!?+--dL0X#f%m+AWzRiE(wUGJ3o)ozl4FW`&*{102esGZ6Vx z&26brKNB1+sT1s;Py=`Z-k57ob5cks!`8fX0vJ!VQ1?CYgY(9^33+)KMmzTmCC2@z z&GvoZx)=1`a6mrB0XUh|v-9(c+`9<@TLnAikUFt6ak)0FBP+<2^{|hKt%SJ%b67eG zv3- zT&XRo!aEF5g$`Fri7L^r=#d_VJVToo;@Hv%vX>_>p{u-79`?#fr*B%CNxAy<<|7C zI0=WO=11{><+2v2jJJiQw3iez9O;)OK$<>3r`Nxsn&*kis{V zkP&irt*=0k6ItDIk-!K{CdYDhX)MWU->o!}f9fT^l52-(S1>I`FEpTro#_>r&2VsV z?z8FM5rI>2SOJWhl+OusrBo%p<{_{lOli|TZC|7fiU6=yJ5HJbm*w!3_|gvzA93Nd zVwsg!eFZ^ecKQs#5)`fKs#dfzMdxw^)`e45uHGKGtj#=xCtn}ba5EbeEDQtA2xrrM zyts4qURW{+*b%!eM&kv*fY+l6DG`fu#C0TQEZ0W-A&SJ`_wu-y3Yy;vJpC5!pqXoI zA$7Nxfnb*|u()t&aMhfrQk)MF9o`r1-Nqwy_tMmDT*7;F8!WjTxj~rFMpPBmG538} zjSo+QRzBmECcft``Pr36h>uP8Z{ZFJzM&XYA2d~7t$n(Yp5k;XuP zJ5Yl{xi4k6jO;Nd_IeXSOCB#<4iJh}pqkA~6e{}5t^@o)p3$T6Pp#vp-+~R}l|Zj= z0QH_tbz3osMmx1!989sh#}tXYD#sB?Q+O<6Pi3ip$d39@H$BH zrCt|wB|s=rsNd70$5XUm4_8`JG#j=9q*2hjS*r`+DDU4~;x z>lCci5pHVnTGyr;aNk$Wz~$)2?ulk%ip_EAK7#GC2Zaq?18M6f&309z)t`pdRmy8E z={7k08Hzf zY8~saOIB%XEhF+)M|?tr$Q0?c74A$hLBhOc;g%sMtqFOj^gvFuHv%8AXlt)*{&R+R zfZ~~KUVPSlW=>}SNQ}Tc6;4;sBa|>cMN@wc0#vWx+)1H#_Q{&;nWA>fXtBR$N3;~A zEp=If#Y;ZZIb{d}%x{M!N1sq~S8Yc4t|5#YB~Sm=+6n44g)IjROSwFT3I7DkBmDcE zvlvL(a}{shM6jG=Rcl`3Eq_0=uK?J`hbm+fQ{T{MD=RU;^&Wxi%U^BYjMNwVE+=S+ z-I}jb>XR`QQXUT{whmyKO?J+-auY?*{xCBy2*J#kBA*dD{5-o$_h2t5{{$GXv(ok2 zB*Gd74#}H(f1m!&S$F#l-twv7H3PP-Nx~7>Hhv6=(&-hV*!Tn<71<))XTPX{#x9Ku^_6|oyO*P^?3%9Sb>slQ-a0I_+vAm`v;sx6L{2*n!G5LFB_w z=VhOgNn3qHgsG%}F8QBw24l#kW^SXT11ZSa1HjPl;+2tu;i+XCL#Hvgo~4SxR}T&8 z-ILmM19QW1TcUeO~oaGG4XqaS3ROU0>5|17PW;*<{6jf5#?}t(g*RG zJr8it!pz(@?de_$q+mJ=0O2|n_79CkO~=~PTq`x5jPL>h;8iJm(@K+&Vd6MPk;d{r zFwoblx=#=Ho?-kRSpx_oPqXNFemWq+z#ftj(X3;U30U(W!CTrc#g;MxhHi48H^HUr zkY`L0VL7zgMudGffqI)n_#Fxc^D#AKbWVJwSbUI|YtKaPu{S)>q~bd3IgOa8^EuJD22G3rxZ=%KE1uX9gO3=_u9&D=MO&gKXKJp{!pIBoyu7I%4+a8Q0wD@auksd zss;=fH_R9aN$`nzhhX4Bc%~d^wU`gw%CRVjViy*O2Rpx=Em9~T$KNF6>O`C(0Z=6- zz2F`+r$eOU(Ov!q?ZLD#Z+cY1EK%S^mi4T-2&;4hZJkih;l*vObeMqaR%G`0?m(3p zA?_Nn#*OB?dwUWVtR1OuMzRfm%`!hI$ikJDoAli#{Gh+a)Qr^S0A!cc&@7YZageIp zGPJd$AX3bXBYCPOpCm!nJc6T5BG*}Qo=o4nGD7WI*fXWDRoV~Mkok2VLmPS&9>zt_+C*{r0%Zw-?voMFu5#a(vi(8vs3pE?(`1_~tA345uiRd4>2k}u-kM~he zebAizszhBtkPU$?9>lU)w4gD@%%D8 z1pOR#jK!o=#iq~k%$RJhv5M9wy`Lyp4y+MaeJ8Y72NtJirfMRryPw8i4{y*PJYd&r z#9%2!?x)XlPcyac^gCtS@BU?!Gk7gU{``3H^k1Oi)J_c$tRGyL0NRS45|u#h4$Akt z3K7o zD@&L*XEmE(wygc;mOf9IOc2slXW|+MYNnZcoc*)W*PIE2o>F4|)GM1&3#a=0Wi?tM zaR*@JZg_H=(xTK#<)ko}I7XmEgp^^2J4e#Bj$Eq*>xe)6Vo5 zMeRYG^s0^y5fO>hf$Y)QX7*%sLNiezpZlJwcR~&`brs&;7aX2RVYB;VJu($?_Q{EY zrvZF~&TW_Y9yWbg+zE9JUn=A(X_NwRy~Q?%?r(nXcXeA4QsfK98tP8|Zb_b0&*MDu zGRWh#vIWrd?D;;4RC0r|E6Y2H0Jj6|3qJ*?zK4nwr>uT{-6Qg+-x9@l7(A$sqGYbe z624MI%6JRx2$1zGm-0r9S%QEqt$^+jiOykSlG_M{rNvp%!jUgM$P&_xmnN2Zt25Ov z38-)h{K@xZu5Z6Re$F)_Xo#E8$feMdbMZq`zO!2Cr*#eUr-j%~sZiXH z5f7O_-`>tCKq5db_WAUr`yUfXDHJ5eA+%&9a1HfV9`7noGR-holm;?|gI(FNiq}#| z1AK_xwD3Z^BjnpBDwFvhz~o0{-3#Bc;ksBoz35IK**_$up*(N%e*nUNm`W7UOj;d> zN)3h!6!oomL$-_b*~OtM^g2e9i^xo?d0e_&iW76Dbco@WwjZ|@1KhmJhGu}?lLkSY zD>am@;zF*$y$Cjb-p+t!Rv$a8d=I}vC=Ez~rA0o~!xO7D+{C5Dkxvx#r^?h!8@dBA zGCNnP+lR^R)!rD}iO^JZ?oVMEWEf8aG7B1QgVw z(4&v`ofm=!vN$&2B}rW+ei*OsN#c1U>K9Ol$zNOu+CZ-HOf1-g#Ph&19WF&;w>Deu z?&#sRNe1FzD2BC1@7C-!+$%+;sv6V6Ix@p1^-!J8Qy)$|fp?u*{RGN;CLaN~>yay$ z|1tJ)=a(9lEKr?-f6JGSQ^J@>%}j=w&+*7BIw`eaZ%A!oVH4BY9I&N_sJj8`*I-X7 zUVOc6*p2~^w<4TeanJEpPQ_@`cJ|TN>!wxo6r)K_$E?zeiy}~SUxP1waRyRV7$V-Y z6t_qedXuc(%JXJCTeO*3YK>;ToU>jf&qpbPO&gVB#eUtg%xyY+!E}zm;RVsecw#+E z>MbuatvZ7dv3?W+>=Ttu%jpe3IwHE-iY>AHB(+yCBY^7pta!0S4SCzZT1apqG77K0 zh0`R{hW@2ZM08zs1;c>QyE5l2|62LZ`z8SlHKaoXlnP|Cw6Mx9ykbs$ z`VMm9nsm!)#r)+>i%tu$OM%6U$?yAK^GavfOBvB{hlTeidt4fc9II#+K3IzBwwM;3 z2M-H=J$?V}I2em^gqZPFyoyXj0ZJ+8`3}B)p|2SGcNeyvRmsiKk%9!|9X2^q$8E@M zmKc8R+CvqwqO>v8!LIfSX?h@M-Bw6iS$ECv2%!kpMQ@y7F6 zV2U|McoHC-=HF7)|HLSK>lK0&5Vz}uOX*x{Ty?8A*1UpSffJ@ix@H}8dN6V1J1J9X zx3{X_m#yT2l_Sph%k(3ZEy~b7@|LT#BhC6cNogJ3+m`h)dKY?6!||`%eD3Y7_03gt zC#Pb#7g8+*h;-dDTCv{-D^E71h1|*~eu>E=4jgl1Vf(qC!i1_{A%hVf^h_vk2H+@UH&oK~GCp z)kr0{+NeRnleBV#_IFuZJ~e?SpCV0PCQXjC1Jk7GCJWgxnr(9-<7{(TFrQo$Pmja1 zZ?X~5;%M5-aK9moSo0OjSIK|Vf_3vSDsF92d65|Pb>Txu4nlJg9jq?8N5U>T;zaI6 zoy*R=;dS6d>EkLS$j!Zk6Hut zz1Q!ar~3!)<9b}{TXU^%j5)@b5P@)dR+Y4C17<8-nZp)zl#8LQK_l@bYvG=cxF3Tl za@^_l!YBa%fS<^h%c`MThcW;J(fylFJ|Xq_5J#Z$l;s8d_Di1{w;SX5MHVkKdp(N+ zoU1J5%S!^FlDh`XKNngqEF|c_mu6IUoBg|oKY{d-!{p>S1N&6LaSh`#PBq$$UBWde zHx@#iDjqoI@DR@4rA9= zYIAyBC0F${IyN|}o=dYwV`+qC_$Zicz~ESQa30tSoB{GQwI03B2)?T`&mHDf6Sd{5 zNKMq!b=z*923x&aUG=ZY;8n7lZTN92)s@0HNiO{%m(VfeKEp43#8vV5k8OPP2~4e}}z^ycz=)1rONSzYcedG%@AtGofYU+RLUz0?#Cq{& zJxy=nl-==My&G1x+-)+Bc10}h>l+-J#CW#$*Cqdq^+mvtU+J>V4rgk=GXc$m*#Fpd zYo939#T!@mPX8woXG=_Qn-6ht935|>(}?kU*I&A>XrWh2V95b;OXoN0JaSkrYny>1 z$+kB;lS;)5Wz1iRedb8=W6`=SoBD(0Pc8Pvv4{G`{r^F+es@bCrB2u(*G>)&jh*_| zgl>e{fbcA`7)JW2JP48{OSVj9_}~DMIDwXVHYRzpUMx_Ry+Ep*O!ZugCe5c18cakN zawzXK5S7dpxY|s9U)0kc=shwgdPivBnH`oeWZJhe;aWtY^KOGNXwhA2W9AXclMZsm@r4FNDTBB%yV z)%wBLy_a70O8!^#!wh z&vTso78K*CHsUX6u5&Pg7YdGPemx;{ZqYFSckU-ZrD-*qoka-0;qCCjnM zbvw|ww7chaBCaANUp%R<935lb*kNU55VQJk()7L-wg1eU=C%JV2=uWV1;UdeN-!Ad zPrhhVaUP3F$3tN#qcsX4Z|Ufh(a$lAaA^tJsJZ8Y6(RBNM&yTfq!OuOMAj$W7v0PT z2kA^iRcdwCcFm4;y-xJ$y3yKKOOQ@)zfe0V>zf3q-W6w?t)%*;5Sq z9G=4f{)?P=YHvF2UK4zj@3-6;NDy_oNr!H|ZT1sTx-i87Z_nz`3m(68HY*Q$1b!R+ z{vsqpT+&Dp#8(K;SB?)w1jvBw--&r9q)c+B?Tva!8<|sRm+-DACXv^y4>d^!T!pAE z+4;6=sT5b&&g9(+f3PlNY7M6!N&h;vp-gG71Q+r1tmp4!4-4S~l`wiX?r!AdKZlQs z&OYw%cV5PwX@6|w{Fb-cc{L-8kF{;ip}fkH;v8QE<*}?xXkxg2+b|bUSEp($?Meh`Xi37k& zMu#?_SYnf$lrs8~zQFar4MgD@5*Ch8hvp`M=4oT>@O7+`Vx4K30VFlKcv}mn%VFbV zDRXM6R6mt|aGWeA2SvV{jhkO(lz{Q@DN-?9GPAM!zwn{Ltpqb`7|ToSI=3ZeIwD{w zBWWpx)-?|yA@_ZJjTm@?VSfoBC8sD#f@Lcm`B+@=vvto2_<#a%b{^{yMo6JS$_yFS zt`IEHoY~3fQ#E~M4AY0wgP~*6aAbONq00tj2FkfF9oS{w+cD8+B&{R9cI}ej`=QTt zCOGxI$Ti`A=t{DqJ`HoKcE&|!eTWP|y0))nluPV^mTnub61tci4=t$c0UQ&RV8(yA z5_H8hR_yDTa65BZaia*CM;AJyBa8M20!pVv$Vw3IoZ-x`_THDu`^(ys-qW`nqt2?< z>s6;dncI#FpYPS>Vrb2q<}q>#lUAioAVGOum^!+e&-Pbmn^r+x-=*oPA6(1mSX6RlZgRgOU;Ci&{i( z>^mCx`z7;_34gRcgzm$2MJw1asyOR?K@ed~x;zk>mj*&ja>P#Qh7nflGXv!8>zmBI z1A}ALO?g$$!I;SxB@jaMb;~Ep-tXDbVO`x15%e)wZ^w1!+~etg#(VC52XIYXjccgj zCaz?aTkPFR`@8Kcy1KDnsOgkOxNmp=dVSCC(bSb2;~mOB0R^;-gC7Jg_)(k;t-v;D zm3D27=4JV>kc;1B{cm$Z48nBeK|37a_R7`_`+B4priM?`e2_pt3o-Zvz~E`sqlGPaqjKo*Z|8eCkMaq{)iU>U9to?Qh4e2Oh^TxmfIfqL!@45ID) z9EXTC>Idt&`+45mC+A^+4_u3jj}_E1H?mJEBw9AEoEA`GM#FLbj#RvkOlekcy3CFEiSF!wU!h2m!Rbb0oRKR;%K5 zyX|HG=L7w366-~_{ZlDlcr8~s>GTuPOeh@LHMl|Q#i^>Mo`Gj zJaAb9l?-ZLp`x87S@q+s^Z-Q?tRBNaakaTamZx-e^y!FIe!}#95mkP0maT)1a?|BM z)AXuk&e>)Yv74}#pMa_&f!}UMlH7o{E(nG!zWMg)om;@$^ic~Q&C#UuOBYqn zO=UU6(_+kDnJa(x;E123iH)Lsn9I4KhojUtg<&^_)c}6JclirV*&KbX!?L<2y*s8g zaQdz`l#O0a<8&*|h5~8Jw_|gQhrPeK=1woIL9~GDfe@l)F z;UjBJ=eGMa=S7Dw=--KV_U|5D`J83l&0!a55yBaRSCeXa6WdOL09xI51?-}5Td_^F z8PG3Qbg+z}6Ye$72P#`PWqCRriQP)EPIA{l{gM6z^mcYM K0{?pabKzf8moQHN literal 0 HcmV?d00001 diff --git a/maixcdk/static/image/search/cancel.svg b/maixcdk/static/image/search/cancel.svg new file mode 100644 index 00000000..46102a4c --- /dev/null +++ b/maixcdk/static/image/search/cancel.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/maixcdk/static/image/search/close.svg b/maixcdk/static/image/search/close.svg new file mode 100644 index 00000000..87c50f5d --- /dev/null +++ b/maixcdk/static/image/search/close.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/maixcdk/static/image/search/search.svg b/maixcdk/static/image/search/search.svg new file mode 100644 index 00000000..3fafc630 --- /dev/null +++ b/maixcdk/static/image/search/search.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/maixcdk/static/image/search/up.svg b/maixcdk/static/image/search/up.svg new file mode 100644 index 00000000..1ed67152 --- /dev/null +++ b/maixcdk/static/image/search/up.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/maixcdk/static/image/theme_default/anchor.svg b/maixcdk/static/image/theme_default/anchor.svg new file mode 100644 index 00000000..4cbdda12 --- /dev/null +++ b/maixcdk/static/image/theme_default/anchor.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/maixcdk/static/image/theme_default/array.svg b/maixcdk/static/image/theme_default/array.svg new file mode 100644 index 00000000..5c5c5148 --- /dev/null +++ b/maixcdk/static/image/theme_default/array.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/maixcdk/static/image/theme_default/back.svg b/maixcdk/static/image/theme_default/back.svg new file mode 100644 index 00000000..e2729940 --- /dev/null +++ b/maixcdk/static/image/theme_default/back.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/maixcdk/static/image/theme_default/dark_mode.svg b/maixcdk/static/image/theme_default/dark_mode.svg new file mode 100644 index 00000000..15523d8e --- /dev/null +++ b/maixcdk/static/image/theme_default/dark_mode.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/maixcdk/static/image/theme_default/ext_link.svg b/maixcdk/static/image/theme_default/ext_link.svg new file mode 100644 index 00000000..ded48739 --- /dev/null +++ b/maixcdk/static/image/theme_default/ext_link.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/maixcdk/static/image/theme_default/indicator.svg b/maixcdk/static/image/theme_default/indicator.svg new file mode 100644 index 00000000..7170d305 --- /dev/null +++ b/maixcdk/static/image/theme_default/indicator.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/maixcdk/static/image/theme_default/light_mode.svg b/maixcdk/static/image/theme_default/light_mode.svg new file mode 100644 index 00000000..0be13395 --- /dev/null +++ b/maixcdk/static/image/theme_default/light_mode.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/maixcdk/static/image/theme_default/menu.svg b/maixcdk/static/image/theme_default/menu.svg new file mode 100644 index 00000000..5f9cdda6 --- /dev/null +++ b/maixcdk/static/image/theme_default/menu.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/maixcdk/static/image/theme_default/print.svg b/maixcdk/static/image/theme_default/print.svg new file mode 100644 index 00000000..3b343178 --- /dev/null +++ b/maixcdk/static/image/theme_default/print.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/maixcdk/static/image/theme_default/to-top.svg b/maixcdk/static/image/theme_default/to-top.svg new file mode 100644 index 00000000..59f0a172 --- /dev/null +++ b/maixcdk/static/image/theme_default/to-top.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/maixcdk/static/images/thumbs_up/up.svg b/maixcdk/static/images/thumbs_up/up.svg new file mode 100644 index 00000000..fda49330 --- /dev/null +++ b/maixcdk/static/images/thumbs_up/up.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/maixcdk/static/images/thumbs_up/upped.svg b/maixcdk/static/images/thumbs_up/upped.svg new file mode 100644 index 00000000..f5c9305d --- /dev/null +++ b/maixcdk/static/images/thumbs_up/upped.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/maixcdk/static/js/custom.js b/maixcdk/static/js/custom.js new file mode 100644 index 00000000..e69de29b diff --git a/maixcdk/static/js/search/search_main.js b/maixcdk/static/js/search/search_main.js new file mode 100644 index 00000000..5e91975a --- /dev/null +++ b/maixcdk/static/js/search/search_main.js @@ -0,0 +1,351 @@ + +jQuery.fn.highlight = function (pat) { + function innerHighlight(node, pat) { + var skip = 0; + if (node.nodeType == 3) { + var pos = node.data.toUpperCase().indexOf(pat); + if (pos >= 0) { + var spannode = document.createElement('span'); + spannode.className = 'search_highlight'; + var middlebit = node.splitText(pos); + var endbit = middlebit.splitText(pat.length); + var middleclone = middlebit.cloneNode(true); + spannode.appendChild(middleclone); + middlebit.parentNode.replaceChild(spannode, middlebit); + skip = 1; + } + } + else if (node.nodeType == 1 && node.childNodes && !/(script|style)/i.test(node.tagName)) { + for (var i = 0; i < node.childNodes.length; ++i) { + i += innerHighlight(node.childNodes[i], pat); + } + } + return skip; + } + return this.each(function () { + innerHighlight(this, pat.toUpperCase()); + }); +}; + +window.onload = function(){ +} + +$(document).ready(function(){ + var waiting_search = false; + var search_index = null; + var search_content = { + "curr": null, + "others":{} + } + function onDownloadOk(data, arg1, arg2){ + search_index = data; + var pathname = window.location.pathname; + var curr_url = null; + var others_url = []; + for(var url in search_index){ + if(pathname.indexOf(url) != -1){ + if(!curr_url){ + curr_url = url; + }else{ // already have math item, e.g. `/get_started/zh/install/index.html /get_started/zh` + // and now `/get_started/zh/install/index.html /` + // choose longger one + if(url.length > curr_url.length){ + others_url.push(curr_url); + curr_url = url; + }else{ + others_url.push(url); + } + } + }else{ + others_url.push(url); + } + } + if(search_index[curr_url]){ + downloadJson(search_index[curr_url][1], onIndexDownloadOk, curr_url, true, search_index[curr_url][0]); + } + for(var i in others_url){ + url = others_url[i]; + downloadJson(search_index[url][1], onIndexDownloadOk, url, false, search_index[url][0]); + } + } + function onIndexDownloadOk(data, url, is_curr, doc_name){ + if(is_curr){ + search_content["curr"] = [url, doc_name, data]; + }else{ + search_content["others"][url] = [url, doc_name, data]; + } + if(waiting_search == true){ + waiting_search = false; + onSearch(); + } + } + downloadJson("/maixcdk/static/search_index/index.json", onDownloadOk); + var input_hint = $("#search_input_hint").html(); + var loading_hint = $("#search_loading_hint").html(); + var download_err_hint = $("#search_download_err_hint").html(); + var other_docs_result_hint = $("#search_other_docs_result_hint").html(); + var curr_doc_result_hint = $("#search_curr_doc_result_hint").html(); + $("body").append('

    '); + $("#search").bind("click", function(e){ + $("body").css("overflow-y", "hidden"); + $("#search_wrapper").show(); + $("#search_input").focus(); + $("#wrapper").addClass("blur"); + $("#navbar").addClass("blur"); + }); + $("#search_wrapper .close").bind("click", function(e){ + $("body").css("overflow-y", "auto"); + $("#search_wrapper").hide(); + $("#wrapper").removeClass("blur"); + $("#navbar").removeClass("blur"); + }); + $("#search_input").bind("input propertychange", function(){ + setTimeout(() => { + onSearch(); + }, 1000); + }); + function onSearch(){ + $("#search_result_name").empty(); + $("#search_result_content").empty(); + $("#search_result_content").append('
      '+ curr_doc_result_hint +'
    '); + $("#search_result_content").append('
      '+ other_docs_result_hint +'
    '); + if(!search_index){ + $("#search_result_content").append('
    '+ loading_hint +'
    '); + waiting_search = true; + return; + } + if(!search_content["curr"] && search_content["others"].length == 0){ + $("#search_result_content").append('
    '+ loading_hint +'
    '); + waiting_search = true; + return; + } + $("#search_curr_result > .hint").addClass("searching"); + var search_keywords = $("#search_input").val(); + search_doc(search_content["curr"], "#search_curr_result"); + var doc_id = 0; + for(var url in search_content["others"]){ + search_doc(search_content["others"][url], "#search_others_result", doc_id); + doc_id += 1; + } + addSearchResultClickListener(); + function search_doc(data, containerId, doc_id="curr"){ + var doc_id_str = 'result_wrapper_' + doc_id; + var findFlag = false; + var items = data[2]; + for(var url in items){ + var content = items[url]; + search_keywords = search_keywords.trim(); + if(search_keywords.length <= 0){ + return; + } + var keywords = search_keywords.split(" "); + var find = false; + var find_strs = ""; + for(var i in keywords){ + var keyword = keywords[i]; + if(content["title"] && content["title"].indexOf(keyword) >= 0){ + find = true; + } + } + if(content["content"] && content["content"].length > 0){ + find_strs = search(keywords, content["content"]); + if(find_strs.length > 0){ + find = true; + } + } + if(find){ + if(!findFlag){ + $("#search_result_name").append('
  1. '+ data[1] +'
  2. '); + $(containerId).append('
    '+data[1]+'
    '); + findFlag = true; + } + $("#"+doc_id_str).append('
  3. '+ (content["title"]?content["title"]:url) + + '

    ' + find_strs + '
  4. '); + } + } + } + $("#search_curr_result > .hint").removeClass("searching"); + } + function downloadJson(url, callback, arg1=null, arg2=null, arg3=null){ + $.ajax({ + type: "GET", + url: url, + contentType: "application/json", + dataType: "json", + success: function(data){ + callback(data, arg1, arg2, arg3); + }, + error: function(){ + $("#search_result_content").empty(); + $("#search_result_content").append('
    '+ download_err_hint + ': '+ url +'
    '); + } + }); + } + highlightKeywords(); +}); + +function focusItems(id, contrainerId, offset=0, classname=null){ + var elementTop = 0; + if(classname){ + elementTop = $("."+classname)[0].offsetTop - offset; + }else{ + elementTop = $("#"+id)[0].offsetTop - offset; + } + + $("#"+contrainerId).animate({scrollTop: elementTop},500); +} + + +function addSearchResultClickListener(){ + $("#search_result_name > li").on("click", function(e){ + var targetId = e.target.attributes.result_id.value; + focusItems(targetId, "search_result_content", $("#search_title").height() + $("#search_result .hint").height()); + }); +} + +function highlightKeywords(){ + var highlight_keywords = getQueryVariable("highlight"); + if(highlight_keywords){ + // add search result btn + var html = document.getElementsByTagName("html")[0]; + var lang = html.lang.split("-")[0].toLowerCase() + let strs = { + "zh": { + "Previous": "上一个", + "Next": "下一个" + } + } + if(lang in strs){ + var pre_name = strs[lang]["Previous"]; + var next_name = strs[lang]["Next"]; + }else{ + var pre_name = "Previous"; + var next_name = "Next"; + } + $("body").append('
    ' + + '' + + '' + + '' + + '
    '); + var highlight_keywords = decodeURI(highlight_keywords); + highlight_keywords = highlight_keywords.split(" "); + for(var i=0; i .previous").on("click", function(){ + let old = currSearchIdx; + currSearchIdx -= 1; + if (currSearchIdx < 0){ + currSearchIdx = $(".search_highlight").length - 1; + } + window.scrollTo({ + top: $(".search_highlight")[currSearchIdx].offsetTop - window.screen.height / 3, + behavior: "smooth" + }); + $($(".search_highlight")[old]).removeClass("selected_highlight") + $($(".search_highlight")[currSearchIdx]).addClass("selected_highlight") + }); + $("#search_ctrl_btn > .next").on("click", function(){ + let old = currSearchIdx; + currSearchIdx += 1; + if (currSearchIdx >= $(".search_highlight").length){ + currSearchIdx = 0; + } + window.scrollTo({ + top: $(".search_highlight")[currSearchIdx].offsetTop - window.screen.height / 3, + behavior: "smooth" + }); + $($(".search_highlight")[old]).removeClass("selected_highlight") + $($(".search_highlight")[currSearchIdx]).addClass("selected_highlight") + }); + } +} +function getQueryVariable(variable) +{ + var query = window.location.search.substring(1); + var vars = query.split("&"); + for (var i=0;i= 0){ + idxs.push({ + "idx": idx + idx_rel, + "len": keyword.length + }); + _idxs = _search([keyword], content.substr(idx + keyword.length), idx_rel + idx + keyword.length); + idxs = idxs.concat(_idxs); + } + } + return idxs + } + var find_strs = ""; + idxs = _search(keywords, content); + idxs = idxs.sort((a, b)=> a.idx-b.idx); + var idx_last = -1; + var len_last = 0; + for(var i=0; i= 0 && (idx - idx_last -len_last) < show_length){ // last keyword too close + find_strs += content.substr(idx_last + len_last, idx - (idx_last + len_last)) + ''+ content.substr(idx, len) +'' + }else{ + var start_idx = (idx - show_length < 0) ? 0 : (idx - show_length); + find_strs += '...' + content.substr(start_idx, idx - start_idx) + + '' + content.substr(idx, len) + + ''; + } + var idx_next = -1; + if(i < idxs.length -1){ + idx_next = idxs[i + 1]['idx']; + } + if(idx_next >= 0 && ((idx_next - idx - len) < show_length) ){ // next keywor too close + }else{ + find_strs += content.substr(idx + len, show_length) + '...'; + } + idx_last = idx; + len_last = len; + } + return find_strs +} + diff --git a/maixcdk/static/js/theme_default/jquery.min.js b/maixcdk/static/js/theme_default/jquery.min.js new file mode 100644 index 00000000..b0614034 --- /dev/null +++ b/maixcdk/static/js/theme_default/jquery.min.js @@ -0,0 +1,2 @@ +/*! jQuery v3.5.1 | (c) JS Foundation and other contributors | jquery.org/license */ +!function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(C,e){"use strict";var t=[],r=Object.getPrototypeOf,s=t.slice,g=t.flat?function(e){return t.flat.call(e)}:function(e){return t.concat.apply([],e)},u=t.push,i=t.indexOf,n={},o=n.toString,v=n.hasOwnProperty,a=v.toString,l=a.call(Object),y={},m=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType},x=function(e){return null!=e&&e===e.window},E=C.document,c={type:!0,src:!0,nonce:!0,noModule:!0};function b(e,t,n){var r,i,o=(n=n||E).createElement("script");if(o.text=e,t)for(r in c)(i=t[r]||t.getAttribute&&t.getAttribute(r))&&o.setAttribute(r,i);n.head.appendChild(o).parentNode.removeChild(o)}function w(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?n[o.call(e)]||"object":typeof e}var f="3.5.1",S=function(e,t){return new S.fn.init(e,t)};function p(e){var t=!!e&&"length"in e&&e.length,n=w(e);return!m(e)&&!x(e)&&("array"===n||0===t||"number"==typeof t&&0+~]|"+M+")"+M+"*"),U=new RegExp(M+"|>"),X=new RegExp(F),V=new RegExp("^"+I+"$"),G={ID:new RegExp("^#("+I+")"),CLASS:new RegExp("^\\.("+I+")"),TAG:new RegExp("^("+I+"|[*])"),ATTR:new RegExp("^"+W),PSEUDO:new RegExp("^"+F),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:new RegExp("^(?:"+R+")$","i"),needsContext:new RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},Y=/HTML$/i,Q=/^(?:input|select|textarea|button)$/i,J=/^h\d$/i,K=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ee=/[+~]/,te=new RegExp("\\\\[\\da-fA-F]{1,6}"+M+"?|\\\\([^\\r\\n\\f])","g"),ne=function(e,t){var n="0x"+e.slice(1)-65536;return t||(n<0?String.fromCharCode(n+65536):String.fromCharCode(n>>10|55296,1023&n|56320))},re=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ie=function(e,t){return t?"\0"===e?"\ufffd":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e},oe=function(){T()},ae=be(function(e){return!0===e.disabled&&"fieldset"===e.nodeName.toLowerCase()},{dir:"parentNode",next:"legend"});try{H.apply(t=O.call(p.childNodes),p.childNodes),t[p.childNodes.length].nodeType}catch(e){H={apply:t.length?function(e,t){L.apply(e,O.call(t))}:function(e,t){var n=e.length,r=0;while(e[n++]=t[r++]);e.length=n-1}}}function se(t,e,n,r){var i,o,a,s,u,l,c,f=e&&e.ownerDocument,p=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==p&&9!==p&&11!==p)return n;if(!r&&(T(e),e=e||C,E)){if(11!==p&&(u=Z.exec(t)))if(i=u[1]){if(9===p){if(!(a=e.getElementById(i)))return n;if(a.id===i)return n.push(a),n}else if(f&&(a=f.getElementById(i))&&y(e,a)&&a.id===i)return n.push(a),n}else{if(u[2])return H.apply(n,e.getElementsByTagName(t)),n;if((i=u[3])&&d.getElementsByClassName&&e.getElementsByClassName)return H.apply(n,e.getElementsByClassName(i)),n}if(d.qsa&&!N[t+" "]&&(!v||!v.test(t))&&(1!==p||"object"!==e.nodeName.toLowerCase())){if(c=t,f=e,1===p&&(U.test(t)||z.test(t))){(f=ee.test(t)&&ye(e.parentNode)||e)===e&&d.scope||((s=e.getAttribute("id"))?s=s.replace(re,ie):e.setAttribute("id",s=S)),o=(l=h(t)).length;while(o--)l[o]=(s?"#"+s:":scope")+" "+xe(l[o]);c=l.join(",")}try{return H.apply(n,f.querySelectorAll(c)),n}catch(e){N(t,!0)}finally{s===S&&e.removeAttribute("id")}}}return g(t.replace($,"$1"),e,n,r)}function ue(){var r=[];return function e(t,n){return r.push(t+" ")>b.cacheLength&&delete e[r.shift()],e[t+" "]=n}}function le(e){return e[S]=!0,e}function ce(e){var t=C.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function fe(e,t){var n=e.split("|"),r=n.length;while(r--)b.attrHandle[n[r]]=t}function pe(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(r)return r;if(n)while(n=n.nextSibling)if(n===t)return-1;return e?1:-1}function de(t){return function(e){return"input"===e.nodeName.toLowerCase()&&e.type===t}}function he(n){return function(e){var t=e.nodeName.toLowerCase();return("input"===t||"button"===t)&&e.type===n}}function ge(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&ae(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function ve(a){return le(function(o){return o=+o,le(function(e,t){var n,r=a([],e.length,o),i=r.length;while(i--)e[n=r[i]]&&(e[n]=!(t[n]=e[n]))})})}function ye(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}for(e in d=se.support={},i=se.isXML=function(e){var t=e.namespaceURI,n=(e.ownerDocument||e).documentElement;return!Y.test(t||n&&n.nodeName||"HTML")},T=se.setDocument=function(e){var t,n,r=e?e.ownerDocument||e:p;return r!=C&&9===r.nodeType&&r.documentElement&&(a=(C=r).documentElement,E=!i(C),p!=C&&(n=C.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener("unload",oe,!1):n.attachEvent&&n.attachEvent("onunload",oe)),d.scope=ce(function(e){return a.appendChild(e).appendChild(C.createElement("div")),"undefined"!=typeof e.querySelectorAll&&!e.querySelectorAll(":scope fieldset div").length}),d.attributes=ce(function(e){return e.className="i",!e.getAttribute("className")}),d.getElementsByTagName=ce(function(e){return e.appendChild(C.createComment("")),!e.getElementsByTagName("*").length}),d.getElementsByClassName=K.test(C.getElementsByClassName),d.getById=ce(function(e){return a.appendChild(e).id=S,!C.getElementsByName||!C.getElementsByName(S).length}),d.getById?(b.filter.ID=function(e){var t=e.replace(te,ne);return function(e){return e.getAttribute("id")===t}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n=t.getElementById(e);return n?[n]:[]}}):(b.filter.ID=function(e){var n=e.replace(te,ne);return function(e){var t="undefined"!=typeof e.getAttributeNode&&e.getAttributeNode("id");return t&&t.value===n}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];i=t.getElementsByName(e),r=0;while(o=i[r++])if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),b.find.TAG=d.getElementsByTagName?function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):d.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){while(n=o[i++])1===n.nodeType&&r.push(n);return r}return o},b.find.CLASS=d.getElementsByClassName&&function(e,t){if("undefined"!=typeof t.getElementsByClassName&&E)return t.getElementsByClassName(e)},s=[],v=[],(d.qsa=K.test(C.querySelectorAll))&&(ce(function(e){var t;a.appendChild(e).innerHTML="",e.querySelectorAll("[msallowcapture^='']").length&&v.push("[*^$]="+M+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||v.push("\\["+M+"*(?:value|"+R+")"),e.querySelectorAll("[id~="+S+"-]").length||v.push("~="),(t=C.createElement("input")).setAttribute("name",""),e.appendChild(t),e.querySelectorAll("[name='']").length||v.push("\\["+M+"*name"+M+"*="+M+"*(?:''|\"\")"),e.querySelectorAll(":checked").length||v.push(":checked"),e.querySelectorAll("a#"+S+"+*").length||v.push(".#.+[+~]"),e.querySelectorAll("\\\f"),v.push("[\\r\\n\\f]")}),ce(function(e){e.innerHTML="";var t=C.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&v.push("name"+M+"*[*^$|!~]?="),2!==e.querySelectorAll(":enabled").length&&v.push(":enabled",":disabled"),a.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&v.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),v.push(",.*:")})),(d.matchesSelector=K.test(c=a.matches||a.webkitMatchesSelector||a.mozMatchesSelector||a.oMatchesSelector||a.msMatchesSelector))&&ce(function(e){d.disconnectedMatch=c.call(e,"*"),c.call(e,"[s!='']:x"),s.push("!=",F)}),v=v.length&&new RegExp(v.join("|")),s=s.length&&new RegExp(s.join("|")),t=K.test(a.compareDocumentPosition),y=t||K.test(a.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},D=t?function(e,t){if(e===t)return l=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)==(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!d.sortDetached&&t.compareDocumentPosition(e)===n?e==C||e.ownerDocument==p&&y(p,e)?-1:t==C||t.ownerDocument==p&&y(p,t)?1:u?P(u,e)-P(u,t):0:4&n?-1:1)}:function(e,t){if(e===t)return l=!0,0;var n,r=0,i=e.parentNode,o=t.parentNode,a=[e],s=[t];if(!i||!o)return e==C?-1:t==C?1:i?-1:o?1:u?P(u,e)-P(u,t):0;if(i===o)return pe(e,t);n=e;while(n=n.parentNode)a.unshift(n);n=t;while(n=n.parentNode)s.unshift(n);while(a[r]===s[r])r++;return r?pe(a[r],s[r]):a[r]==p?-1:s[r]==p?1:0}),C},se.matches=function(e,t){return se(e,null,null,t)},se.matchesSelector=function(e,t){if(T(e),d.matchesSelector&&E&&!N[t+" "]&&(!s||!s.test(t))&&(!v||!v.test(t)))try{var n=c.call(e,t);if(n||d.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){N(t,!0)}return 0":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(te,ne),e[3]=(e[3]||e[4]||e[5]||"").replace(te,ne),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||se.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&se.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return G.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&X.test(n)&&(t=h(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(te,ne).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=m[e+" "];return t||(t=new RegExp("(^|"+M+")"+e+"("+M+"|$)"))&&m(e,function(e){return t.test("string"==typeof e.className&&e.className||"undefined"!=typeof e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(n,r,i){return function(e){var t=se.attr(e,n);return null==t?"!="===r:!r||(t+="","="===r?t===i:"!="===r?t!==i:"^="===r?i&&0===t.indexOf(i):"*="===r?i&&-1:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function D(e,n,r){return m(n)?S.grep(e,function(e,t){return!!n.call(e,t,e)!==r}):n.nodeType?S.grep(e,function(e){return e===n!==r}):"string"!=typeof n?S.grep(e,function(e){return-1)[^>]*|#([\w-]+))$/;(S.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||j,"string"==typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:q.exec(e))||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof S?t[0]:t,S.merge(this,S.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:E,!0)),N.test(r[1])&&S.isPlainObject(t))for(r in t)m(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(i=E.getElementById(r[2]))&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):m(e)?void 0!==n.ready?n.ready(e):e(S):S.makeArray(e,this)}).prototype=S.fn,j=S(E);var L=/^(?:parents|prev(?:Until|All))/,H={children:!0,contents:!0,next:!0,prev:!0};function O(e,t){while((e=e[t])&&1!==e.nodeType);return e}S.fn.extend({has:function(e){var t=S(e,this),n=t.length;return this.filter(function(){for(var e=0;e\x20\t\r\n\f]*)/i,he=/^$|^module$|\/(?:java|ecma)script/i;ce=E.createDocumentFragment().appendChild(E.createElement("div")),(fe=E.createElement("input")).setAttribute("type","radio"),fe.setAttribute("checked","checked"),fe.setAttribute("name","t"),ce.appendChild(fe),y.checkClone=ce.cloneNode(!0).cloneNode(!0).lastChild.checked,ce.innerHTML="",y.noCloneChecked=!!ce.cloneNode(!0).lastChild.defaultValue,ce.innerHTML="",y.option=!!ce.lastChild;var ge={thead:[1,"","
    "],col:[2,"","
    "],tr:[2,"","
    "],td:[3,"","
    "],_default:[0,"",""]};function ve(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&A(e,t)?S.merge([e],n):n}function ye(e,t){for(var n=0,r=e.length;n",""]);var me=/<|&#?\w+;/;function xe(e,t,n,r,i){for(var o,a,s,u,l,c,f=t.createDocumentFragment(),p=[],d=0,h=e.length;d\s*$/g;function qe(e,t){return A(e,"table")&&A(11!==t.nodeType?t:t.firstChild,"tr")&&S(e).children("tbody")[0]||e}function Le(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function He(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Oe(e,t){var n,r,i,o,a,s;if(1===t.nodeType){if(Y.hasData(e)&&(s=Y.get(e).events))for(i in Y.remove(t,"handle events"),s)for(n=0,r=s[i].length;n").attr(n.scriptAttrs||{}).prop({charset:n.scriptCharset,src:n.url}).on("load error",i=function(e){r.remove(),i=null,e&&t("error"===e.type?404:200,e.type)}),E.head.appendChild(r[0])},abort:function(){i&&i()}}});var Ut,Xt=[],Vt=/(=)\?(?=&|$)|\?\?/;S.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=Xt.pop()||S.expando+"_"+Ct.guid++;return this[e]=!0,e}}),S.ajaxPrefilter("json jsonp",function(e,t,n){var r,i,o,a=!1!==e.jsonp&&(Vt.test(e.url)?"url":"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&Vt.test(e.data)&&"data");if(a||"jsonp"===e.dataTypes[0])return r=e.jsonpCallback=m(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,a?e[a]=e[a].replace(Vt,"$1"+r):!1!==e.jsonp&&(e.url+=(Et.test(e.url)?"&":"?")+e.jsonp+"="+r),e.converters["script json"]=function(){return o||S.error(r+" was not called"),o[0]},e.dataTypes[0]="json",i=C[r],C[r]=function(){o=arguments},n.always(function(){void 0===i?S(C).removeProp(r):C[r]=i,e[r]&&(e.jsonpCallback=t.jsonpCallback,Xt.push(r)),o&&m(i)&&i(o[0]),o=i=void 0}),"script"}),y.createHTMLDocument=((Ut=E.implementation.createHTMLDocument("").body).innerHTML="
    ",2===Ut.childNodes.length),S.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(y.createHTMLDocument?((r=(t=E.implementation.createHTMLDocument("")).createElement("base")).href=E.location.href,t.head.appendChild(r)):t=E),o=!n&&[],(i=N.exec(e))?[t.createElement(i[1])]:(i=xe([e],t,o),o&&o.length&&S(o).remove(),S.merge([],i.childNodes)));var r,i,o},S.fn.load=function(e,t,n){var r,i,o,a=this,s=e.indexOf(" ");return-1").append(S.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},S.expr.pseudos.animated=function(t){return S.grep(S.timers,function(e){return t===e.elem}).length},S.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l=S.css(e,"position"),c=S(e),f={};"static"===l&&(e.style.position="relative"),s=c.offset(),o=S.css(e,"top"),u=S.css(e,"left"),("absolute"===l||"fixed"===l)&&-1<(o+u).indexOf("auto")?(a=(r=c.position()).top,i=r.left):(a=parseFloat(o)||0,i=parseFloat(u)||0),m(t)&&(t=t.call(e,n,S.extend({},s))),null!=t.top&&(f.top=t.top-s.top+a),null!=t.left&&(f.left=t.left-s.left+i),"using"in t?t.using.call(e,f):("number"==typeof f.top&&(f.top+="px"),"number"==typeof f.left&&(f.left+="px"),c.css(f))}},S.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){S.offset.setOffset(this,t,e)});var e,n,r=this[0];return r?r.getClientRects().length?(e=r.getBoundingClientRect(),n=r.ownerDocument.defaultView,{top:e.top+n.pageYOffset,left:e.left+n.pageXOffset}):{top:0,left:0}:void 0},position:function(){if(this[0]){var e,t,n,r=this[0],i={top:0,left:0};if("fixed"===S.css(r,"position"))t=r.getBoundingClientRect();else{t=this.offset(),n=r.ownerDocument,e=r.offsetParent||n.documentElement;while(e&&(e===n.body||e===n.documentElement)&&"static"===S.css(e,"position"))e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=S(e).offset()).top+=S.css(e,"borderTopWidth",!0),i.left+=S.css(e,"borderLeftWidth",!0))}return{top:t.top-i.top-S.css(r,"marginTop",!0),left:t.left-i.left-S.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent;while(e&&"static"===S.css(e,"position"))e=e.offsetParent;return e||re})}}),S.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,i){var o="pageYOffset"===i;S.fn[t]=function(e){return $(this,function(e,t,n){var r;if(x(e)?r=e:9===e.nodeType&&(r=e.defaultView),void 0===n)return r?r[i]:e[t];r?r.scrollTo(o?r.pageXOffset:n,o?n:r.pageYOffset):e[t]=n},t,e,arguments.length)}}),S.each(["top","left"],function(e,n){S.cssHooks[n]=$e(y.pixelPosition,function(e,t){if(t)return t=Be(e,n),Me.test(t)?S(e).position()[n]+"px":t})}),S.each({Height:"height",Width:"width"},function(a,s){S.each({padding:"inner"+a,content:s,"":"outer"+a},function(r,o){S.fn[o]=function(e,t){var n=arguments.length&&(r||"boolean"!=typeof e),i=r||(!0===e||!0===t?"margin":"border");return $(this,function(e,t,n){var r;return x(e)?0===o.indexOf("outer")?e["inner"+a]:e.document.documentElement["client"+a]:9===e.nodeType?(r=e.documentElement,Math.max(e.body["scroll"+a],r["scroll"+a],e.body["offset"+a],r["offset"+a],r["client"+a])):void 0===n?S.css(e,t,i):S.style(e,t,n,i)},s,n?e:void 0,n)}})}),S.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){S.fn[t]=function(e){return this.on(t,e)}}),S.fn.extend({bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)},hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)}}),S.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,n){S.fn[n]=function(e,t){return 0 a").bind("click", function(e){ + var is_click_indicator = $(e.target).hasClass("sub_indicator"); + var a_obj = $(this); + if(a_obj.attr("href") == window.location.pathname){ + show_collapse_item(a_obj); + return false; + } + show_collapse_item(a_obj); + if(is_click_indicator){ // click indicator, only collapse, not jump to link + return false; + } + var screenW = $(window).width(); + if(screenW > 900){ + return; + } + link_href = $(this).attr("href").split(location.host); + if(link_href.length > 1){ + link_href = link_href[1]; + }else{ + link_href = link_href[0]; + } + url_href = location.href.split(location.host)[1] + let link_url = link_href.split("#")[0]; + let sub = $(this).next(); + var haveSub = false; + if(sub && sub.prop("nodeName")){ + haveSub = sub.prop("nodeName").toLowerCase() == "ul"; + } + if((link_href != decodeURIComponent(url_href) || !haveSub) && location.pathname == link_url){ // current page, and jump to header, close sidebar + location.href = link_href; + menu_toggle(); + } + }); +} + +function hello(){ + console.log('\n\n\ + _ _ \n\ + | | | | \n\ + | |_ ___ ___ __| | ___ ___ \n\ + | __/ _ \\/ _ \\/ _` |/ _ \\ / __|\n\ + | || __/ __/ (_| | (_) | (__ \n\ + \\__\\___|\\___|\\__,_|\\___/ \\___|\n\ + \n\ + generated by teedoc: \n\ + \n\ + https://github.com/teedoc/teedoc\n\ + \n\n\n\ +'); +} + + +function addTOC(){ + if(!document.getElementById("toc_content")) + return; + tocbot.init({ + // Where to render the table of contents. + tocSelector: '#toc_content', + // Where to grab the headings to build the table of contents. + contentSelector: '#article_content', + // Which headings to grab inside of the contentSelector element. + headingSelector: 'h1, h2, h3, h4', + // For headings inside relative or absolute positioned containers within content. + hasInnerContainers: true, + }); +} + +function toChineseNumber(n) { + if (!Number.isInteger(n) && n < 0) { + throw Error('请输入自然数'); + } + + const digits = ['零', '一', '二', '三', '四', '五', '六', '七', '八', '九']; + const positions = ['', '十', '百', '千', '万', '十万', '百万', '千万', '亿', '十亿', '百亿', '千亿']; + const charArray = String(n).split(''); + let result = ''; + let prevIsZero = false; + //处理0 deal zero + for (let i = 0; i < charArray.length; i++) { + const ch = charArray[i]; + if (ch !== '0' && !prevIsZero) { + result += digits[parseInt(ch)] + positions[charArray.length - i - 1]; + } else if (ch === '0') { + prevIsZero = true; + } else if (ch !== '0' && prevIsZero) { + result += '零' + digits[parseInt(ch)] + positions[charArray.length - i - 1]; + } + } + //处理十 deal ten + if (n < 100) { + result = result.replace('一十', '十'); + } + return result; + } + +function addSequence(){ + if(!tocbot._parseContent){ + return; + } + var headings = tocbot._parseContent.selectHeadings(document.getElementById("article_content"), tocbot.options.headingSelector); + var counth2=0, counth3=0, counth4=0; + var html = document.getElementsByTagName("html")[0]; + var isZh = html.lang.substring(0, 2).toLowerCase() == "zh"; + for(var i=0; i' + seq + ''); + } +} + + +function getSplitter(){ + var sizes = localStorage.getItem("splitter_w"); + if(sizes){ + try + { + sizes = JSON.parse(sizes); + } + catch(err) + { + sizes = false; + } + } + if(!sizes){ + var screenW = $(window).width(); + var split_w = 0; + if(!sidebar_width_is_percent){ + split_w = parseInt(sidebar_width/screenW*100); + }else{ + split_w = sidebar_width; + } + sizes = [split_w, 100-split_w]; + setSplitter(sizes); + } + return sizes; +} +function setSplitter(sizes){ + localStorage.setItem("splitter_w", JSON.stringify(sizes)); +} + +var hasSplitter = false; + +function createSplitter(){ + var split = Split(["#sidebar_wrapper", "#article"],{ + gutterSize: 3, + gutterAlign: 'start', + minSize: 200, + elementStyle: function (dimension, size, gutterSize) { + return { + 'width': 'calc(' + size + '% - ' + gutterSize + 'px)', + } + }, + onDragEnd: function (sizes) { + setSplitter(sizes) + }, + }); + hasSplitter = true; + var screenW = $(window).width(); + var sizes = getSplitter(); + split_w = parseInt(sizes[0]); + if(isNaN(split_w) || (split_w + 20) >= screenW){ + if(!sidebar_width_is_percent){ + split_w = parseInt(sidebar_width/screenW*100); + }else{ + split_w = sidebar_width; + } + } + split.setSizes([split_w, 100 - split_w]); + $(".gutter").append('
    '); + $(".gutter").hover(function(){ + $(".gutter").css("width", "10px"); + $(".gutter_icon").css("width", "10px"); + },function(){ + $(".gutter").css("width", "3px"); + $(".gutter_icon").css("width", "3px"); + }); +} + +function addSplitter(){ + var screenW = $(window).width(); + if(screenW > 900) + { + createSplitter(); + } +} + +function registerOnWindowResize(has_sidebar){ + window.onresize = function(){ + var screenW = $(window).width(); + if(!has_sidebar){ + return; + } + if(screenW < 900){ + $("#sidebar_wrapper").removeAttr("style"); + if($("#menu").hasClass("close")){ + $("#sidebar_wrapper").css("display", "block"); + } + $(".gutter").css("display", "none"); + $("#article").css("width", "100%"); + }else{ + if(!hasSplitter){ + createSplitter(); + } + if($("#sidebar_wrapper").css("display") != "none"){ + $(".gutter").css("display", "block"); + } + } + } +} + +function focusSidebar(){ + var windowH = window.innerHeight; + var active = $("#sidebar .active")[0]; + if(!active) + return; + var offset = active.offsetTop; + if(offset > windowH/2){ + $("#sidebar .show").scrollTop(offset); + } +} + +function imageViewer(){ + var content_e = document.getElementById("content_body"); + if(!content_e){ + content_e = document.getElementById("page_wrapper"); + } + const gallery = new Viewer(content_e); +} + +function addAnchor(){ + $("#content_body h2, #content_body h3, #content_body h4, #content_body h5").each(function(){ + if($(this).attr("id")){ + $(this).append('#'); + } + }); +} + +function rerender(){ + Prism.highlightAll(); +} + +function addPrintPage(){ + if(!$("#article_info_right")){ + return; + } + $("#article_info_right").append(''); + + var beforePrint = function(){ + // update style changed by js: + $("#article").css("width", "100%"); + // rerender for proper output + rerender(); + } + var afterPrint = function() { + // location.reload(); + } + if (window.matchMedia) { + var mediaQueryList = window.matchMedia('print'); + mediaQueryList.addListener(function(mql) { + if (mql.matches) { + beforePrint(); + } else { + afterPrint(); + } + }); + } + window.onbeforeprint = beforePrint; + window.onafterprint = afterPrint; + $("#print_page").click(function(){ + window.print(); + }); +} + +function addTocMobileListener(){ + $("#toc_btn").click(function(){ + if($("#toc_wrapper").hasClass("show")){ + $("#toc_wrapper").removeClass("show"); + }else{ + $("#toc_wrapper").addClass("show"); + } + }); + $("#toc_wrapper").click(function(){ + if($("#toc_btn").is(":visible")){ + $("#toc_wrapper").removeClass("show"); + } + }); +} + +function addTabsetListener(){ + $(".tabset-tab-label").on("click", function(){ + let this_obj = $(this); + // already active, do nothing + if(this_obj.hasClass("tabset-tab-active")){ + return; + } + // remove all active tabset-tab-active and tabset-text-active class from all have class that startswith tabset-id-, + // then add active class to the same idx tab-label and tab-text + let tabset_id = null; + let same_id_tabsets = []; + let old_idx = this_obj.parent().find(".tabset-tab-active").attr("idx"); + let new_idx = this_obj.attr("idx"); + let tabset_obj = this_obj.parent().parent().parent(); + tabset_obj.attr("class").split(' ').forEach(function(item){ + if(item.startsWith("tabset-id-")){ + tabset_id = item; + } + }); + if(!tabset_id){ + same_id_tabsets = [tabset_obj[0]]; // to DOM element + }else{ + same_id_tabsets = document.getElementsByClassName(tabset_id); + } + for (let tabset of same_id_tabsets) { + console.log(tabset); + let tab_labels = tabset.getElementsByClassName("tabset-tab-label"); + tab_labels[old_idx].classList.remove("tabset-tab-active"); + tab_labels[new_idx].classList.add("tabset-tab-active"); + let tab_texts = tabset.getElementsByClassName("tabset-text"); + tab_texts[old_idx].classList.remove("tabset-text-active"); + tab_texts[new_idx].classList.add("tabset-text-active"); + } + }); +} diff --git a/maixcdk/static/js/theme_default/pre_main.js b/maixcdk/static/js/theme_default/pre_main.js new file mode 100644 index 00000000..22a3025d --- /dev/null +++ b/maixcdk/static/js/theme_default/pre_main.js @@ -0,0 +1,54 @@ +(function(){ + var theme = getTheme(); + setTheme(theme); +}()); + +function addCss(filename) { + var head = document.getElementsByTagName('head')[0]; + var link = document.createElement('link'); + link.rel = 'stylesheet'; + link.type = 'text/css'; + link.href = filename; + head.appendChild(link); +} +function removejscssfile(filename, filetype) { + var targetelement = (filetype == "js") ? "script" : (filetype == "css") ? "link" : "none" + var targetattr = (filetype == "js") ? "src" : (filetype == "css") ? "href" : "none" + var allsuspects = document.getElementsByTagName(targetelement) + for (var i = allsuspects.length; i >= 0; i--) { + if (allsuspects[i] && allsuspects[i].getAttribute(targetattr) != null && allsuspects[i].getAttribute(targetattr).indexOf(filename) != -1) + allsuspects[i].parentNode.removeChild(allsuspects[i]) + } +} + + +function getTheme(){ + var t = localStorage.getItem("theme"); + if(!t){ + t = "light"; + setTheme(t); + } + return t; +} +function setTheme(theme){ + var obj = document.getElementById("themes"); + if(theme=="dark"){ + if(obj){ + obj.classList.remove("light"); + obj.classList.add("dark"); + } + document.getElementsByTagName("html")[0].classList.add("dark"); + // load dark and light togher, distingush by .dark class instead use single css file + // removejscssfile("/maixcdk/static/css/theme_default/light.css", "css"); + // addCss("/maixcdk/static/css/theme_default/dark.css"); + }else{ + if(obj){ + obj.classList.remove("dark"); + obj.classList.add("light"); + } + document.getElementsByTagName("html")[0].classList.remove("dark"); + // removejscssfile("/maixcdk/static/css/theme_default/dark.css", "css"); + // addCss("/maixcdk/static/css/theme_default/light.css"); + } + localStorage.setItem("theme", theme); +} diff --git a/maixcdk/static/js/theme_default/split.js b/maixcdk/static/js/theme_default/split.js new file mode 100644 index 00000000..79f2131a --- /dev/null +++ b/maixcdk/static/js/theme_default/split.js @@ -0,0 +1,3 @@ +/*! Split.js - v1.6.4 */ +!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e="undefined"!=typeof globalThis?globalThis:e||self).Split=t()}(this,(function(){"use strict";var e="undefined"!=typeof window?window:null,t=null===e,n=t?void 0:e.document,i=function(){return!1},r=t?"calc":["","-webkit-","-moz-","-o-"].filter((function(e){var t=n.createElement("div");return t.style.cssText="width:"+e+"calc(9px)",!!t.style.length})).shift()+"calc",s=function(e){return"string"==typeof e||e instanceof String},o=function(e){if(s(e)){var t=n.querySelector(e);if(!t)throw new Error("Selector "+e+" did not match a DOM element");return t}return e},a=function(e,t,n){var i=e[t];return void 0!==i?i:n},u=function(e,t,n,i){if(t){if("end"===i)return 0;if("center"===i)return e/2}else if(n){if("start"===i)return 0;if("center"===i)return e/2}return e},l=function(e,t){var i=n.createElement("div");return i.className="gutter gutter-"+t,i},c=function(e,t,n){var i={};return s(t)?i[e]=t:i[e]=r+"("+t+"% - "+n+"px)",i},h=function(e,t){var n;return(n={})[e]=t+"px",n};return function(r,s){if(void 0===s&&(s={}),t)return{};var d,f,v,m,g,p,y=r;Array.from&&(y=Array.from(y));var z=o(y[0]).parentNode,S=getComputedStyle?getComputedStyle(z):null,b=S?S.flexDirection:null,E=a(s,"sizes")||y.map((function(){return 100/y.length})),_=a(s,"minSize",100),L=Array.isArray(_)?_:y.map((function(){return _})),w=a(s,"maxSize",1/0),x=Array.isArray(w)?w:y.map((function(){return w})),k=a(s,"expandToMin",!1),C=a(s,"gutterSize",10),M=a(s,"gutterAlign","center"),U=a(s,"snapOffset",30),A=a(s,"dragInterval",1),O=a(s,"direction","horizontal"),D=a(s,"cursor","horizontal"===O?"col-resize":"row-resize"),B=a(s,"gutter",l),T=a(s,"elementStyle",c),j=a(s,"gutterStyle",h);function F(e,t,n,i){var r=T(d,t,n,i);Object.keys(r).forEach((function(t){e.style[t]=r[t]}))}function R(){return p.map((function(e){return e.size}))}function N(e){return"touches"in e?e.touches[0][f]:e[f]}function q(e){var t=p[this.a],n=p[this.b],i=t.size+n.size;t.size=e/this.size*i,n.size=i-e/this.size*i,F(t.element,t.size,this._b,t.i),F(n.element,n.size,this._c,n.i)}function H(e){var t,n=p[this.a],r=p[this.b];this.dragging&&(t=N(e)-this.start+(this._b-this.dragOffset),A>1&&(t=Math.round(t/A)*A),t<=n.minSize+U+this._b?t=n.minSize+this._b:t>=this.size-(r.minSize+U+this._c)&&(t=this.size-(r.minSize+this._c)),t>=n.maxSize-U+this._b?t=n.maxSize+this._b:t<=this.size-(r.maxSize-U+this._c)&&(t=this.size-(r.maxSize+this._c)),q.call(this,t),a(s,"onDrag",i)(R()))}function I(){var e=p[this.a].element,t=p[this.b].element,n=e.getBoundingClientRect(),i=t.getBoundingClientRect();this.size=n[d]+i[d]+this._b+this._c,this.start=n[v],this.end=n[m]}function W(e){var t=function(e){if(!getComputedStyle)return null;var t=getComputedStyle(e);if(!t)return null;var n=e[g];return 0===n?null:n-="horizontal"===O?parseFloat(t.paddingLeft)+parseFloat(t.paddingRight):parseFloat(t.paddingTop)+parseFloat(t.paddingBottom)}(z);if(null===t)return e;if(L.reduce((function(e,t){return e+t}),0)>t)return e;var n=0,i=[],r=e.map((function(r,s){var o=t*r/100,a=u(C,0===s,s===e.length-1,M),l=L[s]+a;return o0&&i[r]-n>0){var o=Math.min(n,i[r]-n);n-=o,s=e-o}return s/t*100}))}function X(){var t=p[this.a].element,r=p[this.b].element;this.dragging&&a(s,"onDragEnd",i)(R()),this.dragging=!1,e.removeEventListener("mouseup",this.stop),e.removeEventListener("touchend",this.stop),e.removeEventListener("touchcancel",this.stop),e.removeEventListener("mousemove",this.move),e.removeEventListener("touchmove",this.move),this.stop=null,this.move=null,t.removeEventListener("selectstart",i),t.removeEventListener("dragstart",i),r.removeEventListener("selectstart",i),r.removeEventListener("dragstart",i),t.style.userSelect="",t.style.webkitUserSelect="",t.style.MozUserSelect="",t.style.pointerEvents="",r.style.userSelect="",r.style.webkitUserSelect="",r.style.MozUserSelect="",r.style.pointerEvents="",this.gutter.style.cursor="",this.parent.style.cursor="",n.body.style.cursor=""}function Y(t){if(!("button"in t)||0===t.button){var r=p[this.a].element,o=p[this.b].element;this.dragging||a(s,"onDragStart",i)(R()),t.preventDefault(),this.dragging=!0,this.move=H.bind(this),this.stop=X.bind(this),e.addEventListener("mouseup",this.stop),e.addEventListener("touchend",this.stop),e.addEventListener("touchcancel",this.stop),e.addEventListener("mousemove",this.move),e.addEventListener("touchmove",this.move),r.addEventListener("selectstart",i),r.addEventListener("dragstart",i),o.addEventListener("selectstart",i),o.addEventListener("dragstart",i),r.style.userSelect="none",r.style.webkitUserSelect="none",r.style.MozUserSelect="none",r.style.pointerEvents="none",o.style.userSelect="none",o.style.webkitUserSelect="none",o.style.MozUserSelect="none",o.style.pointerEvents="none",this.gutter.style.cursor=D,this.parent.style.cursor=D,n.body.style.cursor=D,I.call(this),this.dragOffset=N(t)-this.end}}"horizontal"===O?(d="width",f="clientX",v="left",m="right",g="clientWidth"):"vertical"===O&&(d="height",f="clientY",v="top",m="bottom",g="clientHeight"),E=W(E);var G=[];function J(e){var t=e.i===G.length,n=t?G[e.i-1]:G[e.i];I.call(n);var i=t?n.size-e.minSize-n._c:e.minSize+n._b;q.call(n,i)}return(p=y.map((function(e,t){var n,i={element:o(e),size:E[t],minSize:L[t],maxSize:x[t],i:t};if(t>0&&((n={a:t-1,b:t,dragging:!1,direction:O,parent:z})._b=u(C,t-1==0,!1,M),n._c=u(C,!1,t===y.length-1,M),"row-reverse"===b||"column-reverse"===b)){var r=n.a;n.a=n.b,n.b=r}if(t>0){var s=B(t,O,i.element);!function(e,t,n){var i=j(d,t,n);Object.keys(i).forEach((function(t){e.style[t]=i[t]}))}(s,C,t),n._a=Y.bind(n),s.addEventListener("mousedown",n._a),s.addEventListener("touchstart",n._a),z.insertBefore(s,i.element),n.gutter=s}return F(i.element,i.size,u(C,0===t,t===y.length-1,M),t),t>0&&G.push(n),i}))).forEach((function(e){var t=e.element.getBoundingClientRect()[d];t0){var i=G[n-1],r=p[i.a],s=p[i.b];r.size=t[n-1],s.size=e,F(r.element,r.size,i._b,r.i),F(s.element,s.size,i._c,s.i)}}))},getSizes:R,collapse:function(e){J(p[e])},destroy:function(e,t){G.forEach((function(n){if(!0!==t?n.parent.removeChild(n.gutter):(n.gutter.removeEventListener("mousedown",n._a),n.gutter.removeEventListener("touchstart",n._a)),!0!==e){var i=T(d,n.a.size,n._b);Object.keys(i).forEach((function(e){p[n.a].element.style[e]="",p[n.b].element.style[e]=""}))}}))},parent:z,pairs:G}}})); +//# sourceMappingURL=split.min.js.map diff --git a/maixcdk/static/js/theme_default/tocbot.min.js b/maixcdk/static/js/theme_default/tocbot.min.js new file mode 100644 index 00000000..64f46c79 --- /dev/null +++ b/maixcdk/static/js/theme_default/tocbot.min.js @@ -0,0 +1 @@ +(()=>{var e={163:e=>{e.exports=function(e){var t=[].forEach,n=[].some,o=document.body,l=!0,r=" ";function i(n,o){var l,c,a,u=o.appendChild((l=n,c=document.createElement("li"),a=document.createElement("a"),e.listItemClass&&c.setAttribute("class",e.listItemClass),e.onClick&&(a.onclick=e.onClick),e.includeTitleTags&&a.setAttribute("title",l.textContent),e.includeHtml&&l.childNodes.length?t.call(l.childNodes,(function(e){a.appendChild(e.cloneNode(!0))})):a.textContent=l.textContent,a.setAttribute("href",e.basePath+"#"+l.id),a.setAttribute("class",e.linkClass+r+"node-name--"+l.nodeName+r+e.extraLinkClasses),c.appendChild(a),c));if(n.children.length){var d=s(n.isCollapsed);n.children.forEach((function(e){i(e,d)})),u.appendChild(d)}}function s(t){var n=e.orderedList?"ol":"ul",o=document.createElement(n),l=e.listClass+r+e.extraListClasses;return t&&(l+=r+e.collapsibleClass,l+=r+e.isCollapsedClass),o.setAttribute("class",l),o}function c(t){var n=0;return t!==document.querySelector(e.contentSelector&&null!=t)&&(n=t.offsetTop,e.hasInnerContainers&&(n+=c(t.offsetParent))),n}function a(t){return t&&-1!==t.className.indexOf(e.collapsibleClass)&&-1!==t.className.indexOf(e.isCollapsedClass)?(t.className=t.className.split(r+e.isCollapsedClass).join(""),a(t.parentNode.parentNode)):t}return{enableTocAnimation:function(){l=!0},disableTocAnimation:function(t){var n=t.target||t.srcElement;"string"==typeof n.className&&-1!==n.className.indexOf(e.linkClass)&&(l=!1)},render:function(e,t){var n=s(!1);if(t.forEach((function(e){i(e,n)})),null!==e)return e.firstChild&&e.removeChild(e.firstChild),0===t.length?e:e.appendChild(n)},updateToc:function(i){var s;s=e.scrollContainer&&document.querySelector(e.scrollContainer)?document.querySelector(e.scrollContainer).scrollTop:document.documentElement.scrollTop||o.scrollTop,e.positionFixedSelector&&function(){var t;t=e.scrollContainer&&document.querySelector(e.scrollContainer)?document.querySelector(e.scrollContainer).scrollTop:document.documentElement.scrollTop||o.scrollTop;var n=document.querySelector(e.positionFixedSelector);"auto"===e.fixedSidebarOffset&&(e.fixedSidebarOffset=document.querySelector(e.tocSelector).offsetTop),t>e.fixedSidebarOffset?-1===n.className.indexOf(e.positionFixedClass)&&(n.className+=r+e.positionFixedClass):n.className=n.className.split(r+e.positionFixedClass).join("")}();var u,d=i;if(l&&null!==document.querySelector(e.tocSelector)&&d.length>0){n.call(d,(function(t,n){return c(t)>s+e.headingsOffset+10?(u=d[0===n?n:n-1],!0):n===d.length-1?(u=d[d.length-1],!0):void 0}));var f=document.querySelector(e.tocSelector).querySelectorAll("."+e.linkClass);t.call(f,(function(t){t.className=t.className.split(r+e.activeLinkClass).join("")}));var m=document.querySelector(e.tocSelector).querySelectorAll("."+e.listItemClass);t.call(m,(function(t){t.className=t.className.split(r+e.activeListItemClass).join("")}));var h=document.querySelector(e.tocSelector).querySelector("."+e.linkClass+".node-name--"+u.nodeName+'[href="'+e.basePath+"#"+u.id.replace(/([ #;&,.+*~':"!^$[\]()=>|/@])/g,"\\$1")+'"]');h&&-1===h.className.indexOf(e.activeLinkClass)&&(h.className+=r+e.activeLinkClass);var p=h&&h.parentNode;p&&-1===p.className.indexOf(e.activeListItemClass)&&(p.className+=r+e.activeListItemClass);var C=document.querySelector(e.tocSelector).querySelectorAll("."+e.listClass+"."+e.collapsibleClass);t.call(C,(function(t){-1===t.className.indexOf(e.isCollapsedClass)&&(t.className+=r+e.isCollapsedClass)})),h&&h.nextSibling&&-1!==h.nextSibling.className.indexOf(e.isCollapsedClass)&&(h.nextSibling.className=h.nextSibling.className.split(r+e.isCollapsedClass).join("")),a(h&&h.parentNode.parentNode)}}}}},547:e=>{e.exports={tocSelector:".js-toc",contentSelector:".js-toc-content",headingSelector:"h1, h2, h3",ignoreSelector:".js-toc-ignore",hasInnerContainers:!1,linkClass:"toc-link",extraLinkClasses:"",activeLinkClass:"is-active-link",listClass:"toc-list",extraListClasses:"",isCollapsedClass:"is-collapsed",collapsibleClass:"is-collapsible",listItemClass:"toc-list-item",activeListItemClass:"is-active-li",collapseDepth:0,scrollSmooth:!0,scrollSmoothDuration:420,scrollSmoothOffset:0,scrollEndCallback:function(e){},headingsOffset:1,throttleTimeout:50,positionFixedSelector:null,positionFixedClass:"is-position-fixed",fixedSidebarOffset:"auto",includeHtml:!1,includeTitleTags:!1,onClick:function(e){},orderedList:!0,scrollContainer:null,skipRendering:!1,headingLabelCallback:!1,ignoreHiddenElements:!1,headingObjectCallback:null,basePath:"",disableTocScrollSync:!1}},971:function(e,t,n){var o,l,r;l=[],o=function(e){"use strict";var t,o,l,r=n(547),i={},s={},c=n(163),a=n(279),u=n(938),d=!!(e&&e.document&&e.document.querySelector&&e.addEventListener);if("undefined"!=typeof window||d){var f=Object.prototype.hasOwnProperty;return s.destroy=function(){var e=h(i);null!==e&&(i.skipRendering||e&&(e.innerHTML=""),i.scrollContainer&&document.querySelector(i.scrollContainer)?(document.querySelector(i.scrollContainer).removeEventListener("scroll",this._scrollListener,!1),document.querySelector(i.scrollContainer).removeEventListener("resize",this._scrollListener,!1),t&&document.querySelector(i.scrollContainer).removeEventListener("click",this._clickListener,!1)):(document.removeEventListener("scroll",this._scrollListener,!1),document.removeEventListener("resize",this._scrollListener,!1),t&&document.removeEventListener("click",this._clickListener,!1)))},s.init=function(e){if(d){i=function(){for(var e={},t=0;t{e.exports=function(e){var t=[].reduce;function n(e){return e[e.length-1]}function o(e){return+e.nodeName.toUpperCase().replace("H","")}function l(t){if(!(t instanceof window.HTMLElement))return t;if(e.ignoreHiddenElements&&(!t.offsetHeight||!t.offsetParent))return null;const n=t.getAttribute("data-heading-label")||(e.headingLabelCallback?String(e.headingLabelCallback(t.textContent)):t.textContent.trim());var l={id:t.id,children:[],nodeName:t.nodeName,headingLevel:o(t),textContent:n};return e.includeHtml&&(l.childNodes=t.childNodes),e.headingObjectCallback?e.headingObjectCallback(l,t):l}return{nestHeadingsArray:function(o){return t.call(o,(function(t,o){var r=l(o);return r&&function(t,o){for(var r=l(t),i=r.headingLevel,s=o,c=n(s),a=i-(c?c.headingLevel:0);a>0&&(!(c=n(s))||i!==c.headingLevel);)c&&void 0!==c.children&&(s=c.children),a--;i>=e.collapseDepth&&(r.isCollapsed=!0),s.push(r)}(r,t.nest),t}),{nest:[]})},selectHeadings:function(t,n){var o=n;e.ignoreSelector&&(o=n.split(",").map((function(t){return t.trim()+":not("+e.ignoreSelector+")"})));try{return t.querySelectorAll(o)}catch(e){return console.warn("Headers not found with selector: "+o),null}}}}},374:(e,t)=>{t.initSmoothScrolling=function(e){var t=e.duration,n=e.offset,o=location.hash?l(location.href):location.href;function l(e){return e.slice(0,e.lastIndexOf("#"))}document.body.addEventListener("click",(function(r){var i;"a"!==(i=r.target).tagName.toLowerCase()||!(i.hash.length>0||"#"===i.href.charAt(i.href.length-1))||l(i.href)!==o&&l(i.href)+"#"!==o||r.target.className.indexOf("no-smooth-scroll")>-1||"#"===r.target.href.charAt(r.target.href.length-2)&&"!"===r.target.href.charAt(r.target.href.length-1)||-1===r.target.className.indexOf(e.linkClass)||function(e,t){var n,o,l=window.pageYOffset,r={duration:t.duration,offset:t.offset||0,callback:t.callback,easing:t.easing||function(e,t,n,o){return(e/=o/2)<1?n/2*e*e+t:-n/2*(--e*(e-2)-1)+t}},i=document.querySelector('[id="'+decodeURI(e).split("#").join("")+'"]')||document.querySelector('[id="'+e.split("#").join("")+'"]'),s="string"==typeof e?r.offset+(e?i&&i.getBoundingClientRect().top||0:-(document.documentElement.scrollTop||document.body.scrollTop)):e,c="function"==typeof r.duration?r.duration(s):r.duration;function a(e){o=e-n,window.scrollTo(0,r.easing(o,l,s,c)),o{e.exports=function(e){var t=document.querySelector(e.tocSelector);if(t&&t.scrollHeight>t.clientHeight){var n=t.querySelector("."+e.activeListItemClass);n&&(t.scrollTop=n.offsetTop)}}}},t={};function n(o){var l=t[o];if(void 0!==l)return l.exports;var r=t[o]={exports:{}};return e[o].call(r.exports,r,r.exports,n),r.exports}n.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"==typeof window)return window}}(),n(971)})(); \ No newline at end of file diff --git a/maixcdk/static/js/theme_default/viewer.min.js b/maixcdk/static/js/theme_default/viewer.min.js new file mode 100644 index 00000000..c5376e39 --- /dev/null +++ b/maixcdk/static/js/theme_default/viewer.min.js @@ -0,0 +1,10 @@ +/*! + * Viewer.js v1.10.0 + * https://fengyuanchen.github.io/viewerjs + * + * Copyright 2015-present Chen Fengyuan + * Released under the MIT license + * + * Date: 2021-06-12T07:57:10.970Z + */ +!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t="undefined"!=typeof globalThis?globalThis:t||self).Viewer=e()}(this,function(){"use strict";function e(e,t){var i,n=Object.keys(e);return Object.getOwnPropertySymbols&&(i=Object.getOwnPropertySymbols(e),t&&(i=i.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),n.push.apply(n,i)),n}function l(n){for(var t=1;t=this.length||this.viewed&&t===this.index)return this;if(!this.isShown)return this.index=t,this.show();this.viewing&&this.viewing.abort();var e=this.element,n=this.options,o=this.title,s=this.canvas,a=this.items[t],r=a.querySelector("img"),h=gt(r,"originalUrl"),l=r.getAttribute("alt"),c=document.createElement("img");if(ot(n.inheritedAttributes,function(t){var e=r.getAttribute(t);null!==e&&c.setAttribute(t,e)}),c.src=h,c.alt=l,nt(n.view)&&yt(e,"view",n.view,{once:!0}),!1===xt(e,"view",{originalImage:this.images[t],index:t,image:c})||!this.isShown||this.hiding||this.played)return this;h=this.items[this.index];ct(h,m),h.removeAttribute("aria-selected"),lt(a,m),a.setAttribute("aria-selected",!0),n.focus&&a.focus(),this.image=c,this.viewed=!1,this.index=t,this.imageData={},lt(c,D),n.loading&<(s,T),s.innerHTML="",s.appendChild(c),this.renderList(),o.innerHTML="";function u(){var t=i.imageData,e=Array.isArray(n.title)?n.title[1]:n.title;o.innerHTML=_(t=nt(e)?e.call(i,c,t):"".concat(l," (").concat(t.naturalWidth," × ").concat(t.naturalHeight,")"))?t.replace(/&(?!amp;|quot;|#39;|lt;|gt;)/g,"&").replace(/"/g,""").replace(/'/g,"'").replace(//g,">"):t}var d;return yt(e,V,u,{once:!0}),this.viewing={abort:function(){wt(e,V,u),c.complete?i.imageRendering?i.imageRendering.abort():i.imageInitializing&&i.imageInitializing.abort():(c.src="",wt(c,N,d),i.timeout&&clearTimeout(i.timeout))}},c.complete?this.load():(yt(c,N,d=this.load.bind(this),{once:!0}),this.timeout&&clearTimeout(this.timeout),this.timeout=setTimeout(function(){ct(c,D),i.timeout=!1},1e3)),this},prev:function(){var t=this.index-1;return t<0&&(t=0Math.abs(r)&&(this.pointers={},1
    ',n=(i=d.querySelector(".".concat(g,"-container"))).querySelector(".".concat(g,"-title")),o=i.querySelector(".".concat(g,"-toolbar")),a=i.querySelector(".".concat(g,"-navbar")),m=i.querySelector(".".concat(g,"-button")),d=i.querySelector(".".concat(g,"-canvas")),this.parent=e,this.viewer=i,this.title=n,this.toolbar=o,this.navbar=a,this.button=m,this.canvas=d,this.footer=i.querySelector(".".concat(g,"-footer")),this.tooltipBox=i.querySelector(".".concat(g,"-tooltip")),this.player=i.querySelector(".".concat(g,"-player")),this.list=i.querySelector(".".concat(g,"-list")),i.id="".concat(g).concat(this.id),n.id="".concat(g,"Title").concat(this.id),lt(n,s.title?Tt(Array.isArray(s.title)?s.title[0]:s.title):w),lt(a,s.navbar?Tt(s.navbar):w),ut(m,w,!s.button),s.keyboard&&m.setAttribute("tabindex",0),s.backdrop&&(lt(i,"".concat(g,"-backdrop")),s.inline||"static"===s.backdrop||ft(d,K,"hide")),_(s.className)&&s.className&&s.className.split(Z).forEach(function(t){lt(i,t)}),s.toolbar?(r=document.createElement("ul"),h=it(s.toolbar),l=$.slice(0,3),c=$.slice(7,9),u=$.slice(9),h||lt(o,Tt(s.toolbar)),ot(h?s.toolbar:$,function(t,e){var i=h&&it(t),n=h?mt(e):t,o=i&&!Q(t.show)?t.show:t;!o||!s.zoomable&&-1!==l.indexOf(n)||!s.rotatable&&-1!==c.indexOf(n)||!s.scalable&&-1!==u.indexOf(n)||(e=i&&!Q(t.size)?t.size:t,i=i&&!Q(t.click)?t.click:t,t=document.createElement("li"),s.keyboard&&t.setAttribute("tabindex",0),t.setAttribute("role","button"),lt(t,"".concat(g,"-").concat(n)),nt(i)||ft(t,K,n),J(o)&<(t,Tt(o)),-1!==["small","large"].indexOf(e)?lt(t,"".concat(g,"-").concat(e)):"play"===n&<(t,"".concat(g,"-large")),nt(i)&&yt(t,O,i),r.appendChild(t))}),o.appendChild(r)):lt(o,w),s.rotatable||(lt(d=o.querySelectorAll('li[class*="rotate"]'),D),ot(d,function(t){o.appendChild(t)})),s.inline?(lt(m,b),rt(i,{zIndex:s.zIndexInline}),"static"===window.getComputedStyle(e).position&&rt(e,{position:"relative"}),e.insertBefore(i,t.nextSibling)):(lt(m,f),lt(i,p),lt(i,v),lt(i,w),rt(i,{zIndex:s.zIndex}),(m=(m=_(m=s.container)?t.ownerDocument.querySelector(m):m)||this.body).appendChild(i)),s.inline&&(this.render(),this.bind(),this.isShown=!0),this.ready=!0,nt(s.ready)&&yt(t,j,s.ready,{once:!0}),!1!==xt(t,j)?this.ready&&s.inline&&this.view(this.index):this.ready=!1)}}])&&o(t.prototype,e),n&&o(t,n),i}();return st(n.prototype,It,r,t,St,Ot),n}); \ No newline at end of file diff --git a/maixcdk/static/js/thumbs_up/main.js b/maixcdk/static/js/thumbs_up/main.js new file mode 100644 index 00000000..b463ed74 --- /dev/null +++ b/maixcdk/static/js/thumbs_up/main.js @@ -0,0 +1,215 @@ + + +var conf=js_vars["teedoc-plugin-thumbs-up"]; +(function(){ + document.addEventListener("DOMContentLoaded", function(event) { + var contentBody = document.getElementById("content_body"); + if(!contentBody){ + return; + } + // add message show element + var messageEL = document.createElement("div"); + messageEL.className = "thumbs-message"; + let msgContentEl = document.createElement("div"); + msgContentEl.classList = ["thumbs-message-content"]; + messageEL.appendChild(msgContentEl); + contentBody.appendChild(messageEL); + // create a div to hold the thumbs up button, and add it to the content body + var thumbsUpDiv = document.createElement("div"); + thumbsUpDiv.id = "thumbs_up_container"; + contentBody.appendChild(thumbsUpDiv); + // create the thumbs up button + var thumbsUpButton = document.createElement("button"); + thumbsUpButton.classList = ["thumbs-up"]; + thumbsUpDiv.appendChild(thumbsUpButton); + var thumbsUpIcon = document.createElement("img"); + thumbsUpIcon.src = conf.icon; + thumbsUpIcon.classList = ["thumbs-up-icon"]; + thumbsUpButton.appendChild(thumbsUpIcon); + var thumbsUpLabel = document.createElement("span"); + thumbsUpLabel.classList = ["thumbs-up-label"]; + thumbsUpLabel.innerHTML = conf.label_up; + thumbsUpButton.appendChild(thumbsUpLabel); + var thumbsUpCount = document.createElement("span"); + thumbsUpCount.classList = ["thumbs-up-count"]; + thumbsUpCount.innerHTML = "(0)"; + thumbsUpButton.appendChild(thumbsUpCount); + // create the thumbs down button + var thumbsDownButton = document.createElement("button"); + thumbsDownButton.classList = ["thumbs-down"]; + thumbsUpDiv.appendChild(thumbsDownButton); + var thumbsDownIcon = document.createElement("img"); + thumbsDownIcon.src = conf.icon; + thumbsDownIcon.classList = ["thumbs-down-icon"]; + thumbsDownButton.appendChild(thumbsDownIcon); + var thumbsDownLabel = document.createElement("span"); + thumbsDownLabel.classList = ["thumbs-down-label"]; + thumbsDownLabel.innerHTML = conf.label_down; + thumbsDownButton.appendChild(thumbsDownLabel); + var thumbsDownCount = document.createElement("span"); + thumbsDownCount.classList = ["thumbs-down-count"]; + thumbsDownCount.innerHTML = ""; + thumbsDownButton.appendChild(thumbsDownCount); + // add click listeners to the buttons + var thumbs_up = document.getElementsByClassName("thumbs-up"); + for (var i = 0; i < thumbs_up.length; i++) { + thumbs_up[i].addEventListener("click", function(e) { + onClick(true); + }); + } + var thumbs_down = document.getElementsByClassName("thumbs-down"); + for (var i = 0; i < thumbs_down.length; i++) { + thumbs_down[i].addEventListener("click", function(e) { + onClick(false); + }); + } + setIcon(); + getCount(); + }); +})(); + +function showMsg(msg){ + let msgEl = document.getElementsByClassName("thumbs-message")[0]; + let msgContentEl = document.getElementsByClassName("thumbs-message-content")[0]; + msgContentEl.innerHTML = msg; + if (jQuery) { + $(msgEl).fadeIn(500, function(){ + setTimeout(function(){ + $(msgEl).fadeOut(500); + }, 3000); + }); + }else{ + console.log("no jquery"); + msgEl.style.display = "flex"; + setTimeout(function(){ + msgEl.style.display = "none"; + }, 5000); + } +} + +function onClick(up){ + let path = check_path(location.pathname); + let did = localStorage.getItem("thumbs_" + (up?"up":"down") + "_" + path); + if (did){ + showMsg(conf.msg_already_voted); + return; + } + var url = conf.url; + if(up){ + url = url + "/api/thumbs_up"; + }else{ + url = url + "/api/thumbs_down"; + } + var page = location.pathname + var data = { + "type": up ? "up" : "down", + "path": page, + "url": location.protocol + "//" + location.host + location.pathname + }; + if(!up){ + data["msg"] = prompt(conf.msg_down_prompt); + if(!data["msg"]){ + return; + } + if(data["msg"].length < 10){ + showMsg(conf.msg_down_prompt_error); + return; + } + } + var xhr = new XMLHttpRequest(); + xhr.open("POST", url, true); + xhr.setRequestHeader("Content-Type", "application/json"); + xhr.onreadystatechange = function() { + if (xhr.readyState === 4 && xhr.status === 200) { + var response = JSON.parse(xhr.responseText); + setUpCount(response["up_count"], up); + setDownCount(response["down_count"], !up); + showMsg(conf.msg_thanks); + }else if (xhr.status != 200){ + showMsg(conf.msg_error); + } + }; + xhr.send(JSON.stringify(data)); +} + +function getCount(){ + let path = check_path(location.pathname); + let url = conf.url + "/api/thumbs_count"; + var data = { + "path": path + }; + var xhr = new XMLHttpRequest(); + xhr.open("POST", url, true); + xhr.setRequestHeader("Content-Type", "application/json"); + xhr.onreadystatechange = function() { + if (xhr.readyState === 4 && xhr.status === 200) { + var response = JSON.parse(xhr.responseText); + setUpCount(response["up_count"]); + setDownCount(response["down_count"]); + }else if (xhr.status != 200){ + showMsg(conf.msg_error); + } + }; + xhr.send(JSON.stringify(data)); +} + +function check_path(path){ + if(!path){ + return path; + } + if (path[path.length - 1] == "/"){ + path = path + "index.html"; + }else{ + let temp = path.split("/"); + if(temp[temp.length - 1].indexOf(".") == -1){ + path = path + ".html"; + } + } + return path; +} + +function setUpCount(count, add=false){ + if(add){ + let path = check_path(location.pathname); + localStorage.setItem("thumbs_up_" + path, true); + setIcon(); + } + if(!conf.show_up_count){ + return; + } + var selector = ".thumbs-up-count"; + var thumbs_up = document.querySelector(selector); + thumbs_up.innerHTML = "(" + count + ")"; +} + +function setDownCount(count, add=false){ + if(add){ + let path = check_path(location.pathname); + localStorage.setItem("thumbs_down_" + path, true); + setIcon(); + } + if(!conf.show_down_count){ + return; + } + var selector = ".thumbs-down-count"; + var thumbs_down = document.querySelector(selector); + thumbs_down.innerHTML = "(" + count + ")"; +} + +function setIcon(){ + let path = check_path(location.pathname); + let upIcon = document.getElementsByClassName("thumbs-up-icon")[0]; + let downIcon = document.getElementsByClassName("thumbs-down-icon")[0]; + let did = localStorage.getItem("thumbs_up_" + path); + if (did){ + upIcon.src = conf.icon_clicked; + }else{ + upIcon.src = conf.icon; + } + did = localStorage.getItem("thumbs_down_" + path); + if (did){ + downIcon.src = conf.icon_clicked; + }else{ + downIcon.src = conf.icon; + } +} diff --git a/maixcdk/static/js/thumbs_up/style.css b/maixcdk/static/js/thumbs_up/style.css new file mode 100644 index 00000000..89b5dd01 --- /dev/null +++ b/maixcdk/static/js/thumbs_up/style.css @@ -0,0 +1,66 @@ +#thumbs_up_container{ + margin-top: 2em; + display: inline-flex; + border-top: 0.1em solid #f1f1f1; +} + +#thumbs_up_container button { + padding: 1em; + border-radius: 0.6em; + background-color: #f1f1f1; + color: #606975; + border: none; + cursor: pointer; + margin: 0.5em 1em; + transition: 0.4s; + display: flex; + align-items: center; +} +#thumbs_up_container button:hover { + scale: 1.2; +} +#thumbs_up_container button > img { + margin-right: 1em; + cursor: pointer; +} +.thumbs-down-icon { + transform: rotate(180deg); +} +.thumbs-up-count { + padding: 0 0.5em; + color: #26a69a; +} +.thumbs-message { + display: none; + position: fixed; + top: 3em; + right: 1em; + background-color: #4caf50; + color: white; + border-radius: 0.6em; + align-items: center; + padding: 1em; + z-index: 999999; +} +.thumbs-message-content { + display: flex; + align-items: center; + height: 4em; + min-width: 6em; +} + +/* dark mode */ + +.dark #thumbs_up_container{ + border-top: 0.1em solid #2d2d2d; +} +.dark #thumbs_up_container button { + background-color: #2d2d2d; + color: #a2a2a2; +} + +@media print { + #thumbs_up_container { + display: none; + } +} diff --git a/maixcdk/static/search_index/index.json b/maixcdk/static/search_index/index.json new file mode 100644 index 00000000..6d576e2c --- /dev/null +++ b/maixcdk/static/search_index/index.json @@ -0,0 +1 @@ +{"/doc/":["MaixCDK","/maixcdk/static/search_index/index_0.json"],"/api/":["MaixCDK API Doc","/maixcdk/static/search_index/index_1.json"],"/doc/zh/":["MaixCDK 中文文档","/maixcdk/static/search_index/index_2.json"],"/":["Pages","/maixcdk/static/search_index/index_3.json"],"/zh/":["中文页面","/maixcdk/static/search_index/index_4.json"]} \ No newline at end of file diff --git a/maixcdk/static/search_index/index_0.json b/maixcdk/static/search_index/index_0.json new file mode 100644 index 00000000..c3b156e0 --- /dev/null +++ b/maixcdk/static/search_index/index_0.json @@ -0,0 +1 @@ +{"/maixcdk/doc/convention/add_api.html":{"title":"Add API for MaixCDK / MaixPy","content":" title: Add API for MaixCDK / MaixPy ## Code Guidelines Please refer to [Code Guidelines](./index.html) first. ## How to Add an API At the end of the [Quick Start](../index.html), we briefly mentioned adding a new API to MaixPy using annotations. It looks straightforward – you only need to add a comment to the API function, for example: ```cpp namespace maix::example { /** * @brief Say hello to someone * @param[in] name The name of the person, of string type * @return A string containing \"hello\" + name * @maixpy maix.example.hello */ std::string hello(std::string name); } ``` Then you can call this in MaixPy: ```python from maix import example result example.hello(\"Bob\") print(result) ``` To ensure that the APIs we add are **usable** for users, we need to follow these guidelines: * Design the API names and parameters to be reasonable, general, and highly cross platform. * Ensure the API is annotated (documentation will be automatically generated during compilation). * The API should come with usage documentation, a tutorial, and example code. Here is a more detailed process and guidelines: 1. **Confirm the functionality and add a usage document and example code in the [MaixPy Documentation Source](https://github.com/sipeed/MaixPy/tree/main/docs/doc)**. This acts as a design document, helping to avoid frequent API changes due to incomplete considerations during coding. It also serves as documentation. **(This is very important!)** 2. You can add an **application document** under [docs/doc/application](https://github.com/sipeed/MaixCDK/tree/main/docs/doc/application) to record development details. Use lowercase filenames with underscores, e.g., `peripheral/uart.md` or `ai/yolov2.md`. 3. Mention the sources or open source projects referenced for API design in the development document to facilitate the review process and improve the chances of passing the review quickly. 4. Refer to [components/basic/include/maix_api_example.hpp] and add the API to an appropriate `component`. If it's a new component, consider discussing its rationality first in [issues](https://github.com/sipeed/MaixCDK/issues). > Note: The `API` is identified through comments, which helps automatically generate documentation and `MaixPy` source code. Pay close attention to the annotation guidelines and refer to `maix_api_example.hpp` for specifics. > Additionally, because `MaixCDK` does not include definitions related to `Python.h` or `Pybind11.h`, language native types are automatically converted by `pybind11`. For instance, `void hello(std::string a, std::vector b)` is equivalent to `def hello(a: str, b: list)` in `MaixPy`. > Common conversions include `std::vector` to `list`, `std::map` to `dict`, `std::valarray` (accepts `list` and `bytes` as input, returns `list`), and `maix::Bytes` (both input and return values are `bytes`). `std::function` maps to a function in MaixPy. For more details, refer to the [pybind11 documentation](https://pybind11.readthedocs.io/en/stable/advanced/cast/overview.html#conversion table). 5. Add a C++ example to the `examples` directory and ensure it compiles and runs successfully. 6. The documentation will be automatically generated during compilation. Check the generated files under `docs/doc/api` for any errors and correct them in the code if needed. 7. Test the updated `MaixPy` project with the new `MaixCDK` to ensure it compiles successfully and the generated documentation is correct. Fix any errors if they occur. 8. Submit your code to your own GitHub repository and wait for the `action` to automatically build and test it. Correct any errors promptly. 9. Once all online tests pass, submit a `PR` (Pull Request) and request to merge it into the `dev` branch on [GitHub](https://github.com/sipeed/MaixCDK). ## Manually Adding a MaixPy API The above method can automatically generate a MaixPy API, but in certain scenarios, manual addition might be necessary. For example, when the parameter is a specific type, such as `numpy.array`: * Add the header file and code under `components/maix/include` in the `MaixPy` project. You can use the same `namespace` as in `MaixCDK`. For instance, the function `maix.image.cv2image` converts a `numpy` array to an `image.Image` object. Refer to the definitions in the `convert_image.hpp` file. More references: * [Building MaixPy](https://wiki.sipeed.com/maixpy/doc/zh/source_code/build.html) * [Adding a C/C++ Module to MaixPy for MaixCAM](https://wiki.sipeed.com/maixpy/doc/zh/source_code/add_c_module.html)"},"/maixcdk/doc/dev/vscode_debug.html":{"title":"使用 VSCode 在线调试","content":" title: 使用 VSCode 在线调试 ## 调试 这里主要提供 vscode + gdb 的调试方法,看不太懂可以先跳过,可以先使用代码加`printf`打印的方式调试。 **(1).** 对于在本机(PC)运行,VSCode + GDB 在线调试 这里以 PC 为 Linux 系统为例: * 添加 MaixCDK(第一次试用推荐这样) 或者 工程目录到 VSCode 工作区 * 拷贝 [tools/vscode/vscode_local_debug/.vscode](../../../tools/vscode/vscode_local_debug/.vscode) 目录到上一步的工作目录下 * 根据`.vscode`是在 MaixCDK 还是在工程目录下,修改`.vscode/launch.json`中的`cwd`字段 * 按键盘 `F5` 即可开始调试 > windows 也类似,修改`.vscode`里面的相关命令和路径即可 **(2).** 对于在嵌入式设备(/远程设备,带 Linux 系统)调试 使用 VSCode + gdbserver 在嵌入式设备(/远程设备,带 Linux 系统)调试 这里以 PC 为 Linux 系统为例: * 先保证远程设备有`gdbserver`这个程序,以及 PC 有`gdb multiarch`这个程序 * 将 [tools/vscode/vscode_remote_debug/.vscode](../../../tools/vscode/vscode_remote_debug/.vscode) 目录拷贝到工程目录下 * 编辑 `launch.json` 和 `build_run_gdbserver.sh` 文件,修改里面的路径和命令,以及用户名等。 > 建议先将 PC 的 ssh key 加入到远程设备的 `~/.ssh/authorized_keys` 文件中,这样就不需要输入密码了。 * 每次调试需要执行 `build_run_gdbserver.sh` 脚本,然后在 VSCode 中按 `F5` 即可开始调试 > 脚本会编译工程,然后拷贝可执行文件到远程设备,并且启动 `gdbserver`。 > 按 F5 启动调试时, VSCode 使用 GDB 连接到远程设备的`gdbserver`以调试。"},"/maixcdk/doc/dev/docker/index.html":{"title":"MaixCDK docker building environment","content":"MaixCDK docker building environment ## About Docker and install Docker Docker is a tool, here we use it to create a clean Ubuntu environment to build MaixCDK. Use docker you don't need to install dependencies manually, just create a docker container and then all ready. Docker install doc see [Docker official doc](https://docs.docker.com/engine/install/ubuntu/) After installation, you can use `docker version` to check if it is installed successfully. ## Pull from docker hub (recommended), or build by yourself ```shell docker pull sipeed/maixcdk builder ``` > Or you can build from Dockerfile by yourself. > > ```shell > docker build network host t maixcdk builder . > ``` > You can also add proxy by add args:` network host build arg http_proxy http://127.0.0.1:8123 build arg https_proxy http://127.0.0.1:8123` ## Create and run container The upper step we got a docker system image, now we create a container to run this image. ```shell docker run it network host hostname maixcdk env name maixcdk env env USER $USER env UID `id u` env GID `id g` env MAIXCDK_PATH /home/${USER}/MaixCDK v /home/${USER}/MaixCDK:/home/${USER}/MaixCDK sipeed/maixcdk builder ``` > !! DO NOT add `/bin/bash` to the end of the command. > ` network host` means use the same network as host PC. > ` hostname` means set hostname of container to `maixcdk env`. > ` name` means set container name to `maixcdk env`, then you can use `docker` command to control it. > Then assign `USER`(your user name of host PC), user id, group id to use the same as host PC's user info in container to avoid permission problem. > You can use ` v host_dir:container_dir` to map your data to container, e.g. ` v /home/${USER}/MaixCDK:/home/${USER}/MaixCDK v /home/${USER}/projects:/home/${USER}/projects`. > It's recommended to map your directories to the container's same directory, this is useful to see logs. > ` env MAIXCDK_PATH /home/${USER}/MaixCDK` arg to set `MAIXCDK_PATH` environment variable, so you can compile your project anywhere in container. > `sipeed/maixcdk builder` is the image name, if you build by yourself, use `maixcdk builder` instead. Then you can use shell command in container. The user's password is `maixcdk` by default, if you want to change it, use `docker exec it maixcdk env passwd` to change it. ## Build MaixCDK projects or examples When step into container, you can use shell command to build according to the MaixCDK document. ```shell cd /MaixCDK/examples/hello_world maixcdk build maixcdk run cd ~/projects/my_project maixcdk build maixcdk run ``` ## Stop container ```shell docker stop maixcdk env ``` ## RUN container ```shell docker start maixcdk env docker attach maixcdk env ``` ## Execute command through host shell ```shell docker exec it user $USER maixcdk env \"cd /MaixCDK/examples/hello_world && maixcdk build && maixcdk run\" ``` ```shell docker exec it user $USER maixcdk env /bin/bash ``` ## Remove container ```shell docker stop maixcdk env docker rm maixcdk env ```"},"/maixcdk/doc/index.html":{"title":"Quick Start with MaixCDK","content":" title: Quick Start with MaixCDK ## Introduction to MaixCDK MaixCDK provides C++ APIs for commonly used AI functions related to image processing, vision, audio, and peripherals, enabling quick prototyping and stable product development. MaixCDK is not only a C++ SDK but also auto generates Python API bindings, so development can be done in Python through [MaixPy](https://wiki.sipeed.com/maixpy/). Basic Linux knowledge and a fundamental understanding of cross compilation are required to use MaixCDK. ## Basic Knowledge To use MaixCDK, it is assumed that you are already familiar with the following knowledge. If not, please learn them first or consider using [MaixPy](https://wiki.sipeed.com/maixpy/): * Proficient in using Linux for development, familiar with the terminal and common commands. * Proficient in either C or C++ programming language. C++ proficiency is not required, but you must understand the basic syntax and object oriented concepts. * Able to actively read and analyze source code to troubleshoot issues. * Chinese developers should be familiar with using network proxies. * Understand cross compilation. ## How to Find Resources and Troubleshoot 1. Read [MaixCDK source code](https://github.com/sipeed/MaixCDK). 2. Since MaixCDK shares the same functionality/API as MaixPy, detailed tutorials are not provided separately. Refer to the [MaixPy documentation](https://wiki.sipeed.com/maixpy/); the principles and code are nearly identical, requiring only minor modifications. 3. It’s recommended to get hands on experience with MaixPy before using MaixCDK for a smoother learning curve. 4. Carefully review the official documentation, including MaixCDK, MaixPy, and hardware documentation. 5. If issues arise, start by checking [MaixCDK FAQ](https://wiki.sipeed.com/maixcdk/doc/zh/faq.html), [MaixPy FAQ](https://wiki.sipeed.com/maixpy/doc/zh/faq.html), [MaixCAM Hardware FAQ](https://wiki.sipeed.com/hardware/zh/maixcam/faq.html), and the [source code issues](https://github.com/sipeed/MaixCDK/issues). 6. Check out the [MaixHub Share Plaza](https://maixhub.com/share) for community insights. 7. **Read error logs carefully and patiently**, following logs from top to bottom, as errors might appear in the middle—don’t skip ahead hastily! ## Quick Start ### Setting Up the System and Environment Two options are available: #### Local Machine: **Only supported on Linux**, with **Ubuntu > 20.04** recommended. Note that the MaixCAM toolchain only supports x86_64 CPUs and is not compatible with ARM based computers, such as ARM MacOS. ```shell sudo apt update sudo apt install git cmake build essential python3 python3 pip autoconf automake libtool cmake version # cmake version should be > 3.13 ``` > To compile for a Linux PC (instead of cross compiling for a dev board), if you’re using `Ubuntu`, ensure the system version is `> 20.04`, or some dependencies may be too outdated to compile. Install dependencies following the commands in the [Dockerfile](https://github.com/sipeed/MaixCDK/blob/main/docs/doc/dev/docker/Dockerfile). > If compilation errors occur, consider [using Docker to compile](./dev/docker/index.html). #### Docker: The `Docker` environment includes `ubuntu20.04` and dependencies, making it ready for compilation. For users familiar with `Docker` or those facing issues with local setup, refer to the [Docker Usage Guide](./dev/docker/index.html). ### Obtaining the Source Code ```shell git clone https://github.com/Sipeed/MaixCDK ``` > * Stable Release versions can be downloaded from the [release page](https://github.com/Sipeed/MaixCDK/releases). > * Alternatively, check [MaixPy release](https://github.com/Sipeed/MaixPy/releases) assets for `maixcdk_version_xxxxx.txt`, where `xxxxx` indicates the MaixPy version in use. Use `git checkout xxxx` to switch to the corresponding version. > For users in China experiencing slow clone speeds, use `git clone https://gitee.com/Sipeed/MaixCDK`. ### Installing Dependencies ```shell cd MaixCDK pip install U pip # Update pip to the latest version pip install U r requirements.txt # Install dependencies ``` > Users in China can add the parameter ` i https://pypi.tuna.tsinghua.edu.cn/simple` to use the Tsinghua mirror. > Dependencies are already installed in the `Docker` environment, but you can update them to the latest version within the Docker container. Run `maixtool` and `maixcdk` commands in the terminal to view help information. > If the commands are not found, try restarting the terminal or use `find / name \"maixtool\"` to locate `maixtool`, then set it in the system path using `export PATH directory_containing_maixtool:$PATH`. ### Compilation ```shell cd examples/hello_world maixcdk menuconfig ``` Follow the prompts to select the device platform. A menu appears to configure parameters. For first time use, the default parameters are fine (or skip `menuconfig` and go straight to build), then press `ESC`, and `Y` to save and exit. ```shell maixcdk build ``` The first time you run this step, the device will download the compilation toolchain. If the download is slow, you can manually download it to the specified directory as prompted, and then proceed with the compilation. >! The resources are mostly downloaded from GitHub, and download speeds in China may be slow or even fail (the list of files to download is in `dl/pkgs_info.json`). There are several common solutions: > 1. Set a proxy in the terminal (recommended), for example: `export http_proxy http://127.0.0.1:8123 https_proxy http://127.0.0.1:8123`. Here, `http://127.0.0.1:8123` is the address of your HTTP proxy. > 2. Manually download to the `dl/pkgs` folder: During the download, the download URL and local path will be printed. You can manually download the files and place them in the corresponding directory. When you run the build command again, it will use the locally prepared files (Note: the file’s sha256 checksum must match, i.e., it must be the same file). > 3. Users in China can go to the [QQ Group](../) on the homepage, find the `MaixCDK` folder, and download the files to the `MaixCDK/dl` directory. >! For common errors and solutions, refer to the [FAQ](./faq.html). After the compilation, you will find the binary program files in the `build` directory, and the dependent `.so` files in `build/dl_lib`. After modifying the code, you can run `maixcdk build` again to compile. If you **haven’t added or removed source files**, you can run `maixcdk build2` or `maixcdk build no gen` for faster compilation (it will only compile the modified files). > This is because the `build` command starts the entire build process from scratch, scanning files and recompiling. In contrast, the `build2` command will not scan for file additions or deletions and will only compile the edited files. > Note: The `build2` command will not detect file additions or deletions, so if you **add or remove files**, you must run the `build` command again. Run `maixcdk distclean` to clear all temporary build files and start fresh (this increases build time and is typically used to troubleshoot issues). ### Uploading to the Device Copy the executable and `dl_lib` folder to the device for execution. Use `scp` to copy files, for example: ```shell scp r dist/ root@10.127.117.1:/root/ ``` The default password is `root`. ### Running the Program Run the program via SSH. Ensure no other programs are running (including the startup application launcher). Steps: * Connect MaixVision to the device to close the Launcher, or use SSH to `kill` the `launcher_daemon`. * SSH into the device, e.g., `ssh root@192.168.0.123`, password `root`. * Navigate to the executable directory and run it, e.g., `cd /root/dist/camera_display_release && ./camera_display`. ### Packaging for Release In the project directory, use `maixcdk p maixcam release` to create a program package for `maixcam` in the `dist` folder. This package can be uploaded to the [MaixHub App Store](https://maixhub.com/app). Usage: * Method 1: Unzip and copy to the device, run `chmod +x program_name && ./program_name`. * Method 2: Use the [App Store](https://maixhub.com/app/12) application on the device to install from MaixHub. * Method 3: For developers, if the device is connected to the same LAN as the PC, use `maixcdk deploy` to generate a QR code, which the device can scan to install. * Method 4: Copy the package to the device and install it by running `/maixapp/apps/app_store/app_store install xxx.zip`. Application releases should follow the [App Development Guidelines](./convention/app.html). ### Creating a New Project To create a project: ```shell maixcdk new ``` ## Development convention To get started with MaixCDK, please begin by reading the [MaixCDK Development Guidelines](./convention/index.html). ## Adding an API to MaixPy Since MaixPy’s core is largely MaixCDK, adding APIs to MaixPy is straightforward. Just annotate the function with `@maixpy maix.xxx.xxxx`. For example, to implement the following API: ```python from maix import example result example.hello(\"Bob\") print(result) ``` Simply add a declaration in [maix_api_example.hpp](https://github.com/sipeed/MaixCDK/blob/main/components/basic/include/maix_api_example.hpp): ```cpp namespace maix::example { /** * @brief say hello to someone * @param[in] name name of someone, string type * @return string type, content is hello + name * @maixpy maix.example.hello */ std::string hello(std::string name); } ``` Then compile the `MaixPy` project to get an installation package, which can be installed on the device to use the new API—simple, right? For more detailed documentation, refer to [Add API](./convention/add_api.html)."},"/maixcdk/doc/faq.html":{"title":"MaixCDK FAQ","content":"MaixCDK FAQ You can also find FAQ from: * [MaixPy FAQ](https://wiki.sipeed.com/maixpy/doc/en/faq.html) * [MaixCAM FAQ](https://wiki.sipeed.com/hardware/zh/maixcam/faq.html) * [MaixPy souce code FAQ](https://wiki.sipeed.com/maixpy/doc/zh/source_code/faq.html) ## Common Compilation Errors and General Solutions * **Errors such as extraction failures**: Try deleting the corresponding files in the `dl/pkgs` and `dl/extracted` directories, then recompile and download again. * **Compilation errors**: * Run `maixcdk build verbose` to see where the error occurs. **Carefully check the error log** and investigate the issue step by step. * Run `maixcdk distclean` to clean temporary files, then try recompiling. * Visit the [GitHub commit history](https://github.com/sipeed/MaixCDK/commits/main/) to check whether the automated tests for each commit passed (a green checkmark ✅ means it passed, a red cross ❌ means it failed). You can switch your local code to a commit that passed the tests ✅ and recompile. Use the command `git checkout `, for example: `git checkout 3aba2fe3fa9de9f638bb9cb34eca0c2e0f5f3813`. If switching fails, you may need to search for Git usage instructions or start over, but make sure to back up any changes you made to your code. ## Downloading ippicv_2021.8_lnx_intel64_20230330_general.tgz takes a long time or fail Manually download according to the log's url, and put it into: `MaixCDK > components > opencv > opencv4 > .cache > ippicv` The file name is `43219bdc7e3805adcbe3a1e2f1f3ef3b ippicv_2021.8_lnx_intel64_20230330_general.tgz`, File name and url can also be found in `MaixCDK/components/3rd_party/opencv/opencv4/3rdparty/ippicv/ippicv.cmake` So the same as `ade` cache file `.cache/ade/4f93a0844dfc463c617d83b09011819a v0.1.2b.zip` ## Exception: parse_api_from_header **.hpp error: 'members' API comment not complete. e.g. ```cpp /** * Class for communication protocol */ class CommProtocol { /** * Read data to buffer, and try to decode it as maix.protocol.MSG object * @return decoded data, if nullptr, means no valid frame found. * Attentioin, delete it after use in C++. * @maixpy maix.comm.CommProtocol.get_msg */ protocol::MSG *get_msg(); } ``` Here `class CommProtocol` not add `@maixpy maix.comm.CommProtocol` but its method `get_msg` add it. So we add `@maixpy maix.comm.CommProtocol` to `class CommProtocol` comment will fix this error. ## Build OpenSSL Error when using WSL( Windows Subsystem Layer) When I add openssl to my project ![a0cee88e7a7a747c2d34eadb31a925bd](https://github.com/user attachments/assets/77b0c057 fb0b 4980 8ff4 413fd14dec28) build fail occured: ![3b42197634ee4cd6a7b0462636e8dd34](https://github.com/user attachments/assets/d23da336 8096 43ec aec8 23691caaacf2) Use \"maixcdk build verbose\" to check . I found that windows path polluted wsl path . and there are \"(\" and space in path ,which make configure of openssl fail . Fix : fix the path : edit `wsl.conf` in wsl ```sh sudo nano /etc/wsl.conf ``` create the file if no exist. add the content below : ``` [interop] appendWindowsPath false ``` restart wsl ``` wsl shutdown Ubuntu ``` ![9a86a628630209725d362f07b51ecb9a](https://github.com/user attachments/assets/79571b2c 3449 4ae8 afdd 69917d4986ce) path is fixed ,openssl configure succ ![d6e43b3bf8e5c68d9966636464b08a43](https://github.com/user attachments/assets/f69be859 dc9c 4a7d 82f3 06df0ea03ed5)"},"/maixcdk/doc/more.html":{"title":"更多 MaixCDK 文档","content":" title: 更多 MaixCDK 文档 MaixCDK 由于是 MaixPy 的大多数 API 底层实现,所以 [MaixPy 的文档](https://wiki.sipeed.com/maixpy/)也适用于 MaixCDK,比如 功能介绍和教程,系统定制等等。"},"/maixcdk/doc/dev/quick_start.html":{"title":"MaixCDK quick start","content":" title: MaixCDK quick start see [quick start](../index.html)"},"/maixcdk/doc/application/ai/yolo11.html":{"title":"MaixCDK YOLO11 develop notes","content":" title: MaixCDK YOLO11 develop notes Souce code in [MaixCDK/components/nn/include/maix_nn_yolo11.hpp](https://github.com/sipeed/MaixCDK/blob/main/components/nn/include/maix_nn_yolo11.hpp) Model port from [ultralytics/ultralytics](https://github.com/ultralytics/ultralytics), train and convert model refer to [MaixPy doc customize yolo11](https://wiki.sipeed.com/maixpy/doc/en/vision/customize_model_yolov8.html)."},"/maixcdk/doc/application/index.html":{"title":"MaixCDK Application notes","content":" title: MaixCDK Application notes These notes is MaixCDK developer notes, taken down by developer when create some functions. If you want to known more features and functions and documentation, please visit [MaixPy documentation](https://wiki.sipeed.com/maixpy/)"},"/maixcdk/doc/application/ui/lvgl.html":{"title":"Use LVGL in MaixCDK","content":" title: Use LVGL in MaixCDK ## run gui_lvgl demo * Go to `examples/gui_lvgl` in MaixCDK. * Execute `maixcdk build` to build the project for PC. * Execute `maixcdk run` to run the project on PC. You can also execute `maixcdk menuconfig` to change platform to build for other platform. ## Custom your own UI * Download [squareline](https://squareline.io/) and install first. * Create a new UI project in squareline. * Edit your UI. * Export UI files, then you will get a `ui` folder. * Copy all ui files to `examples/gui_lvgl/ui` folder. * Run `maixcdk build` to build. Or you can mannually write code and not use squareline."},"/maixcdk/doc/application/peripheral/uart.html":{"title":"","content":""},"/maixcdk/doc/convention/i18n.html":{"title":"MaixCDK i18n(Internationalization), multi language support","content":" title: MaixCDK i18n(Internationalization), multi language support You can use any i18n library you like, [gettext](https://www.gnu.org/software/gettext/) for example, they are supported in Python and C++. And we provide a simple i18n library, for simple use case. ## For MaixPy See [MaixPy i18n documentation](https://wiki.sipeed.com/maixpy/doc/zh/gui/i18n.html). ## For MaixCDK: The same as MaixPy's, there's two ways: ### Simple translation dict Ensure your source file if `UTF 8` encoded first. ```cpp #include \"maix_i18n.hpp\" const std::map locale_zh_dict { {\"out\", \"输出\"}, {\"hello\", \"你好\"} }; const std::map locale_ja_dict { // {\"out\", \"出力\"}, {\"hello\", \"こんにちは\"} }; const std::map> locales_dict { {\"zh\", locale_zh_dict}, {\"ja\", locale_ja_dict} }; i18n::Trans trans(locales_dict); int main() { log::info(\"system locale: %s\\n\", i18n::get_locale().c_str()); log::info(\"%s: %s\\n\", trans.tr(\"out\").c_str(), trans.tr(\"hello\").c_str()); trans.set_locale(\"zh\"); printf(\"%s: %s\\n\", trans.tr(\"out\").c_str(), trans.tr(\"hello\").c_str()); trans.set_locale(\"en\"); printf(\"%s: %s\\n\", trans.tr(\"out\").c_str(), trans.tr(\"hello\").c_str()); trans.set_locale(\"ja\"); printf(\"%s: %s\\n\", trans.tr(\"out\").c_str(), trans.tr(\"hello\").c_str()); return 0; } ``` ### Seperated translation files The upper demo is more simple for little translation strings, but if you have many strings need to translate, this way is recommended, use this way: * We don't need to change source code when we want to change translation, translation strings in seperate yaml files. * It's easier to find translation strings, support auto scan strings which need to be translated and auto generate yaml files. ```cpp err::Err e trans.load(\"locales\"); // load from locales directory err::check_raise(e, \"load translation yamls failed\"); log::info(\"system locale: %s\\n\", i18n::get_locale().c_str()); log::info(\"%s: %s, %s\\n\", i18n::get_locale().c_str(), trans.tr(\"out\").c_str(), trans.tr(\"hello\").c_str()); trans.set_locale(\"zh\"); log::info(\"zh: %s, %s\\n\", trans.tr(\"out\").c_str(), trans.tr(\"hello\").c_str()); trans.set_locale(\"en\"); log::info(\"en: %s, %s\\n\", trans.tr(\"out\").c_str(), trans.tr(\"hello\").c_str()); trans.set_locale(\"ja\"); log::info(\"ja: %s, %s\\n\", trans.tr(\"out\").c_str(), trans.tr(\"hello\").c_str()); ``` Full demo see [examples/i18n](https://github.com/sipeed/MaixCDK/tree/main/examples/i18n) for example. Then we exexute `maixtool i18n d . r`, this will scan all the strings translate by `tr()` or `_()` function and generate `locales` directory and translation files. Manually translate the `yaml` files in `locales`, then run program on device, put `locales` directory besides program. ## Show in LVGL APP See how to show custom font at [https://neucrack.com/p/514](https://neucrack.com/p/514) . Then use this piece of code: ```cpp LV_FONT_DECLARE(zh_fonts); static const std::map fonts { {\"zh\", (void*)&zh_fonts} }; const lv_font_t *get_font_by_locale(const string &locale) { const std::map::const_iterator iter fonts.find(locale); if (iter fonts.end()) { return &zh_fonts; } return (lv_font_t *)iter >second; } ``` Finally you can use i18n font by ```cpp std::string locale i18n::get_locale(); lv_obj_set_style_text_font(lv_scr_act() , get_font_by_locale(locale), LV_PART_MAIN); lv_obj_t *label lv_label_create(lv_scr_act()); lv_label_set_text(label, trans.tr(\"hello\").c_str()); ```"},"/maixcdk/doc/convention/protocol.html":{"title":"Maix Communicate Protocol","content":" title: Maix Communicate Protocol update: date: 2023 11 28 author: neucrack version: 1.0.0 content: Designed and implemented the protocol documentation and code API > This article is translated from Chinese by ChatGPT, may have error, Pull Request is welcome! ## Introduction to Maix Serial Protocol Devices running MaixCDK or MaixPy can be controlled not only directly via the device's touch screen and buttons but also as modules using `UART` (serial port) or `I2C`. > Since I2C operates in a master slave mode, the protocol adopts a request response format: `Request` + `Response`. > For UART protocol, some functions support active reporting. Please refer to the specific protocol details. The communication protocol is explained in detail below. ## How to Use Maix Device Upon startup, go to the `Settings` application, and select the communication interface under `Communication` settings: * **Serial Port**: Uses the serial port for communication. The specific serial port depends on the board, with a default baud rate of `115200`. * **TCP**: Starts a TCP service on the Maix device, allowing the master device to connect via TCP. The default port is `5555`. Once the master device is connected to the Maix device, it can communicate following the protocol, where the master device acts as the primary device, and the Maix device as the slave. **Development on Maix Device Side**: You can easily implement command responses using the provided `maix.comm.CommProtocol` class. Refer to the examples [comm_protocol](../../../examples/protocol_demo) (C++) or [comm_protocol.py](https://github.com/sipeed/MaixPy/blob/main/examples/protocol) (MaixPy) for details. **Development on Master Device Side**: The master device can implement the protocol based on the chip and programming language. Template code is provided in the appendix. ## Data Frame header (4B LE) data len (4B LE)(flags+cmd+body+crc) flags (1B) cmd (1B) body (nB) CRC16_IBM (2B LE) (all previous) Decimal Example 3148663466 9 0 1 hello 17451 Hex Example 0xBBACCAAA 0x00000009 0x00 0x01 hello 0x442B Byte Stream (Hex) AA CA AC BB 09 00 00 00 00 01 68 65 6C 6C 6F 2B 44 > **Note**: Multi byte data uses little endian (LE) encoding. For example, `data_len` is `0x00000006`, with `06` in the lowest byte, so it is sent first as `0x06`, followed by `0x00 0x00 0x00`. > Strings are sent in order, e.g., `hello` is sent as `h`, then `e`, `l`, `l`, `o`. > In this example, the final data sent is: `AA CA AC BB 09 00 00 00 00 01 68 65 6C 6C 6F 2B 44`. `header`: 4 byte header marking the start of a frame, fixed as `0xAA 0xCA 0xAC 0xBB`, sent starting with `0xAA`. `data len`: 4 byte data length, including the length of `flags`, `cmd`, `body`, and `CRC`. `flags`: 1 byte flag where each bit indicates: MSB `is_resp`: Indicates if it is a response. `0` for request, `1` for response or active report (requires the third highest bit set to `1`). Second highest bit `resp_ok`: For requests: Reserved. For responses: `1` for success, `0` for failure. Third highest bit `is_report`: For requests: Reserved. For responses: `1` for active report, `0` for response message. Bits 4 6: Reserved for future use. Lowest 2 bits `version`: Protocol version, updated only for incompatible changes. Compatible changes do not require a version update. The current version is `0`. `cmd`: 1 byte command type, with several predefined commands listed in [Command Definitions](#command definitions). Custom commands range from `0` to `maix.protocol.CMD.CMD_APP_MAX`. `body`: Variable length, `< (2^32 1)`. Different commands have different `body` content, detailed below for each command. `crc16`: 2 byte CRC check value using the `CRC IBM` method, verifying data integrity during transmission. See [C Code Implementation](#C CRC16) or [Python CRC16](#Python CRC16). For encoding and decoding, see [Appendix: Code](#Appendix Code). ### Request and Response #### Sending Request Data direction: MCU or other master device > Maix device Set the highest bit of `flags` (`is_resp`) to `0`. The `body` content is determined by `cmd`. #### Receiving Response Data direction: Maix device > MCU or other master device Set the highest bit of `flags` (`is_resp`) to `1`. For a successful response: Set `resp_ok` to `1`, and the `body` content is determined by `cmd`. An empty `body` is the simplest successful response. For a failed response: Set `resp_ok` to `0`. The first byte of `body` is the error code. Refer to [MaixCDK maix.err.Err](../../../components/basic/include/maix_err.hpp) for error codes. The following bytes in `body` contain the error message in `UTF 8` encoding, preferably in plain English for better compatibility. Each request should have a corresponding response, either successful (`RESP_OK`) or failed (`RESP_ERR`). If `RESP_OK` has no specified `body`, it is empty. ### Active Data Reporting Data direction: Maix device > MCU or other master device The master device must first enable active reporting using the `CMD_SET_REPORT` command (only supported for specific commands). > For example, if the APP supports the `CMD_GET_TEMP` command to get temperature data, the master can use the `CMD_SET_REPORT` command to enable periodic temperature reporting. If the APP does not support active reporting for `CMD_GET_TEMP`, it will respond with `CMD_ERROR`. Set the highest bit of `flags` (`is_resp`) to `1` and the third bit `is_report` to `1`. The `body` content depends on the `cmd`. ## Examples Example: The MCU connects to the Maix device via the serial port using the default baud rate of `115200`. The MCU requests the list of applications from the Maix device. The steps are as follows: 1. According to the protocol specification, the MCU sends a request with `cmd` set to `0xF9` (`CMD_APP_LIST`), and an empty `body`. Actual byte stream: `AA CA AC BB 04 00 00 00 01 F9 C9 77`. 2. The Maix device responds with `cmd` set to `0xF9` and `flags` set to `0xC1` (with `0x80` for response and `0x40` for success). The `body` contains the application list. If there are two applications, the actual byte stream is: `AA CA AC BB 0A 00 00 00 C1 F9 02 66 61 63 65 00 66 61 63 65 00 F6 06`. ## Command Definitions The `cmd` values in the protocol frame are defined as follows: Command Name Value Description CMD_APP_MAX 0xC8 Maximum value for custom commands (exclusive) CMD_SET_REPORT 0xF8 Set active reporting CMD_APP_LIST 0xF9 Query application list CMD_START_APP 0xFA Start an application CMD_EXIT_APP 0xFB Exit the current application CMD_CUR_APP_INFO 0xFC Query current application info CMD_APP_INFO 0xFD Query specific application info CMD_KEY 0xFE Simulate key press message CMD_TOUCH 0xFF Simulate touch message Note that `CMD_APP_MAX` defines the range for custom commands, from `0` up to (but not including) `CMD_APP_MAX`. Each `cmd` has specific request and response data and a unique `body`. Detailed explanations for each command are provided below: ### CMD_SET_REPORT Enables or disables active reporting for specific commands. Active reporting includes: 1. Event based reporting, such as reporting detected faces. 2. Periodic reporting, such as reporting temperature every 5 seconds. If both periodic and event based reporting are enabled, the timer restarts after an event report. #### Request `body`: cmd (1B) on_off (1B) event (1B) timer (4B) Description Command for active reporting Enable (1) or disable (0) Event reporting (1 for enable, 0 for disable) Timer for periodic reporting in ms (set to 0 if not needed) Example 0x02 0x01 1 5000 #### Response If the command supports active reporting, respond with `RESP_OK`; otherwise, respond with `RESP_ERR`. `body`: None ### CMD_APP_LIST Queries the list of available applications. #### Request `body`: None #### Response `body`: number (1B) app1 ... app n info Description Number of applications id1 (null terminated string) ... idn Example 0x02 'face\\0' ... 'appn\\0' ### CMD_CUR_APP_INFO Gets the current application information. #### Request `body`: None #### Response `body`: idx (1B) app info (id + name + brief) Description Application index Application info (id, name in UTF 8, brief description in UTF 8) Example 0x00 'face\\0face\\0face detect\\0' ### CMD_APP_INFO Queries specific application information. #### Request `body`: idx (1B) app_id (nB) Description Application index Application ID Example 0x02 'face' Either `idx` or `app_id` can be specified: * `idx`: Application index (starts from 0). Setting to `0xFF` means it is not specified. * `app_id`: Application ID. If `idx` is specified, `app_id` can be omitted. #### Response `body`: idx (1B) app info (id + name + brief) Example 0x00 'face\\0face\\0face detect\\0' ### CMD_START_APP Requests to start a specified application. This command will exit the current application and start the specified one. * If the APP receives this command, it must call the API `maix.app.switch_app` to switch the application. > There is a risk if the APP does not correctly implement the response to this command, prompting the developer to implement it. * If the Launcher receives this command, it will start the specified application. #### Request `body`: idx (1B) app_id (nB) app_func (nB) Description Application index (starts from 0, set to `0xFF` if unspecified) Application ID (optional if `idx` is specified) Function to execute if the application has multiple functions Example 0x02 'scan' 'qrcode' #### Response `body`: None ### CMD_EXIT_APP Requests to exit the current application. #### Request `body`: None #### Response `body`: None ### CMD_KEY Sends a simulated key press request. #### Request `body`: key (4B) value (1B) Key value (little endian) 0x01 (pressed), 0x00 (released), 0x02 (long press) #### Response `body`: None ### CMD_TOUCH Sends a simulated touch request. #### Request `body`: x y event (1B) x coordinate y coordinate Event type Event types: * 0x00: Press * 0x01: Release * 0x02: Move #### Response `body`: None ## Application (APPS) Protocol Specification ### Camera Commands: Command Value Description Response CMD_SNAP 0x01 Take a photo ### Classifier TODO: `body` Description: The request consists of a single byte representing the command, as shown in the table below: Command Value Description Response CMD_RECOGNIZE 0x01 Recognize object CMD_APP_CMD Response: * Response for command `CMD_RECOGNIZE`: The response `cmd` is `CMD_APP_CMD`, and the `body` is structured as follows: CMD_RECOGNIZE id (2B uint16 LE) prob (4B float LE) name CMD_RECOGNIZE value Recognized id (index), little endian Probability, float, little endian Name, UTF 8 encoded ### Face Detection TODO: `body` Description: The request consists of a single byte representing the command, as shown in the table below: Command Value Description Response CMD_POS 0x01 Detect face CMD_APP_CMD Response: * Response for command `CMD_POS`: The response `cmd` is `CMD_APP_CMD`, and the `body` is structured as follows: CMD_POS face num (2B LE) prob (4B float LE) x (2B LE) y (2B LE) w (2B LE) h (2B LE) ... CMD_POS value Number of detected faces Probability, float, little endian Top left x coordinate of the face box Top left y coordinate of the face box Width of the face box Height of the face box Remaining faces... ### Face Recognition TODO: `body` Description: The request consists of a single byte representing the command, as shown in the table below: Command Value Description Response CMD_FACES 0x01 Recognize faces CMD_APP_CMD CMD_USERS 0x02 Query all users CMD_APP_CMD CMD_RECORD 0x03 Record a face CMD_APP_CMD CMD_REMOVE 0x04 Remove a face CMD_APP_CMD Request: `CMD_APP_CMD` plus an additional byte for `app_cmd`. Some commands have extra parameters, as follows: * Request for command `CMD_RECORD`: CMD_RECORD user name CMD_RECORD value Name of the user being recorded * Request for command `CMD_REMOVE`: CMD_REMOVE user idx (2B int16) user name CMD_REMOVE value User index, 2 bytes, little endian Name of the user to be removed Either index or username can be provided. Response: * Response for command `CMD_FACES`: The response `cmd` is `CMD_APP_CMD`, and the `body` is structured as follows: CMD_FACES face num (2B LE) id (2B) name_len (1B) name prob (4B float LE) x (2B LE) y (2B LE) w (2B LE) h (2B LE) ... CMD_FACES value Number of detected faces Face ID (index) Length of the name Name, UTF 8 encoded Probability, float, little endian Top left x coordinate of the face box Top left y coordinate of the face box Width of the face box Height of the face box Remaining faces... * Response for command `CMD_USERS`: The response `cmd` is `CMD_APP_CMD`, and the `body` is structured as follows: CMD_USERS user num (2B LE) name_len (1B) name ... CMD_USERS value Number of users Length of the username Name, UTF 8 encoded Remaining usernames... * Response for command `CMD_RECORD`: `CMD_OK` or `CMD_ERROR` * Response for command `CMD_REMOVE`: `CMD_OK` or `CMD_ERROR` ## Appendix: Code ### C CRC16 IBM ```c unsigned short crc16_IBM(unsigned char *ptr, int len) { unsigned int i; unsigned short crc 0x0000; while(len ) { crc ^ *ptr++; for (i 0; i < 8; ++i) { if (crc & 1) crc (crc >> 1) ^ 0xA001; else crc (crc >> 1); } } return crc; } ``` Alternatively, using a lookup table: ```c const unsigned int crc16_table[256] { 0x0000, 0xc0c1, 0xc181, 0x0140, 0xc301, 0x03c0, 0x0280, 0xc241, 0xc601, 0x06c0, 0x0780, 0xc741, 0x0500, 0xc5c1, 0xc481, 0x0440, 0xcc01, 0x0cc0, 0x0d80, 0xcd41, 0x0f00, 0xcfc1, 0xce81, 0x0e40, 0x0a00, 0xcac1, 0xcb81, 0x0b40, 0xc901, 0x09c0, 0x0880, 0xc841, 0xd801, 0x18c0, 0x1980, 0xd941, 0x1b00, 0xdbc1, 0xda81, 0x1a40, 0x1e00, 0xdec1, 0xdf81, 0x1f40, 0xdd01, 0x1dc0, 0x1c80, 0xdc41, 0x1400, 0xd4c1, 0xd581, 0x1540, 0xd701, 0x17c0, 0x1680, 0xd641, 0xd201, 0x12c0, 0x1380, 0xd341, 0x1100, 0xd1c1, 0xd081, 0x1040, 0xf001, 0x30c0, 0x3180, 0xf141, 0x3300, 0xf3c1, 0xf281, 0x3240, 0x3600, 0xf6c1, 0xf781, 0x3740, 0xf501, 0x35c0, 0x3480, 0xf441, 0x3c00, 0xfcc1, 0xfd81, 0x3d40, 0xff01, 0x3fc0, 0x3e80, 0xfe41, 0xfa01, 0x3ac0, 0x3b80, 0xfb41, 0x3900, 0xf9c1, 0xf881, 0x3840, 0x2800, 0xe8c1, 0xe981, 0x2940, 0xeb01, 0x2bc0, 0x2a80, 0xea41, 0xee01, 0x2ec0, 0x2f80, 0xef41, 0x2d00, 0xedc1, 0xec81, 0x2c40, 0xe401, 0x24c0, 0x2580, 0xe541, 0x2700, 0xe7c1, 0xe681, 0x2640, 0x2200, 0xe2c1, 0xe381, 0x2340, 0xe101, 0x21c0, 0x2080, 0xe041, 0xa001, 0x60c0, 0x6180, 0xa141, 0x6300, 0xa3c1, 0xa281, 0x6240, 0x6600, 0xa6c1, 0xa781, 0x6740, 0xa501, 0x65c0, 0x6480, 0xa441, 0x6c00, 0xacc1, 0xad81, 0x6d40, 0xaf01, 0x6fc0, 0x6e80, 0xae41, 0xaa01, 0x6ac0, 0x6b80, 0xab41, 0x6900, 0xa9c1, 0xa881, 0x6840, 0x7800, 0xb8c1, 0xb981, 0x7940, 0xbb01, 0x7bc0, 0x7a80, 0xba41, 0xbe01, 0x7ec0, 0x7f80, 0xbf41, 0x7d00, 0xbdc1, 0xbc81, 0x7c40, 0xb401, 0x74c0, 0x7580, 0xb541, 0x7700, 0xb7c1, 0xb681, 0x7640, 0x7200, 0xb2c1, 0xb381, 0x7340, 0xb101, 0x71c0, 0x7080, 0xb041, 0x5000, 0x90c1, 0x9181, 0x5140, 0x9301, 0x53c0, 0x5280, 0x9241, 0x9601, 0x56c0, 0x5780, 0x9741, 0x5500, 0x95c1, 0x9481, 0x5440, 0x9c01, 0x5cc0, 0x5d80, 0x9d41, 0x5f00, 0x9fc1, 0x9e81, 0x5e40, 0x5a00, 0x9ac1, 0x9b81, 0x5b40, 0x9901, 0x59c0, 0x5880, 0x9841, 0x8801, 0x48c0, 0x4980, 0x8941, 0x4b00, 0x8bc1, 0x8a81, 0x4a40, 0x4e00, 0x8ec1, 0x8f81, 0x4f40, 0x8d01, 0x4dc0, 0x4c80, 0x8c41, 0x4400, 0x84c1, 0x8581, 0x4540, 0x8701, 0x47c0, 0x4680, 0x8641, 0x8201, 0x42c0, 0x4380, 0x8341, 0x4100, 0x81c1, 0x8081, 0x4040, }; unsigned short crc16_IBM(const unsigned char *ptr,int len) { unsigned short crc 0x0000; while(len ) { crc (crc >> 8) ^ crc16_table[(crc ^ *ptr++) & 0xff]; } return (crc); } ```"},"/maixcdk/doc/convention/app.html":{"title":"MaixCDK APP framework guide","content":"MaixCDK APP framework guide ## Introduction User use steps: * When device boot up, will automatically start `launcher`. * Use select one APP to start. * Run selected APP. * User interact with APP. * User exit APP. * `launcher` will start again and wait for user to select APP. User install new APP: * Ensure device is connected to internet(can connect WiFi in `app_settings` APP). * Open [maixhub.com/app](https://maixhub.com/app) to find APP, click `download` button, and a `QR code` and a `install code` will be shown. * Open `app_store` APP in device to open camera to scan QR code, or input install code to install the APP. * Return to launcher, the new APP will be shown in the list. ## Pack APP If use `MaixCDK`: * Create a `app.yaml` in your project folder, see below for format. * Execute `maixcdk release P maixcam` to pack APP for `maixcam` platform. * Then you will find a `app_store_v1.0.0.zip` in `dist` folder, this is the APP package. * You can upload this package to [maixhub.com/app](https://maixhub.com/app) to share with others. * Or you can execute `maixcdk deploy P maixcam` to serve a local server and a QR code will be shown. * Or you can upload this app file to device and execute `app_store install app_path.zip` to install by command. If use `MaixPy`, you can use `MaixVision Workstation` to release APP, or use `maixtool` to release manually: * Create a `app.yaml` in your project folder, see below for format. * Create a `main.py` in your project folder, this is the entry of your APP. * Execute `maixtool release` in this folder, `dist/app_id_vx.x.x.zip` will be generated. * You can upload this package to [maixhub.com/app](https://maixhub.com/app) to share with others. * Or you can execute `maixtool deploy` to serve a local server and a QR code will be shown. `app.yaml` format: ```yaml id: my_app # unique id, use lowercase and `_` to separate words name: My APP name[zh]: 我的应用 # Chinese name version: 1.0.0 # version number, major.minor.patch icon: assets/my_app.png # can be png or lottie json file, or empty author: Sipeed Ltd desc: My APP description desc[zh]: 我的应用描述 #### Include files method 1: # By default will include all files in project dir except exclude files exclude: # not support regular expression, .git and __pycache__ is always exclude .vscode compile build dist # extra_include: # src: dst # build/filename123: filename123 #### Include files method 2: # White list mode, only include files in files dict. # If no this key or value is empty, will use method 1. # files: # assets # hello.py # main.py #### Include files method 2.1: # White list mode, only include files in files dict. # If no this key or value is empty, will use method 1. # files: # assets: assets ``` `exclude` is blacklist mode, `files` is whitelist mode, you can use one of them. ## Files convention * All app data is stored in `/maixapp`. * Apps are stored in `/maixapp/apps`. * There is a `/maixapp/apps/app.info` INI file for simple description of installed apps. Install and uninstall APP will update this file. > developer or use can manually copy APP directories here and execute `python gen_app_info.py` will generate `app.info` file. * APP store in `/maixapp/apps/app_id` folder, every app must contain `app_id` executable file, or `main.sh` shell script, or `main.py` python script. * When boot up APP, the launcher will find file in app_id folder: `main.sh` > `main.py` > `app_id`. The `main.sh` will be executed by `sh`, `main.py` will be executed by `python3`, `app_id` will be directly executed. * All shared data is stored in `/maixapp/share`. * All pictures are stored in `/maixapp/share/picture`. * All video files are stored in `/maixapp/share/video`. * Temporary data can be stored in `/maixapp/tmp`. Note that this directory is located on the file system (SD card), which differs from the system's `/tmp` directory. The `/tmp` directory on the system is a virtual file system in memory, offering faster read/write speeds but with limited memory size. Large files and log files that need to be stored long term (which may grow over time) are recommended to be placed in the `/maixapp/tmp` directory. * Font files are stored in `/maixapp/share/font`. * Icon files are stored in `/maixapp/share/icon`. * APP's data files created at runtime can be stored in `/maixapp/apps/app_id/data`. * **All this path can be get by API `maix.app.get_xxx_path`, more detail see API doc or [maix_app.hpp](https://github.com/sipeed/MaixCDK/blob/main/components/basic/include/maix_app.hpp) file.** ## Switch from APP to anothor APP Use `void maix::app::switch_app(const string &app_id, int idx 1, const std::string &start_param \"\")` function to switch APP. This will exit current APP and start another APP, and parse `start_param` string to the second APP, the second APP can get this param by `maix::app::get_start_param()`."},"/maixcdk/doc/convention/memcheck.html":{"title":"Memory Check Method","content":" title: Memory Check Method ## Introduction Use the **Valgrind** tool to check for memory leaks, out of bounds memory access, and other memory related issues. ## Installation ```shell sudo apt install valgrind ``` ## Using Valgrind ```shell cd examples/hello_world maixcdk build # Output a brief log valgrind ./build/hello_world # Output a detailed log # tool memcheck: Specifies the tool as memcheck. Memcheck is the default tool, so this option can be omitted. # leak check full: Displays detailed information for each memory leak. # log file valgrind.log: Outputs the memory leak check result to the specified file. Here, valgrind.log is a custom filename. valgrind tool memcheck leak check full log file valgrind.log ./build/hello_world ``` ## Analyzing Valgrind Output ### Checking Memory Leak Summary In case of memory leaks, you may see logs similar to the following: ```shell LEAK SUMMARY: definitely lost: 48 bytes in 3 blocks. # Memory definitely leaked (e.g., memory allocated by a pointer not freed) indirectly lost: 32 bytes in 2 blocks. # Indirectly leaked memory (e.g., a double pointer's memory not freed, causing indirect leakage) possibly lost: 96 bytes in 6 blocks. still reachable: 64 bytes in 4 blocks. suppressed: 0 bytes in 0 blocks. ``` ### Checking Detailed Memory Errors There are various types of memory errors that Valgrind can detect. Here is an example log. For more details, refer to the [official documentation](https://valgrind.org/docs/manual/mc manual.html). ```shell 8 bytes in 1 blocks are definitely lost in loss record 1 of 14 # Identifies where memory is leaked at 0x........: malloc (vg_replace_malloc.c:...) by 0x........: mk (leak tree.c:11) by 0x........: main (leak tree.c:39) 88 (8 direct, 80 indirect) bytes in 1 blocks are definitely lost in loss record 13 of 14 at 0x........: malloc (vg_replace_malloc.c:...) by 0x........: mk (leak tree.c:11) by 0x........: main (leak tree.c:25) ``` ## Troubleshooting Unresolved Issues If you encounter issues that cannot be resolved, refer to the [official documentation](https://valgrind.org)."},"/maixcdk/doc/convention/index.html":{"title":"MaixCDK Development Guidelines and Guidance","content":" title: MaixCDK Development Guidelines and Guidance ## General Guidelines * **Simplicity and Ease of Use**: Assume minimal prior experience from users. Minimize required actions and provide simple APIs with comprehensive documentation. > For example, instead of asking users to choose and download a toolchain, it is better to automatically select and download the toolchain based on the chosen platform, reducing the entry barrier. * **Universality**: APIs should be designed to be platform agnostic and provide consistent abstraction. If this cannot be achieved, reconsider whether the feature should be included. * **Consistency**: Maintain consistent API styles and coding standards. * **Extensibility**: While ensuring core functionality, provide extension interfaces to allow users to add features easily. * **Depth**: Keep APIs simple but document the underlying principles. Open source as much code as possible to facilitate deeper exploration by users. ## Source Code and Binary Files * **Avoid Using Git Submodules**: This facilitates faster downloads for users in China. Even if the main repository is mirrored, submodules still need to be fetched from GitHub, which can be slow for Chinese users. * **Do Not Store Large Files or Binaries in the Source Code Repository**: Storing these will significantly increase the Git repository size. Git is optimized for text files; handle binary files as described below. * **Automatically Download Third Party Libraries and Binaries Before Compilation**: Define necessary files for download in [component.py](https://github.com/sipeed/MaixCDK/blob/main/components/3rd_party/asio/component.py). During compilation, they will be downloaded to `dl/pkgs` and extracted to `dl/extracted`, allowing direct inclusion in `CMakeLists.txt`, e.g., `list(APPEND ADD_INCLUDE \"${DL_EXTRACTED_PATH}/sunxi_mpp/sunxi mpp 1.0.0/include\")`. > The list of files to be downloaded is stored in `dl/pkgs_info.json` during each build. Users with slow internet connections can manually download these files from official sources or third party services and place them in `dl/pkgs`. * **Do Not Modify Third Party Libraries**: Avoid modifying the source code of third party libraries to facilitate upgrades. If modifications are necessary, consider applying patches automatically after extraction. ## Overview of MaixCDK Architecture For general application developers, key concepts include: * MaixCDK consists of two main parts: `MaixCDK` (library storage) and `project` (application code). Official examples and apps are located in `MaixCDK/examples` and `MaixCDK/projects`, respectively. You can also create your own projects in `MaixCDK/projects`. Alternatively, you can separate the two and set an environment variable `MAIXCDK_PATH` pointing to the `MaixCDK` directory, e.g., `export MAIXCDK_PATH /home/xxx/MaixCDK`. This allows projects to reside in other locations, such as `/home/xxx/projects`. * **Components**: Each functional module can be encapsulated as a component, making it easy to include in different applications. * For example, the `main` component in [examples/hello_world](./examples/hello_world) and various components in [components](./components). You can also add custom components, like `hello_world/component1`. * Use the environment variable `MAIXCDK_EXTRA_COMPONENTS_PATH` to specify additional component paths. * Each component includes a `CMakeLists.txt` file describing its contents, e.g., `list(APPEND ADD_INCLUDE \"include\")` for header files, `list(APPEND ADD_SRCS \"src/hello.c\")` for source files, and `list(APPEND ADD_REQUIREMENTS basic)` for dependencies. * **Kconfig**: Provides terminal based configuration options. Each component can include a `Kconfig` file for setting options, accessible via `maixcdk menuconfig`. The configuration is saved in `build/config`, generating `global_config.cmake` and `global_config.h` for use in `CMakeLists.txt` and C/C++ files. * **Third Party Library Integration**: There are two recommended methods: * **Method 1**: Specify third party libraries in the component’s `CMakeLists.txt` for automatic download during compilation. This is preferred for libraries integrated into `MaixCDK`. * **Method 2**: Package and publish the library as a Python package on [pypi.org](https://pypi.org) with the naming convention `maixcdk xxx`. Users can then install it using `pip install maixcdk xxx`. * **Documentation**: Located in the [docs](./docs/) directory. API documentation is auto generated from code; do not edit it manually. The application documentation serves as a user guide. ## Coding Style To ensure consistency across MaixCDK and MaixPy APIs, follow these coding style guidelines: * **Function Names**: Use lowercase with underscores, e.g., `get_name`. * **Variable Names**: Use lowercase with underscores, e.g., `file_path`. * **Class Names**: Use CamelCase, with common abbreviations in uppercase, e.g., `Person`, `YOLOv2`, `UART`. * **Macros**: Use uppercase with underscores, e.g., `MAIXPY_VERSION`. * **Class Member Variables**: Use lowercase with underscores without `m_` prefix, e.g., `name`. * **Private Class Member Variables**: Prefix with `_`, e.g., `_name`. * **Using Class Member Variables**: Explicitly use `this >` for clarity, e.g., `this >name`. * **Namespace**: Use the `maix` namespace for all official APIs, with sub namespaces for different features, e.g., `maix::thread`, `maix::peripheral`. * **Source File Naming**: Use lowercase with underscores, e.g., `maix_peripheral_uart.cpp`. Use `.hpp` for C++ header files. * **Comments**: Follow Doxygen style for API documentation, as shown in [components/basic/include/maix_api_example.hpp](../../../components/basic/include/maix_api_example.hpp). ### API Documentation Guidelines Include the following keywords in your API comments: * **brief**: A brief description of the functionality. * **param**: Detailed parameter descriptions, including value requirements and direction (e.g., `param[in] a`). * **return**: Detailed return value descriptions. * **retval**: Use this for specific return value explanations, e.g., `@retval 0 success`. * **attention**: Special considerations for using the API. * **maixpy**: Indicates a `MaixPy` API, including the package and variable name, e.g., `maix.example`. * **maixcdk**: Indicates a `MaixCDK` API. Follow the guidelines strictly, especially when defining types and default values, to ensure accurate `MaixPy API` and documentation generation. ## API Standardization Suggestions * Prefer MaixCDK APIs over direct third party APIs for better cross platform compatibility, e.g., use `maix_fs.hpp` for file operations. * Use logging APIs from `maix_log.hpp` for consistent logging and to manage log levels. * Use error handling from `maix_err.hpp` for consistent error codes and exception handling. * For common APIs across modules, define a base class and inherit it in specific implementations, enhancing code reuse and consistency across platforms."},"/maixcdk/doc/convention/nn.html":{"title":"NN convention","content":"NN convention ## NN model file Every AI model described by a `.mud` file, which is a INI format file. MUD(Model Universal Description) file is a simple format to describe a model. > The reason we create this file is that every hardware platform has its own model format, it's difficult to load them directly, and we have to write many different code to load them, now we use MUD file and wrote model info in it to make load model easier. MUD file definition: ```ini [basic] type cvimodel model model_path_relative_to_mud_file [extra] model_type classifier input_type bgr mean 103.94, 116.78, 123.68 scale 0.017, 0.017, 0.017 labels labels.txt ``` `basic` section is required, `extra` section is optional. `basic` section describes model type and model path. * `type` is model type, now we support `cvimodel` for `MaixCam`. * `model` is model path relative to MUD file. `extra` section describes model extra info, the application can get it by `model.extra_info()` method. * `model_type` is model function type, like `classifier` and `yolov2`, it's optional for application. * `input_type` is model input type, like `bgr` and `gray`, it's optional for application. * `mean` is model input mean value, it's optional for application. * `scale` is model input scale value, it's optional for application. * `labels` is model labels file path, it's optional for application. Current MaixCDK support: * classifier * classifier_no_top * yolo11 * yolov8 * yolov5 * pp_ocr * retinaface * nanotrack * retinaface * face_detector * speech * and more ... please refer to [components/nn/include](https://github.com/sipeed/MaixCDK/tree/main/components/nn/include) souce code and search `model_type` keyword and see `load` method."}} \ No newline at end of file diff --git a/maixcdk/static/search_index/index_1.json b/maixcdk/static/search_index/index_1.json new file mode 100644 index 00000000..eba252a8 --- /dev/null +++ b/maixcdk/static/search_index/index_1.json @@ -0,0 +1 @@ +{"/maixcdk/api/maix/ext_dev/fp5510.html":{"title":"maix::ext_dev::fp5510","content":" title: maix::ext_dev::fp5510 maix.ext_dev.fp5510 module > This is `maix::ext_dev::fp5510` module of [MaixCDK](https://github.com/sipeed/MaixCDK). > All of these elements are in namespace `maix::ext_dev::fp5510`. > > For MaixCDK developer: DO NOT edit this doc file manually, this doc is auto generated! ## Module {#Module} No module ## Enum {#Enum} ## Variable {#Variable} ## Function {#Function} ## Class {#Class} ### FP5510 {#FP5510} FP5510 class > C++ defination code: > ```cpp > class FP5510 > ``` #### \\_\\_init\\_\\_ {#\\_\\_init\\_\\_} Construct a new FP5510 object item description **type** func **param** **id**: iic number, default is 4
    **slave_addr**: slave address of fp5510, default is 0x0c.
    **freq**: iic frequency, default is 400k
    **static** False > C++ defination code: > ```cpp > FP5510(int id 4, int slave_addr 0x0c, int freq 400000) > ``` #### set\\_pos {#set\\_pos} Set fp5510 position item description **type** func **param** **pos**: the position of fp5510, range is [0, 1023]
    **static** False > C++ defination code: > ```cpp > void set_pos(uint32_t pos) > ``` #### get\\_pos {#get\\_pos} Get fp5510 position item description **type** func **return** returns the position of fp5510, range is [0, 1023] **static** False > C++ defination code: > ```cpp > uint32_t get_pos() > ```"},"/maixcdk/api/maix/ext_dev/mlx90640.html":{"title":"maix::ext_dev::mlx90640","content":" title: maix::ext_dev::mlx90640 maix.ext_dev.mlx90640 module > This is `maix::ext_dev::mlx90640` module of [MaixCDK](https://github.com/sipeed/MaixCDK). > All of these elements are in namespace `maix::ext_dev::mlx90640`. > > For MaixCDK developer: DO NOT edit this doc file manually, this doc is auto generated! ## Module {#Module} No module ## Enum {#Enum} ### Cmap {#Cmap} Cmap item describe **values** **WHITE_HOT**:
    **BLACK_HOT**:
    **IRONBOW**:
    **NIGHT**:
    **RED_HOT**:
    **WHITE_HOT_SD**:
    **BLACK_HOT_SD**:
    **RED_HOT_SD**:
    > C++ defination code: > ```cpp > enum class Cmap : uint8_t { > WHITE_HOT 0, > BLACK_HOT, > IRONBOW, > NIGHT, > RED_HOT, > WHITE_HOT_SD, > BLACK_HOT_SD, > RED_HOT_SD > } > ``` ### FPS {#FPS} MLX90640 FPS item describe **values** **FPS_1**:
    **FPS_2**:
    **FPS_4**:
    **FPS_8**:
    **FPS_16**:
    **FPS_32**:
    **FPS_64**:
    > C++ defination code: > ```cpp > enum class FPS : uint8_t { > FPS_1 0b001, > FPS_2 0b010, > FPS_4 0b011, > FPS_8 0b100, > FPS_16 0b101, > FPS_32 0b110, > FPS_64 0b111, > } > ``` ## Variable {#Variable} ### MLX\\_W {#MLX\\_W} MLX90640 Image Width. item description **value** **32** **readonly** True > C++ defination code: > ```cpp > constexpr uint32_t MLX_W 32 > ``` ### MLX\\_H {#MLX\\_H} MLX90640 Image Height. item description **value** **24** **readonly** True > C++ defination code: > ```cpp > constexpr uint32_t MLX_H 24 > ``` ## Function {#Function} ### to\\_kmatrix {#to\\_kmatrix} CMatrix to KMatrix. item description **param** **matrix**: CMatrix type.
    **return** KMatrix > C++ defination code: > ```cpp > KMatrix to_kmatrix(const CMatrix& matrix) > ``` ### to\\_cmatrix {#to\\_cmatrix} KMatrix to CMatrix item description **param** **matrix**: KMatrix type.
    **return** CMatrix > C++ defination code: > ```cpp > CMatrix to_cmatrix(const KMatrix& matrix) > ``` ## Class {#Class} ### MLX90640Celsius {#MLX90640Celsius} MLX90640 (℃) > C++ defination code: > ```cpp > class MLX90640Celsius final > ``` #### \\_\\_init\\_\\_ {#\\_\\_init\\_\\_} Construct a new MLX90640Celsius object\\nThis constructor initializes an MLX90640Celsius object with the specified parameters\\nto configure the I2C bus communication, frame rate, color mapping, temperature ranges,\\nand emissivity for the MLX90640 thermal camera. item description **type** func **param** **i2c_bus_num**: The I2C bus number to which the MLX90640 is connected.
    **fps**: The preferred frame rate for the MLX90640, default is FPS::FPS_32.
    **cmap**: The color mapping to be used for generating the pseudo color image, default is Cmap::WHITE_HOT.
    **temp_min**: The minimum reference temperature (in °C) for generating the pseudo color image. Default is 1.
    **temp_max**: The maximum reference temperature (in °C) for generating the pseudo color image. Default is 1.
    If both max and min are equal, it operates in auto mode:
    the maximum temperature in the frame is taken as the maximum reference temperature,
    and the minimum temperature in the frame is taken as the minimum reference temperature.
    **emissivity**: The emissivity parameter for the MLX90640, default is 0.95.
    **static** False > C++ defination code: > ```cpp > MLX90640Celsius(int i2c_bus_num, > ::maix::ext_dev::mlx90640::FPS fps ::maix::ext_dev::mlx90640::FPS::FPS_32, > ::maix::ext_dev::mlx90640::Cmap cmap ::maix::ext_dev::mlx90640::Cmap::WHITE_HOT, > float temp_min 1, float temp_max 1, float emissivity 0.95) > ``` #### matrix {#matrix} Retrieves sensor data and returns a temperature matrix of size MLX_H * MLX_W\\nMLX_W: 32\\n \\n\\nMLX_H \\n: 24 \\nThe matrix structure is represented as list[MLX_H][MLX_W],\\nwhere MLX_H is the number of rows (24) and MLX_W is the number of columns (32). item description **type** func **return** CMatrix containing the temperature data, or an empty matrix ([]) if the operation fails. **static** False > C++ defination code: > ```cpp > CMatrix matrix() > ``` #### image {#image} Obtains sensor data and converts it into a pseudo color image\\nThis function retrieves the thermal data from the sensor and processes it\\nto generate a pseudo color representation of the temperature distribution. item description **type** func **return** maix::image::Image* A raw pointer to a maix image object.
    It is the responsibility of the caller to free this memory
    in C/C++ to prevent memory leaks. **static** False > C++ defination code: > ```cpp > ::maix::image::Image* image() > ``` #### min\\_temp\\_point {#min\\_temp\\_point} Finds the pixel with the minimum temperature from the most recent reading\\nThis function identifies the pixel with the minimum temperature\\nfrom the latest data obtained from the sensor. item description **type** func **return** Point A tuple of type , representing
    (x, y, temperature) of the pixel with the minimum temperature.
    If the operation fails, the return values will be x, y < 0. **static** False > C++ defination code: > ```cpp > Point min_temp_point() > ``` #### max\\_temp\\_point {#max\\_temp\\_point} Finds the pixel with the maximum temperature from the most recent reading\\nThis function identifies the pixel with the maximum temperature\\nfrom the latest data obtained from the sensor. item description **type** func **return** Point A tuple of type , representing
    (x, y, temperature) of the pixel with the maximum temperature.
    If the operation fails, the return values will be x, y < 0. **static** False > C++ defination code: > ```cpp > Point max_temp_point() > ``` #### center\\_point {#center\\_point} Finds the center pixel from the most recent reading\\nThis function determines the center pixel of the temperature matrix\\nbased on the most recent data obtained from the sensor. item description **type** func **return** Point A tuple of type , representing
    (x, y, temperature) of the center pixel in the temperature matrix.
    If the operation fails, the return values will be x, y < 0. **static** False > C++ defination code: > ```cpp > Point center_point() > ``` #### image\\_from {#image\\_from} Converts a given matrix of temperature data into an image\\nThis function takes a temperature matrix and generates\\na corresponding image representation based on the\\nconfigured color map and other parameters. item description **type** func **param** **matrix**: The temperature matrix to be converted.
    **return** maix::image::Image* A pointer to the generated image.
    It is the responsibility of the caller to free this memory
    in C/C++ to prevent memory leaks. **static** False > C++ defination code: > ```cpp > ::maix::image::Image* image_from(const CMatrix& matrix) > ``` #### max\\_temp\\_point\\_from {#max\\_temp\\_point\\_from} Finds the pixel with the maximum temperature from the given matrix\\nThis static function identifies the pixel with the maximum temperature\\nfrom the specified temperature matrix. item description **type** func **param** **matrix**: The temperature matrix to be analyzed.
    **return** Point A tuple of type , representing
    (x, y, temperature) of the pixel with the maximum temperature.
    If the operation fails, the return values will be x, y < 0. **static** True > C++ defination code: > ```cpp > static Point max_temp_point_from(const CMatrix& matrix) > ``` #### min\\_temp\\_point\\_from {#min\\_temp\\_point\\_from} Finds the pixel with the minimum temperature from the given matrix\\nThis static function identifies the pixel with the minimum temperature\\nfrom the specified temperature matrix. item description **type** func **param** **matrix**: The temperature matrix to be analyzed.
    **return** Point A tuple of type , representing
    (x, y, temperature) of the pixel with the minimum temperature.
    If the operation fails, the return values will be x, y < 0. **static** True > C++ defination code: > ```cpp > static Point min_temp_point_from(const CMatrix& matrix) > ``` #### center\\_point\\_from {#center\\_point\\_from} Finds the center pixel from the given matrix\\nThis static function determines the center pixel of the\\nspecified temperature matrix based on its dimensions. item description **type** func **param** **matrix**: The temperature matrix to be analyzed.
    **return** Point A tuple of type , representing
    (x, y, temperature) of the center pixel in the matrix.
    If the operation fails, the return values will be x, y < 0. **static** True > C++ defination code: > ```cpp > static Point center_point_from(const CMatrix& matrix) > ``` ### MLX90640Kelvin {#MLX90640Kelvin} MLX90640 (K)) > C++ defination code: > ```cpp > class MLX90640Kelvin final > ``` #### \\_\\_init\\_\\_ {#\\_\\_init\\_\\_ 2} Construct a new MLX90640Kelvin object\\nThis constructor initializes an MLX90640Kelvin object with the specified parameters\\nto configure the I2C bus communication, frame rate, color mapping, temperature ranges,\\nand emissivity for the MLX90640 thermal camera. item description **type** func **param** **i2c_bus_num**: The I2C bus number to which the MLX90640 is connected.
    **fps**: The preferred frame rate for the MLX90640, default is FPS::FPS_32.
    **cmap**: The color mapping to be used for generating the pseudo color image, default is Cmap::WHITE_HOT.
    **temp_min**: The minimum reference temperature (in K) for generating the pseudo color image. Default is 1.
    **temp_max**: The maximum reference temperature (in K) for generating the pseudo color image. Default is 1.
    If both max and min are equal, it operates in auto mode:
    the maximum temperature in the frame is taken as the maximum reference temperature,
    and the minimum temperature in the frame is taken as the minimum reference temperature.
    **emissivity**: The emissivity parameter for the MLX90640, default is 0.95.
    **static** False > C++ defination code: > ```cpp > MLX90640Kelvin( int i2c_bus_num, > ::maix::ext_dev::mlx90640::FPS fps ::maix::ext_dev::mlx90640::FPS::FPS_32, > ::maix::ext_dev::mlx90640::Cmap cmap ::maix::ext_dev::mlx90640::Cmap::WHITE_HOT, > float temp_min 1, float temp_max 1, float emissivity 0.95) > ``` #### matrix {#matrix 2} Retrieves sensor data and returns a temperature matrix of size MLX_H * MLX_W\\nMLX_W: 32\\n \\n\\nMLX_H \\n: 24 \\nThe matrix structure is represented as list[MLX_H][MLX_W],\\nwhere MLX_H is the number of rows (24) and MLX_W is the number of columns (32). item description **type** func **return** KMatrix containing the temperature data, or an empty matrix ([]) if the operation fails. **static** False > C++ defination code: > ```cpp > KMatrix matrix() > ``` #### image {#image 2} Obtains sensor data and converts it into a pseudo color image\\nThis function retrieves the thermal data from the sensor and processes it\\nto generate a pseudo color representation of the temperature distribution. item description **type** func **return** maix::image::Image* A raw pointer to a maix image object.
    It is the responsibility of the caller to free this memory
    in C/C++ to prevent memory leaks. **static** False > C++ defination code: > ```cpp > ::maix::image::Image* image() > ``` #### max\\_temp\\_point {#max\\_temp\\_point 2} Finds the pixel with the minimum temperature from the most recent reading\\nThis function identifies the pixel with the minimum temperature\\nfrom the latest data obtained from the sensor. item description **type** func **return** Point A tuple of type , representing
    (x, y, temperature) of the pixel with the minimum temperature.
    If the operation fails, the return values will be x, y < 0. **static** False > C++ defination code: > ```cpp > Point max_temp_point() > ``` #### min\\_temp\\_point {#min\\_temp\\_point 2} Finds the pixel with the maximum temperature from the most recent reading\\nThis function identifies the pixel with the maximum temperature\\nfrom the latest data obtained from the sensor. item description **type** func **return** Point A tuple of type , representing
    (x, y, temperature) of the pixel with the maximum temperature.
    If the operation fails, the return values will be x, y < 0. **static** False > C++ defination code: > ```cpp > Point min_temp_point() > ``` #### center\\_point {#center\\_point 2} Finds the center pixel from the most recent reading\\nThis function determines the center pixel of the temperature matrix\\nbased on the most recent data obtained from the sensor. item description **type** func **return** Point A tuple of type , representing
    (x, y, temperature) of the center pixel in the temperature matrix.
    If the operation fails, the return values will be x, y < 0. **static** False > C++ defination code: > ```cpp > Point center_point() > ``` #### image\\_from {#image\\_from 2} Converts a given matrix of temperature data into an image\\nThis function takes a temperature matrix and generates\\na corresponding image representation based on the\\nconfigured color map and other parameters. item description **type** func **param** **matrix**: The temperature matrix to be converted.
    **return** maix::image::Image* A pointer to the generated image.
    It is the responsibility of the caller to free this memory
    in C/C++ to prevent memory leaks. **static** False > C++ defination code: > ```cpp > ::maix::image::Image* image_from(const KMatrix& matrix) > ``` #### max\\_temp\\_point\\_from {#max\\_temp\\_point\\_from 2} Finds the pixel with the maximum temperature from the given matrix\\nThis static function identifies the pixel with the maximum temperature\\nfrom the specified temperature matrix. item description **type** func **param** **matrix**: The temperature matrix to be analyzed.
    **return** Point A tuple of type , representing
    (x, y, temperature) of the pixel with the maximum temperature.
    If the operation fails, the return values will be x, y < 0. **static** True > C++ defination code: > ```cpp > static Point max_temp_point_from(const KMatrix& matrix) > ``` #### min\\_temp\\_point\\_from {#min\\_temp\\_point\\_from 2} Finds the pixel with the minimum temperature from the given matrix\\nThis static function identifies the pixel with the minimum temperature\\nfrom the specified temperature matrix. item description **type** func **param** **matrix**: The temperature matrix to be analyzed.
    **return** Point A tuple of type , representing
    (x, y, temperature) of the pixel with the minimum temperature.
    If the operation fails, the return values will be x, y < 0. **static** True > C++ defination code: > ```cpp > static Point min_temp_point_from(const KMatrix& matrix) > ``` #### center\\_point\\_from {#center\\_point\\_from 2} Finds the center pixel from the given matrix\\nThis static function determines the center pixel of the\\nspecified temperature matrix based on its dimensions. item description **type** func **param** **matrix**: The temperature matrix to be analyzed.
    **return** Point A tuple of type , representing
    (x, y, temperature) of the center pixel in the matrix.
    If the operation fails, the return values will be x, y < 0. **static** True > C++ defination code: > ```cpp > static Point center_point_from(const KMatrix& matrix) > ```"},"/maixcdk/api/maix/ext_dev/axp2101.html":{"title":"maix::ext_dev::axp2101","content":" title: maix::ext_dev::axp2101 maix.ext_dev.axp2101 module > This is `maix::ext_dev::axp2101` module of [MaixCDK](https://github.com/sipeed/MaixCDK). > All of these elements are in namespace `maix::ext_dev::axp2101`. > > For MaixCDK developer: DO NOT edit this doc file manually, this doc is auto generated! ## Module {#Module} No module ## Enum {#Enum} ### ChargerStatus {#ChargerStatus} charger status item describe **values** **CHG_TRI_STATE**: tri_charge
    **CHG_PRE_STATE**: pre_charge
    **CHG_CC_STATE**: constant charge
    **CHG_CV_STATE**: constant voltage
    **CHG_DONE_STATE**: charge done
    **CHG_STOP_STATE**: not charge
    > C++ defination code: > ```cpp > enum class ChargerStatus { > CHG_TRI_STATE, //tri_charge > CHG_PRE_STATE, //pre_charge > CHG_CC_STATE, //constant charge > CHG_CV_STATE, //constant voltage > CHG_DONE_STATE, //charge done > CHG_STOP_STATE, //not charge > } > ``` ### ChargerCurrent {#ChargerCurrent} charger current item describe **values** **CHG_CUR_0MA**:
    **CHG_CUR_100MA**:
    **CHG_CUR_125MA**:
    **CHG_CUR_150MA**:
    **CHG_CUR_175MA**:
    **CHG_CUR_200MA**:
    **CHG_CUR_300MA**:
    **CHG_CUR_400MA**:
    **CHG_CUR_500MA**:
    **CHG_CUR_600MA**:
    **CHG_CUR_700MA**:
    **CHG_CUR_800MA**:
    **CHG_CUR_900MA**:
    **CHG_CUR_1000MA**:
    > C++ defination code: > ```cpp > enum class ChargerCurrent { > CHG_CUR_0MA, > CHG_CUR_100MA 4, > CHG_CUR_125MA, > CHG_CUR_150MA, > CHG_CUR_175MA, > CHG_CUR_200MA, > CHG_CUR_300MA, > CHG_CUR_400MA, > CHG_CUR_500MA, > CHG_CUR_600MA, > CHG_CUR_700MA, > CHG_CUR_800MA, > CHG_CUR_900MA, > CHG_CUR_1000MA, > } > ``` ### PowerChannel {#PowerChannel} power channel item describe **values** **DCDC1**:
    **DCDC2**:
    **DCDC3**:
    **DCDC4**:
    **DCDC5**:
    **ALDO1**:
    **ALDO2**:
    **ALDO3**:
    **ALDO4**:
    **BLDO1**:
    **BLDO2**:
    **DLDO1**:
    **DLDO2**:
    **VBACKUP**:
    **CPULDO**:
    > C++ defination code: > ```cpp > enum class PowerChannel { > DCDC1, > DCDC2, > DCDC3, > DCDC4, > DCDC5, > ALDO1, > ALDO2, > ALDO3, > ALDO4, > BLDO1, > BLDO2, > DLDO1, > DLDO2, > VBACKUP, > CPULDO, > } > ``` ### PowerOffTime {#PowerOffTime} power off time item describe **values** **POWEROFF_4S**:
    **POWEROFF_6S**:
    **POWEROFF_8S**:
    **POWEROFF_10S**:
    **POWEROFF_DISABLE**:
    > C++ defination code: > ```cpp > enum class PowerOffTime { > POWEROFF_4S, > POWEROFF_6S, > POWEROFF_8S, > POWEROFF_10S, > POWEROFF_DISABLE 65535, > } > ``` ### PowerOnTime {#PowerOnTime} power on time item describe **values** **POWERON_128MS**:
    **POWERON_512MS**:
    **POWERON_1S**:
    **POWERON_2S**:
    > C++ defination code: > ```cpp > enum class PowerOnTime { > POWERON_128MS, > POWERON_512MS, > POWERON_1S, > POWERON_2S, > } > ``` ## Variable {#Variable} ## Function {#Function} ## Class {#Class} ### AXP2101 {#AXP2101} Peripheral AXP2101 class > C++ defination code: > ```cpp > class AXP2101 > ``` #### \\_\\_init\\_\\_ {#\\_\\_init\\_\\_} AXP2101 constructor. item description **type** func **param** **i2c_bus**: i2c bus number.
    **addr**: pmu device addr.
    **static** False > C++ defination code: > ```cpp > AXP2101(int i2c_bus 1, uint8_t addr 0x34) > ``` #### init {#init} Initialise the AXP2101. item description **type** func **return** err::Err type, if init success, return err::ERR_NONE. **static** False > C++ defination code: > ```cpp > err::Err init() > ``` #### poweroff {#poweroff} Poweroff immediately. item description **type** func **return** err::Err type, if init success, return err::ERR_NONE. **static** False > C++ defination code: > ```cpp > err::Err poweroff() > ``` #### is\\_bat\\_connect {#is\\_bat\\_connect} Is the battery connected. item description **type** func **return** bool type, if battery is connected, return true. **static** False > C++ defination code: > ```cpp > bool is_bat_connect() > ``` #### is\\_vbus\\_in {#is\\_vbus\\_in} Is the power adapter connected. item description **type** func **return** bool type, if power adapter is connected, return true. **static** False > C++ defination code: > ```cpp > bool is_vbus_in() > ``` #### is\\_charging {#is\\_charging} Is bat charging. item description **type** func **return** bool type, if bat is charging, return true. **static** False > C++ defination code: > ```cpp > bool is_charging() > ``` #### get\\_bat\\_percent {#get\\_bat\\_percent} Get the battery percentage. item description **type** func **return** int type, return battery percentage. **static** False > C++ defination code: > ```cpp > int get_bat_percent() > ``` #### get\\_charger\\_status {#get\\_charger\\_status} Get the battery charging status. item description **type** func **return** int type, return battery charging status. **static** False > C++ defination code: > ```cpp > ext_dev::axp2101::ChargerStatus get_charger_status() > ``` #### get\\_charger\\_status (overload 1) {#get\\_charger\\_status (overload 1)} Get the battery voltage. item description **type** func **return** uint16_t type, return battery voltage. **static** False > C++ defination code: > ```cpp > uint16_t get_bat_vol() > ``` #### clean\\_irq {#clean\\_irq} Clear interrupt flag. item description **type** func **return** err::Err type, if clean success, return err::ERR_NONE. **static** False > C++ defination code: > ```cpp > err::Err clean_irq() > ``` #### set\\_bat\\_charging\\_cur {#set\\_bat\\_charging\\_cur} Set the battery charging current. item description **type** func **param** **current**: The current to be set.
    The available values are 0mA, 100mA, 125mA, 150mA, 175mA,
    200mA, 300mA, 400mA, 500mA, 600mA, 700mA, 800mA, 900mA, and 1000mA.
    **return** err::Err type, if set success, return err::ERR_NONE. **static** False > C++ defination code: > ```cpp > err::Err set_bat_charging_cur(ext_dev::axp2101::ChargerCurrent current) > ``` #### get\\_bat\\_charging\\_cur {#get\\_bat\\_charging\\_cur} Get the battery charging current. item description **type** func **return** ChargerCurrent, return the currently set charging current. **static** False > C++ defination code: > ```cpp > ext_dev::axp2101::ChargerCurrent get_bat_charging_cur() > ``` #### dcdc1 {#dcdc1} Set and get the PMU DCDC1 voltage. item description **type** func **param** **voltage**: The voltage to be set,
    voltage range is 1500mV~3400mV(step 20mV).
    **return** int, return the PMU DCDC1 voltage. **static** False > C++ defination code: > ```cpp > int dcdc1(int voltage 1) > ``` #### dcdc2 {#dcdc2} Set and get the PMU DCDC2 voltage. item description **type** func **param** **voltage**: The voltage to be set,
    voltage range is 500mV~1200mV(step 10mV) and 1220mV~1540mV(step 20mV).
    **return** int, return the PMU DCDC2 voltage. **static** False > C++ defination code: > ```cpp > int dcdc2(int voltage 1) > ``` #### dcdc3 {#dcdc3} Set and get the PMU DCDC3 voltage. item description **type** func **param** **voltage**: The voltage to be set,
    voltage range is 500mV~1200mV(step 10mV) and 1220mV~1540mV(step 20mV).
    **return** int, return the PMU DCDC3 voltage. **static** False > C++ defination code: > ```cpp > int dcdc3(int voltage 1) > ``` #### dcdc4 {#dcdc4} Set and get the PMU DCDC4 voltage. item description **type** func **param** **voltage**: The voltage to be set,
    voltage range is 500mV~1200mV(step 10mV) and 1220mV~1840mV(step 20mV).
    **return** int, return the PMU DCDC4 voltage. **static** False > C++ defination code: > ```cpp > int dcdc4(int voltage 1) > ``` #### dcdc5 {#dcdc5} Set and get the PMU DCDC5 voltage. item description **type** func **param** **voltage**: The voltage to be set,
    voltage range is 1400mV~3700mV(step 100mV).
    **return** int, return the PMU DCDC5 voltage. **static** False > C++ defination code: > ```cpp > int dcdc5(int voltage 1) > ``` #### aldo1 {#aldo1} Set and get the PMU ALDO1 voltage. item description **type** func **param** **voltage**: The voltage to be set,
    voltage range is 500mV~3500mV(step 100mV).
    **return** int, return the PMU ALDO1 voltage. **static** False > C++ defination code: > ```cpp > int aldo1(int voltage 1) > ``` #### aldo2 {#aldo2} Set and get the PMU ALDO2 voltage. item description **type** func **param** **voltage**: The voltage to be set,
    voltage range is 500mV~3500mV(step 100mV).
    **return** int, return the PMU ALDO2 voltage. **static** False > C++ defination code: > ```cpp > int aldo2(int voltage 1) > ``` #### aldo3 {#aldo3} Set and get the PMU ALDO3 voltage. item description **type** func **param** **voltage**: The voltage to be set,
    voltage range is 500mV~3500mV(step 100mV).
    **return** int, return the PMU ALDO3 voltage. **static** False > C++ defination code: > ```cpp > int aldo3(int voltage 1) > ``` #### aldo4 {#aldo4} Set and get the PMU ALDO4 voltage. item description **type** func **param** **voltage**: The voltage to be set,
    voltage range is 500mV~3500mV(step 100mV).
    **return** int, return the PMU ALDO4 voltage. **static** False > C++ defination code: > ```cpp > int aldo4(int voltage 1) > ``` #### bldo1 {#bldo1} Set and get the PMU BLDO1 voltage. item description **type** func **param** **voltage**: The voltage to be set,
    voltage range is 500mV~3500mV(step 100mV).
    **return** int, return the PMU BLDO1 voltage. **static** False > C++ defination code: > ```cpp > int bldo1(int voltage 1) > ``` #### bldo2 {#bldo2} Set and get the PMU BLDO2 voltage. item description **type** func **param** **voltage**: The voltage to be set,
    voltage range is 500mV~3500mV(step 100mV).
    **return** int, return the PMU BLDO2 voltage. **static** False > C++ defination code: > ```cpp > int bldo2(int voltage 1) > ``` #### set\\_poweroff\\_time {#set\\_poweroff\\_time} Set power off time, The device will shut down\\nif the power button is held down longer than this time. item description **type** func **param** **tm**: The time to be set, you can set it to 4s, 6s, 8s, or 10s.
    **return** err::Err type, if set success, return err::ERR_NONE. **static** False > C++ defination code: > ```cpp > err::Err set_poweroff_time(ext_dev::axp2101::PowerOffTime tm) > ``` #### get\\_poweroff\\_time {#get\\_poweroff\\_time} Get power off time. item description **type** func **return** PowerOffTime, return power off time. **static** False > C++ defination code: > ```cpp > ext_dev::axp2101::PowerOffTime get_poweroff_time() > ``` #### set\\_poweron\\_time {#set\\_poweron\\_time} Set power on time, The device will power on\\nif the power button is held down longer than this time. item description **type** func **param** **tm**: The time to be set, you can set it to 128ms, 512ms, 1s, or 2s.
    **return** err::Err type, if set success, return err::ERR_NONE. **static** False > C++ defination code: > ```cpp > err::Err set_poweron_time(ext_dev::axp2101::PowerOnTime tm) > ``` #### get\\_poweron\\_time {#get\\_poweron\\_time} Get power on time. item description **type** func **return** PowerOnTime, return power on time. **static** False > C++ defination code: > ```cpp > ext_dev::axp2101::PowerOnTime get_poweron_time() > ```"},"/maixcdk/api/maix/ext_dev/qmi8658.html":{"title":"maix::ext_dev::qmi8658","content":" title: maix::ext_dev::qmi8658 maix.ext_dev.qmi8658 module > This is `maix::ext_dev::qmi8658` module of [MaixCDK](https://github.com/sipeed/MaixCDK). > All of these elements are in namespace `maix::ext_dev::qmi8658`. > > For MaixCDK developer: DO NOT edit this doc file manually, this doc is auto generated! ## Module {#Module} No module ## Enum {#Enum} ## Variable {#Variable} ## Function {#Function} ## Class {#Class} ### QMI8658 {#QMI8658} QMI8656 driver class > C++ defination code: > ```cpp > class QMI8658 > ``` #### \\_\\_init\\_\\_ {#\\_\\_init\\_\\_} Construct a new QMI8658 object, will open QMI8658 item description **type** func **param** **i2c_bus**: i2c bus number. Automatically selects the on board qmi8658 when 1 is passed in.
    **addr**: QMI8658 i2c addr.
    **freq**: QMI8658 freq
    **mode**: QMI8658 Mode: ACC_ONLY/GYRO_ONLY/DUAL
    **acc_scale**: acc scale, see @qmi8658::AccScale
    **acc_odr**: acc output data rate, see @qmi8658::AccOdr
    **gyro_scale**: gyro scale, see @qmi8658::GyroScale
    **gyro_odr**: gyro output data rate, see @qmi8658::GyroOdr
    **block**: block or non block, defalut is true
    **static** False > C++ defination code: > ```cpp > QMI8658(int i2c_bus 1, int addr 0x6B, int freq 400000, > maix::ext_dev::imu::Mode mode maix::ext_dev::imu::Mode::DUAL, > maix::ext_dev::imu::AccScale acc_scale maix::ext_dev::imu::AccScale::ACC_SCALE_2G, > maix::ext_dev::imu::AccOdr acc_odr maix::ext_dev::imu::AccOdr::ACC_ODR_8000, > maix::ext_dev::imu::GyroScale gyro_scale maix::ext_dev::imu::GyroScale::GYRO_SCALE_16DPS, > maix::ext_dev::imu::GyroOdr gyro_odr maix::ext_dev::imu::GyroOdr::GYRO_ODR_8000, > bool block true) > ``` #### read {#read} Read data from QMI8658. item description **type** func **return** list type. If only one of the outputs is initialized, only [x,y,z] of that output will be returned.
    If all outputs are initialized, [acc_x, acc_y, acc_z, gyro_x, gyro_y, gyro_z] is returned. **static** False > C++ defination code: > ```cpp > std::vector read() > ```"},"/maixcdk/api/maix/ext_dev/tmc2209.html":{"title":"maix::ext_dev::tmc2209","content":" title: maix::ext_dev::tmc2209 maix.ext_dev.tmc2209 module > This is `maix::ext_dev::tmc2209` module of [MaixCDK](https://github.com/sipeed/MaixCDK). > All of these elements are in namespace `maix::ext_dev::tmc2209`. > > For MaixCDK developer: DO NOT edit this doc file manually, this doc is auto generated! ## Module {#Module} No module ## Enum {#Enum} ## Variable {#Variable} ## Function {#Function} ### slide\\_scan {#slide\\_scan} Scan and initialize the slide with the given parameters item description **param** **port**: UART port, string type.
    **addr**: TMC2209 UART address, range 0x00~0x03, integer type.
    **baud**: UART baud rate, integer type.
    **step_angle**: Motor step angle, float type.
    **micro_step**: Motor micro step, options: 1/2/4/8/16/32/64/128/256, integer type.
    **round_mm**: Round distance in mm, float type.
    **speed_mm_s**: Speed of the slide in mm/s, float type.
    **dir**: Direction of movement, boolean type. Default is true.
    **use_internal_sense_resistors**: Enable internal sense resistors if true, disable if false, boolean type. Default is true.
    **run_current_per**: Motor run current percentage, range 0~100(%), integer type. Default is 100%.
    **hold_current_per**: Motor hold current percentage, range 0~100(%), integer type. Default is 100%.
    **conf_save_path**: Configuration save path, string type. Default is \"./slide_conf.bin\".
    **force_update**: Force update the configuration if true, boolean type. Default is true.
    > C++ defination code: > ```cpp > void slide_scan(const char* port, uint8_t addr, long baud, /* Uart init param */ > float step_angle, uint16_t micro_step, float round_mm, /* Motor init param */ > float speed_mm_s, bool dir true, bool use_internal_sense_resistors true, uint8_t run_current_per 100, > uint8_t hold_current_per 100, const std::string conf_save_path \"./slide_conf.bin\", > bool force_update true /* Driver init param */) > ``` ### slide\\_test {#slide\\_test} Test the slide with the given parameters\\nThis function tests the slide by moving it in the specified direction until a stall condition is detected, as defined in the configuration file. item description **param** **port**: UART port, string type.
    **addr**: TMC2209 UART address, range 0x00~0x03, integer type.
    **baud**: UART baud rate, integer type.
    **step_angle**: Motor step angle, float type.
    **micro_step**: Motor micro step, options: 1/2/4/8/16/32/64/128/256, integer type.
    **round_mm**: Round distance in mm, float type.
    **speed_mm_s**: Speed of the slide in mm/s, float type.
    **dir**: Direction of movement, boolean type. Default is true.
    **use_internal_sense_resistors**: Enable internal sense resistors if true, disable if false, boolean type. Default is true.
    **run_current_per**: Motor run current percentage, range 0~100(%), integer type. Default is 100%.
    **hold_current_per**: Motor hold current percentage, range 0~100(%), integer type. Default is 100%.
    **conf_save_path**: Configuration save path, string type. Default is \"./slide_conf.bin\".
    > C++ defination code: > ```cpp > void slide_test(const char* port, uint8_t addr, long baud, /* Uart init param */ > float step_angle, uint16_t micro_step, float round_mm, /* Motor init param */ > float speed_mm_s, bool dir true, bool use_internal_sense_resistors true, uint8_t run_current_per 100, > uint8_t hold_current_per 100, const std::string conf_save_path \"./slide_conf.bin\"/* Driver init param */) > ``` ## Class {#Class} ### Slide {#Slide} Slide Class > C++ defination code: > ```cpp > class Slide > ``` #### \\_\\_init\\_\\_ {#\\_\\_init\\_\\_} Constructor for Slide\\nInitializes the Slide object with the specified parameters. item description **type** func **param** **port**: UART port, string type.
    **addr**: TMC2209 UART address, range 0x00~0x03, integer type.
    **baud**: UART baud rate, integer type.
    **step_angle**: Motor step angle, float type.
    **micro_step**: Motor micro step, options: 1/2/4/8/16/32/64/128/256, integer type.
    **round_mm**: Round distance in mm, float type.
    **speed_mm_s**: Speed of the slide in mm/s, float type. Default is 1, indicating the use of a default speed factor.
    **use_internal_sense_resistors**: Enable internal sense resistors if TRUE, disable if FALSE, boolean type. Default is TRUE.
    **run_current_per**: Motor run current percentage, range 0~100(%), integer type. Default is 100%.
    **hold_current_per**: Motor hold current percentage, range 0~100(%), integer type. Default is 100%.
    **cfg_file_path**: Configuration file path, string type. Default is an empty string, indicating no configuration file.
    **static** False > C++ defination code: > ```cpp > Slide(const char* port, uint8_t addr, long baud, /* Uart init param */ > float step_angle, uint16_t micro_step, float round_mm, /* Motor init param */ > float speed_mm_s 1, bool use_internal_sense_resistors true, uint8_t run_current_per 100, > uint8_t hold_current_per 100, std::string cfg_file_path \"\" /* Driver init param */) > ``` #### load\\_conf {#load\\_conf} Load configuration from a file\\nLoads the configuration settings for the slide from the specified file path. item description **type** func **param** **path**: Path to the configuration file, string type.
    **static** False > C++ defination code: > ```cpp > void load_conf(std::string path) > ``` #### move {#move} Move the slide by a specified length\\nMoves the slide by the specified length at the given speed. Optionally checks for stall conditions. item description **type** func **param** **oft**: Length to move, float type.
    **speed_mm_s**: Speed in mm/s. Default is 1, indicating the use of the default speed set during initialization.
    **check**: Enable movement check if true, boolean type. Default is true.
    **static** False > C++ defination code: > ```cpp > void move(float oft, int speed_mm_s 1, bool check true) > ``` #### reset {#reset} Reset the slide position\\nResets the slide position in the specified direction at the given speed. item description **type** func **param** **dir**: Direction of reset, boolean type. Default is false.
    **speed_mm_s**: Speed in mm/s. Default is 1, indicating the use of the speed set during initialization.
    **static** False > C++ defination code: > ```cpp > void reset(bool dir false, int speed_mm_s 1) > ``` #### stop\\_default\\_per {#stop\\_default\\_per} Get or set the stop default percentage\\nRetrieves or sets the stop default percentage. If the parameter is 1, it returns the current setting. item description **type** func **param** **per**: Stop default percentage, range 0~100(%), integer type. Default is 1, indicating no change.
    **return** int Current stop default percentage if per is 1, otherwise the new set percentage. **static** False > C++ defination code: > ```cpp > int stop_default_per(int per 1) > ``` #### run\\_current\\_per {#run\\_current\\_per} Get or set the run current percentage\\nRetrieves or sets the run current percentage. If the parameter is 1, it returns the current setting. item description **type** func **param** **per**: Run current percentage, range 0~100(%), integer type. Default is 1, indicating no change.
    **return** int Current run current percentage if per is 1, otherwise the new set percentage. **static** False > C++ defination code: > ```cpp > int run_current_per(int per 1) > ``` #### hold\\_current\\_per {#hold\\_current\\_per} Get or set the hold current percentage\\nRetrieves or sets the hold current percentage. If the parameter is 1, it returns the current setting. item description **type** func **param** **per**: Hold current percentage, range 0~100(%), integer type. Default is 1, indicating no change.
    **return** int Current hold current percentage if per is 1, otherwise the new set percentage. **static** False > C++ defination code: > ```cpp > int hold_current_per(int per 1) > ``` #### use\\_internal\\_sense\\_resistors {#use\\_internal\\_sense\\_resistors} Enable or disable internal sense resistors\\nEnables or disables the internal sense resistors based on the provided boolean value. item description **type** func **param** **b**: Boolean value to enable (true) or disable (false) internal sense resistors. Default is true.
    **static** False > C++ defination code: > ```cpp > void use_internal_sense_resistors(bool b true) > ``` ### ScrewSlide {#ScrewSlide} ScrewSlide Class > C++ defination code: > ```cpp > class ScrewSlide > ``` #### \\_\\_init\\_\\_ {#\\_\\_init\\_\\_ 2} Constructor for ScrewSlide item description **type** func **param** **port**: UART port, string type.
    **addr**: TMC2209 UART address, range 0x00~0x03, integer type.
    **baud**: UART baud rate, integer type.
    **step_angle**: Motor step angle, float type.
    **micro_step**: Motor micro step, options: 1/2/4/8/16/32/64/128/256, integer type.
    **screw_pitch**: Screw pitch of the slide, integer type.
    **speed_mm_s**: Speed of the slide in mm/s, 10 means 10mm/s, float type.
    Default is 1, indicating the use of a default speed factor.
    **use_internal_sense_resistors**: Enable internal sense resistors if TRUE,
    disable if FALSE, boolean type. Default is TRUE.
    **run_current_per**: Motor run current percentage, range 0~100(%), integer type. Default is 100%.
    **hold_current_per**: Motor hold current percentage, range 0~100(%), integer type. Default is 100%.
    **static** False > C++ defination code: > ```cpp > ScrewSlide(const char* port, uint8_t addr, long baud, /* Uart init param */ > float step_angle, uint16_t micro_step, float screw_pitch, /* Motor init param */ > float speed_mm_s 1, bool use_internal_sense_resistors true, uint8_t run_current_per 100, > uint8_t hold_current_per 100) > ``` #### move {#move 2} Move the slide by a specified length item description **type** func **param** **oft**: Length to move, 10 means 10mm, float type.
    Positive values move the slide in the positive direction, negative values move it in the opposite direction.
    **speed_mm_s**: Speed in mm/s. Default is 1, indicating the use of the default speed set during initialization.
    **callback**: Callback function to be called during movement.
    The callback function receives the current progress percentage (0~100%) of the movement.
    If the callback returns true, the move operation will be terminated immediately. Default is nullptr.
    **static** False > C++ defination code: > ```cpp > void move(float oft, int speed_mm_s 1, std::function callback nullptr) > ``` #### reset {#reset 2} Reset the slide position item description **type** func **param** **callback**: Callback function to be called during the reset loop.
    The reset operation will only terminate if the callback returns true.
    **dir**: Direction of reset. Default is false.
    **speed_mm_s**: Speed in mm/s. Default is 1, indicating the use of the speed set during initialization.
    **static** False > C++ defination code: > ```cpp > void reset(std::function callback, bool dir false, int speed_mm_s 1) > ``` #### run\\_current\\_per {#run\\_current\\_per 2} Get or set the run current percentage item description **type** func **param** **per**: Run current percentage, range 0~100(%).
    Default is 1, indicating no change and returning the current run current percentage.
    **return** int Current run current percentage if per is 1, otherwise the new set percentage. **static** False > C++ defination code: > ```cpp > int run_current_per(int per 1) > ``` #### hold\\_current\\_per {#hold\\_current\\_per 2} Get or set the hold current percentage item description **type** func **param** **per**: Hold current percentage, range 0~100(%). Default is 1, indicating no change and returning the current hold current percentage.
    **return** int Current hold current percentage if per is 1, otherwise the new set percentage. **static** False > C++ defination code: > ```cpp > int hold_current_per(int per 1) > ``` #### use\\_internal\\_sense\\_resistors {#use\\_internal\\_sense\\_resistors 2} Enable or disable internal sense resistors item description **type** func **param** **b**: Boolean value to enable (true) or disable (false) internal sense resistors. Default is true.
    **static** False > C++ defination code: > ```cpp > void use_internal_sense_resistors(bool b true) > ```"},"/maixcdk/api/maix/ext_dev/pmu.html":{"title":"maix::ext_dev::pmu","content":" title: maix::ext_dev::pmu maix.ext_dev.pmu module > This is `maix::ext_dev::pmu` module of [MaixCDK](https://github.com/sipeed/MaixCDK). > All of these elements are in namespace `maix::ext_dev::pmu`. > > For MaixCDK developer: DO NOT edit this doc file manually, this doc is auto generated! ## Module {#Module} No module ## Enum {#Enum} ### ChargerStatus {#ChargerStatus} charger status item describe **values** **CHG_TRI_STATE**: tri_charge
    **CHG_PRE_STATE**: pre_charge
    **CHG_CC_STATE**: constant charge
    **CHG_CV_STATE**: constant voltage
    **CHG_DONE_STATE**: charge done
    **CHG_STOP_STATE**: not charge
    > C++ defination code: > ```cpp > enum class ChargerStatus { > CHG_TRI_STATE, //tri_charge > CHG_PRE_STATE, //pre_charge > CHG_CC_STATE, //constant charge > CHG_CV_STATE, //constant voltage > CHG_DONE_STATE, //charge done > CHG_STOP_STATE, //not charge > } > ``` ### PowerChannel {#PowerChannel} power channel item describe **values** **DCDC1**:
    **DCDC2**:
    **DCDC3**:
    **DCDC4**:
    **DCDC5**:
    **ALDO1**:
    **ALDO2**:
    **ALDO3**:
    **ALDO4**:
    **BLDO1**:
    **BLDO2**:
    **DLDO1**:
    **DLDO2**:
    **VBACKUP**:
    **CPULDO**:
    > C++ defination code: > ```cpp > enum class PowerChannel { > DCDC1, > DCDC2, > DCDC3, > DCDC4, > DCDC5, > ALDO1, > ALDO2, > ALDO3, > ALDO4, > BLDO1, > BLDO2, > DLDO1, > DLDO2, > VBACKUP, > CPULDO, > } > ``` ## Variable {#Variable} ## Function {#Function} ## Class {#Class} ### PMU {#PMU} PMU driver class > C++ defination code: > ```cpp > class PMU > ``` #### \\_\\_init\\_\\_ {#\\_\\_init\\_\\_} Construct a new PMU object, will open PMU. item description **type** func **param** **driver**: driver name, only support \"axp2101\".
    **i2c_bus**: i2c bus number. Automatically selects the on board pmu when 1 is passed in.
    **addr**: PMU i2c addr.
    **static** False > C++ defination code: > ```cpp > PMU(std::string driver \"axp2101\", int i2c_bus 1, int addr 0x34) > ``` #### poweroff {#poweroff} Poweroff immediately. item description **type** func **return** err::Err type, if init success, return err::ERR_NONE. **static** False > C++ defination code: > ```cpp > err::Err poweroff() > ``` #### is\\_bat\\_connect {#is\\_bat\\_connect} Is the battery connected. item description **type** func **return** bool type, if battery is connected, return true. **static** False > C++ defination code: > ```cpp > bool is_bat_connect() > ``` #### is\\_vbus\\_in {#is\\_vbus\\_in} Is the power adapter connected. item description **type** func **return** bool type, if power adapter is connected, return true. **static** False > C++ defination code: > ```cpp > bool is_vbus_in() > ``` #### is\\_charging {#is\\_charging} Is bat charging. item description **type** func **return** bool type, if bat is charging, return true. **static** False > C++ defination code: > ```cpp > bool is_charging() > ``` #### get\\_bat\\_percent {#get\\_bat\\_percent} Get the battery percentage. item description **type** func **return** int type, return battery percentage. **static** False > C++ defination code: > ```cpp > int get_bat_percent() > ``` #### get\\_charger\\_status {#get\\_charger\\_status} Get the battery charging status. item description **type** func **return** int type, return battery charging status. **static** False > C++ defination code: > ```cpp > ext_dev::pmu::ChargerStatus get_charger_status() > ``` #### get\\_vat\\_vol {#get\\_vat\\_vol} Get the battery voltage. item description **type** func **return** uint16_t type, return battery voltage. **static** False > C++ defination code: > ```cpp > uint16_t get_bat_vol() > ``` #### clean\\_irq {#clean\\_irq} Clear interrupt flag. item description **type** func **return** err::Err type, if clean success, return err::ERR_NONE. **static** False > C++ defination code: > ```cpp > err::Err clean_irq() > ``` #### set\\_bat\\_charging\\_cur {#set\\_bat\\_charging\\_cur} Set the battery charging current. item description **type** func **param** **current**: The current to be set.
    **return** err::Err type, if set success, return err::ERR_NONE. **static** False > C++ defination code: > ```cpp > err::Err set_bat_charging_cur(int current) > ``` #### get\\_bat\\_charging\\_cur {#get\\_bat\\_charging\\_cur} Get the battery charging current. item description **type** func **return** int, return the currently set charging current. **static** False > C++ defination code: > ```cpp > int get_bat_charging_cur() > ``` #### set\\_vol {#set\\_vol} Set the PMU channel voltage.\\nYou can retrieve the available channel from ext_dev.pmu.PowerChannel. item description **type** func **param** **voltage**: The voltage to be set.
    **return** int, return the channel voltage. **static** False > C++ defination code: > ```cpp > err::Err set_vol(ext_dev::pmu::PowerChannel channel, int voltage) > ``` #### get\\_vol {#get\\_vol} Get the PMU channel voltage.\\nYou can retrieve the available channel from ext_dev.pmu.PowerChannel. item description **type** func **return** err::Err type, if set success, return err::ERR_NONE. **static** False > C++ defination code: > ```cpp > int get_vol(ext_dev::pmu::PowerChannel channel) > ```"},"/maixcdk/api/maix/ext_dev/imu.html":{"title":"maix::ext_dev::imu","content":" title: maix::ext_dev::imu maix.ext_dev.imu module > This is `maix::ext_dev::imu` module of [MaixCDK](https://github.com/sipeed/MaixCDK). > All of these elements are in namespace `maix::ext_dev::imu`. > > For MaixCDK developer: DO NOT edit this doc file manually, this doc is auto generated! ## Module {#Module} No module ## Enum {#Enum} ### Mode {#Mode} imu mode item describe **values** **ACC_ONLY**:
    **GYRO_ONLY**:
    **DUAL**:
    > C++ defination code: > ```cpp > enum class Mode { > ACC_ONLY 0, > GYRO_ONLY, > DUAL > } > ``` ### AccScale {#AccScale} imu acc scale item describe **values** **ACC_SCALE_2G**:
    **ACC_SCALE_4G**:
    **ACC_SCALE_8G**:
    **ACC_SCALE_16G**:
    > C++ defination code: > ```cpp > enum class AccScale { > ACC_SCALE_2G 0, > ACC_SCALE_4G, > ACC_SCALE_8G, > ACC_SCALE_16G > } > ``` ### AccOdr {#AccOdr} imu acc output data rate item describe **values** **ACC_ODR_8000**: Accelerometer ODR set to 8000 Hz.
    **ACC_ODR_4000**: Accelerometer ODR set to 4000 Hz.
    **ACC_ODR_2000**: Accelerometer ODR set to 2000 Hz.
    **ACC_ODR_1000**: Accelerometer ODR set to 1000 Hz.
    **ACC_ODR_500**: Accelerometer ODR set to 500 Hz.
    **ACC_ODR_250**: Accelerometer ODR set to 250 Hz.
    **ACC_ODR_125**: Accelerometer ODR set to 125 Hz.
    **ACC_ODR_62_5**: Accelerometer ODR set to 62.5 Hz.
    **ACC_ODR_31_25**: Accelerometer ODR set to 31.25 Hz.
    **ACC_ODR_128**: Accelerometer ODR set to 128 Hz.
    **ACC_ODR_21**: Accelerometer ODR set to 21 Hz.
    **ACC_ODR_11**: Accelerometer ODR set to 11 Hz.
    **ACC_ODR_3**: Accelerometer ODR set to 3 Hz.
    > C++ defination code: > ```cpp > enum class AccOdr { > ACC_ODR_8000, // Accelerometer ODR set to 8000 Hz. > ACC_ODR_4000, // Accelerometer ODR set to 4000 Hz. > ACC_ODR_2000, // Accelerometer ODR set to 2000 Hz. > ACC_ODR_1000, // Accelerometer ODR set to 1000 Hz. > ACC_ODR_500, // Accelerometer ODR set to 500 Hz. > ACC_ODR_250, // Accelerometer ODR set to 250 Hz. > ACC_ODR_125, // Accelerometer ODR set to 125 Hz. > ACC_ODR_62_5, // Accelerometer ODR set to 62.5 Hz. > ACC_ODR_31_25, // Accelerometer ODR set to 31.25 Hz. > ACC_ODR_128 12, // Accelerometer ODR set to 128 Hz. > ACC_ODR_21, // Accelerometer ODR set to 21 Hz. > ACC_ODR_11, // Accelerometer ODR set to 11 Hz. > ACC_ODR_3, // Accelerometer ODR set to 3 Hz. > } > ``` ### GyroScale {#GyroScale} imu gyro scale item describe **values** **GYRO_SCALE_16DPS**: Gyroscope scale set to ±16 degrees per second.
    **GYRO_SCALE_32DPS**: Gyroscope scale set to ±32 degrees per second.
    **GYRO_SCALE_64DPS**: Gyroscope scale set to ±64 degrees per second.
    **GYRO_SCALE_128DPS**: Gyroscope scale set to ±128 degrees per second.
    **GYRO_SCALE_256DPS**: Gyroscope scale set to ±256 degrees per second.
    **GYRO_SCALE_512DPS**: Gyroscope scale set to ±512 degrees per second.
    **GYRO_SCALE_1024DPS**: Gyroscope scale set to ±1024 degrees per second.
    **GYRO_SCALE_2048DPS**: Gyroscope scale set to ±2048 degrees per second.
    > C++ defination code: > ```cpp > enum class GyroScale { > GYRO_SCALE_16DPS 0, // Gyroscope scale set to ±16 degrees per second. > GYRO_SCALE_32DPS, // Gyroscope scale set to ±32 degrees per second. > GYRO_SCALE_64DPS, // Gyroscope scale set to ±64 degrees per second. > GYRO_SCALE_128DPS, // Gyroscope scale set to ±128 degrees per second. > GYRO_SCALE_256DPS, // Gyroscope scale set to ±256 degrees per second. > GYRO_SCALE_512DPS, // Gyroscope scale set to ±512 degrees per second. > GYRO_SCALE_1024DPS, // Gyroscope scale set to ±1024 degrees per second. > GYRO_SCALE_2048DPS, // Gyroscope scale set to ±2048 degrees per second. > } > ``` ### GyroOdr {#GyroOdr} imu gyro output data rate item describe **values** **GYRO_ODR_8000**: Gyroscope ODR set to 8000 Hz.
    **GYRO_ODR_4000**: Gyroscope ODR set to 4000 Hz.
    **GYRO_ODR_2000**: Gyroscope ODR set to 2000 Hz.
    **GYRO_ODR_1000**: Gyroscope ODR set to 1000 Hz.
    **GYRO_ODR_500**: Gyroscope ODR set to 500 Hz.
    **GYRO_ODR_250**: Gyroscope ODR set to 250 Hz.
    **GYRO_ODR_125**: Gyroscope ODR set to 125 Hz.
    **GYRO_ODR_62_5**: Gyroscope ODR set to 62.5 Hz.
    **GYRO_ODR_31_25**: Gyroscope ODR set to 31.25 Hz.
    > C++ defination code: > ```cpp > enum class GyroOdr { > GYRO_ODR_8000, // Gyroscope ODR set to 8000 Hz. > GYRO_ODR_4000, // Gyroscope ODR set to 4000 Hz. > GYRO_ODR_2000, // Gyroscope ODR set to 2000 Hz. > GYRO_ODR_1000, // Gyroscope ODR set to 1000 Hz. > GYRO_ODR_500, // Gyroscope ODR set to 500 Hz. > GYRO_ODR_250, // Gyroscope ODR set to 250 Hz. > GYRO_ODR_125, // Gyroscope ODR set to 125 Hz. > GYRO_ODR_62_5, // Gyroscope ODR set to 62.5 Hz. > GYRO_ODR_31_25, // Gyroscope ODR set to 31.25 Hz. > } > ``` ## Variable {#Variable} ## Function {#Function} ## Class {#Class} ### IMU {#IMU} QMI8656 driver class > C++ defination code: > ```cpp > class IMU > ``` #### \\_\\_init\\_\\_ {#\\_\\_init\\_\\_} Construct a new IMU object, will open IMU item description **type** func **param** **driver**: driver name, only support \"qmi8656\"
    **i2c_bus**: i2c bus number. Automatically selects the on board imu when 1 is passed in.
    **addr**: IMU i2c addr.
    **freq**: IMU freq
    **mode**: IMU Mode: ACC_ONLY/GYRO_ONLY/DUAL
    **acc_scale**: acc scale, see @imu::AccScale
    **acc_odr**: acc output data rate, see @imu::AccOdr
    **gyro_scale**: gyro scale, see @imu::GyroScale
    **gyro_odr**: gyro output data rate, see @imu::GyroOdr
    **block**: block or non block, defalut is true
    **static** False > C++ defination code: > ```cpp > IMU(std::string driver, int i2c_bus 1, int addr 0x6B, int freq 400000, > maix::ext_dev::imu::Mode mode maix::ext_dev::imu::Mode::DUAL, > maix::ext_dev::imu::AccScale acc_scale maix::ext_dev::imu::AccScale::ACC_SCALE_2G, > maix::ext_dev::imu::AccOdr acc_odr maix::ext_dev::imu::AccOdr::ACC_ODR_8000, > maix::ext_dev::imu::GyroScale gyro_scale maix::ext_dev::imu::GyroScale::GYRO_SCALE_16DPS, > maix::ext_dev::imu::GyroOdr gyro_odr maix::ext_dev::imu::GyroOdr::GYRO_ODR_8000, > bool block true) > ``` #### read {#read} Read data from IMU. item description **type** func **return** list type. If only one of the outputs is initialized, only [x,y,z] of that output will be returned.
    If all outputs are initialized, [acc_x, acc_y, acc_z, gyro_x, gyro_y, gyro_z] is returned. **static** False > C++ defination code: > ```cpp > std::vector read() > ``` #### calculate\\_calibration {#calculate\\_calibration} Caculate calibration, save calibration data to /maixapp/shart/imu_calibration item description **type** func **param** **time_ms**: caculate max time, unit:ms
    **return** err::Err **static** False > C++ defination code: > ```cpp > err::Err calculate_calibration(uint64_t time_ms 30 * 1000) > ``` #### get\\_calibration {#get\\_calibration} Get calibration data item description **type** func **return** return an array, format is [acc_x_bias, acc_y_bias, acc_z_bias, gyro_x_bias, gyro_y_bias, gyro_z_bias]
    If the calibration file cannot be found, an empty array will be returned. **static** False > C++ defination code: > ```cpp > std::vector get_calibration() > ``` ### Gcsv {#Gcsv} Gcsv class > C++ defination code: > ```cpp > class Gcsv > ``` #### \\_\\_init\\_\\_ {#\\_\\_init\\_\\_ 2} Construct a new IMU object item description **type** func **static** False > C++ defination code: > ```cpp > Gcsv() > ``` #### open {#open} Open a file item description **type** func **param** **path**: the path where data will be saved
    **tscale**: time scale, default is 0.001
    **gscale**: gyroscope scale factor, default is 1, unit:g
    **ascale**: accelerometer scale factor, default is 1, unit:radians/second
    **mscale**: magnetometer scale factor, default is 1(unused)
    **version**: version number, default is \"1.3\"
    **id**: identifier for the IMU, default is \"imu\"
    **orientation**: sensor orientation, default is \"YxZ\"
    **return** error code **static** False > C++ defination code: > ```cpp > err::Err open(std::string path, double tscale 0.001, double gscale 1, double ascale 1, double mscale 1, std::string version \"1.3\", std::string id \"imu\", std::string orientation \"YxZ\") > ``` #### close {#close} Close file item description **type** func **return** error code **static** False > C++ defination code: > ```cpp > err::Err close() > ``` #### is\\_opened {#is\\_opened} Check if the object is already open item description **type** func **return** true, opened; false, not opened **static** False > C++ defination code: > ```cpp > bool is_opened() > ``` #### write {#write} Write imu data to gcsv file item description **type** func **param** **t**: Timestamp of the current data. The actual value is equal to t * tscale. unit:s
    **gyro**: Gyroscope data must be an array consisting of x, y, and z axis data. The actual value is equal to gyro * gscale. unit:g
    **acc**: Acceleration data must be an array consisting of x, y, and z axis data. The actual value is equal to acc * ascale.unit:radians/second
    **mag**: Magnetic data must be an array consisting of x, y, and z axis data. Currently not supported.
    **static** False > C++ defination code: > ```cpp > err::Err write(double timestamp, std::vector gyro, std::vector acc, std::vector mag std::vector()) > ```"},"/maixcdk/api/maix/log.html":{"title":"maix::log","content":" title: maix::log maix.log module > This is `maix::log` module of [MaixCDK](https://github.com/sipeed/MaixCDK). > All of these elements are in namespace `maix::log`. > > For MaixCDK developer: DO NOT edit this doc file manually, this doc is auto generated! ## Module {#Module} No module ## Enum {#Enum} ## Variable {#Variable} ## Function {#Function} ### error {#error} print error log item description **param** **fmt**: format string
    **...**: args
    > C++ defination code: > ```cpp > void error(const char *fmt, ...) > ``` ### warn {#warn} print warning log item description **param** **fmt**: format string
    **...**: args
    > C++ defination code: > ```cpp > void warn(const char *fmt, ...) > ``` ### info {#info} print info log item description **param** **fmt**: format string
    **...**: args
    > C++ defination code: > ```cpp > void info(const char *fmt, ...) > ``` ### debug {#debug} print debug log item description **param** **fmt**: format string
    **...**: args
    > C++ defination code: > ```cpp > void debug(const char *fmt, ...) > ``` ### error0 {#error0} print error log, but not add '\\n' at end item description **param** **fmt**: format string
    **...**: args
    > C++ defination code: > ```cpp > void error0(const char *fmt, ...) > ``` ### warn0 {#warn0} print warning log, but not add '\\n' at end item description **param** **fmt**: format string
    **...**: args
    > C++ defination code: > ```cpp > void warn0(const char *fmt, ...) > ``` ### info0 {#info0} print info log, but not add '\\n' at end item description **param** **fmt**: format string
    **...**: args
    > C++ defination code: > ```cpp > void info0(const char *fmt, ...) > ``` ### debug0 {#debug0} print debug log, but not add '\\n' at end item description **param** **fmt**: format string
    **...**: args
    > C++ defination code: > ```cpp > void debug0(const char *fmt, ...) > ``` ### print {#print} same as printf, but recommend use this function instead of printf\\nthis function will add prefix like \\\" [E] \\\" to log item description **param** **fmt**: format string
    **...**: args
    > C++ defination code: > ```cpp > void print(const char *fmt, ...) > ``` ## Class {#Class}"},"/maixcdk/api/maix/nn/F.html":{"title":"maix::nn::F","content":" title: maix::nn::F maix.nn.F module > This is `maix::nn::F` module of [MaixCDK](https://github.com/sipeed/MaixCDK). > All of these elements are in namespace `maix::nn::F`. > > For MaixCDK developer: DO NOT edit this doc file manually, this doc is auto generated! ## Module {#Module} No module ## Enum {#Enum} ## Variable {#Variable} ## Function {#Function} ### softmax {#softmax} Softmax, only support 1D tensor, multi dimension tensor will be treated as 1D tensor item description **param** **tensor**: input tensor
    **replace**: change input tensor data directly, if not, will create a new tensor
    **throw** If arg error, will raise err.Exception error **return** output tensor, if arg replace is true, return the arg tensor's address.
    If not replace, return a new object, so In C++, you should delete it manually in this case! > C++ defination code: > ```cpp > tensor::Tensor *softmax(tensor::Tensor *tensor, bool replace) > ``` ## Class {#Class}"},"/maixcdk/api/maix/camera.html":{"title":"maix::camera","content":" title: maix::camera maix.camera module, access camera device and get image from it > This is `maix::camera` module of [MaixCDK](https://github.com/sipeed/MaixCDK). > All of these elements are in namespace `maix::camera`. > > For MaixCDK developer: DO NOT edit this doc file manually, this doc is auto generated! ## Module {#Module} No module ## Enum {#Enum} ## Variable {#Variable} ## Function {#Function} ### list\\_devices {#list\\_devices} List all supported camera devices. item description **return** Returns the path to the camera device. > C++ defination code: > ```cpp > std::vector list_devices() > ``` ### set\\_regs\\_enable {#set\\_regs\\_enable} Enable set camera registers, default is false, if set to true, will not set camera registers, you can manually set registers by write_reg API. item description **param** **enable**: enable/disable set camera registers
    > C++ defination code: > ```cpp > void set_regs_enable(bool enable true) > ``` ### get\\_device\\_name {#get\\_device\\_name} Get device name. Most of the time, the returned name is the name of the sensor. > C++ defination code: > ```cpp > std::string get_device_name() > ``` ## Class {#Class} ### Camera {#Camera} Camera class > C++ defination code: > ```cpp > class Camera > ``` #### Camera {#Camera 2} Construct a new Camera object.\\nMaximum resolution support 2560x1440. item description **type** func **param** **width**: camera width, default is 1, means auto, mostly means max width of camera support
    **height**: camera height, default is 1, means auto, mostly means max height of camera support
    **format**: camera output format, default is image.Format.FMT_RGB888
    **device**: camera device path, you can get devices by list_devices method, by default(value is NULL(None in MaixPy)) means the first device
    **fps**: camera fps, default is 1, means auto, mostly means max fps of camera support
    **buff_num**: camera buffer number, default is 3, means 3 buffer, one used by user, one used for cache the next frame,
    more than one buffer will accelerate image read speed, but will cost more memory.
    **open**: If true, camera will automatically call open() after creation. default is true.
    **raw**: If true, you can use read_raw() to capture the raw image output from the sensor.
    **static** False > C++ defination code: > ```cpp > Camera(int width 1, int height 1, image::Format format image::FMT_RGB888, const char *device nullptr, double fps 1, int buff_num 3, bool open true, bool raw false) > ``` #### get\\_ch\\_nums {#get\\_ch\\_nums} Get the number of channels supported by the camera. item description **type** func **return** Returns the maximum number of channels. **static** False > C++ defination code: > ```cpp > int get_ch_nums() > ``` #### open {#open} Open camera and run item description **type** func **param** **width**: camera width, default is 1, means auto, mostly means max width of camera support
    **height**: camera height, default is 1, means auto, mostly means max height of camera support
    **format**: camera output format, default same as the constructor's format argument
    **fps**: camera fps, default is 1, means auto, mostly means max fps of camera support
    **buff_num**: camera buffer number, default is 3, means 3 buffer, one used by user, one used for cache the next frame,
    more than one buffer will accelerate image read speed, but will cost more memory.
    **return** error code, err::ERR_NONE means success, others means failed **static** False > C++ defination code: > ```cpp > err::Err open(int width 1, int height 1, image::Format format image::FMT_INVALID, double fps 1, int buff_num 1) > ``` #### read {#read} Get one frame image from camera buffer, must call open method before read.\\nIf open method not called, will call it automatically, if open failed, will throw exception!\\nSo call open method before read is recommended. item description **type** func **param** **buff**: buffer to store image data, if buff is nullptr, will alloc memory automatically.
    In MaixPy, default to None, you can create a image.Image object, then pass img.data() to buff.
    **block**: block read, default is true, means block util read image successfully,
    if set to false, will return nullptr if no image in buffer
    **block_ms**: block read timeout
    **return** image::Image object, if failed, return nullptr, you should delete if manually in C++ **static** False > C++ defination code: > ```cpp > image::Image *read(void *buff nullptr, size_t buff_size 0, bool block true, int block_ms 1) > ``` #### read\\_raw {#read\\_raw} Read the raw image and obtain the width, height, and format of the raw image through the returned Image object. item description **type** func **note** The raw image is in a Bayer format, and its width and height are affected by the driver. Modifying the size and format is generally not allowed. **return** image::Image object, if failed, return nullptr, you should delete if manually in C++ **static** False > C++ defination code: > ```cpp > image::Image *read_raw() > ``` #### clear\\_buff {#clear\\_buff} Clear buff to ensure the next read image is the latest image item description **type** func **static** False > C++ defination code: > ```cpp > void clear_buff() > ``` #### skip\\_frames {#skip\\_frames} Read some frames and drop, this is usually used avoid read not stable image when camera just opened. item description **type** func **param** **num**: number of frames to read and drop
    **static** False > C++ defination code: > ```cpp > void skip_frames(int num) > ``` #### close {#close} Close camera item description **type** func **static** False > C++ defination code: > ```cpp > void close() > ``` #### add\\_channel {#add\\_channel} Add a new channel and return a new Camera object, you can use close() to close this channel. item description **type** func **param** **width**: camera width, default is 1, means auto, mostly means max width of camera support
    **height**: camera height, default is 1, means auto, mostly means max height of camera support
    **format**: camera output format, default is RGB888
    **fps**: camera fps, default is 1, means auto, mostly means max fps of camera support
    **buff_num**: camera buffer number, default is 3, means 3 buffer, one used by user, one used for cache the next frame,
    more than one buffer will accelerate image read speed, but will cost more memory.
    **open**: If true, camera will automatically call open() after creation. default is true.
    **return** new Camera object **static** False > C++ defination code: > ```cpp > camera::Camera *add_channel(int width 1, int height 1, image::Format format image::FMT_RGB888, double fps 1, int buff_num 3, bool open true) > ``` #### is\\_opened {#is\\_opened} Check if camera is opened item description **type** func **return** true if camera is opened, false if not **static** False > C++ defination code: > ```cpp > bool is_opened() > ``` #### is\\_closed {#is\\_closed} check camera device is closed or not item description **type** func **return** closed or not, bool type **static** False > C++ defination code: > ```cpp > bool is_closed() > ``` #### width {#width} Get camera width item description **type** func **return** camera width **static** False > C++ defination code: > ```cpp > int width() > ``` #### height {#height} Get camera height item description **type** func **return** camera height **static** False > C++ defination code: > ```cpp > int height() > ``` #### fps {#fps} Get camera fps item description **type** func **return** camera fps **static** False > C++ defination code: > ```cpp > double fps() > ``` #### format {#format} Get camera output format item description **type** func **return** camera output format, image::Format object **static** False > C++ defination code: > ```cpp > image::Format format() > ``` #### buff\\_num {#buff\\_num} Get camera buffer number item description **type** func **return** camera buffer number **static** False > C++ defination code: > ```cpp > int buff_num() > ``` #### hmirror {#hmirror} Set/Get camera horizontal mirror item description **type** func **return** camera horizontal mirror **static** False > C++ defination code: > ```cpp > int hmirror(int value 1) > ``` #### vflip {#vflip} Set/Get camera vertical flip item description **type** func **return** camera vertical flip **static** False > C++ defination code: > ```cpp > int vflip(int value 1) > ``` #### device {#device} Get camera device path item description **type** func **return** camera device path **static** False > C++ defination code: > ```cpp > std::string device() > ``` #### write\\_reg {#write\\_reg} Write camera register item description **type** func **param** **addr**: register address
    **data**: register data
    **bit_width**: register data bit width, default is 8
    **return** error code, err::ERR_NONE means success, others means failed **static** False > C++ defination code: > ```cpp > err::Err write_reg(int addr, int data, int bit_width 8) > ``` #### read\\_reg {#read\\_reg} Read camera register item description **type** func **param** **addr**: register address
    **bit_width**: register data bit width, default is 8
    **return** register data, 1 means failed **static** False > C++ defination code: > ```cpp > int read_reg(int addr, int bit_width 8) > ``` #### show\\_colorbar {#show\\_colorbar} Camera output color bar image for test item description **type** func **param** **enable**: enable/disable color bar
    **return** error code, err::ERR_NONE means success, others means failed **static** False > C++ defination code: > ```cpp > err::Err show_colorbar(bool enable) > ``` #### get\\_channel {#get\\_channel} Get channel of camera item description **type** func **return** channel number **static** False > C++ defination code: > ```cpp > int get_channel() > ``` #### set\\_resolution {#set\\_resolution} Set camera resolution item description **type** func **param** **width**: new width
    **height**: new height
    **return** error code, err::ERR_NONE means success, others means failed **static** False > C++ defination code: > ```cpp > err::Err set_resolution(int width, int height) > ``` #### set\\_fps {#set\\_fps} Set camera fps item description **type** func **param** **fps**: new fps
    **return** error code, err::ERR_NONE means success, others means failed **static** False > C++ defination code: > ```cpp > err::Err set_fps(double fps) > ``` #### exposure {#exposure} Set/Get camera exposure item description **type** func **attention** This method will affect the isp and thus the image, so please be careful with it. **param** **value**: exposure time. unit: us
    If value 1, return exposure time.
    If value ! 0, set and return exposure time.
    **return** camera exposure time **static** False > C++ defination code: > ```cpp > int exposure(int value 1) > ``` #### gain {#gain} Set/Get camera gain item description **type** func **attention** This method will affect the isp and thus the image, so please be careful with it. **param** **value**: camera gain.
    If value 1, returns camera gain.
    If value ! 0, set and return camera gain.
    **return** camera gain **static** False > C++ defination code: > ```cpp > int gain(int value 1) > ``` #### luma {#luma} Set/Get camera luma item description **type** func **attention** This method will affect the isp and thus the image, so please be careful with it. **param** **value**: luma value, range is [0, 100]
    If value 1, returns luma value.
    If value ! 0, set and return luma value.
    **return** returns luma value **static** False > C++ defination code: > ```cpp > int luma(int value 1) > ``` #### constrast {#constrast} Set/Get camera constrast item description **type** func **attention** This method will affect the isp and thus the image, so please be careful with it. **param** **value**: constrast value, range is [0, 100]
    If value 1, returns constrast value.
    If value ! 0, set and return constrast value.
    **return** returns constrast value **static** False > C++ defination code: > ```cpp > int constrast(int value 1) > ``` #### saturation {#saturation} Set/Get camera saturation item description **type** func **attention** This method will affect the isp and thus the image, so please be careful with it. **param** **value**: saturation value, range is [0, 100]
    If value 1, returns saturation value.
    If value ! 0, set and return saturation value.
    **return** returns saturation value **static** False > C++ defination code: > ```cpp > int saturation(int value 1) > ``` #### awb\\_mode {#awb\\_mode} Set/Get white balance mode (deprecated interface) item description **type** func **attention** This method will affect the isp and thus the image, so please be careful with it.
    This interface may be deprecated in the future, and there may be incompatibilities in the definition of the parameters of the new interface **param** **value**: value 0, means set white balance to auto mode, value 1, means set white balance to manual mode, default is auto mode.
    **return** returns awb mode **static** False > C++ defination code: > ```cpp > int awb_mode(int value 1) > ``` #### set\\_awb {#set\\_awb} Set/Get white balance mode item description **type** func **attention** This method will affect the isp and thus the image, so please be careful with it. **param** **value**: value 0, means set white balance to manual mode, value 1, means set white balance to auto mode, default is auto mode.
    **return** returns awb mode **static** False > C++ defination code: > ```cpp > int set_awb(int mode 1) > ``` #### exp\\_mode {#exp\\_mode} Set/Get exposure mode (deprecated interface) item description **type** func **attention** This method will affect the isp and thus the image, so please be careful with it.
    This interface may be deprecated in the future, and there may be incompatibilities in the definition of the parameters of the new interface **param** **value**: value 0, means set exposure to auto mode, value 1, means set exposure to manual mode, default is auto mode.
    **return** returns exposure mode **static** False > C++ defination code: > ```cpp > int exp_mode(int value 1) > ``` #### set\\_windowing {#set\\_windowing} Set window size of camera item description **type** func **param** **roi**: Support two input formats, [x,y,w,h] set the coordinates and size of the window;
    [w,h] set the size of the window, when the window is centred.
    **return** error code **static** False > C++ defination code: > ```cpp > err::Err set_windowing(std::vector roi) > ```"},"/maixcdk/api/index.html":{"title":"MaixCDK API -- Maix AI machine vision platform C/C++ API","content":" title: MaixCDK API Maix AI machine vision platform C/C++ API > For MaixCDK developer: This API documentation is generated from the source code, DO NOT edit this file manually! MaixCDK API documentation, modules: module brief [maix::image](./image/maix.html) maix.image module, image related definition and functions [maix::audio](./audio/maix.html) maix.audio module [maix::tracker](./tracker/maix.html) maix.tracker module [maix::http](./http/maix.html) maix.http module [maix::camera](./camera/maix.html) maix.camera module, access camera device and get image from it [maix::rtsp](./rtsp/maix.html) maix.rtsp module [maix::rtmp](./rtmp/maix.html) maix.rtmp module [maix::touchscreen](./touchscreen/maix.html) maix.touchscreen module [maix::video](./video/maix.html) maix.video module [maix::display](./display/maix.html) maix.display module, control display device and show image on it [maix::uvc](./uvc/maix.html) maix.uvc module [maix::network](./network/maix.html) maix.network module [maix::comm](./comm/maix.html) maix.comm module [maix::modbus](./modbus/maix.html) maix.modbus module [maix::fs](./fs/maix.html) maix.fs module [maix::Bytes](./Bytes/maix.html) Bytes type for Python bytes compatibility. [maix::app](./app/maix.html) maix.app module [maix::protocol](./protocol/maix.html) maix.protocol module [maix::time](./time/maix.html) maix.time module [maix::err](./err/maix.html) maix.err module [maix::example](./example/maix.html) example module, this will be maix.example module in MaixPy, maix::example namespace in MaixCDK [maix::util](./util/maix.html) maix.util module [maix::thread](./thread/maix.html) maix.thread module [maix::sys](./sys/maix.html) maix.sys module [maix::log](./log/maix.html) maix.log module [maix::tensor](./tensor/maix.html) maix.tensor module [maix::i18n](./i18n/maix.html) maix.i18n module [maix::peripheral](./peripheral/maix.html) Chip's peripheral driver [maix::ext_dev](./ext_dev/maix.html) maix.ext_dev module [maix::nn](./nn/maix.html) maix.nn module "},"/maixcdk/api/maix/peripheral.html":{"title":"maix::peripheral","content":" title: maix::peripheral Chip's peripheral driver > This is `maix::peripheral` module of [MaixCDK](https://github.com/sipeed/MaixCDK). > All of these elements are in namespace `maix::peripheral`. > > For MaixCDK developer: DO NOT edit this doc file manually, this doc is auto generated! ## Module {#Module} module brief [key](./peripheral/key.html) maix.peripheral.key module [i2c](./peripheral/i2c.html) maix.peripheral.i2c module [spi](./peripheral/spi.html) maix.peripheral.spi module [pwm](./peripheral/pwm.html) maix.peripheral.pwm module [wdt](./peripheral/wdt.html) maix.peripheral.wdt module [adc](./peripheral/adc.html) maix.peripheral.adc module [pinmap](./peripheral/pinmap.html) maix.peripheral.pinmap module [uart](./peripheral/uart.html) maix uart peripheral driver [gpio](./peripheral/gpio.html) maix.peripheral.gpio module [hid](./peripheral/hid.html) maix.peripheral.hid module [timer](./peripheral/timer.html) maix.peripheral.timer module ## Enum {#Enum} ## Variable {#Variable} ## Function {#Function} ## Class {#Class}"},"/maixcdk/api/maix/tracker.html":{"title":"maix::tracker","content":" title: maix::tracker maix.tracker module > This is `maix::tracker` module of [MaixCDK](https://github.com/sipeed/MaixCDK). > All of these elements are in namespace `maix::tracker`. > > For MaixCDK developer: DO NOT edit this doc file manually, this doc is auto generated! ## Module {#Module} No module ## Enum {#Enum} ## Variable {#Variable} ## Function {#Function} ## Class {#Class} ### Object {#Object} tracker.Object class > C++ defination code: > ```cpp > class Object > ``` #### Object {#Object 2} tracker.Object class constructor item description **type** func **static** False > C++ defination code: > ```cpp > Object(const int &x, const int &y, const int &w, const int &h, const int &class_id, const float &score) > ``` #### x {#x} position x attribute. item description **type** var **static** False **readonly** False > C++ defination code: > ```cpp > int x > ``` #### y {#y} position y attribute. item description **type** var **static** False **readonly** False > C++ defination code: > ```cpp > int y > ``` #### w {#w} position rectangle width. item description **type** var **static** False **readonly** False > C++ defination code: > ```cpp > int w > ``` #### h {#h} position rectangle height. item description **type** var **static** False **readonly** False > C++ defination code: > ```cpp > int h > ``` #### class\\_id {#class\\_id} object class id, int type. item description **type** var **static** False **readonly** False > C++ defination code: > ```cpp > int class_id > ``` #### score {#score} object score(prob). item description **type** var **static** False **readonly** False > C++ defination code: > ```cpp > float score > ``` ### Track {#Track} tracker.Track class > C++ defination code: > ```cpp > class Track > ``` #### Track {#Track 2} tracker.Track class constructor item description **type** func **static** False > C++ defination code: > ```cpp > Track(const size_t &id, const float &score, const bool &lost, const size_t &start_frame_id, const size_t &frame_id) > ``` #### Track (overload 1) {#Track (overload 1)} tracker.Track class constructor item description **type** func **static** False > C++ defination code: > ```cpp > Track() > ``` #### id {#id} track id. item description **type** var **static** False **readonly** False > C++ defination code: > ```cpp > size_t id > ``` #### score {#score 2} track score(prob). item description **type** var **static** False **readonly** False > C++ defination code: > ```cpp > float score > ``` #### lost {#lost} whether this track lost. item description **type** var **static** False **readonly** False > C++ defination code: > ```cpp > bool lost > ``` #### start\\_frame\\_id {#start\\_frame\\_id} track start frame id. item description **type** var **static** False **readonly** False > C++ defination code: > ```cpp > size_t start_frame_id > ``` #### frame\\_id {#frame\\_id} track current frame id. item description **type** var **static** False **readonly** False > C++ defination code: > ```cpp > size_t frame_id > ``` #### history {#history} track position history, the last one is latest position. item description **type** var **static** False **readonly** False > C++ defination code: > ```cpp > std::deque history > ``` ### ByteTracker {#ByteTracker} tracker.ByteTracker class > C++ defination code: > ```cpp > class ByteTracker > ``` #### ByteTracker {#ByteTracker 2} tracker.ByteTracker class constructor item description **type** func **param** **max_lost_buff_num**: the frames for keep lost tracks.
    **track_thresh**: tracking confidence threshold.
    **high_thresh**: threshold to add to new track.
    **match_thresh**: matching threshold for tracking, e.g. one object in two frame iou < match_thresh we think they are the same obj.
    **max_history**: max tack's position history length.
    **static** False > C++ defination code: > ```cpp > ByteTracker(const int &max_lost_buff_num 60, > const float &track_thresh 0.5, > const float &high_thresh 0.6, > const float &match_thresh 0.8, > const int &max_history 20) > ``` #### update {#update} update tracks according to current detected objects. item description **type** func **static** False > C++ defination code: > ```cpp > std::vector update(const std::vector &objs) > ```"},"/maixcdk/api/maix/util.html":{"title":"maix::util","content":" title: maix::util maix.util module > This is `maix::util` module of [MaixCDK](https://github.com/sipeed/MaixCDK). > All of these elements are in namespace `maix::util`. > > For MaixCDK developer: DO NOT edit this doc file manually, this doc is auto generated! ## Module {#Module} No module ## Enum {#Enum} ## Variable {#Variable} ## Function {#Function} ### disable\\_kernel\\_debug {#disable\\_kernel\\_debug} disable the kernel debug > C++ defination code: > ```cpp > void disable_kernel_debug() > ``` ### enable\\_kernel\\_debug {#enable\\_kernel\\_debug} disable the kernel debug > C++ defination code: > ```cpp > void enable_kernel_debug() > ``` ### register\\_exit\\_function {#register\\_exit\\_function} register exit function > C++ defination code: > ```cpp > void register_exit_function(void (*process)(void)) > ``` ### do\\_exit\\_function {#do\\_exit\\_function} exec all of exit function > C++ defination code: > ```cpp > void do_exit_function() > ``` ### register\\_atexit {#register\\_atexit} Registering default processes that need to be executed on exit > C++ defination code: > ```cpp > void register_atexit() > ``` ## Class {#Class}"},"/maixcdk/api/maix/tensor.html":{"title":"maix::tensor","content":" title: maix::tensor maix.tensor module > This is `maix::tensor` module of [MaixCDK](https://github.com/sipeed/MaixCDK). > All of these elements are in namespace `maix::tensor`. > > For MaixCDK developer: DO NOT edit this doc file manually, this doc is auto generated! ## Module {#Module} No module ## Enum {#Enum} ### DType {#DType} Tensor data types item describe **values** **UINT8**:
    **INT8**:
    **UINT16**:
    **INT16**:
    **UINT32**:
    **INT32**:
    **FLOAT16**:
    **FLOAT32**:
    **FLOAT64**:
    **BOOL**:
    **DTYPE_MAX**:
    > C++ defination code: > ```cpp > enum DType > { > UINT8 0, > INT8, > UINT16, > INT16, > UINT32, > INT32, > FLOAT16, > FLOAT32, > FLOAT64, > BOOL, > // STRING, > // OBJECT, > DTYPE_MAX > } > ``` ## Variable {#Variable} ### dtype\\_size {#dtype\\_size} Tensor data type size in bytes item description **attention** It's a copy of this variable in MaixPy,
    so change it in C++ (e.g. update var in hello function) will not take effect the var inMaixPy.
    So we add const for this var to avoid this mistake. **value** **{
    1, // UINT8
    1, // INT8
    2, // UINT16
    2, // INT16
    4, // UINT32
    4, // INT32
    2, // FLOAT16
    4, // FLOAT32
    8, // FLOAT64
    1, // BOOL
    // 1, // STRING
    // 1, // OBJECT
    0
    }** **readonly** True > C++ defination code: > ```cpp > const std::vector dtype_size { > 1, // UINT8 > 1, // INT8 > 2, // UINT16 > 2, // INT16 > 4, // UINT32 > 4, // INT32 > 2, // FLOAT16 > 4, // FLOAT32 > 8, // FLOAT64 > 1, // BOOL > // 1, // STRING > // 1, // OBJECT > 0 > } > ``` ### dtype\\_name {#dtype\\_name} Tensor data type name item description **value** **{
    \"uint8\",
    \"int8\",
    \"uint16\",
    \"int16\",
    \"uint32\",
    \"int32\",
    \"float16\",
    \"float32\",
    \"float64\",
    \"bool\",
    // \"string\",
    // \"object\",
    \"invalid\"
    }** **readonly** True > C++ defination code: > ```cpp > const std::vector dtype_name { > \"uint8\", > \"int8\", > \"uint16\", > \"int16\", > \"uint32\", > \"int32\", > \"float16\", > \"float32\", > \"float64\", > \"bool\", > // \"string\", > // \"object\", > \"invalid\" > } > ``` ## Function {#Function} ## Class {#Class} ### Tensor {#Tensor} Tensor class > C++ defination code: > ```cpp > class Tensor > ``` #### \\_\\_init\\_\\_ {#\\_\\_init\\_\\_} Tensor constructor item description **type** func **param** **shape**: tensor shape, a int list
    **dtype**: tensor element data type, see DType of this module
    **static** False > C++ defination code: > ```cpp > Tensor(std::vector shape, tensor::DType dtype) > ``` #### Tensor {#Tensor 2} Tensor constructor item description **type** func **param** **shape**: tensor shape, a int list
    **dtype**: tensor element data type, see DType of this module
    **data**: pointer to data content, can be nullptr, it will automatically alloc memory
    and detroy it when this object is destroyed
    **copy**: defalt true to alloc new memory and copy from data.
    **static** False > C++ defination code: > ```cpp > Tensor(std::vector shape, tensor::DType dtype, void *data, bool copy true) > ``` #### to\\_str {#to\\_str} To string item description **type** func **static** False > C++ defination code: > ```cpp > std::string to_str() > ``` #### \\_\\_str\\_\\_ {#\\_\\_str\\_\\_} To string item description **type** func **static** False > C++ defination code: > ```cpp > std::string __str__() > ``` #### shape {#shape} get tensor shape item description **type** func **return** tensor shape, a int list **static** False > C++ defination code: > ```cpp > std::vector shape() > ``` #### expand\\_dims {#expand\\_dims} expand tensor shape item description **type** func **param** **axis**: axis to expand
    **static** False > C++ defination code: > ```cpp > void expand_dims(int axis) > ``` #### reshape {#reshape} reshape tensor shape, if size not match, it will throw an err::Exception item description **type** func **param** **shape**: new shape
    **static** False > C++ defination code: > ```cpp > void reshape(std::vector shape) > ``` #### flatten {#flatten} Flatten tensor shape to 1D item description **type** func **static** False > C++ defination code: > ```cpp > void flatten() > ``` #### dtype {#dtype 2} get tensor data type item description **type** func **return** tensor data type, see DType of this module **static** False > C++ defination code: > ```cpp > tensor::DType dtype() > ``` #### to\\_float\\_list {#to\\_float\\_list} get tensor data and return a list item description **type** func **return** list type data **static** False > C++ defination code: > ```cpp > std::valarray* to_float_list() > ``` #### argmax {#argmax} argmax of tensor item description **type** func **param** **axis**: By default, the index is into the flattened array, otherwise along the specified axis., wrong axis will throw an err::Exception
    **return** argmax result, you need to delete it after use in C++. **static** False > C++ defination code: > ```cpp > tensor::Tensor *argmax(int axis 0xffff) > ``` #### argmax1 {#argmax1} argmax1, flattened data max index item description **type** func **return** argmax result, int type **static** False > C++ defination code: > ```cpp > int argmax1() > ``` ### Tensors {#Tensors} Tensors > C++ defination code: > ```cpp > class Tensors > ``` #### Tensors {#Tensors 2} Constructor of Tensors item description **type** func **static** False > C++ defination code: > ```cpp > Tensors() > ``` #### add\\_tensor {#add\\_tensor} Add tensor item description **type** func **static** False > C++ defination code: > ```cpp > void add_tensor(const std::string &key, tensor::Tensor *tensor, bool copy, bool auto_delete) > ``` #### rm\\_tensor {#rm\\_tensor} Remove tensor item description **type** func **static** False > C++ defination code: > ```cpp > void rm_tensor(const std::string &key) > ``` #### clear {#clear} Clear tensors item description **type** func **static** False > C++ defination code: > ```cpp > void clear() > ``` #### begin {#begin} Begin of tensors item description **type** func **static** False > C++ defination code: > ```cpp > std::map::iterator begin() > ``` #### end {#end} End of tensors item description **type** func **static** False > C++ defination code: > ```cpp > std::map::iterator end() > ``` #### next {#next} __next__ item description **type** func **static** False > C++ defination code: > ```cpp > std::map::iterator next(std::map::iterator it) > ``` #### get\\_tensor {#get\\_tensor} Get tensor by key item description **type** func **static** False > C++ defination code: > ```cpp > tensor::Tensor &get_tensor(const std::string &key) > ``` #### [] {#[]} Operator [] item description **type** func **static** False > C++ defination code: > ```cpp > tensor::Tensor &operator[](const std::string &key) > ``` #### size {#size} Size item description **type** func **static** False > C++ defination code: > ```cpp > size_t size() > ``` #### keys {#keys} Get names item description **type** func **static** False > C++ defination code: > ```cpp > std::vector keys() > ``` #### tensors {#tensors 3} Tensors data, dict type item description **type** var **static** False **readonly** False > C++ defination code: > ```cpp > std::map tensors > ```"},"/maixcdk/api/maix/touchscreen.html":{"title":"maix::touchscreen","content":" title: maix::touchscreen maix.touchscreen module > This is `maix::touchscreen` module of [MaixCDK](https://github.com/sipeed/MaixCDK). > All of these elements are in namespace `maix::touchscreen`. > > For MaixCDK developer: DO NOT edit this doc file manually, this doc is auto generated! ## Module {#Module} No module ## Enum {#Enum} ## Variable {#Variable} ## Function {#Function} ## Class {#Class} ### TouchScreen {#TouchScreen} TouchScreen class > C++ defination code: > ```cpp > class TouchScreen > ``` #### TouchScreen {#TouchScreen 2} Construct a new TouchScreen object item description **type** func **param** **device**: touchscreen device path, you can get devices by list_devices method, by default(value is NULL(None in MaixPy)) means the first device
    **open**: If true, touchscreen will automatically call open() after creation. default is true.
    **static** False > C++ defination code: > ```cpp > TouchScreen(const std::string &device \"\", bool open true) > ``` #### open {#open} open touchscreen device item description **type** func **return** error code, err::ERR_NONE means success, others means failed **static** False > C++ defination code: > ```cpp > err::Err open() > ``` #### close {#close} close touchscreen device item description **type** func **return** error code, err::ERR_NONE means success, others means failed **static** False > C++ defination code: > ```cpp > err::Err close() > ``` #### read {#read} read touchscreen device. item description **type** func **attention** This method will discard same event in buffer, that is:
    if too many move event in buffer when call this method, it will only return the last one,
    and if read pressed or released event, it will return immediately. **param** **x**: x coordinate
    **y**: y coordinate
    **pressed**: pressed state
    **return** error code, err::ERR_NONE means success, others means failed, if no event return err::ERR_NOT_READY **static** False > C++ defination code: > ```cpp > err::Err read(int &x, int &y, bool &pressed) > ``` #### read (overload 1) {#read (overload 1)} read touchscreen device item description **type** func **attention** This method will discard same event in buffer, that is:
    if too many move event in buffer when call this method, it will only return the last one,
    and if read pressed or released event, it will return immediately. **return** Returns a list include x, y, pressed state **static** False > C++ defination code: > ```cpp > std::vector read() > ``` #### read (overload 2) {#read (overload 2)} read touchscreen device item description **type** func **attention** This method will return immediately if have event, so it's better to use available() to check if have more event in buffer,
    or too much event in buffer when your program call this read() interval is too long will make your program slow. **param** **x**: x coordinate
    **y**: y coordinate
    **pressed**: pressed state
    **return** error code, err::ERR_NONE means success, others means failed, if no event return err::ERR_NOT_READY **static** False > C++ defination code: > ```cpp > err::Err read0(int &x, int &y, bool &pressed) > ``` #### read (overload 3) {#read (overload 3)} read touchscreen device item description **type** func **attention** This method will return immediately if have event, so it's better to use available() to check if have more event in buffer,
    or too much event in buffer when your program call this read() interval is too long will make your program slow. **return** Returns a list include x, y, pressed state **static** False > C++ defination code: > ```cpp > std::vector read0() > ``` #### available {#available} If we need to read from touchscreen, for event driven touchscreen means have event or not item description **type** func **param** **timeout**: 1 means block, 0 means no block, >0 means timeout, default is 0, unit is ms.
    **return** true if need to read(have event), false if not **static** False > C++ defination code: > ```cpp > bool available(int timeout 0) > ``` #### is\\_opened {#is\\_opened} Check if touchscreen is opened item description **type** func **return** true if touchscreen is opened, false if not **static** False > C++ defination code: > ```cpp > bool is_opened() > ```"},"/maixcdk/api/maix/example.html":{"title":"maix::example","content":" title: maix::example example module, this will be maix.example module in MaixPy, maix::example namespace in MaixCDK > This is `maix::example` module of [MaixCDK](https://github.com/sipeed/MaixCDK). > All of these elements are in namespace `maix::example`. > > For MaixCDK developer: DO NOT edit this doc file manually, this doc is auto generated! ## Module {#Module} No module ## Enum {#Enum} ### Kind {#Kind} Example enum(not recommend! See Kind2) item describe **values** **KIND_NONE**: Kind none, value always 0, other enum value will auto increase
    **KIND_DOG**: Kind dog
    **KIND_CAT**: Kind cat, value is auto generated according to KING_DOG
    **KIND_BIRD**:
    **KIND_MAX**: Max Kind quantity
    You can get max Kind value by KIND_MAX 1
    > C++ defination code: > ```cpp > enum Kind > { > KIND_NONE 0, /** Kind none, value always 0, other enum value will auto increase */ > KIND_DOG, /** Kind dog*/ > KIND_CAT, // Kind cat, value is auto generated according to KING_DOG > KIND_BIRD, > KIND_MAX /* Max Kind quantity, > You can get max Kind value by KIND_MAX 1 > */ > } > ``` ### Kind2 {#Kind2} Example enum class(recommend!) item describe **values** **NONE**: Kind none, value always 0, other enum value will auto increase
    **DOG**: Kind dog
    **CAT**: Kind cat, value is auto generated according to KING_DOG
    **BIRD**:
    **MAX**: Max Kind quantity
    You can get max Kind value by KIND_MAX 1
    > C++ defination code: > ```cpp > enum class Kind2 > { > NONE 0, /** Kind none, value always 0, other enum value will auto increase */ > DOG, /** Kind dog*/ > CAT, // Kind cat, value is auto generated according to KING_DOG > BIRD, > MAX /* Max Kind quantity, > You can get max Kind value by KIND_MAX 1 > */ > } > ``` ## Variable {#Variable} ### var1 {#var1} Example module variable item description **attention** It's a copy of this variable in MaixPy,
    so change it in C++ (e.g. update var in hello function) will not take effect the var inMaixPy.
    So we add const for this var to avoid this mistake. **value** **\"Sipeed\"** **readonly** True > C++ defination code: > ```cpp > const std::string var1 \"Sipeed\" > ``` ### list\\_var {#list\\_var} Tensor data type size in bytes item description **attention** **1**. DO NOT use C/C++ array directly for python API, the python wrapper not support it.
    Use std::vector instead.
    **2**. It's a copy of this variable in MaixPy,
    so change it in C++ (e.g. update var in hello function) will not take effect the var inMaixPy.
    So we add const for this var to avoid this mistake.
    **value** **{
    0, 1, 2, 3, 4, 5, 6, 7, 8, 9}** **readonly** True > C++ defination code: > ```cpp > const std::vector list_var { > 0, 1, 2, 3, 4, 5, 6, 7, 8, 9} > ``` ### test\\_var {#test\\_var} Example module variable test_var item description **attention** It's a copy of this variable in MaixPy, so if you change it in C++, it will not take effect in MaixPy.
    And change it in MaixPy will not take effect in C++ as well !!!
    If you want to use vars shared between C++ and MaixPy, you can create a class and use its member. **value** **100** **readonly** False > C++ defination code: > ```cpp > int test_var 100 > ``` ## Function {#Function} ### hello {#hello} say hello to someone item description **param** **name**: direction [in], name of someone, string type
    **return** string type, content is hello + name > C++ defination code: > ```cpp > std::string hello(std::string name) > ``` ### hello\\_maixcdk {#hello\\_maixcdk} This is an API only for MaixCDK, MaixPy can't use it.\\nOnly item with `maixcdk` or `maixpy` keyword will be exported as MaixCDK API. > C++ defination code: > ```cpp > std::string hello_maixcdk(std::string name) > ``` ### change\\_arg\\_name {#change\\_arg\\_name} Change arg name example item description **param** **e**: Example object
    **return** same as arg > C++ defination code: > ```cpp > example::Example *change_arg_name(example::Example *e) > ``` ### change\\_arg\\_name2 {#change\\_arg\\_name2} Change arg name example item description **param** **e**: Example object
    > C++ defination code: > ```cpp > void change_arg_name2(example::Example &e) > ``` ## Class {#Class} ### Test {#Test} Test class > C++ defination code: > ```cpp > class Test > ``` #### Test {#Test 2} Test constructor item description **type** func **static** False > C++ defination code: > ```cpp > Test() > ``` ### Example {#Example} Example class\\nthis class will be export to MaixPy as maix.example.Example > C++ defination code: > ```cpp > class Example > ``` #### Example {#Example 2} Example constructor\\nthis constructor will be export to MaixPy as maix.example.Example.__init__ item description **type** func **param** **name**: direction [in], name of Example, string type
    **age**: direction [in], age of Example, int type, default is 18, value range is [0, 100]
    **attention** to make auto generate code work, param Kind should with full namespace name `example::Kind` instead of `Kind`,
    namespace `maix` can be ignored. **static** False > C++ defination code: > ```cpp > Example(std::string &name, int age 18, example::Kind pet example::KIND_NONE) > ``` #### get\\_name {#get\\_name} get name of Example\\nyou can also get name by property `name`. item description **type** func **return** name of Example, string type **static** False > C++ defination code: > ```cpp > std::string get_name() > ``` #### get\\_age {#get\\_age} get age of Example item description **type** func **return** age of Example, int type, value range is [0, 100] **static** False > C++ defination code: > ```cpp > int get_age() > ``` #### set\\_name {#set\\_name} set name of Example item description **type** func **param** **name**: name of Example, string type
    **static** False > C++ defination code: > ```cpp > void set_name(std::string name) > ``` #### set\\_age {#set\\_age} set age of Example item description **type** func **param** **age**: age of Example, int type, value range is [0, 100]
    **static** False > C++ defination code: > ```cpp > void set_age(int age) > ``` #### set\\_pet {#set\\_pet} Example enum member item description **type** func **attention** **static** False > C++ defination code: > ```cpp > void set_pet(example::Kind pet) > ``` #### get\\_pet {#get\\_pet} Example enum member item description **type** func **static** False > C++ defination code: > ```cpp > example::Kind get_pet() > ``` #### get\\_list {#get\\_list} get list example item description **type** func **param** **in**: direction [in], input list, items are int type.
    In MaixPy, you can pass list or tuple to this API
    **return** list, items are int type, content is [1, 2, 3] + in. Alloc item, del in MaixPy will auto free memory. **static** False > C++ defination code: > ```cpp > std::vector *get_list(std::vector in) > ``` #### get\\_dict {#get\\_dict} Example dict API item description **type** func **param** **in**: direction [in], input dict, key is string type, value is int type.
    In MaixPy, you can pass `dict` to this API
    **return** dict, key is string type, value is int type, content is {\"a\": 1} + in
    In MaixPy, return type is `dict` object **static** False > C++ defination code: > ```cpp > std::map get_dict(std::map &in) > ``` #### hello {#hello 2} say hello to someone item description **type** func **param** **name**: name of someone, string type
    **return** string type, content is Example::hello_str + name **static** True > C++ defination code: > ```cpp > static std::string hello(std::string name) > ``` #### hello\\_bytes {#hello\\_bytes} param is bytes example item description **type** func **param** **bytes**: bytes type param
    **return** bytes type, return value is bytes changed value **static** True > C++ defination code: > ```cpp > static Bytes *hello_bytes(Bytes &bytes) > ``` #### callback {#callback} Callback example item description **type** func **param** **cb**: callback function, param is two int type, return is int type
    **return** int type, return value is cb's return value. **static** True > C++ defination code: > ```cpp > static int callback(std::function cb) > ``` #### callback2 {#callback2} Callback example item description **type** func **param** **cb**: callback function, param is a int list type and int type, return is int type
    **return** int type, return value is cb's return value. **static** True > C++ defination code: > ```cpp > static int callback2(std::function, int)> cb) > ``` #### hello\\_dict {#hello\\_dict} Dict param example item description **type** func **param** **dict**: dict type param, key is string type, value is int type
    **static** True > C++ defination code: > ```cpp > static std::map *hello_dict(std::map *dict) > ``` #### name {#name} name member of Example item description **type** var **static** False **readonly** False > C++ defination code: > ```cpp > std::string name > ``` #### age {#age} age member of Example, value range should be [0, 100] item description **type** var **static** False **readonly** False > C++ defination code: > ```cpp > int age > ``` #### hello\\_str {#hello\\_str} hello_str member of Example, default value is \\\"hello \\\" item description **type** var **static** True **readonly** False > C++ defination code: > ```cpp > static std::string hello_str > ``` #### var1 {#var1 2} Example module readonly variable item description **type** var **static** False **readonly** True > C++ defination code: > ```cpp > const std::string var1 \"Example.var1\" > ``` #### var2 {#var2} Example module readonly variable item description **type** var **static** False **readonly** True > C++ defination code: > ```cpp > std::string var2 \"Example.var2\" > ``` #### dict\\_test {#dict\\_test} dict_test, return dict type, and element is pointer type(alloc in C++).\\nHere when the returned Tensor object will auto delete by Python GC. item description **type** func **static** True > C++ defination code: > ```cpp > static std::map *dict_test() > ```"},"/maixcdk/api/maix/time.html":{"title":"maix::time","content":" title: maix::time maix.time module > This is `maix::time` module of [MaixCDK](https://github.com/sipeed/MaixCDK). > All of these elements are in namespace `maix::time`. > > For MaixCDK developer: DO NOT edit this doc file manually, this doc is auto generated! ## Module {#Module} No module ## Enum {#Enum} ## Variable {#Variable} ## Function {#Function} ### time {#time} Get current time in s item description **return** current time in s, double type **attention** If board have no RTC battery, when bootup and connect to network,
    system will automatically sync time by NTP, will cause time() have big change,
    e.g. before NTP: 10(s), after: 1718590639.5149617(s).
    If you want to calculate time interval, please use ticks_s(). > C++ defination code: > ```cpp > double time() > ``` ### time\\_ms {#time\\_ms} Get current time in ms item description **return** current time in ms, uint64_t type **attention** If board have no RTC battery, when bootup and connect to network,
    system will automatically sync time by NTP, will cause time() have big change,
    e.g. before NTP: 10000(ms), after: 1718590639000(ms)
    If you want to calculate time interval, please use ticks_ms(). > C++ defination code: > ```cpp > uint64_t time_ms() > ``` ### time\\_s {#time\\_s} Get current time in s item description **return** current time in s, uint64_t type **attention** If board have no RTC battery, when bootup and connect to network,
    system will automatically sync time by NTP, will cause time() have big change,
    e.g. before NTP: 10(s), after: 1718590639(s) > C++ defination code: > ```cpp > uint64_t time_s() > ``` ### time\\_us {#time\\_us} Get current time in us item description **return** current time in us, uint64_t type **attention** If board have no RTC battery, when bootup and connect to network,
    system will automatically sync time by NTP, will cause time() have big change,
    e.g. before NTP: 10000000(us), after: 1718590639000000(s)
    If you want to calculate time interval, please use ticks_us(). > C++ defination code: > ```cpp > uint64_t time_us() > ``` ### time\\_diff {#time\\_diff} Calculate time difference in s. item description **param** **last**: last time
    **now**: current time, can be 1 if use current time
    **return** time difference **attention** If board have no RTC battery, when bootup and connect to network,
    system will automatically sync time by NTP, will cause time() have big change, and lead to big value.
    e.g. before NTP: 1(s), after: 1718590500(s)
    If you want to calculate time interval, please use ticks_diff(). > C++ defination code: > ```cpp > double time_diff(double last, double now 1) > ``` ### ticks\\_s {#ticks\\_s} Get current time in s since bootup item description **return** current time in s, double type > C++ defination code: > ```cpp > double ticks_s() > ``` ### ticks\\_ms {#ticks\\_ms} Get current time in ms since bootup item description **return** current time in ms, uint64_t type > C++ defination code: > ```cpp > uint64_t ticks_ms() > ``` ### ticks\\_us {#ticks\\_us} Get current time in us since bootup item description **return** current time in us, uint64_t type > C++ defination code: > ```cpp > uint64_t ticks_us() > ``` ### ticks\\_diff {#ticks\\_diff} Calculate time difference in s. item description **param** **last**: last time
    **now**: current time, can be 1 if use current time
    **return** time difference > C++ defination code: > ```cpp > double ticks_diff(double last, double now 1) > ``` ### sleep {#sleep} Sleep seconds item description **param** **s**: seconds, double type
    > C++ defination code: > ```cpp > void sleep(double s) > ``` ### sleep\\_ms {#sleep\\_ms} Sleep milliseconds item description **param** **ms**: milliseconds, uint64_t type
    > C++ defination code: > ```cpp > void sleep_ms(uint64_t ms) > ``` ### sleep\\_us {#sleep\\_us} Sleep microseconds item description **param** **us**: microseconds, uint64_t type
    > C++ defination code: > ```cpp > void sleep_us(uint64_t us) > ``` ### fps {#fps} Calculate FPS since last call this method.\\nAttention, this method is not multi thread safe, only call this method in one threads.\\nIf you want to use in multi threads, please use time.FPS class.\\nFPS is average value of recent n(buff_len) times, and you can call fps_set_buff_len(10) to change buffer length, default is 20.\\nMultiple invoke this function will calculate fps between two invoke, and you can also call fps_start() fisrt to manually assign fps calulate start point. item description **return** float type, current fps since last call this method > C++ defination code: > ```cpp > float fps() > ``` ### fps\\_start {#fps\\_start} Manually set fps calculation start point, then you can call fps() function to calculate fps between fps_start() and fps(). > C++ defination code: > ```cpp > void fps_start() > ``` ### fps\\_set\\_buff\\_len {#fps\\_set\\_buff\\_len} Set fps method buffer length, by default the buffer length is 10. item description **param** **len**: Buffer length to store recent fps value.
    > C++ defination code: > ```cpp > void fps_set_buff_len(int len) > ``` ### now {#now} Get current UTC date and time item description **return** current date and time, DateTime type > C++ defination code: > ```cpp > time::DateTime *now() > ``` ### localtime {#localtime} Get local time item description **return** local time, DateTime type > C++ defination code: > ```cpp > time::DateTime *localtime() > ``` ### strptime {#strptime} DateTime from string item description **param** **str**: date time string
    **format**: date time format
    **return** DateTime > C++ defination code: > ```cpp > time::DateTime *strptime(const std::string &str, const std::string &format) > ``` ### gmtime {#gmtime} timestamp to DateTime(time zone is UTC (value 0)) item description **param** **timestamp**: double timestamp
    **return** DateTime > C++ defination code: > ```cpp > time::DateTime *gmtime(double timestamp) > ``` ### timezone {#timezone} Set or get timezone item description **param** **timezone**: string type, can be empty and default to empty, if empty, only return crrent timezone, a \"region/city\" string, e.g. Asia/Shanghai, Etc/UTC, you can get all by list_timezones function.
    **return** string type, return current timezone setting. **attention** when set new timezone, time setting not take effect in this process for some API, so you need to restart program. > C++ defination code: > ```cpp > std::string timezone(const std::string &timezone \"\") > ``` ### timezone (overload 1) {#timezone (overload 1)} Set or get timezone item description **param** **region**: string type, which region to set, can be empty means only get current, default empty.
    **city**: string type, which city to set, can be empty means only get current, default empty.
    **return** list type, return current timezone setting, first is region, second is city. **attention** when set new timezone, time setting not take effect in this process for some API, so you need to restart program. > C++ defination code: > ```cpp > std::vector timezone2(const std::string ®ion \"\", const std::string &city \"\") > ``` ### list\\_timezones {#list\\_timezones} List all timezone info item description **return** A dict with key are regions, and value are region's cities. > C++ defination code: > ```cpp > std::map> list_timezones() > ``` ### ntp\\_timetuple {#ntp\\_timetuple} Retrieves time from an NTP server\\nThis function fetches the current time from the specified NTP server and port,\\nreturning a tuple containing the time details. item description **param** **host**: The hostname or IP address of the NTP server.
    **port**: The port number of the NTP server. Use 1 for the default port 123.
    **retry**: The number of retry attempts. Must be at least 1.
    **timeout_ms**: The timeout duration in milliseconds. Must be non negative.
    **return** A list of 6 elements: [year, month, day, hour, minute, second] > C++ defination code: > ```cpp > std::vector ntp_timetuple(std::string host, int port 1, uint8_t retry 3, int timeout_ms 0) > ``` ### ntp\\_timetuple\\_with\\_config {#ntp\\_timetuple\\_with\\_config} Retrieves time from an NTP server using a configuration file\\nThis function reads the configuration from a YAML file to fetch the current time\\nfrom a list of specified NTP servers, returning a tuple containing the time details. item description **param** **path**: The path to the YAML configuration file, which should include:
    Config:
    retry: Number of retry attempts (must be at least 1)
    total_timeout_ms: Total timeout duration in milliseconds (must be non negative)
    NtpServers:
    host: Hostname or IP address of the NTP server
    port: Port number of the NTP server (use 123 for default)
    Example YAML configuration:
    Config:
    retry: 3
    total_timeout_ms: 10000
    NtpServers:
    host: \"pool.ntp.org\"
    port: 123
    host: \"time.nist.gov\"
    port: 123
    host: \"time.windows.com\"
    port: 123
    **return** A list of 6 elements: [year, month, day, hour, minute, second] > C++ defination code: > ```cpp > std::vector ntp_timetuple_with_config(std::string path) > ``` ### ntp\\_sync\\_sys\\_time {#ntp\\_sync\\_sys\\_time} Retrieves time from an NTP server and synchronizes the system time\\nThis function fetches the current time from the specified NTP server and port,\\nthen synchronizes the system time with the retrieved time. item description **param** **host**: The hostname or IP address of the NTP server.
    **port**: The port number of the NTP server. Use 123 for the default port.
    **retry**: The number of retry attempts. Must be at least 1.
    **timeout_ms**: The timeout duration in milliseconds. Must be non negative.
    **return** A list of 6 elements: [year, month, day, hour, minute, second] > C++ defination code: > ```cpp > std::vector ntp_sync_sys_time(std::string host, int port 1, uint8_t retry 3, int timeout_ms 0) > ``` ### ntp\\_sync\\_sys\\_time\\_with\\_config {#ntp\\_sync\\_sys\\_time\\_with\\_config} Retrieves time from an NTP server using a configuration file and synchronizes the system time\\nThis function reads the configuration from a YAML file to fetch the current time\\nfrom a list of specified NTP servers, then synchronizes the system time with the retrieved time. item description **param** **path**: The path to the YAML configuration file, which should include:
    Config:
    retry: Number of retry attempts (must be at least 1)
    total_timeout_ms: Total timeout duration in milliseconds (must be non negative)
    NtpServers:
    host: Hostname or IP address of the NTP server
    port: Port number of the NTP server (use 123 for default)
    Example YAML configuration:
    Config:
    retry: 3
    total_timeout_ms: 10000
    NtpServers:
    host: \"pool.ntp.org\"
    port: 123
    host: \"time.nist.gov\"
    port: 123
    host: \"time.windows.com\"
    port: 123
    **return** A vector of integers containing the time details: [year, month, day, hour, minute, second] > C++ defination code: > ```cpp > std::vector ntp_sync_sys_time_with_config(std::string path) > ``` ## Class {#Class} ### FPS {#FPS 2} FPS class to use average filter to calculate FPS. > C++ defination code: > ```cpp > class FPS > ``` #### FPS {#FPS 3} FPS class constructor item description **type** func **param** **buff_len**: Average buffer length, default 20, that is, fps() function will return the average fps in recent buff_len times fps.
    **static** False > C++ defination code: > ```cpp > FPS(int buff_len 20) > ``` #### start {#start} Manually set fps calculation start point, then you can call fps() function to calculate fps between start() and fps(). item description **type** func **static** False > C++ defination code: > ```cpp > void start() > ``` #### fps {#fps 4} The same as end function. item description **type** func **return** float type, current fps since last call this method **static** False > C++ defination code: > ```cpp > float fps() > ``` #### fps (overload 1) {#fps (overload 1)} Calculate FPS since last call this method.\\nFPS is average value of recent n(buff_len) times, and you can call fps_set_buff_len(10) to change buffer length, default is 20.\\nMultiple invoke this function will calculate fps between two invoke, and you can also call fps_start() fisrt to manually assign fps calulate start point. item description **type** func **return** float type, current fps since last call this method **static** False > C++ defination code: > ```cpp > inline float end() > ``` #### set\\_buff\\_len {#set\\_buff\\_len} Set fps method buffer length, by default the buffer length is 10. item description **type** func **param** **len**: Buffer length to store recent fps value.
    **static** False > C++ defination code: > ```cpp > void set_buff_len(int len) > ``` ### DateTime {#DateTime} Date and time class > C++ defination code: > ```cpp > class DateTime > ``` #### year {#year} Year item description **type** var **static** False **readonly** False > C++ defination code: > ```cpp > int year > ``` #### month {#month} Month, 1~12 item description **type** var **static** False **readonly** False > C++ defination code: > ```cpp > int month > ``` #### day {#day} Day item description **type** var **static** False **readonly** False > C++ defination code: > ```cpp > int day > ``` #### hour {#hour} Hour item description **type** var **static** False **readonly** False > C++ defination code: > ```cpp > int hour > ``` #### minute {#minute} Minute item description **type** var **static** False **readonly** False > C++ defination code: > ```cpp > int minute > ``` #### second {#second} Second item description **type** var **static** False **readonly** False > C++ defination code: > ```cpp > int second > ``` #### microsecond {#microsecond} Microsecond item description **type** var **static** False **readonly** False > C++ defination code: > ```cpp > int microsecond > ``` #### yearday {#yearday} Year day item description **type** var **static** False **readonly** False > C++ defination code: > ```cpp > int yearday > ``` #### weekday {#weekday} Weekday, 0 is Monday, 6 is Sunday item description **type** var **static** False **readonly** False > C++ defination code: > ```cpp > int weekday > ``` #### zone {#zone} Time zone item description **type** var **static** False **readonly** False > C++ defination code: > ```cpp > float zone > ``` #### zone\\_name {#zone\\_name} Time zone name item description **type** var **static** False **readonly** False > C++ defination code: > ```cpp > std::string zone_name > ``` #### DateTime {#DateTime 2} Constructor item description **type** func **param** **year**: year
    **month**: month
    **day**: day
    **hour**: hour
    **minute**: minute
    **second**: second
    **microsecond**: microsecond
    **yearday**: year day
    **weekday**: weekday
    **zone**: time zone
    **static** False > C++ defination code: > ```cpp > DateTime(int year 0, int month 0, int day 0, int hour 0, int minute 0, int second 0, int microsecond 0, int yearday 0, int weekday 0, int zone 0) > ``` #### strftime {#strftime} Convert to string item description **type** func **return** date time string **static** False > C++ defination code: > ```cpp > std::string strftime(const std::string &format) > ``` #### timestamp {#timestamp} Convert to float timestamp item description **type** func **return** float timestamp **static** False > C++ defination code: > ```cpp > double timestamp() > ```"},"/maixcdk/api/maix/sys.html":{"title":"maix::sys","content":" title: maix::sys maix.sys module > This is `maix::sys` module of [MaixCDK](https://github.com/sipeed/MaixCDK). > All of these elements are in namespace `maix::sys`. > > For MaixCDK developer: DO NOT edit this doc file manually, this doc is auto generated! ## Module {#Module} No module ## Enum {#Enum} ## Variable {#Variable} ## Function {#Function} ### os\\_version {#os\\_version} Get system version item description **return** version string, e.g. \"maixcam 2024 08 13 maixpy v4.4.20\" > C++ defination code: > ```cpp > std::string os_version() > ``` ### maixpy\\_version {#maixpy\\_version} Get MaixPy version, if get failed will return empty string. item description **return** version string, e.g. \"4.4.21\" > C++ defination code: > ```cpp > std::string maixpy_version() > ``` ### runtime\\_version {#runtime\\_version} Get runtime version item description **return** current runtime version > C++ defination code: > ```cpp > std::string runtime_version() > ``` ### device\\_id {#device\\_id} Get device configs, we also say board configs. e.g. for MaixCAM it read form /boot/board item description **param** **cache**: read id from cache(if exists, or will call device_configs first internally) if true,
    if false, always read fron config file.
    **return** device id, e.g. \"maixcam\" \"maixcam_pro\" **throw** If board config file error will throw out exception(err.Exception) > C++ defination code: > ```cpp > std::map device_configs(bool cache true) > ``` ### device\\_id (overload 1) {#device\\_id (overload 1)} Get device id item description **param** **cache**: read id from cache(if exists, or will call device_configs first internally) if true,
    if false, always read fron config file.
    **return** device id, e.g. \"maixcam\" \"maixcam_pro\" > C++ defination code: > ```cpp > std::string device_id(bool cache true) > ``` ### device\\_name {#device\\_name} Get device name item description **param** **cache**: read id from cache(if exists, or will call device_configs first internally) if true,
    if false, always read fron config file.
    **return** device name, e.g. \"MaixCAM\" \"MaixCAM Pro\" > C++ defination code: > ```cpp > std::string device_name(bool cache true) > ``` ### host\\_name {#host\\_name} Get host name item description **return** host name, e.g. \"maixcam 2f9f\" > C++ defination code: > ```cpp > std::string host_name() > ``` ### host\\_domain {#host\\_domain} Get host domain item description **return** host domain, e.g. \"maixcam 2f9f.local\" > C++ defination code: > ```cpp > std::string host_domain() > ``` ### ip\\_address {#ip\\_address} Get ip address item description **return** ip address, dict type, e.g. {\"eth0\": \"192.168.0.195\", \"wlan0\": \"192.168.0.123\", \"usb0\": \"10.47.159.1\"} > C++ defination code: > ```cpp > std::map ip_address() > ``` ### mac\\_address {#mac\\_address} Get mac address item description **return** mac address, dict type, e.g. {\"eth0\": \"00:0c:29:2f:9f:00\", \"wlan0\": \"00:0c:29:2f:9f:01\", \"usb0\": \"00:0c:29:2f:9f:02\"} > C++ defination code: > ```cpp > std::map mac_address() > ``` ### device\\_key {#device\\_key} Get device key, can be unique id of device item description **return** device key, 32 bytes hex string, e.g. \"1234567890abcdef1234567890abcdef\" > C++ defination code: > ```cpp > std::string device_key() > ``` ### memory\\_info {#memory\\_info} Get memory info item description **return** memory info, dict type, e.g. {\"total\": 1024, \"used\": 512, \"hw_total\": 256*1024*1024}
    total: total memory size in Byte.
    used: used memory size in Byte.
    hw_total: total memory size in Byte of hardware, the total < hw_total,
    OS kernel may reserve some memory for some hardware like camera, npu, display etc. > C++ defination code: > ```cpp > std::map memory_info() > ``` ### bytes\\_to\\_human {#bytes\\_to\\_human} Bytes to human readable string item description **param** **bytes:**: bytes size,e.g. 1234B 1234/1024 1.205 KB
    **precision:**: decimal precision, default 2
    **base:**: base number, default 1024
    **unit:**: unit string, e.g. \"B\"
    **sep:**: separator string, e.g. \" \"
    **return** human readable string, e.g. \"1.21 KB\" > C++ defination code: > ```cpp > std::string bytes_to_human(unsigned long long bytes, int precision 2, int base 1024, const std::string &unit \"B\", const std::string &sep \" \") > ``` ### cpu\\_freq {#cpu\\_freq} Get CPU frequency item description **return** CPU frequency, dict type, e.g. {\"cpu0\": 1000000000, \"cpu1\": 1000000000} > C++ defination code: > ```cpp > std::map cpu_freq() > ``` ### cpu\\_temp {#cpu\\_temp} Get CPU temperature item description **return** CPU temperature, unit dgree, dict type, e.g. {\"cpu\": 50.0, \"cpu0\": 50, \"cpu1\": 50} > C++ defination code: > ```cpp > std::map cpu_temp() > ``` ### cpu\\_usage {#cpu\\_usage} Get CPU usage item description **return** CPU usage, dict type, e.g. {\"cpu\": 50.0, \"cpu0\": 50, \"cpu1\": 50} > C++ defination code: > ```cpp > std::map cpu_usage() > ``` ### npu\\_freq {#npu\\_freq} Get NPU frequency item description **return** NPU frequency, dict type, e.g. {\"npu0\": 500000000} > C++ defination code: > ```cpp > std::map npu_freq() > ``` ### disk\\_usage {#disk\\_usage} Get disk usage item description **param** **path:**: disk path, default \"/\"
    **return** disk usage, dict type, e.g. {\"total\": 1024, \"used\": 512} > C++ defination code: > ```cpp > std::map disk_usage(const std::string &path \"/\") > ``` ### disk\\_partitions {#disk\\_partitions} Get disk partition and mount point info item description **param** **only_disk**: only return real disk, tempfs sysfs etc. not return, default true.
    **return** disk partition and mount point info, list type, e.g. [{\"device\": \"/dev/mmcblk0p1\", \"mountpoint\": \"/mnt/sdcard\", \"fstype\": \"vfat\"}] > C++ defination code: > ```cpp > std::vector> disk_partitions(bool only_disk true) > ``` ### register\\_default\\_signal\\_handle {#register\\_default\\_signal\\_handle} register default signal handle > C++ defination code: > ```cpp > void register_default_signal_handle() > ``` ### poweroff {#poweroff} Power off device > C++ defination code: > ```cpp > void poweroff() > ``` ### reboot {#reboot} Power off device and power on > C++ defination code: > ```cpp > void reboot() > ``` ## Class {#Class}"},"/maixcdk/api/maix/network/wifi.html":{"title":"maix::network::wifi","content":" title: maix::network::wifi maix.network.wifi module > This is `maix::network::wifi` module of [MaixCDK](https://github.com/sipeed/MaixCDK). > All of these elements are in namespace `maix::network::wifi`. > > For MaixCDK developer: DO NOT edit this doc file manually, this doc is auto generated! ## Module {#Module} No module ## Enum {#Enum} ## Variable {#Variable} ## Function {#Function} ### list\\_devices {#list\\_devices} List WiFi interfaces item description **return** WiFi interface list, string type > C++ defination code: > ```cpp > std::vector list_devices() > ``` ## Class {#Class} ### AP\\_Info {#AP\\_Info} WiFi AP info > C++ defination code: > ```cpp > class AP_Info > ``` #### ssid {#ssid} WiFi AP info SSID item description **type** var **static** False **readonly** False > C++ defination code: > ```cpp > std::vector ssid > ``` #### bssid {#bssid} WiFi AP info BSSID item description **type** var **static** False **readonly** False > C++ defination code: > ```cpp > std::string bssid > ``` #### security {#security} WiFi AP info security item description **type** var **static** False **readonly** False > C++ defination code: > ```cpp > std::string security > ``` #### channel {#channel} WiFi AP info channel item description **type** var **static** False **readonly** False > C++ defination code: > ```cpp > int channel > ``` #### frequency {#frequency} WiFi AP info frequency item description **type** var **static** False **readonly** False > C++ defination code: > ```cpp > int frequency > ``` #### rssi {#rssi} WiFi AP info rssi item description **type** var **static** False **readonly** False > C++ defination code: > ```cpp > int rssi > ``` #### ssid\\_str {#ssid\\_str} WiFi AP info ssid_str item description **type** func **static** False > C++ defination code: > ```cpp > std::string ssid_str() > ``` ### Wifi {#Wifi} Wifi class > C++ defination code: > ```cpp > class Wifi > ``` #### Wifi {#Wifi 2} Wifi class item description **type** func **param** **iface**: wifi interface name, default is wlan0
    **static** False > C++ defination code: > ```cpp > Wifi(std::string iface \"wlan0\") > ``` #### get\\_ip {#get\\_ip} Get current WiFi ip item description **type** func **return** ip, string type, if network not connected, will return empty string. **static** False > C++ defination code: > ```cpp > std::string get_ip() > ``` #### get\\_mac {#get\\_mac} Get current WiFi MAC address item description **type** func **return** ip, string type. **static** False > C++ defination code: > ```cpp > std::string get_mac() > ``` #### get\\_ssid {#get\\_ssid} Get current WiFi SSID item description **type** func **param** **from_cache**: if true, will not read config from file, direct use ssid in cache.
    attention, first time call this method will auto matically read config from file, and if call connect method will set cache.
    **return** SSID, string type. **static** False > C++ defination code: > ```cpp > std::string get_ssid(bool from_cache true) > ``` #### get\\_gateway {#get\\_gateway} Get current WiFi ip item description **type** func **return** ip, string type, if network not connected, will return empty string. **static** False > C++ defination code: > ```cpp > std::string get_gateway() > ``` #### start\\_scan {#start\\_scan} WiFi start scan AP info around in background. item description **type** func **return** If success, return err.Err.ERR_NONE, else means failed. **static** False > C++ defination code: > ```cpp > err::Err start_scan() > ``` #### get\\_scan\\_result {#get\\_scan\\_result} Get WiFi scan AP info. item description **type** func **return** wifi.AP_Info list. **static** False > C++ defination code: > ```cpp > std::vector get_scan_result() > ``` #### stop\\_scan {#stop\\_scan} Stop WiFi scan AP info. item description **type** func **static** False > C++ defination code: > ```cpp > void stop_scan() > ``` #### connect {#connect} Connect to WiFi AP. item description **type** func **param** **ssid**: SSID of AP
    **password**: password of AP, if no password, leave it empty.
    **wait**: wait for got IP or failed or timeout.
    **timeout**: connect timeout internal, unit second.
    **return** If success, return err.Err.ERR_NONE, else means failed. **static** False > C++ defination code: > ```cpp > err::Err connect(const std::string &ssid, const std::string &password, bool wait true, int timeout 60) > ``` #### disconnect {#disconnect} Disconnect from WiFi AP. item description **type** func **return** If success, return err.Err.ERR_NONE, else means failed. **static** False > C++ defination code: > ```cpp > err::Err disconnect() > ``` #### is\\_connected {#is\\_connected} See if WiFi is connected to AP. item description **type** func **return** If connected return true, else false. **static** False > C++ defination code: > ```cpp > bool is_connected() > ``` #### start\\_ap {#start\\_ap} Start WiFi AP. item description **type** func **param** **ssid**: SSID of AP.
    **password**: password of AP, if no password, leave it empty.
    **ip**: ip address of hostap, default empty string means auto generated one according to hardware.
    **netmask**: netmask, default 255.255.255.0, now only support 255.255.255.0 .
    **mode**: WiFi mode, default g(IEEE 802.11g (2.4 GHz)), a IEEE 802.11a (5 GHz), b IEEE 802.11b (2.4 GHz).
    **channel**: WiFi channel number, 0 means auto select. MaixCAM not support auto, will default channel 1.
    **hidden**: hidden SSID or not.
    **return** If success, return err.Err.ERR_NONE, else means failed. **static** False > C++ defination code: > ```cpp > err::Err start_ap(const std::string &ssid, const std::string &password, > std::string mode \"g\", int channel 0, > const std::string &ip \"192.168.66.1\", const std::string &netmask \"255.255.255.0\", > bool hidden false) > ``` #### stop\\_ap {#stop\\_ap} Stop WiFi AP. item description **type** func **return** If success, return err.Err.ERR_NONE, else means failed. **static** False > C++ defination code: > ```cpp > err::Err stop_ap() > ``` #### is\\_ap\\_mode {#is\\_ap\\_mode} Whether WiFi is AP mode item description **type** func **return** True if AP mode now, or False. **static** False > C++ defination code: > ```cpp > bool is_ap_mode() > ```"},"/maixcdk/api/maix/modbus.html":{"title":"maix::modbus","content":" title: maix::modbus maix.modbus module > This is `maix::modbus` module of [MaixCDK](https://github.com/sipeed/MaixCDK). > All of these elements are in namespace `maix::modbus`. > > For MaixCDK developer: DO NOT edit this doc file manually, this doc is auto generated! ## Module {#Module} module brief [Slave](./modbus/Slave.html) maix.modbus.Slave module ## Enum {#Enum} ## Variable {#Variable} ## Function {#Function} ## Class {#Class}"},"/maixcdk/api/maix/comm/modbus.html":{"title":"maix::comm::modbus","content":" title: maix::comm::modbus maix.comm.modbus module > This is `maix::comm::modbus` module of [MaixCDK](https://github.com/sipeed/MaixCDK). > All of these elements are in namespace `maix::comm::modbus`. > > For MaixCDK developer: DO NOT edit this doc file manually, this doc is auto generated! ## Module {#Module} No module ## Enum {#Enum} ### Mode {#Mode} modbus mode item describe **values** **RTU**:
    **TCP**:
    > C++ defination code: > ```cpp > enum class Mode : unsigned char { > RTU, > TCP > } > ``` ### RequestType {#RequestType} Modbus request types enumeration.\\nThis enumeration defines the various Modbus request types,\\nincluding functions for reading and writing coils, registers,\\nas well as diagnostics and identification. item describe **values** **READ_COILS**: < Read Coils
    **READ_DISCRETE_INPUTS**: < Read Discrete Inputs
    **READ_HOLDING_REGISTERS**: < Read Holding Registers
    **READ_INPUT_REGISTERS**: < Read Input Registers
    **WRITE_SINGLE_COIL**: < Write Single Coil
    **WRITE_SINGLE_REGISTER**: < Write Single Register
    **DIAGNOSTICS**: < Diagnostics (Serial Line only)
    **GET_COMM_EVENT_COUNTER**: < Get Comm Event Counter (Serial Line only)
    **WRITE_MULTIPLE_COILS**: < Write Multiple Coils
    **WRITE_MULTIPLE_REGISTERS**: < Write Multiple Registers
    **REPORT_SERVER_ID**: < Report Slave ID (Serial Line only)
    **MASK_WRITE_REGISTER**: < Mask Write Register
    **READ_WRITE_MULTIPLE_REGISTERS**: < Read/Write Multiple Registers
    **READ_DEVICE_IDENTIFICATION**: < Read Device Identification
    **UNKNOWN**: < Unknown Request Type
    > C++ defination code: > ```cpp > enum class RequestType : unsigned char { > READ_COILS 0x01, ///< Read Coils > READ_DISCRETE_INPUTS 0x02, ///< Read Discrete Inputs > READ_HOLDING_REGISTERS 0x03, ///< Read Holding Registers > READ_INPUT_REGISTERS 0x04, ///< Read Input Registers > WRITE_SINGLE_COIL 0x05, ///< Write Single Coil > WRITE_SINGLE_REGISTER 0x06, ///< Write Single Register > DIAGNOSTICS 0x08, ///< Diagnostics (Serial Line only) > GET_COMM_EVENT_COUNTER 0x0B, ///< Get Comm Event Counter (Serial Line only) > WRITE_MULTIPLE_COILS 0x0F, ///< Write Multiple Coils > WRITE_MULTIPLE_REGISTERS 0x10, ///< Write Multiple Registers > REPORT_SERVER_ID 0x11, ///< Report Slave ID (Serial Line only) > MASK_WRITE_REGISTER 0x16, ///< Mask Write Register > READ_WRITE_MULTIPLE_REGISTERS 0x17, ///< Read/Write Multiple Registers > READ_DEVICE_IDENTIFICATION 0x2B, ///< Read Device Identification > UNKNOWN 0xFF ///< Unknown Request Type > } > ``` ## Variable {#Variable} ## Function {#Function} ### set\\_master\\_debug {#set\\_master\\_debug} Set the master debug ON/OFF item description **param** **debug**: True(ON) or False(OFF)
    > C++ defination code: > ```cpp > void set_master_debug(bool debug) > ``` ## Class {#Class} ### RegisterInfo {#RegisterInfo} Structure to hold information about a Modbus register.\\nThis structure contains the starting address and size of a Modbus register,\\nallowing for easy management of register information. > C++ defination code: > ```cpp > struct RegisterInfo > ``` ### Registers {#Registers} Structure to hold information about multiple Modbus registers.\\nThis structure aggregates information for various types of Modbus registers,\\nincluding coils, discrete inputs, holding registers, and input registers. > C++ defination code: > ```cpp > struct Registers > ``` ### Slave {#Slave} Class for modbus Slave > C++ defination code: > ```cpp > class Slave > ``` #### \\_\\_init\\_\\_ {#\\_\\_init\\_\\_} Modbus Slave constructor.\\nThis constructor initializes a Modbus Slave instance. Depending on the mode (RTU or TCP),\\nit sets up the necessary parameters for communication and defines the register structure. item description **type** func **param** **mode**: Specifies the communication mode: RTU or TCP.
    **ip_or_device**: The UART device name if using RTU mode.
    If TCP mode is selected, this parameter is ignored.
    **coils_start**: The starting address of the coils register.
    **coils_size**: The number of coils to manage.
    **discrete_start**: The starting address of the discrete inputs register.
    **discrete_size**: The number of discrete inputs to manage.
    **holding_start**: The starting address of the holding registers.
    **holding_size**: The number of holding registers to manage.
    **input_start**: The starting address of the input registers.
    **input_size**: The number of input registers to manage.
    **rtu_baud**: The baud rate for RTU communication.
    Supported rates include: 110, 300, 600, 1200, 2400, 4800,
    9600, 19200, 38400, 57600, 115200, 230400, 460800,
    500000, 576000, 921600, 1000000, 1152000, 1500000,
    2500000, 3000000, 3500000, 4000000.
    Default is 115200. Ensure that the selected baud rate
    is supported by the underlying hardware and libmodbus.
    **rtu_slave**: The RTU slave address. Ignored in TCP mode. Default is 1.
    **tcp_port**: The port used for TCP communication. Ignored in RTU mode. Default is 502.
    **debug**: A boolean flag to enable or disable debug mode. Default is false.
    **see** modbus.Mode for valid modes. **static** False > C++ defination code: > ```cpp > Slave(maix::comm::modbus::Mode mode, const std::string& ip_or_device, > uint32_t coils_start 0, uint32_t coils_size 0, > uint32_t discrete_start 0, uint32_t discrete_size 0, > uint32_t holding_start 0, uint32_t holding_size 0, > uint32_t input_start 0, uint32_t input_size 0, > int rtu_baud 115200, uint8_t rtu_slave 1, > int tcp_port 502, bool debug false) > ``` #### receive {#receive} Receives a Modbus request\\nThis function is used to receive a Modbus request from the client. The behavior of the function\\ndepends on the parameter `timeout_ms` provided, which dictates how long the function will wait\\nfor a request before returning. item description **type** func **note** This function gets and parses the request, it does not manipulate the registers. **param** **timeout_ms**: Timeout setting
    1 Block indefinitely until a request is received
    0 Non blocking mode; function returns immediately, regardless of whether a request is received
    >0 Blocking mode; function will wait for the specified number of milliseconds for a request
    **return** maix::err::Err type, @see maix::err::Err **static** False > C++ defination code: > ```cpp > ::maix::err::Err receive(const int timeout_ms 1) > ``` #### request\\_type {#request\\_type} Gets the type of the Modbus request that was successfully received\\nThis function can be used to retrieve the type of the request received after a successful\\ncall to `receive()`. The return value indicates the type of the Modbus request, allowing\\nthe user to understand and process the received request appropriately. item description **type** func **return** RequestType The type of the Modbus request that has been received. **see** modbus.RequestType **static** False > C++ defination code: > ```cpp > ::maix::comm::modbus::RequestType request_type() > ``` #### reply {#reply} Processes the request and returns the corresponding data.\\nThis function handles the requests received from the client. It retrieves any data that the client\\nneeds to write to the registers and updates the registers accordingly. Additionally, it retrieves\\nthe requested data from the registers and sends it back to the client in the response.\\nThis function is essential for managing read and write operations in a Modbus Slave context. item description **type** func **note** The function will modify the Slave's internal state based on the data received in the
    request, and ensure that the appropriate data is returned to the client. **return** maix::err::Err type, @see maix::err::Err **static** False > C++ defination code: > ```cpp > ::maix::err::Err reply() > ``` #### receive\\_and\\_reply {#receive\\_and\\_reply} Receives a request from the client and sends a response.\\nThis function combines the operations of receiving a request and sending a corresponding\\nresponse in a single call. It waits for a specified duration (defined by the `timeout_ms`\\nparameter) to receive a request from the client. Upon successful receipt of the request,\\nit processes the request and prepares the necessary data to be sent back to the client. item description **type** func **param** **timeout_ms**: The timeout duration for waiting to receive a request.
    A value of 1 makes the function block indefinitely until a request
    is received.
    A value of 0 makes it non blocking, returning immediately without
    waiting for a request.
    A positive value specifies the maximum time (in milliseconds) to wait
    for a request before timing out.
    **return** RequestType The type of the Modbus request that has been received. **see** modbus.RequestType **static** False > C++ defination code: > ```cpp > ::maix::comm::modbus::RequestType receive_and_reply(const int timeout_ms 1) > ``` #### coils {#coils} Reads from or writes to coils.\\nThis function can be used to either read data from coils or write data to them.\\nIf the `data` parameter is empty, the function performs a read operation.\\nIf `data` is not empty, the function writes the contents of `data` to the coils\\nstarting at the specified index. item description **type** func **param** **data**: A vector of data to be written. If empty, a read operation is performed.
    If not empty, the data will overwrite the coils from `index`.
    **index**: The starting index for writing data. This parameter is ignored during read operations.
    **return** std::vector When the read operation is successful, return all data in the coils as a list.
    When the write operation is successful, return a non empty list; when it fails, return an empty list. **static** False > C++ defination code: > ```cpp > std::vector coils(const std::vector& data std::vector{}, const uint32_t index 0) > ``` #### discrete\\_input {#discrete\\_input} Reads from or writes to discrete input.\\nThis function can be used to either read data from discrete input or write data to them.\\nIf the `data` parameter is empty, the function performs a read operation.\\nIf `data` is not empty, the function writes the contents of `data` to the discrete input\\nstarting at the specified index. item description **type** func **param** **data**: A vector of data to be written. If empty, a read operation is performed.
    If not empty, the data will overwrite the discrete input from `index`.
    **index**: The starting index for writing data. This parameter is ignored during read operations.
    **return** std::vector When the read operation is successful, return all data in the discrete input as a list.
    When the write operation is successful, return a non empty list; when it fails, return an empty list. **static** False > C++ defination code: > ```cpp > std::vector discrete_input(const std::vector& data std::vector{}, const uint32_t index 0) > ``` #### input\\_registers {#input\\_registers} Reads from or writes to input registers.\\nThis function can be used to either read data from input registers or write data to them.\\nIf the `data` parameter is empty, the function performs a read operation.\\nIf `data` is not empty, the function writes the contents of `data` to the input registers\\nstarting at the specified index. item description **type** func **param** **data**: A vector of data to be written. If empty, a read operation is performed.
    If not empty, the data will overwrite the input registers from `index`.
    **index**: The starting index for writing data. This parameter is ignored during read operations.
    **return** std::vector When the read operation is successful, return all data in the input registers as a list.
    When the write operation is successful, return a non empty list; when it fails, return an empty list. **static** False > C++ defination code: > ```cpp > std::vector input_registers(const std::vector& data std::vector{}, const uint32_t index 0) > ``` #### holding\\_registers {#holding\\_registers} Reads from or writes to holding registers.\\nThis function can be used to either read data from holding registers or write data to them.\\nIf the `data` parameter is empty, the function performs a read operation.\\nIf `data` is not empty, the function writes the contents of `data` to the holding registers\\nstarting at the specified index. item description **type** func **param** **data**: A vector of data to be written. If empty, a read operation is performed.
    If not empty, the data will overwrite the holding registers from `index`.
    **index**: The starting index for writing data. This parameter is ignored during read operations.
    **return** std::vector When the read operation is successful, return all data in the holding registers as a list.
    When the write operation is successful, return a non empty list; when it fails, return an empty list. **static** False > C++ defination code: > ```cpp > std::vector holding_registers(const std::vector& data std::vector{}, const uint32_t index 0) > ``` ### MasterRTU {#MasterRTU} Class for modbus MasterRTU > C++ defination code: > ```cpp > class MasterRTU final > ``` #### \\_\\_init\\_\\_ {#\\_\\_init\\_\\_ 2} Construct a new MasterRTU object item description **type** func **param** **device**: Default uart device.
    **baudrate**: Default uart baudrate.
    **static** False > C++ defination code: > ```cpp > MasterRTU(const std::string& device \"\", const int baudrate 115200) > ``` #### read\\_coils {#read\\_coils} Reads coils from the Modbus device.\\nThis function reads a specified number of coils starting from a given address.\\nIt includes timeout settings to define how long to wait for a response. item description **type** func **param** **slave_id**: The RTU slave address.
    **addr**: The starting address for reading coils.
    **size**: The number of coils to read.
    **timeout_ms**: The timeout duration for waiting to receive a request.
    A value of 1 makes the function block indefinitely until a request
    is received.
    A value of 0 makes it non blocking, returning immediately without
    waiting for a request.
    A positive value specifies the maximum time (in milliseconds) to wait
    for a request before timing out.
    **device**: The UART device to use. An empty string (\"\") indicates that the
    default device from the constructor will be used.
    **baudrate**: The UART baud rate. A value of 1 signifies that the default baud rate
    from the constructor will be applied.
    **return** std::vector/list[int] A vector containing the read coil values. **static** False > C++ defination code: > ```cpp > std::vector read_coils(const uint32_t slave_id, const uint32_t addr, > const uint32_t size, const int timeout_ms 1, > const std::string& device \"\", const int baudrate 1) > ``` #### read\\_coils (overload 1) {#read\\_coils (overload 1)} Reads coils from the Modbus device.\\nThis function reads a specified number of coils starting from a given address.\\nIt includes timeout settings to define how long to wait for a response. item description **type** func **param** **device**: The UART device to use.
    **baudrate**: he UART baud rate.
    **slave_id**: The RTU slave address.
    **addr**: The starting address for reading coils.
    **size**: The number of coils to read.
    **timeout_ms**: The timeout duration for waiting to receive a request.
    A value of 1 makes the function block indefinitely until a request
    is received.
    A value of 0 makes it non blocking, returning immediately without
    waiting for a request.
    A positive value specifies the maximum time (in milliseconds) to wait
    for a request before timing out.
    **return** std::vector/list[int] A vector containing the read coil values. **static** True > C++ defination code: > ```cpp > static std::vector read_coils( const std::string& device, const int baudrate, > const uint32_t slave_id, const uint32_t addr, > const uint32_t size, const int timeout_ms 1) > ``` #### write\\_coils {#write\\_coils} Writes values to coils on the Modbus device.\\nThis function writes the specified data to the coils starting from a given address. item description **type** func **param** **slave_id**: The RTU slave address.
    **data**: A vector containing the coil values to write.
    **addr**: The starting address for writing coils.
    **timeout_ms**: The timeout duration for the write operation.
    A value of 1 makes the function block until the write is complete.
    A value of 0 makes it non blocking.
    A positive value specifies the maximum time (in milliseconds) to wait.
    **device**: The UART device to use. An empty string (\"\") indicates that the
    default device from the constructor will be used.
    **baudrate**: The UART baud rate. A value of 1 signifies that the default baud rate
    from the constructor will be applied.
    **return** int Returns the number of bytes written on success, or a value less than 0 on failure. **static** False > C++ defination code: > ```cpp > int write_coils(const uint32_t slave_id, const std::vector& data, > const uint32_t addr, const int timeout_ms 1, > const std::string& device \"\", const int baudrate 1) > ``` #### write\\_coils (overload 1) {#write\\_coils (overload 1)} Writes values to coils on the Modbus device.\\nThis function writes the specified data to the coils starting from a given address. item description **type** func **param** **device**: The UART device to use.
    **baudrate**: The UART baud rate.
    **slave_id**: The RTU slave address.
    **data**: A vector containing the coil values to write.
    **addr**: The starting address for writing coils.
    **timeout_ms**: The timeout duration for the write operation.
    A value of 1 makes the function block until the write is complete.
    A value of 0 makes it non blocking.
    A positive value specifies the maximum time (in milliseconds) to wait.
    **return** int Returns the number of bytes written on success, or a value less than 0 on failure. **static** True > C++ defination code: > ```cpp > static int write_coils(const std::string& device, const int baudrate, > const uint32_t slave_id, const std::vector& data, > const uint32_t addr, const int timeout_ms 1) > ``` #### read\\_discrete\\_input {#read\\_discrete\\_input} Reads discrete inputs from the Modbus device.\\nThis function reads a specified number of discrete inputs starting from a given address. item description **type** func **param** **slave_id**: The RTU slave address.
    **addr**: The starting address for reading discrete inputs.
    **size**: The number of discrete inputs to read.
    **timeout_ms**: The timeout duration for the write operation.
    A value of 1 makes the function block until the write is complete.
    A value of 0 makes it non blocking.
    A positive value specifies the maximum time (in milliseconds) to wait.
    **device**: The UART device to use. An empty string (\"\") indicates that the
    default device from the constructor will be used.
    **baudrate**: The UART baud rate. A value of 1 signifies that the default baud rate
    from the constructor will be applied.
    **return** std::vector/list[int] A vector containing the read discrete input values. **static** False > C++ defination code: > ```cpp > std::vector read_discrete_input(const uint32_t slave_id, const uint32_t addr, > const uint32_t size, const int timeout_ms 1, > const std::string& device \"\", const int baudrate 1) > ``` #### read\\_discrete\\_input (overload 1) {#read\\_discrete\\_input (overload 1)} Reads discrete inputs from the Modbus device.\\nThis function reads a specified number of discrete inputs starting from a given address. item description **type** func **param** **device**: The UART device to use.
    **baudrate**: The UART baud rate.
    **slave_id**: The RTU slave address.
    **addr**: The starting address for reading discrete inputs.
    **size**: The number of discrete inputs to read.
    **timeout_ms**: The timeout duration for the write operation.
    A value of 1 makes the function block until the write is complete.
    A value of 0 makes it non blocking.
    A positive value specifies the maximum time (in milliseconds) to wait.
    **return** std::vector/list[int] A vector containing the read discrete input values. **static** True > C++ defination code: > ```cpp > static std::vector read_discrete_input(const std::string& device, const int baudrate, > const uint32_t slave_id, const uint32_t addr, > const uint32_t size, const int timeout_ms 1) > ``` #### read\\_input\\_registers {#read\\_input\\_registers} Reads input registers from the Modbus device.\\nThis function reads a specified number of input registers starting from a given address. item description **type** func **param** **slave_id**: The RTU slave address.
    **addr**: The starting address for reading input registers.
    **size**: The number of input registers to read.
    **timeout_ms**: The timeout duration for the write operation.
    A value of 1 makes the function block until the write is complete.
    A value of 0 makes it non blocking.
    A positive value specifies the maximum time (in milliseconds) to wait.
    **device**: The UART device to use. An empty string (\"\") indicates that the
    default device from the constructor will be used.
    **baudrate**: The UART baud rate. A value of 1 signifies that the default baud rate
    from the constructor will be applied.
    **return** std::vector/list[int] A vector containing the read input register values. **static** False > C++ defination code: > ```cpp > std::vector read_input_registers(const uint32_t slave_id, const uint32_t addr, > const uint32_t size, const int timeout_ms 1, > const std::string& device \"\", const int baudrate 1) > ``` #### read\\_input\\_registers (overload 1) {#read\\_input\\_registers (overload 1)} Reads input registers from the Modbus device.\\nThis function reads a specified number of input registers starting from a given address. item description **type** func **param** **device**: The UART device to use.
    **baudrate**: The UART baud rate.
    **slave_id**: The RTU slave address.
    **addr**: The starting address for reading input registers.
    **size**: The number of input registers to read.
    **timeout_ms**: The timeout duration for the write operation.
    A value of 1 makes the function block until the write is complete.
    A value of 0 makes it non blocking.
    A positive value specifies the maximum time (in milliseconds) to wait.
    **return** std::vector/list[int] A vector containing the read input register values. **static** True > C++ defination code: > ```cpp > static std::vector read_input_registers(const std::string& device, const int baudrate, > const uint32_t slave_id, const uint32_t addr, > const uint32_t size, const int timeout_ms 1) > ``` #### read\\_holding\\_registers {#read\\_holding\\_registers} Reads holding registers from the Modbus device.\\nThis function reads a specified number of holding registers starting from a given address. item description **type** func **param** **slave_id**: The RTU slave address.
    **addr**: The starting address for reading holding registers.
    **size**: The number of holding registers to read.
    **timeout_ms**: The timeout duration for the write operation.
    A value of 1 makes the function block until the write is complete.
    A value of 0 makes it non blocking.
    A positive value specifies the maximum time (in milliseconds) to wait.
    **device**: The UART device to use. An empty string (\"\") indicates that the
    default device from the constructor will be used.
    **baudrate**: The UART baud rate. A value of 1 signifies that the default baud rate
    from the constructor will be applied.
    **return** std::vector/list[int] A vector containing the read holding register values. **static** False > C++ defination code: > ```cpp > std::vector read_holding_registers(const uint32_t slave_id, const uint32_t addr, > const uint32_t size, const int timeout_ms 1, > const std::string& device \"\", const int baudrate 1) > ``` #### read\\_holding\\_registers (overload 1) {#read\\_holding\\_registers (overload 1)} Reads holding registers from the Modbus device.\\nThis function reads a specified number of holding registers starting from a given address. item description **type** func **param** **device**: The UART device to use.
    **baudrate**: The UART baud rate.
    **slave_id**: The RTU slave address.
    **addr**: The starting address for reading holding registers.
    **size**: The number of holding registers to read.
    **timeout_ms**: The timeout duration for the write operation.
    A value of 1 makes the function block until the write is complete.
    A value of 0 makes it non blocking.
    A positive value specifies the maximum time (in milliseconds) to wait.
    **return** std::vector/list[int] A vector containing the read holding register values. **static** True > C++ defination code: > ```cpp > static std::vector read_holding_registers(const std::string& device, const int baudrate, > const uint32_t slave_id, const uint32_t addr, > const uint32_t size, const int timeout_ms 1) > ``` #### write\\_holding\\_registers {#write\\_holding\\_registers} Writes values to holding registers on the Modbus device.\\nThis function writes the specified data to the holding registers starting from a given address. item description **type** func **param** **slave_id**: The RTU slave address.
    **data**: A vector containing the values to write to holding registers.
    **addr**: The starting address for writing holding registers.
    **timeout_ms**: The timeout duration for the write operation.
    A value of 1 makes the function block until the write is complete.
    A value of 0 makes it non blocking.
    A positive value specifies the maximum time (in milliseconds) to wait.
    **device**: The UART device to use. An empty string (\"\") indicates that the
    default device from the constructor will be used.
    **baudrate**: The UART baud rate. A value of 1 signifies that the default baud rate
    from the constructor will be applied.
    **return** int Returns the number of bytes written on success, or a value less than 0 on failure. **static** False > C++ defination code: > ```cpp > int write_holding_registers(const uint32_t slave_id, const std::vector& data, > const uint32_t addr, const int timeout_ms 1, > const std::string& device \"\", const int baudrate 1) > ``` #### write\\_holding\\_registers (overload 1) {#write\\_holding\\_registers (overload 1)} Writes values to holding registers on the Modbus device.\\nThis function writes the specified data to the holding registers starting from a given address. item description **type** func **param** **device**: The UART device to use.
    **baudrate**: The UART baud rate.
    **slave_id**: The RTU slave address.
    **data**: A vector containing the values to write to holding registers.
    **addr**: The starting address for writing holding registers.
    **timeout_ms**: The timeout duration for the write operation.
    A value of 1 makes the function block until the write is complete.
    A value of 0 makes it non blocking.
    A positive value specifies the maximum time (in milliseconds) to wait.
    **return** int Returns the number of bytes written on success, or a value less than 0 on failure. **static** True > C++ defination code: > ```cpp > static int write_holding_registers(const std::string& device, const int baudrate, > const uint32_t slave_id, const std::vector& data, > const uint32_t addr, const int timeout_ms 1) > ``` ### MasterTCP {#MasterTCP} Class for modbus Master > C++ defination code: > ```cpp > class MasterTCP final > ``` #### \\_\\_init\\_\\_ {#\\_\\_init\\_\\_ 3} Construct a new MasterTCP object item description **type** func **param** **port**: Device tcp port.
    **static** False > C++ defination code: > ```cpp > MasterTCP(const int port 502) > ``` #### read\\_coils {#read\\_coils 2} Reads coils from the Modbus device.\\nThis function reads a specified number of coils starting from a given address.\\nIt includes timeout settings to define how long to wait for a response. item description **type** func **param** **ip**: The TCP IP address.
    **addr**: The starting address for reading coils.
    **size**: The number of coils to read.
    **timeout_ms**: The timeout duration for waiting to receive a request.
    A value of 1 makes the function block indefinitely until a request
    is received.
    A value of 0 makes it non blocking, returning immediately without
    waiting for a request.
    A positive value specifies the maximum time (in milliseconds) to wait
    for a request before timing out.
    **port**: The TCP port. A value of 1 signifies that the default port
    from the constructor will be applied.
    **return** std::vector/list[int] A vector containing the read coil values. **static** False > C++ defination code: > ```cpp > std::vector read_coils(const std::string ip, const uint32_t addr, > const uint32_t size, const int timeout_ms 1, > const int port 1) > ``` #### read\\_coils (overload 1) {#read\\_coils (overload 1) 2} Reads coils from the Modbus device.\\nThis function reads a specified number of coils starting from a given address.\\nIt includes timeout settings to define how long to wait for a response. item description **type** func **param** **ip**: The TCP IP address.
    **port**: The TCP port.
    **addr**: The starting address for reading coils.
    **size**: The number of coils to read.
    **timeout_ms**: The timeout duration for waiting to receive a request.
    A value of 1 makes the function block indefinitely until a request
    is received.
    A value of 0 makes it non blocking, returning immediately without
    waiting for a request.
    A positive value specifies the maximum time (in milliseconds) to wait
    for a request before timing out.
    **return** std::vector/list[int] A vector containing the read coil values. **static** True > C++ defination code: > ```cpp > static std::vector read_coils( const std::string ip, const int port, > const uint32_t addr, > const uint32_t size, const int timeout_ms 1) > ``` #### write\\_coils {#write\\_coils 2} Writes values to coils on the Modbus device.\\nThis function writes the specified data to the coils starting from a given address. item description **type** func **param** **ip**: The TCP IP address.
    **data**: A vector containing the coil values to write.
    **addr**: The starting address for writing coils.
    **timeout_ms**: The timeout duration for the write operation.
    A value of 1 makes the function block until the write is complete.
    A value of 0 makes it non blocking.
    A positive value specifies the maximum time (in milliseconds) to wait.
    **port**: The TCP port. A value of 1 signifies that the default port
    from the constructor will be applied.
    **return** int Returns the number of bytes written on success, or a value less than 0 on failure. **static** False > C++ defination code: > ```cpp > int write_coils(const std::string ip, const std::vector& data, > const uint32_t addr, const int timeout_ms 1, > const int port 1) > ``` #### write\\_coils (overload 1) {#write\\_coils (overload 1) 2} Writes values to coils on the Modbus device.\\nThis function writes the specified data to the coils starting from a given address. item description **type** func **param** **ip**: The TCP IP address.
    **port**: The TCP port.
    **data**: A vector containing the coil values to write.
    **addr**: The starting address for writing coils.
    **timeout_ms**: The timeout duration for the write operation.
    A value of 1 makes the function block until the write is complete.
    A value of 0 makes it non blocking.
    A positive value specifies the maximum time (in milliseconds) to wait.
    **return** int Returns the number of bytes written on success, or a value less than 0 on failure. **static** True > C++ defination code: > ```cpp > static int write_coils(const std::string ip, const int port, > const std::vector& data, > const uint32_t addr, const int timeout_ms 1) > ``` #### read\\_discrete\\_input {#read\\_discrete\\_input 2} Reads discrete inputs from the Modbus device.\\nThis function reads a specified number of discrete inputs starting from a given address. item description **type** func **param** **ip**: The TCP IP address.
    **addr**: The starting address for reading discrete inputs.
    **size**: The number of discrete inputs to read.
    **timeout_ms**: The timeout duration for the write operation.
    A value of 1 makes the function block until the write is complete.
    A value of 0 makes it non blocking.
    A positive value specifies the maximum time (in milliseconds) to wait.
    **port**: The TCP port. A value of 1 signifies that the default port
    from the constructor will be applied.
    **return** std::vector/list[int] A vector containing the read discrete input values. **static** False > C++ defination code: > ```cpp > std::vector read_discrete_input(const std::string ip, const uint32_t addr, > const uint32_t size, const int timeout_ms 1, > const int port 1) > ``` #### read\\_discrete\\_input (overload 1) {#read\\_discrete\\_input (overload 1) 2} Reads discrete inputs from the Modbus device.\\nThis function reads a specified number of discrete inputs starting from a given address. item description **type** func **param** **ip**: The TCP IP address.
    **port**: The TCP port.
    **addr**: The starting address for reading discrete inputs.
    **size**: The number of discrete inputs to read.
    **timeout_ms**: The timeout duration for the write operation.
    A value of 1 makes the function block until the write is complete.
    A value of 0 makes it non blocking.
    A positive value specifies the maximum time (in milliseconds) to wait.
    **return** std::vector/list[int] A vector containing the read discrete input values. **static** True > C++ defination code: > ```cpp > static std::vector read_discrete_input(const std::string ip, const int port, > const uint32_t addr, > const uint32_t size, const int timeout_ms 1) > ``` #### read\\_input\\_registers {#read\\_input\\_registers 2} Reads input registers from the Modbus device.\\nThis function reads a specified number of input registers starting from a given address. item description **type** func **param** **ip**: The TCP IP address.
    **addr**: The starting address for reading input registers.
    **size**: The number of input registers to read.
    **timeout_ms**: The timeout duration for the write operation.
    A value of 1 makes the function block until the write is complete.
    A value of 0 makes it non blocking.
    A positive value specifies the maximum time (in milliseconds) to wait.
    **port**: The TCP port. A value of 1 signifies that the default port
    from the constructor will be applied.
    **return** std::vector/list[int] A vector containing the read input register values. **static** False > C++ defination code: > ```cpp > std::vector read_input_registers(const std::string ip, const uint32_t addr, > const uint32_t size, const int timeout_ms 1, > const int port 1) > ``` #### read\\_input\\_registers (overload 1) {#read\\_input\\_registers (overload 1) 2} Reads input registers from the Modbus device.\\nThis function reads a specified number of input registers starting from a given address. item description **type** func **param** **ip**: The TCP IP address.
    **port**: The TCP port.
    **addr**: The starting address for reading input registers.
    **size**: The number of input registers to read.
    **timeout_ms**: The timeout duration for the write operation.
    A value of 1 makes the function block until the write is complete.
    A value of 0 makes it non blocking.
    A positive value specifies the maximum time (in milliseconds) to wait.
    **return** std::vector/list[int] A vector containing the read input register values. **static** True > C++ defination code: > ```cpp > static std::vector read_input_registers(const std::string ip, const int port, > const uint32_t addr, > const uint32_t size, const int timeout_ms 1) > ``` #### read\\_holding\\_registers {#read\\_holding\\_registers 2} Reads holding registers from the Modbus device.\\nThis function reads a specified number of holding registers starting from a given address. item description **type** func **param** **ip**: The TCP IP address.
    **addr**: The starting address for reading holding registers.
    **size**: The number of holding registers to read.
    **timeout_ms**: The timeout duration for the write operation.
    A value of 1 makes the function block until the write is complete.
    A value of 0 makes it non blocking.
    A positive value specifies the maximum time (in milliseconds) to wait.
    **port**: The TCP port. A value of 1 signifies that the default port
    from the constructor will be applied.
    **return** std::vector/list[int] A vector containing the read holding register values. **static** False > C++ defination code: > ```cpp > std::vector read_holding_registers(const std::string ip, const uint32_t addr, > const uint32_t size, const int timeout_ms 1, > const int port 1) > ``` #### read\\_holding\\_registers (overload 1) {#read\\_holding\\_registers (overload 1) 2} Reads holding registers from the Modbus device.\\nThis function reads a specified number of holding registers starting from a given address. item description **type** func **param** **ip**: The TCP IP address.
    **port**: The TCP port.
    **addr**: The starting address for reading holding registers.
    **size**: The number of holding registers to read.
    **timeout_ms**: The timeout duration for the write operation.
    A value of 1 makes the function block until the write is complete.
    A value of 0 makes it non blocking.
    A positive value specifies the maximum time (in milliseconds) to wait.
    **return** std::vector/list[int] A vector containing the read holding register values. **static** True > C++ defination code: > ```cpp > static std::vector read_holding_registers(const std::string ip, const int port, > const uint32_t addr, > const uint32_t size, const int timeout_ms 1) > ``` #### write\\_holding\\_registers {#write\\_holding\\_registers 2} Writes values to holding registers on the Modbus device.\\nThis function writes the specified data to the holding registers starting from a given address. item description **type** func **param** **ip**: The TCP IP address.
    **data**: A vector containing the values to write to holding registers.
    **addr**: The starting address for writing holding registers.
    **timeout_ms**: The timeout duration for the write operation.
    A value of 1 makes the function block until the write is complete.
    A value of 0 makes it non blocking.
    A positive value specifies the maximum time (in milliseconds) to wait.
    **port**: The TCP port. A value of 1 signifies that the default port
    from the constructor will be applied.
    **return** int Returns the number of bytes written on success, or a value less than 0 on failure. **static** False > C++ defination code: > ```cpp > int write_holding_registers(const std::string ip, const std::vector& data, > const uint32_t addr, const int timeout_ms 1, > const int port 1) > ``` #### write\\_holding\\_registers (overload 1) {#write\\_holding\\_registers (overload 1) 2} Writes values to holding registers on the Modbus device.\\nThis function writes the specified data to the holding registers starting from a given address. item description **type** func **param** **ip**: The TCP IP address.
    **port**: The TCP port.
    **data**: A vector containing the values to write to holding registers.
    **addr**: The starting address for writing holding registers.
    **timeout_ms**: The timeout duration for the write operation.
    A value of 1 makes the function block until the write is complete.
    A value of 0 makes it non blocking.
    A positive value specifies the maximum time (in milliseconds) to wait.
    **return** int Returns the number of bytes written on success, or a value less than 0 on failure. **static** True > C++ defination code: > ```cpp > static int write_holding_registers(const std::string ip, const int port, > const std::vector& data, > const uint32_t addr, const int timeout_ms 1) > ```"},"/maixcdk/api/maix/modbus/Slave.html":{"title":"maix::modbus::Slave","content":" title: maix::modbus::Slave maix.modbus.Slave module > This is `maix::modbus::Slave` module of [MaixCDK](https://github.com/sipeed/MaixCDK). > All of these elements are in namespace `maix::modbus::Slave`. > > For MaixCDK developer: DO NOT edit this doc file manually, this doc is auto generated! ## Module {#Module} No module ## Enum {#Enum} ## Variable {#Variable} ## Function {#Function} ### \\_\\_init\\_\\_ {#\\_\\_init\\_\\_} Constructor for creating a Modbus Slave instance with specified registers.\\nThis constructor initializes a Modbus Slave using the provided mode and connection\\nparameters. It also allows for defining register information through a\\n`Registers` object, enabling easier management of multiple registers at once. item description **param** **mode**: Specifies the communication mode: RTU or TCP.
    **ip_or_device**: The UART device name if using RTU mode.
    If TCP mode is chosen, this parameter is ignored.
    **registers**: A Registers object that holds starting addresses and sizes
    for coils, discrete inputs, holding registers, and input registers.
    This allows the user to set up the Slave's register configuration
    in a structured manner.
    **rtu_baud**: The baud rate for RTU communication.
    Supported rates include: 110, 300, 600, 1200, 2400, 4800,
    9600, 19200, 38400, 57600, 115200, 230400, 460800,
    500000, 576000, 921600, 1000000, 1152000, 1500000,
    2500000, 3000000, 3500000, 4000000.
    Default is 115200. Ensure that the selected baud rate
    is supported by the underlying hardware and libmodbus.
    **rtu_slave**: The RTU slave address. Ignored in TCP mode. Default is 1.
    **tcp_port**: The port used for TCP communication. Ignored in RTU mode. Default is 502.
    **debug**: A boolean flag to enable or disable debug mode. Default is false.
    **see** modbus.Mode for valid modes. > C++ defination code: > ```cpp > Slave(maix::comm::modbus::Mode mode, const std::string& ip_or_device, > const Registers& registers Registers{}, > int rtu_baud 115200, uint8_t rtu_slave 1, > int tcp_port 502, bool debug false) > ``` ## Class {#Class}"},"/maixcdk/api/maix/rtmp.html":{"title":"maix::rtmp","content":" title: maix::rtmp maix.rtmp module > This is `maix::rtmp` module of [MaixCDK](https://github.com/sipeed/MaixCDK). > All of these elements are in namespace `maix::rtmp`. > > For MaixCDK developer: DO NOT edit this doc file manually, this doc is auto generated! ## Module {#Module} No module ## Enum {#Enum} ### TagType {#TagType} Video type item describe **values** **TAG_NONE**:
    **TAG_VIDEO**:
    **TAG_AUDIO**:
    **TAG_SCRIPT**:
    > C++ defination code: > ```cpp > enum TagType > { > TAG_NONE, > TAG_VIDEO, > TAG_AUDIO, > TAG_SCRIPT, > } > ``` ## Variable {#Variable} ## Function {#Function} ## Class {#Class} ### Rtmp {#Rtmp} Rtmp class > C++ defination code: > ```cpp > class Rtmp > ``` #### Rtmp {#Rtmp 2} Construct a new Video object item description **type** func **note** Rtmp url : rtmp://host:prot/app/stream
    example:
    r Rtmp(\"localhost\", 1935, \"live\", \"stream\")
    means rtmp url is rtmp://localhost:1935/live/stream **param** **host**: rtmp ip
    **port**: rtmp port, default is 1935.
    **app**: rtmp app name
    **stream**: rtmp stream name
    **bitrate**: rtmp bitrate, default is 1000 * 1000
    **static** False > C++ defination code: > ```cpp > Rtmp(std::string host \"localhost\", int port 1935, std::string app std::string(), std::string stream std::string(), int bitrate 1000 * 1000) > ``` #### push\\_video {#push\\_video} Get bitrate item description **type** func **return** bitrate **static** False > C++ defination code: > ```cpp > int bitrate() > ``` #### push\\_video (overload 1) {#push\\_video (overload 1)} Push rtmp video data item description **type** func **return** return 0 ok, other error **static** False > C++ defination code: > ```cpp > int push_video(void *data, size_t data_size, uint32_t timestamp) > ``` #### push\\_audio {#push\\_audio} Push rtmp audio data item description **type** func **return** return 0 ok, other error **static** False > C++ defination code: > ```cpp > int push_audio(void *data, size_t data_size, uint32_t timestamp) > ``` #### push\\_script {#push\\_script} Push rtmp script data item description **type** func **return** return 0 ok, other error **static** False > C++ defination code: > ```cpp > int push_script(void *data, size_t data_size, uint32_t timestamp) > ``` #### bind\\_camera {#bind\\_camera} Bind camera item description **type** func **note** If the cam object is bound, the cam object cannot be used elsewhere. **param** **cam**: camera object
    **return** error code, err::ERR_NONE means success, others means failed **static** False > C++ defination code: > ```cpp > err::Err bind_camera(camera::Camera *cam) > ``` #### bind\\_audio\\_recorder {#bind\\_audio\\_recorder} Bind audio recorder item description **type** func **note** If the audio_recorder object is bound, the audio_recorder object cannot be used elsewhere. **param** **recorder**: audio_recorder object
    **return** error code, err::ERR_NONE means success, others means failed **static** False > C++ defination code: > ```cpp > err::Err bind_audio_recorder(audio::Recorder *recorder) > ``` #### bind\\_display {#bind\\_display} Bind display item description **type** func **note** If the display object is bound, the display object cannot be used elsewhere. **param** **disaply**: display object
    **return** error code, err::ERR_NONE means success, others means failed **static** False > C++ defination code: > ```cpp > err::Err bind_display(display::Display *display) > ``` #### get\\_camera {#get\\_camera} If you bind a camera, return the camera object. item description **type** func **return** Camera object **static** False > C++ defination code: > ```cpp > camera::Camera *get_camera() > ``` #### capture {#capture} If you bind a camera, capture the image of the camera item description **type** func **note** The return value may be null, you must check whether the return value is null **return** Image object **static** False > C++ defination code: > ```cpp > image::Image *capture() > ``` #### start {#start} Start push stream item description **type** func **note** only support flv file now **param** **path**: File path, if you passed file path, cyclic push the file, else if you bound camera, push the camera image.(This parameter has been deprecated)
    **return** error code, err::ERR_NONE means success, others means failed **static** False > C++ defination code: > ```cpp > err::Err start(std::string path std::string()) > ``` #### stop {#stop} Stop push stream item description **type** func **return** error code, err::ERR_NONE means success, others means failed **static** False > C++ defination code: > ```cpp > err::Err stop() > ``` #### lock {#lock} Lock item description **type** func **param** **time**: lock time, unit:ms
    **return** error code, err::ERR_NONE means success, others means failed **static** False > C++ defination code: > ```cpp > err::Err lock(uint32_t time) > ``` #### unlock {#unlock} Unlock item description **type** func **return** error code, err::ERR_NONE means success, others means failed **static** False > C++ defination code: > ```cpp > err::Err unlock() > ``` #### get\\_path {#get\\_path} Get the file path of the push stream item description **type** func **return** file path **static** False > C++ defination code: > ```cpp > std::string get_path() > ``` #### get\\_path (overload 1) {#get\\_path (overload 1)} Check whether push streaming has started item description **type** func **return** If rtmp thread is running, returns true **static** False > C++ defination code: > ```cpp > bool is_started() > ```"},"/maixcdk/api/maix/video.html":{"title":"maix::video","content":" title: maix::video maix.video module > This is `maix::video` module of [MaixCDK](https://github.com/sipeed/MaixCDK). > All of these elements are in namespace `maix::video`. > > For MaixCDK developer: DO NOT edit this doc file manually, this doc is auto generated! ## Module {#Module} No module ## Enum {#Enum} ### VideoType {#VideoType} Video type item describe **values** **VIDEO_NONE**: format invalid
    **VIDEO_ENC_H265_CBR**: Deprecated
    **VIDEO_ENC_MP4_CBR**: Deprecated
    **VIDEO_DEC_H265_CBR**: Deprecated
    **VIDEO_DEC_MP4_CBR**: Deprecated
    **VIDEO_H264_CBR**: Deprecated
    **VIDEO_H265_CBR**: Deprecated
    **VIDEO_H264_CBR_MP4**: Deprecated
    **VIDEO_H265_CBR_MP4**: Deprecated
    **VIDEO_H264**:
    **VIDEO_H264_MP4**:
    **VIDEO_H264_FLV**:
    **VIDEO_H265**:
    **VIDEO_H265_MP4**:
    > C++ defination code: > ```cpp > enum VideoType > { > VIDEO_NONE 0, // format invalid > VIDEO_ENC_H265_CBR, // Deprecated > VIDEO_ENC_MP4_CBR, // Deprecated > VIDEO_DEC_H265_CBR, // Deprecated > VIDEO_DEC_MP4_CBR, // Deprecated > VIDEO_H264_CBR, // Deprecated > VIDEO_H265_CBR, // Deprecated > VIDEO_H264_CBR_MP4, // Deprecated > VIDEO_H265_CBR_MP4, // Deprecated > > VIDEO_H264, > VIDEO_H264_MP4, > VIDEO_H264_FLV, > VIDEO_H265, > VIDEO_H265_MP4, > } > ``` ### MediaType {#MediaType} Video type item describe **values** **MEDIA_TYPE_UNKNOWN**: Represents an unknown media type, which is usually treated as AVMEDIA_TYPE_DATA.
    **MEDIA_TYPE_VIDEO**: Represents a video stream, such as video content encoded in H.264, MPEG 4, etc.
    **MEDIA_TYPE_AUDIO**: Represents an audio stream, such as audio content encoded in AAC, MP3, etc.
    **MEDIA_TYPE_DATA**: Represents opaque data streams that are usually continuous. This type of stream is not necessarily audio or video and may be used for other data purposes.
    **MEDIA_TYPE_SUBTITLE**: Represents a subtitle stream used for displaying text or subtitle information, such as SRT, ASS, etc.
    **MEDIA_TYPE_ATTACHMENT**: Represents attachment streams that are usually sparse. Attachment streams can include images, fonts, or other files that need to be bundled with the media.
    **MEDIA_TYPE_NB**: Represents the number of media types (count) and indicates the total number of media types defined in this enumeration. It is not a media type itself but is used for counting enumeration items.
    > C++ defination code: > ```cpp > enum MediaType > { > MEDIA_TYPE_UNKNOWN 1, // Represents an unknown media type, which is usually treated as AVMEDIA_TYPE_DATA. > MEDIA_TYPE_VIDEO, // Represents a video stream, such as video content encoded in H.264, MPEG 4, etc. > MEDIA_TYPE_AUDIO, // Represents an audio stream, such as audio content encoded in AAC, MP3, etc. > MEDIA_TYPE_DATA, // Represents opaque data streams that are usually continuous. This type of stream is not necessarily audio or video and may be used for other data purposes. > MEDIA_TYPE_SUBTITLE, // Represents a subtitle stream used for displaying text or subtitle information, such as SRT, ASS, etc. > MEDIA_TYPE_ATTACHMENT, // Represents attachment streams that are usually sparse. Attachment streams can include images, fonts, or other files that need to be bundled with the media. > MEDIA_TYPE_NB // Represents the number of media types (count) and indicates the total number of media types defined in this enumeration. It is not a media type itself but is used for counting enumeration items. > } > ``` ## Variable {#Variable} ## Function {#Function} ### timebase\\_to\\_us {#timebase\\_to\\_us} Convert a value in timebase units to microseconds. value * 1000000 / (timebase[1] / timebase[0]) item description **param** **timebse**: Time base, used as the unit for calculating playback time. It must be an array containing two parameters,
    in the format [num, den], where the first parameter is the numerator of the time base, and the second parameter is the denominator of the time base.
    **value**: Input value
    **return** Return the result in microseconds. > C++ defination code: > ```cpp > double timebase_to_us(std::vector timebase, uint64_t value) > ``` ### timebase\\_to\\_ms {#timebase\\_to\\_ms} Convert a value in timebase units to milliseconds. item description **param** **timebse**: Time base, used as the unit for calculating playback time. It must be an array containing two parameters,
    in the format [num, den], where the first parameter is the numerator of the time base, and the second parameter is the denominator of the time base.
    **value**: Input value
    **return** Return the result in milliseconds. > C++ defination code: > ```cpp > double timebase_to_ms(std::vector timebase, uint64_t value) > ``` ## Class {#Class} ### Context {#Context} Context class > C++ defination code: > ```cpp > class Context > ``` #### Context {#Context 2} Construct a new Context object item description **type** func **param** **media_type**: enable capture, if true, you can use capture() function to get an image object
    **timebase**: Time base, used as the unit for calculating playback time. It must be an array containing two parameters,
    in the format [num, den], where the first parameter is the numerator of the time base, and the second parameter is the denominator of the time base.
    **static** False > C++ defination code: > ```cpp > Context(video::MediaType media_type, std::vector timebase) > ``` #### Context (overload 1) {#Context (overload 1)} Construct a new Context object item description **type** func **param** **media_type**: enable capture, if true, you can use capture() function to get an image object
    **timebase**: Time base, used as the unit for calculating playback time. It must be an array containing two parameters,
    in the format [num, den], where the first parameter is the numerator of the time base, and the second parameter is the denominator of the time base.
    **sample_rate**: sampling rate of audio
    **format**: audio format
    **channels**: number of audio channels
    **static** False > C++ defination code: > ```cpp > Context(video::MediaType media_type, std::vector timebase, int sample_rate, audio::Format format, int channels) > ``` #### audio\\_sample\\_rate {#audio\\_sample\\_rate} Get sample rate of audio (only valid in the context of audio) item description **type** func **return** sample rate **static** False > C++ defination code: > ```cpp > int audio_sample_rate() > ``` #### audio\\_sample\\_rate (overload 1) {#audio\\_sample\\_rate (overload 1)} Get sample rate of audio (only valid in the context of audio) item description **type** func **return** sample rate **static** False > C++ defination code: > ```cpp > int audio_sample_rate() > ``` #### audio\\_channels {#audio\\_channels} Get channels of audio (only valid in the context of audio) item description **type** func **return** channels **static** False > C++ defination code: > ```cpp > int audio_channels() > ``` #### audio\\_channels (overload 1) {#audio\\_channels (overload 1)} Get channels of audio (only valid in the context of audio) item description **type** func **return** channels **static** False > C++ defination code: > ```cpp > int audio_channels() > ``` #### audio\\_format {#audio\\_format} Get format of audio (only valid in the context of audio) item description **type** func **return** audio format. @see audio::Format **static** False > C++ defination code: > ```cpp > audio::Format audio_format() > ``` #### audio\\_format (overload 1) {#audio\\_format (overload 1)} Get format of audio (only valid in the context of audio) item description **type** func **return** audio format. @see audio::Format **static** False > C++ defination code: > ```cpp > audio::Format audio_format() > ``` #### set\\_pcm {#set\\_pcm} Set pcm data (only valid in the context of audio) item description **type** func **param** **duration**: Duration of the current pcm. unit: timebase
    **pts**: The start time of this pcm playback. If it is 0, it means this parameter is not supported. unit: timebase
    **return** err::Err **static** False > C++ defination code: > ```cpp > err::Err set_pcm(maix::Bytes *data, int duration 0, uint64_t pts 0, bool copy true) > ``` #### get\\_pcm {#get\\_pcm} Get pcm data (only valid in the context of audio) item description **type** func **attention** Note that if you call this interface, you are responsible for releasing the memory of the data, and this interface cannot be called again. **return** Bytes **static** False > C++ defination code: > ```cpp > Bytes *get_pcm() > ``` #### set\\_image {#set\\_image} Set image info item description **type** func **param** **image**: image data
    **duration**: Duration of the current image. unit: timebase
    **pts**: The start time of this image playback. If it is 0, it means this parameter is not supported. unit: timebase
    **last_pts**: The start time of the previous image playback. It can be used to ensure the playback order. If it is 0, it means this parameter is not supported. unit: timebase
    **static** False > C++ defination code: > ```cpp > void set_image(image::Image *image, int duration 0, uint64_t pts 0, uint64_t last_pts 0) > ``` #### set\\_raw\\_data {#set\\_raw\\_data} Set private data item description **type** func **param** **data**: private raw data
    **data_size**: private raw data size
    **duration**: Duration of the current image. unit: timebase
    **pts**: The start time of this image playback. If it is 0, it means this parameter is not supported. unit: timebase
    **last_pts**: The start time of the previous image playback. It can be used to ensure the playback order. If it is 0, it means this parameter is not supported. unit: timebase
    **static** False > C++ defination code: > ```cpp > void set_raw_data(void *data, size_t data_size, int duration 0, uint64_t pts 0, uint64_t last_pts 0, bool copy false) > ``` #### get\\_raw\\_data {#get\\_raw\\_data} Get private data item description **type** func **static** False > C++ defination code: > ```cpp > void *get_raw_data() > ``` #### image {#image} Retrieve the image data to be played. item description **type** func **attention** Note that if you call this interface, you are responsible for releasing the memory of the image, and this interface cannot be called again. **static** False > C++ defination code: > ```cpp > image::Image *image() > ``` #### media\\_type {#media\\_type} Get the media type to determine whether it is video, audio, or another media type. item description **type** func **static** False > C++ defination code: > ```cpp > video::MediaType media_type() > ``` #### pts {#pts} Get the start time of the current playback., in units of time base. item description **type** func **static** False > C++ defination code: > ```cpp > uint64_t pts() > ``` #### last\\_pts {#last\\_pts} Get the start time of the previous playback, in units of time base. item description **type** func **static** False > C++ defination code: > ```cpp > uint64_t last_pts() > ``` #### timebase {#timebase} Get the time base. item description **type** func **static** False > C++ defination code: > ```cpp > std::vector timebase() > ``` #### duration {#duration} Duration of the current frame. unit: timebase item description **type** func **static** False > C++ defination code: > ```cpp > int duration() > ``` #### duration\\_us {#duration\\_us} Duration of the current frame. unit: us item description **type** func **static** False > C++ defination code: > ```cpp > uint64_t duration_us() > ``` ### Frame {#Frame} Frame class > C++ defination code: > ```cpp > class Frame > ``` #### Frame {#Frame 2} Frame object item description **type** func **param** **data**: src data pointer, use pointers directly without copying.
    Note: this object will try to free this memory
    **len**: data len
    **pts**: presentation time stamp. unit: time_base
    **dts**: decoding time stamp. unit: time_base
    **duration**: packet display time. unit: time_base (not used)
    **auto_detele**: if true, will delete data when destruct. When copy is true, this arg will be ignore.
    **copy**: data will be copy to new buffer if true, if false, will use data directly,
    default true to ensure memory safety.
    **static** False > C++ defination code: > ```cpp > Frame(uint8_t *data, int len, uint64_t pts 1, uint64_t dts 1, int64_t duration 0, bool auto_detele false, bool copy false) > ``` #### Frame (overload 1) {#Frame (overload 1)} Frame number (pair of numerator and denominator). item description **type** func **static** False > C++ defination code: > ```cpp > Frame() > ``` #### get {#get} Get raw data of packet item description **type** func **param** **data**: data pointer
    **len**: data length pointer
    **return** raw data **static** False > C++ defination code: > ```cpp > err::Err get(void **data, int *len) > ``` #### to\\_bytes {#to\\_bytes} Get raw data of packet item description **type** func **param** **copy**: if true, will alloc memory and copy data to new buffer
    **return** raw data **static** False > C++ defination code: > ```cpp > Bytes *to_bytes(bool copy false) > ``` #### size {#size} Get raw data size of packet item description **type** func **return** size of raw data **static** False > C++ defination code: > ```cpp > size_t size() > ``` #### is\\_valid {#is\\_valid} Check packet is valid item description **type** func **return** true, packet is valid; false, packet is invalid **static** False > C++ defination code: > ```cpp > bool is_valid() > ``` #### set\\_pts {#set\\_pts} Set pts item description **type** func **param** **pts**: presentation time stamp. unit: time_base
    **static** False > C++ defination code: > ```cpp > void set_pts(uint64_t pts) > ``` #### set\\_dts {#set\\_dts} Set dts item description **type** func **param** **dts**: decoding time stamp. unit: time_base
    **static** False > C++ defination code: > ```cpp > void set_dts(uint64_t dts) > ``` #### set\\_duration {#set\\_duration} Set duration item description **type** func **param** **duration**: packet display time. unit: time_base
    **static** False > C++ defination code: > ```cpp > void set_duration(uint64_t duration) > ``` #### get\\_pts {#get\\_pts} Set pts item description **type** func **param** **pts**: presentation time stamp. unit: time_base
    **return** pts value **static** False > C++ defination code: > ```cpp > uint64_t get_pts() > ``` #### get\\_dts {#get\\_dts} Set dts item description **type** func **param** **dts**: decoding time stamp. unit: time_base
    **return** dts value **static** False > C++ defination code: > ```cpp > uint64_t get_dts() > ``` #### get\\_duration {#get\\_duration} Get duration item description **type** func **return** duration value **static** False > C++ defination code: > ```cpp > uint64_t get_duration() > ``` #### type {#type} Get frame type item description **type** func **return** video type. @see video::VideoType **static** False > C++ defination code: > ```cpp > video::VideoType type() > ``` ### Packet {#Packet} Packet class > C++ defination code: > ```cpp > class Packet > ``` #### Packet {#Packet 2} Packet number (pair of numerator and denominator). item description **type** func **param** **data**: src data pointer, use pointers directly without copying.
    Note: this object will try to free this memory
    **len**: data len
    **pts**: presentation time stamp. unit: time_base
    **dts**: decoding time stamp. unit: time_base
    **duration**: packet display time. unit: time_base
    **static** False > C++ defination code: > ```cpp > Packet(uint8_t *data, int len, uint64_t pts 1, uint64_t dts 1, int64_t duration 0) > ``` #### Packet (overload 1) {#Packet (overload 1)} Packet number (pair of numerator and denominator). item description **type** func **static** False > C++ defination code: > ```cpp > Packet() > ``` #### get {#get 2} Get raw data of packet item description **type** func **return** raw data **static** False > C++ defination code: > ```cpp > std::vector get() > ``` #### data {#data} Get raw data of packet item description **type** func **return** raw data **static** False > C++ defination code: > ```cpp > uint8_t *data() > ``` #### data\\_size {#data\\_size} Get raw data size of packet item description **type** func **return** size of raw data **static** False > C++ defination code: > ```cpp > size_t data_size() > ``` #### is\\_valid {#is\\_valid 2} Check packet is valid item description **type** func **return** true, packet is valid; false, packet is invalid **static** False > C++ defination code: > ```cpp > bool is_valid() > ``` #### set\\_pts {#set\\_pts 2} Set pts item description **type** func **param** **pts**: presentation time stamp. unit: time_base
    **return** true, packet is valid; false, packet is invalid **static** False > C++ defination code: > ```cpp > void set_pts(uint64_t pts) > ``` #### set\\_dts {#set\\_dts 2} Set dts item description **type** func **param** **dts**: decoding time stamp. unit: time_base
    **return** true, packet is valid; false, packet is invalid **static** False > C++ defination code: > ```cpp > void set_dts(uint64_t dts) > ``` #### set\\_duration {#set\\_duration 2} Set duration item description **type** func **param** **duration**: packet display time. unit: time_base
    **return** true, packet is valid; false, packet is invalid **static** False > C++ defination code: > ```cpp > void set_duration(uint64_t duration) > ``` ### Encoder {#Encoder} Encode class > C++ defination code: > ```cpp > class Encoder > ``` #### Encoder {#Encoder 2} Construct a new Video object item description **type** func **param** **width**: picture width. this value may be set automatically. default is 2560.
    **height**: picture height. this value may be set automatically. default is 1440.
    **format**: picture format. default is image::Format::FMT_YVU420SP. @see image::Format
    **type**: video encode/decode type. default is ENC_H265_CBR. @see EncodeType
    **framerate**: frame rate. framerate default is 30, means 30 frames per second
    for video. 1/time_base is not the average frame rate if the frame rate is not constant.
    **gop**: for h264/h265 encoding, the interval between two I frames, default is 50.
    **bitrate**: for h264/h265 encoding, used to limit the bandwidth used by compressed data, default is 3000kbps
    **time_base**: frame time base. time_base default is 1000, means 1/1000 ms (not used)
    **capture**: enable capture, if true, you can use capture() function to get an image object
    **block**: This parameter determines whether encoding should block until it is complete.
    If set to true, it will wait until encoding is finished before returning.
    If set to false, it will return the current encoding result on the next call.
    **static** False > C++ defination code: > ```cpp > Encoder(std::string path \"\", int width 2560, int height 1440, image::Format format image::Format::FMT_YVU420SP, video::VideoType type video::VideoType::VIDEO_H264, int framerate 30, int gop 50, int bitrate 3000 * 1000, int time_base 1000, bool capture false, bool block true) > ``` #### bind\\_camera {#bind\\_camera} Bind camera item description **type** func **param** **camera**: camera object
    **return** error code, err::ERR_NONE means success, others means failed **static** False > C++ defination code: > ```cpp > err::Err bind_camera(camera::Camera *camera) > ``` #### encode {#encode} Encode image. item description **type** func **param** **img**: the image will be encode.
    if the img is NULL, this function will try to get image from camera, you must use bind_camera() function to bind the camera.
    **pcm**: the pcm data will be encode.
    **return** encode result **static** False > C++ defination code: > ```cpp > video::Frame *encode(image::Image *img maix::video::Encoder::NoneImage, Bytes *pcm maix::video::Encoder::NoneBytes) > ``` #### capture {#capture} Capture image item description **type** func **attention** Each time encode is called, the last captured image will be released. **return** error code **static** False > C++ defination code: > ```cpp > image::Image *capture() > ``` #### width {#width} Get video width item description **type** func **return** video width **static** False > C++ defination code: > ```cpp > int width() > ``` #### height {#height} Get video height item description **type** func **return** video height **static** False > C++ defination code: > ```cpp > int height() > ``` #### format {#format} Get video format item description **type** func **return** video format **static** False > C++ defination code: > ```cpp > image::Format format() > ``` #### type {#type 2} Get video encode type item description **type** func **return** VideoType **static** False > C++ defination code: > ```cpp > video::VideoType type() > ``` #### framerate {#framerate} Get video encode framerate item description **type** func **return** frame rate **static** False > C++ defination code: > ```cpp > int framerate() > ``` #### gop {#gop} Get video encode gop item description **type** func **return** gop value **static** False > C++ defination code: > ```cpp > int gop() > ``` #### bitrate {#bitrate} Get video encode bitrate item description **type** func **return** bitrate value **static** False > C++ defination code: > ```cpp > int bitrate() > ``` #### time\\_base {#time\\_base} Get video encode time base item description **type** func **return** time base value **static** False > C++ defination code: > ```cpp > int time_base() > ``` #### get\\_pts {#get\\_pts 2} Get current pts, unit: time_base\\nNote: The current default is to assume that there is no B frame implementation, so pts and bts are always the same item description **type** func **param** **time_ms**: start time from the first frame. unit: ms
    **return** time base value **static** False > C++ defination code: > ```cpp > uint64_t get_pts(uint64_t time_ms) > ``` #### get\\_dts {#get\\_dts 2} Get current dts, unit: time_base\\nNote: The current default is to assume that there is no B frame implementation, so pts and bts are always the same item description **type** func **param** **time_ms**: start time from the first frame. unit: ms
    **return** time base value **static** False > C++ defination code: > ```cpp > uint64_t get_dts(uint64_t time_ms) > ``` ### Decoder {#Decoder} Decoder class > C++ defination code: > ```cpp > class Decoder > ``` #### Decoder {#Decoder 2} Construct a new decoder object item description **type** func **param** **path**: Path to the file to be decoded. Supports files with .264 and .mp4 extensions. Note that only mp4 files containing h.264 streams are supported.
    **format**: Decoded output format, currently only support YUV420SP
    **static** False > C++ defination code: > ```cpp > Decoder(std::string path, image::Format format image::Format::FMT_YVU420SP) > ``` #### decode\\_video {#decode\\_video} Decode the video stream, returning the image of the next frame each time. item description **type** func **param** **block**: Whether it blocks or not. If true, it will wait for the decoding to complete and return the current frame.
    If false, it will return the result of the previous frame's decoding. If the previous frame's decoding result is empty,
    it will return an unknown Context, and you can use the media_type method of the Context to determine if a valid result exists.
    default is true.
    **return** Decoded context information. **static** False > C++ defination code: > ```cpp > video::Context * decode_video(bool block true) > ``` #### decode\\_audio {#decode\\_audio} Decode the video stream, returning the image of the next frame each time. item description **type** func **return** Decoded context information. **static** False > C++ defination code: > ```cpp > video::Context * decode_audio() > ``` #### decode {#decode} Decode the video and audio stream item description **type** func **param** **block**: Whether it blocks or not. If true, it will wait for the decoding to complete and return the current frame.
    If false, it will return the result of the previous frame's decoding. If the previous frame's decoding result is empty,
    it will return an unknown Context, and you can use the media_type method of the Context to determine if a valid result exists.
    default is true.
    **return** Decoded context information. **static** False > C++ defination code: > ```cpp > video::Context * decode(bool block true) > ``` #### unpack {#unpack} Unpacking the video and audio stream item description **type** func **return** Unpacking context information. **static** False > C++ defination code: > ```cpp > video::Context * unpack() > ``` #### width {#width 2} Get the video width item description **type** func **return** video width **static** False > C++ defination code: > ```cpp > int width() > ``` #### height {#height 2} Get the video height item description **type** func **return** video height **static** False > C++ defination code: > ```cpp > int height() > ``` #### bitrate {#bitrate 2} Get the video bitrate item description **type** func **return** bitrate value **static** False > C++ defination code: > ```cpp > int bitrate() > ``` #### fps {#fps} Get the video fps item description **type** func **return** fps value **static** False > C++ defination code: > ```cpp > int fps() > ``` #### seek {#seek} Seek to the required playback position item description **type** func **param** **time**: timestamp value, unit: s
    **return** return the current position, unit: s **static** False > C++ defination code: > ```cpp > double seek(double time 1) > ``` #### duration {#duration 2} Get the maximum duration of the video. If it returns 0, it means it cannot be predicted. item description **type** func **return** duration value, unit: s **static** False > C++ defination code: > ```cpp > double duration() > ``` #### timebase {#timebase 2} Get the time base. item description **type** func **static** False > C++ defination code: > ```cpp > std::vector timebase() > ``` #### has\\_audio {#has\\_audio} If find audio data, return true item description **type** func **static** False > C++ defination code: > ```cpp > bool has_audio() > ``` #### has\\_video {#has\\_video} If find video data, return true item description **type** func **static** False > C++ defination code: > ```cpp > bool has_video() > ``` ### Video {#Video} Video class > C++ defination code: > ```cpp > class Video > ``` #### Video {#Video 2} Construct a new Video object item description **type** func **param** **path**: video path. the path determines the location where you load or save the file, if path is none, the video module will not save or load file.
    xxx.h265 means video format is H265, xxx.mp4 means video format is MP4
    **width**: picture width. this value may be set automatically. default is 2560.
    **height**: picture height. this value may be set automatically. default is 1440.
    **format**: picture pixel format. this value may be set automatically. default is FMT_YVU420SP.
    **time_base**: frame time base. time_base default is 30, means 1/30 ms
    **framerate**: frame rate. framerate default is 30, means 30 frames per second
    for video. 1/time_base is not the average frame rate if the frame rate is not constant.
    **capture**: enable capture, if true, you can use capture() function to get an image object
    **open**: If true, video will automatically call open() after creation. default is true.
    **static** False > C++ defination code: > ```cpp > Video(std::string path std::string(), int width 2560, int height 1440, image::Format format image::Format::FMT_YVU420SP, int time_base 30, int framerate 30, bool capture false, bool open true) > ``` #### open {#open} Open video and run item description **type** func **param** **path**: video path. the path determines the location where you load or save the file, if path is none, the video module will not save or load file.
    xxx.h265 means video format is H265, xxx.mp4 means video format is MP4
    **fps**: video fps
    **return** error code, err::ERR_NONE means success, others means failed **static** False > C++ defination code: > ```cpp > err::Err open(std::string path std::string(), double fps 30.0) > ``` #### close {#close} Close video item description **type** func **static** False > C++ defination code: > ```cpp > void close() > ``` #### bind\\_camera {#bind\\_camera 2} Bind camera item description **type** func **param** **camera**: camera object
    **return** error code, err::ERR_NONE means success, others means failed **static** False > C++ defination code: > ```cpp > err::Err bind_camera(camera::Camera *camera) > ``` #### encode {#encode 2} Encode image. item description **type** func **param** **img**: the image will be encode.
    if the img is NULL, this function will try to get image from camera, you must use bind_camera() function to bind the camera.
    **return** encode result **static** False > C++ defination code: > ```cpp > video::Packet *encode(image::Image *img maix::video::Video::NoneImage) > ``` #### decode {#decode 2} Decode frame item description **type** func **param** **frame**: the frame will be decode
    **return** decode result **static** False > C++ defination code: > ```cpp > image::Image *decode(video::Frame *frame nullptr) > ``` #### finish {#finish} Encode or decode finish item description **type** func **return** error code **static** False > C++ defination code: > ```cpp > err::Err finish() > ``` #### capture {#capture 2} Capture image item description **type** func **attention** Each time encode is called, the last captured image will be released. **return** error code **static** False > C++ defination code: > ```cpp > image::Image *capture() > ``` #### is\\_recording {#is\\_recording} Check if video is recording item description **type** func **return** true if video is recording, false if not **static** False > C++ defination code: > ```cpp > bool is_recording() > ``` #### is\\_opened {#is\\_opened} Check if video is opened item description **type** func **return** true if video is opened, false if not **static** False > C++ defination code: > ```cpp > bool is_opened() > ``` #### is\\_closed {#is\\_closed} check video device is closed or not item description **type** func **return** closed or not, bool type **static** False > C++ defination code: > ```cpp > bool is_closed() > ``` #### width {#width 3} Get video width item description **type** func **return** video width **static** False > C++ defination code: > ```cpp > int width() > ``` #### height {#height 3} Get video height item description **type** func **return** video height **static** False > C++ defination code: > ```cpp > int height() > ``` ### VideoRecorder {#VideoRecorder} Video Recorder class. This module is not fully supported and may be deprecated in the future. > C++ defination code: > ```cpp > class VideoRecorder > ``` #### VideoRecorder {#VideoRecorder 2} Construct a new VideoRecorder object. This is an object that integrates recording, video capturing, and display functions, which can be used to achieve high resolution video input when needed. item description **type** func **param** **open**: If true, video will automatically call open() after creation. default is true.
    **static** False > C++ defination code: > ```cpp > VideoRecorder(bool open true) > ``` #### lock {#lock} lock video item description **type** func **param** **timeout**: timeout in ms. unit:ms
    **return** error code **static** False > C++ defination code: > ```cpp > err::Err lock(int64_t timeout 1) > ``` #### unlock {#unlock} unlock video item description **type** func **return** error code **static** False > C++ defination code: > ```cpp > err::Err unlock() > ``` #### open {#open 2} Start a thread to handle the input function. item description **type** func **return** error code **static** False > C++ defination code: > ```cpp > err::Err open() > ``` #### close {#close 2} Stop the thread, and reset the object. item description **type** func **return** error code **static** False > C++ defination code: > ```cpp > err::Err close() > ``` #### is\\_opened {#is\\_opened 2} Check whether the object is opened. item description **type** func **static** False > C++ defination code: > ```cpp > bool is_opened() > ``` #### bind\\_display {#bind\\_display} Bind a Display object. if this object is not bound, it will not be displayed. item description **type** func **param** **display**: display object
    **fit**: fit mode. It is recommended to fill in FIT_COVER or FIT_FILL. For maixcam, using FIT_CONTAIN may affect the
    functionality of the second layer created by add_channel() in the Display. default is FIT_COVER.
    **return** error code **static** False > C++ defination code: > ```cpp > err::Err bind_display(display::Display *display, image::Fit fit image::FIT_COVER) > ``` #### bind\\_camera {#bind\\_camera 3} Bind a Camera object. if this object is not bound, images cannot be captured. item description **type** func **param** **camera**: camera object
    **return** error code **static** False > C++ defination code: > ```cpp > err::Err bind_camera(camera::Camera *camera) > ``` #### bind\\_audio {#bind\\_audio} Bind a AudioRecorder object. if this object is not bound, audio cannot be captured. item description **type** func **param** **audio**: audio recorder object
    **return** error code **static** False > C++ defination code: > ```cpp > err::Err bind_audio(audio::Recorder *audio) > ``` #### bind\\_imu {#bind\\_imu} Bind a IMU object. if this object is not bound, imu data cannot be captured. item description **type** func **param** **imu**: imu object
    **return** error code **static** False > C++ defination code: > ```cpp > err::Err bind_imu(void *imu) > ``` #### reset {#reset} Reset the video recorder. item description **type** func **note** It will not reset the bound object; if you have already bound the display using bind_display(), there is no need to rebind the display after calling reset(). **return** error code **static** False > C++ defination code: > ```cpp > err::Err reset() > ``` #### config\\_path {#config\\_path} The recorded video will be saved to this path, and this API cannot be called during runtime. item description **type** func **param** **path**: The path of the video file to be saved
    **return** error code **static** False > C++ defination code: > ```cpp > err::Err config_path(std::string path) > ``` #### get\\_path {#get\\_path} Get the path of the video file to be saved item description **type** func **return** path **static** False > C++ defination code: > ```cpp > std::string get_path() > ``` #### config\\_snapshot {#config\\_snapshot} Set the snapshot parameters item description **type** func **note** Enabling snapshot functionality may result in some performance loss. **param** **enable**: enable or disable snapshot
    **resolution**: image resolution of snapshot
    **format**: image format of snapshot
    **return** error code **static** False > C++ defination code: > ```cpp > err::Err config_snapshot(bool enable, std::vector resolution std::vector(), image::Format format image::Format::FMT_YVU420SP) > ``` #### config\\_resolution {#config\\_resolution} Set the resolution of the video, and this API cannot be called during runtime. item description **type** func **note** You must bind the camera first, and this interface will modify the camera's resolution. The width must be divisible by 32. **param** **resolution**: The resolution of the video
    **return** error code **static** False > C++ defination code: > ```cpp > err::Err config_resolution(std::vector resolution) > ``` #### get\\_resolution {#get\\_resolution} Get the resolution of the video item description **type** func **return** the resolution of the video **static** False > C++ defination code: > ```cpp > std::vector get_resolution() > ``` #### config\\_fps {#config\\_fps} Set the fps of the video, and this API cannot be called during runtime. item description **type** func **note** This interface only affect the fps of the encoded file. **return** error code **static** False > C++ defination code: > ```cpp > err::Err config_fps(int fps) > ``` #### get\\_fps {#get\\_fps} Get the fps of the video. item description **type** func **return** fps value **static** False > C++ defination code: > ```cpp > int get_fps() > ``` #### config\\_bitrate {#config\\_bitrate} Set the bitrate of the video, and this API cannot be called during runtime. item description **type** func **return** error code **static** False > C++ defination code: > ```cpp > err::Err config_bitrate(int bitrate) > ``` #### get\\_bitrate {#get\\_bitrate} Get the bitrate of the video. item description **type** func **return** bitrate value **static** False > C++ defination code: > ```cpp > int get_bitrate() > ``` #### mute {#mute} Set/Get the mute of the video item description **type** func **param** **data**: If the parameter is true, mute; if false, unmute; if no parameter is provided, return the mute status.
    **return** error code **static** False > C++ defination code: > ```cpp > int mute(int data 1) > ``` #### volume {#volume} Set/Get the volume of the video item description **type** func **param** **data**: The volume of the video, the range is 0 100. if no parameter is provided, return the volume.
    **return** error code **static** False > C++ defination code: > ```cpp > int volume(int data 1) > ``` #### seek {#seek 2} Get the current position of the video item description **type** func **return** current position, unit: ms **static** False > C++ defination code: > ```cpp > int64_t seek() > ``` #### record\\_start {#record\\_start} Start recording item description **type** func **note** You must bind the camera at a minimum during input. Additionally,
    if you bind a display, the input image will be shown,
    if you bind a audio, audio will be recorded,
    if you bind a IMU, IMU data will be logged. **return** error code **static** False > C++ defination code: > ```cpp > err::Err record_start() > ``` #### snapshot {#snapshot} Take a snapshot item description **type** func **return** image::Image **static** False > C++ defination code: > ```cpp > image::Image *snapshot() > ``` #### record\\_finish {#record\\_finish} Stop recording and save the video item description **type** func **return** error code **static** False > C++ defination code: > ```cpp > err::Err record_finish() > ``` #### draw\\_rect {#draw\\_rect} Draw a rect on the video item description **type** func **param** **id**: id of the rect, range is [0, 15]
    **x**: x coordinate
    **y**: y coordinate
    **w**: width
    **h**: height
    **color**: color
    **tickness**: The line width of the rectangular box; if set to 1, it indicates that the rectangular box will be filled.
    **hidden**: Hide or show the rectangular box
    **return** error code **static** False > C++ defination code: > ```cpp > err::Err draw_rect(int id, int x, int y, int w, int h, image::Color color image::COLOR_WHITE, int thickness 1, bool hidden false) > ```"},"/maixcdk/api/maix/nn.html":{"title":"maix::nn","content":" title: maix::nn maix.nn module > This is `maix::nn` module of [MaixCDK](https://github.com/sipeed/MaixCDK). > All of these elements are in namespace `maix::nn`. > > For MaixCDK developer: DO NOT edit this doc file manually, this doc is auto generated! ## Module {#Module} module brief [F](./nn/F.html) maix.nn.F module ## Enum {#Enum} ### SpeechDevice {#SpeechDevice} speech device item describe **values** **DEVICE_NONE**:
    **DEVICE_PCM**:
    **DEVICE_MIC**:
    **DEVICE_WAV**:
    > C++ defination code: > ```cpp > enum class SpeechDevice { > DEVICE_NONE 1, > DEVICE_PCM, > DEVICE_MIC, > DEVICE_WAV, > } > ``` ### SpeechDecoder {#SpeechDecoder} speech decoder type item describe **values** **DECODER_RAW**:
    **DECODER_DIG**:
    **DECODER_LVCSR**:
    **DECODER_KWS**:
    **DECODER_ALL**:
    > C++ defination code: > ```cpp > enum class SpeechDecoder { > DECODER_RAW 1, > DECODER_DIG 2, > DECODER_LVCSR 4, > DECODER_KWS 8, > DECODER_ALL 65535, > } > ``` ## Variable {#Variable} ## Function {#Function} ## Class {#Class} ### NanoTrack {#NanoTrack} NanoTrack class > C++ defination code: > ```cpp > class NanoTrack > ``` #### NanoTrack {#NanoTrack 2} Constructor of NanoTrack class item description **type** func **param** **model**: model path, default empty, you can load model later by load function.
    **throw** If model arg is not empty and load failed, will throw err::Exception. **static** False > C++ defination code: > ```cpp > NanoTrack(const string &model \"\") > ``` #### load {#load} Load model from file item description **type** func **param** **model**: Model path want to load
    **return** err::Err **static** False > C++ defination code: > ```cpp > err::Err load(const string &model) > ``` #### init {#init} Init tracker, give tacker first target image and target position. item description **type** func **param** **img**: Image want to detect, target should be in this image.
    **x**: the target position left top coordinate x.
    **y**: the target position left top coordinate y.
    **w**: the target width.
    **h**: the target height.
    **throw** If image format not match model input format, will throw err::Exception. **static** False > C++ defination code: > ```cpp > void init(image::Image &img, int x, int y, int w, int h) > ``` #### track {#track} Track object acoording to last object position and the init function learned target feature. item description **type** func **param** **img**: image to detect object and track, can be any resolution, before detect it will crop a area according to last time target's position.
    **threshold**: If score < threshold, will see this new detection is invalid, but remain return this new detecion, default 0.9.
    **return** object, position and score, and detect area in points's first 4 element(x, y, w, h, center_x, center_y, input_size, target_size) **static** False > C++ defination code: > ```cpp > nn::Object track(image::Image &img, float threshold 0.9) > ``` #### input\\_size {#input\\_size} Get model input size item description **type** func **return** model input size **static** False > C++ defination code: > ```cpp > image::Size input_size() > ``` #### input\\_width {#input\\_width} Get model input width item description **type** func **return** model input size of width **static** False > C++ defination code: > ```cpp > int input_width() > ``` #### input\\_height {#input\\_height} Get model input height item description **type** func **return** model input size of height **static** False > C++ defination code: > ```cpp > int input_height() > ``` #### input\\_format {#input\\_format} Get input image format item description **type** func **return** input image format, image::Format type. **static** False > C++ defination code: > ```cpp > image::Format input_format() > ``` #### mean {#mean} Get mean value, list type item description **type** var **static** False **readonly** False > C++ defination code: > ```cpp > std::vector mean > ``` #### scale {#scale} Get scale value, list type item description **type** var **static** False **readonly** False > C++ defination code: > ```cpp > std::vector scale > ``` ### OCR\\_Box {#OCR\\_Box} Object for OCR detect box > C++ defination code: > ```cpp > class OCR_Box > ``` #### OCR\\_Box {#OCR\\_Box 2} OCR_Box constructor item description **type** func **static** False > C++ defination code: > ```cpp > OCR_Box(int x1 0, int y1 0, int x2 0, int y2 0, int x3 0, int y3 0, int x4 0, int y4 0) > ``` #### x1 {#x1} left top point of box item description **type** var **static** False **readonly** False > C++ defination code: > ```cpp > int x1 > ``` #### y1 {#y1} left top point of box item description **type** var **static** False **readonly** False > C++ defination code: > ```cpp > int y1 > ``` #### x2 {#x2} right top point of box item description **type** var **static** False **readonly** False > C++ defination code: > ```cpp > int x2 > ``` #### y2 {#y2} right top point of box item description **type** var **static** False **readonly** False > C++ defination code: > ```cpp > int y2 > ``` #### x3 {#x3} right bottom point of box item description **type** var **static** False **readonly** False > C++ defination code: > ```cpp > int x3 > ``` #### y3 {#y3} right bottom point of box item description **type** var **static** False **readonly** False > C++ defination code: > ```cpp > int y3 > ``` #### x4 {#x4} left bottom point of box item description **type** var **static** False **readonly** False > C++ defination code: > ```cpp > int x4 > ``` #### y4 {#y4} left bottom point of box item description **type** var **static** False **readonly** False > C++ defination code: > ```cpp > int y4 > ``` #### to\\_list {#to\\_list} convert box point to a list type. item description **type** func **return** list type, element is int type, value [x1, y1, x2, y2, x3, y3, x4, y4]. **static** False > C++ defination code: > ```cpp > std::vector to_list() > ``` ### OCR\\_Object {#OCR\\_Object} Object for OCR detect result > C++ defination code: > ```cpp > class OCR_Object > ``` #### OCR\\_Object {#OCR\\_Object 2} Constructor of Object for OCR detect result item description **type** func **param** **score**: score
    **static** False > C++ defination code: > ```cpp > OCR_Object(const nn::OCR_Box &box, const std::vector &idx_list, const std::vector &char_list, float score 0, const std::vector &char_pos std::vector()) > ``` #### box {#box} OCR_Object box, 4 points box, first point at the left top, clock wise. item description **type** var **static** False **readonly** False > C++ defination code: > ```cpp > nn::OCR_Box box > ``` #### score {#score} Object score item description **type** var **static** False **readonly** False > C++ defination code: > ```cpp > float score > ``` #### idx\\_list {#idx\\_list} chars' idx list, element is int type. item description **type** var **static** False **readonly** False > C++ defination code: > ```cpp > std::vector idx_list > ``` #### char\\_pos {#char\\_pos} Chars' position relative to left item description **type** var **static** False **readonly** False > C++ defination code: > ```cpp > std::vector char_pos > ``` #### char\\_str {#char\\_str} Get OCR_Object's charactors, return a string type. item description **type** func **return** All charactors in string type. **static** False > C++ defination code: > ```cpp > const std::string &char_str() > ``` #### char\\_list {#char\\_list} Get OCR_Object's charactors, return a list type. item description **type** func **return** All charactors in list type. **static** False > C++ defination code: > ```cpp > const std::vector &char_list() > ``` #### update\\_chars {#update\\_chars} Set OCR_Object's charactors item description **type** func **param** **char_list**: All charactors in list type.
    **static** False > C++ defination code: > ```cpp > void update_chars(const std::vector &char_list) > ``` #### to\\_str {#to\\_str} OCR_Object info to string item description **type** func **return** OCR_Object info string **static** False > C++ defination code: > ```cpp > std::string to_str() > ``` ### OCR\\_Objects {#OCR\\_Objects} OCR_Objects Class for detect result > C++ defination code: > ```cpp > class OCR_Objects > ``` #### OCR\\_Objects {#OCR\\_Objects 2} Constructor of OCR_Objects class item description **type** func **static** False > C++ defination code: > ```cpp > OCR_Objects() > ``` #### add {#add} Add object to objects item description **type** func **throw** Throw exception if no memory **static** False > C++ defination code: > ```cpp > nn::OCR_Object &add(const nn::OCR_Box &box, const std::vector &idx_list, const std::vector &char_list, float score 0, const std::vector &char_pos std::vector()) > ``` #### remove {#remove} Remove object form objects item description **type** func **static** False > C++ defination code: > ```cpp > err::Err remove(int idx) > ``` #### at {#at} Get object item item description **type** func **static** False > C++ defination code: > ```cpp > nn::OCR_Object &at(int idx) > ``` #### [] {#[]} Get object item item description **type** func **static** False > C++ defination code: > ```cpp > nn::OCR_Object &operator[](int idx) > ``` #### size {#size} Get size item description **type** func **static** False > C++ defination code: > ```cpp > size_t size() > ``` #### begin {#begin} Begin item description **type** func **static** False > C++ defination code: > ```cpp > std::vector::iterator begin() > ``` #### end {#end} End item description **type** func **static** False > C++ defination code: > ```cpp > std::vector::iterator end() > ``` ### Speech {#Speech} Speech > C++ defination code: > ```cpp > class Speech > ``` #### Speech {#Speech 2} Construct a new Speech object item description **type** func **param** **model**: model path, default empty, you can load model later by load function.
    **throw** If model arg is not empty and load failed, will throw err::Exception. **static** False > C++ defination code: > ```cpp > Speech(const string &model \"\") > ``` #### Speech (overload 1) {#Speech (overload 1)} Construct a new Speech object item description **type** func **param** **model**: model path, default empty, you can load model later by load function.
    **throw** If model arg is not empty and load failed, will throw err::Exception. **static** False > C++ defination code: > ```cpp > Speech(const string &model \"\") > ``` #### load {#load 2} Load model from file item description **type** func **param** **model**: Model path want to load
    **return** err::Err **static** False > C++ defination code: > ```cpp > err::Err load(const string &model) > ``` #### load (overload 1) {#load (overload 1)} Load model from file item description **type** func **param** **model**: Model path want to load
    **return** err::Err **static** False > C++ defination code: > ```cpp > err::Err load(const string &model) > ``` #### init {#init 2} Init the ASR library and select the type and name of the audio device. item description **type** func **param** **dev_type**: device type want to detect, can choose between WAV, PCM, or MIC.
    **device_name**: device name want to detect, can choose a WAV file, a PCM file, or a MIC device name.
    **throw** **1**. If am model is not loaded, will throw err::ERR_NOT_IMPL.
    **2**. If device is not supported, will throw err::ERR_NOT_IMPL.
    **return** err::Err type, if init success, return err::ERR_NONE **static** False > C++ defination code: > ```cpp > err::Err init(nn::SpeechDevice dev_type, const string &device_name \"\") > ``` #### init (overload 1) {#init (overload 1)} Init the ASR library and select the type and name of the audio device. item description **type** func **param** **dev_type**: device type want to detect, can choose between WAV, PCM, or MIC.
    **device_name**: device name want to detect, can choose a WAV file, a PCM file, or a MIC device name.
    **throw** **1**. If am model is not loaded, will throw err::ERR_NOT_IMPL.
    **2**. If device is not supported, will throw err::ERR_NOT_IMPL.
    **return** err::Err type, if init success, return err::ERR_NONE **static** False > C++ defination code: > ```cpp > err::Err init(nn::SpeechDevice dev_type, const string &device_name \"\") > ``` #### devive {#devive} Reset the device, usually used for PCM/WAV recognition,\\nsuch as identifying the next WAV file. item description **type** func **param** **dev_type**: device type want to detect, can choose between WAV, PCM, or MIC.
    **device_name**: device name want to detect, can choose a WAV file, a PCM file, or a MIC device name.
    **throw** If device is not supported, will throw err::ERR_NOT_IMPL. **return** err::Err type, if init success, return err::ERR_NONE **static** False > C++ defination code: > ```cpp > err::Err devive(nn::SpeechDevice dev_type, const string &device_name) > ``` #### devive (overload 1) {#devive (overload 1)} Reset the device, usually used for PCM/WAV recognition,\\nsuch as identifying the next WAV file. item description **type** func **param** **dev_type**: device type want to detect, can choose between WAV, PCM, or MIC.
    **device_name**: device name want to detect, can choose a WAV file, a PCM file, or a MIC device name.
    **throw** If device is not supported, will throw err::ERR_NOT_IMPL. **return** err::Err type, if init success, return err::ERR_NONE **static** False > C++ defination code: > ```cpp > err::Err devive(nn::SpeechDevice dev_type, const string &device_name) > ``` #### dec\\_deinit {#dec\\_deinit} Deinit the decoder. item description **type** func **param** **decoder**: decoder type want to deinit
    can choose between DECODER_RAW, DECODER_DIG, DECODER_LVCSR, DECODER_KWS or DECODER_ALL.
    **throw** If device is not supported, will throw err::ERR_NOT_IMPL. **static** False > C++ defination code: > ```cpp > void dec_deinit(nn::SpeechDecoder decoder) > ``` #### dec\\_deinit (overload 1) {#dec\\_deinit (overload 1)} Deinit the decoder. item description **type** func **param** **decoder**: decoder type want to deinit
    can choose between DECODER_RAW, DECODER_DIG, DECODER_LVCSR, DECODER_KWS or DECODER_ALL.
    **throw** If device is not supported, will throw err::ERR_NOT_IMPL. **static** False > C++ defination code: > ```cpp > void dec_deinit(nn::SpeechDecoder decoder) > ``` #### raw {#raw} Init raw decoder, it will output the prediction results of the original AM. item description **type** func **param** **callback**: raw decoder user callback.
    **return** err::Err type, if init success, return err::ERR_NONE **static** False > C++ defination code: > ```cpp > err::Err raw(std::function>, int)> callback) > ``` #### raw (overload 1) {#raw (overload 1)} Get raw decoder status item description **type** func **return** bool, raw decoder status **static** False > C++ defination code: > ```cpp > bool raw() > ``` #### raw (overload 2) {#raw (overload 2)} Init raw decoder, it will output the prediction results of the original AM. item description **type** func **param** **callback**: raw decoder user callback.
    **return** err::Err type, if init success, return err::ERR_NONE **static** False > C++ defination code: > ```cpp > err::Err raw(std::function>, int)> callback) > ``` #### raw (overload 3) {#raw (overload 3)} Get raw decoder status item description **type** func **return** bool, raw decoder status **static** False > C++ defination code: > ```cpp > bool raw() > ``` #### digit {#digit} Init digit decoder, it will output the Chinese digit recognition results within the last 4 seconds. item description **type** func **param** **blank**: If it exceeds this value, insert a '_' in the output result to indicate idle mute.
    **callback**: digit decoder user callback.
    **return** err::Err type, if init success, return err::ERR_NONE **static** False > C++ defination code: > ```cpp > err::Err digit(int blank, std::function callback) > ``` #### digit (overload 1) {#digit (overload 1)} Get digit decoder status item description **type** func **return** bool, digit decoder status **static** False > C++ defination code: > ```cpp > bool digit() > ``` #### digit (overload 2) {#digit (overload 2)} Init digit decoder, it will output the Chinese digit recognition results within the last 4 seconds. item description **type** func **param** **blank**: If it exceeds this value, insert a '_' in the output result to indicate idle mute.
    **callback**: digit decoder user callback.
    **return** err::Err type, if init success, return err::ERR_NONE **static** False > C++ defination code: > ```cpp > err::Err digit(int blank, std::function callback) > ``` #### digit (overload 3) {#digit (overload 3)} Get digit decoder status item description **type** func **return** bool, digit decoder status **static** False > C++ defination code: > ```cpp > bool digit() > ``` #### kws {#kws} Init kws decoder, it will output a probability list of all registered keywords in the latest frame,\\nusers can set their own thresholds for wake up. item description **type** func **param** **kw_tbl**: Keyword list, filled in with spaces separated by pinyin, for example: xiao3 ai4 tong2 xue2
    **kw_gate**: kw_gate, keyword probability gate table, the number should be the same as kw_tbl
    **auto_similar**: Whether to perform automatic homophone processing,
    setting it to true will automatically calculate the probability by using pinyin with different tones as homophones
    **callback**: digit decoder user callback.
    **return** err::Err type, if init success, return err::ERR_NONE **static** False > C++ defination code: > ```cpp > err::Err kws(std::vector kw_tbl, std::vector kw_gate, std::function, int)> callback, bool auto_similar true) > ``` #### kws (overload 1) {#kws (overload 1)} Get kws decoder status item description **type** func **return** bool, kws decoder status **static** False > C++ defination code: > ```cpp > bool kws() > ``` #### kws (overload 2) {#kws (overload 2)} Init kws decoder, it will output a probability list of all registered keywords in the latest frame,\\nusers can set their own thresholds for wake up. item description **type** func **param** **kw_tbl**: Keyword list, filled in with spaces separated by pinyin, for example: xiao3 ai4 tong2 xue2
    **kw_gate**: kw_gate, keyword probability gate table, the number should be the same as kw_tbl
    **auto_similar**: Whether to perform automatic homophone processing,
    setting it to true will automatically calculate the probability by using pinyin with different tones as homophones
    **callback**: digit decoder user callback.
    **return** err::Err type, if init success, return err::ERR_NONE **static** False > C++ defination code: > ```cpp > err::Err kws(std::vector kw_tbl, std::vector kw_gate, std::function, int)> callback, bool auto_similar true) > ``` #### kws (overload 3) {#kws (overload 3)} Get kws decoder status item description **type** func **return** bool, kws decoder status **static** False > C++ defination code: > ```cpp > bool kws() > ``` #### lvcsr {#lvcsr} Init lvcsr decoder, it will output continuous speech recognition results (less than 1024 Chinese characters). item description **type** func **param** **sfst_name**: Sfst file path.
    **sym_name**: Sym file path (output symbol table).
    **phones_txt**: Path to phones.bin (pinyin table).
    **words_txt**: Path to words.bin (dictionary table).
    **callback**: lvcsr decoder user callback.
    **beam**: The beam size for WFST search is set to 8 by default, and it is recommended to be between 3 and 9.
    The larger the size, the larger the search space, and the more accurate but slower the search.
    **bg_prob**: The absolute value of the natural logarithm of the default probability value for background pinyin
    outside of BEAM CNT is set to 10 by default.
    **scale**: acoustics_cost log(pny_prob)*scale.
    **mmap**: use mmap to load the WFST decoding image,
    If set to true, the beam should be less than 5.
    **return** err::Err type, if init success, return err::ERR_NONE **static** False > C++ defination code: > ```cpp > err::Err lvcsr(const string &sfst_name, const string &sym_name, > const string &phones_txt, const string &words_txt, > std::function, int)> callback, > float beam 8, float bg_prob 10, float scale 0.5, bool mmap false) > ``` #### lvcsr (overload 1) {#lvcsr (overload 1)} Get lvcsr decoder status item description **type** func **return** bool, lvcsr decoder status **static** False > C++ defination code: > ```cpp > bool lvcsr() > ``` #### lvcsr (overload 2) {#lvcsr (overload 2)} Init lvcsr decoder, it will output continuous speech recognition results (less than 1024 Chinese characters). item description **type** func **param** **sfst_name**: Sfst file path.
    **sym_name**: Sym file path (output symbol table).
    **phones_txt**: Path to phones.bin (pinyin table).
    **words_txt**: Path to words.bin (dictionary table).
    **callback**: lvcsr decoder user callback.
    **beam**: The beam size for WFST search is set to 8 by default, and it is recommended to be between 3 and 9.
    The larger the size, the larger the search space, and the more accurate but slower the search.
    **bg_prob**: The absolute value of the natural logarithm of the default probability value for background pinyin
    outside of BEAM CNT is set to 10 by default.
    **scale**: acoustics_cost log(pny_prob)*scale.
    **mmap**: use mmap to load the WFST decoding image,
    If set to true, the beam should be less than 5.
    **return** err::Err type, if init success, return err::ERR_NONE **static** False > C++ defination code: > ```cpp > err::Err lvcsr(const string &sfst_name, const string &sym_name, > const string &phones_txt, const string &words_txt, > std::function, int)> callback, > float beam 8, float bg_prob 10, float scale 0.5, bool mmap false) > ``` #### lvcsr (overload 3) {#lvcsr (overload 3)} Get lvcsr decoder status item description **type** func **return** bool, lvcsr decoder status **static** False > C++ defination code: > ```cpp > bool lvcsr() > ``` #### run {#run} Run speech recognition, user can run 1 frame at a time and do other processing after running,\\nor it can run continuously within a thread and be stopped by an external thread. item description **type** func **param** **frame**: The number of frames per run.
    **return** int type, return actual number of frames in the run. **static** False > C++ defination code: > ```cpp > int run(int frame) > ``` #### run (overload 1) {#run (overload 1)} Run speech recognition, user can run 1 frame at a time and do other processing after running,\\nor it can run continuously within a thread and be stopped by an external thread. item description **type** func **param** **frame**: The number of frames per run.
    **return** int type, return actual number of frames in the run. **static** False > C++ defination code: > ```cpp > int run(int frame) > ``` #### clear {#clear} Reset internal cache operation item description **type** func **static** False > C++ defination code: > ```cpp > void clear() > ``` #### clear (overload 1) {#clear (overload 1)} Reset internal cache operation item description **type** func **static** False > C++ defination code: > ```cpp > void clear() > ``` #### frame\\_time {#frame\\_time} Get the time of one frame. item description **type** func **return** int type, return the time of one frame. **static** False > C++ defination code: > ```cpp > int frame_time() > ``` #### frame\\_time (overload 1) {#frame\\_time (overload 1)} Get the time of one frame. item description **type** func **return** int type, return the time of one frame. **static** False > C++ defination code: > ```cpp > int frame_time() > ``` #### similar {#similar} Manually register mute words, and each pinyin can register up to 10 homophones,\\nplease note that using this interface to register homophones will overwrite,\\nthe homophone table automatically generated in the \\\"automatic homophone processing\\\" feature. item description **type** func **param** **dev_type**: device type want to detect, can choose between WAV, PCM, or MIC.
    **device_name**: device name want to detect, can choose a WAV file, a PCM file, or a MIC device name.
    **return** err::Err type, if init success, return err::ERR_NONE **static** False > C++ defination code: > ```cpp > err::Err similar(const string &pny, std::vector similar_pnys) > ``` #### similar (overload 1) {#similar (overload 1)} Manually register mute words, and each pinyin can register up to 10 homophones,\\nplease note that using this interface to register homophones will overwrite,\\nthe homophone table automatically generated in the \\\"automatic homophone processing\\\" feature. item description **type** func **param** **dev_type**: device type want to detect, can choose between WAV, PCM, or MIC.
    **device_name**: device name want to detect, can choose a WAV file, a PCM file, or a MIC device name.
    **return** err::Err type, if init success, return err::ERR_NONE **static** False > C++ defination code: > ```cpp > err::Err similar(const string &pny, std::vector similar_pnys) > ``` #### skip\\_frames {#skip\\_frames} Run some frames and drop, this can be used to avoid\\nincorrect recognition results when switching decoders. item description **type** func **param** **num**: number of frames to run and drop
    **static** False > C++ defination code: > ```cpp > void skip_frames(int num) > ``` #### skip\\_frames (overload 1) {#skip\\_frames (overload 1)} Run some frames and drop, this can be used to avoid\\nincorrect recognition results when switching decoders. item description **type** func **param** **num**: number of frames to run and drop
    **static** False > C++ defination code: > ```cpp > void skip_frames(int num) > ``` #### mean {#mean 2} Get mean value, list type item description **type** var **static** False **readonly** False > C++ defination code: > ```cpp > std::vector mean > ``` #### scale {#scale 2} Get scale value, list type item description **type** var **static** False **readonly** False > C++ defination code: > ```cpp > std::vector scale > ``` #### dev\\_type {#dev\\_type} get device type item description **type** func **return** nn::SpeechDevice type, see SpeechDevice of this module **static** False > C++ defination code: > ```cpp > nn::SpeechDevice dev_type() > ``` #### dev\\_type (overload 1) {#dev\\_type (overload 1)} get device type item description **type** func **return** nn::SpeechDevice type, see SpeechDevice of this module **static** False > C++ defination code: > ```cpp > nn::SpeechDevice dev_type() > ``` ### YOLOv8 {#YOLOv8} YOLOv8 class > C++ defination code: > ```cpp > class YOLOv8 > ``` #### YOLOv8 {#YOLOv8 2} Constructor of YOLOv8 class item description **type** func **param** **model**: model path, default empty, you can load model later by load function.
    **dual_buff**: direction [in], prepare dual input output buffer to accelarate forward, that is, when NPU is forwarding we not wait and prepare the next input buff.
    If you want to ensure every time forward output the input's result, set this arg to false please.
    Default true to ensure speed.
    **throw** If model arg is not empty and load failed, will throw err::Exception. **static** False > C++ defination code: > ```cpp > YOLOv8(const string &model \"\", bool dual_buff true) > ``` #### load {#load 3} Load model from file item description **type** func **param** **model**: Model path want to load
    **return** err::Err **static** False > C++ defination code: > ```cpp > err::Err load(const string &model) > ``` #### detect {#detect} Detect objects from image item description **type** func **param** **img**: Image want to detect, if image's size not match model input's, will auto resize with fit method.
    **conf_th**: Confidence threshold, default 0.5.
    **iou_th**: IoU threshold, default 0.45.
    **fit**: Resize method, default image.Fit.FIT_CONTAIN.
    **keypoint_th**: keypoint threshold, default 0.5, only for yolov8 pose model.
    **throw** If image format not match model input format, will throw err::Exception. **return** Object list. In C++, you should delete it after use.
    If model is yolov8 pose, object's points have value, and if points' value < 0 means that point is invalid(conf < keypoint_th). **static** False > C++ defination code: > ```cpp > nn::Objects *detect(image::Image &img, float conf_th 0.5, float iou_th 0.45, maix::image::Fit fit maix::image::FIT_CONTAIN, float keypoint_th 0.5) > ``` #### input\\_size {#input\\_size 2} Get model input size item description **type** func **return** model input size **static** False > C++ defination code: > ```cpp > image::Size input_size() > ``` #### input\\_width {#input\\_width 2} Get model input width item description **type** func **return** model input size of width **static** False > C++ defination code: > ```cpp > int input_width() > ``` #### input\\_height {#input\\_height 2} Get model input height item description **type** func **return** model input size of height **static** False > C++ defination code: > ```cpp > int input_height() > ``` #### input\\_format {#input\\_format 2} Get input image format item description **type** func **return** input image format, image::Format type. **static** False > C++ defination code: > ```cpp > image::Format input_format() > ``` #### draw\\_pose {#draw\\_pose} Draw pose keypoints on image item description **type** func **param** **img**: image object, maix.image.Image type.
    **points**: keypoits, int list type, [x, y, x, y ...]
    **radius**: radius of points.
    **color**: color of points.
    **body**: true, if points' length is 17*2 and body is ture, will draw lines as human body, if set to false won't draw lines, default true.
    **static** False > C++ defination code: > ```cpp > void draw_pose(image::Image &img, std::vector points, int radius 4, image::Color color image::COLOR_RED, bool body true) > ``` #### draw\\_seg\\_mask {#draw\\_seg\\_mask} Draw segmentation on image item description **type** func **param** **img**: image object, maix.image.Image type.
    **seg_mask**: segmentation mask image by detect method, a grayscale image
    **threshold**: only mask's value > threshold will be draw on image, value from 0 to 255.
    **static** False > C++ defination code: > ```cpp > void draw_seg_mask(image::Image &img, int x, int y, image::Image &seg_mask, int threshold 127) > ``` #### labels {#labels} Labels list item description **type** var **static** False **readonly** False > C++ defination code: > ```cpp > std::vector labels > ``` #### label\\_path {#label\\_path} Label file path item description **type** var **static** False **readonly** False > C++ defination code: > ```cpp > std::string label_path > ``` #### mean {#mean 3} Get mean value, list type item description **type** var **static** False **readonly** False > C++ defination code: > ```cpp > std::vector mean > ``` #### scale {#scale 3} Get scale value, list type item description **type** var **static** False **readonly** False > C++ defination code: > ```cpp > std::vector scale > ``` ### Object {#Object} Object for detect result > C++ defination code: > ```cpp > class Object > ``` #### Object {#Object 2} Constructor of Object for detect result item description **type** func **param** **x**: left top x
    **y**: left top y
    **w**: width
    **h**: height
    **class_id**: class id
    **score**: score
    **static** False > C++ defination code: > ```cpp > Object(int x 0, int y 0, int w 0, int h 0, int class_id 0, float score 0, std::vector points std::vector()) > ``` #### to\\_str {#to\\_str 2} Object info to string item description **type** func **return** Object info string **static** False > C++ defination code: > ```cpp > std::string to_str() > ``` #### x {#x} Object left top coordinate x item description **type** var **static** False **readonly** False > C++ defination code: > ```cpp > int x > ``` #### y {#y} Object left top coordinate y item description **type** var **static** False **readonly** False > C++ defination code: > ```cpp > int y > ``` #### w {#w} Object width item description **type** var **static** False **readonly** False > C++ defination code: > ```cpp > int w > ``` #### h {#h} Object height item description **type** var **static** False **readonly** False > C++ defination code: > ```cpp > int h > ``` #### class\\_id {#class\\_id} Object class id item description **type** var **static** False **readonly** False > C++ defination code: > ```cpp > int class_id > ``` #### score {#score 2} Object score item description **type** var **static** False **readonly** False > C++ defination code: > ```cpp > float score > ``` #### points {#points} keypoints item description **type** var **static** False **readonly** False > C++ defination code: > ```cpp > std::vector points > ``` #### seg\\_mask {#seg\\_mask} segmentation mask, uint8 list type, shape is h * w but flattened to one dimension, value fron 0 to 255. item description **type** var **attention** For efficiency, it's a pointer in C++, use this carefully! **static** False **readonly** False > C++ defination code: > ```cpp > image::Image *seg_mask > ``` ### ObjectFloat {#ObjectFloat} Object for detect result > C++ defination code: > ```cpp > class ObjectFloat > ``` #### ObjectFloat {#ObjectFloat 2} Constructor of Object for detect result item description **type** func **param** **x**: left top x
    **y**: left top y
    **w**: width
    **h**: height
    **class_id**: class id
    **score**: score
    **static** False > C++ defination code: > ```cpp > ObjectFloat(float x 0, float y 0, float w 0, float h 0, float class_id 0, float score 0, std::vector points std::vector()) > ``` #### to\\_str {#to\\_str 3} Object info to string item description **type** func **return** Object info string **static** False > C++ defination code: > ```cpp > std::string to_str() > ``` #### x {#x 2} Object left top coordinate x item description **type** var **static** False **readonly** False > C++ defination code: > ```cpp > float x > ``` #### y {#y 2} Object left top coordinate y item description **type** var **static** False **readonly** False > C++ defination code: > ```cpp > float y > ``` #### w {#w 2} Object width item description **type** var **static** False **readonly** False > C++ defination code: > ```cpp > float w > ``` #### h {#h 2} Object height item description **type** var **static** False **readonly** False > C++ defination code: > ```cpp > float h > ``` #### class\\_id {#class\\_id 2} Object class id item description **type** var **static** False **readonly** False > C++ defination code: > ```cpp > float class_id > ``` #### score {#score 3} Object score item description **type** var **static** False **readonly** False > C++ defination code: > ```cpp > float score > ``` #### points {#points 2} keypoints item description **type** var **static** False **readonly** False > C++ defination code: > ```cpp > std::vector points > ``` ### Objects {#Objects} Objects Class for detect result > C++ defination code: > ```cpp > class Objects > ``` #### Objects {#Objects 2} Constructor of Objects class item description **type** func **static** False > C++ defination code: > ```cpp > Objects() > ``` #### add {#add 2} Add object to objects item description **type** func **throw** Throw exception if no memory **static** False > C++ defination code: > ```cpp > nn::Object &add(int x 0, int y 0, int w 0, int h 0, int class_id 0, float score 0, std::vector points std::vector()) > ``` #### remove {#remove 2} Remove object form objects item description **type** func **static** False > C++ defination code: > ```cpp > err::Err remove(int idx) > ``` #### at {#at 2} Get object item item description **type** func **static** False > C++ defination code: > ```cpp > nn::Object &at(int idx) > ``` #### [] {#[] 2} Get object item item description **type** func **static** False > C++ defination code: > ```cpp > nn::Object &operator[](int idx) > ``` #### size {#size 2} Get size item description **type** func **static** False > C++ defination code: > ```cpp > size_t size() > ``` #### begin {#begin 2} Begin item description **type** func **static** False > C++ defination code: > ```cpp > std::vector::iterator begin() > ``` #### end {#end 2} End item description **type** func **static** False > C++ defination code: > ```cpp > std::vector::iterator end() > ``` ### MUD {#MUD} MUD(model universal describe file) class > C++ defination code: > ```cpp > class MUD > ``` #### MUD {#MUD 2} MUD constructor item description **type** func **param** **model_path**: direction [in], model file path, model format can be MUD(model universal describe file) file.
    If model_path set, will load model from file, load failed will raise err.Exception.
    If model_path not set, you can load model later by load function.
    **static** False > C++ defination code: > ```cpp > MUD(const char *model_path nullptr) > ``` #### load {#load 4} Load model from file item description **type** func **param** **model_path**: direction [in], model file path, model format can be MUD(model universal describe file) file.
    **return** error code, if load success, return err::ERR_NONE **static** False > C++ defination code: > ```cpp > err::Err load(const std::string &model_path) > ``` #### type {#type} Model type, string type item description **type** var **static** False **readonly** False > C++ defination code: > ```cpp > std::string type > ``` #### items {#items} Model config items, different model type has different config items item description **type** var **static** False **readonly** False > C++ defination code: > ```cpp > std::map> items > ``` ### LayerInfo {#LayerInfo} NN model layer info > C++ defination code: > ```cpp > class LayerInfo > ``` #### LayerInfo {#LayerInfo 2} LayerInfo constructor item description **type** func **param** **name**: direction [in], layer name
    **dtype**: direction [in], layer data type
    **shape**: direction [in], layer shape
    **static** False > C++ defination code: > ```cpp > LayerInfo(const std::string &name \"\", tensor::DType dtype tensor::DType::FLOAT32, std::vector shape std::vector()) > ``` #### name {#name} Layer name item description **type** var **static** False **readonly** False > C++ defination code: > ```cpp > std::string name > ``` #### dtype {#dtype} Layer data type item description **type** var **attention** If model is quantized, this is the real quantized data type like int8 float16,
    in most scene, inputs and outputs we actually use float32 in API like forward. **static** False **readonly** False > C++ defination code: > ```cpp > tensor::DType dtype > ``` #### shape {#shape} Layer shape item description **type** var **static** False **readonly** False > C++ defination code: > ```cpp > std::vector shape > ``` #### shape\\_int {#shape\\_int} Shape as one int type, multiply all dims of shape item description **type** func **static** False > C++ defination code: > ```cpp > int shape_int() > ``` #### to\\_str {#to\\_str 4} To string item description **type** func **static** False > C++ defination code: > ```cpp > std::string to_str() > ``` #### \\_\\_str\\_\\_ {#\\_\\_str\\_\\_} To string item description **type** func **static** False > C++ defination code: > ```cpp > std::string __str__() > ``` ### NN {#NN} Neural network class > C++ defination code: > ```cpp > class NN > ``` #### \\_\\_init\\_\\_ {#\\_\\_init\\_\\_} Neural network constructor item description **type** func **param** **model**: direction [in], model file path, model format can be MUD(model universal describe file) file.
    If model_path set, will load model from file, load failed will raise err.Exception.
    If model_path not set, you can load model later by load function.
    **dual_buff**: direction [in], prepare dual input output buffer to accelarate forward, that is, when NPU is forwarding we not wait and prepare the next input buff.
    If you want to ensure every time forward output the input's result, set this arg to false please.
    Default true to ensure speed.
    **static** False > C++ defination code: > ```cpp > NN(const std::string &model \"\", bool dual_buff true) > ``` #### load {#load 5} Load model from file item description **type** func **param** **model**: direction [in], model file path, model format can be MUD(model universal describe file) file.
    **return** error code, if load success, return err::ERR_NONE **static** False > C++ defination code: > ```cpp > err::Err load(const std::string &model) > ``` #### loaded {#loaded} Is model loaded item description **type** func **return** true if model loaded, else false **static** False > C++ defination code: > ```cpp > bool loaded() > ``` #### set\\_dual\\_buff {#set\\_dual\\_buff} Enable dual buff or disable dual buff item description **type** func **param** **enable**: true to enable, false to disable
    **static** False > C++ defination code: > ```cpp > void set_dual_buff(bool enable) > ``` #### inputs\\_info {#inputs\\_info} Get model input layer info item description **type** func **return** input layer info **static** False > C++ defination code: > ```cpp > std::vector inputs_info() > ``` #### outputs\\_info {#outputs\\_info} Get model output layer info item description **type** func **return** output layer info **static** False > C++ defination code: > ```cpp > std::vector outputs_info() > ``` #### extra\\_info {#extra\\_info} Get model extra info define in MUD file item description **type** func **return** extra info, dict type, key value object, attention: key and value are all string type. **static** False > C++ defination code: > ```cpp > std::map extra_info() > ``` #### forward {#forward} forward run model, get output of model,\\nthis is specially for MaixPy, not efficient, but easy to use in MaixPy item description **type** func **param** **input**: direction [in], input tensor
    **copy_result**: If set true, will copy result to a new variable; else will use a internal memory, you can only use it until to the next forward.
    Default true to avoid problems, you can set it to false manually to make speed faster.
    **dual_buff_wait**: bool type, only for dual_buff mode, if true, will inference this image and wait for result, default false.
    **return** output tensor. In C++, you should manually delete tensors in return value and return value.
    If dual_buff mode, it can be NULL(None in MaixPy) means not ready. **throw** if error ocurrs like no memory or arg error, will raise err.Exception. **static** False > C++ defination code: > ```cpp > tensor::Tensors *forward(tensor::Tensors &inputs, bool copy_result true, bool dual_buff_wait false) > ``` #### forward\\_image {#forward\\_image} forward model, param is image item description **type** func **param** **img**: input image
    **mean**: mean value, a list type, e.g. [0.485, 0.456, 0.406], default is empty list means not normalize.
    **scale**: scale value, a list type, e.g. [1/0.229, 1/0.224, 1/0.225], default is empty list means not normalize.
    **fit**: fit mode, if the image size of input not equal to model's input, it will auto resize use this fit method,
    default is image.Fit.FIT_FILL for easy coordinate calculation, but for more accurate result, use image.Fit.FIT_CONTAIN is better.
    **copy_result**: If set true, will copy result to a new variable; else will use a internal memory, you can only use it until to the next forward.
    Default true to avoid problems, you can set it to false manually to make speed faster.
    **dual_buff_wait**: bool type, only for dual_buff mode, if true, will inference this image and wait for result, default false.
    **return** output tensor. In C++, you should manually delete tensors in return value and return value.
    If dual_buff mode, it can be NULL(None in MaixPy) means not ready. **throw** If error occurs, like arg error or alloc memory failed, will raise err.Exception. **static** False > C++ defination code: > ```cpp > tensor::Tensors *forward_image(image::Image &img, std::vector mean std::vector(), std::vector scale std::vector(), image::Fit fit image::Fit::FIT_FILL, bool copy_result true, bool dual_buff_wait false) > ``` ### FaceObject {#FaceObject} Face object > C++ defination code: > ```cpp > class FaceObject > ``` #### FaceObject {#FaceObject 2} Constructor item description **type** func **static** False > C++ defination code: > ```cpp > FaceObject(int x 0, int y 0, int w 0, int h 0, int class_id 0, float score 0, std::vector points std::vector(), std::vector feature std::vector(), image::Image face image::Image()) > ``` #### to\\_str {#to\\_str 5} FaceObject info to string item description **type** func **return** FaceObject info string **static** False > C++ defination code: > ```cpp > std::string to_str() > ``` #### x {#x 3} FaceObject left top coordinate x item description **type** var **static** False **readonly** False > C++ defination code: > ```cpp > int x > ``` #### y {#y 3} FaceObject left top coordinate y item description **type** var **static** False **readonly** False > C++ defination code: > ```cpp > int y > ``` #### w {#w 3} FaceObject width item description **type** var **static** False **readonly** False > C++ defination code: > ```cpp > int w > ``` #### h {#h 3} FaceObject height item description **type** var **static** False **readonly** False > C++ defination code: > ```cpp > int h > ``` #### class\\_id {#class\\_id 3} FaceObject class id item description **type** var **static** False **readonly** False > C++ defination code: > ```cpp > int class_id > ``` #### score {#score 4} FaceObject score item description **type** var **static** False **readonly** False > C++ defination code: > ```cpp > float score > ``` #### points {#points 3} keypoints item description **type** var **static** False **readonly** False > C++ defination code: > ```cpp > std::vector points > ``` #### feature {#feature} feature, float list type item description **type** var **static** False **readonly** False > C++ defination code: > ```cpp > std::vector feature > ``` #### face {#face} face image item description **type** var **static** False **readonly** False > C++ defination code: > ```cpp > image::Image face > ``` ### FaceObjects {#FaceObjects} Objects Class for detect result > C++ defination code: > ```cpp > class FaceObjects > ``` #### FaceObjects {#FaceObjects 2} Constructor of FaceObjects class item description **type** func **static** False > C++ defination code: > ```cpp > FaceObjects() > ``` #### add {#add 3} Add object to FaceObjects item description **type** func **throw** Throw exception if no memory **static** False > C++ defination code: > ```cpp > nn::FaceObject &add(int x 0, int y 0, int w 0, int h 0, int class_id 0, float score 0, std::vector points std::vector(), std::vector feature std::vector(), image::Image face image::Image()) > ``` #### remove {#remove 3} Remove object form FaceObjects item description **type** func **static** False > C++ defination code: > ```cpp > err::Err remove(int idx) > ``` #### at {#at 3} Get object item item description **type** func **static** False > C++ defination code: > ```cpp > nn::FaceObject &at(int idx) > ``` #### [] {#[] 3} Get object item item description **type** func **static** False > C++ defination code: > ```cpp > nn::FaceObject &operator[](int idx) > ``` #### size {#size 3} Get size item description **type** func **static** False > C++ defination code: > ```cpp > size_t size() > ``` #### begin {#begin 3} Begin item description **type** func **static** False > C++ defination code: > ```cpp > std::vector::iterator begin() > ``` #### end {#end 3} End item description **type** func **static** False > C++ defination code: > ```cpp > std::vector::iterator end() > ``` ### FaceRecognizer {#FaceRecognizer} FaceRecognizer class > C++ defination code: > ```cpp > class FaceRecognizer > ``` #### FaceRecognizer {#FaceRecognizer 2} Constructor of FaceRecognizer class item description **type** func **param** **detect_model**: face detect model path, default empty, you can load model later by load function.
    **feature_model**: feature extract model
    **dual_buff**: direction [in], prepare dual input output buffer to accelarate forward, that is, when NPU is forwarding we not wait and prepare the next input buff.
    If you want to ensure every time forward output the input's result, set this arg to false please.
    Default true to ensure speed.
    **throw** If model arg is not empty and load failed, will throw err::Exception. **static** False > C++ defination code: > ```cpp > FaceRecognizer(const string &detect_model \"\", const string &feature_model \"\", bool dual_buff true) > ``` #### load {#load 6} Load model from file item description **type** func **param** **detect_model**: face detect model path, default empty, you can load model later by load function.
    **feature_model**: feature extract model
    **return** err::Err **static** False > C++ defination code: > ```cpp > err::Err load(const string &detect_model, const string &feature_model) > ``` #### recognize {#recognize} Detect objects from image item description **type** func **param** **img**: Image want to detect, if image's size not match model input's, will auto resize with fit method.
    **conf_th**: Detect confidence threshold, default 0.5.
    **iou_th**: Detect IoU threshold, default 0.45.
    **compare_th**: Compare two face score threshold, default 0.8, if two faces' score < this value, will see this face fas unknown.
    **get_feature**: return feature or not, if true will copy features to result, if false will not copy feature to result to save time and memory.
    **get_face**: return face image or not, if true result object's face attribute will valid, or face sttribute is empty. Get face image will alloc memory and copy image, so will lead to slower speed.
    **fit**: Resize method, default image.Fit.FIT_CONTAIN.
    **throw** If image format not match model input format, will throw err::Exception. **return** FaceObjects object. In C++, you should delete it after use. **static** False > C++ defination code: > ```cpp > nn::FaceObjects *recognize(image::Image &img, float conf_th 0.5, float iou_th 0.45, float compare_th 0.8, bool get_feature false, bool get_face false, maix::image::Fit fit maix::image::FIT_CONTAIN) > ``` #### add\\_face {#add\\_face} Add face to lib item description **type** func **param** **face**: face object, find by recognize
    **label**: face label(name)
    **static** False > C++ defination code: > ```cpp > err::Err add_face(nn::FaceObject *face, const std::string &label) > ``` #### remove\\_face {#remove\\_face} remove face from lib item description **type** func **param** **idx**: index of face in lib, default 1 means use label, value [0,face_num), idx and label must have one, idx have high priotiry.
    **label**: which face to remove, default to empty string mean use idx, idx and label must have one, idx have high priotiry.
    **static** False > C++ defination code: > ```cpp > err::Err remove_face(int idx 1, const std::string &label \"\") > ``` #### save\\_faces {#save\\_faces} Save faces info to a file item description **type** func **param** **path**: where to save, string type.
    **return** err.Err type **static** False > C++ defination code: > ```cpp > err::Err save_faces(const std::string &path) > ``` #### load\\_faces {#load\\_faces} Load faces info from a file item description **type** func **param** **path**: from where to load, string type.
    **return** err::Err type **static** False > C++ defination code: > ```cpp > err::Err load_faces(const std::string &path) > ``` #### input\\_size {#input\\_size 3} Get model input size item description **type** func **return** model input size **static** False > C++ defination code: > ```cpp > image::Size input_size() > ``` #### input\\_width {#input\\_width 3} Get model input width item description **type** func **return** model input size of width **static** False > C++ defination code: > ```cpp > int input_width() > ``` #### input\\_height {#input\\_height 3} Get model input height item description **type** func **return** model input size of height **static** False > C++ defination code: > ```cpp > int input_height() > ``` #### input\\_format {#input\\_format 3} Get input image format item description **type** func **return** input image format, image::Format type. **static** False > C++ defination code: > ```cpp > image::Format input_format() > ``` #### mean\\_detector {#mean\\_detector} Get mean value, list type item description **type** var **static** False **readonly** False > C++ defination code: > ```cpp > std::vector mean_detector > ``` #### scale\\_detector {#scale\\_detector} Get scale value, list type item description **type** var **static** False **readonly** False > C++ defination code: > ```cpp > std::vector scale_detector > ``` #### mean\\_feature {#mean\\_feature} Get mean value, list type item description **type** var **static** False **readonly** False > C++ defination code: > ```cpp > std::vector mean_feature > ``` #### scale\\_feature {#scale\\_feature} Get scale value, list type item description **type** var **static** False **readonly** False > C++ defination code: > ```cpp > std::vector scale_feature > ``` #### labels {#labels 2} labels, list type, first is \\\"unknown\\\" item description **type** var **static** False **readonly** False > C++ defination code: > ```cpp > std::vector labels > ``` #### features {#features} features item description **type** var **static** False **readonly** False > C++ defination code: > ```cpp > std::vector> features > ``` ### SelfLearnClassifier {#SelfLearnClassifier} SelfLearnClassifier > C++ defination code: > ```cpp > class SelfLearnClassifier > ``` #### SelfLearnClassifier {#SelfLearnClassifier 2} Construct a new SelfLearnClassifier object item description **type** func **param** **model**: MUD model path, if empty, will not load model, you can call load_model() later.
    if not empty, will load model and will raise err::Exception if load failed.
    **dual_buff**: direction [in], prepare dual input output buffer to accelarate forward, that is, when NPU is forwarding we not wait and prepare the next input buff.
    If you want to ensure every time forward output the input's result, set this arg to false please.
    Default true to ensure speed.
    **static** False > C++ defination code: > ```cpp > SelfLearnClassifier(const std::string &model \"\", bool dual_buff true) > ``` #### load\\_model {#load\\_model} Load model from file, model format is .mud,\\nMUD file should contain [extra] section, have key values:\\n model_type: classifier_no_top\\n input_type: rgb or bgr\\n mean: 123.675, 116.28, 103.53\\n scale: 0.017124753831663668, 0.01750700280112045, 0.017429193899782137 item description **type** func **param** **model**: MUD model path
    **return** error code, if load failed, return error code **static** False > C++ defination code: > ```cpp > err::Err load_model(const string &model) > ``` #### classify {#classify} Classify image item description **type** func **param** **img**: image, format should match model input_type, or will raise err.Exception
    **fit**: image resize fit mode, default Fit.FIT_COVER, see image.Fit.
    **throw** If error occurred, will raise err::Exception, you can find reason in log, mostly caused by args error or hardware error. **return** result, a list of (idx, distance), smaller distance means more similar. In C++, you need to delete it after use. **static** False > C++ defination code: > ```cpp > std::vector> *classify(image::Image &img, image::Fit fit image::FIT_COVER) > ``` #### add\\_class {#add\\_class} Add a class to recognize item description **type** func **param** **img**: Add a image as a new class
    **fit**: image resize fit mode, default Fit.FIT_COVER, see image.Fit.
    **static** False > C++ defination code: > ```cpp > void add_class(image::Image &img, image::Fit fit image::FIT_COVER) > ``` #### class\\_num {#class\\_num} Get class number item description **type** func **static** False > C++ defination code: > ```cpp > int class_num() > ``` #### rm\\_class {#rm\\_class} Remove a class item description **type** func **param** **idx**: index, value from 0 to class_num();
    **static** False > C++ defination code: > ```cpp > err::Err rm_class(int idx) > ``` #### add\\_sample {#add\\_sample} Add sample, you should call learn method after add some samples to learn classes.\\nSample image can be any of classes we already added. item description **type** func **param** **img**: Add a image as a new sample.
    **static** False > C++ defination code: > ```cpp > void add_sample(image::Image &img, image::Fit fit image::FIT_COVER) > ``` #### rm\\_sample {#rm\\_sample} Remove a sample item description **type** func **param** **idx**: index, value from 0 to sample_num();
    **static** False > C++ defination code: > ```cpp > err::Err rm_sample(int idx) > ``` #### sample\\_num {#sample\\_num} Get sample number item description **type** func **static** False > C++ defination code: > ```cpp > int sample_num() > ``` #### learn {#learn} Start auto learn class features from classes image and samples.\\nYou should call this method after you add some samples. item description **type** func **return** learn epoch(times), 0 means learn nothing. **static** False > C++ defination code: > ```cpp > int learn() > ``` #### clear {#clear 2} Clear all class and samples item description **type** func **static** False > C++ defination code: > ```cpp > void clear() > ``` #### input\\_size {#input\\_size 4} Get model input size, only for image input item description **type** func **return** model input size **static** False > C++ defination code: > ```cpp > image::Size input_size() > ``` #### input\\_width {#input\\_width 4} Get model input width, only for image input item description **type** func **return** model input size of width **static** False > C++ defination code: > ```cpp > int input_width() > ``` #### input\\_height {#input\\_height 4} Get model input height, only for image input item description **type** func **return** model input size of height **static** False > C++ defination code: > ```cpp > int input_height() > ``` #### input\\_format {#input\\_format 4} Get input image format, only for image input item description **type** func **return** input image format, image::Format type. **static** False > C++ defination code: > ```cpp > image::Format input_format() > ``` #### input\\_shape {#input\\_shape} Get input shape, if have multiple input, only return first input shape item description **type** func **return** input shape, list type **static** False > C++ defination code: > ```cpp > std::vector input_shape() > ``` #### save {#save} Save features and labels to a binary file item description **type** func **param** **path**: file path to save, e.g. /root/my_classes.bin
    **labels**: class labels, can be None, or length must equal to class num, or will return err::Err
    **return** maix.err.Err if labels exists but length not equal to class num, or save file failed, or class num is 0. **static** False > C++ defination code: > ```cpp > err::Err save(const std::string &path, const std::vector &labels std::vector()) > ``` #### load {#load 7} Load features info from binary file item description **type** func **param** **path**: feature info binary file path, e.g. /root/my_classes.bin
    **static** False > C++ defination code: > ```cpp > std::vector load(const std::string &path) > ``` #### labels {#labels 3} Labels list item description **type** var **static** False **readonly** False > C++ defination code: > ```cpp > std::vector labels > ``` #### label\\_path {#label\\_path 2} Label file path item description **type** var **static** False **readonly** False > C++ defination code: > ```cpp > std::string label_path > ``` #### mean {#mean 4} Get mean value, list type item description **type** var **static** False **readonly** False > C++ defination code: > ```cpp > std::vector mean > ``` #### scale {#scale 4} Get scale value, list type item description **type** var **static** False **readonly** False > C++ defination code: > ```cpp > std::vector scale > ``` ### YOLOv5 {#YOLOv5} YOLOv5 class > C++ defination code: > ```cpp > class YOLOv5 > ``` #### YOLOv5 {#YOLOv5 2} Constructor of YOLOv5 class item description **type** func **param** **model**: model path, default empty, you can load model later by load function.
    **dual_buff**: direction [in], prepare dual input output buffer to accelarate forward, that is, when NPU is forwarding we not wait and prepare the next input buff.
    If you want to ensure every time forward output the input's result, set this arg to false please.
    Default true to ensure speed.
    **throw** If model arg is not empty and load failed, will throw err::Exception. **static** False > C++ defination code: > ```cpp > YOLOv5(const string &model \"\", bool dual_buff true) > ``` #### load {#load 8} Load model from file item description **type** func **param** **model**: Model path want to load
    **return** err::Err **static** False > C++ defination code: > ```cpp > err::Err load(const string &model) > ``` #### detect {#detect 2} Detect objects from image item description **type** func **param** **img**: Image want to detect, if image's size not match model input's, will auto resize with fit method.
    **conf_th**: Confidence threshold, default 0.5.
    **iou_th**: IoU threshold, default 0.45.
    **fit**: Resize method, default image.Fit.FIT_CONTAIN.
    **throw** If image format not match model input format, will throw err::Exception. **return** Object list. In C++, you should delete it after use. **static** False > C++ defination code: > ```cpp > std::vector *detect(image::Image &img, float conf_th 0.5, float iou_th 0.45, maix::image::Fit fit maix::image::FIT_CONTAIN) > ``` #### input\\_size {#input\\_size 5} Get model input size item description **type** func **return** model input size **static** False > C++ defination code: > ```cpp > image::Size input_size() > ``` #### input\\_width {#input\\_width 5} Get model input width item description **type** func **return** model input size of width **static** False > C++ defination code: > ```cpp > int input_width() > ``` #### input\\_height {#input\\_height 5} Get model input height item description **type** func **return** model input size of height **static** False > C++ defination code: > ```cpp > int input_height() > ``` #### input\\_format {#input\\_format 5} Get input image format item description **type** func **return** input image format, image::Format type. **static** False > C++ defination code: > ```cpp > image::Format input_format() > ``` #### labels {#labels 4} Labels list item description **type** var **static** False **readonly** False > C++ defination code: > ```cpp > std::vector labels > ``` #### label\\_path {#label\\_path 3} Label file path item description **type** var **static** False **readonly** False > C++ defination code: > ```cpp > std::string label_path > ``` #### mean {#mean 5} Get mean value, list type item description **type** var **static** False **readonly** False > C++ defination code: > ```cpp > std::vector mean > ``` #### scale {#scale 5} Get scale value, list type item description **type** var **static** False **readonly** False > C++ defination code: > ```cpp > std::vector scale > ``` #### anchors {#anchors} Get anchors item description **type** var **static** False **readonly** False > C++ defination code: > ```cpp > std::vector anchors > ``` ### YOLO11 {#YOLO11} YOLO11 class > C++ defination code: > ```cpp > class YOLO11 > ``` #### YOLO11 {#YOLO11 2} Constructor of YOLO11 class item description **type** func **param** **model**: model path, default empty, you can load model later by load function.
    **dual_buff**: direction [in], prepare dual input output buffer to accelarate forward, that is, when NPU is forwarding we not wait and prepare the next input buff.
    If you want to ensure every time forward output the input's result, set this arg to false please.
    Default true to ensure speed.
    **throw** If model arg is not empty and load failed, will throw err::Exception. **static** False > C++ defination code: > ```cpp > YOLO11(const string &model \"\", bool dual_buff true) > ``` #### load {#load 9} Load model from file item description **type** func **param** **model**: Model path want to load
    **return** err::Err **static** False > C++ defination code: > ```cpp > err::Err load(const string &model) > ``` #### detect {#detect 3} Detect objects from image item description **type** func **param** **img**: Image want to detect, if image's size not match model input's, will auto resize with fit method.
    **conf_th**: Confidence threshold, default 0.5.
    **iou_th**: IoU threshold, default 0.45.
    **fit**: Resize method, default image.Fit.FIT_CONTAIN.
    **keypoint_th**: keypoint threshold, default 0.5, only for yolo11 pose model.
    **throw** If image format not match model input format, will throw err::Exception. **return** Object list. In C++, you should delete it after use.
    If model is yolo11 pose, object's points have value, and if points' value < 0 means that point is invalid(conf < keypoint_th). **static** False > C++ defination code: > ```cpp > nn::Objects *detect(image::Image &img, float conf_th 0.5, float iou_th 0.45, maix::image::Fit fit maix::image::FIT_CONTAIN, float keypoint_th 0.5) > ``` #### input\\_size {#input\\_size 6} Get model input size item description **type** func **return** model input size **static** False > C++ defination code: > ```cpp > image::Size input_size() > ``` #### input\\_width {#input\\_width 6} Get model input width item description **type** func **return** model input size of width **static** False > C++ defination code: > ```cpp > int input_width() > ``` #### input\\_height {#input\\_height 6} Get model input height item description **type** func **return** model input size of height **static** False > C++ defination code: > ```cpp > int input_height() > ``` #### input\\_format {#input\\_format 6} Get input image format item description **type** func **return** input image format, image::Format type. **static** False > C++ defination code: > ```cpp > image::Format input_format() > ``` #### draw\\_pose {#draw\\_pose 2} Draw pose keypoints on image item description **type** func **param** **img**: image object, maix.image.Image type.
    **points**: keypoits, int list type, [x, y, x, y ...]
    **radius**: radius of points.
    **color**: color of points.
    **body**: true, if points' length is 17*2 and body is ture, will draw lines as human body, if set to false won't draw lines, default true.
    **static** False > C++ defination code: > ```cpp > void draw_pose(image::Image &img, std::vector points, int radius 4, image::Color color image::COLOR_RED, bool body true) > ``` #### draw\\_seg\\_mask {#draw\\_seg\\_mask 2} Draw segmentation on image item description **type** func **param** **img**: image object, maix.image.Image type.
    **seg_mask**: segmentation mask image by detect method, a grayscale image
    **threshold**: only mask's value > threshold will be draw on image, value from 0 to 255.
    **static** False > C++ defination code: > ```cpp > void draw_seg_mask(image::Image &img, int x, int y, image::Image &seg_mask, int threshold 127) > ``` #### labels {#labels 5} Labels list item description **type** var **static** False **readonly** False > C++ defination code: > ```cpp > std::vector labels > ``` #### label\\_path {#label\\_path 4} Label file path item description **type** var **static** False **readonly** False > C++ defination code: > ```cpp > std::string label_path > ``` #### mean {#mean 6} Get mean value, list type item description **type** var **static** False **readonly** False > C++ defination code: > ```cpp > std::vector mean > ``` #### scale {#scale 6} Get scale value, list type item description **type** var **static** False **readonly** False > C++ defination code: > ```cpp > std::vector scale > ``` ### Classifier {#Classifier} Classifier > C++ defination code: > ```cpp > class Classifier > ``` #### Classifier {#Classifier 2} Construct a new Classifier object item description **type** func **param** **model**: MUD model path, if empty, will not load model, you can call load() later.
    if not empty, will load model and will raise err::Exception if load failed.
    **dual_buff**: direction [in], prepare dual input output buffer to accelarate forward, that is, when NPU is forwarding we not wait and prepare the next input buff.
    If you want to ensure every time forward output the input's result, set this arg to false please.
    Default true to ensure speed.
    **static** False > C++ defination code: > ```cpp > Classifier(const string &model \"\", bool dual_buff true) > ``` #### load {#load 10} Load model from file, model format is .mud,\\nMUD file should contain [extra] section, have key values:\\n model_type: classifier\\n input_type: rgb or bgr\\n mean: 123.675, 116.28, 103.53\\n scale: 0.017124753831663668, 0.01750700280112045, 0.017429193899782137\\n labels: imagenet_classes.txt item description **type** func **param** **model**: MUD model path
    **return** error code, if load failed, return error code **static** False > C++ defination code: > ```cpp > err::Err load(const string &model) > ``` #### classify {#classify 2} Forward image to model, get result. Only for image input, use classify_raw for tensor input. item description **type** func **param** **img**: image, format should match model input_type, or will raise err.Exception
    **softmax**: if true, will do softmax to result, or will return raw value
    **fit**: image resize fit mode, default Fit.FIT_COVER, see image.Fit.
    **throw** If error occurred, will raise err::Exception, you can find reason in log, mostly caused by args error or hardware error. **return** result, a list of (label, score). If in dual_buff mode, value can be one element list and score is zero when not ready. In C++, you need to delete it after use. **static** False > C++ defination code: > ```cpp > std::vector> *classify(image::Image &img, bool softmax true, image::Fit fit image::FIT_COVER) > ``` #### classify\\_raw {#classify\\_raw} Forward tensor data to model, get result item description **type** func **param** **data**: tensor data, format should match model input_type, or will raise err.Excetion
    **softmax**: if true, will do softmax to result, or will return raw value
    **throw** If error occurred, will raise err::Exception, you can find reason in log, mostly caused by args error or hardware error. **return** result, a list of (label, score). In C++, you need to delete it after use. **static** False > C++ defination code: > ```cpp > std::vector> *classify_raw(tensor::Tensor &data, bool softmax true) > ``` #### input\\_size {#input\\_size 7} Get model input size, only for image input item description **type** func **return** model input size **static** False > C++ defination code: > ```cpp > image::Size input_size() > ``` #### input\\_width {#input\\_width 7} Get model input width, only for image input item description **type** func **return** model input size of width **static** False > C++ defination code: > ```cpp > int input_width() > ``` #### input\\_height {#input\\_height 7} Get model input height, only for image input item description **type** func **return** model input size of height **static** False > C++ defination code: > ```cpp > int input_height() > ``` #### input\\_format {#input\\_format 7} Get input image format, only for image input item description **type** func **return** input image format, image::Format type. **static** False > C++ defination code: > ```cpp > image::Format input_format() > ``` #### input\\_shape {#input\\_shape 2} Get input shape, if have multiple input, only return first input shape item description **type** func **return** input shape, list type **static** False > C++ defination code: > ```cpp > std::vector input_shape() > ``` #### labels {#labels 6} Labels list item description **type** var **static** False **readonly** False > C++ defination code: > ```cpp > std::vector labels > ``` #### label\\_path {#label\\_path 5} Label file path item description **type** var **static** False **readonly** False > C++ defination code: > ```cpp > std::string label_path > ``` #### mean {#mean 7} Get mean value, list type item description **type** var **static** False **readonly** False > C++ defination code: > ```cpp > std::vector mean > ``` #### scale {#scale 7} Get scale value, list type item description **type** var **static** False **readonly** False > C++ defination code: > ```cpp > std::vector scale > ``` ### Retinaface {#Retinaface} Retinaface class > C++ defination code: > ```cpp > class Retinaface > ``` #### Retinaface {#Retinaface 2} Constructor of Retinaface class item description **type** func **param** **model**: model path, default empty, you can load model later by load function.
    **dual_buff**: direction [in], prepare dual input output buffer to accelarate forward, that is, when NPU is forwarding we not wait and prepare the next input buff.
    If you want to ensure every time forward output the input's result, set this arg to false please.
    Default true to ensure speed.
    **throw** If model arg is not empty and load failed, will throw err::Exception. **static** False > C++ defination code: > ```cpp > Retinaface(const string &model \"\", bool dual_buff true) > ``` #### load {#load 11} Load model from file item description **type** func **param** **model**: Model path want to load
    **return** err::Err **static** False > C++ defination code: > ```cpp > err::Err load(const string &model) > ``` #### detect {#detect 4} Detect objects from image item description **type** func **param** **img**: Image want to detect, if image's size not match model input's, will auto resize with fit method.
    **conf_th**: Confidence threshold, default 0.4.
    **iou_th**: IoU threshold, default 0.45.
    **fit**: Resize method, default image.Fit.FIT_CONTAIN.
    **throw** If image format not match model input format, will throw err::Exception. **return** Object list. In C++, you should delete it after use. **static** False > C++ defination code: > ```cpp > std::vector *detect(image::Image &img, float conf_th 0.4, float iou_th 0.45, maix::image::Fit fit maix::image::FIT_CONTAIN) > ``` #### input\\_size {#input\\_size 8} Get model input size item description **type** func **return** model input size **static** False > C++ defination code: > ```cpp > image::Size input_size() > ``` #### input\\_width {#input\\_width 8} Get model input width item description **type** func **return** model input size of width **static** False > C++ defination code: > ```cpp > int input_width() > ``` #### input\\_height {#input\\_height 8} Get model input height item description **type** func **return** model input size of height **static** False > C++ defination code: > ```cpp > int input_height() > ``` #### input\\_format {#input\\_format 8} Get input image format item description **type** func **return** input image format, image::Format type. **static** False > C++ defination code: > ```cpp > image::Format input_format() > ``` #### mean {#mean 8} Get mean value, list type item description **type** var **static** False **readonly** False > C++ defination code: > ```cpp > std::vector mean > ``` #### scale {#scale 8} Get scale value, list type item description **type** var **static** False **readonly** False > C++ defination code: > ```cpp > std::vector scale > ``` ### FaceDetector {#FaceDetector} FaceDetector class > C++ defination code: > ```cpp > class FaceDetector > ``` #### FaceDetector {#FaceDetector 2} Constructor of FaceDetector class item description **type** func **param** **model**: model path, default empty, you can load model later by load function.
    **dual_buff**: direction [in], prepare dual input output buffer to accelarate forward, that is, when NPU is forwarding we not wait and prepare the next input buff.
    If you want to ensure every time forward output the input's result, set this arg to false please.
    Default true to ensure speed.
    **throw** If model arg is not empty and load failed, will throw err::Exception. **static** False > C++ defination code: > ```cpp > FaceDetector(const string &model \"\", bool dual_buff true) > ``` #### load {#load 12} Load model from file item description **type** func **param** **model**: Model path want to load
    **return** err::Err **static** False > C++ defination code: > ```cpp > err::Err load(const string &model) > ``` #### detect {#detect 5} Detect objects from image item description **type** func **param** **img**: Image want to detect, if image's size not match model input's, will auto resize with fit method.
    **conf_th**: Confidence threshold, default 0.5.
    **iou_th**: IoU threshold, default 0.45.
    **fit**: Resize method, default image.Fit.FIT_CONTAIN.
    **throw** If image format not match model input format, will throw err::Exception. **return** Object list. In C++, you should delete it after use. **static** False > C++ defination code: > ```cpp > std::vector *detect(image::Image &img, float conf_th 0.5, float iou_th 0.45, maix::image::Fit fit maix::image::FIT_CONTAIN) > ``` #### input\\_size {#input\\_size 9} Get model input size item description **type** func **return** model input size **static** False > C++ defination code: > ```cpp > image::Size input_size() > ``` #### input\\_width {#input\\_width 9} Get model input width item description **type** func **return** model input size of width **static** False > C++ defination code: > ```cpp > int input_width() > ``` #### input\\_height {#input\\_height 9} Get model input height item description **type** func **return** model input size of height **static** False > C++ defination code: > ```cpp > int input_height() > ``` #### input\\_format {#input\\_format 9} Get input image format item description **type** func **return** input image format, image::Format type. **static** False > C++ defination code: > ```cpp > image::Format input_format() > ``` #### mean {#mean 9} Get mean value, list type item description **type** var **static** False **readonly** False > C++ defination code: > ```cpp > std::vector mean > ``` #### scale {#scale 9} Get scale value, list type item description **type** var **static** False **readonly** False > C++ defination code: > ```cpp > std::vector scale > ``` ### PP\\_OCR {#PP\\_OCR} PP_OCR class > C++ defination code: > ```cpp > class PP_OCR > ``` #### PP\\_OCR {#PP\\_OCR 2} Constructor of PP_OCR class item description **type** func **param** **model**: model path, default empty, you can load model later by load function.
    **throw** If model arg is not empty and load failed, will throw err::Exception. **static** False > C++ defination code: > ```cpp > PP_OCR(const string &model \"\") > ``` #### load {#load 13} Load model from file item description **type** func **param** **model**: Model path want to load
    **return** err::Err **static** False > C++ defination code: > ```cpp > err::Err load(const string &model) > ``` #### detect {#detect 6} Detect objects from image item description **type** func **param** **img**: Image want to detect, if image's size not match model input's, will auto resize with fit method.
    **thresh**: Confidence threshold where pixels have charactor, default 0.3.
    **box_thresh**: Box threshold, the box prob higher than this value will be valid, default 0.6.
    **fit**: Resize method, default image.Fit.FIT_CONTAIN.
    **char_box**: Calculate every charactor's box, default false, if true then you can get charactor's box by nn.OCR_Object's char_boxes attribute.
    **throw** If image format not match model input format or no memory, will throw err::Exception. **return** nn.OCR_Objects type. In C++, you should delete it after use. **static** False > C++ defination code: > ```cpp > nn::OCR_Objects *detect(image::Image &img, float thresh 0.3, float box_thresh 0.6, maix::image::Fit fit maix::image::FIT_CONTAIN, bool char_box false) > ``` #### recognize {#recognize 2} Only recognize, not detect item description **type** func **param** **img**: image to recognize chractors, can be a stanrd cropped charactors image,
    if crop image not standard, you can use box_points to assgin where the charactors' 4 corner is.
    **box_points**: list type, length must be 8 or 0, default empty means not transfer image to standard image.
    4 points postiion, format: [x1, y1, x2, y2, x3, y3, x4, y4], point 1 at the left top, point 2 right top...
    **char_box**: Calculate every charactor's box, default false, if true then you can get charactor's box by nn.OCR_Object's char_boxes attribute.
    **static** False > C++ defination code: > ```cpp > nn::OCR_Object *recognize(image::Image &img, const std::vector &box_points std::vector()) > ``` #### draw\\_seg\\_mask {#draw\\_seg\\_mask 3} Draw segmentation on image item description **type** func **param** **img**: image object, maix.image.Image type.
    **seg_mask**: segmentation mask image by detect method, a grayscale image
    **threshold**: only mask's value > threshold will be draw on image, value from 0 to 255.
    **static** False > C++ defination code: > ```cpp > void draw_seg_mask(image::Image &img, int x, int y, image::Image &seg_mask, int threshold 127) > ``` #### input\\_size {#input\\_size 10} Get model input size item description **type** func **return** model input size **static** False > C++ defination code: > ```cpp > image::Size input_size() > ``` #### input\\_width {#input\\_width 10} Get model input width item description **type** func **return** model input size of width **static** False > C++ defination code: > ```cpp > int input_width() > ``` #### input\\_height {#input\\_height 10} Get model input height item description **type** func **return** model input size of height **static** False > C++ defination code: > ```cpp > int input_height() > ``` #### input\\_format {#input\\_format 10} Get input image format item description **type** func **return** input image format, image::Format type. **static** False > C++ defination code: > ```cpp > image::Format input_format() > ``` #### mean {#mean 10} Get mean value, list type item description **type** var **static** False **readonly** False > C++ defination code: > ```cpp > std::vector mean > ``` #### scale {#scale 10} Get scale value, list type item description **type** var **static** False **readonly** False > C++ defination code: > ```cpp > std::vector scale > ``` #### rec\\_mean {#rec\\_mean} Get mean value, list type item description **type** var **static** False **readonly** False > C++ defination code: > ```cpp > std::vector rec_mean > ``` #### rec\\_scale {#rec\\_scale} Get scale value, list type item description **type** var **static** False **readonly** False > C++ defination code: > ```cpp > std::vector rec_scale > ``` #### labels {#labels 7} labels (charactors) item description **type** var **static** False **readonly** False > C++ defination code: > ```cpp > std::vector labels > ``` #### det {#det} model have detect model item description **type** var **static** False **readonly** False > C++ defination code: > ```cpp > bool det > ``` #### rec {#rec} model have recognize model item description **type** var **static** False **readonly** False > C++ defination code: > ```cpp > bool rec > ```"},"/maixcdk/api/maix/http.html":{"title":"maix::http","content":" title: maix::http maix.http module > This is `maix::http` module of [MaixCDK](https://github.com/sipeed/MaixCDK). > All of these elements are in namespace `maix::http`. > > For MaixCDK developer: DO NOT edit this doc file manually, this doc is auto generated! ## Module {#Module} No module ## Enum {#Enum} ## Variable {#Variable} ## Function {#Function} ## Class {#Class} ### JpegStreamer {#JpegStreamer} JpegStreamer class > C++ defination code: > ```cpp > class JpegStreamer > ``` #### JpegStreamer {#JpegStreamer 2} Construct a new jpeg streamer object item description **type** func **note** You can get the picture stream through http://host:port/stream, you can also get it through http://ip:port, and you can add personal style through set_html() at this time **param** **host**: http host
    **port**: http port, default is 8000
    **client_number**: the max number of client
    **static** False > C++ defination code: > ```cpp > JpegStreamer(std::string host std::string(), int port 8000, int client_number 16) > ``` #### start {#start} start jpeg streame item description **type** func **return** error code, err::ERR_NONE means success, others means failed **static** False > C++ defination code: > ```cpp > err::Err start() > ``` #### start (overload 1) {#start (overload 1)} stop http item description **type** func **return** error code, err::ERR_NONE means success, others means failed **static** False > C++ defination code: > ```cpp > err::Err stop() > ``` #### write {#write} Write data to http item description **type** func **param** **img**: image object
    **return** error code, err::ERR_NONE means success, others means failed **static** False > C++ defination code: > ```cpp > err::Err write(image::Image *img) > ``` #### set\\_html {#set\\_html} add your style in this api\\ndefault is:\\n\\n\\n

    JPG Stream

    \\n\\n\\n item description **type** func **param** **data**: html code
    **return** error code, err::ERR_NONE means success, others means failed **static** False > C++ defination code: > ```cpp > err::Err set_html(std::string data) > ``` #### host {#host} Get host item description **type** func **return** host name **static** False > C++ defination code: > ```cpp > std::string host() > ``` #### port {#port} Get port item description **type** func **return** port **static** False > C++ defination code: > ```cpp > int port() > ```"},"/maixcdk/api/maix/peripheral/pwm.html":{"title":"maix::peripheral::pwm","content":" title: maix::peripheral::pwm maix.peripheral.pwm module > This is `maix::peripheral::pwm` module of [MaixCDK](https://github.com/sipeed/MaixCDK). > All of these elements are in namespace `maix::peripheral::pwm`. > > For MaixCDK developer: DO NOT edit this doc file manually, this doc is auto generated! ## Module {#Module} No module ## Enum {#Enum} ## Variable {#Variable} ## Function {#Function} ## Class {#Class} ### PWM {#PWM} Peripheral pwm class > C++ defination code: > ```cpp > class PWM > ``` #### \\_\\_init\\_\\_ {#\\_\\_init\\_\\_} PWM constructor item description **type** func **param** **pin**: direction [in], pwm id, int type, like 0, 1, 2 etc.
    **freq**: direction [in], pwm frequency, unit: Hz. int type. default is 1000
    **duty**: direction [in], pwm duty. double type. range is [0, 100], default is 0.
    **enable**: direction [in], enable pwm output right now. bool type. default is true, if false, you need to call enable() to enable pwm output.
    **duty_val**: direction [in], pwm duty value, int type. default 1 means not set and auto calculate by freq and duty.
    This arg directly set pwm duty value, if set, will ignore duty arg.
    duty_val duty / 100 * T_ns, T_ns 1 / freq * 1000000000.
    **throw** If args error or init pwm failed, will throw err::Exception **static** False > C++ defination code: > ```cpp > PWM(int id, int freq 1000, double duty 0, bool enable true, int duty_val 1) > ``` #### duty {#duty} get or set pwm duty item description **type** func **param** **duty**: direction [in], pwm duty, double type, value in [0, 100], default 1 means only read.
    **return** current duty, float type, if set and set failed will return err::Err **static** False > C++ defination code: > ```cpp > double duty(double duty 1) > ``` #### duty\\_val {#duty\\_val} set pwm duty value item description **type** func **param** **duty_val**: direction [in], pwm duty value. int type. default is 1
    duty_val > 0 means set duty_val
    duty_val 1 or not set, return current duty_val
    **return** int type
    when get duty_val, return current duty_val, else return err::Err code. **static** False > C++ defination code: > ```cpp > int duty_val(int duty_val 1) > ``` #### freq {#freq} get or set pwm frequency item description **type** func **param** **freq**: direction [in], pwm frequency. int type. default is 1
    freq > 0, set freq
    freq 1 or not set, return current freq
    **return** int type, current freq, if set and set failed will return err::Err **static** False > C++ defination code: > ```cpp > int freq(int freq 1) > ``` #### enable {#enable} set pwm enable item description **type** func **return** err::Err type, err.Err.ERR_NONE means success **static** False > C++ defination code: > ```cpp > err::Err enable() > ``` #### disable {#disable} set pwm disable item description **type** func **return** err::Err type, err.Err.ERR_NONE means success **static** False > C++ defination code: > ```cpp > err::Err disable() > ``` #### is\\_enabled {#is\\_enabled} get pwm enable status item description **type** func **return** bool type, true means enable, false means disable **static** False > C++ defination code: > ```cpp > bool is_enabled() > ```"},"/maixcdk/api/maix/peripheral/wdt.html":{"title":"maix::peripheral::wdt","content":" title: maix::peripheral::wdt maix.peripheral.wdt module > This is `maix::peripheral::wdt` module of [MaixCDK](https://github.com/sipeed/MaixCDK). > All of these elements are in namespace `maix::peripheral::wdt`. > > For MaixCDK developer: DO NOT edit this doc file manually, this doc is auto generated! ## Module {#Module} No module ## Enum {#Enum} ## Variable {#Variable} ## Function {#Function} ## Class {#Class} ### WDT {#WDT} Peripheral wdt class > C++ defination code: > ```cpp > class WDT > ``` #### \\_\\_init\\_\\_ {#\\_\\_init\\_\\_} WDT constructor, after construct, the wdt will auto start. item description **type** func **param** **id**: direction [in], id of wdt, int type
    **feed_ms**: direction [in], feed interval, int type, unit is ms, you must feed wdt in this interval, or system will restart.
    **static** False > C++ defination code: > ```cpp > WDT(int id, int feed_ms) > ``` #### feed {#feed} feed wdt item description **type** func **return** error code, if feed success, return err::ERR_NONE **static** False > C++ defination code: > ```cpp > int feed() > ``` #### stop {#stop} stop wdt item description **type** func **static** False > C++ defination code: > ```cpp > int stop() > ``` #### restart {#restart} restart wdt, stop and start watchdog timer. item description **type** func **static** False > C++ defination code: > ```cpp > int restart() > ```"},"/maixcdk/api/maix/peripheral/uart.html":{"title":"maix::peripheral::uart","content":" title: maix::peripheral::uart maix uart peripheral driver > This is `maix::peripheral::uart` module of [MaixCDK](https://github.com/sipeed/MaixCDK). > All of these elements are in namespace `maix::peripheral::uart`. > > For MaixCDK developer: DO NOT edit this doc file manually, this doc is auto generated! ## Module {#Module} No module ## Enum {#Enum} ### PARITY {#PARITY} uart parity enum item describe **values** **PARITY_NONE**: no parity
    **PARITY_ODD**: odd parity
    **PARITY_EVEN**: even parity
    **PARITY_MAX**:
    > C++ defination code: > ```cpp > enum PARITY > { > PARITY_NONE 0x00, // no parity > PARITY_ODD 0x01, // odd parity > PARITY_EVEN 0x02, // even parity > PARITY_MAX > } > ``` ### STOP {#STOP} uart stop bits item describe **values** **STOP_1**: 1 stop bit
    **STOP_2**: 2 stop bits
    **STOP_1_5**: 1.5 stop bits
    **STOP_MAX**:
    > C++ defination code: > ```cpp > enum STOP > { > STOP_1 0x01, // 1 stop bit > STOP_2 0x02, // 2 stop bits > STOP_1_5 0x03, // 1.5 stop bits > STOP_MAX > } > ``` ### BITS {#BITS} uart stop bits item describe **values** **BITS_5**: 5 data bits
    **BITS_6**: 6 data bits
    **BITS_7**: 7 data bits
    **BITS_8**: 8 data bits
    **BITS_MAX**:
    > C++ defination code: > ```cpp > enum BITS > { > BITS_5 5, // 5 data bits > BITS_6 6, // 6 data bits > BITS_7 7, // 7 data bits > BITS_8 8, // 8 data bits > BITS_MAX > } > ``` ### FLOW\\_CTRL {#FLOW\\_CTRL} uart flow control item describe **values** **FLOW_CTRL_NONE**: no flow control
    **FLOW_CTRL_HW**: hardware flow control
    **FLOW_CTRL_MAX**:
    > C++ defination code: > ```cpp > enum FLOW_CTRL > { > FLOW_CTRL_NONE 0, // no flow control > FLOW_CTRL_HW 1, // hardware flow control > FLOW_CTRL_MAX > } > ``` ## Variable {#Variable} ## Function {#Function} ### list\\_devices {#list\\_devices} Get supported uart ports. item description **return** uart ports list, string type. > C++ defination code: > ```cpp > std::vector list_devices() > ``` ## Class {#Class} ### UART {#UART} maix uart peripheral driver > C++ defination code: > ```cpp > class UART : public comm::CommBase > ``` #### \\_\\_init\\_\\_ {#\\_\\_init\\_\\_} UART constructor. You need to call open() to open the device. item description **type** func **param** **port**: uart port. string type, can get it by uart.list_devices().
    If empty, will not open device in constructor, default empty.
    if not empty, will auto open device in constructor, open fail will throw err.Exception.
    **baudrate**: baudrate of uart. int type, default 115200.
    **databits**: databits, values @see uart.DATA_BITS
    **parity**: parity, values @see uart.PARITY
    **stopbits**: stopbits, values @see uart.STOP_BITS
    **flow_control**: flow_control, values @see uart.FLOW_CTRL
    **static** False > C++ defination code: > ```cpp > UART(const std::string &port \"\", int baudrate 115200, uart::BITS databits uart::BITS_8, > uart::PARITY parity uart::PARITY_NONE, uart::STOP stopbits uart::STOP_1, > uart::FLOW_CTRL flow_ctrl uart::FLOW_CTRL_NONE) > ``` #### set\\_port {#set\\_port} Set port item description **type** func **param** **port**: uart port. string type, can get it by uart.list_devices().
    **return** set port error code, err.Err type. **static** False > C++ defination code: > ```cpp > err::Err set_port(const std::string &port) > ``` #### get\\_port {#get\\_port} Get port item description **type** func **return** uart port, string type. **static** False > C++ defination code: > ```cpp > std::string get_port() > ``` #### set\\_baudrate {#set\\_baudrate} Set baud rate item description **type** func **param** **baudrate**: baudrate of uart. int type, default 115200.
    **return** set baud rate error code, err.Err type. **static** False > C++ defination code: > ```cpp > err::Err set_baudrate(int baudrate) > ``` #### get\\_baudrate {#get\\_baudrate} Get baud rate item description **type** func **return** baud rate, int type. **static** False > C++ defination code: > ```cpp > int get_baudrate() > ``` #### open {#open} Open uart device, before open, port must be set in constructor or by set_port().\\nIf already opened, do nothing and return err.ERR_NONE. item description **type** func **return** open device error code, err.Err type. **static** False > C++ defination code: > ```cpp > err::Err open() > ``` #### is\\_open {#is\\_open} Check if device is opened. item description **type** func **return** true if opened, false if not opened. **static** False > C++ defination code: > ```cpp > bool is_open() > ``` #### close {#close} Close uart device, if already closed, do nothing and return err.ERR_NONE. item description **type** func **return** close device error code, err.Err type. **static** False > C++ defination code: > ```cpp > err::Err close() > ``` #### set\\_received\\_callback {#set\\_received\\_callback} Set received callback function item description **type** func **param** **callback**: function to call when received data
    **static** False > C++ defination code: > ```cpp > void set_received_callback(std::function callback) > ``` #### write {#write} Send data to device item description **type** func **param** **buff**: data buffer
    **len**: data length need to send
    **return** sent data length, < 0 means error, value is err.Err. **static** False > C++ defination code: > ```cpp > int write(const uint8_t *buff, int len) > ``` #### write (overload 1) {#write (overload 1)} Send data to device item description **type** func **param** **buff**: data buffer
    **len**: data length need to send, if len 1, means buff is a string, send buff until '\\0'.
    **return** sent data length, < 0 means error, value is err.Err. **static** False > C++ defination code: > ```cpp > int write(const char *buff, int len 1) > ``` #### write (overload 2) {#write (overload 2)} Send string data item description **type** func **param** **str**: string data
    **return** sent data length, < 0 means error, value is err.Err. **static** False > C++ defination code: > ```cpp > int write(const std::string &str) > ``` #### write (overload 3) {#write (overload 3)} Send data to uart item description **type** func **param** **data**: direction [in], data to send, bytes type. If you want to send str type, use str.encode() to convert.
    **return** sent length, int type, if < 0 means error, value is err.Err. **static** False > C++ defination code: > ```cpp > int write(Bytes &data) > ``` #### write\\_str {#write\\_str} Send string data item description **type** func **param** **str**: string data
    **return** sent data length, < 0 means error, value is err.Err. **static** False > C++ defination code: > ```cpp > int write_str(const std::string &str) > ``` #### available {#available} Check if data available or wait data available. item description **type** func **param** **timeout**: unit ms, timeout to wait data, default 0.
    0 means check data available and return immediately,
    > 0 means wait until data available or timeout.
    1 means wait until data available.
    **return** available data number, 0 if timeout or no data, <0 if error, value is err.Err, can be err::ERR_IO, err::ERR_CANCEL, err::ERR_NOT_OPEN. **throw** err.Exception if fatal error. **static** False > C++ defination code: > ```cpp > int available(int timeout 0) > ``` #### read {#read} Receive data item description **type** func **param** **buff**: data buffer to store received data
    **buff_len**: data buffer length
    **recv_len**: max data length want to receive, default 1.
    1 means read data in uart receive buffer.
    >0 means read recv_len data want to receive.
    other values is invalid.
    **timeout**: unit ms, timeout to receive data, default 0.
    0 means read data in uart receive buffer and return immediately,
    1 means block until read recv_len data,
    >0 means block until read recv_len data or timeout.
    **return** received data length, < 0 means error, value is err.Err. **static** False > C++ defination code: > ```cpp > int read(uint8_t *buff, int buff_len, int recv_len 1, int timeout 0) > ``` #### read (overload 1) {#read (overload 1)} Recv data from uart item description **type** func **param** **len**: max data length want to receive, default 1.
    1 means read data in uart receive buffer.
    >0 means read len data want to receive.
    other values is invalid.
    **timeout**: unit ms, timeout to receive data, default 0.
    0 means read data in uart receive buffer and return immediately,
    1 means block until read len data,
    >0 means block until read len data or timeout.
    **return** received data, bytes type.
    Attention, you need to delete the returned object yourself in C++. **throw** Read failed will raise err.Exception error. **static** False > C++ defination code: > ```cpp > Bytes *read(int len 1, int timeout 0) > ``` #### readline {#readline} Read line from uart, that is read until '\\n' or '\\r\\n'. item description **type** func **param** **timeout**: unit ms, timeout to receive data, default 1 means block until read '\\n' or '\\r\\n'.
    > 0 means block until read '\\n' or '\\r\\n' or timeout.
    **return** received data, bytes type. If timeout will return the current received data despite not read '\\n' or '\\r\\n'.
    e.g. If we want to read b'123\\n', but when we only read b'12', timeout, then return b'12'. **static** False > C++ defination code: > ```cpp > Bytes *readline(int timeout 1) > ```"},"/maixcdk/api/maix/peripheral/adc.html":{"title":"maix::peripheral::adc","content":" title: maix::peripheral::adc maix.peripheral.adc module > This is `maix::peripheral::adc` module of [MaixCDK](https://github.com/sipeed/MaixCDK). > All of these elements are in namespace `maix::peripheral::adc`. > > For MaixCDK developer: DO NOT edit this doc file manually, this doc is auto generated! ## Module {#Module} No module ## Enum {#Enum} ## Variable {#Variable} ### RES\\_BIT\\_8 {#RES\\_BIT\\_8} 8 bit resolution, supported by the actual hardware item description **value** **8** **readonly** True > C++ defination code: > ```cpp > const int RES_BIT_8 8 > ``` ### RES\\_BIT\\_10 {#RES\\_BIT\\_10} 10 bit resolution, supported by the actual hardware item description **value** **10** **readonly** True > C++ defination code: > ```cpp > const int RES_BIT_10 10 > ``` ### RES\\_BIT\\_12 {#RES\\_BIT\\_12} 12 bit resolution, supported by the actual hardware item description **value** **12** **readonly** True > C++ defination code: > ```cpp > const int RES_BIT_12 12 > ``` ### RES\\_BIT\\_16 {#RES\\_BIT\\_16} 16 bit resolution, supported by the actual hardware item description **value** **16** **readonly** True > C++ defination code: > ```cpp > const int RES_BIT_16 16 > ``` ## Function {#Function} ## Class {#Class} ### ADC {#ADC} Peripheral adc class > C++ defination code: > ```cpp > class ADC > ``` #### \\_\\_init\\_\\_ {#\\_\\_init\\_\\_} ADC constructor item description **type** func **param** **pin**: direction [in], adc pin, int type
    **resolution**: direction [in], adc resolution. default is 1, means use default resolution
    option:
    resolution adc.RES_BIT_8, means 8 bit resolution
    resolution adc.RES_BIT_10, means 10 bit resolution
    resolution adc.RES_BIT_12, means 12 bit resolution
    resolution adc.RES_BIT_16, means 16 bit resolution
    the default resolution is determined by actual hardware.
    **vref**: direction [in], adc refer voltage. default is 1, means use default refer voltage.
    the default vref is determined by actual hardware. range: [0.0, 10.0]
    **static** False > C++ defination code: > ```cpp > ADC(int pin, int resolution, float vref 1) > ``` #### read {#read} read adc value item description **type** func **return** adc data, int type
    if resolution is 8 bit, return value range is [0, 255]
    if resolution is 10 bit, return value range is [0, 1023]
    if resolution is 12 bit, return value range is [0, 4095]
    if resolution is 16 bit, return value range is [0, 65535] **static** False > C++ defination code: > ```cpp > int read() > ``` #### read\\_vol {#read\\_vol} read adc voltage item description **type** func **return** adc voltage, float type。the range is [0.0, vref] **static** False > C++ defination code: > ```cpp > float read_vol() > ```"},"/maixcdk/api/maix/peripheral/hid.html":{"title":"maix::peripheral::hid","content":" title: maix::peripheral::hid maix.peripheral.hid module > This is `maix::peripheral::hid` module of [MaixCDK](https://github.com/sipeed/MaixCDK). > All of these elements are in namespace `maix::peripheral::hid`. > > For MaixCDK developer: DO NOT edit this doc file manually, this doc is auto generated! ## Module {#Module} No module ## Enum {#Enum} ### DeviceType {#DeviceType} Device enum of hid item describe **values** **DEVICE_MOUSE**:
    **DEVICE_KEYBOARD**:
    **DEVICE_TOUCHPAD**:
    > C++ defination code: > ```cpp > enum DeviceType { > DEVICE_MOUSE 0, > DEVICE_KEYBOARD, > DEVICE_TOUCHPAD > } > ``` ## Variable {#Variable} ## Function {#Function} ## Class {#Class} ### Hid {#Hid} Hid class > C++ defination code: > ```cpp > class Hid > ``` #### \\_\\_init\\_\\_ {#\\_\\_init\\_\\_} Hid Device constructor item description **type** func **param** **device_type**: Device type, used to select mouse, keyboard, or touchpad.
    **open**: auto open device in constructor, if false, you need call open() to open device
    **static** False > C++ defination code: > ```cpp > Hid(hid::DeviceType device_type, bool open true) > ``` #### open {#open} Open hid device item description **type** func **return** err::Err **static** False > C++ defination code: > ```cpp > err::Err open() > ``` #### close {#close} Close hid device item description **type** func **return** err::Err **static** False > C++ defination code: > ```cpp > err::Err close() > ``` #### write {#write} Write data to hid device item description **type** func **param** **data**: data to write
    For the keyboard, 8 bytes of data need to be written, with the format as follows:
    data [0x00, #
    0x00, #
    0x00, # Key value. Refer to the \"Universal Serial Bus HID Usage Tables\" section of the official documentation(https://www.usb.org).
    0x00, #
    0x00, #
    0x00, #
    0x00, #
    0x00] #
    For the mouse, 4 bytes of data need to be written, with the format as follows:
    data [0x00, # Button state
    0x00: no button pressed
    0x01: press left button
    0x02: press right button
    0x04: press middle button
    x, # X axis relative coordinates. Signed number, positive values for x indicate movement to the right
    y, # Y axis relative coordinates. Signed number, positive values for y indicate movement downward
    0x00] # Wheel movement. Signed number, positive values indicate downward movement.
    For the touchpad, 6 bytes of data need to be written, with the format as follows:
    data [0x00, # Button state (0: no button pressed, 0x01: press left button, 0x10, press right button.)
    x & 0xFF, (x >> 8) & 0xFF, # X axis absolute coordinate, 0 means unused.
    Note: You must map the target position to the range [0x1, 0x7FFF]. This means x value * 0x7FFF /
    y & 0xFF, (y >> 8) & 0xFF, # Y axis absolute coordinate, 0 means unused.
    Note: You must map the target position to the range [0x1, 0x7FFF]. This means y value * 0x7FFF /
    0x00, # Wheel movement. Signed number, positive values indicate downward movement.
    **return** err::Err **static** False > C++ defination code: > ```cpp > err::Err write(std::vector &data) > ``` #### is\\_opened {#is\\_opened} Check if hid device is opened item description **type** func **return** bool **static** False > C++ defination code: > ```cpp > bool is_opened() > ```"},"/maixcdk/api/maix/peripheral/gpio.html":{"title":"maix::peripheral::gpio","content":" title: maix::peripheral::gpio maix.peripheral.gpio module > This is `maix::peripheral::gpio` module of [MaixCDK](https://github.com/sipeed/MaixCDK). > All of these elements are in namespace `maix::peripheral::gpio`. > > For MaixCDK developer: DO NOT edit this doc file manually, this doc is auto generated! ## Module {#Module} No module ## Enum {#Enum} ### Mode {#Mode} GPIO mode item describe **values** **IN**: input mode
    **OUT**: output mode
    **OUT_OD**: output open drain mode
    **MODE_MAX**:
    > C++ defination code: > ```cpp > enum Mode > { > IN 0x01, // input mode > OUT 0x02, // output mode > OUT_OD 0x03, // output open drain mode > MODE_MAX > } > ``` ### Pull {#Pull} GPIO pull mode item describe **values** **PULL_NONE**: pull none mode
    **PULL_UP**: pull up mode
    **PULL_DOWN**: pull down mode
    **PULL_MAX**:
    > C++ defination code: > ```cpp > enum Pull > { > PULL_NONE 0x00, // pull none mode > PULL_UP 0x01, // pull up mode > PULL_DOWN 0x02, // pull down mode > PULL_MAX > } > ``` ## Variable {#Variable} ## Function {#Function} ## Class {#Class} ### GPIO {#GPIO} Peripheral gpio class > C++ defination code: > ```cpp > class GPIO > ``` #### \\_\\_init\\_\\_ {#\\_\\_init\\_\\_} GPIO constructor item description **type** func **param** **pin**: direction [in], gpio pin name, string type the same as board's pin name, e.g. \"B14\" or \"GPIOB14\", or number string like \"10\" if board no gpiochipe name.
    **mode**: direction [in], gpio mode. gpio.Mode type, default is gpio.Mode.IN (input) mode.
    **pull**: direction [in], gpio pull. gpio.Pull type, default is gpio.Pull.PULL_NONE (pull none) mode.
    For input mode, this will set gpio default status(value), if set to gpio.Pull.PULL_NONE, gpio value will be floating.
    For output mode, this will set gpio default status(value), if set to gpio.Pull.PULL_UP, gpio value will be 1, else 0.
    **throw** err::Exception if open gpio device failed. **static** False > C++ defination code: > ```cpp > GPIO(std::string pin, gpio::Mode mode gpio::Mode::IN, gpio::Pull pull gpio::Pull::PULL_NONE) > ``` #### value {#value} set and get gpio value item description **type** func **param** **value**: direction [in], gpio value. int type.
    0, means write gpio to low level
    1, means write gpio to high level
    1, means read gpio value, not set
    **return** int type, return gpio value, can be 0 or 1 **static** False > C++ defination code: > ```cpp > int value(int value 1) > ``` #### high {#high} set gpio high (value to 1) item description **type** func **static** False > C++ defination code: > ```cpp > void high() > ``` #### low {#low} set gpio low (value to 0) item description **type** func **static** False > C++ defination code: > ```cpp > void low() > ``` #### toggle {#toggle} gpio toggle item description **type** func **static** False > C++ defination code: > ```cpp > void toggle() > ``` #### get\\_mode {#get\\_mode} gpio get mode item description **type** func **static** False > C++ defination code: > ```cpp > gpio::Mode get_mode() > ``` #### get\\_pull {#get\\_pull} get gpio pull item description **type** func **return** gpio::Pull type **static** False > C++ defination code: > ```cpp > gpio::Pull get_pull() > ``` #### reset {#reset} reset gpio item description **type** func **param** **mode**: direction [in], gpio mode. gpio.Mode type
    **pull**: direction [in], gpio pull. gpio.Pull type
    For input mode, this will set gpio default status(value), if set to gpio.Pull.PULL_NONE, gpio value will be floating.
    For output mode, this will set gpio default status(value), if set to gpio.Pull.PULL_UP, gpio value will be 1, else 0.
    **return** err::Err type **static** False > C++ defination code: > ```cpp > err::Err reset(gpio::Mode mode, gpio::Pull pull) > ```"},"/maixcdk/api/maix/peripheral/spi.html":{"title":"maix::peripheral::spi","content":" title: maix::peripheral::spi maix.peripheral.spi module > This is `maix::peripheral::spi` module of [MaixCDK](https://github.com/sipeed/MaixCDK). > All of these elements are in namespace `maix::peripheral::spi`. > > For MaixCDK developer: DO NOT edit this doc file manually, this doc is auto generated! ## Module {#Module} No module ## Enum {#Enum} ### Mode {#Mode} SPI mode enum item describe **values** **MASTER**: spi master mode
    **SLAVE**: spi slave mode
    > C++ defination code: > ```cpp > enum Mode > { > MASTER 0x0, // spi master mode > SLAVE 0x1, // spi slave mode > } > ``` ## Variable {#Variable} ## Function {#Function} ## Class {#Class} ### SPI {#SPI} Peripheral spi class > C++ defination code: > ```cpp > class SPI > ``` #### \\_\\_init\\_\\_ {#\\_\\_init\\_\\_} SPI constructor item description **type** func **param** **id**: direction [in], spi bus id, int type
    **mode**: direction [in], mode of spi, spi.Mode type, spi.Mode.MASTER or spi.Mode.SLAVE.
    **freq**: direction [in], freq of spi, int type
    **polarity**: direction [in], polarity of spi, 0 means idle level of clock is low, 1 means high, int type, default is 0.
    **phase**: direction [in], phase of spi, 0 means data is captured on the first edge of the SPI clock cycle, 1 means second, int type, default is 0.
    **bits**: direction [in], bits of spi, int type, default is 8.
    **cs_enable**: direction [in], cs pin active level, default is 0(low)
    **soft_cs**: direction [in], not use hardware cs, bool type, if set true, you can operate cs pin use gpio manually.
    **cs**: direction [in], soft cs pin number, std::string type, default is \"GPIOA19\", if SPI support multi hardware cs, you can set it to other value.
    **static** False > C++ defination code: > ```cpp > SPI(int id, spi::Mode mode, int freq, int polarity 0, int phase 0, > int bits 8, unsigned char cs_enable 0, bool soft_cs false, std::string cs \"GPIOA19\") > ``` #### read {#read} read data from spi item description **type** func **param** **length**: direction [in], read length, int type
    **return** bytes data, Bytes type in C++, bytes type in MaixPy. You need to delete it manually after use in C++. **static** False > C++ defination code: > ```cpp > Bytes *read(int length) > ``` #### read (overload 1) {#read (overload 1)} read data from spi item description **type** func **param** **length**: direction [in], read length, unsigned int type
    **return** bytes data, vector type **static** False > C++ defination code: > ```cpp > std::vector read(unsigned int length) > ``` #### write {#write} write data to spi item description **type** func **param** **data**: direction [in], data to write, vector type
    the member range of the list is [0,255]
    **return** write length, int type, if write failed, return err::Err code. **static** False > C++ defination code: > ```cpp > int write(std::vector data) > ``` #### write (overload 1) {#write (overload 1)} write data to spi item description **type** func **param** **data**: direction [in], data to write, Bytes type in C++, bytes type in MaixPy
    **return** write length, int type, if write failed, return err::Err code. **static** False > C++ defination code: > ```cpp > int write(Bytes *data) > ``` #### write\\_read {#write\\_read} write data to spi and read data from spi at the same time. item description **type** func **param** **data**: direction [in], data to write, vector type.
    **read_len**: direction [in], read length, int type, should > 0.
    **return** read data, vector type **static** False > C++ defination code: > ```cpp > std::vector write_read(std::vector data, int read_len) > ``` #### write\\_read (overload 1) {#write\\_read (overload 1)} write data to spi and read data from spi at the same time. item description **type** func **param** **data**: direction [in], data to write, Bytes type in C++, bytes type in MaixPy
    **read_len**: direction [in], read length, int type, should > 0.
    **return** read data, Bytes type in C++, bytes type in MaixPy. You need to delete it manually after use in C++. **static** False > C++ defination code: > ```cpp > Bytes *write_read(Bytes *data, int read_len) > ``` #### is\\_busy {#is\\_busy} get busy status of spi item description **type** func **return** busy status, bool type **static** False > C++ defination code: > ```cpp > bool is_busy() > ```"},"/maixcdk/api/maix/peripheral/timer.html":{"title":"maix::peripheral::timer","content":" title: maix::peripheral::timer maix.peripheral.timer module > This is `maix::peripheral::timer` module of [MaixCDK](https://github.com/sipeed/MaixCDK). > All of these elements are in namespace `maix::peripheral::timer`. > > For MaixCDK developer: DO NOT edit this doc file manually, this doc is auto generated! ## Module {#Module} No module ## Enum {#Enum} ## Variable {#Variable} ## Function {#Function} ## Class {#Class} ### TIMER {#TIMER} Peripheral timer class > C++ defination code: > ```cpp > class TIMER > ``` #### \\_\\_init\\_\\_ {#\\_\\_init\\_\\_} TIMER constructor item description **type** func **static** False > C++ defination code: > ```cpp > TIMER() > ```"},"/maixcdk/api/maix/peripheral/i2c.html":{"title":"maix::peripheral::i2c","content":" title: maix::peripheral::i2c maix.peripheral.i2c module > This is `maix::peripheral::i2c` module of [MaixCDK](https://github.com/sipeed/MaixCDK). > All of these elements are in namespace `maix::peripheral::i2c`. > > For MaixCDK developer: DO NOT edit this doc file manually, this doc is auto generated! ## Module {#Module} No module ## Enum {#Enum} ### AddrSize {#AddrSize} Address size enum item describe **values** **SEVEN_BIT**: 7 bit address mode
    **TEN_BIT**: 10 bit address mode
    > C++ defination code: > ```cpp > enum AddrSize > { > SEVEN_BIT 7, // 7 bit address mode > TEN_BIT 10 // 10 bit address mode > } > ``` ### Mode {#Mode} I2C mode enum item describe **values** **MASTER**: master mode
    **SLAVE**: slave mode
    > C++ defination code: > ```cpp > enum Mode > { > MASTER 0x00, // master mode > SLAVE 0x01 // slave mode > } > ``` ## Variable {#Variable} ## Function {#Function} ### list\\_devices {#list\\_devices} Get supported i2c bus devices. item description **return** i2c bus devices list, int type, is the i2c bus id. > C++ defination code: > ```cpp > std::vector list_devices() > ``` ## Class {#Class} ### I2C {#I2C} Peripheral i2c class > C++ defination code: > ```cpp > class I2C > ``` #### \\_\\_init\\_\\_ {#\\_\\_init\\_\\_} I2C Device constructor\\nthis constructor will be export to MaixPy as _maix.example.Example.__init__ item description **type** func **param** **id**: direction [in], i2c bus id, int type, e.g. 0, 1, 2
    **freq**: direction [in], i2c clock, int type, default is 100000(100kbit/s), will auto set fast mode if freq > 100000.
    **mode**: direction [in], mode of i2c, i2c.Mode.SLAVE or i2c.Mode.MASTER.
    **addr_size**: direction [in], address length of i2c, i2c.AddrSize.SEVEN_BIT or i2c.AddrSize.TEN_BIT.
    **throw** err::Exception if open i2c device failed. **static** False > C++ defination code: > ```cpp > I2C(int id, i2c::Mode mode, int freq 100000, i2c::AddrSize addr_size i2c::AddrSize::SEVEN_BIT) > ``` #### scan {#scan} scan all i2c salve address on the bus item description **type** func **param** **addr**: If 1, only scan this addr, or scan from 0x08~0x77, default 1.
    **return** the list of i2c slave address, int list type. **static** False > C++ defination code: > ```cpp > std::vector scan(int addr 1) > ``` #### writeto {#writeto} write data to i2c slave item description **type** func **param** **addr**: direction [in], i2c slave address, int type
    **data**: direction [in], data to write, vector type in C++, int list in MaixPy.
    Note: The range of value should be in [0,255].
    **return** if success, return the length of written data, error occurred will return err::Err。 **static** False > C++ defination code: > ```cpp > int writeto(int addr, const std::vector data) > ``` #### writeto (overload 1) {#writeto (overload 1)} write data to i2c slave item description **type** func **param** **addr**: direction [in], i2c slave address, int type
    **data**: direction [in], data to write, bytes type.
    Note: The range of value should be in [0,255].
    **return** if success, return the length of written data, error occurred will return err::Err. **static** False > C++ defination code: > ```cpp > int writeto(int addr, const Bytes &data) > ``` #### writeto (overload 2) {#writeto (overload 2)} write data to i2c slave item description **type** func **param** **addr**: direction [in], i2c slave address, int type
    **data**: direction [in], data to write, uint8_t type.
    **len**: direction [in], data length to write, int type
    **return** if success, return the length of written data, error occurred will return err::Err. **static** False > C++ defination code: > ```cpp > int writeto(int addr, const uint8_t *data, int len) > ``` #### readfrom {#readfrom} read data from i2c slave item description **type** func **param** **addr**: direction [in], i2c slave address, int type
    **len**: direction [in], data length to read, int type
    **return** the list of data read from i2c slave, bytes type, you should delete it after use in C++.
    If read failed, return nullptr in C++, None in MaixPy. **static** False > C++ defination code: > ```cpp > Bytes* readfrom(int addr, int len) > ``` #### writeto\\_mem {#writeto\\_mem} write data to i2c slave's memory address item description **type** func **param** **addr**: direction [in], i2c slave address, int type
    **mem_addr**: direction [in], memory address want to write, int type.
    **data**: direction [in], data to write, vector type.
    **mem_addr_size**: direction [in], memory address size, default is 8.
    **mem_addr_le**: direction [in], memory address little endian, default is false, that is send high byte first.
    **return** data length written if success, error occurred will return err::Err. **static** False > C++ defination code: > ```cpp > int writeto_mem(int addr, int mem_addr, const std::vector data, int mem_addr_size 8, bool mem_addr_le false) > ``` #### writeto\\_mem (overload 1) {#writeto\\_mem (overload 1)} write data to i2c slave's memory address item description **type** func **param** **addr**: direction [in], i2c slave address, int type
    **mem_addr**: direction [in], memory address want to write, int type.
    **data**: direction [in], data to write, bytes type.
    **mem_addr_size**: direction [in], memory address size, default is 8.
    **mem_addr_le**: direction [in], memory address little endian, default is false, that is send high byte first.
    **return** data length written if success, error occurred will return err::Err. **static** False > C++ defination code: > ```cpp > int writeto_mem(int addr, int mem_addr, const Bytes &data, int mem_addr_size 8, bool mem_addr_le false) > ``` #### writeto\\_mem (overload 2) {#writeto\\_mem (overload 2)} write data to i2c slave's memory address item description **type** func **param** **addr**: direction [in], i2c slave address, int type
    **mem_addr**: direction [in], memory address want to write, int type.
    **data**: direction [in], data to write, uint8_t type.
    **len**: direction [in], data length to write, int type
    **mem_addr_size**: direction [in], memory address size, default is 8.
    **mem_addr_le**: direction [in], memory address little endian, default is false, that is send high byte first.
    **return** data length written if success, error occurred will return err::Err. **static** False > C++ defination code: > ```cpp > int writeto_mem(int addr, int mem_addr, const uint8_t *data, int len, int mem_addr_size 8, bool mem_addr_le false) > ``` #### readfrom\\_mem {#readfrom\\_mem} read data from i2c slave item description **type** func **param** **addr**: direction [in], i2c slave address, int type
    **mem_addr**: direction [in], memory address want to read, int type.
    **len**: direction [in], data length to read, int type
    **mem_addr_size**: direction [in], memory address size, default is 8.
    **mem_addr_le**: direction [in], memory address little endian, default is false, that is send high byte first.
    **return** the list of data read from i2c slave, bytes type, you should delete it after use in C++.
    If read failed, return nullptr in C++, None in MaixPy. **static** False > C++ defination code: > ```cpp > Bytes* readfrom_mem(int addr, int mem_addr, int len, int mem_addr_size 8, bool mem_addr_le false) > ```"},"/maixcdk/api/maix/peripheral/key.html":{"title":"maix::peripheral::key","content":" title: maix::peripheral::key maix.peripheral.key module > This is `maix::peripheral::key` module of [MaixCDK](https://github.com/sipeed/MaixCDK). > All of these elements are in namespace `maix::peripheral::key`. > > For MaixCDK developer: DO NOT edit this doc file manually, this doc is auto generated! ## Module {#Module} No module ## Enum {#Enum} ### Keys {#Keys} Keys enum, id the same as linux input.h(input event codes.h) item describe **values** **KEY_NONE**:
    **KEY_ESC**:
    **KEY_POWER**:
    **KEY_OK**:
    **KEY_OPTION**:
    **KEY_NEXT**:
    **KEY_PREV**:
    > C++ defination code: > ```cpp > enum Keys{ > KEY_NONE 0x000, > KEY_ESC 0x001, > KEY_POWER 0x074, > KEY_OK 0x160, > KEY_OPTION 0x165, > KEY_NEXT 0x197, > KEY_PREV 0x19c, > } > ``` ### State {#State} Key state enum item describe **values** **KEY_RELEASED**:
    **KEY_PRESSED**:
    **KEY_LONG_PRESSED**:
    > C++ defination code: > ```cpp > enum State{ > KEY_RELEASED 0, > KEY_PRESSED 1, > KEY_LONG_PRESSED 2, > } > ``` ## Variable {#Variable} ## Function {#Function} ### add\\_default\\_listener {#add\\_default\\_listener} Add default listener, if you want to exit app when press ok button, you can just call this function.\\nThis function is auto called in MaixPy' startup code, so you don't need to call it in MaixPy.\\nCreate Key object will auto call rm_default_listener() to cancel the default ok button function.\\nWhen ok button pressed, a SIGINT signal will be raise and call app.set_exit_flag(True). > C++ defination code: > ```cpp > void add_default_listener() > ``` ### rm\\_default\\_listener {#rm\\_default\\_listener} Remove default listener, if you want to cancel the default ok button function(exit app), you can just call this function. > C++ defination code: > ```cpp > void rm_default_listener() > ``` ## Class {#Class} ### Key {#Key} Key input class > C++ defination code: > ```cpp > class Key > ``` #### Key {#Key 2} Key Device constructor item description **type** func **param** **callback**: When key triggered and callback is not empty(empty In MaixPy is None, in C++ is nullptr),
    callback will be called with args key(key.Keys) and value(key.State).
    If set to null, you can get key value by read() function.
    This callback called in a standalone thread, so you can block a while in callback, and you should be carefully when operate shared data.
    **open**: auto open device in constructor, if false, you need call open() to open device.
    **device**: Specifies the input device to use. The default initializes all keys,
    for a specific device, provide the path (e.g., \"/dev/input/device\").
    **long_press_time**: The duration (in milliseconds) from pressing the key to triggering the long press event. Default is 2000ms.
    **static** False > C++ defination code: > ```cpp > Key(std::function callback nullptr, bool open true, const string &device \"\", int long_press_time 2000) > ``` #### open {#open} Open(Initialize) key device, if already opened, will close first and then open. item description **type** func **return** err::Err type, err.Err.ERR_NONE means success **static** False > C++ defination code: > ```cpp > err::Err open() > ``` #### close {#close} Close key device item description **type** func **return** err::Err type, err.Err.ERR_NONE means success **static** False > C++ defination code: > ```cpp > err::Err close() > ``` #### is\\_opened {#is\\_opened} Check key device is opened item description **type** func **return** bool type, true means opened, false means closed **static** False > C++ defination code: > ```cpp > bool is_opened() > ``` #### read {#read} Read key input, if callback is set, DO NOT call this function manually. item description **type** func **param** **key**: maix.key.Keys type, indicate which key is triggered, e.g. maix.key.Keys.KEY_OK mean the OK key is triggered.
    If read failed, will not change the value of key.
    **value**: maix.key.State type, indicate the key state, e.g. maix.key.State.KEY_PRESSED mean the key is pressed
    If read failed, will not change the value of value.
    **return** err::Err type, err.Err.ERR_NONE means success, err.Err.ERR_NOT_READY means no key input, other means error. **static** False > C++ defination code: > ```cpp > err::Err read(int &key, int &value) > ``` #### read (overload 1) {#read (overload 1)} Read key input, and return key and value, if callback is set, DO NOT call this function manually. item description **type** func **return** list type, first is key(maix.key.Keys), second is value(maix.key.State), if no key input, return [0, 0] **throw** If read failed, will throw maix.err.Exception. **static** False > C++ defination code: > ```cpp > std::pair read() > ``` #### long\\_press\\_time {#long\\_press\\_time} Sets and retrieves the key's long press time. item description **type** func **param** **press_time**: The long press time to set for the key.
    Setting it to 0 will disable the long press event.
    **return** int type, the current long press time for the key (in milliseconds). **static** False > C++ defination code: > ```cpp > int long_press_time(int press_time 1) > ```"},"/maixcdk/api/maix/peripheral/pinmap.html":{"title":"maix::peripheral::pinmap","content":" title: maix::peripheral::pinmap maix.peripheral.pinmap module > This is `maix::peripheral::pinmap` module of [MaixCDK](https://github.com/sipeed/MaixCDK). > All of these elements are in namespace `maix::peripheral::pinmap`. > > For MaixCDK developer: DO NOT edit this doc file manually, this doc is auto generated! ## Module {#Module} No module ## Enum {#Enum} ## Variable {#Variable} ## Function {#Function} ### get\\_pins {#get\\_pins} Get all pins of devices item description **return** pin name list, string type. > C++ defination code: > ```cpp > std::vector get_pins() > ``` ### get\\_pin\\_functions {#get\\_pin\\_functions} Get all function of a pin item description **param** **pin**: pin name, string type.
    **return** function list, function name is string type. **throw** If pin name error will throwout err.Err.ERR_ARGS error. > C++ defination code: > ```cpp > std::vector get_pin_functions(const std::string &pin) > ``` ### set\\_pin\\_function {#set\\_pin\\_function} Set function of a pin item description **param** **pin**: pin name, string type.
    **func**: which function should this pin use.
    **return** if set ok, will return err.Err.ERR_NONE, else error occurs. > C++ defination code: > ```cpp > err::Err set_pin_function(const std::string &pin, const std::string &func) > ``` ## Class {#Class}"},"/maixcdk/api/maix/ext_dev/bm8563.html":{"title":"maix::ext_dev::bm8563","content":" title: maix::ext_dev::bm8563 maix.ext_dev.bm8563 module > This is `maix::ext_dev::bm8563` module of [MaixCDK](https://github.com/sipeed/MaixCDK). > All of these elements are in namespace `maix::ext_dev::bm8563`. > > For MaixCDK developer: DO NOT edit this doc file manually, this doc is auto generated! ## Module {#Module} No module ## Enum {#Enum} ## Variable {#Variable} ## Function {#Function} ## Class {#Class} ### BM8563 {#BM8563} Peripheral BM8563 class > C++ defination code: > ```cpp > class BM8563 > ``` #### \\_\\_init\\_\\_ {#\\_\\_init\\_\\_} BM8563 constructor item description **type** func **param** **i2c_bus**: i2c bus number.
    **static** False > C++ defination code: > ```cpp > BM8563(int i2c_bus 1) > ``` #### datetime {#datetime} Get or set the date and time of the BM8563. item description **type** func **param** **timetuple**: time tuple, like (year, month, day[, hour[, minute[, second]]])
    **return** time tuple, like (year, month, day[, hour[, minute[, second]]]) **static** False > C++ defination code: > ```cpp > std::vector datetime(std::vector timetuple std::vector()) > ``` #### init {#init} Initialise the BM8563. item description **type** func **param** **timetuple**: time tuple, like (year, month, day[, hour[, minute[, second]]])
    **return** err::Err type, if init success, return err::ERR_NONE **static** False > C++ defination code: > ```cpp > err::Err init(std::vector timetuple) > ``` #### now {#now} Get get the current datetime. item description **type** func **return** time tuple, like (year, month, day[, hour[, minute[, second]]]) **static** False > C++ defination code: > ```cpp > std::vector now() > ``` #### deinit {#deinit} Deinit the BM8563. item description **type** func **return** err::Err err::Err type, if deinit success, return err::ERR_NONE **static** False > C++ defination code: > ```cpp > err::Err deinit() > ``` #### hctosys {#hctosys} Set the system time from the BM8563 item description **type** func **return** err::Err type **static** False > C++ defination code: > ```cpp > err::Err hctosys() > ``` #### systohc {#systohc} Set the BM8563 from the system time item description **type** func **return** err::Err type **static** False > C++ defination code: > ```cpp > err::Err systohc() > ```"},"/maixcdk/api/maix/audio.html":{"title":"maix::audio","content":" title: maix::audio maix.audio module > This is `maix::audio` module of [MaixCDK](https://github.com/sipeed/MaixCDK). > All of these elements are in namespace `maix::audio`. > > For MaixCDK developer: DO NOT edit this doc file manually, this doc is auto generated! ## Module {#Module} No module ## Enum {#Enum} ### Format {#Format} Audio type item describe **values** **FMT_NONE**: format invalid
    **FMT_S8**: unsigned 8 bits
    **FMT_S16_LE**: signed 16 bits, little endian
    **FMT_S32_LE**: signed 32 bits, little endian
    **FMT_S16_BE**: signed 16 bits, big endian
    **FMT_S32_BE**: signed 32 bits, big endian
    **FMT_U8**: unsigned 8 bits
    **FMT_U16_LE**: unsigned 16 bits, little endian
    **FMT_U32_LE**: unsigned 32 bits, little endian
    **FMT_U16_BE**: unsigned 16 bits, big endian
    **FMT_U32_BE**: unsigned 32 bits, big endian
    > C++ defination code: > ```cpp > enum Format > { > FMT_NONE 0, // format invalid > FMT_S8, // unsigned 8 bits > FMT_S16_LE, // signed 16 bits, little endian > FMT_S32_LE, // signed 32 bits, little endian > FMT_S16_BE, // signed 16 bits, big endian > FMT_S32_BE, // signed 32 bits, big endian > FMT_U8, // unsigned 8 bits > FMT_U16_LE, // unsigned 16 bits, little endian > FMT_U32_LE, // unsigned 32 bits, little endian > FMT_U16_BE, // unsigned 16 bits, big endian > FMT_U32_BE, // unsigned 32 bits, big endian > } > ``` ## Variable {#Variable} ## Function {#Function} ## Class {#Class} ### Recorder {#Recorder} Recorder class > C++ defination code: > ```cpp > class Recorder > ``` #### Recorder {#Recorder 2} Construct a new Recorder object. currectly only pcm and wav formats supported. item description **type** func **param** **path**: record path. the path determines the location where you save the file, if path is none, the audio module will not save file.
    **sample_rate**: record sample rate, default is 48000(48KHz), means 48000 samples per second.
    **format**: record sample format, default is audio::Format::FMT_S16_LE, means sampling 16 bits at a time and save as signed 16 bits, little endian. see @audio::Format
    **channel**: record sample channel, default is 1, means 1 channel sampling at the same time
    **static** False > C++ defination code: > ```cpp > Recorder(std::string path std::string(), int sample_rate 48000, audio::Format format audio::Format::FMT_S16_LE, int channel 1) > ``` #### volume {#volume} Set/Get record volume item description **type** func **param** **value**: volume value, If you use this parameter, audio will set the value to volume,
    if you don't, it will return the current volume. range is [0, 100].
    **return** the current volume **static** False > C++ defination code: > ```cpp > int volume(int value 1) > ``` #### mute {#mute} Mute item description **type** func **param** **data**: mute data, If you set this parameter to true, audio will set the value to mute,
    if you don't, it will return the current mute status.
    **return** Returns whether mute is currently enabled. **static** False > C++ defination code: > ```cpp > bool mute(int data 1) > ``` #### record {#record} Record, Read all cached data in buffer and return. If there is no audio data in the buffer, may return empty data. item description **type** func **param** **record_ms**: Block and record audio data lasting `record_ms` milliseconds and save it to a file, the return value does not return audio data. Only valid if the initialisation `path` is set.
    **return** pcm data. datatype @see Bytes. If you pass in record_ms parameter, the return value is an empty Bytes object. **static** False > C++ defination code: > ```cpp > maix::Bytes *record(int record_ms 1) > ``` #### record\\_bytes {#record\\_bytes} Record, Read all cached data in buffer and return. If there is no audio data in the buffer, may return empty data. item description **type** func **note** This interface is experimental and may be removed in the future. **param** **record_size**: Record audio data of size record_size.
    **return** pcm data. datatype @see Bytes. If you pass in record_ms parameter, the return value is an empty Bytes object. **static** False > C++ defination code: > ```cpp > maix::Bytes *record_bytes(int record_size 1) > ``` #### finish {#finish} Finish the record, if you have passed in the path, this api will save the audio data to file. item description **type** func **return** error code, err::ERR_NONE means success, others means failed **static** False > C++ defination code: > ```cpp > err::Err finish() > ``` #### sample\\_rate {#sample\\_rate} Get sample rate item description **type** func **return** returns sample rate **static** False > C++ defination code: > ```cpp > int sample_rate() > ``` #### format {#format 2} Get sample format item description **type** func **return** returns sample format **static** False > C++ defination code: > ```cpp > audio::Format format() > ``` #### channel {#channel} Get sample channel item description **type** func **return** returns sample channel **static** False > C++ defination code: > ```cpp > int channel() > ``` ### Player {#Player} Player class > C++ defination code: > ```cpp > class Player > ``` #### Player {#Player 2} Construct a new Player object item description **type** func **param** **path**: player path. the path determines the location where you save the file, if path is none, the audio module will not save file.
    **sample_rate**: player sample rate, default is 48000(48KHz), means 48000 samples per second.
    **format**: player sample format, default is audio::Format::FMT_S16_LE, means sampling 16 bits at a time and save as signed 16 bits, little endian. see @audio::Format
    **channel**: player sample channel, default is 1, means 1 channel sampling at the same time
    **static** False > C++ defination code: > ```cpp > Player(std::string path std::string(), int sample_rate 48000, audio::Format format audio::Format::FMT_S16_LE, int channel 1) > ``` #### volume {#volume 2} Set/Get player volume item description **type** func **param** **value**: volume value, If you use this parameter, audio will set the value to volume,
    if you don't, it will return the current volume. range is [0, 100].
    **return** the current volume **static** False > C++ defination code: > ```cpp > int volume(int value 1) > ``` #### play {#play} Play item description **type** func **param** **data**: audio data, must be raw data
    **return** error code, err::ERR_NONE means success, others means failed **static** False > C++ defination code: > ```cpp > err::Err play(maix::Bytes *data maix::audio::Player::NoneBytes) > ``` #### sample\\_rate {#sample\\_rate 2} Get sample rate item description **type** func **return** returns sample rate **static** False > C++ defination code: > ```cpp > int sample_rate() > ``` #### format {#format 3} Get sample format item description **type** func **return** returns sample format **static** False > C++ defination code: > ```cpp > audio::Format format() > ``` #### channel {#channel 2} Get sample channel item description **type** func **return** returns sample channel **static** False > C++ defination code: > ```cpp > int channel() > ```"},"/maixcdk/api/maix/err.html":{"title":"maix::err","content":" title: maix::err maix.err module > This is `maix::err` module of [MaixCDK](https://github.com/sipeed/MaixCDK). > All of these elements are in namespace `maix::err`. > > For MaixCDK developer: DO NOT edit this doc file manually, this doc is auto generated! ## Module {#Module} No module ## Enum {#Enum} ### Err {#Err} Maix Error code item describe **values** **ERR_NONE**: No error
    **ERR_ARGS**: Invalid arguments
    **ERR_NO_MEM**: No memory
    **ERR_NOT_IMPL**: Not implemented
    **ERR_NOT_READY**: Not ready
    **ERR_NOT_INIT**: Not initialized
    **ERR_NOT_OPEN**: Not opened
    **ERR_NOT_PERMIT**: Not permitted
    **ERR_REOPEN**: Re open
    **ERR_BUSY**: Busy
    **ERR_READ**: Read error
    **ERR_WRITE**: Write error
    **ERR_TIMEOUT**: Timeout
    **ERR_RUNTIME**: Runtime error
    **ERR_IO**: IO error
    **ERR_NOT_FOUND**: Not found
    **ERR_ALREAY_EXIST**: Already exist
    **ERR_BUFF_FULL**: Buffer full
    **ERR_BUFF_EMPTY**: Buffer empty
    **ERR_CANCEL**: Cancel
    **ERR_OVERFLOW**: Overflow
    **ERR_MAX**:
    > C++ defination code: > ```cpp > enum Err > { > // !!! fixed error code, DO NOT change number already defined, only append new error code > ERR_NONE 0, // No error > ERR_ARGS , // Invalid arguments > ERR_NO_MEM , // No memory > ERR_NOT_IMPL , // Not implemented > ERR_NOT_READY , // Not ready > ERR_NOT_INIT , // Not initialized > ERR_NOT_OPEN , // Not opened > ERR_NOT_PERMIT , // Not permitted > ERR_REOPEN , // Re open > ERR_BUSY , // Busy > ERR_READ , // Read error > ERR_WRITE , // Write error > ERR_TIMEOUT , // Timeout > ERR_RUNTIME , // Runtime error > ERR_IO , // IO error > ERR_NOT_FOUND , // Not found > ERR_ALREAY_EXIST , // Already exist > ERR_BUFF_FULL , // Buffer full > ERR_BUFF_EMPTY , // Buffer empty > ERR_CANCEL , // Cancel > ERR_OVERFLOW , // Overflow > ERR_MAX, > } > ``` ## Variable {#Variable} ## Function {#Function} ### to\\_str {#to\\_str} Error code to string item description **param** **e**: direction [in], error code, err::Err type
    **return** error string > C++ defination code: > ```cpp > std::string to_str(err::Err e) > ``` ### get\\_error {#get\\_error} get last error string item description **return** error string > C++ defination code: > ```cpp > std::string& get_error() > ``` ### set\\_error {#set\\_error} set last error string item description **param** **str**: direction [in], error string
    > C++ defination code: > ```cpp > void set_error(const std::string &str) > ``` ### check\\_raise {#check\\_raise} Check error code, if not ERR_NONE, raise err.Exception item description **param** **e**: direction [in], error code, err::Err type
    **msg**: direction [in], error message
    > C++ defination code: > ```cpp > void check_raise(err::Err e, const std::string &msg \"\") > ``` ### check\\_bool\\_raise {#check\\_bool\\_raise} Check condition, if false, raise err.Exception item description **param** **ok**: direction [in], condition, if true, do nothing, if false, raise err.Exception
    **msg**: direction [in], error message
    > C++ defination code: > ```cpp > void check_bool_raise(bool ok, const std::string &msg \"\") > ``` ### check\\_null\\_raise {#check\\_null\\_raise} Check NULL pointer, if NULL, raise exception item description **param** **ptr**: direction [in], pointer
    **msg**: direction [in], error message
    > C++ defination code: > ```cpp > void check_null_raise(void *ptr, const std::string &msg \"\") > ``` ## Class {#Class} ### Exception {#Exception} Maix Exception > C++ defination code: > ```cpp > class Exception : public std::exception > ```"},"/maixcdk/api/maix/fs.html":{"title":"maix::fs","content":" title: maix::fs maix.fs module > This is `maix::fs` module of [MaixCDK](https://github.com/sipeed/MaixCDK). > All of these elements are in namespace `maix::fs`. > > For MaixCDK developer: DO NOT edit this doc file manually, this doc is auto generated! ## Module {#Module} No module ## Enum {#Enum} ### SEEK {#SEEK} SEEK enums item describe **values** **SEEK_SET**: Seek from beginning of file.
    **SEEK_CUR**: Seek from current position.
    **SEEK_END**: Seek from end of file.
    > C++ defination code: > ```cpp > enum SEEK > { > SEEK_SET 0, // Seek from beginning of file. > SEEK_CUR 1, // Seek from current position. > SEEK_END 2, // Seek from end of file. > } > ``` ## Variable {#Variable} ## Function {#Function} ### isabs {#isabs} Check if the path is absolute path item description **param** **path**: path to check
    **return** true if path is absolute path > C++ defination code: > ```cpp > bool isabs(const std::string &path) > ``` ### isdir {#isdir} Check if the path is a directory, if not exist, throw exception item description **param** **path**: path to check
    **return** true if path is a directory > C++ defination code: > ```cpp > bool isdir(const std::string &path) > ``` ### isfile {#isfile} Check if the path is a file, if not exist, throw exception item description **param** **path**: path to check
    **return** true if path is a file > C++ defination code: > ```cpp > bool isfile(const std::string &path) > ``` ### islink {#islink} Check if the path is a link, if not exist, throw exception item description **param** **path**: path to check
    **return** true if path is a link > C++ defination code: > ```cpp > bool islink(const std::string &path) > ``` ### symlink {#symlink} Create soft link item description **param** **src**: real file path
    **link**: link file path
    **force**: force link, if already have link file, will delet it first then create.
    > C++ defination code: > ```cpp > err::Err symlink(const std::string &src, const std::string &link, bool force false) > ``` ### exists {#exists} Check if the path exists item description **param** **path**: path to check
    **return** true if path exists > C++ defination code: > ```cpp > bool exists(const std::string &path) > ``` ### mkdir {#mkdir} Create a directory recursively item description **param** **path**: path to create
    **exist_ok**: if true, also return true if directory already exists
    **recursive**: if true, create directory recursively, otherwise, only create one directory, default is true
    **return** err::ERR_NONE(err.Err.ERR_NONE in MaixPy) if success, other error code if failed > C++ defination code: > ```cpp > err::Err mkdir(const std::string &path, bool exist_ok true, bool recursive true) > ``` ### rmdir {#rmdir} Remove a directory item description **param** **path**: path to remove
    **recursive**: if true, remove directory recursively, otherwise, only remove empty directory, default is false
    **return** err::ERR_NONE(err.Err.ERR_NONE in MaixPy) if success, other error code if failed > C++ defination code: > ```cpp > err::Err rmdir(const std::string &path, bool recursive false) > ``` ### remove {#remove} Remove a file item description **param** **path**: path to remove
    **return** err::ERR_NONE(err.Err.ERR_NONE in MaixPy) if success, other error code if failed > C++ defination code: > ```cpp > err::Err remove(const std::string &path) > ``` ### rename {#rename} Rename a file or directory item description **param** **src**: source path
    **dst**: destination path, if destination dirs not exist, will auto create
    **return** err::ERR_NONE(err.Err.ERR_NONE in MaixPy) if success, other error code if failed > C++ defination code: > ```cpp > err::Err rename(const std::string &src, const std::string &dst) > ``` ### sync {#sync} Sync files, ensure they're wrriten to disk from RAM > C++ defination code: > ```cpp > void sync() > ``` ### getsize {#getsize} Get file size item description **param** **path**: path to get size
    **return** file size if success, err::Err code if failed > C++ defination code: > ```cpp > int getsize(const std::string &path) > ``` ### dirname {#dirname} Get directory name of path item description **param** **path**: path to get dirname
    **return** dirname if success, empty string if failed > C++ defination code: > ```cpp > std::string dirname(const std::string &path) > ``` ### basename {#basename} Get base name of path item description **param** **path**: path to get basename
    **return** basename if success, empty string if failed > C++ defination code: > ```cpp > std::string basename(const std::string &path) > ``` ### abspath {#abspath} Get absolute path item description **param** **path**: path to get absolute path
    **return** absolute path if success, empty string if failed > C++ defination code: > ```cpp > std::string abspath(const std::string &path) > ``` ### getcwd {#getcwd} Get current working directory item description **return** current working directory absolute path > C++ defination code: > ```cpp > std::string getcwd() > ``` ### realpath {#realpath} Get realpath of path item description **param** **path**: path to get realpath
    **return** realpath if success, empty string if failed > C++ defination code: > ```cpp > std::string realpath(const std::string &path) > ``` ### splitext {#splitext} Get file extension item description **param** **path**: path to get extension
    **return** prefix_path and extension list if success, empty string if failed > C++ defination code: > ```cpp > std::vector splitext(const std::string &path) > ``` ### listdir {#listdir} List files in directory item description **param** **path**: path to list
    **recursive**: if true, list recursively, otherwise, only list current directory, default is false
    **full_path**: if true, return full path, otherwise, only return basename, default is false
    **return** files list if success, nullptr if failed, you should manually delete it in C++. > C++ defination code: > ```cpp > std::vector *listdir(const std::string &path, bool recursive false, bool full_path false) > ``` ### open {#open} Open a file, and return a File object item description **param** **path**: path to open
    **mode**: open mode, support \"r\", \"w\", \"a\", \"r+\", \"w+\", \"a+\", \"rb\", \"wb\", \"ab\", \"rb+\", \"wb+\", \"ab+\"
    **return** File object if success(need to delete object manually in C/C++), nullptr if failed > C++ defination code: > ```cpp > fs::File *open(const std::string &path, const std::string &mode) > ``` ### tempdir {#tempdir} Get temp files directory item description **return** temp files directory > C++ defination code: > ```cpp > std::string tempdir() > ``` ## Class {#Class} ### File {#File} File read write ops > C++ defination code: > ```cpp > class File > ``` #### File {#File 2} Construct File object item description **type** func **static** False > C++ defination code: > ```cpp > File() > ``` #### open {#open 2} Open a file item description **type** func **param** **path**: path to open
    **mode**: open mode, support \"r\", \"w\", \"a\", \"r+\", \"w+\", \"a+\", \"rb\", \"wb\", \"ab\", \"rb+\", \"wb+\", \"ab+\"
    **return** err::ERR_NONE(err.Err.ERR_NONE in MaixPy) if success, other error code if failed **static** False > C++ defination code: > ```cpp > err::Err open(const std::string &path, const std::string &mode) > ``` #### close {#close} Close a file item description **type** func **static** False > C++ defination code: > ```cpp > void close() > ``` #### read {#read} Read data from file item description **type** func **param** **buf**: buffer to store data
    **size**: buffer size(max read size)
    **return** read size if success, err::Err code if failed **static** False > C++ defination code: > ```cpp > int read(void *buf, int size) > ``` #### read (overload 1) {#read (overload 1)} Read data from file API2 item description **type** func **param** **size**: max read size
    **return** bytes data if success(need delete manually in C/C++), nullptr if failed **static** False > C++ defination code: > ```cpp > std::vector *read(int size) > ``` #### readline {#readline} Read line from file item description **type** func **param** **line**: buffer to store line
    **return** read size if success, err::Err code if failed **static** False > C++ defination code: > ```cpp > int readline(std::string &line) > ``` #### readline (overload 1) {#readline (overload 1)} Read line from file item description **type** func **return** line if success, None(nullptr in C++) if failed. You need to delete the returned object manually in C/C++. **static** False > C++ defination code: > ```cpp > std::string *readline() > ``` #### eof {#eof} End of file or not item description **type** func **return** 0 if not reach end of file, else eof. **static** False > C++ defination code: > ```cpp > int eof() > ``` #### write {#write} Write data to file item description **type** func **param** **buf**: buffer to write
    **size**: buffer size
    **return** write size if success, err::Err code if failed **static** False > C++ defination code: > ```cpp > int write(const void *buf, int size) > ``` #### write (overload 1) {#write (overload 1)} Write data to file API2 item description **type** func **param** **buf**: buffer to write
    **return** write size if success, err::Err code if failed **static** False > C++ defination code: > ```cpp > int write(const std::vector &buf) > ``` #### seek {#seek 2} Seek file position item description **type** func **param** **offset**: offset to seek
    **whence**: @see maix.fs.SEEK
    **return** new position if success, err::Err code if failed **static** False > C++ defination code: > ```cpp > int seek(int offset, int whence) > ``` #### tell {#tell} Get file position item description **type** func **return** file position if success, err::Err code if failed **static** False > C++ defination code: > ```cpp > int tell() > ``` #### flush {#flush} Flush file item description **type** func **return** err::ERR_NONE(err.Err.ERR_NONE in MaixPy) if success, other error code if failed **static** False > C++ defination code: > ```cpp > err::Err flush() > ```"},"/maixcdk/api/maix/network.html":{"title":"maix::network","content":" title: maix::network maix.network module > This is `maix::network` module of [MaixCDK](https://github.com/sipeed/MaixCDK). > All of these elements are in namespace `maix::network`. > > For MaixCDK developer: DO NOT edit this doc file manually, this doc is auto generated! ## Module {#Module} module brief [wifi](./network/wifi.html) maix.network.wifi module ## Enum {#Enum} ## Variable {#Variable} ## Function {#Function} ### have\\_network {#have\\_network} Return if device have network(WiFi/Eth etc.) item description **return** True if have network, else False. > C++ defination code: > ```cpp > bool have_network() > ``` ## Class {#Class}"},"/maixcdk/api/maix/thread.html":{"title":"maix::thread","content":" title: maix::thread maix.thread module > This is `maix::thread` module of [MaixCDK](https://github.com/sipeed/MaixCDK). > All of these elements are in namespace `maix::thread`. > > For MaixCDK developer: DO NOT edit this doc file manually, this doc is auto generated! ## Module {#Module} No module ## Enum {#Enum} ## Variable {#Variable} ## Function {#Function} ## Class {#Class} ### Thread {#Thread} thread class > C++ defination code: > ```cpp > class Thread > ``` #### Thread {#Thread 2} create thread item description **type** func **param** **func**: direction [in], thread function, one `args` parameter, void* type, no return value
    **args**: direction [in], thread function parameter
    **static** False > C++ defination code: > ```cpp > Thread(std::function func, void *args nullptr) > ``` #### join {#join} wait thread exit item description **type** func **static** False > C++ defination code: > ```cpp > void join() > ``` #### detach {#detach} detach thread, detach will auto start thread and you can't use join anymore. item description **type** func **static** False > C++ defination code: > ```cpp > void detach() > ``` #### joinable {#joinable} Check if thread is joinable item description **type** func **return** true if thread is joinable **static** False > C++ defination code: > ```cpp > bool joinable() > ```"},"/maixcdk/api/maix/i18n.html":{"title":"maix::i18n","content":" title: maix::i18n maix.i18n module > This is `maix::i18n` module of [MaixCDK](https://github.com/sipeed/MaixCDK). > All of these elements are in namespace `maix::i18n`. > > For MaixCDK developer: DO NOT edit this doc file manually, this doc is auto generated! ## Module {#Module} No module ## Enum {#Enum} ## Variable {#Variable} ### locales {#locales} i18n locales list item description **value** **{
    \"en\",
    \"zh\",
    \"zh tw\",
    \"ja\"}** **readonly** False > C++ defination code: > ```cpp > static std::vector locales { > \"en\", > \"zh\", > \"zh tw\", > \"ja\"} > ``` ### names {#names} i18n language names list item description **value** **{
    \"English\",
    \"简体中文\",
    \"繁體中文\",
    \"日本語\"}** **readonly** True > C++ defination code: > ```cpp > const static std::vector names { > \"English\", > \"简体中文\", > \"繁體中文\", > \"日本語\"} > ``` ## Function {#Function} ### get\\_locale {#get\\_locale} Get system config of locale. item description **return** language locale, e.g. en, zh, zh_CN, zh_TW, etc. > C++ defination code: > ```cpp > string get_locale() > ``` ### get\\_language\\_name {#get\\_language\\_name} Get system config of language name. item description **return** language name, e.g. English, 简体中文, 繁體中文, etc. > C++ defination code: > ```cpp > string get_language_name() > ``` ### load\\_trans\\_yaml {#load\\_trans\\_yaml} Load translations from yaml files. item description **param** **locales_dir**: translation yaml files directory.
    **return** A dict contains all translations, e.g. {\"zh\":{\"hello\": \"你好\"}, \"en\":{\"hello\": \"hello\"}}, you should delete it after use in C++. > C++ defination code: > ```cpp > const std::map> *load_trans_yaml(const std::string &locales_dir) > ``` ### load\\_trans\\_yaml (overload 1) {#load\\_trans\\_yaml (overload 1)} Load translations from yaml files. item description **param** **locales_dir**: translation yaml files directory.
    **dict**: dict to store key values. A dict contains all translations, e.g. {\"zh\":{\"hello\": \"你好\"}, \"en\":{\"hello\": \"hello\"}}, you should delete it after use in C++.
    **return** err::ERR > C++ defination code: > ```cpp > err::Err load_trans_yaml(const std::string &locales_dir, std::map> &dict) > ``` ## Class {#Class} ### Trans {#Trans} Translate helper class. > C++ defination code: > ```cpp > class Trans > ``` #### Trans {#Trans 2} Translate helper class constructor.\\nBy default locale is get by `i18n.get_locale()` function which set by system settings.\\nBut you can also manually set by `set_locale` function temporarily. item description **type** func **param** **locales_dict**: locales dict, e.g. {\"zh\": {\"Confirm\": \"确认\", \"OK\": \"好的\"}, \"en\": {\"Confirm\": \"Confirm\", \"OK\": \"OK\"}}
    **static** False > C++ defination code: > ```cpp > Trans(const std::map> &locales_dict std::map>()) > ``` #### load {#load} Load translation from yaml files generated by `maixtool i18n` command. item description **type** func **param** **locales_dir**: the translation files directory.
    **return** err.Err type, no error will return err.Err.ERR_NONE. **static** False > C++ defination code: > ```cpp > err::Err load(const std::string &locales_dir) > ``` #### update\\_dict {#update\\_dict} Update translation dict. item description **type** func **param** **dict**: the new translation dict.
    **return** err.Err type, no error will return err.Err.ERR_NONE. **static** False > C++ defination code: > ```cpp > err::Err update_dict(const std::map> &dict) > ``` #### tr {#tr} Translate string by key. item description **type** func **param** **key**: string key, e.g. \"Confirm\"
    **locale**: locale name, if not assign, use default locale set by system settings or set_locale function.
    **return** translated string, if find translation, return it, or return key, e.g. \"确认\", \"Confirm\", etc. **static** False > C++ defination code: > ```cpp > string tr(const string &key, const string locale \"\") > ``` #### set\\_locale {#set\\_locale} Set locale temporarily, will not affect system settings. item description **type** func **param** **locale**: locale name, e.g. \"zh\", \"en\", etc. @see maix.i18n.locales
    **static** False > C++ defination code: > ```cpp > void set_locale(const string &locale) > ``` #### get\\_locale {#get\\_locale 2} Get current locale. item description **type** func **return** locale name, e.g. \"zh\", \"en\", etc. @see maix.i18n.locales **static** False > C++ defination code: > ```cpp > string get_locale() > ```"},"/maixcdk/api/maix/image.html":{"title":"maix::image","content":" title: maix::image maix.image module, image related definition and functions > This is `maix::image` module of [MaixCDK](https://github.com/sipeed/MaixCDK). > All of these elements are in namespace `maix::image`. > > For MaixCDK developer: DO NOT edit this doc file manually, this doc is auto generated! ## Module {#Module} No module ## Enum {#Enum} ### Format {#Format} Image formats item describe **attention** for MaixPy firmware developers, update this enum will also need to update the fmt_size and fmt_names too !!! **values** **FMT_RGB888**: RGBRGB...RGB, R at the lowest address
    **FMT_BGR888**: BGRBGR...BGR, B at the lowest address
    **FMT_RGBA8888**: RGBARGBA...RGBA, R at the lowest address
    **FMT_BGRA8888**: BGRABGRA...BGRA, B at the lowest address
    **FMT_RGB565**:
    **FMT_BGR565**:
    **FMT_YUV422SP**: YYY...UVUVUV...UVUV
    **FMT_YUV422P**: YYY...UUU...VVV
    **FMT_YVU420SP**: YYY...VUVUVU...VUVU, NV21
    **FMT_YUV420SP**: YYY...UVUVUV...UVUV, NV12
    **FMT_YVU420P**: YYY...VVV...UUU
    **FMT_YUV420P**: YYY...UUU...VVV
    **FMT_GRAYSCALE**:
    **FMT_BGGR6**: 6 bit Bayer format with a BGGR pattern.
    **FMT_GBRG6**: 6 bit Bayer format with a GBRG pattern.
    **FMT_GRBG6**: 6 bit Bayer format with a GRBG pattern.
    **FMT_RGGB6**: 6 bit Bayer format with a RGGB pattern.
    **FMT_BGGR8**: 8 bit Bayer format with a BGGR pattern.
    **FMT_GBRG8**: 8 bit Bayer format with a GBRG pattern.
    **FMT_GRBG8**: 8 bit Bayer format with a GRBG pattern.
    **FMT_RGGB8**: 8 bit Bayer format with a RGGB pattern.
    **FMT_BGGR10**: 10 bit Bayer format with a BGGR pattern.
    **FMT_GBRG10**: 10 bit Bayer format with a GBRG pattern.
    **FMT_GRBG10**: 10 bit Bayer format with a GRBG pattern.
    **FMT_RGGB10**: 10 bit Bayer format with a RGGB pattern.
    **FMT_BGGR12**: 12 bit Bayer format with a BGGR pattern.
    **FMT_GBRG12**: 12 bit Bayer format with a GBRG pattern.
    **FMT_GRBG12**: 12 bit Bayer format with a GRBG pattern.
    **FMT_RGGB12**: 12 bit Bayer format with a RGGB pattern.
    **FMT_UNCOMPRESSED_MAX**:
    **FMT_COMPRESSED_MIN**:
    **FMT_JPEG**:
    **FMT_PNG**:
    **FMT_COMPRESSED_MAX**:
    **FMT_INVALID**: format not valid
    > C++ defination code: > ```cpp > enum Format > { > FMT_RGB888 0, // RGBRGB...RGB, R at the lowest address > FMT_BGR888, // BGRBGR...BGR, B at the lowest address > FMT_RGBA8888, // RGBARGBA...RGBA, R at the lowest address > FMT_BGRA8888, // BGRABGRA...BGRA, B at the lowest address > FMT_RGB565, > FMT_BGR565, > FMT_YUV422SP, // YYY...UVUVUV...UVUV > FMT_YUV422P, // YYY...UUU...VVV > FMT_YVU420SP, // YYY...VUVUVU...VUVU, NV21 > FMT_YUV420SP, // YYY...UVUVUV...UVUV, NV12 > FMT_YVU420P, // YYY...VVV...UUU > FMT_YUV420P, // YYY...UUU...VVV > FMT_GRAYSCALE, > FMT_BGGR6, // 6 bit Bayer format with a BGGR pattern. > FMT_GBRG6, // 6 bit Bayer format with a GBRG pattern. > FMT_GRBG6, // 6 bit Bayer format with a GRBG pattern. > FMT_RGGB6, // 6 bit Bayer format with a RGGB pattern. > FMT_BGGR8, // 8 bit Bayer format with a BGGR pattern. > FMT_GBRG8, // 8 bit Bayer format with a GBRG pattern. > FMT_GRBG8, // 8 bit Bayer format with a GRBG pattern. > FMT_RGGB8, // 8 bit Bayer format with a RGGB pattern. > FMT_BGGR10, // 10 bit Bayer format with a BGGR pattern. > FMT_GBRG10, // 10 bit Bayer format with a GBRG pattern. > FMT_GRBG10, // 10 bit Bayer format with a GRBG pattern. > FMT_RGGB10, // 10 bit Bayer format with a RGGB pattern. > FMT_BGGR12, // 12 bit Bayer format with a BGGR pattern. > FMT_GBRG12, // 12 bit Bayer format with a GBRG pattern. > FMT_GRBG12, // 12 bit Bayer format with a GRBG pattern. > FMT_RGGB12, // 12 bit Bayer format with a RGGB pattern. > FMT_UNCOMPRESSED_MAX, > > // compressed format below, not compressed should define upper > FMT_COMPRESSED_MIN, > FMT_JPEG, > FMT_PNG, > FMT_COMPRESSED_MAX, > > FMT_INVALID 0xFF // format not valid > } > ``` ### Fit {#Fit} Object fit method item describe **values** **FIT_NONE**: no object fit, keep original
    **FIT_FILL**: width to new width, height to new height, may be stretch
    **FIT_CONTAIN**: keep aspect ratio, fill blank area with black color
    **FIT_COVER**: keep aspect ratio, crop image to fit new size
    **FIT_MAX**:
    > C++ defination code: > ```cpp > enum Fit > { > FIT_NONE 1, // no object fit, keep original > FIT_FILL 0, // width to new width, height to new height, may be stretch > FIT_CONTAIN, // keep aspect ratio, fill blank area with black color > FIT_COVER, // keep aspect ratio, crop image to fit new size > FIT_MAX > } > ``` ### ResizeMethod {#ResizeMethod} Resize method item describe **values** **NEAREST**:
    **BILINEAR**:
    **BICUBIC**:
    **AREA**:
    **LANCZOS**:
    **HAMMING**:
    **RESIZE_METHOD_MAX**:
    > C++ defination code: > ```cpp > enum ResizeMethod > { > NEAREST 0, > BILINEAR, > BICUBIC, > AREA, > LANCZOS, > HAMMING, > RESIZE_METHOD_MAX > } > ``` ### ApriltagFamilies {#ApriltagFamilies} Family of apriltag item describe **values** **TAG16H5**:
    **TAG25H7**:
    **TAG25H9**:
    **TAG36H10**:
    **TAG36H11**:
    **ARTOOLKIT**:
    > C++ defination code: > ```cpp > enum ApriltagFamilies > { > TAG16H5 1, > TAG25H7 2, > TAG25H9 4, > TAG36H10 8, > TAG36H11 16, > ARTOOLKIT 32 > } > ``` ### TemplateMatch {#TemplateMatch} Template match method item describe **values** **SEARCH_EX**: Exhaustive search
    **SEARCH_DS**: Diamond search
    > C++ defination code: > ```cpp > enum TemplateMatch > { > SEARCH_EX, // Exhaustive search > SEARCH_DS, // Diamond search > } > ``` ### CornerDetector {#CornerDetector} CornerDetector class item describe **values** **CORNER_FAST**:
    **CORNER_AGAST**:
    > C++ defination code: > ```cpp > enum CornerDetector > { > CORNER_FAST, > CORNER_AGAST > } > ``` ### EdgeDetector {#EdgeDetector} EdgeDetector class item describe **values** **EDGE_CANNY**:
    **EDGE_SIMPLE**:
    > C++ defination code: > ```cpp > enum EdgeDetector > { > EDGE_CANNY, > EDGE_SIMPLE, > } > ``` ### FlipDir {#FlipDir} FlipDir item describe **values** **X**:
    **Y**:
    **XY**:
    > C++ defination code: > ```cpp > enum class FlipDir > { > X, > Y, > XY > } > ``` ### QRCodeDecoderType {#QRCodeDecoderType} QRCode decode type class item describe **values** **QRCODE_DECODER_TYPE_ZBAR**:
    **QRCODE_DECODER_TYPE_QUIRC**:
    > C++ defination code: > ```cpp > enum class QRCodeDecoderType { > QRCODE_DECODER_TYPE_ZBAR, > QRCODE_DECODER_TYPE_QUIRC > } > ``` ### LineType {#LineType} Line type class item describe **values** **LINE_NORMAL**:
    **LINE_CROSS**:
    **LINE_T**:
    **LINE_L**:
    > C++ defination code: > ```cpp > enum class LineType { > LINE_NORMAL, > LINE_CROSS, > LINE_T, > LINE_L, > } > ``` ## Variable {#Variable} ### fmt\\_size {#fmt\\_size} Image format size in bytes item description **attention** It's a copy of this variable in MaixPy,
    so change it in C++ (e.g. update var in hello function) will not take effect the var inMaixPy.
    So we add const for this var to avoid this mistake. **value** **{
    3,
    3,
    4,
    4,
    2,
    2,
    2,
    2,
    1.5,
    1.5,
    1.5,
    1.5,
    1, // grayscale
    0.75, // 6 bit Bayer format
    0.75, // 6 bit Bayer format
    0.75, // 6 bit Bayer format
    0.75, // 6 bit Bayer format
    1, // 8 bit Bayer format
    1, // 8 bit Bayer format
    1, // 8 bit Bayer format
    1, // 8 bit Bayer format
    1.25, // 10 bit Bayer format
    1.25, // 10 bit Bayer format
    1.25, // 10 bit Bayer format
    1.25, // 10 bit Bayer format
    1.5, // 12 bit Bayer format
    1.5, // 12 bit Bayer format
    1.5, // 12 bit Bayer format
    1.5, // 12 bit Bayer format
    0, // uncompereed_max
    0, // compressed_min
    1, // jpeg
    1, // png
    0, // compressed_max
    0 // invalid
    }** **readonly** True > C++ defination code: > ```cpp > const std::vector fmt_size { > 3, > 3, > 4, > 4, > 2, > 2, > 2, > 2, > 1.5, > 1.5, > 1.5, > 1.5, > 1, // grayscale > 0.75, // 6 bit Bayer format > 0.75, // 6 bit Bayer format > 0.75, // 6 bit Bayer format > 0.75, // 6 bit Bayer format > 1, // 8 bit Bayer format > 1, // 8 bit Bayer format > 1, // 8 bit Bayer format > 1, // 8 bit Bayer format > 1.25, // 10 bit Bayer format > 1.25, // 10 bit Bayer format > 1.25, // 10 bit Bayer format > 1.25, // 10 bit Bayer format > 1.5, // 12 bit Bayer format > 1.5, // 12 bit Bayer format > 1.5, // 12 bit Bayer format > 1.5, // 12 bit Bayer format > 0, // uncompereed_max > 0, // compressed_min > 1, // jpeg > 1, // png > 0, // compressed_max > 0 // invalid > } > ``` ### fmt\\_names {#fmt\\_names} Image format string item description **value** **{
    \"RGB888\",
    \"BGR888\",
    \"RGBA8888\",
    \"BGRA8888\",
    \"RGB565\",
    \"BGR565\",
    \"YUV422SP\",
    \"YUV422P\",
    \"YVU420SP\",
    \"YUV420SP\",
    \"YVU420P\",
    \"YUV420P\",
    \"GRAYSCALE\",
    \"BGGR6\",
    \"GBRG6\",
    \"GRBG6\",
    \"RG6B6\",
    \"BGGR8\",
    \"GBRG8\",
    \"GRBG8\",
    \"RG6B8\",
    \"BGGR10\",
    \"GBRG10\",
    \"GRBG10\",
    \"RG6B10\",
    \"BGGR12\",
    \"GBRG12\",
    \"GRBG12\",
    \"RG6B12\",
    \"UNCOMPRESSED_MAX\",
    \"COMPRESSED_MIN\",
    \"JPEG\",
    \"PNG\",
    \"COMPRESSED_MAX\",
    \"INVALID\"
    }** **readonly** True > C++ defination code: > ```cpp > const std::vector fmt_names { > \"RGB888\", > \"BGR888\", > \"RGBA8888\", > \"BGRA8888\", > \"RGB565\", > \"BGR565\", > \"YUV422SP\", > \"YUV422P\", > \"YVU420SP\", > \"YUV420SP\", > \"YVU420P\", > \"YUV420P\", > \"GRAYSCALE\", > \"BGGR6\", > \"GBRG6\", > \"GRBG6\", > \"RG6B6\", > \"BGGR8\", > \"GBRG8\", > \"GRBG8\", > \"RG6B8\", > \"BGGR10\", > \"GBRG10\", > \"GRBG10\", > \"RG6B10\", > \"BGGR12\", > \"GBRG12\", > \"GRBG12\", > \"RG6B12\", > \"UNCOMPRESSED_MAX\", > \"COMPRESSED_MIN\", > \"JPEG\", > \"PNG\", > \"COMPRESSED_MAX\", > \"INVALID\" > } > ``` ### COLOR\\_WHITE {#COLOR\\_WHITE} Predefined color white item description **value** **image::Color::from_rgb(255, 255, 255)** **readonly** True > C++ defination code: > ```cpp > const image::Color COLOR_WHITE image::Color::from_rgb(255, 255, 255) > ``` ### COLOR\\_BLACK {#COLOR\\_BLACK} Predefined color black item description **value** **image::Color::from_rgb(0, 0, 0)** **readonly** True > C++ defination code: > ```cpp > const image::Color COLOR_BLACK image::Color::from_rgb(0, 0, 0) > ``` ### COLOR\\_RED {#COLOR\\_RED} Predefined color red item description **value** **image::Color::from_rgb(255, 0, 0)** **readonly** True > C++ defination code: > ```cpp > const image::Color COLOR_RED image::Color::from_rgb(255, 0, 0) > ``` ### COLOR\\_GREEN {#COLOR\\_GREEN} Predefined color green item description **value** **image::Color::from_rgb(0, 255, 0)** **readonly** True > C++ defination code: > ```cpp > const image::Color COLOR_GREEN image::Color::from_rgb(0, 255, 0) > ``` ### COLOR\\_BLUE {#COLOR\\_BLUE} Predefined color blue item description **value** **image::Color::from_rgb(0, 0, 255)** **readonly** True > C++ defination code: > ```cpp > const image::Color COLOR_BLUE image::Color::from_rgb(0, 0, 255) > ``` ### COLOR\\_YELLOW {#COLOR\\_YELLOW} Predefined color yellow item description **value** **image::Color::from_rgb(255, 255, 0)** **readonly** True > C++ defination code: > ```cpp > const image::Color COLOR_YELLOW image::Color::from_rgb(255, 255, 0) > ``` ### COLOR\\_PURPLE {#COLOR\\_PURPLE} Predefined color purple item description **value** **image::Color::from_rgb(143, 0, 255)** **readonly** True > C++ defination code: > ```cpp > const image::Color COLOR_PURPLE image::Color::from_rgb(143, 0, 255) > ``` ### COLOR\\_ORANGE {#COLOR\\_ORANGE} Predefined color orange item description **value** **image::Color::from_rgb(255, 127, 0)** **readonly** True > C++ defination code: > ```cpp > const image::Color COLOR_ORANGE image::Color::from_rgb(255, 127, 0) > ``` ### COLOR\\_GRAY {#COLOR\\_GRAY} Predefined color gray item description **value** **image::Color::from_rgb(127, 127, 127)** **readonly** True > C++ defination code: > ```cpp > const image::Color COLOR_GRAY image::Color::from_rgb(127, 127, 127) > ``` ## Function {#Function} ### resize\\_map\\_pos {#resize\\_map\\_pos} map point position or rectangle position from one image size to another image size(resize) item description **param** **int**: h_out target image height
    **fit**: resize method, see maix.image.Fit
    **x**: original point x, or rectagle left top point's x
    **y**: original point y, or rectagle left top point's y
    **w**: original rectagle width, can be 1 if not use this arg, default 1.
    **h**: original rectagle height, can be 1 if not use this arg, default 1.
    **return** list type, [x, y] if map point, [x, y, w, h] if resize rectangle. > C++ defination code: > ```cpp > std::vector resize_map_pos(int w_in, int h_in, int w_out, int h_out, image::Fit fit, int x, int y, int w 1, int h 1) > ``` ### resize\\_map\\_pos (overload 1) {#resize\\_map\\_pos (overload 1)} map point position or rectangle position from this image size to another image size(resize) item description **param** **int**: h_out target image height
    **fit**: resize method, see maix.image.Fit
    **x**: original point x, or rectagle left top point's x
    **y**: original point y, or rectagle left top point's y
    **w**: original rectagle width, can be 1 if not use this arg, default 1.
    **h**: original rectagle height, can be 1 if not use this arg, default 1.
    **return** list type, [x, y] if map point, [x, y, w, h] if resize rectangle. > C++ defination code: > ```cpp > std::vector resize_map_pos(int w_out, int h_out, image::Fit fit, int x, int y, int w 1, int h 1) > ``` ### resize\\_map\\_pos\\_reverse {#resize\\_map\\_pos\\_reverse} reverse resize_map_pos method, when we call image.resize method resiz image 'a' to image 'b', we want to known the original position on 'a' whith a knew point on 'b' item description **param** **int**: h_out image height after resized
    **fit**: resize method, see maix.image.Fit
    **x**: point on resized image x, or rectagle left top point's x
    **y**: original point y, or rectagle left top point's y
    **w**: original rectagle width, can be 1 if not use this arg, default 1.
    **h**: original rectagle height, can be 1 if not use this arg, default 1.
    **return** list type, [x, y] if map point, [x, y, w, h] if resize rectangle. > C++ defination code: > ```cpp > std::vector resize_map_pos_reverse(int w_in, int h_in, int w_out, int h_out, image::Fit fit, int x, int y, int w 1, int h 1) > ``` ### load {#load} Load image from file, and convert to Image object item description **param** **path**: image file path
    **format**: read as this format, if not match, will convert to this format, by default is RGB888
    **return** Image object, if load failed, will return None(nullptr in C++), so you should care about it. > C++ defination code: > ```cpp > image::Image *load(const char *path, image::Format format image::Format::FMT_RGB888) > ``` ### from\\_bytes {#from\\_bytes} Create image from bytes item description **param** **width**: image width
    **height**: image height
    **format**: image format
    **data**: image data, if data is None, will malloc memory for image data
    If the image is in jpeg format, data must be filled in.
    **copy**: if true and data is not None, will copy data to new buffer, else will use data directly. default is true to avoid memory leak.
    Use it carefully!!!
    **return** Image object > C++ defination code: > ```cpp > image::Image *from_bytes(int width, int height, image::Format format, Bytes *data, bool copy true) > ``` ### load\\_font {#load\\_font} Load font from file item description **param** **name**: font name, used to identify font
    **path**: font file path, support ttf, ttc, otf
    **size**: font size, font height, by default is 16
    **return** error code, err::ERR_NONE is ok, other is error > C++ defination code: > ```cpp > err::Err load_font(const std::string &name, const char *path, int size 16) > ``` ### set\\_default\\_font {#set\\_default\\_font} Set default font, if not call this method, default is hershey_plain item description **param** **name**: font name, supported names can be get by fonts()
    **return** error code, err::ERR_NONE is ok, other is error > C++ defination code: > ```cpp > err::Err set_default_font(const std::string &name) > ``` ### fonts {#fonts} Get all loaded fonts item description **return** all loaded fonts, string list type > C++ defination code: > ```cpp > std::vector *fonts() > ``` ### string\\_size {#string\\_size} Get text rendered width and height item description **param** **string**: text content
    **scale**: font scale, by default(value is 1)
    **thickness**: text thickness(line width), by default(value is 1)
    **return** text rendered width and height, [width, height] > C++ defination code: > ```cpp > image::Size string_size(std::string string, float scale 1, int thickness 1, const std::string &font \"\") > ``` ## Class {#Class} ### QRCodeDetector {#QRCodeDetector} QRCodeDetector class > C++ defination code: > ```cpp > class QRCodeDetector > ``` #### \\_\\_init\\_\\_ {#\\_\\_init\\_\\_} QRCodeDetector constructor.\\nUse npu to accelerate the speed of QR code scanning, note that this object will occupy npu resources item description **type** func **static** False > C++ defination code: > ```cpp > QRCodeDetector() > ``` #### detect {#detect} Finds all qrcodes in the image. item description **type** func **param** **img**: The image to find qrcodes.
    **roi**: The region of interest, input in the format of (x, y, w, h), x and y are the coordinates of the upper left corner, w and h are the width and height of roi.
    default is None, means whole image.
    **decoder_type**: Select the QR code decoding method. Choosing QRCODE_DECODER_TYPE_QUIRC allows for retrieving QR code version, ECC level, mask, data type, and other details,
    though it may decode slower at lower resolutions. Opting for QRCODE_DECODER_TYPE_ZBAR enables faster decoding at lower resolutions but may slow down at higher resolutions,
    providing only the QR code content and position information. default is QRCODE_DECODER_TYPE_ZBAR.
    **return** Returns the qrcodes of the image **static** False > C++ defination code: > ```cpp > std::vector detect(image::Image *img, std::vector roi std::vector(), image::QRCodeDecoderType decoder_type image::QRCodeDecoderType::QRCODE_DECODER_TYPE_ZBAR) > ``` ### Size {#Size} Image size type > C++ defination code: > ```cpp > class Size > ``` #### \\_\\_init\\_\\_ {#\\_\\_init\\_\\_ 2} Construct a new Size object item description **type** func **param** **width**: image width
    **height**: image height
    **static** False > C++ defination code: > ```cpp > Size(int width 0, int height 0) > ``` #### width {#width} width of size item description **type** func **param** **width**: set new width, if not set, only return current width
    **static** False > C++ defination code: > ```cpp > int width(int width 1) > ``` #### height {#height} height of size item description **type** func **param** **height**: set new height, if not set, only return current height
    **static** False > C++ defination code: > ```cpp > int height(int height 1) > ``` #### [] {#[]} Subscript operator item description **type** func **param** **index**: 0 for width, 1 for height
    **return** int& width or height **static** False > C++ defination code: > ```cpp > int &operator[](int index) > ``` #### \\_\\_str\\_\\_ {#\\_\\_str\\_\\_} to string item description **type** func **static** False > C++ defination code: > ```cpp > std::string __str__() > ``` ### Line {#Line} Line class > C++ defination code: > ```cpp > class Line > ``` #### \\_\\_init\\_\\_ {#\\_\\_init\\_\\_ 3} Line constructor item description **type** func **param** **x1**: coordinate x1 of the straight line
    **y1**: coordinate y1 of the straight line
    **x2**: coordinate x2 of the straight line
    **y2**: coordinate y2 of the straight line
    **magnitude**: magnitude of the straight line after Hough transformation
    **theta**: angle of the straight line after Hough transformation
    **rho**: p value of the straight line after Hough transformation
    **static** False > C++ defination code: > ```cpp > Line(int x1, int y1, int x2, int y2, int magnitude 0, int theta 0, int rho 0) > ``` #### \\_\\_getitem\\_\\_ {#\\_\\_getitem\\_\\_} Subscript operator item description **type** func **param** **index**: [0] get x1 of line
    [1] get y1 of line
    [2] get x2 of line
    [3] get y2 of line
    [4] get length of line
    [5] get magnitude of the straight line after Hough transformation
    [6] get angle of the straight line after Hough transformation (0 179 degrees)
    [7] get p value of the straight line after Hough transformation
    **return** int& **static** False > C++ defination code: > ```cpp > int &__getitem__(int index) > ``` #### x1 {#x1} get x1 of line item description **type** func **return** return x1 of the line, type is int **static** False > C++ defination code: > ```cpp > int x1() > ``` #### y1 {#y1} get y1 of line item description **type** func **return** return y1 of the line, type is int **static** False > C++ defination code: > ```cpp > int y1() > ``` #### x2 {#x2} get x2 of line item description **type** func **return** return x2 of the line, type is int **static** False > C++ defination code: > ```cpp > int x2() > ``` #### y2 {#y2} get y2 of line item description **type** func **return** return y2 of the line, type is int **static** False > C++ defination code: > ```cpp > int y2() > ``` #### length {#length} get length of line item description **type** func **return** return length of the line, type is int **static** False > C++ defination code: > ```cpp > int length() > ``` #### magnitude {#magnitude} get magnitude of the straight line after Hough transformation item description **type** func **return** return magnitude, type is int **static** False > C++ defination code: > ```cpp > int magnitude() > ``` #### theta {#theta} get angle of the straight line after Hough transformation (0 179 degrees) item description **type** func **return** return angle, type is int **static** False > C++ defination code: > ```cpp > int theta() > ``` #### rho {#rho} get p value of the straight line after Hough transformation item description **type** func **return** return p value, type is int **static** False > C++ defination code: > ```cpp > int rho() > ``` ### Rect {#Rect} Rect class > C++ defination code: > ```cpp > class Rect > ``` #### \\_\\_init\\_\\_ {#\\_\\_init\\_\\_ 4} Rect constructor item description **type** func **param** **corners**: corners of rect
    **x**: coordinate x of the straight line
    **y**: coordinate y of the straight line
    **w**: coordinate w of the straight line
    **h**: coordinate h of the straight line
    **magnitude**: magnitude of the straight line after Hough transformation
    **static** False > C++ defination code: > ```cpp > Rect(std::vector> &corners, int x, int y, int w, int h, int magnitude 0) > ``` #### \\_\\_getitem\\_\\_ {#\\_\\_getitem\\_\\_ 2} Subscript operator item description **type** func **param** **index**: [0] get x of rect
    [1] get y of rect
    [2] get w of rect
    [3] get h of rect
    [4] get magnitude of the straight line after Hough transformation
    **return** int& **static** False > C++ defination code: > ```cpp > int &__getitem__(int index) > ``` #### corners {#corners} get corners of rect item description **type** func **return** return the coordinate of the rect. **static** False > C++ defination code: > ```cpp > std::vector> corners() > ``` #### rect {#rect 2} get rectangle of rect item description **type** func **return** return the rectangle of the rect. format is {x, y, w, h}, type is std::vector **static** False > C++ defination code: > ```cpp > std::vector rect() > ``` #### x {#x} get x of rect item description **type** func **return** return x of the rect, type is int **static** False > C++ defination code: > ```cpp > int x() > ``` #### y {#y} get y of rect item description **type** func **return** return y of the rect, type is int **static** False > C++ defination code: > ```cpp > int y() > ``` #### w {#w} get w of rect item description **type** func **return** return w of the rect, type is int **static** False > C++ defination code: > ```cpp > int w() > ``` #### h {#h} get h of rect item description **type** func **return** return h of the rect, type is int **static** False > C++ defination code: > ```cpp > int h() > ``` #### magnitude {#magnitude 2} get magnitude of the straight line after Hough transformation item description **type** func **return** return magnitude, type is int **static** False > C++ defination code: > ```cpp > int magnitude() > ``` ### Circle {#Circle} circle class > C++ defination code: > ```cpp > class Circle > ``` #### \\_\\_init\\_\\_ {#\\_\\_init\\_\\_ 5} Circle constructor item description **type** func **param** **x**: coordinate x of the circle
    **y**: coordinate y of the circle
    **r**: coordinate r of the circle
    **magnitude**: coordinate y2 of the straight line
    **static** False > C++ defination code: > ```cpp > Circle(int x, int y, int r, int magnitude) > ``` #### \\_\\_getitem\\_\\_ {#\\_\\_getitem\\_\\_ 3} Subscript operator item description **type** func **param** **index**: [0] get x of circle
    [1] get y of circle
    [2] get r of circle
    [3] get magnitude of the circle after Hough transformation
    **return** int& **static** False > C++ defination code: > ```cpp > int &__getitem__(int index) > ``` #### x {#x 2} get x of circle item description **type** func **return** return x of the circle, type is int **static** False > C++ defination code: > ```cpp > int x() > ``` #### y {#y 2} get y of circle item description **type** func **return** return y of the circle, type is int **static** False > C++ defination code: > ```cpp > int y() > ``` #### r {#r} get r of circle item description **type** func **return** return r of the circle, type is int **static** False > C++ defination code: > ```cpp > int r() > ``` #### magnitude {#magnitude 3} get magnitude of the circle after Hough transformation item description **type** func **return** return magnitude, type is int **static** False > C++ defination code: > ```cpp > int magnitude() > ``` ### Blob {#Blob} Blob class > C++ defination code: > ```cpp > class Blob > ``` #### \\_\\_init\\_\\_ {#\\_\\_init\\_\\_ 6} Blob constructor item description **type** func **param** **rect**: blob rect, type is std::vector
    **corners**: blob corners, type is std::vector>
    **mini_corners**: blob mini_corners, type is std::vector>
    **cx**: blob center x, type is float
    **cy**: blob center y, type is float
    **pixels**: blob pixels, type is int
    **rotation**: blob rotation, type is float
    **code**: blob code, type is int
    **count**: blob count, type is int
    **perimeter**: blob perimeter, type is int
    **roundness**: blob roundness, type is float
    **x_hist_bins**: blob x_hist_bins, type is std::vector
    **y_hist_bins**: blob y_hist_bins, type is std::vector
    **static** False > C++ defination code: > ```cpp > Blob(std::vector &rect, std::vector> &corners, std::vector> &mini_corners,float cx, float cy, int pixels, float rotation, int code, int count, int perimeter, float roundness, std::vector &x_hist_bins, std::vector &y_hist_bins) > ``` #### \\_\\_getitem\\_\\_ {#\\_\\_getitem\\_\\_ 4} Subscript operator item description **type** func **param** **index**: [0] Returns the blob’s bounding box x coordinate
    [1] Returns the blob’s bounding box y coordinate
    [2] Returns the blob’s bounding box w coordinate
    [3] Returns the blob’s bounding box h coordinate
    [4] Returns the number of pixels that are part of this blob
    [5] Returns the centroid x position of the blob
    [6] Returns the centroid y position of the blob
    **return** int& width or height **static** False > C++ defination code: > ```cpp > int &__getitem__(int index) > ``` #### corners {#corners 2} get blob corners item description **type** func **return** Returns a list of 4 (x,y) tuples of the 4 corners of the object.
    (x0, y0)___________(x1, y1)



    ___________
    (x3, y3) (x2, y2)
    note: the order of corners may change **static** False > C++ defination code: > ```cpp > std::vector> corners() > ``` #### mini\\_corners {#mini\\_corners} get blob mini corners item description **type** func **return** Returns a list of 4 (x,y) tuples of the 4 corners than bound the min area rectangle of the blob.
    (x0, y0)___________(x1, y1)



    ___________
    (x3, y3) (x2, y2)
    note: the order of corners may change **static** False > C++ defination code: > ```cpp > std::vector> mini_corners() > ``` #### rect {#rect 3} get blob rect item description **type** func **return** Returns the center coordinates and width and height of the rectangle. format is (x, y, w, h)
    w
    (x, y) ___________

    h

    ___________ **static** False > C++ defination code: > ```cpp > std::vector rect() > ``` #### x {#x 3} get blob x of the upper left coordinate item description **type** func **return** Returns the x coordinate of the upper left corner of the rectangle. **static** False > C++ defination code: > ```cpp > int x() > ``` #### y {#y 3} get blob y of the upper left coordinate item description **type** func **return** Returns the y coordinate of the upper left corner of the rectangle. **static** False > C++ defination code: > ```cpp > int y() > ``` #### w {#w 2} get blob width item description **type** func **return** Returns the blob’s bounding box w coordinate **static** False > C++ defination code: > ```cpp > int w() > ``` #### h {#h 2} get blob height item description **type** func **return** Returns the blob’s bounding box h coordinate **static** False > C++ defination code: > ```cpp > int h() > ``` #### pixels {#pixels} get blob pixels item description **type** func **return** Returns the number of pixels that are part of this blob. **static** False > C++ defination code: > ```cpp > int pixels() > ``` #### cx {#cx} get blob center x item description **type** func **return** Returns the centroid x position of the blob **static** False > C++ defination code: > ```cpp > int cx() > ``` #### cy {#cy} get blob center y item description **type** func **return** Returns the centroid y position of the blob **static** False > C++ defination code: > ```cpp > int cy() > ``` #### cxf {#cxf} get blob center x item description **type** func **return** Returns the centroid x position of the blob **static** False > C++ defination code: > ```cpp > float cxf() > ``` #### cyf {#cyf} get blob center y item description **type** func **return** Returns the centroid y position of the blob **static** False > C++ defination code: > ```cpp > float cyf() > ``` #### rotation {#rotation} get blob rotation item description **type** func **return** Returns the rotation of the blob in radians (float). If the blob is like a pencil or pen this value will be unique for 0 180 degrees. **static** False > C++ defination code: > ```cpp > float rotation() > ``` #### rotation\\_rad {#rotation\\_rad} get blob rotation_rad item description **type** func **return** Returns the rotation of the blob in radians **static** False > C++ defination code: > ```cpp > float rotation_rad() > ``` #### rotation\\_deg {#rotation\\_deg} get blob rotation_deg item description **type** func **return** Returns the rotation of the blob in degrees. **static** False > C++ defination code: > ```cpp > int rotation_deg() > ``` #### code {#code} get blob code item description **type** func **return** Returns a 32 bit binary number with a bit set in it for each color threshold that’s part of this blob **static** False > C++ defination code: > ```cpp > int code() > ``` #### count {#count} get blob count item description **type** func **return** Returns the number of blobs merged into this blob. **static** False > C++ defination code: > ```cpp > int count() > ``` #### perimeter {#perimeter} get blob merge_cnt item description **type** func **return** Returns the number of pixels on this blob’s perimeter. **static** False > C++ defination code: > ```cpp > int perimeter() > ``` #### roundness {#roundness} get blob roundness item description **type** func **return** Returns a value between 0 and 1 representing how round the object is **static** False > C++ defination code: > ```cpp > float roundness() > ``` #### elongation {#elongation} get blob elongation item description **type** func **returnReturns** a value between 0 and 1 representing how long (not round) the object is **static** False > C++ defination code: > ```cpp > float elongation() > ``` #### area {#area} get blob area item description **type** func **return** Returns the area of the bounding box around the blob **static** False > C++ defination code: > ```cpp > int area() > ``` #### density {#density} get blob density item description **type** func **return** Returns the density ratio of the blob **static** False > C++ defination code: > ```cpp > float density() > ``` #### extent {#extent} Alias for blob.density() item description **type** func **return** Returns the density ratio of the blob **static** False > C++ defination code: > ```cpp > float extent() > ``` #### compactness {#compactness} get blob compactness item description **type** func **return** Returns the compactness ratio of the blob **static** False > C++ defination code: > ```cpp > float compactness() > ``` #### solidity {#solidity} get blob solidity item description **type** func **return** Returns the solidity ratio of the blob **static** False > C++ defination code: > ```cpp > float solidity() > ``` #### convexity {#convexity} get blob convexity item description **type** func **return** Returns a value between 0 and 1 representing how convex the object is **static** False > C++ defination code: > ```cpp > float convexity() > ``` #### x\\_hist\\_bins {#x\\_hist\\_bins} get blob x_hist_bins item description **type** func **return** Returns the x_hist_bins of the blob **static** False > C++ defination code: > ```cpp > std::vector x_hist_bins() > ``` #### y\\_hist\\_bins {#y\\_hist\\_bins} get blob y_hist_bins item description **type** func **return** Returns the y_hist_bins of the blob **static** False > C++ defination code: > ```cpp > std::vector y_hist_bins() > ``` #### major\\_axis\\_line {#major\\_axis\\_line} get blob major_axis_line item description **type** func **return** Returns a line tuple (x1, y1, x2, y2) of the minor axis of the blob. **static** False > C++ defination code: > ```cpp > std::vector major_axis_line() > ``` #### minor\\_axis\\_line {#minor\\_axis\\_line} get blob minor_axis_line item description **type** func **return** Returns a line tuple (x1, y1, x2, y2) of the minor axis of the blob. **static** False > C++ defination code: > ```cpp > std::vector minor_axis_line() > ``` #### enclosing\\_circle {#enclosing\\_circle} get blob enclosing_circle item description **type** func **return** Returns a circle tuple (x, y, r) of the circle that encloses the min area rectangle of a blob. **static** False > C++ defination code: > ```cpp > std::vector enclosing_circle() > ``` #### enclosed\\_ellipse {#enclosed\\_ellipse} get blob enclosed_ellipse item description **type** func **return** Returns an ellipse tuple (x, y, rx, ry, rotation) of the ellipse that fits inside of the min area rectangle of a blob. **static** False > C++ defination code: > ```cpp > std::vector enclosed_ellipse() > ``` ### QRCode {#QRCode} QRCode class > C++ defination code: > ```cpp > class QRCode > ``` #### \\_\\_init\\_\\_ {#\\_\\_init\\_\\_ 7} QRCode constructor item description **type** func **param** **rect**: rect of corners, type is std::vector
    **corners**: corners of QRCode
    **payload**: payload of the QRCode
    **version**: version of the QRCode
    **ecc_level**: ecc_level of the QRCode
    **mask**: mask of the QRCode
    **data_type**: data_type of the QRCode
    **eci**: eci of the QRCode
    **static** False > C++ defination code: > ```cpp > QRCode(std::vector &rect, std::vector> &corners, std::string &payload, int version, int ecc_level, int mask, int data_type, int eci) > ``` #### \\_\\_getitem\\_\\_ {#\\_\\_getitem\\_\\_ 5} Subscript operator item description **type** func **param** **index**: [0] Returns the qrcode’s bounding box x coordinate
    [1] Returns the qrcode’s bounding box y coordinate
    [2] Returns the qrcode’s bounding box w coordinate
    [3] Returns the qrcode’s bounding box h coordinate
    [4] Not support this index, try to use payload() method
    [5] Returns the version of qrcode
    [6] Returns the error correction level of qrcode
    [7] Returns the mask of qrcode
    [8] Returns the datatype of qrcode
    [9] Returns the eci of qrcode
    **return** int& **static** False > C++ defination code: > ```cpp > int &__getitem__(int index) > ``` #### corners {#corners 3} get coordinate of QRCode item description **type** func **return** return the coordinate of the QRCode. **static** False > C++ defination code: > ```cpp > std::vector> corners() > ``` #### rect {#rect 4} get rectangle of QRCode item description **type** func **return** return the rectangle of the QRCode. format is {x, y, w, h}, type is std::vector **static** False > C++ defination code: > ```cpp > std::vector rect() > ``` #### x {#x 4} get x of QRCode item description **type** func **return** return x of the QRCode, type is int **static** False > C++ defination code: > ```cpp > int x() > ``` #### y {#y 4} get y of QRCode item description **type** func **return** return y of the QRCode, type is int **static** False > C++ defination code: > ```cpp > int y() > ``` #### w {#w 3} get w of QRCode item description **type** func **return** return w of the QRCode, type is int **static** False > C++ defination code: > ```cpp > int w() > ``` #### h {#h 3} get h of QRCode item description **type** func **return** return h of the QRCode, type is int **static** False > C++ defination code: > ```cpp > int h() > ``` #### payload {#payload} get QRCode payload item description **type** func **return** return area of the QRCode **static** False > C++ defination code: > ```cpp > std::string payload() > ``` #### version {#version} get QRCode version item description **type** func **return** return version of the QRCode **static** False > C++ defination code: > ```cpp > int version() > ``` #### ecc\\_level {#ecc\\_level} get QRCode error correction level item description **type** func **return** return error correction level of the QRCode **static** False > C++ defination code: > ```cpp > int ecc_level() > ``` #### mask {#mask} get QRCode mask item description **type** func **return** return mask of the QRCode **static** False > C++ defination code: > ```cpp > int mask() > ``` #### data\\_type {#data\\_type} get QRCode dataType item description **type** func **return** return mask of the QRCode **static** False > C++ defination code: > ```cpp > int data_type() > ``` #### eci {#eci} get QRCode eci item description **type** func **return** return data of the QRCode **static** False > C++ defination code: > ```cpp > int eci() > ``` #### is\\_numeric {#is\\_numeric} check QRCode is numeric item description **type** func **return** return true if the result type of the QRCode is numeric **static** False > C++ defination code: > ```cpp > bool is_numeric() > ``` #### is\\_alphanumeric {#is\\_alphanumeric} check QRCode is alphanumeric item description **type** func **return** return true if the result type of the QRCode is alphanumeric **static** False > C++ defination code: > ```cpp > bool is_alphanumeric() > ``` #### is\\_binary {#is\\_binary} check QRCode is binary item description **type** func **return** return true if the result type of the QRCode is binary **static** False > C++ defination code: > ```cpp > bool is_binary() > ``` #### is\\_kanji {#is\\_kanji} check QRCode is kanji item description **type** func **return** return true if the result type of the QRCode is kanji **static** False > C++ defination code: > ```cpp > bool is_kanji() > ``` ### AprilTag {#AprilTag} AprilTag class > C++ defination code: > ```cpp > class AprilTag > ``` #### \\_\\_init\\_\\_ {#\\_\\_init\\_\\_ 8} AprilTag constructor item description **type** func **param** **rect**: Inlucdes the top left corner and the width and height of the rectangle. format is {x, y, w, h}, type is std::vector
    **corners**: Includes the four corners of the rectangle. format is {{x0, y0}, {x1, y1}, {x2, y2}, {x3, y3}}, type is std::vector>
    **id**: The id of the AprilTag
    **famliy**: The family of the AprilTag
    **centroid_x**: The x coordinate of the center of the AprilTag
    **centroid_y**: The y coordinate of the center of the AprilTag
    **rotation**: The rotation of the AprilTag
    **decision_margin**: The decision_margin of the AprilTag
    **hamming**: The hamming of the AprilTag
    **goodness**: The goodness of the AprilTag
    **x_translation**: The x_translation of the AprilTag
    **y_translation**: The y_translation of the AprilTag
    **z_translation**: The z_translation of the AprilTag
    **x_rotation**: The x_rotation of the AprilTag
    **y_rotation**: The y_rotation of the AprilTag
    **z_rotation**: The z_rotation of the AprilTag
    **static** False > C++ defination code: > ```cpp > AprilTag(std::vector &rect, std::vector> &corners, int id, int famliy, float centroid_x, float centroid_y, float rotation, float decision_margin, int hamming, float goodness, float x_translation, float y_translation, float z_translation, float x_rotation, float y_rotation, float z_rotation) > ``` #### \\_\\_getitem\\_\\_ {#\\_\\_getitem\\_\\_ 6} Subscript operator item description **type** func **param** **index**: [0] Returns the apriltag’s bounding box x coordinate
    [1] Returns the apriltag’s bounding box y coordinate
    [2] Returns the apriltag’s bounding box w coordinate
    [3] Returns the apriltag’s bounding box h coordinate
    [4] Returns the apriltag’s id
    [5] Returns the apriltag’s family
    [6] Not support
    [7] Not support
    [8] Not support
    [9] Not support
    [10] Returns the apriltag’s hamming
    [11] Not support
    [12] Not support
    [13] Not support
    [14] Not support
    [15] Not support
    [16] Not support
    [17] Not support
    **return** int& **static** False > C++ defination code: > ```cpp > int &__getitem__(int index) > ``` #### corners {#corners 4} get coordinate of AprilTag item description **type** func **return** return the coordinate of the AprilTag. **static** False > C++ defination code: > ```cpp > std::vector> corners() > ``` #### rect {#rect 5} get rectangle of AprilTag item description **type** func **return** return the rectangle of the AprilTag. format is {x, y, w, h}, type is std::vector **static** False > C++ defination code: > ```cpp > std::vector rect() > ``` #### x {#x 5} get x of AprilTag item description **type** func **return** return x of the AprilTag, type is int **static** False > C++ defination code: > ```cpp > int x() > ``` #### y {#y 5} get y of AprilTag item description **type** func **return** return y of the AprilTag, type is int **static** False > C++ defination code: > ```cpp > int y() > ``` #### w {#w 4} get w of AprilTag item description **type** func **return** return w of the AprilTag, type is int **static** False > C++ defination code: > ```cpp > int w() > ``` #### h {#h 4} get h of AprilTag item description **type** func **return** return h of the AprilTag, type is int **static** False > C++ defination code: > ```cpp > int h() > ``` #### id {#id} get id of AprilTag item description **type** func **return** return id of the AprilTag, type is int **static** False > C++ defination code: > ```cpp > int id() > ``` #### family {#family} get family of AprilTag item description **type** func **return** return family of the AprilTag, type is int **static** False > C++ defination code: > ```cpp > int family() > ``` #### cx {#cx 2} get cx of AprilTag item description **type** func **return** return cx of the AprilTag, type is int **static** False > C++ defination code: > ```cpp > int cx() > ``` #### cxf {#cxf 2} get cxf of AprilTag item description **type** func **return** return cxf of the AprilTag, type is float **static** False > C++ defination code: > ```cpp > float cxf() > ``` #### cy {#cy 2} get cy of AprilTag item description **type** func **return** return cy of the AprilTag, type is int **static** False > C++ defination code: > ```cpp > int cy() > ``` #### cyf {#cyf 2} get cyf of AprilTag item description **type** func **return** return cyf of the AprilTag, type is float **static** False > C++ defination code: > ```cpp > float cyf() > ``` #### rotation {#rotation 2} get rotation of AprilTag item description **type** func **return** return rotation of the AprilTag, type is float **static** False > C++ defination code: > ```cpp > float rotation() > ``` #### decision\\_margin {#decision\\_margin} Get decision_margin of AprilTag item description **type** func **return** Returns the quality of the apriltag match (0.0 1.0) where 1.0 is the best. **static** False > C++ defination code: > ```cpp > float decision_margin() > ``` #### hamming {#hamming} get hamming of AprilTag item description **type** func **return** Returns the number of accepted bit errors for this tag.
    return 0, means 0 bit errors will be accepted.
    1 is TAG25H7, means up to 1 bit error may be accepted
    2 is TAG25H9, means up to 3 bit errors may be accepted
    3 is TAG36H10, means up to 3 bit errors may be accepted
    4 is TAG36H11, means up to 4 bit errors may be accepted
    5 is ARTOOLKIT, means 0 bit errors will be accepted **static** False > C++ defination code: > ```cpp > int hamming() > ``` #### goodness {#goodness} get goodness of AprilTag item description **type** func **return** return goodness of the AprilTag, type is float
    Note: This value is always 0.0 for now. **static** False > C++ defination code: > ```cpp > float goodness() > ``` #### x\\_translation {#x\\_translation} get x_translation of AprilTag item description **type** func **return** return x_translation of the AprilTag, type is float **static** False > C++ defination code: > ```cpp > float x_translation() > ``` #### y\\_translation {#y\\_translation} get y_translation of AprilTag item description **type** func **return** return y_translation of the AprilTag, type is float **static** False > C++ defination code: > ```cpp > float y_translation() > ``` #### z\\_translation {#z\\_translation} get z_translation of AprilTag item description **type** func **return** return z_translation of the AprilTag, type is float **static** False > C++ defination code: > ```cpp > float z_translation() > ``` #### x\\_rotation {#x\\_rotation} get x_rotation of AprilTag item description **type** func **return** return x_rotation of the AprilTag, type is float **static** False > C++ defination code: > ```cpp > float x_rotation() > ``` #### y\\_rotation {#y\\_rotation} get y_rotation of AprilTag item description **type** func **return** return y_rotation of the AprilTag, type is float **static** False > C++ defination code: > ```cpp > float y_rotation() > ``` #### z\\_rotation {#z\\_rotation} get z_rotation of AprilTag item description **type** func **return** return z_rotation of the AprilTag, type is float **static** False > C++ defination code: > ```cpp > float z_rotation() > ``` ### DataMatrix {#DataMatrix} DataMatrix class > C++ defination code: > ```cpp > class DataMatrix > ``` #### \\_\\_init\\_\\_ {#\\_\\_init\\_\\_ 9} DataMatrix constructor item description **type** func **param** **rect**: Inlucdes the top left corner and the width and height of the rectangle. format is {x, y, w, h}, type is std::vector
    **corners**: Includes the four corners of the rectangle. format is {{x0, y0}, {x1, y1}, {x2, y2}, {x3, y3}}, type is std::vector>
    **payload**: The payload of the DataMatrix
    **rotation**: The rotation of the DataMatrix
    **rows**: The rows of the DataMatrix
    **columns**: The columns of the DataMatrix
    **capacity**: The capacity of the DataMatrix
    **padding**: The padding of the DataMatrix
    **static** False > C++ defination code: > ```cpp > DataMatrix(std::vector &rect, std::vector> &corners, std::string &payload, float rotation, int rows, int columns, int capacity, int padding) > ``` #### \\_\\_getitem\\_\\_ {#\\_\\_getitem\\_\\_ 7} Subscript operator item description **type** func **param** **index**: [0] get x of DataMatrix
    [1] get y of DataMatrix
    [2] get w of DataMatrix
    [3] get h of DataMatrix
    [4] Not support this index, try to use payload() method
    [5] Not support this index, try to use rotation() method
    [6] get rows of DataMatrix
    [7] get columns of DataMatrix
    [8] get capacity of DataMatrix
    [9] get padding of DataMatrix
    **return** int& **static** False > C++ defination code: > ```cpp > int &__getitem__(int index) > ``` #### corners {#corners 5} get coordinate of DataMatrix item description **type** func **return** return the coordinate of the DataMatrix. **static** False > C++ defination code: > ```cpp > std::vector> corners() > ``` #### rect {#rect 6} get rectangle of DataMatrix item description **type** func **return** return the rectangle of the DataMatrix. format is {x, y, w, h}, type is std::vector **static** False > C++ defination code: > ```cpp > std::vector rect() > ``` #### x {#x 6} get x of DataMatrix item description **type** func **return** return x of the DataMatrix, type is int **static** False > C++ defination code: > ```cpp > int x() > ``` #### y {#y 6} get y of DataMatrix item description **type** func **return** return y of the DataMatrix, type is int **static** False > C++ defination code: > ```cpp > int y() > ``` #### w {#w 5} get w of DataMatrix item description **type** func **return** return w of the DataMatrix, type is int **static** False > C++ defination code: > ```cpp > int w() > ``` #### h {#h 5} get h of DataMatrix item description **type** func **return** return h of the DataMatrix, type is int **static** False > C++ defination code: > ```cpp > int h() > ``` #### payload {#payload 2} get payload of DataMatrix item description **type** func **return** return payload of the DataMatrix, type is std::string **static** False > C++ defination code: > ```cpp > std::string payload() > ``` #### rotation {#rotation 3} get rotation of DataMatrix item description **type** func **return** return rotation of the DataMatrix, type is float **static** False > C++ defination code: > ```cpp > float rotation() > ``` #### rows {#rows} get rows of DataMatrix item description **type** func **return** return rows of the DataMatrix, type is int **static** False > C++ defination code: > ```cpp > int rows() > ``` #### columns {#columns} get columns of DataMatrix item description **type** func **return** return columns of the DataMatrix, type is int **static** False > C++ defination code: > ```cpp > int columns() > ``` #### capacity {#capacity} get capacity of DataMatrix item description **type** func **return** returns how many characters could fit in this data matrix, type is int **static** False > C++ defination code: > ```cpp > int capacity() > ``` #### padding {#padding} get padding of DataMatrix item description **type** func **return** returns how many unused characters are in this data matrix, type is int **static** False > C++ defination code: > ```cpp > int padding() > ``` ### BarCode {#BarCode} BarCode class > C++ defination code: > ```cpp > class BarCode > ``` #### \\_\\_init\\_\\_ {#\\_\\_init\\_\\_ 10} BarCode constructor item description **type** func **param** **rect**: Inlucdes the top left corner and the width and height of the rectangle. format is {x, y, w, h}, type is std::vector
    **corners**: Includes the four corners of the rectangle. format is {{x0, y0}, {x1, y1}, {x2, y2}, {x3, y3}}, type is std::vector>
    **payload**: The payload of the BarCode
    **type**: The type of the BarCode
    **rotation**: The rotation of the BarCode
    **quality**: The quality of the BarCode
    **static** False > C++ defination code: > ```cpp > BarCode(std::vector &rect, std::vector> &corners, std::string &payload, int type, float rotation, int quality) > ``` #### \\_\\_getitem\\_\\_ {#\\_\\_getitem\\_\\_ 8} Subscript operator item description **type** func **param** **index**: [0] get x of BarCode
    [1] get y of BarCode
    [2] get w of BarCode
    [3] get h of BarCode
    [4] Not support this index, try to use payload() method
    [5] get type of BarCode
    [6] Not support this index, try to use rotation() method
    [7] get quality of BarCode
    **return** int& **static** False > C++ defination code: > ```cpp > int &__getitem__(int index) > ``` #### corners {#corners 6} get coordinate of BarCode item description **type** func **return** return the coordinate of the BarCode. **static** False > C++ defination code: > ```cpp > std::vector> corners() > ``` #### rect {#rect 7} get rectangle of BarCode item description **type** func **return** return the rectangle of the BarCode. format is {x, y, w, h}, type is std::vector **static** False > C++ defination code: > ```cpp > std::vector rect() > ``` #### x {#x 7} get x of BarCode item description **type** func **return** return x of the BarCode, type is int **static** False > C++ defination code: > ```cpp > int x() > ``` #### y {#y 7} get y of BarCode item description **type** func **return** return y of the BarCode, type is int **static** False > C++ defination code: > ```cpp > int y() > ``` #### w {#w 6} get w of BarCode item description **type** func **return** return w of the BarCode, type is int **static** False > C++ defination code: > ```cpp > int w() > ``` #### h {#h 6} get h of BarCode item description **type** func **return** return h of the BarCode, type is int **static** False > C++ defination code: > ```cpp > int h() > ``` #### payload {#payload 3} get payload of BarCode item description **type** func **return** return payload of the BarCode, type is std::string **static** False > C++ defination code: > ```cpp > std::string payload() > ``` #### type {#type} get type of BarCode item description **type** func **return** return type of the BarCode, type is int **static** False > C++ defination code: > ```cpp > int type() > ``` #### rotation {#rotation 4} get rotation of BarCode item description **type** func **return** return rotation of the BarCode, type is float. FIXME: always return 0.0 **static** False > C++ defination code: > ```cpp > float rotation() > ``` #### quality {#quality} get quality of BarCode item description **type** func **return** return quality of the BarCode, type is int **static** False > C++ defination code: > ```cpp > int quality() > ``` ### Statistics {#Statistics} Statistics class > C++ defination code: > ```cpp > class Statistics > ``` #### \\_\\_init\\_\\_ {#\\_\\_init\\_\\_ 11} Statistics constructor item description **type** func **param** **format**: The statistics source image format
    **l_statistics**: The statistics of the L channel. format is {mean, median, mode, std_dev, min, max, lq, uq}, type is std::vector
    **a_statistics**: The statistics of the A channel. format is {mean, median, mode, std_dev, min, max, lq, uq}, type is std::vector
    **b_statistics**: The statistics of the B channel. format is {mean, median, mode, std_dev, min, max, lq, uq}, type is std::vector
    **static** False > C++ defination code: > ```cpp > Statistics(image::Format format, std::vector &l_statistics, std::vector &a_statistics, std::vector &b_statistics) > ``` #### \\_\\_getitem\\_\\_ {#\\_\\_getitem\\_\\_ 9} Subscript operator item description **type** func **param** **index**: array index
    **return** int& **static** False > C++ defination code: > ```cpp > int &__getitem__(int index) > ``` #### format {#format 2} get format of Statistics source image item description **type** func **return** return format of the Statistics source image, type is image::Format **static** False > C++ defination code: > ```cpp > image::Format format() > ``` #### l\\_mean {#l\\_mean} get L channel mean item description **type** func **return** return L channel mean, type is int **static** False > C++ defination code: > ```cpp > int l_mean() > ``` #### l\\_median {#l\\_median} get L channel median item description **type** func **return** return L channel median, type is int **static** False > C++ defination code: > ```cpp > int l_median() > ``` #### l\\_mode {#l\\_mode} get L channel mode item description **type** func **return** return L channel mode, type is int **static** False > C++ defination code: > ```cpp > int l_mode() > ``` #### l\\_std\\_dev {#l\\_std\\_dev} get L channel std_dev item description **type** func **return** return L channel std_dev, type is int **static** False > C++ defination code: > ```cpp > int l_std_dev() > ``` #### l\\_min {#l\\_min} get L channel min item description **type** func **return** return L channel min, type is int **static** False > C++ defination code: > ```cpp > int l_min() > ``` #### l\\_max {#l\\_max} get L channel max item description **type** func **return** return L channel max, type is int **static** False > C++ defination code: > ```cpp > int l_max() > ``` #### l\\_lq {#l\\_lq} get L channel lq item description **type** func **return** return L channel lq, type is int **static** False > C++ defination code: > ```cpp > int l_lq() > ``` #### l\\_uq {#l\\_uq} get L channel uq item description **type** func **return** return L channel uq, type is int **static** False > C++ defination code: > ```cpp > int l_uq() > ``` #### a\\_mean {#a\\_mean} get A channel mean item description **type** func **return** return A channel mean, type is int **static** False > C++ defination code: > ```cpp > int a_mean() > ``` #### a\\_median {#a\\_median} get A channea median item description **type** func **return** return A channel median, type is int **static** False > C++ defination code: > ```cpp > int a_median() > ``` #### a\\_mode {#a\\_mode} get A channel mode item description **type** func **return** return A channel mode, type is int **static** False > C++ defination code: > ```cpp > int a_mode() > ``` #### a\\_std\\_dev {#a\\_std\\_dev} get A channel std_dev item description **type** func **return** return A channel std_dev, type is int **static** False > C++ defination code: > ```cpp > int a_std_dev() > ``` #### a\\_min {#a\\_min} get A channel min item description **type** func **return** return A channel min, type is int **static** False > C++ defination code: > ```cpp > int a_min() > ``` #### a\\_max {#a\\_max} get A channel max item description **type** func **return** return A channel max, type is int **static** False > C++ defination code: > ```cpp > int a_max() > ``` #### a\\_lq {#a\\_lq} get A channel lq item description **type** func **return** return A channel lq, type is int **static** False > C++ defination code: > ```cpp > int a_lq() > ``` #### a\\_uq {#a\\_uq} get A channel uq item description **type** func **return** return A channel uq, type is int **static** False > C++ defination code: > ```cpp > int a_uq() > ``` #### b\\_mean {#b\\_mean} get B channel mean item description **type** func **return** return B channel mean, type is int **static** False > C++ defination code: > ```cpp > int b_mean() > ``` #### b\\_median {#b\\_median} get B channea median item description **type** func **return** return B channel median, type is int **static** False > C++ defination code: > ```cpp > int b_median() > ``` #### b\\_mode {#b\\_mode} get B channel mode item description **type** func **return** return B channel mode, type is int **static** False > C++ defination code: > ```cpp > int b_mode() > ``` #### b\\_std\\_dev {#b\\_std\\_dev} get B channel std_dev item description **type** func **return** return B channel std_dev, type is int **static** False > C++ defination code: > ```cpp > int b_std_dev() > ``` #### b\\_min {#b\\_min} get B channel min item description **type** func **return** return B channel min, type is int **static** False > C++ defination code: > ```cpp > int b_min() > ``` #### b\\_max {#b\\_max} get B channel max item description **type** func **return** return B channel max, type is int **static** False > C++ defination code: > ```cpp > int b_max() > ``` #### b\\_lq {#b\\_lq} get B channel lq item description **type** func **return** return B channel lq, type is int **static** False > C++ defination code: > ```cpp > int b_lq() > ``` #### b\\_uq {#b\\_uq} get B channel uq item description **type** func **return** return B channel uq, type is int **static** False > C++ defination code: > ```cpp > int b_uq() > ``` ### Displacement {#Displacement} Displacement class > C++ defination code: > ```cpp > class Displacement > ``` #### \\_\\_init\\_\\_ {#\\_\\_init\\_\\_ 12} Displacement constructor item description **type** func **param** **x_translation**: The x_translation of the Displacement
    **y_translation**: The y_translation of the Displacement
    **rotation**: The rotation of the Displacement
    **scale**: The scale of the Displacement
    **response**: The response of the Displacement
    **static** False > C++ defination code: > ```cpp > Displacement(float x_translation, float y_translation, float rotation, float scale, float response) > ``` #### \\_\\_getitem\\_\\_ {#\\_\\_getitem\\_\\_ 10} Subscript operator item description **type** func **param** **index**: array index
    **return** int& **static** False > C++ defination code: > ```cpp > int &__getitem__(int index) > ``` #### x\\_translation {#x\\_translation 2} get x_translation of Displacement item description **type** func **return** return x_translation of the Displacement, type is float **static** False > C++ defination code: > ```cpp > float x_translation() > ``` #### y\\_translation {#y\\_translation 2} get y_translation of Displacement item description **type** func **return** return y_translation of the Displacement, type is float **static** False > C++ defination code: > ```cpp > float y_translation() > ``` #### rotation {#rotation 5} get rotation of Displacement item description **type** func **return** return rotation of the Displacement, type is float **static** False > C++ defination code: > ```cpp > float rotation() > ``` #### scale {#scale} get scale of Displacement item description **type** func **return** return scale of the Displacement, type is float **static** False > C++ defination code: > ```cpp > float scale() > ``` #### response {#response} get response of Displacement item description **type** func **return** return response of the Displacement, type is float **static** False > C++ defination code: > ```cpp > float response() > ``` ### Percentile {#Percentile} Percentile class > C++ defination code: > ```cpp > class Percentile > ``` #### \\_\\_init\\_\\_ {#\\_\\_init\\_\\_ 13} Percentile constructor item description **type** func **param** **l_value**: for grayscale image, it is grayscale percentile value (between 0 and 255).
    for rgb888 image, it is l channel percentile value of lab (between 0 and 100).
    **a_value**: for rgb888 image, it is a channel percentile value of lab format(between 128 and 127).
    **b_value**: for rgb888 image, it is b channel percentile value of lab format(between 128 and 127).
    **static** False > C++ defination code: > ```cpp > Percentile(int l_value, int a_value 0, int b_value 0) > ``` #### \\_\\_getitem\\_\\_ {#\\_\\_getitem\\_\\_ 11} Subscript operator item description **type** func **static** False > C++ defination code: > ```cpp > int &__getitem__(int index) > ``` #### value {#value} Return the grayscale percentile value (between 0 and 255). item description **type** func **return** returns grayscale percentile value **static** False > C++ defination code: > ```cpp > int value() > ``` #### l\\_value {#l\\_value} Return the l channel percentile value of lab format (between 0 and 100). item description **type** func **return** returns l channel percentile value **static** False > C++ defination code: > ```cpp > int l_value() > ``` #### a\\_value {#a\\_value} Return the a channel percentile value of lab format (between 128 and 127). item description **type** func **return** returns a channel percentile value **static** False > C++ defination code: > ```cpp > int a_value() > ``` #### b\\_value {#b\\_value} Return the b channel percentile value of lab format (between 128 and 127). item description **type** func **return** returns b channel percentile value **static** False > C++ defination code: > ```cpp > int b_value() > ``` ### Threshold {#Threshold} Threshold class > C++ defination code: > ```cpp > class Threshold > ``` #### \\_\\_init\\_\\_ {#\\_\\_init\\_\\_ 14} Threshold constructor item description **type** func **param** **l_value**: for grayscale image, it is grayscale threshold value (between 0 and 255).
    for rgb888 image, it is l channel threshold value of lab (between 0 and 100).
    **a_value**: for rgb888 image, it is a channel threshold value of lab format(between 128 and 127).
    **b_value**: for rgb888 image, it is b channel threshold value of lab format(between 128 and 127).
    **static** False > C++ defination code: > ```cpp > Threshold(int l_value, int a_value 0, int b_value 0) > ``` #### \\_\\_getitem\\_\\_ {#\\_\\_getitem\\_\\_ 12} Subscript operator item description **type** func **static** False > C++ defination code: > ```cpp > int &__getitem__(int index) > ``` #### value {#value 2} Return the grayscale threshold value (between 0 and 255). item description **type** func **return** returns grayscale threshold value **static** False > C++ defination code: > ```cpp > int value() > ``` #### l\\_value {#l\\_value 2} Return the l channel threshold value of lab format (between 0 and 100). item description **type** func **return** returns l channel percentile value **static** False > C++ defination code: > ```cpp > int l_value() > ``` #### a\\_value {#a\\_value 2} Return the a channel threshold value of lab format (between 128 and 127). item description **type** func **return** returns a channel percentile value **static** False > C++ defination code: > ```cpp > int a_value() > ``` #### b\\_value {#b\\_value 2} Return the b channel threshold value of lab format (between 128 and 127). item description **type** func **return** returns b channel percentile value **static** False > C++ defination code: > ```cpp > int b_value() > ``` ### Histogram {#Histogram} Histogram class > C++ defination code: > ```cpp > class Histogram > ``` #### \\_\\_init\\_\\_ {#\\_\\_init\\_\\_ 15} Histogram constructor item description **type** func **param** **l_value**: for grayscale image, it is grayscale threshold value list (the range of element values in the list is 0 and 255).
    for rgb888 image, it is l channel threshold value list of lab (the range of element values in the list is 0 and 100).
    **a_value**: for rgb888 image, it is a channel threshold value list of lab format(the range of element values in the list is 128 and 127).
    **b_value**: for rgb888 image, it is b channel threshold value list of lab format(the range of element values in the list is 128 and 127).
    **format**: format of the source image
    **static** False > C++ defination code: > ```cpp > Histogram(std::vector l_bin, std::vector a_bin, std::vector b_bin, image::Format format image::Format::FMT_RGB888) > ``` #### \\_\\_getitem\\_\\_ {#\\_\\_getitem\\_\\_ 13} Subscript operator item description **type** func **static** False > C++ defination code: > ```cpp > int &__getitem__(int index) > ``` #### bins {#bins} Returns a list of floats for the grayscale histogram. item description **type** func **static** False > C++ defination code: > ```cpp > std::vector bins() > ``` #### l\\_bins {#l\\_bins} Returns a list of floats for the RGB565 histogram LAB L channel. item description **type** func **static** False > C++ defination code: > ```cpp > std::vector l_bins() > ``` #### a\\_bins {#a\\_bins} Returns a list of floats for the RGB565 histogram LAB A channel. item description **type** func **static** False > C++ defination code: > ```cpp > std::vector a_bins() > ``` #### b\\_bins {#b\\_bins} Returns a list of floats for the RGB565 histogram LAB B channel. item description **type** func **static** False > C++ defination code: > ```cpp > std::vector b_bins() > ``` #### get\\_percentile {#get\\_percentile} Computes the CDF of the histogram channels and returns a image::Percentile object item description **type** func **param** **percentile**: the values of the histogram at the passed in percentile (0.0 1.0) (float).
    So, if you pass in 0.1 this method will tell you (going from left to right in the histogram)
    what bin when summed into an accumulator caused the accumulator to cross 0.1. This is useful
    to determine min (with 0.1) and max (with 0.9) of a color distribution without outlier effects
    ruining your results for adaptive color tracking.
    **return** image::Percentile object **static** False > C++ defination code: > ```cpp > image::Percentile get_percentile(float percentile) > ``` #### get\\_threshold {#get\\_threshold} Uses Otsu’s Method to compute the optimal threshold values that split the histogram into two halves for each channel of the histogram and returns a image::Threshold object. item description **type** func **return** image::Threshold object **static** False > C++ defination code: > ```cpp > image::Threshold get_threshold() > ``` #### get\\_statistics {#get\\_statistics} Computes the mean, median, mode, standard deviation, min, max, lower quartile, and upper quartile of each color channel in the histogram and returns a image::Statistics object. item description **type** func **return** image::Statistics object **static** False > C++ defination code: > ```cpp > image::Statistics get_statistics() > ``` ### LBPKeyPoint {#LBPKeyPoint} LBPKeyPoint class > C++ defination code: > ```cpp > class LBPKeyPoint > ``` #### \\_\\_init\\_\\_ {#\\_\\_init\\_\\_ 16} LBPKeyPoint constructor item description **type** func **param** **data**: The data of the LBPKeyPoint
    **static** False > C++ defination code: > ```cpp > LBPKeyPoint(std::valarray &data) > ``` ### KeyPoint {#KeyPoint} KeyPoint class > C++ defination code: > ```cpp > class KeyPoint > ``` #### \\_\\_init\\_\\_ {#\\_\\_init\\_\\_ 17} KeyPoint constructor item description **type** func **param** **x**: The x of the KeyPoint
    **y**: The y of the KeyPoint
    **score**: The score of the KeyPoint
    **octave**: The octave of the KeyPoint
    **angle**: The angle of the KeyPoint
    **matched**: The matched of the KeyPoint
    **desc**: The desc of the KeyPoint
    **static** False > C++ defination code: > ```cpp > KeyPoint(uint16_t x, uint16_t y, uint16_t score, uint16_t octave, uint16_t angle, uint16_t matched, std::vector &desc) > ``` ### KPTMatch {#KPTMatch} KPTMatch class > C++ defination code: > ```cpp > class KPTMatch > ``` #### \\_\\_init\\_\\_ {#\\_\\_init\\_\\_ 18} KPTMatch constructor item description **type** func **param** **cx**: The cx of the KPTMatch
    **cy**: The cy of the KPTMatch
    **x**: The x of the KPTMatch
    **y**: The y of the KPTMatch
    **w**: The w of the KPTMatch
    **h**: The h of the KPTMatch
    **score**: The score of the KPTMatch
    **theta**: The theta of the KPTMatch
    **match**: The match of the KPTMatch
    **static** False > C++ defination code: > ```cpp > KPTMatch(int cx, int cy, int x, int y, int w, int h, int score, int theta, int match) > ``` ### ORBKeyPoint {#ORBKeyPoint} ORBKeyPoint class > C++ defination code: > ```cpp > class ORBKeyPoint > ``` #### \\_\\_init\\_\\_ {#\\_\\_init\\_\\_ 19} ORBKeyPoint constructor item description **type** func **param** **data**: The data of the ORBKeyPoint
    **threshold**: The threshold of the ORBKeyPoint
    **normalized**: The normalized of the ORBKeyPoint
    **static** False > C++ defination code: > ```cpp > ORBKeyPoint(std::vector &data, int threshold, bool normalized) > ``` #### get\\_data {#get\\_data} get data of ORBKeyPoint item description **type** func **return** return data of the ORBKeyPoint, type is std::vector **static** False > C++ defination code: > ```cpp > std::vector get_data() > ``` ### HaarCascade {#HaarCascade} HaarCascade class > C++ defination code: > ```cpp > class HaarCascade > ``` #### \\_\\_init\\_\\_ {#\\_\\_init\\_\\_ 20} HaarCascade constructor item description **type** func **param** **data**: The data of the HaarCascade
    **threshold**: The threshold of the HaarCascade
    **normalized**: The normalized of the HaarCascade
    **static** False > C++ defination code: > ```cpp > HaarCascade() > ``` #### \\_\\_init\\_\\_ (overload 1) {#\\_\\_init\\_\\_ (overload 1)} LineGroup constructor item description **type** func **param** **id**: The id of line
    **type**: The line list type, @see image::LineType
    **lines**: The line list
    **points**: Point sets of line
    **static** False > C++ defination code: > ```cpp > LineGroup(int id, image::LineType type, std::vector lines, std::vector>> points std::vector>>()) > ``` ### LineGroup {#LineGroup} LineGroup class > C++ defination code: > ```cpp > class LineGroup > ``` #### id {#id 2} Get the line id of group, first id is 0. item description **type** func **return** return id **static** False > C++ defination code: > ```cpp > int id() > ``` #### type {#type 2} Get the line type of group item description **type** func **return** returns line type. @see LineType **static** False > C++ defination code: > ```cpp > image::LineType type() > ``` #### lines {#lines} Get a list of line item description **type** func **return** returns a list composed of Line objects **static** False > C++ defination code: > ```cpp > std::vector lines() > ``` #### points {#points} Get the key points of line item description **type** func **return** returns a list composed of (x,y) coordnates. **static** False > C++ defination code: > ```cpp > std::vector>> points() > ``` ### Image {#Image} Image class > C++ defination code: > ```cpp > class Image > ``` #### Image {#Image 2} Image constructor item description **type** func **param** **width**: image width, should > 0
    **height**: image height, should > 0
    **format**: image format @see image::Format
    **static** False > C++ defination code: > ```cpp > Image(int width, int height, image::Format format image::Format::FMT_RGB888) > ``` #### Image (overload 1) {#Image (overload 1)} Image constructor item description **type** func **param** **width**: image width, should > 0
    **height**: image height, should > 0
    **format**: image format @see image::Format
    **data**: image data, if data is nullptr, will malloc memory for image data
    If the image is in jpeg format, data must be filled in.
    **data_size**: image data size, only for compressed format like jpeg png, data_size must be filled in, or should be 1, default is 1.
    **copy**: if true and data is not nullptr, will copy data to new buffer, else will use data directly. default is true to avoid memory leak.
    **static** False > C++ defination code: > ```cpp > Image(int width, int height, image::Format format, uint8_t *data, int data_size, bool copy) > ``` #### update {#update} set image item description **type** func **static** False > C++ defination code: > ```cpp > err::Err update(int width, int height, image::Format format, uint8_t *data NULL, int data_size 0, bool copy true) > ``` #### format {#format 3} Get image's format item description **type** func **see** image.Format **static** False > C++ defination code: > ```cpp > image::Format format() > ``` #### size {#size 2} Get image's size, [width, height] item description **type** func **static** False > C++ defination code: > ```cpp > image::Size size() > ``` #### data\\_size {#data\\_size} Get image's data size item description **type** func **static** False > C++ defination code: > ```cpp > int data_size() > ``` #### width {#width 2} Get image's width item description **type** func **static** False > C++ defination code: > ```cpp > int width() > ``` #### height {#height 2} Get image's height item description **type** func **static** False > C++ defination code: > ```cpp > int height() > ``` #### data {#data} Get image's data pointer.\\nIn MaixPy is capsule object. item description **type** func **static** False > C++ defination code: > ```cpp > void *data() > ``` #### \\_\\_str\\_\\_ {#\\_\\_str\\_\\_ 2} To string method item description **type** func **static** False > C++ defination code: > ```cpp > std::string __str__() > ``` #### to\\_str {#to\\_str} To string method item description **type** func **static** False > C++ defination code: > ```cpp > std::string to_str() > ``` #### get\\_pixel {#get\\_pixel} Get pixel of image item description **type** func **param** **x**: pixel's coordinate x. x must less than image's width
    **y**: pixel's coordinate y. y must less than image's height
    **rgbtuple**: switch return value method. rgbtuple decides whether to split the return or not. default is false.
    **return** pixel value,
    According to image format and rgbtuple, return different value:
    format is FMT_RGB888, rgbtuple is true, return [R, G, B]; rgbtuple is false, return [RGB]
    foramt is FMT_BGR888, rgbtuple is true, return [B, G, R]; rgbtuple is false, return [BGR]
    format is FMT_GRAYSCALE, return [GRAY]; **static** False > C++ defination code: > ```cpp > std::vector get_pixel(int x, int y, bool rgbtuple false) > ``` #### set\\_pixel {#set\\_pixel} Set pixel of image item description **type** func **param** **x**: pixel's coordinate x. x must less than image's width
    **y**: pixel's coordinate y. y must less than image's height
    **pixel**: pixel value, according to image format and size of pixel, has different operation:
    format is FMT_RGB888, pixel size must be 1 or 3, if size is 1, will split pixel[0] to [R, G, B]; if size is 3, will use pixel directly
    format is FMT_BGR888, pixel size must be 1 or 3, if size is 1, will split pixel[0] to [B, G, R]; if size is 3, will use pixel directly
    format is FMT_GRAYSCALE, pixel size must be 1, will use pixel directly
    **return** error code, Err::ERR_NONE is ok, other is error **static** False > C++ defination code: > ```cpp > err::Err set_pixel(int x, int y, std::vector pixel) > ``` #### to\\_tensor {#to\\_tensor} Convert Image object to tensor::Tensor object item description **type** func **param** **chw**: if true, the shape of tensor is [C, H, W], else [H, W, C]
    **copy**: if true, will alloc memory for tensor data, else will use the memory of Image object
    **return** tensor::Tensor object pointer, an allocated tensor object **static** False > C++ defination code: > ```cpp > tensor::Tensor *to_tensor(bool chw false, bool copy true) > ``` #### to\\_bytes {#to\\_bytes} Get image's data and convert to array bytes item description **type** func **param** **copy**: if true, will alloc memory and copy data to new buffer,
    else will use the memory of Image object, delete bytes object will not affect Image object,
    but delete Image object will make bytes object invalid, it may cause program crash !!!!
    So use this param carefully.
    **return** image's data bytes, need be delete by caller in C++. **static** False > C++ defination code: > ```cpp > Bytes *to_bytes(bool copy true) > ``` #### to\\_format {#to\\_format} Convert image to specific format item description **type** func **param** **format**: format want to convert to, @see image::Format, only support RGB888, BGR888, RGBA8888, BGRA8888, GRAYSCALE, JPEG.
    **return** new image object. Need be delete by caller in C++. **throw** err.Exception, if two images' format not support, **or already the format**, will raise exception **static** False > C++ defination code: > ```cpp > image::Image *to_format(const image::Format &format) > ``` #### to\\_format (overload 1) {#to\\_format (overload 1)} Convert image to specific format item description **type** func **param** **format**: format want to convert to, @see image::Format, only support RGB888, BGR888, RGBA8888, BGRA8888, GRAYSCALE, JPEG.
    **buff**: user's buffer, if buff is nullptr, will malloc memory for new image data, else will use buff directly
    **return** new image object. Need be delete by caller in C++. **throw** err.Exception, if two images' format not support, **or already the format**, will raise exception **static** False > C++ defination code: > ```cpp > image::Image *to_format(const image::Format &format, void *buff, size_t buff_size) > ``` #### to\\_jpeg {#to\\_jpeg} Convert image to jpeg item description **type** func **param** **quality**: the quality of jpg, default is 95. For MaixCAM supported range is (50, 100], if < 50 will be fixed to 51.
    **return** new image object. Need be delete by caller in C++. **throw** err.Exception, if two images' format not support, **or already the format**, will raise exception **static** False > C++ defination code: > ```cpp > image::Image *to_jpeg(int quality 95) > ``` #### draw\\_image {#draw\\_image} Draw image on this image item description **type** func **param** **x**: left top corner of image point's coordinate x
    **y**: left top corner of image point's coordinate y
    **img**: image object to draw, the caller's channel must < the args' channel,
    e.g. caller is RGB888, args is RGBA8888, will throw exception, but caller is RGBA8888, args is RGB888 or RGBA8888 is ok
    **return** this image object self **static** False > C++ defination code: > ```cpp > image::Image *draw_image(int x, int y, image::Image &img) > ``` #### draw\\_rect {#draw\\_rect} Fill rectangle color to image item description **type** func **param** **x**: left top corner of rectangle point's coordinate x
    **y**: left top corner of rectangle point's coordinate y
    **w**: rectangle width
    **h**: rectangle height
    **color**: rectangle color
    **thickness**: rectangle thickness(line width), by default(value is 1), 1 means fill rectangle
    **return** this image object self **static** False > C++ defination code: > ```cpp > image::Image *draw_rect(int x, int y, int w, int h, const image::Color &color, int thickness 1) > ``` #### draw\\_line {#draw\\_line} Draw line on image item description **type** func **param** **x1**: start point's coordinate x
    **y1**: start point's coordinate y
    **x2**: end point's coordinate x
    **y2**: end point's coordinate y
    **color**: line color @see image::Color
    **thickness**: line thickness(line width), by default(value is 1)
    **return** this image object self **static** False > C++ defination code: > ```cpp > image::Image *draw_line(int x1, int y1, int x2, int y2, const image::Color &color, int thickness 1) > ``` #### draw\\_circle {#draw\\_circle} Draw circle on image item description **type** func **param** **x**: circle center point's coordinate x
    **y**: circle center point's coordinate y
    **radius**: circle radius
    **color**: circle color @see image::Color
    **thickness**: circle thickness(line width), default 1 means fill circle
    **return** this image object self **static** False > C++ defination code: > ```cpp > image::Image *draw_circle(int x, int y, int radius, const image::Color &color, int thickness 1) > ``` #### draw\\_ellipse {#draw\\_ellipse} Draw ellipse on image item description **type** func **param** **x**: ellipse center point's coordinate x
    **y**: ellipse center point's coordinate y
    **a**: ellipse major axis length
    **b**: ellipse minor axis length
    **angle**: ellipse rotation angle
    **start_angle**: ellipse start angle
    **end_angle**: ellipse end angle
    **color**: ellipse color @see image::Color
    **thickness**: ellipse thickness(line width), by default(value is 1), 1 means fill ellipse
    **return** this image object self **static** False > C++ defination code: > ```cpp > image::Image *draw_ellipse(int x, int y, int a, int b, float angle, float start_angle, float end_angle, const image::Color &color, int thickness 1) > ``` #### draw\\_string {#draw\\_string} Draw text on image item description **type** func **param** **x**: text left top point's coordinate x
    **y**: text left top point's coordinate y
    **string**: text content
    **color**: text color @see image::Color, default is white
    **scale**: font scale, by default(value is 1)
    **thickness**: text thickness(line width), if negative, the glyph is filled, by default(value is 1)
    **wrap**: if true, will auto wrap text to next line if text width > image width, by default(value is true)
    **return** this image object self **static** False > C++ defination code: > ```cpp > image::Image *draw_string(int x, int y, const std::string &textstring, const image::Color &color image::COLOR_WHITE, float scale 1, int thickness 1, > bool wrap true, int wrap_space 4, const std::string &font \"\") > ``` #### draw\\_cross {#draw\\_cross} Draw cross on image item description **type** func **param** **x**: cross center point's coordinate x
    **y**: cross center point's coordinate y
    **color**: cross color @see image::Color
    **size**: how long the lines of the cross extend, by default(value is 5). So the line length is `2 * size + thickness`
    **thickness**: cross thickness(line width), by default(value is 1)
    **static** False > C++ defination code: > ```cpp > image::Image *draw_cross(int x, int y, const image::Color &color, int size 5, int thickness 1) > ``` #### draw\\_arrow {#draw\\_arrow} Draw arrow on image item description **type** func **param** **x0**: start coordinate of the arrow x0
    **y0**: start coordinate of the arrow y0
    **x1**: end coordinate of the arrow x1
    **y1**: end coordinate of the arrow y1
    **color**: cross color @see image::Color
    **thickness**: cross thickness(line width), by default(value is 1)
    **return** this image object self **static** False > C++ defination code: > ```cpp > image::Image *draw_arrow(int x0, int y0, int x1, int y1, const image::Color &color, int thickness 1) > ``` #### draw\\_edges {#draw\\_edges} Draw edges on image item description **type** func **param** **corners**: edges, [[x0, y0], [x1, y1], [x2, y2], [x3, y3]]
    **color**: edges color @see image::Color
    **size**: the circle of radius size. TODO: support in the feature
    **thickness**: edges thickness(line width), by default(value is 1)
    **fill**: if true, will fill edges, by default(value is false)
    **return** this image object self **static** False > C++ defination code: > ```cpp > image::Image *draw_edges(std::vector> corners, const image::Color &color, int size 0, int thickness 1, bool fill false) > ``` #### draw\\_keypoints {#draw\\_keypoints} Draw keypoints on image item description **type** func **param** **keypoints**: keypoints, [x1, y1, x2, y2...] or [x, y, rotation_andle_in_degrees, x2, y2, rotation_andle_in_degrees2](TODO: rotation_andle_in_degrees support in the feature)
    **color**: keypoints color @see image::Color
    **size**: size of keypoints(radius)
    **thickness**: keypoints thickness(line width), by default(value is 1 means fill circle)
    **line_thickness**: line thickness, default 0 means not draw lines, > 0 will draw lines connect points.
    **return** this image object self **static** False > C++ defination code: > ```cpp > image::Image *draw_keypoints(const std::vector &keypoints, const image::Color &color, int size 4, int thickness 1, int line_thickness 0) > ``` #### resize {#resize} Resize image, will create a new resized image object item description **type** func **param** **width**: new width, if value is 1, will use height to calculate aspect ratio
    **height**: new height, if value is 1, will use width to calculate aspect ratio
    **object_fit**: fill, contain, cover, by default is fill
    **method**: resize method, by default is NEAREST
    **return** Always return a new resized image object even size not change, So in C++ you should take care of the return value to avoid memory leak.
    And it's better to judge whether the size has changed before calling this function to make the program more efficient.
    e.g.
    if img >width() ! width img >height() ! height:
    img img >resize(width, height); **static** False > C++ defination code: > ```cpp > image::Image *resize(int width, int height, image::Fit object_fit image::Fit::FIT_FILL, image::ResizeMethod method image::ResizeMethod::NEAREST) > ``` #### affine {#affine} Affine transform image, will create a new transformed image object, need 3 points. item description **type** func **param** **src_points**: three source points, [x1, y1, x2, y2, x3, y3]
    **dst_points**: three destination points, [x1, y1, x2, y2, x3, y3]
    **width**: new width, if value is 1, will use height to calculate aspect ratio
    **height**: new height, if value is 1, will use width to calculate aspect ratio
    **method**: resize method, by default is bilinear
    **return** new transformed image object **static** False > C++ defination code: > ```cpp > image::Image *affine(std::vector src_points, std::vector dst_points, int width 1, int height 1, image::ResizeMethod method image::ResizeMethod::BILINEAR) > ``` #### affine (overload 1) {#affine (overload 1)} Perspective transform image, will create a new transformed image object, need 4 points. item description **type** func **param** **src_points**: three source points, [x1, y1, x2, y2, x3, y3, x4, y4]
    **dst_points**: three destination points, [x1, y1, x2, y2, x3, y3, x4, y4]
    **width**: new width, if value is 1, will use height to calculate aspect ratio
    **height**: new height, if value is 1, will use width to calculate aspect ratio
    **method**: resize method, by default is bilinear
    **return** new transformed image object **static** False > C++ defination code: > ```cpp > image::Image* perspective(std::vector src_points, std::vector dst_points, int width 1, int height 1, image::ResizeMethod method image::ResizeMethod::BILINEAR) > ``` #### copy {#copy} Copy image, will create a new copied image object item description **type** func **return** new copied image object **static** False > C++ defination code: > ```cpp > image::Image *copy() > ``` #### crop {#crop} Crop image, will create a new cropped image object item description **type** func **param** **x**: left top corner of crop rectangle point's coordinate x
    **y**: left top corner of crop rectangle point's coordinate y
    **w**: crop rectangle width
    **h**: crop rectangle height
    **return** new cropped image object **static** False > C++ defination code: > ```cpp > image::Image *crop(int x, int y, int w, int h) > ``` #### rotate {#rotate} Rotate image, will create a new rotated image object item description **type** func **param** **angle**: anti clock wise rotate angle, if angle is 90 or 270, and width or height is 1, will swap width and height, or will throw exception
    **width**: new width, if value is 1, will use height to calculate aspect ratio
    **height**: new height, if value is 1, will use width to calculate aspect ratio
    **method**: resize method, by default is bilinear
    **return** new rotated image object **static** False > C++ defination code: > ```cpp > image::Image *rotate(float angle, int width 1, int height 1, image::ResizeMethod method image::ResizeMethod::BILINEAR) > ``` #### flip {#flip} Vertical flip image, and return a new image. item description **type** func **param** **dir**: flip dir, see image.FlipDir, e.g. image.FlipDir.X is vertical flip.
    **return** new flipped image. **throw** When arg error, will throw out err.Err exception. **static** False > C++ defination code: > ```cpp > image::Image *flip(const image::FlipDir dir) > ``` #### mean\\_pool {#mean\\_pool} Finds the mean of x_div * y_div squares in the image and returns the modified image composed of the mean of each square. item description **type** func **param** **x_div**: The width of the squares.
    **y_div**: The height of the squares.
    **copy**: Select whether to return a new image or modify the original image. default is false.
    If true, returns a new image composed of the mean of each square; If false, returns the modified image composed of the mean of each square.
    **return** Returns the image after the operation is completed. **static** False > C++ defination code: > ```cpp > image::Image *mean_pool(int x_div, int y_div, bool copy false) > ``` #### midpoint\\_pool {#midpoint\\_pool} Finds the midpoint of x_div * y_div squares in the image and returns the modified image composed of the mean of each square. item description **type** func **param** **x_div**: The width of the squares.
    **y_div**: The height of the squares.
    **bias**: The bias of the midpoint. default is 0.5.
    midpoint value is equal to (max * bias + min * (1 bias))
    **copy**: Select whether to return a new image or modify the original image. default is false.
    If true, returns a new image composed of the midpoint of each square; If false, returns the modified image composed of the midpoint of each square.
    **return** Returns the image after the operation is completed. **static** False > C++ defination code: > ```cpp > image::Image *midpoint_pool(int x_div, int y_div, double bias 0.5, bool copy false) > ``` #### compress {#compress} JPEG compresses the image in place, the same as to_jpeg functioin, it's recommend to use to_jpeg instead. item description **type** func **param** **quality**: The quality of the compressed image. default is 95.
    **return** Returns the compressed JPEG image **static** False > C++ defination code: > ```cpp > image::Image *compress(int quality 95) > ``` #### clear {#clear} Sets all pixels in the image to zero item description **type** func **param** **mask**: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.
    Only pixels set in the mask are modified. default is None.
    **return** Returns the image after the operation is completed. **static** False > C++ defination code: > ```cpp > image::Image *clear(image::Image *mask nullptr) > ``` #### mask\\_rectange {#mask\\_rectange} Zeros a rectangular part of the image. If no arguments are supplied this method zeros the center of the image. item description **type** func **param** **x**: The x coordinate of the top left corner of the rectangle.
    **y**: The y coordinate of the top left corner of the rectangle.
    **w**: The width of the rectangle.
    **h**: The height of the rectangle.
    **return** Returns the image after the operation is completed. **static** False > C++ defination code: > ```cpp > image::Image *mask_rectange(int x 1, int y 1, int w 1, int h 1) > ``` #### mask\\_circle {#mask\\_circle} Zeros a circular part of the image. If no arguments are supplied this method zeros the center of the image. item description **type** func **param** **x**: The x coordinate of the center of the circle.
    **y**: The y coordinate of the center of the circle.
    **radius**: The radius of the circle.
    **return** Returns the image after the operation is completed. **static** False > C++ defination code: > ```cpp > image::Image *mask_circle(int x 1, int y 1, int radius 1) > ``` #### mask\\_ellipse {#mask\\_ellipse} Zeros a ellipse part of the image. If no arguments are supplied this method zeros the center of the image. item description **type** func **param** **x**: The x coordinate of the center of the ellipse.
    **y**: The y coordinate of the center of the ellipse.
    **radius_x**: The radius of the ellipse in the x direction.
    **radius_y**: The radius of the ellipse in the y direction.
    **rotation_angle_in_degrees**: The rotation angle of the ellipse in degrees.
    **return** Returns the image after the operation is completed. **static** False > C++ defination code: > ```cpp > image::Image *mask_ellipse(int x 1, int y 1, int radius_x 1, int radius_y 1, float rotation_angle_in_degrees 0) > ``` #### binary {#binary} Sets all pixels in the image to black or white depending on if the pixel is inside of a threshold in the threshold list thresholds or not. item description **type** func **note** For GRAYSCALE format, Lmin and Lmax range is [0, 255]. For RGB888 format, Lmin and Lmax range is [0, 100]. **param** **thresholds**: You can define multiple thresholds.
    For GRAYSCALE format, you can use {{Lmin, Lmax}, ...} to define one or more thresholds.
    For RGB888 format, you can use {{Lmin, Lmax, Amin, Amax, Bmin, Bmax}, ...} to define one or more thresholds.
    Where the upper case L,A,B represent the L,A,B channels of the LAB image format, and min, max represent the minimum and maximum values of the corresponding channels.
    **invert**: If true, the thresholds will be inverted before the operation. default is false.
    **zero**: If zero is true, the image will be set the pixels within the threshold to 0, other pixels remain unchanged. If zero is false, the image will be set to black or white. default is false.
    **mask**: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.
    Only pixels set in the mask are modified. default is None.
    **to_bitmap**: If true, the image will be converted to a bitmap image before thresholding. default is false. TODO: support in the feature
    **copy**: Select whether to return a new image or modify the original image. default is false.
    **return** Returns the image after the operation is completed. **static** False > C++ defination code: > ```cpp > image::Image *binary(std::vector> thresholds std::vector>(), bool invert false, bool zero false, image::Image *mask nullptr, bool to_bitmap false, bool copy false) > ``` #### invert {#invert} Inverts the image in place. item description **type** func **return** Returns the image after the operation is completed **static** False > C++ defination code: > ```cpp > image::Image *invert() > ``` #### b\\_and {#b\\_and} Performs a bitwise and operation between the image and the other image. item description **type** func **param** **other**: The other image should be an image and should be the same size as the image being operated on. TODO: support path?
    **mask**: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.
    Only pixels set in the mask are modified. default is None.
    **return** Returns the image after the operation is completed. **static** False > C++ defination code: > ```cpp > image::Image *b_and(image::Image *other, image::Image *mask nullptr) > ``` #### b\\_nand {#b\\_nand} Performs a bitwise nand operation between the image and the other image. item description **type** func **param** **other**: The other image should be an image and should be the same size as the image being operated on. TODO: support path?
    **mask**: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.
    Only pixels set in the mask are modified. default is None.
    **return** Returns the image after the operation is completed. **static** False > C++ defination code: > ```cpp > image::Image *b_nand(image::Image *other, image::Image *mask nullptr) > ``` #### b\\_or {#b\\_or} Performs a bitwise or operation between the image and the other image. item description **type** func **param** **other**: The other image should be an image and should be the same size as the image being operated on. TODO: support path?
    **mask**: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.
    Only pixels set in the mask are modified. default is None.
    **return** Returns the image after the operation is completed. **static** False > C++ defination code: > ```cpp > image::Image *b_or(image::Image *other, image::Image *mask nullptr) > ``` #### b\\_nor {#b\\_nor} Performs a bitwise nor operation between the image and the other image. item description **type** func **param** **other**: The other image should be an image and should be the same size as the image being operated on. TODO: support path?
    **mask**: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.
    Only pixels set in the mask are modified. default is None.
    **return** Returns the image after the operation is completed. **static** False > C++ defination code: > ```cpp > image::Image *b_nor(image::Image *other, image::Image *mask nullptr) > ``` #### b\\_xor {#b\\_xor} Performs a bitwise xor operation between the image and the other image. item description **type** func **param** **other**: The other image should be an image and should be the same size as the image being operated on. TODO: support path?
    **mask**: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.
    Only pixels set in the mask are modified. default is None.
    **return** Returns the image after the operation is completed. **static** False > C++ defination code: > ```cpp > image::Image *b_xor(image::Image *other, image::Image *mask nullptr) > ``` #### b\\_xnor {#b\\_xnor} Performs a bitwise xnor operation between the image and the other image. item description **type** func **param** **other**: The other image should be an image and should be the same size as the image being operated on. TODO: support path?
    **mask**: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.
    Only pixels set in the mask are modified. default is None.
    **return** Returns the image after the operation is completed. **static** False > C++ defination code: > ```cpp > image::Image *b_xnor(image::Image *other, image::Image *mask nullptr) > ``` #### awb {#awb} Performs an auto white balance operation on the image. TODO: support in the feature item description **type** func **param** **max**: if True uses the white patch algorithm instead. default is false.
    **return** Returns the image after the operation is completed. **static** False > C++ defination code: > ```cpp > image::Image *awb(bool max false) > ``` #### ccm {#ccm} Multiples the passed (3x3) or (4x3) floating point color correction matrix with the image.\\nnote: Grayscale format is not support. item description **type** func **param** **matrix**: The color correction matrix to use. 3x3 or 4x3 matrix.
    Weights may either be positive or negative, and the sum of each column in the 3x3 matrix should generally be 1.
    example:
    {
    1, 0, 0,
    0, 1, 0,
    0, 0, 1,
    }
    Where the last row of the 4x3 matrix is an offset per color channel. If you add an offset you may wish to make the
    weights sum to less than 1 to account for the offset.
    example:
    {
    1, 0, 0,
    0, 1, 0,
    0, 0, 1,
    0, 0, 0,
    }
    **return** Returns the image after the operation is completed. **static** False > C++ defination code: > ```cpp > image::Image *ccm(std::vector &matrix) > ``` #### gamma {#gamma} Quickly changes the image gamma, contrast, and brightness. Create a array whose size is usually 255,\\nand use the parameters gamma, contrast, and brightness to calculate the value of the array, and then map the\\nimage pixel value through the value of the array.\\nThe calculation method for array is: array[array_idx] (powf((array_idx / 255.0), (1 / gamma)) * contrast + brightness) * scale,\\n`powf` is a function used to calculate floating point power.\\n`array` is the array used for mapping.\\n`array_idx` is the index of the array, the maximum value is determined according to the image format, usually 255.\\n`scale` is a constant, the value is determined by the image format, usually 255.\\nMapping method:\\nAssume that a pixel value in the image is 128, then map the pixel value to the value of array[128]\\nUsers can adjust the value of the array through the gamma, contrast, and brightness parameters. item description **type** func **param** **gamma**: The contrast gamma greater than 1.0 makes the image darker in a non linear manner while less than 1.0 makes the image brighter. default is 1.0.
    **contrast**: The contrast value greater than 1.0 makes the image brighter in a linear manner while less than 1.0 makes the image darker. default is 1.0.
    **brightness**: The brightness value greater than 0.0 makes the image brighter in a constant manner while less than 0.0 makes the image darker. default is 0.0.
    **return** Returns the image after the operation is completed. **static** False > C++ defination code: > ```cpp > image::Image *gamma(double gamma 1.0, double contrast 1.0, double brightness 0.0) > ``` #### gamma\\_corr {#gamma\\_corr} Alias for Image.gamma. item description **type** func **param** **gamma**: The contrast gamma greater than 1.0 makes the image darker in a non linear manner while less than 1.0 makes the image brighter. default is 1.0.
    **contrast**: The contrast value greater than 1.0 makes the image brighter in a linear manner while less than 1.0 makes the image darker. default is 1.0.
    **brightness**: The brightness value greater than 0.0 makes the image brighter in a constant manner while less than 0.0 makes the image darker. default is 0.0.
    **return** Returns the image after the operation is completed. **static** False > C++ defination code: > ```cpp > image::Image *gamma_corr(double gamma, double contrast 1.0, double brightness 0.0) > ``` #### negate {#negate} Flips (numerically inverts) all pixels values in an image item description **type** func **return** Returns the image after the operation is completed. **static** False > C++ defination code: > ```cpp > image::Image *negate() > ``` #### replace {#replace} Replaces all pixels in the image with the corresponding pixels in the other image. item description **type** func **param** **other**: The other image should be an image and should be the same size as the image being operated on.
    **hmirror**: If true, the image will be horizontally mirrored before the operation. default is false.
    **vflip**: If true, the image will be vertically flipped before the operation. default is false.
    **transpose**: If true, the image can be used to rotate 90 degrees or 270 degrees.
    hmirror false, vflip false, transpose false, the image will not be rotated.
    hmirror false, vflip true, transpose true, the image will be rotated 90 degrees.
    hmirror true, vflip true, transpose false, the image will be rotated 180 degrees.
    hmirror true, vflip false, transpose true, the image will be rotated 270 degrees.
    **mask**: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.
    Only pixels set in the mask are modified. default is None.
    **return** Returns the image after the operation is completed. **static** False > C++ defination code: > ```cpp > image::Image *replace(image::Image *other nullptr, bool hmirror false, bool vflip false, bool transpose false, image::Image *mask nullptr) > ``` #### set {#set} Alias for Image::replace. item description **type** func **param** **other**: The other image should be an image and should be the same size as the image being operated on.
    **hmirror**: If true, the image will be horizontally mirrored before the operation. default is false.
    **vflip**: If true, the image will be vertically flipped before the operation. default is false.
    **mask**: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.
    Only pixels set in the mask are modified. default is None.
    **return** Returns the image after the operation is completed. **static** False > C++ defination code: > ```cpp > image::Image *set(image::Image *other, bool hmirror false, bool vflip false, bool transpose false, image::Image *mask nullptr) > ``` #### add {#add} Adds the other image to the image. item description **type** func **param** **other**: The other image should be an image and should be the same size as the image being operated on. TODO: support path?
    **mask**: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.
    Only pixels set in the mask are modified. default is None.
    **return** Returns the image after the operation is completed. **static** False > C++ defination code: > ```cpp > image::Image *add(image::Image *other, image::Image *mask nullptr) > ``` #### sub {#sub} Subtracts the other image from the image. item description **type** func **param** **other**: The other image should be an image and should be the same size as the image being operated on. TODO: support path?
    **reverse**: If true, the image will be reversed before the operation. default is false.
    **mask**: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.
    Only pixels set in the mask are modified. default is None.
    **return** Returns the image after the operation is completed. **static** False > C++ defination code: > ```cpp > image::Image *sub(image::Image *other, bool reverse false, image::Image *mask nullptr) > ``` #### mul {#mul} Multiplies the image by the other image.\\nNote: This method is meant for image blending and cannot multiply the pixels in the image by a scalar like 2. item description **type** func **param** **other**: The other image should be an image and should be the same size as the image being operated on. TODO: support path?
    **invert**: If true, the image will be change the multiplication operation from a*b to 1/((1/a)*(1/b)).
    In particular, this lightens the image instead of darkening it (e.g. multiply versus burn operations). default is false.
    **mask**: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.
    Only pixels set in the mask are modified. default is None.
    **return** Returns the image after the operation is completed. **static** False > C++ defination code: > ```cpp > image::Image *mul(image::Image *other, bool invert false, image::Image *mask nullptr) > ``` #### div {#div} Divides the image by the other image.\\nThis method is meant for image blending and cannot divide the pixels in the image by a scalar like 2. item description **type** func **param** **other**: The other image should be an image and should be the same size as the image being operated on. TODO: support path?
    **invert**: If true, the image will be change the division direction from a/b to b/a. default is false.
    **mod**: If true, the image will be change the division operation to the modulus operation. default is false.
    **mask**: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.
    Only pixels set in the mask are modified. default is None.
    **return** Returns the image after the operation is completed. **static** False > C++ defination code: > ```cpp > image::Image *div(image::Image *other, bool invert false, bool mod false, image::Image *mask nullptr) > ``` #### min {#min} Caculate the minimum of each pixel in the image and the other image. item description **type** func **param** **other**: The other image should be an image and should be the same size as the image being operated on.
    **mask**: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.
    Only pixels set in the mask are modified. default is None.
    **return** Returns the image after the operation is completed. **static** False > C++ defination code: > ```cpp > image::Image *min(image::Image *other, image::Image *mask nullptr) > ``` #### max {#max} Caculate the maximum of each pixel in the image and the other image. item description **type** func **param** **other**: The other image should be an image and should be the same size as the image being operated on.
    **mask**: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.
    Only pixels set in the mask are modified. default is None.
    **return** Returns the image after the operation is completed. **static** False > C++ defination code: > ```cpp > image::Image *max(image::Image *other, image::Image *mask nullptr) > ``` #### difference {#difference} Caculate the absolute value of the difference between each pixel in the image and the other image. item description **type** func **param** **other**: The other image should be an image and should be the same size as the image being operated on.
    **mask**: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.
    Only pixels set in the mask are modified. default is None.
    **return** Returns the image after the operation is completed. **static** False > C++ defination code: > ```cpp > image::Image *difference(image::Image *other, image::Image *mask nullptr) > ``` #### blend {#blend} Blends the image with the other image.\\nres alpha * this_img / 256 + (256 alpha) * other_img / 256 item description **type** func **param** **other**: The other image should be an image and should be the same size as the image being operated on.
    **alpha**: The alpha value of the blend, the value range is [0, 256],default is 128.
    **mask**: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.
    Only pixels set in the mask are modified. default is None.
    **return** Returns the image after the operation is completed. **static** False > C++ defination code: > ```cpp > image::Image *blend(image::Image *other, int alpha 128, image::Image *mask nullptr) > ``` #### histeq {#histeq} Runs the histogram equalization algorithm on the image. item description **type** func **param** **adaptive**: If true, an adaptive histogram equalization method will be run on the image instead which as generally better results than non adaptive histogram qualization but a longer run time. default is false.
    **clip_limit**: Provides a way to limit the contrast of the adaptive histogram qualization. Use a small value for this, like 10, to produce good histogram equalized contrast limited images. default is 1.
    **mask**: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.
    Only pixels set in the mask are modified. default is None.
    **return** Returns the image after the operation is completed. **static** False > C++ defination code: > ```cpp > image::Image *histeq(bool adaptive false, int clip_limit 1, image::Image *mask nullptr) > ``` #### mean {#mean} Standard mean blurring filter using a box filter.\\nThe parameters offset and invert are valid when threshold is True. item description **type** func **param** **size**: Kernel size. The actual kernel size is ((size * 2) + 1) * ((size * 2) + 1). Use 1(3x3 kernel), 2(5x5 kernel).
    **threshold**: If true, which will enable adaptive thresholding of the image which sets pixels to white or black based on a pixel’s brightness in relation to the brightness of the kernel of pixels around them.
    default is false.
    **offset**: The larger the offset value, the lower brightness pixels on the original image will be set to white. default is 0.
    **invert**: If true, the image will be inverted before the operation. default is false.
    **mask**: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.
    Only pixels set in the mask are modified. default is None.
    **return** Returns the image after the operation is completed. **static** False > C++ defination code: > ```cpp > image::Image *mean(int size, bool threshold false, int offset 0, bool invert false, image::Image *mask nullptr) > ``` #### median {#median} Runs the median filter on the image. The median filter is the best filter for smoothing surfaces while preserving edges but it is very slow. item description **type** func **param** **size**: Kernel size. The actual kernel size is ((size * 2) + 1) * ((size * 2) + 1). Use 1(3x3 kernel), 2(5x5 kernel).
    **percentile**: This parameter controls the percentile of the value used in the kernel. You can set this to 0 for a min filter, 0.25 for a lower quartile filter, 0.75 for an upper quartile filter, and 1.0 for a max filter. default is 0.5.
    **threshold**: If true, which will enable adaptive thresholding of the image which sets pixels to white or black based on a pixel’s brightness in relation to the brightness of the kernel of pixels around them.
    default is false.
    **offset**: The larger the offset value, the lower brightness pixels on the original image will be set to white. default is 0.
    **invert**: If true, the image will be inverted before the operation. default is false.
    **mask**: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.
    Only pixels set in the mask are modified. default is None.
    **return** Returns the image after the operation is completed. **static** False > C++ defination code: > ```cpp > image::Image *median(int size, double percentile 0.5, bool threshold false, int offset 0, bool invert false, image::Image *mask nullptr) > ``` #### mode {#mode} Runs the mode filter on the image by replacing each pixel with the mode of their neighbors. item description **type** func **param** **size**: Kernel size. The actual kernel size is ((size * 2) + 1) * ((size * 2) + 1). Use 1(3x3 kernel), 2(5x5 kernel).
    **threshold**: If true, which will enable adaptive thresholding of the image which sets pixels to white or black based on a pixel’s brightness in relation to the brightness of the kernel of pixels around them.
    default is false.
    **offset**: The larger the offset value, the lower brightness pixels on the original image will be set to white. default is 0.
    **invert**: If true, the image will be inverted before the operation. default is false.
    **mask**: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.
    Only pixels set in the mask are modified. default is None.
    **return** Returns the image after the operation is completed. **static** False > C++ defination code: > ```cpp > image::Image *mode(int size, bool threshold false, int offset 0, bool invert false, image::Image *mask nullptr) > ``` #### midpoint {#midpoint} Runs the midpoint filter on the image.This filter finds the midpoint (max * bias + min * (1 bias)) of each pixel neighborhood in the image. item description **type** func **param** **size**: Kernel size. The actual kernel size is ((size * 2) + 1) * ((size * 2) + 1). Use 1(3x3 kernel), 2(5x5 kernel).
    **bias**: The bias of the midpoint. default is 0.5.
    **threshold**: If true, which will enable adaptive thresholding of the image which sets pixels to white or black based on a pixel’s brightness in relation to the brightness of the kernel of pixels around them.
    default is false.
    **offset**: The larger the offset value, the lower brightness pixels on the original image will be set to white. default is 0.
    **invert**: If true, the image will be inverted before the operation. default is false.
    **mask**: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.
    Only pixels set in the mask are modified. default is None.
    **return** Returns the image after the operation is completed. **static** False > C++ defination code: > ```cpp > image::Image *midpoint(int size, double bias 0.5, bool threshold false, int offset 0, bool invert false, image::Image *mask nullptr) > ``` #### morph {#morph} Convolves the image by a filter kernel. This allows you to do general purpose convolutions on an image. item description **type** func **param** **size**: Kernel size. The actual kernel size is ((size * 2) + 1) * ((size * 2) + 1). Use 1(3x3 kernel), 2(5x5 kernel).
    **kernel**: The kernel used for convolution. The kernel should be a list of lists of numbers. The kernel should be the same size as the actual kernel size.
    **mul**: This parameter is used to multiply the convolved pixel results. default is auto.
    **add**: This parameter is the value to be added to each convolution pixel result. default is 0.0.
    **threshold**: If true, which will enable adaptive thresholding of the image which sets pixels to white or black based on a pixel’s brightness in relation to the brightness of the kernel of pixels around them.
    default is false.
    **offset**: The larger the offset value, the lower brightness pixels on the original image will be set to white. default is 0.
    **invert**: If true, the image will be inverted before the operation. default is false.
    **mask**: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.
    Only pixels set in the mask are modified. default is None.
    **return** Returns the image after the operation is completed. **static** False > C++ defination code: > ```cpp > image::Image *morph(int size, std::vector kernel, float mul 1, float add 0.0, bool threshold false, int offset 0, bool invert false, image::Image *mask nullptr) > ``` #### gaussian {#gaussian} Convolves the image by a smoothing guassian kernel. item description **type** func **param** **size**: Kernel size. The actual kernel size is ((size * 2) + 1) * ((size * 2) + 1). Use 1(3x3 kernel), 2(5x5 kernel).
    **unsharp**: If true, this method will perform an unsharp mask operation instead of gaussian filtering operation, this improves the clarity of image edges. default is false.
    **mul**: This parameter is used to multiply the convolved pixel results. default is auto.
    **add**: This parameter is the value to be added to each convolution pixel result. default is 0.0.
    **threshold**: If true, which will enable adaptive thresholding of the image which sets pixels to white or black based on a pixel’s brightness in relation to the brightness of the kernel of pixels around them.
    default is false.
    **offset**: The larger the offset value, the lower brightness pixels on the original image will be set to white. default is 0.
    **invert**: If true, the image will be inverted before the operation. default is false.
    **mask**: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.
    Only pixels set in the mask are modified. default is None.
    **return** Returns the image after the operation is completed. **static** False > C++ defination code: > ```cpp > image::Image *gaussian(int size, bool unsharp false, float mul 1, float add 0.0, bool threshold false, int offset 0, bool invert false, image::Image *mask nullptr) > ``` #### laplacian {#laplacian} Convolves the image by a edge detecting laplacian kernel. item description **type** func **param** **size**: Kernel size. The actual kernel size is ((size * 2) + 1) * ((size * 2) + 1). Use 1(3x3 kernel), 2(5x5 kernel).
    **sharpen**: If True, this method will sharpen the image instead of an unthresholded edge detection image. Then increase the kernel size to improve image clarity. default is false.
    **mul**: This parameter is used to multiply the convolved pixel results. default is auto.
    **add**: This parameter is the value to be added to each convolution pixel result. default is 0.0.
    **threshold**: If true, which will enable adaptive thresholding of the image which sets pixels to white or black based on a pixel’s brightness in relation to the brightness of the kernel of pixels around them.
    default is false.
    **offset**: The larger the offset value, the lower brightness pixels on the original image will be set to white. default is 0.
    **invert**: If true, the image will be inverted before the operation. default is false.
    **mask**: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.
    Only pixels set in the mask are modified. default is None.
    **return** Returns the image after the operation is completed. **static** False > C++ defination code: > ```cpp > image::Image *laplacian(int size, bool sharpen false, float mul 1, float add 0.0, bool threshold false, int offset 0, bool invert false, image::Image *mask nullptr) > ``` #### bilateral {#bilateral} Convolves the image by a bilateral filter. item description **type** func **param** **size**: Kernel size. The actual kernel size is ((size * 2) + 1) * ((size * 2) + 1). Use 1(3x3 kernel), 2(5x5 kernel).
    **color_sigma**: Controls how closely colors are matched using the bilateral filter. default is 0.1.
    **space_sigma**: Controls how closely pixels space wise are blurred with each other. default is 1.
    **threshold**: If true, which will enable adaptive thresholding of the image which sets pixels to white or black based on a pixel’s brightness in relation to the brightness of the kernel of pixels around them.
    default is false.
    **offset**: The larger the offset value, the lower brightness pixels on the original image will be set to white. default is 0.
    **invert**: If true, the image will be inverted before the operation. default is false.
    **mask**: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.
    Only pixels set in the mask are modified. default is None.
    **return** Returns the image after the operation is completed. **static** False > C++ defination code: > ```cpp > image::Image *bilateral(int size, double color_sigma 0.1, double space_sigma 1, bool threshold false, int offset 0, bool invert false, image::Image *mask nullptr) > ``` #### linpolar {#linpolar} Re project’s and image from cartessian coordinates to linear polar coordinates. item description **type** func **param** **reverse**: If true, the image will be reverse polar transformed. default is false.
    **return** Returns the image after the operation is completed. **static** False > C++ defination code: > ```cpp > image::Image *linpolar(bool reverse false) > ``` #### logpolar {#logpolar} Re project’s and image from cartessian coordinates to log polar coordinates. item description **type** func **param** **reverse**: If true, the image will be reverse polar transformed. default is false.
    **return** Returns the image after the operation is completed. **static** False > C++ defination code: > ```cpp > image::Image *logpolar(bool reverse false) > ``` #### lens\\_corr {#lens\\_corr} Performs a lens correction operation on the image. TODO: support in the feature item description **type** func **param** **strength**: The strength of the lens correction. default is 1.8.
    **zoom**: The zoom of the lens correction. default is 1.0.
    **x_corr**: The x correction of the lens correction. default is 0.0.
    **y_corr**: The y correction of the lens correction. default is 0.0.
    **return** Returns the image after the operation is completed. **static** False > C++ defination code: > ```cpp > image::Image *lens_corr(double strength 1.8, double zoom 1.0, double x_corr 0.0, double y_corr 0.0) > ``` #### rotation\\_corr {#rotation\\_corr} Performs a rotation correction operation on the image. TODO: support in the feature item description **type** func **param** **x_rotation**: The x rotation of the rotation correction. default is 0.0.
    **y_rotation**: The y rotation of the rotation correction. default is 0.0.
    **z_rotation**: The z rotation of the rotation correction. default is 0.0.
    **x_translation**: The x translation of the rotation correction. default is 0.0.
    **y_translation**: The y translation of the rotation correction. default is 0.0.
    **zoom**: The zoom of the rotation correction. default is 1.0.
    **fov**: The fov of the rotation correction. default is 60.0.
    **corners**: The corners of the rotation correction. default is None.
    **return** Returns the image after the operation is completed. **static** False > C++ defination code: > ```cpp > image::Image *rotation_corr(double x_rotation 0.0, double y_rotation 0.0, double z_rotation 0.0, double x_translation 0.0, double y_translation 0.0, double zoom 1.0, double fov 60.0, std::vector corners std::vector()) > ``` #### get\\_histogram {#get\\_histogram} Computes the normalized histogram on all color channels and returns a image::Histogram object. item description **type** func **note** For GRAYSCALE format, Lmin and Lmax range is [0, 255]. For RGB888 format, Lmin and Lmax range is [0, 100]. **param** **thresholds**: You can define multiple thresholds.
    For GRAYSCALE format, you can use {{Lmin, Lmax}, ...} to define one or more thresholds.
    For RGB888 format, you can use {{Lmin, Lmax, Amin, Amax, Bmin, Bmax}, ...} to define one or more thresholds.
    Where the upper case L,A,B represent the L,A,B channels of the LAB image format, and min, max represent the minimum and maximum values of the corresponding channels.
    **invert**: If true, the thresholds will be inverted before the operation. default is false.
    **roi**: The region of interest, input in the format of (x, y, w, h), x and y are the coordinates of the upper left corner, w and h are the width and height of roi.
    default is None, means whole image.
    **bins**: The number of bins to use for the histogram.
    In GRAYSCALE format, setting range is [2, 256], default is 100.
    In RGB888 format, setting range is [2, 100], default is 100.
    **l_bins**: The number of bins to use for the l channel of the histogram. Only valid in RGB888 format.
    If an invalid value is set, bins will be used instead. The setting range is [2, 100], default is 100.
    **a_bins**: The number of bins to use for the a channel of the histogram.
    Only valid in RGB888 format.The setting range is [2, 256], default is 256.
    **b_bins**: The number of bins to use for the b channel of the histogram.
    Only valid in RGB888 format. The setting range is [2, 256], default is 256.
    **difference**: difference may be set to an image object to cause this method to operate on the difference image between the current image and the difference image object.
    default is None.
    **return** Returns image::Histogram object **static** False > C++ defination code: > ```cpp > image::Histogram get_histogram(std::vector> thresholds std::vector>(), bool invert false, std::vector roi std::vector(), int bins 1, int l_bins 100, int a_bins 256, int b_bins 256, image::Image *difference nullptr) > ``` #### get\\_statistics {#get\\_statistics 2} Gets the statistics of the image. TODO: support in the feature item description **type** func **note** For GRAYSCALE format, Lmin and Lmax range is [0, 255]. For RGB888 format, Lmin and Lmax range is [0, 100]. **param** **thresholds**: You can define multiple thresholds.
    For GRAYSCALE format, you can use {{Lmin, Lmax}, ...} to define one or more thresholds.
    For RGB888 format, you can use {{Lmin, Lmax, Amin, Amax, Bmin, Bmax}, ...} to define one or more thresholds.
    Where the upper case L,A,B represent the L,A,B channels of the LAB image format, and min, max represent the minimum and maximum values of the corresponding channels.
    **invert**: If true, the image will be inverted before the operation. default is false.
    **roi**: The region of interest, input in the format of (x, y, w, h), x and y are the coordinates of the upper left corner, w and h are the width and height of roi.
    default is None, means whole image.
    **bins**: The number of bins to use for the statistics. default is 1.
    **l_bins**: The number of bins to use for the l channel of the statistics. default is 1.
    **a_bins**: The number of bins to use for the a channel of the statistics. default is 1.
    **b_bins**: The number of bins to use for the b channel of the statistics. default is 1.
    **difference**: The difference image to use for the statistics. default is None.
    **return** Returns the statistics of the image **static** False > C++ defination code: > ```cpp > image::Statistics get_statistics(std::vector> thresholds std::vector>(), bool invert false, std::vector roi std::vector(), int bins 1, int l_bins 1, int a_bins 1, int b_bins 1, image::Image *difference nullptr) > ``` #### get\\_regression {#get\\_regression} Gets the regression of the image. item description **type** func **note** For GRAYSCALE format, Lmin and Lmax range is [0, 255]. For RGB888 format, Lmin and Lmax range is [0, 100]. **param** **thresholds**: You can define multiple thresholds.
    For GRAYSCALE format, you can use {{Lmin, Lmax}, ...} to define one or more thresholds.
    For RGB888 format, you can use {{Lmin, Lmax, Amin, Amax, Bmin, Bmax}, ...} to define one or more thresholds.
    Where the upper case L,A,B represent the L,A,B channels of the LAB image format, and min, max represent the minimum and maximum values of the corresponding channels.
    **invert**: If true, the image will be inverted before the operation. default is false.
    **roi**: The region of interest, input in the format of (x, y, w, h), x and y are the coordinates of the upper left corner, w and h are the width and height of roi.
    default is None, means whole image.
    **x_stride**: The x stride to use for the regression. default is 2.
    **y_stride**: The y stride to use for the regression. default is 1.
    **area_threshold**: The area threshold to use for the regression. default is 10.
    **pixels_threshold**: The pixels threshold to use for the regression. default is 10.
    **robust**: If true, the regression will be robust. default is false.
    **return** Returns the regression of the image **static** False > C++ defination code: > ```cpp > std::vector get_regression(std::vector> thresholds std::vector>(), bool invert false, std::vector roi std::vector(), int x_stride 2, int y_stride 1, int area_threshold 10, int pixels_threshold 10, bool robust false) > ``` #### save {#save} Save image to file item description **type** func **param** **path**: file path
    **quality**: image quality, by default(value is 95), support jpeg and png format
    **return** error code, err::ERR_NONE is ok, other is error **static** False > C++ defination code: > ```cpp > err::Err save(const char *path, int quality 95) > ``` #### flood\\_fill {#flood\\_fill} Flood fills a region of the image starting from location x, y. item description **type** func **param** **x**: The x coordinate of the seed point.
    **y**: The y coordinate of the seed point.
    **seed_threshold**: The seed_threshold value controls how different any pixel in the fill area may be from the original starting pixel. default is 0.05.
    **floating_threshold**: The floating_threshold value controls how different any pixel in the fill area may be from any neighbor pixels. default is 0.05.
    **color**: The color to fill the region with. default is white.
    **invert**: If true, the image will be inverted before the operation. default is false.
    **clear_background**: If true, the background will be cleared before the operation. default is false.
    **mask**: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.
    Only pixels set in the mask are modified. default is None. FIXME: the mask image works abnormally
    **return** Returns the image after the operation is completed. **static** False > C++ defination code: > ```cpp > image::Image *flood_fill(int x, int y, float seed_threshold 0.05, float floating_threshold 0.05, image::Color color image::COLOR_WHITE, bool invert false, bool clear_background false, image::Image *mask nullptr) > ``` #### erode {#erode} Erodes the image in place. item description **type** func **param** **size**: Kernel size. The actual kernel size is ((size * 2) + 1) * ((size * 2) + 1). Use 1(3x3 kernel), 2(5x5 kernel).
    **threshold**: The number of pixels in the kernel that are not 0. If it is less than or equal to the threshold, set the center pixel to black. default is (kernel_size 1).
    **mask**: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.
    Only pixels set in the mask are modified. default is None.
    **return** Returns the image after the operation is completed. **static** False > C++ defination code: > ```cpp > image::Image *erode(int size, int threshold 1, image::Image *mask nullptr) > ``` #### dilate {#dilate} Dilates the image in place. item description **type** func **param** **size**: Kernel size. The actual kernel size is ((size * 2) + 1) * ((size * 2) + 1). Use 1(3x3 kernel), 2(5x5 kernel).
    **threshold**: The number of pixels in the kernel that are not 0. If it is greater than or equal to the threshold, set the center pixel to white. default is 0.
    **mask**: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.
    Only pixels set in the mask are modified. default is None.
    **return** Returns the image after the operation is completed. **static** False > C++ defination code: > ```cpp > image::Image *dilate(int size, int threshold 0, image::Image *mask nullptr) > ``` #### open {#open} Performs erosion and dilation on an image in order. item description **type** func **param** **size**: Kernel size. The actual kernel size is ((size * 2) + 1) * ((size * 2) + 1). Use 1(3x3 kernel), 2(5x5 kernel).
    **threshold**: As the threshold for erosion and dilation, the actual threshold for erosion is (kernel_size 1 threshold), the actual threshold for dialation is threshold. default is 0.
    **mask**: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.
    Only pixels set in the mask are modified. default is None.
    **return** Returns the image after the operation is completed. **static** False > C++ defination code: > ```cpp > image::Image *open(int size, int threshold 0, image::Image *mask nullptr) > ``` #### close {#close} Performs dilation and erosion on an image in order. item description **type** func **param** **size**: Kernel size. The actual kernel size is ((size * 2) + 1) * ((size * 2) + 1). Use 1(3x3 kernel), 2(5x5 kernel).
    **threshold**: As the threshold for erosion and dilation, the actual threshold for erosion is (kernel_size 1 threshold), the actual threshold for dialation is threshold. default is 0.
    **mask**: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.
    Only pixels set in the mask are modified. default is None.
    **return** Returns the image after the operation is completed. **static** False > C++ defination code: > ```cpp > image::Image *close(int size, int threshold 0, image::Image *mask nullptr) > ``` #### top\\_hat {#top\\_hat} Returns the image difference of the image and Image.open()’ed image. item description **type** func **param** **size**: Kernel size. The actual kernel size is ((size * 2) + 1) * ((size * 2) + 1). Use 1(3x3 kernel), 2(5x5 kernel).
    **threshold**: As the threshold for open method. default is 0.
    **mask**: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.
    Only pixels set in the mask are modified. default is None.
    **return** Returns the image after the operation is completed. **static** False > C++ defination code: > ```cpp > image::Image *top_hat(int size, int threshold 0, image::Image *mask nullptr) > ``` #### black\\_hat {#black\\_hat} Returns the image difference of the image and Image.close()’ed image. item description **type** func **param** **size**: Kernel size. The actual kernel size is ((size * 2) + 1) * ((size * 2) + 1). Use 1(3x3 kernel), 2(5x5 kernel).
    **threshold**: As the threshold for close method. default is 0.
    **mask**: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.
    Only pixels set in the mask are modified. default is None.
    **return** Returns the image after the operation is completed. **static** False > C++ defination code: > ```cpp > image::Image *black_hat(int size, int threshold 0, image::Image *mask nullptr) > ``` #### find\\_blobs {#find\\_blobs} Finds all blobs in the image and returns a list of image.Blob class which describe each Blob.\\nPlease see the image.Blob object more more information. item description **type** func **note** For GRAYSCALE format, Lmin and Lmax range is [0, 255]. For RGB888 format, Lmin and Lmax range is [0, 100]. **param** **thresholds**: You can define multiple thresholds.
    For GRAYSCALE format, you can use {{Lmin, Lmax}, ...} to define one or more thresholds.
    For RGB888 format, you can use {{Lmin, Lmax, Amin, Amax, Bmin, Bmax}, ...} to define one or more thresholds.
    Where the upper case L,A,B represent the L,A,B channels of the LAB image format, and min, max represent the minimum and maximum values of the corresponding channels.
    **invert**: if true, will invert thresholds before find blobs, default is false
    **roi**: The region of interest, input in the format of (x, y, w, h), x and y are the coordinates of the upper left corner, w and h are the width and height of roi.
    default is None, means whole image.
    **x_stride**: x stride is the number of x pixels to skip when doing the hough transform. default is 2
    **y_stride**: y_stride is the number of y pixels to skip when doing the hough transform. default is 1
    **area_threshold**: area threshold, if the blob area is smaller than area_threshold, the blob is not returned, default is 10
    **pixels_threshold**: pixels threshold, if the blob pixels is smaller than area_threshold, the blob is not returned,, default is 10.
    when x_stride and y_stride is equal to 1, pixels_threshold is equivalent to area_threshold
    **merge**: if True merges all not filtered out blobs whos bounding rectangles intersect each other. default is false
    **margin**: margin can be used to increase or decrease the size of the bounding rectangles for blobs during the intersection test.
    For example, with a margin of 1 blobs whos bounding rectangles are 1 pixel away from each other will be merged. default is 0
    **x_hist_bins_max**: if set to non zero populates a histogram buffer in each blob object with an x_histogram projection of all columns in the object. This value then sets the number of bins for that projection.
    **y_hist_bins_max**: if set to non zero populates a histogram buffer in each blob object with an y_histogram projection of all rows in the object. This value then sets the number of bins for that projection.
    **return** Return the blob when found blobs, format is (blob1, blob2, ...), you can use blob class methods to do more operations. **static** False > C++ defination code: > ```cpp > std::vector find_blobs(std::vector> thresholds std::vector>(), bool invert false, std::vector roi std::vector(), int x_stride 2, int y_stride 1, int area_threshold 10, int pixels_threshold 10, bool merge false, int margin 0, int x_hist_bins_max 0, int y_hist_bins_max 0) > ``` #### find\\_lines {#find\\_lines} Find lines in image item description **type** func **param** **roi**: The region of interest, input in the format of (x, y, w, h), x and y are the coordinates of the upper left corner, w and h are the width and height of roi.
    default is None, means whole image.
    **x_stride**: x stride is the number of x pixels to skip when doing the hough transform. default is 2
    **y_stride**: y_stride is the number of y pixels to skip when doing the hough transform. default is 1
    **threshold**: threshold threshold controls what lines are detected from the hough transform. Only lines with a magnitude greater than or equal to threshold are returned.
    The right value of threshold for your application is image dependent. default is 1000.
    **theta_margin**: theta_margin controls the merging of detected lines. default is 25.
    **rho_margin**: rho_margin controls the merging of detected lines. default is 25.
    **return** Return the line when found lines, format is (line1, line2, ...), you can use line class methods to do more operations **static** False > C++ defination code: > ```cpp > std::vector find_lines(std::vector roi std::vector(), int x_stride 2, int y_stride 1, double threshold 1000, double theta_margin 25, double rho_margin 25) > ``` #### find\\_line\\_segments {#find\\_line\\_segments} Finds all line segments in the image. item description **type** func **param** **roi**: The region of interest, input in the format of (x, y, w, h), x and y are the coordinates of the upper left corner, w and h are the width and height of roi.
    default is None, means whole image.
    **merge_distance**: The maximum distance between two lines to merge them. default is 0.
    **max_theta_difference**: The maximum difference between two lines to merge them. default is 15.
    **return** Return the line when found lines, format is (line1, line2, ...), you can use line class methods to do more operations **static** False > C++ defination code: > ```cpp > std::vector find_line_segments(std::vector roi std::vector(), int merge_distance 0, int max_theta_difference 15) > ``` #### search\\_line\\_path {#search\\_line\\_path} Search the path of line item description **type** func **param** **thresholds**: You can define multiple thresholds.
    For GRAYSCALE format, you can use {{Lmin, Lmax}, ...} to define one or more thresholds.
    For RGB888 format, you can use {{Lmin, Lmax, Amin, Amax, Bmin, Bmax}, ...} to define one or more thresholds.
    Where the upper case L,A,B represent the L,A,B channels of the LAB image format, and min, max represent the minimum and maximum values of the corresponding channels.
    **detect_pixel_size**: Before finding the path, the screen is divided into several smaller blocks, each with a width and height of detect_pixel_size. The smaller the detect_pixel_size, the finer the division. the unit is pixels.
    **point_merge_size**: Minimum distance between merged point sets. the unit is pixels.
    **connection_max_size**: Minimum size allowed for connecting points to form a line. the unit is pixels.
    **connection_max_distance**: Minimum distance allowed for point to line. the unit is pixels.
    **connection_max_angle**: Minimum angle allowed for connecting points to form a line.
    **return** Return the line when found lines, format is (groupline1, groupline2, ...), you can use LineGroup class methods to do more operations **static** False > C++ defination code: > ```cpp > std::vector search_line_path(std::vector> thresholds std::vector>(), int detect_pixel_size 30, int point_merge_size 15, int connection_max_size 51, int connection_max_distance 20, int connection_max_angle 20) > ``` #### find\\_circles {#find\\_circles} Find circles in image item description **type** func **param** **roi**: The region of interest, input in the format of (x, y, w, h), x and y are the coordinates of the upper left corner, w and h are the width and height of roi.
    default is None, means whole image.
    **x_stride**: x stride is the number of x pixels to skip when doing the hough transform. default is 2
    **y_stride**: y_stride is the number of y pixels to skip when doing the hough transform. default is 1
    **threshold**: threshold controls what circles are detected from the hough transform. Only circles with a magnitude greater than or equal to threshold are returned.
    The right value of threshold for your application is image dependent.
    **x_margin**: x_margin controls the merging of detected circles. Circles which are x_margin, y_margin, and r_margin pixels apart are merged. default is 10
    **y_margin**: y_margin controls the merging of detected circles. Circles which are x_margin, y_margin, and r_margin pixels apart are merged. default is 10
    **r_margin**: r_margin controls the merging of detected circles. Circles which are x_margin, y_margin, and r_margin pixels apart are merged. default is 10
    **r_min**: r_min controls the minimum circle radius detected. Increase this to speed up the algorithm. default is 2
    **r_max**: r_max controls the maximum circle radius detected. Decrease this to speed up the algorithm. default is min(roi.w / 2, roi.h / 2)
    **r_step**: r_step controls how to step the radius detection by. default is 2.
    **return** Return the circle when found circles, format is (circle1, circle2, ...), you can use circle class methods to do more operations **static** False > C++ defination code: > ```cpp > std::vector find_circles(std::vector roi std::vector(), int x_stride 2, int y_stride 1, int threshold 2000, int x_margin 10, int y_margin 10, int r_margin 10, int r_min 2, int r_max 1, int r_step 2) > ``` #### find\\_rects {#find\\_rects} Finds all rects in the image. item description **type** func **param** **roi**: The region of interest, input in the format of (x, y, w, h), x and y are the coordinates of the upper left corner, w and h are the width and height of roi.
    default is None, means whole image.
    **threshold**: The threshold to use for the rects. default is 10000.
    **return** Returns the rects of the image **static** False > C++ defination code: > ```cpp > std::vector find_rects(std::vector roi std::vector(), int threshold 10000) > ``` #### find\\_qrcodes {#find\\_qrcodes} Finds all qrcodes in the image. item description **type** func **param** **roi**: The region of interest, input in the format of (x, y, w, h), x and y are the coordinates of the upper left corner, w and h are the width and height of roi.
    default is None, means whole image.
    **decoder_type**: Select the QR code decoding method. Choosing QRCODE_DECODER_TYPE_QUIRC allows for retrieving QR code version, ECC level, mask, data type, and other details,
    though it may decode slower at lower resolutions. Opting for QRCODE_DECODER_TYPE_ZBAR enables faster decoding at lower resolutions but may slow down at higher resolutions,
    providing only the QR code content and position information. default is QRCODE_DECODER_TYPE_ZBAR.
    **return** Returns the qrcodes of the image **static** False > C++ defination code: > ```cpp > std::vector find_qrcodes(std::vector roi std::vector(), image::QRCodeDecoderType decoder_type image::QRCodeDecoderType::QRCODE_DECODER_TYPE_ZBAR) > ``` #### find\\_apriltags {#find\\_apriltags} Finds all apriltags in the image. item description **type** func **param** **roi**: The region of interest, input in the format of (x, y, w, h), x and y are the coordinates of the upper left corner, w and h are the width and height of roi.
    default is None, means whole image.
    **families**: The families to use for the apriltags. default is TAG36H11.
    **fx**: The camera X focal length in pixels, default is 1.
    **fy**: The camera Y focal length in pixels, default is 1.
    **cx**: The camera X center in pixels, default is image.width / 2.
    **cy**: The camera Y center in pixels, default is image.height / 2.
    **return** Returns the apriltags of the image **static** False > C++ defination code: > ```cpp > std::vector find_apriltags(std::vector roi std::vector(), image::ApriltagFamilies families image::ApriltagFamilies::TAG36H11, float fx 1, float fy 1, int cx 1, int cy 1) > ``` #### find\\_datamatrices {#find\\_datamatrices} Finds all datamatrices in the image. item description **type** func **param** **roi**: The region of interest, input in the format of (x, y, w, h), x and y are the coordinates of the upper left corner, w and h are the width and height of roi.
    default is None, means whole image.
    **effort**: Controls how much time to spend trying to find data matrix matches. default is 200.
    **return** Returns the datamatrices of the image **static** False > C++ defination code: > ```cpp > std::vector find_datamatrices(std::vector roi std::vector(), int effort 200) > ``` #### find\\_barcodes {#find\\_barcodes} Finds all barcodes in the image. item description **type** func **param** **roi**: The region of interest, input in the format of (x, y, w, h), x and y are the coordinates of the upper left corner, w and h are the width and height of roi.
    default is None, means whole image.
    **return** Returns the barcodes of the image **static** False > C++ defination code: > ```cpp > std::vector find_barcodes(std::vector roi std::vector()) > ``` #### find\\_displacement {#find\\_displacement} Finds the displacement between the image and the template. TODO: support in the feature\\nnote: this method must be used on power of 2 image sizes item description **type** func **param** **template_image**: The template image.
    **roi**: The region of interest, input in the format of (x, y, w, h), x and y are the coordinates of the upper left corner, w and h are the width and height of roi.
    default is None, means whole image.
    **template_roi**: The region of interest rectangle (x, y, w, h) to work in. If not specified, it is equal to the image rectangle.
    **logpolar**: If true, it will instead find rotation and scale changes between the two images. default is false.
    **return** Returns the displacement of the image **static** False > C++ defination code: > ```cpp > image::Displacement find_displacement(image::Image &template_image, std::vector roi std::vector(), std::vector template_roi std::vector(), bool logpolar false) > ``` #### find\\_template {#find\\_template} Finds the template in the image. item description **type** func **param** **template_image**: The template image.
    **threshold**: Threshold is floating point number (0.0 1.0) where a higher threshold prevents false positives while lowering the detection rate while a lower threshold does the opposite.
    **roi**: The region of interest, input in the format of (x, y, w, h), x and y are the coordinates of the upper left corner, w and h are the width and height of roi.
    default is None, means whole image. Only valid in SEARCH_EX mode.
    **step**: The step size to use for the template. default is 2. Only valid in SEARCH_EX mode
    **search**: The search method to use for the template. default is SEARCH_EX.
    **return** Returns a bounding box tuple (x, y, w, h) for the matching location otherwise None. **static** False > C++ defination code: > ```cpp > std::vector find_template(image::Image &template_image, float threshold, std::vector roi std::vector(), int step 2, image::TemplateMatch search image::TemplateMatch::SEARCH_EX) > ``` #### find\\_features {#find\\_features} Finds the features in the image. TODO: support in the feature item description **type** func **param** **cascade**: The cascade to use for the features. default is CASCADE_FRONTALFACE_ALT.
    **threshold**: The threshold to use for the features. default is 0.5.
    **scale**: The scale to use for the features. default is 1.5.
    **roi**: The region of interest, input in the format of (x, y, w, h), x and y are the coordinates of the upper left corner, w and h are the width and height of roi.
    default is None, means whole image.
    **return** Returns the features of the image **static** False > C++ defination code: > ```cpp > std::vector find_features(int cascade, float threshold 0.5, float scale 1.5, std::vector roi std::vector()) > ``` #### find\\_lbp {#find\\_lbp} Finds the lbp in the image. TODO: support in the feature. item description **type** func **param** **roi**: The region of interest, input in the format of (x, y, w, h), x and y are the coordinates of the upper left corner, w and h are the width and height of roi.
    default is None, means whole image.
    **return** Returns the lbp of the image **static** False > C++ defination code: > ```cpp > image::LBPKeyPoint find_lbp(std::vector roi std::vector()) > ``` #### find\\_keypoints {#find\\_keypoints} Finds the keypoints in the image. TODO: support in the feature. item description **type** func **param** **roi**: The region of interest, input in the format of (x, y, w, h), x and y are the coordinates of the upper left corner, w and h are the width and height of roi.
    default is None, means whole image.
    **threshold**: The threshold to use for the keypoints. default is 20.
    **normalized**: If true, the image will be normalized before the operation. default is false.
    **scale_factor**: The scale factor to use for the keypoints. default is 1.5.
    **max_keypoints**: The maximum number of keypoints to use for the keypoints. default is 100.
    **corner_detector**: The corner detector to use for the keypoints. default is CORNER_AGAST.
    **return** Returns the keypoints of the image **static** False > C++ defination code: > ```cpp > image::ORBKeyPoint find_keypoints(std::vector roi std::vector(), int threshold 20, bool normalized false, float scale_factor 1.5, int max_keypoints 100, image::CornerDetector corner_detector image::CornerDetector::CORNER_AGAST) > ``` #### find\\_edges {#find\\_edges} Finds the edges in the image. item description **type** func **param** **edge_type**: The edge type to use for the edges. default is EDGE_CANNY.
    **roi**: The region of interest, input in the format of (x, y, w, h), x and y are the coordinates of the upper left corner, w and h are the width and height of roi.
    default is None, means whole image.
    **threshold**: The threshold to use for the edges. default is 20.
    **return** Returns the edges of the image **static** False > C++ defination code: > ```cpp > image::Image* find_edges(image::EdgeDetector edge_type, std::vector roi std::vector(), std::vector threshold std::vector({100, 200})) > ``` #### find\\_hog {#find\\_hog} Finds the hog in the image. TODO: support in the feature item description **type** func **param** **roi**: The region of interest, input in the format of (x, y, w, h), x and y are the coordinates of the upper left corner, w and h are the width and height of roi.
    default is None, means whole image.
    **size**: The size to use for the hog. default is 8.
    **return** Returns the hog of the image **static** False > C++ defination code: > ```cpp > image::Image* find_hog(std::vector roi std::vector(), int size 8) > ``` #### match\\_lbp\\_descriptor {#match\\_lbp\\_descriptor} Matches the lbp descriptor of the image. TODO: support in the feature item description **type** func **param** **desc1**: The descriptor to use for the match.
    **desc2**: The descriptor to use for the match.
    **return** Returns the match of the image **static** False > C++ defination code: > ```cpp > int match_lbp_descriptor(image::LBPKeyPoint &desc1, image::LBPKeyPoint &desc2) > ``` #### match\\_orb\\_descriptor {#match\\_orb\\_descriptor} Matches the orb descriptor of the image. TODO: support in the feature item description **type** func **param** **desc1**: The descriptor to use for the match.
    **desc2**: The descriptor to use for the match.
    **threshold**: The threshold to use for the match. default is 95.
    **filter_outliers**: If true, the image will be filter_outliers before the operation. default is false.
    **return** Returns the match of the image **static** False > C++ defination code: > ```cpp > image::KPTMatch match_orb_descriptor(image::ORBKeyPoint &desc1, image::ORBKeyPoint &desc2, int threshold 95, bool filter_outliers false) > ``` ### Color {#Color} Color class > C++ defination code: > ```cpp > class Color > ``` #### \\_\\_init\\_\\_ {#\\_\\_init\\_\\_ 21} Color constructor item description **type** func **param** **alpha**: alpha channel, value range: 0 ~ 1
    **static** False > C++ defination code: > ```cpp > Color(uint8_t ch1, uint8_t ch2 0, uint8_t ch3 0, float alpha 0, image::Format format image::FMT_GRAYSCALE) > ``` #### r {#r 2} Color red channel item description **type** var **static** False **readonly** False > C++ defination code: > ```cpp > uint8_t r > ``` #### g {#g} Color green channel item description **type** var **static** False **readonly** False > C++ defination code: > ```cpp > uint8_t g > ``` #### b {#b} Color blue channel item description **type** var **static** False **readonly** False > C++ defination code: > ```cpp > uint8_t b > ``` #### alpha {#alpha} Color alpha channel, value from 0.0 to 1.0, float value item description **type** var **static** False **readonly** False > C++ defination code: > ```cpp > float alpha > ``` #### gray {#gray} Color gray channel item description **type** var **static** False **readonly** False > C++ defination code: > ```cpp > uint8_t gray > ``` #### format {#format 4} Color format item description **type** var **static** False **readonly** False > C++ defination code: > ```cpp > image::Format format > ``` #### hex {#hex} Get color's hex value item description **type** func **static** False > C++ defination code: > ```cpp > uint32_t hex() > ``` #### from\\_rgb {#from\\_rgb} Create Color object from RGB channels item description **type** func **static** True > C++ defination code: > ```cpp > static image::Color from_rgb(uint8_t r, uint8_t g, uint8_t b) > ``` #### from\\_bgr {#from\\_bgr} Create Color object from BGR channels item description **type** func **static** True > C++ defination code: > ```cpp > static image::Color from_bgr(uint8_t b, uint8_t g, uint8_t r) > ``` #### from\\_gray {#from\\_gray} Create Color object from gray channel item description **type** func **static** True > C++ defination code: > ```cpp > static image::Color from_gray(uint8_t gray) > ``` #### from\\_rgba {#from\\_rgba} Create Color object from RGBA channels item description **type** func **param** **alpha**: alpha channel, float value, value range: 0 ~ 1
    **static** True > C++ defination code: > ```cpp > static image::Color from_rgba(uint8_t r, uint8_t g, uint8_t b, float alpha) > ``` #### from\\_bgra {#from\\_bgra} Create Color object from BGRA channels item description **type** func **param** **alpha**: alpha channel, float value, value range: 0 ~ 1
    **static** True > C++ defination code: > ```cpp > static image::Color from_bgra(uint8_t b, uint8_t g, uint8_t r, float alpha) > ``` #### from\\_hex {#from\\_hex} Create Color object from hex value item description **type** func **param** **hex**: hex value, e.g. 0x0000FF00, lower address if first channel
    **format**: color format, @see image::Format
    **static** True > C++ defination code: > ```cpp > static image::Color from_hex(uint32_t hex, image::Format &format) > ``` #### to\\_format {#to\\_format 2} Convert Color format item description **type** func **param** **format**: format want to convert to, @see image::Format, only support RGB888, BGR888, RGBA8888, BGRA8888, GRAYSCALE.
    **static** False > C++ defination code: > ```cpp > void to_format(const image::Format &format) > ``` #### to\\_format2 {#to\\_format2} Convert color format and return a new Color object item description **type** func **param** **format**: format want to convert to, @see image::Format, only support RGB888, BGR888, RGBA8888, BGRA8888, GRAYSCALE.
    **return** new Color object, you need to delete it manually in C++. **static** False > C++ defination code: > ```cpp > image::Color *to_format2(const image::Format &format) > ```"},"/maixcdk/api/maix/display.html":{"title":"maix::display","content":" title: maix::display maix.display module, control display device and show image on it > This is `maix::display` module of [MaixCDK](https://github.com/sipeed/MaixCDK). > All of these elements are in namespace `maix::display`. > > For MaixCDK developer: DO NOT edit this doc file manually, this doc is auto generated! ## Module {#Module} No module ## Enum {#Enum} ## Variable {#Variable} ## Function {#Function} ### send\\_to\\_maixvision {#send\\_to\\_maixvision} Send image to MaixVision work station if connected.\\nIf you want to debug your program an don't want to initialize display, use this method. item description **param** **img**: image to send, image.Image object
    > C++ defination code: > ```cpp > void send_to_maixvision(image::Image &img) > ``` ### set\\_trans\\_image\\_quality {#set\\_trans\\_image\\_quality} Set image transport quality(only for JPEG) item description **param** **quality**: default 95, value from 51 ~ 100
    > C++ defination code: > ```cpp > void set_trans_image_quality(const int value) > ``` ## Class {#Class} ### Display {#Display} Display class > C++ defination code: > ```cpp > class Display > ``` #### Display {#Display 2} Construct a new Display object item description **type** func **param** **width**: display width, by default(value is 1) means auto detect,
    if width > max device supported width, will auto set to max device supported width
    **height**: display height, by default(value is 1) means auto detect,
    if height > max device supported height, will auto set to max device supported height
    **device**: display device name, you can get devices by list_devices method, by default(value is NULL(None in MaixPy)) means the first device
    **open**: If true, display will automatically call open() after creation. default is true.
    **static** False > C++ defination code: > ```cpp > Display(int width 1, int height 1, image::Format format image::FMT_RGB888, const std::string &device \"\", bool open true) > ``` #### Display (overload 1) {#Display (overload 1)} Construct a new Display object. item description **type** func **attention** DisplayBase * parameter need to be set manually, otherwise the operation of this object will be invalid. **param** **device**: display device path, you can get devices by list_devices method, by default(value is NULL(None in MaixPy)) means the first device
    **base**: basic operation objects.
    **width**: display width, default is 1, means auto, mostly means max width of display support
    **height**: display height, default is 1, means auto, mostly means max height of display support
    **format**: display output format
    **open**: If true, display will automatically call open() after creation. default is true.
    **static** False > C++ defination code: > ```cpp > Display(const std::string &device, DisplayBase *base, int width 1, int height 1, image::Format format image::FMT_INVALID, bool open true) > ``` #### width {#width} Get display width item description **type** func **return** width **static** False > C++ defination code: > ```cpp > int width() > ``` #### height {#height} Get display height item description **type** func **param** **ch**: channel to get, by default(value is 0) means the first channel
    **return** height **static** False > C++ defination code: > ```cpp > int height() > ``` #### size {#size} Get display size item description **type** func **param** **ch**: channel to get, by default(value is 0) means the first channel
    **return** size A list type in MaixPy, [width, height] **static** False > C++ defination code: > ```cpp > std::vector size() > ``` #### format {#format} Get display format item description **type** func **return** format **static** False > C++ defination code: > ```cpp > image::Format format() > ``` #### open {#open} open display device, if already opened, will return err.ERR_NONE. item description **type** func **param** **width**: display width, default is 1, means auto, mostly means max width of display support
    **height**: display height, default is 1, means auto, mostly means max height of display support
    **format**: display output format, default is RGB888
    **return** error code **static** False > C++ defination code: > ```cpp > err::Err open(int width 1, int height 1, image::Format format image::FMT_INVALID) > ``` #### close {#close} close display device item description **type** func **return** error code **static** False > C++ defination code: > ```cpp > err::Err close() > ``` #### add\\_channel {#add\\_channel} Add a new channel and return a new Display object, you can use close() to close this channel. item description **type** func **attention** If a new disp channel is created, it is recommended to set fit image::FIT_COVER or fit image::FIT_FILL when running show for the main channel,
    otherwise the display of the new disp channel may be abnormal. **param** **width**: display width, default is 1, means auto, mostly means max width of display support. Maximum width must not exceed the main channel.
    **height**: display height, default is 1, means auto, mostly means max height of display support. Maximum height must not exceed the main channel.
    **format**: display output format, default is FMT_BGRA8888
    **open**: If true, display will automatically call open() after creation. default is true.
    **return** new Display object **static** False > C++ defination code: > ```cpp > display::Display *add_channel(int width 1, int height 1, image::Format format image::FMT_BGRA8888, bool open true) > ``` #### is\\_opened {#is\\_opened} check display device is opened or not item description **type** func **return** opened or not, bool type **static** False > C++ defination code: > ```cpp > bool is_opened() > ``` #### is\\_closed {#is\\_closed} check display device is closed or not item description **type** func **return** closed or not, bool type **static** False > C++ defination code: > ```cpp > bool is_closed() > ``` #### show {#show} show image on display device, and will also send to MaixVision work station if connected. item description **type** func **param** **img**: image to show, image.Image object,
    if the size of image smaller than display size, will show in the center of display;
    if the size of image bigger than display size, will auto resize to display size and keep ratio, fill blank with black color.
    **fit**: image in screen fit mode, by default(value is image.FIT_CONTAIN), @see image.Fit for more details
    e.g. image.FIT_CONTAIN means resize image to fit display size and keep ratio, fill blank with black color.
    **return** error code **static** False > C++ defination code: > ```cpp > err::Err show(image::Image &img, image::Fit fit image::FIT_CONTAIN) > ``` #### device {#device} Get display device path item description **type** func **return** display device path **static** False > C++ defination code: > ```cpp > std::string device() > ``` #### set\\_backlight {#set\\_backlight} Set display backlight item description **type** func **param** **value**: backlight value, float type, range is [0, 100]
    **static** False > C++ defination code: > ```cpp > void set_backlight(float value) > ``` #### get\\_backlight {#get\\_backlight} Get display backlight item description **type** func **return** value backlight value, float type, range is [0, 100] **static** False > C++ defination code: > ```cpp > float get_backlight() > ``` #### set\\_hmirror {#set\\_hmirror} Set display mirror item description **type** func **param** **en**: enable/disable mirror
    **static** False > C++ defination code: > ```cpp > err::Err set_hmirror(bool en) > ``` #### set\\_vflip {#set\\_vflip} Set display flip item description **type** func **param** **en**: enable/disable flip
    **static** False > C++ defination code: > ```cpp > err::Err set_vflip(bool en) > ```"},"/maixcdk/api/maix/protocol.html":{"title":"maix::protocol","content":" title: maix::protocol maix.protocol module > This is `maix::protocol` module of [MaixCDK](https://github.com/sipeed/MaixCDK). > All of these elements are in namespace `maix::protocol`. > > For MaixCDK developer: DO NOT edit this doc file manually, this doc is auto generated! ## Module {#Module} No module ## Enum {#Enum} ### CMD {#CMD} protocol cmd, more doc see MaixCDK document's convention doc item describe **note** max app custom CMD value should < CMD_APP_MAX **values** **CMD_APP_MAX**: 200, max app custom CMD value should < CMD_APP_MAX
    **CMD_SET_REPORT**: set auto upload data mode
    **CMD_APP_LIST**:
    **CMD_START_APP**:
    **CMD_EXIT_APP**:
    **CMD_CUR_APP_INFO**:
    **CMD_APP_INFO**:
    **CMD_KEY**:
    **CMD_TOUCH**:
    > C++ defination code: > ```cpp > enum CMD > { > CMD_APP_MAX 0xC8, // 200, max app custom CMD value should < CMD_APP_MAX > > CMD_SET_REPORT 0xF8, // set auto upload data mode > CMD_APP_LIST 0xF9, > CMD_START_APP 0xFA, > CMD_EXIT_APP 0xFB, > CMD_CUR_APP_INFO 0xFC, > CMD_APP_INFO 0xFD, > CMD_KEY 0xFE, > CMD_TOUCH 0xFF, > } > ``` ### FLAGS {#FLAGS} protocol flags, more doc see MaixCDK document's convention doc item describe **values** **FLAG_REQ**:
    **FLAG_RESP**:
    **FLAG_IS_RESP_MASK**:
    **FLAG_RESP_OK**:
    **FLAG_RESP_ERR**:
    **FLAG_RESP_OK_MASK**:
    **FLAG_REPORT**:
    **FLAG_REPORT_MASK**:
    **FLAG_VERSION_MASK**:
    > C++ defination code: > ```cpp > enum FLAGS > { > FLAG_REQ 0x00, > FLAG_RESP 0x80, > FLAG_IS_RESP_MASK 0x80, > > FLAG_RESP_OK 0x40, > FLAG_RESP_ERR 0x00, > FLAG_RESP_OK_MASK 0x40, > > FLAG_REPORT 0x20, > FLAG_REPORT_MASK 0x20, > > FLAG_VERSION_MASK 0x03 > } > ``` ## Variable {#Variable} ### VERSION {#VERSION} protocol version item description **value** **1** **readonly** True > C++ defination code: > ```cpp > const uint8_t VERSION 1 > ``` ### HEADER {#HEADER} protocol header item description **readonly** False > C++ defination code: > ```cpp > extern uint32_t HEADER > ``` ## Function {#Function} ### crc16\\_IBM {#crc16\\_IBM} CRC16 IBM item description **param** **data**: data
    **len**: data length
    **return** CRC16 IBM value, uint16_t type. > C++ defination code: > ```cpp > uint16_t crc16_IBM(unsigned char *data, size_t len) > ``` ### crc16\\_IBM (overload 1) {#crc16\\_IBM (overload 1)} CRC16 IBM item description **param** **data**: data, bytes type.
    **return** CRC16 IBM value, uint16_t type. > C++ defination code: > ```cpp > uint16_t crc16_IBM(const Bytes *data) > ``` ### encode {#encode} Encode message to buffer item description **param** **out_buff**: output buffer
    **out_buff_len**: output buffer length
    **cmd**: CMD value
    **flags**: FLAGS value, @see maix.protocol.FLAGS
    **body**: message body, can be null
    **body_len**: message body length, can be 0
    **code**: error code, only for error message, that is FLAGS.FLAG_ERR in flags
    **version**: protocol version
    **return** encoded data length, if < 0, means error, and the error code is err.Err > C++ defination code: > ```cpp > int encode(uint8_t *out_buff, int out_buff_len, uint8_t cmd, uint8_t flags, uint8_t *body, int body_len, uint8_t code 0xFF, const uint8_t version VERSION) > ``` ## Class {#Class} ### MSG {#MSG} protocol msg > C++ defination code: > ```cpp > class MSG > ``` #### version {#version 2} protocol version item description **type** var **static** False **readonly** False > C++ defination code: > ```cpp > uint8_t version > ``` #### resp\\_ok {#resp\\_ok} Indicate response message type, true means CMD valid and the CMD processed correctly, (only for response msg) item description **type** var **static** False **readonly** False > C++ defination code: > ```cpp > uint8_t resp_ok > ``` #### has\\_been\\_replied {#has\\_been\\_replied} Flag whether CMD has been processed and responded to CMD sender.\\nE.g. CMD CMD_START_APP will be automatically processed in CommProtocol.get_msg function,\\nso the return msg will set this flag to true. item description **type** var **static** False **readonly** False > C++ defination code: > ```cpp > bool has_been_replied{false} > ``` #### cmd {#cmd 2} CMD value item description **type** var **static** False **readonly** False > C++ defination code: > ```cpp > uint8_t cmd > ``` #### is\\_resp {#is\\_resp} message is response or not, contrast with is_req item description **type** var **static** False **readonly** False > C++ defination code: > ```cpp > bool is_resp > ``` #### body {#body} Message body, read only, use set_body() to update item description **type** var **attention** DO NOT manually change this value **static** False **readonly** False > C++ defination code: > ```cpp > uint8_t *body > ``` #### body\\_len {#body\\_len} Message body length, read only, use set_body() to update item description **type** var **attention** DO NOT manually change this value **static** False **readonly** False > C++ defination code: > ```cpp > int body_len > ``` #### encode\\_resp\\_ok {#encode\\_resp\\_ok} Encode response ok(success) message item description **type** func **param** **buff**: output buffer
    **buff_len**: output buffer length
    **body**: response body, can be null
    **body_len**: response body length, can be 0
    **return** encoded data length, if < 0, means error, and the error code is err.Err **static** False > C++ defination code: > ```cpp > int encode_resp_ok(uint8_t *buff, int buff_len, uint8_t *body nullptr, int body_len 0) > ``` #### encode\\_resp\\_ok (overload 1) {#encode\\_resp\\_ok (overload 1)} Encode response ok(success) message item description **type** func **param** **body**: response body, can be null
    **return** encoded data, if nullptr, means error, and the error code is err.Err **static** False > C++ defination code: > ```cpp > Bytes *encode_resp_ok(uint8_t *body nullptr, int body_len 0) > ``` #### encode\\_resp\\_ok (overload 2) {#encode\\_resp\\_ok (overload 2)} Encode response ok(success) message item description **type** func **param** **body**: response body, can be null
    **return** encoded data, if nullptr, means error, and the error code is err.Err **static** False > C++ defination code: > ```cpp > Bytes *encode_resp_ok(Bytes *body nullptr) > ``` #### encode\\_report {#encode\\_report} Encode proactively report message item description **type** func **param** **buff**: output buffer
    **buff_len**: output buffer length
    **body**: report body, can be null
    **body_len**: report body length, can be 0
    **return** encoded data length, if < 0, means error, and the error code is err.Err **static** False > C++ defination code: > ```cpp > int encode_report(uint8_t *buff, int buff_len, uint8_t *body nullptr, int body_len 0) > ``` #### encode\\_report (overload 1) {#encode\\_report (overload 1)} Encode proactively report message item description **type** func **param** **body**: report body, can be null
    **return** encoded data, if nullptr, means error, and the error code is err.Err **static** False > C++ defination code: > ```cpp > Bytes *encode_report(uint8_t *body nullptr, int body_len 0) > ``` #### encode\\_report (overload 2) {#encode\\_report (overload 2)} Encode proactively report message item description **type** func **param** **body**: report body, can be null
    **return** encoded data, if nullptr, means error, and the error code is err.Err **static** False > C++ defination code: > ```cpp > Bytes *encode_report(Bytes *body nullptr) > ``` #### encode\\_resp\\_err {#encode\\_resp\\_err} Encode response error message item description **type** func **param** **buff**: output buffer
    **buff_len**: output buffer length
    **code**: error code
    **msg**: error message
    **return** encoded data length, if < 0, means error, and the error code is err.Err **static** False > C++ defination code: > ```cpp > int encode_resp_err(uint8_t *buff, int buff_len, err::Err code, const std::string &msg) > ``` #### encode\\_resp\\_err (overload 1) {#encode\\_resp\\_err (overload 1)} Encode response error message item description **type** func **param** **code**: error code
    **msg**: error message
    **return** encoded data, if nullptr, means error, and the error code is err.Err **static** False > C++ defination code: > ```cpp > Bytes *encode_resp_err(err::Err code, const std::string &msg) > ``` #### set\\_body {#set\\_body} Update message body item description **type** func **param** **body_new**: new body data
    **body_len**: new body data length
    **static** False > C++ defination code: > ```cpp > void set_body(uint8_t *body_new, int body_len) > ``` #### set\\_body (overload 1) {#set\\_body (overload 1)} Update message body item description **type** func **param** **body_new**: new body data
    **static** False > C++ defination code: > ```cpp > void set_body(Bytes *body_new) > ``` #### get\\_body {#get\\_body} Get message body item description **type** func **return** message body, bytes type **static** False > C++ defination code: > ```cpp > Bytes *get_body() > ``` ### Protocol {#Protocol} Communicate protocol > C++ defination code: > ```cpp > class Protocol > ``` #### Protocol {#Protocol 2} Construct a new Protocol object item description **type** func **param** **buff_size**: Data queue buffer size
    **static** False > C++ defination code: > ```cpp > Protocol(int buff_size 1024, uint32_t header maix::protocol::HEADER) > ``` #### buff\\_size {#buff\\_size} Data queue buffer size item description **type** func **static** False > C++ defination code: > ```cpp > int buff_size() > ``` #### push\\_data {#push\\_data} Add data to data queue item description **type** func **param** **new_data**: new data
    **len**: new data length
    **return** error code, maybe err.Err.ERR_BUFF_FULL **static** False > C++ defination code: > ```cpp > err::Err push_data(uint8_t *new_data, int len) > ``` #### push\\_data (overload 1) {#push\\_data (overload 1)} Add data to data queue item description **type** func **param** **new_data**: new data
    **return** error code, maybe err.Err.ERR_BUFF_FULL **static** False > C++ defination code: > ```cpp > err::Err push_data(const Bytes *new_data) > ``` #### decode {#decode} Decode data in data queue and return a message item description **type** func **param** **new_data**: new data add to data queue, if null, only decode.
    **len**: new data length, can be 0.
    **return** decoded message, if nullptr, means no message decoded. **static** False > C++ defination code: > ```cpp > protocol::MSG *decode(uint8_t *new_data nullptr, size_t len 0) > ``` #### decode (overload 1) {#decode (overload 1)} Decode data in data queue and return a message item description **type** func **param** **new_data**: new data add to data queue, if null, only decode.
    **return** decoded message, if nullptr, means no message decoded. **static** False > C++ defination code: > ```cpp > protocol::MSG *decode(const Bytes *new_data nullptr) > ``` #### encode\\_resp\\_ok {#encode\\_resp\\_ok 2} Encode response ok(success) message to buffer item description **type** func **param** **buff**: output buffer
    **buff_len**: output buffer length
    **cmd**: CMD value
    **body**: response body, can be null
    **body_len**: response body length, can be 0
    **return** encoded data length, if < 0, means error, and the error code is err.Err **static** False > C++ defination code: > ```cpp > int encode_resp_ok(uint8_t *buff, int buff_len, uint8_t cmd, uint8_t *body nullptr, int body_len 0) > ``` #### encode\\_resp\\_ok (overload 1) {#encode\\_resp\\_ok (overload 1) 2} Encode response ok(success) message to buffer item description **type** func **param** **cmd**: CMD value
    **body**: response body, can be null
    **body_len**: response body length, can be 0
    **return** encoded data, if nullptr, means error, and the error code is err.Err **static** False > C++ defination code: > ```cpp > Bytes *encode_resp_ok(uint8_t cmd, uint8_t *body nullptr, int body_len 0) > ``` #### encode\\_resp\\_ok (overload 2) {#encode\\_resp\\_ok (overload 2) 2} Encode response ok(success) message to buffer item description **type** func **param** **cmd**: CMD value
    **body**: response body, can be null
    **return** encoded data, if nullptr, means error, and the error code is err.Err **static** False > C++ defination code: > ```cpp > Bytes *encode_resp_ok(uint8_t cmd, Bytes *body nullptr) > ``` #### encode\\_report {#encode\\_report 2} Encode proactively report message to buffer item description **type** func **param** **buff**: output buffer
    **buff_len**: output buffer length
    **cmd**: CMD value
    **body**: report body, can be null
    **body_len**: report body length, can be 0
    **return** encoded data length, if < 0, means error, and the error code is err.Err **static** False > C++ defination code: > ```cpp > int encode_report(uint8_t *buff, int buff_len, uint8_t cmd, uint8_t *body nullptr, int body_len 0) > ``` #### encode\\_report (overload 1) {#encode\\_report (overload 1) 2} Encode proactively report message to buffer item description **type** func **param** **cmd**: CMD value
    **body**: report body, can be null
    **body_len**: report body length, can be 0
    **return** encoded data, if nullptr, means error, and the error code is err.Err **static** False > C++ defination code: > ```cpp > Bytes *encode_report(uint8_t cmd, uint8_t *body nullptr, int body_len 0) > ``` #### encode\\_report (overload 2) {#encode\\_report (overload 2) 2} Encode proactively report message to buffer item description **type** func **param** **cmd**: CMD value
    **body**: report body, can be null
    **return** encoded data, if nullptr, means error, and the error code is err.Err **static** False > C++ defination code: > ```cpp > Bytes *encode_report(uint8_t cmd, Bytes *body nullptr) > ``` #### encode\\_resp\\_err {#encode\\_resp\\_err 2} Encode response error message to buffer item description **type** func **param** **buff**: output buffer
    **buff_len**: output buffer length
    **cmd**: CMD value
    **code**: error code
    **msg**: error message
    **return** encoded data length, if < 0, means error, and the error code is err.Err **static** False > C++ defination code: > ```cpp > int encode_resp_err(uint8_t *buff, int buff_len, uint8_t cmd, err::Err code, const std::string &msg) > ``` #### encode\\_resp\\_err (overload 1) {#encode\\_resp\\_err (overload 1) 2} Encode response error message to buffer item description **type** func **param** **cmd**: CMD value
    **code**: error code
    **msg**: error message
    **return** encoded data, if nullptr, means error, and the error code is err.Err **static** False > C++ defination code: > ```cpp > Bytes *encode_resp_err(uint8_t cmd, err::Err code, const std::string &msg) > ```"},"/maixcdk/api/maix/uvc.html":{"title":"maix::uvc","content":" title: maix::uvc maix.uvc module > This is `maix::uvc` module of [MaixCDK](https://github.com/sipeed/MaixCDK). > All of these elements are in namespace `maix::uvc`. > > For MaixCDK developer: DO NOT edit this doc file manually, this doc is auto generated! ## Module {#Module} No module ## Enum {#Enum} ## Variable {#Variable} ## Function {#Function} ### get\\_supported\\_formats {#get\\_supported\\_formats} get_supported_formats function > C++ defination code: > ```cpp > std::vector get_supported_formats() > ``` ## Class {#Class} ### UvcStreamer {#UvcStreamer} UvcStreamer class > C++ defination code: > ```cpp > class UvcStreamer > ``` #### UvcStreamer {#UvcStreamer 2} Construct a new jpeg streamer object item description **type** func **note** You can get the picture stream through http://host:port/stream, you can also get it through http://ip:port, and you can add personal style through set_html() at this time **param** **host**: http host
    **port**: http port, default is 8000
    **client_number**: the max number of client
    **static** False > C++ defination code: > ```cpp > UvcStreamer(unsigned index 0) > ``` #### show {#show} Write data to uvc item description **type** func **param** **img**: image object
    **return** error code, err::ERR_NONE means success, others means failed **static** False > C++ defination code: > ```cpp > err::Err show(image::Image *img) > ``` #### use\\_mjpg {#use\\_mjpg} use mjpg on uvc item description **type** func **param** **b**: using mjpg: 0 for NOT, others to use
    **return** void **static** False > C++ defination code: > ```cpp > void use_mjpg(uint32_t b 1) > ```"},"/maixcdk/api/maix/app.html":{"title":"maix::app","content":" title: maix::app maix.app module > This is `maix::app` module of [MaixCDK](https://github.com/sipeed/MaixCDK). > All of these elements are in namespace `maix::app`. > > For MaixCDK developer: DO NOT edit this doc file manually, this doc is auto generated! ## Module {#Module} No module ## Enum {#Enum} ## Variable {#Variable} ## Function {#Function} ### app\\_id {#app\\_id} Get current APP ID. item description **return** APP ID. > C++ defination code: > ```cpp > string app_id() > ``` ### set\\_app\\_id {#set\\_app\\_id} Set current APP ID. item description **param** **app_id**: APP ID.
    > C++ defination code: > ```cpp > string set_app_id(const string &app_id) > ``` ### get\\_apps\\_info\\_path {#get\\_apps\\_info\\_path} Get APP info file path. > C++ defination code: > ```cpp > string get_apps_info_path() > ``` ### get\\_apps\\_info {#get\\_apps\\_info} Get APP info list. item description **param** **ignore_launcher**: if true, ignore launcher APP. default false.
    **ignore_app_store**: if true, ignore app store APP. default false.
    **return** APP info list. APP_Info object list. > C++ defination code: > ```cpp > vector &get_apps_info(bool ignore_launcher false, bool ignore_app_store false) > ``` ### get\\_app\\_info {#get\\_app\\_info} Get app info by app id. item description **return** app.APP_Info type. > C++ defination code: > ```cpp > app::APP_Info get_app_info(const std::string &app_id) > ``` ### get\\_app\\_data\\_path {#get\\_app\\_data\\_path} Get APP info, APP can store private data in this directory. item description **return** APP data path \"./data\", just return the data folder in current path because APP executed in app install path or project path.
    So, you must execute your program in you project path to use the project/data folder when you debug your APP. > C++ defination code: > ```cpp > string get_app_data_path() > ``` ### get\\_app\\_path {#get\\_app\\_path} Get APP path. item description **param** **app_id**: APP ID, if empty, return current APP path, else return the APP path by app_id.
    **return** APP path, just return the current path because APP executed in app install path or project path.
    So, you must execute your program in you project path to use the project/data folder when you debug your APP. > C++ defination code: > ```cpp > string get_app_path(const string &app_id \"\") > ``` ### get\\_tmp\\_path {#get\\_tmp\\_path} Get global temporary data path, APPs can use this path as temporary data directory. item description **return** temporary data path. > C++ defination code: > ```cpp > string get_tmp_path() > ``` ### get\\_share\\_path {#get\\_share\\_path} Get data path of share, shared data like picture and video will put in this directory item description **return** share data path. > C++ defination code: > ```cpp > string get_share_path() > ``` ### get\\_picture\\_path {#get\\_picture\\_path} Get picture path of share, shared picture will put in this directory item description **return** share picture path. > C++ defination code: > ```cpp > string get_picture_path() > ``` ### get\\_video\\_path {#get\\_video\\_path} Get video path of share, shared video will put in this directory item description **return** share video path. > C++ defination code: > ```cpp > string get_video_path() > ``` ### get\\_font\\_path {#get\\_font\\_path} Get font path of share, shared font will put in this directory item description **return** share font path. > C++ defination code: > ```cpp > string get_font_path() > ``` ### get\\_icon\\_path {#get\\_icon\\_path} Get icon path of share, shared icon will put in this directory item description **return** share icon path. > C++ defination code: > ```cpp > string get_icon_path() > ``` ### get\\_sys\\_config\\_kv {#get\\_sys\\_config\\_kv} Get system config item value. item description **param** **item**: name of setting item, e.g. wifi, language. more see settings APP.
    **key**: config key, e.g. for wifi, key can be ssid, for language, key can be locale.
    **value**: default value, if not found, return this value.
    **from_cache**: if true, read from cache, if false, read from file.
    **return** config value, always string type, if not found, return empty string. > C++ defination code: > ```cpp > string get_sys_config_kv(const string &item, const string &key, const string &value \"\", bool from_cache true) > ``` ### get\\_app\\_config\\_kv {#get\\_app\\_config\\_kv} Get APP config item value. item description **param** **item**: name of setting item, e.g. user_info
    **key**: config key, e.g. for user_info, key can be name, age etc.
    **value**: default value, if not found, return this value.
    **from_cache**: if true, read from cache, if false, read from file.
    **return** config value, always string type, if not found, return empty string. > C++ defination code: > ```cpp > string get_app_config_kv(const string &item, const string &key, const string &value \"\", bool from_cache true) > ``` ### set\\_app\\_config\\_kv {#set\\_app\\_config\\_kv} Set APP config item value. item description **param** **item**: name of setting item, e.g. user_info
    **key**: config key, e.g. for user_info, key can be name, age etc.
    **value**: config value, always string type.
    **write_file**: if true, write to file, if false, just write to cache.
    **return** err::Err > C++ defination code: > ```cpp > err::Err set_app_config_kv(const string &item, const string &key, const string &value, bool write_file true) > ``` ### get\\_app\\_config\\_path {#get\\_app\\_config\\_path} Get APP config path, ini format, so you can use your own ini parser to parse it like `configparser` in Python.\\nAll APP config info is recommended to store in this file. item description **return** APP config path(ini format). > C++ defination code: > ```cpp > string get_app_config_path() > ``` ### set\\_exit\\_msg {#set\\_exit\\_msg} Set APP exit code and exit message.\\nIf code ! 0, the launcher will show a dialog to user, and display the msg. item description **param** **code**: exit code, 0 means success, other means error, if code is 0, do nothing.
    **msg**: exit message, if code is 0, msg is not used.
    **return** exit code, the same as arg @code. > C++ defination code: > ```cpp > err::Err set_exit_msg(err::Err code, const string &msg) > ``` ### get\\_exit\\_msg {#get\\_exit\\_msg} Get APP exit code and exit message. item description **param** **cache**: if true, read from cache, if false, read from file. default false.
    **return** exit return app_id, exit code and exit message. > C++ defination code: > ```cpp > tuple get_exit_msg(bool cache false) > ``` ### have\\_exit\\_msg {#have\\_exit\\_msg} Check if have exit msg item description **param** **cache**: if true, just check from cache, if false, check from file. default false.
    **return** true if have exit msg, false if not. > C++ defination code: > ```cpp > bool have_exit_msg(bool cache false) > ``` ### switch\\_app {#switch\\_app} Exit this APP and start another APP(by launcher).\\nCall this API will call set_exit_flag(true), you should check app::need_exit() in your code.\\nAnd exit this APP if app::need_exit() return true. item description **param** **app_id**: APP ID which will be started. app_id and idx must have one is valid.
    **idx**: APP index. app_id and idx must have one is valid.
    **start_param**: string type, will send to app, app can get this param by `app.get_start_param()`
    **attention** If app id or idx the same as current app, do nothing. > C++ defination code: > ```cpp > void switch_app(const string &app_id, int idx 1, const std::string &start_param \"\") > ``` ### get\\_start\\_param {#get\\_start\\_param} Get start param set by caller item description **return** param, string type > C++ defination code: > ```cpp > const std::string get_start_param() > ``` ### need\\_exit {#need\\_exit} Shoule this APP exit? item description **return** true if this APP should exit, false if not. **attention** This API is a function, not a variable. > C++ defination code: > ```cpp > bool need_exit() > ``` ### running {#running} App should running? The same as !app::need_exit() (not app::need_exit() in MaixPy). item description **return** true if this APP should running, false if not. **attention** This API is a function, not a variable. > C++ defination code: > ```cpp > bool running() > ``` ### set\\_exit\\_flag {#set\\_exit\\_flag} Set exit flag. You can get exit flag by app.need_exit(). item description **param** **exit**: true if this APP should exit, false if not.
    > C++ defination code: > ```cpp > void set_exit_flag(bool exit) > ``` ## Class {#Class} ### Version {#Version} APP version > C++ defination code: > ```cpp > class Version > ``` #### \\_\\_str\\_\\_ {#\\_\\_str\\_\\_} Convert to string, e.g. 1.0.0 item description **type** func **static** False > C++ defination code: > ```cpp > std::string __str__() > ``` #### from\\_str {#from\\_str} Convert from string, e.g. \\\"1.0.0\\\" item description **type** func **static** True > C++ defination code: > ```cpp > static app::Version from_str(const string &version_str) > ``` ### APP\\_Info {#APP\\_Info} APP info > C++ defination code: > ```cpp > class APP_Info > ``` #### id {#id} APP id item description **type** var **static** False **readonly** False > C++ defination code: > ```cpp > string id > ``` #### name {#name} APP name item description **type** var **static** False **readonly** False > C++ defination code: > ```cpp > string name > ``` #### icon {#icon} APP icon item description **type** var **static** False **readonly** False > C++ defination code: > ```cpp > string icon > ``` #### version {#version 2} APP version item description **type** var **static** False **readonly** False > C++ defination code: > ```cpp > Version version > ``` #### exec {#exec} APP exec item description **type** var **static** False **readonly** False > C++ defination code: > ```cpp > string exec > ``` #### author {#author} APP author item description **type** var **static** False **readonly** False > C++ defination code: > ```cpp > string author > ``` #### desc {#desc} APP desc item description **type** var **static** False **readonly** False > C++ defination code: > ```cpp > string desc > ``` #### names {#names} APP names item description **type** var **static** False **readonly** False > C++ defination code: > ```cpp > map names > ``` #### descs {#descs} APP descs item description **type** var **static** False **readonly** False > C++ defination code: > ```cpp > map descs > ```"},"/maixcdk/api/maix/ext_dev.html":{"title":"maix::ext_dev","content":" title: maix::ext_dev maix.ext_dev module > This is `maix::ext_dev` module of [MaixCDK](https://github.com/sipeed/MaixCDK). > All of these elements are in namespace `maix::ext_dev`. > > For MaixCDK developer: DO NOT edit this doc file manually, this doc is auto generated! ## Module {#Module} module brief [tmc2209](./ext_dev/tmc2209.html) maix.ext_dev.tmc2209 module [bm8563](./ext_dev/bm8563.html) maix.ext_dev.bm8563 module [qmi8658](./ext_dev/qmi8658.html) maix.ext_dev.qmi8658 module [mlx90640](./ext_dev/mlx90640.html) maix.ext_dev.mlx90640 module [fp5510](./ext_dev/fp5510.html) maix.ext_dev.fp5510 module [imu](./ext_dev/imu.html) maix.ext_dev.imu module [pmu](./ext_dev/pmu.html) maix.ext_dev.pmu module [axp2101](./ext_dev/axp2101.html) maix.ext_dev.axp2101 module ## Enum {#Enum} ## Variable {#Variable} ## Function {#Function} ## Class {#Class}"},"/maixcdk/api/maix/comm.html":{"title":"maix::comm","content":" title: maix::comm maix.comm module > This is `maix::comm` module of [MaixCDK](https://github.com/sipeed/MaixCDK). > All of these elements are in namespace `maix::comm`. > > For MaixCDK developer: DO NOT edit this doc file manually, this doc is auto generated! ## Module {#Module} module brief [modbus](./comm/modbus.html) maix.comm.modbus module ## Enum {#Enum} ## Variable {#Variable} ## Function {#Function} ### add\\_default\\_comm\\_listener {#add\\_default\\_comm\\_listener} Add default CommProtocol listener.\\nWhen the application uses this port, the listening thread will immediately\\nrelease the port resources and exit. If you need to start the default listening thread again,\\nplease release the default port resources and then call this function. > C++ defination code: > ```cpp > void add_default_comm_listener() > ``` ### rm\\_default\\_comm\\_listener {#rm\\_default\\_comm\\_listener} Remove default CommProtocol listener. item description **return** bool type. > C++ defination code: > ```cpp > bool rm_default_comm_listener() > ``` ## Class {#Class} ### CommProtocol {#CommProtocol} Class for communication protocol > C++ defination code: > ```cpp > class CommProtocol > ``` #### CommProtocol {#CommProtocol 2} Construct a new CommProtocol object item description **type** func **param** **buff_size**: buffer size, default to 1024 bytes
    **static** False > C++ defination code: > ```cpp > CommProtocol(int buff_size 1024, uint32_t header maix::protocol::HEADER) > ``` #### get\\_msg {#get\\_msg} Read data to buffer, and try to decode it as maix.protocol.MSG object item description **type** func **param** **timeout**: unit ms, 0 means return immediatly, 1 means block util have msg, >0 means block until have msg or timeout.
    **return** decoded data, if nullptr, means no valid frame found.
    Attentioin, delete it after use in C++. **static** False > C++ defination code: > ```cpp > protocol::MSG *get_msg(int timeout 0) > ``` #### resp\\_ok {#resp\\_ok} Send response ok(success) message item description **type** func **param** **buff**: output buffer
    **buff_len**: output buffer length
    **cmd**: CMD value
    **body**: response body, can be null
    **body_len**: response body length, can be 0
    **return** send response error code, maix.err.Err type **static** False > C++ defination code: > ```cpp > err::Err resp_ok(uint8_t *buff, int buff_len, uint8_t cmd, uint8_t *body nullptr, int body_len 0) > ``` #### resp\\_ok (overload 1) {#resp\\_ok (overload 1)} Send response ok(success) message item description **type** func **param** **cmd**: CMD value
    **body**: response body, can be null
    **body_len**: response body length, can be 0
    **return** encoded data, if nullptr, means error, and the error code is err.Err.
    Attentioin, delete it after use in C++. **static** False > C++ defination code: > ```cpp > err::Err resp_ok(uint8_t cmd, uint8_t *body nullptr, int body_len 0) > ``` #### resp\\_ok (overload 2) {#resp\\_ok (overload 2)} Send response ok(success) message item description **type** func **param** **cmd**: CMD value
    **body**: response body, can be null
    **return** encoded data, if nullptr, means error, and the error code is err.Err.
    Attentioin, delete it after use in C++. **static** False > C++ defination code: > ```cpp > err::Err resp_ok(uint8_t cmd, Bytes *body nullptr) > ``` #### report {#report} Send report message item description **type** func **param** **buff**: output buffer
    **buff_len**: output buffer length
    **cmd**: CMD value
    **body**: report body, can be null
    **body_len**: report body length, can be 0
    **return** send report error code, maix.err.Err type **static** False > C++ defination code: > ```cpp > err::Err report(uint8_t *buff, int buff_len, uint8_t cmd, uint8_t *body nullptr, int body_len 0) > ``` #### report (overload 1) {#report (overload 1)} Send report message item description **type** func **param** **cmd**: CMD value
    **body**: report body, can be null
    **body_len**: report body length, can be 0
    **return** encoded data, if nullptr, means error, and the error code is err.Err.
    Attentioin, delete it after use in C++. **static** False > C++ defination code: > ```cpp > err::Err report(uint8_t cmd, uint8_t *body nullptr, int body_len 0) > ``` #### report (overload 2) {#report (overload 2)} Send report message item description **type** func **param** **cmd**: CMD value
    **body**: report body, can be null
    **return** encoded data, if nullptr, means error, and the error code is err.Err.
    Attentioin, delete it after use in C++. **static** False > C++ defination code: > ```cpp > err::Err report(uint8_t cmd, Bytes *body nullptr) > ``` #### resp\\_err {#resp\\_err} Encode response error message to buffer item description **type** func **param** **buff**: output buffer
    **buff_len**: output buffer length
    **cmd**: CMD value
    **code**: error code
    **msg**: error message
    **return** send response error code, maix.err.Err type **static** False > C++ defination code: > ```cpp > err::Err resp_err(uint8_t *buff, int buff_len, uint8_t cmd, err::Err code, const std::string &msg) > ``` #### resp\\_err (overload 1) {#resp\\_err (overload 1)} Encode response error message to buffer item description **type** func **param** **cmd**: CMD value
    **code**: error code
    **msg**: error message
    **return** encoded data, if nullptr, means error, and the error code is err.Err.
    Attentioin, delete it after use in C++. **static** False > C++ defination code: > ```cpp > err::Err resp_err(uint8_t cmd, err::Err code, const std::string &msg) > ``` ### CommBase {#CommBase} Communication base class, all communication methods should implement this interface > C++ defination code: > ```cpp > class CommBase > ``` #### open {#open} Open device, if already opened, do nothing and return err.ERR_NONE. item description **type** func **return** open device error code, err.Err type. **static** False > C++ defination code: > ```cpp > virtual err::Err open() > ``` #### close {#close} Close device, if already closed, do nothing and return err.ERR_NONE. item description **type** func **return** close device error code, err.Err type. **static** False > C++ defination code: > ```cpp > virtual err::Err close() > ``` #### is\\_open {#is\\_open} Check if opened item description **type** func **return** true if opened, else false. **static** False > C++ defination code: > ```cpp > virtual bool is_open() > ``` #### write {#write} Send data to device item description **type** func **param** **buff**: data buffer
    **len**: data length need to send, the len must < buff length.
    **return** sent data length, < 0 means error, value is err.Err. **static** False > C++ defination code: > ```cpp > virtual int write(const uint8_t *buff, int len) > ``` #### write (overload 1) {#write (overload 1)} Send data to uart item description **type** func **param** **data**: direction [in], data to send, bytes type. If you want to send str type, use str.encode() to convert.
    **return** sent length, int type, if < 0 means error, value is err.Err. **static** False > C++ defination code: > ```cpp > virtual int write(Bytes &data) > ``` #### read {#read} Receive data item description **type** func **param** **buff**: data buffer to store received data
    **buff_len**: data buffer length
    **recv_len**: max data length want to receive, default 1.
    1 means read data in uart receive buffer.
    >0 means read recv_len data want to receive.
    other values is invalid.
    **timeout**: unit ms, timeout to receive data, default 0.
    0 means read data in uart receive buffer and return immediately,
    1 means block until read recv_len data,
    >0 means block until read recv_len data or timeout.
    **return** received data length, < 0 means error, value is err.Err. **static** False > C++ defination code: > ```cpp > virtual int read(uint8_t *buff, int buff_len, int recv_len, int timeout) > ``` #### read (overload 1) {#read (overload 1)} Recv data from uart item description **type** func **param** **len**: max data length want to receive, default 1.
    1 means read data in uart receive buffer.
    >0 means read len data want to receive.
    other values is invalid.
    **timeout**: unit ms, timeout to receive data, default 0.
    0 means read data in uart receive buffer and return immediately,
    1 means block until read len data,
    >0 means block until read len data or timeout.
    **return** received data, bytes type. **static** False > C++ defination code: > ```cpp > virtual Bytes *read(int len, int timeout) > ```"},"/maixcdk/api/maix/rtsp.html":{"title":"maix::rtsp","content":" title: maix::rtsp maix.rtsp module > This is `maix::rtsp` module of [MaixCDK](https://github.com/sipeed/MaixCDK). > All of these elements are in namespace `maix::rtsp`. > > For MaixCDK developer: DO NOT edit this doc file manually, this doc is auto generated! ## Module {#Module} No module ## Enum {#Enum} ### RtspStreamType {#RtspStreamType} The stream type of rtsp item describe **values** **RTSP_STREAM_NONE**: format invalid
    **RTSP_STREAM_H264**:
    **RTSP_STREAM_H265**:
    > C++ defination code: > ```cpp > enum RtspStreamType > { > RTSP_STREAM_NONE 0, // format invalid > RTSP_STREAM_H264, > RTSP_STREAM_H265, > } > ``` ## Variable {#Variable} ## Function {#Function} ## Class {#Class} ### Region {#Region} Region class > C++ defination code: > ```cpp > class Region > ``` #### Region {#Region 2} Construct a new Region object item description **type** func **param** **x**: region coordinate x
    **y**: region coordinate y
    **width**: region width
    **height**: region height
    **format**: region format
    **camera**: bind region to camera
    **static** False > C++ defination code: > ```cpp > Region(int x, int y, int width, int height, image::Format format, camera::Camera *camera) > ``` #### get\\_canvas {#get\\_canvas} Return an image object from region item description **type** func **return** image object **static** False > C++ defination code: > ```cpp > image::Image *get_canvas() > ``` #### update\\_canvas {#update\\_canvas} Update canvas item description **type** func **return** error code **static** False > C++ defination code: > ```cpp > err::Err update_canvas() > ``` ### Rtsp {#Rtsp} Rtsp class > C++ defination code: > ```cpp > class Rtsp > ``` #### Rtsp {#Rtsp 2} Construct a new Video object item description **type** func **param** **ip**: rtsp ip
    **port**: rtsp port
    **fps**: rtsp fps
    **stream_type**: rtsp stream type
    **bitrate**: rtsp bitrate
    **static** False > C++ defination code: > ```cpp > Rtsp(std::string ip std::string(), int port 8554, int fps 30, rtsp::RtspStreamType stream_type rtsp::RtspStreamType::RTSP_STREAM_H264, int bitrate 3000 * 1000) > ``` #### start {#start} start rtsp item description **type** func **return** error code, err::ERR_NONE means success, others means failed **static** False > C++ defination code: > ```cpp > err::Err start() > ``` #### start (overload 1) {#start (overload 1)} stop rtsp item description **type** func **return** error code, err::ERR_NONE means success, others means failed **static** False > C++ defination code: > ```cpp > err::Err stop() > ``` #### bind\\_camera {#bind\\_camera} Bind camera item description **type** func **param** **camera**: camera object
    **return** error code, err::ERR_NONE means success, others means failed **static** False > C++ defination code: > ```cpp > err::Err bind_camera(camera::Camera *camera) > ``` #### bind\\_audio\\_recorder {#bind\\_audio\\_recorder} Bind audio recorder item description **type** func **note** If the audio_recorder object is bound, the audio_recorder object cannot be used elsewhere. **param** **recorder**: audio_recorder object
    **return** error code, err::ERR_NONE means success, others means failed **static** False > C++ defination code: > ```cpp > err::Err bind_audio_recorder(audio::Recorder *recorder) > ``` #### write {#write} Write data to rtsp(This function will be removed in the future) item description **type** func **param** **frame**: video frame data
    **return** error code, err::ERR_NONE means success, others means failed **static** False > C++ defination code: > ```cpp > err::Err write(video::Frame &frame) > ``` #### get\\_url {#get\\_url} Get url of rtsp item description **type** func **return** url of rtsp **static** False > C++ defination code: > ```cpp > std::string get_url() > ``` #### get\\_urls {#get\\_urls} Get url list of rtsp item description **type** func **return** url list of rtsp **static** False > C++ defination code: > ```cpp > std::vector get_urls() > ``` #### to\\_camera {#to\\_camera} Get camera object from rtsp item description **type** func **return** camera object **static** False > C++ defination code: > ```cpp > camera::Camera *to_camera() > ``` #### rtsp\\_is\\_start {#rtsp\\_is\\_start} return rtsp start status item description **type** func **return** true means rtsp is start, false means rtsp is stop. **static** False > C++ defination code: > ```cpp > bool rtsp_is_start() > ``` #### add\\_region {#add\\_region} return a region object, you can draw image on the region.(This function will be removed in the future) item description **type** func **param** **x**: region coordinate x
    **y**: region coordinate y
    **width**: region width
    **height**: region height
    **format**: region format, support Format::FMT_BGRA8888 only
    **return** the reigon object **static** False > C++ defination code: > ```cpp > rtsp::Region *add_region(int x, int y, int width, int height, image::Format format image::Format::FMT_BGRA8888) > ``` #### update\\_region {#update\\_region} update and show region(This function will be removed in the future) item description **type** func **return** error code **static** False > C++ defination code: > ```cpp > err::Err update_region(rtsp::Region ®ion) > ``` #### del\\_region {#del\\_region} del region(This function will be removed in the future) item description **type** func **return** error code **static** False > C++ defination code: > ```cpp > err::Err del_region(rtsp::Region *region) > ``` #### draw\\_rect {#draw\\_rect} Draw a rectangle on the canvas(This function will be removed in the future) item description **type** func **param** **id**: region id
    **x**: rectangle coordinate x
    **y**: rectangle coordinate y
    **width**: rectangle width
    **height**: rectangle height
    **color**: rectangle color
    **thickness**: rectangle thickness. If you set it to 1, the rectangle will be filled.
    **return** error code **static** False > C++ defination code: > ```cpp > err::Err draw_rect(int id, int x, int y, int width, int height, image::Color color, int thickness 1) > ``` #### draw\\_string {#draw\\_string} Draw a string on the canvas(This function will be removed in the future) item description **type** func **param** **id**: region id
    **x**: string coordinate x
    **y**: string coordinate y
    **str**: string
    **color**: string color
    **size**: string size
    **thickness**: string thickness
    **return** error code **static** False > C++ defination code: > ```cpp > err::Err draw_string(int id, int x, int y, const char *str, image::Color color, int size 16, int thickness 1) > ```"}} \ No newline at end of file diff --git a/maixcdk/static/search_index/index_2.json b/maixcdk/static/search_index/index_2.json new file mode 100644 index 00000000..96d67dfa --- /dev/null +++ b/maixcdk/static/search_index/index_2.json @@ -0,0 +1 @@ +{"/maixcdk/doc/zh/convention/add_api.html":{"title":"Add API for MaixCDK / MaixPy","content":" title: Add API for MaixCDK / MaixPy ## 代码规范 请先看[代码规范](./index.html) ## 如何添加 API 在 [快速开始](../index.html) 中末尾我们提到过通过注释的方式给 MaixPy 添加一个新的 API,看起来非常简单,只需要给 API 函数添加一个注释即可,比如 ```cpp namespace maix::example { /** * @brief say hello to someone * @param[in] name name of someone, string type * @return string type, content is hello + name * @maixpy maix.example.hello */ std::string hello(std::string name); } ``` 然后就可以在 MaixPy 中调用了: ```python from maix import example result example.hello(\"Bob\") print(result) ``` 为了尽量保证我们添加的 API 对用户**可用**,我们需要保证以下几个特性: * API 名字和参数设计合理,通用性、跨平台性强。 * API 有注释(编译时会自动生成 API 文档)。 * API 不只是 API,有使用介绍文档教程和例程代码。 这里更详细地阐述和规范流程: * **确认功能,先在[MaixPy 文档源码](https://github.com/sipeed/MaixPy/tree/main/docs/doc)中添加一份使用**文档和例程**。相当于设计文档,这样做可以避免直接写代码考虑不全后期不停修改 API,同时也有了文档。**(这很重要!!!) * 可以在[docs/doc/application](https://github.com/sipeed/MaixCDK/tree/main/docs/doc/application) 目录下找到合适的地方添加一份**应用文档**,用来记录开发时的一些细节。文件名全小写,单词使用下划线隔开比如`peripheral/uart.md` 或者`ai/yolov2.md`。 * 最好是在开发文档里面注明 API 设计参考了哪些资料或者开源项目,方便大家审阅 API 的通用性和合理性,会更快通过审阅。 * 参考[components/basic/include/maix_api_example.hpp],在合适的 `component`中添加 API,如果是新的组件,尽量先在[issues](https://github.com/sipeed/MaixCDK/issues)中讨论合理性。 > 注意这里使用了注释来标识 `API`,方便自动生成文档和`MaixPy`源码,所以要十分小心,具体请看上面的注释规范说明以及`maix_api_example.hpp`文件。 > 另外为了让在`MaixCDK`中写的 `API`能顺利生成 `MaixPy` 的 `API`,而且因为`MaixCDK`中不包含 `Python.h` 和 `Pybind11.h`等跟 `Python`相关的定义, > 语言自带的类型都是最终由`pybind11`自动转换的,比如`void hello(std::string a, std::vector b)` 最终等价 `MaixPy` 中的`def hello(a: str, b: list)`。 > 常见的比如 `std::vector`对应`list`, `std::map`对应`dict`, `std::valarray`(作为参数可以接受`list`和`bytes`, 返回值会变成 `list`) 和 `maix::Bytes`(作为参数和返回值都是`bytes`)对应 `bytes`,`std::function` 对应 MaixPy 中的函数等,具体更多可以参考[pybind11 文档](https://pybind11.readthedocs.io/en/stable/advanced/cast/overview.html#conversion table) * 在`examples`目录添加一个 C++ 例程,保证它能编译运行。 * 编译会自动生成文档,检查 `docs/doc/api`下生成的文档是否有误,有误则检测修改代码。 * 编译测试[MaixPy](https://github.com/sipeed/MaixPy)工程基于更新后的 `MaixCDK` 能否通过,以及查看生成的`MaixPy`文档是否有误,有误则检测修改代码。 * `git`提交代码到`github`自己的仓库,等待`action`自动构建和测试,检查是否有错误,如果有错误,及时修改。 * 所有在线测试无误后,提交 `PR`(`Pull Request`), 在 [github](https://github.com/sipeed/MaixCDK) 和 [github](https://github.com/sipeed/MaixCDK) 分别请求合并到`dev`分支。 ## 手动添加 MaixPy API 上面的方法可以自动生成 MaixPy API,但是在某些场景下可能需要手动添加,比如 参数是特定的类型,以 `numpy.array`为参数举例: * 在 `MaixPy` 项目中的`components/maix/include`下添加头文件和代码,可以使用和 `MaixCDK`相同的`namespace`,比如`maix.image.cv2image`函数是将`numpy`数组转化为`image.Image`对象,具体看`convert_image.hpp`文件中的定义。 更多参考: * [构建 MaixPy](https://wiki.sipeed.com/maixpy/doc/zh/source_code/build.html) * [给 MaixCAM MaixPy 添加一个 C/C++ 模块](https://wiki.sipeed.com/maixpy/doc/zh/source_code/add_c_module.html)"},"/maixcdk/doc/zh/dev/vscode_debug.html":{"title":"使用 VSCode 在线调试","content":" title: 使用 VSCode 在线调试 ## 调试 这里主要提供 vscode + gdb 的调试方法,看不太懂可以先跳过,可以先使用代码加`printf`打印的方式调试。 **(1).** 对于在本机(PC)运行,VSCode + GDB 在线调试 这里以 PC 为 Linux 系统为例: * 添加 MaixCDK(第一次试用推荐这样) 或者 工程目录到 VSCode 工作区 * 拷贝 [tools/vscode/vscode_local_debug/.vscode](../../../tools/vscode/vscode_local_debug/.vscode) 目录到上一步的工作目录下 * 根据`.vscode`是在 MaixCDK 还是在工程目录下,修改`.vscode/launch.json`中的`cwd`字段 * 按键盘 `F5` 即可开始调试 > windows 也类似,修改`.vscode`里面的相关命令和路径即可 **(2).** 对于在嵌入式设备(/远程设备,带 Linux 系统)调试 使用 VSCode + gdbserver 在嵌入式设备(/远程设备,带 Linux 系统)调试 这里以 PC 为 Linux 系统为例: * 先保证远程设备有`gdbserver`这个程序,以及 PC 有`gdb multiarch`这个程序 * 将 [tools/vscode/vscode_remote_debug/.vscode](../../../tools/vscode/vscode_remote_debug/.vscode) 目录拷贝到工程目录下 * 编辑 `launch.json` 和 `build_run_gdbserver.sh` 文件,修改里面的路径和命令,以及用户名等。 > 建议先将 PC 的 ssh key 加入到远程设备的 `~/.ssh/authorized_keys` 文件中,这样就不需要输入密码了。 * 每次调试需要执行 `build_run_gdbserver.sh` 脚本,然后在 VSCode 中按 `F5` 即可开始调试 > 脚本会编译工程,然后拷贝可执行文件到远程设备,并且启动 `gdbserver`。 > 按 F5 启动调试时, VSCode 使用 GDB 连接到远程设备的`gdbserver`以调试。"},"/maixcdk/doc/zh/dev/docker/index.html":{"title":"MaixCDK Docker 构建环境","content":"MaixCDK Docker 构建环境 ## 关于 Docker 和安装 Docker Docker 是一种工具,我们在这里使用它来创建一个干净的 Ubuntu 环境用于构建 MaixCDK。 使用 Docker,你无需手动安装依赖项,只需创建一个 Docker 容器,一切环境就准备好了。 安装 Docker 的文档请参考 [Docker 官方文档](https://docs.docker.com/engine/install/ubuntu/)。 安装完成后,你可以使用 `docker version` 检查是否安装成功。 ## 从 Docker Hub 拉取(推荐),或自行构建 ```shell docker pull sipeed/maixcdk builder ``` > 或者你也可以通过 Dockerfile 自行构建: > > ```shell > docker build network host t maixcdk builder . > ``` > 你也可以通过添加参数使用代理: > ` network host build arg http_proxy http://127.0.0.1:8123 build arg https_proxy http://127.0.0.1:8123`。 ## 创建并运行容器 在上一步中我们得到了一个 Docker 系统镜像,现在我们创建一个容器来运行这个镜像。 ```shell docker run it network host hostname maixcdk env name maixcdk env env USER $USER env UID `id u` env GID `id g` env MAIXCDK_PATH /home/${USER}/MaixCDK v /home/${USER}/MaixCDK:/home/${USER}/MaixCDK sipeed/maixcdk builder ``` > !! 不要在命令末尾添加 `/bin/bash`。 > ` network host` 表示使用与主机相同的网络。 > ` hostname` 设置容器的主机名为 `maixcdk env`。 > ` name` 设置容器名称为 `maixcdk env`,方便使用 `docker` 命令进行控制。 > `USER`(主机的用户名)、用户 ID 和组 ID 将与主机的用户信息一致,避免权限问题。 > 你可以使用 ` v host_dir:container_dir` 将你的数据映射到容器中,例如:` v /home/${USER}/MaixCDK:/home/${USER}/MaixCDK v /home/${USER}/projects:/home/${USER}/projects`。 > 建议将主机目录映射到容器的相同目录,这样查看日志会更方便。 > 使用 ` env MAIXCDK_PATH /home/${USER}/MaixCDK` 参数设置 `MAIXCDK_PATH` 环境变量,这样你可以在容器内任何位置编译项目。 > `sipeed/maixcdk builder` 是镜像名称,如果你自行构建,请使用 `maixcdk builder`。 接下来你可以在容器中使用 shell 命令。默认用户密码为 `maixcdk`,如果需要修改密码,可以使用以下命令: ```shell docker exec it maixcdk env passwd ``` ## 构建 MaixCDK 项目或示例 进入容器后,可以根据 MaixCDK 文档使用 shell 命令进行构建。 ```shell cd /MaixCDK/examples/hello_world maixcdk build maixcdk run cd ~/projects/my_project maixcdk build maixcdk run ``` ## 停止容器 ```shell docker stop maixcdk env ``` ## 启动容器 ```shell docker start maixcdk env docker attach maixcdk env ``` ## 从主机 shell 执行命令 ```shell docker exec it user $USER maixcdk env \"cd /MaixCDK/examples/hello_world && maixcdk build && maixcdk run\" ``` ```shell docker exec it user $USER maixcdk env /bin/bash ``` ## 删除容器 ```shell docker stop maixcdk env docker rm maixcdk env ```"},"/maixcdk/doc/zh/index.html":{"title":"MaixCDK 快速开始","content":" title: MaixCDK 快速开始 ## MaixCDK 基本介绍 MaixCDK 使用 C++ 封装了常用的 AI 图像、视觉、语音,外设相关的 API,使用 MaixCDK 可以快速验证产品原型和开发稳定的产品。 MaixCDK 不光是一套 C++ SDK,同时会自动生成 Python API 绑定,即可以使用 Python 进行开发,也就是[MaixPy](https://wiki.sipeed.com/maixpy/)。 使用 MaixCDK 需要基本的 Linux 使用经验和懂交叉编译的基本概念。 ## 基础知识 要使用 MaixCDK,均假设你已经会以下知识,不会请先自行学习或者请转角使用[MaixPy](https://wiki.sipeed.com/maixpy/): * 熟练使用 Linux 进行开发,熟悉终端以及常见命令使用。 * 熟练掌握 C/C++ 其中一种语言,其中 C++ 可以不熟练但是必须了解基础语法和面向对象概念。 * 会主动看源码分析问题。 * 中国开发者须了解使用网络代理。 * 了解交叉编译。 ## 如何找资料和解决问题 1. 多看 [MaixCDK 源码](https://github.com/sipeed/MaixCDK)。 2. 由于功能 / `API` 和 `MaixPy` 相同,`MaixCDK` 不再单独提供详细的教程,请参考[MaixPy 文档](https://wiki.sipeed.com/maixpy/),原理和代码基本一致,稍微转换一下就能使用。 3. 建议不要直接从 `MaixCDK` 上手,先体验完基本的 `MaixPy` 使用再使用 MaixCDK 会轻松很多。 4. 多看仔细看官方文档,包括 MaixCDK、MaixPy、硬件文档。 5. 遇到问题先从 [MaixCDK FAQ](https://wiki.sipeed.com/maixcdk/doc/zh/faq.html), [MaixPy FAQ](https://wiki.sipeed.com/maixpy/doc/zh/faq.html), [MaixCAM 硬件 FAQ](https://wiki.sipeed.com/hardware/zh/maixcam/faq.html) 以及[源码 issues](https://github.com/sipeed/MaixCDK/issues) 等地方找答案。 6. [MaixHub 分享广场](https://maixhub.com/share) 看社区成员的经验。 7. **仔细 耐心** 看 错误`LOG`, 从上到下看日志,出错日志有时可能在中间,不要跳过着急!! ## 快速开始 ### 准备系统和环境 两种方式: #### 本机: **仅支持 Linux 系统**,推荐使用 **Ubuntu > 20.04**。 注意 MaixCAM 工具链只支持 x86_64 CPU,不支持 ARM 电脑,特别是如果你是 ARM MacOS 则无法编译过。 ``` sudo apt update sudo apt install git cmake build essential python3 python3 pip autoconf automake libtool cmake version # cmake 版本应该 > 3.13 ``` > 如果你希望编译出来到 Linux PC 上跑,而不是交叉编译到开发板,如果是 `Ubuntu`,请使用系统版本`> 20.04`,否则有些依赖包可能会版本太旧无法编译通过,并且按照[Dockerfile](https://github.com/sipeed/MaixCDK/blob/main/docs/doc/dev/docker/Dockerfile)里面的安装依赖的命令来安装依赖。 > 如果编译仍然报错,请[使用 Docker 环境进行编译](./dev/docker/index.html)。 #### Docker: `Docker` 环境准备好了 `ubuntu20.04` 系统和依赖,可以直接获取开始编译,**对 `Docker` 熟悉 或者 搭建本地开发环境遇到问题**可以参考。 详细请看 [Docker 环境使用方法](./dev/docker/index.html)。 ### 获取源码 ``` git clone https://github.com/Sipeed/MaixCDK ``` > * 稳定的 Release 版本可以到 [release 页面](https://github.com/Sipeed/MaixCDK/releases) 下载。 > * 另外也可以看 [MaixPy release](https://github.com/Sipeed/MaixPy/releases) assets 下的 `maixcdk_version_xxxxx.txt`, 这个`xxxxx` 就是 MaixPy 对应 release 使用的版本,可以使用`git checkout xxxx`来切换到对应的版本。 > 中国国内用户可能克隆速度比较慢,可以使用`git clone https://gitee.com/Sipeed/MaixCDK` ### 安装依赖 ``` cd MaixCDK pip install U pip # 更新 pip 到最新版本 pip install U r requirements.txt # 安装依赖 ``` > 中国国内可以加` i https://pypi.tuna.tsinghua.edu.cn/simple`参数来使用清华源。 > `Docker`环境里面已经装好了,不过也可以在`Docker`容器里面执行命令更新到最新版本。 此时在终端执行`maixtool`和`maixcdk`命令可以看到帮助信息。 > 如果报错找不到命令,可以尝试重启终端,或者通过`find / name \"maixtool\"`来找到`maixtool`命令的位置,然后通过`export PATH maixtool所在目录;$PATH`来设置系统环境变量,重启终端就可以执行`maixtool`命令了。 ### 编译 ```shell cd examples/hello_world maixcdk menuconfig ``` 根据提示选择设备平台,会出来一个界面可以配置一些参数,初次使用用默认的参数即可(用默认的参数也可以不执行 menuconfig, 直接执行 build 命令),然后按`ESC`按键,再按`Y`保存退出。 ```shell maixcdk build ``` 第一次执行这一步会根据设备下载编译工具链,下载如果太慢,可以根据提示手动下载到提示的目录,然后再执行编译。 >! 下载的资源基本都是 github 上的,中国国内下载速度可能会比较慢甚至失败(要下载的文件列表在`dl/pkgs_info.json`),有几种常见解决方法: > 1. 终端设置代理(推荐), 比如:`export http_proxy http://127.0.0.1:8123 https_proxy http://127.0.0.1:8123`,这里`http://127.0.0.1:8123`就是你的`http`代理的地址。 > 2. 手动下载到`dl/pkgs`下:下载时,会打印下载连接和下载到本地的路径,手动下载文件方到对应路径,再次执行编译就会直接使用本地准备好的(注意文件 sha256 校验值必须相同即同一个文件)。 > 3. 中国国内用户可以到 [首页 QQ 群](../) 群文件`MaixCDK`文件夹下载放到`MaixCDK/dl`目录下。 >! 常见错误和解决方法看[FAQ](./faq.html) 编译完后在`build`目录下可以看到二进制程序文件,以及`build/dl_lib`下有依赖的`so`文件。 修改了代码后,再次执行`maixcdk build`即可编译。 如果你**没有增删源码文件可以执行`maixcdk build2` 或者 `maixcdk build no gen` 编译会更快**(只编译修改了的文件)。 > 因为`build`命令会从头开始构建,扫描文件再编译,`build2`命令则不会扫描文件增删,直接编译编辑过的文件。 > 注意`build2`命令不会检测到文件增加或者删除,如果**增删了文件必须再执行一遍`build`命令**。 也可以执行`maixcdk distclean` 清除所有编译产生的临时文件以从一个干净的环境开始编译(但是这样构建时间会很长,一般编译出现奇怪的问题可以先尝试这样解决)。 ### 上传程序到设备 拷贝 可执行文件 和 `dl_lib`文件夹 到设备运行。 可以通过 `scp`命令来拷贝,比如: ```shell scp r dist/ root@10.127.117.1:/root/ ``` 默认密码是`root` ### 运行 通过 ssh 终端运行程序。注意要保证没有程序正在运行(包括开机的应用选择界面(Launcher))。 具体方法: * MaixVision 连接设备,这会让 Launcher 退出。也可以在 ssh 终端手动`kill` `launcher_daemon`程序。(**重要!!**) * ssh 连接设备,比如 `ssh root@192.168.0.123`, 密码是 `root`。 * 然后到可知性文件目录下执行文件, 比如 `cd /root/dist/camera_display_release && ./camera_display` ### 打包发布 在工程目录下,使用 `maixcdk p maixcam release` 可以为 `maixcam` 打包一个程序包并且存放在`dist`目录,可以上传发布到[MaixHub 应用商店](https://maixhub.com/app)。 安装包使用方法: * 方法一: ssh 终端,直接解压拷贝到设备,执行`chmod +x 程序名 && ./程序名`即可运行。 * 方法二: 在设备运行[应用商店](https://maixhub.com/app/12)应用,在 [MaixHub 应用商店](https://maixhub.com/app) 扫码安装。 * 方法三: 对于开发者,保证设备已经连到了和电脑所在局域网,在工程目录执行`maixcdk deploy` 会出现一个二维码, 在设备运行[应用商店](https://maixhub.com/app/12)应用扫码安装。 * 方法四: 拷贝安装包到设备,在设备执行`/maixapp/apps/app_store/app_store install xxx.zip` 即可安装应用。 这里简单提及一下,发布的应用需要遵循[APP 开发准则](./convention/app.html)。 ### 新建工程 使用命令创建工程: ```shell maixcdk new ``` ## 为 MaixPy 添加 API 因为 MaixPy 底层大多数就是 MaixCDK,而为 MaixPy 添加 API 也非常简单,给函数加一个注释`@maixpy maix.xxx.xxxx` 就可以了。 比如要实现以下 API: ```python from maix import example result example.hello(\"Bob\") print(result) ``` 只需要在[maix_api_example.hpp](https://github.com/sipeed/MaixCDK/blob/main/components/basic/include/maix_api_example.hpp) 中添加声明: ```cpp namespace maix::example { /** * @brief say hello to someone * @param[in] name name of someone, string type * @return string type, content is hello + name * @maixpy maix.example.hello */ std::string hello(std::string name); } ``` 然后编译`MaixPy`项目得到 MaixPy 安装包,安装到设备即可使用新的 API 了,简单吧! 更详细的文档请看 [添加 API](./convention/add_api.html) ## 开发准则 要开始使用 MaixCDK,请从阅读[MaixCDK 开发准则](./convention/index.html) 开始。"},"/maixcdk/doc/zh/faq.html":{"title":"MaixCDK FAQ","content":"MaixCDK FAQ You can also find FAQ from: * [MaixPy FAQ](https://wiki.sipeed.com/maixpy/doc/en/faq.html) * [MaixCAM FAQ](https://wiki.sipeed.com/hardware/zh/maixcam/faq.html) * [MaixPy 源码 FAQ](https://wiki.sipeed.com/maixpy/doc/zh/source_code/faq.html) ## 常见编译错误的通用解决方法 * **提示解压失败等错误**: 可以尝试删除掉`dl/pkgs`和`dl/extracted`目录下的对应文件让重新编译下载即可。 * **编译报错**: * 执行`maixcdk build verbose` 查看哪里报错,**仔细看报错日志**一步一步探寻问题。 * 执行 `maixcdk distclean` 清理临时文件后重新编译。 * 到[github 提交记录](https://github.com/sipeed/MaixCDK/commits/main/)处看到每个提交的自动测试是否通过(绿色的勾勾✅就是通过,红色叉叉❌就是失败),可以将本地代码切换到测试通过的提交✅再编译(本地执行`git checkout 提交号`比如`git checkout 3aba2fe3fa9de9f638bb9cb34eca0c2e0f5f3813`, 如果切换失败请自行搜索 git 用法或者直接从头来过,注意备份自己修改的代码)。 ## Downloading ippicv_2021.8_lnx_intel64_20230330_general.tgz takes a long time or fail Manually download according to the log's url, and put it into: `MaixCDK > components > opencv > opencv4 > .cache > ippicv` The file name is `43219bdc7e3805adcbe3a1e2f1f3ef3b ippicv_2021.8_lnx_intel64_20230330_general.tgz`, File name and url can also be found in `MaixCDK/components/3rd_party/opencv/opencv4/3rdparty/ippicv/ippicv.cmake` So the same as `ade` cache file `.cache/ade/4f93a0844dfc463c617d83b09011819a v0.1.2b.zip` ## Exception: parse_api_from_header **.hpp error: 'members' API comment not complete. e.g. ```cpp /** * Class for communication protocol */ class CommProtocol { /** * Read data to buffer, and try to decode it as maix.protocol.MSG object * @return decoded data, if nullptr, means no valid frame found. * Attentioin, delete it after use in C++. * @maixpy maix.comm.CommProtocol.get_msg */ protocol::MSG *get_msg(); } ``` Here `class CommProtocol` not add `@maixpy maix.comm.CommProtocol` but its method `get_msg` add it. So we add `@maixpy maix.comm.CommProtocol` to `class CommProtocol` comment will fix this error. ## 使用WSL编译OpenSSL时出错的修复方法 当我在工程中使用openssl时: ![a0cee88e7a7a747c2d34eadb31a925bd](https://github.com/user attachments/assets/7de123b5 aae6 4a92 8d88 9d9a7a57f419) 编译报错: ![3b42197634ee4cd6a7b0462636e8dd34](https://github.com/user attachments/assets/5ffe5433 ac0f 4096 8374 5d76c43ed320) 用verbose查看命令发现, Path里是包含“(”的,这是windows的Path将WSL的path污染了。 参照网上的方法,在WSL中: ``` sudo nano /etc/wsl.conf ``` 如果没有则新建,内容如下: ```conf [interop] appendWindowsPath false ``` 重启WSL后, Path干净了。 ![9a86a628630209725d362f07b51ecb9a](https://github.com/user attachments/assets/af7f11d2 9bef 4df1 aeeb 0388dce18241) 编译openssl也成功了。 ![d6e43b3bf8e5c68d9966636464b08a43](https://github.com/user attachments/assets/c41eaa03 f1d8 49b9 bc27 88c63ee4cf4f)"},"/maixcdk/doc/zh/more.html":{"title":"更多 MaixCDK 文档","content":" title: 更多 MaixCDK 文档 MaixCDK 由于是 MaixPy 的大多数 API 底层实现,所以 [MaixPy 的文档](https://wiki.sipeed.com/maixpy/)也适用于 MaixCDK,比如 功能介绍和教程,系统定制等等。"},"/maixcdk/doc/zh/dev/quick_start.html":{"title":"MaixCDK quick start","content":" title: MaixCDK quick start see [quick start](../index.html)"},"/maixcdk/doc/zh/application/ai/yolo11.html":{"title":"MaixCDK YOLO11 develop notes","content":" title: MaixCDK YOLO11 develop notes 源代码在: [MaixCDK/components/nn/include/maix_nn_yolo11.hpp](https://github.com/sipeed/MaixCDK/blob/main/components/nn/include/maix_nn_yolo11.hpp) 模型来自 [ultralytics/ultralytics](https://github.com/ultralytics/ultralytics), 训练和转换模型参考 [MaixPy doc customize yolo11](https://wiki.sipeed.com/maixpy/doc/en/vision/customize_model_yolov8.html)。"},"/maixcdk/doc/zh/application/index.html":{"title":"MaixCDK 应用笔记","content":" title: MaixCDK 应用笔记 这些笔记是 MaixCDK 开发者在创建某些功能时记录的开发笔记。 如果你想了解更多功能和详细文档,请访问 [MaixPy 文档](https://wiki.sipeed.com/maixpy/)。"},"/maixcdk/doc/zh/application/ui/lvgl.html":{"title":"在 MaixCDK 中使用 LVGL","content":" title: 在 MaixCDK 中使用 LVGL ## 运行 gui_lvgl 示例 * 进入 MaixCDK 的 `examples/gui_lvgl` 目录。 * 执行 `maixcdk build` 来在 PC 上构建项目。 * 执行 `maixcdk run` 来在 PC 上运行项目。 你还可以执行 `maixcdk menuconfig` 来切换平台,构建适用于其他平台的项目。 ## 自定义 UI * 首先下载并安装 [Squareline](https://squareline.io/)。 * 在 Squareline 中创建一个新的 UI 项目。 * 编辑你的 UI。 * 导出 UI 文件,此时会得到一个 `ui` 文件夹。 * 将所有 UI 文件复制到 `examples/gui_lvgl/ui` 文件夹。 * 运行 `maixcdk build` 进行构建。"},"/maixcdk/doc/zh/application/peripheral/uart.html":{"title":"","content":""},"/maixcdk/doc/zh/convention/i18n.html":{"title":"MaixCDK 国际化(i18n)与多语言支持","content":" title: MaixCDK 国际化(i18n)与多语言支持 你可以使用任何喜欢的国际化库,例如 [gettext](https://www.gnu.org/software/gettext/),它支持 Python 和 C++。 此外,我们还提供了一个简单的 i18n 库,适用于简单的使用场景。 ## 针对 MaixPy 请参阅 [MaixPy 国际化文档](https://wiki.sipeed.com/maixpy/doc/zh/gui/i18n.html)。 ## 针对 MaixCDK 与 MaixPy 相同,有两种方法可以使用: ### 简单的翻译字典 首先确保你的源文件编码为 `UTF 8`。 ```cpp #include \"maix_i18n.hpp\" const std::map locale_zh_dict { {\"out\", \"输出\"}, {\"hello\", \"你好\"} }; const std::map locale_ja_dict { // {\"out\", \"出力\"}, {\"hello\", \"こんにちは\"} }; const std::map> locales_dict { {\"zh\", locale_zh_dict}, {\"ja\", locale_ja_dict} }; i18n::Trans trans(locales_dict); int main() { log::info(\"系统语言: %s\\n\", i18n::get_locale().c_str()); log::info(\"%s: %s\\n\", trans.tr(\"out\").c_str(), trans.tr(\"hello\").c_str()); trans.set_locale(\"zh\"); printf(\"%s: %s\\n\", trans.tr(\"out\").c_str(), trans.tr(\"hello\").c_str()); trans.set_locale(\"en\"); printf(\"%s: %s\\n\", trans.tr(\"out\").c_str(), trans.tr(\"hello\").c_str()); trans.set_locale(\"ja\"); printf(\"%s: %s\\n\", trans.tr(\"out\").c_str(), trans.tr(\"hello\").c_str()); return 0; } ``` ### 分离的翻译文件 上面的示例适用于少量翻译字符串。如果需要翻译大量字符串,推荐使用此方法: * 不需要修改源代码即可更换翻译内容,翻译字符串保存在独立的 yaml 文件中。 * 更容易定位翻译字符串,支持自动扫描需要翻译的字符串,并自动生成 yaml 文件。 ```cpp err::Err e trans.load(\"locales\"); // 从 locales 目录加载翻译文件 err::check_raise(e, \"加载翻译 yaml 文件失败\"); log::info(\"系统语言: %s\\n\", i18n::get_locale().c_str()); log::info(\"%s: %s, %s\\n\", i18n::get_locale().c_str(), trans.tr(\"out\").c_str(), trans.tr(\"hello\").c_str()); trans.set_locale(\"zh\"); log::info(\"zh: %s, %s\\n\", trans.tr(\"out\").c_str(), trans.tr(\"hello\").c_str()); trans.set_locale(\"en\"); log::info(\"en: %s, %s\\n\", trans.tr(\"out\").c_str(), trans.tr(\"hello\").c_str()); trans.set_locale(\"ja\"); log::info(\"ja: %s, %s\\n\", trans.tr(\"out\").c_str(), trans.tr(\"hello\").c_str()); ``` 完整示例请参见 [examples/i18n](https://github.com/sipeed/MaixCDK/tree/main/examples/i18n)。 然后执行 `maixtool i18n d . r`,这将扫描所有使用 `tr()` 或 `_()` 的翻译字符串,生成 `locales` 目录和翻译文件。手动翻译 `locales` 中的 yaml 文件后,将其放置在程序旁边并运行。 ## 在 LVGL 应用中显示国际化字体 查看如何显示自定义字体:[https://neucrack.com/p/514](https://neucrack.com/p/514)。 使用以下代码: ```cpp LV_FONT_DECLARE(zh_fonts); static const std::map fonts { {\"zh\", (void*)&zh_fonts} }; const lv_font_t *get_font_by_locale(const string &locale) { const std::map::const_iterator iter fonts.find(locale); if (iter fonts.end()) { return &zh_fonts; } return (lv_font_t *)iter >second; } ``` 最后,使用国际化字体: ```cpp std::string locale i18n::get_locale(); lv_obj_set_style_text_font(lv_scr_act(), get_font_by_locale(locale), LV_PART_MAIN); lv_obj_t *label lv_label_create(lv_scr_act()); lv_label_set_text(label, trans.tr(\"hello\").c_str()); ```"},"/maixcdk/doc/zh/convention/protocol.html":{"title":"Maix communicate Protocol","content":" title: Maix communicate Protocol update: date: 2023 11 28 author: neucrack version: 1.0.0 content: 设计并编写协议文档和代码 API 实现 ## Maix 串口协议简介 运行 MaixCDK 或者 MaixPy 的设备, 除了可以直接使用设备上的触摸屏和按键操作外, 还可以作为模块,可以使用 `UART`(串口) 或者 `I2C` 进行通信控制。 > 因为 I2C 为主从模式,所以协议都采用问答模式,一问一答,即`Request`+`Response` > 对于 UART 协议, 部分功能支持配置主动上报,具体请看协议 后文会详细阐述通信协议内容。 ## Maix 设备端如何使用 开机进入 `设置` 应用,在 `通信` 设置里面选择通信接口,有: * **串口**:选择后会使用串口进行通信,串口根据板子决定,波特率默认为`115200`。 * **TCP**:选择后 Maix 设备会启动一个 TCP 服务,主控端可以通过 TCP 连接 Maix 设备,端口默认为`5555`。 然后主控连接上 Maix 设备后,就可以通过协议进行通信了, 主控作为主设备, Maix 设备作为从设备。 **Maix 设备端开发**: 用提供的`maix.comm.CommProtocol`类可以很方便实现命令响应,具体参考例程 [comm_protocol](../../../examples/protocol_demo)(C++)或者 [comm_protocol.py](https://github.com/sipeed/MaixPy/blob/main/examples/protocol)(MaixPy)。 **主控端开发**: 主控端根据芯片和开发语言可自行实现协议,在文末附录中有提供模板代码。 ## 数据帧 header(4B LE) data len(4B LE)(flags+cmd+body+crc) flags(1B) cmd(1B) body(nB) CRC16_IBM(2B LE)(前面所有) 十进制示例 3148663466 9 0 1 hello 17451 十六进制示例 0xBBACCAAA 0x00000009 0x00 0x01 hello 0x442B 字节流(十六进制) AA CA AC BB 09 00 00 00 00 01 68 65 6c 6c 6F 2B 44 > **注意**这里超过一个字节的数据均采用小端(LE)编码,比如这里 `data_len` 为 `0x00000006`,`06`在最低位,发送时需要先发送`0x06`再发送`0x00` `0x00` `0x00`。 > 字符串就按照顺序发即可,比如`hello`,先发`h`再发`e` `l` `l` `o`。 > 这里的例子,最终发送数据: `AA CA AC BB 09 00 00 00 00 01 68 65 6c 6c 6F 2B 44`。 * `header`: 头,4 字节,用来标识一帧的开始,固定为 4 字节 `0xAA 0xCA 0xAC 0xBB`, 先发`0xAA` * `data len`: 数据长度, 4 字节, 包含了 `flags` `cmd` + `body` + `CRC` 的长度。 * `flags`: 一个字节,各个位分别表示: * 最高位 `is_resp`: 是否是响应,`0`代表发送请求,`1`代表 响应 或者 主动上报(第三高位需要置`1`)。 * 第二高位 `resp_ok`: * 对于请求,保留位。 * 对于响应,`1`表示成功,`0`表示失败。 * 第三高位 `is_report`: * 对于请求,保留位。 * 对于响应,`1`表示主动上报,`0`表示为响应消息。 * 第 4~6 高位: 保留以后使用。 * 低 2位 `version`: 协议版本,以后修改不兼容的协议才会更改这个版本号,如果修改协议后与当前版本协议兼容则这个版本号不需要升级。目前的版本为 `0`。 * `cmd`: 基本命令类型,1 字节,已经预先定义了几个命令,看后文[命令定义](#命令定义),这些预定义命令的值从 255 逐渐递减,APP 自定义的命令可以从 `0 ~ maix.protocol.CMD.CMD_APP_MAX`。 * `body`: 内容,变长, 长度只要 `< (2^32 1)` 即可,不同的命令对应不同的`body`,在后面会对每个命令进行详细说明 * `crc16`: CRC 校验值,2 字节, 用以校验帧数据在传输过程中是否出错,使用 `CRC IBM` 方法计算,可以参见[C 代码实现](#C CRC16),或者 [Python CRC16](#Python CRC16)。和`data_len`同样两个字节小端存放,传输时先传输低位再传输高位。 编解码的代码见[附录:代码](#附录:代码) ## 请求和响应 ### 发送方主动请求 数据方向为: 单片机或其它主控设备 > Maix 设备 `flags`最高位`is_resp`设置为`0`, `body` 内容由`cmd`决定; ### 接收方响应 数据方向为: Maix 设备 > 单片机或其它主控设备 `flags`最高位`is_resp`设置为`1`。 * 对于成功响应:`resp_ok` 设置为 `1`, `body` 内容由`cmd`决定, 其中最简单的成功响应即 `body` 为空。 * 对是失败响应: * `resp_ok`设置为 `0`。 * `body` 第一个字节为错误码, 具体的错误码见[MaixCDK maix.err.Err](../../../components/basic/include/maix_err.hpp)。 * `body` 后面的字节为错误字符串信息,`UTF 8` 编码,一般情况下建议用纯英文,提高兼容性。 每个请求均应有对应的响应,即执行成功或者失败,后面均用`RESP_OK`和`RESP_ERR`来代替执行成功和失败两种响应。 `RESP_OK`的 `body` 字节不说明就是没有,有会单独进行说明。 ### 主动上报数据 数据方向为: Maix 设备 > 单片机或其它主控设备 需要主控先通过`CMD_SET_REPORT`命令设置需要主动上报的数据(需要对应的命令支持) > 比如 APP 支持 `CMD_GET_TEMP` 命令获取温度,主控可以通过 `CMD_SET_REPORT` 命令设置主动定时上报温度,然后 APP 收到这个命令后,就会定时上报温度,如果 APP 不支持设置`CMD_GET_TEMP`命令的主动上报,则会响应`CMD_ERROR`。 `flags`最高位`is_resp`设置为`1`,第三位`is_report` 设置为 `1`,`body` 内容由`cmd`决定。 ## 实例 举例: 单片机与 Maix 设备通过串口连接,默认使用`115200`波特率。 单片机向 Maix 设备请求获取 应用列表,步骤: 1. 根据下方的协议说明,单片机通过串口发送`cmd`为`0xF9`的请求,即`CMD_APP_LIST`,`body`为空。实际字节流: `AA CA AC BB 04 00 00 00 01 F9 C9 77`。 2. Maix 设备收到请求后,返回`cmd`为`0xF9`, `flags`为`0x01 0x80 0x40 > 0xC1`的响应(响应`flags`最高为`1`所以有`0x80`, 成功响应第二高位为`1`所以有`0x40`),`body`内容为应用列表,具体内容见下方协议说明。假如有两个 APP,实际字节流: `AA CA AC BB 0A 00 00 00 C1 F9 02 66 61 63 65 00 66 61 63 65 00 F6 06`。 ## 命令定义 协议帧中的`cmd`取值如下: 命令名 值 含义 CMD_APP_MAX 0xC8 应用可自定义命令最大值(不含) CMD_SET_REPORT 0xF8 设置主动上报 CMD_APP_LIST 0xF9 应用列表查询 CMD_START_APP 0xFA 启动应用 CMD_EXIT_APP 0xFB 退出应用 CMD_CUR_APP_INFO 0xFC 当前应用信息查询 CMD_APP_INFO 0xFD 应用信息查询 CMD_KEY 0xFE 按键模拟消息 CMD_TOUCH 0xFF 触摸模拟消息 注意这里有个 `CMD_APP_MAX`, 任何 APP 自定义的命令都应该在`0 ~ CMD_APP_MAX`之间,包含`0`,不包含`CMD_APP_MAX`。 不同的`cmd`对应不同的请求和响应数据, 以及不同的`body`,详细协议(主要阐述`cmd`和`body`)如下: ### CMD_SET_REPORT 开启或关闭命令主动上报。 主动上报包括: 1. 有事件时主动上报,比如检测到人脸时主动上报人脸信息。 2. 定时上报,比如每隔 5s 上报一次温度。 如果定时上报和事件上报同时开启,则事件上报后,定时器重新计时。 #### 请求 `body`: cmd(1B) on_off(1B) event(1B) timer(4B) 解释 需要开启主动上报的命令 开关(1 开, 0 关) 事件上报(1 开, 0 关) 定时上报,单位 ms,不需要定时则设置为 0 例子 0x02 0x01 5000 #### 响应 如果相应的命令支持主动上报,则响应`RESP_OK`,否则响应`RESP_ERR`,均由应用自行决定。 `body`: 无 ### CMD_APP_LIST 获取应用列表 #### 请求 `body` 为空 #### 响应 `body`: number(1B) app1 ... app n info 解释 应用数量 id1 + '\\0'结尾的字符串 ... idn 例子 0x02 'face\\0' ... 'appn\\0' ### CMD_CUR_APP_INFO 获取当前应用信息 #### 请求 `body` 为空 #### 响应 `body`: idx(1B) app info(id + name + brief) 解释 应用序号 应用信息(id, 名字(UTF 8 编码),简介(UTF 8 编码)) 例子 0x00 'face\\0face\\0face detect\\0' ### CMD_APP_INFO 获取指定应用信息 #### 请求 `body` : idx(1B) app_id(nB) 解释 应用序号 应用 ID 例子 0x02 'face' `idx` 和 `app_id` 二选一即可 * `idx`: 应用序号(从0开始),设置为 0xFF 表示不设置 * `app_id`: 应用 ID,如果 idx 设置了,可以不用设置 #### 响应 `body`: idx(1B) app info(id + name + brief) 解释 应用序号 应用信息(id, 名字(UTF 8 编码),简介(UTF 8 编码)) 例子 0x00 'face\\0face\\0face detect\\0' ### CMD_START_APP 请求启动指定应用,执行此命令会退出当前应用,然后启动指定应用。 * 如果是 APP 收到这个命令,则它需要调用 API `maix.app.switch_app` 切换 APP。 > 这里存在一个风险,就是如果 APP 没有正确实现响应这个命令,则可以敦促开发者实现这个命令。 * 如果时 Launcher 收到这个命令后会启动对应的应用。 #### 请求 `body`: idx(1B) app_id(nB) app_func(nB) 解释 应用序号(从0开始),设置为 0xFF 表示不设置 应用 ID,如果 idx 设置了,可以不用设置 该应用存在多个功能时用于指定应用启动时执行的功能 例子 0x02 'scan' 'qrcode' `idx` 、 `app_id` 和 `app_func` 三个参数如何使用: * 不带参数启动应用: 单独设置 `idx` 或者 `app_id` * 带参数启动应用: > `idx` + `app_func`,设置 `idx` 后,解释器会将后续的第一个字符串视为 `app_func`,如果有多个字符串将会返回错误。 > `app_id` + `app_func`,不设置 `idx`,解释器会在后续字符串中查找 `app_id` 和 `app_func`,不符合条件将会返回错误。 #### 响应 `body`: 无 ### CMD_EXIT_APP 请求退出当前应用 #### 请求 无 `body` #### 响应 `body`: 无 ### CMD_KEY 发送模拟按键请求 #### 请求 `body`: key(4B) value(1B) 键值(小端) 取值:0x01(/0x00/0x02) * `key`: 键值,4 字节,发送时需要按小端编码,比如`0x00000001` 发送时的字节流为`0x01 0x00 0x00 0x00`,支持的取值为: * 38: \"up\" * 40: \"down\" * 37: \"left\" * 39: \"right\" * 108: \"enter\" * 27: \"esc\" * 0x01010101: \"ok\" * 0x02020202: \"ret\" * 0x03030303: \"pre\" * 0x04040404: \"next\" * `value`: 按键值, 1 字节 * 0x01: 按下 * 0x00: 释放 * 0x02: 长按 #### 响应 `body`: 无 ### CMD_TOUCH 发送模拟触摸请求 #### 请求 `body`: x y event(1B) x 坐标 y 坐标 事件 event 取值: * 0x00: 按下 * 0x01: 抬起 * 0x02: 移动 #### 响应 `body`:无 ## 应用(APPS)协议说明 ### 相机 命令: 命令 取值 含义 响应 CMD_SNAP 0x01 拍照 ### 分类器 TODO: `body`说明: 请求只有一个字节, 代表了命令, 具体如下表: 命令 取值 含义 响应 CMD_RECOGNIZE 0x01 识别物体 CMD_APP_CMD 响应: * 命令 `CMD_RECOGNIZE` 的响应: 响应 `cmd`为 `CMD_APP_CMD`, `body`: CMD_RECOGNIZE id(2B uint16 LE) prob(4B float LE) name CMD_RECOGNIZE 值 识别到的 id(下标),小端 概率, 浮点型, 小端 名字, UTF 8 编码 ### 人脸检测 TODO: `body`说明: 请求只有一个字节, 代表了命令, 具体如下表: 命令 取值 含义 响应 CMD_POS 0x01 检测人脸 CMD_APP_CMD 响应: * 命令 `CMD_POS` 的响应: 响应 `cmd`为 `CMD_APP_CMD`, `body`: CMD_POS face num(2B LE) prob(4B float LE) x(2B LE) y(2B LE) w(2B LE) h(2B LE) ... CMD_POS 值 检测到的人脸数量 概率, 浮点型, 小端 人脸框左上角横坐标 人脸框左上角纵坐标 人脸框宽 人脸框高 剩下的人脸... ### 人脸识别 TODO: `body`说明: 请求只有一个字节, 代表了命令, 具体如下表: 命令 取值 含义 响应 CMD_FACES 0x01 识别人脸 CMD_APP_CMD CMD_USERS 0x02 查询所有用户 CMD_APP_CMD CMD_RECORD 0x03 录入人脸 CMD_APP_CMD CMD_REMOVE 0x04 删除人脸 CMD_APP_CMD 请求 `CMD_APP_CMD`加一个字节的`app_cmd`,个别命令有额外的参数,如下: * 命令 `CMD_RECORD` 的请求 CMD_RECORD user name CMD_RECORD 值 录制的用户名 * 命令 `CMD_REMOVE` 的请求 CMD_REMOVE user idx(2B int16) user name CMD_REMOVE 值 用户下标, 两字节,小端 要删除的用户名 下标和用户名二选一 响应: * 命令 `CMD_FACES` 的响应: 响应 `cmd`为 `CMD_APP_CMD`, `body`: CMD_FACES face num(2B LE) id(2B) name_len(1B) name prob(4B float LE) x(2B LE) y(2B LE) w(2B LE) h(2B LE) ... CMD_FACES 值 检测到的人脸数量 人脸 ID(下标) 名字长度 名字, UTF 8 编码 概率, 浮点型, 小端 人脸框左上角横坐标 人脸框左上角纵坐标 人脸框宽 人脸框高 剩下的人脸... * 命令 `CMD_USERS` 的响应: 响应 `cmd`为 `CMD_APP_CMD`, `body`: CMD_USERS user num(2B LE) name_len(1B) name ... CMD_USERS 值 用户数量 用户名长度 名字, UTF 8 编码 剩下的用户名... * 命令 `CMD_RECORD` 的响应: `CMD_OK` 或者 `CMD_ERROR` * 命令 `CMD_REMOVE` 的响应: `CMD_OK` 或者 `CMD_ERROR` ## 附录:代码 ### C CRC16 IBM ```c unsigned short crc16_IBM(unsigned char *ptr, int len) { unsigned int i; unsigned short crc 0x0000; while(len ) { crc ^ *ptr++; for (i 0; i < 8; ++i) { if (crc & 1) crc (crc >> 1) ^ 0xA001; else crc (crc >> 1); } } return crc; } ``` 或者查表法: ```c const unsigned int crc16_table[256] { 0x0000, 0xc0c1, 0xc181, 0x0140, 0xc301, 0x03c0, 0x0280, 0xc241, 0xc601, 0x06c0, 0x0780, 0xc741, 0x0500, 0xc5c1, 0xc481, 0x0440, 0xcc01, 0x0cc0, 0x0d80, 0xcd41, 0x0f00, 0xcfc1, 0xce81, 0x0e40, 0x0a00, 0xcac1, 0xcb81, 0x0b40, 0xc901, 0x09c0, 0x0880, 0xc841, 0xd801, 0x18c0, 0x1980, 0xd941, 0x1b00, 0xdbc1, 0xda81, 0x1a40, 0x1e00, 0xdec1, 0xdf81, 0x1f40, 0xdd01, 0x1dc0, 0x1c80, 0xdc41, 0x1400, 0xd4c1, 0xd581, 0x1540, 0xd701, 0x17c0, 0x1680, 0xd641, 0xd201, 0x12c0, 0x1380, 0xd341, 0x1100, 0xd1c1, 0xd081, 0x1040, 0xf001, 0x30c0, 0x3180, 0xf141, 0x3300, 0xf3c1, 0xf281, 0x3240, 0x3600, 0xf6c1, 0xf781, 0x3740, 0xf501, 0x35c0, 0x3480, 0xf441, 0x3c00, 0xfcc1, 0xfd81, 0x3d40, 0xff01, 0x3fc0, 0x3e80, 0xfe41, 0xfa01, 0x3ac0, 0x3b80, 0xfb41, 0x3900, 0xf9c1, 0xf881, 0x3840, 0x2800, 0xe8c1, 0xe981, 0x2940, 0xeb01, 0x2bc0, 0x2a80, 0xea41, 0xee01, 0x2ec0, 0x2f80, 0xef41, 0x2d00, 0xedc1, 0xec81, 0x2c40, 0xe401, 0x24c0, 0x2580, 0xe541, 0x2700, 0xe7c1, 0xe681, 0x2640, 0x2200, 0xe2c1, 0xe381, 0x2340, 0xe101, 0x21c0, 0x2080, 0xe041, 0xa001, 0x60c0, 0x6180, 0xa141, 0x6300, 0xa3c1, 0xa281, 0x6240, 0x6600, 0xa6c1, 0xa781, 0x6740, 0xa501, 0x65c0, 0x6480, 0xa441, 0x6c00, 0xacc1, 0xad81, 0x6d40, 0xaf01, 0x6fc0, 0x6e80, 0xae41, 0xaa01, 0x6ac0, 0x6b80, 0xab41, 0x6900, 0xa9c1, 0xa881, 0x6840, 0x7800, 0xb8c1, 0xb981, 0x7940, 0xbb01, 0x7bc0, 0x7a80, 0xba41, 0xbe01, 0x7ec0, 0x7f80, 0xbf41, 0x7d00, 0xbdc1, 0xbc81, 0x7c40, 0xb401, 0x74c0, 0x7580, 0xb541, 0x7700, 0xb7c1, 0xb681, 0x7640, 0x7200, 0xb2c1, 0xb381, 0x7340, 0xb101, 0x71c0, 0x7080, 0xb041, 0x5000, 0x90c1, 0x9181, 0x5140, 0x9301, 0x53c0, 0x5280, 0x9241, 0x9601, 0x56c0, 0x5780, 0x9741, 0x5500, 0x95c1, 0x9481, 0x5440, 0x9c01, 0x5cc0, 0x5d80, 0x9d41, 0x5f00, 0x9fc1, 0x9e81, 0x5e40, 0x5a00, 0x9ac1, 0x9b81, 0x5b40, 0x9901, 0x59c0, 0x5880, 0x9841, 0x8801, 0x48c0, 0x4980, 0x8941, 0x4b00, 0x8bc1, 0x8a81, 0x4a40, 0x4e00, 0x8ec1, 0x8f81, 0x4f40, 0x8d01, 0x4dc0, 0x4c80, 0x8c41, 0x4400, 0x84c1, 0x8581, 0x4540, 0x8701, 0x47c0, 0x4680, 0x8641, 0x8201, 0x42c0, 0x4380, 0x8341, 0x4100, 0x81c1, 0x8081, 0x4040, }; unsigned short crc16_IBM(const unsigned char *ptr,int len) { unsigned short crc 0x0000; while(len ) { crc (crc >> 8) ^ crc16_table[(crc ^ *ptr++) & 0xff]; } return (crc); } ```"},"/maixcdk/doc/zh/convention/app.html":{"title":"MaixCDK 应用框架指南","content":"MaixCDK 应用框架指南 ## 简介 用户使用步骤: * 设备启动时会自动启动 `launcher`。 * 用户选择一个 APP 启动。 * 运行选中的 APP。 * 用户与 APP 交互。 * 用户退出 APP。 * `launcher` 会再次启动并等待用户选择 APP。 用户安装新的 APP: * 确保设备已连接到互联网(可以在 `app_settings` APP 中连接 WiFi)。 * 打开 [maixhub.com/app](https://maixhub.com/app) 查找 APP,点击“下载”按钮,会显示一个二维码和安装码。 * 在设备上打开 `app_store` APP,使用摄像头扫描二维码,或输入安装码来安装 APP。 * 返回 `launcher`,新安装的 APP 会显示在列表中。 ## 打包 APP 如果使用 `MaixCDK`: * 在项目文件夹中创建一个 `app.yaml`,格式见下文。 * 执行 `maixcdk release P maixcam` 来为 `maixcam` 平台打包 APP。 * 在 `dist` 文件夹中会找到一个 `app_store_v1.0.0.zip`,这是打包好的 APP 文件。 * 你可以将这个包上传到 [maixhub.com/app](https://maixhub.com/app) 与他人分享。 * 或者执行 `maixcdk deploy P maixcam` 来启动本地服务器,并显示一个二维码。 * 你也可以将这个文件上传到设备,并执行 `app_store install app_path.zip` 来通过命令安装。 如果使用 `MaixPy`,你可以使用 `MaixVision Workstation` 打包 APP,或手动使用 `maixtool`: * 在项目文件夹中创建一个 `app.yaml` 文件,格式见下文。 * 创建一个 `main.py` 文件,这是 APP 的入口。 * 在此文件夹中执行 `maixtool release`,将生成 `dist/app_id_vx.x.x.zip`。 * 你可以将这个包上传到 [maixhub.com/app](https://maixhub.com/app) 与他人分享。 * 或者执行 `maixtool deploy` 来启动本地服务器,并显示一个二维码。 `app.yaml` 格式: ```yaml id: my_app # 唯一 ID,使用小写字母并用下划线分隔单词 name: My APP name[zh]: 我的应用 # 中文名称 version: 1.0.0 # 版本号,格式为 major.minor.patch icon: assets/my_app.png # 图标文件,可以是 png 或 lottie json 文件,或为空 author: Sipeed Ltd desc: My APP description desc[zh]: 我的应用描述 #### 包含文件方法 1: # 默认情况下,会包含项目目录中的所有文件,除了排除文件 exclude: # 不支持正则表达式,.git 和 __pycache__ 总是会被排除 .vscode compile build dist # extra_include: # src: dst # build/filename123: filename123 #### 包含文件方法 2: # 白名单模式,只包含 files 字典中的文件。 # 如果没有此键或值为空,将使用方法 1。 # files: # assets # hello.py # main.py #### 包含文件方法 2.1: # 白名单模式,只包含 files 字典中的文件。 # 如果没有此键或值为空,将使用方法 1。 # files: # assets: assets ``` `exclude` 为黑名单模式,`files` 为白名单模式,你可以选择其中一种方式。 ## 文件约定 * 所有应用数据存储在 `/maixapp`。 * 应用存储在 `/maixapp/apps`。 * `/maixapp/apps/app.info` 为描述已安装应用的 INI 文件。安装和卸载应用会更新此文件。 > 开发者或用户也可以手动复制应用目录到此,并执行 `python gen_app_info.py` 生成 `app.info` 文件。 * 应用存放在 `/maixapp/apps/app_id` 文件夹中,每个应用必须包含 `app_id` 可执行文件,或 `main.sh` 脚本,或 `main.py` 脚本。 * 启动应用时,launcher 会在 `app_id` 文件夹中寻找:`main.sh` > `main.py` > `app_id` 文件。`main.sh` 使用 `sh` 执行,`main.py` 使用 `python3` 执行,`app_id` 直接执行。 * 共享数据存储在 `/maixapp/share`。 * 图片文件存储在 `/maixapp/share/picture`。 * 视频文件存储在 `/maixapp/share/video`。 * 临时数据可以存储在 `/maixapp/tmp`,注意,和 Linux 本身的`/tmp` 目录不同的是这个目录是在文件系统(SD卡)上的,系统`/tmp`是在内存上虚拟的文件系统,`/tmp`读写速度更快但是内存大小受限,大文件以及需要长期记录的日志文件(随着时间推移可能变得比较大)建议放在`/maixapp/tmp`目录下。 * 字体文件存储在 `/maixapp/share/font`。 * 图标文件存储在 `/maixapp/share/icon`。 * 应用运行时创建的数据文件可以存储在 `/maixapp/apps/app_id/data`。 * **所有路径都可以通过 API `maix.app.get_xxx_path` 获取,更多详情请参考 API 文档或 [maix_app.hpp](https://github.com/sipeed/MaixCDK/blob/main/components/basic/include/maix_app.hpp) 文件。** ## 切换应用 使用 `void maix::app::switch_app(const string &app_id, int idx 1, const std::string &start_param \"\")` 函数来切换应用。 这将退出当前应用并启动另一个应用,并将 `start_param` 字符串传递给目标应用,目标应用可以通过 `maix::app::get_start_param()` 获取此参数。"},"/maixcdk/doc/zh/convention/memcheck.html":{"title":"内存检查方法","content":"内存检查方法 ## 简介 使用valgrind工具检查内存泄露、内存越界等问题 ## 安装 ```shell sudo apt install valgrind ``` ## 使用valgrind ```shell cd examples/hello_world maixcdk build # 输出简要日志 valgrind ./build/hello_world # 输出更详细日志 # tool memcheck:指定工具为memcheck, memcheck是默认工具,该参数可以省略 # leak check full:详细的显示每个单独的内存泄露信息 # log file valgrind.log:将内存泄露检查结果输出到指定文件, valgrind.log为自定义的文件名 valgrind tool memcheck leak check full log file valgrind.log ./build/hello_world ``` ## 观察valgrind输出日志的方法 ### 观察内存泄露摘要信息 内存泄露时可以看到类似如下日志 ```shell LEAK SUMMARY: definitely lost: 48 bytes in 3 blocks. # 一定泄露的内存,例如一级指针指向的内存没有free indirectly lost: 32 bytes in 2 blocks. # 间接泄露的内存,例如二级指针指向的内存没有free,间接导致二级指针指向的一级指针指向的内存没有free possibly lost: 96 bytes in 6 blocks. still reachable: 64 bytes in 4 blocks. suppressed: 0 bytes in 0 blocks. ``` ### 观察内存异常详细信息 内存操作有多种异常,可以看到类似如下日志,详情见[官方文档](https://valgrind.org/docs/manual/mc manual.html)查看具体含义。 ```shell 8 bytes in 1 blocks are definitely lost in loss record 1 of 14 # 找到内存泄露的位置 at 0x........: malloc (vg_replace_malloc.c:...) by 0x........: mk (leak tree.c:11) by 0x........: main (leak tree.c:39) 88 (8 direct, 80 indirect) bytes in 1 blocks are definitely lost in loss record 13 of 14 at 0x........: malloc (vg_replace_malloc.c:...) by 0x........: mk (leak tree.c:11) by 0x........: main (leak tree.c:25) ``` ## 遇到无法解决的问题 见[官方文档](https://valgrind.org)"},"/maixcdk/doc/zh/convention/index.html":{"title":"MaixCDK 开发准则和指导","content":"MaixCDK 开发准则和指导 ## 总体准则 * 简单简洁易用。 不假设用户已经有特定的开发经验,尽量少操作,API 尽量简单,有详细指导文档。 > 比如 相比 让用户自己选择并下载工具链,根据用户选择的平台自动选择并下载工具链更好,入门门槛更低。 * 通用性。API 在设计时应该保证能在不同平台通用和统一抽象,如果做不到,那么这个功能可能得再三斟酌是否应该增加。 * 统一性。API 风格统一,代码风格统一。 * 扩展性。 保证核心功能的同时,尽量提供扩展接口,方便用户扩展。 * 深度性。API 足够简单,文档写明原理,源码尽量开源,方便用户深入研究。 ## 源码和二进制文件 * **不用 git 子模块**:方便中国用户下载,因为如果子模块在 github,就算对仓库做了镜像,子模块始终还是要去 github 拉取,中国用户会非常缓慢。 * **不要往源码仓库放大文件和二进制文件**:这会大大增加仓库 git 的大小, git 只擅长管理文本文件,二进制文件采用下一条的方式管理。 * **对于第三方库和二进制文件,在编译前自动下载到本地**:使用[component.py](https://github.com/sipeed/MaixCDK/blob/main/components/3rd_party/asio/component.py)定义在编译开始前需要自动下载到`dl/pkgs`并自动解压到`dl/extracted`目录下的文件,这样就能直接在`CMakeLists.txt`中引用源码了,比如`list(APPEND ADD_INCLUDE \"${DL_EXTRACTED_PATH}/sunxi_mpp/sunxi mpp 1.0.0/include\")`。 > 每次编译时会将所有需要下载的文件列表写入到`dl/pkgs_info.json`,用户有网速问题的可以到官方 QQ 群或者第三方提供的网盘手动下载放到`dl/pkgs`目录即可,这样可以解决网络环境导致的下载速度慢问题。 * **不修改第三方库源码**:不修改第三方源码,方便升级第三方库。(如果以后发现有这样的需求可以考虑在解压后增加自动打 patch 的功能) ## MaixCDK 架构简介 对于普通应用开发者, 必要知识: * 主要由`MaixCDK` 和 `project`两大部分组成,前者是`库`存放的地方,后者是应用代码存放的地方。 官方的例程和`APP`都直接放在`MaixCDK/examples` 和 `MaixCDK/projects`目录下,你也可以直接在`MaixCDK/projects`创建你的应用项目。 另外也可以两者分开放,在系统环境变量中加一个变量`MAIXCDK_PATH`,值为`MaixCDK`目录比如`/home/xxx/MaixCDK`,比如编辑`~/.bashrc`添加`export MAIXCDK_PATH /home/xxx/MaixCDK`。 这样项目就可以放其它位置了比如`/home/xxx/projects` * 组件:每个功能模块可以封装成一个组件,方便不同应用选择性地使用。 * 可以看到[examples/hello_world](./examples/hello_world)中有个`main`组件,[components](./components)中有很多组件,还可以自己添加组件,比如`hello_world/component1`或者`hello_world/compoents/component2`。 * 也可以设置环境变量`MAIXCDK_EXTRA_COMPONENTS_PATH`来指定其它额外的组件库。 * 每个组件包含一个`CMakeLists.txt`来描述组件内容,比如`list(APPEND ADD_INCLUDE \"include\")`来指定包含的头文件路径,`list(APPEND ADD_SRCS \"src/hello.c\")`来包含源文件,`list(APPEND ADD_REQUIREMENTS basic)`来依赖其它组件等。 * 另外,默认也会到 python `site packages` 目录寻找,也就是说,如果你了解 python 库打包,你的组件包可以直接发布到 [pypi.org](https://pypi.org), 这样用户通过`pip install maixcdk xxx` 就可以快速安装你的组件包了! 可以参考[examples/maixcdk example](https://github.com/sipeed/MaixCDK/blob/main//examples/maixcdk example)组件。 * Kconfig: 带终端界面的可配置项。每个组件下面都可以有一个`Kconfig`文件,里面可以设置一些配置项,在执行`maixcdk menuconfig`时就可以看到选项了,保存后会在`build/config`目录下生成`global_config.cmake`,`global_config.h`文件,可以直接在组件的`CMakeLists.txt`和`c/cpp`文件中使用。`Kconfig`的语法可以参考其它组件,活话则自行搜索、参考[这里](https://github.com/ulfalizer/Kconfiglib/tree/master/tests)等。 * 依赖的第三方库: 两种方式,开发者可以自行选择,推荐集成到`MaixCDK`中的使用方式一,个人开发者发布的组件可以使用方式二。 * 方式一:依赖的第三方库在编译时会自动被下载到`dl`文件夹,都在组件`CMakeLists.txt`中指定需要下载的文件,编译时会将所有需要下载的文件列表写入到`dl/pkgs_info.json`,这样的好处是遇到网络问题可以手动下载放到对应位置。 * 方式二:使用 python package 的方式将源码和资源文件都打包发布到 [pypi.org](https://pypi.org),取名为`maixcdk xxx`方便大家搜索到,这样用户通过`pip install maixcdk xxx` 就可以快速安装你的组件包了,而且用户也可以在安装时通过` i`参数来设置镜像源。可以参考[examples/maixcdk example](https://github.com/sipeed/MaixCDK/blob/main/examples/maixcdk example)组件。 * 文档:在[docs](./docs/)目录下包含了应用文档和 API 文档, API 文档是从代码自动生成的,不要手动修改,应用文档是具体功能的入门指导文档。 ## 代码风格 为了保持 MaixCDK 和 MaixPy API 的统一性,以及方便用户和开发者阅读,简单规范了以下代码风格: * **函数名**:全小写,单词之间用下划线隔开,比如`get_name`。 * **变量名**:全小写,单词之间用下划线隔开,比如`file_path`。 * **类名**:大驼峰,某些简单的缩写词可以全大写,比如 `Person`, `YOLOv2`, `UART`, `PWM`。 * **宏**:全大写,单词之间用下划线隔开,比如`MAIXPY_VERSION`。 * **类成员变量**:不用加`m_`前缀,全小写+下划线,比如`name`,这样方便`Python`里的`API`足够简洁。 * **类私有成员变量**:前面加`_`,比如`_name`。 * **使用类成员变量**:因为成员变量没有类似`m_`开头的明显标识,所以显示地使用`this >`,比如`this >name`,而不是`name`来提高可阅读性。 * **namespace**:所有`MaixCDK`官方的`API`都在`maix`命名空间下,`maix`下再有一个`namespace`用来区分不同的功能,可以是一个头文件一个`namespace`,也可以是一个目录一个`namespace`,比如比如`maix::thread`、`maix::peripheral`、`maix::nn`、`maix::peripheral::uart`等。 在生成`MaixPy` `API` 时,也会自动生成相应的模块,比如`maix.thread`、`maix.peripheral`、`maix.nn`、`maix.peripheral.uart`等。 * **源文件命名**:全小写,单词之间用下划线隔开,比如`maix_peripheral_uart.cpp`, `C++` 头文件使用`.hpp`后缀。 * **注释**:`API`的注释使用`doxygen`风格,参考[components/basic/include/maix_api_example.hpp](../../../components/basic/include/maix_api_example.hpp)中的使用方法。 * **API 注释文档**:一般需要写以下关键字 * **brief**: 一句话描述功能 * **param**: 参数说明,一定要详细说明参数的取值要求(比如取值范围),注意点,不能是简单的参数名称复读,那文档就没什么意义了,还不如不写。也可以加数据方向,比如`param[in] a`表示`a`是输入参数,`param[out] b`表示`b`是输出参数,`param[in,out] c`表示`c`是输入输出参数。 * **return**:返回值说明,一定要详细说明返回值的取值情况(比如取值范围),注意点,同样不能是简单的返回值名称复读。 * **retval**:出了使用`return`统一说明返回值,也可以用过过个这个关键字来阐述不同返回值的意义,比如`@retval 0 success`。 * **attention**: API 使用的注意点。 * **maixpy**:标识这是一个 `MaixPy` `API`,内容为在`MaixPy`中的包名+变量名,比如`maix.example`、`maix.example.hello`、`maix.example.Example.name`等。注意加了这个关键词不仅会生成`MaixPy` `API`和文档,如果没有同时指定`maixcdk`关键字,还会用这个名称生成`MaixCDK`的`API`文档 * **maixcdk**: 标识这是一个 `MaixCDK` `API`,如果同时存在`maixpy`关键字则优先使用这个作为`MaixCDK`的`API`名称。比如`* @maixcdk maix.example.hello_maixcdk`。 另外,对于本 SDK 中特殊的地方,比如为了能正确准确地生成 `MaixPy API`和文档,需要遵循: * **API 中的类型和默认值需要完整的定义,不省略**,`maix`明明空间可以省略,具体地: * **命名空间写全**, 比如`image::Image`,而不是`Image`。 * **枚举类型写全**,比如`image::Format::FMT_RGB888`,而不是`Format::FMT_RGB888`或者`image::FMT_RGB888`或者`FMT_RGB888`。 ## API 规范化建议 * 如果 MaixCDK 有的 API, 尽量使用,而不是直接使用第三方 API,方便不同平台移植,比如文件操作用`maix_fs.hpp`中的 API,而不是直接使用 C++ 的`fstream`。 * 打印日志使用`maix_log.hpp`中的`log::info` `log::debug`等 API, 这样在`release`版本中`debug`日志会被自动去掉,而且可以通过`maixcdk menuconfig`来设置日志级别。也方便不同平台移植。 * 错误代码使用`maix_err.hpp`中的`err::Err`,统一管理所有错误代码,方便用户查找错误原因。 * 抛出异常使用`maix_err.hpp`中的`err::Exception`,统一管理所有异常,方便用户查找错误原因, 并且**需要在 API 注释中说明可能抛出的异常和类型**。 * 对于多个模块有共性的 API,尽量有一个共同特性的基类,其它类继承并实现,比如`maix_peripheral_uart.hpp`中的`UART`继承`maix_comm.hpp`中的通信基类`CommBase`,这样方便 C++ 开发,也方便编写`MaixPy`的 API。 > 比如 `Display` 类,可以直接暴露给 MaixPy 作为 API,由于不同平台实现可能不同,定义一个`DisplayBase`基类,不同平台实现自己的`Display`类比如`SDL_Display`,然后在`Display`类里面统一调用`DisplayBase`的 API,这样就可以保证`MaixPy`的 API 通用性,用户只需要知道`Display`类,不需要知道下面用了什么具体的实现方法,提高移植性的同时用户使用也更加简单。"},"/maixcdk/doc/zh/convention/nn.html":{"title":"NN 规范","content":"# NN 规范 ## 神经网络模型文件 每个 AI 模型都使用 `.mud` 文件进行描述,这是一种 INI 格式的文件。 MUD(Model Universal Description,模型通用描述)文件是一种简单的模型描述格式。 > 创建这个文件的原因在于,各种硬件平台的模型格式不同,无法直接加载,我们需要编写多种不同的代码来加载模型。而现在使用 MUD 文件,只需在其中写入模型信息,即可简化模型加载过程。 MUD 文件定义如下: ```ini [basic] type cvimodel model model_path_relative_to_mud_file [extra] model_type classifier input_type bgr mean 103.94, 116.78, 123.68 scale 0.017, 0.017, 0.017 labels labels.txt ``` `basic` 部分是必需的,`extra` 部分是可选的。 * `basic` 部分描述了模型的类型和模型路径。 * `type` 表示模型类型,目前支持 `MaixCam` 的 `cvimodel` 类型。 * `model` 表示模型的相对路径,相对于 MUD 文件所在位置。 * `extra` 部分描述了模型的额外信息,应用程序可以通过 `model.extra_info()` 方法获取。 * `model_type` 表示模型的功能类型,如 `classifier`(分类器)和 `yolov2`(目标检测),此项为可选。 * `input_type` 表示模型的输入类型,如 `bgr` 和 `gray`(灰度图),此项为可选。 * `mean` 表示模型输入的均值,此项为可选。 * `scale` 表示模型输入的缩放比例,此项为可选。 * `labels` 表示模型标签文件的路径,此项为可选。 ## 当前 MaixCDK 支持的模型类型: * `classifier` * `classifier_no_top` * `yolo11` * `yolov8` * `yolov5` * `pp_ocr` * `retinaface` * `nanotrack` * `face_detector` * `speech` * 以及更多类型,详情请参考 [components/nn/include](https://github.com/sipeed/MaixCDK/tree/main/components/nn/include) 源代码,并搜索 `model_type` 关键字查看 `load` 方法。"},"/maixcdk/doc/zh/no_translate.html":{"title":"no_translate_title","content":" title: no_translate_title class: md_page
    no_translate_hint
    visit_hint
    "}} \ No newline at end of file diff --git a/maixcdk/static/search_index/index_3.json b/maixcdk/static/search_index/index_3.json new file mode 100644 index 00000000..3bcf3c35 --- /dev/null +++ b/maixcdk/static/search_index/index_3.json @@ -0,0 +1 @@ +{"/maixcdk/404.html":{"title":"","content":" layout: 404.html "},"/maixcdk/index.html":{"title":"MaixCDK","content":" title: MaixCDK id: home_page

    MaixCDK

    Fast implementation of AI vision and auditory applications

    [![GitHub Repo stars](https://img.shields.io/github/stars/sipeed/MaixCDK?style social)](https://github.com/sipeed/MaixCDK)[![Apache 2.0](https://img.shields.io/badge/license Apache%20v2.0 orange.svg)](\"https://github.com/sipeed/MaixCDK/blob/main/LICENSE.html)[![GitHub downloads](https://img.shields.io/github/downloads/sipeed/maixcdk/total?label GitHub%20downloads)](https://github.com/sipeed/MaixCDK) [![Build MaixCAM](https://github.com/sipeed/MaixCDK/actions/workflows/build_maixcam.yml/badge.svg)](https://github.com/sipeed/MaixCDK/actions/workflows/build_maixcam.yml)[![Trigger wiki](https://github.com/sipeed/MaixCDK/actions/workflows/trigger_wiki.yml/badge.svg)](https://github.com/sipeed/MaixCDK/actions/workflows/trigger_wiki.yml)
    English [中文](./zh/)
    If you like MaixCDK or MaixPy, please give a star ⭐️ to the [MaixPy](https://github.com/sipeed/MaixPy) and [MaixCDK](https://github.com/sipeed/MaixCDK) open source project to encourage us to develop more features.

    Simple API Design, AI Image Recognition within 20 Lines of Code

    ```cpp #include \"maix_nn.hpp\" #include \"maix_camera.hpp\" #include \"maix_display.hpp\" int main() { nn::Classifier classifier(\"/root/models/mobilenetv2.mud\"); image::Size input_size classifier.input_size(); camera::Camera cam camera::Camera(input_size.width(), input_size.height(), classifier.input_format()); display::Display disp display::Display(); char msg[64]; while(!app::need_exit()) { image::Image *img cam.read(); auto *result classifier.classify(*img); int max_idx result >at(0).first; float max_score result >at(0).second; snprintf(msg, sizeof(msg), \"%5.2f: %s\", max_score, classifier.labels[max_idx].c_str()); img >draw_string(10, 10, msg, image::COLOR_RED); disp.show(*img); delete result; delete img; } return 0; } ```

    Same simple Python API binding

    ```python from maix import camera, display, image, nn classifier nn.Classifier(model \"/root/models/mobilenetv2.mud\") cam camera.Camera(classifier.input_width(), classifier.input_height(), classifier.input_format()) disp display.Display() while 1: img cam.read() res classifier.classify(img) max_idx, max_prob res[0] msg f\"{max_prob:5.2f}: {classifier.labels[max_idx]}\" img.draw_string(10, 10, msg, image.COLOR_RED) disp.show(img) ```

    Variety of built in functions

    The functionality of MaixCDK is kept in sync with MaixPy, and the MaixPy documentation is also applicable to MaixCDK.

    Add Python binding in one second

    Just add comments, then you can use this API in MaixPy!
    Python demo code: ```python from maix import uart devices uart.list_devices() print(devices) ```
    MaixCDK implemention in `maix_uart.hpp`: ```cpp namespace maix::uart { /** * List all UART devices can be directly used. * @return All device path, list type, element is string type * @maixpy maix.uart.list_devices */ std::vector list_devices(); } ```

    Online AI Training Platform MaixHub

    No need for AI expertise or expensive training equipment, train models with one click, deploy to MaixCAM with one click.
    ## Maix Ecosystem ## Community {#community}
    Community Address **MaixCDK Documentation** [MaixCDK Documentation](https://wiki.sipeed.com/maixcdk/) **MaixPy Documentation** [MaixPy Documentation](https://wiki.sipeed.com/maixpy/) **App Store** [maixhub.com/app](https://maixhub.com/app) **Project Sharing** [maixhub.com/share](https://maixhub.com/share) **Bilibili** Search for `MaixCAM` or `MaixPy` on Bilibili **Discussion** [maixhub.com/discussion](https://maixhub.com/discussion) **MaixCDK issues** [github.com/sipeed/MaixPy/issues](https://github.com/sipeed/MaixCDK/issues) **Telegram** [t.me/maixpy](https://t.me/maixpy) **QQ Group** 862340358
    "}} \ No newline at end of file diff --git a/maixcdk/static/search_index/index_4.json b/maixcdk/static/search_index/index_4.json new file mode 100644 index 00000000..76bd269c --- /dev/null +++ b/maixcdk/static/search_index/index_4.json @@ -0,0 +1 @@ +{"/maixcdk/zh/index.html":{"title":"MaixCDK","content":" title: MaixCDK id: home_page

    MaixCDK

    快速实现 AI 视觉和听觉应用

    [![GitHub Repo stars](https://img.shields.io/github/stars/sipeed/MaixCDK?style social)](https://github.com/sipeed/MaixCDK)[![Apache 2.0](https://img.shields.io/badge/license Apache%20v2.0 orange.svg)](\"https://github.com/sipeed/MaixCDK/blob/main/LICENSE.html)[![GitHub downloads](https://img.shields.io/github/downloads/sipeed/maixcdk/total?label GitHub%20downloads)](https://github.com/sipeed/MaixCDK) [![Build MaixCAM](https://github.com/sipeed/MaixCDK/actions/workflows/build_maixcam.yml/badge.svg)](https://github.com/sipeed/MaixCDK/actions/workflows/build_maixcam.yml)[![Trigger wiki](https://github.com/sipeed/MaixCDK/actions/workflows/trigger_wiki.yml/badge.svg)](https://github.com/sipeed/MaixCDK/actions/workflows/trigger_wiki.yml)
    [English](../) 中文
    如果您喜欢 MaixCDK 或 MaixPy,请为 [MaixPy](https://github.com/sipeed/MaixPy) 和 [MaixCDK](https://github.com/sipeed/MaixCDK) 开源项目点赞 ⭐️,以鼓励我们开发更多功能。

    简单的 API 设计,20 行代码实现 AI 图像识别

    ```cpp #include \"maix_nn.hpp\" #include \"maix_camera.hpp\" #include \"maix_display.hpp\" int main() { nn::Classifier classifier(\"/root/models/mobilenetv2.mud\"); image::Size input_size classifier.input_size(); camera::Camera cam camera::Camera(input_size.width(), input_size.height(), classifier.input_format()); display::Display disp display::Display(); char msg[64]; while(!app::need_exit()) { image::Image *img cam.read(); auto *result classifier.classify(*img); int max_idx result >at(0).first; float max_score result >at(0).second; snprintf(msg, sizeof(msg), \"%5.2f: %s\", max_score, classifier.labels[max_idx].c_str()); img >draw_string(10, 10, msg, image::COLOR_RED); disp.show(*img); delete result; delete img; } return 0; } ```

    同样简单的 Python API 绑定

    ```python from maix import camera, display, image, nn classifier nn.Classifier(model \"/root/models/mobilenetv2.mud\") cam camera.Camera(classifier.input_width(), classifier.input_height(), classifier.input_format()) disp display.Display() while 1: img cam.read() res classifier.classify(img) max_idx, max_prob res[0] msg f\"{max_prob:5.2f}: {classifier.labels[max_idx]}\" img.draw_string(10, 10, msg, image.COLOR_RED) disp.show(img) ```

    多样的内置功能

    MaixCDK 的功能与 MaixPy 保持同步,MaixPy 的文档也适用于 MaixCDK。

    一秒添加 Python 绑定

    只需添加注释,即可在 MaixPy 中使用此 API!
    Python 示例代码: ```python from maix import uart devices uart.list_devices() print(devices) ```
    MaixCDK 在 `maix_uart.hpp` 中的实现: ```cpp namespace maix::uart { /** * List all UART devices can be directly used. * @return All device path, list type, element is string type * @maixpy maix.uart.list_devices */ std::vector list_devices(); } ```

    在线 AI 训练平台 MaixHub

    无需 AI 专业知识或昂贵的训练设备,一键训练模型,一键部署到 MaixCAM。
    ## Maix 生态系统 ## 社区 {#community}
    社区 地址 **MaixCDK 文档** [MaixCDK 文档](https://wiki.sipeed.com/maixcdk/) **MaixPy 文档** [MaixPy 文档](https://wiki.sipeed.com/maixpy/) **应用商店** [maixhub.com/app](https://maixhub.com/app) **项目分享** [maixhub.com/share](https://maixhub.com/share) **Bilibili** 在 Bilibili 上搜索 `MaixCAM` 或 `MaixPy` **讨论** [maixhub.com/discussion](https://maixhub.com/discussion) **MaixCDK 问题** [github.com/sipeed/MaixPy/issues](https://github.com/sipeed/MaixCDK/issues) **Telegram** [t.me/maixpy](https://t.me/maixpy) **QQ 群** 862340358
    "},"/maixcdk/zh/no_translate.html":{"title":"no_translate_title","content":" title: no_translate_title class: md_page
    no_translate_hint
    visit_hint
    "}} \ No newline at end of file diff --git a/maixcdk/teedoc-plugin-markdown-parser/mermaid.min.js b/maixcdk/teedoc-plugin-markdown-parser/mermaid.min.js new file mode 100644 index 00000000..02a60732 --- /dev/null +++ b/maixcdk/teedoc-plugin-markdown-parser/mermaid.min.js @@ -0,0 +1,3 @@ +/*! For license information please see mermaid.min.js.LICENSE.txt */ +!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.mermaid=e():t.mermaid=e()}("undefined"!=typeof self?self:this,(()=>(()=>{var t={1362:(t,e,n)=>{t=n.nmd(t);var r=function(){var t=function(t,e,n,r){for(n=n||{},r=t.length;r--;n[t[r]]=e);return n},e=[1,3],n=[1,7],r=[1,8],i=[1,9],a=[1,10],o=[1,13],s=[1,12],c=[1,16,25],u=[1,20],l=[1,31],h=[1,32],f=[1,33],d=[1,35],p=[1,38],g=[1,36],y=[1,37],m=[1,39],v=[1,40],b=[1,41],_=[1,42],x=[1,45],w=[1,46],k=[1,47],T=[1,48],C=[16,25],E=[1,62],S=[1,63],A=[1,64],M=[1,65],N=[1,66],D=[1,67],B=[16,25,32,44,45,53,56,57,58,59,60,61,66,68],L=[16,25,30,32,44,45,49,53,56,57,58,59,60,61,66,68,83,84,85,86],O=[5,8,9,10,11,16,19,23,25],I=[53,83,84,85,86],R=[53,60,61,83,84,85,86],F=[53,56,57,58,59,83,84,85,86],P=[16,25,32],Y=[1,99],j={trace:function(){},yy:{},symbols_:{error:2,start:3,mermaidDoc:4,statments:5,direction:6,directive:7,direction_tb:8,direction_bt:9,direction_rl:10,direction_lr:11,graphConfig:12,openDirective:13,typeDirective:14,closeDirective:15,NEWLINE:16,":":17,argDirective:18,open_directive:19,type_directive:20,arg_directive:21,close_directive:22,CLASS_DIAGRAM:23,statements:24,EOF:25,statement:26,className:27,alphaNumToken:28,classLiteralName:29,GENERICTYPE:30,relationStatement:31,LABEL:32,classStatement:33,methodStatement:34,annotationStatement:35,clickStatement:36,cssClassStatement:37,acc_title:38,acc_title_value:39,acc_descr:40,acc_descr_value:41,acc_descr_multiline_value:42,CLASS:43,STYLE_SEPARATOR:44,STRUCT_START:45,members:46,STRUCT_STOP:47,ANNOTATION_START:48,ANNOTATION_END:49,MEMBER:50,SEPARATOR:51,relation:52,STR:53,relationType:54,lineType:55,AGGREGATION:56,EXTENSION:57,COMPOSITION:58,DEPENDENCY:59,LINE:60,DOTTED_LINE:61,CALLBACK:62,LINK:63,LINK_TARGET:64,CLICK:65,CALLBACK_NAME:66,CALLBACK_ARGS:67,HREF:68,CSSCLASS:69,commentToken:70,textToken:71,graphCodeTokens:72,textNoTagsToken:73,TAGSTART:74,TAGEND:75,"==":76,"--":77,PCT:78,DEFAULT:79,SPACE:80,MINUS:81,keywords:82,UNICODE_TEXT:83,NUM:84,ALPHA:85,BQUOTE_STR:86,$accept:0,$end:1},terminals_:{2:"error",5:"statments",8:"direction_tb",9:"direction_bt",10:"direction_rl",11:"direction_lr",16:"NEWLINE",17:":",19:"open_directive",20:"type_directive",21:"arg_directive",22:"close_directive",23:"CLASS_DIAGRAM",25:"EOF",30:"GENERICTYPE",32:"LABEL",38:"acc_title",39:"acc_title_value",40:"acc_descr",41:"acc_descr_value",42:"acc_descr_multiline_value",43:"CLASS",44:"STYLE_SEPARATOR",45:"STRUCT_START",47:"STRUCT_STOP",48:"ANNOTATION_START",49:"ANNOTATION_END",50:"MEMBER",51:"SEPARATOR",53:"STR",56:"AGGREGATION",57:"EXTENSION",58:"COMPOSITION",59:"DEPENDENCY",60:"LINE",61:"DOTTED_LINE",62:"CALLBACK",63:"LINK",64:"LINK_TARGET",65:"CLICK",66:"CALLBACK_NAME",67:"CALLBACK_ARGS",68:"HREF",69:"CSSCLASS",72:"graphCodeTokens",74:"TAGSTART",75:"TAGEND",76:"==",77:"--",78:"PCT",79:"DEFAULT",80:"SPACE",81:"MINUS",82:"keywords",83:"UNICODE_TEXT",84:"NUM",85:"ALPHA",86:"BQUOTE_STR"},productions_:[0,[3,1],[3,1],[3,1],[3,2],[6,1],[6,1],[6,1],[6,1],[4,1],[7,4],[7,6],[13,1],[14,1],[18,1],[15,1],[12,4],[24,1],[24,2],[24,3],[27,1],[27,1],[27,2],[27,2],[27,2],[26,1],[26,2],[26,1],[26,1],[26,1],[26,1],[26,1],[26,1],[26,1],[26,2],[26,2],[26,1],[33,2],[33,4],[33,5],[33,7],[35,4],[46,1],[46,2],[34,1],[34,2],[34,1],[34,1],[31,3],[31,4],[31,4],[31,5],[52,3],[52,2],[52,2],[52,1],[54,1],[54,1],[54,1],[54,1],[55,1],[55,1],[36,3],[36,4],[36,3],[36,4],[36,4],[36,5],[36,3],[36,4],[36,4],[36,5],[36,3],[36,4],[36,4],[36,5],[37,3],[70,1],[70,1],[71,1],[71,1],[71,1],[71,1],[71,1],[71,1],[71,1],[73,1],[73,1],[73,1],[73,1],[28,1],[28,1],[28,1],[29,1]],performAction:function(t,e,n,r,i,a,o){var s=a.length-1;switch(i){case 5:r.setDirection("TB");break;case 6:r.setDirection("BT");break;case 7:r.setDirection("RL");break;case 8:r.setDirection("LR");break;case 12:r.parseDirective("%%{","open_directive");break;case 13:r.parseDirective(a[s],"type_directive");break;case 14:a[s]=a[s].trim().replace(/'/g,'"'),r.parseDirective(a[s],"arg_directive");break;case 15:r.parseDirective("}%%","close_directive","class");break;case 20:case 21:this.$=a[s];break;case 22:this.$=a[s-1]+a[s];break;case 23:case 24:this.$=a[s-1]+"~"+a[s];break;case 25:r.addRelation(a[s]);break;case 26:a[s-1].title=r.cleanupLabel(a[s]),r.addRelation(a[s-1]);break;case 34:this.$=a[s].trim(),r.setTitle(this.$);break;case 35:case 36:this.$=a[s].trim(),r.setAccDescription(this.$);break;case 37:r.addClass(a[s]);break;case 38:r.addClass(a[s-2]),r.setCssClass(a[s-2],a[s]);break;case 39:r.addClass(a[s-3]),r.addMembers(a[s-3],a[s-1]);break;case 40:r.addClass(a[s-5]),r.setCssClass(a[s-5],a[s-3]),r.addMembers(a[s-5],a[s-1]);break;case 41:r.addAnnotation(a[s],a[s-2]);break;case 42:this.$=[a[s]];break;case 43:a[s].push(a[s-1]),this.$=a[s];break;case 44:case 46:case 47:break;case 45:r.addMember(a[s-1],r.cleanupLabel(a[s]));break;case 48:this.$={id1:a[s-2],id2:a[s],relation:a[s-1],relationTitle1:"none",relationTitle2:"none"};break;case 49:this.$={id1:a[s-3],id2:a[s],relation:a[s-1],relationTitle1:a[s-2],relationTitle2:"none"};break;case 50:this.$={id1:a[s-3],id2:a[s],relation:a[s-2],relationTitle1:"none",relationTitle2:a[s-1]};break;case 51:this.$={id1:a[s-4],id2:a[s],relation:a[s-2],relationTitle1:a[s-3],relationTitle2:a[s-1]};break;case 52:this.$={type1:a[s-2],type2:a[s],lineType:a[s-1]};break;case 53:this.$={type1:"none",type2:a[s],lineType:a[s-1]};break;case 54:this.$={type1:a[s-1],type2:"none",lineType:a[s]};break;case 55:this.$={type1:"none",type2:"none",lineType:a[s]};break;case 56:this.$=r.relationType.AGGREGATION;break;case 57:this.$=r.relationType.EXTENSION;break;case 58:this.$=r.relationType.COMPOSITION;break;case 59:this.$=r.relationType.DEPENDENCY;break;case 60:this.$=r.lineType.LINE;break;case 61:this.$=r.lineType.DOTTED_LINE;break;case 62:case 68:this.$=a[s-2],r.setClickEvent(a[s-1],a[s]);break;case 63:case 69:this.$=a[s-3],r.setClickEvent(a[s-2],a[s-1]),r.setTooltip(a[s-2],a[s]);break;case 64:case 72:this.$=a[s-2],r.setLink(a[s-1],a[s]);break;case 65:case 73:this.$=a[s-3],r.setLink(a[s-2],a[s-1],a[s]);break;case 66:case 74:this.$=a[s-3],r.setLink(a[s-2],a[s-1]),r.setTooltip(a[s-2],a[s]);break;case 67:case 75:this.$=a[s-4],r.setLink(a[s-3],a[s-2],a[s]),r.setTooltip(a[s-3],a[s-1]);break;case 70:this.$=a[s-3],r.setClickEvent(a[s-2],a[s-1],a[s]);break;case 71:this.$=a[s-4],r.setClickEvent(a[s-3],a[s-2],a[s-1]),r.setTooltip(a[s-3],a[s]);break;case 76:r.setCssClass(a[s-1],a[s])}},table:[{3:1,4:2,5:e,6:4,7:5,8:n,9:r,10:i,11:a,12:6,13:11,19:o,23:s},{1:[3]},{1:[2,1]},{1:[2,2]},{1:[2,3]},{3:14,4:2,5:e,6:4,7:5,8:n,9:r,10:i,11:a,12:6,13:11,19:o,23:s},{1:[2,9]},t(c,[2,5]),t(c,[2,6]),t(c,[2,7]),t(c,[2,8]),{14:15,20:[1,16]},{16:[1,17]},{20:[2,12]},{1:[2,4]},{15:18,17:[1,19],22:u},t([17,22],[2,13]),{6:30,7:29,8:n,9:r,10:i,11:a,13:11,19:o,24:21,26:22,27:34,28:43,29:44,31:23,33:24,34:25,35:26,36:27,37:28,38:l,40:h,42:f,43:d,48:p,50:g,51:y,62:m,63:v,65:b,69:_,83:x,84:w,85:k,86:T},{16:[1,49]},{18:50,21:[1,51]},{16:[2,15]},{25:[1,52]},{16:[1,53],25:[2,17]},t(C,[2,25],{32:[1,54]}),t(C,[2,27]),t(C,[2,28]),t(C,[2,29]),t(C,[2,30]),t(C,[2,31]),t(C,[2,32]),t(C,[2,33]),{39:[1,55]},{41:[1,56]},t(C,[2,36]),t(C,[2,44],{52:57,54:60,55:61,32:[1,59],53:[1,58],56:E,57:S,58:A,59:M,60:N,61:D}),{27:68,28:43,29:44,83:x,84:w,85:k,86:T},t(C,[2,46]),t(C,[2,47]),{28:69,83:x,84:w,85:k},{27:70,28:43,29:44,83:x,84:w,85:k,86:T},{27:71,28:43,29:44,83:x,84:w,85:k,86:T},{27:72,28:43,29:44,83:x,84:w,85:k,86:T},{53:[1,73]},t(B,[2,20],{28:43,29:44,27:74,30:[1,75],83:x,84:w,85:k,86:T}),t(B,[2,21],{30:[1,76]}),t(L,[2,90]),t(L,[2,91]),t(L,[2,92]),t([16,25,30,32,44,45,53,56,57,58,59,60,61,66,68],[2,93]),t(O,[2,10]),{15:77,22:u},{22:[2,14]},{1:[2,16]},{6:30,7:29,8:n,9:r,10:i,11:a,13:11,19:o,24:78,25:[2,18],26:22,27:34,28:43,29:44,31:23,33:24,34:25,35:26,36:27,37:28,38:l,40:h,42:f,43:d,48:p,50:g,51:y,62:m,63:v,65:b,69:_,83:x,84:w,85:k,86:T},t(C,[2,26]),t(C,[2,34]),t(C,[2,35]),{27:79,28:43,29:44,53:[1,80],83:x,84:w,85:k,86:T},{52:81,54:60,55:61,56:E,57:S,58:A,59:M,60:N,61:D},t(C,[2,45]),{55:82,60:N,61:D},t(I,[2,55],{54:83,56:E,57:S,58:A,59:M}),t(R,[2,56]),t(R,[2,57]),t(R,[2,58]),t(R,[2,59]),t(F,[2,60]),t(F,[2,61]),t(C,[2,37],{44:[1,84],45:[1,85]}),{49:[1,86]},{53:[1,87]},{53:[1,88]},{66:[1,89],68:[1,90]},{28:91,83:x,84:w,85:k},t(B,[2,22]),t(B,[2,23]),t(B,[2,24]),{16:[1,92]},{25:[2,19]},t(P,[2,48]),{27:93,28:43,29:44,83:x,84:w,85:k,86:T},{27:94,28:43,29:44,53:[1,95],83:x,84:w,85:k,86:T},t(I,[2,54],{54:96,56:E,57:S,58:A,59:M}),t(I,[2,53]),{28:97,83:x,84:w,85:k},{46:98,50:Y},{27:100,28:43,29:44,83:x,84:w,85:k,86:T},t(C,[2,62],{53:[1,101]}),t(C,[2,64],{53:[1,103],64:[1,102]}),t(C,[2,68],{53:[1,104],67:[1,105]}),t(C,[2,72],{53:[1,107],64:[1,106]}),t(C,[2,76]),t(O,[2,11]),t(P,[2,50]),t(P,[2,49]),{27:108,28:43,29:44,83:x,84:w,85:k,86:T},t(I,[2,52]),t(C,[2,38],{45:[1,109]}),{47:[1,110]},{46:111,47:[2,42],50:Y},t(C,[2,41]),t(C,[2,63]),t(C,[2,65]),t(C,[2,66],{64:[1,112]}),t(C,[2,69]),t(C,[2,70],{53:[1,113]}),t(C,[2,73]),t(C,[2,74],{64:[1,114]}),t(P,[2,51]),{46:115,50:Y},t(C,[2,39]),{47:[2,43]},t(C,[2,67]),t(C,[2,71]),t(C,[2,75]),{47:[1,116]},t(C,[2,40])],defaultActions:{2:[2,1],3:[2,2],4:[2,3],6:[2,9],13:[2,12],14:[2,4],20:[2,15],51:[2,14],52:[2,16],78:[2,19],111:[2,43]},parseError:function(t,e){if(!e.recoverable){var n=new Error(t);throw n.hash=e,n}this.trace(t)},parse:function(t){var e=this,n=[0],r=[],i=[null],a=[],o=this.table,s="",c=0,u=0,l=0,h=2,f=1,d=a.slice.call(arguments,1),p=Object.create(this.lexer),g={yy:{}};for(var y in this.yy)Object.prototype.hasOwnProperty.call(this.yy,y)&&(g.yy[y]=this.yy[y]);p.setInput(t,g.yy),g.yy.lexer=p,g.yy.parser=this,void 0===p.yylloc&&(p.yylloc={});var m=p.yylloc;a.push(m);var v=p.options&&p.options.ranges;function b(){var t;return"number"!=typeof(t=r.pop()||p.lex()||f)&&(t instanceof Array&&(t=(r=t).pop()),t=e.symbols_[t]||t),t}"function"==typeof g.yy.parseError?this.parseError=g.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;for(var _,x,w,k,T,C,E,S,A,M={};;){if(w=n[n.length-1],this.defaultActions[w]?k=this.defaultActions[w]:(null==_&&(_=b()),k=o[w]&&o[w][_]),void 0===k||!k.length||!k[0]){var N="";for(C in A=[],o[w])this.terminals_[C]&&C>h&&A.push("'"+this.terminals_[C]+"'");N=p.showPosition?"Parse error on line "+(c+1)+":\n"+p.showPosition()+"\nExpecting "+A.join(", ")+", got '"+(this.terminals_[_]||_)+"'":"Parse error on line "+(c+1)+": Unexpected "+(_==f?"end of input":"'"+(this.terminals_[_]||_)+"'"),this.parseError(N,{text:p.match,token:this.terminals_[_]||_,line:p.yylineno,loc:m,expected:A})}if(k[0]instanceof Array&&k.length>1)throw new Error("Parse Error: multiple actions possible at state: "+w+", token: "+_);switch(k[0]){case 1:n.push(_),i.push(p.yytext),a.push(p.yylloc),n.push(k[1]),_=null,x?(_=x,x=null):(u=p.yyleng,s=p.yytext,c=p.yylineno,m=p.yylloc,l>0&&l--);break;case 2:if(E=this.productions_[k[1]][1],M.$=i[i.length-E],M._$={first_line:a[a.length-(E||1)].first_line,last_line:a[a.length-1].last_line,first_column:a[a.length-(E||1)].first_column,last_column:a[a.length-1].last_column},v&&(M._$.range=[a[a.length-(E||1)].range[0],a[a.length-1].range[1]]),void 0!==(T=this.performAction.apply(M,[s,u,c,g.yy,k[1],i,a].concat(d))))return T;E&&(n=n.slice(0,-1*E*2),i=i.slice(0,-1*E),a=a.slice(0,-1*E)),n.push(this.productions_[k[1]][0]),i.push(M.$),a.push(M._$),S=o[n[n.length-2]][n[n.length-1]],n.push(S);break;case 3:return!0}}return!0}},U={EOF:1,parseError:function(t,e){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,e)},setInput:function(t,e){return this.yy=e||this.yy||{},this._input=t,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},input:function(){var t=this._input[0];return this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t,t.match(/(?:\r\n?|\n).*/g)?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),t},unput:function(t){var e=t.length,n=t.split(/(?:\r\n?|\n)/g);this._input=t+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-e),this.offset-=e;var r=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),n.length-1&&(this.yylineno-=n.length-1);var i=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:n?(n.length===r.length?this.yylloc.first_column:0)+r[r.length-n.length].length-n[0].length:this.yylloc.first_column-e},this.options.ranges&&(this.yylloc.range=[i[0],i[0]+this.yyleng-e]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject:function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):this.parseError("Lexical error on line "+(this.yylineno+1)+". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},less:function(t){this.unput(this.match.slice(t))},pastInput:function(){var t=this.matched.substr(0,this.matched.length-this.match.length);return(t.length>20?"...":"")+t.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var t=this.match;return t.length<20&&(t+=this._input.substr(0,20-t.length)),(t.substr(0,20)+(t.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var t=this.pastInput(),e=new Array(t.length+1).join("-");return t+this.upcomingInput()+"\n"+e+"^"},test_match:function(t,e){var n,r,i;if(this.options.backtrack_lexer&&(i={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(i.yylloc.range=this.yylloc.range.slice(0))),(r=t[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=r.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:r?r[r.length-1].length-r[r.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],n=this.performAction.call(this,this.yy,this,e,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),n)return n;if(this._backtrack){for(var a in i)this[a]=i[a];return!1}return!1},next:function(){if(this.done)return this.EOF;var t,e,n,r;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var i=this._currentRules(),a=0;ae[0].length)){if(e=n,r=a,this.options.backtrack_lexer){if(!1!==(t=this.test_match(n,i[a])))return t;if(this._backtrack){e=!1;continue}return!1}if(!this.options.flex)break}return e?!1!==(t=this.test_match(e,i[r]))&&t:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){return this.next()||this.lex()},begin:function(t){this.conditionStack.push(t)},popState:function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]},_currentRules:function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},topState:function(t){return(t=this.conditionStack.length-1-Math.abs(t||0))>=0?this.conditionStack[t]:"INITIAL"},pushState:function(t){this.begin(t)},stateStackSize:function(){return this.conditionStack.length},options:{},performAction:function(t,e,n,r){switch(n){case 0:return this.begin("open_directive"),19;case 1:return 8;case 2:return 9;case 3:return 10;case 4:return 11;case 5:return this.begin("type_directive"),20;case 6:return this.popState(),this.begin("arg_directive"),17;case 7:return this.popState(),this.popState(),22;case 8:return 21;case 9:case 10:case 19:case 26:break;case 11:return this.begin("acc_title"),38;case 12:return this.popState(),"acc_title_value";case 13:return this.begin("acc_descr"),40;case 14:return this.popState(),"acc_descr_value";case 15:this.begin("acc_descr_multiline");break;case 16:case 36:case 39:case 42:case 45:case 48:case 51:this.popState();break;case 17:return"acc_descr_multiline_value";case 18:return 16;case 20:case 21:return 23;case 22:return this.begin("struct"),45;case 23:return"EOF_IN_STRUCT";case 24:return"OPEN_IN_STRUCT";case 25:return this.popState(),47;case 27:return"MEMBER";case 28:return 43;case 29:return 69;case 30:return 62;case 31:return 63;case 32:return 65;case 33:return 48;case 34:return 49;case 35:this.begin("generic");break;case 37:return"GENERICTYPE";case 38:this.begin("string");break;case 40:return"STR";case 41:this.begin("bqstring");break;case 43:return"BQUOTE_STR";case 44:this.begin("href");break;case 46:return 68;case 47:this.begin("callback_name");break;case 49:this.popState(),this.begin("callback_args");break;case 50:return 66;case 52:return 67;case 53:case 54:case 55:case 56:return 64;case 57:case 58:return 57;case 59:case 60:return 59;case 61:return 58;case 62:return 56;case 63:return 60;case 64:return 61;case 65:return 32;case 66:return 44;case 67:return 81;case 68:return"DOT";case 69:return"PLUS";case 70:return 78;case 71:case 72:return"EQUALS";case 73:return 85;case 74:return"PUNCTUATION";case 75:return 84;case 76:return 83;case 77:return 80;case 78:return 25}},rules:[/^(?:%%\{)/,/^(?:.*direction\s+TB[^\n]*)/,/^(?:.*direction\s+BT[^\n]*)/,/^(?:.*direction\s+RL[^\n]*)/,/^(?:.*direction\s+LR[^\n]*)/,/^(?:((?:(?!\}%%)[^:.])*))/,/^(?::)/,/^(?:\}%%)/,/^(?:((?:(?!\}%%).|\n)*))/,/^(?:%%(?!\{)*[^\n]*(\r?\n?)+)/,/^(?:%%[^\n]*(\r?\n)*)/,/^(?:accTitle\s*:\s*)/,/^(?:(?!\n||)*[^\n]*)/,/^(?:accDescr\s*:\s*)/,/^(?:(?!\n||)*[^\n]*)/,/^(?:accDescr\s*\{\s*)/,/^(?:[\}])/,/^(?:[^\}]*)/,/^(?:\s*(\r?\n)+)/,/^(?:\s+)/,/^(?:classDiagram-v2\b)/,/^(?:classDiagram\b)/,/^(?:[{])/,/^(?:$)/,/^(?:[{])/,/^(?:[}])/,/^(?:[\n])/,/^(?:[^{}\n]*)/,/^(?:class\b)/,/^(?:cssClass\b)/,/^(?:callback\b)/,/^(?:link\b)/,/^(?:click\b)/,/^(?:<<)/,/^(?:>>)/,/^(?:[~])/,/^(?:[~])/,/^(?:[^~]*)/,/^(?:["])/,/^(?:["])/,/^(?:[^"]*)/,/^(?:[`])/,/^(?:[`])/,/^(?:[^`]+)/,/^(?:href[\s]+["])/,/^(?:["])/,/^(?:[^"]*)/,/^(?:call[\s]+)/,/^(?:\([\s]*\))/,/^(?:\()/,/^(?:[^(]*)/,/^(?:\))/,/^(?:[^)]*)/,/^(?:_self\b)/,/^(?:_blank\b)/,/^(?:_parent\b)/,/^(?:_top\b)/,/^(?:\s*<\|)/,/^(?:\s*\|>)/,/^(?:\s*>)/,/^(?:\s*<)/,/^(?:\s*\*)/,/^(?:\s*o\b)/,/^(?:--)/,/^(?:\.\.)/,/^(?::{1}[^:\n;]+)/,/^(?::{3})/,/^(?:-)/,/^(?:\.)/,/^(?:\+)/,/^(?:%)/,/^(?:=)/,/^(?:=)/,/^(?:\w+)/,/^(?:[!"#$%&'*+,-.`?\\/])/,/^(?:[0-9]+)/,/^(?:[\u00AA\u00B5\u00BA\u00C0-\u00D6\u00D8-\u00F6]|[\u00F8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377]|[\u037A-\u037D\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5]|[\u03F7-\u0481\u048A-\u0527\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA]|[\u05F0-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE]|[\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA]|[\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u08A0]|[\u08A2-\u08AC\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0977]|[\u0979-\u097F\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2]|[\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u0A05-\u0A0A]|[\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39]|[\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8]|[\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0B05-\u0B0C]|[\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C]|[\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99]|[\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0]|[\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C33\u0C35-\u0C39\u0C3D]|[\u0C58\u0C59\u0C60\u0C61\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3]|[\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10]|[\u0D12-\u0D3A\u0D3D\u0D4E\u0D60\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1]|[\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81]|[\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3]|[\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6]|[\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A]|[\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081]|[\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D]|[\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0]|[\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310]|[\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F4\u1401-\u166C]|[\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u1700-\u170C\u170E-\u1711]|[\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7]|[\u17DC\u1820-\u1877\u1880-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191C]|[\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19C1-\u19C7\u1A00-\u1A16]|[\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF]|[\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1CE9-\u1CEC]|[\u1CEE-\u1CF1\u1CF5\u1CF6\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D]|[\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D]|[\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3]|[\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F]|[\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128]|[\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2183\u2184]|[\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3]|[\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6]|[\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE]|[\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005\u3006\u3031-\u3035\u303B\u303C]|[\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D]|[\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FCC]|[\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B]|[\uA640-\uA66E\uA67F-\uA697\uA6A0-\uA6E5\uA717-\uA71F\uA722-\uA788]|[\uA78B-\uA78E\uA790-\uA793\uA7A0-\uA7AA\uA7F8-\uA801\uA803-\uA805]|[\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB]|[\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uAA00-\uAA28]|[\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA80-\uAAAF\uAAB1\uAAB5]|[\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4]|[\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E]|[\uABC0-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D]|[\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36]|[\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D]|[\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC]|[\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF]|[\uFFD2-\uFFD7\uFFDA-\uFFDC])/,/^(?:\s)/,/^(?:$)/],conditions:{acc_descr_multiline:{rules:[16,17],inclusive:!1},acc_descr:{rules:[14],inclusive:!1},acc_title:{rules:[12],inclusive:!1},arg_directive:{rules:[7,8],inclusive:!1},type_directive:{rules:[6,7],inclusive:!1},open_directive:{rules:[5],inclusive:!1},callback_args:{rules:[51,52],inclusive:!1},callback_name:{rules:[48,49,50],inclusive:!1},href:{rules:[45,46],inclusive:!1},struct:{rules:[23,24,25,26,27],inclusive:!1},generic:{rules:[36,37],inclusive:!1},bqstring:{rules:[42,43],inclusive:!1},string:{rules:[39,40],inclusive:!1},INITIAL:{rules:[0,1,2,3,4,9,10,11,13,15,18,19,20,21,22,28,29,30,31,32,33,34,35,38,41,44,47,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78],inclusive:!0}}};function z(){this.yy={}}return j.lexer=U,z.prototype=j,j.Parser=z,new z}();e.parser=r,e.Parser=r.Parser,e.parse=function(){return r.parse.apply(r,arguments)},e.main=function(t){t[1]||(console.log("Usage: "+t[0]+" FILE"),process.exit(1));var r=n(8218).readFileSync(n(6470).normalize(t[1]),"utf8");return e.parser.parse(r)},n.c[n.s]===t&&e.main(process.argv.slice(1))},5890:(t,e,n)=>{t=n.nmd(t);var r=function(){var t=function(t,e,n,r){for(n=n||{},r=t.length;r--;n[t[r]]=e);return n},e=[1,2],n=[1,5],r=[6,9,11,23,25,27,29,30,48],i=[1,17],a=[1,18],o=[1,19],s=[1,20],c=[1,21],u=[1,24],l=[1,29],h=[1,30],f=[1,31],d=[1,32],p=[1,44],g=[30,45,46],y=[4,6,9,11,23,25,27,29,30,48],m=[41,42,43,44],v=[22,36],b=[1,62],_={trace:function(){},yy:{},symbols_:{error:2,start:3,ER_DIAGRAM:4,document:5,EOF:6,directive:7,line:8,SPACE:9,statement:10,NEWLINE:11,openDirective:12,typeDirective:13,closeDirective:14,":":15,argDirective:16,entityName:17,relSpec:18,role:19,BLOCK_START:20,attributes:21,BLOCK_STOP:22,title:23,title_value:24,acc_title:25,acc_title_value:26,acc_descr:27,acc_descr_value:28,acc_descr_multiline_value:29,ALPHANUM:30,attribute:31,attributeType:32,attributeName:33,attributeKeyType:34,attributeComment:35,ATTRIBUTE_WORD:36,ATTRIBUTE_KEY:37,COMMENT:38,cardinality:39,relType:40,ZERO_OR_ONE:41,ZERO_OR_MORE:42,ONE_OR_MORE:43,ONLY_ONE:44,NON_IDENTIFYING:45,IDENTIFYING:46,WORD:47,open_directive:48,type_directive:49,arg_directive:50,close_directive:51,$accept:0,$end:1},terminals_:{2:"error",4:"ER_DIAGRAM",6:"EOF",9:"SPACE",11:"NEWLINE",15:":",20:"BLOCK_START",22:"BLOCK_STOP",23:"title",24:"title_value",25:"acc_title",26:"acc_title_value",27:"acc_descr",28:"acc_descr_value",29:"acc_descr_multiline_value",30:"ALPHANUM",36:"ATTRIBUTE_WORD",37:"ATTRIBUTE_KEY",38:"COMMENT",41:"ZERO_OR_ONE",42:"ZERO_OR_MORE",43:"ONE_OR_MORE",44:"ONLY_ONE",45:"NON_IDENTIFYING",46:"IDENTIFYING",47:"WORD",48:"open_directive",49:"type_directive",50:"arg_directive",51:"close_directive"},productions_:[0,[3,3],[3,2],[5,0],[5,2],[8,2],[8,1],[8,1],[8,1],[7,4],[7,6],[10,1],[10,5],[10,4],[10,3],[10,1],[10,2],[10,2],[10,2],[10,1],[17,1],[21,1],[21,2],[31,2],[31,3],[31,3],[31,4],[32,1],[33,1],[34,1],[35,1],[18,3],[39,1],[39,1],[39,1],[39,1],[40,1],[40,1],[19,1],[19,1],[12,1],[13,1],[16,1],[14,1]],performAction:function(t,e,n,r,i,a,o){var s=a.length-1;switch(i){case 1:break;case 3:case 7:case 8:this.$=[];break;case 4:a[s-1].push(a[s]),this.$=a[s-1];break;case 5:case 6:case 20:case 27:case 28:case 29:case 39:this.$=a[s];break;case 12:r.addEntity(a[s-4]),r.addEntity(a[s-2]),r.addRelationship(a[s-4],a[s],a[s-2],a[s-3]);break;case 13:r.addEntity(a[s-3]),r.addAttributes(a[s-3],a[s-1]);break;case 14:r.addEntity(a[s-2]);break;case 15:r.addEntity(a[s]);break;case 16:case 17:this.$=a[s].trim(),r.setTitle(this.$);break;case 18:case 19:this.$=a[s].trim(),r.setAccDescription(this.$);break;case 21:this.$=[a[s]];break;case 22:a[s].push(a[s-1]),this.$=a[s];break;case 23:this.$={attributeType:a[s-1],attributeName:a[s]};break;case 24:this.$={attributeType:a[s-2],attributeName:a[s-1],attributeKeyType:a[s]};break;case 25:this.$={attributeType:a[s-2],attributeName:a[s-1],attributeComment:a[s]};break;case 26:this.$={attributeType:a[s-3],attributeName:a[s-2],attributeKeyType:a[s-1],attributeComment:a[s]};break;case 30:case 38:this.$=a[s].replace(/"/g,"");break;case 31:this.$={cardA:a[s],relType:a[s-1],cardB:a[s-2]};break;case 32:this.$=r.Cardinality.ZERO_OR_ONE;break;case 33:this.$=r.Cardinality.ZERO_OR_MORE;break;case 34:this.$=r.Cardinality.ONE_OR_MORE;break;case 35:this.$=r.Cardinality.ONLY_ONE;break;case 36:this.$=r.Identification.NON_IDENTIFYING;break;case 37:this.$=r.Identification.IDENTIFYING;break;case 40:r.parseDirective("%%{","open_directive");break;case 41:r.parseDirective(a[s],"type_directive");break;case 42:a[s]=a[s].trim().replace(/'/g,'"'),r.parseDirective(a[s],"arg_directive");break;case 43:r.parseDirective("}%%","close_directive","er")}},table:[{3:1,4:e,7:3,12:4,48:n},{1:[3]},t(r,[2,3],{5:6}),{3:7,4:e,7:3,12:4,48:n},{13:8,49:[1,9]},{49:[2,40]},{6:[1,10],7:15,8:11,9:[1,12],10:13,11:[1,14],12:4,17:16,23:i,25:a,27:o,29:s,30:c,48:n},{1:[2,2]},{14:22,15:[1,23],51:u},t([15,51],[2,41]),t(r,[2,8],{1:[2,1]}),t(r,[2,4]),{7:15,10:25,12:4,17:16,23:i,25:a,27:o,29:s,30:c,48:n},t(r,[2,6]),t(r,[2,7]),t(r,[2,11]),t(r,[2,15],{18:26,39:28,20:[1,27],41:l,42:h,43:f,44:d}),{24:[1,33]},{26:[1,34]},{28:[1,35]},t(r,[2,19]),t([6,9,11,15,20,23,25,27,29,30,41,42,43,44,48],[2,20]),{11:[1,36]},{16:37,50:[1,38]},{11:[2,43]},t(r,[2,5]),{17:39,30:c},{21:40,22:[1,41],31:42,32:43,36:p},{40:45,45:[1,46],46:[1,47]},t(g,[2,32]),t(g,[2,33]),t(g,[2,34]),t(g,[2,35]),t(r,[2,16]),t(r,[2,17]),t(r,[2,18]),t(y,[2,9]),{14:48,51:u},{51:[2,42]},{15:[1,49]},{22:[1,50]},t(r,[2,14]),{21:51,22:[2,21],31:42,32:43,36:p},{33:52,36:[1,53]},{36:[2,27]},{39:54,41:l,42:h,43:f,44:d},t(m,[2,36]),t(m,[2,37]),{11:[1,55]},{19:56,30:[1,58],47:[1,57]},t(r,[2,13]),{22:[2,22]},t(v,[2,23],{34:59,35:60,37:[1,61],38:b}),t([22,36,37,38],[2,28]),{30:[2,31]},t(y,[2,10]),t(r,[2,12]),t(r,[2,38]),t(r,[2,39]),t(v,[2,24],{35:63,38:b}),t(v,[2,25]),t([22,36,38],[2,29]),t(v,[2,30]),t(v,[2,26])],defaultActions:{5:[2,40],7:[2,2],24:[2,43],38:[2,42],44:[2,27],51:[2,22],54:[2,31]},parseError:function(t,e){if(!e.recoverable){var n=new Error(t);throw n.hash=e,n}this.trace(t)},parse:function(t){var e=this,n=[0],r=[],i=[null],a=[],o=this.table,s="",c=0,u=0,l=0,h=2,f=1,d=a.slice.call(arguments,1),p=Object.create(this.lexer),g={yy:{}};for(var y in this.yy)Object.prototype.hasOwnProperty.call(this.yy,y)&&(g.yy[y]=this.yy[y]);p.setInput(t,g.yy),g.yy.lexer=p,g.yy.parser=this,void 0===p.yylloc&&(p.yylloc={});var m=p.yylloc;a.push(m);var v=p.options&&p.options.ranges;function b(){var t;return"number"!=typeof(t=r.pop()||p.lex()||f)&&(t instanceof Array&&(t=(r=t).pop()),t=e.symbols_[t]||t),t}"function"==typeof g.yy.parseError?this.parseError=g.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;for(var _,x,w,k,T,C,E,S,A,M={};;){if(w=n[n.length-1],this.defaultActions[w]?k=this.defaultActions[w]:(null==_&&(_=b()),k=o[w]&&o[w][_]),void 0===k||!k.length||!k[0]){var N="";for(C in A=[],o[w])this.terminals_[C]&&C>h&&A.push("'"+this.terminals_[C]+"'");N=p.showPosition?"Parse error on line "+(c+1)+":\n"+p.showPosition()+"\nExpecting "+A.join(", ")+", got '"+(this.terminals_[_]||_)+"'":"Parse error on line "+(c+1)+": Unexpected "+(_==f?"end of input":"'"+(this.terminals_[_]||_)+"'"),this.parseError(N,{text:p.match,token:this.terminals_[_]||_,line:p.yylineno,loc:m,expected:A})}if(k[0]instanceof Array&&k.length>1)throw new Error("Parse Error: multiple actions possible at state: "+w+", token: "+_);switch(k[0]){case 1:n.push(_),i.push(p.yytext),a.push(p.yylloc),n.push(k[1]),_=null,x?(_=x,x=null):(u=p.yyleng,s=p.yytext,c=p.yylineno,m=p.yylloc,l>0&&l--);break;case 2:if(E=this.productions_[k[1]][1],M.$=i[i.length-E],M._$={first_line:a[a.length-(E||1)].first_line,last_line:a[a.length-1].last_line,first_column:a[a.length-(E||1)].first_column,last_column:a[a.length-1].last_column},v&&(M._$.range=[a[a.length-(E||1)].range[0],a[a.length-1].range[1]]),void 0!==(T=this.performAction.apply(M,[s,u,c,g.yy,k[1],i,a].concat(d))))return T;E&&(n=n.slice(0,-1*E*2),i=i.slice(0,-1*E),a=a.slice(0,-1*E)),n.push(this.productions_[k[1]][0]),i.push(M.$),a.push(M._$),S=o[n[n.length-2]][n[n.length-1]],n.push(S);break;case 3:return!0}}return!0}},x={EOF:1,parseError:function(t,e){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,e)},setInput:function(t,e){return this.yy=e||this.yy||{},this._input=t,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},input:function(){var t=this._input[0];return this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t,t.match(/(?:\r\n?|\n).*/g)?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),t},unput:function(t){var e=t.length,n=t.split(/(?:\r\n?|\n)/g);this._input=t+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-e),this.offset-=e;var r=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),n.length-1&&(this.yylineno-=n.length-1);var i=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:n?(n.length===r.length?this.yylloc.first_column:0)+r[r.length-n.length].length-n[0].length:this.yylloc.first_column-e},this.options.ranges&&(this.yylloc.range=[i[0],i[0]+this.yyleng-e]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject:function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):this.parseError("Lexical error on line "+(this.yylineno+1)+". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},less:function(t){this.unput(this.match.slice(t))},pastInput:function(){var t=this.matched.substr(0,this.matched.length-this.match.length);return(t.length>20?"...":"")+t.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var t=this.match;return t.length<20&&(t+=this._input.substr(0,20-t.length)),(t.substr(0,20)+(t.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var t=this.pastInput(),e=new Array(t.length+1).join("-");return t+this.upcomingInput()+"\n"+e+"^"},test_match:function(t,e){var n,r,i;if(this.options.backtrack_lexer&&(i={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(i.yylloc.range=this.yylloc.range.slice(0))),(r=t[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=r.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:r?r[r.length-1].length-r[r.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],n=this.performAction.call(this,this.yy,this,e,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),n)return n;if(this._backtrack){for(var a in i)this[a]=i[a];return!1}return!1},next:function(){if(this.done)return this.EOF;var t,e,n,r;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var i=this._currentRules(),a=0;ae[0].length)){if(e=n,r=a,this.options.backtrack_lexer){if(!1!==(t=this.test_match(n,i[a])))return t;if(this._backtrack){e=!1;continue}return!1}if(!this.options.flex)break}return e?!1!==(t=this.test_match(e,i[r]))&&t:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){return this.next()||this.lex()},begin:function(t){this.conditionStack.push(t)},popState:function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]},_currentRules:function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},topState:function(t){return(t=this.conditionStack.length-1-Math.abs(t||0))>=0?this.conditionStack[t]:"INITIAL"},pushState:function(t){this.begin(t)},stateStackSize:function(){return this.conditionStack.length},options:{"case-insensitive":!0},performAction:function(t,e,n,r){switch(n){case 0:return this.begin("acc_title"),25;case 1:return this.popState(),"acc_title_value";case 2:return this.begin("acc_descr"),27;case 3:return this.popState(),"acc_descr_value";case 4:this.begin("acc_descr_multiline");break;case 5:this.popState();break;case 6:return"acc_descr_multiline_value";case 7:return this.begin("open_directive"),48;case 8:return this.begin("type_directive"),49;case 9:return this.popState(),this.begin("arg_directive"),15;case 10:return this.popState(),this.popState(),51;case 11:return 50;case 12:case 13:case 15:case 20:case 24:break;case 14:return 11;case 16:return 9;case 17:return 47;case 18:return 4;case 19:return this.begin("block"),20;case 21:return 37;case 22:return 36;case 23:return 38;case 25:return this.popState(),22;case 26:case 39:return e.yytext[0];case 27:case 31:return 41;case 28:case 32:return 42;case 29:case 33:return 43;case 30:return 44;case 34:case 36:case 37:return 45;case 35:return 46;case 38:return 30;case 40:return 6}},rules:[/^(?:accTitle\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*\{\s*)/i,/^(?:[\}])/i,/^(?:[^\}]*)/i,/^(?:%%\{)/i,/^(?:((?:(?!\}%%)[^:.])*))/i,/^(?::)/i,/^(?:\}%%)/i,/^(?:((?:(?!\}%%).|\n)*))/i,/^(?:%(?!\{)[^\n]*)/i,/^(?:[^\}]%%[^\n]*)/i,/^(?:[\n]+)/i,/^(?:\s+)/i,/^(?:[\s]+)/i,/^(?:"[^"]*")/i,/^(?:erDiagram\b)/i,/^(?:\{)/i,/^(?:\s+)/i,/^(?:(?:PK)|(?:FK))/i,/^(?:[A-Za-z][A-Za-z0-9\-_]*)/i,/^(?:"[^"]*")/i,/^(?:[\n]+)/i,/^(?:\})/i,/^(?:.)/i,/^(?:\|o\b)/i,/^(?:\}o\b)/i,/^(?:\}\|)/i,/^(?:\|\|)/i,/^(?:o\|)/i,/^(?:o\{)/i,/^(?:\|\{)/i,/^(?:\.\.)/i,/^(?:--)/i,/^(?:\.-)/i,/^(?:-\.)/i,/^(?:[A-Za-z][A-Za-z0-9\-_]*)/i,/^(?:.)/i,/^(?:$)/i],conditions:{acc_descr_multiline:{rules:[5,6],inclusive:!1},acc_descr:{rules:[3],inclusive:!1},acc_title:{rules:[1],inclusive:!1},open_directive:{rules:[8],inclusive:!1},type_directive:{rules:[9,10],inclusive:!1},arg_directive:{rules:[10,11],inclusive:!1},block:{rules:[20,21,22,23,24,25,26],inclusive:!1},INITIAL:{rules:[0,2,4,7,12,13,14,15,16,17,18,19,27,28,29,30,31,32,33,34,35,36,37,38,39,40],inclusive:!0}}};function w(){this.yy={}}return _.lexer=x,w.prototype=_,_.Parser=w,new w}();e.parser=r,e.Parser=r.Parser,e.parse=function(){return r.parse.apply(r,arguments)},e.main=function(t){t[1]||(console.log("Usage: "+t[0]+" FILE"),process.exit(1));var r=n(8009).readFileSync(n(6470).normalize(t[1]),"utf8");return e.parser.parse(r)},n.c[n.s]===t&&e.main(process.argv.slice(1))},3602:(t,e,n)=>{t=n.nmd(t);var r=function(){var t=function(t,e,n,r){for(n=n||{},r=t.length;r--;n[t[r]]=e);return n},e=[1,9],n=[1,7],r=[1,6],i=[1,8],a=[1,20,21,22,23,38,44,46,48,52,66,67,86,87,88,89,90,91,95,105,106,109,111,112,118,119,120,121,122,123,124,125,126,127],o=[2,10],s=[1,20],c=[1,21],u=[1,22],l=[1,23],h=[1,30],f=[1,32],d=[1,33],p=[1,34],g=[1,62],y=[1,48],m=[1,52],v=[1,36],b=[1,37],_=[1,38],x=[1,39],w=[1,40],k=[1,56],T=[1,63],C=[1,51],E=[1,53],S=[1,55],A=[1,59],M=[1,60],N=[1,41],D=[1,42],B=[1,43],L=[1,44],O=[1,61],I=[1,50],R=[1,54],F=[1,57],P=[1,58],Y=[1,49],j=[1,66],U=[1,71],z=[1,20,21,22,23,38,42,44,46,48,52,66,67,86,87,88,89,90,91,95,105,106,109,111,112,118,119,120,121,122,123,124,125,126,127],$=[1,75],q=[1,74],H=[1,76],W=[20,21,23,81,82],V=[1,99],G=[1,104],X=[1,107],Z=[1,108],Q=[1,101],K=[1,106],J=[1,109],tt=[1,102],et=[1,114],nt=[1,113],rt=[1,103],it=[1,105],at=[1,110],ot=[1,111],st=[1,112],ct=[1,115],ut=[20,21,22,23,81,82],lt=[20,21,22,23,53,81,82],ht=[20,21,22,23,40,52,53,55,57,59,61,63,65,66,67,69,71,73,74,76,81,82,91,95,105,106,109,111,112,122,123,124,125,126,127],ft=[20,21,23],dt=[20,21,23,52,66,67,81,82,91,95,105,106,109,111,112,122,123,124,125,126,127],pt=[1,12,20,21,22,23,24,38,42,44,46,48,52,66,67,86,87,88,89,90,91,95,105,106,109,111,112,118,119,120,121,122,123,124,125,126,127],gt=[52,66,67,91,95,105,106,109,111,112,122,123,124,125,126,127],yt=[1,149],mt=[1,157],vt=[1,158],bt=[1,159],_t=[1,160],xt=[1,144],wt=[1,145],kt=[1,141],Tt=[1,152],Ct=[1,153],Et=[1,154],St=[1,155],At=[1,156],Mt=[1,161],Nt=[1,162],Dt=[1,147],Bt=[1,150],Lt=[1,146],Ot=[1,143],It=[20,21,22,23,38,42,44,46,48,52,66,67,86,87,88,89,90,91,95,105,106,109,111,112,118,119,120,121,122,123,124,125,126,127],Rt=[1,165],Ft=[20,21,22,23,26,52,66,67,91,105,106,109,111,112,122,123,124,125,126,127],Pt=[20,21,22,23,24,26,38,40,41,42,52,56,58,60,62,64,66,67,68,70,72,73,75,77,81,82,86,87,88,89,90,91,92,95,105,106,109,111,112,113,114,122,123,124,125,126,127],Yt=[12,21,22,24],jt=[22,106],Ut=[1,250],zt=[1,245],$t=[1,246],qt=[1,254],Ht=[1,251],Wt=[1,248],Vt=[1,247],Gt=[1,249],Xt=[1,252],Zt=[1,253],Qt=[1,255],Kt=[1,273],Jt=[20,21,23,106],te=[20,21,22,23,66,67,86,102,105,106,109,110,111,112,113],ee={trace:function(){},yy:{},symbols_:{error:2,start:3,mermaidDoc:4,directive:5,openDirective:6,typeDirective:7,closeDirective:8,separator:9,":":10,argDirective:11,open_directive:12,type_directive:13,arg_directive:14,close_directive:15,graphConfig:16,document:17,line:18,statement:19,SEMI:20,NEWLINE:21,SPACE:22,EOF:23,GRAPH:24,NODIR:25,DIR:26,FirstStmtSeperator:27,ending:28,endToken:29,spaceList:30,spaceListNewline:31,verticeStatement:32,styleStatement:33,linkStyleStatement:34,classDefStatement:35,classStatement:36,clickStatement:37,subgraph:38,text:39,SQS:40,SQE:41,end:42,direction:43,acc_title:44,acc_title_value:45,acc_descr:46,acc_descr_value:47,acc_descr_multiline_value:48,link:49,node:50,vertex:51,AMP:52,STYLE_SEPARATOR:53,idString:54,DOUBLECIRCLESTART:55,DOUBLECIRCLEEND:56,PS:57,PE:58,"(-":59,"-)":60,STADIUMSTART:61,STADIUMEND:62,SUBROUTINESTART:63,SUBROUTINEEND:64,VERTEX_WITH_PROPS_START:65,ALPHA:66,COLON:67,PIPE:68,CYLINDERSTART:69,CYLINDEREND:70,DIAMOND_START:71,DIAMOND_STOP:72,TAGEND:73,TRAPSTART:74,TRAPEND:75,INVTRAPSTART:76,INVTRAPEND:77,linkStatement:78,arrowText:79,TESTSTR:80,START_LINK:81,LINK:82,textToken:83,STR:84,keywords:85,STYLE:86,LINKSTYLE:87,CLASSDEF:88,CLASS:89,CLICK:90,DOWN:91,UP:92,textNoTags:93,textNoTagsToken:94,DEFAULT:95,stylesOpt:96,alphaNum:97,CALLBACKNAME:98,CALLBACKARGS:99,HREF:100,LINK_TARGET:101,HEX:102,numList:103,INTERPOLATE:104,NUM:105,COMMA:106,style:107,styleComponent:108,MINUS:109,UNIT:110,BRKT:111,DOT:112,PCT:113,TAGSTART:114,alphaNumToken:115,idStringToken:116,alphaNumStatement:117,direction_tb:118,direction_bt:119,direction_rl:120,direction_lr:121,PUNCTUATION:122,UNICODE_TEXT:123,PLUS:124,EQUALS:125,MULT:126,UNDERSCORE:127,graphCodeTokens:128,ARROW_CROSS:129,ARROW_POINT:130,ARROW_CIRCLE:131,ARROW_OPEN:132,QUOTE:133,$accept:0,$end:1},terminals_:{2:"error",10:":",12:"open_directive",13:"type_directive",14:"arg_directive",15:"close_directive",20:"SEMI",21:"NEWLINE",22:"SPACE",23:"EOF",24:"GRAPH",25:"NODIR",26:"DIR",38:"subgraph",40:"SQS",41:"SQE",42:"end",44:"acc_title",45:"acc_title_value",46:"acc_descr",47:"acc_descr_value",48:"acc_descr_multiline_value",52:"AMP",53:"STYLE_SEPARATOR",55:"DOUBLECIRCLESTART",56:"DOUBLECIRCLEEND",57:"PS",58:"PE",59:"(-",60:"-)",61:"STADIUMSTART",62:"STADIUMEND",63:"SUBROUTINESTART",64:"SUBROUTINEEND",65:"VERTEX_WITH_PROPS_START",66:"ALPHA",67:"COLON",68:"PIPE",69:"CYLINDERSTART",70:"CYLINDEREND",71:"DIAMOND_START",72:"DIAMOND_STOP",73:"TAGEND",74:"TRAPSTART",75:"TRAPEND",76:"INVTRAPSTART",77:"INVTRAPEND",80:"TESTSTR",81:"START_LINK",82:"LINK",84:"STR",86:"STYLE",87:"LINKSTYLE",88:"CLASSDEF",89:"CLASS",90:"CLICK",91:"DOWN",92:"UP",95:"DEFAULT",98:"CALLBACKNAME",99:"CALLBACKARGS",100:"HREF",101:"LINK_TARGET",102:"HEX",104:"INTERPOLATE",105:"NUM",106:"COMMA",109:"MINUS",110:"UNIT",111:"BRKT",112:"DOT",113:"PCT",114:"TAGSTART",118:"direction_tb",119:"direction_bt",120:"direction_rl",121:"direction_lr",122:"PUNCTUATION",123:"UNICODE_TEXT",124:"PLUS",125:"EQUALS",126:"MULT",127:"UNDERSCORE",129:"ARROW_CROSS",130:"ARROW_POINT",131:"ARROW_CIRCLE",132:"ARROW_OPEN",133:"QUOTE"},productions_:[0,[3,1],[3,2],[5,4],[5,6],[6,1],[7,1],[11,1],[8,1],[4,2],[17,0],[17,2],[18,1],[18,1],[18,1],[18,1],[18,1],[16,2],[16,2],[16,2],[16,3],[28,2],[28,1],[29,1],[29,1],[29,1],[27,1],[27,1],[27,2],[31,2],[31,2],[31,1],[31,1],[30,2],[30,1],[19,2],[19,2],[19,2],[19,2],[19,2],[19,2],[19,9],[19,6],[19,4],[19,1],[19,2],[19,2],[19,1],[9,1],[9,1],[9,1],[32,3],[32,4],[32,2],[32,1],[50,1],[50,5],[50,3],[51,4],[51,4],[51,6],[51,4],[51,4],[51,4],[51,8],[51,4],[51,4],[51,4],[51,6],[51,4],[51,4],[51,4],[51,4],[51,4],[51,1],[49,2],[49,3],[49,3],[49,1],[49,3],[78,1],[79,3],[39,1],[39,2],[39,1],[85,1],[85,1],[85,1],[85,1],[85,1],[85,1],[85,1],[85,1],[85,1],[85,1],[85,1],[93,1],[93,2],[35,5],[35,5],[36,5],[37,2],[37,4],[37,3],[37,5],[37,2],[37,4],[37,4],[37,6],[37,2],[37,4],[37,2],[37,4],[37,4],[37,6],[33,5],[33,5],[34,5],[34,5],[34,9],[34,9],[34,7],[34,7],[103,1],[103,3],[96,1],[96,3],[107,1],[107,2],[108,1],[108,1],[108,1],[108,1],[108,1],[108,1],[108,1],[108,1],[108,1],[108,1],[108,1],[83,1],[83,1],[83,1],[83,1],[83,1],[83,1],[94,1],[94,1],[94,1],[94,1],[54,1],[54,2],[97,1],[97,2],[117,1],[117,1],[117,1],[117,1],[43,1],[43,1],[43,1],[43,1],[115,1],[115,1],[115,1],[115,1],[115,1],[115,1],[115,1],[115,1],[115,1],[115,1],[115,1],[115,1],[115,1],[116,1],[116,1],[116,1],[116,1],[116,1],[116,1],[116,1],[116,1],[116,1],[116,1],[116,1],[116,1],[116,1],[116,1],[116,1],[116,1],[128,1],[128,1],[128,1],[128,1],[128,1],[128,1],[128,1],[128,1],[128,1],[128,1],[128,1],[128,1],[128,1],[128,1],[128,1],[128,1],[128,1],[128,1],[128,1],[128,1],[128,1],[128,1],[128,1],[128,1],[128,1],[128,1]],performAction:function(t,e,n,r,i,a,o){var s=a.length-1;switch(i){case 5:r.parseDirective("%%{","open_directive");break;case 6:r.parseDirective(a[s],"type_directive");break;case 7:a[s]=a[s].trim().replace(/'/g,'"'),r.parseDirective(a[s],"arg_directive");break;case 8:r.parseDirective("}%%","close_directive","flowchart");break;case 10:case 36:case 37:case 38:case 39:case 40:this.$=[];break;case 11:a[s]!==[]&&a[s-1].push(a[s]),this.$=a[s-1];break;case 12:case 82:case 84:case 96:case 152:case 154:case 155:case 78:case 150:this.$=a[s];break;case 19:r.setDirection("TB"),this.$="TB";break;case 20:r.setDirection(a[s-1]),this.$=a[s-1];break;case 35:this.$=a[s-1].nodes;break;case 41:this.$=r.addSubGraph(a[s-6],a[s-1],a[s-4]);break;case 42:this.$=r.addSubGraph(a[s-3],a[s-1],a[s-3]);break;case 43:this.$=r.addSubGraph(void 0,a[s-1],void 0);break;case 45:this.$=a[s].trim(),r.setTitle(this.$);break;case 46:case 47:this.$=a[s].trim(),r.setAccDescription(this.$);break;case 51:r.addLink(a[s-2].stmt,a[s],a[s-1]),this.$={stmt:a[s],nodes:a[s].concat(a[s-2].nodes)};break;case 52:r.addLink(a[s-3].stmt,a[s-1],a[s-2]),this.$={stmt:a[s-1],nodes:a[s-1].concat(a[s-3].nodes)};break;case 53:this.$={stmt:a[s-1],nodes:a[s-1]};break;case 54:this.$={stmt:a[s],nodes:a[s]};break;case 55:case 123:case 125:this.$=[a[s]];break;case 56:this.$=a[s-4].concat(a[s]);break;case 57:this.$=[a[s-2]],r.setClass(a[s-2],a[s]);break;case 58:this.$=a[s-3],r.addVertex(a[s-3],a[s-1],"square");break;case 59:this.$=a[s-3],r.addVertex(a[s-3],a[s-1],"doublecircle");break;case 60:this.$=a[s-5],r.addVertex(a[s-5],a[s-2],"circle");break;case 61:this.$=a[s-3],r.addVertex(a[s-3],a[s-1],"ellipse");break;case 62:this.$=a[s-3],r.addVertex(a[s-3],a[s-1],"stadium");break;case 63:this.$=a[s-3],r.addVertex(a[s-3],a[s-1],"subroutine");break;case 64:this.$=a[s-7],r.addVertex(a[s-7],a[s-1],"rect",void 0,void 0,void 0,Object.fromEntries([[a[s-5],a[s-3]]]));break;case 65:this.$=a[s-3],r.addVertex(a[s-3],a[s-1],"cylinder");break;case 66:this.$=a[s-3],r.addVertex(a[s-3],a[s-1],"round");break;case 67:this.$=a[s-3],r.addVertex(a[s-3],a[s-1],"diamond");break;case 68:this.$=a[s-5],r.addVertex(a[s-5],a[s-2],"hexagon");break;case 69:this.$=a[s-3],r.addVertex(a[s-3],a[s-1],"odd");break;case 70:this.$=a[s-3],r.addVertex(a[s-3],a[s-1],"trapezoid");break;case 71:this.$=a[s-3],r.addVertex(a[s-3],a[s-1],"inv_trapezoid");break;case 72:this.$=a[s-3],r.addVertex(a[s-3],a[s-1],"lean_right");break;case 73:this.$=a[s-3],r.addVertex(a[s-3],a[s-1],"lean_left");break;case 74:this.$=a[s],r.addVertex(a[s]);break;case 75:a[s-1].text=a[s],this.$=a[s-1];break;case 76:case 77:a[s-2].text=a[s-1],this.$=a[s-2];break;case 79:var c=r.destructLink(a[s],a[s-2]);this.$={type:c.type,stroke:c.stroke,length:c.length,text:a[s-1]};break;case 80:c=r.destructLink(a[s]),this.$={type:c.type,stroke:c.stroke,length:c.length};break;case 81:this.$=a[s-1];break;case 83:case 97:case 153:case 151:this.$=a[s-1]+""+a[s];break;case 98:case 99:this.$=a[s-4],r.addClass(a[s-2],a[s]);break;case 100:this.$=a[s-4],r.setClass(a[s-2],a[s]);break;case 101:case 109:this.$=a[s-1],r.setClickEvent(a[s-1],a[s]);break;case 102:case 110:this.$=a[s-3],r.setClickEvent(a[s-3],a[s-2]),r.setTooltip(a[s-3],a[s]);break;case 103:this.$=a[s-2],r.setClickEvent(a[s-2],a[s-1],a[s]);break;case 104:this.$=a[s-4],r.setClickEvent(a[s-4],a[s-3],a[s-2]),r.setTooltip(a[s-4],a[s]);break;case 105:case 111:this.$=a[s-1],r.setLink(a[s-1],a[s]);break;case 106:case 112:this.$=a[s-3],r.setLink(a[s-3],a[s-2]),r.setTooltip(a[s-3],a[s]);break;case 107:case 113:this.$=a[s-3],r.setLink(a[s-3],a[s-2],a[s]);break;case 108:case 114:this.$=a[s-5],r.setLink(a[s-5],a[s-4],a[s]),r.setTooltip(a[s-5],a[s-2]);break;case 115:this.$=a[s-4],r.addVertex(a[s-2],void 0,void 0,a[s]);break;case 116:case 118:this.$=a[s-4],r.updateLink(a[s-2],a[s]);break;case 117:this.$=a[s-4],r.updateLink([a[s-2]],a[s]);break;case 119:this.$=a[s-8],r.updateLinkInterpolate([a[s-6]],a[s-2]),r.updateLink([a[s-6]],a[s]);break;case 120:this.$=a[s-8],r.updateLinkInterpolate(a[s-6],a[s-2]),r.updateLink(a[s-6],a[s]);break;case 121:this.$=a[s-6],r.updateLinkInterpolate([a[s-4]],a[s]);break;case 122:this.$=a[s-6],r.updateLinkInterpolate(a[s-4],a[s]);break;case 124:case 126:a[s-2].push(a[s]),this.$=a[s-2];break;case 128:this.$=a[s-1]+a[s];break;case 156:this.$="v";break;case 157:this.$="-";break;case 158:this.$={stmt:"dir",value:"TB"};break;case 159:this.$={stmt:"dir",value:"BT"};break;case 160:this.$={stmt:"dir",value:"RL"};break;case 161:this.$={stmt:"dir",value:"LR"}}},table:[{3:1,4:2,5:3,6:5,12:e,16:4,21:n,22:r,24:i},{1:[3]},{1:[2,1]},{3:10,4:2,5:3,6:5,12:e,16:4,21:n,22:r,24:i},t(a,o,{17:11}),{7:12,13:[1,13]},{16:14,21:n,22:r,24:i},{16:15,21:n,22:r,24:i},{25:[1,16],26:[1,17]},{13:[2,5]},{1:[2,2]},{1:[2,9],18:18,19:19,20:s,21:c,22:u,23:l,32:24,33:25,34:26,35:27,36:28,37:29,38:h,43:31,44:f,46:d,48:p,50:35,51:45,52:g,54:46,66:y,67:m,86:v,87:b,88:_,89:x,90:w,91:k,95:T,105:C,106:E,109:S,111:A,112:M,116:47,118:N,119:D,120:B,121:L,122:O,123:I,124:R,125:F,126:P,127:Y},{8:64,10:[1,65],15:j},t([10,15],[2,6]),t(a,[2,17]),t(a,[2,18]),t(a,[2,19]),{20:[1,68],21:[1,69],22:U,27:67,30:70},t(z,[2,11]),t(z,[2,12]),t(z,[2,13]),t(z,[2,14]),t(z,[2,15]),t(z,[2,16]),{9:72,20:$,21:q,23:H,49:73,78:77,81:[1,78],82:[1,79]},{9:80,20:$,21:q,23:H},{9:81,20:$,21:q,23:H},{9:82,20:$,21:q,23:H},{9:83,20:$,21:q,23:H},{9:84,20:$,21:q,23:H},{9:86,20:$,21:q,22:[1,85],23:H},t(z,[2,44]),{45:[1,87]},{47:[1,88]},t(z,[2,47]),t(W,[2,54],{30:89,22:U}),{22:[1,90]},{22:[1,91]},{22:[1,92]},{22:[1,93]},{26:V,52:G,66:X,67:Z,84:[1,97],91:Q,97:96,98:[1,94],100:[1,95],105:K,106:J,109:tt,111:et,112:nt,115:100,117:98,122:rt,123:it,124:at,125:ot,126:st,127:ct},t(z,[2,158]),t(z,[2,159]),t(z,[2,160]),t(z,[2,161]),t(ut,[2,55],{53:[1,116]}),t(lt,[2,74],{116:129,40:[1,117],52:g,55:[1,118],57:[1,119],59:[1,120],61:[1,121],63:[1,122],65:[1,123],66:y,67:m,69:[1,124],71:[1,125],73:[1,126],74:[1,127],76:[1,128],91:k,95:T,105:C,106:E,109:S,111:A,112:M,122:O,123:I,124:R,125:F,126:P,127:Y}),t(ht,[2,150]),t(ht,[2,175]),t(ht,[2,176]),t(ht,[2,177]),t(ht,[2,178]),t(ht,[2,179]),t(ht,[2,180]),t(ht,[2,181]),t(ht,[2,182]),t(ht,[2,183]),t(ht,[2,184]),t(ht,[2,185]),t(ht,[2,186]),t(ht,[2,187]),t(ht,[2,188]),t(ht,[2,189]),t(ht,[2,190]),{9:130,20:$,21:q,23:H},{11:131,14:[1,132]},t(ft,[2,8]),t(a,[2,20]),t(a,[2,26]),t(a,[2,27]),{21:[1,133]},t(dt,[2,34],{30:134,22:U}),t(z,[2,35]),{50:135,51:45,52:g,54:46,66:y,67:m,91:k,95:T,105:C,106:E,109:S,111:A,112:M,116:47,122:O,123:I,124:R,125:F,126:P,127:Y},t(pt,[2,48]),t(pt,[2,49]),t(pt,[2,50]),t(gt,[2,78],{79:136,68:[1,138],80:[1,137]}),{22:yt,24:mt,26:vt,38:bt,39:139,42:_t,52:G,66:X,67:Z,73:xt,81:wt,83:140,84:kt,85:151,86:Tt,87:Ct,88:Et,89:St,90:At,91:Mt,92:Nt,94:142,95:Dt,105:K,106:J,109:Bt,111:et,112:nt,113:Lt,114:Ot,115:148,122:rt,123:it,124:at,125:ot,126:st,127:ct},t([52,66,67,68,80,91,95,105,106,109,111,112,122,123,124,125,126,127],[2,80]),t(z,[2,36]),t(z,[2,37]),t(z,[2,38]),t(z,[2,39]),t(z,[2,40]),{22:yt,24:mt,26:vt,38:bt,39:163,42:_t,52:G,66:X,67:Z,73:xt,81:wt,83:140,84:kt,85:151,86:Tt,87:Ct,88:Et,89:St,90:At,91:Mt,92:Nt,94:142,95:Dt,105:K,106:J,109:Bt,111:et,112:nt,113:Lt,114:Ot,115:148,122:rt,123:it,124:at,125:ot,126:st,127:ct},t(It,o,{17:164}),t(z,[2,45]),t(z,[2,46]),t(W,[2,53],{52:Rt}),{26:V,52:G,66:X,67:Z,91:Q,97:166,102:[1,167],105:K,106:J,109:tt,111:et,112:nt,115:100,117:98,122:rt,123:it,124:at,125:ot,126:st,127:ct},{95:[1,168],103:169,105:[1,170]},{26:V,52:G,66:X,67:Z,91:Q,95:[1,171],97:172,105:K,106:J,109:tt,111:et,112:nt,115:100,117:98,122:rt,123:it,124:at,125:ot,126:st,127:ct},{26:V,52:G,66:X,67:Z,91:Q,97:173,105:K,106:J,109:tt,111:et,112:nt,115:100,117:98,122:rt,123:it,124:at,125:ot,126:st,127:ct},t(ft,[2,101],{22:[1,174],99:[1,175]}),t(ft,[2,105],{22:[1,176]}),t(ft,[2,109],{115:100,117:178,22:[1,177],26:V,52:G,66:X,67:Z,91:Q,105:K,106:J,109:tt,111:et,112:nt,122:rt,123:it,124:at,125:ot,126:st,127:ct}),t(ft,[2,111],{22:[1,179]}),t(Ft,[2,152]),t(Ft,[2,154]),t(Ft,[2,155]),t(Ft,[2,156]),t(Ft,[2,157]),t(Pt,[2,162]),t(Pt,[2,163]),t(Pt,[2,164]),t(Pt,[2,165]),t(Pt,[2,166]),t(Pt,[2,167]),t(Pt,[2,168]),t(Pt,[2,169]),t(Pt,[2,170]),t(Pt,[2,171]),t(Pt,[2,172]),t(Pt,[2,173]),t(Pt,[2,174]),{52:g,54:180,66:y,67:m,91:k,95:T,105:C,106:E,109:S,111:A,112:M,116:47,122:O,123:I,124:R,125:F,126:P,127:Y},{22:yt,24:mt,26:vt,38:bt,39:181,42:_t,52:G,66:X,67:Z,73:xt,81:wt,83:140,84:kt,85:151,86:Tt,87:Ct,88:Et,89:St,90:At,91:Mt,92:Nt,94:142,95:Dt,105:K,106:J,109:Bt,111:et,112:nt,113:Lt,114:Ot,115:148,122:rt,123:it,124:at,125:ot,126:st,127:ct},{22:yt,24:mt,26:vt,38:bt,39:182,42:_t,52:G,66:X,67:Z,73:xt,81:wt,83:140,84:kt,85:151,86:Tt,87:Ct,88:Et,89:St,90:At,91:Mt,92:Nt,94:142,95:Dt,105:K,106:J,109:Bt,111:et,112:nt,113:Lt,114:Ot,115:148,122:rt,123:it,124:at,125:ot,126:st,127:ct},{22:yt,24:mt,26:vt,38:bt,39:184,42:_t,52:G,57:[1,183],66:X,67:Z,73:xt,81:wt,83:140,84:kt,85:151,86:Tt,87:Ct,88:Et,89:St,90:At,91:Mt,92:Nt,94:142,95:Dt,105:K,106:J,109:Bt,111:et,112:nt,113:Lt,114:Ot,115:148,122:rt,123:it,124:at,125:ot,126:st,127:ct},{22:yt,24:mt,26:vt,38:bt,39:185,42:_t,52:G,66:X,67:Z,73:xt,81:wt,83:140,84:kt,85:151,86:Tt,87:Ct,88:Et,89:St,90:At,91:Mt,92:Nt,94:142,95:Dt,105:K,106:J,109:Bt,111:et,112:nt,113:Lt,114:Ot,115:148,122:rt,123:it,124:at,125:ot,126:st,127:ct},{22:yt,24:mt,26:vt,38:bt,39:186,42:_t,52:G,66:X,67:Z,73:xt,81:wt,83:140,84:kt,85:151,86:Tt,87:Ct,88:Et,89:St,90:At,91:Mt,92:Nt,94:142,95:Dt,105:K,106:J,109:Bt,111:et,112:nt,113:Lt,114:Ot,115:148,122:rt,123:it,124:at,125:ot,126:st,127:ct},{22:yt,24:mt,26:vt,38:bt,39:187,42:_t,52:G,66:X,67:Z,73:xt,81:wt,83:140,84:kt,85:151,86:Tt,87:Ct,88:Et,89:St,90:At,91:Mt,92:Nt,94:142,95:Dt,105:K,106:J,109:Bt,111:et,112:nt,113:Lt,114:Ot,115:148,122:rt,123:it,124:at,125:ot,126:st,127:ct},{66:[1,188]},{22:yt,24:mt,26:vt,38:bt,39:189,42:_t,52:G,66:X,67:Z,73:xt,81:wt,83:140,84:kt,85:151,86:Tt,87:Ct,88:Et,89:St,90:At,91:Mt,92:Nt,94:142,95:Dt,105:K,106:J,109:Bt,111:et,112:nt,113:Lt,114:Ot,115:148,122:rt,123:it,124:at,125:ot,126:st,127:ct},{22:yt,24:mt,26:vt,38:bt,39:190,42:_t,52:G,66:X,67:Z,71:[1,191],73:xt,81:wt,83:140,84:kt,85:151,86:Tt,87:Ct,88:Et,89:St,90:At,91:Mt,92:Nt,94:142,95:Dt,105:K,106:J,109:Bt,111:et,112:nt,113:Lt,114:Ot,115:148,122:rt,123:it,124:at,125:ot,126:st,127:ct},{22:yt,24:mt,26:vt,38:bt,39:192,42:_t,52:G,66:X,67:Z,73:xt,81:wt,83:140,84:kt,85:151,86:Tt,87:Ct,88:Et,89:St,90:At,91:Mt,92:Nt,94:142,95:Dt,105:K,106:J,109:Bt,111:et,112:nt,113:Lt,114:Ot,115:148,122:rt,123:it,124:at,125:ot,126:st,127:ct},{22:yt,24:mt,26:vt,38:bt,39:193,42:_t,52:G,66:X,67:Z,73:xt,81:wt,83:140,84:kt,85:151,86:Tt,87:Ct,88:Et,89:St,90:At,91:Mt,92:Nt,94:142,95:Dt,105:K,106:J,109:Bt,111:et,112:nt,113:Lt,114:Ot,115:148,122:rt,123:it,124:at,125:ot,126:st,127:ct},{22:yt,24:mt,26:vt,38:bt,39:194,42:_t,52:G,66:X,67:Z,73:xt,81:wt,83:140,84:kt,85:151,86:Tt,87:Ct,88:Et,89:St,90:At,91:Mt,92:Nt,94:142,95:Dt,105:K,106:J,109:Bt,111:et,112:nt,113:Lt,114:Ot,115:148,122:rt,123:it,124:at,125:ot,126:st,127:ct},t(ht,[2,151]),t(Yt,[2,3]),{8:195,15:j},{15:[2,7]},t(a,[2,28]),t(dt,[2,33]),t(W,[2,51],{30:196,22:U}),t(gt,[2,75],{22:[1,197]}),{22:[1,198]},{22:yt,24:mt,26:vt,38:bt,39:199,42:_t,52:G,66:X,67:Z,73:xt,81:wt,83:140,84:kt,85:151,86:Tt,87:Ct,88:Et,89:St,90:At,91:Mt,92:Nt,94:142,95:Dt,105:K,106:J,109:Bt,111:et,112:nt,113:Lt,114:Ot,115:148,122:rt,123:it,124:at,125:ot,126:st,127:ct},{22:yt,24:mt,26:vt,38:bt,42:_t,52:G,66:X,67:Z,73:xt,81:wt,82:[1,200],83:201,85:151,86:Tt,87:Ct,88:Et,89:St,90:At,91:Mt,92:Nt,94:142,95:Dt,105:K,106:J,109:Bt,111:et,112:nt,113:Lt,114:Ot,115:148,122:rt,123:it,124:at,125:ot,126:st,127:ct},t(Pt,[2,82]),t(Pt,[2,84]),t(Pt,[2,140]),t(Pt,[2,141]),t(Pt,[2,142]),t(Pt,[2,143]),t(Pt,[2,144]),t(Pt,[2,145]),t(Pt,[2,146]),t(Pt,[2,147]),t(Pt,[2,148]),t(Pt,[2,149]),t(Pt,[2,85]),t(Pt,[2,86]),t(Pt,[2,87]),t(Pt,[2,88]),t(Pt,[2,89]),t(Pt,[2,90]),t(Pt,[2,91]),t(Pt,[2,92]),t(Pt,[2,93]),t(Pt,[2,94]),t(Pt,[2,95]),{9:203,20:$,21:q,22:yt,23:H,24:mt,26:vt,38:bt,40:[1,202],42:_t,52:G,66:X,67:Z,73:xt,81:wt,83:201,85:151,86:Tt,87:Ct,88:Et,89:St,90:At,91:Mt,92:Nt,94:142,95:Dt,105:K,106:J,109:Bt,111:et,112:nt,113:Lt,114:Ot,115:148,122:rt,123:it,124:at,125:ot,126:st,127:ct},{18:18,19:19,20:s,21:c,22:u,23:l,32:24,33:25,34:26,35:27,36:28,37:29,38:h,42:[1,204],43:31,44:f,46:d,48:p,50:35,51:45,52:g,54:46,66:y,67:m,86:v,87:b,88:_,89:x,90:w,91:k,95:T,105:C,106:E,109:S,111:A,112:M,116:47,118:N,119:D,120:B,121:L,122:O,123:I,124:R,125:F,126:P,127:Y},{22:U,30:205},{22:[1,206],26:V,52:G,66:X,67:Z,91:Q,105:K,106:J,109:tt,111:et,112:nt,115:100,117:178,122:rt,123:it,124:at,125:ot,126:st,127:ct},{22:[1,207]},{22:[1,208]},{22:[1,209],106:[1,210]},t(jt,[2,123]),{22:[1,211]},{22:[1,212],26:V,52:G,66:X,67:Z,91:Q,105:K,106:J,109:tt,111:et,112:nt,115:100,117:178,122:rt,123:it,124:at,125:ot,126:st,127:ct},{22:[1,213],26:V,52:G,66:X,67:Z,91:Q,105:K,106:J,109:tt,111:et,112:nt,115:100,117:178,122:rt,123:it,124:at,125:ot,126:st,127:ct},{84:[1,214]},t(ft,[2,103],{22:[1,215]}),{84:[1,216],101:[1,217]},{84:[1,218]},t(Ft,[2,153]),{84:[1,219],101:[1,220]},t(ut,[2,57],{116:129,52:g,66:y,67:m,91:k,95:T,105:C,106:E,109:S,111:A,112:M,122:O,123:I,124:R,125:F,126:P,127:Y}),{22:yt,24:mt,26:vt,38:bt,41:[1,221],42:_t,52:G,66:X,67:Z,73:xt,81:wt,83:201,85:151,86:Tt,87:Ct,88:Et,89:St,90:At,91:Mt,92:Nt,94:142,95:Dt,105:K,106:J,109:Bt,111:et,112:nt,113:Lt,114:Ot,115:148,122:rt,123:it,124:at,125:ot,126:st,127:ct},{22:yt,24:mt,26:vt,38:bt,42:_t,52:G,56:[1,222],66:X,67:Z,73:xt,81:wt,83:201,85:151,86:Tt,87:Ct,88:Et,89:St,90:At,91:Mt,92:Nt,94:142,95:Dt,105:K,106:J,109:Bt,111:et,112:nt,113:Lt,114:Ot,115:148,122:rt,123:it,124:at,125:ot,126:st,127:ct},{22:yt,24:mt,26:vt,38:bt,39:223,42:_t,52:G,66:X,67:Z,73:xt,81:wt,83:140,84:kt,85:151,86:Tt,87:Ct,88:Et,89:St,90:At,91:Mt,92:Nt,94:142,95:Dt,105:K,106:J,109:Bt,111:et,112:nt,113:Lt,114:Ot,115:148,122:rt,123:it,124:at,125:ot,126:st,127:ct},{22:yt,24:mt,26:vt,38:bt,42:_t,52:G,58:[1,224],66:X,67:Z,73:xt,81:wt,83:201,85:151,86:Tt,87:Ct,88:Et,89:St,90:At,91:Mt,92:Nt,94:142,95:Dt,105:K,106:J,109:Bt,111:et,112:nt,113:Lt,114:Ot,115:148,122:rt,123:it,124:at,125:ot,126:st,127:ct},{22:yt,24:mt,26:vt,38:bt,42:_t,52:G,60:[1,225],66:X,67:Z,73:xt,81:wt,83:201,85:151,86:Tt,87:Ct,88:Et,89:St,90:At,91:Mt,92:Nt,94:142,95:Dt,105:K,106:J,109:Bt,111:et,112:nt,113:Lt,114:Ot,115:148,122:rt,123:it,124:at,125:ot,126:st,127:ct},{22:yt,24:mt,26:vt,38:bt,42:_t,52:G,62:[1,226],66:X,67:Z,73:xt,81:wt,83:201,85:151,86:Tt,87:Ct,88:Et,89:St,90:At,91:Mt,92:Nt,94:142,95:Dt,105:K,106:J,109:Bt,111:et,112:nt,113:Lt,114:Ot,115:148,122:rt,123:it,124:at,125:ot,126:st,127:ct},{22:yt,24:mt,26:vt,38:bt,42:_t,52:G,64:[1,227],66:X,67:Z,73:xt,81:wt,83:201,85:151,86:Tt,87:Ct,88:Et,89:St,90:At,91:Mt,92:Nt,94:142,95:Dt,105:K,106:J,109:Bt,111:et,112:nt,113:Lt,114:Ot,115:148,122:rt,123:it,124:at,125:ot,126:st,127:ct},{67:[1,228]},{22:yt,24:mt,26:vt,38:bt,42:_t,52:G,66:X,67:Z,70:[1,229],73:xt,81:wt,83:201,85:151,86:Tt,87:Ct,88:Et,89:St,90:At,91:Mt,92:Nt,94:142,95:Dt,105:K,106:J,109:Bt,111:et,112:nt,113:Lt,114:Ot,115:148,122:rt,123:it,124:at,125:ot,126:st,127:ct},{22:yt,24:mt,26:vt,38:bt,42:_t,52:G,66:X,67:Z,72:[1,230],73:xt,81:wt,83:201,85:151,86:Tt,87:Ct,88:Et,89:St,90:At,91:Mt,92:Nt,94:142,95:Dt,105:K,106:J,109:Bt,111:et,112:nt,113:Lt,114:Ot,115:148,122:rt,123:it,124:at,125:ot,126:st,127:ct},{22:yt,24:mt,26:vt,38:bt,39:231,42:_t,52:G,66:X,67:Z,73:xt,81:wt,83:140,84:kt,85:151,86:Tt,87:Ct,88:Et,89:St,90:At,91:Mt,92:Nt,94:142,95:Dt,105:K,106:J,109:Bt,111:et,112:nt,113:Lt,114:Ot,115:148,122:rt,123:it,124:at,125:ot,126:st,127:ct},{22:yt,24:mt,26:vt,38:bt,41:[1,232],42:_t,52:G,66:X,67:Z,73:xt,81:wt,83:201,85:151,86:Tt,87:Ct,88:Et,89:St,90:At,91:Mt,92:Nt,94:142,95:Dt,105:K,106:J,109:Bt,111:et,112:nt,113:Lt,114:Ot,115:148,122:rt,123:it,124:at,125:ot,126:st,127:ct},{22:yt,24:mt,26:vt,38:bt,42:_t,52:G,66:X,67:Z,73:xt,75:[1,233],77:[1,234],81:wt,83:201,85:151,86:Tt,87:Ct,88:Et,89:St,90:At,91:Mt,92:Nt,94:142,95:Dt,105:K,106:J,109:Bt,111:et,112:nt,113:Lt,114:Ot,115:148,122:rt,123:it,124:at,125:ot,126:st,127:ct},{22:yt,24:mt,26:vt,38:bt,42:_t,52:G,66:X,67:Z,73:xt,75:[1,236],77:[1,235],81:wt,83:201,85:151,86:Tt,87:Ct,88:Et,89:St,90:At,91:Mt,92:Nt,94:142,95:Dt,105:K,106:J,109:Bt,111:et,112:nt,113:Lt,114:Ot,115:148,122:rt,123:it,124:at,125:ot,126:st,127:ct},{9:237,20:$,21:q,23:H},t(W,[2,52],{52:Rt}),t(gt,[2,77]),t(gt,[2,76]),{22:yt,24:mt,26:vt,38:bt,42:_t,52:G,66:X,67:Z,68:[1,238],73:xt,81:wt,83:201,85:151,86:Tt,87:Ct,88:Et,89:St,90:At,91:Mt,92:Nt,94:142,95:Dt,105:K,106:J,109:Bt,111:et,112:nt,113:Lt,114:Ot,115:148,122:rt,123:it,124:at,125:ot,126:st,127:ct},t(gt,[2,79]),t(Pt,[2,83]),{22:yt,24:mt,26:vt,38:bt,39:239,42:_t,52:G,66:X,67:Z,73:xt,81:wt,83:140,84:kt,85:151,86:Tt,87:Ct,88:Et,89:St,90:At,91:Mt,92:Nt,94:142,95:Dt,105:K,106:J,109:Bt,111:et,112:nt,113:Lt,114:Ot,115:148,122:rt,123:it,124:at,125:ot,126:st,127:ct},t(It,o,{17:240}),t(z,[2,43]),{51:241,52:g,54:46,66:y,67:m,91:k,95:T,105:C,106:E,109:S,111:A,112:M,116:47,122:O,123:I,124:R,125:F,126:P,127:Y},{22:Ut,66:zt,67:$t,86:qt,96:242,102:Ht,105:Wt,107:243,108:244,109:Vt,110:Gt,111:Xt,112:Zt,113:Qt},{22:Ut,66:zt,67:$t,86:qt,96:256,102:Ht,105:Wt,107:243,108:244,109:Vt,110:Gt,111:Xt,112:Zt,113:Qt},{22:Ut,66:zt,67:$t,86:qt,96:257,102:Ht,104:[1,258],105:Wt,107:243,108:244,109:Vt,110:Gt,111:Xt,112:Zt,113:Qt},{22:Ut,66:zt,67:$t,86:qt,96:259,102:Ht,104:[1,260],105:Wt,107:243,108:244,109:Vt,110:Gt,111:Xt,112:Zt,113:Qt},{105:[1,261]},{22:Ut,66:zt,67:$t,86:qt,96:262,102:Ht,105:Wt,107:243,108:244,109:Vt,110:Gt,111:Xt,112:Zt,113:Qt},{22:Ut,66:zt,67:$t,86:qt,96:263,102:Ht,105:Wt,107:243,108:244,109:Vt,110:Gt,111:Xt,112:Zt,113:Qt},{26:V,52:G,66:X,67:Z,91:Q,97:264,105:K,106:J,109:tt,111:et,112:nt,115:100,117:98,122:rt,123:it,124:at,125:ot,126:st,127:ct},t(ft,[2,102]),{84:[1,265]},t(ft,[2,106],{22:[1,266]}),t(ft,[2,107]),t(ft,[2,110]),t(ft,[2,112],{22:[1,267]}),t(ft,[2,113]),t(lt,[2,58]),t(lt,[2,59]),{22:yt,24:mt,26:vt,38:bt,42:_t,52:G,58:[1,268],66:X,67:Z,73:xt,81:wt,83:201,85:151,86:Tt,87:Ct,88:Et,89:St,90:At,91:Mt,92:Nt,94:142,95:Dt,105:K,106:J,109:Bt,111:et,112:nt,113:Lt,114:Ot,115:148,122:rt,123:it,124:at,125:ot,126:st,127:ct},t(lt,[2,66]),t(lt,[2,61]),t(lt,[2,62]),t(lt,[2,63]),{66:[1,269]},t(lt,[2,65]),t(lt,[2,67]),{22:yt,24:mt,26:vt,38:bt,42:_t,52:G,66:X,67:Z,72:[1,270],73:xt,81:wt,83:201,85:151,86:Tt,87:Ct,88:Et,89:St,90:At,91:Mt,92:Nt,94:142,95:Dt,105:K,106:J,109:Bt,111:et,112:nt,113:Lt,114:Ot,115:148,122:rt,123:it,124:at,125:ot,126:st,127:ct},t(lt,[2,69]),t(lt,[2,70]),t(lt,[2,72]),t(lt,[2,71]),t(lt,[2,73]),t(Yt,[2,4]),t([22,52,66,67,91,95,105,106,109,111,112,122,123,124,125,126,127],[2,81]),{22:yt,24:mt,26:vt,38:bt,41:[1,271],42:_t,52:G,66:X,67:Z,73:xt,81:wt,83:201,85:151,86:Tt,87:Ct,88:Et,89:St,90:At,91:Mt,92:Nt,94:142,95:Dt,105:K,106:J,109:Bt,111:et,112:nt,113:Lt,114:Ot,115:148,122:rt,123:it,124:at,125:ot,126:st,127:ct},{18:18,19:19,20:s,21:c,22:u,23:l,32:24,33:25,34:26,35:27,36:28,37:29,38:h,42:[1,272],43:31,44:f,46:d,48:p,50:35,51:45,52:g,54:46,66:y,67:m,86:v,87:b,88:_,89:x,90:w,91:k,95:T,105:C,106:E,109:S,111:A,112:M,116:47,118:N,119:D,120:B,121:L,122:O,123:I,124:R,125:F,126:P,127:Y},t(ut,[2,56]),t(ft,[2,115],{106:Kt}),t(Jt,[2,125],{108:274,22:Ut,66:zt,67:$t,86:qt,102:Ht,105:Wt,109:Vt,110:Gt,111:Xt,112:Zt,113:Qt}),t(te,[2,127]),t(te,[2,129]),t(te,[2,130]),t(te,[2,131]),t(te,[2,132]),t(te,[2,133]),t(te,[2,134]),t(te,[2,135]),t(te,[2,136]),t(te,[2,137]),t(te,[2,138]),t(te,[2,139]),t(ft,[2,116],{106:Kt}),t(ft,[2,117],{106:Kt}),{22:[1,275]},t(ft,[2,118],{106:Kt}),{22:[1,276]},t(jt,[2,124]),t(ft,[2,98],{106:Kt}),t(ft,[2,99],{106:Kt}),t(ft,[2,100],{115:100,117:178,26:V,52:G,66:X,67:Z,91:Q,105:K,106:J,109:tt,111:et,112:nt,122:rt,123:it,124:at,125:ot,126:st,127:ct}),t(ft,[2,104]),{101:[1,277]},{101:[1,278]},{58:[1,279]},{68:[1,280]},{72:[1,281]},{9:282,20:$,21:q,23:H},t(z,[2,42]),{22:Ut,66:zt,67:$t,86:qt,102:Ht,105:Wt,107:283,108:244,109:Vt,110:Gt,111:Xt,112:Zt,113:Qt},t(te,[2,128]),{26:V,52:G,66:X,67:Z,91:Q,97:284,105:K,106:J,109:tt,111:et,112:nt,115:100,117:98,122:rt,123:it,124:at,125:ot,126:st,127:ct},{26:V,52:G,66:X,67:Z,91:Q,97:285,105:K,106:J,109:tt,111:et,112:nt,115:100,117:98,122:rt,123:it,124:at,125:ot,126:st,127:ct},t(ft,[2,108]),t(ft,[2,114]),t(lt,[2,60]),{22:yt,24:mt,26:vt,38:bt,39:286,42:_t,52:G,66:X,67:Z,73:xt,81:wt,83:140,84:kt,85:151,86:Tt,87:Ct,88:Et,89:St,90:At,91:Mt,92:Nt,94:142,95:Dt,105:K,106:J,109:Bt,111:et,112:nt,113:Lt,114:Ot,115:148,122:rt,123:it,124:at,125:ot,126:st,127:ct},t(lt,[2,68]),t(It,o,{17:287}),t(Jt,[2,126],{108:274,22:Ut,66:zt,67:$t,86:qt,102:Ht,105:Wt,109:Vt,110:Gt,111:Xt,112:Zt,113:Qt}),t(ft,[2,121],{115:100,117:178,22:[1,288],26:V,52:G,66:X,67:Z,91:Q,105:K,106:J,109:tt,111:et,112:nt,122:rt,123:it,124:at,125:ot,126:st,127:ct}),t(ft,[2,122],{115:100,117:178,22:[1,289],26:V,52:G,66:X,67:Z,91:Q,105:K,106:J,109:tt,111:et,112:nt,122:rt,123:it,124:at,125:ot,126:st,127:ct}),{22:yt,24:mt,26:vt,38:bt,41:[1,290],42:_t,52:G,66:X,67:Z,73:xt,81:wt,83:201,85:151,86:Tt,87:Ct,88:Et,89:St,90:At,91:Mt,92:Nt,94:142,95:Dt,105:K,106:J,109:Bt,111:et,112:nt,113:Lt,114:Ot,115:148,122:rt,123:it,124:at,125:ot,126:st,127:ct},{18:18,19:19,20:s,21:c,22:u,23:l,32:24,33:25,34:26,35:27,36:28,37:29,38:h,42:[1,291],43:31,44:f,46:d,48:p,50:35,51:45,52:g,54:46,66:y,67:m,86:v,87:b,88:_,89:x,90:w,91:k,95:T,105:C,106:E,109:S,111:A,112:M,116:47,118:N,119:D,120:B,121:L,122:O,123:I,124:R,125:F,126:P,127:Y},{22:Ut,66:zt,67:$t,86:qt,96:292,102:Ht,105:Wt,107:243,108:244,109:Vt,110:Gt,111:Xt,112:Zt,113:Qt},{22:Ut,66:zt,67:$t,86:qt,96:293,102:Ht,105:Wt,107:243,108:244,109:Vt,110:Gt,111:Xt,112:Zt,113:Qt},t(lt,[2,64]),t(z,[2,41]),t(ft,[2,119],{106:Kt}),t(ft,[2,120],{106:Kt})],defaultActions:{2:[2,1],9:[2,5],10:[2,2],132:[2,7]},parseError:function(t,e){if(!e.recoverable){var n=new Error(t);throw n.hash=e,n}this.trace(t)},parse:function(t){var e=this,n=[0],r=[],i=[null],a=[],o=this.table,s="",c=0,u=0,l=0,h=2,f=1,d=a.slice.call(arguments,1),p=Object.create(this.lexer),g={yy:{}};for(var y in this.yy)Object.prototype.hasOwnProperty.call(this.yy,y)&&(g.yy[y]=this.yy[y]);p.setInput(t,g.yy),g.yy.lexer=p,g.yy.parser=this,void 0===p.yylloc&&(p.yylloc={});var m=p.yylloc;a.push(m);var v=p.options&&p.options.ranges;function b(){var t;return"number"!=typeof(t=r.pop()||p.lex()||f)&&(t instanceof Array&&(t=(r=t).pop()),t=e.symbols_[t]||t),t}"function"==typeof g.yy.parseError?this.parseError=g.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;for(var _,x,w,k,T,C,E,S,A,M={};;){if(w=n[n.length-1],this.defaultActions[w]?k=this.defaultActions[w]:(null==_&&(_=b()),k=o[w]&&o[w][_]),void 0===k||!k.length||!k[0]){var N="";for(C in A=[],o[w])this.terminals_[C]&&C>h&&A.push("'"+this.terminals_[C]+"'");N=p.showPosition?"Parse error on line "+(c+1)+":\n"+p.showPosition()+"\nExpecting "+A.join(", ")+", got '"+(this.terminals_[_]||_)+"'":"Parse error on line "+(c+1)+": Unexpected "+(_==f?"end of input":"'"+(this.terminals_[_]||_)+"'"),this.parseError(N,{text:p.match,token:this.terminals_[_]||_,line:p.yylineno,loc:m,expected:A})}if(k[0]instanceof Array&&k.length>1)throw new Error("Parse Error: multiple actions possible at state: "+w+", token: "+_);switch(k[0]){case 1:n.push(_),i.push(p.yytext),a.push(p.yylloc),n.push(k[1]),_=null,x?(_=x,x=null):(u=p.yyleng,s=p.yytext,c=p.yylineno,m=p.yylloc,l>0&&l--);break;case 2:if(E=this.productions_[k[1]][1],M.$=i[i.length-E],M._$={first_line:a[a.length-(E||1)].first_line,last_line:a[a.length-1].last_line,first_column:a[a.length-(E||1)].first_column,last_column:a[a.length-1].last_column},v&&(M._$.range=[a[a.length-(E||1)].range[0],a[a.length-1].range[1]]),void 0!==(T=this.performAction.apply(M,[s,u,c,g.yy,k[1],i,a].concat(d))))return T;E&&(n=n.slice(0,-1*E*2),i=i.slice(0,-1*E),a=a.slice(0,-1*E)),n.push(this.productions_[k[1]][0]),i.push(M.$),a.push(M._$),S=o[n[n.length-2]][n[n.length-1]],n.push(S);break;case 3:return!0}}return!0}},ne={EOF:1,parseError:function(t,e){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,e)},setInput:function(t,e){return this.yy=e||this.yy||{},this._input=t,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},input:function(){var t=this._input[0];return this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t,t.match(/(?:\r\n?|\n).*/g)?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),t},unput:function(t){var e=t.length,n=t.split(/(?:\r\n?|\n)/g);this._input=t+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-e),this.offset-=e;var r=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),n.length-1&&(this.yylineno-=n.length-1);var i=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:n?(n.length===r.length?this.yylloc.first_column:0)+r[r.length-n.length].length-n[0].length:this.yylloc.first_column-e},this.options.ranges&&(this.yylloc.range=[i[0],i[0]+this.yyleng-e]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject:function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):this.parseError("Lexical error on line "+(this.yylineno+1)+". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},less:function(t){this.unput(this.match.slice(t))},pastInput:function(){var t=this.matched.substr(0,this.matched.length-this.match.length);return(t.length>20?"...":"")+t.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var t=this.match;return t.length<20&&(t+=this._input.substr(0,20-t.length)),(t.substr(0,20)+(t.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var t=this.pastInput(),e=new Array(t.length+1).join("-");return t+this.upcomingInput()+"\n"+e+"^"},test_match:function(t,e){var n,r,i;if(this.options.backtrack_lexer&&(i={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(i.yylloc.range=this.yylloc.range.slice(0))),(r=t[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=r.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:r?r[r.length-1].length-r[r.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],n=this.performAction.call(this,this.yy,this,e,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),n)return n;if(this._backtrack){for(var a in i)this[a]=i[a];return!1}return!1},next:function(){if(this.done)return this.EOF;var t,e,n,r;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var i=this._currentRules(),a=0;ae[0].length)){if(e=n,r=a,this.options.backtrack_lexer){if(!1!==(t=this.test_match(n,i[a])))return t;if(this._backtrack){e=!1;continue}return!1}if(!this.options.flex)break}return e?!1!==(t=this.test_match(e,i[r]))&&t:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){return this.next()||this.lex()},begin:function(t){this.conditionStack.push(t)},popState:function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]},_currentRules:function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},topState:function(t){return(t=this.conditionStack.length-1-Math.abs(t||0))>=0?this.conditionStack[t]:"INITIAL"},pushState:function(t){this.begin(t)},stateStackSize:function(){return this.conditionStack.length},options:{},performAction:function(t,e,n,r){switch(n){case 0:return this.begin("open_directive"),12;case 1:return this.begin("type_directive"),13;case 2:return this.popState(),this.begin("arg_directive"),10;case 3:return this.popState(),this.popState(),15;case 4:return 14;case 5:case 6:break;case 7:return this.begin("acc_title"),44;case 8:return this.popState(),"acc_title_value";case 9:return this.begin("acc_descr"),46;case 10:return this.popState(),"acc_descr_value";case 11:this.begin("acc_descr_multiline");break;case 12:case 15:case 24:case 27:case 30:case 33:this.popState();break;case 13:return"acc_descr_multiline_value";case 14:this.begin("string");break;case 16:return"STR";case 17:return 86;case 18:return 95;case 19:return 87;case 20:return 104;case 21:return 88;case 22:return 89;case 23:this.begin("href");break;case 25:return 100;case 26:this.begin("callbackname");break;case 28:this.popState(),this.begin("callbackargs");break;case 29:return 98;case 31:return 99;case 32:this.begin("click");break;case 34:return 90;case 35:case 36:return t.lex.firstGraph()&&this.begin("dir"),24;case 37:return 38;case 38:return 42;case 39:case 40:case 41:case 42:return 101;case 43:return this.popState(),25;case 44:case 45:case 46:case 47:case 48:case 49:case 50:case 51:case 52:case 53:return this.popState(),26;case 54:return 118;case 55:return 119;case 56:return 120;case 57:return 121;case 58:return 105;case 59:return 111;case 60:return 53;case 61:return 67;case 62:return 52;case 63:return 20;case 64:return 106;case 65:return 126;case 66:case 67:case 68:return 82;case 69:case 70:case 71:return 81;case 72:return 59;case 73:return 60;case 74:return 61;case 75:return 62;case 76:return 63;case 77:return 64;case 78:return 65;case 79:return 69;case 80:return 70;case 81:return 55;case 82:return 56;case 83:return 109;case 84:return 112;case 85:return 127;case 86:return 124;case 87:return 113;case 88:case 89:return 125;case 90:return 114;case 91:return 73;case 92:return 92;case 93:return"SEP";case 94:return 91;case 95:return 66;case 96:return 75;case 97:return 74;case 98:return 77;case 99:return 76;case 100:return 122;case 101:return 123;case 102:return 68;case 103:return 57;case 104:return 58;case 105:return 40;case 106:return 41;case 107:return 71;case 108:return 72;case 109:return 133;case 110:return 21;case 111:return 22;case 112:return 23}},rules:[/^(?:%%\{)/,/^(?:((?:(?!\}%%)[^:.])*))/,/^(?::)/,/^(?:\}%%)/,/^(?:((?:(?!\}%%).|\n)*))/,/^(?:%%(?!\{)[^\n]*)/,/^(?:[^\}]%%[^\n]*)/,/^(?:accTitle\s*:\s*)/,/^(?:(?!\n||)*[^\n]*)/,/^(?:accDescr\s*:\s*)/,/^(?:(?!\n||)*[^\n]*)/,/^(?:accDescr\s*\{\s*)/,/^(?:[\}])/,/^(?:[^\}]*)/,/^(?:["])/,/^(?:["])/,/^(?:[^"]*)/,/^(?:style\b)/,/^(?:default\b)/,/^(?:linkStyle\b)/,/^(?:interpolate\b)/,/^(?:classDef\b)/,/^(?:class\b)/,/^(?:href[\s]+["])/,/^(?:["])/,/^(?:[^"]*)/,/^(?:call[\s]+)/,/^(?:\([\s]*\))/,/^(?:\()/,/^(?:[^(]*)/,/^(?:\))/,/^(?:[^)]*)/,/^(?:click[\s]+)/,/^(?:[\s\n])/,/^(?:[^\s\n]*)/,/^(?:graph\b)/,/^(?:flowchart\b)/,/^(?:subgraph\b)/,/^(?:end\b\s*)/,/^(?:_self\b)/,/^(?:_blank\b)/,/^(?:_parent\b)/,/^(?:_top\b)/,/^(?:(\r?\n)*\s*\n)/,/^(?:\s*LR\b)/,/^(?:\s*RL\b)/,/^(?:\s*TB\b)/,/^(?:\s*BT\b)/,/^(?:\s*TD\b)/,/^(?:\s*BR\b)/,/^(?:\s*<)/,/^(?:\s*>)/,/^(?:\s*\^)/,/^(?:\s*v\b)/,/^(?:.*direction\s+TB[^\n]*)/,/^(?:.*direction\s+BT[^\n]*)/,/^(?:.*direction\s+RL[^\n]*)/,/^(?:.*direction\s+LR[^\n]*)/,/^(?:[0-9]+)/,/^(?:#)/,/^(?::::)/,/^(?::)/,/^(?:&)/,/^(?:;)/,/^(?:,)/,/^(?:\*)/,/^(?:\s*[xo<]?--+[-xo>]\s*)/,/^(?:\s*[xo<]?==+[=xo>]\s*)/,/^(?:\s*[xo<]?-?\.+-[xo>]?\s*)/,/^(?:\s*[xo<]?--\s*)/,/^(?:\s*[xo<]?==\s*)/,/^(?:\s*[xo<]?-\.\s*)/,/^(?:\(-)/,/^(?:-\))/,/^(?:\(\[)/,/^(?:\]\))/,/^(?:\[\[)/,/^(?:\]\])/,/^(?:\[\|)/,/^(?:\[\()/,/^(?:\)\])/,/^(?:\(\(\()/,/^(?:\)\)\))/,/^(?:-)/,/^(?:\.)/,/^(?:[\_])/,/^(?:\+)/,/^(?:%)/,/^(?:=)/,/^(?:=)/,/^(?:<)/,/^(?:>)/,/^(?:\^)/,/^(?:\\\|)/,/^(?:v\b)/,/^(?:[A-Za-z]+)/,/^(?:\\\])/,/^(?:\[\/)/,/^(?:\/\])/,/^(?:\[\\)/,/^(?:[!"#$%&'*+,-.`?\\_/])/,/^(?:[\u00AA\u00B5\u00BA\u00C0-\u00D6\u00D8-\u00F6]|[\u00F8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377]|[\u037A-\u037D\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5]|[\u03F7-\u0481\u048A-\u0527\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA]|[\u05F0-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE]|[\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA]|[\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u08A0]|[\u08A2-\u08AC\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0977]|[\u0979-\u097F\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2]|[\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u0A05-\u0A0A]|[\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39]|[\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8]|[\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0B05-\u0B0C]|[\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C]|[\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99]|[\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0]|[\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C33\u0C35-\u0C39\u0C3D]|[\u0C58\u0C59\u0C60\u0C61\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3]|[\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10]|[\u0D12-\u0D3A\u0D3D\u0D4E\u0D60\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1]|[\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81]|[\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3]|[\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6]|[\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A]|[\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081]|[\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D]|[\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0]|[\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310]|[\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F4\u1401-\u166C]|[\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u1700-\u170C\u170E-\u1711]|[\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7]|[\u17DC\u1820-\u1877\u1880-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191C]|[\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19C1-\u19C7\u1A00-\u1A16]|[\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF]|[\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1CE9-\u1CEC]|[\u1CEE-\u1CF1\u1CF5\u1CF6\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D]|[\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D]|[\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3]|[\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F]|[\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128]|[\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2183\u2184]|[\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3]|[\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6]|[\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE]|[\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005\u3006\u3031-\u3035\u303B\u303C]|[\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D]|[\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FCC]|[\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B]|[\uA640-\uA66E\uA67F-\uA697\uA6A0-\uA6E5\uA717-\uA71F\uA722-\uA788]|[\uA78B-\uA78E\uA790-\uA793\uA7A0-\uA7AA\uA7F8-\uA801\uA803-\uA805]|[\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB]|[\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uAA00-\uAA28]|[\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA80-\uAAAF\uAAB1\uAAB5]|[\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4]|[\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E]|[\uABC0-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D]|[\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36]|[\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D]|[\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC]|[\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF]|[\uFFD2-\uFFD7\uFFDA-\uFFDC])/,/^(?:\|)/,/^(?:\()/,/^(?:\))/,/^(?:\[)/,/^(?:\])/,/^(?:\{)/,/^(?:\})/,/^(?:")/,/^(?:(\r?\n)+)/,/^(?:\s)/,/^(?:$)/],conditions:{close_directive:{rules:[],inclusive:!1},arg_directive:{rules:[3,4],inclusive:!1},type_directive:{rules:[2,3],inclusive:!1},open_directive:{rules:[1],inclusive:!1},callbackargs:{rules:[30,31],inclusive:!1},callbackname:{rules:[27,28,29],inclusive:!1},href:{rules:[24,25],inclusive:!1},click:{rules:[33,34],inclusive:!1},vertex:{rules:[],inclusive:!1},dir:{rules:[43,44,45,46,47,48,49,50,51,52,53],inclusive:!1},acc_descr_multiline:{rules:[12,13],inclusive:!1},acc_descr:{rules:[10],inclusive:!1},acc_title:{rules:[8],inclusive:!1},string:{rules:[15,16],inclusive:!1},INITIAL:{rules:[0,5,6,7,9,11,14,17,18,19,20,21,22,23,26,32,35,36,37,38,39,40,41,42,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112],inclusive:!0}}};function re(){this.yy={}}return ee.lexer=ne,re.prototype=ee,ee.Parser=re,new re}();e.parser=r,e.Parser=r.Parser,e.parse=function(){return r.parse.apply(r,arguments)},e.main=function(t){t[1]||(console.log("Usage: "+t[0]+" FILE"),process.exit(1));var r=n(5354).readFileSync(n(6470).normalize(t[1]),"utf8");return e.parser.parse(r)},n.c[n.s]===t&&e.main(process.argv.slice(1))},9959:(t,e,n)=>{t=n.nmd(t);var r=function(){var t=function(t,e,n,r){for(n=n||{},r=t.length;r--;n[t[r]]=e);return n},e=[1,3],n=[1,5],r=[7,9,11,12,13,14,15,16,17,18,19,20,22,24,25,27,34,39],i=[1,15],a=[1,16],o=[1,17],s=[1,18],c=[1,19],u=[1,20],l=[1,21],h=[1,22],f=[1,23],d=[1,24],p=[1,25],g=[1,26],y=[1,28],m=[1,30],v=[1,33],b=[5,7,9,11,12,13,14,15,16,17,18,19,20,22,24,25,27,34,39],_={trace:function(){},yy:{},symbols_:{error:2,start:3,directive:4,gantt:5,document:6,EOF:7,line:8,SPACE:9,statement:10,NL:11,dateFormat:12,inclusiveEndDates:13,topAxis:14,axisFormat:15,excludes:16,includes:17,todayMarker:18,title:19,acc_title:20,acc_title_value:21,acc_descr:22,acc_descr_value:23,acc_descr_multiline_value:24,section:25,clickStatement:26,taskTxt:27,taskData:28,openDirective:29,typeDirective:30,closeDirective:31,":":32,argDirective:33,click:34,callbackname:35,callbackargs:36,href:37,clickStatementDebug:38,open_directive:39,type_directive:40,arg_directive:41,close_directive:42,$accept:0,$end:1},terminals_:{2:"error",5:"gantt",7:"EOF",9:"SPACE",11:"NL",12:"dateFormat",13:"inclusiveEndDates",14:"topAxis",15:"axisFormat",16:"excludes",17:"includes",18:"todayMarker",19:"title",20:"acc_title",21:"acc_title_value",22:"acc_descr",23:"acc_descr_value",24:"acc_descr_multiline_value",25:"section",27:"taskTxt",28:"taskData",32:":",34:"click",35:"callbackname",36:"callbackargs",37:"href",39:"open_directive",40:"type_directive",41:"arg_directive",42:"close_directive"},productions_:[0,[3,2],[3,3],[6,0],[6,2],[8,2],[8,1],[8,1],[8,1],[10,1],[10,1],[10,1],[10,1],[10,1],[10,1],[10,1],[10,1],[10,2],[10,2],[10,1],[10,1],[10,1],[10,2],[10,1],[4,4],[4,6],[26,2],[26,3],[26,3],[26,4],[26,3],[26,4],[26,2],[38,2],[38,3],[38,3],[38,4],[38,3],[38,4],[38,2],[29,1],[30,1],[33,1],[31,1]],performAction:function(t,e,n,r,i,a,o){var s=a.length-1;switch(i){case 2:return a[s-1];case 3:case 7:case 8:this.$=[];break;case 4:a[s-1].push(a[s]),this.$=a[s-1];break;case 5:case 6:this.$=a[s];break;case 9:r.setDateFormat(a[s].substr(11)),this.$=a[s].substr(11);break;case 10:r.enableInclusiveEndDates(),this.$=a[s].substr(18);break;case 11:r.TopAxis(),this.$=a[s].substr(8);break;case 12:r.setAxisFormat(a[s].substr(11)),this.$=a[s].substr(11);break;case 13:r.setExcludes(a[s].substr(9)),this.$=a[s].substr(9);break;case 14:r.setIncludes(a[s].substr(9)),this.$=a[s].substr(9);break;case 15:r.setTodayMarker(a[s].substr(12)),this.$=a[s].substr(12);break;case 16:r.setTitle(a[s].substr(6)),this.$=a[s].substr(6);break;case 17:this.$=a[s].trim(),r.setTitle(this.$);break;case 18:case 19:this.$=a[s].trim(),r.setAccDescription(this.$);break;case 20:r.addSection(a[s].substr(8)),this.$=a[s].substr(8);break;case 22:r.addTask(a[s-1],a[s]),this.$="task";break;case 26:this.$=a[s-1],r.setClickEvent(a[s-1],a[s],null);break;case 27:this.$=a[s-2],r.setClickEvent(a[s-2],a[s-1],a[s]);break;case 28:this.$=a[s-2],r.setClickEvent(a[s-2],a[s-1],null),r.setLink(a[s-2],a[s]);break;case 29:this.$=a[s-3],r.setClickEvent(a[s-3],a[s-2],a[s-1]),r.setLink(a[s-3],a[s]);break;case 30:this.$=a[s-2],r.setClickEvent(a[s-2],a[s],null),r.setLink(a[s-2],a[s-1]);break;case 31:this.$=a[s-3],r.setClickEvent(a[s-3],a[s-1],a[s]),r.setLink(a[s-3],a[s-2]);break;case 32:this.$=a[s-1],r.setLink(a[s-1],a[s]);break;case 33:case 39:this.$=a[s-1]+" "+a[s];break;case 34:case 35:case 37:this.$=a[s-2]+" "+a[s-1]+" "+a[s];break;case 36:case 38:this.$=a[s-3]+" "+a[s-2]+" "+a[s-1]+" "+a[s];break;case 40:r.parseDirective("%%{","open_directive");break;case 41:r.parseDirective(a[s],"type_directive");break;case 42:a[s]=a[s].trim().replace(/'/g,'"'),r.parseDirective(a[s],"arg_directive");break;case 43:r.parseDirective("}%%","close_directive","gantt")}},table:[{3:1,4:2,5:e,29:4,39:n},{1:[3]},{3:6,4:2,5:e,29:4,39:n},t(r,[2,3],{6:7}),{30:8,40:[1,9]},{40:[2,40]},{1:[2,1]},{4:29,7:[1,10],8:11,9:[1,12],10:13,11:[1,14],12:i,13:a,14:o,15:s,16:c,17:u,18:l,19:h,20:f,22:d,24:p,25:g,26:27,27:y,29:4,34:m,39:n},{31:31,32:[1,32],42:v},t([32,42],[2,41]),t(r,[2,8],{1:[2,2]}),t(r,[2,4]),{4:29,10:34,12:i,13:a,14:o,15:s,16:c,17:u,18:l,19:h,20:f,22:d,24:p,25:g,26:27,27:y,29:4,34:m,39:n},t(r,[2,6]),t(r,[2,7]),t(r,[2,9]),t(r,[2,10]),t(r,[2,11]),t(r,[2,12]),t(r,[2,13]),t(r,[2,14]),t(r,[2,15]),t(r,[2,16]),{21:[1,35]},{23:[1,36]},t(r,[2,19]),t(r,[2,20]),t(r,[2,21]),{28:[1,37]},t(r,[2,23]),{35:[1,38],37:[1,39]},{11:[1,40]},{33:41,41:[1,42]},{11:[2,43]},t(r,[2,5]),t(r,[2,17]),t(r,[2,18]),t(r,[2,22]),t(r,[2,26],{36:[1,43],37:[1,44]}),t(r,[2,32],{35:[1,45]}),t(b,[2,24]),{31:46,42:v},{42:[2,42]},t(r,[2,27],{37:[1,47]}),t(r,[2,28]),t(r,[2,30],{36:[1,48]}),{11:[1,49]},t(r,[2,29]),t(r,[2,31]),t(b,[2,25])],defaultActions:{5:[2,40],6:[2,1],33:[2,43],42:[2,42]},parseError:function(t,e){if(!e.recoverable){var n=new Error(t);throw n.hash=e,n}this.trace(t)},parse:function(t){var e=this,n=[0],r=[],i=[null],a=[],o=this.table,s="",c=0,u=0,l=0,h=2,f=1,d=a.slice.call(arguments,1),p=Object.create(this.lexer),g={yy:{}};for(var y in this.yy)Object.prototype.hasOwnProperty.call(this.yy,y)&&(g.yy[y]=this.yy[y]);p.setInput(t,g.yy),g.yy.lexer=p,g.yy.parser=this,void 0===p.yylloc&&(p.yylloc={});var m=p.yylloc;a.push(m);var v=p.options&&p.options.ranges;function b(){var t;return"number"!=typeof(t=r.pop()||p.lex()||f)&&(t instanceof Array&&(t=(r=t).pop()),t=e.symbols_[t]||t),t}"function"==typeof g.yy.parseError?this.parseError=g.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;for(var _,x,w,k,T,C,E,S,A,M={};;){if(w=n[n.length-1],this.defaultActions[w]?k=this.defaultActions[w]:(null==_&&(_=b()),k=o[w]&&o[w][_]),void 0===k||!k.length||!k[0]){var N="";for(C in A=[],o[w])this.terminals_[C]&&C>h&&A.push("'"+this.terminals_[C]+"'");N=p.showPosition?"Parse error on line "+(c+1)+":\n"+p.showPosition()+"\nExpecting "+A.join(", ")+", got '"+(this.terminals_[_]||_)+"'":"Parse error on line "+(c+1)+": Unexpected "+(_==f?"end of input":"'"+(this.terminals_[_]||_)+"'"),this.parseError(N,{text:p.match,token:this.terminals_[_]||_,line:p.yylineno,loc:m,expected:A})}if(k[0]instanceof Array&&k.length>1)throw new Error("Parse Error: multiple actions possible at state: "+w+", token: "+_);switch(k[0]){case 1:n.push(_),i.push(p.yytext),a.push(p.yylloc),n.push(k[1]),_=null,x?(_=x,x=null):(u=p.yyleng,s=p.yytext,c=p.yylineno,m=p.yylloc,l>0&&l--);break;case 2:if(E=this.productions_[k[1]][1],M.$=i[i.length-E],M._$={first_line:a[a.length-(E||1)].first_line,last_line:a[a.length-1].last_line,first_column:a[a.length-(E||1)].first_column,last_column:a[a.length-1].last_column},v&&(M._$.range=[a[a.length-(E||1)].range[0],a[a.length-1].range[1]]),void 0!==(T=this.performAction.apply(M,[s,u,c,g.yy,k[1],i,a].concat(d))))return T;E&&(n=n.slice(0,-1*E*2),i=i.slice(0,-1*E),a=a.slice(0,-1*E)),n.push(this.productions_[k[1]][0]),i.push(M.$),a.push(M._$),S=o[n[n.length-2]][n[n.length-1]],n.push(S);break;case 3:return!0}}return!0}},x={EOF:1,parseError:function(t,e){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,e)},setInput:function(t,e){return this.yy=e||this.yy||{},this._input=t,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},input:function(){var t=this._input[0];return this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t,t.match(/(?:\r\n?|\n).*/g)?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),t},unput:function(t){var e=t.length,n=t.split(/(?:\r\n?|\n)/g);this._input=t+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-e),this.offset-=e;var r=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),n.length-1&&(this.yylineno-=n.length-1);var i=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:n?(n.length===r.length?this.yylloc.first_column:0)+r[r.length-n.length].length-n[0].length:this.yylloc.first_column-e},this.options.ranges&&(this.yylloc.range=[i[0],i[0]+this.yyleng-e]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject:function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):this.parseError("Lexical error on line "+(this.yylineno+1)+". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},less:function(t){this.unput(this.match.slice(t))},pastInput:function(){var t=this.matched.substr(0,this.matched.length-this.match.length);return(t.length>20?"...":"")+t.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var t=this.match;return t.length<20&&(t+=this._input.substr(0,20-t.length)),(t.substr(0,20)+(t.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var t=this.pastInput(),e=new Array(t.length+1).join("-");return t+this.upcomingInput()+"\n"+e+"^"},test_match:function(t,e){var n,r,i;if(this.options.backtrack_lexer&&(i={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(i.yylloc.range=this.yylloc.range.slice(0))),(r=t[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=r.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:r?r[r.length-1].length-r[r.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],n=this.performAction.call(this,this.yy,this,e,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),n)return n;if(this._backtrack){for(var a in i)this[a]=i[a];return!1}return!1},next:function(){if(this.done)return this.EOF;var t,e,n,r;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var i=this._currentRules(),a=0;ae[0].length)){if(e=n,r=a,this.options.backtrack_lexer){if(!1!==(t=this.test_match(n,i[a])))return t;if(this._backtrack){e=!1;continue}return!1}if(!this.options.flex)break}return e?!1!==(t=this.test_match(e,i[r]))&&t:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){return this.next()||this.lex()},begin:function(t){this.conditionStack.push(t)},popState:function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]},_currentRules:function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},topState:function(t){return(t=this.conditionStack.length-1-Math.abs(t||0))>=0?this.conditionStack[t]:"INITIAL"},pushState:function(t){this.begin(t)},stateStackSize:function(){return this.conditionStack.length},options:{"case-insensitive":!0},performAction:function(t,e,n,r){switch(n){case 0:return this.begin("open_directive"),39;case 1:return this.begin("type_directive"),40;case 2:return this.popState(),this.begin("arg_directive"),32;case 3:return this.popState(),this.popState(),42;case 4:return 41;case 5:return this.begin("acc_title"),20;case 6:return this.popState(),"acc_title_value";case 7:return this.begin("acc_descr"),22;case 8:return this.popState(),"acc_descr_value";case 9:this.begin("acc_descr_multiline");break;case 10:case 20:case 23:case 26:case 29:this.popState();break;case 11:return"acc_descr_multiline_value";case 12:case 13:case 14:case 16:case 17:case 18:break;case 15:return 11;case 19:this.begin("href");break;case 21:return 37;case 22:this.begin("callbackname");break;case 24:this.popState(),this.begin("callbackargs");break;case 25:return 35;case 27:return 36;case 28:this.begin("click");break;case 30:return 34;case 31:return 5;case 32:return 12;case 33:return 13;case 34:return 14;case 35:return 15;case 36:return 17;case 37:return 16;case 38:return 18;case 39:return"date";case 40:return 19;case 41:return"accDescription";case 42:return 25;case 43:return 27;case 44:return 28;case 45:return 32;case 46:return 7;case 47:return"INVALID"}},rules:[/^(?:%%\{)/i,/^(?:((?:(?!\}%%)[^:.])*))/i,/^(?::)/i,/^(?:\}%%)/i,/^(?:((?:(?!\}%%).|\n)*))/i,/^(?:accTitle\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*\{\s*)/i,/^(?:[\}])/i,/^(?:[^\}]*)/i,/^(?:%%(?!\{)*[^\n]*)/i,/^(?:[^\}]%%*[^\n]*)/i,/^(?:%%*[^\n]*[\n]*)/i,/^(?:[\n]+)/i,/^(?:\s+)/i,/^(?:#[^\n]*)/i,/^(?:%[^\n]*)/i,/^(?:href[\s]+["])/i,/^(?:["])/i,/^(?:[^"]*)/i,/^(?:call[\s]+)/i,/^(?:\([\s]*\))/i,/^(?:\()/i,/^(?:[^(]*)/i,/^(?:\))/i,/^(?:[^)]*)/i,/^(?:click[\s]+)/i,/^(?:[\s\n])/i,/^(?:[^\s\n]*)/i,/^(?:gantt\b)/i,/^(?:dateFormat\s[^#\n;]+)/i,/^(?:inclusiveEndDates\b)/i,/^(?:topAxis\b)/i,/^(?:axisFormat\s[^#\n;]+)/i,/^(?:includes\s[^#\n;]+)/i,/^(?:excludes\s[^#\n;]+)/i,/^(?:todayMarker\s[^\n;]+)/i,/^(?:\d\d\d\d-\d\d-\d\d\b)/i,/^(?:title\s[^#\n;]+)/i,/^(?:accDescription\s[^#\n;]+)/i,/^(?:section\s[^#:\n;]+)/i,/^(?:[^#:\n;]+)/i,/^(?::[^#\n;]+)/i,/^(?::)/i,/^(?:$)/i,/^(?:.)/i],conditions:{acc_descr_multiline:{rules:[10,11],inclusive:!1},acc_descr:{rules:[8],inclusive:!1},acc_title:{rules:[6],inclusive:!1},close_directive:{rules:[],inclusive:!1},arg_directive:{rules:[3,4],inclusive:!1},type_directive:{rules:[2,3],inclusive:!1},open_directive:{rules:[1],inclusive:!1},callbackargs:{rules:[26,27],inclusive:!1},callbackname:{rules:[23,24,25],inclusive:!1},href:{rules:[20,21],inclusive:!1},click:{rules:[29,30],inclusive:!1},INITIAL:{rules:[0,5,7,9,12,13,14,15,16,17,18,19,22,28,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47],inclusive:!0}}};function w(){this.yy={}}return _.lexer=x,w.prototype=_,_.Parser=w,new w}();e.parser=r,e.Parser=r.Parser,e.parse=function(){return r.parse.apply(r,arguments)},e.main=function(t){t[1]||(console.log("Usage: "+t[0]+" FILE"),process.exit(1));var r=n(6878).readFileSync(n(6470).normalize(t[1]),"utf8");return e.parser.parse(r)},n.c[n.s]===t&&e.main(process.argv.slice(1))},2553:(t,e,n)=>{t=n.nmd(t);var r=function(){var t=function(t,e,n,r){for(n=n||{},r=t.length;r--;n[t[r]]=e);return n},e=[1,4],n=[1,7],r=[1,5],i=[1,9],a=[1,6],o=[2,6],s=[1,16],c=[6,8,14,19,21,23,24,26,28,31,34,47,51],u=[8,14,19,21,23,24,26,28,31,34],l=[8,13,14,19,21,23,24,26,28,31,34],h=[1,26],f=[6,8,14,47,51],d=[8,14,51],p=[1,61],g=[1,62],y=[1,63],m=[8,14,32,38,39,51],v={trace:function(){},yy:{},symbols_:{error:2,start:3,eol:4,directive:5,GG:6,document:7,EOF:8,":":9,DIR:10,options:11,body:12,OPT:13,NL:14,line:15,statement:16,commitStatement:17,mergeStatement:18,acc_title:19,acc_title_value:20,acc_descr:21,acc_descr_value:22,acc_descr_multiline_value:23,section:24,branchStatement:25,CHECKOUT:26,ID:27,BRANCH:28,ORDER:29,NUM:30,MERGE:31,COMMIT_TAG:32,STR:33,COMMIT:34,commit_arg:35,COMMIT_TYPE:36,commitType:37,COMMIT_ID:38,COMMIT_MSG:39,NORMAL:40,REVERSE:41,HIGHLIGHT:42,openDirective:43,typeDirective:44,closeDirective:45,argDirective:46,open_directive:47,type_directive:48,arg_directive:49,close_directive:50,";":51,$accept:0,$end:1},terminals_:{2:"error",6:"GG",8:"EOF",9:":",10:"DIR",13:"OPT",14:"NL",19:"acc_title",20:"acc_title_value",21:"acc_descr",22:"acc_descr_value",23:"acc_descr_multiline_value",24:"section",26:"CHECKOUT",27:"ID",28:"BRANCH",29:"ORDER",30:"NUM",31:"MERGE",32:"COMMIT_TAG",33:"STR",34:"COMMIT",36:"COMMIT_TYPE",38:"COMMIT_ID",39:"COMMIT_MSG",40:"NORMAL",41:"REVERSE",42:"HIGHLIGHT",47:"open_directive",48:"type_directive",49:"arg_directive",50:"close_directive",51:";"},productions_:[0,[3,2],[3,2],[3,3],[3,4],[3,5],[7,0],[7,2],[11,2],[11,1],[12,0],[12,2],[15,2],[15,1],[16,1],[16,1],[16,2],[16,2],[16,1],[16,1],[16,1],[16,2],[25,2],[25,4],[18,2],[18,4],[17,2],[17,3],[17,3],[17,5],[17,5],[17,3],[17,5],[17,5],[17,5],[17,5],[17,7],[17,7],[17,7],[17,7],[17,7],[17,7],[17,3],[17,5],[17,5],[17,5],[17,5],[17,5],[17,5],[17,7],[17,7],[17,7],[17,7],[17,7],[17,7],[17,7],[17,7],[17,7],[17,7],[17,7],[17,7],[17,7],[17,7],[17,7],[17,7],[17,7],[17,7],[17,9],[17,9],[17,9],[17,9],[17,9],[17,9],[17,9],[17,9],[17,9],[17,9],[17,9],[17,9],[17,9],[17,9],[17,9],[17,9],[17,9],[17,9],[17,9],[17,9],[17,9],[17,9],[17,9],[17,9],[35,0],[35,1],[37,1],[37,1],[37,1],[5,3],[5,5],[43,1],[44,1],[46,1],[45,1],[4,1],[4,1],[4,1]],performAction:function(t,e,n,r,i,a,o){var s=a.length-1;switch(i){case 3:return a[s];case 4:return a[s-1];case 5:return r.setDirection(a[s-3]),a[s-1];case 7:r.setOptions(a[s-1]),this.$=a[s];break;case 8:a[s-1]+=a[s],this.$=a[s-1];break;case 10:this.$=[];break;case 11:a[s-1].push(a[s]),this.$=a[s-1];break;case 12:this.$=a[s-1];break;case 16:this.$=a[s].trim(),r.setTitle(this.$);break;case 17:case 18:this.$=a[s].trim(),r.setAccDescription(this.$);break;case 19:r.addSection(a[s].substr(8)),this.$=a[s].substr(8);break;case 21:r.checkout(a[s]);break;case 22:r.branch(a[s]);break;case 23:r.branch(a[s-2],a[s]);break;case 24:r.merge(a[s]);break;case 25:r.merge(a[s-2],a[s]);break;case 26:r.commit(a[s]);break;case 27:r.commit("","",r.commitType.NORMAL,a[s]);break;case 28:r.commit("","",a[s],"");break;case 29:r.commit("","",a[s],a[s-2]);break;case 30:r.commit("","",a[s-2],a[s]);break;case 31:r.commit("",a[s],r.commitType.NORMAL,"");break;case 32:r.commit("",a[s-2],r.commitType.NORMAL,a[s]);break;case 33:r.commit("",a[s],r.commitType.NORMAL,a[s-2]);break;case 34:r.commit("",a[s-2],a[s],"");break;case 35:r.commit("",a[s],a[s-2],"");break;case 36:r.commit("",a[s-4],a[s-2],a[s]);break;case 37:r.commit("",a[s-4],a[s],a[s-2]);break;case 38:r.commit("",a[s-2],a[s-4],a[s]);break;case 39:r.commit("",a[s],a[s-4],a[s-2]);break;case 40:r.commit("",a[s],a[s-2],a[s-4]);break;case 41:r.commit("",a[s-2],a[s],a[s-4]);break;case 42:r.commit(a[s],"",r.commitType.NORMAL,"");break;case 43:r.commit(a[s],"",r.commitType.NORMAL,a[s-2]);break;case 44:r.commit(a[s-2],"",r.commitType.NORMAL,a[s]);break;case 45:r.commit(a[s-2],"",a[s],"");break;case 46:r.commit(a[s],"",a[s-2],"");break;case 47:r.commit(a[s],a[s-2],r.commitType.NORMAL,"");break;case 48:r.commit(a[s-2],a[s],r.commitType.NORMAL,"");break;case 49:r.commit(a[s-4],"",a[s-2],a[s]);break;case 50:r.commit(a[s-4],"",a[s],a[s-2]);break;case 51:r.commit(a[s-2],"",a[s-4],a[s]);break;case 52:r.commit(a[s],"",a[s-4],a[s-2]);break;case 53:r.commit(a[s],"",a[s-2],a[s-4]);break;case 54:r.commit(a[s-2],"",a[s],a[s-4]);break;case 55:r.commit(a[s-4],a[s],a[s-2],"");break;case 56:r.commit(a[s-4],a[s-2],a[s],"");break;case 57:r.commit(a[s-2],a[s],a[s-4],"");break;case 58:r.commit(a[s],a[s-2],a[s-4],"");break;case 59:r.commit(a[s],a[s-4],a[s-2],"");break;case 60:r.commit(a[s-2],a[s-4],a[s],"");break;case 61:r.commit(a[s-4],a[s],r.commitType.NORMAL,a[s-2]);break;case 62:r.commit(a[s-4],a[s-2],r.commitType.NORMAL,a[s]);break;case 63:r.commit(a[s-2],a[s],r.commitType.NORMAL,a[s-4]);break;case 64:r.commit(a[s],a[s-2],r.commitType.NORMAL,a[s-4]);break;case 65:r.commit(a[s],a[s-4],r.commitType.NORMAL,a[s-2]);break;case 66:r.commit(a[s-2],a[s-4],r.commitType.NORMAL,a[s]);break;case 67:r.commit(a[s-6],a[s-4],a[s-2],a[s]);break;case 68:r.commit(a[s-6],a[s-4],a[s],a[s-2]);break;case 69:r.commit(a[s-6],a[s-2],a[s-4],a[s]);break;case 70:r.commit(a[s-6],a[s],a[s-4],a[s-2]);break;case 71:r.commit(a[s-6],a[s-2],a[s],a[s-4]);break;case 72:r.commit(a[s-6],a[s],a[s-2],a[s-4]);break;case 73:r.commit(a[s-4],a[s-6],a[s-2],a[s]);break;case 74:r.commit(a[s-4],a[s-6],a[s],a[s-2]);break;case 75:r.commit(a[s-2],a[s-6],a[s-4],a[s]);break;case 76:r.commit(a[s],a[s-6],a[s-4],a[s-2]);break;case 77:r.commit(a[s-2],a[s-6],a[s],a[s-4]);break;case 78:r.commit(a[s],a[s-6],a[s-2],a[s-4]);break;case 79:r.commit(a[s],a[s-4],a[s-2],a[s-6]);break;case 80:r.commit(a[s-2],a[s-4],a[s],a[s-6]);break;case 81:r.commit(a[s],a[s-2],a[s-4],a[s-6]);break;case 82:r.commit(a[s-2],a[s],a[s-4],a[s-6]);break;case 83:r.commit(a[s-4],a[s-2],a[s],a[s-6]);break;case 84:r.commit(a[s-4],a[s],a[s-2],a[s-6]);break;case 85:r.commit(a[s-2],a[s-4],a[s-6],a[s]);break;case 86:r.commit(a[s],a[s-4],a[s-6],a[s-2]);break;case 87:r.commit(a[s-2],a[s],a[s-6],a[s-4]);break;case 88:r.commit(a[s],a[s-2],a[s-6],a[s-4]);break;case 89:r.commit(a[s-4],a[s-2],a[s-6],a[s]);break;case 90:r.commit(a[s-4],a[s],a[s-6],a[s-2]);break;case 91:this.$="";break;case 92:this.$=a[s];break;case 93:this.$=r.commitType.NORMAL;break;case 94:this.$=r.commitType.REVERSE;break;case 95:this.$=r.commitType.HIGHLIGHT;break;case 98:r.parseDirective("%%{","open_directive");break;case 99:r.parseDirective(a[s],"type_directive");break;case 100:a[s]=a[s].trim().replace(/'/g,'"'),r.parseDirective(a[s],"arg_directive");break;case 101:r.parseDirective("}%%","close_directive","gitGraph")}},table:[{3:1,4:2,5:3,6:e,8:n,14:r,43:8,47:i,51:a},{1:[3]},{3:10,4:2,5:3,6:e,8:n,14:r,43:8,47:i,51:a},{3:11,4:2,5:3,6:e,8:n,14:r,43:8,47:i,51:a},{7:12,8:o,9:[1,13],10:[1,14],11:15,14:s},t(c,[2,102]),t(c,[2,103]),t(c,[2,104]),{44:17,48:[1,18]},{48:[2,98]},{1:[2,1]},{1:[2,2]},{8:[1,19]},{7:20,8:o,11:15,14:s},{9:[1,21]},t(u,[2,10],{12:22,13:[1,23]}),t(l,[2,9]),{9:[1,25],45:24,50:h},t([9,50],[2,99]),{1:[2,3]},{8:[1,27]},{7:28,8:o,11:15,14:s},{8:[2,7],14:[1,31],15:29,16:30,17:32,18:33,19:[1,34],21:[1,35],23:[1,36],24:[1,37],25:38,26:[1,39],28:[1,42],31:[1,41],34:[1,40]},t(l,[2,8]),t(f,[2,96]),{46:43,49:[1,44]},t(f,[2,101]),{1:[2,4]},{8:[1,45]},t(u,[2,11]),{4:46,8:n,14:r,51:a},t(u,[2,13]),t(d,[2,14]),t(d,[2,15]),{20:[1,47]},{22:[1,48]},t(d,[2,18]),t(d,[2,19]),t(d,[2,20]),{27:[1,49]},t(d,[2,91],{35:50,32:[1,51],33:[1,55],36:[1,52],38:[1,53],39:[1,54]}),{27:[1,56]},{27:[1,57]},{45:58,50:h},{50:[2,100]},{1:[2,5]},t(u,[2,12]),t(d,[2,16]),t(d,[2,17]),t(d,[2,21]),t(d,[2,26]),{33:[1,59]},{37:60,40:p,41:g,42:y},{33:[1,64]},{33:[1,65]},t(d,[2,92]),t(d,[2,24],{32:[1,66]}),t(d,[2,22],{29:[1,67]}),t(f,[2,97]),t(d,[2,27],{36:[1,68],38:[1,69],39:[1,70]}),t(d,[2,28],{32:[1,71],38:[1,72],39:[1,73]}),t(m,[2,93]),t(m,[2,94]),t(m,[2,95]),t(d,[2,31],{32:[1,74],36:[1,75],39:[1,76]}),t(d,[2,42],{32:[1,77],36:[1,78],38:[1,79]}),{33:[1,80]},{30:[1,81]},{37:82,40:p,41:g,42:y},{33:[1,83]},{33:[1,84]},{33:[1,85]},{33:[1,86]},{33:[1,87]},{33:[1,88]},{37:89,40:p,41:g,42:y},{33:[1,90]},{33:[1,91]},{37:92,40:p,41:g,42:y},{33:[1,93]},t(d,[2,25]),t(d,[2,23]),t(d,[2,29],{38:[1,94],39:[1,95]}),t(d,[2,33],{36:[1,96],39:[1,97]}),t(d,[2,43],{36:[1,98],38:[1,99]}),t(d,[2,30],{38:[1,100],39:[1,101]}),t(d,[2,35],{32:[1,102],39:[1,103]}),t(d,[2,46],{32:[1,104],38:[1,105]}),t(d,[2,32],{36:[1,106],39:[1,107]}),t(d,[2,34],{32:[1,108],39:[1,109]}),t(d,[2,47],{32:[1,111],36:[1,110]}),t(d,[2,44],{36:[1,112],38:[1,113]}),t(d,[2,45],{32:[1,114],38:[1,115]}),t(d,[2,48],{32:[1,117],36:[1,116]}),{33:[1,118]},{33:[1,119]},{37:120,40:p,41:g,42:y},{33:[1,121]},{37:122,40:p,41:g,42:y},{33:[1,123]},{33:[1,124]},{33:[1,125]},{33:[1,126]},{33:[1,127]},{33:[1,128]},{33:[1,129]},{37:130,40:p,41:g,42:y},{33:[1,131]},{33:[1,132]},{33:[1,133]},{37:134,40:p,41:g,42:y},{33:[1,135]},{37:136,40:p,41:g,42:y},{33:[1,137]},{33:[1,138]},{33:[1,139]},{37:140,40:p,41:g,42:y},{33:[1,141]},t(d,[2,40],{39:[1,142]}),t(d,[2,53],{38:[1,143]}),t(d,[2,41],{39:[1,144]}),t(d,[2,64],{36:[1,145]}),t(d,[2,54],{38:[1,146]}),t(d,[2,63],{36:[1,147]}),t(d,[2,39],{39:[1,148]}),t(d,[2,52],{38:[1,149]}),t(d,[2,38],{39:[1,150]}),t(d,[2,58],{32:[1,151]}),t(d,[2,51],{38:[1,152]}),t(d,[2,57],{32:[1,153]}),t(d,[2,37],{39:[1,154]}),t(d,[2,65],{36:[1,155]}),t(d,[2,36],{39:[1,156]}),t(d,[2,59],{32:[1,157]}),t(d,[2,60],{32:[1,158]}),t(d,[2,66],{36:[1,159]}),t(d,[2,50],{38:[1,160]}),t(d,[2,61],{36:[1,161]}),t(d,[2,49],{38:[1,162]}),t(d,[2,55],{32:[1,163]}),t(d,[2,56],{32:[1,164]}),t(d,[2,62],{36:[1,165]}),{33:[1,166]},{33:[1,167]},{33:[1,168]},{37:169,40:p,41:g,42:y},{33:[1,170]},{37:171,40:p,41:g,42:y},{33:[1,172]},{33:[1,173]},{33:[1,174]},{33:[1,175]},{33:[1,176]},{33:[1,177]},{33:[1,178]},{37:179,40:p,41:g,42:y},{33:[1,180]},{33:[1,181]},{33:[1,182]},{37:183,40:p,41:g,42:y},{33:[1,184]},{37:185,40:p,41:g,42:y},{33:[1,186]},{33:[1,187]},{33:[1,188]},{37:189,40:p,41:g,42:y},t(d,[2,81]),t(d,[2,82]),t(d,[2,79]),t(d,[2,80]),t(d,[2,84]),t(d,[2,83]),t(d,[2,88]),t(d,[2,87]),t(d,[2,86]),t(d,[2,85]),t(d,[2,90]),t(d,[2,89]),t(d,[2,78]),t(d,[2,77]),t(d,[2,76]),t(d,[2,75]),t(d,[2,73]),t(d,[2,74]),t(d,[2,72]),t(d,[2,71]),t(d,[2,70]),t(d,[2,69]),t(d,[2,67]),t(d,[2,68])],defaultActions:{9:[2,98],10:[2,1],11:[2,2],19:[2,3],27:[2,4],44:[2,100],45:[2,5]},parseError:function(t,e){if(!e.recoverable){var n=new Error(t);throw n.hash=e,n}this.trace(t)},parse:function(t){var e=this,n=[0],r=[],i=[null],a=[],o=this.table,s="",c=0,u=0,l=0,h=2,f=1,d=a.slice.call(arguments,1),p=Object.create(this.lexer),g={yy:{}};for(var y in this.yy)Object.prototype.hasOwnProperty.call(this.yy,y)&&(g.yy[y]=this.yy[y]);p.setInput(t,g.yy),g.yy.lexer=p,g.yy.parser=this,void 0===p.yylloc&&(p.yylloc={});var m=p.yylloc;a.push(m);var v=p.options&&p.options.ranges;function b(){var t;return"number"!=typeof(t=r.pop()||p.lex()||f)&&(t instanceof Array&&(t=(r=t).pop()),t=e.symbols_[t]||t),t}"function"==typeof g.yy.parseError?this.parseError=g.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;for(var _,x,w,k,T,C,E,S,A,M={};;){if(w=n[n.length-1],this.defaultActions[w]?k=this.defaultActions[w]:(null==_&&(_=b()),k=o[w]&&o[w][_]),void 0===k||!k.length||!k[0]){var N="";for(C in A=[],o[w])this.terminals_[C]&&C>h&&A.push("'"+this.terminals_[C]+"'");N=p.showPosition?"Parse error on line "+(c+1)+":\n"+p.showPosition()+"\nExpecting "+A.join(", ")+", got '"+(this.terminals_[_]||_)+"'":"Parse error on line "+(c+1)+": Unexpected "+(_==f?"end of input":"'"+(this.terminals_[_]||_)+"'"),this.parseError(N,{text:p.match,token:this.terminals_[_]||_,line:p.yylineno,loc:m,expected:A})}if(k[0]instanceof Array&&k.length>1)throw new Error("Parse Error: multiple actions possible at state: "+w+", token: "+_);switch(k[0]){case 1:n.push(_),i.push(p.yytext),a.push(p.yylloc),n.push(k[1]),_=null,x?(_=x,x=null):(u=p.yyleng,s=p.yytext,c=p.yylineno,m=p.yylloc,l>0&&l--);break;case 2:if(E=this.productions_[k[1]][1],M.$=i[i.length-E],M._$={first_line:a[a.length-(E||1)].first_line,last_line:a[a.length-1].last_line,first_column:a[a.length-(E||1)].first_column,last_column:a[a.length-1].last_column},v&&(M._$.range=[a[a.length-(E||1)].range[0],a[a.length-1].range[1]]),void 0!==(T=this.performAction.apply(M,[s,u,c,g.yy,k[1],i,a].concat(d))))return T;E&&(n=n.slice(0,-1*E*2),i=i.slice(0,-1*E),a=a.slice(0,-1*E)),n.push(this.productions_[k[1]][0]),i.push(M.$),a.push(M._$),S=o[n[n.length-2]][n[n.length-1]],n.push(S);break;case 3:return!0}}return!0}},b={EOF:1,parseError:function(t,e){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,e)},setInput:function(t,e){return this.yy=e||this.yy||{},this._input=t,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},input:function(){var t=this._input[0];return this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t,t.match(/(?:\r\n?|\n).*/g)?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),t},unput:function(t){var e=t.length,n=t.split(/(?:\r\n?|\n)/g);this._input=t+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-e),this.offset-=e;var r=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),n.length-1&&(this.yylineno-=n.length-1);var i=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:n?(n.length===r.length?this.yylloc.first_column:0)+r[r.length-n.length].length-n[0].length:this.yylloc.first_column-e},this.options.ranges&&(this.yylloc.range=[i[0],i[0]+this.yyleng-e]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject:function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):this.parseError("Lexical error on line "+(this.yylineno+1)+". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},less:function(t){this.unput(this.match.slice(t))},pastInput:function(){var t=this.matched.substr(0,this.matched.length-this.match.length);return(t.length>20?"...":"")+t.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var t=this.match;return t.length<20&&(t+=this._input.substr(0,20-t.length)),(t.substr(0,20)+(t.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var t=this.pastInput(),e=new Array(t.length+1).join("-");return t+this.upcomingInput()+"\n"+e+"^"},test_match:function(t,e){var n,r,i;if(this.options.backtrack_lexer&&(i={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(i.yylloc.range=this.yylloc.range.slice(0))),(r=t[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=r.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:r?r[r.length-1].length-r[r.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],n=this.performAction.call(this,this.yy,this,e,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),n)return n;if(this._backtrack){for(var a in i)this[a]=i[a];return!1}return!1},next:function(){if(this.done)return this.EOF;var t,e,n,r;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var i=this._currentRules(),a=0;ae[0].length)){if(e=n,r=a,this.options.backtrack_lexer){if(!1!==(t=this.test_match(n,i[a])))return t;if(this._backtrack){e=!1;continue}return!1}if(!this.options.flex)break}return e?!1!==(t=this.test_match(e,i[r]))&&t:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){return this.next()||this.lex()},begin:function(t){this.conditionStack.push(t)},popState:function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]},_currentRules:function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},topState:function(t){return(t=this.conditionStack.length-1-Math.abs(t||0))>=0?this.conditionStack[t]:"INITIAL"},pushState:function(t){this.begin(t)},stateStackSize:function(){return this.conditionStack.length},options:{"case-insensitive":!0},performAction:function(t,e,n,r){switch(n){case 0:return this.begin("open_directive"),47;case 1:return this.begin("type_directive"),48;case 2:return this.popState(),this.begin("arg_directive"),9;case 3:return this.popState(),this.popState(),50;case 4:return 49;case 5:return this.begin("acc_title"),19;case 6:return this.popState(),"acc_title_value";case 7:return this.begin("acc_descr"),21;case 8:return this.popState(),"acc_descr_value";case 9:this.begin("acc_descr_multiline");break;case 10:case 34:case 37:this.popState();break;case 11:return"acc_descr_multiline_value";case 12:return 14;case 13:case 14:case 15:break;case 16:return 6;case 17:return 34;case 18:return 38;case 19:return 36;case 20:return 39;case 21:return 40;case 22:return 41;case 23:return 42;case 24:return 32;case 25:return 28;case 26:return 29;case 27:return 31;case 28:return 26;case 29:case 30:return 10;case 31:return 9;case 32:return"CARET";case 33:this.begin("options");break;case 35:return 13;case 36:this.begin("string");break;case 38:return 33;case 39:return 30;case 40:return 27;case 41:return 8}},rules:[/^(?:%%\{)/i,/^(?:((?:(?!\}%%)[^:.])*))/i,/^(?::)/i,/^(?:\}%%)/i,/^(?:((?:(?!\}%%).|\n)*))/i,/^(?:accTitle\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*\{\s*)/i,/^(?:[\}])/i,/^(?:[^\}]*)/i,/^(?:(\r?\n)+)/i,/^(?:\s+)/i,/^(?:#[^\n]*)/i,/^(?:%[^\n]*)/i,/^(?:gitGraph\b)/i,/^(?:commit\b)/i,/^(?:id:)/i,/^(?:type:)/i,/^(?:msg:)/i,/^(?:NORMAL\b)/i,/^(?:REVERSE\b)/i,/^(?:HIGHLIGHT\b)/i,/^(?:tag:)/i,/^(?:branch\b)/i,/^(?:order:)/i,/^(?:merge\b)/i,/^(?:checkout\b)/i,/^(?:LR\b)/i,/^(?:BT\b)/i,/^(?::)/i,/^(?:\^)/i,/^(?:options\r?\n)/i,/^(?:[ \r\n\t]+end\b)/i,/^(?:[\s\S]+(?=[ \r\n\t]+end))/i,/^(?:["])/i,/^(?:["])/i,/^(?:[^"]*)/i,/^(?:[0-9]+)/i,/^(?:[a-zA-Z][-_\./a-zA-Z0-9]*[-_a-zA-Z0-9])/i,/^(?:$)/i],conditions:{acc_descr_multiline:{rules:[10,11],inclusive:!1},acc_descr:{rules:[8],inclusive:!1},acc_title:{rules:[6],inclusive:!1},close_directive:{rules:[],inclusive:!1},arg_directive:{rules:[3,4],inclusive:!1},type_directive:{rules:[2,3],inclusive:!1},open_directive:{rules:[1],inclusive:!1},options:{rules:[34,35],inclusive:!1},string:{rules:[37,38],inclusive:!1},INITIAL:{rules:[0,5,7,9,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,36,39,40,41],inclusive:!0}}};function _(){this.yy={}}return v.lexer=b,_.prototype=v,v.Parser=_,new _}();e.parser=r,e.Parser=r.Parser,e.parse=function(){return r.parse.apply(r,arguments)},e.main=function(t){t[1]||(console.log("Usage: "+t[0]+" FILE"),process.exit(1));var r=n(8183).readFileSync(n(6470).normalize(t[1]),"utf8");return e.parser.parse(r)},n.c[n.s]===t&&e.main(process.argv.slice(1))},6765:(t,e,n)=>{t=n.nmd(t);var r=function(){var t=function(t,e,n,r){for(n=n||{},r=t.length;r--;n[t[r]]=e);return n},e=[6,9,10],n={trace:function(){},yy:{},symbols_:{error:2,start:3,info:4,document:5,EOF:6,line:7,statement:8,NL:9,showInfo:10,$accept:0,$end:1},terminals_:{2:"error",4:"info",6:"EOF",9:"NL",10:"showInfo"},productions_:[0,[3,3],[5,0],[5,2],[7,1],[7,1],[8,1]],performAction:function(t,e,n,r,i,a,o){switch(a.length,i){case 1:return r;case 4:break;case 6:r.setInfo(!0)}},table:[{3:1,4:[1,2]},{1:[3]},t(e,[2,2],{5:3}),{6:[1,4],7:5,8:6,9:[1,7],10:[1,8]},{1:[2,1]},t(e,[2,3]),t(e,[2,4]),t(e,[2,5]),t(e,[2,6])],defaultActions:{4:[2,1]},parseError:function(t,e){if(!e.recoverable){var n=new Error(t);throw n.hash=e,n}this.trace(t)},parse:function(t){var e=this,n=[0],r=[],i=[null],a=[],o=this.table,s="",c=0,u=0,l=0,h=2,f=1,d=a.slice.call(arguments,1),p=Object.create(this.lexer),g={yy:{}};for(var y in this.yy)Object.prototype.hasOwnProperty.call(this.yy,y)&&(g.yy[y]=this.yy[y]);p.setInput(t,g.yy),g.yy.lexer=p,g.yy.parser=this,void 0===p.yylloc&&(p.yylloc={});var m=p.yylloc;a.push(m);var v=p.options&&p.options.ranges;function b(){var t;return"number"!=typeof(t=r.pop()||p.lex()||f)&&(t instanceof Array&&(t=(r=t).pop()),t=e.symbols_[t]||t),t}"function"==typeof g.yy.parseError?this.parseError=g.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;for(var _,x,w,k,T,C,E,S,A,M={};;){if(w=n[n.length-1],this.defaultActions[w]?k=this.defaultActions[w]:(null==_&&(_=b()),k=o[w]&&o[w][_]),void 0===k||!k.length||!k[0]){var N="";for(C in A=[],o[w])this.terminals_[C]&&C>h&&A.push("'"+this.terminals_[C]+"'");N=p.showPosition?"Parse error on line "+(c+1)+":\n"+p.showPosition()+"\nExpecting "+A.join(", ")+", got '"+(this.terminals_[_]||_)+"'":"Parse error on line "+(c+1)+": Unexpected "+(_==f?"end of input":"'"+(this.terminals_[_]||_)+"'"),this.parseError(N,{text:p.match,token:this.terminals_[_]||_,line:p.yylineno,loc:m,expected:A})}if(k[0]instanceof Array&&k.length>1)throw new Error("Parse Error: multiple actions possible at state: "+w+", token: "+_);switch(k[0]){case 1:n.push(_),i.push(p.yytext),a.push(p.yylloc),n.push(k[1]),_=null,x?(_=x,x=null):(u=p.yyleng,s=p.yytext,c=p.yylineno,m=p.yylloc,l>0&&l--);break;case 2:if(E=this.productions_[k[1]][1],M.$=i[i.length-E],M._$={first_line:a[a.length-(E||1)].first_line,last_line:a[a.length-1].last_line,first_column:a[a.length-(E||1)].first_column,last_column:a[a.length-1].last_column},v&&(M._$.range=[a[a.length-(E||1)].range[0],a[a.length-1].range[1]]),void 0!==(T=this.performAction.apply(M,[s,u,c,g.yy,k[1],i,a].concat(d))))return T;E&&(n=n.slice(0,-1*E*2),i=i.slice(0,-1*E),a=a.slice(0,-1*E)),n.push(this.productions_[k[1]][0]),i.push(M.$),a.push(M._$),S=o[n[n.length-2]][n[n.length-1]],n.push(S);break;case 3:return!0}}return!0}},r={EOF:1,parseError:function(t,e){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,e)},setInput:function(t,e){return this.yy=e||this.yy||{},this._input=t,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},input:function(){var t=this._input[0];return this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t,t.match(/(?:\r\n?|\n).*/g)?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),t},unput:function(t){var e=t.length,n=t.split(/(?:\r\n?|\n)/g);this._input=t+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-e),this.offset-=e;var r=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),n.length-1&&(this.yylineno-=n.length-1);var i=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:n?(n.length===r.length?this.yylloc.first_column:0)+r[r.length-n.length].length-n[0].length:this.yylloc.first_column-e},this.options.ranges&&(this.yylloc.range=[i[0],i[0]+this.yyleng-e]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject:function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):this.parseError("Lexical error on line "+(this.yylineno+1)+". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},less:function(t){this.unput(this.match.slice(t))},pastInput:function(){var t=this.matched.substr(0,this.matched.length-this.match.length);return(t.length>20?"...":"")+t.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var t=this.match;return t.length<20&&(t+=this._input.substr(0,20-t.length)),(t.substr(0,20)+(t.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var t=this.pastInput(),e=new Array(t.length+1).join("-");return t+this.upcomingInput()+"\n"+e+"^"},test_match:function(t,e){var n,r,i;if(this.options.backtrack_lexer&&(i={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(i.yylloc.range=this.yylloc.range.slice(0))),(r=t[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=r.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:r?r[r.length-1].length-r[r.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],n=this.performAction.call(this,this.yy,this,e,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),n)return n;if(this._backtrack){for(var a in i)this[a]=i[a];return!1}return!1},next:function(){if(this.done)return this.EOF;var t,e,n,r;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var i=this._currentRules(),a=0;ae[0].length)){if(e=n,r=a,this.options.backtrack_lexer){if(!1!==(t=this.test_match(n,i[a])))return t;if(this._backtrack){e=!1;continue}return!1}if(!this.options.flex)break}return e?!1!==(t=this.test_match(e,i[r]))&&t:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){return this.next()||this.lex()},begin:function(t){this.conditionStack.push(t)},popState:function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]},_currentRules:function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},topState:function(t){return(t=this.conditionStack.length-1-Math.abs(t||0))>=0?this.conditionStack[t]:"INITIAL"},pushState:function(t){this.begin(t)},stateStackSize:function(){return this.conditionStack.length},options:{"case-insensitive":!0},performAction:function(t,e,n,r){switch(n){case 0:return 4;case 1:return 9;case 2:return"space";case 3:return 10;case 4:return 6;case 5:return"TXT"}},rules:[/^(?:info\b)/i,/^(?:[\s\n\r]+)/i,/^(?:[\s]+)/i,/^(?:showInfo\b)/i,/^(?:$)/i,/^(?:.)/i],conditions:{INITIAL:{rules:[0,1,2,3,4,5],inclusive:!0}}};function i(){this.yy={}}return n.lexer=r,i.prototype=n,n.Parser=i,new i}();e.parser=r,e.Parser=r.Parser,e.parse=function(){return r.parse.apply(r,arguments)},e.main=function(t){t[1]||(console.log("Usage: "+t[0]+" FILE"),process.exit(1));var r=n(1428).readFileSync(n(6470).normalize(t[1]),"utf8");return e.parser.parse(r)},n.c[n.s]===t&&e.main(process.argv.slice(1))},7062:(t,e,n)=>{t=n.nmd(t);var r=function(){var t=function(t,e,n,r){for(n=n||{},r=t.length;r--;n[t[r]]=e);return n},e=[1,4],n=[1,5],r=[1,6],i=[1,7],a=[1,9],o=[1,11,13,15,17,19,20,26,27,28,29],s=[2,5],c=[1,6,11,13,15,17,19,20,26,27,28,29],u=[26,27,28],l=[2,8],h=[1,18],f=[1,19],d=[1,20],p=[1,21],g=[1,22],y=[1,23],m=[1,28],v=[6,26,27,28,29],b={trace:function(){},yy:{},symbols_:{error:2,start:3,eol:4,directive:5,PIE:6,document:7,showData:8,line:9,statement:10,txt:11,value:12,title:13,title_value:14,acc_title:15,acc_title_value:16,acc_descr:17,acc_descr_value:18,acc_descr_multiline_value:19,section:20,openDirective:21,typeDirective:22,closeDirective:23,":":24,argDirective:25,NEWLINE:26,";":27,EOF:28,open_directive:29,type_directive:30,arg_directive:31,close_directive:32,$accept:0,$end:1},terminals_:{2:"error",6:"PIE",8:"showData",11:"txt",12:"value",13:"title",14:"title_value",15:"acc_title",16:"acc_title_value",17:"acc_descr",18:"acc_descr_value",19:"acc_descr_multiline_value",20:"section",24:":",26:"NEWLINE",27:";",28:"EOF",29:"open_directive",30:"type_directive",31:"arg_directive",32:"close_directive"},productions_:[0,[3,2],[3,2],[3,2],[3,3],[7,0],[7,2],[9,2],[10,0],[10,2],[10,2],[10,2],[10,2],[10,1],[10,1],[10,1],[5,3],[5,5],[4,1],[4,1],[4,1],[21,1],[22,1],[25,1],[23,1]],performAction:function(t,e,n,r,i,a,o){var s=a.length-1;switch(i){case 4:r.setShowData(!0);break;case 7:this.$=a[s-1];break;case 9:r.addSection(a[s-1],r.cleanupValue(a[s]));break;case 10:this.$=a[s].trim(),r.setPieTitle(this.$);break;case 11:this.$=a[s].trim(),r.setTitle(this.$);break;case 12:case 13:this.$=a[s].trim(),r.setAccDescription(this.$);break;case 14:r.addSection(a[s].substr(8)),this.$=a[s].substr(8);break;case 21:r.parseDirective("%%{","open_directive");break;case 22:r.parseDirective(a[s],"type_directive");break;case 23:a[s]=a[s].trim().replace(/'/g,'"'),r.parseDirective(a[s],"arg_directive");break;case 24:r.parseDirective("}%%","close_directive","pie")}},table:[{3:1,4:2,5:3,6:e,21:8,26:n,27:r,28:i,29:a},{1:[3]},{3:10,4:2,5:3,6:e,21:8,26:n,27:r,28:i,29:a},{3:11,4:2,5:3,6:e,21:8,26:n,27:r,28:i,29:a},t(o,s,{7:12,8:[1,13]}),t(c,[2,18]),t(c,[2,19]),t(c,[2,20]),{22:14,30:[1,15]},{30:[2,21]},{1:[2,1]},{1:[2,2]},t(u,l,{21:8,9:16,10:17,5:24,1:[2,3],11:h,13:f,15:d,17:p,19:g,20:y,29:a}),t(o,s,{7:25}),{23:26,24:[1,27],32:m},t([24,32],[2,22]),t(o,[2,6]),{4:29,26:n,27:r,28:i},{12:[1,30]},{14:[1,31]},{16:[1,32]},{18:[1,33]},t(u,[2,13]),t(u,[2,14]),t(u,[2,15]),t(u,l,{21:8,9:16,10:17,5:24,1:[2,4],11:h,13:f,15:d,17:p,19:g,20:y,29:a}),t(v,[2,16]),{25:34,31:[1,35]},t(v,[2,24]),t(o,[2,7]),t(u,[2,9]),t(u,[2,10]),t(u,[2,11]),t(u,[2,12]),{23:36,32:m},{32:[2,23]},t(v,[2,17])],defaultActions:{9:[2,21],10:[2,1],11:[2,2],35:[2,23]},parseError:function(t,e){if(!e.recoverable){var n=new Error(t);throw n.hash=e,n}this.trace(t)},parse:function(t){var e=this,n=[0],r=[],i=[null],a=[],o=this.table,s="",c=0,u=0,l=0,h=2,f=1,d=a.slice.call(arguments,1),p=Object.create(this.lexer),g={yy:{}};for(var y in this.yy)Object.prototype.hasOwnProperty.call(this.yy,y)&&(g.yy[y]=this.yy[y]);p.setInput(t,g.yy),g.yy.lexer=p,g.yy.parser=this,void 0===p.yylloc&&(p.yylloc={});var m=p.yylloc;a.push(m);var v=p.options&&p.options.ranges;function b(){var t;return"number"!=typeof(t=r.pop()||p.lex()||f)&&(t instanceof Array&&(t=(r=t).pop()),t=e.symbols_[t]||t),t}"function"==typeof g.yy.parseError?this.parseError=g.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;for(var _,x,w,k,T,C,E,S,A,M={};;){if(w=n[n.length-1],this.defaultActions[w]?k=this.defaultActions[w]:(null==_&&(_=b()),k=o[w]&&o[w][_]),void 0===k||!k.length||!k[0]){var N="";for(C in A=[],o[w])this.terminals_[C]&&C>h&&A.push("'"+this.terminals_[C]+"'");N=p.showPosition?"Parse error on line "+(c+1)+":\n"+p.showPosition()+"\nExpecting "+A.join(", ")+", got '"+(this.terminals_[_]||_)+"'":"Parse error on line "+(c+1)+": Unexpected "+(_==f?"end of input":"'"+(this.terminals_[_]||_)+"'"),this.parseError(N,{text:p.match,token:this.terminals_[_]||_,line:p.yylineno,loc:m,expected:A})}if(k[0]instanceof Array&&k.length>1)throw new Error("Parse Error: multiple actions possible at state: "+w+", token: "+_);switch(k[0]){case 1:n.push(_),i.push(p.yytext),a.push(p.yylloc),n.push(k[1]),_=null,x?(_=x,x=null):(u=p.yyleng,s=p.yytext,c=p.yylineno,m=p.yylloc,l>0&&l--);break;case 2:if(E=this.productions_[k[1]][1],M.$=i[i.length-E],M._$={first_line:a[a.length-(E||1)].first_line,last_line:a[a.length-1].last_line,first_column:a[a.length-(E||1)].first_column,last_column:a[a.length-1].last_column},v&&(M._$.range=[a[a.length-(E||1)].range[0],a[a.length-1].range[1]]),void 0!==(T=this.performAction.apply(M,[s,u,c,g.yy,k[1],i,a].concat(d))))return T;E&&(n=n.slice(0,-1*E*2),i=i.slice(0,-1*E),a=a.slice(0,-1*E)),n.push(this.productions_[k[1]][0]),i.push(M.$),a.push(M._$),S=o[n[n.length-2]][n[n.length-1]],n.push(S);break;case 3:return!0}}return!0}},_={EOF:1,parseError:function(t,e){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,e)},setInput:function(t,e){return this.yy=e||this.yy||{},this._input=t,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},input:function(){var t=this._input[0];return this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t,t.match(/(?:\r\n?|\n).*/g)?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),t},unput:function(t){var e=t.length,n=t.split(/(?:\r\n?|\n)/g);this._input=t+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-e),this.offset-=e;var r=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),n.length-1&&(this.yylineno-=n.length-1);var i=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:n?(n.length===r.length?this.yylloc.first_column:0)+r[r.length-n.length].length-n[0].length:this.yylloc.first_column-e},this.options.ranges&&(this.yylloc.range=[i[0],i[0]+this.yyleng-e]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject:function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):this.parseError("Lexical error on line "+(this.yylineno+1)+". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},less:function(t){this.unput(this.match.slice(t))},pastInput:function(){var t=this.matched.substr(0,this.matched.length-this.match.length);return(t.length>20?"...":"")+t.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var t=this.match;return t.length<20&&(t+=this._input.substr(0,20-t.length)),(t.substr(0,20)+(t.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var t=this.pastInput(),e=new Array(t.length+1).join("-");return t+this.upcomingInput()+"\n"+e+"^"},test_match:function(t,e){var n,r,i;if(this.options.backtrack_lexer&&(i={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(i.yylloc.range=this.yylloc.range.slice(0))),(r=t[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=r.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:r?r[r.length-1].length-r[r.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],n=this.performAction.call(this,this.yy,this,e,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),n)return n;if(this._backtrack){for(var a in i)this[a]=i[a];return!1}return!1},next:function(){if(this.done)return this.EOF;var t,e,n,r;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var i=this._currentRules(),a=0;ae[0].length)){if(e=n,r=a,this.options.backtrack_lexer){if(!1!==(t=this.test_match(n,i[a])))return t;if(this._backtrack){e=!1;continue}return!1}if(!this.options.flex)break}return e?!1!==(t=this.test_match(e,i[r]))&&t:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){return this.next()||this.lex()},begin:function(t){this.conditionStack.push(t)},popState:function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]},_currentRules:function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},topState:function(t){return(t=this.conditionStack.length-1-Math.abs(t||0))>=0?this.conditionStack[t]:"INITIAL"},pushState:function(t){this.begin(t)},stateStackSize:function(){return this.conditionStack.length},options:{"case-insensitive":!0},performAction:function(t,e,n,r){switch(n){case 0:return this.begin("open_directive"),29;case 1:return this.begin("type_directive"),30;case 2:return this.popState(),this.begin("arg_directive"),24;case 3:return this.popState(),this.popState(),32;case 4:return 31;case 5:case 6:case 8:case 9:break;case 7:return 26;case 10:return this.begin("title"),13;case 11:return this.popState(),"title_value";case 12:return this.begin("acc_title"),15;case 13:return this.popState(),"acc_title_value";case 14:return this.begin("acc_descr"),17;case 15:return this.popState(),"acc_descr_value";case 16:this.begin("acc_descr_multiline");break;case 17:case 20:this.popState();break;case 18:return"acc_descr_multiline_value";case 19:this.begin("string");break;case 21:return"txt";case 22:return 6;case 23:return 8;case 24:return"value";case 25:return 28}},rules:[/^(?:%%\{)/i,/^(?:((?:(?!\}%%)[^:.])*))/i,/^(?::)/i,/^(?:\}%%)/i,/^(?:((?:(?!\}%%).|\n)*))/i,/^(?:%%(?!\{)[^\n]*)/i,/^(?:[^\}]%%[^\n]*)/i,/^(?:[\n\r]+)/i,/^(?:%%[^\n]*)/i,/^(?:[\s]+)/i,/^(?:title\b)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accTitle\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*\{\s*)/i,/^(?:[\}])/i,/^(?:[^\}]*)/i,/^(?:["])/i,/^(?:["])/i,/^(?:[^"]*)/i,/^(?:pie\b)/i,/^(?:showData\b)/i,/^(?::[\s]*[\d]+(?:\.[\d]+)?)/i,/^(?:$)/i],conditions:{acc_descr_multiline:{rules:[17,18],inclusive:!1},acc_descr:{rules:[15],inclusive:!1},acc_title:{rules:[13],inclusive:!1},close_directive:{rules:[],inclusive:!1},arg_directive:{rules:[3,4],inclusive:!1},type_directive:{rules:[2,3],inclusive:!1},open_directive:{rules:[1],inclusive:!1},title:{rules:[11],inclusive:!1},string:{rules:[20,21],inclusive:!1},INITIAL:{rules:[0,5,6,7,8,9,10,12,14,16,19,22,23,24,25],inclusive:!0}}};function x(){this.yy={}}return b.lexer=_,x.prototype=b,b.Parser=x,new x}();e.parser=r,e.Parser=r.Parser,e.parse=function(){return r.parse.apply(r,arguments)},e.main=function(t){t[1]||(console.log("Usage: "+t[0]+" FILE"),process.exit(1));var r=n(4551).readFileSync(n(6470).normalize(t[1]),"utf8");return e.parser.parse(r)},n.c[n.s]===t&&e.main(process.argv.slice(1))},3176:(t,e,n)=>{t=n.nmd(t);var r=function(){var t=function(t,e,n,r){for(n=n||{},r=t.length;r--;n[t[r]]=e);return n},e=[1,3],n=[1,5],r=[1,6],i=[1,7],a=[1,8],o=[5,6,8,14,16,18,19,40,41,42,43,44,45,53,71,72],s=[1,22],c=[2,13],u=[1,26],l=[1,27],h=[1,28],f=[1,29],d=[1,30],p=[1,31],g=[1,24],y=[1,32],m=[1,33],v=[1,36],b=[71,72],_=[5,8,14,16,18,19,40,41,42,43,44,45,53,60,62,71,72],x=[1,56],w=[1,57],k=[1,58],T=[1,59],C=[1,60],E=[1,61],S=[1,62],A=[62,63],M=[1,74],N=[1,70],D=[1,71],B=[1,72],L=[1,73],O=[1,75],I=[1,79],R=[1,80],F=[1,77],P=[1,78],Y=[5,8,14,16,18,19,40,41,42,43,44,45,53,71,72],j={trace:function(){},yy:{},symbols_:{error:2,start:3,directive:4,NEWLINE:5,RD:6,diagram:7,EOF:8,openDirective:9,typeDirective:10,closeDirective:11,":":12,argDirective:13,acc_title:14,acc_title_value:15,acc_descr:16,acc_descr_value:17,acc_descr_multiline_value:18,open_directive:19,type_directive:20,arg_directive:21,close_directive:22,requirementDef:23,elementDef:24,relationshipDef:25,requirementType:26,requirementName:27,STRUCT_START:28,requirementBody:29,ID:30,COLONSEP:31,id:32,TEXT:33,text:34,RISK:35,riskLevel:36,VERIFYMTHD:37,verifyType:38,STRUCT_STOP:39,REQUIREMENT:40,FUNCTIONAL_REQUIREMENT:41,INTERFACE_REQUIREMENT:42,PERFORMANCE_REQUIREMENT:43,PHYSICAL_REQUIREMENT:44,DESIGN_CONSTRAINT:45,LOW_RISK:46,MED_RISK:47,HIGH_RISK:48,VERIFY_ANALYSIS:49,VERIFY_DEMONSTRATION:50,VERIFY_INSPECTION:51,VERIFY_TEST:52,ELEMENT:53,elementName:54,elementBody:55,TYPE:56,type:57,DOCREF:58,ref:59,END_ARROW_L:60,relationship:61,LINE:62,END_ARROW_R:63,CONTAINS:64,COPIES:65,DERIVES:66,SATISFIES:67,VERIFIES:68,REFINES:69,TRACES:70,unqString:71,qString:72,$accept:0,$end:1},terminals_:{2:"error",5:"NEWLINE",6:"RD",8:"EOF",12:":",14:"acc_title",15:"acc_title_value",16:"acc_descr",17:"acc_descr_value",18:"acc_descr_multiline_value",19:"open_directive",20:"type_directive",21:"arg_directive",22:"close_directive",28:"STRUCT_START",30:"ID",31:"COLONSEP",33:"TEXT",35:"RISK",37:"VERIFYMTHD",39:"STRUCT_STOP",40:"REQUIREMENT",41:"FUNCTIONAL_REQUIREMENT",42:"INTERFACE_REQUIREMENT",43:"PERFORMANCE_REQUIREMENT",44:"PHYSICAL_REQUIREMENT",45:"DESIGN_CONSTRAINT",46:"LOW_RISK",47:"MED_RISK",48:"HIGH_RISK",49:"VERIFY_ANALYSIS",50:"VERIFY_DEMONSTRATION",51:"VERIFY_INSPECTION",52:"VERIFY_TEST",53:"ELEMENT",56:"TYPE",58:"DOCREF",60:"END_ARROW_L",62:"LINE",63:"END_ARROW_R",64:"CONTAINS",65:"COPIES",66:"DERIVES",67:"SATISFIES",68:"VERIFIES",69:"REFINES",70:"TRACES",71:"unqString",72:"qString"},productions_:[0,[3,3],[3,2],[3,4],[4,3],[4,5],[4,2],[4,2],[4,1],[9,1],[10,1],[13,1],[11,1],[7,0],[7,2],[7,2],[7,2],[7,2],[7,2],[23,5],[29,5],[29,5],[29,5],[29,5],[29,2],[29,1],[26,1],[26,1],[26,1],[26,1],[26,1],[26,1],[36,1],[36,1],[36,1],[38,1],[38,1],[38,1],[38,1],[24,5],[55,5],[55,5],[55,2],[55,1],[25,5],[25,5],[61,1],[61,1],[61,1],[61,1],[61,1],[61,1],[61,1],[27,1],[27,1],[32,1],[32,1],[34,1],[34,1],[54,1],[54,1],[57,1],[57,1],[59,1],[59,1]],performAction:function(t,e,n,r,i,a,o){var s=a.length-1;switch(i){case 6:this.$=a[s].trim(),r.setTitle(this.$);break;case 7:case 8:this.$=a[s].trim(),r.setAccDescription(this.$);break;case 9:r.parseDirective("%%{","open_directive");break;case 10:r.parseDirective(a[s],"type_directive");break;case 11:a[s]=a[s].trim().replace(/'/g,'"'),r.parseDirective(a[s],"arg_directive");break;case 12:r.parseDirective("}%%","close_directive","pie");break;case 13:this.$=[];break;case 19:r.addRequirement(a[s-3],a[s-4]);break;case 20:r.setNewReqId(a[s-2]);break;case 21:r.setNewReqText(a[s-2]);break;case 22:r.setNewReqRisk(a[s-2]);break;case 23:r.setNewReqVerifyMethod(a[s-2]);break;case 26:this.$=r.RequirementType.REQUIREMENT;break;case 27:this.$=r.RequirementType.FUNCTIONAL_REQUIREMENT;break;case 28:this.$=r.RequirementType.INTERFACE_REQUIREMENT;break;case 29:this.$=r.RequirementType.PERFORMANCE_REQUIREMENT;break;case 30:this.$=r.RequirementType.PHYSICAL_REQUIREMENT;break;case 31:this.$=r.RequirementType.DESIGN_CONSTRAINT;break;case 32:this.$=r.RiskLevel.LOW_RISK;break;case 33:this.$=r.RiskLevel.MED_RISK;break;case 34:this.$=r.RiskLevel.HIGH_RISK;break;case 35:this.$=r.VerifyType.VERIFY_ANALYSIS;break;case 36:this.$=r.VerifyType.VERIFY_DEMONSTRATION;break;case 37:this.$=r.VerifyType.VERIFY_INSPECTION;break;case 38:this.$=r.VerifyType.VERIFY_TEST;break;case 39:r.addElement(a[s-3]);break;case 40:r.setNewElementType(a[s-2]);break;case 41:r.setNewElementDocRef(a[s-2]);break;case 44:r.addRelationship(a[s-2],a[s],a[s-4]);break;case 45:r.addRelationship(a[s-2],a[s-4],a[s]);break;case 46:this.$=r.Relationships.CONTAINS;break;case 47:this.$=r.Relationships.COPIES;break;case 48:this.$=r.Relationships.DERIVES;break;case 49:this.$=r.Relationships.SATISFIES;break;case 50:this.$=r.Relationships.VERIFIES;break;case 51:this.$=r.Relationships.REFINES;break;case 52:this.$=r.Relationships.TRACES}},table:[{3:1,4:2,6:e,9:4,14:n,16:r,18:i,19:a},{1:[3]},{3:10,4:2,5:[1,9],6:e,9:4,14:n,16:r,18:i,19:a},{5:[1,11]},{10:12,20:[1,13]},{15:[1,14]},{17:[1,15]},t(o,[2,8]),{20:[2,9]},{3:16,4:2,6:e,9:4,14:n,16:r,18:i,19:a},{1:[2,2]},{4:21,5:s,7:17,8:c,9:4,14:n,16:r,18:i,19:a,23:18,24:19,25:20,26:23,32:25,40:u,41:l,42:h,43:f,44:d,45:p,53:g,71:y,72:m},{11:34,12:[1,35],22:v},t([12,22],[2,10]),t(o,[2,6]),t(o,[2,7]),{1:[2,1]},{8:[1,37]},{4:21,5:s,7:38,8:c,9:4,14:n,16:r,18:i,19:a,23:18,24:19,25:20,26:23,32:25,40:u,41:l,42:h,43:f,44:d,45:p,53:g,71:y,72:m},{4:21,5:s,7:39,8:c,9:4,14:n,16:r,18:i,19:a,23:18,24:19,25:20,26:23,32:25,40:u,41:l,42:h,43:f,44:d,45:p,53:g,71:y,72:m},{4:21,5:s,7:40,8:c,9:4,14:n,16:r,18:i,19:a,23:18,24:19,25:20,26:23,32:25,40:u,41:l,42:h,43:f,44:d,45:p,53:g,71:y,72:m},{4:21,5:s,7:41,8:c,9:4,14:n,16:r,18:i,19:a,23:18,24:19,25:20,26:23,32:25,40:u,41:l,42:h,43:f,44:d,45:p,53:g,71:y,72:m},{4:21,5:s,7:42,8:c,9:4,14:n,16:r,18:i,19:a,23:18,24:19,25:20,26:23,32:25,40:u,41:l,42:h,43:f,44:d,45:p,53:g,71:y,72:m},{27:43,71:[1,44],72:[1,45]},{54:46,71:[1,47],72:[1,48]},{60:[1,49],62:[1,50]},t(b,[2,26]),t(b,[2,27]),t(b,[2,28]),t(b,[2,29]),t(b,[2,30]),t(b,[2,31]),t(_,[2,55]),t(_,[2,56]),t(o,[2,4]),{13:51,21:[1,52]},t(o,[2,12]),{1:[2,3]},{8:[2,14]},{8:[2,15]},{8:[2,16]},{8:[2,17]},{8:[2,18]},{28:[1,53]},{28:[2,53]},{28:[2,54]},{28:[1,54]},{28:[2,59]},{28:[2,60]},{61:55,64:x,65:w,66:k,67:T,68:C,69:E,70:S},{61:63,64:x,65:w,66:k,67:T,68:C,69:E,70:S},{11:64,22:v},{22:[2,11]},{5:[1,65]},{5:[1,66]},{62:[1,67]},t(A,[2,46]),t(A,[2,47]),t(A,[2,48]),t(A,[2,49]),t(A,[2,50]),t(A,[2,51]),t(A,[2,52]),{63:[1,68]},t(o,[2,5]),{5:M,29:69,30:N,33:D,35:B,37:L,39:O},{5:I,39:R,55:76,56:F,58:P},{32:81,71:y,72:m},{32:82,71:y,72:m},t(Y,[2,19]),{31:[1,83]},{31:[1,84]},{31:[1,85]},{31:[1,86]},{5:M,29:87,30:N,33:D,35:B,37:L,39:O},t(Y,[2,25]),t(Y,[2,39]),{31:[1,88]},{31:[1,89]},{5:I,39:R,55:90,56:F,58:P},t(Y,[2,43]),t(Y,[2,44]),t(Y,[2,45]),{32:91,71:y,72:m},{34:92,71:[1,93],72:[1,94]},{36:95,46:[1,96],47:[1,97],48:[1,98]},{38:99,49:[1,100],50:[1,101],51:[1,102],52:[1,103]},t(Y,[2,24]),{57:104,71:[1,105],72:[1,106]},{59:107,71:[1,108],72:[1,109]},t(Y,[2,42]),{5:[1,110]},{5:[1,111]},{5:[2,57]},{5:[2,58]},{5:[1,112]},{5:[2,32]},{5:[2,33]},{5:[2,34]},{5:[1,113]},{5:[2,35]},{5:[2,36]},{5:[2,37]},{5:[2,38]},{5:[1,114]},{5:[2,61]},{5:[2,62]},{5:[1,115]},{5:[2,63]},{5:[2,64]},{5:M,29:116,30:N,33:D,35:B,37:L,39:O},{5:M,29:117,30:N,33:D,35:B,37:L,39:O},{5:M,29:118,30:N,33:D,35:B,37:L,39:O},{5:M,29:119,30:N,33:D,35:B,37:L,39:O},{5:I,39:R,55:120,56:F,58:P},{5:I,39:R,55:121,56:F,58:P},t(Y,[2,20]),t(Y,[2,21]),t(Y,[2,22]),t(Y,[2,23]),t(Y,[2,40]),t(Y,[2,41])],defaultActions:{8:[2,9],10:[2,2],16:[2,1],37:[2,3],38:[2,14],39:[2,15],40:[2,16],41:[2,17],42:[2,18],44:[2,53],45:[2,54],47:[2,59],48:[2,60],52:[2,11],93:[2,57],94:[2,58],96:[2,32],97:[2,33],98:[2,34],100:[2,35],101:[2,36],102:[2,37],103:[2,38],105:[2,61],106:[2,62],108:[2,63],109:[2,64]},parseError:function(t,e){if(!e.recoverable){var n=new Error(t);throw n.hash=e,n}this.trace(t)},parse:function(t){var e=this,n=[0],r=[],i=[null],a=[],o=this.table,s="",c=0,u=0,l=0,h=2,f=1,d=a.slice.call(arguments,1),p=Object.create(this.lexer),g={yy:{}};for(var y in this.yy)Object.prototype.hasOwnProperty.call(this.yy,y)&&(g.yy[y]=this.yy[y]);p.setInput(t,g.yy),g.yy.lexer=p,g.yy.parser=this,void 0===p.yylloc&&(p.yylloc={});var m=p.yylloc;a.push(m);var v=p.options&&p.options.ranges;function b(){var t;return"number"!=typeof(t=r.pop()||p.lex()||f)&&(t instanceof Array&&(t=(r=t).pop()),t=e.symbols_[t]||t),t}"function"==typeof g.yy.parseError?this.parseError=g.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;for(var _,x,w,k,T,C,E,S,A,M={};;){if(w=n[n.length-1],this.defaultActions[w]?k=this.defaultActions[w]:(null==_&&(_=b()),k=o[w]&&o[w][_]),void 0===k||!k.length||!k[0]){var N="";for(C in A=[],o[w])this.terminals_[C]&&C>h&&A.push("'"+this.terminals_[C]+"'");N=p.showPosition?"Parse error on line "+(c+1)+":\n"+p.showPosition()+"\nExpecting "+A.join(", ")+", got '"+(this.terminals_[_]||_)+"'":"Parse error on line "+(c+1)+": Unexpected "+(_==f?"end of input":"'"+(this.terminals_[_]||_)+"'"),this.parseError(N,{text:p.match,token:this.terminals_[_]||_,line:p.yylineno,loc:m,expected:A})}if(k[0]instanceof Array&&k.length>1)throw new Error("Parse Error: multiple actions possible at state: "+w+", token: "+_);switch(k[0]){case 1:n.push(_),i.push(p.yytext),a.push(p.yylloc),n.push(k[1]),_=null,x?(_=x,x=null):(u=p.yyleng,s=p.yytext,c=p.yylineno,m=p.yylloc,l>0&&l--);break;case 2:if(E=this.productions_[k[1]][1],M.$=i[i.length-E],M._$={first_line:a[a.length-(E||1)].first_line,last_line:a[a.length-1].last_line,first_column:a[a.length-(E||1)].first_column,last_column:a[a.length-1].last_column},v&&(M._$.range=[a[a.length-(E||1)].range[0],a[a.length-1].range[1]]),void 0!==(T=this.performAction.apply(M,[s,u,c,g.yy,k[1],i,a].concat(d))))return T;E&&(n=n.slice(0,-1*E*2),i=i.slice(0,-1*E),a=a.slice(0,-1*E)),n.push(this.productions_[k[1]][0]),i.push(M.$),a.push(M._$),S=o[n[n.length-2]][n[n.length-1]],n.push(S);break;case 3:return!0}}return!0}},U={EOF:1,parseError:function(t,e){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,e)},setInput:function(t,e){return this.yy=e||this.yy||{},this._input=t,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},input:function(){var t=this._input[0];return this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t,t.match(/(?:\r\n?|\n).*/g)?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),t},unput:function(t){var e=t.length,n=t.split(/(?:\r\n?|\n)/g);this._input=t+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-e),this.offset-=e;var r=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),n.length-1&&(this.yylineno-=n.length-1);var i=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:n?(n.length===r.length?this.yylloc.first_column:0)+r[r.length-n.length].length-n[0].length:this.yylloc.first_column-e},this.options.ranges&&(this.yylloc.range=[i[0],i[0]+this.yyleng-e]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject:function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):this.parseError("Lexical error on line "+(this.yylineno+1)+". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},less:function(t){this.unput(this.match.slice(t))},pastInput:function(){var t=this.matched.substr(0,this.matched.length-this.match.length);return(t.length>20?"...":"")+t.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var t=this.match;return t.length<20&&(t+=this._input.substr(0,20-t.length)),(t.substr(0,20)+(t.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var t=this.pastInput(),e=new Array(t.length+1).join("-");return t+this.upcomingInput()+"\n"+e+"^"},test_match:function(t,e){var n,r,i;if(this.options.backtrack_lexer&&(i={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(i.yylloc.range=this.yylloc.range.slice(0))),(r=t[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=r.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:r?r[r.length-1].length-r[r.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],n=this.performAction.call(this,this.yy,this,e,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),n)return n;if(this._backtrack){for(var a in i)this[a]=i[a];return!1}return!1},next:function(){if(this.done)return this.EOF;var t,e,n,r;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var i=this._currentRules(),a=0;ae[0].length)){if(e=n,r=a,this.options.backtrack_lexer){if(!1!==(t=this.test_match(n,i[a])))return t;if(this._backtrack){e=!1;continue}return!1}if(!this.options.flex)break}return e?!1!==(t=this.test_match(e,i[r]))&&t:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){return this.next()||this.lex()},begin:function(t){this.conditionStack.push(t)},popState:function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]},_currentRules:function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},topState:function(t){return(t=this.conditionStack.length-1-Math.abs(t||0))>=0?this.conditionStack[t]:"INITIAL"},pushState:function(t){this.begin(t)},stateStackSize:function(){return this.conditionStack.length},options:{"case-insensitive":!0},performAction:function(t,e,n,r){switch(n){case 0:return this.begin("open_directive"),19;case 1:return this.begin("type_directive"),20;case 2:return this.popState(),this.begin("arg_directive"),12;case 3:return this.popState(),this.popState(),22;case 4:return 21;case 5:return"title";case 6:return this.begin("acc_title"),14;case 7:return this.popState(),"acc_title_value";case 8:return this.begin("acc_descr"),16;case 9:return this.popState(),"acc_descr_value";case 10:this.begin("acc_descr_multiline");break;case 11:case 53:this.popState();break;case 12:return"acc_descr_multiline_value";case 13:return 5;case 14:case 15:case 16:break;case 17:return 8;case 18:return 6;case 19:return 28;case 20:return 39;case 21:return 31;case 22:return 30;case 23:return 33;case 24:return 35;case 25:return 37;case 26:return 40;case 27:return 41;case 28:return 42;case 29:return 43;case 30:return 44;case 31:return 45;case 32:return 46;case 33:return 47;case 34:return 48;case 35:return 49;case 36:return 50;case 37:return 51;case 38:return 52;case 39:return 53;case 40:return 64;case 41:return 65;case 42:return 66;case 43:return 67;case 44:return 68;case 45:return 69;case 46:return 70;case 47:return 56;case 48:return 58;case 49:return 60;case 50:return 63;case 51:return 62;case 52:this.begin("string");break;case 54:return"qString";case 55:return e.yytext=e.yytext.trim(),71}},rules:[/^(?:%%\{)/i,/^(?:((?:(?!\}%%)[^:.])*))/i,/^(?::)/i,/^(?:\}%%)/i,/^(?:((?:(?!\}%%).|\n)*))/i,/^(?:title\s[^#\n;]+)/i,/^(?:accTitle\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*\{\s*)/i,/^(?:[\}])/i,/^(?:[^\}]*)/i,/^(?:(\r?\n)+)/i,/^(?:\s+)/i,/^(?:#[^\n]*)/i,/^(?:%[^\n]*)/i,/^(?:$)/i,/^(?:requirementDiagram\b)/i,/^(?:\{)/i,/^(?:\})/i,/^(?::)/i,/^(?:id\b)/i,/^(?:text\b)/i,/^(?:risk\b)/i,/^(?:verifyMethod\b)/i,/^(?:requirement\b)/i,/^(?:functionalRequirement\b)/i,/^(?:interfaceRequirement\b)/i,/^(?:performanceRequirement\b)/i,/^(?:physicalRequirement\b)/i,/^(?:designConstraint\b)/i,/^(?:low\b)/i,/^(?:medium\b)/i,/^(?:high\b)/i,/^(?:analysis\b)/i,/^(?:demonstration\b)/i,/^(?:inspection\b)/i,/^(?:test\b)/i,/^(?:element\b)/i,/^(?:contains\b)/i,/^(?:copies\b)/i,/^(?:derives\b)/i,/^(?:satisfies\b)/i,/^(?:verifies\b)/i,/^(?:refines\b)/i,/^(?:traces\b)/i,/^(?:type\b)/i,/^(?:docref\b)/i,/^(?:<-)/i,/^(?:->)/i,/^(?:-)/i,/^(?:["])/i,/^(?:["])/i,/^(?:[^"]*)/i,/^(?:[\w][^\r\n\{\<\>\-\=]*)/i],conditions:{acc_descr_multiline:{rules:[11,12],inclusive:!1},acc_descr:{rules:[9],inclusive:!1},acc_title:{rules:[7],inclusive:!1},close_directive:{rules:[],inclusive:!1},arg_directive:{rules:[3,4],inclusive:!1},type_directive:{rules:[2,3],inclusive:!1},open_directive:{rules:[1],inclusive:!1},unqString:{rules:[],inclusive:!1},token:{rules:[],inclusive:!1},string:{rules:[53,54],inclusive:!1},INITIAL:{rules:[0,5,6,8,10,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,55],inclusive:!0}}};function z(){this.yy={}}return j.lexer=U,z.prototype=j,j.Parser=z,new z}();e.parser=r,e.Parser=r.Parser,e.parse=function(){return r.parse.apply(r,arguments)},e.main=function(t){t[1]||(console.log("Usage: "+t[0]+" FILE"),process.exit(1));var r=n(8800).readFileSync(n(6470).normalize(t[1]),"utf8");return e.parser.parse(r)},n.c[n.s]===t&&e.main(process.argv.slice(1))},6876:(t,e,n)=>{t=n.nmd(t);var r=function(){var t=function(t,e,n,r){for(n=n||{},r=t.length;r--;n[t[r]]=e);return n},e=[1,2],n=[1,3],r=[1,5],i=[1,7],a=[2,5],o=[1,15],s=[1,17],c=[1,18],u=[1,19],l=[1,21],h=[1,22],f=[1,23],d=[1,29],p=[1,30],g=[1,31],y=[1,32],m=[1,33],v=[1,34],b=[1,35],_=[1,36],x=[1,37],w=[1,38],k=[1,41],T=[1,42],C=[1,43],E=[1,44],S=[1,45],A=[1,46],M=[1,49],N=[1,4,5,16,20,22,25,26,32,33,34,36,38,39,40,41,42,43,45,47,48,49,54,55,56,57,65,75],D=[4,5,16,20,22,25,26,32,33,34,36,38,39,40,41,42,43,45,49,54,55,56,57,65,75],B=[4,5,16,20,22,25,26,32,33,34,36,38,39,40,41,42,43,45,48,49,54,55,56,57,65,75],L=[4,5,16,20,22,25,26,32,33,34,36,38,39,40,41,42,43,45,47,49,54,55,56,57,65,75],O=[63,64,65],I=[1,114],R=[1,4,5,7,16,20,22,25,26,32,33,34,36,38,39,40,41,42,43,45,47,48,49,54,55,56,57,65,75],F={trace:function(){},yy:{},symbols_:{error:2,start:3,SPACE:4,NEWLINE:5,directive:6,SD:7,document:8,line:9,statement:10,openDirective:11,typeDirective:12,closeDirective:13,":":14,argDirective:15,participant:16,actor:17,AS:18,restOfLine:19,participant_actor:20,signal:21,autonumber:22,NUM:23,off:24,activate:25,deactivate:26,note_statement:27,links_statement:28,link_statement:29,properties_statement:30,details_statement:31,title:32,legacy_title:33,acc_title:34,acc_title_value:35,acc_descr:36,acc_descr_value:37,acc_descr_multiline_value:38,loop:39,end:40,rect:41,opt:42,alt:43,else_sections:44,par:45,par_sections:46,and:47,else:48,note:49,placement:50,text2:51,over:52,actor_pair:53,links:54,link:55,properties:56,details:57,spaceList:58,",":59,left_of:60,right_of:61,signaltype:62,"+":63,"-":64,ACTOR:65,SOLID_OPEN_ARROW:66,DOTTED_OPEN_ARROW:67,SOLID_ARROW:68,DOTTED_ARROW:69,SOLID_CROSS:70,DOTTED_CROSS:71,SOLID_POINT:72,DOTTED_POINT:73,TXT:74,open_directive:75,type_directive:76,arg_directive:77,close_directive:78,$accept:0,$end:1},terminals_:{2:"error",4:"SPACE",5:"NEWLINE",7:"SD",14:":",16:"participant",18:"AS",19:"restOfLine",20:"participant_actor",22:"autonumber",23:"NUM",24:"off",25:"activate",26:"deactivate",32:"title",33:"legacy_title",34:"acc_title",35:"acc_title_value",36:"acc_descr",37:"acc_descr_value",38:"acc_descr_multiline_value",39:"loop",40:"end",41:"rect",42:"opt",43:"alt",45:"par",47:"and",48:"else",49:"note",52:"over",54:"links",55:"link",56:"properties",57:"details",59:",",60:"left_of",61:"right_of",63:"+",64:"-",65:"ACTOR",66:"SOLID_OPEN_ARROW",67:"DOTTED_OPEN_ARROW",68:"SOLID_ARROW",69:"DOTTED_ARROW",70:"SOLID_CROSS",71:"DOTTED_CROSS",72:"SOLID_POINT",73:"DOTTED_POINT",74:"TXT",75:"open_directive",76:"type_directive",77:"arg_directive",78:"close_directive"},productions_:[0,[3,2],[3,2],[3,2],[3,2],[8,0],[8,2],[9,2],[9,1],[9,1],[6,4],[6,6],[10,5],[10,3],[10,5],[10,3],[10,2],[10,4],[10,3],[10,3],[10,2],[10,3],[10,3],[10,2],[10,2],[10,2],[10,2],[10,2],[10,1],[10,1],[10,2],[10,2],[10,1],[10,4],[10,4],[10,4],[10,4],[10,4],[10,1],[46,1],[46,4],[44,1],[44,4],[27,4],[27,4],[28,3],[29,3],[30,3],[31,3],[58,2],[58,1],[53,3],[53,1],[50,1],[50,1],[21,5],[21,5],[21,4],[17,1],[62,1],[62,1],[62,1],[62,1],[62,1],[62,1],[62,1],[62,1],[51,1],[11,1],[12,1],[15,1],[13,1]],performAction:function(t,e,n,r,i,a,o){var s=a.length-1;switch(i){case 4:return r.apply(a[s]),a[s];case 5:case 9:this.$=[];break;case 6:a[s-1].push(a[s]),this.$=a[s-1];break;case 7:case 8:case 52:this.$=a[s];break;case 12:a[s-3].type="addParticipant",a[s-3].description=r.parseMessage(a[s-1]),this.$=a[s-3];break;case 13:a[s-1].type="addParticipant",this.$=a[s-1];break;case 14:a[s-3].type="addActor",a[s-3].description=r.parseMessage(a[s-1]),this.$=a[s-3];break;case 15:a[s-1].type="addActor",this.$=a[s-1];break;case 17:this.$={type:"sequenceIndex",sequenceIndex:Number(a[s-2]),sequenceIndexStep:Number(a[s-1]),sequenceVisible:!0,signalType:r.LINETYPE.AUTONUMBER};break;case 18:this.$={type:"sequenceIndex",sequenceIndex:Number(a[s-1]),sequenceIndexStep:1,sequenceVisible:!0,signalType:r.LINETYPE.AUTONUMBER};break;case 19:this.$={type:"sequenceIndex",sequenceVisible:!1,signalType:r.LINETYPE.AUTONUMBER};break;case 20:this.$={type:"sequenceIndex",sequenceVisible:!0,signalType:r.LINETYPE.AUTONUMBER};break;case 21:this.$={type:"activeStart",signalType:r.LINETYPE.ACTIVE_START,actor:a[s-1]};break;case 22:this.$={type:"activeEnd",signalType:r.LINETYPE.ACTIVE_END,actor:a[s-1]};break;case 28:r.setDiagramTitle(a[s].substring(6)),this.$=a[s].substring(6);break;case 29:r.setDiagramTitle(a[s].substring(7)),this.$=a[s].substring(7);break;case 30:this.$=a[s].trim(),r.setTitle(this.$);break;case 31:case 32:this.$=a[s].trim(),r.setAccDescription(this.$);break;case 33:a[s-1].unshift({type:"loopStart",loopText:r.parseMessage(a[s-2]),signalType:r.LINETYPE.LOOP_START}),a[s-1].push({type:"loopEnd",loopText:a[s-2],signalType:r.LINETYPE.LOOP_END}),this.$=a[s-1];break;case 34:a[s-1].unshift({type:"rectStart",color:r.parseMessage(a[s-2]),signalType:r.LINETYPE.RECT_START}),a[s-1].push({type:"rectEnd",color:r.parseMessage(a[s-2]),signalType:r.LINETYPE.RECT_END}),this.$=a[s-1];break;case 35:a[s-1].unshift({type:"optStart",optText:r.parseMessage(a[s-2]),signalType:r.LINETYPE.OPT_START}),a[s-1].push({type:"optEnd",optText:r.parseMessage(a[s-2]),signalType:r.LINETYPE.OPT_END}),this.$=a[s-1];break;case 36:a[s-1].unshift({type:"altStart",altText:r.parseMessage(a[s-2]),signalType:r.LINETYPE.ALT_START}),a[s-1].push({type:"altEnd",signalType:r.LINETYPE.ALT_END}),this.$=a[s-1];break;case 37:a[s-1].unshift({type:"parStart",parText:r.parseMessage(a[s-2]),signalType:r.LINETYPE.PAR_START}),a[s-1].push({type:"parEnd",signalType:r.LINETYPE.PAR_END}),this.$=a[s-1];break;case 40:this.$=a[s-3].concat([{type:"and",parText:r.parseMessage(a[s-1]),signalType:r.LINETYPE.PAR_AND},a[s]]);break;case 42:this.$=a[s-3].concat([{type:"else",altText:r.parseMessage(a[s-1]),signalType:r.LINETYPE.ALT_ELSE},a[s]]);break;case 43:this.$=[a[s-1],{type:"addNote",placement:a[s-2],actor:a[s-1].actor,text:a[s]}];break;case 44:a[s-2]=[].concat(a[s-1],a[s-1]).slice(0,2),a[s-2][0]=a[s-2][0].actor,a[s-2][1]=a[s-2][1].actor,this.$=[a[s-1],{type:"addNote",placement:r.PLACEMENT.OVER,actor:a[s-2].slice(0,2),text:a[s]}];break;case 45:this.$=[a[s-1],{type:"addLinks",actor:a[s-1].actor,text:a[s]}];break;case 46:this.$=[a[s-1],{type:"addALink",actor:a[s-1].actor,text:a[s]}];break;case 47:this.$=[a[s-1],{type:"addProperties",actor:a[s-1].actor,text:a[s]}];break;case 48:this.$=[a[s-1],{type:"addDetails",actor:a[s-1].actor,text:a[s]}];break;case 51:this.$=[a[s-2],a[s]];break;case 53:this.$=r.PLACEMENT.LEFTOF;break;case 54:this.$=r.PLACEMENT.RIGHTOF;break;case 55:this.$=[a[s-4],a[s-1],{type:"addMessage",from:a[s-4].actor,to:a[s-1].actor,signalType:a[s-3],msg:a[s]},{type:"activeStart",signalType:r.LINETYPE.ACTIVE_START,actor:a[s-1]}];break;case 56:this.$=[a[s-4],a[s-1],{type:"addMessage",from:a[s-4].actor,to:a[s-1].actor,signalType:a[s-3],msg:a[s]},{type:"activeEnd",signalType:r.LINETYPE.ACTIVE_END,actor:a[s-4]}];break;case 57:this.$=[a[s-3],a[s-1],{type:"addMessage",from:a[s-3].actor,to:a[s-1].actor,signalType:a[s-2],msg:a[s]}];break;case 58:this.$={type:"addParticipant",actor:a[s]};break;case 59:this.$=r.LINETYPE.SOLID_OPEN;break;case 60:this.$=r.LINETYPE.DOTTED_OPEN;break;case 61:this.$=r.LINETYPE.SOLID;break;case 62:this.$=r.LINETYPE.DOTTED;break;case 63:this.$=r.LINETYPE.SOLID_CROSS;break;case 64:this.$=r.LINETYPE.DOTTED_CROSS;break;case 65:this.$=r.LINETYPE.SOLID_POINT;break;case 66:this.$=r.LINETYPE.DOTTED_POINT;break;case 67:this.$=r.parseMessage(a[s].trim().substring(1));break;case 68:r.parseDirective("%%{","open_directive");break;case 69:r.parseDirective(a[s],"type_directive");break;case 70:a[s]=a[s].trim().replace(/'/g,'"'),r.parseDirective(a[s],"arg_directive");break;case 71:r.parseDirective("}%%","close_directive","sequence")}},table:[{3:1,4:e,5:n,6:4,7:r,11:6,75:i},{1:[3]},{3:8,4:e,5:n,6:4,7:r,11:6,75:i},{3:9,4:e,5:n,6:4,7:r,11:6,75:i},{3:10,4:e,5:n,6:4,7:r,11:6,75:i},t([1,4,5,16,20,22,25,26,32,33,34,36,38,39,41,42,43,45,49,54,55,56,57,65,75],a,{8:11}),{12:12,76:[1,13]},{76:[2,68]},{1:[2,1]},{1:[2,2]},{1:[2,3]},{1:[2,4],4:o,5:s,6:39,9:14,10:16,11:6,16:c,17:40,20:u,21:20,22:l,25:h,26:f,27:24,28:25,29:26,30:27,31:28,32:d,33:p,34:g,36:y,38:m,39:v,41:b,42:_,43:x,45:w,49:k,54:T,55:C,56:E,57:S,65:A,75:i},{13:47,14:[1,48],78:M},t([14,78],[2,69]),t(N,[2,6]),{6:39,10:50,11:6,16:c,17:40,20:u,21:20,22:l,25:h,26:f,27:24,28:25,29:26,30:27,31:28,32:d,33:p,34:g,36:y,38:m,39:v,41:b,42:_,43:x,45:w,49:k,54:T,55:C,56:E,57:S,65:A,75:i},t(N,[2,8]),t(N,[2,9]),{17:51,65:A},{17:52,65:A},{5:[1,53]},{5:[1,56],23:[1,54],24:[1,55]},{17:57,65:A},{17:58,65:A},{5:[1,59]},{5:[1,60]},{5:[1,61]},{5:[1,62]},{5:[1,63]},t(N,[2,28]),t(N,[2,29]),{35:[1,64]},{37:[1,65]},t(N,[2,32]),{19:[1,66]},{19:[1,67]},{19:[1,68]},{19:[1,69]},{19:[1,70]},t(N,[2,38]),{62:71,66:[1,72],67:[1,73],68:[1,74],69:[1,75],70:[1,76],71:[1,77],72:[1,78],73:[1,79]},{50:80,52:[1,81],60:[1,82],61:[1,83]},{17:84,65:A},{17:85,65:A},{17:86,65:A},{17:87,65:A},t([5,18,59,66,67,68,69,70,71,72,73,74],[2,58]),{5:[1,88]},{15:89,77:[1,90]},{5:[2,71]},t(N,[2,7]),{5:[1,92],18:[1,91]},{5:[1,94],18:[1,93]},t(N,[2,16]),{5:[1,96],23:[1,95]},{5:[1,97]},t(N,[2,20]),{5:[1,98]},{5:[1,99]},t(N,[2,23]),t(N,[2,24]),t(N,[2,25]),t(N,[2,26]),t(N,[2,27]),t(N,[2,30]),t(N,[2,31]),t(D,a,{8:100}),t(D,a,{8:101}),t(D,a,{8:102}),t(B,a,{44:103,8:104}),t(L,a,{46:105,8:106}),{17:109,63:[1,107],64:[1,108],65:A},t(O,[2,59]),t(O,[2,60]),t(O,[2,61]),t(O,[2,62]),t(O,[2,63]),t(O,[2,64]),t(O,[2,65]),t(O,[2,66]),{17:110,65:A},{17:112,53:111,65:A},{65:[2,53]},{65:[2,54]},{51:113,74:I},{51:115,74:I},{51:116,74:I},{51:117,74:I},t(R,[2,10]),{13:118,78:M},{78:[2,70]},{19:[1,119]},t(N,[2,13]),{19:[1,120]},t(N,[2,15]),{5:[1,121]},t(N,[2,18]),t(N,[2,19]),t(N,[2,21]),t(N,[2,22]),{4:o,5:s,6:39,9:14,10:16,11:6,16:c,17:40,20:u,21:20,22:l,25:h,26:f,27:24,28:25,29:26,30:27,31:28,32:d,33:p,34:g,36:y,38:m,39:v,40:[1,122],41:b,42:_,43:x,45:w,49:k,54:T,55:C,56:E,57:S,65:A,75:i},{4:o,5:s,6:39,9:14,10:16,11:6,16:c,17:40,20:u,21:20,22:l,25:h,26:f,27:24,28:25,29:26,30:27,31:28,32:d,33:p,34:g,36:y,38:m,39:v,40:[1,123],41:b,42:_,43:x,45:w,49:k,54:T,55:C,56:E,57:S,65:A,75:i},{4:o,5:s,6:39,9:14,10:16,11:6,16:c,17:40,20:u,21:20,22:l,25:h,26:f,27:24,28:25,29:26,30:27,31:28,32:d,33:p,34:g,36:y,38:m,39:v,40:[1,124],41:b,42:_,43:x,45:w,49:k,54:T,55:C,56:E,57:S,65:A,75:i},{40:[1,125]},{4:o,5:s,6:39,9:14,10:16,11:6,16:c,17:40,20:u,21:20,22:l,25:h,26:f,27:24,28:25,29:26,30:27,31:28,32:d,33:p,34:g,36:y,38:m,39:v,40:[2,41],41:b,42:_,43:x,45:w,48:[1,126],49:k,54:T,55:C,56:E,57:S,65:A,75:i},{40:[1,127]},{4:o,5:s,6:39,9:14,10:16,11:6,16:c,17:40,20:u,21:20,22:l,25:h,26:f,27:24,28:25,29:26,30:27,31:28,32:d,33:p,34:g,36:y,38:m,39:v,40:[2,39],41:b,42:_,43:x,45:w,47:[1,128],49:k,54:T,55:C,56:E,57:S,65:A,75:i},{17:129,65:A},{17:130,65:A},{51:131,74:I},{51:132,74:I},{51:133,74:I},{59:[1,134],74:[2,52]},{5:[2,45]},{5:[2,67]},{5:[2,46]},{5:[2,47]},{5:[2,48]},{5:[1,135]},{5:[1,136]},{5:[1,137]},t(N,[2,17]),t(N,[2,33]),t(N,[2,34]),t(N,[2,35]),t(N,[2,36]),{19:[1,138]},t(N,[2,37]),{19:[1,139]},{51:140,74:I},{51:141,74:I},{5:[2,57]},{5:[2,43]},{5:[2,44]},{17:142,65:A},t(R,[2,11]),t(N,[2,12]),t(N,[2,14]),t(B,a,{8:104,44:143}),t(L,a,{8:106,46:144}),{5:[2,55]},{5:[2,56]},{74:[2,51]},{40:[2,42]},{40:[2,40]}],defaultActions:{7:[2,68],8:[2,1],9:[2,2],10:[2,3],49:[2,71],82:[2,53],83:[2,54],90:[2,70],113:[2,45],114:[2,67],115:[2,46],116:[2,47],117:[2,48],131:[2,57],132:[2,43],133:[2,44],140:[2,55],141:[2,56],142:[2,51],143:[2,42],144:[2,40]},parseError:function(t,e){if(!e.recoverable){var n=new Error(t);throw n.hash=e,n}this.trace(t)},parse:function(t){var e=this,n=[0],r=[],i=[null],a=[],o=this.table,s="",c=0,u=0,l=0,h=2,f=1,d=a.slice.call(arguments,1),p=Object.create(this.lexer),g={yy:{}};for(var y in this.yy)Object.prototype.hasOwnProperty.call(this.yy,y)&&(g.yy[y]=this.yy[y]);p.setInput(t,g.yy),g.yy.lexer=p,g.yy.parser=this,void 0===p.yylloc&&(p.yylloc={});var m=p.yylloc;a.push(m);var v=p.options&&p.options.ranges;function b(){var t;return"number"!=typeof(t=r.pop()||p.lex()||f)&&(t instanceof Array&&(t=(r=t).pop()),t=e.symbols_[t]||t),t}"function"==typeof g.yy.parseError?this.parseError=g.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;for(var _,x,w,k,T,C,E,S,A,M={};;){if(w=n[n.length-1],this.defaultActions[w]?k=this.defaultActions[w]:(null==_&&(_=b()),k=o[w]&&o[w][_]),void 0===k||!k.length||!k[0]){var N="";for(C in A=[],o[w])this.terminals_[C]&&C>h&&A.push("'"+this.terminals_[C]+"'");N=p.showPosition?"Parse error on line "+(c+1)+":\n"+p.showPosition()+"\nExpecting "+A.join(", ")+", got '"+(this.terminals_[_]||_)+"'":"Parse error on line "+(c+1)+": Unexpected "+(_==f?"end of input":"'"+(this.terminals_[_]||_)+"'"),this.parseError(N,{text:p.match,token:this.terminals_[_]||_,line:p.yylineno,loc:m,expected:A})}if(k[0]instanceof Array&&k.length>1)throw new Error("Parse Error: multiple actions possible at state: "+w+", token: "+_);switch(k[0]){case 1:n.push(_),i.push(p.yytext),a.push(p.yylloc),n.push(k[1]),_=null,x?(_=x,x=null):(u=p.yyleng,s=p.yytext,c=p.yylineno,m=p.yylloc,l>0&&l--);break;case 2:if(E=this.productions_[k[1]][1],M.$=i[i.length-E],M._$={first_line:a[a.length-(E||1)].first_line,last_line:a[a.length-1].last_line,first_column:a[a.length-(E||1)].first_column,last_column:a[a.length-1].last_column},v&&(M._$.range=[a[a.length-(E||1)].range[0],a[a.length-1].range[1]]),void 0!==(T=this.performAction.apply(M,[s,u,c,g.yy,k[1],i,a].concat(d))))return T;E&&(n=n.slice(0,-1*E*2),i=i.slice(0,-1*E),a=a.slice(0,-1*E)),n.push(this.productions_[k[1]][0]),i.push(M.$),a.push(M._$),S=o[n[n.length-2]][n[n.length-1]],n.push(S);break;case 3:return!0}}return!0}},P={EOF:1,parseError:function(t,e){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,e)},setInput:function(t,e){return this.yy=e||this.yy||{},this._input=t,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},input:function(){var t=this._input[0];return this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t,t.match(/(?:\r\n?|\n).*/g)?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),t},unput:function(t){var e=t.length,n=t.split(/(?:\r\n?|\n)/g);this._input=t+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-e),this.offset-=e;var r=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),n.length-1&&(this.yylineno-=n.length-1);var i=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:n?(n.length===r.length?this.yylloc.first_column:0)+r[r.length-n.length].length-n[0].length:this.yylloc.first_column-e},this.options.ranges&&(this.yylloc.range=[i[0],i[0]+this.yyleng-e]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject:function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):this.parseError("Lexical error on line "+(this.yylineno+1)+". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},less:function(t){this.unput(this.match.slice(t))},pastInput:function(){var t=this.matched.substr(0,this.matched.length-this.match.length);return(t.length>20?"...":"")+t.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var t=this.match;return t.length<20&&(t+=this._input.substr(0,20-t.length)),(t.substr(0,20)+(t.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var t=this.pastInput(),e=new Array(t.length+1).join("-");return t+this.upcomingInput()+"\n"+e+"^"},test_match:function(t,e){var n,r,i;if(this.options.backtrack_lexer&&(i={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(i.yylloc.range=this.yylloc.range.slice(0))),(r=t[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=r.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:r?r[r.length-1].length-r[r.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],n=this.performAction.call(this,this.yy,this,e,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),n)return n;if(this._backtrack){for(var a in i)this[a]=i[a];return!1}return!1},next:function(){if(this.done)return this.EOF;var t,e,n,r;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var i=this._currentRules(),a=0;ae[0].length)){if(e=n,r=a,this.options.backtrack_lexer){if(!1!==(t=this.test_match(n,i[a])))return t;if(this._backtrack){e=!1;continue}return!1}if(!this.options.flex)break}return e?!1!==(t=this.test_match(e,i[r]))&&t:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){return this.next()||this.lex()},begin:function(t){this.conditionStack.push(t)},popState:function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]},_currentRules:function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},topState:function(t){return(t=this.conditionStack.length-1-Math.abs(t||0))>=0?this.conditionStack[t]:"INITIAL"},pushState:function(t){this.begin(t)},stateStackSize:function(){return this.conditionStack.length},options:{"case-insensitive":!0},performAction:function(t,e,n,r){switch(n){case 0:return this.begin("open_directive"),75;case 1:return this.begin("type_directive"),76;case 2:return this.popState(),this.begin("arg_directive"),14;case 3:return this.popState(),this.popState(),78;case 4:return 77;case 5:case 49:case 62:return 5;case 6:case 7:case 8:case 9:case 10:break;case 11:return 23;case 12:return this.begin("ID"),16;case 13:return this.begin("ID"),20;case 14:return e.yytext=e.yytext.trim(),this.begin("ALIAS"),65;case 15:return this.popState(),this.popState(),this.begin("LINE"),18;case 16:return this.popState(),this.popState(),5;case 17:return this.begin("LINE"),39;case 18:return this.begin("LINE"),41;case 19:return this.begin("LINE"),42;case 20:return this.begin("LINE"),43;case 21:return this.begin("LINE"),48;case 22:return this.begin("LINE"),45;case 23:return this.begin("LINE"),47;case 24:return this.popState(),19;case 25:return 40;case 26:return 60;case 27:return 61;case 28:return 54;case 29:return 55;case 30:return 56;case 31:return 57;case 32:return 52;case 33:return 49;case 34:return this.begin("ID"),25;case 35:return this.begin("ID"),26;case 36:return 32;case 37:return 33;case 38:return this.begin("acc_title"),34;case 39:return this.popState(),"acc_title_value";case 40:return this.begin("acc_descr"),36;case 41:return this.popState(),"acc_descr_value";case 42:this.begin("acc_descr_multiline");break;case 43:this.popState();break;case 44:return"acc_descr_multiline_value";case 45:return 7;case 46:return 22;case 47:return 24;case 48:return 59;case 50:return e.yytext=e.yytext.trim(),65;case 51:return 68;case 52:return 69;case 53:return 66;case 54:return 67;case 55:return 70;case 56:return 71;case 57:return 72;case 58:return 73;case 59:return 74;case 60:return 63;case 61:return 64;case 63:return"INVALID"}},rules:[/^(?:%%\{)/i,/^(?:((?:(?!\}%%)[^:.])*))/i,/^(?::)/i,/^(?:\}%%)/i,/^(?:((?:(?!\}%%).|\n)*))/i,/^(?:[\n]+)/i,/^(?:\s+)/i,/^(?:((?!\n)\s)+)/i,/^(?:#[^\n]*)/i,/^(?:%(?!\{)[^\n]*)/i,/^(?:[^\}]%%[^\n]*)/i,/^(?:[0-9]+(?=[ \n]+))/i,/^(?:participant\b)/i,/^(?:actor\b)/i,/^(?:[^\->:\n,;]+?(?=((?!\n)\s)+as(?!\n)\s|[#\n;]|$))/i,/^(?:as\b)/i,/^(?:(?:))/i,/^(?:loop\b)/i,/^(?:rect\b)/i,/^(?:opt\b)/i,/^(?:alt\b)/i,/^(?:else\b)/i,/^(?:par\b)/i,/^(?:and\b)/i,/^(?:(?:[:]?(?:no)?wrap)?[^#\n;]*)/i,/^(?:end\b)/i,/^(?:left of\b)/i,/^(?:right of\b)/i,/^(?:links\b)/i,/^(?:link\b)/i,/^(?:properties\b)/i,/^(?:details\b)/i,/^(?:over\b)/i,/^(?:note\b)/i,/^(?:activate\b)/i,/^(?:deactivate\b)/i,/^(?:title\s[^#\n;]+)/i,/^(?:title:\s[^#\n;]+)/i,/^(?:accTitle\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*\{\s*)/i,/^(?:[\}])/i,/^(?:[^\}]*)/i,/^(?:sequenceDiagram\b)/i,/^(?:autonumber\b)/i,/^(?:off\b)/i,/^(?:,)/i,/^(?:;)/i,/^(?:[^\+\->:\n,;]+((?!(-x|--x|-\)|--\)))[\-]*[^\+\->:\n,;]+)*)/i,/^(?:->>)/i,/^(?:-->>)/i,/^(?:->)/i,/^(?:-->)/i,/^(?:-[x])/i,/^(?:--[x])/i,/^(?:-[\)])/i,/^(?:--[\)])/i,/^(?::(?:(?:no)?wrap)?[^#\n;]+)/i,/^(?:\+)/i,/^(?:-)/i,/^(?:$)/i,/^(?:.)/i],conditions:{acc_descr_multiline:{rules:[43,44],inclusive:!1},acc_descr:{rules:[41],inclusive:!1},acc_title:{rules:[39],inclusive:!1},open_directive:{rules:[1,8],inclusive:!1},type_directive:{rules:[2,3,8],inclusive:!1},arg_directive:{rules:[3,4,8],inclusive:!1},ID:{rules:[7,8,14],inclusive:!1},ALIAS:{rules:[7,8,15,16],inclusive:!1},LINE:{rules:[7,8,24],inclusive:!1},INITIAL:{rules:[0,5,6,8,9,10,11,12,13,17,18,19,20,21,22,23,25,26,27,28,29,30,31,32,33,34,35,36,37,38,40,42,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63],inclusive:!0}}};function Y(){this.yy={}}return F.lexer=P,Y.prototype=F,F.Parser=Y,new Y}();e.parser=r,e.Parser=r.Parser,e.parse=function(){return r.parse.apply(r,arguments)},e.main=function(t){t[1]||(console.log("Usage: "+t[0]+" FILE"),process.exit(1));var r=n(1993).readFileSync(n(6470).normalize(t[1]),"utf8");return e.parser.parse(r)},n.c[n.s]===t&&e.main(process.argv.slice(1))},3584:(t,e,n)=>{t=n.nmd(t);var r=function(){var t=function(t,e,n,r){for(n=n||{},r=t.length;r--;n[t[r]]=e);return n},e=[1,2],n=[1,3],r=[1,5],i=[1,7],a=[2,5],o=[1,15],s=[1,17],c=[1,19],u=[1,20],l=[1,21],h=[1,22],f=[1,33],d=[1,23],p=[1,24],g=[1,25],y=[1,26],m=[1,27],v=[1,30],b=[1,31],_=[1,32],x=[1,35],w=[1,36],k=[1,37],T=[1,38],C=[1,34],E=[1,41],S=[1,4,5,14,15,17,19,20,22,23,24,25,26,27,31,33,35,41,42,43,44,47,50],A=[1,4,5,12,13,14,15,17,19,20,22,23,24,25,26,27,31,33,35,41,42,43,44,47,50],M=[1,4,5,7,14,15,17,19,20,22,23,24,25,26,27,31,33,35,41,42,43,44,47,50],N=[4,5,14,15,17,19,20,22,23,24,25,26,27,31,33,35,41,42,43,44,47,50],D={trace:function(){},yy:{},symbols_:{error:2,start:3,SPACE:4,NL:5,directive:6,SD:7,document:8,line:9,statement:10,idStatement:11,DESCR:12,"--\x3e":13,HIDE_EMPTY:14,scale:15,WIDTH:16,COMPOSIT_STATE:17,STRUCT_START:18,STRUCT_STOP:19,STATE_DESCR:20,AS:21,ID:22,FORK:23,JOIN:24,CHOICE:25,CONCURRENT:26,note:27,notePosition:28,NOTE_TEXT:29,direction:30,acc_title:31,acc_title_value:32,acc_descr:33,acc_descr_value:34,acc_descr_multiline_value:35,openDirective:36,typeDirective:37,closeDirective:38,":":39,argDirective:40,direction_tb:41,direction_bt:42,direction_rl:43,direction_lr:44,eol:45,";":46,EDGE_STATE:47,left_of:48,right_of:49,open_directive:50,type_directive:51,arg_directive:52,close_directive:53,$accept:0,$end:1},terminals_:{2:"error",4:"SPACE",5:"NL",7:"SD",12:"DESCR",13:"--\x3e",14:"HIDE_EMPTY",15:"scale",16:"WIDTH",17:"COMPOSIT_STATE",18:"STRUCT_START",19:"STRUCT_STOP",20:"STATE_DESCR",21:"AS",22:"ID",23:"FORK",24:"JOIN",25:"CHOICE",26:"CONCURRENT",27:"note",29:"NOTE_TEXT",31:"acc_title",32:"acc_title_value",33:"acc_descr",34:"acc_descr_value",35:"acc_descr_multiline_value",39:":",41:"direction_tb",42:"direction_bt",43:"direction_rl",44:"direction_lr",46:";",47:"EDGE_STATE",48:"left_of",49:"right_of",50:"open_directive",51:"type_directive",52:"arg_directive",53:"close_directive"},productions_:[0,[3,2],[3,2],[3,2],[3,2],[8,0],[8,2],[9,2],[9,1],[9,1],[10,1],[10,2],[10,3],[10,4],[10,1],[10,2],[10,1],[10,4],[10,3],[10,6],[10,1],[10,1],[10,1],[10,1],[10,4],[10,4],[10,1],[10,1],[10,2],[10,2],[10,1],[6,3],[6,5],[30,1],[30,1],[30,1],[30,1],[45,1],[45,1],[11,1],[11,1],[28,1],[28,1],[36,1],[37,1],[40,1],[38,1]],performAction:function(t,e,n,r,i,a,o){var s=a.length-1;switch(i){case 4:return r.setRootDoc(a[s]),a[s];case 5:this.$=[];break;case 6:"nl"!=a[s]&&(a[s-1].push(a[s]),this.$=a[s-1]);break;case 7:case 8:case 39:case 40:this.$=a[s];break;case 9:this.$="nl";break;case 10:this.$={stmt:"state",id:a[s],type:"default",description:""};break;case 11:this.$={stmt:"state",id:a[s-1],type:"default",description:r.trimColon(a[s])};break;case 12:this.$={stmt:"relation",state1:{stmt:"state",id:a[s-2],type:"default",description:""},state2:{stmt:"state",id:a[s],type:"default",description:""}};break;case 13:this.$={stmt:"relation",state1:{stmt:"state",id:a[s-3],type:"default",description:""},state2:{stmt:"state",id:a[s-1],type:"default",description:""},description:a[s].substr(1).trim()};break;case 17:this.$={stmt:"state",id:a[s-3],type:"default",description:"",doc:a[s-1]};break;case 18:var c=a[s],u=a[s-2].trim();if(a[s].match(":")){var l=a[s].split(":");c=l[0],u=[u,l[1]]}this.$={stmt:"state",id:c,type:"default",description:u};break;case 19:this.$={stmt:"state",id:a[s-3],type:"default",description:a[s-5],doc:a[s-1]};break;case 20:this.$={stmt:"state",id:a[s],type:"fork"};break;case 21:this.$={stmt:"state",id:a[s],type:"join"};break;case 22:this.$={stmt:"state",id:a[s],type:"choice"};break;case 23:this.$={stmt:"state",id:r.getDividerId(),type:"divider"};break;case 24:this.$={stmt:"state",id:a[s-1].trim(),note:{position:a[s-2].trim(),text:a[s].trim()}};break;case 28:this.$=a[s].trim(),r.setTitle(this.$);break;case 29:case 30:this.$=a[s].trim(),r.setAccDescription(this.$);break;case 33:r.setDirection("TB"),this.$={stmt:"dir",value:"TB"};break;case 34:r.setDirection("BT"),this.$={stmt:"dir",value:"BT"};break;case 35:r.setDirection("RL"),this.$={stmt:"dir",value:"RL"};break;case 36:r.setDirection("LR"),this.$={stmt:"dir",value:"LR"};break;case 43:r.parseDirective("%%{","open_directive");break;case 44:r.parseDirective(a[s],"type_directive");break;case 45:a[s]=a[s].trim().replace(/'/g,'"'),r.parseDirective(a[s],"arg_directive");break;case 46:r.parseDirective("}%%","close_directive","state")}},table:[{3:1,4:e,5:n,6:4,7:r,36:6,50:i},{1:[3]},{3:8,4:e,5:n,6:4,7:r,36:6,50:i},{3:9,4:e,5:n,6:4,7:r,36:6,50:i},{3:10,4:e,5:n,6:4,7:r,36:6,50:i},t([1,4,5,14,15,17,20,22,23,24,25,26,27,31,33,35,41,42,43,44,47,50],a,{8:11}),{37:12,51:[1,13]},{51:[2,43]},{1:[2,1]},{1:[2,2]},{1:[2,3]},{1:[2,4],4:o,5:s,6:28,9:14,10:16,11:18,14:c,15:u,17:l,20:h,22:f,23:d,24:p,25:g,26:y,27:m,30:29,31:v,33:b,35:_,36:6,41:x,42:w,43:k,44:T,47:C,50:i},{38:39,39:[1,40],53:E},t([39,53],[2,44]),t(S,[2,6]),{6:28,10:42,11:18,14:c,15:u,17:l,20:h,22:f,23:d,24:p,25:g,26:y,27:m,30:29,31:v,33:b,35:_,36:6,41:x,42:w,43:k,44:T,47:C,50:i},t(S,[2,8]),t(S,[2,9]),t(S,[2,10],{12:[1,43],13:[1,44]}),t(S,[2,14]),{16:[1,45]},t(S,[2,16],{18:[1,46]}),{21:[1,47]},t(S,[2,20]),t(S,[2,21]),t(S,[2,22]),t(S,[2,23]),{28:48,29:[1,49],48:[1,50],49:[1,51]},t(S,[2,26]),t(S,[2,27]),{32:[1,52]},{34:[1,53]},t(S,[2,30]),t(A,[2,39]),t(A,[2,40]),t(S,[2,33]),t(S,[2,34]),t(S,[2,35]),t(S,[2,36]),t(M,[2,31]),{40:54,52:[1,55]},t(M,[2,46]),t(S,[2,7]),t(S,[2,11]),{11:56,22:f,47:C},t(S,[2,15]),t(N,a,{8:57}),{22:[1,58]},{22:[1,59]},{21:[1,60]},{22:[2,41]},{22:[2,42]},t(S,[2,28]),t(S,[2,29]),{38:61,53:E},{53:[2,45]},t(S,[2,12],{12:[1,62]}),{4:o,5:s,6:28,9:14,10:16,11:18,14:c,15:u,17:l,19:[1,63],20:h,22:f,23:d,24:p,25:g,26:y,27:m,30:29,31:v,33:b,35:_,36:6,41:x,42:w,43:k,44:T,47:C,50:i},t(S,[2,18],{18:[1,64]}),{29:[1,65]},{22:[1,66]},t(M,[2,32]),t(S,[2,13]),t(S,[2,17]),t(N,a,{8:67}),t(S,[2,24]),t(S,[2,25]),{4:o,5:s,6:28,9:14,10:16,11:18,14:c,15:u,17:l,19:[1,68],20:h,22:f,23:d,24:p,25:g,26:y,27:m,30:29,31:v,33:b,35:_,36:6,41:x,42:w,43:k,44:T,47:C,50:i},t(S,[2,19])],defaultActions:{7:[2,43],8:[2,1],9:[2,2],10:[2,3],50:[2,41],51:[2,42],55:[2,45]},parseError:function(t,e){if(!e.recoverable){var n=new Error(t);throw n.hash=e,n}this.trace(t)},parse:function(t){var e=this,n=[0],r=[],i=[null],a=[],o=this.table,s="",c=0,u=0,l=0,h=2,f=1,d=a.slice.call(arguments,1),p=Object.create(this.lexer),g={yy:{}};for(var y in this.yy)Object.prototype.hasOwnProperty.call(this.yy,y)&&(g.yy[y]=this.yy[y]);p.setInput(t,g.yy),g.yy.lexer=p,g.yy.parser=this,void 0===p.yylloc&&(p.yylloc={});var m=p.yylloc;a.push(m);var v=p.options&&p.options.ranges;function b(){var t;return"number"!=typeof(t=r.pop()||p.lex()||f)&&(t instanceof Array&&(t=(r=t).pop()),t=e.symbols_[t]||t),t}"function"==typeof g.yy.parseError?this.parseError=g.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;for(var _,x,w,k,T,C,E,S,A,M={};;){if(w=n[n.length-1],this.defaultActions[w]?k=this.defaultActions[w]:(null==_&&(_=b()),k=o[w]&&o[w][_]),void 0===k||!k.length||!k[0]){var N="";for(C in A=[],o[w])this.terminals_[C]&&C>h&&A.push("'"+this.terminals_[C]+"'");N=p.showPosition?"Parse error on line "+(c+1)+":\n"+p.showPosition()+"\nExpecting "+A.join(", ")+", got '"+(this.terminals_[_]||_)+"'":"Parse error on line "+(c+1)+": Unexpected "+(_==f?"end of input":"'"+(this.terminals_[_]||_)+"'"),this.parseError(N,{text:p.match,token:this.terminals_[_]||_,line:p.yylineno,loc:m,expected:A})}if(k[0]instanceof Array&&k.length>1)throw new Error("Parse Error: multiple actions possible at state: "+w+", token: "+_);switch(k[0]){case 1:n.push(_),i.push(p.yytext),a.push(p.yylloc),n.push(k[1]),_=null,x?(_=x,x=null):(u=p.yyleng,s=p.yytext,c=p.yylineno,m=p.yylloc,l>0&&l--);break;case 2:if(E=this.productions_[k[1]][1],M.$=i[i.length-E],M._$={first_line:a[a.length-(E||1)].first_line,last_line:a[a.length-1].last_line,first_column:a[a.length-(E||1)].first_column,last_column:a[a.length-1].last_column},v&&(M._$.range=[a[a.length-(E||1)].range[0],a[a.length-1].range[1]]),void 0!==(T=this.performAction.apply(M,[s,u,c,g.yy,k[1],i,a].concat(d))))return T;E&&(n=n.slice(0,-1*E*2),i=i.slice(0,-1*E),a=a.slice(0,-1*E)),n.push(this.productions_[k[1]][0]),i.push(M.$),a.push(M._$),S=o[n[n.length-2]][n[n.length-1]],n.push(S);break;case 3:return!0}}return!0}},B={EOF:1,parseError:function(t,e){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,e)},setInput:function(t,e){return this.yy=e||this.yy||{},this._input=t,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},input:function(){var t=this._input[0];return this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t,t.match(/(?:\r\n?|\n).*/g)?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),t},unput:function(t){var e=t.length,n=t.split(/(?:\r\n?|\n)/g);this._input=t+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-e),this.offset-=e;var r=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),n.length-1&&(this.yylineno-=n.length-1);var i=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:n?(n.length===r.length?this.yylloc.first_column:0)+r[r.length-n.length].length-n[0].length:this.yylloc.first_column-e},this.options.ranges&&(this.yylloc.range=[i[0],i[0]+this.yyleng-e]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject:function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):this.parseError("Lexical error on line "+(this.yylineno+1)+". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},less:function(t){this.unput(this.match.slice(t))},pastInput:function(){var t=this.matched.substr(0,this.matched.length-this.match.length);return(t.length>20?"...":"")+t.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var t=this.match;return t.length<20&&(t+=this._input.substr(0,20-t.length)),(t.substr(0,20)+(t.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var t=this.pastInput(),e=new Array(t.length+1).join("-");return t+this.upcomingInput()+"\n"+e+"^"},test_match:function(t,e){var n,r,i;if(this.options.backtrack_lexer&&(i={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(i.yylloc.range=this.yylloc.range.slice(0))),(r=t[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=r.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:r?r[r.length-1].length-r[r.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],n=this.performAction.call(this,this.yy,this,e,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),n)return n;if(this._backtrack){for(var a in i)this[a]=i[a];return!1}return!1},next:function(){if(this.done)return this.EOF;var t,e,n,r;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var i=this._currentRules(),a=0;ae[0].length)){if(e=n,r=a,this.options.backtrack_lexer){if(!1!==(t=this.test_match(n,i[a])))return t;if(this._backtrack){e=!1;continue}return!1}if(!this.options.flex)break}return e?!1!==(t=this.test_match(e,i[r]))&&t:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){return this.next()||this.lex()},begin:function(t){this.conditionStack.push(t)},popState:function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]},_currentRules:function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},topState:function(t){return(t=this.conditionStack.length-1-Math.abs(t||0))>=0?this.conditionStack[t]:"INITIAL"},pushState:function(t){this.begin(t)},stateStackSize:function(){return this.conditionStack.length},options:{"case-insensitive":!0},performAction:function(t,e,n,r){switch(n){case 0:case 33:return 41;case 1:case 34:return 42;case 2:case 35:return 43;case 3:case 36:return 44;case 4:return this.begin("open_directive"),50;case 5:return this.begin("type_directive"),51;case 6:return this.popState(),this.begin("arg_directive"),39;case 7:return this.popState(),this.popState(),53;case 8:return 52;case 9:case 10:case 12:case 13:case 14:case 15:case 46:case 52:break;case 11:case 66:return 5;case 16:return this.pushState("SCALE"),15;case 17:return 16;case 18:case 24:case 40:case 43:this.popState();break;case 19:return this.begin("acc_title"),31;case 20:return this.popState(),"acc_title_value";case 21:return this.begin("acc_descr"),33;case 22:return this.popState(),"acc_descr_value";case 23:this.begin("acc_descr_multiline");break;case 25:return"acc_descr_multiline_value";case 26:this.pushState("STATE");break;case 27:case 30:return this.popState(),e.yytext=e.yytext.slice(0,-8).trim(),23;case 28:case 31:return this.popState(),e.yytext=e.yytext.slice(0,-8).trim(),24;case 29:case 32:return this.popState(),e.yytext=e.yytext.slice(0,-10).trim(),25;case 37:this.begin("STATE_STRING");break;case 38:return this.popState(),this.pushState("STATE_ID"),"AS";case 39:case 54:return this.popState(),"ID";case 41:return"STATE_DESCR";case 42:return 17;case 44:return this.popState(),this.pushState("struct"),18;case 45:return this.popState(),19;case 47:return this.begin("NOTE"),27;case 48:return this.popState(),this.pushState("NOTE_ID"),48;case 49:return this.popState(),this.pushState("NOTE_ID"),49;case 50:this.popState(),this.pushState("FLOATING_NOTE");break;case 51:return this.popState(),this.pushState("FLOATING_NOTE_ID"),"AS";case 53:return"NOTE_TEXT";case 55:return this.popState(),this.pushState("NOTE_TEXT"),22;case 56:return this.popState(),e.yytext=e.yytext.substr(2).trim(),29;case 57:return this.popState(),e.yytext=e.yytext.slice(0,-8).trim(),29;case 58:case 59:return 7;case 60:return 14;case 61:return 47;case 62:return 22;case 63:return e.yytext=e.yytext.trim(),12;case 64:return 13;case 65:return 26;case 67:return"INVALID"}},rules:[/^(?:.*direction\s+TB[^\n]*)/i,/^(?:.*direction\s+BT[^\n]*)/i,/^(?:.*direction\s+RL[^\n]*)/i,/^(?:.*direction\s+LR[^\n]*)/i,/^(?:%%\{)/i,/^(?:((?:(?!\}%%)[^:.])*))/i,/^(?::)/i,/^(?:\}%%)/i,/^(?:((?:(?!\}%%).|\n)*))/i,/^(?:%%(?!\{)[^\n]*)/i,/^(?:[^\}]%%[^\n]*)/i,/^(?:[\n]+)/i,/^(?:[\s]+)/i,/^(?:((?!\n)\s)+)/i,/^(?:#[^\n]*)/i,/^(?:%[^\n]*)/i,/^(?:scale\s+)/i,/^(?:\d+)/i,/^(?:\s+width\b)/i,/^(?:accTitle\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*\{\s*)/i,/^(?:[\}])/i,/^(?:[^\}]*)/i,/^(?:state\s+)/i,/^(?:.*<>)/i,/^(?:.*<>)/i,/^(?:.*<>)/i,/^(?:.*\[\[fork\]\])/i,/^(?:.*\[\[join\]\])/i,/^(?:.*\[\[choice\]\])/i,/^(?:.*direction\s+TB[^\n]*)/i,/^(?:.*direction\s+BT[^\n]*)/i,/^(?:.*direction\s+RL[^\n]*)/i,/^(?:.*direction\s+LR[^\n]*)/i,/^(?:["])/i,/^(?:\s*as\s+)/i,/^(?:[^\n\{]*)/i,/^(?:["])/i,/^(?:[^"]*)/i,/^(?:[^\n\s\{]+)/i,/^(?:\n)/i,/^(?:\{)/i,/^(?:\})/i,/^(?:[\n])/i,/^(?:note\s+)/i,/^(?:left of\b)/i,/^(?:right of\b)/i,/^(?:")/i,/^(?:\s*as\s*)/i,/^(?:["])/i,/^(?:[^"]*)/i,/^(?:[^\n]*)/i,/^(?:\s*[^:\n\s\-]+)/i,/^(?:\s*:[^:\n;]+)/i,/^(?:[\s\S]*?end note\b)/i,/^(?:stateDiagram\s+)/i,/^(?:stateDiagram-v2\s+)/i,/^(?:hide empty description\b)/i,/^(?:\[\*\])/i,/^(?:[^:\n\s\-\{]+)/i,/^(?:\s*:[^:\n;]+)/i,/^(?:-->)/i,/^(?:--)/i,/^(?:$)/i,/^(?:.)/i],conditions:{LINE:{rules:[13,14],inclusive:!1},close_directive:{rules:[13,14],inclusive:!1},arg_directive:{rules:[7,8,13,14],inclusive:!1},type_directive:{rules:[6,7,13,14],inclusive:!1},open_directive:{rules:[5,13,14],inclusive:!1},struct:{rules:[13,14,26,33,34,35,36,45,46,47,61,62,63,64,65],inclusive:!1},FLOATING_NOTE_ID:{rules:[54],inclusive:!1},FLOATING_NOTE:{rules:[51,52,53],inclusive:!1},NOTE_TEXT:{rules:[56,57],inclusive:!1},NOTE_ID:{rules:[55],inclusive:!1},NOTE:{rules:[48,49,50],inclusive:!1},acc_descr_multiline:{rules:[24,25],inclusive:!1},acc_descr:{rules:[22],inclusive:!1},acc_title:{rules:[20],inclusive:!1},SCALE:{rules:[17,18],inclusive:!1},ALIAS:{rules:[],inclusive:!1},STATE_ID:{rules:[39],inclusive:!1},STATE_STRING:{rules:[40,41],inclusive:!1},FORK_STATE:{rules:[],inclusive:!1},STATE:{rules:[13,14,27,28,29,30,31,32,37,38,42,43,44],inclusive:!1},ID:{rules:[13,14],inclusive:!1},INITIAL:{rules:[0,1,2,3,4,9,10,11,12,14,15,16,19,21,23,26,44,47,58,59,60,61,62,63,64,66,67],inclusive:!0}}};function L(){this.yy={}}return D.lexer=B,L.prototype=D,D.Parser=L,new L}();e.parser=r,e.Parser=r.Parser,e.parse=function(){return r.parse.apply(r,arguments)},e.main=function(t){t[1]||(console.log("Usage: "+t[0]+" FILE"),process.exit(1));var r=n(3069).readFileSync(n(6470).normalize(t[1]),"utf8");return e.parser.parse(r)},n.c[n.s]===t&&e.main(process.argv.slice(1))},9763:(t,e,n)=>{t=n.nmd(t);var r=function(){var t=function(t,e,n,r){for(n=n||{},r=t.length;r--;n[t[r]]=e);return n},e=[1,2],n=[1,5],r=[6,9,11,17,18,20,22,23,24,26],i=[1,15],a=[1,16],o=[1,17],s=[1,18],c=[1,19],u=[1,20],l=[1,24],h=[4,6,9,11,17,18,20,22,23,24,26],f={trace:function(){},yy:{},symbols_:{error:2,start:3,journey:4,document:5,EOF:6,directive:7,line:8,SPACE:9,statement:10,NEWLINE:11,openDirective:12,typeDirective:13,closeDirective:14,":":15,argDirective:16,title:17,acc_title:18,acc_title_value:19,acc_descr:20,acc_descr_value:21,acc_descr_multiline_value:22,section:23,taskName:24,taskData:25,open_directive:26,type_directive:27,arg_directive:28,close_directive:29,$accept:0,$end:1},terminals_:{2:"error",4:"journey",6:"EOF",9:"SPACE",11:"NEWLINE",15:":",17:"title",18:"acc_title",19:"acc_title_value",20:"acc_descr",21:"acc_descr_value",22:"acc_descr_multiline_value",23:"section",24:"taskName",25:"taskData",26:"open_directive",27:"type_directive",28:"arg_directive",29:"close_directive"},productions_:[0,[3,3],[3,2],[5,0],[5,2],[8,2],[8,1],[8,1],[8,1],[7,4],[7,6],[10,1],[10,2],[10,2],[10,1],[10,1],[10,2],[10,1],[12,1],[13,1],[16,1],[14,1]],performAction:function(t,e,n,r,i,a,o){var s=a.length-1;switch(i){case 1:return a[s-1];case 3:case 7:case 8:this.$=[];break;case 4:a[s-1].push(a[s]),this.$=a[s-1];break;case 5:case 6:this.$=a[s];break;case 11:r.setTitle(a[s].substr(6)),this.$=a[s].substr(6);break;case 12:this.$=a[s].trim(),r.setTitle(this.$);break;case 13:case 14:this.$=a[s].trim(),r.setAccDescription(this.$);break;case 15:r.addSection(a[s].substr(8)),this.$=a[s].substr(8);break;case 16:r.addTask(a[s-1],a[s]),this.$="task";break;case 18:r.parseDirective("%%{","open_directive");break;case 19:r.parseDirective(a[s],"type_directive");break;case 20:a[s]=a[s].trim().replace(/'/g,'"'),r.parseDirective(a[s],"arg_directive");break;case 21:r.parseDirective("}%%","close_directive","journey")}},table:[{3:1,4:e,7:3,12:4,26:n},{1:[3]},t(r,[2,3],{5:6}),{3:7,4:e,7:3,12:4,26:n},{13:8,27:[1,9]},{27:[2,18]},{6:[1,10],7:21,8:11,9:[1,12],10:13,11:[1,14],12:4,17:i,18:a,20:o,22:s,23:c,24:u,26:n},{1:[2,2]},{14:22,15:[1,23],29:l},t([15,29],[2,19]),t(r,[2,8],{1:[2,1]}),t(r,[2,4]),{7:21,10:25,12:4,17:i,18:a,20:o,22:s,23:c,24:u,26:n},t(r,[2,6]),t(r,[2,7]),t(r,[2,11]),{19:[1,26]},{21:[1,27]},t(r,[2,14]),t(r,[2,15]),{25:[1,28]},t(r,[2,17]),{11:[1,29]},{16:30,28:[1,31]},{11:[2,21]},t(r,[2,5]),t(r,[2,12]),t(r,[2,13]),t(r,[2,16]),t(h,[2,9]),{14:32,29:l},{29:[2,20]},{11:[1,33]},t(h,[2,10])],defaultActions:{5:[2,18],7:[2,2],24:[2,21],31:[2,20]},parseError:function(t,e){if(!e.recoverable){var n=new Error(t);throw n.hash=e,n}this.trace(t)},parse:function(t){var e=this,n=[0],r=[],i=[null],a=[],o=this.table,s="",c=0,u=0,l=0,h=2,f=1,d=a.slice.call(arguments,1),p=Object.create(this.lexer),g={yy:{}};for(var y in this.yy)Object.prototype.hasOwnProperty.call(this.yy,y)&&(g.yy[y]=this.yy[y]);p.setInput(t,g.yy),g.yy.lexer=p,g.yy.parser=this,void 0===p.yylloc&&(p.yylloc={});var m=p.yylloc;a.push(m);var v=p.options&&p.options.ranges;function b(){var t;return"number"!=typeof(t=r.pop()||p.lex()||f)&&(t instanceof Array&&(t=(r=t).pop()),t=e.symbols_[t]||t),t}"function"==typeof g.yy.parseError?this.parseError=g.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;for(var _,x,w,k,T,C,E,S,A,M={};;){if(w=n[n.length-1],this.defaultActions[w]?k=this.defaultActions[w]:(null==_&&(_=b()),k=o[w]&&o[w][_]),void 0===k||!k.length||!k[0]){var N="";for(C in A=[],o[w])this.terminals_[C]&&C>h&&A.push("'"+this.terminals_[C]+"'");N=p.showPosition?"Parse error on line "+(c+1)+":\n"+p.showPosition()+"\nExpecting "+A.join(", ")+", got '"+(this.terminals_[_]||_)+"'":"Parse error on line "+(c+1)+": Unexpected "+(_==f?"end of input":"'"+(this.terminals_[_]||_)+"'"),this.parseError(N,{text:p.match,token:this.terminals_[_]||_,line:p.yylineno,loc:m,expected:A})}if(k[0]instanceof Array&&k.length>1)throw new Error("Parse Error: multiple actions possible at state: "+w+", token: "+_);switch(k[0]){case 1:n.push(_),i.push(p.yytext),a.push(p.yylloc),n.push(k[1]),_=null,x?(_=x,x=null):(u=p.yyleng,s=p.yytext,c=p.yylineno,m=p.yylloc,l>0&&l--);break;case 2:if(E=this.productions_[k[1]][1],M.$=i[i.length-E],M._$={first_line:a[a.length-(E||1)].first_line,last_line:a[a.length-1].last_line,first_column:a[a.length-(E||1)].first_column,last_column:a[a.length-1].last_column},v&&(M._$.range=[a[a.length-(E||1)].range[0],a[a.length-1].range[1]]),void 0!==(T=this.performAction.apply(M,[s,u,c,g.yy,k[1],i,a].concat(d))))return T;E&&(n=n.slice(0,-1*E*2),i=i.slice(0,-1*E),a=a.slice(0,-1*E)),n.push(this.productions_[k[1]][0]),i.push(M.$),a.push(M._$),S=o[n[n.length-2]][n[n.length-1]],n.push(S);break;case 3:return!0}}return!0}},d={EOF:1,parseError:function(t,e){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,e)},setInput:function(t,e){return this.yy=e||this.yy||{},this._input=t,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},input:function(){var t=this._input[0];return this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t,t.match(/(?:\r\n?|\n).*/g)?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),t},unput:function(t){var e=t.length,n=t.split(/(?:\r\n?|\n)/g);this._input=t+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-e),this.offset-=e;var r=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),n.length-1&&(this.yylineno-=n.length-1);var i=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:n?(n.length===r.length?this.yylloc.first_column:0)+r[r.length-n.length].length-n[0].length:this.yylloc.first_column-e},this.options.ranges&&(this.yylloc.range=[i[0],i[0]+this.yyleng-e]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject:function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):this.parseError("Lexical error on line "+(this.yylineno+1)+". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},less:function(t){this.unput(this.match.slice(t))},pastInput:function(){var t=this.matched.substr(0,this.matched.length-this.match.length);return(t.length>20?"...":"")+t.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var t=this.match;return t.length<20&&(t+=this._input.substr(0,20-t.length)),(t.substr(0,20)+(t.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var t=this.pastInput(),e=new Array(t.length+1).join("-");return t+this.upcomingInput()+"\n"+e+"^"},test_match:function(t,e){var n,r,i;if(this.options.backtrack_lexer&&(i={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(i.yylloc.range=this.yylloc.range.slice(0))),(r=t[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=r.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:r?r[r.length-1].length-r[r.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],n=this.performAction.call(this,this.yy,this,e,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),n)return n;if(this._backtrack){for(var a in i)this[a]=i[a];return!1}return!1},next:function(){if(this.done)return this.EOF;var t,e,n,r;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var i=this._currentRules(),a=0;ae[0].length)){if(e=n,r=a,this.options.backtrack_lexer){if(!1!==(t=this.test_match(n,i[a])))return t;if(this._backtrack){e=!1;continue}return!1}if(!this.options.flex)break}return e?!1!==(t=this.test_match(e,i[r]))&&t:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){return this.next()||this.lex()},begin:function(t){this.conditionStack.push(t)},popState:function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]},_currentRules:function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},topState:function(t){return(t=this.conditionStack.length-1-Math.abs(t||0))>=0?this.conditionStack[t]:"INITIAL"},pushState:function(t){this.begin(t)},stateStackSize:function(){return this.conditionStack.length},options:{"case-insensitive":!0},performAction:function(t,e,n,r){switch(n){case 0:return this.begin("open_directive"),26;case 1:return this.begin("type_directive"),27;case 2:return this.popState(),this.begin("arg_directive"),15;case 3:return this.popState(),this.popState(),29;case 4:return 28;case 5:case 6:case 8:case 9:break;case 7:return 11;case 10:return 4;case 11:return 17;case 12:return this.begin("acc_title"),18;case 13:return this.popState(),"acc_title_value";case 14:return this.begin("acc_descr"),20;case 15:return this.popState(),"acc_descr_value";case 16:this.begin("acc_descr_multiline");break;case 17:this.popState();break;case 18:return"acc_descr_multiline_value";case 19:return 23;case 20:return 24;case 21:return 25;case 22:return 15;case 23:return 6;case 24:return"INVALID"}},rules:[/^(?:%%\{)/i,/^(?:((?:(?!\}%%)[^:.])*))/i,/^(?::)/i,/^(?:\}%%)/i,/^(?:((?:(?!\}%%).|\n)*))/i,/^(?:%(?!\{)[^\n]*)/i,/^(?:[^\}]%%[^\n]*)/i,/^(?:[\n]+)/i,/^(?:\s+)/i,/^(?:#[^\n]*)/i,/^(?:journey\b)/i,/^(?:title\s[^#\n;]+)/i,/^(?:accTitle\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*\{\s*)/i,/^(?:[\}])/i,/^(?:[^\}]*)/i,/^(?:section\s[^#:\n;]+)/i,/^(?:[^#:\n;]+)/i,/^(?::[^#\n;]+)/i,/^(?::)/i,/^(?:$)/i,/^(?:.)/i],conditions:{open_directive:{rules:[1],inclusive:!1},type_directive:{rules:[2,3],inclusive:!1},arg_directive:{rules:[3,4],inclusive:!1},acc_descr_multiline:{rules:[17,18],inclusive:!1},acc_descr:{rules:[15],inclusive:!1},acc_title:{rules:[13],inclusive:!1},INITIAL:{rules:[0,5,6,7,8,9,10,11,12,14,16,19,20,21,22,23,24],inclusive:!0}}};function p(){this.yy={}}return f.lexer=d,p.prototype=f,f.Parser=p,new p}();e.parser=r,e.Parser=r.Parser,e.parse=function(){return r.parse.apply(r,arguments)},e.main=function(t){t[1]||(console.log("Usage: "+t[0]+" FILE"),process.exit(1));var r=n(9143).readFileSync(n(6470).normalize(t[1]),"utf8");return e.parser.parse(r)},n.c[n.s]===t&&e.main(process.argv.slice(1))},7967:(t,e)=>{"use strict";e.N=void 0;var n=/^([^\w]*)(javascript|data|vbscript)/im,r=/&#(\w+)(^\w|;)?/g,i=/[\u0000-\u001F\u007F-\u009F\u2000-\u200D\uFEFF]/gim,a=/^([^:]+):/gm,o=[".","/"];e.N=function(t){var e,s=(e=t||"",e.replace(r,(function(t,e){return String.fromCharCode(e)}))).replace(i,"").trim();if(!s)return"about:blank";if(function(t){return o.indexOf(t[0])>-1}(s))return s;var c=s.match(a);if(!c)return s;var u=c[0];return n.test(u)?"about:blank":s}},3841:t=>{t.exports=function(t,e){return t.intersect(e)}},8968:(t,e,n)=>{"use strict";n.d(e,{default:()=>HE});var r=n(1941),i=n.n(r),a={debug:1,info:2,warn:3,error:4,fatal:5},o={debug:function(){},info:function(){},warn:function(){},error:function(){},fatal:function(){}},s=function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"fatal";isNaN(t)&&(t=t.toLowerCase(),void 0!==a[t]&&(t=a[t])),o.trace=function(){},o.debug=function(){},o.info=function(){},o.warn=function(){},o.error=function(){},o.fatal=function(){},t<=a.fatal&&(o.fatal=console.error?console.error.bind(console,c("FATAL"),"color: orange"):console.log.bind(console,"",c("FATAL"))),t<=a.error&&(o.error=console.error?console.error.bind(console,c("ERROR"),"color: orange"):console.log.bind(console,"",c("ERROR"))),t<=a.warn&&(o.warn=console.warn?console.warn.bind(console,c("WARN"),"color: orange"):console.log.bind(console,"",c("WARN"))),t<=a.info&&(o.info=console.info?console.info.bind(console,c("INFO"),"color: lightblue"):console.log.bind(console,"",c("INFO"))),t<=a.debug&&(o.debug=console.debug?console.debug.bind(console,c("DEBUG"),"color: lightgreen"):console.log.bind(console,"",c("DEBUG")))},c=function(t){var e=i()().format("ss.SSS");return"%c".concat(e," : ").concat(t," : ")};function u(t,e){let n;if(void 0===e)for(const e of t)null!=e&&(n=e)&&(n=e);else{let r=-1;for(let i of t)null!=(i=e(i,++r,t))&&(n=i)&&(n=i)}return n}function l(t,e){let n;if(void 0===e)for(const e of t)null!=e&&(n>e||void 0===n&&e>=e)&&(n=e);else{let r=-1;for(let i of t)null!=(i=e(i,++r,t))&&(n>i||void 0===n&&i>=i)&&(n=i)}return n}function h(t){return t}var f=1e-6;function d(t){return"translate("+t+",0)"}function p(t){return"translate(0,"+t+")"}function g(t){return e=>+t(e)}function y(t,e){return e=Math.max(0,t.bandwidth()-2*e)/2,t.round()&&(e=Math.round(e)),n=>+t(n)+e}function m(){return!this.__axis}function v(t,e){var n=[],r=null,i=null,a=6,o=6,s=3,c="undefined"!=typeof window&&window.devicePixelRatio>1?0:.5,u=1===t||4===t?-1:1,l=4===t||2===t?"x":"y",v=1===t||3===t?d:p;function b(d){var p=null==r?e.ticks?e.ticks.apply(e,n):e.domain():r,b=null==i?e.tickFormat?e.tickFormat.apply(e,n):h:i,_=Math.max(a,0)+s,x=e.range(),w=+x[0]+c,k=+x[x.length-1]+c,T=(e.bandwidth?y:g)(e.copy(),c),C=d.selection?d.selection():d,E=C.selectAll(".domain").data([null]),S=C.selectAll(".tick").data(p,e).order(),A=S.exit(),M=S.enter().append("g").attr("class","tick"),N=S.select("line"),D=S.select("text");E=E.merge(E.enter().insert("path",".tick").attr("class","domain").attr("stroke","currentColor")),S=S.merge(M),N=N.merge(M.append("line").attr("stroke","currentColor").attr(l+"2",u*a)),D=D.merge(M.append("text").attr("fill","currentColor").attr(l,u*_).attr("dy",1===t?"0em":3===t?"0.71em":"0.32em")),d!==C&&(E=E.transition(d),S=S.transition(d),N=N.transition(d),D=D.transition(d),A=A.transition(d).attr("opacity",f).attr("transform",(function(t){return isFinite(t=T(t))?v(t+c):this.getAttribute("transform")})),M.attr("opacity",f).attr("transform",(function(t){var e=this.parentNode.__axis;return v((e&&isFinite(e=e(t))?e:T(t))+c)}))),A.remove(),E.attr("d",4===t||2===t?o?"M"+u*o+","+w+"H"+c+"V"+k+"H"+u*o:"M"+c+","+w+"V"+k:o?"M"+w+","+u*o+"V"+c+"H"+k+"V"+u*o:"M"+w+","+c+"H"+k),S.attr("opacity",1).attr("transform",(function(t){return v(T(t)+c)})),N.attr(l+"2",u*a),D.attr(l,u*_).text(b),C.filter(m).attr("fill","none").attr("font-size",10).attr("font-family","sans-serif").attr("text-anchor",2===t?"start":4===t?"end":"middle"),C.each((function(){this.__axis=T}))}return b.scale=function(t){return arguments.length?(e=t,b):e},b.ticks=function(){return n=Array.from(arguments),b},b.tickArguments=function(t){return arguments.length?(n=null==t?[]:Array.from(t),b):n.slice()},b.tickValues=function(t){return arguments.length?(r=null==t?null:Array.from(t),b):r&&r.slice()},b.tickFormat=function(t){return arguments.length?(i=t,b):i},b.tickSize=function(t){return arguments.length?(a=o=+t,b):a},b.tickSizeInner=function(t){return arguments.length?(a=+t,b):a},b.tickSizeOuter=function(t){return arguments.length?(o=+t,b):o},b.tickPadding=function(t){return arguments.length?(s=+t,b):s},b.offset=function(t){return arguments.length?(c=+t,b):c},b}function b(){}function _(t){return null==t?b:function(){return this.querySelector(t)}}function x(t){return null==t?[]:Array.isArray(t)?t:Array.from(t)}function w(){return[]}function k(t){return null==t?w:function(){return this.querySelectorAll(t)}}function T(t){return function(){return this.matches(t)}}function C(t){return function(e){return e.matches(t)}}var E=Array.prototype.find;function S(){return this.firstElementChild}var A=Array.prototype.filter;function M(){return Array.from(this.children)}function N(t){return new Array(t.length)}function D(t,e){this.ownerDocument=t.ownerDocument,this.namespaceURI=t.namespaceURI,this._next=null,this._parent=t,this.__data__=e}function B(t){return function(){return t}}function L(t,e,n,r,i,a){for(var o,s=0,c=e.length,u=a.length;se?1:t>=e?0:NaN}D.prototype={constructor:D,appendChild:function(t){return this._parent.insertBefore(t,this._next)},insertBefore:function(t,e){return this._parent.insertBefore(t,e)},querySelector:function(t){return this._parent.querySelector(t)},querySelectorAll:function(t){return this._parent.querySelectorAll(t)}};var P="http://www.w3.org/1999/xhtml";const Y={svg:"http://www.w3.org/2000/svg",xhtml:P,xlink:"http://www.w3.org/1999/xlink",xml:"http://www.w3.org/XML/1998/namespace",xmlns:"http://www.w3.org/2000/xmlns/"};function j(t){var e=t+="",n=e.indexOf(":");return n>=0&&"xmlns"!==(e=t.slice(0,n))&&(t=t.slice(n+1)),Y.hasOwnProperty(e)?{space:Y[e],local:t}:t}function U(t){return function(){this.removeAttribute(t)}}function z(t){return function(){this.removeAttributeNS(t.space,t.local)}}function $(t,e){return function(){this.setAttribute(t,e)}}function q(t,e){return function(){this.setAttributeNS(t.space,t.local,e)}}function H(t,e){return function(){var n=e.apply(this,arguments);null==n?this.removeAttribute(t):this.setAttribute(t,n)}}function W(t,e){return function(){var n=e.apply(this,arguments);null==n?this.removeAttributeNS(t.space,t.local):this.setAttributeNS(t.space,t.local,n)}}function V(t){return t.ownerDocument&&t.ownerDocument.defaultView||t.document&&t||t.defaultView}function G(t){return function(){this.style.removeProperty(t)}}function X(t,e,n){return function(){this.style.setProperty(t,e,n)}}function Z(t,e,n){return function(){var r=e.apply(this,arguments);null==r?this.style.removeProperty(t):this.style.setProperty(t,r,n)}}function Q(t,e){return t.style.getPropertyValue(e)||V(t).getComputedStyle(t,null).getPropertyValue(e)}function K(t){return function(){delete this[t]}}function J(t,e){return function(){this[t]=e}}function tt(t,e){return function(){var n=e.apply(this,arguments);null==n?delete this[t]:this[t]=n}}function et(t){return t.trim().split(/^|\s+/)}function nt(t){return t.classList||new rt(t)}function rt(t){this._node=t,this._names=et(t.getAttribute("class")||"")}function it(t,e){for(var n=nt(t),r=-1,i=e.length;++r=0&&(e=t.slice(n+1),t=t.slice(0,n)),{type:t,name:e}}))}function Ct(t){return function(){var e=this.__on;if(e){for(var n,r=0,i=-1,a=e.length;r=0&&(this._names.splice(e,1),this._node.setAttribute("class",this._names.join(" ")))},contains:function(t){return this._names.indexOf(t)>=0}};var Nt=[null];function Dt(t,e){this._groups=t,this._parents=e}function Bt(){return new Dt([[document.documentElement]],Nt)}Dt.prototype=Bt.prototype={constructor:Dt,select:function(t){"function"!=typeof t&&(t=_(t));for(var e=this._groups,n=e.length,r=new Array(n),i=0;i=x&&(x=_+1);!(b=y[x])&&++x=0;)(r=i[a])&&(o&&4^r.compareDocumentPosition(o)&&o.parentNode.insertBefore(r,o),o=r);return this},sort:function(t){function e(e,n){return e&&n?t(e.__data__,n.__data__):!e-!n}t||(t=F);for(var n=this._groups,r=n.length,i=new Array(r),a=0;a1?this.each((null==e?G:"function"==typeof e?Z:X)(t,e,null==n?"":n)):Q(this.node(),t)},property:function(t,e){return arguments.length>1?this.each((null==e?K:"function"==typeof e?tt:J)(t,e)):this.node()[t]},classed:function(t,e){var n=et(t+"");if(arguments.length<2){for(var r=nt(this.node()),i=-1,a=n.length;++i{}};function It(){for(var t,e=0,n=arguments.length,r={};e=0&&(n=t.slice(r+1),t=t.slice(0,r)),t&&!e.hasOwnProperty(t))throw new Error("unknown type: "+t);return{type:t,name:n}}))}function Pt(t,e){for(var n,r=0,i=t.length;r0)for(var n,r,i=new Array(n),a=0;a=0&&e._call.call(void 0,t),e=e._next;--$t}()}finally{$t=0,function(){for(var t,e,n=Ut,r=1/0;n;)n._call?(r>n._time&&(r=n._time),t=n,n=n._next):(e=n._next,n._next=null,n=t?t._next=e:Ut=e);zt=t,re(r)}(),Vt=0}}function ne(){var t=Xt.now(),e=t-Wt;e>1e3&&(Gt-=e,Wt=t)}function re(t){$t||(qt&&(qt=clearTimeout(qt)),t-Vt>24?(t<1/0&&(qt=setTimeout(ee,t-Xt.now()-Gt)),Ht&&(Ht=clearInterval(Ht))):(Ht||(Wt=Xt.now(),Ht=setInterval(ne,1e3)),$t=1,Zt(ee)))}function ie(t,e,n){var r=new Jt;return e=null==e?0:+e,r.restart((n=>{r.stop(),t(n+e)}),e,n),r}Jt.prototype=te.prototype={constructor:Jt,restart:function(t,e,n){if("function"!=typeof t)throw new TypeError("callback is not a function");n=(null==n?Qt():+n)+(null==e?0:+e),this._next||zt===this||(zt?zt._next=this:Ut=this,zt=this),this._call=t,this._time=n,re()},stop:function(){this._call&&(this._call=null,this._time=1/0,re())}};var ae=jt("start","end","cancel","interrupt"),oe=[];function se(t,e,n,r,i,a){var o=t.__transition;if(o){if(n in o)return}else t.__transition={};!function(t,e,n){var r,i=t.__transition;function a(c){var u,l,h,f;if(1!==n.state)return s();for(u in i)if((f=i[u]).name===n.name){if(3===f.state)return ie(a);4===f.state?(f.state=6,f.timer.stop(),f.on.call("interrupt",t,t.__data__,f.index,f.group),delete i[u]):+u0)throw new Error("too late; already scheduled");return n}function ue(t,e){var n=le(t,e);if(n.state>3)throw new Error("too late; already running");return n}function le(t,e){var n=t.__transition;if(!n||!(n=n[e]))throw new Error("transition not found");return n}function he(t,e){return t=+t,e=+e,function(n){return t*(1-n)+e*n}}var fe,de=180/Math.PI,pe={translateX:0,translateY:0,rotate:0,skewX:0,scaleX:1,scaleY:1};function ge(t,e,n,r,i,a){var o,s,c;return(o=Math.sqrt(t*t+e*e))&&(t/=o,e/=o),(c=t*n+e*r)&&(n-=t*c,r-=e*c),(s=Math.sqrt(n*n+r*r))&&(n/=s,r/=s,c/=s),t*r180?e+=360:e-t>180&&(t+=360),a.push({i:n.push(i(n)+"rotate(",null,r)-2,x:he(t,e)})):e&&n.push(i(n)+"rotate("+e+r)}(a.rotate,o.rotate,s,c),function(t,e,n,a){t!==e?a.push({i:n.push(i(n)+"skewX(",null,r)-2,x:he(t,e)}):e&&n.push(i(n)+"skewX("+e+r)}(a.skewX,o.skewX,s,c),function(t,e,n,r,a,o){if(t!==n||e!==r){var s=a.push(i(a)+"scale(",null,",",null,")");o.push({i:s-4,x:he(t,n)},{i:s-2,x:he(e,r)})}else 1===n&&1===r||a.push(i(a)+"scale("+n+","+r+")")}(a.scaleX,a.scaleY,o.scaleX,o.scaleY,s,c),a=o=null,function(t){for(var e,n=-1,r=c.length;++n>8&15|e>>4&240,e>>4&15|240&e,(15&e)<<4|15&e,1):8===n?ze(e>>24&255,e>>16&255,e>>8&255,(255&e)/255):4===n?ze(e>>12&15|e>>8&240,e>>8&15|e>>4&240,e>>4&15|240&e,((15&e)<<4|15&e)/255):null):(e=De.exec(t))?new He(e[1],e[2],e[3],1):(e=Be.exec(t))?new He(255*e[1]/100,255*e[2]/100,255*e[3]/100,1):(e=Le.exec(t))?ze(e[1],e[2],e[3],e[4]):(e=Oe.exec(t))?ze(255*e[1]/100,255*e[2]/100,255*e[3]/100,e[4]):(e=Ie.exec(t))?Xe(e[1],e[2]/100,e[3]/100,1):(e=Re.exec(t))?Xe(e[1],e[2]/100,e[3]/100,e[4]):Fe.hasOwnProperty(t)?Ue(Fe[t]):"transparent"===t?new He(NaN,NaN,NaN,0):null}function Ue(t){return new He(t>>16&255,t>>8&255,255&t,1)}function ze(t,e,n,r){return r<=0&&(t=e=n=NaN),new He(t,e,n,r)}function $e(t){return t instanceof Te||(t=je(t)),t?new He((t=t.rgb()).r,t.g,t.b,t.opacity):new He}function qe(t,e,n,r){return 1===arguments.length?$e(t):new He(t,e,n,null==r?1:r)}function He(t,e,n,r){this.r=+t,this.g=+e,this.b=+n,this.opacity=+r}function We(){return"#"+Ge(this.r)+Ge(this.g)+Ge(this.b)}function Ve(){var t=this.opacity;return(1===(t=isNaN(t)?1:Math.max(0,Math.min(1,t)))?"rgb(":"rgba(")+Math.max(0,Math.min(255,Math.round(this.r)||0))+", "+Math.max(0,Math.min(255,Math.round(this.g)||0))+", "+Math.max(0,Math.min(255,Math.round(this.b)||0))+(1===t?")":", "+t+")")}function Ge(t){return((t=Math.max(0,Math.min(255,Math.round(t)||0)))<16?"0":"")+t.toString(16)}function Xe(t,e,n,r){return r<=0?t=e=n=NaN:n<=0||n>=1?t=e=NaN:e<=0&&(t=NaN),new Qe(t,e,n,r)}function Ze(t){if(t instanceof Qe)return new Qe(t.h,t.s,t.l,t.opacity);if(t instanceof Te||(t=je(t)),!t)return new Qe;if(t instanceof Qe)return t;var e=(t=t.rgb()).r/255,n=t.g/255,r=t.b/255,i=Math.min(e,n,r),a=Math.max(e,n,r),o=NaN,s=a-i,c=(a+i)/2;return s?(o=e===a?(n-r)/s+6*(n0&&c<1?0:o,new Qe(o,s,c,t.opacity)}function Qe(t,e,n,r){this.h=+t,this.s=+e,this.l=+n,this.opacity=+r}function Ke(t,e,n){return 255*(t<60?e+(n-e)*t/60:t<180?n:t<240?e+(n-e)*(240-t)/60:e)}function Je(t,e,n,r,i){var a=t*t,o=a*t;return((1-3*t+3*a-o)*e+(4-6*a+3*o)*n+(1+3*t+3*a-3*o)*r+o*i)/6}we(Te,je,{copy:function(t){return Object.assign(new this.constructor,this,t)},displayable:function(){return this.rgb().displayable()},hex:Pe,formatHex:Pe,formatHsl:function(){return Ze(this).formatHsl()},formatRgb:Ye,toString:Ye}),we(He,qe,ke(Te,{brighter:function(t){return t=null==t?Ee:Math.pow(Ee,t),new He(this.r*t,this.g*t,this.b*t,this.opacity)},darker:function(t){return t=null==t?Ce:Math.pow(Ce,t),new He(this.r*t,this.g*t,this.b*t,this.opacity)},rgb:function(){return this},displayable:function(){return-.5<=this.r&&this.r<255.5&&-.5<=this.g&&this.g<255.5&&-.5<=this.b&&this.b<255.5&&0<=this.opacity&&this.opacity<=1},hex:We,formatHex:We,formatRgb:Ve,toString:Ve})),we(Qe,(function(t,e,n,r){return 1===arguments.length?Ze(t):new Qe(t,e,n,null==r?1:r)}),ke(Te,{brighter:function(t){return t=null==t?Ee:Math.pow(Ee,t),new Qe(this.h,this.s,this.l*t,this.opacity)},darker:function(t){return t=null==t?Ce:Math.pow(Ce,t),new Qe(this.h,this.s,this.l*t,this.opacity)},rgb:function(){var t=this.h%360+360*(this.h<0),e=isNaN(t)||isNaN(this.s)?0:this.s,n=this.l,r=n+(n<.5?n:1-n)*e,i=2*n-r;return new He(Ke(t>=240?t-240:t+120,i,r),Ke(t,i,r),Ke(t<120?t+240:t-120,i,r),this.opacity)},displayable:function(){return(0<=this.s&&this.s<=1||isNaN(this.s))&&0<=this.l&&this.l<=1&&0<=this.opacity&&this.opacity<=1},formatHsl:function(){var t=this.opacity;return(1===(t=isNaN(t)?1:Math.max(0,Math.min(1,t)))?"hsl(":"hsla(")+(this.h||0)+", "+100*(this.s||0)+"%, "+100*(this.l||0)+"%"+(1===t?")":", "+t+")")}}));const tn=t=>()=>t;function en(t,e){var n=e-t;return n?function(t,e){return function(n){return t+n*e}}(t,n):tn(isNaN(t)?e:t)}const nn=function t(e){var n=function(t){return 1==(t=+t)?en:function(e,n){return n-e?function(t,e,n){return t=Math.pow(t,n),e=Math.pow(e,n)-t,n=1/n,function(r){return Math.pow(t+r*e,n)}}(e,n,t):tn(isNaN(e)?n:e)}}(e);function r(t,e){var r=n((t=qe(t)).r,(e=qe(e)).r),i=n(t.g,e.g),a=n(t.b,e.b),o=en(t.opacity,e.opacity);return function(e){return t.r=r(e),t.g=i(e),t.b=a(e),t.opacity=o(e),t+""}}return r.gamma=t,r}(1);function rn(t){return function(e){var n,r,i=e.length,a=new Array(i),o=new Array(i),s=new Array(i);for(n=0;n=1?(n=1,e-1):Math.floor(n*e),i=t[r],a=t[r+1],o=r>0?t[r-1]:2*i-a,s=ra&&(i=e.slice(a,i),s[o]?s[o]+=i:s[++o]=i),(n=n[0])===(r=r[0])?s[o]?s[o]+=r:s[++o]=r:(s[++o]=null,c.push({i:o,x:he(n,r)})),a=on.lastIndex;return a=0&&(t=t.slice(0,e)),!t||"start"===t}))}(e)?ce:ue;return function(){var o=a(this,t),s=o.on;s!==r&&(i=(r=s).copy()).on(e,n),o.on=i}}var Cn=Lt.prototype.constructor;function En(t){return function(){this.style.removeProperty(t)}}function Sn(t,e,n){return function(r){this.style.setProperty(t,e.call(this,r),n)}}function An(t,e,n){var r,i;function a(){var a=e.apply(this,arguments);return a!==i&&(r=(i=a)&&Sn(t,a,n)),r}return a._value=e,a}function Mn(t){return function(e){this.textContent=t.call(this,e)}}function Nn(t){var e,n;function r(){var r=t.apply(this,arguments);return r!==n&&(e=(n=r)&&Mn(r)),e}return r._value=t,r}var Dn=0;function Bn(t,e,n,r){this._groups=t,this._parents=e,this._name=n,this._id=r}function Ln(){return++Dn}var On=Lt.prototype;Bn.prototype=function(t){return Lt().transition(t)}.prototype={constructor:Bn,select:function(t){var e=this._name,n=this._id;"function"!=typeof t&&(t=_(t));for(var r=this._groups,i=r.length,a=new Array(i),o=0;o2&&n.state<5,n.state=6,n.timer.stop(),n.on.call(r?"interrupt":"cancel",t,t.__data__,n.index,n.group),delete a[i]):o=!1;o&&delete t.__transition}}(this,t)}))},Lt.prototype.transition=function(t){var e,n;t instanceof Bn?(e=t._id,t=t._name):(e=Ln(),(n=In).time=Qt(),t=null==t?null:t+"");for(var r=this._groups,i=r.length,a=0;a>8&15|e>>4&240,e>>4&15|240&e,(15&e)<<4|15&e,1):8===n?sr(e>>24&255,e>>16&255,e>>8&255,(255&e)/255):4===n?sr(e>>12&15|e>>8&240,e>>8&15|e>>4&240,e>>4&15|240&e,((15&e)<<4|15&e)/255):null):(e=Zn.exec(t))?new lr(e[1],e[2],e[3],1):(e=Qn.exec(t))?new lr(255*e[1]/100,255*e[2]/100,255*e[3]/100,1):(e=Kn.exec(t))?sr(e[1],e[2],e[3],e[4]):(e=Jn.exec(t))?sr(255*e[1]/100,255*e[2]/100,255*e[3]/100,e[4]):(e=tr.exec(t))?pr(e[1],e[2]/100,e[3]/100,1):(e=er.exec(t))?pr(e[1],e[2]/100,e[3]/100,e[4]):nr.hasOwnProperty(t)?or(nr[t]):"transparent"===t?new lr(NaN,NaN,NaN,0):null}function or(t){return new lr(t>>16&255,t>>8&255,255&t,1)}function sr(t,e,n,r){return r<=0&&(t=e=n=NaN),new lr(t,e,n,r)}function cr(t){return t instanceof $n||(t=ar(t)),t?new lr((t=t.rgb()).r,t.g,t.b,t.opacity):new lr}function ur(t,e,n,r){return 1===arguments.length?cr(t):new lr(t,e,n,null==r?1:r)}function lr(t,e,n,r){this.r=+t,this.g=+e,this.b=+n,this.opacity=+r}function hr(){return"#"+dr(this.r)+dr(this.g)+dr(this.b)}function fr(){var t=this.opacity;return(1===(t=isNaN(t)?1:Math.max(0,Math.min(1,t)))?"rgb(":"rgba(")+Math.max(0,Math.min(255,Math.round(this.r)||0))+", "+Math.max(0,Math.min(255,Math.round(this.g)||0))+", "+Math.max(0,Math.min(255,Math.round(this.b)||0))+(1===t?")":", "+t+")")}function dr(t){return((t=Math.max(0,Math.min(255,Math.round(t)||0)))<16?"0":"")+t.toString(16)}function pr(t,e,n,r){return r<=0?t=e=n=NaN:n<=0||n>=1?t=e=NaN:e<=0&&(t=NaN),new yr(t,e,n,r)}function gr(t){if(t instanceof yr)return new yr(t.h,t.s,t.l,t.opacity);if(t instanceof $n||(t=ar(t)),!t)return new yr;if(t instanceof yr)return t;var e=(t=t.rgb()).r/255,n=t.g/255,r=t.b/255,i=Math.min(e,n,r),a=Math.max(e,n,r),o=NaN,s=a-i,c=(a+i)/2;return s?(o=e===a?(n-r)/s+6*(n0&&c<1?0:o,new yr(o,s,c,t.opacity)}function yr(t,e,n,r){this.h=+t,this.s=+e,this.l=+n,this.opacity=+r}function mr(t,e,n){return 255*(t<60?e+(n-e)*t/60:t<180?n:t<240?e+(n-e)*(240-t)/60:e)}Un($n,ar,{copy:function(t){return Object.assign(new this.constructor,this,t)},displayable:function(){return this.rgb().displayable()},hex:rr,formatHex:rr,formatHsl:function(){return gr(this).formatHsl()},formatRgb:ir,toString:ir}),Un(lr,ur,zn($n,{brighter:function(t){return t=null==t?Hn:Math.pow(Hn,t),new lr(this.r*t,this.g*t,this.b*t,this.opacity)},darker:function(t){return t=null==t?qn:Math.pow(qn,t),new lr(this.r*t,this.g*t,this.b*t,this.opacity)},rgb:function(){return this},displayable:function(){return-.5<=this.r&&this.r<255.5&&-.5<=this.g&&this.g<255.5&&-.5<=this.b&&this.b<255.5&&0<=this.opacity&&this.opacity<=1},hex:hr,formatHex:hr,formatRgb:fr,toString:fr})),Un(yr,(function(t,e,n,r){return 1===arguments.length?gr(t):new yr(t,e,n,null==r?1:r)}),zn($n,{brighter:function(t){return t=null==t?Hn:Math.pow(Hn,t),new yr(this.h,this.s,this.l*t,this.opacity)},darker:function(t){return t=null==t?qn:Math.pow(qn,t),new yr(this.h,this.s,this.l*t,this.opacity)},rgb:function(){var t=this.h%360+360*(this.h<0),e=isNaN(t)||isNaN(this.s)?0:this.s,n=this.l,r=n+(n<.5?n:1-n)*e,i=2*n-r;return new lr(mr(t>=240?t-240:t+120,i,r),mr(t,i,r),mr(t<120?t+240:t-120,i,r),this.opacity)},displayable:function(){return(0<=this.s&&this.s<=1||isNaN(this.s))&&0<=this.l&&this.l<=1&&0<=this.opacity&&this.opacity<=1},formatHsl:function(){var t=this.opacity;return(1===(t=isNaN(t)?1:Math.max(0,Math.min(1,t)))?"hsl(":"hsla(")+(this.h||0)+", "+100*(this.s||0)+"%, "+100*(this.l||0)+"%"+(1===t?")":", "+t+")")}}));const vr=Math.PI/180,br=180/Math.PI,_r=.96422,xr=.82521,wr=4/29,kr=6/29,Tr=3*kr*kr;function Cr(t){if(t instanceof Er)return new Er(t.l,t.a,t.b,t.opacity);if(t instanceof Lr)return Or(t);t instanceof lr||(t=cr(t));var e,n,r=Nr(t.r),i=Nr(t.g),a=Nr(t.b),o=Sr((.2225045*r+.7168786*i+.0606169*a)/1);return r===i&&i===a?e=n=o:(e=Sr((.4360747*r+.3850649*i+.1430804*a)/_r),n=Sr((.0139322*r+.0971045*i+.7141733*a)/xr)),new Er(116*o-16,500*(e-o),200*(o-n),t.opacity)}function Er(t,e,n,r){this.l=+t,this.a=+e,this.b=+n,this.opacity=+r}function Sr(t){return t>.008856451679035631?Math.pow(t,1/3):t/Tr+wr}function Ar(t){return t>kr?t*t*t:Tr*(t-wr)}function Mr(t){return 255*(t<=.0031308?12.92*t:1.055*Math.pow(t,1/2.4)-.055)}function Nr(t){return(t/=255)<=.04045?t/12.92:Math.pow((t+.055)/1.055,2.4)}function Dr(t){if(t instanceof Lr)return new Lr(t.h,t.c,t.l,t.opacity);if(t instanceof Er||(t=Cr(t)),0===t.a&&0===t.b)return new Lr(NaN,0()=>t;function Rr(t,e){return function(n){return t+n*e}}function Fr(t,e){var n=e-t;return n?Rr(t,n):Ir(isNaN(t)?e:t)}function Pr(t){return function(e,n){var r=t((e=Br(e)).h,(n=Br(n)).h),i=Fr(e.c,n.c),a=Fr(e.l,n.l),o=Fr(e.opacity,n.opacity);return function(t){return e.h=r(t),e.c=i(t),e.l=a(t),e.opacity=o(t),e+""}}}const Yr=Pr((function(t,e){var n=e-t;return n?Rr(t,n>180||n<-180?n-360*Math.round(n/360):n):Ir(isNaN(t)?e:t)}));Pr(Fr);var jr=Math.sqrt(50),Ur=Math.sqrt(10),zr=Math.sqrt(2);function $r(t,e,n){var r=(e-t)/Math.max(0,n),i=Math.floor(Math.log(r)/Math.LN10),a=r/Math.pow(10,i);return i>=0?(a>=jr?10:a>=Ur?5:a>=zr?2:1)*Math.pow(10,i):-Math.pow(10,-i)/(a>=jr?10:a>=Ur?5:a>=zr?2:1)}function qr(t,e,n){var r=Math.abs(e-t)/Math.max(0,n),i=Math.pow(10,Math.floor(Math.log(r)/Math.LN10)),a=r/i;return a>=jr?i*=10:a>=Ur?i*=5:a>=zr&&(i*=2),ee?1:t>=e?0:NaN}function Wr(t){let e=t,n=t,r=t;function i(t,e,i=0,a=t.length){if(i>>1;r(t[n],e)<0?i=n+1:a=n}while(it(e)-n,n=Hr,r=(e,n)=>Hr(t(e),n)),{left:i,center:function(t,n,r=0,a=t.length){const o=i(t,n,r,a-1);return o>r&&e(t[o-1],n)>-e(t[o],n)?o-1:o},right:function(t,e,i=0,a=t.length){if(i>>1;r(t[n],e)<=0?i=n+1:a=n}while(i>8&15|e>>4&240,e>>4&15|240&e,(15&e)<<4|15&e,1):8===n?yi(e>>24&255,e>>16&255,e>>8&255,(255&e)/255):4===n?yi(e>>12&15|e>>8&240,e>>8&15|e>>4&240,e>>4&15|240&e,((15&e)<<4|15&e)/255):null):(e=ai.exec(t))?new bi(e[1],e[2],e[3],1):(e=oi.exec(t))?new bi(255*e[1]/100,255*e[2]/100,255*e[3]/100,1):(e=si.exec(t))?yi(e[1],e[2],e[3],e[4]):(e=ci.exec(t))?yi(255*e[1]/100,255*e[2]/100,255*e[3]/100,e[4]):(e=ui.exec(t))?ki(e[1],e[2]/100,e[3]/100,1):(e=li.exec(t))?ki(e[1],e[2]/100,e[3]/100,e[4]):hi.hasOwnProperty(t)?gi(hi[t]):"transparent"===t?new bi(NaN,NaN,NaN,0):null}function gi(t){return new bi(t>>16&255,t>>8&255,255&t,1)}function yi(t,e,n,r){return r<=0&&(t=e=n=NaN),new bi(t,e,n,r)}function mi(t){return t instanceof Kr||(t=pi(t)),t?new bi((t=t.rgb()).r,t.g,t.b,t.opacity):new bi}function vi(t,e,n,r){return 1===arguments.length?mi(t):new bi(t,e,n,null==r?1:r)}function bi(t,e,n,r){this.r=+t,this.g=+e,this.b=+n,this.opacity=+r}function _i(){return"#"+wi(this.r)+wi(this.g)+wi(this.b)}function xi(){var t=this.opacity;return(1===(t=isNaN(t)?1:Math.max(0,Math.min(1,t)))?"rgb(":"rgba(")+Math.max(0,Math.min(255,Math.round(this.r)||0))+", "+Math.max(0,Math.min(255,Math.round(this.g)||0))+", "+Math.max(0,Math.min(255,Math.round(this.b)||0))+(1===t?")":", "+t+")")}function wi(t){return((t=Math.max(0,Math.min(255,Math.round(t)||0)))<16?"0":"")+t.toString(16)}function ki(t,e,n,r){return r<=0?t=e=n=NaN:n<=0||n>=1?t=e=NaN:e<=0&&(t=NaN),new Ci(t,e,n,r)}function Ti(t){if(t instanceof Ci)return new Ci(t.h,t.s,t.l,t.opacity);if(t instanceof Kr||(t=pi(t)),!t)return new Ci;if(t instanceof Ci)return t;var e=(t=t.rgb()).r/255,n=t.g/255,r=t.b/255,i=Math.min(e,n,r),a=Math.max(e,n,r),o=NaN,s=a-i,c=(a+i)/2;return s?(o=e===a?(n-r)/s+6*(n0&&c<1?0:o,new Ci(o,s,c,t.opacity)}function Ci(t,e,n,r){this.h=+t,this.s=+e,this.l=+n,this.opacity=+r}function Ei(t,e,n){return 255*(t<60?e+(n-e)*t/60:t<180?n:t<240?e+(n-e)*(240-t)/60:e)}function Si(t,e,n,r,i){var a=t*t,o=a*t;return((1-3*t+3*a-o)*e+(4-6*a+3*o)*n+(1+3*t+3*a-3*o)*r+o*i)/6}Zr(Kr,pi,{copy:function(t){return Object.assign(new this.constructor,this,t)},displayable:function(){return this.rgb().displayable()},hex:fi,formatHex:fi,formatHsl:function(){return Ti(this).formatHsl()},formatRgb:di,toString:di}),Zr(bi,vi,Qr(Kr,{brighter:function(t){return t=null==t?ti:Math.pow(ti,t),new bi(this.r*t,this.g*t,this.b*t,this.opacity)},darker:function(t){return t=null==t?Jr:Math.pow(Jr,t),new bi(this.r*t,this.g*t,this.b*t,this.opacity)},rgb:function(){return this},displayable:function(){return-.5<=this.r&&this.r<255.5&&-.5<=this.g&&this.g<255.5&&-.5<=this.b&&this.b<255.5&&0<=this.opacity&&this.opacity<=1},hex:_i,formatHex:_i,formatRgb:xi,toString:xi})),Zr(Ci,(function(t,e,n,r){return 1===arguments.length?Ti(t):new Ci(t,e,n,null==r?1:r)}),Qr(Kr,{brighter:function(t){return t=null==t?ti:Math.pow(ti,t),new Ci(this.h,this.s,this.l*t,this.opacity)},darker:function(t){return t=null==t?Jr:Math.pow(Jr,t),new Ci(this.h,this.s,this.l*t,this.opacity)},rgb:function(){var t=this.h%360+360*(this.h<0),e=isNaN(t)||isNaN(this.s)?0:this.s,n=this.l,r=n+(n<.5?n:1-n)*e,i=2*n-r;return new bi(Ei(t>=240?t-240:t+120,i,r),Ei(t,i,r),Ei(t<120?t+240:t-120,i,r),this.opacity)},displayable:function(){return(0<=this.s&&this.s<=1||isNaN(this.s))&&0<=this.l&&this.l<=1&&0<=this.opacity&&this.opacity<=1},formatHsl:function(){var t=this.opacity;return(1===(t=isNaN(t)?1:Math.max(0,Math.min(1,t)))?"hsl(":"hsla(")+(this.h||0)+", "+100*(this.s||0)+"%, "+100*(this.l||0)+"%"+(1===t?")":", "+t+")")}}));const Ai=t=>()=>t;function Mi(t,e){var n=e-t;return n?function(t,e){return function(n){return t+n*e}}(t,n):Ai(isNaN(t)?e:t)}const Ni=function t(e){var n=function(t){return 1==(t=+t)?Mi:function(e,n){return n-e?function(t,e,n){return t=Math.pow(t,n),e=Math.pow(e,n)-t,n=1/n,function(r){return Math.pow(t+r*e,n)}}(e,n,t):Ai(isNaN(e)?n:e)}}(e);function r(t,e){var r=n((t=vi(t)).r,(e=vi(e)).r),i=n(t.g,e.g),a=n(t.b,e.b),o=Mi(t.opacity,e.opacity);return function(e){return t.r=r(e),t.g=i(e),t.b=a(e),t.opacity=o(e),t+""}}return r.gamma=t,r}(1);function Di(t){return function(e){var n,r,i=e.length,a=new Array(i),o=new Array(i),s=new Array(i);for(n=0;n=1?(n=1,e-1):Math.floor(n*e),i=t[r],a=t[r+1],o=r>0?t[r-1]:2*i-a,s=ra&&(i=e.slice(a,i),s[o]?s[o]+=i:s[++o]=i),(n=n[0])===(r=r[0])?s[o]?s[o]+=r:s[++o]=r:(s[++o]=null,c.push({i:o,x:Oi(n,r)})),a=Fi.lastIndex;return ae&&(n=t,t=e,e=n),u=function(n){return Math.max(t,Math.min(e,n))}),r=c>2?Vi:Wi,i=a=null,h}function h(e){return null==e||isNaN(e=+e)?n:(i||(i=r(o.map(t),s,c)))(t(u(e)))}return h.invert=function(n){return u(e((a||(a=r(s,o.map(t),Oi)))(n)))},h.domain=function(t){return arguments.length?(o=Array.from(t,zi),l()):o.slice()},h.range=function(t){return arguments.length?(s=Array.from(t),l()):s.slice()},h.rangeRound=function(t){return s=Array.from(t),c=Ui,l()},h.clamp=function(t){return arguments.length?(u=!!t||qi,l()):u!==qi},h.interpolate=function(t){return arguments.length?(c=t,l()):c},h.unknown=function(t){return arguments.length?(n=t,h):n},function(n,r){return t=n,e=r,l()}}()(qi,qi)}function Zi(t,e){switch(arguments.length){case 0:break;case 1:this.range(t);break;default:this.range(e).domain(t)}return this}var Qi,Ki=/^(?:(.)?([<>=^]))?([+\-( ])?([$#])?(0)?(\d+)?(,)?(\.\d+)?(~)?([a-z%])?$/i;function Ji(t){if(!(e=Ki.exec(t)))throw new Error("invalid format: "+t);var e;return new ta({fill:e[1],align:e[2],sign:e[3],symbol:e[4],zero:e[5],width:e[6],comma:e[7],precision:e[8]&&e[8].slice(1),trim:e[9],type:e[10]})}function ta(t){this.fill=void 0===t.fill?" ":t.fill+"",this.align=void 0===t.align?">":t.align+"",this.sign=void 0===t.sign?"-":t.sign+"",this.symbol=void 0===t.symbol?"":t.symbol+"",this.zero=!!t.zero,this.width=void 0===t.width?void 0:+t.width,this.comma=!!t.comma,this.precision=void 0===t.precision?void 0:+t.precision,this.trim=!!t.trim,this.type=void 0===t.type?"":t.type+""}function ea(t,e){if((n=(t=e?t.toExponential(e-1):t.toExponential()).indexOf("e"))<0)return null;var n,r=t.slice(0,n);return[r.length>1?r[0]+r.slice(2):r,+t.slice(n+1)]}function na(t){return(t=ea(Math.abs(t)))?t[1]:NaN}function ra(t,e){var n=ea(t,e);if(!n)return t+"";var r=n[0],i=n[1];return i<0?"0."+new Array(-i).join("0")+r:r.length>i+1?r.slice(0,i+1)+"."+r.slice(i+1):r+new Array(i-r.length+2).join("0")}Ji.prototype=ta.prototype,ta.prototype.toString=function(){return this.fill+this.align+this.sign+this.symbol+(this.zero?"0":"")+(void 0===this.width?"":Math.max(1,0|this.width))+(this.comma?",":"")+(void 0===this.precision?"":"."+Math.max(0,0|this.precision))+(this.trim?"~":"")+this.type};const ia={"%":(t,e)=>(100*t).toFixed(e),b:t=>Math.round(t).toString(2),c:t=>t+"",d:function(t){return Math.abs(t=Math.round(t))>=1e21?t.toLocaleString("en").replace(/,/g,""):t.toString(10)},e:(t,e)=>t.toExponential(e),f:(t,e)=>t.toFixed(e),g:(t,e)=>t.toPrecision(e),o:t=>Math.round(t).toString(8),p:(t,e)=>ra(100*t,e),r:ra,s:function(t,e){var n=ea(t,e);if(!n)return t+"";var r=n[0],i=n[1],a=i-(Qi=3*Math.max(-8,Math.min(8,Math.floor(i/3))))+1,o=r.length;return a===o?r:a>o?r+new Array(a-o+1).join("0"):a>0?r.slice(0,a)+"."+r.slice(a):"0."+new Array(1-a).join("0")+ea(t,Math.max(0,e+a-1))[0]},X:t=>Math.round(t).toString(16).toUpperCase(),x:t=>Math.round(t).toString(16)};function aa(t){return t}var oa,sa,ca,ua=Array.prototype.map,la=["y","z","a","f","p","n","µ","m","","k","M","G","T","P","E","Z","Y"];function ha(t){var e=t.domain;return t.ticks=function(t){var n=e();return function(t,e,n){var r,i,a,o,s=-1;if(n=+n,(t=+t)==(e=+e)&&n>0)return[t];if((r=e0){let n=Math.round(t/o),r=Math.round(e/o);for(n*oe&&--r,a=new Array(i=r-n+1);++se&&--r,a=new Array(i=r-n+1);++s0;){if((i=$r(c,u,n))===r)return a[o]=c,a[s]=u,e(a);if(i>0)c=Math.floor(c/i)*i,u=Math.ceil(u/i)*i;else{if(!(i<0))break;c=Math.ceil(c*i)/i,u=Math.floor(u*i)/i}r=i}return t},t}function fa(){var t=Xi();return t.copy=function(){return Gi(t,fa())},Zi.apply(t,arguments),ha(t)}oa=function(t){var e,n,r=void 0===t.grouping||void 0===t.thousands?aa:(e=ua.call(t.grouping,Number),n=t.thousands+"",function(t,r){for(var i=t.length,a=[],o=0,s=e[0],c=0;i>0&&s>0&&(c+s+1>r&&(s=Math.max(1,r-c)),a.push(t.substring(i-=s,i+s)),!((c+=s+1)>r));)s=e[o=(o+1)%e.length];return a.reverse().join(n)}),i=void 0===t.currency?"":t.currency[0]+"",a=void 0===t.currency?"":t.currency[1]+"",o=void 0===t.decimal?".":t.decimal+"",s=void 0===t.numerals?aa:function(t){return function(e){return e.replace(/[0-9]/g,(function(e){return t[+e]}))}}(ua.call(t.numerals,String)),c=void 0===t.percent?"%":t.percent+"",u=void 0===t.minus?"−":t.minus+"",l=void 0===t.nan?"NaN":t.nan+"";function h(t){var e=(t=Ji(t)).fill,n=t.align,h=t.sign,f=t.symbol,d=t.zero,p=t.width,g=t.comma,y=t.precision,m=t.trim,v=t.type;"n"===v?(g=!0,v="g"):ia[v]||(void 0===y&&(y=12),m=!0,v="g"),(d||"0"===e&&"="===n)&&(d=!0,e="0",n="=");var b="$"===f?i:"#"===f&&/[boxX]/.test(v)?"0"+v.toLowerCase():"",_="$"===f?a:/[%p]/.test(v)?c:"",x=ia[v],w=/[defgprs%]/.test(v);function k(t){var i,a,c,f=b,k=_;if("c"===v)k=x(t)+k,t="";else{var T=(t=+t)<0||1/t<0;if(t=isNaN(t)?l:x(Math.abs(t),y),m&&(t=function(t){t:for(var e,n=t.length,r=1,i=-1;r0&&(i=0)}return i>0?t.slice(0,i)+t.slice(e+1):t}(t)),T&&0==+t&&"+"!==h&&(T=!1),f=(T?"("===h?h:u:"-"===h||"("===h?"":h)+f,k=("s"===v?la[8+Qi/3]:"")+k+(T&&"("===h?")":""),w)for(i=-1,a=t.length;++i(c=t.charCodeAt(i))||c>57){k=(46===c?o+t.slice(i+1):t.slice(i))+k,t=t.slice(0,i);break}}g&&!d&&(t=r(t,1/0));var C=f.length+t.length+k.length,E=C>1)+f+t+k+E.slice(C);break;default:t=E+f+t+k}return s(t)}return y=void 0===y?6:/[gprs]/.test(v)?Math.max(1,Math.min(21,y)):Math.max(0,Math.min(20,y)),k.toString=function(){return t+""},k}return{format:h,formatPrefix:function(t,e){var n=h(((t=Ji(t)).type="f",t)),r=3*Math.max(-8,Math.min(8,Math.floor(na(e)/3))),i=Math.pow(10,-r),a=la[8+r/3];return function(t){return n(i*t)+a}}}}({thousands:",",grouping:[3],currency:["$",""]}),sa=oa.format,ca=oa.formatPrefix;class da extends Map{constructor(t,e=ga){if(super(),Object.defineProperties(this,{_intern:{value:new Map},_key:{value:e}}),null!=t)for(const[e,n]of t)this.set(e,n)}get(t){return super.get(pa(this,t))}has(t){return super.has(pa(this,t))}set(t,e){return super.set(function({_intern:t,_key:e},n){const r=e(n);return t.has(r)?t.get(r):(t.set(r,n),n)}(this,t),e)}delete(t){return super.delete(function({_intern:t,_key:e},n){const r=e(n);return t.has(r)&&(n=t.get(r),t.delete(r)),n}(this,t))}}function pa({_intern:t,_key:e},n){const r=e(n);return t.has(r)?t.get(r):n}function ga(t){return null!==t&&"object"==typeof t?t.valueOf():t}Set;const ya=Symbol("implicit");function ma(){var t=new da,e=[],n=[],r=ya;function i(i){let a=t.get(i);if(void 0===a){if(r!==ya)return r;t.set(i,a=e.push(i)-1)}return n[a%n.length]}return i.domain=function(n){if(!arguments.length)return e.slice();e=[],t=new da;for(const r of n)t.has(r)||t.set(r,e.push(r)-1);return i},i.range=function(t){return arguments.length?(n=Array.from(t),i):n.slice()},i.unknown=function(t){return arguments.length?(r=t,i):r},i.copy=function(){return ma(e,n).unknown(r)},Zi.apply(i,arguments),i}const va=1e3,ba=6e4,_a=36e5,xa=864e5,wa=6048e5,ka=31536e6;var Ta=new Date,Ca=new Date;function Ea(t,e,n,r){function i(e){return t(e=0===arguments.length?new Date:new Date(+e)),e}return i.floor=function(e){return t(e=new Date(+e)),e},i.ceil=function(n){return t(n=new Date(n-1)),e(n,1),t(n),n},i.round=function(t){var e=i(t),n=i.ceil(t);return t-e0))return s;do{s.push(o=new Date(+n)),e(n,a),t(n)}while(o=e)for(;t(e),!n(e);)e.setTime(e-1)}),(function(t,r){if(t>=t)if(r<0)for(;++r<=0;)for(;e(t,-1),!n(t););else for(;--r>=0;)for(;e(t,1),!n(t););}))},n&&(i.count=function(e,r){return Ta.setTime(+e),Ca.setTime(+r),t(Ta),t(Ca),Math.floor(n(Ta,Ca))},i.every=function(t){return t=Math.floor(t),isFinite(t)&&t>0?t>1?i.filter(r?function(e){return r(e)%t==0}:function(e){return i.count(0,e)%t==0}):i:null}),i}var Sa=Ea((function(){}),(function(t,e){t.setTime(+t+e)}),(function(t,e){return e-t}));Sa.every=function(t){return t=Math.floor(t),isFinite(t)&&t>0?t>1?Ea((function(e){e.setTime(Math.floor(e/t)*t)}),(function(e,n){e.setTime(+e+n*t)}),(function(e,n){return(n-e)/t})):Sa:null};const Aa=Sa;Sa.range;var Ma=Ea((function(t){t.setTime(t-t.getMilliseconds())}),(function(t,e){t.setTime(+t+e*va)}),(function(t,e){return(e-t)/va}),(function(t){return t.getUTCSeconds()}));const Na=Ma;Ma.range;var Da=Ea((function(t){t.setTime(t-t.getMilliseconds()-t.getSeconds()*va)}),(function(t,e){t.setTime(+t+e*ba)}),(function(t,e){return(e-t)/ba}),(function(t){return t.getMinutes()}));const Ba=Da;Da.range;var La=Ea((function(t){t.setTime(t-t.getMilliseconds()-t.getSeconds()*va-t.getMinutes()*ba)}),(function(t,e){t.setTime(+t+e*_a)}),(function(t,e){return(e-t)/_a}),(function(t){return t.getHours()}));const Oa=La;La.range;var Ia=Ea((t=>t.setHours(0,0,0,0)),((t,e)=>t.setDate(t.getDate()+e)),((t,e)=>(e-t-(e.getTimezoneOffset()-t.getTimezoneOffset())*ba)/xa),(t=>t.getDate()-1));const Ra=Ia;function Fa(t){return Ea((function(e){e.setDate(e.getDate()-(e.getDay()+7-t)%7),e.setHours(0,0,0,0)}),(function(t,e){t.setDate(t.getDate()+7*e)}),(function(t,e){return(e-t-(e.getTimezoneOffset()-t.getTimezoneOffset())*ba)/wa}))}Ia.range;var Pa=Fa(0),Ya=Fa(1),ja=Fa(2),Ua=Fa(3),za=Fa(4),$a=Fa(5),qa=Fa(6),Ha=(Pa.range,Ya.range,ja.range,Ua.range,za.range,$a.range,qa.range,Ea((function(t){t.setDate(1),t.setHours(0,0,0,0)}),(function(t,e){t.setMonth(t.getMonth()+e)}),(function(t,e){return e.getMonth()-t.getMonth()+12*(e.getFullYear()-t.getFullYear())}),(function(t){return t.getMonth()})));const Wa=Ha;Ha.range;var Va=Ea((function(t){t.setMonth(0,1),t.setHours(0,0,0,0)}),(function(t,e){t.setFullYear(t.getFullYear()+e)}),(function(t,e){return e.getFullYear()-t.getFullYear()}),(function(t){return t.getFullYear()}));Va.every=function(t){return isFinite(t=Math.floor(t))&&t>0?Ea((function(e){e.setFullYear(Math.floor(e.getFullYear()/t)*t),e.setMonth(0,1),e.setHours(0,0,0,0)}),(function(e,n){e.setFullYear(e.getFullYear()+n*t)})):null};const Ga=Va;Va.range;var Xa=Ea((function(t){t.setUTCSeconds(0,0)}),(function(t,e){t.setTime(+t+e*ba)}),(function(t,e){return(e-t)/ba}),(function(t){return t.getUTCMinutes()}));const Za=Xa;Xa.range;var Qa=Ea((function(t){t.setUTCMinutes(0,0,0)}),(function(t,e){t.setTime(+t+e*_a)}),(function(t,e){return(e-t)/_a}),(function(t){return t.getUTCHours()}));const Ka=Qa;Qa.range;var Ja=Ea((function(t){t.setUTCHours(0,0,0,0)}),(function(t,e){t.setUTCDate(t.getUTCDate()+e)}),(function(t,e){return(e-t)/xa}),(function(t){return t.getUTCDate()-1}));const to=Ja;function eo(t){return Ea((function(e){e.setUTCDate(e.getUTCDate()-(e.getUTCDay()+7-t)%7),e.setUTCHours(0,0,0,0)}),(function(t,e){t.setUTCDate(t.getUTCDate()+7*e)}),(function(t,e){return(e-t)/wa}))}Ja.range;var no=eo(0),ro=eo(1),io=eo(2),ao=eo(3),oo=eo(4),so=eo(5),co=eo(6),uo=(no.range,ro.range,io.range,ao.range,oo.range,so.range,co.range,Ea((function(t){t.setUTCDate(1),t.setUTCHours(0,0,0,0)}),(function(t,e){t.setUTCMonth(t.getUTCMonth()+e)}),(function(t,e){return e.getUTCMonth()-t.getUTCMonth()+12*(e.getUTCFullYear()-t.getUTCFullYear())}),(function(t){return t.getUTCMonth()})));const lo=uo;uo.range;var ho=Ea((function(t){t.setUTCMonth(0,1),t.setUTCHours(0,0,0,0)}),(function(t,e){t.setUTCFullYear(t.getUTCFullYear()+e)}),(function(t,e){return e.getUTCFullYear()-t.getUTCFullYear()}),(function(t){return t.getUTCFullYear()}));ho.every=function(t){return isFinite(t=Math.floor(t))&&t>0?Ea((function(e){e.setUTCFullYear(Math.floor(e.getUTCFullYear()/t)*t),e.setUTCMonth(0,1),e.setUTCHours(0,0,0,0)}),(function(e,n){e.setUTCFullYear(e.getUTCFullYear()+n*t)})):null};const fo=ho;function po(t,e,n,r,i,a){const o=[[Na,1,va],[Na,5,5e3],[Na,15,15e3],[Na,30,3e4],[a,1,ba],[a,5,3e5],[a,15,9e5],[a,30,18e5],[i,1,_a],[i,3,108e5],[i,6,216e5],[i,12,432e5],[r,1,xa],[r,2,1728e5],[n,1,wa],[e,1,2592e6],[e,3,7776e6],[t,1,ka]];function s(e,n,r){const i=Math.abs(n-e)/r,a=Wr((([,,t])=>t)).right(o,i);if(a===o.length)return t.every(qr(e/ka,n/ka,r));if(0===a)return Aa.every(Math.max(qr(e,n,r),1));const[s,c]=o[i/o[a-1][2][t.toLowerCase(),e])))}function Bo(t,e,n){var r=Co.exec(e.slice(n,n+1));return r?(t.w=+r[0],n+r[0].length):-1}function Lo(t,e,n){var r=Co.exec(e.slice(n,n+1));return r?(t.u=+r[0],n+r[0].length):-1}function Oo(t,e,n){var r=Co.exec(e.slice(n,n+2));return r?(t.U=+r[0],n+r[0].length):-1}function Io(t,e,n){var r=Co.exec(e.slice(n,n+2));return r?(t.V=+r[0],n+r[0].length):-1}function Ro(t,e,n){var r=Co.exec(e.slice(n,n+2));return r?(t.W=+r[0],n+r[0].length):-1}function Fo(t,e,n){var r=Co.exec(e.slice(n,n+4));return r?(t.y=+r[0],n+r[0].length):-1}function Po(t,e,n){var r=Co.exec(e.slice(n,n+2));return r?(t.y=+r[0]+(+r[0]>68?1900:2e3),n+r[0].length):-1}function Yo(t,e,n){var r=/^(Z)|([+-]\d\d)(?::?(\d\d))?/.exec(e.slice(n,n+6));return r?(t.Z=r[1]?0:-(r[2]+(r[3]||"00")),n+r[0].length):-1}function jo(t,e,n){var r=Co.exec(e.slice(n,n+1));return r?(t.q=3*r[0]-3,n+r[0].length):-1}function Uo(t,e,n){var r=Co.exec(e.slice(n,n+2));return r?(t.m=r[0]-1,n+r[0].length):-1}function zo(t,e,n){var r=Co.exec(e.slice(n,n+2));return r?(t.d=+r[0],n+r[0].length):-1}function $o(t,e,n){var r=Co.exec(e.slice(n,n+3));return r?(t.m=0,t.d=+r[0],n+r[0].length):-1}function qo(t,e,n){var r=Co.exec(e.slice(n,n+2));return r?(t.H=+r[0],n+r[0].length):-1}function Ho(t,e,n){var r=Co.exec(e.slice(n,n+2));return r?(t.M=+r[0],n+r[0].length):-1}function Wo(t,e,n){var r=Co.exec(e.slice(n,n+2));return r?(t.S=+r[0],n+r[0].length):-1}function Vo(t,e,n){var r=Co.exec(e.slice(n,n+3));return r?(t.L=+r[0],n+r[0].length):-1}function Go(t,e,n){var r=Co.exec(e.slice(n,n+6));return r?(t.L=Math.floor(r[0]/1e3),n+r[0].length):-1}function Xo(t,e,n){var r=Eo.exec(e.slice(n,n+1));return r?n+r[0].length:-1}function Zo(t,e,n){var r=Co.exec(e.slice(n));return r?(t.Q=+r[0],n+r[0].length):-1}function Qo(t,e,n){var r=Co.exec(e.slice(n));return r?(t.s=+r[0],n+r[0].length):-1}function Ko(t,e){return Ao(t.getDate(),e,2)}function Jo(t,e){return Ao(t.getHours(),e,2)}function ts(t,e){return Ao(t.getHours()%12||12,e,2)}function es(t,e){return Ao(1+Ra.count(Ga(t),t),e,3)}function ns(t,e){return Ao(t.getMilliseconds(),e,3)}function rs(t,e){return ns(t,e)+"000"}function is(t,e){return Ao(t.getMonth()+1,e,2)}function as(t,e){return Ao(t.getMinutes(),e,2)}function os(t,e){return Ao(t.getSeconds(),e,2)}function ss(t){var e=t.getDay();return 0===e?7:e}function cs(t,e){return Ao(Pa.count(Ga(t)-1,t),e,2)}function us(t){var e=t.getDay();return e>=4||0===e?za(t):za.ceil(t)}function ls(t,e){return t=us(t),Ao(za.count(Ga(t),t)+(4===Ga(t).getDay()),e,2)}function hs(t){return t.getDay()}function fs(t,e){return Ao(Ya.count(Ga(t)-1,t),e,2)}function ds(t,e){return Ao(t.getFullYear()%100,e,2)}function ps(t,e){return Ao((t=us(t)).getFullYear()%100,e,2)}function gs(t,e){return Ao(t.getFullYear()%1e4,e,4)}function ys(t,e){var n=t.getDay();return Ao((t=n>=4||0===n?za(t):za.ceil(t)).getFullYear()%1e4,e,4)}function ms(t){var e=t.getTimezoneOffset();return(e>0?"-":(e*=-1,"+"))+Ao(e/60|0,"0",2)+Ao(e%60,"0",2)}function vs(t,e){return Ao(t.getUTCDate(),e,2)}function bs(t,e){return Ao(t.getUTCHours(),e,2)}function _s(t,e){return Ao(t.getUTCHours()%12||12,e,2)}function xs(t,e){return Ao(1+to.count(fo(t),t),e,3)}function ws(t,e){return Ao(t.getUTCMilliseconds(),e,3)}function ks(t,e){return ws(t,e)+"000"}function Ts(t,e){return Ao(t.getUTCMonth()+1,e,2)}function Cs(t,e){return Ao(t.getUTCMinutes(),e,2)}function Es(t,e){return Ao(t.getUTCSeconds(),e,2)}function Ss(t){var e=t.getUTCDay();return 0===e?7:e}function As(t,e){return Ao(no.count(fo(t)-1,t),e,2)}function Ms(t){var e=t.getUTCDay();return e>=4||0===e?oo(t):oo.ceil(t)}function Ns(t,e){return t=Ms(t),Ao(oo.count(fo(t),t)+(4===fo(t).getUTCDay()),e,2)}function Ds(t){return t.getUTCDay()}function Bs(t,e){return Ao(ro.count(fo(t)-1,t),e,2)}function Ls(t,e){return Ao(t.getUTCFullYear()%100,e,2)}function Os(t,e){return Ao((t=Ms(t)).getUTCFullYear()%100,e,2)}function Is(t,e){return Ao(t.getUTCFullYear()%1e4,e,4)}function Rs(t,e){var n=t.getUTCDay();return Ao((t=n>=4||0===n?oo(t):oo.ceil(t)).getUTCFullYear()%1e4,e,4)}function Fs(){return"+0000"}function Ps(){return"%"}function Ys(t){return+t}function js(t){return Math.floor(+t/1e3)}function Us(t){return new Date(t)}function zs(t){return t instanceof Date?+t:+new Date(+t)}function $s(t,e,n,r,i,a,o,s,c,u){var l=Xi(),h=l.invert,f=l.domain,d=u(".%L"),p=u(":%S"),g=u("%I:%M"),y=u("%I %p"),m=u("%a %d"),v=u("%b %d"),b=u("%B"),_=u("%Y");function x(t){return(c(t)=12)]},q:function(t){return 1+~~(t.getMonth()/3)},Q:Ys,s:js,S:os,u:ss,U:cs,V:ls,w:hs,W:fs,x:null,X:null,y:ds,Y:gs,Z:ms,"%":Ps},_={a:function(t){return o[t.getUTCDay()]},A:function(t){return a[t.getUTCDay()]},b:function(t){return c[t.getUTCMonth()]},B:function(t){return s[t.getUTCMonth()]},c:null,d:vs,e:vs,f:ks,g:Os,G:Rs,H:bs,I:_s,j:xs,L:ws,m:Ts,M:Cs,p:function(t){return i[+(t.getUTCHours()>=12)]},q:function(t){return 1+~~(t.getUTCMonth()/3)},Q:Ys,s:js,S:Es,u:Ss,U:As,V:Ns,w:Ds,W:Bs,x:null,X:null,y:Ls,Y:Is,Z:Fs,"%":Ps},x={a:function(t,e,n){var r=d.exec(e.slice(n));return r?(t.w=p.get(r[0].toLowerCase()),n+r[0].length):-1},A:function(t,e,n){var r=h.exec(e.slice(n));return r?(t.w=f.get(r[0].toLowerCase()),n+r[0].length):-1},b:function(t,e,n){var r=m.exec(e.slice(n));return r?(t.m=v.get(r[0].toLowerCase()),n+r[0].length):-1},B:function(t,e,n){var r=g.exec(e.slice(n));return r?(t.m=y.get(r[0].toLowerCase()),n+r[0].length):-1},c:function(t,n,r){return T(t,e,n,r)},d:zo,e:zo,f:Go,g:Po,G:Fo,H:qo,I:qo,j:$o,L:Vo,m:Uo,M:Ho,p:function(t,e,n){var r=u.exec(e.slice(n));return r?(t.p=l.get(r[0].toLowerCase()),n+r[0].length):-1},q:jo,Q:Zo,s:Qo,S:Wo,u:Lo,U:Oo,V:Io,w:Bo,W:Ro,x:function(t,e,r){return T(t,n,e,r)},X:function(t,e,n){return T(t,r,e,n)},y:Po,Y:Fo,Z:Yo,"%":Xo};function w(t,e){return function(n){var r,i,a,o=[],s=-1,c=0,u=t.length;for(n instanceof Date||(n=new Date(+n));++s53)return null;"w"in a||(a.w=1),"Z"in a?(i=(r=_o(xo(a.y,0,1))).getUTCDay(),r=i>4||0===i?ro.ceil(r):ro(r),r=to.offset(r,7*(a.V-1)),a.y=r.getUTCFullYear(),a.m=r.getUTCMonth(),a.d=r.getUTCDate()+(a.w+6)%7):(i=(r=bo(xo(a.y,0,1))).getDay(),r=i>4||0===i?Ya.ceil(r):Ya(r),r=Ra.offset(r,7*(a.V-1)),a.y=r.getFullYear(),a.m=r.getMonth(),a.d=r.getDate()+(a.w+6)%7)}else("W"in a||"U"in a)&&("w"in a||(a.w="u"in a?a.u%7:"W"in a?1:0),i="Z"in a?_o(xo(a.y,0,1)).getUTCDay():bo(xo(a.y,0,1)).getDay(),a.m=0,a.d="W"in a?(a.w+6)%7+7*a.W-(i+5)%7:a.w+7*a.U-(i+6)%7);return"Z"in a?(a.H+=a.Z/100|0,a.M+=a.Z%100,_o(a)):bo(a)}}function T(t,e,n,r){for(var i,a,o=0,s=e.length,c=n.length;o=c)return-1;if(37===(i=e.charCodeAt(o++))){if(i=e.charAt(o++),!(a=x[i in To?e.charAt(o++):i])||(r=a(t,n,r))<0)return-1}else if(i!=n.charCodeAt(r++))return-1}return r}return b.x=w(n,b),b.X=w(r,b),b.c=w(e,b),_.x=w(n,_),_.X=w(r,_),_.c=w(e,_),{format:function(t){var e=w(t+="",b);return e.toString=function(){return t},e},parse:function(t){var e=k(t+="",!1);return e.toString=function(){return t},e},utcFormat:function(t){var e=w(t+="",_);return e.toString=function(){return t},e},utcParse:function(t){var e=k(t+="",!0);return e.toString=function(){return t},e}}}({dateTime:"%x, %X",date:"%-m/%-d/%Y",time:"%-I:%M:%S %p",periods:["AM","PM"],days:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],shortDays:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],months:["January","February","March","April","May","June","July","August","September","October","November","December"],shortMonths:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"]}),ko=wo.format,wo.parse,wo.utcFormat,wo.utcParse;var Qs=Array.prototype.find;function Ks(){return this.firstElementChild}var Js=Array.prototype.filter;function tc(){return Array.from(this.children)}function ec(t){return new Array(t.length)}function nc(t,e){this.ownerDocument=t.ownerDocument,this.namespaceURI=t.namespaceURI,this._next=null,this._parent=t,this.__data__=e}function rc(t){return function(){return t}}function ic(t,e,n,r,i,a){for(var o,s=0,c=e.length,u=a.length;se?1:t>=e?0:NaN}nc.prototype={constructor:nc,appendChild:function(t){return this._parent.insertBefore(t,this._next)},insertBefore:function(t,e){return this._parent.insertBefore(t,e)},querySelector:function(t){return this._parent.querySelector(t)},querySelectorAll:function(t){return this._parent.querySelectorAll(t)}};var uc="http://www.w3.org/1999/xhtml";const lc={svg:"http://www.w3.org/2000/svg",xhtml:uc,xlink:"http://www.w3.org/1999/xlink",xml:"http://www.w3.org/XML/1998/namespace",xmlns:"http://www.w3.org/2000/xmlns/"};function hc(t){var e=t+="",n=e.indexOf(":");return n>=0&&"xmlns"!==(e=t.slice(0,n))&&(t=t.slice(n+1)),lc.hasOwnProperty(e)?{space:lc[e],local:t}:t}function fc(t){return function(){this.removeAttribute(t)}}function dc(t){return function(){this.removeAttributeNS(t.space,t.local)}}function pc(t,e){return function(){this.setAttribute(t,e)}}function gc(t,e){return function(){this.setAttributeNS(t.space,t.local,e)}}function yc(t,e){return function(){var n=e.apply(this,arguments);null==n?this.removeAttribute(t):this.setAttribute(t,n)}}function mc(t,e){return function(){var n=e.apply(this,arguments);null==n?this.removeAttributeNS(t.space,t.local):this.setAttributeNS(t.space,t.local,n)}}function vc(t){return t.ownerDocument&&t.ownerDocument.defaultView||t.document&&t||t.defaultView}function bc(t){return function(){this.style.removeProperty(t)}}function _c(t,e,n){return function(){this.style.setProperty(t,e,n)}}function xc(t,e,n){return function(){var r=e.apply(this,arguments);null==r?this.style.removeProperty(t):this.style.setProperty(t,r,n)}}function wc(t,e){return t.style.getPropertyValue(e)||vc(t).getComputedStyle(t,null).getPropertyValue(e)}function kc(t){return function(){delete this[t]}}function Tc(t,e){return function(){this[t]=e}}function Cc(t,e){return function(){var n=e.apply(this,arguments);null==n?delete this[t]:this[t]=n}}function Ec(t){return t.trim().split(/^|\s+/)}function Sc(t){return t.classList||new Ac(t)}function Ac(t){this._node=t,this._names=Ec(t.getAttribute("class")||"")}function Mc(t,e){for(var n=Sc(t),r=-1,i=e.length;++r=0&&(e=t.slice(n+1),t=t.slice(0,n)),{type:t,name:e}}))}function Zc(t){return function(){var e=this.__on;if(e){for(var n,r=0,i=-1,a=e.length;r=0&&(this._names.splice(e,1),this._node.setAttribute("class",this._names.join(" ")))},contains:function(t){return this._names.indexOf(t)>=0}};var eu=[null];function nu(t,e){this._groups=t,this._parents=e}function ru(){return new nu([[document.documentElement]],eu)}nu.prototype=ru.prototype={constructor:nu,select:function(t){"function"!=typeof t&&(t=Hs(t));for(var e=this._groups,n=e.length,r=new Array(n),i=0;i=x&&(x=_+1);!(b=y[x])&&++x=0;)(r=i[a])&&(o&&4^r.compareDocumentPosition(o)&&o.parentNode.insertBefore(r,o),o=r);return this},sort:function(t){function e(e,n){return e&&n?t(e.__data__,n.__data__):!e-!n}t||(t=cc);for(var n=this._groups,r=n.length,i=new Array(r),a=0;a1?this.each((null==e?bc:"function"==typeof e?xc:_c)(t,e,null==n?"":n)):wc(this.node(),t)},property:function(t,e){return arguments.length>1?this.each((null==e?kc:"function"==typeof e?Cc:Tc)(t,e)):this.node()[t]},classed:function(t,e){var n=Ec(t+"");if(arguments.length<2){for(var r=Sc(this.node()),i=-1,a=n.length;++iuu)if(Math.abs(l*s-c*u)>uu&&i){var f=n-a,d=r-o,p=s*s+c*c,g=f*f+d*d,y=Math.sqrt(p),m=Math.sqrt(h),v=i*Math.tan((su-Math.acos((p+h-g)/(2*y*m)))/2),b=v/m,_=v/y;Math.abs(b-1)>uu&&(this._+="L"+(t+b*u)+","+(e+b*l)),this._+="A"+i+","+i+",0,0,"+ +(l*f>u*d)+","+(this._x1=t+_*s)+","+(this._y1=e+_*c)}else this._+="L"+(this._x1=t)+","+(this._y1=e)},arc:function(t,e,n,r,i,a){t=+t,e=+e,a=!!a;var o=(n=+n)*Math.cos(r),s=n*Math.sin(r),c=t+o,u=e+s,l=1^a,h=a?r-i:i-r;if(n<0)throw new Error("negative radius: "+n);null===this._x1?this._+="M"+c+","+u:(Math.abs(this._x1-c)>uu||Math.abs(this._y1-u)>uu)&&(this._+="L"+c+","+u),n&&(h<0&&(h=h%cu+cu),h>lu?this._+="A"+n+","+n+",0,1,"+l+","+(t-o)+","+(e-s)+"A"+n+","+n+",0,1,"+l+","+(this._x1=c)+","+(this._y1=u):h>uu&&(this._+="A"+n+","+n+",0,"+ +(h>=su)+","+l+","+(this._x1=t+n*Math.cos(i))+","+(this._y1=e+n*Math.sin(i))))},rect:function(t,e,n,r){this._+="M"+(this._x0=this._x1=+t)+","+(this._y0=this._y1=+e)+"h"+ +n+"v"+ +r+"h"+-n+"Z"},toString:function(){return this._}};const du=fu;function pu(t){return function(){return t}}var gu=Math.abs,yu=Math.atan2,mu=Math.cos,vu=Math.max,bu=Math.min,_u=Math.sin,xu=Math.sqrt,wu=1e-12,ku=Math.PI,Tu=ku/2,Cu=2*ku;function Eu(t){return t>1?0:t<-1?ku:Math.acos(t)}function Su(t){return t>=1?Tu:t<=-1?-Tu:Math.asin(t)}function Au(t){return t.innerRadius}function Mu(t){return t.outerRadius}function Nu(t){return t.startAngle}function Du(t){return t.endAngle}function Bu(t){return t&&t.padAngle}function Lu(t,e,n,r,i,a,o,s){var c=n-t,u=r-e,l=o-i,h=s-a,f=h*c-l*u;if(!(f*fN*N+D*D&&(T=E,C=S),{cx:T,cy:C,x01:-l,y01:-h,x11:T*(i/x-1),y11:C*(i/x-1)}}function Iu(){var t=Au,e=Mu,n=pu(0),r=null,i=Nu,a=Du,o=Bu,s=null;function c(){var c,u,l=+t.apply(this,arguments),h=+e.apply(this,arguments),f=i.apply(this,arguments)-Tu,d=a.apply(this,arguments)-Tu,p=gu(d-f),g=d>f;if(s||(s=c=du()),hwu)if(p>Cu-wu)s.moveTo(h*mu(f),h*_u(f)),s.arc(0,0,h,f,d,!g),l>wu&&(s.moveTo(l*mu(d),l*_u(d)),s.arc(0,0,l,d,f,g));else{var y,m,v=f,b=d,_=f,x=d,w=p,k=p,T=o.apply(this,arguments)/2,C=T>wu&&(r?+r.apply(this,arguments):xu(l*l+h*h)),E=bu(gu(h-l)/2,+n.apply(this,arguments)),S=E,A=E;if(C>wu){var M=Su(C/l*_u(T)),N=Su(C/h*_u(T));(w-=2*M)>wu?(_+=M*=g?1:-1,x-=M):(w=0,_=x=(f+d)/2),(k-=2*N)>wu?(v+=N*=g?1:-1,b-=N):(k=0,v=b=(f+d)/2)}var D=h*mu(v),B=h*_u(v),L=l*mu(x),O=l*_u(x);if(E>wu){var I,R=h*mu(b),F=h*_u(b),P=l*mu(_),Y=l*_u(_);if(pwu?A>wu?(y=Ou(P,Y,D,B,h,A,g),m=Ou(R,F,L,O,h,A,g),s.moveTo(y.cx+y.x01,y.cy+y.y01),Awu&&w>wu?S>wu?(y=Ou(L,O,R,F,l,-S,g),m=Ou(D,B,P,Y,l,-S,g),s.lineTo(y.cx+y.x01,y.cy+y.y01),St?1:e>=t?0:NaN}function $u(t){return t}function qu(){}function Hu(t,e,n){t._context.bezierCurveTo((2*t._x0+t._x1)/3,(2*t._y0+t._y1)/3,(t._x0+2*t._x1)/3,(t._y0+2*t._y1)/3,(t._x0+4*t._x1+e)/6,(t._y0+4*t._y1+n)/6)}function Wu(t){this._context=t}function Vu(t){return new Wu(t)}function Gu(t){this._context=t}function Xu(t){this._context=t}function Zu(t){this._context=t}function Qu(t){return t<0?-1:1}function Ku(t,e,n){var r=t._x1-t._x0,i=e-t._x1,a=(t._y1-t._y0)/(r||i<0&&-0),o=(n-t._y1)/(i||r<0&&-0),s=(a*i+o*r)/(r+i);return(Qu(a)+Qu(o))*Math.min(Math.abs(a),Math.abs(o),.5*Math.abs(s))||0}function Ju(t,e){var n=t._x1-t._x0;return n?(3*(t._y1-t._y0)/n-e)/2:e}function tl(t,e,n){var r=t._x0,i=t._y0,a=t._x1,o=t._y1,s=(a-r)/3;t._context.bezierCurveTo(r+s,i+s*e,a-s,o-s*n,a,o)}function el(t){this._context=t}function nl(t){this._context=new rl(t)}function rl(t){this._context=t}function il(t){this._context=t}function al(t){var e,n,r=t.length-1,i=new Array(r),a=new Array(r),o=new Array(r);for(i[0]=0,a[0]=2,o[0]=t[0]+2*t[1],e=1;e=0;--e)i[e]=(o[e]-i[e+1])/a[e];for(a[r-1]=(t[r]+i[r-1])/2,e=0;e=0&&(this._t=1-this._t,this._line=1-this._line)},point:function(t,e){switch(t=+t,e=+e,this._point){case 0:this._point=1,this._line?this._context.lineTo(t,e):this._context.moveTo(t,e);break;case 1:this._point=2;default:if(this._t<=0)this._context.lineTo(this._x,e),this._context.lineTo(t,e);else{var n=this._x*(1-this._t)+t*this._t;this._context.lineTo(n,this._y),this._context.lineTo(n,e)}}this._x=t,this._y=e}};var sl=new Date,cl=new Date;function ul(t,e,n,r){function i(e){return t(e=0===arguments.length?new Date:new Date(+e)),e}return i.floor=function(e){return t(e=new Date(+e)),e},i.ceil=function(n){return t(n=new Date(n-1)),e(n,1),t(n),n},i.round=function(t){var e=i(t),n=i.ceil(t);return t-e0))return s;do{s.push(o=new Date(+n)),e(n,a),t(n)}while(o=e)for(;t(e),!n(e);)e.setTime(e-1)}),(function(t,r){if(t>=t)if(r<0)for(;++r<=0;)for(;e(t,-1),!n(t););else for(;--r>=0;)for(;e(t,1),!n(t););}))},n&&(i.count=function(e,r){return sl.setTime(+e),cl.setTime(+r),t(sl),t(cl),Math.floor(n(sl,cl))},i.every=function(t){return t=Math.floor(t),isFinite(t)&&t>0?t>1?i.filter(r?function(e){return r(e)%t==0}:function(e){return i.count(0,e)%t==0}):i:null}),i}const ll=864e5,hl=6048e5;function fl(t){return ul((function(e){e.setUTCDate(e.getUTCDate()-(e.getUTCDay()+7-t)%7),e.setUTCHours(0,0,0,0)}),(function(t,e){t.setUTCDate(t.getUTCDate()+7*e)}),(function(t,e){return(e-t)/hl}))}var dl=fl(0),pl=fl(1),gl=fl(2),yl=fl(3),ml=fl(4),vl=fl(5),bl=fl(6),_l=(dl.range,pl.range,gl.range,yl.range,ml.range,vl.range,bl.range,ul((function(t){t.setUTCHours(0,0,0,0)}),(function(t,e){t.setUTCDate(t.getUTCDate()+e)}),(function(t,e){return(e-t)/ll}),(function(t){return t.getUTCDate()-1})));const xl=_l;function wl(t){return ul((function(e){e.setDate(e.getDate()-(e.getDay()+7-t)%7),e.setHours(0,0,0,0)}),(function(t,e){t.setDate(t.getDate()+7*e)}),(function(t,e){return(e-t-6e4*(e.getTimezoneOffset()-t.getTimezoneOffset()))/hl}))}_l.range;var kl=wl(0),Tl=wl(1),Cl=wl(2),El=wl(3),Sl=wl(4),Al=wl(5),Ml=wl(6),Nl=(kl.range,Tl.range,Cl.range,El.range,Sl.range,Al.range,Ml.range,ul((t=>t.setHours(0,0,0,0)),((t,e)=>t.setDate(t.getDate()+e)),((t,e)=>(e-t-6e4*(e.getTimezoneOffset()-t.getTimezoneOffset()))/ll),(t=>t.getDate()-1)));const Dl=Nl;Nl.range;var Bl=ul((function(t){t.setMonth(0,1),t.setHours(0,0,0,0)}),(function(t,e){t.setFullYear(t.getFullYear()+e)}),(function(t,e){return e.getFullYear()-t.getFullYear()}),(function(t){return t.getFullYear()}));Bl.every=function(t){return isFinite(t=Math.floor(t))&&t>0?ul((function(e){e.setFullYear(Math.floor(e.getFullYear()/t)*t),e.setMonth(0,1),e.setHours(0,0,0,0)}),(function(e,n){e.setFullYear(e.getFullYear()+n*t)})):null};const Ll=Bl;Bl.range;var Ol=ul((function(t){t.setUTCMonth(0,1),t.setUTCHours(0,0,0,0)}),(function(t,e){t.setUTCFullYear(t.getUTCFullYear()+e)}),(function(t,e){return e.getUTCFullYear()-t.getUTCFullYear()}),(function(t){return t.getUTCFullYear()}));Ol.every=function(t){return isFinite(t=Math.floor(t))&&t>0?ul((function(e){e.setUTCFullYear(Math.floor(e.getUTCFullYear()/t)*t),e.setUTCMonth(0,1),e.setUTCHours(0,0,0,0)}),(function(e,n){e.setUTCFullYear(e.getUTCFullYear()+n*t)})):null};const Il=Ol;function Rl(t){if(0<=t.y&&t.y<100){var e=new Date(-1,t.m,t.d,t.H,t.M,t.S,t.L);return e.setFullYear(t.y),e}return new Date(t.y,t.m,t.d,t.H,t.M,t.S,t.L)}function Fl(t){if(0<=t.y&&t.y<100){var e=new Date(Date.UTC(-1,t.m,t.d,t.H,t.M,t.S,t.L));return e.setUTCFullYear(t.y),e}return new Date(Date.UTC(t.y,t.m,t.d,t.H,t.M,t.S,t.L))}function Pl(t,e,n){return{y:t,m:e,d:n,H:0,M:0,S:0,L:0}}Ol.range;var Yl,jl,Ul={"-":"",_:" ",0:"0"},zl=/^\s*\d+/,$l=/^%/,ql=/[\\^$*+?|[\]().{}]/g;function Hl(t,e,n){var r=t<0?"-":"",i=(r?-t:t)+"",a=i.length;return r+(a[t.toLowerCase(),e])))}function Xl(t,e,n){var r=zl.exec(e.slice(n,n+1));return r?(t.w=+r[0],n+r[0].length):-1}function Zl(t,e,n){var r=zl.exec(e.slice(n,n+1));return r?(t.u=+r[0],n+r[0].length):-1}function Ql(t,e,n){var r=zl.exec(e.slice(n,n+2));return r?(t.U=+r[0],n+r[0].length):-1}function Kl(t,e,n){var r=zl.exec(e.slice(n,n+2));return r?(t.V=+r[0],n+r[0].length):-1}function Jl(t,e,n){var r=zl.exec(e.slice(n,n+2));return r?(t.W=+r[0],n+r[0].length):-1}function th(t,e,n){var r=zl.exec(e.slice(n,n+4));return r?(t.y=+r[0],n+r[0].length):-1}function eh(t,e,n){var r=zl.exec(e.slice(n,n+2));return r?(t.y=+r[0]+(+r[0]>68?1900:2e3),n+r[0].length):-1}function nh(t,e,n){var r=/^(Z)|([+-]\d\d)(?::?(\d\d))?/.exec(e.slice(n,n+6));return r?(t.Z=r[1]?0:-(r[2]+(r[3]||"00")),n+r[0].length):-1}function rh(t,e,n){var r=zl.exec(e.slice(n,n+1));return r?(t.q=3*r[0]-3,n+r[0].length):-1}function ih(t,e,n){var r=zl.exec(e.slice(n,n+2));return r?(t.m=r[0]-1,n+r[0].length):-1}function ah(t,e,n){var r=zl.exec(e.slice(n,n+2));return r?(t.d=+r[0],n+r[0].length):-1}function oh(t,e,n){var r=zl.exec(e.slice(n,n+3));return r?(t.m=0,t.d=+r[0],n+r[0].length):-1}function sh(t,e,n){var r=zl.exec(e.slice(n,n+2));return r?(t.H=+r[0],n+r[0].length):-1}function ch(t,e,n){var r=zl.exec(e.slice(n,n+2));return r?(t.M=+r[0],n+r[0].length):-1}function uh(t,e,n){var r=zl.exec(e.slice(n,n+2));return r?(t.S=+r[0],n+r[0].length):-1}function lh(t,e,n){var r=zl.exec(e.slice(n,n+3));return r?(t.L=+r[0],n+r[0].length):-1}function hh(t,e,n){var r=zl.exec(e.slice(n,n+6));return r?(t.L=Math.floor(r[0]/1e3),n+r[0].length):-1}function fh(t,e,n){var r=$l.exec(e.slice(n,n+1));return r?n+r[0].length:-1}function dh(t,e,n){var r=zl.exec(e.slice(n));return r?(t.Q=+r[0],n+r[0].length):-1}function ph(t,e,n){var r=zl.exec(e.slice(n));return r?(t.s=+r[0],n+r[0].length):-1}function gh(t,e){return Hl(t.getDate(),e,2)}function yh(t,e){return Hl(t.getHours(),e,2)}function mh(t,e){return Hl(t.getHours()%12||12,e,2)}function vh(t,e){return Hl(1+Dl.count(Ll(t),t),e,3)}function bh(t,e){return Hl(t.getMilliseconds(),e,3)}function _h(t,e){return bh(t,e)+"000"}function xh(t,e){return Hl(t.getMonth()+1,e,2)}function wh(t,e){return Hl(t.getMinutes(),e,2)}function kh(t,e){return Hl(t.getSeconds(),e,2)}function Th(t){var e=t.getDay();return 0===e?7:e}function Ch(t,e){return Hl(kl.count(Ll(t)-1,t),e,2)}function Eh(t){var e=t.getDay();return e>=4||0===e?Sl(t):Sl.ceil(t)}function Sh(t,e){return t=Eh(t),Hl(Sl.count(Ll(t),t)+(4===Ll(t).getDay()),e,2)}function Ah(t){return t.getDay()}function Mh(t,e){return Hl(Tl.count(Ll(t)-1,t),e,2)}function Nh(t,e){return Hl(t.getFullYear()%100,e,2)}function Dh(t,e){return Hl((t=Eh(t)).getFullYear()%100,e,2)}function Bh(t,e){return Hl(t.getFullYear()%1e4,e,4)}function Lh(t,e){var n=t.getDay();return Hl((t=n>=4||0===n?Sl(t):Sl.ceil(t)).getFullYear()%1e4,e,4)}function Oh(t){var e=t.getTimezoneOffset();return(e>0?"-":(e*=-1,"+"))+Hl(e/60|0,"0",2)+Hl(e%60,"0",2)}function Ih(t,e){return Hl(t.getUTCDate(),e,2)}function Rh(t,e){return Hl(t.getUTCHours(),e,2)}function Fh(t,e){return Hl(t.getUTCHours()%12||12,e,2)}function Ph(t,e){return Hl(1+xl.count(Il(t),t),e,3)}function Yh(t,e){return Hl(t.getUTCMilliseconds(),e,3)}function jh(t,e){return Yh(t,e)+"000"}function Uh(t,e){return Hl(t.getUTCMonth()+1,e,2)}function zh(t,e){return Hl(t.getUTCMinutes(),e,2)}function $h(t,e){return Hl(t.getUTCSeconds(),e,2)}function qh(t){var e=t.getUTCDay();return 0===e?7:e}function Hh(t,e){return Hl(dl.count(Il(t)-1,t),e,2)}function Wh(t){var e=t.getUTCDay();return e>=4||0===e?ml(t):ml.ceil(t)}function Vh(t,e){return t=Wh(t),Hl(ml.count(Il(t),t)+(4===Il(t).getUTCDay()),e,2)}function Gh(t){return t.getUTCDay()}function Xh(t,e){return Hl(pl.count(Il(t)-1,t),e,2)}function Zh(t,e){return Hl(t.getUTCFullYear()%100,e,2)}function Qh(t,e){return Hl((t=Wh(t)).getUTCFullYear()%100,e,2)}function Kh(t,e){return Hl(t.getUTCFullYear()%1e4,e,4)}function Jh(t,e){var n=t.getUTCDay();return Hl((t=n>=4||0===n?ml(t):ml.ceil(t)).getUTCFullYear()%1e4,e,4)}function tf(){return"+0000"}function ef(){return"%"}function nf(t){return+t}function rf(t){return Math.floor(+t/1e3)}Yl=function(t){var e=t.dateTime,n=t.date,r=t.time,i=t.periods,a=t.days,o=t.shortDays,s=t.months,c=t.shortMonths,u=Vl(i),l=Gl(i),h=Vl(a),f=Gl(a),d=Vl(o),p=Gl(o),g=Vl(s),y=Gl(s),m=Vl(c),v=Gl(c),b={a:function(t){return o[t.getDay()]},A:function(t){return a[t.getDay()]},b:function(t){return c[t.getMonth()]},B:function(t){return s[t.getMonth()]},c:null,d:gh,e:gh,f:_h,g:Dh,G:Lh,H:yh,I:mh,j:vh,L:bh,m:xh,M:wh,p:function(t){return i[+(t.getHours()>=12)]},q:function(t){return 1+~~(t.getMonth()/3)},Q:nf,s:rf,S:kh,u:Th,U:Ch,V:Sh,w:Ah,W:Mh,x:null,X:null,y:Nh,Y:Bh,Z:Oh,"%":ef},_={a:function(t){return o[t.getUTCDay()]},A:function(t){return a[t.getUTCDay()]},b:function(t){return c[t.getUTCMonth()]},B:function(t){return s[t.getUTCMonth()]},c:null,d:Ih,e:Ih,f:jh,g:Qh,G:Jh,H:Rh,I:Fh,j:Ph,L:Yh,m:Uh,M:zh,p:function(t){return i[+(t.getUTCHours()>=12)]},q:function(t){return 1+~~(t.getUTCMonth()/3)},Q:nf,s:rf,S:$h,u:qh,U:Hh,V:Vh,w:Gh,W:Xh,x:null,X:null,y:Zh,Y:Kh,Z:tf,"%":ef},x={a:function(t,e,n){var r=d.exec(e.slice(n));return r?(t.w=p.get(r[0].toLowerCase()),n+r[0].length):-1},A:function(t,e,n){var r=h.exec(e.slice(n));return r?(t.w=f.get(r[0].toLowerCase()),n+r[0].length):-1},b:function(t,e,n){var r=m.exec(e.slice(n));return r?(t.m=v.get(r[0].toLowerCase()),n+r[0].length):-1},B:function(t,e,n){var r=g.exec(e.slice(n));return r?(t.m=y.get(r[0].toLowerCase()),n+r[0].length):-1},c:function(t,n,r){return T(t,e,n,r)},d:ah,e:ah,f:hh,g:eh,G:th,H:sh,I:sh,j:oh,L:lh,m:ih,M:ch,p:function(t,e,n){var r=u.exec(e.slice(n));return r?(t.p=l.get(r[0].toLowerCase()),n+r[0].length):-1},q:rh,Q:dh,s:ph,S:uh,u:Zl,U:Ql,V:Kl,w:Xl,W:Jl,x:function(t,e,r){return T(t,n,e,r)},X:function(t,e,n){return T(t,r,e,n)},y:eh,Y:th,Z:nh,"%":fh};function w(t,e){return function(n){var r,i,a,o=[],s=-1,c=0,u=t.length;for(n instanceof Date||(n=new Date(+n));++s53)return null;"w"in a||(a.w=1),"Z"in a?(i=(r=Fl(Pl(a.y,0,1))).getUTCDay(),r=i>4||0===i?pl.ceil(r):pl(r),r=xl.offset(r,7*(a.V-1)),a.y=r.getUTCFullYear(),a.m=r.getUTCMonth(),a.d=r.getUTCDate()+(a.w+6)%7):(i=(r=Rl(Pl(a.y,0,1))).getDay(),r=i>4||0===i?Tl.ceil(r):Tl(r),r=Dl.offset(r,7*(a.V-1)),a.y=r.getFullYear(),a.m=r.getMonth(),a.d=r.getDate()+(a.w+6)%7)}else("W"in a||"U"in a)&&("w"in a||(a.w="u"in a?a.u%7:"W"in a?1:0),i="Z"in a?Fl(Pl(a.y,0,1)).getUTCDay():Rl(Pl(a.y,0,1)).getDay(),a.m=0,a.d="W"in a?(a.w+6)%7+7*a.W-(i+5)%7:a.w+7*a.U-(i+6)%7);return"Z"in a?(a.H+=a.Z/100|0,a.M+=a.Z%100,Fl(a)):Rl(a)}}function T(t,e,n,r){for(var i,a,o=0,s=e.length,c=n.length;o=c)return-1;if(37===(i=e.charCodeAt(o++))){if(i=e.charAt(o++),!(a=x[i in Ul?e.charAt(o++):i])||(r=a(t,n,r))<0)return-1}else if(i!=n.charCodeAt(r++))return-1}return r}return b.x=w(n,b),b.X=w(r,b),b.c=w(e,b),_.x=w(n,_),_.X=w(r,_),_.c=w(e,_),{format:function(t){var e=w(t+="",b);return e.toString=function(){return t},e},parse:function(t){var e=k(t+="",!1);return e.toString=function(){return t},e},utcFormat:function(t){var e=w(t+="",_);return e.toString=function(){return t},e},utcParse:function(t){var e=k(t+="",!0);return e.toString=function(){return t},e}}}({dateTime:"%x, %X",date:"%-m/%-d/%Y",time:"%-I:%M:%S %p",periods:["AM","PM"],days:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],shortDays:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],months:["January","February","March","April","May","June","July","August","September","October","November","December"],shortMonths:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"]}),jl=Yl.format,Yl.parse,Yl.utcFormat,Yl.utcParse;var af={value:()=>{}};function of(){for(var t,e=0,n=arguments.length,r={};e=0&&(n=t.slice(r+1),t=t.slice(0,r)),t&&!e.hasOwnProperty(t))throw new Error("unknown type: "+t);return{type:t,name:n}}))}function uf(t,e){for(var n,r=0,i=t.length;r0)for(var n,r,i=new Array(n),a=0;a=0&&e._call.call(void 0,t),e=e._next;--pf}()}finally{pf=0,function(){for(var t,e,n=ff,r=1/0;n;)n._call?(r>n._time&&(r=n._time),t=n,n=n._next):(e=n._next,n._next=null,n=t?t._next=e:ff=e);df=t,Af(r)}(),vf=0}}function Sf(){var t=_f.now(),e=t-mf;e>1e3&&(bf-=e,mf=t)}function Af(t){pf||(gf&&(gf=clearTimeout(gf)),t-vf>24?(t<1/0&&(gf=setTimeout(Ef,t-_f.now()-bf)),yf&&(yf=clearInterval(yf))):(yf||(mf=_f.now(),yf=setInterval(Sf,1e3)),pf=1,xf(Ef)))}function Mf(t,e,n){var r=new Tf;return e=null==e?0:+e,r.restart((n=>{r.stop(),t(n+e)}),e,n),r}Tf.prototype=Cf.prototype={constructor:Tf,restart:function(t,e,n){if("function"!=typeof t)throw new TypeError("callback is not a function");n=(null==n?wf():+n)+(null==e?0:+e),this._next||df===this||(df?df._next=this:ff=this,df=this),this._call=t,this._time=n,Af()},stop:function(){this._call&&(this._call=null,this._time=1/0,Af())}};var Nf=hf("start","end","cancel","interrupt"),Df=[];function Bf(t,e,n,r,i,a){var o=t.__transition;if(o){if(n in o)return}else t.__transition={};!function(t,e,n){var r,i=t.__transition;function a(c){var u,l,h,f;if(1!==n.state)return s();for(u in i)if((f=i[u]).name===n.name){if(3===f.state)return Mf(a);4===f.state?(f.state=6,f.timer.stop(),f.on.call("interrupt",t,t.__data__,f.index,f.group),delete i[u]):+u0)throw new Error("too late; already scheduled");return n}function Of(t,e){var n=If(t,e);if(n.state>3)throw new Error("too late; already running");return n}function If(t,e){var n=t.__transition;if(!n||!(n=n[e]))throw new Error("transition not found");return n}function Rf(t,e){return t=+t,e=+e,function(n){return t*(1-n)+e*n}}var Ff,Pf=180/Math.PI,Yf={translateX:0,translateY:0,rotate:0,skewX:0,scaleX:1,scaleY:1};function jf(t,e,n,r,i,a){var o,s,c;return(o=Math.sqrt(t*t+e*e))&&(t/=o,e/=o),(c=t*n+e*r)&&(n-=t*c,r-=e*c),(s=Math.sqrt(n*n+r*r))&&(n/=s,r/=s,c/=s),t*r180?e+=360:e-t>180&&(t+=360),a.push({i:n.push(i(n)+"rotate(",null,r)-2,x:Rf(t,e)})):e&&n.push(i(n)+"rotate("+e+r)}(a.rotate,o.rotate,s,c),function(t,e,n,a){t!==e?a.push({i:n.push(i(n)+"skewX(",null,r)-2,x:Rf(t,e)}):e&&n.push(i(n)+"skewX("+e+r)}(a.skewX,o.skewX,s,c),function(t,e,n,r,a,o){if(t!==n||e!==r){var s=a.push(i(a)+"scale(",null,",",null,")");o.push({i:s-4,x:Rf(t,n)},{i:s-2,x:Rf(e,r)})}else 1===n&&1===r||a.push(i(a)+"scale("+n+","+r+")")}(a.scaleX,a.scaleY,o.scaleX,o.scaleY,s,c),a=o=null,function(t){for(var e,n=-1,r=c.length;++n=1?(n=1,e-1):Math.floor(n*e),i=t[r],a=t[r+1],o=r>0?t[r-1]:2*i-a,s=ra&&(i=e.slice(a,i),s[o]?s[o]+=i:s[++o]=i),(n=n[0])===(r=r[0])?s[o]?s[o]+=r:s[++o]=r:(s[++o]=null,c.push({i:o,x:Rf(n,r)})),a=Qf.lastIndex;return a=0&&(t=t.slice(0,e)),!t||"start"===t}))}(e)?Lf:Of;return function(){var o=a(this,t),s=o.on;s!==r&&(i=(r=s).copy()).on(e,n),o.on=i}}var yd=iu.prototype.constructor;function md(t){return function(){this.style.removeProperty(t)}}function vd(t,e,n){return function(r){this.style.setProperty(t,e.call(this,r),n)}}function bd(t,e,n){var r,i;function a(){var a=e.apply(this,arguments);return a!==i&&(r=(i=a)&&vd(t,a,n)),r}return a._value=e,a}function _d(t){return function(e){this.textContent=t.call(this,e)}}function xd(t){var e,n;function r(){var r=t.apply(this,arguments);return r!==n&&(e=(n=r)&&_d(r)),e}return r._value=t,r}var wd=0;function kd(t,e,n,r){this._groups=t,this._parents=e,this._name=n,this._id=r}function Td(){return++wd}var Cd=iu.prototype;kd.prototype=function(t){return iu().transition(t)}.prototype={constructor:kd,select:function(t){var e=this._name,n=this._id;"function"!=typeof t&&(t=Hs(t));for(var r=this._groups,i=r.length,a=new Array(i),o=0;o2&&n.state<5,n.state=6,n.timer.stop(),n.on.call(r?"interrupt":"cancel",t,t.__data__,n.index,n.group),delete a[i]):o=!1;o&&delete t.__transition}}(this,t)}))},iu.prototype.transition=function(t){var e,n;t instanceof kd?(e=t._id,t=t._name):(e=Td(),(n=Ed).time=wf(),t=null==t?null:t+"");for(var r=this._groups,i=r.length,a=0;ae?1:t>=e?0:NaN}jd.prototype={constructor:jd,appendChild:function(t){return this._parent.insertBefore(t,this._next)},insertBefore:function(t,e){return this._parent.insertBefore(t,e)},querySelector:function(t){return this._parent.querySelector(t)},querySelectorAll:function(t){return this._parent.querySelectorAll(t)}};var Vd="http://www.w3.org/1999/xhtml";const Gd={svg:"http://www.w3.org/2000/svg",xhtml:Vd,xlink:"http://www.w3.org/1999/xlink",xml:"http://www.w3.org/XML/1998/namespace",xmlns:"http://www.w3.org/2000/xmlns/"};function Xd(t){var e=t+="",n=e.indexOf(":");return n>=0&&"xmlns"!==(e=t.slice(0,n))&&(t=t.slice(n+1)),Gd.hasOwnProperty(e)?{space:Gd[e],local:t}:t}function Zd(t){return function(){this.removeAttribute(t)}}function Qd(t){return function(){this.removeAttributeNS(t.space,t.local)}}function Kd(t,e){return function(){this.setAttribute(t,e)}}function Jd(t,e){return function(){this.setAttributeNS(t.space,t.local,e)}}function tp(t,e){return function(){var n=e.apply(this,arguments);null==n?this.removeAttribute(t):this.setAttribute(t,n)}}function ep(t,e){return function(){var n=e.apply(this,arguments);null==n?this.removeAttributeNS(t.space,t.local):this.setAttributeNS(t.space,t.local,n)}}function np(t){return t.ownerDocument&&t.ownerDocument.defaultView||t.document&&t||t.defaultView}function rp(t){return function(){this.style.removeProperty(t)}}function ip(t,e,n){return function(){this.style.setProperty(t,e,n)}}function ap(t,e,n){return function(){var r=e.apply(this,arguments);null==r?this.style.removeProperty(t):this.style.setProperty(t,r,n)}}function op(t,e){return t.style.getPropertyValue(e)||np(t).getComputedStyle(t,null).getPropertyValue(e)}function sp(t){return function(){delete this[t]}}function cp(t,e){return function(){this[t]=e}}function up(t,e){return function(){var n=e.apply(this,arguments);null==n?delete this[t]:this[t]=n}}function lp(t){return t.trim().split(/^|\s+/)}function hp(t){return t.classList||new fp(t)}function fp(t){this._node=t,this._names=lp(t.getAttribute("class")||"")}function dp(t,e){for(var n=hp(t),r=-1,i=e.length;++r=0&&(e=t.slice(n+1),t=t.slice(0,n)),{type:t,name:e}}))}function Op(t){return function(){var e=this.__on;if(e){for(var n,r=0,i=-1,a=e.length;r=0&&(this._names.splice(e,1),this._node.setAttribute("class",this._names.join(" ")))},contains:function(t){return this._names.indexOf(t)>=0}};var Yp=[null];function jp(t,e){this._groups=t,this._parents=e}function Up(){return new jp([[document.documentElement]],Yp)}jp.prototype=Up.prototype={constructor:jp,select:function(t){"function"!=typeof t&&(t=Md(t));for(var e=this._groups,n=e.length,r=new Array(n),i=0;i=x&&(x=_+1);!(b=y[x])&&++x=0;)(r=i[a])&&(o&&4^r.compareDocumentPosition(o)&&o.parentNode.insertBefore(r,o),o=r);return this},sort:function(t){function e(e,n){return e&&n?t(e.__data__,n.__data__):!e-!n}t||(t=Wd);for(var n=this._groups,r=n.length,i=new Array(r),a=0;a1?this.each((null==e?rp:"function"==typeof e?ap:ip)(t,e,null==n?"":n)):op(this.node(),t)},property:function(t,e){return arguments.length>1?this.each((null==e?sp:"function"==typeof e?up:cp)(t,e)):this.node()[t]},classed:function(t,e){var n=lp(t+"");if(arguments.length<2){for(var r=hp(this.node()),i=-1,a=n.length;++i{}};function qp(){for(var t,e=0,n=arguments.length,r={};e=0&&(n=t.slice(r+1),t=t.slice(0,r)),t&&!e.hasOwnProperty(t))throw new Error("unknown type: "+t);return{type:t,name:n}}))}function Vp(t,e){for(var n,r=0,i=t.length;r0)for(var n,r,i=new Array(n),a=0;a=0&&e._call.call(void 0,t),e=e._next;--Kp}()}finally{Kp=0,function(){for(var t,e,n=Zp,r=1/0;n;)n._call?(r>n._time&&(r=n._time),t=n,n=n._next):(e=n._next,n._next=null,n=t?t._next=e:Zp=e);Qp=t,fg(r)}(),ng=0}}function hg(){var t=ig.now(),e=t-eg;e>1e3&&(rg-=e,eg=t)}function fg(t){Kp||(Jp&&(Jp=clearTimeout(Jp)),t-ng>24?(t<1/0&&(Jp=setTimeout(lg,t-ig.now()-rg)),tg&&(tg=clearInterval(tg))):(tg||(eg=ig.now(),tg=setInterval(hg,1e3)),Kp=1,ag(lg)))}function dg(t,e,n){var r=new cg;return e=null==e?0:+e,r.restart((n=>{r.stop(),t(n+e)}),e,n),r}cg.prototype=ug.prototype={constructor:cg,restart:function(t,e,n){if("function"!=typeof t)throw new TypeError("callback is not a function");n=(null==n?og():+n)+(null==e?0:+e),this._next||Qp===this||(Qp?Qp._next=this:Zp=this,Qp=this),this._call=t,this._time=n,fg()},stop:function(){this._call&&(this._call=null,this._time=1/0,fg())}};var pg=Xp("start","end","cancel","interrupt"),gg=[];function yg(t,e,n,r,i,a){var o=t.__transition;if(o){if(n in o)return}else t.__transition={};!function(t,e,n){var r,i=t.__transition;function a(c){var u,l,h,f;if(1!==n.state)return s();for(u in i)if((f=i[u]).name===n.name){if(3===f.state)return dg(a);4===f.state?(f.state=6,f.timer.stop(),f.on.call("interrupt",t,t.__data__,f.index,f.group),delete i[u]):+u0)throw new Error("too late; already scheduled");return n}function vg(t,e){var n=bg(t,e);if(n.state>3)throw new Error("too late; already running");return n}function bg(t,e){var n=t.__transition;if(!n||!(n=n[e]))throw new Error("transition not found");return n}function _g(t,e){return t=+t,e=+e,function(n){return t*(1-n)+e*n}}var xg,wg=180/Math.PI,kg={translateX:0,translateY:0,rotate:0,skewX:0,scaleX:1,scaleY:1};function Tg(t,e,n,r,i,a){var o,s,c;return(o=Math.sqrt(t*t+e*e))&&(t/=o,e/=o),(c=t*n+e*r)&&(n-=t*c,r-=e*c),(s=Math.sqrt(n*n+r*r))&&(n/=s,r/=s,c/=s),t*r180?e+=360:e-t>180&&(t+=360),a.push({i:n.push(i(n)+"rotate(",null,r)-2,x:_g(t,e)})):e&&n.push(i(n)+"rotate("+e+r)}(a.rotate,o.rotate,s,c),function(t,e,n,a){t!==e?a.push({i:n.push(i(n)+"skewX(",null,r)-2,x:_g(t,e)}):e&&n.push(i(n)+"skewX("+e+r)}(a.skewX,o.skewX,s,c),function(t,e,n,r,a,o){if(t!==n||e!==r){var s=a.push(i(a)+"scale(",null,",",null,")");o.push({i:s-4,x:_g(t,n)},{i:s-2,x:_g(e,r)})}else 1===n&&1===r||a.push(i(a)+"scale("+n+","+r+")")}(a.scaleX,a.scaleY,o.scaleX,o.scaleY,s,c),a=o=null,function(t){for(var e,n=-1,r=c.length;++n>8&15|e>>4&240,e>>4&15|240&e,(15&e)<<4|15&e,1):8===n?Qg(e>>24&255,e>>16&255,e>>8&255,(255&e)/255):4===n?Qg(e>>12&15|e>>8&240,e>>8&15|e>>4&240,e>>4&15|240&e,((15&e)<<4|15&e)/255):null):(e=jg.exec(t))?new ty(e[1],e[2],e[3],1):(e=Ug.exec(t))?new ty(255*e[1]/100,255*e[2]/100,255*e[3]/100,1):(e=zg.exec(t))?Qg(e[1],e[2],e[3],e[4]):(e=$g.exec(t))?Qg(255*e[1]/100,255*e[2]/100,255*e[3]/100,e[4]):(e=qg.exec(t))?iy(e[1],e[2]/100,e[3]/100,1):(e=Hg.exec(t))?iy(e[1],e[2]/100,e[3]/100,e[4]):Wg.hasOwnProperty(t)?Zg(Wg[t]):"transparent"===t?new ty(NaN,NaN,NaN,0):null}function Zg(t){return new ty(t>>16&255,t>>8&255,255&t,1)}function Qg(t,e,n,r){return r<=0&&(t=e=n=NaN),new ty(t,e,n,r)}function Kg(t){return t instanceof Lg||(t=Xg(t)),t?new ty((t=t.rgb()).r,t.g,t.b,t.opacity):new ty}function Jg(t,e,n,r){return 1===arguments.length?Kg(t):new ty(t,e,n,null==r?1:r)}function ty(t,e,n,r){this.r=+t,this.g=+e,this.b=+n,this.opacity=+r}function ey(){return"#"+ry(this.r)+ry(this.g)+ry(this.b)}function ny(){var t=this.opacity;return(1===(t=isNaN(t)?1:Math.max(0,Math.min(1,t)))?"rgb(":"rgba(")+Math.max(0,Math.min(255,Math.round(this.r)||0))+", "+Math.max(0,Math.min(255,Math.round(this.g)||0))+", "+Math.max(0,Math.min(255,Math.round(this.b)||0))+(1===t?")":", "+t+")")}function ry(t){return((t=Math.max(0,Math.min(255,Math.round(t)||0)))<16?"0":"")+t.toString(16)}function iy(t,e,n,r){return r<=0?t=e=n=NaN:n<=0||n>=1?t=e=NaN:e<=0&&(t=NaN),new oy(t,e,n,r)}function ay(t){if(t instanceof oy)return new oy(t.h,t.s,t.l,t.opacity);if(t instanceof Lg||(t=Xg(t)),!t)return new oy;if(t instanceof oy)return t;var e=(t=t.rgb()).r/255,n=t.g/255,r=t.b/255,i=Math.min(e,n,r),a=Math.max(e,n,r),o=NaN,s=a-i,c=(a+i)/2;return s?(o=e===a?(n-r)/s+6*(n0&&c<1?0:o,new oy(o,s,c,t.opacity)}function oy(t,e,n,r){this.h=+t,this.s=+e,this.l=+n,this.opacity=+r}function sy(t,e,n){return 255*(t<60?e+(n-e)*t/60:t<180?n:t<240?e+(n-e)*(240-t)/60:e)}function cy(t,e,n,r,i){var a=t*t,o=a*t;return((1-3*t+3*a-o)*e+(4-6*a+3*o)*n+(1+3*t+3*a-3*o)*r+o*i)/6}Dg(Lg,Xg,{copy:function(t){return Object.assign(new this.constructor,this,t)},displayable:function(){return this.rgb().displayable()},hex:Vg,formatHex:Vg,formatHsl:function(){return ay(this).formatHsl()},formatRgb:Gg,toString:Gg}),Dg(ty,Jg,Bg(Lg,{brighter:function(t){return t=null==t?Ig:Math.pow(Ig,t),new ty(this.r*t,this.g*t,this.b*t,this.opacity)},darker:function(t){return t=null==t?Og:Math.pow(Og,t),new ty(this.r*t,this.g*t,this.b*t,this.opacity)},rgb:function(){return this},displayable:function(){return-.5<=this.r&&this.r<255.5&&-.5<=this.g&&this.g<255.5&&-.5<=this.b&&this.b<255.5&&0<=this.opacity&&this.opacity<=1},hex:ey,formatHex:ey,formatRgb:ny,toString:ny})),Dg(oy,(function(t,e,n,r){return 1===arguments.length?ay(t):new oy(t,e,n,null==r?1:r)}),Bg(Lg,{brighter:function(t){return t=null==t?Ig:Math.pow(Ig,t),new oy(this.h,this.s,this.l*t,this.opacity)},darker:function(t){return t=null==t?Og:Math.pow(Og,t),new oy(this.h,this.s,this.l*t,this.opacity)},rgb:function(){var t=this.h%360+360*(this.h<0),e=isNaN(t)||isNaN(this.s)?0:this.s,n=this.l,r=n+(n<.5?n:1-n)*e,i=2*n-r;return new ty(sy(t>=240?t-240:t+120,i,r),sy(t,i,r),sy(t<120?t+240:t-120,i,r),this.opacity)},displayable:function(){return(0<=this.s&&this.s<=1||isNaN(this.s))&&0<=this.l&&this.l<=1&&0<=this.opacity&&this.opacity<=1},formatHsl:function(){var t=this.opacity;return(1===(t=isNaN(t)?1:Math.max(0,Math.min(1,t)))?"hsl(":"hsla(")+(this.h||0)+", "+100*(this.s||0)+"%, "+100*(this.l||0)+"%"+(1===t?")":", "+t+")")}}));const uy=t=>()=>t;function ly(t,e){var n=e-t;return n?function(t,e){return function(n){return t+n*e}}(t,n):uy(isNaN(t)?e:t)}const hy=function t(e){var n=function(t){return 1==(t=+t)?ly:function(e,n){return n-e?function(t,e,n){return t=Math.pow(t,n),e=Math.pow(e,n)-t,n=1/n,function(r){return Math.pow(t+r*e,n)}}(e,n,t):uy(isNaN(e)?n:e)}}(e);function r(t,e){var r=n((t=Jg(t)).r,(e=Jg(e)).r),i=n(t.g,e.g),a=n(t.b,e.b),o=ly(t.opacity,e.opacity);return function(e){return t.r=r(e),t.g=i(e),t.b=a(e),t.opacity=o(e),t+""}}return r.gamma=t,r}(1);function fy(t){return function(e){var n,r,i=e.length,a=new Array(i),o=new Array(i),s=new Array(i);for(n=0;n=1?(n=1,e-1):Math.floor(n*e),i=t[r],a=t[r+1],o=r>0?t[r-1]:2*i-a,s=ra&&(i=e.slice(a,i),s[o]?s[o]+=i:s[++o]=i),(n=n[0])===(r=r[0])?s[o]?s[o]+=r:s[++o]=r:(s[++o]=null,c.push({i:o,x:_g(n,r)})),a=py.lastIndex;return a=0&&(t=t.slice(0,e)),!t||"start"===t}))}(e)?mg:vg;return function(){var o=a(this,t),s=o.on;s!==r&&(i=(r=s).copy()).on(e,n),o.on=i}}var Ly=zp.prototype.constructor;function Oy(t){return function(){this.style.removeProperty(t)}}function Iy(t,e,n){return function(r){this.style.setProperty(t,e.call(this,r),n)}}function Ry(t,e,n){var r,i;function a(){var a=e.apply(this,arguments);return a!==i&&(r=(i=a)&&Iy(t,a,n)),r}return a._value=e,a}function Fy(t){return function(e){this.textContent=t.call(this,e)}}function Py(t){var e,n;function r(){var r=t.apply(this,arguments);return r!==n&&(e=(n=r)&&Fy(r)),e}return r._value=t,r}var Yy=0;function jy(t,e,n,r){this._groups=t,this._parents=e,this._name=n,this._id=r}function Uy(){return++Yy}var zy=zp.prototype;jy.prototype=function(t){return zp().transition(t)}.prototype={constructor:jy,select:function(t){var e=this._name,n=this._id;"function"!=typeof t&&(t=Md(t));for(var r=this._groups,i=r.length,a=new Array(i),o=0;o2&&n.state<5,n.state=6,n.timer.stop(),n.on.call(r?"interrupt":"cancel",t,t.__data__,n.index,n.group),delete a[i]):o=!1;o&&delete t.__transition}}(this,t)}))},zp.prototype.transition=function(t){var e,n;t instanceof jy?(e=t._id,t=t._name):(e=Uy(),(n=$y).time=og(),t=null==t?null:t+"");for(var r=this._groups,i=r.length,a=0;a0?tm(fm,--lm):0,cm--,10===hm&&(cm=1,sm--),hm}function gm(){return hm=lm2||bm(hm)>3?"":" "}function wm(t,e){for(;--e&&gm()&&!(hm<48||hm>102||hm>57&&hm<65||hm>70&&hm<97););return vm(t,mm()+(e<6&&32==ym()&&32==gm()))}function km(t){for(;gm();)switch(hm){case t:return lm;case 34:case 39:34!==t&&39!==t&&km(hm);break;case 40:41===t&&km(t);break;case 92:gm()}return lm}function Tm(t,e){for(;gm()&&t+hm!==57&&(t+hm!==84||47!==ym()););return"/*"+vm(e,lm-1)+"*"+Zy(47===t?t:gm())}function Cm(t){for(;!bm(ym());)gm();return vm(t,lm)}function Em(t){return function(t){return fm="",t}(Sm("",null,null,null,[""],t=function(t){return sm=cm=1,um=nm(fm=t),lm=0,[]}(t),0,[0],t))}function Sm(t,e,n,r,i,a,o,s,c){for(var u=0,l=0,h=o,f=0,d=0,p=0,g=1,y=1,m=1,v=0,b="",_=i,x=a,w=r,k=b;y;)switch(p=v,v=gm()){case 40:if(108!=p&&58==k.charCodeAt(h-1)){-1!=Jy(k+=Ky(_m(v),"&","&\f"),"&\f")&&(m=-1);break}case 34:case 39:case 91:k+=_m(v);break;case 9:case 10:case 13:case 32:k+=xm(p);break;case 92:k+=wm(mm()-1,7);continue;case 47:switch(ym()){case 42:case 47:im(Mm(Tm(gm(),mm()),e,n),c);break;default:k+="/"}break;case 123*g:s[u++]=nm(k)*m;case 125*g:case 59:case 0:switch(v){case 0:case 125:y=0;case 59+l:d>0&&nm(k)-h&&im(d>32?Nm(k+";",r,n,h-1):Nm(Ky(k," ","")+";",r,n,h-2),c);break;case 59:k+=";";default:if(im(w=Am(k,e,n,u,l,i,s,b,_=[],x=[],h),a),123===v)if(0===l)Sm(k,e,w,w,_,a,h,s,x);else switch(f){case 100:case 109:case 115:Sm(t,w,w,r&&im(Am(t,w,w,0,0,i,s,b,i,_=[],h),x),i,x,h,s,r?_:x);break;default:Sm(k,w,w,w,[""],x,0,s,x)}}u=l=d=0,g=m=1,b=k="",h=o;break;case 58:h=1+nm(k),d=p;default:if(g<1)if(123==v)--g;else if(125==v&&0==g++&&125==pm())continue;switch(k+=Zy(v),v*g){case 38:m=l>0?1:(k+="\f",-1);break;case 44:s[u++]=(nm(k)-1)*m,m=1;break;case 64:45===ym()&&(k+=_m(gm())),f=ym(),l=h=nm(b=k+=Cm(mm())),v++;break;case 45:45===p&&2==nm(k)&&(g=0)}}return a}function Am(t,e,n,r,i,a,o,s,c,u,l){for(var h=i-1,f=0===i?a:[""],d=rm(f),p=0,g=0,y=0;p0?f[m]+" "+v:Ky(v,/&\f/g,f[m])))&&(c[y++]=b);return dm(t,e,n,0===i?Vy:s,c,u,l)}function Mm(t,e,n){return dm(t,e,n,Wy,Zy(hm),em(t,2,-2),0)}function Nm(t,e,n,r){return dm(t,e,n,Gy,em(t,0,r),em(t,r+1,-1),r)}const Dm="9.1.1";var Bm=n(7967),Lm=n(7856),Om=n.n(Lm),Im=function(t){var e=t.replace(/\\u[\dA-F]{4}/gi,(function(t){return String.fromCharCode(parseInt(t.replace(/\\u/g,""),16))}));return e=(e=(e=e.replace(/\\x([0-9a-f]{2})/gi,(function(t,e){return String.fromCharCode(parseInt(e,16))}))).replace(/\\[\d\d\d]{3}/gi,(function(t){return String.fromCharCode(parseInt(t.replace(/\\/g,""),8))}))).replace(/\\[\d\d\d]{2}/gi,(function(t){return String.fromCharCode(parseInt(t.replace(/\\/g,""),8))}))},Rm=function(t){for(var e="",n=0;n>=0;){if(!((n=t.indexOf("=0)){e+=t,n=-1;break}e+=t.substr(0,n),(n=(t=t.substr(n+1)).indexOf("<\/script>"))>=0&&(n+=9,t=t.substr(n))}var r=Im(e);return(r=(r=(r=(r=r.replaceAll(/script>/gi,"#")).replaceAll(/javascript:/gi,"#")).replaceAll(/javascript&colon/gi,"#")).replaceAll(/onerror=/gi,"onerror:")).replaceAll(/')}else"loose"!==s.securityLevel&&(T=Om().sanitize(T,{ADD_TAGS:["foreignobject"],ADD_ATTR:["dominant-baseline"]}));if(void 0!==n)switch(g){case"flowchart":case"flowchart-v2":n(T,Gx.bindFunctions);break;case"gantt":n(T,Qw.bindFunctions);break;case"class":case"classDiagram":n(T,Zb.bindFunctions);break;default:n(T)}else o.debug("CB = undefined!");IT.forEach((function(t){t()})),IT=[];var S="sandbox"===s.securityLevel?"#i"+t:"#d"+t,A=au(S).node();return null!==A&&"function"==typeof A.remove&&au(S).node().remove(),T},parse:function(t){t+="\n";var e=wb(),n=db.detectInit(t,e);n&&o.info("reinit ",n);var r,i=db.detectType(t,e);switch(o.debug("Type "+i),i){case"gitGraph":wk.clear(),(r=Tk()).parser.yy=wk;break;case"flowchart":case"flowchart-v2":Gx.clear(),(r=Zx()).parser.yy=Gx;break;case"sequence":OT.clear(),(r=pT()).parser.yy=OT;break;case"gantt":(r=ek()).parser.yy=Qw;break;case"class":case"classDiagram":(r=n_()).parser.yy=Zb;break;case"state":case"stateDiagram":(r=EC()).parser.yy=UC;break;case"info":o.debug("info info info"),(r=Fk()).parser.yy=Ik;break;case"pie":o.debug("pie"),(r=Uk()).parser.yy=Hk;break;case"er":o.debug("er"),(r=dx()).parser.yy=hx;break;case"journey":o.debug("Journey"),(r=pE()).parser.yy=fE;break;case"requirement":case"requirementDiagram":o.debug("RequirementDiagram"),(r=Zk()).parser.yy=nT}return r.parser.yy.graphType=i,r.parser.yy.parseError=function(t,e){throw{str:t,hash:e}},r.parse(t),r},parseDirective:function(t,e,n,r){try{if(void 0!==e)switch(e=e.trim(),n){case"open_directive":PE={};break;case"type_directive":PE.type=e.toLowerCase();break;case"arg_directive":PE.args=JSON.parse(e);break;case"close_directive":(function(t,e,n){switch(o.debug("Directive type=".concat(e.type," with args:"),e.args),e.type){case"init":case"initialize":["config"].forEach((function(t){void 0!==e.args[t]&&("flowchart-v2"===n&&(n="flowchart"),e.args[n]=e.args[t],delete e.args[t])})),o.debug("sanitize in handleDirective",e.args),hb(e.args),o.debug("sanitize in handleDirective (done)",e.args),e.args,Tb(e.args);break;case"wrap":case"nowrap":t&&t.setWrap&&t.setWrap("wrap"===e.type);break;case"themeCss":o.warn("themeCss encountered");break;default:o.warn("Unhandled directive: source: '%%{".concat(e.type,": ").concat(JSON.stringify(e.args?e.args:{}),"}%%"),e)}})(t,PE,r),PE=null}}catch(t){o.error("Error while rendering sequenceDiagram directive: ".concat(e," jison context: ").concat(n)),o.error(t.message)}},initialize:function(t){t&&t.fontFamily&&(t.themeVariables&&t.themeVariables.fontFamily||(t.themeVariables={fontFamily:t.fontFamily})),function(t){gb=rb({},t)}(t),t&&t.theme&&Mv[t.theme]?t.themeVariables=Mv[t.theme].getThemeVariables(t.themeVariables):t&&(t.themeVariables=Mv.default.getThemeVariables(t.themeVariables));var e="object"===RE(t)?function(t){return mb=rb({},yb),mb=rb(mb,t),t.theme&&Mv[t.theme]&&(mb.themeVariables=Mv[t.theme].getThemeVariables(t.themeVariables)),bb=_b(mb,vb),mb}(t):xb();YE(e),s(e.logLevel)},reinitialize:function(){},getConfig:wb,setConfig:function(t){return rb(bb,t),wb()},getSiteConfig:xb,updateSiteConfig:function(t){return mb=rb(mb,t),_b(mb,vb),mb},reset:function(){Cb()},globalReset:function(){Cb(),YE(wb())},defaultConfig:yb});s(wb().logLevel),Cb(wb());const UE=jE;var zE=function(){var t,e,n=UE.getConfig();arguments.length>=2?(void 0!==arguments[0]&&(qE.sequenceConfig=arguments[0]),t=arguments[1]):t=arguments[0],"function"==typeof arguments[arguments.length-1]?(e=arguments[arguments.length-1],o.debug("Callback function found")):void 0!==n.mermaid&&("function"==typeof n.mermaid.callback?(e=n.mermaid.callback,o.debug("Callback function found")):o.debug("No Callback function found")),t=void 0===t?document.querySelectorAll(".mermaid"):"string"==typeof t?document.querySelectorAll(t):t instanceof window.Node?[t]:t,o.debug("Start On Load before: "+qE.startOnLoad),void 0!==qE.startOnLoad&&(o.debug("Start On Load inner: "+qE.startOnLoad),UE.updateSiteConfig({startOnLoad:qE.startOnLoad})),void 0!==qE.ganttConfig&&UE.updateSiteConfig({gantt:qE.ganttConfig});for(var r,i=new db.initIdGeneratior(n.deterministicIds,n.deterministicIDSeed),a=function(n){var a=t[n];if(a.getAttribute("data-processed"))return"continue";a.setAttribute("data-processed",!0);var s="mermaid-".concat(i.next());r=a.innerHTML,r=db.entityDecode(r).trim().replace(//gi,"
    ");var c=db.detectInit(r);c&&o.debug("Detected early reinit: ",c),UE.render(s,r,(function(t,n){a.innerHTML=t,void 0!==e&&e(s),n&&n(a)}),a)},s=0;s{t.exports={graphlib:n(6614),dagre:n(1463),intersect:n(8114),render:n(5787),util:n(8355),version:n(5689)}},9144:(t,e,n)=>{var r=n(8355);function i(t,e,n,i){var a=t.append("marker").attr("id",e).attr("viewBox","0 0 10 10").attr("refX",9).attr("refY",5).attr("markerUnits","strokeWidth").attr("markerWidth",8).attr("markerHeight",6).attr("orient","auto").append("path").attr("d","M 0 0 L 10 5 L 0 10 z").style("stroke-width",1).style("stroke-dasharray","1,0");r.applyStyle(a,n[i+"Style"]),n[i+"Class"]&&a.attr("class",n[i+"Class"])}t.exports={default:i,normal:i,vee:function(t,e,n,i){var a=t.append("marker").attr("id",e).attr("viewBox","0 0 10 10").attr("refX",9).attr("refY",5).attr("markerUnits","strokeWidth").attr("markerWidth",8).attr("markerHeight",6).attr("orient","auto").append("path").attr("d","M 0 0 L 10 5 L 0 10 L 4 5 z").style("stroke-width",1).style("stroke-dasharray","1,0");r.applyStyle(a,n[i+"Style"]),n[i+"Class"]&&a.attr("class",n[i+"Class"])},undirected:function(t,e,n,i){var a=t.append("marker").attr("id",e).attr("viewBox","0 0 10 10").attr("refX",9).attr("refY",5).attr("markerUnits","strokeWidth").attr("markerWidth",8).attr("markerHeight",6).attr("orient","auto").append("path").attr("d","M 0 5 L 10 5").style("stroke-width",1).style("stroke-dasharray","1,0");r.applyStyle(a,n[i+"Style"]),n[i+"Class"]&&a.attr("class",n[i+"Class"])}}},5632:(t,e,n)=>{var r=n(8355),i=n(4322),a=n(1322);t.exports=function(t,e){var n,o=e.nodes().filter((function(t){return r.isSubgraph(e,t)})),s=t.selectAll("g.cluster").data(o,(function(t){return t}));return s.selectAll("*").remove(),s.enter().append("g").attr("class","cluster").attr("id",(function(t){return e.node(t).id})).style("opacity",0),s=t.selectAll("g.cluster"),r.applyTransition(s,e).style("opacity",1),s.each((function(t){var n=e.node(t),r=i.select(this);i.select(this).append("rect");var o=r.append("g").attr("class","label");a(o,n,n.clusterLabelPos)})),s.selectAll("rect").each((function(t){var n=e.node(t),a=i.select(this);r.applyStyle(a,n.style)})),n=s.exit?s.exit():s.selectAll(null),r.applyTransition(n,e).style("opacity",0).remove(),s}},6315:(t,e,n)=>{"use strict";var r=n(1034),i=n(1322),a=n(8355),o=n(4322);t.exports=function(t,e){var n,s=t.selectAll("g.edgeLabel").data(e.edges(),(function(t){return a.edgeToId(t)})).classed("update",!0);return s.exit().remove(),s.enter().append("g").classed("edgeLabel",!0).style("opacity",0),(s=t.selectAll("g.edgeLabel")).each((function(t){var n=o.select(this);n.select(".label").remove();var a=e.edge(t),s=i(n,e.edge(t),0,0).classed("label",!0),c=s.node().getBBox();a.labelId&&s.attr("id",a.labelId),r.has(a,"width")||(a.width=c.width),r.has(a,"height")||(a.height=c.height)})),n=s.exit?s.exit():s.selectAll(null),a.applyTransition(n,e).style("opacity",0).remove(),s}},940:(t,e,n)=>{"use strict";var r=n(1034),i=n(3042),a=n(8355),o=n(4322);function s(t,e){var n=(o.line||o.svg.line)().x((function(t){return t.x})).y((function(t){return t.y}));return(n.curve||n.interpolate)(t.curve),n(e)}t.exports=function(t,e,n){var c=t.selectAll("g.edgePath").data(e.edges(),(function(t){return a.edgeToId(t)})).classed("update",!0),u=function(t,e){var n=t.enter().append("g").attr("class","edgePath").style("opacity",0);return n.append("path").attr("class","path").attr("d",(function(t){var n=e.edge(t),i=e.node(t.v).elem;return s(n,r.range(n.points.length).map((function(){return e=(t=i).getBBox(),{x:(n=t.ownerSVGElement.getScreenCTM().inverse().multiply(t.getScreenCTM()).translate(e.width/2,e.height/2)).e,y:n.f};var t,e,n})))})),n.append("defs"),n}(c,e);!function(t,e){var n=t.exit();a.applyTransition(n,e).style("opacity",0).remove()}(c,e);var l=void 0!==c.merge?c.merge(u):c;return a.applyTransition(l,e).style("opacity",1),l.each((function(t){var n=o.select(this),r=e.edge(t);r.elem=this,r.id&&n.attr("id",r.id),a.applyClass(n,r.class,(n.classed("update")?"update ":"")+"edgePath")})),l.selectAll("path.path").each((function(t){var n=e.edge(t);n.arrowheadId=r.uniqueId("arrowhead");var c=o.select(this).attr("marker-end",(function(){return"url("+(t=location.href,e=n.arrowheadId,t.split("#")[0]+"#"+e+")");var t,e})).style("fill","none");a.applyTransition(c,e).attr("d",(function(t){return function(t,e){var n=t.edge(e),r=t.node(e.v),a=t.node(e.w),o=n.points.slice(1,n.points.length-1);return o.unshift(i(r,o[0])),o.push(i(a,o[o.length-1])),s(n,o)}(e,t)})),a.applyStyle(c,n.style)})),l.selectAll("defs *").remove(),l.selectAll("defs").each((function(t){var r=e.edge(t);(0,n[r.arrowhead])(o.select(this),r.arrowheadId,r,"arrowhead")})),l}},607:(t,e,n)=>{"use strict";var r=n(1034),i=n(1322),a=n(8355),o=n(4322);t.exports=function(t,e,n){var s,c=e.nodes().filter((function(t){return!a.isSubgraph(e,t)})),u=t.selectAll("g.node").data(c,(function(t){return t})).classed("update",!0);return u.exit().remove(),u.enter().append("g").attr("class","node").style("opacity",0),(u=t.selectAll("g.node")).each((function(t){var s=e.node(t),c=o.select(this);a.applyClass(c,s.class,(c.classed("update")?"update ":"")+"node"),c.select("g.label").remove();var u=c.append("g").attr("class","label"),l=i(u,s),h=n[s.shape],f=r.pick(l.node().getBBox(),"width","height");s.elem=this,s.id&&c.attr("id",s.id),s.labelId&&u.attr("id",s.labelId),r.has(s,"width")&&(f.width=s.width),r.has(s,"height")&&(f.height=s.height),f.width+=s.paddingLeft+s.paddingRight,f.height+=s.paddingTop+s.paddingBottom,u.attr("transform","translate("+(s.paddingLeft-s.paddingRight)/2+","+(s.paddingTop-s.paddingBottom)/2+")");var d=o.select(this);d.select(".label-container").remove();var p=h(d,f,s).classed("label-container",!0);a.applyStyle(p,s.style);var g=p.node().getBBox();s.width=g.width,s.height=g.height})),s=u.exit?u.exit():u.selectAll(null),a.applyTransition(s,e).style("opacity",0).remove(),u}},4322:(t,e,n)=>{var r;if(!r)try{r=n(7188)}catch(t){}r||(r=window.d3),t.exports=r},1463:(t,e,n)=>{var r;try{r=n(681)}catch(t){}r||(r=window.dagre),t.exports=r},6614:(t,e,n)=>{var r;try{r=n(8282)}catch(t){}r||(r=window.graphlib),t.exports=r},8114:(t,e,n)=>{t.exports={node:n(3042),circle:n(6587),ellipse:n(3260),polygon:n(5337),rect:n(8049)}},6587:(t,e,n)=>{var r=n(3260);t.exports=function(t,e,n){return r(t,e,e,n)}},3260:t=>{t.exports=function(t,e,n,r){var i=t.x,a=t.y,o=i-r.x,s=a-r.y,c=Math.sqrt(e*e*s*s+n*n*o*o),u=Math.abs(e*n*o/c);r.x{function e(t,e){return t*e>0}t.exports=function(t,n,r,i){var a,o,s,c,u,l,h,f,d,p,g,y,m;if(!(a=n.y-t.y,s=t.x-n.x,u=n.x*t.y-t.x*n.y,d=a*r.x+s*r.y+u,p=a*i.x+s*i.y+u,0!==d&&0!==p&&e(d,p)||(o=i.y-r.y,c=r.x-i.x,l=i.x*r.y-r.x*i.y,h=o*t.x+c*t.y+l,f=o*n.x+c*n.y+l,0!==h&&0!==f&&e(h,f)||0==(g=a*c-o*s))))return y=Math.abs(g/2),{x:(m=s*l-c*u)<0?(m-y)/g:(m+y)/g,y:(m=o*u-a*l)<0?(m-y)/g:(m+y)/g}}},3042:t=>{t.exports=function(t,e){return t.intersect(e)}},5337:(t,e,n)=>{var r=n(6808);t.exports=function(t,e,n){var i=t.x,a=t.y,o=[],s=Number.POSITIVE_INFINITY,c=Number.POSITIVE_INFINITY;e.forEach((function(t){s=Math.min(s,t.x),c=Math.min(c,t.y)}));for(var u=i-t.width/2-s,l=a-t.height/2-c,h=0;h1&&o.sort((function(t,e){var r=t.x-n.x,i=t.y-n.y,a=Math.sqrt(r*r+i*i),o=e.x-n.x,s=e.y-n.y,c=Math.sqrt(o*o+s*s);return a{t.exports=function(t,e){var n,r,i=t.x,a=t.y,o=e.x-i,s=e.y-a,c=t.width/2,u=t.height/2;return Math.abs(s)*c>Math.abs(o)*u?(s<0&&(u=-u),n=0===s?0:u*o/s,r=u):(o<0&&(c=-c),n=c,r=0===o?0:c*s/o),{x:i+n,y:a+r}}},8284:(t,e,n)=>{var r=n(8355);t.exports=function(t,e){var n=t.append("foreignObject").attr("width","100000"),i=n.append("xhtml:div");i.attr("xmlns","http://www.w3.org/1999/xhtml");var a=e.label;switch(typeof a){case"function":i.insert(a);break;case"object":i.insert((function(){return a}));break;default:i.html(a)}r.applyStyle(i,e.labelStyle),i.style("display","inline-block"),i.style("white-space","nowrap");var o=i.node().getBoundingClientRect();return n.attr("width",o.width).attr("height",o.height),n}},1322:(t,e,n)=>{var r=n(7318),i=n(8284),a=n(8287);t.exports=function(t,e,n){var o=e.label,s=t.append("g");"svg"===e.labelType?a(s,e):"string"!=typeof o||"html"===e.labelType?i(s,e):r(s,e);var c,u=s.node().getBBox();switch(n){case"top":c=-e.height/2;break;case"bottom":c=e.height/2-u.height;break;default:c=-u.height/2}return s.attr("transform","translate("+-u.width/2+","+c+")"),s}},8287:(t,e,n)=>{var r=n(8355);t.exports=function(t,e){var n=t;return n.node().appendChild(e.label),r.applyStyle(n,e.labelStyle),n}},7318:(t,e,n)=>{var r=n(8355);t.exports=function(t,e){for(var n=t.append("text"),i=function(t){for(var e,n="",r=!1,i=0;i{var r;try{r={defaults:n(1747),each:n(6073),isFunction:n(3560),isPlainObject:n(8630),pick:n(9722),has:n(8721),range:n(6026),uniqueId:n(3955)}}catch(t){}r||(r=window._),t.exports=r},6381:(t,e,n)=>{"use strict";var r=n(8355),i=n(4322);t.exports=function(t,e){var n=t.filter((function(){return!i.select(this).classed("update")}));function a(t){var n=e.node(t);return"translate("+n.x+","+n.y+")"}n.attr("transform",a),r.applyTransition(t,e).style("opacity",1).attr("transform",a),r.applyTransition(n.selectAll("rect"),e).attr("width",(function(t){return e.node(t).width})).attr("height",(function(t){return e.node(t).height})).attr("x",(function(t){return-e.node(t).width/2})).attr("y",(function(t){return-e.node(t).height/2}))}},4577:(t,e,n)=>{"use strict";var r=n(8355),i=n(4322),a=n(1034);t.exports=function(t,e){function n(t){var n=e.edge(t);return a.has(n,"x")?"translate("+n.x+","+n.y+")":""}t.filter((function(){return!i.select(this).classed("update")})).attr("transform",n),r.applyTransition(t,e).style("opacity",1).attr("transform",n)}},4849:(t,e,n)=>{"use strict";var r=n(8355),i=n(4322);t.exports=function(t,e){function n(t){var n=e.node(t);return"translate("+n.x+","+n.y+")"}t.filter((function(){return!i.select(this).classed("update")})).attr("transform",n),r.applyTransition(t,e).style("opacity",1).attr("transform",n)}},5787:(t,e,n)=>{var r=n(1034),i=n(4322),a=n(1463).layout;t.exports=function(){var t=n(607),e=n(5632),i=n(6315),u=n(940),l=n(4849),h=n(4577),f=n(6381),d=n(4418),p=n(9144),g=function(n,g){!function(t){t.nodes().forEach((function(e){var n=t.node(e);r.has(n,"label")||t.children(e).length||(n.label=e),r.has(n,"paddingX")&&r.defaults(n,{paddingLeft:n.paddingX,paddingRight:n.paddingX}),r.has(n,"paddingY")&&r.defaults(n,{paddingTop:n.paddingY,paddingBottom:n.paddingY}),r.has(n,"padding")&&r.defaults(n,{paddingLeft:n.padding,paddingRight:n.padding,paddingTop:n.padding,paddingBottom:n.padding}),r.defaults(n,o),r.each(["paddingLeft","paddingRight","paddingTop","paddingBottom"],(function(t){n[t]=Number(n[t])})),r.has(n,"width")&&(n._prevWidth=n.width),r.has(n,"height")&&(n._prevHeight=n.height)})),t.edges().forEach((function(e){var n=t.edge(e);r.has(n,"label")||(n.label=""),r.defaults(n,s)}))}(g);var y=c(n,"output"),m=c(y,"clusters"),v=c(y,"edgePaths"),b=i(c(y,"edgeLabels"),g),_=t(c(y,"nodes"),g,d);a(g),l(_,g),h(b,g),u(v,g,p);var x=e(m,g);f(x,g),function(t){r.each(t.nodes(),(function(e){var n=t.node(e);r.has(n,"_prevWidth")?n.width=n._prevWidth:delete n.width,r.has(n,"_prevHeight")?n.height=n._prevHeight:delete n.height,delete n._prevWidth,delete n._prevHeight}))}(g)};return g.createNodes=function(e){return arguments.length?(t=e,g):t},g.createClusters=function(t){return arguments.length?(e=t,g):e},g.createEdgeLabels=function(t){return arguments.length?(i=t,g):i},g.createEdgePaths=function(t){return arguments.length?(u=t,g):u},g.shapes=function(t){return arguments.length?(d=t,g):d},g.arrows=function(t){return arguments.length?(p=t,g):p},g};var o={paddingLeft:10,paddingRight:10,paddingTop:10,paddingBottom:10,rx:0,ry:0,shape:"rect"},s={arrowhead:"normal",curve:i.curveLinear};function c(t,e){var n=t.select("g."+e);return n.empty()&&(n=t.append("g").attr("class",e)),n}},4418:(t,e,n)=>{"use strict";var r=n(8049),i=n(3260),a=n(6587),o=n(5337);t.exports={rect:function(t,e,n){var i=t.insert("rect",":first-child").attr("rx",n.rx).attr("ry",n.ry).attr("x",-e.width/2).attr("y",-e.height/2).attr("width",e.width).attr("height",e.height);return n.intersect=function(t){return r(n,t)},i},ellipse:function(t,e,n){var r=e.width/2,a=e.height/2,o=t.insert("ellipse",":first-child").attr("x",-e.width/2).attr("y",-e.height/2).attr("rx",r).attr("ry",a);return n.intersect=function(t){return i(n,r,a,t)},o},circle:function(t,e,n){var r=Math.max(e.width,e.height)/2,i=t.insert("circle",":first-child").attr("x",-e.width/2).attr("y",-e.height/2).attr("r",r);return n.intersect=function(t){return a(n,r,t)},i},diamond:function(t,e,n){var r=e.width*Math.SQRT2/2,i=e.height*Math.SQRT2/2,a=[{x:0,y:-i},{x:-r,y:0},{x:0,y:i},{x:r,y:0}],s=t.insert("polygon",":first-child").attr("points",a.map((function(t){return t.x+","+t.y})).join(" "));return n.intersect=function(t){return o(n,a,t)},s}}},8355:(t,e,n)=>{var r=n(1034);t.exports={isSubgraph:function(t,e){return!!t.children(e).length},edgeToId:function(t){return a(t.v)+":"+a(t.w)+":"+a(t.name)},applyStyle:function(t,e){e&&t.attr("style",e)},applyClass:function(t,e,n){e&&t.attr("class",e).attr("class",n+" "+t.attr("class"))},applyTransition:function(t,e){var n=e.graph();if(r.isPlainObject(n)){var i=n.transition;if(r.isFunction(i))return i(t)}return t}};var i=/:/g;function a(t){return t?String(t).replace(i,"\\:"):""}},5689:t=>{t.exports="0.6.4"},7188:(t,e,n)=>{"use strict";n.r(e),n.d(e,{FormatSpecifier:()=>uc,active:()=>Jr,arc:()=>fx,area:()=>vx,areaRadial:()=>Sx,ascending:()=>i,autoType:()=>Fo,axisBottom:()=>it,axisLeft:()=>at,axisRight:()=>rt,axisTop:()=>nt,bisect:()=>u,bisectLeft:()=>c,bisectRight:()=>s,bisector:()=>a,blob:()=>ms,brush:()=>Ai,brushSelection:()=>Ci,brushX:()=>Ei,brushY:()=>Si,buffer:()=>bs,chord:()=>Fi,clientPoint:()=>Dn,cluster:()=>Sd,color:()=>Ve,contourDensity:()=>oo,contours:()=>to,create:()=>Y_,creator:()=>ie,cross:()=>f,csv:()=>Ts,csvFormat:()=>To,csvFormatBody:()=>Co,csvFormatRow:()=>So,csvFormatRows:()=>Eo,csvFormatValue:()=>Ao,csvParse:()=>wo,csvParseRows:()=>ko,cubehelix:()=>qa,curveBasis:()=>sw,curveBasisClosed:()=>uw,curveBasisOpen:()=>hw,curveBundle:()=>dw,curveCardinal:()=>yw,curveCardinalClosed:()=>vw,curveCardinalOpen:()=>_w,curveCatmullRom:()=>kw,curveCatmullRomClosed:()=>Cw,curveCatmullRomOpen:()=>Sw,curveLinear:()=>px,curveLinearClosed:()=>Mw,curveMonotoneX:()=>Fw,curveMonotoneY:()=>Pw,curveNatural:()=>Uw,curveStep:()=>$w,curveStepAfter:()=>Hw,curveStepBefore:()=>qw,customEvent:()=>ye,descending:()=>d,deviation:()=>y,dispatch:()=>ft,drag:()=>po,dragDisable:()=>Se,dragEnable:()=>Ae,dsv:()=>ks,dsvFormat:()=>_o,easeBack:()=>hs,easeBackIn:()=>us,easeBackInOut:()=>hs,easeBackOut:()=>ls,easeBounce:()=>os,easeBounceIn:()=>as,easeBounceInOut:()=>ss,easeBounceOut:()=>os,easeCircle:()=>rs,easeCircleIn:()=>es,easeCircleInOut:()=>rs,easeCircleOut:()=>ns,easeCubic:()=>Xr,easeCubicIn:()=>Vr,easeCubicInOut:()=>Xr,easeCubicOut:()=>Gr,easeElastic:()=>ps,easeElasticIn:()=>ds,easeElasticInOut:()=>gs,easeElasticOut:()=>ps,easeExp:()=>ts,easeExpIn:()=>Ko,easeExpInOut:()=>ts,easeExpOut:()=>Jo,easeLinear:()=>Yo,easePoly:()=>Ho,easePolyIn:()=>$o,easePolyInOut:()=>Ho,easePolyOut:()=>qo,easeQuad:()=>zo,easeQuadIn:()=>jo,easeQuadInOut:()=>zo,easeQuadOut:()=>Uo,easeSin:()=>Zo,easeSinIn:()=>Go,easeSinInOut:()=>Zo,easeSinOut:()=>Xo,entries:()=>pa,event:()=>le,extent:()=>m,forceCenter:()=>Ls,forceCollide:()=>Ws,forceLink:()=>Xs,forceManyBody:()=>tc,forceRadial:()=>ec,forceSimulation:()=>Js,forceX:()=>nc,forceY:()=>rc,format:()=>pc,formatDefaultLocale:()=>bc,formatLocale:()=>vc,formatPrefix:()=>gc,formatSpecifier:()=>cc,geoAlbers:()=>zf,geoAlbersUsa:()=>$f,geoArea:()=>gu,geoAzimuthalEqualArea:()=>Vf,geoAzimuthalEqualAreaRaw:()=>Wf,geoAzimuthalEquidistant:()=>Xf,geoAzimuthalEquidistantRaw:()=>Gf,geoBounds:()=>sl,geoCentroid:()=>bl,geoCircle:()=>Nl,geoClipAntimeridian:()=>zl,geoClipCircle:()=>$l,geoClipExtent:()=>Vl,geoClipRectangle:()=>Wl,geoConicConformal:()=>ed,geoConicConformalRaw:()=>td,geoConicEqualArea:()=>Uf,geoConicEqualAreaRaw:()=>jf,geoConicEquidistant:()=>ad,geoConicEquidistantRaw:()=>id,geoContains:()=>ph,geoDistance:()=>ah,geoEqualEarth:()=>fd,geoEqualEarthRaw:()=>hd,geoEquirectangular:()=>rd,geoEquirectangularRaw:()=>nd,geoGnomonic:()=>pd,geoGnomonicRaw:()=>dd,geoGraticule:()=>mh,geoGraticule10:()=>vh,geoIdentity:()=>gd,geoInterpolate:()=>bh,geoLength:()=>nh,geoMercator:()=>Qf,geoMercatorRaw:()=>Zf,geoNaturalEarth1:()=>md,geoNaturalEarth1Raw:()=>yd,geoOrthographic:()=>bd,geoOrthographicRaw:()=>vd,geoPath:()=>kf,geoProjection:()=>Ff,geoProjectionMutator:()=>Pf,geoRotation:()=>Sl,geoStereographic:()=>xd,geoStereographicRaw:()=>_d,geoStream:()=>nu,geoTransform:()=>Tf,geoTransverseMercator:()=>kd,geoTransverseMercatorRaw:()=>wd,gray:()=>ka,hcl:()=>Ba,hierarchy:()=>Md,histogram:()=>D,hsl:()=>an,html:()=>Ds,image:()=>Es,interpolate:()=>Mn,interpolateArray:()=>xn,interpolateBasis:()=>un,interpolateBasisClosed:()=>ln,interpolateBlues:()=>f_,interpolateBrBG:()=>Tb,interpolateBuGn:()=>zb,interpolateBuPu:()=>qb,interpolateCividis:()=>k_,interpolateCool:()=>E_,interpolateCubehelix:()=>Up,interpolateCubehelixDefault:()=>T_,interpolateCubehelixLong:()=>zp,interpolateDate:()=>kn,interpolateDiscrete:()=>Sp,interpolateGnBu:()=>Wb,interpolateGreens:()=>p_,interpolateGreys:()=>y_,interpolateHcl:()=>Pp,interpolateHclLong:()=>Yp,interpolateHsl:()=>Op,interpolateHslLong:()=>Ip,interpolateHue:()=>Ap,interpolateInferno:()=>F_,interpolateLab:()=>Rp,interpolateMagma:()=>R_,interpolateNumber:()=>Tn,interpolateNumberArray:()=>bn,interpolateObject:()=>Cn,interpolateOrRd:()=>Gb,interpolateOranges:()=>w_,interpolatePRGn:()=>Eb,interpolatePiYG:()=>Ab,interpolatePlasma:()=>P_,interpolatePuBu:()=>Kb,interpolatePuBuGn:()=>Zb,interpolatePuOr:()=>Nb,interpolatePuRd:()=>t_,interpolatePurples:()=>v_,interpolateRainbow:()=>A_,interpolateRdBu:()=>Bb,interpolateRdGy:()=>Ob,interpolateRdPu:()=>n_,interpolateRdYlBu:()=>Rb,interpolateRdYlGn:()=>Pb,interpolateReds:()=>__,interpolateRgb:()=>gn,interpolateRgbBasis:()=>mn,interpolateRgbBasisClosed:()=>vn,interpolateRound:()=>Mp,interpolateSinebow:()=>B_,interpolateSpectral:()=>jb,interpolateString:()=>An,interpolateTransformCss:()=>pr,interpolateTransformSvg:()=>gr,interpolateTurbo:()=>L_,interpolateViridis:()=>I_,interpolateWarm:()=>C_,interpolateYlGn:()=>o_,interpolateYlGnBu:()=>i_,interpolateYlOrBr:()=>c_,interpolateYlOrRd:()=>l_,interpolateZoom:()=>Bp,interrupt:()=>ar,interval:()=>fk,isoFormat:()=>uk,isoParse:()=>hk,json:()=>As,keys:()=>fa,lab:()=>Ta,lch:()=>Da,line:()=>mx,lineRadial:()=>Ex,linkHorizontal:()=>Rx,linkRadial:()=>Px,linkVertical:()=>Fx,local:()=>U_,map:()=>na,matcher:()=>mt,max:()=>I,mean:()=>R,median:()=>F,merge:()=>P,min:()=>Y,mouse:()=>Ln,namespace:()=>Ct,namespaces:()=>Tt,nest:()=>ra,now:()=>qn,pack:()=>tp,packEnclose:()=>Id,packSiblings:()=>Gd,pairs:()=>l,partition:()=>op,path:()=>Wi,permute:()=>j,pie:()=>xx,piecewise:()=>$p,pointRadial:()=>Ax,polygonArea:()=>Hp,polygonCentroid:()=>Wp,polygonContains:()=>Qp,polygonHull:()=>Zp,polygonLength:()=>Kp,precisionFixed:()=>_c,precisionPrefix:()=>xc,precisionRound:()=>wc,quadtree:()=>js,quantile:()=>B,quantize:()=>qp,radialArea:()=>Sx,radialLine:()=>Ex,randomBates:()=>ig,randomExponential:()=>ag,randomIrwinHall:()=>rg,randomLogNormal:()=>ng,randomNormal:()=>eg,randomUniform:()=>tg,range:()=>k,rgb:()=>Qe,ribbon:()=>Ki,scaleBand:()=>dg,scaleDiverging:()=>ob,scaleDivergingLog:()=>sb,scaleDivergingPow:()=>ub,scaleDivergingSqrt:()=>lb,scaleDivergingSymlog:()=>cb,scaleIdentity:()=>Mg,scaleImplicit:()=>hg,scaleLinear:()=>Ag,scaleLog:()=>Pg,scaleOrdinal:()=>fg,scalePoint:()=>gg,scalePow:()=>Vg,scaleQuantile:()=>Xg,scaleQuantize:()=>Zg,scaleSequential:()=>Jv,scaleSequentialLog:()=>tb,scaleSequentialPow:()=>nb,scaleSequentialQuantile:()=>ib,scaleSequentialSqrt:()=>rb,scaleSequentialSymlog:()=>eb,scaleSqrt:()=>Gg,scaleSymlog:()=>zg,scaleThreshold:()=>Qg,scaleTime:()=>jv,scaleUtc:()=>Zv,scan:()=>U,schemeAccent:()=>db,schemeBlues:()=>h_,schemeBrBG:()=>kb,schemeBuGn:()=>Ub,schemeBuPu:()=>$b,schemeCategory10:()=>fb,schemeDark2:()=>pb,schemeGnBu:()=>Hb,schemeGreens:()=>d_,schemeGreys:()=>g_,schemeOrRd:()=>Vb,schemeOranges:()=>x_,schemePRGn:()=>Cb,schemePaired:()=>gb,schemePastel1:()=>yb,schemePastel2:()=>mb,schemePiYG:()=>Sb,schemePuBu:()=>Qb,schemePuBuGn:()=>Xb,schemePuOr:()=>Mb,schemePuRd:()=>Jb,schemePurples:()=>m_,schemeRdBu:()=>Db,schemeRdGy:()=>Lb,schemeRdPu:()=>e_,schemeRdYlBu:()=>Ib,schemeRdYlGn:()=>Fb,schemeReds:()=>b_,schemeSet1:()=>vb,schemeSet2:()=>bb,schemeSet3:()=>_b,schemeSpectral:()=>Yb,schemeTableau10:()=>xb,schemeYlGn:()=>a_,schemeYlGnBu:()=>r_,schemeYlOrBr:()=>s_,schemeYlOrRd:()=>u_,select:()=>Te,selectAll:()=>$_,selection:()=>ke,selector:()=>pt,selectorAll:()=>yt,set:()=>ha,shuffle:()=>z,stack:()=>Xw,stackOffsetDiverging:()=>Qw,stackOffsetExpand:()=>Zw,stackOffsetNone:()=>Ww,stackOffsetSilhouette:()=>Kw,stackOffsetWiggle:()=>Jw,stackOrderAppearance:()=>tk,stackOrderAscending:()=>nk,stackOrderDescending:()=>ik,stackOrderInsideOut:()=>ak,stackOrderNone:()=>Vw,stackOrderReverse:()=>ok,stratify:()=>hp,style:()=>Rt,sum:()=>$,svg:()=>Bs,symbol:()=>rw,symbolCircle:()=>Yx,symbolCross:()=>jx,symbolDiamond:()=>$x,symbolSquare:()=>Gx,symbolStar:()=>Vx,symbolTriangle:()=>Zx,symbolWye:()=>ew,symbols:()=>nw,text:()=>xs,thresholdFreedmanDiaconis:()=>L,thresholdScott:()=>O,thresholdSturges:()=>N,tickFormat:()=>Eg,tickIncrement:()=>A,tickStep:()=>M,ticks:()=>S,timeDay:()=>Ay,timeDays:()=>My,timeFormat:()=>pm,timeFormatDefaultLocale:()=>Iv,timeFormatLocale:()=>fm,timeFriday:()=>vy,timeFridays:()=>Cy,timeHour:()=>Dy,timeHours:()=>By,timeInterval:()=>ty,timeMillisecond:()=>jy,timeMilliseconds:()=>Uy,timeMinute:()=>Oy,timeMinutes:()=>Iy,timeMonday:()=>py,timeMondays:()=>xy,timeMonth:()=>ay,timeMonths:()=>oy,timeParse:()=>gm,timeSaturday:()=>by,timeSaturdays:()=>Ey,timeSecond:()=>Fy,timeSeconds:()=>Py,timeSunday:()=>dy,timeSundays:()=>_y,timeThursday:()=>my,timeThursdays:()=>Ty,timeTuesday:()=>gy,timeTuesdays:()=>wy,timeWednesday:()=>yy,timeWednesdays:()=>ky,timeWeek:()=>dy,timeWeeks:()=>_y,timeYear:()=>ny,timeYears:()=>ry,timeout:()=>Kn,timer:()=>Vn,timerFlush:()=>Gn,touch:()=>Bn,touches:()=>q_,transition:()=>qr,transpose:()=>q,tree:()=>vp,treemap:()=>kp,treemapBinary:()=>Tp,treemapDice:()=>ap,treemapResquarify:()=>Ep,treemapSlice:()=>bp,treemapSliceDice:()=>Cp,treemapSquarify:()=>wp,tsv:()=>Cs,tsvFormat:()=>Bo,tsvFormatBody:()=>Lo,tsvFormatRow:()=>Io,tsvFormatRows:()=>Oo,tsvFormatValue:()=>Ro,tsvParse:()=>No,tsvParseRows:()=>Do,utcDay:()=>im,utcDays:()=>am,utcFormat:()=>ym,utcFriday:()=>Gy,utcFridays:()=>em,utcHour:()=>Hv,utcHours:()=>Wv,utcMillisecond:()=>jy,utcMilliseconds:()=>Uy,utcMinute:()=>Gv,utcMinutes:()=>Xv,utcMonday:()=>qy,utcMondays:()=>Qy,utcMonth:()=>zv,utcMonths:()=>$v,utcParse:()=>mm,utcSaturday:()=>Xy,utcSaturdays:()=>nm,utcSecond:()=>Fy,utcSeconds:()=>Py,utcSunday:()=>$y,utcSundays:()=>Zy,utcThursday:()=>Vy,utcThursdays:()=>tm,utcTuesday:()=>Hy,utcTuesdays:()=>Ky,utcWednesday:()=>Wy,utcWednesdays:()=>Jy,utcWeek:()=>$y,utcWeeks:()=>Zy,utcYear:()=>sm,utcYears:()=>cm,values:()=>da,variance:()=>g,version:()=>r,voronoi:()=>Kk,window:()=>Bt,xml:()=>Ns,zip:()=>W,zoom:()=>fT,zoomIdentity:()=>nT,zoomTransform:()=>rT});var r="5.16.0";function i(t,e){return te?1:t>=e?0:NaN}function a(t){var e;return 1===t.length&&(e=t,t=function(t,n){return i(e(t),n)}),{left:function(e,n,r,i){for(null==r&&(r=0),null==i&&(i=e.length);r>>1;t(e[a],n)<0?r=a+1:i=a}return r},right:function(e,n,r,i){for(null==r&&(r=0),null==i&&(i=e.length);r>>1;t(e[a],n)>0?i=a:r=a+1}return r}}}var o=a(i),s=o.right,c=o.left;const u=s;function l(t,e){null==e&&(e=h);for(var n=0,r=t.length-1,i=t[0],a=new Array(r<0?0:r);nt?1:e>=t?0:NaN}function p(t){return null===t?NaN:+t}function g(t,e){var n,r,i=t.length,a=0,o=-1,s=0,c=0;if(null==e)for(;++o1)return c/(a-1)}function y(t,e){var n=g(t,e);return n?Math.sqrt(n):n}function m(t,e){var n,r,i,a=t.length,o=-1;if(null==e){for(;++o=n)for(r=i=n;++on&&(r=n),i=n)for(r=i=n;++on&&(r=n),i0)return[t];if((r=e0)for(t=Math.ceil(t/o),e=Math.floor(e/o),a=new Array(i=Math.ceil(e-t+1));++s=0?(a>=T?10:a>=C?5:a>=E?2:1)*Math.pow(10,i):-Math.pow(10,-i)/(a>=T?10:a>=C?5:a>=E?2:1)}function M(t,e,n){var r=Math.abs(e-t)/Math.max(0,n),i=Math.pow(10,Math.floor(Math.log(r)/Math.LN10)),a=r/i;return a>=T?i*=10:a>=C?i*=5:a>=E&&(i*=2),eh;)f.pop(),--d;var p,g=new Array(d+1);for(i=0;i<=d;++i)(p=g[i]=[]).x0=i>0?f[i-1]:l,p.x1=i=1)return+n(t[r-1],r-1,t);var r,i=(r-1)*e,a=Math.floor(i),o=+n(t[a],a,t);return o+(+n(t[a+1],a+1,t)-o)*(i-a)}}function L(t,e,n){return t=_.call(t,p).sort(i),Math.ceil((n-e)/(2*(B(t,.75)-B(t,.25))*Math.pow(t.length,-1/3)))}function O(t,e,n){return Math.ceil((n-e)/(3.5*y(t)*Math.pow(t.length,-1/3)))}function I(t,e){var n,r,i=t.length,a=-1;if(null==e){for(;++a=n)for(r=n;++ar&&(r=n)}else for(;++a=n)for(r=n;++ar&&(r=n);return r}function R(t,e){var n,r=t.length,i=r,a=-1,o=0;if(null==e)for(;++a=0;)for(e=(r=t[i]).length;--e>=0;)n[--o]=r[e];return n}function Y(t,e){var n,r,i=t.length,a=-1;if(null==e){for(;++a=n)for(r=n;++an&&(r=n)}else for(;++a=n)for(r=n;++an&&(r=n);return r}function j(t,e){for(var n=e.length,r=new Array(n);n--;)r[n]=t[e[n]];return r}function U(t,e){if(n=t.length){var n,r,a=0,o=0,s=t[o];for(null==e&&(e=i);++a=0&&(n=t.slice(r+1),t=t.slice(0,r)),t&&!e.hasOwnProperty(t))throw new Error("unknown type: "+t);return{type:t,name:n}}))}function lt(t,e){for(var n,r=0,i=t.length;r0)for(var n,r,i=new Array(n),a=0;ae?1:t>=e?0:NaN}bt.prototype={constructor:bt,appendChild:function(t){return this._parent.insertBefore(t,this._next)},insertBefore:function(t,e){return this._parent.insertBefore(t,e)},querySelector:function(t){return this._parent.querySelector(t)},querySelectorAll:function(t){return this._parent.querySelectorAll(t)}};var kt="http://www.w3.org/1999/xhtml";const Tt={svg:"http://www.w3.org/2000/svg",xhtml:kt,xlink:"http://www.w3.org/1999/xlink",xml:"http://www.w3.org/XML/1998/namespace",xmlns:"http://www.w3.org/2000/xmlns/"};function Ct(t){var e=t+="",n=e.indexOf(":");return n>=0&&"xmlns"!==(e=t.slice(0,n))&&(t=t.slice(n+1)),Tt.hasOwnProperty(e)?{space:Tt[e],local:t}:t}function Et(t){return function(){this.removeAttribute(t)}}function St(t){return function(){this.removeAttributeNS(t.space,t.local)}}function At(t,e){return function(){this.setAttribute(t,e)}}function Mt(t,e){return function(){this.setAttributeNS(t.space,t.local,e)}}function Nt(t,e){return function(){var n=e.apply(this,arguments);null==n?this.removeAttribute(t):this.setAttribute(t,n)}}function Dt(t,e){return function(){var n=e.apply(this,arguments);null==n?this.removeAttributeNS(t.space,t.local):this.setAttributeNS(t.space,t.local,n)}}function Bt(t){return t.ownerDocument&&t.ownerDocument.defaultView||t.document&&t||t.defaultView}function Lt(t){return function(){this.style.removeProperty(t)}}function Ot(t,e,n){return function(){this.style.setProperty(t,e,n)}}function It(t,e,n){return function(){var r=e.apply(this,arguments);null==r?this.style.removeProperty(t):this.style.setProperty(t,r,n)}}function Rt(t,e){return t.style.getPropertyValue(e)||Bt(t).getComputedStyle(t,null).getPropertyValue(e)}function Ft(t){return function(){delete this[t]}}function Pt(t,e){return function(){this[t]=e}}function Yt(t,e){return function(){var n=e.apply(this,arguments);null==n?delete this[t]:this[t]=n}}function jt(t){return t.trim().split(/^|\s+/)}function Ut(t){return t.classList||new zt(t)}function zt(t){this._node=t,this._names=jt(t.getAttribute("class")||"")}function $t(t,e){for(var n=Ut(t),r=-1,i=e.length;++r=0&&(this._names.splice(e,1),this._node.setAttribute("class",this._names.join(" ")))},contains:function(t){return this._names.indexOf(t)>=0}};var ue={},le=null;function he(t,e,n){return t=fe(t,e,n),function(e){var n=e.relatedTarget;n&&(n===this||8&n.compareDocumentPosition(this))||t.call(this,e)}}function fe(t,e,n){return function(r){var i=le;le=r;try{t.call(this,this.__data__,e,n)}finally{le=i}}}function de(t){return t.trim().split(/^|\s+/).map((function(t){var e="",n=t.indexOf(".");return n>=0&&(e=t.slice(n+1),t=t.slice(0,n)),{type:t,name:e}}))}function pe(t){return function(){var e=this.__on;if(e){for(var n,r=0,i=-1,a=e.length;r=x&&(x=_+1);!(b=m[x])&&++x=0;)(r=i[a])&&(o&&4^r.compareDocumentPosition(o)&&o.parentNode.insertBefore(r,o),o=r);return this},sort:function(t){function e(e,n){return e&&n?t(e.__data__,n.__data__):!e-!n}t||(t=wt);for(var n=this._groups,r=n.length,i=new Array(r),a=0;a1?this.each((null==e?Lt:"function"==typeof e?It:Ot)(t,e,null==n?"":n)):Rt(this.node(),t)},property:function(t,e){return arguments.length>1?this.each((null==e?Ft:"function"==typeof e?Yt:Pt)(t,e)):this.node()[t]},classed:function(t,e){var n=jt(t+"");if(arguments.length<2){for(var r=Ut(this.node()),i=-1,a=n.length;++i>8&15|e>>4&240,e>>4&15|240&e,(15&e)<<4|15&e,1):8===n?Xe(e>>24&255,e>>16&255,e>>8&255,(255&e)/255):4===n?Xe(e>>12&15|e>>8&240,e>>8&15|e>>4&240,e>>4&15|240&e,((15&e)<<4|15&e)/255):null):(e=Pe.exec(t))?new Ke(e[1],e[2],e[3],1):(e=Ye.exec(t))?new Ke(255*e[1]/100,255*e[2]/100,255*e[3]/100,1):(e=je.exec(t))?Xe(e[1],e[2],e[3],e[4]):(e=Ue.exec(t))?Xe(255*e[1]/100,255*e[2]/100,255*e[3]/100,e[4]):(e=ze.exec(t))?nn(e[1],e[2]/100,e[3]/100,1):(e=$e.exec(t))?nn(e[1],e[2]/100,e[3]/100,e[4]):qe.hasOwnProperty(t)?Ge(qe[t]):"transparent"===t?new Ke(NaN,NaN,NaN,0):null}function Ge(t){return new Ke(t>>16&255,t>>8&255,255&t,1)}function Xe(t,e,n,r){return r<=0&&(t=e=n=NaN),new Ke(t,e,n,r)}function Ze(t){return t instanceof De||(t=Ve(t)),t?new Ke((t=t.rgb()).r,t.g,t.b,t.opacity):new Ke}function Qe(t,e,n,r){return 1===arguments.length?Ze(t):new Ke(t,e,n,null==r?1:r)}function Ke(t,e,n,r){this.r=+t,this.g=+e,this.b=+n,this.opacity=+r}function Je(){return"#"+en(this.r)+en(this.g)+en(this.b)}function tn(){var t=this.opacity;return(1===(t=isNaN(t)?1:Math.max(0,Math.min(1,t)))?"rgb(":"rgba(")+Math.max(0,Math.min(255,Math.round(this.r)||0))+", "+Math.max(0,Math.min(255,Math.round(this.g)||0))+", "+Math.max(0,Math.min(255,Math.round(this.b)||0))+(1===t?")":", "+t+")")}function en(t){return((t=Math.max(0,Math.min(255,Math.round(t)||0)))<16?"0":"")+t.toString(16)}function nn(t,e,n,r){return r<=0?t=e=n=NaN:n<=0||n>=1?t=e=NaN:e<=0&&(t=NaN),new on(t,e,n,r)}function rn(t){if(t instanceof on)return new on(t.h,t.s,t.l,t.opacity);if(t instanceof De||(t=Ve(t)),!t)return new on;if(t instanceof on)return t;var e=(t=t.rgb()).r/255,n=t.g/255,r=t.b/255,i=Math.min(e,n,r),a=Math.max(e,n,r),o=NaN,s=a-i,c=(a+i)/2;return s?(o=e===a?(n-r)/s+6*(n0&&c<1?0:o,new on(o,s,c,t.opacity)}function an(t,e,n,r){return 1===arguments.length?rn(t):new on(t,e,n,null==r?1:r)}function on(t,e,n,r){this.h=+t,this.s=+e,this.l=+n,this.opacity=+r}function sn(t,e,n){return 255*(t<60?e+(n-e)*t/60:t<180?n:t<240?e+(n-e)*(240-t)/60:e)}function cn(t,e,n,r,i){var a=t*t,o=a*t;return((1-3*t+3*a-o)*e+(4-6*a+3*o)*n+(1+3*t+3*a-3*o)*r+o*i)/6}function un(t){var e=t.length-1;return function(n){var r=n<=0?n=0:n>=1?(n=1,e-1):Math.floor(n*e),i=t[r],a=t[r+1],o=r>0?t[r-1]:2*i-a,s=r180||n<-180?n-360*Math.round(n/360):n):hn(isNaN(t)?e:t)}function pn(t,e){var n=e-t;return n?fn(t,n):hn(isNaN(t)?e:t)}Me(De,Ve,{copy:function(t){return Object.assign(new this.constructor,this,t)},displayable:function(){return this.rgb().displayable()},hex:He,formatHex:He,formatHsl:function(){return rn(this).formatHsl()},formatRgb:We,toString:We}),Me(Ke,Qe,Ne(De,{brighter:function(t){return t=null==t?Le:Math.pow(Le,t),new Ke(this.r*t,this.g*t,this.b*t,this.opacity)},darker:function(t){return t=null==t?Be:Math.pow(Be,t),new Ke(this.r*t,this.g*t,this.b*t,this.opacity)},rgb:function(){return this},displayable:function(){return-.5<=this.r&&this.r<255.5&&-.5<=this.g&&this.g<255.5&&-.5<=this.b&&this.b<255.5&&0<=this.opacity&&this.opacity<=1},hex:Je,formatHex:Je,formatRgb:tn,toString:tn})),Me(on,an,Ne(De,{brighter:function(t){return t=null==t?Le:Math.pow(Le,t),new on(this.h,this.s,this.l*t,this.opacity)},darker:function(t){return t=null==t?Be:Math.pow(Be,t),new on(this.h,this.s,this.l*t,this.opacity)},rgb:function(){var t=this.h%360+360*(this.h<0),e=isNaN(t)||isNaN(this.s)?0:this.s,n=this.l,r=n+(n<.5?n:1-n)*e,i=2*n-r;return new Ke(sn(t>=240?t-240:t+120,i,r),sn(t,i,r),sn(t<120?t+240:t-120,i,r),this.opacity)},displayable:function(){return(0<=this.s&&this.s<=1||isNaN(this.s))&&0<=this.l&&this.l<=1&&0<=this.opacity&&this.opacity<=1},formatHsl:function(){var t=this.opacity;return(1===(t=isNaN(t)?1:Math.max(0,Math.min(1,t)))?"hsl(":"hsla(")+(this.h||0)+", "+100*(this.s||0)+"%, "+100*(this.l||0)+"%"+(1===t?")":", "+t+")")}}));const gn=function t(e){var n=function(t){return 1==(t=+t)?pn:function(e,n){return n-e?function(t,e,n){return t=Math.pow(t,n),e=Math.pow(e,n)-t,n=1/n,function(r){return Math.pow(t+r*e,n)}}(e,n,t):hn(isNaN(e)?n:e)}}(e);function r(t,e){var r=n((t=Qe(t)).r,(e=Qe(e)).r),i=n(t.g,e.g),a=n(t.b,e.b),o=pn(t.opacity,e.opacity);return function(e){return t.r=r(e),t.g=i(e),t.b=a(e),t.opacity=o(e),t+""}}return r.gamma=t,r}(1);function yn(t){return function(e){var n,r,i=e.length,a=new Array(i),o=new Array(i),s=new Array(i);for(n=0;na&&(i=e.slice(a,i),s[o]?s[o]+=i:s[++o]=i),(n=n[0])===(r=r[0])?s[o]?s[o]+=r:s[++o]=r:(s[++o]=null,c.push({i:o,x:Tn(n,r)})),a=Sn.lastIndex;return a=0&&e._call.call(null,t),e=e._next;--Rn}function Xn(){jn=(Yn=zn.now())+Un,Rn=Fn=0;try{Gn()}finally{Rn=0,function(){for(var t,e,n=On,r=1/0;n;)n._call?(r>n._time&&(r=n._time),t=n,n=n._next):(e=n._next,n._next=null,n=t?t._next=e:On=e);In=t,Qn(r)}(),jn=0}}function Zn(){var t=zn.now(),e=t-Yn;e>1e3&&(Un-=e,Yn=t)}function Qn(t){Rn||(Fn&&(Fn=clearTimeout(Fn)),t-jn>24?(t<1/0&&(Fn=setTimeout(Xn,t-zn.now()-Un)),Pn&&(Pn=clearInterval(Pn))):(Pn||(Yn=zn.now(),Pn=setInterval(Zn,1e3)),Rn=1,$n(Xn)))}function Kn(t,e,n){var r=new Wn;return e=null==e?0:+e,r.restart((function(n){r.stop(),t(n+e)}),e,n),r}Wn.prototype=Vn.prototype={constructor:Wn,restart:function(t,e,n){if("function"!=typeof t)throw new TypeError("callback is not a function");n=(null==n?qn():+n)+(null==e?0:+e),this._next||In===this||(In?In._next=this:On=this,In=this),this._call=t,this._time=n,Qn()},stop:function(){this._call&&(this._call=null,this._time=1/0,Qn())}};var Jn=ft("start","end","cancel","interrupt"),tr=[];function er(t,e,n,r,i,a){var o=t.__transition;if(o){if(n in o)return}else t.__transition={};!function(t,e,n){var r,i=t.__transition;function a(c){var u,l,h,f;if(1!==n.state)return s();for(u in i)if((f=i[u]).name===n.name){if(3===f.state)return Kn(a);4===f.state?(f.state=6,f.timer.stop(),f.on.call("interrupt",t,t.__data__,f.index,f.group),delete i[u]):+u0)throw new Error("too late; already scheduled");return n}function rr(t,e){var n=ir(t,e);if(n.state>3)throw new Error("too late; already running");return n}function ir(t,e){var n=t.__transition;if(!n||!(n=n[e]))throw new Error("transition not found");return n}function ar(t,e){var n,r,i,a=t.__transition,o=!0;if(a){for(i in e=null==e?null:e+"",a)(n=a[i]).name===e?(r=n.state>2&&n.state<5,n.state=6,n.timer.stop(),n.on.call(r?"interrupt":"cancel",t,t.__data__,n.index,n.group),delete a[i]):o=!1;o&&delete t.__transition}}var or,sr,cr,ur,lr=180/Math.PI,hr={translateX:0,translateY:0,rotate:0,skewX:0,scaleX:1,scaleY:1};function fr(t,e,n,r,i,a){var o,s,c;return(o=Math.sqrt(t*t+e*e))&&(t/=o,e/=o),(c=t*n+e*r)&&(n-=t*c,r-=e*c),(s=Math.sqrt(n*n+r*r))&&(n/=s,r/=s,c/=s),t*r180?e+=360:e-t>180&&(t+=360),a.push({i:n.push(i(n)+"rotate(",null,r)-2,x:Tn(t,e)})):e&&n.push(i(n)+"rotate("+e+r)}(a.rotate,o.rotate,s,c),function(t,e,n,a){t!==e?a.push({i:n.push(i(n)+"skewX(",null,r)-2,x:Tn(t,e)}):e&&n.push(i(n)+"skewX("+e+r)}(a.skewX,o.skewX,s,c),function(t,e,n,r,a,o){if(t!==n||e!==r){var s=a.push(i(a)+"scale(",null,",",null,")");o.push({i:s-4,x:Tn(t,n)},{i:s-2,x:Tn(e,r)})}else 1===n&&1===r||a.push(i(a)+"scale("+n+","+r+")")}(a.scaleX,a.scaleY,o.scaleX,o.scaleY,s,c),a=o=null,function(t){for(var e,n=-1,r=c.length;++n=0&&(t=t.slice(0,e)),!t||"start"===t}))}(e)?nr:rr;return function(){var o=a(this,t),s=o.on;s!==r&&(i=(r=s).copy()).on(e,n),o.on=i}}var Rr=ke.prototype.constructor;function Fr(t){return function(){this.style.removeProperty(t)}}function Pr(t,e,n){return function(r){this.style.setProperty(t,e.call(this,r),n)}}function Yr(t,e,n){var r,i;function a(){var a=e.apply(this,arguments);return a!==i&&(r=(i=a)&&Pr(t,a,n)),r}return a._value=e,a}function jr(t){return function(e){this.textContent=t.call(this,e)}}function Ur(t){var e,n;function r(){var r=t.apply(this,arguments);return r!==n&&(e=(n=r)&&jr(r)),e}return r._value=t,r}var zr=0;function $r(t,e,n,r){this._groups=t,this._parents=e,this._name=n,this._id=r}function qr(t){return ke().transition(t)}function Hr(){return++zr}var Wr=ke.prototype;function Vr(t){return t*t*t}function Gr(t){return--t*t*t+1}function Xr(t){return((t*=2)<=1?t*t*t:(t-=2)*t*t+2)/2}$r.prototype=qr.prototype={constructor:$r,select:function(t){var e=this._name,n=this._id;"function"!=typeof t&&(t=pt(t));for(var r=this._groups,i=r.length,a=new Array(i),o=0;o1&&n.name===e)return new $r([[t]],Kr,e,+r);return null}function ti(t){return function(){return t}}function ei(t,e,n){this.target=t,this.type=e,this.selection=n}function ni(){le.stopImmediatePropagation()}function ri(){le.preventDefault(),le.stopImmediatePropagation()}var ii={name:"drag"},ai={name:"space"},oi={name:"handle"},si={name:"center"};function ci(t){return[+t[0],+t[1]]}function ui(t){return[ci(t[0]),ci(t[1])]}function li(t){return function(e){return Bn(e,le.touches,t)}}var hi={name:"x",handles:["w","e"].map(bi),input:function(t,e){return null==t?null:[[+t[0],e[0][1]],[+t[1],e[1][1]]]},output:function(t){return t&&[t[0][0],t[1][0]]}},fi={name:"y",handles:["n","s"].map(bi),input:function(t,e){return null==t?null:[[e[0][0],+t[0]],[e[1][0],+t[1]]]},output:function(t){return t&&[t[0][1],t[1][1]]}},di={name:"xy",handles:["n","w","e","s","nw","ne","sw","se"].map(bi),input:function(t){return null==t?null:ui(t)},output:function(t){return t}},pi={overlay:"crosshair",selection:"move",n:"ns-resize",e:"ew-resize",s:"ns-resize",w:"ew-resize",nw:"nwse-resize",ne:"nesw-resize",se:"nwse-resize",sw:"nesw-resize"},gi={e:"w",w:"e",nw:"ne",ne:"nw",se:"sw",sw:"se"},yi={n:"s",s:"n",nw:"sw",ne:"se",se:"ne",sw:"nw"},mi={overlay:1,selection:1,n:null,e:1,s:null,w:-1,nw:-1,ne:1,se:1,sw:-1},vi={overlay:1,selection:1,n:-1,e:null,s:1,w:null,nw:-1,ne:-1,se:1,sw:1};function bi(t){return{type:t}}function _i(){return!le.ctrlKey&&!le.button}function xi(){var t=this.ownerSVGElement||this;return t.hasAttribute("viewBox")?[[(t=t.viewBox.baseVal).x,t.y],[t.x+t.width,t.y+t.height]]:[[0,0],[t.width.baseVal.value,t.height.baseVal.value]]}function wi(){return navigator.maxTouchPoints||"ontouchstart"in this}function ki(t){for(;!t.__brush;)if(!(t=t.parentNode))return;return t.__brush}function Ti(t){return t[0][0]===t[1][0]||t[0][1]===t[1][1]}function Ci(t){var e=t.__brush;return e?e.dim.output(e.selection):null}function Ei(){return Mi(hi)}function Si(){return Mi(fi)}function Ai(){return Mi(di)}function Mi(t){var e,n=xi,r=_i,i=wi,a=!0,o=ft("start","brush","end"),s=6;function c(e){var n=e.property("__brush",g).selectAll(".overlay").data([bi("overlay")]);n.enter().append("rect").attr("class","overlay").attr("pointer-events","all").attr("cursor",pi.overlay).merge(n).each((function(){var t=ki(this).extent;Te(this).attr("x",t[0][0]).attr("y",t[0][1]).attr("width",t[1][0]-t[0][0]).attr("height",t[1][1]-t[0][1])})),e.selectAll(".selection").data([bi("selection")]).enter().append("rect").attr("class","selection").attr("cursor",pi.selection).attr("fill","#777").attr("fill-opacity",.3).attr("stroke","#fff").attr("shape-rendering","crispEdges");var r=e.selectAll(".handle").data(t.handles,(function(t){return t.type}));r.exit().remove(),r.enter().append("rect").attr("class",(function(t){return"handle handle--"+t.type})).attr("cursor",(function(t){return pi[t.type]})),e.each(u).attr("fill","none").attr("pointer-events","all").on("mousedown.brush",f).filter(i).on("touchstart.brush",f).on("touchmove.brush",d).on("touchend.brush touchcancel.brush",p).style("touch-action","none").style("-webkit-tap-highlight-color","rgba(0,0,0,0)")}function u(){var t=Te(this),e=ki(this).selection;e?(t.selectAll(".selection").style("display",null).attr("x",e[0][0]).attr("y",e[0][1]).attr("width",e[1][0]-e[0][0]).attr("height",e[1][1]-e[0][1]),t.selectAll(".handle").style("display",null).attr("x",(function(t){return"e"===t.type[t.type.length-1]?e[1][0]-s/2:e[0][0]-s/2})).attr("y",(function(t){return"s"===t.type[0]?e[1][1]-s/2:e[0][1]-s/2})).attr("width",(function(t){return"n"===t.type||"s"===t.type?e[1][0]-e[0][0]+s:s})).attr("height",(function(t){return"e"===t.type||"w"===t.type?e[1][1]-e[0][1]+s:s}))):t.selectAll(".selection,.handle").style("display","none").attr("x",null).attr("y",null).attr("width",null).attr("height",null)}function l(t,e,n){var r=t.__brush.emitter;return!r||n&&r.clean?new h(t,e,n):r}function h(t,e,n){this.that=t,this.args=e,this.state=t.__brush,this.active=0,this.clean=n}function f(){if((!e||le.touches)&&r.apply(this,arguments)){var n,i,o,s,c,h,f,d,p,g,y,m=this,v=le.target.__data__.type,b="selection"===(a&&le.metaKey?v="overlay":v)?ii:a&&le.altKey?si:oi,_=t===fi?null:mi[v],x=t===hi?null:vi[v],w=ki(m),k=w.extent,T=w.selection,C=k[0][0],E=k[0][1],S=k[1][0],A=k[1][1],M=0,N=0,D=_&&x&&a&&le.shiftKey,B=le.touches?li(le.changedTouches[0].identifier):Ln,L=B(m),O=L,I=l(m,arguments,!0).beforestart();"overlay"===v?(T&&(p=!0),w.selection=T=[[n=t===fi?C:L[0],o=t===hi?E:L[1]],[c=t===fi?S:n,f=t===hi?A:o]]):(n=T[0][0],o=T[0][1],c=T[1][0],f=T[1][1]),i=n,s=o,h=c,d=f;var R=Te(m).attr("pointer-events","none"),F=R.selectAll(".overlay").attr("cursor",pi[v]);if(le.touches)I.moved=Y,I.ended=U;else{var P=Te(le.view).on("mousemove.brush",Y,!0).on("mouseup.brush",U,!0);a&&P.on("keydown.brush",z,!0).on("keyup.brush",$,!0),Se(le.view)}ni(),ar(m),u.call(m),I.start()}function Y(){var t=B(m);!D||g||y||(Math.abs(t[0]-O[0])>Math.abs(t[1]-O[1])?y=!0:g=!0),O=t,p=!0,ri(),j()}function j(){var t;switch(M=O[0]-L[0],N=O[1]-L[1],b){case ai:case ii:_&&(M=Math.max(C-n,Math.min(S-c,M)),i=n+M,h=c+M),x&&(N=Math.max(E-o,Math.min(A-f,N)),s=o+N,d=f+N);break;case oi:_<0?(M=Math.max(C-n,Math.min(S-n,M)),i=n+M,h=c):_>0&&(M=Math.max(C-c,Math.min(S-c,M)),i=n,h=c+M),x<0?(N=Math.max(E-o,Math.min(A-o,N)),s=o+N,d=f):x>0&&(N=Math.max(E-f,Math.min(A-f,N)),s=o,d=f+N);break;case si:_&&(i=Math.max(C,Math.min(S,n-M*_)),h=Math.max(C,Math.min(S,c+M*_))),x&&(s=Math.max(E,Math.min(A,o-N*x)),d=Math.max(E,Math.min(A,f+N*x)))}h0&&(n=i-M),x<0?f=d-N:x>0&&(o=s-N),b=ai,F.attr("cursor",pi.selection),j());break;default:return}ri()}function $(){switch(le.keyCode){case 16:D&&(g=y=D=!1,j());break;case 18:b===si&&(_<0?c=h:_>0&&(n=i),x<0?f=d:x>0&&(o=s),b=oi,j());break;case 32:b===ai&&(le.altKey?(_&&(c=h-M*_,n=i+M*_),x&&(f=d-N*x,o=s+N*x),b=si):(_<0?c=h:_>0&&(n=i),x<0?f=d:x>0&&(o=s),b=oi),F.attr("cursor",pi[v]),j());break;default:return}ri()}}function d(){l(this,arguments).moved()}function p(){l(this,arguments).ended()}function g(){var e=this.__brush||{selection:null};return e.extent=ui(n.apply(this,arguments)),e.dim=t,e}return c.move=function(e,n){e.selection?e.on("start.brush",(function(){l(this,arguments).beforestart().start()})).on("interrupt.brush end.brush",(function(){l(this,arguments).end()})).tween("brush",(function(){var e=this,r=e.__brush,i=l(e,arguments),a=r.selection,o=t.input("function"==typeof n?n.apply(this,arguments):n,r.extent),s=Mn(a,o);function c(t){r.selection=1===t&&null===o?null:s(t),u.call(e),i.brush()}return null!==a&&null!==o?c:c(1)})):e.each((function(){var e=this,r=arguments,i=e.__brush,a=t.input("function"==typeof n?n.apply(e,r):n,i.extent),o=l(e,r).beforestart();ar(e),i.selection=null===a?null:a,u.call(e),o.start().brush().end()}))},c.clear=function(t){c.move(t,null)},h.prototype={beforestart:function(){return 1==++this.active&&(this.state.emitter=this,this.starting=!0),this},start:function(){return this.starting?(this.starting=!1,this.emit("start")):this.emit("brush"),this},brush:function(){return this.emit("brush"),this},end:function(){return 0==--this.active&&(delete this.state.emitter,this.emit("end")),this},emit:function(e){ye(new ei(c,e,t.output(this.state.selection)),o.apply,o,[e,this.that,this.args])}},c.extent=function(t){return arguments.length?(n="function"==typeof t?t:ti(ui(t)),c):n},c.filter=function(t){return arguments.length?(r="function"==typeof t?t:ti(!!t),c):r},c.touchable=function(t){return arguments.length?(i="function"==typeof t?t:ti(!!t),c):i},c.handleSize=function(t){return arguments.length?(s=+t,c):s},c.keyModifiers=function(t){return arguments.length?(a=!!t,c):a},c.on=function(){var t=o.on.apply(o,arguments);return t===o?c:t},c}var Ni=Math.cos,Di=Math.sin,Bi=Math.PI,Li=Bi/2,Oi=2*Bi,Ii=Math.max;function Ri(t){return function(e,n){return t(e.source.value+e.target.value,n.source.value+n.target.value)}}function Fi(){var t=0,e=null,n=null,r=null;function i(i){var a,o,s,c,u,l,h=i.length,f=[],d=k(h),p=[],g=[],y=g.groups=new Array(h),m=new Array(h*h);for(a=0,u=-1;++uzi)if(Math.abs(l*s-c*u)>zi&&i){var f=n-a,d=r-o,p=s*s+c*c,g=f*f+d*d,y=Math.sqrt(p),m=Math.sqrt(h),v=i*Math.tan((ji-Math.acos((p+h-g)/(2*y*m)))/2),b=v/m,_=v/y;Math.abs(b-1)>zi&&(this._+="L"+(t+b*u)+","+(e+b*l)),this._+="A"+i+","+i+",0,0,"+ +(l*f>u*d)+","+(this._x1=t+_*s)+","+(this._y1=e+_*c)}else this._+="L"+(this._x1=t)+","+(this._y1=e)},arc:function(t,e,n,r,i,a){t=+t,e=+e,a=!!a;var o=(n=+n)*Math.cos(r),s=n*Math.sin(r),c=t+o,u=e+s,l=1^a,h=a?r-i:i-r;if(n<0)throw new Error("negative radius: "+n);null===this._x1?this._+="M"+c+","+u:(Math.abs(this._x1-c)>zi||Math.abs(this._y1-u)>zi)&&(this._+="L"+c+","+u),n&&(h<0&&(h=h%Ui+Ui),h>$i?this._+="A"+n+","+n+",0,1,"+l+","+(t-o)+","+(e-s)+"A"+n+","+n+",0,1,"+l+","+(this._x1=c)+","+(this._y1=u):h>zi&&(this._+="A"+n+","+n+",0,"+ +(h>=ji)+","+l+","+(this._x1=t+n*Math.cos(i))+","+(this._y1=e+n*Math.sin(i))))},rect:function(t,e,n,r){this._+="M"+(this._x0=this._x1=+t)+","+(this._y0=this._y1=+e)+"h"+ +n+"v"+ +r+"h"+-n+"Z"},toString:function(){return this._}};const Wi=Hi;function Vi(t){return t.source}function Gi(t){return t.target}function Xi(t){return t.radius}function Zi(t){return t.startAngle}function Qi(t){return t.endAngle}function Ki(){var t=Vi,e=Gi,n=Xi,r=Zi,i=Qi,a=null;function o(){var o,s=Pi.call(arguments),c=t.apply(this,s),u=e.apply(this,s),l=+n.apply(this,(s[0]=c,s)),h=r.apply(this,s)-Li,f=i.apply(this,s)-Li,d=l*Ni(h),p=l*Di(h),g=+n.apply(this,(s[0]=u,s)),y=r.apply(this,s)-Li,m=i.apply(this,s)-Li;if(a||(a=o=Wi()),a.moveTo(d,p),a.arc(0,0,l,h,f),h===y&&f===m||(a.quadraticCurveTo(0,0,g*Ni(y),g*Di(y)),a.arc(0,0,g,y,m)),a.quadraticCurveTo(0,0,d,p),a.closePath(),o)return a=null,o+""||null}return o.radius=function(t){return arguments.length?(n="function"==typeof t?t:Yi(+t),o):n},o.startAngle=function(t){return arguments.length?(r="function"==typeof t?t:Yi(+t),o):r},o.endAngle=function(t){return arguments.length?(i="function"==typeof t?t:Yi(+t),o):i},o.source=function(e){return arguments.length?(t=e,o):t},o.target=function(t){return arguments.length?(e=t,o):e},o.context=function(t){return arguments.length?(a=null==t?null:t,o):a},o}var Ji="$";function ta(){}function ea(t,e){var n=new ta;if(t instanceof ta)t.each((function(t,e){n.set(e,t)}));else if(Array.isArray(t)){var r,i=-1,a=t.length;if(null==e)for(;++i=r.length)return null!=t&&n.sort(t),null!=e?e(n):n;for(var c,u,l,h=-1,f=n.length,d=r[i++],p=na(),g=o();++hr.length)return t;var a,s=i[n-1];return null!=e&&n>=r.length?a=t.entries():(a=[],t.each((function(t,e){a.push({key:e,values:o(t,n)})}))),null!=s?a.sort((function(t,e){return s(t.key,e.key)})):a}return n={object:function(t){return a(t,0,ia,aa)},map:function(t){return a(t,0,oa,sa)},entries:function(t){return o(a(t,0,oa,sa),0)},key:function(t){return r.push(t),n},sortKeys:function(t){return i[r.length-1]=t,n},sortValues:function(e){return t=e,n},rollup:function(t){return e=t,n}}}function ia(){return{}}function aa(t,e,n){t[e]=n}function oa(){return na()}function sa(t,e,n){t.set(e,n)}function ca(){}var ua=na.prototype;function la(t,e){var n=new ca;if(t instanceof ca)t.each((function(t){n.add(t)}));else if(t){var r=-1,i=t.length;if(null==e)for(;++r.008856451679035631?Math.pow(t,1/3):t/xa+ba}function Sa(t){return t>_a?t*t*t:xa*(t-ba)}function Aa(t){return 255*(t<=.0031308?12.92*t:1.055*Math.pow(t,1/2.4)-.055)}function Ma(t){return(t/=255)<=.04045?t/12.92:Math.pow((t+.055)/1.055,2.4)}function Na(t){if(t instanceof La)return new La(t.h,t.c,t.l,t.opacity);if(t instanceof Ca||(t=wa(t)),0===t.a&&0===t.b)return new La(NaN,0r!=d>r&&n<(f-u)*(r-l)/(d-l)+u&&(i=-i)}return i}function Qa(t,e,n){var r,i,a,o;return function(t,e,n){return(e[0]-t[0])*(n[1]-t[1])==(n[0]-t[0])*(e[1]-t[1])}(t,e,n)&&(i=t[r=+(t[0]===e[0])],a=n[r],o=e[r],i<=a&&a<=o||o<=a&&a<=i)}function Ka(){}var Ja=[[],[[[1,1.5],[.5,1]]],[[[1.5,1],[1,1.5]]],[[[1.5,1],[.5,1]]],[[[1,.5],[1.5,1]]],[[[1,1.5],[.5,1]],[[1,.5],[1.5,1]]],[[[1,.5],[1,1.5]]],[[[1,.5],[.5,1]]],[[[.5,1],[1,.5]]],[[[1,1.5],[1,.5]]],[[[.5,1],[1,.5]],[[1.5,1],[1,1.5]]],[[[1.5,1],[1,.5]]],[[[.5,1],[1.5,1]]],[[[1,1.5],[1.5,1]]],[[[.5,1],[1,1.5]]],[]];function to(){var t=1,e=1,n=N,r=s;function i(t){var e=n(t);if(Array.isArray(e))e=e.slice().sort(Va);else{var r=m(t),i=r[0],o=r[1];e=M(i,o,e),e=k(Math.floor(i/e)*e,Math.floor(o/e)*e,e)}return e.map((function(e){return a(t,e)}))}function a(n,i){var a=[],s=[];return function(n,r,i){var a,s,c,u,l,h,f=new Array,d=new Array;for(a=s=-1,u=n[0]>=r,Ja[u<<1].forEach(p);++a=r,Ja[c|u<<1].forEach(p);for(Ja[u<<0].forEach(p);++s=r,l=n[s*t]>=r,Ja[u<<1|l<<2].forEach(p);++a=r,h=l,l=n[s*t+a+1]>=r,Ja[c|u<<1|l<<2|h<<3].forEach(p);Ja[u|l<<3].forEach(p)}for(a=-1,l=n[s*t]>=r,Ja[l<<2].forEach(p);++a=r,Ja[l<<2|h<<3].forEach(p);function p(t){var e,n,r=[t[0][0]+a,t[0][1]+s],c=[t[1][0]+a,t[1][1]+s],u=o(r),l=o(c);(e=d[u])?(n=f[l])?(delete d[e.end],delete f[n.start],e===n?(e.ring.push(c),i(e.ring)):f[e.start]=d[n.end]={start:e.start,end:n.end,ring:e.ring.concat(n.ring)}):(delete d[e.end],e.ring.push(c),d[e.end=l]=e):(e=f[l])?(n=d[u])?(delete f[e.start],delete d[n.end],e===n?(e.ring.push(c),i(e.ring)):f[n.start]=d[e.end]={start:n.start,end:e.end,ring:n.ring.concat(e.ring)}):(delete f[e.start],e.ring.unshift(r),f[e.start=u]=e):f[u]=d[l]={start:u,end:l,ring:[r,c]}}Ja[l<<3].forEach(p)}(n,i,(function(t){r(t,n,i),function(t){for(var e=0,n=t.length,r=t[n-1][1]*t[0][0]-t[n-1][0]*t[0][1];++e0?a.push([t]):s.push(t)})),s.forEach((function(t){for(var e,n=0,r=a.length;n0&&o0&&s0&&a>0))throw new Error("invalid size");return t=r,e=a,i},i.thresholds=function(t){return arguments.length?(n="function"==typeof t?t:Array.isArray(t)?Ga(Wa.call(t)):Ga(t),i):n},i.smooth=function(t){return arguments.length?(r=t?s:Ka,i):r===s},i}function eo(t,e,n){for(var r=t.width,i=t.height,a=1+(n<<1),o=0;o=n&&(s>=a&&(c-=t.data[s-a+o*r]),e.data[s-n+o*r]=c/Math.min(s+1,r-1+a-s,a))}function no(t,e,n){for(var r=t.width,i=t.height,a=1+(n<<1),o=0;o=n&&(s>=a&&(c-=t.data[o+(s-a)*r]),e.data[o+(s-n)*r]=c/Math.min(s+1,i-1+a-s,a))}function ro(t){return t[0]}function io(t){return t[1]}function ao(){return 1}function oo(){var t=ro,e=io,n=ao,r=960,i=500,a=20,o=2,s=3*a,c=r+2*s>>o,u=i+2*s>>o,l=Ga(20);function h(r){var i=new Float32Array(c*u),h=new Float32Array(c*u);r.forEach((function(r,a,l){var h=+t(r,a,l)+s>>o,f=+e(r,a,l)+s>>o,d=+n(r,a,l);h>=0&&h=0&&f>o),no({width:c,height:u,data:h},{width:c,height:u,data:i},a>>o),eo({width:c,height:u,data:i},{width:c,height:u,data:h},a>>o),no({width:c,height:u,data:h},{width:c,height:u,data:i},a>>o),eo({width:c,height:u,data:i},{width:c,height:u,data:h},a>>o),no({width:c,height:u,data:h},{width:c,height:u,data:i},a>>o);var d=l(i);if(!Array.isArray(d)){var p=I(i);d=M(0,p,d),(d=k(0,Math.floor(p/d)*d,d)).shift()}return to().thresholds(d).size([c,u])(i).map(f)}function f(t){return t.value*=Math.pow(2,-2*o),t.coordinates.forEach(d),t}function d(t){t.forEach(p)}function p(t){t.forEach(g)}function g(t){t[0]=t[0]*Math.pow(2,o)-s,t[1]=t[1]*Math.pow(2,o)-s}function y(){return c=r+2*(s=3*a)>>o,u=i+2*s>>o,h}return h.x=function(e){return arguments.length?(t="function"==typeof e?e:Ga(+e),h):t},h.y=function(t){return arguments.length?(e="function"==typeof t?t:Ga(+t),h):e},h.weight=function(t){return arguments.length?(n="function"==typeof t?t:Ga(+t),h):n},h.size=function(t){if(!arguments.length)return[r,i];var e=Math.ceil(t[0]),n=Math.ceil(t[1]);if(!(e>=0||e>=0))throw new Error("invalid size");return r=e,i=n,y()},h.cellSize=function(t){if(!arguments.length)return 1<=1))throw new Error("invalid cell size");return o=Math.floor(Math.log(t)/Math.LN2),y()},h.thresholds=function(t){return arguments.length?(l="function"==typeof t?t:Array.isArray(t)?Ga(Wa.call(t)):Ga(t),h):l},h.bandwidth=function(t){if(!arguments.length)return Math.sqrt(a*(a+1));if(!((t=+t)>=0))throw new Error("invalid bandwidth");return a=Math.round((Math.sqrt(4*t*t+1)-1)/2),y()},h}function so(t){return function(){return t}}function co(t,e,n,r,i,a,o,s,c,u){this.target=t,this.type=e,this.subject=n,this.identifier=r,this.active=i,this.x=a,this.y=o,this.dx=s,this.dy=c,this._=u}function uo(){return!le.ctrlKey&&!le.button}function lo(){return this.parentNode}function ho(t){return null==t?{x:le.x,y:le.y}:t}function fo(){return navigator.maxTouchPoints||"ontouchstart"in this}function po(){var t,e,n,r,i=uo,a=lo,o=ho,s=fo,c={},u=ft("start","drag","end"),l=0,h=0;function f(t){t.on("mousedown.drag",d).filter(s).on("touchstart.drag",y).on("touchmove.drag",m).on("touchend.drag touchcancel.drag",v).style("touch-action","none").style("-webkit-tap-highlight-color","rgba(0,0,0,0)")}function d(){if(!r&&i.apply(this,arguments)){var o=b("mouse",a.apply(this,arguments),Ln,this,arguments);o&&(Te(le.view).on("mousemove.drag",p,!0).on("mouseup.drag",g,!0),Se(le.view),Ce(),n=!1,t=le.clientX,e=le.clientY,o("start"))}}function p(){if(Ee(),!n){var r=le.clientX-t,i=le.clientY-e;n=r*r+i*i>h}c.mouse("drag")}function g(){Te(le.view).on("mousemove.drag mouseup.drag",null),Ae(le.view,n),Ee(),c.mouse("end")}function y(){if(i.apply(this,arguments)){var t,e,n=le.changedTouches,r=a.apply(this,arguments),o=n.length;for(t=0;t=a?c=!0:10===(r=t.charCodeAt(o++))?u=!0:13===r&&(u=!0,10===t.charCodeAt(o)&&++o),t.slice(i+1,e-1).replace(/""/g,'"')}for(;o9999?"+"+bo(t,6):bo(t,4)}(t.getUTCFullYear())+"-"+bo(t.getUTCMonth()+1,2)+"-"+bo(t.getUTCDate(),2)+(i?"T"+bo(e,2)+":"+bo(n,2)+":"+bo(r,2)+"."+bo(i,3)+"Z":r?"T"+bo(e,2)+":"+bo(n,2)+":"+bo(r,2)+"Z":n||e?"T"+bo(e,2)+":"+bo(n,2)+"Z":"")}(t):e.test(t+="")?'"'+t.replace(/"/g,'""')+'"':t}return{parse:function(t,e){var n,i,a=r(t,(function(t,r){if(n)return n(t,r-1);i=t,n=e?function(t,e){var n=mo(t);return function(r,i){return e(n(r),i,t)}}(t,e):mo(t)}));return a.columns=i||[],a},parseRows:r,format:function(e,n){return null==n&&(n=vo(e)),[n.map(o).join(t)].concat(i(e,n)).join("\n")},formatBody:function(t,e){return null==e&&(e=vo(t)),i(t,e).join("\n")},formatRows:function(t){return t.map(a).join("\n")},formatRow:a,formatValue:o}}var xo=_o(","),wo=xo.parse,ko=xo.parseRows,To=xo.format,Co=xo.formatBody,Eo=xo.formatRows,So=xo.formatRow,Ao=xo.formatValue,Mo=_o("\t"),No=Mo.parse,Do=Mo.parseRows,Bo=Mo.format,Lo=Mo.formatBody,Oo=Mo.formatRows,Io=Mo.formatRow,Ro=Mo.formatValue;function Fo(t){for(var e in t){var n,r,i=t[e].trim();if(i)if("true"===i)i=!0;else if("false"===i)i=!1;else if("NaN"===i)i=NaN;else if(isNaN(n=+i)){if(!(r=i.match(/^([-+]\d{2})?\d{4}(-\d{2}(-\d{2})?)?(T\d{2}:\d{2}(:\d{2}(\.\d{3})?)?(Z|[-+]\d{2}:\d{2})?)?$/)))continue;Po&&r[4]&&!r[7]&&(i=i.replace(/-/g,"/").replace(/T/," ")),i=new Date(i)}else i=n;else i=null;t[e]=i}return t}var Po=new Date("2019-01-01T00:00").getHours()||new Date("2019-07-01T00:00").getHours();function Yo(t){return+t}function jo(t){return t*t}function Uo(t){return t*(2-t)}function zo(t){return((t*=2)<=1?t*t:--t*(2-t)+1)/2}var $o=function t(e){function n(t){return Math.pow(t,e)}return e=+e,n.exponent=t,n}(3),qo=function t(e){function n(t){return 1-Math.pow(1-t,e)}return e=+e,n.exponent=t,n}(3),Ho=function t(e){function n(t){return((t*=2)<=1?Math.pow(t,e):2-Math.pow(2-t,e))/2}return e=+e,n.exponent=t,n}(3),Wo=Math.PI,Vo=Wo/2;function Go(t){return 1==+t?1:1-Math.cos(t*Vo)}function Xo(t){return Math.sin(t*Vo)}function Zo(t){return(1-Math.cos(Wo*t))/2}function Qo(t){return 1.0009775171065494*(Math.pow(2,-10*t)-.0009765625)}function Ko(t){return Qo(1-+t)}function Jo(t){return 1-Qo(t)}function ts(t){return((t*=2)<=1?Qo(1-t):2-Qo(t-1))/2}function es(t){return 1-Math.sqrt(1-t*t)}function ns(t){return Math.sqrt(1- --t*t)}function rs(t){return((t*=2)<=1?1-Math.sqrt(1-t*t):Math.sqrt(1-(t-=2)*t)+1)/2}var is=7.5625;function as(t){return 1-os(1-t)}function os(t){return(t=+t)<.36363636363636365?is*t*t:t<.7272727272727273?is*(t-=.5454545454545454)*t+.75:t<.9090909090909091?is*(t-=.8181818181818182)*t+.9375:is*(t-=.9545454545454546)*t+.984375}function ss(t){return((t*=2)<=1?1-os(1-t):os(t-1)+1)/2}var cs=1.70158,us=function t(e){function n(t){return(t=+t)*t*(e*(t-1)+t)}return e=+e,n.overshoot=t,n}(cs),ls=function t(e){function n(t){return--t*t*((t+1)*e+t)+1}return e=+e,n.overshoot=t,n}(cs),hs=function t(e){function n(t){return((t*=2)<1?t*t*((e+1)*t-e):(t-=2)*t*((e+1)*t+e)+2)/2}return e=+e,n.overshoot=t,n}(cs),fs=2*Math.PI,ds=function t(e,n){var r=Math.asin(1/(e=Math.max(1,e)))*(n/=fs);function i(t){return e*Qo(- --t)*Math.sin((r-t)/n)}return i.amplitude=function(e){return t(e,n*fs)},i.period=function(n){return t(e,n)},i}(1,.3),ps=function t(e,n){var r=Math.asin(1/(e=Math.max(1,e)))*(n/=fs);function i(t){return 1-e*Qo(t=+t)*Math.sin((t+r)/n)}return i.amplitude=function(e){return t(e,n*fs)},i.period=function(n){return t(e,n)},i}(1,.3),gs=function t(e,n){var r=Math.asin(1/(e=Math.max(1,e)))*(n/=fs);function i(t){return((t=2*t-1)<0?e*Qo(-t)*Math.sin((r-t)/n):2-e*Qo(t)*Math.sin((r+t)/n))/2}return i.amplitude=function(e){return t(e,n*fs)},i.period=function(n){return t(e,n)},i}(1,.3);function ys(t){if(!t.ok)throw new Error(t.status+" "+t.statusText);return t.blob()}function ms(t,e){return fetch(t,e).then(ys)}function vs(t){if(!t.ok)throw new Error(t.status+" "+t.statusText);return t.arrayBuffer()}function bs(t,e){return fetch(t,e).then(vs)}function _s(t){if(!t.ok)throw new Error(t.status+" "+t.statusText);return t.text()}function xs(t,e){return fetch(t,e).then(_s)}function ws(t){return function(e,n,r){return 2===arguments.length&&"function"==typeof n&&(r=n,n=void 0),xs(e,n).then((function(e){return t(e,r)}))}}function ks(t,e,n,r){3===arguments.length&&"function"==typeof n&&(r=n,n=void 0);var i=_o(t);return xs(e,n).then((function(t){return i.parse(t,r)}))}var Ts=ws(wo),Cs=ws(No);function Es(t,e){return new Promise((function(n,r){var i=new Image;for(var a in e)i[a]=e[a];i.onerror=r,i.onload=function(){n(i)},i.src=t}))}function Ss(t){if(!t.ok)throw new Error(t.status+" "+t.statusText);if(204!==t.status&&205!==t.status)return t.json()}function As(t,e){return fetch(t,e).then(Ss)}function Ms(t){return function(e,n){return xs(e,n).then((function(e){return(new DOMParser).parseFromString(e,t)}))}}const Ns=Ms("application/xml");var Ds=Ms("text/html"),Bs=Ms("image/svg+xml");function Ls(t,e){var n;function r(){var r,i,a=n.length,o=0,s=0;for(r=0;r=(a=(g+m)/2))?g=a:m=a,(l=n>=(o=(y+v)/2))?y=o:v=o,i=d,!(d=d[h=l<<1|u]))return i[h]=p,t;if(s=+t._x.call(null,d.data),c=+t._y.call(null,d.data),e===s&&n===c)return p.next=d,i?i[h]=p:t._root=p,t;do{i=i?i[h]=new Array(4):t._root=new Array(4),(u=e>=(a=(g+m)/2))?g=a:m=a,(l=n>=(o=(y+v)/2))?y=o:v=o}while((h=l<<1|u)==(f=(c>=o)<<1|s>=a));return i[f]=d,i[h]=p,t}function Fs(t,e,n,r,i){this.node=t,this.x0=e,this.y0=n,this.x1=r,this.y1=i}function Ps(t){return t[0]}function Ys(t){return t[1]}function js(t,e,n){var r=new Us(null==e?Ps:e,null==n?Ys:n,NaN,NaN,NaN,NaN);return null==t?r:r.addAll(t)}function Us(t,e,n,r,i,a){this._x=t,this._y=e,this._x0=n,this._y0=r,this._x1=i,this._y1=a,this._root=void 0}function zs(t){for(var e={data:t.data},n=e;t=t.next;)n=n.next={data:t.data};return e}var $s=js.prototype=Us.prototype;function qs(t){return t.x+t.vx}function Hs(t){return t.y+t.vy}function Ws(t){var e,n,r=1,i=1;function a(){for(var t,a,s,c,u,l,h,f=e.length,d=0;dc+d||iu+d||as.index){var p=c-o.x-o.vx,g=u-o.y-o.vy,y=p*p+g*g;yt.r&&(t.r=t[e].r)}function s(){if(e){var r,i,a=e.length;for(n=new Array(a),r=0;rl&&(l=r),ih&&(h=i));if(c>l||u>h)return this;for(this.cover(c,u).cover(l,h),n=0;nt||t>=i||r>e||e>=a;)switch(s=(ef||(a=c.y0)>d||(o=c.x1)=m)<<1|t>=y)&&(c=p[p.length-1],p[p.length-1]=p[p.length-1-u],p[p.length-1-u]=c)}else{var v=t-+this._x.call(null,g.data),b=e-+this._y.call(null,g.data),_=v*v+b*b;if(_=(s=(p+y)/2))?p=s:y=s,(l=o>=(c=(g+m)/2))?g=c:m=c,e=d,!(d=d[h=l<<1|u]))return this;if(!d.length)break;(e[h+1&3]||e[h+2&3]||e[h+3&3])&&(n=e,f=h)}for(;d.data!==t;)if(r=d,!(d=d.next))return this;return(i=d.next)&&delete d.next,r?(i?r.next=i:delete r.next,this):e?(i?e[h]=i:delete e[h],(d=e[0]||e[1]||e[2]||e[3])&&d===(e[3]||e[2]||e[1]||e[0])&&!d.length&&(n?n[f]=d:this._root=d),this):(this._root=i,this)},$s.removeAll=function(t){for(var e=0,n=t.length;e1?(null==n?s.remove(t):s.set(t,d(n)),e):s.get(t)},find:function(e,n,r){var i,a,o,s,c,u=0,l=t.length;for(null==r?r=1/0:r*=r,u=0;u1?(u.on(t,n),e):u.on(t)}}}function tc(){var t,e,n,r,i=Os(-30),a=1,o=1/0,s=.81;function c(r){var i,a=t.length,o=js(t,Zs,Qs).visitAfter(l);for(n=r,i=0;i=o)){(t.data!==e||t.next)&&(0===l&&(d+=(l=Is())*l),0===h&&(d+=(h=Is())*h),d1?r[0]+r.slice(2):r,+t.slice(n+1)]}function ac(t){return(t=ic(Math.abs(t)))?t[1]:NaN}var oc,sc=/^(?:(.)?([<>=^]))?([+\-( ])?([$#])?(0)?(\d+)?(,)?(\.\d+)?(~)?([a-z%])?$/i;function cc(t){if(!(e=sc.exec(t)))throw new Error("invalid format: "+t);var e;return new uc({fill:e[1],align:e[2],sign:e[3],symbol:e[4],zero:e[5],width:e[6],comma:e[7],precision:e[8]&&e[8].slice(1),trim:e[9],type:e[10]})}function uc(t){this.fill=void 0===t.fill?" ":t.fill+"",this.align=void 0===t.align?">":t.align+"",this.sign=void 0===t.sign?"-":t.sign+"",this.symbol=void 0===t.symbol?"":t.symbol+"",this.zero=!!t.zero,this.width=void 0===t.width?void 0:+t.width,this.comma=!!t.comma,this.precision=void 0===t.precision?void 0:+t.precision,this.trim=!!t.trim,this.type=void 0===t.type?"":t.type+""}function lc(t,e){var n=ic(t,e);if(!n)return t+"";var r=n[0],i=n[1];return i<0?"0."+new Array(-i).join("0")+r:r.length>i+1?r.slice(0,i+1)+"."+r.slice(i+1):r+new Array(i-r.length+2).join("0")}cc.prototype=uc.prototype,uc.prototype.toString=function(){return this.fill+this.align+this.sign+this.symbol+(this.zero?"0":"")+(void 0===this.width?"":Math.max(1,0|this.width))+(this.comma?",":"")+(void 0===this.precision?"":"."+Math.max(0,0|this.precision))+(this.trim?"~":"")+this.type};const hc={"%":function(t,e){return(100*t).toFixed(e)},b:function(t){return Math.round(t).toString(2)},c:function(t){return t+""},d:function(t){return Math.abs(t=Math.round(t))>=1e21?t.toLocaleString("en").replace(/,/g,""):t.toString(10)},e:function(t,e){return t.toExponential(e)},f:function(t,e){return t.toFixed(e)},g:function(t,e){return t.toPrecision(e)},o:function(t){return Math.round(t).toString(8)},p:function(t,e){return lc(100*t,e)},r:lc,s:function(t,e){var n=ic(t,e);if(!n)return t+"";var r=n[0],i=n[1],a=i-(oc=3*Math.max(-8,Math.min(8,Math.floor(i/3))))+1,o=r.length;return a===o?r:a>o?r+new Array(a-o+1).join("0"):a>0?r.slice(0,a)+"."+r.slice(a):"0."+new Array(1-a).join("0")+ic(t,Math.max(0,e+a-1))[0]},X:function(t){return Math.round(t).toString(16).toUpperCase()},x:function(t){return Math.round(t).toString(16)}};function fc(t){return t}var dc,pc,gc,yc=Array.prototype.map,mc=["y","z","a","f","p","n","µ","m","","k","M","G","T","P","E","Z","Y"];function vc(t){var e,n,r=void 0===t.grouping||void 0===t.thousands?fc:(e=yc.call(t.grouping,Number),n=t.thousands+"",function(t,r){for(var i=t.length,a=[],o=0,s=e[0],c=0;i>0&&s>0&&(c+s+1>r&&(s=Math.max(1,r-c)),a.push(t.substring(i-=s,i+s)),!((c+=s+1)>r));)s=e[o=(o+1)%e.length];return a.reverse().join(n)}),i=void 0===t.currency?"":t.currency[0]+"",a=void 0===t.currency?"":t.currency[1]+"",o=void 0===t.decimal?".":t.decimal+"",s=void 0===t.numerals?fc:function(t){return function(e){return e.replace(/[0-9]/g,(function(e){return t[+e]}))}}(yc.call(t.numerals,String)),c=void 0===t.percent?"%":t.percent+"",u=void 0===t.minus?"-":t.minus+"",l=void 0===t.nan?"NaN":t.nan+"";function h(t){var e=(t=cc(t)).fill,n=t.align,h=t.sign,f=t.symbol,d=t.zero,p=t.width,g=t.comma,y=t.precision,m=t.trim,v=t.type;"n"===v?(g=!0,v="g"):hc[v]||(void 0===y&&(y=12),m=!0,v="g"),(d||"0"===e&&"="===n)&&(d=!0,e="0",n="=");var b="$"===f?i:"#"===f&&/[boxX]/.test(v)?"0"+v.toLowerCase():"",_="$"===f?a:/[%p]/.test(v)?c:"",x=hc[v],w=/[defgprs%]/.test(v);function k(t){var i,a,c,f=b,k=_;if("c"===v)k=x(t)+k,t="";else{var T=(t=+t)<0||1/t<0;if(t=isNaN(t)?l:x(Math.abs(t),y),m&&(t=function(t){t:for(var e,n=t.length,r=1,i=-1;r0&&(i=0)}return i>0?t.slice(0,i)+t.slice(e+1):t}(t)),T&&0==+t&&"+"!==h&&(T=!1),f=(T?"("===h?h:u:"-"===h||"("===h?"":h)+f,k=("s"===v?mc[8+oc/3]:"")+k+(T&&"("===h?")":""),w)for(i=-1,a=t.length;++i(c=t.charCodeAt(i))||c>57){k=(46===c?o+t.slice(i+1):t.slice(i))+k,t=t.slice(0,i);break}}g&&!d&&(t=r(t,1/0));var C=f.length+t.length+k.length,E=C>1)+f+t+k+E.slice(C);break;default:t=E+f+t+k}return s(t)}return y=void 0===y?6:/[gprs]/.test(v)?Math.max(1,Math.min(21,y)):Math.max(0,Math.min(20,y)),k.toString=function(){return t+""},k}return{format:h,formatPrefix:function(t,e){var n=h(((t=cc(t)).type="f",t)),r=3*Math.max(-8,Math.min(8,Math.floor(ac(e)/3))),i=Math.pow(10,-r),a=mc[8+r/3];return function(t){return n(i*t)+a}}}}function bc(t){return dc=vc(t),pc=dc.format,gc=dc.formatPrefix,dc}function _c(t){return Math.max(0,-ac(Math.abs(t)))}function xc(t,e){return Math.max(0,3*Math.max(-8,Math.min(8,Math.floor(ac(e)/3)))-ac(Math.abs(t)))}function wc(t,e){return t=Math.abs(t),e=Math.abs(e)-t,Math.max(0,ac(e)-ac(t))+1}function kc(){return new Tc}function Tc(){this.reset()}bc({decimal:".",thousands:",",grouping:[3],currency:["$",""],minus:"-"}),Tc.prototype={constructor:Tc,reset:function(){this.s=this.t=0},add:function(t){Ec(Cc,t,this.t),Ec(this,Cc.s,this.s),this.s?this.t+=Cc.t:this.s=Cc.t},valueOf:function(){return this.s}};var Cc=new Tc;function Ec(t,e,n){var r=t.s=e+n,i=r-e,a=r-i;t.t=e-a+(n-i)}var Sc=1e-6,Ac=1e-12,Mc=Math.PI,Nc=Mc/2,Dc=Mc/4,Bc=2*Mc,Lc=180/Mc,Oc=Mc/180,Ic=Math.abs,Rc=Math.atan,Fc=Math.atan2,Pc=Math.cos,Yc=Math.ceil,jc=Math.exp,Uc=(Math.floor,Math.log),zc=Math.pow,$c=Math.sin,qc=Math.sign||function(t){return t>0?1:t<0?-1:0},Hc=Math.sqrt,Wc=Math.tan;function Vc(t){return t>1?0:t<-1?Mc:Math.acos(t)}function Gc(t){return t>1?Nc:t<-1?-Nc:Math.asin(t)}function Xc(t){return(t=$c(t/2))*t}function Zc(){}function Qc(t,e){t&&Jc.hasOwnProperty(t.type)&&Jc[t.type](t,e)}var Kc={Feature:function(t,e){Qc(t.geometry,e)},FeatureCollection:function(t,e){for(var n=t.features,r=-1,i=n.length;++r=0?1:-1,i=r*n,a=Pc(e=(e*=Oc)/2+Dc),o=$c(e),s=su*o,c=ou*a+s*Pc(i),u=s*r*$c(i);cu.add(Fc(u,c)),au=t,ou=a,su=o}function gu(t){return uu.reset(),nu(t,lu),2*uu}function yu(t){return[Fc(t[1],t[0]),Gc(t[2])]}function mu(t){var e=t[0],n=t[1],r=Pc(n);return[r*Pc(e),r*$c(e),$c(n)]}function vu(t,e){return t[0]*e[0]+t[1]*e[1]+t[2]*e[2]}function bu(t,e){return[t[1]*e[2]-t[2]*e[1],t[2]*e[0]-t[0]*e[2],t[0]*e[1]-t[1]*e[0]]}function _u(t,e){t[0]+=e[0],t[1]+=e[1],t[2]+=e[2]}function xu(t,e){return[t[0]*e,t[1]*e,t[2]*e]}function wu(t){var e=Hc(t[0]*t[0]+t[1]*t[1]+t[2]*t[2]);t[0]/=e,t[1]/=e,t[2]/=e}var ku,Tu,Cu,Eu,Su,Au,Mu,Nu,Du,Bu,Lu,Ou,Iu,Ru,Fu,Pu,Yu,ju,Uu,zu,$u,qu,Hu,Wu,Vu,Gu,Xu=kc(),Zu={point:Qu,lineStart:Ju,lineEnd:tl,polygonStart:function(){Zu.point=el,Zu.lineStart=nl,Zu.lineEnd=rl,Xu.reset(),lu.polygonStart()},polygonEnd:function(){lu.polygonEnd(),Zu.point=Qu,Zu.lineStart=Ju,Zu.lineEnd=tl,cu<0?(ku=-(Cu=180),Tu=-(Eu=90)):Xu>Sc?Eu=90:Xu<-1e-6&&(Tu=-90),Bu[0]=ku,Bu[1]=Cu},sphere:function(){ku=-(Cu=180),Tu=-(Eu=90)}};function Qu(t,e){Du.push(Bu=[ku=t,Cu=t]),eEu&&(Eu=e)}function Ku(t,e){var n=mu([t*Oc,e*Oc]);if(Nu){var r=bu(Nu,n),i=bu([r[1],-r[0],0],r);wu(i),i=yu(i);var a,o=t-Su,s=o>0?1:-1,c=i[0]*Lc*s,u=Ic(o)>180;u^(s*SuEu&&(Eu=a):u^(s*Su<(c=(c+360)%360-180)&&cEu&&(Eu=e)),u?til(ku,Cu)&&(Cu=t):il(t,Cu)>il(ku,Cu)&&(ku=t):Cu>=ku?(tCu&&(Cu=t)):t>Su?il(ku,t)>il(ku,Cu)&&(Cu=t):il(t,Cu)>il(ku,Cu)&&(ku=t)}else Du.push(Bu=[ku=t,Cu=t]);eEu&&(Eu=e),Nu=n,Su=t}function Ju(){Zu.point=Ku}function tl(){Bu[0]=ku,Bu[1]=Cu,Zu.point=Qu,Nu=null}function el(t,e){if(Nu){var n=t-Su;Xu.add(Ic(n)>180?n+(n>0?360:-360):n)}else Au=t,Mu=e;lu.point(t,e),Ku(t,e)}function nl(){lu.lineStart()}function rl(){el(Au,Mu),lu.lineEnd(),Ic(Xu)>Sc&&(ku=-(Cu=180)),Bu[0]=ku,Bu[1]=Cu,Nu=null}function il(t,e){return(e-=t)<0?e+360:e}function al(t,e){return t[0]-e[0]}function ol(t,e){return t[0]<=t[1]?t[0]<=e&&e<=t[1]:eil(r[0],r[1])&&(r[1]=i[1]),il(i[0],r[1])>il(r[0],r[1])&&(r[0]=i[0])):a.push(r=i);for(o=-1/0,e=0,r=a[n=a.length-1];e<=n;r=i,++e)i=a[e],(s=il(r[1],i[0]))>o&&(o=s,ku=i[0],Cu=r[1])}return Du=Bu=null,ku===1/0||Tu===1/0?[[NaN,NaN],[NaN,NaN]]:[[ku,Tu],[Cu,Eu]]}var cl={sphere:Zc,point:ul,lineStart:hl,lineEnd:pl,polygonStart:function(){cl.lineStart=gl,cl.lineEnd=yl},polygonEnd:function(){cl.lineStart=hl,cl.lineEnd=pl}};function ul(t,e){t*=Oc;var n=Pc(e*=Oc);ll(n*Pc(t),n*$c(t),$c(e))}function ll(t,e,n){++Lu,Iu+=(t-Iu)/Lu,Ru+=(e-Ru)/Lu,Fu+=(n-Fu)/Lu}function hl(){cl.point=fl}function fl(t,e){t*=Oc;var n=Pc(e*=Oc);Wu=n*Pc(t),Vu=n*$c(t),Gu=$c(e),cl.point=dl,ll(Wu,Vu,Gu)}function dl(t,e){t*=Oc;var n=Pc(e*=Oc),r=n*Pc(t),i=n*$c(t),a=$c(e),o=Fc(Hc((o=Vu*a-Gu*i)*o+(o=Gu*r-Wu*a)*o+(o=Wu*i-Vu*r)*o),Wu*r+Vu*i+Gu*a);Ou+=o,Pu+=o*(Wu+(Wu=r)),Yu+=o*(Vu+(Vu=i)),ju+=o*(Gu+(Gu=a)),ll(Wu,Vu,Gu)}function pl(){cl.point=ul}function gl(){cl.point=ml}function yl(){vl(qu,Hu),cl.point=ul}function ml(t,e){qu=t,Hu=e,t*=Oc,e*=Oc,cl.point=vl;var n=Pc(e);Wu=n*Pc(t),Vu=n*$c(t),Gu=$c(e),ll(Wu,Vu,Gu)}function vl(t,e){t*=Oc;var n=Pc(e*=Oc),r=n*Pc(t),i=n*$c(t),a=$c(e),o=Vu*a-Gu*i,s=Gu*r-Wu*a,c=Wu*i-Vu*r,u=Hc(o*o+s*s+c*c),l=Gc(u),h=u&&-l/u;Uu+=h*o,zu+=h*s,$u+=h*c,Ou+=l,Pu+=l*(Wu+(Wu=r)),Yu+=l*(Vu+(Vu=i)),ju+=l*(Gu+(Gu=a)),ll(Wu,Vu,Gu)}function bl(t){Lu=Ou=Iu=Ru=Fu=Pu=Yu=ju=Uu=zu=$u=0,nu(t,cl);var e=Uu,n=zu,r=$u,i=e*e+n*n+r*r;return iMc?t+Math.round(-t/Bc)*Bc:t,e]}function kl(t,e,n){return(t%=Bc)?e||n?xl(Cl(t),El(e,n)):Cl(t):e||n?El(e,n):wl}function Tl(t){return function(e,n){return[(e+=t)>Mc?e-Bc:e<-Mc?e+Bc:e,n]}}function Cl(t){var e=Tl(t);return e.invert=Tl(-t),e}function El(t,e){var n=Pc(t),r=$c(t),i=Pc(e),a=$c(e);function o(t,e){var o=Pc(e),s=Pc(t)*o,c=$c(t)*o,u=$c(e),l=u*n+s*r;return[Fc(c*i-l*a,s*n-u*r),Gc(l*i+c*a)]}return o.invert=function(t,e){var o=Pc(e),s=Pc(t)*o,c=$c(t)*o,u=$c(e),l=u*i-c*a;return[Fc(c*i+u*a,s*n+l*r),Gc(l*n-s*r)]},o}function Sl(t){function e(e){return(e=t(e[0]*Oc,e[1]*Oc))[0]*=Lc,e[1]*=Lc,e}return t=kl(t[0]*Oc,t[1]*Oc,t.length>2?t[2]*Oc:0),e.invert=function(e){return(e=t.invert(e[0]*Oc,e[1]*Oc))[0]*=Lc,e[1]*=Lc,e},e}function Al(t,e,n,r,i,a){if(n){var o=Pc(e),s=$c(e),c=r*n;null==i?(i=e+r*Bc,a=e-c/2):(i=Ml(o,i),a=Ml(o,a),(r>0?ia)&&(i+=r*Bc));for(var u,l=i;r>0?l>a:l1&&e.push(e.pop().concat(e.shift()))},result:function(){var n=e;return e=[],t=null,n}}}function Bl(t,e){return Ic(t[0]-e[0])=0;--a)i.point((l=u[a])[0],l[1]);else r(f.x,f.p.x,-1,i);f=f.p}u=(f=f.o).z,d=!d}while(!f.v);i.lineEnd()}}}function Il(t){if(e=t.length){for(var e,n,r=0,i=t[0];++r=0?1:-1,C=T*k,E=C>Mc,S=g*x;if(Rl.add(Fc(S*T*$c(C),y*w+S*Pc(C))),o+=E?k+T*Bc:k,E^d>=n^b>=n){var A=bu(mu(f),mu(v));wu(A);var M=bu(a,A);wu(M);var N=(E^k>=0?-1:1)*Gc(M[2]);(r>N||r===N&&(A[0]||A[1]))&&(s+=E^k>=0?1:-1)}}return(o<-1e-6||o0){for(h||(i.polygonStart(),h=!0),i.lineStart(),t=0;t1&&2&c&&f.push(f.pop().concat(f.shift())),o.push(f.filter(jl))}return f}}function jl(t){return t.length>1}function Ul(t,e){return((t=t.x)[0]<0?t[1]-Nc-Sc:Nc-t[1])-((e=e.x)[0]<0?e[1]-Nc-Sc:Nc-e[1])}const zl=Yl((function(){return!0}),(function(t){var e,n=NaN,r=NaN,i=NaN;return{lineStart:function(){t.lineStart(),e=1},point:function(a,o){var s=a>0?Mc:-Mc,c=Ic(a-n);Ic(c-Mc)0?Nc:-Nc),t.point(i,r),t.lineEnd(),t.lineStart(),t.point(s,r),t.point(a,r),e=0):i!==s&&c>=Mc&&(Ic(n-i)Sc?Rc(($c(e)*(a=Pc(r))*$c(n)-$c(r)*(i=Pc(e))*$c(t))/(i*a*o)):(e+r)/2}(n,r,a,o),t.point(i,r),t.lineEnd(),t.lineStart(),t.point(s,r),e=0),t.point(n=a,r=o),i=s},lineEnd:function(){t.lineEnd(),n=r=NaN},clean:function(){return 2-e}}}),(function(t,e,n,r){var i;if(null==t)i=n*Nc,r.point(-Mc,i),r.point(0,i),r.point(Mc,i),r.point(Mc,0),r.point(Mc,-i),r.point(0,-i),r.point(-Mc,-i),r.point(-Mc,0),r.point(-Mc,i);else if(Ic(t[0]-e[0])>Sc){var a=t[0]0,i=Ic(e)>Sc;function a(t,n){return Pc(t)*Pc(n)>e}function o(t,n,r){var i=[1,0,0],a=bu(mu(t),mu(n)),o=vu(a,a),s=a[0],c=o-s*s;if(!c)return!r&&t;var u=e*o/c,l=-e*s/c,h=bu(i,a),f=xu(i,u);_u(f,xu(a,l));var d=h,p=vu(f,d),g=vu(d,d),y=p*p-g*(vu(f,f)-1);if(!(y<0)){var m=Hc(y),v=xu(d,(-p-m)/g);if(_u(v,f),v=yu(v),!r)return v;var b,_=t[0],x=n[0],w=t[1],k=n[1];x<_&&(b=_,_=x,x=b);var T=x-_,C=Ic(T-Mc)0^v[1]<(Ic(v[0]-_)Mc^(_<=v[0]&&v[0]<=x)){var E=xu(d,(-p+m)/g);return _u(E,f),[v,yu(E)]}}}function s(e,n){var i=r?t:Mc-t,a=0;return e<-i?a|=1:e>i&&(a|=2),n<-i?a|=4:n>i&&(a|=8),a}return Yl(a,(function(t){var e,n,c,u,l;return{lineStart:function(){u=c=!1,l=1},point:function(h,f){var d,p=[h,f],g=a(h,f),y=r?g?0:s(h,f):g?s(h+(h<0?Mc:-Mc),f):0;if(!e&&(u=c=g)&&t.lineStart(),g!==c&&(!(d=o(e,p))||Bl(e,d)||Bl(p,d))&&(p[2]=1),g!==c)l=0,g?(t.lineStart(),d=o(p,e),t.point(d[0],d[1])):(d=o(e,p),t.point(d[0],d[1],2),t.lineEnd()),e=d;else if(i&&e&&r^g){var m;y&n||!(m=o(p,e,!0))||(l=0,r?(t.lineStart(),t.point(m[0][0],m[0][1]),t.point(m[1][0],m[1][1]),t.lineEnd()):(t.point(m[1][0],m[1][1]),t.lineEnd(),t.lineStart(),t.point(m[0][0],m[0][1],3)))}!g||e&&Bl(e,p)||t.point(p[0],p[1]),e=p,c=g,n=y},lineEnd:function(){c&&t.lineEnd(),e=null},clean:function(){return l|(u&&c)<<1}}}),(function(e,r,i,a){Al(a,t,n,i,e,r)}),r?[0,-t]:[-Mc,t-Mc])}var ql=1e9,Hl=-ql;function Wl(t,e,n,r){function i(i,a){return t<=i&&i<=n&&e<=a&&a<=r}function a(i,a,s,u){var l=0,h=0;if(null==i||(l=o(i,s))!==(h=o(a,s))||c(i,a)<0^s>0)do{u.point(0===l||3===l?t:n,l>1?r:e)}while((l=(l+s+4)%4)!==h);else u.point(a[0],a[1])}function o(r,i){return Ic(r[0]-t)0?0:3:Ic(r[0]-n)0?2:1:Ic(r[1]-e)0?1:0:i>0?3:2}function s(t,e){return c(t.x,e.x)}function c(t,e){var n=o(t,1),r=o(e,1);return n!==r?n-r:0===n?e[1]-t[1]:1===n?t[0]-e[0]:2===n?t[1]-e[1]:e[0]-t[0]}return function(o){var c,u,l,h,f,d,p,g,y,m,v,b=o,_=Dl(),x={point:w,lineStart:function(){x.point=k,u&&u.push(l=[]),m=!0,y=!1,p=g=NaN},lineEnd:function(){c&&(k(h,f),d&&y&&_.rejoin(),c.push(_.result())),x.point=w,y&&b.lineEnd()},polygonStart:function(){b=_,c=[],u=[],v=!0},polygonEnd:function(){var e=function(){for(var e=0,n=0,i=u.length;nr&&(f-a)*(r-o)>(d-o)*(t-a)&&++e:d<=r&&(f-a)*(r-o)<(d-o)*(t-a)&&--e;return e}(),n=v&&e,i=(c=P(c)).length;(n||i)&&(o.polygonStart(),n&&(o.lineStart(),a(null,null,1,o),o.lineEnd()),i&&Ol(c,s,e,a,o),o.polygonEnd()),b=o,c=u=l=null}};function w(t,e){i(t,e)&&b.point(t,e)}function k(a,o){var s=i(a,o);if(u&&l.push([a,o]),m)h=a,f=o,d=s,m=!1,s&&(b.lineStart(),b.point(a,o));else if(s&&y)b.point(a,o);else{var c=[p=Math.max(Hl,Math.min(ql,p)),g=Math.max(Hl,Math.min(ql,g))],_=[a=Math.max(Hl,Math.min(ql,a)),o=Math.max(Hl,Math.min(ql,o))];!function(t,e,n,r,i,a){var o,s=t[0],c=t[1],u=0,l=1,h=e[0]-s,f=e[1]-c;if(o=n-s,h||!(o>0)){if(o/=h,h<0){if(o0){if(o>l)return;o>u&&(u=o)}if(o=i-s,h||!(o<0)){if(o/=h,h<0){if(o>l)return;o>u&&(u=o)}else if(h>0){if(o0)){if(o/=f,f<0){if(o0){if(o>l)return;o>u&&(u=o)}if(o=a-c,f||!(o<0)){if(o/=f,f<0){if(o>l)return;o>u&&(u=o)}else if(f>0){if(o0&&(t[0]=s+u*h,t[1]=c+u*f),l<1&&(e[0]=s+l*h,e[1]=c+l*f),!0}}}}}(c,_,t,e,n,r)?s&&(b.lineStart(),b.point(a,o),v=!1):(y||(b.lineStart(),b.point(c[0],c[1])),b.point(_[0],_[1]),s||b.lineEnd(),v=!1)}p=a,g=o,y=s}return x}}function Vl(){var t,e,n,r=0,i=0,a=960,o=500;return n={stream:function(n){return t&&e===n?t:t=Wl(r,i,a,o)(e=n)},extent:function(s){return arguments.length?(r=+s[0][0],i=+s[0][1],a=+s[1][0],o=+s[1][1],t=e=null,n):[[r,i],[a,o]]}}}var Gl,Xl,Zl,Ql=kc(),Kl={sphere:Zc,point:Zc,lineStart:function(){Kl.point=th,Kl.lineEnd=Jl},lineEnd:Zc,polygonStart:Zc,polygonEnd:Zc};function Jl(){Kl.point=Kl.lineEnd=Zc}function th(t,e){Gl=t*=Oc,Xl=$c(e*=Oc),Zl=Pc(e),Kl.point=eh}function eh(t,e){t*=Oc;var n=$c(e*=Oc),r=Pc(e),i=Ic(t-Gl),a=Pc(i),o=r*$c(i),s=Zl*n-Xl*r*a,c=Xl*n+Zl*r*a;Ql.add(Fc(Hc(o*o+s*s),c)),Gl=t,Xl=n,Zl=r}function nh(t){return Ql.reset(),nu(t,Kl),+Ql}var rh=[null,null],ih={type:"LineString",coordinates:rh};function ah(t,e){return rh[0]=t,rh[1]=e,nh(ih)}var oh={Feature:function(t,e){return ch(t.geometry,e)},FeatureCollection:function(t,e){for(var n=t.features,r=-1,i=n.length;++r0&&(i=ah(t[a],t[a-1]))>0&&n<=i&&r<=i&&(n+r-i)*(1-Math.pow((n-r)/i,2))Sc})).map(c)).concat(k(Yc(a/d)*d,i,d).filter((function(t){return Ic(t%g)>Sc})).map(u))}return m.lines=function(){return v().map((function(t){return{type:"LineString",coordinates:t}}))},m.outline=function(){return{type:"Polygon",coordinates:[l(r).concat(h(o).slice(1),l(n).reverse().slice(1),h(s).reverse().slice(1))]}},m.extent=function(t){return arguments.length?m.extentMajor(t).extentMinor(t):m.extentMinor()},m.extentMajor=function(t){return arguments.length?(r=+t[0][0],n=+t[1][0],s=+t[0][1],o=+t[1][1],r>n&&(t=r,r=n,n=t),s>o&&(t=s,s=o,o=t),m.precision(y)):[[r,s],[n,o]]},m.extentMinor=function(n){return arguments.length?(e=+n[0][0],t=+n[1][0],a=+n[0][1],i=+n[1][1],e>t&&(n=e,e=t,t=n),a>i&&(n=a,a=i,i=n),m.precision(y)):[[e,a],[t,i]]},m.step=function(t){return arguments.length?m.stepMajor(t).stepMinor(t):m.stepMinor()},m.stepMajor=function(t){return arguments.length?(p=+t[0],g=+t[1],m):[p,g]},m.stepMinor=function(t){return arguments.length?(f=+t[0],d=+t[1],m):[f,d]},m.precision=function(f){return arguments.length?(y=+f,c=gh(a,i,90),u=yh(e,t,y),l=gh(s,o,90),h=yh(r,n,y),m):y},m.extentMajor([[-180,-89.999999],[180,89.999999]]).extentMinor([[-180,-80.000001],[180,80.000001]])}function vh(){return mh()()}function bh(t,e){var n=t[0]*Oc,r=t[1]*Oc,i=e[0]*Oc,a=e[1]*Oc,o=Pc(r),s=$c(r),c=Pc(a),u=$c(a),l=o*Pc(n),h=o*$c(n),f=c*Pc(i),d=c*$c(i),p=2*Gc(Hc(Xc(a-r)+o*c*Xc(i-n))),g=$c(p),y=p?function(t){var e=$c(t*=p)/g,n=$c(p-t)/g,r=n*l+e*f,i=n*h+e*d,a=n*s+e*u;return[Fc(i,r)*Lc,Fc(a,Hc(r*r+i*i))*Lc]}:function(){return[n*Lc,r*Lc]};return y.distance=p,y}function _h(t){return t}var xh,wh,kh,Th,Ch=kc(),Eh=kc(),Sh={point:Zc,lineStart:Zc,lineEnd:Zc,polygonStart:function(){Sh.lineStart=Ah,Sh.lineEnd=Dh},polygonEnd:function(){Sh.lineStart=Sh.lineEnd=Sh.point=Zc,Ch.add(Ic(Eh)),Eh.reset()},result:function(){var t=Ch/2;return Ch.reset(),t}};function Ah(){Sh.point=Mh}function Mh(t,e){Sh.point=Nh,xh=kh=t,wh=Th=e}function Nh(t,e){Eh.add(Th*t-kh*e),kh=t,Th=e}function Dh(){Nh(xh,wh)}const Bh=Sh;var Lh=1/0,Oh=Lh,Ih=-Lh,Rh=Ih,Fh={point:function(t,e){tIh&&(Ih=t),eRh&&(Rh=e)},lineStart:Zc,lineEnd:Zc,polygonStart:Zc,polygonEnd:Zc,result:function(){var t=[[Lh,Oh],[Ih,Rh]];return Ih=Rh=-(Oh=Lh=1/0),t}};const Ph=Fh;var Yh,jh,Uh,zh,$h=0,qh=0,Hh=0,Wh=0,Vh=0,Gh=0,Xh=0,Zh=0,Qh=0,Kh={point:Jh,lineStart:tf,lineEnd:rf,polygonStart:function(){Kh.lineStart=af,Kh.lineEnd=of},polygonEnd:function(){Kh.point=Jh,Kh.lineStart=tf,Kh.lineEnd=rf},result:function(){var t=Qh?[Xh/Qh,Zh/Qh]:Gh?[Wh/Gh,Vh/Gh]:Hh?[$h/Hh,qh/Hh]:[NaN,NaN];return $h=qh=Hh=Wh=Vh=Gh=Xh=Zh=Qh=0,t}};function Jh(t,e){$h+=t,qh+=e,++Hh}function tf(){Kh.point=ef}function ef(t,e){Kh.point=nf,Jh(Uh=t,zh=e)}function nf(t,e){var n=t-Uh,r=e-zh,i=Hc(n*n+r*r);Wh+=i*(Uh+t)/2,Vh+=i*(zh+e)/2,Gh+=i,Jh(Uh=t,zh=e)}function rf(){Kh.point=Jh}function af(){Kh.point=sf}function of(){cf(Yh,jh)}function sf(t,e){Kh.point=cf,Jh(Yh=Uh=t,jh=zh=e)}function cf(t,e){var n=t-Uh,r=e-zh,i=Hc(n*n+r*r);Wh+=i*(Uh+t)/2,Vh+=i*(zh+e)/2,Gh+=i,Xh+=(i=zh*t-Uh*e)*(Uh+t),Zh+=i*(zh+e),Qh+=3*i,Jh(Uh=t,zh=e)}const uf=Kh;function lf(t){this._context=t}lf.prototype={_radius:4.5,pointRadius:function(t){return this._radius=t,this},polygonStart:function(){this._line=0},polygonEnd:function(){this._line=NaN},lineStart:function(){this._point=0},lineEnd:function(){0===this._line&&this._context.closePath(),this._point=NaN},point:function(t,e){switch(this._point){case 0:this._context.moveTo(t,e),this._point=1;break;case 1:this._context.lineTo(t,e);break;default:this._context.moveTo(t+this._radius,e),this._context.arc(t,e,this._radius,0,Bc)}},result:Zc};var hf,ff,df,pf,gf,yf=kc(),mf={point:Zc,lineStart:function(){mf.point=vf},lineEnd:function(){hf&&bf(ff,df),mf.point=Zc},polygonStart:function(){hf=!0},polygonEnd:function(){hf=null},result:function(){var t=+yf;return yf.reset(),t}};function vf(t,e){mf.point=bf,ff=pf=t,df=gf=e}function bf(t,e){pf-=t,gf-=e,yf.add(Hc(pf*pf+gf*gf)),pf=t,gf=e}const _f=mf;function xf(){this._string=[]}function wf(t){return"m0,"+t+"a"+t+","+t+" 0 1,1 0,"+-2*t+"a"+t+","+t+" 0 1,1 0,"+2*t+"z"}function kf(t,e){var n,r,i=4.5;function a(t){return t&&("function"==typeof i&&r.pointRadius(+i.apply(this,arguments)),nu(t,n(r))),r.result()}return a.area=function(t){return nu(t,n(Bh)),Bh.result()},a.measure=function(t){return nu(t,n(_f)),_f.result()},a.bounds=function(t){return nu(t,n(Ph)),Ph.result()},a.centroid=function(t){return nu(t,n(uf)),uf.result()},a.projection=function(e){return arguments.length?(n=null==e?(t=null,_h):(t=e).stream,a):t},a.context=function(t){return arguments.length?(r=null==t?(e=null,new xf):new lf(e=t),"function"!=typeof i&&r.pointRadius(i),a):e},a.pointRadius=function(t){return arguments.length?(i="function"==typeof t?t:(r.pointRadius(+t),+t),a):i},a.projection(t).context(e)}function Tf(t){return{stream:Cf(t)}}function Cf(t){return function(e){var n=new Ef;for(var r in t)n[r]=t[r];return n.stream=e,n}}function Ef(){}function Sf(t,e,n){var r=t.clipExtent&&t.clipExtent();return t.scale(150).translate([0,0]),null!=r&&t.clipExtent(null),nu(n,t.stream(Ph)),e(Ph.result()),null!=r&&t.clipExtent(r),t}function Af(t,e,n){return Sf(t,(function(n){var r=e[1][0]-e[0][0],i=e[1][1]-e[0][1],a=Math.min(r/(n[1][0]-n[0][0]),i/(n[1][1]-n[0][1])),o=+e[0][0]+(r-a*(n[1][0]+n[0][0]))/2,s=+e[0][1]+(i-a*(n[1][1]+n[0][1]))/2;t.scale(150*a).translate([o,s])}),n)}function Mf(t,e,n){return Af(t,[[0,0],e],n)}function Nf(t,e,n){return Sf(t,(function(n){var r=+e,i=r/(n[1][0]-n[0][0]),a=(r-i*(n[1][0]+n[0][0]))/2,o=-i*n[0][1];t.scale(150*i).translate([a,o])}),n)}function Df(t,e,n){return Sf(t,(function(n){var r=+e,i=r/(n[1][1]-n[0][1]),a=-i*n[0][0],o=(r-i*(n[1][1]+n[0][1]))/2;t.scale(150*i).translate([a,o])}),n)}xf.prototype={_radius:4.5,_circle:wf(4.5),pointRadius:function(t){return(t=+t)!==this._radius&&(this._radius=t,this._circle=null),this},polygonStart:function(){this._line=0},polygonEnd:function(){this._line=NaN},lineStart:function(){this._point=0},lineEnd:function(){0===this._line&&this._string.push("Z"),this._point=NaN},point:function(t,e){switch(this._point){case 0:this._string.push("M",t,",",e),this._point=1;break;case 1:this._string.push("L",t,",",e);break;default:null==this._circle&&(this._circle=wf(this._radius)),this._string.push("M",t,",",e,this._circle)}},result:function(){if(this._string.length){var t=this._string.join("");return this._string=[],t}return null}},Ef.prototype={constructor:Ef,point:function(t,e){this.stream.point(t,e)},sphere:function(){this.stream.sphere()},lineStart:function(){this.stream.lineStart()},lineEnd:function(){this.stream.lineEnd()},polygonStart:function(){this.stream.polygonStart()},polygonEnd:function(){this.stream.polygonEnd()}};var Bf=Pc(30*Oc);function Lf(t,e){return+e?function(t,e){function n(r,i,a,o,s,c,u,l,h,f,d,p,g,y){var m=u-r,v=l-i,b=m*m+v*v;if(b>4*e&&g--){var _=o+f,x=s+d,w=c+p,k=Hc(_*_+x*x+w*w),T=Gc(w/=k),C=Ic(Ic(w)-1)e||Ic((m*M+v*N)/b-.5)>.3||o*f+s*d+c*p2?t[2]%360*Oc:0,M()):[y*Lc,m*Lc,v*Lc]},S.angle=function(t){return arguments.length?(b=t%360*Oc,M()):b*Lc},S.reflectX=function(t){return arguments.length?(_=t?-1:1,M()):_<0},S.reflectY=function(t){return arguments.length?(x=t?-1:1,M()):x<0},S.precision=function(t){return arguments.length?(o=Lf(s,E=t*t),N()):Hc(E)},S.fitExtent=function(t,e){return Af(S,t,e)},S.fitSize=function(t,e){return Mf(S,t,e)},S.fitWidth=function(t,e){return Nf(S,t,e)},S.fitHeight=function(t,e){return Df(S,t,e)},function(){return e=t.apply(this,arguments),S.invert=e.invert&&A,M()}}function Yf(t){var e=0,n=Mc/3,r=Pf(t),i=r(e,n);return i.parallels=function(t){return arguments.length?r(e=t[0]*Oc,n=t[1]*Oc):[e*Lc,n*Lc]},i}function jf(t,e){var n=$c(t),r=(n+$c(e))/2;if(Ic(r)=.12&&i<.234&&r>=-.425&&r<-.214?s:i>=.166&&i<.234&&r>=-.214&&r<-.115?c:o).invert(t)},l.stream=function(n){return t&&e===n?t:(r=[o.stream(e=n),s.stream(n),c.stream(n)],i=r.length,t={point:function(t,e){for(var n=-1;++n0?e<-Nc+Sc&&(e=-Nc+Sc):e>Nc-Sc&&(e=Nc-Sc);var n=i/zc(Jf(e),r);return[n*$c(r*t),i-n*Pc(r*t)]}return a.invert=function(t,e){var n=i-e,a=qc(r)*Hc(t*t+n*n),o=Fc(t,Ic(n))*qc(n);return n*r<0&&(o-=Mc*qc(t)*qc(n)),[o/r,2*Rc(zc(i/a,1/r))-Nc]},a}function ed(){return Yf(td).scale(109.5).parallels([30,30])}function nd(t,e){return[t,e]}function rd(){return Ff(nd).scale(152.63)}function id(t,e){var n=Pc(t),r=t===e?$c(t):(n-Pc(e))/(e-t),i=n/r+t;if(Ic(r)2?t[2]+90:90]):[(t=n())[0],t[1],t[2]-90]},n([0,0,90]).scale(159.155)}function Td(t,e){return t.parent===e.parent?1:2}function Cd(t,e){return t+e.x}function Ed(t,e){return Math.max(t,e.y)}function Sd(){var t=Td,e=1,n=1,r=!1;function i(i){var a,o=0;i.eachAfter((function(e){var n=e.children;n?(e.x=function(t){return t.reduce(Cd,0)/t.length}(n),e.y=function(t){return 1+t.reduce(Ed,0)}(n)):(e.x=a?o+=t(e,a):0,e.y=0,a=e)}));var s=function(t){for(var e;e=t.children;)t=e[0];return t}(i),c=function(t){for(var e;e=t.children;)t=e[e.length-1];return t}(i),u=s.x-t(s,c)/2,l=c.x+t(c,s)/2;return i.eachAfter(r?function(t){t.x=(t.x-i.x)*e,t.y=(i.y-t.y)*n}:function(t){t.x=(t.x-u)/(l-u)*e,t.y=(1-(i.y?t.y/i.y:1))*n})}return i.separation=function(e){return arguments.length?(t=e,i):t},i.size=function(t){return arguments.length?(r=!1,e=+t[0],n=+t[1],i):r?null:[e,n]},i.nodeSize=function(t){return arguments.length?(r=!0,e=+t[0],n=+t[1],i):r?[e,n]:null},i}function Ad(t){var e=0,n=t.children,r=n&&n.length;if(r)for(;--r>=0;)e+=n[r].value;else e=1;t.value=e}function Md(t,e){var n,r,i,a,o,s=new Ld(t),c=+t.value&&(s.value=t.value),u=[s];for(null==e&&(e=Nd);n=u.pop();)if(c&&(n.value=+n.data.value),(i=e(n.data))&&(o=i.length))for(n.children=new Array(o),a=o-1;a>=0;--a)u.push(r=n.children[a]=new Ld(i[a])),r.parent=n,r.depth=n.depth+1;return s.eachBefore(Bd)}function Nd(t){return t.children}function Dd(t){t.data=t.data.data}function Bd(t){var e=0;do{t.height=e}while((t=t.parent)&&t.height<++e)}function Ld(t){this.data=t,this.depth=this.height=0,this.parent=null}hd.invert=function(t,e){for(var n,r=e,i=r*r,a=i*i*i,o=0;o<12&&(a=(i=(r-=n=(r*(od+sd*i+a*(cd+ud*i))-e)/(od+3*sd*i+a*(7*cd+9*ud*i)))*r)*i*i,!(Ic(n)Sc&&--i>0);return[t/(.8707+(a=r*r)*(a*(a*a*a*(.003971-.001529*a)-.013791)-.131979)),r]},vd.invert=Hf(Gc),_d.invert=Hf((function(t){return 2*Rc(t)})),wd.invert=function(t,e){return[-e,2*Rc(jc(t))-Nc]},Ld.prototype=Md.prototype={constructor:Ld,count:function(){return this.eachAfter(Ad)},each:function(t){var e,n,r,i,a=this,o=[a];do{for(e=o.reverse(),o=[];a=e.pop();)if(t(a),n=a.children)for(r=0,i=n.length;r=0;--n)i.push(e[n]);return this},sum:function(t){return this.eachAfter((function(e){for(var n=+t(e.data)||0,r=e.children,i=r&&r.length;--i>=0;)n+=r[i].value;e.value=n}))},sort:function(t){return this.eachBefore((function(e){e.children&&e.children.sort(t)}))},path:function(t){for(var e=this,n=function(t,e){if(t===e)return t;var n=t.ancestors(),r=e.ancestors(),i=null;for(t=n.pop(),e=r.pop();t===e;)i=t,t=n.pop(),e=r.pop();return i}(e,t),r=[e];e!==n;)e=e.parent,r.push(e);for(var i=r.length;t!==n;)r.splice(i,0,t),t=t.parent;return r},ancestors:function(){for(var t=this,e=[t];t=t.parent;)e.push(t);return e},descendants:function(){var t=[];return this.each((function(e){t.push(e)})),t},leaves:function(){var t=[];return this.eachBefore((function(e){e.children||t.push(e)})),t},links:function(){var t=this,e=[];return t.each((function(n){n!==t&&e.push({source:n.parent,target:n})})),e},copy:function(){return Md(this).eachBefore(Dd)}};var Od=Array.prototype.slice;function Id(t){for(var e,n,r=0,i=(t=function(t){for(var e,n,r=t.length;r;)n=Math.random()*r--|0,e=t[r],t[r]=t[n],t[n]=e;return t}(Od.call(t))).length,a=[];r0&&n*n>r*r+i*i}function Yd(t,e){for(var n=0;n(o*=o)?(r=(u+o-i)/(2*u),a=Math.sqrt(Math.max(0,o/u-r*r)),n.x=t.x-r*s-a*c,n.y=t.y-r*c+a*s):(r=(u+i-o)/(2*u),a=Math.sqrt(Math.max(0,i/u-r*r)),n.x=e.x+r*s-a*c,n.y=e.y+r*c+a*s)):(n.x=e.x+n.r,n.y=e.y)}function qd(t,e){var n=t.r+e.r-1e-6,r=e.x-t.x,i=e.y-t.y;return n>0&&n*n>r*r+i*i}function Hd(t){var e=t._,n=t.next._,r=e.r+n.r,i=(e.x*n.r+n.x*e.r)/r,a=(e.y*n.r+n.y*e.r)/r;return i*i+a*a}function Wd(t){this._=t,this.next=null,this.previous=null}function Vd(t){if(!(i=t.length))return 0;var e,n,r,i,a,o,s,c,u,l,h;if((e=t[0]).x=0,e.y=0,!(i>1))return e.r;if(n=t[1],e.x=-n.r,n.x=e.r,n.y=0,!(i>2))return e.r+n.r;$d(n,e,r=t[2]),e=new Wd(e),n=new Wd(n),r=new Wd(r),e.next=r.previous=n,n.next=e.previous=r,r.next=n.previous=e;t:for(s=3;s0)throw new Error("cycle");return a}return n.id=function(e){return arguments.length?(t=Zd(e),n):t},n.parentId=function(t){return arguments.length?(e=Zd(t),n):e},n}function fp(t,e){return t.parent===e.parent?1:2}function dp(t){var e=t.children;return e?e[0]:t.t}function pp(t){var e=t.children;return e?e[e.length-1]:t.t}function gp(t,e,n){var r=n/(e.i-t.i);e.c-=r,e.s+=n,t.c+=r,e.z+=n,e.m+=n}function yp(t,e,n){return t.a.parent===e.parent?t.a:n}function mp(t,e){this._=t,this.parent=null,this.children=null,this.A=null,this.a=this,this.z=0,this.m=0,this.c=0,this.s=0,this.t=null,this.i=e}function vp(){var t=fp,e=1,n=1,r=null;function i(i){var c=function(t){for(var e,n,r,i,a,o=new mp(t,0),s=[o];e=s.pop();)if(r=e._.children)for(e.children=new Array(a=r.length),i=a-1;i>=0;--i)s.push(n=e.children[i]=new mp(r[i],i)),n.parent=e;return(o.parent=new mp(null,0)).children=[o],o}(i);if(c.eachAfter(a),c.parent.m=-c.z,c.eachBefore(o),r)i.eachBefore(s);else{var u=i,l=i,h=i;i.eachBefore((function(t){t.xl.x&&(l=t),t.depth>h.depth&&(h=t)}));var f=u===l?1:t(u,l)/2,d=f-u.x,p=e/(l.x+f+d),g=n/(h.depth||1);i.eachBefore((function(t){t.x=(t.x+d)*p,t.y=t.depth*g}))}return i}function a(e){var n=e.children,r=e.parent.children,i=e.i?r[e.i-1]:null;if(n){!function(t){for(var e,n=0,r=0,i=t.children,a=i.length;--a>=0;)(e=i[a]).z+=n,e.m+=n,n+=e.s+(r+=e.c)}(e);var a=(n[0].z+n[n.length-1].z)/2;i?(e.z=i.z+t(e._,i._),e.m=e.z-a):e.z=a}else i&&(e.z=i.z+t(e._,i._));e.parent.A=function(e,n,r){if(n){for(var i,a=e,o=e,s=n,c=a.parent.children[0],u=a.m,l=o.m,h=s.m,f=c.m;s=pp(s),a=dp(a),s&&a;)c=dp(c),(o=pp(o)).a=e,(i=s.z+h-a.z-u+t(s._,a._))>0&&(gp(yp(s,e,r),e,i),u+=i,l+=i),h+=s.m,u+=a.m,f+=c.m,l+=o.m;s&&!pp(o)&&(o.t=s,o.m+=h-l),a&&!dp(c)&&(c.t=a,c.m+=u-f,r=e)}return r}(e,i,e.parent.A||r[0])}function o(t){t._.x=t.z+t.parent.m,t.m+=t.parent.m}function s(t){t.x*=e,t.y=t.depth*n}return i.separation=function(e){return arguments.length?(t=e,i):t},i.size=function(t){return arguments.length?(r=!1,e=+t[0],n=+t[1],i):r?null:[e,n]},i.nodeSize=function(t){return arguments.length?(r=!0,e=+t[0],n=+t[1],i):r?[e,n]:null},i}function bp(t,e,n,r,i){for(var a,o=t.children,s=-1,c=o.length,u=t.value&&(i-n)/t.value;++sf&&(f=s),y=l*l*g,(d=Math.max(f/y,y/h))>p){l-=s;break}p=d}m.push(o={value:l,dice:c1?e:1)},n}(_p);function kp(){var t=wp,e=!1,n=1,r=1,i=[0],a=Qd,o=Qd,s=Qd,c=Qd,u=Qd;function l(t){return t.x0=t.y0=0,t.x1=n,t.y1=r,t.eachBefore(h),i=[0],e&&t.eachBefore(ip),t}function h(e){var n=i[e.depth],r=e.x0+n,l=e.y0+n,h=e.x1-n,f=e.y1-n;h=n-1){var l=s[e];return l.x0=i,l.y0=a,l.x1=o,void(l.y1=c)}for(var h=u[e],f=r/2+h,d=e+1,p=n-1;d>>1;u[g]c-a){var v=(i*m+o*y)/r;t(e,d,y,i,a,v,c),t(d,n,m,v,a,o,c)}else{var b=(a*m+c*y)/r;t(e,d,y,i,a,o,b),t(d,n,m,i,b,o,c)}}(0,c,t.value,e,n,r,i)}function Cp(t,e,n,r,i){(1&t.depth?bp:ap)(t,e,n,r,i)}const Ep=function t(e){function n(t,n,r,i,a){if((o=t._squarify)&&o.ratio===e)for(var o,s,c,u,l,h=-1,f=o.length,d=t.value;++h1?e:1)},n}(_p);function Sp(t){var e=t.length;return function(n){return t[Math.max(0,Math.min(e-1,Math.floor(n*e)))]}}function Ap(t,e){var n=dn(+t,+e);return function(t){var e=n(t);return e-360*Math.floor(e/360)}}function Mp(t,e){return t=+t,e=+e,function(n){return Math.round(t*(1-n)+e*n)}}var Np=Math.SQRT2;function Dp(t){return((t=Math.exp(t))+1/t)/2}function Bp(t,e){var n,r,i=t[0],a=t[1],o=t[2],s=e[0],c=e[1],u=e[2],l=s-i,h=c-a,f=l*l+h*h;if(f<1e-12)r=Math.log(u/o)/Np,n=function(t){return[i+t*l,a+t*h,o*Math.exp(Np*t*r)]};else{var d=Math.sqrt(f),p=(u*u-o*o+4*f)/(2*o*2*d),g=(u*u-o*o-4*f)/(2*u*2*d),y=Math.log(Math.sqrt(p*p+1)-p),m=Math.log(Math.sqrt(g*g+1)-g);r=(m-y)/Np,n=function(t){var e,n=t*r,s=Dp(y),c=o/(2*d)*(s*(e=Np*n+y,((e=Math.exp(2*e))-1)/(e+1))-function(t){return((t=Math.exp(t))-1/t)/2}(y));return[i+c*l,a+c*h,o*s/Dp(Np*n+y)]}}return n.duration=1e3*r,n}function Lp(t){return function(e,n){var r=t((e=an(e)).h,(n=an(n)).h),i=pn(e.s,n.s),a=pn(e.l,n.l),o=pn(e.opacity,n.opacity);return function(t){return e.h=r(t),e.s=i(t),e.l=a(t),e.opacity=o(t),e+""}}}const Op=Lp(dn);var Ip=Lp(pn);function Rp(t,e){var n=pn((t=Ta(t)).l,(e=Ta(e)).l),r=pn(t.a,e.a),i=pn(t.b,e.b),a=pn(t.opacity,e.opacity);return function(e){return t.l=n(e),t.a=r(e),t.b=i(e),t.opacity=a(e),t+""}}function Fp(t){return function(e,n){var r=t((e=Ba(e)).h,(n=Ba(n)).h),i=pn(e.c,n.c),a=pn(e.l,n.l),o=pn(e.opacity,n.opacity);return function(t){return e.h=r(t),e.c=i(t),e.l=a(t),e.opacity=o(t),e+""}}}const Pp=Fp(dn);var Yp=Fp(pn);function jp(t){return function e(n){function r(e,r){var i=t((e=qa(e)).h,(r=qa(r)).h),a=pn(e.s,r.s),o=pn(e.l,r.l),s=pn(e.opacity,r.opacity);return function(t){return e.h=i(t),e.s=a(t),e.l=o(Math.pow(t,n)),e.opacity=s(t),e+""}}return n=+n,r.gamma=e,r}(1)}const Up=jp(dn);var zp=jp(pn);function $p(t,e){for(var n=0,r=e.length-1,i=e[0],a=new Array(r<0?0:r);n1&&Vp(t[n[r-2]],t[n[r-1]],t[i])<=0;)--r;n[r++]=i}return n.slice(0,r)}function Zp(t){if((n=t.length)<3)return null;var e,n,r=new Array(n),i=new Array(n);for(e=0;e=0;--e)u.push(t[r[a[e]][2]]);for(e=+s;es!=u>s&&o<(c-n)*(s-r)/(u-r)+n&&(l=!l),c=n,u=r;return l}function Kp(t){for(var e,n,r=-1,i=t.length,a=t[i-1],o=a[0],s=a[1],c=0;++r1);return t+n*a*Math.sqrt(-2*Math.log(i)/i)}}return n.source=t,n}(Jp),ng=function t(e){function n(){var t=eg.source(e).apply(this,arguments);return function(){return Math.exp(t())}}return n.source=t,n}(Jp),rg=function t(e){function n(t){return function(){for(var n=0,r=0;rr&&(e=n,n=r,r=e),function(t){return Math.max(n,Math.min(r,t))}}function xg(t,e,n){var r=t[0],i=t[1],a=e[0],o=e[1];return i2?wg:xg,i=a=null,h}function h(e){return isNaN(e=+e)?n:(i||(i=r(o.map(t),s,c)))(t(u(e)))}return h.invert=function(n){return u(e((a||(a=r(s,o.map(t),Tn)))(n)))},h.domain=function(t){return arguments.length?(o=ug.call(t,yg),u===vg||(u=_g(o)),l()):o.slice()},h.range=function(t){return arguments.length?(s=lg.call(t),l()):s.slice()},h.rangeRound=function(t){return s=lg.call(t),c=Mp,l()},h.clamp=function(t){return arguments.length?(u=t?_g(o):vg,h):u!==vg},h.interpolate=function(t){return arguments.length?(c=t,l()):c},h.unknown=function(t){return arguments.length?(n=t,h):n},function(n,r){return t=n,e=r,l()}}function Cg(t,e){return Tg()(t,e)}function Eg(t,e,n,r){var i,a=M(t,e,n);switch((r=cc(null==r?",f":r)).type){case"s":var o=Math.max(Math.abs(t),Math.abs(e));return null!=r.precision||isNaN(i=xc(a,o))||(r.precision=i),gc(r,o);case"":case"e":case"g":case"p":case"r":null!=r.precision||isNaN(i=wc(a,Math.max(Math.abs(t),Math.abs(e))))||(r.precision=i-("e"===r.type));break;case"f":case"%":null!=r.precision||isNaN(i=_c(a))||(r.precision=i-2*("%"===r.type))}return pc(r)}function Sg(t){var e=t.domain;return t.ticks=function(t){var n=e();return S(n[0],n[n.length-1],null==t?10:t)},t.tickFormat=function(t,n){var r=e();return Eg(r[0],r[r.length-1],null==t?10:t,n)},t.nice=function(n){null==n&&(n=10);var r,i=e(),a=0,o=i.length-1,s=i[a],c=i[o];return c0?r=A(s=Math.floor(s/r)*r,c=Math.ceil(c/r)*r,n):r<0&&(r=A(s=Math.ceil(s*r)/r,c=Math.floor(c*r)/r,n)),r>0?(i[a]=Math.floor(s/r)*r,i[o]=Math.ceil(c/r)*r,e(i)):r<0&&(i[a]=Math.ceil(s*r)/r,i[o]=Math.floor(c*r)/r,e(i)),t},t}function Ag(){var t=Cg(vg,vg);return t.copy=function(){return kg(t,Ag())},og.apply(t,arguments),Sg(t)}function Mg(t){var e;function n(t){return isNaN(t=+t)?e:t}return n.invert=n,n.domain=n.range=function(e){return arguments.length?(t=ug.call(e,yg),n):t.slice()},n.unknown=function(t){return arguments.length?(e=t,n):e},n.copy=function(){return Mg(t).unknown(e)},t=arguments.length?ug.call(t,yg):[0,1],Sg(n)}function Ng(t,e){var n,r=0,i=(t=t.slice()).length-1,a=t[r],o=t[i];return o0){for(;fc)break;g.push(h)}}else for(;f=1;--l)if(!((h=u*l)c)break;g.push(h)}}else g=S(f,d,Math.min(d-f,p)).map(n);return r?g.reverse():g},r.tickFormat=function(t,i){if(null==i&&(i=10===a?".0e":","),"function"!=typeof i&&(i=pc(i)),t===1/0)return i;null==t&&(t=10);var o=Math.max(1,a*t/r.ticks().length);return function(t){var r=t/n(Math.round(e(t)));return r*a0?r[i-1]:e[0],i=r?[i[r-1],n]:[i[o-1],i[o]]},o.unknown=function(e){return arguments.length?(t=e,o):o},o.thresholds=function(){return i.slice()},o.copy=function(){return Zg().domain([e,n]).range(a).unknown(t)},og.apply(Sg(o),arguments)}function Qg(){var t,e=[.5],n=[0,1],r=1;function i(i){return i<=i?n[u(e,i,0,r)]:t}return i.domain=function(t){return arguments.length?(e=lg.call(t),r=Math.min(e.length,n.length-1),i):e.slice()},i.range=function(t){return arguments.length?(n=lg.call(t),r=Math.min(e.length,n.length-1),i):n.slice()},i.invertExtent=function(t){var r=n.indexOf(t);return[e[r-1],e[r]]},i.unknown=function(e){return arguments.length?(t=e,i):t},i.copy=function(){return Qg().domain(e).range(n).unknown(t)},og.apply(i,arguments)}var Kg=new Date,Jg=new Date;function ty(t,e,n,r){function i(e){return t(e=0===arguments.length?new Date:new Date(+e)),e}return i.floor=function(e){return t(e=new Date(+e)),e},i.ceil=function(n){return t(n=new Date(n-1)),e(n,1),t(n),n},i.round=function(t){var e=i(t),n=i.ceil(t);return t-e0))return s;do{s.push(o=new Date(+n)),e(n,a),t(n)}while(o=e)for(;t(e),!n(e);)e.setTime(e-1)}),(function(t,r){if(t>=t)if(r<0)for(;++r<=0;)for(;e(t,-1),!n(t););else for(;--r>=0;)for(;e(t,1),!n(t););}))},n&&(i.count=function(e,r){return Kg.setTime(+e),Jg.setTime(+r),t(Kg),t(Jg),Math.floor(n(Kg,Jg))},i.every=function(t){return t=Math.floor(t),isFinite(t)&&t>0?t>1?i.filter(r?function(e){return r(e)%t==0}:function(e){return i.count(0,e)%t==0}):i:null}),i}var ey=ty((function(t){t.setMonth(0,1),t.setHours(0,0,0,0)}),(function(t,e){t.setFullYear(t.getFullYear()+e)}),(function(t,e){return e.getFullYear()-t.getFullYear()}),(function(t){return t.getFullYear()}));ey.every=function(t){return isFinite(t=Math.floor(t))&&t>0?ty((function(e){e.setFullYear(Math.floor(e.getFullYear()/t)*t),e.setMonth(0,1),e.setHours(0,0,0,0)}),(function(e,n){e.setFullYear(e.getFullYear()+n*t)})):null};const ny=ey;var ry=ey.range,iy=ty((function(t){t.setDate(1),t.setHours(0,0,0,0)}),(function(t,e){t.setMonth(t.getMonth()+e)}),(function(t,e){return e.getMonth()-t.getMonth()+12*(e.getFullYear()-t.getFullYear())}),(function(t){return t.getMonth()}));const ay=iy;var oy=iy.range,sy=1e3,cy=6e4,uy=36e5,ly=864e5,hy=6048e5;function fy(t){return ty((function(e){e.setDate(e.getDate()-(e.getDay()+7-t)%7),e.setHours(0,0,0,0)}),(function(t,e){t.setDate(t.getDate()+7*e)}),(function(t,e){return(e-t-(e.getTimezoneOffset()-t.getTimezoneOffset())*cy)/hy}))}var dy=fy(0),py=fy(1),gy=fy(2),yy=fy(3),my=fy(4),vy=fy(5),by=fy(6),_y=dy.range,xy=py.range,wy=gy.range,ky=yy.range,Ty=my.range,Cy=vy.range,Ey=by.range,Sy=ty((function(t){t.setHours(0,0,0,0)}),(function(t,e){t.setDate(t.getDate()+e)}),(function(t,e){return(e-t-(e.getTimezoneOffset()-t.getTimezoneOffset())*cy)/ly}),(function(t){return t.getDate()-1}));const Ay=Sy;var My=Sy.range,Ny=ty((function(t){t.setTime(t-t.getMilliseconds()-t.getSeconds()*sy-t.getMinutes()*cy)}),(function(t,e){t.setTime(+t+e*uy)}),(function(t,e){return(e-t)/uy}),(function(t){return t.getHours()}));const Dy=Ny;var By=Ny.range,Ly=ty((function(t){t.setTime(t-t.getMilliseconds()-t.getSeconds()*sy)}),(function(t,e){t.setTime(+t+e*cy)}),(function(t,e){return(e-t)/cy}),(function(t){return t.getMinutes()}));const Oy=Ly;var Iy=Ly.range,Ry=ty((function(t){t.setTime(t-t.getMilliseconds())}),(function(t,e){t.setTime(+t+e*sy)}),(function(t,e){return(e-t)/sy}),(function(t){return t.getUTCSeconds()}));const Fy=Ry;var Py=Ry.range,Yy=ty((function(){}),(function(t,e){t.setTime(+t+e)}),(function(t,e){return e-t}));Yy.every=function(t){return t=Math.floor(t),isFinite(t)&&t>0?t>1?ty((function(e){e.setTime(Math.floor(e/t)*t)}),(function(e,n){e.setTime(+e+n*t)}),(function(e,n){return(n-e)/t})):Yy:null};const jy=Yy;var Uy=Yy.range;function zy(t){return ty((function(e){e.setUTCDate(e.getUTCDate()-(e.getUTCDay()+7-t)%7),e.setUTCHours(0,0,0,0)}),(function(t,e){t.setUTCDate(t.getUTCDate()+7*e)}),(function(t,e){return(e-t)/hy}))}var $y=zy(0),qy=zy(1),Hy=zy(2),Wy=zy(3),Vy=zy(4),Gy=zy(5),Xy=zy(6),Zy=$y.range,Qy=qy.range,Ky=Hy.range,Jy=Wy.range,tm=Vy.range,em=Gy.range,nm=Xy.range,rm=ty((function(t){t.setUTCHours(0,0,0,0)}),(function(t,e){t.setUTCDate(t.getUTCDate()+e)}),(function(t,e){return(e-t)/ly}),(function(t){return t.getUTCDate()-1}));const im=rm;var am=rm.range,om=ty((function(t){t.setUTCMonth(0,1),t.setUTCHours(0,0,0,0)}),(function(t,e){t.setUTCFullYear(t.getUTCFullYear()+e)}),(function(t,e){return e.getUTCFullYear()-t.getUTCFullYear()}),(function(t){return t.getUTCFullYear()}));om.every=function(t){return isFinite(t=Math.floor(t))&&t>0?ty((function(e){e.setUTCFullYear(Math.floor(e.getUTCFullYear()/t)*t),e.setUTCMonth(0,1),e.setUTCHours(0,0,0,0)}),(function(e,n){e.setUTCFullYear(e.getUTCFullYear()+n*t)})):null};const sm=om;var cm=om.range;function um(t){if(0<=t.y&&t.y<100){var e=new Date(-1,t.m,t.d,t.H,t.M,t.S,t.L);return e.setFullYear(t.y),e}return new Date(t.y,t.m,t.d,t.H,t.M,t.S,t.L)}function lm(t){if(0<=t.y&&t.y<100){var e=new Date(Date.UTC(-1,t.m,t.d,t.H,t.M,t.S,t.L));return e.setUTCFullYear(t.y),e}return new Date(Date.UTC(t.y,t.m,t.d,t.H,t.M,t.S,t.L))}function hm(t,e,n){return{y:t,m:e,d:n,H:0,M:0,S:0,L:0}}function fm(t){var e=t.dateTime,n=t.date,r=t.time,i=t.periods,a=t.days,o=t.shortDays,s=t.months,c=t.shortMonths,u=Tm(i),l=Cm(i),h=Tm(a),f=Cm(a),d=Tm(o),p=Cm(o),g=Tm(s),y=Cm(s),m=Tm(c),v=Cm(c),b={a:function(t){return o[t.getDay()]},A:function(t){return a[t.getDay()]},b:function(t){return c[t.getMonth()]},B:function(t){return s[t.getMonth()]},c:null,d:Wm,e:Wm,f:Qm,g:cv,G:lv,H:Vm,I:Gm,j:Xm,L:Zm,m:Km,M:Jm,p:function(t){return i[+(t.getHours()>=12)]},q:function(t){return 1+~~(t.getMonth()/3)},Q:Lv,s:Ov,S:tv,u:ev,U:nv,V:iv,w:av,W:ov,x:null,X:null,y:sv,Y:uv,Z:hv,"%":Bv},_={a:function(t){return o[t.getUTCDay()]},A:function(t){return a[t.getUTCDay()]},b:function(t){return c[t.getUTCMonth()]},B:function(t){return s[t.getUTCMonth()]},c:null,d:fv,e:fv,f:mv,g:Av,G:Nv,H:dv,I:pv,j:gv,L:yv,m:vv,M:bv,p:function(t){return i[+(t.getUTCHours()>=12)]},q:function(t){return 1+~~(t.getUTCMonth()/3)},Q:Lv,s:Ov,S:_v,u:xv,U:wv,V:Tv,w:Cv,W:Ev,x:null,X:null,y:Sv,Y:Mv,Z:Dv,"%":Bv},x={a:function(t,e,n){var r=d.exec(e.slice(n));return r?(t.w=p[r[0].toLowerCase()],n+r[0].length):-1},A:function(t,e,n){var r=h.exec(e.slice(n));return r?(t.w=f[r[0].toLowerCase()],n+r[0].length):-1},b:function(t,e,n){var r=m.exec(e.slice(n));return r?(t.m=v[r[0].toLowerCase()],n+r[0].length):-1},B:function(t,e,n){var r=g.exec(e.slice(n));return r?(t.m=y[r[0].toLowerCase()],n+r[0].length):-1},c:function(t,n,r){return T(t,e,n,r)},d:Rm,e:Rm,f:zm,g:Bm,G:Dm,H:Pm,I:Pm,j:Fm,L:Um,m:Im,M:Ym,p:function(t,e,n){var r=u.exec(e.slice(n));return r?(t.p=l[r[0].toLowerCase()],n+r[0].length):-1},q:Om,Q:qm,s:Hm,S:jm,u:Sm,U:Am,V:Mm,w:Em,W:Nm,x:function(t,e,r){return T(t,n,e,r)},X:function(t,e,n){return T(t,r,e,n)},y:Bm,Y:Dm,Z:Lm,"%":$m};function w(t,e){return function(n){var r,i,a,o=[],s=-1,c=0,u=t.length;for(n instanceof Date||(n=new Date(+n));++s53)return null;"w"in a||(a.w=1),"Z"in a?(i=(r=lm(hm(a.y,0,1))).getUTCDay(),r=i>4||0===i?qy.ceil(r):qy(r),r=im.offset(r,7*(a.V-1)),a.y=r.getUTCFullYear(),a.m=r.getUTCMonth(),a.d=r.getUTCDate()+(a.w+6)%7):(i=(r=um(hm(a.y,0,1))).getDay(),r=i>4||0===i?py.ceil(r):py(r),r=Ay.offset(r,7*(a.V-1)),a.y=r.getFullYear(),a.m=r.getMonth(),a.d=r.getDate()+(a.w+6)%7)}else("W"in a||"U"in a)&&("w"in a||(a.w="u"in a?a.u%7:"W"in a?1:0),i="Z"in a?lm(hm(a.y,0,1)).getUTCDay():um(hm(a.y,0,1)).getDay(),a.m=0,a.d="W"in a?(a.w+6)%7+7*a.W-(i+5)%7:a.w+7*a.U-(i+6)%7);return"Z"in a?(a.H+=a.Z/100|0,a.M+=a.Z%100,lm(a)):um(a)}}function T(t,e,n,r){for(var i,a,o=0,s=e.length,c=n.length;o=c)return-1;if(37===(i=e.charCodeAt(o++))){if(i=e.charAt(o++),!(a=x[i in vm?e.charAt(o++):i])||(r=a(t,n,r))<0)return-1}else if(i!=n.charCodeAt(r++))return-1}return r}return b.x=w(n,b),b.X=w(r,b),b.c=w(e,b),_.x=w(n,_),_.X=w(r,_),_.c=w(e,_),{format:function(t){var e=w(t+="",b);return e.toString=function(){return t},e},parse:function(t){var e=k(t+="",!1);return e.toString=function(){return t},e},utcFormat:function(t){var e=w(t+="",_);return e.toString=function(){return t},e},utcParse:function(t){var e=k(t+="",!0);return e.toString=function(){return t},e}}}var dm,pm,gm,ym,mm,vm={"-":"",_:" ",0:"0"},bm=/^\s*\d+/,_m=/^%/,xm=/[\\^$*+?|[\]().{}]/g;function wm(t,e,n){var r=t<0?"-":"",i=(r?-t:t)+"",a=i.length;return r+(a68?1900:2e3),n+r[0].length):-1}function Lm(t,e,n){var r=/^(Z)|([+-]\d\d)(?::?(\d\d))?/.exec(e.slice(n,n+6));return r?(t.Z=r[1]?0:-(r[2]+(r[3]||"00")),n+r[0].length):-1}function Om(t,e,n){var r=bm.exec(e.slice(n,n+1));return r?(t.q=3*r[0]-3,n+r[0].length):-1}function Im(t,e,n){var r=bm.exec(e.slice(n,n+2));return r?(t.m=r[0]-1,n+r[0].length):-1}function Rm(t,e,n){var r=bm.exec(e.slice(n,n+2));return r?(t.d=+r[0],n+r[0].length):-1}function Fm(t,e,n){var r=bm.exec(e.slice(n,n+3));return r?(t.m=0,t.d=+r[0],n+r[0].length):-1}function Pm(t,e,n){var r=bm.exec(e.slice(n,n+2));return r?(t.H=+r[0],n+r[0].length):-1}function Ym(t,e,n){var r=bm.exec(e.slice(n,n+2));return r?(t.M=+r[0],n+r[0].length):-1}function jm(t,e,n){var r=bm.exec(e.slice(n,n+2));return r?(t.S=+r[0],n+r[0].length):-1}function Um(t,e,n){var r=bm.exec(e.slice(n,n+3));return r?(t.L=+r[0],n+r[0].length):-1}function zm(t,e,n){var r=bm.exec(e.slice(n,n+6));return r?(t.L=Math.floor(r[0]/1e3),n+r[0].length):-1}function $m(t,e,n){var r=_m.exec(e.slice(n,n+1));return r?n+r[0].length:-1}function qm(t,e,n){var r=bm.exec(e.slice(n));return r?(t.Q=+r[0],n+r[0].length):-1}function Hm(t,e,n){var r=bm.exec(e.slice(n));return r?(t.s=+r[0],n+r[0].length):-1}function Wm(t,e){return wm(t.getDate(),e,2)}function Vm(t,e){return wm(t.getHours(),e,2)}function Gm(t,e){return wm(t.getHours()%12||12,e,2)}function Xm(t,e){return wm(1+Ay.count(ny(t),t),e,3)}function Zm(t,e){return wm(t.getMilliseconds(),e,3)}function Qm(t,e){return Zm(t,e)+"000"}function Km(t,e){return wm(t.getMonth()+1,e,2)}function Jm(t,e){return wm(t.getMinutes(),e,2)}function tv(t,e){return wm(t.getSeconds(),e,2)}function ev(t){var e=t.getDay();return 0===e?7:e}function nv(t,e){return wm(dy.count(ny(t)-1,t),e,2)}function rv(t){var e=t.getDay();return e>=4||0===e?my(t):my.ceil(t)}function iv(t,e){return t=rv(t),wm(my.count(ny(t),t)+(4===ny(t).getDay()),e,2)}function av(t){return t.getDay()}function ov(t,e){return wm(py.count(ny(t)-1,t),e,2)}function sv(t,e){return wm(t.getFullYear()%100,e,2)}function cv(t,e){return wm((t=rv(t)).getFullYear()%100,e,2)}function uv(t,e){return wm(t.getFullYear()%1e4,e,4)}function lv(t,e){var n=t.getDay();return wm((t=n>=4||0===n?my(t):my.ceil(t)).getFullYear()%1e4,e,4)}function hv(t){var e=t.getTimezoneOffset();return(e>0?"-":(e*=-1,"+"))+wm(e/60|0,"0",2)+wm(e%60,"0",2)}function fv(t,e){return wm(t.getUTCDate(),e,2)}function dv(t,e){return wm(t.getUTCHours(),e,2)}function pv(t,e){return wm(t.getUTCHours()%12||12,e,2)}function gv(t,e){return wm(1+im.count(sm(t),t),e,3)}function yv(t,e){return wm(t.getUTCMilliseconds(),e,3)}function mv(t,e){return yv(t,e)+"000"}function vv(t,e){return wm(t.getUTCMonth()+1,e,2)}function bv(t,e){return wm(t.getUTCMinutes(),e,2)}function _v(t,e){return wm(t.getUTCSeconds(),e,2)}function xv(t){var e=t.getUTCDay();return 0===e?7:e}function wv(t,e){return wm($y.count(sm(t)-1,t),e,2)}function kv(t){var e=t.getUTCDay();return e>=4||0===e?Vy(t):Vy.ceil(t)}function Tv(t,e){return t=kv(t),wm(Vy.count(sm(t),t)+(4===sm(t).getUTCDay()),e,2)}function Cv(t){return t.getUTCDay()}function Ev(t,e){return wm(qy.count(sm(t)-1,t),e,2)}function Sv(t,e){return wm(t.getUTCFullYear()%100,e,2)}function Av(t,e){return wm((t=kv(t)).getUTCFullYear()%100,e,2)}function Mv(t,e){return wm(t.getUTCFullYear()%1e4,e,4)}function Nv(t,e){var n=t.getUTCDay();return wm((t=n>=4||0===n?Vy(t):Vy.ceil(t)).getUTCFullYear()%1e4,e,4)}function Dv(){return"+0000"}function Bv(){return"%"}function Lv(t){return+t}function Ov(t){return Math.floor(+t/1e3)}function Iv(t){return dm=fm(t),pm=dm.format,gm=dm.parse,ym=dm.utcFormat,mm=dm.utcParse,dm}Iv({dateTime:"%x, %X",date:"%-m/%-d/%Y",time:"%-I:%M:%S %p",periods:["AM","PM"],days:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],shortDays:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],months:["January","February","March","April","May","June","July","August","September","October","November","December"],shortMonths:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"]});var Rv=31536e6;function Fv(t){return new Date(t)}function Pv(t){return t instanceof Date?+t:+new Date(+t)}function Yv(t,e,n,r,i,o,s,c,u){var l=Cg(vg,vg),h=l.invert,f=l.domain,d=u(".%L"),p=u(":%S"),g=u("%I:%M"),y=u("%I %p"),m=u("%a %d"),v=u("%b %d"),b=u("%B"),_=u("%Y"),x=[[s,1,1e3],[s,5,5e3],[s,15,15e3],[s,30,3e4],[o,1,6e4],[o,5,3e5],[o,15,9e5],[o,30,18e5],[i,1,36e5],[i,3,108e5],[i,6,216e5],[i,12,432e5],[r,1,864e5],[r,2,1728e5],[n,1,6048e5],[e,1,2592e6],[e,3,7776e6],[t,1,Rv]];function w(a){return(s(a)1)&&(t-=Math.floor(t));var e=Math.abs(t-.5);return S_.h=360*t-100,S_.s=1.5-1.5*e,S_.l=.8-.9*e,S_+""}var M_=Qe(),N_=Math.PI/3,D_=2*Math.PI/3;function B_(t){var e;return t=(.5-t)*Math.PI,M_.r=255*(e=Math.sin(t))*e,M_.g=255*(e=Math.sin(t+N_))*e,M_.b=255*(e=Math.sin(t+D_))*e,M_+""}function L_(t){return t=Math.max(0,Math.min(1,t)),"rgb("+Math.max(0,Math.min(255,Math.round(34.61+t*(1172.33-t*(10793.56-t*(33300.12-t*(38394.49-14825.05*t)))))))+", "+Math.max(0,Math.min(255,Math.round(23.31+t*(557.33+t*(1225.33-t*(3574.96-t*(1073.77+707.56*t)))))))+", "+Math.max(0,Math.min(255,Math.round(27.2+t*(3211.1-t*(15327.97-t*(27814-t*(22569.18-6838.66*t)))))))+")"}function O_(t){var e=t.length;return function(n){return t[Math.max(0,Math.min(e-1,Math.floor(n*e)))]}}const I_=O_(hb("44015444025645045745055946075a46085c460a5d460b5e470d60470e6147106347116447136548146748166848176948186a481a6c481b6d481c6e481d6f481f70482071482173482374482475482576482677482878482979472a7a472c7a472d7b472e7c472f7d46307e46327e46337f463480453581453781453882443983443a83443b84433d84433e85423f854240864241864142874144874045884046883f47883f48893e49893e4a893e4c8a3d4d8a3d4e8a3c4f8a3c508b3b518b3b528b3a538b3a548c39558c39568c38588c38598c375a8c375b8d365c8d365d8d355e8d355f8d34608d34618d33628d33638d32648e32658e31668e31678e31688e30698e306a8e2f6b8e2f6c8e2e6d8e2e6e8e2e6f8e2d708e2d718e2c718e2c728e2c738e2b748e2b758e2a768e2a778e2a788e29798e297a8e297b8e287c8e287d8e277e8e277f8e27808e26818e26828e26828e25838e25848e25858e24868e24878e23888e23898e238a8d228b8d228c8d228d8d218e8d218f8d21908d21918c20928c20928c20938c1f948c1f958b1f968b1f978b1f988b1f998a1f9a8a1e9b8a1e9c891e9d891f9e891f9f881fa0881fa1881fa1871fa28720a38620a48621a58521a68522a78522a88423a98324aa8325ab8225ac8226ad8127ad8128ae8029af7f2ab07f2cb17e2db27d2eb37c2fb47c31b57b32b67a34b67935b77937b87838b9773aba763bbb753dbc743fbc7340bd7242be7144bf7046c06f48c16e4ac16d4cc26c4ec36b50c46a52c56954c56856c66758c7655ac8645cc8635ec96260ca6063cb5f65cb5e67cc5c69cd5b6ccd5a6ece5870cf5773d05675d05477d1537ad1517cd2507fd34e81d34d84d44b86d54989d5488bd6468ed64590d74393d74195d84098d83e9bd93c9dd93ba0da39a2da37a5db36a8db34aadc32addc30b0dd2fb2dd2db5de2bb8de29bade28bddf26c0df25c2df23c5e021c8e020cae11fcde11dd0e11cd2e21bd5e21ad8e219dae319dde318dfe318e2e418e5e419e7e419eae51aece51befe51cf1e51df4e61ef6e620f8e621fbe723fde725"));var R_=O_(hb("00000401000501010601010802010902020b02020d03030f03031204041405041606051806051a07061c08071e0907200a08220b09240c09260d0a290e0b2b100b2d110c2f120d31130d34140e36150e38160f3b180f3d19103f1a10421c10441d11471e114920114b21114e22115024125325125527125829115a2a115c2c115f2d11612f116331116533106734106936106b38106c390f6e3b0f703d0f713f0f72400f74420f75440f764510774710784910784a10794c117a4e117b4f127b51127c52137c54137d56147d57157e59157e5a167e5c167f5d177f5f187f601880621980641a80651a80671b80681c816a1c816b1d816d1d816e1e81701f81721f817320817521817621817822817922827b23827c23827e24828025828125818326818426818627818827818928818b29818c29818e2a81902a81912b81932b80942c80962c80982d80992d809b2e7f9c2e7f9e2f7fa02f7fa1307ea3307ea5317ea6317da8327daa337dab337cad347cae347bb0357bb2357bb3367ab5367ab73779b83779ba3878bc3978bd3977bf3a77c03a76c23b75c43c75c53c74c73d73c83e73ca3e72cc3f71cd4071cf4070d0416fd2426fd3436ed5446dd6456cd8456cd9466bdb476adc4869de4968df4a68e04c67e24d66e34e65e44f64e55064e75263e85362e95462ea5661eb5760ec5860ed5a5fee5b5eef5d5ef05f5ef1605df2625df2645cf3655cf4675cf4695cf56b5cf66c5cf66e5cf7705cf7725cf8745cf8765cf9785df9795df97b5dfa7d5efa7f5efa815ffb835ffb8560fb8761fc8961fc8a62fc8c63fc8e64fc9065fd9266fd9467fd9668fd9869fd9a6afd9b6bfe9d6cfe9f6dfea16efea36ffea571fea772fea973feaa74feac76feae77feb078feb27afeb47bfeb67cfeb77efeb97ffebb81febd82febf84fec185fec287fec488fec68afec88cfeca8dfecc8ffecd90fecf92fed194fed395fed597fed799fed89afdda9cfddc9efddea0fde0a1fde2a3fde3a5fde5a7fde7a9fde9aafdebacfcecaefceeb0fcf0b2fcf2b4fcf4b6fcf6b8fcf7b9fcf9bbfcfbbdfcfdbf")),F_=O_(hb("00000401000501010601010802010a02020c02020e03021004031204031405041706041907051b08051d09061f0a07220b07240c08260d08290e092b10092d110a30120a32140b34150b37160b39180c3c190c3e1b0c411c0c431e0c451f0c48210c4a230c4c240c4f260c51280b53290b552b0b572d0b592f0a5b310a5c320a5e340a5f3609613809623909633b09643d09653e0966400a67420a68440a68450a69470b6a490b6a4a0c6b4c0c6b4d0d6c4f0d6c510e6c520e6d540f6d550f6d57106e59106e5a116e5c126e5d126e5f136e61136e62146e64156e65156e67166e69166e6a176e6c186e6d186e6f196e71196e721a6e741a6e751b6e771c6d781c6d7a1d6d7c1d6d7d1e6d7f1e6c801f6c82206c84206b85216b87216b88226a8a226a8c23698d23698f24699025689225689326679526679727669827669a28659b29649d29649f2a63a02a63a22b62a32c61a52c60a62d60a82e5fa92e5eab2f5ead305dae305cb0315bb1325ab3325ab43359b63458b73557b93556ba3655bc3754bd3853bf3952c03a51c13a50c33b4fc43c4ec63d4dc73e4cc83f4bca404acb4149cc4248ce4347cf4446d04545d24644d34743d44842d54a41d74b3fd84c3ed94d3dda4e3cdb503bdd513ade5238df5337e05536e15635e25734e35933e45a31e55c30e65d2fe75e2ee8602de9612bea632aeb6429eb6628ec6726ed6925ee6a24ef6c23ef6e21f06f20f1711ff1731df2741cf3761bf37819f47918f57b17f57d15f67e14f68013f78212f78410f8850ff8870ef8890cf98b0bf98c0af98e09fa9008fa9207fa9407fb9606fb9706fb9906fb9b06fb9d07fc9f07fca108fca309fca50afca60cfca80dfcaa0ffcac11fcae12fcb014fcb216fcb418fbb61afbb81dfbba1ffbbc21fbbe23fac026fac228fac42afac62df9c72ff9c932f9cb35f8cd37f8cf3af7d13df7d340f6d543f6d746f5d949f5db4cf4dd4ff4df53f4e156f3e35af3e55df2e661f2e865f2ea69f1ec6df1ed71f1ef75f1f179f2f27df2f482f3f586f3f68af4f88ef5f992f6fa96f8fb9af9fc9dfafda1fcffa4")),P_=O_(hb("0d088710078813078916078a19068c1b068d1d068e20068f2206902406912605912805922a05932c05942e05952f059631059733059735049837049938049a3a049a3c049b3e049c3f049c41049d43039e44039e46039f48039f4903a04b03a14c02a14e02a25002a25102a35302a35502a45601a45801a45901a55b01a55c01a65e01a66001a66100a76300a76400a76600a76700a86900a86a00a86c00a86e00a86f00a87100a87201a87401a87501a87701a87801a87a02a87b02a87d03a87e03a88004a88104a78305a78405a78606a68707a68808a68a09a58b0aa58d0ba58e0ca48f0da4910ea3920fa39410a29511a19613a19814a099159f9a169f9c179e9d189d9e199da01a9ca11b9ba21d9aa31e9aa51f99a62098a72197a82296aa2395ab2494ac2694ad2793ae2892b02991b12a90b22b8fb32c8eb42e8db52f8cb6308bb7318ab83289ba3388bb3488bc3587bd3786be3885bf3984c03a83c13b82c23c81c33d80c43e7fc5407ec6417dc7427cc8437bc9447aca457acb4679cc4778cc4977cd4a76ce4b75cf4c74d04d73d14e72d24f71d35171d45270d5536fd5546ed6556dd7566cd8576bd9586ada5a6ada5b69db5c68dc5d67dd5e66de5f65de6164df6263e06363e16462e26561e26660e3685fe4695ee56a5de56b5de66c5ce76e5be76f5ae87059e97158e97257ea7457eb7556eb7655ec7754ed7953ed7a52ee7b51ef7c51ef7e50f07f4ff0804ef1814df1834cf2844bf3854bf3874af48849f48948f58b47f58c46f68d45f68f44f79044f79143f79342f89441f89540f9973ff9983ef99a3efa9b3dfa9c3cfa9e3bfb9f3afba139fba238fca338fca537fca636fca835fca934fdab33fdac33fdae32fdaf31fdb130fdb22ffdb42ffdb52efeb72dfeb82cfeba2cfebb2bfebd2afebe2afec029fdc229fdc328fdc527fdc627fdc827fdca26fdcb26fccd25fcce25fcd025fcd225fbd324fbd524fbd724fad824fada24f9dc24f9dd25f8df25f8e125f7e225f7e425f6e626f6e826f5e926f5eb27f4ed27f3ee27f3f027f2f227f1f426f1f525f0f724f0f921"));function Y_(t){return Te(ie(t).call(document.documentElement))}var j_=0;function U_(){return new z_}function z_(){this._="@"+(++j_).toString(36)}function $_(t){return"string"==typeof t?new xe([document.querySelectorAll(t)],[document.documentElement]):new xe([null==t?[]:t],_e)}function q_(t,e){null==e&&(e=Nn().touches);for(var n=0,r=e?e.length:0,i=new Array(r);n1?0:t<-1?tx:Math.acos(t)}function ix(t){return t>=1?ex:t<=-1?-ex:Math.asin(t)}function ax(t){return t.innerRadius}function ox(t){return t.outerRadius}function sx(t){return t.startAngle}function cx(t){return t.endAngle}function ux(t){return t&&t.padAngle}function lx(t,e,n,r,i,a,o,s){var c=n-t,u=r-e,l=o-i,h=s-a,f=h*c-l*u;if(!(f*fN*N+D*D&&(T=E,C=S),{cx:T,cy:C,x01:-l,y01:-h,x11:T*(i/x-1),y11:C*(i/x-1)}}function fx(){var t=ax,e=ox,n=H_(0),r=null,i=sx,a=cx,o=ux,s=null;function c(){var c,u,l=+t.apply(this,arguments),h=+e.apply(this,arguments),f=i.apply(this,arguments)-ex,d=a.apply(this,arguments)-ex,p=W_(d-f),g=d>f;if(s||(s=c=Wi()),hJ_)if(p>nx-J_)s.moveTo(h*G_(f),h*Q_(f)),s.arc(0,0,h,f,d,!g),l>J_&&(s.moveTo(l*G_(d),l*Q_(d)),s.arc(0,0,l,d,f,g));else{var y,m,v=f,b=d,_=f,x=d,w=p,k=p,T=o.apply(this,arguments)/2,C=T>J_&&(r?+r.apply(this,arguments):K_(l*l+h*h)),E=Z_(W_(h-l)/2,+n.apply(this,arguments)),S=E,A=E;if(C>J_){var M=ix(C/l*Q_(T)),N=ix(C/h*Q_(T));(w-=2*M)>J_?(_+=M*=g?1:-1,x-=M):(w=0,_=x=(f+d)/2),(k-=2*N)>J_?(v+=N*=g?1:-1,b-=N):(k=0,v=b=(f+d)/2)}var D=h*G_(v),B=h*Q_(v),L=l*G_(x),O=l*Q_(x);if(E>J_){var I,R=h*G_(b),F=h*Q_(b),P=l*G_(_),Y=l*Q_(_);if(pJ_?A>J_?(y=hx(P,Y,D,B,h,A,g),m=hx(R,F,L,O,h,A,g),s.moveTo(y.cx+y.x01,y.cy+y.y01),AJ_&&w>J_?S>J_?(y=hx(L,O,R,F,l,-S,g),m=hx(D,B,P,Y,l,-S,g),s.lineTo(y.cx+y.x01,y.cy+y.y01),S=l;--h)s.point(y[h],m[h]);s.lineEnd(),s.areaEnd()}g&&(y[u]=+t(f,u,c),m[u]=+n(f,u,c),s.point(e?+e(f,u,c):y[u],r?+r(f,u,c):m[u]))}if(d)return s=null,d+""||null}function u(){return mx().defined(i).curve(o).context(a)}return c.x=function(n){return arguments.length?(t="function"==typeof n?n:H_(+n),e=null,c):t},c.x0=function(e){return arguments.length?(t="function"==typeof e?e:H_(+e),c):t},c.x1=function(t){return arguments.length?(e=null==t?null:"function"==typeof t?t:H_(+t),c):e},c.y=function(t){return arguments.length?(n="function"==typeof t?t:H_(+t),r=null,c):n},c.y0=function(t){return arguments.length?(n="function"==typeof t?t:H_(+t),c):n},c.y1=function(t){return arguments.length?(r=null==t?null:"function"==typeof t?t:H_(+t),c):r},c.lineX0=c.lineY0=function(){return u().x(t).y(n)},c.lineY1=function(){return u().x(t).y(r)},c.lineX1=function(){return u().x(e).y(n)},c.defined=function(t){return arguments.length?(i="function"==typeof t?t:H_(!!t),c):i},c.curve=function(t){return arguments.length?(o=t,null!=a&&(s=o(a)),c):o},c.context=function(t){return arguments.length?(null==t?a=s=null:s=o(a=t),c):a},c}function bx(t,e){return et?1:e>=t?0:NaN}function _x(t){return t}function xx(){var t=_x,e=bx,n=null,r=H_(0),i=H_(nx),a=H_(0);function o(o){var s,c,u,l,h,f=o.length,d=0,p=new Array(f),g=new Array(f),y=+r.apply(this,arguments),m=Math.min(nx,Math.max(-nx,i.apply(this,arguments)-y)),v=Math.min(Math.abs(m)/f,a.apply(this,arguments)),b=v*(m<0?-1:1);for(s=0;s0&&(d+=h);for(null!=e?p.sort((function(t,n){return e(g[t],g[n])})):null!=n&&p.sort((function(t,e){return n(o[t],o[e])})),s=0,u=d?(m-f*b)/d:0;s0?h*u:0)+b,g[c]={data:o[c],index:s,value:h,startAngle:y,endAngle:l,padAngle:v};return g}return o.value=function(e){return arguments.length?(t="function"==typeof e?e:H_(+e),o):t},o.sortValues=function(t){return arguments.length?(e=t,n=null,o):e},o.sort=function(t){return arguments.length?(n=t,e=null,o):n},o.startAngle=function(t){return arguments.length?(r="function"==typeof t?t:H_(+t),o):r},o.endAngle=function(t){return arguments.length?(i="function"==typeof t?t:H_(+t),o):i},o.padAngle=function(t){return arguments.length?(a="function"==typeof t?t:H_(+t),o):a},o}dx.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._point=0},lineEnd:function(){(this._line||0!==this._line&&1===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(t,e){switch(t=+t,e=+e,this._point){case 0:this._point=1,this._line?this._context.lineTo(t,e):this._context.moveTo(t,e);break;case 1:this._point=2;default:this._context.lineTo(t,e)}}};var wx=Tx(px);function kx(t){this._curve=t}function Tx(t){function e(e){return new kx(t(e))}return e._curve=t,e}function Cx(t){var e=t.curve;return t.angle=t.x,delete t.x,t.radius=t.y,delete t.y,t.curve=function(t){return arguments.length?e(Tx(t)):e()._curve},t}function Ex(){return Cx(mx().curve(wx))}function Sx(){var t=vx().curve(wx),e=t.curve,n=t.lineX0,r=t.lineX1,i=t.lineY0,a=t.lineY1;return t.angle=t.x,delete t.x,t.startAngle=t.x0,delete t.x0,t.endAngle=t.x1,delete t.x1,t.radius=t.y,delete t.y,t.innerRadius=t.y0,delete t.y0,t.outerRadius=t.y1,delete t.y1,t.lineStartAngle=function(){return Cx(n())},delete t.lineX0,t.lineEndAngle=function(){return Cx(r())},delete t.lineX1,t.lineInnerRadius=function(){return Cx(i())},delete t.lineY0,t.lineOuterRadius=function(){return Cx(a())},delete t.lineY1,t.curve=function(t){return arguments.length?e(Tx(t)):e()._curve},t}function Ax(t,e){return[(e=+e)*Math.cos(t-=Math.PI/2),e*Math.sin(t)]}kx.prototype={areaStart:function(){this._curve.areaStart()},areaEnd:function(){this._curve.areaEnd()},lineStart:function(){this._curve.lineStart()},lineEnd:function(){this._curve.lineEnd()},point:function(t,e){this._curve.point(e*Math.sin(t),e*-Math.cos(t))}};var Mx=Array.prototype.slice;function Nx(t){return t.source}function Dx(t){return t.target}function Bx(t){var e=Nx,n=Dx,r=gx,i=yx,a=null;function o(){var o,s=Mx.call(arguments),c=e.apply(this,s),u=n.apply(this,s);if(a||(a=o=Wi()),t(a,+r.apply(this,(s[0]=c,s)),+i.apply(this,s),+r.apply(this,(s[0]=u,s)),+i.apply(this,s)),o)return a=null,o+""||null}return o.source=function(t){return arguments.length?(e=t,o):e},o.target=function(t){return arguments.length?(n=t,o):n},o.x=function(t){return arguments.length?(r="function"==typeof t?t:H_(+t),o):r},o.y=function(t){return arguments.length?(i="function"==typeof t?t:H_(+t),o):i},o.context=function(t){return arguments.length?(a=null==t?null:t,o):a},o}function Lx(t,e,n,r,i){t.moveTo(e,n),t.bezierCurveTo(e=(e+r)/2,n,e,i,r,i)}function Ox(t,e,n,r,i){t.moveTo(e,n),t.bezierCurveTo(e,n=(n+i)/2,r,n,r,i)}function Ix(t,e,n,r,i){var a=Ax(e,n),o=Ax(e,n=(n+i)/2),s=Ax(r,n),c=Ax(r,i);t.moveTo(a[0],a[1]),t.bezierCurveTo(o[0],o[1],s[0],s[1],c[0],c[1])}function Rx(){return Bx(Lx)}function Fx(){return Bx(Ox)}function Px(){var t=Bx(Ix);return t.angle=t.x,delete t.x,t.radius=t.y,delete t.y,t}const Yx={draw:function(t,e){var n=Math.sqrt(e/tx);t.moveTo(n,0),t.arc(0,0,n,0,nx)}},jx={draw:function(t,e){var n=Math.sqrt(e/5)/2;t.moveTo(-3*n,-n),t.lineTo(-n,-n),t.lineTo(-n,-3*n),t.lineTo(n,-3*n),t.lineTo(n,-n),t.lineTo(3*n,-n),t.lineTo(3*n,n),t.lineTo(n,n),t.lineTo(n,3*n),t.lineTo(-n,3*n),t.lineTo(-n,n),t.lineTo(-3*n,n),t.closePath()}};var Ux=Math.sqrt(1/3),zx=2*Ux;const $x={draw:function(t,e){var n=Math.sqrt(e/zx),r=n*Ux;t.moveTo(0,-n),t.lineTo(r,0),t.lineTo(0,n),t.lineTo(-r,0),t.closePath()}};var qx=Math.sin(tx/10)/Math.sin(7*tx/10),Hx=Math.sin(nx/10)*qx,Wx=-Math.cos(nx/10)*qx;const Vx={draw:function(t,e){var n=Math.sqrt(.8908130915292852*e),r=Hx*n,i=Wx*n;t.moveTo(0,-n),t.lineTo(r,i);for(var a=1;a<5;++a){var o=nx*a/5,s=Math.cos(o),c=Math.sin(o);t.lineTo(c*n,-s*n),t.lineTo(s*r-c*i,c*r+s*i)}t.closePath()}},Gx={draw:function(t,e){var n=Math.sqrt(e),r=-n/2;t.rect(r,r,n,n)}};var Xx=Math.sqrt(3);const Zx={draw:function(t,e){var n=-Math.sqrt(e/(3*Xx));t.moveTo(0,2*n),t.lineTo(-Xx*n,-n),t.lineTo(Xx*n,-n),t.closePath()}};var Qx=-.5,Kx=Math.sqrt(3)/2,Jx=1/Math.sqrt(12),tw=3*(Jx/2+1);const ew={draw:function(t,e){var n=Math.sqrt(e/tw),r=n/2,i=n*Jx,a=r,o=n*Jx+n,s=-a,c=o;t.moveTo(r,i),t.lineTo(a,o),t.lineTo(s,c),t.lineTo(Qx*r-Kx*i,Kx*r+Qx*i),t.lineTo(Qx*a-Kx*o,Kx*a+Qx*o),t.lineTo(Qx*s-Kx*c,Kx*s+Qx*c),t.lineTo(Qx*r+Kx*i,Qx*i-Kx*r),t.lineTo(Qx*a+Kx*o,Qx*o-Kx*a),t.lineTo(Qx*s+Kx*c,Qx*c-Kx*s),t.closePath()}};var nw=[Yx,jx,$x,Gx,Vx,Zx,ew];function rw(){var t=H_(Yx),e=H_(64),n=null;function r(){var r;if(n||(n=r=Wi()),t.apply(this,arguments).draw(n,+e.apply(this,arguments)),r)return n=null,r+""||null}return r.type=function(e){return arguments.length?(t="function"==typeof e?e:H_(e),r):t},r.size=function(t){return arguments.length?(e="function"==typeof t?t:H_(+t),r):e},r.context=function(t){return arguments.length?(n=null==t?null:t,r):n},r}function iw(){}function aw(t,e,n){t._context.bezierCurveTo((2*t._x0+t._x1)/3,(2*t._y0+t._y1)/3,(t._x0+2*t._x1)/3,(t._y0+2*t._y1)/3,(t._x0+4*t._x1+e)/6,(t._y0+4*t._y1+n)/6)}function ow(t){this._context=t}function sw(t){return new ow(t)}function cw(t){this._context=t}function uw(t){return new cw(t)}function lw(t){this._context=t}function hw(t){return new lw(t)}function fw(t,e){this._basis=new ow(t),this._beta=e}ow.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._y0=this._y1=NaN,this._point=0},lineEnd:function(){switch(this._point){case 3:aw(this,this._x1,this._y1);case 2:this._context.lineTo(this._x1,this._y1)}(this._line||0!==this._line&&1===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(t,e){switch(t=+t,e=+e,this._point){case 0:this._point=1,this._line?this._context.lineTo(t,e):this._context.moveTo(t,e);break;case 1:this._point=2;break;case 2:this._point=3,this._context.lineTo((5*this._x0+this._x1)/6,(5*this._y0+this._y1)/6);default:aw(this,t,e)}this._x0=this._x1,this._x1=t,this._y0=this._y1,this._y1=e}},cw.prototype={areaStart:iw,areaEnd:iw,lineStart:function(){this._x0=this._x1=this._x2=this._x3=this._x4=this._y0=this._y1=this._y2=this._y3=this._y4=NaN,this._point=0},lineEnd:function(){switch(this._point){case 1:this._context.moveTo(this._x2,this._y2),this._context.closePath();break;case 2:this._context.moveTo((this._x2+2*this._x3)/3,(this._y2+2*this._y3)/3),this._context.lineTo((this._x3+2*this._x2)/3,(this._y3+2*this._y2)/3),this._context.closePath();break;case 3:this.point(this._x2,this._y2),this.point(this._x3,this._y3),this.point(this._x4,this._y4)}},point:function(t,e){switch(t=+t,e=+e,this._point){case 0:this._point=1,this._x2=t,this._y2=e;break;case 1:this._point=2,this._x3=t,this._y3=e;break;case 2:this._point=3,this._x4=t,this._y4=e,this._context.moveTo((this._x0+4*this._x1+t)/6,(this._y0+4*this._y1+e)/6);break;default:aw(this,t,e)}this._x0=this._x1,this._x1=t,this._y0=this._y1,this._y1=e}},lw.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._y0=this._y1=NaN,this._point=0},lineEnd:function(){(this._line||0!==this._line&&3===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(t,e){switch(t=+t,e=+e,this._point){case 0:this._point=1;break;case 1:this._point=2;break;case 2:this._point=3;var n=(this._x0+4*this._x1+t)/6,r=(this._y0+4*this._y1+e)/6;this._line?this._context.lineTo(n,r):this._context.moveTo(n,r);break;case 3:this._point=4;default:aw(this,t,e)}this._x0=this._x1,this._x1=t,this._y0=this._y1,this._y1=e}},fw.prototype={lineStart:function(){this._x=[],this._y=[],this._basis.lineStart()},lineEnd:function(){var t=this._x,e=this._y,n=t.length-1;if(n>0)for(var r,i=t[0],a=e[0],o=t[n]-i,s=e[n]-a,c=-1;++c<=n;)r=c/n,this._basis.point(this._beta*t[c]+(1-this._beta)*(i+r*o),this._beta*e[c]+(1-this._beta)*(a+r*s));this._x=this._y=null,this._basis.lineEnd()},point:function(t,e){this._x.push(+t),this._y.push(+e)}};const dw=function t(e){function n(t){return 1===e?new ow(t):new fw(t,e)}return n.beta=function(e){return t(+e)},n}(.85);function pw(t,e,n){t._context.bezierCurveTo(t._x1+t._k*(t._x2-t._x0),t._y1+t._k*(t._y2-t._y0),t._x2+t._k*(t._x1-e),t._y2+t._k*(t._y1-n),t._x2,t._y2)}function gw(t,e){this._context=t,this._k=(1-e)/6}gw.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._x2=this._y0=this._y1=this._y2=NaN,this._point=0},lineEnd:function(){switch(this._point){case 2:this._context.lineTo(this._x2,this._y2);break;case 3:pw(this,this._x1,this._y1)}(this._line||0!==this._line&&1===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(t,e){switch(t=+t,e=+e,this._point){case 0:this._point=1,this._line?this._context.lineTo(t,e):this._context.moveTo(t,e);break;case 1:this._point=2,this._x1=t,this._y1=e;break;case 2:this._point=3;default:pw(this,t,e)}this._x0=this._x1,this._x1=this._x2,this._x2=t,this._y0=this._y1,this._y1=this._y2,this._y2=e}};const yw=function t(e){function n(t){return new gw(t,e)}return n.tension=function(e){return t(+e)},n}(0);function mw(t,e){this._context=t,this._k=(1-e)/6}mw.prototype={areaStart:iw,areaEnd:iw,lineStart:function(){this._x0=this._x1=this._x2=this._x3=this._x4=this._x5=this._y0=this._y1=this._y2=this._y3=this._y4=this._y5=NaN,this._point=0},lineEnd:function(){switch(this._point){case 1:this._context.moveTo(this._x3,this._y3),this._context.closePath();break;case 2:this._context.lineTo(this._x3,this._y3),this._context.closePath();break;case 3:this.point(this._x3,this._y3),this.point(this._x4,this._y4),this.point(this._x5,this._y5)}},point:function(t,e){switch(t=+t,e=+e,this._point){case 0:this._point=1,this._x3=t,this._y3=e;break;case 1:this._point=2,this._context.moveTo(this._x4=t,this._y4=e);break;case 2:this._point=3,this._x5=t,this._y5=e;break;default:pw(this,t,e)}this._x0=this._x1,this._x1=this._x2,this._x2=t,this._y0=this._y1,this._y1=this._y2,this._y2=e}};const vw=function t(e){function n(t){return new mw(t,e)}return n.tension=function(e){return t(+e)},n}(0);function bw(t,e){this._context=t,this._k=(1-e)/6}bw.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._x2=this._y0=this._y1=this._y2=NaN,this._point=0},lineEnd:function(){(this._line||0!==this._line&&3===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(t,e){switch(t=+t,e=+e,this._point){case 0:this._point=1;break;case 1:this._point=2;break;case 2:this._point=3,this._line?this._context.lineTo(this._x2,this._y2):this._context.moveTo(this._x2,this._y2);break;case 3:this._point=4;default:pw(this,t,e)}this._x0=this._x1,this._x1=this._x2,this._x2=t,this._y0=this._y1,this._y1=this._y2,this._y2=e}};const _w=function t(e){function n(t){return new bw(t,e)}return n.tension=function(e){return t(+e)},n}(0);function xw(t,e,n){var r=t._x1,i=t._y1,a=t._x2,o=t._y2;if(t._l01_a>J_){var s=2*t._l01_2a+3*t._l01_a*t._l12_a+t._l12_2a,c=3*t._l01_a*(t._l01_a+t._l12_a);r=(r*s-t._x0*t._l12_2a+t._x2*t._l01_2a)/c,i=(i*s-t._y0*t._l12_2a+t._y2*t._l01_2a)/c}if(t._l23_a>J_){var u=2*t._l23_2a+3*t._l23_a*t._l12_a+t._l12_2a,l=3*t._l23_a*(t._l23_a+t._l12_a);a=(a*u+t._x1*t._l23_2a-e*t._l12_2a)/l,o=(o*u+t._y1*t._l23_2a-n*t._l12_2a)/l}t._context.bezierCurveTo(r,i,a,o,t._x2,t._y2)}function ww(t,e){this._context=t,this._alpha=e}ww.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._x2=this._y0=this._y1=this._y2=NaN,this._l01_a=this._l12_a=this._l23_a=this._l01_2a=this._l12_2a=this._l23_2a=this._point=0},lineEnd:function(){switch(this._point){case 2:this._context.lineTo(this._x2,this._y2);break;case 3:this.point(this._x2,this._y2)}(this._line||0!==this._line&&1===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(t,e){if(t=+t,e=+e,this._point){var n=this._x2-t,r=this._y2-e;this._l23_a=Math.sqrt(this._l23_2a=Math.pow(n*n+r*r,this._alpha))}switch(this._point){case 0:this._point=1,this._line?this._context.lineTo(t,e):this._context.moveTo(t,e);break;case 1:this._point=2;break;case 2:this._point=3;default:xw(this,t,e)}this._l01_a=this._l12_a,this._l12_a=this._l23_a,this._l01_2a=this._l12_2a,this._l12_2a=this._l23_2a,this._x0=this._x1,this._x1=this._x2,this._x2=t,this._y0=this._y1,this._y1=this._y2,this._y2=e}};const kw=function t(e){function n(t){return e?new ww(t,e):new gw(t,0)}return n.alpha=function(e){return t(+e)},n}(.5);function Tw(t,e){this._context=t,this._alpha=e}Tw.prototype={areaStart:iw,areaEnd:iw,lineStart:function(){this._x0=this._x1=this._x2=this._x3=this._x4=this._x5=this._y0=this._y1=this._y2=this._y3=this._y4=this._y5=NaN,this._l01_a=this._l12_a=this._l23_a=this._l01_2a=this._l12_2a=this._l23_2a=this._point=0},lineEnd:function(){switch(this._point){case 1:this._context.moveTo(this._x3,this._y3),this._context.closePath();break;case 2:this._context.lineTo(this._x3,this._y3),this._context.closePath();break;case 3:this.point(this._x3,this._y3),this.point(this._x4,this._y4),this.point(this._x5,this._y5)}},point:function(t,e){if(t=+t,e=+e,this._point){var n=this._x2-t,r=this._y2-e;this._l23_a=Math.sqrt(this._l23_2a=Math.pow(n*n+r*r,this._alpha))}switch(this._point){case 0:this._point=1,this._x3=t,this._y3=e;break;case 1:this._point=2,this._context.moveTo(this._x4=t,this._y4=e);break;case 2:this._point=3,this._x5=t,this._y5=e;break;default:xw(this,t,e)}this._l01_a=this._l12_a,this._l12_a=this._l23_a,this._l01_2a=this._l12_2a,this._l12_2a=this._l23_2a,this._x0=this._x1,this._x1=this._x2,this._x2=t,this._y0=this._y1,this._y1=this._y2,this._y2=e}};const Cw=function t(e){function n(t){return e?new Tw(t,e):new mw(t,0)}return n.alpha=function(e){return t(+e)},n}(.5);function Ew(t,e){this._context=t,this._alpha=e}Ew.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._x2=this._y0=this._y1=this._y2=NaN,this._l01_a=this._l12_a=this._l23_a=this._l01_2a=this._l12_2a=this._l23_2a=this._point=0},lineEnd:function(){(this._line||0!==this._line&&3===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(t,e){if(t=+t,e=+e,this._point){var n=this._x2-t,r=this._y2-e;this._l23_a=Math.sqrt(this._l23_2a=Math.pow(n*n+r*r,this._alpha))}switch(this._point){case 0:this._point=1;break;case 1:this._point=2;break;case 2:this._point=3,this._line?this._context.lineTo(this._x2,this._y2):this._context.moveTo(this._x2,this._y2);break;case 3:this._point=4;default:xw(this,t,e)}this._l01_a=this._l12_a,this._l12_a=this._l23_a,this._l01_2a=this._l12_2a,this._l12_2a=this._l23_2a,this._x0=this._x1,this._x1=this._x2,this._x2=t,this._y0=this._y1,this._y1=this._y2,this._y2=e}};const Sw=function t(e){function n(t){return e?new Ew(t,e):new bw(t,0)}return n.alpha=function(e){return t(+e)},n}(.5);function Aw(t){this._context=t}function Mw(t){return new Aw(t)}function Nw(t){return t<0?-1:1}function Dw(t,e,n){var r=t._x1-t._x0,i=e-t._x1,a=(t._y1-t._y0)/(r||i<0&&-0),o=(n-t._y1)/(i||r<0&&-0),s=(a*i+o*r)/(r+i);return(Nw(a)+Nw(o))*Math.min(Math.abs(a),Math.abs(o),.5*Math.abs(s))||0}function Bw(t,e){var n=t._x1-t._x0;return n?(3*(t._y1-t._y0)/n-e)/2:e}function Lw(t,e,n){var r=t._x0,i=t._y0,a=t._x1,o=t._y1,s=(a-r)/3;t._context.bezierCurveTo(r+s,i+s*e,a-s,o-s*n,a,o)}function Ow(t){this._context=t}function Iw(t){this._context=new Rw(t)}function Rw(t){this._context=t}function Fw(t){return new Ow(t)}function Pw(t){return new Iw(t)}function Yw(t){this._context=t}function jw(t){var e,n,r=t.length-1,i=new Array(r),a=new Array(r),o=new Array(r);for(i[0]=0,a[0]=2,o[0]=t[0]+2*t[1],e=1;e=0;--e)i[e]=(o[e]-i[e+1])/a[e];for(a[r-1]=(t[r]+i[r-1])/2,e=0;e1)for(var n,r,i,a=1,o=t[e[0]],s=o.length;a=0;)n[e]=e;return n}function Gw(t,e){return t[e]}function Xw(){var t=H_([]),e=Vw,n=Ww,r=Gw;function i(i){var a,o,s=t.apply(this,arguments),c=i.length,u=s.length,l=new Array(u);for(a=0;a0){for(var n,r,i,a=0,o=t[0].length;a0)for(var n,r,i,a,o,s,c=0,u=t[e[0]].length;c0?(r[0]=a,r[1]=a+=i):i<0?(r[1]=o,r[0]=o+=i):(r[0]=0,r[1]=i)}function Kw(t,e){if((n=t.length)>0){for(var n,r=0,i=t[e[0]],a=i.length;r0&&(r=(n=t[e[0]]).length)>0){for(var n,r,i,a=0,o=1;oa&&(a=e,r=n);return r}function nk(t){var e=t.map(rk);return Vw(t).sort((function(t,n){return e[t]-e[n]}))}function rk(t){for(var e,n=0,r=-1,i=t.length;++r=0&&(this._t=1-this._t,this._line=1-this._line)},point:function(t,e){switch(t=+t,e=+e,this._point){case 0:this._point=1,this._line?this._context.lineTo(t,e):this._context.moveTo(t,e);break;case 1:this._point=2;default:if(this._t<=0)this._context.lineTo(this._x,e),this._context.lineTo(t,e);else{var n=this._x*(1-this._t)+t*this._t;this._context.lineTo(n,this._y),this._context.lineTo(n,e)}}this._x=t,this._y=e}};var sk="%Y-%m-%dT%H:%M:%S.%LZ",ck=Date.prototype.toISOString?function(t){return t.toISOString()}:ym(sk);const uk=ck;var lk=+new Date("2000-01-01T00:00:00.000Z")?function(t){var e=new Date(t);return isNaN(e)?null:e}:mm(sk);const hk=lk;function fk(t,e,n){var r=new Wn,i=e;return null==e?(r.restart(t,e,n),r):(e=+e,n=null==n?qn():+n,r.restart((function a(o){o+=i,r.restart(a,i+=e,n),t(o)}),e,n),r)}function dk(t){return function(){return t}}function pk(t){return t[0]}function gk(t){return t[1]}function yk(){this._=null}function mk(t){t.U=t.C=t.L=t.R=t.P=t.N=null}function vk(t,e){var n=e,r=e.R,i=n.U;i?i.L===n?i.L=r:i.R=r:t._=r,r.U=i,n.U=r,n.R=r.L,n.R&&(n.R.U=n),r.L=n}function bk(t,e){var n=e,r=e.L,i=n.U;i?i.L===n?i.L=r:i.R=r:t._=r,r.U=i,n.U=r,n.L=r.R,n.L&&(n.L.U=n),r.R=n}function _k(t){for(;t.L;)t=t.L;return t}yk.prototype={constructor:yk,insert:function(t,e){var n,r,i;if(t){if(e.P=t,e.N=t.N,t.N&&(t.N.P=e),t.N=e,t.R){for(t=t.R;t.L;)t=t.L;t.L=e}else t.R=e;n=t}else this._?(t=_k(this._),e.P=null,e.N=t,t.P=t.L=e,n=t):(e.P=e.N=null,this._=e,n=null);for(e.L=e.R=null,e.U=n,e.C=!0,t=e;n&&n.C;)n===(r=n.U).L?(i=r.R)&&i.C?(n.C=i.C=!1,r.C=!0,t=r):(t===n.R&&(vk(this,n),n=(t=n).U),n.C=!1,r.C=!0,bk(this,r)):(i=r.L)&&i.C?(n.C=i.C=!1,r.C=!0,t=r):(t===n.L&&(bk(this,n),n=(t=n).U),n.C=!1,r.C=!0,vk(this,r)),n=t.U;this._.C=!1},remove:function(t){t.N&&(t.N.P=t.P),t.P&&(t.P.N=t.N),t.N=t.P=null;var e,n,r,i=t.U,a=t.L,o=t.R;if(n=a?o?_k(o):a:o,i?i.L===t?i.L=n:i.R=n:this._=n,a&&o?(r=n.C,n.C=t.C,n.L=a,a.U=n,n!==o?(i=n.U,n.U=t.U,t=n.R,i.L=t,n.R=o,o.U=n):(n.U=i,i=n,t=n.R)):(r=t.C,t=n),t&&(t.U=i),!r)if(t&&t.C)t.C=!1;else{do{if(t===this._)break;if(t===i.L){if((e=i.R).C&&(e.C=!1,i.C=!0,vk(this,i),e=i.R),e.L&&e.L.C||e.R&&e.R.C){e.R&&e.R.C||(e.L.C=!1,e.C=!0,bk(this,e),e=i.R),e.C=i.C,i.C=e.R.C=!1,vk(this,i),t=this._;break}}else if((e=i.L).C&&(e.C=!1,i.C=!0,bk(this,i),e=i.L),e.L&&e.L.C||e.R&&e.R.C){e.L&&e.L.C||(e.R.C=!1,e.C=!0,vk(this,e),e=i.L),e.C=i.C,i.C=e.L.C=!1,bk(this,i),t=this._;break}e.C=!0,t=i,i=i.U}while(!t.C);t&&(t.C=!1)}}};const xk=yk;function wk(t,e,n,r){var i=[null,null],a=Wk.push(i)-1;return i.left=t,i.right=e,n&&Tk(i,t,e,n),r&&Tk(i,e,t,r),qk[t.index].halfedges.push(a),qk[e.index].halfedges.push(a),i}function kk(t,e,n){var r=[e,n];return r.left=t,r}function Tk(t,e,n,r){t[0]||t[1]?t.left===n?t[1]=r:t[0]=r:(t[0]=r,t.left=e,t.right=n)}function Ck(t,e,n,r,i){var a,o=t[0],s=t[1],c=o[0],u=o[1],l=0,h=1,f=s[0]-c,d=s[1]-u;if(a=e-c,f||!(a>0)){if(a/=f,f<0){if(a0){if(a>h)return;a>l&&(l=a)}if(a=r-c,f||!(a<0)){if(a/=f,f<0){if(a>h)return;a>l&&(l=a)}else if(f>0){if(a0)){if(a/=d,d<0){if(a0){if(a>h)return;a>l&&(l=a)}if(a=i-u,d||!(a<0)){if(a/=d,d<0){if(a>h)return;a>l&&(l=a)}else if(d>0){if(a0||h<1)||(l>0&&(t[0]=[c+l*f,u+l*d]),h<1&&(t[1]=[c+h*f,u+h*d]),!0)}}}}}function Ek(t,e,n,r,i){var a=t[1];if(a)return!0;var o,s,c=t[0],u=t.left,l=t.right,h=u[0],f=u[1],d=l[0],p=l[1],g=(h+d)/2,y=(f+p)/2;if(p===f){if(g=r)return;if(h>d){if(c){if(c[1]>=i)return}else c=[g,n];a=[g,i]}else{if(c){if(c[1]1)if(h>d){if(c){if(c[1]>=i)return}else c=[(n-s)/o,n];a=[(i-s)/o,i]}else{if(c){if(c[1]=r)return}else c=[e,o*e+s];a=[r,o*r+s]}else{if(c){if(c[0]=-Gk)){var d=c*c+u*u,p=l*l+h*h,g=(h*d-u*p)/f,y=(c*p-l*d)/f,m=Dk.pop()||new Bk;m.arc=t,m.site=i,m.x=g+o,m.y=(m.cy=y+s)+Math.sqrt(g*g+y*y),t.circle=m;for(var v=null,b=Hk._;b;)if(m.yVk)s=s.L;else{if(!((i=a-zk(s,o))>Vk)){r>-Vk?(e=s.P,n=s):i>-Vk?(e=s,n=s.N):e=n=s;break}if(!s.R){e=s;break}s=s.R}!function(t){qk[t.index]={site:t,halfedges:[]}}(t);var c=Fk(t);if($k.insert(e,c),e||n){if(e===n)return Ok(e),n=Fk(e.site),$k.insert(c,n),c.edge=n.edge=wk(e.site,c.site),Lk(e),void Lk(n);if(n){Ok(e),Ok(n);var u=e.site,l=u[0],h=u[1],f=t[0]-l,d=t[1]-h,p=n.site,g=p[0]-l,y=p[1]-h,m=2*(f*y-d*g),v=f*f+d*d,b=g*g+y*y,_=[(y*v-d*b)/m+l,(f*b-g*v)/m+h];Tk(n.edge,u,p,_),c.edge=wk(u,t,null,_),n.edge=wk(t,p,null,_),Lk(e),Lk(n)}else c.edge=wk(e.site,c.site)}}function Uk(t,e){var n=t.site,r=n[0],i=n[1],a=i-e;if(!a)return r;var o=t.P;if(!o)return-1/0;var s=(n=o.site)[0],c=n[1],u=c-e;if(!u)return s;var l=s-r,h=1/a-1/u,f=l/u;return h?(-f+Math.sqrt(f*f-2*h*(l*l/(-2*u)-c+u/2+i-a/2)))/h+r:(r+s)/2}function zk(t,e){var n=t.N;if(n)return Uk(n,e);var r=t.site;return r[1]===e?r[0]:1/0}var $k,qk,Hk,Wk,Vk=1e-6,Gk=1e-12;function Xk(t,e,n){return(t[0]-n[0])*(e[1]-t[1])-(t[0]-e[0])*(n[1]-t[1])}function Zk(t,e){return e[1]-t[1]||e[0]-t[0]}function Qk(t,e){var n,r,i,a=t.sort(Zk).pop();for(Wk=[],qk=new Array(t.length),$k=new xk,Hk=new xk;;)if(i=Nk,a&&(!i||a[1]Vk||Math.abs(i[0][1]-i[1][1])>Vk)||delete Wk[a]}(o,s,c,u),function(t,e,n,r){var i,a,o,s,c,u,l,h,f,d,p,g,y=qk.length,m=!0;for(i=0;iVk||Math.abs(g-f)>Vk)&&(c.splice(s,0,Wk.push(kk(o,d,Math.abs(p-t)Vk?[t,Math.abs(h-t)Vk?[Math.abs(f-r)Vk?[n,Math.abs(h-n)Vk?[Math.abs(f-e)=s)return null;var c=t-i.site[0],u=e-i.site[1],l=c*c+u*u;do{i=a.cells[r=o],o=null,i.halfedges.forEach((function(n){var r=a.edges[n],s=r.left;if(s!==i.site&&s||(s=r.right)){var c=t-s[0],u=e-s[1],h=c*c+u*u;hr?(r+i)/2:Math.min(0,r)||Math.max(0,i),o>a?(a+o)/2:Math.min(0,a)||Math.max(0,o))}function fT(){var t,e,n=oT,r=sT,i=hT,a=uT,o=lT,s=[0,1/0],c=[[-1/0,-1/0],[1/0,1/0]],u=250,l=Bp,h=ft("start","zoom","end"),f=500,d=0;function p(t){t.property("__zoom",cT).on("wheel.zoom",x).on("mousedown.zoom",w).on("dblclick.zoom",k).filter(o).on("touchstart.zoom",T).on("touchmove.zoom",C).on("touchend.zoom touchcancel.zoom",E).style("touch-action","none").style("-webkit-tap-highlight-color","rgba(0,0,0,0)")}function g(t,e){return(e=Math.max(s[0],Math.min(s[1],e)))===t.k?t:new eT(e,t.x,t.y)}function y(t,e,n){var r=e[0]-n[0]*t.k,i=e[1]-n[1]*t.k;return r===t.x&&i===t.y?t:new eT(t.k,r,i)}function m(t){return[(+t[0][0]+ +t[1][0])/2,(+t[0][1]+ +t[1][1])/2]}function v(t,e,n){t.on("start.zoom",(function(){b(this,arguments).start()})).on("interrupt.zoom end.zoom",(function(){b(this,arguments).end()})).tween("zoom",(function(){var t=this,i=arguments,a=b(t,i),o=r.apply(t,i),s=null==n?m(o):"function"==typeof n?n.apply(t,i):n,c=Math.max(o[1][0]-o[0][0],o[1][1]-o[0][1]),u=t.__zoom,h="function"==typeof e?e.apply(t,i):e,f=l(u.invert(s).concat(c/u.k),h.invert(s).concat(c/h.k));return function(t){if(1===t)t=h;else{var e=f(t),n=c/e[2];t=new eT(n,s[0]-e[0]*n,s[1]-e[1]*n)}a.zoom(null,t)}}))}function b(t,e,n){return!n&&t.__zooming||new _(t,e)}function _(t,e){this.that=t,this.args=e,this.active=0,this.extent=r.apply(t,e),this.taps=0}function x(){if(n.apply(this,arguments)){var t=b(this,arguments),e=this.__zoom,r=Math.max(s[0],Math.min(s[1],e.k*Math.pow(2,a.apply(this,arguments)))),o=Ln(this);if(t.wheel)t.mouse[0][0]===o[0]&&t.mouse[0][1]===o[1]||(t.mouse[1]=e.invert(t.mouse[0]=o)),clearTimeout(t.wheel);else{if(e.k===r)return;t.mouse=[o,e.invert(o)],ar(this),t.start()}aT(),t.wheel=setTimeout(u,150),t.zoom("mouse",i(y(g(e,r),t.mouse[0],t.mouse[1]),t.extent,c))}function u(){t.wheel=null,t.end()}}function w(){if(!e&&n.apply(this,arguments)){var t=b(this,arguments,!0),r=Te(le.view).on("mousemove.zoom",u,!0).on("mouseup.zoom",l,!0),a=Ln(this),o=le.clientX,s=le.clientY;Se(le.view),iT(),t.mouse=[a,this.__zoom.invert(a)],ar(this),t.start()}function u(){if(aT(),!t.moved){var e=le.clientX-o,n=le.clientY-s;t.moved=e*e+n*n>d}t.zoom("mouse",i(y(t.that.__zoom,t.mouse[0]=Ln(t.that),t.mouse[1]),t.extent,c))}function l(){r.on("mousemove.zoom mouseup.zoom",null),Ae(le.view,t.moved),aT(),t.end()}}function k(){if(n.apply(this,arguments)){var t=this.__zoom,e=Ln(this),a=t.invert(e),o=t.k*(le.shiftKey?.5:2),s=i(y(g(t,o),e,a),r.apply(this,arguments),c);aT(),u>0?Te(this).transition().duration(u).call(v,s,e):Te(this).call(p.transform,s)}}function T(){if(n.apply(this,arguments)){var e,r,i,a,o=le.touches,s=o.length,c=b(this,arguments,le.changedTouches.length===s);for(iT(),r=0;r{t.exports={graphlib:n(574),layout:n(8123),debug:n(7570),util:{time:n(1138).time,notime:n(1138).notime},version:n(8177)}},2188:(t,e,n)=>{"use strict";var r=n(8436),i=n(4079);t.exports={run:function(t){var e="greedy"===t.graph().acyclicer?i(t,function(t){return function(e){return t.edge(e).weight}}(t)):function(t){var e=[],n={},i={};return r.forEach(t.nodes(),(function a(o){r.has(i,o)||(i[o]=!0,n[o]=!0,r.forEach(t.outEdges(o),(function(t){r.has(n,t.w)?e.push(t):a(t.w)})),delete n[o])})),e}(t);r.forEach(e,(function(e){var n=t.edge(e);t.removeEdge(e),n.forwardName=e.name,n.reversed=!0,t.setEdge(e.w,e.v,n,r.uniqueId("rev"))}))},undo:function(t){r.forEach(t.edges(),(function(e){var n=t.edge(e);if(n.reversed){t.removeEdge(e);var r=n.forwardName;delete n.reversed,delete n.forwardName,t.setEdge(e.w,e.v,n,r)}}))}}},1133:(t,e,n)=>{var r=n(8436),i=n(1138);function a(t,e,n,r,a,o){var s={width:0,height:0,rank:o,borderType:e},c=a[e][o-1],u=i.addDummyNode(t,"border",s,n);a[e][o]=u,t.setParent(u,r),c&&t.setEdge(c,u,{weight:1})}t.exports=function(t){r.forEach(t.children(),(function e(n){var i=t.children(n),o=t.node(n);if(i.length&&r.forEach(i,e),r.has(o,"minRank")){o.borderLeft=[],o.borderRight=[];for(var s=o.minRank,c=o.maxRank+1;s{"use strict";var r=n(8436);function i(t){r.forEach(t.nodes(),(function(e){a(t.node(e))})),r.forEach(t.edges(),(function(e){a(t.edge(e))}))}function a(t){var e=t.width;t.width=t.height,t.height=e}function o(t){t.y=-t.y}function s(t){var e=t.x;t.x=t.y,t.y=e}t.exports={adjust:function(t){var e=t.graph().rankdir.toLowerCase();"lr"!==e&&"rl"!==e||i(t)},undo:function(t){var e=t.graph().rankdir.toLowerCase();"bt"!==e&&"rl"!==e||function(t){r.forEach(t.nodes(),(function(e){o(t.node(e))})),r.forEach(t.edges(),(function(e){var n=t.edge(e);r.forEach(n.points,o),r.has(n,"y")&&o(n)}))}(t),"lr"!==e&&"rl"!==e||(function(t){r.forEach(t.nodes(),(function(e){s(t.node(e))})),r.forEach(t.edges(),(function(e){var n=t.edge(e);r.forEach(n.points,s),r.has(n,"x")&&s(n)}))}(t),i(t))}}},7822:t=>{function e(){var t={};t._next=t._prev=t,this._sentinel=t}function n(t){t._prev._next=t._next,t._next._prev=t._prev,delete t._next,delete t._prev}function r(t,e){if("_next"!==t&&"_prev"!==t)return e}t.exports=e,e.prototype.dequeue=function(){var t=this._sentinel,e=t._prev;if(e!==t)return n(e),e},e.prototype.enqueue=function(t){var e=this._sentinel;t._prev&&t._next&&n(t),t._next=e._next,e._next._prev=t,e._next=t,t._prev=e},e.prototype.toString=function(){for(var t=[],e=this._sentinel,n=e._prev;n!==e;)t.push(JSON.stringify(n,r)),n=n._prev;return"["+t.join(", ")+"]"}},7570:(t,e,n)=>{var r=n(8436),i=n(1138),a=n(574).Graph;t.exports={debugOrdering:function(t){var e=i.buildLayerMatrix(t),n=new a({compound:!0,multigraph:!0}).setGraph({});return r.forEach(t.nodes(),(function(e){n.setNode(e,{label:e}),n.setParent(e,"layer"+t.node(e).rank)})),r.forEach(t.edges(),(function(t){n.setEdge(t.v,t.w,{},t.name)})),r.forEach(e,(function(t,e){var i="layer"+e;n.setNode(i,{rank:"same"}),r.reduce(t,(function(t,e){return n.setEdge(t,e,{style:"invis"}),e}))})),n}}},574:(t,e,n)=>{var r;try{r=n(8282)}catch(t){}r||(r=window.graphlib),t.exports=r},4079:(t,e,n)=>{var r=n(8436),i=n(574).Graph,a=n(7822);t.exports=function(t,e){if(t.nodeCount()<=1)return[];var n=function(t,e){var n=new i,o=0,s=0;r.forEach(t.nodes(),(function(t){n.setNode(t,{v:t,in:0,out:0})})),r.forEach(t.edges(),(function(t){var r=n.edge(t.v,t.w)||0,i=e(t),a=r+i;n.setEdge(t.v,t.w,a),s=Math.max(s,n.node(t.v).out+=i),o=Math.max(o,n.node(t.w).in+=i)}));var u=r.range(s+o+3).map((function(){return new a})),l=o+1;return r.forEach(n.nodes(),(function(t){c(u,l,n.node(t))})),{graph:n,buckets:u,zeroIdx:l}}(t,e||o),u=function(t,e,n){for(var r,i=[],a=e[e.length-1],o=e[0];t.nodeCount();){for(;r=o.dequeue();)s(t,e,n,r);for(;r=a.dequeue();)s(t,e,n,r);if(t.nodeCount())for(var c=e.length-2;c>0;--c)if(r=e[c].dequeue()){i=i.concat(s(t,e,n,r,!0));break}}return i}(n.graph,n.buckets,n.zeroIdx);return r.flatten(r.map(u,(function(e){return t.outEdges(e.v,e.w)})),!0)};var o=r.constant(1);function s(t,e,n,i,a){var o=a?[]:void 0;return r.forEach(t.inEdges(i.v),(function(r){var i=t.edge(r),s=t.node(r.v);a&&o.push({v:r.v,w:r.w}),s.out-=i,c(e,n,s)})),r.forEach(t.outEdges(i.v),(function(r){var i=t.edge(r),a=r.w,o=t.node(a);o.in-=i,c(e,n,o)})),t.removeNode(i.v),o}function c(t,e,n){n.out?n.in?t[n.out-n.in+e].enqueue(n):t[t.length-1].enqueue(n):t[0].enqueue(n)}},8123:(t,e,n)=>{"use strict";var r=n(8436),i=n(2188),a=n(5995),o=n(8093),s=n(1138).normalizeRanks,c=n(4219),u=n(1138).removeEmptyRanks,l=n(2981),h=n(1133),f=n(3258),d=n(3408),p=n(7873),g=n(1138),y=n(574).Graph;t.exports=function(t,e){var n=e&&e.debugTiming?g.time:g.notime;n("layout",(function(){var e=n(" buildLayoutGraph",(function(){return function(t){var e=new y({multigraph:!0,compound:!0}),n=E(t.graph());return e.setGraph(r.merge({},v,C(n,m),r.pick(n,b))),r.forEach(t.nodes(),(function(n){var i=E(t.node(n));e.setNode(n,r.defaults(C(i,_),x)),e.setParent(n,t.parent(n))})),r.forEach(t.edges(),(function(n){var i=E(t.edge(n));e.setEdge(n,r.merge({},k,C(i,w),r.pick(i,T)))})),e}(t)}));n(" runLayout",(function(){!function(t,e){e(" makeSpaceForEdgeLabels",(function(){!function(t){var e=t.graph();e.ranksep/=2,r.forEach(t.edges(),(function(n){var r=t.edge(n);r.minlen*=2,"c"!==r.labelpos.toLowerCase()&&("TB"===e.rankdir||"BT"===e.rankdir?r.width+=r.labeloffset:r.height+=r.labeloffset)}))}(t)})),e(" removeSelfEdges",(function(){!function(t){r.forEach(t.edges(),(function(e){if(e.v===e.w){var n=t.node(e.v);n.selfEdges||(n.selfEdges=[]),n.selfEdges.push({e,label:t.edge(e)}),t.removeEdge(e)}}))}(t)})),e(" acyclic",(function(){i.run(t)})),e(" nestingGraph.run",(function(){l.run(t)})),e(" rank",(function(){o(g.asNonCompoundGraph(t))})),e(" injectEdgeLabelProxies",(function(){!function(t){r.forEach(t.edges(),(function(e){var n=t.edge(e);if(n.width&&n.height){var r=t.node(e.v),i={rank:(t.node(e.w).rank-r.rank)/2+r.rank,e};g.addDummyNode(t,"edge-proxy",i,"_ep")}}))}(t)})),e(" removeEmptyRanks",(function(){u(t)})),e(" nestingGraph.cleanup",(function(){l.cleanup(t)})),e(" normalizeRanks",(function(){s(t)})),e(" assignRankMinMax",(function(){!function(t){var e=0;r.forEach(t.nodes(),(function(n){var i=t.node(n);i.borderTop&&(i.minRank=t.node(i.borderTop).rank,i.maxRank=t.node(i.borderBottom).rank,e=r.max(e,i.maxRank))})),t.graph().maxRank=e}(t)})),e(" removeEdgeLabelProxies",(function(){!function(t){r.forEach(t.nodes(),(function(e){var n=t.node(e);"edge-proxy"===n.dummy&&(t.edge(n.e).labelRank=n.rank,t.removeNode(e))}))}(t)})),e(" normalize.run",(function(){a.run(t)})),e(" parentDummyChains",(function(){c(t)})),e(" addBorderSegments",(function(){h(t)})),e(" order",(function(){d(t)})),e(" insertSelfEdges",(function(){!function(t){var e=g.buildLayerMatrix(t);r.forEach(e,(function(e){var n=0;r.forEach(e,(function(e,i){var a=t.node(e);a.order=i+n,r.forEach(a.selfEdges,(function(e){g.addDummyNode(t,"selfedge",{width:e.label.width,height:e.label.height,rank:a.rank,order:i+ ++n,e:e.e,label:e.label},"_se")})),delete a.selfEdges}))}))}(t)})),e(" adjustCoordinateSystem",(function(){f.adjust(t)})),e(" position",(function(){p(t)})),e(" positionSelfEdges",(function(){!function(t){r.forEach(t.nodes(),(function(e){var n=t.node(e);if("selfedge"===n.dummy){var r=t.node(n.e.v),i=r.x+r.width/2,a=r.y,o=n.x-i,s=r.height/2;t.setEdge(n.e,n.label),t.removeNode(e),n.label.points=[{x:i+2*o/3,y:a-s},{x:i+5*o/6,y:a-s},{x:i+o,y:a},{x:i+5*o/6,y:a+s},{x:i+2*o/3,y:a+s}],n.label.x=n.x,n.label.y=n.y}}))}(t)})),e(" removeBorderNodes",(function(){!function(t){r.forEach(t.nodes(),(function(e){if(t.children(e).length){var n=t.node(e),i=t.node(n.borderTop),a=t.node(n.borderBottom),o=t.node(r.last(n.borderLeft)),s=t.node(r.last(n.borderRight));n.width=Math.abs(s.x-o.x),n.height=Math.abs(a.y-i.y),n.x=o.x+n.width/2,n.y=i.y+n.height/2}})),r.forEach(t.nodes(),(function(e){"border"===t.node(e).dummy&&t.removeNode(e)}))}(t)})),e(" normalize.undo",(function(){a.undo(t)})),e(" fixupEdgeLabelCoords",(function(){!function(t){r.forEach(t.edges(),(function(e){var n=t.edge(e);if(r.has(n,"x"))switch("l"!==n.labelpos&&"r"!==n.labelpos||(n.width-=n.labeloffset),n.labelpos){case"l":n.x-=n.width/2+n.labeloffset;break;case"r":n.x+=n.width/2+n.labeloffset}}))}(t)})),e(" undoCoordinateSystem",(function(){f.undo(t)})),e(" translateGraph",(function(){!function(t){var e=Number.POSITIVE_INFINITY,n=0,i=Number.POSITIVE_INFINITY,a=0,o=t.graph(),s=o.marginx||0,c=o.marginy||0;function u(t){var r=t.x,o=t.y,s=t.width,c=t.height;e=Math.min(e,r-s/2),n=Math.max(n,r+s/2),i=Math.min(i,o-c/2),a=Math.max(a,o+c/2)}r.forEach(t.nodes(),(function(e){u(t.node(e))})),r.forEach(t.edges(),(function(e){var n=t.edge(e);r.has(n,"x")&&u(n)})),e-=s,i-=c,r.forEach(t.nodes(),(function(n){var r=t.node(n);r.x-=e,r.y-=i})),r.forEach(t.edges(),(function(n){var a=t.edge(n);r.forEach(a.points,(function(t){t.x-=e,t.y-=i})),r.has(a,"x")&&(a.x-=e),r.has(a,"y")&&(a.y-=i)})),o.width=n-e+s,o.height=a-i+c}(t)})),e(" assignNodeIntersects",(function(){!function(t){r.forEach(t.edges(),(function(e){var n,r,i=t.edge(e),a=t.node(e.v),o=t.node(e.w);i.points?(n=i.points[0],r=i.points[i.points.length-1]):(i.points=[],n=o,r=a),i.points.unshift(g.intersectRect(a,n)),i.points.push(g.intersectRect(o,r))}))}(t)})),e(" reversePoints",(function(){!function(t){r.forEach(t.edges(),(function(e){var n=t.edge(e);n.reversed&&n.points.reverse()}))}(t)})),e(" acyclic.undo",(function(){i.undo(t)}))}(e,n)})),n(" updateInputGraph",(function(){!function(t,e){r.forEach(t.nodes(),(function(n){var r=t.node(n),i=e.node(n);r&&(r.x=i.x,r.y=i.y,e.children(n).length&&(r.width=i.width,r.height=i.height))})),r.forEach(t.edges(),(function(n){var i=t.edge(n),a=e.edge(n);i.points=a.points,r.has(a,"x")&&(i.x=a.x,i.y=a.y)})),t.graph().width=e.graph().width,t.graph().height=e.graph().height}(t,e)}))}))};var m=["nodesep","edgesep","ranksep","marginx","marginy"],v={ranksep:50,edgesep:20,nodesep:50,rankdir:"tb"},b=["acyclicer","ranker","rankdir","align"],_=["width","height"],x={width:0,height:0},w=["minlen","weight","width","height","labeloffset"],k={minlen:1,weight:1,width:0,height:0,labeloffset:10,labelpos:"r"},T=["labelpos"];function C(t,e){return r.mapValues(r.pick(t,e),Number)}function E(t){var e={};return r.forEach(t,(function(t,n){e[n.toLowerCase()]=t})),e}},8436:(t,e,n)=>{var r;try{r={cloneDeep:n(361),constant:n(5703),defaults:n(1747),each:n(6073),filter:n(3105),find:n(3311),flatten:n(5564),forEach:n(4486),forIn:n(2620),has:n(8721),isUndefined:n(2353),last:n(928),map:n(5161),mapValues:n(6604),max:n(6162),merge:n(3857),min:n(3632),minBy:n(2762),now:n(7771),pick:n(9722),range:n(6026),reduce:n(4061),sortBy:n(9734),uniqueId:n(3955),values:n(2628),zipObject:n(7287)}}catch(t){}r||(r=window._),t.exports=r},2981:(t,e,n)=>{var r=n(8436),i=n(1138);function a(t,e,n,o,s,c,u){var l=t.children(u);if(l.length){var h=i.addBorderNode(t,"_bt"),f=i.addBorderNode(t,"_bb"),d=t.node(u);t.setParent(h,u),d.borderTop=h,t.setParent(f,u),d.borderBottom=f,r.forEach(l,(function(r){a(t,e,n,o,s,c,r);var i=t.node(r),l=i.borderTop?i.borderTop:r,d=i.borderBottom?i.borderBottom:r,p=i.borderTop?o:2*o,g=l!==d?1:s-c[u]+1;t.setEdge(h,l,{weight:p,minlen:g,nestingEdge:!0}),t.setEdge(d,f,{weight:p,minlen:g,nestingEdge:!0})})),t.parent(u)||t.setEdge(e,h,{weight:0,minlen:s+c[u]})}else u!==e&&t.setEdge(e,u,{weight:0,minlen:n})}t.exports={run:function(t){var e=i.addDummyNode(t,"root",{},"_root"),n=function(t){var e={};function n(i,a){var o=t.children(i);o&&o.length&&r.forEach(o,(function(t){n(t,a+1)})),e[i]=a}return r.forEach(t.children(),(function(t){n(t,1)})),e}(t),o=r.max(r.values(n))-1,s=2*o+1;t.graph().nestingRoot=e,r.forEach(t.edges(),(function(e){t.edge(e).minlen*=s}));var c=function(t){return r.reduce(t.edges(),(function(e,n){return e+t.edge(n).weight}),0)}(t)+1;r.forEach(t.children(),(function(r){a(t,e,s,c,o,n,r)})),t.graph().nodeRankFactor=s},cleanup:function(t){var e=t.graph();t.removeNode(e.nestingRoot),delete e.nestingRoot,r.forEach(t.edges(),(function(e){t.edge(e).nestingEdge&&t.removeEdge(e)}))}}},5995:(t,e,n)=>{"use strict";var r=n(8436),i=n(1138);t.exports={run:function(t){t.graph().dummyChains=[],r.forEach(t.edges(),(function(e){!function(t,e){var n,r,a,o=e.v,s=t.node(o).rank,c=e.w,u=t.node(c).rank,l=e.name,h=t.edge(e),f=h.labelRank;if(u!==s+1){for(t.removeEdge(e),a=0,++s;s{var r=n(8436);t.exports=function(t,e,n){var i,a={};r.forEach(n,(function(n){for(var r,o,s=t.parent(n);s;){if((r=t.parent(s))?(o=a[r],a[r]=s):(o=i,i=s),o&&o!==s)return void e.setEdge(o,s);s=r}}))}},5439:(t,e,n)=>{var r=n(8436);t.exports=function(t,e){return r.map(e,(function(e){var n=t.inEdges(e);if(n.length){var i=r.reduce(n,(function(e,n){var r=t.edge(n),i=t.node(n.v);return{sum:e.sum+r.weight*i.order,weight:e.weight+r.weight}}),{sum:0,weight:0});return{v:e,barycenter:i.sum/i.weight,weight:i.weight}}return{v:e}}))}},3128:(t,e,n)=>{var r=n(8436),i=n(574).Graph;t.exports=function(t,e,n){var a=function(t){for(var e;t.hasNode(e=r.uniqueId("_root")););return e}(t),o=new i({compound:!0}).setGraph({root:a}).setDefaultNodeLabel((function(e){return t.node(e)}));return r.forEach(t.nodes(),(function(i){var s=t.node(i),c=t.parent(i);(s.rank===e||s.minRank<=e&&e<=s.maxRank)&&(o.setNode(i),o.setParent(i,c||a),r.forEach(t[n](i),(function(e){var n=e.v===i?e.w:e.v,a=o.edge(n,i),s=r.isUndefined(a)?0:a.weight;o.setEdge(n,i,{weight:t.edge(e).weight+s})})),r.has(s,"minRank")&&o.setNode(i,{borderLeft:s.borderLeft[e],borderRight:s.borderRight[e]}))})),o}},6630:(t,e,n)=>{"use strict";var r=n(8436);function i(t,e,n){for(var i=r.zipObject(n,r.map(n,(function(t,e){return e}))),a=r.flatten(r.map(e,(function(e){return r.sortBy(r.map(t.outEdges(e),(function(e){return{pos:i[e.w],weight:t.edge(e).weight}})),"pos")})),!0),o=1;o0;)e%2&&(n+=c[e+1]),c[e=e-1>>1]+=t.weight;u+=t.weight*n}))),u}t.exports=function(t,e){for(var n=0,r=1;r{"use strict";var r=n(8436),i=n(2588),a=n(6630),o=n(1026),s=n(3128),c=n(5093),u=n(574).Graph,l=n(1138);function h(t,e,n){return r.map(e,(function(e){return s(t,e,n)}))}function f(t,e){var n=new u;r.forEach(t,(function(t){var i=t.graph().root,a=o(t,i,n,e);r.forEach(a.vs,(function(e,n){t.node(e).order=n})),c(t,n,a.vs)}))}function d(t,e){r.forEach(e,(function(e){r.forEach(e,(function(e,n){t.node(e).order=n}))}))}t.exports=function(t){var e=l.maxRank(t),n=h(t,r.range(1,e+1),"inEdges"),o=h(t,r.range(e-1,-1,-1),"outEdges"),s=i(t);d(t,s);for(var c,u=Number.POSITIVE_INFINITY,p=0,g=0;g<4;++p,++g){f(p%2?n:o,p%4>=2),s=l.buildLayerMatrix(t);var y=a(t,s);y{"use strict";var r=n(8436);t.exports=function(t){var e={},n=r.filter(t.nodes(),(function(e){return!t.children(e).length})),i=r.max(r.map(n,(function(e){return t.node(e).rank}))),a=r.map(r.range(i+1),(function(){return[]})),o=r.sortBy(n,(function(e){return t.node(e).rank}));return r.forEach(o,(function n(i){if(!r.has(e,i)){e[i]=!0;var o=t.node(i);a[o.rank].push(i),r.forEach(t.successors(i),n)}})),a}},9567:(t,e,n)=>{"use strict";var r=n(8436);t.exports=function(t,e){var n={};return r.forEach(t,(function(t,e){var i=n[t.v]={indegree:0,in:[],out:[],vs:[t.v],i:e};r.isUndefined(t.barycenter)||(i.barycenter=t.barycenter,i.weight=t.weight)})),r.forEach(e.edges(),(function(t){var e=n[t.v],i=n[t.w];r.isUndefined(e)||r.isUndefined(i)||(i.indegree++,e.out.push(n[t.w]))})),function(t){var e=[];function n(t){return function(e){var n,i,a,o;e.merged||(r.isUndefined(e.barycenter)||r.isUndefined(t.barycenter)||e.barycenter>=t.barycenter)&&(i=e,a=0,o=0,(n=t).weight&&(a+=n.barycenter*n.weight,o+=n.weight),i.weight&&(a+=i.barycenter*i.weight,o+=i.weight),n.vs=i.vs.concat(n.vs),n.barycenter=a/o,n.weight=o,n.i=Math.min(i.i,n.i),i.merged=!0)}}function i(e){return function(n){n.in.push(e),0==--n.indegree&&t.push(n)}}for(;t.length;){var a=t.pop();e.push(a),r.forEach(a.in.reverse(),n(a)),r.forEach(a.out,i(a))}return r.map(r.filter(e,(function(t){return!t.merged})),(function(t){return r.pick(t,["vs","i","barycenter","weight"])}))}(r.filter(n,(function(t){return!t.indegree})))}},1026:(t,e,n)=>{var r=n(8436),i=n(5439),a=n(9567),o=n(7304);t.exports=function t(e,n,s,c){var u=e.children(n),l=e.node(n),h=l?l.borderLeft:void 0,f=l?l.borderRight:void 0,d={};h&&(u=r.filter(u,(function(t){return t!==h&&t!==f})));var p=i(e,u);r.forEach(p,(function(n){if(e.children(n.v).length){var i=t(e,n.v,s,c);d[n.v]=i,r.has(i,"barycenter")&&(a=n,o=i,r.isUndefined(a.barycenter)?(a.barycenter=o.barycenter,a.weight=o.weight):(a.barycenter=(a.barycenter*a.weight+o.barycenter*o.weight)/(a.weight+o.weight),a.weight+=o.weight))}var a,o}));var g=a(p,s);!function(t,e){r.forEach(t,(function(t){t.vs=r.flatten(t.vs.map((function(t){return e[t]?e[t].vs:t})),!0)}))}(g,d);var y=o(g,c);if(h&&(y.vs=r.flatten([h,y.vs,f],!0),e.predecessors(h).length)){var m=e.node(e.predecessors(h)[0]),v=e.node(e.predecessors(f)[0]);r.has(y,"barycenter")||(y.barycenter=0,y.weight=0),y.barycenter=(y.barycenter*y.weight+m.order+v.order)/(y.weight+2),y.weight+=2}return y}},7304:(t,e,n)=>{var r=n(8436),i=n(1138);function a(t,e,n){for(var i;e.length&&(i=r.last(e)).i<=n;)e.pop(),t.push(i.vs),n++;return n}t.exports=function(t,e){var n,o=i.partition(t,(function(t){return r.has(t,"barycenter")})),s=o.lhs,c=r.sortBy(o.rhs,(function(t){return-t.i})),u=[],l=0,h=0,f=0;s.sort((n=!!e,function(t,e){return t.barycentere.barycenter?1:n?e.i-t.i:t.i-e.i})),f=a(u,c,f),r.forEach(s,(function(t){f+=t.vs.length,u.push(t.vs),l+=t.barycenter*t.weight,h+=t.weight,f=a(u,c,f)}));var d={vs:r.flatten(u,!0)};return h&&(d.barycenter=l/h,d.weight=h),d}},4219:(t,e,n)=>{var r=n(8436);t.exports=function(t){var e=function(t){var e={},n=0;return r.forEach(t.children(),(function i(a){var o=n;r.forEach(t.children(a),i),e[a]={low:o,lim:n++}})),e}(t);r.forEach(t.graph().dummyChains,(function(n){for(var r=t.node(n),i=r.edgeObj,a=function(t,e,n,r){var i,a,o=[],s=[],c=Math.min(e[n].low,e[r].low),u=Math.max(e[n].lim,e[r].lim);i=n;do{i=t.parent(i),o.push(i)}while(i&&(e[i].low>c||u>e[i].lim));for(a=i,i=r;(i=t.parent(i))!==a;)s.push(i);return{path:o.concat(s.reverse()),lca:a}}(t,e,i.v,i.w),o=a.path,s=a.lca,c=0,u=o[c],l=!0;n!==i.w;){if(r=t.node(n),l){for(;(u=o[c])!==s&&t.node(u).maxRank{"use strict";var r=n(8436),i=n(574).Graph,a=n(1138);function o(t,e){var n={};return r.reduce(e,(function(e,i){var a=0,o=0,s=e.length,u=r.last(i);return r.forEach(i,(function(e,l){var h=function(t,e){if(t.node(e).dummy)return r.find(t.predecessors(e),(function(e){return t.node(e).dummy}))}(t,e),f=h?t.node(h).order:s;(h||e===u)&&(r.forEach(i.slice(o,l+1),(function(e){r.forEach(t.predecessors(e),(function(r){var i=t.node(r),o=i.order;!(os)&&c(n,e,u)}))}))}return r.reduce(e,(function(e,n){var a,o=-1,s=0;return r.forEach(n,(function(r,c){if("border"===t.node(r).dummy){var u=t.predecessors(r);u.length&&(a=t.node(u[0]).order,i(n,s,c,o,a),s=c,o=a)}i(n,s,n.length,a,e.length)})),n})),n}function c(t,e,n){if(e>n){var r=e;e=n,n=r}var i=t[e];i||(t[e]=i={}),i[n]=!0}function u(t,e,n){if(e>n){var i=e;e=n,n=i}return r.has(t[e],n)}function l(t,e,n,i){var a={},o={},s={};return r.forEach(e,(function(t){r.forEach(t,(function(t,e){a[t]=t,o[t]=t,s[t]=e}))})),r.forEach(e,(function(t){var e=-1;r.forEach(t,(function(t){var c=i(t);if(c.length){c=r.sortBy(c,(function(t){return s[t]}));for(var l=(c.length-1)/2,h=Math.floor(l),f=Math.ceil(l);h<=f;++h){var d=c[h];o[t]===t&&e{"use strict";var r=n(8436),i=n(1138),a=n(3573).positionX;t.exports=function(t){(function(t){var e=i.buildLayerMatrix(t),n=t.graph().ranksep,a=0;r.forEach(e,(function(e){var i=r.max(r.map(e,(function(e){return t.node(e).height})));r.forEach(e,(function(e){t.node(e).y=a+i/2})),a+=i+n}))})(t=i.asNonCompoundGraph(t)),r.forEach(a(t),(function(e,n){t.node(n).x=e}))}},300:(t,e,n)=>{"use strict";var r=n(8436),i=n(574).Graph,a=n(6681).slack;function o(t,e){return r.forEach(t.nodes(),(function n(i){r.forEach(e.nodeEdges(i),(function(r){var o=r.v,s=i===o?r.w:o;t.hasNode(s)||a(e,r)||(t.setNode(s,{}),t.setEdge(i,s,{}),n(s))}))})),t.nodeCount()}function s(t,e){return r.minBy(e.edges(),(function(n){if(t.hasNode(n.v)!==t.hasNode(n.w))return a(e,n)}))}function c(t,e,n){r.forEach(t.nodes(),(function(t){e.node(t).rank+=n}))}t.exports=function(t){var e,n,r=new i({directed:!1}),u=t.nodes()[0],l=t.nodeCount();for(r.setNode(u,{});o(r,t){"use strict";var r=n(6681).longestPath,i=n(300),a=n(2472);t.exports=function(t){switch(t.graph().ranker){case"network-simplex":default:!function(t){a(t)}(t);break;case"tight-tree":!function(t){r(t),i(t)}(t);break;case"longest-path":o(t)}};var o=r},2472:(t,e,n)=>{"use strict";var r=n(8436),i=n(300),a=n(6681).slack,o=n(6681).longestPath,s=n(574).alg.preorder,c=n(574).alg.postorder,u=n(1138).simplify;function l(t){t=u(t),o(t);var e,n=i(t);for(d(n),h(n,t);e=g(n);)m(n,t,e,y(n,t,e))}function h(t,e){var n=c(t,t.nodes());n=n.slice(0,n.length-1),r.forEach(n,(function(n){!function(t,e,n){var r=t.node(n).parent;t.edge(n,r).cutvalue=f(t,e,n)}(t,e,n)}))}function f(t,e,n){var i=t.node(n).parent,a=!0,o=e.edge(n,i),s=0;return o||(a=!1,o=e.edge(i,n)),s=o.weight,r.forEach(e.nodeEdges(n),(function(r){var o,c,u=r.v===n,l=u?r.w:r.v;if(l!==i){var h=u===a,f=e.edge(r).weight;if(s+=h?f:-f,o=n,c=l,t.hasEdge(o,c)){var d=t.edge(n,l).cutvalue;s+=h?-d:d}}})),s}function d(t,e){arguments.length<2&&(e=t.nodes()[0]),p(t,{},1,e)}function p(t,e,n,i,a){var o=n,s=t.node(i);return e[i]=!0,r.forEach(t.neighbors(i),(function(a){r.has(e,a)||(n=p(t,e,n,a,i))})),s.low=o,s.lim=n++,a?s.parent=a:delete s.parent,n}function g(t){return r.find(t.edges(),(function(e){return t.edge(e).cutvalue<0}))}function y(t,e,n){var i=n.v,o=n.w;e.hasEdge(i,o)||(i=n.w,o=n.v);var s=t.node(i),c=t.node(o),u=s,l=!1;s.lim>c.lim&&(u=c,l=!0);var h=r.filter(e.edges(),(function(e){return l===v(0,t.node(e.v),u)&&l!==v(0,t.node(e.w),u)}));return r.minBy(h,(function(t){return a(e,t)}))}function m(t,e,n,i){var a=n.v,o=n.w;t.removeEdge(a,o),t.setEdge(i.v,i.w,{}),d(t),h(t,e),function(t,e){var n=r.find(t.nodes(),(function(t){return!e.node(t).parent})),i=s(t,n);i=i.slice(1),r.forEach(i,(function(n){var r=t.node(n).parent,i=e.edge(n,r),a=!1;i||(i=e.edge(r,n),a=!0),e.node(n).rank=e.node(r).rank+(a?i.minlen:-i.minlen)}))}(t,e)}function v(t,e,n){return n.low<=e.lim&&e.lim<=n.lim}t.exports=l,l.initLowLimValues=d,l.initCutValues=h,l.calcCutValue=f,l.leaveEdge=g,l.enterEdge=y,l.exchangeEdges=m},6681:(t,e,n)=>{"use strict";var r=n(8436);t.exports={longestPath:function(t){var e={};r.forEach(t.sources(),(function n(i){var a=t.node(i);if(r.has(e,i))return a.rank;e[i]=!0;var o=r.min(r.map(t.outEdges(i),(function(e){return n(e.w)-t.edge(e).minlen})));return o!==Number.POSITIVE_INFINITY&&null!=o||(o=0),a.rank=o}))},slack:function(t,e){return t.node(e.w).rank-t.node(e.v).rank-t.edge(e).minlen}}},1138:(t,e,n)=>{"use strict";var r=n(8436),i=n(574).Graph;function a(t,e,n,i){var a;do{a=r.uniqueId(i)}while(t.hasNode(a));return n.dummy=e,t.setNode(a,n),a}function o(t){return r.max(r.map(t.nodes(),(function(e){var n=t.node(e).rank;if(!r.isUndefined(n))return n})))}t.exports={addDummyNode:a,simplify:function(t){var e=(new i).setGraph(t.graph());return r.forEach(t.nodes(),(function(n){e.setNode(n,t.node(n))})),r.forEach(t.edges(),(function(n){var r=e.edge(n.v,n.w)||{weight:0,minlen:1},i=t.edge(n);e.setEdge(n.v,n.w,{weight:r.weight+i.weight,minlen:Math.max(r.minlen,i.minlen)})})),e},asNonCompoundGraph:function(t){var e=new i({multigraph:t.isMultigraph()}).setGraph(t.graph());return r.forEach(t.nodes(),(function(n){t.children(n).length||e.setNode(n,t.node(n))})),r.forEach(t.edges(),(function(n){e.setEdge(n,t.edge(n))})),e},successorWeights:function(t){var e=r.map(t.nodes(),(function(e){var n={};return r.forEach(t.outEdges(e),(function(e){n[e.w]=(n[e.w]||0)+t.edge(e).weight})),n}));return r.zipObject(t.nodes(),e)},predecessorWeights:function(t){var e=r.map(t.nodes(),(function(e){var n={};return r.forEach(t.inEdges(e),(function(e){n[e.v]=(n[e.v]||0)+t.edge(e).weight})),n}));return r.zipObject(t.nodes(),e)},intersectRect:function(t,e){var n,r,i=t.x,a=t.y,o=e.x-i,s=e.y-a,c=t.width/2,u=t.height/2;if(!o&&!s)throw new Error("Not possible to find intersection inside of the rectangle");return Math.abs(s)*c>Math.abs(o)*u?(s<0&&(u=-u),n=u*o/s,r=u):(o<0&&(c=-c),n=c,r=c*s/o),{x:i+n,y:a+r}},buildLayerMatrix:function(t){var e=r.map(r.range(o(t)+1),(function(){return[]}));return r.forEach(t.nodes(),(function(n){var i=t.node(n),a=i.rank;r.isUndefined(a)||(e[a][i.order]=n)})),e},normalizeRanks:function(t){var e=r.min(r.map(t.nodes(),(function(e){return t.node(e).rank})));r.forEach(t.nodes(),(function(n){var i=t.node(n);r.has(i,"rank")&&(i.rank-=e)}))},removeEmptyRanks:function(t){var e=r.min(r.map(t.nodes(),(function(e){return t.node(e).rank}))),n=[];r.forEach(t.nodes(),(function(r){var i=t.node(r).rank-e;n[i]||(n[i]=[]),n[i].push(r)}));var i=0,a=t.graph().nodeRankFactor;r.forEach(n,(function(e,n){r.isUndefined(e)&&n%a!=0?--i:i&&r.forEach(e,(function(e){t.node(e).rank+=i}))}))},addBorderNode:function(t,e,n,r){var i={width:0,height:0};return arguments.length>=4&&(i.rank=n,i.order=r),a(t,"border",i,e)},maxRank:o,partition:function(t,e){var n={lhs:[],rhs:[]};return r.forEach(t,(function(t){e(t)?n.lhs.push(t):n.rhs.push(t)})),n},time:function(t,e){var n=r.now();try{return e()}finally{console.log(t+" time: "+(r.now()-n)+"ms")}},notime:function(t,e){return e()}}},8177:t=>{t.exports="0.8.5"},7856:function(t){t.exports=function(){"use strict";var t=Object.hasOwnProperty,e=Object.setPrototypeOf,n=Object.isFrozen,r=Object.getPrototypeOf,i=Object.getOwnPropertyDescriptor,a=Object.freeze,o=Object.seal,s=Object.create,c="undefined"!=typeof Reflect&&Reflect,u=c.apply,l=c.construct;u||(u=function(t,e,n){return t.apply(e,n)}),a||(a=function(t){return t}),o||(o=function(t){return t}),l||(l=function(t,e){return new(Function.prototype.bind.apply(t,[null].concat(function(t){if(Array.isArray(t)){for(var e=0,n=Array(t.length);e1?n-1:0),i=1;i/gm),Y=o(/^data-[\-\w.\u00B7-\uFFFF]/),j=o(/^aria-[\-\w]+$/),U=o(/^(?:(?:(?:f|ht)tps?|mailto|tel|callto|cid|xmpp):|[^a-z]|[a-z+.\-]+(?:[^a-z+.\-:]|$))/i),z=o(/^(?:\w+script|data):/i),$=o(/[\u0000-\u0020\u00A0\u1680\u180E\u2000-\u2029\u205F\u3000]/g),q=o(/^html$/i),H="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t};function W(t){if(Array.isArray(t)){for(var e=0,n=Array(t.length);e0&&void 0!==arguments[0]?arguments[0]:V(),n=function(e){return t(e)};if(n.version="2.3.6",n.removed=[],!e||!e.document||9!==e.document.nodeType)return n.isSupported=!1,n;var r=e.document,i=e.document,o=e.DocumentFragment,s=e.HTMLTemplateElement,c=e.Node,u=e.Element,l=e.NodeFilter,h=e.NamedNodeMap,w=void 0===h?e.NamedNodeMap||e.MozNamedAttrMap:h,X=e.HTMLFormElement,Z=e.DOMParser,Q=e.trustedTypes,K=u.prototype,J=C(K,"cloneNode"),tt=C(K,"nextSibling"),et=C(K,"childNodes"),nt=C(K,"parentNode");if("function"==typeof s){var rt=i.createElement("template");rt.content&&rt.content.ownerDocument&&(i=rt.content.ownerDocument)}var it=G(Q,r),at=it?it.createHTML(""):"",ot=i,st=ot.implementation,ct=ot.createNodeIterator,ut=ot.createDocumentFragment,lt=ot.getElementsByTagName,ht=r.importNode,ft={};try{ft=T(i).documentMode?i.documentMode:{}}catch(t){}var dt={};n.isSupported="function"==typeof nt&&st&&void 0!==st.createHTMLDocument&&9!==ft;var pt=F,gt=P,yt=Y,mt=j,vt=z,bt=$,_t=U,xt=null,wt=k({},[].concat(W(E),W(S),W(A),W(N),W(B))),kt=null,Tt=k({},[].concat(W(L),W(O),W(I),W(R))),Ct=Object.seal(Object.create(null,{tagNameCheck:{writable:!0,configurable:!1,enumerable:!0,value:null},attributeNameCheck:{writable:!0,configurable:!1,enumerable:!0,value:null},allowCustomizedBuiltInElements:{writable:!0,configurable:!1,enumerable:!0,value:!1}})),Et=null,St=null,At=!0,Mt=!0,Nt=!1,Dt=!1,Bt=!1,Lt=!1,Ot=!1,It=!1,Rt=!1,Ft=!1,Pt=!0,Yt=!0,jt=!1,Ut={},zt=null,$t=k({},["annotation-xml","audio","colgroup","desc","foreignobject","head","iframe","math","mi","mn","mo","ms","mtext","noembed","noframes","noscript","plaintext","script","style","svg","template","thead","title","video","xmp"]),qt=null,Ht=k({},["audio","video","img","source","image","track"]),Wt=null,Vt=k({},["alt","class","for","id","label","name","pattern","placeholder","role","summary","title","value","style","xmlns"]),Gt="http://www.w3.org/1998/Math/MathML",Xt="http://www.w3.org/2000/svg",Zt="http://www.w3.org/1999/xhtml",Qt=Zt,Kt=!1,Jt=void 0,te=["application/xhtml+xml","text/html"],ee="text/html",ne=void 0,re=null,ie=i.createElement("form"),ae=function(t){return t instanceof RegExp||t instanceof Function},oe=function(t){re&&re===t||(t&&"object"===(void 0===t?"undefined":H(t))||(t={}),t=T(t),xt="ALLOWED_TAGS"in t?k({},t.ALLOWED_TAGS):wt,kt="ALLOWED_ATTR"in t?k({},t.ALLOWED_ATTR):Tt,Wt="ADD_URI_SAFE_ATTR"in t?k(T(Vt),t.ADD_URI_SAFE_ATTR):Vt,qt="ADD_DATA_URI_TAGS"in t?k(T(Ht),t.ADD_DATA_URI_TAGS):Ht,zt="FORBID_CONTENTS"in t?k({},t.FORBID_CONTENTS):$t,Et="FORBID_TAGS"in t?k({},t.FORBID_TAGS):{},St="FORBID_ATTR"in t?k({},t.FORBID_ATTR):{},Ut="USE_PROFILES"in t&&t.USE_PROFILES,At=!1!==t.ALLOW_ARIA_ATTR,Mt=!1!==t.ALLOW_DATA_ATTR,Nt=t.ALLOW_UNKNOWN_PROTOCOLS||!1,Dt=t.SAFE_FOR_TEMPLATES||!1,Bt=t.WHOLE_DOCUMENT||!1,It=t.RETURN_DOM||!1,Rt=t.RETURN_DOM_FRAGMENT||!1,Ft=t.RETURN_TRUSTED_TYPE||!1,Ot=t.FORCE_BODY||!1,Pt=!1!==t.SANITIZE_DOM,Yt=!1!==t.KEEP_CONTENT,jt=t.IN_PLACE||!1,_t=t.ALLOWED_URI_REGEXP||_t,Qt=t.NAMESPACE||Zt,t.CUSTOM_ELEMENT_HANDLING&&ae(t.CUSTOM_ELEMENT_HANDLING.tagNameCheck)&&(Ct.tagNameCheck=t.CUSTOM_ELEMENT_HANDLING.tagNameCheck),t.CUSTOM_ELEMENT_HANDLING&&ae(t.CUSTOM_ELEMENT_HANDLING.attributeNameCheck)&&(Ct.attributeNameCheck=t.CUSTOM_ELEMENT_HANDLING.attributeNameCheck),t.CUSTOM_ELEMENT_HANDLING&&"boolean"==typeof t.CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements&&(Ct.allowCustomizedBuiltInElements=t.CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements),Jt=Jt=-1===te.indexOf(t.PARSER_MEDIA_TYPE)?ee:t.PARSER_MEDIA_TYPE,ne="application/xhtml+xml"===Jt?function(t){return t}:g,Dt&&(Mt=!1),Rt&&(It=!0),Ut&&(xt=k({},[].concat(W(B))),kt=[],!0===Ut.html&&(k(xt,E),k(kt,L)),!0===Ut.svg&&(k(xt,S),k(kt,O),k(kt,R)),!0===Ut.svgFilters&&(k(xt,A),k(kt,O),k(kt,R)),!0===Ut.mathMl&&(k(xt,N),k(kt,I),k(kt,R))),t.ADD_TAGS&&(xt===wt&&(xt=T(xt)),k(xt,t.ADD_TAGS)),t.ADD_ATTR&&(kt===Tt&&(kt=T(kt)),k(kt,t.ADD_ATTR)),t.ADD_URI_SAFE_ATTR&&k(Wt,t.ADD_URI_SAFE_ATTR),t.FORBID_CONTENTS&&(zt===$t&&(zt=T(zt)),k(zt,t.FORBID_CONTENTS)),Yt&&(xt["#text"]=!0),Bt&&k(xt,["html","head","body"]),xt.table&&(k(xt,["tbody"]),delete Et.tbody),a&&a(t),re=t)},se=k({},["mi","mo","mn","ms","mtext"]),ce=k({},["foreignobject","desc","title","annotation-xml"]),ue=k({},S);k(ue,A),k(ue,M);var le=k({},N);k(le,D);var he=function(t){var e=nt(t);e&&e.tagName||(e={namespaceURI:Zt,tagName:"template"});var n=g(t.tagName),r=g(e.tagName);if(t.namespaceURI===Xt)return e.namespaceURI===Zt?"svg"===n:e.namespaceURI===Gt?"svg"===n&&("annotation-xml"===r||se[r]):Boolean(ue[n]);if(t.namespaceURI===Gt)return e.namespaceURI===Zt?"math"===n:e.namespaceURI===Xt?"math"===n&&ce[r]:Boolean(le[n]);if(t.namespaceURI===Zt){if(e.namespaceURI===Xt&&!ce[r])return!1;if(e.namespaceURI===Gt&&!se[r])return!1;var i=k({},["title","style","font","a","script"]);return!le[n]&&(i[n]||!ue[n])}return!1},fe=function(t){p(n.removed,{element:t});try{t.parentNode.removeChild(t)}catch(e){try{t.outerHTML=at}catch(e){t.remove()}}},de=function(t,e){try{p(n.removed,{attribute:e.getAttributeNode(t),from:e})}catch(t){p(n.removed,{attribute:null,from:e})}if(e.removeAttribute(t),"is"===t&&!kt[t])if(It||Rt)try{fe(e)}catch(t){}else try{e.setAttribute(t,"")}catch(t){}},pe=function(t){var e=void 0,n=void 0;if(Ot)t=""+t;else{var r=y(t,/^[\r\n\t ]+/);n=r&&r[0]}"application/xhtml+xml"===Jt&&(t=''+t+"");var a=it?it.createHTML(t):t;if(Qt===Zt)try{e=(new Z).parseFromString(a,Jt)}catch(t){}if(!e||!e.documentElement){e=st.createDocument(Qt,"template",null);try{e.documentElement.innerHTML=Kt?"":a}catch(t){}}var o=e.body||e.documentElement;return t&&n&&o.insertBefore(i.createTextNode(n),o.childNodes[0]||null),Qt===Zt?lt.call(e,Bt?"html":"body")[0]:Bt?e.documentElement:o},ge=function(t){return ct.call(t.ownerDocument||t,t,l.SHOW_ELEMENT|l.SHOW_COMMENT|l.SHOW_TEXT,null,!1)},ye=function(t){return t instanceof X&&("string"!=typeof t.nodeName||"string"!=typeof t.textContent||"function"!=typeof t.removeChild||!(t.attributes instanceof w)||"function"!=typeof t.removeAttribute||"function"!=typeof t.setAttribute||"string"!=typeof t.namespaceURI||"function"!=typeof t.insertBefore)},me=function(t){return"object"===(void 0===c?"undefined":H(c))?t instanceof c:t&&"object"===(void 0===t?"undefined":H(t))&&"number"==typeof t.nodeType&&"string"==typeof t.nodeName},ve=function(t,e,r){dt[t]&&f(dt[t],(function(t){t.call(n,e,r,re)}))},be=function(t){var e=void 0;if(ve("beforeSanitizeElements",t,null),ye(t))return fe(t),!0;if(y(t.nodeName,/[\u0080-\uFFFF]/))return fe(t),!0;var r=ne(t.nodeName);if(ve("uponSanitizeElement",t,{tagName:r,allowedTags:xt}),!me(t.firstElementChild)&&(!me(t.content)||!me(t.content.firstElementChild))&&_(/<[/\w]/g,t.innerHTML)&&_(/<[/\w]/g,t.textContent))return fe(t),!0;if("select"===r&&_(/